diff options
Diffstat (limited to 'zebra/zebra_rib.c')
| -rw-r--r-- | zebra/zebra_rib.c | 444 |
1 files changed, 151 insertions, 293 deletions
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index ffa3161f2b..0bb9b58118 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -139,7 +139,6 @@ zebra_check_addr (struct prefix *p) || IPV4_LINKLOCAL(addr)) return 0; } -#ifdef HAVE_IPV6 if (p->family == AF_INET6) { if (IN6_IS_ADDR_LOOPBACK (&p->u.prefix6)) @@ -147,7 +146,6 @@ zebra_check_addr (struct prefix *p) if (IN6_IS_ADDR_LINKLOCAL(&p->u.prefix6)) return 0; } -#endif /* HAVE_IPV6 */ return 1; } @@ -348,7 +346,6 @@ nexthop_ipv4_ifindex_ol_add (struct rib *rib, const struct in_addr *ipv4, return nexthop; } -#ifdef HAVE_IPV6 struct nexthop * nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6) { @@ -394,7 +391,6 @@ nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6, return nexthop; } -#endif /* HAVE_IPV6 */ struct nexthop * nexthop_blackhole_add (struct rib *rib) @@ -650,7 +646,6 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set, return 0; } -#ifdef HAVE_IPV6 /* If force flag is not set, do not modify falgs at all for uninstall the route from FIB. */ static int @@ -840,7 +835,6 @@ nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set, } return 0; } -#endif /* HAVE_IPV6 */ struct rib * rib_match_ipv4 (struct in_addr addr, vrf_id_t vrf_id) @@ -1026,7 +1020,6 @@ rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate, return ZEBRA_RIB_NOTFOUND; } -#ifdef HAVE_IPV6 struct rib * rib_match_ipv6 (struct in6_addr *addr, vrf_id_t vrf_id) { @@ -1088,7 +1081,6 @@ rib_match_ipv6 (struct in6_addr *addr, vrf_id_t vrf_id) } return NULL; } -#endif /* HAVE_IPV6 */ #define RIB_SYSTEM_ROUTE(R) \ ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT) @@ -1153,7 +1145,6 @@ nexthop_active_check (struct route_node *rn, struct rib *rib, else UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); break; -#ifdef HAVE_IPV6 case NEXTHOP_TYPE_IPV6: family = AFI_IP6; if (nexthop_active_ipv6 (rib, nexthop, set, rn)) @@ -1181,7 +1172,6 @@ nexthop_active_check (struct route_node *rn, struct rib *rib, UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); } break; -#endif /* HAVE_IPV6 */ case NEXTHOP_TYPE_BLACKHOLE: SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); break; @@ -1305,11 +1295,9 @@ rib_install_kernel (struct route_node *rn, struct rib *rib, int update) else ret = kernel_add_ipv4 (&rn->p, rib); break; -#ifdef HAVE_IPV6 case AF_INET6: ret = kernel_add_ipv6 (&rn->p, rib); break; -#endif /* HAVE_IPV6 */ } /* This condition is never met, if we are using rt_socket.c */ @@ -1339,11 +1327,9 @@ rib_uninstall_kernel (struct route_node *rn, struct rib *rib) case AF_INET: ret = kernel_delete_ipv4 (&rn->p, rib); break; -#ifdef HAVE_IPV6 case AF_INET6: ret = kernel_delete_ipv6 (&rn->p, rib); break; -#endif /* HAVE_IPV6 */ } for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) @@ -1781,10 +1767,8 @@ meta_queue_process_complete (struct work_queue *dummy) { zebra_evaluate_rnh(0, AF_INET, 0, RNH_NEXTHOP_TYPE, NULL); zebra_evaluate_rnh(0, AF_INET, 0, RNH_IMPORT_CHECK_TYPE, NULL); -#ifdef HAVE_IPV6 zebra_evaluate_rnh(0, AF_INET6, 0, RNH_NEXTHOP_TYPE, NULL); zebra_evaluate_rnh(0, AF_INET6, 0, RNH_IMPORT_CHECK_TYPE, NULL); -#endif /* HAVE_IPV6 */ } /* Dispatch the meta queue by picking, processing and unlocking the next RN from @@ -1967,7 +1951,7 @@ rib_queue_init (struct zebra_t *zebra) * as a route_node will not be requeued, if already queued. * * RIBs are submitted via rib_addnode or rib_delnode which set minimal - * state, or static_install_ipv{4,6} (when an existing RIB is updated) + * state, or static_install_route (when an existing RIB is updated) * and then submit route_node to queue for best-path selection later. * Order of add/delete state changes are preserved for any given RIB. * @@ -2678,7 +2662,7 @@ rib_delete_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p, /* Install static route into rib. */ static void -static_install_ipv4 (struct prefix *p, struct static_ipv4 *si) +static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si) { struct rib *rib; struct route_node *rn; @@ -2686,7 +2670,7 @@ static_install_ipv4 (struct prefix *p, struct static_ipv4 *si) struct prefix nh_p; /* Lookup table. */ - table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, si->vrf_id); + table = zebra_vrf_table (afi, safi, si->vrf_id); if (! table) return; @@ -2712,19 +2696,32 @@ static_install_ipv4 (struct prefix *p, struct static_ipv4 *si) route_unlock_node (rn); switch (si->type) { - case STATIC_IPV4_GATEWAY: - nexthop_ipv4_add (rib, &si->gate.ipv4, NULL); - nh_p.family = AF_INET; - nh_p.prefixlen = IPV4_MAX_BITLEN; - nh_p.u.prefix4 = si->gate.ipv4; - zebra_register_rnh_static_nh(&nh_p, rn); - break; - case STATIC_IPV4_IFNAME: - nexthop_ifname_add (rib, si->gate.ifname); - break; - case STATIC_IPV4_BLACKHOLE: - nexthop_blackhole_add (rib); - break; + case STATIC_IPV4_GATEWAY: + nexthop_ipv4_add (rib, &si->addr.ipv4, NULL); + nh_p.family = AF_INET; + nh_p.prefixlen = IPV4_MAX_BITLEN; + nh_p.u.prefix4 = si->addr.ipv4; + zebra_register_rnh_static_nh(&nh_p, rn); + break; + case STATIC_IPV4_IFNAME: + nexthop_ifname_add (rib, si->ifname); + break; + case STATIC_IPV4_BLACKHOLE: + nexthop_blackhole_add (rib); + break; + case STATIC_IPV6_GATEWAY: + nexthop_ipv6_add (rib, &si->addr.ipv6); + nh_p.family = AF_INET6; + nh_p.prefixlen = IPV6_MAX_BITLEN; + nh_p.u.prefix6 = si->addr.ipv6; + zebra_register_rnh_static_nh(&nh_p, rn); + break; + case STATIC_IPV6_IFNAME: + nexthop_ifname_add (rib, si->ifname); + break; + case STATIC_IPV6_GATEWAY_IFNAME: + nexthop_ipv6_ifname_add (rib, &si->addr.ipv6, si->ifname); + break; } rib_queue_add (&zebrad, rn); } @@ -2744,19 +2741,32 @@ static_install_ipv4 (struct prefix *p, struct static_ipv4 *si) switch (si->type) { - case STATIC_IPV4_GATEWAY: - nexthop_ipv4_add (rib, &si->gate.ipv4, NULL); - nh_p.family = AF_INET; - nh_p.prefixlen = IPV4_MAX_BITLEN; - nh_p.u.prefix4 = si->gate.ipv4; - zebra_register_rnh_static_nh(&nh_p, rn); - break; - case STATIC_IPV4_IFNAME: - nexthop_ifname_add (rib, si->gate.ifname); - break; - case STATIC_IPV4_BLACKHOLE: - nexthop_blackhole_add (rib); - break; + case STATIC_IPV4_GATEWAY: + nexthop_ipv4_add (rib, &si->addr.ipv4, NULL); + nh_p.family = AF_INET; + nh_p.prefixlen = IPV4_MAX_BITLEN; + nh_p.u.prefix4 = si->addr.ipv4; + zebra_register_rnh_static_nh(&nh_p, rn); + break; + case STATIC_IPV4_IFNAME: + nexthop_ifname_add (rib, si->ifname); + break; + case STATIC_IPV4_BLACKHOLE: + nexthop_blackhole_add (rib); + break; + case STATIC_IPV6_GATEWAY: + nexthop_ipv6_add (rib, &si->addr.ipv6); + nh_p.family = AF_INET6; + nh_p.prefixlen = IPV6_MAX_BITLEN; + nh_p.u.prefix6 = si->addr.ipv6; + zebra_register_rnh_static_nh(&nh_p, rn); + break; + case STATIC_IPV6_IFNAME: + nexthop_ifname_add (rib, si->ifname); + break; + case STATIC_IPV6_GATEWAY_IFNAME: + nexthop_ipv6_ifname_add (rib, &si->addr.ipv6, si->ifname); + break; } /* Save the flags of this static routes (reject, blackhole) */ @@ -2768,25 +2778,38 @@ static_install_ipv4 (struct prefix *p, struct static_ipv4 *si) } static int -static_ipv4_nexthop_same (struct nexthop *nexthop, struct static_ipv4 *si) +static_nexthop_same (struct nexthop *nexthop, struct static_route *si) { if (nexthop->type == NEXTHOP_TYPE_IPV4 && si->type == STATIC_IPV4_GATEWAY - && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->gate.ipv4)) + && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->addr.ipv4)) return 1; if (nexthop->type == NEXTHOP_TYPE_IFNAME && si->type == STATIC_IPV4_IFNAME - && strcmp (nexthop->ifname, si->gate.ifname) == 0) + && strcmp (nexthop->ifname, si->ifname) == 0) return 1; if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE && si->type == STATIC_IPV4_BLACKHOLE) return 1; + if (nexthop->type == NEXTHOP_TYPE_IPV6 + && si->type == STATIC_IPV6_GATEWAY + && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->addr.ipv6)) + return 1; + if (nexthop->type == NEXTHOP_TYPE_IFNAME + && si->type == STATIC_IPV6_IFNAME + && strcmp (nexthop->ifname, si->ifname) == 0) + return 1; + if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME + && si->type == STATIC_IPV6_GATEWAY_IFNAME + && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->addr.ipv6) + && strcmp (nexthop->ifname, si->ifname) == 0) + return 1; return 0; } /* Uninstall static route from RIB. */ static void -static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si) +static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si) { struct route_node *rn; struct rib *rib; @@ -2795,7 +2818,7 @@ static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si) struct prefix nh_p; /* Lookup table. */ - table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, si->vrf_id); + table = zebra_vrf_table (afi, safi, si->vrf_id); if (! table) return; @@ -2822,7 +2845,7 @@ static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si) /* Lookup nexthop. */ for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) - if (static_ipv4_nexthop_same (nexthop, si)) + if (static_nexthop_same (nexthop, si)) break; /* Can't find nexthop. */ @@ -2844,23 +2867,46 @@ static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si) UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) { - /* 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 + 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); + } } } - /* Delete the nexthop and dereg from NHT */ - nh_p.family = AF_INET; - nh_p.prefixlen = IPV4_MAX_BITLEN; - nh_p.u.prefix4 = nexthop->gate.ipv4; + if (afi == AFI_IP) + { + /* Delete the nexthop and dereg from NHT */ + nh_p.family = AF_INET; + nh_p.prefixlen = IPV4_MAX_BITLEN; + nh_p.u.prefix4 = nexthop->gate.ipv4; + } + else + { + nh_p.family = AF_INET6; + nh_p.prefixlen = IPV6_MAX_BITLEN; + nh_p.u.prefix6 = nexthop->gate.ipv6; + } nexthop_delete (rib, nexthop); zebra_deregister_rnh_static_nh(&nh_p, rn); nexthop_free (nexthop, rn); @@ -2876,10 +2922,10 @@ static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname, { u_char type = 0; struct route_node *rn; - struct static_ipv4 *si; - struct static_ipv4 *pp; - struct static_ipv4 *cp; - struct static_ipv4 *update = NULL; + struct static_route *si; + struct static_route *pp; + struct static_route *cp; + struct static_route *update = NULL; struct zebra_vrf *zvrf = vrf_info_get (vrf_id); struct route_table *stable = zvrf->stable[AFI_IP][SAFI_UNICAST]; @@ -2901,8 +2947,8 @@ static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname, for (si = rn->info; si; si = si->next) { if (type == si->type - && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4)) - && (! ifname || strcmp (ifname, si->gate.ifname) == 0)) + && (! gate || IPV4_ADDR_SAME (gate, &si->addr.ipv4)) + && (! ifname || strcmp (ifname, si->ifname) == 0)) { if ((distance == si->distance) && (tag == si->tag)) { @@ -2919,7 +2965,7 @@ static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname, static_delete_ipv4 (p, gate, ifname, update->tag, update->distance, vrf_id); /* Make new static route structure. */ - si = XCALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4)); + si = XCALLOC (MTYPE_STATIC_ROUTE, sizeof (struct static_route)); si->type = type; si->distance = distance; @@ -2928,9 +2974,9 @@ static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname, si->vrf_id = vrf_id; if (gate) - si->gate.ipv4 = *gate; + si->addr.ipv4 = *gate; if (ifname) - si->gate.ifname = XSTRDUP (0, ifname); + si->ifname = XSTRDUP (0, ifname); /* Add new static route information to the tree with sort by distance value and gateway address. */ @@ -2942,9 +2988,9 @@ static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname, continue; if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY) { - if (ntohl (si->gate.ipv4.s_addr) < ntohl (cp->gate.ipv4.s_addr)) + if (ntohl (si->addr.ipv4.s_addr) < ntohl (cp->addr.ipv4.s_addr)) break; - if (ntohl (si->gate.ipv4.s_addr) > ntohl (cp->gate.ipv4.s_addr)) + if (ntohl (si->addr.ipv4.s_addr) > ntohl (cp->addr.ipv4.s_addr)) continue; } } @@ -2960,7 +3006,7 @@ static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname, si->next = cp; /* Install into rib. */ - static_install_ipv4 (p, si); + static_install_route (AFI_IP, SAFI_UNICAST, p, si); return 1; } @@ -2972,7 +3018,7 @@ static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname, { u_char type = 0; struct route_node *rn; - struct static_ipv4 *si; + struct static_route *si; struct route_table *stable; /* Lookup table. */ @@ -2996,8 +3042,8 @@ static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname, /* Find same static route is the tree */ for (si = rn->info; si; si = si->next) if (type == si->type - && (! gate || IPV4_ADDR_SAME (gate, &si->gate.ipv4)) - && (! ifname || strcmp (ifname, si->gate.ifname) == 0) + && (! gate || IPV4_ADDR_SAME (gate, &si->addr.ipv4)) + && (! ifname || strcmp (ifname, si->ifname) == 0) && (! tag || (tag == si->tag))) break; @@ -3009,7 +3055,7 @@ static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname, } /* Install into rib. */ - static_uninstall_ipv4 (p, si); + static_uninstall_route (AFI_IP, SAFI_UNICAST, p, si); /* Unlink static route from linked list. */ if (si->prev) @@ -3022,8 +3068,8 @@ static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname, /* Free static route configuration. */ if (ifname) - XFREE (0, si->gate.ifname); - XFREE (MTYPE_STATIC_IPV4, si); + XFREE (0, si->ifname); + XFREE (MTYPE_STATIC_ROUTE, si); route_unlock_node (rn); @@ -3031,7 +3077,6 @@ static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname, } -#ifdef HAVE_IPV6 int rib_bogus_ipv6 (int type, struct prefix_ipv6 *p, struct in6_addr *gate, unsigned int ifindex, int table) @@ -3442,200 +3487,6 @@ rib_delete_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p, return 0; } -/* Install static route into rib. */ -static void -static_install_ipv6 (struct prefix *p, struct static_ipv6 *si) -{ - struct rib *rib; - struct route_table *table; - struct route_node *rn; - struct prefix nh_p; - - /* Lookup table. */ - table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, si->vrf_id); - if (! table) - return; - - /* Lookup existing route */ - rn = route_node_get (table, p); - RNODE_FOREACH_RIB (rn, rib) - { - if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED)) - continue; - - if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance) - break; - } - - if (rib) - { - /* if tag value changed , update old value in RIB */ - if (rib->tag != si->tag) - rib->tag = si->tag; - - /* Same distance static route is there. Update it with new - nexthop. */ - route_unlock_node (rn); - - switch (si->type) - { - case STATIC_IPV6_GATEWAY: - nexthop_ipv6_add (rib, &si->ipv6); - nh_p.family = AF_INET6; - nh_p.prefixlen = IPV6_MAX_BITLEN; - nh_p.u.prefix6 = si->ipv6; - zebra_register_rnh_static_nh(&nh_p, rn); - break; - case STATIC_IPV6_IFNAME: - nexthop_ifname_add (rib, si->ifname); - break; - case STATIC_IPV6_GATEWAY_IFNAME: - nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname); - break; - } - rib_queue_add (&zebrad, rn); - } - else - { - /* This is new static route. */ - rib = XCALLOC (MTYPE_RIB, sizeof (struct rib)); - - rib->type = ZEBRA_ROUTE_STATIC; - rib->instance = 0; - rib->distance = si->distance; - rib->metric = 0; - rib->vrf_id = si->vrf_id; - rib->table = zebrad.rtm_table_default; - rib->nexthop_num = 0; - rib->tag = si->tag; - - switch (si->type) - { - case STATIC_IPV6_GATEWAY: - nexthop_ipv6_add (rib, &si->ipv6); - nh_p.family = AF_INET6; - nh_p.prefixlen = IPV6_MAX_BITLEN; - nh_p.u.prefix6 = si->ipv6; - zebra_register_rnh_static_nh(&nh_p, rn); - break; - case STATIC_IPV6_IFNAME: - nexthop_ifname_add (rib, si->ifname); - break; - case STATIC_IPV6_GATEWAY_IFNAME: - nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname); - break; - } - - /* Save the flags of this static routes (reject, blackhole) */ - rib->flags = si->flags; - - /* Link this rib to the tree. */ - rib_addnode (rn, rib); - } -} - -static int -static_ipv6_nexthop_same (struct nexthop *nexthop, struct static_ipv6 *si) -{ - if (nexthop->type == NEXTHOP_TYPE_IPV6 - && si->type == STATIC_IPV6_GATEWAY - && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6)) - return 1; - if (nexthop->type == NEXTHOP_TYPE_IFNAME - && si->type == STATIC_IPV6_IFNAME - && strcmp (nexthop->ifname, si->ifname) == 0) - return 1; - if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME - && si->type == STATIC_IPV6_GATEWAY_IFNAME - && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->ipv6) - && strcmp (nexthop->ifname, si->ifname) == 0) - return 1; - return 0; -} - -static void -static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si) -{ - struct route_table *table; - struct route_node *rn; - struct rib *rib; - struct nexthop *nexthop; - struct prefix nh_p; - - /* Lookup table. */ - table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, si->vrf_id); - if (! table) - return; - - /* Lookup existing route with type and distance. */ - rn = route_node_lookup (table, (struct prefix *) p); - if (! rn) - return; - - RNODE_FOREACH_RIB (rn, rib) - { - if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED)) - continue; - - if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance && - rib->tag == si->tag) - break; - } - - if (! rib) - { - route_unlock_node (rn); - return; - } - - /* Lookup nexthop. */ - for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) - if (static_ipv6_nexthop_same (nexthop, si)) - break; - - /* Can't find nexthop. */ - if (! nexthop) - { - route_unlock_node (rn); - return; - } - - /* Check nexthop. */ - if (rib->nexthop_num == 1) - { - rib_delnode (rn, rib); - } - else - { - /* Mark this nexthop as inactive and reinstall the route. Then, delete - * the nexthop. There is no need to re-evaluate the route for this - * scenario. - */ - UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); - if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) - { - 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); - } - } - - /* Delete the nexthop and dereg from NHT */ - nh_p.family = AF_INET6; - nh_p.prefixlen = IPV6_MAX_BITLEN; - nh_p.u.prefix6 = nexthop->gate.ipv6; - nexthop_delete (rib, nexthop); - zebra_deregister_rnh_static_nh(&nh_p, rn); - nexthop_free (nexthop, rn); - } - /* Unlock node. */ - route_unlock_node (rn); -} - /* Add static route into static route configuration. */ int static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate, @@ -3643,9 +3494,10 @@ static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate, u_char distance, vrf_id_t vrf_id) { struct route_node *rn; - struct static_ipv6 *si; - struct static_ipv6 *pp; - struct static_ipv6 *cp; + struct static_route *si; + struct static_route *pp; + struct static_route *cp; + struct static_route *update = NULL; struct zebra_vrf *zvrf = vrf_info_get (vrf_id); struct route_table *stable = zvrf->stable[AFI_IP6][SAFI_UNICAST]; @@ -3666,19 +3518,26 @@ static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate, /* Do nothing if there is a same static route. */ for (si = rn->info; si; si = si->next) { - if (distance == si->distance - && type == si->type - && tag == si->tag - && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6)) + if (type == si->type + && (! gate || IPV6_ADDR_SAME (gate, &si->addr.ipv6)) && (! ifname || strcmp (ifname, si->ifname) == 0)) { - route_unlock_node (rn); - return 0; + if ((distance == si->distance) && (tag == si->tag)) + { + route_unlock_node (rn); + return 0; + } + else + update = si; } } + /* Distance or tag changed. */ + if (update) + static_delete_ipv6 (p, type, gate, ifname, update->tag, update->distance, vrf_id); + /* Make new static route structure. */ - si = XCALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6)); + si = XCALLOC (MTYPE_STATIC_ROUTE, sizeof (struct static_route)); si->type = type; si->distance = distance; @@ -3689,13 +3548,13 @@ static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate, switch (type) { case STATIC_IPV6_GATEWAY: - si->ipv6 = *gate; + si->addr.ipv6 = *gate; break; case STATIC_IPV6_IFNAME: si->ifname = XSTRDUP (0, ifname); break; case STATIC_IPV6_GATEWAY_IFNAME: - si->ipv6 = *gate; + si->addr.ipv6 = *gate; si->ifname = XSTRDUP (0, ifname); break; } @@ -3721,7 +3580,7 @@ static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate, si->next = cp; /* Install into rib. */ - static_install_ipv6 (p, si); + static_install_route (AFI_IP6, SAFI_UNICAST, p, si); return 1; } @@ -3733,7 +3592,7 @@ static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate, vrf_id_t vrf_id) { struct route_node *rn; - struct static_ipv6 *si; + struct static_route *si; struct route_table *stable; /* Lookup table. */ @@ -3750,7 +3609,7 @@ static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate, for (si = rn->info; si; si = si->next) if (distance == si->distance && type == si->type - && (! gate || IPV6_ADDR_SAME (gate, &si->ipv6)) + && (! gate || IPV6_ADDR_SAME (gate, &si->addr.ipv6)) && (! ifname || strcmp (ifname, si->ifname) == 0) && (! tag || (tag == si->tag))) break; @@ -3763,7 +3622,7 @@ static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate, } /* Install into rib. */ - static_uninstall_ipv6 (p, si); + static_uninstall_route (AFI_IP6, SAFI_UNICAST, p, si); /* Unlink static route from linked list. */ if (si->prev) @@ -3776,11 +3635,10 @@ static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate, /* Free static route configuration. */ if (ifname) XFREE (0, si->ifname); - XFREE (MTYPE_STATIC_IPV6, si); + XFREE (MTYPE_STATIC_ROUTE, si); return 1; } -#endif /* HAVE_IPV6 */ /* RIB update function. */ void |
