2 * The olsr.org Optimized Link-State Routing daemon(olsrd)
3 * Copyright (c) 2004, Andreas Tonnesen(andreto@olsr.org)
4 * Copyright (c) 2007, Sven-Ola for the policy routing stuff
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of olsr.org, olsrd nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
34 * Visit http://www.olsr.org for more information.
36 * If you find this software useful feel free to make a donation
37 * to the project. For more information see the website or contact
38 * the copyright holders.
42 #include "kernel_tunnel.h"
44 #include "olsr_types.h"
50 #include <netinet/in.h>
51 #include <sys/ioctl.h>
54 #include <linux/if_tunnel.h>
55 #include <linux/ip6_tunnel.h>
58 #include <sys/socket.h>
59 #include <sys/ioctl.h>
60 #include <sys/types.h>
63 static const char DEV_IPV4_TUNNEL[IFNAMSIZ] = "tunl0";
64 static const char DEV_IPV6_TUNNEL[IFNAMSIZ] = "ip6tnl0";
66 static bool store_iptunnel_state;
68 int olsr_os_init_iptunnel(void) {
69 const char *dev = olsr_cnf->ip_version == AF_INET ? DEV_IPV4_TUNNEL : DEV_IPV6_TUNNEL;
71 store_iptunnel_state = olsr_if_isup(dev);
72 if (store_iptunnel_state) {
75 return olsr_if_set_state(dev, true);
78 void olsr_os_cleanup_iptunnel(void) {
79 if (!store_iptunnel_state) {
80 olsr_if_set_state(olsr_cnf->ip_version == AF_INET ? DEV_IPV4_TUNNEL : DEV_IPV6_TUNNEL, false);
84 static const char *get_tunnelcmd_name(uint32_t cmd) {
85 static const char ADD[] = "add";
86 static const char CHANGE[] = "change";
87 static const char DELETE[] = "delete";
101 static int os_ip4_tunnel(const char *name, in_addr_t *target, uint32_t cmd)
105 struct ip_tunnel_parm p;
107 /* only IPIP tunnel if OLSR runs with IPv6 */
108 assert (olsr_cnf->ip_version == AF_INET);
109 memset(&p, 0, sizeof(p));
112 p.iph.protocol = IPPROTO_IPIP;
114 p.iph.daddr = *target;
116 strncpy(p.name, name, IFNAMSIZ);
118 memset(&ifr, 0, sizeof(ifr));
119 strncpy(ifr.ifr_name, cmd == SIOCADDTUNNEL ? DEV_IPV4_TUNNEL : name, IFNAMSIZ);
120 ifr.ifr_ifru.ifru_data = (void *) &p;
122 if ((err = ioctl(olsr_cnf->ioctl_s, cmd, &ifr))) {
123 olsr_syslog(OLSR_LOG_ERR, "Cannot %s a tunnel %s: %s (%d)\n",
124 get_tunnelcmd_name(cmd), name, strerror(errno), errno);
129 static int os_ip6_tunnel(const char *name, struct in6_addr *target, uint32_t cmd, uint8_t proto)
133 struct ip6_tnl_parm p;
135 /* only IP6 tunnel if OLSR runs with IPv6 */
136 assert (olsr_cnf->ip_version == AF_INET6);
137 memset(&p, 0, sizeof(p));
142 strncpy(p.name, name, IFNAMSIZ);
144 memset(&ifr, 0, sizeof(ifr));
145 strncpy(ifr.ifr_name, cmd == SIOCADDTUNNEL ? DEV_IPV6_TUNNEL : name, IFNAMSIZ);
146 ifr.ifr_ifru.ifru_data = (void *) &p;
148 if ((err = ioctl(olsr_cnf->ioctl_s, cmd, &ifr))) {
149 olsr_syslog(OLSR_LOG_ERR, "Cannot %s a tunnel %s: %s (%d)\n",
150 get_tunnelcmd_name(cmd), name, strerror(errno), errno);
155 int olsr_os_add_ipip_tunnel(const char *name, union olsr_ip_addr *target, bool transportV4) {
156 if (olsr_cnf->ip_version == AF_INET) {
159 return os_ip4_tunnel(name, &target->v4.s_addr, SIOCADDTUNNEL);
161 return os_ip6_tunnel(name, &target->v6, SIOCADDTUNNEL, transportV4 ? IPPROTO_IPIP : IPPROTO_IPV6);
164 int olsr_os_change_ipip_tunnel(const char *name, union olsr_ip_addr *target, bool transportV4) {
165 if (olsr_cnf->ip_version == AF_INET) {
168 return os_ip4_tunnel(name, &target->v4.s_addr, SIOCCHGTUNNEL);
170 return os_ip6_tunnel(name, &target->v6, SIOCCHGTUNNEL, transportV4 ? IPPROTO_IPIP : IPPROTO_IPV6);
173 int olsr_os_del_ipip_tunnel(const char *name, bool transportV4) {
174 if (olsr_cnf->ip_version == AF_INET) {
177 return os_ip4_tunnel(name, NULL, SIOCDELTUNNEL);
179 return os_ip6_tunnel(name, NULL, SIOCDELTUNNEL, transportV4 ? IPPROTO_IPIP : IPPROTO_IPV6);