summaryrefslogtreecommitdiff
path: root/zebra/zebra_rib.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/zebra_rib.c')
-rw-r--r--zebra/zebra_rib.c66
1 files changed, 44 insertions, 22 deletions
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index fbd3c6eb77..af159da3cc 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -3123,6 +3123,17 @@ static void rib_addnode(struct route_node *rn,
rib_link(rn, re, process);
}
+static void rib_re_nhg_free(struct route_entry *re)
+{
+ if (re->nhe && re->nhe_id) {
+ assert(re->nhe->id == re->nhe_id);
+ route_entry_update_nhe(re, NULL);
+ } else if (re->nhe && re->nhe->nhg.nexthop)
+ nexthops_free(re->nhe->nhg.nexthop);
+
+ nexthops_free(re->fib_ng.nexthop);
+}
+
/*
* rib_unlink
*
@@ -3149,14 +3160,7 @@ void rib_unlink(struct route_node *rn, struct route_entry *re)
if (dest->selected_fib == re)
dest->selected_fib = NULL;
- if (re->nhe && re->nhe_id) {
- assert(re->nhe->id == re->nhe_id);
-
- route_entry_update_nhe(re, NULL);
- } else if (re->nhe && re->nhe->nhg.nexthop)
- nexthops_free(re->nhe->nhg.nexthop);
-
- nexthops_free(re->fib_ng.nexthop);
+ rib_re_nhg_free(re);
zapi_re_opaque_free(re->opaque);
@@ -3346,7 +3350,7 @@ void _route_entry_dump(const char *func, union prefixconstptr pp,
*/
int rib_add_multipath_nhe(afi_t afi, safi_t safi, struct prefix *p,
struct prefix_ipv6 *src_p, struct route_entry *re,
- struct nhg_hash_entry *re_nhe)
+ struct nhg_hash_entry *re_nhe, bool startup)
{
struct nhg_hash_entry *nhe = NULL;
struct route_table *table;
@@ -3438,6 +3442,26 @@ int rib_add_multipath_nhe(afi_t afi, safi_t safi, struct prefix *p,
same = first_same;
+ if (!startup &&
+ (re->flags & ZEBRA_FLAG_SELFROUTE) && zrouter.asic_offloaded) {
+ if (!same) {
+ if (IS_ZEBRA_DEBUG_RIB)
+ zlog_debug("prefix: %pRN is a self route where we do not have an entry for it. Dropping this update, it's useless", rn);
+ /*
+ * We are not on startup, this is a self route
+ * and we have asic offload. Which means
+ * we are getting a callback for a entry
+ * that was already deleted to the kernel
+ * but an earlier response was just handed
+ * back. Drop it on the floor
+ */
+ rib_re_nhg_free(re);
+
+ XFREE(MTYPE_RE, re);
+ return ret;
+ }
+ }
+
/* If this route is kernel/connected route, notify the dataplane. */
if (RIB_SYSTEM_ROUTE(re)) {
/* Notify dataplane */
@@ -3491,7 +3515,7 @@ int rib_add_multipath_nhe(afi_t afi, safi_t safi, struct prefix *p,
*/
int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
struct prefix_ipv6 *src_p, struct route_entry *re,
- struct nexthop_group *ng)
+ struct nexthop_group *ng, bool startup)
{
int ret;
struct nhg_hash_entry nhe;
@@ -3512,7 +3536,7 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
else if (re->nhe_id > 0)
nhe.id = re->nhe_id;
- ret = rib_add_multipath_nhe(afi, safi, p, src_p, re, &nhe);
+ ret = rib_add_multipath_nhe(afi, safi, p, src_p, re, &nhe, startup);
/* In this path, the callers expect memory to be freed. */
nexthop_group_delete(&ng);
@@ -3743,7 +3767,7 @@ int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
unsigned short instance, uint32_t flags, struct prefix *p,
struct prefix_ipv6 *src_p, const struct nexthop *nh,
uint32_t nhe_id, uint32_t table_id, uint32_t metric, uint32_t mtu,
- uint8_t distance, route_tag_t tag)
+ uint8_t distance, route_tag_t tag, bool startup)
{
struct route_entry *re = NULL;
struct nexthop *nexthop = NULL;
@@ -3775,7 +3799,7 @@ int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
nexthop_group_add_sorted(ng, nexthop);
}
- return rib_add_multipath(afi, safi, p, src_p, re, ng);
+ return rib_add_multipath(afi, safi, p, src_p, re, ng, startup);
}
static const char *rib_update_event2str(enum rib_update_event event)
@@ -3924,7 +3948,7 @@ static void rib_update_ctx_fini(struct rib_update_ctx **ctx)
XFREE(MTYPE_RIB_UPDATE_CTX, *ctx);
}
-static int rib_update_handler(struct thread *thread)
+static void rib_update_handler(struct thread *thread)
{
struct rib_update_ctx *ctx;
@@ -3936,8 +3960,6 @@ static int rib_update_handler(struct thread *thread)
rib_update_handle_vrf(ctx->vrf_id, ctx->event, ZEBRA_ROUTE_ALL);
rib_update_ctx_fini(&ctx);
-
- return 0;
}
/*
@@ -4031,7 +4053,7 @@ void rib_sweep_table(struct route_table *table)
}
/* Sweep all RIB tables. */
-int rib_sweep_route(struct thread *t)
+void rib_sweep_route(struct thread *t)
{
struct vrf *vrf;
struct zebra_vrf *zvrf;
@@ -4046,8 +4068,6 @@ int rib_sweep_route(struct thread *t)
zebra_router_sweep_route();
zebra_router_sweep_nhgs();
-
- return 0;
}
/* Remove specific by protocol routes from 'table'. */
@@ -4157,7 +4177,7 @@ done:
* Handle results from the dataplane system. Dequeue update context
* structs, dispatch to appropriate internal handlers.
*/
-static int rib_process_dplane_results(struct thread *thread)
+static void rib_process_dplane_results(struct thread *thread)
{
struct zebra_dplane_ctx *ctx;
struct dplane_ctx_q ctxlist;
@@ -4300,6 +4320,10 @@ static int rib_process_dplane_results(struct thread *thread)
zebra_if_addr_update_ctx(ctx);
break;
+ case DPLANE_OP_INTF_NETCONFIG:
+ zebra_if_netconf_update_ctx(ctx);
+ break;
+
/* Some op codes not handled here */
case DPLANE_OP_ADDR_INSTALL:
case DPLANE_OP_ADDR_UNINSTALL:
@@ -4325,8 +4349,6 @@ static int rib_process_dplane_results(struct thread *thread)
}
} while (1);
-
- return 0;
}
/*