diff options
author | Renato Westphal <renato@openbsd.org> | 2017-09-27 14:11:11 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-09-27 14:11:11 +0200 |
commit | 310f64be9333129002beb0b002741655ae38ab8b (patch) | |
tree | aa9a00401296f8af4f332755acb3899ad5664127 /zebra | |
parent | Merge pull request #1249 from donaldsharp/debugodebug (diff) | |
parent | zebra: Do not allow delete of route from kernel in non-startup case (diff) | |
download | frr-310f64be9333129002beb0b002741655ae38ab8b.tar.xz frr-310f64be9333129002beb0b002741655ae38ab8b.zip |
Merge pull request #1240 from donaldsharp/allow_self_delete
zebra: Do not allow delete of route from kernel in non-startup case
Diffstat (limited to 'zebra')
-rw-r--r-- | zebra/connected.c | 4 | ||||
-rw-r--r-- | zebra/kernel_socket.c | 8 | ||||
-rw-r--r-- | zebra/redistribute.c | 2 | ||||
-rw-r--r-- | zebra/rib.h | 2 | ||||
-rw-r--r-- | zebra/rt_netlink.c | 4 | ||||
-rw-r--r-- | zebra/zebra_rib.c | 28 | ||||
-rw-r--r-- | zebra/zserv.c | 6 |
7 files changed, 39 insertions, 15 deletions
diff --git a/zebra/connected.c b/zebra/connected.c index 77a560c6b..18dc6a970 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -396,10 +396,10 @@ void connected_down(struct interface *ifp, struct connected *ifc) * head. */ rib_delete(afi, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0, - &p, NULL, &nh, 0, 0); + &p, NULL, &nh, 0, 0, false); rib_delete(afi, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, - 0, &p, NULL, &nh, 0, 0); + 0, &p, NULL, &nh, 0, 0, false); if (IS_ZEBRA_DEBUG_RIB_DETAILED) { char buf[PREFIX_STRLEN]; diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c index df8cdb3ab..9907ef5b7 100644 --- a/zebra/kernel_socket.c +++ b/zebra/kernel_socket.c @@ -1042,7 +1042,7 @@ void rtm_read(struct rt_msghdr *rtm) if (rtm->rtm_type == RTM_CHANGE) rib_delete(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL, - NULL, 0, 0); + NULL, 0, 0, true); if (!nh.type) { nh.type = NEXTHOP_TYPE_IPV4; @@ -1057,7 +1057,7 @@ void rtm_read(struct rt_msghdr *rtm) else rib_delete(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL, - &nh, 0, 0); + &nh, 0, 0, true); } if (dest.sa.sa_family == AF_INET6) { /* One day we might have a debug section here like one in the @@ -1088,7 +1088,7 @@ void rtm_read(struct rt_msghdr *rtm) if (rtm->rtm_type == RTM_CHANGE) rib_delete(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL, - NULL, 0, 0); + NULL, 0, 0, true); if (!nh.type) { nh.type = ifindex ? NEXTHOP_TYPE_IPV6_IFINDEX @@ -1105,7 +1105,7 @@ void rtm_read(struct rt_msghdr *rtm) else rib_delete(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL, - &nh, 0, 0); + &nh, 0, 0, true); } } diff --git a/zebra/redistribute.c b/zebra/redistribute.c index 76e0df40b..890ad887d 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -558,7 +558,7 @@ int zebra_del_import_table_entry(struct route_node *rn, struct route_entry *re) rib_delete(afi, SAFI_UNICAST, re->vrf_id, ZEBRA_ROUTE_TABLE, re->table, re->flags, &p, NULL, NULL, - zebrad.rtm_table_default, re->metric); + zebrad.rtm_table_default, re->metric, false); return 0; } diff --git a/zebra/rib.h b/zebra/rib.h index 4cc69377d..e36132124 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -302,7 +302,7 @@ extern int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *, extern void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, int flags, struct prefix *p, struct prefix_ipv6 *src_p, const struct nexthop *nh, - u_int32_t table_id, u_int32_t metric); + u_int32_t table_id, u_int32_t metric, bool fromkernel); extern struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t, union g_addr *, diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index d67d67027..573f60f4c 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -560,13 +560,13 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl, memcpy(&nh.gate, gate, sz); rib_delete(afi, SAFI_UNICAST, vrf_id, proto, 0, flags, &p, NULL, &nh, - table, metric); + table, metric, true); } else { /* XXX: need to compare the entire list of nexthops * here for NLM_F_APPEND stupidity */ rib_delete(afi, SAFI_UNICAST, vrf_id, proto, 0, flags, &p, NULL, NULL, - table, metric); + table, metric, true); } } diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 64cef1b01..61a18e2df 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -2299,7 +2299,7 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p, void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, int flags, struct prefix *p, struct prefix_ipv6 *src_p, const struct nexthop *nh, - u_int32_t table_id, u_int32_t metric) + u_int32_t table_id, u_int32_t metric, bool fromkernel) { struct route_table *table; struct route_node *rn; @@ -2380,6 +2380,21 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, /* If same type of route can't be found and this message is from kernel. */ if (!same) { + /* + * In the past(HA!) we could get here because + * we were receiving a route delete from the + * kernel and we're not marking the proto + * as coming from it's appropriate originator. + * Now that we are properly noticing the fact + * that the kernel has deleted our route we + * are not going to get called in this path + * I am going to leave this here because + * this might still work this way on non-linux + * platforms as well as some weird state I have + * not properly thought of yet. + * If we can show that this code path is + * dead then we can remove it. + */ if (fib && type == ZEBRA_ROUTE_KERNEL && CHECK_FLAG(flags, ZEBRA_FLAG_SELFROUTE)) { if (IS_ZEBRA_DEBUG_RIB) { @@ -2428,8 +2443,17 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, } } - if (same) + if (same) { + if (fromkernel && + CHECK_FLAG(flags, ZEBRA_FLAG_SELFROUTE) && + !allow_delete) { + rib_install_kernel(rn, same, NULL); + route_unlock_node(rn); + + return; + } rib_delnode(rn, same); + } route_unlock_node(rn); return; diff --git a/zebra/zserv.c b/zebra/zserv.c index 2c0e1a020..fd2c5dd97 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -1165,7 +1165,7 @@ static int zread_route_del(struct zserv *client, u_short length, rib_delete(afi, api.safi, zvrf_id(zvrf), api.type, api.instance, api.flags, &api.prefix, src_p, NULL, zvrf->table_id, - api.metric); + api.metric, false); /* Stats */ switch (api.prefix.family) { @@ -1331,7 +1331,7 @@ static int zread_ipv4_delete(struct zserv *client, u_short length, table_id = zvrf->table_id; rib_delete(AFI_IP, api.safi, zvrf_id(zvrf), api.type, api.instance, - api.flags, &p, NULL, NULL, table_id, 0); + api.flags, &p, NULL, NULL, table_id, 0, false); client->v4_route_del_cnt++; return 0; } @@ -1693,7 +1693,7 @@ static int zread_ipv6_delete(struct zserv *client, u_short length, src_pp = NULL; rib_delete(AFI_IP6, api.safi, zvrf_id(zvrf), api.type, api.instance, - api.flags, &p, src_pp, NULL, client->rtm_table, 0); + api.flags, &p, src_pp, NULL, client->rtm_table, 0, false); client->v6_route_del_cnt++; return 0; |