FD.io VPP  v18.07.1-13-g909ba93
Vector Packet Processing
node.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #define _GNU_SOURCE
17 #include <vnet/bonding/node.h>
18 #include <vnet/ethernet/packet.h>
19 #include <lacp/node.h>
20 
21 lacp_state_struct lacp_state_array[] = {
22 #define _(b, s, n) {.bit = b, .str = #s, },
24 #undef _
25  {.str = NULL}
26 };
27 
29 
30 /** \file
31 
32  2 x LACP graph nodes: an "interior" node to process
33  incoming announcements, and a "process" node to periodically
34  send announcements.
35 
36  The interior node is neither pipelined nor dual-looped, because
37  it would be very unusual to see more than one LACP packet in
38  a given input frame. So, it's a very simple / straighforward
39  example.
40 */
41 
42 /*
43  * packet counter strings
44  * Dump these counters via the "show error" CLI command
45  */
46 static char *lacp_error_strings[] = {
47 #define _(sym,string) string,
49 #undef _
50 };
51 
52 /*
53  * We actually send all lacp pkts to the "error" node after scanning
54  * them, so the graph node has only one next-index. The "error-drop"
55  * node automatically bumps our per-node packet counters for us.
56  */
57 typedef enum
58 {
61 } lacp_next_t;
62 
63 /*
64  * Process a frame of lacp packets
65  * Expect 1 packet / frame
66  */
67 static uword
69  vlib_node_runtime_t * node, vlib_frame_t * frame)
70 {
71  u32 n_left_from, *from;
73  uword n_trace = vlib_get_trace_count (vm, node);
74 
75  from = vlib_frame_vector_args (frame); /* array of buffer indices */
76  n_left_from = frame->n_vectors; /* number of buffer indices */
77 
78  while (n_left_from > 0)
79  {
80  u32 bi0;
81  vlib_buffer_t *b0;
82  u32 next0, error0;
83 
84  bi0 = from[0];
85  b0 = vlib_get_buffer (vm, bi0);
86 
87  next0 = LACP_INPUT_NEXT_NORMAL;
88 
89  /* scan this lacp pkt. error0 is the counter index to bump */
90  error0 = lacp_input (vm, b0, bi0);
91  b0->error = node->errors[error0];
92 
93  /* If this pkt is traced, snapshoot the data */
94  if (PREDICT_FALSE (n_trace > 0))
95  {
96  int len;
97  vlib_trace_buffer (vm, node, next0, b0,
98  /* follow_chain */ 0);
99  vlib_set_trace_count (vm, node, --n_trace);
100  t0 = vlib_add_trace (vm, node, b0, sizeof (*t0));
101  len = (b0->current_length < sizeof (t0->pkt))
102  ? b0->current_length : sizeof (t0->pkt);
103  t0->len = len;
104  t0->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX];
105  clib_memcpy (&t0->pkt, vlib_buffer_get_current (b0), len);
106  }
107  /* push this pkt to the next graph node, always error-drop */
108  vlib_set_next_frame_buffer (vm, node, next0, bi0);
109 
110  from += 1;
111  n_left_from -= 1;
112  }
113 
114  return frame->n_vectors;
115 }
116 
117 /*
118  * lacp input graph node declaration
119  */
120 /* *INDENT-OFF* */
122  .function = lacp_node_fn,
123  .name = "lacp-input",
124  .vector_size = sizeof (u32),
125  .type = VLIB_NODE_TYPE_INTERNAL,
126 
127  .n_errors = LACP_N_ERROR,
128  .error_strings = lacp_error_strings,
129 
130  .format_trace = lacp_input_format_trace,
131 
132  .n_next_nodes = LACP_INPUT_N_NEXT,
133  .next_nodes = {
134  [LACP_INPUT_NEXT_NORMAL] = "error-drop",
135  },
136 };
137 /* *INDENT-ON* */
138 
139 /*
140  * lacp periodic function
141  */
142 static uword
144 {
145  lacp_main_t *lm = &lacp_main;
146  f64 poll_time_remaining;
147  uword event_type, *event_data = 0;
148  u8 enabled = 0;
149 
150  /* So we can send events to the lacp process */
152 
153  ethernet_register_input_type (vm, ETHERNET_TYPE_SLOW_PROTOCOLS /* LACP */ ,
154  lacp_input_node.index);
155 
156  poll_time_remaining = 0.2;
157  while (1)
158  {
159  if (enabled)
160  poll_time_remaining =
161  vlib_process_wait_for_event_or_clock (vm, poll_time_remaining);
162  else
164 
165  event_type = vlib_process_get_events (vm, &event_data);
166  switch (event_type)
167  {
168  case ~0: /* no events => timeout */
169  break;
171  enabled = 1;
172  break;
174  enabled = 0;
175  continue;
176  default:
177  clib_warning ("BUG: event type 0x%wx", event_type);
178  break;
179  }
180  if (event_data)
181  _vec_len (event_data) = 0;
182 
183  if (vlib_process_suspend_time_is_zero (poll_time_remaining))
184  {
185  lacp_periodic (vm);
186  poll_time_remaining = 0.2;
187  }
188  }
189 
190  return 0;
191 }
192 
193 /*
194  * lacp periodic node declaration
195  */
196 /* *INDENT-OFF* */
198  .function = lacp_process,
199  .type = VLIB_NODE_TYPE_PROCESS,
200  .name = "lacp-process",
201 };
202 /* *INDENT-ON* */
203 
204 /*
205  * fd.io coding-style-patch-verification: ON
206  *
207  * Local Variables:
208  * eval: (c-set-style "gnu")
209  * End:
210  */
static u32 vlib_get_trace_count(vlib_main_t *vm, vlib_node_runtime_t *rt)
Definition: trace_funcs.h:143
static f64 vlib_process_wait_for_event_or_clock(vlib_main_t *vm, f64 dt)
Suspend a cooperative multi-tasking thread Waits for an event, or for the indicated number of seconds...
Definition: node_funcs.h:699
static uword * vlib_process_wait_for_event(vlib_main_t *vm)
Definition: node_funcs.h:619
static void vlib_set_next_frame_buffer(vlib_main_t *vm, vlib_node_runtime_t *node, u32 next_index, u32 buffer_index)
Definition: node_funcs.h:397
#define NULL
Definition: clib.h:55
vlib_error_t * errors
Vector of errors for this node.
Definition: node.h:451
static vlib_node_registration_t lacp_input_node
(constructor) VLIB_REGISTER_NODE (lacp_input_node)
Definition: node.c:121
unsigned char u8
Definition: types.h:56
static uword vlib_process_suspend_time_is_zero(f64 dt)
Returns TRUE if a process suspend time is less than 10us.
Definition: node_funcs.h:436
double f64
Definition: types.h:142
static void vlib_trace_buffer(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, vlib_buffer_t *b, int follow_chain)
Definition: trace_funcs.h:104
lacp_next_t
Definition: node.c:57
u8 * lacp_input_format_trace(u8 *s, va_list *args)
Definition: input.c:241
static uword vlib_process_get_events(vlib_main_t *vm, uword **data_vector)
Return the first event type which has occurred and a vector of per-event data of that type...
Definition: node_funcs.h:542
unsigned int u32
Definition: types.h:88
void lacp_periodic(vlib_main_t *vm)
Definition: lacp.c:137
u16 current_length
Nbytes between current data and the end of this buffer.
Definition: buffer.h:108
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:202
#define PREDICT_FALSE(x)
Definition: clib.h:105
static uword lacp_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
Definition: node.c:143
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:135
#define foreach_lacp_state_flag
Definition: protocol.h:71
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:153
u16 n_vectors
Definition: node.h:380
vlib_main_t * vm
Definition: buffer.c:294
#define clib_warning(format, args...)
Definition: error.h:59
#define clib_memcpy(a, b, c)
Definition: string.h:75
union lacp_input_trace_t::@439 pkt
lacp_main_t lacp_main
Definition: lacp.c:25
#define foreach_lacp_error
Definition: node.h:61
lacp_error_t lacp_input(vlib_main_t *vm, vlib_buffer_t *b0, u32 bi0)
Definition: input.c:135
void ethernet_register_input_type(vlib_main_t *vm, ethernet_type_t type, u32 node_index)
Definition: node.c:1342
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace_funcs.h:55
struct _vlib_node_registration vlib_node_registration_t
u32 lacp_process_node_index
Definition: node.h:123
u32 sw_if_index
Definition: node.h:80
u64 uword
Definition: types.h:112
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:267
#define vnet_buffer(b)
Definition: buffer.h:360
static vlib_node_registration_t lacp_process_node
(constructor) VLIB_REGISTER_NODE (lacp_process_node)
Definition: node.c:28
static char * lacp_error_strings[]
Definition: node.c:46
static void vlib_set_trace_count(vlib_main_t *vm, vlib_node_runtime_t *rt, u32 count)
Definition: trace_funcs.h:159
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:57
static uword lacp_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: node.c:68
Definition: defs.h:46