+// SPDX-License-Identifier: GPL-2.0-or-later
/* Route map function of bgpd.
* Copyright (C) 1998, 1999 Kunihiro Ishiguro
- *
- * This file is part of GNU Zebra.
- *
- * GNU Zebra is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * GNU Zebra is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; see the file COPYING; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <zebra.h>
{
struct aspath *aspath;
- aspath = aspath_str2aspath(arg);
+ aspath = aspath_str2aspath(arg, bgp_get_asnotation(NULL));
if (!aspath)
return NULL;
return aspath;
if (prefix->family == AF_INET) {
alist = access_list_lookup(AFI_IP, (char *)rule);
- if (alist == NULL)
+ if (alist == NULL) {
+ if (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
access-list name. */
static void *route_match_ip_address_compile(const char *arg)
{
+ struct access_list *alist;
+
+ alist = access_list_lookup(AFI_IP, arg);
+ if (!alist)
+ zlog_warn(
+ "Access List specified %s does not exist yet, default will be NO_MATCH until it is created",
+ arg);
return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
}
route_match_ip_address_free
};
-/* `match ip next-hop IP_ADDRESS' */
+/* `match ip next-hop <IP_ADDRESS_ACCESS_LIST_NAME>' */
/* Match function return 1 if match is success else return zero. */
static enum route_map_cmd_result_t
p.prefixlen = IPV4_MAX_BITLEN;
alist = access_list_lookup(AFI_IP, (char *)rule);
- if (alist == NULL)
+ if (alist == NULL) {
+ if (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
p.prefixlen = IPV4_MAX_BITLEN;
alist = access_list_lookup(AFI_IP, (char *)rule);
- if (alist == NULL)
+ if (alist == NULL) {
+ if (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
struct prefix_list *plist;
plist = prefix_list_lookup(afi, (char *)rule);
- if (plist == NULL)
+ if (plist == NULL) {
+ if (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;
+ }
if (prefix->family == AF_FLOWSPEC)
return route_match_prefix_list_flowspec(afi, plist,
p.prefixlen = IPV4_MAX_BITLEN;
plist = prefix_list_lookup(AFI_IP, (char *)rule);
- if (plist == NULL)
+ if (plist == NULL) {
+ if (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
p.prefixlen = IPV6_MAX_BITLEN;
plist = prefix_list_lookup(AFI_IP6, (char *)rule);
- if (!plist)
+ if (!plist) {
+ if (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;
+ }
if (prefix_list_apply(plist, &p) == PREFIX_PERMIT)
return RMAP_MATCH;
p.prefixlen = IPV4_MAX_BITLEN;
plist = prefix_list_lookup(AFI_IP, (char *)rule);
- if (plist == NULL)
+ if (plist == NULL) {
+ if (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
struct prefix p;
alist = access_list_lookup(AFI_L2VPN, (char *)rule);
- if (alist == NULL)
- return RMAP_NOMATCH;
+ if (alist == NULL) {
+ if (CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL))
+ zlog_debug(
+ "%s: Access-List Specified: %s does not exist defaulting to NO_MATCH",
+ __func__, (char *)rule);
- if (prefix->u.prefix_evpn.route_type != BGP_EVPN_MAC_IP_ROUTE)
return RMAP_NOMATCH;
+ }
+ if (prefix->u.prefix_evpn.route_type != BGP_EVPN_MAC_IP_ROUTE) {
+ if (CHECK_FLAG(rmap_debug, DEBUG_ROUTEMAP_DETAIL))
+ zlog_debug(
+ "%s: Prefix %pFX is not a EVPN MAC IP ROUTE defaulting to NO_MATCH",
+ __func__, prefix);
+ return RMAP_NOMATCH;
+ }
p.family = AF_ETHERNET;
p.prefixlen = ETH_ALEN * 8;
char *endptr = NULL;
unsigned long tmpval;
- /* Locpref value shoud be integer. */
- if (!all_digit(arg))
- return NULL;
-
errno = 0;
tmpval = strtoul(arg, &endptr, 10);
if (*endptr != '\0' || errno || tmpval > UINT32_MAX)
origin = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(uint8_t));
if (strcmp(arg, "igp") == 0)
- *origin = 0;
+ *origin = BGP_ORIGIN_IGP;
else if (strcmp(arg, "egp") == 0)
- *origin = 1;
+ *origin = BGP_ORIGIN_EGP;
else
- *origin = 2;
+ *origin = BGP_ORIGIN_INCOMPLETE;
return origin;
}
if (prefix->family == AF_INET6) {
alist = access_list_lookup(AFI_IP6, (char *)rule);
- if (alist == NULL)
+ if (alist == NULL) {
+ if (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
static void *route_match_ipv6_address_compile(const char *arg)
{
+ struct access_list *alist;
+
+ alist = access_list_lookup(AFI_IP6, arg);
+ if (!alist)
+ zlog_warn(
+ "Access List specified %s does not exist yet, default will be NO_MATCH until it is created",
+ arg);
+
return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
}
p.prefixlen = IPV6_MAX_BITLEN;
alist = access_list_lookup(AFI_IP6, (char *)rule);
- if (!alist)
+ if (!alist) {
+ if (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;
+ }
if (access_list_apply(alist, &p) == FILTER_PERMIT)
return RMAP_MATCH;
route_match_ipv6_next_hop_address_free
};
-/* `match ip next-hop IP_ADDRESS' */
+/* `match ip next-hop address IP_ADDRESS' */
static enum route_map_cmd_result_t
route_match_ipv4_next_hop(void *rule, const struct prefix *prefix, void *object)
{
struct in6_addr *address;
struct bgp_path_info *path;
+ struct bgp_dest *dest;
+ struct bgp_table *table = NULL;
/* Fetch routemap's rule information. */
address = rule;
path = object;
+ dest = path->net;
+
+ if (!dest)
+ return RMAP_OKAY;
+
+ table = bgp_dest_table(dest);
+ if (!table)
+ return RMAP_OKAY;
/* Set next hop value. */
path->attr->mp_nexthop_local = *address;
/* Set nexthop length. */
- if (path->attr->mp_nexthop_len != BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
+ if (table->safi == SAFI_MPLS_VPN || table->safi == SAFI_ENCAP ||
+ table->safi == SAFI_EVPN)
+ path->attr->mp_nexthop_len = BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL;
+ else
path->attr->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
SET_FLAG(path->attr->rmap_change_flags,
DEFUN_YANG (set_aspath_prepend_asn,
set_aspath_prepend_asn_cmd,
- "set as-path prepend (1-4294967295)...",
+ "set as-path prepend ASNUM...",
SET_STR
"Transform BGP AS_PATH attribute\n"
"Prepend to the as-path\n"
- "AS number\n")
+ AS_STR)
{
int idx_asn = 3;
int ret;
char *str;
+ struct aspath *aspath;
str = argv_concat(argv, argc, idx_asn);
"./set-action[action='frr-bgp-route-map:as-path-prepend']";
char xpath_value[XPATH_MAXLEN];
+ aspath = route_aspath_compile(str);
+ if (!aspath) {
+ vty_out(vty, "%% Invalid AS path value %s\n", str);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ route_aspath_free(aspath);
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
snprintf(xpath_value, sizeof(xpath_value),
"%s/rmap-set-action/frr-bgp-route-map:prepend-as-path", xpath);
DEFPY_YANG (set_aspath_replace_asn,
set_aspath_replace_asn_cmd,
- "set as-path replace <any|(1-4294967295)>$replace",
+ "set as-path replace <any|ASNUM>$replace",
SET_STR
"Transform BGP AS_PATH attribute\n"
"Replace AS number to local AS number\n"
"Replace any AS number to local AS number\n"
- "Replace a specific AS number to local AS number\n")
+ "Replace a specific AS number in plain or dotted format to local AS number\n")
{
const char *xpath =
"./set-action[action='frr-bgp-route-map:as-path-replace']";
char xpath_value[XPATH_MAXLEN];
+ as_t as_value;
+
+ if (!strmatch(replace, "any") && !asn_str2asn(replace, &as_value)) {
+ vty_out(vty, "%% Invalid AS value %s\n", replace);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
snprintf(xpath_value, sizeof(xpath_value),
DEFPY_YANG (no_set_aspath_replace_asn,
no_set_aspath_replace_asn_cmd,
- "no set as-path replace [<any|(1-4294967295)>]",
+ "no set as-path replace [<any|ASNUM>]",
NO_STR
SET_STR
"Transform BGP AS_PATH attribute\n"
"Replace AS number to local AS number\n"
"Replace any AS number to local AS number\n"
- "Replace a specific AS number to local AS number\n")
+ "Replace a specific AS number in plain or dotted format to local AS number\n")
{
const char *xpath =
"./set-action[action='frr-bgp-route-map:as-path-replace']";
DEFUN_YANG (no_set_aspath_prepend,
no_set_aspath_prepend_cmd,
- "no set as-path prepend [(1-4294967295)]",
+ "no set as-path prepend [ASNUM]",
NO_STR
SET_STR
"Transform BGP AS_PATH attribute\n"
"Prepend to the as-path\n"
- "AS number\n")
+ AS_STR)
{
const char *xpath =
"./set-action[action='frr-bgp-route-map:as-path-prepend']";
DEFUN_YANG (set_aspath_exclude,
set_aspath_exclude_cmd,
- "set as-path exclude (1-4294967295)...",
+ "set as-path exclude ASNUM...",
SET_STR
"Transform BGP AS-path attribute\n"
"Exclude from the as-path\n"
- "AS number\n")
+ AS_STR)
{
int idx_asn = 3;
int ret;
char *str;
+ struct aspath *aspath;
str = argv_concat(argv, argc, idx_asn);
"./set-action[action='frr-bgp-route-map:as-path-exclude']";
char xpath_value[XPATH_MAXLEN];
+ aspath = route_aspath_compile(str);
+ if (!aspath) {
+ vty_out(vty, "%% Invalid AS path value %s\n", str);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ route_aspath_free(aspath);
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
snprintf(xpath_value, sizeof(xpath_value),
"%s/rmap-set-action/frr-bgp-route-map:exclude-as-path", xpath);
DEFUN_YANG (no_set_aspath_exclude,
no_set_aspath_exclude_cmd,
- "no set as-path exclude (1-4294967295)...",
+ "no set as-path exclude ASNUM...",
NO_STR
SET_STR
"Transform BGP AS_PATH attribute\n"
else
first = 1;
+#if CONFDATE > 20230801
+CPP_NOTICE("Deprecate COMMUNITY_INTERNET BGP community")
+#endif
if (strncmp(argv[i]->arg, "internet", strlen(argv[i]->arg))
== 0) {
buffer_putstr(b, "internet");
+ vty_out(vty, "%% `internet` community is deprecated\n");
+ zlog_warn("`internet` community is deprecated");
continue;
}
if (strncmp(argv[i]->arg, "local-AS", strlen(argv[i]->arg))
DEFUN_YANG (set_aggregator_as,
set_aggregator_as_cmd,
- "set aggregator as (1-4294967295) A.B.C.D",
+ "set aggregator as ASNUM A.B.C.D",
SET_STR
"BGP aggregator attribute\n"
"AS number of aggregator\n"
- "AS number\n"
+ AS_STR
"IP address of aggregator\n")
{
int idx_number = 3;
char xpath_addr[XPATH_MAXLEN];
const char *xpath =
"./set-action[action='frr-bgp-route-map:aggregator']";
+ as_t as_value;
+
+ if (!asn_str2asn(argv[idx_number]->arg, &as_value)) {
+ vty_out(vty, "%% Invalid AS value %s\n", argv[idx_number]->arg);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
DEFUN_YANG (no_set_aggregator_as,
no_set_aggregator_as_cmd,
- "no set aggregator as [(1-4294967295) A.B.C.D]",
+ "no set aggregator as [ASNUM A.B.C.D]",
NO_STR
SET_STR
"BGP aggregator attribute\n"
"AS number of aggregator\n"
- "AS number\n"
+ AS_STR
"IP address of aggregator\n")
{
const char *xpath =