Revision fe9f1a6d

View differences:

conf/cf-lex.l
123 123
}
124 124

  
125 125
{DIGIT}+\.{DIGIT}+\.{DIGIT}+\.{DIGIT}+ {
126
  ip4_addr a;
127
  if (!ip4_pton(yytext, &a))
126
  if (!ip4_pton(yytext, &cf_lval.ip4))
128 127
    cf_error("Invalid IPv4 address %s", yytext);
129

  
130
#ifdef IPV6
131
  cf_lval.i32 = ip4_to_u32(a);
132
  return RTRID;
133
#else
134
  cf_lval.a = ipa_from_ip4(a);
135
  return IPA;
136
#endif
128
  return IP4;
137 129
}
138 130

  
139 131
({XIGIT}*::|({XIGIT}*:){3,})({XIGIT}*|{DIGIT}+\.{DIGIT}+\.{DIGIT}+\.{DIGIT}+) {
140
#ifdef IPV6
141
  if (ipa_pton(yytext, &cf_lval.a))
142
    return IPA;
143
  cf_error("Invalid IPv6 address %s", yytext);
144
#else
145
  cf_error("This is an IPv4 router, therefore IPv6 addresses are not supported");
146
#endif
132
  if (!ip6_pton(yytext, &cf_lval.ip6))
133
    cf_error("Invalid IPv6 address %s", yytext);
134
  return IP6;
147 135
}
148 136

  
149 137
0x{XIGIT}+ {
conf/conf.c
133 133
  protos_postconfig(c);
134 134
  if (EMPTY_LIST(c->protos))
135 135
    cf_error("No protocol is specified in the config file");
136
#ifdef IPV6
136
  /* XXXX */
137 137
  if (!c->router_id)
138
    cf_error("Router ID must be configured manually on IPv6 routers");
139
#endif
138
    cf_error("Router ID must be configured manually");
139

  
140 140
  return 1;
141 141
}
142 142

  
conf/confbase.Y
39 39
  int i;
40 40
  u32 i32;
41 41
  ip_addr a;
42
  ip4_addr ip4;
43
  ip6_addr ip6;
42 44
  struct symbol *s;
43 45
  char *t;
44 46
  struct rtable_config *r;
......
66 68
%token GEQ LEQ NEQ AND OR
67 69
%token PO PC
68 70
%token <i> NUM ENUM
69
%token <i32> RTRID
70
%token <a> IPA
71
%token <ip4> IP4
72
%token <ip6> IP6
71 73
%token <s> SYM
72 74
%token <t> TEXT
73 75
%type <iface> ipa_scope
......
75 77
%type <i> expr bool pxlen
76 78
%type <i32> expr_us
77 79
%type <time> datetime
78
%type <a> ipa
80
%type <a> ipa ipa_raw
79 81
%type <px> prefix prefix_or_ipa
80 82
%type <t> text
81 83
%type <t> text_or_none
84
%type <t> opttext
82 85

  
83 86
%nonassoc PREFIX_DUMMY
84 87
%left AND OR
......
148 151

  
149 152
/* Addresses, prefixes and netmasks */
150 153

  
154
ipa_raw:
155
   IP4 { $$ = ipa_from_ip4($1); }
156
 | IP6 { $$ = ipa_from_ip6($1); }
157
 ;
158

  
151 159
ipa:
152
   IPA
160
   ipa_raw
153 161
 | SYM {
154 162
     if ($1->class != (SYM_CONSTANT | T_IP)) cf_error("IP address expected");
155 163
     $$ = SYM_VAL($1).px.ip;
......
205 213
 |      { $$ = NULL; }
206 214
 ;
207 215

  
216
opttext:
217
    TEXT
218
 | /* empty */ { $$ = NULL; }
219
 ;
220

  
221

  
208 222
CF_CODE
209 223

  
210 224
CF_END
configure.in
205 205

  
206 206
AC_SUBST(iproutedir)
207 207

  
208
all_protocols="$proto_bfd bgp ospf pipe $proto_radv rip static"
208
all_protocols="$proto_bfd ospf pipe $proto_radv rip static"
209 209
all_protocols=`echo $all_protocols | sed 's/ /,/g'`
210 210

  
211 211
if test "$with_protocols" = all ; then
filter/config.Y
477 477
 * Complex types, their bison value is struct f_val
478 478
 */
479 479
fipa:
480
   IPA %prec PREFIX_DUMMY { $$.type = T_IP; $$.val.px.ip = $1; }
480
   ipa_raw %prec PREFIX_DUMMY { $$.type = T_IP; $$.val.px.ip = $1; }
481 481
 ;
482 482

  
483 483

  
......
491 491

  
492 492
set_atom:
493 493
   NUM   { $$.type = T_INT; $$.val.i = $1; }
494
 | RTRID { $$.type = T_QUAD; $$.val.i = $1; }
495 494
 | fipa  { $$ = $1; }
496 495
 | ENUM  { $$.type = pair_a($1); $$.val.i = pair_b($1); }
497 496
 | '(' term ')' {
......
508 507
switch_atom:
509 508
   NUM   { $$.type = T_INT; $$.val.i = $1; }
510 509
 | '(' term ')' { $$.type = T_INT; $$.val.i = f_eval_int($2); }
511
 | RTRID { $$.type = T_QUAD; $$.val.i = $1; }
512 510
 | fipa  { $$ = $1; }
513 511
 | ENUM  { $$.type = pair_a($1); $$.val.i = pair_b($1); }
514 512
 ;
......
575 573
 ;
576 574

  
577 575
fprefix_s:
578
   IPA '/' NUM %prec '/' {
576
   ipa_raw '/' NUM %prec '/' {
579 577
     if (($3 < 0) || ($3 > MAX_PREFIX_LENGTH) || !ip_is_prefix($1, $3)) cf_error("Invalid network prefix: %I/%d.", $1, $3);
580 578
     $$.type = T_PREFIX; $$.val.px.ip = $1; $$.val.px.len = $3;
581 579
   }
......
646 644
 | TEXT   { $$ = f_new_inst(); $$->code = 'c'; $$->aux = T_STRING; $$->a2.p = $1; }
647 645
 | fipa	   { NEW_F_VAL; $$ = f_new_inst(); $$->code = 'C'; $$->a1.p = val; *val = $1; }
648 646
 | fprefix_s {NEW_F_VAL; $$ = f_new_inst(); $$->code = 'C'; $$->a1.p = val; *val = $1; }
649
 | RTRID  { $$ = f_new_inst(); $$->code = 'c'; $$->aux = T_QUAD;  $$->a2.i = $1; }
650 647
 | '[' set_items ']' { DBG( "We've got a set here..." ); $$ = f_new_inst(); $$->code = 'c'; $$->aux = T_SET; $$->a2.p = build_tree($2); DBG( "ook\n" ); }
651 648
 | '[' fprefix_set ']' { $$ = f_new_inst(); $$->code = 'c'; $$->aux = T_PREFIX_SET;  $$->a2.p = $2; }
652 649
 | ENUM	  { $$ = f_new_inst(); $$->code = 'c'; $$->aux = $1 >> 16; $$->a2.i = $1 & 0xffff; }
filter/filter.c
792 792
      {
793 793
      case SA_FROM:	res.val.px.ip = rta->from; break;
794 794
      case SA_GW:	res.val.px.ip = rta->gw; break;
795
      case SA_NET:	res.val.px.ip = (*f_rte)->net->n.prefix;
796
			res.val.px.len = (*f_rte)->net->n.pxlen; break;
795
      case SA_NET:	res.val.px.ip = net_prefix((*f_rte)->net->n.addr);
796
			res.val.px.len = net_pxlen((*f_rte)->net->n.addr); break;
797 797
      case SA_PROTO:	res.val.s = rta->src->proto->name; break;
798 798
      case SA_SOURCE:	res.val.i = rta->source; break;
799 799
      case SA_SCOPE:	res.val.i = rta->scope; break;
......
1292 1292
    else
1293 1293
    {
1294 1294
      ACCESS_RTE;
1295
      v1.val.px.ip = (*f_rte)->net->n.prefix;
1296
      v1.val.px.len = (*f_rte)->net->n.pxlen;
1295
      v1.val.px.ip = net_prefix((*f_rte)->net->n.addr);
1296
      v1.val.px.len = net_pxlen((*f_rte)->net->n.addr);
1297 1297

  
1298 1298
      /* We ignore temporary attributes, probably not a problem here */
1299 1299
      /* 0x02 is a value of BA_AS_PATH, we don't want to include BGP headers */
lib/bitops.c
28 28
 *
29 29
 * This function checks whether the given integer @x represents
30 30
 * a valid bit mask (binary representation contains first ones, then
31
 * zeroes) and returns the number of ones or -1 if the mask is invalid.
31
 * zeroes) and returns the number of ones or 255 if the mask is invalid.
32 32
 */
33
int
33
uint
34 34
u32_masklen(u32 x)
35 35
{
36 36
  int l = 0;
37 37
  u32 n = ~x;
38 38

  
39
  if (n & (n+1)) return -1;
39
  if (n & (n+1)) return 255;
40 40
  if (x & 0x0000ffff) { x &= 0x0000ffff; l += 16; }
41 41
  if (x & 0x00ff00ff) { x &= 0x00ff00ff; l += 8; }
42 42
  if (x & 0x0f0f0f0f) { x &= 0x0f0f0f0f; l += 4; }
lib/bitops.h
19 19
 */
20 20

  
21 21
u32 u32_mkmask(uint n);
22
int u32_masklen(u32 x);
22
uint u32_masklen(u32 x);
23 23

  
24 24
u32 u32_log2(u32 v);
25 25

  
lib/ip.c
58 58
  return a;
59 59
}
60 60

  
61
int
61
uint
62 62
ip6_masklen(ip6_addr *a)
63 63
{
64 64
  int i, j, n;
......
72 72
      n += j;
73 73
      while (++i < 4)
74 74
	if (a->addr[i])
75
	  return -1;
75
	  return 255;
76 76
      break;
77 77
    }
78 78

  
lib/ip.h
30 30
#define IP4_NONE		_MI4(0)
31 31
#define IP6_NONE		_MI6(0,0,0,0)
32 32

  
33
#define IP4_MAX_PREFIX_LENGTH	32
34
#define IP6_MAX_PREFIX_LENGTH	128
35

  
33 36
#define IP4_MIN_MTU		576
34 37
#define IP6_MIN_MTU		1280
35 38

  
......
39 42
#define IP6_HEADER_LENGTH	40
40 43
#define UDP_HEADER_LENGTH	8
41 44

  
42

  
43 45
#ifdef IPV6
44 46
#define MAX_PREFIX_LENGTH 128
45 47
#define BITS_PER_IP_ADDRESS 128
46 48
#define STD_ADDRESS_P_LENGTH 39
47
#define SIZE_OF_IP_HEADER 40
48 49
#else
49 50
#define MAX_PREFIX_LENGTH 32
50 51
#define BITS_PER_IP_ADDRESS 32
51 52
#define STD_ADDRESS_P_LENGTH 15
52
#define SIZE_OF_IP_HEADER 24
53 53
#endif
54 54

  
55 55

  
......
319 319
static inline ip4_addr ip4_mkmask(uint n)
320 320
{ return _MI4(u32_mkmask(n)); }
321 321

  
322
static inline int ip4_masklen(ip4_addr a)
322
static inline uint ip4_masklen(ip4_addr a)
323 323
{ return u32_masklen(_I(a)); }
324 324

  
325 325
ip6_addr ip6_mkmask(uint n);
326
int ip6_masklen(ip6_addr *a);
326
uint ip6_masklen(ip6_addr *a);
327 327

  
328 328
/* ipX_pxlen() requires that x != y */
329 329
static inline uint ip4_pxlen(ip4_addr a, ip4_addr b)
......
345 345
static inline u32 ip6_getbit(ip6_addr a, uint pos)
346 346
{ return a.addr[pos / 32] & (0x80000000 >> (pos % 32)); }
347 347

  
348
static inline u32 ip4_setbit(ip4_addr *a, uint pos)
349
{ return _I(*a) |= (0x80000000 >> pos); }
350

  
351
static inline u32 ip6_setbit(ip6_addr *a, uint pos)
352
{ return a->addr[pos / 32] |= (0x80000000 >> (pos % 32)); }
353

  
354
static inline u32 ip4_clrbit(ip4_addr *a, uint pos)
355
{ return _I(*a) &= ~(0x80000000 >> pos); }
356

  
357
static inline u32 ip6_clrbit(ip6_addr *a, uint pos)
358
{ return a->addr[pos / 32] &= ~(0x80000000 >> (pos % 32)); }
359

  
348 360
static inline ip4_addr ip4_opposite_m1(ip4_addr a)
349 361
{ return _MI4(_I(a) ^ 1); }
350 362

  
......
364 376
#define ipa_masklen(x) ip6_masklen(&x)
365 377
#define ipa_pxlen(x,y) ip6_pxlen(x,y)
366 378
#define ipa_getbit(x,n) ip6_getbit(x,n)
379
#define ipa_setbit(x,n) ip6_setbit(x,n)
380
#define ipa_clrbit(x,n) ip6_clrbit(x,n)
367 381
#define ipa_opposite_m1(x) ip6_opposite_m1(x)
368 382
#define ipa_opposite_m2(x) ip6_opposite_m2(x)
369 383
#else
......
371 385
#define ipa_masklen(x) ip4_masklen(x)
372 386
#define ipa_pxlen(x,y) ip4_pxlen(x,y)
373 387
#define ipa_getbit(x,n) ip4_getbit(x,n)
388
#define ipa_setbit(x,n) ip4_setbit(x,n)
389
#define ipa_clrbit(x,n) ip4_clrbit(x,n)
374 390
#define ipa_opposite_m1(x) ip4_opposite_m1(x)
375 391
#define ipa_opposite_m2(x) ip4_opposite_m2(x)
376 392
#endif
lib/net.c
1

  
2
#include "nest/bird.h"
3
#include "lib/ip.h"
4
#include "lib/net.h"
5

  
6
const u16 net_addr_length[] = {
7
  [NET_IP4] = sizeof(net_addr_ip4),
8
  [NET_IP6] = sizeof(net_addr_ip6),
9
  [NET_VPN4] = sizeof(net_addr_vpn4),
10
  [NET_VPN6] = sizeof(net_addr_vpn6)
11
}
12

  
13
char *
14
net_format(const net_addr *N, char *buf, int buflen)
15
{
16
  net_addr_union *n = (void *) N;
17

  
18
  /* FIXME: quick hack */
19
  switch (n->n.type)
20
  {
21
  case NET_IP4:
22
    return bsnprintf(buf, buflen, "%I/%d", n->ip4.prefix, n->ip4.pxlen);
23
  case NET_IP6:
24
    return bsnprintf(buf, buflen, "%I/%d", n->ip6.prefix, n->ip6.pxlen);
25
  case NET_VPN4:
26
    return bsnprintf(buf, buflen, "%u:%u %I/%d", (u32) (n->vpn4.rd >> 32), (u32) n->vpn4.rd, n->vpn4.prefix, n->vpn4.pxlen);
27
  case NET_VPN6:
28
    return bsnprintf(buf, buflen, "%u:%u %I/%d", (u32) (n->vpn6.rd >> 32), (u32) n->vpn6.rd, n->vpn6.prefix, n->vpn6.pxlen);
29
  }
30
}
31

  
32
int
33
net_classify(const net_addr *N)
34
{
35
  net_addr_union *n = (void *) N;
36

  
37
  switch (n->n.type)
38
  {
39
  case NET_IP4:
40
  case NET_VPN4:
41
    return ip4_zero(n->ip4.prefix) ? (IADDR_HOST | SCOPE_UNIVERSE) : ip4_classify(n->ip4.prefix);
42

  
43
  case NET_IP6:
44
  case NET_VPN6:
45
    return ip6_zero(n->ip6.prefix) ? (IADDR_HOST | SCOPE_UNIVERSE) : ip6_classify(n->ip6.prefix);
46
  }
47
}
lib/net.h
1
/*
2
 *	BIRD Internet Routing Daemon -- Network addresses
3
 *
4
 *	(c) 2015 Ondrej Zajicek <santiago@crfreenet.org>
5
 *	(c) 2015 CZ.NIC z.s.p.o.
6
 *
7
 *	Can be freely distributed and used under the terms of the GNU GPL.
8
 */
9

  
10
#ifndef _BIRD_NET_H_
11
#define _BIRD_NET_H_
12

  
13
#include "lib/ip.h"
14

  
15

  
16
#define NET_IP4		1
17
#define NET_IP6		2
18
#define NET_VPN4	3
19
#define NET_VPN6	4
20
#define NET_MAX		5
21

  
22

  
23
typedef struct net_addr {
24
  u8 type;
25
  u8 pxlen;
26
  u16 length;
27
  u64 align[0];
28
  u32 space[4];
29
} net_addr;
30

  
31
typedef struct net_addr_ip4 {
32
  u8 type;
33
  u8 pxlen;
34
  u16 length;
35
  ip4_addr prefix;
36
} net_addr_ip4;
37

  
38
typedef struct net_addr_ip6 {
39
  u8 type;
40
  u8 pxlen;
41
  u16 length;
42
  ip6_addr prefix;
43
} net_addr_ip6;
44

  
45
typedef struct net_addr_vpn4 {
46
  u8 type;
47
  u8 pxlen;
48
  u16 length;
49
  ip4_addr prefix;
50
  u64 rd;
51
} net_addr_vpn4;
52

  
53
typedef struct net_addr_vpn6 {
54
  u8 type;
55
  u8 pxlen;
56
  u16 length;
57
  ip6_addr prefix;
58
  u64 rd;
59
} net_addr_vpn6;
60

  
61

  
62
typedef union net_addr_union {
63
  net_addr n;
64
  net_addr_ip4 ip4;
65
  net_addr_ip6 ip6;
66
  net_addr_vpn4 vpn4;
67
  net_addr_vpn6 vpn6;
68
} net_addr_union;
69

  
70

  
71
extern const u16 net_addr_length[];
72

  
73

  
74
#define NET_ADDR_IP4(prefix,pxlen) \
75
  ((net_addr_ip4) { NET_IP4, pxlen, sizeof(net_addr_ip4), prefix })
76

  
77
#define NET_ADDR_IP6(prefix,pxlen) \
78
  ((net_addr_ip6) { NET_IP6, pxlen, sizeof(net_addr_ip6), prefix })
79

  
80
#define NET_ADDR_VPN4(prefix,pxlen,rd) \
81
  ((net_addr_vpn4) { NET_VPN4, pxlen, sizeof(net_addr_vpn4), prefix, rd })
82

  
83
#define NET_ADDR_VPN6(prefix,pxlen,rd) \
84
  ((net_addr_vpn6) { NET_VPN6, pxlen, sizeof(net_addr_vpn6), prefix, rd })
85

  
86

  
87
static inline void net_fill_ip4(net_addr *a, ip4_addr prefix, uint pxlen)
88
{ *(net_addr_ip4 *)a = NET_ADDR_IP4(prefix, pxlen); }
89

  
90
static inline void net_fill_ip6(net_addr *a, ip6_addr prefix, uint pxlen)
91
{ *(net_addr_ip6 *)a = NET_ADDR_IP6(prefix, pxlen); }
92

  
93
static inline void net_fill_vpn4(net_addr *a, ip4_addr prefix, uint pxlen, u64 rd)
94
{ *(net_addr_vpn4 *)a = NET_ADDR_VPN4(prefix, pxlen, rd); }
95

  
96
static inline void net_fill_vpn6(net_addr *a, ip6_addr prefix, uint pxlen, u64 rd)
97
{ *(net_addr_vpn6 *)a = NET_ADDR_VPN6(prefix, pxlen, rd); }
98

  
99
static inline void net_fill_ipa(net_addr *a, ip_addr prefix, uint pxlen)
100
{
101
  if (ipa_is_ip4(prefix))
102
    net_fill_ip4(a, ipa_to_ip4(prefix), pxlen);
103
  else
104
    net_fill_ip6(a, ipa_to_ip6(prefix), pxlen);
105
}
106

  
107
static inline ip4_addr net4_prefix(const net_addr *a)
108
{ return ((net_addr_ip4 *) a)->prefix; }
109

  
110
static inline ip6_addr net6_prefix(const net_addr *a)
111
{ return ((net_addr_ip6 *) a)->prefix; }
112

  
113
static inline ip_addr net_prefix(const net_addr *a)
114
{
115
  switch (a->type)
116
  {
117
  case NET_IP4:
118
  case NET_VPN4: return ipa_from_ip4(net4_prefix(a));
119
  case NET_IP6:
120
  case NET_VPN6: return ipa_from_ip6(net6_prefix(a));
121
  default: return IPA_NONE;
122
  }
123
}
124

  
125
static inline uint net4_pxlen(const net_addr *a)
126
{ return a->pxlen; }
127

  
128
static inline uint net6_pxlen(const net_addr *a)
129
{ return a->pxlen; }
130

  
131
static inline uint net_pxlen(const net_addr *a)
132
{ return a->pxlen; }
133

  
134

  
135
static inline int net_equal(const net_addr *a, const net_addr *b)
136
{ return (a->length == b->length) && !memcmp(a, b, a->length); }
137

  
138
static inline int net_equal_ip4(const net_addr_ip4 *a, const net_addr_ip4 *b)
139
{ return !memcmp(a, b, sizeof(net_addr_ip4)); }
140

  
141
static inline int net_equal_ip6(const net_addr_ip6 *a, const net_addr_ip6 *b)
142
{ return !memcmp(a, b, sizeof(net_addr_ip6)); }
143

  
144
static inline int net_equal_vpn4(const net_addr_vpn4 *a, const net_addr_vpn4 *b)
145
{ return !memcmp(a, b, sizeof(net_addr_vpn4)); }
146

  
147
static inline int net_equal_vpn6(const net_addr_vpn6 *a, const net_addr_vpn6 *b)
148
{ return !memcmp(a, b, sizeof(net_addr_vpn6)); }
149

  
150

  
151
static inline int net_zero_ip4(const net_addr_ip4 *a)
152
{ return !a->pxlen && ip4_zero(a->prefix); }
153

  
154
static inline int net_zero_ip6(const net_addr_ip6 *a)
155
{ return !a->pxlen && ip6_zero(a->prefix); }
156

  
157
static inline int net_zero_vpn4(const net_addr_vpn4 *a)
158
{ return !a->pxlen && ip4_zero(a->prefix) && !a->rd; }
159

  
160
static inline int net_zero_vpn6(const net_addr_vpn6 *a)
161
{ return !a->pxlen && ip6_zero(a->prefix) && !a->rd; }
162

  
163

  
164
static inline void net_copy(net_addr *dst, const net_addr *src)
165
{ memcpy(dst, src, src->length); }
166

  
167
static inline void net_copy_ip4(net_addr_ip4 *dst, const net_addr_ip4 *src)
168
{ memcpy(dst, src, sizeof(net_addr_ip4)); }
169

  
170
static inline void net_copy_ip6(net_addr_ip6 *dst, const net_addr_ip6 *src)
171
{ memcpy(dst, src, sizeof(net_addr_ip6)); }
172

  
173
static inline void net_copy_vpn4(net_addr_vpn4 *dst, const net_addr_vpn4 *src)
174
{ memcpy(dst, src, sizeof(net_addr_vpn4)); }
175

  
176
static inline void net_copy_vpn6(net_addr_vpn6 *dst, const net_addr_vpn6 *src)
177
{ memcpy(dst, src, sizeof(net_addr_vpn6)); }
178

  
179

  
180
static inline u32 net_hash_ip4(const net_addr_ip4 *n)
181
{ return ip4_hash(n->prefix) ^ ((u32) n->pxlen << 26); }
182

  
183
static inline u32 net_hash_ip6(const net_addr_ip6 *n)
184
{ return ip6_hash(n->prefix) ^ ((u32) n->pxlen << 26); }
185

  
186
/* XXXX */
187
static inline u32 u64_hash(u32 a)
188
{ return u32_hash(a); }
189

  
190
static inline u32 net_hash_vpn4(const net_addr_vpn4 *n)
191
{ return ip4_hash(n->prefix) ^ ((u32) n->pxlen << 26) ^ u64_hash(n->rd); }
192

  
193
static inline u32 net_hash_vpn6(const net_addr_vpn6 *n)
194
{ return ip6_hash(n->prefix) ^ ((u32) n->pxlen << 26) ^ u64_hash(n->rd); }
195

  
196

  
197
static inline void net_normalize_ip4(net_addr_ip4 *n)
198
{ n->prefix = ip4_and(n->prefix, ip4_mkmask(n->pxlen)); }
199

  
200
static inline void net_normalize_ip6(net_addr_ip6 *n)
201
{ n->prefix = ip6_and(n->prefix, ip6_mkmask(n->pxlen)); }
202

  
203
void net_normalize(net_addr *N);
204

  
205
int net_validate(const net_addr *N);
206
int net_classify(const net_addr *N);
207
char * net_format(const net_addr *N, char *buf, int buflen);
208

  
209

  
210

  
211
#endif
212

  
213

  
214

  
lib/printf.c
236 236
		case 'M':
237 237
			s = strerror(va_arg(args, int));
238 238
			goto str;
239
		case 'N':
240
			if (field_width == 1)
241
				field_width = STD_ADDRESS_P_LENGTH; /* XXXX */
242
			net_format(va_arg(args, net_addr *), ipbuf, sizeof(ipbuf));
243
			s = ipbuf;
244
			goto str;
239 245
		case 's':
240 246
			s = va_arg(args, char *);
241 247
			if (!s)
nest/Makefile
1
source=rt-table.c rt-fib.c rt-attr.c rt-roa.c proto.c iface.c rt-dev.c password.c cli.c locks.c cmds.c neighbor.c \
1
source=rt-table.c rt-fib.c rt-attr.c proto.c iface.c rt-dev.c password.c cli.c locks.c cmds.c neighbor.c \
2 2
	a-path.c a-set.c
3 3
root-rel=../
4 4
dir-name=nest
nest/bird.h
12 12
#include "sysdep/config.h"
13 13
#include "lib/birdlib.h"
14 14
#include "lib/ip.h"
15
#include "lib/net.h"
15 16

  
16 17
#endif
nest/config.Y
55 55

  
56 56
CF_KEYWORDS(ROUTER, ID, PROTOCOL, TEMPLATE, PREFERENCE, DISABLED, DEBUG, ALL, OFF, DIRECT)
57 57
CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, TABLE, STATES, ROUTES, FILTERS)
58
CF_KEYWORDS(IPV4, IPVX, VPN4, VPN6)
58 59
CF_KEYWORDS(RECEIVE, LIMIT, ACTION, WARN, BLOCK, RESTART, DISABLE, KEEP, FILTERED)
59 60
CF_KEYWORDS(PASSWORD, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, INTERFACES)
60 61
CF_KEYWORDS(PRIMARY, STATS, COUNT, FOR, COMMANDS, PREEXPORT, NOEXPORT, GENERATE, ROA)
......
77 78
%type <ro> roa_args
78 79
%type <rot> roa_table_arg
79 80
%type <sd> sym_args
80
%type <i> proto_start echo_mask echo_size debug_mask debug_list debug_flag mrtdump_mask mrtdump_list mrtdump_flag export_mode roa_mode limit_action tab_sorted tos
81
%type <i> proto_start echo_mask echo_size debug_mask debug_list debug_flag mrtdump_mask mrtdump_list mrtdump_flag export_mode roa_mode limit_action table_type table_sorted tos
81 82
%type <ps> proto_patt proto_patt2
82 83
%type <g> limit_spec
83 84

  
......
95 96
idval:
96 97
   NUM { $$ = $1; }
97 98
 | '(' term ')' { $$ = f_eval_int($2); }
98
 | RTRID
99
 | IPA {
100
#ifndef IPV6
101
     $$ = ipa_to_u32($1);
102
#else
103
     cf_error("Router IDs must be entered as hexadecimal numbers or IPv4 addresses in IPv6 version");
104
#endif
105
   }
99
 | IP4 { $$ = ip4_to_u32($1); }
106 100
 | SYM {
107 101
     if ($1->class == (SYM_CONSTANT | T_INT) || $1->class == (SYM_CONSTANT | T_QUAD))
108 102
       $$ = SYM_VAL($1).i;
......
140 134

  
141 135
/* Creation of routing tables */
142 136

  
143
tab_sorted:
137
CF_ADDTO(conf, table)
138

  
139
table_type:
140
   /* empty */ { $$ = NET_IP4; }
141
 | IPV4 { $$ = NET_IP4; }
142
 | IPVX { $$ = NET_IP6; } /* XXXX */
143
 | VPN4 { $$ = NET_VPN4; }
144
 | VPN6 { $$ = NET_VPN6; }
145
 ;
146

  
147
table_sorted:
144 148
          { $$ = 0; }
145 149
 | SORTED { $$ = 1; }
146 150
 ;
147 151

  
148
CF_ADDTO(conf, newtab)
149

  
150
newtab: TABLE SYM tab_sorted {
152
table: table_type TABLE SYM table_sorted {
151 153
   struct rtable_config *cf;
152
   cf = rt_new_table($2);
153
   cf->sorted = $3;
154
   cf = rt_new_table($3, $1);
155
   cf->sorted = $4;
154 156
   }
155 157
 ;
156 158

  
nest/route.h
35 35
struct fib_node {
36 36
  struct fib_node *next;		/* Next in hash chain */
37 37
  struct fib_iterator *readers;		/* List of readers of this node */
38
  byte pxlen;
39
  byte flags;				/* User-defined */
40
  byte x0, x1;				/* User-defined */
41
  u32 uid;				/* Unique ID based on hash */
42
  ip_addr prefix;			/* In host order */
38
  byte flags;				/* User-defined, will be removed */
39
  u32 uid;				/* Unique ID based on hash, will be removed */
40
  net_addr addr[0];
43 41
};
44 42

  
45 43
struct fib_iterator {			/* See lib/slists.h for an explanation */
......
50 48
  uint hash;
51 49
};
52 50

  
53
typedef void (*fib_init_func)(struct fib_node *);
51
typedef void (*fib_init_fn)(void *);
54 52

  
55 53
struct fib {
56 54
  pool *fib_pool;			/* Pool holding all our data */
......
59 57
  uint hash_size;			/* Number of hash table entries (a power of two) */
60 58
  uint hash_order;			/* Binary logarithm of hash_size */
61 59
  uint hash_shift;			/* 16 - hash_log */
60
  uint addr_type;			/* Type of address data stored in fib (NET_*) */
61
  uint node_size;	/* XXXX */
62
  uint node_offset;	/* XXXX */
62 63
  uint entries;				/* Number of entries */
63 64
  uint entries_min, entries_max;	/* Entry count limits (else start rehashing) */
64
  fib_init_func init;			/* Constructor */
65
  fib_init_fn init;			/* Constructor */
65 66
};
66 67

  
67
void fib_init(struct fib *, pool *, unsigned node_size, unsigned hash_order, fib_init_func init);
68
void *fib_find(struct fib *, ip_addr *, int);	/* Find or return NULL if doesn't exist */
69
void *fib_get(struct fib *, ip_addr *, int); 	/* Find or create new if nonexistent */
70
void *fib_route(struct fib *, ip_addr, int);	/* Longest-match routing lookup */
68
void fib_init(struct fib *f, pool *p, uint addr_type, uint node_size, uint node_offset, uint hash_order, fib_init_fn init);
69
void *fib_find(struct fib *, net_addr *);	/* Find or return NULL if doesn't exist */
70
void *fib_get(struct fib *, net_addr *); 	/* Find or create new if nonexistent */
71
void *fib_route(struct fib *, net_addr *);	/* Longest-match routing lookup */
71 72
void fib_delete(struct fib *, void *);	/* Remove fib entry */
72 73
void fib_free(struct fib *);		/* Destroy the fib */
73 74
void fib_check(struct fib *);		/* Consistency check for debugging */
......
77 78
void fit_put(struct fib_iterator *, struct fib_node *);
78 79
void fit_put_next(struct fib *f, struct fib_iterator *i, struct fib_node *n, uint hpos);
79 80

  
80

  
81
/* XXXX: return user entries */
81 82
#define FIB_WALK(fib, z) do {					\
82 83
	struct fib_node *z, **ff = (fib)->hash_table;		\
83 84
	uint count = (fib)->hash_size;				\
......
126 127
  char *name;
127 128
  struct rtable *table;
128 129
  struct proto_config *krt_attached;	/* Kernel syncer attached to this table */
130
  uint addr_type;			/* Type of address data stored in table (NET_*) */
129 131
  int gc_max_ops;			/* Maximum number of operations before GC is run */
130 132
  int gc_min_time;			/* Minimum time between two consecutive GC runs */
131 133
  byte sorted;				/* Routes of network are sorted according to rte_better() */
......
136 138
  struct fib fib;
137 139
  char *name;				/* Name of this table */
138 140
  list hooks;				/* List of announcement hooks */
141
  uint addr_type;			/* Type of address data stored in table (NET_*) */
139 142
  int pipe_busy;			/* Pipe loop detection */
140 143
  int use_count;			/* Number of protocols using this table */
141 144
  struct hostcache *hostcache;
......
160 163
#define RPS_RUNNING	2
161 164

  
162 165
typedef struct network {
163
  struct fib_node n;			/* FIB flags reserved for kernel syncer */
164 166
  struct rte *routes;			/* Available routes for this network */
167
  struct fib_node n;			/* FIB flags reserved for kernel syncer */
165 168
} net;
166 169

  
167 170
struct hostcache {
......
262 265
void rt_lock_table(rtable *);
263 266
void rt_unlock_table(rtable *);
264 267
void rt_setup(pool *, rtable *, char *, struct rtable_config *);
265
static inline net *net_find(rtable *tab, ip_addr addr, unsigned len) { return (net *) fib_find(&tab->fib, &addr, len); }
266
static inline net *net_get(rtable *tab, ip_addr addr, unsigned len) { return (net *) fib_get(&tab->fib, &addr, len); }
268
static inline net *net_find(rtable *tab, net_addr *addr) { return (net *) fib_find(&tab->fib, addr); }
269
static inline net *net_get(rtable *tab, net_addr *addr) { return (net *) fib_get(&tab->fib, addr); }
270

  
271
static inline net *net_find_ipa(rtable *tab, ip_addr px, uint pxlen)
272
{ net_addr addr; net_fill_ipa(&addr, px, pxlen); return (net *) fib_find(&tab->fib, &addr); }
273
static inline net *net_get_ipa(rtable *tab, ip_addr px, uint pxlen)
274
{ net_addr addr; net_fill_ipa(&addr, px, pxlen); return (net *) fib_get(&tab->fib, &addr); }
275

  
267 276
rte *rte_find(net *net, struct rte_src *src);
268 277
rte *rte_get_temp(struct rta *);
269 278
void rte_update2(struct announce_hook *ah, net *net, rte *new, struct rte_src *src);
270 279
static inline void rte_update(struct proto *p, net *net, rte *new) { rte_update2(p->main_ahook, net, new, p->main_source); }
271 280
void rte_discard(rtable *tab, rte *old);
272
int rt_examine(rtable *t, ip_addr prefix, int pxlen, struct proto *p, struct filter *filter);
281
int rt_examine(rtable *t, net_addr *a, struct proto *p, struct filter *filter);
273 282
rte *rt_export_merged(struct announce_hook *ah, net *net, rte **rt_free, struct ea_list **tmpa, int silent);
274 283
void rt_refresh_begin(rtable *t, struct announce_hook *ah);
275 284
void rt_refresh_end(rtable *t, struct announce_hook *ah);
......
283 292
int rt_feed_baby(struct proto *p);
284 293
void rt_feed_baby_abort(struct proto *p);
285 294
int rt_prune_loop(void);
286
struct rtable_config *rt_new_table(struct symbol *s);
295
struct rtable_config *rt_new_table(struct symbol *s, uint addr_type);
287 296

  
288 297
static inline void
289 298
rt_mark_for_prune(rtable *tab)
nest/rt-dev.c
45 45
      net *n;
46 46

  
47 47
      DBG("dev_if_notify: %s:%I going down\n", ad->iface->name, ad->ip);
48
      n = net_find(p->table, ad->prefix, ad->pxlen);
48
      n = net_find_ipa(p->table, ad->prefix, ad->pxlen);
49 49
      if (!n)
50 50
	{
51 51
	  DBG("dev_if_notify: device shutdown: prefix not found\n");
......
77 77
      };
78 78

  
79 79
      a = rta_lookup(&a0);
80
      n = net_get(p->table, ad->prefix, ad->pxlen);
80
      n = net_get_ipa(p->table, ad->prefix, ad->pxlen);
81 81
      e = rte_get_temp(a);
82 82
      e->net = n;
83 83
      e->pflags = 0;
nest/rt-fib.c
48 48
#define HASH_LO_STEP 2
49 49
#define HASH_LO_MIN 10
50 50

  
51

  
52
static inline void * fib_node_to_user(struct fib *f, struct fib_node *e)
53
{ return (void *) ((char *) e - f->node_offset); }
54

  
55
static inline struct fib_node * fib_user_to_node(struct fib *f, void *e)
56
{ return (void *) ((char *) e + f->node_offset); }
57

  
51 58
static void
52 59
fib_ht_alloc(struct fib *f)
53 60
{
......
72 79
  mb_free(h);
73 80
}
74 81

  
75
static inline unsigned
76
fib_hash(struct fib *f, ip_addr *a)
77
{
78
  return ipa_hash(*a) >> f->hash_shift;
79
}
80 82

  
81
static void
82
fib_dummy_init(struct fib_node *dummy UNUSED)
83
{
84
}
83
static u32
84
fib_hash(struct fib *f, net_addr *a);
85 85

  
86 86
/**
87 87
 * fib_init - initialize a new FIB
......
96 96
 * This function initializes a newly allocated FIB and prepares it for use.
97 97
 */
98 98
void
99
fib_init(struct fib *f, pool *p, unsigned node_size, unsigned hash_order, fib_init_func init)
99
fib_init(struct fib *f, pool *p, uint addr_type, uint node_size, uint node_offset, uint hash_order, fib_init_fn init)
100 100
{
101
  uint addr_length = net_addr_length[addr_type];
102

  
101 103
  if (!hash_order)
102 104
    hash_order = HASH_DEF_ORDER;
103 105
  f->fib_pool = p;
104
  f->fib_slab = sl_new(p, node_size);
106
  f->fib_slab = addr_length ? sl_new(p, node_size + addr_length) : NULL;
107
  f->addr_type = addr_type;
108
  f->node_size = node_size;
109
  f->node_offset = node_offset;
105 110
  f->hash_order = hash_order;
106 111
  fib_ht_alloc(f);
107 112
  bzero(f->hash_table, f->hash_size * sizeof(struct fib_node *));
108 113
  f->entries = 0;
109 114
  f->entries_min = 0;
110
  f->init = init ? : fib_dummy_init;
115
  f->init = init;
111 116
}
112 117

  
113 118
static void
......
133 138
      while (e = x)
134 139
	{
135 140
	  x = e->next;
136
	  nh = fib_hash(f, &e->prefix);
141
	  nh = fib_hash(f, e->addr);
137 142
	  while (nh > ni)
138 143
	    {
139 144
	      *t = NULL;
......
153 158
  fib_ht_free(m);
154 159
}
155 160

  
161
#define CAST(t) (net_addr_##t *)
162

  
163
#define FIB_HASH(f,a,t) (net_hash_##t(CAST(t) a) >> f->hash_shift)
164

  
165
#define FIB_FIND(f,a,t)							\
166
  ({									\
167
    struct fib_node *e = f->hash_table[FIB_HASH(f, a, t)];		\
168
    while (e && !net_equal_##t(CAST(t) e->addr, CAST(t) a))		\
169
      e = e->next;							\
170
    fib_node_to_user(f, e);						\
171
  })
172

  
173
#define FIB_INSERT(f,a,e,t)						\
174
  ({									\
175
  u32 h = net_hash_##t(CAST(t) a);					\
176
  struct fib_node **ee = f->hash_table + (h >> f->hash_shift);		\
177
  struct fib_node *g;							\
178
									\
179
  while ((g = *ee) && (net_hash_##t(CAST(t) g->addr) < h))		\
180
    ee = &g->next;							\
181
									\
182
  net_copy_##t(CAST(t) e->addr, CAST(t) a);				\
183
  e->next = *ee;							\
184
  *ee = e;								\
185
  })
186

  
187

  
188
static u32
189
fib_hash(struct fib *f, net_addr *a)
190
{
191
  switch (f->addr_type)
192
  {
193
  case NET_IP4: return FIB_HASH(f, a, ip4);
194
  case NET_IP6: return FIB_HASH(f, a, ip6);
195
  case NET_VPN4: return FIB_HASH(f, a, vpn4);
196
  case NET_VPN6: return FIB_HASH(f, a, vpn6);
197
  default: bug("invalid type");
198
  }
199
}
200

  
201
void *
202
fib_find(struct fib *f, net_addr *a)
203
{
204
  ASSERT(f->addr_type == a->type);
205

  
206
  switch (f->addr_type)
207
  {
208
  case NET_IP4: return FIB_FIND(f, a, ip4);
209
  case NET_IP6: return FIB_FIND(f, a, ip6);
210
  case NET_VPN4: return FIB_FIND(f, a, vpn4);
211
  case NET_VPN6: return FIB_FIND(f, a, vpn6);
212
  default: bug("invalid type");
213
  }
214
}
215

  
216
static void
217
fib_insert(struct fib *f, net_addr *a, struct fib_node *e)
218
{
219
  switch (f->addr_type)
220
  {
221
  case NET_IP4: FIB_INSERT(f, a, e, ip4); return;
222
  case NET_IP6: FIB_INSERT(f, a, e, ip6); return;
223
  case NET_VPN4: FIB_INSERT(f, a, e, vpn4); return;
224
  case NET_VPN6: FIB_INSERT(f, a, e, vpn6); return;
225
  default: bug("invalid type");
226
  }
227
}
228

  
229

  
230

  
156 231
/**
157 232
 * fib_find - search for FIB node by prefix
158 233
 * @f: FIB to search in
......
162 237
 * Search for a FIB node corresponding to the given prefix, return
163 238
 * a pointer to it or %NULL if no such node exists.
164 239
 */
240
/*
165 241
void *
166
fib_find(struct fib *f, ip_addr *a, int len)
242
fib_find(struct fib *f, net_addr *a)
167 243
{
168 244
  struct fib_node *e = f->hash_table[fib_hash(f, a)];
169 245

  
......
171 247
    e = e->next;
172 248
  return e;
173 249
}
174

  
175
/*
176
int
177
fib_histogram(struct fib *f)
178
{
179
  log(L_WARN "Histogram dump start %d %d", f->hash_size, f->entries);
180

  
181
  int i, j;
182
  struct fib_node *e;
183

  
184
  for (i = 0; i < f->hash_size; i++)
185
    {
186
      j = 0;
187
      for (e = f->hash_table[i]; e != NULL; e = e->next)
188
	j++;
189
      if (j > 0)
190
        log(L_WARN "Histogram line %d: %d", i, j);
191
    }
192

  
193
  log(L_WARN "Histogram dump end");
194
}
195 250
*/
196 251

  
197 252
/**
......
204 259
 * return a pointer to it. If no such node exists, create it.
205 260
 */
206 261
void *
207
fib_get(struct fib *f, ip_addr *a, int len)
262
fib_get(struct fib *f, net_addr *a)
208 263
{
209
  uint h = ipa_hash(*a);
210
  struct fib_node **ee = f->hash_table + (h >> f->hash_shift);
211
  struct fib_node *g, *e = *ee;
212
  u32 uid = h << 16;
213

  
214
  while (e && (e->pxlen != len || !ipa_equal(*a, e->prefix)))
215
    e = e->next;
216
  if (e)
217
    return e;
218
#ifdef DEBUGGING
219
  if (len < 0 || len > BITS_PER_IP_ADDRESS || !ip_is_prefix(*a,len))
220
    bug("fib_get() called for invalid address");
221
#endif
264
  char *b = fib_find(f, a);
265
  if (b)
266
    return b;
222 267

  
223
  while ((g = *ee) && g->uid < uid)
224
    ee = &g->next;
225
  while ((g = *ee) && g->uid == uid)
226
    {
227
      ee = &g->next;
228
      uid++;
229
    }
268
  if (f->fib_slab)
269
    b = sl_alloc(f->fib_slab);
270
  else
271
    b = mb_alloc(f->fib_pool, f->node_size + a->length);
230 272

  
231
  if ((uid >> 16) != h)
232
    log(L_ERR "FIB hash table chains are too long");
273
  struct fib_node *e = (void *) (b + f->node_offset);
274
  e->readers = NULL;
275
  e->flags = 0;
276
  e->uid = 0;
277
  fib_insert(f, a, e);
233 278

  
234
  // log (L_WARN "FIB_GET %I %x %x", *a, h, uid);
279
  memset(b, 0, f->node_offset);
280
  if (f->init)
281
    f->init(b);
235 282

  
236
  e = sl_alloc(f->fib_slab);
237
  e->prefix = *a;
238
  e->pxlen = len;
239
  e->next = *ee;
240
  e->uid = uid;
241
  *ee = e;
242
  e->readers = NULL;
243
  f->init(e);
244 283
  if (f->entries++ > f->entries_max)
245 284
    fib_rehash(f, HASH_HI_STEP);
246 285

  
247
  return e;
286
  return b;
248 287
}
249 288

  
250 289
/**
......
257 296
 * network, that is a node which a CIDR router would use for routing
258 297
 * that network.
259 298
 */
299
/*
260 300
void *
261 301
fib_route(struct fib *f, ip_addr a, int len)
262 302
{
......
273 313
    }
274 314
  return NULL;
275 315
}
316
*/
276 317

  
277 318
static inline void
278 319
fib_merge_readers(struct fib_iterator *i, struct fib_node *to)
......
320 361
void
321 362
fib_delete(struct fib *f, void *E)
322 363
{
323
  struct fib_node *e = E;
324
  uint h = fib_hash(f, &e->prefix);
364
  struct fib_node *e = fib_user_to_node(f, E);
365
  uint h = fib_hash(f, e->addr);
325 366
  struct fib_node **ee = f->hash_table + h;
326 367
  struct fib_iterator *it;
327 368

  
......
413 454
  if (k = i->next)
414 455
    k->prev = j;
415 456
  j->next = k;
416
  i->hash = fib_hash(f, &n->prefix);
457
  i->hash = fib_hash(f, n->addr);
417 458
  return n;
418 459
}
419 460

  
......
498 539
    bug("fib_check: invalid entry count (%d != %d)", ec, f->entries);
499 540
}
500 541

  
542
/*
543
int
544
fib_histogram(struct fib *f)
545
{
546
  log(L_WARN "Histogram dump start %d %d", f->hash_size, f->entries);
547

  
548
  int i, j;
549
  struct fib_node *e;
550

  
551
  for (i = 0; i < f->hash_size; i++)
552
    {
553
      j = 0;
554
      for (e = f->hash_table[i]; e != NULL; e = e->next)
555
	j++;
556
      if (j > 0)
557
        log(L_WARN "Histogram line %d: %d", i, j);
558
    }
559

  
560
  log(L_WARN "Histogram dump end");
561
}
562
*/
563

  
501 564
#endif
502 565

  
503 566
#ifdef TEST
......
517 580
      struct fib_iterator *j;
518 581
      for(n=f.hash_table[i]; n; n=n->next)
519 582
	{
520
	  debug("%04x %04x %p %I/%2d", i, ipa_hash(n->prefix), n, n->prefix, n->pxlen);
583
	  debug("%04x %08x %p %N", i, ipa_hash(n->prefix), n, n->addr);
521 584
	  for(j=n->readers; j; j=j->next)
522 585
	    debug(" %p[%p]", j, j->node);
523 586
	  debug("\n");
nest/rt-table.c
69 69
}
70 70

  
71 71
/* Like fib_route(), but skips empty net entries */
72
/*
72 73
static net *
73 74
net_route(rtable *tab, ip_addr a, int len)
74 75
{
......
85 86
    }
86 87
  return NULL;
87 88
}
88

  
89
static void
90
rte_init(struct fib_node *N)
91
{
92
  net *n = (net *) N;
93

  
94
  N->flags = 0;
95
  n->routes = NULL;
96
}
89
*/
97 90

  
98 91
/**
99 92
 * rte_find - find a route
......
230 223
  byte via[STD_ADDRESS_P_LENGTH+32];
231 224

  
232 225
  rt_format_via(e, via);
233
  log(L_TRACE "%s %c %s %I/%d %s", p->name, dir, msg, e->net->n.prefix, e->net->n.pxlen, via);
226
  log(L_TRACE "%s %c %s %N %s", p->name, dir, msg, e->net->n.addr, via);
234 227
}
235 228

  
236 229
static inline void
......
788 781
  int c;
789 782
  net *n = e->net;
790 783

  
791
  if ((n->n.pxlen > BITS_PER_IP_ADDRESS) || !ip_is_prefix(n->n.prefix,n->n.pxlen))
792
    {
793
      log(L_WARN "Ignoring bogus prefix %I/%d received via %s",
794
	  n->n.prefix, n->n.pxlen, e->sender->proto->name);
795
      return 0;
796
    }
784
  // (n->n.pxlen > BITS_PER_IP_ADDRESS) || !ip_is_prefix(n->n.prefix,n->n.pxlen))
785
  if (!net_validate(n->n.addr))
786
  {
787
    log(L_WARN "Ignoring bogus prefix %N received via %s",
788
	n->n.addr, e->sender->proto->name);
789
    return 0;
790
  }
797 791

  
798
  c = ipa_classify_net(n->n.prefix);
792
  c = net_classify(n->n.addr);
799 793
  if ((c < 0) || !(c & IADDR_HOST) || ((c & IADDR_SCOPE_MASK) <= SCOPE_LINK))
800
    {
801
      log(L_WARN "Ignoring bogus route %I/%d received via %s",
802
	  n->n.prefix, n->n.pxlen, e->sender->proto->name);
803
      return 0;
804
    }
794
  {
795
    log(L_WARN "Ignoring bogus route %N received via %s",
796
	n->n.addr, e->sender->proto->name);
797
    return 0;
798
  }
805 799

  
806 800
  return 1;
807 801
}
......
870 864
	    {
871 865
	      if (new)
872 866
		{
873
		  log_rl(&rl_pipe, L_ERR "Pipe collision detected when sending %I/%d to table %s",
874
		      net->n.prefix, net->n.pxlen, table->name);
867
		  log_rl(&rl_pipe, L_ERR "Pipe collision detected when sending %N to table %s",
868
		      net->n.addr, table->name);
875 869
		  rte_free_quick(new);
876 870
		}
877 871
	      return;
......
1278 1272

  
1279 1273
/* Check rtable for best route to given net whether it would be exported do p */
1280 1274
int
1281
rt_examine(rtable *t, ip_addr prefix, int pxlen, struct proto *p, struct filter *filter)
1275
rt_examine(rtable *t, net_addr *a, struct proto *p, struct filter *filter)
1282 1276
{
1283
  net *n = net_find(t, prefix, pxlen);
1277
  net *n = net_find(t, a);
1284 1278
  rte *rt = n ? n->routes : NULL;
1285 1279

  
1286 1280
  if (!rte_is_valid(rt))
......
1376 1370
rte_dump(rte *e)
1377 1371
{
1378 1372
  net *n = e->net;
1379
  debug("%-1I/%2d ", n->n.prefix, n->n.pxlen);
1373
  debug("%-1N ", n->n.addr);
1380 1374
  debug("KF=%02x PF=%02x pref=%d lm=%d ", n->n.flags, e->pflags, e->pref, now-e->lastmod);
1381 1375
  rta_dump(e->attrs);
1382 1376
  if (e->attrs->src->proto->proto->dump_attrs)
......
1527 1521
rt_setup(pool *p, rtable *t, char *name, struct rtable_config *cf)
1528 1522
{
1529 1523
  bzero(t, sizeof(*t));
1530
  fib_init(&t->fib, p, sizeof(net), 0, rte_init);
1531 1524
  t->name = name;
1532 1525
  t->config = cf;
1526
  t->addr_type = cf ? cf->addr_type : NET_IP4;
1527
  fib_init(&t->fib, p, t->addr_type, sizeof(net), OFFSETOF(net, n), 0, NULL);
1533 1528
  init_list(&t->hooks);
1534 1529
  if (cf)
1535 1530
    {
......
1660 1655
  struct symbol *s = cf_find_symbol("master");
1661 1656

  
1662 1657
  init_list(&c->tables);
1663
  c->master_rtc = rt_new_table(s);
1658
  c->master_rtc = rt_new_table(s, NET_IP4);
1664 1659
}
1665 1660

  
1666 1661

  
......
1817 1812

  
1818 1813

  
1819 1814
struct rtable_config *
1820
rt_new_table(struct symbol *s)
1815
rt_new_table(struct symbol *s, uint addr_type)
1821 1816
{
1822 1817
  /* Hack that allows to 'redefine' the master table */
1823 1818
  if ((s->class == SYM_TABLE) && (s->def == new_config->master_rtc))
......
1827 1822

  
1828 1823
  cf_define_symbol(s, SYM_TABLE, c);
1829 1824
  c->name = s->name;
1825
  c->addr_type = addr_type;
1830 1826
  add_tail(&new_config->tables, &c->n);
1831 1827
  c->gc_max_ops = 1000;
1832 1828
  c->gc_min_time = 5;
......
2196 2192
  if (tab->hcu_scheduled)
2197 2193
    return;
2198 2194

  
2199
  if (trie_match_prefix(hc->trie, net->n.prefix, net->n.pxlen))
2200
    rt_schedule_hcu(tab);
2195
  // XXXX
2196
  // if (trie_match_prefix(hc->trie, net->n.prefix, net->n.pxlen))
2197
  // rt_schedule_hcu(tab);
2201 2198
}
2202 2199

  
2203 2200
static int
......
2253 2250
  he->dest = RTD_UNREACHABLE;
2254 2251
  he->igp_metric = 0;
2255 2252

  
2256
  net *n = net_route(tab, he->addr, MAX_PREFIX_LENGTH);
2253
  // XXXX
2254
  // net *n = net_route(tab, he->addr, MAX_PREFIX_LENGTH);
2255
  net *n = NULL;
2257 2256
  if (n)
2258 2257
    {
2259 2258
      rte *e = n->routes;
2260 2259
      rta *a = e->attrs;
2261
      pxlen = n->n.pxlen;
2260
      pxlen = n->n.addr->pxlen;
2262 2261

  
2263 2262
      if (a->hostentry)
2264 2263
	{
2265 2264
	  /* Recursive route should not depend on another recursive route */
2266
	  log(L_WARN "Next hop address %I resolvable through recursive route for %I/%d",
2267
	      he->addr, n->n.prefix, pxlen);
2265
	  log(L_WARN "Next hop address %I resolvable through recursive route for %N",
2266
	      he->addr, n->n.addr);
2268 2267
	  goto done;
2269 2268
	}
2270 2269

  
......
2425 2424
  int first = 1;
2426 2425
  int pass = 0;
2427 2426

  
2428
  bsprintf(ia, "%I/%d", n->n.prefix, n->n.pxlen);
2427
  bsprintf(ia, "%N", n->n.addr);
2429 2428

  
2430 2429
  if (d->export_mode)
2431 2430
    {
......
2589 2588
    }
2590 2589
  else
2591 2590
    {
2591
      /* XXXX 
2592 2592
      if (d->show_for)
2593 2593
	n = net_route(d->table, d->prefix, d->pxlen);
2594 2594
      else
2595 2595
	n = net_find(d->table, d->prefix, d->pxlen);
2596
      */
2597
      n = NULL;
2596 2598

  
2597 2599
      if (n)
2598 2600
	rt_show_net(this_cli, n, d);
......
2613 2615
 * net_find - find a network entry
2614 2616
 * @tab: a routing table
2615 2617
 * @addr: address of the network
2616
 * @len: length of the network prefix
2617 2618
 *
2618 2619
 * net_find() looks up the given network in routing table @tab and
2619 2620
 * returns a pointer to its &net entry or %NULL if no such network
2620 2621
 * exists.
2621 2622
 */
2622
static inline net *net_find(rtable *tab, ip_addr addr, unsigned len)
2623
static inline net *net_find(rtable *tab, net_addr *addr)
2623 2624
{ DUMMY; }
2624 2625

  
2625 2626
/**
2626 2627
 * net_get - obtain a network entry
2627 2628
 * @tab: a routing table
2628 2629
 * @addr: address of the network
2629
 * @len: length of the network prefix
2630 2630
 *
2631 2631
 * net_get() looks up the given network in routing table @tab and
2632 2632
 * returns a pointer to its &net entry. If no such entry exists, it's
2633 2633
 * created.
2634 2634
 */
2635
static inline net *net_get(rtable *tab, ip_addr addr, unsigned len)
2635
static inline net *net_get(rtable *tab, net_addr *addr)
2636 2636
{ DUMMY; }
2637 2637

  
2638 2638
/**
proto/ospf/config.Y
132 132
CF_KEYWORDS(GLOBAL, LSID, ROUTER, SELF, INSTANCE, REAL, NETMASK, TX, PRIORITY, LENGTH)
133 133
CF_KEYWORDS(SECONDARY, MERGE, LSA, SUPPRESSION)
134 134

  
135
%type <t> opttext
136 135
%type <ld> lsadb_args
137 136
%type <i> nbma_eligible
138 137

  
......
401 400
  ospf_iface_start ospf_iface_patt_list ospf_iface_opt_list { ospf_iface_finish(); }
402 401
 ;
403 402

  
404
opttext:
405
    TEXT
406
 | /* empty */ { $$ = NULL; }
407
 ;
408

  
409 403
CF_ADDTO(dynamic_attr, OSPF_METRIC1 { $$ = f_new_dynamic_attr(EAF_TYPE_INT | EAF_TEMP, T_INT, EA_OSPF_METRIC1); })
410 404
CF_ADDTO(dynamic_attr, OSPF_METRIC2 { $$ = f_new_dynamic_attr(EAF_TYPE_INT | EAF_TEMP, T_INT, EA_OSPF_METRIC2); })
411 405
CF_ADDTO(dynamic_attr, OSPF_TAG { $$ = f_new_dynamic_attr(EAF_TYPE_INT | EAF_TEMP, T_INT, EA_OSPF_TAG); })
proto/ospf/hello.c
105 105
  }
106 106

  
107 107
  i = 0;
108
  max = (ospf_pkt_maxsize(ifa) - length) / sizeof(u32);
108
  max = (ospf_pkt_maxsize(p, ifa) - length) / sizeof(u32);
109 109

  
110 110
  /* Fill all neighbors */
111 111
  if (kind != OHS_SHUTDOWN)
proto/ospf/iface.c
67 67
int
68 68
ospf_iface_assure_bufsize(struct ospf_iface *ifa, uint plen)
69 69
{
70
  plen += SIZE_OF_IP_HEADER;
70
  struct ospf_proto *p = ifa->oa->po;
71

  
72
  plen += ospf_is_v2(p) ? IP4_HEADER_LENGTH : IP6_HEADER_LENGTH;
71 73

  
72 74
  /* This is relevant just for OSPFv2 */
73 75
  if (ifa->autype == OSPF_AUTH_CRYPT)
proto/ospf/lsalib.c
280 280

  
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff