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