xref: /openbsd/usr.sbin/eigrpd/eigrpd.h (revision ac61aa8a)
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