1/* $OpenBSD: rde.h,v 1.303 2024/05/29 10:36:32 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 33enum peer_state { 34 PEER_NONE, 35 PEER_DOWN, 36 PEER_UP, 37 PEER_ERR /* error occurred going to PEER_DOWN state */ 38}; 39 40LIST_HEAD(prefix_list, prefix); 41TAILQ_HEAD(prefix_queue, prefix); 42RB_HEAD(rib_tree, rib_entry); 43 44struct rib_entry { 45 RB_ENTRY(rib_entry) rib_e; 46 struct prefix_queue prefix_h; 47 struct pt_entry *prefix; 48 uint16_t rib_id; 49 uint16_t lock; 50}; 51 52struct 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 uint16_t id; 61 uint16_t flags; 62 uint16_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 */ 73RB_HEAD(peer_tree, rde_peer); 74RB_HEAD(prefix_tree, prefix); 75RB_HEAD(prefix_index, prefix); 76struct iq; 77 78struct rde_peer { 79 RB_ENTRY(rde_peer) entry; 80 SIMPLEQ_HEAD(, iq) imsg_queue; 81 struct peer_config conf; 82 struct rde_peer_stats stats; 83 struct bgpd_addr remote_addr; 84 struct bgpd_addr local_v4_addr; 85 struct bgpd_addr local_v6_addr; 86 struct capabilities capa; 87 struct addpath_eval eval; 88 struct prefix_index adj_rib_out; 89 struct prefix_tree updates[AID_MAX]; 90 struct prefix_tree withdraws[AID_MAX]; 91 struct filter_head *out_rules; 92 time_t staletime[AID_MAX]; 93 uint32_t remote_bgpid; 94 uint32_t path_id_tx; 95 unsigned int local_if_scope; 96 enum peer_state state; 97 enum export_type export_type; 98 enum role role; 99 uint16_t loc_rib_id; 100 uint16_t short_as; 101 uint16_t mrt_idx; 102 uint8_t recv_eor; /* bitfield per AID */ 103 uint8_t sent_eor; /* bitfield per AID */ 104 uint8_t reconf_out; /* out filter changed */ 105 uint8_t reconf_rib; /* rib changed */ 106 uint8_t throttled; 107 uint8_t flags; 108}; 109 110struct rde_aspa; 111struct rde_aspa_state { 112 uint8_t onlyup; 113 uint8_t downup; 114}; 115 116#define AS_SET 1 117#define AS_SEQUENCE 2 118#define AS_CONFED_SEQUENCE 3 119#define AS_CONFED_SET 4 120#define ASPATH_HEADER_SIZE (offsetof(struct aspath, data)) 121 122struct aspath { 123 uint32_t source_as; /* cached source_as */ 124 uint16_t len; /* total length of aspath in octets */ 125 uint16_t ascnt; /* number of AS hops in data */ 126 u_char data[1]; /* placeholder for actual data */ 127}; 128 129enum 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_OTC=35, 148 ATTR_FIRST_UNKNOWN, /* after this all attributes are unknown */ 149}; 150 151/* attribute flags. 4 low order bits reserved */ 152#define ATTR_EXTLEN 0x10 153#define ATTR_PARTIAL 0x20 154#define ATTR_TRANSITIVE 0x40 155#define ATTR_OPTIONAL 0x80 156#define ATTR_RESERVED 0x0f 157/* by default mask the reserved bits and the ext len bit */ 158#define ATTR_DEFMASK (ATTR_RESERVED | ATTR_EXTLEN) 159 160/* default attribute flags for well known attributes */ 161#define ATTR_WELL_KNOWN ATTR_TRANSITIVE 162 163struct attr { 164 RB_ENTRY(attr) entry; 165 u_char *data; 166 int refcnt; 167 uint16_t len; 168 uint8_t flags; 169 uint8_t type; 170}; 171 172struct rde_community { 173 RB_ENTRY(rde_community) entry; 174 int size; 175 int nentries; 176 int flags; 177 int refcnt; 178 struct community *communities; 179}; 180 181#define PARTIAL_COMMUNITIES 0x01 182#define PARTIAL_LARGE_COMMUNITIES 0x02 183#define PARTIAL_EXT_COMMUNITIES 0x04 184 185#define F_ATTR_ORIGIN 0x00001 186#define F_ATTR_ASPATH 0x00002 187#define F_ATTR_NEXTHOP 0x00004 188#define F_ATTR_LOCALPREF 0x00008 189#define F_ATTR_MED 0x00010 190#define F_ATTR_MED_ANNOUNCE 0x00020 191#define F_ATTR_MP_REACH 0x00040 192#define F_ATTR_MP_UNREACH 0x00080 193#define F_ATTR_AS4BYTE_NEW 0x00100 /* AS4_PATH or AS4_AGGREGATOR */ 194#define F_ATTR_LOOP 0x00200 /* path would cause a route loop */ 195#define F_PREFIX_ANNOUNCED 0x00400 196#define F_ANN_DYNAMIC 0x00800 197#define F_ATTR_OTC 0x01000 /* OTC present */ 198#define F_ATTR_OTC_LEAK 0x02000 /* otc leak, not eligible */ 199#define F_ATTR_PARSE_ERR 0x10000 /* parse error, not eligible */ 200#define F_ATTR_LINKED 0x20000 /* if set path is on various lists */ 201 202#define ORIGIN_IGP 0 203#define ORIGIN_EGP 1 204#define ORIGIN_INCOMPLETE 2 205 206#define DEFAULT_LPREF 100 207 208struct rde_aspath { 209 RB_ENTRY(rde_aspath) entry; 210 struct attr **others; 211 struct aspath *aspath; 212 struct rde_aspa_state aspa_state; 213 int refcnt; 214 uint32_t flags; /* internally used */ 215 uint32_t med; /* multi exit disc */ 216 uint32_t lpref; /* local pref */ 217 uint32_t weight; /* low prio lpref */ 218 uint16_t rtlabelid; /* route label id */ 219 uint16_t pftableid; /* pf table id */ 220 uint8_t origin; 221 uint8_t others_len; 222 uint8_t aspa_generation; 223}; 224 225enum nexthop_state { 226 NEXTHOP_LOOKUP, 227 NEXTHOP_UNREACH, 228 NEXTHOP_REACH, 229 NEXTHOP_FLAPPED /* only used by oldstate */ 230}; 231 232struct nexthop { 233 RB_ENTRY(nexthop) entry; 234 TAILQ_ENTRY(nexthop) runner_l; 235 struct prefix_list prefix_h; 236 struct prefix *next_prefix; 237 struct bgpd_addr exit_nexthop; 238 struct bgpd_addr true_nexthop; 239 struct bgpd_addr nexthop_net; 240#if 0 241 /* 242 * currently we use the boolean nexthop state, this could be exchanged 243 * with a variable cost with a max for unreachable. 244 */ 245 uint32_t costs; 246#endif 247 int refcnt; 248 enum nexthop_state state; 249 enum nexthop_state oldstate; 250 uint8_t nexthop_netlen; 251 uint8_t flags; 252#define NEXTHOP_CONNECTED 0x01 253}; 254 255/* generic entry without address specific part */ 256struct pt_entry { 257 RB_ENTRY(pt_entry) pt_e; 258 uint8_t aid; 259 uint8_t prefixlen; 260 uint16_t len; 261 uint32_t refcnt; 262 uint8_t data[4]; /* data depending on aid */ 263}; 264 265struct prefix { 266 union { 267 struct { 268 TAILQ_ENTRY(prefix) rib; 269 LIST_ENTRY(prefix) nexthop; 270 struct rib_entry *re; 271 } list; 272 struct { 273 RB_ENTRY(prefix) index, update; 274 } tree; 275 } entry; 276 struct pt_entry *pt; 277 struct rde_aspath *aspath; 278 struct rde_community *communities; 279 struct rde_peer *peer; 280 struct nexthop *nexthop; /* may be NULL */ 281 time_t lastchange; 282 uint32_t path_id; 283 uint32_t path_id_tx; 284 uint8_t validation_state; 285 uint8_t nhflags; 286 int8_t dmetric; /* decision metric */ 287 uint8_t flags; 288#define PREFIX_FLAG_WITHDRAW 0x01 /* enqueued on withdraw queue */ 289#define PREFIX_FLAG_UPDATE 0x02 /* enqueued on update queue */ 290#define PREFIX_FLAG_DEAD 0x04 /* locked but removed */ 291#define PREFIX_FLAG_STALE 0x08 /* stale entry (graceful reload) */ 292#define PREFIX_FLAG_MASK 0x0f /* mask for the prefix types */ 293#define PREFIX_FLAG_ADJOUT 0x10 /* prefix is in the adj-out rib */ 294#define PREFIX_FLAG_EOR 0x20 /* prefix is EoR */ 295#define PREFIX_NEXTHOP_LINKED 0x40 /* prefix is linked onto nexthop list */ 296#define PREFIX_FLAG_LOCKED 0x80 /* locked by rib walker */ 297 298#define PREFIX_DMETRIC_NONE 0 299#define PREFIX_DMETRIC_INVALID 1 300#define PREFIX_DMETRIC_VALID 2 301#define PREFIX_DMETRIC_AS_WIDE 3 302#define PREFIX_DMETRIC_ECMP 4 303#define PREFIX_DMETRIC_BEST 5 304}; 305 306/* possible states for nhflags */ 307#define NEXTHOP_SELF 0x01 308#define NEXTHOP_REJECT 0x02 309#define NEXTHOP_BLACKHOLE 0x04 310#define NEXTHOP_NOMODIFY 0x08 311#define NEXTHOP_MASK 0x0f 312#define NEXTHOP_VALID 0x80 313 314struct filterstate { 315 struct rde_aspath aspath; 316 struct rde_community communities; 317 struct nexthop *nexthop; 318 uint8_t nhflags; 319 uint8_t vstate; 320}; 321 322enum eval_mode { 323 EVAL_DEFAULT, 324 EVAL_ALL, 325 EVAL_RECONF, 326}; 327 328extern struct rde_memstats rdemem; 329 330/* prototypes */ 331/* mrt.c */ 332int mrt_dump_v2_hdr(struct mrt *, struct bgpd_config *); 333void mrt_dump_upcall(struct rib_entry *, void *); 334 335/* rde.c */ 336void rde_update_err(struct rde_peer *, uint8_t , uint8_t, 337 struct ibuf *); 338void rde_update_log(const char *, uint16_t, 339 const struct rde_peer *, const struct bgpd_addr *, 340 const struct bgpd_addr *, uint8_t); 341void rde_send_kroute_flush(struct rib *); 342void rde_send_kroute(struct rib *, struct prefix *, struct prefix *); 343void rde_send_nexthop(struct bgpd_addr *, int); 344void rde_pftable_add(uint16_t, struct prefix *); 345void rde_pftable_del(uint16_t, struct prefix *); 346 347int rde_evaluate_all(void); 348uint32_t rde_local_as(void); 349int rde_decisionflags(void); 350void rde_peer_send_rrefresh(struct rde_peer *, uint8_t, uint8_t); 351int rde_match_peer(struct rde_peer *, struct ctl_neighbor *); 352 353/* rde_peer.c */ 354int peer_has_as4byte(struct rde_peer *); 355int peer_has_add_path(struct rde_peer *, uint8_t, int); 356int peer_accept_no_as_set(struct rde_peer *); 357void peer_init(struct filter_head *); 358void peer_shutdown(void); 359void peer_foreach(void (*)(struct rde_peer *, void *), void *); 360struct rde_peer *peer_get(uint32_t); 361struct rde_peer *peer_match(struct ctl_neighbor *, uint32_t); 362struct rde_peer *peer_add(uint32_t, struct peer_config *, struct filter_head *); 363struct filter_head *peer_apply_out_filter(struct rde_peer *, 364 struct filter_head *); 365 366void rde_generate_updates(struct rib_entry *, struct prefix *, 367 struct prefix *, enum eval_mode); 368 369void peer_up(struct rde_peer *, struct session_up *); 370void peer_down(struct rde_peer *, void *); 371void peer_flush(struct rde_peer *, uint8_t, time_t); 372void peer_stale(struct rde_peer *, uint8_t, int); 373void peer_dump(struct rde_peer *, uint8_t); 374void peer_begin_rrefresh(struct rde_peer *, uint8_t); 375 376void peer_imsg_push(struct rde_peer *, struct imsg *); 377int peer_imsg_pop(struct rde_peer *, struct imsg *); 378int peer_imsg_pending(void); 379void peer_imsg_flush(struct rde_peer *); 380 381RB_PROTOTYPE(peer_tree, rde_peer, entry, peer_cmp); 382 383/* rde_attr.c */ 384int attr_writebuf(struct ibuf *, uint8_t, uint8_t, void *, 385 uint16_t); 386void attr_shutdown(void); 387int attr_optadd(struct rde_aspath *, uint8_t, uint8_t, 388 void *, uint16_t); 389struct attr *attr_optget(const struct rde_aspath *, uint8_t); 390void attr_copy(struct rde_aspath *, const struct rde_aspath *); 391int attr_compare(struct rde_aspath *, struct rde_aspath *); 392void attr_freeall(struct rde_aspath *); 393void attr_free(struct rde_aspath *, struct attr *); 394 395struct aspath *aspath_get(void *, uint16_t); 396struct aspath *aspath_copy(struct aspath *); 397void aspath_put(struct aspath *); 398u_char *aspath_deflate(u_char *, uint16_t *, int *); 399void aspath_merge(struct rde_aspath *, struct attr *); 400uint32_t aspath_neighbor(struct aspath *); 401int aspath_loopfree(struct aspath *, uint32_t); 402int aspath_compare(struct aspath *, struct aspath *); 403int aspath_match(struct aspath *, struct filter_as *, uint32_t); 404u_char *aspath_prepend(struct aspath *, uint32_t, int, uint16_t *); 405u_char *aspath_override(struct aspath *, uint32_t, uint32_t, 406 uint16_t *); 407int aspath_lenmatch(struct aspath *, enum aslen_spec, u_int); 408 409static inline u_char * 410aspath_dump(struct aspath *aspath) 411{ 412 return (aspath->data); 413} 414 415static inline uint16_t 416aspath_length(struct aspath *aspath) 417{ 418 return (aspath->len); 419} 420 421static inline uint32_t 422aspath_origin(struct aspath *aspath) 423{ 424 return (aspath->source_as); 425} 426 427/* rde_community.c */ 428int community_match(struct rde_community *, struct community *, 429 struct rde_peer *); 430int community_count(struct rde_community *, uint8_t type); 431int community_set(struct rde_community *, struct community *, 432 struct rde_peer *); 433void community_delete(struct rde_community *, struct community *, 434 struct rde_peer *); 435 436int community_add(struct rde_community *, int, struct ibuf *); 437int community_large_add(struct rde_community *, int, struct ibuf *); 438int community_ext_add(struct rde_community *, int, int, struct ibuf *); 439int community_writebuf(struct rde_community *, uint8_t, int, struct ibuf *); 440 441void communities_shutdown(void); 442struct rde_community *communities_lookup(struct rde_community *); 443struct rde_community *communities_link(struct rde_community *); 444void communities_unlink(struct rde_community *); 445 446int communities_equal(struct rde_community *, struct rde_community *); 447void communities_copy(struct rde_community *, struct rde_community *); 448void communities_clean(struct rde_community *); 449 450static inline struct rde_community * 451communities_ref(struct rde_community *comm) 452{ 453 if (comm->refcnt == 0) 454 fatalx("%s: not-referenced community", __func__); 455 comm->refcnt++; 456 rdemem.comm_refs++; 457 return comm; 458} 459 460static inline void 461communities_unref(struct rde_community *comm) 462{ 463 if (comm == NULL) 464 return; 465 rdemem.comm_refs--; 466 if (--comm->refcnt == 1) /* last ref is hold internally */ 467 communities_unlink(comm); 468} 469 470int community_to_rd(struct community *, uint64_t *); 471 472/* rde_decide.c */ 473int prefix_eligible(struct prefix *); 474struct prefix *prefix_best(struct rib_entry *); 475void prefix_evaluate(struct rib_entry *, struct prefix *, 476 struct prefix *); 477void prefix_evaluate_nexthop(struct prefix *, enum nexthop_state, 478 enum nexthop_state); 479 480/* rde_filter.c */ 481void rde_apply_set(struct filter_set_head *, struct rde_peer *, 482 struct rde_peer *, struct filterstate *, u_int8_t); 483void rde_filterstate_init(struct filterstate *); 484void rde_filterstate_prep(struct filterstate *, struct prefix *); 485void rde_filterstate_copy(struct filterstate *, struct filterstate *); 486void rde_filterstate_set_vstate(struct filterstate *, uint8_t, uint8_t); 487void rde_filterstate_clean(struct filterstate *); 488int rde_filter_skip_rule(struct rde_peer *, struct filter_rule *); 489int rde_filter_equal(struct filter_head *, struct filter_head *); 490void rde_filter_calc_skip_steps(struct filter_head *); 491enum filter_actions rde_filter(struct filter_head *, struct rde_peer *, 492 struct rde_peer *, struct bgpd_addr *, uint8_t, 493 struct filterstate *); 494 495/* rde_prefix.c */ 496void pt_init(void); 497void pt_shutdown(void); 498void pt_getaddr(struct pt_entry *, struct bgpd_addr *); 499int pt_getflowspec(struct pt_entry *, uint8_t **); 500struct pt_entry *pt_fill(struct bgpd_addr *, int); 501struct pt_entry *pt_get(struct bgpd_addr *, int); 502struct pt_entry *pt_add(struct bgpd_addr *, int); 503struct pt_entry *pt_get_flow(struct flowspec *); 504struct pt_entry *pt_add_flow(struct flowspec *); 505void pt_remove(struct pt_entry *); 506struct pt_entry *pt_lookup(struct bgpd_addr *); 507int pt_prefix_cmp(const struct pt_entry *, const struct pt_entry *); 508int pt_writebuf(struct ibuf *, struct pt_entry *, int, int, uint32_t); 509 510static inline struct pt_entry * 511pt_ref(struct pt_entry *pt) 512{ 513 ++pt->refcnt; 514 if (pt->refcnt == 0) 515 fatalx("pt_ref: overflow"); 516 return pt; 517} 518 519static inline void 520pt_unref(struct pt_entry *pt) 521{ 522 if (pt->refcnt == 0) 523 fatalx("pt_unref: underflow"); 524 if (--pt->refcnt == 0) 525 pt_remove(pt); 526} 527 528/* rde_rib.c */ 529extern uint16_t rib_size; 530 531struct rib *rib_new(char *, u_int, uint16_t); 532int rib_update(struct rib *); 533struct rib *rib_byid(uint16_t); 534uint16_t rib_find(char *); 535void rib_free(struct rib *); 536void rib_shutdown(void); 537struct rib_entry *rib_get(struct rib *, struct pt_entry *); 538struct rib_entry *rib_get_addr(struct rib *, struct bgpd_addr *, int); 539struct rib_entry *rib_match(struct rib *, struct bgpd_addr *); 540int rib_dump_pending(void); 541void rib_dump_runner(void); 542int rib_dump_new(uint16_t, uint8_t, unsigned int, void *, 543 void (*)(struct rib_entry *, void *), 544 void (*)(void *, uint8_t), 545 int (*)(void *)); 546int rib_dump_subtree(uint16_t, struct bgpd_addr *, uint8_t, 547 unsigned int count, void *arg, 548 void (*)(struct rib_entry *, void *), 549 void (*)(void *, uint8_t), 550 int (*)(void *)); 551void rib_dump_terminate(void *); 552 553extern struct rib flowrib; 554 555static inline struct rib * 556re_rib(struct rib_entry *re) 557{ 558 if (re->prefix->aid == AID_FLOWSPECv4 || 559 re->prefix->aid == AID_FLOWSPECv6) 560 return &flowrib; 561 return rib_byid(re->rib_id); 562} 563 564void path_shutdown(void); 565struct rde_aspath *path_copy(struct rde_aspath *, const struct rde_aspath *); 566struct rde_aspath *path_prep(struct rde_aspath *); 567struct rde_aspath *path_get(void); 568void path_clean(struct rde_aspath *); 569void path_put(struct rde_aspath *); 570 571#define PREFIX_SIZE(x) (((x) + 7) / 8 + 1) 572struct prefix *prefix_get(struct rib *, struct rde_peer *, uint32_t, 573 struct bgpd_addr *, int); 574struct prefix *prefix_adjout_get(struct rde_peer *, uint32_t, 575 struct pt_entry *); 576struct prefix *prefix_adjout_first(struct rde_peer *, struct pt_entry *); 577struct prefix *prefix_adjout_next(struct rde_peer *, struct prefix *); 578struct prefix *prefix_adjout_lookup(struct rde_peer *, struct bgpd_addr *, 579 int); 580struct prefix *prefix_adjout_match(struct rde_peer *, struct bgpd_addr *); 581int prefix_update(struct rib *, struct rde_peer *, uint32_t, 582 uint32_t, struct filterstate *, struct bgpd_addr *, int); 583int prefix_withdraw(struct rib *, struct rde_peer *, uint32_t, 584 struct bgpd_addr *, int); 585int prefix_flowspec_update(struct rde_peer *, struct filterstate *, 586 struct pt_entry *, uint32_t); 587int prefix_flowspec_withdraw(struct rde_peer *, struct pt_entry *); 588void prefix_flowspec_dump(uint8_t, void *, 589 void (*)(struct rib_entry *, void *), 590 void (*)(void *, uint8_t)); 591void prefix_add_eor(struct rde_peer *, uint8_t); 592void prefix_adjout_update(struct prefix *, struct rde_peer *, 593 struct filterstate *, struct pt_entry *, uint32_t); 594void prefix_adjout_withdraw(struct prefix *); 595void prefix_adjout_destroy(struct prefix *); 596int prefix_dump_new(struct rde_peer *, uint8_t, unsigned int, 597 void *, void (*)(struct prefix *, void *), 598 void (*)(void *, uint8_t), int (*)(void *)); 599int prefix_dump_subtree(struct rde_peer *, struct bgpd_addr *, 600 uint8_t, unsigned int, void *, 601 void (*)(struct prefix *, void *), 602 void (*)(void *, uint8_t), int (*)(void *)); 603struct prefix *prefix_bypeer(struct rib_entry *, struct rde_peer *, 604 uint32_t); 605void prefix_destroy(struct prefix *); 606 607RB_PROTOTYPE(prefix_tree, prefix, entry, prefix_cmp) 608 609static inline struct rde_peer * 610prefix_peer(struct prefix *p) 611{ 612 return (p->peer); 613} 614 615static inline struct rde_aspath * 616prefix_aspath(struct prefix *p) 617{ 618 return (p->aspath); 619} 620 621static inline struct rde_community * 622prefix_communities(struct prefix *p) 623{ 624 return (p->communities); 625} 626 627static inline struct nexthop * 628prefix_nexthop(struct prefix *p) 629{ 630 return (p->nexthop); 631} 632 633static inline uint8_t 634prefix_nhflags(struct prefix *p) 635{ 636 return (p->nhflags & NEXTHOP_MASK); 637} 638 639static inline int 640prefix_nhvalid(struct prefix *p) 641{ 642 return ((p->nhflags & NEXTHOP_VALID) != 0); 643} 644 645static inline uint8_t 646prefix_roa_vstate(struct prefix *p) 647{ 648 return (p->validation_state & ROA_MASK); 649} 650 651static inline uint8_t 652prefix_aspa_vstate(struct prefix *p) 653{ 654 return (p->validation_state >> 4); 655} 656 657static inline void 658prefix_set_vstate(struct prefix *p, uint8_t roa_vstate, uint8_t aspa_vstate) 659{ 660 p->validation_state = roa_vstate & ROA_MASK; 661 p->validation_state |= aspa_vstate << 4; 662} 663 664static inline struct rib_entry * 665prefix_re(struct prefix *p) 666{ 667 if (p->flags & PREFIX_FLAG_ADJOUT) 668 return NULL; 669 return (p->entry.list.re); 670} 671 672void nexthop_shutdown(void); 673int nexthop_pending(void); 674void nexthop_runner(void); 675void nexthop_modify(struct nexthop *, enum action_types, uint8_t, 676 struct nexthop **, uint8_t *); 677void nexthop_link(struct prefix *); 678void nexthop_unlink(struct prefix *); 679void nexthop_update(struct kroute_nexthop *); 680struct nexthop *nexthop_get(struct bgpd_addr *); 681struct nexthop *nexthop_ref(struct nexthop *); 682int nexthop_unref(struct nexthop *); 683 684/* rde_update.c */ 685void up_generate_updates(struct rde_peer *, struct rib_entry *); 686void up_generate_addpath(struct rde_peer *, struct rib_entry *); 687void up_generate_addpath_all(struct rde_peer *, struct rib_entry *, 688 struct prefix *, struct prefix *); 689void up_generate_default(struct rde_peer *, uint8_t); 690int up_is_eor(struct rde_peer *, uint8_t); 691int up_dump_withdraws(struct ibuf *, struct rde_peer *, uint8_t); 692int up_dump_update(struct ibuf *, struct rde_peer *, uint8_t); 693 694/* rde_aspa.c */ 695void aspa_validation(struct rde_aspa *, struct aspath *, 696 struct rde_aspa_state *); 697struct rde_aspa *aspa_table_prep(uint32_t, size_t); 698void aspa_add_set(struct rde_aspa *, uint32_t, const uint32_t *, 699 uint32_t); 700void aspa_table_free(struct rde_aspa *); 701void aspa_table_stats(const struct rde_aspa *, 702 struct ctl_show_set *); 703int aspa_table_equal(const struct rde_aspa *, 704 const struct rde_aspa *); 705void aspa_table_unchanged(struct rde_aspa *, 706 const struct rde_aspa *); 707 708#endif /* __RDE_H__ */ 709