]>
Commit | Line | Data |
---|---|---|
718e3744 | 1 | /* |
2 | * Prefix structure. | |
3 | * Copyright (C) 1998 Kunihiro Ishiguro | |
4 | * | |
5 | * This file is part of GNU Zebra. | |
6 | * | |
7 | * GNU Zebra is free software; you can redistribute it and/or modify it | |
8 | * under the terms of the GNU General Public License as published by the | |
9 | * Free Software Foundation; either version 2, or (at your option) any | |
10 | * later version. | |
11 | * | |
12 | * GNU Zebra is distributed in the hope that it will be useful, but | |
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 | * General Public License for more details. | |
16 | * | |
896014f4 DL |
17 | * You should have received a copy of the GNU General Public License along |
18 | * with this program; see the file COPYING; if not, write to the Free Software | |
19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
718e3744 | 20 | */ |
21 | ||
22 | #ifndef _ZEBRA_PREFIX_H | |
23 | #define _ZEBRA_PREFIX_H | |
24 | ||
32ac65d9 | 25 | #ifdef SUNOS_5 |
d62a17ae | 26 | #include <sys/ethernet.h> |
32ac65d9 | 27 | #else |
d62a17ae | 28 | #ifdef GNU_LINUX |
29 | #include <net/ethernet.h> | |
30 | #else | |
31 | #include <netinet/if_ether.h> | |
32 | #endif | |
32ac65d9 | 33 | #endif |
8cc4198f | 34 | #include "sockunion.h" |
86f1ef44 | 35 | #include "ipaddr.h" |
de1a880c | 36 | #include "compiler.h" |
8cc4198f | 37 | |
7628d862 DS |
38 | #ifndef ETH_ALEN |
39 | #define ETH_ALEN 6 | |
40 | #endif | |
41 | ||
7628d862 | 42 | #define ETHER_ADDR_STRLEN (3*ETH_ALEN) |
32ac65d9 LB |
43 | /* |
44 | * there isn't a portable ethernet address type. We define our | |
45 | * own to simplify internal handling | |
46 | */ | |
47 | struct ethaddr { | |
d7c0a89a | 48 | uint8_t octet[ETH_ALEN]; |
d62a17ae | 49 | } __attribute__((packed)); |
32ac65d9 LB |
50 | |
51 | ||
d62a17ae | 52 | /* length is the number of valuable bits of prefix structure |
9d303b37 DL |
53 | * 18 bytes is current length in structure, if address is ipv4 |
54 | * 30 bytes is in case of ipv6 | |
55 | */ | |
a440846e | 56 | #define PREFIX_LEN_ROUTE_TYPE_5_IPV4 (18*8) |
57 | #define PREFIX_LEN_ROUTE_TYPE_5_IPV6 (30*8) | |
58 | ||
59 | /* EVPN address (RFC 7432) */ | |
d62a17ae | 60 | struct evpn_addr { |
d7c0a89a QY |
61 | uint8_t route_type; |
62 | uint8_t ip_prefix_length; | |
d62a17ae | 63 | struct ethaddr mac; |
64 | uint32_t eth_tag; | |
65 | struct ipaddr ip; | |
86f1ef44 | 66 | #if 0 |
a440846e | 67 | union |
68 | { | |
d7c0a89a | 69 | uint8_t addr; |
a440846e | 70 | struct in_addr v4_addr; |
71 | struct in6_addr v6_addr; | |
72 | } ip; | |
86f1ef44 | 73 | #endif |
a440846e | 74 | }; |
75 | ||
86f1ef44 | 76 | #define IS_EVPN_PREFIX_IPADDR_NONE(evp) IS_IPADDR_NONE(&(evp)->prefix.ip) |
77 | #define IS_EVPN_PREFIX_IPADDR_V4(evp) IS_IPADDR_V4(&(evp)->prefix.ip) | |
78 | #define IS_EVPN_PREFIX_IPADDR_V6(evp) IS_IPADDR_V6(&(evp)->prefix.ip) | |
a440846e | 79 | |
9d24baaa | 80 | /* |
81 | * A struct prefix contains an address family, a prefix length, and an | |
82 | * address. This can represent either a 'network prefix' as defined | |
83 | * by CIDR, where the 'host bits' of the prefix are 0 | |
84 | * (e.g. AF_INET:10.0.0.0/8), or an address and netmask | |
85 | * (e.g. AF_INET:10.0.0.9/8), such as might be configured on an | |
86 | * interface. | |
87 | */ | |
88 | ||
32ac65d9 LB |
89 | /* different OSes use different names */ |
90 | #if defined(AF_PACKET) | |
91 | #define AF_ETHERNET AF_PACKET | |
92 | #else | |
93 | #if defined(AF_LINK) | |
94 | #define AF_ETHERNET AF_LINK | |
95 | #endif | |
96 | #endif | |
97 | ||
b03b8898 DS |
98 | /* The 'family' in the prefix structure is internal to FRR and need not |
99 | * map to standard OS AF_ definitions except where needed for interacting | |
100 | * with the kernel. However, AF_ definitions are currently in use and | |
101 | * prevalent across the code. Define a new FRR-specific AF for EVPN to | |
102 | * distinguish between 'ethernet' (MAC-only) and 'evpn' prefixes and | |
103 | * ensure it does not conflict with any OS AF_ definition. | |
104 | */ | |
105 | #if !defined(AF_EVPN) | |
106 | #define AF_EVPN (AF_MAX + 1) | |
107 | #endif | |
108 | ||
9a14899b PG |
109 | #if !defined(AF_FLOWSPEC) |
110 | #define AF_FLOWSPEC (AF_MAX + 2) | |
111 | #endif | |
112 | ||
113 | struct flowspec_prefix { | |
114 | uint16_t prefixlen; /* length in bytes */ | |
115 | uintptr_t ptr; | |
116 | }; | |
117 | ||
b03b8898 | 118 | /* FRR generic prefix structure. */ |
d62a17ae | 119 | struct prefix { |
d7c0a89a QY |
120 | uint8_t family; |
121 | uint8_t prefixlen; | |
d62a17ae | 122 | union { |
d7c0a89a | 123 | uint8_t prefix; |
d62a17ae | 124 | struct in_addr prefix4; |
125 | struct in6_addr prefix6; | |
126 | struct { | |
127 | struct in_addr id; | |
128 | struct in_addr adv_router; | |
129 | } lp; | |
130 | struct ethaddr prefix_eth; /* AF_ETHERNET */ | |
d7c0a89a | 131 | uint8_t val[16]; |
d62a17ae | 132 | uintptr_t ptr; |
b03b8898 | 133 | struct evpn_addr prefix_evpn; /* AF_EVPN */ |
9a14899b | 134 | struct flowspec_prefix prefix_flowspec; /* AF_FLOWSPEC */ |
d62a17ae | 135 | } u __attribute__((aligned(8))); |
718e3744 | 136 | }; |
137 | ||
138 | /* IPv4 prefix structure. */ | |
d62a17ae | 139 | struct prefix_ipv4 { |
d7c0a89a QY |
140 | uint8_t family; |
141 | uint8_t prefixlen; | |
d62a17ae | 142 | struct in_addr prefix __attribute__((aligned(8))); |
718e3744 | 143 | }; |
144 | ||
145 | /* IPv6 prefix structure. */ | |
d62a17ae | 146 | struct prefix_ipv6 { |
d7c0a89a QY |
147 | uint8_t family; |
148 | uint8_t prefixlen; | |
d62a17ae | 149 | struct in6_addr prefix __attribute__((aligned(8))); |
718e3744 | 150 | }; |
718e3744 | 151 | |
d62a17ae | 152 | struct prefix_ls { |
d7c0a89a QY |
153 | uint8_t family; |
154 | uint8_t prefixlen; | |
d62a17ae | 155 | struct in_addr id __attribute__((aligned(8))); |
156 | struct in_addr adv_router; | |
718e3744 | 157 | }; |
158 | ||
159 | /* Prefix for routing distinguisher. */ | |
d62a17ae | 160 | struct prefix_rd { |
d7c0a89a QY |
161 | uint8_t family; |
162 | uint8_t prefixlen; | |
163 | uint8_t val[8] __attribute__((aligned(8))); | |
718e3744 | 164 | }; |
165 | ||
32ac65d9 | 166 | /* Prefix for ethernet. */ |
d62a17ae | 167 | struct prefix_eth { |
d7c0a89a QY |
168 | uint8_t family; |
169 | uint8_t prefixlen; | |
d62a17ae | 170 | struct ethaddr eth_addr __attribute__((aligned(8))); /* AF_ETHERNET */ |
32ac65d9 LB |
171 | }; |
172 | ||
86f1ef44 | 173 | /* EVPN prefix structure. */ |
d62a17ae | 174 | struct prefix_evpn { |
d7c0a89a QY |
175 | uint8_t family; |
176 | uint8_t prefixlen; | |
d62a17ae | 177 | struct evpn_addr prefix __attribute__((aligned(8))); |
86f1ef44 | 178 | }; |
179 | ||
b4b359a2 | 180 | /* Prefix for a generic pointer */ |
d62a17ae | 181 | struct prefix_ptr { |
d7c0a89a QY |
182 | uint8_t family; |
183 | uint8_t prefixlen; | |
d62a17ae | 184 | uintptr_t prefix __attribute__((aligned(8))); |
b4b359a2 PM |
185 | }; |
186 | ||
9a14899b PG |
187 | /* Prefix for a Flowspec entry */ |
188 | struct prefix_fs { | |
189 | uint8_t family; | |
190 | uint8_t prefixlen; /* unused */ | |
191 | struct flowspec_prefix prefix __attribute__((aligned(8))); | |
192 | }; | |
193 | ||
d62a17ae | 194 | struct prefix_sg { |
d7c0a89a QY |
195 | uint8_t family; |
196 | uint8_t prefixlen; | |
d62a17ae | 197 | struct in_addr src __attribute__((aligned(8))); |
198 | struct in_addr grp; | |
e9219290 DS |
199 | }; |
200 | ||
f7bf4153 DL |
201 | /* helper to get type safety/avoid casts on calls |
202 | * (w/o this, functions accepting all prefix types need casts on the caller | |
203 | * side, which strips type safety since the cast will accept any pointer | |
204 | * type.) | |
205 | */ | |
d62a17ae | 206 | union prefixptr { |
207 | struct prefix *p; | |
208 | struct prefix_ipv4 *p4; | |
209 | struct prefix_ipv6 *p6; | |
210 | struct prefix_evpn *evp; | |
9a14899b | 211 | const struct prefix_fs *fs; |
d62a17ae | 212 | } __attribute__((transparent_union)); |
213 | ||
214 | union prefixconstptr { | |
215 | const struct prefix *p; | |
216 | const struct prefix_ipv4 *p4; | |
217 | const struct prefix_ipv6 *p6; | |
218 | const struct prefix_evpn *evp; | |
9a14899b | 219 | const struct prefix_fs *fs; |
d62a17ae | 220 | } __attribute__((transparent_union)); |
f7bf4153 | 221 | |
718e3744 | 222 | #ifndef INET_ADDRSTRLEN |
223 | #define INET_ADDRSTRLEN 16 | |
224 | #endif /* INET_ADDRSTRLEN */ | |
225 | ||
226 | #ifndef INET6_ADDRSTRLEN | |
227 | #define INET6_ADDRSTRLEN 46 | |
228 | #endif /* INET6_ADDRSTRLEN */ | |
229 | ||
230 | #ifndef INET6_BUFSIZ | |
231 | #define INET6_BUFSIZ 51 | |
232 | #endif /* INET6_BUFSIZ */ | |
233 | ||
855110bb TT |
234 | /* Maximum prefix string length (IPv6) */ |
235 | #define PREFIX_STRLEN 51 | |
236 | ||
718e3744 | 237 | /* Max bit/byte length of IPv4 address. */ |
238 | #define IPV4_MAX_BYTELEN 4 | |
239 | #define IPV4_MAX_BITLEN 32 | |
240 | #define IPV4_MAX_PREFIXLEN 32 | |
241 | #define IPV4_ADDR_CMP(D,S) memcmp ((D), (S), IPV4_MAX_BYTELEN) | |
19aad877 JB |
242 | |
243 | static inline bool ipv4_addr_same(const struct in_addr *a, | |
244 | const struct in_addr *b) | |
245 | { | |
246 | return (a->s_addr == b->s_addr); | |
247 | } | |
248 | #define IPV4_ADDR_SAME(A,B) ipv4_addr_same((A), (B)) | |
249 | ||
250 | static inline void ipv4_addr_copy(struct in_addr *dst, | |
251 | const struct in_addr *src) | |
252 | { | |
253 | dst->s_addr = src->s_addr; | |
254 | } | |
255 | #define IPV4_ADDR_COPY(D,S) ipv4_addr_copy((D), (S)) | |
718e3744 | 256 | |
d7c0a89a QY |
257 | #define IPV4_NET0(a) ((((uint32_t)(a)) & 0xff000000) == 0x00000000) |
258 | #define IPV4_NET127(a) ((((uint32_t)(a)) & 0xff000000) == 0x7f000000) | |
259 | #define IPV4_LINKLOCAL(a) ((((uint32_t)(a)) & 0xffff0000) == 0xa9fe0000) | |
260 | #define IPV4_CLASS_DE(a) ((((uint32_t)(a)) & 0xe0000000) == 0xe0000000) | |
261 | #define IPV4_MC_LINKLOCAL(a) ((((uint32_t)(a)) & 0xffffff00) == 0xe0000000) | |
718e3744 | 262 | |
263 | /* Max bit/byte length of IPv6 address. */ | |
264 | #define IPV6_MAX_BYTELEN 16 | |
265 | #define IPV6_MAX_BITLEN 128 | |
266 | #define IPV6_MAX_PREFIXLEN 128 | |
267 | #define IPV6_ADDR_CMP(D,S) memcmp ((D), (S), IPV6_MAX_BYTELEN) | |
268 | #define IPV6_ADDR_SAME(D,S) (memcmp ((D), (S), IPV6_MAX_BYTELEN) == 0) | |
269 | #define IPV6_ADDR_COPY(D,S) memcpy ((D), (S), IPV6_MAX_BYTELEN) | |
270 | ||
271 | /* Count prefix size from mask length */ | |
272 | #define PSIZE(a) (((a) + 7) / (8)) | |
273 | ||
cd1964ff DS |
274 | #define BSIZE(a) ((a) * (8)) |
275 | ||
718e3744 | 276 | /* Prefix's family member. */ |
277 | #define PREFIX_FAMILY(p) ((p)->family) | |
278 | ||
5c6ed111 DL |
279 | /* glibc defines s6_addr32 to __in6_u.__u6_addr32 if __USE_{MISC || GNU} */ |
280 | #ifndef s6_addr32 | |
281 | #if defined(SUNOS_5) | |
282 | /* Some SunOS define s6_addr32 only to kernel */ | |
283 | #define s6_addr32 _S6_un._S6_u32 | |
284 | #else | |
285 | #define s6_addr32 __u6_addr.__u6_addr32 | |
286 | #endif /* SUNOS_5 */ | |
287 | #endif /*s6_addr32*/ | |
288 | ||
718e3744 | 289 | /* Prototypes. */ |
f3ccedaa | 290 | extern int str2family(const char *); |
d62a17ae | 291 | extern int afi2family(afi_t); |
292 | extern afi_t family2afi(int); | |
db2fde34 | 293 | extern const char *family2str(int family); |
1ec23d90 | 294 | extern const char *safi2str(safi_t safi); |
32ac65d9 | 295 | extern const char *afi2str(afi_t afi); |
8cc4198f | 296 | |
f63f06da | 297 | /* Check bit of the prefix. */ |
d7c0a89a | 298 | extern unsigned int prefix_bit(const uint8_t *prefix, const uint8_t prefixlen); |
d62a17ae | 299 | extern unsigned int prefix6_bit(const struct in6_addr *prefix, |
d7c0a89a | 300 | const uint8_t prefixlen); |
f63f06da | 301 | |
d62a17ae | 302 | extern struct prefix *prefix_new(void); |
303 | extern void prefix_free(struct prefix *); | |
304 | extern const char *prefix_family_str(const struct prefix *); | |
305 | extern int prefix_blen(const struct prefix *); | |
306 | extern int str2prefix(const char *, struct prefix *); | |
4690c7d7 | 307 | |
a9ea959f | 308 | #define PREFIX2STR_BUFFER PREFIX_STRLEN |
309 | ||
d62a17ae | 310 | extern const char *prefix2str(union prefixconstptr, char *, int); |
311 | extern int prefix_match(const struct prefix *, const struct prefix *); | |
312 | extern int prefix_match_network_statement(const struct prefix *, | |
313 | const struct prefix *); | |
314 | extern int prefix_same(const struct prefix *, const struct prefix *); | |
315 | extern int prefix_cmp(const struct prefix *, const struct prefix *); | |
316 | extern int prefix_common_bits(const struct prefix *, const struct prefix *); | |
317 | extern void prefix_copy(struct prefix *dest, const struct prefix *src); | |
318 | extern void apply_mask(struct prefix *); | |
319 | ||
320 | extern struct prefix *sockunion2prefix(const union sockunion *dest, | |
321 | const union sockunion *mask); | |
322 | extern struct prefix *sockunion2hostprefix(const union sockunion *, | |
323 | struct prefix *p); | |
324 | extern void prefix2sockunion(const struct prefix *, union sockunion *); | |
325 | ||
326 | extern int str2prefix_eth(const char *, struct prefix_eth *); | |
327 | ||
328 | extern struct prefix_ipv4 *prefix_ipv4_new(void); | |
329 | extern void prefix_ipv4_free(struct prefix_ipv4 *); | |
330 | extern int str2prefix_ipv4(const char *, struct prefix_ipv4 *); | |
331 | extern void apply_mask_ipv4(struct prefix_ipv4 *); | |
332 | ||
996c9314 | 333 | #define PREFIX_COPY(DST, SRC) \ |
72a1b201 | 334 | *((struct prefix *)(DST)) = *((const struct prefix *)(SRC)) |
996c9314 | 335 | #define PREFIX_COPY_IPV4(DST, SRC) \ |
e4529636 AS |
336 | *((struct prefix_ipv4 *)(DST)) = *((const struct prefix_ipv4 *)(SRC)); |
337 | ||
d62a17ae | 338 | extern int prefix_ipv4_any(const struct prefix_ipv4 *); |
339 | extern void apply_classful_mask_ipv4(struct prefix_ipv4 *); | |
8cc4198f | 340 | |
d7c0a89a | 341 | extern uint8_t ip_masklen(struct in_addr); |
d62a17ae | 342 | extern void masklen2ip(const int, struct in_addr *); |
3fb9cd6e | 343 | /* returns the network portion of the host address */ |
d62a17ae | 344 | extern in_addr_t ipv4_network_addr(in_addr_t hostaddr, int masklen); |
3fb9cd6e | 345 | /* given the address of a host on a network and the network mask length, |
346 | * calculate the broadcast address for that network; | |
347 | * special treatment for /31: returns the address of the other host | |
348 | * on the network by flipping the host bit */ | |
d62a17ae | 349 | extern in_addr_t ipv4_broadcast_addr(in_addr_t hostaddr, int masklen); |
3fb9cd6e | 350 | |
d62a17ae | 351 | extern int netmask_str2prefix_str(const char *, const char *, char *); |
718e3744 | 352 | |
d62a17ae | 353 | extern struct prefix_ipv6 *prefix_ipv6_new(void); |
354 | extern void prefix_ipv6_free(struct prefix_ipv6 *); | |
355 | extern int str2prefix_ipv6(const char *, struct prefix_ipv6 *); | |
356 | extern void apply_mask_ipv6(struct prefix_ipv6 *); | |
718e3744 | 357 | |
d62a17ae | 358 | #define PREFIX_COPY_IPV6(DST, SRC) \ |
e4529636 AS |
359 | *((struct prefix_ipv6 *)(DST)) = *((const struct prefix_ipv6 *)(SRC)); |
360 | ||
d62a17ae | 361 | extern int ip6_masklen(struct in6_addr); |
362 | extern void masklen2ip6(const int, struct in6_addr *); | |
b04c699e | 363 | |
d62a17ae | 364 | extern const char *inet6_ntoa(struct in6_addr); |
5920990f | 365 | |
523cafc4 | 366 | extern int is_zero_mac(struct ethaddr *mac); |
db42a173 PG |
367 | extern int prefix_str2mac(const char *str, struct ethaddr *mac); |
368 | extern char *prefix_mac2str(const struct ethaddr *mac, char *buf, int size); | |
c215ecaf | 369 | |
7a7761d2 CF |
370 | extern unsigned prefix_hash_key(void *pp); |
371 | ||
d62a17ae | 372 | static inline int ipv6_martian(struct in6_addr *addr) |
d914d5ff | 373 | { |
d62a17ae | 374 | struct in6_addr localhost_addr; |
d914d5ff | 375 | |
d62a17ae | 376 | inet_pton(AF_INET6, "::1", &localhost_addr); |
d914d5ff | 377 | |
d62a17ae | 378 | if (IPV6_ADDR_SAME(&localhost_addr, addr)) |
379 | return 1; | |
d914d5ff | 380 | |
d62a17ae | 381 | return 0; |
d914d5ff DS |
382 | } |
383 | ||
d62a17ae | 384 | extern int all_digit(const char *); |
d37ba549 | 385 | extern int macstr2prefix_evpn(const char *str, struct prefix_evpn *p); |
718e3744 | 386 | |
d914d5ff | 387 | /* NOTE: This routine expects the address argument in network byte order. */ |
d62a17ae | 388 | static inline int ipv4_martian(struct in_addr *addr) |
6ee06fa9 | 389 | { |
d62a17ae | 390 | in_addr_t ip = ntohl(addr->s_addr); |
6ee06fa9 | 391 | |
d62a17ae | 392 | if (IPV4_NET0(ip) || IPV4_NET127(ip) || IPV4_CLASS_DE(ip)) { |
393 | return 1; | |
394 | } | |
395 | return 0; | |
6ee06fa9 PM |
396 | } |
397 | ||
f229873a | 398 | static inline int is_default_prefix(const struct prefix *p) |
18ff3edd | 399 | { |
d62a17ae | 400 | if (!p) |
401 | return 0; | |
18ff3edd | 402 | |
996c9314 LB |
403 | if ((p->family == AF_INET) && (p->u.prefix4.s_addr == INADDR_ANY) |
404 | && (p->prefixlen == 0)) | |
f229873a DS |
405 | return 1; |
406 | ||
996c9314 LB |
407 | if ((p->family == AF_INET6) && (p->prefixlen == 0) |
408 | && (!memcmp(&p->u.prefix6, &in6addr_any, sizeof(struct in6_addr)))) | |
d62a17ae | 409 | return 1; |
18ff3edd | 410 | |
d62a17ae | 411 | return 0; |
18ff3edd DS |
412 | } |
413 | ||
408b00c4 MK |
414 | static inline int is_host_route(struct prefix *p) |
415 | { | |
416 | if (p->family == AF_INET) | |
417 | return (p->prefixlen == IPV4_MAX_BITLEN); | |
418 | else if (p->family == AF_INET6) | |
419 | return (p->prefixlen == IPV6_MAX_BITLEN); | |
420 | return 0; | |
421 | } | |
422 | ||
718e3744 | 423 | #endif /* _ZEBRA_PREFIX_H */ |