Statistics
| Branch: | Revision:

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

History | View | Annotate | Download (6.49 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
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
    return bsnprintf(buf, buflen, "%I4/%d", n->ip4.prefix, n->ip4.pxlen);
66
  case NET_IP6:
67
    return bsnprintf(buf, buflen, "%I6/%d", n->ip6.prefix, n->ip6.pxlen);
68
  case NET_VPN4:
69
    return bsnprintf(buf, buflen, "%u:%u %I4/%d", (u32) (n->vpn4.rd >> 32), (u32) n->vpn4.rd, n->vpn4.prefix, n->vpn4.pxlen);
70
  case NET_VPN6:
71
    return bsnprintf(buf, buflen, "%u:%u %I6/%d", (u32) (n->vpn6.rd >> 32), (u32) n->vpn6.rd, n->vpn6.prefix, n->vpn6.pxlen);
72
  case NET_ROA4:
73
    return bsnprintf(buf, buflen, "%I4/%u-%u AS%u",  n->roa4.prefix, n->roa4.pxlen, n->roa4.max_pxlen, n->roa4.asn);
74
  case NET_ROA6:
75
    return bsnprintf(buf, buflen, "%I6/%u-%u AS%u",  n->roa6.prefix, n->roa6.pxlen, n->roa6.max_pxlen, n->roa6.asn);
76
  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
  case NET_MPLS:
81
    return bsnprintf(buf, buflen, "%u", n->mpls.label);
82
  }
83

    
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
  case NET_ROA4:
95
  case NET_FLOW4:
96
    return ipa_from_ip4(ip4_mkmask(net4_pxlen(a)));
97

    
98
  case NET_IP6:
99
  case NET_VPN6:
100
  case NET_ROA6:
101
  case NET_FLOW6:
102
    return ipa_from_ip6(ip6_mkmask(net6_pxlen(a)));
103

    
104
  case NET_MPLS:
105
  default:
106
    return IPA_NONE;
107
  }
108
}
109

    
110
int
111
net_compare(const net_addr *a, const net_addr *b)
112
{
113
  if (a->type != b->type)
114
    return uint_cmp(a->type, b->type);
115

    
116
  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
  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
  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
  case NET_MPLS:
135
    return net_compare_mpls((const net_addr_mpls *) a, (const net_addr_mpls *) b);
136
  }
137
  return 0;
138
}
139

    
140
#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
  case NET_FLOW4: return NET_HASH(n, flow4);
154
  case NET_FLOW6: return NET_HASH(n, flow6);
155
  default: bug("invalid type");
156
  }
157
}
158

    
159

    
160
int
161
net_validate(const net_addr *N)
162
{
163
  switch (N->type)
164
  {
165
  case NET_IP4:
166
  case NET_VPN4:
167
  case NET_ROA4:
168
  case NET_FLOW4:
169
    return net_validate_ip4((net_addr_ip4 *) N);
170

    
171
  case NET_IP6:
172
  case NET_VPN6:
173
  case NET_ROA6:
174
  case NET_FLOW6:
175
    return net_validate_ip6((net_addr_ip6 *) N);
176

    
177
  case NET_MPLS:
178
    return net_validate_mpls((net_addr_mpls *) N);
179

    
180
  default:
181
    return 0;
182
  }
183
}
184

    
185
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
  case NET_ROA4:
195
  case NET_FLOW4:
196
    return net_normalize_ip4(&n->ip4);
197

    
198
  case NET_IP6:
199
  case NET_VPN6:
200
  case NET_ROA6:
201
  case NET_FLOW6:
202
    return net_normalize_ip6(&n->ip6);
203

    
204
  case NET_MPLS:
205
    return;
206
  }
207
}
208

    
209
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
  case NET_ROA4:
219
  case NET_FLOW4:
220
    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
  case NET_ROA6:
225
  case NET_FLOW6:
226
    return ip6_zero(n->ip6.prefix) ? (IADDR_HOST | SCOPE_UNIVERSE) : ip6_classify(&n->ip6.prefix);
227

    
228
  case NET_MPLS:
229
    return IADDR_HOST | SCOPE_UNIVERSE;
230
  }
231

    
232
  return IADDR_INVALID;
233
}
234

    
235
int
236
ipa_in_netX(const ip_addr a, const net_addr *n)
237
{
238
  switch (n->type)
239
  {
240
  case NET_IP4:
241
  case NET_VPN4:
242
  case NET_ROA4:
243
  case NET_FLOW4:
244
    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

    
248
  case NET_IP6:
249
  case NET_VPN6:
250
  case NET_ROA6:
251
  case NET_FLOW6:
252
    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

    
256
  case NET_MPLS:
257
  default:
258
    return 0;
259
  }
260
}
261

    
262
int
263
net_in_netX(const net_addr *a, const net_addr *n)
264
{
265
  if (a->type != n->type)
266
    return 0;
267

    
268
  return (net_pxlen(n) <= net_pxlen(a)) && ipa_in_netX(net_prefix(a), n);
269
}