FD.io VPP  v21.10.1-2-g0a485f517
Vector Packet Processing
pppoe_cp_node.c
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 pemplied.
13  * See the License for the specific language governing permissions and
14  * lpemitations under the License.
15  *------------------------------------------------------------------
16  */
17 
18 #include <vlib/vlib.h>
19 #include <vnet/ppp/packet.h>
20 #include <pppoe/pppoe.h>
21 
22 #define foreach_pppoe_cp_next \
23 _(DROP, "error-drop") \
24 _(INTERFACE, "interface-output" ) \
25 
26 typedef enum
27 {
28 #define _(s,n) PPPOE_CP_NEXT_##s,
30 #undef _
33 
34 typedef struct {
42 
43 static u8 * format_pppoe_cp_trace (u8 * s, va_list * args)
44 {
45  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
46  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
47  pppoe_cp_trace_t * t = va_arg (*args, pppoe_cp_trace_t *);
48  pppoe_main_t * pem = &pppoe_main;
49 
50  if (t->sw_if_index != pem->cp_if_index)
51  {
52  s = format (s, "PPPoE dispatch from sw_if_index %d next %d error %d \n"
53  " pppoe_code 0x%x ppp_proto 0x%x",
54  t->sw_if_index, t->next_index, t->error,
55  t->pppoe_code, t->ppp_proto);
56  }
57  else
58  {
59  s = format (s, "PPPoE dispatch from cp_if_index %d next %d error %d \n"
60  " pppoe_code 0x%x ppp_proto 0x%x",
61  t->cp_if_index, t->next_index, t->error,
62  t->pppoe_code, t->ppp_proto);
63  }
64  return s;
65 }
66 
70 {
71  u32 n_left_from, next_index, * from, * to_next;
72  pppoe_main_t * pem = &pppoe_main;
73  vnet_main_t * vnm = pem->vnet_main;
75  u32 pkts_decapsulated = 0;
77  u32 stats_sw_if_index, stats_n_packets, stats_n_bytes;
78  pppoe_entry_key_t cached_key;
79  pppoe_entry_result_t cached_result;
80 
82  n_left_from = from_frame->n_vectors;
83 
84  /* Clear the one-entry cache in case session table was updated */
85  cached_key.raw = ~0;
86  cached_result.raw = ~0; /* warning be gone */
87 
88  next_index = node->cached_next_index;
89  stats_sw_if_index = node->runtime_data[0];
90  stats_n_packets = stats_n_bytes = 0;
91 
92  while (n_left_from > 0)
93  {
94  u32 n_left_to_next;
95 
97  to_next, n_left_to_next);
98 
99  while (n_left_from > 0 && n_left_to_next > 0)
100  {
101  u32 bi0;
102  vlib_buffer_t * b0;
103  ethernet_header_t *h0;
104  pppoe_header_t * pppoe0;
105  pppoe_entry_key_t key0;
106  pppoe_entry_result_t result0;
107 
108  u32 bucket0;
109  u32 next0;
110  u32 error0 = 0;
111  u32 rx_sw_if_index0=~0, tx_sw_if_index0=~0, len0;
114 
115  bi0 = from[0];
116  to_next[0] = bi0;
117  from += 1;
118  to_next += 1;
119  n_left_from -= 1;
120  n_left_to_next -= 1;
121 
122  b0 = vlib_get_buffer (vm, bi0);
123  /* leaves current_data pointing at the pppoe header */
124  pppoe0 = vlib_buffer_get_current (b0);
125  rx_sw_if_index0 = vnet_buffer(b0)->sw_if_index[VLIB_RX];
126 
127  if (PREDICT_FALSE (pppoe0->ver_type != PPPOE_VER_TYPE))
128  {
129  error0 = PPPOE_ERROR_BAD_VER_TYPE;
130  next0 = PPPOE_INPUT_NEXT_DROP;
131  goto trace00;
132  }
133 
134  vlib_buffer_reset(b0);
135  h0 = vlib_buffer_get_current (b0);
136 
137  if(rx_sw_if_index0 == pem->cp_if_index)
138  {
139  pppoe_lookup_1 (&pem->link_table, &cached_key, &cached_result,
140  h0->dst_address, 0,
141  &key0, &bucket0, &result0);
142  tx_sw_if_index0 = result0.fields.sw_if_index;
143 
144  if (PREDICT_FALSE (tx_sw_if_index0 == ~0))
145  {
146  error0 = PPPOE_ERROR_NO_SUCH_SESSION;
147  next0 = PPPOE_INPUT_NEXT_DROP;
148  goto trace00;
149  }
150 
151  next0 = PPPOE_CP_NEXT_INTERFACE;
152  vnet_buffer(b0)->sw_if_index[VLIB_TX] = tx_sw_if_index0;
153 
154  /* set src mac address */
155  si = vnet_get_sw_interface(vnm, tx_sw_if_index0);
158  }
160  clib_memcpy_fast (vlib_buffer_get_current (b0)+6, hi->hw_address, 6);
161  }
162  else
163  {
164  pppoe_lookup_1 (&pem->link_table, &cached_key, &cached_result,
165  h0->src_address, 0,
166  &key0, &bucket0, &result0);
167  tx_sw_if_index0 = result0.fields.sw_if_index;
168 
169  /* learn client session */
170  pppoe_learn_process (&pem->link_table, rx_sw_if_index0,
171  &key0, &cached_key,
172  &bucket0, &result0);
173 
174  next0 = PPPOE_CP_NEXT_INTERFACE;
175  vnet_buffer(b0)->sw_if_index[VLIB_TX] = pem->cp_if_index;
176  }
177 
178  len0 = vlib_buffer_length_in_chain (vm, b0);
179 
180  pkts_decapsulated ++;
181  stats_n_packets += 1;
182  stats_n_bytes += len0;
183 
184  /* Batch stats increment on the same pppoe session so counter
185  is not incremented per packet */
186  if (PREDICT_FALSE (rx_sw_if_index0 != stats_sw_if_index))
187  {
188  stats_n_packets -= 1;
189  stats_n_bytes -= len0;
190  if (stats_n_packets)
193  thread_index, stats_sw_if_index,
194  stats_n_packets, stats_n_bytes);
195  stats_n_packets = 1;
196  stats_n_bytes = len0;
197  stats_sw_if_index = rx_sw_if_index0;
198  }
199 
200  trace00:
201  b0->error = error0 ? node->errors[error0] : 0;
202 
203  if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED))
204  {
205  pppoe_cp_trace_t *tr
206  = vlib_add_trace (vm, node, b0, sizeof (*tr));
207  tr->next_index = next0;
208  tr->error = error0;
209  tr->sw_if_index = tx_sw_if_index0;
210  tr->cp_if_index = pem->cp_if_index;
211  tr->pppoe_code = pppoe0->code;
212  tr->ppp_proto = clib_net_to_host_u16(pppoe0->ppp_proto);
213  }
215  to_next, n_left_to_next,
216  bi0, next0);
217  }
218 
219  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
220  }
221  /* Do we still need this now that session tx stats is kept? */
223  PPPOE_ERROR_DECAPSULATED,
224  pkts_decapsulated);
225 
226  /* Increment any remaining batch stats */
227  if (stats_n_packets)
228  {
231  thread_index, stats_sw_if_index, stats_n_packets, stats_n_bytes);
232  node->runtime_data[0] = stats_sw_if_index;
233  }
234 
235  return from_frame->n_vectors;
236 }
237 
239  .name = "pppoe-cp-dispatch",
240  /* Takes a vector of packets. */
241  .vector_size = sizeof (u32),
242 
243  .n_errors = PPPOE_N_ERROR,
244  .error_strings = pppoe_error_strings,
245 
246  .n_next_nodes = PPPOE_CP_N_NEXT,
247  .next_nodes = {
248 #define _(s,n) [PPPOE_CP_NEXT_##s] = n,
250 #undef _
251  },
252 
253  .format_trace = format_pppoe_cp_trace,
254 };
255 
vlib.h
PPPOE_N_ERROR
@ PPPOE_N_ERROR
Definition: pppoe.h:94
foreach_pppoe_cp_next
#define foreach_pppoe_cp_next
Definition: pppoe_cp_node.c:22
im
vnet_interface_main_t * im
Definition: interface_output.c:415
pppoe_error_strings
char * pppoe_error_strings[]
Definition: pppoe_decap.c:462
thread_index
u32 thread_index
Definition: nat44_ei_hairpinning.c:495
pppoe_header_t::ppp_proto
u16 ppp_proto
Definition: pppoe.h:43
vnet_sw_interface_t::type
vnet_sw_interface_type_t type
Definition: interface.h:871
vnet_sw_interface_t
Definition: interface.h:869
format_pppoe_cp_trace
static u8 * format_pppoe_cp_trace(u8 *s, va_list *args)
Definition: pppoe_cp_node.c:43
pppoe_header_t::ver_type
u8 ver_type
Definition: pppoe.h:39
next_index
nat44_ei_hairpin_src_next_t next_index
Definition: nat44_ei_hairpinning.c:412
vlib_get_buffer
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:111
pppoe_entry_result_t
Definition: pppoe.h:136
ethernet_header_t::dst_address
u8 dst_address[6]
Definition: packet.h:55
ethernet_header_t::src_address
u8 src_address[6]
Definition: packet.h:56
node
vlib_main_t vlib_node_runtime_t * node
Definition: nat44_ei.c:3047
VNET_SW_INTERFACE_TYPE_SUB
@ VNET_SW_INTERFACE_TYPE_SUB
Definition: interface.h:767
vnet_interface_main_t
Definition: interface.h:990
pppoe_main_t::vnet_main
vnet_main_t * vnet_main
Definition: pppoe.h:177
u16
unsigned short u16
Definition: types.h:57
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
VLIB_RX
@ VLIB_RX
Definition: defs.h:46
vnet_get_sw_interface
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
Definition: interface_funcs.h:58
from_frame
vlib_main_t vlib_node_runtime_t vlib_frame_t * from_frame
Definition: esp_encrypt.c:1328
hi
vl_api_ip4_address_t hi
Definition: arp.api:37
pppoe_learn_process
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:242
vlib_frame_t
Definition: node.h:372
vlib_buffer_length_in_chain
static uword vlib_buffer_length_in_chain(vlib_main_t *vm, vlib_buffer_t *b)
Get length in bytes of the buffer chain.
Definition: buffer_funcs.h:433
clib_memcpy_fast
static_always_inline void * clib_memcpy_fast(void *restrict dst, const void *restrict src, size_t n)
Definition: string.h:92
PPPOE_VER_TYPE
#define PPPOE_VER_TYPE
Definition: pppoe.h:46
pppoe_cp_trace_t::ppp_proto
u16 ppp_proto
Definition: pppoe_cp_node.c:39
pppoe_input_node
vlib_node_registration_t pppoe_input_node
(constructor) VLIB_REGISTER_NODE (pppoe_input_node)
Definition: pppoe_decap.c:470
pppoe_cp_trace_t::cp_if_index
u32 cp_if_index
Definition: pppoe_cp_node.c:37
pppoe_main_t::cp_if_index
u32 cp_if_index
Definition: pppoe.h:170
PPPOE_CP_N_NEXT
@ PPPOE_CP_N_NEXT
Definition: pppoe_cp_node.c:31
pppoe_main_t
Definition: pppoe.h:152
vlib_buffer_t::error
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:145
pppoe_cp_trace_t::next_index
u32 next_index
Definition: pppoe_cp_node.c:35
VLIB_NODE_FN
#define VLIB_NODE_FN(node)
Definition: node.h:202
CLIB_UNUSED
#define CLIB_UNUSED(x)
Definition: clib.h:90
vnet_buffer
#define vnet_buffer(b)
Definition: buffer.h:441
vnet_get_hw_interface
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
Definition: interface_funcs.h:44
pppoe_cp_trace_t::error
u32 error
Definition: pppoe_cp_node.c:40
PREDICT_FALSE
#define PREDICT_FALSE(x)
Definition: clib.h:124
vlib_get_thread_index
static_always_inline uword vlib_get_thread_index(void)
Definition: threads.h:187
vlib_frame_vector_args
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:301
ethernet_header_t
Definition: packet.h:52
vlib_node_increment_counter
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
Definition: node_funcs.h:1244
pppoe_cp_next_t
pppoe_cp_next_t
Definition: pppoe_cp_node.c:26
pppoe_cp_trace_t::sw_if_index
u32 sw_if_index
Definition: pppoe_cp_node.c:36
pppoe_entry_result_t::raw
u64 raw
Definition: pppoe.h:147
VNET_INTERFACE_COUNTER_RX
@ VNET_INTERFACE_COUNTER_RX
Definition: interface.h:915
pppoe_cp_trace_t
Definition: pppoe_cp_node.c:34
pppoe_header_t::code
u8 code
Definition: pppoe.h:40
vlib_node_registration_t
struct _vlib_node_registration vlib_node_registration_t
vnet_interface_main_t::combined_sw_if_counters
vlib_combined_counter_main_t * combined_sw_if_counters
Definition: interface.h:1024
pppoe_lookup_1
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:277
vnet_hw_interface_t
Definition: interface.h:638
vnet_main_t
Definition: vnet.h:76
vlib_validate_buffer_enqueue_x1
#define vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, bi0, next0)
Finish enqueueing one buffer forward in the graph.
Definition: buffer_node.h:224
vnet_sw_interface_t::sup_sw_if_index
u32 sup_sw_if_index
Definition: interface.h:881
pppoe_entry_key_t::raw
u64 raw
Definition: pppoe.h:127
pppoe_cp_trace_t::pppoe_code
u8 pppoe_code
Definition: pppoe_cp_node.c:38
format
description fragment has unexpected format
Definition: map.api:433
pppoe_entry_result_t::fields
struct pppoe_entry_result_t::@776::@778 fields
vlib_put_next_frame
vlib_put_next_frame(vm, node, next_index, 0)
pppoe_header_t
Definition: pppoe.h:37
u32
unsigned int u32
Definition: types.h:88
si
vnet_sw_interface_t * si
Definition: interface_output.c:418
packet.h
vlib_main_t
Definition: main.h:102
vlib_node_t
Definition: node.h:247
vlib_add_trace
void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace.c:628
pppoe_cp_dispatch_node
vlib_node_registration_t pppoe_cp_dispatch_node
(constructor) VLIB_REGISTER_NODE (pppoe_cp_dispatch_node)
Definition: pppoe_cp_node.c:238
u8
unsigned char u8
Definition: types.h:56
vlib_buffer_get_current
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:257
vnet_sw_interface_t::hw_if_index
u32 hw_if_index
Definition: interface.h:887
vlib_node_runtime_t
Definition: node.h:454
vlib_buffer_reset
static void vlib_buffer_reset(vlib_buffer_t *b)
Reset current header & length to state they were in when packet was received.
Definition: buffer.h:305
from
from
Definition: nat44_ei_hairpinning.c:415
vlib_get_next_frame
#define vlib_get_next_frame(vm, node, next_index, vectors, n_vectors_left)
Get pointer to next frame vector data by (vlib_node_runtime_t, next_index).
Definition: node_funcs.h:395
VLIB_TX
@ VLIB_TX
Definition: defs.h:47
pppoe_main
pppoe_main_t pppoe_main
Definition: pppoe.c:38
n_left_from
n_left_from
Definition: nat44_ei_hairpinning.c:416
vnet_main_t::interface_main
vnet_interface_main_t interface_main
Definition: vnet.h:81
vlib_increment_combined_counter
vlib_increment_combined_counter(ccm, ti, sw_if_index, n_buffers, n_bytes)
pppoe.h
pppoe_entry_key_t
Definition: pppoe.h:113
vlib_buffer_t::flags
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index,...
Definition: buffer.h:133
vlib_buffer_t
VLIB buffer representation.
Definition: buffer.h:111
VLIB_REGISTER_NODE
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169