diff options
author | vivek <vivek@cumulusnetworks.com> | 2017-05-15 21:33:59 +0200 |
---|---|---|
committer | Donald Sharp <sharpd@cumulusnetworks.com> | 2017-07-12 18:34:32 +0200 |
commit | 8557760ca8d05af9864a02bc2f4a244d02adf10c (patch) | |
tree | 5afc01ed898477a1177d99acd732054cbe6006ea | |
parent | bgpd: Refine extended community handling (diff) | |
download | frr-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.am | 4 | ||||
-rw-r--r-- | bgpd/bgp_mplsvpn.c | 196 | ||||
-rw-r--r-- | bgpd/bgp_mplsvpn.h | 46 | ||||
-rw-r--r-- | bgpd/bgp_rd.c | 232 | ||||
-rw-r--r-- | bgpd/bgp_rd.h | 74 |
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 */ |