1 /*
2 * BIRD Internet Routing Daemon -- Protocols
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 #ifndef _BIRD_PROTOCOL_H_
10 #define _BIRD_PROTOCOL_H_
11
12 #include "lib/lists.h"
13 #include "lib/resource.h"
14 #include "lib/timer.h"
15 #include "nest/route.h"
16 #include "conf/conf.h"
17
18 struct iface;
19 struct ifa;
20 struct rtable;
21 struct rte;
22 struct neighbor;
23 struct rta;
24 struct network;
25 struct proto_config;
26 struct config;
27 struct proto;
28 struct event;
29 struct ea_list;
30 struct eattr;
31 struct symbol;
32
33 /*
34 * Routing Protocol
35 */
36
37 struct protocol {
38 node n;
39 char *name;
40 char *template; /* Template for automatic generation of names */
41 int name_counter; /* Counter for automatic name generation */
42 int attr_class; /* Attribute class known to this protocol */
43 int multitable; /* Protocol handles all announce hooks itself */
44 uint preference; /* Default protocol preference */
45 uint config_size; /* Size of protocol config */
46
47 void (*preconfig)(struct protocol *, struct config *); /* Just before configuring */
48 void (*postconfig)(struct proto_config *); /* After configuring each instance */
49 struct proto * (*init)(struct proto_config *); /* Create new instance */
50 int (*reconfigure)(struct proto *, struct proto_config *); /* Try to reconfigure instance, returns success */
51 void (*dump)(struct proto *); /* Debugging dump */
52 void (*dump_attrs)(struct rte *); /* Dump protocol-dependent attributes */
53 int (*start)(struct proto *); /* Start the instance */
54 int (*shutdown)(struct proto *); /* Stop the instance */
55 void (*cleanup)(struct proto *); /* Called after shutdown when protocol became hungry/down */
56 void (*get_status)(struct proto *, byte *buf); /* Get instance status (for `show protocols' command) */
57 void (*get_route_info)(struct rte *, byte *buf, struct ea_list *attrs); /* Get route information (for `show route' command) */
58 int (*get_attr)(struct eattr *, byte *buf, int buflen); /* ASCIIfy dynamic attribute (returns GA_*) */
59 void (*show_proto_info)(struct proto *); /* Show protocol info (for `show protocols all' command) */
60 void (*copy_config)(struct proto_config *, struct proto_config *); /* Copy config from given protocol instance */
61 };
62
63 void protos_build(void);
64 void proto_build(struct protocol *);
65 void protos_preconfig(struct config *);
66 void protos_postconfig(struct config *);
67 void protos_commit(struct config *new, struct config *old, int force_restart, int type);
68 void protos_dump_all(void);
69
70 #define GA_UNKNOWN 0 /* Attribute not recognized */
71 #define GA_NAME 1 /* Result = name */
72 #define GA_FULL 2 /* Result = both name and value */
73
74 /*
75 * Known protocols
76 */
77
78 extern struct protocol
79 proto_device, proto_radv, proto_rip, proto_static, proto_mrt,
80 proto_ospf, proto_pipe, proto_bgp, proto_bfd, proto_babel;
81
82 /*
83 * Routing Protocol Instance
84 */
85
86 struct proto_config {
87 node n;
88 struct config *global; /* Global configuration data */
89 struct protocol *protocol; /* Protocol */
90 struct proto *proto; /* Instance we've created */
91 char *name;
92 char *dsc;
93 int class; /* SYM_PROTO or SYM_TEMPLATE */
94 u32 debug, mrtdump; /* Debugging bitfields, both use D_* constants */
95 unsigned preference, disabled; /* Generic parameters */
96 int vrf_set; /* Related VRF instance (below) is defined */
97 int in_keep_filtered; /* Routes rejected in import filter are kept */
98 u32 router_id; /* Protocol specific router ID */
99 struct iface *vrf; /* Related VRF instance, NULL if global */
100 struct rtable_config *table; /* Table we're attached to */
101 struct filter *in_filter, *out_filter; /* Attached filters */
102 struct proto_limit *rx_limit; /* Limit for receiving routes from protocol
103 (relevant when in_keep_filtered is active) */
104 struct proto_limit *in_limit; /* Limit for importing routes from protocol */
105 struct proto_limit *out_limit; /* Limit for exporting routes to protocol */
106
107 /* Check proto_reconfigure() and proto_copy_config() after changing struct proto_config */
108
109 /* Protocol-specific data follow... */
110 };
111
112 /* Protocol statistics */
113 struct proto_stats {
114 /* Import - from protocol to core */
115 u32 imp_routes; /* Number of routes successfully imported to the (adjacent) routing table */
116 u32 filt_routes; /* Number of routes rejected in import filter but kept in the routing table */
117 u32 pref_routes; /* Number of routes that are preferred, sum over all routing tables */
118 u32 imp_updates_received; /* Number of route updates received */
119 u32 imp_updates_invalid; /* Number of route updates rejected as invalid */
120 u32 imp_updates_filtered; /* Number of route updates rejected by filters */
121 u32 imp_updates_ignored; /* Number of route updates rejected as already in route table */
122 u32 imp_updates_accepted; /* Number of route updates accepted and imported */
123 u32 imp_withdraws_received; /* Number of route withdraws received */
124 u32 imp_withdraws_invalid; /* Number of route withdraws rejected as invalid */
125 u32 imp_withdraws_ignored; /* Number of route withdraws rejected as already not in route table */
126 u32 imp_withdraws_accepted; /* Number of route withdraws accepted and processed */
127
128 /* Export - from core to protocol */
129 u32 exp_routes; /* Number of routes successfully exported to the protocol */
130 u32 exp_updates_received; /* Number of route updates received */
131 u32 exp_updates_rejected; /* Number of route updates rejected by protocol */
132 u32 exp_updates_filtered; /* Number of route updates rejected by filters */
133 u32 exp_updates_accepted; /* Number of route updates accepted and exported */
134 u32 exp_withdraws_received; /* Number of route withdraws received */
135 u32 exp_withdraws_accepted; /* Number of route withdraws accepted and processed */
136 };
137
138 struct proto {
139 node n; /* Node in *_proto_list */
140 node glob_node; /* Node in global proto_list */
141 struct protocol *proto; /* Protocol */
142 struct proto_config *cf; /* Configuration data */
143 struct proto_config *cf_new; /* Configuration we want to switch to after shutdown (NULL=delete) */
144 pool *pool; /* Pool containing local objects */
145 struct event *attn; /* "Pay attention" event */
146
147 char *name; /* Name of this instance (== cf->name) */
148 u32 debug; /* Debugging flags */
149 u32 mrtdump; /* MRTDump flags */
150 unsigned preference; /* Default route preference */
151 byte accept_ra_types; /* Which types of route announcements are accepted (RA_OPTIMAL or RA_ANY) */
152 byte disabled; /* Manually disabled */
153 byte vrf_set; /* Related VRF instance (above) is defined */
154 byte proto_state; /* Protocol state machine (PS_*, see below) */
155 byte core_state; /* Core state machine (FS_*, see below) */
156 byte export_state; /* Route export state (ES_*, see below) */
157 byte reconfiguring; /* We're shutting down due to reconfiguration */
158 byte refeeding; /* We are refeeding (valid only if export_state == ES_FEEDING) */
159 byte flushing; /* Protocol is flushed in current flush loop round */
160 byte gr_recovery; /* Protocol should participate in graceful restart recovery */
161 byte gr_lock; /* Graceful restart mechanism should wait for this proto */
162 byte gr_wait; /* Route export to protocol is postponed until graceful restart */
163 byte down_sched; /* Shutdown is scheduled for later (PDS_*) */
164 byte down_code; /* Reason for shutdown (PDC_* codes) */
165 byte merge_limit; /* Maximal number of nexthops for RA_MERGED */
166 u32 hash_key; /* Random key used for hashing of neighbors */
167 bird_clock_t last_state_change; /* Time of last state transition */
168 char *last_state_name_announced; /* Last state name we've announced to the user */
169 char *message; /* State-change message, allocated from proto_pool */
170 struct proto_stats stats; /* Current protocol statistics */
171
172 /*
173 * General protocol hooks:
174 *
175 * if_notify Notify protocol about interface state changes.
176 * ifa_notify Notify protocol about interface address changes.
177 * rt_notify Notify protocol about routing table updates.
178 * neigh_notify Notify protocol about neighbor cache events.
179 * make_tmp_attrs Construct ea_list from private attrs stored in rte.
180 * store_tmp_attrs Store private attrs back to the rte.
181 * import_control Called as the first step of the route importing process.
182 * It can construct a new rte, add private attributes and
183 * decide whether the route shall be imported: 1=yes, -1=no,
184 * 0=process it through the import filter set by the user.
185 * reload_routes Request protocol to reload all its routes to the core
186 * (using rte_update()). Returns: 0=reload cannot be done,
187 * 1= reload is scheduled and will happen (asynchronously).
188 * feed_begin Notify protocol about beginning of route feeding.
189 * feed_end Notify protocol about finish of route feeding.
190 */
191
192 void (*if_notify)(struct proto *, unsigned flags, struct iface *i);
193 void (*ifa_notify)(struct proto *, unsigned flags, struct ifa *a);
194 void (*rt_notify)(struct proto *, struct rtable *table, struct network *net, struct rte *new, struct rte *old, struct ea_list *attrs);
195 void (*neigh_notify)(struct neighbor *neigh);
196 struct ea_list *(*make_tmp_attrs)(struct rte *rt, struct linpool *pool);
197 void (*store_tmp_attrs)(struct rte *rt, struct ea_list *attrs);
198 int (*import_control)(struct proto *, struct rte **rt, struct ea_list **attrs, struct linpool *pool);
199 int (*reload_routes)(struct proto *);
200 void (*feed_begin)(struct proto *, int initial);
201 void (*feed_end)(struct proto *);
202
203 /*
204 * Routing entry hooks (called only for routes belonging to this protocol):
205 *
206 * rte_recalculate Called at the beginning of the best route selection
207 * rte_better Compare two rte's and decide which one is better (1=first, 0=second).
208 * rte_same Compare two rte's and decide whether they are identical (1=yes, 0=no).
209 * rte_mergable Compare two rte's and decide whether they could be merged (1=yes, 0=no).
210 * rte_insert Called whenever a rte is inserted to a routing table.
211 * rte_remove Called whenever a rte is removed from the routing table.
212 */
213
214 int (*rte_recalculate)(struct rtable *, struct network *, struct rte *, struct rte *, struct rte *);
215 int (*rte_better)(struct rte *, struct rte *);
216 int (*rte_same)(struct rte *, struct rte *);
217 int (*rte_mergable)(struct rte *, struct rte *);
218 struct rte * (*rte_modify)(struct rte *, struct linpool *);
219 void (*rte_insert)(struct network *, struct rte *);
220 void (*rte_remove)(struct network *, struct rte *);
221
222 struct iface *vrf; /* Related VRF instance, NULL if global */
223 struct rtable *table; /* Our primary routing table */
224 struct rte_src *main_source; /* Primary route source */
225 struct announce_hook *main_ahook; /* Primary announcement hook */
226 struct announce_hook *ahooks; /* Announcement hooks for this protocol */
227
228 struct fib_iterator *feed_iterator; /* Routing table iterator used during protocol feeding */
229 struct announce_hook *feed_ahook; /* Announce hook we currently feed */
230
231 /* Hic sunt protocol-specific data */
232 };
233
234 struct proto_spec {
235 void *ptr;
236 int patt;
237 };
238
239
240 #define PDS_DISABLE 1 /* Proto disable scheduled */
241 #define PDS_RESTART 2 /* Proto restart scheduled */
242
243 #define PDC_CF_REMOVE 0x01 /* Removed in new config */
244 #define PDC_CF_DISABLE 0x02 /* Disabled in new config */
245 #define PDC_CF_RESTART 0x03 /* Restart due to reconfiguration */
246 #define PDC_CMD_DISABLE 0x11 /* Result of disable command */
247 #define PDC_CMD_RESTART 0x12 /* Result of restart command */
248 #define PDC_CMD_SHUTDOWN 0x13 /* Result of global shutdown */
249 #define PDC_RX_LIMIT_HIT 0x21 /* Route receive limit reached */
250 #define PDC_IN_LIMIT_HIT 0x22 /* Route import limit reached */
251 #define PDC_OUT_LIMIT_HIT 0x23 /* Route export limit reached */
252
253
254 void *proto_new(struct proto_config *, unsigned size);
255 void *proto_config_new(struct protocol *, int class);
256 void proto_copy_config(struct proto_config *dest, struct proto_config *src);
257 void proto_set_message(struct proto *p, char *msg, int len);
258 void proto_request_feeding(struct proto *p);
259
260 static inline void
proto_copy_rest(struct proto_config * dest,struct proto_config * src,unsigned size)261 proto_copy_rest(struct proto_config *dest, struct proto_config *src, unsigned size)
262 { memcpy(dest + 1, src + 1, size - sizeof(struct proto_config)); }
263
264 void graceful_restart_recovery(void);
265 void graceful_restart_init(void);
266 void graceful_restart_show_status(void);
267 void proto_graceful_restart_lock(struct proto *p);
268 void proto_graceful_restart_unlock(struct proto *p);
269
270 #define DEFAULT_GR_WAIT 240
271
272 void proto_show_limit(struct proto_limit *l, const char *dsc);
273 void proto_show_basic_info(struct proto *p);
274
275 void proto_cmd_show(struct proto *, uintptr_t, int);
276 void proto_cmd_disable(struct proto *, uintptr_t, int);
277 void proto_cmd_enable(struct proto *, uintptr_t, int);
278 void proto_cmd_restart(struct proto *, uintptr_t, int);
279 void proto_cmd_reload(struct proto *, uintptr_t, int);
280 void proto_cmd_debug(struct proto *, uintptr_t, int);
281 void proto_cmd_mrtdump(struct proto *, uintptr_t, int);
282
283 void proto_apply_cmd(struct proto_spec ps, void (* cmd)(struct proto *, uintptr_t, int), int restricted, uintptr_t arg);
284 struct proto *proto_get_named(struct symbol *, struct protocol *);
285
286 #define CMD_RELOAD 0
287 #define CMD_RELOAD_IN 1
288 #define CMD_RELOAD_OUT 2
289
290 static inline u32
proto_get_router_id(struct proto_config * pc)291 proto_get_router_id(struct proto_config *pc)
292 {
293 return pc->router_id ? pc->router_id : pc->global->router_id;
294 }
295
296 static inline struct ea_list *
rte_make_tmp_attrs(struct rte * rt,struct linpool * pool)297 rte_make_tmp_attrs(struct rte *rt, struct linpool *pool)
298 {
299 struct ea_list *(*mta)(struct rte *rt, struct linpool *pool);
300 mta = rt->attrs->src->proto->make_tmp_attrs;
301 return mta ? mta(rt, pool) : NULL;
302 }
303
304 /* Moved from route.h to avoid dependency conflicts */
rte_update(struct proto * p,net * net,rte * new)305 static inline void rte_update(struct proto *p, net *net, rte *new) { rte_update2(p->main_ahook, net, new, p->main_source); }
306
307 extern list active_proto_list;
308
309 /*
310 * Each protocol instance runs two different state machines:
311 *
312 * [P] The protocol machine: (implemented inside protocol)
313 *
314 * DOWN ----> START
315 * ^ |
316 * | V
317 * STOP <---- UP
318 *
319 * States: DOWN Protocol is down and it's waiting for the core
320 * requesting protocol start.
321 * START Protocol is waiting for connection with the rest
322 * of the network and it's not willing to accept
323 * packets. When it connects, it goes to UP state.
324 * UP Protocol is up and running. When the network
325 * connection breaks down or the core requests
326 * protocol to be terminated, it goes to STOP state.
327 * STOP Protocol is disconnecting from the network.
328 * After it disconnects, it returns to DOWN state.
329 *
330 * In: start() Called in DOWN state to request protocol startup.
331 * Returns new state: either UP or START (in this
332 * case, the protocol will notify the core when it
333 * finally comes UP).
334 * stop() Called in START, UP or STOP state to request
335 * protocol shutdown. Returns new state: either
336 * DOWN or STOP (in this case, the protocol will
337 * notify the core when it finally comes DOWN).
338 *
339 * Out: proto_notify_state() -- called by protocol instance when
340 * it does any state transition not covered by
341 * return values of start() and stop(). This includes
342 * START->UP (delayed protocol startup), UP->STOP
343 * (spontaneous shutdown) and STOP->DOWN (delayed
344 * shutdown).
345 */
346
347 #define PS_DOWN 0
348 #define PS_START 1
349 #define PS_UP 2
350 #define PS_STOP 3
351
352 void proto_notify_state(struct proto *p, unsigned state);
353
354 /*
355 * [F] The feeder machine: (implemented in core routines)
356 *
357 * HUNGRY ----> FEEDING
358 * ^ |
359 * | V
360 * FLUSHING <---- HAPPY
361 *
362 * States: HUNGRY Protocol either administratively down (i.e.,
363 * disabled by the user) or temporarily down
364 * (i.e., [P] is not UP)
365 * FEEDING The protocol came up and we're feeding it
366 * initial routes. [P] is UP.
367 * HAPPY The protocol is up and it's receiving normal
368 * routing updates. [P] is UP.
369 * FLUSHING The protocol is down and we're removing its
370 * routes from the table. [P] is STOP or DOWN.
371 *
372 * Normal lifecycle of a protocol looks like:
373 *
374 * HUNGRY/DOWN --> HUNGRY/START --> HUNGRY/UP -->
375 * FEEDING/UP --> HAPPY/UP --> FLUSHING/STOP|DOWN -->
376 * HUNGRY/STOP|DOWN --> HUNGRY/DOWN
377 *
378 * Sometimes, protocol might switch from HAPPY/UP to FEEDING/UP
379 * if it wants to refeed the routes (for example BGP does so
380 * as a result of received ROUTE-REFRESH request).
381 */
382
383 #define FS_HUNGRY 0
384 #define FS_FEEDING 1 /* obsolete */
385 #define FS_HAPPY 2
386 #define FS_FLUSHING 3
387
388
389 #define ES_DOWN 0
390 #define ES_FEEDING 1
391 #define ES_READY 2
392
393
394
395 /*
396 * Debugging flags
397 */
398
399 #define D_STATES 1 /* [core] State transitions */
400 #define D_ROUTES 2 /* [core] Routes passed by the filters */
401 #define D_FILTERS 4 /* [core] Routes rejected by the filters */
402 #define D_IFACES 8 /* [core] Interface events */
403 #define D_EVENTS 16 /* Protocol events */
404 #define D_PACKETS 32 /* Packets sent/received */
405
406 #ifndef PARSER
407 #define TRACE(flags, msg, args...) \
408 do { if (p->p.debug & flags) log(L_TRACE "%s: " msg, p->p.name , ## args ); } while(0)
409 #endif
410
411
412 /*
413 * MRTDump flags
414 */
415
416 #define MD_STATES 1 /* Protocol state changes (BGP4MP_MESSAGE_AS4) */
417 #define MD_MESSAGES 2 /* Protocol packets (BGP4MP_MESSAGE_AS4) */
418
419 /*
420 * Known unique protocol instances as referenced by config routines
421 */
422
423 extern struct proto_config *cf_dev_proto;
424
425
426 /*
427 * Protocol limits
428 */
429
430 #define PLD_RX 0 /* Receive limit */
431 #define PLD_IN 1 /* Import limit */
432 #define PLD_OUT 2 /* Export limit */
433 #define PLD_MAX 3
434
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
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
444 struct proto_limit {
445 u32 limit; /* Maximum number of prefixes */
446 byte action; /* Action to take (PLA_*) */
447 byte state; /* State of limit (PLS_*) */
448 };
449
450 void proto_notify_limit(struct announce_hook *ah, struct proto_limit *l, int dir, u32 rt_count);
451 void proto_verify_limits(struct announce_hook *ah);
452
453 static inline void
proto_reset_limit(struct proto_limit * l)454 proto_reset_limit(struct proto_limit *l)
455 {
456 if (l)
457 l->state = PLS_INITIAL;
458 }
459
460
461 /*
462 * Route Announcement Hook
463 */
464
465 struct announce_hook {
466 node n;
467 struct rtable *table;
468 struct proto *proto;
469 struct filter *in_filter; /* Input filter */
470 struct filter *out_filter; /* Output filter */
471 struct proto_limit *rx_limit; /* Receive limit (for in_keep_filtered) */
472 struct proto_limit *in_limit; /* Input limit */
473 struct proto_limit *out_limit; /* Output limit */
474 struct proto_stats *stats; /* Per-table protocol statistics */
475 struct announce_hook *next; /* Next hook for the same protocol */
476 int in_keep_filtered; /* Routes rejected in import filter are kept */
477 bird_clock_t last_out_filter_change; /* Last time when out_filter _changed_ */
478 };
479
480 struct announce_hook *proto_add_announce_hook(struct proto *p, struct rtable *t, struct proto_stats *stats);
481 struct announce_hook *proto_find_announce_hook(struct proto *p, struct rtable *t);
482
483 #endif
484