File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / bird2 / lib / net.h
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Oct 21 16:03:56 2019 UTC (4 years, 9 months ago) by misho
Branches: bird2, MAIN
CVS tags: v2_0_7p0, HEAD
bird2 ver 2.0.7

    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>