Annotation of embedaddon/bird/nest/rt-dev.c, revision 1.1.1.1
1.1 misho 1: /*
2: * BIRD -- Direct Device Routes
3: *
4: * (c) 1998--2000 Martin Mares <mj@ucw.cz>
5: *
6: * Can be freely distributed and used under the terms of the GNU GPL.
7: */
8:
9: /**
10: * DOC: Direct
11: *
12: * The Direct protocol works by converting all ifa_notify() events it receives
13: * to rte_update() calls for the corresponding network.
14: */
15:
16: #undef LOCAL_DEBUG
17:
18: #include "nest/bird.h"
19: #include "nest/iface.h"
20: #include "nest/protocol.h"
21: #include "nest/route.h"
22: #include "nest/rt-dev.h"
23: #include "conf/conf.h"
24: #include "lib/resource.h"
25: #include "lib/string.h"
26:
27: static void
28: dev_ifa_notify(struct proto *p, unsigned c, struct ifa *ad)
29: {
30: struct rt_dev_config *P = (void *) p->cf;
31:
32: if (!EMPTY_LIST(P->iface_list) &&
33: !iface_patt_find(&P->iface_list, ad->iface, ad->iface->addr))
34: /* Empty list is automagically treated as "*" */
35: return;
36:
37: if (ad->flags & IA_SECONDARY)
38: return;
39:
40: if (ad->scope <= SCOPE_LINK)
41: return;
42:
43: if (c & IF_CHANGE_DOWN)
44: {
45: net *n;
46:
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);
49: if (!n)
50: {
51: DBG("dev_if_notify: device shutdown: prefix not found\n");
52: return;
53: }
54:
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: }
59: else if (c & IF_CHANGE_UP)
60: {
61: rta *a;
62: net *n;
63: rte *e;
64:
65: DBG("dev_if_notify: %s:%I going up\n", ad->iface->name, ad->ip);
66:
67: if (P->check_link && !(ad->iface->flags & IF_LINK_UP))
68: return;
69:
70: /* Use iface ID as local source ID */
71: struct rte_src *src = rt_get_source(p, ad->iface->index);
72:
73: rta a0 = {
74: .src = src,
75: .source = RTS_DEVICE,
76: .scope = SCOPE_UNIVERSE,
77: .cast = RTC_UNICAST,
78: .dest = RTD_DEVICE,
79: .iface = ad->iface
80: };
81:
82: a = rta_lookup(&a0);
83: n = net_get(p->table, ad->prefix, ad->pxlen);
84: e = rte_get_temp(a);
85: e->net = n;
86: e->pflags = 0;
87: rte_update2(p->main_ahook, n, e, src);
88: }
89: }
90:
91: static void
92: dev_if_notify(struct proto *p, uint c, struct iface *iface)
93: {
94: struct rt_dev_config *cf = (void *) p->cf;
95:
96: if (c & (IF_CHANGE_UP | IF_CHANGE_DOWN))
97: return;
98:
99: if ((c & IF_CHANGE_LINK) && cf->check_link)
100: {
101: uint ac = (iface->flags & IF_LINK_UP) ? IF_CHANGE_UP : IF_CHANGE_DOWN;
102:
103: struct ifa *a;
104: WALK_LIST(a, iface->addrs)
105: dev_ifa_notify(p, ac, a);
106: }
107: }
108:
109:
110: static struct proto *
111: dev_init(struct proto_config *c)
112: {
113: struct proto *p = proto_new(c, sizeof(struct proto));
114:
115: p->if_notify = dev_if_notify;
116: p->ifa_notify = dev_ifa_notify;
117: return p;
118: }
119:
120: static int
121: dev_reconfigure(struct proto *p, struct proto_config *new)
122: {
123: struct rt_dev_config *o = (struct rt_dev_config *) p->cf;
124: struct rt_dev_config *n = (struct rt_dev_config *) new;
125:
126: return iface_patts_equal(&o->iface_list, &n->iface_list, NULL) &&
127: (o->check_link == n->check_link);
128: }
129:
130: static void
131: dev_copy_config(struct proto_config *dest, struct proto_config *src)
132: {
133: struct rt_dev_config *d = (struct rt_dev_config *) dest;
134: struct rt_dev_config *s = (struct rt_dev_config *) src;
135:
136: /*
137: * We copy iface_list as ifaces can be shared by more direct protocols.
138: * Copy suffices to be is shallow, because new nodes can be added, but
139: * old nodes cannot be modified (although they contain internal lists).
140: */
141: cfg_copy_list(&d->iface_list, &s->iface_list, sizeof(struct iface_patt));
142:
143: d->check_link = s->check_link;
144: }
145:
146: struct protocol proto_device = {
147: .name = "Direct",
148: .template = "direct%d",
149: .preference = DEF_PREF_DIRECT,
150: .config_size = sizeof(struct rt_dev_config),
151: .init = dev_init,
152: .reconfigure = dev_reconfigure,
153: .copy_config = dev_copy_config
154: };
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>