Statistics
| Branch: | Revision:

iof-bird / bird-2.0.1 / lib / net.c @ 6b3f1a54

History | View | Annotate | Download (7.92 KB)

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_MPLS]        = "mpls",
18
};
19

    
20
const u16 net_addr_length[] = {
21
  [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
  [NET_FLOW6]         = 0,
29
  [NET_MPLS]        = sizeof(net_addr_mpls),
30
};
31

    
32
const u8 net_max_prefix_length[] = {
33
  [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
  [NET_FLOW6]         = IP6_MAX_PREFIX_LENGTH,
41
  [NET_MPLS]        = 0,
42
};
43

    
44
const u16 net_max_text_length[] = {
45
  [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
  [NET_FLOW6]         = 0,        /* "flow6 { ... }" */
53
  [NET_MPLS]        = 7,        /* "1048575" */
54
};
55

    
56

    
57
int
58
rd_format(const u64 rd, char *buf, int buflen)
59
{
60
  switch (rd >> 48)
61
  {
62
    case 0: return bsnprintf(buf, buflen, "%u:%u", (u32) (rd >> 32), (u32) rd);
63
    case 1: return bsnprintf(buf, buflen, "%I4:%u", ip4_from_u32(rd >> 16), (u32) (rd & 0xffff));
64
    case 2: if (((u32) (rd >> 16)) >> 16)
65
              return bsnprintf(buf, buflen, "%u:%u", (u32) (rd >> 16), (u32) (rd & 0xffff));
66
            else
67
              return bsnprintf(buf, buflen, "2:%u:%u", (u32) (rd >> 16), (u32) (rd & 0xffff));
68
    default: return bsnprintf(buf, buflen, "X:%08x:%08x", (u32) (rd >> 32), (u32) rd);
69
  }
70
}
71

    
72
int
73
net_format(const net_addr *N, char *buf, int buflen)
74
{
75
  net_addr_union *n = (void *) N;
76
  buf[0] = 0;
77

    
78
  switch (n->n.type)
79
  {
80
  case NET_IP4:
81
    return bsnprintf(buf, buflen, "%I4/%d", n->ip4.prefix, n->ip4.pxlen);
82
  case NET_IP6:
83
    return bsnprintf(buf, buflen, "%I6/%d", n->ip6.prefix, n->ip6.pxlen);
84
  case NET_VPN4:
85
    {
86
    int c = rd_format(n->vpn4.rd, buf, buflen);
87
    ADVANCE(buf, buflen, c);
88
    return bsnprintf(buf, buflen, " %I4/%d", n->vpn4.prefix, n->vpn4.pxlen);
89
    }
90
  case NET_VPN6:
91
    {
92
    /* XXX: RD format is specified for VPN4; not found any for VPN6, reusing the same as for VPN4 */
93
    int c = rd_format(n->vpn6.rd, buf, buflen);
94
    ADVANCE(buf, buflen, c);
95
    return bsnprintf(buf, buflen, " %I6/%d", n->vpn6.prefix, n->vpn6.pxlen);
96
    }
97
  case NET_ROA4:
98
    return bsnprintf(buf, buflen, "%I4/%u-%u AS%u",  n->roa4.prefix, n->roa4.pxlen, n->roa4.max_pxlen, n->roa4.asn);
99
  case NET_ROA6:
100
    return bsnprintf(buf, buflen, "%I6/%u-%u AS%u",  n->roa6.prefix, n->roa6.pxlen, n->roa6.max_pxlen, n->roa6.asn);
101
  case NET_FLOW4:
102
    return flow4_net_format(buf, buflen, &n->flow4);
103
  case NET_FLOW6:
104
    return flow6_net_format(buf, buflen, &n->flow6);
105
  case NET_MPLS:
106
    return bsnprintf(buf, buflen, "%u", n->mpls.label);
107
  }
108

    
109
  bug("unknown network type");
110
}
111

    
112
ip_addr
113
net_pxmask(const net_addr *a)
114
{
115
  switch (a->type)
116
  {
117
  case NET_IP4:
118
  case NET_VPN4:
119
  case NET_ROA4:
120
  case NET_FLOW4:
121
    return ipa_from_ip4(ip4_mkmask(net4_pxlen(a)));
122

    
123
  case NET_IP6:
124
  case NET_VPN6:
125
  case NET_ROA6:
126
  case NET_FLOW6:
127
    return ipa_from_ip6(ip6_mkmask(net6_pxlen(a)));
128

    
129
  case NET_MPLS:
130
  default:
131
    return IPA_NONE;
132
  }
133
}
134

    
135
int
136
net_compare(const net_addr *a, const net_addr *b)
137
{
138
  if (a->type != b->type)
139
    return uint_cmp(a->type, b->type);
140

    
141
  switch (a->type)
142
  {
143
  case NET_IP4:
144
    return net_compare_ip4((const net_addr_ip4 *) a, (const net_addr_ip4 *) b);
145
  case NET_IP6:
146
    return net_compare_ip6((const net_addr_ip6 *) a, (const net_addr_ip6 *) b);
147
  case NET_VPN4:
148
    return net_compare_vpn4((const net_addr_vpn4 *) a, (const net_addr_vpn4 *) b);
149
  case NET_VPN6:
150
    return net_compare_vpn6((const net_addr_vpn6 *) a, (const net_addr_vpn6 *) b);
151
  case NET_ROA4:
152
    return net_compare_roa4((const net_addr_roa4 *) a, (const net_addr_roa4 *) b);
153
  case NET_ROA6:
154
    return net_compare_roa6((const net_addr_roa6 *) a, (const net_addr_roa6 *) b);
155
  case NET_FLOW4:
156
    return net_compare_flow4((const net_addr_flow4 *) a, (const net_addr_flow4 *) b);
157
  case NET_FLOW6:
158
    return net_compare_flow6((const net_addr_flow6 *) a, (const net_addr_flow6 *) b);
159
  case NET_MPLS:
160
    return net_compare_mpls((const net_addr_mpls *) a, (const net_addr_mpls *) b);
161
  }
162
  return 0;
163
}
164

    
165
#define NET_HASH(a,t) net_hash_##t((const net_addr_##t *) a)
166

    
167
u32
168
net_hash(const net_addr *n)
169
{
170
  switch (n->type)
171
  {
172
  case NET_IP4: return NET_HASH(n, ip4);
173
  case NET_IP6: return NET_HASH(n, ip6);
174
  case NET_VPN4: return NET_HASH(n, vpn4);
175
  case NET_VPN6: return NET_HASH(n, vpn6);
176
  case NET_ROA4: return NET_HASH(n, roa4);
177
  case NET_ROA6: return NET_HASH(n, roa6);
178
  case NET_FLOW4: return NET_HASH(n, flow4);
179
  case NET_FLOW6: return NET_HASH(n, flow6);
180
  case NET_MPLS: return NET_HASH(n, mpls);
181
  default: bug("invalid type");
182
  }
183
}
184

    
185

    
186
#define NET_VALIDATE(a,t) net_validate_##t((const net_addr_##t *) a)
187

    
188
int
189
net_validate(const net_addr *n)
190
{
191
  switch (n->type)
192
  {
193
  case NET_IP4: return NET_VALIDATE(n, ip4);
194
  case NET_IP6: return NET_VALIDATE(n, ip6);
195
  case NET_VPN4: return NET_VALIDATE(n, vpn4);
196
  case NET_VPN6: return NET_VALIDATE(n, vpn6);
197
  case NET_ROA4: return NET_VALIDATE(n, roa4);
198
  case NET_ROA6: return NET_VALIDATE(n, roa6);
199
  case NET_FLOW4: return NET_VALIDATE(n, flow4);
200
  case NET_FLOW6: return NET_VALIDATE(n, flow6);
201
  case NET_MPLS: return NET_VALIDATE(n, mpls);
202
  default: return 0;
203
  }
204
}
205

    
206
void
207
net_normalize(net_addr *N)
208
{
209
  net_addr_union *n = (void *) N;
210

    
211
  switch (n->n.type)
212
  {
213
  case NET_IP4:
214
  case NET_VPN4:
215
  case NET_ROA4:
216
  case NET_FLOW4:
217
    return net_normalize_ip4(&n->ip4);
218

    
219
  case NET_IP6:
220
  case NET_VPN6:
221
  case NET_ROA6:
222
  case NET_FLOW6:
223
    return net_normalize_ip6(&n->ip6);
224

    
225
  case NET_MPLS:
226
    return;
227
  }
228
}
229

    
230
int
231
net_classify(const net_addr *N)
232
{
233
  net_addr_union *n = (void *) N;
234

    
235
  switch (n->n.type)
236
  {
237
  case NET_IP4:
238
  case NET_VPN4:
239
  case NET_ROA4:
240
  case NET_FLOW4:
241
    return ip4_zero(n->ip4.prefix) ? (IADDR_HOST | SCOPE_UNIVERSE) : ip4_classify(n->ip4.prefix);
242

    
243
  case NET_IP6:
244
  case NET_VPN6:
245
  case NET_ROA6:
246
  case NET_FLOW6:
247
    return ip6_zero(n->ip6.prefix) ? (IADDR_HOST | SCOPE_UNIVERSE) : ip6_classify(&n->ip6.prefix);
248

    
249
  case NET_MPLS:
250
    return IADDR_HOST | SCOPE_UNIVERSE;
251
  }
252

    
253
  return IADDR_INVALID;
254
}
255

    
256
int
257
ipa_in_netX(const ip_addr a, const net_addr *n)
258
{
259
  switch (n->type)
260
  {
261
  case NET_IP4:
262
  case NET_VPN4:
263
  case NET_ROA4:
264
  case NET_FLOW4:
265
    if (!ipa_is_ip4(a)) return 0;
266
    return ip4_zero(ip4_and(ip4_xor(ipa_to_ip4(a), net4_prefix(n)),
267
                            ip4_mkmask(net4_pxlen(n))));
268

    
269
  case NET_IP6:
270
  case NET_VPN6:
271
  case NET_ROA6:
272
  case NET_FLOW6:
273
    if (ipa_is_ip4(a)) return 0;
274
    return ip6_zero(ip6_and(ip6_xor(ipa_to_ip6(a), net6_prefix(n)),
275
                            ip6_mkmask(net6_pxlen(n))));
276

    
277
  case NET_MPLS:
278
  default:
279
    return 0;
280
  }
281
}
282

    
283
int
284
net_in_netX(const net_addr *a, const net_addr *n)
285
{
286
  if (a->type != n->type)
287
    return 0;
288

    
289
  return (net_pxlen(n) <= net_pxlen(a)) && ipa_in_netX(net_prefix(a), n);
290
}
291

    
292
#define CHECK_NET(T,S) \
293
  ({ if (sizeof(T) != S) die("sizeof %s is %d/%d", #T, (int) sizeof(T), S); })
294

    
295
void
296
net_init(void)
297
{
298
  CHECK_NET(net_addr,                24);
299
  CHECK_NET(net_addr_ip4,         8);
300
  CHECK_NET(net_addr_ip6,        20);
301
  CHECK_NET(net_addr_vpn4,        16);
302
  CHECK_NET(net_addr_vpn6,        32);
303
  CHECK_NET(net_addr_roa4,        16);
304
  CHECK_NET(net_addr_roa6,        28);
305
  CHECK_NET(net_addr_flow4,         8);
306
  CHECK_NET(net_addr_flow6,        20);
307
  CHECK_NET(net_addr_mpls,         8);
308
}