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