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 nexthop
.type
= NEXTHOP_TYPE_IPV4_IFINDEX
;
181 SET_FLAG(api
.message
, ZAPI_MESSAGE_METRIC
);
185 debugf(BABEL_DEBUG_ROUTE
, "%s route (ipv4) to zebra",
186 add
? "adding" : "removing" );
187 return zapi_route (add
? ZEBRA_IPV4_ROUTE_ADD
:
188 ZEBRA_IPV4_ROUTE_DELETE
,
189 zclient
, &quagga_prefix
, NULL
, &api
);
193 kernel_route_v6(int add
, const unsigned char *pref
, unsigned short plen
,
194 const unsigned char *gate
, int ifindex
, unsigned int metric
)
196 struct zapi_route api
; /* quagga's communication system */
197 struct prefix quagga_prefix
; /* quagga's prefix */
198 struct in6_addr babel_prefix_addr
; /* babeld's prefix addr */
199 struct nexthop nexthop
; /* next router to go */
200 struct nexthop
*nexthop_pointer
= &nexthop
;
202 /* convert to be understandable by quagga */
203 /* convert given addresses */
204 uchar_to_in6addr(&babel_prefix_addr
, pref
);
205 uchar_to_in6addr(&nexthop
.gate
.ipv6
, gate
);
207 /* make prefix structure */
208 memset (&quagga_prefix
, 0, sizeof(quagga_prefix
));
209 quagga_prefix
.family
= AF_INET6
;
210 IPV6_ADDR_COPY (&quagga_prefix
.u
.prefix6
, &babel_prefix_addr
);
211 quagga_prefix
.prefixlen
= plen
;
212 apply_mask(&quagga_prefix
);
214 memset(&api
, 0, sizeof(api
));
215 api
.type
= ZEBRA_ROUTE_BABEL
;
219 api
.safi
= SAFI_UNICAST
;
220 api
.vrf_id
= VRF_DEFAULT
;
222 if(metric
>= KERNEL_INFINITY
) {
223 api
.flags
= ZEBRA_FLAG_REJECT
;
226 SET_FLAG(api
.message
, ZAPI_MESSAGE_NEXTHOP
);
228 api
.nexthop
= &nexthop_pointer
;
229 nexthop
.ifindex
= ifindex
;
230 nexthop
.type
= NEXTHOP_TYPE_IPV6_IFINDEX
;
231 SET_FLAG(api
.message
, ZAPI_MESSAGE_METRIC
);
235 debugf(BABEL_DEBUG_ROUTE
, "%s route (ipv6) to zebra",
236 add
? "adding" : "removing" );
237 return zapi_route (add
? ZEBRA_IPV6_ROUTE_ADD
:
238 ZEBRA_IPV6_ROUTE_DELETE
,
239 zclient
, &quagga_prefix
, NULL
, &api
);
243 if_eui64(char *ifname
, int ifindex
, unsigned char *eui
)
245 struct interface
*ifp
= if_lookup_by_index(ifindex
, VRF_DEFAULT
);
250 u_char len
= (u_char
) ifp
->hw_addr_len
;
251 char *tmp
= (void*) ifp
->hw_addr
;
256 } else if (len
== 6) {
260 memcpy(eui
+5, tmp
+3, 3);
267 /* Like gettimeofday, but returns monotonic time. If POSIX clocks are not
268 available, falls back to gettimeofday but enforces monotonicity. */
270 gettime(struct timeval
*tv
)
275 /* If /dev/urandom doesn't exist, this will fail with ENOENT, which the
276 caller will deal with gracefully. */
279 read_random_bytes(void *buf
, size_t len
)
284 fd
= open("/dev/urandom", O_RDONLY
);
288 rc
= read(fd
, buf
, len
);
289 if(rc
< 0 || (unsigned) rc
< len
)