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 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 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