]>
git.ipfire.org Git - thirdparty/bird.git/blob - lib/net.c
5 #include "lib/flowspec.h"
8 const char * const net_label
[] = {
15 [NET_FLOW4
] = "flow4",
16 [NET_FLOW6
] = "flow6",
17 [NET_IP6_SADR
]= "ipv6-sadr",
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
),
30 [NET_IP6_SADR
]= sizeof(net_addr_ip6_sadr
),
31 [NET_MPLS
] = sizeof(net_addr_mpls
),
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
,
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" */
62 rd_format(const u64 rd
, char *buf
, int buflen
)
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));
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
);
77 net_format(const net_addr
*N
, char *buf
, int buflen
)
79 net_addr_union
*n
= (void *) N
;
85 return bsnprintf(buf
, buflen
, "%I4/%d", n
->ip4
.prefix
, n
->ip4
.pxlen
);
87 return bsnprintf(buf
, buflen
, "%I6/%d", n
->ip6
.prefix
, n
->ip6
.pxlen
);
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
);
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
);
102 return bsnprintf(buf
, buflen
, "%I4/%u-%u AS%u", n
->roa4
.prefix
, n
->roa4
.pxlen
, n
->roa4
.max_pxlen
, n
->roa4
.asn
);
104 return bsnprintf(buf
, buflen
, "%I6/%u-%u AS%u", n
->roa6
.prefix
, n
->roa6
.pxlen
, n
->roa6
.max_pxlen
, n
->roa6
.asn
);
106 return flow4_net_format(buf
, buflen
, &n
->flow4
);
108 return flow6_net_format(buf
, buflen
, &n
->flow6
);
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
);
112 return bsnprintf(buf
, buflen
, "%u", n
->mpls
.label
);
115 bug("unknown network type");
119 net_pxmask(const net_addr
*a
)
127 return ipa_from_ip4(ip4_mkmask(net4_pxlen(a
)));
134 return ipa_from_ip6(ip6_mkmask(net6_pxlen(a
)));
143 net_compare(const net_addr
*a
, const net_addr
*b
)
145 if (a
->type
!= b
->type
)
146 return uint_cmp(a
->type
, b
->type
);
151 return net_compare_ip4((const net_addr_ip4
*) a
, (const net_addr_ip4
*) b
);
153 return net_compare_ip6((const net_addr_ip6
*) a
, (const net_addr_ip6
*) b
);
155 return net_compare_vpn4((const net_addr_vpn4
*) a
, (const net_addr_vpn4
*) b
);
157 return net_compare_vpn6((const net_addr_vpn6
*) a
, (const net_addr_vpn6
*) b
);
159 return net_compare_roa4((const net_addr_roa4
*) a
, (const net_addr_roa4
*) b
);
161 return net_compare_roa6((const net_addr_roa6
*) a
, (const net_addr_roa6
*) b
);
163 return net_compare_flow4((const net_addr_flow4
*) a
, (const net_addr_flow4
*) b
);
165 return net_compare_flow6((const net_addr_flow6
*) a
, (const net_addr_flow6
*) b
);
167 return net_compare_ip6_sadr((const net_addr_ip6_sadr
*) a
, (const net_addr_ip6_sadr
*) b
);
169 return net_compare_mpls((const net_addr_mpls
*) a
, (const net_addr_mpls
*) b
);
174 #define NET_HASH(a,t) net_hash_##t((const net_addr_##t *) a)
177 net_hash(const net_addr
*n
)
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");
196 #define NET_VALIDATE(a,t) net_validate_##t((const net_addr_##t *) a)
199 net_validate(const net_addr
*n
)
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
);
218 net_normalize(net_addr
*N
)
220 net_addr_union
*n
= (void *) N
;
228 return net_normalize_ip4(&n
->ip4
);
234 return net_normalize_ip6(&n
->ip6
);
237 return net_normalize_ip6_sadr(&n
->ip6_sadr
);
245 net_classify(const net_addr
*N
)
247 net_addr_union
*n
= (void *) N
;
255 return ip4_zero(n
->ip4
.prefix
) ? (IADDR_HOST
| SCOPE_UNIVERSE
) : ip4_classify(n
->ip4
.prefix
);
261 return ip6_zero(n
->ip6
.prefix
) ? (IADDR_HOST
| SCOPE_UNIVERSE
) : ip6_classify(&n
->ip6
.prefix
);
264 return ip6_zero(n
->ip6_sadr
.dst_prefix
) ? (IADDR_HOST
| SCOPE_UNIVERSE
) : ip6_classify(&n
->ip6_sadr
.dst_prefix
);
267 return IADDR_HOST
| SCOPE_UNIVERSE
;
270 return IADDR_INVALID
;
274 ipa_in_netX(const ip_addr a
, const net_addr
*n
)
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
))));
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
))));
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
))));
306 net_in_netX(const net_addr
*a
, const net_addr
*n
)
308 if (a
->type
!= n
->type
)
311 return (net_pxlen(n
) <= net_pxlen(a
)) && ipa_in_netX(net_prefix(a
), n
);
314 #define CHECK_NET(T,S) \
315 ({ if (sizeof(T) != S) die("sizeof %s is %d/%d", #T, (int) sizeof(T), S); })
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);