FD.io VPP  v18.07.1-19-g511ce25
Vector Packet Processing
pppoe.h
Go to the documentation of this file.
1 /*
2  *------------------------------------------------------------------
3  * Copyright (c) 2017 Intel and/or its affiliates.
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *------------------------------------------------------------------
16  */
17 
18 #ifndef _PPPOE_H
19 #define _PPPOE_H
20 
21 #include <vnet/plugin/plugin.h>
22 #include <vppinfra/lock.h>
23 #include <vppinfra/error.h>
24 #include <vppinfra/hash.h>
25 #include <vnet/vnet.h>
26 #include <vnet/ip/ip.h>
27 #include <vnet/ethernet/ethernet.h>
28 #include <vnet/ip/ip4_packet.h>
29 #include <vnet/ip/ip6_packet.h>
30 #include <vnet/dpo/dpo.h>
31 #include <vnet/adj/adj_types.h>
32 #include <vnet/fib/fib_table.h>
33 #include <vlib/vlib.h>
34 #include <vppinfra/bihash_8_8.h>
35 
36 
37 typedef struct
38 {
45 
46 #define PPPOE_VER_TYPE 0x11
47 #define PPPOE_PADS 0x65
48 
49 typedef struct
50 {
51  /* Required for pool_get_aligned */
52  CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
53 
54  /* pppoe session_id in HOST byte order */
56 
57  /* session client addresses */
58  ip46_address_t client_ip;
59 
60  /* the index of tx interface for pppoe encaped packet */
62 
63  /** FIB indices - inner IP packet lookup here */
65 
66  u8 local_mac[6];
67  u8 client_mac[6];
68 
69  /* vnet intfc index */
72 
74 
75 #define foreach_pppoe_input_next \
76 _(DROP, "error-drop") \
77 _(IP4_INPUT, "ip4-input") \
78 _(IP6_INPUT, "ip6-input" ) \
79 _(CP_INPUT, "pppoe-cp-dispatch" ) \
80 
81 typedef enum
82 {
83 #define _(s,n) PPPOE_INPUT_NEXT_##s,
85 #undef _
88 
89 typedef enum
90 {
91 #define pppoe_error(n,s) PPPOE_ERROR_##n,
92 #include <pppoe/pppoe_error.def>
93 #undef pppoe_error
96 
97 
98 #define MTU 1500
99 #define MTU_BUFFERS ((MTU + VLIB_BUFFER_DATA_SIZE - 1) / VLIB_BUFFER_DATA_SIZE)
100 #define NUM_BUFFERS_TO_ALLOC 32
101 
102 /*
103  * The size of pppoe session table
104  */
105 #define PPPOE_NUM_BUCKETS (64 * 1024)
106 #define PPPOE_MEMORY_SIZE (8<<20)
107 
108 /* *INDENT-OFF* */
109 /*
110  * The PPPoE key is the mac address and session ID
111  */
112 typedef struct
113 {
114  union
115  {
116  struct
117  {
119  u8 mac[6];
120  } fields;
121  struct
122  {
125  } words;
127  };
129 /* *INDENT-ON* */
130 
131 /* *INDENT-OFF* */
132 /*
133  * The PPPoE entry results
134  */
135 typedef struct
136 {
137  union
138  {
139  struct
140  {
142 
144 
145  } fields;
147  };
149 /* *INDENT-ON* */
150 
151 typedef struct
152 {
153  /* Vector of encap session instances, */
155 
156  /* For CP: vector of CP path */
157  BVT (clib_bihash) link_table;
158 
159  /* For DP: vector of DP path */
160  BVT (clib_bihash) session_table;
161 
162  /* Free vlib hw_if_indices */
163  u32 *free_pppoe_session_hw_if_indices;
164 
165  /* Mapping from sw_if_index to session index */
166  u32 *session_index_by_sw_if_index;
167 
168  /* used for pppoe cp path */
169  u32 cp_if_index;
170 
171  /* API message ID base */
173 
174  /* convenience */
177 
178 } pppoe_main_t;
179 
180 extern pppoe_main_t pppoe_main;
181 
184 
185 typedef struct
186 {
190  ip46_address_t client_ip;
193  u8 local_mac[6];
194  u8 client_mac[6];
196 
198  (vnet_pppoe_add_del_session_args_t * a, u32 * sw_if_indexp);
199 
200 typedef struct
201 {
206 
208 pppoe_make_key (u8 * mac_address, u16 session_id)
209 {
210  u64 temp;
211 
212  /*
213  * The mac address in memory is A:B:C:D:E:F
214  * The session_id in register is H:L
215  */
216 #if CLIB_ARCH_IS_LITTLE_ENDIAN
217  /*
218  * Create the in-register key as F:E:D:C:B:A:H:L
219  * In memory the key is L:H:A:B:C:D:E:F
220  */
221  temp = *((u64 *) (mac_address)) << 16;
222  temp = (temp & ~0xffff) | (u64) (session_id);
223 #else
224  /*
225  * Create the in-register key as H:L:A:B:C:D:E:F
226  * In memory the key is H:L:A:B:C:D:E:F
227  */
228  temp = *((u64 *) (mac_address)) >> 16;
229  temp = temp | (((u64) session_id) << 48);
230 #endif
231 
232  return temp;
233 }
234 
235 /**
236  * Perform learning on one packet based on the mac table lookup result.
237  * */
239 pppoe_learn_process (BVT (clib_bihash) * table,
240  u32 sw_if_index0,
241  pppoe_entry_key_t * key0,
242  pppoe_entry_key_t * cached_key,
243  u32 * bucket0, pppoe_entry_result_t * result0)
244 {
245  /* Check mac table lookup result */
246  if (PREDICT_TRUE (result0->fields.sw_if_index == sw_if_index0))
247  {
248  /*
249  * The entry was in the table, and the sw_if_index matched, the normal case
250  */
251  return;
252  }
253  else if (result0->fields.sw_if_index == ~0)
254  {
255  /* The entry was not in table, so add it */
256  result0->fields.sw_if_index = sw_if_index0;
257  result0->fields.session_index = ~0;
258  cached_key->raw = ~0; /* invalidate the cache */
259  }
260  else
261  {
262  /* The entry was in the table, but with the wrong sw_if_index mapping (mac move) */
263  result0->fields.sw_if_index = sw_if_index0;
264  }
265 
266  /* Update the entry */
267  BVT (clib_bihash_kv) kv;
268  kv.key = key0->raw;
269  kv.value = result0->raw;
270  BV (clib_bihash_add_del) (table, &kv, 1 /* is_add */ );
271 }
272 
274 pppoe_lookup_1 (BVT (clib_bihash) * table,
275  pppoe_entry_key_t * cached_key,
276  pppoe_entry_result_t * cached_result,
277  u8 * mac0,
278  u16 session_id0,
279  pppoe_entry_key_t * key0,
280  u32 * bucket0, pppoe_entry_result_t * result0)
281 {
282  /* set up key */
283  key0->raw = pppoe_make_key (mac0, session_id0);
284  *bucket0 = ~0;
285 
286  if (key0->raw == cached_key->raw)
287  {
288  /* Hit in the one-entry cache */
289  result0->raw = cached_result->raw;
290  }
291  else
292  {
293  /* Do a regular session table lookup */
294  BVT (clib_bihash_kv) kv;
295 
296  kv.key = key0->raw;
297  kv.value = ~0ULL;
298  BV (clib_bihash_search_inline) (table, &kv);
299  result0->raw = kv.value;
300 
301  /* Update one-entry cache */
302  cached_key->raw = key0->raw;
303  cached_result->raw = result0->raw;
304  }
305 }
306 
308 pppoe_update_1 (BVT (clib_bihash) * table,
309  u8 * mac0,
310  u16 session_id0,
311  pppoe_entry_key_t * key0,
312  u32 * bucket0, pppoe_entry_result_t * result0)
313 {
314  /* set up key */
315  key0->raw = pppoe_make_key (mac0, session_id0);
316  *bucket0 = ~0;
317 
318  /* Update the entry */
319  BVT (clib_bihash_kv) kv;
320  kv.key = key0->raw;
321  kv.value = result0->raw;
322  BV (clib_bihash_add_del) (table, &kv, 1 /* is_add */ );
323 
324 }
325 #endif /* _PPPOE_H */
326 
327 /*
328  * fd.io coding-style-patch-verification: ON
329  *
330  * Local Variables:
331  * eval: (c-set-style "gnu")
332  * End:
333  */
u16 ppp_proto
Definition: pppoe.h:43
Definition: pppoe.h:112
#define CLIB_CACHE_LINE_ALIGN_MARK(mark)
Definition: cache.h:63
a
Definition: bitmap.h:538
static_always_inline void pppoe_learn_process(BVT(clib_bihash)*table, u32 sw_if_index0, pppoe_entry_key_t *key0, pppoe_entry_key_t *cached_key, u32 *bucket0, pppoe_entry_result_t *result0)
Perform learning on one packet based on the mac table lookup result.
Definition: pppoe.h:239
u32 encap_if_index
Definition: pppoe.h:61
#define PREDICT_TRUE(x)
Definition: clib.h:106
unsigned long u64
Definition: types.h:89
u16 session_id
Definition: pppoe.h:55
u64 raw
Definition: pppoe.h:146
#define foreach_pppoe_input_next
Definition: pppoe.h:75
unsigned char u8
Definition: types.h:56
static u16 msg_id_base
Definition: gbp_api.c:68
static_always_inline void pppoe_lookup_1(BVT(clib_bihash)*table, pppoe_entry_key_t *cached_key, pppoe_entry_result_t *cached_result, u8 *mac0, u16 session_id0, pppoe_entry_key_t *key0, u32 *bucket0, pppoe_entry_result_t *result0)
Definition: pppoe.h:274
#define static_always_inline
Definition: clib.h:93
int clib_bihash_add_del(clib_bihash *h, clib_bihash_kv *add_v, int is_add)
Add or delete a (key,value) pair from a bi-hash table.
#define always_inline
Definition: clib.h:92
static BVT(clib_bihash)
Definition: adj_nbr.c:26
unsigned int u32
Definition: types.h:88
u64 raw
Definition: pppoe.h:126
u32 sw_if_index
Definition: pppoe.h:141
unsigned short u16
Definition: types.h:57
u16 session_id
Definition: pppoe.h:41
u16 length
Definition: pppoe.h:42
u32 hw_if_index
Definition: pppoe.h:71
ip46_address_t client_ip
Definition: pppoe.h:58
vnet_main_t vnet_main
Definition: misc.c:43
int clib_bihash_search_inline(clib_bihash *h, clib_bihash_kv *in_out_kv)
Search a bi-hash table.
u32 w0
Definition: pppoe.h:123
pppoe_input_next_t
Definition: pppoe.h:81
u32 w1
Definition: pppoe.h:124
vlib_node_registration_t pppoe_input_node
(constructor) VLIB_REGISTER_NODE (pppoe_input_node)
Definition: pppoe_decap.c:401
u32 session_index
Definition: pppoe.h:143
static u64 pppoe_make_key(u8 *mac_address, u16 session_id)
Definition: pppoe.h:208
pppoe_input_error_t
Definition: pppoe.h:89
pppoe_session_t * sessions
Definition: pppoe.h:154
static_always_inline void pppoe_update_1(BVT(clib_bihash)*table, u8 *mac0, u16 session_id0, pppoe_entry_key_t *key0, u32 *bucket0, pppoe_entry_result_t *result0)
Definition: pppoe.h:308
pppoe_main_t pppoe_main
Definition: jvpp_pppoe.h:39
Definition: pppoe.h:135
u32 sw_if_index
Definition: pppoe.h:70
vlib_node_registration_t pppoe_cp_dispatch_node
(constructor) VLIB_REGISTER_NODE (pppoe_cp_dispatch_node)
u16 session_id
Definition: pppoe.h:118
int vlib_main(vlib_main_t *volatile vm, unformat_input_t *input)
Definition: main.c:1695
struct _vlib_node_registration vlib_node_registration_t
u32 decap_fib_index
FIB indices - inner IP packet lookup here.
Definition: pppoe.h:64
struct pppoe_entry_result_t::@504::@506 fields
int vnet_pppoe_add_del_session(vnet_pppoe_add_del_session_args_t *a, u32 *sw_if_indexp)
Definition: pppoe.c:256
u8 ver_type
Definition: pppoe.h:39