]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_routemap.c
Merge pull request #8982 from dlqs/lua-func-stack
[mirror_frr.git] / bgpd / bgp_routemap.c
index 4b71ba30ce58d997c483a4920e89130ba7c8c718..09dd71c0205db663675e758b911b9a6a659b6ed8 100644 (file)
@@ -52,6 +52,7 @@
 #include "bgpd/bgp_zebra.h"
 #include "bgpd/bgp_regex.h"
 #include "bgpd/bgp_community.h"
+#include "bgpd/bgp_community_alias.h"
 #include "bgpd/bgp_clist.h"
 #include "bgpd/bgp_filter.h"
 #include "bgpd/bgp_mplsvpn.h"
@@ -1180,6 +1181,55 @@ static const struct route_map_rule_cmd route_match_vrl_source_vrf_cmd = {
        route_match_vrl_source_vrf_free
 };
 
+/* `match alias` */
+static enum route_map_cmd_result_t
+route_match_alias(void *rule, const struct prefix *prefix, void *object)
+{
+       char *alias = rule;
+       struct bgp_path_info *path = object;
+       char **communities;
+       int num;
+
+       if (path->attr->community) {
+               frrstr_split(path->attr->community->str, " ", &communities,
+                            &num);
+               for (int i = 0; i < num; i++) {
+                       const char *com2alias =
+                               bgp_community2alias(communities[i]);
+                       if (strcmp(alias, com2alias) == 0)
+                               return RMAP_MATCH;
+               }
+       }
+
+       if (path->attr->lcommunity) {
+               frrstr_split(path->attr->lcommunity->str, " ", &communities,
+                            &num);
+               for (int i = 0; i < num; i++) {
+                       const char *com2alias =
+                               bgp_community2alias(communities[i]);
+                       if (strcmp(alias, com2alias) == 0)
+                               return RMAP_MATCH;
+               }
+       }
+
+       return RMAP_NOMATCH;
+}
+
+static void *route_match_alias_compile(const char *arg)
+{
+
+       return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
+}
+
+static void route_match_alias_free(void *rule)
+{
+       XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
+}
+
+static const struct route_map_rule_cmd route_match_alias_cmd = {
+       "alias", route_match_alias, route_match_alias_compile,
+       route_match_alias_free};
+
 /* `match local-preference LOCAL-PREF' */
 
 /* Match function return 1 if match is success else return zero. */
@@ -4598,6 +4648,58 @@ DEFUN_YANG (no_match_local_pref,
        return nb_cli_apply_changes(vty, NULL);
 }
 
+DEFUN_YANG(match_alias, match_alias_cmd, "match alias ALIAS_NAME",
+          MATCH_STR
+          "Match BGP community alias name\n"
+          "BGP community alias name\n")
+{
+       const char *alias = argv[2]->arg;
+       struct community_alias ca1;
+       struct community_alias *lookup_alias;
+
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:match-alias']";
+       char xpath_value[XPATH_MAXLEN];
+
+       memset(&ca1, 0, sizeof(ca1));
+       strlcpy(ca1.alias, alias, sizeof(ca1.alias));
+       lookup_alias = bgp_ca_alias_lookup(&ca1);
+       if (!lookup_alias) {
+               vty_out(vty, "%% BGP alias name '%s' does not exist\n", alias);
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-match-condition/frr-bgp-route-map:alias", xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, alias);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+
+DEFUN_YANG(no_match_alias, no_match_alias_cmd, "no match alias [ALIAS_NAME]",
+          NO_STR MATCH_STR
+          "Match BGP community alias name\n"
+          "BGP community alias name\n")
+{
+       int idx_alias = 3;
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:match-alias']";
+       char xpath_value[XPATH_MAXLEN];
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+
+       if (argc <= idx_alias)
+               return nb_cli_apply_changes(vty, NULL);
+
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-match-condition/frr-bgp-route-map:alias", xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY,
+                             argv[idx_alias]->arg);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
 
 DEFPY_YANG (match_community,
        match_community_cmd,
@@ -6287,6 +6389,7 @@ void bgp_route_map_init(void)
        route_map_no_set_tag_hook(generic_set_delete);
 
        route_map_install_match(&route_match_peer_cmd);
+       route_map_install_match(&route_match_alias_cmd);
        route_map_install_match(&route_match_local_pref_cmd);
 #ifdef HAVE_SCRIPTING
        route_map_install_match(&route_match_script_cmd);
@@ -6371,6 +6474,8 @@ void bgp_route_map_init(void)
        install_element(RMAP_NODE, &no_match_aspath_cmd);
        install_element(RMAP_NODE, &match_local_pref_cmd);
        install_element(RMAP_NODE, &no_match_local_pref_cmd);
+       install_element(RMAP_NODE, &match_alias_cmd);
+       install_element(RMAP_NODE, &no_match_alias_cmd);
        install_element(RMAP_NODE, &match_community_cmd);
        install_element(RMAP_NODE, &no_match_community_cmd);
        install_element(RMAP_NODE, &match_lcommunity_cmd);