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 zebra_route(int add
, int familt
, const unsigned char *pref
, unsigned short plen
,
55 const unsigned char *gate
, int ifindex
, unsigned int metric
);
58 kernel_interface_operational(struct interface
*interface
)
60 return if_is_operative(interface
);
64 kernel_interface_mtu(struct interface
*interface
)
66 return MIN(interface
->mtu
, interface
->mtu6
);
70 kernel_interface_wireless(struct interface
*interface
)
76 kernel_route(int operation
, const unsigned char *pref
, unsigned short plen
,
77 const unsigned char *gate
, int ifindex
, unsigned int metric
,
78 const unsigned char *newgate
, int newifindex
,
79 unsigned int newmetric
)
84 /* Check that the protocol family is consistent. */
85 if(plen
>= 96 && v4mapped(pref
)) {
101 return zebra_route(1, family
, pref
, plen
, gate
, ifindex
, metric
);
104 return zebra_route(0, family
, pref
, plen
, gate
, ifindex
, metric
);
107 if(newmetric
== metric
&& memcmp(newgate
, gate
, 16) == 0 &&
108 newifindex
== ifindex
)
110 debugf(BABEL_DEBUG_ROUTE
, "Modify route: delete old; add new.");
111 rc
= zebra_route(0, family
, pref
, plen
, gate
, ifindex
, metric
);
115 rc
= zebra_route(1, family
, pref
, plen
, newgate
, newifindex
,
120 zlog_err("this should never happen (false value - kernel_route)");
128 zebra_route(int add
, int family
, const unsigned char *pref
, unsigned short plen
,
129 const unsigned char *gate
, int ifindex
, unsigned int metric
)
131 struct zapi_route api
; /* quagga's communication system */
132 struct prefix quagga_prefix
; /* quagga's prefix */
133 union g_addr babel_prefix_addr
; /* babeld's prefix addr */
134 struct zapi_nexthop
*api_nh
; /* next router to go - no ECMP */
136 api_nh
= &api
.nexthops
[0];
138 /* convert to be understandable by quagga */
139 /* convert given addresses */
142 uchar_to_inaddr(&babel_prefix_addr
.ipv4
, pref
);
145 uchar_to_in6addr(&babel_prefix_addr
.ipv6
, pref
);
149 /* make prefix structure */
150 memset (&quagga_prefix
, 0, sizeof(quagga_prefix
));
151 quagga_prefix
.family
= family
;
154 IPV4_ADDR_COPY (&quagga_prefix
.u
.prefix4
, &babel_prefix_addr
.ipv4
);
155 /* our plen is for v4mapped's addr */
156 quagga_prefix
.prefixlen
= plen
- 96;
159 IPV6_ADDR_COPY (&quagga_prefix
.u
.prefix6
, &babel_prefix_addr
.ipv6
);
160 quagga_prefix
.prefixlen
= plen
;
163 apply_mask(&quagga_prefix
);
165 memset(&api
, 0, sizeof(api
));
166 api
.type
= ZEBRA_ROUTE_BABEL
;
167 api
.safi
= SAFI_UNICAST
;
168 api
.vrf_id
= VRF_DEFAULT
;
169 api
.prefix
= quagga_prefix
;
171 if(metric
>= KERNEL_INFINITY
) {
172 zapi_route_set_blackhole(&api
, BLACKHOLE_REJECT
);
174 SET_FLAG(api
.message
, ZAPI_MESSAGE_NEXTHOP
);
176 api_nh
->ifindex
= ifindex
;
177 api_nh
->vrf_id
= VRF_DEFAULT
;
180 uchar_to_inaddr(&api_nh
->gate
.ipv4
, gate
);
181 if (IPV4_ADDR_SAME (&api_nh
->gate
.ipv4
, &quagga_prefix
.u
.prefix4
) &&
182 quagga_prefix
.prefixlen
== 32) {
183 api_nh
->type
= NEXTHOP_TYPE_IFINDEX
;
185 api_nh
->type
= NEXTHOP_TYPE_IPV4_IFINDEX
;
189 uchar_to_in6addr(&api_nh
->gate
.ipv6
, gate
);
190 /* difference to IPv4: always leave the linklocal as nexthop */
191 api_nh
->type
= NEXTHOP_TYPE_IPV6_IFINDEX
;
194 SET_FLAG(api
.message
, ZAPI_MESSAGE_METRIC
);
198 debugf(BABEL_DEBUG_ROUTE
, "%s route (%s) to zebra",
199 add
? "adding" : "removing",
200 (family
== AF_INET
) ? "ipv4" : "ipv6");
201 return zclient_route_send (add
? ZEBRA_ROUTE_ADD
: ZEBRA_ROUTE_DELETE
,
206 if_eui64(int ifindex
, unsigned char *eui
)
208 struct interface
*ifp
= if_lookup_by_index(ifindex
, VRF_DEFAULT
);
213 uint8_t len
= (uint8_t)ifp
->hw_addr_len
;
214 char *tmp
= (void*) ifp
->hw_addr
;
219 } else if (len
== 6) {
223 memcpy(eui
+5, tmp
+3, 3);
230 /* Like gettimeofday, but returns monotonic time. If POSIX clocks are not
231 available, falls back to gettimeofday but enforces monotonicity. */
233 gettime(struct timeval
*tv
)
238 /* If /dev/urandom doesn't exist, this will fail with ENOENT, which the
239 caller will deal with gracefully. */
242 read_random_bytes(void *buf
, size_t len
)
247 fd
= open("/dev/urandom", O_RDONLY
);
251 rc
= read(fd
, buf
, len
);
252 if(rc
< 0 || (unsigned) rc
< len
)