zebra: support static srcdest routes

Signed-off-by: Christian Franke <chris@opensourcerouting.org>
This commit is contained in:
Christian Franke 2016-11-24 17:10:19 +01:00 committed by Christian Franke
parent 0573778371
commit c423229b54
5 changed files with 260 additions and 97 deletions

View File

@ -521,7 +521,7 @@ DEFUN (ipv6_route_label,
"Specify label(s) for this route\n" "Specify label(s) for this route\n"
"One or more labels separated by '/'\n") "One or more labels separated by '/'\n")
{ {
return static_ipv6_func (vty, 1, argv[2]->arg, argv[3]->arg, NULL, NULL, NULL, NULL, NULL, argv[5]->arg); return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, NULL, NULL, NULL, NULL, argv[5]->arg);
} }
DEFUN (ipv6_route_tag_label, DEFUN (ipv6_route_tag_label,
@ -537,7 +537,7 @@ DEFUN (ipv6_route_tag_label,
"Specify label(s) for this route\n" "Specify label(s) for this route\n"
"One or more labels separated by '/'\n") "One or more labels separated by '/'\n")
{ {
return static_ipv6_func (vty, 1, argv[2]->arg, argv[3]->arg, NULL, NULL, argv[5]->arg, NULL, NULL, argv[7]->arg); return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, NULL, argv[5]->arg, NULL, NULL, argv[7]->arg);
} }
DEFUN (ipv6_route_ifname_label, DEFUN (ipv6_route_ifname_label,
@ -551,7 +551,7 @@ DEFUN (ipv6_route_ifname_label,
"Specify label(s) for this route\n" "Specify label(s) for this route\n"
"One or more labels separated by '/'\n") "One or more labels separated by '/'\n")
{ {
return static_ipv6_func (vty, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL, NULL, NULL, NULL, argv[6]->arg); return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, argv[4]->arg, NULL, NULL, NULL, NULL, argv[6]->arg);
} }
DEFUN (ipv6_route_ifname_tag_label, DEFUN (ipv6_route_ifname_tag_label,
ipv6_route_ifname_tag_label_cmd, ipv6_route_ifname_tag_label_cmd,
@ -566,7 +566,7 @@ DEFUN (ipv6_route_ifname_tag_label,
"Specify label(s) for this route\n" "Specify label(s) for this route\n"
"One or more labels separated by '/'\n") "One or more labels separated by '/'\n")
{ {
return static_ipv6_func (vty, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL, argv[6]->arg, NULL, NULL, argv[8]->arg); return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, argv[4]->arg, NULL, argv[6]->arg, NULL, NULL, argv[8]->arg);
} }
DEFUN (ipv6_route_pref_label, DEFUN (ipv6_route_pref_label,
@ -581,7 +581,7 @@ DEFUN (ipv6_route_pref_label,
"Specify label(s) for this route\n" "Specify label(s) for this route\n"
"One or more labels separated by '/'\n") "One or more labels separated by '/'\n")
{ {
return static_ipv6_func (vty, 1, argv[2]->arg, argv[3]->arg, NULL, NULL, NULL, argv[4]->arg, NULL, argv[6]->arg); return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, NULL, NULL, argv[4]->arg, NULL, argv[6]->arg);
} }
DEFUN (ipv6_route_pref_tag_label, DEFUN (ipv6_route_pref_tag_label,
@ -598,7 +598,7 @@ DEFUN (ipv6_route_pref_tag_label,
"Specify label(s) for this route\n" "Specify label(s) for this route\n"
"One or more labels separated by '/'\n") "One or more labels separated by '/'\n")
{ {
return static_ipv6_func (vty, 1, argv[2]->arg, argv[3]->arg, NULL, NULL, argv[5]->arg, argv[6]->arg, NULL, argv[8]->arg); return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, NULL, argv[5]->arg, argv[6]->arg, NULL, argv[8]->arg);
} }
DEFUN (ipv6_route_ifname_pref_label, DEFUN (ipv6_route_ifname_pref_label,
@ -613,7 +613,7 @@ DEFUN (ipv6_route_ifname_pref_label,
"Specify label(s) for this route\n" "Specify label(s) for this route\n"
"One or more labels separated by '/'\n") "One or more labels separated by '/'\n")
{ {
return static_ipv6_func (vty, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL, NULL, argv[5]->arg, NULL, argv[7]->arg); return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, argv[4]->arg, NULL, NULL, argv[5]->arg, NULL, argv[7]->arg);
} }
DEFUN (ipv6_route_ifname_pref_tag_label, DEFUN (ipv6_route_ifname_pref_tag_label,
@ -630,7 +630,7 @@ DEFUN (ipv6_route_ifname_pref_tag_label,
"Specify label(s) for this route\n" "Specify label(s) for this route\n"
"One or more labels separated by '/'\n") "One or more labels separated by '/'\n")
{ {
return static_ipv6_func (vty, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL, argv[6]->arg, argv[7]->arg, NULL, argv[9]->arg); return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, argv[4]->arg, NULL, argv[6]->arg, argv[7]->arg, NULL, argv[9]->arg);
} }
DEFUN (no_ipv6_route_label, DEFUN (no_ipv6_route_label,
@ -645,7 +645,7 @@ DEFUN (no_ipv6_route_label,
"Specify label(s) for this route\n" "Specify label(s) for this route\n"
"One or more labels separated by '/'\n") "One or more labels separated by '/'\n")
{ {
return static_ipv6_func (vty, 0, argv[3]->arg, argv[4]->arg, NULL, NULL, NULL, NULL, NULL, argv[6]->arg); return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, NULL, NULL, NULL, NULL, argv[6]->arg);
} }
DEFUN (no_ipv6_route_tag_label, DEFUN (no_ipv6_route_tag_label,
@ -662,7 +662,7 @@ DEFUN (no_ipv6_route_tag_label,
"Specify label(s) for this route\n" "Specify label(s) for this route\n"
"One or more labels separated by '/'\n") "One or more labels separated by '/'\n")
{ {
return static_ipv6_func (vty, 0, argv[3]->arg, argv[4]->arg, NULL, NULL, argv[6]->arg, NULL, NULL, argv[8]->arg); return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, NULL, argv[6]->arg, NULL, NULL, argv[8]->arg);
} }
DEFUN (no_ipv6_route_ifname_label, DEFUN (no_ipv6_route_ifname_label,
@ -677,7 +677,7 @@ DEFUN (no_ipv6_route_ifname_label,
"Specify label(s) for this route\n" "Specify label(s) for this route\n"
"One or more labels separated by '/'\n") "One or more labels separated by '/'\n")
{ {
return static_ipv6_func (vty, 0, argv[3]->arg, argv[4]->arg, argv[5]->arg, NULL, NULL, NULL, NULL, argv[7]->arg); return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, argv[5]->arg, NULL, NULL, NULL, NULL, argv[7]->arg);
} }
DEFUN (no_ipv6_route_ifname_tag_label, DEFUN (no_ipv6_route_ifname_tag_label,
@ -694,7 +694,7 @@ DEFUN (no_ipv6_route_ifname_tag_label,
"Specify label(s) for this route\n" "Specify label(s) for this route\n"
"One or more labels separated by '/'\n") "One or more labels separated by '/'\n")
{ {
return static_ipv6_func (vty, 0, argv[3]->arg, argv[4]->arg, argv[5]->arg, NULL, argv[7]->arg, NULL, NULL, argv[9]->arg); return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, argv[5]->arg, NULL, argv[7]->arg, NULL, NULL, argv[9]->arg);
} }
DEFUN (no_ipv6_route_pref_label, DEFUN (no_ipv6_route_pref_label,
@ -710,7 +710,7 @@ DEFUN (no_ipv6_route_pref_label,
"Specify label(s) for this route\n" "Specify label(s) for this route\n"
"One or more labels separated by '/'\n") "One or more labels separated by '/'\n")
{ {
return static_ipv6_func (vty, 0, argv[3]->arg, argv[4]->arg, NULL, NULL, NULL, argv[5]->arg, NULL, argv[7]->arg); return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, NULL, NULL, argv[5]->arg, NULL, argv[7]->arg);
} }
DEFUN (no_ipv6_route_pref_tag_label, DEFUN (no_ipv6_route_pref_tag_label,
@ -728,7 +728,7 @@ DEFUN (no_ipv6_route_pref_tag_label,
"Specify label(s) for this route\n" "Specify label(s) for this route\n"
"One or more labels separated by '/'\n") "One or more labels separated by '/'\n")
{ {
return static_ipv6_func (vty, 0, argv[3]->arg, argv[4]->arg, NULL, NULL, argv[6]->arg, argv[7]->arg, NULL, argv[9]->arg); return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, NULL, argv[6]->arg, argv[7]->arg, NULL, argv[9]->arg);
} }
DEFUN (no_ipv6_route_ifname_pref_label, DEFUN (no_ipv6_route_ifname_pref_label,
@ -744,7 +744,7 @@ DEFUN (no_ipv6_route_ifname_pref_label,
"Specify label(s) for this route\n" "Specify label(s) for this route\n"
"One or more labels separated by '/'\n") "One or more labels separated by '/'\n")
{ {
return static_ipv6_func (vty, 0, argv[3]->arg, argv[4]->arg, argv[5]->arg, NULL, NULL, argv[6]->arg, NULL, argv[8]->arg); return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, argv[5]->arg, NULL, NULL, argv[6]->arg, NULL, argv[8]->arg);
} }
DEFUN (no_ipv6_route_ifname_pref_tag_label, DEFUN (no_ipv6_route_ifname_pref_tag_label,
@ -762,7 +762,7 @@ DEFUN (no_ipv6_route_ifname_pref_tag_label,
"Specify label(s) for this route\n" "Specify label(s) for this route\n"
"One or more labels separated by '/'\n") "One or more labels separated by '/'\n")
{ {
return static_ipv6_func (vty, 0, argv[3]->arg, argv[4]->arg, argv[5]->arg, NULL, argv[7]->arg, argv[8]->arg, NULL, argv[10]->arg); return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, argv[5]->arg, NULL, argv[7]->arg, argv[8]->arg, NULL, argv[10]->arg);
} }
/* MPLS LSP configuration write function. */ /* MPLS LSP configuration write function. */

View File

@ -24,6 +24,7 @@
#include <lib/nexthop.h> #include <lib/nexthop.h>
#include <lib/memory.h> #include <lib/memory.h>
#include <lib/srcdest_table.h>
#include "vty.h" #include "vty.h"
#include "zebra/debug.h" #include "zebra/debug.h"
@ -37,7 +38,8 @@
/* Install static route into rib. */ /* Install static route into rib. */
void 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 rib *rib;
struct route_node *rn; struct route_node *rn;
@ -53,7 +55,7 @@ static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_ro
memset (&nh_p, 0, sizeof (nh_p)); memset (&nh_p, 0, sizeof (nh_p));
/* Lookup existing route */ /* Lookup existing route */
rn = route_node_get (table, p); rn = srcdest_rnode_get (table, p, src_p);
RNODE_FOREACH_RIB (rn, rib) RNODE_FOREACH_RIB (rn, rib)
{ {
if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED)) if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
@ -252,7 +254,8 @@ static_nexthop_same (struct nexthop *nexthop, struct static_route *si)
/* Uninstall static route from RIB. */ /* Uninstall static route from RIB. */
void 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 route_node *rn;
struct rib *rib; struct rib *rib;
@ -266,7 +269,7 @@ static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_
return; return;
/* Lookup existing route with type and distance. */ /* Lookup existing route with type and distance. */
rn = route_node_lookup (table, p); rn = srcdest_rnode_lookup (table, p, src_p);
if (! rn) if (! rn)
return; return;
@ -328,13 +331,13 @@ static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_
rib_install_kernel (rn, rib, rib); rib_install_kernel (rn, rib, rib);
/* Update redistribution if it's selected */ /* Update redistribution if it's selected */
if (CHECK_FLAG(rib->flags, ZEBRA_FLAG_SELECTED)) if (CHECK_FLAG(rib->flags, ZEBRA_FLAG_SELECTED))
redistribute_update (&rn->p, NULL, rib, NULL); redistribute_update (p, (struct prefix*)src_p, rib, NULL);
} }
else else
{ {
/* Remove from redistribute if selected route becomes inactive */ /* Remove from redistribute if selected route becomes inactive */
if (CHECK_FLAG(rib->flags, ZEBRA_FLAG_SELECTED)) if (CHECK_FLAG(rib->flags, ZEBRA_FLAG_SELECTED))
redistribute_delete (&rn->p, NULL, rib); redistribute_delete (p, (struct prefix*)src_p, rib);
/* Remove from kernel if fib route becomes inactive */ /* Remove from kernel if fib route becomes inactive */
if (CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB)) if (CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB))
rib_uninstall_kernel (rn, rib); rib_uninstall_kernel (rn, rib);
@ -364,6 +367,7 @@ static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_
int int
static_add_route (afi_t afi, safi_t safi, u_char type, struct prefix *p, 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, union g_addr *gate, ifindex_t ifindex,
const char *ifname, u_char flags, route_tag_t tag, const char *ifname, u_char flags, route_tag_t tag,
u_char distance, struct zebra_vrf *zvrf, u_char distance, struct zebra_vrf *zvrf,
@ -391,7 +395,7 @@ static_add_route (afi_t afi, safi_t safi, u_char type, struct prefix *p,
return -1; return -1;
/* Lookup static route prefix. */ /* 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. */ /* Do nothing if there is a same static route. */
for (si = rn->info; si; si = si->next) for (si = rn->info; si; si = si->next)
@ -416,7 +420,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. */ /* Distance or tag or label changed, delete existing first. */
if (update) 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); update->distance, zvrf, &update->snh_label);
/* Make new static route structure. */ /* Make new static route structure. */
@ -477,13 +481,14 @@ static_add_route (afi_t afi, safi_t safi, u_char type, struct prefix *p,
si->next = cp; si->next = cp;
/* Install into rib. */ /* Install into rib. */
static_install_route (afi, safi, p, si); static_install_route (afi, safi, p, src_p, si);
return 1; return 1;
} }
int int
static_delete_route (afi_t afi, safi_t safi, u_char type, struct prefix *p, 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, union g_addr *gate, ifindex_t ifindex,
route_tag_t tag, u_char distance, struct zebra_vrf *zvrf, route_tag_t tag, u_char distance, struct zebra_vrf *zvrf,
struct static_nh_label *snh_label) struct static_nh_label *snh_label)
@ -498,7 +503,7 @@ static_delete_route (afi_t afi, safi_t safi, u_char type, struct prefix *p,
return -1; return -1;
/* Lookup static route prefix. */ /* Lookup static route prefix. */
rn = route_node_lookup (stable, p); rn = srcdest_rnode_lookup (stable, p, src_p);
if (! rn) if (! rn)
return 0; return 0;
@ -522,7 +527,7 @@ static_delete_route (afi_t afi, safi_t safi, u_char type, struct prefix *p,
} }
/* Install into rib. */ /* 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. */ /* Unlink static route from linked list. */
if (si->prev) if (si->prev)

View File

@ -83,12 +83,15 @@ struct static_route
}; };
extern void extern 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);
extern void extern 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);
extern int extern int
static_add_route (afi_t, safi_t safi, u_char type, struct prefix *p, static_add_route (afi_t, safi_t safi, u_char type, struct prefix *p,
struct prefix_ipv6 *src_p,
union g_addr *gate, ifindex_t ifindex, union g_addr *gate, ifindex_t ifindex,
const char *ifname, u_char flags, route_tag_t tag, const char *ifname, u_char flags, route_tag_t tag,
u_char distance, struct zebra_vrf *zvrf, u_char distance, struct zebra_vrf *zvrf,
@ -96,6 +99,7 @@ static_add_route (afi_t, safi_t safi, u_char type, struct prefix *p,
extern int extern int
static_delete_route (afi_t, safi_t safi, u_char type, struct prefix *p, static_delete_route (afi_t, 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, union g_addr *gate, ifindex_t ifindex, route_tag_t tag,
u_char distance, struct zebra_vrf *zvrf, u_char distance, struct zebra_vrf *zvrf,
struct static_nh_label *snh_label); struct static_nh_label *snh_label);
@ -109,6 +113,7 @@ zebra_static_ipv4 (struct vty *vty, safi_t safi, int add_cmd,
int int
static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str, static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
const char *src_str,
const char *gate_str, const char *ifname, const char *gate_str, const char *ifname,
const char *flag_str, const char *tag_str, const char *flag_str, const char *tag_str,
const char *distance_str, const char *vrf_id_str, const char *distance_str, const char *vrf_id_str,

View File

@ -133,7 +133,7 @@ zebra_vrf_static_route_interface_fixup (struct interface *ifp)
(si->ifindex != ifp->ifindex)) (si->ifindex != ifp->ifindex))
{ {
si->ifindex = ifp->ifindex; si->ifindex = ifp->ifindex;
static_install_route (afi, safi, &rn->p, si); static_install_route (afi, safi, &rn->p, NULL, si);
} }
} }
} }
@ -177,7 +177,7 @@ zebra_vrf_enable (struct vrf *vrf)
else else
continue; continue;
} }
static_install_route (afi, safi, &rn->p, si); static_install_route (afi, safi, &rn->p, NULL, si);
} }
} }
@ -208,7 +208,7 @@ zebra_vrf_disable (struct vrf *vrf)
for (rn = route_top (stable); rn; rn = route_next (rn)) for (rn = route_top (stable); rn; rn = route_next (rn))
for (si = rn->info; si; si = si->next) for (si = rn->info; si; si = si->next)
static_uninstall_route(afi, safi, &rn->p, si); static_uninstall_route(afi, safi, &rn->p, NULL, si);
} }
return 0; return 0;
@ -344,8 +344,7 @@ zebra_rtable_node_cleanup (struct route_table *table, struct route_node *node)
} }
static void static void
zebra_stable_node_destroy (route_table_delegate_t *delegate, zebra_stable_node_cleanup (struct route_table *table, struct route_node *node)
struct route_table *table, struct route_node *node)
{ {
struct static_route *si, *next; struct static_route *si, *next;
@ -355,8 +354,6 @@ zebra_stable_node_destroy (route_table_delegate_t *delegate,
next = si->next; next = si->next;
XFREE (MTYPE_STATIC_ROUTE, si); XFREE (MTYPE_STATIC_ROUTE, si);
} }
route_node_destroy (delegate, table, node);
} }
static void static void
@ -366,11 +363,6 @@ zebra_rnhtable_node_cleanup (struct route_table *table, struct route_node *node)
zebra_free_rnh (node->info); zebra_free_rnh (node->info);
} }
route_table_delegate_t zebra_stable_delegate = {
.create_node = route_node_create,
.destroy_node = zebra_stable_node_destroy
};
/* /*
* Create a routing table for the specific AFI/SAFI in the given VRF. * Create a routing table for the specific AFI/SAFI in the given VRF.
*/ */
@ -410,11 +402,15 @@ zebra_vrf_alloc (void)
for (afi = AFI_IP; afi <= AFI_IP6; afi++) for (afi = AFI_IP; afi <= AFI_IP6; afi++)
{ {
for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++)
{ {
zebra_vrf_table_create (zvrf, afi, safi); zebra_vrf_table_create (zvrf, afi, safi);
zvrf->stable[afi][safi] = if (afi == AFI_IP6)
route_table_init_with_delegate (&zebra_stable_delegate); table = srcdest_table_init();
} else
table = route_table_init();
table->cleanup = zebra_stable_node_cleanup;
zvrf->stable[afi][safi] = table;
}
table = route_table_init(); table = route_table_init();
table->cleanup = zebra_rnhtable_node_cleanup; table->cleanup = zebra_rnhtable_node_cleanup;

View File

@ -142,10 +142,10 @@ zebra_static_ipv4 (struct vty *vty, safi_t safi, int add_cmd,
return CMD_WARNING; return CMD_WARNING;
} }
if (add_cmd) if (add_cmd)
static_add_route (AFI_IP, safi, type, &p, NULL, ifindex, ifname, static_add_route (AFI_IP, safi, type, &p, NULL, NULL, ifindex, ifname,
ZEBRA_FLAG_BLACKHOLE, tag, distance, zvrf, &snh_label); ZEBRA_FLAG_BLACKHOLE, tag, distance, zvrf, &snh_label);
else else
static_delete_route (AFI_IP, safi, type, &p, NULL, ifindex, tag, static_delete_route (AFI_IP, safi, type, &p, NULL, NULL, ifindex, tag,
distance, zvrf, &snh_label); distance, zvrf, &snh_label);
return CMD_SUCCESS; return CMD_SUCCESS;
} }
@ -170,10 +170,10 @@ zebra_static_ipv4 (struct vty *vty, safi_t safi, int add_cmd,
if (gate_str == NULL) if (gate_str == NULL)
{ {
if (add_cmd) if (add_cmd)
static_add_route (AFI_IP, safi, type, &p, NULL, ifindex, ifname, flag, static_add_route (AFI_IP, safi, type, &p, NULL, NULL, ifindex, ifname, flag,
tag, distance, zvrf, &snh_label); tag, distance, zvrf, &snh_label);
else else
static_delete_route (AFI_IP, safi, type, &p, NULL, ifindex, tag, distance, static_delete_route (AFI_IP, safi, type, &p, NULL, NULL, ifindex, tag, distance,
zvrf, &snh_label); zvrf, &snh_label);
return CMD_SUCCESS; return CMD_SUCCESS;
@ -199,11 +199,11 @@ zebra_static_ipv4 (struct vty *vty, safi_t safi, int add_cmd,
type = STATIC_IPV4_GATEWAY; type = STATIC_IPV4_GATEWAY;
if (add_cmd) if (add_cmd)
static_add_route (AFI_IP, safi, type, &p, static_add_route (AFI_IP, safi, type, &p, NULL,
ifindex ? NULL : (union g_addr *)&gate, ifindex, ifname, ifindex ? NULL : (union g_addr *)&gate, ifindex, ifname,
flag, tag, distance, zvrf, &snh_label); flag, tag, distance, zvrf, &snh_label);
else else
static_delete_route (AFI_IP, safi, type, &p, static_delete_route (AFI_IP, safi, type, &p, NULL,
ifindex ? NULL : (union g_addr *)&gate, ifindex, tag, ifindex ? NULL : (union g_addr *)&gate, ifindex, tag,
distance, zvrf, &snh_label); distance, zvrf, &snh_label);
@ -2329,6 +2329,7 @@ static_config_ipv4 (struct vty *vty, safi_t safi, const char *cmd)
/* General fucntion for IPv6 static route. */ /* General fucntion for IPv6 static route. */
int int
static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str, static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
const char *src_str,
const char *gate_str, const char *ifname, const char *gate_str, const char *ifname,
const char *flag_str, const char *tag_str, const char *flag_str, const char *tag_str,
const char *distance_str, const char *vrf_id_str, const char *distance_str, const char *vrf_id_str,
@ -2336,7 +2337,8 @@ static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
{ {
int ret; int ret;
u_char distance; u_char distance;
struct prefix p; struct prefix p, src;
struct prefix_ipv6 *src_p = NULL;
struct in6_addr *gate = NULL; struct in6_addr *gate = NULL;
struct in6_addr gate_addr; struct in6_addr gate_addr;
u_char type = STATIC_BLACKHOLE; u_char type = STATIC_BLACKHOLE;
@ -2354,6 +2356,17 @@ static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
return CMD_WARNING; return CMD_WARNING;
} }
if (src_str)
{
ret = str2prefix (src_str, &src);
if (ret <= 0 || src.family != AF_INET6)
{
vty_out (vty, "%% Malformed source address%s", VTY_NEWLINE);
return CMD_WARNING;
}
src_p = (struct prefix_ipv6*)&src;
}
/* Apply mask for given prefix. */ /* Apply mask for given prefix. */
apply_mask (&p); apply_mask (&p);
@ -2407,10 +2420,10 @@ static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
return CMD_WARNING; return CMD_WARNING;
} }
if (add_cmd) if (add_cmd)
static_add_route (AFI_IP6, SAFI_UNICAST, type, &p, NULL, ifindex, ifname, static_add_route (AFI_IP6, SAFI_UNICAST, type, &p, NULL, NULL, ifindex, ifname,
ZEBRA_FLAG_BLACKHOLE, tag, distance, zvrf, &snh_label); ZEBRA_FLAG_BLACKHOLE, tag, distance, zvrf, &snh_label);
else else
static_delete_route (AFI_IP6, SAFI_UNICAST, type, &p, NULL, ifindex, tag, static_delete_route (AFI_IP6, SAFI_UNICAST, type, &p, NULL, NULL, ifindex, tag,
distance, zvrf, &snh_label); distance, zvrf, &snh_label);
return CMD_SUCCESS; return CMD_SUCCESS;
} }
@ -2474,10 +2487,10 @@ static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
} }
if (add_cmd) if (add_cmd)
static_add_route (AFI_IP6, SAFI_UNICAST, type, &p, (union g_addr *)gate, static_add_route (AFI_IP6, SAFI_UNICAST, type, &p, src_p, (union g_addr *)gate,
ifindex, ifname, flag, tag, distance, zvrf, &snh_label); ifindex, ifname, flag, tag, distance, zvrf, &snh_label);
else else
static_delete_route (AFI_IP6, SAFI_UNICAST, type, &p, (union g_addr *)gate, static_delete_route (AFI_IP6, SAFI_UNICAST, type, &p, src_p, (union g_addr *)gate,
ifindex, tag, distance, zvrf, &snh_label); ifindex, tag, distance, zvrf, &snh_label);
return CMD_SUCCESS; return CMD_SUCCESS;
@ -2485,10 +2498,12 @@ static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
DEFUN (ipv6_route, DEFUN (ipv6_route,
ipv6_route_cmd, ipv6_route_cmd,
"ipv6 route X:X::X:X/M <X:X::X:X|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]", "ipv6 route X:X::X:X/M [from X:X::X:X/M] <X:X::X:X|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
IP_STR IP_STR
"Establish static routes\n" "Establish static routes\n"
"IPv6 destination prefix (e.g. 3ffe:506::/32)\n" "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
"IPv6 source-dest route\n"
"IPv6 source prefix\n"
"IPv6 gateway address\n" "IPv6 gateway address\n"
"IPv6 gateway interface name\n" "IPv6 gateway interface name\n"
"Null interface\n" "Null interface\n"
@ -2501,15 +2516,29 @@ DEFUN (ipv6_route,
"One or more labels separated by '/'\n") "One or more labels separated by '/'\n")
{ {
int idx_ipv6_prefixlen = 2; int idx_ipv6_prefixlen = 2;
int idx_ipv6_ifname = 3; int idx_ipv6_ifname;
int idx_curr = 4; int idx_curr;
char *tag, *distance, *vrf; char *src, *tag, *distance, *vrf;
if (!strcmp(argv[3]->text, "from"))
{
src = argv[4]->arg;
idx_ipv6_ifname = 5;
idx_curr = 6;
}
else
{
src = NULL;
idx_ipv6_ifname = 3;
idx_curr = 4;
}
tag = distance = vrf = NULL; tag = distance = vrf = NULL;
zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
return static_ipv6_func (vty, 1, return static_ipv6_func (vty, 1,
argv[idx_ipv6_prefixlen]->arg, argv[idx_ipv6_prefixlen]->arg,
src,
argv[idx_ipv6_ifname]->arg, argv[idx_ipv6_ifname]->arg,
NULL, NULL, NULL, NULL,
tag, distance, vrf, NULL); tag, distance, vrf, NULL);
@ -2517,10 +2546,12 @@ DEFUN (ipv6_route,
DEFUN (ipv6_route_flags, DEFUN (ipv6_route_flags,
ipv6_route_flags_cmd, ipv6_route_flags_cmd,
"ipv6 route X:X::X:X/M <X:X::X:X|INTERFACE> <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]", "ipv6 route X:X::X:X/M [from X:X::X:X/M] <X:X::X:X|INTERFACE> <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
IP_STR IP_STR
"Establish static routes\n" "Establish static routes\n"
"IPv6 destination prefix (e.g. 3ffe:506::/32)\n" "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
"IPv6 source-dest route\n"
"IPv6 source prefix\n"
"IPv6 gateway address\n" "IPv6 gateway address\n"
"IPv6 gateway interface name\n" "IPv6 gateway interface name\n"
"Emit an ICMP unreachable when matched\n" "Emit an ICMP unreachable when matched\n"
@ -2534,16 +2565,32 @@ DEFUN (ipv6_route_flags,
"One or more labels separated by '/'\n") "One or more labels separated by '/'\n")
{ {
int idx_ipv6_prefixlen = 2; int idx_ipv6_prefixlen = 2;
int idx_ipv6_ifname = 3; int idx_ipv6_ifname;
int idx_reject_blackhole = 4; int idx_reject_blackhole;
int idx_curr = 5; int idx_curr;
char *tag, *distance, *vrf; char *src, *tag, *distance, *vrf;
if (!strcmp(argv[3]->text, "from"))
{
src = argv[4]->arg;
idx_ipv6_ifname = 5;
idx_reject_blackhole = 6;
idx_curr = 7;
}
else
{
src = NULL;
idx_ipv6_ifname = 3;
idx_reject_blackhole = 4;
idx_curr = 5;
}
tag = distance = vrf = NULL; tag = distance = vrf = NULL;
zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
return static_ipv6_func (vty, 1, return static_ipv6_func (vty, 1,
argv[idx_ipv6_prefixlen]->arg, argv[idx_ipv6_prefixlen]->arg,
src,
argv[idx_ipv6_ifname]->arg, argv[idx_ipv6_ifname]->arg,
NULL, NULL,
argv[idx_reject_blackhole]->arg, argv[idx_reject_blackhole]->arg,
@ -2552,10 +2599,12 @@ DEFUN (ipv6_route_flags,
DEFUN (ipv6_route_ifname, DEFUN (ipv6_route_ifname,
ipv6_route_ifname_cmd, ipv6_route_ifname_cmd,
"ipv6 route X:X::X:X/M X:X::X:X INTERFACE [tag (1-4294967295)] [(1-255)] [vrf NAME]", "ipv6 route X:X::X:X/M [from X:X::X:X/M] X:X::X:X INTERFACE [tag (1-4294967295)] [(1-255)] [vrf NAME]",
IP_STR IP_STR
"Establish static routes\n" "Establish static routes\n"
"IPv6 destination prefix (e.g. 3ffe:506::/32)\n" "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
"IPv6 source-dest route\n"
"IPv6 source prefix\n"
"IPv6 gateway address\n" "IPv6 gateway address\n"
"IPv6 gateway interface name\n" "IPv6 gateway interface name\n"
"Set tag for this route\n" "Set tag for this route\n"
@ -2569,13 +2618,29 @@ DEFUN (ipv6_route_ifname,
int idx_ipv6 = 3; int idx_ipv6 = 3;
int idx_interface = 4; int idx_interface = 4;
int idx_curr = 5; int idx_curr = 5;
char *tag, *distance, *vrf; char *src, *tag, *distance, *vrf;
if (!strcmp(argv[3]->text, "from"))
{
src = argv[4]->arg;
idx_ipv6 = 5;
idx_interface = 6;
idx_curr = 7;
}
else
{
src = NULL;
idx_ipv6 = 3;
idx_interface = 4;
idx_curr = 5;
}
tag = distance = vrf = NULL; tag = distance = vrf = NULL;
zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
return static_ipv6_func (vty, 1, return static_ipv6_func (vty, 1,
argv[idx_ipv6_prefixlen]->arg, argv[idx_ipv6_prefixlen]->arg,
src,
argv[idx_ipv6]->arg, argv[idx_ipv6]->arg,
argv[idx_interface]->arg, argv[idx_interface]->arg,
NULL, NULL,
@ -2584,10 +2649,12 @@ DEFUN (ipv6_route_ifname,
DEFUN (ipv6_route_ifname_flags, DEFUN (ipv6_route_ifname_flags,
ipv6_route_ifname_flags_cmd, ipv6_route_ifname_flags_cmd,
"ipv6 route X:X::X:X/M X:X::X:X INTERFACE <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]", "ipv6 route X:X::X:X/M [from X:X::X:X/M] X:X::X:X INTERFACE <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
IP_STR IP_STR
"Establish static routes\n" "Establish static routes\n"
"IPv6 destination prefix (e.g. 3ffe:506::/32)\n" "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
"IPv6 source-dest route\n"
"IPv6 source prefix\n"
"IPv6 gateway address\n" "IPv6 gateway address\n"
"IPv6 gateway interface name\n" "IPv6 gateway interface name\n"
"Emit an ICMP unreachable when matched\n" "Emit an ICMP unreachable when matched\n"
@ -2600,17 +2667,35 @@ DEFUN (ipv6_route_ifname_flags,
"One or more labels separated by '/'\n") "One or more labels separated by '/'\n")
{ {
int idx_ipv6_prefixlen = 2; int idx_ipv6_prefixlen = 2;
int idx_ipv6 = 3; int idx_ipv6;
int idx_interface = 4; int idx_interface;
int idx_reject_blackhole = 5; int idx_reject_blackhole;
int idx_curr = 6; int idx_curr;
char *tag, *distance, *vrf; char *src, *tag, *distance, *vrf;
if (!strcmp(argv[3]->text, "from"))
{
src = argv[4]->arg;
idx_ipv6 = 5;
idx_interface = 6;
idx_reject_blackhole = 7;
idx_curr = 8;
}
else
{
src = NULL;
idx_ipv6 = 3;
idx_interface = 4;
idx_reject_blackhole = 5;
idx_curr = 6;
}
tag = distance = vrf = NULL; tag = distance = vrf = NULL;
zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
return static_ipv6_func (vty, 1, return static_ipv6_func (vty, 1,
argv[idx_ipv6_prefixlen]->arg, argv[idx_ipv6_prefixlen]->arg,
src,
argv[idx_ipv6]->arg, argv[idx_ipv6]->arg,
argv[idx_interface]->arg, argv[idx_interface]->arg,
argv[idx_reject_blackhole]->arg, argv[idx_reject_blackhole]->arg,
@ -2619,11 +2704,13 @@ DEFUN (ipv6_route_ifname_flags,
DEFUN (no_ipv6_route, DEFUN (no_ipv6_route,
no_ipv6_route_cmd, no_ipv6_route_cmd,
"no ipv6 route X:X::X:X/M <X:X::X:X|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]", "no ipv6 route X:X::X:X/M [from X:X::X:X/M] <X:X::X:X|INTERFACE|null0> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
NO_STR NO_STR
IP_STR IP_STR
"Establish static routes\n" "Establish static routes\n"
"IPv6 destination prefix (e.g. 3ffe:506::/32)\n" "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
"IPv6 source-dest route\n"
"IPv6 source prefix\n"
"IPv6 gateway address\n" "IPv6 gateway address\n"
"IPv6 gateway interface name\n" "IPv6 gateway interface name\n"
"Null interface\n" "Null interface\n"
@ -2635,15 +2722,29 @@ DEFUN (no_ipv6_route,
"One or more labels separated by '/'\n") "One or more labels separated by '/'\n")
{ {
int idx_ipv6_prefixlen = 3; int idx_ipv6_prefixlen = 3;
int idx_ipv6_ifname = 4; int idx_ipv6_ifname;
int idx_curr = 5; int idx_curr;
char *tag, *distance, *vrf; char *src, *tag, *distance, *vrf;
if (!strcmp(argv[4]->text, "from"))
{
src = argv[5]->arg;
idx_ipv6_ifname = 6;
idx_curr = 7;
}
else
{
src = NULL;
idx_ipv6_ifname = 4;
idx_curr = 5;
}
tag = distance = vrf = NULL; tag = distance = vrf = NULL;
zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
return static_ipv6_func (vty, 0, return static_ipv6_func (vty, 0,
argv[idx_ipv6_prefixlen]->arg, argv[idx_ipv6_prefixlen]->arg,
src,
argv[idx_ipv6_ifname]->arg, argv[idx_ipv6_ifname]->arg,
NULL, NULL, NULL, NULL,
tag, distance, vrf, NULL); tag, distance, vrf, NULL);
@ -2651,11 +2752,13 @@ DEFUN (no_ipv6_route,
DEFUN (no_ipv6_route_flags, DEFUN (no_ipv6_route_flags,
no_ipv6_route_flags_cmd, no_ipv6_route_flags_cmd,
"no ipv6 route X:X::X:X/M <X:X::X:X|INTERFACE> <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]", "no ipv6 route X:X::X:X/M [from X:X::X:X/M] <X:X::X:X|INTERFACE> <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
NO_STR NO_STR
IP_STR IP_STR
"Establish static routes\n" "Establish static routes\n"
"IPv6 destination prefix (e.g. 3ffe:506::/32)\n" "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
"IPv6 source-dest route\n"
"IPv6 source prefix\n"
"IPv6 gateway address\n" "IPv6 gateway address\n"
"IPv6 gateway interface name\n" "IPv6 gateway interface name\n"
"Emit an ICMP unreachable when matched\n" "Emit an ICMP unreachable when matched\n"
@ -2668,16 +2771,32 @@ DEFUN (no_ipv6_route_flags,
"One or more labels separated by '/'\n") "One or more labels separated by '/'\n")
{ {
int idx_ipv6_prefixlen = 3; int idx_ipv6_prefixlen = 3;
int idx_ipv6_ifname = 4; int idx_ipv6_ifname;
int idx_reject_blackhole = 5; int idx_reject_blackhole;
int idx_curr = 6; int idx_curr;
char *tag, *distance, *vrf; char *src, *tag, *distance, *vrf;
if (!strcmp(argv[4]->text, "from"))
{
src = argv[5]->arg;
idx_ipv6_ifname = 6;
idx_reject_blackhole = 7;
idx_curr = 8;
}
else
{
src = NULL;
idx_ipv6_ifname = 4;
idx_reject_blackhole = 5;
idx_curr = 6;
}
tag = distance = vrf = NULL; tag = distance = vrf = NULL;
zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
return static_ipv6_func (vty, 0, return static_ipv6_func (vty, 0,
argv[idx_ipv6_prefixlen]->arg, argv[idx_ipv6_prefixlen]->arg,
src,
argv[idx_ipv6_ifname]->arg, argv[idx_ipv6_ifname]->arg,
NULL, NULL,
argv[idx_reject_blackhole]->arg, argv[idx_reject_blackhole]->arg,
@ -2686,11 +2805,13 @@ DEFUN (no_ipv6_route_flags,
DEFUN (no_ipv6_route_ifname, DEFUN (no_ipv6_route_ifname,
no_ipv6_route_ifname_cmd, no_ipv6_route_ifname_cmd,
"no ipv6 route X:X::X:X/M X:X::X:X INTERFACE [tag (1-4294967295)] [(1-255)] [vrf NAME]", "no ipv6 route X:X::X:X/M [from X:X::X:X/M] X:X::X:X INTERFACE [tag (1-4294967295)] [(1-255)] [vrf NAME]",
NO_STR NO_STR
IP_STR IP_STR
"Establish static routes\n" "Establish static routes\n"
"IPv6 destination prefix (e.g. 3ffe:506::/32)\n" "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
"IPv6 source-dest route\n"
"IPv6 source prefix\n"
"IPv6 gateway address\n" "IPv6 gateway address\n"
"IPv6 gateway interface name\n" "IPv6 gateway interface name\n"
"Set tag for this route\n" "Set tag for this route\n"
@ -2701,16 +2822,32 @@ DEFUN (no_ipv6_route_ifname,
"One or more labels separated by '/'\n") "One or more labels separated by '/'\n")
{ {
int idx_ipv6_prefixlen = 3; int idx_ipv6_prefixlen = 3;
int idx_ipv6 = 4; int idx_ipv6;
int idx_interface = 5; int idx_interface;
int idx_curr = 6; int idx_curr;
char *tag, *distance, *vrf; char *src, *tag, *distance, *vrf;
if (!strcmp(argv[4]->text, "from"))
{
src = argv[5]->arg;
idx_ipv6 = 6;
idx_interface = 7;
idx_curr = 8;
}
else
{
src = NULL;
idx_ipv6 = 4;
idx_interface = 5;
idx_curr = 6;
}
tag = distance = vrf = NULL; tag = distance = vrf = NULL;
zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
return static_ipv6_func (vty, 0, return static_ipv6_func (vty, 0,
argv[idx_ipv6_prefixlen]->arg, argv[idx_ipv6_prefixlen]->arg,
src,
argv[idx_ipv6]->arg, argv[idx_ipv6]->arg,
argv[idx_interface]->arg, argv[idx_interface]->arg,
NULL, NULL,
@ -2719,11 +2856,13 @@ DEFUN (no_ipv6_route_ifname,
DEFUN (no_ipv6_route_ifname_flags, DEFUN (no_ipv6_route_ifname_flags,
no_ipv6_route_ifname_flags_cmd, no_ipv6_route_ifname_flags_cmd,
"no ipv6 route X:X::X:X/M X:X::X:X INTERFACE <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]", "no ipv6 route X:X::X:X/M [from X:X::X:X/M] X:X::X:X INTERFACE <reject|blackhole> [tag (1-4294967295)] [(1-255)] [vrf NAME]",
NO_STR NO_STR
IP_STR IP_STR
"Establish static routes\n" "Establish static routes\n"
"IPv6 destination prefix (e.g. 3ffe:506::/32)\n" "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
"IPv6 source-dest route\n"
"IPv6 source prefix\n"
"IPv6 gateway address\n" "IPv6 gateway address\n"
"IPv6 gateway interface name\n" "IPv6 gateway interface name\n"
"Emit an ICMP unreachable when matched\n" "Emit an ICMP unreachable when matched\n"
@ -2736,17 +2875,35 @@ DEFUN (no_ipv6_route_ifname_flags,
"One or more labels separated by '/'\n") "One or more labels separated by '/'\n")
{ {
int idx_ipv6_prefixlen = 3; int idx_ipv6_prefixlen = 3;
int idx_ipv6 = 4; int idx_ipv6;
int idx_interface = 5; int idx_interface;
int idx_reject_blackhole = 6; int idx_reject_blackhole;
int idx_curr = 7; int idx_curr;
char *tag, *distance, *vrf; char *src, *tag, *distance, *vrf;
if (!strcmp(argv[4]->text, "from"))
{
src = argv[5]->arg;
idx_ipv6 = 6;
idx_interface = 7;
idx_reject_blackhole = 8;
idx_curr = 9;
}
else
{
src = NULL;
idx_ipv6 = 4;
idx_interface = 5;
idx_reject_blackhole = 6;
idx_curr = 7;
}
tag = distance = vrf = NULL; tag = distance = vrf = NULL;
zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
return static_ipv6_func (vty, 0, return static_ipv6_func (vty, 0,
argv[idx_ipv6_prefixlen]->arg, argv[idx_ipv6_prefixlen]->arg,
src,
argv[idx_ipv6]->arg, argv[idx_ipv6]->arg,
argv[idx_interface]->arg, argv[idx_interface]->arg,
argv[idx_reject_blackhole]->arg, argv[idx_reject_blackhole]->arg,
@ -3590,7 +3747,7 @@ static_config_ipv6 (struct vty *vty)
struct route_node *rn; struct route_node *rn;
struct static_route *si; struct static_route *si;
int write = 0; int write = 0;
char buf[PREFIX_STRLEN]; char buf[SRCDEST2STR_BUFFER];
struct route_table *stable; struct route_table *stable;
struct vrf *vrf; struct vrf *vrf;
struct zebra_vrf *zvrf; struct zebra_vrf *zvrf;
@ -3602,10 +3759,10 @@ static_config_ipv6 (struct vty *vty)
if ((stable = zvrf->stable[AFI_IP6][SAFI_UNICAST]) == NULL) if ((stable = zvrf->stable[AFI_IP6][SAFI_UNICAST]) == NULL)
continue; continue;
for (rn = route_top (stable); rn; rn = route_next (rn)) for (rn = route_top (stable); rn; rn = srcdest_route_next (rn))
for (si = rn->info; si; si = si->next) for (si = rn->info; si; si = si->next)
{ {
vty_out (vty, "ipv6 route %s", prefix2str (&rn->p, buf, sizeof buf)); vty_out (vty, "ipv6 route %s", srcdest_rnode2str (rn, buf, sizeof buf));
switch (si->type) switch (si->type)
{ {