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