]> git.proxmox.com Git - mirror_frr.git/commitdiff
bgpd: Separate out RD handling functions
authorvivek <vivek@cumulusnetworks.com>
Mon, 15 May 2017 19:33:59 +0000 (12:33 -0700)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 12 Jul 2017 16:34:32 +0000 (12:34 -0400)
BGP Route Distinguisher (RD) handling is common for different flavors
of BGP VPNs such as BGP/MPLS IP VPNs (RFC 4364) and BGP EVPNs (RFC 7432).
Separate out the RD handling functions into its own files.

Note: No functional change introduced with this commit.

Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
bgpd/Makefile.am
bgpd/bgp_mplsvpn.c
bgpd/bgp_mplsvpn.h
bgpd/bgp_rd.c [new file with mode: 0644]
bgpd/bgp_rd.h [new file with mode: 0644]

index f096f0ff114f131856ab22157dd2a60d2975b645..9a4e5fd6aafd7a1e4cb891b9e60a00ac2794f5cd 100644 (file)
@@ -83,7 +83,7 @@ libbgp_a_SOURCES = \
        bgp_damp.c bgp_table.c bgp_advertise.c bgp_vty.c bgp_mpath.c \
        bgp_nht.c bgp_updgrp.c bgp_updgrp_packet.c bgp_updgrp_adv.c bgp_bfd.c \
        bgp_encap_tlv.c $(BGP_VNC_RFAPI_SRC) bgp_attr_evpn.c \
-       bgp_evpn.c bgp_evpn_vty.c bgp_vpn.c bgp_label.c
+       bgp_evpn.c bgp_evpn_vty.c bgp_vpn.c bgp_label.c bgp_rd.c
 
 noinst_HEADERS = \
        bgp_memory.h \
@@ -95,7 +95,7 @@ noinst_HEADERS = \
        bgp_advertise.h bgp_vty.h bgp_mpath.h bgp_nht.h \
        bgp_updgrp.h bgp_bfd.h bgp_encap_tlv.h bgp_encap_types.h \
        $(BGP_VNC_RFAPI_HD) bgp_attr_evpn.h bgp_evpn.h bgp_evpn_vty.h \
-        bgp_vpn.h bgp_label.h
+        bgp_vpn.h bgp_label.h bgp_rd.h
 
 bgpd_SOURCES = bgp_main.c
 bgpd_LDADD = libbgp.a  $(BGP_VNC_RFP_LIB) ../lib/libfrr.la @LIBCAP@ @LIBM@
index b5fbfd8bb6c85866d8f2a0eefb050b396c6d518a..3973663e9daad343050e3a1866efaa22933abfb0 100644 (file)
@@ -62,31 +62,6 @@ argv_find_and_parse_vpnvx(struct cmd_token **argv, int argc, int *index, afi_t *
    return ret;
 }
 
-u_int16_t
-decode_rd_type (u_char *pnt)
-{
-  u_int16_t v;
-  
-  v = ((u_int16_t) *pnt++ << 8);
-#if ENABLE_BGP_VNC
-  /*
-   * VNC L2 stores LHI in lower byte, so omit it
-   */
-  if (v != RD_TYPE_VNC_ETH)
-    v |= (u_int16_t) *pnt;
-#else                           /* duplicate code for clarity */
-  v |= (u_int16_t) *pnt;
-#endif
-
-  return v;
-}
-
-void
-encode_rd_type (u_int16_t v, u_char *pnt)
-{
-  *((u_int16_t *)pnt) = htons(v);
-}
-
 u_int32_t
 decode_label (mpls_label_t *label_pnt)
 {
@@ -111,54 +86,6 @@ encode_label(mpls_label_t label,
     *pnt++ = ((label<<4)+1) & 0xff; /* S=1 */
 }
 
-/* type == RD_TYPE_AS */
-void
-decode_rd_as (u_char *pnt, struct rd_as *rd_as)
-{
-  rd_as->as = (u_int16_t) *pnt++ << 8;
-  rd_as->as |= (u_int16_t) *pnt++;
-  
-  rd_as->val = ((u_int32_t) *pnt++ << 24);
-  rd_as->val |= ((u_int32_t) *pnt++ << 16);
-  rd_as->val |= ((u_int32_t) *pnt++ << 8);
-  rd_as->val |= (u_int32_t) *pnt;
-}
-
-/* type == RD_TYPE_AS4 */
-void
-decode_rd_as4 (u_char *pnt, struct rd_as *rd_as)
-{
-  rd_as->as  = (u_int32_t) *pnt++ << 24;
-  rd_as->as |= (u_int32_t) *pnt++ << 16;
-  rd_as->as |= (u_int32_t) *pnt++ << 8;
-  rd_as->as |= (u_int32_t) *pnt++;
-
-  rd_as->val  = ((u_int16_t) *pnt++ << 8);
-  rd_as->val |= (u_int16_t) *pnt;
-}
-
-/* type == RD_TYPE_IP */
-void
-decode_rd_ip (u_char *pnt, struct rd_ip *rd_ip)
-{
-  memcpy (&rd_ip->ip, pnt, 4);
-  pnt += 4;
-  
-  rd_ip->val = ((u_int16_t) *pnt++ << 8);
-  rd_ip->val |= (u_int16_t) *pnt;
-}
-
-#if ENABLE_BGP_VNC
-/* type == RD_TYPE_VNC_ETH */
-void
-decode_rd_vnc_eth (u_char *pnt, struct rd_vnc_eth *rd_vnc_eth)
-{
-  rd_vnc_eth->type = RD_TYPE_VNC_ETH;
-  rd_vnc_eth->local_nve_id = pnt[1];
-  memcpy (rd_vnc_eth->macaddr.octet, pnt + 2, ETHER_ADDR_LEN);
-}
-#endif
-
 int
 bgp_nlri_parse_vpn (struct peer *peer, struct attr *attr,
                     struct bgp_nlri *packet)
@@ -313,129 +240,6 @@ bgp_nlri_parse_vpn (struct peer *peer, struct attr *attr,
 #undef VPN_PREFIXLEN_MIN_BYTES
 }
 
-int
-str2prefix_rd (const char *str, struct prefix_rd *prd)
-{
-  int ret; /* ret of called functions */
-  int lret; /* local ret, of this func */
-  char *p;
-  char *p2;
-  struct stream *s = NULL;
-  char *half = NULL;
-  struct in_addr addr;
-
-  s = stream_new (8);
-
-  prd->family = AF_UNSPEC;
-  prd->prefixlen = 64;
-
-  lret = 0;
-  p = strchr (str, ':');
-  if (! p)
-    goto out;
-
-  if (! all_digit (p + 1))
-    goto out;
-
-  half = XMALLOC (MTYPE_TMP, (p - str) + 1);
-  memcpy (half, str, (p - str));
-  half[p - str] = '\0';
-
-  p2 = strchr (str, '.');
-
-  if (! p2)
-    {
-      unsigned long as_val;
-
-      if (! all_digit (half))
-        goto out;
-
-      as_val = atol(half);
-      if (as_val > 0xffff)
-        {
-          stream_putw (s, RD_TYPE_AS4);
-          stream_putl (s, as_val);
-          stream_putw (s, atol (p + 1));
-        }
-      else
-        {
-          stream_putw (s, RD_TYPE_AS);
-          stream_putw (s, as_val);
-          stream_putl (s, atol (p + 1));
-        }
-    }
-  else
-    {
-      ret = inet_aton (half, &addr);
-      if (! ret)
-        goto out;
-
-      stream_putw (s, RD_TYPE_IP);
-      stream_put_in_addr (s, &addr);
-      stream_putw (s, atol (p + 1));
-    }
-  memcpy (prd->val, s->data, 8);
-  lret = 1;
-
-out:
-  if (s)
-    stream_free (s);
-  if (half)
-    XFREE(MTYPE_TMP, half);
-  return lret;
-}
-
-char *
-prefix_rd2str (struct prefix_rd *prd, char *buf, size_t size)
-{
-  u_char *pnt;
-  u_int16_t type;
-  struct rd_as rd_as;
-  struct rd_ip rd_ip;
-
-  if (size < RD_ADDRSTRLEN)
-    return NULL;
-
-  pnt = prd->val;
-
-  type = decode_rd_type (pnt);
-
-  if (type == RD_TYPE_AS)
-    {
-      decode_rd_as (pnt + 2, &rd_as);
-      snprintf (buf, size, "%u:%d", rd_as.as, rd_as.val);
-      return buf;
-    }
-  else if (type == RD_TYPE_AS4)
-    {
-      decode_rd_as4 (pnt + 2, &rd_as);
-      snprintf (buf, size, "%u:%d", rd_as.as, rd_as.val);
-      return buf;
-    }
-  else if (type == RD_TYPE_IP)
-    {
-      decode_rd_ip (pnt + 2, &rd_ip);
-      snprintf (buf, size, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
-      return buf;
-    }
-#if ENABLE_BGP_VNC
-  else if (type == RD_TYPE_VNC_ETH)
-    {
-      snprintf(buf, size, "LHI:%d, %02x:%02x:%02x:%02x:%02x:%02x",
-           *(pnt+1),   /* LHI */
-           *(pnt+2),   /* MAC[0] */
-           *(pnt+3),
-           *(pnt+4),
-           *(pnt+5),
-           *(pnt+6),
-           *(pnt+7));
-
-      return buf;
-    }
-#endif
-  return NULL;
-}
-
 /* For testing purpose, static route of MPLS-VPN. */
 DEFUN (vpnv4_network,
        vpnv4_network_cmd,
index 4ba4597d069059bdb33ef2a9929e31b6c55ad216..eeb2f63ff362020c1bbb13260c63c6f7b0b5db66 100644 (file)
@@ -1,7 +1,7 @@
 /* MPLS-VPN
  * Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
  *
- * This file is part of GNU Zebra.
+ * This file is part of GxNU 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
 #define _QUAGGA_BGP_MPLSVPN_H
 
 #include "bgpd/bgp_route.h"
-
-#define RD_TYPE_AS      0
-#define RD_TYPE_IP      1
-#define RD_TYPE_AS4     2
-#if ENABLE_BGP_VNC
-#define RD_TYPE_VNC_ETH        0xff00  /* VNC L2VPN */
-#endif
-
-#define RD_ADDRSTRLEN  28
+#include "bgpd/bgp_rd.h"
 
 #ifdef MPLS_LABEL_MAX
 # undef MPLS_LABEL_MAX
@@ -74,44 +66,10 @@ typedef enum {
 #define V4_HEADER_OVERLAY \
   "   Network          Next Hop      EthTag    Overlay Index   RouterMac"
 
-struct rd_as
-{
-  u_int16_t type;
-  as_t as;
-  u_int32_t val;
-};
-
-struct rd_ip
-{
-  u_int16_t type;
-  struct in_addr ip;
-  u_int16_t val;
-};
-
-#if ENABLE_BGP_VNC
-struct rd_vnc_eth
-{
-  u_int16_t type;
-  uint8_t local_nve_id;
-  struct ethaddr macaddr;
-};
-#endif
-
-extern u_int16_t decode_rd_type (u_char *);
-extern void encode_rd_type (u_int16_t, u_char *);
 extern void bgp_mplsvpn_init (void);
 extern int bgp_nlri_parse_vpn (struct peer *, struct attr *, struct bgp_nlri *);
 extern u_int32_t decode_label (mpls_label_t *);
 extern void encode_label(mpls_label_t, mpls_label_t *);
-extern void decode_rd_as (u_char *, struct rd_as *);
-extern void decode_rd_as4 (u_char *, struct rd_as *);
-extern void decode_rd_ip (u_char *, struct rd_ip *);
-#if ENABLE_BGP_VNC
-extern void
-decode_rd_vnc_eth (u_char *pnt, struct rd_vnc_eth *rd_vnc_eth);
-#endif
-extern int str2prefix_rd (const char *, struct prefix_rd *);
-extern char *prefix_rd2str (struct prefix_rd *, char *, size_t);
 
 extern int
 argv_find_and_parse_vpnvx(struct cmd_token **argv, int argc, int *index, afi_t *afi);
diff --git a/bgpd/bgp_rd.c b/bgpd/bgp_rd.c
new file mode 100644 (file)
index 0000000..03257a2
--- /dev/null
@@ -0,0 +1,232 @@
+/* BGP RD definitions for BGP-based VPNs (IP/EVPN)
+ * -- brought over from bgpd/bgp_mplsvpn.c
+ * Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
+ *
+ * This file is part of FRR.
+ *
+ * FRR 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.
+ *
+ * FRR 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 FRR; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <zebra.h>
+#include "command.h"
+#include "log.h"
+#include "prefix.h"
+#include "memory.h"
+#include "stream.h"
+#include "filter.h"
+
+#include "bgpd/bgpd.h"
+#include "bgpd/bgp_rd.h"
+#include "bgpd/bgp_attr.h"
+
+#if ENABLE_BGP_VNC
+#include "bgpd/rfapi/rfapi_backend.h"
+#endif
+
+u_int16_t
+decode_rd_type (u_char *pnt)
+{
+  u_int16_t v;
+
+  v = ((u_int16_t) *pnt++ << 8);
+#if ENABLE_BGP_VNC
+  /*
+   * VNC L2 stores LHI in lower byte, so omit it
+   */
+  if (v != RD_TYPE_VNC_ETH)
+    v |= (u_int16_t) *pnt;
+#else                           /* duplicate code for clarity */
+  v |= (u_int16_t) *pnt;
+#endif
+  return v;
+}
+
+void
+encode_rd_type (u_int16_t v, u_char *pnt)
+{
+  *((u_int16_t *)pnt) = htons(v);
+}
+
+/* type == RD_TYPE_AS */
+void
+decode_rd_as (u_char *pnt, struct rd_as *rd_as)
+{
+  rd_as->as = (u_int16_t) *pnt++ << 8;
+  rd_as->as |= (u_int16_t) *pnt++;
+
+  rd_as->val = ((u_int32_t) *pnt++ << 24);
+  rd_as->val |= ((u_int32_t) *pnt++ << 16);
+  rd_as->val |= ((u_int32_t) *pnt++ << 8);
+  rd_as->val |= (u_int32_t) *pnt;
+}
+
+/* type == RD_TYPE_AS4 */
+void
+decode_rd_as4 (u_char *pnt, struct rd_as *rd_as)
+{
+  rd_as->as  = (u_int32_t) *pnt++ << 24;
+  rd_as->as |= (u_int32_t) *pnt++ << 16;
+  rd_as->as |= (u_int32_t) *pnt++ << 8;
+  rd_as->as |= (u_int32_t) *pnt++;
+
+  rd_as->val  = ((u_int16_t) *pnt++ << 8);
+  rd_as->val |= (u_int16_t) *pnt;
+}
+
+/* type == RD_TYPE_IP */
+void
+decode_rd_ip (u_char *pnt, struct rd_ip *rd_ip)
+{
+  memcpy (&rd_ip->ip, pnt, 4);
+  pnt += 4;
+
+  rd_ip->val = ((u_int16_t) *pnt++ << 8);
+  rd_ip->val |= (u_int16_t) *pnt;
+}
+
+#if ENABLE_BGP_VNC
+/* type == RD_TYPE_VNC_ETH */
+void
+decode_rd_vnc_eth (u_char *pnt, struct rd_vnc_eth *rd_vnc_eth)
+{
+  rd_vnc_eth->type = RD_TYPE_VNC_ETH;
+  rd_vnc_eth->local_nve_id = pnt[1];
+  memcpy (rd_vnc_eth->macaddr.octet, pnt + 2, ETHER_ADDR_LEN);
+}
+#endif
+
+int
+str2prefix_rd (const char *str, struct prefix_rd *prd)
+{
+  int ret; /* ret of called functions */
+  int lret; /* local ret, of this func */
+  char *p;
+  char *p2;
+  struct stream *s = NULL;
+  char *half = NULL;
+  struct in_addr addr;
+
+  s = stream_new (8);
+
+  prd->family = AF_UNSPEC;
+  prd->prefixlen = 64;
+
+  lret = 0;
+  p = strchr (str, ':');
+  if (! p)
+    goto out;
+
+  if (! all_digit (p + 1))
+    goto out;
+
+  half = XMALLOC (MTYPE_TMP, (p - str) + 1);
+  memcpy (half, str, (p - str));
+  half[p - str] = '\0';
+
+  p2 = strchr (str, '.');
+
+  if (! p2)
+    {
+      unsigned long as_val;
+
+      if (! all_digit (half))
+        goto out;
+
+      as_val = atol(half);
+      if (as_val > 0xffff)
+        {
+          stream_putw (s, RD_TYPE_AS4);
+          stream_putl (s, as_val);
+          stream_putw (s, atol (p + 1));
+        }
+      else
+        {
+          stream_putw (s, RD_TYPE_AS);
+          stream_putw (s, as_val);
+          stream_putl (s, atol (p + 1));
+        }
+    }
+  else
+    {
+      ret = inet_aton (half, &addr);
+      if (! ret)
+        goto out;
+
+      stream_putw (s, RD_TYPE_IP);
+      stream_put_in_addr (s, &addr);
+      stream_putw (s, atol (p + 1));
+    }
+  memcpy (prd->val, s->data, 8);
+  lret = 1;
+
+out:
+  if (s)
+    stream_free (s);
+  if (half)
+    XFREE(MTYPE_TMP, half);
+  return lret;
+}
+
+char *
+prefix_rd2str (struct prefix_rd *prd, char *buf, size_t size)
+{
+  u_char *pnt;
+  u_int16_t type;
+  struct rd_as rd_as;
+  struct rd_ip rd_ip;
+
+  if (size < RD_ADDRSTRLEN)
+    return NULL;
+
+  pnt = prd->val;
+
+  type = decode_rd_type (pnt);
+
+  if (type == RD_TYPE_AS)
+    {
+      decode_rd_as (pnt + 2, &rd_as);
+      snprintf (buf, size, "%u:%d", rd_as.as, rd_as.val);
+      return buf;
+    }
+  else if (type == RD_TYPE_AS4)
+    {
+      decode_rd_as4 (pnt + 2, &rd_as);
+      snprintf (buf, size, "%u:%d", rd_as.as, rd_as.val);
+      return buf;
+    }
+  else if (type == RD_TYPE_IP)
+    {
+      decode_rd_ip (pnt + 2, &rd_ip);
+      snprintf (buf, size, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
+      return buf;
+    }
+#if ENABLE_BGP_VNC
+  else if (type == RD_TYPE_VNC_ETH)
+    {
+      snprintf(buf, size, "LHI:%d, %02x:%02x:%02x:%02x:%02x:%02x",
+           *(pnt+1),   /* LHI */
+           *(pnt+2),   /* MAC[0] */
+           *(pnt+3),
+           *(pnt+4),
+           *(pnt+5),
+           *(pnt+6),
+           *(pnt+7));
+
+      return buf;
+    }
+#endif
+  return NULL;
+}
diff --git a/bgpd/bgp_rd.h b/bgpd/bgp_rd.h
new file mode 100644 (file)
index 0000000..2c7df9d
--- /dev/null
@@ -0,0 +1,74 @@
+/* BGP RD definitions for BGP-based VPNs (IP/EVPN)
+ * -- brought over from bgpd/bgp_mplsvpn.h
+ * Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
+ *
+ * This file is part of FRR.
+ *
+ * FRR 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.
+ *
+ * FRR 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 FRR; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef _QUAGGA_BGP_RD_H
+#define _QUAGGA_BGP_RD_H
+
+/* RD types */
+#define RD_TYPE_AS      0
+#define RD_TYPE_IP      1
+#define RD_TYPE_AS4     2
+
+#if ENABLE_BGP_VNC
+#define RD_TYPE_VNC_ETH        0xff00  /* VNC L2VPN */
+#endif
+
+#define RD_ADDRSTRLEN  28
+
+struct rd_as
+{
+  u_int16_t type;
+  as_t as;
+  u_int32_t val;
+};
+
+struct rd_ip
+{
+  u_int16_t type;
+  struct in_addr ip;
+  u_int16_t val;
+};
+
+#if ENABLE_BGP_VNC
+struct rd_vnc_eth
+{
+  u_int16_t type;
+  uint8_t local_nve_id;
+  struct ethaddr macaddr;
+};
+#endif
+
+extern u_int16_t decode_rd_type (u_char *pnt);
+extern void encode_rd_type (u_int16_t, u_char *);
+
+extern void decode_rd_as (u_char *pnt, struct rd_as *rd_as);
+extern void decode_rd_as4 (u_char *pnt, struct rd_as *rd_as);
+extern void decode_rd_ip (u_char *pnt, struct rd_ip *rd_ip);
+#if ENABLE_BGP_VNC
+extern void
+decode_rd_vnc_eth (u_char *pnt, struct rd_vnc_eth *rd_vnc_eth);
+#endif
+
+extern int str2prefix_rd (const char *, struct prefix_rd *);
+extern char *prefix_rd2str (struct prefix_rd *, char *, size_t);
+
+#endif /* _QUAGGA_BGP_RD_H */