summaryrefslogtreecommitdiffstats
path: root/src/vnet/ethernet/arp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/ethernet/arp.c')
-rw-r--r--src/vnet/ethernet/arp.c84
1 files changed, 63 insertions, 21 deletions
diff --git a/src/vnet/ethernet/arp.c b/src/vnet/ethernet/arp.c
index 0298541bb46..8f07fa55394 100644
--- a/src/vnet/ethernet/arp.c
+++ b/src/vnet/ethernet/arp.c
@@ -23,6 +23,7 @@
#include <vppinfra/mhash.h>
#include <vnet/fib/ip4_fib.h>
#include <vnet/adj/adj_nbr.h>
+#include <vnet/adj/adj_mcast.h>
#include <vnet/mpls/mpls.h>
/**
@@ -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;
}
}