From 26e2ae362baf207d82e4c1ac76bc1c2b2df6ccaa Mon Sep 17 00:00:00 2001 From: Josh Bailey Date: Thu, 22 Mar 2012 01:09:21 -0700 Subject: zebra: read multipath routes and hw addr from netlink * zebra/rt_netlink.c: - Pick up the hardware address of an interface when we receive a netlink link change message. Extract code for parsing the link-layer hardware address into a new function so we can reuse it. - netlink_routing_table(): Update to handle multipath routes. - netlink_route_change(): Update to handle multipath routes. Fix problem where the metric was not being read out. * zebra/zebra_rib.[ch]: Extern nexthop_ipv4_ifindex_add() -- it is now called from the netlink code. From: Josh Bailey Signed-off-by: Avneesh Sachdev Signed-off-by: David Lamparter --- zebra/zebra_rib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'zebra/zebra_rib.c') diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 12f3fa5a..580b75bb 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -225,7 +225,7 @@ nexthop_ipv4_add (struct rib *rib, struct in_addr *ipv4, struct in_addr *src) return nexthop; } -static struct nexthop * +struct nexthop * nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4, struct in_addr *src, unsigned int ifindex) { -- cgit v1.2.3 From fc328ac9d3d49b871c1139f36deb702a254c0d4f Mon Sep 17 00:00:00 2001 From: Subbaiah Venkata Date: Tue, 27 Mar 2012 16:35:22 -0700 Subject: zebra: add more logs/asserts to rib work queue code * zebra/zebra_rib.c: (rib_queue_add, rib_queue_init) Add some more logs and asserts. From: Subbaiah Venkata Signed-off-by: Avneesh Sachdev Signed-off-by: David Lamparter --- zebra/zebra_rib.c | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) (limited to 'zebra/zebra_rib.c') diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 580b75bb..0035eb6e 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -1271,14 +1271,30 @@ rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn) static void rib_queue_add (struct zebra_t *zebra, struct route_node *rn) { + char buf[INET_ADDRSTRLEN]; + assert (zebra && rn); if (IS_ZEBRA_DEBUG_RIB_Q) + inet_ntop (AF_INET, &rn->p.u.prefix, buf, INET_ADDRSTRLEN); + + /* Pointless to queue a route_node with no RIB entries to add or remove */ + if (!rn->info) { - char buf[INET6_ADDRSTRLEN]; + zlog_debug ("%s: called for route_node (%p, %d) with no ribs", + __func__, rn, rn->lock); + zlog_backtrace(LOG_DEBUG); + return; + } - zlog_info ("%s: %s/%d: work queue added", __func__, - inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN), - rn->p.prefixlen); + if (IS_ZEBRA_DEBUG_RIB_Q) + zlog_info ("%s: %s/%d: work queue added", __func__, buf, rn->p.prefixlen); + + assert (zebra); + + if (zebra->ribq == NULL) + { + zlog_err ("%s: work_queue does not exist!", __func__); + return; } /* @@ -1293,6 +1309,11 @@ rib_queue_add (struct zebra_t *zebra, struct route_node *rn) work_queue_add (zebra->ribq, zebra->mq); rib_meta_queue_add (zebra->mq, rn); + + if (IS_ZEBRA_DEBUG_RIB_Q) + zlog_debug ("%s: %s/%d: rn %p queued", __func__, buf, rn->p.prefixlen, rn); + + return; } /* Create new meta queue. @@ -1320,6 +1341,8 @@ meta_queue_new (void) static void rib_queue_init (struct zebra_t *zebra) { + assert (zebra); + if (! (zebra->ribq = work_queue_new (zebra->master, "route_node processing"))) { @@ -1335,7 +1358,11 @@ rib_queue_init (struct zebra_t *zebra) zebra->ribq->spec.hold = rib_process_hold_time; if (!(zebra->mq = meta_queue_new ())) + { zlog_err ("%s: could not initialise meta queue!", __func__); + return; + } + return; } /* RIB updates are processed via a queue of pointers to route_nodes. -- cgit v1.2.3 From af56d404cd56d94ad3b2ec3f159650eb72baef0a Mon Sep 17 00:00:00 2001 From: Josh Bailey Date: Wed, 21 Mar 2012 18:47:51 -0700 Subject: zebra: clean up client routes when client goes away * zebra/zebra_rib.c: Add code to clean up routes added by a client (as identfied by 'rib type'). * zebra/zserv.[ch]: Maintain the type of the routes added by a client on the 'zserv' structure -- assume that a given client uses a single route type for now. Clean up routes from a client when the client goes away (in zebra_client_close()). From: Josh Bailey Signed-off-by: Avneesh Sachdev Signed-off-by: David Lamparter --- zebra/zebra_rib.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'zebra/zebra_rib.c') diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 0035eb6e..8da6c84a 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -2905,6 +2905,61 @@ rib_sweep_route (void) rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0)); } +/* Delete routes learned from a given client. */ +/* TODO(wsun) May need to split the sweep process into multiple batches, + * so that the process won't take too long if the table is large. */ +static void +rib_sweep_client_table (struct route_table *table, int rib_type) +{ + struct route_node *rn; + struct rib *rib; + struct rib *next; + int ret = 0; + + if (table) + for (rn = route_top (table); rn; rn = route_next (rn)) + for (rib = rn->info; rib; rib = next) + { + next = rib->next; + + if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED)) + continue; + + if (rib->type == rib_type) + if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)) + { + /* TODO(wsun) Is this mandatory? What about graceful restart/ + * non-stop forwarding */ + ret = rib_uninstall_kernel (rn, rib); + if (! ret) + rib_delnode (rn, rib); + else + zlog_err ("%s: could not delete routes from kernel!", + __func__); + } + else + { + /* Always delete the node. */ + rib_delnode (rn, rib); + } + } +} + +/* Sweep all routes learned from a given client from RIB tables. */ +void +rib_sweep_client_route (struct zserv *client) +{ + assert(client); + int route_type = client->route_type; + if (route_type != ZEBRA_ROUTE_MAX) + { + zlog_debug ("%s: Removing existing routes from client type %d", + __func__, route_type); + rib_sweep_client_table (vrf_table (AFI_IP, SAFI_UNICAST, 0), route_type); + rib_sweep_client_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0), route_type); + } +} + /* Close RIB and clean up kernel routes. */ static void rib_close_table (struct route_table *table) -- cgit v1.2.3