]>
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" |
9685deb9 | 14 | #include "lib/timer.h" |
4cdd0784 | 15 | #include "conf/conf.h" |
58ef912c | 16 | |
2326b001 | 17 | struct iface; |
9a158361 | 18 | struct ifa; |
dca75fd7 | 19 | struct rtable; |
2326b001 MM |
20 | struct rte; |
21 | struct neighbor; | |
1b769b08 | 22 | struct rta; |
8c43696d | 23 | struct network; |
31b3e1bb MM |
24 | struct proto_config; |
25 | struct config; | |
26 | struct proto; | |
64011f89 | 27 | struct event; |
bb027be1 | 28 | struct ea_list; |
3991d84e | 29 | struct eattr; |
ae97b946 | 30 | struct symbol; |
2326b001 | 31 | |
58ef912c MM |
32 | /* |
33 | * Routing Protocol | |
34 | */ | |
35 | ||
36 | struct 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 | 62 | void protos_build(void); |
3991d84e | 63 | void proto_build(struct protocol *); |
31b3e1bb MM |
64 | void protos_preconfig(struct config *); |
65 | void protos_postconfig(struct config *); | |
bf1aec97 | 66 | void protos_commit(struct config *new, struct config *old, int force_restart, int type); |
87d2be86 | 67 | void 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 | 77 | extern struct protocol |
93e868c7 | 78 | proto_device, proto_radv, proto_rip, proto_static, |
6a8d3f1c | 79 | proto_ospf, proto_pipe, proto_bgp, proto_bfd; |
58ef912c MM |
80 | |
81 | /* | |
82 | * Routing Protocol Instance | |
83 | */ | |
84 | ||
31b3e1bb MM |
85 | struct 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 |
110 | struct 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 | 135 | struct 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 |
227 | struct 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 | 247 | void *proto_new(struct proto_config *, unsigned size); |
2bbc3083 | 248 | void *proto_config_new(struct protocol *, int class); |
a7f23f58 | 249 | void proto_copy_config(struct proto_config *dest, struct proto_config *src); |
bf47fe4b | 250 | void proto_request_feeding(struct proto *p); |
e304fd4b | 251 | |
a7f23f58 OZ |
252 | static inline void |
253 | proto_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 |
256 | void graceful_restart_recovery(void); |
257 | void graceful_restart_init(void); | |
258 | void graceful_restart_show_status(void); | |
259 | void proto_graceful_restart_lock(struct proto *p); | |
260 | void proto_graceful_restart_unlock(struct proto *p); | |
261 | ||
262 | #define DEFAULT_GR_WAIT 240 | |
c0adf7e9 | 263 | |
ebecb6f6 | 264 | void proto_show_limit(struct proto_limit *l, const char *dsc); |
c0adf7e9 OZ |
265 | void proto_show_basic_info(struct proto *p); |
266 | ||
ae80a2de PT |
267 | void proto_cmd_show(struct proto *, uint, int); |
268 | void proto_cmd_disable(struct proto *, uint, int); | |
269 | void proto_cmd_enable(struct proto *, uint, int); | |
270 | void proto_cmd_restart(struct proto *, uint, int); | |
271 | void proto_cmd_reload(struct proto *, uint, int); | |
272 | void proto_cmd_debug(struct proto *, uint, int); | |
273 | void proto_cmd_mrtdump(struct proto *, uint, int); | |
274 | ||
275 | void proto_apply_cmd(struct proto_spec ps, void (* cmd)(struct proto *, uint, int), int restricted, uint arg); | |
02c1fbdd | 276 | struct 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 |
282 | static inline u32 |
283 | proto_get_router_id(struct proto_config *pc) | |
284 | { | |
285 | return pc->router_id ? pc->router_id : pc->global->router_id; | |
286 | } | |
287 | ||
f14a4bec | 288 | extern 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 | ||
333 | void 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 | 404 | extern 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 |
425 | struct 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 | 431 | void proto_notify_limit(struct announce_hook *ah, struct proto_limit *l, int dir, u32 rt_count); |
984d7349 | 432 | void proto_verify_limits(struct announce_hook *ah); |
7d0a31de | 433 | |
ab758e4f OZ |
434 | static inline void |
435 | proto_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 | ||
446 | struct 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 | 460 | struct announce_hook *proto_add_announce_hook(struct proto *p, struct rtable *t, struct proto_stats *stats); |
c0adf7e9 | 461 | struct announce_hook *proto_find_announce_hook(struct proto *p, struct rtable *t); |
c8387626 | 462 | |
58ef912c | 463 | #endif |