]> git.puffer.fish Git - mirror/frr.git/commitdiff
bgpd: provide a match clause to match EVPN default route
authorMitesh Kanjariya <mitesh@marvel-07.cumulusnetworks.com>
Thu, 22 Feb 2018 06:02:07 +0000 (22:02 -0800)
committermitesh <mitesh@cumulusnetworks.com>
Fri, 23 Feb 2018 01:42:07 +0000 (17:42 -0800)
A Border Leaf can originate a default route
for all the leafs within the POD.
However, we do not want to advertise this route outside the POD.
Therefore, we provide an option
to filter a EVPN type5 default route through a route-map.

Signed-off-by: Mitesh Kanjariya <mitesh@cumulusnetworks.com>
0001-bgpd-support-for-default-originate-type-5-route.patch [deleted file]
bgpd/bgp_evpn_private.h
bgpd/bgp_routemap.c

diff --git a/0001-bgpd-support-for-default-originate-type-5-route.patch b/0001-bgpd-support-for-default-originate-type-5-route.patch
deleted file mode 100644 (file)
index 9212108..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-From dbc3fbc612ce6523a596804c270600de1f6f2309 Mon Sep 17 00:00:00 2001
-From: Mitesh Kanjariya <mitesh@marvel-07.cumulusnetworks.com>
-Date: Thu, 15 Feb 2018 17:20:27 -0800
-Subject: [PATCH] bgpd: support for default-originate type-5 route
-
-Implement support for 'default-originate' for L2VPN/EVPN address family.
-This is needed for the case where external routing within a POD,
-will follow the default route to the border/exit leaf.
-The border/exit leaf has more than one next hop to forward the packet on to,
-depending on the destination IP.
-
-Signed-off-by: Mitesh Kanjariya <mitesh@cumulusnetworks.com>
----
- bgpd/bgp_evpn_private.h | 14 ++++++++
- bgpd/bgp_evpn_vty.c     | 89 +++++++++++++++++++++++++++++++++++++++++++++++++
- bgpd/bgpd.h             |  2 ++
- 3 files changed, 105 insertions(+)
-
-diff --git a/bgpd/bgp_evpn_private.h b/bgpd/bgp_evpn_private.h
-index 5ff16c3..bc68e25 100644
---- a/bgpd/bgp_evpn_private.h
-+++ b/bgpd/bgp_evpn_private.h
-@@ -349,6 +349,20 @@ static inline void build_evpn_type3_prefix(struct prefix_evpn *p,
-       p->prefix.ip.ipaddr_v4 = originator_ip;
- }
-+static inline int evpn_default_originate_set(struct bgp *bgp, afi_t afi,
-+                                           safi_t safi)
-+{
-+      if (afi == AFI_IP &&
-+          CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
-+                     BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV4))
-+              return 1;
-+      else if (afi == AFI_IP6 &&
-+               CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
-+                          BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV6))
-+              return 1;
-+      return 0;
-+}
-+
- extern void evpn_rt_delete_auto(struct bgp*, vni_t, struct list*);
- extern void bgp_evpn_configure_export_rt_for_vrf(struct bgp *bgp_vrf,
-                                                struct ecommunity *ecomadd);
-diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c
-index 1720744..5ce71db 100644
---- a/bgpd/bgp_evpn_vty.c
-+++ b/bgpd/bgp_evpn_vty.c
-@@ -2476,6 +2476,48 @@ static void evpn_unset_advertise_default_gw(struct bgp *bgp,
- /*
-  * evpn - enable advertisement of default g/w
-  */
-+static void evpn_process_default_originate_cmd(struct bgp *bgp_vrf,
-+                                             afi_t afi, int add)
-+{
-+      struct prefix ip_prefix;
-+      safi_t safi = SAFI_UNICAST; /* ipv4/ipv6 unicast */
-+
-+      /* form the default prefix 0.0.0.0/0 */
-+      memset(&ip_prefix, 0, sizeof(struct prefix));
-+      ip_prefix.family = afi2family(afi);
-+      ip_prefix.prefixlen = 0;
-+
-+      if (add) {
-+              /* bail if we are already advertising default route */
-+              if (evpn_default_originate_set(bgp_vrf, afi, safi))
-+                      return;
-+
-+              if (afi == AFI_IP)
-+                      SET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
-+                               BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV4);
-+              else if (afi == AFI_IP6)
-+                      SET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
-+                               BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV6);
-+              bgp_evpn_advertise_type5_route(bgp_vrf, &ip_prefix,
-+                                             NULL, afi, safi);
-+      } else {
-+              /* bail out if we havent advertised the default route */
-+              if (!evpn_default_originate_set(bgp_vrf, afi, safi))
-+                      return;
-+              if (afi == AFI_IP)
-+                      UNSET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
-+                                 BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV4);
-+              else if (afi == AFI_IP6)
-+                      UNSET_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
-+                                 BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV6);
-+              bgp_evpn_withdraw_type5_route(bgp_vrf, &ip_prefix,
-+                                            afi, safi);
-+      }
-+}
-+
-+/*
-+ * evpn - enable advertisement of default g/w
-+ */
- static void evpn_set_advertise_subnet(struct bgp *bgp,
-                                     struct bgpevpn *vpn)
- {
-@@ -2671,6 +2713,43 @@ DEFUN (no_bgp_evpn_advertise_all_vni,
-       return CMD_SUCCESS;
- }
-+DEFUN (bgp_evpn_default_originate,
-+       bgp_evpn_default_originate_cmd,
-+       "default-originate <ipv4 | ipv6>",
-+       "originate a default route\n"
-+       "ipv4 address family\n"
-+       "ipv6 address family\n")
-+{
-+      afi_t afi = 0;
-+      int idx_afi = 0;
-+      struct bgp *bgp_vrf = VTY_GET_CONTEXT(bgp);
-+
-+      if (!bgp_vrf)
-+              return CMD_WARNING;
-+      argv_find_and_parse_afi(argv, argc, &idx_afi, &afi);
-+      evpn_process_default_originate_cmd(bgp_vrf, afi, 1);
-+      return CMD_SUCCESS;
-+}
-+
-+DEFUN (no_bgp_evpn_default_originate,
-+       no_bgp_evpn_default_originate_cmd,
-+       "no default-originate <ipv4 | ipv6>",
-+       NO_STR
-+       "withdraw a default route\n"
-+       "ipv4 address family\n"
-+       "ipv6 address family\n")
-+{
-+      afi_t afi = 0;
-+      int idx_afi = 0;
-+      struct bgp *bgp_vrf = VTY_GET_CONTEXT(bgp);
-+
-+      if (!bgp_vrf)
-+              return CMD_WARNING;
-+      argv_find_and_parse_afi(argv, argc, &idx_afi, &afi);
-+      evpn_process_default_originate_cmd(bgp_vrf, afi, 0);
-+      return CMD_SUCCESS;
-+}
-+
- DEFUN (bgp_evpn_advertise_vni_subnet,
-        bgp_evpn_advertise_vni_subnet_cmd,
-        "advertise-subnet",
-@@ -4382,6 +4461,14 @@ void bgp_config_write_evpn_info(struct vty *vty, struct bgp *bgp, afi_t afi,
-       if (CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
-                      BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST))
-               vty_out(vty, "  advertise ipv6 unicast\n");
-+
-+      if (CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
-+                     BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV4))
-+              vty_out(vty, "  default-originate ipv4\n");
-+
-+      if (CHECK_FLAG(bgp->af_flags[AFI_L2VPN][SAFI_EVPN],
-+                     BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV6))
-+              vty_out(vty, "  default-originate ipv6\n");
- }
- void bgp_ethernetvpn_init(void)
-@@ -4411,6 +4498,8 @@ void bgp_ethernetvpn_init(void)
-       install_element(BGP_EVPN_NODE, &no_bgp_evpn_advertise_default_gw_cmd);
-       install_element(BGP_EVPN_NODE, &bgp_evpn_advertise_type5_cmd);
-       install_element(BGP_EVPN_NODE, &no_bgp_evpn_advertise_type5_cmd);
-+      install_element(BGP_EVPN_NODE, &bgp_evpn_default_originate_cmd);
-+      install_element(BGP_EVPN_NODE, &no_bgp_evpn_default_originate_cmd);
-       /* "show bgp l2vpn evpn" commands. */
-       install_element(VIEW_NODE, &show_bgp_l2vpn_evpn_vni_cmd);
-diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
-index 5b77be2..274ca82 100644
---- a/bgpd/bgpd.h
-+++ b/bgpd/bgpd.h
-@@ -323,6 +323,8 @@ struct bgp {
- /* l2vpn evpn flags */
- #define BGP_L2VPN_EVPN_ADVERTISE_IPV4_UNICAST      (1 << 0)
- #define BGP_L2VPN_EVPN_ADVERTISE_IPV6_UNICAST      (1 << 1)
-+#define BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV4    (1 << 2)
-+#define BGP_L2VPN_EVPN_DEFAULT_ORIGINATE_IPV6    (1 << 3)
-       /* Route table for next-hop lookup cache. */
--- 
-2.7.4
-
index bc68e259b60234c52bd6ac14d125184e18f5f513..4b2742058beefabaedacba2d0ebd770e35a8460f 100644 (file)
@@ -280,6 +280,14 @@ static inline void ip_prefix_from_type5_prefix(struct prefix_evpn *evp,
        }
 }
 
+static inline int is_evpn_prefix_default(struct prefix *evp)
+{
+       if (evp->family != AF_EVPN)
+               return 0;
+
+       return ((evp->u.prefix_evpn.ip_prefix_length  == 0) ? 1 : 0);
+}
+
 static inline void ip_prefix_from_type2_prefix(struct prefix_evpn *evp,
                                               struct prefix *ip)
 {
index 4d5624d3b0027a6d501aa4ab55dc025dc37336ea..b3cd4b7af7c89bc047c39714b85ebf6fb76e16e9 100644 (file)
@@ -594,6 +594,24 @@ struct route_map_rule_cmd route_match_ip_route_source_prefix_list_cmd = {
        route_match_ip_route_source_prefix_list_compile,
        route_match_ip_route_source_prefix_list_free};
 
+/* `match evpn default-route' */
+
+/* Match function should return 1 if match is success else 0 */
+static route_map_result_t route_match_evpn_default_route(void *rule,
+                                                        struct prefix *p,
+                                                        route_map_object_t
+                                                        type, void *object)
+{
+       if (type == RMAP_BGP && is_evpn_prefix_default(p))
+               return RMAP_MATCH;
+
+       return RMAP_NOMATCH;
+}
+
+/* Route map commands for default-route matching. */
+struct route_map_rule_cmd route_match_evpn_default_route_cmd = {
+       "evpn default-route", route_match_evpn_default_route, NULL, NULL};
+
 /* `match mac address MAC_ACCESS_LIST' */
 
 /* Match function should return 1 if match is success else return
@@ -3249,6 +3267,29 @@ DEFUN (no_match_evpn_vni,
                                      RMAP_EVENT_MATCH_DELETED);
 }
 
+DEFUN (match_evpn_default_route,
+       match_evpn_default_route_cmd,
+       "match evpn default-route",
+       MATCH_STR
+       EVPN_HELP_STR
+       "default EVPN type-5 route\n")
+{
+       return bgp_route_match_add(vty, "evpn default-route", NULL,
+                                  RMAP_EVENT_MATCH_ADDED);
+}
+
+DEFUN (no_match_evpn_default_route,
+       no_match_evpn_default_route_cmd,
+       "no match evpn default-route",
+       NO_STR
+       MATCH_STR
+       EVPN_HELP_STR
+       "default EVPN type-5 route\n")
+{
+       return bgp_route_match_delete(vty, "evpn default-route", NULL,
+                                     RMAP_EVENT_MATCH_DELETED);
+}
+
 DEFUN (match_peer,
        match_peer_cmd,
        "match peer <A.B.C.D|X:X::X:X|WORD>",
@@ -4628,6 +4669,7 @@ void bgp_route_map_init(void)
        route_map_install_match(&route_match_mac_address_cmd);
        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_set(&route_set_ip_nexthop_cmd);
        route_map_install_set(&route_set_local_pref_cmd);
@@ -4664,6 +4706,8 @@ void bgp_route_map_init(void)
        install_element(RMAP_NODE, &no_match_evpn_vni_cmd);
        install_element(RMAP_NODE, &match_evpn_route_type_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_aspath_cmd);
        install_element(RMAP_NODE, &no_match_aspath_cmd);