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