xref: /openbsd/usr.sbin/eigrpd/eigrpd.h (revision f8d44979)
1 /*	$OpenBSD: eigrpd.h,v 1.27 2021/11/03 13:48:46 deraadt 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 struct seq_addr_entry {
232 	TAILQ_ENTRY(seq_addr_entry) entry;
233 	int			 af;
234 	union eigrpd_addr	 addr;
235 };
236 TAILQ_HEAD(seq_addr_head, seq_addr_entry);
237 
238 #define	REDIST_STATIC		0x01
239 #define	REDIST_RIP		0x02
240 #define	REDIST_OSPF		0x04
241 #define	REDIST_CONNECTED	0x08
242 #define	REDIST_DEFAULT		0x10
243 #define	REDIST_ADDR		0x20
244 #define	REDIST_NO		0x40
245 
246 struct redist_metric {
247 	uint32_t		 bandwidth;
248 	uint32_t		 delay;
249 	uint8_t			 reliability;
250 	uint8_t			 load;
251 	uint16_t		 mtu;
252 };
253 
254 struct redistribute {
255 	SIMPLEQ_ENTRY(redistribute) entry;
256 	uint8_t			 type;
257 	int			 af;
258 	union eigrpd_addr	 addr;
259 	uint8_t			 prefixlen;
260 	struct redist_metric	*metric;
261 	struct {
262 		uint32_t	 as;
263 		uint32_t	 metric;
264 		uint32_t	 tag;
265 	} emetric;
266 };
267 SIMPLEQ_HEAD(redist_list, redistribute);
268 
269 struct eigrp_stats {
270 	uint32_t		 hellos_sent;
271 	uint32_t		 hellos_recv;
272 	uint32_t		 updates_sent;
273 	uint32_t		 updates_recv;
274 	uint32_t		 queries_sent;
275 	uint32_t		 queries_recv;
276 	uint32_t		 replies_sent;
277 	uint32_t		 replies_recv;
278 	uint32_t		 acks_sent;
279 	uint32_t		 acks_recv;
280 	uint32_t		 squeries_sent;
281 	uint32_t		 squeries_recv;
282 	uint32_t		 sreplies_sent;
283 	uint32_t		 sreplies_recv;
284 };
285 
286 /* eigrp instance */
287 struct eigrp {
288 	TAILQ_ENTRY(eigrp)	 entry;
289 	int			 af;
290 	uint16_t		 as;
291 	uint8_t			 kvalues[6];
292 	uint16_t		 active_timeout;
293 	uint8_t			 maximum_hops;
294 	uint8_t			 maximum_paths;
295 	uint8_t			 variance;
296 	struct redist_metric	*dflt_metric;
297 	struct redist_list	 redist_list;
298 	TAILQ_HEAD(, eigrp_iface) ei_list;
299 	struct nbr_addr_head	 nbrs;
300 	struct rde_nbr		*rnbr_redist;
301 	struct rde_nbr		*rnbr_summary;
302 	struct rt_tree		 topology;
303 	uint32_t		 seq_num;
304 	struct eigrp_stats	 stats;
305 };
306 
307 /* eigrp_conf */
308 enum eigrpd_process {
309 	PROC_MAIN,
310 	PROC_EIGRP_ENGINE,
311 	PROC_RDE_ENGINE
312 };
313 
314 struct eigrpd_conf {
315 	struct in_addr		 rtr_id;
316 	unsigned int		 rdomain;
317 	uint8_t			 fib_priority_internal;
318 	uint8_t			 fib_priority_external;
319 	uint8_t			 fib_priority_summary;
320 	TAILQ_HEAD(, iface)	 iface_list;
321 	TAILQ_HEAD(, eigrp)	 instances;
322 	int			 flags;
323 #define	EIGRPD_FLAG_NO_FIB_UPDATE 0x0001
324 };
325 
326 struct eigrpd_global {
327 	int			 cmd_opts;
328 	time_t			 uptime;
329 	int			 eigrp_socket_v4;
330 	int			 eigrp_socket_v6;
331 	struct in_addr		 mcast_addr_v4;
332 	struct in6_addr		 mcast_addr_v6;
333 };
334 
335 extern struct eigrpd_global global;
336 
337 /* kroute */
338 struct kroute {
339 	int			 af;
340 	union eigrpd_addr	 prefix;
341 	uint8_t			 prefixlen;
342 	union eigrpd_addr	 nexthop;
343 	unsigned short		 ifindex;
344 	uint8_t			 priority;
345 	uint16_t		 flags;
346 };
347 
348 struct kaddr {
349 	unsigned short		 ifindex;
350 	int			 af;
351 	union eigrpd_addr	 addr;
352 	uint8_t			 prefixlen;
353 	union eigrpd_addr	 dstbrd;
354 };
355 
356 struct kif {
357 	char			 ifname[IF_NAMESIZE];
358 	unsigned short		 ifindex;
359 	int			 flags;
360 	uint8_t			 link_state;
361 	int			 mtu;
362 	unsigned int		 rdomain;
363 	uint8_t			 if_type;
364 	uint64_t		 baudrate;
365 	uint8_t			 nh_reachable;	/* for nexthop verification */
366 };
367 
368 /* control data structures */
369 struct ctl_iface {
370 	int			 af;
371 	uint16_t		 as;
372 	char			 name[IF_NAMESIZE];
373 	unsigned int		 ifindex;
374 	union eigrpd_addr	 addr;
375 	uint8_t			 prefixlen;
376 	uint16_t		 flags;
377 	uint8_t			 linkstate;
378 	int			 mtu;
379 	enum iface_type		 type;
380 	uint8_t			 if_type;
381 	uint64_t		 baudrate;
382 	uint32_t		 delay;
383 	uint32_t		 bandwidth;
384 	uint16_t		 hello_holdtime;
385 	uint16_t		 hello_interval;
386 	uint8_t			 splithorizon;
387 	uint8_t			 passive;
388 	time_t			 uptime;
389 	int			 nbr_cnt;
390 };
391 
392 struct ctl_nbr {
393 	int			 af;
394 	uint16_t		 as;
395 	char			 ifname[IF_NAMESIZE];
396 	union eigrpd_addr	 addr;
397 	uint16_t		 hello_holdtime;
398 	time_t			 uptime;
399 };
400 
401 struct ctl_rt {
402 	int			 af;
403 	uint16_t		 as;
404 	union eigrpd_addr	 prefix;
405 	uint8_t			 prefixlen;
406 	enum route_type		 type;
407 	union eigrpd_addr	 nexthop;
408 	char			 ifname[IF_NAMESIZE];
409 	uint32_t		 distance;
410 	uint32_t		 rdistance;
411 	uint32_t		 fdistance;
412 	int			 state;
413 	uint8_t			 flags;
414 	struct {
415 		uint32_t	 delay;
416 		uint32_t	 bandwidth;
417 		uint32_t	 mtu;
418 		uint8_t		 hop_count;
419 		uint8_t		 reliability;
420 		uint8_t		 load;
421 	} metric;
422 	struct classic_emetric	 emetric;
423 };
424 #define	F_CTL_RT_FIRST		0x01
425 #define	F_CTL_RT_SUCCESSOR	0x02
426 #define	F_CTL_RT_FSUCCESSOR	0x04
427 
428 struct ctl_show_topology_req {
429 	int			 af;
430 	union eigrpd_addr	 prefix;
431 	uint8_t			 prefixlen;
432 	uint16_t		 flags;
433 };
434 
435 struct ctl_stats {
436 	int			 af;
437 	uint16_t		 as;
438 	struct eigrp_stats	 stats;
439 };
440 
441 #define min(x,y) ((x) <= (y) ? (x) : (y))
442 #define max(x,y) ((x) > (y) ? (x) : (y))
443 
444 extern struct eigrpd_conf	*eigrpd_conf;
445 extern struct iface_id_head	 ifaces_by_id;
446 
447 /* parse.y */
448 struct eigrpd_conf	*parse_config(char *);
449 int			 cmdline_symset(char *);
450 
451 /* in_cksum.c */
452 uint16_t	 in_cksum(void *, size_t);
453 
454 /* kroute.c */
455 int		 kif_init(void);
456 int		 kr_init(int, unsigned int);
457 void		 kif_redistribute(void);
458 int		 kr_change(struct kroute *);
459 int		 kr_delete(struct kroute *);
460 void		 kr_shutdown(void);
461 void		 kr_fib_couple(void);
462 void		 kr_fib_decouple(void);
463 void		 kr_show_route(struct imsg *);
464 void		 kr_ifinfo(char *, pid_t);
465 struct kif	*kif_findname(char *);
466 void		 kif_clear(void);
467 
468 /* util.c */
469 uint8_t		 mask2prefixlen(in_addr_t);
470 uint8_t		 mask2prefixlen6(struct sockaddr_in6 *);
471 in_addr_t	 prefixlen2mask(uint8_t);
472 struct in6_addr	*prefixlen2mask6(uint8_t);
473 void		 eigrp_applymask(int, union eigrpd_addr *,
474 		    const union eigrpd_addr *, int);
475 int		 eigrp_addrcmp(int, const union eigrpd_addr *,
476 		    const union eigrpd_addr *);
477 int		 eigrp_addrisset(int, const union eigrpd_addr *);
478 int		 eigrp_prefixcmp(int, const union eigrpd_addr *,
479 		    const union eigrpd_addr *, uint8_t);
480 int		 bad_addr_v4(struct in_addr);
481 int		 bad_addr_v6(struct in6_addr *);
482 int		 bad_addr(int, union eigrpd_addr *);
483 void		 embedscope(struct sockaddr_in6 *);
484 void		 recoverscope(struct sockaddr_in6 *);
485 void		 addscope(struct sockaddr_in6 *, uint32_t);
486 void		 clearscope(struct in6_addr *);
487 void		 sa2addr(struct sockaddr *, int *, union eigrpd_addr *);
488 
489 /* eigrpd.c */
490 int		 main_imsg_compose_eigrpe(int, pid_t, void *, uint16_t);
491 int		 main_imsg_compose_rde(int, pid_t, void *, uint16_t);
492 void		 imsg_event_add(struct imsgev *);
493 int		 imsg_compose_event(struct imsgev *, uint16_t, uint32_t,
494 		    pid_t, int, void *, uint16_t);
495 struct eigrp	*eigrp_find(struct eigrpd_conf *, int, uint16_t);
496 void		 merge_config(struct eigrpd_conf *, struct eigrpd_conf *,
497 		    enum eigrpd_process);
498 struct eigrpd_conf *config_new_empty(void);
499 void		 config_clear(struct eigrpd_conf *, enum eigrpd_process);
500 
501 /* printconf.c */
502 void		 print_config(struct eigrpd_conf *);
503 
504 /* logmsg.c */
505 const char	*log_in6addr(const struct in6_addr *);
506 const char	*log_in6addr_scope(const struct in6_addr *, unsigned int);
507 const char	*log_sockaddr(void *);
508 const char	*log_addr(int, union eigrpd_addr *);
509 const char	*log_prefix(struct rt_node *);
510 const char	*log_route_origin(int, struct rde_nbr *);
511 const char	*opcode_name(uint8_t);
512 const char	*af_name(int);
513 const char	*if_type_name(enum iface_type);
514 const char	*dual_state_name(int);
515 const char	*ext_proto_name(int);
516 
517 #endif	/* _EIGRPD_H_ */
518