xref: /openbsd/usr.sbin/bgpd/rde.h (revision d89ec533)
1 /*	$OpenBSD: rde.h,v 1.242 2021/08/09 08:15:34 claudio 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 #include <stdint.h>
26 #include <stddef.h>
27 
28 #include "bgpd.h"
29 #include "log.h"
30 
31 /* rde internal structures */
32 
33 enum peer_state {
34 	PEER_NONE,
35 	PEER_DOWN,
36 	PEER_UP,
37 	PEER_ERR	/* error occurred going to PEER_DOWN state */
38 };
39 
40 LIST_HEAD(prefix_list, prefix);
41 RB_HEAD(rib_tree, rib_entry);
42 
43 struct rib_entry {
44 	RB_ENTRY(rib_entry)	 rib_e;
45 	struct prefix_list	 prefix_h;
46 	struct prefix		*active;	/* for fast access */
47 	struct pt_entry		*prefix;
48 	u_int16_t		 rib_id;
49 	u_int16_t		 lock;
50 };
51 
52 struct rib {
53 	struct rib_tree		tree;
54 	char			name[PEER_DESCR_LEN];
55 	struct filter_head	*in_rules;
56 	struct filter_head	*in_rules_tmp;
57 	u_int			rtableid;
58 	u_int			rtableid_tmp;
59 	enum reconf_action	state, fibstate;
60 	u_int16_t		id;
61 	u_int16_t		flags;
62 	u_int16_t		flags_tmp;
63 };
64 
65 #define RIB_ADJ_IN	0
66 #define RIB_LOC_START	1
67 #define RIB_NOTFOUND	0xffff
68 
69 /*
70  * How do we identify peers between the session handler and the rde?
71  * Currently I assume that we can do that with the neighbor_ip...
72  */
73 LIST_HEAD(rde_peer_head, rde_peer);
74 LIST_HEAD(aspath_list, aspath);
75 LIST_HEAD(attr_list, attr);
76 LIST_HEAD(aspath_head, rde_aspath);
77 RB_HEAD(prefix_tree, prefix);
78 RB_HEAD(prefix_index, prefix);
79 struct iq;
80 
81 struct rde_peer {
82 	LIST_ENTRY(rde_peer)		 hash_l; /* hash list over all peers */
83 	LIST_ENTRY(rde_peer)		 peer_l; /* list of all peers */
84 	SIMPLEQ_HEAD(, iq)		 imsg_queue;
85 	struct peer_config		 conf;
86 	struct bgpd_addr		 remote_addr;
87 	struct bgpd_addr		 local_v4_addr;
88 	struct bgpd_addr		 local_v6_addr;
89 	struct capabilities		 capa;
90 	struct prefix_index		 adj_rib_out;
91 	struct prefix_tree		 updates[AID_MAX];
92 	struct prefix_tree		 withdraws[AID_MAX];
93 	time_t				 staletime[AID_MAX];
94 	u_int64_t			 prefix_rcvd_update;
95 	u_int64_t			 prefix_rcvd_withdraw;
96 	u_int64_t			 prefix_rcvd_eor;
97 	u_int64_t			 prefix_sent_update;
98 	u_int64_t			 prefix_sent_withdraw;
99 	u_int64_t			 prefix_sent_eor;
100 	u_int32_t			 prefix_cnt;
101 	u_int32_t			 prefix_out_cnt;
102 	u_int32_t			 remote_bgpid; /* host byte order! */
103 	u_int32_t			 up_nlricnt;
104 	u_int32_t			 up_wcnt;
105 	enum peer_state			 state;
106 	enum export_type		 export_type;
107 	u_int16_t			 loc_rib_id;
108 	u_int16_t			 short_as;
109 	u_int16_t			 mrt_idx;
110 	u_int8_t			 recv_eor;	/* bitfield per AID */
111 	u_int8_t			 sent_eor;	/* bitfield per AID */
112 	u_int8_t			 reconf_out;	/* out filter changed */
113 	u_int8_t			 reconf_rib;	/* rib changed */
114 	u_int8_t			 throttled;
115 	u_int8_t			 flags;
116 };
117 
118 #define AS_SET			1
119 #define AS_SEQUENCE		2
120 #define AS_CONFED_SEQUENCE	3
121 #define AS_CONFED_SET		4
122 #define ASPATH_HEADER_SIZE	(offsetof(struct aspath, data))
123 
124 struct aspath {
125 	LIST_ENTRY(aspath)	entry;
126 	u_int32_t		source_as;	/* cached source_as */
127 	int			refcnt;	/* reference count */
128 	u_int16_t		len;	/* total length of aspath in octets */
129 	u_int16_t		ascnt;	/* number of AS hops in data */
130 	u_char			data[1]; /* placeholder for actual data */
131 };
132 
133 enum attrtypes {
134 	ATTR_UNDEF,
135 	ATTR_ORIGIN,
136 	ATTR_ASPATH,
137 	ATTR_NEXTHOP,
138 	ATTR_MED,
139 	ATTR_LOCALPREF,
140 	ATTR_ATOMIC_AGGREGATE,
141 	ATTR_AGGREGATOR,
142 	ATTR_COMMUNITIES,
143 	ATTR_ORIGINATOR_ID,
144 	ATTR_CLUSTER_LIST,
145 	ATTR_MP_REACH_NLRI=14,
146 	ATTR_MP_UNREACH_NLRI=15,
147 	ATTR_EXT_COMMUNITIES=16,
148 	ATTR_AS4_PATH=17,
149 	ATTR_AS4_AGGREGATOR=18,
150 	ATTR_LARGE_COMMUNITIES=32,
151 	ATTR_FIRST_UNKNOWN,	/* after this all attributes are unknown */
152 };
153 
154 /* attribute flags. 4 low order bits reserved */
155 #define	ATTR_EXTLEN		0x10
156 #define ATTR_PARTIAL		0x20
157 #define ATTR_TRANSITIVE		0x40
158 #define ATTR_OPTIONAL		0x80
159 #define ATTR_RESERVED		0x0f
160 /* by default mask the reserved bits and the ext len bit */
161 #define ATTR_DEFMASK		(ATTR_RESERVED | ATTR_EXTLEN)
162 
163 /* default attribute flags for well known attributes */
164 #define ATTR_WELL_KNOWN		ATTR_TRANSITIVE
165 
166 struct attr {
167 	LIST_ENTRY(attr)		 entry;
168 	u_char				*data;
169 	u_int64_t			 hash;
170 	int				 refcnt;
171 	u_int16_t			 len;
172 	u_int8_t			 flags;
173 	u_int8_t			 type;
174 };
175 
176 struct mpattr {
177 	void		*reach;
178 	void		*unreach;
179 	u_int16_t	 reach_len;
180 	u_int16_t	 unreach_len;
181 };
182 
183 struct rde_community {
184 	LIST_ENTRY(rde_community)	entry;
185 	size_t				size;
186 	size_t				nentries;
187 	int				flags;
188 	int				refcnt;
189 	struct community		*communities;
190 };
191 
192 #define	PARTIAL_COMMUNITIES		0x01
193 #define	PARTIAL_LARGE_COMMUNITIES	0x02
194 #define	PARTIAL_EXT_COMMUNITIES		0x04
195 
196 #define	F_ATTR_ORIGIN		0x00001
197 #define	F_ATTR_ASPATH		0x00002
198 #define	F_ATTR_NEXTHOP		0x00004
199 #define	F_ATTR_LOCALPREF	0x00008
200 #define	F_ATTR_MED		0x00010
201 #define	F_ATTR_MED_ANNOUNCE	0x00020
202 #define	F_ATTR_MP_REACH		0x00040
203 #define	F_ATTR_MP_UNREACH	0x00080
204 #define	F_ATTR_AS4BYTE_NEW	0x00100	/* AS4_PATH or AS4_AGGREGATOR */
205 #define	F_ATTR_LOOP		0x00200 /* path would cause a route loop */
206 #define	F_PREFIX_ANNOUNCED	0x00400
207 #define	F_ANN_DYNAMIC		0x00800
208 #define	F_ATTR_PARSE_ERR	0x10000 /* parse error, not eligable */
209 #define	F_ATTR_LINKED		0x20000 /* if set path is on various lists */
210 
211 
212 #define ORIGIN_IGP		0
213 #define ORIGIN_EGP		1
214 #define ORIGIN_INCOMPLETE	2
215 
216 #define DEFAULT_LPREF		100
217 
218 struct rde_aspath {
219 	LIST_ENTRY(rde_aspath)		 path_l;
220 	struct attr			**others;
221 	struct aspath			*aspath;
222 	u_int64_t			 hash;
223 	int				 refcnt;
224 	u_int32_t			 flags;		/* internally used */
225 #define	aspath_hashstart	med
226 	u_int32_t			 med;		/* multi exit disc */
227 	u_int32_t			 lpref;		/* local pref */
228 	u_int32_t			 weight;	/* low prio lpref */
229 	u_int16_t			 rtlabelid;	/* route label id */
230 	u_int16_t			 pftableid;	/* pf table id */
231 	u_int8_t			 origin;
232 #define	aspath_hashend		others_len
233 	u_int8_t			 others_len;
234 };
235 
236 enum nexthop_state {
237 	NEXTHOP_LOOKUP,
238 	NEXTHOP_UNREACH,
239 	NEXTHOP_REACH,
240 	NEXTHOP_FLAPPED
241 };
242 
243 struct nexthop {
244 	LIST_ENTRY(nexthop)	nexthop_l;
245 	TAILQ_ENTRY(nexthop)	runner_l;
246 	struct prefix_list	prefix_h;
247 	struct prefix		*next_prefix;
248 	struct bgpd_addr	exit_nexthop;
249 	struct bgpd_addr	true_nexthop;
250 	struct bgpd_addr	nexthop_net;
251 #if 0
252 	/*
253 	 * currently we use the boolean nexthop state, this could be exchanged
254 	 * with a variable cost with a max for unreachable.
255 	 */
256 	u_int32_t		costs;
257 #endif
258 	int			refcnt;
259 	enum nexthop_state	state;
260 	enum nexthop_state	oldstate;
261 	u_int8_t		nexthop_netlen;
262 	u_int8_t		flags;
263 #define NEXTHOP_CONNECTED	0x01
264 };
265 
266 /* generic entry without address specific part */
267 struct pt_entry {
268 	RB_ENTRY(pt_entry)		 pt_e;
269 	u_int8_t			 aid;
270 	u_int8_t			 prefixlen;
271 	u_int16_t			 refcnt;
272 };
273 
274 struct pt_entry4 {
275 	RB_ENTRY(pt_entry)		 pt_e;
276 	u_int8_t			 aid;
277 	u_int8_t			 prefixlen;
278 	u_int16_t			 refcnt;
279 	struct in_addr			 prefix4;
280 };
281 
282 struct pt_entry6 {
283 	RB_ENTRY(pt_entry)		 pt_e;
284 	u_int8_t			 aid;
285 	u_int8_t			 prefixlen;
286 	u_int16_t			 refcnt;
287 	struct in6_addr			 prefix6;
288 };
289 
290 struct pt_entry_vpn4 {
291 	RB_ENTRY(pt_entry)		 pt_e;
292 	u_int8_t			 aid;
293 	u_int8_t			 prefixlen;
294 	u_int16_t			 refcnt;
295 	struct in_addr			 prefix4;
296 	u_int64_t			 rd;
297 	u_int8_t			 labelstack[21];
298 	u_int8_t			 labellen;
299 	u_int8_t			 pad1;
300 	u_int8_t			 pad2;
301 };
302 
303 struct pt_entry_vpn6 {
304 	RB_ENTRY(pt_entry)		 pt_e;
305 	u_int8_t			 aid;
306 	u_int8_t			 prefixlen;
307 	u_int16_t			 refcnt;
308 	struct in6_addr			 prefix6;
309 	u_int64_t			 rd;
310 	u_int8_t			 labelstack[21];
311 	u_int8_t			 labellen;
312 	u_int8_t			 pad1;
313 	u_int8_t			 pad2;
314 };
315 
316 struct prefix {
317 	union {
318 		struct {
319 			LIST_ENTRY(prefix)	 rib, nexthop;
320 			struct rib_entry	*re;
321 		} list;
322 		struct {
323 			RB_ENTRY(prefix)	 index, update;
324 		} tree;
325 	}				 entry;
326 	struct pt_entry			*pt;
327 	struct rde_aspath		*aspath;
328 	struct rde_community		*communities;
329 	struct rde_peer			*peer;
330 	struct nexthop			*nexthop;	/* may be NULL */
331 	time_t				 lastchange;
332 	u_int32_t			 path_id;
333 	u_int32_t			 path_id_tx;
334 	u_int8_t			 validation_state;
335 	u_int8_t			 nhflags;
336 	u_int8_t			 eor;
337 	u_int8_t			 flags;
338 #define	PREFIX_FLAG_WITHDRAW	0x01	/* enqueued on withdraw queue */
339 #define	PREFIX_FLAG_UPDATE	0x02	/* enqueued on update queue */
340 #define	PREFIX_FLAG_DEAD	0x04	/* locked but removed */
341 #define	PREFIX_FLAG_STALE	0x08	/* stale entry (graceful reload) */
342 #define	PREFIX_FLAG_MASK	0x0f	/* mask for the prefix types */
343 #define	PREFIX_FLAG_ADJOUT	0x10	/* prefix is in the adj-out rib */
344 #define	PREFIX_NEXTHOP_LINKED	0x40	/* prefix is linked onto nexthop list */
345 #define	PREFIX_FLAG_LOCKED	0x80	/* locked by rib walker */
346 };
347 
348 /* possible states for nhflags */
349 #define	NEXTHOP_SELF		0x01
350 #define	NEXTHOP_REJECT		0x02
351 #define	NEXTHOP_BLACKHOLE	0x04
352 #define	NEXTHOP_NOMODIFY	0x08
353 
354 struct filterstate {
355 	struct rde_aspath	 aspath;
356 	struct rde_community	 communities;
357 	struct nexthop		*nexthop;
358 	u_int8_t		 nhflags;
359 };
360 
361 extern struct rde_memstats rdemem;
362 
363 /* prototypes */
364 /* mrt.c */
365 int		mrt_dump_v2_hdr(struct mrt *, struct bgpd_config *,
366 		    struct rde_peer_head *);
367 void		mrt_dump_upcall(struct rib_entry *, void *);
368 
369 /* rde.c */
370 void		 rde_update_err(struct rde_peer *, u_int8_t , u_int8_t,
371 		     void *, u_int16_t);
372 void		 rde_update_log(const char *, u_int16_t,
373 		     const struct rde_peer *, const struct bgpd_addr *,
374 		     const struct bgpd_addr *, u_int8_t);
375 void		rde_send_kroute_flush(struct rib *);
376 void		rde_send_kroute(struct rib *, struct prefix *, struct prefix *);
377 void		rde_send_nexthop(struct bgpd_addr *, int);
378 void		rde_pftable_add(u_int16_t, struct prefix *);
379 void		rde_pftable_del(u_int16_t, struct prefix *);
380 
381 int		rde_evaluate_all(void);
382 void		rde_generate_updates(struct rib *, struct prefix *,
383 		    struct prefix *, int);
384 u_int32_t	rde_local_as(void);
385 int		rde_decisionflags(void);
386 void		rde_peer_send_rrefresh(struct rde_peer *, u_int8_t, u_int8_t);
387 int		rde_match_peer(struct rde_peer *, struct ctl_neighbor *);
388 
389 /* rde_peer.c */
390 int		 peer_has_as4byte(struct rde_peer *);
391 int		 peer_has_add_path(struct rde_peer *, u_int8_t, int);
392 int		 peer_accept_no_as_set(struct rde_peer *);
393 void		 peer_init(u_int32_t);
394 void		 peer_shutdown(void);
395 void		 peer_foreach(void (*)(struct rde_peer *, void *), void *);
396 struct rde_peer	*peer_get(u_int32_t);
397 struct rde_peer *peer_match(struct ctl_neighbor *, u_int32_t);
398 struct rde_peer	*peer_add(u_int32_t, struct peer_config *);
399 
400 int		 peer_up(struct rde_peer *, struct session_up *);
401 void		 peer_down(struct rde_peer *, void *);
402 void		 peer_flush(struct rde_peer *, u_int8_t, time_t);
403 void		 peer_stale(struct rde_peer *, u_int8_t);
404 void		 peer_dump(struct rde_peer *, u_int8_t);
405 void		 peer_begin_rrefresh(struct rde_peer *, u_int8_t);
406 
407 void		 peer_imsg_push(struct rde_peer *, struct imsg *);
408 int		 peer_imsg_pop(struct rde_peer *, struct imsg *);
409 int		 peer_imsg_pending(void);
410 void		 peer_imsg_flush(struct rde_peer *);
411 
412 /* rde_attr.c */
413 int		 attr_write(void *, u_int16_t, u_int8_t, u_int8_t, void *,
414 		     u_int16_t);
415 int		 attr_writebuf(struct ibuf *, u_int8_t, u_int8_t, void *,
416 		     u_int16_t);
417 void		 attr_init(u_int32_t);
418 void		 attr_shutdown(void);
419 void		 attr_hash_stats(struct rde_hashstats *);
420 int		 attr_optadd(struct rde_aspath *, u_int8_t, u_int8_t,
421 		     void *, u_int16_t);
422 struct attr	*attr_optget(const struct rde_aspath *, u_int8_t);
423 void		 attr_copy(struct rde_aspath *, const struct rde_aspath *);
424 int		 attr_compare(struct rde_aspath *, struct rde_aspath *);
425 u_int64_t	 attr_hash(struct rde_aspath *);
426 void		 attr_freeall(struct rde_aspath *);
427 void		 attr_free(struct rde_aspath *, struct attr *);
428 #define		 attr_optlen(x)	\
429     ((x)->len > 255 ? (x)->len + 4 : (x)->len + 3)
430 
431 void		 aspath_init(u_int32_t);
432 void		 aspath_shutdown(void);
433 void		 aspath_hash_stats(struct rde_hashstats *);
434 struct aspath	*aspath_get(void *, u_int16_t);
435 void		 aspath_put(struct aspath *);
436 u_char		*aspath_deflate(u_char *, u_int16_t *, int *);
437 void		 aspath_merge(struct rde_aspath *, struct attr *);
438 u_char		*aspath_dump(struct aspath *);
439 u_int16_t	 aspath_length(struct aspath *);
440 u_int32_t	 aspath_neighbor(struct aspath *);
441 u_int32_t	 aspath_origin(struct aspath *);
442 int		 aspath_loopfree(struct aspath *, u_int32_t);
443 int		 aspath_compare(struct aspath *, struct aspath *);
444 int		 aspath_match(struct aspath *, struct filter_as *, u_int32_t);
445 u_char		*aspath_prepend(struct aspath *, u_int32_t, int, u_int16_t *);
446 u_char		*aspath_override(struct aspath *, u_int32_t, u_int32_t,
447 		    u_int16_t *);
448 int		 aspath_lenmatch(struct aspath *, enum aslen_spec, u_int);
449 
450 /* rde_community.c */
451 int	community_match(struct rde_community *, struct community *,
452 	    struct rde_peer *);
453 int	community_set(struct rde_community *, struct community *,
454 	    struct rde_peer *);
455 void	community_delete(struct rde_community *, struct community *,
456 	    struct rde_peer *);
457 
458 int	community_add(struct rde_community *, int, void *, size_t);
459 int	community_large_add(struct rde_community *, int, void *, size_t);
460 int	community_ext_add(struct rde_community *, int, void *, size_t);
461 
462 int	community_write(struct rde_community *, void *, u_int16_t);
463 int	community_large_write(struct rde_community *, void *, u_int16_t);
464 int	community_ext_write(struct rde_community *, int, void *, u_int16_t);
465 int	community_writebuf(struct ibuf *, struct rde_community *);
466 
467 void			 communities_init(u_int32_t);
468 void			 communities_shutdown(void);
469 void			 communities_hash_stats(struct rde_hashstats *);
470 struct rde_community	*communities_lookup(struct rde_community *);
471 struct rde_community	*communities_link(struct rde_community *);
472 void			 communities_unlink(struct rde_community *);
473 
474 int	 communities_equal(struct rde_community *, struct rde_community *);
475 void	 communities_copy(struct rde_community *, struct rde_community *);
476 void	 communities_clean(struct rde_community *);
477 
478 static inline struct rde_community *
479 communities_ref(struct rde_community *comm)
480 {
481 	if (comm->refcnt == 0)
482 		fatalx("%s: not-referenced community", __func__);
483 	comm->refcnt++;
484 	rdemem.comm_refs++;
485 	return comm;
486 }
487 
488 static inline void
489 communities_unref(struct rde_community *comm)
490 {
491 	if (comm == NULL)
492 		return;
493 	rdemem.comm_refs--;
494 	if (--comm->refcnt == 1)	/* last ref is hold internally */
495 		communities_unlink(comm);
496 }
497 
498 int	community_to_rd(struct community *, u_int64_t *);
499 
500 /* rde_decide.c */
501 int	prefix_eligible(struct prefix *);
502 void	prefix_evaluate(struct rib_entry *, struct prefix *, struct prefix *);
503 
504 /* rde_filter.c */
505 void	rde_apply_set(struct filter_set_head *, struct rde_peer *,
506 	    struct rde_peer *, struct filterstate *, u_int8_t);
507 void	rde_filterstate_prep(struct filterstate *, struct rde_aspath *,
508 	    struct rde_community *, struct nexthop *, u_int8_t);
509 void	rde_filterstate_clean(struct filterstate *);
510 int	rde_filter_equal(struct filter_head *, struct filter_head *,
511 	    struct rde_peer *);
512 void	rde_filter_calc_skip_steps(struct filter_head *);
513 enum filter_actions rde_filter(struct filter_head *, struct rde_peer *,
514 	    struct rde_peer *, struct bgpd_addr *, u_int8_t, u_int8_t,
515 	    struct filterstate *);
516 
517 /* rde_prefix.c */
518 void	 pt_init(void);
519 void	 pt_shutdown(void);
520 void	 pt_getaddr(struct pt_entry *, struct bgpd_addr *);
521 struct pt_entry	*pt_fill(struct bgpd_addr *, int);
522 struct pt_entry	*pt_get(struct bgpd_addr *, int);
523 struct pt_entry *pt_add(struct bgpd_addr *, int);
524 void	 pt_remove(struct pt_entry *);
525 struct pt_entry	*pt_lookup(struct bgpd_addr *);
526 int	 pt_prefix_cmp(const struct pt_entry *, const struct pt_entry *);
527 
528 static inline struct pt_entry *
529 pt_ref(struct pt_entry *pt)
530 {
531 	++pt->refcnt;
532 	if (pt->refcnt == 0)
533 		fatalx("pt_ref: overflow");
534 	return pt;
535 }
536 
537 static inline void
538 pt_unref(struct pt_entry *pt)
539 {
540 	if (pt->refcnt == 0)
541 		fatalx("pt_unref: underflow");
542 	if (--pt->refcnt == 0)
543 		pt_remove(pt);
544 }
545 
546 /* rde_rib.c */
547 extern u_int16_t	rib_size;
548 
549 struct rib	*rib_new(char *, u_int, u_int16_t);
550 void		 rib_update(struct rib *);
551 struct rib	*rib_byid(u_int16_t);
552 u_int16_t	 rib_find(char *);
553 void		 rib_free(struct rib *);
554 void		 rib_shutdown(void);
555 struct rib_entry *rib_get(struct rib *, struct bgpd_addr *, int);
556 struct rib_entry *rib_match(struct rib *, struct bgpd_addr *);
557 int		 rib_dump_pending(void);
558 void		 rib_dump_runner(void);
559 int		 rib_dump_new(u_int16_t, u_int8_t, unsigned int, void *,
560 		    void (*)(struct rib_entry *, void *),
561 		    void (*)(void *, u_int8_t),
562 		    int (*)(void *));
563 void		 rib_dump_terminate(void *);
564 
565 static inline struct rib *
566 re_rib(struct rib_entry *re)
567 {
568 	return rib_byid(re->rib_id);
569 }
570 
571 void		 path_init(u_int32_t);
572 void		 path_shutdown(void);
573 void		 path_hash_stats(struct rde_hashstats *);
574 int		 path_compare(struct rde_aspath *, struct rde_aspath *);
575 u_int32_t	 path_remove_stale(struct rde_aspath *, u_int8_t, time_t);
576 struct rde_aspath *path_copy(struct rde_aspath *, const struct rde_aspath *);
577 struct rde_aspath *path_prep(struct rde_aspath *);
578 struct rde_aspath *path_get(void);
579 void		 path_clean(struct rde_aspath *);
580 void		 path_put(struct rde_aspath *);
581 
582 #define	PREFIX_SIZE(x)	(((x) + 7) / 8 + 1)
583 struct prefix	*prefix_get(struct rib *, struct rde_peer *, u_int32_t,
584 		    struct bgpd_addr *, int);
585 struct prefix	*prefix_lookup(struct rde_peer *, struct bgpd_addr *, int);
586 struct prefix	*prefix_match(struct rde_peer *, struct bgpd_addr *);
587 int		 prefix_update(struct rib *, struct rde_peer *, u_int32_t,
588 		     struct filterstate *, struct bgpd_addr *, int, u_int8_t);
589 int		 prefix_withdraw(struct rib *, struct rde_peer *, u_int32_t,
590 		    struct bgpd_addr *, int);
591 void		 prefix_add_eor(struct rde_peer *, u_int8_t);
592 int		 prefix_adjout_update(struct rde_peer *, struct filterstate *,
593 		    struct bgpd_addr *, int, u_int8_t);
594 int		 prefix_adjout_withdraw(struct rde_peer *, struct bgpd_addr *,
595 		    int);
596 void		 prefix_adjout_destroy(struct prefix *p);
597 void		 prefix_adjout_dump(struct rde_peer *, void *,
598 		    void (*)(struct prefix *, void *));
599 int		 prefix_dump_new(struct rde_peer *, u_int8_t, unsigned int,
600 		    void *, void (*)(struct prefix *, void *),
601 		    void (*)(void *, u_int8_t), int (*)(void *));
602 int		 prefix_write(u_char *, int, struct bgpd_addr *, u_int8_t, int);
603 int		 prefix_writebuf(struct ibuf *, struct bgpd_addr *, u_int8_t);
604 struct prefix	*prefix_bypeer(struct rib_entry *, struct rde_peer *,
605 		    u_int32_t);
606 void		 prefix_destroy(struct prefix *);
607 void		 prefix_relink(struct prefix *, struct rde_aspath *, int);
608 
609 RB_PROTOTYPE(prefix_tree, prefix, entry, prefix_cmp)
610 
611 static inline struct rde_peer *
612 prefix_peer(struct prefix *p)
613 {
614 	return (p->peer);
615 }
616 
617 static inline struct rde_aspath *
618 prefix_aspath(struct prefix *p)
619 {
620 	return (p->aspath);
621 }
622 
623 static inline struct rde_community *
624 prefix_communities(struct prefix *p)
625 {
626 	return (p->communities);
627 }
628 
629 static inline struct nexthop *
630 prefix_nexthop(struct prefix *p)
631 {
632 	return (p->nexthop);
633 }
634 
635 static inline u_int8_t
636 prefix_nhflags(struct prefix *p)
637 {
638 	return (p->nhflags);
639 }
640 
641 static inline u_int8_t
642 prefix_vstate(struct prefix *p)
643 {
644 	return (p->validation_state & ROA_MASK);
645 }
646 
647 static inline struct rib_entry *
648 prefix_re(struct prefix *p)
649 {
650 	if (p->flags & PREFIX_FLAG_ADJOUT)
651 		return NULL;
652 	return (p->entry.list.re);
653 }
654 
655 void		 nexthop_init(u_int32_t);
656 void		 nexthop_shutdown(void);
657 int		 nexthop_pending(void);
658 void		 nexthop_runner(void);
659 void		 nexthop_modify(struct nexthop *, enum action_types, u_int8_t,
660 		    struct nexthop **, u_int8_t *);
661 void		 nexthop_link(struct prefix *);
662 void		 nexthop_unlink(struct prefix *);
663 void		 nexthop_update(struct kroute_nexthop *);
664 struct nexthop	*nexthop_get(struct bgpd_addr *);
665 struct nexthop	*nexthop_ref(struct nexthop *);
666 int		 nexthop_unref(struct nexthop *);
667 int		 nexthop_compare(struct nexthop *, struct nexthop *);
668 
669 /* rde_update.c */
670 void		 up_init(struct rde_peer *);
671 void		 up_generate_updates(struct filter_head *, struct rde_peer *,
672 		     struct prefix *, struct prefix *);
673 void		 up_generate_default(struct filter_head *, struct rde_peer *,
674 		     u_int8_t);
675 int		 up_is_eor(struct rde_peer *, u_int8_t);
676 int		 up_dump_withdraws(u_char *, int, struct rde_peer *, u_int8_t);
677 int		 up_dump_mp_unreach(u_char *, int, struct rde_peer *, u_int8_t);
678 int		 up_dump_attrnlri(u_char *, int, struct rde_peer *);
679 int		 up_dump_mp_reach(u_char *, int, struct rde_peer *, u_int8_t);
680 
681 #endif /* __RDE_H__ */
682