1 /* $OpenBSD: rde.h,v 1.234 2020/06/05 19:50:59 denis 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_send_pftable(u_int16_t, struct bgpd_addr *, 372 u_int8_t, int); 373 void rde_send_pftable_commit(void); 374 375 void rde_generate_updates(struct rib *, struct prefix *, 376 struct prefix *); 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 * 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 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 void prefix_evaluate(struct prefix *, struct rib_entry *); 491 492 /* rde_filter.c */ 493 void rde_apply_set(struct filter_set_head *, struct rde_peer *, 494 struct rde_peer *, struct filterstate *, u_int8_t); 495 void rde_filterstate_prep(struct filterstate *, struct rde_aspath *, 496 struct rde_community *, struct nexthop *, u_int8_t); 497 void rde_filterstate_clean(struct filterstate *); 498 int rde_filter_equal(struct filter_head *, struct filter_head *, 499 struct rde_peer *); 500 void rde_filter_calc_skip_steps(struct filter_head *); 501 enum filter_actions rde_filter(struct filter_head *, struct rde_peer *, 502 struct rde_peer *, struct bgpd_addr *, u_int8_t, u_int8_t, 503 struct filterstate *); 504 505 /* rde_prefix.c */ 506 void pt_init(void); 507 void pt_shutdown(void); 508 void pt_getaddr(struct pt_entry *, struct bgpd_addr *); 509 struct pt_entry *pt_fill(struct bgpd_addr *, int); 510 struct pt_entry *pt_get(struct bgpd_addr *, int); 511 struct pt_entry *pt_add(struct bgpd_addr *, int); 512 void pt_remove(struct pt_entry *); 513 struct pt_entry *pt_lookup(struct bgpd_addr *); 514 int pt_prefix_cmp(const struct pt_entry *, const struct pt_entry *); 515 516 static inline struct pt_entry * 517 pt_ref(struct pt_entry *pt) 518 { 519 ++pt->refcnt; 520 if (pt->refcnt == 0) 521 fatalx("pt_ref: overflow"); 522 return pt; 523 } 524 525 static inline void 526 pt_unref(struct pt_entry *pt) 527 { 528 if (pt->refcnt == 0) 529 fatalx("pt_unref: underflow"); 530 if (--pt->refcnt == 0) 531 pt_remove(pt); 532 } 533 534 /* rde_rib.c */ 535 extern u_int16_t rib_size; 536 537 struct rib *rib_new(char *, u_int, u_int16_t); 538 void rib_update(struct rib *); 539 struct rib *rib_byid(u_int16_t); 540 u_int16_t rib_find(char *); 541 void rib_free(struct rib *); 542 void rib_shutdown(void); 543 struct rib_entry *rib_get(struct rib *, struct bgpd_addr *, int); 544 struct rib_entry *rib_match(struct rib *, struct bgpd_addr *); 545 int rib_dump_pending(void); 546 void rib_dump_runner(void); 547 int rib_dump_new(u_int16_t, u_int8_t, unsigned int, void *, 548 void (*)(struct rib_entry *, void *), 549 void (*)(void *, u_int8_t), 550 int (*)(void *)); 551 void rib_dump_terminate(void *); 552 553 static inline struct rib * 554 re_rib(struct rib_entry *re) 555 { 556 return rib_byid(re->rib_id); 557 } 558 559 void path_init(u_int32_t); 560 void path_shutdown(void); 561 void path_hash_stats(struct rde_hashstats *); 562 int path_compare(struct rde_aspath *, struct rde_aspath *); 563 u_int32_t path_remove_stale(struct rde_aspath *, u_int8_t, time_t); 564 struct rde_aspath *path_copy(struct rde_aspath *, const struct rde_aspath *); 565 struct rde_aspath *path_prep(struct rde_aspath *); 566 struct rde_aspath *path_get(void); 567 void path_clean(struct rde_aspath *); 568 void path_put(struct rde_aspath *); 569 570 #define PREFIX_SIZE(x) (((x) + 7) / 8 + 1) 571 struct prefix *prefix_get(struct rib *, struct rde_peer *, 572 struct bgpd_addr *, int); 573 struct prefix *prefix_lookup(struct rde_peer *, struct bgpd_addr *, int); 574 struct prefix *prefix_match(struct rde_peer *, struct bgpd_addr *); 575 int prefix_update(struct rib *, struct rde_peer *, 576 struct filterstate *, struct bgpd_addr *, int, u_int8_t); 577 int prefix_withdraw(struct rib *, struct rde_peer *, 578 struct bgpd_addr *, int); 579 void prefix_add_eor(struct rde_peer *, u_int8_t); 580 int prefix_adjout_update(struct rde_peer *, struct filterstate *, 581 struct bgpd_addr *, int, u_int8_t); 582 int prefix_adjout_withdraw(struct rde_peer *, struct bgpd_addr *, 583 int); 584 void prefix_adjout_destroy(struct prefix *p); 585 void prefix_adjout_dump(struct rde_peer *, void *, 586 void (*)(struct prefix *, void *)); 587 int prefix_dump_new(struct rde_peer *, u_int8_t, unsigned int, 588 void *, void (*)(struct prefix *, void *), 589 void (*)(void *, u_int8_t), int (*)(void *)); 590 int prefix_write(u_char *, int, struct bgpd_addr *, u_int8_t, int); 591 int prefix_writebuf(struct ibuf *, struct bgpd_addr *, u_int8_t); 592 struct prefix *prefix_bypeer(struct rib_entry *, struct rde_peer *); 593 void prefix_destroy(struct prefix *); 594 void prefix_relink(struct prefix *, struct rde_aspath *, int); 595 596 RB_PROTOTYPE(prefix_tree, prefix, entry, prefix_cmp) 597 598 static inline struct rde_peer * 599 prefix_peer(struct prefix *p) 600 { 601 return (p->peer); 602 } 603 604 static inline struct rde_aspath * 605 prefix_aspath(struct prefix *p) 606 { 607 return (p->aspath); 608 } 609 610 static inline struct rde_community * 611 prefix_communities(struct prefix *p) 612 { 613 return (p->communities); 614 } 615 616 static inline struct nexthop * 617 prefix_nexthop(struct prefix *p) 618 { 619 return (p->nexthop); 620 } 621 622 static inline u_int8_t 623 prefix_nhflags(struct prefix *p) 624 { 625 return (p->nhflags); 626 } 627 628 static inline u_int8_t 629 prefix_vstate(struct prefix *p) 630 { 631 return (p->validation_state & ROA_MASK); 632 } 633 634 void nexthop_init(u_int32_t); 635 void nexthop_shutdown(void); 636 int nexthop_pending(void); 637 void nexthop_runner(void); 638 void nexthop_modify(struct nexthop *, enum action_types, u_int8_t, 639 struct nexthop **, u_int8_t *); 640 void nexthop_link(struct prefix *); 641 void nexthop_unlink(struct prefix *); 642 void nexthop_update(struct kroute_nexthop *); 643 struct nexthop *nexthop_get(struct bgpd_addr *); 644 struct nexthop *nexthop_ref(struct nexthop *); 645 int nexthop_unref(struct nexthop *); 646 int nexthop_compare(struct nexthop *, struct nexthop *); 647 648 /* rde_update.c */ 649 void up_init(struct rde_peer *); 650 void up_generate_updates(struct filter_head *, struct rde_peer *, 651 struct prefix *, struct prefix *); 652 void up_generate_default(struct filter_head *, struct rde_peer *, 653 u_int8_t); 654 int up_is_eor(struct rde_peer *, u_int8_t); 655 int up_dump_withdraws(u_char *, int, struct rde_peer *, u_int8_t); 656 int up_dump_mp_unreach(u_char *, int, struct rde_peer *, u_int8_t); 657 int up_dump_attrnlri(u_char *, int, struct rde_peer *); 658 int up_dump_mp_reach(u_char *, int, struct rde_peer *, u_int8_t); 659 660 #endif /* __RDE_H__ */ 661