Statistics
| Branch: | Revision:

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

History | View | Annotate | Download (23.4 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/event.h"
15
#include "sysdep/unix/timer.h"
16
#include "nest/route.h"
17
#include "conf/conf.h"
18

    
19
struct iface;
20
struct ifa;
21
struct rtable;
22
struct rte;
23
struct neighbor;
24
struct rta;
25
struct network;
26
struct proto_config;
27
struct channel_limit;
28
struct channel_config;
29
struct config;
30
struct proto;
31
struct channel;
32
struct ea_list;
33
struct eattr;
34
struct symbol;
35

    
36

    
37
/*
38
 *        Routing Protocol
39
 */
40

    
41
struct protocol {
42
  node n;
43
  char *name;
44
  char *template;                        /* Template for automatic generation of names */
45
  int name_counter;                        /* Counter for automatic name generation */
46
  int attr_class;                        /* Attribute class known to this protocol */
47
  uint preference;                        /* Default protocol preference */
48
  uint channel_mask;                        /* Mask of accepted channel types (NB_*) */
49
  uint proto_size;                        /* Size of protocol data structure */
50
  uint config_size;                        /* Size of protocol config data structure */
51

    
52
  void (*preconfig)(struct protocol *, struct config *);        /* Just before configuring */
53
  void (*postconfig)(struct proto_config *);                        /* After configuring each instance */
54
  struct proto * (*init)(struct proto_config *);                /* Create new instance */
55
  int (*reconfigure)(struct proto *, struct proto_config *);        /* Try to reconfigure instance, returns success */
56
  void (*dump)(struct proto *);                        /* Debugging dump */
57
  void (*dump_attrs)(struct rte *);                /* Dump protocol-dependent attributes */
58
  int (*start)(struct proto *);                        /* Start the instance */
59
  int (*shutdown)(struct proto *);                /* Stop the instance */
60
  void (*cleanup)(struct proto *);                /* Called after shutdown when protocol became hungry/down */
61
  void (*get_status)(struct proto *, byte *buf); /* Get instance status (for `show protocols' command) */
62
  void (*get_route_info)(struct rte *, byte *buf, struct ea_list *attrs); /* Get route information (for `show route' command) */
63
  int (*get_attr)(struct eattr *, byte *buf, int buflen);        /* ASCIIfy dynamic attribute (returns GA_*) */
64
  void (*show_proto_info)(struct proto *);        /* Show protocol info (for `show protocols all' command) */
65
  void (*copy_config)(struct proto_config *, struct proto_config *);        /* Copy config from given protocol instance */
66
};
67

    
68
void protos_build(void);
69
void proto_build(struct protocol *);
70
void protos_preconfig(struct config *);
71
void protos_commit(struct config *new, struct config *old, int force_restart, int type);
72
void protos_dump_all(void);
73

    
74
#define GA_UNKNOWN        0                /* Attribute not recognized */
75
#define GA_NAME                1                /* Result = name */
76
#define GA_FULL                2                /* Result = both name and value */
77

    
78
/*
79
 *        Known protocols
80
 */
81

    
82
extern struct protocol
83
  proto_device, proto_radv, proto_rip, proto_static,
84
  proto_ospf, proto_pipe, proto_bgp, proto_bfd, proto_babel, proto_rpki;
85

    
86
/*
87
 *        Routing Protocol Instance
88
 */
89

    
90
struct proto_config {
91
  node n;
92
  struct config *global;                /* Global configuration data */
93
  struct protocol *protocol;                /* Protocol */
94
  struct proto *proto;                        /* Instance we've created */
95
  char *name;
96
  char *dsc;
97
  int class;                                /* SYM_PROTO or SYM_TEMPLATE */
98
  u8 net_type;                                /* Protocol network type (NET_*), 0 for undefined */
99
  u8 disabled;                                /* Protocol enabled/disabled by default */
100
  u32 debug, mrtdump;                        /* Debugging bitfields, both use D_* constants */
101
  u32 router_id;                        /* Protocol specific router ID */
102

    
103
  list channels;                        /* List of channel configs (struct channel_config) */
104

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

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

    
110
/* Protocol statistics */
111
struct proto_stats {
112
  /* Import - from protocol to core */
113
  u32 imp_routes;                /* Number of routes successfully imported to the (adjacent) routing table */
114
  u32 filt_routes;                /* Number of routes rejected in import filter but kept in the routing table */
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 global proto_list */
137
  struct protocol *proto;                /* Protocol */
138
  struct proto_config *cf;                /* Configuration data */
139
  struct proto_config *cf_new;                /* Configuration we want to switch to after shutdown (NULL=delete) */
140
  pool *pool;                                /* Pool containing local objects */
141
  event *event;                                /* Protocol event */
142

    
143
  list channels;                        /* List of channels to rtables (struct channel) */
144
  struct channel *main_channel;                /* Primary channel */
145
  struct rte_src *main_source;                /* Primary route source */
146

    
147
  char *name;                                /* Name of this instance (== cf->name) */
148
  u32 debug;                                /* Debugging flags */
149
  u32 mrtdump;                                /* MRTDump flags */
150
  uint active_channels;                        /* Number of active channels */
151
  byte net_type;                        /* Protocol network type (NET_*), 0 for undefined */
152
  byte disabled;                        /* Manually disabled */
153
  byte proto_state;                        /* Protocol state machine (PS_*, see below) */
154
  byte active;                                /* From PS_START to cleanup after PS_STOP */
155
  byte do_start;                        /* Start actions are scheduled */
156
  byte do_stop;                                /* Stop actions are scheduled */
157
  byte reconfiguring;                        /* We're shutting down due to reconfiguration */
158
  byte gr_recovery;                        /* Protocol should participate in graceful restart recovery */
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

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

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

    
196
  /*
197
   *        Routing entry hooks (called only for routes belonging to this protocol):
198
   *
199
   *           rte_recalculate Called at the beginning of the best route selection
200
   *           rte_better        Compare two rte's and decide which one is better (1=first, 0=second).
201
   *       rte_same        Compare two rte's and decide whether they are identical (1=yes, 0=no).
202
   *       rte_mergable        Compare two rte's and decide whether they could be merged (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
  int (*rte_mergable)(struct rte *, struct rte *);
211
  void (*rte_insert)(struct network *, struct rte *);
212
  void (*rte_remove)(struct network *, struct rte *);
213

    
214
  /* Hic sunt protocol-specific data */
215
};
216

    
217
struct proto_spec {
218
  void *ptr;
219
  int patt;
220
};
221

    
222

    
223
#define PDS_DISABLE                1        /* Proto disable scheduled */
224
#define PDS_RESTART                2        /* Proto restart scheduled */
225

    
226
#define PDC_CF_REMOVE                0x01        /* Removed in new config */
227
#define PDC_CF_DISABLE                0x02        /* Disabled in new config */
228
#define PDC_CF_RESTART                0x03        /* Restart due to reconfiguration */
229
#define PDC_CMD_DISABLE                0x11        /* Result of disable command */
230
#define PDC_CMD_RESTART                0x12        /* Result of restart command */
231
#define PDC_CMD_SHUTDOWN        0x13        /* Result of global shutdown */
232
#define PDC_RX_LIMIT_HIT        0x21        /* Route receive limit reached */
233
#define PDC_IN_LIMIT_HIT        0x22        /* Route import limit reached */
234
#define PDC_OUT_LIMIT_HIT        0x23        /* Route export limit reached */
235

    
236

    
237
void *proto_new(struct proto_config *);
238
void *proto_config_new(struct protocol *, int class);
239
void proto_copy_config(struct proto_config *dest, struct proto_config *src);
240

    
241
void graceful_restart_recovery(void);
242
void graceful_restart_init(void);
243
void graceful_restart_show_status(void);
244
void channel_graceful_restart_lock(struct channel *c);
245
void channel_graceful_restart_unlock(struct channel *c);
246

    
247
#define DEFAULT_GR_WAIT        240
248

    
249
void channel_show_limit(struct channel_limit *l, const char *dsc);
250
void channel_show_info(struct channel *c);
251

    
252
void proto_cmd_show(struct proto *, uint, int);
253
void proto_cmd_disable(struct proto *, uint, int);
254
void proto_cmd_enable(struct proto *, uint, int);
255
void proto_cmd_restart(struct proto *, uint, int);
256
void proto_cmd_reload(struct proto *, uint, int);
257
void proto_cmd_debug(struct proto *, uint, int);
258
void proto_cmd_mrtdump(struct proto *, uint, int);
259

    
260
void proto_apply_cmd(struct proto_spec ps, void (* cmd)(struct proto *, uint, int), int restricted, uint arg);
261
struct proto *proto_get_named(struct symbol *, struct protocol *);
262

    
263
#define CMD_RELOAD        0
264
#define CMD_RELOAD_IN        1
265
#define CMD_RELOAD_OUT        2
266

    
267
static inline u32
268
proto_get_router_id(struct proto_config *pc)
269
{
270
  return pc->router_id ? pc->router_id : pc->global->router_id;
271
}
272

    
273
static inline struct ea_list *
274
rte_make_tmp_attrs(struct rte *rt, struct linpool *pool)
275
{
276
  struct ea_list *(*mta)(struct rte *rt, struct linpool *pool);
277
  mta = rt->attrs->src->proto->make_tmp_attrs;
278
  return mta ? mta(rt, pool) : NULL;
279
}
280

    
281
/* Moved from route.h to avoid dependency conflicts */
282
static inline void rte_update(struct proto *p, const net_addr *n, rte *new) { rte_update2(p->main_channel, n, new, p->main_source); }
283

    
284
extern pool *proto_pool;
285
extern list 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

    
362

    
363
/*
364
 *        Debugging flags
365
 */
366

    
367
#define D_STATES 1                /* [core] State transitions */
368
#define D_ROUTES 2                /* [core] Routes passed by the filters */
369
#define D_FILTERS 4                /* [core] Routes rejected by the filters */
370
#define D_IFACES 8                /* [core] Interface events */
371
#define D_EVENTS 16                /* Protocol events */
372
#define D_PACKETS 32                /* Packets sent/received */
373

    
374
#ifndef PARSER
375
#define TRACE(flags, msg, args...) \
376
  do { if (p->p.debug & flags) log(L_TRACE "%s: " msg, p->p.name , ## args ); } while(0)
377
#endif
378

    
379

    
380
/*
381
 *        MRTDump flags
382
 */
383

    
384
#define MD_STATES        1                /* Protocol state changes (BGP4MP_MESSAGE_AS4) */
385
#define MD_MESSAGES        2                /* Protocol packets (BGP4MP_MESSAGE_AS4) */
386

    
387
/*
388
 *        Known unique protocol instances as referenced by config routines
389
 */
390

    
391
extern struct proto_config *cf_dev_proto;
392

    
393

    
394
/*
395
 * Protocol limits
396
 */
397

    
398
#define PLD_RX                0        /* Receive limit */
399
#define PLD_IN                1        /* Import limit */
400
#define PLD_OUT                2        /* Export limit */
401
#define PLD_MAX                3
402

    
403
#define PLA_NONE        0        /* No limit */
404
#define PLA_WARN        1        /* Issue log warning */
405
#define PLA_BLOCK        2        /* Block new routes */
406
#define PLA_RESTART        4        /* Force protocol restart */
407
#define PLA_DISABLE        5        /* Shutdown and disable protocol */
408

    
409
#define PLS_INITIAL        0        /* Initial limit state after protocol start */
410
#define PLS_ACTIVE        1        /* Limit was hit */
411
#define PLS_BLOCKED        2        /* Limit is active and blocking new routes */
412

    
413
struct channel_limit {
414
  u32 limit;                        /* Maximum number of prefixes */
415
  u8 action;                        /* Action to take (PLA_*) */
416
  u8 state;                        /* State of limit (PLS_*) */
417
};
418

    
419
void channel_notify_limit(struct channel *c, struct channel_limit *l, int dir, u32 rt_count);
420

    
421

    
422
/*
423
 *        Channels
424
 */
425

    
426
struct channel_class {
427
  uint channel_size;                        /* Size of channel data structure */
428
  uint config_size;                        /* Size of channel config data structure */
429

    
430
  void (*init)(struct channel *, struct channel_config *);        /* Create new instance */
431
  int (*reconfigure)(struct channel *, struct channel_config *);        /* Try to reconfigure instance, returns success */
432
  int (*start)(struct channel *);        /* Start the instance */
433
  void (*shutdown)(struct channel *);        /* Stop the instance */
434
  void (*cleanup)(struct channel *);        /* Channel finished flush */
435

    
436
  void (*copy_config)(struct channel_config *, struct channel_config *); /* Copy config from given channel instance */
437
#if 0
438
  XXXX;
439
  void (*preconfig)(struct protocol *, struct config *);        /* Just before configuring */
440
  void (*postconfig)(struct proto_config *);                        /* After configuring each instance */
441

442

443
  void (*dump)(struct proto *);                        /* Debugging dump */
444
  void (*dump_attrs)(struct rte *);                /* Dump protocol-dependent attributes */
445

446
  void (*get_status)(struct proto *, byte *buf); /* Get instance status (for `show protocols' command) */
447
  void (*get_route_info)(struct rte *, byte *buf, struct ea_list *attrs); /* Get route information (for `show route' command) */
448
  int (*get_attr)(struct eattr *, byte *buf, int buflen);        /* ASCIIfy dynamic attribute (returns GA_*) */
449
  void (*show_proto_info)(struct proto *);        /* Show protocol info (for `show protocols all' command) */
450

451
#endif
452
};
453

    
454
extern struct channel_class channel_bgp;
455

    
456
struct channel_config {
457
  node n;
458
  const char *name;
459
  const struct channel_class *channel;
460

    
461
  struct rtable_config *table;                /* Table we're attached to */
462
  struct filter *in_filter, *out_filter; /* Attached filters */
463
  struct channel_limit rx_limit;        /* Limit for receiving routes from protocol
464
                                           (relevant when in_keep_filtered is active) */
465
  struct channel_limit in_limit;        /* Limit for importing routes from protocol */
466
  struct channel_limit out_limit;        /* Limit for exporting routes to protocol */
467

    
468
  u8 net_type;                                /* Routing table network type (NET_*), 0 for undefined */
469
  u8 ra_mode;                                /* Mode of received route advertisements (RA_*) */
470
  u16 preference;                        /* Default route preference */
471
  u8 merge_limit;                        /* Maximal number of nexthops for RA_MERGED */
472
  u8 in_keep_filtered;                        /* Routes rejected in import filter are kept */
473
};
474

    
475
struct channel {
476
  node n;                                /* Node in proto->channels */
477
  node table_node;                        /* Node in table->channels */
478

    
479
  const char *name;                        /* Channel name (may be NULL) */
480
  const struct channel_class *channel;
481
  struct proto *proto;
482

    
483
  struct rtable *table;
484
  struct filter *in_filter;                /* Input filter */
485
  struct filter *out_filter;                /* Output filter */
486
  struct channel_limit rx_limit;        /* Receive limit (for in_keep_filtered) */
487
  struct channel_limit in_limit;        /* Input limit */
488
  struct channel_limit out_limit;        /* Output limit */
489

    
490
  struct event *feed_event;                /* Event responsible for feeding */
491
  struct fib_iterator feed_fit;                /* Routing table iterator used during feeding */
492
  struct proto_stats stats;                /* Per-channel protocol statistics */
493

    
494
  u8 net_type;                                /* Routing table network type (NET_*), 0 for undefined */
495
  u8 ra_mode;                                /* Mode of received route advertisements (RA_*) */
496
  u16 preference;                        /* Default route preference */
497
  u8 merge_limit;                        /* Maximal number of nexthops for RA_MERGED */
498
  u8 in_keep_filtered;                        /* Routes rejected in import filter are kept */
499
  u8 disabled;
500
  u8 stale;                                /* Used in reconfiguration */
501

    
502
  u8 channel_state;
503
  u8 export_state;                        /* Route export state (ES_*, see below) */
504
  u8 feed_active;
505
  u8 flush_active;
506
  u8 refeeding;                                /* We are refeeding (valid only if export_state == ES_FEEDING) */
507
  u8 reloadable;                        /* Hook reload_routes() is allowed on the channel */
508
  u8 gr_lock;                                /* Graceful restart mechanism should wait for this channel */
509
  u8 gr_wait;                                /* Route export to channel is postponed until graceful restart */
510

    
511
  bird_clock_t last_state_change;        /* Time of last state transition */
512
};
513

    
514

    
515
/*
516
 * Channel states
517
 *
518
 * CS_DOWN - The initial and the final state of a channel. There is no route
519
 * exchange between the protocol and the table. Channel is not counted as
520
 * active. Channel keeps a ptr to the table, but do not lock the table and is
521
 * not linked in the table. Generally, new closed channels are created in
522
 * protocols' init() hooks. The protocol is expected to explicitly activate its
523
 * channels (by calling channel_init() or channel_open()).
524
 *
525
 * CS_START - The channel as a connection between the protocol and the table is
526
 * initialized (counted as active by the protocol, linked in the table and keeps
527
 * the table locked), but there is no current route exchange. There still may be
528
 * routes associated with the channel in the routing table if the channel falls
529
 * to CS_START from CS_UP. Generally, channels are initialized in protocols'
530
 * start() hooks when going to PS_START.
531
 *
532
 * CS_UP - The channel is initialized and the route exchange is allowed. Note
533
 * that even in CS_UP state, route export may still be down (ES_DOWN) by the
534
 * core decision (e.g. waiting for table convergence after graceful restart).
535
 * I.e., the protocol decides to open the channel but the core decides to start
536
 * route export. Route import (caused by rte_update() from the protocol) is not
537
 * restricted by that and is on volition of the protocol. Generally, channels
538
 * are opened in protocols' start() hooks when going to PS_UP.
539
 *
540
 * CS_FLUSHING - The transitional state between initialized channel and closed
541
 * channel. The channel is still initialized, but no route exchange is allowed.
542
 * Instead, the associated table is running flush loop to remove routes imported
543
 * through the channel. After that, the channel changes state to CS_DOWN and
544
 * is detached from the table (the table is unlocked and the channel is unlinked
545
 * from it). Unlike other states, the CS_FLUSHING state is not explicitly
546
 * entered or left by the protocol. A protocol may request to close a channel
547
 * (by calling channel_close()), which causes the channel to change state to
548
 * CS_FLUSHING and later to CS_DOWN. Also note that channels are closed
549
 * automatically by the core when the protocol is going down.
550
 *
551
 * Allowed transitions:
552
 *
553
 * CS_DOWN        -> CS_START / CS_UP
554
 * CS_START        -> CS_UP / CS_FLUSHING
555
 * CS_UP        -> CS_START / CS_FLUSHING
556
 * CS_FLUSHING        -> CS_DOWN (automatic)
557
 */
558

    
559
#define CS_DOWN                0
560
#define CS_START        1
561
#define CS_UP                2
562
#define CS_FLUSHING        3
563

    
564
#define ES_DOWN                0
565
#define ES_FEEDING        1
566
#define ES_READY        2
567

    
568

    
569
struct channel_config *proto_cf_find_channel(struct proto_config *p, uint net_type);
570
static inline struct channel_config *proto_cf_main_channel(struct proto_config *pc)
571
{ struct channel_config *cc = HEAD(pc->channels); return NODE_VALID(cc) ? cc : NULL; }
572

    
573
struct channel *proto_find_channel_by_table(struct proto *p, struct rtable *t);
574
struct channel *proto_find_channel_by_name(struct proto *p, const char *n);
575
struct channel *proto_add_channel(struct proto *p, struct channel_config *cf);
576
int proto_configure_channel(struct proto *p, struct channel **c, struct channel_config *cf);
577

    
578
void channel_set_state(struct channel *c, uint state);
579

    
580
static inline void channel_init(struct channel *c) { channel_set_state(c, CS_START); }
581
static inline void channel_open(struct channel *c) { channel_set_state(c, CS_UP); }
582
static inline void channel_close(struct channel *c) { channel_set_state(c, CS_FLUSHING); }
583

    
584
void channel_request_feeding(struct channel *c);
585
void *channel_config_new(const struct channel_class *cc, uint net_type, struct proto_config *proto);
586
int channel_reconfigure(struct channel *c, struct channel_config *cf);
587

    
588

    
589
#endif