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.c102
1 files changed, 27 insertions, 75 deletions
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 574083ae02..0226c355c8 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -503,7 +503,7 @@ struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t vrf_id,
/* Lookup table. */
table = zebra_vrf_table(afi, safi, vrf_id);
if (!table)
- return 0;
+ return NULL;
memset(&p, 0, sizeof(p));
p.family = afi;
@@ -552,65 +552,6 @@ struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t vrf_id,
return NULL;
}
-struct route_entry *rib_match_multicast(afi_t afi, vrf_id_t vrf_id,
- union g_addr *gaddr,
- struct route_node **rn_out)
-{
- struct route_entry *re = NULL, *mre = NULL, *ure = NULL;
- struct route_node *m_rn = NULL, *u_rn = NULL;
-
- switch (zrouter.ipv4_multicast_mode) {
- case MCAST_MRIB_ONLY:
- return rib_match(afi, SAFI_MULTICAST, vrf_id, gaddr, rn_out);
- case MCAST_URIB_ONLY:
- return rib_match(afi, SAFI_UNICAST, vrf_id, gaddr, rn_out);
- case MCAST_NO_CONFIG:
- case MCAST_MIX_MRIB_FIRST:
- re = mre = rib_match(afi, SAFI_MULTICAST, vrf_id, gaddr, &m_rn);
- if (!mre)
- re = ure = rib_match(afi, SAFI_UNICAST, vrf_id, gaddr,
- &u_rn);
- break;
- case MCAST_MIX_DISTANCE:
- mre = rib_match(afi, SAFI_MULTICAST, vrf_id, gaddr, &m_rn);
- ure = rib_match(afi, SAFI_UNICAST, vrf_id, gaddr, &u_rn);
- if (mre && ure)
- re = ure->distance < mre->distance ? ure : mre;
- else if (mre)
- re = mre;
- else if (ure)
- re = ure;
- break;
- case MCAST_MIX_PFXLEN:
- mre = rib_match(afi, SAFI_MULTICAST, vrf_id, gaddr, &m_rn);
- ure = rib_match(afi, SAFI_UNICAST, vrf_id, gaddr, &u_rn);
- if (mre && ure)
- re = u_rn->p.prefixlen > m_rn->p.prefixlen ? ure : mre;
- else if (mre)
- re = mre;
- else if (ure)
- re = ure;
- break;
- }
-
- if (rn_out)
- *rn_out = (re == mre) ? m_rn : u_rn;
-
- if (IS_ZEBRA_DEBUG_RIB) {
- char buf[BUFSIZ];
- inet_ntop(afi == AFI_IP ? AF_INET : AF_INET6, gaddr, buf,
- BUFSIZ);
-
- zlog_debug("%s: %s: %pRN vrf: %s(%u) found %s, using %s",
- __func__, buf, (re == mre) ? m_rn : u_rn,
- vrf_id_to_name(vrf_id), vrf_id,
- mre ? (ure ? "MRIB+URIB" : "MRIB")
- : ure ? "URIB" : "nothing",
- re == ure ? "URIB" : re == mre ? "MRIB" : "none");
- }
- return re;
-}
-
/*
* Is this RIB labeled-unicast? It must be of type BGP and all paths
* (nexthops) must have a label.
@@ -1480,7 +1421,7 @@ static void rib_process(struct route_node *rn)
rib_process_update_fib(zvrf, rn, old_fib, new_fib);
else if (new_fib)
rib_process_add_fib(zvrf, rn, new_fib);
- else if (old_fib)
+ else if (old_fib && !RIB_SYSTEM_ROUTE(old_fib))
rib_process_del_fib(zvrf, rn, old_fib);
/* Remove all RE entries queued for removal */
@@ -2838,6 +2779,8 @@ static void process_subq_early_route_add(struct zebra_early_route *ere)
if (!ere->startup && (re->flags & ZEBRA_FLAG_SELFROUTE) &&
zrouter.asic_offloaded) {
+ struct route_entry *entry;
+
if (!same) {
if (IS_ZEBRA_DEBUG_RIB)
zlog_debug(
@@ -2854,6 +2797,25 @@ static void process_subq_early_route_add(struct zebra_early_route *ere)
early_route_memory_free(ere);
return;
}
+
+ RNODE_FOREACH_RE (rn, entry) {
+ if (CHECK_FLAG(entry->status, ROUTE_ENTRY_REMOVED))
+ continue;
+
+ if (entry->type != ere->re->type)
+ continue;
+
+ /*
+ * If we have an entry that is changed but un
+ * processed and not a self route, then
+ * we should just drop this new self route
+ */
+ if (CHECK_FLAG(entry->status, ROUTE_ENTRY_CHANGED) &&
+ !(entry->flags & ZEBRA_FLAG_SELFROUTE)) {
+ early_route_memory_free(ere);
+ return;
+ }
+ }
}
/* Set default distance by route type. */
@@ -3746,10 +3708,8 @@ static struct meta_queue *meta_queue_new(void)
new = XCALLOC(MTYPE_WORK_QUEUE, sizeof(struct meta_queue));
- for (i = 0; i < MQ_SIZE; i++) {
+ for (i = 0; i < MQ_SIZE; i++)
new->subq[i] = list_new();
- assert(new->subq[i]);
- }
return new;
}
@@ -3935,12 +3895,7 @@ void meta_queue_free(struct meta_queue *mq, struct zebra_vrf *zvrf)
/* initialise zebra rib work queue */
static void rib_queue_init(void)
{
- if (!(zrouter.ribq = work_queue_new(zrouter.master,
- "route_node processing"))) {
- flog_err(EC_ZEBRA_WQ_NONEXISTENT,
- "%s: could not initialise work queue!", __func__);
- return;
- }
+ zrouter.ribq = work_queue_new(zrouter.master, "route_node processing");
/* fill in the work queue spec */
zrouter.ribq->spec.workfunc = &meta_queue_process;
@@ -3950,11 +3905,8 @@ static void rib_queue_init(void)
zrouter.ribq->spec.hold = ZEBRA_RIB_PROCESS_HOLD_TIME;
zrouter.ribq->spec.retry = ZEBRA_RIB_PROCESS_RETRY_TIME;
- if (!(zrouter.mq = meta_queue_new())) {
- flog_err(EC_ZEBRA_WQ_NONEXISTENT,
- "%s: could not initialise meta queue!", __func__);
- return;
- }
+ zrouter.mq = meta_queue_new();
+
return;
}