]>
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 | |
5e244469 RW |
38 | #ifdef __cplusplus |
39 | extern "C" { | |
40 | #endif | |
41 | ||
7628d862 DS |
42 | #ifndef ETH_ALEN |
43 | #define ETH_ALEN 6 | |
44 | #endif | |
45 | ||
50f74cf1 | 46 | #define ESI_BYTES 10 |
2bb9eff4 | 47 | #define ESI_STR_LEN (3 * ESI_BYTES) |
50f74cf1 | 48 | |
7628d862 | 49 | #define ETHER_ADDR_STRLEN (3*ETH_ALEN) |
32ac65d9 LB |
50 | /* |
51 | * there isn't a portable ethernet address type. We define our | |
52 | * own to simplify internal handling | |
53 | */ | |
54 | struct ethaddr { | |
d7c0a89a | 55 | uint8_t octet[ETH_ALEN]; |
d62a17ae | 56 | } __attribute__((packed)); |
32ac65d9 LB |
57 | |
58 | ||
d62a17ae | 59 | /* length is the number of valuable bits of prefix structure |
9d303b37 DL |
60 | * 18 bytes is current length in structure, if address is ipv4 |
61 | * 30 bytes is in case of ipv6 | |
62 | */ | |
a440846e | 63 | #define PREFIX_LEN_ROUTE_TYPE_5_IPV4 (18*8) |
64 | #define PREFIX_LEN_ROUTE_TYPE_5_IPV6 (30*8) | |
65 | ||
3714a385 | 66 | typedef struct esi_t_ { |
67 | uint8_t val[10]; | |
68 | } esi_t; | |
69 | ||
70 | struct evpn_ead_addr { | |
71 | esi_t esi; | |
72 | uint32_t eth_tag; | |
73 | }; | |
74 | ||
75 | struct evpn_macip_addr { | |
76 | uint32_t eth_tag; | |
d7c0a89a | 77 | uint8_t ip_prefix_length; |
d62a17ae | 78 | struct ethaddr mac; |
3714a385 | 79 | struct ipaddr ip; |
80 | }; | |
81 | ||
82 | struct evpn_imet_addr { | |
d62a17ae | 83 | uint32_t eth_tag; |
3714a385 | 84 | uint8_t ip_prefix_length; |
85 | struct ipaddr ip; | |
86 | }; | |
87 | ||
88 | struct evpn_es_addr { | |
89 | esi_t esi; | |
90 | uint8_t ip_prefix_length; | |
d62a17ae | 91 | struct ipaddr ip; |
a440846e | 92 | }; |
93 | ||
3714a385 | 94 | struct evpn_prefix_addr { |
95 | uint32_t eth_tag; | |
96 | uint8_t ip_prefix_length; | |
97 | struct ipaddr ip; | |
98 | }; | |
99 | ||
100 | /* EVPN address (RFC 7432) */ | |
101 | struct evpn_addr { | |
102 | uint8_t route_type; | |
103 | union { | |
104 | struct evpn_ead_addr _ead_addr; | |
105 | struct evpn_macip_addr _macip_addr; | |
106 | struct evpn_imet_addr _imet_addr; | |
107 | struct evpn_es_addr _es_addr; | |
108 | struct evpn_prefix_addr _prefix_addr; | |
109 | } u; | |
110 | #define ead_addr u._ead_addr | |
111 | #define macip_addr u._macip_addr | |
112 | #define imet_addr u._imet_addr | |
113 | #define es_addr u._es_addr | |
114 | #define prefix_addr u._prefix_addr | |
115 | }; | |
a440846e | 116 | |
9d24baaa | 117 | /* |
118 | * A struct prefix contains an address family, a prefix length, and an | |
119 | * address. This can represent either a 'network prefix' as defined | |
120 | * by CIDR, where the 'host bits' of the prefix are 0 | |
121 | * (e.g. AF_INET:10.0.0.0/8), or an address and netmask | |
122 | * (e.g. AF_INET:10.0.0.9/8), such as might be configured on an | |
123 | * interface. | |
124 | */ | |
125 | ||
32ac65d9 LB |
126 | /* different OSes use different names */ |
127 | #if defined(AF_PACKET) | |
128 | #define AF_ETHERNET AF_PACKET | |
129 | #else | |
130 | #if defined(AF_LINK) | |
131 | #define AF_ETHERNET AF_LINK | |
132 | #endif | |
133 | #endif | |
134 | ||
b03b8898 DS |
135 | /* The 'family' in the prefix structure is internal to FRR and need not |
136 | * map to standard OS AF_ definitions except where needed for interacting | |
137 | * with the kernel. However, AF_ definitions are currently in use and | |
138 | * prevalent across the code. Define a new FRR-specific AF for EVPN to | |
139 | * distinguish between 'ethernet' (MAC-only) and 'evpn' prefixes and | |
140 | * ensure it does not conflict with any OS AF_ definition. | |
141 | */ | |
142 | #if !defined(AF_EVPN) | |
143 | #define AF_EVPN (AF_MAX + 1) | |
144 | #endif | |
145 | ||
9a14899b PG |
146 | #if !defined(AF_FLOWSPEC) |
147 | #define AF_FLOWSPEC (AF_MAX + 2) | |
148 | #endif | |
149 | ||
150 | struct flowspec_prefix { | |
151 | uint16_t prefixlen; /* length in bytes */ | |
152 | uintptr_t ptr; | |
153 | }; | |
154 | ||
b03b8898 | 155 | /* FRR generic prefix structure. */ |
d62a17ae | 156 | struct prefix { |
d7c0a89a | 157 | uint8_t family; |
f93eee44 | 158 | uint16_t prefixlen; |
d62a17ae | 159 | union { |
d7c0a89a | 160 | uint8_t prefix; |
d62a17ae | 161 | struct in_addr prefix4; |
162 | struct in6_addr prefix6; | |
163 | struct { | |
164 | struct in_addr id; | |
165 | struct in_addr adv_router; | |
166 | } lp; | |
167 | struct ethaddr prefix_eth; /* AF_ETHERNET */ | |
d7c0a89a | 168 | uint8_t val[16]; |
6a923ca4 | 169 | uint32_t val32[4]; |
d62a17ae | 170 | uintptr_t ptr; |
b03b8898 | 171 | struct evpn_addr prefix_evpn; /* AF_EVPN */ |
9a14899b | 172 | struct flowspec_prefix prefix_flowspec; /* AF_FLOWSPEC */ |
d62a17ae | 173 | } u __attribute__((aligned(8))); |
718e3744 | 174 | }; |
175 | ||
176 | /* IPv4 prefix structure. */ | |
d62a17ae | 177 | struct prefix_ipv4 { |
d7c0a89a | 178 | uint8_t family; |
f93eee44 | 179 | uint16_t prefixlen; |
d62a17ae | 180 | struct in_addr prefix __attribute__((aligned(8))); |
718e3744 | 181 | }; |
182 | ||
183 | /* IPv6 prefix structure. */ | |
d62a17ae | 184 | struct prefix_ipv6 { |
d7c0a89a | 185 | uint8_t family; |
f93eee44 | 186 | uint16_t prefixlen; |
d62a17ae | 187 | struct in6_addr prefix __attribute__((aligned(8))); |
718e3744 | 188 | }; |
718e3744 | 189 | |
d62a17ae | 190 | struct prefix_ls { |
d7c0a89a | 191 | uint8_t family; |
f93eee44 | 192 | uint16_t prefixlen; |
d62a17ae | 193 | struct in_addr id __attribute__((aligned(8))); |
194 | struct in_addr adv_router; | |
718e3744 | 195 | }; |
196 | ||
197 | /* Prefix for routing distinguisher. */ | |
d62a17ae | 198 | struct prefix_rd { |
d7c0a89a | 199 | uint8_t family; |
f93eee44 | 200 | uint16_t prefixlen; |
d7c0a89a | 201 | uint8_t val[8] __attribute__((aligned(8))); |
718e3744 | 202 | }; |
203 | ||
32ac65d9 | 204 | /* Prefix for ethernet. */ |
d62a17ae | 205 | struct prefix_eth { |
d7c0a89a | 206 | uint8_t family; |
f93eee44 | 207 | uint16_t prefixlen; |
d62a17ae | 208 | struct ethaddr eth_addr __attribute__((aligned(8))); /* AF_ETHERNET */ |
32ac65d9 LB |
209 | }; |
210 | ||
86f1ef44 | 211 | /* EVPN prefix structure. */ |
d62a17ae | 212 | struct prefix_evpn { |
d7c0a89a | 213 | uint8_t family; |
f93eee44 | 214 | uint16_t prefixlen; |
d62a17ae | 215 | struct evpn_addr prefix __attribute__((aligned(8))); |
86f1ef44 | 216 | }; |
217 | ||
3714a385 | 218 | static inline int is_evpn_prefix_ipaddr_none(const struct prefix_evpn *evp) |
219 | { | |
220 | if (evp->prefix.route_type == 2) | |
221 | return IS_IPADDR_NONE(&(evp)->prefix.macip_addr.ip); | |
222 | if (evp->prefix.route_type == 3) | |
223 | return IS_IPADDR_NONE(&(evp)->prefix.imet_addr.ip); | |
50f74cf1 | 224 | if (evp->prefix.route_type == 4) |
225 | return IS_IPADDR_NONE(&(evp)->prefix.es_addr.ip); | |
3714a385 | 226 | if (evp->prefix.route_type == 5) |
227 | return IS_IPADDR_NONE(&(evp)->prefix.prefix_addr.ip); | |
228 | return 0; | |
229 | } | |
230 | ||
231 | static inline int is_evpn_prefix_ipaddr_v4(const struct prefix_evpn *evp) | |
232 | { | |
233 | if (evp->prefix.route_type == 2) | |
234 | return IS_IPADDR_V4(&(evp)->prefix.macip_addr.ip); | |
235 | if (evp->prefix.route_type == 3) | |
236 | return IS_IPADDR_V4(&(evp)->prefix.imet_addr.ip); | |
50f74cf1 | 237 | if (evp->prefix.route_type == 4) |
238 | return IS_IPADDR_V4(&(evp)->prefix.es_addr.ip); | |
3714a385 | 239 | if (evp->prefix.route_type == 5) |
240 | return IS_IPADDR_V4(&(evp)->prefix.prefix_addr.ip); | |
241 | return 0; | |
242 | } | |
243 | ||
244 | static inline int is_evpn_prefix_ipaddr_v6(const struct prefix_evpn *evp) | |
245 | { | |
246 | if (evp->prefix.route_type == 2) | |
247 | return IS_IPADDR_V6(&(evp)->prefix.macip_addr.ip); | |
248 | if (evp->prefix.route_type == 3) | |
249 | return IS_IPADDR_V6(&(evp)->prefix.imet_addr.ip); | |
50f74cf1 | 250 | if (evp->prefix.route_type == 4) |
251 | return IS_IPADDR_V6(&(evp)->prefix.es_addr.ip); | |
3714a385 | 252 | if (evp->prefix.route_type == 5) |
253 | return IS_IPADDR_V6(&(evp)->prefix.prefix_addr.ip); | |
254 | return 0; | |
255 | } | |
256 | ||
b4b359a2 | 257 | /* Prefix for a generic pointer */ |
d62a17ae | 258 | struct prefix_ptr { |
d7c0a89a | 259 | uint8_t family; |
f93eee44 | 260 | uint16_t prefixlen; |
d62a17ae | 261 | uintptr_t prefix __attribute__((aligned(8))); |
b4b359a2 PM |
262 | }; |
263 | ||
9a14899b PG |
264 | /* Prefix for a Flowspec entry */ |
265 | struct prefix_fs { | |
266 | uint8_t family; | |
f93eee44 | 267 | uint16_t prefixlen; /* unused */ |
9a14899b PG |
268 | struct flowspec_prefix prefix __attribute__((aligned(8))); |
269 | }; | |
270 | ||
d62a17ae | 271 | struct prefix_sg { |
d7c0a89a | 272 | uint8_t family; |
f93eee44 | 273 | uint16_t prefixlen; |
d62a17ae | 274 | struct in_addr src __attribute__((aligned(8))); |
275 | struct in_addr grp; | |
e9219290 DS |
276 | }; |
277 | ||
f7bf4153 DL |
278 | /* helper to get type safety/avoid casts on calls |
279 | * (w/o this, functions accepting all prefix types need casts on the caller | |
280 | * side, which strips type safety since the cast will accept any pointer | |
281 | * type.) | |
282 | */ | |
be566e4e DL |
283 | #ifndef __cplusplus |
284 | #define prefixtype(uname, typename, fieldname) \ | |
285 | typename *fieldname; | |
286 | #else | |
287 | #define prefixtype(uname, typename, fieldname) \ | |
288 | typename *fieldname; \ | |
289 | uname(typename *x) { this->fieldname = x; } | |
290 | #endif | |
291 | ||
d62a17ae | 292 | union prefixptr { |
be566e4e DL |
293 | prefixtype(prefixptr, struct prefix, p) |
294 | prefixtype(prefixptr, struct prefix_ipv4, p4) | |
295 | prefixtype(prefixptr, struct prefix_ipv6, p6) | |
296 | prefixtype(prefixptr, struct prefix_evpn, evp) | |
297 | prefixtype(prefixptr, struct prefix_fs, fs) | |
d62a17ae | 298 | } __attribute__((transparent_union)); |
299 | ||
300 | union prefixconstptr { | |
be566e4e DL |
301 | prefixtype(prefixconstptr, const struct prefix, p) |
302 | prefixtype(prefixconstptr, const struct prefix_ipv4, p4) | |
303 | prefixtype(prefixconstptr, const struct prefix_ipv6, p6) | |
304 | prefixtype(prefixconstptr, const struct prefix_evpn, evp) | |
305 | prefixtype(prefixconstptr, const struct prefix_fs, fs) | |
d62a17ae | 306 | } __attribute__((transparent_union)); |
f7bf4153 | 307 | |
718e3744 | 308 | #ifndef INET_ADDRSTRLEN |
309 | #define INET_ADDRSTRLEN 16 | |
310 | #endif /* INET_ADDRSTRLEN */ | |
311 | ||
312 | #ifndef INET6_ADDRSTRLEN | |
f93eee44 | 313 | /* dead:beef:dead:beef:dead:beef:dead:beef + \0 */ |
718e3744 | 314 | #define INET6_ADDRSTRLEN 46 |
315 | #endif /* INET6_ADDRSTRLEN */ | |
316 | ||
317 | #ifndef INET6_BUFSIZ | |
f93eee44 | 318 | #define INET6_BUFSIZ 53 |
718e3744 | 319 | #endif /* INET6_BUFSIZ */ |
320 | ||
61be6e94 QY |
321 | /* Maximum string length of the result of prefix2str */ |
322 | #define PREFIX_STRLEN 80 | |
855110bb | 323 | |
c6b6b53b AK |
324 | /* |
325 | * Longest possible length of a (S,G) string is 36 bytes | |
fef32740 | 326 | * 123.123.123.123 = 15 * 2 |
c6b6b53b AK |
327 | * (,) = 3 |
328 | * NULL Character at end = 1 | |
329 | * (123.123.123.123,123.123.123.123) | |
330 | */ | |
fef32740 | 331 | #define PREFIX_SG_STR_LEN 34 |
c6b6b53b | 332 | |
718e3744 | 333 | /* Max bit/byte length of IPv4 address. */ |
334 | #define IPV4_MAX_BYTELEN 4 | |
335 | #define IPV4_MAX_BITLEN 32 | |
336 | #define IPV4_MAX_PREFIXLEN 32 | |
337 | #define IPV4_ADDR_CMP(D,S) memcmp ((D), (S), IPV4_MAX_BYTELEN) | |
19aad877 JB |
338 | |
339 | static inline bool ipv4_addr_same(const struct in_addr *a, | |
340 | const struct in_addr *b) | |
341 | { | |
342 | return (a->s_addr == b->s_addr); | |
343 | } | |
344 | #define IPV4_ADDR_SAME(A,B) ipv4_addr_same((A), (B)) | |
345 | ||
346 | static inline void ipv4_addr_copy(struct in_addr *dst, | |
347 | const struct in_addr *src) | |
348 | { | |
349 | dst->s_addr = src->s_addr; | |
350 | } | |
351 | #define IPV4_ADDR_COPY(D,S) ipv4_addr_copy((D), (S)) | |
718e3744 | 352 | |
d7c0a89a QY |
353 | #define IPV4_NET0(a) ((((uint32_t)(a)) & 0xff000000) == 0x00000000) |
354 | #define IPV4_NET127(a) ((((uint32_t)(a)) & 0xff000000) == 0x7f000000) | |
355 | #define IPV4_LINKLOCAL(a) ((((uint32_t)(a)) & 0xffff0000) == 0xa9fe0000) | |
356 | #define IPV4_CLASS_DE(a) ((((uint32_t)(a)) & 0xe0000000) == 0xe0000000) | |
357 | #define IPV4_MC_LINKLOCAL(a) ((((uint32_t)(a)) & 0xffffff00) == 0xe0000000) | |
718e3744 | 358 | |
359 | /* Max bit/byte length of IPv6 address. */ | |
360 | #define IPV6_MAX_BYTELEN 16 | |
361 | #define IPV6_MAX_BITLEN 128 | |
362 | #define IPV6_MAX_PREFIXLEN 128 | |
363 | #define IPV6_ADDR_CMP(D,S) memcmp ((D), (S), IPV6_MAX_BYTELEN) | |
364 | #define IPV6_ADDR_SAME(D,S) (memcmp ((D), (S), IPV6_MAX_BYTELEN) == 0) | |
365 | #define IPV6_ADDR_COPY(D,S) memcpy ((D), (S), IPV6_MAX_BYTELEN) | |
366 | ||
367 | /* Count prefix size from mask length */ | |
368 | #define PSIZE(a) (((a) + 7) / (8)) | |
369 | ||
cd1964ff DS |
370 | #define BSIZE(a) ((a) * (8)) |
371 | ||
718e3744 | 372 | /* Prefix's family member. */ |
373 | #define PREFIX_FAMILY(p) ((p)->family) | |
374 | ||
5c6ed111 DL |
375 | /* glibc defines s6_addr32 to __in6_u.__u6_addr32 if __USE_{MISC || GNU} */ |
376 | #ifndef s6_addr32 | |
377 | #if defined(SUNOS_5) | |
378 | /* Some SunOS define s6_addr32 only to kernel */ | |
379 | #define s6_addr32 _S6_un._S6_u32 | |
380 | #else | |
381 | #define s6_addr32 __u6_addr.__u6_addr32 | |
382 | #endif /* SUNOS_5 */ | |
383 | #endif /*s6_addr32*/ | |
384 | ||
718e3744 | 385 | /* Prototypes. */ |
f3ccedaa | 386 | extern int str2family(const char *); |
d62a17ae | 387 | extern int afi2family(afi_t); |
388 | extern afi_t family2afi(int); | |
db2fde34 | 389 | extern const char *family2str(int family); |
1ec23d90 | 390 | extern const char *safi2str(safi_t safi); |
32ac65d9 | 391 | extern const char *afi2str(afi_t afi); |
8cc4198f | 392 | |
f63f06da | 393 | /* Check bit of the prefix. */ |
f93eee44 | 394 | extern unsigned int prefix_bit(const uint8_t *prefix, const uint16_t prefixlen); |
f63f06da | 395 | |
d62a17ae | 396 | extern struct prefix *prefix_new(void); |
63265b5c DS |
397 | extern void prefix_free(struct prefix **p); |
398 | /* | |
399 | * Function to handle prefix_free being used as a del function. | |
400 | */ | |
401 | extern void prefix_free_lists(void *arg); | |
d62a17ae | 402 | extern const char *prefix_family_str(const struct prefix *); |
403 | extern int prefix_blen(const struct prefix *); | |
404 | extern int str2prefix(const char *, struct prefix *); | |
4690c7d7 | 405 | |
a9ea959f | 406 | #define PREFIX2STR_BUFFER PREFIX_STRLEN |
407 | ||
c6b6b53b AK |
408 | extern void prefix_mcast_inet4_dump(const char *onfail, struct in_addr addr, |
409 | char *buf, int buf_size); | |
410 | extern const char *prefix_sg2str(const struct prefix_sg *sg, char *str); | |
d62a17ae | 411 | extern const char *prefix2str(union prefixconstptr, char *, int); |
44c69747 LK |
412 | extern int evpn_type5_prefix_match(const struct prefix *evpn_pfx, |
413 | const struct prefix *match_pfx); | |
d62a17ae | 414 | extern int prefix_match(const struct prefix *, const struct prefix *); |
415 | extern int prefix_match_network_statement(const struct prefix *, | |
416 | const struct prefix *); | |
9c3a2171 DL |
417 | extern int prefix_same(union prefixconstptr, union prefixconstptr); |
418 | extern int prefix_cmp(union prefixconstptr, union prefixconstptr); | |
d62a17ae | 419 | extern int prefix_common_bits(const struct prefix *, const struct prefix *); |
9c3a2171 | 420 | extern void prefix_copy(union prefixptr, union prefixconstptr); |
d62a17ae | 421 | extern void apply_mask(struct prefix *); |
422 | ||
4937287f DL |
423 | #ifdef __clang_analyzer__ |
424 | /* clang-SA doesn't understand transparent unions, making it think that the | |
425 | * target of prefix_copy is uninitialized. So just memset the target. | |
426 | * cf. https://bugs.llvm.org/show_bug.cgi?id=42811 | |
427 | */ | |
428 | #define prefix_copy(a, b) ({ memset(a, 0, sizeof(*a)); prefix_copy(a, b); }) | |
429 | #endif | |
430 | ||
d62a17ae | 431 | extern struct prefix *sockunion2hostprefix(const union sockunion *, |
432 | struct prefix *p); | |
433 | extern void prefix2sockunion(const struct prefix *, union sockunion *); | |
434 | ||
435 | extern int str2prefix_eth(const char *, struct prefix_eth *); | |
436 | ||
437 | extern struct prefix_ipv4 *prefix_ipv4_new(void); | |
63265b5c | 438 | extern void prefix_ipv4_free(struct prefix_ipv4 **p); |
d62a17ae | 439 | extern int str2prefix_ipv4(const char *, struct prefix_ipv4 *); |
440 | extern void apply_mask_ipv4(struct prefix_ipv4 *); | |
441 | ||
996c9314 | 442 | #define PREFIX_COPY(DST, SRC) \ |
72a1b201 | 443 | *((struct prefix *)(DST)) = *((const struct prefix *)(SRC)) |
996c9314 | 444 | #define PREFIX_COPY_IPV4(DST, SRC) \ |
e4529636 AS |
445 | *((struct prefix_ipv4 *)(DST)) = *((const struct prefix_ipv4 *)(SRC)); |
446 | ||
d62a17ae | 447 | extern int prefix_ipv4_any(const struct prefix_ipv4 *); |
448 | extern void apply_classful_mask_ipv4(struct prefix_ipv4 *); | |
8cc4198f | 449 | |
d7c0a89a | 450 | extern uint8_t ip_masklen(struct in_addr); |
d62a17ae | 451 | extern void masklen2ip(const int, struct in_addr *); |
3fb9cd6e | 452 | /* given the address of a host on a network and the network mask length, |
453 | * calculate the broadcast address for that network; | |
2d48474e | 454 | * special treatment for /31 according to RFC3021 section 3.3 */ |
d62a17ae | 455 | extern in_addr_t ipv4_broadcast_addr(in_addr_t hostaddr, int masklen); |
3fb9cd6e | 456 | |
d62a17ae | 457 | extern int netmask_str2prefix_str(const char *, const char *, char *); |
718e3744 | 458 | |
d62a17ae | 459 | extern struct prefix_ipv6 *prefix_ipv6_new(void); |
63265b5c | 460 | extern void prefix_ipv6_free(struct prefix_ipv6 **p); |
d62a17ae | 461 | extern int str2prefix_ipv6(const char *, struct prefix_ipv6 *); |
462 | extern void apply_mask_ipv6(struct prefix_ipv6 *); | |
718e3744 | 463 | |
d62a17ae | 464 | #define PREFIX_COPY_IPV6(DST, SRC) \ |
e4529636 AS |
465 | *((struct prefix_ipv6 *)(DST)) = *((const struct prefix_ipv6 *)(SRC)); |
466 | ||
d62a17ae | 467 | extern int ip6_masklen(struct in6_addr); |
468 | extern void masklen2ip6(const int, struct in6_addr *); | |
b04c699e | 469 | |
d62a17ae | 470 | extern const char *inet6_ntoa(struct in6_addr); |
5920990f | 471 | |
a9e08ebc | 472 | extern int is_zero_mac(const struct ethaddr *mac); |
c6ec0c74 KA |
473 | extern bool is_mcast_mac(const struct ethaddr *mac); |
474 | extern bool is_bcast_mac(const struct ethaddr *mac); | |
db42a173 PG |
475 | extern int prefix_str2mac(const char *str, struct ethaddr *mac); |
476 | extern char *prefix_mac2str(const struct ethaddr *mac, char *buf, int size); | |
c215ecaf | 477 | |
62b4b3b6 | 478 | extern unsigned prefix_hash_key(const void *pp); |
7a7761d2 | 479 | |
50f74cf1 | 480 | extern int str_to_esi(const char *str, esi_t *esi); |
481 | extern char *esi_to_str(const esi_t *esi, char *buf, int size); | |
50f74cf1 | 482 | extern void prefix_evpn_hexdump(const struct prefix_evpn *p); |
483 | ||
d62a17ae | 484 | static inline int ipv6_martian(struct in6_addr *addr) |
d914d5ff | 485 | { |
d62a17ae | 486 | struct in6_addr localhost_addr; |
d914d5ff | 487 | |
d62a17ae | 488 | inet_pton(AF_INET6, "::1", &localhost_addr); |
d914d5ff | 489 | |
d62a17ae | 490 | if (IPV6_ADDR_SAME(&localhost_addr, addr)) |
491 | return 1; | |
d914d5ff | 492 | |
d62a17ae | 493 | return 0; |
d914d5ff DS |
494 | } |
495 | ||
d37ba549 | 496 | extern int macstr2prefix_evpn(const char *str, struct prefix_evpn *p); |
718e3744 | 497 | |
d914d5ff | 498 | /* NOTE: This routine expects the address argument in network byte order. */ |
d62a17ae | 499 | static inline int ipv4_martian(struct in_addr *addr) |
6ee06fa9 | 500 | { |
d62a17ae | 501 | in_addr_t ip = ntohl(addr->s_addr); |
6ee06fa9 | 502 | |
d62a17ae | 503 | if (IPV4_NET0(ip) || IPV4_NET127(ip) || IPV4_CLASS_DE(ip)) { |
504 | return 1; | |
505 | } | |
506 | return 0; | |
6ee06fa9 PM |
507 | } |
508 | ||
f229873a | 509 | static inline int is_default_prefix(const struct prefix *p) |
18ff3edd | 510 | { |
d62a17ae | 511 | if (!p) |
512 | return 0; | |
18ff3edd | 513 | |
996c9314 LB |
514 | if ((p->family == AF_INET) && (p->u.prefix4.s_addr == INADDR_ANY) |
515 | && (p->prefixlen == 0)) | |
f229873a DS |
516 | return 1; |
517 | ||
996c9314 LB |
518 | if ((p->family == AF_INET6) && (p->prefixlen == 0) |
519 | && (!memcmp(&p->u.prefix6, &in6addr_any, sizeof(struct in6_addr)))) | |
d62a17ae | 520 | return 1; |
18ff3edd | 521 | |
d62a17ae | 522 | return 0; |
18ff3edd DS |
523 | } |
524 | ||
408b00c4 MK |
525 | static inline int is_host_route(struct prefix *p) |
526 | { | |
527 | if (p->family == AF_INET) | |
528 | return (p->prefixlen == IPV4_MAX_BITLEN); | |
529 | else if (p->family == AF_INET6) | |
530 | return (p->prefixlen == IPV6_MAX_BITLEN); | |
531 | return 0; | |
532 | } | |
5e244469 | 533 | |
35518f54 | 534 | static inline int is_default_host_route(const struct prefix *p) |
1eb6c3ea CS |
535 | { |
536 | if (p->family == AF_INET) { | |
537 | return (p->u.prefix4.s_addr == INADDR_ANY && | |
538 | p->prefixlen == IPV4_MAX_BITLEN); | |
539 | } else if (p->family == AF_INET6) { | |
540 | return ((!memcmp(&p->u.prefix6, &in6addr_any, | |
541 | sizeof(struct in6_addr))) && | |
542 | p->prefixlen == IPV6_MAX_BITLEN); | |
543 | } | |
544 | return 0; | |
545 | } | |
546 | ||
07ef3e34 DL |
547 | #ifdef _FRR_ATTRIBUTE_PRINTFRR |
548 | #pragma FRR printfrr_ext "%pI4" (struct in_addr *) | |
549 | #pragma FRR printfrr_ext "%pI4" (in_addr_t *) | |
550 | ||
551 | #pragma FRR printfrr_ext "%pI6" (struct in6_addr *) | |
552 | ||
553 | #pragma FRR printfrr_ext "%pFX" (struct prefix *) | |
554 | #pragma FRR printfrr_ext "%pFX" (struct prefix_ipv4 *) | |
555 | #pragma FRR printfrr_ext "%pFX" (struct prefix_ipv6 *) | |
556 | #pragma FRR printfrr_ext "%pFX" (struct prefix_eth *) | |
557 | #pragma FRR printfrr_ext "%pFX" (struct prefix_evpn *) | |
558 | #pragma FRR printfrr_ext "%pFX" (struct prefix_fs *) | |
559 | ||
560 | #pragma FRR printfrr_ext "%pSG4" (struct prefix_sg *) | |
561 | #endif | |
562 | ||
5e244469 RW |
563 | #ifdef __cplusplus |
564 | } | |
565 | #endif | |
566 | ||
718e3744 | 567 | #endif /* _ZEBRA_PREFIX_H */ |