]>
Commit | Line | Data |
---|---|---|
58ef912c MM |
1 | /* |
2 | * BIRD Internet Routing Daemon -- Protocols | |
3 | * | |
7293c5dd | 4 | * (c) 1998--2000 Martin Mares <mj@ucw.cz> |
58ef912c MM |
5 | * |
6 | * Can be freely distributed and used under the terms of the GNU GPL. | |
7 | */ | |
8 | ||
9 | #ifndef _BIRD_PROTOCOL_H_ | |
10 | #define _BIRD_PROTOCOL_H_ | |
11 | ||
2326b001 | 12 | #include "lib/lists.h" |
1feea03e | 13 | #include "lib/resource.h" |
f4a60a9b | 14 | #include "lib/event.h" |
f4a60a9b | 15 | #include "nest/route.h" |
4cdd0784 | 16 | #include "conf/conf.h" |
58ef912c | 17 | |
2326b001 | 18 | struct iface; |
9a158361 | 19 | struct ifa; |
dca75fd7 | 20 | struct rtable; |
2326b001 MM |
21 | struct rte; |
22 | struct neighbor; | |
1b769b08 | 23 | struct rta; |
8c43696d | 24 | struct network; |
31b3e1bb | 25 | struct proto_config; |
f4a60a9b OZ |
26 | struct channel_limit; |
27 | struct channel_config; | |
31b3e1bb MM |
28 | struct config; |
29 | struct proto; | |
f4a60a9b | 30 | struct channel; |
bb027be1 | 31 | struct ea_list; |
3991d84e | 32 | struct eattr; |
ae97b946 | 33 | struct symbol; |
2326b001 | 34 | |
f4a60a9b | 35 | |
58ef912c MM |
36 | /* |
37 | * Routing Protocol | |
38 | */ | |
39 | ||
ee7e2ffd JMM |
40 | enum protocol_class { |
41 | PROTOCOL_NONE, | |
42 | PROTOCOL_BABEL, | |
43 | PROTOCOL_BFD, | |
44 | PROTOCOL_BGP, | |
45 | PROTOCOL_DEVICE, | |
46 | PROTOCOL_DIRECT, | |
47 | PROTOCOL_KERNEL, | |
48 | PROTOCOL_OSPF, | |
863ecfc7 | 49 | PROTOCOL_MRT, |
82b74253 | 50 | PROTOCOL_PERF, |
ee7e2ffd JMM |
51 | PROTOCOL_PIPE, |
52 | PROTOCOL_RADV, | |
53 | PROTOCOL_RIP, | |
54 | PROTOCOL_RPKI, | |
55 | PROTOCOL_STATIC, | |
56 | PROTOCOL__MAX | |
57 | }; | |
58 | ||
59 | extern struct protocol *class_to_protocol[PROTOCOL__MAX]; | |
60 | ||
58ef912c | 61 | struct protocol { |
a5f1a60e | 62 | node n; |
58ef912c | 63 | char *name; |
d272fe22 | 64 | char *template; /* Template for automatic generation of names */ |
4ba84ebc | 65 | int name_counter; /* Counter for automatic name generation */ |
ee7e2ffd | 66 | enum protocol_class class; /* Machine readable protocol class */ |
2bbc3083 | 67 | uint preference; /* Default protocol preference */ |
f4a60a9b OZ |
68 | uint channel_mask; /* Mask of accepted channel types (NB_*) */ |
69 | uint proto_size; /* Size of protocol data structure */ | |
70 | uint config_size; /* Size of protocol config data structure */ | |
58ef912c | 71 | |
31b3e1bb MM |
72 | void (*preconfig)(struct protocol *, struct config *); /* Just before configuring */ |
73 | void (*postconfig)(struct proto_config *); /* After configuring each instance */ | |
74 | struct proto * (*init)(struct proto_config *); /* Create new instance */ | |
50fe90ed | 75 | int (*reconfigure)(struct proto *, struct proto_config *); /* Try to reconfigure instance, returns success */ |
31b3e1bb | 76 | void (*dump)(struct proto *); /* Debugging dump */ |
69ec9087 | 77 | void (*dump_attrs)(struct rte *); /* Dump protocol-dependent attributes */ |
31b3e1bb MM |
78 | int (*start)(struct proto *); /* Start the instance */ |
79 | int (*shutdown)(struct proto *); /* Stop the instance */ | |
cfe34a31 | 80 | void (*cleanup)(struct proto *); /* Called after shutdown when protocol became hungry/down */ |
9685deb9 | 81 | void (*get_status)(struct proto *, byte *buf); /* Get instance status (for `show protocols' command) */ |
13c0be19 | 82 | void (*get_route_info)(struct rte *, byte *buf); /* Get route information (for `show route' command) */ |
aebe06b4 | 83 | int (*get_attr)(struct eattr *, byte *buf, int buflen); /* ASCIIfy dynamic attribute (returns GA_*) */ |
b8113a5e | 84 | void (*show_proto_info)(struct proto *); /* Show protocol info (for `show protocols all' command) */ |
a7f23f58 | 85 | void (*copy_config)(struct proto_config *, struct proto_config *); /* Copy config from given protocol instance */ |
58ef912c MM |
86 | }; |
87 | ||
0432c017 | 88 | void protos_build(void); |
3991d84e | 89 | void proto_build(struct protocol *); |
31b3e1bb | 90 | void protos_preconfig(struct config *); |
bf1aec97 | 91 | void protos_commit(struct config *new, struct config *old, int force_restart, int type); |
e0835db4 | 92 | struct proto * proto_spawn(struct proto_config *cf, uint disabled); |
87d2be86 | 93 | void protos_dump_all(void); |
a5f1a60e | 94 | |
3991d84e MM |
95 | #define GA_UNKNOWN 0 /* Attribute not recognized */ |
96 | #define GA_NAME 1 /* Result = name */ | |
97 | #define GA_FULL 2 /* Result = both name and value */ | |
58ef912c MM |
98 | |
99 | /* | |
100 | * Known protocols | |
101 | */ | |
102 | ||
2638249d | 103 | extern struct protocol |
863ecfc7 | 104 | proto_device, proto_radv, proto_rip, proto_static, proto_mrt, |
82b74253 MM |
105 | proto_ospf, proto_perf, |
106 | proto_pipe, proto_bgp, proto_bfd, proto_babel, proto_rpki; | |
58ef912c MM |
107 | |
108 | /* | |
109 | * Routing Protocol Instance | |
110 | */ | |
111 | ||
31b3e1bb MM |
112 | struct proto_config { |
113 | node n; | |
114 | struct config *global; /* Global configuration data */ | |
1d2664a4 MM |
115 | struct protocol *protocol; /* Protocol */ |
116 | struct proto *proto; /* Instance we've created */ | |
e0835db4 | 117 | struct proto_config *parent; /* Parent proto_config for dynamic protocols */ |
31b3e1bb | 118 | char *name; |
e04555c0 | 119 | char *dsc; |
a7f23f58 | 120 | int class; /* SYM_PROTO or SYM_TEMPLATE */ |
f4a60a9b OZ |
121 | u8 net_type; /* Protocol network type (NET_*), 0 for undefined */ |
122 | u8 disabled; /* Protocol enabled/disabled by default */ | |
cf31112f | 123 | u32 debug, mrtdump; /* Debugging bitfields, both use D_* constants */ |
4cdd0784 | 124 | u32 router_id; /* Protocol specific router ID */ |
f4a60a9b OZ |
125 | |
126 | list channels; /* List of channel configs (struct channel_config) */ | |
943478b0 | 127 | struct iface *vrf; /* Related VRF instance, NULL if global */ |
31b3e1bb | 128 | |
a7f23f58 OZ |
129 | /* Check proto_reconfigure() and proto_copy_config() after changing struct proto_config */ |
130 | ||
31b3e1bb MM |
131 | /* Protocol-specific data follow... */ |
132 | }; | |
133 | ||
ebecb6f6 | 134 | /* Protocol statistics */ |
925fe2d3 OZ |
135 | struct proto_stats { |
136 | /* Import - from protocol to core */ | |
137 | u32 imp_routes; /* Number of routes successfully imported to the (adjacent) routing table */ | |
15550957 | 138 | u32 filt_routes; /* Number of routes rejected in import filter but kept in the routing table */ |
e1c275d8 | 139 | u32 pref_routes; /* Number of routes selected as best in the (adjacent) routing table */ |
925fe2d3 OZ |
140 | u32 imp_updates_received; /* Number of route updates received */ |
141 | u32 imp_updates_invalid; /* Number of route updates rejected as invalid */ | |
142 | u32 imp_updates_filtered; /* Number of route updates rejected by filters */ | |
143 | u32 imp_updates_ignored; /* Number of route updates rejected as already in route table */ | |
144 | u32 imp_updates_accepted; /* Number of route updates accepted and imported */ | |
145 | u32 imp_withdraws_received; /* Number of route withdraws received */ | |
146 | u32 imp_withdraws_invalid; /* Number of route withdraws rejected as invalid */ | |
147 | u32 imp_withdraws_ignored; /* Number of route withdraws rejected as already not in route table */ | |
148 | u32 imp_withdraws_accepted; /* Number of route withdraws accepted and processed */ | |
149 | ||
150 | /* Export - from core to protocol */ | |
151 | u32 exp_routes; /* Number of routes successfully exported to the protocol */ | |
152 | u32 exp_updates_received; /* Number of route updates received */ | |
153 | u32 exp_updates_rejected; /* Number of route updates rejected by protocol */ | |
154 | u32 exp_updates_filtered; /* Number of route updates rejected by filters */ | |
2bbc3083 | 155 | u32 exp_updates_accepted; /* Number of route updates accepted and exported */ |
925fe2d3 OZ |
156 | u32 exp_withdraws_received; /* Number of route withdraws received */ |
157 | u32 exp_withdraws_accepted; /* Number of route withdraws accepted and processed */ | |
158 | }; | |
159 | ||
58ef912c | 160 | struct proto { |
f4a60a9b | 161 | node n; /* Node in global proto_list */ |
58ef912c | 162 | struct protocol *proto; /* Protocol */ |
31b3e1bb | 163 | struct proto_config *cf; /* Configuration data */ |
50fe90ed | 164 | struct proto_config *cf_new; /* Configuration we want to switch to after shutdown (NULL=delete) */ |
31b3e1bb | 165 | pool *pool; /* Pool containing local objects */ |
f4a60a9b OZ |
166 | event *event; /* Protocol event */ |
167 | ||
168 | list channels; /* List of channels to rtables (struct channel) */ | |
169 | struct channel *main_channel; /* Primary channel */ | |
170 | struct rte_src *main_source; /* Primary route source */ | |
46434a3c | 171 | struct iface *vrf; /* Related VRF instance, NULL if global */ |
31b3e1bb | 172 | |
64011f89 | 173 | char *name; /* Name of this instance (== cf->name) */ |
cf31112f OZ |
174 | u32 debug; /* Debugging flags */ |
175 | u32 mrtdump; /* MRTDump flags */ | |
f4a60a9b OZ |
176 | uint active_channels; /* Number of active channels */ |
177 | byte net_type; /* Protocol network type (NET_*), 0 for undefined */ | |
ebecb6f6 OZ |
178 | byte disabled; /* Manually disabled */ |
179 | byte proto_state; /* Protocol state machine (PS_*, see below) */ | |
f4a60a9b OZ |
180 | byte active; /* From PS_START to cleanup after PS_STOP */ |
181 | byte do_start; /* Start actions are scheduled */ | |
182 | byte do_stop; /* Stop actions are scheduled */ | |
ebecb6f6 | 183 | byte reconfiguring; /* We're shutting down due to reconfiguration */ |
0c791f87 | 184 | byte gr_recovery; /* Protocol should participate in graceful restart recovery */ |
ebecb6f6 OZ |
185 | byte down_sched; /* Shutdown is scheduled for later (PDS_*) */ |
186 | byte down_code; /* Reason for shutdown (PDC_* codes) */ | |
7293c5dd | 187 | u32 hash_key; /* Random key used for hashing of neighbors */ |
f047271c | 188 | btime last_state_change; /* Time of last state transition */ |
df9f0fb3 | 189 | char *last_state_name_announced; /* Last state name we've announced to the user */ |
cd1d9961 | 190 | char *message; /* State-change message, allocated from proto_pool */ |
58ef912c | 191 | |
9e0e485e MM |
192 | /* |
193 | * General protocol hooks: | |
194 | * | |
195 | * if_notify Notify protocol about interface state changes. | |
9a158361 | 196 | * ifa_notify Notify protocol about interface address changes. |
9e0e485e MM |
197 | * rt_notify Notify protocol about routing table updates. |
198 | * neigh_notify Notify protocol about neighbor cache events. | |
875cc073 OZ |
199 | * make_tmp_attrs Add attributes to rta from from private attrs stored in rte. The route and rta MUST NOT be cached. |
200 | * store_tmp_attrs Store private attrs back to rte and undef added attributes. The route and rta MUST NOT be cached. | |
14375237 | 201 | * preexport Called as the first step of the route exporting process. |
9e0e485e | 202 | * It can construct a new rte, add private attributes and |
14375237 JMM |
203 | * decide whether the route shall be exported: 1=yes, -1=no, |
204 | * 0=process it through the export filter set by the user. | |
f4a60a9b | 205 | * reload_routes Request channel to reload all its routes to the core |
bf47fe4b OZ |
206 | * (using rte_update()). Returns: 0=reload cannot be done, |
207 | * 1= reload is scheduled and will happen (asynchronously). | |
f4a60a9b OZ |
208 | * feed_begin Notify channel about beginning of route feeding. |
209 | * feed_end Notify channel about finish of route feeding. | |
9e0e485e MM |
210 | */ |
211 | ||
9a158361 MM |
212 | void (*if_notify)(struct proto *, unsigned flags, struct iface *i); |
213 | void (*ifa_notify)(struct proto *, unsigned flags, struct ifa *a); | |
13c0be19 | 214 | void (*rt_notify)(struct proto *, struct channel *, struct network *net, struct rte *new, struct rte *old); |
4cc78c50 | 215 | void (*neigh_notify)(struct neighbor *neigh); |
875cc073 OZ |
216 | void (*make_tmp_attrs)(struct rte *rt, struct linpool *pool); |
217 | void (*store_tmp_attrs)(struct rte *rt, struct linpool *pool); | |
14375237 | 218 | int (*preexport)(struct proto *, struct rte **rt, struct linpool *pool); |
f4a60a9b OZ |
219 | void (*reload_routes)(struct channel *); |
220 | void (*feed_begin)(struct channel *, int initial); | |
221 | void (*feed_end)(struct channel *); | |
9e0e485e MM |
222 | |
223 | /* | |
094d2bdb | 224 | * Routing entry hooks (called only for routes belonging to this protocol): |
9e0e485e | 225 | * |
2bbc3083 | 226 | * rte_recalculate Called at the beginning of the best route selection |
9e0e485e | 227 | * rte_better Compare two rte's and decide which one is better (1=first, 0=second). |
67be5b23 | 228 | * rte_same Compare two rte's and decide whether they are identical (1=yes, 0=no). |
8d9eef17 | 229 | * rte_mergable Compare two rte's and decide whether they could be merged (1=yes, 0=no). |
9e0e485e MM |
230 | * rte_insert Called whenever a rte is inserted to a routing table. |
231 | * rte_remove Called whenever a rte is removed from the routing table. | |
232 | */ | |
58ef912c | 233 | |
be4cd99a | 234 | int (*rte_recalculate)(struct rtable *, struct network *, struct rte *, struct rte *, struct rte *); |
2326b001 | 235 | int (*rte_better)(struct rte *, struct rte *); |
67be5b23 | 236 | int (*rte_same)(struct rte *, struct rte *); |
8d9eef17 | 237 | int (*rte_mergable)(struct rte *, struct rte *); |
5bd73431 | 238 | struct rte * (*rte_modify)(struct rte *, struct linpool *); |
acc62f5e MM |
239 | void (*rte_insert)(struct network *, struct rte *); |
240 | void (*rte_remove)(struct network *, struct rte *); | |
2326b001 | 241 | |
58ef912c MM |
242 | /* Hic sunt protocol-specific data */ |
243 | }; | |
244 | ||
e304fd4b OZ |
245 | struct proto_spec { |
246 | void *ptr; | |
247 | int patt; | |
248 | }; | |
249 | ||
250 | ||
ebecb6f6 OZ |
251 | #define PDS_DISABLE 1 /* Proto disable scheduled */ |
252 | #define PDS_RESTART 2 /* Proto restart scheduled */ | |
253 | ||
254 | #define PDC_CF_REMOVE 0x01 /* Removed in new config */ | |
255 | #define PDC_CF_DISABLE 0x02 /* Disabled in new config */ | |
256 | #define PDC_CF_RESTART 0x03 /* Restart due to reconfiguration */ | |
257 | #define PDC_CMD_DISABLE 0x11 /* Result of disable command */ | |
258 | #define PDC_CMD_RESTART 0x12 /* Result of restart command */ | |
5400c0e7 | 259 | #define PDC_CMD_SHUTDOWN 0x13 /* Result of global shutdown */ |
b662290f OZ |
260 | #define PDC_RX_LIMIT_HIT 0x21 /* Route receive limit reached */ |
261 | #define PDC_IN_LIMIT_HIT 0x22 /* Route import limit reached */ | |
262 | #define PDC_OUT_LIMIT_HIT 0x23 /* Route export limit reached */ | |
ebecb6f6 OZ |
263 | |
264 | ||
f4a60a9b | 265 | void *proto_new(struct proto_config *); |
2bbc3083 | 266 | void *proto_config_new(struct protocol *, int class); |
a7f23f58 | 267 | void proto_copy_config(struct proto_config *dest, struct proto_config *src); |
e0835db4 | 268 | void proto_clone_config(struct symbol *sym, struct proto_config *parent); |
cd1d9961 | 269 | void proto_set_message(struct proto *p, char *msg, int len); |
a7f23f58 | 270 | |
0c791f87 OZ |
271 | void graceful_restart_recovery(void); |
272 | void graceful_restart_init(void); | |
273 | void graceful_restart_show_status(void); | |
f4a60a9b OZ |
274 | void channel_graceful_restart_lock(struct channel *c); |
275 | void channel_graceful_restart_unlock(struct channel *c); | |
0c791f87 OZ |
276 | |
277 | #define DEFAULT_GR_WAIT 240 | |
c0adf7e9 | 278 | |
f4a60a9b OZ |
279 | void channel_show_limit(struct channel_limit *l, const char *dsc); |
280 | void channel_show_info(struct channel *c); | |
c0adf7e9 | 281 | |
cd1d9961 OZ |
282 | void proto_cmd_show(struct proto *, uintptr_t, int); |
283 | void proto_cmd_disable(struct proto *, uintptr_t, int); | |
284 | void proto_cmd_enable(struct proto *, uintptr_t, int); | |
285 | void proto_cmd_restart(struct proto *, uintptr_t, int); | |
286 | void proto_cmd_reload(struct proto *, uintptr_t, int); | |
287 | void proto_cmd_debug(struct proto *, uintptr_t, int); | |
288 | void proto_cmd_mrtdump(struct proto *, uintptr_t, int); | |
ae80a2de | 289 | |
cd1d9961 | 290 | void proto_apply_cmd(struct proto_spec ps, void (* cmd)(struct proto *, uintptr_t, int), int restricted, uintptr_t arg); |
02c1fbdd | 291 | struct proto *proto_get_named(struct symbol *, struct protocol *); |
e304fd4b OZ |
292 | |
293 | #define CMD_RELOAD 0 | |
294 | #define CMD_RELOAD_IN 1 | |
295 | #define CMD_RELOAD_OUT 2 | |
8a7fb885 | 296 | |
4cdd0784 OZ |
297 | static inline u32 |
298 | proto_get_router_id(struct proto_config *pc) | |
299 | { | |
300 | return pc->router_id ? pc->router_id : pc->global->router_id; | |
301 | } | |
302 | ||
f4a60a9b | 303 | |
d15b0b0a | 304 | extern pool *proto_pool; |
f4a60a9b | 305 | extern list proto_list; |
2326b001 | 306 | |
31b3e1bb MM |
307 | /* |
308 | * Each protocol instance runs two different state machines: | |
309 | * | |
310 | * [P] The protocol machine: (implemented inside protocol) | |
311 | * | |
312 | * DOWN ----> START | |
313 | * ^ | | |
314 | * | V | |
315 | * STOP <---- UP | |
316 | * | |
317 | * States: DOWN Protocol is down and it's waiting for the core | |
318 | * requesting protocol start. | |
319 | * START Protocol is waiting for connection with the rest | |
320 | * of the network and it's not willing to accept | |
321 | * packets. When it connects, it goes to UP state. | |
322 | * UP Protocol is up and running. When the network | |
323 | * connection breaks down or the core requests | |
324 | * protocol to be terminated, it goes to STOP state. | |
325 | * STOP Protocol is disconnecting from the network. | |
326 | * After it disconnects, it returns to DOWN state. | |
327 | * | |
328 | * In: start() Called in DOWN state to request protocol startup. | |
329 | * Returns new state: either UP or START (in this | |
330 | * case, the protocol will notify the core when it | |
331 | * finally comes UP). | |
332 | * stop() Called in START, UP or STOP state to request | |
333 | * protocol shutdown. Returns new state: either | |
334 | * DOWN or STOP (in this case, the protocol will | |
335 | * notify the core when it finally comes DOWN). | |
336 | * | |
337 | * Out: proto_notify_state() -- called by protocol instance when | |
338 | * it does any state transition not covered by | |
339 | * return values of start() and stop(). This includes | |
340 | * START->UP (delayed protocol startup), UP->STOP | |
341 | * (spontaneous shutdown) and STOP->DOWN (delayed | |
342 | * shutdown). | |
343 | */ | |
344 | ||
345 | #define PS_DOWN 0 | |
346 | #define PS_START 1 | |
347 | #define PS_UP 2 | |
348 | #define PS_STOP 3 | |
349 | ||
350 | void proto_notify_state(struct proto *p, unsigned state); | |
351 | ||
352 | /* | |
353 | * [F] The feeder machine: (implemented in core routines) | |
354 | * | |
355 | * HUNGRY ----> FEEDING | |
356 | * ^ | | |
a82f692e | 357 | * | V |
31b3e1bb MM |
358 | * FLUSHING <---- HAPPY |
359 | * | |
360 | * States: HUNGRY Protocol either administratively down (i.e., | |
361 | * disabled by the user) or temporarily down | |
362 | * (i.e., [P] is not UP) | |
363 | * FEEDING The protocol came up and we're feeding it | |
364 | * initial routes. [P] is UP. | |
365 | * HAPPY The protocol is up and it's receiving normal | |
366 | * routing updates. [P] is UP. | |
367 | * FLUSHING The protocol is down and we're removing its | |
368 | * routes from the table. [P] is STOP or DOWN. | |
369 | * | |
370 | * Normal lifecycle of a protocol looks like: | |
371 | * | |
372 | * HUNGRY/DOWN --> HUNGRY/START --> HUNGRY/UP --> | |
373 | * FEEDING/UP --> HAPPY/UP --> FLUSHING/STOP|DOWN --> | |
374 | * HUNGRY/STOP|DOWN --> HUNGRY/DOWN | |
bf47fe4b | 375 | * |
2bbc3083 | 376 | * Sometimes, protocol might switch from HAPPY/UP to FEEDING/UP |
bf47fe4b OZ |
377 | * if it wants to refeed the routes (for example BGP does so |
378 | * as a result of received ROUTE-REFRESH request). | |
31b3e1bb MM |
379 | */ |
380 | ||
0c791f87 | 381 | |
31b3e1bb | 382 | |
96d8e3bf MM |
383 | /* |
384 | * Debugging flags | |
385 | */ | |
386 | ||
387 | #define D_STATES 1 /* [core] State transitions */ | |
388 | #define D_ROUTES 2 /* [core] Routes passed by the filters */ | |
6a9f28b0 MM |
389 | #define D_FILTERS 4 /* [core] Routes rejected by the filters */ |
390 | #define D_IFACES 8 /* [core] Interface events */ | |
391 | #define D_EVENTS 16 /* Protocol events */ | |
392 | #define D_PACKETS 32 /* Packets sent/received */ | |
96d8e3bf | 393 | |
6a8d3f1c OZ |
394 | #ifndef PARSER |
395 | #define TRACE(flags, msg, args...) \ | |
396 | do { if (p->p.debug & flags) log(L_TRACE "%s: " msg, p->p.name , ## args ); } while(0) | |
397 | #endif | |
398 | ||
399 | ||
cf31112f OZ |
400 | /* |
401 | * MRTDump flags | |
402 | */ | |
403 | ||
404 | #define MD_STATES 1 /* Protocol state changes (BGP4MP_MESSAGE_AS4) */ | |
405 | #define MD_MESSAGES 2 /* Protocol packets (BGP4MP_MESSAGE_AS4) */ | |
406 | ||
50d8424a MM |
407 | /* |
408 | * Known unique protocol instances as referenced by config routines | |
409 | */ | |
410 | ||
31b3e1bb | 411 | extern struct proto_config *cf_dev_proto; |
50d8424a | 412 | |
ebecb6f6 OZ |
413 | |
414 | /* | |
415 | * Protocol limits | |
416 | */ | |
417 | ||
b662290f OZ |
418 | #define PLD_RX 0 /* Receive limit */ |
419 | #define PLD_IN 1 /* Import limit */ | |
420 | #define PLD_OUT 2 /* Export limit */ | |
421 | #define PLD_MAX 3 | |
422 | ||
f4a60a9b | 423 | #define PLA_NONE 0 /* No limit */ |
ebecb6f6 OZ |
424 | #define PLA_WARN 1 /* Issue log warning */ |
425 | #define PLA_BLOCK 2 /* Block new routes */ | |
426 | #define PLA_RESTART 4 /* Force protocol restart */ | |
427 | #define PLA_DISABLE 5 /* Shutdown and disable protocol */ | |
428 | ||
7d0a31de OZ |
429 | #define PLS_INITIAL 0 /* Initial limit state after protocol start */ |
430 | #define PLS_ACTIVE 1 /* Limit was hit */ | |
431 | #define PLS_BLOCKED 2 /* Limit is active and blocking new routes */ | |
432 | ||
f4a60a9b | 433 | struct channel_limit { |
ebecb6f6 | 434 | u32 limit; /* Maximum number of prefixes */ |
f4a60a9b OZ |
435 | u8 action; /* Action to take (PLA_*) */ |
436 | u8 state; /* State of limit (PLS_*) */ | |
ebecb6f6 OZ |
437 | }; |
438 | ||
f4a60a9b | 439 | void channel_notify_limit(struct channel *c, struct channel_limit *l, int dir, u32 rt_count); |
7d0a31de | 440 | |
2bbc3083 | 441 | |
0e02abfd | 442 | /* |
f4a60a9b | 443 | * Channels |
0e02abfd MM |
444 | */ |
445 | ||
f4a60a9b OZ |
446 | struct channel_class { |
447 | uint channel_size; /* Size of channel data structure */ | |
448 | uint config_size; /* Size of channel config data structure */ | |
449 | ||
d15b0b0a | 450 | void (*init)(struct channel *, struct channel_config *); /* Create new instance */ |
f4a60a9b OZ |
451 | int (*reconfigure)(struct channel *, struct channel_config *); /* Try to reconfigure instance, returns success */ |
452 | int (*start)(struct channel *); /* Start the instance */ | |
d15b0b0a OZ |
453 | void (*shutdown)(struct channel *); /* Stop the instance */ |
454 | void (*cleanup)(struct channel *); /* Channel finished flush */ | |
f4a60a9b OZ |
455 | |
456 | void (*copy_config)(struct channel_config *, struct channel_config *); /* Copy config from given channel instance */ | |
457 | #if 0 | |
d15b0b0a | 458 | XXXX; |
f4a60a9b OZ |
459 | void (*preconfig)(struct protocol *, struct config *); /* Just before configuring */ |
460 | void (*postconfig)(struct proto_config *); /* After configuring each instance */ | |
461 | ||
462 | ||
463 | void (*dump)(struct proto *); /* Debugging dump */ | |
464 | void (*dump_attrs)(struct rte *); /* Dump protocol-dependent attributes */ | |
d15b0b0a | 465 | |
f4a60a9b | 466 | void (*get_status)(struct proto *, byte *buf); /* Get instance status (for `show protocols' command) */ |
13c0be19 | 467 | void (*get_route_info)(struct rte *, byte *buf); /* Get route information (for `show route' command) */ |
f4a60a9b OZ |
468 | int (*get_attr)(struct eattr *, byte *buf, int buflen); /* ASCIIfy dynamic attribute (returns GA_*) */ |
469 | void (*show_proto_info)(struct proto *); /* Show protocol info (for `show protocols all' command) */ | |
470 | ||
471 | #endif | |
472 | }; | |
473 | ||
d15b0b0a OZ |
474 | extern struct channel_class channel_bgp; |
475 | ||
f4a60a9b | 476 | struct channel_config { |
0e02abfd | 477 | node n; |
f4a60a9b OZ |
478 | const char *name; |
479 | const struct channel_class *channel; | |
480 | ||
72163bd5 | 481 | struct proto_config *parent; /* Where channel is defined (proto or template) */ |
f4a60a9b OZ |
482 | struct rtable_config *table; /* Table we're attached to */ |
483 | struct filter *in_filter, *out_filter; /* Attached filters */ | |
484 | struct channel_limit rx_limit; /* Limit for receiving routes from protocol | |
485 | (relevant when in_keep_filtered is active) */ | |
486 | struct channel_limit in_limit; /* Limit for importing routes from protocol */ | |
487 | struct channel_limit out_limit; /* Limit for exporting routes to protocol */ | |
488 | ||
489 | u8 net_type; /* Routing table network type (NET_*), 0 for undefined */ | |
490 | u8 ra_mode; /* Mode of received route advertisements (RA_*) */ | |
491 | u16 preference; /* Default route preference */ | |
492 | u8 merge_limit; /* Maximal number of nexthops for RA_MERGED */ | |
493 | u8 in_keep_filtered; /* Routes rejected in import filter are kept */ | |
494 | }; | |
495 | ||
496 | struct channel { | |
497 | node n; /* Node in proto->channels */ | |
498 | node table_node; /* Node in table->channels */ | |
499 | ||
500 | const char *name; /* Channel name (may be NULL) */ | |
501 | const struct channel_class *channel; | |
0e02abfd | 502 | struct proto *proto; |
f4a60a9b OZ |
503 | |
504 | struct rtable *table; | |
c0adf7e9 OZ |
505 | struct filter *in_filter; /* Input filter */ |
506 | struct filter *out_filter; /* Output filter */ | |
f4a60a9b OZ |
507 | struct channel_limit rx_limit; /* Receive limit (for in_keep_filtered) */ |
508 | struct channel_limit in_limit; /* Input limit */ | |
509 | struct channel_limit out_limit; /* Output limit */ | |
510 | ||
511 | struct event *feed_event; /* Event responsible for feeding */ | |
512 | struct fib_iterator feed_fit; /* Routing table iterator used during feeding */ | |
513 | struct proto_stats stats; /* Per-channel protocol statistics */ | |
514 | ||
515 | u8 net_type; /* Routing table network type (NET_*), 0 for undefined */ | |
516 | u8 ra_mode; /* Mode of received route advertisements (RA_*) */ | |
517 | u16 preference; /* Default route preference */ | |
518 | u8 merge_limit; /* Maximal number of nexthops for RA_MERGED */ | |
519 | u8 in_keep_filtered; /* Routes rejected in import filter are kept */ | |
520 | u8 disabled; | |
d15b0b0a | 521 | u8 stale; /* Used in reconfiguration */ |
f4a60a9b OZ |
522 | |
523 | u8 channel_state; | |
524 | u8 export_state; /* Route export state (ES_*, see below) */ | |
525 | u8 feed_active; | |
526 | u8 flush_active; | |
527 | u8 refeeding; /* We are refeeding (valid only if export_state == ES_FEEDING) */ | |
528 | u8 reloadable; /* Hook reload_routes() is allowed on the channel */ | |
529 | u8 gr_lock; /* Graceful restart mechanism should wait for this channel */ | |
530 | u8 gr_wait; /* Route export to channel is postponed until graceful restart */ | |
531 | ||
f047271c | 532 | btime last_state_change; /* Time of last state transition */ |
a81e18da | 533 | btime last_tx_filter_change; |
682d3f7d OZ |
534 | |
535 | struct rtable *in_table; /* Internal table for received routes */ | |
536 | struct event *reload_event; /* Event responsible for reloading from in_table */ | |
537 | struct fib_iterator reload_fit; /* Iterator in in_table used during reloading */ | |
538 | u8 reload_active; /* Iterator reload_fit is linked */ | |
0e02abfd MM |
539 | }; |
540 | ||
f4a60a9b OZ |
541 | |
542 | /* | |
543 | * Channel states | |
544 | * | |
545 | * CS_DOWN - The initial and the final state of a channel. There is no route | |
546 | * exchange between the protocol and the table. Channel is not counted as | |
547 | * active. Channel keeps a ptr to the table, but do not lock the table and is | |
548 | * not linked in the table. Generally, new closed channels are created in | |
549 | * protocols' init() hooks. The protocol is expected to explicitly activate its | |
550 | * channels (by calling channel_init() or channel_open()). | |
551 | * | |
552 | * CS_START - The channel as a connection between the protocol and the table is | |
553 | * initialized (counted as active by the protocol, linked in the table and keeps | |
554 | * the table locked), but there is no current route exchange. There still may be | |
555 | * routes associated with the channel in the routing table if the channel falls | |
556 | * to CS_START from CS_UP. Generally, channels are initialized in protocols' | |
557 | * start() hooks when going to PS_START. | |
558 | * | |
559 | * CS_UP - The channel is initialized and the route exchange is allowed. Note | |
560 | * that even in CS_UP state, route export may still be down (ES_DOWN) by the | |
561 | * core decision (e.g. waiting for table convergence after graceful restart). | |
562 | * I.e., the protocol decides to open the channel but the core decides to start | |
563 | * route export. Route import (caused by rte_update() from the protocol) is not | |
564 | * restricted by that and is on volition of the protocol. Generally, channels | |
565 | * are opened in protocols' start() hooks when going to PS_UP. | |
566 | * | |
567 | * CS_FLUSHING - The transitional state between initialized channel and closed | |
568 | * channel. The channel is still initialized, but no route exchange is allowed. | |
569 | * Instead, the associated table is running flush loop to remove routes imported | |
570 | * through the channel. After that, the channel changes state to CS_DOWN and | |
571 | * is detached from the table (the table is unlocked and the channel is unlinked | |
572 | * from it). Unlike other states, the CS_FLUSHING state is not explicitly | |
573 | * entered or left by the protocol. A protocol may request to close a channel | |
574 | * (by calling channel_close()), which causes the channel to change state to | |
575 | * CS_FLUSHING and later to CS_DOWN. Also note that channels are closed | |
576 | * automatically by the core when the protocol is going down. | |
577 | * | |
578 | * Allowed transitions: | |
579 | * | |
580 | * CS_DOWN -> CS_START / CS_UP | |
581 | * CS_START -> CS_UP / CS_FLUSHING | |
582 | * CS_UP -> CS_START / CS_FLUSHING | |
583 | * CS_FLUSHING -> CS_DOWN (automatic) | |
584 | */ | |
585 | ||
586 | #define CS_DOWN 0 | |
587 | #define CS_START 1 | |
588 | #define CS_UP 2 | |
589 | #define CS_FLUSHING 3 | |
590 | ||
591 | #define ES_DOWN 0 | |
592 | #define ES_FEEDING 1 | |
593 | #define ES_READY 2 | |
594 | ||
595 | ||
596 | struct channel_config *proto_cf_find_channel(struct proto_config *p, uint net_type); | |
597 | static inline struct channel_config *proto_cf_main_channel(struct proto_config *pc) | |
598 | { struct channel_config *cc = HEAD(pc->channels); return NODE_VALID(cc) ? cc : NULL; } | |
599 | ||
600 | struct channel *proto_find_channel_by_table(struct proto *p, struct rtable *t); | |
b2949999 | 601 | struct channel *proto_find_channel_by_name(struct proto *p, const char *n); |
f4a60a9b OZ |
602 | struct channel *proto_add_channel(struct proto *p, struct channel_config *cf); |
603 | int proto_configure_channel(struct proto *p, struct channel **c, struct channel_config *cf); | |
604 | ||
605 | void channel_set_state(struct channel *c, uint state); | |
682d3f7d OZ |
606 | void channel_setup_in_table(struct channel *c); |
607 | void channel_schedule_reload(struct channel *c); | |
f4a60a9b | 608 | |
f4a60a9b OZ |
609 | static inline void channel_init(struct channel *c) { channel_set_state(c, CS_START); } |
610 | static inline void channel_open(struct channel *c) { channel_set_state(c, CS_UP); } | |
611 | static inline void channel_close(struct channel *c) { channel_set_state(c, CS_FLUSHING); } | |
f4a60a9b OZ |
612 | |
613 | void channel_request_feeding(struct channel *c); | |
72163bd5 OZ |
614 | void *channel_config_new(const struct channel_class *cc, const char *name, uint net_type, struct proto_config *proto); |
615 | void *channel_config_get(const struct channel_class *cc, const char *name, uint net_type, struct proto_config *proto); | |
f4a60a9b OZ |
616 | int channel_reconfigure(struct channel *c, struct channel_config *cf); |
617 | ||
c8387626 | 618 | |
682d3f7d OZ |
619 | /* Moved from route.h to avoid dependency conflicts */ |
620 | static inline void rte_update(struct proto *p, const net_addr *n, rte *new) { rte_update2(p->main_channel, n, new, p->main_source); } | |
621 | ||
622 | static inline void | |
623 | rte_update3(struct channel *c, const net_addr *n, rte *new, struct rte_src *src) | |
624 | { | |
625 | if (c->in_table && !rte_update_in(c, n, new, src)) | |
626 | return; | |
627 | ||
628 | rte_update2(c, n, new, src); | |
629 | } | |
630 | ||
631 | ||
58ef912c | 632 | #endif |