X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fethernet%2Farp.c;h=da56c2b64cc42ef91afa6f1c5adb84cb3c67191d;hb=8b30e471df4d42214619e1d6c50cc8298426b45f;hp=08e91373b64ff9d709b89c813542e4bf28ee3c7e;hpb=1500254bee11355bbd69cc1dd9705be4f002f2bd;p=vpp.git diff --git a/src/vnet/ethernet/arp.c b/src/vnet/ethernet/arp.c index 08e91373b64..da56c2b64cc 100644 --- a/src/vnet/ethernet/arp.c +++ b/src/vnet/ethernet/arp.c @@ -92,6 +92,9 @@ typedef struct /* Proxy arp vector */ ethernet_proxy_arp_t *proxy_arps; + + uword wc_ip4_arp_publisher_node; + uword wc_ip4_arp_publisher_et; } ethernet_arp_main_t; static ethernet_arp_main_t ethernet_arp_main; @@ -106,6 +109,7 @@ typedef struct #define ETHERNET_ARP_ARGS_REMOVE (1<<0) #define ETHERNET_ARP_ARGS_FLUSH (1<<1) #define ETHERNET_ARP_ARGS_POPULATE (1<<2) +#define ETHERNET_ARP_ARGS_WC_PUB (1<<3) } vnet_arp_set_ip4_over_ethernet_rpc_args_t; static const u8 vrrp_prefix[] = { 0x00, 0x00, 0x5E, 0x00, 0x01 }; @@ -199,7 +203,7 @@ format_ethernet_arp_header (u8 * s, va_list * va) { ethernet_arp_header_t *a = va_arg (*va, ethernet_arp_header_t *); u32 max_header_bytes = va_arg (*va, u32); - uword indent; + u32 indent; u16 l2_type, l3_type; if (max_header_bytes != 0 && sizeof (a[0]) > max_header_bytes) @@ -451,8 +455,10 @@ arp_update_adjacency (vnet_main_t * vnm, u32 sw_if_index, u32 ai) switch (adj->lookup_next_index) { - case IP_LOOKUP_NEXT_ARP: case IP_LOOKUP_NEXT_GLEAN: + adj_glean_update_rewrite (ai); + break; + case IP_LOOKUP_NEXT_ARP: if (NULL != e) { adj_nbr_walk_nh4 (sw_if_index, @@ -523,7 +529,7 @@ arp_update_adjacency (vnet_main_t * vnm, u32 sw_if_index, u32 ai) } static void -arp_adj_fib_add (ethernet_arp_ip4_entry_t * e, uint32_t fib_index) +arp_adj_fib_add (ethernet_arp_ip4_entry_t * e, u32 fib_index) { fib_prefix_t pfx = { .fp_len = 32, @@ -540,7 +546,7 @@ arp_adj_fib_add (ethernet_arp_ip4_entry_t * e, uint32_t fib_index) fib_table_lock (fib_index, FIB_PROTOCOL_IP4, FIB_SOURCE_ADJ); } -int +static int vnet_arp_set_ip4_over_ethernet_internal (vnet_main_t * vnm, vnet_arp_set_ip4_over_ethernet_rpc_args_t * args) @@ -611,7 +617,7 @@ vnet_arp_set_ip4_over_ethernet_internal (vnet_main_t * vnm, */ if (0 == memcmp (e->ethernet_address, a->ethernet, sizeof (e->ethernet_address))) - return -1; + goto check_customers; /* Update time stamp and ethernet address. */ clib_memcpy (e->ethernet_address, a->ethernet, @@ -626,6 +632,7 @@ vnet_arp_set_ip4_over_ethernet_internal (vnet_main_t * vnm, adj_nbr_walk_nh4 (sw_if_index, &e->ip4_address, arp_mk_complete_walk, e); +check_customers: /* Customer(s) waiting for this address to be resolved? */ p = hash_get (am->pending_resolutions_by_address, a->ip4.as_u32); if (p) @@ -1118,6 +1125,12 @@ arp_input (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) &arp0->ip4_over_ethernet[0]); goto drop1; } + else if (arp0->opcode == + clib_host_to_net_u16 (ETHERNET_ARP_OPCODE_request) && + (dst_is_local0 == 0)) + { + goto drop1; + } send_reply: /* Send a reply. @@ -1507,6 +1520,52 @@ vnet_arp_populate_ip4_over_ethernet (vnet_main_t * vnm, return 0; } +/** + * @brief publish wildcard arp event + * @param sw_if_index The interface on which the ARP entires are acted + */ +static int +vnet_arp_wc_publish (u32 sw_if_index, void *a_arg) +{ + ethernet_arp_ip4_over_ethernet_address_t *a = a_arg; + vnet_arp_set_ip4_over_ethernet_rpc_args_t args = { + .flags = ETHERNET_ARP_ARGS_WC_PUB, + .sw_if_index = sw_if_index, + .a = *a + }; + + vl_api_rpc_call_main_thread (set_ip4_over_ethernet_rpc_callback, + (u8 *) & args, sizeof (args)); + return 0; +} + +static void +vnet_arp_wc_publish_internal (vnet_main_t * vnm, + vnet_arp_set_ip4_over_ethernet_rpc_args_t * + args) +{ + vlib_main_t *vm = vlib_get_main (); + ethernet_arp_main_t *am = ðernet_arp_main; + uword ni = am->wc_ip4_arp_publisher_node; + uword et = am->wc_ip4_arp_publisher_et; + + if (ni == (uword) ~ 0) + return; + wc_arp_report_t *r = + vlib_process_signal_event_data (vm, ni, et, 1, sizeof *r); + r->ip4 = args->a.ip4.as_u32; + r->sw_if_index = args->sw_if_index; + memcpy (r->mac, args->a.ethernet, sizeof r->mac); +} + +void +wc_arp_set_publisher_node (uword node_index, uword event_type) +{ + ethernet_arp_main_t *am = ðernet_arp_main; + am->wc_ip4_arp_publisher_node = node_index; + am->wc_ip4_arp_publisher_et = event_type; +} + /* * arp_add_del_interface_address * @@ -1568,7 +1627,7 @@ arp_add_del_interface_address (ip4_main_t * im, } void -arp_adj_fib_remove (ethernet_arp_ip4_entry_t * e, uint32_t fib_index) +arp_adj_fib_remove (ethernet_arp_ip4_entry_t * e, u32 fib_index) { if (FIB_NODE_INDEX_INVALID != e->fib_entry_index) { @@ -1652,6 +1711,7 @@ ethernet_arp_init (vlib_main_t * vm) am->pending_resolutions_by_address = hash_create (0, sizeof (uword)); am->mac_changes_by_address = hash_create (0, sizeof (uword)); + am->wc_ip4_arp_publisher_node = (uword) ~ 0; /* don't trace ARP error packets */ { @@ -1795,6 +1855,8 @@ set_ip4_over_ethernet_rpc_callback (vnet_arp_set_ip4_over_ethernet_rpc_args_t vnet_arp_flush_ip4_over_ethernet_internal (vm, a); else if (a->flags & ETHERNET_ARP_ARGS_POPULATE) vnet_arp_populate_ip4_over_ethernet_internal (vm, a); + else if (a->flags & ETHERNET_ARP_ARGS_WC_PUB) + vnet_arp_wc_publish_internal (vm, a); else vnet_arp_set_ip4_over_ethernet_internal (vm, a); } @@ -2277,31 +2339,9 @@ arp_term_l2bd (vlib_main_t * vm, /* Check if anyone want ARP request events for L2 BDs */ { - pending_resolution_t *mc; ethernet_arp_main_t *am = ðernet_arp_main; - uword *p = hash_get (am->mac_changes_by_address, 0); - if (p) - { - u32 next_index = p[0]; - while (next_index != (u32) ~ 0) - { - int (*fp) (u32, u8 *, u32, u32); - int rv = 1; - mc = pool_elt_at_index (am->mac_changes, next_index); - fp = mc->data_callback; - /* Call the callback, return 1 to suppress dup events */ - if (fp) - rv = (*fp) (mc->data, - arp0->ip4_over_ethernet[0].ethernet, - sw_if_index0, - arp0->ip4_over_ethernet[0].ip4.as_u32); - /* Signal the resolver process */ - if (rv == 0) - vlib_process_signal_event (vm, mc->node_index, - mc->type_opaque, mc->data); - next_index = mc->next_index; - } - } + if (am->wc_ip4_arp_publisher_node != (uword) ~ 0) + vnet_arp_wc_publish (sw_if_index0, &arp0->ip4_over_ethernet[0]); } /* lookup BD mac_by_ip4 hash table for MAC entry */ @@ -2449,9 +2489,11 @@ ethernet_arp_change_mac (u32 sw_if_index) change_arp_mac (sw_if_index, e); })); /* *INDENT-ON* */ + + adj_glean_update_rewrite (adj_glean_get (FIB_PROTOCOL_IP4, sw_if_index)); } -void static +void send_ip4_garp (vlib_main_t * vm, vnet_hw_interface_t * hi) { ip4_main_t *i4m = &ip4_main; @@ -2495,42 +2537,6 @@ send_ip4_garp (vlib_main_t * vm, vnet_hw_interface_t * hi) } } -static vlib_node_registration_t send_garp_na_proc_node; - -static uword -send_garp_na_process (vlib_main_t * vm, - vlib_node_runtime_t * rt, vlib_frame_t * f) -{ - vnet_main_t *vnm = vnet_get_main (); - uword event_type, *event_data = 0; - - send_garp_na_process_node_index = send_garp_na_proc_node.index; - - while (1) - { - vlib_process_wait_for_event (vm); - event_type = vlib_process_get_events (vm, &event_data); - if ((event_type == SEND_GARP_NA) && (vec_len (event_data) >= 1)) - { - u32 hw_if_index = event_data[0]; - vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index); - send_ip4_garp (vm, hi); - send_ip6_na (vm, hi); - } - vec_reset_length (event_data); - } - return 0; -} - - -/* *INDENT-OFF* */ -VLIB_REGISTER_NODE (send_garp_na_proc_node, static) = { - .function = send_garp_na_process, - .type = VLIB_NODE_TYPE_PROCESS, - .name = "send-garp-na-process", -}; -/* *INDENT-ON* */ - /* * fd.io coding-style-patch-verification: ON *