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;
}