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