xref: /freebsd/sys/netinet/ip_carp.h (revision 5b56413d04e608379c9a306373554a8e4d321bc0)
1 /*	$OpenBSD: ip_carp.h,v 1.8 2004/07/29 22:12:15 mcbride Exp $	*/
2 
3 /*-
4  * SPDX-License-Identifier: BSD-2-Clause
5  *
6  * Copyright (c) 2002 Michael Shalayeff. All rights reserved.
7  * Copyright (c) 2003 Ryan McBride. All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
22  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24  * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
27  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28  * THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #ifndef _IP_CARP_H
32 #define	_IP_CARP_H
33 
34 #ifdef _KERNEL
35 /*
36  * The CARP header layout is as follows:
37  *
38  *     0                   1                   2                   3
39  *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
40  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
41  *    |Version| Type  | VirtualHostID |    AdvSkew    |    Auth Len   |
42  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
43  *    |   Reserved    |     AdvBase   |          Checksum             |
44  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
45  *    |                         Counter (1)                           |
46  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
47  *    |                         Counter (2)                           |
48  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
49  *    |                        SHA-1 HMAC (1)                         |
50  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
51  *    |                        SHA-1 HMAC (2)                         |
52  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
53  *    |                        SHA-1 HMAC (3)                         |
54  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
55  *    |                        SHA-1 HMAC (4)                         |
56  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57  *    |                        SHA-1 HMAC (5)                         |
58  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59  *
60  */
61 
62 struct carp_header {
63 #if BYTE_ORDER == LITTLE_ENDIAN
64 	u_int8_t	carp_type:4,
65 			carp_version:4;
66 #endif
67 #if BYTE_ORDER == BIG_ENDIAN
68 	u_int8_t	carp_version:4,
69 			carp_type:4;
70 #endif
71 	u_int8_t	carp_vhid;	/* virtual host id */
72 	u_int8_t	carp_advskew;	/* advertisement skew */
73 	u_int8_t	carp_authlen;   /* size of counter+md, 32bit chunks */
74 	u_int8_t	carp_pad1;	/* reserved */
75 	u_int8_t	carp_advbase;	/* advertisement interval */
76 	u_int16_t	carp_cksum;
77 	u_int32_t	carp_counter[2];
78 	unsigned char	carp_md[20];	/* SHA1 HMAC */
79 } __packed;
80 
81 CTASSERT(sizeof(struct carp_header) == 36);
82 
83 /*
84  * The VRRPv3 header layout is as follows:
85  * See RFC9568, 5.1.  VRRP Packet Format
86  *
87  *   0                   1                   2                   3
88  *   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
89  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
90  *  |Version| Type  | Virtual Rtr ID|   Priority    |Count IPvX Addr|
91  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
92  *  |(rsvd) |     Max Adver Int     |          Checksum             |
93  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
94  *  |                                                               |
95  *  +                                                               +
96  *  |                       IPvX Address(es)                        |
97  *  +                                                               +
98  *  +                                                               +
99  *  +                                                               +
100  *  +                                                               +
101  *  |                                                               |
102  *  +                                                               +
103  *  |                                                               |
104  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
105  *
106  */
107 
108 struct vrrpv3_header {
109 #if BYTE_ORDER == LITTLE_ENDIAN
110 	uint8_t		vrrp_type:4,
111 			vrrp_version:4;
112 #endif
113 #if BYTE_ORDER == BIG_ENDIAN
114 	uint8_t		vrrp_version:4,
115 			vrrp_type:4;
116 #endif
117 	uint8_t		vrrp_vrtid;
118 	uint8_t		vrrp_priority;
119 	uint8_t		vrrp_count_addr;
120 	uint16_t	vrrp_max_adver_int;
121 	uint16_t	vrrp_checksum;
122 } __packed;
123 
124 CTASSERT(sizeof(struct vrrpv3_header) == 8);
125 #endif /* _KERNEL */
126 
127 #define	CARP_DFLTTL		255
128 
129 /* carp_type */
130 #define	CARP_ADVERTISEMENT	0x01
131 
132 #define	CARP_KEY_LEN		20	/* a sha1 hash of a passphrase */
133 
134 /* carp_advbase */
135 #define	CARP_DFLTINTV		1
136 
137 #define	VRRP_TYPE_ADVERTISEMENT	0x01
138 #define	VRRP_MAX_INTERVAL	(0x1000 - 1)
139 /*
140  * Statistics.
141  */
142 struct carpstats {
143 	uint64_t	carps_ipackets;		/* total input packets, IPv4 */
144 	uint64_t	carps_ipackets6;	/* total input packets, IPv6 */
145 	uint64_t	carps_badif;		/* wrong interface */
146 	uint64_t	carps_badttl;		/* TTL is not CARP_DFLTTL */
147 	uint64_t	carps_hdrops;		/* packets shorter than hdr */
148 	uint64_t	carps_badsum;		/* bad checksum */
149 	uint64_t	carps_badver;		/* bad (incl unsupp) version */
150 	uint64_t	carps_badlen;		/* data length does not match */
151 	uint64_t	carps_badauth;		/* bad authentication */
152 	uint64_t	carps_badvhid;		/* bad VHID */
153 	uint64_t	carps_badaddrs;		/* bad address list */
154 
155 	uint64_t	carps_opackets;		/* total output packets, IPv4 */
156 	uint64_t	carps_opackets6;	/* total output packets, IPv6 */
157 	uint64_t	carps_onomem;		/* no memory for an mbuf */
158 	uint64_t	carps_ostates;		/* total state updates sent */
159 
160 	uint64_t	carps_preempt;		/* if enabled, preemptions */
161 };
162 
163 /*
164  * Configuration structure for SIOCSVH SIOCGVH
165  */
166 struct carpreq {
167 	int		carpr_count;
168 	int		carpr_vhid;
169 #define	CARP_MAXVHID	255
170 	int		carpr_state;
171 #define	CARP_STATES	"INIT", "BACKUP", "MASTER"
172 #define	CARP_MAXSTATE	2
173 	int		carpr_advskew;
174 #define	CARP_MAXSKEW	240
175 	int		carpr_advbase;
176 	unsigned char	carpr_key[CARP_KEY_LEN];
177 };
178 #define	SIOCSVH	_IOWR('i', 245, struct ifreq)
179 #define	SIOCGVH	_IOWR('i', 246, struct ifreq)
180 
181 typedef enum carp_version {
182 	CARP_VERSION_CARP	= 2,
183 	CARP_VERSION_VRRPv3	= 3,
184 } carp_version_t;
185 
186 #ifdef _KERNEL
187 int		carp_ioctl(struct ifreq *, u_long, struct thread *);
188 int		carp_attach(struct ifaddr *, int);
189 void		carp_detach(struct ifaddr *, bool);
190 void		carp_carpdev_state(struct ifnet *);
191 int		carp_output (struct ifnet *, struct mbuf *,
192 		    const struct sockaddr *);
193 int		carp_master(struct ifaddr *);
194 int		carp_iamatch(struct ifaddr *, uint8_t **);
195 struct ifaddr	*carp_iamatch6(struct ifnet *, struct in6_addr *);
196 char *		carp_macmatch6(struct ifnet *, struct mbuf *, const struct in6_addr *);
197 int		carp_forus(struct ifnet *, u_char *);
198 
199 /* These are external networking stack hooks for CARP */
200 /* net/if.c */
201 extern int (*carp_ioctl_p)(struct ifreq *, u_long, struct thread *);
202 extern int (*carp_attach_p)(struct ifaddr *, int);
203 extern void (*carp_detach_p)(struct ifaddr *, bool);
204 extern void (*carp_linkstate_p)(struct ifnet *);
205 extern void (*carp_demote_adj_p)(int, char *);
206 extern int (*carp_master_p)(struct ifaddr *);
207 /* net/if_bridge.c net/if_ethersubr.c */
208 extern int (*carp_forus_p)(struct ifnet *, u_char *);
209 /* net/if_ethersubr.c */
210 extern int (*carp_output_p)(struct ifnet *, struct mbuf *,
211     const struct sockaddr *);
212 /* net/rtsock.c */
213 extern int (*carp_get_vhid_p)(struct ifaddr *);
214 #ifdef INET
215 /* netinet/if_ether.c */
216 extern int (*carp_iamatch_p)(struct ifaddr *, uint8_t **);
217 #endif
218 #ifdef INET6
219 /* netinet6/nd6_nbr.c */
220 extern struct ifaddr *(*carp_iamatch6_p)(struct ifnet *, struct in6_addr *);
221 extern char * (*carp_macmatch6_p)(struct ifnet *, struct mbuf *,
222     const struct in6_addr *);
223 #endif
224 #endif
225 #endif /* _IP_CARP_H */
226