blob: 8cd1db6393f127b1480babadf35a19c33268878d [file] [log] [blame]
Paul Jakma57345092011-12-25 17:52:09 +01001/*
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
19Copyright (c) 2007, 2008 by Juliusz Chroboczek
20
21Permission is hereby granted, free of charge, to any person obtaining a copy
22of this software and associated documentation files (the "Software"), to deal
23in the Software without restriction, including without limitation the rights
24to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
25copies of the Software, and to permit persons to whom the Software is
26furnished to do so, subject to the following conditions:
27
28The above copyright notice and this permission notice shall be included in
29all copies or substantial portions of the Software.
30
31THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
32IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
33FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
34AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
35LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
36OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
37THE SOFTWARE.
38*/
39
Paul Jakma57345092011-12-25 17:52:09 +010040#include <zebra.h>
41#include "if.h"
42
43#include "babeld.h"
44#include "util.h"
45#include "net.h"
46#include "babel_interface.h"
47#include "source.h"
48#include "neighbour.h"
49#include "route.h"
50#include "xroute.h"
51#include "resend.h"
52#include "message.h"
53#include "kernel.h"
54
55unsigned char packet_header[4] = {42, 2};
56
57int parasitic = 0;
58int split_horizon = 1;
59
60unsigned short myseqno = 0;
61struct timeval seqno_time = {0, 0};
62
63#define UNICAST_BUFSIZE 1024
64int unicast_buffered = 0;
65unsigned char *unicast_buffer = NULL;
66struct neighbour *unicast_neighbour = NULL;
67struct timeval unicast_flush_timeout = {0, 0};
68
69static const unsigned char v4prefix[16] =
70 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0 };
71
Matthieu Boutierc35fafd2012-01-23 23:46:32 +010072/* Parse a network prefix, encoded in the somewhat baroque compressed
73 representation used by Babel. Return the number of bytes parsed. */
Paul Jakma57345092011-12-25 17:52:09 +010074static int
75network_prefix(int ae, int plen, unsigned int omitted,
76 const unsigned char *p, const unsigned char *dp,
77 unsigned int len, unsigned char *p_r)
78{
79 unsigned pb;
80 unsigned char prefix[16];
Matthieu Boutierc35fafd2012-01-23 23:46:32 +010081 int ret = -1;
Paul Jakma57345092011-12-25 17:52:09 +010082
83 if(plen >= 0)
84 pb = (plen + 7) / 8;
85 else if(ae == 1)
86 pb = 4;
87 else
88 pb = 16;
89
90 if(pb > 16)
91 return -1;
92
93 memset(prefix, 0, 16);
94
95 switch(ae) {
Matthieu Boutierc35fafd2012-01-23 23:46:32 +010096 case 0:
97 ret = 0;
98 break;
Paul Jakma57345092011-12-25 17:52:09 +010099 case 1:
100 if(omitted > 4 || pb > 4 || (pb > omitted && len < pb - omitted))
101 return -1;
102 memcpy(prefix, v4prefix, 12);
103 if(omitted) {
104 if (dp == NULL || !v4mapped(dp)) return -1;
105 memcpy(prefix, dp, 12 + omitted);
106 }
107 if(pb > omitted) memcpy(prefix + 12 + omitted, p, pb - omitted);
Matthieu Boutierc35fafd2012-01-23 23:46:32 +0100108 ret = pb - omitted;
Paul Jakma57345092011-12-25 17:52:09 +0100109 break;
110 case 2:
111 if(omitted > 16 || (pb > omitted && len < pb - omitted)) return -1;
112 if(omitted) {
113 if (dp == NULL || v4mapped(dp)) return -1;
114 memcpy(prefix, dp, omitted);
115 }
116 if(pb > omitted) memcpy(prefix + omitted, p, pb - omitted);
Matthieu Boutierc35fafd2012-01-23 23:46:32 +0100117 ret = pb - omitted;
Paul Jakma57345092011-12-25 17:52:09 +0100118 break;
119 case 3:
120 if(pb > 8 && len < pb - 8) return -1;
121 prefix[0] = 0xfe;
122 prefix[1] = 0x80;
123 if(pb > 8) memcpy(prefix + 8, p, pb - 8);
Matthieu Boutierc35fafd2012-01-23 23:46:32 +0100124 ret = pb - 8;
Paul Jakma57345092011-12-25 17:52:09 +0100125 break;
126 default:
127 return -1;
128 }
129
130 mask_prefix(p_r, prefix, plen < 0 ? 128 : ae == 1 ? plen + 96 : plen);
Matthieu Boutierc35fafd2012-01-23 23:46:32 +0100131 return ret;
132}
133
134static void
135parse_route_attributes(const unsigned char *a, int alen,
136 unsigned char *channels)
137{
138 int type, len, i = 0;
139
140 while(i < alen) {
141 type = a[i];
142 if(type == 0) {
143 i++;
144 continue;
145 }
146
147 if(i + 1 > alen) {
148 fprintf(stderr, "Received truncated attributes.\n");
149 return;
150 }
151 len = a[i + 1];
152 if(i + len > alen) {
153 fprintf(stderr, "Received truncated attributes.\n");
154 return;
155 }
156
157 if(type == 1) {
158 /* Nothing. */
159 } else if(type == 2) {
160 if(len > DIVERSITY_HOPS) {
161 fprintf(stderr,
162 "Received overlong channel information (%d > %d).\n",
163 len, DIVERSITY_HOPS);
164 len = DIVERSITY_HOPS;
165 }
166 if(memchr(a + i + 2, 0, len) != NULL) {
167 /* 0 is reserved. */
168 fprintf(stderr, "Channel information contains 0!");
169 return;
170 }
171 memset(channels, 0, DIVERSITY_HOPS);
172 memcpy(channels, a + i + 2, len);
173 } else {
174 fprintf(stderr, "Received unknown route attribute %d.\n", type);
175 }
176
177 i += len + 2;
178 }
Paul Jakma57345092011-12-25 17:52:09 +0100179}
180
181static int
182network_address(int ae, const unsigned char *a, unsigned int len,
183 unsigned char *a_r)
184{
185 return network_prefix(ae, -1, 0, a, NULL, len, a_r);
186}
187
Matthieu Boutierc35fafd2012-01-23 23:46:32 +0100188static int
189channels_len(unsigned char *channels)
190{
191 unsigned char *p = memchr(channels, 0, DIVERSITY_HOPS);
192 return p ? (p - channels) : DIVERSITY_HOPS;
193}
194
Paul Jakma57345092011-12-25 17:52:09 +0100195void
196parse_packet(const unsigned char *from, struct interface *ifp,
197 const unsigned char *packet, int packetlen)
198{
199 int i;
200 const unsigned char *message;
201 unsigned char type, len;
202 int bodylen;
203 struct neighbour *neigh;
204 int have_router_id = 0, have_v4_prefix = 0, have_v6_prefix = 0,
205 have_v4_nh = 0, have_v6_nh = 0;
206 unsigned char router_id[8], v4_prefix[16], v6_prefix[16],
207 v4_nh[16], v6_nh[16];
208
209 if(!linklocal(from)) {
Matthieu Boutier4eedea52012-01-17 22:46:21 +0100210 zlog_err("Received packet from non-local address %s.",
211 format_address(from));
Paul Jakma57345092011-12-25 17:52:09 +0100212 return;
213 }
214
215 if(packet[0] != 42) {
Matthieu Boutier4eedea52012-01-17 22:46:21 +0100216 zlog_err("Received malformed packet on %s from %s.",
217 ifp->name, format_address(from));
Paul Jakma57345092011-12-25 17:52:09 +0100218 return;
219 }
220
221 if(packet[1] != 2) {
Matthieu Boutier4eedea52012-01-17 22:46:21 +0100222 zlog_err("Received packet with unknown version %d on %s from %s.",
223 packet[1], ifp->name, format_address(from));
Paul Jakma57345092011-12-25 17:52:09 +0100224 return;
225 }
226
227 neigh = find_neighbour(from, ifp);
228 if(neigh == NULL) {
Matthieu Boutier4eedea52012-01-17 22:46:21 +0100229 zlog_err("Couldn't allocate neighbour.");
Paul Jakma57345092011-12-25 17:52:09 +0100230 return;
231 }
232
233 DO_NTOHS(bodylen, packet + 2);
234
235 if(bodylen + 4 > packetlen) {
Matthieu Boutier4eedea52012-01-17 22:46:21 +0100236 zlog_err("Received truncated packet (%d + 4 > %d).",
237 bodylen, packetlen);
Paul Jakma57345092011-12-25 17:52:09 +0100238 bodylen = packetlen - 4;
239 }
240
241 i = 0;
242 while(i < bodylen) {
243 message = packet + 4 + i;
244 type = message[0];
245 if(type == MESSAGE_PAD1) {
246 debugf(BABEL_DEBUG_COMMON,"Received pad1 from %s on %s.",
247 format_address(from), ifp->name);
248 i++;
249 continue;
250 }
251 if(i + 1 > bodylen) {
Matthieu Boutier4eedea52012-01-17 22:46:21 +0100252 zlog_err("Received truncated message.");
Paul Jakma57345092011-12-25 17:52:09 +0100253 break;
254 }
255 len = message[1];
256 if(i + len > bodylen) {
Matthieu Boutier4eedea52012-01-17 22:46:21 +0100257 zlog_err("Received truncated message.");
Paul Jakma57345092011-12-25 17:52:09 +0100258 break;
259 }
260
261 if(type == MESSAGE_PADN) {
262 debugf(BABEL_DEBUG_COMMON,"Received pad%d from %s on %s.",
263 len, format_address(from), ifp->name);
264 } else if(type == MESSAGE_ACK_REQ) {
265 unsigned short nonce, interval;
266 if(len < 6) goto fail;
267 DO_NTOHS(nonce, message + 4);
268 DO_NTOHS(interval, message + 6);
269 debugf(BABEL_DEBUG_COMMON,"Received ack-req (%04X %d) from %s on %s.",
270 nonce, interval, format_address(from), ifp->name);
271 send_ack(neigh, nonce, interval);
272 } else if(type == MESSAGE_ACK) {
273 debugf(BABEL_DEBUG_COMMON,"Received ack from %s on %s.",
274 format_address(from), ifp->name);
275 /* Nothing right now */
276 } else if(type == MESSAGE_HELLO) {
277 unsigned short seqno, interval;
278 int changed;
279 if(len < 6) goto fail;
280 DO_NTOHS(seqno, message + 4);
281 DO_NTOHS(interval, message + 6);
282 debugf(BABEL_DEBUG_COMMON,"Received hello %d (%d) from %s on %s.",
283 seqno, interval,
284 format_address(from), ifp->name);
285 babel_get_if_nfo(ifp)->activity_time = babel_now.tv_sec;
286 changed = update_neighbour(neigh, seqno, interval);
287 update_neighbour_metric(neigh, changed);
288 if(interval > 0)
289 schedule_neighbours_check(interval * 10, 0);
290 } else if(type == MESSAGE_IHU) {
291 unsigned short txcost, interval;
292 unsigned char address[16];
293 int rc;
294 if(len < 6) goto fail;
295 DO_NTOHS(txcost, message + 4);
296 DO_NTOHS(interval, message + 6);
297 rc = network_address(message[2], message + 8, len - 6, address);
298 if(rc < 0) goto fail;
299 debugf(BABEL_DEBUG_COMMON,"Received ihu %d (%d) from %s on %s for %s.",
300 txcost, interval,
301 format_address(from), ifp->name,
302 format_address(address));
303 if(message[2] == 0 || is_interface_ll_address(ifp, address)) {
304 int changed = txcost != neigh->txcost;
305 neigh->txcost = txcost;
306 neigh->ihu_time = babel_now;
307 neigh->ihu_interval = interval;
308 update_neighbour_metric(neigh, changed);
309 if(interval > 0)
310 schedule_neighbours_check(interval * 10 * 3, 0);
311 }
312 } else if(type == MESSAGE_ROUTER_ID) {
313 if(len < 10) {
314 have_router_id = 0;
315 goto fail;
316 }
317 memcpy(router_id, message + 4, 8);
318 have_router_id = 1;
319 debugf(BABEL_DEBUG_COMMON,"Received router-id %s from %s on %s.",
320 format_eui64(router_id), format_address(from), ifp->name);
321 } else if(type == MESSAGE_NH) {
322 unsigned char nh[16];
323 int rc;
324 if(len < 2) {
325 have_v4_nh = 0;
326 have_v6_nh = 0;
327 goto fail;
328 }
329 rc = network_address(message[2], message + 4, len - 2,
330 nh);
331 if(rc < 0) {
332 have_v4_nh = 0;
333 have_v6_nh = 0;
334 goto fail;
335 }
336 debugf(BABEL_DEBUG_COMMON,"Received nh %s (%d) from %s on %s.",
337 format_address(nh), message[2],
338 format_address(from), ifp->name);
339 if(message[2] == 1) {
340 memcpy(v4_nh, nh, 16);
341 have_v4_nh = 1;
342 } else {
343 memcpy(v6_nh, nh, 16);
344 have_v6_nh = 1;
345 }
346 } else if(type == MESSAGE_UPDATE) {
347 unsigned char prefix[16], *nh;
348 unsigned char plen;
Matthieu Boutierc35fafd2012-01-23 23:46:32 +0100349 unsigned char channels[DIVERSITY_HOPS];
Paul Jakma57345092011-12-25 17:52:09 +0100350 unsigned short interval, seqno, metric;
Matthieu Boutierc35fafd2012-01-23 23:46:32 +0100351 int rc, parsed_len;
Paul Jakma57345092011-12-25 17:52:09 +0100352 if(len < 10) {
353 if(len < 2 || message[3] & 0x80)
354 have_v4_prefix = have_v6_prefix = 0;
355 goto fail;
356 }
357 DO_NTOHS(interval, message + 6);
358 DO_NTOHS(seqno, message + 8);
359 DO_NTOHS(metric, message + 10);
360 if(message[5] == 0 ||
361 (message[3] == 1 ? have_v4_prefix : have_v6_prefix))
362 rc = network_prefix(message[2], message[4], message[5],
363 message + 12,
364 message[2] == 1 ? v4_prefix : v6_prefix,
365 len - 10, prefix);
366 else
367 rc = -1;
368 if(rc < 0) {
369 if(message[3] & 0x80)
370 have_v4_prefix = have_v6_prefix = 0;
371 goto fail;
372 }
Matthieu Boutierc35fafd2012-01-23 23:46:32 +0100373 parsed_len = 10 + rc;
Paul Jakma57345092011-12-25 17:52:09 +0100374
375 plen = message[4] + (message[2] == 1 ? 96 : 0);
376
377 if(message[3] & 0x80) {
378 if(message[2] == 1) {
379 memcpy(v4_prefix, prefix, 16);
380 have_v4_prefix = 1;
381 } else {
382 memcpy(v6_prefix, prefix, 16);
383 have_v6_prefix = 1;
384 }
385 }
386 if(message[3] & 0x40) {
387 if(message[2] == 1) {
388 memset(router_id, 0, 4);
389 memcpy(router_id + 4, prefix + 12, 4);
390 } else {
391 memcpy(router_id, prefix + 8, 8);
392 }
393 have_router_id = 1;
394 }
395 if(!have_router_id && message[2] != 0) {
Matthieu Boutier4eedea52012-01-17 22:46:21 +0100396 zlog_err("Received prefix with no router id.");
Paul Jakma57345092011-12-25 17:52:09 +0100397 goto fail;
398 }
399 debugf(BABEL_DEBUG_COMMON,"Received update%s%s for %s from %s on %s.",
400 (message[3] & 0x80) ? "/prefix" : "",
401 (message[3] & 0x40) ? "/id" : "",
402 format_prefix(prefix, plen),
403 format_address(from), ifp->name);
404
405 if(message[2] == 0) {
406 if(metric < 0xFFFF) {
Matthieu Boutier4eedea52012-01-17 22:46:21 +0100407 zlog_err("Received wildcard update with finite metric.");
Paul Jakma57345092011-12-25 17:52:09 +0100408 goto done;
409 }
410 retract_neighbour_routes(neigh);
411 goto done;
412 } else if(message[2] == 1) {
413 if(!have_v4_nh)
414 goto fail;
415 nh = v4_nh;
416 } else if(have_v6_nh) {
417 nh = v6_nh;
418 } else {
419 nh = neigh->address;
420 }
421
422 if(message[2] == 1) {
423 if(!babel_get_if_nfo(ifp)->ipv4)
424 goto done;
425 }
426
Matthieu Boutierc35fafd2012-01-23 23:46:32 +0100427 if((ifp->flags & BABEL_IF_FARAWAY)) {
428 channels[0] = 0;
429 } else {
430 /* This will be overwritten by parse_route_attributes below. */
431 if(metric < 256) {
432 /* Assume non-interfering (wired) link. */
433 channels[0] = 0;
434 } else {
435 /* Assume interfering. */
436 channels[0] = BABEL_IF_CHANNEL_INTERFERING;
437 channels[1] = 0;
438 }
439
440 if(parsed_len < len)
441 parse_route_attributes(message + 2 + parsed_len,
442 len - parsed_len, channels);
443 }
444
Paul Jakma57345092011-12-25 17:52:09 +0100445 update_route(router_id, prefix, plen, seqno, metric, interval,
Matthieu Boutierc35fafd2012-01-23 23:46:32 +0100446 neigh, nh,
447 channels, channels_len(channels));
Paul Jakma57345092011-12-25 17:52:09 +0100448 } else if(type == MESSAGE_REQUEST) {
449 unsigned char prefix[16], plen;
450 int rc;
451 if(len < 2) goto fail;
452 rc = network_prefix(message[2], message[3], 0,
453 message + 4, NULL, len - 2, prefix);
454 if(rc < 0) goto fail;
455 plen = message[3] + (message[2] == 1 ? 96 : 0);
456 debugf(BABEL_DEBUG_COMMON,"Received request for %s from %s on %s.",
457 message[2] == 0 ? "any" : format_prefix(prefix, plen),
458 format_address(from), ifp->name);
459 if(message[2] == 0) {
Matthieu Boutierc35fafd2012-01-23 23:46:32 +0100460 struct babel_interface *babel_ifp =babel_get_if_nfo(neigh->ifp);
Paul Jakma57345092011-12-25 17:52:09 +0100461 /* If a neighbour is requesting a full route dump from us,
462 we might as well send it an IHU. */
463 send_ihu(neigh, NULL);
Matthieu Boutierc35fafd2012-01-23 23:46:32 +0100464 /* Since nodes send wildcard requests on boot, booting
465 a large number of nodes at the same time may cause an
466 update storm. Ignore a wildcard request that happens
467 shortly after we sent a full update. */
468 if(babel_ifp->last_update_time <
469 babel_now.tv_sec - MAX(babel_ifp->hello_interval / 100, 1))
470 send_update(neigh->ifp, 0, NULL, 0);
Paul Jakma57345092011-12-25 17:52:09 +0100471 } else {
472 send_update(neigh->ifp, 0, prefix, plen);
473 }
474 } else if(type == MESSAGE_MH_REQUEST) {
475 unsigned char prefix[16], plen;
476 unsigned short seqno;
477 int rc;
478 if(len < 14) goto fail;
479 DO_NTOHS(seqno, message + 4);
480 rc = network_prefix(message[2], message[3], 0,
481 message + 16, NULL, len - 14, prefix);
482 if(rc < 0) goto fail;
483 plen = message[3] + (message[2] == 1 ? 96 : 0);
484 debugf(BABEL_DEBUG_COMMON,"Received request (%d) for %s from %s on %s (%s, %d).",
485 message[6],
486 format_prefix(prefix, plen),
487 format_address(from), ifp->name,
488 format_eui64(message + 8), seqno);
489 handle_request(neigh, prefix, plen, message[6],
490 seqno, message + 8);
491 } else {
492 debugf(BABEL_DEBUG_COMMON,"Received unknown packet type %d from %s on %s.",
493 type, format_address(from), ifp->name);
494 }
495 done:
496 i += len + 2;
497 continue;
498
499 fail:
Matthieu Boutier4eedea52012-01-17 22:46:21 +0100500 zlog_err("Couldn't parse packet (%d, %d) from %s on %s.",
501 message[0], message[1], format_address(from), ifp->name);
Paul Jakma57345092011-12-25 17:52:09 +0100502 goto done;
503 }
504 return;
505}
506
507/* Under normal circumstances, there are enough moderation mechanisms
508 elsewhere in the protocol to make sure that this last-ditch check
509 should never trigger. But I'm superstitious. */
510
511static int
512check_bucket(struct interface *ifp)
513{
514 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
515 if(babel_ifp->bucket <= 0) {
516 int seconds = babel_now.tv_sec - babel_ifp->bucket_time;
517 if(seconds > 0) {
518 babel_ifp->bucket = MIN(BUCKET_TOKENS_MAX,
519 seconds * BUCKET_TOKENS_PER_SEC);
520 }
521 /* Reset bucket time unconditionally, in case clock is stepped. */
522 babel_ifp->bucket_time = babel_now.tv_sec;
523 }
524
525 if(babel_ifp->bucket > 0) {
526 babel_ifp->bucket--;
527 return 1;
528 } else {
529 return 0;
530 }
531}
532
533void
534flushbuf(struct interface *ifp)
535{
536 int rc;
537 struct sockaddr_in6 sin6;
538 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
539
540 assert(babel_ifp->buffered <= babel_ifp->bufsize);
541
542 flushupdates(ifp);
543
544 if(babel_ifp->buffered > 0) {
545 debugf(BABEL_DEBUG_COMMON," (flushing %d buffered bytes on %s)",
546 babel_ifp->buffered, ifp->name);
547 if(check_bucket(ifp)) {
548 memset(&sin6, 0, sizeof(sin6));
549 sin6.sin6_family = AF_INET6;
550 memcpy(&sin6.sin6_addr, protocol_group, 16);
551 sin6.sin6_port = htons(protocol_port);
552 sin6.sin6_scope_id = ifp->ifindex;
553 DO_HTONS(packet_header + 2, babel_ifp->buffered);
554 rc = babel_send(protocol_socket,
555 packet_header, sizeof(packet_header),
556 babel_ifp->sendbuf, babel_ifp->buffered,
557 (struct sockaddr*)&sin6, sizeof(sin6));
558 if(rc < 0)
559 zlog_err("send: %s", safe_strerror(errno));
560 } else {
Matthieu Boutier4eedea52012-01-17 22:46:21 +0100561 zlog_err("Warning: bucket full, dropping packet to %s.",
562 ifp->name);
Paul Jakma57345092011-12-25 17:52:09 +0100563 }
564 }
565 VALGRIND_MAKE_MEM_UNDEFINED(babel_ifp->sendbuf, babel_ifp->bufsize);
566 babel_ifp->buffered = 0;
567 babel_ifp->have_buffered_hello = 0;
568 babel_ifp->have_buffered_id = 0;
569 babel_ifp->have_buffered_nh = 0;
570 babel_ifp->have_buffered_prefix = 0;
571 babel_ifp->flush_timeout.tv_sec = 0;
572 babel_ifp->flush_timeout.tv_usec = 0;
573}
574
575static void
576schedule_flush(struct interface *ifp)
577{
578 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
579 unsigned msecs = jitter(babel_ifp, 0);
580 if(babel_ifp->flush_timeout.tv_sec != 0 &&
581 timeval_minus_msec(&babel_ifp->flush_timeout, &babel_now) < msecs)
582 return;
583 set_timeout(&babel_ifp->flush_timeout, msecs);
584}
585
586static void
587schedule_flush_now(struct interface *ifp)
588{
589 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
590 /* Almost now */
591 unsigned msecs = roughly(10);
592 if(babel_ifp->flush_timeout.tv_sec != 0 &&
593 timeval_minus_msec(&babel_ifp->flush_timeout, &babel_now) < msecs)
594 return;
595 set_timeout(&babel_ifp->flush_timeout, msecs);
596}
597
598static void
599schedule_unicast_flush(unsigned msecs)
600{
601 if(!unicast_neighbour)
602 return;
603 if(unicast_flush_timeout.tv_sec != 0 &&
604 timeval_minus_msec(&unicast_flush_timeout, &babel_now) < msecs)
605 return;
606 unicast_flush_timeout.tv_usec = (babel_now.tv_usec + msecs * 1000) %1000000;
607 unicast_flush_timeout.tv_sec =
608 babel_now.tv_sec + (babel_now.tv_usec / 1000 + msecs) / 1000;
609}
610
611static void
612ensure_space(struct interface *ifp, int space)
613{
614 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
615 if(babel_ifp->bufsize - babel_ifp->buffered < space)
616 flushbuf(ifp);
617}
618
619static void
620start_message(struct interface *ifp, int type, int len)
621{
622 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
623 if(babel_ifp->bufsize - babel_ifp->buffered < len + 2)
624 flushbuf(ifp);
625 babel_ifp->sendbuf[babel_ifp->buffered++] = type;
626 babel_ifp->sendbuf[babel_ifp->buffered++] = len;
627}
628
629static void
630end_message(struct interface *ifp, int type, int bytes)
631{
632 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
633 assert(babel_ifp->buffered >= bytes + 2 &&
634 babel_ifp->sendbuf[babel_ifp->buffered - bytes - 2] == type &&
635 babel_ifp->sendbuf[babel_ifp->buffered - bytes - 1] == bytes);
636 schedule_flush(ifp);
637}
638
639static void
640accumulate_byte(struct interface *ifp, unsigned char value)
641{
642 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
643 babel_ifp->sendbuf[babel_ifp->buffered++] = value;
644}
645
646static void
647accumulate_short(struct interface *ifp, unsigned short value)
648{
649 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
650 DO_HTONS(babel_ifp->sendbuf + babel_ifp->buffered, value);
651 babel_ifp->buffered += 2;
652}
653
654static void
655accumulate_bytes(struct interface *ifp,
656 const unsigned char *value, unsigned len)
657{
658 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
659 memcpy(babel_ifp->sendbuf + babel_ifp->buffered, value, len);
660 babel_ifp->buffered += len;
661}
662
663static int
664start_unicast_message(struct neighbour *neigh, int type, int len)
665{
666 if(unicast_neighbour) {
667 if(neigh != unicast_neighbour ||
668 unicast_buffered + len + 2 >=
669 MIN(UNICAST_BUFSIZE, babel_get_if_nfo(neigh->ifp)->bufsize))
670 flush_unicast(0);
671 }
672 if(!unicast_buffer)
673 unicast_buffer = malloc(UNICAST_BUFSIZE);
674 if(!unicast_buffer) {
675 zlog_err("malloc(unicast_buffer): %s", safe_strerror(errno));
676 return -1;
677 }
678
679 unicast_neighbour = neigh;
680
681 unicast_buffer[unicast_buffered++] = type;
682 unicast_buffer[unicast_buffered++] = len;
683 return 1;
684}
685
686static void
687end_unicast_message(struct neighbour *neigh, int type, int bytes)
688{
689 assert(unicast_neighbour == neigh && unicast_buffered >= bytes + 2 &&
690 unicast_buffer[unicast_buffered - bytes - 2] == type &&
691 unicast_buffer[unicast_buffered - bytes - 1] == bytes);
692 schedule_unicast_flush(jitter(babel_get_if_nfo(neigh->ifp), 0));
693}
694
695static void
696accumulate_unicast_byte(struct neighbour *neigh, unsigned char value)
697{
698 unicast_buffer[unicast_buffered++] = value;
699}
700
701static void
702accumulate_unicast_short(struct neighbour *neigh, unsigned short value)
703{
704 DO_HTONS(unicast_buffer + unicast_buffered, value);
705 unicast_buffered += 2;
706}
707
708static void
709accumulate_unicast_bytes(struct neighbour *neigh,
710 const unsigned char *value, unsigned len)
711{
712 memcpy(unicast_buffer + unicast_buffered, value, len);
713 unicast_buffered += len;
714}
715
716void
717send_ack(struct neighbour *neigh, unsigned short nonce, unsigned short interval)
718{
719 int rc;
720 debugf(BABEL_DEBUG_COMMON,"Sending ack (%04x) to %s on %s.",
721 nonce, format_address(neigh->address), neigh->ifp->name);
722 rc = start_unicast_message(neigh, MESSAGE_ACK, 2); if(rc < 0) return;
723 accumulate_unicast_short(neigh, nonce);
724 end_unicast_message(neigh, MESSAGE_ACK, 2);
725 /* Roughly yields a value no larger than 3/2, so this meets the deadline */
726 schedule_unicast_flush(roughly(interval * 6));
727}
728
729void
730send_hello_noupdate(struct interface *ifp, unsigned interval)
731{
732 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
733 /* This avoids sending multiple hellos in a single packet, which breaks
734 link quality estimation. */
735 if(babel_ifp->have_buffered_hello)
736 flushbuf(ifp);
737
738 babel_ifp->hello_seqno = seqno_plus(babel_ifp->hello_seqno, 1);
739 set_timeout(&babel_ifp->hello_timeout, babel_ifp->hello_interval);
740
741 if(!if_up(ifp))
742 return;
743
744 debugf(BABEL_DEBUG_COMMON,"Sending hello %d (%d) to %s.",
745 babel_ifp->hello_seqno, interval, ifp->name);
746
747 start_message(ifp, MESSAGE_HELLO, 6);
748 accumulate_short(ifp, 0);
749 accumulate_short(ifp, babel_ifp->hello_seqno);
750 accumulate_short(ifp, interval > 0xFFFF ? 0xFFFF : interval);
751 end_message(ifp, MESSAGE_HELLO, 6);
752 babel_ifp->have_buffered_hello = 1;
753}
754
755void
756send_hello(struct interface *ifp)
757{
Matthieu Boutierc35fafd2012-01-23 23:46:32 +0100758 int changed;
759 changed = update_hello_interval(ifp);
Paul Jakma57345092011-12-25 17:52:09 +0100760 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
761 send_hello_noupdate(ifp, (babel_ifp->hello_interval + 9) / 10);
762 /* Send full IHU every 3 hellos, and marginal IHU each time */
Matthieu Boutierc35fafd2012-01-23 23:46:32 +0100763 if(changed || babel_ifp->hello_seqno % 3 == 0)
Paul Jakma57345092011-12-25 17:52:09 +0100764 send_ihu(NULL, ifp);
765 else
766 send_marginal_ihu(ifp);
767}
768
769void
770flush_unicast(int dofree)
771{
772 struct sockaddr_in6 sin6;
773 int rc;
774
775 if(unicast_buffered == 0)
776 goto done;
777
778 if(!if_up(unicast_neighbour->ifp))
779 goto done;
780
781 /* Preserve ordering of messages */
782 flushbuf(unicast_neighbour->ifp);
783
784 if(check_bucket(unicast_neighbour->ifp)) {
785 memset(&sin6, 0, sizeof(sin6));
786 sin6.sin6_family = AF_INET6;
787 memcpy(&sin6.sin6_addr, unicast_neighbour->address, 16);
788 sin6.sin6_port = htons(protocol_port);
789 sin6.sin6_scope_id = unicast_neighbour->ifp->ifindex;
790 DO_HTONS(packet_header + 2, unicast_buffered);
791 rc = babel_send(protocol_socket,
792 packet_header, sizeof(packet_header),
793 unicast_buffer, unicast_buffered,
794 (struct sockaddr*)&sin6, sizeof(sin6));
795 if(rc < 0)
796 zlog_err("send(unicast): %s", safe_strerror(errno));
797 } else {
Matthieu Boutier4eedea52012-01-17 22:46:21 +0100798 zlog_err("Warning: bucket full, dropping unicast packet to %s if %s.",
799 format_address(unicast_neighbour->address),
800 unicast_neighbour->ifp->name);
Paul Jakma57345092011-12-25 17:52:09 +0100801 }
802
803 done:
804 VALGRIND_MAKE_MEM_UNDEFINED(unicast_buffer, UNICAST_BUFSIZE);
805 unicast_buffered = 0;
806 if(dofree && unicast_buffer) {
807 free(unicast_buffer);
808 unicast_buffer = NULL;
809 }
810 unicast_neighbour = NULL;
811 unicast_flush_timeout.tv_sec = 0;
812 unicast_flush_timeout.tv_usec = 0;
813}
814
815static void
816really_send_update(struct interface *ifp,
817 const unsigned char *id,
818 const unsigned char *prefix, unsigned char plen,
Matthieu Boutierc35fafd2012-01-23 23:46:32 +0100819 unsigned short seqno, unsigned short metric,
820 unsigned char *channels, int channels_len)
Paul Jakma57345092011-12-25 17:52:09 +0100821{
822 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
823 int add_metric, v4, real_plen, omit = 0;
824 const unsigned char *real_prefix;
825 unsigned short flags = 0;
Matthieu Boutierc35fafd2012-01-23 23:46:32 +0100826 int channels_size;
827
828 if(diversity_kind != DIVERSITY_CHANNEL)
829 channels_len = -1;
830
831 channels_size = channels_len >= 0 ? channels_len + 2 : 0;
Paul Jakma57345092011-12-25 17:52:09 +0100832
833 if(!if_up(ifp))
834 return;
835
836 add_metric = output_filter(id, prefix, plen, ifp->ifindex);
837 if(add_metric >= INFINITY)
838 return;
839
840 metric = MIN(metric + add_metric, INFINITY);
841 /* Worst case */
842 ensure_space(ifp, 20 + 12 + 28);
843
844 v4 = plen >= 96 && v4mapped(prefix);
845
846 if(v4) {
847 if(!babel_ifp->ipv4)
848 return;
849 if(!babel_ifp->have_buffered_nh ||
850 memcmp(babel_ifp->buffered_nh, babel_ifp->ipv4, 4) != 0) {
851 start_message(ifp, MESSAGE_NH, 6);
852 accumulate_byte(ifp, 1);
853 accumulate_byte(ifp, 0);
854 accumulate_bytes(ifp, babel_ifp->ipv4, 4);
855 end_message(ifp, MESSAGE_NH, 6);
856 memcpy(babel_ifp->buffered_nh, babel_ifp->ipv4, 4);
857 babel_ifp->have_buffered_nh = 1;
858 }
859
860 real_prefix = prefix + 12;
861 real_plen = plen - 96;
862 } else {
863 if(babel_ifp->have_buffered_prefix) {
864 while(omit < plen / 8 &&
865 babel_ifp->buffered_prefix[omit] == prefix[omit])
866 omit++;
867 }
868 if(!babel_ifp->have_buffered_prefix || plen >= 48)
869 flags |= 0x80;
870 real_prefix = prefix;
871 real_plen = plen;
872 }
873
874 if(!babel_ifp->have_buffered_id
875 || memcmp(id, babel_ifp->buffered_id, 8) != 0) {
876 if(real_plen == 128 && memcmp(real_prefix + 8, id, 8) == 0) {
877 flags |= 0x40;
878 } else {
879 start_message(ifp, MESSAGE_ROUTER_ID, 10);
880 accumulate_short(ifp, 0);
881 accumulate_bytes(ifp, id, 8);
882 end_message(ifp, MESSAGE_ROUTER_ID, 10);
883 }
884 memcpy(babel_ifp->buffered_id, id, 16);
885 babel_ifp->have_buffered_id = 1;
886 }
887
Matthieu Boutierc35fafd2012-01-23 23:46:32 +0100888 start_message(ifp, MESSAGE_UPDATE, 10 + (real_plen + 7) / 8 - omit +
889 channels_size);
Paul Jakma57345092011-12-25 17:52:09 +0100890 accumulate_byte(ifp, v4 ? 1 : 2);
891 accumulate_byte(ifp, flags);
892 accumulate_byte(ifp, real_plen);
893 accumulate_byte(ifp, omit);
894 accumulate_short(ifp, (babel_ifp->update_interval + 5) / 10);
895 accumulate_short(ifp, seqno);
896 accumulate_short(ifp, metric);
897 accumulate_bytes(ifp, real_prefix + omit, (real_plen + 7) / 8 - omit);
Matthieu Boutierc35fafd2012-01-23 23:46:32 +0100898 /* Note that an empty channels TLV is different from no such TLV. */
899 if(channels_len >= 0) {
900 accumulate_byte(ifp, 2);
901 accumulate_byte(ifp, channels_len);
902 accumulate_bytes(ifp, channels, channels_len);
903 }
904 end_message(ifp, MESSAGE_UPDATE, 10 + (real_plen + 7) / 8 - omit +
905 channels_size);
Paul Jakma57345092011-12-25 17:52:09 +0100906
907 if(flags & 0x80) {
908 memcpy(babel_ifp->buffered_prefix, prefix, 16);
909 babel_ifp->have_buffered_prefix = 1;
910 }
911}
912
913static int
914compare_buffered_updates(const void *av, const void *bv)
915{
916 const struct buffered_update *a = av, *b = bv;
917 int rc, v4a, v4b, ma, mb;
918
919 rc = memcmp(a->id, b->id, 8);
920 if(rc != 0)
921 return rc;
922
923 v4a = (a->plen >= 96 && v4mapped(a->prefix));
924 v4b = (b->plen >= 96 && v4mapped(b->prefix));
925
926 if(v4a > v4b)
927 return 1;
928 else if(v4a < v4b)
929 return -1;
930
931 ma = (!v4a && a->plen == 128 && memcmp(a->prefix + 8, a->id, 8) == 0);
932 mb = (!v4b && b->plen == 128 && memcmp(b->prefix + 8, b->id, 8) == 0);
933
934 if(ma > mb)
935 return -1;
936 else if(mb > ma)
937 return 1;
938
939 if(a->plen < b->plen)
940 return 1;
941 else if(a->plen > b->plen)
942 return -1;
943
944 return memcmp(a->prefix, b->prefix, 16);
945}
946
947void
948flushupdates(struct interface *ifp)
949{
950 babel_interface_nfo *babel_ifp = NULL;
951 struct xroute *xroute;
Denis Ovsienkoef4de4d2012-01-08 15:29:19 +0400952 struct babel_route *route;
Paul Jakma57345092011-12-25 17:52:09 +0100953 const unsigned char *last_prefix = NULL;
954 unsigned char last_plen = 0xFF;
955 int i;
956
957 if(ifp == NULL) {
958 struct interface *ifp_aux;
959 struct listnode *linklist_node = NULL;
960 FOR_ALL_INTERFACES(ifp_aux, linklist_node)
961 flushupdates(ifp_aux);
962 return;
963 }
964
965 babel_ifp = babel_get_if_nfo(ifp);
966 if(babel_ifp->num_buffered_updates > 0) {
967 struct buffered_update *b = babel_ifp->buffered_updates;
968 int n = babel_ifp->num_buffered_updates;
969
970 babel_ifp->buffered_updates = NULL;
971 babel_ifp->update_bufsize = 0;
972 babel_ifp->num_buffered_updates = 0;
973
974 if(!if_up(ifp))
975 goto done;
976
977 debugf(BABEL_DEBUG_COMMON," (flushing %d buffered updates on %s (%d))",
978 n, ifp->name, ifp->ifindex);
979
980 /* In order to send fewer update messages, we want to send updates
981 with the same router-id together, with IPv6 going out before IPv4. */
982
983 for(i = 0; i < n; i++) {
984 route = find_installed_route(b[i].prefix, b[i].plen);
985 if(route)
986 memcpy(b[i].id, route->src->id, 8);
987 else
988 memcpy(b[i].id, myid, 8);
989 }
990
991 qsort(b, n, sizeof(struct buffered_update), compare_buffered_updates);
992
993 for(i = 0; i < n; i++) {
Paul Jakma57345092011-12-25 17:52:09 +0100994 /* The same update may be scheduled multiple times before it is
995 sent out. Since our buffer is now sorted, it is enough to
996 compare with the previous update. */
997
998 if(last_prefix) {
999 if(b[i].plen == last_plen &&
1000 memcmp(b[i].prefix, last_prefix, 16) == 0)
1001 continue;
1002 }
1003
1004 xroute = find_xroute(b[i].prefix, b[i].plen);
1005 route = find_installed_route(b[i].prefix, b[i].plen);
1006
1007 if(xroute && (!route || xroute->metric <= kernel_metric)) {
1008 really_send_update(ifp, myid,
1009 xroute->prefix, xroute->plen,
Matthieu Boutierc35fafd2012-01-23 23:46:32 +01001010 myseqno, xroute->metric,
1011 NULL, 0);
Paul Jakma57345092011-12-25 17:52:09 +01001012 last_prefix = xroute->prefix;
1013 last_plen = xroute->plen;
1014 } else if(route) {
Matthieu Boutierc35fafd2012-01-23 23:46:32 +01001015 unsigned char channels[DIVERSITY_HOPS];
1016 int chlen;
1017 struct interface *route_ifp = route->neigh->ifp;
1018 struct babel_interface *babel_route_ifp = NULL;
1019 unsigned short metric;
1020 unsigned short seqno;
1021
Paul Jakma57345092011-12-25 17:52:09 +01001022 seqno = route->seqno;
Matthieu Boutierc35fafd2012-01-23 23:46:32 +01001023 metric =
1024 route_interferes(route, ifp) ?
1025 route_metric(route) :
1026 route_metric_noninterfering(route);
1027
Paul Jakma57345092011-12-25 17:52:09 +01001028 if(metric < INFINITY)
1029 satisfy_request(route->src->prefix, route->src->plen,
1030 seqno, route->src->id, ifp);
1031 if((babel_ifp->flags & BABEL_IF_SPLIT_HORIZON) &&
1032 route->neigh->ifp == ifp)
1033 continue;
Matthieu Boutierc35fafd2012-01-23 23:46:32 +01001034
1035 babel_route_ifp = babel_get_if_nfo(route_ifp);
1036 if(babel_route_ifp->channel ==BABEL_IF_CHANNEL_NONINTERFERING) {
1037 memcpy(channels, route->channels, DIVERSITY_HOPS);
1038 } else {
1039 if(babel_route_ifp->channel == BABEL_IF_CHANNEL_UNKNOWN)
1040 channels[0] = BABEL_IF_CHANNEL_INTERFERING;
1041 else {
1042 assert(babel_route_ifp->channel > 0 &&
1043 babel_route_ifp->channel <= 255);
1044 channels[0] = babel_route_ifp->channel;
1045 }
1046 memcpy(channels + 1, route->channels, DIVERSITY_HOPS - 1);
1047 }
1048
1049 chlen = channels_len(channels);
Paul Jakma57345092011-12-25 17:52:09 +01001050 really_send_update(ifp, route->src->id,
1051 route->src->prefix,
1052 route->src->plen,
Matthieu Boutierc35fafd2012-01-23 23:46:32 +01001053 seqno, metric,
1054 channels, chlen);
Paul Jakma57345092011-12-25 17:52:09 +01001055 update_source(route->src, seqno, metric);
1056 last_prefix = route->src->prefix;
1057 last_plen = route->src->plen;
1058 } else {
1059 /* There's no route for this prefix. This can happen shortly
1060 after an xroute has been retracted, so send a retraction. */
1061 really_send_update(ifp, myid, b[i].prefix, b[i].plen,
Matthieu Boutierc35fafd2012-01-23 23:46:32 +01001062 myseqno, INFINITY, NULL, -1);
Paul Jakma57345092011-12-25 17:52:09 +01001063 }
1064 }
1065 schedule_flush_now(ifp);
1066 done:
1067 free(b);
1068 }
1069 babel_ifp->update_flush_timeout.tv_sec = 0;
1070 babel_ifp->update_flush_timeout.tv_usec = 0;
1071}
1072
1073static void
1074schedule_update_flush(struct interface *ifp, int urgent)
1075{
1076 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
1077 unsigned msecs;
1078 msecs = update_jitter(babel_ifp, urgent);
1079 if(babel_ifp->update_flush_timeout.tv_sec != 0 &&
1080 timeval_minus_msec(&babel_ifp->update_flush_timeout, &babel_now) < msecs)
1081 return;
1082 set_timeout(&babel_ifp->update_flush_timeout, msecs);
1083}
1084
1085static void
1086buffer_update(struct interface *ifp,
1087 const unsigned char *prefix, unsigned char plen)
1088{
1089 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
1090 if(babel_ifp->num_buffered_updates > 0 &&
1091 babel_ifp->num_buffered_updates >= babel_ifp->update_bufsize)
1092 flushupdates(ifp);
1093
1094 if(babel_ifp->update_bufsize == 0) {
1095 int n;
1096 assert(babel_ifp->buffered_updates == NULL);
Matthieu Boutierc35fafd2012-01-23 23:46:32 +01001097 /* Allocate enough space to hold a full update. Since the
1098 number of installed routes will grow over time, make sure we
1099 have enough space to send a full-ish frame. */
1100 n = installed_routes_estimate() + xroutes_estimate() + 4;
1101 n = MAX(n, babel_ifp->bufsize / 16);
Paul Jakma57345092011-12-25 17:52:09 +01001102 again:
1103 babel_ifp->buffered_updates = malloc(n *sizeof(struct buffered_update));
1104 if(babel_ifp->buffered_updates == NULL) {
1105 zlog_err("malloc(buffered_updates): %s", safe_strerror(errno));
1106 if(n > 4) {
Matthieu Boutierc35fafd2012-01-23 23:46:32 +01001107 /* Try again with a tiny buffer. */
Paul Jakma57345092011-12-25 17:52:09 +01001108 n = 4;
1109 goto again;
1110 }
1111 return;
1112 }
1113 babel_ifp->update_bufsize = n;
1114 babel_ifp->num_buffered_updates = 0;
1115 }
1116
1117 memcpy(babel_ifp->buffered_updates[babel_ifp->num_buffered_updates].prefix,
1118 prefix, 16);
1119 babel_ifp->buffered_updates[babel_ifp->num_buffered_updates].plen = plen;
1120 babel_ifp->num_buffered_updates++;
1121}
1122
Matthieu Boutierc35fafd2012-01-23 23:46:32 +01001123static void
1124buffer_update_callback(struct babel_route *route, void *closure)
1125{
1126 buffer_update((struct interface*)closure,
1127 route->src->prefix, route->src->plen);
1128}
1129
Paul Jakma57345092011-12-25 17:52:09 +01001130void
1131send_update(struct interface *ifp, int urgent,
1132 const unsigned char *prefix, unsigned char plen)
1133{
1134 babel_interface_nfo *babel_ifp = NULL;
Paul Jakma57345092011-12-25 17:52:09 +01001135
1136 if(ifp == NULL) {
1137 struct interface *ifp_aux;
1138 struct listnode *linklist_node = NULL;
Denis Ovsienkoef4de4d2012-01-08 15:29:19 +04001139 struct babel_route *route;
Paul Jakma57345092011-12-25 17:52:09 +01001140 FOR_ALL_INTERFACES(ifp_aux, linklist_node)
1141 send_update(ifp_aux, urgent, prefix, plen);
1142 if(prefix) {
1143 /* Since flushupdates only deals with non-wildcard interfaces, we
1144 need to do this now. */
1145 route = find_installed_route(prefix, plen);
1146 if(route && route_metric(route) < INFINITY)
1147 satisfy_request(prefix, plen, route->src->seqno, route->src->id,
1148 NULL);
1149 }
1150 return;
1151 }
1152
1153 if(!if_up(ifp))
1154 return;
1155
1156 babel_ifp = babel_get_if_nfo(ifp);
1157 if(prefix) {
1158 if(!parasitic || find_xroute(prefix, plen)) {
1159 debugf(BABEL_DEBUG_COMMON,"Sending update to %s for %s.",
1160 ifp->name, format_prefix(prefix, plen));
1161 buffer_update(ifp, prefix, plen);
1162 }
1163 } else {
1164 if(!interface_idle(babel_ifp)) {
1165 send_self_update(ifp);
1166 if(!parasitic) {
Matthieu Boutierc35fafd2012-01-23 23:46:32 +01001167 debugf(BABEL_DEBUG_COMMON,"Sending update to %s for any.",
1168 ifp->name);
1169 for_all_installed_routes(buffer_update_callback, ifp);
Paul Jakma57345092011-12-25 17:52:09 +01001170 }
1171 }
1172 set_timeout(&babel_ifp->update_timeout, babel_ifp->update_interval);
Matthieu Boutierc35fafd2012-01-23 23:46:32 +01001173 babel_ifp->last_update_time = babel_now.tv_sec;
Paul Jakma57345092011-12-25 17:52:09 +01001174 }
1175 schedule_update_flush(ifp, urgent);
1176}
1177
1178void
1179send_update_resend(struct interface *ifp,
1180 const unsigned char *prefix, unsigned char plen)
1181{
1182 int delay;
1183
1184 assert(prefix != NULL);
1185
1186 send_update(ifp, 1, prefix, plen);
1187
1188 delay = 2000;
1189 delay = MIN(delay, wireless_hello_interval / 2);
1190 delay = MIN(delay, wired_hello_interval / 2);
1191 delay = MAX(delay, 10);
1192 record_resend(RESEND_UPDATE, prefix, plen, 0, 0, NULL, delay);
1193}
1194
1195void
1196send_wildcard_retraction(struct interface *ifp)
1197{
1198 babel_interface_nfo *babel_ifp = NULL;
1199 if(ifp == NULL) {
1200 struct interface *ifp_aux;
1201 struct listnode *linklist_node = NULL;
1202 FOR_ALL_INTERFACES(ifp_aux, linklist_node)
1203 send_wildcard_retraction(ifp_aux);
1204 return;
1205 }
1206
1207 if(!if_up(ifp))
1208 return;
1209
1210 babel_ifp = babel_get_if_nfo(ifp);
1211 start_message(ifp, MESSAGE_UPDATE, 10);
1212 accumulate_byte(ifp, 0);
1213 accumulate_byte(ifp, 0x40);
1214 accumulate_byte(ifp, 0);
1215 accumulate_byte(ifp, 0);
1216 accumulate_short(ifp, 0xFFFF);
1217 accumulate_short(ifp, myseqno);
1218 accumulate_short(ifp, 0xFFFF);
1219 end_message(ifp, MESSAGE_UPDATE, 10);
1220
1221 babel_ifp->have_buffered_id = 0;
1222}
1223
1224void
1225update_myseqno()
1226{
1227 myseqno = seqno_plus(myseqno, 1);
1228 seqno_time = babel_now;
1229}
1230
Matthieu Boutierc35fafd2012-01-23 23:46:32 +01001231static void
1232send_xroute_update_callback(struct xroute *xroute, void *closure)
1233{
1234 struct interface *ifp = (struct interface*)closure;
1235 send_update(ifp, 0, xroute->prefix, xroute->plen);
1236}
1237
Paul Jakma57345092011-12-25 17:52:09 +01001238void
1239send_self_update(struct interface *ifp)
1240{
Paul Jakma57345092011-12-25 17:52:09 +01001241 if(ifp == NULL) {
1242 struct interface *ifp_aux;
1243 struct listnode *linklist_node = NULL;
1244 FOR_ALL_INTERFACES(ifp_aux, linklist_node) {
1245 if(!if_up(ifp_aux))
1246 continue;
1247 send_self_update(ifp_aux);
1248 }
1249 return;
1250 }
1251
1252 if(!interface_idle(babel_get_if_nfo(ifp))) {
1253 debugf(BABEL_DEBUG_COMMON,"Sending self update to %s.", ifp->name);
Matthieu Boutierc35fafd2012-01-23 23:46:32 +01001254 for_all_xroutes(send_xroute_update_callback, ifp);
Paul Jakma57345092011-12-25 17:52:09 +01001255 }
1256}
1257
1258void
1259send_ihu(struct neighbour *neigh, struct interface *ifp)
1260{
1261 babel_interface_nfo *babel_ifp = NULL;
1262 int rxcost, interval;
1263 int ll;
1264
1265 if(neigh == NULL && ifp == NULL) {
1266 struct interface *ifp_aux;
1267 struct listnode *linklist_node = NULL;
1268 FOR_ALL_INTERFACES(ifp_aux, linklist_node) {
1269 if(if_up(ifp_aux))
1270 continue;
1271 send_ihu(NULL, ifp_aux);
1272 }
1273 return;
1274 }
1275
1276 if(neigh == NULL) {
1277 struct neighbour *ngh;
1278 FOR_ALL_NEIGHBOURS(ngh) {
1279 if(ngh->ifp == ifp)
1280 send_ihu(ngh, ifp);
1281 }
1282 return;
1283 }
1284
1285
1286 if(ifp && neigh->ifp != ifp)
1287 return;
1288
1289 ifp = neigh->ifp;
1290 babel_ifp = babel_get_if_nfo(ifp);
1291 if(!if_up(ifp))
1292 return;
1293
1294 rxcost = neighbour_rxcost(neigh);
1295 interval = (babel_ifp->hello_interval * 3 + 9) / 10;
1296
1297 /* Conceptually, an IHU is a unicast message. We usually send them as
1298 multicast, since this allows aggregation into a single packet and
1299 avoids an ARP exchange. If we already have a unicast message queued
1300 for this neighbour, however, we might as well piggyback the IHU. */
1301 debugf(BABEL_DEBUG_COMMON,"Sending %sihu %d on %s to %s.",
1302 unicast_neighbour == neigh ? "unicast " : "",
1303 rxcost,
1304 neigh->ifp->name,
1305 format_address(neigh->address));
1306
1307 ll = linklocal(neigh->address);
1308
1309 if(unicast_neighbour != neigh) {
1310 start_message(ifp, MESSAGE_IHU, ll ? 14 : 22);
1311 accumulate_byte(ifp, ll ? 3 : 2);
1312 accumulate_byte(ifp, 0);
1313 accumulate_short(ifp, rxcost);
1314 accumulate_short(ifp, interval);
1315 if(ll)
1316 accumulate_bytes(ifp, neigh->address + 8, 8);
1317 else
1318 accumulate_bytes(ifp, neigh->address, 16);
1319 end_message(ifp, MESSAGE_IHU, ll ? 14 : 22);
1320 } else {
1321 int rc;
1322 rc = start_unicast_message(neigh, MESSAGE_IHU, ll ? 14 : 22);
1323 if(rc < 0) return;
1324 accumulate_unicast_byte(neigh, ll ? 3 : 2);
1325 accumulate_unicast_byte(neigh, 0);
1326 accumulate_unicast_short(neigh, rxcost);
1327 accumulate_unicast_short(neigh, interval);
1328 if(ll)
1329 accumulate_unicast_bytes(neigh, neigh->address + 8, 8);
1330 else
1331 accumulate_unicast_bytes(neigh, neigh->address, 16);
1332 end_unicast_message(neigh, MESSAGE_IHU, ll ? 14 : 22);
1333 }
1334}
1335
1336/* Send IHUs to all marginal neighbours */
1337void
1338send_marginal_ihu(struct interface *ifp)
1339{
1340 struct neighbour *neigh;
1341 FOR_ALL_NEIGHBOURS(neigh) {
1342 if(ifp && neigh->ifp != ifp)
1343 continue;
1344 if(neigh->txcost >= 384 || (neigh->reach & 0xF000) != 0xF000)
1345 send_ihu(neigh, ifp);
1346 }
1347}
1348
1349void
1350send_request(struct interface *ifp,
1351 const unsigned char *prefix, unsigned char plen)
1352{
Paul Jakma57345092011-12-25 17:52:09 +01001353 int v4, len;
1354
1355 if(ifp == NULL) {
1356 struct interface *ifp_aux;
1357 struct listnode *linklist_node = NULL;
1358 FOR_ALL_INTERFACES(ifp_aux, linklist_node) {
1359 if(if_up(ifp_aux))
1360 continue;
1361 send_request(ifp_aux, prefix, plen);
1362 }
1363 return;
1364 }
1365
1366 /* make sure any buffered updates go out before this request. */
1367 flushupdates(ifp);
1368
1369 if(!if_up(ifp))
1370 return;
1371
Paul Jakma57345092011-12-25 17:52:09 +01001372 debugf(BABEL_DEBUG_COMMON,"sending request to %s for %s.",
1373 ifp->name, prefix ? format_prefix(prefix, plen) : "any");
1374 v4 = plen >= 96 && v4mapped(prefix);
1375 len = !prefix ? 2 : v4 ? 6 : 18;
1376
1377 start_message(ifp, MESSAGE_REQUEST, len);
1378 accumulate_byte(ifp, !prefix ? 0 : v4 ? 1 : 2);
1379 accumulate_byte(ifp, !prefix ? 0 : v4 ? plen - 96 : plen);
1380 if(prefix) {
1381 if(v4)
1382 accumulate_bytes(ifp, prefix + 12, 4);
1383 else
1384 accumulate_bytes(ifp, prefix, 16);
1385 }
1386 end_message(ifp, MESSAGE_REQUEST, len);
1387}
1388
1389void
1390send_unicast_request(struct neighbour *neigh,
1391 const unsigned char *prefix, unsigned char plen)
1392{
1393 int rc, v4, len;
1394
1395 /* make sure any buffered updates go out before this request. */
1396 flushupdates(neigh->ifp);
1397
1398 debugf(BABEL_DEBUG_COMMON,"sending unicast request to %s for %s.",
1399 format_address(neigh->address),
1400 prefix ? format_prefix(prefix, plen) : "any");
1401 v4 = plen >= 96 && v4mapped(prefix);
1402 len = !prefix ? 2 : v4 ? 6 : 18;
1403
1404 rc = start_unicast_message(neigh, MESSAGE_REQUEST, len);
1405 if(rc < 0) return;
1406 accumulate_unicast_byte(neigh, !prefix ? 0 : v4 ? 1 : 2);
1407 accumulate_unicast_byte(neigh, !prefix ? 0 : v4 ? plen - 96 : plen);
1408 if(prefix) {
1409 if(v4)
1410 accumulate_unicast_bytes(neigh, prefix + 12, 4);
1411 else
1412 accumulate_unicast_bytes(neigh, prefix, 16);
1413 }
1414 end_unicast_message(neigh, MESSAGE_REQUEST, len);
1415}
1416
1417void
1418send_multihop_request(struct interface *ifp,
1419 const unsigned char *prefix, unsigned char plen,
1420 unsigned short seqno, const unsigned char *id,
1421 unsigned short hop_count)
1422{
Paul Jakma57345092011-12-25 17:52:09 +01001423 int v4, pb, len;
1424
1425 /* Make sure any buffered updates go out before this request. */
1426 flushupdates(ifp);
1427
1428 if(ifp == NULL) {
1429 struct interface *ifp_aux;
1430 struct listnode *linklist_node = NULL;
1431 FOR_ALL_INTERFACES(ifp_aux, linklist_node) {
1432 if(!if_up(ifp_aux))
1433 continue;
1434 send_multihop_request(ifp_aux, prefix, plen, seqno, id, hop_count);
1435 }
1436 return;
1437 }
1438
1439 if(!if_up(ifp))
1440 return;
1441
Paul Jakma57345092011-12-25 17:52:09 +01001442 debugf(BABEL_DEBUG_COMMON,"Sending request (%d) on %s for %s.",
1443 hop_count, ifp->name, format_prefix(prefix, plen));
1444 v4 = plen >= 96 && v4mapped(prefix);
1445 pb = v4 ? ((plen - 96) + 7) / 8 : (plen + 7) / 8;
1446 len = 6 + 8 + pb;
1447
1448 start_message(ifp, MESSAGE_MH_REQUEST, len);
1449 accumulate_byte(ifp, v4 ? 1 : 2);
1450 accumulate_byte(ifp, v4 ? plen - 96 : plen);
1451 accumulate_short(ifp, seqno);
1452 accumulate_byte(ifp, hop_count);
1453 accumulate_byte(ifp, 0);
1454 accumulate_bytes(ifp, id, 8);
1455 if(prefix) {
1456 if(v4)
1457 accumulate_bytes(ifp, prefix + 12, pb);
1458 else
1459 accumulate_bytes(ifp, prefix, pb);
1460 }
1461 end_message(ifp, MESSAGE_MH_REQUEST, len);
1462}
1463
1464void
1465send_unicast_multihop_request(struct neighbour *neigh,
1466 const unsigned char *prefix, unsigned char plen,
1467 unsigned short seqno, const unsigned char *id,
1468 unsigned short hop_count)
1469{
1470 int rc, v4, pb, len;
1471
1472 /* Make sure any buffered updates go out before this request. */
1473 flushupdates(neigh->ifp);
1474
1475 debugf(BABEL_DEBUG_COMMON,"Sending multi-hop request to %s for %s (%d hops).",
1476 format_address(neigh->address),
1477 format_prefix(prefix, plen), hop_count);
1478 v4 = plen >= 96 && v4mapped(prefix);
1479 pb = v4 ? ((plen - 96) + 7) / 8 : (plen + 7) / 8;
1480 len = 6 + 8 + pb;
1481
1482 rc = start_unicast_message(neigh, MESSAGE_MH_REQUEST, len);
1483 if(rc < 0) return;
1484 accumulate_unicast_byte(neigh, v4 ? 1 : 2);
1485 accumulate_unicast_byte(neigh, v4 ? plen - 96 : plen);
1486 accumulate_unicast_short(neigh, seqno);
1487 accumulate_unicast_byte(neigh, hop_count);
1488 accumulate_unicast_byte(neigh, 0);
1489 accumulate_unicast_bytes(neigh, id, 8);
1490 if(prefix) {
1491 if(v4)
1492 accumulate_unicast_bytes(neigh, prefix + 12, pb);
1493 else
1494 accumulate_unicast_bytes(neigh, prefix, pb);
1495 }
1496 end_unicast_message(neigh, MESSAGE_MH_REQUEST, len);
1497}
1498
1499void
1500send_request_resend(struct neighbour *neigh,
1501 const unsigned char *prefix, unsigned char plen,
1502 unsigned short seqno, unsigned char *id)
1503{
1504 int delay;
1505
1506 if(neigh)
1507 send_unicast_multihop_request(neigh, prefix, plen, seqno, id, 127);
1508 else
1509 send_multihop_request(NULL, prefix, plen, seqno, id, 127);
1510
1511 delay = 2000;
1512 delay = MIN(delay, wireless_hello_interval / 2);
1513 delay = MIN(delay, wired_hello_interval / 2);
1514 delay = MAX(delay, 10);
1515 record_resend(RESEND_REQUEST, prefix, plen, seqno, id,
1516 neigh ? neigh->ifp : NULL, delay);
1517}
1518
1519void
1520handle_request(struct neighbour *neigh, const unsigned char *prefix,
1521 unsigned char plen, unsigned char hop_count,
1522 unsigned short seqno, const unsigned char *id)
1523{
1524 struct xroute *xroute;
Denis Ovsienkoef4de4d2012-01-08 15:29:19 +04001525 struct babel_route *route;
Paul Jakma57345092011-12-25 17:52:09 +01001526 struct neighbour *successor = NULL;
1527
1528 xroute = find_xroute(prefix, plen);
1529 route = find_installed_route(prefix, plen);
1530
1531 if(xroute && (!route || xroute->metric <= kernel_metric)) {
1532 if(hop_count > 0 && memcmp(id, myid, 8) == 0) {
1533 if(seqno_compare(seqno, myseqno) > 0) {
1534 if(seqno_minus(seqno, myseqno) > 100) {
1535 /* Hopelessly out-of-date request */
1536 return;
1537 }
1538 update_myseqno();
1539 }
1540 }
1541 send_update(neigh->ifp, 1, prefix, plen);
1542 return;
1543 }
1544
1545 if(route &&
1546 (memcmp(id, route->src->id, 8) != 0 ||
1547 seqno_compare(seqno, route->seqno) <= 0)) {
1548 send_update(neigh->ifp, 1, prefix, plen);
1549 return;
1550 }
1551
1552 if(hop_count <= 1)
1553 return;
1554
1555 if(route && memcmp(id, route->src->id, 8) == 0 &&
1556 seqno_minus(seqno, route->seqno) > 100) {
1557 /* Hopelessly out-of-date */
1558 return;
1559 }
1560
1561 if(request_redundant(neigh->ifp, prefix, plen, seqno, id))
1562 return;
1563
1564 /* Let's try to forward this request. */
1565 if(route && route_metric(route) < INFINITY)
1566 successor = route->neigh;
1567
1568 if(!successor || successor == neigh) {
1569 /* We were about to forward a request to its requestor. Try to
1570 find a different neighbour to forward the request to. */
Denis Ovsienkoef4de4d2012-01-08 15:29:19 +04001571 struct babel_route *other_route;
Paul Jakma57345092011-12-25 17:52:09 +01001572
1573 other_route = find_best_route(prefix, plen, 0, neigh);
1574 if(other_route && route_metric(other_route) < INFINITY)
1575 successor = other_route->neigh;
1576 }
1577
1578 if(!successor || successor == neigh)
1579 /* Give up */
1580 return;
1581
1582 send_unicast_multihop_request(successor, prefix, plen, seqno, id,
1583 hop_count - 1);
1584 record_resend(RESEND_REQUEST, prefix, plen, seqno, id,
1585 neigh->ifp, 0);
1586}