Statistics
| Branch: | Revision:

iof-bird-daemon / proto / static / static.c @ 08c69a77

History | View | Annotate | Download (3.33 KB)

1
/*
2
 *        BIRD -- Static Route Generator
3
 *
4
 *        (c) 1998 Martin Mares <mj@ucw.cz>
5
 *
6
 *        Can be freely distributed and used under the terms of the GNU GPL.
7
 */
8

    
9
#define LOCAL_DEBUG
10

    
11
#include <string.h>
12

    
13
#include "nest/bird.h"
14
#include "nest/iface.h"
15
#include "nest/protocol.h"
16
#include "nest/route.h"
17
#include "conf/conf.h"
18

    
19
#include "static.h"
20

    
21
#define GET_DATA struct static_proto *p = (struct static_proto *) P
22

    
23
static void
24
static_install(struct static_proto *p, struct static_route *r, struct iface *ifa)
25
{
26
  net *n;
27
  rta a, *aa;
28
  rte *e;
29

    
30
  DBG("Installing static route %I/%d, rtd=%d\n", r->net, r->masklen, r->dest);
31
  bzero(&a, sizeof(a));
32
  a.proto = &p->p;
33
  a.source = (r->dest == RTD_DEVICE) ? RTS_STATIC_DEVICE : RTS_STATIC;
34
  a.scope = SCOPE_UNIVERSE;
35
  a.cast = RTC_UNICAST;
36
  a.dest = r->dest;
37
  a.tos = 0;
38
  a.gw = r->via;
39
  a.iface = ifa;
40
  aa = rta_lookup(&a);
41

    
42
  n = net_get(&master_table, a.tos, r->net, r->masklen);
43
  e = rte_get_temp(aa);
44
  e->net = n;
45
  e->pflags = 0;
46
  rte_update(n, &p->p, e);
47
}
48

    
49
static void
50
static_remove(struct static_proto *p, struct static_route *r)
51
{
52
  net *n;
53

    
54
  DBG("Removing static route %I/%d\n", r->net, r->masklen);
55
  n = net_find(&master_table, 0, r->net, r->masklen);
56
  if (n)
57
    rte_update(n, &p->p, NULL);
58
}
59

    
60
static void
61
static_start(struct proto *P)
62
{
63
  GET_DATA;
64
  struct static_route *r;
65

    
66
  DBG("Static: take off!\n");
67
  WALK_LIST(r, p->other_routes)
68
    switch (r->dest)
69
      {
70
      case RTD_ROUTER:
71
        {
72
          struct neighbor *n = neigh_find(P, &r->via, NEF_STICKY);
73
          if (n)
74
            {
75
              r->chain = n->data;
76
              n->data = r;
77
              r->neigh = n;
78
              static_install(p, r, n->iface);
79
            }
80
          else
81
            log(L_ERR "Static route destination %I is invalid. Ignoring.\n", r->via);
82
          break;
83
        }
84
      case RTD_DEVICE:
85
        bug("Static device routes are not supported");
86
        /* FIXME: Static device routes */
87
      default:
88
        static_install(p, r, NULL);
89
      }
90
}
91

    
92
static void
93
static_neigh_notify(struct neighbor *n)
94
{
95
  struct static_proto *p = (struct static_proto *) n->proto;
96
  struct static_route *r;
97

    
98
  DBG("Static: neighbor notify for %I: iface %p\n", n->addr, n->iface);
99
  for(r=n->data; r; r=r->chain)
100
    if (n->iface)
101
      static_install(p, r, n->iface);
102
    else
103
      static_remove(p, r);
104
}
105

    
106
static void
107
static_dump_rt(struct static_route *r)
108
{
109
  debug("%16I/%2d: ", r->net, r->masklen);
110
  switch (r->dest)
111
    {
112
    case RTD_ROUTER:
113
      debug("via %I\n", r->via);
114
      break;
115
    case RTD_DEVICE:
116
      debug("dev %s\n", r->if_name);
117
      break;
118
    default:
119
      debug("rtd %d\n", r->dest);
120
      break;
121
    }
122
}
123

    
124
static void
125
static_dump(struct proto *P)
126
{
127
  GET_DATA;
128
  struct static_route *r;
129

    
130
  debug("Independent static routes:\n");
131
  WALK_LIST(r, p->other_routes)
132
    static_dump_rt(r);
133
  debug("Device static routes:\n");
134
  WALK_LIST(r, p->iface_routes)
135
    static_dump_rt(r);
136
}
137

    
138
void
139
static_init_instance(struct static_proto *P)
140
{
141
  struct proto *p = &P->p;
142

    
143
  p->preference = DEF_PREF_STATIC;
144
  p->start = static_start;
145
  p->neigh_notify = static_neigh_notify;
146
  p->dump = static_dump;
147
  init_list(&P->iface_routes);
148
  init_list(&P->other_routes);
149
}
150

    
151
static void
152
static_init(struct protocol *p)
153
{
154
}
155

    
156
static void
157
static_preconfig(struct protocol *x)
158
{
159
}
160

    
161
static void
162
static_postconfig(struct protocol *p)
163
{
164
}
165

    
166
struct protocol proto_static = {
167
  { NULL, NULL },
168
  "Static",
169
  0,
170
  static_init,
171
  static_preconfig,
172
  static_postconfig
173
};