From 98874cda5853ea2d6b2dc32001b935d394b88430 Mon Sep 17 00:00:00 2001 From: Július Milan Date: Tue, 16 Feb 2021 19:20:47 +0100 Subject: fib: fix sa selection for fib routed destinations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The move from ip4(6)_src_address_for_packet to fib_sas4(6)_get changed the behavior, so that the new looked only to adjacent gleans. This caused a problem for destinations routed according to FIB table. To reproduce: vpp# create tap vpp# set interface state tap0 up vpp# set interface ip address tap0 192.168.11.1/24 vpp# ip route add 192.168.20.0/24 via 192.168.11.2 linux$ sudo ip addr add 192.168.20.1/24 dev lo linux$ sudo ip link set tap0 up linux$ sudo ip addr add 192.168.11.2/24 dev tap0 vpp# ping 192.168.20.1 Failed: no source address for egress interface Type: fix Signed-off-by: Július Milan Signed-off-by: Neale Ranns Change-Id: I22899f4dbbf8c1c85ccce72f801b92c183195b5d --- src/vnet/adj/adj_glean.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'src/vnet/adj/adj_glean.c') diff --git a/src/vnet/adj/adj_glean.c b/src/vnet/adj/adj_glean.c index e956318a1ff..8df104bd19d 100644 --- a/src/vnet/adj/adj_glean.c +++ b/src/vnet/adj/adj_glean.c @@ -258,8 +258,8 @@ adj_glean_get_src (fib_protocol_t proto, u32 sw_if_index, const ip46_address_t *nh) { + const ip46_address_t *conn, *source; const ip_adjacency_t *adj; - ip46_address_t *conn; adj_index_t ai; if (vec_len(adj_gleans[proto]) <= sw_if_index || @@ -274,23 +274,33 @@ adj_glean_get_src (fib_protocol_t proto, if (nh) pfx.fp_addr = *nh; + /* + * An interface can have more than one glean address. Where + * possible we want to return a source address from the same + * subnet as the destination. If this is not possible then any address + * will do. + */ + source = NULL; + hash_foreach_mem(conn, ai, adj_gleans[proto][sw_if_index], ({ adj = adj_get(ai); if (adj->sub_type.glean.rx_pfx.fp_len > 0) { + source = &adj->sub_type.glean.rx_pfx.fp_addr; + /* if no destination is specified use the just glean */ if (NULL == nh) - return (&adj->sub_type.glean.rx_pfx.fp_addr); + return (source); /* check the clean covers the desintation */ if (fib_prefix_is_cover(&adj->sub_type.glean.rx_pfx, &pfx)) - return (&adj->sub_type.glean.rx_pfx.fp_addr); + return (source); } })); - return (NULL); + return (source); } void -- cgit 1.2.3-korg