OpenVPN
route.h
Go to the documentation of this file.
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-2025 OpenVPN 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 along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 */
23
24/*
25 * Support routines for adding/deleting network routes.
26 */
27
28#ifndef ROUTE_H
29#define ROUTE_H
30
31#include "basic.h"
32#include "tun.h"
33#include "misc.h"
34#include "networking.h"
35
36#ifdef _WIN32
37/*
38 * Windows route methods
39 */
40#define ROUTE_METHOD_ADAPTIVE 0 /* try IP helper first then route.exe */
41#define ROUTE_METHOD_IPAPI 1 /* use IP helper API */
42#define ROUTE_METHOD_EXE 2 /* use route.exe */
43#define ROUTE_METHOD_SERVICE 3 /* use the privileged Windows service */
44#define ROUTE_METHOD_MASK 3
45#endif
46
47/*
48 * Route add/delete flags (must stay clear of ROUTE_METHOD bits)
49 */
50#define ROUTE_DELETE_FIRST (1<<2)
51#define ROUTE_REF_GW (1<<3)
52
54{
55#define N_ROUTE_BYPASS 8
58};
59
61{
62 /* bits indicating which members below are defined */
63#define RTSA_REMOTE_ENDPOINT (1<<0)
64#define RTSA_REMOTE_HOST (1<<1)
65#define RTSA_DEFAULT_METRIC (1<<2)
66 unsigned int flags;
67
68 in_addr_t remote_endpoint;
69 in_addr_t remote_host;
70 int remote_host_local; /* TLA_x value */
74};
75
78 const char *network;
79 const char *netmask;
80 const char *gateway;
82 const char *metric;
83};
84
85/* redirect-gateway flags */
86#define RG_ENABLE (1<<0)
87#define RG_LOCAL (1<<1)
88#define RG_DEF1 (1<<2)
89#define RG_BYPASS_DHCP (1<<3)
90#define RG_BYPASS_DNS (1<<4)
91#define RG_REROUTE_GW (1<<5)
92#define RG_AUTO_LOCAL (1<<6)
93#define RG_BLOCK_LOCAL (1<<7)
94
96 unsigned int flags; /* RG_x flags */
98 struct gc_arena *gc;
99};
100
103 const char *prefix; /* e.g. "2001:db8:1::/64" */
104 const char *gateway; /* e.g. "2001:db8:0::2" */
105 const char *metric; /* e.g. "5" */
107};
108
110 unsigned int flags; /* RG_x flags, see route_option-list */
112 struct gc_arena *gc;
113};
114
116#define RT_DEFINED (1<<0)
117#define RT_ADDED (1<<1)
118#define RT_METRIC_DEFINED (1<<2)
120 unsigned int flags;
121 const struct route_option *option;
122 in_addr_t network;
123 in_addr_t netmask;
124 in_addr_t gateway;
127};
128
131 unsigned int flags; /* RT_ flags, see route_ipv4 */
132 struct in6_addr network;
133 unsigned int netbits;
134 struct in6_addr gateway;
137 /* gateway interface */
138#ifdef _WIN32
139 DWORD adapter_index; /* interface or ~0 if undefined */
140#else
141 char *iface; /* interface name (null terminated) */
142#endif
143};
144
145
147 in_addr_t addr;
148 in_addr_t netmask;
149};
150
152#define RGI_ADDR_DEFINED (1<<0) /* set if gateway.addr defined */
153#define RGI_NETMASK_DEFINED (1<<1) /* set if gateway.netmask defined */
154#define RGI_HWADDR_DEFINED (1<<2) /* set if hwaddr is defined */
155#define RGI_IFACE_DEFINED (1<<3) /* set if iface is defined */
156#define RGI_OVERFLOW (1<<4) /* set if more interface addresses than will fit in addrs */
157#define RGI_ON_LINK (1<<5)
158 unsigned int flags;
159
160 /* gateway interface */
161#ifdef _WIN32
162 DWORD adapter_index; /* interface or ~0 if undefined */
163#elif defined(TARGET_HAIKU)
164 char iface[PATH_MAX]; /* iface names are full /dev path with driver name */
165#else
166 char iface[16]; /* interface name (null terminated), may be empty */
167#endif
168
169 /* gateway interface hardware address */
170 uint8_t hwaddr[6];
171
172 /* gateway/router address */
174
175 /* address/netmask pairs bound to interface */
176#define RGI_N_ADDRESSES 8
177 int n_addrs; /* len of addrs, may be 0 */
178 struct route_gateway_address addrs[RGI_N_ADDRESSES]; /* local addresses attached to iface */
179};
180
182 struct in6_addr addr_ipv6;
184};
185
187/* RGI_ flags used as in route_gateway_info */
188 unsigned int flags;
189
190 /* gateway interface */
191#ifdef _WIN32
192 DWORD adapter_index; /* interface or ~0 if undefined */
193#else
194 /* non linux platform don't have this constant defined */
195#ifndef IFNAMSIZ
196#if defined(TARGET_HAIKU)
197/* iface names are full /dev path with driver name */
198#define IFNAMSIZ PATH_MAX
199#else
200#define IFNAMSIZ 16
201#endif
202#endif
203 char iface[IFNAMSIZ]; /* interface name (null terminated), may be empty */
204#endif
205
206 /* gateway interface hardware address */
207 uint8_t hwaddr[6];
208
209 /* gateway/router address */
211
212 /* address/netmask pairs bound to interface */
213#define RGI_N_ADDRESSES 8
214 int n_addrs; /* len of addrs, may be 0 */
215 struct route_ipv6_gateway_address addrs[RGI_N_ADDRESSES]; /* local addresses attached to iface */
216};
217
219#define RL_DID_REDIRECT_DEFAULT_GATEWAY (1<<0)
220#define RL_DID_LOCAL (1<<1)
221#define RL_ROUTES_ADDED (1<<2)
222 unsigned int iflags;
223
226 unsigned int flags; /* RG_x flags */
228 struct gc_arena gc;
229};
230
232 unsigned int iflags; /* RL_ flags, see route_list */
233
234 unsigned int spec_flags; /* RTSA_ flags, route_special_addr */
235 struct in6_addr remote_endpoint_ipv6; /* inside tun */
236 struct in6_addr remote_host_ipv6; /* --remote address */
238
240 unsigned int flags; /* RG_x flags, see route_option_list */
242 struct gc_arena gc;
243};
244
245/* internal OpenVPN route */
246struct iroute {
247 in_addr_t network;
249 struct iroute *next;
250};
251
253 struct in6_addr network;
254 unsigned int netbits;
256};
257
268bool block_local_needed(const struct route_list *rl);
269
271
273
274struct route_option_list *clone_route_option_list(const struct route_option_list *src, struct gc_arena *a);
275
277
278void copy_route_option_list(struct route_option_list *dest, const struct route_option_list *src, struct gc_arena *a);
279
281 const struct route_ipv6_option_list *src,
282 struct gc_arena *a);
283
284void route_ipv6_clear_host_bits( struct route_ipv6 *r6 );
285
286bool add_route_ipv6(struct route_ipv6 *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es, openvpn_net_ctx_t *ctx);
287
288void delete_route_ipv6(const struct route_ipv6 *r, const struct tuntap *tt, const struct env_set *es, openvpn_net_ctx_t *ctx);
289
290bool add_route(struct route_ipv4 *r, const struct tuntap *tt, unsigned int flags,
291 const struct route_gateway_info *rgi, const struct env_set *es,
292 openvpn_net_ctx_t *ctx);
293
295 const char *network,
296 const char *netmask,
297 const char *gateway,
298 const char *metric,
299 int table_id);
300
302 const char *prefix,
303 const char *gateway,
304 const char *metric,
305 int table_id);
306
307bool init_route_list(struct route_list *rl,
308 const struct route_option_list *opt,
309 const char *remote_endpoint,
310 int default_metric,
311 in_addr_t remote_host,
312 struct env_set *es,
313 openvpn_net_ctx_t *ctx);
314
316 const struct route_ipv6_option_list *opt6,
317 const char *remote_endpoint,
318 int default_metric,
319 const struct in6_addr *remote_host,
320 struct env_set *es,
321 openvpn_net_ctx_t *ctx);
322
324 struct env_set *es,
325 const in_addr_t addr);
326
327bool add_routes(struct route_list *rl, struct route_ipv6_list *rl6,
328 const struct tuntap *tt, unsigned int flags,
329 const struct env_set *es, openvpn_net_ctx_t *ctx);
330
331void delete_routes(struct route_list *rl,
332 struct route_ipv6_list *rl6,
333 const struct tuntap *tt,
334 unsigned int flags,
335 const struct env_set *es,
336 openvpn_net_ctx_t *ctx);
337
338void setenv_routes(struct env_set *es, const struct route_list *rl);
339
340void setenv_routes_ipv6(struct env_set *es, const struct route_ipv6_list *rl6);
341
342bool is_special_addr(const char *addr_str);
343
352 in_addr_t dest,
353 openvpn_net_ctx_t *ctx);
354
356 const struct in6_addr *dest,
357 openvpn_net_ctx_t *ctx);
358
359void print_default_gateway(const int msglevel,
360 const struct route_gateway_info *rgi,
361 const struct route_ipv6_gateway_info *rgi6);
362
363/*
364 * Test if addr is reachable via a local interface (return ILA_LOCAL),
365 * or if it needs to be routed via the default gateway (return
366 * ILA_NONLOCAL). If the current platform doesn't implement this
367 * function, return ILA_NOT_IMPLEMENTED.
368 */
369#define TLA_NOT_IMPLEMENTED 0
370#define TLA_NONLOCAL 1
371#define TLA_LOCAL 2
372int test_local_addr(const in_addr_t addr, const struct route_gateway_info *rgi);
373
374#ifndef ENABLE_SMALL
375void print_route_options(const struct route_option_list *rol,
376 int level);
377
378#endif
379
380void print_routes(const struct route_list *rl, int level);
381
382#ifdef _WIN32
383
384void show_routes(int msglev);
385
386bool test_routes(const struct route_list *rl, const struct tuntap *tt);
387
388#else /* ifdef _WIN32 */
389static inline bool
390test_routes(const struct route_list *rl, const struct tuntap *tt)
391{
392 return true;
393}
394#endif
395
396bool netmask_to_netbits(const in_addr_t network, const in_addr_t netmask, int *netbits);
397
398int netmask_to_netbits2(in_addr_t netmask);
399
400static inline in_addr_t
401netbits_to_netmask(const int netbits)
402{
403 const int addrlen = sizeof(in_addr_t) * 8;
404 in_addr_t mask = 0;
405 if (netbits > 0 && netbits <= addrlen)
406 {
407 mask = IPV4_NETMASK_HOST << (addrlen-netbits);
408 }
409 return mask;
410}
411
412static inline bool
414{
415 if (!rl)
416 {
417 return false;
418 }
419 else
420 {
421 return !(rl->spec.flags & RTSA_REMOTE_ENDPOINT);
422 }
423}
424
425static inline int
430
431#endif /* ifndef ROUTE_H */
void * openvpn_net_ctx_t
Definition networking.h:39
#define IPV4_NETMASK_HOST
Definition basic.h:35
#define BOOL_CAST(x)
Definition basic.h:27
static bool route_list_vpn_gateway_needed(const struct route_list *rl)
Definition route.h:413
bool add_routes(struct route_list *rl, struct route_ipv6_list *rl6, const struct tuntap *tt, unsigned int flags, const struct env_set *es, openvpn_net_ctx_t *ctx)
Definition route.c:1197
bool is_special_addr(const char *addr_str)
Definition route.c:306
struct route_option_list * clone_route_option_list(const struct route_option_list *src, struct gc_arena *a)
Definition route.c:155
void setenv_routes_ipv6(struct env_set *es, const struct route_ipv6_list *rl6)
Definition route.c:1497
int netmask_to_netbits2(in_addr_t netmask)
Definition route.c:4148
struct route_ipv6_option_list * new_route_ipv6_option_list(struct gc_arena *a)
Definition route.c:139
#define RL_DID_REDIRECT_DEFAULT_GATEWAY
Definition route.h:219
#define RTSA_REMOTE_ENDPOINT
Definition route.h:63
bool test_routes(const struct route_list *rl, const struct tuntap *tt)
Definition route.c:2656
static int route_did_redirect_default_gateway(const struct route_list *rl)
Definition route.h:426
bool block_local_needed(const struct route_list *rl)
Get the decision whether to block traffic to local networks while the VPN is connected.
Definition route.c:629
static in_addr_t netbits_to_netmask(const int netbits)
Definition route.h:401
void show_routes(int msglev)
Definition route.c:3317
void print_route_options(const struct route_option_list *rol, int level)
Definition route.c:1327
void route_list_add_vpn_gateway(struct route_list *rl, struct env_set *es, const in_addr_t addr)
Definition route.c:565
void add_route_ipv6_to_option_list(struct route_ipv6_option_list *l, const char *prefix, const char *gateway, const char *metric, int table_id)
Definition route.c:534
void print_default_gateway(const int msglevel, const struct route_gateway_info *rgi, const struct route_ipv6_gateway_info *rgi6)
Definition route.c:1343
void copy_route_option_list(struct route_option_list *dest, const struct route_option_list *src, struct gc_arena *a)
Definition route.c:173
void copy_route_ipv6_option_list(struct route_ipv6_option_list *dest, const struct route_ipv6_option_list *src, struct gc_arena *a)
Definition route.c:180
bool add_route(struct route_ipv4 *r, const struct tuntap *tt, unsigned int flags, const struct route_gateway_info *rgi, const struct env_set *es, openvpn_net_ctx_t *ctx)
Definition route.c:1575
bool add_route_ipv6(struct route_ipv6 *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es, openvpn_net_ctx_t *ctx)
Definition route.c:1924
void get_default_gateway_ipv6(struct route_ipv6_gateway_info *rgi, const struct in6_addr *dest, openvpn_net_ctx_t *ctx)
Definition route.c:2895
void get_default_gateway(struct route_gateway_info *rgi, in_addr_t dest, openvpn_net_ctx_t *ctx)
Retrieves the best gateway for a given destination based on the routing table.
Definition route.c:2794
struct route_ipv6_option_list * clone_route_ipv6_option_list(const struct route_ipv6_option_list *src, struct gc_arena *a)
Definition route.c:164
struct route_option_list * new_route_option_list(struct gc_arena *a)
Definition route.c:130
int test_local_addr(const in_addr_t addr, const struct route_gateway_info *rgi)
Definition route.c:4254
bool init_route_list(struct route_list *rl, const struct route_option_list *opt, const char *remote_endpoint, int default_metric, in_addr_t remote_host, struct env_set *es, openvpn_net_ctx_t *ctx)
Definition route.c:639
#define RGI_N_ADDRESSES
Definition route.h:176
bool init_route_ipv6_list(struct route_ipv6_list *rl6, const struct route_ipv6_option_list *opt6, const char *remote_endpoint, int default_metric, const struct in6_addr *remote_host, struct env_set *es, openvpn_net_ctx_t *ctx)
Definition route.c:798
#define N_ROUTE_BYPASS
Definition route.h:55
void route_ipv6_clear_host_bits(struct route_ipv6 *r6)
Definition route.c:1901
void delete_routes(struct route_list *rl, struct route_ipv6_list *rl6, const struct tuntap *tt, unsigned int flags, const struct env_set *es, openvpn_net_ctx_t *ctx)
Definition route.c:1264
void print_routes(const struct route_list *rl, int level)
Definition route.c:1429
bool netmask_to_netbits(const in_addr_t network, const in_addr_t netmask, int *netbits)
Definition route.c:4117
void setenv_routes(struct env_set *es, const struct route_list *rl)
Definition route.c:1459
void add_route_to_option_list(struct route_option_list *l, const char *network, const char *netmask, const char *gateway, const char *metric, int table_id)
Definition route.c:514
void delete_route_ipv6(const struct route_ipv6 *r, const struct tuntap *tt, const struct env_set *es, openvpn_net_ctx_t *ctx)
Definition route.c:2393
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:117
struct iroute_ipv6 * next
Definition route.h:255
unsigned int netbits
Definition route.h:254
struct in6_addr network
Definition route.h:253
in_addr_t network
Definition route.h:247
int netbits
Definition route.h:248
struct iroute * next
Definition route.h:249
int n_bypass
Definition route.h:56
in_addr_t bypass[N_ROUTE_BYPASS]
Definition route.h:57
in_addr_t netmask
Definition route.h:148
uint8_t hwaddr[6]
Definition route.h:170
unsigned int flags
Definition route.h:158
struct route_gateway_address addrs[RGI_N_ADDRESSES]
Definition route.h:178
DWORD adapter_index
Definition route.h:162
struct route_gateway_address gateway
Definition route.h:173
const struct route_option * option
Definition route.h:121
int metric
Definition route.h:126
struct route_ipv4 * next
Definition route.h:119
int table_id
Definition route.h:125
in_addr_t network
Definition route.h:122
in_addr_t netmask
Definition route.h:123
in_addr_t gateway
Definition route.h:124
unsigned int flags
Definition route.h:120
struct in6_addr addr_ipv6
Definition route.h:182
struct route_ipv6_gateway_address gateway
Definition route.h:210
struct route_ipv6_gateway_address addrs[RGI_N_ADDRESSES]
Definition route.h:215
unsigned int flags
Definition route.h:188
uint8_t hwaddr[6]
Definition route.h:207
unsigned int iflags
Definition route.h:232
unsigned int flags
Definition route.h:240
struct route_ipv6_gateway_info rgi6
Definition route.h:239
struct route_ipv6 * routes_ipv6
Definition route.h:241
unsigned int spec_flags
Definition route.h:234
int default_metric
Definition route.h:237
struct in6_addr remote_host_ipv6
Definition route.h:236
struct gc_arena gc
Definition route.h:242
struct in6_addr remote_endpoint_ipv6
Definition route.h:235
unsigned int flags
Definition route.h:110
struct gc_arena * gc
Definition route.h:112
struct route_ipv6_option * routes_ipv6
Definition route.h:111
struct route_ipv6_option * next
Definition route.h:102
const char * gateway
Definition route.h:104
const char * metric
Definition route.h:105
const char * prefix
Definition route.h:103
struct in6_addr gateway
Definition route.h:134
DWORD adapter_index
Definition route.h:139
unsigned int netbits
Definition route.h:133
struct route_ipv6 * next
Definition route.h:130
unsigned int flags
Definition route.h:131
struct in6_addr network
Definition route.h:132
int table_id
Definition route.h:136
int metric
Definition route.h:135
struct route_gateway_info rgi
Definition route.h:225
struct route_ipv4 * routes
Definition route.h:227
struct route_special_addr spec
Definition route.h:224
unsigned int flags
Definition route.h:226
struct gc_arena gc
Definition route.h:228
unsigned int iflags
Definition route.h:222
struct gc_arena * gc
Definition route.h:98
unsigned int flags
Definition route.h:96
struct route_option * routes
Definition route.h:97
int table_id
Definition route.h:81
const char * network
Definition route.h:78
const char * netmask
Definition route.h:79
struct route_option * next
Definition route.h:77
const char * gateway
Definition route.h:80
const char * metric
Definition route.h:82
in_addr_t remote_host
Definition route.h:69
struct route_bypass bypass
Definition route.h:71
unsigned int flags
Definition route.h:66
in_addr_t remote_endpoint
Definition route.h:68
int remote_host_local
Definition route.h:70
Definition tun.h:178
static char * iface
struct env_set * es