1 /* 2 * Copyright (c) 2013-2015 Cisco Systems, Inc. and others. All rights reserved. 3 * 4 * This program and the accompanying materials are made available under the 5 * terms of the Eclipse Public License v1.0 which accompanies this distribution, 6 * and is available at http://www.eclipse.org/legal/epl-v10.html 7 * 8 */ 9 10 #ifndef BGPCOMMON_H_ 11 #define BGPCOMMON_H_ 12 13 #include <string> 14 #include <cstdint> 15 #include <sstream> 16 #include <cinttypes> 17 #include <cstring> 18 #include <sys/types.h> 19 20 namespace bgp { 21 #define BGP_MAX_MSG_SIZE 65535 // Max payload size - Larger than RFC4271 of 4096 22 #define BGP_MSG_HDR_LEN 19 // BGP message header size 23 #define BGP_OPEN_MSG_MIN_LEN 29 // Includes the expected header size 24 #define BGP_VERSION 4 25 #define BGP_CAP_PARAM_TYPE 2 26 #define BGP_AS_TRANS 23456 // BGP ASN when AS exceeds 16bits 27 28 29 /** 30 * defines whether the attribute is optional (if 31 * set to 1) or well-known (if set to 0) 32 */ 33 #define ATTR_FLAG_OPT(flags) ( flags & 0x80 ) 34 35 /** 36 * defines whether an optional attribute is 37 * transitive (if set to 1) or non-transitive (if set to 0) 38 */ 39 #define ATTR_FLAG_TRANS(flags) ( flags & 0x40 ) 40 41 /** 42 * defines whether the information contained in the 43 * (if set to 1) or complete (if set to 0) 44 */ 45 #define ATTR_FLAG_PARTIAL(flags) ( flags & 0x20 ) 46 47 /** 48 * defines whether the Attribute Length is one octet 49 * (if set to 0) or two octets (if set to 1) 50 * 51 * \details 52 * If the Extended Length bit of the Attribute Flags octet is set 53 * to 0, the third octet of the Path Attribute contains the length 54 * of the attribute data in octets. 55 * 56 * If the Extended Length bit of the Attribute Flags octet is set 57 * to 1, the third and fourth octets of the path attribute contain 58 * the length of the attribute data in octets. 59 */ 60 #define ATTR_FLAG_EXTENDED(flags) ( flags & 0x10 ) 61 62 /** 63 * Defines the BGP address-families (AFI) 64 * http://www.iana.org/assignments/address-family-numbers/address-family-numbers.xhtml 65 */ 66 enum BGP_AFI { 67 BGP_AFI_IPV4=1, 68 BGP_AFI_IPV6=2, 69 BGP_AFI_L2VPN=25, 70 BGP_AFI_BGPLS=16388 71 }; 72 73 /** 74 * Defines the BGP subsequent address-families (SAFI) 75 * http://www.iana.org/assignments/safi-namespace/safi-namespace.xhtml 76 */ 77 enum BGP_SAFI { 78 BGP_SAFI_UNICAST=1, 79 BGP_SAFI_MULTICAST=2, 80 81 BGP_SAFI_NLRI_LABEL=4, // RFC3107 82 BGP_SAFI_MCAST_VPN, // RFC6514 83 84 BGP_SAFI_VPLS=65, // RFC4761, RFC6074 85 BGP_SAFI_MDT, // RFC6037 86 BGP_SAFI_4over6, // RFC5747 87 BGP_SAFI_6over4, // yong cui 88 89 BGP_SAFI_EVPN=70, // draft-ietf-l2vpn-evpn 90 BGP_SAFI_BGPLS=71, // draft-ietf-idr-ls-distribution 91 92 BGP_SAFI_MPLS=128, // RFC4364 93 BGP_SAFI_MCAST_MPLS_VPN, // RFC6513, RFC6514 94 95 BGP_SAFI_RT_CONSTRAINS=132 // RFC4684 96 }; 97 98 /** 99 * ENUM to define the prefix type used for prefix nlri maps in returned data 100 */ 101 enum PREFIX_TYPE { 102 PREFIX_UNICAST_V4=1, 103 PREFIX_UNICAST_V6, 104 PREFIX_LABEL_UNICAST_V4, 105 PREFIX_LABEL_UNICAST_V6, 106 PREFIX_VPN_V4, 107 PREFIX_VPN_v6, 108 PREFIX_MULTICAST_V4, 109 // Add BGP-LS types 110 }; 111 112 /** 113 * struct is used for nlri prefixes 114 */ 115 struct prefix_tuple { 116 /** 117 * len in bits of the IP address prefix 118 * length of 0 indicates a prefix that matches all IP addresses 119 */ 120 PREFIX_TYPE type; ///< Prefix type - RIB type 121 unsigned char len; ///< Length of prefix in bits 122 std::string prefix; ///< Printed form of the IP address 123 uint8_t prefix_bin[16]; ///< Prefix in binary form 124 uint32_t path_id; ///< Path ID (add path draft-ietf-idr-add-paths-15) 125 bool isIPv4; ///< True if IPv4, false if IPv6 126 127 std::string labels; ///< Labels in the format of label, label, ... 128 }; 129 130 /** 131 * Struct for Route Distinguisher 132 */ 133 struct rd_tuple { 134 std::string rd_administrator_subfield; 135 std::string rd_assigned_number; 136 uint8_t rd_type; 137 }; 138 139 /** 140 * struct is used for l3vpn 141 */ 142 struct vpn_tuple: prefix_tuple, rd_tuple { 143 // inherits 144 }; 145 146 /** 147 * Struct is used for evpn 148 */ 149 struct evpn_tuple: prefix_tuple, rd_tuple { 150 std::string ethernet_segment_identifier; 151 std::string ethernet_tag_id_hex; 152 uint8_t mac_len; 153 std::string mac; 154 uint8_t ip_len; 155 std::string ip; 156 int mpls_label_1; 157 int mpls_label_2; 158 uint8_t originating_router_ip_len; 159 std::string originating_router_ip; 160 }; 161 162 /*********************************************************************//** 163 * Simple function to swap bytes around from network to host or 164 * host to networking. This method will convert any size byte variable, 165 * unlike ntohs and ntohl. 166 * 167 * @param [in/out] var Variable containing data to update 168 * @param [in] size Size of var - Default is size of var 169 *********************************************************************/ parse_mac(u_char * data_pointer)170 inline std::string parse_mac(u_char *data_pointer) { 171 u_char *pointer = data_pointer; 172 173 std::ostringstream mac_stringstream; 174 175 for (int i = 0; i < 6; ++i) { 176 if (i != 0) mac_stringstream << ':'; 177 mac_stringstream.width(2); 178 mac_stringstream.fill('0'); 179 mac_stringstream << std::hex << (int)(pointer[i]); 180 } 181 182 return mac_stringstream.str(); 183 } 184 185 /*********************************************************************//** 186 * Simple function to swap bytes around from network to host or 187 * host to networking. This method will convert any size byte variable, 188 * unlike ntohs and ntohl. 189 * 190 * @param [in/out] var Variable containing data to update 191 * @param [in] size Size of var - Default is size of var 192 *********************************************************************/ 193 template <typename VarT> 194 void SWAP_BYTES(VarT *var, int size=sizeof(VarT)) { 195 if (size <= 1) 196 return; 197 198 u_char *v = (u_char *)var; 199 200 // Allocate a working buffer 201 u_char buf[size]; 202 203 // Make a copy 204 memcpy(buf, var, size); 205 206 int i2 = 0; 207 for (int i=size-1; i >= 0; i--) 208 v[i2++] = buf[i]; 209 210 } 211 212 /** 213 * Function to get string representation of AFI code. 214 * @param code AFI http://www.iana.org/assignments/address-family-numbers/address-family-numbers.xhtml 215 * @return string like "IPv6" or "IPv4" 216 */ GET_AFI_STRING_BY_CODE(int code)217 inline std::string GET_AFI_STRING_BY_CODE(int code) { 218 std::string afi_string; 219 220 switch (code) { 221 case bgp::BGP_AFI_IPV4 : 222 afi_string = "IPv4"; 223 break; 224 225 case bgp::BGP_AFI_IPV6 : 226 afi_string = "IPv6"; 227 break; 228 229 case bgp::BGP_AFI_BGPLS : 230 afi_string = "BGP-LS"; 231 break; 232 233 default: 234 afi_string = "unknown"; 235 break; 236 } 237 return afi_string; 238 } 239 240 /** 241 * Function to get string representation of SAFI code. 242 * @param code SAFI http://www.iana.org/assignments/safi-namespace/safi-namespace.xhtml 243 * @return string like "Unicast" or "Multicast" 244 */ GET_SAFI_STRING_BY_CODE(int code)245 inline std::string GET_SAFI_STRING_BY_CODE(int code) { 246 std::string safi_string; 247 248 switch (code) { 249 case bgp::BGP_SAFI_UNICAST : // Unicast IP forwarding 250 safi_string = "Unicast"; 251 break; 252 253 case bgp::BGP_SAFI_MULTICAST : // Multicast IP forwarding 254 safi_string = "Multicast"; 255 break; 256 257 case bgp::BGP_SAFI_NLRI_LABEL : // NLRI with MPLS Labels 258 safi_string = "Labeled Unicast"; 259 break; 260 261 case bgp::BGP_SAFI_MCAST_VPN : // MCAST VPN 262 safi_string = "MCAST VPN"; 263 break; 264 265 case bgp::BGP_SAFI_VPLS : // VPLS 266 safi_string = "VPLS"; 267 break; 268 269 case bgp::BGP_SAFI_MDT : // BGP MDT 270 safi_string = "BGP MDT"; 271 break; 272 273 case bgp::BGP_SAFI_4over6 : // BGP 4over6 274 safi_string = "BGP 4over6"; 275 break; 276 277 case bgp::BGP_SAFI_6over4 : // BGP 6over4 278 safi_string = "BGP 6over4"; 279 break; 280 281 case bgp::BGP_SAFI_EVPN : // BGP EVPNs 282 safi_string = "BGP EVPNs"; 283 break; 284 285 case bgp::BGP_SAFI_BGPLS : // BGP-LS 286 safi_string = "BGP-LS"; 287 break; 288 289 case bgp::BGP_SAFI_MPLS : // MPLS-Labeled VPN 290 safi_string = "MPLS-Labeled VPN"; 291 break; 292 293 case bgp::BGP_SAFI_MCAST_MPLS_VPN : // Multicast BGP/MPLS VPN 294 safi_string = "Multicast BGP/MPLS VPN"; 295 break; 296 297 case bgp::BGP_SAFI_RT_CONSTRAINS : // Route target constrains 298 safi_string = "RT constrains"; 299 break; 300 301 } 302 return safi_string; 303 } 304 305 } 306 307 #endif /* BGPCOMMON_H */ 308