]> git.proxmox.com Git - mirror_frr.git/blame - babeld/kernel.c
Merge branch 'master' into bfd-final
[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"
98c02f4c 46#include "nexthop.h"
ca10883e
DS
47
48#include "util.h"
49#include "babel_interface.h"
50#include "babel_zebra.h"
51
52
53static int
c8f9e916
RW
54zebra_route(int add, int familt, const unsigned char *pref, unsigned short plen,
55 const unsigned char *gate, int ifindex, unsigned int metric);
ca10883e
DS
56
57int
58kernel_interface_operational(struct interface *interface)
59{
60 return if_is_operative(interface);
61}
62
63int
64kernel_interface_mtu(struct interface *interface)
65{
66 return MIN(interface->mtu, interface->mtu6);
67}
68
69int
70kernel_interface_wireless(struct interface *interface)
71{
72 return 0;
73}
74
75int
e8c8f2e0
DS
76kernel_route(enum babel_kernel_routes operation, const unsigned char *pref,
77 unsigned short plen, const unsigned char *gate, int ifindex,
78 unsigned int metric, const unsigned char *newgate, int newifindex,
ca10883e
DS
79 unsigned int newmetric)
80{
81 int rc;
c8f9e916 82 int family;
ca10883e
DS
83
84 /* Check that the protocol family is consistent. */
85 if(plen >= 96 && v4mapped(pref)) {
86 if(!v4mapped(gate)) {
87 errno = EINVAL;
88 return -1;
89 }
c8f9e916 90 family = AF_INET;
ca10883e
DS
91 } else {
92 if(v4mapped(gate)) {
93 errno = EINVAL;
94 return -1;
95 }
c8f9e916 96 family = AF_INET6;
ca10883e
DS
97 }
98
99 switch (operation) {
100 case ROUTE_ADD:
c8f9e916 101 return zebra_route(1, family, pref, plen, gate, ifindex, metric);
ca10883e
DS
102 break;
103 case ROUTE_FLUSH:
c8f9e916 104 return zebra_route(0, family, pref, plen, gate, ifindex, metric);
ca10883e
DS
105 break;
106 case ROUTE_MODIFY:
107 if(newmetric == metric && memcmp(newgate, gate, 16) == 0 &&
108 newifindex == ifindex)
109 return 0;
110 debugf(BABEL_DEBUG_ROUTE, "Modify route: delete old; add new.");
c8f9e916 111 rc = zebra_route(0, family, pref, plen, gate, ifindex, metric);
ca10883e
DS
112 if (rc < 0)
113 return -1;
114
c8f9e916
RW
115 rc = zebra_route(1, family, pref, plen, newgate, newifindex,
116 newmetric);
ca10883e
DS
117 return rc;
118 break;
ca10883e 119 }
e8c8f2e0
DS
120
121 return 0;
ca10883e
DS
122}
123
124static int
c8f9e916
RW
125zebra_route(int add, int family, const unsigned char *pref, unsigned short plen,
126 const unsigned char *gate, int ifindex, unsigned int metric)
ca10883e 127{
98c02f4c
DS
128 struct zapi_route api; /* quagga's communication system */
129 struct prefix quagga_prefix; /* quagga's prefix */
c8f9e916
RW
130 union g_addr babel_prefix_addr; /* babeld's prefix addr */
131 struct zapi_nexthop *api_nh; /* next router to go - no ECMP */
bb1b9c47
RW
132
133 api_nh = &api.nexthops[0];
ca10883e
DS
134
135 /* convert to be understandable by quagga */
136 /* convert given addresses */
c8f9e916
RW
137 switch (family) {
138 case AF_INET:
139 uchar_to_inaddr(&babel_prefix_addr.ipv4, pref);
140 break;
141 case AF_INET6:
142 uchar_to_in6addr(&babel_prefix_addr.ipv6, pref);
143 break;
ca10883e
DS
144 }
145
ca10883e
DS
146 /* make prefix structure */
147 memset (&quagga_prefix, 0, sizeof(quagga_prefix));
c8f9e916
RW
148 quagga_prefix.family = family;
149 switch (family) {
150 case AF_INET:
151 IPV4_ADDR_COPY (&quagga_prefix.u.prefix4, &babel_prefix_addr.ipv4);
152 /* our plen is for v4mapped's addr */
153 quagga_prefix.prefixlen = plen - 96;
154 break;
155 case AF_INET6:
156 IPV6_ADDR_COPY (&quagga_prefix.u.prefix6, &babel_prefix_addr.ipv6);
157 quagga_prefix.prefixlen = plen;
158 break;
159 }
98c02f4c 160 apply_mask(&quagga_prefix);
ca10883e 161
e4d9c771 162 memset(&api, 0, sizeof(api));
ca10883e 163 api.type = ZEBRA_ROUTE_BABEL;
ca10883e 164 api.safi = SAFI_UNICAST;
e4d9c771 165 api.vrf_id = VRF_DEFAULT;
bb1b9c47 166 api.prefix = quagga_prefix;
e4d9c771 167
ca10883e 168 if(metric >= KERNEL_INFINITY) {
09a484dd 169 zapi_route_set_blackhole(&api, BLACKHOLE_REJECT);
ca10883e
DS
170 } else {
171 SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
172 api.nexthop_num = 1;
bb1b9c47 173 api_nh->ifindex = ifindex;
4a7371e9
DS
174 api_nh->vrf_id = VRF_DEFAULT;
175 switch (family) {
c8f9e916
RW
176 case AF_INET:
177 uchar_to_inaddr(&api_nh->gate.ipv4, gate);
178 if (IPV4_ADDR_SAME (&api_nh->gate.ipv4, &quagga_prefix.u.prefix4) &&
179 quagga_prefix.prefixlen == 32) {
180 api_nh->type = NEXTHOP_TYPE_IFINDEX;
181 } else {
182 api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX;
183 }
184 break;
185 case AF_INET6:
186 uchar_to_in6addr(&api_nh->gate.ipv6, gate);
187 /* difference to IPv4: always leave the linklocal as nexthop */
188 api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX;
189 break;
190 }
ca10883e
DS
191 SET_FLAG(api.message, ZAPI_MESSAGE_METRIC);
192 api.metric = metric;
193 }
194
c8f9e916
RW
195 debugf(BABEL_DEBUG_ROUTE, "%s route (%s) to zebra",
196 add ? "adding" : "removing",
197 (family == AF_INET) ? "ipv4" : "ipv6");
0e51b4a3
RW
198 return zclient_route_send (add ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE,
199 zclient, &api);
ca10883e
DS
200}
201
202int
edb1d4a0 203if_eui64(int ifindex, unsigned char *eui)
ca10883e
DS
204{
205 struct interface *ifp = if_lookup_by_index(ifindex, VRF_DEFAULT);
206 if (ifp == NULL) {
207 return -1;
208 }
7217de2d 209
d7c0a89a 210 uint8_t len = (uint8_t)ifp->hw_addr_len;
ca10883e 211 char *tmp = (void*) ifp->hw_addr;
7217de2d 212
ca10883e
DS
213 if (len == 8) {
214 memcpy(eui, tmp, 8);
215 eui[0] ^= 2;
216 } else if (len == 6) {
217 memcpy(eui, tmp, 3);
218 eui[3] = 0xFF;
219 eui[4] = 0xFE;
220 memcpy(eui+5, tmp+3, 3);
221 } else {
222 return -1;
223 }
224 return 0;
225}
226
227/* Like gettimeofday, but returns monotonic time. If POSIX clocks are not
228 available, falls back to gettimeofday but enforces monotonicity. */
229int
230gettime(struct timeval *tv)
231{
232 return monotime(tv);
233}
234
235/* If /dev/urandom doesn't exist, this will fail with ENOENT, which the
236 caller will deal with gracefully. */
237
238int
239read_random_bytes(void *buf, size_t len)
240{
241 int fd;
242 int rc;
243
244 fd = open("/dev/urandom", O_RDONLY);
245 if(fd < 0) {
246 rc = -1;
247 } else {
248 rc = read(fd, buf, len);
249 if(rc < 0 || (unsigned) rc < len)
250 rc = -1;
251 close(fd);
252 }
253 return rc;
254}