1c398230bSWarner Losh /*- 2fe267a55SPedro F. Giffuni * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3fe267a55SPedro F. Giffuni * 48e96e13eSMaxim Sobolev * Copyright (c) 1998 The NetBSD Foundation, Inc. 5f325335cSAndrey V. Elsukov * Copyright (c) 2014 Andrey V. Elsukov <ae@FreeBSD.org> 68e96e13eSMaxim Sobolev * All rights reserved 78e96e13eSMaxim Sobolev * 88e96e13eSMaxim Sobolev * This code is derived from software contributed to The NetBSD Foundation 98e96e13eSMaxim Sobolev * by Heiko W.Rupp <hwr@pilhuhn.de> 108e96e13eSMaxim Sobolev * 118e96e13eSMaxim Sobolev * Redistribution and use in source and binary forms, with or without 128e96e13eSMaxim Sobolev * modification, are permitted provided that the following conditions 138e96e13eSMaxim Sobolev * are met: 148e96e13eSMaxim Sobolev * 1. Redistributions of source code must retain the above copyright 158e96e13eSMaxim Sobolev * notice, this list of conditions and the following disclaimer. 168e96e13eSMaxim Sobolev * 2. Redistributions in binary form must reproduce the above copyright 178e96e13eSMaxim Sobolev * notice, this list of conditions and the following disclaimer in the 188e96e13eSMaxim Sobolev * documentation and/or other materials provided with the distribution. 198e96e13eSMaxim Sobolev * 208e96e13eSMaxim Sobolev * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 218e96e13eSMaxim Sobolev * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 228e96e13eSMaxim Sobolev * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 238e96e13eSMaxim Sobolev * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 248e96e13eSMaxim Sobolev * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 258e96e13eSMaxim Sobolev * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 268e96e13eSMaxim Sobolev * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 278e96e13eSMaxim Sobolev * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 288e96e13eSMaxim Sobolev * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 298e96e13eSMaxim Sobolev * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 308e96e13eSMaxim Sobolev * POSSIBILITY OF SUCH DAMAGE. 31f325335cSAndrey V. Elsukov * 32f325335cSAndrey V. Elsukov * $NetBSD: if_gre.h,v 1.13 2003/11/10 08:51:52 wiz Exp $ 33f325335cSAndrey V. Elsukov * $FreeBSD$ 348e96e13eSMaxim Sobolev */ 358e96e13eSMaxim Sobolev 36f325335cSAndrey V. Elsukov #ifndef _NET_IF_GRE_H_ 37f325335cSAndrey V. Elsukov #define _NET_IF_GRE_H_ 388e96e13eSMaxim Sobolev 39ccd6d236SMaxim Sobolev #ifdef _KERNEL 40f325335cSAndrey V. Elsukov /* GRE header according to RFC 2784 and RFC 2890 */ 41f325335cSAndrey V. Elsukov struct grehdr { 42f325335cSAndrey V. Elsukov uint16_t gre_flags; /* GRE flags */ 43f325335cSAndrey V. Elsukov #define GRE_FLAGS_CP 0x8000 /* checksum present */ 44f325335cSAndrey V. Elsukov #define GRE_FLAGS_KP 0x2000 /* key present */ 45f325335cSAndrey V. Elsukov #define GRE_FLAGS_SP 0x1000 /* sequence present */ 46f325335cSAndrey V. Elsukov #define GRE_FLAGS_MASK (GRE_FLAGS_CP|GRE_FLAGS_KP|GRE_FLAGS_SP) 47f325335cSAndrey V. Elsukov uint16_t gre_proto; /* protocol type */ 48f325335cSAndrey V. Elsukov uint32_t gre_opts[0]; /* optional fields */ 49f325335cSAndrey V. Elsukov } __packed; 508e96e13eSMaxim Sobolev 51f325335cSAndrey V. Elsukov #ifdef INET 52f325335cSAndrey V. Elsukov struct greip { 53f325335cSAndrey V. Elsukov struct ip gi_ip; 54f325335cSAndrey V. Elsukov struct grehdr gi_gre; 55f325335cSAndrey V. Elsukov } __packed; 56*aee793eeSAndrey V. Elsukov 57*aee793eeSAndrey V. Elsukov struct greudp { 58*aee793eeSAndrey V. Elsukov struct ip gi_ip; 59*aee793eeSAndrey V. Elsukov struct udphdr gi_udp; 60*aee793eeSAndrey V. Elsukov struct grehdr gi_gre; 61*aee793eeSAndrey V. Elsukov } __packed; 62*aee793eeSAndrey V. Elsukov #endif /* INET */ 63f325335cSAndrey V. Elsukov 64f325335cSAndrey V. Elsukov #ifdef INET6 65f325335cSAndrey V. Elsukov struct greip6 { 66f325335cSAndrey V. Elsukov struct ip6_hdr gi6_ip6; 67f325335cSAndrey V. Elsukov struct grehdr gi6_gre; 68f325335cSAndrey V. Elsukov } __packed; 69*aee793eeSAndrey V. Elsukov 70*aee793eeSAndrey V. Elsukov struct greudp6 { 71*aee793eeSAndrey V. Elsukov struct ip6_hdr gi6_ip6; 72*aee793eeSAndrey V. Elsukov struct udphdr gi6_udp; 73*aee793eeSAndrey V. Elsukov struct grehdr gi6_gre; 74*aee793eeSAndrey V. Elsukov } __packed; 75*aee793eeSAndrey V. Elsukov #endif /* INET6 */ 76*aee793eeSAndrey V. Elsukov 77*aee793eeSAndrey V. Elsukov CK_LIST_HEAD(gre_list, gre_softc); 78*aee793eeSAndrey V. Elsukov CK_LIST_HEAD(gre_sockets, gre_socket); 79*aee793eeSAndrey V. Elsukov struct gre_socket { 80*aee793eeSAndrey V. Elsukov struct socket *so; 81*aee793eeSAndrey V. Elsukov struct gre_list list; 82*aee793eeSAndrey V. Elsukov CK_LIST_ENTRY(gre_socket) chain; 83*aee793eeSAndrey V. Elsukov struct epoch_context epoch_ctx; 84*aee793eeSAndrey V. Elsukov }; 857735aeb9SMaxim Sobolev 868e96e13eSMaxim Sobolev struct gre_softc { 87f325335cSAndrey V. Elsukov struct ifnet *gre_ifp; 88f325335cSAndrey V. Elsukov int gre_family; /* AF of delivery header */ 89f325335cSAndrey V. Elsukov uint32_t gre_iseq; 90f325335cSAndrey V. Elsukov uint32_t gre_oseq; 91f325335cSAndrey V. Elsukov uint32_t gre_key; 92f325335cSAndrey V. Elsukov uint32_t gre_options; 93*aee793eeSAndrey V. Elsukov uint32_t gre_csumflags; 94*aee793eeSAndrey V. Elsukov uint32_t gre_port; 95f325335cSAndrey V. Elsukov u_int gre_fibnum; 96f325335cSAndrey V. Elsukov u_int gre_hlen; /* header size */ 97f325335cSAndrey V. Elsukov union { 98f325335cSAndrey V. Elsukov void *hdr; 99f325335cSAndrey V. Elsukov #ifdef INET 100*aee793eeSAndrey V. Elsukov struct greip *iphdr; 101*aee793eeSAndrey V. Elsukov struct greudp *udphdr; 102f325335cSAndrey V. Elsukov #endif 103f325335cSAndrey V. Elsukov #ifdef INET6 104*aee793eeSAndrey V. Elsukov struct greip6 *ip6hdr; 105*aee793eeSAndrey V. Elsukov struct greudp6 *udp6hdr; 106f325335cSAndrey V. Elsukov #endif 107f325335cSAndrey V. Elsukov } gre_uhdr; 108*aee793eeSAndrey V. Elsukov struct gre_socket *gre_so; 109a5185adeSAndrey V. Elsukov 110a5185adeSAndrey V. Elsukov CK_LIST_ENTRY(gre_softc) chain; 11119873f47SAndrey V. Elsukov CK_LIST_ENTRY(gre_softc) srchash; 1128e96e13eSMaxim Sobolev }; 113a5185adeSAndrey V. Elsukov MALLOC_DECLARE(M_GRE); 114a5185adeSAndrey V. Elsukov 115a5185adeSAndrey V. Elsukov #ifndef GRE_HASH_SIZE 116a5185adeSAndrey V. Elsukov #define GRE_HASH_SIZE (1 << 4) 117a5185adeSAndrey V. Elsukov #endif 118a5185adeSAndrey V. Elsukov 119f325335cSAndrey V. Elsukov #define GRE2IFP(sc) ((sc)->gre_ifp) 12019873f47SAndrey V. Elsukov #define GRE_RLOCK_TRACKER struct epoch_tracker gre_et 12119873f47SAndrey V. Elsukov #define GRE_RLOCK() epoch_enter_preempt(net_epoch_preempt, &gre_et) 1226573d758SMatt Macy #define GRE_RUNLOCK() epoch_exit_preempt(net_epoch_preempt, &gre_et) 123a5185adeSAndrey V. Elsukov #define GRE_WAIT() epoch_wait_preempt(net_epoch_preempt) 1248e96e13eSMaxim Sobolev 125f325335cSAndrey V. Elsukov #define gre_hdr gre_uhdr.hdr 126*aee793eeSAndrey V. Elsukov #define gre_iphdr gre_uhdr.iphdr 127*aee793eeSAndrey V. Elsukov #define gre_ip6hdr gre_uhdr.ip6hdr 128*aee793eeSAndrey V. Elsukov #define gre_udphdr gre_uhdr.udphdr 129*aee793eeSAndrey V. Elsukov #define gre_udp6hdr gre_uhdr.udp6hdr 130*aee793eeSAndrey V. Elsukov 131*aee793eeSAndrey V. Elsukov #define gre_oip gre_iphdr->gi_ip 132*aee793eeSAndrey V. Elsukov #define gre_udp gre_udphdr->gi_udp 133*aee793eeSAndrey V. Elsukov #define gre_oip6 gre_ip6hdr->gi6_ip6 134*aee793eeSAndrey V. Elsukov #define gre_udp6 gre_udp6hdr->gi6_udp 1358e96e13eSMaxim Sobolev 136a5185adeSAndrey V. Elsukov struct gre_list *gre_hashinit(void); 137a5185adeSAndrey V. Elsukov void gre_hashdestroy(struct gre_list *); 138a5185adeSAndrey V. Elsukov 1396d8fdfa9SAndrey V. Elsukov int gre_input(struct mbuf *, int, int, void *); 140*aee793eeSAndrey V. Elsukov void gre_update_hdr(struct gre_softc *, struct grehdr *); 141*aee793eeSAndrey V. Elsukov void gre_update_udphdr(struct gre_softc *, struct udphdr *, uint16_t); 142*aee793eeSAndrey V. Elsukov void gre_sofree(epoch_context_t); 143a5185adeSAndrey V. Elsukov 144a5185adeSAndrey V. Elsukov void in_gre_init(void); 145a5185adeSAndrey V. Elsukov void in_gre_uninit(void); 146*aee793eeSAndrey V. Elsukov int in_gre_setopts(struct gre_softc *, u_long, uint32_t); 147a5185adeSAndrey V. Elsukov int in_gre_ioctl(struct gre_softc *, u_long, caddr_t); 148f188f14dSAndrey V. Elsukov int in_gre_output(struct mbuf *, int, int); 149a5185adeSAndrey V. Elsukov 150a5185adeSAndrey V. Elsukov void in6_gre_init(void); 151a5185adeSAndrey V. Elsukov void in6_gre_uninit(void); 152*aee793eeSAndrey V. Elsukov int in6_gre_setopts(struct gre_softc *, u_long, uint32_t); 153a5185adeSAndrey V. Elsukov int in6_gre_ioctl(struct gre_softc *, u_long, caddr_t); 154*aee793eeSAndrey V. Elsukov int in6_gre_output(struct mbuf *, int, int, uint32_t); 1558e96e13eSMaxim Sobolev /* 15616199bf2SMaxim Sobolev * CISCO uses special type for GRE tunnel created as part of WCCP 15716199bf2SMaxim Sobolev * connection, while in fact those packets are just IPv4 encapsulated 15816199bf2SMaxim Sobolev * into GRE. 15916199bf2SMaxim Sobolev */ 160f325335cSAndrey V. Elsukov #define ETHERTYPE_WCCP 0x883E 161ccd6d236SMaxim Sobolev #endif /* _KERNEL */ 162ccd6d236SMaxim Sobolev 1638e96e13eSMaxim Sobolev #define GRESADDRS _IOW('i', 101, struct ifreq) 1648e96e13eSMaxim Sobolev #define GRESADDRD _IOW('i', 102, struct ifreq) 1658e96e13eSMaxim Sobolev #define GREGADDRS _IOWR('i', 103, struct ifreq) 1668e96e13eSMaxim Sobolev #define GREGADDRD _IOWR('i', 104, struct ifreq) 1678e96e13eSMaxim Sobolev #define GRESPROTO _IOW('i' , 105, struct ifreq) 1688e96e13eSMaxim Sobolev #define GREGPROTO _IOWR('i', 106, struct ifreq) 169f325335cSAndrey V. Elsukov 170131c55bcSAndrew Thompson #define GREGKEY _IOWR('i', 107, struct ifreq) 171131c55bcSAndrew Thompson #define GRESKEY _IOW('i', 108, struct ifreq) 172f325335cSAndrey V. Elsukov #define GREGOPTS _IOWR('i', 109, struct ifreq) 173f325335cSAndrey V. Elsukov #define GRESOPTS _IOW('i', 110, struct ifreq) 174*aee793eeSAndrey V. Elsukov #define GREGPORT _IOWR('i', 111, struct ifreq) 175*aee793eeSAndrey V. Elsukov #define GRESPORT _IOW('i', 112, struct ifreq) 176*aee793eeSAndrey V. Elsukov 177*aee793eeSAndrey V. Elsukov /* GRE-in-UDP encapsulation destination port as defined in RFC8086 */ 178*aee793eeSAndrey V. Elsukov #define GRE_UDPPORT 4754 1798e96e13eSMaxim Sobolev 180f325335cSAndrey V. Elsukov #define GRE_ENABLE_CSUM 0x0001 181f325335cSAndrey V. Elsukov #define GRE_ENABLE_SEQ 0x0002 182*aee793eeSAndrey V. Elsukov #define GRE_UDPENCAP 0x0004 183*aee793eeSAndrey V. Elsukov #define GRE_OPTMASK (GRE_ENABLE_CSUM|GRE_ENABLE_SEQ|GRE_UDPENCAP) 18489c58b73SHiroki Sato 185f325335cSAndrey V. Elsukov #endif /* _NET_IF_GRE_H_ */ 186