Merge pull request #78 from ffontaine/master
[olsrd.git] / src / olsr_niit.c
1 /*
2  * The olsr.org Optimized Link-State Routing daemon (olsrd)
3  *
4  * (c) by the OLSR project
5  *
6  * See our Git repository to find out who worked on this file
7  * and thus is a copyright holder on it.
8  *
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  *
15  * * Redistributions of source code must retain the above copyright
16  *   notice, this list of conditions and the following disclaimer.
17  * * Redistributions in binary form must reproduce the above copyright
18  *   notice, this list of conditions and the following disclaimer in
19  *   the documentation and/or other materials provided with the
20  *   distribution.
21  * * Neither the name of olsr.org, olsrd nor the names of its
22  *   contributors may be used to endorse or promote products derived
23  *   from this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
28  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
29  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
30  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
31  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  *
38  * Visit http://www.olsr.org for more information.
39  *
40  * If you find this software useful feel free to make a donation
41  * to the project. For more information see the website or contact
42  * the copyright holders.
43  *
44  */
45
46 #include "defs.h"
47 #include "kernel_routes.h"
48 #include "net_os.h"
49 #include "olsr_niit.h"
50
51 #include <net/if.h>
52
53 #ifdef __linux__
54 static void handle_niit_ifchange (int if_index, struct interface_olsr *iface, enum olsr_ifchg_flag);
55
56 static bool niit4to6_active, niit6to4_active;
57
58 void olsr_init_niit(void) {
59   if (olsr_cnf->ip_version == AF_INET) {
60     olsr_cnf->use_niit = false;
61     return;
62   }
63
64   olsr_cnf->niit4to6_if_index = if_nametoindex(DEF_NIIT4TO6_IFNAME);
65   if (olsr_cnf->niit4to6_if_index <= 0) {
66     OLSR_PRINTF(1, "Warning, %s device is not available, deactivating NIIT\n", DEF_NIIT4TO6_IFNAME);
67     olsr_cnf->use_niit = false;
68     return;
69   }
70   olsr_cnf->niit6to4_if_index = if_nametoindex(DEF_NIIT6TO4_IFNAME);
71   if (olsr_cnf->niit6to4_if_index <= 0) {
72     OLSR_PRINTF(1, "Warning, %s device is not available, deactivating NIIT\n", DEF_NIIT6TO4_IFNAME);
73     olsr_cnf->use_niit = false;
74     return;
75   }
76
77   niit4to6_active = olsr_if_isup(DEF_NIIT4TO6_IFNAME);
78   niit6to4_active = olsr_if_isup(DEF_NIIT6TO4_IFNAME);
79
80   olsr_add_ifchange_handler(&handle_niit_ifchange);
81   olsr_add_ifchange_handler(&handle_niit_ifchange);
82   return;
83 }
84
85 void olsr_setup_niit_routes(void) {
86   struct ip_prefix_list *h;
87
88   if (!niit4to6_active || !niit6to4_active) {
89     return;
90   }
91   for (h = olsr_cnf->hna_entries; h != NULL; h = h->next) {
92     if (ip_prefix_is_mappedv4(&h->net)) {
93       olsr_os_niit_6to4_route(&h->net, true);
94     }
95   }
96 }
97
98 void olsr_cleanup_niit_routes(void) {
99   struct ip_prefix_list *h;
100
101   if (!niit6to4_active) {
102     return;
103   }
104   for (h = olsr_cnf->hna_entries; h != NULL; h = h->next) {
105     if (ip_prefix_is_mappedv4(&h->net)) {
106       olsr_os_niit_6to4_route(&h->net, false);
107     }
108   }
109 }
110
111 void olsr_niit_handle_route(const struct rt_entry *rt, bool set) {
112   if (olsr_cnf->ip_version == AF_INET6 && olsr_cnf->use_niit
113       && niit4to6_active && niit6to4_active && is_prefix_niit_ipv6(&rt->rt_dst)) {
114     struct olsr_ip_prefix dst_v4;
115
116     prefix_mappedv4_to_v4(&dst_v4, &rt->rt_dst);
117     olsr_os_niit_4to6_route(&dst_v4, set);
118   }
119 }
120
121 static void refresh_niit4to6_routes(bool set) {
122   struct rt_entry *rt;
123
124   if (set && (!niit4to6_active || !niit6to4_active)) {
125     return;
126   }
127   if (!set && !niit4to6_active) {
128     return;
129   }
130
131   OLSR_FOR_ALL_RT_ENTRIES(rt) {
132     if (is_prefix_niit_ipv6(&rt->rt_dst)) {
133       struct olsr_ip_prefix dst_v4;
134
135       prefix_mappedv4_to_v4(&dst_v4, &rt->rt_dst);
136       olsr_os_niit_4to6_route(&dst_v4, set);
137     }
138   } OLSR_FOR_ALL_RT_ENTRIES_END(rt)
139 }
140
141 static void handle_niit_ifchange (int if_index, struct interface_olsr *iface __attribute__ ((unused)),
142     enum olsr_ifchg_flag flag) {
143   bool active;
144
145   active = niit4to6_active && niit6to4_active;
146   if (if_index == olsr_cnf->niit4to6_if_index) {
147     niit4to6_active = flag != IFCHG_IF_REMOVE;
148   }
149   if (if_index == olsr_cnf->niit6to4_if_index) {
150     niit6to4_active = flag != IFCHG_IF_REMOVE;
151   }
152
153   if (active != (niit4to6_active && niit6to4_active)) {
154     /* niit status change */
155     if (!active) {
156       /* from inactive to active */
157       olsr_setup_niit_routes();
158       refresh_niit4to6_routes(true);
159     }
160     else {
161       /* the other way around */
162       olsr_cleanup_niit_routes();
163       refresh_niit4to6_routes(false);
164     }
165   }
166
167 }
168 #endif /* __linux__ */