]> git.puffer.fish Git - mirror/frr.git/commitdiff
lib: Refine EVPN prefix definition
authorvivek <vivek@cumulusnetworks.com>
Mon, 15 May 2017 05:20:33 +0000 (22:20 -0700)
committervivek <vivek@cumulusnetworks.com>
Thu, 25 May 2017 17:20:03 +0000 (10:20 -0700)
Modify EVPN prefix to use the generic IP address structure. Add support
for EVPN type-2 and type-3 prefix dump. Fix references to modified fields
as needed.

Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
bgpd/bgp_attr_evpn.c
bgpd/bgp_evpn.c
bgpd/bgp_route.c
lib/prefix.c
lib/prefix.h

index e565d0801b20de996bed0d5db9930b463a53ec1c..6970d5a6791f4c2a57f8023c16ee988af360a564 100644 (file)
@@ -125,13 +125,13 @@ bgp_build_evpn_prefix(int evpn_type, uint32_t eth_tag, struct prefix *dst)
                p_evpn_p->eth_tag = eth_tag;
                p_evpn_p->ip_prefix_length = p2.prefixlen;
                if (src->family == AF_INET) {
-                       p_evpn_p->flags = IP_PREFIX_V4;
-                       memcpy(&p_evpn_p->ip.v4_addr, &src->u.prefix4,
+                        SET_IPADDR_V4 (&p_evpn_p->ip);
+                       memcpy(&p_evpn_p->ip.ipaddr_v4, &src->u.prefix4,
                               sizeof(struct in_addr));
                        dst->prefixlen = (u_char) PREFIX_LEN_ROUTE_TYPE_5_IPV4;
                } else {
-                       p_evpn_p->flags = IP_PREFIX_V6;
-                       memcpy(&p_evpn_p->ip.v6_addr, &src->u.prefix6,
+                        SET_IPADDR_V6 (&p_evpn_p->ip);
+                       memcpy(&p_evpn_p->ip.ipaddr_v6, &src->u.prefix6,
                               sizeof(struct in6_addr));
                        dst->prefixlen = (u_char) PREFIX_LEN_ROUTE_TYPE_5_IPV6;
                }
index c5a0ef8893808a312bb3e3bac2dfcda881c4fdf4..6738f3cd1681bd34fb1efc8cfa5db299b81d0e88 100644 (file)
@@ -124,20 +124,20 @@ bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr,
                        /* determine IPv4 or IPv6 prefix */
                        if (route_length - 4 - 10 - 8 -
                            3 /* label to be read */  >= 32) {
-                               p_evpn_p->flags = IP_PREFIX_V6;
-                               memcpy(&(p_evpn_p->ip.v6_addr), pnt, 16);
+                               SET_IPADDR_V6 (&p_evpn_p->ip);
+                               memcpy(&(p_evpn_p->ip.ipaddr_v6), pnt, 16);
                                pnt += 16;
                                memcpy(&evpn.gw_ip.ipv6, pnt, 16);
                                pnt += 16;
                        } else {
-                               p_evpn_p->flags = IP_PREFIX_V4;
-                               memcpy(&(p_evpn_p->ip.v4_addr), pnt, 4);
+                               SET_IPADDR_V4 (&p_evpn_p->ip);
+                               memcpy(&(p_evpn_p->ip.ipaddr_v4), pnt, 4);
                                pnt += 4;
                                memcpy(&evpn.gw_ip.ipv4, pnt, 4);
                                pnt += 4;
                        }
                        p.family = AFI_L2VPN;
-                       if (p_evpn_p->flags == IP_PREFIX_V4)
+                       if (IS_IPADDR_V4(&p_evpn_p->ip))
                                p.prefixlen =
                                    (u_char) PREFIX_LEN_ROUTE_TYPE_5_IPV4;
                        else
@@ -184,7 +184,7 @@ bgp_packet_mpattr_route_type_5(struct stream *s,
        if (p->family != AF_ETHERNET)
                return;
        p_evpn_p = &(p->u.prefix_evpn);
-       if (p_evpn_p->flags & IP_PREFIX_V4)
+        if (IS_IPADDR_V4(&p_evpn_p->ip))
                len = 8;        /* ipv4 */
        else
                len = 32;       /* ipv6 */
@@ -199,12 +199,12 @@ bgp_packet_mpattr_route_type_5(struct stream *s,
                stream_put(s, &temp, 10);
        stream_putl(s, p_evpn_p->eth_tag);
        stream_putc(s, p_evpn_p->ip_prefix_length);
-       if (p_evpn_p->flags & IP_PREFIX_V4)
-               stream_put_ipv4(s, p_evpn_p->ip.v4_addr.s_addr);
+        if (IS_IPADDR_V4(&p_evpn_p->ip))
+               stream_put_ipv4(s, p_evpn_p->ip.ipaddr_v4.s_addr);
        else
-               stream_put(s, &p_evpn_p->ip.v6_addr, 16);
+               stream_put(s, &p_evpn_p->ip.ipaddr_v6, 16);
        if (attr && attr->extra) {
-               if (p_evpn_p->flags & IP_PREFIX_V4)
+                if (IS_IPADDR_V4(&p_evpn_p->ip))
                        stream_put_ipv4(s,
                                        attr->extra->evpn_overlay.gw_ip.ipv4.
                                        s_addr);
@@ -212,7 +212,7 @@ bgp_packet_mpattr_route_type_5(struct stream *s,
                        stream_put(s, &(attr->extra->evpn_overlay.gw_ip.ipv6),
                                   16);
        } else {
-               if (p_evpn_p->flags & IP_PREFIX_V4)
+                if (IS_IPADDR_V4(&p_evpn_p->ip))
                        stream_put_ipv4(s, 0);
                else
                        stream_put(s, &temp, 16);
index 7a328e79d7f4ebbb54923973eb32e49e9f27bfaa..8f028b32c4654b94e9cc147635643ac10ee333af 100644 (file)
@@ -4608,8 +4608,10 @@ bgp_static_set_safi (afi_t afi, safi_t safi, struct vty *vty, const char *ip_str
               vty_out (vty, "%% Malformed GatewayIp%s", VTY_NEWLINE);
               return CMD_WARNING;
             }
-          if((gw_ip.family == AF_INET &&  (p.u.prefix_evpn.flags & IP_PREFIX_V6))
-             || (gw_ip.family == AF_INET6 &&  (p.u.prefix_evpn.flags & IP_PREFIX_V4)))
+          if((gw_ip.family == AF_INET &&
+              IS_EVPN_PREFIX_IPADDR_V6((struct prefix_evpn *)&p)) ||
+             (gw_ip.family == AF_INET6 &&
+              IS_EVPN_PREFIX_IPADDR_V4((struct prefix_evpn *)&p)))
             {
               vty_out (vty, "%% GatewayIp family differs with IP prefix%s", VTY_NEWLINE);
               return CMD_WARNING;
@@ -6815,11 +6817,11 @@ route_vty_out_overlay (struct vty *vty, struct prefix *p,
       char *str = esi2str(id);
       vty_out (vty, "%s", str);
       XFREE (MTYPE_TMP, str);
-      if (p->u.prefix_evpn.flags & IP_PREFIX_V4)
+      if (IS_EVPN_PREFIX_IPADDR_V4((struct prefix_evpn *)p))
        {
           vty_out (vty, "/%s", inet_ntoa (attr->extra->evpn_overlay.gw_ip.ipv4));
        }
-      else if (p->u.prefix_evpn.flags & IP_PREFIX_V6)
+      else if (IS_EVPN_PREFIX_IPADDR_V6((struct prefix_evpn *)p))
        {
           vty_out (vty, "/%s",
                    inet_ntop (AF_INET6, &(attr->extra->evpn_overlay.gw_ip.ipv6),
index 9c228cf9548c1a42609fa27a9109a57fd34b22cb..1bf196551ff440f7d4d91959d52478a6666efcc8 100644 (file)
@@ -852,6 +852,66 @@ str2prefix (const char *str, struct prefix *p)
   return 0;
 }
 
+static const char *
+prefixeth2str (const struct prefix *p, char *str, int size)
+{
+  u_char family;
+  char buf[PREFIX2STR_BUFFER];
+  char buf2[ETHER_ADDR_STRLEN];
+
+  if (p->u.prefix_evpn.route_type == 2)
+    {
+      if (IS_EVPN_PREFIX_IPADDR_NONE((struct prefix_evpn *)p))
+        snprintf (str, size, "[%d]:[%s]/%d",
+                  p->u.prefix_evpn.route_type,
+                  prefix_mac2str (&p->u.prefix_evpn.mac, buf2, sizeof (buf2)),
+                  p->prefixlen);
+      else
+        {
+          family = IS_EVPN_PREFIX_IPADDR_V4((struct prefix_evpn *)p) ? \
+                   AF_INET : AF_INET6;
+          snprintf (str, size, "[%d]:[%s]:[%s]/%d",
+                    p->u.prefix_evpn.route_type,
+                    prefix_mac2str (&p->u.prefix_evpn.mac, buf2, sizeof (buf2)),
+                    inet_ntop (family, &p->u.prefix_evpn.ip.ip.addr,
+                               buf, PREFIX2STR_BUFFER),
+                    p->prefixlen);
+        }
+    }
+  else if (p->u.prefix_evpn.route_type == 3)
+    {
+      family = IS_EVPN_PREFIX_IPADDR_V4((struct prefix_evpn *)p) ? \
+               AF_INET : AF_INET6;
+      snprintf (str, size, "[%d]:[%s]/%d",
+                p->u.prefix_evpn.route_type,
+                inet_ntop (family, &p->u.prefix_evpn.ip.ip.addr,
+                           buf, PREFIX2STR_BUFFER),
+                p->prefixlen);
+    }
+  else if (p->u.prefix_evpn.route_type == 5)
+    {
+      family = IS_EVPN_PREFIX_IPADDR_V4((struct prefix_evpn *)p) ? \
+               AF_INET : AF_INET6;
+      snprintf (str, size, "[%d]:[%u][%s]/%d",
+                p->u.prefix_evpn.route_type,
+                p->u.prefix_evpn.eth_tag,
+                inet_ntop (family, &p->u.prefix_evpn.ip.ip.addr,
+                           buf, PREFIX2STR_BUFFER),
+                p->prefixlen);
+    }
+  else
+    {
+      sprintf (str, "UNK AF_ETHER prefix");
+      snprintf(str, size, "%02x:%02x:%02x:%02x:%02x:%02x/%d",
+               p->u.prefix_eth.octet[0], p->u.prefix_eth.octet[1],
+               p->u.prefix_eth.octet[2], p->u.prefix_eth.octet[3],
+               p->u.prefix_eth.octet[4], p->u.prefix_eth.octet[5],
+               p->prefixlen);
+    }
+
+  return str;
+}
+
 const char *
 prefix2str (union prefixconstptr pu, char *str, int size)
 {
@@ -868,28 +928,9 @@ prefix2str (union prefixconstptr pu, char *str, int size)
         break;
 
       case AF_ETHERNET:
-        if (p->u.prefix_evpn.route_type == 5)
-          {
-            u_char family;
-            family = (p->u.prefix_evpn.flags & (IP_ADDR_V4 | IP_PREFIX_V4)) ?
-              AF_INET : AF_INET6;
-            snprintf (str, size, "[%d]:[%u][%s]/%d",
-                      p->u.prefix_evpn.route_type,
-                      p->u.prefix_evpn.eth_tag,
-                      inet_ntop (family, &p->u.prefix_evpn.ip.addr,
-                                 buf, PREFIX2STR_BUFFER),
-                      p->prefixlen);
-          }
-        else
-          {
-            sprintf (str, "UNK AF_ETHER prefix");
-            snprintf(str, size, "%02x:%02x:%02x:%02x:%02x:%02x/%d",
-                     p->u.prefix_eth.octet[0], p->u.prefix_eth.octet[1],
-                     p->u.prefix_eth.octet[2], p->u.prefix_eth.octet[3],
-                     p->u.prefix_eth.octet[4], p->u.prefix_eth.octet[5],
-                     p->prefixlen);
-          }
+        prefixeth2str (p, str, size);
         break;
+
       default:
         sprintf (str, "UNK prefix");
         break;
index 35dfddd9d346701a8f55731e3c65cfd7e353bd6e..a377c275737b70ed10f619b7d2038ec256014ed5 100644 (file)
@@ -32,6 +32,7 @@
 # endif
 #endif
 #include "sockunion.h"
+#include "ipaddr.h"
 
 #ifndef ETHER_ADDR_LEN
 #ifdef ETHERADDRL
@@ -62,30 +63,23 @@ struct ethaddr {
 struct evpn_addr
 {
   u_char route_type;
-  u_char flags;
-#define IP_ADDR_NONE      0x0
-#define IP_ADDR_V4        0x1
-#define IP_ADDR_V6        0x2
-#define IP_PREFIX_V4      0x4
-#define IP_PREFIX_V6      0x8
+  u_char ip_prefix_length;
   struct ethaddr mac;
   uint32_t eth_tag;
-  u_char ip_prefix_length;
+  ipaddr_t ip;
+#if 0
   union
   {
     u_char addr;
     struct in_addr v4_addr;
     struct in6_addr v6_addr;
   } ip;
+#endif
 };
 
-/* EVPN prefix structure. */
-struct prefix_evpn
-{
-  u_char family;
-  u_char prefixlen;
-  struct evpn_addr prefix __attribute__ ((aligned (8)));
-};
+#define IS_EVPN_PREFIX_IPADDR_NONE(evp)  IS_IPADDR_NONE(&(evp)->prefix.ip)
+#define IS_EVPN_PREFIX_IPADDR_V4(evp)    IS_IPADDR_V4(&(evp)->prefix.ip)
+#define IS_EVPN_PREFIX_IPADDR_V6(evp)    IS_IPADDR_V6(&(evp)->prefix.ip)
 
 /*
  * A struct prefix contains an address family, a prefix length, and an
@@ -167,6 +161,14 @@ struct prefix_eth
   struct ethaddr eth_addr __attribute__ ((aligned (8))); /* AF_ETHERNET */
 };
 
+/* EVPN prefix structure. */
+struct prefix_evpn
+{
+  u_char family;
+  u_char prefixlen;
+  struct evpn_addr prefix __attribute__ ((aligned (8)));
+};
+
 /* Prefix for a generic pointer */
 struct prefix_ptr
 {