xref: /openbsd/sys/netinet/ip_carp.h (revision 3d877566)
1 /*	$OpenBSD: ip_carp.h,v 1.51 2021/03/07 06:02:32 dlg Exp $	*/
2 
3 /*
4  * Copyright (c) 2002 Michael Shalayeff. All rights reserved.
5  * Copyright (c) 2003 Ryan McBride. All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
20  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22  * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
25  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26  * THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #ifndef _NETINET_IP_CARP_H_
30 #define _NETINET_IP_CARP_H_
31 
32 /*
33  * The CARP header layout is as follows:
34  *
35  *     0                   1                   2                   3
36  *     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
37  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
38  *    |Version| Type  | VirtualHostID |    AdvSkew    |    Auth Len   |
39  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
40  *    |    Demotion   |     AdvBase   |          Checksum             |
41  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
42  *    |                         Counter (1)                           |
43  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
44  *    |                         Counter (2)                           |
45  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
46  *    |                        SHA-1 HMAC (1)                         |
47  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
48  *    |                        SHA-1 HMAC (2)                         |
49  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
50  *    |                        SHA-1 HMAC (3)                         |
51  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
52  *    |                        SHA-1 HMAC (4)                         |
53  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
54  *    |                        SHA-1 HMAC (5)                         |
55  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
56  *
57  */
58 
59 struct carp_header {
60 #if _BYTE_ORDER == _LITTLE_ENDIAN
61 	u_int		carp_type:4,
62 			carp_version:4;
63 #endif
64 #if _BYTE_ORDER == _BIG_ENDIAN
65 	u_int		carp_version:4,
66 			carp_type:4;
67 #endif
68 	u_int8_t	carp_vhid;	/* virtual host id */
69 	u_int8_t	carp_advskew;	/* advertisement skew */
70 	u_int8_t	carp_authlen;   /* size of counter+md, 32bit chunks */
71 	u_int8_t	carp_demote;	/* demotion indicator */
72 	u_int8_t	carp_advbase;	/* advertisement interval */
73 	u_int16_t	carp_cksum;
74 	u_int32_t	carp_counter[2];
75 	unsigned char	carp_md[20];	/* SHA1 HMAC */
76 } __packed;
77 
78 #define	CARP_DFLTTL		255
79 
80 /* carp_version */
81 #define	CARP_VERSION		2
82 
83 /* carp_type */
84 #define	CARP_ADVERTISEMENT	0x01
85 
86 #define	CARP_KEY_LEN		20	/* a sha1 hash of a passphrase */
87 
88 /* carp_advbase */
89 #define	CARP_DFLTINTV		1
90 
91 /*
92  * Statistics.
93  */
94 struct carpstats {
95 	u_int64_t	carps_ipackets;		/* total input packets, IPv4 */
96 	u_int64_t	carps_ipackets6;	/* total input packets, IPv6 */
97 	u_int64_t	carps_badif;		/* wrong interface */
98 	u_int64_t	carps_badttl;		/* TTL is not CARP_DFLTTL */
99 	u_int64_t	carps_hdrops;		/* packets shorter than hdr */
100 	u_int64_t	carps_badsum;		/* bad checksum */
101 	u_int64_t	carps_badver;		/* bad (incl unsupp) version */
102 	u_int64_t	carps_badlen;		/* data length does not match */
103 	u_int64_t	carps_badauth;		/* bad authentication */
104 	u_int64_t	carps_badvhid;		/* bad VHID */
105 	u_int64_t	carps_badaddrs;		/* bad address list */
106 
107 	u_int64_t	carps_opackets;		/* total output packets, IPv4 */
108 	u_int64_t	carps_opackets6;	/* total output packets, IPv6 */
109 	u_int64_t	carps_onomem;		/* no memory for an mbuf */
110 	u_int64_t	carps_ostates;		/* total state updates sent */
111 
112 	u_int64_t	carps_preempt;		/* transitions to master */
113 };
114 
115 #define CARPDEVNAMSIZ	16
116 #ifdef IFNAMSIZ
117 #if CARPDEVNAMSIZ != IFNAMSIZ
118 #error namsiz mismatch
119 #endif
120 #endif
121 
122 /*
123  * Configuration structure for SIOCSVH SIOCGVH
124  */
125 struct carpreq {
126 	int		carpr_state;
127 #define	CARP_STATES	"INIT", "BACKUP", "MASTER"
128 #define	CARP_MAXSTATE	2
129 #define	CARP_MAXNODES	32
130 
131 	char		carpr_carpdev[CARPDEVNAMSIZ];
132 	u_int8_t	carpr_vhids[CARP_MAXNODES];
133 	u_int8_t	carpr_advskews[CARP_MAXNODES];
134 	u_int8_t	carpr_states[CARP_MAXNODES];
135 #define	CARP_BAL_MODES	"none", "ip", "ip-stealth", "ip-unicast"
136 #define CARP_BAL_NONE		0
137 #define CARP_BAL_IP		1
138 #define CARP_BAL_IPSTEALTH	2
139 #define CARP_BAL_IPUNICAST	3
140 #define CARP_BAL_MAXID		3
141 	u_int8_t	carpr_balancing;
142 	int		carpr_advbase;
143 	unsigned char	carpr_key[CARP_KEY_LEN];
144 	struct in_addr	carpr_peer;
145 };
146 
147 /*
148  * Names for CARP sysctl objects
149  */
150 #define	CARPCTL_ALLOW		1	/* accept incoming CARP packets */
151 #define	CARPCTL_PREEMPT		2	/* high-pri backup preemption mode */
152 #define	CARPCTL_LOG		3	/* log bad packets */
153 #define	CARPCTL_STATS		4	/* CARP stats */
154 #define	CARPCTL_MAXID		5
155 
156 #define	CARPCTL_NAMES { \
157 	{ 0, 0 }, \
158 	{ "allow", CTLTYPE_INT }, \
159 	{ "preempt", CTLTYPE_INT }, \
160 	{ "log", CTLTYPE_INT }, \
161 	{ "stats", CTLTYPE_STRUCT }, \
162 }
163 
164 #ifdef _KERNEL
165 
166 #include <net/if_types.h>
167 #include <sys/percpu.h>
168 
169 enum carpstat_counters {
170 	carps_ipackets,
171 	carps_ipackets6,
172 	carps_badif,
173 	carps_badttl,
174 	carps_hdrops,
175 	carps_badsum,
176 	carps_badver,
177 	carps_badlen,
178 	carps_badauth,
179 	carps_badvhid,
180 	carps_badaddrs,
181 	carps_opackets,
182 	carps_opackets6,
183 	carps_onomem,
184 	carps_ostates,
185 	carps_preempt,
186 	carps_ncounters,
187 };
188 
189 extern struct cpumem *carpcounters;
190 
191 static inline void
carpstat_inc(enum carpstat_counters c)192 carpstat_inc(enum carpstat_counters c)
193 {
194 	counters_inc(carpcounters, c);
195 }
196 
197 /*
198  * If two carp interfaces share same physical interface, then we pretend all IP
199  * addresses belong to single interface.
200  */
201 static inline int
carp_strict_addr_chk(struct ifnet * ifp_a,struct ifnet * ifp_b)202 carp_strict_addr_chk(struct ifnet *ifp_a, struct ifnet *ifp_b)
203 {
204 	return ((ifp_a->if_type == IFT_CARP &&
205 	    ifp_b->if_index == ifp_a->if_carpdevidx) ||
206 	    (ifp_b->if_type == IFT_CARP &&
207 	    ifp_a->if_index == ifp_b->if_carpdevidx) ||
208 	    (ifp_a->if_type == IFT_CARP && ifp_b->if_type == IFT_CARP &&
209 	    ifp_a->if_carpdevidx == ifp_b->if_carpdevidx));
210 }
211 
212 struct mbuf	*carp_input(struct ifnet *, struct mbuf *, uint64_t);
213 
214 int		 carp_proto_input(struct mbuf **, int *, int, int);
215 void		 carp_carpdev_state(void *);
216 void		 carp_group_demote_adj(struct ifnet *, int, char *);
217 int		 carp6_proto_input(struct mbuf **, int *, int, int);
218 int		 carp_iamatch(struct ifnet *);
219 int		 carp_ourether(struct ifnet *, u_int8_t *);
220 int		 carp_output(struct ifnet *, struct mbuf *, struct sockaddr *,
221 		     struct rtentry *);
222 int		 carp_sysctl(int *, u_int,  void *, size_t *, void *, size_t);
223 int		 carp_lsdrop(struct ifnet *, struct mbuf *, sa_family_t,
224 		    u_int32_t *, u_int32_t *, int);
225 #endif /* _KERNEL */
226 #endif /* _NETINET_IP_CARP_H_ */
227