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