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