xref: /openbsd-src/usr.sbin/bgpd/bgpd.h (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1 /*	$OpenBSD: bgpd.h,v 1.295 2016/09/02 14:00:29 benno Exp $ */
2 
3 /*
4  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 #ifndef __BGPD_H__
19 #define	__BGPD_H__
20 
21 #include <sys/types.h>
22 #include <sys/socket.h>
23 #include <sys/queue.h>
24 #include <sys/tree.h>
25 #include <net/route.h>
26 #include <netinet/in.h>
27 #include <arpa/inet.h>
28 #include <net/if.h>
29 #include <net/pfkeyv2.h>
30 
31 #include <poll.h>
32 #include <stdarg.h>
33 
34 #include <imsg.h>
35 
36 #include "log.h"
37 
38 #define	BGP_VERSION			4
39 #define	BGP_PORT			179
40 #define	CONFFILE			"/etc/bgpd.conf"
41 #define	BGPD_USER			"_bgpd"
42 #define	PEER_DESCR_LEN			32
43 #define	PFTABLE_LEN			32
44 #define	TCP_MD5_KEY_LEN			80
45 #define	IPSEC_ENC_KEY_LEN		32
46 #define	IPSEC_AUTH_KEY_LEN		20
47 
48 #define	MAX_PKTSIZE			4096
49 #define	MIN_HOLDTIME			3
50 #define	READ_BUF_SIZE			65535
51 #define	RT_BUF_SIZE			16384
52 #define	MAX_RTSOCK_BUF			128 * 1024
53 
54 #define	BGPD_OPT_VERBOSE		0x0001
55 #define	BGPD_OPT_VERBOSE2		0x0002
56 #define	BGPD_OPT_NOACTION		0x0004
57 #define	BGPD_OPT_FORCE_DEMOTE		0x0008
58 
59 #define	BGPD_FLAG_NO_EVALUATE		0x0002
60 #define	BGPD_FLAG_REFLECTOR		0x0004
61 #define	BGPD_FLAG_NEXTHOP_BGP		0x0080
62 #define	BGPD_FLAG_NEXTHOP_DEFAULT	0x1000
63 #define	BGPD_FLAG_DECISION_MASK		0x0f00
64 #define	BGPD_FLAG_DECISION_ROUTEAGE	0x0100
65 #define	BGPD_FLAG_DECISION_TRANS_AS	0x0200
66 #define	BGPD_FLAG_DECISION_MED_ALWAYS	0x0400
67 
68 #define	BGPD_LOG_UPDATES		0x0001
69 
70 #define	SOCKET_NAME			"/var/run/bgpd.sock"
71 
72 #define	F_BGPD_INSERTED		0x0001
73 #define	F_KERNEL		0x0002
74 #define	F_CONNECTED		0x0004
75 #define	F_NEXTHOP		0x0008
76 #define	F_DOWN			0x0010
77 #define	F_STATIC		0x0020
78 #define	F_DYNAMIC		0x0040
79 #define	F_REJECT		0x0080
80 #define	F_BLACKHOLE		0x0100
81 #define	F_LONGER		0x0200
82 #define	F_MPLS			0x0400
83 #define	F_REDISTRIBUTED		0x0800
84 #define	F_CTL_DETAIL		0x1000	/* only used by bgpctl */
85 #define	F_CTL_ADJ_IN		0x2000
86 #define	F_CTL_ADJ_OUT		0x4000
87 #define	F_CTL_ACTIVE		0x8000
88 
89 /*
90  * Limit the number of control messages generated by the RDE and queued in
91  * session engine. The RDE limit defines how many imsg are generated in
92  * one poll round. Then if the SE limit is hit the RDE control socket will no
93  * longer be polled.
94  */
95 #define RDE_RUNNER_ROUNDS	100
96 #define SESSION_CTL_QUEUE_MAX	10000
97 
98 enum bgpd_process {
99 	PROC_MAIN,
100 	PROC_SE,
101 	PROC_RDE
102 } bgpd_process;
103 
104 enum reconf_action {
105 	RECONF_NONE,
106 	RECONF_KEEP,
107 	RECONF_REINIT,
108 	RECONF_RELOAD,
109 	RECONF_DELETE
110 };
111 
112 /* Address Family Numbers as per RFC 1700 */
113 #define	AFI_UNSPEC	0
114 #define	AFI_IPv4	1
115 #define	AFI_IPv6	2
116 
117 /* Subsequent Address Family Identifier as per RFC 4760 */
118 #define	SAFI_NONE	0
119 #define	SAFI_UNICAST	1
120 #define	SAFI_MULTICAST	2
121 #define	SAFI_MPLS	4
122 #define	SAFI_MPLSVPN	128
123 
124 struct aid {
125 	u_int16_t	 afi;
126 	sa_family_t	 af;
127 	u_int8_t	 safi;
128 	char		*name;
129 };
130 
131 extern const struct aid aid_vals[];
132 
133 #define	AID_UNSPEC	0
134 #define	AID_INET	1
135 #define	AID_INET6	2
136 #define	AID_VPN_IPv4	3
137 #define	AID_MAX		4
138 #define	AID_MIN		1	/* skip AID_UNSPEC since that is a dummy */
139 
140 #define AID_VALS	{					\
141 	/* afi, af, safii, name */				\
142 	{ AFI_UNSPEC, AF_UNSPEC, SAFI_NONE, "unspec"},		\
143 	{ AFI_IPv4, AF_INET, SAFI_UNICAST, "IPv4 unicast" },	\
144 	{ AFI_IPv6, AF_INET6, SAFI_UNICAST, "IPv6 unicast" },	\
145 	{ AFI_IPv4, AF_INET, SAFI_MPLSVPN, "IPv4 vpn" }		\
146 }
147 
148 #define AID_PTSIZE	{				\
149 	0,						\
150 	sizeof(struct pt_entry4), 			\
151 	sizeof(struct pt_entry6),			\
152 	sizeof(struct pt_entry_vpn4)			\
153 }
154 
155 struct vpn4_addr {
156 	u_int64_t	rd;
157 	struct in_addr	addr;
158 	u_int8_t	labelstack[21];	/* max that makes sense */
159 	u_int8_t	labellen;
160 	u_int8_t	pad1;
161 	u_int8_t	pad2;
162 };
163 
164 #define BGP_MPLS_BOS	0x01
165 
166 struct bgpd_addr {
167 	union {
168 		struct in_addr		v4;
169 		struct in6_addr		v6;
170 		struct vpn4_addr	vpn4;
171 		/* maximum size for a prefix is 256 bits */
172 		u_int8_t		addr8[32];
173 		u_int16_t		addr16[16];
174 		u_int32_t		addr32[8];
175 	} ba;		    /* 128-bit address */
176 	u_int32_t	scope_id;	/* iface scope id for v6 */
177 	u_int8_t	aid;
178 #define	v4	ba.v4
179 #define	v6	ba.v6
180 #define	vpn4	ba.vpn4
181 #define	addr8	ba.addr8
182 #define	addr16	ba.addr16
183 #define	addr32	ba.addr32
184 };
185 
186 #define	DEFAULT_LISTENER	0x01
187 #define	LISTENER_LISTENING	0x02
188 
189 struct listen_addr {
190 	TAILQ_ENTRY(listen_addr)	 entry;
191 	struct sockaddr_storage		 sa;
192 	int				 fd;
193 	enum reconf_action		 reconf;
194 	u_int8_t			 flags;
195 };
196 
197 TAILQ_HEAD(listen_addrs, listen_addr);
198 TAILQ_HEAD(filter_set_head, filter_set);
199 
200 struct rdomain;
201 SIMPLEQ_HEAD(rdomain_head, rdomain);
202 
203 struct network;
204 TAILQ_HEAD(network_head, network);
205 
206 struct filter_rule;
207 TAILQ_HEAD(filter_head, filter_rule);
208 
209 struct bgpd_config {
210 	struct rdomain_head			 rdomains;
211 	struct network_head			 networks;
212 	struct filter_head			*filters;
213 	struct listen_addrs			*listen_addrs;
214 	struct mrt_head				*mrt;
215 	char					*csock;
216 	char					*rcsock;
217 	int					 flags;
218 	int					 log;
219 	u_int32_t				 bgpid;
220 	u_int32_t				 clusterid;
221 	u_int32_t				 as;
222 	u_int16_t				 short_as;
223 	u_int16_t				 holdtime;
224 	u_int16_t				 min_holdtime;
225 	u_int16_t				 connectretry;
226 	u_int8_t				 fib_priority;
227 };
228 
229 extern int cmd_opts;
230 
231 enum announce_type {
232 	ANNOUNCE_UNDEF,
233 	ANNOUNCE_SELF,
234 	ANNOUNCE_NONE,
235 	ANNOUNCE_DEFAULT_ROUTE,
236 	ANNOUNCE_ALL
237 };
238 
239 enum enforce_as {
240 	ENFORCE_AS_UNDEF,
241 	ENFORCE_AS_OFF,
242 	ENFORCE_AS_ON
243 };
244 
245 enum auth_method {
246 	AUTH_NONE,
247 	AUTH_MD5SIG,
248 	AUTH_IPSEC_MANUAL_ESP,
249 	AUTH_IPSEC_MANUAL_AH,
250 	AUTH_IPSEC_IKE_ESP,
251 	AUTH_IPSEC_IKE_AH
252 };
253 
254 struct peer_auth {
255 	char			md5key[TCP_MD5_KEY_LEN];
256 	char			auth_key_in[IPSEC_AUTH_KEY_LEN];
257 	char			auth_key_out[IPSEC_AUTH_KEY_LEN];
258 	char			enc_key_in[IPSEC_ENC_KEY_LEN];
259 	char			enc_key_out[IPSEC_ENC_KEY_LEN];
260 	u_int32_t		spi_in;
261 	u_int32_t		spi_out;
262 	enum auth_method	method;
263 	u_int8_t		md5key_len;
264 	u_int8_t		auth_alg_in;
265 	u_int8_t		auth_alg_out;
266 	u_int8_t		auth_keylen_in;
267 	u_int8_t		auth_keylen_out;
268 	u_int8_t		enc_alg_in;
269 	u_int8_t		enc_alg_out;
270 	u_int8_t		enc_keylen_in;
271 	u_int8_t		enc_keylen_out;
272 };
273 
274 struct capabilities {
275 	struct {
276 		int16_t	timeout;	/* graceful restart timeout */
277 		int8_t	flags[AID_MAX];	/* graceful restart per AID flags */
278 		int8_t	restart;	/* graceful restart, RFC 4724 */
279 	}	grestart;
280 	int8_t	mp[AID_MAX];		/* multiprotocol extensions, RFC 4760 */
281 	int8_t	refresh;		/* route refresh, RFC 2918 */
282 	int8_t	as4byte;		/* 4-byte ASnum, RFC 4893 */
283 };
284 
285 #define	CAPA_GR_PRESENT		0x01
286 #define	CAPA_GR_RESTART		0x02
287 #define	CAPA_GR_FORWARD		0x04
288 #define	CAPA_GR_RESTARTING	0x08
289 
290 #define	CAPA_GR_TIMEMASK	0x0fff
291 #define	CAPA_GR_R_FLAG		0x8000
292 #define	CAPA_GR_F_FLAG		0x80
293 
294 struct peer_config {
295 	struct bgpd_addr	 remote_addr;
296 	struct bgpd_addr	 local_addr;
297 	struct peer_auth	 auth;
298 	struct capabilities	 capabilities;
299 	char			 group[PEER_DESCR_LEN];
300 	char			 descr[PEER_DESCR_LEN];
301 	char			 rib[PEER_DESCR_LEN];
302 	char			 if_depend[IFNAMSIZ];
303 	char			 demote_group[IFNAMSIZ];
304 	u_int32_t		 id;
305 	u_int32_t		 groupid;
306 	u_int32_t		 remote_as;
307 	u_int32_t		 local_as;
308 	u_int32_t		 max_prefix;
309 	enum announce_type	 announce_type;
310 	enum enforce_as		 enforce_as;
311 	enum reconf_action	 reconf_action;
312 	u_int16_t		 max_prefix_restart;
313 	u_int16_t		 holdtime;
314 	u_int16_t		 min_holdtime;
315 	u_int16_t		 local_short_as;
316 	u_int8_t		 template;
317 	u_int8_t		 remote_masklen;
318 	u_int8_t		 ebgp;		/* 0 = ibgp else ebgp */
319 	u_int8_t		 distance;	/* 1 = direct, >1 = multihop */
320 	u_int8_t		 passive;
321 	u_int8_t		 down;
322 	u_int8_t		 announce_capa;
323 	u_int8_t		 reflector_client;
324 	u_int8_t		 softreconfig_in;
325 	u_int8_t		 softreconfig_out;
326 	u_int8_t		 ttlsec;	/* TTL security hack */
327 	u_int8_t		 flags;
328 };
329 
330 #define PEERFLAG_TRANS_AS	0x01
331 #define PEERFLAG_LOG_UPDATES	0x02
332 
333 enum network_type {
334 	NETWORK_DEFAULT,
335 	NETWORK_STATIC,
336 	NETWORK_CONNECTED,
337 	NETWORK_MRTCLONE
338 };
339 
340 struct network_config {
341 	struct bgpd_addr	 prefix;
342 	struct filter_set_head	 attrset;
343 	struct rde_aspath	*asp;
344 	u_int			 rtableid;
345 	enum network_type	 type;
346 	u_int8_t		 prefixlen;
347 	u_int8_t		 old;	/* used for reloading */
348 };
349 
350 struct network {
351 	struct network_config		net;
352 	TAILQ_ENTRY(network)		entry;
353 };
354 
355 enum imsg_type {
356 	IMSG_NONE,
357 	IMSG_CTL_END,
358 	IMSG_CTL_RELOAD,
359 	IMSG_CTL_FIB_COUPLE,
360 	IMSG_CTL_FIB_DECOUPLE,
361 	IMSG_CTL_NEIGHBOR_UP,
362 	IMSG_CTL_NEIGHBOR_DOWN,
363 	IMSG_CTL_NEIGHBOR_CLEAR,
364 	IMSG_CTL_NEIGHBOR_RREFRESH,
365 	IMSG_CTL_NEIGHBOR_DESTROY,
366 	IMSG_CTL_KROUTE,
367 	IMSG_CTL_KROUTE_ADDR,
368 	IMSG_CTL_RESULT,
369 	IMSG_CTL_SHOW_NEIGHBOR,
370 	IMSG_CTL_SHOW_NEXTHOP,
371 	IMSG_CTL_SHOW_INTERFACE,
372 	IMSG_CTL_SHOW_RIB,
373 	IMSG_CTL_SHOW_RIB_AS,
374 	IMSG_CTL_SHOW_RIB_PREFIX,
375 	IMSG_CTL_SHOW_RIB_ATTR,
376 	IMSG_CTL_SHOW_RIB_COMMUNITY,
377 	IMSG_CTL_SHOW_NETWORK,
378 	IMSG_CTL_SHOW_RIB_MEM,
379 	IMSG_CTL_SHOW_TERSE,
380 	IMSG_CTL_SHOW_TIMER,
381 	IMSG_CTL_LOG_VERBOSE,
382 	IMSG_CTL_SHOW_FIB_TABLES,
383 	IMSG_NETWORK_ADD,
384 	IMSG_NETWORK_ASPATH,
385 	IMSG_NETWORK_ATTR,
386 	IMSG_NETWORK_REMOVE,
387 	IMSG_NETWORK_FLUSH,
388 	IMSG_NETWORK_DONE,
389 	IMSG_FILTER_SET,
390 	IMSG_SOCKET_CONN,
391 	IMSG_SOCKET_CONN_CTL,
392 	IMSG_RECONF_CONF,
393 	IMSG_RECONF_RIB,
394 	IMSG_RECONF_PEER,
395 	IMSG_RECONF_FILTER,
396 	IMSG_RECONF_LISTENER,
397 	IMSG_RECONF_CTRL,
398 	IMSG_RECONF_RDOMAIN,
399 	IMSG_RECONF_RDOMAIN_EXPORT,
400 	IMSG_RECONF_RDOMAIN_IMPORT,
401 	IMSG_RECONF_RDOMAIN_DONE,
402 	IMSG_RECONF_DONE,
403 	IMSG_UPDATE,
404 	IMSG_UPDATE_ERR,
405 	IMSG_SESSION_ADD,
406 	IMSG_SESSION_UP,
407 	IMSG_SESSION_DOWN,
408 	IMSG_SESSION_STALE,
409 	IMSG_SESSION_FLUSH,
410 	IMSG_SESSION_RESTARTED,
411 	IMSG_MRT_OPEN,
412 	IMSG_MRT_REOPEN,
413 	IMSG_MRT_CLOSE,
414 	IMSG_KROUTE_CHANGE,
415 	IMSG_KROUTE_DELETE,
416 	IMSG_NEXTHOP_ADD,
417 	IMSG_NEXTHOP_REMOVE,
418 	IMSG_NEXTHOP_UPDATE,
419 	IMSG_PFTABLE_ADD,
420 	IMSG_PFTABLE_REMOVE,
421 	IMSG_PFTABLE_COMMIT,
422 	IMSG_REFRESH,
423 	IMSG_IFINFO,
424 	IMSG_DEMOTE
425 };
426 
427 struct demote_msg {
428 	char		 demote_group[IFNAMSIZ];
429 	int		 level;
430 };
431 
432 enum ctl_results {
433 	CTL_RES_OK,
434 	CTL_RES_NOSUCHPEER,
435 	CTL_RES_DENIED,
436 	CTL_RES_NOCAP,
437 	CTL_RES_PARSE_ERROR,
438 	CTL_RES_PENDING,
439 	CTL_RES_NOMEM,
440 	CTL_RES_BADPEER,
441 	CTL_RES_BADSTATE
442 };
443 
444 /* needed for session.h parse prototype */
445 LIST_HEAD(mrt_head, mrt);
446 
447 /* error codes and subcodes needed in SE and RDE */
448 enum err_codes {
449 	ERR_HEADER = 1,
450 	ERR_OPEN,
451 	ERR_UPDATE,
452 	ERR_HOLDTIMEREXPIRED,
453 	ERR_FSM,
454 	ERR_CEASE
455 };
456 
457 enum suberr_update {
458 	ERR_UPD_UNSPECIFIC,
459 	ERR_UPD_ATTRLIST,
460 	ERR_UPD_UNKNWN_WK_ATTR,
461 	ERR_UPD_MISSNG_WK_ATTR,
462 	ERR_UPD_ATTRFLAGS,
463 	ERR_UPD_ATTRLEN,
464 	ERR_UPD_ORIGIN,
465 	ERR_UPD_LOOP,
466 	ERR_UPD_NEXTHOP,
467 	ERR_UPD_OPTATTR,
468 	ERR_UPD_NETWORK,
469 	ERR_UPD_ASPATH
470 };
471 
472 enum suberr_cease {
473 	ERR_CEASE_MAX_PREFIX = 1,
474 	ERR_CEASE_ADMIN_DOWN,
475 	ERR_CEASE_PEER_UNCONF,
476 	ERR_CEASE_ADMIN_RESET,
477 	ERR_CEASE_CONN_REJECT,
478 	ERR_CEASE_OTHER_CHANGE,
479 	ERR_CEASE_COLLISION,
480 	ERR_CEASE_RSRC_EXHAUST
481 };
482 
483 struct kroute_node;
484 struct kroute6_node;
485 struct knexthop_node;
486 RB_HEAD(kroute_tree, kroute_node);
487 RB_HEAD(kroute6_tree, kroute6_node);
488 RB_HEAD(knexthop_tree, knexthop_node);
489 
490 struct ktable {
491 	char			 descr[PEER_DESCR_LEN];
492 	char			 ifmpe[IFNAMSIZ];
493 	struct kroute_tree	 krt;
494 	struct kroute6_tree	 krt6;
495 	struct knexthop_tree	 knt;
496 	struct network_head	 krn;
497 	u_int			 rtableid;
498 	u_int			 nhtableid; /* rdomain id for nexthop lookup */
499 	u_int			 ifindex;   /* ifindex of ifmpe */
500 	int			 nhrefcnt;  /* refcnt for nexthop table */
501 	enum reconf_action	 state;
502 	u_int8_t		 fib_conf;  /* configured FIB sync flag */
503 	u_int8_t		 fib_sync;  /* is FIB synced with kernel? */
504 };
505 
506 struct kroute_full {
507 	struct bgpd_addr	prefix;
508 	struct bgpd_addr	nexthop;
509 	char			label[RTLABEL_LEN];
510 	u_int16_t		flags;
511 	u_short			ifindex;
512 	u_int8_t		prefixlen;
513 	u_int8_t		priority;
514 };
515 
516 struct kroute {
517 	struct in_addr	prefix;
518 	struct in_addr	nexthop;
519 	u_int32_t	mplslabel;
520 	u_int16_t	flags;
521 	u_int16_t	labelid;
522 	u_short		ifindex;
523 	u_int8_t	prefixlen;
524 	u_int8_t	priority;
525 };
526 
527 struct kroute6 {
528 	struct in6_addr	prefix;
529 	struct in6_addr	nexthop;
530 	u_int16_t	flags;
531 	u_int16_t	labelid;
532 	u_short		ifindex;
533 	u_int8_t	prefixlen;
534 	u_int8_t	priority;
535 };
536 
537 struct kroute_nexthop {
538 	struct bgpd_addr	nexthop;
539 	struct bgpd_addr	gateway;
540 	struct bgpd_addr	net;
541 	u_int8_t		valid;
542 	u_int8_t		connected;
543 	u_int8_t		netlen;
544 };
545 
546 struct kif {
547 	char			 ifname[IFNAMSIZ];
548 	u_int64_t		 baudrate;
549 	int			 flags;
550 	u_short			 ifindex;
551 	u_int8_t		 if_type;
552 	u_int8_t		 link_state;
553 	u_int8_t		 nh_reachable;	/* for nexthop verification */
554 };
555 
556 struct session_up {
557 	struct bgpd_addr	local_addr;
558 	struct bgpd_addr	remote_addr;
559 	struct capabilities	capa;
560 	u_int32_t		remote_bgpid;
561 	u_int16_t		short_as;
562 };
563 
564 struct pftable_msg {
565 	struct bgpd_addr	addr;
566 	char			pftable[PFTABLE_LEN];
567 	u_int8_t		len;
568 };
569 
570 struct ctl_show_nexthop {
571 	struct bgpd_addr	addr;
572 	struct kif		kif;
573 	union {
574 		struct kroute		kr4;
575 		struct kroute6		kr6;
576 	} kr;
577 	u_int8_t		valid;
578 	u_int8_t		krvalid;
579 };
580 
581 struct ctl_neighbor {
582 	struct bgpd_addr	addr;
583 	char			descr[PEER_DESCR_LEN];
584 	int			show_timers;
585 };
586 
587 #define	F_PREF_ELIGIBLE	0x01
588 #define	F_PREF_ACTIVE	0x02
589 #define	F_PREF_INTERNAL	0x04
590 #define	F_PREF_ANNOUNCE	0x08
591 #define	F_PREF_STALE	0x10
592 
593 struct ctl_show_rib {
594 	struct bgpd_addr	true_nexthop;
595 	struct bgpd_addr	exit_nexthop;
596 	struct bgpd_addr	prefix;
597 	struct bgpd_addr	remote_addr;
598 	char			descr[PEER_DESCR_LEN];
599 	time_t			lastchange;
600 	u_int32_t		remote_id;
601 	u_int32_t		local_pref;
602 	u_int32_t		med;
603 	u_int32_t		weight;
604 	u_int16_t		aspath_len;
605 	u_int16_t		flags;
606 	u_int8_t		prefixlen;
607 	u_int8_t		origin;
608 	/* plus a aspath_len bytes long aspath */
609 };
610 
611 enum as_spec {
612 	AS_NONE,
613 	AS_ALL,
614 	AS_SOURCE,
615 	AS_TRANSIT,
616 	AS_PEER,
617 	AS_EMPTY
618 };
619 
620 enum aslen_spec {
621 	ASLEN_NONE,
622 	ASLEN_MAX,
623 	ASLEN_SEQ
624 };
625 
626 struct filter_as {
627 	u_int32_t	as;
628 	u_int16_t	flags;
629 	enum as_spec	type;
630 	u_int8_t	op;
631 	u_int32_t	as_min;
632 	u_int32_t	as_max;
633 };
634 
635 struct filter_aslen {
636 	u_int		aslen;
637 	enum aslen_spec	type;
638 };
639 
640 #define AS_FLAG_NEIGHBORAS	0x01
641 
642 struct filter_community {
643 	int		as;
644 	int		type;
645 };
646 
647 struct filter_extcommunity {
648 	u_int16_t	flags;
649 	u_int8_t	type;
650 	u_int8_t	subtype;	/* if extended type */
651 	union {
652 		struct ext_as {
653 			u_int16_t	as;
654 			u_int32_t	val;
655 		}		ext_as;
656 		struct ext_as4 {
657 			u_int32_t	as4;
658 			u_int16_t	val;
659 		}		ext_as4;
660 		struct ext_ip {
661 			struct in_addr	addr;
662 			u_int16_t	val;
663 		}		ext_ip;
664 		u_int64_t	ext_opaq;	/* only 48 bits */
665 	}		data;
666 };
667 
668 struct ctl_show_rib_request {
669 	char			rib[PEER_DESCR_LEN];
670 	struct ctl_neighbor	neighbor;
671 	struct bgpd_addr	prefix;
672 	struct filter_as	as;
673 	struct filter_community community;
674 	u_int32_t		peerid;
675 	pid_t			pid;
676 	u_int16_t		flags;
677 	enum imsg_type		type;
678 	u_int8_t		prefixlen;
679 	u_int8_t		aid;
680 };
681 
682 enum filter_actions {
683 	ACTION_NONE,
684 	ACTION_ALLOW,
685 	ACTION_DENY
686 };
687 
688 enum directions {
689 	DIR_IN = 1,
690 	DIR_OUT
691 };
692 
693 enum from_spec {
694 	FROM_ALL,
695 	FROM_ADDRESS,
696 	FROM_DESCR,
697 	FROM_GROUP
698 };
699 
700 enum comp_ops {
701 	OP_NONE,
702 	OP_RANGE,
703 	OP_XRANGE,
704 	OP_EQ,
705 	OP_NE,
706 	OP_LE,
707 	OP_LT,
708 	OP_GE,
709 	OP_GT
710 };
711 
712 struct filter_peers {
713 	u_int32_t	peerid;
714 	u_int32_t	groupid;
715 	u_int32_t	remote_as;
716 	u_int16_t	ribid;
717 };
718 
719 /* special community type */
720 #define	COMMUNITY_ERROR			-1
721 #define	COMMUNITY_ANY			-2
722 #define	COMMUNITY_NEIGHBOR_AS		-3
723 #define	COMMUNITY_UNSET			-4
724 #define	COMMUNITY_WELLKNOWN		0xffff
725 #define	COMMUNITY_BLACKHOLE		0x029A	/* draft-ymbk-grow-blackholing-01 */
726 #define	COMMUNITY_NO_EXPORT		0xff01
727 #define	COMMUNITY_NO_ADVERTISE		0xff02
728 #define	COMMUNITY_NO_EXPSUBCONFED	0xff03
729 #define	COMMUNITY_NO_PEER		0xff04	/* RFC 3765 */
730 
731 /* extended community definitions */
732 #define EXT_COMMUNITY_IANA		0x80
733 #define EXT_COMMUNITY_TRANSITIVE	0x40
734 #define EXT_COMMUNITY_VALUE		0x3f
735 /* extended types */
736 #define EXT_COMMUNITY_TWO_AS		0	/* 2 octet AS specific */
737 #define EXT_COMMUNITY_IPV4		1	/* IPv4 specific */
738 #define EXT_COMMUNITY_FOUR_AS		2	/* 4 octet AS specific */
739 #define EXT_COMMUNITY_OPAQUE		3	/* opaque ext community */
740 /* sub types */
741 #define EXT_COMMUNITY_ROUTE_TGT		2	/* RFC 4360 & RFC4364 */
742 #define EXT_COMMUNITY_ROUTE_ORIG	3	/* RFC 4360 & RFC4364 */
743 #define EXT_COMMUNITY_OSPF_DOM_ID	5	/* RFC 4577 */
744 #define EXT_COMMUNITY_OSPF_RTR_TYPE	6	/* RFC 4577 */
745 #define EXT_COMMUNITY_OSPF_RTR_ID	7	/* RFC 4577 */
746 #define EXT_COMMUNITY_BGP_COLLECT	8	/* RFC 4384 */
747 /* other handy defines */
748 #define EXT_COMMUNITY_OPAQUE_MAX	0xffffffffffffULL
749 #define EXT_COMMUNITY_FLAG_VALID	0x01
750 
751 struct ext_comm_pairs {
752 	u_int8_t	type;
753 	u_int8_t	subtype;
754 	u_int8_t	transitive;	/* transitive bit needs to be set */
755 };
756 
757 #define IANA_EXT_COMMUNITIES	{					\
758 	{ EXT_COMMUNITY_TWO_AS, EXT_COMMUNITY_ROUTE_TGT, 0 },		\
759 	{ EXT_COMMUNITY_TWO_AS, EXT_COMMUNITY_ROUTE_ORIG, 0 },		\
760 	{ EXT_COMMUNITY_TWO_AS, EXT_COMMUNITY_OSPF_DOM_ID, 0 },		\
761 	{ EXT_COMMUNITY_TWO_AS, EXT_COMMUNITY_BGP_COLLECT, 0 },		\
762 	{ EXT_COMMUNITY_FOUR_AS, EXT_COMMUNITY_ROUTE_TGT, 0 },		\
763 	{ EXT_COMMUNITY_FOUR_AS, EXT_COMMUNITY_ROUTE_ORIG, 0 },		\
764 	{ EXT_COMMUNITY_IPV4, EXT_COMMUNITY_ROUTE_TGT, 0 },		\
765 	{ EXT_COMMUNITY_IPV4, EXT_COMMUNITY_ROUTE_ORIG, 0 },		\
766 	{ EXT_COMMUNITY_IPV4, EXT_COMMUNITY_OSPF_RTR_ID, 0 },		\
767 	{ EXT_COMMUNITY_OPAQUE, EXT_COMMUNITY_OSPF_RTR_TYPE, 0 }	\
768 }
769 
770 
771 struct filter_prefix {
772 	struct bgpd_addr	addr;
773 	u_int8_t		op;
774 	u_int8_t		len;
775 	u_int8_t		len_min;
776 	u_int8_t		len_max;
777 };
778 
779 struct filter_nexthop {
780 	struct bgpd_addr	addr;
781 	u_int8_t		flags;
782 #define FILTER_NEXTHOP_ADDR	1
783 #define FILTER_NEXTHOP_NEIGHBOR	2
784 };
785 
786 struct filter_match {
787 	struct filter_prefix		prefix;
788 	struct filter_nexthop		nexthop;
789 	struct filter_as		as;
790 	struct filter_aslen		aslen;
791 	struct filter_community		community;
792 	struct filter_extcommunity	ext_community;
793 };
794 
795 union filter_rule_ptr {
796 	struct filter_rule		*ptr;
797 	u_int32_t			 nr;
798 };
799 
800 struct filter_rule {
801 	TAILQ_ENTRY(filter_rule)	entry;
802 	char				rib[PEER_DESCR_LEN];
803 	struct filter_peers		peer;
804 	struct filter_match		match;
805 	struct filter_set_head		set;
806 #define RDE_FILTER_SKIP_DIR		0
807 #define RDE_FILTER_SKIP_GROUPID		1
808 #define RDE_FILTER_SKIP_REMOTE_AS	2
809 #define RDE_FILTER_SKIP_PEERID		3
810 #define RDE_FILTER_SKIP_COUNT		4
811 	union filter_rule_ptr		skip[RDE_FILTER_SKIP_COUNT];
812 	enum filter_actions		action;
813 	enum directions			dir;
814 	u_int8_t			quick;
815 };
816 
817 enum action_types {
818 	ACTION_SET_LOCALPREF,
819 	ACTION_SET_RELATIVE_LOCALPREF,
820 	ACTION_SET_MED,
821 	ACTION_SET_RELATIVE_MED,
822 	ACTION_SET_WEIGHT,
823 	ACTION_SET_RELATIVE_WEIGHT,
824 	ACTION_SET_PREPEND_SELF,
825 	ACTION_SET_PREPEND_PEER,
826 	ACTION_SET_NEXTHOP,
827 	ACTION_SET_NEXTHOP_REJECT,
828 	ACTION_SET_NEXTHOP_BLACKHOLE,
829 	ACTION_SET_NEXTHOP_NOMODIFY,
830 	ACTION_SET_NEXTHOP_SELF,
831 	ACTION_SET_COMMUNITY,
832 	ACTION_DEL_COMMUNITY,
833 	ACTION_SET_EXT_COMMUNITY,
834 	ACTION_DEL_EXT_COMMUNITY,
835 	ACTION_PFTABLE,
836 	ACTION_PFTABLE_ID,
837 	ACTION_RTLABEL,
838 	ACTION_RTLABEL_ID,
839 	ACTION_SET_ORIGIN
840 };
841 
842 struct filter_set {
843 	TAILQ_ENTRY(filter_set)		entry;
844 	union {
845 		u_int8_t		prepend;
846 		u_int16_t		id;
847 		u_int32_t		metric;
848 		int32_t			relative;
849 		struct bgpd_addr	nexthop;
850 		struct filter_community	community;
851 		struct filter_extcommunity	ext_community;
852 		char			pftable[PFTABLE_LEN];
853 		char			rtlabel[RTLABEL_LEN];
854 		u_int8_t		origin;
855 	} action;
856 	enum action_types		type;
857 };
858 
859 struct rdomain {
860 	SIMPLEQ_ENTRY(rdomain)		entry;
861 	char				descr[PEER_DESCR_LEN];
862 	char				ifmpe[IFNAMSIZ];
863 	struct filter_set_head		import;
864 	struct filter_set_head		export;
865 	struct network_head		net_l;
866 	u_int64_t			rd;
867 	u_int				rtableid;
868 	u_int				label;
869 	int				flags;
870 };
871 
872 struct rde_rib {
873 	SIMPLEQ_ENTRY(rde_rib)	entry;
874 	char			name[PEER_DESCR_LEN];
875 	u_int			rtableid;
876 	u_int16_t		id;
877 	u_int16_t		flags;
878 };
879 SIMPLEQ_HEAD(rib_names, rde_rib);
880 extern struct rib_names ribnames;
881 
882 /* rde_rib flags */
883 #define F_RIB_ENTRYLOCK		0x0001
884 #define F_RIB_NOEVALUATE	0x0002
885 #define F_RIB_NOFIB		0x0004
886 #define F_RIB_NOFIBSYNC		0x0008
887 #define F_RIB_HASNOFIB		(F_RIB_NOFIB | F_RIB_NOEVALUATE)
888 
889 /* 4-byte magic AS number */
890 #define AS_TRANS	23456
891 
892 struct rde_memstats {
893 	int64_t		path_cnt;
894 	int64_t		prefix_cnt;
895 	int64_t		rib_cnt;
896 	int64_t		pt_cnt[AID_MAX];
897 	int64_t		nexthop_cnt;
898 	int64_t		aspath_cnt;
899 	int64_t		aspath_size;
900 	int64_t		aspath_refs;
901 	int64_t		attr_cnt;
902 	int64_t		attr_refs;
903 	int64_t		attr_data;
904 	int64_t		attr_dcnt;
905 };
906 
907 #define	MRT_FILE_LEN	512
908 #define	MRT2MC(x)	((struct mrt_config *)(x))
909 #define	MRT_MAX_TIMEOUT	7200
910 
911 enum mrt_type {
912 	MRT_NONE,
913 	MRT_TABLE_DUMP,
914 	MRT_TABLE_DUMP_MP,
915 	MRT_TABLE_DUMP_V2,
916 	MRT_ALL_IN,
917 	MRT_ALL_OUT,
918 	MRT_UPDATE_IN,
919 	MRT_UPDATE_OUT
920 };
921 
922 enum mrt_state {
923 	MRT_STATE_RUNNING,
924 	MRT_STATE_OPEN,
925 	MRT_STATE_REOPEN,
926 	MRT_STATE_REMOVE
927 };
928 
929 struct mrt {
930 	char			rib[PEER_DESCR_LEN];
931 	struct msgbuf		wbuf;
932 	LIST_ENTRY(mrt)		entry;
933 	u_int32_t		peer_id;
934 	u_int32_t		group_id;
935 	enum mrt_type		type;
936 	enum mrt_state		state;
937 	u_int16_t		seqnum;
938 };
939 
940 struct mrt_config {
941 	struct mrt		conf;
942 	char			name[MRT_FILE_LEN];	/* base file name */
943 	char			file[MRT_FILE_LEN];	/* actual file name */
944 	time_t			ReopenTimer;
945 	int			ReopenTimerInterval;
946 };
947 
948 /* prototypes */
949 /* bgpd.c */
950 void		 send_nexthop_update(struct kroute_nexthop *);
951 void		 send_imsg_session(int, pid_t, void *, u_int16_t);
952 int		 send_network(int, struct network_config *,
953 		     struct filter_set_head *);
954 int		 bgpd_filternexthop(struct kroute *, struct kroute6 *);
955 void		 set_pollfd(struct pollfd *, struct imsgbuf *);
956 int		 handle_pollfd(struct pollfd *, struct imsgbuf *);
957 
958 /* control.c */
959 void	control_cleanup(const char *);
960 int	control_imsg_relay(struct imsg *);
961 
962 /* config.c */
963 struct bgpd_config	*new_config(void);
964 void			free_config(struct bgpd_config *);
965 void	filterlist_free(struct filter_head *);
966 int	host(const char *, struct bgpd_addr *, u_int8_t *);
967 
968 /* kroute.c */
969 int		 kr_init(void);
970 int		 ktable_update(u_int, char *, char *, int, u_int8_t);
971 void		 ktable_preload(void);
972 void		 ktable_postload(u_int8_t);
973 int		 ktable_exists(u_int, u_int *);
974 int		 kr_change(u_int, struct kroute_full *,  u_int8_t);
975 int		 kr_delete(u_int, struct kroute_full *, u_int8_t);
976 void		 kr_shutdown(u_int8_t);
977 void		 kr_fib_couple(u_int, u_int8_t);
978 void		 kr_fib_couple_all(u_int8_t);
979 void		 kr_fib_decouple(u_int, u_int8_t);
980 void		 kr_fib_decouple_all(u_int8_t);
981 void		 kr_fib_update_prio_all(u_int8_t);
982 int		 kr_dispatch_msg(void);
983 int		 kr_nexthop_add(u_int32_t, struct bgpd_addr *);
984 void		 kr_nexthop_delete(u_int32_t, struct bgpd_addr *);
985 void		 kr_show_route(struct imsg *);
986 void		 kr_ifinfo(char *);
987 int		 kr_net_reload(u_int, struct network_head *);
988 int		 kr_reload(void);
989 struct in6_addr	*prefixlen2mask6(u_int8_t prefixlen);
990 
991 /* log.c */
992 void		 log_init(int);
993 void		 log_verbose(int);
994 void		 logit(int, const char *, ...)
995 			__attribute__((__format__ (printf, 2, 3)));
996 void		 vlog(int, const char *, va_list)
997 			__attribute__((__format__ (printf, 2, 0)));
998 void		 log_peer_warn(const struct peer_config *, const char *, ...)
999 			__attribute__((__format__ (printf, 2, 3)));
1000 void		 log_peer_warnx(const struct peer_config *, const char *, ...)
1001 			__attribute__((__format__ (printf, 2, 3)));
1002 void		 log_warn(const char *, ...)
1003 			__attribute__((__format__ (printf, 1, 2)));
1004 void		 log_warnx(const char *, ...)
1005 			__attribute__((__format__ (printf, 1, 2)));
1006 void		 log_info(const char *, ...)
1007 			__attribute__((__format__ (printf, 1, 2)));
1008 void		 log_debug(const char *, ...)
1009 			__attribute__((__format__ (printf, 1, 2)));
1010 void		 fatal(const char *, ...) __dead
1011 			__attribute__((__format__ (printf, 1, 2)));
1012 void		 fatalx(const char *) __dead
1013 			__attribute__((__format__ (printf, 1, 0)));
1014 
1015 /* mrt.c */
1016 void		 mrt_clear_seq(void);
1017 void		 mrt_write(struct mrt *);
1018 void		 mrt_clean(struct mrt *);
1019 void		 mrt_init(struct imsgbuf *, struct imsgbuf *);
1020 int		 mrt_timeout(struct mrt_head *);
1021 void		 mrt_reconfigure(struct mrt_head *);
1022 void		 mrt_handler(struct mrt_head *);
1023 struct mrt	*mrt_get(struct mrt_head *, struct mrt *);
1024 int		 mrt_mergeconfig(struct mrt_head *, struct mrt_head *);
1025 
1026 /* name2id.c */
1027 u_int16_t	 rib_name2id(const char *);
1028 const char	*rib_id2name(u_int16_t);
1029 void		 rib_unref(u_int16_t);
1030 void		 rib_ref(u_int16_t);
1031 u_int16_t	 rtlabel_name2id(const char *);
1032 const char	*rtlabel_id2name(u_int16_t);
1033 void		 rtlabel_unref(u_int16_t);
1034 void		 rtlabel_ref(u_int16_t);
1035 u_int16_t	 pftable_name2id(const char *);
1036 const char	*pftable_id2name(u_int16_t);
1037 void		 pftable_unref(u_int16_t);
1038 void		 pftable_ref(u_int16_t);
1039 
1040 /* parse.y */
1041 int	 cmdline_symset(char *);
1042 
1043 /* pftable.c */
1044 int	pftable_exists(const char *);
1045 int	pftable_add(const char *);
1046 int	pftable_clear_all(void);
1047 int	pftable_addr_add(struct pftable_msg *);
1048 int	pftable_addr_remove(struct pftable_msg *);
1049 int	pftable_commit(void);
1050 
1051 /* rde_filter.c */
1052 void		 filterset_free(struct filter_set_head *);
1053 int		 filterset_cmp(struct filter_set *, struct filter_set *);
1054 void		 filterset_move(struct filter_set_head *,
1055 		    struct filter_set_head *);
1056 const char	*filterset_name(enum action_types);
1057 
1058 /* util.c */
1059 const char	*log_addr(const struct bgpd_addr *);
1060 const char	*log_in6addr(const struct in6_addr *);
1061 const char	*log_sockaddr(struct sockaddr *);
1062 const char	*log_as(u_int32_t);
1063 const char	*log_rd(u_int64_t);
1064 const char	*log_ext_subtype(u_int8_t);
1065 int		 aspath_snprint(char *, size_t, void *, u_int16_t);
1066 int		 aspath_asprint(char **, void *, u_int16_t);
1067 size_t		 aspath_strlen(void *, u_int16_t);
1068 int		 aspath_match(void *, u_int16_t, struct filter_as *, u_int32_t);
1069 int		 as_compare(u_int8_t, u_int32_t, u_int32_t, u_int32_t, u_int32_t);
1070 u_int32_t	 aspath_extract(const void *, int);
1071 int		 prefix_compare(const struct bgpd_addr *,
1072 		    const struct bgpd_addr *, int);
1073 in_addr_t	 prefixlen2mask(u_int8_t);
1074 void		 inet6applymask(struct in6_addr *, const struct in6_addr *,
1075 		    int);
1076 const char	*aid2str(u_int8_t);
1077 int		 aid2afi(u_int8_t, u_int16_t *, u_int8_t *);
1078 int		 afi2aid(u_int16_t, u_int8_t, u_int8_t *);
1079 sa_family_t	 aid2af(u_int8_t);
1080 int		 af2aid(sa_family_t, u_int8_t, u_int8_t *);
1081 struct sockaddr	*addr2sa(struct bgpd_addr *, u_int16_t);
1082 void		 sa2addr(struct sockaddr *, struct bgpd_addr *);
1083 
1084 static const char * const log_procnames[] = {
1085 	"parent",
1086 	"SE",
1087 	"RDE"
1088 };
1089 
1090 /* logmsg.c and needed by bgpctl */
1091 static const char * const statenames[] = {
1092 	"None",
1093 	"Idle",
1094 	"Connect",
1095 	"Active",
1096 	"OpenSent",
1097 	"OpenConfirm",
1098 	"Established"
1099 };
1100 
1101 static const char * const msgtypenames[] = {
1102 	"NONE",
1103 	"OPEN",
1104 	"UPDATE",
1105 	"NOTIFICATION",
1106 	"KEEPALIVE",
1107 	"RREFRESH"
1108 };
1109 
1110 static const char * const eventnames[] = {
1111 	"None",
1112 	"Start",
1113 	"Stop",
1114 	"Connection opened",
1115 	"Connection closed",
1116 	"Connection open failed",
1117 	"Fatal error",
1118 	"ConnectRetryTimer expired",
1119 	"HoldTimer expired",
1120 	"KeepaliveTimer expired",
1121 	"OPEN message received",
1122 	"KEEPALIVE message received",
1123 	"UPDATE message received",
1124 	"NOTIFICATION received"
1125 };
1126 
1127 static const char * const errnames[] = {
1128 	"none",
1129 	"Header error",
1130 	"error in OPEN message",
1131 	"error in UPDATE message",
1132 	"HoldTimer expired",
1133 	"Finite State Machine error",
1134 	"Cease"
1135 };
1136 
1137 static const char * const suberr_header_names[] = {
1138 	"none",
1139 	"synchronization error",
1140 	"wrong length",
1141 	"unknown message type"
1142 };
1143 
1144 static const char * const suberr_open_names[] = {
1145 	"none",
1146 	"version mismatch",
1147 	"AS unacceptable",
1148 	"BGPID invalid",
1149 	"optional parameter error",
1150 	"authentication error",
1151 	"unacceptable holdtime",
1152 	"unsupported capability",
1153 	"group membership conflict",	/* draft-ietf-idr-bgp-multisession-07 */
1154 	"group membership required"	/* draft-ietf-idr-bgp-multisession-07 */
1155 };
1156 
1157 static const char * const suberr_fsm_names[] = {
1158 	"unspecified error",
1159 	"received unexpected message in OpenSent",
1160 	"received unexpected message in OpenConfirm",
1161 	"received unexpected message in Established"
1162 };
1163 
1164 static const char * const suberr_update_names[] = {
1165 	"none",
1166 	"attribute list error",
1167 	"unknown well-known attribute",
1168 	"well-known attribute missing",
1169 	"attribute flags error",
1170 	"attribute length wrong",
1171 	"origin unacceptable",
1172 	"loop detected",
1173 	"nexthop unacceptable",
1174 	"optional attribute error",
1175 	"network unacceptable",
1176 	"AS-Path unacceptable"
1177 };
1178 
1179 static const char * const suberr_cease_names[] = {
1180 	"none",
1181 	"max-prefix exceeded",
1182 	"administratively down",
1183 	"peer unconfigured",
1184 	"administrative reset",
1185 	"connection rejected",
1186 	"other config change",
1187 	"collision",
1188 	"resource exhaustion"
1189 };
1190 
1191 static const char * const ctl_res_strerror[] = {
1192 	"no error",
1193 	"no such neighbor",
1194 	"permission denied",
1195 	"neighbor does not have this capability",
1196 	"config file has errors, reload failed",
1197 	"previous reload still running",
1198 	"out of memory",
1199 	"not a cloned peer",
1200 	"peer still active, down peer first"
1201 };
1202 
1203 static const char * const timernames[] = {
1204 	"None",
1205 	"ConnectRetryTimer",
1206 	"KeepaliveTimer",
1207 	"HoldTimer",
1208 	"IdleHoldTimer",
1209 	"IdleHoldResetTimer",
1210 	"CarpUndemoteTimer",
1211 	""
1212 };
1213 
1214 #endif /* __BGPD_H__ */
1215