Annotation of embedaddon/bird2/lib/net.h, revision 1.1
1.1 ! misho 1: /*
! 2: * BIRD Internet Routing Daemon -- Network addresses
! 3: *
! 4: * (c) 2015 Ondrej Zajicek <santiago@crfreenet.org>
! 5: * (c) 2015 CZ.NIC z.s.p.o.
! 6: *
! 7: * Can be freely distributed and used under the terms of the GNU GPL.
! 8: */
! 9:
! 10: #ifndef _BIRD_NET_H_
! 11: #define _BIRD_NET_H_
! 12:
! 13: #include "lib/ip.h"
! 14:
! 15:
! 16: #define NET_IP4 1
! 17: #define NET_IP6 2
! 18: #define NET_VPN4 3
! 19: #define NET_VPN6 4
! 20: #define NET_ROA4 5
! 21: #define NET_ROA6 6
! 22: #define NET_FLOW4 7
! 23: #define NET_FLOW6 8
! 24: #define NET_IP6_SADR 9
! 25: #define NET_MPLS 10
! 26: #define NET_MAX 11
! 27:
! 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)
! 38:
! 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
! 44:
! 45:
! 46: typedef struct net_addr {
! 47: u8 type;
! 48: u8 pxlen;
! 49: u16 length;
! 50: u8 data[20];
! 51: u64 align[0];
! 52: } net_addr;
! 53:
! 54: typedef struct net_addr_ip4 {
! 55: u8 type;
! 56: u8 pxlen;
! 57: u16 length;
! 58: ip4_addr prefix;
! 59: } net_addr_ip4;
! 60:
! 61: typedef struct net_addr_ip6 {
! 62: u8 type;
! 63: u8 pxlen;
! 64: u16 length;
! 65: ip6_addr prefix;
! 66: } net_addr_ip6;
! 67:
! 68: typedef struct net_addr_vpn4 {
! 69: u8 type;
! 70: u8 pxlen;
! 71: u16 length;
! 72: ip4_addr prefix;
! 73: u64 rd;
! 74: } net_addr_vpn4;
! 75:
! 76: typedef struct net_addr_vpn6 {
! 77: u8 type;
! 78: u8 pxlen;
! 79: u16 length;
! 80: ip6_addr prefix;
! 81: u32 padding;
! 82: u64 rd;
! 83: } net_addr_vpn6;
! 84:
! 85: typedef struct net_addr_roa4 {
! 86: u8 type;
! 87: u8 pxlen;
! 88: u16 length;
! 89: ip4_addr prefix;
! 90: u32 max_pxlen;
! 91: u32 asn;
! 92: } net_addr_roa4;
! 93:
! 94: typedef struct net_addr_roa6 {
! 95: u8 type;
! 96: u8 pxlen;
! 97: u16 length;
! 98: ip6_addr prefix;
! 99: u32 max_pxlen;
! 100: u32 asn;
! 101: } net_addr_roa6;
! 102:
! 103: typedef struct net_addr_flow4 {
! 104: u8 type;
! 105: u8 pxlen;
! 106: u16 length;
! 107: ip4_addr prefix;
! 108: byte data[0];
! 109: } net_addr_flow4;
! 110:
! 111: typedef struct net_addr_flow6 {
! 112: u8 type;
! 113: u8 pxlen;
! 114: u16 length;
! 115: ip6_addr prefix;
! 116: byte data[0];
! 117: } net_addr_flow6;
! 118:
! 119: typedef struct net_addr_mpls {
! 120: u8 type;
! 121: u8 pxlen;
! 122: u16 length;
! 123: u32 label;
! 124: } net_addr_mpls;
! 125:
! 126: typedef struct net_addr_ip6_sadr {
! 127: u8 type;
! 128: u8 dst_pxlen;
! 129: u16 length;
! 130: ip6_addr dst_prefix;
! 131: s32 src_pxlen; /* s32 to avoid padding */
! 132: ip6_addr src_prefix;
! 133: } net_addr_ip6_sadr;
! 134:
! 135: typedef union net_addr_union {
! 136: net_addr n;
! 137: net_addr_ip4 ip4;
! 138: net_addr_ip6 ip6;
! 139: net_addr_vpn4 vpn4;
! 140: net_addr_vpn6 vpn6;
! 141: net_addr_roa4 roa4;
! 142: net_addr_roa6 roa6;
! 143: net_addr_flow4 flow4;
! 144: net_addr_flow6 flow6;
! 145: net_addr_ip6_sadr ip6_sadr;
! 146: net_addr_mpls mpls;
! 147: } net_addr_union;
! 148:
! 149:
! 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[];
! 154:
! 155: #define NET_MAX_TEXT_LENGTH 256
! 156:
! 157:
! 158: #define NET_ADDR_IP4(prefix,pxlen) \
! 159: ((net_addr_ip4) { NET_IP4, pxlen, sizeof(net_addr_ip4), prefix })
! 160:
! 161: #define NET_ADDR_IP6(prefix,pxlen) \
! 162: ((net_addr_ip6) { NET_IP6, pxlen, sizeof(net_addr_ip6), prefix })
! 163:
! 164: #define NET_ADDR_VPN4(prefix,pxlen,rd) \
! 165: ((net_addr_vpn4) { NET_VPN4, pxlen, sizeof(net_addr_vpn4), prefix, rd })
! 166:
! 167: #define NET_ADDR_VPN6(prefix,pxlen,rd) \
! 168: ((net_addr_vpn6) { NET_VPN6, pxlen, sizeof(net_addr_vpn6), prefix, 0, rd })
! 169:
! 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 })
! 172:
! 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 })
! 175:
! 176: #define NET_ADDR_FLOW4(prefix,pxlen,dlen) \
! 177: ((net_addr_flow4) { NET_FLOW4, pxlen, sizeof(net_addr_ip4) + dlen, prefix })
! 178:
! 179: #define NET_ADDR_FLOW6(prefix,pxlen,dlen) \
! 180: ((net_addr_flow6) { NET_FLOW6, pxlen, sizeof(net_addr_ip6) + dlen, prefix })
! 181:
! 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 })
! 184:
! 185: #define NET_ADDR_MPLS(label) \
! 186: ((net_addr_mpls) { NET_MPLS, 20, sizeof(net_addr_mpls), label })
! 187:
! 188:
! 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); }
! 191:
! 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); }
! 194:
! 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); }
! 197:
! 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); }
! 200:
! 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); }
! 203:
! 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); }
! 206:
! 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); }
! 209:
! 210: static inline void net_fill_mpls(net_addr *a, u32 label)
! 211: { *(net_addr_mpls *)a = NET_ADDR_MPLS(label); }
! 212:
! 213: static inline void net_fill_ipa(net_addr *a, ip_addr prefix, uint pxlen)
! 214: {
! 215: if (ipa_is_ip4(prefix))
! 216: net_fill_ip4(a, ipa_to_ip4(prefix), pxlen);
! 217: else
! 218: net_fill_ip6(a, ipa_to_ip6(prefix), pxlen);
! 219: }
! 220:
! 221: static inline void net_fill_ip_host(net_addr *a, ip_addr prefix)
! 222: {
! 223: if (ipa_is_ip4(prefix))
! 224: net_fill_ip4(a, ipa_to_ip4(prefix), IP4_MAX_PREFIX_LENGTH);
! 225: else
! 226: net_fill_ip6(a, ipa_to_ip6(prefix), IP6_MAX_PREFIX_LENGTH);
! 227: }
! 228:
! 229: static inline void net_fill_flow4(net_addr *a, ip4_addr prefix, uint pxlen, byte *data, uint dlen)
! 230: {
! 231: net_addr_flow4 *f = (void *) a;
! 232: *f = NET_ADDR_FLOW4(prefix, pxlen, dlen);
! 233: memcpy(f->data, data, dlen);
! 234: }
! 235:
! 236: static inline void net_fill_flow6(net_addr *a, ip6_addr prefix, uint pxlen, byte *data, uint dlen)
! 237: {
! 238: net_addr_flow6 *f = (void *) a;
! 239: *f = NET_ADDR_FLOW6(prefix, pxlen, dlen);
! 240: memcpy(f->data, data, dlen);
! 241: }
! 242:
! 243: /* Make NET_IP6_SADR from NET_IP6, assuming there is enough space */
! 244: static inline void net_make_ip6_sadr(net_addr *a)
! 245: {
! 246: net_addr_ip6_sadr *n = (void *) a;
! 247: n->type = NET_IP6_SADR;
! 248: n->length = sizeof(net_addr_ip6_sadr);
! 249: n->src_pxlen = 0;
! 250: n->src_prefix = IP6_NONE;
! 251: }
! 252:
! 253: static inline int net_val_match(u8 type, u32 mask)
! 254: { return !!((1 << type) & mask); }
! 255:
! 256: static inline int net_type_match(const net_addr *a, u32 mask)
! 257: { return net_val_match(a->type, mask); }
! 258:
! 259: static inline int net_is_ip(const net_addr *a)
! 260: { return (a->type == NET_IP4) || (a->type == NET_IP6); }
! 261:
! 262: static inline int net_is_vpn(const net_addr *a)
! 263: { return (a->type == NET_VPN4) || (a->type == NET_VPN6); }
! 264:
! 265: static inline int net_is_roa(const net_addr *a)
! 266: { return (a->type == NET_ROA4) || (a->type == NET_ROA6); }
! 267:
! 268: static inline int net_is_flow(const net_addr *a)
! 269: { return (a->type == NET_FLOW4) || (a->type == NET_FLOW6); }
! 270:
! 271: static inline int net_is_sadr(const net_addr *a)
! 272: { return (a->type == NET_IP6_SADR); }
! 273:
! 274: static inline ip4_addr net4_prefix(const net_addr *a)
! 275: { return ((net_addr_ip4 *) a)->prefix; }
! 276:
! 277: static inline ip6_addr net6_prefix(const net_addr *a)
! 278: { return ((net_addr_ip6 *) a)->prefix; }
! 279:
! 280: static inline ip_addr net_prefix(const net_addr *a)
! 281: {
! 282: switch (a->type)
! 283: {
! 284: case NET_IP4:
! 285: case NET_VPN4:
! 286: case NET_ROA4:
! 287: case NET_FLOW4:
! 288: return ipa_from_ip4(net4_prefix(a));
! 289:
! 290: case NET_IP6:
! 291: case NET_VPN6:
! 292: case NET_ROA6:
! 293: case NET_FLOW6:
! 294: case NET_IP6_SADR:
! 295: return ipa_from_ip6(net6_prefix(a));
! 296:
! 297: case NET_MPLS:
! 298: default:
! 299: return IPA_NONE;
! 300: }
! 301: }
! 302:
! 303: static inline u32 net_mpls(const net_addr *a)
! 304: {
! 305: if (a->type == NET_MPLS)
! 306: return ((net_addr_mpls *) a)->label;
! 307:
! 308: bug("Can't call net_mpls on non-mpls net_addr");
! 309: }
! 310:
! 311: static inline uint net4_pxlen(const net_addr *a)
! 312: { return a->pxlen; }
! 313:
! 314: static inline uint net6_pxlen(const net_addr *a)
! 315: { return a->pxlen; }
! 316:
! 317: static inline uint net_pxlen(const net_addr *a)
! 318: { return a->pxlen; }
! 319:
! 320: ip_addr net_pxmask(const net_addr *a);
! 321:
! 322: static inline u64 net_rd(const net_addr *a)
! 323: {
! 324: switch (a->type)
! 325: {
! 326: case NET_VPN4:
! 327: return ((net_addr_vpn4 *)a)->rd;
! 328: case NET_VPN6:
! 329: return ((net_addr_vpn6 *)a)->rd;
! 330: }
! 331: return 0;
! 332: }
! 333:
! 334:
! 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); }
! 337:
! 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)); }
! 340:
! 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)); }
! 343:
! 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)); }
! 346:
! 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)); }
! 349:
! 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)); }
! 352:
! 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)); }
! 355:
! 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); }
! 358:
! 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); }
! 361:
! 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)); }
! 364:
! 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)); }
! 367:
! 368:
! 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); }
! 371:
! 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); }
! 374:
! 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); }
! 377:
! 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); }
! 380:
! 381:
! 382: static inline int net_zero_ip4(const net_addr_ip4 *a)
! 383: { return !a->pxlen && ip4_zero(a->prefix); }
! 384:
! 385: static inline int net_zero_ip6(const net_addr_ip6 *a)
! 386: { return !a->pxlen && ip6_zero(a->prefix); }
! 387:
! 388: static inline int net_zero_vpn4(const net_addr_vpn4 *a)
! 389: { return !a->pxlen && ip4_zero(a->prefix) && !a->rd; }
! 390:
! 391: static inline int net_zero_vpn6(const net_addr_vpn6 *a)
! 392: { return !a->pxlen && ip6_zero(a->prefix) && !a->rd; }
! 393:
! 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; }
! 396:
! 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; }
! 399:
! 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)); }
! 402:
! 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)); }
! 405:
! 406: static inline int net_zero_mpls(const net_addr_mpls *a)
! 407: { return !a->label; }
! 408:
! 409:
! 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); }
! 412:
! 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); }
! 415:
! 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); }
! 418:
! 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); }
! 421:
! 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); }
! 424:
! 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); }
! 427:
! 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)); }
! 430:
! 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)); }
! 433:
! 434: static inline int net_compare_ip6_sadr(const net_addr_ip6_sadr *a, const net_addr_ip6_sadr *b)
! 435: {
! 436: return
! 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);
! 439: }
! 440:
! 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); }
! 443:
! 444: int net_compare(const net_addr *a, const net_addr *b);
! 445:
! 446:
! 447: static inline void net_copy(net_addr *dst, const net_addr *src)
! 448: { memcpy(dst, src, src->length); }
! 449:
! 450: static inline void net_copy_ip4(net_addr_ip4 *dst, const net_addr_ip4 *src)
! 451: { memcpy(dst, src, sizeof(net_addr_ip4)); }
! 452:
! 453: static inline void net_copy_ip6(net_addr_ip6 *dst, const net_addr_ip6 *src)
! 454: { memcpy(dst, src, sizeof(net_addr_ip6)); }
! 455:
! 456: static inline void net_copy_vpn4(net_addr_vpn4 *dst, const net_addr_vpn4 *src)
! 457: { memcpy(dst, src, sizeof(net_addr_vpn4)); }
! 458:
! 459: static inline void net_copy_vpn6(net_addr_vpn6 *dst, const net_addr_vpn6 *src)
! 460: { memcpy(dst, src, sizeof(net_addr_vpn6)); }
! 461:
! 462: static inline void net_copy_roa4(net_addr_roa4 *dst, const net_addr_roa4 *src)
! 463: { memcpy(dst, src, sizeof(net_addr_roa4)); }
! 464:
! 465: static inline void net_copy_roa6(net_addr_roa6 *dst, const net_addr_roa6 *src)
! 466: { memcpy(dst, src, sizeof(net_addr_roa6)); }
! 467:
! 468: static inline void net_copy_flow4(net_addr_flow4 *dst, const net_addr_flow4 *src)
! 469: { memcpy(dst, src, src->length); }
! 470:
! 471: static inline void net_copy_flow6(net_addr_flow6 *dst, const net_addr_flow6 *src)
! 472: { memcpy(dst, src, src->length); }
! 473:
! 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)); }
! 476:
! 477: static inline void net_copy_mpls(net_addr_mpls *dst, const net_addr_mpls *src)
! 478: { memcpy(dst, src, sizeof(net_addr_mpls)); }
! 479:
! 480:
! 481: /* XXXX */
! 482: static inline u32 u64_hash(u64 a)
! 483: { return u32_hash(a); }
! 484:
! 485: static inline u32 net_hash_ip4(const net_addr_ip4 *n)
! 486: { return ip4_hash(n->prefix) ^ ((u32) n->pxlen << 26); }
! 487:
! 488: static inline u32 net_hash_ip6(const net_addr_ip6 *n)
! 489: { return ip6_hash(n->prefix) ^ ((u32) n->pxlen << 26); }
! 490:
! 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); }
! 493:
! 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); }
! 496:
! 497: static inline u32 net_hash_roa4(const net_addr_roa4 *n)
! 498: { return ip4_hash(n->prefix) ^ ((u32) n->pxlen << 26); }
! 499:
! 500: static inline u32 net_hash_roa6(const net_addr_roa6 *n)
! 501: { return ip6_hash(n->prefix) ^ ((u32) n->pxlen << 26); }
! 502:
! 503: static inline u32 net_hash_flow4(const net_addr_flow4 *n)
! 504: { return ip4_hash(n->prefix) ^ ((u32) n->pxlen << 26); }
! 505:
! 506: static inline u32 net_hash_flow6(const net_addr_flow6 *n)
! 507: { return ip6_hash(n->prefix) ^ ((u32) n->pxlen << 26); }
! 508:
! 509: static inline u32 net_hash_ip6_sadr(const net_addr_ip6_sadr *n)
! 510: { return net_hash_ip6((net_addr_ip6 *) n); }
! 511:
! 512: static inline u32 net_hash_mpls(const net_addr_mpls *n)
! 513: { return n->label; }
! 514:
! 515: u32 net_hash(const net_addr *a);
! 516:
! 517:
! 518: static inline int net_validate_px4(const ip4_addr prefix, uint pxlen)
! 519: {
! 520: return (pxlen <= IP4_MAX_PREFIX_LENGTH) &&
! 521: ip4_zero(ip4_and(prefix, ip4_not(ip4_mkmask(pxlen))));
! 522: }
! 523:
! 524: static inline int net_validate_px6(const ip6_addr prefix, uint pxlen)
! 525: {
! 526: return (pxlen <= IP6_MAX_PREFIX_LENGTH) &&
! 527: ip6_zero(ip6_and(prefix, ip6_not(ip6_mkmask(pxlen))));
! 528: }
! 529:
! 530: static inline int net_validate_ip4(const net_addr_ip4 *n)
! 531: { return net_validate_px4(n->prefix, n->pxlen); }
! 532:
! 533: static inline int net_validate_ip6(const net_addr_ip6 *n)
! 534: { return net_validate_px6(n->prefix, n->pxlen); }
! 535:
! 536: static inline int net_validate_vpn4(const net_addr_vpn4 *n)
! 537: { return net_validate_px4(n->prefix, n->pxlen); }
! 538:
! 539: static inline int net_validate_vpn6(const net_addr_vpn6 *n)
! 540: { return net_validate_px6(n->prefix, n->pxlen); }
! 541:
! 542: static inline int net_validate_roa4(const net_addr_roa4 *n)
! 543: {
! 544: return net_validate_px4(n->prefix, n->pxlen) &&
! 545: (n->pxlen <= n->max_pxlen) && (n->max_pxlen <= IP4_MAX_PREFIX_LENGTH);
! 546: }
! 547:
! 548: static inline int net_validate_roa6(const net_addr_roa6 *n)
! 549: {
! 550: return net_validate_px6(n->prefix, n->pxlen) &&
! 551: (n->pxlen <= n->max_pxlen) && (n->max_pxlen <= IP6_MAX_PREFIX_LENGTH);
! 552: }
! 553:
! 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); }
! 557:
! 558: static inline int net_validate_flow6(const net_addr_flow6 *n)
! 559: { return net_validate_px6(n->prefix, n->pxlen); }
! 560:
! 561: static inline int net_validate_mpls(const net_addr_mpls *n)
! 562: { return n->label < (1 << 20); }
! 563:
! 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); }
! 566:
! 567: int net_validate(const net_addr *N);
! 568:
! 569:
! 570: static inline void net_normalize_ip4(net_addr_ip4 *n)
! 571: { n->prefix = ip4_and(n->prefix, ip4_mkmask(n->pxlen)); }
! 572:
! 573: static inline void net_normalize_ip6(net_addr_ip6 *n)
! 574: { n->prefix = ip6_and(n->prefix, ip6_mkmask(n->pxlen)); }
! 575:
! 576: static inline void net_normalize_vpn4(net_addr_vpn4 *n)
! 577: { net_normalize_ip4((net_addr_ip4 *) n); }
! 578:
! 579: static inline void net_normalize_vpn6(net_addr_vpn6 *n)
! 580: { net_normalize_ip6((net_addr_ip6 *) n); }
! 581:
! 582: static inline void net_normalize_ip6_sadr(net_addr_ip6_sadr *n)
! 583: {
! 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));
! 586: }
! 587:
! 588: void net_normalize(net_addr *N);
! 589:
! 590:
! 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);
! 594:
! 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))); }
! 597:
! 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))); }
! 600:
! 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); }
! 603:
! 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); }
! 606:
! 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); }
! 609:
! 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); }
! 612:
! 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); }
! 615:
! 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); }
! 618:
! 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);
! 621:
! 622: void net_init(void);
! 623:
! 624: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>