ifp->vrf_id, RT_TABLE_MAIN, ifp->metric, 0, SAFI_MULTICAST);
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
- zlog_debug ("%s: calling rib_update", __func__);
-
- rib_update (ifp->vrf_id);
+ zlog_debug ("%u: IF %s IPv4 address add/up, scheduling RIB processing",
+ ifp->vrf_id, ifp->name);
+ rib_update (ifp->vrf_id, RIB_UPDATE_IF_CHANGE);
}
/* Add connected IPv4 route to the interface. */
SAFI_MULTICAST);
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
- zlog_debug ("%s: calling rib_update_static", __func__);
+ zlog_debug ("%u: IF %s IPv4 address down, scheduling RIB processing",
+ ifp->vrf_id, ifp->name);
- rib_update_static (ifp->vrf_id);
+ rib_update (ifp->vrf_id, RIB_UPDATE_IF_CHANGE);
}
/* Delete connected IPv4 route to the interface. */
connected_withdraw (ifc);
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
- zlog_debug ("%s: calling rib_update_static", __func__);
+ zlog_debug ("%u: IF %s IPv4 address del, scheduling RIB processing",
+ ifp->vrf_id, ifp->name);
- rib_update_static(ifp->vrf_id);
+ rib_update (ifp->vrf_id, RIB_UPDATE_IF_CHANGE);
}
#ifdef HAVE_IPV6
RT_TABLE_MAIN, ifp->metric, 0, SAFI_UNICAST);
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
- zlog_debug ("%s: calling rib_update", __func__);
+ zlog_debug ("%u: IF %s IPv6 address down, scheduling RIB processing",
+ ifp->vrf_id, ifp->name);
- rib_update (ifp->vrf_id);
+ rib_update (ifp->vrf_id, RIB_UPDATE_IF_CHANGE);
}
/* Add connected IPv6 route to the interface. */
ifp->vrf_id, 0, SAFI_UNICAST);
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
- zlog_debug ("%s: calling rib_update_static", __func__);
+ zlog_debug ("%u: IF %s IPv6 address down, scheduling RIB processing",
+ ifp->vrf_id, ifp->name);
- rib_update_static (ifp->vrf_id);
+ rib_update (ifp->vrf_id, RIB_UPDATE_IF_CHANGE);
}
void
connected_withdraw (ifc);
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
- zlog_debug ("%s: calling rib_update_static", __func__);
+ zlog_debug ("%u: IF %s IPv6 address del, scheduling RIB processing",
+ ifp->vrf_id, ifp->name);
- rib_update_static(ifp->vrf_id);
+ rib_update (ifp->vrf_id, RIB_UPDATE_IF_CHANGE);
}
#endif /* HAVE_IPV6 */
}
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
- zlog_debug ("%s: calling rib_update on interface %s up", __func__,
- ifp->name);
-
- /* Examine all static routes. */
- rib_update (ifp->vrf_id);
+ zlog_debug ("%u: IF %s up, scheduling RIB processing",
+ ifp->vrf_id, ifp->name);
+ rib_update (ifp->vrf_id, RIB_UPDATE_IF_CHANGE);
}
/* Interface goes down. We have to manage different behavior of based
}
}
- /* Examine all static routes which direct to the interface. */
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
- zlog_debug ("%s: calling rib_update_static on interface %s down", __func__,
- ifp->name);
-
- rib_update_static (ifp->vrf_id);
+ zlog_debug ("%u: IF %s down, scheduling RIB processing",
+ ifp->vrf_id, ifp->name);
+ rib_update (ifp->vrf_id, RIB_UPDATE_IF_CHANGE);
if_nbr_ipv6ll_to_ipv4ll_neigh_del_all (ifp);
rib_tables_iter_state_t state;
} rib_tables_iter_t;
+/* Events/reasons triggering a RIB update. */
+typedef enum
+{
+ RIB_UPDATE_IF_CHANGE,
+ RIB_UPDATE_RMAP_CHANGE,
+ RIB_UPDATE_OTHER
+} rib_update_event_t;
+
extern struct nexthop *rib_nexthop_ifindex_add (struct rib *, unsigned int);
extern struct nexthop *rib_nexthop_ifname_add (struct rib *, char *);
extern struct nexthop *rib_nexthop_blackhole_add (struct rib *);
extern struct rib *rib_lookup_ipv4 (struct prefix_ipv4 *, vrf_id_t);
-extern void rib_update (vrf_id_t);
-extern void rib_update_static (vrf_id_t);
+extern void rib_update (vrf_id_t, rib_update_event_t);
extern void rib_weed_tables (void);
extern void rib_sweep_route (void);
extern void rib_close_table (struct route_table *);
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)
proto_rm[AFI_IP][i] = XSTRDUP (MTYPE_ROUTE_MAP_NAME, argv[1]);
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
- zlog_debug ("%s: calling rib_update", __func__);
+ zlog_debug ("%u: IPv4 Routemap config for protocol %s, scheduling RIB processing",
+ VRF_DEFAULT, argv[0]);
- rib_update(VRF_DEFAULT);
+ rib_update(VRF_DEFAULT, RIB_UPDATE_RMAP_CHANGE);
return CMD_SUCCESS;
}
proto_rm[AFI_IP][i] = NULL;
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
- zlog_debug ("%s: calling rib_update", __func__);
-
- rib_update(VRF_DEFAULT);
+ zlog_debug ("%u: IPv4 Routemap unconfig for protocol %s, scheduling RIB processing",
+ VRF_DEFAULT, argv[0]);
+ rib_update(VRF_DEFAULT, RIB_UPDATE_RMAP_CHANGE);
}
return CMD_SUCCESS;
}
proto_rm[AFI_IP6][i] = XSTRDUP (MTYPE_ROUTE_MAP_NAME, argv[1]);
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
- zlog_debug ("%s: calling rib_update", __func__);
+ zlog_debug ("%u: IPv6 Routemap config for protocol %s, scheduling RIB processing",
+ VRF_DEFAULT, argv[0]);
- rib_update(VRF_DEFAULT);
+ rib_update(VRF_DEFAULT, RIB_UPDATE_RMAP_CHANGE);
return CMD_SUCCESS;
}
proto_rm[AFI_IP6][i] = NULL;
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
- zlog_debug ("%s: calling rib_update", __func__);
+ zlog_debug ("%u: IPv6 Routemap unconfig for protocol %s, scheduling RIB processing",
+ VRF_DEFAULT, argv[0]);
- rib_update(VRF_DEFAULT);
+ rib_update(VRF_DEFAULT, RIB_UPDATE_RMAP_CHANGE);
}
return CMD_SUCCESS;
}
zlog_debug("Event driven route-map update triggered");
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
- zlog_debug ("%s: calling rib_update", __func__);
+ zlog_debug ("%u: Routemap update-timer fired, scheduling RIB processing",
+ VRF_DEFAULT);
- rib_update(VRF_DEFAULT);
+ rib_update(VRF_DEFAULT, RIB_UPDATE_RMAP_CHANGE);
zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);