diff options
| author | Donald Sharp <sharpd@cumulusnetworks.com> | 2017-09-25 14:33:14 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-09-25 14:33:14 -0400 |
| commit | 5176f7b7135f412eee4b6c2240e851c642e8bd8c (patch) | |
| tree | a2cc51e3818b7ca21a084e4c99768ebcf037ef47 /zebra/zebra_rib.c | |
| parent | d61444089689c2874b510703b238e2b8a4fca4a4 (diff) | |
| parent | 66af68454bbace3e11e0e3a6dd865f2046939487 (diff) | |
Merge pull request #1213 from opensourcerouting/zebra-netlink
Misc RIB/Netlink fixes
Diffstat (limited to 'zebra/zebra_rib.c')
| -rw-r--r-- | zebra/zebra_rib.c | 124 |
1 files changed, 24 insertions, 100 deletions
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index bb49663319..622e001285 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -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; } @@ -2437,70 +2442,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 +2457,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. */ |
