2 * This file is free software: you may copy, redistribute and/or modify it
3 * under the terms of the GNU General Public License as published by the
4 * Free Software Foundation, either version 2 of the License, or (at your
5 * option) any later version.
7 * This file is distributed in the hope that it will be useful, but
8 * WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 * This file incorporates work covered by the following copyright and
18 Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek
20 Permission is hereby granted, free of charge, to any person obtaining a copy
21 of this software and associated documentation files (the "Software"), to deal
22 in the Software without restriction, including without limitation the rights
23 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
24 copies of the Software, and to permit persons to whom the Software is
25 furnished to do so, subject to the following conditions:
27 The above copyright notice and this permission notice shall be included in
28 all copies or substantial portions of the Software.
30 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
31 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
32 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
33 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
34 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
35 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
39 #include <sys/types.h>
40 #include <sys/socket.h>
41 #include <netinet/in.h>
43 #include <arpa/inet.h>
56 #include "babel_interface.h"
57 #include "babel_zebra.h"
61 kernel_route_add_v4(const unsigned char *pref
, unsigned short plen
,
62 const unsigned char *gate
, int ifindex
, unsigned int metric
,
63 const unsigned char *newgate
, int newifindex
,
64 unsigned int newmetric
);
66 kernel_route_add_v6(const unsigned char *pref
, unsigned short plen
,
67 const unsigned char *gate
, int ifindex
, unsigned int metric
,
68 const unsigned char *newgate
, int newifindex
,
69 unsigned int newmetric
);
71 kernel_route_delete_v4(const unsigned char *pref
, unsigned short plen
,
72 const unsigned char *gate
, int ifindex
,
74 const unsigned char *newgate
, int newifindex
,
75 unsigned int newmetric
);
77 kernel_route_delete_v6(const unsigned char *pref
, unsigned short plen
,
78 const unsigned char *gate
, int ifindex
,
80 const unsigned char *newgate
, int newifindex
,
81 unsigned int newmetric
);
84 int export_table
= -1, import_table
= -1; /* just for compatibility */
87 kernel_setup(int setup
)
92 /* get a connection with zebra client, at all costs */
94 kernel_setup_socket(int setup
)
100 kernel_setup_interface(int setup
, struct interface
*interface
)
106 kernel_interface_operational(struct interface
*interface
)
108 return if_is_operative(interface
);
112 kernel_interface_ipv4(struct interface
*interface
, unsigned char *addr_r
)
114 assert(0); /* function not used */
119 kernel_interface_mtu(struct interface
*interface
)
121 return MIN(interface
->mtu
, interface
->mtu6
);
125 kernel_interface_wireless(struct interface
*interface
)
131 zapi_ipv6_route (u_char cmd
, struct zclient
*zclient
,
132 struct prefix_ipv6
*p
, struct zapi_ipv6
*api
);
135 kernel_route(int operation
, const unsigned char *pref
, unsigned short plen
,
136 const unsigned char *gate
, int ifindex
, unsigned int metric
,
137 const unsigned char *newgate
, int newifindex
,
138 unsigned int newmetric
)
144 /* Check that the protocol family is consistent. */
145 if(plen
>= 96 && v4mapped(pref
)) {
146 if(!v4mapped(gate
)) {
162 kernel_route_add_v4(pref
, plen
, gate
, ifindex
, metric
,
163 newgate
, newifindex
, newmetric
):
164 kernel_route_add_v6(pref
, plen
, gate
, ifindex
, metric
,
165 newgate
, newifindex
, newmetric
);
169 kernel_route_delete_v4(pref
, plen
, gate
, ifindex
, metric
,
170 newgate
, newifindex
, newmetric
):
171 kernel_route_delete_v6(pref
, plen
, gate
, ifindex
, metric
,
172 newgate
, newifindex
, newmetric
);
175 if(newmetric
== metric
&& memcmp(newgate
, gate
, 16) == 0 &&
176 newifindex
== ifindex
)
178 /* It is better to add the new route before removing the old
179 one, to avoid losing packets. However, if the old and new
180 priorities are equal, this only works if the kernel supports
181 ECMP. So we first try the "right" order, and fall back on
182 the "wrong" order if it fails with EEXIST. */
184 kernel_route_add_v4(pref
, plen
,
185 newgate
, newifindex
, newmetric
,
187 kernel_route_add_v6(pref
, plen
,
188 newgate
, newifindex
, newmetric
,
199 kernel_route_delete_v4(pref
, plen
,
200 gate
, ifindex
, metric
,
203 kernel_route_delete_v6(pref
, plen
,
204 gate
, ifindex
, metric
,
210 kernel_route_add_v4(pref
, plen
,
211 newgate
, newifindex
, newmetric
,
213 kernel_route_add_v6(pref
, plen
,
214 newgate
, newifindex
, newmetric
,
219 /* In principle, we should try to re-install the flushed
220 route on failure to preserve. However, this should
221 hopefully not matter much in practice. */
228 zlog_err("this should never appens (false value - kernel_route)");
236 kernel_route_add_v4(const unsigned char *pref
, unsigned short plen
,
237 const unsigned char *gate
, int ifindex
, unsigned int metric
,
238 const unsigned char *newgate
, int newifindex
,
239 unsigned int newmetric
)
241 unsigned int tmp_ifindex
= ifindex
; /* (for typing) */
242 struct zapi_ipv4 api
; /* quagga's communication system */
243 struct prefix_ipv4 quagga_prefix
; /* quagga's prefix */
244 struct in_addr babel_prefix_addr
; /* babeld's prefix addr */
245 struct in_addr nexthop
; /* next router to go */
246 struct in_addr
*nexthop_pointer
= &nexthop
; /* it's an array! */
248 /* convert to be comprehensive by quagga */
249 /* convert given addresses */
250 uchar_to_inaddr(&babel_prefix_addr
, pref
);
251 uchar_to_inaddr(&nexthop
, gate
);
253 /* make prefix structure */
254 memset (&quagga_prefix
, 0, sizeof(quagga_prefix
));
255 quagga_prefix
.family
= AF_INET
;
256 IPV4_ADDR_COPY (&quagga_prefix
.prefix
, &babel_prefix_addr
);
257 quagga_prefix
.prefixlen
= plen
- 96; /* our plen is for v4mapped's addr */
258 apply_mask_ipv4(&quagga_prefix
);
260 api
.type
= ZEBRA_ROUTE_BABEL
;
263 SET_FLAG(api
.message
, ZAPI_MESSAGE_NEXTHOP
);
265 api
.nexthop
= &nexthop_pointer
;
266 SET_FLAG(api
.message
, ZAPI_MESSAGE_IFINDEX
);
268 api
.ifindex
= &tmp_ifindex
;
269 SET_FLAG(api
.message
, ZAPI_MESSAGE_METRIC
);
272 debugf(BABEL_DEBUG_ROUTE
, "adding route (ipv4) to zebra");
273 return zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD
, zclient
,
274 &quagga_prefix
, &api
);
278 kernel_route_add_v6(const unsigned char *pref
, unsigned short plen
,
279 const unsigned char *gate
, int ifindex
, unsigned int metric
,
280 const unsigned char *newgate
, int newifindex
,
281 unsigned int newmetric
)
283 unsigned int tmp_ifindex
= ifindex
; /* (for typing) */
284 struct zapi_ipv6 api
; /* quagga's communication system */
285 struct prefix_ipv6 quagga_prefix
; /* quagga's prefix */
286 struct in6_addr babel_prefix_addr
; /* babeld's prefix addr */
287 struct in6_addr nexthop
; /* next router to go */
288 struct in6_addr
*nexthop_pointer
= &nexthop
;
290 /* convert to be comprehensive by quagga */
291 /* convert given addresses */
292 uchar_to_in6addr(&babel_prefix_addr
, pref
);
293 uchar_to_in6addr(&nexthop
, gate
);
295 /* make prefix structure */
296 memset (&quagga_prefix
, 0, sizeof(quagga_prefix
));
297 quagga_prefix
.family
= AF_INET6
;
298 IPV6_ADDR_COPY (&quagga_prefix
.prefix
, &babel_prefix_addr
);
299 quagga_prefix
.prefixlen
= plen
;
300 apply_mask_ipv6(&quagga_prefix
);
302 api
.type
= ZEBRA_ROUTE_BABEL
;
305 SET_FLAG(api
.message
, ZAPI_MESSAGE_NEXTHOP
);
307 api
.nexthop
= &nexthop_pointer
;
308 SET_FLAG(api
.message
, ZAPI_MESSAGE_IFINDEX
);
310 api
.ifindex
= &tmp_ifindex
;
311 SET_FLAG(api
.message
, ZAPI_MESSAGE_METRIC
);
314 debugf(BABEL_DEBUG_ROUTE
, "adding route (ipv6) to zebra");
315 return zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD
, zclient
,
316 &quagga_prefix
, &api
);
320 kernel_route_delete_v4(const unsigned char *pref
, unsigned short plen
,
321 const unsigned char *gate
, int ifindex
,
323 const unsigned char *newgate
, int newifindex
,
324 unsigned int newmetric
)
326 unsigned int tmp_ifindex
= ifindex
; /* (for typing) */
327 struct zapi_ipv4 api
; /* quagga's communication system */
328 struct prefix_ipv4 quagga_prefix
; /* quagga's prefix */
329 struct in_addr babel_prefix_addr
; /* babeld's prefix addr */
330 struct in_addr nexthop
; /* next router to go */
331 struct in_addr
*nexthop_pointer
= &nexthop
; /* it's an array! */
333 /* convert to be comprehensive by quagga */
334 /* convert given addresses */
335 uchar_to_inaddr(&babel_prefix_addr
, pref
);
336 uchar_to_inaddr(&nexthop
, gate
);
338 /* make prefix structure */
339 memset (&quagga_prefix
, 0, sizeof(quagga_prefix
));
340 quagga_prefix
.family
= AF_INET
;
341 IPV4_ADDR_COPY (&quagga_prefix
.prefix
, &babel_prefix_addr
);
342 quagga_prefix
.prefixlen
= plen
- 96;
343 apply_mask_ipv4(&quagga_prefix
);
345 api
.type
= ZEBRA_ROUTE_BABEL
;
348 SET_FLAG(api
.message
, ZAPI_MESSAGE_NEXTHOP
);
350 api
.nexthop
= &nexthop_pointer
;
351 SET_FLAG(api
.message
, ZAPI_MESSAGE_IFINDEX
);
353 api
.ifindex
= &tmp_ifindex
;
354 SET_FLAG(api
.message
, ZAPI_MESSAGE_METRIC
);
357 debugf(BABEL_DEBUG_ROUTE
, "removing route (ipv4) to zebra");
358 return zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE
, zclient
,
359 &quagga_prefix
, &api
);
363 kernel_route_delete_v6(const unsigned char *pref
, unsigned short plen
,
364 const unsigned char *gate
, int ifindex
,
366 const unsigned char *newgate
, int newifindex
,
367 unsigned int newmetric
)
369 unsigned int tmp_ifindex
= ifindex
; /* (for typing) */
370 struct zapi_ipv6 api
; /* quagga's communication system */
371 struct prefix_ipv6 quagga_prefix
; /* quagga's prefix */
372 struct in6_addr babel_prefix_addr
; /* babeld's prefix addr */
373 struct in6_addr nexthop
; /* next router to go */
374 struct in6_addr
*nexthop_pointer
= &nexthop
;
376 /* convert to be comprehensive by quagga */
377 /* convert given addresses */
378 uchar_to_in6addr(&babel_prefix_addr
, pref
);
379 uchar_to_in6addr(&nexthop
, gate
);
381 /* make prefix structure */
382 memset (&quagga_prefix
, 0, sizeof(quagga_prefix
));
383 quagga_prefix
.family
= AF_INET6
;
384 IPV6_ADDR_COPY (&quagga_prefix
.prefix
, &babel_prefix_addr
);
385 quagga_prefix
.prefixlen
= plen
;
386 apply_mask_ipv6(&quagga_prefix
);
388 api
.type
= ZEBRA_ROUTE_BABEL
;
391 SET_FLAG(api
.message
, ZAPI_MESSAGE_NEXTHOP
);
393 api
.nexthop
= &nexthop_pointer
;
394 SET_FLAG(api
.message
, ZAPI_MESSAGE_IFINDEX
);
396 api
.ifindex
= &tmp_ifindex
;
398 debugf(BABEL_DEBUG_ROUTE
, "removing route (ipv6) to zebra");
399 return zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE
, zclient
,
400 &quagga_prefix
, &api
);
404 kernel_routes(struct kernel_route
*routes
, int maxroutes
)
406 fprintf(stderr
, "\tkernel_routes --- not implemented\n");
411 kernel_callback(int (*fn
)(int, void*), void *closure
)
413 struct thread thread
;
414 fprintf(stderr
, "\tkernel_callback\n");
415 /* do a little work on threads */
416 if (thread_fetch(master
, &thread
) != NULL
) {
417 thread_call (&thread
);
423 kernel_addresses(struct interface
*interface
, int ll
,
424 struct kernel_route
*routes
, int maxroutes
)
426 fprintf(stderr
, "\tkernel_addresses --- not implemented\n");
431 if_eui64(char *ifname
, int ifindex
, unsigned char *eui
)
433 struct interface
*ifp
= if_lookup_by_index(ifindex
);
437 #ifdef HAVE_STRUCT_SOCKADDR_DL
438 u_char len
= ifp
->sdl
.sdl_alen
;
439 char *tmp
= ifp
->sdl
.sdl_data
+ ifp
->sdl
.sdl_nlen
;
441 u_char len
= (u_char
) ifp
->hw_addr_len
;
442 char *tmp
= (void*) ifp
->hw_addr
;
447 } else if (len
== 6) {
451 memcpy(eui
+5, tmp
+3, 3);
452 } else if (len
> 8) {
455 memset(eui
, 0, 8 - len
);
456 memcpy(eui
+ 8 - len
, tmp
, len
);