frr/zebra/zebra_routemap.c

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

1407 lines
36 KiB
C
Raw Normal View History

// SPDX-License-Identifier: GPL-2.0-or-later
/* zebra routemap.
* Copyright (C) 2006 IBM Corporation
*/
#include <zebra.h>
#include "memory.h"
#include "prefix.h"
#include "rib.h"
#include "vty.h"
#include "routemap.h"
#include "command.h"
#include "filter.h"
#include "plist.h"
#include "nexthop.h"
#include "lib/route_types.h"
#include "vrf.h"
#include "frrstr.h"
#include "zebra/zebra_router.h"
#include "zebra/redistribute.h"
#include "zebra/debug.h"
#include "zebra/zebra_rnh.h"
#include "zebra/zebra_routemap.h"
#include "zebra/zebra_vrf.h"
#include "zebra/zebra_routemap_clippy.c"
static uint32_t zebra_rmap_update_timer = ZEBRA_RMAP_DEFAULT_UPDATE_TIMER;
static struct event *zebra_t_rmap_update = NULL;
char *zebra_import_table_routemap[AFI_MAX][SAFI_MAX][ZEBRA_KERNEL_TABLE_MAX];
struct zebra_rmap_obj {
struct nexthop *nexthop;
struct route_entry *re;
};
/* 'match tag TAG'
* Match function return 1 if match is success else return 0
*/
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP Introducing a 3rd state for route_map_apply library function: RMAP_NOOP Traditionally route map MATCH rule apis were designed to return a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH. (Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR). Depending on this response, the following statemachine decided the course of action: State1: If match cmd returns RMAP_MATCH then, keep existing behaviour. If routemap type is PERMIT, execute set cmds or call cmds if applicable, otherwise PERMIT! Else If routemap type is DENY, we DENYMATCH right away State2: If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH We require a 3rd state because of the following situation: The issue - what if, the rule api needs to abort or ignore a rule?: "match evpn vni xx" route-map filter can be applied to incoming routes regardless of whether the tunnel type is vxlan or mpls. This rule should be N/A for mpls based evpn route, but applicable to only vxlan based evpn route. Also, this rule should be applicable for routes with VNI label only, and not for routes without labels. For example, type 3 and type 4 EVPN routes do not have labels, so, this match cmd should let them through. Today, the filter produces either a match or nomatch response regardless of whether it is mpls/vxlan, resulting in either permitting or denying the route.. So an mpls evpn route may get filtered out incorrectly. Eg: "route-map RM1 permit 10 ; match evpn vni 20" or "route-map RM2 deny 20 ; match vni 20" With the introduction of the 3rd state, we can abort this rule check safely. How? The rules api can now return RMAP_NOOP to indicate that it encountered an invalid check, and needs to abort just that rule, but continue with other rules. As a result we have a 3rd state: State3: If match cmd returned RMAP_NOOP Then, proceed to other route-map, otherwise if there are no more rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH. Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
static enum route_map_cmd_result_t
route_match_tag(void *rule, const struct prefix *prefix, void *object)
{
route_tag_t *tag;
struct zebra_rmap_obj *rm_data;
tag = rule;
rm_data = object;
if (rm_data->re->tag == *tag)
return RMAP_MATCH;
return RMAP_NOMATCH;
}
/* Route map commands for tag matching */
static const struct route_map_rule_cmd route_match_tag_cmd = {
"tag",
route_match_tag,
route_map_rule_tag_compile,
route_map_rule_tag_free,
};
/* `match interface IFNAME' */
/* Match function return 1 if match is success else return zero. */
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP Introducing a 3rd state for route_map_apply library function: RMAP_NOOP Traditionally route map MATCH rule apis were designed to return a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH. (Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR). Depending on this response, the following statemachine decided the course of action: State1: If match cmd returns RMAP_MATCH then, keep existing behaviour. If routemap type is PERMIT, execute set cmds or call cmds if applicable, otherwise PERMIT! Else If routemap type is DENY, we DENYMATCH right away State2: If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH We require a 3rd state because of the following situation: The issue - what if, the rule api needs to abort or ignore a rule?: "match evpn vni xx" route-map filter can be applied to incoming routes regardless of whether the tunnel type is vxlan or mpls. This rule should be N/A for mpls based evpn route, but applicable to only vxlan based evpn route. Also, this rule should be applicable for routes with VNI label only, and not for routes without labels. For example, type 3 and type 4 EVPN routes do not have labels, so, this match cmd should let them through. Today, the filter produces either a match or nomatch response regardless of whether it is mpls/vxlan, resulting in either permitting or denying the route.. So an mpls evpn route may get filtered out incorrectly. Eg: "route-map RM1 permit 10 ; match evpn vni 20" or "route-map RM2 deny 20 ; match vni 20" With the introduction of the 3rd state, we can abort this rule check safely. How? The rules api can now return RMAP_NOOP to indicate that it encountered an invalid check, and needs to abort just that rule, but continue with other rules. As a result we have a 3rd state: State3: If match cmd returned RMAP_NOOP Then, proceed to other route-map, otherwise if there are no more rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH. Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
static enum route_map_cmd_result_t
route_match_interface(void *rule, const struct prefix *prefix, void *object)
{
struct zebra_rmap_obj *rm_data;
char *ifname = rule;
ifindex_t ifindex;
if (strcasecmp(ifname, "any") == 0)
return RMAP_MATCH;
rm_data = object;
if (!rm_data || !rm_data->nexthop)
return RMAP_NOMATCH;
ifindex = ifname2ifindex(ifname, rm_data->nexthop->vrf_id);
if (ifindex == 0)
return RMAP_NOMATCH;
if (rm_data->nexthop->ifindex == ifindex)
return RMAP_MATCH;
return RMAP_NOMATCH;
}
/* Route map `match interface' match statement. `arg' is IFNAME value */
static void *route_match_interface_compile(const char *arg)
{
return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
}
/* Free route map's compiled `match interface' value. */
static void route_match_interface_free(void *rule)
{
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, "%-24s : %-10s\n", zebra_route_string(i),
PROTO_RM_NAME(zvrf, af_type, i));
else
vty_out(vty, "%-24s : none\n", zebra_route_string(i));
}
}
static void show_vrf_nht_rm(struct vty *vty, struct zebra_vrf *zvrf,
zebra: json support for show ip nht route-map Changes: JSON support added for below commands, - show ip nht route-map vrf all json - show ip nht route-map vrf <name> json - show ipv6 nht route-map vrf all json - show ipv6 nht route-map vrf <name> json - show ipv6 nht route-map json - show ip nht route-map json Testing Done: Unit testing completed. tor-1# show ip nht route-map vrf default json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ip nht route-map vrf all json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "mgmt":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "sym_1":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ipv6 nht route-map vrf default json { "afi":"ipv6", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"kernel-policy", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } Ticket:#3229016 Issue:3229016 Signed-off-by: Sindhu Parvathi Gopinathan <sgopinathan@nvidia.com>
2022-11-08 06:40:13 +01:00
int af_type, json_object *json)
{
int i;
zebra: json support for show ip nht route-map Changes: JSON support added for below commands, - show ip nht route-map vrf all json - show ip nht route-map vrf <name> json - show ipv6 nht route-map vrf all json - show ipv6 nht route-map vrf <name> json - show ipv6 nht route-map json - show ip nht route-map json Testing Done: Unit testing completed. tor-1# show ip nht route-map vrf default json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ip nht route-map vrf all json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "mgmt":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "sym_1":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ipv6 nht route-map vrf default json { "afi":"ipv6", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"kernel-policy", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } Ticket:#3229016 Issue:3229016 Signed-off-by: Sindhu Parvathi Gopinathan <sgopinathan@nvidia.com>
2022-11-08 06:40:13 +01:00
if (!json) {
vty_out(vty, "Protocol : route-map\n");
vty_out(vty, "-------------------------------------\n");
}
for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
zebra: json support for show ip nht route-map Changes: JSON support added for below commands, - show ip nht route-map vrf all json - show ip nht route-map vrf <name> json - show ipv6 nht route-map vrf all json - show ipv6 nht route-map vrf <name> json - show ipv6 nht route-map json - show ip nht route-map json Testing Done: Unit testing completed. tor-1# show ip nht route-map vrf default json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ip nht route-map vrf all json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "mgmt":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "sym_1":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ipv6 nht route-map vrf default json { "afi":"ipv6", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"kernel-policy", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } Ticket:#3229016 Issue:3229016 Signed-off-by: Sindhu Parvathi Gopinathan <sgopinathan@nvidia.com>
2022-11-08 06:40:13 +01:00
if (json) {
if (NHT_RM_NAME(zvrf, af_type, i))
json_object_string_add(
json, zebra_route_string(i),
NHT_RM_NAME(zvrf, af_type, i));
else
json_object_string_add(
json, zebra_route_string(i), "none");
} else {
if (NHT_RM_NAME(zvrf, af_type, i))
vty_out(vty, "%-24s : %-10s\n",
zebra_route_string(i),
NHT_RM_NAME(zvrf, af_type, i));
else
vty_out(vty, "%-24s : none\n",
zebra_route_string(i));
}
}
if (json) {
if (NHT_RM_NAME(zvrf, af_type, i))
zebra: json support for show ip nht route-map Changes: JSON support added for below commands, - show ip nht route-map vrf all json - show ip nht route-map vrf <name> json - show ipv6 nht route-map vrf all json - show ipv6 nht route-map vrf <name> json - show ipv6 nht route-map json - show ip nht route-map json Testing Done: Unit testing completed. tor-1# show ip nht route-map vrf default json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ip nht route-map vrf all json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "mgmt":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "sym_1":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ipv6 nht route-map vrf default json { "afi":"ipv6", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"kernel-policy", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } Ticket:#3229016 Issue:3229016 Signed-off-by: Sindhu Parvathi Gopinathan <sgopinathan@nvidia.com>
2022-11-08 06:40:13 +01:00
json_object_string_add(json, "any",
NHT_RM_NAME(zvrf, af_type, i));
else
json_object_string_add(json, "any", "none");
} else {
if (NHT_RM_NAME(zvrf, af_type, i))
vty_out(vty, "%-24s : %-10s\n", "any",
NHT_RM_NAME(zvrf, af_type, i));
else
zebra: json support for show ip nht route-map Changes: JSON support added for below commands, - show ip nht route-map vrf all json - show ip nht route-map vrf <name> json - show ipv6 nht route-map vrf all json - show ipv6 nht route-map vrf <name> json - show ipv6 nht route-map json - show ip nht route-map json Testing Done: Unit testing completed. tor-1# show ip nht route-map vrf default json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ip nht route-map vrf all json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "mgmt":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "sym_1":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ipv6 nht route-map vrf default json { "afi":"ipv6", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"kernel-policy", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } Ticket:#3229016 Issue:3229016 Signed-off-by: Sindhu Parvathi Gopinathan <sgopinathan@nvidia.com>
2022-11-08 06:40:13 +01:00
vty_out(vty, "%-24s : 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,
zebra: json support for show ip nht route-map Changes: JSON support added for below commands, - show ip nht route-map vrf all json - show ip nht route-map vrf <name> json - show ipv6 nht route-map vrf all json - show ipv6 nht route-map vrf <name> json - show ipv6 nht route-map json - show ip nht route-map json Testing Done: Unit testing completed. tor-1# show ip nht route-map vrf default json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ip nht route-map vrf all json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "mgmt":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "sym_1":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ipv6 nht route-map vrf default json { "afi":"ipv6", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"kernel-policy", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } Ticket:#3229016 Issue:3229016 Signed-off-by: Sindhu Parvathi Gopinathan <sgopinathan@nvidia.com>
2022-11-08 06:40:13 +01:00
const char *vrf_name, bool use_json)
{
struct zebra_vrf *zvrf;
zebra: json support for show ip nht route-map Changes: JSON support added for below commands, - show ip nht route-map vrf all json - show ip nht route-map vrf <name> json - show ipv6 nht route-map vrf all json - show ipv6 nht route-map vrf <name> json - show ipv6 nht route-map json - show ip nht route-map json Testing Done: Unit testing completed. tor-1# show ip nht route-map vrf default json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ip nht route-map vrf all json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "mgmt":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "sym_1":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ipv6 nht route-map vrf default json { "afi":"ipv6", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"kernel-policy", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } Ticket:#3229016 Issue:3229016 Signed-off-by: Sindhu Parvathi Gopinathan <sgopinathan@nvidia.com>
2022-11-08 06:40:13 +01:00
json_object *json = NULL;
json_object *json_vrfs = NULL;
if (use_json) {
json = json_object_new_object();
json_vrfs = json_object_new_object();
json_object_string_add(json, "afi",
(af_type == AFI_IP) ? "ipv4" : "ipv6");
}
if (vrf_all) {
struct vrf *vrf;
zebra: json support for show ip nht route-map Changes: JSON support added for below commands, - show ip nht route-map vrf all json - show ip nht route-map vrf <name> json - show ipv6 nht route-map vrf all json - show ipv6 nht route-map vrf <name> json - show ipv6 nht route-map json - show ip nht route-map json Testing Done: Unit testing completed. tor-1# show ip nht route-map vrf default json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ip nht route-map vrf all json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "mgmt":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "sym_1":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ipv6 nht route-map vrf default json { "afi":"ipv6", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"kernel-policy", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } Ticket:#3229016 Issue:3229016 Signed-off-by: Sindhu Parvathi Gopinathan <sgopinathan@nvidia.com>
2022-11-08 06:40:13 +01:00
if (use_json)
json_object_object_add(json, "vrfs", json_vrfs);
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
zvrf = (struct zebra_vrf *)vrf->info;
if (zvrf == NULL)
continue;
zebra: json support for show ip nht route-map Changes: JSON support added for below commands, - show ip nht route-map vrf all json - show ip nht route-map vrf <name> json - show ipv6 nht route-map vrf all json - show ipv6 nht route-map vrf <name> json - show ipv6 nht route-map json - show ip nht route-map json Testing Done: Unit testing completed. tor-1# show ip nht route-map vrf default json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ip nht route-map vrf all json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "mgmt":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "sym_1":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ipv6 nht route-map vrf default json { "afi":"ipv6", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"kernel-policy", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } Ticket:#3229016 Issue:3229016 Signed-off-by: Sindhu Parvathi Gopinathan <sgopinathan@nvidia.com>
2022-11-08 06:40:13 +01:00
if (use_json) {
json_object *json_proto = NULL;
json_object *json_vrf = NULL;
json_vrf = json_object_new_object();
json_object_object_add(
json_vrfs, zvrf->vrf->name, json_vrf);
json_proto = json_object_new_object();
json_object_object_add(json_vrf, "protocols",
json_proto);
show_vrf_nht_rm(vty, zvrf, af_type, json_proto);
} else {
vty_out(vty, "VRF: %s\n", zvrf->vrf->name);
show_vrf_nht_rm(vty, zvrf, af_type, NULL);
}
}
} else {
zebra: json support for show ip nht route-map Changes: JSON support added for below commands, - show ip nht route-map vrf all json - show ip nht route-map vrf <name> json - show ipv6 nht route-map vrf all json - show ipv6 nht route-map vrf <name> json - show ipv6 nht route-map json - show ip nht route-map json Testing Done: Unit testing completed. tor-1# show ip nht route-map vrf default json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ip nht route-map vrf all json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "mgmt":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "sym_1":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ipv6 nht route-map vrf default json { "afi":"ipv6", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"kernel-policy", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } Ticket:#3229016 Issue:3229016 Signed-off-by: Sindhu Parvathi Gopinathan <sgopinathan@nvidia.com>
2022-11-08 06:40:13 +01:00
json_object *json_proto = NULL;
json_object *json_vrf = NULL;
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);
zebra: json support for show ip nht route-map Changes: JSON support added for below commands, - show ip nht route-map vrf all json - show ip nht route-map vrf <name> json - show ipv6 nht route-map vrf all json - show ipv6 nht route-map vrf <name> json - show ipv6 nht route-map json - show ip nht route-map json Testing Done: Unit testing completed. tor-1# show ip nht route-map vrf default json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ip nht route-map vrf all json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "mgmt":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "sym_1":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ipv6 nht route-map vrf default json { "afi":"ipv6", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"kernel-policy", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } Ticket:#3229016 Issue:3229016 Signed-off-by: Sindhu Parvathi Gopinathan <sgopinathan@nvidia.com>
2022-11-08 06:40:13 +01:00
if (!zvrf) {
json_object_free(json);
json_object_free(json_vrfs);
return CMD_SUCCESS;
zebra: json support for show ip nht route-map Changes: JSON support added for below commands, - show ip nht route-map vrf all json - show ip nht route-map vrf <name> json - show ipv6 nht route-map vrf all json - show ipv6 nht route-map vrf <name> json - show ipv6 nht route-map json - show ip nht route-map json Testing Done: Unit testing completed. tor-1# show ip nht route-map vrf default json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ip nht route-map vrf all json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "mgmt":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "sym_1":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ipv6 nht route-map vrf default json { "afi":"ipv6", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"kernel-policy", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } Ticket:#3229016 Issue:3229016 Signed-off-by: Sindhu Parvathi Gopinathan <sgopinathan@nvidia.com>
2022-11-08 06:40:13 +01:00
}
zebra: json support for show ip nht route-map Changes: JSON support added for below commands, - show ip nht route-map vrf all json - show ip nht route-map vrf <name> json - show ipv6 nht route-map vrf all json - show ipv6 nht route-map vrf <name> json - show ipv6 nht route-map json - show ip nht route-map json Testing Done: Unit testing completed. tor-1# show ip nht route-map vrf default json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ip nht route-map vrf all json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "mgmt":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "sym_1":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ipv6 nht route-map vrf default json { "afi":"ipv6", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"kernel-policy", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } Ticket:#3229016 Issue:3229016 Signed-off-by: Sindhu Parvathi Gopinathan <sgopinathan@nvidia.com>
2022-11-08 06:40:13 +01:00
if (use_json) {
json_object_object_add(json, "vrfs", json_vrfs);
json_vrf = json_object_new_object();
json_object_object_add(json_vrfs, zvrf->vrf->name,
json_vrf);
json_proto = json_object_new_object();
json_object_object_add(json_vrf, "protocols",
json_proto);
show_vrf_nht_rm(vty, zvrf, af_type, json_proto);
} else {
vty_out(vty, "VRF: %s\n", zvrf->vrf->name);
show_vrf_nht_rm(vty, zvrf, af_type, NULL);
}
}
zebra: json support for show ip nht route-map Changes: JSON support added for below commands, - show ip nht route-map vrf all json - show ip nht route-map vrf <name> json - show ipv6 nht route-map vrf all json - show ipv6 nht route-map vrf <name> json - show ipv6 nht route-map json - show ip nht route-map json Testing Done: Unit testing completed. tor-1# show ip nht route-map vrf default json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ip nht route-map vrf all json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "mgmt":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "sym_1":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ipv6 nht route-map vrf default json { "afi":"ipv6", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"kernel-policy", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } Ticket:#3229016 Issue:3229016 Signed-off-by: Sindhu Parvathi Gopinathan <sgopinathan@nvidia.com>
2022-11-08 06:40:13 +01:00
if (use_json)
vty_json(vty, json);
return CMD_SUCCESS;
}
/* Route map commands for interface matching */
static const struct route_map_rule_cmd route_match_interface_cmd = {
"interface",
route_match_interface,
route_match_interface_compile,
route_match_interface_free
};
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));
}
route_map_counter_decrement(PROTO_RM_MAP(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));
route_map_counter_increment(PROTO_RM_MAP(zvrf, afi, rtype));
zebra: Deny the routes if ip protocol CLI refers to an undefined rmap Currently zebra does not deny the routes if `ip protocol <proto> route-map FOO` commmand is configured with reference to an undefined route-map (FOO in this case). However, on FRR restart, in zebra_route_map_check() routes get denied if route-map name is available but the route-map is not defined. This change was introduced in fd303a4ba14c762550db972317e1e88528768005. Fix: When `ip protocol <proto> route-map FOO` CLI is configured with reference to an undefined route-map FOO, let the processing in ip_protocol_rm_add() and ip_protocol_rm_del() go through so that zebra can deny the routes instead of simply returning. This will result in consistent behavior. Testing Done: Before fix: ``` spine-1# configure spine-1(config)# ip protocol bgp route-map rmap7 root@spine-1:mgmt:/var/home/cumulus# vtysh -c "show run" | grep rmap7 ip protocol bgp route-map rmap7 root@spine-1:mgmt:/var/home/cumulus# spine-1(config)# do show ip route Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP, T - Table, A - Babel, D - SHARP, F - PBR, f - OpenFabric, Z - FRR, > - selected route, * - FIB route, q - queued, r - rejected, b - backup t - trapped, o - offload failure C>* 27.0.0.1/32 is directly connected, lo, 02:27:45 B>* 27.0.0.3/32 [20/0] via fe80::202:ff:fe00:21, downlink_1, weight 1, 02:27:35 B>* 27.0.0.4/32 [20/0] via fe80::202:ff:fe00:29, downlink_2, weight 1, 02:27:40 B>* 27.0.0.5/32 [20/0] via fe80::202:ff:fe00:31, downlink_3, weight 1, 02:27:40 B>* 27.0.0.6/32 [20/0] via fe80::202:ff:fe00:39, downlink_4, weight 1, 02:27:40 ``` After fix: ``` spine-1(config)# ip protocol bgp route-map route-map67 spine-1(config)# do show ip route Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP, T - Table, A - Babel, D - SHARP, F - PBR, f - OpenFabric, Z - FRR, > - selected route, * - FIB route, q - queued, r - rejected, b - backup t - trapped, o - offload failure C>* 27.0.0.1/32 is directly connected, lo, 00:35:03 B 27.0.0.3/32 [20/0] via fe80::202:ff:fe00:21, downlink_1 inactive, weight 1, 00:34:58 B 27.0.0.4/32 [20/0] via fe80::202:ff:fe00:29, downlink_2 inactive, weight 1, 00:34:57 B 27.0.0.5/32 [20/0] via fe80::202:ff:fe00:31, downlink_3 inactive, weight 1, 00:34:57 B 27.0.0.6/32 [20/0] via fe80::202:ff:fe00:39, downlink_4 inactive, weight 1, 00:34:58 spine-1(config)# root@spine-1:mgmt:/var/home/cumulus# ip route show root@spine-1:mgmt:/var/home/cumulus# ``` Signed-off-by: Pooja Jagadeesh Doijode <pdoijode@nvidia.com>
2024-05-17 01:36:18 +02:00
if (PROTO_RM_NAME(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,
rtype);
}
return CMD_SUCCESS;
}
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) {
route_map_counter_decrement(PROTO_RM_MAP(zvrf, afi, rtype));
zebra: Deny the routes if ip protocol CLI refers to an undefined rmap Currently zebra does not deny the routes if `ip protocol <proto> route-map FOO` commmand is configured with reference to an undefined route-map (FOO in this case). However, on FRR restart, in zebra_route_map_check() routes get denied if route-map name is available but the route-map is not defined. This change was introduced in fd303a4ba14c762550db972317e1e88528768005. Fix: When `ip protocol <proto> route-map FOO` CLI is configured with reference to an undefined route-map FOO, let the processing in ip_protocol_rm_add() and ip_protocol_rm_del() go through so that zebra can deny the routes instead of simply returning. This will result in consistent behavior. Testing Done: Before fix: ``` spine-1# configure spine-1(config)# ip protocol bgp route-map rmap7 root@spine-1:mgmt:/var/home/cumulus# vtysh -c "show run" | grep rmap7 ip protocol bgp route-map rmap7 root@spine-1:mgmt:/var/home/cumulus# spine-1(config)# do show ip route Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP, T - Table, A - Babel, D - SHARP, F - PBR, f - OpenFabric, Z - FRR, > - selected route, * - FIB route, q - queued, r - rejected, b - backup t - trapped, o - offload failure C>* 27.0.0.1/32 is directly connected, lo, 02:27:45 B>* 27.0.0.3/32 [20/0] via fe80::202:ff:fe00:21, downlink_1, weight 1, 02:27:35 B>* 27.0.0.4/32 [20/0] via fe80::202:ff:fe00:29, downlink_2, weight 1, 02:27:40 B>* 27.0.0.5/32 [20/0] via fe80::202:ff:fe00:31, downlink_3, weight 1, 02:27:40 B>* 27.0.0.6/32 [20/0] via fe80::202:ff:fe00:39, downlink_4, weight 1, 02:27:40 ``` After fix: ``` spine-1(config)# ip protocol bgp route-map route-map67 spine-1(config)# do show ip route Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP, T - Table, A - Babel, D - SHARP, F - PBR, f - OpenFabric, Z - FRR, > - selected route, * - FIB route, q - queued, r - rejected, b - backup t - trapped, o - offload failure C>* 27.0.0.1/32 is directly connected, lo, 00:35:03 B 27.0.0.3/32 [20/0] via fe80::202:ff:fe00:21, downlink_1 inactive, weight 1, 00:34:58 B 27.0.0.4/32 [20/0] via fe80::202:ff:fe00:29, downlink_2 inactive, weight 1, 00:34:57 B 27.0.0.5/32 [20/0] via fe80::202:ff:fe00:31, downlink_3 inactive, weight 1, 00:34:57 B 27.0.0.6/32 [20/0] via fe80::202:ff:fe00:39, downlink_4 inactive, weight 1, 00:34:58 spine-1(config)# root@spine-1:mgmt:/var/home/cumulus# ip route show root@spine-1:mgmt:/var/home/cumulus# ``` Signed-off-by: Pooja Jagadeesh Doijode <pdoijode@nvidia.com>
2024-05-17 01:36:18 +02:00
if (PROTO_RM_NAME(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,
rtype);
}
XFREE(MTYPE_ROUTE_MAP_NAME, PROTO_RM_NAME(zvrf, afi, rtype));
}
return CMD_SUCCESS;
}
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));
}
route_map_counter_decrement(NHT_RM_MAP(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));
route_map_counter_increment(NHT_RM_MAP(zvrf, afi, rtype));
if (NHT_RM_MAP(zvrf, afi, rtype))
zebra_evaluate_rnh(zvrf, afi, 1, NULL, SAFI_UNICAST);
return CMD_SUCCESS;
}
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) {
route_map_counter_decrement(NHT_RM_MAP(zvrf, afi, rtype));
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, afi, 1, NULL, SAFI_UNICAST);
}
XFREE(MTYPE_ROUTE_MAP_NAME, NHT_RM_NAME(zvrf, afi, rtype));
}
return CMD_SUCCESS;
}
DEFPY (show_ip_protocol,
show_ip_protocol_cmd,
"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 ret = show_proto_rm(vty, AFI_IP, vrf_all, vrf_name);
return ret;
}
DEFPY (show_ipv6_protocol,
show_ipv6_protocol_cmd,
"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 ret = show_proto_rm(vty, AFI_IP6, vrf_all, vrf_name);
return ret;
}
DEFPY (show_ip_protocol_nht,
show_ip_protocol_nht_cmd,
zebra: json support for show ip nht route-map Changes: JSON support added for below commands, - show ip nht route-map vrf all json - show ip nht route-map vrf <name> json - show ipv6 nht route-map vrf all json - show ipv6 nht route-map vrf <name> json - show ipv6 nht route-map json - show ip nht route-map json Testing Done: Unit testing completed. tor-1# show ip nht route-map vrf default json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ip nht route-map vrf all json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "mgmt":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "sym_1":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ipv6 nht route-map vrf default json { "afi":"ipv6", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"kernel-policy", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } Ticket:#3229016 Issue:3229016 Signed-off-by: Sindhu Parvathi Gopinathan <sgopinathan@nvidia.com>
2022-11-08 06:40:13 +01:00
"show ip nht route-map [vrf <NAME$vrf_name|all$vrf_all>] [json]",
SHOW_STR
IP_STR
zebra: json support for show ip nht route-map Changes: JSON support added for below commands, - show ip nht route-map vrf all json - show ip nht route-map vrf <name> json - show ipv6 nht route-map vrf all json - show ipv6 nht route-map vrf <name> json - show ipv6 nht route-map json - show ip nht route-map json Testing Done: Unit testing completed. tor-1# show ip nht route-map vrf default json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ip nht route-map vrf all json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "mgmt":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "sym_1":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ipv6 nht route-map vrf default json { "afi":"ipv6", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"kernel-policy", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } Ticket:#3229016 Issue:3229016 Signed-off-by: Sindhu Parvathi Gopinathan <sgopinathan@nvidia.com>
2022-11-08 06:40:13 +01:00
"IPv4 nexthop tracking table\n"
"IPv4 Next Hop tracking filtering status\n"
VRF_CMD_HELP_STR
"All VRFs\n"
JSON_STR)
{
zebra: json support for show ip nht route-map Changes: JSON support added for below commands, - show ip nht route-map vrf all json - show ip nht route-map vrf <name> json - show ipv6 nht route-map vrf all json - show ipv6 nht route-map vrf <name> json - show ipv6 nht route-map json - show ip nht route-map json Testing Done: Unit testing completed. tor-1# show ip nht route-map vrf default json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ip nht route-map vrf all json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "mgmt":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "sym_1":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ipv6 nht route-map vrf default json { "afi":"ipv6", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"kernel-policy", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } Ticket:#3229016 Issue:3229016 Signed-off-by: Sindhu Parvathi Gopinathan <sgopinathan@nvidia.com>
2022-11-08 06:40:13 +01:00
int ret;
bool uj = use_json(argc, argv);
ret = show_nht_rm(vty, AFI_IP, vrf_all, vrf_name, uj);
return ret;
}
DEFPY (show_ipv6_protocol_nht,
show_ipv6_protocol_nht_cmd,
zebra: json support for show ip nht route-map Changes: JSON support added for below commands, - show ip nht route-map vrf all json - show ip nht route-map vrf <name> json - show ipv6 nht route-map vrf all json - show ipv6 nht route-map vrf <name> json - show ipv6 nht route-map json - show ip nht route-map json Testing Done: Unit testing completed. tor-1# show ip nht route-map vrf default json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ip nht route-map vrf all json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "mgmt":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "sym_1":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ipv6 nht route-map vrf default json { "afi":"ipv6", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"kernel-policy", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } Ticket:#3229016 Issue:3229016 Signed-off-by: Sindhu Parvathi Gopinathan <sgopinathan@nvidia.com>
2022-11-08 06:40:13 +01:00
"show ipv6 nht route-map [vrf <NAME$vrf_name|all$vrf_all>] [json]",
SHOW_STR
IP6_STR
zebra: json support for show ip nht route-map Changes: JSON support added for below commands, - show ip nht route-map vrf all json - show ip nht route-map vrf <name> json - show ipv6 nht route-map vrf all json - show ipv6 nht route-map vrf <name> json - show ipv6 nht route-map json - show ip nht route-map json Testing Done: Unit testing completed. tor-1# show ip nht route-map vrf default json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ip nht route-map vrf all json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "mgmt":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "sym_1":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ipv6 nht route-map vrf default json { "afi":"ipv6", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"kernel-policy", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } Ticket:#3229016 Issue:3229016 Signed-off-by: Sindhu Parvathi Gopinathan <sgopinathan@nvidia.com>
2022-11-08 06:40:13 +01:00
"IPv6 nexthop tracking table\n"
"IPv6 Next Hop tracking filtering status\n"
VRF_CMD_HELP_STR
"All VRFs\n"
JSON_STR)
{
zebra: json support for show ip nht route-map Changes: JSON support added for below commands, - show ip nht route-map vrf all json - show ip nht route-map vrf <name> json - show ipv6 nht route-map vrf all json - show ipv6 nht route-map vrf <name> json - show ipv6 nht route-map json - show ip nht route-map json Testing Done: Unit testing completed. tor-1# show ip nht route-map vrf default json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ip nht route-map vrf all json { "afi":"ipv4", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"none", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "mgmt":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } }, "sym_1":{ "protocols":{ "system":"none", "kernel":"none", "connected":"none", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"bgp-policy", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } tor-1# show ipv6 nht route-map vrf default json { "afi":"ipv6", "vrfs":{ "default":{ "protocols":{ "system":"none", "kernel":"kernel-policy", "connected":"connected-policy", "static":"none", "rip":"none", "ripng":"none", "ospf":"none", "ospf6":"none", "isis":"none", "bgp":"none", "pim":"none", "eigrp":"none", "nhrp":"none", "hsls":"none", "olsr":"none", "table":"none", "ldp":"none", "vnc":"none", "vnc-direct":"none", "vnc-rn":"none", "bgp-direct":"none", "bgp-direct-to-nve-groups":"none", "babel":"none", "sharp":"none", "pbr":"none", "bfd":"none", "openfabric":"none", "vrrp":"none", "zebra":"none", "frr":"none", "wildcard":"none", "any":"none" } } } } Ticket:#3229016 Issue:3229016 Signed-off-by: Sindhu Parvathi Gopinathan <sgopinathan@nvidia.com>
2022-11-08 06:40:13 +01:00
int ret;
bool uj = use_json(argc, argv);
ret = show_nht_rm(vty, AFI_IP6, vrf_all, vrf_name, uj);
return ret;
}
/*XXXXXXXXXXXXXXXXXXXXXXXXXXXX*/
/* `match ip next-hop IP_ACCESS_LIST' */
/* Match function return 1 if match is success else return zero. */
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP Introducing a 3rd state for route_map_apply library function: RMAP_NOOP Traditionally route map MATCH rule apis were designed to return a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH. (Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR). Depending on this response, the following statemachine decided the course of action: State1: If match cmd returns RMAP_MATCH then, keep existing behaviour. If routemap type is PERMIT, execute set cmds or call cmds if applicable, otherwise PERMIT! Else If routemap type is DENY, we DENYMATCH right away State2: If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH We require a 3rd state because of the following situation: The issue - what if, the rule api needs to abort or ignore a rule?: "match evpn vni xx" route-map filter can be applied to incoming routes regardless of whether the tunnel type is vxlan or mpls. This rule should be N/A for mpls based evpn route, but applicable to only vxlan based evpn route. Also, this rule should be applicable for routes with VNI label only, and not for routes without labels. For example, type 3 and type 4 EVPN routes do not have labels, so, this match cmd should let them through. Today, the filter produces either a match or nomatch response regardless of whether it is mpls/vxlan, resulting in either permitting or denying the route.. So an mpls evpn route may get filtered out incorrectly. Eg: "route-map RM1 permit 10 ; match evpn vni 20" or "route-map RM2 deny 20 ; match vni 20" With the introduction of the 3rd state, we can abort this rule check safely. How? The rules api can now return RMAP_NOOP to indicate that it encountered an invalid check, and needs to abort just that rule, but continue with other rules. As a result we have a 3rd state: State3: If match cmd returned RMAP_NOOP Then, proceed to other route-map, otherwise if there are no more rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH. Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
static enum route_map_cmd_result_t
route_match_ip_next_hop(void *rule, const struct prefix *prefix, void *object)
{
struct access_list *alist;
struct zebra_rmap_obj *rm_data;
struct prefix_ipv4 p;
rm_data = object;
if (!rm_data)
return RMAP_NOMATCH;
switch (rm_data->nexthop->type) {
case NEXTHOP_TYPE_IFINDEX:
/* Interface routes can't match ip next-hop */
return RMAP_NOMATCH;
case NEXTHOP_TYPE_IPV4_IFINDEX:
case NEXTHOP_TYPE_IPV4:
p.family = AF_INET;
p.prefix = rm_data->nexthop->gate.ipv4;
p.prefixlen = IPV4_MAX_BITLEN;
break;
case NEXTHOP_TYPE_IPV6:
case NEXTHOP_TYPE_IPV6_IFINDEX:
case NEXTHOP_TYPE_BLACKHOLE:
return RMAP_NOMATCH;
}
alist = access_list_lookup(AFI_IP, (char *)rule);
if (alist == NULL) {
if (unlikely(CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL)))
zlog_debug(
"%s: Access-List Specified: %s does not exist defaulting to NO_MATCH",
__func__, (char *)rule);
return RMAP_NOMATCH;
}
return (access_list_apply(alist, &p) == FILTER_DENY ? RMAP_NOMATCH
: RMAP_MATCH);
}
/* Route map `ip next-hop' match statement. `arg' should be
access-list name. */
static void *route_match_ip_next_hop_compile(const char *arg)
{
return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
}
/* Free route map's compiled `. */
static void route_match_ip_next_hop_free(void *rule)
{
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
}
/* Route map commands for ip next-hop matching. */
static const struct route_map_rule_cmd route_match_ip_next_hop_cmd = {
"ip next-hop",
route_match_ip_next_hop,
route_match_ip_next_hop_compile,
route_match_ip_next_hop_free
};
/* `match ip next-hop prefix-list PREFIX_LIST' */
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP Introducing a 3rd state for route_map_apply library function: RMAP_NOOP Traditionally route map MATCH rule apis were designed to return a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH. (Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR). Depending on this response, the following statemachine decided the course of action: State1: If match cmd returns RMAP_MATCH then, keep existing behaviour. If routemap type is PERMIT, execute set cmds or call cmds if applicable, otherwise PERMIT! Else If routemap type is DENY, we DENYMATCH right away State2: If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH We require a 3rd state because of the following situation: The issue - what if, the rule api needs to abort or ignore a rule?: "match evpn vni xx" route-map filter can be applied to incoming routes regardless of whether the tunnel type is vxlan or mpls. This rule should be N/A for mpls based evpn route, but applicable to only vxlan based evpn route. Also, this rule should be applicable for routes with VNI label only, and not for routes without labels. For example, type 3 and type 4 EVPN routes do not have labels, so, this match cmd should let them through. Today, the filter produces either a match or nomatch response regardless of whether it is mpls/vxlan, resulting in either permitting or denying the route.. So an mpls evpn route may get filtered out incorrectly. Eg: "route-map RM1 permit 10 ; match evpn vni 20" or "route-map RM2 deny 20 ; match vni 20" With the introduction of the 3rd state, we can abort this rule check safely. How? The rules api can now return RMAP_NOOP to indicate that it encountered an invalid check, and needs to abort just that rule, but continue with other rules. As a result we have a 3rd state: State3: If match cmd returned RMAP_NOOP Then, proceed to other route-map, otherwise if there are no more rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH. Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
static enum route_map_cmd_result_t
route_match_ip_next_hop_prefix_list(void *rule, const struct prefix *prefix,
void *object)
{
struct prefix_list *plist;
struct zebra_rmap_obj *rm_data;
struct prefix_ipv4 p;
rm_data = (struct zebra_rmap_obj *)object;
if (!rm_data)
return RMAP_NOMATCH;
switch (rm_data->nexthop->type) {
case NEXTHOP_TYPE_IFINDEX:
/* Interface routes can't match ip next-hop */
return RMAP_NOMATCH;
case NEXTHOP_TYPE_IPV4_IFINDEX:
case NEXTHOP_TYPE_IPV4:
p.family = AF_INET;
p.prefix = rm_data->nexthop->gate.ipv4;
p.prefixlen = IPV4_MAX_BITLEN;
break;
case NEXTHOP_TYPE_IPV6:
case NEXTHOP_TYPE_IPV6_IFINDEX:
case NEXTHOP_TYPE_BLACKHOLE:
return RMAP_NOMATCH;
}
plist = prefix_list_lookup(AFI_IP, (char *)rule);
if (plist == NULL) {
if (unlikely(CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL)))
zlog_debug(
"%s: Prefix List %s specified does not exist defaulting to NO_MATCH",
__func__, (char *)rule);
return RMAP_NOMATCH;
}
return (prefix_list_apply(plist, &p) == PREFIX_DENY ? RMAP_NOMATCH
: RMAP_MATCH);
}
static void *route_match_ip_next_hop_prefix_list_compile(const char *arg)
{
return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
}
static void route_match_ip_next_hop_prefix_list_free(void *rule)
{
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
}
static const struct route_map_rule_cmd
route_match_ip_next_hop_prefix_list_cmd = {
"ip next-hop prefix-list",
route_match_ip_next_hop_prefix_list,
route_match_ip_next_hop_prefix_list_compile,
route_match_ip_next_hop_prefix_list_free
};
/* `match ip address IP_ACCESS_LIST' */
/* Match function should return 1 if match is success else return
zero. */
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP Introducing a 3rd state for route_map_apply library function: RMAP_NOOP Traditionally route map MATCH rule apis were designed to return a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH. (Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR). Depending on this response, the following statemachine decided the course of action: State1: If match cmd returns RMAP_MATCH then, keep existing behaviour. If routemap type is PERMIT, execute set cmds or call cmds if applicable, otherwise PERMIT! Else If routemap type is DENY, we DENYMATCH right away State2: If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH We require a 3rd state because of the following situation: The issue - what if, the rule api needs to abort or ignore a rule?: "match evpn vni xx" route-map filter can be applied to incoming routes regardless of whether the tunnel type is vxlan or mpls. This rule should be N/A for mpls based evpn route, but applicable to only vxlan based evpn route. Also, this rule should be applicable for routes with VNI label only, and not for routes without labels. For example, type 3 and type 4 EVPN routes do not have labels, so, this match cmd should let them through. Today, the filter produces either a match or nomatch response regardless of whether it is mpls/vxlan, resulting in either permitting or denying the route.. So an mpls evpn route may get filtered out incorrectly. Eg: "route-map RM1 permit 10 ; match evpn vni 20" or "route-map RM2 deny 20 ; match vni 20" With the introduction of the 3rd state, we can abort this rule check safely. How? The rules api can now return RMAP_NOOP to indicate that it encountered an invalid check, and needs to abort just that rule, but continue with other rules. As a result we have a 3rd state: State3: If match cmd returned RMAP_NOOP Then, proceed to other route-map, otherwise if there are no more rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH. Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
static enum route_map_cmd_result_t
route_match_address(afi_t afi, void *rule, const struct prefix *prefix,
void *object)
{
struct access_list *alist;
alist = access_list_lookup(afi, (char *)rule);
if (alist == NULL) {
if (unlikely(CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL)))
zlog_debug(
"%s: Access-List Specified: %s does not exist defaulting to NO_MATCH",
__func__, (char *)rule);
return RMAP_NOMATCH;
}
return (access_list_apply(alist, prefix) == FILTER_DENY ? RMAP_NOMATCH
: RMAP_MATCH);
}
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP Introducing a 3rd state for route_map_apply library function: RMAP_NOOP Traditionally route map MATCH rule apis were designed to return a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH. (Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR). Depending on this response, the following statemachine decided the course of action: State1: If match cmd returns RMAP_MATCH then, keep existing behaviour. If routemap type is PERMIT, execute set cmds or call cmds if applicable, otherwise PERMIT! Else If routemap type is DENY, we DENYMATCH right away State2: If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH We require a 3rd state because of the following situation: The issue - what if, the rule api needs to abort or ignore a rule?: "match evpn vni xx" route-map filter can be applied to incoming routes regardless of whether the tunnel type is vxlan or mpls. This rule should be N/A for mpls based evpn route, but applicable to only vxlan based evpn route. Also, this rule should be applicable for routes with VNI label only, and not for routes without labels. For example, type 3 and type 4 EVPN routes do not have labels, so, this match cmd should let them through. Today, the filter produces either a match or nomatch response regardless of whether it is mpls/vxlan, resulting in either permitting or denying the route.. So an mpls evpn route may get filtered out incorrectly. Eg: "route-map RM1 permit 10 ; match evpn vni 20" or "route-map RM2 deny 20 ; match vni 20" With the introduction of the 3rd state, we can abort this rule check safely. How? The rules api can now return RMAP_NOOP to indicate that it encountered an invalid check, and needs to abort just that rule, but continue with other rules. As a result we have a 3rd state: State3: If match cmd returned RMAP_NOOP Then, proceed to other route-map, otherwise if there are no more rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH. Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
static enum route_map_cmd_result_t
route_match_ip_address(void *rule, const struct prefix *prefix, void *object)
{
return route_match_address(AFI_IP, rule, prefix, object);
}
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP Introducing a 3rd state for route_map_apply library function: RMAP_NOOP Traditionally route map MATCH rule apis were designed to return a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH. (Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR). Depending on this response, the following statemachine decided the course of action: State1: If match cmd returns RMAP_MATCH then, keep existing behaviour. If routemap type is PERMIT, execute set cmds or call cmds if applicable, otherwise PERMIT! Else If routemap type is DENY, we DENYMATCH right away State2: If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH We require a 3rd state because of the following situation: The issue - what if, the rule api needs to abort or ignore a rule?: "match evpn vni xx" route-map filter can be applied to incoming routes regardless of whether the tunnel type is vxlan or mpls. This rule should be N/A for mpls based evpn route, but applicable to only vxlan based evpn route. Also, this rule should be applicable for routes with VNI label only, and not for routes without labels. For example, type 3 and type 4 EVPN routes do not have labels, so, this match cmd should let them through. Today, the filter produces either a match or nomatch response regardless of whether it is mpls/vxlan, resulting in either permitting or denying the route.. So an mpls evpn route may get filtered out incorrectly. Eg: "route-map RM1 permit 10 ; match evpn vni 20" or "route-map RM2 deny 20 ; match vni 20" With the introduction of the 3rd state, we can abort this rule check safely. How? The rules api can now return RMAP_NOOP to indicate that it encountered an invalid check, and needs to abort just that rule, but continue with other rules. As a result we have a 3rd state: State3: If match cmd returned RMAP_NOOP Then, proceed to other route-map, otherwise if there are no more rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH. Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
static enum route_map_cmd_result_t
route_match_ipv6_address(void *rule, const struct prefix *prefix, void *object)
{
return route_match_address(AFI_IP6, rule, prefix, object);
}
/* Route map `ip address' match statement. `arg' should be
access-list name. */
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_address_free(void *rule)
{
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
}
/* Route map commands for ip address matching. */
static const struct route_map_rule_cmd route_match_ip_address_cmd = {
"ip address",
route_match_ip_address,
route_match_address_compile,
route_match_address_free
};
/* Route map commands for ipv6 address matching. */
static const 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' */
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP Introducing a 3rd state for route_map_apply library function: RMAP_NOOP Traditionally route map MATCH rule apis were designed to return a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH. (Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR). Depending on this response, the following statemachine decided the course of action: State1: If match cmd returns RMAP_MATCH then, keep existing behaviour. If routemap type is PERMIT, execute set cmds or call cmds if applicable, otherwise PERMIT! Else If routemap type is DENY, we DENYMATCH right away State2: If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH We require a 3rd state because of the following situation: The issue - what if, the rule api needs to abort or ignore a rule?: "match evpn vni xx" route-map filter can be applied to incoming routes regardless of whether the tunnel type is vxlan or mpls. This rule should be N/A for mpls based evpn route, but applicable to only vxlan based evpn route. Also, this rule should be applicable for routes with VNI label only, and not for routes without labels. For example, type 3 and type 4 EVPN routes do not have labels, so, this match cmd should let them through. Today, the filter produces either a match or nomatch response regardless of whether it is mpls/vxlan, resulting in either permitting or denying the route.. So an mpls evpn route may get filtered out incorrectly. Eg: "route-map RM1 permit 10 ; match evpn vni 20" or "route-map RM2 deny 20 ; match vni 20" With the introduction of the 3rd state, we can abort this rule check safely. How? The rules api can now return RMAP_NOOP to indicate that it encountered an invalid check, and needs to abort just that rule, but continue with other rules. As a result we have a 3rd state: State3: If match cmd returned RMAP_NOOP Then, proceed to other route-map, otherwise if there are no more rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH. Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
static enum route_map_cmd_result_t
route_match_address_prefix_list(void *rule, const struct prefix *prefix,
void *object, afi_t afi)
{
struct prefix_list *plist;
plist = prefix_list_lookup(afi, (char *)rule);
if (plist == NULL) {
if (unlikely(CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL)))
zlog_debug("%s: Prefix List %s (%s) specified does not exist defaulting to NO_MATCH",
__func__, (char *)rule, afi2str(afi));
return RMAP_NOMATCH;
}
return (prefix_list_apply(plist, prefix) == PREFIX_DENY ? RMAP_NOMATCH
: RMAP_MATCH);
}
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP Introducing a 3rd state for route_map_apply library function: RMAP_NOOP Traditionally route map MATCH rule apis were designed to return a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH. (Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR). Depending on this response, the following statemachine decided the course of action: State1: If match cmd returns RMAP_MATCH then, keep existing behaviour. If routemap type is PERMIT, execute set cmds or call cmds if applicable, otherwise PERMIT! Else If routemap type is DENY, we DENYMATCH right away State2: If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH We require a 3rd state because of the following situation: The issue - what if, the rule api needs to abort or ignore a rule?: "match evpn vni xx" route-map filter can be applied to incoming routes regardless of whether the tunnel type is vxlan or mpls. This rule should be N/A for mpls based evpn route, but applicable to only vxlan based evpn route. Also, this rule should be applicable for routes with VNI label only, and not for routes without labels. For example, type 3 and type 4 EVPN routes do not have labels, so, this match cmd should let them through. Today, the filter produces either a match or nomatch response regardless of whether it is mpls/vxlan, resulting in either permitting or denying the route.. So an mpls evpn route may get filtered out incorrectly. Eg: "route-map RM1 permit 10 ; match evpn vni 20" or "route-map RM2 deny 20 ; match vni 20" With the introduction of the 3rd state, we can abort this rule check safely. How? The rules api can now return RMAP_NOOP to indicate that it encountered an invalid check, and needs to abort just that rule, but continue with other rules. As a result we have a 3rd state: State3: If match cmd returned RMAP_NOOP Then, proceed to other route-map, otherwise if there are no more rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH. Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
static enum route_map_cmd_result_t
route_match_ip_address_prefix_list(void *rule, const struct prefix *prefix,
void *object)
{
return (route_match_address_prefix_list(rule, prefix, 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_address_prefix_list_free(void *rule)
{
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
}
static const struct route_map_rule_cmd
route_match_ip_address_prefix_list_cmd = {
"ip address prefix-list",
route_match_ip_address_prefix_list,
route_match_address_prefix_list_compile,
route_match_address_prefix_list_free
};
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP Introducing a 3rd state for route_map_apply library function: RMAP_NOOP Traditionally route map MATCH rule apis were designed to return a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH. (Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR). Depending on this response, the following statemachine decided the course of action: State1: If match cmd returns RMAP_MATCH then, keep existing behaviour. If routemap type is PERMIT, execute set cmds or call cmds if applicable, otherwise PERMIT! Else If routemap type is DENY, we DENYMATCH right away State2: If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH We require a 3rd state because of the following situation: The issue - what if, the rule api needs to abort or ignore a rule?: "match evpn vni xx" route-map filter can be applied to incoming routes regardless of whether the tunnel type is vxlan or mpls. This rule should be N/A for mpls based evpn route, but applicable to only vxlan based evpn route. Also, this rule should be applicable for routes with VNI label only, and not for routes without labels. For example, type 3 and type 4 EVPN routes do not have labels, so, this match cmd should let them through. Today, the filter produces either a match or nomatch response regardless of whether it is mpls/vxlan, resulting in either permitting or denying the route.. So an mpls evpn route may get filtered out incorrectly. Eg: "route-map RM1 permit 10 ; match evpn vni 20" or "route-map RM2 deny 20 ; match vni 20" With the introduction of the 3rd state, we can abort this rule check safely. How? The rules api can now return RMAP_NOOP to indicate that it encountered an invalid check, and needs to abort just that rule, but continue with other rules. As a result we have a 3rd state: State3: If match cmd returned RMAP_NOOP Then, proceed to other route-map, otherwise if there are no more rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH. Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
static enum route_map_cmd_result_t
route_match_ipv6_address_prefix_list(void *rule, const struct prefix *prefix,
void *object)
{
return (route_match_address_prefix_list(rule, prefix, object, AFI_IP6));
}
static const 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 ipv6 next-hop type <TYPE>' */
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP Introducing a 3rd state for route_map_apply library function: RMAP_NOOP Traditionally route map MATCH rule apis were designed to return a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH. (Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR). Depending on this response, the following statemachine decided the course of action: State1: If match cmd returns RMAP_MATCH then, keep existing behaviour. If routemap type is PERMIT, execute set cmds or call cmds if applicable, otherwise PERMIT! Else If routemap type is DENY, we DENYMATCH right away State2: If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH We require a 3rd state because of the following situation: The issue - what if, the rule api needs to abort or ignore a rule?: "match evpn vni xx" route-map filter can be applied to incoming routes regardless of whether the tunnel type is vxlan or mpls. This rule should be N/A for mpls based evpn route, but applicable to only vxlan based evpn route. Also, this rule should be applicable for routes with VNI label only, and not for routes without labels. For example, type 3 and type 4 EVPN routes do not have labels, so, this match cmd should let them through. Today, the filter produces either a match or nomatch response regardless of whether it is mpls/vxlan, resulting in either permitting or denying the route.. So an mpls evpn route may get filtered out incorrectly. Eg: "route-map RM1 permit 10 ; match evpn vni 20" or "route-map RM2 deny 20 ; match vni 20" With the introduction of the 3rd state, we can abort this rule check safely. How? The rules api can now return RMAP_NOOP to indicate that it encountered an invalid check, and needs to abort just that rule, but continue with other rules. As a result we have a 3rd state: State3: If match cmd returned RMAP_NOOP Then, proceed to other route-map, otherwise if there are no more rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH. Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
static enum route_map_cmd_result_t
route_match_ipv6_next_hop_type(void *rule, const struct prefix *prefix,
void *object)
{
struct zebra_rmap_obj *rm_data;
if (prefix->family == AF_INET6) {
rm_data = (struct zebra_rmap_obj *)object;
if (!rm_data)
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP Introducing a 3rd state for route_map_apply library function: RMAP_NOOP Traditionally route map MATCH rule apis were designed to return a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH. (Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR). Depending on this response, the following statemachine decided the course of action: State1: If match cmd returns RMAP_MATCH then, keep existing behaviour. If routemap type is PERMIT, execute set cmds or call cmds if applicable, otherwise PERMIT! Else If routemap type is DENY, we DENYMATCH right away State2: If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH We require a 3rd state because of the following situation: The issue - what if, the rule api needs to abort or ignore a rule?: "match evpn vni xx" route-map filter can be applied to incoming routes regardless of whether the tunnel type is vxlan or mpls. This rule should be N/A for mpls based evpn route, but applicable to only vxlan based evpn route. Also, this rule should be applicable for routes with VNI label only, and not for routes without labels. For example, type 3 and type 4 EVPN routes do not have labels, so, this match cmd should let them through. Today, the filter produces either a match or nomatch response regardless of whether it is mpls/vxlan, resulting in either permitting or denying the route.. So an mpls evpn route may get filtered out incorrectly. Eg: "route-map RM1 permit 10 ; match evpn vni 20" or "route-map RM2 deny 20 ; match vni 20" With the introduction of the 3rd state, we can abort this rule check safely. How? The rules api can now return RMAP_NOOP to indicate that it encountered an invalid check, and needs to abort just that rule, but continue with other rules. As a result we have a 3rd state: State3: If match cmd returned RMAP_NOOP Then, proceed to other route-map, otherwise if there are no more rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH. Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
return RMAP_NOMATCH;
if (rm_data->nexthop->type == NEXTHOP_TYPE_BLACKHOLE)
return RMAP_MATCH;
}
return RMAP_NOMATCH;
}
static void *route_match_ipv6_next_hop_type_compile(const char *arg)
{
return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
}
static void route_match_ipv6_next_hop_type_free(void *rule)
{
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
}
static const struct route_map_rule_cmd
route_match_ipv6_next_hop_type_cmd = {
"ipv6 next-hop type",
route_match_ipv6_next_hop_type,
route_match_ipv6_next_hop_type_compile,
route_match_ipv6_next_hop_type_free
};
/* `match ip address prefix-len PREFIXLEN' */
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP Introducing a 3rd state for route_map_apply library function: RMAP_NOOP Traditionally route map MATCH rule apis were designed to return a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH. (Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR). Depending on this response, the following statemachine decided the course of action: State1: If match cmd returns RMAP_MATCH then, keep existing behaviour. If routemap type is PERMIT, execute set cmds or call cmds if applicable, otherwise PERMIT! Else If routemap type is DENY, we DENYMATCH right away State2: If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH We require a 3rd state because of the following situation: The issue - what if, the rule api needs to abort or ignore a rule?: "match evpn vni xx" route-map filter can be applied to incoming routes regardless of whether the tunnel type is vxlan or mpls. This rule should be N/A for mpls based evpn route, but applicable to only vxlan based evpn route. Also, this rule should be applicable for routes with VNI label only, and not for routes without labels. For example, type 3 and type 4 EVPN routes do not have labels, so, this match cmd should let them through. Today, the filter produces either a match or nomatch response regardless of whether it is mpls/vxlan, resulting in either permitting or denying the route.. So an mpls evpn route may get filtered out incorrectly. Eg: "route-map RM1 permit 10 ; match evpn vni 20" or "route-map RM2 deny 20 ; match vni 20" With the introduction of the 3rd state, we can abort this rule check safely. How? The rules api can now return RMAP_NOOP to indicate that it encountered an invalid check, and needs to abort just that rule, but continue with other rules. As a result we have a 3rd state: State3: If match cmd returned RMAP_NOOP Then, proceed to other route-map, otherwise if there are no more rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH. Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
static enum route_map_cmd_result_t
route_match_address_prefix_len(void *rule, const struct prefix *prefix,
void *object)
{
uint32_t *prefixlen = (uint32_t *)rule;
return ((prefix->prefixlen == *prefixlen) ? RMAP_MATCH : RMAP_NOMATCH);
}
static void *route_match_address_prefix_len_compile(const char *arg)
{
uint32_t *prefix_len;
char *endptr = NULL;
unsigned long tmpval;
/* prefix len value shoud be integer. */
if (!all_digit(arg))
return NULL;
errno = 0;
tmpval = strtoul(arg, &endptr, 10);
if (*endptr != '\0' || errno || tmpval > UINT32_MAX)
return NULL;
prefix_len = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(uint32_t));
*prefix_len = tmpval;
return prefix_len;
}
static void route_match_address_prefix_len_free(void *rule)
{
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
}
static const struct route_map_rule_cmd
route_match_ip_address_prefix_len_cmd = {
"ip address prefix-len",
route_match_address_prefix_len,
route_match_address_prefix_len_compile,
route_match_address_prefix_len_free
};
static const struct route_map_rule_cmd
route_match_ipv6_address_prefix_len_cmd = {
"ipv6 address prefix-len",
route_match_address_prefix_len,
route_match_address_prefix_len_compile,
route_match_address_prefix_len_free
};
/* `match ip nexthop prefix-len PREFIXLEN' */
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP Introducing a 3rd state for route_map_apply library function: RMAP_NOOP Traditionally route map MATCH rule apis were designed to return a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH. (Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR). Depending on this response, the following statemachine decided the course of action: State1: If match cmd returns RMAP_MATCH then, keep existing behaviour. If routemap type is PERMIT, execute set cmds or call cmds if applicable, otherwise PERMIT! Else If routemap type is DENY, we DENYMATCH right away State2: If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH We require a 3rd state because of the following situation: The issue - what if, the rule api needs to abort or ignore a rule?: "match evpn vni xx" route-map filter can be applied to incoming routes regardless of whether the tunnel type is vxlan or mpls. This rule should be N/A for mpls based evpn route, but applicable to only vxlan based evpn route. Also, this rule should be applicable for routes with VNI label only, and not for routes without labels. For example, type 3 and type 4 EVPN routes do not have labels, so, this match cmd should let them through. Today, the filter produces either a match or nomatch response regardless of whether it is mpls/vxlan, resulting in either permitting or denying the route.. So an mpls evpn route may get filtered out incorrectly. Eg: "route-map RM1 permit 10 ; match evpn vni 20" or "route-map RM2 deny 20 ; match vni 20" With the introduction of the 3rd state, we can abort this rule check safely. How? The rules api can now return RMAP_NOOP to indicate that it encountered an invalid check, and needs to abort just that rule, but continue with other rules. As a result we have a 3rd state: State3: If match cmd returned RMAP_NOOP Then, proceed to other route-map, otherwise if there are no more rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH. Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
static enum route_map_cmd_result_t
route_match_ip_nexthop_prefix_len(void *rule, const struct prefix *prefix,
void *object)
{
uint32_t *prefixlen = (uint32_t *)rule;
struct zebra_rmap_obj *rm_data;
struct prefix_ipv4 p;
rm_data = (struct zebra_rmap_obj *)object;
if (!rm_data || !rm_data->nexthop)
return RMAP_NOMATCH;
switch (rm_data->nexthop->type) {
case NEXTHOP_TYPE_IFINDEX:
/* Interface routes can't match ip next-hop */
return RMAP_NOMATCH;
case NEXTHOP_TYPE_IPV4_IFINDEX:
case NEXTHOP_TYPE_IPV4:
p.family = AF_INET;
p.prefix = rm_data->nexthop->gate.ipv4;
p.prefixlen = IPV4_MAX_BITLEN;
break;
case NEXTHOP_TYPE_IPV6:
case NEXTHOP_TYPE_IPV6_IFINDEX:
case NEXTHOP_TYPE_BLACKHOLE:
return RMAP_NOMATCH;
}
return ((p.prefixlen == *prefixlen) ? RMAP_MATCH : RMAP_NOMATCH);
}
static const struct route_map_rule_cmd
route_match_ip_nexthop_prefix_len_cmd = {
"ip next-hop prefix-len",
route_match_ip_nexthop_prefix_len,
route_match_address_prefix_len_compile, /* reuse */
route_match_address_prefix_len_free /* reuse */
};
/* `match ip next-hop type <blackhole>' */
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP Introducing a 3rd state for route_map_apply library function: RMAP_NOOP Traditionally route map MATCH rule apis were designed to return a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH. (Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR). Depending on this response, the following statemachine decided the course of action: State1: If match cmd returns RMAP_MATCH then, keep existing behaviour. If routemap type is PERMIT, execute set cmds or call cmds if applicable, otherwise PERMIT! Else If routemap type is DENY, we DENYMATCH right away State2: If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH We require a 3rd state because of the following situation: The issue - what if, the rule api needs to abort or ignore a rule?: "match evpn vni xx" route-map filter can be applied to incoming routes regardless of whether the tunnel type is vxlan or mpls. This rule should be N/A for mpls based evpn route, but applicable to only vxlan based evpn route. Also, this rule should be applicable for routes with VNI label only, and not for routes without labels. For example, type 3 and type 4 EVPN routes do not have labels, so, this match cmd should let them through. Today, the filter produces either a match or nomatch response regardless of whether it is mpls/vxlan, resulting in either permitting or denying the route.. So an mpls evpn route may get filtered out incorrectly. Eg: "route-map RM1 permit 10 ; match evpn vni 20" or "route-map RM2 deny 20 ; match vni 20" With the introduction of the 3rd state, we can abort this rule check safely. How? The rules api can now return RMAP_NOOP to indicate that it encountered an invalid check, and needs to abort just that rule, but continue with other rules. As a result we have a 3rd state: State3: If match cmd returned RMAP_NOOP Then, proceed to other route-map, otherwise if there are no more rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH. Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
static enum route_map_cmd_result_t
route_match_ip_next_hop_type(void *rule, const struct prefix *prefix,
void *object)
{
struct zebra_rmap_obj *rm_data;
if (prefix->family == AF_INET) {
rm_data = (struct zebra_rmap_obj *)object;
if (!rm_data)
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP Introducing a 3rd state for route_map_apply library function: RMAP_NOOP Traditionally route map MATCH rule apis were designed to return a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH. (Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR). Depending on this response, the following statemachine decided the course of action: State1: If match cmd returns RMAP_MATCH then, keep existing behaviour. If routemap type is PERMIT, execute set cmds or call cmds if applicable, otherwise PERMIT! Else If routemap type is DENY, we DENYMATCH right away State2: If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH We require a 3rd state because of the following situation: The issue - what if, the rule api needs to abort or ignore a rule?: "match evpn vni xx" route-map filter can be applied to incoming routes regardless of whether the tunnel type is vxlan or mpls. This rule should be N/A for mpls based evpn route, but applicable to only vxlan based evpn route. Also, this rule should be applicable for routes with VNI label only, and not for routes without labels. For example, type 3 and type 4 EVPN routes do not have labels, so, this match cmd should let them through. Today, the filter produces either a match or nomatch response regardless of whether it is mpls/vxlan, resulting in either permitting or denying the route.. So an mpls evpn route may get filtered out incorrectly. Eg: "route-map RM1 permit 10 ; match evpn vni 20" or "route-map RM2 deny 20 ; match vni 20" With the introduction of the 3rd state, we can abort this rule check safely. How? The rules api can now return RMAP_NOOP to indicate that it encountered an invalid check, and needs to abort just that rule, but continue with other rules. As a result we have a 3rd state: State3: If match cmd returned RMAP_NOOP Then, proceed to other route-map, otherwise if there are no more rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH. Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
return RMAP_NOMATCH;
if (rm_data->nexthop->type == NEXTHOP_TYPE_BLACKHOLE)
return RMAP_MATCH;
}
return RMAP_NOMATCH;
}
static void *route_match_ip_next_hop_type_compile(const char *arg)
{
return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
}
static void route_match_ip_next_hop_type_free(void *rule)
{
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
}
static const struct route_map_rule_cmd
route_match_ip_next_hop_type_cmd = {
"ip next-hop type",
route_match_ip_next_hop_type,
route_match_ip_next_hop_type_compile,
route_match_ip_next_hop_type_free
};
/* `match source-protocol PROTOCOL' */
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP Introducing a 3rd state for route_map_apply library function: RMAP_NOOP Traditionally route map MATCH rule apis were designed to return a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH. (Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR). Depending on this response, the following statemachine decided the course of action: State1: If match cmd returns RMAP_MATCH then, keep existing behaviour. If routemap type is PERMIT, execute set cmds or call cmds if applicable, otherwise PERMIT! Else If routemap type is DENY, we DENYMATCH right away State2: If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH We require a 3rd state because of the following situation: The issue - what if, the rule api needs to abort or ignore a rule?: "match evpn vni xx" route-map filter can be applied to incoming routes regardless of whether the tunnel type is vxlan or mpls. This rule should be N/A for mpls based evpn route, but applicable to only vxlan based evpn route. Also, this rule should be applicable for routes with VNI label only, and not for routes without labels. For example, type 3 and type 4 EVPN routes do not have labels, so, this match cmd should let them through. Today, the filter produces either a match or nomatch response regardless of whether it is mpls/vxlan, resulting in either permitting or denying the route.. So an mpls evpn route may get filtered out incorrectly. Eg: "route-map RM1 permit 10 ; match evpn vni 20" or "route-map RM2 deny 20 ; match vni 20" With the introduction of the 3rd state, we can abort this rule check safely. How? The rules api can now return RMAP_NOOP to indicate that it encountered an invalid check, and needs to abort just that rule, but continue with other rules. As a result we have a 3rd state: State3: If match cmd returned RMAP_NOOP Then, proceed to other route-map, otherwise if there are no more rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH. Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
static enum route_map_cmd_result_t
route_match_source_protocol(void *rule, const struct prefix *p, void *object)
{
int32_t *rib_type = (int32_t *)rule;
struct zebra_rmap_obj *rm_data;
rm_data = (struct zebra_rmap_obj *)object;
if (!rm_data)
return RMAP_NOMATCH;
return ((rm_data->re->type == *rib_type) ? RMAP_MATCH : RMAP_NOMATCH);
}
static void *route_match_source_protocol_compile(const char *arg)
{
uint32_t *rib_type;
int i;
i = proto_name2num(arg);
rib_type = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(uint32_t));
*rib_type = i;
return rib_type;
}
static void route_match_source_protocol_free(void *rule)
{
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
}
static const struct route_map_rule_cmd route_match_source_protocol_cmd = {
"source-protocol",
route_match_source_protocol,
route_match_source_protocol_compile,
route_match_source_protocol_free
};
/* `source-instance` */
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP Introducing a 3rd state for route_map_apply library function: RMAP_NOOP Traditionally route map MATCH rule apis were designed to return a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH. (Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR). Depending on this response, the following statemachine decided the course of action: State1: If match cmd returns RMAP_MATCH then, keep existing behaviour. If routemap type is PERMIT, execute set cmds or call cmds if applicable, otherwise PERMIT! Else If routemap type is DENY, we DENYMATCH right away State2: If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH We require a 3rd state because of the following situation: The issue - what if, the rule api needs to abort or ignore a rule?: "match evpn vni xx" route-map filter can be applied to incoming routes regardless of whether the tunnel type is vxlan or mpls. This rule should be N/A for mpls based evpn route, but applicable to only vxlan based evpn route. Also, this rule should be applicable for routes with VNI label only, and not for routes without labels. For example, type 3 and type 4 EVPN routes do not have labels, so, this match cmd should let them through. Today, the filter produces either a match or nomatch response regardless of whether it is mpls/vxlan, resulting in either permitting or denying the route.. So an mpls evpn route may get filtered out incorrectly. Eg: "route-map RM1 permit 10 ; match evpn vni 20" or "route-map RM2 deny 20 ; match vni 20" With the introduction of the 3rd state, we can abort this rule check safely. How? The rules api can now return RMAP_NOOP to indicate that it encountered an invalid check, and needs to abort just that rule, but continue with other rules. As a result we have a 3rd state: State3: If match cmd returned RMAP_NOOP Then, proceed to other route-map, otherwise if there are no more rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH. Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
static enum route_map_cmd_result_t
route_match_source_instance(void *rule, const struct prefix *p, void *object)
{
uint8_t *instance = (uint8_t *)rule;
struct zebra_rmap_obj *rm_data;
rm_data = (struct zebra_rmap_obj *)object;
if (!rm_data)
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP Introducing a 3rd state for route_map_apply library function: RMAP_NOOP Traditionally route map MATCH rule apis were designed to return a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH. (Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR). Depending on this response, the following statemachine decided the course of action: State1: If match cmd returns RMAP_MATCH then, keep existing behaviour. If routemap type is PERMIT, execute set cmds or call cmds if applicable, otherwise PERMIT! Else If routemap type is DENY, we DENYMATCH right away State2: If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH We require a 3rd state because of the following situation: The issue - what if, the rule api needs to abort or ignore a rule?: "match evpn vni xx" route-map filter can be applied to incoming routes regardless of whether the tunnel type is vxlan or mpls. This rule should be N/A for mpls based evpn route, but applicable to only vxlan based evpn route. Also, this rule should be applicable for routes with VNI label only, and not for routes without labels. For example, type 3 and type 4 EVPN routes do not have labels, so, this match cmd should let them through. Today, the filter produces either a match or nomatch response regardless of whether it is mpls/vxlan, resulting in either permitting or denying the route.. So an mpls evpn route may get filtered out incorrectly. Eg: "route-map RM1 permit 10 ; match evpn vni 20" or "route-map RM2 deny 20 ; match vni 20" With the introduction of the 3rd state, we can abort this rule check safely. How? The rules api can now return RMAP_NOOP to indicate that it encountered an invalid check, and needs to abort just that rule, but continue with other rules. As a result we have a 3rd state: State3: If match cmd returned RMAP_NOOP Then, proceed to other route-map, otherwise if there are no more rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH. Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
return RMAP_NOMATCH;
return (rm_data->re->instance == *instance) ? RMAP_MATCH : RMAP_NOMATCH;
}
static void *route_match_source_instance_compile(const char *arg)
{
uint8_t *instance;
int i;
i = atoi(arg);
instance = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(uint8_t));
*instance = i;
return instance;
}
static void route_match_source_instance_free(void *rule)
{
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
}
static const struct route_map_rule_cmd route_match_source_instance_cmd = {
"source-instance",
route_match_source_instance,
route_match_source_instance_compile,
route_match_source_instance_free
};
/* `set src A.B.C.D' */
/* Set src. */
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP Introducing a 3rd state for route_map_apply library function: RMAP_NOOP Traditionally route map MATCH rule apis were designed to return a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH. (Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR). Depending on this response, the following statemachine decided the course of action: State1: If match cmd returns RMAP_MATCH then, keep existing behaviour. If routemap type is PERMIT, execute set cmds or call cmds if applicable, otherwise PERMIT! Else If routemap type is DENY, we DENYMATCH right away State2: If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH We require a 3rd state because of the following situation: The issue - what if, the rule api needs to abort or ignore a rule?: "match evpn vni xx" route-map filter can be applied to incoming routes regardless of whether the tunnel type is vxlan or mpls. This rule should be N/A for mpls based evpn route, but applicable to only vxlan based evpn route. Also, this rule should be applicable for routes with VNI label only, and not for routes without labels. For example, type 3 and type 4 EVPN routes do not have labels, so, this match cmd should let them through. Today, the filter produces either a match or nomatch response regardless of whether it is mpls/vxlan, resulting in either permitting or denying the route.. So an mpls evpn route may get filtered out incorrectly. Eg: "route-map RM1 permit 10 ; match evpn vni 20" or "route-map RM2 deny 20 ; match vni 20" With the introduction of the 3rd state, we can abort this rule check safely. How? The rules api can now return RMAP_NOOP to indicate that it encountered an invalid check, and needs to abort just that rule, but continue with other rules. As a result we have a 3rd state: State3: If match cmd returned RMAP_NOOP Then, proceed to other route-map, otherwise if there are no more rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH. Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
static enum route_map_cmd_result_t
route_set_src(void *rule, const struct prefix *prefix, void *object)
{
struct zebra_rmap_obj *rm_data;
rm_data = (struct zebra_rmap_obj *)object;
rm_data->nexthop->rmap_src = *(union g_addr *)rule;
return RMAP_OKAY;
}
/* set src compilation. */
static void *route_set_src_compile(const char *arg)
{
union g_addr src = {}, *psrc;
/* IPv4 first, to ensure no garbage in the 12 unused bytes */
if ((inet_pton(AF_INET, arg, &src.ipv4) == 1) ||
(inet_pton(AF_INET6, arg, &src.ipv6) == 1)) {
psrc = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(union g_addr));
*psrc = src;
return psrc;
}
return NULL;
}
/* Free route map's compiled `set src' value. */
static void route_set_src_free(void *rule)
{
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
}
/* Set src rule structure. */
static const struct route_map_rule_cmd route_set_src_cmd = {
"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;
struct route_map *old = NULL;
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));
old = PROTO_RM_MAP(zvrf, AFI_IP, i);
PROTO_RM_MAP(zvrf, AFI_IP, i) =
route_map_lookup_by_name(rmap_name);
/* old is NULL. i.e Route map creation event.
* So update applied_counter.
* If Old is not NULL, i.e It may be routemap
* updation or deletion.
* So no need to update the counter.
*/
if (!old)
route_map_counter_increment(
PROTO_RM_MAP(zvrf, AFI_IP, i));
/* There is single rib table for all protocols
*/
table = zvrf->table[AFI_IP][SAFI_UNICAST];
if (table) {
rib_update_table(
table,
RIB_UPDATE_RMAP_CHANGE,
i);
}
}
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));
old = PROTO_RM_MAP(zvrf, AFI_IP6, i);
PROTO_RM_MAP(zvrf, AFI_IP6, i) =
route_map_lookup_by_name(rmap_name);
if (!old)
route_map_counter_increment(
PROTO_RM_MAP(zvrf, AFI_IP6, i));
/* There is single rib table for all protocols
*/
table = zvrf->table[AFI_IP6][SAFI_UNICAST];
if (table) {
rib_update_table(
table,
RIB_UPDATE_RMAP_CHANGE,
i);
}
}
}
}
}
/* 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;
struct route_map *old = NULL;
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));
old = NHT_RM_MAP(zvrf, AFI_IP, i);
NHT_RM_MAP(zvrf, AFI_IP, i) =
route_map_lookup_by_name(rmap_name);
if (!old)
route_map_counter_increment(
NHT_RM_MAP(zvrf, AFI_IP, i));
/* 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, AFI_IP, 1, NULL,
SAFI_UNICAST);
}
}
}
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));
old = NHT_RM_MAP(zvrf, AFI_IP6, i);
NHT_RM_MAP(zvrf, AFI_IP6, i) =
route_map_lookup_by_name(rmap_name);
if (!old)
route_map_counter_increment(
NHT_RM_MAP(zvrf, AFI_IP6, i));
/* 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, AFI_IP6, 1, NULL,
SAFI_UNICAST);
}
}
}
}
}
}
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 void zebra_route_map_update_timer(struct event *thread)
{
if (IS_ZEBRA_DEBUG_EVENT)
zlog_debug("Event driven route-map update triggered");
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
zlog_debug(
"%u: Routemap update-timer fired, scheduling RIB processing",
VRF_DEFAULT);
route_map_walk_update_list(zebra_route_map_process_update_cb);
/*
* This code needs to be updated to be:
* 1) VRF Aware <sigh>
* 2) Route-map aware
*/
}
void zebra_route_map_set_delay_timer(uint32_t value)
{
zebra_rmap_update_timer = value;
if (!value && zebra_t_rmap_update) {
/* Event driven route map updates is being disabled */
/* But there's a pending timer. Fire it off now */
EVENT_OFF(zebra_t_rmap_update);
zebra_route_map_update_timer(NULL);
}
}
void zebra_routemap_finish(void)
{
/* Set zebra_rmap_update_timer to 0 so that it wont schedule again */
zebra_rmap_update_timer = 0;
/* Thread off if any scheduled already */
EVENT_OFF(zebra_t_rmap_update);
route_map_finish();
}
route_map_result_t zebra_route_map_check(afi_t family, struct route_entry *re,
const struct prefix *p,
struct nexthop *nexthop,
struct zebra_vrf *zvrf)
{
struct route_map *rmap = NULL;
char *rm_name;
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP Introducing a 3rd state for route_map_apply library function: RMAP_NOOP Traditionally route map MATCH rule apis were designed to return a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH. (Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR). Depending on this response, the following statemachine decided the course of action: State1: If match cmd returns RMAP_MATCH then, keep existing behaviour. If routemap type is PERMIT, execute set cmds or call cmds if applicable, otherwise PERMIT! Else If routemap type is DENY, we DENYMATCH right away State2: If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH We require a 3rd state because of the following situation: The issue - what if, the rule api needs to abort or ignore a rule?: "match evpn vni xx" route-map filter can be applied to incoming routes regardless of whether the tunnel type is vxlan or mpls. This rule should be N/A for mpls based evpn route, but applicable to only vxlan based evpn route. Also, this rule should be applicable for routes with VNI label only, and not for routes without labels. For example, type 3 and type 4 EVPN routes do not have labels, so, this match cmd should let them through. Today, the filter produces either a match or nomatch response regardless of whether it is mpls/vxlan, resulting in either permitting or denying the route.. So an mpls evpn route may get filtered out incorrectly. Eg: "route-map RM1 permit 10 ; match evpn vni 20" or "route-map RM2 deny 20 ; match vni 20" With the introduction of the 3rd state, we can abort this rule check safely. How? The rules api can now return RMAP_NOOP to indicate that it encountered an invalid check, and needs to abort just that rule, but continue with other rules. As a result we have a 3rd state: State3: If match cmd returned RMAP_NOOP Then, proceed to other route-map, otherwise if there are no more rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH. Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
route_map_result_t ret = RMAP_PERMITMATCH;
struct zebra_rmap_obj rm_obj;
rm_obj.nexthop = nexthop;
rm_obj.re = re;
if (re->type >= 0 && re->type < ZEBRA_ROUTE_MAX) {
rm_name = PROTO_RM_NAME(zvrf, family, re->type);
rmap = PROTO_RM_MAP(zvrf, family, re->type);
if (rm_name && !rmap)
return RMAP_DENYMATCH;
}
if (!rmap) {
rm_name = PROTO_RM_NAME(zvrf, family, ZEBRA_ROUTE_ALL);
rmap = PROTO_RM_MAP(zvrf, family, ZEBRA_ROUTE_ALL);
if (rm_name && !rmap)
return RMAP_DENYMATCH;
}
if (rmap) {
ret = route_map_apply(rmap, p, &rm_obj);
}
return (ret);
}
char *zebra_get_import_table_route_map(afi_t afi, safi_t safi, uint32_t table)
{
return zebra_import_table_routemap[afi][safi][table];
}
void zebra_add_import_table_route_map(afi_t afi, safi_t safi, const char *rmap_name, uint32_t table)
{
zebra_import_table_routemap[afi][safi][table] = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
}
void zebra_del_import_table_route_map(afi_t afi, safi_t safi, uint32_t table)
{
XFREE(MTYPE_ROUTE_MAP_NAME, zebra_import_table_routemap[afi][safi][table]);
}
route_map_result_t zebra_import_table_route_map_check(int family,
struct route_entry *re,
const struct prefix *p,
struct nexthop *nexthop,
const char *rmap_name)
{
struct route_map *rmap = NULL;
route_map_result_t ret = RMAP_DENYMATCH;
struct zebra_rmap_obj rm_obj;
rm_obj.nexthop = nexthop;
rm_obj.re = re;
if (re->type >= 0 && re->type < ZEBRA_ROUTE_MAX)
rmap = route_map_lookup_by_name(rmap_name);
if (rmap) {
ret = route_map_apply(rmap, p, &rm_obj);
}
return (ret);
}
route_map_result_t zebra_nht_route_map_check(afi_t afi, int client_proto,
const struct prefix *p,
struct zebra_vrf *zvrf,
struct route_entry *re,
struct nexthop *nexthop)
{
struct route_map *rmap = NULL;
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP Introducing a 3rd state for route_map_apply library function: RMAP_NOOP Traditionally route map MATCH rule apis were designed to return a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH. (Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR). Depending on this response, the following statemachine decided the course of action: State1: If match cmd returns RMAP_MATCH then, keep existing behaviour. If routemap type is PERMIT, execute set cmds or call cmds if applicable, otherwise PERMIT! Else If routemap type is DENY, we DENYMATCH right away State2: If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH We require a 3rd state because of the following situation: The issue - what if, the rule api needs to abort or ignore a rule?: "match evpn vni xx" route-map filter can be applied to incoming routes regardless of whether the tunnel type is vxlan or mpls. This rule should be N/A for mpls based evpn route, but applicable to only vxlan based evpn route. Also, this rule should be applicable for routes with VNI label only, and not for routes without labels. For example, type 3 and type 4 EVPN routes do not have labels, so, this match cmd should let them through. Today, the filter produces either a match or nomatch response regardless of whether it is mpls/vxlan, resulting in either permitting or denying the route.. So an mpls evpn route may get filtered out incorrectly. Eg: "route-map RM1 permit 10 ; match evpn vni 20" or "route-map RM2 deny 20 ; match vni 20" With the introduction of the 3rd state, we can abort this rule check safely. How? The rules api can now return RMAP_NOOP to indicate that it encountered an invalid check, and needs to abort just that rule, but continue with other rules. As a result we have a 3rd state: State3: If match cmd returned RMAP_NOOP Then, proceed to other route-map, otherwise if there are no more rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH. Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
2019-06-19 23:04:36 +02:00
route_map_result_t ret = RMAP_PERMITMATCH;
struct zebra_rmap_obj rm_obj;
rm_obj.nexthop = nexthop;
rm_obj.re = re;
if (client_proto >= 0 && client_proto < ZEBRA_ROUTE_MAX)
rmap = NHT_RM_MAP(zvrf, afi, client_proto);
if (!rmap && NHT_RM_MAP(zvrf, afi, ZEBRA_ROUTE_MAX))
rmap = NHT_RM_MAP(zvrf, afi, ZEBRA_ROUTE_MAX);
if (rmap)
ret = route_map_apply(rmap, p, &rm_obj);
return ret;
}
static void zebra_route_map_mark_update(const char *rmap_name)
{
/* rmap_update_timer of 0 means don't do route updates */
if (zebra_rmap_update_timer)
EVENT_OFF(zebra_t_rmap_update);
event_add_timer(zrouter.master, zebra_route_map_update_timer, NULL,
zebra_rmap_update_timer, &zebra_t_rmap_update);
}
static void zebra_route_map_add(const char *rmap_name)
{
if (route_map_mark_updated(rmap_name) == 0)
zebra_route_map_mark_update(rmap_name);
route_map_notify_dependencies(rmap_name, RMAP_EVENT_MATCH_ADDED);
}
static void zebra_route_map_delete(const char *rmap_name)
{
if (route_map_mark_updated(rmap_name) == 0)
zebra_route_map_mark_update(rmap_name);
route_map_notify_dependencies(rmap_name, RMAP_EVENT_MATCH_DELETED);
}
static void zebra_route_map_event(const char *rmap_name)
{
if (route_map_mark_updated(rmap_name) == 0)
zebra_route_map_mark_update(rmap_name);
route_map_notify_dependencies(rmap_name, RMAP_EVENT_MATCH_ADDED);
}
void zebra_routemap_vrf_delete(struct zebra_vrf *zvrf)
{
afi_t afi;
uint8_t type;
for (afi = AFI_IP; afi < AFI_MAX; afi++) {
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
if (PROTO_RM_NAME(zvrf, afi, type))
XFREE(MTYPE_ROUTE_MAP_NAME,
PROTO_RM_NAME(zvrf, afi, type));
if (NHT_RM_NAME(zvrf, afi, type))
XFREE(MTYPE_ROUTE_MAP_NAME,
NHT_RM_NAME(zvrf, afi, type));
}
}
}
void zebra_route_map_init(void)
{
install_element(VIEW_NODE, &show_ip_protocol_cmd);
install_element(VIEW_NODE, &show_ipv6_protocol_cmd);
install_element(VIEW_NODE, &show_ip_protocol_nht_cmd);
install_element(VIEW_NODE, &show_ipv6_protocol_nht_cmd);
route_map_init_new(true);
route_map_add_hook(zebra_route_map_add);
route_map_delete_hook(zebra_route_map_delete);
route_map_event_hook(zebra_route_map_event);
route_map_match_interface_hook(generic_match_add);
route_map_no_match_interface_hook(generic_match_delete);
route_map_match_ip_address_hook(generic_match_add);
route_map_no_match_ip_address_hook(generic_match_delete);
route_map_match_ip_address_prefix_list_hook(generic_match_add);
route_map_no_match_ip_address_prefix_list_hook(generic_match_delete);
route_map_match_ip_next_hop_hook(generic_match_add);
route_map_no_match_ip_next_hop_hook(generic_match_delete);
route_map_match_ip_next_hop_prefix_list_hook(generic_match_add);
route_map_no_match_ip_next_hop_prefix_list_hook(generic_match_delete);
route_map_match_ip_next_hop_type_hook(generic_match_add);
route_map_no_match_ip_next_hop_type_hook(generic_match_delete);
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_match_ipv6_next_hop_type_hook(generic_match_add);
route_map_no_match_ipv6_next_hop_type_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);
route_map_install_match(&route_match_ip_next_hop_type_cmd);
route_map_install_match(&route_match_ipv6_next_hop_type_cmd);
route_map_install_match(&route_match_source_protocol_cmd);
route_map_install_match(&route_match_source_instance_cmd);
/* */
route_map_install_set(&route_set_src_cmd);
}