From e2fe097424fb169dfe01421ff17b8ccd0c26b4a6 Mon Sep 17 00:00:00 2001 From: Neale Ranns Date: Thu, 26 Nov 2020 08:37:27 +0000 Subject: fib: Source Address Selection Type: feature Use the FIB to provide SAS (in so far as it is today) - Use the glean adjacency as the record of the connected prefixes = there's a glean per-{interface, protocol, connected-prefix} - Keep the glean up to date with whatever the recieve host prefix is (since it can change) Signed-off-by: Neale Ranns Change-Id: I0f3dd1edb1f3fc965af1c7c586709028eb9cdeac --- src/vnet/ip-neighbor/ip4_neighbor.c | 29 +++++++++++++-------------- src/vnet/ip-neighbor/ip4_neighbor.h | 2 +- src/vnet/ip-neighbor/ip6_neighbor.c | 22 +++++++++------------ src/vnet/ip-neighbor/ip6_neighbor.h | 15 +++++++------- src/vnet/ip-neighbor/ip_neighbor.c | 39 +++++++++++++------------------------ src/vnet/ip-neighbor/ip_neighbor.h | 3 ++- 6 files changed, 48 insertions(+), 62 deletions(-) (limited to 'src/vnet/ip-neighbor') diff --git a/src/vnet/ip-neighbor/ip4_neighbor.c b/src/vnet/ip-neighbor/ip4_neighbor.c index 7c0cbdcb2a2..c268b96e00d 100644 --- a/src/vnet/ip-neighbor/ip4_neighbor.c +++ b/src/vnet/ip-neighbor/ip4_neighbor.c @@ -40,23 +40,23 @@ #include #include #include +#include /** ARP throttling */ static throttle_t arp_throttle; void -ip4_neighbor_probe_dst (const ip_adjacency_t * adj, const ip4_address_t * dst) +ip4_neighbor_probe_dst (u32 sw_if_index, const ip4_address_t * dst) { - ip_interface_address_t *ia; - ip4_address_t *src; + ip4_address_t src; + adj_index_t ai; - src = ip4_interface_address_matching_destination - (&ip4_main, - &adj->sub_type.nbr.next_hop.ip4, adj->rewrite_header.sw_if_index, &ia); - if (!src) - return; + /* any glean will do, it's just for the rewrite */ + ai = adj_glean_get (FIB_PROTOCOL_IP4, sw_if_index, NULL); - ip4_neighbor_probe (vlib_get_main (), vnet_get_main (), adj, src, dst); + if (ADJ_INDEX_INVALID != ai && fib_sas4_get (sw_if_index, dst, &src)) + ip4_neighbor_probe (vlib_get_main (), + vnet_get_main (), adj_get (ai), &src, dst); } void @@ -67,11 +67,12 @@ ip4_neighbor_advertise (vlib_main_t * vm, vnet_hw_interface_t *hi = vnet_get_sup_hw_interface (vnm, sw_if_index); ip4_main_t *i4m = &ip4_main; u8 *rewrite, rewrite_len; + ip4_address_t tmp; if (NULL == addr) { - ip4_main_t *i4m = &ip4_main; - addr = ip4_interface_first_address (i4m, sw_if_index, 0); + fib_sas4_get (sw_if_index, NULL, &tmp); + addr = &tmp; } if (addr) @@ -122,8 +123,6 @@ ip4_arp_inline (vlib_main_t * vm, vlib_frame_t * frame, int is_glean) { vnet_main_t *vnm = vnet_get_main (); - ip4_main_t *im = &ip4_main; - ip_lookup_main_t *lm = &im->lookup_main; u32 *from, *to_next_drop; uword n_left_from, n_left_to_next_drop, next_index; u32 thread_index = vm->thread_index; @@ -171,14 +170,14 @@ ip4_arp_inline (vlib_main_t * vm, /* resolve the packet's destination */ ip4_header_t *ip0 = vlib_buffer_get_current (p0); resolve0 = ip0->dst_address; - src0 = adj0->sub_type.glean.receive_addr.ip4; + src0 = adj0->sub_type.glean.rx_pfx.fp_addr.ip4; } else { /* resolve the incomplete adj */ resolve0 = adj0->sub_type.nbr.next_hop.ip4; /* Src IP address in ARP header. */ - if (ip4_src_address_for_packet (lm, sw_if_index0, &src0)) + if (!fib_sas4_get (sw_if_index0, &resolve0, &src0)) { /* No source address available */ p0->error = node->errors[IP4_ARP_ERROR_NO_SOURCE_ADDRESS]; diff --git a/src/vnet/ip-neighbor/ip4_neighbor.h b/src/vnet/ip-neighbor/ip4_neighbor.h index c52e2d446af..8805beadf23 100644 --- a/src/vnet/ip-neighbor/ip4_neighbor.h +++ b/src/vnet/ip-neighbor/ip4_neighbor.h @@ -19,7 +19,7 @@ #include #include -extern void ip4_neighbor_probe_dst (const ip_adjacency_t * adj, +extern void ip4_neighbor_probe_dst (u32 sw_if_index, const ip4_address_t * dst); extern void ip4_neighbor_advertise (vlib_main_t * vm, vnet_main_t * vnm, diff --git a/src/vnet/ip-neighbor/ip6_neighbor.c b/src/vnet/ip-neighbor/ip6_neighbor.c index ca67d85778d..478eca7fa27 100644 --- a/src/vnet/ip-neighbor/ip6_neighbor.c +++ b/src/vnet/ip-neighbor/ip6_neighbor.c @@ -17,23 +17,19 @@ #include #include +#include /** ND throttling */ static throttle_t nd_throttle; void -ip6_neighbor_probe_dst (const ip_adjacency_t * adj, const ip6_address_t * dst) +ip6_neighbor_probe_dst (u32 sw_if_index, const ip6_address_t * dst) { - ip_interface_address_t *ia; - ip6_address_t *src; + ip6_address_t src; - src = ip6_interface_address_matching_destination - (&ip6_main, dst, adj->rewrite_header.sw_if_index, &ia); - - if (!src) - return; - - ip6_neighbor_probe (vlib_get_main (), vnet_get_main (), adj, src, dst); + if (fib_sas6_get (sw_if_index, dst, &src)) + ip6_neighbor_probe (vlib_get_main (), vnet_get_main (), + sw_if_index, &src, dst); } void @@ -210,15 +206,15 @@ ip6_discover_neighbor_inline (vlib_main_t * vm, * Choose source address based on destination lookup * adjacency. */ - if (!ip6_src_address_for_packet (sw_if_index0, - &ip0->dst_address, &src)) + if (!fib_sas6_get (sw_if_index0, &ip0->dst_address, &src)) { /* There is no address on the interface */ p0->error = node->errors[IP6_NBR_ERROR_NO_SOURCE_ADDRESS]; continue; } - b0 = ip6_neighbor_probe (vm, vnm, adj0, &src, &ip0->dst_address); + b0 = ip6_neighbor_probe (vm, vnm, sw_if_index0, + &src, &ip0->dst_address); if (PREDICT_TRUE (NULL != b0)) { diff --git a/src/vnet/ip-neighbor/ip6_neighbor.h b/src/vnet/ip-neighbor/ip6_neighbor.h index 7f76efd2c86..681e634861c 100644 --- a/src/vnet/ip-neighbor/ip6_neighbor.h +++ b/src/vnet/ip-neighbor/ip6_neighbor.h @@ -34,17 +34,18 @@ extern void ip6_neighbor_advertise (vlib_main_t * vm, u32 sw_if_index, const ip6_address_t * addr); -extern void ip6_neighbor_probe_dst (const ip_adjacency_t * adj, +extern void ip6_neighbor_probe_dst (u32 sw_if_index, const ip6_address_t * dst); always_inline vlib_buffer_t * ip6_neighbor_probe (vlib_main_t * vm, vnet_main_t * vnm, - const ip_adjacency_t * adj, + u32 sw_if_index, const ip6_address_t * src, const ip6_address_t * dst) { icmp6_neighbor_solicitation_header_t *h0; vnet_hw_interface_t *hw_if0; + const ip_adjacency_t *adj; vlib_buffer_t *b0; int bogus_length; u32 bi0 = 0; @@ -52,17 +53,17 @@ ip6_neighbor_probe (vlib_main_t * vm, h0 = vlib_packet_template_get_packet (vm, &ip6_neighbor_packet_template, &bi0); if (!h0) - return NULL;; + return NULL; /* if the interface has been disabled for ip6, later steps to retrieve * an adjacency will result in a segv. */ - if (!ip6_link_is_enabled (adj->rewrite_header.sw_if_index)) + if (!ip6_link_is_enabled (sw_if_index)) return NULL; b0 = vlib_get_buffer (vm, bi0); - hw_if0 = vnet_get_sup_hw_interface (vnm, adj->rewrite_header.sw_if_index); + hw_if0 = vnet_get_sup_hw_interface (vnm, sw_if_index); /* * Destination address is a solicited node multicast address. @@ -87,11 +88,11 @@ ip6_neighbor_probe (vlib_main_t * vm, ASSERT (bogus_length == 0); VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b0); - vnet_buffer (b0)->sw_if_index[VLIB_TX] = adj->rewrite_header.sw_if_index; + vnet_buffer (b0)->sw_if_index[VLIB_TX] = sw_if_index; /* Use the link's mcast adj to ship the packet */ vnet_buffer (b0)->ip.adj_index[VLIB_TX] = - ip6_link_get_mcast_adj (adj->rewrite_header.sw_if_index); + ip6_link_get_mcast_adj (sw_if_index); adj = adj_get (vnet_buffer (b0)->ip.adj_index[VLIB_TX]); b0->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED; diff --git a/src/vnet/ip-neighbor/ip_neighbor.c b/src/vnet/ip-neighbor/ip_neighbor.c index 5786775dc98..2dd8e748be6 100644 --- a/src/vnet/ip-neighbor/ip_neighbor.c +++ b/src/vnet/ip-neighbor/ip_neighbor.c @@ -1011,22 +1011,19 @@ ip_neighbor_register (ip_address_family_t af, const ip_neighbor_vft_t * vft) } void -ip_neighbor_probe_dst (const ip_adjacency_t * adj, const ip46_address_t * dst) +ip_neighbor_probe_dst (u32 sw_if_index, + ip_address_family_t af, const ip46_address_t * dst) { - if (!vnet_sw_interface_is_admin_up (vnet_get_main (), - adj->rewrite_header.sw_if_index)) + if (!vnet_sw_interface_is_admin_up (vnet_get_main (), sw_if_index)) return; - switch (adj->ia_nh_proto) + switch (af) { - case FIB_PROTOCOL_IP6: - ip6_neighbor_probe_dst (adj, &dst->ip6); + case AF_IP6: + ip6_neighbor_probe_dst (sw_if_index, &dst->ip6); break; - case FIB_PROTOCOL_IP4: - ip4_neighbor_probe_dst (adj, &dst->ip4); - break; - case FIB_PROTOCOL_MPLS: - ASSERT (0); + case AF_IP4: + ip4_neighbor_probe_dst (sw_if_index, &dst->ip4); break; } } @@ -1034,7 +1031,9 @@ ip_neighbor_probe_dst (const ip_adjacency_t * adj, const ip46_address_t * dst) void ip_neighbor_probe (const ip_adjacency_t * adj) { - ip_neighbor_probe_dst (adj, &adj->sub_type.nbr.next_hop); + ip_neighbor_probe_dst (adj->rewrite_header.sw_if_index, + ip_address_family_from_fib_proto (adj->ia_nh_proto), + &adj->sub_type.nbr.next_hop); } void @@ -1147,7 +1146,6 @@ ip_neighbor_ethernet_change_mac (ethernet_main_t * em, u32 sw_if_index, uword opaque) { ip_neighbor_t *ipn; - adj_index_t ai; IP_NEIGHBOR_DBG ("mac-change: %U", format_vnet_sw_if_index_name, vnet_get_main (), @@ -1165,10 +1163,7 @@ ip_neighbor_ethernet_change_mac (ethernet_main_t * em, })); /* *INDENT-ON* */ - ai = adj_glean_get (FIB_PROTOCOL_IP4, sw_if_index); - - if (ADJ_INDEX_INVALID != ai) - adj_glean_update_rewrite (ai); + adj_glean_update_rewrite_itf (sw_if_index); } void @@ -1543,14 +1538,8 @@ ip_neighbour_age_out (index_t ipni, f64 now, f64 * wait) } else { - adj_index_t ai; - - ai = adj_glean_get (ip_address_family_to_fib_proto (af), - ip_neighbor_get_sw_if_index (ipn)); - - if (ADJ_INDEX_INVALID != ai) - ip_neighbor_probe_dst (adj_get (ai), - &ip_addr_46 (&ipn->ipn_key->ipnk_ip)); + ip_neighbor_probe_dst (ip_neighbor_get_sw_if_index (ipn), + af, &ip_addr_46 (&ipn->ipn_key->ipnk_ip)); ipn->ipn_n_probes++; *wait = 1; diff --git a/src/vnet/ip-neighbor/ip_neighbor.h b/src/vnet/ip-neighbor/ip_neighbor.h index 419c49491a3..064569b56ce 100644 --- a/src/vnet/ip-neighbor/ip_neighbor.h +++ b/src/vnet/ip-neighbor/ip_neighbor.h @@ -54,7 +54,8 @@ extern void ip_neighbor_learn (const ip_neighbor_learn_t * l); extern void ip_neighbor_update (vnet_main_t * vnm, adj_index_t ai); extern void ip_neighbor_probe (const ip_adjacency_t * adj); -extern void ip_neighbor_probe_dst (const ip_adjacency_t * adj, +extern void ip_neighbor_probe_dst (u32 sw_if_index, + ip_address_family_t af, const ip46_address_t * ip); extern void ip_neighbor_mark (ip_address_family_t af); -- cgit 1.2.3-korg