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

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

31 32 33 34 35
/*
 *	Routing Protocol
 */

struct protocol {
36
  node n;
37
  char *name;
38
  char *template;			/* Template for automatic generation of names */
39
  int name_counter;			/* Counter for automatic name generation */
40
  int attr_class;			/* Attribute class known to this protocol */
41

42 43 44
  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 */
45
  int (*reconfigure)(struct proto *, struct proto_config *);	/* Try to reconfigure instance, returns success */
46
  void (*dump)(struct proto *);			/* Debugging dump */
47
  void (*dump_attrs)(struct rte *);		/* Dump protocol-dependent attributes */
48 49
  int (*start)(struct proto *);			/* Start the instance */
  int (*shutdown)(struct proto *);		/* Stop the instance */
50
  void (*get_status)(struct proto *, byte *buf); /* Get instance status (for `show protocols' command) */
51
  void (*get_route_info)(struct rte *, byte *buf, struct ea_list *attrs); /* Get route information (for `show route' command) */
52
  int (*get_attr)(struct eattr *, byte *buf, int buflen);	/* ASCIIfy dynamic attribute (returns GA_*) */
53 54
};

55
void protos_build(void);
56
void proto_build(struct protocol *);
57 58
void protos_preconfig(struct config *);
void protos_postconfig(struct config *);
59
void protos_commit(struct config *new, struct config *old, int force_restart, int type);
60
void protos_dump_all(void);
61

62 63 64
#define GA_UNKNOWN	0		/* Attribute not recognized */
#define GA_NAME		1		/* Result = name */
#define GA_FULL		2		/* Result = both name and value */
65 66 67 68 69

/*
 *	Known protocols
 */

Martin Mareš's avatar
Martin Mareš committed
70 71 72
extern struct protocol
  proto_device, proto_rip, proto_static,
  proto_ospf, proto_pipe, proto_bgp;
73 74 75 76 77

/*
 *	Routing Protocol Instance
 */

78 79 80
struct proto_config {
  node n;
  struct config *global;		/* Global configuration data */
81 82
  struct protocol *protocol;		/* Protocol */
  struct proto *proto;			/* Instance we've created */
83
  char *name;
84
  char *dsc;
85 86
  u32 debug, mrtdump;			/* Debugging bitfields, both use D_* constants */
  unsigned preference, disabled;	/* Generic parameters */
87
  u32 router_id;			/* Protocol specific router ID */
88
  struct rtable_config *table;		/* Table we're attached to */
89
  struct filter *in_filter, *out_filter; /* Attached filters */
90 91 92 93

  /* Protocol-specific data follow... */
};

94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
  /* Protocol statistics */
struct proto_stats {
  /* Import - from protocol to core */
  u32 imp_routes;		/* Number of routes successfully imported to the (adjacent) routing table */
  u32 pref_routes;		/* Number of routes that are preferred, sum over all routing table */
  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 */
  u32 exp_updates_accepted;	/* Number of route updates accepted and exported */ 
  u32 exp_withdraws_received;	/* Number of route withdraws received */
  u32 exp_withdraws_accepted;	/* Number of route withdraws accepted and processed */
};

119
struct proto {
120 121
  node n;				/* Node in *_proto_list */
  node glob_node;			/* Node in global proto_list */
122
  struct protocol *proto;		/* Protocol */
123
  struct proto_config *cf;		/* Configuration data */
124
  struct proto_config *cf_new;		/* Configuration we want to switch to after shutdown (NULL=delete) */
125
  pool *pool;				/* Pool containing local objects */
126
  struct event *attn;			/* "Pay attention" event */
127

128
  char *name;				/* Name of this instance (== cf->name) */
129 130
  u32 debug;				/* Debugging flags */
  u32 mrtdump;				/* MRTDump flags */
131
  unsigned preference;			/* Default route preference */
132
  int min_scope;			/* Minimal route scope accepted */
133
  unsigned accept_ra_types;		/* Which types of route announcements are accepted (RA_OPTIMAL or RA_ANY) */
134
  unsigned disabled;			/* Manually disabled */
135 136
  unsigned proto_state;			/* Protocol state machine (see below) */
  unsigned core_state;			/* Core state machine (see below) */
137
  unsigned core_goal;			/* State we want to reach (see below) */
138
  unsigned reconfiguring;		/* We're shutting down due to reconfiguration */
Ondřej Zajíček's avatar
Ondřej Zajíček committed
139
  unsigned refeeding;			/* We are refeeding (valid only if core_state == FS_FEEDING) */
140
  u32 hash_key;				/* Random key used for hashing of neighbors */
141
  bird_clock_t last_state_change;	/* Time of last state transition */
142
  char *last_state_name_announced;	/* Last state name we've announced to the user */
143
  struct proto_stats stats;		/* Current protocol statistics */
144

145 146 147 148
  /*
   *	General protocol hooks:
   *
   *	   if_notify	Notify protocol about interface state changes.
149
   *	   ifa_notify	Notify protocol about interface address changes.
150 151 152 153 154 155 156 157
   *	   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.
158 159 160
   *	   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).
161 162
   */

163 164
  void (*if_notify)(struct proto *, unsigned flags, struct iface *i);
  void (*ifa_notify)(struct proto *, unsigned flags, struct ifa *a);
165
  void (*rt_notify)(struct proto *, struct network *net, struct rte *new, struct rte *old, struct ea_list *attrs);
166
  void (*neigh_notify)(struct neighbor *neigh);
167 168 169
  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);
170
  int (*reload_routes)(struct proto *);
171 172 173 174 175

  /*
   *	Routing entry hooks (called only for rte's belonging to this protocol):
   *
   *	   rte_better	Compare two rte's and decide which one is better (1=first, 0=second).
176
   *       rte_same	Compare two rte's and decide whether they are identical (1=yes, 0=no).
177 178 179
   *	   rte_insert	Called whenever a rte is inserted to a routing table.
   *	   rte_remove	Called whenever a rte is removed from the routing table.
   */
180

181
  int (*rte_better)(struct rte *, struct rte *);
182
  int (*rte_same)(struct rte *, struct rte *);
183 184
  void (*rte_insert)(struct network *, struct rte *);
  void (*rte_remove)(struct network *, struct rte *);
185

186
  struct rtable *table;			/* Our primary routing table */
187 188
  struct filter *in_filter;		/* Input filter */
  struct filter *out_filter;		/* Output filter */
189
  struct announce_hook *ahooks;		/* Announcement hooks for this protocol */
190

191 192 193
  struct fib_iterator *feed_iterator;	/* Routing table iterator used during protocol feeding */
  struct announce_hook *feed_ahook;	/* Announce hook we currently feed */

194 195 196
  /* Hic sunt protocol-specific data */
};

197 198
void *proto_new(struct proto_config *, unsigned size);
void *proto_config_new(struct protocol *, unsigned size);
199

200
void proto_request_feeding(struct proto *p);
201
void proto_show(struct symbol *, int);
202
struct proto *proto_get_named(struct symbol *, struct protocol *);
203
void proto_xxable(char *, int);
204
void proto_debug(char *, int, unsigned int);
205

206 207 208 209 210 211 212
#define XX_DISABLE	0
#define XX_ENABLE	1
#define XX_RESTART	2
#define XX_RELOAD	3
#define XX_RELOAD_IN	4
#define XX_RELOAD_OUT	5

213 214 215 216 217 218
static inline u32
proto_get_router_id(struct proto_config *pc)
{
  return pc->router_id ? pc->router_id : pc->global->router_id;
}

219
extern list active_proto_list;
220

221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288
/*
 *  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
289 290 291 292
 *
 *	Sometimes, protocol might switch from HAPPY/UP to FEEDING/UP 
 *	if it wants to refeed the routes (for example BGP does so
 *	as a result of received ROUTE-REFRESH request).
293 294 295 296 297 298 299
 */

#define FS_HUNGRY 0
#define FS_FEEDING 1
#define FS_HAPPY 2
#define FS_FLUSHING 3

300 301 302 303 304 305
/*
 *	Debugging flags
 */

#define D_STATES 1		/* [core] State transitions */
#define D_ROUTES 2		/* [core] Routes passed by the filters */
306 307 308 309
#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 */
310

311 312 313 314 315 316 317
/*
 *	MRTDump flags
 */

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

318 319 320 321
/*
 *	Known unique protocol instances as referenced by config routines
 */

322
extern struct proto_config *cf_dev_proto;
323

324 325 326 327 328 329 330 331 332 333 334 335 336
/*
 *	Route Announcement Hook
 */

struct announce_hook {
  node n;
  struct rtable *table;
  struct proto *proto;
  struct announce_hook *next;		/* Next hook for the same protocol */
};

struct announce_hook *proto_add_announce_hook(struct proto *, struct rtable *);

337 338 339 340 341 342 343 344 345 346
/*
 *	Some pipe-specific nest hacks
 */

#ifdef CONFIG_PIPE

static inline int proto_is_pipe(struct proto *p)
{ return p->proto == &proto_pipe; }

struct rtable *pipe_get_peer_table(struct proto *p);
347
struct proto_stats *pipe_get_peer_stats(struct proto *p);
348 349 350 351

#endif


352
#endif