#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
}
rv = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct rmap_value));
- if (!rv)
- return NULL;
rv->action = action;
rv->variable = var;
{
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);
}
char *end = NULL;
vni = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(vni_t));
- if (!vni)
- return NULL;
*vni = strtoul(arg, &end, 10);
if (*end != '\0') {
"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. */
local_pref = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(uint32_t));
- if (!local_pref)
- return local_pref;
-
*local_pref = tmpval;
return local_pref;
}
{
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);
}
static void *route_set_lcommunity_delete_compile(const char *arg)
{
struct rmap_community *rcom;
- char *p;
- char *str;
- int len;
+ char **splits;
+ int num;
+
+ frrstr_split(arg, " ", &splits, &num);
rcom = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct rmap_community));
+ rcom->name = XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, splits[0]);
+ rcom->name_hash = bgp_clist_hash_key(rcom->name);
- p = strchr(arg, ' ');
- if (p) {
- len = p - arg;
- str = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, len + 1);
- memcpy(str, arg, len);
- } else
- str = NULL;
+ for (int i = 0; i < num; i++)
+ XFREE(MTYPE_TMP, splits[i]);
+ XFREE(MTYPE_TMP, splits);
- rcom->name = str;
- rcom->name_hash = bgp_clist_hash_key(rcom->name);
return rcom;
}
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;
}
&& peer->su_remote
&& sockunion_family(peer->su_remote) == AF_INET6) {
/* Set next hop preference to global */
- path->attr->mp_nexthop_prefer_global = TRUE;
+ path->attr->mp_nexthop_prefer_global = true;
SET_FLAG(path->attr->rmap_change_flags,
BATTR_RMAP_IPV6_PREFER_GLOBAL_CHANGED);
} else {
- path->attr->mp_nexthop_prefer_global = FALSE;
+ path->attr->mp_nexthop_prefer_global = false;
SET_FLAG(path->attr->rmap_change_flags,
BATTR_RMAP_IPV6_PREFER_GLOBAL_CHANGED);
}
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;
}
if (bgp->table_map[afi][safi].name
&& (strcmp(rmap_name, bgp->table_map[afi][safi].name)
== 0)) {
+
+ /* bgp->table_map[afi][safi].map is NULL.
+ * i.e Route map creation event.
+ * So update applied_counter.
+ * If it is not NULL, i.e It may be routemap updation or
+ * deletion. so no need to update the counter.
+ */
+ if (!bgp->table_map[afi][safi].map)
+ route_map_counter_increment(map);
bgp->table_map[afi][safi].map = map;
if (BGP_DEBUG(zebra, ZEBRA))
|| (strcmp(rmap_name, bgp_static->rmap.name) != 0))
continue;
+ if (!bgp_static->rmap.map)
+ route_map_counter_increment(map);
+
bgp_static->rmap.map = map;
if (route_update && !bgp_static->backdoor) {
|| (strcmp(rmap_name, red->rmap.name) != 0))
continue;
+ if (!red->rmap.map)
+ route_map_counter_increment(map);
+
red->rmap.map = map;
if (!route_update)
!= 0)
continue;
+ /* Make sure the route-map is populated here if not already done */
+ bgp->adv_cmd_rmap[afi][safi].map = map;
+
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug(
"Processing route_map %s update on advertise type5 route command",
rmap_name);
- bgp_evpn_withdraw_type5_routes(bgp, afi, safi);
- bgp_evpn_advertise_type5_routes(bgp, afi, safi);
+
+ if (route_update && advertise_type5_routes(bgp, afi)) {
+ bgp_evpn_withdraw_type5_routes(bgp, afi, safi);
+ bgp_evpn_advertise_type5_routes(bgp, afi, safi);
+ }
}
}
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>",
"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");
+ char *args;
+ args = argv_concat(argv, argc, idx_comm_list);
generic_set_add(vty, VTY_GET_CONTEXT(route_map_index), "comm-list",
- str);
+ args);
+ XFREE(MTYPE_TMP, args);
- XFREE(MTYPE_TMP, str);
return CMD_SUCCESS;
}
"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");
+ int idx_lcomm_list = 2;
+ char *args;
+ args = argv_concat(argv, argc, idx_lcomm_list);
generic_set_add(vty, VTY_GET_CONTEXT(route_map_index),
- "large-comm-list", str);
+ "large-comm-list", args);
+ XFREE(MTYPE_TMP, args);
- XFREE(MTYPE_TMP, str);
return CMD_SUCCESS;
}
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);
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);