From: Donald Sharp Date: Mon, 30 Jan 2017 19:50:06 +0000 (-0500) Subject: zebra: Add multipath parsing to V6 X-Git-Tag: frr-3.0-branchpoint~18^2~1 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=a2ca67d1d2;p=matthieu%2Ffrr.git 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 --- 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; }