X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fethernet%2Farp.c;h=8f07fa55394d0724a8126da865b9db51fea166ef;hb=32e1c010b0c34fd0984f7fc45fae648a182025c5;hp=b388e778ac8aa2d7a256ba1a8e732bed306163e7;hpb=7cd468a3d7dee7d6c92f69a0bb7061ae208ec727;p=vpp.git diff --git a/src/vnet/ethernet/arp.c b/src/vnet/ethernet/arp.c index b388e778ac8..8f07fa55394 100644 --- a/src/vnet/ethernet/arp.c +++ b/src/vnet/ethernet/arp.c @@ -23,6 +23,7 @@ #include #include #include +#include #include /** @@ -438,33 +439,74 @@ arp_update_adjacency (vnet_main_t * vnm, u32 sw_if_index, u32 ai) arp_int = &am->ethernet_arp_by_sw_if_index[sw_if_index]; e = arp_entry_find (arp_int, &adj->sub_type.nbr.next_hop.ip4); - if (NULL != e) - { - adj_nbr_walk_nh4 (sw_if_index, - &e->ip4_address, arp_mk_complete_walk, e); - } - else + switch (adj->lookup_next_index) { + case IP_LOOKUP_NEXT_ARP: + case IP_LOOKUP_NEXT_GLEAN: + if (NULL != e) + { + adj_nbr_walk_nh4 (sw_if_index, + &e->ip4_address, arp_mk_complete_walk, e); + } + else + { + /* + * no matching ARP entry. + * construct the rewrite required to for an ARP packet, and stick + * that in the adj's pipe to smoke. + */ + adj_nbr_update_rewrite + (ai, + ADJ_NBR_REWRITE_FLAG_INCOMPLETE, + ethernet_build_rewrite + (vnm, + sw_if_index, + VNET_LINK_ARP, + VNET_REWRITE_FOR_SW_INTERFACE_ADDRESS_BROADCAST)); + + /* + * since the FIB has added this adj for a route, it makes sense it + * may want to forward traffic sometime soon. Let's send a + * speculative ARP. just one. If we were to do periodically that + * wouldn't be bad either, but that's more code than i'm prepared to + * write at this time for relatively little reward. + */ + arp_nbr_probe (adj); + } + break; + case IP_LOOKUP_NEXT_MCAST: /* - * no matching ARP entry. - * construct the rewire required to for an ARP packet, and stick - * that in the adj's pipe to smoke. + * Construct a partial rewrite from the known ethernet mcast dest MAC */ - adj_nbr_update_rewrite (ai, - ADJ_NBR_REWRITE_FLAG_INCOMPLETE, - ethernet_build_rewrite (vnm, - sw_if_index, - VNET_LINK_ARP, - VNET_REWRITE_FOR_SW_INTERFACE_ADDRESS_BROADCAST)); + adj_mcast_update_rewrite + (ai, + ethernet_build_rewrite (vnm, + sw_if_index, + adj->ia_link, + ethernet_ip4_mcast_dst_addr ())); /* - * since the FIB has added this adj for a route, it makes sense it may - * want to forward traffic sometime soon. Let's send a speculative ARP. - * just one. If we were to do periodically that wouldn't be bad either, - * but that's more code than i'm prepared to write at this time for - * relatively little reward. + * Complete the remaining fields of the adj's rewrite to direct the + * complete of the rewrite at switch time by copying in the IP + * dst address's bytes. + * Ofset is 11 bytes from the end of the MAC header - which is three + * bytes into the desintation address. And we write 3 bytes. */ - arp_nbr_probe (adj); + adj->rewrite_header.dst_mcast_offset = 11; + adj->rewrite_header.dst_mcast_n_bytes = 3; + + break; + + case IP_LOOKUP_NEXT_DROP: + case IP_LOOKUP_NEXT_PUNT: + case IP_LOOKUP_NEXT_LOCAL: + case IP_LOOKUP_NEXT_REWRITE: + case IP_LOOKUP_NEXT_LOAD_BALANCE: + case IP_LOOKUP_NEXT_MIDCHAIN: + case IP_LOOKUP_NEXT_ICMP_ERROR: + case IP_LOOKUP_N_NEXT: + ASSERT (0); + break; } } @@ -1043,12 +1085,25 @@ arp_input (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) src_flags = fib_entry_get_flags (src_fei); if (!((FIB_ENTRY_FLAG_ATTACHED & src_flags) || - (FIB_ENTRY_FLAG_CONNECTED & src_flags)) || - sw_if_index0 != fib_entry_get_resolving_interface (src_fei)) + (FIB_ENTRY_FLAG_CONNECTED & src_flags))) { + /* + * The packet was sent from an address that is not connected nor attached + * i.e. it is not from an address that is covered by a link's sub-net, + * nor is it a already learned host resp. + */ error0 = ETHERNET_ARP_ERROR_l3_src_address_not_local; goto drop2; } + if (sw_if_index0 != fib_entry_get_resolving_interface (src_fei)) + { + /* + * The interface the ARP was received on is not the interface + * on which the covering prefix is configured. Maybe this is a case + * for unnumbered. + */ + is_unnum0 = 1; + } /* Reject requests/replies with our local interface address. */ if (FIB_ENTRY_FLAG_LOCAL & src_flags)