summaryrefslogtreecommitdiffstats
path: root/zebra/rt_netlink.c
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2017-01-30 20:50:06 +0100
committerDonald Sharp <sharpd@cumulusnetworks.com>2017-03-01 14:30:50 +0100
commita2ca67d1d21ee8fdf33906e12815663584634e94 (patch)
treed7b257d6c9ba755d127b54661c3368dcc9f1eec2 /zebra/rt_netlink.c
parentzebra: Refactor netlink_route_change and netlink_route_change_read_unicast (diff)
downloadfrr-a2ca67d1d21ee8fdf33906e12815663584634e94.tar.xz
frr-a2ca67d1d21ee8fdf33906e12815663584634e94.zip
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>
Diffstat (limited to '')
-rw-r--r--zebra/rt_netlink.c191
1 files changed, 95 insertions, 96 deletions
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index 4e5c16a33..0c3d17dbd 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -241,121 +241,120 @@ 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;
+ }
+ else if (rtm->rtm_family == AF_INET6)
+ {
+ p.family = AF_INET6;
+ memcpy (&p.u.prefix6, dest, 16);
+ 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;
- }
+ 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];
- zlog_debug ("%s %s vrf %u",
- nl_msg_type_to_str (h->nlmsg_type),
- prefix2str (&p, buf, sizeof(buf)), 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 (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 (h->nlmsg_type == RTM_NEWROUTE)
+ 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
{
- 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 (;;)
{
- /* 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;
+ 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]);
- }
+ 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 (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
- rib_nexthop_ifindex_add (rib, index);
-
- len -= NLMSG_ALIGN(rtnh->rtnh_len);
- rtnh = RTNH_NEXT(rtnh);
+ else if (rtm->rtm_family == AF_INET6)
+ {
+ if (index)
+ rib_nexthop_ipv6_ifindex_add (rib, gate, index);
+ else
+ rib_nexthop_ipv6_add (rib,gate);
+ }
}
-
- 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)
- {
- p.family = AF_INET6;
- memcpy (&p.u.prefix6, dest, 16);
- p.prefixlen = rtm->rtm_dst_len;
+ rib_nexthop_ifindex_add (rib, index);
- src_p.family = AF_INET6;
- memcpy (&src_p.prefix, src, 16);
- src_p.prefixlen = rtm->rtm_src_len;
+ len -= NLMSG_ALIGN(rtnh->rtnh_len);
+ rtnh = RTNH_NEXT(rtnh);
+ }
- 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);
+ 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);
}
-
- 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,
- table, metric, mtu, 0);
- else
- rib_delete (AFI_IP6, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL,
- 0, flags, &p, &src_p, gate, index, table);
}
+ else
+ rib_delete (afi, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL, 0, flags,
+ &p, NULL, gate, index, table);
return 0;
}