diff options
Diffstat (limited to 'zebra/zebra_static.c')
| -rw-r--r-- | zebra/zebra_static.c | 187 |
1 files changed, 84 insertions, 103 deletions
diff --git a/zebra/zebra_static.c b/zebra/zebra_static.c index 5894a8955b..05336ca6b2 100644 --- a/zebra/zebra_static.c +++ b/zebra/zebra_static.c @@ -15,16 +15,17 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with Quagga; see the file COPYING. If not, write to the Free - * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include <zebra.h> #include <lib/nexthop.h> #include <lib/memory.h> +#include <lib/srcdest_table.h> +#include "vty.h" #include "zebra/debug.h" #include "zebra/rib.h" #include "zebra/zserv.h" @@ -36,9 +37,10 @@ /* Install static route into rib. */ void -static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si) +static_install_route (afi_t afi, safi_t safi, struct prefix *p, + struct prefix_ipv6 *src_p, struct static_route *si) { - struct rib *rib; + struct route_entry *re; struct route_node *rn; struct route_table *table; struct prefix nh_p; @@ -49,22 +51,24 @@ static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_ro if (! table) return; + memset (&nh_p, 0, sizeof (nh_p)); + /* Lookup existing route */ - rn = route_node_get (table, p); - RNODE_FOREACH_RIB (rn, rib) + rn = srcdest_rnode_get (table, p, src_p); + RNODE_FOREACH_RE (rn, re) { - if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED)) + if (CHECK_FLAG (re->status, ROUTE_ENTRY_REMOVED)) continue; - if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance) + if (re->type == ZEBRA_ROUTE_STATIC && re->distance == si->distance) break; } - if (rib) + if (re) { /* if tag value changed , update old value in RIB */ - if (rib->tag != si->tag) - rib->tag = si->tag; + if (re->tag != si->tag) + re->tag = si->tag; /* Same distance static route is there. Update it with new nexthop. */ @@ -72,27 +76,27 @@ static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_ro switch (si->type) { case STATIC_IPV4_GATEWAY: - nexthop = rib_nexthop_ipv4_add (rib, &si->addr.ipv4, NULL); + nexthop = route_entry_nexthop_ipv4_add (re, &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(si->vrf_id, &nh_p, rn); break; case STATIC_IFINDEX: - nexthop = rib_nexthop_ifindex_add (rib, si->ifindex); + nexthop = route_entry_nexthop_ifindex_add (re, si->ifindex); break; case STATIC_BLACKHOLE: - nexthop = rib_nexthop_blackhole_add (rib); + nexthop = route_entry_nexthop_blackhole_add (re); break; case STATIC_IPV6_GATEWAY: - nexthop = rib_nexthop_ipv6_add (rib, &si->addr.ipv6); + nexthop = route_entry_nexthop_ipv6_add (re, &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(si->vrf_id, &nh_p, rn); break; case STATIC_IPV6_GATEWAY_IFINDEX: - nexthop = rib_nexthop_ipv6_ifindex_add (rib, &si->addr.ipv6, + nexthop = route_entry_nexthop_ipv6_ifindex_add (re, &si->addr.ipv6, si->ifindex); break; } @@ -107,8 +111,8 @@ static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_ro if (IS_ZEBRA_DEBUG_RIB) { inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN); - zlog_debug ("%u:%s/%d: Modifying route rn %p, rib %p (type %d)", - si->vrf_id, buf, p->prefixlen, rn, rib, rib->type); + zlog_debug ("%u:%s/%d: Modifying route rn %p, re %p (type %d)", + si->vrf_id, buf, p->prefixlen, rn, re, re->type); } } /* Schedule route for processing or invoke NHT, as appropriate. */ @@ -121,42 +125,42 @@ static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_ro 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->mtu = 0; - rib->vrf_id = si->vrf_id; - rib->table = si->vrf_id ? (zebra_vrf_lookup_by_id(si->vrf_id))->table_id : zebrad.rtm_table_default; - rib->nexthop_num = 0; - rib->tag = si->tag; + re = XCALLOC (MTYPE_RE, sizeof (struct route_entry)); + + re->type = ZEBRA_ROUTE_STATIC; + re->instance = 0; + re->distance = si->distance; + re->metric = 0; + re->mtu = 0; + re->vrf_id = si->vrf_id; + re->table = si->vrf_id ? (zebra_vrf_lookup_by_id(si->vrf_id))->table_id : zebrad.rtm_table_default; + re->nexthop_num = 0; + re->tag = si->tag; switch (si->type) { case STATIC_IPV4_GATEWAY: - nexthop = rib_nexthop_ipv4_add (rib, &si->addr.ipv4, NULL); + nexthop = route_entry_nexthop_ipv4_add (re, &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(si->vrf_id, &nh_p, rn); break; case STATIC_IFINDEX: - nexthop = rib_nexthop_ifindex_add (rib, si->ifindex); + nexthop = route_entry_nexthop_ifindex_add (re, si->ifindex); break; case STATIC_BLACKHOLE: - nexthop = rib_nexthop_blackhole_add (rib); + nexthop = route_entry_nexthop_blackhole_add (re); break; case STATIC_IPV6_GATEWAY: - nexthop = rib_nexthop_ipv6_add (rib, &si->addr.ipv6); + nexthop = route_entry_nexthop_ipv6_add (re, &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(si->vrf_id, &nh_p, rn); break; case STATIC_IPV6_GATEWAY_IFINDEX: - nexthop = rib_nexthop_ipv6_ifindex_add (rib, &si->addr.ipv6, + nexthop = route_entry_nexthop_ipv6_ifindex_add (re, &si->addr.ipv6, si->ifindex); break; } @@ -166,7 +170,7 @@ static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_ro &si->snh_label.label[0]); /* Save the flags of this static routes (reject, blackhole) */ - rib->flags = si->flags; + re->flags = si->flags; if (IS_ZEBRA_DEBUG_RIB) { @@ -174,50 +178,27 @@ static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_ro if (IS_ZEBRA_DEBUG_RIB) { inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN); - zlog_debug ("%u:%s/%d: Inserting route rn %p, rib %p (type %d)", - si->vrf_id, buf, p->prefixlen, rn, rib, rib->type); + zlog_debug ("%u:%s/%d: Inserting route rn %p, re %p (type %d)", + si->vrf_id, buf, p->prefixlen, rn, re, re->type); } } - /* Link this rib to the tree. Schedule for processing or invoke NHT, + /* Link this re to the tree. Schedule for processing or invoke NHT, * as appropriate. */ if (si->type == STATIC_IPV4_GATEWAY || si->type == STATIC_IPV6_GATEWAY) { - rib_addnode (rn, rib, 0); + rib_addnode (rn, re, 0); zebra_evaluate_rnh(si->vrf_id, nh_p.family, 1, RNH_NEXTHOP_TYPE, &nh_p); } else - rib_addnode (rn, rib, 1); + rib_addnode (rn, re, 1); } } static int -static_nexthop_label_same (struct nexthop *nexthop, - struct static_nh_label *snh_label) -{ - int i; - - if ((snh_label->num_labels == 0 && nexthop->nh_label) || - (snh_label->num_labels != 0 && !nexthop->nh_label)) - return 0; - - if (snh_label->num_labels != 0) - if (snh_label->num_labels != nexthop->nh_label->num_labels) - return 0; - - for (i = 0; i < snh_label->num_labels; i++) - if (snh_label->label[i] != nexthop->nh_label->label[i]) - return 0; - - return 1; -} - -static int static_nexthop_same (struct nexthop *nexthop, struct static_route *si) { - int gw_match = 0; - if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE && si->type == STATIC_BLACKHOLE) return 1; @@ -225,34 +206,31 @@ 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->addr.ipv4)) - gw_match = 1; + return 1; else if (nexthop->type == NEXTHOP_TYPE_IFINDEX && si->type == STATIC_IFINDEX && nexthop->ifindex == si->ifindex) - gw_match = 1; + return 1; else if (nexthop->type == NEXTHOP_TYPE_IPV6 && si->type == STATIC_IPV6_GATEWAY && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->addr.ipv6)) - gw_match = 1; + return 1; else if (nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX && si->type == STATIC_IPV6_GATEWAY_IFINDEX && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->addr.ipv6) && nexthop->ifindex == si->ifindex) - gw_match = 1; - - if (!gw_match) - return 0; + return 1; - /* Check match on label(s), if any */ - return static_nexthop_label_same (nexthop, &si->snh_label); + return 0; } /* Uninstall static route from RIB. */ void -static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si) +static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, + struct prefix_ipv6 *src_p, struct static_route *si) { struct route_node *rn; - struct rib *rib; + struct route_entry *re; struct nexthop *nexthop; struct route_table *table; struct prefix nh_p; @@ -263,28 +241,28 @@ static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_ return; /* Lookup existing route with type and distance. */ - rn = route_node_lookup (table, p); + rn = srcdest_rnode_lookup (table, p, src_p); if (! rn) return; - RNODE_FOREACH_RIB (rn, rib) + RNODE_FOREACH_RE (rn, re) { - if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED)) + if (CHECK_FLAG (re->status, ROUTE_ENTRY_REMOVED)) continue; - if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance && - rib->tag == si->tag) + if (re->type == ZEBRA_ROUTE_STATIC && re->distance == si->distance && + re->tag == si->tag) break; } - if (! rib) + if (! re) { route_unlock_node (rn); return; } /* Lookup nexthop. */ - for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) + for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next) if (static_nexthop_same (nexthop, si)) break; @@ -296,8 +274,8 @@ static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_ } /* Check nexthop. */ - if (rib->nexthop_num == 1) - rib_delnode (rn, rib); + if (re->nexthop_num == 1) + rib_delnode (rn, re); else { /* Mark this nexthop as inactive and reinstall the route. Then, delete @@ -310,31 +288,31 @@ static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_ if (IS_ZEBRA_DEBUG_RIB) { inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN); - zlog_debug ("%u:%s/%d: Modifying route rn %p, rib %p (type %d)", - si->vrf_id, buf, p->prefixlen, rn, rib, rib->type); + zlog_debug ("%u:%s/%d: Modifying route rn %p, re %p (type %d)", + si->vrf_id, buf, p->prefixlen, rn, re, re->type); } } 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) + if (re->nexthop_active_num > 1) { /* Update route in kernel if it's in fib */ - if (CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB)) - rib_install_kernel (rn, rib, rib); + if (CHECK_FLAG(re->status, ROUTE_ENTRY_SELECTED_FIB)) + rib_install_kernel (rn, re, re); /* Update redistribution if it's selected */ - if (CHECK_FLAG(rib->flags, ZEBRA_FLAG_SELECTED)) - redistribute_update (&rn->p, rib, NULL); + if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED)) + redistribute_update (p, (struct prefix*)src_p, re, NULL); } else { /* Remove from redistribute if selected route becomes inactive */ - if (CHECK_FLAG(rib->flags, ZEBRA_FLAG_SELECTED)) - redistribute_delete (&rn->p, rib); + if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED)) + redistribute_delete (p, (struct prefix*)src_p, re); /* Remove from kernel if fib route becomes inactive */ - if (CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB)) - rib_uninstall_kernel (rn, rib); + if (CHECK_FLAG(re->status, ROUTE_ENTRY_SELECTED_FIB)) + rib_uninstall_kernel (rn, re); } } @@ -351,7 +329,7 @@ static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_ nh_p.prefixlen = IPV6_MAX_BITLEN; nh_p.u.prefix6 = nexthop->gate.ipv6; } - rib_nexthop_delete (rib, nexthop); + route_entry_nexthop_delete (re, nexthop); zebra_deregister_rnh_static_nh(si->vrf_id, &nh_p, rn); nexthop_free (nexthop); } @@ -361,6 +339,7 @@ static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_ int static_add_route (afi_t afi, safi_t safi, u_char type, struct prefix *p, + struct prefix_ipv6 *src_p, union g_addr *gate, ifindex_t ifindex, const char *ifname, u_char flags, route_tag_t tag, u_char distance, struct zebra_vrf *zvrf, @@ -388,7 +367,7 @@ static_add_route (afi_t afi, safi_t safi, u_char type, struct prefix *p, return -1; /* Lookup static route prefix. */ - rn = route_node_get (stable, p); + rn = srcdest_rnode_get (stable, p, src_p); /* Do nothing if there is a same static route. */ for (si = rn->info; si; si = si->next) @@ -400,7 +379,8 @@ static_add_route (afi_t afi, safi_t safi, u_char type, struct prefix *p, && (! ifindex || ifindex == si->ifindex)) { if ((distance == si->distance) && (tag == si->tag) && - !memcmp (&si->snh_label, snh_label, sizeof (struct static_nh_label))) + !memcmp (&si->snh_label, snh_label, sizeof (struct static_nh_label)) && + si->flags == flags) { route_unlock_node (rn); return 0; @@ -412,7 +392,7 @@ static_add_route (afi_t afi, safi_t safi, u_char type, struct prefix *p, /* Distance or tag or label changed, delete existing first. */ if (update) - static_delete_route (afi, safi, type, p, gate, ifindex, update->tag, + static_delete_route (afi, safi, type, p, src_p, gate, ifindex, update->tag, update->distance, zvrf, &update->snh_label); /* Make new static route structure. */ @@ -473,13 +453,14 @@ static_add_route (afi_t afi, safi_t safi, u_char type, struct prefix *p, si->next = cp; /* Install into rib. */ - static_install_route (afi, safi, p, si); + static_install_route (afi, safi, p, src_p, si); return 1; } int static_delete_route (afi_t afi, safi_t safi, u_char type, struct prefix *p, + struct prefix_ipv6 *src_p, union g_addr *gate, ifindex_t ifindex, route_tag_t tag, u_char distance, struct zebra_vrf *zvrf, struct static_nh_label *snh_label) @@ -494,7 +475,7 @@ static_delete_route (afi_t afi, safi_t safi, u_char type, struct prefix *p, return -1; /* Lookup static route prefix. */ - rn = route_node_lookup (stable, p); + rn = srcdest_rnode_lookup (stable, p, src_p); if (! rn) return 0; @@ -518,7 +499,7 @@ static_delete_route (afi_t afi, safi_t safi, u_char type, struct prefix *p, } /* Install into rib. */ - static_uninstall_route (afi, safi, p, si); + static_uninstall_route (afi, safi, p, src_p, si); /* Unlink static route from linked list. */ if (si->prev) |
