]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: make _vpnv4 static handling SAFI-agnostic
authorLou Berger <lberger@labn.net>
Tue, 12 Jan 2016 18:41:53 +0000 (13:41 -0500)
committervivek <vivek@cumulusnetworks.com>
Mon, 6 Jun 2016 23:33:33 +0000 (16:33 -0700)
This changes the existing _vpnv4 functions for MPLS-VPN into
SAFI-agnostic functions, renaming them from *_vpnv4 to *_safi.

Also adds route-map support while at it.

Signed-off-by: Lou Berger <lberger@labn.net>
Reviewed-by: David Lamparter <equinox@opensourcerouting.org>
(cherry picked from commit a76d9ca3584c1751a592457c167c1e146648ceb6)

Conflicts:
bgpd/bgp_route.c

bgpd/bgp_mplsvpn.c
bgpd/bgp_route.c
bgpd/bgp_route.h

index d7ac8923e6d8385f4281c438530e4894a376b5f1..3dd2cc51fe0d22b9be18f14e9d8b7e7d553b9ee3 100644 (file)
@@ -340,7 +340,22 @@ DEFUN (vpnv4_network,
        "BGP tag\n"
        "tag value\n")
 {
-  return bgp_static_set_vpnv4 (vty, argv[0], argv[1], argv[2]);
+  return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[0], argv[1], argv[2], NULL);
+}
+
+DEFUN (vpnv4_network_route_map,
+       vpnv4_network_route_map_cmd,
+       "network A.B.C.D/M rd ASN:nn_or_IP-address:nn tag WORD route-map WORD",
+       "Specify a network to announce via BGP\n"
+       "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
+       "Specify Route Distinguisher\n"
+       "VPN Route Distinguisher\n"
+       "BGP tag\n"
+       "tag value\n"
+       "route map\n"
+       "route map name\n")
+{
+  return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[0], argv[1], argv[2], argv[3]);
 }
 
 /* For testing purpose, static route of MPLS-VPN. */
@@ -355,7 +370,7 @@ DEFUN (no_vpnv4_network,
        "BGP tag\n"
        "tag value\n")
 {
-  return bgp_static_unset_vpnv4 (vty, argv[0], argv[1], argv[2]);
+  return bgp_static_unset_safi (SAFI_MPLS_VPN, vty, argv[0], argv[1], argv[2]);
 }
 
 static int
@@ -1020,6 +1035,7 @@ void
 bgp_mplsvpn_init (void)
 {
   install_element (BGP_VPNV4_NODE, &vpnv4_network_cmd);
+  install_element (BGP_VPNV4_NODE, &vpnv4_network_route_map_cmd);
   install_element (BGP_VPNV4_NODE, &no_vpnv4_network_cmd);
 
 
index adc6407bb9a7d1d05744b5093a7f9420de1d7be7..1b17dc36b5bcb5fe9a232f0936c479c8da9daa41 100644 (file)
@@ -3476,36 +3476,6 @@ bgp_static_update (struct bgp *bgp, struct prefix *p,
   bgp_static_update_main (bgp, p, bgp_static, afi, safi);
 }
 
-static void
-bgp_static_update_vpnv4 (struct bgp *bgp, struct prefix *p, afi_t afi,
-                        safi_t safi, struct prefix_rd *prd, u_char *tag)
-{
-  struct bgp_node *rn;
-  struct bgp_info *new;
-  
-  rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd);
-
-  /* Make new BGP info. */
-  new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
-                 bgp_attr_default_intern(BGP_ORIGIN_IGP), rn);
-
-  SET_FLAG (new->flags, BGP_INFO_VALID);
-  new->extra = bgp_info_extra_new();
-  memcpy (new->extra->tag, tag, 3);
-
-  /* Aggregate address increment. */
-  bgp_aggregate_increment (bgp, p, new, afi, safi);
-  
-  /* Register new BGP information. */
-  bgp_info_add (rn, new);
-
-  /* route_node_get lock */
-  bgp_unlock_node (rn);
-  
-  /* Process change. */
-  bgp_process (bgp, rn, afi, safi);
-}
-
 void
 bgp_static_withdraw (struct bgp *bgp, struct prefix *p, afi_t afi,
                     safi_t safi)
@@ -3535,9 +3505,12 @@ bgp_static_withdraw (struct bgp *bgp, struct prefix *p, afi_t afi,
   bgp_unlock_node (rn);
 }
 
+/*
+ * Used for SAFI_MPLS_VPN and SAFI_ENCAP
+ */
 static void
-bgp_static_withdraw_vpnv4 (struct bgp *bgp, struct prefix *p, afi_t afi,
-                          safi_t safi, struct prefix_rd *prd, u_char *tag)
+bgp_static_withdraw_safi (struct bgp *bgp, struct prefix *p, afi_t afi,
+                          safi_t safi, struct prefix_rd *prd, u_char *tag)
 {
   struct bgp_node *rn;
   struct bgp_info *ri;
@@ -3563,6 +3536,127 @@ bgp_static_withdraw_vpnv4 (struct bgp *bgp, struct prefix *p, afi_t afi,
   bgp_unlock_node (rn);
 }
 
+static void
+bgp_static_update_safi (struct bgp *bgp, struct prefix *p,
+                        struct bgp_static *bgp_static, afi_t afi, safi_t safi)
+{
+  struct bgp_node *rn;
+  struct bgp_info *new;
+  struct attr *attr_new;
+  struct attr attr = { 0 };
+  struct bgp_info *ri;
+
+  assert (bgp_static);
+
+  rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, &bgp_static->prd);
+
+  bgp_attr_default_set (&attr, BGP_ORIGIN_IGP);
+
+  attr.nexthop = bgp_static->igpnexthop;
+  attr.med = bgp_static->igpmetric;
+  attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
+
+  /* Apply route-map. */
+  if (bgp_static->rmap.name)
+    {
+      struct attr attr_tmp = attr;
+      struct bgp_info info;
+      int ret;
+
+      info.peer = bgp->peer_self;
+      info.attr = &attr_tmp;
+
+      SET_FLAG (bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
+
+      ret = route_map_apply (bgp_static->rmap.map, p, RMAP_BGP, &info);
+
+      bgp->peer_self->rmap_type = 0;
+
+      if (ret == RMAP_DENYMATCH)
+        {
+          /* Free uninterned attribute. */
+          bgp_attr_flush (&attr_tmp);
+
+          /* Unintern original. */
+          aspath_unintern (&attr.aspath);
+          bgp_attr_extra_free (&attr);
+          bgp_static_withdraw_safi (bgp, p, afi, safi, &bgp_static->prd,
+                                    bgp_static->tag);
+          return;
+        }
+
+      attr_new = bgp_attr_intern (&attr_tmp);
+    }
+  else
+    {
+      attr_new = bgp_attr_intern (&attr);
+    }
+
+  for (ri = rn->info; ri; ri = ri->next)
+    if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP
+        && ri->sub_type == BGP_ROUTE_STATIC)
+      break;
+
+  if (ri)
+    {
+      if (attrhash_cmp (ri->attr, attr_new) &&
+          !CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
+        {
+          bgp_unlock_node (rn);
+          bgp_attr_unintern (&attr_new);
+          aspath_unintern (&attr.aspath);
+          bgp_attr_extra_free (&attr);
+          return;
+        }
+      else
+        {
+          /* The attribute is changed. */
+          bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
+
+          /* Rewrite BGP route information. */
+          if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
+            bgp_info_restore(rn, ri);
+          else
+            bgp_aggregate_decrement (bgp, p, ri, afi, safi);
+          bgp_attr_unintern (&ri->attr);
+          ri->attr = attr_new;
+          ri->uptime = bgp_clock ();
+
+          /* Process change. */
+          bgp_aggregate_increment (bgp, p, ri, afi, safi);
+          bgp_process (bgp, rn, afi, safi);
+          bgp_unlock_node (rn);
+          aspath_unintern (&attr.aspath);
+          bgp_attr_extra_free (&attr);
+          return;
+        }
+    }
+
+
+  /* Make new BGP info. */
+  new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self, attr_new,
+                 rn);
+  SET_FLAG (new->flags, BGP_INFO_VALID);
+  new->extra = bgp_info_extra_new();
+  memcpy (new->extra->tag, bgp_static->tag, 3);
+
+  /* Aggregate address increment. */
+  bgp_aggregate_increment (bgp, p, new, afi, safi);
+
+  /* Register new BGP information. */
+  bgp_info_add (rn, new);
+
+  /* route_node_get lock */
+  bgp_unlock_node (rn);
+
+  /* Process change. */
+  bgp_process (bgp, rn, afi, safi);
+
+  /* Unintern original. */
+  aspath_unintern (&attr.aspath);
+  bgp_attr_extra_free (&attr);
+}
+
 /* Configure static BGP network.  When user don't run zebra, static
    route should be installed as valid.  */
 static int
@@ -3726,10 +3820,7 @@ bgp_static_add (struct bgp *bgp)
                for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
                  {
                    bgp_static = rn->info;
-                   bgp_static_update_vpnv4 (bgp, &rm->p,
-                                             AFI_IP, SAFI_MPLS_VPN,
-                                            (struct prefix_rd *)&rn->p,
-                                            bgp_static->tag);
+                    bgp_static_update_safi (bgp, &rm->p, bgp_static, afi, safi);
                  }
              }
            else
@@ -3763,8 +3854,8 @@ bgp_static_delete (struct bgp *bgp)
                for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
                  {
                    bgp_static = rn->info;
-                   bgp_static_withdraw_vpnv4 (bgp, &rm->p,
-                                              AFI_IP, SAFI_MPLS_VPN,
+                   bgp_static_withdraw_safi (bgp, &rm->p,
+                                              AFI_IP, safi,
                                               (struct prefix_rd *)&rn->p,
                                               bgp_static->tag);
                    bgp_static_free (bgp_static);
@@ -3846,9 +3937,15 @@ bgp_purge_static_redist_routes (struct bgp *bgp)
       bgp_purge_af_static_redist_routes (bgp, afi, safi);
 }
 
+/*
+ * gpz 110624
+ * Currently this is used to set static routes for VPN and ENCAP.
+ * I think it can probably be factored with bgp_static_set.
+ */
 int
-bgp_static_set_vpnv4 (struct vty *vty, const char *ip_str, const char *rd_str,
-                     const char *tag_str)
+bgp_static_set_safi (safi_t safi, struct vty *vty, const char *ip_str,
+                     const char *rd_str, const char *tag_str,
+                     const char *rmap_str)
 {
   int ret;
   struct prefix p;
@@ -3884,10 +3981,10 @@ bgp_static_set_vpnv4 (struct vty *vty, const char *ip_str, const char *rd_str,
       return CMD_WARNING;
     }
 
-  prn = bgp_node_get (bgp->route[AFI_IP][SAFI_MPLS_VPN],
+  prn = bgp_node_get (bgp->route[AFI_IP][safi],
                        (struct prefix *)&prd);
   if (prn->info == NULL)
-    prn->info = bgp_table_init (AFI_IP, SAFI_MPLS_VPN);
+    prn->info = bgp_table_init (AFI_IP, safi);
   else
     bgp_unlock_node (prn);
   table = prn->info;
@@ -3903,11 +4000,24 @@ bgp_static_set_vpnv4 (struct vty *vty, const char *ip_str, const char *rd_str,
     {
       /* New configuration. */
       bgp_static = bgp_static_new ();
-      bgp_static->valid = 1;
-      memcpy (bgp_static->tag, tag, 3);
+      bgp_static->backdoor = 0;
+      bgp_static->valid = 0;
+      bgp_static->igpmetric = 0;
+      bgp_static->igpnexthop.s_addr = 0;
+      memcpy(bgp_static->tag, tag, 3);
+      bgp_static->prd = prd;
+
+      if (rmap_str)
+       {
+         if (bgp_static->rmap.name)
+           free (bgp_static->rmap.name);
+         bgp_static->rmap.name = strdup (rmap_str);
+         bgp_static->rmap.map = route_map_lookup_by_name (rmap_str);
+       }
       rn->info = bgp_static;
 
-      bgp_static_update_vpnv4 (bgp, &p, AFI_IP, SAFI_MPLS_VPN, &prd, tag);
+      bgp_static->valid = 1;
+      bgp_static_update_safi (bgp, &p, bgp_static, AFI_IP, safi);
     }
 
   return CMD_SUCCESS;
@@ -3915,8 +4025,8 @@ bgp_static_set_vpnv4 (struct vty *vty, const char *ip_str, const char *rd_str,
 
 /* Configure static BGP network. */
 int
-bgp_static_unset_vpnv4 (struct vty *vty, const char *ip_str, 
-                        const char *rd_str, const char *tag_str)
+bgp_static_unset_safi(safi_t safi, struct vty *vty, const char *ip_str,
+                      const char *rd_str, const char *tag_str)
 {
   int ret;
   struct bgp *bgp;
@@ -3953,10 +4063,10 @@ bgp_static_unset_vpnv4 (struct vty *vty, const char *ip_str,
       return CMD_WARNING;
     }
 
-  prn = bgp_node_get (bgp->route[AFI_IP][SAFI_MPLS_VPN],
+  prn = bgp_node_get (bgp->route[AFI_IP][safi],
                        (struct prefix *)&prd);
   if (prn->info == NULL)
-    prn->info = bgp_table_init (AFI_IP, SAFI_MPLS_VPN);
+    prn->info = bgp_table_init (AFI_IP, safi);
   else
     bgp_unlock_node (prn);
   table = prn->info;
@@ -3965,7 +4075,7 @@ bgp_static_unset_vpnv4 (struct vty *vty, const char *ip_str,
 
   if (rn)
     {
-      bgp_static_withdraw_vpnv4 (bgp, &p, AFI_IP, SAFI_MPLS_VPN, &prd, tag);
+      bgp_static_withdraw_safi (bgp, &p, AFI_IP, safi, &prd, tag);
 
       bgp_static = rn->info;
       bgp_static_free (bgp_static);
index cc26249686a77fa5bc6536c103490f971249e112..8d1eb21010ebb151fb38196848642ebdc2c2cfab 100644 (file)
@@ -145,6 +145,9 @@ struct bgp_static
     struct route_map *map;
   } rmap;
 
+  /* Route Distinguisher */
+  struct prefix_rd     prd;
+
   /* MPLS label.  */
   u_char tag[3];
 };
@@ -253,10 +256,10 @@ extern void bgp_static_update (struct bgp *, struct prefix *, struct bgp_static
                        afi_t, safi_t);
 extern void bgp_static_withdraw (struct bgp *, struct prefix *, afi_t, safi_t);
                      
-extern int bgp_static_set_vpnv4 (struct vty *vty, const char *, 
-                          const char *, const char *);
+extern int bgp_static_set_safi (safi_t safi, struct vty *vty, const char *,
+                          const char *, const char *, const char *);
 
-extern int bgp_static_unset_vpnv4 (struct vty *, const char *, 
+extern int bgp_static_unset_safi (safi_t safi, struct vty *, const char *,
                             const char *, const char *);
 
 /* this is primarily for MPLS-VPN */