Statistics
| Branch: | Revision:

iof-bird-daemon / nest / protocol.h @ ae80a2de

History | View | Annotate | Download (17.5 KB)

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 "conf/conf.h"
16

    
17
struct iface;
18
struct ifa;
19
struct rtable;
20
struct rte;
21
struct neighbor;
22
struct rta;
23
struct network;
24
struct proto_config;
25
struct config;
26
struct proto;
27
struct event;
28
struct ea_list;
29
struct eattr;
30
struct symbol;
31

    
32
/*
33
 *        Routing Protocol
34
 */
35

    
36
struct protocol {
37
  node n;
38
  char *name;
39
  char *template;                        /* Template for automatic generation of names */
40
  int name_counter;                        /* Counter for automatic name generation */
41
  int attr_class;                        /* Attribute class known to this protocol */
42
  int multitable;                        /* Protocol handles all announce hooks itself */
43
  uint preference;                        /* Default protocol preference */
44
  uint config_size;                        /* Size of protocol config */
45

    
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 */
49
  int (*reconfigure)(struct proto *, struct proto_config *);        /* Try to reconfigure instance, returns success */
50
  void (*dump)(struct proto *);                        /* Debugging dump */
51
  void (*dump_attrs)(struct rte *);                /* Dump protocol-dependent attributes */
52
  int (*start)(struct proto *);                        /* Start the instance */
53
  int (*shutdown)(struct proto *);                /* Stop the instance */
54
  void (*cleanup)(struct proto *);                /* Called after shutdown when protocol became hungry/down */
55
  void (*get_status)(struct proto *, byte *buf); /* Get instance status (for `show protocols' command) */
56
  void (*get_route_info)(struct rte *, byte *buf, struct ea_list *attrs); /* Get route information (for `show route' command) */
57
  int (*get_attr)(struct eattr *, byte *buf, int buflen);        /* ASCIIfy dynamic attribute (returns GA_*) */
58
  void (*show_proto_info)(struct proto *);        /* Show protocol info (for `show protocols all' command) */
59
  void (*copy_config)(struct proto_config *, struct proto_config *);        /* Copy config from given protocol instance */
60
};
61

    
62
void protos_build(void);
63
void proto_build(struct protocol *);
64
void protos_preconfig(struct config *);
65
void protos_postconfig(struct config *);
66
void protos_commit(struct config *new, struct config *old, int force_restart, int type);
67
void protos_dump_all(void);
68

    
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 */
72

    
73
/*
74
 *        Known protocols
75
 */
76

    
77
extern struct protocol
78
  proto_device, proto_radv, proto_rip, proto_static,
79
  proto_ospf, proto_pipe, proto_bgp, proto_bfd;
80

    
81
/*
82
 *        Routing Protocol Instance
83
 */
84

    
85
struct proto_config {
86
  node n;
87
  struct config *global;                /* Global configuration data */
88
  struct protocol *protocol;                /* Protocol */
89
  struct proto *proto;                        /* Instance we've created */
90
  char *name;
91
  char *dsc;
92
  int class;                                /* SYM_PROTO or SYM_TEMPLATE */
93
  u32 debug, mrtdump;                        /* Debugging bitfields, both use D_* constants */
94
  unsigned preference, disabled;        /* Generic parameters */
95
  int in_keep_filtered;                        /* Routes rejected in import filter are kept */
96
  u32 router_id;                        /* Protocol specific router ID */
97
  struct rtable_config *table;                /* Table we're attached to */
98
  struct filter *in_filter, *out_filter; /* Attached filters */
99
  struct proto_limit *rx_limit;                /* Limit for receiving routes from protocol
100
                                           (relevant when in_keep_filtered is active) */
101
  struct proto_limit *in_limit;                /* Limit for importing routes from protocol */
102
  struct proto_limit *out_limit;        /* Limit for exporting routes to protocol */
103

    
104
  /* Check proto_reconfigure() and proto_copy_config() after changing struct proto_config */
105

    
106
  /* Protocol-specific data follow... */
107
};
108

    
109
/* Protocol statistics */
110
struct proto_stats {
111
  /* Import - from protocol to core */
112
  u32 imp_routes;                /* Number of routes successfully imported to the (adjacent) routing table */
113
  u32 filt_routes;                /* Number of routes rejected in import filter but kept in the routing table */
114
  u32 pref_routes;                /* Number of routes that are preferred, sum over all routing tables */
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 */
130
  u32 exp_updates_accepted;        /* Number of route updates accepted and exported */
131
  u32 exp_withdraws_received;        /* Number of route withdraws received */
132
  u32 exp_withdraws_accepted;        /* Number of route withdraws accepted and processed */
133
};
134

    
135
struct proto {
136
  node n;                                /* Node in *_proto_list */
137
  node glob_node;                        /* Node in global proto_list */
138
  struct protocol *proto;                /* Protocol */
139
  struct proto_config *cf;                /* Configuration data */
140
  struct proto_config *cf_new;                /* Configuration we want to switch to after shutdown (NULL=delete) */
141
  pool *pool;                                /* Pool containing local objects */
142
  struct event *attn;                        /* "Pay attention" event */
143

    
144
  char *name;                                /* Name of this instance (== cf->name) */
145
  u32 debug;                                /* Debugging flags */
146
  u32 mrtdump;                                /* MRTDump flags */
147
  unsigned preference;                        /* Default route preference */
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) */
152
  byte export_state;                        /* Route export state (ES_*, see below) */
153
  byte reconfiguring;                        /* We're shutting down due to reconfiguration */
154
  byte refeeding;                        /* We are refeeding (valid only if export_state == ES_FEEDING) */
155
  byte flushing;                        /* Protocol is flushed in current flush loop round */
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 */
159
  byte down_sched;                        /* Shutdown is scheduled for later (PDS_*) */
160
  byte down_code;                        /* Reason for shutdown (PDC_* codes) */
161
  u32 hash_key;                                /* Random key used for hashing of neighbors */
162
  bird_clock_t last_state_change;        /* Time of last state transition */
163
  char *last_state_name_announced;        /* Last state name we've announced to the user */
164
  struct proto_stats stats;                /* Current protocol statistics */
165

    
166
  /*
167
   *        General protocol hooks:
168
   *
169
   *           if_notify        Notify protocol about interface state changes.
170
   *           ifa_notify        Notify protocol about interface address changes.
171
   *           rt_notify        Notify protocol about routing table updates.
172
   *           neigh_notify        Notify protocol about neighbor cache events.
173
   *           make_tmp_attrs  Construct ea_list from private attrs stored in rte.
174
   *           store_tmp_attrs Store private attrs back to the rte.
175
   *           import_control  Called as the first step of the route importing process.
176
   *                        It can construct a new rte, add private attributes and
177
   *                        decide whether the route shall be imported: 1=yes, -1=no,
178
   *                        0=process it through the import filter set by the user.
179
   *           reload_routes   Request protocol to reload all its routes to the core
180
   *                        (using rte_update()). Returns: 0=reload cannot be done,
181
   *                        1= reload is scheduled and will happen (asynchronously).
182
   *           feed_begin        Notify protocol about beginning of route feeding.
183
   *           feed_end        Notify protocol about finish of route feeding.
184
   */
185

    
186
  void (*if_notify)(struct proto *, unsigned flags, struct iface *i);
187
  void (*ifa_notify)(struct proto *, unsigned flags, struct ifa *a);
188
  void (*rt_notify)(struct proto *, struct rtable *table, struct network *net, struct rte *new, struct rte *old, struct ea_list *attrs);
189
  void (*neigh_notify)(struct neighbor *neigh);
190
  struct ea_list *(*make_tmp_attrs)(struct rte *rt, struct linpool *pool);
191
  void (*store_tmp_attrs)(struct rte *rt, struct ea_list *attrs);
192
  int (*import_control)(struct proto *, struct rte **rt, struct ea_list **attrs, struct linpool *pool);
193
  int (*reload_routes)(struct proto *);
194
  void (*feed_begin)(struct proto *, int initial);
195
  void (*feed_end)(struct proto *);
196

    
197
  /*
198
   *        Routing entry hooks (called only for routes belonging to this protocol):
199
   *
200
   *           rte_recalculate Called at the beginning of the best route selection
201
   *           rte_better        Compare two rte's and decide which one is better (1=first, 0=second).
202
   *       rte_same        Compare two rte's and decide whether they are identical (1=yes, 0=no).
203
   *           rte_insert        Called whenever a rte is inserted to a routing table.
204
   *           rte_remove        Called whenever a rte is removed from the routing table.
205
   */
206

    
207
  int (*rte_recalculate)(struct rtable *, struct network *, struct rte *, struct rte *, struct rte *);
208
  int (*rte_better)(struct rte *, struct rte *);
209
  int (*rte_same)(struct rte *, struct rte *);
210
  void (*rte_insert)(struct network *, struct rte *);
211
  void (*rte_remove)(struct network *, struct rte *);
212

    
213
  struct rtable *table;                        /* Our primary routing table */
214
  struct rte_src *main_source;                /* Primary route source */
215
  struct announce_hook *main_ahook;        /* Primary announcement hook */
216
  struct announce_hook *ahooks;                /* Announcement hooks for this protocol */
217

    
218
  struct fib_iterator *feed_iterator;        /* Routing table iterator used during protocol feeding */
219
  struct announce_hook *feed_ahook;        /* Announce hook we currently feed */
220

    
221
  /* Hic sunt protocol-specific data */
222
};
223

    
224
struct proto_spec {
225
  void *ptr;
226
  int patt;
227
};
228

    
229

    
230
#define PDS_DISABLE                1        /* Proto disable scheduled */
231
#define PDS_RESTART                2        /* Proto restart scheduled */
232

    
233
#define PDC_CF_REMOVE                0x01        /* Removed in new config */
234
#define PDC_CF_DISABLE                0x02        /* Disabled in new config */
235
#define PDC_CF_RESTART                0x03        /* Restart due to reconfiguration */
236
#define PDC_CMD_DISABLE                0x11        /* Result of disable command */
237
#define PDC_CMD_RESTART                0x12        /* Result of restart command */
238
#define PDC_CMD_SHUTDOWN        0x13        /* Result of global shutdown */
239
#define PDC_RX_LIMIT_HIT        0x21        /* Route receive limit reached */
240
#define PDC_IN_LIMIT_HIT        0x22        /* Route import limit reached */
241
#define PDC_OUT_LIMIT_HIT        0x23        /* Route export limit reached */
242

    
243

    
244
void *proto_new(struct proto_config *, unsigned size);
245
void *proto_config_new(struct protocol *, int class);
246
void proto_copy_config(struct proto_config *dest, struct proto_config *src);
247
void proto_request_feeding(struct proto *p);
248

    
249
static inline void
250
proto_copy_rest(struct proto_config *dest, struct proto_config *src, unsigned size)
251
{ memcpy(dest + 1, src + 1, size - sizeof(struct proto_config)); }
252

    
253
void graceful_restart_recovery(void);
254
void graceful_restart_init(void);
255
void graceful_restart_show_status(void);
256
void proto_graceful_restart_lock(struct proto *p);
257
void proto_graceful_restart_unlock(struct proto *p);
258

    
259
#define DEFAULT_GR_WAIT        240
260

    
261
void proto_show_limit(struct proto_limit *l, const char *dsc);
262
void proto_show_basic_info(struct proto *p);
263

    
264
void proto_cmd_show(struct proto *, uint, int);
265
void proto_cmd_disable(struct proto *, uint, int);
266
void proto_cmd_enable(struct proto *, uint, int);
267
void proto_cmd_restart(struct proto *, uint, int);
268
void proto_cmd_reload(struct proto *, uint, int);
269
void proto_cmd_debug(struct proto *, uint, int);
270
void proto_cmd_mrtdump(struct proto *, uint, int);
271

    
272
void proto_apply_cmd(struct proto_spec ps, void (* cmd)(struct proto *, uint, int), int restricted, uint arg);
273
struct proto *proto_get_named(struct symbol *, struct protocol *);
274

    
275
#define CMD_RELOAD        0
276
#define CMD_RELOAD_IN        1
277
#define CMD_RELOAD_OUT        2
278

    
279
static inline u32
280
proto_get_router_id(struct proto_config *pc)
281
{
282
  return pc->router_id ? pc->router_id : pc->global->router_id;
283
}
284

    
285
extern list active_proto_list;
286

    
287
/*
288
 *  Each protocol instance runs two different state machines:
289
 *
290
 *  [P] The protocol machine: (implemented inside protocol)
291
 *
292
 *                DOWN    ---->    START
293
 *                  ^                   |
294
 *                  |                   V
295
 *                STOP    <----     UP
296
 *
297
 *        States:        DOWN        Protocol is down and it's waiting for the core
298
 *                        requesting protocol start.
299
 *                START        Protocol is waiting for connection with the rest
300
 *                        of the network and it's not willing to accept
301
 *                        packets. When it connects, it goes to UP state.
302
 *                UP        Protocol is up and running. When the network
303
 *                        connection breaks down or the core requests
304
 *                        protocol to be terminated, it goes to STOP state.
305
 *                STOP        Protocol is disconnecting from the network.
306
 *                        After it disconnects, it returns to DOWN state.
307
 *
308
 *        In:        start()        Called in DOWN state to request protocol startup.
309
 *                        Returns new state: either UP or START (in this
310
 *                        case, the protocol will notify the core when it
311
 *                        finally comes UP).
312
 *                stop()        Called in START, UP or STOP state to request
313
 *                        protocol shutdown. Returns new state: either
314
 *                        DOWN or STOP (in this case, the protocol will
315
 *                        notify the core when it finally comes DOWN).
316
 *
317
 *        Out:        proto_notify_state() -- called by protocol instance when
318
 *                        it does any state transition not covered by
319
 *                        return values of start() and stop(). This includes
320
 *                        START->UP (delayed protocol startup), UP->STOP
321
 *                        (spontaneous shutdown) and STOP->DOWN (delayed
322
 *                        shutdown).
323
 */
324

    
325
#define PS_DOWN 0
326
#define PS_START 1
327
#define PS_UP 2
328
#define PS_STOP 3
329

    
330
void proto_notify_state(struct proto *p, unsigned state);
331

    
332
/*
333
 *  [F] The feeder machine: (implemented in core routines)
334
 *
335
 *                HUNGRY    ---->   FEEDING
336
 *                 ^                     |
337
 *                 |                      V
338
 *                FLUSHING  <----   HAPPY
339
 *
340
 *        States:        HUNGRY        Protocol either administratively down (i.e.,
341
 *                        disabled by the user) or temporarily down
342
 *                        (i.e., [P] is not UP)
343
 *                FEEDING        The protocol came up and we're feeding it
344
 *                        initial routes. [P] is UP.
345
 *                HAPPY        The protocol is up and it's receiving normal
346
 *                        routing updates. [P] is UP.
347
 *                FLUSHING The protocol is down and we're removing its
348
 *                        routes from the table. [P] is STOP or DOWN.
349
 *
350
 *        Normal lifecycle of a protocol looks like:
351
 *
352
 *                HUNGRY/DOWN --> HUNGRY/START --> HUNGRY/UP -->
353
 *                FEEDING/UP --> HAPPY/UP --> FLUSHING/STOP|DOWN -->
354
 *                HUNGRY/STOP|DOWN --> HUNGRY/DOWN
355
 *
356
 *        Sometimes, protocol might switch from HAPPY/UP to FEEDING/UP
357
 *        if it wants to refeed the routes (for example BGP does so
358
 *        as a result of received ROUTE-REFRESH request).
359
 */
360

    
361
#define FS_HUNGRY        0
362
#define FS_FEEDING        1        /* obsolete */
363
#define FS_HAPPY        2
364
#define FS_FLUSHING        3
365

    
366

    
367
#define ES_DOWN                0
368
#define ES_FEEDING        1
369
#define ES_READY        2
370

    
371

    
372

    
373
/*
374
 *        Debugging flags
375
 */
376

    
377
#define D_STATES 1                /* [core] State transitions */
378
#define D_ROUTES 2                /* [core] Routes passed by the filters */
379
#define D_FILTERS 4                /* [core] Routes rejected by the filters */
380
#define D_IFACES 8                /* [core] Interface events */
381
#define D_EVENTS 16                /* Protocol events */
382
#define D_PACKETS 32                /* Packets sent/received */
383

    
384
#ifndef PARSER
385
#define TRACE(flags, msg, args...) \
386
  do { if (p->p.debug & flags) log(L_TRACE "%s: " msg, p->p.name , ## args ); } while(0)
387
#endif
388

    
389

    
390
/*
391
 *        MRTDump flags
392
 */
393

    
394
#define MD_STATES        1                /* Protocol state changes (BGP4MP_MESSAGE_AS4) */
395
#define MD_MESSAGES        2                /* Protocol packets (BGP4MP_MESSAGE_AS4) */
396

    
397
/*
398
 *        Known unique protocol instances as referenced by config routines
399
 */
400

    
401
extern struct proto_config *cf_dev_proto;
402

    
403

    
404
/*
405
 * Protocol limits
406
 */
407

    
408
#define PLD_RX                0        /* Receive limit */
409
#define PLD_IN                1        /* Import limit */
410
#define PLD_OUT                2        /* Export limit */
411
#define PLD_MAX                3
412

    
413
#define PLA_WARN        1        /* Issue log warning */
414
#define PLA_BLOCK        2        /* Block new routes */
415
#define PLA_RESTART        4        /* Force protocol restart */
416
#define PLA_DISABLE        5        /* Shutdown and disable protocol */
417

    
418
#define PLS_INITIAL        0        /* Initial limit state after protocol start */
419
#define PLS_ACTIVE        1        /* Limit was hit */
420
#define PLS_BLOCKED        2        /* Limit is active and blocking new routes */
421

    
422
struct proto_limit {
423
  u32 limit;                        /* Maximum number of prefixes */
424
  byte action;                        /* Action to take (PLA_*) */
425
  byte state;                        /* State of limit (PLS_*) */
426
};
427

    
428
void proto_notify_limit(struct announce_hook *ah, struct proto_limit *l, int dir, u32 rt_count);
429
void proto_verify_limits(struct announce_hook *ah);
430

    
431
static inline void
432
proto_reset_limit(struct proto_limit *l)
433
{
434
  if (l)
435
    l->state = PLS_INITIAL;
436
}
437

    
438

    
439
/*
440
 *        Route Announcement Hook
441
 */
442

    
443
struct announce_hook {
444
  node n;
445
  struct rtable *table;
446
  struct proto *proto;
447
  struct filter *in_filter;                /* Input filter */
448
  struct filter *out_filter;                /* Output filter */
449
  struct proto_limit *rx_limit;                /* Receive limit (for in_keep_filtered) */
450
  struct proto_limit *in_limit;                /* Input limit */
451
  struct proto_limit *out_limit;        /* Output limit */
452
  struct proto_stats *stats;                /* Per-table protocol statistics */
453
  struct announce_hook *next;                /* Next hook for the same protocol */
454
  int in_keep_filtered;                        /* Routes rejected in import filter are kept */
455
};
456

    
457
struct announce_hook *proto_add_announce_hook(struct proto *p, struct rtable *t, struct proto_stats *stats);
458
struct announce_hook *proto_find_announce_hook(struct proto *p, struct rtable *t);
459

    
460
#endif