summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Worley <sworley@cumulusnetworks.com>2019-08-01 23:36:56 +0200
committerStephen Worley <sworley@cumulusnetworks.com>2019-10-25 17:13:42 +0200
commitbc541126e4058b6139f6b693a1adc9af2332317d (patch)
tree2bf53a2d9f076dcd1c352459476553ccdee75d91
parentzebra: Move the supports_nh bool to a better place (diff)
downloadfrr-bc541126e4058b6139f6b693a1adc9af2332317d.tar.xz
frr-bc541126e4058b6139f6b693a1adc9af2332317d.zip
zebra: Use nexthop object id on route delete
When we receive a route delete from the kernel and it contains a nexthop object id, use that to match against route gateways with instead of explicit nexthops. Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com>
-rw-r--r--zebra/connected.c6
-rw-r--r--zebra/kernel_socket.c8
-rw-r--r--zebra/redistribute.c2
-rw-r--r--zebra/rib.h4
-rw-r--r--zebra/rt_netlink.c75
-rw-r--r--zebra/zapi_msg.c2
-rw-r--r--zebra/zebra_rib.c9
7 files changed, 58 insertions, 48 deletions
diff --git a/zebra/connected.c b/zebra/connected.c
index b69c5c6e7..e21b778e3 100644
--- a/zebra/connected.c
+++ b/zebra/connected.c
@@ -393,11 +393,11 @@ void connected_down(struct interface *ifp, struct connected *ifc)
* Same logic as for connected_up(): push the changes into the
* head.
*/
- rib_delete(afi, SAFI_UNICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_CONNECT,
- 0, 0, &p, NULL, &nh, zvrf->table_id, 0, 0, false);
+ rib_delete(afi, SAFI_UNICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_CONNECT, 0,
+ 0, &p, NULL, &nh, 0, zvrf->table_id, 0, 0, false);
rib_delete(afi, SAFI_MULTICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_CONNECT,
- 0, 0, &p, NULL, &nh, zvrf->table_id, 0, 0, false);
+ 0, 0, &p, NULL, &nh, 0, zvrf->table_id, 0, 0, false);
/* Schedule LSP forwarding entries for processing, if appropriate. */
if (zvrf->vrf->vrf_id == VRF_DEFAULT) {
diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c
index 13dd9c8dc..c2812aa47 100644
--- a/zebra/kernel_socket.c
+++ b/zebra/kernel_socket.c
@@ -1139,8 +1139,8 @@ void rtm_read(struct rt_msghdr *rtm)
*/
if (rtm->rtm_type == RTM_CHANGE)
rib_delete(afi, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL,
- 0, zebra_flags, &p, NULL, NULL, RT_TABLE_MAIN,
- 0, 0, true);
+ 0, zebra_flags, &p, NULL, NULL, 0, RT_TABLE_MAIN, 0,
+ 0, true);
if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD
|| rtm->rtm_type == RTM_CHANGE)
rib_add(afi, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0,
@@ -1148,8 +1148,8 @@ void rtm_read(struct rt_msghdr *rtm)
0, 0, 0, 0);
else
rib_delete(afi, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL,
- 0, zebra_flags, &p, NULL, &nh, RT_TABLE_MAIN,
- 0, 0, true);
+ 0, zebra_flags, &p, NULL, &nh, 0, RT_TABLE_MAIN, 0,
+ 0, true);
}
/* Interface function for the kernel routing table updates. Support
diff --git a/zebra/redistribute.c b/zebra/redistribute.c
index 42f8c812b..4e0163f8a 100644
--- a/zebra/redistribute.c
+++ b/zebra/redistribute.c
@@ -696,7 +696,7 @@ int zebra_del_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn,
prefix_copy(&p, &rn->p);
rib_delete(afi, SAFI_UNICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_TABLE,
- re->table, re->flags, &p, NULL, re->ng->nexthop,
+ re->table, re->flags, &p, NULL, re->ng->nexthop, re->nhe_id,
zvrf->table_id, re->metric, re->distance, false);
return 0;
diff --git a/zebra/rib.h b/zebra/rib.h
index 2652b12ab..35aa011c0 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -373,8 +373,8 @@ extern int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
extern void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
unsigned short instance, int flags, struct prefix *p,
struct prefix_ipv6 *src_p, const struct nexthop *nh,
- uint32_t table_id, uint32_t metric, uint8_t distance,
- bool fromkernel);
+ uint32_t nhe_id, uint32_t table_id, uint32_t metric,
+ uint8_t distance, bool fromkernel);
extern struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t vrf_id,
union g_addr *addr,
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index 840354a8b..cdd7b5a92 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -772,44 +772,51 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id,
XFREE(MTYPE_RE, re);
}
} else {
- // TODO: Use nhe_id here as well
- if (!tb[RTA_MULTIPATH]) {
- struct nexthop nh;
- size_t sz = (afi == AFI_IP) ? 4 : 16;
-
- memset(&nh, 0, sizeof(nh));
- if (bh_type == BLACKHOLE_UNSPEC) {
- if (index && !gate)
- nh.type = NEXTHOP_TYPE_IFINDEX;
- else if (index && gate)
- nh.type =
- (afi == AFI_IP)
- ? NEXTHOP_TYPE_IPV4_IFINDEX
- : NEXTHOP_TYPE_IPV6_IFINDEX;
- else if (!index && gate)
- nh.type = (afi == AFI_IP)
- ? NEXTHOP_TYPE_IPV4
- : NEXTHOP_TYPE_IPV6;
- else {
+ if (nhe_id) {
+ rib_delete(afi, SAFI_UNICAST, vrf_id, proto, 0, flags,
+ &p, &src_p, NULL, nhe_id, table, metric,
+ distance, true);
+ } else {
+ if (!tb[RTA_MULTIPATH]) {
+ struct nexthop nh;
+ size_t sz = (afi == AFI_IP) ? 4 : 16;
+
+ memset(&nh, 0, sizeof(nh));
+ if (bh_type == BLACKHOLE_UNSPEC) {
+ if (index && !gate)
+ nh.type = NEXTHOP_TYPE_IFINDEX;
+ else if (index && gate)
+ nh.type =
+ (afi == AFI_IP)
+ ? NEXTHOP_TYPE_IPV4_IFINDEX
+ : NEXTHOP_TYPE_IPV6_IFINDEX;
+ else if (!index && gate)
+ nh.type =
+ (afi == AFI_IP)
+ ? NEXTHOP_TYPE_IPV4
+ : NEXTHOP_TYPE_IPV6;
+ else {
+ nh.type =
+ NEXTHOP_TYPE_BLACKHOLE;
+ nh.bh_type = BLACKHOLE_UNSPEC;
+ }
+ } else {
nh.type = NEXTHOP_TYPE_BLACKHOLE;
- nh.bh_type = BLACKHOLE_UNSPEC;
+ nh.bh_type = bh_type;
}
+ nh.ifindex = index;
+ if (gate)
+ memcpy(&nh.gate, gate, sz);
+ rib_delete(afi, SAFI_UNICAST, vrf_id, proto, 0,
+ flags, &p, &src_p, &nh, 0, table,
+ metric, distance, true);
} else {
- nh.type = NEXTHOP_TYPE_BLACKHOLE;
- nh.bh_type = bh_type;
+ /* 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, &src_p, NULL, 0, table,
+ metric, distance, true);
}
- nh.ifindex = index;
- if (gate)
- memcpy(&nh.gate, gate, sz);
- rib_delete(afi, SAFI_UNICAST, vrf_id, proto, 0, flags,
- &p, &src_p, &nh, table, metric, distance,
- 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, &src_p, NULL, table, metric, distance,
- true);
}
}
diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c
index ecbf39dda..ab4c246d1 100644
--- a/zebra/zapi_msg.c
+++ b/zebra/zapi_msg.c
@@ -1635,7 +1635,7 @@ static void zread_route_del(ZAPI_HANDLER_ARGS)
table_id = zvrf->table_id;
rib_delete(afi, api.safi, zvrf_id(zvrf), api.type, api.instance,
- api.flags, &api.prefix, src_p, NULL, table_id, api.metric,
+ api.flags, &api.prefix, src_p, NULL, 0, table_id, api.metric,
api.distance, false);
/* Stats */
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index bc647864f..144017158 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -2854,8 +2854,8 @@ 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,
unsigned short instance, int flags, struct prefix *p,
struct prefix_ipv6 *src_p, const struct nexthop *nh,
- uint32_t table_id, uint32_t metric, uint8_t distance,
- bool fromkernel)
+ uint32_t nhe_id, uint32_t table_id, uint32_t metric,
+ uint8_t distance, bool fromkernel)
{
struct route_table *table;
struct route_node *rn;
@@ -2926,7 +2926,10 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
break;
}
/* Make sure that the route found has the same gateway. */
- else {
+ else if (nhe_id && re->nhe_id == nhe_id) {
+ same = re;
+ break;
+ } else {
if (nh == NULL) {
same = re;
break;