1 /* $OpenBSD: eigrpd.h,v 1.26 2021/01/19 10:53:25 claudio Exp $ */ 2 3 /* 4 * Copyright (c) 2015 Renato Westphal <renato@openbsd.org> 5 * Copyright (c) 2004 Esben Norby <norby@openbsd.org> 6 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> 7 * 8 * Permission to use, copy, modify, and distribute this software for any 9 * purpose with or without fee is hereby granted, provided that the above 10 * copyright notice and this permission notice appear in all copies. 11 * 12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19 */ 20 21 #ifndef _EIGRPD_H_ 22 #define _EIGRPD_H_ 23 24 #include <sys/queue.h> 25 #include <sys/tree.h> 26 #include <sys/socket.h> 27 #include <net/if.h> 28 #include <netinet/in.h> 29 30 #include <event.h> 31 #include <imsg.h> 32 33 #include "eigrp.h" 34 35 #define CONF_FILE "/etc/eigrpd.conf" 36 #define EIGRPD_SOCKET "/var/run/eigrpd.sock" 37 #define EIGRPD_USER "_eigrpd" 38 39 #define EIGRPD_OPT_VERBOSE 0x00000001 40 #define EIGRPD_OPT_VERBOSE2 0x00000002 41 #define EIGRPD_OPT_NOACTION 0x00000004 42 43 #define NBR_IDSELF 1 44 #define NBR_CNTSTART (NBR_IDSELF + 1) 45 46 #define READ_BUF_SIZE 65535 47 #define PKG_DEF_SIZE 512 /* compromise */ 48 #define RT_BUF_SIZE 16384 49 #define MAX_RTSOCK_BUF (2 * 1024 * 1024) 50 51 #define F_EIGRPD_INSERTED 0x0001 52 #define F_KERNEL 0x0002 53 #define F_CONNECTED 0x0004 54 #define F_STATIC 0x0008 55 #define F_DYNAMIC 0x0010 56 #define F_DOWN 0x0020 57 #define F_REJECT 0x0040 58 #define F_BLACKHOLE 0x0080 59 #define F_REDISTRIBUTED 0x0100 60 #define F_CTL_EXTERNAL 0x0200 /* only used by eigrpctl */ 61 #define F_CTL_ACTIVE 0x0400 62 #define F_CTL_ALLLINKS 0x0800 63 64 struct imsgev { 65 struct imsgbuf ibuf; 66 void (*handler)(int, short, void *); 67 struct event ev; 68 short events; 69 }; 70 71 enum imsg_type { 72 IMSG_CTL_RELOAD, 73 IMSG_CTL_SHOW_INTERFACE, 74 IMSG_CTL_SHOW_NBR, 75 IMSG_CTL_SHOW_TOPOLOGY, 76 IMSG_CTL_SHOW_STATS, 77 IMSG_CTL_CLEAR_NBR, 78 IMSG_CTL_FIB_COUPLE, 79 IMSG_CTL_FIB_DECOUPLE, 80 IMSG_CTL_IFACE, 81 IMSG_CTL_KROUTE, 82 IMSG_CTL_IFINFO, 83 IMSG_CTL_END, 84 IMSG_CTL_LOG_VERBOSE, 85 IMSG_KROUTE_CHANGE, 86 IMSG_KROUTE_DELETE, 87 IMSG_NONE, 88 IMSG_IFINFO, 89 IMSG_IFDOWN, 90 IMSG_NEWADDR, 91 IMSG_DELADDR, 92 IMSG_NETWORK_ADD, 93 IMSG_NETWORK_DEL, 94 IMSG_NEIGHBOR_UP, 95 IMSG_NEIGHBOR_DOWN, 96 IMSG_RECV_UPDATE_INIT, 97 IMSG_RECV_UPDATE, 98 IMSG_RECV_QUERY, 99 IMSG_RECV_REPLY, 100 IMSG_RECV_SIAQUERY, 101 IMSG_RECV_SIAREPLY, 102 IMSG_SEND_UPDATE, 103 IMSG_SEND_QUERY, 104 IMSG_SEND_REPLY, 105 IMSG_SEND_MUPDATE, 106 IMSG_SEND_MQUERY, 107 IMSG_SEND_UPDATE_END, 108 IMSG_SEND_REPLY_END, 109 IMSG_SEND_SIAQUERY_END, 110 IMSG_SEND_SIAREPLY_END, 111 IMSG_SEND_MUPDATE_END, 112 IMSG_SEND_MQUERY_END, 113 IMSG_SOCKET_IPC, 114 IMSG_RECONF_CONF, 115 IMSG_RECONF_IFACE, 116 IMSG_RECONF_INSTANCE, 117 IMSG_RECONF_EIGRP_IFACE, 118 IMSG_RECONF_END 119 }; 120 121 /* forward declarations */ 122 struct eigrp_iface; 123 RB_HEAD(iface_id_head, eigrp_iface); 124 struct nbr; 125 RB_HEAD(nbr_addr_head, nbr); 126 RB_HEAD(nbr_pid_head, nbr); 127 struct rde_nbr; 128 RB_HEAD(rde_nbr_head, rde_nbr); 129 struct rt_node; 130 RB_HEAD(rt_tree, rt_node); 131 132 union eigrpd_addr { 133 struct in_addr v4; 134 struct in6_addr v6; 135 }; 136 137 #define IN6_IS_SCOPE_EMBED(a) \ 138 ((IN6_IS_ADDR_LINKLOCAL(a)) || \ 139 (IN6_IS_ADDR_MC_LINKLOCAL(a)) || \ 140 (IN6_IS_ADDR_MC_INTFACELOCAL(a))) 141 142 /* interface types */ 143 enum iface_type { 144 IF_TYPE_POINTOPOINT, 145 IF_TYPE_BROADCAST 146 }; 147 148 struct if_addr { 149 TAILQ_ENTRY(if_addr) entry; 150 int af; 151 union eigrpd_addr addr; 152 uint8_t prefixlen; 153 union eigrpd_addr dstbrd; 154 }; 155 TAILQ_HEAD(if_addr_head, if_addr); 156 157 struct iface { 158 TAILQ_ENTRY(iface) entry; 159 TAILQ_HEAD(, eigrp_iface) ei_list; 160 unsigned int ifindex; 161 unsigned int rdomain; 162 char name[IF_NAMESIZE]; 163 struct if_addr_head addr_list; 164 struct in6_addr linklocal; 165 int mtu; 166 enum iface_type type; 167 uint8_t if_type; 168 uint64_t baudrate; 169 uint16_t flags; 170 uint8_t linkstate; 171 uint8_t group_count_v4; 172 uint8_t group_count_v6; 173 }; 174 175 enum route_type { 176 EIGRP_ROUTE_INTERNAL, 177 EIGRP_ROUTE_EXTERNAL 178 }; 179 180 /* routing information advertised by update/query/reply messages */ 181 struct rinfo { 182 int af; 183 enum route_type type; 184 union eigrpd_addr prefix; 185 uint8_t prefixlen; 186 union eigrpd_addr nexthop; 187 struct classic_metric metric; 188 struct classic_emetric emetric; 189 }; 190 191 struct rinfo_entry { 192 TAILQ_ENTRY(rinfo_entry) entry; 193 struct rinfo rinfo; 194 }; 195 TAILQ_HEAD(rinfo_head, rinfo_entry); 196 197 /* interface states */ 198 #define IF_STA_DOWN 0x01 199 #define IF_STA_ACTIVE 0x02 200 201 struct summary_addr { 202 TAILQ_ENTRY(summary_addr) entry; 203 union eigrpd_addr prefix; 204 uint8_t prefixlen; 205 }; 206 207 struct eigrp_iface { 208 RB_ENTRY(eigrp_iface) id_tree; 209 TAILQ_ENTRY(eigrp_iface) e_entry; 210 TAILQ_ENTRY(eigrp_iface) i_entry; 211 struct eigrp *eigrp; 212 struct iface *iface; 213 int state; 214 uint32_t ifaceid; 215 struct event hello_timer; 216 uint32_t delay; 217 uint32_t bandwidth; 218 uint16_t hello_holdtime; 219 uint16_t hello_interval; 220 uint8_t splithorizon; 221 uint8_t passive; 222 time_t uptime; 223 TAILQ_HEAD(, nbr) nbr_list; 224 struct nbr *self; 225 struct rinfo_head update_list; /* multicast updates */ 226 struct rinfo_head query_list; /* multicast queries */ 227 TAILQ_HEAD(, summary_addr) summary_list; 228 }; 229 RB_PROTOTYPE(iface_id_head, eigrp_iface, id_tree, iface_id_compare) 230 231 #define INADDRSZ 4 232 #define IN6ADDRSZ 16 233 234 struct seq_addr_entry { 235 TAILQ_ENTRY(seq_addr_entry) entry; 236 int af; 237 union eigrpd_addr addr; 238 }; 239 TAILQ_HEAD(seq_addr_head, seq_addr_entry); 240 241 #define REDIST_STATIC 0x01 242 #define REDIST_RIP 0x02 243 #define REDIST_OSPF 0x04 244 #define REDIST_CONNECTED 0x08 245 #define REDIST_DEFAULT 0x10 246 #define REDIST_ADDR 0x20 247 #define REDIST_NO 0x40 248 249 struct redist_metric { 250 uint32_t bandwidth; 251 uint32_t delay; 252 uint8_t reliability; 253 uint8_t load; 254 uint16_t mtu; 255 }; 256 257 struct redistribute { 258 SIMPLEQ_ENTRY(redistribute) entry; 259 uint8_t type; 260 int af; 261 union eigrpd_addr addr; 262 uint8_t prefixlen; 263 struct redist_metric *metric; 264 struct { 265 uint32_t as; 266 uint32_t metric; 267 uint32_t tag; 268 } emetric; 269 }; 270 SIMPLEQ_HEAD(redist_list, redistribute); 271 272 struct eigrp_stats { 273 uint32_t hellos_sent; 274 uint32_t hellos_recv; 275 uint32_t updates_sent; 276 uint32_t updates_recv; 277 uint32_t queries_sent; 278 uint32_t queries_recv; 279 uint32_t replies_sent; 280 uint32_t replies_recv; 281 uint32_t acks_sent; 282 uint32_t acks_recv; 283 uint32_t squeries_sent; 284 uint32_t squeries_recv; 285 uint32_t sreplies_sent; 286 uint32_t sreplies_recv; 287 }; 288 289 /* eigrp instance */ 290 struct eigrp { 291 TAILQ_ENTRY(eigrp) entry; 292 int af; 293 uint16_t as; 294 uint8_t kvalues[6]; 295 uint16_t active_timeout; 296 uint8_t maximum_hops; 297 uint8_t maximum_paths; 298 uint8_t variance; 299 struct redist_metric *dflt_metric; 300 struct redist_list redist_list; 301 TAILQ_HEAD(, eigrp_iface) ei_list; 302 struct nbr_addr_head nbrs; 303 struct rde_nbr *rnbr_redist; 304 struct rde_nbr *rnbr_summary; 305 struct rt_tree topology; 306 uint32_t seq_num; 307 struct eigrp_stats stats; 308 }; 309 310 /* eigrp_conf */ 311 enum eigrpd_process { 312 PROC_MAIN, 313 PROC_EIGRP_ENGINE, 314 PROC_RDE_ENGINE 315 }; 316 317 struct eigrpd_conf { 318 struct in_addr rtr_id; 319 unsigned int rdomain; 320 uint8_t fib_priority_internal; 321 uint8_t fib_priority_external; 322 uint8_t fib_priority_summary; 323 TAILQ_HEAD(, iface) iface_list; 324 TAILQ_HEAD(, eigrp) instances; 325 int flags; 326 #define EIGRPD_FLAG_NO_FIB_UPDATE 0x0001 327 }; 328 329 struct eigrpd_global { 330 int cmd_opts; 331 time_t uptime; 332 int eigrp_socket_v4; 333 int eigrp_socket_v6; 334 struct in_addr mcast_addr_v4; 335 struct in6_addr mcast_addr_v6; 336 }; 337 338 extern struct eigrpd_global global; 339 340 /* kroute */ 341 struct kroute { 342 int af; 343 union eigrpd_addr prefix; 344 uint8_t prefixlen; 345 union eigrpd_addr nexthop; 346 unsigned short ifindex; 347 uint8_t priority; 348 uint16_t flags; 349 }; 350 351 struct kaddr { 352 unsigned short ifindex; 353 int af; 354 union eigrpd_addr addr; 355 uint8_t prefixlen; 356 union eigrpd_addr dstbrd; 357 }; 358 359 struct kif { 360 char ifname[IF_NAMESIZE]; 361 unsigned short ifindex; 362 int flags; 363 uint8_t link_state; 364 int mtu; 365 unsigned int rdomain; 366 uint8_t if_type; 367 uint64_t baudrate; 368 uint8_t nh_reachable; /* for nexthop verification */ 369 }; 370 371 /* control data structures */ 372 struct ctl_iface { 373 int af; 374 uint16_t as; 375 char name[IF_NAMESIZE]; 376 unsigned int ifindex; 377 union eigrpd_addr addr; 378 uint8_t prefixlen; 379 uint16_t flags; 380 uint8_t linkstate; 381 int mtu; 382 enum iface_type type; 383 uint8_t if_type; 384 uint64_t baudrate; 385 uint32_t delay; 386 uint32_t bandwidth; 387 uint16_t hello_holdtime; 388 uint16_t hello_interval; 389 uint8_t splithorizon; 390 uint8_t passive; 391 time_t uptime; 392 int nbr_cnt; 393 }; 394 395 struct ctl_nbr { 396 int af; 397 uint16_t as; 398 char ifname[IF_NAMESIZE]; 399 union eigrpd_addr addr; 400 uint16_t hello_holdtime; 401 time_t uptime; 402 }; 403 404 struct ctl_rt { 405 int af; 406 uint16_t as; 407 union eigrpd_addr prefix; 408 uint8_t prefixlen; 409 enum route_type type; 410 union eigrpd_addr nexthop; 411 char ifname[IF_NAMESIZE]; 412 uint32_t distance; 413 uint32_t rdistance; 414 uint32_t fdistance; 415 int state; 416 uint8_t flags; 417 struct { 418 uint32_t delay; 419 uint32_t bandwidth; 420 uint32_t mtu; 421 uint8_t hop_count; 422 uint8_t reliability; 423 uint8_t load; 424 } metric; 425 struct classic_emetric emetric; 426 }; 427 #define F_CTL_RT_FIRST 0x01 428 #define F_CTL_RT_SUCCESSOR 0x02 429 #define F_CTL_RT_FSUCCESSOR 0x04 430 431 struct ctl_show_topology_req { 432 int af; 433 union eigrpd_addr prefix; 434 uint8_t prefixlen; 435 uint16_t flags; 436 }; 437 438 struct ctl_stats { 439 int af; 440 uint16_t as; 441 struct eigrp_stats stats; 442 }; 443 444 #define min(x,y) ((x) <= (y) ? (x) : (y)) 445 #define max(x,y) ((x) > (y) ? (x) : (y)) 446 447 extern struct eigrpd_conf *eigrpd_conf; 448 extern struct iface_id_head ifaces_by_id; 449 450 /* parse.y */ 451 struct eigrpd_conf *parse_config(char *); 452 int cmdline_symset(char *); 453 454 /* in_cksum.c */ 455 uint16_t in_cksum(void *, size_t); 456 457 /* kroute.c */ 458 int kif_init(void); 459 int kr_init(int, unsigned int); 460 void kif_redistribute(void); 461 int kr_change(struct kroute *); 462 int kr_delete(struct kroute *); 463 void kr_shutdown(void); 464 void kr_fib_couple(void); 465 void kr_fib_decouple(void); 466 void kr_show_route(struct imsg *); 467 void kr_ifinfo(char *, pid_t); 468 struct kif *kif_findname(char *); 469 void kif_clear(void); 470 471 /* util.c */ 472 uint8_t mask2prefixlen(in_addr_t); 473 uint8_t mask2prefixlen6(struct sockaddr_in6 *); 474 in_addr_t prefixlen2mask(uint8_t); 475 struct in6_addr *prefixlen2mask6(uint8_t); 476 void eigrp_applymask(int, union eigrpd_addr *, 477 const union eigrpd_addr *, int); 478 int eigrp_addrcmp(int, const union eigrpd_addr *, 479 const union eigrpd_addr *); 480 int eigrp_addrisset(int, const union eigrpd_addr *); 481 int eigrp_prefixcmp(int, const union eigrpd_addr *, 482 const union eigrpd_addr *, uint8_t); 483 int bad_addr_v4(struct in_addr); 484 int bad_addr_v6(struct in6_addr *); 485 int bad_addr(int, union eigrpd_addr *); 486 void embedscope(struct sockaddr_in6 *); 487 void recoverscope(struct sockaddr_in6 *); 488 void addscope(struct sockaddr_in6 *, uint32_t); 489 void clearscope(struct in6_addr *); 490 void sa2addr(struct sockaddr *, int *, union eigrpd_addr *); 491 492 /* eigrpd.c */ 493 int main_imsg_compose_eigrpe(int, pid_t, void *, uint16_t); 494 int main_imsg_compose_rde(int, pid_t, void *, uint16_t); 495 void imsg_event_add(struct imsgev *); 496 int imsg_compose_event(struct imsgev *, uint16_t, uint32_t, 497 pid_t, int, void *, uint16_t); 498 struct eigrp *eigrp_find(struct eigrpd_conf *, int, uint16_t); 499 void merge_config(struct eigrpd_conf *, struct eigrpd_conf *, 500 enum eigrpd_process); 501 struct eigrpd_conf *config_new_empty(void); 502 void config_clear(struct eigrpd_conf *, enum eigrpd_process); 503 504 /* printconf.c */ 505 void print_config(struct eigrpd_conf *); 506 507 /* logmsg.c */ 508 const char *log_in6addr(const struct in6_addr *); 509 const char *log_in6addr_scope(const struct in6_addr *, unsigned int); 510 const char *log_sockaddr(void *); 511 const char *log_addr(int, union eigrpd_addr *); 512 const char *log_prefix(struct rt_node *); 513 const char *log_route_origin(int, struct rde_nbr *); 514 const char *opcode_name(uint8_t); 515 const char *af_name(int); 516 const char *if_type_name(enum iface_type); 517 const char *dual_state_name(int); 518 const char *ext_proto_name(int); 519 520 #endif /* _EIGRPD_H_ */ 521