protocol.h 24.9 KB
Newer Older
1 2 3
/*
 *	BIRD Internet Routing Daemon -- Protocols
 *
4
 *	(c) 1998--2000 Martin Mares <mj@ucw.cz>
5 6 7 8 9 10 11
 *
 *	Can be freely distributed and used under the terms of the GNU GPL.
 */

#ifndef _BIRD_PROTOCOL_H_
#define _BIRD_PROTOCOL_H_

12
#include "lib/lists.h"
13
#include "lib/resource.h"
14 15
#include "lib/event.h"
#include "nest/route.h"
16
#include "conf/conf.h"
17

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

35

36 37 38 39
/*
 *	Routing Protocol
 */

40 41 42 43 44 45 46 47 48
enum protocol_class {
  PROTOCOL_NONE,
  PROTOCOL_BABEL,
  PROTOCOL_BFD,
  PROTOCOL_BGP,
  PROTOCOL_DEVICE,
  PROTOCOL_DIRECT,
  PROTOCOL_KERNEL,
  PROTOCOL_OSPF,
Ondřej Zajíček's avatar
Ondřej Zajíček committed
49
  PROTOCOL_MRT,
50
  PROTOCOL_PERF,
51 52 53 54 55 56 57 58 59 60
  PROTOCOL_PIPE,
  PROTOCOL_RADV,
  PROTOCOL_RIP,
  PROTOCOL_RPKI,
  PROTOCOL_STATIC,
  PROTOCOL__MAX
};

extern struct protocol *class_to_protocol[PROTOCOL__MAX];

61
struct protocol {
62
  node n;
63
  char *name;
64
  char *template;			/* Template for automatic generation of names */
65
  int name_counter;			/* Counter for automatic name generation */
66
  enum protocol_class class;		/* Machine readable protocol class */
67
  uint preference;			/* Default protocol preference */
68 69 70
  uint channel_mask;			/* Mask of accepted channel types (NB_*) */
  uint proto_size;			/* Size of protocol data structure */
  uint config_size;			/* Size of protocol config data structure */
71

72 73 74
  void (*preconfig)(struct protocol *, struct config *);	/* Just before configuring */
  void (*postconfig)(struct proto_config *);			/* After configuring each instance */
  struct proto * (*init)(struct proto_config *);		/* Create new instance */
75
  int (*reconfigure)(struct proto *, struct proto_config *);	/* Try to reconfigure instance, returns success */
76
  void (*dump)(struct proto *);			/* Debugging dump */
77
  void (*dump_attrs)(struct rte *);		/* Dump protocol-dependent attributes */
78 79
  int (*start)(struct proto *);			/* Start the instance */
  int (*shutdown)(struct proto *);		/* Stop the instance */
80
  void (*cleanup)(struct proto *);		/* Called after shutdown when protocol became hungry/down */
81
  void (*get_status)(struct proto *, byte *buf); /* Get instance status (for `show protocols' command) */
82
  void (*get_route_info)(struct rte *, byte *buf); /* Get route information (for `show route' command) */
83
  int (*get_attr)(struct eattr *, byte *buf, int buflen);	/* ASCIIfy dynamic attribute (returns GA_*) */
84
  void (*show_proto_info)(struct proto *);	/* Show protocol info (for `show protocols all' command) */
85
  void (*copy_config)(struct proto_config *, struct proto_config *);	/* Copy config from given protocol instance */
86 87
};

88
void protos_build(void);
89
void proto_build(struct protocol *);
90
void protos_preconfig(struct config *);
91
void protos_commit(struct config *new, struct config *old, int force_restart, int type);
92
void protos_dump_all(void);
93

94 95 96
#define GA_UNKNOWN	0		/* Attribute not recognized */
#define GA_NAME		1		/* Result = name */
#define GA_FULL		2		/* Result = both name and value */
97 98 99 100 101

/*
 *	Known protocols
 */

102
extern struct protocol
Ondřej Zajíček's avatar
Ondřej Zajíček committed
103
  proto_device, proto_radv, proto_rip, proto_static, proto_mrt,
104 105
  proto_ospf, proto_perf,
  proto_pipe, proto_bgp, proto_bfd, proto_babel, proto_rpki;
106 107 108 109 110

/*
 *	Routing Protocol Instance
 */

111 112 113
struct proto_config {
  node n;
  struct config *global;		/* Global configuration data */
114 115
  struct protocol *protocol;		/* Protocol */
  struct proto *proto;			/* Instance we've created */
116
  char *name;
117
  char *dsc;
118
  int class;				/* SYM_PROTO or SYM_TEMPLATE */
119 120
  u8 net_type;				/* Protocol network type (NET_*), 0 for undefined */
  u8 disabled;				/* Protocol enabled/disabled by default */
121
  u32 debug, mrtdump;			/* Debugging bitfields, both use D_* constants */
122
  u32 router_id;			/* Protocol specific router ID */
123 124

  list channels;			/* List of channel configs (struct channel_config) */
Ondřej Zajíček's avatar
Ondřej Zajíček committed
125
  struct iface *vrf;			/* Related VRF instance, NULL if global */
126

127 128
  /* Check proto_reconfigure() and proto_copy_config() after changing struct proto_config */

129 130 131
  /* Protocol-specific data follow... */
};

132
/* Protocol statistics */
133 134 135
struct proto_stats {
  /* Import - from protocol to core */
  u32 imp_routes;		/* Number of routes successfully imported to the (adjacent) routing table */
136
  u32 filt_routes;		/* Number of routes rejected in import filter but kept in the routing table */
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
  u32 imp_updates_received;	/* Number of route updates received */
  u32 imp_updates_invalid;	/* Number of route updates rejected as invalid */
  u32 imp_updates_filtered;	/* Number of route updates rejected by filters */
  u32 imp_updates_ignored;	/* Number of route updates rejected as already in route table */
  u32 imp_updates_accepted;	/* Number of route updates accepted and imported */
  u32 imp_withdraws_received;	/* Number of route withdraws received */
  u32 imp_withdraws_invalid;	/* Number of route withdraws rejected as invalid */
  u32 imp_withdraws_ignored;	/* Number of route withdraws rejected as already not in route table */
  u32 imp_withdraws_accepted;	/* Number of route withdraws accepted and processed */

  /* Export - from core to protocol */
  u32 exp_routes;		/* Number of routes successfully exported to the protocol */
  u32 exp_updates_received;	/* Number of route updates received */
  u32 exp_updates_rejected;	/* Number of route updates rejected by protocol */
  u32 exp_updates_filtered;	/* Number of route updates rejected by filters */
152
  u32 exp_updates_accepted;	/* Number of route updates accepted and exported */
153 154 155 156
  u32 exp_withdraws_received;	/* Number of route withdraws received */
  u32 exp_withdraws_accepted;	/* Number of route withdraws accepted and processed */
};

157
struct proto {
158
  node n;				/* Node in global proto_list */
159
  struct protocol *proto;		/* Protocol */
160
  struct proto_config *cf;		/* Configuration data */
161
  struct proto_config *cf_new;		/* Configuration we want to switch to after shutdown (NULL=delete) */
162
  pool *pool;				/* Pool containing local objects */
163 164 165 166 167
  event *event;				/* Protocol event */

  list channels;			/* List of channels to rtables (struct channel) */
  struct channel *main_channel;		/* Primary channel */
  struct rte_src *main_source;		/* Primary route source */
168
  struct iface *vrf;			/* Related VRF instance, NULL if global */
169

170
  char *name;				/* Name of this instance (== cf->name) */
171 172
  u32 debug;				/* Debugging flags */
  u32 mrtdump;				/* MRTDump flags */
173 174
  uint active_channels;			/* Number of active channels */
  byte net_type;			/* Protocol network type (NET_*), 0 for undefined */
175 176
  byte disabled;			/* Manually disabled */
  byte proto_state;			/* Protocol state machine (PS_*, see below) */
177 178 179
  byte active;				/* From PS_START to cleanup after PS_STOP */
  byte do_start;			/* Start actions are scheduled */
  byte do_stop;				/* Stop actions are scheduled */
180
  byte reconfiguring;			/* We're shutting down due to reconfiguration */
181
  byte gr_recovery;			/* Protocol should participate in graceful restart recovery */
182 183
  byte down_sched;			/* Shutdown is scheduled for later (PDS_*) */
  byte down_code;			/* Reason for shutdown (PDC_* codes) */
184
  u32 hash_key;				/* Random key used for hashing of neighbors */
185
  btime last_state_change;		/* Time of last state transition */
186
  char *last_state_name_announced;	/* Last state name we've announced to the user */
187
  char *message;			/* State-change message, allocated from proto_pool */
188

189 190 191 192
  /*
   *	General protocol hooks:
   *
   *	   if_notify	Notify protocol about interface state changes.
193
   *	   ifa_notify	Notify protocol about interface address changes.
194 195
   *	   rt_notify	Notify protocol about routing table updates.
   *	   neigh_notify	Notify protocol about neighbor cache events.
196
   *	   make_tmp_attrs  Construct ea_list from private attrs stored in rta.
197
   *	   store_tmp_attrs Store private attrs back to rta. The route MUST NOT be cached.
198
   *	   preexport  Called as the first step of the route exporting process.
199
   *			It can construct a new rte, add private attributes and
200 201
   *			decide whether the route shall be exported: 1=yes, -1=no,
   *			0=process it through the export filter set by the user.
202
   *	   reload_routes   Request channel to reload all its routes to the core
203 204
   *			(using rte_update()). Returns: 0=reload cannot be done,
   *			1= reload is scheduled and will happen (asynchronously).
205 206
   *	   feed_begin	Notify channel about beginning of route feeding.
   *	   feed_end	Notify channel about finish of route feeding.
207 208
   */

209 210
  void (*if_notify)(struct proto *, unsigned flags, struct iface *i);
  void (*ifa_notify)(struct proto *, unsigned flags, struct ifa *a);
211
  void (*rt_notify)(struct proto *, struct channel *, struct network *net, struct rte *new, struct rte *old);
212
  void (*neigh_notify)(struct neighbor *neigh);
213
  struct ea_list *(*make_tmp_attrs)(struct rte *rt, struct linpool *pool);
214
  void (*store_tmp_attrs)(struct rte *rt);
215
  int (*preexport)(struct proto *, struct rte **rt, struct linpool *pool);
216 217 218
  void (*reload_routes)(struct channel *);
  void (*feed_begin)(struct channel *, int initial);
  void (*feed_end)(struct channel *);
219 220

  /*
221
   *	Routing entry hooks (called only for routes belonging to this protocol):
222
   *
223
   *	   rte_recalculate Called at the beginning of the best route selection
224
   *	   rte_better	Compare two rte's and decide which one is better (1=first, 0=second).
225
   *       rte_same	Compare two rte's and decide whether they are identical (1=yes, 0=no).
226
   *       rte_mergable	Compare two rte's and decide whether they could be merged (1=yes, 0=no).
227 228 229
   *	   rte_insert	Called whenever a rte is inserted to a routing table.
   *	   rte_remove	Called whenever a rte is removed from the routing table.
   */
230

231
  int (*rte_recalculate)(struct rtable *, struct network *, struct rte *, struct rte *, struct rte *);
232
  int (*rte_better)(struct rte *, struct rte *);
233
  int (*rte_same)(struct rte *, struct rte *);
234
  int (*rte_mergable)(struct rte *, struct rte *);
235
  struct rte * (*rte_modify)(struct rte *, struct linpool *);
236 237
  void (*rte_insert)(struct network *, struct rte *);
  void (*rte_remove)(struct network *, struct rte *);
238

239 240 241
  /* Hic sunt protocol-specific data */
};

242 243 244 245 246 247
struct proto_spec {
  void *ptr;
  int patt;
};


248 249 250 251 252 253 254 255
#define PDS_DISABLE		1	/* Proto disable scheduled */
#define PDS_RESTART		2	/* Proto restart scheduled */

#define PDC_CF_REMOVE		0x01	/* Removed in new config */
#define PDC_CF_DISABLE		0x02	/* Disabled in new config */
#define PDC_CF_RESTART		0x03	/* Restart due to reconfiguration */
#define PDC_CMD_DISABLE		0x11	/* Result of disable command */
#define PDC_CMD_RESTART		0x12	/* Result of restart command */
256
#define PDC_CMD_SHUTDOWN	0x13	/* Result of global shutdown */
257 258 259
#define PDC_RX_LIMIT_HIT	0x21	/* Route receive limit reached */
#define PDC_IN_LIMIT_HIT	0x22	/* Route import limit reached */
#define PDC_OUT_LIMIT_HIT	0x23	/* Route export limit reached */
260 261


262
void *proto_new(struct proto_config *);
263
void *proto_config_new(struct protocol *, int class);
264
void proto_copy_config(struct proto_config *dest, struct proto_config *src);
265
void proto_set_message(struct proto *p, char *msg, int len);
266

267 268 269
void graceful_restart_recovery(void);
void graceful_restart_init(void);
void graceful_restart_show_status(void);
270 271
void channel_graceful_restart_lock(struct channel *c);
void channel_graceful_restart_unlock(struct channel *c);
272 273

#define DEFAULT_GR_WAIT	240
274

275 276
void channel_show_limit(struct channel_limit *l, const char *dsc);
void channel_show_info(struct channel *c);
277

278 279 280 281 282 283 284
void proto_cmd_show(struct proto *, uintptr_t, int);
void proto_cmd_disable(struct proto *, uintptr_t, int);
void proto_cmd_enable(struct proto *, uintptr_t, int);
void proto_cmd_restart(struct proto *, uintptr_t, int);
void proto_cmd_reload(struct proto *, uintptr_t, int);
void proto_cmd_debug(struct proto *, uintptr_t, int);
void proto_cmd_mrtdump(struct proto *, uintptr_t, int);
Pavel Tvrdík's avatar
Pavel Tvrdík committed
285

286
void proto_apply_cmd(struct proto_spec ps, void (* cmd)(struct proto *, uintptr_t, int), int restricted, uintptr_t arg);
287
struct proto *proto_get_named(struct symbol *, struct protocol *);
288 289 290 291

#define CMD_RELOAD	0
#define CMD_RELOAD_IN	1
#define CMD_RELOAD_OUT	2
292

293 294 295 296 297 298
static inline u32
proto_get_router_id(struct proto_config *pc)
{
  return pc->router_id ? pc->router_id : pc->global->router_id;
}

299 300
static inline void
rte_make_tmp_attrs(struct rte **rt, struct linpool *pool)
301 302
{
  struct ea_list *(*mta)(struct rte *rt, struct linpool *pool);
303 304 305 306 307 308
  mta = (*rt)->attrs->src->proto->make_tmp_attrs;
  if (!mta) return;
  *rt = rte_cow_rta(*rt, pool);
  struct ea_list *ea = mta(*rt, pool);
  ea->next = (*rt)->attrs->eattrs;
  (*rt)->attrs->eattrs = ea;
309 310
}

311

Ondřej Zajíček's avatar
Ondřej Zajíček committed
312
extern pool *proto_pool;
313
extern list proto_list;
314

315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364
/*
 *  Each protocol instance runs two different state machines:
 *
 *  [P] The protocol machine: (implemented inside protocol)
 *
 *		DOWN    ---->    START
 *		  ^		   |
 *		  |		   V
 *		STOP    <----     UP
 *
 *	States:	DOWN	Protocol is down and it's waiting for the core
 *			requesting protocol start.
 *		START	Protocol is waiting for connection with the rest
 *			of the network and it's not willing to accept
 *			packets. When it connects, it goes to UP state.
 *		UP	Protocol is up and running. When the network
 *			connection breaks down or the core requests
 *			protocol to be terminated, it goes to STOP state.
 *		STOP	Protocol is disconnecting from the network.
 *			After it disconnects, it returns to DOWN state.
 *
 *	In:	start()	Called in DOWN state to request protocol startup.
 *			Returns new state: either UP or START (in this
 *			case, the protocol will notify the core when it
 *			finally comes UP).
 *		stop()	Called in START, UP or STOP state to request
 *			protocol shutdown. Returns new state: either
 *			DOWN or STOP (in this case, the protocol will
 *			notify the core when it finally comes DOWN).
 *
 *	Out:	proto_notify_state() -- called by protocol instance when
 *			it does any state transition not covered by
 *			return values of start() and stop(). This includes
 *			START->UP (delayed protocol startup), UP->STOP
 *			(spontaneous shutdown) and STOP->DOWN (delayed
 *			shutdown).
 */

#define PS_DOWN 0
#define PS_START 1
#define PS_UP 2
#define PS_STOP 3

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

/*
 *  [F] The feeder machine: (implemented in core routines)
 *
 *		HUNGRY    ---->   FEEDING
 *		 ^		     |
365
 *		 |		     V
366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382
 *		FLUSHING  <----   HAPPY
 *
 *	States:	HUNGRY	Protocol either administratively down (i.e.,
 *			disabled by the user) or temporarily down
 *			(i.e., [P] is not UP)
 *		FEEDING	The protocol came up and we're feeding it
 *			initial routes. [P] is UP.
 *		HAPPY	The protocol is up and it's receiving normal
 *			routing updates. [P] is UP.
 *		FLUSHING The protocol is down and we're removing its
 *			routes from the table. [P] is STOP or DOWN.
 *
 *	Normal lifecycle of a protocol looks like:
 *
 *		HUNGRY/DOWN --> HUNGRY/START --> HUNGRY/UP -->
 *		FEEDING/UP --> HAPPY/UP --> FLUSHING/STOP|DOWN -->
 *		HUNGRY/STOP|DOWN --> HUNGRY/DOWN
383
 *
384
 *	Sometimes, protocol might switch from HAPPY/UP to FEEDING/UP
385 386
 *	if it wants to refeed the routes (for example BGP does so
 *	as a result of received ROUTE-REFRESH request).
387 388
 */

389

390

391 392 393 394 395 396
/*
 *	Debugging flags
 */

#define D_STATES 1		/* [core] State transitions */
#define D_ROUTES 2		/* [core] Routes passed by the filters */
397 398 399 400
#define D_FILTERS 4		/* [core] Routes rejected by the filters */
#define D_IFACES 8		/* [core] Interface events */
#define D_EVENTS 16		/* Protocol events */
#define D_PACKETS 32		/* Packets sent/received */
401

402 403 404 405 406 407
#ifndef PARSER
#define TRACE(flags, msg, args...) \
  do { if (p->p.debug & flags) log(L_TRACE "%s: " msg, p->p.name , ## args ); } while(0)
#endif


408 409 410 411 412 413 414
/*
 *	MRTDump flags
 */

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

415 416 417 418
/*
 *	Known unique protocol instances as referenced by config routines
 */

419
extern struct proto_config *cf_dev_proto;
420

421 422 423 424 425

/*
 * Protocol limits
 */

426 427 428 429 430
#define PLD_RX		0	/* Receive limit */
#define PLD_IN		1	/* Import limit */
#define PLD_OUT		2	/* Export limit */
#define PLD_MAX		3

431
#define PLA_NONE	0	/* No limit */
432 433 434 435 436
#define PLA_WARN	1	/* Issue log warning */
#define PLA_BLOCK	2	/* Block new routes */
#define PLA_RESTART	4	/* Force protocol restart */
#define PLA_DISABLE	5	/* Shutdown and disable protocol */

437 438 439 440
#define PLS_INITIAL	0	/* Initial limit state after protocol start */
#define PLS_ACTIVE	1	/* Limit was hit */
#define PLS_BLOCKED	2	/* Limit is active and blocking new routes */

441
struct channel_limit {
442
  u32 limit;			/* Maximum number of prefixes */
443 444
  u8 action;			/* Action to take (PLA_*) */
  u8 state;			/* State of limit (PLS_*) */
445 446
};

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

449

450
/*
451
 *	Channels
452 453
 */

454 455 456 457
struct channel_class {
  uint channel_size;			/* Size of channel data structure */
  uint config_size;			/* Size of channel config data structure */

Ondřej Zajíček's avatar
Ondřej Zajíček committed
458
  void (*init)(struct channel *, struct channel_config *);	/* Create new instance */
459 460
  int (*reconfigure)(struct channel *, struct channel_config *);	/* Try to reconfigure instance, returns success */
  int (*start)(struct channel *);	/* Start the instance */
Ondřej Zajíček's avatar
Ondřej Zajíček committed
461 462
  void (*shutdown)(struct channel *);	/* Stop the instance */
  void (*cleanup)(struct channel *);	/* Channel finished flush */
463 464 465

  void (*copy_config)(struct channel_config *, struct channel_config *); /* Copy config from given channel instance */
#if 0
Ondřej Zajíček's avatar
Ondřej Zajíček committed
466
  XXXX;
467 468 469 470 471 472
  void (*preconfig)(struct protocol *, struct config *);	/* Just before configuring */
  void (*postconfig)(struct proto_config *);			/* After configuring each instance */


  void (*dump)(struct proto *);			/* Debugging dump */
  void (*dump_attrs)(struct rte *);		/* Dump protocol-dependent attributes */
Ondřej Zajíček's avatar
Ondřej Zajíček committed
473

474
  void (*get_status)(struct proto *, byte *buf); /* Get instance status (for `show protocols' command) */
475
  void (*get_route_info)(struct rte *, byte *buf); /* Get route information (for `show route' command) */
476 477 478 479 480 481
  int (*get_attr)(struct eattr *, byte *buf, int buflen);	/* ASCIIfy dynamic attribute (returns GA_*) */
  void (*show_proto_info)(struct proto *);	/* Show protocol info (for `show protocols all' command) */

#endif
};

Ondřej Zajíček's avatar
Ondřej Zajíček committed
482 483
extern struct channel_class channel_bgp;

484
struct channel_config {
485
  node n;
486 487 488
  const char *name;
  const struct channel_class *channel;

489
  struct proto_config *parent;		/* Where channel is defined (proto or template) */
490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509
  struct rtable_config *table;		/* Table we're attached to */
  struct filter *in_filter, *out_filter; /* Attached filters */
  struct channel_limit rx_limit;	/* Limit for receiving routes from protocol
					   (relevant when in_keep_filtered is active) */
  struct channel_limit in_limit;	/* Limit for importing routes from protocol */
  struct channel_limit out_limit;	/* Limit for exporting routes to protocol */

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

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

  const char *name;			/* Channel name (may be NULL) */
  const struct channel_class *channel;
510
  struct proto *proto;
511 512

  struct rtable *table;
513 514
  struct filter *in_filter;		/* Input filter */
  struct filter *out_filter;		/* Output filter */
515 516 517 518 519 520 521 522 523 524 525 526 527 528
  struct channel_limit rx_limit;	/* Receive limit (for in_keep_filtered) */
  struct channel_limit in_limit;	/* Input limit */
  struct channel_limit out_limit;	/* Output limit */

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

  u8 net_type;				/* Routing table network type (NET_*), 0 for undefined */
  u8 ra_mode;				/* Mode of received route advertisements (RA_*) */
  u16 preference;			/* Default route preference */
  u8 merge_limit;			/* Maximal number of nexthops for RA_MERGED */
  u8 in_keep_filtered;			/* Routes rejected in import filter are kept */
  u8 disabled;
Ondřej Zajíček's avatar
Ondřej Zajíček committed
529
  u8 stale;				/* Used in reconfiguration */
530 531 532 533 534 535 536 537 538 539

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

540
  btime last_state_change;		/* Time of last state transition */
541
  btime last_tx_filter_change;
542 543 544 545 546

  struct rtable *in_table;		/* Internal table for received routes */
  struct event *reload_event;		/* Event responsible for reloading from in_table */
  struct fib_iterator reload_fit;	/* Iterator in in_table used during reloading */
  u8 reload_active;			/* Iterator reload_fit is linked */
547 548
};

549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608

/*
 * Channel states
 *
 * CS_DOWN - The initial and the final state of a channel. There is no route
 * exchange between the protocol and the table. Channel is not counted as
 * active. Channel keeps a ptr to the table, but do not lock the table and is
 * not linked in the table. Generally, new closed channels are created in
 * protocols' init() hooks. The protocol is expected to explicitly activate its
 * channels (by calling channel_init() or channel_open()).
 *
 * CS_START - The channel as a connection between the protocol and the table is
 * initialized (counted as active by the protocol, linked in the table and keeps
 * the table locked), but there is no current route exchange. There still may be
 * routes associated with the channel in the routing table if the channel falls
 * to CS_START from CS_UP. Generally, channels are initialized in protocols'
 * start() hooks when going to PS_START.
 *
 * CS_UP - The channel is initialized and the route exchange is allowed. Note
 * that even in CS_UP state, route export may still be down (ES_DOWN) by the
 * core decision (e.g. waiting for table convergence after graceful restart).
 * I.e., the protocol decides to open the channel but the core decides to start
 * route export. Route import (caused by rte_update() from the protocol) is not
 * restricted by that and is on volition of the protocol. Generally, channels
 * are opened in protocols' start() hooks when going to PS_UP.
 *
 * CS_FLUSHING - The transitional state between initialized channel and closed
 * channel. The channel is still initialized, but no route exchange is allowed.
 * Instead, the associated table is running flush loop to remove routes imported
 * through the channel. After that, the channel changes state to CS_DOWN and
 * is detached from the table (the table is unlocked and the channel is unlinked
 * from it). Unlike other states, the CS_FLUSHING state is not explicitly
 * entered or left by the protocol. A protocol may request to close a channel
 * (by calling channel_close()), which causes the channel to change state to
 * CS_FLUSHING and later to CS_DOWN. Also note that channels are closed
 * automatically by the core when the protocol is going down.
 *
 * Allowed transitions:
 *
 * CS_DOWN	-> CS_START / CS_UP
 * CS_START	-> CS_UP / CS_FLUSHING
 * CS_UP	-> CS_START / CS_FLUSHING
 * CS_FLUSHING	-> CS_DOWN (automatic)
 */

#define CS_DOWN		0
#define CS_START	1
#define CS_UP		2
#define CS_FLUSHING	3

#define ES_DOWN		0
#define ES_FEEDING	1
#define ES_READY	2


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

struct channel *proto_find_channel_by_table(struct proto *p, struct rtable *t);
609
struct channel *proto_find_channel_by_name(struct proto *p, const char *n);
610 611 612 613
struct channel *proto_add_channel(struct proto *p, struct channel_config *cf);
int proto_configure_channel(struct proto *p, struct channel **c, struct channel_config *cf);

void channel_set_state(struct channel *c, uint state);
614 615
void channel_setup_in_table(struct channel *c);
void channel_schedule_reload(struct channel *c);
616 617 618 619 620 621

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

void channel_request_feeding(struct channel *c);
622 623
void *channel_config_new(const struct channel_class *cc, const char *name, uint net_type, struct proto_config *proto);
void *channel_config_get(const struct channel_class *cc, const char *name, uint net_type, struct proto_config *proto);
624 625
int channel_reconfigure(struct channel *c, struct channel_config *cf);

626

627 628 629 630 631 632 633 634 635 636 637 638 639
/* Moved from route.h to avoid dependency conflicts */
static inline void rte_update(struct proto *p, const net_addr *n, rte *new) { rte_update2(p->main_channel, n, new, p->main_source); }

static inline void
rte_update3(struct channel *c, const net_addr *n, rte *new, struct rte_src *src)
{
  if (c->in_table && !rte_update_in(c, n, new, src))
    return;

  rte_update2(c, n, new, src);
}


640
#endif