diff options
author | Donald Sharp <sharpd@cumulusnetworks.com> | 2016-09-01 13:20:02 +0200 |
---|---|---|
committer | Donald Sharp <sharpd@cumulusnetworks.com> | 2016-09-01 13:20:02 +0200 |
commit | 28f6dde859dad5785aa40067a9ce611684e28fb4 (patch) | |
tree | 0eec75011e5aa89f109bce8c126f10d8d889d663 /zebra | |
parent | quagga-reload.py should be importable (diff) | |
download | frr-28f6dde859dad5785aa40067a9ce611684e28fb4.tar.xz frr-28f6dde859dad5785aa40067a9ce611684e28fb4.zip |
zebra: Create zebra_static.[ch] to isolate code
Isolate the zebra static_XXX functions from zebra_rib.c
This is the first in a series of changes to clean up
the zebra code a bit more.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Diffstat (limited to 'zebra')
-rw-r--r-- | zebra/Makefile.am | 6 | ||||
-rw-r--r-- | zebra/rib.h | 75 | ||||
-rw-r--r-- | zebra/zebra_rib.c | 593 | ||||
-rw-r--r-- | zebra/zebra_static.c | 617 | ||||
-rw-r--r-- | zebra/zebra_static.h | 95 | ||||
-rw-r--r-- | zebra/zebra_vrf.c | 1 | ||||
-rw-r--r-- | zebra/zebra_vty.c | 3 |
7 files changed, 729 insertions, 661 deletions
diff --git a/zebra/Makefile.am b/zebra/Makefile.am index 4492f9e6d..0218af81b 100644 --- a/zebra/Makefile.am +++ b/zebra/Makefile.am @@ -31,19 +31,19 @@ zebra_SOURCES = \ redistribute.c debug.c rtadv.c zebra_snmp.c zebra_vty.c \ irdp_main.c irdp_interface.c irdp_packet.c router-id.c zebra_fpm.c \ $(othersrc) zebra_ptm.c zebra_rnh.c zebra_ptm_redistribute.c \ - zebra_ns.c zebra_vrf.c + zebra_ns.c zebra_vrf.c zebra_static.c testzebra_SOURCES = test_main.c zebra_rib.c interface.c connected.c debug.c \ zebra_vty.c zebra_ptm.c zebra_routemap.c zebra_ns.c zebra_vrf.c \ kernel_null.c redistribute_null.c ioctl_null.c misc_null.c zebra_rnh_null.c \ - zebra_ptm_null.c rtadv_null.c if_null.c zserv_null.c + zebra_ptm_null.c rtadv_null.c if_null.c zserv_null.c zebra_static.c noinst_HEADERS = \ connected.h ioctl.h rib.h rt.h zserv.h redistribute.h debug.h rtadv.h \ interface.h ipforward.h irdp.h router-id.h kernel_socket.h \ rt_netlink.h zebra_fpm.h zebra_fpm_private.h zebra_rnh.h \ zebra_ptm_redistribute.h zebra_ptm.h zebra_routemap.h \ - zebra_ns.h zebra_vrf.h ioctl_solaris.h + zebra_ns.h zebra_vrf.h ioctl_solaris.h zebra_static.h zebra_LDADD = $(otherobj) ../lib/libzebra.la $(LIBCAP) diff --git a/zebra/rib.h b/zebra/rib.h index 095b9c6f8..32f370f9e 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -175,51 +175,6 @@ typedef struct rib_dest_t_ #define RNODE_FOREACH_RIB_SAFE(rn, rib, next) \ RIB_DEST_FOREACH_ROUTE_SAFE (rib_dest_from_rnode (rn), rib, next) -/* Static route information. */ -struct static_route -{ - /* For linked list. */ - struct static_route *prev; - struct static_route *next; - - /* VRF identifier. */ - vrf_id_t vrf_id; - - /* Administrative distance. */ - u_char distance; - - /* Tag */ - u_short tag; - - /* Flag for this static route's type. */ - u_char type; -#define STATIC_IFINDEX 1 -#define STATIC_IPV4_GATEWAY 2 -#define STATIC_IPV4_BLACKHOLE 3 -#define STATIC_IPV6_GATEWAY 4 -#define STATIC_IPV6_GATEWAY_IFINDEX 5 - - /* - * Nexthop value. - * - * Under IPv4 addr and ifindex are - * used independentyly. - * STATIC_IPV4_GATEWAY uses addr - * STATIC_IFINDEX uses ifindex - */ - union g_addr addr; - ifindex_t ifindex; - - char ifname[INTERFACE_NAMSIZ + 1]; - - /* bit flags */ - u_char flags; -/* - see ZEBRA_FLAG_REJECT - ZEBRA_FLAG_BLACKHOLE - */ -}; - /* The following for loop allows to iterate over the nexthop * structure of routes. * @@ -365,6 +320,7 @@ extern int rib_lookup_ipv4_route (struct prefix_ipv4 *, union sockunion *, #define ZEBRA_RIB_FOUND_CONNECTED 2 #define ZEBRA_RIB_NOTFOUND 3 +extern void rib_nexthop_delete (struct rib *rib, struct nexthop *nexthop); extern struct nexthop *rib_nexthop_ipv6_add (struct rib *, struct in6_addr *); extern struct nexthop *rib_nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6, @@ -374,6 +330,11 @@ extern int is_zebra_valid_kernel_table(u_int32_t table_id); extern int is_zebra_main_routing_table(u_int32_t table_id); extern int zebra_check_addr (struct prefix *p); +extern void rib_addnode (struct route_node *rn, struct rib *rib, int process); +extern void rib_delnode (struct route_node *rn, struct rib *rib); +extern int rib_install_kernel (struct route_node *rn, struct rib *rib, int update); +extern int rib_uninstall_kernel (struct route_node *rn, struct rib *rib); + /* NOTE: * All rib_add_ipv[46]* functions will not just add prefix into RIB, but * also implicitly withdraw equal prefix of same type. */ @@ -404,20 +365,6 @@ extern void rib_init (void); extern unsigned long rib_score_proto (u_char proto, u_short instance); extern void rib_queue_add (struct route_node *rn); -extern void -static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si); -extern void -static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si); - -extern int -static_add_ipv4 (safi_t safi, struct prefix *p, struct in_addr *gate, ifindex_t ifindex, - const char *ifname, u_char flags, u_short tag, - u_char distance, struct zebra_vrf *zvrf); - -extern int -static_delete_ipv4 (safi_t safi, struct prefix *p, struct in_addr *gate, ifindex_t ifindex, - u_short tag, u_char distance, struct zebra_vrf *zvrf); - extern int rib_add_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p, struct in6_addr *gate, ifindex_t ifindex, vrf_id_t vrf_id, @@ -436,19 +383,9 @@ extern struct rib *rib_match_ipv6 (struct in6_addr *, vrf_id_t); extern struct route_table *rib_table_ipv6; extern int -static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate, - ifindex_t ifindex, const char *ifname, u_char flags, - u_short tag, u_char distance, struct zebra_vrf *zvrf); - -extern int rib_add_ipv6_multipath (struct prefix *, struct rib *, safi_t, ifindex_t); -extern int -static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate, - ifindex_t ifindex, u_short tag, u_char distance, - struct zebra_vrf *zvrf); - extern int rib_gc_dest (struct route_node *rn); extern struct route_table *rib_tables_iter_next (rib_tables_iter_t *iter); diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 195d3633e..0db1b0a68 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -195,7 +195,7 @@ rib_copy_nexthops (struct rib *rib, struct nexthop *nh) } /* Delete specified nexthop from the list. */ -static void +void rib_nexthop_delete (struct rib *rib, struct nexthop *nexthop) { if (nexthop->next) @@ -1248,7 +1248,7 @@ nexthop_active_update (struct route_node *rn, struct rib *rib, int set) /* Update flag indicates whether this is a "replace" or not. Currently, this * is only used for IPv4. */ -static int +int rib_install_kernel (struct route_node *rn, struct rib *rib, int update) { int ret = 0; @@ -1303,7 +1303,7 @@ rib_install_kernel (struct route_node *rn, struct rib *rib, int update) } /* Uninstall the route from kernel. */ -static int +int rib_uninstall_kernel (struct route_node *rn, struct rib *rib) { int ret = 0; @@ -1555,7 +1555,6 @@ rib_process_update_route (struct zebra_vrf *zvrf, struct route_node *rn, for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next) UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); } - } /* Update for redistribution. */ @@ -2324,7 +2323,7 @@ rib_link (struct route_node *rn, struct rib *rib, int process) rib_queue_add (rn); } -static void +void rib_addnode (struct route_node *rn, struct rib *rib, int process) { /* RIB node has been un-removed before route-node is processed. @@ -2379,7 +2378,7 @@ rib_unlink (struct route_node *rn, struct rib *rib) } -static void +void rib_delnode (struct route_node *rn, struct rib *rib) { afi_t afi; @@ -2910,440 +2909,7 @@ rib_delete_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p, return 0; } -/* Install static route into rib. */ -void -static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si) -{ - struct rib *rib; - struct route_node *rn; - struct route_table *table; - struct prefix nh_p; - - /* Lookup table. */ - table = zebra_vrf_table (afi, safi, 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_IPV4_GATEWAY: - rib_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(si->vrf_id, &nh_p, rn); - break; - case STATIC_IFINDEX: - rib_nexthop_ifindex_add (rib, si->ifindex); - break; - case STATIC_IPV4_BLACKHOLE: - rib_nexthop_blackhole_add (rib); - break; - case STATIC_IPV6_GATEWAY: - rib_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(si->vrf_id, &nh_p, rn); - break; - case STATIC_IPV6_GATEWAY_IFINDEX: - rib_nexthop_ipv6_ifindex_add (rib, &si->addr.ipv6, si->ifindex); - break; - } - - if (IS_ZEBRA_DEBUG_RIB) - { - char buf[INET6_ADDRSTRLEN]; - 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); - } - } - /* Schedule route for processing or invoke NHT, as appropriate. */ - if (si->type == STATIC_IPV4_GATEWAY || - si->type == STATIC_IPV6_GATEWAY) - zebra_evaluate_rnh(si->vrf_id, nh_p.family, 1, RNH_NEXTHOP_TYPE, &nh_p); - else - rib_queue_add (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->mtu = 0; - rib->vrf_id = si->vrf_id; - rib->table = si->vrf_id ? (zebra_vrf_lookup(si->vrf_id))->table_id : zebrad.rtm_table_default; - rib->nexthop_num = 0; - rib->tag = si->tag; - - switch (si->type) - { - case STATIC_IPV4_GATEWAY: - rib_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(si->vrf_id, &nh_p, rn); - break; - case STATIC_IFINDEX: - rib_nexthop_ifindex_add (rib, si->ifindex); - break; - case STATIC_IPV4_BLACKHOLE: - rib_nexthop_blackhole_add (rib); - break; - case STATIC_IPV6_GATEWAY: - rib_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(si->vrf_id, &nh_p, rn); - break; - case STATIC_IPV6_GATEWAY_IFINDEX: - rib_nexthop_ipv6_ifindex_add (rib, &si->addr.ipv6, si->ifindex); - break; - } - - /* Save the flags of this static routes (reject, blackhole) */ - rib->flags = si->flags; - - if (IS_ZEBRA_DEBUG_RIB) - { - char buf[INET6_ADDRSTRLEN]; - 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); - } - } - /* Link this rib 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); - zebra_evaluate_rnh(si->vrf_id, nh_p.family, 1, RNH_NEXTHOP_TYPE, &nh_p); - } - else - rib_addnode (rn, rib, 1); - } -} - -static int -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)) - return 1; - if (nexthop->type == NEXTHOP_TYPE_IFINDEX - && si->type == STATIC_IFINDEX - && nexthop->ifindex == si->ifindex) - 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_IPV6_IFINDEX - && si->type == STATIC_IPV6_GATEWAY_IFINDEX - && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->addr.ipv6) - && nexthop->ifindex == si->ifindex) - return 1; - return 0; -} - -/* Uninstall static route from RIB. */ -void -static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si) -{ - struct route_node *rn; - struct rib *rib; - struct nexthop *nexthop; - struct route_table *table; - struct prefix nh_p; - - /* Lookup table. */ - table = zebra_vrf_table (afi, safi, si->vrf_id); - if (! table) - return; - - /* Lookup existing route with type and distance. */ - rn = route_node_lookup (table, 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_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. - */ - if (IS_ZEBRA_DEBUG_RIB) - { - char buf[INET6_ADDRSTRLEN]; - 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); - } - } - 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 - { - redistribute_delete (&rn->p, rib); - rib_uninstall_kernel (rn, rib); - } - } - - 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; - } - rib_nexthop_delete (rib, nexthop); - zebra_deregister_rnh_static_nh(si->vrf_id, &nh_p, rn); - nexthop_free (nexthop); - } - /* Unlock node. */ - route_unlock_node (rn); -} - -int -static_add_ipv4 (safi_t safi, struct prefix *p, struct in_addr *gate, ifindex_t ifindex, - const char *ifname, u_char flags, u_short tag, - u_char distance, struct zebra_vrf *zvrf) -{ - u_char type = 0; - struct route_node *rn; - struct static_route *si; - struct static_route *pp; - struct static_route *cp; - struct static_route *update = NULL; - struct route_table *stable = zvrf->stable[AFI_IP][safi]; - - if (! stable) - return -1; - - /* Lookup static route prefix. */ - rn = route_node_get (stable, p); - - /* Make flags. */ - if (gate) - type = STATIC_IPV4_GATEWAY; - else if (ifindex) - type = STATIC_IFINDEX; - else - type = STATIC_IPV4_BLACKHOLE; - - /* Do nothing if there is a same static route. */ - for (si = rn->info; si; si = si->next) - { - if (type == si->type - && (! gate || IPV4_ADDR_SAME (gate, &si->addr.ipv4)) - && (! ifindex || ifindex == si->ifindex)) - { - if ((distance == si->distance) && (tag == si->tag)) - { - route_unlock_node (rn); - return 0; - } - else - update = si; - } - } - - /* Distance or tag changed. */ - if (update) - static_delete_ipv4 (safi, p, gate, ifindex, update->tag, update->distance, zvrf); - - /* Make new static route structure. */ - si = XCALLOC (MTYPE_STATIC_ROUTE, sizeof (struct static_route)); - si->type = type; - si->distance = distance; - si->flags = flags; - si->tag = tag; - si->vrf_id = zvrf->vrf_id; - si->ifindex = ifindex; - if (si->ifindex) - strcpy(si->ifname, ifname); - - if (gate) - si->addr.ipv4 = *gate; - - /* Add new static route information to the tree with sort by - distance value and gateway address. */ - for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next) - { - if (si->distance < cp->distance) - break; - if (si->distance > cp->distance) - continue; - if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY) - { - if (ntohl (si->addr.ipv4.s_addr) < ntohl (cp->addr.ipv4.s_addr)) - break; - if (ntohl (si->addr.ipv4.s_addr) > ntohl (cp->addr.ipv4.s_addr)) - continue; - } - } - - /* Make linked list. */ - if (pp) - pp->next = si; - else - rn->info = si; - if (cp) - cp->prev = si; - si->prev = pp; - si->next = cp; - - /* Install into rib. */ - static_install_route (AFI_IP, safi, p, si); - - return 1; -} - -int -static_delete_ipv4 (safi_t safi, struct prefix *p, struct in_addr *gate, ifindex_t ifindex, - u_short tag, u_char distance, struct zebra_vrf *zvrf) -{ - u_char type = 0; - struct route_node *rn; - struct static_route *si; - struct route_table *stable; - - /* Lookup table. */ - stable = zebra_vrf_static_table (AFI_IP, safi, zvrf); - if (! stable) - return -1; - - /* Lookup static route prefix. */ - rn = route_node_lookup (stable, p); - if (! rn) - return 0; - - /* Make flags. */ - if (gate) - type = STATIC_IPV4_GATEWAY; - else if (ifindex) - type = STATIC_IFINDEX; - else - type = STATIC_IPV4_BLACKHOLE; - - /* 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->addr.ipv4)) - && (! ifindex || ifindex == si->ifindex) - && (! tag || (tag == si->tag))) - break; - - /* Can't find static route. */ - if (! si) - { - route_unlock_node (rn); - return 0; - } - - /* Install into rib. */ - static_uninstall_route (AFI_IP, safi, p, si); - - /* Unlink static route from linked list. */ - if (si->prev) - si->prev->next = si->next; - else - rn->info = si->next; - if (si->next) - si->next->prev = si->prev; - route_unlock_node (rn); - - /* Free static route configuration. */ - XFREE (MTYPE_STATIC_ROUTE, si); - - route_unlock_node (rn); - - return 1; -} int rib_add_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p, @@ -3707,155 +3273,6 @@ rib_delete_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p, return 0; } -/* Add static route into static route configuration. */ -int -static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate, - ifindex_t ifindex, const char *ifname, u_char flags, - u_short tag, u_char distance, struct zebra_vrf *zvrf) -{ - struct route_node *rn; - struct static_route *si; - struct static_route *pp; - struct static_route *cp; - struct static_route *update = NULL; - struct route_table *stable = zvrf->stable[AFI_IP6][SAFI_UNICAST]; - - if (! stable) - return -1; - - if (!gate && - (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFINDEX)) - return -1; - - if (!ifindex && - (type == STATIC_IPV6_GATEWAY_IFINDEX || type == STATIC_IFINDEX)) - return -1; - - /* Lookup static route prefix. */ - rn = route_node_get (stable, p); - - /* Do nothing if there is a same static route. */ - for (si = rn->info; si; si = si->next) - { - if (type == si->type - && (! gate || IPV6_ADDR_SAME (gate, &si->addr.ipv6)) - && (! ifindex || ifindex == si->ifindex)) - { - 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, ifindex, update->tag, update->distance, zvrf); - - /* Make new static route structure. */ - si = XCALLOC (MTYPE_STATIC_ROUTE, sizeof (struct static_route)); - - si->type = type; - si->distance = distance; - si->flags = flags; - si->tag = tag; - si->vrf_id = zvrf->vrf_id; - si->ifindex = ifindex; - if (si->ifindex) - strcpy (si->ifname, ifname); - - switch (type) - { - case STATIC_IPV6_GATEWAY: - si->addr.ipv6 = *gate; - break; - case STATIC_IPV6_GATEWAY_IFINDEX: - si->addr.ipv6 = *gate; - break; - } - - /* Add new static route information to the tree with sort by - distance value and gateway address. */ - for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next) - { - if (si->distance < cp->distance) - break; - if (si->distance > cp->distance) - continue; - } - - /* Make linked list. */ - if (pp) - pp->next = si; - else - rn->info = si; - if (cp) - cp->prev = si; - si->prev = pp; - si->next = cp; - - /* Install into rib. */ - static_install_route (AFI_IP6, SAFI_UNICAST, p, si); - - return 1; -} - -/* Delete static route from static route configuration. */ -int -static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate, - ifindex_t ifindex, u_short tag, u_char distance, - struct zebra_vrf *zvrf) -{ - struct route_node *rn; - struct static_route *si; - struct route_table *stable; - - /* Lookup table. */ - stable = zebra_vrf_static_table (AFI_IP6, SAFI_UNICAST, zvrf); - if (! stable) - return -1; - - /* Lookup static route prefix. */ - rn = route_node_lookup (stable, p); - if (! rn) - return 0; - - /* Find same static route is the tree */ - for (si = rn->info; si; si = si->next) - if (distance == si->distance - && type == si->type - && (! gate || IPV6_ADDR_SAME (gate, &si->addr.ipv6)) - && (! ifindex || ifindex == si->ifindex) - && (! tag || (tag == si->tag))) - break; - - /* Can't find static route. */ - if (! si) - { - route_unlock_node (rn); - return 0; - } - - /* Install into rib. */ - static_uninstall_route (AFI_IP6, SAFI_UNICAST, p, si); - - /* Unlink static route from linked list. */ - if (si->prev) - si->prev->next = si->next; - else - rn->info = si->next; - if (si->next) - si->next->prev = si->prev; - - /* Free static route configuration. */ - XFREE (MTYPE_STATIC_ROUTE, si); - - return 1; -} - /* Schedule routes of a particular table (address-family) based on event. */ static void rib_update_table (struct route_table *table, rib_update_event_t event) diff --git a/zebra/zebra_static.c b/zebra/zebra_static.c new file mode 100644 index 000000000..9d16f1267 --- /dev/null +++ b/zebra/zebra_static.c @@ -0,0 +1,617 @@ +/* + * Static Routing Information code + * Copyright (C) 2016 Cumulus Networks + * Donald Sharp + * + * This file is part of Quagga. + * + * Quagga is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * Quagga is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * 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. + */ +#include <zebra.h> + +#include <lib/nexthop.h> +#include <lib/memory.h> + +#include "zebra/debug.h" +#include "zebra/rib.h" +#include "zebra/zserv.h" +#include "zebra/zebra_vrf.h" +#include "zebra/zebra_static.h" +#include "zebra/zebra_rnh.h" +#include "zebra/redistribute.h" + +/* Install static route into rib. */ +void +static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si) +{ + struct rib *rib; + struct route_node *rn; + struct route_table *table; + struct prefix nh_p; + + /* Lookup table. */ + table = zebra_vrf_table (afi, safi, 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_IPV4_GATEWAY: + rib_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(si->vrf_id, &nh_p, rn); + break; + case STATIC_IFINDEX: + rib_nexthop_ifindex_add (rib, si->ifindex); + break; + case STATIC_IPV4_BLACKHOLE: + rib_nexthop_blackhole_add (rib); + break; + case STATIC_IPV6_GATEWAY: + rib_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(si->vrf_id, &nh_p, rn); + break; + case STATIC_IPV6_GATEWAY_IFINDEX: + rib_nexthop_ipv6_ifindex_add (rib, &si->addr.ipv6, si->ifindex); + break; + } + + if (IS_ZEBRA_DEBUG_RIB) + { + char buf[INET6_ADDRSTRLEN]; + 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); + } + } + /* Schedule route for processing or invoke NHT, as appropriate. */ + if (si->type == STATIC_IPV4_GATEWAY || + si->type == STATIC_IPV6_GATEWAY) + zebra_evaluate_rnh(si->vrf_id, nh_p.family, 1, RNH_NEXTHOP_TYPE, &nh_p); + else + rib_queue_add (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->mtu = 0; + rib->vrf_id = si->vrf_id; + rib->table = si->vrf_id ? (zebra_vrf_lookup(si->vrf_id))->table_id : zebrad.rtm_table_default; + rib->nexthop_num = 0; + rib->tag = si->tag; + + switch (si->type) + { + case STATIC_IPV4_GATEWAY: + rib_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(si->vrf_id, &nh_p, rn); + break; + case STATIC_IFINDEX: + rib_nexthop_ifindex_add (rib, si->ifindex); + break; + case STATIC_IPV4_BLACKHOLE: + rib_nexthop_blackhole_add (rib); + break; + case STATIC_IPV6_GATEWAY: + rib_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(si->vrf_id, &nh_p, rn); + break; + case STATIC_IPV6_GATEWAY_IFINDEX: + rib_nexthop_ipv6_ifindex_add (rib, &si->addr.ipv6, si->ifindex); + break; + } + + /* Save the flags of this static routes (reject, blackhole) */ + rib->flags = si->flags; + + if (IS_ZEBRA_DEBUG_RIB) + { + char buf[INET6_ADDRSTRLEN]; + 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); + } + } + /* Link this rib 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); + zebra_evaluate_rnh(si->vrf_id, nh_p.family, 1, RNH_NEXTHOP_TYPE, &nh_p); + } + else + rib_addnode (rn, rib, 1); + } +} +static int +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)) + return 1; + if (nexthop->type == NEXTHOP_TYPE_IFINDEX + && si->type == STATIC_IFINDEX + && nexthop->ifindex == si->ifindex) + 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_IPV6_IFINDEX + && si->type == STATIC_IPV6_GATEWAY_IFINDEX + && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->addr.ipv6) + && nexthop->ifindex == si->ifindex) + return 1; + return 0; +} + +/* Uninstall static route from RIB. */ +void +static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si) +{ + struct route_node *rn; + struct rib *rib; + struct nexthop *nexthop; + struct route_table *table; + struct prefix nh_p; + + /* Lookup table. */ + table = zebra_vrf_table (afi, safi, si->vrf_id); + if (! table) + return; + + /* Lookup existing route with type and distance. */ + rn = route_node_lookup (table, 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_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. + */ + if (IS_ZEBRA_DEBUG_RIB) + { + char buf[INET6_ADDRSTRLEN]; + 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); + } + } + 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 + { + redistribute_delete (&rn->p, rib); + rib_uninstall_kernel (rn, rib); + } + } + + 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; + } + rib_nexthop_delete (rib, nexthop); + zebra_deregister_rnh_static_nh(si->vrf_id, &nh_p, rn); + nexthop_free (nexthop); + } + /* Unlock node. */ + route_unlock_node (rn); +} + +int +static_add_ipv4 (safi_t safi, struct prefix *p, struct in_addr *gate, ifindex_t ifindex, + const char *ifname, u_char flags, u_short tag, + u_char distance, struct zebra_vrf *zvrf) +{ + u_char type = 0; + struct route_node *rn; + struct static_route *si; + struct static_route *pp; + struct static_route *cp; + struct static_route *update = NULL; + struct route_table *stable = zvrf->stable[AFI_IP][safi]; + + if (! stable) + return -1; + + /* Lookup static route prefix. */ + rn = route_node_get (stable, p); + + /* Make flags. */ + if (gate) + type = STATIC_IPV4_GATEWAY; + else if (ifindex) + type = STATIC_IFINDEX; + else + type = STATIC_IPV4_BLACKHOLE; + + /* Do nothing if there is a same static route. */ + for (si = rn->info; si; si = si->next) + { + if (type == si->type + && (! gate || IPV4_ADDR_SAME (gate, &si->addr.ipv4)) + && (! ifindex || ifindex == si->ifindex)) + { + if ((distance == si->distance) && (tag == si->tag)) + { + route_unlock_node (rn); + return 0; + } + else + update = si; + } + } + + /* Distance or tag changed. */ + if (update) + static_delete_ipv4 (safi, p, gate, ifindex, update->tag, update->distance, zvrf); + + /* Make new static route structure. */ + si = XCALLOC (MTYPE_STATIC_ROUTE, sizeof (struct static_route)); + + si->type = type; + si->distance = distance; + si->flags = flags; + si->tag = tag; + si->vrf_id = zvrf->vrf_id; + si->ifindex = ifindex; + if (si->ifindex) + strcpy(si->ifname, ifname); + + if (gate) + si->addr.ipv4 = *gate; + + /* Add new static route information to the tree with sort by + distance value and gateway address. */ + for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next) + { + if (si->distance < cp->distance) + break; + if (si->distance > cp->distance) + continue; + if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY) + { + if (ntohl (si->addr.ipv4.s_addr) < ntohl (cp->addr.ipv4.s_addr)) + break; + if (ntohl (si->addr.ipv4.s_addr) > ntohl (cp->addr.ipv4.s_addr)) + continue; + } + } + + /* Make linked list. */ + if (pp) + pp->next = si; + else + rn->info = si; + if (cp) + cp->prev = si; + si->prev = pp; + si->next = cp; + + /* Install into rib. */ + static_install_route (AFI_IP, safi, p, si); + + return 1; +} + +int +static_delete_ipv4 (safi_t safi, struct prefix *p, struct in_addr *gate, ifindex_t ifindex, + u_short tag, u_char distance, struct zebra_vrf *zvrf) +{ + u_char type = 0; + struct route_node *rn; + struct static_route *si; + struct route_table *stable; + + /* Lookup table. */ + stable = zebra_vrf_static_table (AFI_IP, safi, zvrf); + if (! stable) + return -1; + + /* Lookup static route prefix. */ + rn = route_node_lookup (stable, p); + if (! rn) + return 0; + + /* Make flags. */ + if (gate) + type = STATIC_IPV4_GATEWAY; + else if (ifindex) + type = STATIC_IFINDEX; + else + type = STATIC_IPV4_BLACKHOLE; + + /* 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->addr.ipv4)) + && (! ifindex || ifindex == si->ifindex) + && (! tag || (tag == si->tag))) + break; + + /* Can't find static route. */ + if (! si) + { + route_unlock_node (rn); + return 0; + } + + /* Install into rib. */ + static_uninstall_route (AFI_IP, safi, p, si); + + /* Unlink static route from linked list. */ + if (si->prev) + si->prev->next = si->next; + else + rn->info = si->next; + if (si->next) + si->next->prev = si->prev; + route_unlock_node (rn); + + /* Free static route configuration. */ + XFREE (MTYPE_STATIC_ROUTE, si); + + route_unlock_node (rn); + + return 1; +} + +/* Add static route into static route configuration. */ +int +static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate, + ifindex_t ifindex, const char *ifname, u_char flags, + u_short tag, u_char distance, struct zebra_vrf *zvrf) +{ + struct route_node *rn; + struct static_route *si; + struct static_route *pp; + struct static_route *cp; + struct static_route *update = NULL; + struct route_table *stable = zvrf->stable[AFI_IP6][SAFI_UNICAST]; + + if (! stable) + return -1; + + if (!gate && + (type == STATIC_IPV6_GATEWAY || type == STATIC_IPV6_GATEWAY_IFINDEX)) + return -1; + + if (!ifindex && + (type == STATIC_IPV6_GATEWAY_IFINDEX || type == STATIC_IFINDEX)) + return -1; + + /* Lookup static route prefix. */ + rn = route_node_get (stable, p); + + /* Do nothing if there is a same static route. */ + for (si = rn->info; si; si = si->next) + { + if (type == si->type + && (! gate || IPV6_ADDR_SAME (gate, &si->addr.ipv6)) + && (! ifindex || ifindex == si->ifindex)) + { + 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, ifindex, update->tag, update->distance, zvrf); + + /* Make new static route structure. */ + si = XCALLOC (MTYPE_STATIC_ROUTE, sizeof (struct static_route)); + + si->type = type; + si->distance = distance; + si->flags = flags; + si->tag = tag; + si->vrf_id = zvrf->vrf_id; + si->ifindex = ifindex; + if (si->ifindex) + strcpy (si->ifname, ifname); + + switch (type) + { + case STATIC_IPV6_GATEWAY: + si->addr.ipv6 = *gate; + break; + case STATIC_IPV6_GATEWAY_IFINDEX: + si->addr.ipv6 = *gate; + break; + } + + /* Add new static route information to the tree with sort by + distance value and gateway address. */ + for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next) + { + if (si->distance < cp->distance) + break; + if (si->distance > cp->distance) + continue; + } + + /* Make linked list. */ + if (pp) + pp->next = si; + else + rn->info = si; + if (cp) + cp->prev = si; + si->prev = pp; + si->next = cp; + + /* Install into rib. */ + static_install_route (AFI_IP6, SAFI_UNICAST, p, si); + + return 1; +} + +/* Delete static route from static route configuration. */ +int +static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate, + ifindex_t ifindex, u_short tag, u_char distance, + struct zebra_vrf *zvrf) +{ + struct route_node *rn; + struct static_route *si; + struct route_table *stable; + + /* Lookup table. */ + stable = zebra_vrf_static_table (AFI_IP6, SAFI_UNICAST, zvrf); + if (! stable) + return -1; + + /* Lookup static route prefix. */ + rn = route_node_lookup (stable, p); + if (! rn) + return 0; + + /* Find same static route is the tree */ + for (si = rn->info; si; si = si->next) + if (distance == si->distance + && type == si->type + && (! gate || IPV6_ADDR_SAME (gate, &si->addr.ipv6)) + && (! ifindex || ifindex == si->ifindex) + && (! tag || (tag == si->tag))) + break; + + /* Can't find static route. */ + if (! si) + { + route_unlock_node (rn); + return 0; + } + + /* Install into rib. */ + static_uninstall_route (AFI_IP6, SAFI_UNICAST, p, si); + + /* Unlink static route from linked list. */ + if (si->prev) + si->prev->next = si->next; + else + rn->info = si->next; + if (si->next) + si->next->prev = si->prev; + + /* Free static route configuration. */ + XFREE (MTYPE_STATIC_ROUTE, si); + + return 1; +} diff --git a/zebra/zebra_static.h b/zebra/zebra_static.h new file mode 100644 index 000000000..a3096725f --- /dev/null +++ b/zebra/zebra_static.h @@ -0,0 +1,95 @@ +/* + * Static Routing Information header + * Copyright (C) 2016 Cumulus Networks + * Donald Sharp + * + * This file is part of Quagga. + * + * Quagga is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * Quagga is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * 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. + */ +#ifndef __ZEBRA_STATIC_H__ +#define __ZEBRA_STATIC_H__ + +/* Static route information. */ +struct static_route +{ + /* For linked list. */ + struct static_route *prev; + struct static_route *next; + + /* VRF identifier. */ + vrf_id_t vrf_id; + + /* Administrative distance. */ + u_char distance; + + /* Tag */ + u_short tag; + + /* Flag for this static route's type. */ + u_char type; +#define STATIC_IFINDEX 1 +#define STATIC_IPV4_GATEWAY 2 +#define STATIC_IPV4_BLACKHOLE 3 +#define STATIC_IPV6_GATEWAY 4 +#define STATIC_IPV6_GATEWAY_IFINDEX 5 + + /* + * Nexthop value. + * + * Under IPv4 addr and ifindex are + * used independentyly. + * STATIC_IPV4_GATEWAY uses addr + * STATIC_IFINDEX uses ifindex + */ + union g_addr addr; + ifindex_t ifindex; + + char ifname[INTERFACE_NAMSIZ + 1]; + + /* bit flags */ + u_char flags; +/* + see ZEBRA_FLAG_REJECT + ZEBRA_FLAG_BLACKHOLE + */ +}; + +extern void +static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si); +extern void +static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_route *si); + +extern int +static_add_ipv4 (safi_t safi, struct prefix *p, struct in_addr *gate, ifindex_t ifindex, + const char *ifname, u_char flags, u_short tag, + u_char distance, struct zebra_vrf *zvrf); + +extern int +static_delete_ipv4 (safi_t safi, struct prefix *p, struct in_addr *gate, ifindex_t ifindex, + u_short tag, u_char distance, struct zebra_vrf *zvrf); + +extern int +static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate, + ifindex_t ifindex, const char *ifname, u_char flags, + u_short tag, u_char distance, struct zebra_vrf *zvrf); + +extern int +static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate, + ifindex_t ifindex, u_short tag, u_char distance, + struct zebra_vrf *zvrf); + +#endif diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index 46dc29d10..d9bd919bf 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -29,6 +29,7 @@ #include "zebra/rib.h" #include "zebra/zebra_vrf.h" #include "zebra/router-id.h" +#include "zebra/zebra_static.h" extern struct zebra_t zebrad; struct list *zvrf_list; diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 3c2626670..716e74c0b 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -29,13 +29,14 @@ #include "rib.h" #include "nexthop.h" #include "vrf.h" +#include "lib/json.h" #include "zebra/zserv.h" #include "zebra/zebra_vrf.h" #include "zebra/zebra_rnh.h" #include "zebra/redistribute.h" #include "zebra/zebra_routemap.h" -#include "lib/json.h" +#include "zebra/zebra_static.h" extern int allow_delete; |