]> git.proxmox.com Git - mirror_frr.git/blame - babeld/kernel.c
babeld: Remove comment (fixed by 64682f5e69).
[mirror_frr.git] / babeld / kernel.c
CommitLineData
ca10883e
DS
1/*
2Copyright 2007, 2008 by Grégoire Henry, Julien Cristau and Juliusz Chroboczek
3Copyright 2011, 2012 by Matthieu Boutier and Juliusz Chroboczek
4
5Permission is hereby granted, free of charge, to any person obtaining a copy
6of this software and associated documentation files (the "Software"), to deal
7in the Software without restriction, including without limitation the rights
8to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9copies of the Software, and to permit persons to whom the Software is
10furnished to do so, subject to the following conditions:
11
12The above copyright notice and this permission notice shall be included in
13all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21THE SOFTWARE.
22*/
23
24#include <sys/time.h>
25#include <sys/param.h>
26#include <time.h>
27
28#include "babeld.h"
29
30
31#include <sys/types.h>
32#include <sys/socket.h>
33#include <netinet/in.h>
34#include <netdb.h>
35#include <arpa/inet.h>
36
37#include <zebra.h>
38#include "prefix.h"
39#include "zclient.h"
40#include "kernel.h"
41#include "privs.h"
42#include "command.h"
43#include "vty.h"
44#include "memory.h"
45#include "thread.h"
46
47#include "util.h"
48#include "babel_interface.h"
49#include "babel_zebra.h"
50
51
52static int
53kernel_route_v4(int add, const unsigned char *pref, unsigned short plen,
54 const unsigned char *gate, int ifindex,
55 unsigned int metric);
56static int
57kernel_route_v6(int add, const unsigned char *pref, unsigned short plen,
58 const unsigned char *gate, int ifindex,
59 unsigned int metric);
60
61int
62kernel_interface_operational(struct interface *interface)
63{
64 return if_is_operative(interface);
65}
66
67int
68kernel_interface_mtu(struct interface *interface)
69{
70 return MIN(interface->mtu, interface->mtu6);
71}
72
73int
74kernel_interface_wireless(struct interface *interface)
75{
76 return 0;
77}
78
79int
80kernel_route(int operation, const unsigned char *pref, unsigned short plen,
81 const unsigned char *gate, int ifindex, unsigned int metric,
82 const unsigned char *newgate, int newifindex,
83 unsigned int newmetric)
84{
85 int rc;
86 int ipv4;
87
88 /* Check that the protocol family is consistent. */
89 if(plen >= 96 && v4mapped(pref)) {
90 if(!v4mapped(gate)) {
91 errno = EINVAL;
92 return -1;
93 }
94 ipv4 = 1;
95 } else {
96 if(v4mapped(gate)) {
97 errno = EINVAL;
98 return -1;
99 }
100 ipv4 = 0;
101 }
102
103 switch (operation) {
104 case ROUTE_ADD:
105 return ipv4 ?
106 kernel_route_v4(1, pref, plen, gate, ifindex, metric):
107 kernel_route_v6(1, pref, plen, gate, ifindex, metric);
108 break;
109 case ROUTE_FLUSH:
110 return ipv4 ?
111 kernel_route_v4(0, pref, plen, gate, ifindex, metric):
112 kernel_route_v6(0, pref, plen, gate, ifindex, metric);
113 break;
114 case ROUTE_MODIFY:
115 if(newmetric == metric && memcmp(newgate, gate, 16) == 0 &&
116 newifindex == ifindex)
117 return 0;
118 debugf(BABEL_DEBUG_ROUTE, "Modify route: delete old; add new.");
119 rc = ipv4 ?
120 kernel_route_v4(0, pref, plen, gate, ifindex, metric):
121 kernel_route_v6(0, pref, plen, gate, ifindex, metric);
122
123 if (rc < 0)
124 return -1;
125
126 rc = ipv4 ?
127 kernel_route_v4(1, pref, plen, newgate, newifindex, newmetric):
128 kernel_route_v6(1, pref, plen, newgate, newifindex, newmetric);
129
130 return rc;
131 break;
132 default:
133 zlog_err("this should never appens (false value - kernel_route)");
134 assert(0);
135 exit(1);
136 break;
137 }
138}
139
140static int
141kernel_route_v4(int add,
142 const unsigned char *pref, unsigned short plen,
143 const unsigned char *gate, int ifindex, unsigned int metric)
144{
145 struct zapi_ipv4 api; /* quagga's communication system */
146 struct prefix_ipv4 quagga_prefix; /* quagga's prefix */
147 struct in_addr babel_prefix_addr; /* babeld's prefix addr */
148 struct in_addr nexthop; /* next router to go */
149 struct in_addr *nexthop_pointer = &nexthop; /* it's an array! */
150
151 /* convert to be understandable by quagga */
152 /* convert given addresses */
153 uchar_to_inaddr(&babel_prefix_addr, pref);
154 uchar_to_inaddr(&nexthop, gate);
155
156 /* make prefix structure */
157 memset (&quagga_prefix, 0, sizeof(quagga_prefix));
158 quagga_prefix.family = AF_INET;
159 IPV4_ADDR_COPY (&quagga_prefix.prefix, &babel_prefix_addr);
160 quagga_prefix.prefixlen = plen - 96; /* our plen is for v4mapped's addr */
161 apply_mask_ipv4(&quagga_prefix);
162
e4d9c771 163 memset(&api, 0, sizeof(api));
ca10883e
DS
164 api.type = ZEBRA_ROUTE_BABEL;
165 api.flags = 0;
166 api.message = 0;
64682f5e 167 api.instance = 0;
ca10883e 168 api.safi = SAFI_UNICAST;
e4d9c771 169 api.vrf_id = VRF_DEFAULT;
ca10883e 170
ca10883e 171 SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
64682f5e 172 SET_FLAG(api.message, ZAPI_MESSAGE_IFINDEX);
ca10883e
DS
173 if(metric >= KERNEL_INFINITY) {
174 api.flags = ZEBRA_FLAG_REJECT;
175 api.nexthop_num = 0;
64682f5e 176 api.ifindex_num = 0;
ca10883e
DS
177 } else {
178 api.nexthop_num = 1;
64682f5e 179 api.ifindex_num = 1;
ca10883e 180 api.nexthop = &nexthop_pointer;
64682f5e 181 api.ifindex = &ifindex;
ca10883e
DS
182 SET_FLAG(api.message, ZAPI_MESSAGE_METRIC);
183 api.metric = metric;
184 }
185
186 debugf(BABEL_DEBUG_ROUTE, "%s route (ipv4) to zebra",
187 add ? "adding" : "removing" );
188 return zapi_ipv4_route (add ? ZEBRA_IPV4_ROUTE_ADD :
189 ZEBRA_IPV4_ROUTE_DELETE,
190 zclient, &quagga_prefix, &api);
191}
192
193static int
194kernel_route_v6(int add, const unsigned char *pref, unsigned short plen,
195 const unsigned char *gate, int ifindex, unsigned int metric)
196{
197 ifindex_t tmp_ifindex = ifindex; /* (for typing) */
198 struct zapi_ipv6 api; /* quagga's communication system */
199 struct prefix_ipv6 quagga_prefix; /* quagga's prefix */
200 struct in6_addr babel_prefix_addr; /* babeld's prefix addr */
201 struct in6_addr nexthop; /* next router to go */
202 struct in6_addr *nexthop_pointer = &nexthop;
203
204 /* convert to be understandable by quagga */
205 /* convert given addresses */
206 uchar_to_in6addr(&babel_prefix_addr, pref);
207 uchar_to_in6addr(&nexthop, gate);
208
209 /* make prefix structure */
210 memset (&quagga_prefix, 0, sizeof(quagga_prefix));
211 quagga_prefix.family = AF_INET6;
212 IPV6_ADDR_COPY (&quagga_prefix.prefix, &babel_prefix_addr);
213 quagga_prefix.prefixlen = plen;
214 apply_mask_ipv6(&quagga_prefix);
215
e4d9c771 216 memset(&api, 0, sizeof(api));
ca10883e
DS
217 api.type = ZEBRA_ROUTE_BABEL;
218 api.flags = 0;
219 api.message = 0;
09b4a7e5 220 api.instance = 0;
ca10883e 221 api.safi = SAFI_UNICAST;
e4d9c771
MB
222 api.vrf_id = VRF_DEFAULT;
223
ca10883e
DS
224 if(metric >= KERNEL_INFINITY) {
225 api.flags = ZEBRA_FLAG_REJECT;
226 api.nexthop_num = 0;
227 api.ifindex_num = 0;
228 } else {
229 SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
230 api.nexthop_num = 1;
231 api.nexthop = &nexthop_pointer;
232 SET_FLAG(api.message, ZAPI_MESSAGE_IFINDEX);
233 api.ifindex_num = 1;
234 api.ifindex = &tmp_ifindex;
235 SET_FLAG(api.message, ZAPI_MESSAGE_METRIC);
236 api.metric = metric;
237 }
238
239 debugf(BABEL_DEBUG_ROUTE, "%s route (ipv6) to zebra",
240 add ? "adding" : "removing" );
241 return zapi_ipv6_route (add ? ZEBRA_IPV6_ROUTE_ADD :
242 ZEBRA_IPV6_ROUTE_DELETE,
243 zclient, &quagga_prefix, NULL, &api);
244}
245
246int
247if_eui64(char *ifname, int ifindex, unsigned char *eui)
248{
249 struct interface *ifp = if_lookup_by_index(ifindex, VRF_DEFAULT);
250 if (ifp == NULL) {
251 return -1;
252 }
253#ifdef HAVE_STRUCT_SOCKADDR_DL
254 u_char len = ifp->sdl.sdl_alen;
255 char *tmp = ifp->sdl.sdl_data + ifp->sdl.sdl_nlen;
256#else
257 u_char len = (u_char) ifp->hw_addr_len;
258 char *tmp = (void*) ifp->hw_addr;
259#endif
260 if (len == 8) {
261 memcpy(eui, tmp, 8);
262 eui[0] ^= 2;
263 } else if (len == 6) {
264 memcpy(eui, tmp, 3);
265 eui[3] = 0xFF;
266 eui[4] = 0xFE;
267 memcpy(eui+5, tmp+3, 3);
268 } else {
269 return -1;
270 }
271 return 0;
272}
273
274/* Like gettimeofday, but returns monotonic time. If POSIX clocks are not
275 available, falls back to gettimeofday but enforces monotonicity. */
276int
277gettime(struct timeval *tv)
278{
279 return monotime(tv);
280}
281
282/* If /dev/urandom doesn't exist, this will fail with ENOENT, which the
283 caller will deal with gracefully. */
284
285int
286read_random_bytes(void *buf, size_t len)
287{
288 int fd;
289 int rc;
290
291 fd = open("/dev/urandom", O_RDONLY);
292 if(fd < 0) {
293 rc = -1;
294 } else {
295 rc = read(fd, buf, len);
296 if(rc < 0 || (unsigned) rc < len)
297 rc = -1;
298 close(fd);
299 }
300 return rc;
301}