forked from Mirror/frr
zebra: Add multipath parsing to V6
In the near future it will be possible to recieve v6 multipath netlink messages. This code change is in prep for it. In the meantime the v6 code path will continue to work as per normal. Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
parent
89a9069abb
commit
a2ca67d1d2
|
@ -241,92 +241,8 @@ netlink_route_change_read_unicast (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
|||
p.family = AF_INET;
|
||||
memcpy (&p.u.prefix4, dest, 4);
|
||||
p.prefixlen = rtm->rtm_dst_len;
|
||||
|
||||
if (rtm->rtm_src_len != 0)
|
||||
{
|
||||
zlog_warn ("unsupported IPv4 sourcedest route (dest %s/%d)",
|
||||
inet_ntoa (p.u.prefix4), p.prefixlen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
{
|
||||
char buf[PREFIX_STRLEN];
|
||||
zlog_debug ("%s %s vrf %u",
|
||||
nl_msg_type_to_str (h->nlmsg_type),
|
||||
prefix2str (&p, buf, sizeof(buf)), vrf_id);
|
||||
}
|
||||
|
||||
if (h->nlmsg_type == RTM_NEWROUTE)
|
||||
{
|
||||
if (!tb[RTA_MULTIPATH])
|
||||
rib_add (AFI_IP, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL,
|
||||
0, flags, &p, NULL, gate, prefsrc, index,
|
||||
table, metric, mtu, 0);
|
||||
else
|
||||
{
|
||||
/* This is a multipath route */
|
||||
|
||||
struct rib *rib;
|
||||
struct rtnexthop *rtnh =
|
||||
(struct rtnexthop *) RTA_DATA (tb[RTA_MULTIPATH]);
|
||||
|
||||
len = RTA_PAYLOAD (tb[RTA_MULTIPATH]);
|
||||
|
||||
rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
|
||||
rib->type = ZEBRA_ROUTE_KERNEL;
|
||||
rib->distance = 0;
|
||||
rib->flags = flags;
|
||||
rib->metric = metric;
|
||||
rib->mtu = mtu;
|
||||
rib->vrf_id = vrf_id;
|
||||
rib->table = table;
|
||||
rib->nexthop_num = 0;
|
||||
rib->uptime = time (NULL);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (len < (int) sizeof (*rtnh) || rtnh->rtnh_len > len)
|
||||
break;
|
||||
|
||||
index = rtnh->rtnh_ifindex;
|
||||
gate = 0;
|
||||
if (rtnh->rtnh_len > sizeof (*rtnh))
|
||||
{
|
||||
memset (tb, 0, sizeof (tb));
|
||||
netlink_parse_rtattr (tb, RTA_MAX, RTNH_DATA (rtnh),
|
||||
rtnh->rtnh_len - sizeof (*rtnh));
|
||||
if (tb[RTA_GATEWAY])
|
||||
gate = RTA_DATA (tb[RTA_GATEWAY]);
|
||||
}
|
||||
|
||||
if (gate)
|
||||
{
|
||||
if (index)
|
||||
rib_nexthop_ipv4_ifindex_add (rib, gate, prefsrc, index);
|
||||
else
|
||||
rib_nexthop_ipv4_add (rib, gate, prefsrc);
|
||||
}
|
||||
else
|
||||
rib_nexthop_ifindex_add (rib, index);
|
||||
|
||||
len -= NLMSG_ALIGN(rtnh->rtnh_len);
|
||||
rtnh = RTNH_NEXT(rtnh);
|
||||
}
|
||||
|
||||
zserv_nexthop_num_warn(__func__, (const struct prefix *)&p,
|
||||
rib->nexthop_num);
|
||||
if (rib->nexthop_num == 0)
|
||||
XFREE (MTYPE_RIB, rib);
|
||||
else
|
||||
rib_add_multipath (AFI_IP, SAFI_UNICAST, &p, NULL, rib);
|
||||
}
|
||||
}
|
||||
else
|
||||
rib_delete (AFI_IP, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL, 0, flags,
|
||||
&p, NULL, gate, index, table);
|
||||
}
|
||||
if (rtm->rtm_family == AF_INET6)
|
||||
else if (rtm->rtm_family == AF_INET6)
|
||||
{
|
||||
p.family = AF_INET6;
|
||||
memcpy (&p.u.prefix6, dest, 16);
|
||||
|
@ -335,27 +251,110 @@ netlink_route_change_read_unicast (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
|||
src_p.family = AF_INET6;
|
||||
memcpy (&src_p.prefix, src, 16);
|
||||
src_p.prefixlen = rtm->rtm_src_len;
|
||||
}
|
||||
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
{
|
||||
char buf[PREFIX_STRLEN];
|
||||
char buf2[PREFIX_STRLEN];
|
||||
zlog_debug ("%s %s%s%s vrf %u",
|
||||
nl_msg_type_to_str (h->nlmsg_type),
|
||||
prefix2str (&p, buf, sizeof(buf)),
|
||||
src_p.prefixlen ? " from " : "",
|
||||
src_p.prefixlen ? prefix2str(&src_p, buf2, sizeof(buf2)) : "",
|
||||
vrf_id);
|
||||
}
|
||||
if (rtm->rtm_src_len != 0)
|
||||
{
|
||||
char buf[PREFIX_STRLEN];
|
||||
zlog_warn ("unsupported IPv[4|6] sourcedest route (dest %s vrf %u)",
|
||||
prefix2str (&p, buf, sizeof(buf)), vrf_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (h->nlmsg_type == RTM_NEWROUTE)
|
||||
rib_add (AFI_IP6, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL,
|
||||
0, flags, &p, &src_p, gate, prefsrc, index,
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
{
|
||||
char buf[PREFIX_STRLEN];
|
||||
char buf2[PREFIX_STRLEN];
|
||||
zlog_debug ("%s %s%s%s vrf %u",
|
||||
nl_msg_type_to_str (h->nlmsg_type),
|
||||
prefix2str (&p, buf, sizeof(buf)),
|
||||
src_p.prefixlen ? " from " : "",
|
||||
src_p.prefixlen ? prefix2str(&src_p, buf2, sizeof(buf2)) : "",
|
||||
vrf_id);
|
||||
}
|
||||
|
||||
afi_t afi = AFI_IP;
|
||||
if (rtm->rtm_family == AF_INET6)
|
||||
afi = AFI_IP6;
|
||||
|
||||
if (h->nlmsg_type == RTM_NEWROUTE)
|
||||
{
|
||||
if (!tb[RTA_MULTIPATH])
|
||||
rib_add (afi, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL,
|
||||
0, flags, &p, NULL, gate, prefsrc, index,
|
||||
table, metric, mtu, 0);
|
||||
else
|
||||
rib_delete (AFI_IP6, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL,
|
||||
0, flags, &p, &src_p, gate, index, table);
|
||||
{
|
||||
/* This is a multipath route */
|
||||
|
||||
struct rib *rib;
|
||||
struct rtnexthop *rtnh =
|
||||
(struct rtnexthop *) RTA_DATA (tb[RTA_MULTIPATH]);
|
||||
|
||||
len = RTA_PAYLOAD (tb[RTA_MULTIPATH]);
|
||||
|
||||
rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
|
||||
rib->type = ZEBRA_ROUTE_KERNEL;
|
||||
rib->distance = 0;
|
||||
rib->flags = flags;
|
||||
rib->metric = metric;
|
||||
rib->mtu = mtu;
|
||||
rib->vrf_id = vrf_id;
|
||||
rib->table = table;
|
||||
rib->nexthop_num = 0;
|
||||
rib->uptime = time (NULL);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (len < (int) sizeof (*rtnh) || rtnh->rtnh_len > len)
|
||||
break;
|
||||
|
||||
index = rtnh->rtnh_ifindex;
|
||||
gate = 0;
|
||||
if (rtnh->rtnh_len > sizeof (*rtnh))
|
||||
{
|
||||
memset (tb, 0, sizeof (tb));
|
||||
netlink_parse_rtattr (tb, RTA_MAX, RTNH_DATA (rtnh),
|
||||
rtnh->rtnh_len - sizeof (*rtnh));
|
||||
if (tb[RTA_GATEWAY])
|
||||
gate = RTA_DATA (tb[RTA_GATEWAY]);
|
||||
}
|
||||
|
||||
if (gate)
|
||||
{
|
||||
if (rtm->rtm_family == AF_INET)
|
||||
{
|
||||
if (index)
|
||||
rib_nexthop_ipv4_ifindex_add (rib, gate, prefsrc, index);
|
||||
else
|
||||
rib_nexthop_ipv4_add (rib, gate, prefsrc);
|
||||
}
|
||||
else if (rtm->rtm_family == AF_INET6)
|
||||
{
|
||||
if (index)
|
||||
rib_nexthop_ipv6_ifindex_add (rib, gate, index);
|
||||
else
|
||||
rib_nexthop_ipv6_add (rib,gate);
|
||||
}
|
||||
}
|
||||
else
|
||||
rib_nexthop_ifindex_add (rib, index);
|
||||
|
||||
len -= NLMSG_ALIGN(rtnh->rtnh_len);
|
||||
rtnh = RTNH_NEXT(rtnh);
|
||||
}
|
||||
|
||||
zserv_nexthop_num_warn(__func__, (const struct prefix *)&p,
|
||||
rib->nexthop_num);
|
||||
if (rib->nexthop_num == 0)
|
||||
XFREE (MTYPE_RIB, rib);
|
||||
else
|
||||
rib_add_multipath (AFI_IP, SAFI_UNICAST, &p, NULL, rib);
|
||||
}
|
||||
}
|
||||
else
|
||||
rib_delete (afi, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL, 0, flags,
|
||||
&p, NULL, gate, index, table);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue