FD.io VPP  v21.06-3-gbb25fbf28
Vector Packet Processing
l2_arp_term.c
Go to the documentation of this file.
1 /*
2  * l2/l2_arp_term.c: IP v4 ARP L2 BD termination
3  *
4  * Copyright (c) 2010 Cisco and/or its affiliates.
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include <vlibmemory/api.h>
19 
20 #include <vnet/l2/l2_arp_term.h>
21 #include <vnet/l2/l2_input.h>
22 #include <vnet/l2/feat_bitmap.h>
23 
24 #include <vnet/ip/ip4_packet.h>
25 #include <vnet/ip/ip6_packet.h>
26 #include <vnet/ip/icmp6.h>
27 #include <vnet/ip/ip6.h>
28 #include <vnet/ip/format.h>
30 
31 static const u8 vrrp_prefix[] = { 0x00, 0x00, 0x5E, 0x00, 0x01 };
32 
34 
35 /*
36  * ARP/ND Termination in a L2 Bridge Domain based on IP4/IP6 to MAC
37  * hash tables mac_by_ip4 and mac_by_ip6 for each BD.
38  */
39 typedef enum
40 {
45 
47 
48 typedef struct
49 {
50  u8 packet_data[64];
52 
53 #define foreach_ethernet_arp_error \
54  _ (replies_sent, "ARP replies sent") \
55  _ (l2_type_not_ethernet, "L2 type not ethernet") \
56  _ (l3_type_not_ip4, "L3 type not IP4") \
57  _ (l3_src_address_not_local, "IP4 source address not local to subnet") \
58  _ (l3_dst_address_not_local, "IP4 destination address not local to subnet") \
59  _ (l3_dst_address_unset, "IP4 destination address is unset") \
60  _ (l3_src_address_is_local, "IP4 source address matches local interface") \
61  _ (l3_src_address_learned, "ARP request IP4 source address learned") \
62  _ (replies_received, "ARP replies received") \
63  _ (opcode_not_request, "ARP opcode not request") \
64  _ (proxy_arp_replies_sent, "Proxy ARP replies sent") \
65  _ (l2_address_mismatch, "ARP hw addr does not match L2 frame src addr") \
66  _ (gratuitous_arp, "ARP probe or announcement dropped") \
67  _ (interface_no_table, "Interface is not mapped to an IP table") \
68  _ (interface_not_ip_enabled, "Interface is not IP enabled") \
69  _ (unnumbered_mismatch, "RX interface is unnumbered to different subnet") \
70 
71 typedef enum
72 {
73 #define _(sym,string) ETHERNET_ARP_ERROR_##sym,
75 #undef _
78 
79 static char *ethernet_arp_error_strings[] = {
80 #define _(sym,string) string,
82 #undef _
83 };
84 
85 static u8 *
86 format_arp_term_input_trace (u8 * s, va_list * va)
87 {
88  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*va, vlib_main_t *);
89  CLIB_UNUSED (vlib_node_t * node) = va_arg (*va, vlib_node_t *);
91 
92  /* arp-term trace data saved is either arp or ip6/icmp6 packet:
93  - for arp, the 1st 16-bit field is hw type of value of 0x0001.
94  - for ip6, the first nibble has value of 6. */
95  s = format (s, "%U", t->packet_data[0] == 0 ?
97  t->packet_data, sizeof (t->packet_data));
98 
99  return s;
100 }
101 
102 void
104 {
106 
107  l2am->publish = on;
108 }
109 
110 static int
112 {
114 
115  vec_add1 (l2am->publish_events, *ctx);
116 
120 
121  return 0;
122 }
123 
124 static inline void
126  const ethernet_arp_ip4_over_ethernet_address_t * a)
127 {
129 
130  if (!l2am->publish)
131  return;
132 
135  .type = IP46_TYPE_IP4,
136  .ip.ip4 = a->ip4,
137  .mac = a->mac,
138  };
139 
141  sizeof (args));
142 }
143 
144 static inline void
146  const ip6_address_t * addr,
147  const mac_address_t * mac)
148 {
150 
151  if (!l2am->publish)
152  return;
153 
156  .type = IP46_TYPE_IP6,
157  .ip.ip6 = *addr,
158  .mac = *mac,
159  };
160 
162  sizeof (args));
163 }
164 
165 static inline int
168  vlib_buffer_t * p0,
169  ethernet_header_t * eth,
170  ip6_header_t * ip, u32 sw_if_index, u16 bd_index)
171 {
172  icmp6_neighbor_solicitation_or_advertisement_header_t *ndh;
174 
176  ndh = ip6_next_header (ip);
177  if (ndh->icmp.type != ICMP6_neighbor_solicitation &&
178  ndh->icmp.type != ICMP6_neighbor_advertisement)
179  return 0;
180 
181  if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) &&
182  (p0->flags & VLIB_BUFFER_IS_TRACED)))
183  {
184  u8 *t0 = vlib_add_trace (vm, node, p0,
185  sizeof (icmp6_input_trace_t));
186  clib_memcpy (t0, ip, sizeof (icmp6_input_trace_t));
187  }
188 
189  /* Check if anyone want ND events for L2 BDs */
190  if (PREDICT_FALSE (!ip6_address_is_link_local_unicast (&ip->src_address)))
191  {
192  l2_arp_term_publish_v6_dp (sw_if_index, &ip->src_address, &mac);
193  }
194 
195  /* Check if MAC entry exsist for solicited target IP */
196  if (ndh->icmp.type == ICMP6_neighbor_solicitation)
197  {
198  icmp6_neighbor_discovery_ethernet_link_layer_address_option_t *opt;
199  l2_bridge_domain_t *bd_config;
200  u8 *macp;
201 
202  opt = (void *) (ndh + 1);
203  if ((opt->header.type !=
204  ICMP6_NEIGHBOR_DISCOVERY_OPTION_source_link_layer_address) ||
205  (opt->header.n_data_u64s != 1))
206  return 0; /* source link layer address option not present */
207 
208  bd_config = vec_elt_at_index (l2input_main.bd_configs, bd_index);
209  macp =
210  (u8 *) hash_get_mem (bd_config->mac_by_ip6, &ndh->target_address);
211  if (macp)
212  { /* found ip-mac entry, generate eighbor advertisement response */
213  int bogus_length;
214  vlib_node_runtime_t *error_node =
216  ip->dst_address = ip->src_address;
217  ip->src_address = ndh->target_address;
218  ip->hop_limit = 255;
219  opt->header.type =
220  ICMP6_NEIGHBOR_DISCOVERY_OPTION_target_link_layer_address;
221  clib_memcpy (opt->ethernet_address, macp, 6);
222  ndh->icmp.type = ICMP6_neighbor_advertisement;
223  ndh->advertisement_flags = clib_host_to_net_u32
226  ndh->icmp.checksum = 0;
227  ndh->icmp.checksum =
228  ip6_tcp_udp_icmp_compute_checksum (vm, p0, ip, &bogus_length);
229  clib_memcpy (eth->dst_address, eth->src_address, 6);
230  clib_memcpy (eth->src_address, macp, 6);
231  vlib_error_count (vm, error_node->node_index,
232  ICMP6_ERROR_NEIGHBOR_ADVERTISEMENTS_TX, 1);
233  return 1;
234  }
235  }
236 
237  return 0;
238 
239 }
240 
241 static uword
244 {
245  l2input_main_t *l2im = &l2input_main;
246  u32 n_left_from, next_index, *from, *to_next;
247  u32 n_replies_sent = 0;
248  u16 last_bd_index = ~0;
249  l2_bridge_domain_t *last_bd_config = 0;
250  l2_input_config_t *cfg0;
251 
253  n_left_from = frame->n_vectors;
254  next_index = node->cached_next_index;
255 
256  while (n_left_from > 0)
257  {
258  u32 n_left_to_next;
259 
260  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
261 
262  while (n_left_from > 0 && n_left_to_next > 0)
263  {
264  vlib_buffer_t *p0;
265  ethernet_header_t *eth0;
266  ethernet_arp_header_t *arp0;
267  ip6_header_t *iph0;
268  u8 *l3h0;
269  u32 pi0, error0, next0, sw_if_index0;
270  u16 ethertype0;
271  u16 bd_index0;
272  u32 ip0;
273  u8 *macp0;
274 
275  pi0 = from[0];
276  to_next[0] = pi0;
277  from += 1;
278  to_next += 1;
279  n_left_from -= 1;
280  n_left_to_next -= 1;
281 
282  p0 = vlib_get_buffer (vm, pi0);
283  // Terminate only local (SHG == 0) ARP
284  if (vnet_buffer (p0)->l2.shg != 0)
285  goto next_l2_feature;
286 
287  eth0 = vlib_buffer_get_current (p0);
288  l3h0 = (u8 *) eth0 + vnet_buffer (p0)->l2.l2_len;
289  ethertype0 = clib_net_to_host_u16 (*(u16 *) (l3h0 - 2));
290  arp0 = (ethernet_arp_header_t *) l3h0;
291 
292  if (ethertype0 != ETHERNET_TYPE_ARP)
293  goto check_ip6_nd;
294 
295  if ((arp0->opcode !=
296  clib_host_to_net_u16 (ETHERNET_ARP_OPCODE_request)) &&
297  (arp0->opcode !=
298  clib_host_to_net_u16 (ETHERNET_ARP_OPCODE_reply)))
299  goto check_ip6_nd;
300 
301  /* Must be ARP request/reply packet here */
302  if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) &&
303  (p0->flags & VLIB_BUFFER_IS_TRACED)))
304  {
305  u8 *t0 = vlib_add_trace (vm, node, p0,
306  sizeof (ethernet_arp_input_trace_t));
307  clib_memcpy_fast (t0, l3h0,
308  sizeof (ethernet_arp_input_trace_t));
309  }
310 
311  error0 = 0;
312  error0 =
313  (arp0->l2_type !=
314  clib_net_to_host_u16 (ETHERNET_ARP_HARDWARE_TYPE_ethernet)
315  ? ETHERNET_ARP_ERROR_l2_type_not_ethernet : error0);
316  error0 =
317  (arp0->l3_type !=
318  clib_net_to_host_u16 (ETHERNET_TYPE_IP4) ?
319  ETHERNET_ARP_ERROR_l3_type_not_ip4 : error0);
320 
321  sw_if_index0 = vnet_buffer (p0)->sw_if_index[VLIB_RX];
322 
323  if (error0)
324  goto drop;
325 
326  /* Trash ARP packets whose ARP-level source addresses do not
327  match, or if requester address is mcast */
328  if (PREDICT_FALSE
330  arp0->ip4_over_ethernet[0].
331  mac.bytes))
332  || ethernet_address_cast (arp0->ip4_over_ethernet[0].mac.bytes))
333  {
334  /* VRRP virtual MAC may be different to SMAC in ARP reply */
336  (arp0->ip4_over_ethernet[0].mac.bytes, vrrp_prefix))
337  {
338  error0 = ETHERNET_ARP_ERROR_l2_address_mismatch;
339  goto drop;
340  }
341  }
342  if (PREDICT_FALSE
344  {
345  error0 = ETHERNET_ARP_ERROR_l3_src_address_not_local;
346  goto drop;
347  }
348 
349  /* Check if anyone want ARP request events for L2 BDs */
350  l2_arp_term_publish_v4_dp (sw_if_index0,
351  &arp0->ip4_over_ethernet[0]);
352 
353  /* lookup BD mac_by_ip4 hash table for MAC entry */
354  ip0 = arp0->ip4_over_ethernet[1].ip4.as_u32;
355  bd_index0 = vnet_buffer (p0)->l2.bd_index;
356  if (PREDICT_FALSE ((bd_index0 != last_bd_index)
357  || (last_bd_index == (u16) ~ 0)))
358  {
359  last_bd_index = bd_index0;
360  last_bd_config = vec_elt_at_index (l2im->bd_configs, bd_index0);
361  }
362  macp0 = (u8 *) hash_get (last_bd_config->mac_by_ip4, ip0);
363 
364  if (PREDICT_FALSE (!macp0))
365  goto next_l2_feature; /* MAC not found */
366  if (PREDICT_FALSE (arp0->ip4_over_ethernet[0].ip4.as_u32 ==
367  arp0->ip4_over_ethernet[1].ip4.as_u32))
368  goto next_l2_feature; /* GARP */
369 
370  /* MAC found, send ARP reply -
371  Convert ARP request packet to ARP reply */
372  arp0->opcode = clib_host_to_net_u16 (ETHERNET_ARP_OPCODE_reply);
373  arp0->ip4_over_ethernet[1] = arp0->ip4_over_ethernet[0];
374  arp0->ip4_over_ethernet[0].ip4.as_u32 = ip0;
375  mac_address_from_bytes (&arp0->ip4_over_ethernet[0].mac, macp0);
376  clib_memcpy_fast (eth0->dst_address, eth0->src_address, 6);
377  clib_memcpy_fast (eth0->src_address, macp0, 6);
378  n_replies_sent += 1;
379 
380  output_response:
381  /* For BVI, need to use l2-fwd node to send ARP reply as
382  l2-output node cannot output packet to BVI properly */
383  cfg0 = vec_elt_at_index (l2im->configs, sw_if_index0);
384  if (PREDICT_FALSE (l2_input_is_bvi (cfg0)))
385  {
386  vnet_buffer (p0)->l2.feature_bitmap |= L2INPUT_FEAT_FWD;
387  vnet_buffer (p0)->sw_if_index[VLIB_RX] = 0;
388  goto next_l2_feature;
389  }
390 
391  /* Send ARP/ND reply back out input interface through l2-output */
392  vnet_buffer (p0)->sw_if_index[VLIB_TX] = sw_if_index0;
393  next0 = ARP_TERM_NEXT_L2_OUTPUT;
395  to_next, n_left_to_next, pi0,
396  next0);
397  continue;
398 
399  check_ip6_nd:
400  /* IP6 ND event notification or solicitation handling to generate
401  local response instead of flooding */
402  iph0 = (ip6_header_t *) l3h0;
403  if (PREDICT_FALSE (ethertype0 == ETHERNET_TYPE_IP6 &&
404  iph0->protocol == IP_PROTOCOL_ICMP6 &&
406  (&iph0->src_address)))
407  {
408  sw_if_index0 = vnet_buffer (p0)->sw_if_index[VLIB_RX];
409  if (vnet_ip6_nd_term
410  (vm, node, p0, eth0, iph0, sw_if_index0,
411  vnet_buffer (p0)->l2.bd_index))
412  goto output_response;
413  }
414 
415  next_l2_feature:
416  {
418  L2INPUT_FEAT_ARP_TERM);
420  to_next, n_left_to_next,
421  pi0, next0);
422  continue;
423  }
424 
425  drop:
426  if (0 == arp0->ip4_over_ethernet[0].ip4.as_u32 ||
427  (arp0->ip4_over_ethernet[0].ip4.as_u32 ==
428  arp0->ip4_over_ethernet[1].ip4.as_u32))
429  {
430  error0 = ETHERNET_ARP_ERROR_gratuitous_arp;
431  }
432  next0 = ARP_TERM_NEXT_DROP;
433  p0->error = node->errors[error0];
434 
436  to_next, n_left_to_next, pi0,
437  next0);
438  }
439 
440  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
441  }
442 
443  vlib_error_count (vm, node->node_index,
444  ETHERNET_ARP_ERROR_replies_sent, n_replies_sent);
445  return frame->n_vectors;
446 }
447 
448 /* *INDENT-OFF* */
450  .function = arp_term_l2bd,
451  .name = "arp-term-l2bd",
452  .vector_size = sizeof (u32),
453  .n_errors = ETHERNET_ARP_N_ERROR,
454  .error_strings = ethernet_arp_error_strings,
455  .n_next_nodes = ARP_TERM_N_NEXT,
456  .next_nodes = {
457  [ARP_TERM_NEXT_L2_OUTPUT] = "l2-output",
458  [ARP_TERM_NEXT_DROP] = "error-drop",
459  },
460  .format_buffer = format_ethernet_arp_header,
461  .format_trace = format_arp_term_input_trace,
462 };
463 /* *INDENT-ON* */
464 
465 clib_error_t *
467 {
468  // Initialize the feature next-node indexes
470  arp_term_l2bd_node.index,
474  return 0;
475 }
476 
478 
479 /*
480  * fd.io coding-style-patch-verification: ON
481  *
482  * Local Variables:
483  * eval: (c-set-style "gnu")
484  * End:
485  */
ip6_address_is_link_local_unicast
static uword ip6_address_is_link_local_unicast(const ip6_address_t *a)
Definition: ip6_packet.h:253
arp_term_next_t
arp_term_next_t
Definition: l2_arp_term.c:39
api.h
ethernet_arp_header_t::opcode
u16 opcode
Definition: arp_packet.h:139
l2_bridge_domain_t
Definition: l2_bd.h:63
mac
vl_api_mac_address_t mac
Definition: l2.api:559
l2_arp_term_publish_v6_dp
static void l2_arp_term_publish_v6_dp(u32 sw_if_index, const ip6_address_t *addr, const mac_address_t *mac)
Definition: l2_arp_term.c:145
format_arp_term_input_trace
static u8 * format_arp_term_input_trace(u8 *s, va_list *va)
Definition: l2_arp_term.c:86
ICMP6_NEIGHBOR_ADVERTISEMENT_FLAG_OVERRIDE
#define ICMP6_NEIGHBOR_ADVERTISEMENT_FLAG_OVERRIDE
frame
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
Definition: nat44_ei.c:3048
l2_input_config_t
Definition: l2_input.h:42
arp_term_init
clib_error_t * arp_term_init(vlib_main_t *vm)
Definition: l2_arp_term.c:466
ip6_tcp_udp_icmp_compute_checksum
u16 ip6_tcp_udp_icmp_compute_checksum(vlib_main_t *vm, vlib_buffer_t *p0, ip6_header_t *ip0, int *bogus_lengthp)
Definition: ip6_forward.c:1098
l2input_main
l2input_main_t l2input_main
Definition: l2_input_node.c:78
clib_memcpy
#define clib_memcpy(d, s, n)
Definition: string.h:197
l2_arp_term_main_t_
Definition: l2_arp_term.h:34
next_index
nat44_ei_hairpin_src_next_t next_index
Definition: nat44_ei_hairpinning.c:412
l2input_main_t
Definition: l2_input.h:83
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
l2_arp_term_main
l2_arp_term_main_t l2_arp_term_main
Definition: l2_arp_term.c:33
format_ip6_header
format_function_t format_ip6_header
Definition: format.h:95
ip6_header_t::protocol
u8 protocol
Definition: ip6_packet.h:304
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
IP46_TYPE_IP4
@ IP46_TYPE_IP4
Definition: ip46_address.h:26
ethernet_arp_header_t::ip4_over_ethernet
ethernet_arp_ip4_over_ethernet_address_t ip4_over_ethernet[2]
Definition: arp_packet.h:142
ARP_TERM_N_NEXT
@ ARP_TERM_N_NEXT
Definition: l2_arp_term.c:43
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
ip6_address_is_unspecified
static uword ip6_address_is_unspecified(const ip6_address_t *a)
Definition: ip6_packet.h:237
l2_arp_term_set_publisher_node
void l2_arp_term_set_publisher_node(bool on)
Definition: l2_arp_term.c:103
L2_ARP_TERM_EVENT_PUBLISH
@ L2_ARP_TERM_EVENT_PUBLISH
Definition: l2_arp_term.h:31
addr
vhost_vring_addr_t addr
Definition: vhost_user.h:130
vlib_error_count
static void vlib_error_count(vlib_main_t *vm, uword node_index, uword counter, uword increment)
Definition: error_funcs.h:57
ip6_next_header
static void * ip6_next_header(ip6_header_t *i)
Definition: ip6_packet.h:407
vlib_frame_t
Definition: node.h:372
vlib_process_signal_event
static void vlib_process_signal_event(vlib_main_t *vm, uword node_index, uword type_opaque, uword data)
Definition: node_funcs.h:1019
clib_memcpy_fast
static_always_inline void * clib_memcpy_fast(void *restrict dst, const void *restrict src, size_t n)
Definition: string.h:92
l2_arp_term_publish_ctx_t_
Definition: l2_arp_term.h:21
ethernet_arp_input_trace_t::packet_data
u8 packet_data[64]
Definition: arp.c:109
ip6_packet.h
ARP_TERM_NEXT_L2_OUTPUT
@ ARP_TERM_NEXT_L2_OUTPUT
Definition: l2_arp_term.c:41
ethernet_mac_address_equal
static int ethernet_mac_address_equal(const u8 *a, const u8 *b)
Definition: mac_address.h:85
l2_bridge_domain_t::mac_by_ip4
uword * mac_by_ip4
Definition: l2_bd.h:101
ethernet_arp_header_t
Definition: arp_packet.h:133
l2_input_is_bvi
static bool l2_input_is_bvi(const l2_input_config_t *input)
Definition: l2_input.h:246
ip4_address_is_multicast
static uword ip4_address_is_multicast(const ip4_address_t *a)
Definition: ip4_packet.h:446
vlib_buffer_t::error
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:145
foreach_ethernet_arp_error
#define foreach_ethernet_arp_error
Definition: l2_arp_term.c:53
icmp6_input_trace_t
Definition: icmp6.h:62
vec_add1
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:606
vnet_ip6_nd_term
static int vnet_ip6_nd_term(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_buffer_t *p0, ethernet_header_t *eth, ip6_header_t *ip, u32 sw_if_index, u16 bd_index)
Definition: l2_arp_term.c:166
CLIB_UNUSED
#define CLIB_UNUSED(x)
Definition: clib.h:90
vnet_buffer
#define vnet_buffer(b)
Definition: buffer.h:437
vec_elt_at_index
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
Definition: vec_bootstrap.h:203
format.h
VLIB_NODE_FLAG_TRACE
#define VLIB_NODE_FLAG_TRACE
Definition: node.h:291
icmp6.h
ethernet_arp_input_trace_t
Definition: arp.c:107
PREDICT_FALSE
#define PREDICT_FALSE(x)
Definition: clib.h:124
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
uword
u64 uword
Definition: types.h:112
hash_get
#define hash_get(h, key)
Definition: hash.h:249
ethernet_header_t
Definition: packet.h:52
l2input_get_feat_names
char ** l2input_get_feat_names(void)
Return an array of strings containing graph node names of each feature.
Definition: l2_input.c:59
ICMP6_NEIGHBOR_ADVERTISEMENT_FLAG_SOLICITED
#define ICMP6_NEIGHBOR_ADVERTISEMENT_FLAG_SOLICITED
L2INPUT_N_FEAT
@ L2INPUT_N_FEAT
Definition: l2_input.h:163
IP46_TYPE_IP6
@ IP46_TYPE_IP6
Definition: ip46_address.h:27
vlib_node_registration_t
struct _vlib_node_registration vlib_node_registration_t
l2_input.h
vnet_l2_feature_next
static u32 vnet_l2_feature_next(vlib_buffer_t *b, u32 *next_nodes, u32 feat_bit)
Return the graph node index for the feature corresponding to the next set bit after clearing the curr...
Definition: feat_bitmap.h:94
ip4_packet.h
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
vlib_node_runtime_t::node_index
u32 node_index
Node index.
Definition: node.h:478
l2_arp_term.h
hash_get_mem
#define hash_get_mem(h, key)
Definition: hash.h:269
arp_term_next_node_index
u32 arp_term_next_node_index[32]
Definition: l2_arp_term.c:46
format
description fragment has unexpected format
Definition: map.api:433
vlib_put_next_frame
vlib_put_next_frame(vm, node, next_index, 0)
ethernet_address_cast
static uword ethernet_address_cast(const u8 *a)
Definition: packet.h:67
u32
unsigned int u32
Definition: types.h:88
ethernet_arp_reply_error_t
ethernet_arp_reply_error_t
Definition: l2_arp_term.c:71
VLIB_INIT_FUNCTION
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:172
ARP_TERM_NEXT_DROP
@ ARP_TERM_NEXT_DROP
Definition: l2_arp_term.c:42
ETHERNET_ARP_N_ERROR
@ ETHERNET_ARP_N_ERROR
Definition: l2_arp_term.c:76
ctx
long ctx[MAX_CONNS]
Definition: main.c:144
vl_api_rpc_call_main_thread
void vl_api_rpc_call_main_thread(void *fp, u8 *data, u32 data_length)
Definition: vlib_api.c:620
ethernet_arp_error_strings
static char * ethernet_arp_error_strings[]
Definition: l2_arp_term.c:79
l2_arp_term_main_t_::publish_events
l2_arp_term_publish_event_t * publish_events
Definition: l2_arp_term.h:38
vlib_node_get_runtime
static vlib_node_runtime_t * vlib_node_get_runtime(vlib_main_t *vm, u32 node_index)
Get node runtime by node index.
Definition: node_funcs.h:116
ip6_header_t
Definition: ip6_packet.h:294
ethernet_arp_header_t::l3_type
u16 l3_type
Definition: arp_packet.h:136
vrrp_prefix
static const u8 vrrp_prefix[]
Definition: l2_arp_term.c:31
mac_address_t_
Definition: mac_address.h:21
ethernet_arp_header_t::l2_type
u16 l2_type
Definition: arp_packet.h:135
ip6_header_t::src_address
ip6_address_t src_address
Definition: ip6_packet.h:310
vlib_main_t
Definition: main.h:102
arp_term_l2bd_node
static vlib_node_registration_t arp_term_l2bd_node
(constructor) VLIB_REGISTER_NODE (arp_term_l2bd_node)
Definition: l2_arp_term.c:449
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
vlib_get_main
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:38
u8
unsigned char u8
Definition: types.h:56
clib_error_t
Definition: clib_error.h:21
a
a
Definition: bitmap.h:544
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
feat_bitmap.h
ip
vl_api_address_t ip
Definition: l2.api:558
vlib_init_function_t
clib_error_t *() vlib_init_function_t(struct vlib_main_t *vm)
Definition: init.h:51
arp_packet.h
l2_arp_term_publish
static int l2_arp_term_publish(l2_arp_term_publish_event_t *ctx)
Definition: l2_arp_term.c:111
l2_arp_term_publish_v4_dp
static void l2_arp_term_publish_v4_dp(u32 sw_if_index, const ethernet_arp_ip4_over_ethernet_address_t *a)
Definition: l2_arp_term.c:125
ip6_icmp_input_node
vlib_node_registration_t ip6_icmp_input_node
(constructor) VLIB_REGISTER_NODE (ip6_icmp_input_node)
Definition: icmp6.c:240
l2_arp_term_publish_ctx_t_::sw_if_index
u32 sw_if_index
Definition: l2_arp_term.h:23
arp_term_l2bd
static uword arp_term_l2bd(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: l2_arp_term.c:242
vlib_node_runtime_t
Definition: node.h:454
l2_bridge_domain_t::mac_by_ip6
uword * mac_by_ip6
Definition: l2_bd.h:102
l2input_main_t::configs
l2_input_config_t * configs
Definition: l2_input.h:90
from
from
Definition: nat44_ei_hairpinning.c:415
l2_arp_term_process_node
vlib_node_registration_t l2_arp_term_process_node
(constructor) VLIB_REGISTER_NODE (l2_arp_term_process_node)
Definition: l2_api.c:1240
sw_if_index
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:34
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
ip6.h
format_ethernet_arp_header
u8 * format_ethernet_arp_header(u8 *s, va_list *va)
Definition: arp_packet.c:59
VLIB_TX
@ VLIB_TX
Definition: defs.h:47
n_left_from
n_left_from
Definition: nat44_ei_hairpinning.c:416
feat_bitmap_init_next_nodes
static void feat_bitmap_init_next_nodes(vlib_main_t *vm, u32 node_index, u32 num_features, char **feat_names, u32 *next_nodes)
Initialize the feature next-node indexes of a graph node.
Definition: feat_bitmap.h:43
l2input_main_t::bd_configs
l2_bridge_domain_t * bd_configs
Definition: l2_input.h:93
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
mac_address_from_bytes
static_always_inline void mac_address_from_bytes(mac_address_t *mac, const u8 *bytes)
Definition: mac_address.h:92
vlib_buffer_t
VLIB buffer representation.
Definition: buffer.h:111
VLIB_REGISTER_NODE
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
l2_arp_term_main_t_::publish
bool publish
Definition: l2_arp_term.h:36