summaryrefslogtreecommitdiff
path: root/zebra/zebra_rib.c
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2015-12-09 04:26:55 -0800
committerDonald Sharp <sharpd@cumulusnetworks.com>2015-12-09 04:26:55 -0800
commit451e7cd49e081de307b682dc24b0ed850e22edfb (patch)
tree9cd6f76b39523cd35703a1583a6ec32bac8849a6 /zebra/zebra_rib.c
parentf6b66ab319e8afd125f3f8eda69fe0dbf132d513 (diff)
parent3d63d59fd1ac70e3bdfc243a40d1cfbc5c547ac6 (diff)
Merge branch 'cmaster' of ssh://stash.cumulusnetworks.com:7999/quag/quagga into cmaster
Diffstat (limited to 'zebra/zebra_rib.c')
-rw-r--r--zebra/zebra_rib.c89
1 files changed, 58 insertions, 31 deletions
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index e41d5d4fad..1859661c13 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -3471,56 +3471,83 @@ static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
return 1;
}
-/* RIB update function. */
-void
-rib_update_static (vrf_id_t vrf_id)
+/* Schedule routes of a particular table (address-family) based on event. */
+static void
+rib_update_table (struct route_table *table, rib_update_event_t event)
{
struct route_node *rn;
- struct route_table *table;
struct rib *rib, *next;
- table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
- if (table)
- for (rn = route_top (table); rn; rn = route_next (rn))
- RNODE_FOREACH_RIB_SAFE (rn, rib, next)
- if (rib->type == ZEBRA_ROUTE_STATIC)
- {
- rib_queue_add (&zebrad, rn);
- break;
- }
+ /* Walk all routes and queue for processing, if appropriate for
+ * the trigger event.
+ */
+ for (rn = route_top (table); rn; rn = route_next (rn))
+ {
+ switch (event)
+ {
+ case RIB_UPDATE_IF_CHANGE:
+ /* Examine all routes that won't get processed by the protocol or
+ * triggered by nexthop evaluation (NHT). This would be system,
+ * kernel and certain static routes. Note that NHT will get
+ * triggered upon an interface event as connected routes always
+ * get queued for processing.
+ */
+ RNODE_FOREACH_RIB_SAFE (rn, rib, next)
+ {
+ if (rib->type == ZEBRA_ROUTE_OSPF ||
+ rib->type == ZEBRA_ROUTE_OSPF6 ||
+ rib->type == ZEBRA_ROUTE_BGP)
+ continue; /* protocol will handle. */
+ else if (rib->type == ZEBRA_ROUTE_STATIC)
+ {
+ struct nexthop *nh;
+ for (nh = rib->nexthop; nh; nh = nh->next)
+ if (!(nh->type == NEXTHOP_TYPE_IPV4 ||
+ nh->type == NEXTHOP_TYPE_IPV6))
+ break;
+
+ /* If we only have nexthops to a gateway, NHT will
+ * take care.
+ */
+ if (nh)
+ rib_queue_add (&zebrad, rn);
+ }
+ else
+ rib_queue_add (&zebrad, rn);
+ }
+ break;
- table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
- if (table)
- for (rn = route_top (table); rn; rn = route_next (rn))
- RNODE_FOREACH_RIB_SAFE (rn, rib, next)
- if (rib->type == ZEBRA_ROUTE_STATIC)
- {
+ case RIB_UPDATE_RMAP_CHANGE:
+ case RIB_UPDATE_OTHER:
+ /* Right now, examine all routes. Can restrict to a protocol in
+ * some cases (TODO).
+ */
+ if (rnode_to_ribs (rn))
rib_queue_add (&zebrad, rn);
- break;
- }
+ break;
+
+ default:
+ break;
+ }
+ }
}
/* RIB update function. */
void
-rib_update (vrf_id_t vrf_id)
+rib_update (vrf_id_t vrf_id, rib_update_event_t event)
{
- struct route_node *rn;
struct route_table *table;
-
+
+ /* Process routes of interested address-families. */
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
if (table)
- for (rn = route_top (table); rn; rn = route_next (rn))
- if (rnode_to_ribs (rn))
- rib_queue_add (&zebrad, rn);
+ rib_update_table (table, event);
table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
if (table)
- for (rn = route_top (table); rn; rn = route_next (rn))
- if (rnode_to_ribs (rn))
- rib_queue_add (&zebrad, rn);
+ rib_update_table (table, event);
}
-
/* Remove all routes which comes from non main table. */
static void
rib_weed_table (struct route_table *table)