]> git.proxmox.com Git - mirror_frr.git/blame_incremental - babeld/kernel.c
bgpd: add debug routine to display which PBR entry is handled
[mirror_frr.git] / babeld / kernel.c
... / ...
CommitLineData
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#include "nexthop.h"
47
48#include "util.h"
49#include "babel_interface.h"
50#include "babel_zebra.h"
51
52
53static int
54zebra_route(int add, int familt, const unsigned char *pref, unsigned short plen,
55 const unsigned char *gate, int ifindex, unsigned int metric);
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
76kernel_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)
80{
81 int rc;
82 int family;
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 }
90 family = AF_INET;
91 } else {
92 if(v4mapped(gate)) {
93 errno = EINVAL;
94 return -1;
95 }
96 family = AF_INET6;
97 }
98
99 switch (operation) {
100 case ROUTE_ADD:
101 return zebra_route(1, family, pref, plen, gate, ifindex, metric);
102 break;
103 case ROUTE_FLUSH:
104 return zebra_route(0, family, pref, plen, gate, ifindex, metric);
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.");
111 rc = zebra_route(0, family, pref, plen, gate, ifindex, metric);
112 if (rc < 0)
113 return -1;
114
115 rc = zebra_route(1, family, pref, plen, newgate, newifindex,
116 newmetric);
117 return rc;
118 break;
119 default:
120 zlog_err("this should never happen (false value - kernel_route)");
121 assert(0);
122 exit(1);
123 break;
124 }
125}
126
127static int
128zebra_route(int add, int family, const unsigned char *pref, unsigned short plen,
129 const unsigned char *gate, int ifindex, unsigned int metric)
130{
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 */
135
136 api_nh = &api.nexthops[0];
137
138 /* convert to be understandable by quagga */
139 /* convert given addresses */
140 switch (family) {
141 case AF_INET:
142 uchar_to_inaddr(&babel_prefix_addr.ipv4, pref);
143 break;
144 case AF_INET6:
145 uchar_to_in6addr(&babel_prefix_addr.ipv6, pref);
146 break;
147 }
148
149 /* make prefix structure */
150 memset (&quagga_prefix, 0, sizeof(quagga_prefix));
151 quagga_prefix.family = family;
152 switch (family) {
153 case AF_INET:
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;
157 break;
158 case AF_INET6:
159 IPV6_ADDR_COPY (&quagga_prefix.u.prefix6, &babel_prefix_addr.ipv6);
160 quagga_prefix.prefixlen = plen;
161 break;
162 }
163 apply_mask(&quagga_prefix);
164
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;
170
171 if(metric >= KERNEL_INFINITY) {
172 zapi_route_set_blackhole(&api, BLACKHOLE_REJECT);
173 } else {
174 SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
175 api.nexthop_num = 1;
176 api_nh->ifindex = ifindex;
177 api_nh->vrf_id = VRF_DEFAULT;
178 switch (family) {
179 case AF_INET:
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;
184 } else {
185 api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX;
186 }
187 break;
188 case AF_INET6:
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;
192 break;
193 }
194 SET_FLAG(api.message, ZAPI_MESSAGE_METRIC);
195 api.metric = metric;
196 }
197
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,
202 zclient, &api);
203}
204
205int
206if_eui64(int ifindex, unsigned char *eui)
207{
208 struct interface *ifp = if_lookup_by_index(ifindex, VRF_DEFAULT);
209 if (ifp == NULL) {
210 return -1;
211 }
212
213 uint8_t len = (uint8_t)ifp->hw_addr_len;
214 char *tmp = (void*) ifp->hw_addr;
215
216 if (len == 8) {
217 memcpy(eui, tmp, 8);
218 eui[0] ^= 2;
219 } else if (len == 6) {
220 memcpy(eui, tmp, 3);
221 eui[3] = 0xFF;
222 eui[4] = 0xFE;
223 memcpy(eui+5, tmp+3, 3);
224 } else {
225 return -1;
226 }
227 return 0;
228}
229
230/* Like gettimeofday, but returns monotonic time. If POSIX clocks are not
231 available, falls back to gettimeofday but enforces monotonicity. */
232int
233gettime(struct timeval *tv)
234{
235 return monotime(tv);
236}
237
238/* If /dev/urandom doesn't exist, this will fail with ENOENT, which the
239 caller will deal with gracefully. */
240
241int
242read_random_bytes(void *buf, size_t len)
243{
244 int fd;
245 int rc;
246
247 fd = open("/dev/urandom", O_RDONLY);
248 if(fd < 0) {
249 rc = -1;
250 } else {
251 rc = read(fd, buf, len);
252 if(rc < 0 || (unsigned) rc < len)
253 rc = -1;
254 close(fd);
255 }
256 return rc;
257}