"Specify label(s) for this route\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,
"Specify label(s) for this route\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,
"Specify label(s) for this route\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,
ipv6_route_ifname_tag_label_cmd,
"Specify label(s) for this route\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,
"Specify label(s) for this route\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,
"Specify label(s) for this route\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,
"Specify label(s) for this route\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,
"Specify label(s) for this route\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,
"Specify label(s) for this route\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,
"Specify label(s) for this route\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,
"Specify label(s) for this route\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,
"Specify label(s) for this route\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,
"Specify label(s) for this route\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,
"Specify label(s) for this route\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,
"Specify label(s) for this route\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,
"Specify label(s) for this route\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. */
#include <lib/nexthop.h>
#include <lib/memory.h>
+#include <lib/srcdest_table.h>
#include "vty.h"
#include "zebra/debug.h"
/* 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_node *rn;
memset (&nh_p, 0, sizeof (nh_p));
/* Lookup existing route */
- rn = route_node_get (table, p);
+ rn = srcdest_rnode_get (table, p, src_p);
RNODE_FOREACH_RIB (rn, rib)
{
if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
/* 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;
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;
rib_install_kernel (rn, rib, rib);
/* Update redistribution if it's 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
{
/* Remove from redistribute if selected route becomes inactive */
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 */
if (CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB))
rib_uninstall_kernel (rn, rib);
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,
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)
/* 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. */
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)
return -1;
/* Lookup static route prefix. */
- rn = route_node_lookup (stable, p);
+ rn = srcdest_rnode_lookup (stable, p, src_p);
if (! rn)
return 0;
}
/* 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)
};
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
-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
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,
const char *ifname, u_char flags, route_tag_t tag,
u_char distance, struct zebra_vrf *zvrf,
extern int
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,
u_char distance, struct zebra_vrf *zvrf,
struct static_nh_label *snh_label);
int
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 *flag_str, const char *tag_str,
const char *distance_str, const char *vrf_id_str,
(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);
}
}
}
else
continue;
}
- static_install_route (afi, safi, &rn->p, si);
+ static_install_route (afi, safi, &rn->p, NULL, si);
}
}
for (rn = route_top (stable); rn; rn = route_next (rn))
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;
}
static void
-zebra_stable_node_destroy (route_table_delegate_t *delegate,
- struct route_table *table, struct route_node *node)
+zebra_stable_node_cleanup (struct route_table *table, struct route_node *node)
{
struct static_route *si, *next;
next = si->next;
XFREE (MTYPE_STATIC_ROUTE, si);
}
-
- route_node_destroy (delegate, table, node);
}
static void
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.
*/
for (afi = AFI_IP; afi <= AFI_IP6; afi++)
{
for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++)
- {
- zebra_vrf_table_create (zvrf, afi, safi);
- zvrf->stable[afi][safi] =
- route_table_init_with_delegate (&zebra_stable_delegate);
- }
+ {
+ zebra_vrf_table_create (zvrf, afi, safi);
+ if (afi == AFI_IP6)
+ 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->cleanup = zebra_rnhtable_node_cleanup;
return CMD_WARNING;
}
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);
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);
return CMD_SUCCESS;
}
if (gate_str == NULL)
{
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);
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);
return CMD_SUCCESS;
type = STATIC_IPV4_GATEWAY;
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,
flag, tag, distance, zvrf, &snh_label);
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,
distance, zvrf, &snh_label);
/* General fucntion for IPv6 static route. */
int
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 *flag_str, const char *tag_str,
const char *distance_str, const char *vrf_id_str,
{
int ret;
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_addr;
u_char type = STATIC_BLACKHOLE;
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 (&p);
return CMD_WARNING;
}
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);
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);
return CMD_SUCCESS;
}
}
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);
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);
return CMD_SUCCESS;
DEFUN (ipv6_route,
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
"Establish static routes\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 interface name\n"
"Null interface\n"
"One or more labels separated by '/'\n")
{
int idx_ipv6_prefixlen = 2;
- int idx_ipv6_ifname = 3;
- int idx_curr = 4;
- char *tag, *distance, *vrf;
+ int idx_ipv6_ifname;
+ int idx_curr;
+ 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;
zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
return static_ipv6_func (vty, 1,
argv[idx_ipv6_prefixlen]->arg,
+ src,
argv[idx_ipv6_ifname]->arg,
NULL, NULL,
tag, distance, vrf, NULL);
DEFUN (ipv6_route_flags,
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
"Establish static routes\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 interface name\n"
"Emit an ICMP unreachable when matched\n"
"One or more labels separated by '/'\n")
{
int idx_ipv6_prefixlen = 2;
- int idx_ipv6_ifname = 3;
- int idx_reject_blackhole = 4;
- int idx_curr = 5;
- char *tag, *distance, *vrf;
+ int idx_ipv6_ifname;
+ int idx_reject_blackhole;
+ int idx_curr;
+ 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;
zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
return static_ipv6_func (vty, 1,
argv[idx_ipv6_prefixlen]->arg,
+ src,
argv[idx_ipv6_ifname]->arg,
NULL,
argv[idx_reject_blackhole]->arg,
DEFUN (ipv6_route_ifname,
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
"Establish static routes\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 interface name\n"
"Set tag for this route\n"
int idx_ipv6 = 3;
int idx_interface = 4;
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;
zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
return static_ipv6_func (vty, 1,
argv[idx_ipv6_prefixlen]->arg,
+ src,
argv[idx_ipv6]->arg,
argv[idx_interface]->arg,
NULL,
DEFUN (ipv6_route_ifname_flags,
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
"Establish static routes\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 interface name\n"
"Emit an ICMP unreachable when matched\n"
"One or more labels separated by '/'\n")
{
int idx_ipv6_prefixlen = 2;
- int idx_ipv6 = 3;
- int idx_interface = 4;
- int idx_reject_blackhole = 5;
- int idx_curr = 6;
- char *tag, *distance, *vrf;
+ int idx_ipv6;
+ int idx_interface;
+ int idx_reject_blackhole;
+ int idx_curr;
+ 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;
zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
return static_ipv6_func (vty, 1,
argv[idx_ipv6_prefixlen]->arg,
+ src,
argv[idx_ipv6]->arg,
argv[idx_interface]->arg,
argv[idx_reject_blackhole]->arg,
DEFUN (no_ipv6_route,
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
IP_STR
"Establish static routes\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 interface name\n"
"Null interface\n"
"One or more labels separated by '/'\n")
{
int idx_ipv6_prefixlen = 3;
- int idx_ipv6_ifname = 4;
- int idx_curr = 5;
- char *tag, *distance, *vrf;
+ int idx_ipv6_ifname;
+ int idx_curr;
+ 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;
zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
return static_ipv6_func (vty, 0,
argv[idx_ipv6_prefixlen]->arg,
+ src,
argv[idx_ipv6_ifname]->arg,
NULL, NULL,
tag, distance, vrf, NULL);
DEFUN (no_ipv6_route_flags,
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
IP_STR
"Establish static routes\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 interface name\n"
"Emit an ICMP unreachable when matched\n"
"One or more labels separated by '/'\n")
{
int idx_ipv6_prefixlen = 3;
- int idx_ipv6_ifname = 4;
- int idx_reject_blackhole = 5;
- int idx_curr = 6;
- char *tag, *distance, *vrf;
+ int idx_ipv6_ifname;
+ int idx_reject_blackhole;
+ int idx_curr;
+ 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;
zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
return static_ipv6_func (vty, 0,
argv[idx_ipv6_prefixlen]->arg,
+ src,
argv[idx_ipv6_ifname]->arg,
NULL,
argv[idx_reject_blackhole]->arg,
DEFUN (no_ipv6_route_ifname,
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
IP_STR
"Establish static routes\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 interface name\n"
"Set tag for this route\n"
"One or more labels separated by '/'\n")
{
int idx_ipv6_prefixlen = 3;
- int idx_ipv6 = 4;
- int idx_interface = 5;
- int idx_curr = 6;
- char *tag, *distance, *vrf;
+ int idx_ipv6;
+ int idx_interface;
+ int idx_curr;
+ 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;
zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
return static_ipv6_func (vty, 0,
argv[idx_ipv6_prefixlen]->arg,
+ src,
argv[idx_ipv6]->arg,
argv[idx_interface]->arg,
NULL,
DEFUN (no_ipv6_route_ifname_flags,
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
IP_STR
"Establish static routes\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 interface name\n"
"Emit an ICMP unreachable when matched\n"
"One or more labels separated by '/'\n")
{
int idx_ipv6_prefixlen = 3;
- int idx_ipv6 = 4;
- int idx_interface = 5;
- int idx_reject_blackhole = 6;
- int idx_curr = 7;
- char *tag, *distance, *vrf;
+ int idx_ipv6;
+ int idx_interface;
+ int idx_reject_blackhole;
+ int idx_curr;
+ 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;
zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL);
return static_ipv6_func (vty, 0,
argv[idx_ipv6_prefixlen]->arg,
+ src,
argv[idx_ipv6]->arg,
argv[idx_interface]->arg,
argv[idx_reject_blackhole]->arg,
struct route_node *rn;
struct static_route *si;
int write = 0;
- char buf[PREFIX_STRLEN];
+ char buf[SRCDEST2STR_BUFFER];
struct route_table *stable;
struct vrf *vrf;
struct zebra_vrf *zvrf;
if ((stable = zvrf->stable[AFI_IP6][SAFI_UNICAST]) == NULL)
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)
{
- 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)
{