]>
git.ipfire.org Git - thirdparty/bird.git/blob - nest/rt-dev.c
2 * BIRD -- Direct Device Routes
4 * (c) 1998--2000 Martin Mares <mj@ucw.cz>
6 * Can be freely distributed and used under the terms of the GNU GPL.
12 * The Direct protocol works by converting all ifa_notify() events it receives
13 * to rte_update() calls for the corresponding network.
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"
28 dev_ifa_notify(struct proto
*p
, unsigned c
, struct ifa
*ad
)
30 struct rt_dev_config
*P
= (void *) p
->cf
;
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 "*" */
37 if (ad
->flags
& IA_SECONDARY
)
40 if (ad
->scope
<= SCOPE_LINK
)
43 if (c
& IF_CHANGE_DOWN
)
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
);
51 DBG("dev_if_notify: device shutdown: prefix not found\n");
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
);
59 else if (c
& IF_CHANGE_UP
)
65 DBG("dev_if_notify: %s:%I going up\n", ad
->iface
->name
, ad
->ip
);
67 if (P
->check_link
&& !(ad
->iface
->flags
& IF_LINK_UP
))
70 /* Use iface ID as local source ID */
71 struct rte_src
*src
= rt_get_source(p
, ad
->iface
->index
);
76 .scope
= SCOPE_UNIVERSE
,
83 n
= net_get(p
->table
, ad
->prefix
, ad
->pxlen
);
87 rte_update2(p
->main_ahook
, n
, e
, src
);
92 dev_if_notify(struct proto
*p
, uint c
, struct iface
*iface
)
94 struct rt_dev_config
*cf
= (void *) p
->cf
;
96 if (c
& (IF_CHANGE_UP
| IF_CHANGE_DOWN
))
99 if ((c
& IF_CHANGE_LINK
) && cf
->check_link
)
101 uint ac
= (iface
->flags
& IF_LINK_UP
) ? IF_CHANGE_UP
: IF_CHANGE_DOWN
;
104 WALK_LIST(a
, iface
->addrs
)
105 dev_ifa_notify(p
, ac
, a
);
110 static struct proto
*
111 dev_init(struct proto_config
*c
)
113 struct proto
*p
= proto_new(c
, sizeof(struct proto
));
115 p
->if_notify
= dev_if_notify
;
116 p
->ifa_notify
= dev_ifa_notify
;
121 dev_reconfigure(struct proto
*p
, struct proto_config
*new)
123 struct rt_dev_config
*o
= (struct rt_dev_config
*) p
->cf
;
124 struct rt_dev_config
*n
= (struct rt_dev_config
*) new;
126 return iface_patts_equal(&o
->iface_list
, &n
->iface_list
, NULL
) &&
127 (o
->check_link
== n
->check_link
);
131 dev_copy_config(struct proto_config
*dest
, struct proto_config
*src
)
133 struct rt_dev_config
*d
= (struct rt_dev_config
*) dest
;
134 struct rt_dev_config
*s
= (struct rt_dev_config
*) src
;
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).
141 cfg_copy_list(&d
->iface_list
, &s
->iface_list
, sizeof(struct iface_patt
));
143 d
->check_link
= s
->check_link
;
146 struct protocol proto_device
= {
148 .template = "direct%d",
149 .preference
= DEF_PREF_DIRECT
,
150 .config_size
= sizeof(struct rt_dev_config
),
152 .reconfigure
= dev_reconfigure
,
153 .copy_config
= dev_copy_config