1 /* $OpenBSD: rde.h,v 1.149 2015/11/06 16:23:26 phessler 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 26 #include "bgpd.h" 27 28 /* rde internal structures */ 29 30 enum peer_state { 31 PEER_NONE, 32 PEER_DOWN, 33 PEER_UP, 34 PEER_ERR /* error occurred going to PEER_DOWN state */ 35 }; 36 37 /* 38 * How do we identify peers between the session handler and the rde? 39 * Currently I assume that we can do that with the neighbor_ip... 40 */ 41 LIST_HEAD(rde_peer_head, rde_peer); 42 LIST_HEAD(aspath_head, rde_aspath); 43 RB_HEAD(uptree_prefix, update_prefix); 44 RB_HEAD(uptree_attr, update_attr); 45 RB_HEAD(rib_tree, rib_entry); 46 TAILQ_HEAD(uplist_prefix, update_prefix); 47 TAILQ_HEAD(uplist_attr, update_attr); 48 49 struct rde_peer { 50 LIST_ENTRY(rde_peer) hash_l; /* hash list over all peers */ 51 LIST_ENTRY(rde_peer) peer_l; /* list of all peers */ 52 struct aspath_head path_h; /* list of all as paths */ 53 struct peer_config conf; 54 struct bgpd_addr remote_addr; 55 struct bgpd_addr local_v4_addr; 56 struct bgpd_addr local_v6_addr; 57 struct uptree_prefix up_prefix; 58 struct uptree_attr up_attrs; 59 struct uplist_attr updates[AID_MAX]; 60 struct uplist_prefix withdraws[AID_MAX]; 61 struct capabilities capa; 62 time_t staletime[AID_MAX]; 63 u_int64_t prefix_rcvd_update; 64 u_int64_t prefix_rcvd_withdraw; 65 u_int64_t prefix_rcvd_eor; 66 u_int64_t prefix_sent_update; 67 u_int64_t prefix_sent_withdraw; 68 u_int64_t prefix_sent_eor; 69 u_int32_t prefix_cnt; /* # of prefixes */ 70 u_int32_t remote_bgpid; /* host byte order! */ 71 u_int32_t up_pcnt; 72 u_int32_t up_acnt; 73 u_int32_t up_nlricnt; 74 u_int32_t up_wcnt; 75 enum peer_state state; 76 u_int16_t ribid; 77 u_int16_t short_as; 78 u_int16_t mrt_idx; 79 u_int8_t reconf_out; /* out filter changed */ 80 u_int8_t reconf_rib; /* rib changed */ 81 }; 82 83 #define AS_SET 1 84 #define AS_SEQUENCE 2 85 #define AS_CONFED_SEQUENCE 3 86 #define AS_CONFED_SET 4 87 #define ASPATH_HEADER_SIZE (sizeof(struct aspath) - sizeof(u_char)) 88 89 LIST_HEAD(aspath_list, aspath); 90 91 struct aspath { 92 LIST_ENTRY(aspath) entry; 93 int refcnt; /* reference count */ 94 u_int16_t len; /* total length of aspath in octets */ 95 u_int16_t ascnt; /* number of AS hops in data */ 96 u_char data[1]; /* placeholder for actual data */ 97 }; 98 99 enum attrtypes { 100 ATTR_UNDEF, 101 ATTR_ORIGIN, 102 ATTR_ASPATH, 103 ATTR_NEXTHOP, 104 ATTR_MED, 105 ATTR_LOCALPREF, 106 ATTR_ATOMIC_AGGREGATE, 107 ATTR_AGGREGATOR, 108 ATTR_COMMUNITIES, 109 ATTR_ORIGINATOR_ID, 110 ATTR_CLUSTER_LIST, 111 ATTR_MP_REACH_NLRI=14, 112 ATTR_MP_UNREACH_NLRI=15, 113 ATTR_EXT_COMMUNITIES=16, 114 ATTR_AS4_PATH=17, 115 ATTR_AS4_AGGREGATOR=18 116 }; 117 118 /* attribute flags. 4 low order bits reserved */ 119 #define ATTR_EXTLEN 0x10 120 #define ATTR_PARTIAL 0x20 121 #define ATTR_TRANSITIVE 0x40 122 #define ATTR_OPTIONAL 0x80 123 #define ATTR_RESERVED 0x0f 124 /* by default mask the reserved bits and the ext len bit */ 125 #define ATTR_DEFMASK (ATTR_RESERVED | ATTR_EXTLEN) 126 127 /* default attribute flags for well known attributes */ 128 #define ATTR_WELL_KNOWN ATTR_TRANSITIVE 129 130 struct attr { 131 LIST_ENTRY(attr) entry; 132 u_char *data; 133 int refcnt; 134 u_int32_t hash; 135 u_int16_t len; 136 u_int8_t flags; 137 u_int8_t type; 138 }; 139 140 struct mpattr { 141 void *reach; 142 void *unreach; 143 u_int16_t reach_len; 144 u_int16_t unreach_len; 145 }; 146 147 LIST_HEAD(attr_list, attr); 148 149 struct path_table { 150 struct aspath_head *path_hashtbl; 151 u_int32_t path_hashmask; 152 }; 153 154 LIST_HEAD(prefix_head, prefix); 155 156 #define F_ATTR_ORIGIN 0x00001 157 #define F_ATTR_ASPATH 0x00002 158 #define F_ATTR_NEXTHOP 0x00004 159 #define F_ATTR_LOCALPREF 0x00008 160 #define F_ATTR_MED 0x00010 161 #define F_ATTR_MED_ANNOUNCE 0x00020 162 #define F_ATTR_MP_REACH 0x00040 163 #define F_ATTR_MP_UNREACH 0x00080 164 #define F_ATTR_AS4BYTE_NEW 0x00100 /* AS4_PATH or AS4_AGGREGATOR */ 165 #define F_ATTR_LOOP 0x00200 /* path would cause a route loop */ 166 #define F_PREFIX_ANNOUNCED 0x00400 167 #define F_ANN_DYNAMIC 0x00800 168 #define F_NEXTHOP_SELF 0x01000 169 #define F_NEXTHOP_REJECT 0x02000 170 #define F_NEXTHOP_BLACKHOLE 0x04000 171 #define F_NEXTHOP_NOMODIFY 0x08000 172 #define F_NEXTHOP_MASK 0x0f000 173 #define F_ATTR_PARSE_ERR 0x10000 174 #define F_ATTR_LINKED 0x20000 175 176 177 #define ORIGIN_IGP 0 178 #define ORIGIN_EGP 1 179 #define ORIGIN_INCOMPLETE 2 180 181 #define DEFAULT_LPREF 100 182 183 struct rde_aspath { 184 LIST_ENTRY(rde_aspath) path_l, peer_l, nexthop_l; 185 struct prefix_head prefix_h; 186 struct attr **others; 187 struct rde_peer *peer; 188 struct aspath *aspath; 189 struct nexthop *nexthop; /* may be NULL */ 190 u_int32_t med; /* multi exit disc */ 191 u_int32_t lpref; /* local pref */ 192 u_int32_t weight; /* low prio lpref */ 193 u_int32_t prefix_cnt; /* # of prefixes */ 194 u_int32_t active_cnt; /* # of active prefixes */ 195 u_int32_t flags; /* internally used */ 196 u_int16_t rtlabelid; /* route label id */ 197 u_int16_t pftableid; /* pf table id */ 198 u_int8_t origin; 199 u_int8_t others_len; 200 }; 201 202 enum nexthop_state { 203 NEXTHOP_LOOKUP, 204 NEXTHOP_UNREACH, 205 NEXTHOP_REACH 206 }; 207 208 struct nexthop { 209 LIST_ENTRY(nexthop) nexthop_l; 210 struct aspath_head path_h; 211 struct bgpd_addr exit_nexthop; 212 struct bgpd_addr true_nexthop; 213 struct bgpd_addr nexthop_net; 214 #if 0 215 /* 216 * currently we use the boolean nexthop state, this could be exchanged 217 * with a variable cost with a max for unreachable. 218 */ 219 u_int32_t costs; 220 #endif 221 int refcnt; /* filterset reference counter */ 222 enum nexthop_state state; 223 u_int8_t nexthop_netlen; 224 u_int8_t flags; 225 #define NEXTHOP_CONNECTED 0x01 226 }; 227 228 /* generic entry without address specific part */ 229 struct pt_entry { 230 RB_ENTRY(pt_entry) pt_e; 231 u_int8_t aid; 232 u_int8_t prefixlen; 233 u_int16_t refcnt; 234 }; 235 236 struct pt_entry4 { 237 RB_ENTRY(pt_entry) pt_e; 238 u_int8_t aid; 239 u_int8_t prefixlen; 240 u_int16_t refcnt; 241 struct in_addr prefix4; 242 }; 243 244 struct pt_entry6 { 245 RB_ENTRY(pt_entry) pt_e; 246 u_int8_t aid; 247 u_int8_t prefixlen; 248 u_int16_t refcnt; 249 struct in6_addr prefix6; 250 }; 251 252 struct pt_entry_vpn4 { 253 RB_ENTRY(pt_entry) pt_e; 254 u_int8_t aid; 255 u_int8_t prefixlen; 256 u_int16_t refcnt; 257 struct in_addr prefix4; 258 u_int64_t rd; 259 u_int8_t labelstack[21]; 260 u_int8_t labellen; 261 u_int8_t pad1; 262 u_int8_t pad2; 263 }; 264 265 struct rib_context { 266 LIST_ENTRY(rib_context) entry; 267 struct rib_entry *ctx_re; 268 struct rib *ctx_rib; 269 void (*ctx_upcall)(struct rib_entry *, void *); 270 void (*ctx_done)(void *); 271 void (*ctx_wait)(void *); 272 void *ctx_arg; 273 unsigned int ctx_count; 274 u_int8_t ctx_aid; 275 }; 276 277 struct rib_entry { 278 RB_ENTRY(rib_entry) rib_e; 279 struct prefix_head prefix_h; 280 struct prefix *active; /* for fast access */ 281 struct pt_entry *prefix; 282 u_int16_t ribid; 283 u_int16_t flags; 284 }; 285 286 struct rib { 287 char name[PEER_DESCR_LEN]; 288 struct rib_tree rib; 289 struct filter_head *in_rules; 290 struct filter_head *in_rules_tmp; 291 u_int rtableid; 292 u_int16_t flags; 293 u_int16_t id; 294 enum reconf_action state; 295 }; 296 297 #define RIB_FAILED 0xffff 298 299 struct prefix { 300 LIST_ENTRY(prefix) rib_l, path_l; 301 struct rde_aspath *aspath; 302 struct pt_entry *prefix; 303 struct rib_entry *rib; /* NULL for Adj-RIB-In */ 304 time_t lastchange; 305 }; 306 307 extern struct rde_memstats rdemem; 308 309 /* prototypes */ 310 /* mrt.c */ 311 int mrt_dump_v2_hdr(struct mrt *, struct bgpd_config *, 312 struct rde_peer_head *); 313 void mrt_dump_upcall(struct rib_entry *, void *); 314 void mrt_done(void *); 315 316 /* rde.c */ 317 void rde_send_kroute(struct prefix *, struct prefix *, u_int16_t); 318 void rde_send_nexthop(struct bgpd_addr *, int); 319 void rde_send_pftable(u_int16_t, struct bgpd_addr *, 320 u_int8_t, int); 321 void rde_send_pftable_commit(void); 322 323 void rde_generate_updates(u_int16_t, struct prefix *, 324 struct prefix *); 325 u_int32_t rde_local_as(void); 326 int rde_noevaluate(void); 327 int rde_decisionflags(void); 328 int rde_as4byte(struct rde_peer *); 329 330 /* rde_attr.c */ 331 int attr_write(void *, u_int16_t, u_int8_t, u_int8_t, void *, 332 u_int16_t); 333 int attr_writebuf(struct ibuf *, u_int8_t, u_int8_t, void *, 334 u_int16_t); 335 void attr_init(u_int32_t); 336 void attr_shutdown(void); 337 int attr_optadd(struct rde_aspath *, u_int8_t, u_int8_t, 338 void *, u_int16_t); 339 struct attr *attr_optget(const struct rde_aspath *, u_int8_t); 340 void attr_copy(struct rde_aspath *, struct rde_aspath *); 341 int attr_compare(struct rde_aspath *, struct rde_aspath *); 342 void attr_freeall(struct rde_aspath *); 343 void attr_free(struct rde_aspath *, struct attr *); 344 #define attr_optlen(x) \ 345 ((x)->len > 255 ? (x)->len + 4 : (x)->len + 3) 346 347 int aspath_verify(void *, u_int16_t, int); 348 #define AS_ERR_LEN -1 349 #define AS_ERR_TYPE -2 350 #define AS_ERR_BAD -3 351 #define AS_ERR_SOFT -4 352 void aspath_init(u_int32_t); 353 void aspath_shutdown(void); 354 struct aspath *aspath_get(void *, u_int16_t); 355 void aspath_put(struct aspath *); 356 u_char *aspath_inflate(void *, u_int16_t, u_int16_t *); 357 u_char *aspath_deflate(u_char *, u_int16_t *, int *); 358 void aspath_merge(struct rde_aspath *, struct attr *); 359 u_char *aspath_dump(struct aspath *); 360 u_int16_t aspath_length(struct aspath *); 361 u_int16_t aspath_count(const void *, u_int16_t); 362 u_int32_t aspath_neighbor(struct aspath *); 363 int aspath_loopfree(struct aspath *, u_int32_t); 364 int aspath_compare(struct aspath *, struct aspath *); 365 u_char *aspath_prepend(struct aspath *, u_int32_t, int, u_int16_t *); 366 int aspath_lenmatch(struct aspath *, enum aslen_spec, u_int); 367 int community_match(struct rde_aspath *, int, int); 368 int community_set(struct rde_aspath *, int, int); 369 void community_delete(struct rde_aspath *, int, int); 370 int community_ext_match(struct rde_aspath *, 371 struct filter_extcommunity *, u_int16_t); 372 int community_ext_set(struct rde_aspath *, 373 struct filter_extcommunity *, u_int16_t); 374 void community_ext_delete(struct rde_aspath *, 375 struct filter_extcommunity *, u_int16_t); 376 int community_ext_conv(struct filter_extcommunity *, u_int16_t, 377 u_int64_t *); 378 379 /* rde_decide.c */ 380 void prefix_evaluate(struct prefix *, struct rib_entry *); 381 382 /* rde_filter.c */ 383 enum filter_actions rde_filter(struct filter_head *, struct rde_aspath **, 384 struct rde_peer *, struct rde_aspath *, 385 struct bgpd_addr *, u_int8_t, struct rde_peer *); 386 void rde_apply_set(struct rde_aspath *, struct filter_set_head *, 387 u_int8_t, struct rde_peer *, struct rde_peer *); 388 int rde_filter_equal(struct filter_head *, struct filter_head *, 389 struct rde_peer *); 390 void rde_filter_calc_skip_steps(struct filter_head *); 391 392 /* rde_prefix.c */ 393 #define pt_empty(pt) ((pt)->refcnt == 0) 394 #define pt_ref(pt) do { \ 395 ++(pt)->refcnt; \ 396 if ((pt)->refcnt == 0) \ 397 fatalx("pt_ref: overflow"); \ 398 } while(0) 399 #define pt_unref(pt) do { \ 400 if ((pt)->refcnt == 0) \ 401 fatalx("pt_unref: underflow"); \ 402 --(pt)->refcnt; \ 403 } while(0) 404 405 void pt_init(void); 406 void pt_shutdown(void); 407 void pt_getaddr(struct pt_entry *, struct bgpd_addr *); 408 struct pt_entry *pt_fill(struct bgpd_addr *, int); 409 struct pt_entry *pt_get(struct bgpd_addr *, int); 410 struct pt_entry *pt_add(struct bgpd_addr *, int); 411 void pt_remove(struct pt_entry *); 412 struct pt_entry *pt_lookup(struct bgpd_addr *); 413 int pt_prefix_cmp(const struct pt_entry *, const struct pt_entry *); 414 415 /* rde_rib.c */ 416 extern u_int16_t rib_size; 417 extern struct rib *ribs; 418 419 u_int16_t rib_new(char *, u_int, u_int16_t); 420 u_int16_t rib_find(char *); 421 void rib_free(struct rib *); 422 struct rib_entry *rib_get(struct rib *, struct bgpd_addr *, int); 423 struct rib_entry *rib_lookup(struct rib *, struct bgpd_addr *); 424 void rib_dump(struct rib *, void (*)(struct rib_entry *, void *), 425 void *, u_int8_t); 426 void rib_dump_r(struct rib_context *); 427 void rib_dump_runner(void); 428 int rib_dump_pending(void); 429 430 void path_init(u_int32_t); 431 void path_shutdown(void); 432 int path_update(struct rib *, struct rde_peer *, 433 struct rde_aspath *, struct bgpd_addr *, int); 434 int path_compare(struct rde_aspath *, struct rde_aspath *); 435 struct rde_aspath *path_lookup(struct rde_aspath *, struct rde_peer *); 436 void path_remove(struct rde_aspath *); 437 u_int32_t path_remove_stale(struct rde_aspath *, u_int8_t); 438 void path_destroy(struct rde_aspath *); 439 int path_empty(struct rde_aspath *); 440 struct rde_aspath *path_copy(struct rde_aspath *); 441 struct rde_aspath *path_get(void); 442 void path_put(struct rde_aspath *); 443 444 #define PREFIX_SIZE(x) (((x) + 7) / 8 + 1) 445 struct prefix *prefix_get(struct rib *, struct rde_peer *, 446 struct bgpd_addr *, int, u_int32_t); 447 int prefix_add(struct rib *, struct rde_aspath *, 448 struct bgpd_addr *, int); 449 void prefix_move(struct rde_aspath *, struct prefix *); 450 int prefix_remove(struct rib *, struct rde_peer *, 451 struct bgpd_addr *, int, u_int32_t); 452 int prefix_write(u_char *, int, struct bgpd_addr *, u_int8_t); 453 int prefix_writebuf(struct ibuf *, struct bgpd_addr *, u_int8_t); 454 struct prefix *prefix_bypeer(struct rib_entry *, struct rde_peer *, 455 u_int32_t); 456 void prefix_updateall(struct rde_aspath *, enum nexthop_state, 457 enum nexthop_state); 458 void prefix_destroy(struct prefix *); 459 void prefix_network_clean(struct rde_peer *, time_t, u_int32_t); 460 461 void nexthop_init(u_int32_t); 462 void nexthop_shutdown(void); 463 void nexthop_modify(struct rde_aspath *, struct bgpd_addr *, 464 enum action_types, u_int8_t); 465 void nexthop_link(struct rde_aspath *); 466 void nexthop_unlink(struct rde_aspath *); 467 int nexthop_delete(struct nexthop *); 468 void nexthop_update(struct kroute_nexthop *); 469 struct nexthop *nexthop_get(struct bgpd_addr *); 470 int nexthop_compare(struct nexthop *, struct nexthop *); 471 472 /* rde_update.c */ 473 void up_init(struct rde_peer *); 474 void up_down(struct rde_peer *); 475 int up_test_update(struct rde_peer *, struct prefix *); 476 int up_generate(struct rde_peer *, struct rde_aspath *, 477 struct bgpd_addr *, u_int8_t); 478 void up_generate_updates(struct filter_head *, struct rde_peer *, 479 struct prefix *, struct prefix *); 480 void up_generate_default(struct filter_head *, struct rde_peer *, 481 u_int8_t); 482 int up_generate_marker(struct rde_peer *, u_int8_t); 483 int up_dump_prefix(u_char *, int, struct uplist_prefix *, 484 struct rde_peer *); 485 int up_dump_attrnlri(u_char *, int, struct rde_peer *); 486 u_char *up_dump_mp_unreach(u_char *, u_int16_t *, struct rde_peer *, 487 u_int8_t); 488 int up_dump_mp_reach(u_char *, u_int16_t *, struct rde_peer *, 489 u_int8_t); 490 491 #endif /* __RDE_H__ */ 492