Annotation of embedaddon/bird2/lib/net.c, revision 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>