diff options
| author | Donald Sharp <sharpd@cumulusnetworks.com> | 2015-12-09 04:26:55 -0800 |
|---|---|---|
| committer | Donald Sharp <sharpd@cumulusnetworks.com> | 2015-12-09 04:26:55 -0800 |
| commit | 451e7cd49e081de307b682dc24b0ed850e22edfb (patch) | |
| tree | 9cd6f76b39523cd35703a1583a6ec32bac8849a6 /zebra/zebra_rib.c | |
| parent | f6b66ab319e8afd125f3f8eda69fe0dbf132d513 (diff) | |
| parent | 3d63d59fd1ac70e3bdfc243a40d1cfbc5c547ac6 (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.c | 89 |
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) |
