zebra: Add afi value for all nexthops sent/received

Since nexthops are always going to need to be address family
specific unless they are only a group, we have to address
this when we receive and send them.

Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com>
This commit is contained in:
Stephen Worley 2019-03-20 13:03:22 -04:00
parent 77b76fc900
commit e8b0e4201e

View File

@ -1910,30 +1910,30 @@ static int netlink_nexthop(int cmd, struct zebra_dplane_ctx *ctx)
// TODO: IF not a group // TODO: IF not a group
const struct nexthop_group nhg = nhe->nhg; const struct nexthop_group nhg = nhe->nhg;
const struct nexthop *nh = nhg.nexthop; const struct nexthop *nh = nhg.nexthop;
const struct prefix *dest_p;
unsigned char family = 0; if (nhe->afi == AFI_IP)
req.nhm.nh_family = AF_INET;
else if (nhe->afi == AFI_IP6)
req.nhm.nh_family = AF_INET6;
switch (nh->type) { switch (nh->type) {
// TODO: Need AF for just index also // TODO: Need AF for just index also
// just use dest? // just use dest?
case NEXTHOP_TYPE_IFINDEX:
dest_p = dplane_ctx_get_dest(ctx);
family = PREFIX_FAMILY(dest_p);
break;
case NEXTHOP_TYPE_IPV4_IFINDEX: case NEXTHOP_TYPE_IPV4_IFINDEX:
family = AF_INET;
addattr_l(&req.n, sizeof(req), NHA_GATEWAY, addattr_l(&req.n, sizeof(req), NHA_GATEWAY,
&nh->gate.ipv4, IPV4_MAX_BYTELEN); &nh->gate.ipv4, IPV4_MAX_BYTELEN);
break; break;
case NEXTHOP_TYPE_IPV6_IFINDEX: case NEXTHOP_TYPE_IPV6_IFINDEX:
family = AF_INET6;
addattr_l(&req.n, sizeof(req), NHA_GATEWAY, addattr_l(&req.n, sizeof(req), NHA_GATEWAY,
&nh->gate.ipv6, IPV6_MAX_BYTELEN); &nh->gate.ipv6, IPV6_MAX_BYTELEN);
break; break;
case NEXTHOP_TYPE_BLACKHOLE: case NEXTHOP_TYPE_BLACKHOLE:
family = AF_UNSPEC; // TODO: Handle this
addattr_l(&req.n, sizeof(req), NHA_BLACKHOLE, NULL, 0); addattr_l(&req.n, sizeof(req), NHA_BLACKHOLE, NULL, 0);
break; break;
case NEXTHOP_TYPE_IFINDEX:
/* Don't need anymore info for this */
break;
case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4:
case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6:
flog_err( flog_err(
@ -1943,7 +1943,6 @@ static int netlink_nexthop(int cmd, struct zebra_dplane_ctx *ctx)
break; break;
} }
req.nhm.nh_family = family;
req.nhm.nh_protocol = zebra2proto(dplane_ctx_get_type(ctx)); req.nhm.nh_protocol = zebra2proto(dplane_ctx_get_type(ctx));
addattr32(&req.n, sizeof(req), NHA_OIF, nh->ifindex); addattr32(&req.n, sizeof(req), NHA_OIF, nh->ifindex);
@ -2224,6 +2223,7 @@ int netlink_nexthop_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
/* nexthop group id */ /* nexthop group id */
uint32_t id; uint32_t id;
unsigned char family; unsigned char family;
afi_t afi = AFI_UNSPEC;
struct interface *ifp = NULL; struct interface *ifp = NULL;
struct nhmsg *nhm = NULL; struct nhmsg *nhm = NULL;
/* struct for nexthop group abstraction */ /* struct for nexthop group abstraction */
@ -2262,13 +2262,15 @@ int netlink_nexthop_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
/* We use the ID key'd nhg table for kernel updates */ /* We use the ID key'd nhg table for kernel updates */
id = *((uint32_t *)RTA_DATA(tb[NHA_ID])); id = *((uint32_t *)RTA_DATA(tb[NHA_ID]));
family = nhm->nh_family;
if (IS_ZEBRA_DEBUG_KERNEL) { if (IS_ZEBRA_DEBUG_KERNEL) {
zlog_debug("Nexthop ID (%u) update from the kernel", id); zlog_debug("Nexthop ID (%u) update from the kernel", id);
} }
/* Lookup via the id */ family = nhm->nh_family;
afi = family2afi(family);
nhe = zebra_nhg_lookup_id(id); nhe = zebra_nhg_lookup_id(id);
if (h->nlmsg_type == RTM_NEWNEXTHOP) { if (h->nlmsg_type == RTM_NEWNEXTHOP) {
@ -2310,7 +2312,7 @@ int netlink_nexthop_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
nexthop_group_copy(&nhe->nhg, &nhg); nexthop_group_copy(&nhe->nhg, &nhg);
} else { } else {
/* This is a new nexthop group */ /* This is a new nexthop group */
nhe = zebra_nhg_find(&nhg, nh.vrf_id, id); nhe = zebra_nhg_find(&nhg, nh.vrf_id, afi, id);
if (nhe) { if (nhe) {
nhe->is_kernel_nh = true; nhe->is_kernel_nh = true;
} else { } else {