xref: /openbsd-src/usr.sbin/bgpd/rde.h (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1 /*	$OpenBSD: rde.h,v 1.149 2015/11/06 16:23:26 phessler Exp $ */
2 
3 /*
4  * Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> and
5  *                          Andre Oppermann <oppermann@networx.ch>
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 #ifndef __RDE_H__
20 #define __RDE_H__
21 
22 #include <sys/types.h>
23 #include <sys/queue.h>
24 #include <sys/tree.h>
25 
26 #include "bgpd.h"
27 
28 /* rde internal structures */
29 
30 enum peer_state {
31 	PEER_NONE,
32 	PEER_DOWN,
33 	PEER_UP,
34 	PEER_ERR	/* error occurred going to PEER_DOWN state */
35 };
36 
37 /*
38  * How do we identify peers between the session handler and the rde?
39  * Currently I assume that we can do that with the neighbor_ip...
40  */
41 LIST_HEAD(rde_peer_head, rde_peer);
42 LIST_HEAD(aspath_head, rde_aspath);
43 RB_HEAD(uptree_prefix, update_prefix);
44 RB_HEAD(uptree_attr, update_attr);
45 RB_HEAD(rib_tree, rib_entry);
46 TAILQ_HEAD(uplist_prefix, update_prefix);
47 TAILQ_HEAD(uplist_attr, update_attr);
48 
49 struct rde_peer {
50 	LIST_ENTRY(rde_peer)		 hash_l; /* hash list over all peers */
51 	LIST_ENTRY(rde_peer)		 peer_l; /* list of all peers */
52 	struct aspath_head		 path_h; /* list of all as paths */
53 	struct peer_config		 conf;
54 	struct bgpd_addr		 remote_addr;
55 	struct bgpd_addr		 local_v4_addr;
56 	struct bgpd_addr		 local_v6_addr;
57 	struct uptree_prefix		 up_prefix;
58 	struct uptree_attr		 up_attrs;
59 	struct uplist_attr		 updates[AID_MAX];
60 	struct uplist_prefix		 withdraws[AID_MAX];
61 	struct capabilities		 capa;
62 	time_t				 staletime[AID_MAX];
63 	u_int64_t			 prefix_rcvd_update;
64 	u_int64_t			 prefix_rcvd_withdraw;
65 	u_int64_t			 prefix_rcvd_eor;
66 	u_int64_t			 prefix_sent_update;
67 	u_int64_t			 prefix_sent_withdraw;
68 	u_int64_t			 prefix_sent_eor;
69 	u_int32_t			 prefix_cnt; /* # of prefixes */
70 	u_int32_t			 remote_bgpid; /* host byte order! */
71 	u_int32_t			 up_pcnt;
72 	u_int32_t			 up_acnt;
73 	u_int32_t			 up_nlricnt;
74 	u_int32_t			 up_wcnt;
75 	enum peer_state			 state;
76 	u_int16_t			 ribid;
77 	u_int16_t			 short_as;
78 	u_int16_t			 mrt_idx;
79 	u_int8_t			 reconf_out;	/* out filter changed */
80 	u_int8_t			 reconf_rib;	/* rib changed */
81 };
82 
83 #define AS_SET			1
84 #define AS_SEQUENCE		2
85 #define AS_CONFED_SEQUENCE	3
86 #define AS_CONFED_SET		4
87 #define ASPATH_HEADER_SIZE	(sizeof(struct aspath) - sizeof(u_char))
88 
89 LIST_HEAD(aspath_list, aspath);
90 
91 struct aspath {
92 	LIST_ENTRY(aspath)	entry;
93 	int			refcnt;	/* reference count */
94 	u_int16_t		len;	/* total length of aspath in octets */
95 	u_int16_t		ascnt;	/* number of AS hops in data */
96 	u_char			data[1]; /* placeholder for actual data */
97 };
98 
99 enum attrtypes {
100 	ATTR_UNDEF,
101 	ATTR_ORIGIN,
102 	ATTR_ASPATH,
103 	ATTR_NEXTHOP,
104 	ATTR_MED,
105 	ATTR_LOCALPREF,
106 	ATTR_ATOMIC_AGGREGATE,
107 	ATTR_AGGREGATOR,
108 	ATTR_COMMUNITIES,
109 	ATTR_ORIGINATOR_ID,
110 	ATTR_CLUSTER_LIST,
111 	ATTR_MP_REACH_NLRI=14,
112 	ATTR_MP_UNREACH_NLRI=15,
113 	ATTR_EXT_COMMUNITIES=16,
114 	ATTR_AS4_PATH=17,
115 	ATTR_AS4_AGGREGATOR=18
116 };
117 
118 /* attribute flags. 4 low order bits reserved */
119 #define	ATTR_EXTLEN		0x10
120 #define ATTR_PARTIAL		0x20
121 #define ATTR_TRANSITIVE		0x40
122 #define ATTR_OPTIONAL		0x80
123 #define ATTR_RESERVED		0x0f
124 /* by default mask the reserved bits and the ext len bit */
125 #define ATTR_DEFMASK		(ATTR_RESERVED | ATTR_EXTLEN)
126 
127 /* default attribute flags for well known attributes */
128 #define ATTR_WELL_KNOWN		ATTR_TRANSITIVE
129 
130 struct attr {
131 	LIST_ENTRY(attr)		 entry;
132 	u_char				*data;
133 	int				 refcnt;
134 	u_int32_t			 hash;
135 	u_int16_t			 len;
136 	u_int8_t			 flags;
137 	u_int8_t			 type;
138 };
139 
140 struct mpattr {
141 	void		*reach;
142 	void		*unreach;
143 	u_int16_t	 reach_len;
144 	u_int16_t	 unreach_len;
145 };
146 
147 LIST_HEAD(attr_list, attr);
148 
149 struct path_table {
150 	struct aspath_head	*path_hashtbl;
151 	u_int32_t		 path_hashmask;
152 };
153 
154 LIST_HEAD(prefix_head, prefix);
155 
156 #define	F_ATTR_ORIGIN		0x00001
157 #define	F_ATTR_ASPATH		0x00002
158 #define	F_ATTR_NEXTHOP		0x00004
159 #define	F_ATTR_LOCALPREF	0x00008
160 #define	F_ATTR_MED		0x00010
161 #define	F_ATTR_MED_ANNOUNCE	0x00020
162 #define	F_ATTR_MP_REACH		0x00040
163 #define	F_ATTR_MP_UNREACH	0x00080
164 #define	F_ATTR_AS4BYTE_NEW	0x00100	/* AS4_PATH or AS4_AGGREGATOR */
165 #define	F_ATTR_LOOP		0x00200 /* path would cause a route loop */
166 #define	F_PREFIX_ANNOUNCED	0x00400
167 #define	F_ANN_DYNAMIC		0x00800
168 #define	F_NEXTHOP_SELF		0x01000
169 #define	F_NEXTHOP_REJECT	0x02000
170 #define	F_NEXTHOP_BLACKHOLE	0x04000
171 #define	F_NEXTHOP_NOMODIFY	0x08000
172 #define	F_NEXTHOP_MASK		0x0f000
173 #define	F_ATTR_PARSE_ERR	0x10000
174 #define	F_ATTR_LINKED		0x20000
175 
176 
177 #define ORIGIN_IGP		0
178 #define ORIGIN_EGP		1
179 #define ORIGIN_INCOMPLETE	2
180 
181 #define DEFAULT_LPREF		100
182 
183 struct rde_aspath {
184 	LIST_ENTRY(rde_aspath)		 path_l, peer_l, nexthop_l;
185 	struct prefix_head		 prefix_h;
186 	struct attr			**others;
187 	struct rde_peer			*peer;
188 	struct aspath			*aspath;
189 	struct nexthop			*nexthop;	/* may be NULL */
190 	u_int32_t			 med;		/* multi exit disc */
191 	u_int32_t			 lpref;		/* local pref */
192 	u_int32_t			 weight;	/* low prio lpref */
193 	u_int32_t			 prefix_cnt; /* # of prefixes */
194 	u_int32_t			 active_cnt; /* # of active prefixes */
195 	u_int32_t			 flags;		/* internally used */
196 	u_int16_t			 rtlabelid;	/* route label id */
197 	u_int16_t			 pftableid;	/* pf table id */
198 	u_int8_t			 origin;
199 	u_int8_t			 others_len;
200 };
201 
202 enum nexthop_state {
203 	NEXTHOP_LOOKUP,
204 	NEXTHOP_UNREACH,
205 	NEXTHOP_REACH
206 };
207 
208 struct nexthop {
209 	LIST_ENTRY(nexthop)	nexthop_l;
210 	struct aspath_head	path_h;
211 	struct bgpd_addr	exit_nexthop;
212 	struct bgpd_addr	true_nexthop;
213 	struct bgpd_addr	nexthop_net;
214 #if 0
215 	/*
216 	 * currently we use the boolean nexthop state, this could be exchanged
217 	 * with a variable cost with a max for unreachable.
218 	 */
219 	u_int32_t		costs;
220 #endif
221 	int			refcnt;	/* filterset reference counter */
222 	enum nexthop_state	state;
223 	u_int8_t		nexthop_netlen;
224 	u_int8_t		flags;
225 #define NEXTHOP_CONNECTED	0x01
226 };
227 
228 /* generic entry without address specific part */
229 struct pt_entry {
230 	RB_ENTRY(pt_entry)		 pt_e;
231 	u_int8_t			 aid;
232 	u_int8_t			 prefixlen;
233 	u_int16_t			 refcnt;
234 };
235 
236 struct pt_entry4 {
237 	RB_ENTRY(pt_entry)		 pt_e;
238 	u_int8_t			 aid;
239 	u_int8_t			 prefixlen;
240 	u_int16_t			 refcnt;
241 	struct in_addr			 prefix4;
242 };
243 
244 struct pt_entry6 {
245 	RB_ENTRY(pt_entry)		 pt_e;
246 	u_int8_t			 aid;
247 	u_int8_t			 prefixlen;
248 	u_int16_t			 refcnt;
249 	struct in6_addr			 prefix6;
250 };
251 
252 struct pt_entry_vpn4 {
253 	RB_ENTRY(pt_entry)		 pt_e;
254 	u_int8_t			 aid;
255 	u_int8_t			 prefixlen;
256 	u_int16_t			 refcnt;
257 	struct in_addr			 prefix4;
258 	u_int64_t			 rd;
259 	u_int8_t			 labelstack[21];
260 	u_int8_t			 labellen;
261 	u_int8_t			 pad1;
262 	u_int8_t			 pad2;
263 };
264 
265 struct rib_context {
266 	LIST_ENTRY(rib_context)		 entry;
267 	struct rib_entry		*ctx_re;
268 	struct rib			*ctx_rib;
269 	void		(*ctx_upcall)(struct rib_entry *, void *);
270 	void		(*ctx_done)(void *);
271 	void		(*ctx_wait)(void *);
272 	void				*ctx_arg;
273 	unsigned int			 ctx_count;
274 	u_int8_t			 ctx_aid;
275 };
276 
277 struct rib_entry {
278 	RB_ENTRY(rib_entry)	 rib_e;
279 	struct prefix_head	 prefix_h;
280 	struct prefix		*active; /* for fast access */
281 	struct pt_entry		*prefix;
282 	u_int16_t		 ribid;
283 	u_int16_t		 flags;
284 };
285 
286 struct rib {
287 	char			name[PEER_DESCR_LEN];
288 	struct rib_tree		rib;
289 	struct filter_head	*in_rules;
290 	struct filter_head	*in_rules_tmp;
291 	u_int			rtableid;
292 	u_int16_t		flags;
293 	u_int16_t		id;
294 	enum reconf_action 	state;
295 };
296 
297 #define RIB_FAILED		0xffff
298 
299 struct prefix {
300 	LIST_ENTRY(prefix)		 rib_l, path_l;
301 	struct rde_aspath		*aspath;
302 	struct pt_entry			*prefix;
303 	struct rib_entry		*rib;	/* NULL for Adj-RIB-In */
304 	time_t				 lastchange;
305 };
306 
307 extern struct rde_memstats rdemem;
308 
309 /* prototypes */
310 /* mrt.c */
311 int		 mrt_dump_v2_hdr(struct mrt *, struct bgpd_config *,
312 		    struct rde_peer_head *);
313 void		 mrt_dump_upcall(struct rib_entry *, void *);
314 void		 mrt_done(void *);
315 
316 /* rde.c */
317 void		 rde_send_kroute(struct prefix *, struct prefix *, u_int16_t);
318 void		 rde_send_nexthop(struct bgpd_addr *, int);
319 void		 rde_send_pftable(u_int16_t, struct bgpd_addr *,
320 		     u_int8_t, int);
321 void		 rde_send_pftable_commit(void);
322 
323 void		 rde_generate_updates(u_int16_t, struct prefix *,
324 		     struct prefix *);
325 u_int32_t	 rde_local_as(void);
326 int		 rde_noevaluate(void);
327 int		 rde_decisionflags(void);
328 int		 rde_as4byte(struct rde_peer *);
329 
330 /* rde_attr.c */
331 int		 attr_write(void *, u_int16_t, u_int8_t, u_int8_t, void *,
332 		     u_int16_t);
333 int		 attr_writebuf(struct ibuf *, u_int8_t, u_int8_t, void *,
334 		     u_int16_t);
335 void		 attr_init(u_int32_t);
336 void		 attr_shutdown(void);
337 int		 attr_optadd(struct rde_aspath *, u_int8_t, u_int8_t,
338 		     void *, u_int16_t);
339 struct attr	*attr_optget(const struct rde_aspath *, u_int8_t);
340 void		 attr_copy(struct rde_aspath *, struct rde_aspath *);
341 int		 attr_compare(struct rde_aspath *, struct rde_aspath *);
342 void		 attr_freeall(struct rde_aspath *);
343 void		 attr_free(struct rde_aspath *, struct attr *);
344 #define		 attr_optlen(x)	\
345     ((x)->len > 255 ? (x)->len + 4 : (x)->len + 3)
346 
347 int		 aspath_verify(void *, u_int16_t, int);
348 #define		 AS_ERR_LEN	-1
349 #define		 AS_ERR_TYPE	-2
350 #define		 AS_ERR_BAD	-3
351 #define		 AS_ERR_SOFT	-4
352 void		 aspath_init(u_int32_t);
353 void		 aspath_shutdown(void);
354 struct aspath	*aspath_get(void *, u_int16_t);
355 void		 aspath_put(struct aspath *);
356 u_char		*aspath_inflate(void *, u_int16_t, u_int16_t *);
357 u_char		*aspath_deflate(u_char *, u_int16_t *, int *);
358 void		 aspath_merge(struct rde_aspath *, struct attr *);
359 u_char		*aspath_dump(struct aspath *);
360 u_int16_t	 aspath_length(struct aspath *);
361 u_int16_t	 aspath_count(const void *, u_int16_t);
362 u_int32_t	 aspath_neighbor(struct aspath *);
363 int		 aspath_loopfree(struct aspath *, u_int32_t);
364 int		 aspath_compare(struct aspath *, struct aspath *);
365 u_char		*aspath_prepend(struct aspath *, u_int32_t, int, u_int16_t *);
366 int		 aspath_lenmatch(struct aspath *, enum aslen_spec, u_int);
367 int		 community_match(struct rde_aspath *, int, int);
368 int		 community_set(struct rde_aspath *, int, int);
369 void		 community_delete(struct rde_aspath *, int, int);
370 int		 community_ext_match(struct rde_aspath *,
371 		    struct filter_extcommunity *, u_int16_t);
372 int		 community_ext_set(struct rde_aspath *,
373 		    struct filter_extcommunity *, u_int16_t);
374 void		 community_ext_delete(struct rde_aspath *,
375 		    struct filter_extcommunity *, u_int16_t);
376 int		 community_ext_conv(struct filter_extcommunity *, u_int16_t,
377 		    u_int64_t *);
378 
379 /* rde_decide.c */
380 void		 prefix_evaluate(struct prefix *, struct rib_entry *);
381 
382 /* rde_filter.c */
383 enum filter_actions rde_filter(struct filter_head *, struct rde_aspath **,
384 		     struct rde_peer *, struct rde_aspath *,
385 		     struct bgpd_addr *, u_int8_t, struct rde_peer *);
386 void		 rde_apply_set(struct rde_aspath *, struct filter_set_head *,
387 		     u_int8_t, struct rde_peer *, struct rde_peer *);
388 int		 rde_filter_equal(struct filter_head *, struct filter_head *,
389 		     struct rde_peer *);
390 void		 rde_filter_calc_skip_steps(struct filter_head *);
391 
392 /* rde_prefix.c */
393 #define pt_empty(pt)	((pt)->refcnt == 0)
394 #define pt_ref(pt)	do {				\
395 	++(pt)->refcnt;					\
396 	if ((pt)->refcnt == 0)				\
397 		fatalx("pt_ref: overflow");		\
398 } while(0)
399 #define pt_unref(pt)	do {				\
400 	if ((pt)->refcnt == 0)				\
401 		fatalx("pt_unref: underflow");		\
402 	--(pt)->refcnt;					\
403 } while(0)
404 
405 void	 pt_init(void);
406 void	 pt_shutdown(void);
407 void	 pt_getaddr(struct pt_entry *, struct bgpd_addr *);
408 struct pt_entry	*pt_fill(struct bgpd_addr *, int);
409 struct pt_entry	*pt_get(struct bgpd_addr *, int);
410 struct pt_entry *pt_add(struct bgpd_addr *, int);
411 void	 pt_remove(struct pt_entry *);
412 struct pt_entry	*pt_lookup(struct bgpd_addr *);
413 int	 pt_prefix_cmp(const struct pt_entry *, const struct pt_entry *);
414 
415 /* rde_rib.c */
416 extern u_int16_t	 rib_size;
417 extern struct rib	*ribs;
418 
419 u_int16_t	 rib_new(char *, u_int, u_int16_t);
420 u_int16_t	 rib_find(char *);
421 void		 rib_free(struct rib *);
422 struct rib_entry *rib_get(struct rib *, struct bgpd_addr *, int);
423 struct rib_entry *rib_lookup(struct rib *, struct bgpd_addr *);
424 void		 rib_dump(struct rib *, void (*)(struct rib_entry *, void *),
425 		     void *, u_int8_t);
426 void		 rib_dump_r(struct rib_context *);
427 void		 rib_dump_runner(void);
428 int		 rib_dump_pending(void);
429 
430 void		 path_init(u_int32_t);
431 void		 path_shutdown(void);
432 int		 path_update(struct rib *, struct rde_peer *,
433 		     struct rde_aspath *, struct bgpd_addr *, int);
434 int		 path_compare(struct rde_aspath *, struct rde_aspath *);
435 struct rde_aspath *path_lookup(struct rde_aspath *, struct rde_peer *);
436 void		 path_remove(struct rde_aspath *);
437 u_int32_t	 path_remove_stale(struct rde_aspath *, u_int8_t);
438 void		 path_destroy(struct rde_aspath *);
439 int		 path_empty(struct rde_aspath *);
440 struct rde_aspath *path_copy(struct rde_aspath *);
441 struct rde_aspath *path_get(void);
442 void		 path_put(struct rde_aspath *);
443 
444 #define	PREFIX_SIZE(x)	(((x) + 7) / 8 + 1)
445 struct prefix	*prefix_get(struct rib *, struct rde_peer *,
446 		    struct bgpd_addr *, int, u_int32_t);
447 int		 prefix_add(struct rib *, struct rde_aspath *,
448 		    struct bgpd_addr *, int);
449 void		 prefix_move(struct rde_aspath *, struct prefix *);
450 int		 prefix_remove(struct rib *, struct rde_peer *,
451 		    struct bgpd_addr *, int, u_int32_t);
452 int		 prefix_write(u_char *, int, struct bgpd_addr *, u_int8_t);
453 int		 prefix_writebuf(struct ibuf *, struct bgpd_addr *, u_int8_t);
454 struct prefix	*prefix_bypeer(struct rib_entry *, struct rde_peer *,
455 		     u_int32_t);
456 void		 prefix_updateall(struct rde_aspath *, enum nexthop_state,
457 		     enum nexthop_state);
458 void		 prefix_destroy(struct prefix *);
459 void		 prefix_network_clean(struct rde_peer *, time_t, u_int32_t);
460 
461 void		 nexthop_init(u_int32_t);
462 void		 nexthop_shutdown(void);
463 void		 nexthop_modify(struct rde_aspath *, struct bgpd_addr *,
464 		     enum action_types, u_int8_t);
465 void		 nexthop_link(struct rde_aspath *);
466 void		 nexthop_unlink(struct rde_aspath *);
467 int		 nexthop_delete(struct nexthop *);
468 void		 nexthop_update(struct kroute_nexthop *);
469 struct nexthop	*nexthop_get(struct bgpd_addr *);
470 int		 nexthop_compare(struct nexthop *, struct nexthop *);
471 
472 /* rde_update.c */
473 void		 up_init(struct rde_peer *);
474 void		 up_down(struct rde_peer *);
475 int		 up_test_update(struct rde_peer *, struct prefix *);
476 int		 up_generate(struct rde_peer *, struct rde_aspath *,
477 		     struct bgpd_addr *, u_int8_t);
478 void		 up_generate_updates(struct filter_head *, struct rde_peer *,
479 		     struct prefix *, struct prefix *);
480 void		 up_generate_default(struct filter_head *, struct rde_peer *,
481 		     u_int8_t);
482 int		 up_generate_marker(struct rde_peer *, u_int8_t);
483 int		 up_dump_prefix(u_char *, int, struct uplist_prefix *,
484 		     struct rde_peer *);
485 int		 up_dump_attrnlri(u_char *, int, struct rde_peer *);
486 u_char		*up_dump_mp_unreach(u_char *, u_int16_t *, struct rde_peer *,
487 		     u_int8_t);
488 int		 up_dump_mp_reach(u_char *, u_int16_t *, struct rde_peer *,
489 		     u_int8_t);
490 
491 #endif /* __RDE_H__ */
492