From a2ca67d1d21ee8fdf33906e12815663584634e94 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Mon, 30 Jan 2017 14:50:06 -0500 Subject: [PATCH] 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 --- zebra/rt_netlink.c | 191 ++++++++++++++++++++++----------------------- 1 file changed, 95 insertions(+), 96 deletions(-) diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 4e5c16a338..0c3d17dbda 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; } -- 2.39.5