From c9d7f8c0126b7b078b06f36096a2b3bbbc1f63b4 Mon Sep 17 00:00:00 2001 From: Stephen Worley Date: Tue, 24 Mar 2020 17:10:08 -0400 Subject: [PATCH 1/2] zebra: abstract route src determiniation into func Abstraction the route src determination from a nexthop in the netlink code into a function for both singlepath and mutlipath to call. Signed-off-by: Stephen Worley (cherry picked from commit 762288f50f5fa29512864fcc7814be83e1b58ff4) --- zebra/rt_netlink.c | 81 ++++++++++++++++------------------------------ 1 file changed, 28 insertions(+), 53 deletions(-) diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 705536595b..dcaf2155f0 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -1513,6 +1513,30 @@ static int netlink_neigh_update(int cmd, int ifindex, uint32_t addr, char *lla, 0); } +static bool nexthop_set_src(const struct nexthop *nexthop, int family, + union g_addr *src) +{ + if (family == AF_INET) { + if (nexthop->rmap_src.ipv4.s_addr != INADDR_ANY) { + src->ipv4 = nexthop->rmap_src.ipv4; + return true; + } else if (nexthop->src.ipv4.s_addr != INADDR_ANY) { + src->ipv4 = nexthop->src.ipv4; + return true; + } + } else if (family == AF_INET6) { + if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->rmap_src.ipv6)) { + src->ipv6 = nexthop->rmap_src.ipv6; + return true; + } else if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->src.ipv6)) { + src->ipv6 = nexthop->src.ipv6; + return true; + } + } + + return false; +} + /* * Routing table change via netlink interface, using a dataplane context object */ @@ -1523,7 +1547,7 @@ static int netlink_route_multipath(int cmd, struct zebra_dplane_ctx *ctx) unsigned int nexthop_num; int family; const char *routedesc; - int setsrc = 0; + bool setsrc = false; union g_addr src; const struct prefix *p, *src_p; uint32_t table_id; @@ -1689,32 +1713,8 @@ static int netlink_route_multipath(int cmd, struct zebra_dplane_ctx *ctx) if (setsrc) continue; - if (family == AF_INET) { - if (nexthop->rmap_src.ipv4.s_addr - != 0) { - src.ipv4 = - nexthop->rmap_src.ipv4; - setsrc = 1; - } else if (nexthop->src.ipv4.s_addr - != 0) { - src.ipv4 = - nexthop->src.ipv4; - setsrc = 1; - } - } else if (family == AF_INET6) { - if (!IN6_IS_ADDR_UNSPECIFIED( - &nexthop->rmap_src.ipv6)) { - src.ipv6 = - nexthop->rmap_src.ipv6; - setsrc = 1; - } else if ( - !IN6_IS_ADDR_UNSPECIFIED( - &nexthop->src.ipv6)) { - src.ipv6 = - nexthop->src.ipv6; - setsrc = 1; - } - } + setsrc = nexthop_set_src(nexthop, family, &src); + continue; } @@ -1757,32 +1757,7 @@ static int netlink_route_multipath(int cmd, struct zebra_dplane_ctx *ctx) if (setsrc) continue; - if (family == AF_INET) { - if (nexthop->rmap_src.ipv4.s_addr - != 0) { - src.ipv4 = - nexthop->rmap_src.ipv4; - setsrc = 1; - } else if (nexthop->src.ipv4.s_addr - != 0) { - src.ipv4 = - nexthop->src.ipv4; - setsrc = 1; - } - } else if (family == AF_INET6) { - if (!IN6_IS_ADDR_UNSPECIFIED( - &nexthop->rmap_src.ipv6)) { - src.ipv6 = - nexthop->rmap_src.ipv6; - setsrc = 1; - } else if ( - !IN6_IS_ADDR_UNSPECIFIED( - &nexthop->src.ipv6)) { - src.ipv6 = - nexthop->src.ipv6; - setsrc = 1; - } - } + setsrc = nexthop_set_src(nexthop, family, &src); continue; } From e85c67d05decf340dcf5663a48c652719d04387f Mon Sep 17 00:00:00 2001 From: Stephen Worley Date: Tue, 24 Mar 2020 17:32:21 -0400 Subject: [PATCH 2/2] zebra: determine src when using nexthop objects Determine src based on nexthop data even when we are using kernel nexthop objects. Before, we were entirely skipping this step and just sending the nexthop ID, ignoring src determination. Signed-off-by: Stephen Worley (cherry picked from commit d8bfd8dc9a899f841967257a6b5f30910fdc17c8) --- zebra/rt_netlink.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index dcaf2155f0..ee8ef6558f 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -1666,6 +1666,23 @@ static int netlink_route_multipath(int cmd, struct zebra_dplane_ctx *ctx) /* Kernel supports nexthop objects */ addattr32(&req.n, sizeof(req), RTA_NH_ID, dplane_ctx_get_nhe_id(ctx)); + + /* Have to determine src still */ + for (ALL_NEXTHOPS_PTR(dplane_ctx_get_ng(ctx), nexthop)) { + if (setsrc) + break; + + setsrc = nexthop_set_src(nexthop, family, &src); + } + + if (setsrc) { + if (family == AF_INET) + addattr_l(&req.n, sizeof(req), RTA_PREFSRC, + &src.ipv4, bytelen); + else if (family == AF_INET6) + addattr_l(&req.n, sizeof(req), RTA_PREFSRC, + &src.ipv6, bytelen); + } goto skip; }