xref: /openbsd/usr.sbin/bgpd/rde.h (revision 17df1aa7)
1 /*	$OpenBSD: rde.h,v 1.134 2010/05/03 13:09:38 claudio Exp $ */
2 
3 /*
4  * Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> and
5  *                          Andre Oppermann <oppermann@pipeline.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 	u_int64_t			 prefix_rcvd_update;
63 	u_int64_t			 prefix_rcvd_withdraw;
64 	u_int64_t			 prefix_sent_update;
65 	u_int64_t			 prefix_sent_withdraw;
66 	u_int32_t			 prefix_cnt; /* # of prefixes */
67 	u_int32_t			 remote_bgpid; /* host byte order! */
68 	u_int32_t			 up_pcnt;
69 	u_int32_t			 up_acnt;
70 	u_int32_t			 up_nlricnt;
71 	u_int32_t			 up_wcnt;
72 	enum peer_state			 state;
73 	u_int16_t			 ribid;
74 	u_int16_t			 short_as;
75 	u_int8_t			 reconf_in;	/* in filter changed */
76 	u_int8_t			 reconf_out;	/* out filter changed */
77 };
78 
79 #define AS_SET			1
80 #define AS_SEQUENCE		2
81 #define ASPATH_HEADER_SIZE	(sizeof(struct aspath) - sizeof(u_char))
82 
83 LIST_HEAD(aspath_list, aspath);
84 
85 struct aspath {
86 	LIST_ENTRY(aspath)	entry;
87 	int			refcnt;	/* reference count */
88 	u_int16_t		len;	/* total length of aspath in octets */
89 	u_int16_t		ascnt;	/* number of AS hops in data */
90 	u_char			data[1]; /* placeholder for actual data */
91 };
92 
93 enum attrtypes {
94 	ATTR_UNDEF,
95 	ATTR_ORIGIN,
96 	ATTR_ASPATH,
97 	ATTR_NEXTHOP,
98 	ATTR_MED,
99 	ATTR_LOCALPREF,
100 	ATTR_ATOMIC_AGGREGATE,
101 	ATTR_AGGREGATOR,
102 	ATTR_COMMUNITIES,
103 	ATTR_ORIGINATOR_ID,
104 	ATTR_CLUSTER_LIST,
105 	ATTR_MP_REACH_NLRI=14,
106 	ATTR_MP_UNREACH_NLRI=15,
107 	ATTR_EXT_COMMUNITIES=16,
108 	ATTR_AS4_PATH=17,
109 	ATTR_AS4_AGGREGATOR=18
110 };
111 
112 /* attribute flags. 4 low order bits reserved */
113 #define	ATTR_EXTLEN		0x10
114 #define ATTR_PARTIAL		0x20
115 #define ATTR_TRANSITIVE		0x40
116 #define ATTR_OPTIONAL		0x80
117 
118 /* default attribute flags for well known attributes */
119 #define ATTR_WELL_KNOWN		ATTR_TRANSITIVE
120 
121 struct attr {
122 	LIST_ENTRY(attr)		 entry;
123 	u_char				*data;
124 	int				 refcnt;
125 	u_int32_t			 hash;
126 	u_int16_t			 len;
127 	u_int8_t			 flags;
128 	u_int8_t			 type;
129 };
130 
131 struct mpattr {
132 	void		*reach;
133 	void		*unreach;
134 	u_int16_t	 reach_len;
135 	u_int16_t	 unreach_len;
136 };
137 
138 LIST_HEAD(attr_list, attr);
139 
140 struct path_table {
141 	struct aspath_head	*path_hashtbl;
142 	u_int32_t		 path_hashmask;
143 };
144 
145 LIST_HEAD(prefix_head, prefix);
146 
147 #define	F_ATTR_ORIGIN		0x00001
148 #define	F_ATTR_ASPATH		0x00002
149 #define	F_ATTR_NEXTHOP		0x00004
150 #define	F_ATTR_LOCALPREF	0x00008
151 #define	F_ATTR_MED		0x00010
152 #define	F_ATTR_MED_ANNOUNCE	0x00020
153 #define	F_ATTR_MP_REACH		0x00040
154 #define	F_ATTR_MP_UNREACH	0x00080
155 #define	F_ATTR_AS4BYTE_NEW	0x00100	/* AS4_PATH or AS4_AGGREGATOR */
156 #define	F_ATTR_LOOP		0x00200 /* path would cause a route loop */
157 #define	F_PREFIX_ANNOUNCED	0x00400
158 #define	F_ANN_DYNAMIC		0x00800
159 #define	F_NEXTHOP_SELF		0x01000
160 #define	F_NEXTHOP_REJECT	0x02000
161 #define	F_NEXTHOP_BLACKHOLE	0x04000
162 #define	F_NEXTHOP_NOMODIFY	0x08000
163 #define	F_ATTR_PARSE_ERR	0x10000
164 #define	F_ATTR_LINKED		0x20000
165 
166 
167 #define ORIGIN_IGP		0
168 #define ORIGIN_EGP		1
169 #define ORIGIN_INCOMPLETE	2
170 
171 #define DEFAULT_LPREF		100
172 
173 struct rde_aspath {
174 	LIST_ENTRY(rde_aspath)		 path_l, peer_l, nexthop_l;
175 	struct prefix_head		 prefix_h;
176 	struct attr			**others;
177 	struct rde_peer			*peer;
178 	struct aspath			*aspath;
179 	struct nexthop			*nexthop;	/* may be NULL */
180 	u_int32_t			 med;		/* multi exit disc */
181 	u_int32_t			 lpref;		/* local pref */
182 	u_int32_t			 weight;	/* low prio lpref */
183 	u_int32_t			 prefix_cnt; /* # of prefixes */
184 	u_int32_t			 active_cnt; /* # of active prefixes */
185 	u_int32_t			 flags;		/* internally used */
186 	u_int16_t			 rtlabelid;	/* route label id */
187 	u_int16_t			 pftableid;	/* pf table id */
188 	u_int8_t			 origin;
189 	u_int8_t			 others_len;
190 };
191 
192 enum nexthop_state {
193 	NEXTHOP_LOOKUP,
194 	NEXTHOP_UNREACH,
195 	NEXTHOP_REACH
196 };
197 
198 struct nexthop {
199 	LIST_ENTRY(nexthop)	nexthop_l;
200 	struct aspath_head	path_h;
201 	struct bgpd_addr	exit_nexthop;
202 	struct bgpd_addr	true_nexthop;
203 	struct bgpd_addr	nexthop_net;
204 #if 0
205 	/*
206 	 * currently we use the boolean nexthop state, this could be exchanged
207 	 * with a variable cost with a max for unreachable.
208 	 */
209 	u_int32_t		costs;
210 #endif
211 	int			refcnt;	/* filterset reference counter */
212 	enum nexthop_state	state;
213 	u_int8_t		nexthop_netlen;
214 	u_int8_t		flags;
215 #define NEXTHOP_CONNECTED	0x01
216 };
217 
218 /* generic entry without address specific part */
219 struct pt_entry {
220 	RB_ENTRY(pt_entry)		 pt_e;
221 	u_int8_t			 aid;
222 	u_int8_t			 prefixlen;
223 	u_int16_t			 refcnt;
224 };
225 
226 struct pt_entry4 {
227 	RB_ENTRY(pt_entry)		 pt_e;
228 	u_int8_t			 aid;
229 	u_int8_t			 prefixlen;
230 	u_int16_t			 refcnt;
231 	struct in_addr			 prefix4;
232 };
233 
234 struct pt_entry6 {
235 	RB_ENTRY(pt_entry)		 pt_e;
236 	u_int8_t			 aid;
237 	u_int8_t			 prefixlen;
238 	u_int16_t			 refcnt;
239 	struct in6_addr			 prefix6;
240 };
241 
242 struct pt_entry_vpn4 {
243 	RB_ENTRY(pt_entry)		 pt_e;
244 	u_int8_t			 aid;
245 	u_int8_t			 prefixlen;
246 	u_int16_t			 refcnt;
247 	struct in_addr			 prefix4;
248 	u_int64_t			 rd;
249 	u_int8_t			 labelstack[21];
250 	u_int8_t			 labellen;
251 	u_int8_t			 pad1;
252 	u_int8_t			 pad2;
253 };
254 
255 struct rib_context {
256 	LIST_ENTRY(rib_context)		 entry;
257 	struct rib_entry		*ctx_re;
258 	struct rib			*ctx_rib;
259 	void		(*ctx_upcall)(struct rib_entry *, void *);
260 	void		(*ctx_done)(void *);
261 	void		(*ctx_wait)(void *);
262 	void				*ctx_arg;
263 	unsigned int			 ctx_count;
264 	u_int8_t			 ctx_aid;
265 };
266 
267 struct rib_entry {
268 	RB_ENTRY(rib_entry)	 rib_e;
269 	struct prefix_head	 prefix_h;
270 	struct prefix		*active; /* for fast access */
271 	struct pt_entry		*prefix;
272 	u_int16_t		 ribid;
273 	u_int16_t		 flags;
274 };
275 
276 struct rib {
277 	char			name[PEER_DESCR_LEN];
278 	struct rib_tree		rib;
279 	u_int			rtableid;
280 	u_int16_t		flags;
281 	u_int16_t		id;
282 	enum reconf_action 	state;
283 };
284 
285 #define RIB_FAILED		0xffff
286 
287 struct prefix {
288 	LIST_ENTRY(prefix)		 rib_l, path_l;
289 	struct rde_aspath		*aspath;
290 	struct pt_entry			*prefix;
291 	struct rib_entry		*rib;	/* NULL for Adj-RIB-In */
292 	time_t				 lastchange;
293 };
294 
295 extern struct rde_memstats rdemem;
296 
297 /* prototypes */
298 /* rde.c */
299 void		 rde_send_kroute(struct prefix *, struct prefix *, u_int16_t);
300 void		 rde_send_nexthop(struct bgpd_addr *, int);
301 void		 rde_send_pftable(u_int16_t, struct bgpd_addr *,
302 		     u_int8_t, int);
303 void		 rde_send_pftable_commit(void);
304 
305 void		 rde_generate_updates(u_int16_t, struct prefix *,
306 		     struct prefix *);
307 u_int32_t	 rde_local_as(void);
308 int		 rde_noevaluate(void);
309 int		 rde_decisionflags(void);
310 int		 rde_as4byte(struct rde_peer *);
311 
312 /* rde_attr.c */
313 int		 attr_write(void *, u_int16_t, u_int8_t, u_int8_t, void *,
314 		     u_int16_t);
315 int		 attr_writebuf(struct buf *, u_int8_t, u_int8_t, void *,
316 		     u_int16_t);
317 void		 attr_init(u_int32_t);
318 void		 attr_shutdown(void);
319 int		 attr_optadd(struct rde_aspath *, u_int8_t, u_int8_t,
320 		     void *, u_int16_t);
321 struct attr	*attr_optget(const struct rde_aspath *, u_int8_t);
322 void		 attr_copy(struct rde_aspath *, struct rde_aspath *);
323 int		 attr_compare(struct rde_aspath *, struct rde_aspath *);
324 void		 attr_freeall(struct rde_aspath *);
325 void		 attr_free(struct rde_aspath *, struct attr *);
326 #define		 attr_optlen(x)	\
327     ((x)->len > 255 ? (x)->len + 4 : (x)->len + 3)
328 
329 int		 aspath_verify(void *, u_int16_t, int);
330 #define		 AS_ERR_LEN	-1
331 #define		 AS_ERR_TYPE	-2
332 #define		 AS_ERR_BAD	-3
333 void		 aspath_init(u_int32_t);
334 void		 aspath_shutdown(void);
335 struct aspath	*aspath_get(void *, u_int16_t);
336 void		 aspath_put(struct aspath *);
337 u_char		*aspath_inflate(void *, u_int16_t, u_int16_t *);
338 u_char		*aspath_deflate(u_char *, u_int16_t *, int *);
339 void		 aspath_merge(struct rde_aspath *, struct attr *);
340 u_char		*aspath_dump(struct aspath *);
341 u_int16_t	 aspath_length(struct aspath *);
342 u_int16_t	 aspath_count(const void *, u_int16_t);
343 u_int32_t	 aspath_neighbor(struct aspath *);
344 int		 aspath_loopfree(struct aspath *, u_int32_t);
345 int		 aspath_compare(struct aspath *, struct aspath *);
346 u_char		*aspath_prepend(struct aspath *, u_int32_t, int, u_int16_t *);
347 int		 aspath_match(struct aspath *, enum as_spec, u_int32_t);
348 int		 community_match(struct rde_aspath *, int, int);
349 int		 community_set(struct rde_aspath *, int, int);
350 void		 community_delete(struct rde_aspath *, int, int);
351 int		 community_ext_match(struct rde_aspath *,
352 		    struct filter_extcommunity *, u_int16_t);
353 int		 community_ext_set(struct rde_aspath *,
354 		    struct filter_extcommunity *, u_int16_t);
355 void		 community_ext_delete(struct rde_aspath *,
356 		    struct filter_extcommunity *, u_int16_t);
357 int		 community_ext_conv(struct filter_extcommunity *, u_int16_t,
358 		    u_int64_t *);
359 
360 /* rde_rib.c */
361 extern u_int16_t	 rib_size;
362 extern struct rib	*ribs;
363 
364 u_int16_t	 rib_new(char *, u_int, u_int16_t);
365 u_int16_t	 rib_find(char *);
366 void		 rib_free(struct rib *);
367 struct rib_entry *rib_get(struct rib *, struct bgpd_addr *, int);
368 struct rib_entry *rib_lookup(struct rib *, struct bgpd_addr *);
369 void		 rib_dump(struct rib *, void (*)(struct rib_entry *, void *),
370 		     void *, u_int8_t);
371 void		 rib_dump_r(struct rib_context *);
372 void		 rib_dump_runner(void);
373 int		 rib_dump_pending(void);
374 
375 void		 path_init(u_int32_t);
376 void		 path_shutdown(void);
377 int		 path_update(struct rib *, struct rde_peer *,
378 		     struct rde_aspath *, struct bgpd_addr *, int);
379 int		 path_compare(struct rde_aspath *, struct rde_aspath *);
380 struct rde_aspath *path_lookup(struct rde_aspath *, struct rde_peer *);
381 void		 path_remove(struct rde_aspath *);
382 void		 path_destroy(struct rde_aspath *);
383 int		 path_empty(struct rde_aspath *);
384 struct rde_aspath *path_copy(struct rde_aspath *);
385 struct rde_aspath *path_get(void);
386 void		 path_put(struct rde_aspath *);
387 
388 #define	PREFIX_SIZE(x)	(((x) + 7) / 8 + 1)
389 int		 prefix_compare(const struct bgpd_addr *,
390 		    const struct bgpd_addr *, int);
391 struct prefix	*prefix_get(struct rib *, struct rde_peer *,
392 		    struct bgpd_addr *, int, u_int32_t);
393 int		 prefix_add(struct rib *, struct rde_aspath *,
394 		    struct bgpd_addr *, int);
395 void		 prefix_move(struct rde_aspath *, struct prefix *);
396 int		 prefix_remove(struct rib *, struct rde_peer *,
397 		    struct bgpd_addr *, int, u_int32_t);
398 int		 prefix_write(u_char *, int, struct bgpd_addr *, u_int8_t);
399 struct prefix	*prefix_bypeer(struct rib_entry *, struct rde_peer *,
400 		     u_int32_t);
401 void		 prefix_updateall(struct rde_aspath *, enum nexthop_state,
402 		     enum nexthop_state);
403 void		 prefix_destroy(struct prefix *);
404 void		 prefix_network_clean(struct rde_peer *, time_t, u_int32_t);
405 
406 void		 nexthop_init(u_int32_t);
407 void		 nexthop_shutdown(void);
408 void		 nexthop_modify(struct rde_aspath *, struct bgpd_addr *,
409 		     enum action_types, u_int8_t);
410 void		 nexthop_link(struct rde_aspath *);
411 void		 nexthop_unlink(struct rde_aspath *);
412 int		 nexthop_delete(struct nexthop *);
413 void		 nexthop_update(struct kroute_nexthop *);
414 struct nexthop	*nexthop_get(struct bgpd_addr *);
415 int		 nexthop_compare(struct nexthop *, struct nexthop *);
416 
417 /* rde_decide.c */
418 void		 prefix_evaluate(struct prefix *, struct rib_entry *);
419 
420 /* rde_update.c */
421 void		 up_init(struct rde_peer *);
422 void		 up_down(struct rde_peer *);
423 int		 up_test_update(struct rde_peer *, struct prefix *);
424 int		 up_generate(struct rde_peer *, struct rde_aspath *,
425 		     struct bgpd_addr *, u_int8_t);
426 void		 up_generate_updates(struct filter_head *, struct rde_peer *,
427 		     struct prefix *, struct prefix *);
428 void		 up_generate_default(struct filter_head *, struct rde_peer *,
429 		     u_int8_t);
430 int		 up_generate_marker(struct rde_peer *, u_int8_t);
431 int		 up_dump_prefix(u_char *, int, struct uplist_prefix *,
432 		     struct rde_peer *);
433 int		 up_dump_attrnlri(u_char *, int, struct rde_peer *);
434 u_char		*up_dump_mp_unreach(u_char *, u_int16_t *, struct rde_peer *,
435 		     u_int8_t);
436 int		 up_dump_mp_reach(u_char *, u_int16_t *, struct rde_peer *,
437 		     u_int8_t);
438 
439 /* rde_prefix.c */
440 #define pt_empty(pt)	((pt)->refcnt == 0)
441 #define pt_ref(pt)	do {				\
442 	++(pt)->refcnt;					\
443 	if ((pt)->refcnt == 0)				\
444 		fatalx("pt_ref: overflow");		\
445 } while(0)
446 #define pt_unref(pt)	do {				\
447 	if ((pt)->refcnt == 0)				\
448 		fatalx("pt_unref: underflow");		\
449 	--(pt)->refcnt;					\
450 } while(0)
451 
452 void	 pt_init(void);
453 void	 pt_shutdown(void);
454 void	 pt_getaddr(struct pt_entry *, struct bgpd_addr *);
455 struct pt_entry	*pt_fill(struct bgpd_addr *, int);
456 struct pt_entry	*pt_get(struct bgpd_addr *, int);
457 struct pt_entry *pt_add(struct bgpd_addr *, int);
458 void	 pt_remove(struct pt_entry *);
459 struct pt_entry	*pt_lookup(struct bgpd_addr *);
460 int	 pt_prefix_cmp(const struct pt_entry *, const struct pt_entry *);
461 
462 
463 /* rde_filter.c */
464 enum filter_actions rde_filter(u_int16_t, struct rde_aspath **,
465 		     struct filter_head *, struct rde_peer *,
466 		     struct rde_aspath *, struct bgpd_addr *, u_int8_t,
467 		     struct rde_peer *, enum directions);
468 void		 rde_apply_set(struct rde_aspath *, struct filter_set_head *,
469 		     u_int8_t, struct rde_peer *, struct rde_peer *);
470 int		 rde_filter_equal(struct filter_head *, struct filter_head *,
471 		     struct rde_peer *, enum directions);
472 
473 /* util.c */
474 u_int32_t	 aspath_extract(const void *, int);
475 
476 #endif /* __RDE_H__ */
477