Revision b1a1faba

View differences:

sysdep/autoconf.h.in
41 41
/* We have <syslog.h> and syslog() */
42 42
#undef HAVE_SYSLOG
43 43

  
44
/* We have <alloca.h> */
45
#undef HAVE_ALLOCA_H
46

  
44 47
/* Are we using dmalloc? */
45 48
#undef HAVE_LIBDMALLOC
49

  
50
/* Readline stuff */
51
#undef HAVE_RL_CRLF
52
#undef HAVE_RL_DING
53

  
54
/* struct sockaddr_in(6) */
55
#undef HAVE_SIN_LEN
sysdep/bsd/Modules
1
krt-scan.h
2
krt-iface.h
3
sysio.h
4
krt-set.h
5
krt-sock.c
6
krt-sock.h
sysdep/bsd/krt-iface.h
1
/*
2
 *	BIRD -- Unix Kernel Socket Route Syncer -- Dummy Include File
3
 *
4
 *	(c) 2004 Ondrej Filip <feela@network.cz>
5
 *
6
 *	Can be freely distributed and used under the terms of the GNU GPL.
7
 */
8

  
9
#ifndef _BIRD_KRT_IFACE_H_
10
#define _BIRD_KRT_IFACE_H_
11

  
12
/*
13
 *  We don't have split iface/scan/set parts. See krt-sock.h.
14
 */
15
static inline int kif_params_same(struct krt_if_params *old, struct krt_if_params *new) { return 1; }
16

  
17
#endif
sysdep/bsd/krt-scan.c
1
/*
2
 *	BIRD -- *BSD Table Scanning
3
 *
4
 *	(c) 2004 Ondrej Filip <feela@network.cz>
5
 *
6
 *	Can be freely distributed and used under the terms of the GNU GPL.
7
 */
8

  
9
#include <stdio.h>
10
#include <ctype.h>
11
#include <fcntl.h>
12
#include <unistd.h>
13
#include <sys/param.h>
14
#include <sys/types.h>
15
#include <sys/sysctl.h>
16
#include <sys/socket.h>
17
#include <net/route.h>
18

  
19
#undef LOCAL_DEBUG
20
#define LOCAL_DEBUG
21

  
22
#include "nest/bird.h"
23
#include "nest/route.h"
24
#include "nest/protocol.h"
25
#include "nest/iface.h"
26
#include "lib/timer.h"
27
#include "lib/unix.h"
28
#include "lib/krt.h"
29
#include "lib/string.h"
30

  
31
static int krt_scan_fd = -1;
32

  
33
struct iface *
34
krt_temp_iface(struct krt_proto *p, char *name)
35
{
36
  struct iface *i;
37

  
38
  WALK_LIST(i, p->scan.temp_ifs)
39
    if (!strcmp(i->name, name))
40
      return i;
41
  i = mb_allocz(p->p.pool, sizeof(struct iface));
42
  strcpy(i->name, name);
43
  add_tail(&p->scan.temp_ifs, &i->n);
44
  return i;
45
}
46

  
47

  
48
void
49
krt_scan_construct(struct krt_config *c)
50
{
51
}
52

  
53
void
54
krt_scan_preconfig(struct config *c)
55
{
56
}
57

  
58
void
59
krt_scan_postconfig(struct krt_config *c)
60
{
61
}
62

  
63
void
64
krt_scan_start(struct krt_proto *x, int first)
65
{
66
  init_list(&x->scan.temp_ifs);
67
}
68

  
69
void
70
krt_scan_shutdown(struct krt_proto *x, int last)
71
{
72
}
73

  
74
void
75
krt_sysctl_scan(struct proto *p, pool *pool, byte **buf, int *bl, int cmd)
76
{
77
  byte *next;
78
  int obl, needed, mib[6], on;
79
  struct ks_msg *m;
80

  
81
  mib[0] = CTL_NET;
82
  mib[1] = PF_ROUTE;
83
  mib[2] = 0;
84
  mib[3] = BIRD_PF;
85
  mib[4] = cmd;
86
  mib[5] = 0;
87

  
88
  if( sysctl(mib, 6 , NULL , &needed, NULL, 0) < 0)
89
  {
90
    die("RT scan...");
91
  }
92

  
93
  obl = *bl;
94

  
95
  while(needed > *bl) *bl *= 2;
96
  while(needed < (*bl/2)) *bl /= 2;
97

  
98
  if( (obl!=*bl) || !*buf)
99
  {
100
    if(*buf) mb_free(*buf);
101
    if( (*buf = mb_alloc(pool, *bl)) == NULL ) die("RT scan buf alloc");
102
  }
103

  
104
  on = needed;
105

  
106
  if( sysctl(mib, 6 , *buf, &needed, NULL, 0) < 0)
107
  {
108
    if(on != needed) return; 	/* The buffer size changed since last sysctl */
109
    die("RT scan 2");
110
  }
111

  
112
  for (next = *buf; next < (*buf + needed); next += m->rtm.rtm_msglen)
113
  {
114
    m = (struct ks_msg *)next;
115
    krt_read_msg(p, m, 1);
116
  }
117
}
118

  
119
void
120
krt_scan_fire(struct krt_proto *p)
121
{
122
  static byte *buf = NULL;
123
  static int bl = 32768;
124
  krt_sysctl_scan((struct proto *)p , p->krt_pool, &buf, &bl, NET_RT_DUMP);
125
}
126

  
127
void
128
krt_if_scan(struct kif_proto *p)
129
{
130
  static byte *buf = NULL;
131
  static int bl = 4096;
132
  struct proto *P = (struct proto *)p;
133
  if_start_update();
134
  krt_sysctl_scan(P, P->pool, &buf, &bl, NET_RT_IFLIST);
135
  if_end_update();
136
}
137

  
sysdep/bsd/krt-scan.h
1
/*
2
 *	BIRD -- *BSD Kernel Route Syncer -- Scanning
3
 *
4
 *	(c) 2004 Ondrej Filip <feela@network.cz>
5
 *
6
 *	Can be freely distributed and used under the terms of the GNU GPL.
7
 */
8

  
9
#ifndef _BIRD_KRT_SCAN_H_
10
#define _BIRD_KRT_SCAN_H_
11

  
12
struct krt_scan_params {
13
};
14

  
15
struct krt_scan_status {
16
  list temp_ifs;			/* Temporary interfaces */
17
};
18

  
19
static inline int krt_scan_params_same(struct krt_scan_params *o, struct krt_scan_params *n) { return 1; }
20

  
21
#endif
sysdep/bsd/krt-set.h
1
/*
2
 *	BIRD -- Unix Kernel Socket Route Syncer -- Dummy Include File
3
 *
4
 *	(c) 2004 Ondrej Filip <feela@network.cz>
5
 *
6
 *	Can be freely distributed and used under the terms of the GNU GPL.
7
 */
8

  
9
#ifndef _BIRD_KRT_SET_H_
10
#define _BIRD_KRT_SET_H_
11

  
12
/*
13
 *  We don't have split iface/scan/set parts. See krt-sock.h.
14
 */
15
#include "lib/krt-sock.h"
16

  
17
#endif
sysdep/bsd/krt-sock.c
1
/*
2
 *	BIRD -- Unix Routing Table Syncing
3
 *
4
 *	(c) 2004 Ondrej Filip <feela@network.cz>
5
 *
6
 *	Can be freely distributed and used under the terms of the GNU GPL.
7
 */
8

  
9
#include <stdio.h>
10
#include <ctype.h>
11
#include <fcntl.h>
12
#include <unistd.h>
13
#include <sys/param.h>
14
#include <sys/types.h>
15
#include <sys/socket.h>
16
#include <sys/sysctl.h>
17
#include <sys/ioctl.h>
18
#include <netinet/in.h>
19
#include <net/route.h>
20
#include <net/if.h>
21
#include <net/if_dl.h>
22

  
23
#undef LOCAL_DEBUG
24

  
25
#include "nest/bird.h"
26
#include "nest/iface.h"
27
#include "nest/route.h"
28
#include "nest/protocol.h"
29
#include "nest/iface.h"
30
#include "lib/timer.h"
31
#include "lib/unix.h"
32
#include "lib/krt.h"
33
#include "lib/string.h"
34
#include "lib/socket.h"
35

  
36
#ifdef IPV6
37
#define HOST_MASK 128
38
#else
39
#define HOST_MASK 32
40
#endif
41

  
42
int rt_sock = 0;
43

  
44
#define CHECK_FAMILY(sa) \
45
  ((((struct sockaddr *)sa)->sa_family) == BIRD_AF)
46

  
47
struct iface *
48
krt_temp_iface_index(struct krt_proto *p, unsigned index)
49
{
50
  struct iface *i, *j;
51

  
52
  WALK_LIST(i, p->scan.temp_ifs)
53
    if (i->index == index)
54
      return i;
55
  i = mb_allocz(p->p.pool, sizeof(struct iface));
56
  if (j = if_find_by_index(index))
57
  {
58
    strcpy(i->name, j->name);
59
    i->addr = j->addr;
60
  }
61
  else
62
    strcpy(i->name, "?");
63
  i->index = index;
64
  add_tail(&p->scan.temp_ifs, &i->n);
65
  return i;
66
}
67

  
68

  
69
int
70
krt_capable(rte *e)
71
{
72
  rta *a = e->attrs;
73

  
74
#ifdef CONFIG_AUTO_ROUTES
75
  if (a->source == RTS_DEVICE)
76
    return 0;
77
#endif
78
  return
79
    a->cast == RTC_UNICAST &&
80
    (a->dest == RTD_ROUTER
81
     || a->dest == RTD_DEVICE
82
#ifdef RTF_REJECT
83
     || a->dest == RTD_UNREACHABLE
84
#endif
85
#ifdef RTF_BLACKHOLE
86
     || a->dest == RTD_BLACKHOLE	/* FIXME Prohibited? */
87
#endif
88
     );
89
}
90

  
91
#define ROUNDUP(a) \
92
        ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
93

  
94
#define NEXTADDR(w, u) \
95
        if (msg.rtm.rtm_addrs & (w)) {\
96
          l = ROUNDUP(((struct sockaddr *)&(u))->sa_len);\
97
          memmove(body, &(u), l); body += l;}
98

  
99
static void
100
krt_sock_send(int cmd, rte *e, char *name)
101
{
102
  net *net = e->net;
103
  rta *a = e->attrs;
104
  static int msg_seq;
105
  struct iface *j, *i = a->iface;
106
  int l;
107
  struct ks_msg msg;
108
  char *body = (char *)msg.buf;
109
  sockaddr gate, mask, dst;
110

  
111
  log("KRT sock send: %I/%d via %I", net->n.prefix, net->n.pxlen, a->gw);
112

  
113
  fill_in_sockaddr(&dst, net->n.prefix, 0);
114
  fill_in_sockaddr(&mask, ipa_mkmask(net->n.pxlen), 0);
115
  fill_in_sockaddr(&gate, a->gw, 0);
116

  
117
  memset (&msg, 0, sizeof (struct rt_msghdr));
118
  msg.rtm.rtm_version = RTM_VERSION;
119
  msg.rtm.rtm_type = cmd;
120
  msg.rtm.rtm_seq = msg_seq++;
121
  msg.rtm.rtm_addrs = RTA_DST;
122
  msg.rtm.rtm_flags = RTF_UP;
123

  
124
  if (net->n.pxlen == HOST_MASK)
125
  {
126
    msg.rtm.rtm_flags |= RTF_HOST;
127
  }
128
  else
129
  {
130
    msg.rtm.rtm_addrs |= RTA_NETMASK;
131
  }
132

  
133
#ifdef RTF_REJECT
134
  if(a->dest == RTD_UNREACHABLE)
135
    msg.rtm.rtm_flags |= RTF_REJECT;
136
#endif
137
#ifdef RTF_BLACKHOLE
138
  if(a->dest == RTD_BLACKHOLE)
139
    msg.rtm.rtm_flags |= RTF_BLACKHOLE;
140
#endif
141

  
142
  /* This is really very nasty, but I'm not able
143
   * to add "(reject|blackhole)" route without
144
   * gateway set
145
   */
146
  if(!i)
147
  {
148
    i = HEAD(iface_list);
149

  
150
    WALK_LIST(j, iface_list)
151
    {
152
      if (j->flags & IF_LOOPBACK)
153
      {
154
        i = j;
155
        break;
156
      }
157
    }
158
  }
159

  
160
  switch (a->dest)
161
  {
162
    case RTD_ROUTER:
163
      msg.rtm.rtm_flags |= RTF_GATEWAY;
164
      msg.rtm.rtm_addrs |= RTA_GATEWAY;
165
      break;
166
#ifdef RTF_REJECT
167
    case RTD_UNREACHABLE:
168
#endif
169
#ifdef RTF_BLACKHOLE
170
    case RTD_BLACKHOLE:
171
#endif
172
    case RTD_DEVICE:
173
      if(i)
174
      {
175
        if (cmd == RTM_ADD && (i->flags & IF_MULTIACCESS) != IF_MULTIACCESS)	/* PTP */
176
          msg.rtm.rtm_flags |= RTF_CLONING;
177

  
178
        if(!i->addr) {
179
          log(L_ERR "KIF: interface \"%s\" has no IP addess", i->name);
180
          return;
181
        }
182

  
183
        fill_in_sockaddr(&gate, i->addr->ip, 0);
184
        msg.rtm.rtm_addrs |= RTA_GATEWAY;
185
      }
186
      else
187
      {
188
        bug("krt-sock: interface route %I/%d without interface", net->n.prefix, net->n.pxlen);
189
      }
190
      break;
191
    default:
192
      bug("krt-sock: unknown flags, but not filtered");
193
  }
194

  
195
  if(i) msg.rtm.rtm_index = i->index;
196

  
197
  NEXTADDR(RTA_DST, dst);
198
  NEXTADDR(RTA_GATEWAY, gate);
199
  NEXTADDR(RTA_NETMASK, mask);
200

  
201
  l = body - (char *)&msg;
202
  msg.rtm.rtm_msglen = l;
203

  
204
  if ((l = write(rt_sock, (char *)&msg, l)) < 0) {
205
          log(L_ERR "KIF: error writting route to socket (%I/%d)", net->n.prefix, net->n.pxlen);
206
  }
207
}
208

  
209
void
210
krt_set_notify(struct krt_proto *p, net *net, rte *new, rte *old)
211
{
212
  if (old)
213
    {
214
      DBG("krt_remove_route(%I/%d)\n", net->n.prefix, net->n.pxlen);
215
      krt_sock_send(RTM_DELETE, old, "RTM_DELETE");
216

  
217
    }
218
  if (new)
219
    {
220
      DBG("krt_add_route(%I/%d)\n", net->n.prefix, net->n.pxlen);
221
      krt_sock_send(RTM_ADD, new, "RTM_ADD");
222
    }
223
}
224

  
225
void
226
krt_set_start(struct krt_proto *x, int first)
227
{
228
  sock *sk_rt;
229
  static int ks_open_tried = 0;
230

  
231
  if (ks_open_tried)
232
    return;
233

  
234
  ks_open_tried = 1;
235

  
236
  DBG("KRT: Opening kernel socket\n");
237

  
238
  if( (rt_sock = socket(PF_ROUTE, SOCK_RAW, AF_UNSPEC)) < 0)
239
    die("Cannot open kernel socket for routes");
240

  
241
  sk_rt = sk_new(krt_pool);
242
  sk_rt->type = SK_MAGIC;
243
  sk_rt->rx_hook = krt_set_hook;
244
  sk_rt->fd = rt_sock;
245
  sk_rt->data = x;
246
  if (sk_open(sk_rt))
247
    bug("Krt_sock: sk_rt_open failed");
248
}
249

  
250
static int
251
krt_set_hook(sock *sk, int size)
252
{
253
  int l;
254
  struct ks_msg msg;
255
  
256
  l = read(sk->fd, (char *)&msg, sizeof(msg));
257

  
258
  krt_read_msg((struct proto *)sk->data, &msg, 0);
259
  return 0;
260
}
261

  
262
void
263
krt_read_rt(struct ks_msg *msg, struct krt_proto *p, int scan)
264
{
265
  sockaddr gate, mask, dst;
266
  rta a;
267
  rte *e;
268
  net *net;
269
  u32 oif;
270
  ip_addr idst, igate, imask;
271
  void *body = (char *)msg->buf;
272
  int new = (msg->rtm.rtm_type == RTM_ADD);
273
  int src;
274
  int flags = msg->rtm.rtm_flags;
275
  int addrs = msg->rtm.rtm_addrs;
276
  int masklen = -1;
277

  
278
  if (!(flags & RTF_UP))
279
  {
280
    DBG("Down.\n");
281
    return;
282
  }
283

  
284
  if (flags & RTF_HOST)
285
    masklen = HOST_MASK;
286

  
287
  if(!CHECK_FAMILY(body)) return;
288

  
289
  if(msg->rtm.rtm_flags & RTF_LLINFO) return;	/* ARPs etc. */
290

  
291
#define GETADDR(p, F) \
292
  memset(p, 0, sizeof(*p));\
293
  if ((addrs & (F)) && ((struct sockaddr *)body)->sa_len) {\
294
    unsigned int l = ROUNDUP(((struct sockaddr *)body)->sa_len);\
295
    memcpy(p, body, (l > sizeof(*p) ? sizeof(*p) : l));\
296
    body += l;}
297

  
298
  GETADDR (&dst, RTA_DST);
299
  GETADDR (&gate, RTA_GATEWAY);
300
  GETADDR (&mask, RTA_NETMASK);
301

  
302
  idst = IPA_NONE;
303
  igate = IPA_NONE;
304
  imask = IPA_NONE;
305

  
306
  get_sockaddr(&dst, &idst, NULL, 0);
307
  if(CHECK_FAMILY(&gate)) get_sockaddr(&gate, &igate, NULL, 0);
308
  get_sockaddr(&mask, &imask, NULL, 0);
309

  
310
  if (masklen < 0) masklen = ipa_mklen(imask);
311

  
312
  if (flags & (RTF_DYNAMIC | RTF_MODIFIED))
313
  {
314
    log(L_WARN "krt: Ignoring redirect to %I/%d via %I", idst, masklen, igate);
315
    return;
316
  }
317

  
318
  if (masklen < 0)
319
  {
320
    log(L_WARN "krt: Got invalid route from kernel!");
321
    return;
322
  }
323

  
324
  net = net_get(p->p.table, idst, masklen);
325

  
326
  memset(&a, 0, sizeof(a));
327

  
328
  a.proto = &p->p;
329
  a.source = RTS_INHERIT;
330
  a.scope = SCOPE_UNIVERSE;
331
  a.cast = RTC_UNICAST;
332
  a.flags = a.aflags = 0;
333
  a.from = IPA_NONE;
334
  a.gw = IPA_NONE;
335
  a.iface = NULL;
336
  a.eattrs = NULL;
337

  
338
  a.dest = RTD_NONE;
339

  
340

  
341
  if (flags & RTF_GATEWAY)
342
  {
343
    neighbor *ng = neigh_find(&p->p, &igate, 0);
344
    if (ng && ng->scope)
345
      a.iface = ng->iface;
346
    else
347
      log(L_WARN "Kernel told us to use non-neighbor %I for %I/%d", igate, net->n.prefix, net->n.pxlen);
348

  
349
    a.dest = RTD_ROUTER;
350
    a.gw = igate;
351
  }
352
  else
353
  {
354
    a.dest = RTD_DEVICE;
355
    a.gw = IPA_NONE;
356
    a.iface = krt_temp_iface_index(p, msg->rtm.rtm_index);
357
  }
358

  
359
#ifdef RTF_REJECT
360
  if(flags & RTF_REJECT) {
361
    a.dest = RTD_UNREACHABLE;
362
    a.gw = IPA_NONE;
363
  }
364
#endif
365

  
366
#ifdef RTF_BLACKHOLE
367
  if(flags & RTF_BLACKHOLE) {
368
    a.dest = RTD_BLACKHOLE;
369
    a.gw = IPA_NONE;
370
  }
371
#endif
372

  
373
  if (a.dest == RTD_NONE)
374
  {
375
    log(L_WARN "Kernel reporting unknown route type to %I/%d", net->n.prefix, net->n.pxlen);
376
    return;
377
  }
378

  
379
  src = KRT_SRC_UNKNOWN;	/* FIXME */
380

  
381

  
382

  
383
  e = rte_get_temp(&a);
384
  e->net = net;
385
  e->u.krt.src = src;
386
  //e->u.krt.proto = i->rtm_protocol;
387
  //e->u.krt.type = i->rtm_type;
388
  e->u.krt.metric = 0;
389

  
390
  if (scan)
391
    krt_got_route(p, e);
392
  else
393
    krt_got_route_async(p, e, new);
394
}
395

  
396
void
397
krt_read_ifinfo(struct ks_msg *msg)
398
{
399
  struct if_msghdr *ifm = (struct if_msghdr *)&msg->rtm;
400
  void *body = (void *)(ifm + 1);
401
  struct sockaddr_dl *dl = NULL;
402
  unsigned int i;
403
  struct iface *iface = NULL, f;
404
  char *ifname = "(none)";
405
  int fl = ifm->ifm_flags;
406

  
407
  for(i = 1; i!=0; i <<= 1)
408
  {
409
    if((i & ifm->ifm_addrs) && (i == RTA_IFP))
410
    {
411
      if( i == RTA_IFP)
412
      {
413
        dl = (struct sockaddr_dl *)body;
414
        break;
415
      }
416
      body += ROUNDUP(((struct sockaddr *)&(body))->sa_len);\
417
    }
418
  }
419

  
420
  if(dl && (dl->sdl_family != AF_LINK))
421
  {
422
    log("Ignoring strange IFINFO");
423
    return;
424
  }
425

  
426
  if(dl) ifname = dl->sdl_data;
427

  
428
  iface = if_find_by_index(ifm->ifm_index);
429

  
430
  if(!iface)
431
  {
432
    /* New interface */
433
    if(!dl) return;	/* No interface name, ignoring */
434
    DBG("New interface \"%s\" found", ifname);
435
    bzero(&f, sizeof(f));
436
    f.index = ifm->ifm_index;
437
    strncpy(f.name, ifname, sizeof(f.name) -1);
438
  }
439
  else
440
  {
441
    memcpy(&f, iface, sizeof(struct iface));
442
  }
443

  
444
  f.mtu = ifm->ifm_data.ifi_mtu;
445
  f.flags = 0;
446

  
447
  if (fl & IFF_UP)
448
  {
449
    //f.flags |= IF_UP;	/* FIXME */
450
    f.flags |= IF_LINK_UP;
451
  }
452
  if (fl & IFF_LOOPBACK)            /* Loopback */
453
    f.flags |= IF_MULTIACCESS | IF_LOOPBACK | IF_IGNORE;
454
  else if (fl & IFF_POINTOPOINT)    /* PtP */
455
    f.flags |= IF_MULTICAST;
456
  else if (fl & IFF_BROADCAST)      /* Broadcast */
457
    f.flags |= IF_MULTIACCESS | IF_BROADCAST | IF_MULTICAST;
458
  else
459
    f.flags |= IF_MULTIACCESS;      /* NBMA */
460

  
461
  if((!iface) || memcmp(&f, iface, sizeof(struct iface)))
462
    if_update(&f);	/* Just if something happens */
463
}
464

  
465
void
466
krt_read_addr(struct ks_msg *msg)
467
{
468
  struct ifa_msghdr *ifam = (struct ifa_msghdr *)&msg->rtm;
469
  void *body = (void *)(ifam + 1);
470
  sockaddr addr, mask, brd;
471
  unsigned int i;
472
  struct iface *iface = NULL;
473
  struct ifa ifa;
474
  struct sockaddr null;
475
  ip_addr iaddr, imask, ibrd;
476
  int addrs = ifam->ifam_addrs;
477
  int scope, masklen = -1;
478
  int new = (ifam->ifam_type == RTM_NEWADDR);
479
  int fl = ifam->ifam_flags;
480

  
481
  if(!(iface = if_find_by_index(ifam->ifam_index)))
482
  {
483
    log(L_ERR "KIF: Received address message for unknown interface %d", ifam->ifam_index);
484
    return;
485
  }
486

  
487
  GETADDR (&null, RTA_DST);
488
  GETADDR (&null, RTA_GATEWAY);
489
  GETADDR (&mask, RTA_NETMASK);
490
  GETADDR (&null, RTA_GENMASK);
491
  GETADDR (&null, RTA_IFP);
492
  GETADDR (&addr, RTA_IFA);
493
  GETADDR (&null, RTA_AUTHOR);
494
  GETADDR (&brd, RTA_BRD);
495

  
496
  if(!CHECK_FAMILY(&addr)) return; /* Some other family address */
497

  
498
  get_sockaddr(&addr, &iaddr, NULL, 0);
499
  get_sockaddr(&mask, &imask, NULL, 0);
500
  get_sockaddr(&brd, &ibrd, NULL, 0);
501

  
502
  if ((masklen = ipa_mklen(imask)) < 0)
503
  {
504
    log("Invalid masklen");
505
    return;
506
  }
507

  
508
  memset(&ifa, 0, sizeof(ifa));
509

  
510
  ifa.iface = iface;
511

  
512
  memcpy(&ifa.ip, &iaddr, sizeof(ip_addr));
513
  ifa.pxlen = masklen;
514
  memcpy(&ifa.brd, &ibrd, sizeof(ip_addr));
515

  
516
  scope = ipa_classify(ifa.ip);
517

  
518
  ifa.prefix = ipa_and(ifa.ip, ipa_mkmask(masklen));
519

  
520
  if (scope < 0)
521
  {
522
    log(L_ERR "KIF: Invalid interface address %I for %s", ifa.ip, iface->name);
523
    return;
524
  }
525
  ifa.scope = scope & IADDR_SCOPE_MASK;
526

  
527
  if (new)
528
    ifa_update(&ifa);
529
  else
530
    ifa_delete(&ifa);
531
}
532

  
533

  
534
void
535
krt_read_msg(struct proto *p, struct ks_msg *msg, int scan)
536
{
537
  switch (msg->rtm.rtm_type)
538
  {
539
    case RTM_GET:
540
      if(!scan) return;
541
    case RTM_ADD:
542
    case RTM_DELETE:
543
      //log("KRT_ADD/DELETE");
544
      krt_read_rt(msg, (struct krt_proto *)p, scan);
545
      break;
546
    case RTM_IFINFO:
547
      //log("KRT_IFINFO");
548
      krt_read_ifinfo(msg);
549
      break;
550
    case RTM_NEWADDR:
551
    case RTM_DELADDR:
552
      //log("KRT_NEWADDR/DELADDR");
553
      krt_read_addr(msg);
554
      break;
555
#ifdef RTM_IFANNOUNCE
556
    case RTM_IFANNOUNCE:
557
      log("KRT_IFANNOUNCE");
558
      //ifan_read (&buf.ian.ifan);
559
      break;
560
#endif /* RTM_IFANNOUNCE */
561
    default:
562
        log("Unprocessed RTM_type: %d", msg->rtm.rtm_type);
563
      break;
564
  }
565
}
566

  
567

  
568
struct iface *
569
krt_temp_iface(struct krt_proto *p, char *name)
570
{
571
  struct iface *i;
572

  
573
  WALK_LIST(i, p->scan.temp_ifs)
574
    if (!strcmp(i->name, name))
575
      return i;
576
  i = mb_allocz(p->p.pool, sizeof(struct iface));
577
  strcpy(i->name, name);
578
  add_tail(&p->scan.temp_ifs, &i->n);
579
  return i;
580
}
581

  
582

  
583
void
584
krt_scan_construct(struct krt_config *c)
585
{
586
}
587

  
588
void
589
krt_scan_preconfig(struct config *c)
590
{
591
}
592

  
593
void
594
krt_scan_postconfig(struct krt_config *c)
595
{
596
}
597

  
598
void
599
krt_scan_start(struct krt_proto *x, int first)
600
{
601
  init_list(&x->scan.temp_ifs);
602
}
603

  
604
void
605
krt_scan_shutdown(struct krt_proto *x, int last)
606
{
607
}
608

  
609
void
610
krt_sysctl_scan(struct proto *p, pool *pool, byte **buf, int *bl, int cmd)
611
{
612
  byte *next;
613
  int obl, needed, mib[6], on;
614
  struct ks_msg *m;
615

  
616
  mib[0] = CTL_NET;
617
  mib[1] = PF_ROUTE;
618
  mib[2] = 0;
619
  mib[3] = BIRD_PF;
620
  mib[4] = cmd;
621
  mib[5] = 0;
622

  
623
  if( sysctl(mib, 6 , NULL , &needed, NULL, 0) < 0)
624
  {
625
    die("RT scan...");
626
  }
627

  
628
  obl = *bl;
629

  
630
  while(needed > *bl) *bl *= 2;
631
  while(needed < (*bl/2)) *bl /= 2;
632

  
633
  if( (obl!=*bl) || !*buf)
634
  {
635
    if(*buf) mb_free(*buf);
636
    if( (*buf = mb_alloc(pool, *bl)) == NULL ) die("RT scan buf alloc");
637
  }
638

  
639
  on = needed;
640

  
641
  if( sysctl(mib, 6 , *buf, &needed, NULL, 0) < 0)
642
  {
643
    if(on != needed) return; 	/* The buffer size changed since last sysctl */
644
    die("RT scan 2");
645
  }
646

  
647
  for (next = *buf; next < (*buf + needed); next += m->rtm.rtm_msglen)
648
  {
649
    m = (struct ks_msg *)next;
650
    krt_read_msg(p, m, 1);
651
  }
652
}
653

  
654
void
655
krt_scan_fire(struct krt_proto *p)
656
{
657
  static byte *buf = NULL;
658
  static int bl = 32768;
659
  krt_sysctl_scan((struct proto *)p , p->krt_pool, &buf, &bl, NET_RT_DUMP);
660
}
661

  
662
void
663
krt_if_scan(struct kif_proto *p)
664
{
665
  static byte *buf = NULL;
666
  static int bl = 4096;
667
  struct proto *P = (struct proto *)p;
668
  if_start_update();
669
  krt_sysctl_scan(P, P->pool, &buf, &bl, NET_RT_IFLIST);
670
  if_end_update();
671
}
672

  
673

  
674
void
675
krt_set_construct(struct krt_config *c)
676
{
677
}
678

  
679
void
680
krt_set_shutdown(struct krt_proto *x, int last)
681
{
682
} 
683

  
684
void
685
krt_if_io_init(void)
686
{
687
}
688

  
689
void
690
krt_if_construct(struct kif_config *c)
691
{
692
}
693

  
694
void
695
krt_if_start(struct kif_proto *p)
696
{
697
}
698

  
699
void
700
krt_if_shutdown(struct kif_proto *p)
701
{
702
}
703

  
sysdep/bsd/krt-sock.h
1
/*
2
 *	BIRD -- Unix Kernel Route Syncer -- Setting
3
 *
4
 *	(c) 2004 Ondrej Filip <feela@network.cz>
5
 *
6
 *	Can be freely distributed and used under the terms of the GNU GPL.
7
 */
8

  
9
#ifndef _BIRD_KRT_SOCK_H_
10
#define _BIRD_KRT_SOCK_H_
11

  
12
#include <sys/socket.h>
13
#include <net/route.h>
14
#include "lib/socket.h"
15

  
16
#ifndef RTAX_MAX
17
#define RTAX_MAX        8
18
#endif
19

  
20

  
21
struct ks_msg
22
{
23
  struct rt_msghdr rtm;
24
  struct sockaddr_storage buf[RTAX_MAX];
25
};
26

  
27

  
28

  
29
extern int krt_set_sock;
30

  
31
struct krt_set_params {
32
};
33

  
34
struct krt_set_status {
35
};
36

  
37
struct krt_if_params {
38
};
39

  
40
struct krt_if_status {
41
};
42

  
43
static int krt_set_hook(sock *sk, int size);
44
static inline int krt_set_params_same(struct krt_set_params *o, struct krt_set_params *n) { return 1; }
45
void krt_read_msg(struct proto *p, struct ks_msg *msg, int scan);
46

  
47
#endif
sysdep/bsd/sysio.h
1
/*
2
 *	BIRD Internet Routing Daemon -- NetBSD Multicasting and Network Includes
3
 *
4
 *	(c) 2004       Ondrej Filip <feela@network.cz>
5
 *
6
 *	Can be freely distributed and used under the terms of the GNU GPL.
7
 */
8

  
9
#ifdef IPV6
10

  
11
static inline void
12
set_inaddr(struct in6_addr * ia, ip_addr a)
13
{
14
	ipa_hton(a);
15
	memcpy(ia, &a, sizeof(a));
16
}
17

  
18
#else
19

  
20
#include <net/if.h>
21

  
22
static inline void
23
set_inaddr(struct in_addr * ia, ip_addr a)
24
{
25
	ipa_hton(a);
26
	memcpy(&ia->s_addr, &a, sizeof(a));
27
}
28

  
29
static inline char *
30
sysio_mcast_setup(sock * s)
31
{
32
	u8              zero = 0;
33
	u8		one = 1;
34

  
35
	if (ipa_nonzero(s->daddr)) {
36

  
37
		if (setsockopt(s->fd, IPPROTO_IP, IP_MULTICAST_LOOP, &zero, sizeof(zero)) < 0) {
38
			log("IP_MULTICAST_LOOP");
39
			return "IP_MULTICAST_LOOP";
40
		}
41

  
42
		if (setsockopt(s->fd, IPPROTO_IP, IP_MULTICAST_TTL, &one, sizeof(one)) < 0) {
43
			log("IP_MULTICAST_TTL");
44
			return "IP_MULTICAST_TTL";
45
		}
46
	}
47
	return NULL;
48
}
49

  
50

  
51
static inline char *
52
sysio_mcast_join(sock * s)
53
{
54
	struct in_addr  m;
55
	struct ip_mreq  mreq;
56
	char   *err;
57

  
58
        set_inaddr(&m, s->iface->addr->ip );
59

  
60
	memset(&mreq, 0, sizeof(mreq));
61
	set_inaddr(&mreq.imr_interface, s->iface->addr->ip);
62
	set_inaddr(&mreq.imr_multiaddr, s->daddr);
63

  
64
	/* And this one sets interface for _receiving_ multicasts from */
65
	if (ipa_nonzero(s->daddr) && setsockopt(s->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) {
66
		log("IP_ADD_MEMBERSHIP");
67
		return "IP_ADD_MEMBERSHIP";
68
	}
69

  
70

  
71
	/* This defines where should we send _outgoing_ multicasts */
72
	if (ipa_nonzero(s->daddr) && setsockopt(s->fd, IPPROTO_IP, IP_MULTICAST_IF, &m, sizeof(m)) < 0) {
73
		log("IP_MULTICAST_IF");
74
		return "IP_MULTICAST_IF";
75
	}
76

  
77
	if (err = sysio_mcast_setup(s))
78
		return err;
79

  
80
	return NULL;
81
}
82

  
83
#endif
sysdep/cf/bsd-v6.h
1
/*
2
 *	Configuration for *BSD based systems (tested on FreeBSD and NetBSD)
3
 *
4
 *	(c) 2004 Ondrej Filip <feela@network.cz>
5
 *
6
 *	Can be freely distributed and used under the terms of the GNU GPL.
7
 */
8

  
9
#define IPV6
10

  
11
#define CONFIG_AUTO_ROUTES
12
#undef CONFIG_SELF_CONSCIOUS
13
#undef CONFIG_MULTIPLE_TABLES
14

  
15
#undef CONFIG_UNIX_IFACE
16
#undef CONFIG_UNIX_SET
17

  
18
#define CONFIG_ALL_MULTICAST
19
#define CONFIG_UNNUM_MULTICAST
20

  
21
/*
22
Link: sysdep/unix
23
Link: sysdep/bsd
24
 */
sysdep/cf/bsd.h
1
/*
2
 *	Configuration for *BSD based systems (tested on FreeBSD and NetBSD)
3
 *
4
 *	(c) 2004 Ondrej Filip <feela@network.cz>
5
 *
6
 *	Can be freely distributed and used under the terms of the GNU GPL.
7
 */
8

  
9
#define CONFIG_AUTO_ROUTES
10
#undef CONFIG_SELF_CONSCIOUS
11
#undef CONFIG_MULTIPLE_TABLES
12

  
13
#undef CONFIG_UNIX_IFACE
14
#undef CONFIG_UNIX_SET
15

  
16
#define CONFIG_ALL_MULTICAST
17
#define CONFIG_UNNUM_MULTICAST
18

  
19
/*
20
Link: sysdep/unix
21
Link: sysdep/bsd
22
 */
sysdep/unix/io.c
2 2
 *	BIRD Internet Routing Daemon -- Unix I/O
3 3
 *
4 4
 *	(c) 1998--2000 Martin Mares <mj@ucw.cz>
5
 *      (c) 2004       Ondrej Filip <feela@network.cz>
5 6
 *
6 7
 *	Can be freely distributed and used under the terms of the GNU GPL.
7 8
 */
......
29 30
#include "lib/unix.h"
30 31
#include "lib/sysio.h"
31 32

  
33
#define LOCAL_DEBUG
32 34
/*
33 35
 *	Tracked Files
34 36
 */
......
399 401
#define SOL_IP IPPROTO_IP
400 402
#endif
401 403

  
404
#ifndef SOL_IPV6
405
#define SOL_IPV6 IPPROTO_IPV6
406
#endif
407

  
408
#ifndef IPV6_ADD_MEMBERSHIP
409
#define IPV6_ADD_MEMBERSHIP IP_ADD_MEMBERSHIP
410
#endif
411

  
402 412
static list sock_list;
403 413

  
404 414
static void
......
476 486
void
477 487
fill_in_sockaddr(sockaddr *sa, ip_addr a, unsigned port)
478 488
{
489
  memset (sa, 0, sizeof (struct sockaddr_in6));
479 490
  sa->sin6_family = AF_INET6;
480 491
  sa->sin6_port = htons(port);
481 492
  sa->sin6_flowinfo = 0;
493
#ifdef HAVE_SIN_LEN
494
  sa->sin6_len = sizeof(struct sockaddr_in6);
495
#endif
482 496
  set_inaddr(&sa->sin6_addr, a);
483 497
}
484 498

  
485 499
void
486
get_sockaddr(sockaddr *sa, ip_addr *a, unsigned *port)
500
get_sockaddr(struct sockaddr_in6 *sa, ip_addr *a, unsigned *port, int check)
487 501
{
488
  if (sa->sin6_family != AF_INET6)
489
    bug("get_sockaddr called for wrong address family");
502
  if (check && sa->sin6_family != AF_INET6)
503
    bug("get_sockaddr called for wrong address family (%d)", sa->sin6_family);
490 504
  if (port)
491 505
    *port = ntohs(sa->sin6_port);
492 506
  memcpy(a, &sa->sin6_addr, sizeof(*a));
......
498 512
void
499 513
fill_in_sockaddr(sockaddr *sa, ip_addr a, unsigned port)
500 514
{
515
  memset (sa, 0, sizeof (struct sockaddr_in));
501 516
  sa->sin_family = AF_INET;
502 517
  sa->sin_port = htons(port);
518
#ifdef HAVE_SIN_LEN
519
  sa->sin_len = sizeof(struct sockaddr_in);
520
#endif
503 521
  set_inaddr(&sa->sin_addr, a);
504 522
}
505 523

  
506 524
void
507
get_sockaddr(sockaddr *sa, ip_addr *a, unsigned *port)
525
get_sockaddr(struct sockaddr_in *sa, ip_addr *a, unsigned *port, int check)
508 526
{
509
  if (sa->sin_family != AF_INET)
510
    bug("get_sockaddr called for wrong address family");
527
  if (check && sa->sin_family != AF_INET)
528
    bug("get_sockaddr called for wrong address family (%d)", sa->sin_family);
511 529
  if (port)
512 530
    *port = ntohs(sa->sin_port);
513 531
  memcpy(a, &sa->sin_addr.s_addr, sizeof(*a));
......
536 554
    WARN("IP_TOS");
537 555
  if (s->ttl >= 0 && setsockopt(fd, SOL_IP, IP_TTL, &s->ttl, sizeof(s->ttl)) < 0)
538 556
    ERR("IP_TTL");
539
  if (s->ttl == 1 && setsockopt(fd, SOL_SOCKET, SO_DONTROUTE, &one, sizeof(one)) < 0)
540
    ERR("SO_DONTROUTE");
557
  //if (s->ttl == 1 && setsockopt(fd, SOL_SOCKET, SO_DONTROUTE, &one, sizeof(one)) < 0)
558
  //  ERR("SO_DONTROUTE");
541 559
#endif
542 560
  err = NULL;
543 561
bad:
......
578 596
      t->rbsize = s->rbsize;
579 597
      t->tbsize = s->tbsize;
580 598
      if (type == SK_TCP)
581
	get_sockaddr((sockaddr *) sa, &t->daddr, &t->dport);
599
	get_sockaddr((sockaddr *) sa, &t->daddr, &t->dport, 1);
582 600
      add_tail(&sock_list, &t->n);
583 601
      if (err = sk_setup(t))
584 602
	{
......
645 663
  s->fd = fd;
646 664

  
647 665
  if (err = sk_setup(s))
666
  {
648 667
    goto bad;
668
  }
649 669
  switch (type)
650 670
    {
651 671
    case SK_UDP:
......
683 703
	    mreq.ipv6mr_ifindex = s->iface->index;
684 704
#else
685 705
	    mreq.ipv6mr_interface = s->iface->index;
686
#endif
706
#endif /* CONFIG_IPV6_GLIBC_20 */
687 707
	    if (setsockopt(fd, SOL_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
688 708
	      ERR("IPV6_ADD_MEMBERSHIP");
689 709
	  }
......
692 712
	ASSERT(s->iface && s->iface->addr);
693 713
	if (err = sysio_mcast_join(s))
694 714
	  goto bad;
695
#endif
715
#endif /* IPV6 */
696 716
      break;
697 717
      }
698 718
    }
......
842 862
	if (s->tbuf == s->tpos)
843 863
	  return 1;
844 864
	fill_in_sockaddr(&sa, s->faddr, s->fport);
865

  
845 866
	e = sendto(s->fd, s->tbuf, s->tpos - s->tbuf, 0, (struct sockaddr *) &sa, sizeof(sa));
846 867
	if (e < 0)
847 868
	  {
......
955 976
	    return 0;
956 977
	  }
957 978
	s->rpos = s->rbuf + e;
958
	get_sockaddr(&sa, &s->faddr, &s->fport);
979
	get_sockaddr(&sa, &s->faddr, &s->fport, 1);
959 980
	s->rx_hook(s, e);
960 981
	return 1;
961 982
      }
sysdep/unix/krt-iface.c
2 2
 *	BIRD -- Unix Interface Scanning and Syncing
3 3
 *
4 4
 *	(c) 1998--2000 Martin Mares <mj@ucw.cz>
5
 *      (c) 2004       Ondrej Filip <feela@network.cz>
5 6
 *
6 7
 *	Can be freely distributed and used under the terms of the GNU GPL.
7 8
 */
......
36 37
  unsigned fl;
37 38
  ip_addr netmask;
38 39
  int l, scope;
40
  sockaddr *sa;
39 41

  
40 42
  if_start_update();
41 43
  for (cnt /= sizeof(struct ifreq); cnt; cnt--, r++)
......
43 45
      int sec = 0;
44 46
      bzero(&i, sizeof(i));
45 47
      bzero(&a, sizeof(a));
46
      DBG("%s\n", r->ifr_name);
47 48
      if (colon = strchr(r->ifr_name, ':'))
48 49
	{
49 50
	  /* It's an alias -- let's interpret it as a secondary interface address */
......
51 52
	  *colon = 0;
52 53
	}
53 54
      strncpy(i.name, r->ifr_name, sizeof(i.name) - 1);
54
      get_sockaddr((struct sockaddr_in *) &r->ifr_addr, &a.ip, NULL);
55

  
56
      if(ioctl(if_scan_sock, SIOCGIFADDR,r)<0) continue;
57

  
58
      get_sockaddr((struct sockaddr_in *) &r->ifr_addr, &a.ip, NULL, 1);
55 59
      if (ipa_nonzero(a.ip))
56 60
	{
57 61
	  l = ipa_classify(a.ip);
......
83 87

  
84 88
      if (ioctl(if_scan_sock, SIOCGIFNETMASK, r) < 0)
85 89
	{ err = "SIOCGIFNETMASK"; goto faulty; }
86
      get_sockaddr((struct sockaddr_in *) &r->ifr_addr, &netmask, NULL);
90
      get_sockaddr((struct sockaddr_in *) &r->ifr_addr, &netmask, NULL, 0);
87 91
      l = ipa_mklen(netmask);
88 92
      if (l < 0 || l == 31)
89 93
	{
90
	  log(L_ERR "%s: Invalid netmask", i.name);
94
	  log(L_ERR "%s: Invalid netmask (%x)", i.name, netmask);
91 95
	  goto bad;
92 96
	}
93 97
      a.pxlen = l;
......
97 101
	  a.flags |= IA_UNNUMBERED;
98 102
	  if (ioctl(if_scan_sock, SIOCGIFDSTADDR, r) < 0)
99 103
	    { err = "SIOCGIFDSTADDR"; goto faulty; }
100
	  get_sockaddr((struct sockaddr_in *) &r->ifr_addr, &a.opposite, NULL);
104
	  get_sockaddr((struct sockaddr_in *) &r->ifr_addr, &a.opposite, NULL, 1);
101 105
	  a.prefix = a.opposite;
102 106
	  a.pxlen = BITS_PER_IP_ADDRESS;
103 107
	}
......
188 192

  
189 193
  for(;;)
190 194
    {
191
      if (last_ifbuf_size)
192
	{
193
	  struct ifreq *r = alloca(last_ifbuf_size);
194
	  ic.ifc_ifcu.ifcu_req = r;
195
	  ic.ifc_len = last_ifbuf_size;
196
	  res = ioctl(if_scan_sock, SIOCGIFCONF, &ic);
197
	  if (res < 0 && errno != EFAULT)
198
	    die("SIOCCGIFCONF: %m");
199
	  if (res >= 0 && ic.ifc_len < last_ifbuf_size)
200
	    {
201
	      scan_ifs(r, ic.ifc_len);
202
	      break;
203
	    }
204
	}
205
#if 0
206
      /*
207
       *  Linux 2.1 and higher supports this, but it's not needed since
208
       *  we prefer to use Netlink there anyway.
209
       */
210
      ic.ifc_req = NULL;
211
      ic.ifc_len = 999999999;
212
      if (ioctl(if_scan_sock, SIOCGIFCONF, &ic) < 0)
213
	die("SIOCIFCONF: %m");
214
      ic.ifc_len += sizeof(struct ifreq);
215
      if (last_ifbuf_size < ic.ifc_len)
216
	{
217
	  last_ifbuf_size = ic.ifc_len;
218
	  DBG("Increased ifconf buffer size to %d\n", last_ifbuf_size);
219
	}
220
#else
195
      ic.ifc_buf = alloca(last_ifbuf_size);
196
      ic.ifc_len = last_ifbuf_size;
197
      res = ioctl(if_scan_sock, SIOCGIFCONF, &ic);
198
      if (res < 0 && errno != EFAULT)
199
        die("SIOCCGIFCONF: %m");
200
      if (res >= 0 && ic.ifc_len <= last_ifbuf_size)
201
        break;
221 202
      last_ifbuf_size *= 2;
222 203
      DBG("Increased ifconf buffer size to %d\n", last_ifbuf_size);
223
#endif
224 204
    }
205
  scan_ifs(ic.ifc_req, ic.ifc_len);
225 206
}
226 207

  
227 208
void
......
247 228
  if (if_scan_sock < 0)
248 229
    die("Cannot create scanning socket: %m");
249 230
}
231

  
sysdep/unix/krt-set.c
13 13
#include <net/route.h>
14 14

  
15 15
#undef LOCAL_DEBUG
16
#define LOCAL_DEBUG
16 17

  
17 18
#include "nest/bird.h"
18 19
#include "nest/iface.h"
......
36 37
    (a->dest == RTD_ROUTER
37 38
     || a->dest == RTD_DEVICE
38 39
#ifdef RTF_REJECT
39
     || a->dest == RTD_UNREACHABLE
40
     || a->dest == RTD_UNREACHABLE		/* FIXME Blackhole, prohibited?? */
40 41
#endif
41 42
     );
42 43
}
......
45 46
krt_ioctl(int ioc, rte *e, char *name)
46 47
{
47 48
  net *net = e->net;
48
  struct rtentry re;
49
  struct ortentry re;
49 50
  rta *a = e->attrs;
50 51

  
51 52
  bzero(&re, sizeof(re));
52 53
  fill_in_sockaddr((struct sockaddr_in *) &re.rt_dst, net->n.prefix, 0);
53
  fill_in_sockaddr((struct sockaddr_in *) &re.rt_genmask, ipa_mkmask(net->n.pxlen), 0);
54
  //fill_in_sockaddr((struct sockaddr_in *) &re.rt_genmask, ipa_mkmask(net->n.pxlen), 0);
54 55
  re.rt_flags = RTF_UP;
55 56
  if (net->n.pxlen == 32)
56 57
    re.rt_flags |= RTF_HOST;
......
61 62
      re.rt_flags |= RTF_GATEWAY;
62 63
      break;
63 64
    case RTD_DEVICE:
64
      re.rt_dev = a->iface->name;
65
      //re.rt_dev = a->iface->name;
65 66
      break;
66 67
#ifdef RTF_REJECT
67 68
    case RTD_UNREACHABLE:
sysdep/unix/main.c
12 12
#include <stdlib.h>
13 13
#include <fcntl.h>
14 14
#include <unistd.h>
15
#include <sys/signal.h>
15
#include <signal.h>
16 16

  
17 17
#include "nest/bird.h"
18 18
#include "lib/lists.h"
sysdep/unix/unix.h
43 43
void io_init(void);
44 44
void io_loop(void);
45 45
void fill_in_sockaddr(sockaddr *sa, ip_addr a, unsigned port);
46
void get_sockaddr(sockaddr *sa, ip_addr *a, unsigned *port);
46
void get_sockaddr(sockaddr *sa, ip_addr *a, unsigned *port, int check);
47 47
int sk_open_unix(struct birdsock *s, char *name);
48 48
void *tracked_fopen(struct pool *, char *name, char *mode);
49 49

  

Also available in: Unified diff