]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_routemap.c
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / bgpd / bgp_routemap.c
index 87e532efbefbfa75fcdfef63c1c1bf6433264b1d..8fd46d00af771347c1648d61f29588c3d78d0a5d 100644 (file)
@@ -1,21 +1,6 @@
+// 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>
@@ -475,8 +460,13 @@ route_match_ip_address(void *rule, const struct prefix *prefix, void *object)
 
        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
@@ -489,6 +479,13 @@ route_match_ip_address(void *rule, const struct prefix *prefix, void *object)
    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);
 }
 
@@ -506,7 +503,7 @@ static const struct route_map_rule_cmd route_match_ip_address_cmd = {
        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
@@ -523,8 +520,14 @@ route_match_ip_next_hop(void *rule, const struct prefix *prefix, void *object)
                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
@@ -577,8 +580,14 @@ route_match_ip_route_source(void *rule, const struct prefix *pfx, void *object)
                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
@@ -666,8 +675,13 @@ route_match_address_prefix_list(void *rule, afi_t afi,
        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,
@@ -722,8 +736,13 @@ route_match_ip_next_hop_prefix_list(void *rule, const struct prefix *prefix,
                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
@@ -766,8 +785,13 @@ route_match_ipv6_next_hop_prefix_list(void *rule, const struct prefix *prefix,
                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;
@@ -866,8 +890,13 @@ route_match_ip_route_source_prefix_list(void *rule, const struct prefix *prefix,
                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
@@ -926,11 +955,21 @@ route_match_mac_address(void *rule, const struct prefix *prefix, void *object)
        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;
@@ -1349,10 +1388,6 @@ static void *route_match_local_pref_compile(const char *arg)
        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)
@@ -2989,11 +3024,11 @@ static void *route_set_origin_compile(const char *arg)
        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;
 }
@@ -3206,8 +3241,14 @@ route_match_ipv6_address(void *rule, const struct prefix *prefix, void *object)
 
        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
@@ -3218,6 +3259,14 @@ route_match_ipv6_address(void *rule, const struct prefix *prefix, void *object)
 
 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);
 }
 
@@ -3249,8 +3298,14 @@ route_match_ipv6_next_hop(void *rule, const struct prefix *prefix, void *object)
                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;
@@ -3332,7 +3387,7 @@ static const struct route_map_rule_cmd route_match_ipv6_next_hop_address_cmd = {
        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)
@@ -3576,17 +3631,29 @@ route_set_ipv6_nexthop_local(void *rule, const struct prefix *p, 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 &&
-           path->attr->mp_nexthop_len != BGP_ATTR_NHLEN_VPNV6_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,
@@ -5835,9 +5902,14 @@ DEFUN_YANG (set_community,
                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))