2 Copyright 2007, 2008 by Grégoire Henry, Julien Cristau and Juliusz Chroboczek
3 Copyright 2011, 2012 by Matthieu Boutier and Juliusz Chroboczek
5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 of this software and associated documentation files (the "Software"), to deal
7 in the Software without restriction, including without limitation the rights
8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 copies of the Software, and to permit persons to whom the Software is
10 furnished to do so, subject to the following conditions:
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 #include <sys/param.h>
31 #include <sys/types.h>
32 #include <sys/socket.h>
33 #include <netinet/in.h>
35 #include <arpa/inet.h>
49 #include "babel_interface.h"
50 #include "babel_zebra.h"
54 kernel_route_v4(int add
, const unsigned char *pref
, unsigned short plen
,
55 const unsigned char *gate
, int ifindex
,
58 kernel_route_v6(int add
, const unsigned char *pref
, unsigned short plen
,
59 const unsigned char *gate
, int ifindex
,
63 kernel_interface_operational(struct interface
*interface
)
65 return if_is_operative(interface
);
69 kernel_interface_mtu(struct interface
*interface
)
71 return MIN(interface
->mtu
, interface
->mtu6
);
75 kernel_interface_wireless(struct interface
*interface
)
81 kernel_route(int operation
, const unsigned char *pref
, unsigned short plen
,
82 const unsigned char *gate
, int ifindex
, unsigned int metric
,
83 const unsigned char *newgate
, int newifindex
,
84 unsigned int newmetric
)
89 /* Check that the protocol family is consistent. */
90 if(plen
>= 96 && v4mapped(pref
)) {
107 kernel_route_v4(1, pref
, plen
, gate
, ifindex
, metric
):
108 kernel_route_v6(1, pref
, plen
, gate
, ifindex
, metric
);
112 kernel_route_v4(0, pref
, plen
, gate
, ifindex
, metric
):
113 kernel_route_v6(0, pref
, plen
, gate
, ifindex
, metric
);
116 if(newmetric
== metric
&& memcmp(newgate
, gate
, 16) == 0 &&
117 newifindex
== ifindex
)
119 debugf(BABEL_DEBUG_ROUTE
, "Modify route: delete old; add new.");
121 kernel_route_v4(0, pref
, plen
, gate
, ifindex
, metric
):
122 kernel_route_v6(0, pref
, plen
, gate
, ifindex
, metric
);
128 kernel_route_v4(1, pref
, plen
, newgate
, newifindex
, newmetric
):
129 kernel_route_v6(1, pref
, plen
, newgate
, newifindex
, newmetric
);
134 zlog_err("this should never appens (false value - kernel_route)");
142 kernel_route_v4(int add
,
143 const unsigned char *pref
, unsigned short plen
,
144 const unsigned char *gate
, int ifindex
, unsigned int metric
)
146 struct zapi_route api
; /* quagga's communication system */
147 struct prefix quagga_prefix
; /* quagga's prefix */
148 struct in_addr babel_prefix_addr
; /* babeld's prefix addr */
149 struct nexthop nexthop
; /* next router to go */
150 struct nexthop
*nexthop_pointer
= &nexthop
; /* it's an array! */
152 /* convert to be understandable by quagga */
153 /* convert given addresses */
154 uchar_to_inaddr(&babel_prefix_addr
, pref
);
155 uchar_to_inaddr(&nexthop
.gate
.ipv4
, gate
);
157 /* make prefix structure */
158 memset (&quagga_prefix
, 0, sizeof(quagga_prefix
));
159 quagga_prefix
.family
= AF_INET
;
160 IPV4_ADDR_COPY (&quagga_prefix
.u
.prefix4
, &babel_prefix_addr
);
161 quagga_prefix
.prefixlen
= plen
- 96; /* our plen is for v4mapped's addr */
162 apply_mask(&quagga_prefix
);
164 memset(&api
, 0, sizeof(api
));
165 api
.type
= ZEBRA_ROUTE_BABEL
;
169 api
.safi
= SAFI_UNICAST
;
170 api
.vrf_id
= VRF_DEFAULT
;
172 SET_FLAG(api
.message
, ZAPI_MESSAGE_NEXTHOP
);
173 if(metric
>= KERNEL_INFINITY
) {
174 api
.flags
= ZEBRA_FLAG_REJECT
;
178 api
.nexthop
= &nexthop_pointer
;
179 nexthop
.ifindex
= ifindex
;
180 if (IPV4_ADDR_SAME (&nexthop
.gate
.ipv4
, &quagga_prefix
.u
.prefix4
) &&
181 quagga_prefix
.prefixlen
== 32) {
182 nexthop
.type
= NEXTHOP_TYPE_IFINDEX
;
184 nexthop
.type
= NEXTHOP_TYPE_IPV4_IFINDEX
;
186 SET_FLAG(api
.message
, ZAPI_MESSAGE_METRIC
);
190 debugf(BABEL_DEBUG_ROUTE
, "%s route (ipv4) to zebra",
191 add
? "adding" : "removing" );
192 return zapi_route (add
? ZEBRA_IPV4_ROUTE_ADD
:
193 ZEBRA_IPV4_ROUTE_DELETE
,
194 zclient
, &quagga_prefix
, NULL
, &api
);
198 kernel_route_v6(int add
, const unsigned char *pref
, unsigned short plen
,
199 const unsigned char *gate
, int ifindex
, unsigned int metric
)
201 struct zapi_route api
; /* quagga's communication system */
202 struct prefix quagga_prefix
; /* quagga's prefix */
203 struct in6_addr babel_prefix_addr
; /* babeld's prefix addr */
204 struct nexthop nexthop
; /* next router to go */
205 struct nexthop
*nexthop_pointer
= &nexthop
;
207 /* convert to be understandable by quagga */
208 /* convert given addresses */
209 uchar_to_in6addr(&babel_prefix_addr
, pref
);
210 uchar_to_in6addr(&nexthop
.gate
.ipv6
, gate
);
212 /* make prefix structure */
213 memset (&quagga_prefix
, 0, sizeof(quagga_prefix
));
214 quagga_prefix
.family
= AF_INET6
;
215 IPV6_ADDR_COPY (&quagga_prefix
.u
.prefix6
, &babel_prefix_addr
);
216 quagga_prefix
.prefixlen
= plen
;
217 apply_mask(&quagga_prefix
);
219 memset(&api
, 0, sizeof(api
));
220 api
.type
= ZEBRA_ROUTE_BABEL
;
224 api
.safi
= SAFI_UNICAST
;
225 api
.vrf_id
= VRF_DEFAULT
;
227 if(metric
>= KERNEL_INFINITY
) {
228 api
.flags
= ZEBRA_FLAG_REJECT
;
231 SET_FLAG(api
.message
, ZAPI_MESSAGE_NEXTHOP
);
233 api
.nexthop
= &nexthop_pointer
;
234 nexthop
.ifindex
= ifindex
;
235 /* difference to IPv4: always leave the linklocal as nexthop */
236 nexthop
.type
= NEXTHOP_TYPE_IPV6_IFINDEX
;
237 SET_FLAG(api
.message
, ZAPI_MESSAGE_METRIC
);
241 debugf(BABEL_DEBUG_ROUTE
, "%s route (ipv6) to zebra",
242 add
? "adding" : "removing" );
243 return zapi_route (add
? ZEBRA_IPV6_ROUTE_ADD
:
244 ZEBRA_IPV6_ROUTE_DELETE
,
245 zclient
, &quagga_prefix
, NULL
, &api
);
249 if_eui64(char *ifname
, int ifindex
, unsigned char *eui
)
251 struct interface
*ifp
= if_lookup_by_index(ifindex
, VRF_DEFAULT
);
256 u_char len
= (u_char
) ifp
->hw_addr_len
;
257 char *tmp
= (void*) ifp
->hw_addr
;
262 } else if (len
== 6) {
266 memcpy(eui
+5, tmp
+3, 3);
273 /* Like gettimeofday, but returns monotonic time. If POSIX clocks are not
274 available, falls back to gettimeofday but enforces monotonicity. */
276 gettime(struct timeval
*tv
)
281 /* If /dev/urandom doesn't exist, this will fail with ENOENT, which the
282 caller will deal with gracefully. */
285 read_random_bytes(void *buf
, size_t len
)
290 fd
= open("/dev/urandom", O_RDONLY
);
294 rc
= read(fd
, buf
, len
);
295 if(rc
< 0 || (unsigned) rc
< len
)