Statistics
| Branch: | Revision:

iof-bird-daemon / nest / rt-dev.c @ 9b9a7143

History | View | Annotate | Download (3.07 KB)

1 c5ffa447 Martin Mares
/*
2
 *        BIRD -- Direct Device Routes
3
 *
4 394aec8f Martin Mares
 *        (c) 1998--2000 Martin Mares <mj@ucw.cz>
5 c5ffa447 Martin Mares
 *
6
 *        Can be freely distributed and used under the terms of the GNU GPL.
7
 */
8
9 47f8e0c2 Martin Mares
/**
10
 * DOC: Direct
11
 *
12 2e9b2421 Martin Mares
 * The Direct protocol works by converting all ifa_notify() events it receives
13 47f8e0c2 Martin Mares
 * to rte_update() calls for the corresponding network.
14
 */
15
16 6b9fa320 Martin Mares
#undef LOCAL_DEBUG
17 c5ffa447 Martin Mares
18
#include "nest/bird.h"
19
#include "nest/iface.h"
20
#include "nest/protocol.h"
21
#include "nest/route.h"
22 50d8424a Martin Mares
#include "nest/rt-dev.h"
23
#include "conf/conf.h"
24 c5ffa447 Martin Mares
#include "lib/resource.h"
25 221135d6 Martin Mares
#include "lib/string.h"
26 c5ffa447 Martin Mares
27
static void
28 9a158361 Martin Mares
dev_ifa_notify(struct proto *p, unsigned c, struct ifa *ad)
29 c5ffa447 Martin Mares
{
30 31b3e1bb Martin Mares
  struct rt_dev_config *P = (void *) p->cf;
31 50d8424a Martin Mares
32 8edf2361 Martin Mares
  if (!EMPTY_LIST(P->iface_list) &&
33 0aad2b92 Ondrej Zajicek
      !iface_patt_find(&P->iface_list, ad->iface, ad->iface->addr))
34 8edf2361 Martin Mares
    /* Empty list is automagically treated as "*" */
35 50d8424a Martin Mares
    return;
36 ff2857b0 Ondrej Zajicek
37 92f8878c Ondrej Zajicek
  if (ad->flags & IA_SECONDARY)
38
    return;
39 ff2857b0 Ondrej Zajicek
40
  if (ad->scope <= SCOPE_LINK)
41
    return;
42
43 b1e4f814 Martin Mares
  if (c & IF_CHANGE_DOWN)
44
    {
45
      net *n;
46
47 9a158361 Martin Mares
      DBG("dev_if_notify: %s:%I going down\n", ad->iface->name, ad->ip);
48
      n = net_find(p->table, ad->prefix, ad->pxlen);
49 b1e4f814 Martin Mares
      if (!n)
50
        {
51 6b9fa320 Martin Mares
          DBG("dev_if_notify: device shutdown: prefix not found\n");
52 b1e4f814 Martin Mares
          return;
53
        }
54 ab4da342 Ondrej Zajicek
55
      /* Use iface ID as local source ID */
56
      struct rte_src *src = rt_get_source(p, ad->iface->index);
57
      rte_update2(p->main_ahook, n, NULL, src);
58 b1e4f814 Martin Mares
    }
59
  else if (c & IF_CHANGE_UP)
60
    {
61 094d2bdb Ondrej Zajicek
      rta *a;
62 b1e4f814 Martin Mares
      net *n;
63
      rte *e;
64
65 6b9fa320 Martin Mares
      DBG("dev_if_notify: %s:%I going up\n", ad->iface->name, ad->ip);
66 094d2bdb Ondrej Zajicek
67 ab4da342 Ondrej Zajicek
      /* Use iface ID as local source ID */
68
      struct rte_src *src = rt_get_source(p, ad->iface->index);
69
70 094d2bdb Ondrej Zajicek
      rta a0 = {
71 ab4da342 Ondrej Zajicek
        .src = src,
72 094d2bdb Ondrej Zajicek
        .source = RTS_DEVICE,
73
        .scope = SCOPE_UNIVERSE,
74
        .cast = RTC_UNICAST,
75
        .dest = RTD_DEVICE,
76
        .iface = ad->iface
77
      };
78
79
      a = rta_lookup(&a0);
80 6a636392 Martin Mares
      n = net_get(p->table, ad->prefix, ad->pxlen);
81 b1e4f814 Martin Mares
      e = rte_get_temp(a);
82 a0762910 Martin Mares
      e->net = n;
83 b1e4f814 Martin Mares
      e->pflags = 0;
84 ab4da342 Ondrej Zajicek
      rte_update2(p->main_ahook, n, e, src);
85 b1e4f814 Martin Mares
    }
86 c5ffa447 Martin Mares
}
87
88 31b3e1bb Martin Mares
static struct proto *
89
dev_init(struct proto_config *c)
90 c5ffa447 Martin Mares
{
91 31b3e1bb Martin Mares
  struct proto *p = proto_new(c, sizeof(struct proto));
92 c5ffa447 Martin Mares
93 9a158361 Martin Mares
  p->ifa_notify = dev_ifa_notify;
94 31b3e1bb Martin Mares
  return p;
95 c5ffa447 Martin Mares
}
96
97 88dc89f9 Martin Mares
static int
98
dev_reconfigure(struct proto *p, struct proto_config *new)
99
{
100
  struct rt_dev_config *o = (struct rt_dev_config *) p->cf;
101
  struct rt_dev_config *n = (struct rt_dev_config *) new;
102 2bbc3083 Ondrej Zajicek
103 88dc89f9 Martin Mares
  return iface_patts_equal(&o->iface_list, &n->iface_list, NULL);
104
}
105
106 a7f23f58 Ondrej Zajicek
static void
107
dev_copy_config(struct proto_config *dest, struct proto_config *src)
108
{
109
  struct rt_dev_config *d = (struct rt_dev_config *) dest;
110
  struct rt_dev_config *s = (struct rt_dev_config *) src;
111
112
  /*
113
   * We copy iface_list as ifaces can be shared by more direct protocols.
114
   * Copy suffices to be is shallow, because new nodes can be added, but
115
   * old nodes cannot be modified (although they contain internal lists).
116
   */
117
  cfg_copy_list(&d->iface_list, &s->iface_list, sizeof(struct iface_patt));
118
}
119
120 c5ffa447 Martin Mares
struct protocol proto_device = {
121 4a591d4b Pavel Tvrdik
  .name =                 "Direct",
122
  .template =                 "direct%d",
123
  .preference =         DEF_PREF_DIRECT,
124 2bbc3083 Ondrej Zajicek
  .config_size =        sizeof(struct rt_dev_config),
125 4a591d4b Pavel Tvrdik
  .init =                 dev_init,
126
  .reconfigure =         dev_reconfigure,
127
  .copy_config =         dev_copy_config
128 c5ffa447 Martin Mares
};