summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvivek <vivek@cumulusnetworks.com>2017-05-15 21:33:59 +0200
committerDonald Sharp <sharpd@cumulusnetworks.com>2017-07-12 18:34:32 +0200
commit8557760ca8d05af9864a02bc2f4a244d02adf10c (patch)
tree5afc01ed898477a1177d99acd732054cbe6006ea
parentbgpd: Refine extended community handling (diff)
downloadfrr-8557760ca8d05af9864a02bc2f4a244d02adf10c.tar.xz
frr-8557760ca8d05af9864a02bc2f4a244d02adf10c.zip
bgpd: Separate out RD handling functions
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>
-rw-r--r--bgpd/Makefile.am4
-rw-r--r--bgpd/bgp_mplsvpn.c196
-rw-r--r--bgpd/bgp_mplsvpn.h46
-rw-r--r--bgpd/bgp_rd.c232
-rw-r--r--bgpd/bgp_rd.h74
5 files changed, 310 insertions, 242 deletions
diff --git a/bgpd/Makefile.am b/bgpd/Makefile.am
index f096f0ff1..9a4e5fd6a 100644
--- a/bgpd/Makefile.am
+++ b/bgpd/Makefile.am
@@ -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@
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c
index b5fbfd8bb..3973663e9 100644
--- a/bgpd/bgp_mplsvpn.c
+++ b/bgpd/bgp_mplsvpn.c
@@ -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,
diff --git a/bgpd/bgp_mplsvpn.h b/bgpd/bgp_mplsvpn.h
index 4ba4597d0..eeb2f63ff 100644
--- a/bgpd/bgp_mplsvpn.h
+++ b/bgpd/bgp_mplsvpn.h
@@ -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
@@ -22,15 +22,7 @@
#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
index 000000000..03257a292
--- /dev/null
+++ b/bgpd/bgp_rd.c
@@ -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
index 000000000..2c7df9d74
--- /dev/null
+++ b/bgpd/bgp_rd.h
@@ -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 */