From: James Li <[email protected]> Do not allow a program outside Quagga to delete a Quagga route from the kernel. To delete a Quagga route, do it inside Quagga.
Signed-off-by: James Li <[email protected]> --- zebra/rt_netlink.c | 9 ++++++--- zebra/zebra_rib.c | 42 ++++++++++++++++++++++++++---------------- 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 2253cc1..f5a9450 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -850,6 +850,7 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h, int len; struct rtmsg *rtm; struct rtattr *tb[RTA_MAX + 1]; + u_char zebra_flags = 0; char anyaddr[16] = { 0 }; @@ -908,6 +909,8 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h, if (rtm->rtm_protocol == RTPROT_ZEBRA && h->nlmsg_type == RTM_NEWROUTE) return 0; + if (rtm->rtm_protocol == RTPROT_ZEBRA) + SET_FLAG(zebra_flags, ZEBRA_FLAG_SELFROUTE); if (rtm->rtm_src_len != 0) { @@ -1031,8 +1034,8 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h, } } else - rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, vrf_id, - SAFI_UNICAST); + rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, gate, + index, vrf_id, SAFI_UNICAST); } #ifdef HAVE_IPV6 @@ -1056,7 +1059,7 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h, rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, vrf_id, table, metric, mtu, 0, SAFI_UNICAST); else - rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, vrf_id, + rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, gate, index, vrf_id, SAFI_UNICAST); } #endif /* HAVE_IPV6 */ diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 674a1f7..812ef96 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -2189,14 +2189,19 @@ rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p, kernel. */ if (! same) { - if (fib && type == ZEBRA_ROUTE_KERNEL) - { - /* Unset flags. */ - for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next) - UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); - - UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED); - } + if (fib && type == ZEBRA_ROUTE_KERNEL && + CHECK_FLAG(flags, ZEBRA_FLAG_SELFROUTE)) + { + if (IS_ZEBRA_DEBUG_KERNEL) + { + zlog_debug ("Zebra route %s/%d was deleted by others from kernel", + inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN), + p->prefixlen); + } + /* This means someone else, other than Zebra, has deleted + * a Zebra router from the kernel. We will add it back */ + rib_install_kernel(rn, fib); + } else { if (IS_ZEBRA_DEBUG_KERNEL) @@ -2847,14 +2852,19 @@ rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p, kernel. */ if (! same) { - if (fib && type == ZEBRA_ROUTE_KERNEL) - { - /* Unset flags. */ - for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next) - UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); - - UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED); - } + if (fib && type == ZEBRA_ROUTE_KERNEL && + CHECK_FLAG(flags, ZEBRA_FLAG_SELFROUTE)) + { + if (IS_ZEBRA_DEBUG_KERNEL) + { + zlog_debug ("Zebra route %s/%d was deleted by others from kernel", + inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN), + p->prefixlen); + } + /* This means someone else, other than Zebra, has deleted a Zebra + * route from the kernel. We will add it back */ + rib_install_kernel(rn, fib); + } else { if (IS_ZEBRA_DEBUG_KERNEL) -- 1.9.1 _______________________________________________ Quagga-dev mailing list [email protected] https://lists.quagga.net/mailman/listinfo/quagga-dev
