xref: /freebsd/sys/netinet/ip_carp.h (revision d9e7dd4a19b81a78a801973f8f5231f46a6d20b8)
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  * CARP authentication length in 32-bit chunks:
85  * counter[2] (8 bytes) + SHA1 HMAC (20 bytes) = 28 bytes = 7 chunks.
86  */
87 #define	CARP_AUTHLEN	7
88 
89 /*
90  * The VRRPv3 header layout is as follows:
91  * See RFC9568, 5.1.  VRRP Packet Format
92  *
93  *   0                   1                   2                   3
94  *   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
95  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
96  *  |Version| Type  | Virtual Rtr ID|   Priority    |Count IPvX Addr|
97  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
98  *  |(rsvd) |     Max Adver Int     |          Checksum             |
99  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
100  *  |                                                               |
101  *  +                                                               +
102  *  |                       IPvX Address(es)                        |
103  *  +                                                               +
104  *  +                                                               +
105  *  +                                                               +
106  *  +                                                               +
107  *  |                                                               |
108  *  +                                                               +
109  *  |                                                               |
110  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
111  *
112  */
113 
114 struct vrrpv3_header {
115 #if BYTE_ORDER == LITTLE_ENDIAN
116 	uint8_t		vrrp_type:4,
117 			vrrp_version:4;
118 #endif
119 #if BYTE_ORDER == BIG_ENDIAN
120 	uint8_t		vrrp_version:4,
121 			vrrp_type:4;
122 #endif
123 	uint8_t		vrrp_vrtid;
124 	uint8_t		vrrp_priority;
125 	uint8_t		vrrp_count_addr;
126 	uint16_t	vrrp_max_adver_int;
127 	uint16_t	vrrp_checksum;
128 } __packed;
129 
130 CTASSERT(sizeof(struct vrrpv3_header) == 8);
131 #endif /* _KERNEL */
132 
133 #define	CARP_DFLTTL		255
134 
135 /* carp_type */
136 #define	CARP_ADVERTISEMENT	0x01
137 
138 #define	CARP_KEY_LEN		20	/* a sha1 hash of a passphrase */
139 
140 /* carp_advbase */
141 #define	CARP_DFLTINTV		1
142 
143 #define	VRRP_TYPE_ADVERTISEMENT	0x01
144 #define	VRRP_MAX_INTERVAL	(0x1000 - 1)
145 /*
146  * Statistics.
147  */
148 struct carpstats {
149 	uint64_t	carps_ipackets;		/* total input packets, IPv4 */
150 	uint64_t	carps_ipackets6;	/* total input packets, IPv6 */
151 	uint64_t	carps_badif;		/* wrong interface */
152 	uint64_t	carps_badttl;		/* TTL is not CARP_DFLTTL */
153 	uint64_t	carps_hdrops;		/* packets shorter than hdr */
154 	uint64_t	carps_badsum;		/* bad checksum */
155 	uint64_t	carps_badver;		/* bad (incl unsupp) version */
156 	uint64_t	carps_badlen;		/* data length does not match */
157 	uint64_t	carps_badauth;		/* bad authentication */
158 	uint64_t	carps_badvhid;		/* bad VHID */
159 	uint64_t	carps_badaddrs;		/* bad address list */
160 
161 	uint64_t	carps_opackets;		/* total output packets, IPv4 */
162 	uint64_t	carps_opackets6;	/* total output packets, IPv6 */
163 	uint64_t	carps_onomem;		/* no memory for an mbuf */
164 	uint64_t	carps_ostates;		/* total state updates sent */
165 
166 	uint64_t	carps_preempt;		/* if enabled, preemptions */
167 };
168 
169 #define	CARP_MAXVHID	255
170 #define	CARP_STATES	"INIT", "BACKUP", "MASTER"
171 #define	CARP_MAXSTATE	2
172 #define	CARP_MAXSKEW	240
173 
174 typedef enum carp_version {
175 	CARP_VERSION_CARP	= 2,
176 	CARP_VERSION_VRRPv3	= 3,
177 } carp_version_t;
178 
179 #ifdef _KERNEL
180 int		carp_attach(struct ifaddr *, int);
181 void		carp_detach(struct ifaddr *, bool);
182 void		carp_carpdev_state(struct ifnet *);
183 int		carp_output (struct ifnet *, struct mbuf *,
184 		    const struct sockaddr *);
185 int		carp_master(struct ifaddr *);
186 int		carp_iamatch(struct ifaddr *, uint8_t **);
187 struct ifaddr	*carp_iamatch6(struct ifnet *, struct in6_addr *);
188 char *		carp_macmatch6(struct ifnet *, struct mbuf *, const struct in6_addr *);
189 int		carp_forus(struct ifnet *, u_char *);
190 
191 /* These are external networking stack hooks for CARP */
192 /* net/if.c */
193 extern int (*carp_attach_p)(struct ifaddr *, int);
194 extern void (*carp_detach_p)(struct ifaddr *, bool);
195 extern void (*carp_linkstate_p)(struct ifnet *);
196 extern void (*carp_demote_adj_p)(int, char *);
197 extern int (*carp_master_p)(struct ifaddr *);
198 /* net/if_bridge.c net/if_ethersubr.c */
199 extern int (*carp_forus_p)(struct ifnet *, u_char *);
200 /* net/if_ethersubr.c */
201 extern int (*carp_output_p)(struct ifnet *, struct mbuf *,
202     const struct sockaddr *);
203 /* net/rtsock.c */
204 extern int (*carp_get_vhid_p)(struct ifaddr *);
205 #ifdef INET
206 /* netinet/if_ether.c */
207 extern int (*carp_iamatch_p)(struct ifaddr *, uint8_t **);
208 #endif
209 #ifdef INET6
210 /* netinet6/nd6_nbr.c */
211 extern struct ifaddr *(*carp_iamatch6_p)(struct ifnet *, struct in6_addr *);
212 extern char * (*carp_macmatch6_p)(struct ifnet *, struct mbuf *,
213     const struct in6_addr *);
214 #endif
215 #endif
216 #endif /* _IP_CARP_H */
217