2 * BIRD Internet Routing Daemon -- Network addresses
4 * (c) 2015 Ondrej Zajicek <santiago@crfreenet.org>
5 * (c) 2015 CZ.NIC z.s.p.o.
7 * Can be freely distributed and used under the terms of the GNU GPL.
24 #define NET_IP6_SADR 9
28 #define NB_IP4 (1 << NET_IP4)
29 #define NB_IP6 (1 << NET_IP6)
30 #define NB_VPN4 (1 << NET_VPN4)
31 #define NB_VPN6 (1 << NET_VPN6)
32 #define NB_ROA4 (1 << NET_ROA4)
33 #define NB_ROA6 (1 << NET_ROA6)
34 #define NB_FLOW4 (1 << NET_FLOW4)
35 #define NB_FLOW6 (1 << NET_FLOW6)
36 #define NB_IP6_SADR (1 << NET_IP6_SADR)
37 #define NB_MPLS (1 << NET_MPLS)
39 #define NB_IP (NB_IP4 | NB_IP6)
40 #define NB_VPN (NB_VPN4 | NB_VPN6)
41 #define NB_FLOW (NB_FLOW4 | NB_FLOW6)
42 #define NB_DEST (NB_IP | NB_IP6_SADR | NB_VPN | NB_MPLS)
43 #define NB_ANY 0xffffffff
46 typedef struct net_addr
{
54 typedef struct net_addr_ip4
{
61 typedef struct net_addr_ip6
{
68 typedef struct net_addr_vpn4
{
76 typedef struct net_addr_vpn6
{
85 typedef struct net_addr_roa4
{
94 typedef struct net_addr_roa6
{
103 typedef struct net_addr_flow4
{
111 typedef struct net_addr_flow6
{
119 typedef struct net_addr_mpls
{
126 typedef struct net_addr_ip6_sadr
{
131 s32 src_pxlen
; /* s32 to avoid padding */
135 typedef union net_addr_union
{
143 net_addr_flow4 flow4
;
144 net_addr_flow6 flow6
;
145 net_addr_ip6_sadr ip6_sadr
;
150 extern const char * const net_label
[];
151 extern const u16 net_addr_length
[];
152 extern const u8 net_max_prefix_length
[];
153 extern const u16 net_max_text_length
[];
155 #define NET_MAX_TEXT_LENGTH 256
158 #define NET_ADDR_IP4(prefix,pxlen) \
159 ((net_addr_ip4) { NET_IP4, pxlen, sizeof(net_addr_ip4), prefix })
161 #define NET_ADDR_IP6(prefix,pxlen) \
162 ((net_addr_ip6) { NET_IP6, pxlen, sizeof(net_addr_ip6), prefix })
164 #define NET_ADDR_VPN4(prefix,pxlen,rd) \
165 ((net_addr_vpn4) { NET_VPN4, pxlen, sizeof(net_addr_vpn4), prefix, rd })
167 #define NET_ADDR_VPN6(prefix,pxlen,rd) \
168 ((net_addr_vpn6) { NET_VPN6, pxlen, sizeof(net_addr_vpn6), prefix, 0, rd })
170 #define NET_ADDR_ROA4(prefix,pxlen,max_pxlen,asn) \
171 ((net_addr_roa4) { NET_ROA4, pxlen, sizeof(net_addr_roa4), prefix, max_pxlen, asn })
173 #define NET_ADDR_ROA6(prefix,pxlen,max_pxlen,asn) \
174 ((net_addr_roa6) { NET_ROA6, pxlen, sizeof(net_addr_roa6), prefix, max_pxlen, asn })
176 #define NET_ADDR_FLOW4(prefix,pxlen,dlen) \
177 ((net_addr_flow4) { NET_FLOW4, pxlen, sizeof(net_addr_ip4) + dlen, prefix })
179 #define NET_ADDR_FLOW6(prefix,pxlen,dlen) \
180 ((net_addr_flow6) { NET_FLOW6, pxlen, sizeof(net_addr_ip6) + dlen, prefix })
182 #define NET_ADDR_IP6_SADR(dst_prefix,dst_pxlen,src_prefix,src_pxlen) \
183 ((net_addr_ip6_sadr) { NET_IP6_SADR, dst_pxlen, sizeof(net_addr_ip6_sadr), dst_prefix, src_pxlen, src_prefix })
185 #define NET_ADDR_MPLS(label) \
186 ((net_addr_mpls) { NET_MPLS, 20, sizeof(net_addr_mpls), label })
189 static inline void net_fill_ip4(net_addr
*a
, ip4_addr prefix
, uint pxlen
)
190 { *(net_addr_ip4
*)a
= NET_ADDR_IP4(prefix
, pxlen
); }
192 static inline void net_fill_ip6(net_addr
*a
, ip6_addr prefix
, uint pxlen
)
193 { *(net_addr_ip6
*)a
= NET_ADDR_IP6(prefix
, pxlen
); }
195 static inline void net_fill_vpn4(net_addr
*a
, ip4_addr prefix
, uint pxlen
, u64 rd
)
196 { *(net_addr_vpn4
*)a
= NET_ADDR_VPN4(prefix
, pxlen
, rd
); }
198 static inline void net_fill_vpn6(net_addr
*a
, ip6_addr prefix
, uint pxlen
, u64 rd
)
199 { *(net_addr_vpn6
*)a
= NET_ADDR_VPN6(prefix
, pxlen
, rd
); }
201 static inline void net_fill_roa4(net_addr
*a
, ip4_addr prefix
, uint pxlen
, uint max_pxlen
, u32 asn
)
202 { *(net_addr_roa4
*)a
= NET_ADDR_ROA4(prefix
, pxlen
, max_pxlen
, asn
); }
204 static inline void net_fill_roa6(net_addr
*a
, ip6_addr prefix
, uint pxlen
, uint max_pxlen
, u32 asn
)
205 { *(net_addr_roa6
*)a
= NET_ADDR_ROA6(prefix
, pxlen
, max_pxlen
, asn
); }
207 static inline void net_fill_ip6_sadr(net_addr
*a
, ip6_addr dst_prefix
, uint dst_pxlen
, ip6_addr src_prefix
, uint src_pxlen
)
208 { *(net_addr_ip6_sadr
*)a
= NET_ADDR_IP6_SADR(dst_prefix
, dst_pxlen
, src_prefix
, src_pxlen
); }
210 static inline void net_fill_mpls(net_addr
*a
, u32 label
)
211 { *(net_addr_mpls
*)a
= NET_ADDR_MPLS(label
); }
213 static inline void net_fill_ipa(net_addr
*a
, ip_addr prefix
, uint pxlen
)
215 if (ipa_is_ip4(prefix
))
216 net_fill_ip4(a
, ipa_to_ip4(prefix
), pxlen
);
218 net_fill_ip6(a
, ipa_to_ip6(prefix
), pxlen
);
221 static inline void net_fill_ip_host(net_addr
*a
, ip_addr prefix
)
223 if (ipa_is_ip4(prefix
))
224 net_fill_ip4(a
, ipa_to_ip4(prefix
), IP4_MAX_PREFIX_LENGTH
);
226 net_fill_ip6(a
, ipa_to_ip6(prefix
), IP6_MAX_PREFIX_LENGTH
);
229 static inline void net_fill_flow4(net_addr
*a
, ip4_addr prefix
, uint pxlen
, byte
*data
, uint dlen
)
231 net_addr_flow4
*f
= (void *) a
;
232 *f
= NET_ADDR_FLOW4(prefix
, pxlen
, dlen
);
233 memcpy(f
->data
, data
, dlen
);
236 static inline void net_fill_flow6(net_addr
*a
, ip6_addr prefix
, uint pxlen
, byte
*data
, uint dlen
)
238 net_addr_flow6
*f
= (void *) a
;
239 *f
= NET_ADDR_FLOW6(prefix
, pxlen
, dlen
);
240 memcpy(f
->data
, data
, dlen
);
243 /* Make NET_IP6_SADR from NET_IP6, assuming there is enough space */
244 static inline void net_make_ip6_sadr(net_addr
*a
)
246 net_addr_ip6_sadr
*n
= (void *) a
;
247 n
->type
= NET_IP6_SADR
;
248 n
->length
= sizeof(net_addr_ip6_sadr
);
250 n
->src_prefix
= IP6_NONE
;
253 static inline int net_val_match(u8 type
, u32 mask
)
254 { return !!((1 << type
) & mask
); }
256 static inline int net_type_match(const net_addr
*a
, u32 mask
)
257 { return net_val_match(a
->type
, mask
); }
259 static inline int net_is_ip(const net_addr
*a
)
260 { return (a
->type
== NET_IP4
) || (a
->type
== NET_IP6
); }
262 static inline int net_is_vpn(const net_addr
*a
)
263 { return (a
->type
== NET_VPN4
) || (a
->type
== NET_VPN6
); }
265 static inline int net_is_roa(const net_addr
*a
)
266 { return (a
->type
== NET_ROA4
) || (a
->type
== NET_ROA6
); }
268 static inline int net_is_flow(const net_addr
*a
)
269 { return (a
->type
== NET_FLOW4
) || (a
->type
== NET_FLOW6
); }
271 static inline int net_is_sadr(const net_addr
*a
)
272 { return (a
->type
== NET_IP6_SADR
); }
274 static inline ip4_addr
net4_prefix(const net_addr
*a
)
275 { return ((net_addr_ip4
*) a
)->prefix
; }
277 static inline ip6_addr
net6_prefix(const net_addr
*a
)
278 { return ((net_addr_ip6
*) a
)->prefix
; }
280 static inline ip_addr
net_prefix(const net_addr
*a
)
288 return ipa_from_ip4(net4_prefix(a
));
295 return ipa_from_ip6(net6_prefix(a
));
303 static inline u32
net_mpls(const net_addr
*a
)
305 if (a
->type
== NET_MPLS
)
306 return ((net_addr_mpls
*) a
)->label
;
308 bug("Can't call net_mpls on non-mpls net_addr");
311 static inline uint
net4_pxlen(const net_addr
*a
)
314 static inline uint
net6_pxlen(const net_addr
*a
)
317 static inline uint
net_pxlen(const net_addr
*a
)
320 ip_addr
net_pxmask(const net_addr
*a
);
322 static inline u64
net_rd(const net_addr
*a
)
327 return ((net_addr_vpn4
*)a
)->rd
;
329 return ((net_addr_vpn6
*)a
)->rd
;
335 static inline int net_equal(const net_addr
*a
, const net_addr
*b
)
336 { return (a
->length
== b
->length
) && !memcmp(a
, b
, a
->length
); }
338 static inline int net_equal_ip4(const net_addr_ip4
*a
, const net_addr_ip4
*b
)
339 { return !memcmp(a
, b
, sizeof(net_addr_ip4
)); }
341 static inline int net_equal_ip6(const net_addr_ip6
*a
, const net_addr_ip6
*b
)
342 { return !memcmp(a
, b
, sizeof(net_addr_ip6
)); }
344 static inline int net_equal_vpn4(const net_addr_vpn4
*a
, const net_addr_vpn4
*b
)
345 { return !memcmp(a
, b
, sizeof(net_addr_vpn4
)); }
347 static inline int net_equal_vpn6(const net_addr_vpn6
*a
, const net_addr_vpn6
*b
)
348 { return !memcmp(a
, b
, sizeof(net_addr_vpn6
)); }
350 static inline int net_equal_roa4(const net_addr_roa4
*a
, const net_addr_roa4
*b
)
351 { return !memcmp(a
, b
, sizeof(net_addr_roa4
)); }
353 static inline int net_equal_roa6(const net_addr_roa6
*a
, const net_addr_roa6
*b
)
354 { return !memcmp(a
, b
, sizeof(net_addr_roa6
)); }
356 static inline int net_equal_flow4(const net_addr_flow4
*a
, const net_addr_flow4
*b
)
357 { return net_equal((const net_addr
*) a
, (const net_addr
*) b
); }
359 static inline int net_equal_flow6(const net_addr_flow6
*a
, const net_addr_flow6
*b
)
360 { return net_equal((const net_addr
*) a
, (const net_addr
*) b
); }
362 static inline int net_equal_ip6_sadr(const net_addr_ip6_sadr
*a
, const net_addr_ip6_sadr
*b
)
363 { return !memcmp(a
, b
, sizeof(net_addr_ip6_sadr
)); }
365 static inline int net_equal_mpls(const net_addr_mpls
*a
, const net_addr_mpls
*b
)
366 { return !memcmp(a
, b
, sizeof(net_addr_mpls
)); }
369 static inline int net_equal_prefix_roa4(const net_addr_roa4
*a
, const net_addr_roa4
*b
)
370 { return ip4_equal(a
->prefix
, b
->prefix
) && (a
->pxlen
== b
->pxlen
); }
372 static inline int net_equal_prefix_roa6(const net_addr_roa6
*a
, const net_addr_roa6
*b
)
373 { return ip6_equal(a
->prefix
, b
->prefix
) && (a
->pxlen
== b
->pxlen
); }
375 static inline int net_equal_dst_ip6_sadr(const net_addr_ip6_sadr
*a
, const net_addr_ip6_sadr
*b
)
376 { return ip6_equal(a
->dst_prefix
, b
->dst_prefix
) && (a
->dst_pxlen
== b
->dst_pxlen
); }
378 static inline int net_equal_src_ip6_sadr(const net_addr_ip6_sadr
*a
, const net_addr_ip6_sadr
*b
)
379 { return ip6_equal(a
->src_prefix
, b
->src_prefix
) && (a
->src_pxlen
== b
->src_pxlen
); }
382 static inline int net_zero_ip4(const net_addr_ip4
*a
)
383 { return !a
->pxlen
&& ip4_zero(a
->prefix
); }
385 static inline int net_zero_ip6(const net_addr_ip6
*a
)
386 { return !a
->pxlen
&& ip6_zero(a
->prefix
); }
388 static inline int net_zero_vpn4(const net_addr_vpn4
*a
)
389 { return !a
->pxlen
&& ip4_zero(a
->prefix
) && !a
->rd
; }
391 static inline int net_zero_vpn6(const net_addr_vpn6
*a
)
392 { return !a
->pxlen
&& ip6_zero(a
->prefix
) && !a
->rd
; }
394 static inline int net_zero_roa4(const net_addr_roa4
*a
)
395 { return !a
->pxlen
&& ip4_zero(a
->prefix
) && !a
->max_pxlen
&& !a
->asn
; }
397 static inline int net_zero_roa6(const net_addr_roa6
*a
)
398 { return !a
->pxlen
&& ip6_zero(a
->prefix
) && !a
->max_pxlen
&& !a
->asn
; }
400 static inline int net_zero_flow4(const net_addr_flow4
*a
)
401 { return !a
->pxlen
&& ip4_zero(a
->prefix
) && (a
->length
== sizeof(net_addr_flow4
)); }
403 static inline int net_zero_flow6(const net_addr_flow6
*a
)
404 { return !a
->pxlen
&& ip6_zero(a
->prefix
) && (a
->length
== sizeof(net_addr_flow6
)); }
406 static inline int net_zero_mpls(const net_addr_mpls
*a
)
407 { return !a
->label
; }
410 static inline int net_compare_ip4(const net_addr_ip4
*a
, const net_addr_ip4
*b
)
411 { return ip4_compare(a
->prefix
, b
->prefix
) ?: uint_cmp(a
->pxlen
, b
->pxlen
); }
413 static inline int net_compare_ip6(const net_addr_ip6
*a
, const net_addr_ip6
*b
)
414 { return ip6_compare(a
->prefix
, b
->prefix
) ?: uint_cmp(a
->pxlen
, b
->pxlen
); }
416 static inline int net_compare_vpn4(const net_addr_vpn4
*a
, const net_addr_vpn4
*b
)
417 { return u64_cmp(a
->rd
, b
->rd
) ?: ip4_compare(a
->prefix
, b
->prefix
) ?: uint_cmp(a
->pxlen
, b
->pxlen
); }
419 static inline int net_compare_vpn6(const net_addr_vpn6
*a
, const net_addr_vpn6
*b
)
420 { return u64_cmp(a
->rd
, b
->rd
) ?: ip6_compare(a
->prefix
, b
->prefix
) ?: uint_cmp(a
->pxlen
, b
->pxlen
); }
422 static inline int net_compare_roa4(const net_addr_roa4
*a
, const net_addr_roa4
*b
)
423 { return ip4_compare(a
->prefix
, b
->prefix
) ?: uint_cmp(a
->pxlen
, b
->pxlen
) ?: uint_cmp(a
->max_pxlen
, b
->max_pxlen
) ?: uint_cmp(a
->asn
, b
->asn
); }
425 static inline int net_compare_roa6(const net_addr_roa6
*a
, const net_addr_roa6
*b
)
426 { return ip6_compare(a
->prefix
, b
->prefix
) ?: uint_cmp(a
->pxlen
, b
->pxlen
) ?: uint_cmp(a
->max_pxlen
, b
->max_pxlen
) ?: uint_cmp(a
->asn
, b
->asn
); }
428 static inline int net_compare_flow4(const net_addr_flow4
*a
, const net_addr_flow4
*b
)
429 { return ip4_compare(a
->prefix
, b
->prefix
) ?: uint_cmp(a
->pxlen
, b
->pxlen
) ?: uint_cmp(a
->length
, b
->length
) ?: memcmp(a
->data
, b
->data
, a
->length
- sizeof(net_addr_flow4
)); }
431 static inline int net_compare_flow6(const net_addr_flow6
*a
, const net_addr_flow6
*b
)
432 { return ip6_compare(a
->prefix
, b
->prefix
) ?: uint_cmp(a
->pxlen
, b
->pxlen
) ?: uint_cmp(a
->length
, b
->length
) ?: memcmp(a
->data
, b
->data
, a
->length
- sizeof(net_addr_flow6
)); }
434 static inline int net_compare_ip6_sadr(const net_addr_ip6_sadr
*a
, const net_addr_ip6_sadr
*b
)
437 ip6_compare(a
->dst_prefix
, b
->dst_prefix
) ?: uint_cmp(a
->dst_pxlen
, b
->dst_pxlen
) ?:
438 ip6_compare(a
->src_prefix
, b
->src_prefix
) ?: uint_cmp(a
->src_pxlen
, b
->src_pxlen
);
441 static inline int net_compare_mpls(const net_addr_mpls
*a
, const net_addr_mpls
*b
)
442 { return uint_cmp(a
->label
, b
->label
); }
444 int net_compare(const net_addr
*a
, const net_addr
*b
);
447 static inline void net_copy(net_addr
*dst
, const net_addr
*src
)
448 { memcpy(dst
, src
, src
->length
); }
450 static inline void net_copy_ip4(net_addr_ip4
*dst
, const net_addr_ip4
*src
)
451 { memcpy(dst
, src
, sizeof(net_addr_ip4
)); }
453 static inline void net_copy_ip6(net_addr_ip6
*dst
, const net_addr_ip6
*src
)
454 { memcpy(dst
, src
, sizeof(net_addr_ip6
)); }
456 static inline void net_copy_vpn4(net_addr_vpn4
*dst
, const net_addr_vpn4
*src
)
457 { memcpy(dst
, src
, sizeof(net_addr_vpn4
)); }
459 static inline void net_copy_vpn6(net_addr_vpn6
*dst
, const net_addr_vpn6
*src
)
460 { memcpy(dst
, src
, sizeof(net_addr_vpn6
)); }
462 static inline void net_copy_roa4(net_addr_roa4
*dst
, const net_addr_roa4
*src
)
463 { memcpy(dst
, src
, sizeof(net_addr_roa4
)); }
465 static inline void net_copy_roa6(net_addr_roa6
*dst
, const net_addr_roa6
*src
)
466 { memcpy(dst
, src
, sizeof(net_addr_roa6
)); }
468 static inline void net_copy_flow4(net_addr_flow4
*dst
, const net_addr_flow4
*src
)
469 { memcpy(dst
, src
, src
->length
); }
471 static inline void net_copy_flow6(net_addr_flow6
*dst
, const net_addr_flow6
*src
)
472 { memcpy(dst
, src
, src
->length
); }
474 static inline void net_copy_ip6_sadr(net_addr_ip6_sadr
*dst
, const net_addr_ip6_sadr
*src
)
475 { memcpy(dst
, src
, sizeof(net_addr_ip6_sadr
)); }
477 static inline void net_copy_mpls(net_addr_mpls
*dst
, const net_addr_mpls
*src
)
478 { memcpy(dst
, src
, sizeof(net_addr_mpls
)); }
482 static inline u32
u64_hash(u64 a
)
483 { return u32_hash(a
); }
485 static inline u32
net_hash_ip4(const net_addr_ip4
*n
)
486 { return ip4_hash(n
->prefix
) ^ ((u32
) n
->pxlen
<< 26); }
488 static inline u32
net_hash_ip6(const net_addr_ip6
*n
)
489 { return ip6_hash(n
->prefix
) ^ ((u32
) n
->pxlen
<< 26); }
491 static inline u32
net_hash_vpn4(const net_addr_vpn4
*n
)
492 { return ip4_hash(n
->prefix
) ^ ((u32
) n
->pxlen
<< 26) ^ u64_hash(n
->rd
); }
494 static inline u32
net_hash_vpn6(const net_addr_vpn6
*n
)
495 { return ip6_hash(n
->prefix
) ^ ((u32
) n
->pxlen
<< 26) ^ u64_hash(n
->rd
); }
497 static inline u32
net_hash_roa4(const net_addr_roa4
*n
)
498 { return ip4_hash(n
->prefix
) ^ ((u32
) n
->pxlen
<< 26); }
500 static inline u32
net_hash_roa6(const net_addr_roa6
*n
)
501 { return ip6_hash(n
->prefix
) ^ ((u32
) n
->pxlen
<< 26); }
503 static inline u32
net_hash_flow4(const net_addr_flow4
*n
)
504 { return ip4_hash(n
->prefix
) ^ ((u32
) n
->pxlen
<< 26); }
506 static inline u32
net_hash_flow6(const net_addr_flow6
*n
)
507 { return ip6_hash(n
->prefix
) ^ ((u32
) n
->pxlen
<< 26); }
509 static inline u32
net_hash_ip6_sadr(const net_addr_ip6_sadr
*n
)
510 { return net_hash_ip6((net_addr_ip6
*) n
); }
512 static inline u32
net_hash_mpls(const net_addr_mpls
*n
)
515 u32
net_hash(const net_addr
*a
);
518 static inline int net_validate_px4(const ip4_addr prefix
, uint pxlen
)
520 return (pxlen
<= IP4_MAX_PREFIX_LENGTH
) &&
521 ip4_zero(ip4_and(prefix
, ip4_not(ip4_mkmask(pxlen
))));
524 static inline int net_validate_px6(const ip6_addr prefix
, uint pxlen
)
526 return (pxlen
<= IP6_MAX_PREFIX_LENGTH
) &&
527 ip6_zero(ip6_and(prefix
, ip6_not(ip6_mkmask(pxlen
))));
530 static inline int net_validate_ip4(const net_addr_ip4
*n
)
531 { return net_validate_px4(n
->prefix
, n
->pxlen
); }
533 static inline int net_validate_ip6(const net_addr_ip6
*n
)
534 { return net_validate_px6(n
->prefix
, n
->pxlen
); }
536 static inline int net_validate_vpn4(const net_addr_vpn4
*n
)
537 { return net_validate_px4(n
->prefix
, n
->pxlen
); }
539 static inline int net_validate_vpn6(const net_addr_vpn6
*n
)
540 { return net_validate_px6(n
->prefix
, n
->pxlen
); }
542 static inline int net_validate_roa4(const net_addr_roa4
*n
)
544 return net_validate_px4(n
->prefix
, n
->pxlen
) &&
545 (n
->pxlen
<= n
->max_pxlen
) && (n
->max_pxlen
<= IP4_MAX_PREFIX_LENGTH
);
548 static inline int net_validate_roa6(const net_addr_roa6
*n
)
550 return net_validate_px6(n
->prefix
, n
->pxlen
) &&
551 (n
->pxlen
<= n
->max_pxlen
) && (n
->max_pxlen
<= IP6_MAX_PREFIX_LENGTH
);
554 // FIXME: Better check, call flow_validate?
555 static inline int net_validate_flow4(const net_addr_flow4
*n
)
556 { return net_validate_px4(n
->prefix
, n
->pxlen
); }
558 static inline int net_validate_flow6(const net_addr_flow6
*n
)
559 { return net_validate_px6(n
->prefix
, n
->pxlen
); }
561 static inline int net_validate_mpls(const net_addr_mpls
*n
)
562 { return n
->label
< (1 << 20); }
564 static inline int net_validate_ip6_sadr(const net_addr_ip6_sadr
*n
)
565 { return net_validate_px6(n
->dst_prefix
, n
->dst_pxlen
) && net_validate_px6(n
->src_prefix
, n
->src_pxlen
); }
567 int net_validate(const net_addr
*N
);
570 static inline void net_normalize_ip4(net_addr_ip4
*n
)
571 { n
->prefix
= ip4_and(n
->prefix
, ip4_mkmask(n
->pxlen
)); }
573 static inline void net_normalize_ip6(net_addr_ip6
*n
)
574 { n
->prefix
= ip6_and(n
->prefix
, ip6_mkmask(n
->pxlen
)); }
576 static inline void net_normalize_vpn4(net_addr_vpn4
*n
)
577 { net_normalize_ip4((net_addr_ip4
*) n
); }
579 static inline void net_normalize_vpn6(net_addr_vpn6
*n
)
580 { net_normalize_ip6((net_addr_ip6
*) n
); }
582 static inline void net_normalize_ip6_sadr(net_addr_ip6_sadr
*n
)
584 n
->dst_prefix
= ip6_and(n
->dst_prefix
, ip6_mkmask(n
->dst_pxlen
));
585 n
->src_prefix
= ip6_and(n
->src_prefix
, ip6_mkmask(n
->src_pxlen
));
588 void net_normalize(net_addr
*N
);
591 int net_classify(const net_addr
*N
);
592 int net_format(const net_addr
*N
, char *buf
, int buflen
);
593 int rd_format(const u64 rd
, char *buf
, int buflen
);
595 static inline int ipa_in_px4(ip4_addr a
, ip4_addr prefix
, uint pxlen
)
596 { return ip4_zero(ip4_and(ip4_xor(a
, prefix
), ip4_mkmask(pxlen
))); }
598 static inline int ipa_in_px6(ip6_addr a
, ip6_addr prefix
, uint pxlen
)
599 { return ip6_zero(ip6_and(ip6_xor(a
, prefix
), ip6_mkmask(pxlen
))); }
601 static inline int ipa_in_net_ip4(ip4_addr a
, const net_addr_ip4
*n
)
602 { return ipa_in_px4(a
, n
->prefix
, n
->pxlen
); }
604 static inline int ipa_in_net_ip6(ip6_addr a
, const net_addr_ip6
*n
)
605 { return ipa_in_px6(a
, n
->prefix
, n
->pxlen
); }
607 static inline int net_in_net_ip4(const net_addr_ip4
*a
, const net_addr_ip4
*b
)
608 { return (a
->pxlen
>= b
->pxlen
) && ipa_in_px4(a
->prefix
, b
->prefix
, b
->pxlen
); }
610 static inline int net_in_net_ip6(const net_addr_ip6
*a
, const net_addr_ip6
*b
)
611 { return (a
->pxlen
>= b
->pxlen
) && ipa_in_px6(a
->prefix
, b
->prefix
, b
->pxlen
); }
613 static inline int net_in_net_dst_ip6_sadr(const net_addr_ip6_sadr
*a
, const net_addr_ip6_sadr
*b
)
614 { return (a
->dst_pxlen
>= b
->dst_pxlen
) && ipa_in_px6(a
->dst_prefix
, b
->dst_prefix
, b
->dst_pxlen
); }
616 static inline int net_in_net_src_ip6_sadr(const net_addr_ip6_sadr
*a
, const net_addr_ip6_sadr
*b
)
617 { return (a
->src_pxlen
>= b
->src_pxlen
) && ipa_in_px6(a
->src_prefix
, b
->src_prefix
, b
->src_pxlen
); }
619 int ipa_in_netX(const ip_addr A
, const net_addr
*N
);
620 int net_in_netX(const net_addr
*A
, const net_addr
*N
);