1/* 2 * OpenVPN -- An application to securely tunnel IP networks 3 * over a single TCP/UDP port, with support for SSL/TLS-based 4 * session authentication and key exchange, 5 * packet encryption, packet authentication, and 6 * packet compression. 7 * 8 * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 12 * as published by the Free Software Foundation. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program (see the file COPYING included with this 21 * distribution); if not, write to the Free Software Foundation, Inc., 22 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 */ 24 25#ifndef MTU_H 26#define MTU_H 27 28#include "buffer.h" 29 30/* 31 * 32 * Packet maninipulation routes such as encrypt, decrypt, compress, decompress 33 * are passed a frame buffer that looks like this: 34 * 35 * [extra_frame bytes] [mtu bytes] [extra_frame_bytes] [compression overflow bytes] 36 * ^ 37 * Pointer passed to function points here so that routine 38 * can make use of extra_frame bytes before pointer 39 * to prepend headers, etc. 40 * 41 * extra_frame bytes is large enough for all encryption related overhead. 42 * 43 * mtu bytes will be the MTU size set in the ifconfig statement that configures 44 * the TUN or TAP device such as: 45 * 46 * ifconfig $1 10.1.0.2 pointopoint 10.1.0.1 mtu 1450 47 * 48 * Compression overflow bytes is the worst-case size expansion that would be 49 * expected if we tried to compress mtu + extra_frame bytes of uncompressible data. 50 */ 51 52/* 53 * Standard ethernet MTU 54 */ 55#define ETHERNET_MTU 1500 56 57/* 58 * It is a fatal error if mtu is less than 59 * this value for tun device. 60 */ 61#define TUN_MTU_MIN 100 62 63/* 64 * Default MTU of network over which tunnel data will pass by TCP/UDP. 65 */ 66#define LINK_MTU_DEFAULT 1500 67 68/* 69 * Default MTU of tunnel device. 70 */ 71#define TUN_MTU_DEFAULT 1500 72 73/* 74 * MTU Defaults for TAP devices 75 */ 76#define TAP_MTU_EXTRA_DEFAULT 32 77 78/* 79 * Default MSSFIX value, used for reducing TCP MTU size 80 */ 81#define MSSFIX_DEFAULT 1450 82 83/* 84 * Alignment of payload data such as IP packet or 85 * ethernet frame. 86 */ 87#define PAYLOAD_ALIGN 4 88 89 90/**************************************************************************/ 91/** 92 * Packet geometry parameters. 93 */ 94struct frame { 95 int link_mtu; /**< Maximum packet size to be sent over 96 * the external network interface. */ 97 98 int link_mtu_dynamic; /**< Dynamic MTU value for the external 99 * network interface. */ 100 101 int extra_frame; /**< Maximum number of bytes that all 102 * processing steps together could add. 103 * @code 104 * frame.link_mtu = "socket MTU" - extra_frame; 105 * @endcode 106 */ 107 108 int extra_buffer; /**< Maximum number of bytes that 109 * processing steps could expand the 110 * internal work buffer. 111 * 112 * This is used by the \link compression 113 * Data Channel Compression 114 * module\endlink to give enough working 115 * space for worst-case expansion of 116 * incompressible content. */ 117 118 int extra_tun; /**< Maximum number of bytes in excess of 119 * the tun/tap MTU that might be read 120 * from or written to the virtual 121 * tun/tap network interface. */ 122 123 int extra_link; /**< Maximum number of bytes in excess of 124 * external network interface's MTU that 125 * might be read from or written to it. */ 126 127 /* 128 * Alignment control 129 */ 130# define FRAME_HEADROOM_MARKER_DECRYPT (1<<0) 131# define FRAME_HEADROOM_MARKER_FRAGMENT (1<<1) 132# define FRAME_HEADROOM_MARKER_READ_LINK (1<<2) 133# define FRAME_HEADROOM_MARKER_READ_STREAM (1<<3) 134 unsigned int align_flags; 135 int align_adjust; 136}; 137 138/* Routines which read struct frame should use the macros below */ 139 140/* 141 * Overhead added to packet payload due to encapsulation 142 */ 143#define EXTRA_FRAME(f) ((f)->extra_frame) 144 145/* 146 * Delta between tun payload size and final TCP/UDP datagram size 147 * (not including extra_link additions) 148 */ 149#define TUN_LINK_DELTA(f) ((f)->extra_frame + (f)->extra_tun) 150 151/* 152 * This is the size to "ifconfig" the tun or tap device. 153 */ 154#define TUN_MTU_SIZE(f) ((f)->link_mtu - TUN_LINK_DELTA(f)) 155#define TUN_MTU_SIZE_DYNAMIC(f) ((f)->link_mtu_dynamic - TUN_LINK_DELTA(f)) 156 157/* 158 * This is the maximum packet size that we need to be able to 159 * read from or write to a tun or tap device. For example, 160 * a tap device ifconfiged to an MTU of 1200 might actually want 161 * to return a packet size of 1214 on a read(). 162 */ 163#define PAYLOAD_SIZE(f) ((f)->link_mtu - (f)->extra_frame) 164#define PAYLOAD_SIZE_DYNAMIC(f) ((f)->link_mtu_dynamic - (f)->extra_frame) 165 166/* 167 * Max size of a payload packet after encryption, compression, etc. 168 * overhead is added. 169 */ 170#define EXPANDED_SIZE(f) ((f)->link_mtu) 171#define EXPANDED_SIZE_DYNAMIC(f) ((f)->link_mtu_dynamic) 172#define EXPANDED_SIZE_MIN(f) (TUN_MTU_MIN + TUN_LINK_DELTA(f)) 173 174/* 175 * These values are used as maximum size constraints 176 * on read() or write() from TUN/TAP device or TCP/UDP port. 177 */ 178#define MAX_RW_SIZE_TUN(f) (PAYLOAD_SIZE(f)) 179#define MAX_RW_SIZE_LINK(f) (EXPANDED_SIZE(f) + (f)->extra_link) 180 181/* 182 * Control buffer headroom allocations to allow for efficient prepending. 183 */ 184#define FRAME_HEADROOM_BASE(f) (TUN_LINK_DELTA(f) + (f)->extra_buffer + (f)->extra_link) 185#define FRAME_HEADROOM(f) frame_headroom(f, 0) 186#define FRAME_HEADROOM_ADJ(f, fm) frame_headroom(f, fm) 187 188/* 189 * Max size of a buffer used to build a packet for output to 190 * the TCP/UDP port. 191 */ 192#define BUF_SIZE(f) (TUN_MTU_SIZE(f) + FRAME_HEADROOM_BASE(f) * 2) 193 194/* 195 * Function prototypes. 196 */ 197 198void frame_finalize (struct frame *frame, 199 bool link_mtu_defined, 200 int link_mtu, 201 bool tun_mtu_defined, 202 int tun_mtu); 203 204void frame_subtract_extra (struct frame *frame, const struct frame *src); 205 206void frame_print (const struct frame *frame, 207 int level, 208 const char *prefix); 209 210void set_mtu_discover_type (int sd, int mtu_type); 211int translate_mtu_discover_type_name (const char *name); 212 213/* 214 * frame_set_mtu_dynamic and flags 215 */ 216 217#define SET_MTU_TUN (1<<0) /* use tun/tap rather than link sizing */ 218#define SET_MTU_UPPER_BOUND (1<<1) /* only decrease dynamic MTU */ 219 220void frame_set_mtu_dynamic (struct frame *frame, int mtu, unsigned int flags); 221 222/* 223 * allocate a buffer for socket or tun layer 224 */ 225void alloc_buf_sock_tun (struct buffer *buf, 226 const struct frame *frame, 227 const bool tuntap_buffer, 228 const unsigned int align_mask); 229 230/* 231 * EXTENDED_SOCKET_ERROR_CAPABILITY functions -- print extra error info 232 * on socket errors, such as PMTU size. As of 2003.05.11, only works 233 * on Linux 2.4+. 234 */ 235 236#if EXTENDED_SOCKET_ERROR_CAPABILITY 237 238void set_sock_extended_error_passing (int sd); 239const char *format_extended_socket_error (int fd, int *mtu, struct gc_arena *gc); 240 241#endif 242 243/* 244 * Calculate a starting offset into a buffer object, dealing with 245 * headroom and alignment issues. 246 */ 247static inline int 248frame_headroom (const struct frame *f, const unsigned int flag_mask) 249{ 250 const int offset = FRAME_HEADROOM_BASE (f); 251 const int adjust = (flag_mask & f->align_flags) ? f->align_adjust : 0; 252 const int delta = ((PAYLOAD_ALIGN << 24) - (offset + adjust)) & (PAYLOAD_ALIGN - 1); 253 return offset + delta; 254} 255 256/* 257 * frame member adjustment functions 258 */ 259 260static inline void 261frame_add_to_extra_frame (struct frame *frame, const int increment) 262{ 263 frame->extra_frame += increment; 264} 265 266static inline void 267frame_add_to_extra_tun (struct frame *frame, const int increment) 268{ 269 frame->extra_tun += increment; 270} 271 272static inline void 273frame_add_to_extra_link (struct frame *frame, const int increment) 274{ 275 frame->extra_link += increment; 276} 277 278static inline void 279frame_add_to_extra_buffer (struct frame *frame, const int increment) 280{ 281 frame->extra_buffer += increment; 282} 283 284static inline void 285frame_add_to_align_adjust (struct frame *frame, const int increment) 286{ 287 frame->align_adjust += increment; 288} 289 290static inline void 291frame_align_to_extra_frame (struct frame *frame) 292{ 293 frame->align_adjust = frame->extra_frame + frame->extra_link; 294} 295 296static inline void 297frame_or_align_flags (struct frame *frame, const unsigned int flag_mask) 298{ 299 frame->align_flags |= flag_mask; 300} 301 302static inline bool 303frame_defined (const struct frame *frame) 304{ 305 return frame->link_mtu > 0; 306} 307 308#endif 309