1 // SPDX-License-Identifier: MIT
3 Copyright 2007, 2008 by Grégoire Henry, Julien Cristau and Juliusz Chroboczek
4 Copyright 2011, 2012 by Matthieu Boutier and Juliusz Chroboczek
12 #include <sys/param.h>
18 #include <sys/types.h>
19 #include <sys/socket.h>
20 #include <netinet/in.h>
22 #include <arpa/inet.h>
36 #include "babel_interface.h"
37 #include "babel_zebra.h"
41 zebra_route(int add
, int familt
, const unsigned char *pref
, unsigned short plen
,
42 const unsigned char *gate
, int ifindex
, unsigned int metric
);
45 kernel_interface_operational(struct interface
*interface
)
47 return if_is_operative(interface
);
51 kernel_interface_mtu(struct interface
*interface
)
53 return MIN(interface
->mtu
, interface
->mtu6
);
57 kernel_interface_wireless(struct interface
*interface
)
63 kernel_route(enum babel_kernel_routes operation
, const unsigned char *pref
,
64 unsigned short plen
, const unsigned char *gate
, int ifindex
,
65 unsigned int metric
, const unsigned char *newgate
, int newifindex
,
66 unsigned int newmetric
)
71 /* Check that the protocol family is consistent. */
72 if(plen
>= 96 && v4mapped(pref
)) {
88 return zebra_route(1, family
, pref
, plen
, gate
, ifindex
, metric
);
90 return zebra_route(0, family
, pref
, plen
, gate
, ifindex
, metric
);
92 if(newmetric
== metric
&& memcmp(newgate
, gate
, 16) == 0 &&
93 newifindex
== ifindex
)
95 debugf(BABEL_DEBUG_ROUTE
, "Modify route: delete old; add new.");
96 rc
= zebra_route(0, family
, pref
, plen
, gate
, ifindex
, metric
);
100 rc
= zebra_route(1, family
, pref
, plen
, newgate
, newifindex
,
109 zebra_route(int add
, int family
, const unsigned char *pref
, unsigned short plen
,
110 const unsigned char *gate
, int ifindex
, unsigned int metric
)
112 struct zapi_route api
; /* quagga's communication system */
113 struct prefix quagga_prefix
; /* quagga's prefix */
114 union g_addr babel_prefix_addr
; /* babeld's prefix addr */
115 struct zapi_nexthop
*api_nh
; /* next router to go - no ECMP */
117 api_nh
= &api
.nexthops
[0];
119 /* convert to be understandable by quagga */
120 /* convert given addresses */
123 uchar_to_inaddr(&babel_prefix_addr
.ipv4
, pref
);
126 uchar_to_in6addr(&babel_prefix_addr
.ipv6
, pref
);
130 /* make prefix structure */
131 memset (&quagga_prefix
, 0, sizeof(quagga_prefix
));
132 quagga_prefix
.family
= family
;
135 IPV4_ADDR_COPY (&quagga_prefix
.u
.prefix4
, &babel_prefix_addr
.ipv4
);
136 /* our plen is for v4mapped's addr */
137 quagga_prefix
.prefixlen
= plen
- 96;
140 IPV6_ADDR_COPY (&quagga_prefix
.u
.prefix6
, &babel_prefix_addr
.ipv6
);
141 quagga_prefix
.prefixlen
= plen
;
144 apply_mask(&quagga_prefix
);
146 memset(&api
, 0, sizeof(api
));
147 api
.type
= ZEBRA_ROUTE_BABEL
;
148 api
.safi
= SAFI_UNICAST
;
149 api
.vrf_id
= VRF_DEFAULT
;
150 api
.prefix
= quagga_prefix
;
152 if(metric
>= KERNEL_INFINITY
) {
153 zapi_route_set_blackhole(&api
, BLACKHOLE_REJECT
);
155 SET_FLAG(api
.message
, ZAPI_MESSAGE_NEXTHOP
);
157 api_nh
->ifindex
= ifindex
;
158 api_nh
->vrf_id
= VRF_DEFAULT
;
161 uchar_to_inaddr(&api_nh
->gate
.ipv4
, gate
);
162 if (IPV4_ADDR_SAME(&api_nh
->gate
.ipv4
, &quagga_prefix
.u
.prefix4
)
163 && quagga_prefix
.prefixlen
== IPV4_MAX_BITLEN
) {
164 api_nh
->type
= NEXTHOP_TYPE_IFINDEX
;
166 api_nh
->type
= NEXTHOP_TYPE_IPV4_IFINDEX
;
170 uchar_to_in6addr(&api_nh
->gate
.ipv6
, gate
);
171 /* difference to IPv4: always leave the linklocal as nexthop */
172 api_nh
->type
= NEXTHOP_TYPE_IPV6_IFINDEX
;
175 SET_FLAG(api
.message
, ZAPI_MESSAGE_METRIC
);
179 debugf(BABEL_DEBUG_ROUTE
, "%s route (%s) to zebra",
180 add
? "adding" : "removing",
181 (family
== AF_INET
) ? "ipv4" : "ipv6");
182 return zclient_route_send (add
? ZEBRA_ROUTE_ADD
: ZEBRA_ROUTE_DELETE
,
187 if_eui64(int ifindex
, unsigned char *eui
)
189 struct interface
*ifp
= if_lookup_by_index(ifindex
, VRF_DEFAULT
);
194 uint8_t len
= (uint8_t)ifp
->hw_addr_len
;
195 char *tmp
= (void*) ifp
->hw_addr
;
200 } else if (len
== 6) {
204 memcpy(eui
+5, tmp
+3, 3);
211 /* Like gettimeofday, but returns monotonic time. If POSIX clocks are not
212 available, falls back to gettimeofday but enforces monotonicity. */
214 gettime(struct timeval
*tv
)
219 /* If /dev/urandom doesn't exist, this will fail with ENOENT, which the
220 caller will deal with gracefully. */
223 read_random_bytes(void *buf
, size_t len
)
228 fd
= open("/dev/urandom", O_RDONLY
);
232 rc
= read(fd
, buf
, len
);
233 if(rc
< 0 || (unsigned) rc
< len
)