diff options
Diffstat (limited to 'zebra/zebra_rib.c')
| -rw-r--r-- | zebra/zebra_rib.c | 156 |
1 files changed, 52 insertions, 104 deletions
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 00550fa07d..fab8c3c932 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -261,7 +261,7 @@ struct nexthop *route_entry_nexthop_ipv4_ifindex_add(struct route_entry *re, if (src) nexthop->src.ipv4 = *src; nexthop->ifindex = ifindex; - ifp = if_lookup_by_index(nexthop->ifindex, VRF_DEFAULT); + ifp = if_lookup_by_index(nexthop->ifindex, re->vrf_id); /*Pending: need to think if null ifp here is ok during bootup? There was a crash because ifp here was coming to be NULL */ if (ifp) @@ -417,7 +417,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re, * address in the routing table. */ if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK)) { - ifp = if_lookup_by_index(nexthop->ifindex, VRF_DEFAULT); + ifp = if_lookup_by_index(nexthop->ifindex, re->vrf_id); if (ifp && connected_is_unnumbered(ifp)) { if (if_is_operative(ifp)) return 1; @@ -2216,23 +2216,18 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p, struct route_entry *same; struct nexthop *nexthop; int ret = 0; - int family; if (!re) return 0; - if (p->family == AF_INET) - family = AFI_IP; - else - family = AFI_IP6; - - assert(!src_p || family == AFI_IP6); + assert(!src_p || afi == AFI_IP6); /* Lookup table. */ - table = zebra_vrf_table_with_table_id(family, safi, re->vrf_id, - re->table); - if (!table) + table = zebra_vrf_table_with_table_id(afi, safi, re->vrf_id, re->table); + if (!table) { + XFREE(MTYPE_RE, re); return 0; + } /* Make it sure prefixlen is applied to the prefix. */ apply_mask(p); @@ -2258,8 +2253,18 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p, if (CHECK_FLAG(same->status, ROUTE_ENTRY_REMOVED)) continue; - if (same->type == re->type && same->instance == re->instance - && same->table == re->table && !RIB_SYSTEM_ROUTE(same)) + if (same->type != re->type) + continue; + if (same->instance != re->instance) + continue; + if (same->type == ZEBRA_ROUTE_KERNEL && + same->metric != re->metric) + continue; + /* + * We should allow duplicate connected routes because of + * IPv6 link-local routes and unnumbered interfaces on Linux. + */ + if (same->type != ZEBRA_ROUTE_CONNECT) break; } @@ -2294,7 +2299,7 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p, void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, int flags, struct prefix *p, struct prefix_ipv6 *src_p, const struct nexthop *nh, - u_int32_t table_id, u_int32_t metric) + u_int32_t table_id, u_int32_t metric, bool fromkernel) { struct route_table *table; struct route_node *rn; @@ -2375,6 +2380,21 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, /* If same type of route can't be found and this message is from kernel. */ if (!same) { + /* + * In the past(HA!) we could get here because + * we were receiving a route delete from the + * kernel and we're not marking the proto + * as coming from it's appropriate originator. + * Now that we are properly noticing the fact + * that the kernel has deleted our route we + * are not going to get called in this path + * I am going to leave this here because + * this might still work this way on non-linux + * platforms as well as some weird state I have + * not properly thought of yet. + * If we can show that this code path is + * dead then we can remove it. + */ if (fib && type == ZEBRA_ROUTE_KERNEL && CHECK_FLAG(flags, ZEBRA_FLAG_SELFROUTE)) { if (IS_ZEBRA_DEBUG_RIB) { @@ -2423,8 +2443,17 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, } } - if (same) + if (same) { + if (fromkernel && + CHECK_FLAG(flags, ZEBRA_FLAG_SELFROUTE) && + !allow_delete) { + rib_install_kernel(rn, same, NULL); + route_unlock_node(rn); + + return; + } rib_delnode(rn, same); + } route_unlock_node(rn); return; @@ -2437,70 +2466,10 @@ int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, u_int32_t mtu, u_char distance) { struct route_entry *re; - struct route_entry *same = NULL; - struct route_table *table; - struct route_node *rn; - struct nexthop *rtnh; - - assert(!src_p || afi == AFI_IP6); - - /* Lookup table. */ - table = zebra_vrf_table_with_table_id(afi, safi, vrf_id, table_id); - if (!table) - return 0; - - /* Make sure mask is applied. */ - apply_mask(p); - if (src_p) - apply_mask_ipv6(src_p); - - /* Set default distance by route type. */ - if (distance == 0) { - distance = route_distance(type); - - /* iBGP distance is 200. */ - if (type == ZEBRA_ROUTE_BGP - && CHECK_FLAG(flags, ZEBRA_FLAG_IBGP)) - distance = 200; - } - - /* Lookup route node.*/ - rn = srcdest_rnode_get(table, p, src_p); - - /* If same type of route are installed, treat it as a implicit - withdraw. */ - RNODE_FOREACH_RE (rn, re) { - if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED)) - continue; - - if (re->type != type) - continue; - if (re->instance != instance) - continue; - if (re->type == ZEBRA_ROUTE_KERNEL && - re->metric != metric) - continue; - if (!RIB_SYSTEM_ROUTE(re)) { - same = re; - break; - } - /* Duplicate system route comes in. */ - rtnh = re->nexthop; - if (nexthop_same_no_recurse(rtnh, nh)) - return 0; - /* - * Nexthop is different. Remove the old route unless it's - * a connected route. This exception is necessary because - * of IPv6 link-local routes and unnumbered interfaces on - * Linux. - */ - else if (type != ZEBRA_ROUTE_CONNECT) - same = re; - } + struct nexthop *nexthop; - /* Allocate new re structure. */ + /* Allocate new route_entry structure. */ re = XCALLOC(MTYPE_RE, sizeof(struct route_entry)); - re->type = type; re->instance = instance; re->distance = distance; @@ -2512,33 +2481,12 @@ int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, re->nexthop_num = 0; re->uptime = time(NULL); - rtnh = nexthop_new(); - *rtnh = *nh; - route_entry_nexthop_add(re, rtnh); - - /* If this route is kernel route, set FIB flag to the route. */ - if (RIB_SYSTEM_ROUTE(re)) - for (rtnh = re->nexthop; rtnh; rtnh = rtnh->next) - SET_FLAG(rtnh->flags, NEXTHOP_FLAG_FIB); - - /* Link new rib to node.*/ - if (IS_ZEBRA_DEBUG_RIB) { - rnode_debug( - rn, vrf_id, - "Inserting route rn %p, re %p (type %d) existing %p", - (void *)rn, (void *)re, re->type, (void *)same); - - if (IS_ZEBRA_DEBUG_RIB_DETAILED) - route_entry_dump(p, src_p, re); - } - rib_addnode(rn, re, 1); - - /* Free implicit route.*/ - if (same) - rib_delnode(rn, same); + /* Add nexthop. */ + nexthop = nexthop_new(); + *nexthop = *nh; + route_entry_nexthop_add(re, nexthop); - route_unlock_node(rn); - return 0; + return rib_add_multipath(afi, safi, p, src_p, re); } /* Schedule routes of a particular table (address-family) based on event. */ |
