aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/ip-neighbor
diff options
context:
space:
mode:
authorNeale Ranns <neale.ranns@cisco.com>2020-11-26 08:37:27 +0000
committerOle Tr�an <otroan@employees.org>2020-12-08 09:00:24 +0000
commite2fe097424fb169dfe01421ff17b8ccd0c26b4a6 (patch)
tree2d9993f78d9165c1aba23b1daa4067106da81b45 /src/vnet/ip-neighbor
parent9b8cb5082471dd670066b8ba2872ffbcc35a87f8 (diff)
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 <neale.ranns@cisco.com> Change-Id: I0f3dd1edb1f3fc965af1c7c586709028eb9cdeac
Diffstat (limited to 'src/vnet/ip-neighbor')
-rw-r--r--src/vnet/ip-neighbor/ip4_neighbor.c29
-rw-r--r--src/vnet/ip-neighbor/ip4_neighbor.h2
-rw-r--r--src/vnet/ip-neighbor/ip6_neighbor.c22
-rw-r--r--src/vnet/ip-neighbor/ip6_neighbor.h15
-rw-r--r--src/vnet/ip-neighbor/ip_neighbor.c39
-rw-r--r--src/vnet/ip-neighbor/ip_neighbor.h3
6 files changed, 48 insertions, 62 deletions
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 <vnet/ip-neighbor/ip4_neighbor.h>
#include <vnet/ethernet/ethernet.h>
#include <vnet/util/throttle.h>
+#include <vnet/fib/fib_sas.h>
/** 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 <vnet/ip/ip.h>
#include <vnet/ethernet/arp_packet.h>
-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 <vnet/ip-neighbor/ip6_neighbor.h>
#include <vnet/util/throttle.h>
+#include <vnet/fib/fib_sas.h>
/** 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);