]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: support for default-originate type-5 route
authorMitesh Kanjariya <mitesh@marvel-07.cumulusnetworks.com>
Fri, 16 Feb 2018 01:20:27 +0000 (17:20 -0800)
committermitesh <mitesh@cumulusnetworks.com>
Fri, 23 Feb 2018 01:31:58 +0000 (17:31 -0800)
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 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>
0001-bgpd-support-for-default-originate-type-5-route.patch [new file with mode: 0644]
bgpd/bgp_evpn_private.h
bgpd/bgp_evpn_vty.c
bgpd/bgpd.h

diff --git a/0001-bgpd-support-for-default-originate-type-5-route.patch b/0001-bgpd-support-for-default-originate-type-5-route.patch
new file mode 100644 (file)
index 0000000..9212108
--- /dev/null
@@ -0,0 +1,180 @@
+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 5ff16c39e9727ee091d0477f5fdc9965d9d6bb4b..bc68e259b60234c52bd6ac14d125184e18f5f513 100644 (file)
@@ -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);
index 1720744439055001f1903e85e1b1c7d2b30cece5..5ce71dbf62979e14a962c8550c4574cfd2b181c5 100644 (file)
@@ -2473,6 +2473,48 @@ static void evpn_unset_advertise_default_gw(struct bgp *bgp,
        return;
 }
 
+/*
+ * 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
  */
@@ -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);
index 5b77be2be9db438037227959bbaf4128bfc9b4e3..274ca82ffcdfb14e6efb1deef65fc54d4850203f 100644 (file)
@@ -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. */