blob: 7930a1b13929b0349dba1b5069e5af9a9d53cd37 [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
72static int
73network_prefix(int ae, int plen, unsigned int omitted,
74 const unsigned char *p, const unsigned char *dp,
75 unsigned int len, unsigned char *p_r)
76{
77 unsigned pb;
78 unsigned char prefix[16];
79
80 if(plen >= 0)
81 pb = (plen + 7) / 8;
82 else if(ae == 1)
83 pb = 4;
84 else
85 pb = 16;
86
87 if(pb > 16)
88 return -1;
89
90 memset(prefix, 0, 16);
91
92 switch(ae) {
93 case 0: break;
94 case 1:
95 if(omitted > 4 || pb > 4 || (pb > omitted && len < pb - omitted))
96 return -1;
97 memcpy(prefix, v4prefix, 12);
98 if(omitted) {
99 if (dp == NULL || !v4mapped(dp)) return -1;
100 memcpy(prefix, dp, 12 + omitted);
101 }
102 if(pb > omitted) memcpy(prefix + 12 + omitted, p, pb - omitted);
103 break;
104 case 2:
105 if(omitted > 16 || (pb > omitted && len < pb - omitted)) return -1;
106 if(omitted) {
107 if (dp == NULL || v4mapped(dp)) return -1;
108 memcpy(prefix, dp, omitted);
109 }
110 if(pb > omitted) memcpy(prefix + omitted, p, pb - omitted);
111 break;
112 case 3:
113 if(pb > 8 && len < pb - 8) return -1;
114 prefix[0] = 0xfe;
115 prefix[1] = 0x80;
116 if(pb > 8) memcpy(prefix + 8, p, pb - 8);
117 break;
118 default:
119 return -1;
120 }
121
122 mask_prefix(p_r, prefix, plen < 0 ? 128 : ae == 1 ? plen + 96 : plen);
123 return 1;
124}
125
126static int
127network_address(int ae, const unsigned char *a, unsigned int len,
128 unsigned char *a_r)
129{
130 return network_prefix(ae, -1, 0, a, NULL, len, a_r);
131}
132
133void
134parse_packet(const unsigned char *from, struct interface *ifp,
135 const unsigned char *packet, int packetlen)
136{
137 int i;
138 const unsigned char *message;
139 unsigned char type, len;
140 int bodylen;
141 struct neighbour *neigh;
142 int have_router_id = 0, have_v4_prefix = 0, have_v6_prefix = 0,
143 have_v4_nh = 0, have_v6_nh = 0;
144 unsigned char router_id[8], v4_prefix[16], v6_prefix[16],
145 v4_nh[16], v6_nh[16];
146
147 if(!linklocal(from)) {
148 fprintf(stderr, "Received packet from non-local address %s.\n",
149 format_address(from));
150 return;
151 }
152
153 if(packet[0] != 42) {
154 fprintf(stderr, "Received malformed packet on %s from %s.\n",
155 ifp->name, format_address(from));
156 return;
157 }
158
159 if(packet[1] != 2) {
160 fprintf(stderr,
161 "Received packet with unknown version %d on %s from %s.\n",
162 packet[1], ifp->name, format_address(from));
163 return;
164 }
165
166 neigh = find_neighbour(from, ifp);
167 if(neigh == NULL) {
168 fprintf(stderr, "Couldn't allocate neighbour.\n");
169 return;
170 }
171
172 DO_NTOHS(bodylen, packet + 2);
173
174 if(bodylen + 4 > packetlen) {
175 fprintf(stderr, "Received truncated packet (%d + 4 > %d).\n",
176 bodylen, packetlen);
177 bodylen = packetlen - 4;
178 }
179
180 i = 0;
181 while(i < bodylen) {
182 message = packet + 4 + i;
183 type = message[0];
184 if(type == MESSAGE_PAD1) {
185 debugf(BABEL_DEBUG_COMMON,"Received pad1 from %s on %s.",
186 format_address(from), ifp->name);
187 i++;
188 continue;
189 }
190 if(i + 1 > bodylen) {
191 fprintf(stderr, "Received truncated message.\n");
192 break;
193 }
194 len = message[1];
195 if(i + len > bodylen) {
196 fprintf(stderr, "Received truncated message.\n");
197 break;
198 }
199
200 if(type == MESSAGE_PADN) {
201 debugf(BABEL_DEBUG_COMMON,"Received pad%d from %s on %s.",
202 len, format_address(from), ifp->name);
203 } else if(type == MESSAGE_ACK_REQ) {
204 unsigned short nonce, interval;
205 if(len < 6) goto fail;
206 DO_NTOHS(nonce, message + 4);
207 DO_NTOHS(interval, message + 6);
208 debugf(BABEL_DEBUG_COMMON,"Received ack-req (%04X %d) from %s on %s.",
209 nonce, interval, format_address(from), ifp->name);
210 send_ack(neigh, nonce, interval);
211 } else if(type == MESSAGE_ACK) {
212 debugf(BABEL_DEBUG_COMMON,"Received ack from %s on %s.",
213 format_address(from), ifp->name);
214 /* Nothing right now */
215 } else if(type == MESSAGE_HELLO) {
216 unsigned short seqno, interval;
217 int changed;
218 if(len < 6) goto fail;
219 DO_NTOHS(seqno, message + 4);
220 DO_NTOHS(interval, message + 6);
221 debugf(BABEL_DEBUG_COMMON,"Received hello %d (%d) from %s on %s.",
222 seqno, interval,
223 format_address(from), ifp->name);
224 babel_get_if_nfo(ifp)->activity_time = babel_now.tv_sec;
225 changed = update_neighbour(neigh, seqno, interval);
226 update_neighbour_metric(neigh, changed);
227 if(interval > 0)
228 schedule_neighbours_check(interval * 10, 0);
229 } else if(type == MESSAGE_IHU) {
230 unsigned short txcost, interval;
231 unsigned char address[16];
232 int rc;
233 if(len < 6) goto fail;
234 DO_NTOHS(txcost, message + 4);
235 DO_NTOHS(interval, message + 6);
236 rc = network_address(message[2], message + 8, len - 6, address);
237 if(rc < 0) goto fail;
238 debugf(BABEL_DEBUG_COMMON,"Received ihu %d (%d) from %s on %s for %s.",
239 txcost, interval,
240 format_address(from), ifp->name,
241 format_address(address));
242 if(message[2] == 0 || is_interface_ll_address(ifp, address)) {
243 int changed = txcost != neigh->txcost;
244 neigh->txcost = txcost;
245 neigh->ihu_time = babel_now;
246 neigh->ihu_interval = interval;
247 update_neighbour_metric(neigh, changed);
248 if(interval > 0)
249 schedule_neighbours_check(interval * 10 * 3, 0);
250 }
251 } else if(type == MESSAGE_ROUTER_ID) {
252 if(len < 10) {
253 have_router_id = 0;
254 goto fail;
255 }
256 memcpy(router_id, message + 4, 8);
257 have_router_id = 1;
258 debugf(BABEL_DEBUG_COMMON,"Received router-id %s from %s on %s.",
259 format_eui64(router_id), format_address(from), ifp->name);
260 } else if(type == MESSAGE_NH) {
261 unsigned char nh[16];
262 int rc;
263 if(len < 2) {
264 have_v4_nh = 0;
265 have_v6_nh = 0;
266 goto fail;
267 }
268 rc = network_address(message[2], message + 4, len - 2,
269 nh);
270 if(rc < 0) {
271 have_v4_nh = 0;
272 have_v6_nh = 0;
273 goto fail;
274 }
275 debugf(BABEL_DEBUG_COMMON,"Received nh %s (%d) from %s on %s.",
276 format_address(nh), message[2],
277 format_address(from), ifp->name);
278 if(message[2] == 1) {
279 memcpy(v4_nh, nh, 16);
280 have_v4_nh = 1;
281 } else {
282 memcpy(v6_nh, nh, 16);
283 have_v6_nh = 1;
284 }
285 } else if(type == MESSAGE_UPDATE) {
286 unsigned char prefix[16], *nh;
287 unsigned char plen;
288 unsigned short interval, seqno, metric;
289 int rc;
290 if(len < 10) {
291 if(len < 2 || message[3] & 0x80)
292 have_v4_prefix = have_v6_prefix = 0;
293 goto fail;
294 }
295 DO_NTOHS(interval, message + 6);
296 DO_NTOHS(seqno, message + 8);
297 DO_NTOHS(metric, message + 10);
298 if(message[5] == 0 ||
299 (message[3] == 1 ? have_v4_prefix : have_v6_prefix))
300 rc = network_prefix(message[2], message[4], message[5],
301 message + 12,
302 message[2] == 1 ? v4_prefix : v6_prefix,
303 len - 10, prefix);
304 else
305 rc = -1;
306 if(rc < 0) {
307 if(message[3] & 0x80)
308 have_v4_prefix = have_v6_prefix = 0;
309 goto fail;
310 }
311
312 plen = message[4] + (message[2] == 1 ? 96 : 0);
313
314 if(message[3] & 0x80) {
315 if(message[2] == 1) {
316 memcpy(v4_prefix, prefix, 16);
317 have_v4_prefix = 1;
318 } else {
319 memcpy(v6_prefix, prefix, 16);
320 have_v6_prefix = 1;
321 }
322 }
323 if(message[3] & 0x40) {
324 if(message[2] == 1) {
325 memset(router_id, 0, 4);
326 memcpy(router_id + 4, prefix + 12, 4);
327 } else {
328 memcpy(router_id, prefix + 8, 8);
329 }
330 have_router_id = 1;
331 }
332 if(!have_router_id && message[2] != 0) {
333 fprintf(stderr, "Received prefix with no router id.\n");
334 goto fail;
335 }
336 debugf(BABEL_DEBUG_COMMON,"Received update%s%s for %s from %s on %s.",
337 (message[3] & 0x80) ? "/prefix" : "",
338 (message[3] & 0x40) ? "/id" : "",
339 format_prefix(prefix, plen),
340 format_address(from), ifp->name);
341
342 if(message[2] == 0) {
343 if(metric < 0xFFFF) {
344 fprintf(stderr,
345 "Received wildcard update with finite metric.\n");
346 goto done;
347 }
348 retract_neighbour_routes(neigh);
349 goto done;
350 } else if(message[2] == 1) {
351 if(!have_v4_nh)
352 goto fail;
353 nh = v4_nh;
354 } else if(have_v6_nh) {
355 nh = v6_nh;
356 } else {
357 nh = neigh->address;
358 }
359
360 if(message[2] == 1) {
361 if(!babel_get_if_nfo(ifp)->ipv4)
362 goto done;
363 }
364
365 update_route(router_id, prefix, plen, seqno, metric, interval,
366 neigh, nh);
367 } else if(type == MESSAGE_REQUEST) {
368 unsigned char prefix[16], plen;
369 int rc;
370 if(len < 2) goto fail;
371 rc = network_prefix(message[2], message[3], 0,
372 message + 4, NULL, len - 2, prefix);
373 if(rc < 0) goto fail;
374 plen = message[3] + (message[2] == 1 ? 96 : 0);
375 debugf(BABEL_DEBUG_COMMON,"Received request for %s from %s on %s.",
376 message[2] == 0 ? "any" : format_prefix(prefix, plen),
377 format_address(from), ifp->name);
378 if(message[2] == 0) {
379 /* If a neighbour is requesting a full route dump from us,
380 we might as well send it an IHU. */
381 send_ihu(neigh, NULL);
382 send_update(neigh->ifp, 0, NULL, 0);
383 } else {
384 send_update(neigh->ifp, 0, prefix, plen);
385 }
386 } else if(type == MESSAGE_MH_REQUEST) {
387 unsigned char prefix[16], plen;
388 unsigned short seqno;
389 int rc;
390 if(len < 14) goto fail;
391 DO_NTOHS(seqno, message + 4);
392 rc = network_prefix(message[2], message[3], 0,
393 message + 16, NULL, len - 14, prefix);
394 if(rc < 0) goto fail;
395 plen = message[3] + (message[2] == 1 ? 96 : 0);
396 debugf(BABEL_DEBUG_COMMON,"Received request (%d) for %s from %s on %s (%s, %d).",
397 message[6],
398 format_prefix(prefix, plen),
399 format_address(from), ifp->name,
400 format_eui64(message + 8), seqno);
401 handle_request(neigh, prefix, plen, message[6],
402 seqno, message + 8);
403 } else {
404 debugf(BABEL_DEBUG_COMMON,"Received unknown packet type %d from %s on %s.",
405 type, format_address(from), ifp->name);
406 }
407 done:
408 i += len + 2;
409 continue;
410
411 fail:
412 fprintf(stderr, "Couldn't parse packet (%d, %d) from %s on %s.\n",
413 message[0], message[1], format_address(from), ifp->name);
414 goto done;
415 }
416 return;
417}
418
419/* Under normal circumstances, there are enough moderation mechanisms
420 elsewhere in the protocol to make sure that this last-ditch check
421 should never trigger. But I'm superstitious. */
422
423static int
424check_bucket(struct interface *ifp)
425{
426 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
427 if(babel_ifp->bucket <= 0) {
428 int seconds = babel_now.tv_sec - babel_ifp->bucket_time;
429 if(seconds > 0) {
430 babel_ifp->bucket = MIN(BUCKET_TOKENS_MAX,
431 seconds * BUCKET_TOKENS_PER_SEC);
432 }
433 /* Reset bucket time unconditionally, in case clock is stepped. */
434 babel_ifp->bucket_time = babel_now.tv_sec;
435 }
436
437 if(babel_ifp->bucket > 0) {
438 babel_ifp->bucket--;
439 return 1;
440 } else {
441 return 0;
442 }
443}
444
445void
446flushbuf(struct interface *ifp)
447{
448 int rc;
449 struct sockaddr_in6 sin6;
450 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
451
452 assert(babel_ifp->buffered <= babel_ifp->bufsize);
453
454 flushupdates(ifp);
455
456 if(babel_ifp->buffered > 0) {
457 debugf(BABEL_DEBUG_COMMON," (flushing %d buffered bytes on %s)",
458 babel_ifp->buffered, ifp->name);
459 if(check_bucket(ifp)) {
460 memset(&sin6, 0, sizeof(sin6));
461 sin6.sin6_family = AF_INET6;
462 memcpy(&sin6.sin6_addr, protocol_group, 16);
463 sin6.sin6_port = htons(protocol_port);
464 sin6.sin6_scope_id = ifp->ifindex;
465 DO_HTONS(packet_header + 2, babel_ifp->buffered);
466 rc = babel_send(protocol_socket,
467 packet_header, sizeof(packet_header),
468 babel_ifp->sendbuf, babel_ifp->buffered,
469 (struct sockaddr*)&sin6, sizeof(sin6));
470 if(rc < 0)
471 zlog_err("send: %s", safe_strerror(errno));
472 } else {
473 fprintf(stderr, "Warning: bucket full, dropping packet to %s.\n",
474 ifp->name);
475 }
476 }
477 VALGRIND_MAKE_MEM_UNDEFINED(babel_ifp->sendbuf, babel_ifp->bufsize);
478 babel_ifp->buffered = 0;
479 babel_ifp->have_buffered_hello = 0;
480 babel_ifp->have_buffered_id = 0;
481 babel_ifp->have_buffered_nh = 0;
482 babel_ifp->have_buffered_prefix = 0;
483 babel_ifp->flush_timeout.tv_sec = 0;
484 babel_ifp->flush_timeout.tv_usec = 0;
485}
486
487static void
488schedule_flush(struct interface *ifp)
489{
490 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
491 unsigned msecs = jitter(babel_ifp, 0);
492 if(babel_ifp->flush_timeout.tv_sec != 0 &&
493 timeval_minus_msec(&babel_ifp->flush_timeout, &babel_now) < msecs)
494 return;
495 set_timeout(&babel_ifp->flush_timeout, msecs);
496}
497
498static void
499schedule_flush_now(struct interface *ifp)
500{
501 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
502 /* Almost now */
503 unsigned msecs = roughly(10);
504 if(babel_ifp->flush_timeout.tv_sec != 0 &&
505 timeval_minus_msec(&babel_ifp->flush_timeout, &babel_now) < msecs)
506 return;
507 set_timeout(&babel_ifp->flush_timeout, msecs);
508}
509
510static void
511schedule_unicast_flush(unsigned msecs)
512{
513 if(!unicast_neighbour)
514 return;
515 if(unicast_flush_timeout.tv_sec != 0 &&
516 timeval_minus_msec(&unicast_flush_timeout, &babel_now) < msecs)
517 return;
518 unicast_flush_timeout.tv_usec = (babel_now.tv_usec + msecs * 1000) %1000000;
519 unicast_flush_timeout.tv_sec =
520 babel_now.tv_sec + (babel_now.tv_usec / 1000 + msecs) / 1000;
521}
522
523static void
524ensure_space(struct interface *ifp, int space)
525{
526 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
527 if(babel_ifp->bufsize - babel_ifp->buffered < space)
528 flushbuf(ifp);
529}
530
531static void
532start_message(struct interface *ifp, int type, int len)
533{
534 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
535 if(babel_ifp->bufsize - babel_ifp->buffered < len + 2)
536 flushbuf(ifp);
537 babel_ifp->sendbuf[babel_ifp->buffered++] = type;
538 babel_ifp->sendbuf[babel_ifp->buffered++] = len;
539}
540
541static void
542end_message(struct interface *ifp, int type, int bytes)
543{
544 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
545 assert(babel_ifp->buffered >= bytes + 2 &&
546 babel_ifp->sendbuf[babel_ifp->buffered - bytes - 2] == type &&
547 babel_ifp->sendbuf[babel_ifp->buffered - bytes - 1] == bytes);
548 schedule_flush(ifp);
549}
550
551static void
552accumulate_byte(struct interface *ifp, unsigned char value)
553{
554 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
555 babel_ifp->sendbuf[babel_ifp->buffered++] = value;
556}
557
558static void
559accumulate_short(struct interface *ifp, unsigned short value)
560{
561 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
562 DO_HTONS(babel_ifp->sendbuf + babel_ifp->buffered, value);
563 babel_ifp->buffered += 2;
564}
565
566static void
567accumulate_bytes(struct interface *ifp,
568 const unsigned char *value, unsigned len)
569{
570 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
571 memcpy(babel_ifp->sendbuf + babel_ifp->buffered, value, len);
572 babel_ifp->buffered += len;
573}
574
575static int
576start_unicast_message(struct neighbour *neigh, int type, int len)
577{
578 if(unicast_neighbour) {
579 if(neigh != unicast_neighbour ||
580 unicast_buffered + len + 2 >=
581 MIN(UNICAST_BUFSIZE, babel_get_if_nfo(neigh->ifp)->bufsize))
582 flush_unicast(0);
583 }
584 if(!unicast_buffer)
585 unicast_buffer = malloc(UNICAST_BUFSIZE);
586 if(!unicast_buffer) {
587 zlog_err("malloc(unicast_buffer): %s", safe_strerror(errno));
588 return -1;
589 }
590
591 unicast_neighbour = neigh;
592
593 unicast_buffer[unicast_buffered++] = type;
594 unicast_buffer[unicast_buffered++] = len;
595 return 1;
596}
597
598static void
599end_unicast_message(struct neighbour *neigh, int type, int bytes)
600{
601 assert(unicast_neighbour == neigh && unicast_buffered >= bytes + 2 &&
602 unicast_buffer[unicast_buffered - bytes - 2] == type &&
603 unicast_buffer[unicast_buffered - bytes - 1] == bytes);
604 schedule_unicast_flush(jitter(babel_get_if_nfo(neigh->ifp), 0));
605}
606
607static void
608accumulate_unicast_byte(struct neighbour *neigh, unsigned char value)
609{
610 unicast_buffer[unicast_buffered++] = value;
611}
612
613static void
614accumulate_unicast_short(struct neighbour *neigh, unsigned short value)
615{
616 DO_HTONS(unicast_buffer + unicast_buffered, value);
617 unicast_buffered += 2;
618}
619
620static void
621accumulate_unicast_bytes(struct neighbour *neigh,
622 const unsigned char *value, unsigned len)
623{
624 memcpy(unicast_buffer + unicast_buffered, value, len);
625 unicast_buffered += len;
626}
627
628void
629send_ack(struct neighbour *neigh, unsigned short nonce, unsigned short interval)
630{
631 int rc;
632 debugf(BABEL_DEBUG_COMMON,"Sending ack (%04x) to %s on %s.",
633 nonce, format_address(neigh->address), neigh->ifp->name);
634 rc = start_unicast_message(neigh, MESSAGE_ACK, 2); if(rc < 0) return;
635 accumulate_unicast_short(neigh, nonce);
636 end_unicast_message(neigh, MESSAGE_ACK, 2);
637 /* Roughly yields a value no larger than 3/2, so this meets the deadline */
638 schedule_unicast_flush(roughly(interval * 6));
639}
640
641void
642send_hello_noupdate(struct interface *ifp, unsigned interval)
643{
644 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
645 /* This avoids sending multiple hellos in a single packet, which breaks
646 link quality estimation. */
647 if(babel_ifp->have_buffered_hello)
648 flushbuf(ifp);
649
650 babel_ifp->hello_seqno = seqno_plus(babel_ifp->hello_seqno, 1);
651 set_timeout(&babel_ifp->hello_timeout, babel_ifp->hello_interval);
652
653 if(!if_up(ifp))
654 return;
655
656 debugf(BABEL_DEBUG_COMMON,"Sending hello %d (%d) to %s.",
657 babel_ifp->hello_seqno, interval, ifp->name);
658
659 start_message(ifp, MESSAGE_HELLO, 6);
660 accumulate_short(ifp, 0);
661 accumulate_short(ifp, babel_ifp->hello_seqno);
662 accumulate_short(ifp, interval > 0xFFFF ? 0xFFFF : interval);
663 end_message(ifp, MESSAGE_HELLO, 6);
664 babel_ifp->have_buffered_hello = 1;
665}
666
667void
668send_hello(struct interface *ifp)
669{
670 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
671 send_hello_noupdate(ifp, (babel_ifp->hello_interval + 9) / 10);
672 /* Send full IHU every 3 hellos, and marginal IHU each time */
673 if(babel_ifp->hello_seqno % 3 == 0)
674 send_ihu(NULL, ifp);
675 else
676 send_marginal_ihu(ifp);
677}
678
679void
680flush_unicast(int dofree)
681{
682 struct sockaddr_in6 sin6;
683 int rc;
684
685 if(unicast_buffered == 0)
686 goto done;
687
688 if(!if_up(unicast_neighbour->ifp))
689 goto done;
690
691 /* Preserve ordering of messages */
692 flushbuf(unicast_neighbour->ifp);
693
694 if(check_bucket(unicast_neighbour->ifp)) {
695 memset(&sin6, 0, sizeof(sin6));
696 sin6.sin6_family = AF_INET6;
697 memcpy(&sin6.sin6_addr, unicast_neighbour->address, 16);
698 sin6.sin6_port = htons(protocol_port);
699 sin6.sin6_scope_id = unicast_neighbour->ifp->ifindex;
700 DO_HTONS(packet_header + 2, unicast_buffered);
701 rc = babel_send(protocol_socket,
702 packet_header, sizeof(packet_header),
703 unicast_buffer, unicast_buffered,
704 (struct sockaddr*)&sin6, sizeof(sin6));
705 if(rc < 0)
706 zlog_err("send(unicast): %s", safe_strerror(errno));
707 } else {
708 fprintf(stderr,
709 "Warning: bucket full, dropping unicast packet"
710 "to %s if %s.\n",
711 format_address(unicast_neighbour->address),
712 unicast_neighbour->ifp->name);
713 }
714
715 done:
716 VALGRIND_MAKE_MEM_UNDEFINED(unicast_buffer, UNICAST_BUFSIZE);
717 unicast_buffered = 0;
718 if(dofree && unicast_buffer) {
719 free(unicast_buffer);
720 unicast_buffer = NULL;
721 }
722 unicast_neighbour = NULL;
723 unicast_flush_timeout.tv_sec = 0;
724 unicast_flush_timeout.tv_usec = 0;
725}
726
727static void
728really_send_update(struct interface *ifp,
729 const unsigned char *id,
730 const unsigned char *prefix, unsigned char plen,
731 unsigned short seqno, unsigned short metric)
732{
733 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
734 int add_metric, v4, real_plen, omit = 0;
735 const unsigned char *real_prefix;
736 unsigned short flags = 0;
737
738 if(!if_up(ifp))
739 return;
740
741 add_metric = output_filter(id, prefix, plen, ifp->ifindex);
742 if(add_metric >= INFINITY)
743 return;
744
745 metric = MIN(metric + add_metric, INFINITY);
746 /* Worst case */
747 ensure_space(ifp, 20 + 12 + 28);
748
749 v4 = plen >= 96 && v4mapped(prefix);
750
751 if(v4) {
752 if(!babel_ifp->ipv4)
753 return;
754 if(!babel_ifp->have_buffered_nh ||
755 memcmp(babel_ifp->buffered_nh, babel_ifp->ipv4, 4) != 0) {
756 start_message(ifp, MESSAGE_NH, 6);
757 accumulate_byte(ifp, 1);
758 accumulate_byte(ifp, 0);
759 accumulate_bytes(ifp, babel_ifp->ipv4, 4);
760 end_message(ifp, MESSAGE_NH, 6);
761 memcpy(babel_ifp->buffered_nh, babel_ifp->ipv4, 4);
762 babel_ifp->have_buffered_nh = 1;
763 }
764
765 real_prefix = prefix + 12;
766 real_plen = plen - 96;
767 } else {
768 if(babel_ifp->have_buffered_prefix) {
769 while(omit < plen / 8 &&
770 babel_ifp->buffered_prefix[omit] == prefix[omit])
771 omit++;
772 }
773 if(!babel_ifp->have_buffered_prefix || plen >= 48)
774 flags |= 0x80;
775 real_prefix = prefix;
776 real_plen = plen;
777 }
778
779 if(!babel_ifp->have_buffered_id
780 || memcmp(id, babel_ifp->buffered_id, 8) != 0) {
781 if(real_plen == 128 && memcmp(real_prefix + 8, id, 8) == 0) {
782 flags |= 0x40;
783 } else {
784 start_message(ifp, MESSAGE_ROUTER_ID, 10);
785 accumulate_short(ifp, 0);
786 accumulate_bytes(ifp, id, 8);
787 end_message(ifp, MESSAGE_ROUTER_ID, 10);
788 }
789 memcpy(babel_ifp->buffered_id, id, 16);
790 babel_ifp->have_buffered_id = 1;
791 }
792
793 start_message(ifp, MESSAGE_UPDATE, 10 + (real_plen + 7) / 8 - omit);
794 accumulate_byte(ifp, v4 ? 1 : 2);
795 accumulate_byte(ifp, flags);
796 accumulate_byte(ifp, real_plen);
797 accumulate_byte(ifp, omit);
798 accumulate_short(ifp, (babel_ifp->update_interval + 5) / 10);
799 accumulate_short(ifp, seqno);
800 accumulate_short(ifp, metric);
801 accumulate_bytes(ifp, real_prefix + omit, (real_plen + 7) / 8 - omit);
802 end_message(ifp, MESSAGE_UPDATE, 10 + (real_plen + 7) / 8 - omit);
803
804 if(flags & 0x80) {
805 memcpy(babel_ifp->buffered_prefix, prefix, 16);
806 babel_ifp->have_buffered_prefix = 1;
807 }
808}
809
810static int
811compare_buffered_updates(const void *av, const void *bv)
812{
813 const struct buffered_update *a = av, *b = bv;
814 int rc, v4a, v4b, ma, mb;
815
816 rc = memcmp(a->id, b->id, 8);
817 if(rc != 0)
818 return rc;
819
820 v4a = (a->plen >= 96 && v4mapped(a->prefix));
821 v4b = (b->plen >= 96 && v4mapped(b->prefix));
822
823 if(v4a > v4b)
824 return 1;
825 else if(v4a < v4b)
826 return -1;
827
828 ma = (!v4a && a->plen == 128 && memcmp(a->prefix + 8, a->id, 8) == 0);
829 mb = (!v4b && b->plen == 128 && memcmp(b->prefix + 8, b->id, 8) == 0);
830
831 if(ma > mb)
832 return -1;
833 else if(mb > ma)
834 return 1;
835
836 if(a->plen < b->plen)
837 return 1;
838 else if(a->plen > b->plen)
839 return -1;
840
841 return memcmp(a->prefix, b->prefix, 16);
842}
843
844void
845flushupdates(struct interface *ifp)
846{
847 babel_interface_nfo *babel_ifp = NULL;
848 struct xroute *xroute;
Denis Ovsienkoef4de4d2012-01-08 15:29:19 +0400849 struct babel_route *route;
Paul Jakma57345092011-12-25 17:52:09 +0100850 const unsigned char *last_prefix = NULL;
851 unsigned char last_plen = 0xFF;
852 int i;
853
854 if(ifp == NULL) {
855 struct interface *ifp_aux;
856 struct listnode *linklist_node = NULL;
857 FOR_ALL_INTERFACES(ifp_aux, linklist_node)
858 flushupdates(ifp_aux);
859 return;
860 }
861
862 babel_ifp = babel_get_if_nfo(ifp);
863 if(babel_ifp->num_buffered_updates > 0) {
864 struct buffered_update *b = babel_ifp->buffered_updates;
865 int n = babel_ifp->num_buffered_updates;
866
867 babel_ifp->buffered_updates = NULL;
868 babel_ifp->update_bufsize = 0;
869 babel_ifp->num_buffered_updates = 0;
870
871 if(!if_up(ifp))
872 goto done;
873
874 debugf(BABEL_DEBUG_COMMON," (flushing %d buffered updates on %s (%d))",
875 n, ifp->name, ifp->ifindex);
876
877 /* In order to send fewer update messages, we want to send updates
878 with the same router-id together, with IPv6 going out before IPv4. */
879
880 for(i = 0; i < n; i++) {
881 route = find_installed_route(b[i].prefix, b[i].plen);
882 if(route)
883 memcpy(b[i].id, route->src->id, 8);
884 else
885 memcpy(b[i].id, myid, 8);
886 }
887
888 qsort(b, n, sizeof(struct buffered_update), compare_buffered_updates);
889
890 for(i = 0; i < n; i++) {
891 unsigned short seqno;
892 unsigned short metric;
893
894 /* The same update may be scheduled multiple times before it is
895 sent out. Since our buffer is now sorted, it is enough to
896 compare with the previous update. */
897
898 if(last_prefix) {
899 if(b[i].plen == last_plen &&
900 memcmp(b[i].prefix, last_prefix, 16) == 0)
901 continue;
902 }
903
904 xroute = find_xroute(b[i].prefix, b[i].plen);
905 route = find_installed_route(b[i].prefix, b[i].plen);
906
907 if(xroute && (!route || xroute->metric <= kernel_metric)) {
908 really_send_update(ifp, myid,
909 xroute->prefix, xroute->plen,
910 myseqno, xroute->metric);
911 last_prefix = xroute->prefix;
912 last_plen = xroute->plen;
913 } else if(route) {
914 seqno = route->seqno;
915 metric = route_metric(route);
916 if(metric < INFINITY)
917 satisfy_request(route->src->prefix, route->src->plen,
918 seqno, route->src->id, ifp);
919 if((babel_ifp->flags & BABEL_IF_SPLIT_HORIZON) &&
920 route->neigh->ifp == ifp)
921 continue;
922 really_send_update(ifp, route->src->id,
923 route->src->prefix,
924 route->src->plen,
925 seqno, metric);
926 update_source(route->src, seqno, metric);
927 last_prefix = route->src->prefix;
928 last_plen = route->src->plen;
929 } else {
930 /* There's no route for this prefix. This can happen shortly
931 after an xroute has been retracted, so send a retraction. */
932 really_send_update(ifp, myid, b[i].prefix, b[i].plen,
933 myseqno, INFINITY);
934 }
935 }
936 schedule_flush_now(ifp);
937 done:
938 free(b);
939 }
940 babel_ifp->update_flush_timeout.tv_sec = 0;
941 babel_ifp->update_flush_timeout.tv_usec = 0;
942}
943
944static void
945schedule_update_flush(struct interface *ifp, int urgent)
946{
947 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
948 unsigned msecs;
949 msecs = update_jitter(babel_ifp, urgent);
950 if(babel_ifp->update_flush_timeout.tv_sec != 0 &&
951 timeval_minus_msec(&babel_ifp->update_flush_timeout, &babel_now) < msecs)
952 return;
953 set_timeout(&babel_ifp->update_flush_timeout, msecs);
954}
955
956static void
957buffer_update(struct interface *ifp,
958 const unsigned char *prefix, unsigned char plen)
959{
960 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
961 if(babel_ifp->num_buffered_updates > 0 &&
962 babel_ifp->num_buffered_updates >= babel_ifp->update_bufsize)
963 flushupdates(ifp);
964
965 if(babel_ifp->update_bufsize == 0) {
966 int n;
967 assert(babel_ifp->buffered_updates == NULL);
968 n = MAX(babel_ifp->bufsize / 16, 4);
969 again:
970 babel_ifp->buffered_updates = malloc(n *sizeof(struct buffered_update));
971 if(babel_ifp->buffered_updates == NULL) {
972 zlog_err("malloc(buffered_updates): %s", safe_strerror(errno));
973 if(n > 4) {
974 n = 4;
975 goto again;
976 }
977 return;
978 }
979 babel_ifp->update_bufsize = n;
980 babel_ifp->num_buffered_updates = 0;
981 }
982
983 memcpy(babel_ifp->buffered_updates[babel_ifp->num_buffered_updates].prefix,
984 prefix, 16);
985 babel_ifp->buffered_updates[babel_ifp->num_buffered_updates].plen = plen;
986 babel_ifp->num_buffered_updates++;
987}
988
989void
990send_update(struct interface *ifp, int urgent,
991 const unsigned char *prefix, unsigned char plen)
992{
993 babel_interface_nfo *babel_ifp = NULL;
994 int i;
995
996 if(ifp == NULL) {
997 struct interface *ifp_aux;
998 struct listnode *linklist_node = NULL;
Denis Ovsienkoef4de4d2012-01-08 15:29:19 +0400999 struct babel_route *route;
Paul Jakma57345092011-12-25 17:52:09 +01001000 FOR_ALL_INTERFACES(ifp_aux, linklist_node)
1001 send_update(ifp_aux, urgent, prefix, plen);
1002 if(prefix) {
1003 /* Since flushupdates only deals with non-wildcard interfaces, we
1004 need to do this now. */
1005 route = find_installed_route(prefix, plen);
1006 if(route && route_metric(route) < INFINITY)
1007 satisfy_request(prefix, plen, route->src->seqno, route->src->id,
1008 NULL);
1009 }
1010 return;
1011 }
1012
1013 if(!if_up(ifp))
1014 return;
1015
1016 babel_ifp = babel_get_if_nfo(ifp);
1017 if(prefix) {
1018 if(!parasitic || find_xroute(prefix, plen)) {
1019 debugf(BABEL_DEBUG_COMMON,"Sending update to %s for %s.",
1020 ifp->name, format_prefix(prefix, plen));
1021 buffer_update(ifp, prefix, plen);
1022 }
1023 } else {
1024 if(!interface_idle(babel_ifp)) {
1025 send_self_update(ifp);
1026 if(!parasitic) {
1027 debugf(BABEL_DEBUG_COMMON,"Sending update to %s for any.", ifp->name);
1028 for(i = 0; i < numroutes; i++)
1029 if(routes[i].installed)
1030 buffer_update(ifp,
1031 routes[i].src->prefix,
1032 routes[i].src->plen);
1033 }
1034 }
1035 set_timeout(&babel_ifp->update_timeout, babel_ifp->update_interval);
1036 }
1037 schedule_update_flush(ifp, urgent);
1038}
1039
1040void
1041send_update_resend(struct interface *ifp,
1042 const unsigned char *prefix, unsigned char plen)
1043{
1044 int delay;
1045
1046 assert(prefix != NULL);
1047
1048 send_update(ifp, 1, prefix, plen);
1049
1050 delay = 2000;
1051 delay = MIN(delay, wireless_hello_interval / 2);
1052 delay = MIN(delay, wired_hello_interval / 2);
1053 delay = MAX(delay, 10);
1054 record_resend(RESEND_UPDATE, prefix, plen, 0, 0, NULL, delay);
1055}
1056
1057void
1058send_wildcard_retraction(struct interface *ifp)
1059{
1060 babel_interface_nfo *babel_ifp = NULL;
1061 if(ifp == NULL) {
1062 struct interface *ifp_aux;
1063 struct listnode *linklist_node = NULL;
1064 FOR_ALL_INTERFACES(ifp_aux, linklist_node)
1065 send_wildcard_retraction(ifp_aux);
1066 return;
1067 }
1068
1069 if(!if_up(ifp))
1070 return;
1071
1072 babel_ifp = babel_get_if_nfo(ifp);
1073 start_message(ifp, MESSAGE_UPDATE, 10);
1074 accumulate_byte(ifp, 0);
1075 accumulate_byte(ifp, 0x40);
1076 accumulate_byte(ifp, 0);
1077 accumulate_byte(ifp, 0);
1078 accumulate_short(ifp, 0xFFFF);
1079 accumulate_short(ifp, myseqno);
1080 accumulate_short(ifp, 0xFFFF);
1081 end_message(ifp, MESSAGE_UPDATE, 10);
1082
1083 babel_ifp->have_buffered_id = 0;
1084}
1085
1086void
1087update_myseqno()
1088{
1089 myseqno = seqno_plus(myseqno, 1);
1090 seqno_time = babel_now;
1091}
1092
1093void
1094send_self_update(struct interface *ifp)
1095{
1096 int i;
1097
1098 if(ifp == NULL) {
1099 struct interface *ifp_aux;
1100 struct listnode *linklist_node = NULL;
1101 FOR_ALL_INTERFACES(ifp_aux, linklist_node) {
1102 if(!if_up(ifp_aux))
1103 continue;
1104 send_self_update(ifp_aux);
1105 }
1106 return;
1107 }
1108
1109 if(!interface_idle(babel_get_if_nfo(ifp))) {
1110 debugf(BABEL_DEBUG_COMMON,"Sending self update to %s.", ifp->name);
1111 for(i = 0; i < numxroutes; i++)
1112 send_update(ifp, 0, xroutes[i].prefix, xroutes[i].plen);
1113 }
1114}
1115
1116void
1117send_ihu(struct neighbour *neigh, struct interface *ifp)
1118{
1119 babel_interface_nfo *babel_ifp = NULL;
1120 int rxcost, interval;
1121 int ll;
1122
1123 if(neigh == NULL && ifp == NULL) {
1124 struct interface *ifp_aux;
1125 struct listnode *linklist_node = NULL;
1126 FOR_ALL_INTERFACES(ifp_aux, linklist_node) {
1127 if(if_up(ifp_aux))
1128 continue;
1129 send_ihu(NULL, ifp_aux);
1130 }
1131 return;
1132 }
1133
1134 if(neigh == NULL) {
1135 struct neighbour *ngh;
1136 FOR_ALL_NEIGHBOURS(ngh) {
1137 if(ngh->ifp == ifp)
1138 send_ihu(ngh, ifp);
1139 }
1140 return;
1141 }
1142
1143
1144 if(ifp && neigh->ifp != ifp)
1145 return;
1146
1147 ifp = neigh->ifp;
1148 babel_ifp = babel_get_if_nfo(ifp);
1149 if(!if_up(ifp))
1150 return;
1151
1152 rxcost = neighbour_rxcost(neigh);
1153 interval = (babel_ifp->hello_interval * 3 + 9) / 10;
1154
1155 /* Conceptually, an IHU is a unicast message. We usually send them as
1156 multicast, since this allows aggregation into a single packet and
1157 avoids an ARP exchange. If we already have a unicast message queued
1158 for this neighbour, however, we might as well piggyback the IHU. */
1159 debugf(BABEL_DEBUG_COMMON,"Sending %sihu %d on %s to %s.",
1160 unicast_neighbour == neigh ? "unicast " : "",
1161 rxcost,
1162 neigh->ifp->name,
1163 format_address(neigh->address));
1164
1165 ll = linklocal(neigh->address);
1166
1167 if(unicast_neighbour != neigh) {
1168 start_message(ifp, MESSAGE_IHU, ll ? 14 : 22);
1169 accumulate_byte(ifp, ll ? 3 : 2);
1170 accumulate_byte(ifp, 0);
1171 accumulate_short(ifp, rxcost);
1172 accumulate_short(ifp, interval);
1173 if(ll)
1174 accumulate_bytes(ifp, neigh->address + 8, 8);
1175 else
1176 accumulate_bytes(ifp, neigh->address, 16);
1177 end_message(ifp, MESSAGE_IHU, ll ? 14 : 22);
1178 } else {
1179 int rc;
1180 rc = start_unicast_message(neigh, MESSAGE_IHU, ll ? 14 : 22);
1181 if(rc < 0) return;
1182 accumulate_unicast_byte(neigh, ll ? 3 : 2);
1183 accumulate_unicast_byte(neigh, 0);
1184 accumulate_unicast_short(neigh, rxcost);
1185 accumulate_unicast_short(neigh, interval);
1186 if(ll)
1187 accumulate_unicast_bytes(neigh, neigh->address + 8, 8);
1188 else
1189 accumulate_unicast_bytes(neigh, neigh->address, 16);
1190 end_unicast_message(neigh, MESSAGE_IHU, ll ? 14 : 22);
1191 }
1192}
1193
1194/* Send IHUs to all marginal neighbours */
1195void
1196send_marginal_ihu(struct interface *ifp)
1197{
1198 struct neighbour *neigh;
1199 FOR_ALL_NEIGHBOURS(neigh) {
1200 if(ifp && neigh->ifp != ifp)
1201 continue;
1202 if(neigh->txcost >= 384 || (neigh->reach & 0xF000) != 0xF000)
1203 send_ihu(neigh, ifp);
1204 }
1205}
1206
1207void
1208send_request(struct interface *ifp,
1209 const unsigned char *prefix, unsigned char plen)
1210{
Paul Jakma57345092011-12-25 17:52:09 +01001211 int v4, len;
1212
1213 if(ifp == NULL) {
1214 struct interface *ifp_aux;
1215 struct listnode *linklist_node = NULL;
1216 FOR_ALL_INTERFACES(ifp_aux, linklist_node) {
1217 if(if_up(ifp_aux))
1218 continue;
1219 send_request(ifp_aux, prefix, plen);
1220 }
1221 return;
1222 }
1223
1224 /* make sure any buffered updates go out before this request. */
1225 flushupdates(ifp);
1226
1227 if(!if_up(ifp))
1228 return;
1229
Paul Jakma57345092011-12-25 17:52:09 +01001230 debugf(BABEL_DEBUG_COMMON,"sending request to %s for %s.",
1231 ifp->name, prefix ? format_prefix(prefix, plen) : "any");
1232 v4 = plen >= 96 && v4mapped(prefix);
1233 len = !prefix ? 2 : v4 ? 6 : 18;
1234
1235 start_message(ifp, MESSAGE_REQUEST, len);
1236 accumulate_byte(ifp, !prefix ? 0 : v4 ? 1 : 2);
1237 accumulate_byte(ifp, !prefix ? 0 : v4 ? plen - 96 : plen);
1238 if(prefix) {
1239 if(v4)
1240 accumulate_bytes(ifp, prefix + 12, 4);
1241 else
1242 accumulate_bytes(ifp, prefix, 16);
1243 }
1244 end_message(ifp, MESSAGE_REQUEST, len);
1245}
1246
1247void
1248send_unicast_request(struct neighbour *neigh,
1249 const unsigned char *prefix, unsigned char plen)
1250{
1251 int rc, v4, len;
1252
1253 /* make sure any buffered updates go out before this request. */
1254 flushupdates(neigh->ifp);
1255
1256 debugf(BABEL_DEBUG_COMMON,"sending unicast request to %s for %s.",
1257 format_address(neigh->address),
1258 prefix ? format_prefix(prefix, plen) : "any");
1259 v4 = plen >= 96 && v4mapped(prefix);
1260 len = !prefix ? 2 : v4 ? 6 : 18;
1261
1262 rc = start_unicast_message(neigh, MESSAGE_REQUEST, len);
1263 if(rc < 0) return;
1264 accumulate_unicast_byte(neigh, !prefix ? 0 : v4 ? 1 : 2);
1265 accumulate_unicast_byte(neigh, !prefix ? 0 : v4 ? plen - 96 : plen);
1266 if(prefix) {
1267 if(v4)
1268 accumulate_unicast_bytes(neigh, prefix + 12, 4);
1269 else
1270 accumulate_unicast_bytes(neigh, prefix, 16);
1271 }
1272 end_unicast_message(neigh, MESSAGE_REQUEST, len);
1273}
1274
1275void
1276send_multihop_request(struct interface *ifp,
1277 const unsigned char *prefix, unsigned char plen,
1278 unsigned short seqno, const unsigned char *id,
1279 unsigned short hop_count)
1280{
Paul Jakma57345092011-12-25 17:52:09 +01001281 int v4, pb, len;
1282
1283 /* Make sure any buffered updates go out before this request. */
1284 flushupdates(ifp);
1285
1286 if(ifp == NULL) {
1287 struct interface *ifp_aux;
1288 struct listnode *linklist_node = NULL;
1289 FOR_ALL_INTERFACES(ifp_aux, linklist_node) {
1290 if(!if_up(ifp_aux))
1291 continue;
1292 send_multihop_request(ifp_aux, prefix, plen, seqno, id, hop_count);
1293 }
1294 return;
1295 }
1296
1297 if(!if_up(ifp))
1298 return;
1299
Paul Jakma57345092011-12-25 17:52:09 +01001300 debugf(BABEL_DEBUG_COMMON,"Sending request (%d) on %s for %s.",
1301 hop_count, ifp->name, format_prefix(prefix, plen));
1302 v4 = plen >= 96 && v4mapped(prefix);
1303 pb = v4 ? ((plen - 96) + 7) / 8 : (plen + 7) / 8;
1304 len = 6 + 8 + pb;
1305
1306 start_message(ifp, MESSAGE_MH_REQUEST, len);
1307 accumulate_byte(ifp, v4 ? 1 : 2);
1308 accumulate_byte(ifp, v4 ? plen - 96 : plen);
1309 accumulate_short(ifp, seqno);
1310 accumulate_byte(ifp, hop_count);
1311 accumulate_byte(ifp, 0);
1312 accumulate_bytes(ifp, id, 8);
1313 if(prefix) {
1314 if(v4)
1315 accumulate_bytes(ifp, prefix + 12, pb);
1316 else
1317 accumulate_bytes(ifp, prefix, pb);
1318 }
1319 end_message(ifp, MESSAGE_MH_REQUEST, len);
1320}
1321
1322void
1323send_unicast_multihop_request(struct neighbour *neigh,
1324 const unsigned char *prefix, unsigned char plen,
1325 unsigned short seqno, const unsigned char *id,
1326 unsigned short hop_count)
1327{
1328 int rc, v4, pb, len;
1329
1330 /* Make sure any buffered updates go out before this request. */
1331 flushupdates(neigh->ifp);
1332
1333 debugf(BABEL_DEBUG_COMMON,"Sending multi-hop request to %s for %s (%d hops).",
1334 format_address(neigh->address),
1335 format_prefix(prefix, plen), hop_count);
1336 v4 = plen >= 96 && v4mapped(prefix);
1337 pb = v4 ? ((plen - 96) + 7) / 8 : (plen + 7) / 8;
1338 len = 6 + 8 + pb;
1339
1340 rc = start_unicast_message(neigh, MESSAGE_MH_REQUEST, len);
1341 if(rc < 0) return;
1342 accumulate_unicast_byte(neigh, v4 ? 1 : 2);
1343 accumulate_unicast_byte(neigh, v4 ? plen - 96 : plen);
1344 accumulate_unicast_short(neigh, seqno);
1345 accumulate_unicast_byte(neigh, hop_count);
1346 accumulate_unicast_byte(neigh, 0);
1347 accumulate_unicast_bytes(neigh, id, 8);
1348 if(prefix) {
1349 if(v4)
1350 accumulate_unicast_bytes(neigh, prefix + 12, pb);
1351 else
1352 accumulate_unicast_bytes(neigh, prefix, pb);
1353 }
1354 end_unicast_message(neigh, MESSAGE_MH_REQUEST, len);
1355}
1356
1357void
1358send_request_resend(struct neighbour *neigh,
1359 const unsigned char *prefix, unsigned char plen,
1360 unsigned short seqno, unsigned char *id)
1361{
1362 int delay;
1363
1364 if(neigh)
1365 send_unicast_multihop_request(neigh, prefix, plen, seqno, id, 127);
1366 else
1367 send_multihop_request(NULL, prefix, plen, seqno, id, 127);
1368
1369 delay = 2000;
1370 delay = MIN(delay, wireless_hello_interval / 2);
1371 delay = MIN(delay, wired_hello_interval / 2);
1372 delay = MAX(delay, 10);
1373 record_resend(RESEND_REQUEST, prefix, plen, seqno, id,
1374 neigh ? neigh->ifp : NULL, delay);
1375}
1376
1377void
1378handle_request(struct neighbour *neigh, const unsigned char *prefix,
1379 unsigned char plen, unsigned char hop_count,
1380 unsigned short seqno, const unsigned char *id)
1381{
1382 struct xroute *xroute;
Denis Ovsienkoef4de4d2012-01-08 15:29:19 +04001383 struct babel_route *route;
Paul Jakma57345092011-12-25 17:52:09 +01001384 struct neighbour *successor = NULL;
1385
1386 xroute = find_xroute(prefix, plen);
1387 route = find_installed_route(prefix, plen);
1388
1389 if(xroute && (!route || xroute->metric <= kernel_metric)) {
1390 if(hop_count > 0 && memcmp(id, myid, 8) == 0) {
1391 if(seqno_compare(seqno, myseqno) > 0) {
1392 if(seqno_minus(seqno, myseqno) > 100) {
1393 /* Hopelessly out-of-date request */
1394 return;
1395 }
1396 update_myseqno();
1397 }
1398 }
1399 send_update(neigh->ifp, 1, prefix, plen);
1400 return;
1401 }
1402
1403 if(route &&
1404 (memcmp(id, route->src->id, 8) != 0 ||
1405 seqno_compare(seqno, route->seqno) <= 0)) {
1406 send_update(neigh->ifp, 1, prefix, plen);
1407 return;
1408 }
1409
1410 if(hop_count <= 1)
1411 return;
1412
1413 if(route && memcmp(id, route->src->id, 8) == 0 &&
1414 seqno_minus(seqno, route->seqno) > 100) {
1415 /* Hopelessly out-of-date */
1416 return;
1417 }
1418
1419 if(request_redundant(neigh->ifp, prefix, plen, seqno, id))
1420 return;
1421
1422 /* Let's try to forward this request. */
1423 if(route && route_metric(route) < INFINITY)
1424 successor = route->neigh;
1425
1426 if(!successor || successor == neigh) {
1427 /* We were about to forward a request to its requestor. Try to
1428 find a different neighbour to forward the request to. */
Denis Ovsienkoef4de4d2012-01-08 15:29:19 +04001429 struct babel_route *other_route;
Paul Jakma57345092011-12-25 17:52:09 +01001430
1431 other_route = find_best_route(prefix, plen, 0, neigh);
1432 if(other_route && route_metric(other_route) < INFINITY)
1433 successor = other_route->neigh;
1434 }
1435
1436 if(!successor || successor == neigh)
1437 /* Give up */
1438 return;
1439
1440 send_unicast_multihop_request(successor, prefix, plen, seqno, id,
1441 hop_count - 1);
1442 record_resend(RESEND_REQUEST, prefix, plen, seqno, id,
1443 neigh->ifp, 0);
1444}