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