Statistics
| Branch: | Revision:

iof-bird-daemon / lib / net.c @ d14f8c3c

History | View | Annotate | Download (6.49 KB)

1 fe9f1a6d Ondrej Zajicek (work)
2
#include "nest/bird.h"
3
#include "lib/ip.h"
4
#include "lib/net.h"
5 77234bbb Ondrej Zajicek (work)
#include "lib/flowspec.h"
6 fe9f1a6d Ondrej Zajicek (work)
7 d7661fbe Jan Moskyto Matejka
8 f4a60a9b Ondrej Zajicek (work)
const char * const net_label[] = {
9 77234bbb Ondrej Zajicek (work)
  [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 33ad6e01 Jan Moskyto Matejka
  [NET_FLOW6]         = "flow6",
17
  [NET_MPLS]        = "mpls",
18 f4a60a9b Ondrej Zajicek (work)
};
19
20 fe9f1a6d Ondrej Zajicek (work)
const u16 net_addr_length[] = {
21 77234bbb Ondrej Zajicek (work)
  [NET_IP4]         = sizeof(net_addr_ip4),
22
  [NET_IP6]         = sizeof(net_addr_ip6),
23
  [NET_VPN4]         = sizeof(net_addr_vpn4),
24
  [NET_VPN6]         = sizeof(net_addr_vpn6),
25
  [NET_ROA4]         = sizeof(net_addr_roa4),
26
  [NET_ROA6]         = sizeof(net_addr_roa6),
27
  [NET_FLOW4]         = 0,
28 33ad6e01 Jan Moskyto Matejka
  [NET_FLOW6]         = 0,
29
  [NET_MPLS]        = sizeof(net_addr_mpls),
30 9b136840 Jan Moskyto Matejka
};
31 fe9f1a6d Ondrej Zajicek (work)
32 d7661fbe Jan Moskyto Matejka
const u8 net_max_prefix_length[] = {
33 77234bbb Ondrej Zajicek (work)
  [NET_IP4]         = IP4_MAX_PREFIX_LENGTH,
34
  [NET_IP6]         = IP6_MAX_PREFIX_LENGTH,
35
  [NET_VPN4]         = IP4_MAX_PREFIX_LENGTH,
36
  [NET_VPN6]         = IP6_MAX_PREFIX_LENGTH,
37
  [NET_ROA4]         = IP4_MAX_PREFIX_LENGTH,
38
  [NET_ROA6]         = IP6_MAX_PREFIX_LENGTH,
39
  [NET_FLOW4]         = IP4_MAX_PREFIX_LENGTH,
40 33ad6e01 Jan Moskyto Matejka
  [NET_FLOW6]         = IP6_MAX_PREFIX_LENGTH,
41
  [NET_MPLS]        = 0,
42 d7661fbe Jan Moskyto Matejka
};
43
44 7fd4143e Jan Moskyto Matejka
const u16 net_max_text_length[] = {
45 77234bbb Ondrej Zajicek (work)
  [NET_IP4]         = 18,        /* "255.255.255.255/32" */
46
  [NET_IP6]         = 43,        /* "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128" */
47
  [NET_VPN4]         = 40,        /* "4294967296:4294967296 255.255.255.255/32" */
48
  [NET_VPN6]         = 65,        /* "4294967296:4294967296 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128" */
49
  [NET_ROA4]         = 34,        /* "255.255.255.255/32-32 AS4294967295" */
50
  [NET_ROA6]         = 60,        /* "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128-128 AS4294967295" */
51
  [NET_FLOW4]         = 0,        /* "flow4 { ... }" */
52 33ad6e01 Jan Moskyto Matejka
  [NET_FLOW6]         = 0,        /* "flow6 { ... }" */
53
  [NET_MPLS]        = 7,        /* "1048575" */
54 7fd4143e Jan Moskyto Matejka
};
55
56 d7661fbe Jan Moskyto Matejka
57 9b136840 Jan Moskyto Matejka
int
58 fe9f1a6d Ondrej Zajicek (work)
net_format(const net_addr *N, char *buf, int buflen)
59
{
60
  net_addr_union *n = (void *) N;
61
62
  switch (n->n.type)
63
  {
64
  case NET_IP4:
65 e691d16a Ondrej Zajicek (work)
    return bsnprintf(buf, buflen, "%I4/%d", n->ip4.prefix, n->ip4.pxlen);
66 fe9f1a6d Ondrej Zajicek (work)
  case NET_IP6:
67 e691d16a Ondrej Zajicek (work)
    return bsnprintf(buf, buflen, "%I6/%d", n->ip6.prefix, n->ip6.pxlen);
68 fe9f1a6d Ondrej Zajicek (work)
  case NET_VPN4:
69 e691d16a Ondrej Zajicek (work)
    return bsnprintf(buf, buflen, "%u:%u %I4/%d", (u32) (n->vpn4.rd >> 32), (u32) n->vpn4.rd, n->vpn4.prefix, n->vpn4.pxlen);
70 fe9f1a6d Ondrej Zajicek (work)
  case NET_VPN6:
71 e691d16a Ondrej Zajicek (work)
    return bsnprintf(buf, buflen, "%u:%u %I6/%d", (u32) (n->vpn6.rd >> 32), (u32) n->vpn6.rd, n->vpn6.prefix, n->vpn6.pxlen);
72 de9b87f5 Pavel Tvrdík
  case NET_ROA4:
73 f9d729ab Pavel Tvrdík
    return bsnprintf(buf, buflen, "%I4/%u-%u AS%u",  n->roa4.prefix, n->roa4.pxlen, n->roa4.max_pxlen, n->roa4.asn);
74 de9b87f5 Pavel Tvrdík
  case NET_ROA6:
75 f9d729ab Pavel Tvrdík
    return bsnprintf(buf, buflen, "%I6/%u-%u AS%u",  n->roa6.prefix, n->roa6.pxlen, n->roa6.max_pxlen, n->roa6.asn);
76 77234bbb Ondrej Zajicek (work)
  case NET_FLOW4:
77
    return flow4_net_format(buf, buflen, &n->flow4);
78
  case NET_FLOW6:
79
    return flow6_net_format(buf, buflen, &n->flow6);
80 33ad6e01 Jan Moskyto Matejka
  case NET_MPLS:
81
    return bsnprintf(buf, buflen, "%u", n->mpls.label);
82 fe9f1a6d Ondrej Zajicek (work)
  }
83 9b136840 Jan Moskyto Matejka
84
  return 0;
85
}
86
87
ip_addr
88
net_pxmask(const net_addr *a)
89
{
90
  switch (a->type)
91
  {
92
  case NET_IP4:
93
  case NET_VPN4:
94 de9b87f5 Pavel Tvrdík
  case NET_ROA4:
95 77234bbb Ondrej Zajicek (work)
  case NET_FLOW4:
96 9b136840 Jan Moskyto Matejka
    return ipa_from_ip4(ip4_mkmask(net4_pxlen(a)));
97
98
  case NET_IP6:
99
  case NET_VPN6:
100 de9b87f5 Pavel Tvrdík
  case NET_ROA6:
101 77234bbb Ondrej Zajicek (work)
  case NET_FLOW6:
102 9b136840 Jan Moskyto Matejka
    return ipa_from_ip6(ip6_mkmask(net6_pxlen(a)));
103
104 33ad6e01 Jan Moskyto Matejka
  case NET_MPLS:
105 9b136840 Jan Moskyto Matejka
  default:
106
    return IPA_NONE;
107
  }
108
}
109
110 5e173e9f Jan Moskyto Matejka
int
111
net_compare(const net_addr *a, const net_addr *b)
112 9b136840 Jan Moskyto Matejka
{
113 5e173e9f Jan Moskyto Matejka
  if (a->type != b->type)
114
    return uint_cmp(a->type, b->type);
115 9b136840 Jan Moskyto Matejka
116 5e173e9f Jan Moskyto Matejka
  switch (a->type)
117
  {
118
  case NET_IP4:
119
    return net_compare_ip4((const net_addr_ip4 *) a, (const net_addr_ip4 *) b);
120
  case NET_IP6:
121
    return net_compare_ip6((const net_addr_ip6 *) a, (const net_addr_ip6 *) b);
122
  case NET_VPN4:
123
    return net_compare_vpn4((const net_addr_vpn4 *) a, (const net_addr_vpn4 *) b);
124
  case NET_VPN6:
125
    return net_compare_vpn6((const net_addr_vpn6 *) a, (const net_addr_vpn6 *) b);
126 de9b87f5 Pavel Tvrdík
  case NET_ROA4:
127
    return net_compare_roa4((const net_addr_roa4 *) a, (const net_addr_roa4 *) b);
128
  case NET_ROA6:
129
    return net_compare_roa6((const net_addr_roa6 *) a, (const net_addr_roa6 *) b);
130 77234bbb Ondrej Zajicek (work)
  case NET_FLOW4:
131
    return net_compare_flow4((const net_addr_flow4 *) a, (const net_addr_flow4 *) b);
132
  case NET_FLOW6:
133
    return net_compare_flow6((const net_addr_flow6 *) a, (const net_addr_flow6 *) b);
134 33ad6e01 Jan Moskyto Matejka
  case NET_MPLS:
135
    return net_compare_mpls((const net_addr_mpls *) a, (const net_addr_mpls *) b);
136 5e173e9f Jan Moskyto Matejka
  }
137
  return 0;
138 9b136840 Jan Moskyto Matejka
}
139
140 d15b0b0a Ondrej Zajicek (work)
#define NET_HASH(a,t) net_hash_##t((const net_addr_##t *) a)
141
142
u32
143
net_hash(const net_addr *n)
144
{
145
  switch (n->type)
146
  {
147
  case NET_IP4: return NET_HASH(n, ip4);
148
  case NET_IP6: return NET_HASH(n, ip6);
149
  case NET_VPN4: return NET_HASH(n, vpn4);
150
  case NET_VPN6: return NET_HASH(n, vpn6);
151
  case NET_ROA4: return NET_HASH(n, roa4);
152
  case NET_ROA6: return NET_HASH(n, roa6);
153 77234bbb Ondrej Zajicek (work)
  case NET_FLOW4: return NET_HASH(n, flow4);
154
  case NET_FLOW6: return NET_HASH(n, flow6);
155 d15b0b0a Ondrej Zajicek (work)
  default: bug("invalid type");
156
  }
157
}
158
159
160 9b136840 Jan Moskyto Matejka
int
161
net_validate(const net_addr *N)
162
{
163 5e173e9f Jan Moskyto Matejka
  switch (N->type)
164 9b136840 Jan Moskyto Matejka
  {
165
  case NET_IP4:
166
  case NET_VPN4:
167 de9b87f5 Pavel Tvrdík
  case NET_ROA4:
168 77234bbb Ondrej Zajicek (work)
  case NET_FLOW4:
169 9b136840 Jan Moskyto Matejka
    return net_validate_ip4((net_addr_ip4 *) N);
170
171
  case NET_IP6:
172
  case NET_VPN6:
173 de9b87f5 Pavel Tvrdík
  case NET_ROA6:
174 77234bbb Ondrej Zajicek (work)
  case NET_FLOW6:
175 9b136840 Jan Moskyto Matejka
    return net_validate_ip6((net_addr_ip6 *) N);
176
177 33ad6e01 Jan Moskyto Matejka
  case NET_MPLS:
178
    return net_validate_mpls((net_addr_mpls *) N);
179
180 9b136840 Jan Moskyto Matejka
  default:
181
    return 0;
182
  }
183 fe9f1a6d Ondrej Zajicek (work)
}
184
185 aedd3a6b Jan Moskyto Matejka
void
186
net_normalize(net_addr *N)
187
{
188
  net_addr_union *n = (void *) N;
189
190
  switch (n->n.type)
191
  {
192
  case NET_IP4:
193
  case NET_VPN4:
194 de9b87f5 Pavel Tvrdík
  case NET_ROA4:
195 77234bbb Ondrej Zajicek (work)
  case NET_FLOW4:
196 aedd3a6b Jan Moskyto Matejka
    return net_normalize_ip4(&n->ip4);
197
198
  case NET_IP6:
199
  case NET_VPN6:
200 de9b87f5 Pavel Tvrdík
  case NET_ROA6:
201 77234bbb Ondrej Zajicek (work)
  case NET_FLOW6:
202 aedd3a6b Jan Moskyto Matejka
    return net_normalize_ip6(&n->ip6);
203 33ad6e01 Jan Moskyto Matejka
204
  case NET_MPLS:
205
    return;
206 aedd3a6b Jan Moskyto Matejka
  }
207
}
208
209 fe9f1a6d Ondrej Zajicek (work)
int
210
net_classify(const net_addr *N)
211
{
212
  net_addr_union *n = (void *) N;
213
214
  switch (n->n.type)
215
  {
216
  case NET_IP4:
217
  case NET_VPN4:
218 de9b87f5 Pavel Tvrdík
  case NET_ROA4:
219 77234bbb Ondrej Zajicek (work)
  case NET_FLOW4:
220 fe9f1a6d Ondrej Zajicek (work)
    return ip4_zero(n->ip4.prefix) ? (IADDR_HOST | SCOPE_UNIVERSE) : ip4_classify(n->ip4.prefix);
221
222
  case NET_IP6:
223
  case NET_VPN6:
224 de9b87f5 Pavel Tvrdík
  case NET_ROA6:
225 77234bbb Ondrej Zajicek (work)
  case NET_FLOW6:
226 9b136840 Jan Moskyto Matejka
    return ip6_zero(n->ip6.prefix) ? (IADDR_HOST | SCOPE_UNIVERSE) : ip6_classify(&n->ip6.prefix);
227 33ad6e01 Jan Moskyto Matejka
228 d14f8c3c Jan Moskyto Matejka
  case NET_MPLS:
229
    return IADDR_HOST | SCOPE_UNIVERSE;
230 fe9f1a6d Ondrej Zajicek (work)
  }
231 9b136840 Jan Moskyto Matejka
232 0bf95f99 Ondrej Zajicek (work)
  return IADDR_INVALID;
233 fe9f1a6d Ondrej Zajicek (work)
}
234 aedd3a6b Jan Moskyto Matejka
235
int
236 0bf95f99 Ondrej Zajicek (work)
ipa_in_netX(const ip_addr a, const net_addr *n)
237 aedd3a6b Jan Moskyto Matejka
{
238 0bf95f99 Ondrej Zajicek (work)
  switch (n->type)
239 aedd3a6b Jan Moskyto Matejka
  {
240
  case NET_IP4:
241
  case NET_VPN4:
242 de9b87f5 Pavel Tvrdík
  case NET_ROA4:
243 77234bbb Ondrej Zajicek (work)
  case NET_FLOW4:
244 0bf95f99 Ondrej Zajicek (work)
    if (!ipa_is_ip4(a)) return 0;
245
    return ip4_zero(ip4_and(ip4_xor(ipa_to_ip4(a), net4_prefix(n)),
246
                            ip4_mkmask(net4_pxlen(n))));
247 aedd3a6b Jan Moskyto Matejka
248
  case NET_IP6:
249
  case NET_VPN6:
250 de9b87f5 Pavel Tvrdík
  case NET_ROA6:
251 77234bbb Ondrej Zajicek (work)
  case NET_FLOW6:
252 0bf95f99 Ondrej Zajicek (work)
    if (ipa_is_ip4(a)) return 0;
253
    return ip6_zero(ip6_and(ip6_xor(ipa_to_ip6(a), net6_prefix(n)),
254
                            ip6_mkmask(net6_pxlen(n))));
255 aedd3a6b Jan Moskyto Matejka
256 33ad6e01 Jan Moskyto Matejka
  case NET_MPLS:
257 0bf95f99 Ondrej Zajicek (work)
  default:
258
    return 0;
259
  }
260 aedd3a6b Jan Moskyto Matejka
}
261
262
int
263 0bf95f99 Ondrej Zajicek (work)
net_in_netX(const net_addr *a, const net_addr *n)
264 aedd3a6b Jan Moskyto Matejka
{
265 0bf95f99 Ondrej Zajicek (work)
  if (a->type != n->type)
266 aedd3a6b Jan Moskyto Matejka
    return 0;
267
268 0bf95f99 Ondrej Zajicek (work)
  return (net_pxlen(n) <= net_pxlen(a)) && ipa_in_netX(net_prefix(a), n);
269 aedd3a6b Jan Moskyto Matejka
}