protocol.h 18.5 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
#include "lib/timer.h"
15
#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 26 27
struct proto_config;
struct config;
struct proto;
28
struct event;
29
struct ea_list;
30
struct eattr;
31
struct symbol;
32

33 34 35 36 37
/*
 *	Routing Protocol
 */

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

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

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

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

/*
 *	Known protocols
 */

78
extern struct protocol
79
  proto_device, proto_radv, proto_rip, proto_static,
80
  proto_ospf, proto_pipe, proto_bgp, proto_bfd, proto_babel;
81 82 83 84 85

/*
 *	Routing Protocol Instance
 */

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

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

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

111
/* Protocol statistics */
112 113 114
struct proto_stats {
  /* Import - from protocol to core */
  u32 imp_routes;		/* Number of routes successfully imported to the (adjacent) routing table */
115
  u32 filt_routes;		/* Number of routes rejected in import filter but kept in the routing table */
116
  u32 pref_routes;		/* Number of routes that are preferred, sum over all routing tables */
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
  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 */
132
  u32 exp_updates_accepted;	/* Number of route updates accepted and exported */
133 134 135 136
  u32 exp_withdraws_received;	/* Number of route withdraws received */
  u32 exp_withdraws_accepted;	/* Number of route withdraws accepted and processed */
};

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

146
  char *name;				/* Name of this instance (== cf->name) */
147 148
  u32 debug;				/* Debugging flags */
  u32 mrtdump;				/* MRTDump flags */
149
  unsigned preference;			/* Default route preference */
150 151 152 153
  byte accept_ra_types;			/* Which types of route announcements are accepted (RA_OPTIMAL or RA_ANY) */
  byte disabled;			/* Manually disabled */
  byte proto_state;			/* Protocol state machine (PS_*, see below) */
  byte core_state;			/* Core state machine (FS_*, see below) */
154
  byte export_state;			/* Route export state (ES_*, see below) */
155
  byte reconfiguring;			/* We're shutting down due to reconfiguration */
156
  byte refeeding;			/* We are refeeding (valid only if export_state == ES_FEEDING) */
157
  byte flushing;			/* Protocol is flushed in current flush loop round */
158 159 160
  byte gr_recovery;			/* Protocol should participate in graceful restart recovery */
  byte gr_lock;				/* Graceful restart mechanism should wait for this proto */
  byte gr_wait;				/* Route export to protocol is postponed until graceful restart */
161 162
  byte down_sched;			/* Shutdown is scheduled for later (PDS_*) */
  byte down_code;			/* Reason for shutdown (PDC_* codes) */
163
  byte merge_limit;			/* Maximal number of nexthops for RA_MERGED */
164
  u32 hash_key;				/* Random key used for hashing of neighbors */
165
  bird_clock_t last_state_change;	/* Time of last state transition */
166
  char *last_state_name_announced;	/* Last state name we've announced to the user */
167
  char *message;			/* State-change message, allocated from proto_pool */
168
  struct proto_stats stats;		/* Current protocol statistics */
169

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

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

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

212
  int (*rte_recalculate)(struct rtable *, struct network *, struct rte *, struct rte *, struct rte *);
213
  int (*rte_better)(struct rte *, struct rte *);
214
  int (*rte_same)(struct rte *, struct rte *);
215
  int (*rte_mergable)(struct rte *, struct rte *);
216 217
  void (*rte_insert)(struct network *, struct rte *);
  void (*rte_remove)(struct network *, struct rte *);
218

Ondřej Zajíček's avatar
Ondřej Zajíček committed
219
  struct iface *vrf;			/* Related VRF instance, NULL if global */
220
  struct rtable *table;			/* Our primary routing table */
221
  struct rte_src *main_source;		/* Primary route source */
222
  struct announce_hook *main_ahook;	/* Primary announcement hook */
223
  struct announce_hook *ahooks;		/* Announcement hooks for this protocol */
224

225 226 227
  struct fib_iterator *feed_iterator;	/* Routing table iterator used during protocol feeding */
  struct announce_hook *feed_ahook;	/* Announce hook we currently feed */

228 229 230
  /* Hic sunt protocol-specific data */
};

231 232 233 234 235 236
struct proto_spec {
  void *ptr;
  int patt;
};


237 238 239 240 241 242 243 244
#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 */
245
#define PDC_CMD_SHUTDOWN	0x13	/* Result of global shutdown */
246 247 248
#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 */
249 250


251
void *proto_new(struct proto_config *, unsigned size);
252
void *proto_config_new(struct protocol *, int class);
253
void proto_copy_config(struct proto_config *dest, struct proto_config *src);
254
void proto_set_message(struct proto *p, char *msg, int len);
255
void proto_request_feeding(struct proto *p);
256

257 258 259 260
static inline void
proto_copy_rest(struct proto_config *dest, struct proto_config *src, unsigned size)
{ memcpy(dest + 1, src + 1, size - sizeof(struct proto_config)); }

261 262 263 264 265 266 267
void graceful_restart_recovery(void);
void graceful_restart_init(void);
void graceful_restart_show_status(void);
void proto_graceful_restart_lock(struct proto *p);
void proto_graceful_restart_unlock(struct proto *p);

#define DEFAULT_GR_WAIT	240
268

269
void proto_show_limit(struct proto_limit *l, const char *dsc);
270 271
void proto_show_basic_info(struct proto *p);

272 273 274 275 276 277 278
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
279

280
void proto_apply_cmd(struct proto_spec ps, void (* cmd)(struct proto *, uintptr_t, int), int restricted, uintptr_t arg);
281
struct proto *proto_get_named(struct symbol *, struct protocol *);
282 283 284 285

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

287 288 289 290 291 292
static inline u32
proto_get_router_id(struct proto_config *pc)
{
  return pc->router_id ? pc->router_id : pc->global->router_id;
}

293 294 295 296 297 298 299 300 301 302 303
static inline struct ea_list *
rte_make_tmp_attrs(struct rte *rt, struct linpool *pool)
{
  struct ea_list *(*mta)(struct rte *rt, struct linpool *pool);
  mta = rt->attrs->src->proto->make_tmp_attrs;
  return mta ? mta(rt, pool) : NULL;
}

/* Moved from route.h to avoid dependency conflicts */
static inline void rte_update(struct proto *p, net *net, rte *new) { rte_update2(p->main_ahook, net, new, p->main_source); }

304
extern list active_proto_list;
305

306 307 308 309 310 311 312 313 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 365 366 367 368 369 370 371 372 373
/*
 *  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
 *		 ^		     |
 *		 | 		     V
 *		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
374
 *
375
 *	Sometimes, protocol might switch from HAPPY/UP to FEEDING/UP
376 377
 *	if it wants to refeed the routes (for example BGP does so
 *	as a result of received ROUTE-REFRESH request).
378 379
 */

380 381 382 383 384 385 386 387 388 389 390
#define FS_HUNGRY	0
#define FS_FEEDING	1	/* obsolete */
#define FS_HAPPY	2
#define FS_FLUSHING	3


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


391

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

#define D_STATES 1		/* [core] State transitions */
#define D_ROUTES 2		/* [core] Routes passed by the filters */
398 399 400 401
#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 */
402

403 404 405 406 407 408
#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


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

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

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

420
extern struct proto_config *cf_dev_proto;
421

422 423 424 425 426

/*
 * Protocol limits
 */

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

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 442 443
struct proto_limit {
  u32 limit;			/* Maximum number of prefixes */
  byte action;			/* Action to take (PLA_*) */
444
  byte state;			/* State of limit (PLS_*) */
445 446
};

447
void proto_notify_limit(struct announce_hook *ah, struct proto_limit *l, int dir, u32 rt_count);
448
void proto_verify_limits(struct announce_hook *ah);
449

450 451
static inline void
proto_reset_limit(struct proto_limit *l)
452 453 454 455 456
{
  if (l)
    l->state = PLS_INITIAL;
}

457

458 459 460 461 462 463 464 465
/*
 *	Route Announcement Hook
 */

struct announce_hook {
  node n;
  struct rtable *table;
  struct proto *proto;
466 467
  struct filter *in_filter;		/* Input filter */
  struct filter *out_filter;		/* Output filter */
468
  struct proto_limit *rx_limit;		/* Receive limit (for in_keep_filtered) */
469
  struct proto_limit *in_limit;		/* Input limit */
470
  struct proto_limit *out_limit;	/* Output limit */
471
  struct proto_stats *stats;		/* Per-table protocol statistics */
472
  struct announce_hook *next;		/* Next hook for the same protocol */
473
  int in_keep_filtered;			/* Routes rejected in import filter are kept */
474 475
};

476
struct announce_hook *proto_add_announce_hook(struct proto *p, struct rtable *t, struct proto_stats *stats);
477
struct announce_hook *proto_find_announce_hook(struct proto *p, struct rtable *t);
478

479
#endif