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