diff options
Diffstat (limited to 'zebra/zebra_rib.c')
| -rw-r--r-- | zebra/zebra_rib.c | 123 |
1 files changed, 50 insertions, 73 deletions
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 0fa9a79c31..300c2143cb 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -1292,7 +1292,10 @@ rib_install_kernel (struct route_node *rn, struct rib *rib, int update) ret = kernel_add_ipv4 (&rn->p, rib); break; case AF_INET6: - ret = kernel_add_ipv6 (&rn->p, rib); + if (update) + ret = kernel_update_ipv6 (&rn->p, rib); + else + ret = kernel_add_ipv6 (&rn->p, rib); break; } @@ -1427,7 +1430,6 @@ rib_process (struct route_node *rn) struct nexthop *nexthop = NULL, *tnexthop; int recursing; char buf[INET6_ADDRSTRLEN]; - int update_ok = 0; assert (rn); @@ -1560,30 +1562,21 @@ rib_process (struct route_node *rn) { zfpm_trigger_update (rn, "updating existing route"); - if (! RIB_SYSTEM_ROUTE (select)) - { - /* For v4, use the replace semantics of netlink. */ - if (PREFIX_FAMILY (&rn->p) == AF_INET) - update_ok = 1; - else - rib_uninstall_kernel (rn, select); - } - - /* Set real nexthop. */ /* Need to check if any NHs are active to clear the * the selected flag */ if (nexthop_active_update (rn, select, 1)) { - /* Clear FIB flag for IPv4, install will set it */ - if (update_ok) + if (! RIB_SYSTEM_ROUTE (select)) { + /* Clear FIB flag if performing a replace, will get set again + * as part of install. + */ for (nexthop = select->nexthop; nexthop; nexthop = nexthop->next) UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); + rib_install_kernel (rn, select, 1); } - if (! RIB_SYSTEM_ROUTE (select)) - rib_install_kernel (rn, select, update_ok); /* assuming that the receiver knows how to dedup */ redistribute_update (&rn->p, select, NULL); @@ -1593,8 +1586,8 @@ rib_process (struct route_node *rn) /* Withdraw unreachable redistribute route */ redistribute_delete(&rn->p, select); - /* For IPv4, do the uninstall here. */ - if (update_ok) + /* Do the uninstall here, if not done earlier. */ + if (! RIB_SYSTEM_ROUTE (select)) rib_uninstall_kernel (rn, select); UNSET_FLAG (select->flags, ZEBRA_FLAG_SELECTED); } @@ -1633,25 +1626,16 @@ rib_process (struct route_node *rn) zfpm_trigger_update (rn, "removing existing route"); - /* If there's no route to replace this with, withdraw redistribute */ + /* If there's no route to replace this with, withdraw redistribute and + * uninstall from kernel. + */ if (!select) - redistribute_delete(&rn->p, fib); - - if (! RIB_SYSTEM_ROUTE (fib)) { - /* For v4, use the replace semantics of netlink -- only if there is - * another route to replace this with. - */ - if (PREFIX_FAMILY (&rn->p) == AF_INET) - { - if (!select) - rib_uninstall_kernel (rn, fib); - else - update_ok = 1; - } - else - rib_uninstall_kernel (rn, fib); + redistribute_delete(&rn->p, fib); + if (! RIB_SYSTEM_ROUTE (fib)) + rib_uninstall_kernel (rn, fib); } + UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED); /* Set real nexthop. */ @@ -1674,15 +1658,25 @@ rib_process (struct route_node *rn) /* Set real nexthop. */ if (nexthop_active_update (rn, select, 1)) { - /* Clear FIB flag for IPv4 for previous installed route. */ - if (update_ok) + if (! RIB_SYSTEM_ROUTE (select)) + { + /* Clear FIB flag if performing a replace, will get set again + * as part of install. + */ + if (fib) + { + for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next) + UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); + } + rib_install_kernel (rn, select, fib? 1 : 0); + } + else { - assert (fib); - for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next) - UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); + /* Uninstall prior route here, if needed. */ + if (fib && !RIB_SYSTEM_ROUTE (fib)) + rib_uninstall_kernel (rn, fib); } - if (! RIB_SYSTEM_ROUTE (select)) - rib_install_kernel (rn, select, update_ok); + SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED); /* Unconditionally announce, this part is exercised by new routes */ /* If we cannot add, for example route added is learnt by the */ @@ -1692,12 +1686,9 @@ rib_process (struct route_node *rn) } else { - /* For IPv4, uninstall prior route here, if any. */ - if (update_ok) - { - assert (fib); - rib_uninstall_kernel (rn, fib); - } + /* Uninstall prior route here, if needed. */ + if (fib && !RIB_SYSTEM_ROUTE (fib)) + rib_uninstall_kernel (rn, fib); /* if "select", the earlier redist delete wouldn't have happened */ if (fib) redistribute_delete(&rn->p, fib); @@ -2864,31 +2855,17 @@ static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_ UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) { - if (afi == AFI_IP) - { - /* If there are other active nexthops, do an update. */ - if (rib->nexthop_active_num > 1) - { - rib_install_kernel (rn, rib, 1); - redistribute_update (&rn->p, rib, NULL); - } - else - { - redistribute_delete (&rn->p, rib); - rib_uninstall_kernel (rn, rib); - } - } - else - { - redistribute_delete (&rn->p, rib); - rib_uninstall_kernel (rn, rib); - /* Are there other active nexthops? */ - if (rib->nexthop_active_num > 1) - { - rib_install_kernel (rn, rib, 0); - redistribute_update (&rn->p, rib, NULL); - } - } + /* If there are other active nexthops, do an update. */ + if (rib->nexthop_active_num > 1) + { + rib_install_kernel (rn, rib, 1); + redistribute_update (&rn->p, rib, NULL); + } + else + { + redistribute_delete (&rn->p, rib); + rib_uninstall_kernel (rn, rib); + } } if (afi == AFI_IP) @@ -3885,7 +3862,7 @@ rib_tables_iter_next (rib_tables_iter_t *iter) { case RIB_TABLES_ITER_S_INIT: - iter->vrf_id = 0; + iter->vrf_id = VRF_DEFAULT; iter->afi_safi_ix = -1; /* Fall through */ |
