49 #define foreach_ethernet_arp_error \ 50 _ (replies_sent, "ARP replies sent") \ 51 _ (l2_type_not_ethernet, "L2 type not ethernet") \ 52 _ (l3_type_not_ip4, "L3 type not IP4") \ 53 _ (l3_src_address_not_local, "IP4 source address not local to subnet") \ 54 _ (l3_dst_address_not_local, "IP4 destination address not local to subnet") \ 55 _ (l3_dst_address_unset, "IP4 destination address is unset") \ 56 _ (l3_src_address_is_local, "IP4 source address matches local interface") \ 57 _ (l3_src_address_learned, "ARP request IP4 source address learned") \ 58 _ (replies_received, "ARP replies received") \ 59 _ (opcode_not_request, "ARP opcode not request") \ 60 _ (proxy_arp_replies_sent, "Proxy ARP replies sent") \ 61 _ (l2_address_mismatch, "ARP hw addr does not match L2 frame src addr") \ 62 _ (gratuitous_arp, "ARP probe or announcement dropped") \ 63 _ (interface_no_table, "Interface is not mapped to an IP table") \ 64 _ (interface_not_ip_enabled, "Interface is not IP enabled") \ 65 _ (unnumbered_mismatch, "RX interface is unnumbered to different subnet") \ 69 #define _(sym,string) ETHERNET_ARP_ERROR_##sym, 76 #define _(sym,string) string, 122 const ethernet_arp_ip4_over_ethernet_address_t *
a)
168 icmp6_neighbor_solicitation_or_advertisement_header_t *ndh;
173 if (ndh->icmp.type != ICMP6_neighbor_solicitation &&
174 ndh->icmp.type != ICMP6_neighbor_advertisement)
178 (p0->
flags & VLIB_BUFFER_IS_TRACED)))
192 if (ndh->icmp.type == ICMP6_neighbor_solicitation)
194 icmp6_neighbor_discovery_ethernet_link_layer_address_option_t *opt;
198 opt = (
void *) (ndh + 1);
199 if ((opt->header.type !=
200 ICMP6_NEIGHBOR_DISCOVERY_OPTION_source_link_layer_address) ||
201 (opt->header.n_data_u64s != 1))
216 ICMP6_NEIGHBOR_DISCOVERY_OPTION_target_link_layer_address;
218 ndh->icmp.type = ICMP6_neighbor_advertisement;
219 ndh->advertisement_flags = clib_host_to_net_u32
222 ndh->icmp.checksum = 0;
228 ICMP6_ERROR_NEIGHBOR_ADVERTISEMENTS_TX, 1);
242 u32 n_left_from, next_index, *from, *to_next;
243 u32 n_replies_sent = 0;
244 u16 last_bd_index = ~0;
252 while (n_left_from > 0)
258 while (n_left_from > 0 && n_left_to_next > 0)
265 u32 pi0, error0, next0, sw_if_index0;
281 goto next_l2_feature;
285 ethertype0 = clib_net_to_host_u16 (*(
u16 *) (l3h0 - 2));
288 if (ethertype0 != ETHERNET_TYPE_ARP)
292 clib_host_to_net_u16 (ETHERNET_ARP_OPCODE_request)) &&
294 clib_host_to_net_u16 (ETHERNET_ARP_OPCODE_reply)))
299 (p0->
flags & VLIB_BUFFER_IS_TRACED)))
310 clib_net_to_host_u16 (ETHERNET_ARP_HARDWARE_TYPE_ethernet)
311 ? ETHERNET_ARP_ERROR_l2_type_not_ethernet : error0);
314 clib_net_to_host_u16 (ETHERNET_TYPE_IP4) ?
315 ETHERNET_ARP_ERROR_l3_type_not_ip4 : error0);
334 error0 = ETHERNET_ARP_ERROR_l2_address_mismatch;
341 error0 = ETHERNET_ARP_ERROR_l3_src_address_not_local;
353 || (last_bd_index == (
u16) ~ 0)))
355 last_bd_index = bd_index0;
361 goto next_l2_feature;
364 goto next_l2_feature;
368 arp0->
opcode = clib_host_to_net_u16 (ETHERNET_ARP_OPCODE_reply);
382 vnet_buffer (p0)->l2.feature_bitmap |= L2INPUT_FEAT_FWD;
384 goto next_l2_feature;
391 to_next, n_left_to_next, pi0,
400 iph0->
protocol == IP_PROTOCOL_ICMP6 &&
406 (vm, node, p0, eth0, iph0, sw_if_index0,
408 goto output_response;
414 L2INPUT_FEAT_ARP_TERM);
416 to_next, n_left_to_next,
426 error0 = ETHERNET_ARP_ERROR_gratuitous_arp;
432 to_next, n_left_to_next, pi0,
440 ETHERNET_ARP_ERROR_replies_sent, n_replies_sent);
447 .name =
"arp-term-l2bd",
448 .vector_size =
sizeof (
u32),
#define ICMP6_NEIGHBOR_ADVERTISEMENT_FLAG_SOLICITED
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index, VLIB_BUFFER_IS_TRACED: trace this buffer.
l2_input_config_t * configs
vlib_node_registration_t l2_arp_term_process_node
(constructor) VLIB_REGISTER_NODE (l2_arp_term_process_node)
l2_arp_term_publish_event_t * publish_events
static void vlib_error_count(vlib_main_t *vm, uword node_index, uword counter, uword increment)
#define clib_memcpy_fast(a, b, c)
clib_error_t * arp_term_init(vlib_main_t *vm)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
void l2_arp_term_set_publisher_node(bool on)
#define foreach_ethernet_arp_error
static uword ip4_address_is_multicast(const ip4_address_t *a)
static void l2_arp_term_publish_v6_dp(u32 sw_if_index, const ip6_address_t *addr, const mac_address_t *mac)
vlib_error_t * errors
Vector of errors for this node.
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...
#define clib_memcpy(d, s, n)
vl_api_interface_index_t sw_if_index
#define VLIB_INIT_FUNCTION(x)
static uword ethernet_address_cast(u8 *a)
#define ICMP6_NEIGHBOR_ADVERTISEMENT_FLAG_OVERRIDE
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
void vl_api_rpc_call_main_thread(void *fp, u8 *data, u32 data_length)
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)
vlib_error_t error
Error code for buffers to be enqueued to error handler.
static_always_inline void mac_address_from_bytes(mac_address_t *mac, const u8 *bytes)
static void vlib_process_signal_event(vlib_main_t *vm, uword node_index, uword type_opaque, uword data)
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
u32 node_index
Node index.
#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.
#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).
ethernet_arp_reply_error_t
vlib_node_registration_t ip6_icmp_input_node
(constructor) VLIB_REGISTER_NODE (ip6_icmp_input_node)
#define VLIB_REGISTER_NODE(x,...)
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.
static int ethernet_mac_address_equal(const u8 *a, const u8 *b)
static vlib_node_runtime_t * vlib_node_get_runtime(vlib_main_t *vm, u32 node_index)
Get node runtime by node index.
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
Release pointer to next frame vector data.
static vlib_node_registration_t arp_term_l2bd_node
(constructor) VLIB_REGISTER_NODE (arp_term_l2bd_node)
vlib_main_t vlib_node_runtime_t * node
static void * ip6_next_header(ip6_header_t *i)
u16 ip6_tcp_udp_icmp_compute_checksum(vlib_main_t *vm, vlib_buffer_t *p0, ip6_header_t *ip0, int *bogus_lengthp)
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
static const u8 vrrp_prefix[]
static uword ip6_address_is_link_local_unicast(const ip6_address_t *a)
static vlib_main_t * vlib_get_main(void)
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
VLIB buffer representation.
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
static uword arp_term_l2bd(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
u32 arp_term_next_node_index[32]
l2_bridge_domain_t * bd_configs
#define hash_get_mem(h, key)
u8 * format_ethernet_arp_header(u8 *s, va_list *va)
static uword ip6_address_is_unspecified(const ip6_address_t *a)
static char * ethernet_arp_error_strings[]
static u8 * format_arp_term_input_trace(u8 *s, va_list *va)
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
u16 flags
Copy of main node flags.
static void l2_arp_term_publish_v4_dp(u32 sw_if_index, const ethernet_arp_ip4_over_ethernet_address_t *a)
#define VLIB_NODE_FLAG_TRACE
l2_arp_term_main_t l2_arp_term_main
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
static int l2_arp_term_publish(l2_arp_term_publish_event_t *ctx)