]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_routemap.c
Merge pull request #3909 from AnuradhaKaruppiah/l3-vni-0
[mirror_frr.git] / bgpd / bgp_routemap.c
index e28acdfbae6170ddb1c15772aaffcd61bb8d978e..c276f5ef7b87ba4dbbd31f26f712f7193d3fda3b 100644 (file)
 #include "bgpd/rfapi/bgp_rfapi_cfg.h"
 #endif
 
+#ifndef VTYSH_EXTRACT_PL
+#include "bgpd/bgp_routemap_clippy.c"
+#endif
+
 /* Memo of route-map commands.
 
 o Cisco route-map
@@ -193,8 +197,6 @@ static void *route_value_compile(const char *arg)
        }
 
        rv = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct rmap_value));
-       if (!rv)
-               return NULL;
 
        rv->action = action;
        rv->variable = var;
@@ -320,8 +322,7 @@ static void route_match_peer_free(void *rule)
 {
        struct bgp_match_peer_compiled *pc = rule;
 
-       if (pc->interface)
-               XFREE(MTYPE_ROUTE_MAP_COMPILED, pc->interface);
+       XFREE(MTYPE_ROUTE_MAP_COMPILED, pc->interface);
 
        XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
 }
@@ -833,8 +834,6 @@ static void *route_match_vni_compile(const char *arg)
        char *end = NULL;
 
        vni = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(vni_t));
-       if (!vni)
-               return NULL;
 
        *vni = strtoul(arg, &end, 10);
        if (*end != '\0') {
@@ -905,6 +904,53 @@ struct route_map_rule_cmd route_match_evpn_route_type_cmd = {
        "evpn route-type", route_match_evpn_route_type,
        route_match_evpn_route_type_compile, route_match_evpn_route_type_free};
 
+/* Route map commands for VRF route leak with source vrf matching */
+static route_map_result_t
+route_match_vrl_source_vrf(void *rule, const struct prefix *prefix,
+                          route_map_object_t type, void *object)
+{
+       struct bgp_path_info *path;
+       char *vrf_name;
+
+       if (type == RMAP_BGP) {
+               vrf_name = rule;
+               path = (struct bgp_path_info *)object;
+
+               if (strncmp(vrf_name, "n/a", VRF_NAMSIZ) == 0)
+                       return RMAP_NOMATCH;
+
+               if (path->extra == NULL)
+                       return RMAP_NOMATCH;
+
+               if (strncmp(vrf_name, vrf_id_to_name(
+                               path->extra->bgp_orig->vrf_id), VRF_NAMSIZ)
+                   == 0)
+                       return RMAP_MATCH;
+       }
+
+       return RMAP_NOMATCH;
+}
+
+static void *route_match_vrl_source_vrf_compile(const char *arg)
+{
+       uint8_t *vrf_name = NULL;
+
+       vrf_name = XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
+
+       return vrf_name;
+}
+
+/* Free route map's compiled `route-type' value. */
+static void route_match_vrl_source_vrf_free(void *rule)
+{
+       XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
+}
+
+struct route_map_rule_cmd route_match_vrl_source_vrf_cmd = {
+       "source-vrf", route_match_vrl_source_vrf,
+       route_match_vrl_source_vrf_compile,
+       route_match_vrl_source_vrf_free};
+
 /* `match local-preference LOCAL-PREF' */
 
 /* Match function return 1 if match is success else return zero. */
@@ -947,9 +993,6 @@ static void *route_match_local_pref_compile(const char *arg)
 
        local_pref = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(uint32_t));
 
-       if (!local_pref)
-               return local_pref;
-
        *local_pref = tmpval;
        return local_pref;
 }
@@ -1504,8 +1547,7 @@ static void route_set_ip_nexthop_free(void *rule)
 {
        struct rmap_ip_nexthop_set *rins = rule;
 
-       if (rins->address)
-               XFREE(MTYPE_ROUTE_MAP_COMPILED, rins->address);
+       XFREE(MTYPE_ROUTE_MAP_COMPILED, rins->address);
 
        XFREE(MTYPE_ROUTE_MAP_COMPILED, rins);
 }
@@ -1995,22 +2037,12 @@ static route_map_result_t route_set_lcommunity_delete(void *rule,
 static void *route_set_lcommunity_delete_compile(const char *arg)
 {
        struct rmap_community *rcom;
-       char *p;
-       char *str;
-       int len;
 
        rcom = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct rmap_community));
 
-       p = strchr(arg, ' ');
-       if (p) {
-               len = p - arg;
-               str = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, len + 1);
-               memcpy(str, arg, len);
-       } else
-               str = NULL;
-
-       rcom->name = str;
+       rcom->name = XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
        rcom->name_hash = bgp_clist_hash_key(rcom->name);
+
        return rcom;
 }
 
@@ -2090,22 +2122,12 @@ static route_map_result_t route_set_community_delete(
 static void *route_set_community_delete_compile(const char *arg)
 {
        struct rmap_community *rcom;
-       char *p;
-       char *str;
-       int len;
 
        rcom = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct rmap_community));
 
-       p = strchr(arg, ' ');
-       if (p) {
-               len = p - arg;
-               str = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, len + 1);
-               memcpy(str, arg, len);
-       } else
-               str = NULL;
-
-       rcom->name = str;
+       rcom->name = XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
        rcom->name_hash = bgp_clist_hash_key(rcom->name);
+
        return rcom;
 }
 
@@ -3054,10 +3076,8 @@ static int bgp_route_match_delete(struct vty *vty, const char *command,
                break;
        }
 
-       if (dep_name)
-               XFREE(MTYPE_ROUTE_MAP_RULE, dep_name);
-       if (rmap_name)
-               XFREE(MTYPE_ROUTE_MAP_NAME, rmap_name);
+       XFREE(MTYPE_ROUTE_MAP_RULE, dep_name);
+       XFREE(MTYPE_ROUTE_MAP_NAME, rmap_name);
 
        return retval;
 }
@@ -3348,7 +3368,7 @@ static void bgp_route_map_process_update(struct bgp *bgp, const char *rmap_name,
                                "Processing route_map %s update on advertise type5 route command",
                                rmap_name);
 
-               if (route_update) {
+               if (route_update && advertise_type5_routes(bgp, afi)) {
                        bgp_evpn_withdraw_type5_routes(bgp, afi, safi);
                        bgp_evpn_advertise_type5_routes(bgp, afi, safi);
                }
@@ -3538,6 +3558,29 @@ DEFUN (no_match_evpn_default_route,
                                      RMAP_EVENT_MATCH_DELETED);
 }
 
+DEFPY(match_vrl_source_vrf,
+      match_vrl_source_vrf_cmd,
+      "match source-vrf NAME$vrf_name",
+      MATCH_STR
+      "source vrf\n"
+      "The VRF name\n")
+{
+       return bgp_route_match_add(vty, "source-vrf", vrf_name,
+                                  RMAP_EVENT_MATCH_ADDED);
+}
+
+DEFPY(no_match_vrl_source_vrf,
+      no_match_vrl_source_vrf_cmd,
+      "no match source-vrf NAME$vrf_name",
+      NO_STR
+      MATCH_STR
+      "source vrf\n"
+      "The VRF name\n")
+{
+       return bgp_route_match_delete(vty, "source-vrf", vrf_name,
+                                     RMAP_EVENT_MATCH_DELETED);
+}
+
 DEFUN (match_peer,
        match_peer_cmd,
        "match peer <A.B.C.D|X:X::X:X|WORD>",
@@ -4277,17 +4320,10 @@ DEFUN (set_community_delete,
        "Delete matching communities\n")
 {
        int idx_comm_list = 2;
-       char *str;
-
-       str = XCALLOC(MTYPE_TMP,
-                     strlen(argv[idx_comm_list]->arg) + strlen(" delete") + 1);
-       strcpy(str, argv[idx_comm_list]->arg);
-       strcpy(str + strlen(argv[idx_comm_list]->arg), " delete");
 
        generic_set_add(vty, VTY_GET_CONTEXT(route_map_index), "comm-list",
-                       str);
+                       argv[idx_comm_list]->arg);
 
-       XFREE(MTYPE_TMP, str);
        return CMD_SUCCESS;
 }
 
@@ -4376,16 +4412,9 @@ DEFUN (set_lcommunity_delete,
        "Large Community-list name\n"
        "Delete matching large communities\n")
 {
-       char *str;
-
-       str = XCALLOC(MTYPE_TMP, strlen(argv[2]->arg) + strlen(" delete") + 1);
-       strcpy(str, argv[2]->arg);
-       strcpy(str + strlen(argv[2]->arg), " delete");
-
        generic_set_add(vty, VTY_GET_CONTEXT(route_map_index),
-                       "large-comm-list", str);
+                       "large-comm-list", argv[2]->arg);
 
-       XFREE(MTYPE_TMP, str);
        return CMD_SUCCESS;
 }
 
@@ -4992,6 +5021,7 @@ void bgp_route_map_init(void)
        route_map_install_match(&route_match_evpn_vni_cmd);
        route_map_install_match(&route_match_evpn_route_type_cmd);
        route_map_install_match(&route_match_evpn_default_route_cmd);
+       route_map_install_match(&route_match_vrl_source_vrf_cmd);
 
        route_map_install_set(&route_set_ip_nexthop_cmd);
        route_map_install_set(&route_set_local_pref_cmd);
@@ -5030,6 +5060,8 @@ void bgp_route_map_init(void)
        install_element(RMAP_NODE, &no_match_evpn_route_type_cmd);
        install_element(RMAP_NODE, &match_evpn_default_route_cmd);
        install_element(RMAP_NODE, &no_match_evpn_default_route_cmd);
+       install_element(RMAP_NODE, &match_vrl_source_vrf_cmd);
+       install_element(RMAP_NODE, &no_match_vrl_source_vrf_cmd);
 
        install_element(RMAP_NODE, &match_aspath_cmd);
        install_element(RMAP_NODE, &no_match_aspath_cmd);