diff options
-rw-r--r-- | zebra/rt_netlink.c | 50 | ||||
-rw-r--r-- | zebra/zebra_rib.c | 4 |
2 files changed, 43 insertions, 11 deletions
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index b29cb216..23acd5f3 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -85,6 +85,28 @@ extern struct zebra_privs_t zserv_privs; extern u_int32_t nl_rcvbufsize; +/* dispatch rtm_type field, return 1 if we want to process this */ +static int +get_discard_or_unicast (unsigned char rtm_type, unsigned *zflags) +{ + switch (rtm_type) + { + case RTN_UNICAST: + *zflags = 0; + return 1; + case RTN_UNREACHABLE: + *zflags = RIB_ZF_REJECT; + return 1; + case RTN_PROHIBIT: + *zflags = RIB_ZF_PROHIBIT; + return 1; + case RTN_BLACKHOLE: + *zflags = RIB_ZF_BLACKHOLE; + return 1; + } + return 0; +} + /* Note: on netlink systems, there should be a 1-to-1 mapping between interface names and ifindex values. */ static void @@ -648,6 +670,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h) struct rtmsg *rtm; struct rtattr *tb[RTA_MAX + 1]; u_char flags = 0; + unsigned discard = 0; char anyaddr[16] = { 0 }; @@ -663,7 +686,8 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h) if (h->nlmsg_type != RTM_NEWROUTE) return 0; - if (rtm->rtm_type != RTN_UNICAST) + + if (!get_discard_or_unicast (rtm->rtm_type, &discard)) return 0; table = rtm->rtm_table; @@ -724,7 +748,8 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h) memcpy (&p.prefix, dest, 4); p.prefixlen = rtm->rtm_dst_len; - rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, flags, &p, gate, src, index, table, metric, 0); + rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, flags | (discard << 8), &p, + gate, src, index, table, metric, 0); } #ifdef HAVE_IPV6 if (rtm->rtm_family == AF_INET6) @@ -734,8 +759,8 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h) memcpy (&p.prefix, dest, 16); p.prefixlen = rtm->rtm_dst_len; - rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, flags, &p, gate, index, table, - metric, 0); + rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, flags | (discard << 8), &p, + gate, index, table, metric, 0); } #endif /* HAVE_IPV6 */ @@ -772,6 +797,7 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h) void *dest; void *gate; void *src; + unsigned discard = 0; rtm = NLMSG_DATA (h); @@ -788,10 +814,10 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h) h->nlmsg_type == RTM_NEWROUTE ? "RTM_NEWROUTE" : "RTM_DELROUTE", rtm->rtm_family == AF_INET ? "ipv4" : "ipv6", - rtm->rtm_type == RTN_UNICAST ? "unicast" : "multicast", + rtm->rtm_type == RTN_UNICAST ? "unicast" : "!unicast", lookup (rtproto_str, rtm->rtm_protocol)); - if (rtm->rtm_type != RTN_UNICAST) + if (!get_discard_or_unicast (rtm->rtm_type, &discard)) { return 0; } @@ -862,9 +888,11 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h) } if (h->nlmsg_type == RTM_NEWROUTE) - rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, src, index, table, 0, 0); + rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, discard << 8, &p, + gate, src, index, table, 0, 0); else - rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, table); + rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, discard << 8, &p, + gate, index, table); } #ifdef HAVE_IPV6 @@ -890,9 +918,11 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h) } if (h->nlmsg_type == RTM_NEWROUTE) - rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, table, 0, 0); + rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, discard << 8, &p, + gate, index, table, 0, 0); else - rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, table); + rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, discard << 8, &p, + gate, index, table); } #endif /* HAVE_IPV6 */ diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 28ca3b12..0f2e7784 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -1562,7 +1562,9 @@ rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p, rib->uptime = time (NULL); /* Nexthop settings. */ - if (gate) + if (RIB_ZF_BLACKHOLE_FLAGS (rib->zflags)) + nexthop_blackhole_add (rib); + else if (gate) { if (ifindex) nexthop_ipv4_ifindex_add (rib, gate, src, ifindex); |