Annotation of embedaddon/bird2/lib/net.c, revision 1.1.1.1

1.1       misho       1: 
                      2: #include "nest/bird.h"
                      3: #include "lib/ip.h"
                      4: #include "lib/net.h"
                      5: #include "lib/flowspec.h"
                      6: 
                      7: 
                      8: const char * const net_label[] = {
                      9:   [NET_IP4]    = "ipv4",
                     10:   [NET_IP6]    = "ipv6",
                     11:   [NET_VPN4]   = "vpn4",
                     12:   [NET_VPN6]   = "vpn6",
                     13:   [NET_ROA4]   = "roa4",
                     14:   [NET_ROA6]   = "roa6",
                     15:   [NET_FLOW4]  = "flow4",
                     16:   [NET_FLOW6]  = "flow6",
                     17:   [NET_IP6_SADR]= "ipv6-sadr",
                     18:   [NET_MPLS]   = "mpls",
                     19: };
                     20: 
                     21: const u16 net_addr_length[] = {
                     22:   [NET_IP4]    = sizeof(net_addr_ip4),
                     23:   [NET_IP6]    = sizeof(net_addr_ip6),
                     24:   [NET_VPN4]   = sizeof(net_addr_vpn4),
                     25:   [NET_VPN6]   = sizeof(net_addr_vpn6),
                     26:   [NET_ROA4]   = sizeof(net_addr_roa4),
                     27:   [NET_ROA6]   = sizeof(net_addr_roa6),
                     28:   [NET_FLOW4]  = 0,
                     29:   [NET_FLOW6]  = 0,
                     30:   [NET_IP6_SADR]= sizeof(net_addr_ip6_sadr),
                     31:   [NET_MPLS]   = sizeof(net_addr_mpls),
                     32: };
                     33: 
                     34: const u8 net_max_prefix_length[] = {
                     35:   [NET_IP4]    = IP4_MAX_PREFIX_LENGTH,
                     36:   [NET_IP6]    = IP6_MAX_PREFIX_LENGTH,
                     37:   [NET_VPN4]   = IP4_MAX_PREFIX_LENGTH,
                     38:   [NET_VPN6]   = IP6_MAX_PREFIX_LENGTH,
                     39:   [NET_ROA4]   = IP4_MAX_PREFIX_LENGTH,
                     40:   [NET_ROA6]   = IP6_MAX_PREFIX_LENGTH,
                     41:   [NET_FLOW4]  = IP4_MAX_PREFIX_LENGTH,
                     42:   [NET_FLOW6]  = IP6_MAX_PREFIX_LENGTH,
                     43:   [NET_IP6_SADR]= IP6_MAX_PREFIX_LENGTH,
                     44:   [NET_MPLS]   = 0,
                     45: };
                     46: 
                     47: const u16 net_max_text_length[] = {
                     48:   [NET_IP4]    = 18,   /* "255.255.255.255/32" */
                     49:   [NET_IP6]    = 43,   /* "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128" */
                     50:   [NET_VPN4]   = 40,   /* "4294967296:4294967296 255.255.255.255/32" */
                     51:   [NET_VPN6]   = 65,   /* "4294967296:4294967296 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128" */
                     52:   [NET_ROA4]   = 34,   /* "255.255.255.255/32-32 AS4294967295" */
                     53:   [NET_ROA6]   = 60,   /* "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128-128 AS4294967295" */
                     54:   [NET_FLOW4]  = 0,    /* "flow4 { ... }" */
                     55:   [NET_FLOW6]  = 0,    /* "flow6 { ... }" */
                     56:   [NET_IP6_SADR]= 92,  /* "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128 from ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128" */
                     57:   [NET_MPLS]   = 7,    /* "1048575" */
                     58: };
                     59: 
                     60: 
                     61: int
                     62: rd_format(const u64 rd, char *buf, int buflen)
                     63: {
                     64:   switch (rd >> 48)
                     65:   {
                     66:     case 0: return bsnprintf(buf, buflen, "%u:%u", (u32) (rd >> 32), (u32) rd);
                     67:     case 1: return bsnprintf(buf, buflen, "%I4:%u", ip4_from_u32(rd >> 16), (u32) (rd & 0xffff));
                     68:     case 2: if (((u32) (rd >> 16)) >> 16)
                     69:              return bsnprintf(buf, buflen, "%u:%u", (u32) (rd >> 16), (u32) (rd & 0xffff));
                     70:            else
                     71:              return bsnprintf(buf, buflen, "2:%u:%u", (u32) (rd >> 16), (u32) (rd & 0xffff));
                     72:     default: return bsnprintf(buf, buflen, "X:%08x:%08x", (u32) (rd >> 32), (u32) rd);
                     73:   }
                     74: }
                     75: 
                     76: int
                     77: net_format(const net_addr *N, char *buf, int buflen)
                     78: {
                     79:   net_addr_union *n = (void *) N;
                     80:   buf[0] = 0;
                     81: 
                     82:   switch (n->n.type)
                     83:   {
                     84:   case NET_IP4:
                     85:     return bsnprintf(buf, buflen, "%I4/%d", n->ip4.prefix, n->ip4.pxlen);
                     86:   case NET_IP6:
                     87:     return bsnprintf(buf, buflen, "%I6/%d", n->ip6.prefix, n->ip6.pxlen);
                     88:   case NET_VPN4:
                     89:     {
                     90:     int c = rd_format(n->vpn4.rd, buf, buflen);
                     91:     ADVANCE(buf, buflen, c);
                     92:     return bsnprintf(buf, buflen, " %I4/%d", n->vpn4.prefix, n->vpn4.pxlen);
                     93:     }
                     94:   case NET_VPN6:
                     95:     {
                     96:     /* XXX: RD format is specified for VPN4; not found any for VPN6, reusing the same as for VPN4 */
                     97:     int c = rd_format(n->vpn6.rd, buf, buflen);
                     98:     ADVANCE(buf, buflen, c);
                     99:     return bsnprintf(buf, buflen, " %I6/%d", n->vpn6.prefix, n->vpn6.pxlen);
                    100:     }
                    101:   case NET_ROA4:
                    102:     return bsnprintf(buf, buflen, "%I4/%u-%u AS%u",  n->roa4.prefix, n->roa4.pxlen, n->roa4.max_pxlen, n->roa4.asn);
                    103:   case NET_ROA6:
                    104:     return bsnprintf(buf, buflen, "%I6/%u-%u AS%u",  n->roa6.prefix, n->roa6.pxlen, n->roa6.max_pxlen, n->roa6.asn);
                    105:   case NET_FLOW4:
                    106:     return flow4_net_format(buf, buflen, &n->flow4);
                    107:   case NET_FLOW6:
                    108:     return flow6_net_format(buf, buflen, &n->flow6);
                    109:   case NET_IP6_SADR:
                    110:     return bsnprintf(buf, buflen, "%I6/%d from %I6/%d", n->ip6_sadr.dst_prefix, n->ip6_sadr.dst_pxlen, n->ip6_sadr.src_prefix, n->ip6_sadr.src_pxlen);
                    111:   case NET_MPLS:
                    112:     return bsnprintf(buf, buflen, "%u", n->mpls.label);
                    113:   }
                    114: 
                    115:   bug("unknown network type");
                    116: }
                    117: 
                    118: ip_addr
                    119: net_pxmask(const net_addr *a)
                    120: {
                    121:   switch (a->type)
                    122:   {
                    123:   case NET_IP4:
                    124:   case NET_VPN4:
                    125:   case NET_ROA4:
                    126:   case NET_FLOW4:
                    127:     return ipa_from_ip4(ip4_mkmask(net4_pxlen(a)));
                    128: 
                    129:   case NET_IP6:
                    130:   case NET_VPN6:
                    131:   case NET_ROA6:
                    132:   case NET_FLOW6:
                    133:   case NET_IP6_SADR:
                    134:     return ipa_from_ip6(ip6_mkmask(net6_pxlen(a)));
                    135: 
                    136:   case NET_MPLS:
                    137:   default:
                    138:     return IPA_NONE;
                    139:   }
                    140: }
                    141: 
                    142: int
                    143: net_compare(const net_addr *a, const net_addr *b)
                    144: {
                    145:   if (a->type != b->type)
                    146:     return uint_cmp(a->type, b->type);
                    147: 
                    148:   switch (a->type)
                    149:   {
                    150:   case NET_IP4:
                    151:     return net_compare_ip4((const net_addr_ip4 *) a, (const net_addr_ip4 *) b);
                    152:   case NET_IP6:
                    153:     return net_compare_ip6((const net_addr_ip6 *) a, (const net_addr_ip6 *) b);
                    154:   case NET_VPN4:
                    155:     return net_compare_vpn4((const net_addr_vpn4 *) a, (const net_addr_vpn4 *) b);
                    156:   case NET_VPN6:
                    157:     return net_compare_vpn6((const net_addr_vpn6 *) a, (const net_addr_vpn6 *) b);
                    158:   case NET_ROA4:
                    159:     return net_compare_roa4((const net_addr_roa4 *) a, (const net_addr_roa4 *) b);
                    160:   case NET_ROA6:
                    161:     return net_compare_roa6((const net_addr_roa6 *) a, (const net_addr_roa6 *) b);
                    162:   case NET_FLOW4:
                    163:     return net_compare_flow4((const net_addr_flow4 *) a, (const net_addr_flow4 *) b);
                    164:   case NET_FLOW6:
                    165:     return net_compare_flow6((const net_addr_flow6 *) a, (const net_addr_flow6 *) b);
                    166:   case NET_IP6_SADR:
                    167:     return net_compare_ip6_sadr((const net_addr_ip6_sadr *) a, (const net_addr_ip6_sadr *) b);
                    168:   case NET_MPLS:
                    169:     return net_compare_mpls((const net_addr_mpls *) a, (const net_addr_mpls *) b);
                    170:   }
                    171:   return 0;
                    172: }
                    173: 
                    174: #define NET_HASH(a,t) net_hash_##t((const net_addr_##t *) a)
                    175: 
                    176: u32
                    177: net_hash(const net_addr *n)
                    178: {
                    179:   switch (n->type)
                    180:   {
                    181:   case NET_IP4: return NET_HASH(n, ip4);
                    182:   case NET_IP6: return NET_HASH(n, ip6);
                    183:   case NET_VPN4: return NET_HASH(n, vpn4);
                    184:   case NET_VPN6: return NET_HASH(n, vpn6);
                    185:   case NET_ROA4: return NET_HASH(n, roa4);
                    186:   case NET_ROA6: return NET_HASH(n, roa6);
                    187:   case NET_FLOW4: return NET_HASH(n, flow4);
                    188:   case NET_FLOW6: return NET_HASH(n, flow6);
                    189:   case NET_IP6_SADR: return NET_HASH(n, ip6_sadr);
                    190:   case NET_MPLS: return NET_HASH(n, mpls);
                    191:   default: bug("invalid type");
                    192:   }
                    193: }
                    194: 
                    195: 
                    196: #define NET_VALIDATE(a,t) net_validate_##t((const net_addr_##t *) a)
                    197: 
                    198: int
                    199: net_validate(const net_addr *n)
                    200: {
                    201:   switch (n->type)
                    202:   {
                    203:   case NET_IP4: return NET_VALIDATE(n, ip4);
                    204:   case NET_IP6: return NET_VALIDATE(n, ip6);
                    205:   case NET_VPN4: return NET_VALIDATE(n, vpn4);
                    206:   case NET_VPN6: return NET_VALIDATE(n, vpn6);
                    207:   case NET_ROA4: return NET_VALIDATE(n, roa4);
                    208:   case NET_ROA6: return NET_VALIDATE(n, roa6);
                    209:   case NET_FLOW4: return NET_VALIDATE(n, flow4);
                    210:   case NET_FLOW6: return NET_VALIDATE(n, flow6);
                    211:   case NET_IP6_SADR: return NET_VALIDATE(n, ip6_sadr);
                    212:   case NET_MPLS: return NET_VALIDATE(n, mpls);
                    213:   default: return 0;
                    214:   }
                    215: }
                    216: 
                    217: void
                    218: net_normalize(net_addr *N)
                    219: {
                    220:   net_addr_union *n = (void *) N;
                    221: 
                    222:   switch (n->n.type)
                    223:   {
                    224:   case NET_IP4:
                    225:   case NET_VPN4:
                    226:   case NET_ROA4:
                    227:   case NET_FLOW4:
                    228:     return net_normalize_ip4(&n->ip4);
                    229: 
                    230:   case NET_IP6:
                    231:   case NET_VPN6:
                    232:   case NET_ROA6:
                    233:   case NET_FLOW6:
                    234:     return net_normalize_ip6(&n->ip6);
                    235: 
                    236:   case NET_IP6_SADR:
                    237:     return net_normalize_ip6_sadr(&n->ip6_sadr);
                    238: 
                    239:   case NET_MPLS:
                    240:     return;
                    241:   }
                    242: }
                    243: 
                    244: int
                    245: net_classify(const net_addr *N)
                    246: {
                    247:   net_addr_union *n = (void *) N;
                    248: 
                    249:   switch (n->n.type)
                    250:   {
                    251:   case NET_IP4:
                    252:   case NET_VPN4:
                    253:   case NET_ROA4:
                    254:   case NET_FLOW4:
                    255:     return ip4_zero(n->ip4.prefix) ? (IADDR_HOST | SCOPE_UNIVERSE) : ip4_classify(n->ip4.prefix);
                    256: 
                    257:   case NET_IP6:
                    258:   case NET_VPN6:
                    259:   case NET_ROA6:
                    260:   case NET_FLOW6:
                    261:     return ip6_zero(n->ip6.prefix) ? (IADDR_HOST | SCOPE_UNIVERSE) : ip6_classify(&n->ip6.prefix);
                    262: 
                    263:   case NET_IP6_SADR:
                    264:     return ip6_zero(n->ip6_sadr.dst_prefix) ? (IADDR_HOST | SCOPE_UNIVERSE) : ip6_classify(&n->ip6_sadr.dst_prefix);
                    265: 
                    266:   case NET_MPLS:
                    267:     return IADDR_HOST | SCOPE_UNIVERSE;
                    268:   }
                    269: 
                    270:   return IADDR_INVALID;
                    271: }
                    272: 
                    273: int
                    274: ipa_in_netX(const ip_addr a, const net_addr *n)
                    275: {
                    276:   switch (n->type)
                    277:   {
                    278:   case NET_IP4:
                    279:   case NET_VPN4:
                    280:   case NET_ROA4:
                    281:   case NET_FLOW4:
                    282:     if (!ipa_is_ip4(a)) return 0;
                    283:     return ip4_zero(ip4_and(ip4_xor(ipa_to_ip4(a), net4_prefix(n)),
                    284:                            ip4_mkmask(net4_pxlen(n))));
                    285: 
                    286:   case NET_IP6:
                    287:   case NET_VPN6:
                    288:   case NET_ROA6:
                    289:   case NET_FLOW6:
                    290:     if (ipa_is_ip4(a)) return 0;
                    291:     return ip6_zero(ip6_and(ip6_xor(ipa_to_ip6(a), net6_prefix(n)),
                    292:                            ip6_mkmask(net6_pxlen(n))));
                    293: 
                    294:   case NET_IP6_SADR:
                    295:     if (ipa_is_ip4(a)) return 0;
                    296:     return ip6_zero(ip6_and(ip6_xor(ipa_to_ip6(a), net6_prefix(n)),
                    297:                            ip6_mkmask(net6_pxlen(n))));
                    298: 
                    299:   case NET_MPLS:
                    300:   default:
                    301:     return 0;
                    302:   }
                    303: }
                    304: 
                    305: int
                    306: net_in_netX(const net_addr *a, const net_addr *n)
                    307: {
                    308:   if (a->type != n->type)
                    309:     return 0;
                    310: 
                    311:   return (net_pxlen(n) <= net_pxlen(a)) && ipa_in_netX(net_prefix(a), n);
                    312: }
                    313: 
                    314: #define CHECK_NET(T,S) \
                    315:   ({ if (sizeof(T) != S) die("sizeof %s is %d/%d", #T, (int) sizeof(T), S); })
                    316: 
                    317: void
                    318: net_init(void)
                    319: {
                    320:   CHECK_NET(net_addr,          24);
                    321:   CHECK_NET(net_addr_ip4,       8);
                    322:   CHECK_NET(net_addr_ip6,      20);
                    323:   CHECK_NET(net_addr_vpn4,     16);
                    324:   CHECK_NET(net_addr_vpn6,     32);
                    325:   CHECK_NET(net_addr_roa4,     16);
                    326:   CHECK_NET(net_addr_roa6,     28);
                    327:   CHECK_NET(net_addr_flow4,     8);
                    328:   CHECK_NET(net_addr_flow6,    20);
                    329:   CHECK_NET(net_addr_ip6_sadr, 40);
                    330:   CHECK_NET(net_addr_mpls,      8);
                    331: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>