diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/Makefile.am | 3 | ||||
| -rw-r--r-- | lib/bitfield.h | 28 | ||||
| -rw-r--r-- | lib/hash.h | 2 | ||||
| -rw-r--r-- | lib/ipaddr.h | 94 | ||||
| -rw-r--r-- | lib/prefix.c | 83 | ||||
| -rw-r--r-- | lib/prefix.h | 30 | ||||
| -rw-r--r-- | lib/vlan.h | 29 | ||||
| -rw-r--r-- | lib/vxlan.h | 29 |
8 files changed, 262 insertions, 36 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am index e1b84587da..5847ad4939 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -86,6 +86,9 @@ pkginclude_HEADERS = \ frr_pthread.h \ vrf_int.h \ termtable.h \ + vlan.h \ + vxlan.h \ + ipaddr.h \ # end noinst_HEADERS = \ diff --git a/lib/bitfield.h b/lib/bitfield.h index 4ff9c7fb2e..1e0b54731a 100644 --- a/lib/bitfield.h +++ b/lib/bitfield.h @@ -78,12 +78,27 @@ typedef unsigned int word_t; bf_set_bit(v, id); \ } while (0) -/** +/* + * allocate and assign 0th bit in the bitfiled. + */ +#define bf_assign_zero_index(v) \ + do { \ + int id = 0; \ + bf_assign_index(v, id); \ + } while (0) + +/* * return an id to bitfield v */ #define bf_release_index(v, id) \ (v).data[bf_index(id)] &= ~(1 << (bf_offset(id))) +/* + * return 0th index back to bitfield + */ +#define bf_release_zero_index(v) \ + bf_release_index(v, 0) + #define bf_index(b) ((b) / WORD_SIZE) #define bf_offset(b) ((b) % WORD_SIZE) @@ -118,4 +133,15 @@ typedef unsigned int word_t; (b) += (w * WORD_SIZE); \ } while (0) +/* + * Free the allocated memory for data + * @v: an instance of bitfield_t struct. + */ +#define bf_free(v) \ + do { \ + if ((v).data) { \ + free((v).data); \ + } \ + } while (0) + #endif diff --git a/lib/hash.h b/lib/hash.h index 9395440acb..01d2b1ddc8 100644 --- a/lib/hash.h +++ b/lib/hash.h @@ -84,6 +84,8 @@ struct hash char *name; }; +#define hashcount(X) ((X)->count) + extern struct hash *hash_create (unsigned int (*) (void *), int (*) (const void *, const void *), const char *); diff --git a/lib/ipaddr.h b/lib/ipaddr.h new file mode 100644 index 0000000000..ea98a1b746 --- /dev/null +++ b/lib/ipaddr.h @@ -0,0 +1,94 @@ +/* + * IP address structure (for generic IPv4 or IPv6 address) + * Copyright (C) 2016, 2017 Cumulus Networks, Inc. + * + * 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 __IPADDR_H__ +#define __IPADDR_H__ + +#include <zebra.h> + +/* + * Generic IP address - union of IPv4 and IPv6 address. + */ +enum ipaddr_type_t +{ + IPADDR_NONE = 0, + IPADDR_V4 = 1, /* IPv4 */ + IPADDR_V6 = 2, /* IPv6 */ +}; + +struct ipaddr +{ + enum ipaddr_type_t ipa_type; + union + { + u_char addr; + struct in_addr _v4_addr; + struct in6_addr _v6_addr; + } ip; +#define ipaddr_v4 ip._v4_addr +#define ipaddr_v6 ip._v6_addr +}; + +#define IS_IPADDR_NONE(p) ((p)->ipa_type == IPADDR_NONE) +#define IS_IPADDR_V4(p) ((p)->ipa_type == IPADDR_V4) +#define IS_IPADDR_V6(p) ((p)->ipa_type == IPADDR_V6) + +#define SET_IPADDR_V4(p) (p)->ipa_type = IPADDR_V4 +#define SET_IPADDR_V6(p) (p)->ipa_type = IPADDR_V6 + +static inline int +str2ipaddr (const char *str, struct ipaddr *ip) +{ + int ret; + + memset (ip, 0, sizeof (struct ipaddr)); + + ret = inet_pton (AF_INET, str, &ip->ipaddr_v4); + if (ret > 0) /* Valid IPv4 address. */ + { + ip->ipa_type = IPADDR_V4; + return 0; + } + ret = inet_pton (AF_INET6, str, &ip->ipaddr_v6); + if (ret > 0) /* Valid IPv6 address. */ + { + ip->ipa_type = IPADDR_V6; + return 0; + } + + return -1; +} + +static inline char * +ipaddr2str (struct ipaddr *ip, char *buf, int size) +{ + buf[0] = '\0'; + if (ip) + { + if (IS_IPADDR_V4(ip)) + inet_ntop (AF_INET, &ip->ip.addr, buf, size); + else if (IS_IPADDR_V6(ip)) + inet_ntop (AF_INET6, &ip->ip.addr, buf, size); + } + return buf; +} +#endif /* __IPADDR_H__ */ diff --git a/lib/prefix.c b/lib/prefix.c index 4131f37fbd..f89b5a5ee6 100644 --- a/lib/prefix.c +++ b/lib/prefix.c @@ -877,6 +877,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) { @@ -893,28 +953,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; diff --git a/lib/prefix.h b/lib/prefix.h index 24144e80a3..549798e92e 100644 --- a/lib/prefix.h +++ b/lib/prefix.h @@ -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; + struct ipaddr 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 { diff --git a/lib/vlan.h b/lib/vlan.h new file mode 100644 index 0000000000..5e735aac1f --- /dev/null +++ b/lib/vlan.h @@ -0,0 +1,29 @@ +/* VLAN (802.1q) common header. + * Copyright (C) 2016, 2017 Cumulus Networks, Inc. + * + * 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 __VLAN_H__ +#define __VLAN_H__ + +/* VLAN Identifier */ +typedef u_int16_t vlanid_t; +#define VLANID_MAX 4095 + +#endif /* __VLAN_H__ */ diff --git a/lib/vxlan.h b/lib/vxlan.h new file mode 100644 index 0000000000..75c7b97347 --- /dev/null +++ b/lib/vxlan.h @@ -0,0 +1,29 @@ +/* VxLAN common header. + * Copyright (C) 2016, 2017 Cumulus Networks, Inc. + * + * 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 __VXLAN_H__ +#define __VXLAN_H__ + +/* VxLAN Network Identifier - 24-bit (RFC 7348) */ +typedef u_int32_t vni_t; +#define VNI_MAX 16777215 /* (2^24 - 1) */ + +#endif /* __VXLAN_H__ */ |
