#include "zebra/zebra_rnh.h"
#include "zebra/zebra_routemap.h"
+#ifndef VTYSH_EXTRACT_PL
+#include "zebra/zebra_routemap_clippy.c"
+#endif
+
static uint32_t zebra_rmap_update_timer = ZEBRA_RMAP_DEFAULT_UPDATE_TIMER;
static struct thread *zebra_t_rmap_update = NULL;
-char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX + 1]; /* "any" == ZEBRA_ROUTE_MAX */
-/* NH Tracking route map */
-char *nht_rm[AFI_MAX][ZEBRA_ROUTE_MAX + 1]; /* "any" == ZEBRA_ROUTE_MAX */
char *zebra_import_table_routemap[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX];
struct nh_rmap_obj {
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
}
+static void show_vrf_proto_rm(struct vty *vty, struct zebra_vrf *zvrf,
+ int af_type)
+{
+ int i;
+
+ vty_out(vty, "Protocol : route-map\n");
+ vty_out(vty, "------------------------\n");
+
+ for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
+ if (PROTO_RM_NAME(zvrf, af_type, i))
+ vty_out(vty, "%-10s : %-10s\n", zebra_route_string(i),
+ PROTO_RM_NAME(zvrf, af_type, i));
+ else
+ vty_out(vty, "%-10s : none\n", zebra_route_string(i));
+ }
+
+ if (PROTO_RM_NAME(zvrf, af_type, i))
+ vty_out(vty, "%-10s : %-10s\n", "any",
+ PROTO_RM_NAME(zvrf, af_type, i));
+ else
+ vty_out(vty, "%-10s : none\n", "any");
+}
+
+static void show_vrf_nht_rm(struct vty *vty, struct zebra_vrf *zvrf,
+ int af_type)
+{
+ int i;
+
+ vty_out(vty, "Protocol : route-map\n");
+ vty_out(vty, "------------------------\n");
+
+ for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
+ if (NHT_RM_NAME(zvrf, af_type, i))
+ vty_out(vty, "%-10s : %-10s\n", zebra_route_string(i),
+ NHT_RM_NAME(zvrf, af_type, i));
+ else
+ vty_out(vty, "%-10s : none\n", zebra_route_string(i));
+ }
+
+ if (NHT_RM_NAME(zvrf, af_type, i))
+ vty_out(vty, "%-10s : %-10s\n", "any",
+ NHT_RM_NAME(zvrf, af_type, i));
+ else
+ vty_out(vty, "%-10s : none\n", "any");
+}
+
+static int show_proto_rm(struct vty *vty, int af_type, const char *vrf_all,
+ const char *vrf_name)
+{
+ struct zebra_vrf *zvrf;
+
+ if (vrf_all) {
+ struct vrf *vrf;
+
+ RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
+ zvrf = (struct zebra_vrf *)vrf->info;
+ if (zvrf == NULL)
+ continue;
+ vty_out(vty, "VRF: %s\n", zvrf->vrf->name);
+ show_vrf_proto_rm(vty, zvrf, af_type);
+ }
+ } else {
+ vrf_id_t vrf_id = VRF_DEFAULT;
+
+ if (vrf_name)
+ VRF_GET_ID(vrf_id, vrf_name, false);
+
+ zvrf = zebra_vrf_lookup_by_id(vrf_id);
+ if (!zvrf)
+ return CMD_SUCCESS;
+
+ vty_out(vty, "VRF: %s\n", zvrf->vrf->name);
+ show_vrf_proto_rm(vty, zvrf, af_type);
+ }
+
+ return CMD_SUCCESS;
+}
+
+static int show_nht_rm(struct vty *vty, int af_type, const char *vrf_all,
+ const char *vrf_name)
+{
+ struct zebra_vrf *zvrf;
+
+ if (vrf_all) {
+ struct vrf *vrf;
+
+ RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
+ zvrf = (struct zebra_vrf *)vrf->info;
+ if (zvrf == NULL)
+ continue;
+
+ vty_out(vty, "VRF: %s\n", zvrf->vrf->name);
+ show_vrf_nht_rm(vty, zvrf, af_type);
+ }
+ } else {
+ vrf_id_t vrf_id = VRF_DEFAULT;
+
+ if (vrf_name)
+ VRF_GET_ID(vrf_id, vrf_name, false);
+
+ zvrf = zebra_vrf_lookup_by_id(vrf_id);
+ if (!zvrf)
+ return CMD_SUCCESS;
+
+ vty_out(vty, "VRF: %s\n", zvrf->vrf->name);
+ show_vrf_nht_rm(vty, zvrf, af_type);
+ }
+
+ return CMD_SUCCESS;
+}
+
/* Route map commands for interface matching */
struct route_map_rule_cmd route_match_interface_cmd = {
"interface", route_match_interface, route_match_interface_compile,
route_match_interface_free};
+static int ip_protocol_rm_add(struct zebra_vrf *zvrf, const char *rmap,
+ int rtype, afi_t afi, safi_t safi)
+{
+ struct route_table *table;
+
+ if (PROTO_RM_NAME(zvrf, afi, rtype)) {
+ if (strcmp(PROTO_RM_NAME(zvrf, afi, rtype), rmap) == 0)
+ return CMD_SUCCESS;
+
+ XFREE(MTYPE_ROUTE_MAP_NAME, PROTO_RM_NAME(zvrf, afi, rtype));
+ }
+
+ PROTO_RM_NAME(zvrf, afi, rtype) = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
+ PROTO_RM_MAP(zvrf, afi, rtype) =
+ route_map_lookup_by_name(PROTO_RM_NAME(zvrf, afi, rtype));
+
+ if (PROTO_RM_MAP(zvrf, afi, rtype)) {
+
+ if (IS_ZEBRA_DEBUG_RIB_DETAILED)
+ zlog_debug(
+ "%u: IPv4 Routemap config for protocol %d scheduling RIB processing",
+ zvrf->vrf->vrf_id, rtype);
+ /* Process routes of interested address-families. */
+ table = zebra_vrf_table(afi, safi, zvrf->vrf->vrf_id);
+ if (table)
+ rib_update_table(table, RIB_UPDATE_RMAP_CHANGE);
+ }
+
+ return CMD_SUCCESS;
+}
+
+static int ip_protocol_rm_del(struct zebra_vrf *zvrf, const char *rmap,
+ int rtype, afi_t afi, safi_t safi)
+{
+ struct route_table *table;
+
+ if (!PROTO_RM_NAME(zvrf, afi, rtype))
+ return CMD_SUCCESS;
+
+ if (!rmap || strcmp(rmap, PROTO_RM_NAME(zvrf, afi, rtype)) == 0) {
+ if (PROTO_RM_MAP(zvrf, afi, rtype)) {
+ if (IS_ZEBRA_DEBUG_RIB_DETAILED)
+ zlog_debug(
+ "%u: IPv4 Routemap unconfig for protocol %d, scheduling RIB processing",
+ zvrf->vrf->vrf_id, rtype);
+ PROTO_RM_MAP(zvrf, afi, rtype) = NULL;
+
+ /* Process routes of interested address-families. */
+ table = zebra_vrf_table(afi, safi, zvrf->vrf->vrf_id);
+ if (table)
+ rib_update_table(table, RIB_UPDATE_RMAP_CHANGE);
+ }
+ XFREE(MTYPE_ROUTE_MAP_NAME, PROTO_RM_NAME(zvrf, afi, rtype));
+ }
+ return CMD_SUCCESS;
+}
+
+static int ip_nht_rm_add(struct zebra_vrf *zvrf, const char *rmap, int rtype,
+ int afi)
+{
+
+ if (NHT_RM_NAME(zvrf, afi, rtype)) {
+ if (strcmp(NHT_RM_NAME(zvrf, afi, rtype), rmap) == 0)
+ return CMD_SUCCESS;
+
+ XFREE(MTYPE_ROUTE_MAP_NAME, NHT_RM_NAME(zvrf, afi, rtype));
+ }
+
+ NHT_RM_NAME(zvrf, afi, rtype) = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
+ NHT_RM_MAP(zvrf, afi, rtype) =
+ route_map_lookup_by_name(NHT_RM_NAME(zvrf, afi, rtype));
+
+ if (NHT_RM_MAP(zvrf, afi, rtype))
+ zebra_evaluate_rnh(zvrf, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
+
+ return CMD_SUCCESS;
+}
+
+static int ip_nht_rm_del(struct zebra_vrf *zvrf, const char *rmap, int rtype,
+ int afi)
+{
+
+ if (!NHT_RM_NAME(zvrf, afi, rtype))
+ return CMD_SUCCESS;
+
+ if (!rmap || strcmp(rmap, NHT_RM_NAME(zvrf, afi, rtype)) == 0) {
+ if (NHT_RM_MAP(zvrf, afi, rtype)) {
+ if (IS_ZEBRA_DEBUG_RIB_DETAILED)
+ zlog_debug(
+ "%u: IPv4 Routemap unconfig for protocol %d, scheduling RIB processing",
+ zvrf->vrf->vrf_id, rtype);
+ NHT_RM_MAP(zvrf, afi, rtype) = NULL;
+
+ zebra_evaluate_rnh(zvrf, AF_INET, 1, RNH_NEXTHOP_TYPE,
+ NULL);
+ }
+ XFREE(MTYPE_ROUTE_MAP_NAME, NHT_RM_NAME(zvrf, afi, rtype));
+ }
+ return CMD_SUCCESS;
+}
+
DEFUN (match_ip_address_prefix_len,
match_ip_address_prefix_len_cmd,
"match ip address prefix-len (0-32)",
return (CMD_SUCCESS);
}
-
-DEFUN (ip_protocol,
+DEFPY (ip_protocol,
ip_protocol_cmd,
- "ip protocol " FRR_IP_PROTOCOL_MAP_STR_ZEBRA " route-map ROUTE-MAP",
+ "ip protocol " FRR_IP_PROTOCOL_MAP_STR_ZEBRA
+ " $proto route-map ROUTE-MAP$rmap",
IP_STR
"Filter routing info exchanged between zebra and protocol\n"
FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
"Specify route-map\n"
"Route map name\n")
{
- char *proto = argv[2]->text;
- char *rmap = argv[4]->arg;
- int i;
+ int ret, rtype;
+
+ ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
+
+ if (!zvrf)
+ return CMD_WARNING;
if (strcasecmp(proto, "any") == 0)
- i = ZEBRA_ROUTE_MAX;
+ rtype = ZEBRA_ROUTE_MAX;
else
- i = proto_name2num(proto);
- if (i < 0) {
+ rtype = proto_name2num(proto);
+ if (rtype < 0) {
vty_out(vty, "invalid protocol name \"%s\"\n", proto);
return CMD_WARNING_CONFIG_FAILED;
}
- if (proto_rm[AFI_IP][i]) {
- if (strcmp(proto_rm[AFI_IP][i], rmap) == 0)
- return CMD_SUCCESS;
- XFREE(MTYPE_ROUTE_MAP_NAME, proto_rm[AFI_IP][i]);
- }
- proto_rm[AFI_IP][i] = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
+ ret = ip_protocol_rm_add(zvrf, rmap, rtype, AFI_IP, SAFI_UNICAST);
- if (IS_ZEBRA_DEBUG_RIB_DETAILED)
- zlog_debug(
- "%u: IPv4 Routemap config for protocol %s, scheduling RIB processing",
- VRF_DEFAULT, proto);
-
- rib_update(VRF_DEFAULT, RIB_UPDATE_RMAP_CHANGE);
- return CMD_SUCCESS;
+ return ret;
}
-DEFUN (no_ip_protocol,
+DEFPY (no_ip_protocol,
no_ip_protocol_cmd,
- "no ip protocol " FRR_IP_PROTOCOL_MAP_STR_ZEBRA " [route-map ROUTE-MAP]",
+ "no ip protocol " FRR_IP_PROTOCOL_MAP_STR_ZEBRA
+ " $proto [route-map ROUTE-MAP$rmap]",
NO_STR
IP_STR
"Stop filtering routing info between zebra and protocol\n"
FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
- "Specify route map\n"
+ "Specify route-map\n"
"Route map name\n")
{
- char *proto = argv[3]->text;
- char *rmap = (argc == 6) ? argv[5]->arg : NULL;
- int i;
+ int ret, rtype;
+
+ ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
+
+ if (!zvrf)
+ return CMD_WARNING;
if (strcasecmp(proto, "any") == 0)
- i = ZEBRA_ROUTE_MAX;
+ rtype = ZEBRA_ROUTE_MAX;
else
- i = proto_name2num(proto);
-
- if (i < 0) {
+ rtype = proto_name2num(proto);
+ if (rtype < 0) {
vty_out(vty, "invalid protocol name \"%s\"\n", proto);
return CMD_WARNING_CONFIG_FAILED;
}
- if (!proto_rm[AFI_IP][i])
- return CMD_SUCCESS;
+ ret = ip_protocol_rm_del(zvrf, rmap, rtype, AFI_IP, SAFI_UNICAST);
- if (!rmap || strcmp(rmap, proto_rm[AFI_IP][i]) == 0) {
- XFREE(MTYPE_ROUTE_MAP_NAME, proto_rm[AFI_IP][i]);
- proto_rm[AFI_IP][i] = NULL;
-
- if (IS_ZEBRA_DEBUG_RIB_DETAILED)
- zlog_debug(
- "%u: IPv4 Routemap unconfig for protocol %s, scheduling RIB processing",
- VRF_DEFAULT, proto);
- rib_update(VRF_DEFAULT, RIB_UPDATE_RMAP_CHANGE);
- }
- return CMD_SUCCESS;
+ return ret;
}
-DEFUN (show_ip_protocol,
+DEFPY (show_ip_protocol,
show_ip_protocol_cmd,
- "show ip protocol",
- SHOW_STR
- IP_STR
- "IP protocol filtering status\n")
+ "show ip protocol [vrf <NAME$vrf_name|all$vrf_all>]",
+ SHOW_STR
+ IP_STR
+ "IP protocol filtering status\n"
+ VRF_FULL_CMD_HELP_STR)
{
- int i;
-
- vty_out(vty, "Protocol : route-map \n");
- vty_out(vty, "------------------------\n");
- for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
- if (proto_rm[AFI_IP][i])
- vty_out(vty, "%-10s : %-10s\n", zebra_route_string(i),
- proto_rm[AFI_IP][i]);
- else
- vty_out(vty, "%-10s : none\n", zebra_route_string(i));
- }
- if (proto_rm[AFI_IP][i])
- vty_out(vty, "%-10s : %-10s\n", "any", proto_rm[AFI_IP][i]);
- else
- vty_out(vty, "%-10s : none\n", "any");
+ int ret = show_proto_rm(vty, AFI_IP, vrf_all, vrf_name);
- return CMD_SUCCESS;
+ return ret;
}
-DEFUN (ipv6_protocol,
+DEFPY (ipv6_protocol,
ipv6_protocol_cmd,
- "ipv6 protocol " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA " route-map ROUTE-MAP",
+ "ipv6 protocol " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA
+ " $proto route-map ROUTE-MAP$rmap",
IP6_STR
"Filter IPv6 routing info exchanged between zebra and protocol\n"
FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
- "Specify route map\n"
+ "Specify route-map\n"
"Route map name\n")
{
- char *proto = argv[2]->text;
- char *rmap = argv[4]->arg;
- int i;
+ int ret, rtype;
+
+ ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
+
+ if (!zvrf)
+ return CMD_WARNING;
if (strcasecmp(proto, "any") == 0)
- i = ZEBRA_ROUTE_MAX;
+ rtype = ZEBRA_ROUTE_MAX;
else
- i = proto_name2num(proto);
- if (i < 0) {
+ rtype = proto_name2num(proto);
+ if (rtype < 0) {
vty_out(vty, "invalid protocol name \"%s\"\n", proto);
return CMD_WARNING_CONFIG_FAILED;
}
- if (proto_rm[AFI_IP6][i]) {
- if (strcmp(proto_rm[AFI_IP6][i], rmap) == 0)
- return CMD_SUCCESS;
-
- XFREE(MTYPE_ROUTE_MAP_NAME, proto_rm[AFI_IP6][i]);
- }
- proto_rm[AFI_IP6][i] = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
- if (IS_ZEBRA_DEBUG_RIB_DETAILED)
- zlog_debug(
- "%u: IPv6 Routemap config for protocol %s, scheduling RIB processing",
- VRF_DEFAULT, proto);
+ ret = ip_protocol_rm_add(zvrf, rmap, rtype, AFI_IP6, SAFI_UNICAST);
- rib_update(VRF_DEFAULT, RIB_UPDATE_RMAP_CHANGE);
- return CMD_SUCCESS;
+ return ret;
}
-DEFUN (no_ipv6_protocol,
+DEFPY (no_ipv6_protocol,
no_ipv6_protocol_cmd,
- "no ipv6 protocol " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA " [route-map ROUTE-MAP]",
+ "no ipv6 protocol " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA
+ " $proto [route-map ROUTE-MAP$rmap]",
NO_STR
IP6_STR
"Stop filtering IPv6 routing info between zebra and protocol\n"
FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
- "Specify route map\n"
+ "Specify route-map\n"
"Route map name\n")
{
- const char *proto = argv[3]->text;
- const char *rmap = (argc == 6) ? argv[5]->arg : NULL;
- int i;
+ int ret, rtype;
+
+ ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
+
+ if (!zvrf)
+ return CMD_WARNING;
if (strcasecmp(proto, "any") == 0)
- i = ZEBRA_ROUTE_MAX;
+ rtype = ZEBRA_ROUTE_MAX;
else
- i = proto_name2num(proto);
- if (i < 0) {
+ rtype = proto_name2num(proto);
+ if (rtype < 0) {
vty_out(vty, "invalid protocol name \"%s\"\n", proto);
return CMD_WARNING_CONFIG_FAILED;
}
- if (!proto_rm[AFI_IP6][i])
- return CMD_SUCCESS;
- if (!rmap || strcmp(rmap, proto_rm[AFI_IP6][i]) == 0) {
- XFREE(MTYPE_ROUTE_MAP_NAME, proto_rm[AFI_IP6][i]);
- proto_rm[AFI_IP6][i] = NULL;
-
- if (IS_ZEBRA_DEBUG_RIB_DETAILED)
- zlog_debug(
- "%u: IPv6 Routemap unconfig for protocol %s, scheduling RIB processing",
- VRF_DEFAULT, proto);
+ ret = ip_protocol_rm_del(zvrf, rmap, rtype, AFI_IP6, SAFI_UNICAST);
- rib_update(VRF_DEFAULT, RIB_UPDATE_RMAP_CHANGE);
- }
- return CMD_SUCCESS;
+ return ret;
}
-DEFUN (show_ipv6_protocol,
+DEFPY (show_ipv6_protocol,
show_ipv6_protocol_cmd,
- "show ipv6 protocol",
- SHOW_STR
- IP6_STR
- "IPv6 protocol filtering status\n")
+ "show ipv6 protocol [vrf <NAME$vrf_name|all$vrf_all>]",
+ SHOW_STR
+ IP6_STR
+ "IPv6 protocol filtering status\n"
+ VRF_FULL_CMD_HELP_STR)
{
- int i;
+ int ret = show_proto_rm(vty, AFI_IP6, vrf_all, vrf_name);
- vty_out(vty, "Protocol : route-map \n");
- vty_out(vty, "------------------------\n");
- for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
- if (proto_rm[AFI_IP6][i])
- vty_out(vty, "%-10s : %-10s\n", zebra_route_string(i),
- proto_rm[AFI_IP6][i]);
- else
- vty_out(vty, "%-10s : none\n", zebra_route_string(i));
- }
- if (proto_rm[AFI_IP6][i])
- vty_out(vty, "%-10s : %-10s\n", "any", proto_rm[AFI_IP6][i]);
- else
- vty_out(vty, "%-10s : none\n", "any");
-
- return CMD_SUCCESS;
+ return ret;
}
-DEFUN (ip_protocol_nht_rmap,
+DEFPY (ip_protocol_nht_rmap,
ip_protocol_nht_rmap_cmd,
- "ip nht " FRR_IP_PROTOCOL_MAP_STR_ZEBRA " route-map ROUTE-MAP",
+ "ip nht " FRR_IP_PROTOCOL_MAP_STR_ZEBRA
+ " $proto route-map ROUTE-MAP$rmap",
IP_STR
"Filter Next Hop tracking route resolution\n"
FRR_IP_PROTOCOL_MAP_HELP_STR_ZEBRA
"Specify route map\n"
"Route map name\n")
{
- char *proto = argv[2]->text;
- char *rmap = argv[4]->arg;
- int i;
+
+ int ret, rtype;
+
+ ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
+
+ if (!zvrf)
+ return CMD_WARNING;
if (strcasecmp(proto, "any") == 0)
- i = ZEBRA_ROUTE_MAX;
+ rtype = ZEBRA_ROUTE_MAX;
else
- i = proto_name2num(proto);
- if (i < 0) {
+ rtype = proto_name2num(proto);
+ if (rtype < 0) {
vty_out(vty, "invalid protocol name \"%s\"\n", proto);
return CMD_WARNING_CONFIG_FAILED;
}
- if (nht_rm[AFI_IP][i]) {
- if (strcmp(nht_rm[AFI_IP][i], rmap) == 0)
- return CMD_SUCCESS;
-
- XFREE(MTYPE_ROUTE_MAP_NAME, nht_rm[AFI_IP][i]);
- }
- nht_rm[AFI_IP][i] = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
- zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
+ ret = ip_nht_rm_add(zvrf, rmap, rtype, AFI_IP);
- return CMD_SUCCESS;
+ return ret;
}
-DEFUN (no_ip_protocol_nht_rmap,
+DEFPY (no_ip_protocol_nht_rmap,
no_ip_protocol_nht_rmap_cmd,
- "no ip nht " FRR_IP_PROTOCOL_MAP_STR_ZEBRA " [route-map ROUTE-MAP]",
+ "no ip nht " FRR_IP_PROTOCOL_MAP_STR_ZEBRA
+ " $proto route-map [ROUTE-MAP$rmap]",
NO_STR
IP_STR
"Filter Next Hop tracking route resolution\n"
"Specify route map\n"
"Route map name\n")
{
- int idx = 0;
- char *proto = argv[3]->text;
- char *rmap = argv_find(argv, argc, "ROUTE-MAP", &idx) ? argv[idx]->arg
- : NULL;
+ int ret, rtype;
- int i = strmatch(proto, "any") ? ZEBRA_ROUTE_MAX
- : proto_name2num(proto);
+ ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
- if (i < 0) {
+ if (!zvrf)
+ return CMD_WARNING;
+
+ if (strcasecmp(proto, "any") == 0)
+ rtype = ZEBRA_ROUTE_MAX;
+ else
+ rtype = proto_name2num(proto);
+ if (rtype < 0) {
vty_out(vty, "invalid protocol name \"%s\"\n", proto);
return CMD_WARNING_CONFIG_FAILED;
}
- if (!nht_rm[AFI_IP][i])
- return CMD_SUCCESS;
+ ret = ip_nht_rm_del(zvrf, rmap, rtype, AFI_IP);
- if (!rmap || strcmp(rmap, nht_rm[AFI_IP][i]) == 0) {
- XFREE(MTYPE_ROUTE_MAP_NAME, nht_rm[AFI_IP][i]);
- nht_rm[AFI_IP][i] = NULL;
- zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
- }
- return CMD_SUCCESS;
+ return ret;
}
-DEFUN (show_ip_protocol_nht,
+DEFPY (show_ip_protocol_nht,
show_ip_protocol_nht_cmd,
- "show ip nht route-map",
+ "show ip nht route-map [vrf <NAME$vrf_name|all$vrf_all>]",
SHOW_STR
IP_STR
"IP nexthop tracking table\n"
- "IP Next Hop tracking filtering status\n")
+ "IP Next Hop tracking filtering status\n"
+ VRF_FULL_CMD_HELP_STR)
{
- int i;
+ int ret = show_nht_rm(vty, AFI_IP, vrf_all, vrf_name);
- vty_out(vty, "Protocol : route-map \n");
- vty_out(vty, "------------------------\n");
- for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
- if (nht_rm[AFI_IP][i])
- vty_out(vty, "%-10s : %-10s\n", zebra_route_string(i),
- nht_rm[AFI_IP][i]);
- else
- vty_out(vty, "%-10s : none\n", zebra_route_string(i));
- }
- if (nht_rm[AFI_IP][i])
- vty_out(vty, "%-10s : %-10s\n", "any", nht_rm[AFI_IP][i]);
- else
- vty_out(vty, "%-10s : none\n", "any");
-
- return CMD_SUCCESS;
+ return ret;
}
-DEFUN (ipv6_protocol_nht_rmap,
+DEFPY (ipv6_protocol_nht_rmap,
ipv6_protocol_nht_rmap_cmd,
- "ipv6 nht " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA " route-map ROUTE-MAP",
+ "ipv6 nht " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA
+ " $proto route-map ROUTE-MAP$rmap",
IP6_STR
"Filter Next Hop tracking route resolution\n"
FRR_IP6_PROTOCOL_MAP_HELP_STR_ZEBRA
"Specify route map\n"
"Route map name\n")
{
- char *proto = argv[2]->text;
- char *rmap = argv[4]->arg;
- int i;
+ int ret, rtype;
+
+ ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
+
+ if (!zvrf)
+ return CMD_WARNING;
if (strcasecmp(proto, "any") == 0)
- i = ZEBRA_ROUTE_MAX;
+ rtype = ZEBRA_ROUTE_MAX;
else
- i = proto_name2num(proto);
- if (i < 0) {
+ rtype = proto_name2num(proto);
+ if (rtype < 0) {
vty_out(vty, "invalid protocol name \"%s\"\n", proto);
return CMD_WARNING_CONFIG_FAILED;
}
- if (nht_rm[AFI_IP6][i])
- XFREE(MTYPE_ROUTE_MAP_NAME, nht_rm[AFI_IP6][i]);
- nht_rm[AFI_IP6][i] = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
- zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
- return CMD_SUCCESS;
+ ret = ip_nht_rm_add(zvrf, rmap, rtype, AFI_IP6);
+
+ return ret;
}
-DEFUN (no_ipv6_protocol_nht_rmap,
+DEFPY (no_ipv6_protocol_nht_rmap,
no_ipv6_protocol_nht_rmap_cmd,
- "no ipv6 nht " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA " [route-map ROUTE-MAP]",
+ "no ipv6 nht " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA
+ " $proto [route-map ROUTE-MAP$rmap]",
NO_STR
IP6_STR
"Filter Next Hop tracking route resolution\n"
"Specify route map\n"
"Route map name\n")
{
- char *proto = argv[3]->text;
- char *rmap = (argc == 6) ? argv[5]->arg : NULL;
- int i;
+ int ret, rtype;
+
+ ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
+
+ if (!zvrf)
+ return CMD_WARNING;
if (strcasecmp(proto, "any") == 0)
- i = ZEBRA_ROUTE_MAX;
+ rtype = ZEBRA_ROUTE_MAX;
else
- i = proto_name2num(proto);
- if (i < 0) {
+ rtype = proto_name2num(proto);
+ if (rtype < 0) {
vty_out(vty, "invalid protocol name \"%s\"\n", proto);
return CMD_WARNING_CONFIG_FAILED;
}
- if (nht_rm[AFI_IP6][i] && rmap && strcmp(rmap, nht_rm[AFI_IP6][i])) {
- vty_out(vty, "invalid route-map \"%s\"\n", rmap);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- if (nht_rm[AFI_IP6][i]) {
- XFREE(MTYPE_ROUTE_MAP_NAME, nht_rm[AFI_IP6][i]);
- nht_rm[AFI_IP6][i] = NULL;
- }
-
- zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
+ ret = ip_nht_rm_del(zvrf, rmap, rtype, AFI_IP6);
- return CMD_SUCCESS;
+ return ret;
}
-DEFUN (show_ipv6_protocol_nht,
+DEFPY (show_ipv6_protocol_nht,
show_ipv6_protocol_nht_cmd,
- "show ipv6 nht route-map",
+ "show ipv6 nht route-map [vrf <NAME$vrf_name|all$vrf_all>]",
SHOW_STR
IP6_STR
"Next Hop filtering status\n"
- "Route-map\n")
+ "Route-map\n"
+ VRF_FULL_CMD_HELP_STR)
{
- int i;
+ int ret = show_nht_rm(vty, AFI_IP6, vrf_all, vrf_name);
- vty_out(vty, "Protocol : route-map \n");
- vty_out(vty, "------------------------\n");
- for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
- if (nht_rm[AFI_IP6][i])
- vty_out(vty, "%-10s : %-10s\n", zebra_route_string(i),
- nht_rm[AFI_IP6][i]);
- else
- vty_out(vty, "%-10s : none\n", zebra_route_string(i));
- }
- if (nht_rm[AFI_IP][i])
- vty_out(vty, "%-10s : %-10s\n", "any", nht_rm[AFI_IP6][i]);
- else
- vty_out(vty, "%-10s : none\n", "any");
-
- return CMD_SUCCESS;
+ return ret;
}
/*XXXXXXXXXXXXXXXXXXXXXXXXXXXX*/
/* Match function should return 1 if match is success else return
zero. */
-static route_map_result_t route_match_ip_address(void *rule,
- const struct prefix *prefix,
- route_map_object_t type,
- void *object)
+static route_map_result_t route_match_address(afi_t afi, void *rule,
+ const struct prefix *prefix,
+ route_map_object_t type,
+ void *object)
{
struct access_list *alist;
if (type == RMAP_ZEBRA) {
- alist = access_list_lookup(AFI_IP, (char *)rule);
+ alist = access_list_lookup(afi, (char *)rule);
if (alist == NULL)
return RMAP_NOMATCH;
return RMAP_NOMATCH;
}
+static route_map_result_t route_match_ip_address(void *rule,
+ const struct prefix *prefix,
+ route_map_object_t type,
+ void *object)
+{
+ return route_match_address(AFI_IP, rule, prefix, type, object);
+}
+
+static route_map_result_t route_match_ipv6_address(void *rule,
+ const struct prefix *prefix,
+ route_map_object_t type,
+ void *object)
+
+{
+ return route_match_address(AFI_IP6, rule, prefix, type, object);
+}
+
/* Route map `ip address' match statement. `arg' should be
access-list name. */
-static void *route_match_ip_address_compile(const char *arg)
+static void *route_match_address_compile(const char *arg)
{
return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
}
/* Free route map's compiled `ip address' value. */
-static void route_match_ip_address_free(void *rule)
+static void route_match_address_free(void *rule)
{
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
}
/* Route map commands for ip address matching. */
static struct route_map_rule_cmd route_match_ip_address_cmd = {
- "ip address", route_match_ip_address, route_match_ip_address_compile,
- route_match_ip_address_free};
+ "ip address", route_match_ip_address, route_match_address_compile,
+ route_match_address_free};
+
+/* Route map commands for ipv6 address matching. */
+static struct route_map_rule_cmd route_match_ipv6_address_cmd = {
+ "ipv6 address", route_match_ipv6_address, route_match_address_compile,
+ route_match_address_free};
/* `match ip address prefix-list PREFIX_LIST' */
static route_map_result_t
-route_match_ip_address_prefix_list(void *rule, const struct prefix *prefix,
- route_map_object_t type, void *object)
+route_match_address_prefix_list(void *rule, const struct prefix *prefix,
+ route_map_object_t type, void *object, afi_t afi)
{
struct prefix_list *plist;
if (type == RMAP_ZEBRA) {
- plist = prefix_list_lookup(AFI_IP, (char *)rule);
+ plist = prefix_list_lookup(afi, (char *)rule);
if (plist == NULL)
return RMAP_NOMATCH;
return RMAP_NOMATCH;
}
-static void *route_match_ip_address_prefix_list_compile(const char *arg)
+static route_map_result_t
+route_match_ip_address_prefix_list(void *rule, const struct prefix *prefix,
+ route_map_object_t type, void *object)
+{
+ return (route_match_address_prefix_list(rule, prefix, type, object,
+ AFI_IP));
+}
+
+static void *route_match_address_prefix_list_compile(const char *arg)
{
return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
}
-static void route_match_ip_address_prefix_list_free(void *rule)
+static void route_match_address_prefix_list_free(void *rule)
{
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
}
static struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd = {
"ip address prefix-list", route_match_ip_address_prefix_list,
- route_match_ip_address_prefix_list_compile,
- route_match_ip_address_prefix_list_free};
+ route_match_address_prefix_list_compile,
+ route_match_address_prefix_list_free};
+static route_map_result_t
+route_match_ipv6_address_prefix_list(void *rule, const struct prefix *prefix,
+ route_map_object_t type, void *object)
+{
+ return (route_match_address_prefix_list(rule, prefix, type, object,
+ AFI_IP6));
+}
+
+static struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd = {
+ "ipv6 address prefix-list", route_match_ipv6_address_prefix_list,
+ route_match_address_prefix_list_compile,
+ route_match_address_prefix_list_free};
/* `match ip address prefix-len PREFIXLEN' */
"src", route_set_src, route_set_src_compile, route_set_src_free,
};
+/* The function checks if the changed routemap specified by parameter rmap
+ * matches the configured protocol routemaps in proto_rm table. If there is
+ * a match then rib_update_table() to process the routes.
+ */
+static void zebra_rib_table_rm_update(const char *rmap)
+{
+ int i = 0;
+ struct route_table *table;
+ struct vrf *vrf = NULL;
+ struct zebra_vrf *zvrf = NULL;
+ char *rmap_name;
+ char afi_ip = 0;
+ char afi_ipv6 = 0;
+
+ RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
+ zvrf = vrf->info;
+ if (!zvrf)
+ continue;
+ for (i = 0; i <= ZEBRA_ROUTE_MAX; i++) {
+ rmap_name = PROTO_RM_NAME(zvrf, AFI_IP, i);
+ if (rmap_name && (strcmp(rmap_name, rmap) == 0)) {
+ if (IS_ZEBRA_DEBUG_EVENT)
+ zlog_debug(
+ "%s : AFI_IP rmap %s, route type %s",
+ __func__, rmap,
+ zebra_route_string(i));
+
+ PROTO_RM_MAP(zvrf, AFI_IP, i) =
+ route_map_lookup_by_name(rmap_name);
+ /* There is single rib table for all protocols
+ */
+ if (afi_ip == 0) {
+ table = zvrf->table[AFI_IP]
+ [SAFI_UNICAST];
+ if (table) {
+
+ afi_ip = 1;
+ rib_update_table(
+ table,
+ RIB_UPDATE_RMAP_CHANGE);
+ }
+ }
+ }
+ rmap_name = PROTO_RM_NAME(zvrf, AFI_IP6, i);
+ if (rmap_name && (strcmp(rmap_name, rmap) == 0)) {
+ if (IS_ZEBRA_DEBUG_EVENT)
+ zlog_debug(
+ "%s : AFI_IP6 rmap %s, route type %s",
+ __func__, rmap,
+ zebra_route_string(i));
+
+ PROTO_RM_MAP(zvrf, AFI_IP6, i) =
+ route_map_lookup_by_name(rmap_name);
+ /* There is single rib table for all protocols
+ */
+ if (afi_ipv6 == 0) {
+ table = zvrf->table[AFI_IP6]
+ [SAFI_UNICAST];
+ if (table) {
+
+ afi_ipv6 = 1;
+ rib_update_table(
+ table,
+ RIB_UPDATE_RMAP_CHANGE);
+ }
+ }
+ }
+ }
+ }
+}
+
+/* The function checks if the changed routemap specified by parameter rmap
+ * matches the configured protocol routemaps in nht_rm table. If there is
+ * a match then zebra_evaluate_rnh() to process the nexthops.
+ */
+static void zebra_nht_rm_update(const char *rmap)
+{
+ int i = 0;
+ struct route_table *table;
+ struct vrf *vrf = NULL;
+ struct zebra_vrf *zvrf = NULL;
+ char *rmap_name;
+ char afi_ip = 0;
+ char afi_ipv6 = 0;
+
+ RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
+ zvrf = vrf->info;
+ if (!zvrf)
+ continue;
+ for (i = 0; i <= ZEBRA_ROUTE_MAX; i++) {
+ rmap_name = NHT_RM_NAME(zvrf, AFI_IP, i);
+ if (rmap_name && (strcmp(rmap_name, rmap) == 0)) {
+ if (IS_ZEBRA_DEBUG_EVENT)
+ zlog_debug(
+ "%s : AFI_IP rmap %s, route type %s",
+ __func__, rmap,
+ zebra_route_string(i));
+
+ NHT_RM_MAP(zvrf, AFI_IP, i) =
+ route_map_lookup_by_name(rmap_name);
+ /* There is single rib table for all protocols
+ */
+ if (afi_ip == 0) {
+ table = zvrf->table[AFI_IP]
+ [SAFI_UNICAST];
+ if (table) {
+
+ afi_ip = 1;
+
+ zebra_evaluate_rnh(
+ zvrf, AF_INET, 1,
+ RNH_NEXTHOP_TYPE, NULL);
+ }
+ }
+ }
+
+ rmap_name = NHT_RM_NAME(zvrf, AFI_IP6, i);
+ if (rmap_name && (strcmp(rmap_name, rmap) == 0)) {
+ if (IS_ZEBRA_DEBUG_EVENT)
+ zlog_debug(
+ "%s : AFI_IP6 rmap %s, route type %s",
+ __func__, rmap,
+ zebra_route_string(i));
+
+ NHT_RM_MAP(zvrf, AFI_IP6, i) =
+ route_map_lookup_by_name(rmap_name);
+ /* There is single rib table for all protocols
+ */
+ if (afi_ipv6 == 0) {
+ table = zvrf->table[AFI_IP6]
+ [SAFI_UNICAST];
+ if (table) {
+
+ afi_ipv6 = 1;
+
+ zebra_evaluate_rnh(
+ zvrf, AF_INET, 1,
+ RNH_NEXTHOP_TYPE, NULL);
+ }
+ }
+ }
+ }
+ }
+}
+
static void zebra_route_map_process_update_cb(char *rmap_name)
{
if (IS_ZEBRA_DEBUG_EVENT)
zlog_debug("Event handler for route-map: %s",
rmap_name);
+ zebra_import_table_rm_update(rmap_name);
+ zebra_rib_table_rm_update(rmap_name);
+ zebra_nht_rm_update(rmap_name);
}
static int zebra_route_map_update_timer(struct thread *thread)
* 1) VRF Aware <sigh>
* 2) Route-map aware
*/
- zebra_import_table_rm_update();
- rib_update(VRF_DEFAULT, RIB_UPDATE_RMAP_CHANGE);
- zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
- zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
-
return (0);
}
return;
}
-route_map_result_t zebra_route_map_check(int family, int rib_type,
- uint8_t instance,
- const struct prefix *p,
- struct nexthop *nexthop,
- vrf_id_t vrf_id, route_tag_t tag)
+route_map_result_t
+zebra_route_map_check(int family, int rib_type, uint8_t instance,
+ const struct prefix *p, struct nexthop *nexthop,
+ struct zebra_vrf *zvrf, route_tag_t tag)
{
struct route_map *rmap = NULL;
route_map_result_t ret = RMAP_MATCH;
struct nh_rmap_obj nh_obj;
nh_obj.nexthop = nexthop;
- nh_obj.vrf_id = vrf_id;
+ nh_obj.vrf_id = nexthop->vrf_id;
nh_obj.source_protocol = rib_type;
nh_obj.instance = instance;
nh_obj.metric = 0;
nh_obj.tag = tag;
if (rib_type >= 0 && rib_type < ZEBRA_ROUTE_MAX)
- rmap = route_map_lookup_by_name(proto_rm[family][rib_type]);
- if (!rmap && proto_rm[family][ZEBRA_ROUTE_MAX])
- rmap = route_map_lookup_by_name(
- proto_rm[family][ZEBRA_ROUTE_MAX]);
+ rmap = PROTO_RM_MAP(zvrf, family, rib_type);
+ if (!rmap && PROTO_RM_NAME(zvrf, family, ZEBRA_ROUTE_MAX))
+ rmap = PROTO_RM_MAP(zvrf, family, ZEBRA_ROUTE_MAX);
if (rmap) {
ret = route_map_apply(rmap, p, RMAP_ZEBRA, &nh_obj);
}
route_map_result_t zebra_nht_route_map_check(int family, int client_proto,
const struct prefix *p,
+ struct zebra_vrf *zvrf,
struct route_entry *re,
struct nexthop *nexthop)
{
nh_obj.tag = re->tag;
if (client_proto >= 0 && client_proto < ZEBRA_ROUTE_MAX)
- rmap = route_map_lookup_by_name(nht_rm[family][client_proto]);
- if (!rmap && nht_rm[family][ZEBRA_ROUTE_MAX])
- rmap = route_map_lookup_by_name(
- nht_rm[family][ZEBRA_ROUTE_MAX]);
+ rmap = NHT_RM_MAP(zvrf, family, client_proto);
+ if (!rmap && NHT_RM_MAP(zvrf, family, ZEBRA_ROUTE_MAX))
+ rmap = NHT_RM_MAP(zvrf, family, ZEBRA_ROUTE_MAX);
if (rmap)
ret = route_map_apply(rmap, p, RMAP_ZEBRA, &nh_obj);
}
/* ip protocol configuration write function */
-void zebra_routemap_config_write_protocol(struct vty *vty)
+void zebra_routemap_config_write_protocol(struct vty *vty,
+ struct zebra_vrf *zvrf)
{
int i;
+ char space[2];
- for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
- if (proto_rm[AFI_IP][i])
- vty_out(vty, "ip protocol %s route-map %s\n",
- zebra_route_string(i), proto_rm[AFI_IP][i]);
+ memset(space, 0, sizeof(space));
- if (proto_rm[AFI_IP6][i])
- vty_out(vty, "ipv6 protocol %s route-map %s\n",
- zebra_route_string(i), proto_rm[AFI_IP6][i]);
+ if (zvrf_id(zvrf) != VRF_DEFAULT)
+ sprintf(space, "%s", " ");
- if (nht_rm[AFI_IP][i])
- vty_out(vty, "ip nht %s route-map %s\n",
- zebra_route_string(i), nht_rm[AFI_IP][i]);
-
- if (nht_rm[AFI_IP6][i])
- vty_out(vty, "ipv6 nht %s route-map %s\n",
- zebra_route_string(i), nht_rm[AFI_IP6][i]);
+ for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
+ if (PROTO_RM_NAME(zvrf, AFI_IP, i))
+ vty_out(vty, "%sip protocol %s route-map %s\n", space,
+ zebra_route_string(i),
+ PROTO_RM_NAME(zvrf, AFI_IP, i));
+
+ if (PROTO_RM_NAME(zvrf, AFI_IP6, i))
+ vty_out(vty, "%sipv6 protocol %s route-map %s\n", space,
+ zebra_route_string(i),
+ PROTO_RM_NAME(zvrf, AFI_IP6, i));
+
+ if (NHT_RM_NAME(zvrf, AFI_IP, i))
+ vty_out(vty, "%sip nht %s route-map %s\n", space,
+ zebra_route_string(i),
+ NHT_RM_NAME(zvrf, AFI_IP, i));
+
+ if (NHT_RM_NAME(zvrf, AFI_IP6, i))
+ vty_out(vty, "%sipv6 nht %s route-map %s\n", space,
+ zebra_route_string(i),
+ NHT_RM_NAME(zvrf, AFI_IP6, i));
}
- if (proto_rm[AFI_IP][ZEBRA_ROUTE_MAX])
- vty_out(vty, "ip protocol %s route-map %s\n", "any",
- proto_rm[AFI_IP][ZEBRA_ROUTE_MAX]);
+ if (PROTO_RM_NAME(zvrf, AFI_IP, ZEBRA_ROUTE_MAX))
+ vty_out(vty, "%sip protocol %s route-map %s\n", space, "any",
+ PROTO_RM_NAME(zvrf, AFI_IP, ZEBRA_ROUTE_MAX));
- if (proto_rm[AFI_IP6][ZEBRA_ROUTE_MAX])
- vty_out(vty, "ipv6 protocol %s route-map %s\n", "any",
- proto_rm[AFI_IP6][ZEBRA_ROUTE_MAX]);
+ if (PROTO_RM_NAME(zvrf, AFI_IP6, ZEBRA_ROUTE_MAX))
+ vty_out(vty, "%sipv6 protocol %s route-map %s\n", space, "any",
+ PROTO_RM_NAME(zvrf, AFI_IP6, ZEBRA_ROUTE_MAX));
- if (nht_rm[AFI_IP][ZEBRA_ROUTE_MAX])
- vty_out(vty, "ip nht %s route-map %s\n", "any",
- nht_rm[AFI_IP][ZEBRA_ROUTE_MAX]);
+ if (NHT_RM_NAME(zvrf, AFI_IP, ZEBRA_ROUTE_MAX))
+ vty_out(vty, "%sip nht %s route-map %s\n", space, "any",
+ NHT_RM_NAME(zvrf, AFI_IP, ZEBRA_ROUTE_MAX));
- if (nht_rm[AFI_IP6][ZEBRA_ROUTE_MAX])
- vty_out(vty, "ipv6 nht %s route-map %s\n", "any",
- nht_rm[AFI_IP6][ZEBRA_ROUTE_MAX]);
+ if (NHT_RM_NAME(zvrf, AFI_IP6, ZEBRA_ROUTE_MAX))
+ vty_out(vty, "%sipv6 nht %s route-map %s\n", space, "any",
+ NHT_RM_NAME(zvrf, AFI_IP6, ZEBRA_ROUTE_MAX));
if (zebra_rmap_update_timer != ZEBRA_RMAP_DEFAULT_UPDATE_TIMER)
vty_out(vty, "zebra route-map delay-timer %d\n",
{
install_element(CONFIG_NODE, &ip_protocol_cmd);
install_element(CONFIG_NODE, &no_ip_protocol_cmd);
+ install_element(VRF_NODE, &ip_protocol_cmd);
+ install_element(VRF_NODE, &no_ip_protocol_cmd);
install_element(VIEW_NODE, &show_ip_protocol_cmd);
install_element(CONFIG_NODE, &ipv6_protocol_cmd);
install_element(CONFIG_NODE, &no_ipv6_protocol_cmd);
+ install_element(VRF_NODE, &ipv6_protocol_cmd);
+ install_element(VRF_NODE, &no_ipv6_protocol_cmd);
install_element(VIEW_NODE, &show_ipv6_protocol_cmd);
install_element(CONFIG_NODE, &ip_protocol_nht_rmap_cmd);
install_element(CONFIG_NODE, &no_ip_protocol_nht_rmap_cmd);
+ install_element(VRF_NODE, &ip_protocol_nht_rmap_cmd);
+ install_element(VRF_NODE, &no_ip_protocol_nht_rmap_cmd);
install_element(VIEW_NODE, &show_ip_protocol_nht_cmd);
install_element(CONFIG_NODE, &ipv6_protocol_nht_rmap_cmd);
install_element(CONFIG_NODE, &no_ipv6_protocol_nht_rmap_cmd);
+ install_element(VRF_NODE, &ipv6_protocol_nht_rmap_cmd);
+ install_element(VRF_NODE, &no_ipv6_protocol_nht_rmap_cmd);
install_element(VIEW_NODE, &show_ipv6_protocol_nht_cmd);
install_element(CONFIG_NODE, &zebra_route_map_timer_cmd);
install_element(CONFIG_NODE, &no_zebra_route_map_timer_cmd);
route_map_match_tag_hook(generic_match_add);
route_map_no_match_tag_hook(generic_match_delete);
+ route_map_match_ipv6_address_hook(generic_match_add);
+ route_map_no_match_ipv6_address_hook(generic_match_delete);
+
+ route_map_match_ipv6_address_prefix_list_hook(generic_match_add);
+ route_map_no_match_ipv6_address_prefix_list_hook(generic_match_delete);
+
route_map_install_match(&route_match_tag_cmd);
route_map_install_match(&route_match_interface_cmd);
route_map_install_match(&route_match_ip_next_hop_cmd);
route_map_install_match(&route_match_ip_next_hop_prefix_list_cmd);
route_map_install_match(&route_match_ip_address_cmd);
+ route_map_install_match(&route_match_ipv6_address_cmd);
route_map_install_match(&route_match_ip_address_prefix_list_cmd);
+ route_map_install_match(&route_match_ipv6_address_prefix_list_cmd);
route_map_install_match(&route_match_ip_address_prefix_len_cmd);
route_map_install_match(&route_match_ipv6_address_prefix_len_cmd);
route_map_install_match(&route_match_ip_nexthop_prefix_len_cmd);