]> git.proxmox.com Git - mirror_frr.git/blame - babeld/message.c
Merge pull request #13484 from sri-mohan1/srib-ldpd
[mirror_frr.git] / babeld / message.c
CommitLineData
acddc0ed 1// SPDX-License-Identifier: MIT
ca10883e
DS
2/*
3Copyright (c) 2007, 2008 by Juliusz Chroboczek
ca10883e
DS
4*/
5
6#include <zebra.h>
7#include "if.h"
8
9#include "babeld.h"
10#include "util.h"
11#include "net.h"
12#include "babel_interface.h"
13#include "source.h"
14#include "neighbour.h"
15#include "route.h"
16#include "xroute.h"
17#include "resend.h"
18#include "message.h"
19#include "kernel.h"
20#include "babel_main.h"
e33b116c 21#include "babel_errors.h"
ca10883e
DS
22
23static unsigned char packet_header[4] = {42, 2};
24
25int split_horizon = 1;
26
27unsigned short myseqno = 0;
28
29#define UNICAST_BUFSIZE 1024
30static int unicast_buffered = 0;
31static unsigned char *unicast_buffer = NULL;
32struct neighbour *unicast_neighbour = NULL;
33struct timeval unicast_flush_timeout = {0, 0};
34
35/* Minimum TLV _body_ length for TLVs of particular types (0 = no limit). */
36static const unsigned char tlv_min_length[MESSAGE_MAX + 1] =
37{
38 [ MESSAGE_PAD1 ] = 0,
39 [ MESSAGE_PADN ] = 0,
40 [ MESSAGE_ACK_REQ ] = 6,
41 [ MESSAGE_ACK ] = 2,
42 [ MESSAGE_HELLO ] = 6,
43 [ MESSAGE_IHU ] = 6,
44 [ MESSAGE_ROUTER_ID ] = 10,
45 [ MESSAGE_NH ] = 2,
46 [ MESSAGE_UPDATE ] = 10,
47 [ MESSAGE_REQUEST ] = 2,
48 [ MESSAGE_MH_REQUEST ] = 14,
49};
50
7d552fe6 51/* Checks whether an AE exists or must be silently ignored */
52static bool
53known_ae(int ae)
54{
55 return ae <= 4;
56}
57
ca10883e
DS
58/* Parse a network prefix, encoded in the somewhat baroque compressed
59 representation used by Babel. Return the number of bytes parsed. */
60static int
61network_prefix(int ae, int plen, unsigned int omitted,
62 const unsigned char *p, const unsigned char *dp,
63 unsigned int len, unsigned char *p_r)
64{
65 unsigned pb;
66 unsigned char prefix[16];
67 int ret = -1;
68
69 if(plen >= 0)
70 pb = (plen + 7) / 8;
71 else if(ae == 1)
72 pb = 4;
73 else
74 pb = 16;
75
76 if(pb > 16)
77 return -1;
78
79 memset(prefix, 0, 16);
80
81 switch(ae) {
82 case 0:
83 ret = 0;
84 break;
85 case 1:
86 if(omitted > 4 || pb > 4 || (pb > omitted && len < pb - omitted))
87 return -1;
88 memcpy(prefix, v4prefix, 12);
89 if(omitted) {
90 if (dp == NULL || !v4mapped(dp)) return -1;
91 memcpy(prefix, dp, 12 + omitted);
92 }
93 if(pb > omitted) memcpy(prefix + 12 + omitted, p, pb - omitted);
94 ret = pb - omitted;
95 break;
96 case 2:
97 if(omitted > 16 || (pb > omitted && len < pb - omitted)) return -1;
98 if(omitted) {
99 if (dp == NULL || v4mapped(dp)) return -1;
100 memcpy(prefix, dp, omitted);
101 }
102 if(pb > omitted) memcpy(prefix + omitted, p, pb - omitted);
103 ret = pb - omitted;
104 break;
105 case 3:
106 if(pb > 8 && len < pb - 8) return -1;
107 prefix[0] = 0xfe;
108 prefix[1] = 0x80;
109 if(pb > 8) memcpy(prefix + 8, p, pb - 8);
110 ret = pb - 8;
111 break;
112 default:
113 return -1;
114 }
115
116 mask_prefix(p_r, prefix, plen < 0 ? 128 : ae == 1 ? plen + 96 : plen);
117 return ret;
118}
119
a76cf7e4
DS
120static bool parse_update_subtlv(const unsigned char *a, int alen,
121 unsigned char *channels)
ca10883e
DS
122{
123 int type, len, i = 0;
124
125 while(i < alen) {
126 type = a[i];
127 if(type == SUBTLV_PAD1) {
128 i++;
129 continue;
130 }
131
c3793352 132 if(i + 1 >= alen) {
5b003f31 133 flog_err(EC_BABEL_PACKET, "Received truncated attributes.");
a76cf7e4
DS
134 return false;
135 }
ca10883e 136 len = a[i + 1];
c3793352 137 if(i + len + 2 > alen) {
5b003f31 138 flog_err(EC_BABEL_PACKET, "Received truncated attributes.");
a76cf7e4
DS
139 return false;
140 }
ca10883e 141
a76cf7e4
DS
142 if (type & SUBTLV_MANDATORY) {
143 /*
144 * RFC 8966 - 4.4
145 * If the mandatory bit is set, then the whole enclosing
146 * TLV MUST be silently ignored (except for updating the
147 * parser state by a Router-Id, Next Hop, or Update TLV,
148 * as described in the next section).
149 */
150 debugf(BABEL_DEBUG_COMMON,
151 "Received Mandatory bit set but this FRR version is not prepared to handle it at this point");
152 return true;
153 } else if (type == SUBTLV_PADN) {
154 /* Nothing. */
155 } else if (type == SUBTLV_DIVERSITY) {
156 if (len > DIVERSITY_HOPS) {
157 flog_err(
158 EC_BABEL_PACKET,
159 "Received overlong channel information (%d > %d).n",
160 len, DIVERSITY_HOPS);
161 len = DIVERSITY_HOPS;
162 }
163 if (memchr(a + i + 2, 0, len) != NULL) {
164 /* 0 is reserved. */
165 flog_err(EC_BABEL_PACKET,
166 "Channel information contains 0!");
167 return false;
168 }
169 memset(channels, 0, DIVERSITY_HOPS);
170 memcpy(channels, a + i + 2, len);
171 } else {
172 debugf(BABEL_DEBUG_COMMON,
173 "Received unknown route attribute %d.", type);
174 }
ca10883e 175
a76cf7e4 176 i += len + 2;
ca10883e 177 }
a76cf7e4 178 return false;
ca10883e
DS
179}
180
181static int
182parse_hello_subtlv(const unsigned char *a, int alen,
183 unsigned int *hello_send_us)
184{
185 int type, len, i = 0, ret = 0;
186
187 while(i < alen) {
c3793352 188 type = a[i];
ca10883e
DS
189 if(type == SUBTLV_PAD1) {
190 i++;
191 continue;
192 }
193
c3793352 194 if(i + 1 >= alen) {
5b003f31 195 flog_err(EC_BABEL_PACKET,
e33b116c 196 "Received truncated sub-TLV on Hello message.");
ca10883e
DS
197 return -1;
198 }
199 len = a[i + 1];
c3793352 200 if(i + len + 2 > alen) {
5b003f31 201 flog_err(EC_BABEL_PACKET,
e33b116c 202 "Received truncated sub-TLV on Hello message.");
ca10883e
DS
203 return -1;
204 }
205
a76cf7e4
DS
206 if (type & SUBTLV_MANDATORY) {
207 /*
208 * RFC 8966 4.4
209 * If the mandatory bit is set, then the whole enclosing
210 * TLV MUST be silently ignored (except for updating the
211 * parser state by a Router-Id, Next Hop, or Update TLV, as
212 * described in the next section).
213 */
214 debugf(BABEL_DEBUG_COMMON,
215 "Received subtlv with Mandatory bit, this version of FRR is not prepared to handle this currently");
216 return -2;
217 } else if (type == SUBTLV_PADN) {
218 /* Nothing to do. */
219 } else if (type == SUBTLV_TIMESTAMP) {
220 if (len >= 4) {
221 DO_NTOHL(*hello_send_us, a + i + 2);
222 ret = 1;
223 } else {
224 flog_err(
225 EC_BABEL_PACKET,
226 "Received incorrect RTT sub-TLV on Hello message.");
227 }
228 } else {
229 debugf(BABEL_DEBUG_COMMON,
230 "Received unknown Hello sub-TLV type %d.", type);
231 }
ca10883e 232
a76cf7e4 233 i += len + 2;
ca10883e
DS
234 }
235 return ret;
236}
237
238static int
239parse_ihu_subtlv(const unsigned char *a, int alen,
240 unsigned int *hello_send_us,
241 unsigned int *hello_rtt_receive_time)
242{
243 int type, len, i = 0, ret = 0;
244
245 while(i < alen) {
c3793352 246 type = a[i];
ca10883e
DS
247 if(type == SUBTLV_PAD1) {
248 i++;
249 continue;
250 }
251
c3793352 252 if(i + 1 >= alen) {
5b003f31 253 flog_err(EC_BABEL_PACKET,
e33b116c 254 "Received truncated sub-TLV on IHU message.");
ca10883e
DS
255 return -1;
256 }
257 len = a[i + 1];
c3793352 258 if(i + len + 2 > alen) {
5b003f31 259 flog_err(EC_BABEL_PACKET,
e33b116c 260 "Received truncated sub-TLV on IHU message.");
ca10883e
DS
261 return -1;
262 }
263
264 if(type == SUBTLV_PADN) {
265 /* Nothing to do. */
266 } else if(type == SUBTLV_TIMESTAMP) {
267 if(len >= 8) {
268 DO_NTOHL(*hello_send_us, a + i + 2);
269 DO_NTOHL(*hello_rtt_receive_time, a + i + 6);
270 ret = 1;
271 }
272 else {
5b003f31 273 flog_err(EC_BABEL_PACKET,
e33b116c 274 "Received incorrect RTT sub-TLV on IHU message.");
ca10883e
DS
275 }
276 } else {
277 debugf(BABEL_DEBUG_COMMON,
278 "Received unknown IHU sub-TLV type %d.", type);
279 }
280
281 i += len + 2;
282 }
283 return ret;
284}
285
7d552fe6 286static int
287parse_request_subtlv(int ae, const unsigned char *a, int alen,
288 unsigned char *src_prefix, unsigned char *src_plen)
289{
290 int type, len, i = 0;
291 int have_src_prefix = 0;
292
293 while(i < alen) {
294 type = a[0];
295 if(type == SUBTLV_PAD1) {
296 i++;
297 continue;
298 }
299
300 if(i + 2 > alen)
301 goto fail;
302
303 len = a[i + 1];
304 if(i + 2 + len > alen)
305 goto fail;
306
307 if(type == SUBTLV_PADN) {
308 /* Nothing to do. */
309 } else if(type == SUBTLV_SOURCE_PREFIX) {
310 int rc;
311 if(len < 1)
312 goto fail;
313 if(a[i + 2] == 0)
314 goto fail;
315 if(have_src_prefix != 0)
316 goto fail;
317 rc = network_prefix(ae, a[i + 2], 0, a + i + 3, NULL,
318 len - 1, src_prefix);
319 if(rc < 0)
320 goto fail;
321 if(ae==1)
322 *src_plen = a[i + 2] + 96;
323 else
324 *src_plen = a[i + 2];
325 have_src_prefix = 1;
326 } else {
327 debugf(BABEL_DEBUG_COMMON,"Received unknown%s Route Request sub-TLV %d.",
328 ((type & 0x80) != 0) ? " mandatory" : "", type);
329 if((type & 0x80) != 0)
330 return -1;
331 }
332
333 i += len + 2;
334 }
335 return 1;
336
337 fail:
338 flog_err(EC_BABEL_PACKET, "Received truncated sub-TLV on Route Request.");
339 return -1;
340}
341
ca10883e
DS
342static int
343network_address(int ae, const unsigned char *a, unsigned int len,
344 unsigned char *a_r)
345{
346 return network_prefix(ae, -1, 0, a, NULL, len, a_r);
347}
348
349static int
350channels_len(unsigned char *channels)
351{
352 unsigned char *p = memchr(channels, 0, DIVERSITY_HOPS);
353 return p ? (p - channels) : DIVERSITY_HOPS;
354}
355
356/* Check, that the provided frame consists of a valid Babel packet header
357 followed by a sequence of TLVs. TLVs of known types are also checked to meet
358 minimum length constraints defined for each. Return 0 for no errors. */
359static int
8128153b 360babel_packet_examin(const unsigned char *packet, int packetlen, int *blength)
ca10883e 361{
50044ec7 362 int i = 0, bodylen;
ca10883e
DS
363 const unsigned char *message;
364 unsigned char type, len;
365
366 if(packetlen < 4 || packet[0] != 42 || packet[1] != 2)
367 return 1;
368 DO_NTOHS(bodylen, packet + 2);
50044ec7 369 if(bodylen + 4 > packetlen) {
370 debugf(BABEL_DEBUG_COMMON, "Received truncated packet (%d + 4 > %d).",
371 bodylen, packetlen);
372 return 1;
373 }
ca10883e
DS
374 while (i < bodylen){
375 message = packet + 4 + i;
376 type = message[0];
377 if(type == MESSAGE_PAD1) {
378 i++;
379 continue;
380 }
c3793352 381 if(i + 2 > bodylen) {
ca10883e
DS
382 debugf(BABEL_DEBUG_COMMON,"Received truncated message.");
383 return 1;
384 }
385 len = message[1];
c3793352 386 if(i + len + 2 > bodylen) {
ca10883e
DS
387 debugf(BABEL_DEBUG_COMMON,"Received truncated message.");
388 return 1;
389 }
390 /* not Pad1 */
391 if(type <= MESSAGE_MAX && tlv_min_length[type] && len < tlv_min_length[type]) {
392 debugf(BABEL_DEBUG_COMMON,"Undersized %u TLV", type);
393 return 1;
394 }
395 i += len + 2;
396 }
8128153b
DS
397
398 *blength = bodylen;
ca10883e
DS
399 return 0;
400}
401
402void
403parse_packet(const unsigned char *from, struct interface *ifp,
404 const unsigned char *packet, int packetlen)
405{
406 int i;
407 const unsigned char *message;
408 unsigned char type, len;
409 int bodylen;
410 struct neighbour *neigh;
411 int have_router_id = 0, have_v4_prefix = 0, have_v6_prefix = 0,
412 have_v4_nh = 0, have_v6_nh = 0;
413 unsigned char router_id[8], v4_prefix[16], v6_prefix[16],
414 v4_nh[16], v6_nh[16];
415 int have_hello_rtt = 0;
416 /* Content of the RTT sub-TLV on IHU messages. */
417 unsigned int hello_send_us = 0, hello_rtt_receive_time = 0;
418 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
419
420 if(babel_ifp->flags & BABEL_IF_TIMESTAMPS) {
421 /* We want to track exactly when we received this packet. */
422 gettime(&babel_now);
423 }
424
425 if(!linklocal(from)) {
5b003f31 426 flog_err(EC_BABEL_PACKET,
e33b116c
DS
427 "Received packet from non-local address %s.",
428 format_address(from));
ca10883e
DS
429 return;
430 }
431
8128153b 432 if (babel_packet_examin (packet, packetlen, &bodylen)) {
5b003f31 433 flog_err(EC_BABEL_PACKET,
e33b116c
DS
434 "Received malformed packet on %s from %s.",
435 ifp->name, format_address(from));
ca10883e
DS
436 return;
437 }
438
439 neigh = find_neighbour(from, ifp);
440 if(neigh == NULL) {
5b003f31 441 flog_err(EC_BABEL_PACKET, "Couldn't allocate neighbour.");
ca10883e
DS
442 return;
443 }
444
ca10883e
DS
445 i = 0;
446 while(i < bodylen) {
447 message = packet + 4 + i;
448 type = message[0];
449 if(type == MESSAGE_PAD1) {
450 debugf(BABEL_DEBUG_COMMON,"Received pad1 from %s on %s.",
451 format_address(from), ifp->name);
452 i++;
453 continue;
454 }
455 len = message[1];
456
457 if(type == MESSAGE_PADN) {
458 debugf(BABEL_DEBUG_COMMON,"Received pad%d from %s on %s.",
459 len, format_address(from), ifp->name);
460 } else if(type == MESSAGE_ACK_REQ) {
461 unsigned short nonce, interval;
462 DO_NTOHS(nonce, message + 4);
463 DO_NTOHS(interval, message + 6);
464 debugf(BABEL_DEBUG_COMMON,"Received ack-req (%04X %d) from %s on %s.",
465 nonce, interval, format_address(from), ifp->name);
466 send_ack(neigh, nonce, interval);
467 } else if(type == MESSAGE_ACK) {
468 debugf(BABEL_DEBUG_COMMON,"Received ack from %s on %s.",
469 format_address(from), ifp->name);
470 /* Nothing right now */
471 } else if(type == MESSAGE_HELLO) {
54a3e60b
DS
472 unsigned short seqno, interval, flags;
473 int changed;
474 unsigned int timestamp = 0;
475
476#define BABEL_UNICAST_HELLO 0x8000
477 DO_NTOHS(flags, message + 2);
478
54a3e60b
DS
479 /*
480 * RFC 8966 Appendix F
481 * TL;DR -> Please ignore Unicast hellos until FRR's
482 * BABEL is brought up to date
483 */
484 if (CHECK_FLAG(flags, BABEL_UNICAST_HELLO)) {
485 debugf(BABEL_DEBUG_COMMON,
486 "Received Unicast Hello from %s on %s that FRR is not prepared to understand yet",
487 format_address(from), ifp->name);
ae1e0e1f 488 goto done;
54a3e60b
DS
489 }
490
491 DO_NTOHS(seqno, message + 4);
492 DO_NTOHS(interval, message + 6);
493 debugf(BABEL_DEBUG_COMMON,
494 "Received hello %d (%d) from %s on %s.", seqno, interval,
495 format_address(from), ifp->name);
496
497 /*
498 * RFC 8966 Appendix F
499 * TL;DR -> Please ignore any Hello packets with the interval
500 * field set to 0
501 */
502 if (interval == 0) {
503 debugf(BABEL_DEBUG_COMMON,
504 "Received hello from %s on %s should be ignored as that this version of FRR does not know how to properly handle interval == 0",
505 format_address(from), ifp->name);
ae1e0e1f 506 goto done;
54a3e60b
DS
507 }
508
509 changed = update_neighbour(neigh, seqno, interval);
510 update_neighbour_metric(neigh, changed);
511 if (interval > 0)
512 /* Multiply by 3/2 to allow hellos to expire. */
513 schedule_neighbours_check(interval * 15, 0);
514 /* Sub-TLV handling. */
515 if (len > 8) {
516 if (parse_hello_subtlv(message + 8, len - 6,
517 &timestamp) > 0) {
518 neigh->hello_send_us = timestamp;
519 neigh->hello_rtt_receive_time = babel_now;
520 have_hello_rtt = 1;
521 }
522 }
ca10883e
DS
523 } else if(type == MESSAGE_IHU) {
524 unsigned short txcost, interval;
525 unsigned char address[16];
526 int rc;
527 DO_NTOHS(txcost, message + 4);
528 DO_NTOHS(interval, message + 6);
529 rc = network_address(message[2], message + 8, len - 6, address);
530 if(rc < 0) goto fail;
531 debugf(BABEL_DEBUG_COMMON,"Received ihu %d (%d) from %s on %s for %s.",
532 txcost, interval,
533 format_address(from), ifp->name,
534 format_address(address));
535 if(message[2] == 0 || is_interface_ll_address(ifp, address)) {
536 int changed = txcost != neigh->txcost;
537 neigh->txcost = txcost;
538 neigh->ihu_time = babel_now;
539 neigh->ihu_interval = interval;
540 update_neighbour_metric(neigh, changed);
541 if(interval > 0)
542 /* Multiply by 3/2 to allow neighbours to expire. */
543 schedule_neighbours_check(interval * 45, 0);
544 /* RTT sub-TLV. */
545 if(len > 10 + rc)
546 parse_ihu_subtlv(message + 8 + rc, len - 6 - rc,
547 &hello_send_us, &hello_rtt_receive_time);
548 }
549 } else if(type == MESSAGE_ROUTER_ID) {
550 memcpy(router_id, message + 4, 8);
551 have_router_id = 1;
552 debugf(BABEL_DEBUG_COMMON,"Received router-id %s from %s on %s.",
553 format_eui64(router_id), format_address(from), ifp->name);
554 } else if(type == MESSAGE_NH) {
555 unsigned char nh[16];
556 int rc;
557 rc = network_address(message[2], message + 4, len - 2,
558 nh);
559 if(rc < 0) {
560 have_v4_nh = 0;
561 have_v6_nh = 0;
562 goto fail;
563 }
564 debugf(BABEL_DEBUG_COMMON,"Received nh %s (%d) from %s on %s.",
565 format_address(nh), message[2],
566 format_address(from), ifp->name);
567 if(message[2] == 1) {
568 memcpy(v4_nh, nh, 16);
569 have_v4_nh = 1;
570 } else {
571 memcpy(v6_nh, nh, 16);
572 have_v6_nh = 1;
573 }
574 } else if(type == MESSAGE_UPDATE) {
575 unsigned char prefix[16], *nh;
576 unsigned char plen;
577 unsigned char channels[DIVERSITY_HOPS];
578 unsigned short interval, seqno, metric;
579 int rc, parsed_len;
a76cf7e4
DS
580 bool ignore_update = false;
581
582 DO_NTOHS(interval, message + 6);
ca10883e
DS
583 DO_NTOHS(seqno, message + 8);
584 DO_NTOHS(metric, message + 10);
585 if(message[5] == 0 ||
586 (message[2] == 1 ? have_v4_prefix : have_v6_prefix))
587 rc = network_prefix(message[2], message[4], message[5],
588 message + 12,
589 message[2] == 1 ? v4_prefix : v6_prefix,
590 len - 10, prefix);
591 else
592 rc = -1;
593 if(rc < 0) {
594 if(message[3] & 0x80)
595 have_v4_prefix = have_v6_prefix = 0;
596 goto fail;
597 }
598 parsed_len = 10 + rc;
599
600 plen = message[4] + (message[2] == 1 ? 96 : 0);
601
602 if(message[3] & 0x80) {
603 if(message[2] == 1) {
604 memcpy(v4_prefix, prefix, 16);
605 have_v4_prefix = 1;
606 } else {
607 memcpy(v6_prefix, prefix, 16);
608 have_v6_prefix = 1;
609 }
610 }
611 if(message[3] & 0x40) {
612 if(message[2] == 1) {
613 memset(router_id, 0, 4);
614 memcpy(router_id + 4, prefix + 12, 4);
615 } else {
616 memcpy(router_id, prefix + 8, 8);
617 }
618 have_router_id = 1;
619 }
620 if(!have_router_id && message[2] != 0) {
5b003f31 621 flog_err(EC_BABEL_PACKET,
e33b116c 622 "Received prefix with no router id.");
ca10883e
DS
623 goto fail;
624 }
625 debugf(BABEL_DEBUG_COMMON,"Received update%s%s for %s from %s on %s.",
626 (message[3] & 0x80) ? "/prefix" : "",
627 (message[3] & 0x40) ? "/id" : "",
628 format_prefix(prefix, plen),
629 format_address(from), ifp->name);
630
631 if(message[2] == 0) {
632 if(metric < 0xFFFF) {
5b003f31 633 flog_err(EC_BABEL_PACKET,
e33b116c 634 "Received wildcard update with finite metric.");
ca10883e
DS
635 goto done;
636 }
637 retract_neighbour_routes(neigh);
638 goto done;
639 } else if(message[2] == 1) {
640 if(!have_v4_nh)
641 goto fail;
642 nh = v4_nh;
643 } else if(have_v6_nh) {
644 nh = v6_nh;
645 } else {
646 nh = neigh->address;
647 }
648
649 if(message[2] == 1) {
650 if(!babel_get_if_nfo(ifp)->ipv4)
651 goto done;
652 }
653
654 if((babel_get_if_nfo(ifp)->flags & BABEL_IF_FARAWAY)) {
655 channels[0] = 0;
656 } else {
657 /* This will be overwritten by parse_update_subtlv below. */
658 if(metric < 256) {
659 /* Assume non-interfering (wired) link. */
660 channels[0] = 0;
661 } else {
662 /* Assume interfering. */
663 channels[0] = BABEL_IF_CHANNEL_INTERFERING;
664 channels[1] = 0;
665 }
666
667 if(parsed_len < len)
a76cf7e4
DS
668 ignore_update =
669 parse_update_subtlv(message + 2 + parsed_len,
670 len - parsed_len, channels);
671 }
672
d5260dc1 673 if (!ignore_update)
a76cf7e4
DS
674 update_route(router_id, prefix, plen, seqno, metric,
675 interval, neigh, nh, channels,
676 channels_len(channels));
677 } else if(type == MESSAGE_REQUEST) {
7d552fe6 678 unsigned char prefix[16], src_prefix[16], plen, src_plen;
679 int rc, is_ss;
680 if(len < 2) goto fail;
681 if(!known_ae(message[2])) {
682 debugf(BABEL_DEBUG_COMMON,"Received request with unknown AE %d. Ignoring.",
683 message[2]);
684 goto done;
685 }
ca10883e
DS
686 rc = network_prefix(message[2], message[3], 0,
687 message + 4, NULL, len - 2, prefix);
688 if(rc < 0) goto fail;
689 plen = message[3] + (message[2] == 1 ? 96 : 0);
690 debugf(BABEL_DEBUG_COMMON,"Received request for %s from %s on %s.",
691 message[2] == 0 ? "any" : format_prefix(prefix, plen),
692 format_address(from), ifp->name);
7d552fe6 693 if(message[2] == 1) {
694 v4tov6(src_prefix, zeroes);
695 src_plen = 96;
696 } else {
697 memcpy(src_prefix, zeroes, 16);
698 src_plen = 0;
699 }
700 rc = parse_request_subtlv(message[2], message + 4 + rc,
701 len - 2 - rc, src_prefix, &src_plen);
702 if(rc < 0)
703 goto done;
704 is_ss = !is_default(src_prefix, src_plen);
ca10883e
DS
705 if(message[2] == 0) {
706 struct babel_interface *neigh_ifp =babel_get_if_nfo(neigh->ifp);
7d552fe6 707 if(is_ss) {
708 /* Wildcard requests don't carry a source prefix. */
709 flog_err(EC_BABEL_PACKET,
710 "Received source-specific wildcard request.");
711 goto done;
712 }
ca10883e
DS
713 /* If a neighbour is requesting a full route dump from us,
714 we might as well send it an IHU. */
715 send_ihu(neigh, NULL);
716 /* Since nodes send wildcard requests on boot, booting
717 a large number of nodes at the same time may cause an
718 update storm. Ignore a wildcard request that happens
719 shortly after we sent a full update. */
720 if(neigh_ifp->last_update_time <
721 (time_t)(babel_now.tv_sec -
722 MAX(neigh_ifp->hello_interval / 100, 1)))
723 send_update(neigh->ifp, 0, NULL, 0);
724 } else {
725 send_update(neigh->ifp, 0, prefix, plen);
726 }
727 } else if(type == MESSAGE_MH_REQUEST) {
728 unsigned char prefix[16], plen;
729 unsigned short seqno;
730 int rc;
731 DO_NTOHS(seqno, message + 4);
732 rc = network_prefix(message[2], message[3], 0,
733 message + 16, NULL, len - 14, prefix);
734 if(rc < 0) goto fail;
735 plen = message[3] + (message[2] == 1 ? 96 : 0);
736 debugf(BABEL_DEBUG_COMMON,"Received request (%d) for %s from %s on %s (%s, %d).",
737 message[6],
738 format_prefix(prefix, plen),
739 format_address(from), ifp->name,
740 format_eui64(message + 8), seqno);
741 handle_request(neigh, prefix, plen, message[6],
742 seqno, message + 8);
743 } else {
744 debugf(BABEL_DEBUG_COMMON,"Received unknown packet type %d from %s on %s.",
745 type, format_address(from), ifp->name);
746 }
747 done:
748 i += len + 2;
749 continue;
750
751 fail:
5b003f31 752 flog_err(EC_BABEL_PACKET,
e33b116c
DS
753 "Couldn't parse packet (%d, %d) from %s on %s.",
754 message[0], message[1], format_address(from), ifp->name);
ca10883e
DS
755 goto done;
756 }
757
758 /* We can calculate the RTT to this neighbour. */
759 if(have_hello_rtt && hello_send_us && hello_rtt_receive_time) {
760 int remote_waiting_us, local_waiting_us;
761 unsigned int rtt, smoothed_rtt;
762 unsigned int old_rttcost;
763 int changed = 0;
764 remote_waiting_us = neigh->hello_send_us - hello_rtt_receive_time;
765 local_waiting_us = time_us(neigh->hello_rtt_receive_time) -
766 hello_send_us;
767
768 /* Sanity checks (validity window of 10 minutes). */
769 if(remote_waiting_us < 0 || local_waiting_us < 0 ||
770 remote_waiting_us > 600000000 || local_waiting_us > 600000000)
771 return;
772
773 rtt = MAX(0, local_waiting_us - remote_waiting_us);
1d5453d6 774 debugf(BABEL_DEBUG_COMMON, "RTT to %s on %s sample result: %d us.",
ca10883e
DS
775 format_address(from), ifp->name, rtt);
776
777 old_rttcost = neighbour_rttcost(neigh);
778 if (valid_rtt(neigh)) {
779 /* Running exponential average. */
780 smoothed_rtt = (babel_ifp->rtt_decay * rtt +
781 (256 - babel_ifp->rtt_decay) * neigh->rtt);
782 /* Rounding (up or down) to get closer to the sample. */
783 neigh->rtt = (neigh->rtt >= rtt) ? smoothed_rtt / 256 :
784 (smoothed_rtt + 255) / 256;
785 } else {
786 /* We prefer to be conservative with new neighbours
787 (higher RTT) */
788 assert(rtt <= 0x7FFFFFFF);
789 neigh->rtt = 2*rtt;
790 }
791 changed = (neighbour_rttcost(neigh) == old_rttcost ? 0 : 1);
792 update_neighbour_metric(neigh, changed);
793 neigh->rtt_time = babel_now;
794 }
795 return;
796}
797
798/* Under normal circumstances, there are enough moderation mechanisms
799 elsewhere in the protocol to make sure that this last-ditch check
800 should never trigger. But I'm superstitious. */
801
802static int
803check_bucket(struct interface *ifp)
804{
805 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
d11c6941 806 if(babel_ifp->bucket == 0) {
ca10883e
DS
807 int seconds = babel_now.tv_sec - babel_ifp->bucket_time;
808 if(seconds > 0) {
809 babel_ifp->bucket = MIN(BUCKET_TOKENS_MAX,
810 seconds * BUCKET_TOKENS_PER_SEC);
811 }
812 /* Reset bucket time unconditionally, in case clock is stepped. */
813 babel_ifp->bucket_time = babel_now.tv_sec;
814 }
815
816 if(babel_ifp->bucket > 0) {
817 babel_ifp->bucket--;
818 return 1;
819 } else {
820 return 0;
821 }
822}
823
824static int
825fill_rtt_message(struct interface *ifp)
826{
827 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
828 if((babel_ifp->flags & BABEL_IF_TIMESTAMPS) &&
829 (babel_ifp->buffered_hello >= 0)) {
830 if(babel_ifp->sendbuf[babel_ifp->buffered_hello + 8] == SUBTLV_PADN &&
831 babel_ifp->sendbuf[babel_ifp->buffered_hello + 9] == 4) {
832 unsigned int time;
833 /* Change the type of sub-TLV. */
834 babel_ifp->sendbuf[babel_ifp->buffered_hello + 8] =
835 SUBTLV_TIMESTAMP;
836 gettime(&babel_now);
837 time = time_us(babel_now);
838 DO_HTONL(babel_ifp->sendbuf + babel_ifp->buffered_hello + 10, time);
839 return 1;
840 } else {
3efd0893 841 flog_err(EC_BABEL_PACKET, "No space left for timestamp sub-TLV (this shouldn't happen)");
ca10883e
DS
842 return -1;
843 }
844 }
845 return 0;
846}
847
848void
849flushbuf(struct interface *ifp)
850{
851 int rc;
852 struct sockaddr_in6 sin6;
853 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
854
855 assert(babel_ifp->buffered <= babel_ifp->bufsize);
856
857 flushupdates(ifp);
858
859 if(babel_ifp->buffered > 0) {
860 debugf(BABEL_DEBUG_COMMON," (flushing %d buffered bytes on %s)",
861 babel_ifp->buffered, ifp->name);
862 if(check_bucket(ifp)) {
863 memset(&sin6, 0, sizeof(sin6));
864 sin6.sin6_family = AF_INET6;
865 memcpy(&sin6.sin6_addr, protocol_group, 16);
866 sin6.sin6_port = htons(protocol_port);
867 sin6.sin6_scope_id = ifp->ifindex;
868 DO_HTONS(packet_header + 2, babel_ifp->buffered);
869 fill_rtt_message(ifp);
870 rc = babel_send(protocol_socket,
871 packet_header, sizeof(packet_header),
872 babel_ifp->sendbuf, babel_ifp->buffered,
873 (struct sockaddr*)&sin6, sizeof(sin6));
874 if(rc < 0)
5b003f31 875 flog_err(EC_BABEL_PACKET, "send: %s", safe_strerror(errno));
ca10883e 876 } else {
5c997d29
DS
877 flog_err(EC_BABEL_PACKET, "Bucket full, dropping packet to %s.",
878 ifp->name);
879 }
ca10883e
DS
880 }
881 VALGRIND_MAKE_MEM_UNDEFINED(babel_ifp->sendbuf, babel_ifp->bufsize);
882 babel_ifp->buffered = 0;
883 babel_ifp->buffered_hello = -1;
884 babel_ifp->have_buffered_id = 0;
885 babel_ifp->have_buffered_nh = 0;
886 babel_ifp->have_buffered_prefix = 0;
887 babel_ifp->flush_timeout.tv_sec = 0;
888 babel_ifp->flush_timeout.tv_usec = 0;
889}
890
891static void
892schedule_flush(struct interface *ifp)
893{
894 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
895 unsigned msecs = jitter(babel_ifp, 0);
896 if(babel_ifp->flush_timeout.tv_sec != 0 &&
897 timeval_minus_msec(&babel_ifp->flush_timeout, &babel_now) < msecs)
898 return;
899 set_timeout(&babel_ifp->flush_timeout, msecs);
900}
901
902static void
903schedule_flush_now(struct interface *ifp)
904{
905 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
906 /* Almost now */
907 unsigned msecs = roughly(10);
908 if(babel_ifp->flush_timeout.tv_sec != 0 &&
909 timeval_minus_msec(&babel_ifp->flush_timeout, &babel_now) < msecs)
910 return;
911 set_timeout(&babel_ifp->flush_timeout, msecs);
912}
913
914static void
915schedule_unicast_flush(unsigned msecs)
916{
917 if(!unicast_neighbour)
918 return;
919 if(unicast_flush_timeout.tv_sec != 0 &&
920 timeval_minus_msec(&unicast_flush_timeout, &babel_now) < msecs)
921 return;
922 unicast_flush_timeout.tv_usec = (babel_now.tv_usec + msecs * 1000) %1000000;
923 unicast_flush_timeout.tv_sec =
924 babel_now.tv_sec + (babel_now.tv_usec / 1000 + msecs) / 1000;
925}
926
927static void
928ensure_space(struct interface *ifp, int space)
929{
930 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
931 if(babel_ifp->bufsize - babel_ifp->buffered < space)
932 flushbuf(ifp);
933}
934
935static void
936start_message(struct interface *ifp, int type, int len)
937{
938 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
939 if(babel_ifp->bufsize - babel_ifp->buffered < len + 2)
940 flushbuf(ifp);
941 babel_ifp->sendbuf[babel_ifp->buffered++] = type;
942 babel_ifp->sendbuf[babel_ifp->buffered++] = len;
943}
944
945static void
946end_message(struct interface *ifp, int type, int bytes)
947{
948 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
949 assert(babel_ifp->buffered >= bytes + 2 &&
950 babel_ifp->sendbuf[babel_ifp->buffered - bytes - 2] == type &&
951 babel_ifp->sendbuf[babel_ifp->buffered - bytes - 1] == bytes);
952 schedule_flush(ifp);
953}
954
955static void
956accumulate_byte(struct interface *ifp, unsigned char value)
957{
958 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
959 babel_ifp->sendbuf[babel_ifp->buffered++] = value;
960}
961
962static void
963accumulate_short(struct interface *ifp, unsigned short value)
964{
965 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
966 DO_HTONS(babel_ifp->sendbuf + babel_ifp->buffered, value);
967 babel_ifp->buffered += 2;
968}
969
970static void
971accumulate_int(struct interface *ifp, unsigned int value)
972{
973 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
974 DO_HTONL(babel_ifp->sendbuf + babel_ifp->buffered, value);
975 babel_ifp->buffered += 4;
976}
977
978static void
979accumulate_bytes(struct interface *ifp,
980 const unsigned char *value, unsigned len)
981{
982 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
983 memcpy(babel_ifp->sendbuf + babel_ifp->buffered, value, len);
984 babel_ifp->buffered += len;
985}
986
987static int
988start_unicast_message(struct neighbour *neigh, int type, int len)
989{
990 if(unicast_neighbour) {
991 if(neigh != unicast_neighbour ||
992 unicast_buffered + len + 2 >=
993 MIN(UNICAST_BUFSIZE, babel_get_if_nfo(neigh->ifp)->bufsize))
994 flush_unicast(0);
995 }
996 if(!unicast_buffer)
997 unicast_buffer = malloc(UNICAST_BUFSIZE);
998 if(!unicast_buffer) {
5b003f31 999 flog_err(EC_BABEL_MEMORY, "malloc(unicast_buffer): %s",
e33b116c 1000 safe_strerror(errno));
ca10883e
DS
1001 return -1;
1002 }
1003
1004 unicast_neighbour = neigh;
1005
1006 unicast_buffer[unicast_buffered++] = type;
1007 unicast_buffer[unicast_buffered++] = len;
1008 return 1;
1009}
1010
1011static void
1012end_unicast_message(struct neighbour *neigh, int type, int bytes)
1013{
1014 assert(unicast_neighbour == neigh && unicast_buffered >= bytes + 2 &&
1015 unicast_buffer[unicast_buffered - bytes - 2] == type &&
1016 unicast_buffer[unicast_buffered - bytes - 1] == bytes);
1017 schedule_unicast_flush(jitter(babel_get_if_nfo(neigh->ifp), 0));
1018}
1019
1020static void
1021accumulate_unicast_byte(struct neighbour *neigh, unsigned char value)
1022{
1023 unicast_buffer[unicast_buffered++] = value;
1024}
1025
1026static void
1027accumulate_unicast_short(struct neighbour *neigh, unsigned short value)
1028{
1029 DO_HTONS(unicast_buffer + unicast_buffered, value);
1030 unicast_buffered += 2;
1031}
1032
1033static void
1034accumulate_unicast_int(struct neighbour *neigh, unsigned int value)
1035{
1036 DO_HTONL(unicast_buffer + unicast_buffered, value);
1037 unicast_buffered += 4;
1038}
1039
1040static void
1041accumulate_unicast_bytes(struct neighbour *neigh,
1042 const unsigned char *value, unsigned len)
1043{
1044 memcpy(unicast_buffer + unicast_buffered, value, len);
1045 unicast_buffered += len;
1046}
1047
1048void
1049send_ack(struct neighbour *neigh, unsigned short nonce, unsigned short interval)
1050{
1051 int rc;
1052 debugf(BABEL_DEBUG_COMMON,"Sending ack (%04x) to %s on %s.",
1053 nonce, format_address(neigh->address), neigh->ifp->name);
1054 rc = start_unicast_message(neigh, MESSAGE_ACK, 2); if(rc < 0) return;
1055 accumulate_unicast_short(neigh, nonce);
1056 end_unicast_message(neigh, MESSAGE_ACK, 2);
1057 /* Roughly yields a value no larger than 3/2, so this meets the deadline */
1058 schedule_unicast_flush(roughly(interval * 6));
1059}
1060
1061void
1062send_hello_noupdate(struct interface *ifp, unsigned interval)
1063{
1064 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
1065 /* This avoids sending multiple hellos in a single packet, which breaks
1066 link quality estimation. */
1067 if(babel_ifp->buffered_hello >= 0)
1068 flushbuf(ifp);
1069
1070 babel_ifp->hello_seqno = seqno_plus(babel_ifp->hello_seqno, 1);
1071 set_timeout(&babel_ifp->hello_timeout, babel_ifp->hello_interval);
1072
1073 if(!if_up(ifp))
1074 return;
1075
1076 debugf(BABEL_DEBUG_COMMON,"Sending hello %d (%d) to %s.",
1077 babel_ifp->hello_seqno, interval, ifp->name);
1078
1079 start_message(ifp, MESSAGE_HELLO,
1080 (babel_ifp->flags & BABEL_IF_TIMESTAMPS) ? 12 : 6);
1081 babel_ifp->buffered_hello = babel_ifp->buffered - 2;
1082 accumulate_short(ifp, 0);
1083 accumulate_short(ifp, babel_ifp->hello_seqno);
1084 accumulate_short(ifp, interval > 0xFFFF ? 0xFFFF : interval);
1085 if(babel_ifp->flags & BABEL_IF_TIMESTAMPS) {
1086 /* Sub-TLV containing the local time of emission. We use a
1087 Pad4 sub-TLV, which we'll fill just before sending. */
1088 accumulate_byte(ifp, SUBTLV_PADN);
1089 accumulate_byte(ifp, 4);
1090 accumulate_int(ifp, 0);
1091 }
1092 end_message(ifp, MESSAGE_HELLO,
1093 (babel_ifp->flags & BABEL_IF_TIMESTAMPS) ? 12 : 6);
1094}
1095
1096void
1097send_hello(struct interface *ifp)
1098{
1099 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
1100 send_hello_noupdate(ifp, (babel_ifp->hello_interval + 9) / 10);
1101 /* Send full IHU every 3 hellos, and marginal IHU each time */
1102 if(babel_ifp->hello_seqno % 3 == 0)
1103 send_ihu(NULL, ifp);
1104 else
1105 send_marginal_ihu(ifp);
1106}
1107
1108void
1109flush_unicast(int dofree)
1110{
1111 struct sockaddr_in6 sin6;
1112 int rc;
1113
1114 if(unicast_buffered == 0)
1115 goto done;
1116
1117 if(!if_up(unicast_neighbour->ifp))
1118 goto done;
1119
1120 /* Preserve ordering of messages */
1121 flushbuf(unicast_neighbour->ifp);
1122
1123 if(check_bucket(unicast_neighbour->ifp)) {
1124 memset(&sin6, 0, sizeof(sin6));
1125 sin6.sin6_family = AF_INET6;
1126 memcpy(&sin6.sin6_addr, unicast_neighbour->address, 16);
1127 sin6.sin6_port = htons(protocol_port);
1128 sin6.sin6_scope_id = unicast_neighbour->ifp->ifindex;
1129 DO_HTONS(packet_header + 2, unicast_buffered);
1130 fill_rtt_message(unicast_neighbour->ifp);
1131 rc = babel_send(protocol_socket,
1132 packet_header, sizeof(packet_header),
1133 unicast_buffer, unicast_buffered,
1134 (struct sockaddr*)&sin6, sizeof(sin6));
1135 if(rc < 0)
5b003f31 1136 flog_err(EC_BABEL_PACKET, "send(unicast): %s",
e33b116c 1137 safe_strerror(errno));
ca10883e 1138 } else {
5c997d29
DS
1139 flog_err(EC_BABEL_PACKET,
1140 "Bucket full, dropping unicast packet to %s if %s.",
1141 format_address(unicast_neighbour->address),
1142 unicast_neighbour->ifp->name);
ca10883e
DS
1143 }
1144
1145 done:
1146 VALGRIND_MAKE_MEM_UNDEFINED(unicast_buffer, UNICAST_BUFSIZE);
1147 unicast_buffered = 0;
1148 if(dofree && unicast_buffer) {
1149 free(unicast_buffer);
1150 unicast_buffer = NULL;
1151 }
1152 unicast_neighbour = NULL;
1153 unicast_flush_timeout.tv_sec = 0;
1154 unicast_flush_timeout.tv_usec = 0;
1155}
1156
1157static void
1158really_send_update(struct interface *ifp,
1159 const unsigned char *id,
1160 const unsigned char *prefix, unsigned char plen,
1161 unsigned short seqno, unsigned short metric,
1162 unsigned char *channels, int channels_len)
1163{
1164 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
1165 int add_metric, v4, real_plen, omit = 0;
1166 const unsigned char *real_prefix;
1167 unsigned short flags = 0;
1168 int channels_size;
1169
1170 if(diversity_kind != DIVERSITY_CHANNEL)
1171 channels_len = -1;
1172
1173 channels_size = channels_len >= 0 ? channels_len + 2 : 0;
1174
1175 if(!if_up(ifp))
1176 return;
1177
1178 add_metric = output_filter(id, prefix, plen, ifp->ifindex);
1179 if(add_metric >= INFINITY)
1180 return;
1181
1182 metric = MIN(metric + add_metric, INFINITY);
1183 /* Worst case */
1184 ensure_space(ifp, 20 + 12 + 28);
1185
1186 v4 = plen >= 96 && v4mapped(prefix);
1187
1188 if(v4) {
1189 if(!babel_ifp->ipv4)
1190 return;
1191 if(!babel_ifp->have_buffered_nh ||
1192 memcmp(babel_ifp->buffered_nh, babel_ifp->ipv4, 4) != 0) {
1193 start_message(ifp, MESSAGE_NH, 6);
1194 accumulate_byte(ifp, 1);
1195 accumulate_byte(ifp, 0);
1196 accumulate_bytes(ifp, babel_ifp->ipv4, 4);
1197 end_message(ifp, MESSAGE_NH, 6);
1198 memcpy(babel_ifp->buffered_nh, babel_ifp->ipv4, 4);
1199 babel_ifp->have_buffered_nh = 1;
1200 }
1201
1202 real_prefix = prefix + 12;
1203 real_plen = plen - 96;
1204 } else {
1205 if(babel_ifp->have_buffered_prefix) {
1206 while(omit < plen / 8 &&
1207 babel_ifp->buffered_prefix[omit] == prefix[omit])
1208 omit++;
1209 }
1210 if(!babel_ifp->have_buffered_prefix || plen >= 48)
1211 flags |= 0x80;
1212 real_prefix = prefix;
1213 real_plen = plen;
1214 }
1215
1216 if(!babel_ifp->have_buffered_id
1217 || memcmp(id, babel_ifp->buffered_id, 8) != 0) {
1218 if(real_plen == 128 && memcmp(real_prefix + 8, id, 8) == 0) {
1219 flags |= 0x40;
1220 } else {
1221 start_message(ifp, MESSAGE_ROUTER_ID, 10);
1222 accumulate_short(ifp, 0);
1223 accumulate_bytes(ifp, id, 8);
1224 end_message(ifp, MESSAGE_ROUTER_ID, 10);
1225 }
01b08f09 1226 memcpy(babel_ifp->buffered_id, id, sizeof(babel_ifp->buffered_id));
ca10883e
DS
1227 babel_ifp->have_buffered_id = 1;
1228 }
1229
1230 start_message(ifp, MESSAGE_UPDATE, 10 + (real_plen + 7) / 8 - omit +
1231 channels_size);
1232 accumulate_byte(ifp, v4 ? 1 : 2);
1233 accumulate_byte(ifp, flags);
1234 accumulate_byte(ifp, real_plen);
1235 accumulate_byte(ifp, omit);
1236 accumulate_short(ifp, (babel_ifp->update_interval + 5) / 10);
1237 accumulate_short(ifp, seqno);
1238 accumulate_short(ifp, metric);
1239 accumulate_bytes(ifp, real_prefix + omit, (real_plen + 7) / 8 - omit);
1240 /* Note that an empty channels TLV is different from no such TLV. */
1241 if(channels_len >= 0) {
1242 accumulate_byte(ifp, 2);
1243 accumulate_byte(ifp, channels_len);
fa3bf3a2
MS
1244
1245 if (channels && channels_len > 0)
1246 accumulate_bytes(ifp, channels, channels_len);
ca10883e
DS
1247 }
1248 end_message(ifp, MESSAGE_UPDATE, 10 + (real_plen + 7) / 8 - omit +
1249 channels_size);
1250
1251 if(flags & 0x80) {
1252 memcpy(babel_ifp->buffered_prefix, prefix, 16);
1253 babel_ifp->have_buffered_prefix = 1;
1254 }
1255}
1256
1257static int
1258compare_buffered_updates(const void *av, const void *bv)
1259{
1260 const struct buffered_update *a = av, *b = bv;
1261 int rc, v4a, v4b, ma, mb;
1262
1263 rc = memcmp(a->id, b->id, 8);
1264 if(rc != 0)
1265 return rc;
1266
1267 v4a = (a->plen >= 96 && v4mapped(a->prefix));
1268 v4b = (b->plen >= 96 && v4mapped(b->prefix));
1269
1270 if(v4a > v4b)
1271 return 1;
1272 else if(v4a < v4b)
1273 return -1;
1274
1275 ma = (!v4a && a->plen == 128 && memcmp(a->prefix + 8, a->id, 8) == 0);
1276 mb = (!v4b && b->plen == 128 && memcmp(b->prefix + 8, b->id, 8) == 0);
1277
1278 if(ma > mb)
1279 return -1;
1280 else if(mb > ma)
1281 return 1;
1282
1283 if(a->plen < b->plen)
1284 return 1;
1285 else if(a->plen > b->plen)
1286 return -1;
1287
1288 return memcmp(a->prefix, b->prefix, 16);
1289}
1290
1291void
1292flushupdates(struct interface *ifp)
1293{
1294 babel_interface_nfo *babel_ifp = NULL;
1295 struct xroute *xroute;
1296 struct babel_route *route;
1297 const unsigned char *last_prefix = NULL;
1298 unsigned char last_plen = 0xFF;
1299 int i;
1300
1301 if(ifp == NULL) {
f4e14fdb
RW
1302 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
1303 struct interface *ifp_aux;
1304 FOR_ALL_INTERFACES(vrf, ifp_aux)
ca10883e
DS
1305 flushupdates(ifp_aux);
1306 return;
1307 }
1308
1309 babel_ifp = babel_get_if_nfo(ifp);
1310 if(babel_ifp->num_buffered_updates > 0) {
1311 struct buffered_update *b = babel_ifp->buffered_updates;
1312 int n = babel_ifp->num_buffered_updates;
1313
1314 babel_ifp->buffered_updates = NULL;
1315 babel_ifp->update_bufsize = 0;
1316 babel_ifp->num_buffered_updates = 0;
1317
1318 if(!if_up(ifp))
1319 goto done;
1320
1321 debugf(BABEL_DEBUG_COMMON," (flushing %d buffered updates on %s (%d))",
1322 n, ifp->name, ifp->ifindex);
1323
1324 /* In order to send fewer update messages, we want to send updates
1325 with the same router-id together, with IPv6 going out before IPv4. */
1326
1327 for(i = 0; i < n; i++) {
1328 route = find_installed_route(b[i].prefix, b[i].plen);
1329 if(route)
1330 memcpy(b[i].id, route->src->id, 8);
1331 else
1332 memcpy(b[i].id, myid, 8);
1333 }
1334
1335 qsort(b, n, sizeof(struct buffered_update), compare_buffered_updates);
1336
1337 for(i = 0; i < n; i++) {
1338 /* The same update may be scheduled multiple times before it is
1339 sent out. Since our buffer is now sorted, it is enough to
1340 compare with the previous update. */
1341
1342 if(last_prefix) {
1343 if(b[i].plen == last_plen &&
1344 memcmp(b[i].prefix, last_prefix, 16) == 0)
1345 continue;
1346 }
1347
1348 xroute = find_xroute(b[i].prefix, b[i].plen);
1349 route = find_installed_route(b[i].prefix, b[i].plen);
1350
1351 if(xroute && (!route || xroute->metric <= kernel_metric)) {
1352 really_send_update(ifp, myid,
1353 xroute->prefix, xroute->plen,
1354 myseqno, xroute->metric,
1355 NULL, 0);
1356 last_prefix = xroute->prefix;
1357 last_plen = xroute->plen;
1358 } else if(route) {
1359 unsigned char channels[DIVERSITY_HOPS];
1360 int chlen;
1361 struct interface *route_ifp = route->neigh->ifp;
1362 struct babel_interface *babel_route_ifp = NULL;
1363 unsigned short metric;
1364 unsigned short seqno;
1365
1366 seqno = route->seqno;
1367 metric =
1368 route_interferes(route, ifp) ?
1369 route_metric(route) :
1370 route_metric_noninterfering(route);
1371
1372 if(metric < INFINITY)
1373 satisfy_request(route->src->prefix, route->src->plen,
1374 seqno, route->src->id, ifp);
1375 if((babel_ifp->flags & BABEL_IF_SPLIT_HORIZON) &&
1376 route->neigh->ifp == ifp)
1377 continue;
1378
1379 babel_route_ifp = babel_get_if_nfo(route_ifp);
1380 if(babel_route_ifp->channel ==BABEL_IF_CHANNEL_NONINTERFERING) {
1381 memcpy(channels, route->channels, DIVERSITY_HOPS);
1382 } else {
1383 if(babel_route_ifp->channel == BABEL_IF_CHANNEL_UNKNOWN)
1384 channels[0] = BABEL_IF_CHANNEL_INTERFERING;
1385 else {
1386 assert(babel_route_ifp->channel > 0 &&
1387 babel_route_ifp->channel <= 255);
1388 channels[0] = babel_route_ifp->channel;
1389 }
1390 memcpy(channels + 1, route->channels, DIVERSITY_HOPS - 1);
1391 }
1392
1393 chlen = channels_len(channels);
1394 really_send_update(ifp, route->src->id,
1395 route->src->prefix,
1396 route->src->plen,
1397 seqno, metric,
1398 channels, chlen);
1399 update_source(route->src, seqno, metric);
1400 last_prefix = route->src->prefix;
1401 last_plen = route->src->plen;
1402 } else {
1403 /* There's no route for this prefix. This can happen shortly
1404 after an xroute has been retracted, so send a retraction. */
1405 really_send_update(ifp, myid, b[i].prefix, b[i].plen,
1406 myseqno, INFINITY, NULL, -1);
1407 }
1408 }
1409 schedule_flush_now(ifp);
1410 done:
1411 free(b);
1412 }
1413 babel_ifp->update_flush_timeout.tv_sec = 0;
1414 babel_ifp->update_flush_timeout.tv_usec = 0;
1415}
1416
1417static void
1418schedule_update_flush(struct interface *ifp, int urgent)
1419{
1420 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
1421 unsigned msecs;
1422 msecs = update_jitter(babel_ifp, urgent);
1423 if(babel_ifp->update_flush_timeout.tv_sec != 0 &&
1424 timeval_minus_msec(&babel_ifp->update_flush_timeout, &babel_now) < msecs)
1425 return;
1426 set_timeout(&babel_ifp->update_flush_timeout, msecs);
1427}
1428
1429static void
1430buffer_update(struct interface *ifp,
1431 const unsigned char *prefix, unsigned char plen)
1432{
1433 babel_interface_nfo *babel_ifp = babel_get_if_nfo(ifp);
1434 if(babel_ifp->num_buffered_updates > 0 &&
1435 babel_ifp->num_buffered_updates >= babel_ifp->update_bufsize)
1436 flushupdates(ifp);
1437
1438 if(babel_ifp->update_bufsize == 0) {
1439 int n;
1440 assert(babel_ifp->buffered_updates == NULL);
1441 /* Allocate enough space to hold a full update. Since the
1442 number of installed routes will grow over time, make sure we
1443 have enough space to send a full-ish frame. */
1444 n = installed_routes_estimate() + xroutes_estimate() + 4;
1445 n = MAX(n, babel_ifp->bufsize / 16);
1446 again:
1447 babel_ifp->buffered_updates = malloc(n *sizeof(struct buffered_update));
1448 if(babel_ifp->buffered_updates == NULL) {
5b003f31 1449 flog_err(EC_BABEL_MEMORY, "malloc(buffered_updates): %s",
e33b116c 1450 safe_strerror(errno));
ca10883e
DS
1451 if(n > 4) {
1452 /* Try again with a tiny buffer. */
1453 n = 4;
1454 goto again;
1455 }
1456 return;
1457 }
1458 babel_ifp->update_bufsize = n;
1459 babel_ifp->num_buffered_updates = 0;
1460 }
1461
1462 memcpy(babel_ifp->buffered_updates[babel_ifp->num_buffered_updates].prefix,
1463 prefix, 16);
1464 babel_ifp->buffered_updates[babel_ifp->num_buffered_updates].plen = plen;
1465 babel_ifp->num_buffered_updates++;
1466}
1467
1468void
1469send_update(struct interface *ifp, int urgent,
1470 const unsigned char *prefix, unsigned char plen)
1471{
1472 babel_interface_nfo *babel_ifp = NULL;
1473
1474 if(ifp == NULL) {
f4e14fdb
RW
1475 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
1476 struct interface *ifp_aux;
ca10883e 1477 struct babel_route *route;
f4e14fdb 1478 FOR_ALL_INTERFACES(vrf, ifp_aux)
ca10883e
DS
1479 send_update(ifp_aux, urgent, prefix, plen);
1480 if(prefix) {
1481 /* Since flushupdates only deals with non-wildcard interfaces, we
1482 need to do this now. */
1483 route = find_installed_route(prefix, plen);
1484 if(route && route_metric(route) < INFINITY)
1485 satisfy_request(prefix, plen, route->src->seqno, route->src->id,
1486 NULL);
1487 }
1488 return;
1489 }
1490
1491 if(!if_up(ifp))
1492 return;
1493
1494 babel_ifp = babel_get_if_nfo(ifp);
1495 if(prefix) {
1496 debugf(BABEL_DEBUG_COMMON,"Sending update to %s for %s.",
1497 ifp->name, format_prefix(prefix, plen));
1498 buffer_update(ifp, prefix, plen);
1499 } else {
1500 struct route_stream *routes = NULL;
1501 send_self_update(ifp);
1502 debugf(BABEL_DEBUG_COMMON,"Sending update to %s for any.", ifp->name);
1503 routes = route_stream(1);
1504 if(routes) {
1505 while(1) {
1506 struct babel_route *route = route_stream_next(routes);
1507 if(route == NULL)
1508 break;
1509 buffer_update(ifp, route->src->prefix, route->src->plen);
1510 }
1511 route_stream_done(routes);
1512 } else {
5b003f31 1513 flog_err(EC_BABEL_MEMORY, "Couldn't allocate route stream.");
ca10883e
DS
1514 }
1515 set_timeout(&babel_ifp->update_timeout, babel_ifp->update_interval);
1516 babel_ifp->last_update_time = babel_now.tv_sec;
1517 }
1518 schedule_update_flush(ifp, urgent);
1519}
1520
1521void
1522send_update_resend(struct interface *ifp,
1523 const unsigned char *prefix, unsigned char plen)
1524{
1525 assert(prefix != NULL);
1526
1527 send_update(ifp, 1, prefix, plen);
1528 record_resend(RESEND_UPDATE, prefix, plen, 0, NULL, NULL, resend_delay);
1529}
1530
1531void
1532send_wildcard_retraction(struct interface *ifp)
1533{
1534 babel_interface_nfo *babel_ifp = NULL;
1535 if(ifp == NULL) {
f4e14fdb
RW
1536 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
1537 struct interface *ifp_aux;
1538 FOR_ALL_INTERFACES(vrf, ifp_aux)
ca10883e
DS
1539 send_wildcard_retraction(ifp_aux);
1540 return;
1541 }
1542
1543 if(!if_up(ifp))
1544 return;
1545
1546 babel_ifp = babel_get_if_nfo(ifp);
1547 start_message(ifp, MESSAGE_UPDATE, 10);
1548 accumulate_byte(ifp, 0);
1549 accumulate_byte(ifp, 0x40);
1550 accumulate_byte(ifp, 0);
1551 accumulate_byte(ifp, 0);
1552 accumulate_short(ifp, 0xFFFF);
1553 accumulate_short(ifp, myseqno);
1554 accumulate_short(ifp, 0xFFFF);
1555 end_message(ifp, MESSAGE_UPDATE, 10);
1556
1557 babel_ifp->have_buffered_id = 0;
1558}
1559
1560void
4d762f26 1561update_myseqno(void)
ca10883e
DS
1562{
1563 myseqno = seqno_plus(myseqno, 1);
1564}
1565
1566void
1567send_self_update(struct interface *ifp)
1568{
1569 struct xroute_stream *xroutes;
1570 if(ifp == NULL) {
f4e14fdb
RW
1571 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
1572 struct interface *ifp_aux;
1573 FOR_ALL_INTERFACES(vrf, ifp_aux) {
ca10883e
DS
1574 if(!if_up(ifp_aux))
1575 continue;
1576 send_self_update(ifp_aux);
1577 }
1578 return;
1579 }
1580
1581 debugf(BABEL_DEBUG_COMMON,"Sending self update to %s.", ifp->name);
1582 xroutes = xroute_stream();
1583 if(xroutes) {
1584 while(1) {
1585 struct xroute *xroute = xroute_stream_next(xroutes);
1586 if(xroute == NULL) break;
1587 send_update(ifp, 0, xroute->prefix, xroute->plen);
1588 }
1589 xroute_stream_done(xroutes);
1590 } else {
5b003f31 1591 flog_err(EC_BABEL_MEMORY, "Couldn't allocate xroute stream.");
ca10883e
DS
1592 }
1593}
1594
1595void
1596send_ihu(struct neighbour *neigh, struct interface *ifp)
1597{
1598 babel_interface_nfo *babel_ifp = NULL;
1599 int rxcost, interval;
1600 int ll;
1601 int send_rtt_data;
1602 int msglen;
1603
1604 if(neigh == NULL && ifp == NULL) {
f4e14fdb 1605 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
ca10883e 1606 struct interface *ifp_aux;
f4e14fdb 1607 FOR_ALL_INTERFACES(vrf, ifp_aux) {
ca10883e
DS
1608 if(if_up(ifp_aux))
1609 continue;
1610 send_ihu(NULL, ifp_aux);
1611 }
1612 return;
1613 }
1614
1615 if(neigh == NULL) {
1616 struct neighbour *ngh;
1617 FOR_ALL_NEIGHBOURS(ngh) {
1618 if(ngh->ifp == ifp)
1619 send_ihu(ngh, ifp);
1620 }
1621 return;
1622 }
1623
1624
1625 if(ifp && neigh->ifp != ifp)
1626 return;
1627
1628 ifp = neigh->ifp;
1629 babel_ifp = babel_get_if_nfo(ifp);
1630 if(!if_up(ifp))
1631 return;
1632
1633 rxcost = neighbour_rxcost(neigh);
1634 interval = (babel_ifp->hello_interval * 3 + 9) / 10;
1635
1636 /* Conceptually, an IHU is a unicast message. We usually send them as
1637 multicast, since this allows aggregation into a single packet and
1638 avoids an ARP exchange. If we already have a unicast message queued
1639 for this neighbour, however, we might as well piggyback the IHU. */
1640 debugf(BABEL_DEBUG_COMMON,"Sending %sihu %d on %s to %s.",
1641 unicast_neighbour == neigh ? "unicast " : "",
1642 rxcost,
1643 neigh->ifp->name,
1644 format_address(neigh->address));
1645
1646 ll = linklocal(neigh->address);
1647
1648 if((babel_ifp->flags & BABEL_IF_TIMESTAMPS) && neigh->hello_send_us
1649 /* Checks whether the RTT data is not too old to be sent. */
1650 && timeval_minus_msec(&babel_now,
1651 &neigh->hello_rtt_receive_time) < 1000000) {
1652 send_rtt_data = 1;
1653 } else {
1654 neigh->hello_send_us = 0;
1655 send_rtt_data = 0;
1656 }
1657
1658 /* The length depends on the format of the address, and then an
1659 optional 10-bytes sub-TLV for timestamps (used to compute a RTT). */
1660 msglen = (ll ? 14 : 22) + (send_rtt_data ? 10 : 0);
1661
1662 if(unicast_neighbour != neigh) {
1663 start_message(ifp, MESSAGE_IHU, msglen);
1664 accumulate_byte(ifp, ll ? 3 : 2);
1665 accumulate_byte(ifp, 0);
1666 accumulate_short(ifp, rxcost);
1667 accumulate_short(ifp, interval);
1668 if(ll)
1669 accumulate_bytes(ifp, neigh->address + 8, 8);
1670 else
1671 accumulate_bytes(ifp, neigh->address, 16);
1672 if (send_rtt_data) {
1673 accumulate_byte(ifp, SUBTLV_TIMESTAMP);
1674 accumulate_byte(ifp, 8);
1675 accumulate_int(ifp, neigh->hello_send_us);
1676 accumulate_int(ifp, time_us(neigh->hello_rtt_receive_time));
1677 }
1678 end_message(ifp, MESSAGE_IHU, msglen);
1679 } else {
1680 int rc;
1681 rc = start_unicast_message(neigh, MESSAGE_IHU, msglen);
1682 if(rc < 0) return;
1683 accumulate_unicast_byte(neigh, ll ? 3 : 2);
1684 accumulate_unicast_byte(neigh, 0);
1685 accumulate_unicast_short(neigh, rxcost);
1686 accumulate_unicast_short(neigh, interval);
1687 if(ll)
1688 accumulate_unicast_bytes(neigh, neigh->address + 8, 8);
1689 else
1690 accumulate_unicast_bytes(neigh, neigh->address, 16);
1691 if (send_rtt_data) {
1692 accumulate_unicast_byte(neigh, SUBTLV_TIMESTAMP);
1693 accumulate_unicast_byte(neigh, 8);
1694 accumulate_unicast_int(neigh, neigh->hello_send_us);
1695 accumulate_unicast_int(neigh,
1696 time_us(neigh->hello_rtt_receive_time));
1697 }
1698 end_unicast_message(neigh, MESSAGE_IHU, msglen);
1699 }
1700}
1701
1702/* Send IHUs to all marginal neighbours */
1703void
1704send_marginal_ihu(struct interface *ifp)
1705{
1706 struct neighbour *neigh;
1707 FOR_ALL_NEIGHBOURS(neigh) {
1708 if(ifp && neigh->ifp != ifp)
1709 continue;
1710 if(neigh->txcost >= 384 || (neigh->reach & 0xF000) != 0xF000)
1711 send_ihu(neigh, ifp);
1712 }
1713}
1714
1715void
1716send_request(struct interface *ifp,
1717 const unsigned char *prefix, unsigned char plen)
1718{
1719 int v4, pb, len;
1720
1721 if(ifp == NULL) {
f4e14fdb
RW
1722 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
1723 struct interface *ifp_aux;
1724 FOR_ALL_INTERFACES(vrf, ifp_aux) {
ca10883e
DS
1725 if(if_up(ifp_aux))
1726 continue;
1727 send_request(ifp_aux, prefix, plen);
1728 }
1729 return;
1730 }
1731
1732 /* make sure any buffered updates go out before this request. */
1733 flushupdates(ifp);
1734
1735 if(!if_up(ifp))
1736 return;
1737
1738 debugf(BABEL_DEBUG_COMMON,"sending request to %s for %s.",
1739 ifp->name, prefix ? format_prefix(prefix, plen) : "any");
1740 v4 = plen >= 96 && v4mapped(prefix);
1741 pb = v4 ? ((plen - 96) + 7) / 8 : (plen + 7) / 8;
1742 len = !prefix ? 2 : 2 + pb;
1743
1744 start_message(ifp, MESSAGE_REQUEST, len);
1745 accumulate_byte(ifp, !prefix ? 0 : v4 ? 1 : 2);
1746 accumulate_byte(ifp, !prefix ? 0 : v4 ? plen - 96 : plen);
1747 if(prefix) {
1748 if(v4)
1749 accumulate_bytes(ifp, prefix + 12, pb);
1750 else
1751 accumulate_bytes(ifp, prefix, pb);
1752 }
1753 end_message(ifp, MESSAGE_REQUEST, len);
1754}
1755
1756void
1757send_unicast_request(struct neighbour *neigh,
1758 const unsigned char *prefix, unsigned char plen)
1759{
1760 int rc, v4, pb, len;
1761
1762 /* make sure any buffered updates go out before this request. */
1763 flushupdates(neigh->ifp);
1764
1765 debugf(BABEL_DEBUG_COMMON,"sending unicast request to %s for %s.",
1766 format_address(neigh->address),
1767 prefix ? format_prefix(prefix, plen) : "any");
1768 v4 = plen >= 96 && v4mapped(prefix);
1769 pb = v4 ? ((plen - 96) + 7) / 8 : (plen + 7) / 8;
1770 len = !prefix ? 2 : 2 + pb;
1771
1772 rc = start_unicast_message(neigh, MESSAGE_REQUEST, len);
1773 if(rc < 0) return;
1774 accumulate_unicast_byte(neigh, !prefix ? 0 : v4 ? 1 : 2);
1775 accumulate_unicast_byte(neigh, !prefix ? 0 : v4 ? plen - 96 : plen);
1776 if(prefix) {
1777 if(v4)
1778 accumulate_unicast_bytes(neigh, prefix + 12, pb);
1779 else
1780 accumulate_unicast_bytes(neigh, prefix, pb);
1781 }
1782 end_unicast_message(neigh, MESSAGE_REQUEST, len);
1783}
1784
1785void
1786send_multihop_request(struct interface *ifp,
1787 const unsigned char *prefix, unsigned char plen,
1788 unsigned short seqno, const unsigned char *id,
1789 unsigned short hop_count)
1790{
1791 int v4, pb, len;
1792
1793 /* Make sure any buffered updates go out before this request. */
1794 flushupdates(ifp);
1795
1796 if(ifp == NULL) {
f4e14fdb
RW
1797 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
1798 struct interface *ifp_aux;
1799 FOR_ALL_INTERFACES(vrf, ifp_aux) {
ca10883e
DS
1800 if(!if_up(ifp_aux))
1801 continue;
1802 send_multihop_request(ifp_aux, prefix, plen, seqno, id, hop_count);
1803 }
1804 return;
1805 }
1806
1807 if(!if_up(ifp))
1808 return;
1809
1810 debugf(BABEL_DEBUG_COMMON,"Sending request (%d) on %s for %s.",
1811 hop_count, ifp->name, format_prefix(prefix, plen));
1812 v4 = plen >= 96 && v4mapped(prefix);
1813 pb = v4 ? ((plen - 96) + 7) / 8 : (plen + 7) / 8;
1814 len = 6 + 8 + pb;
1815
1816 start_message(ifp, MESSAGE_MH_REQUEST, len);
1817 accumulate_byte(ifp, v4 ? 1 : 2);
1818 accumulate_byte(ifp, v4 ? plen - 96 : plen);
1819 accumulate_short(ifp, seqno);
1820 accumulate_byte(ifp, hop_count);
1821 accumulate_byte(ifp, 0);
1822 accumulate_bytes(ifp, id, 8);
1823 if(prefix) {
1824 if(v4)
1825 accumulate_bytes(ifp, prefix + 12, pb);
1826 else
1827 accumulate_bytes(ifp, prefix, pb);
1828 }
1829 end_message(ifp, MESSAGE_MH_REQUEST, len);
1830}
1831
1832void
1833send_unicast_multihop_request(struct neighbour *neigh,
1834 const unsigned char *prefix, unsigned char plen,
1835 unsigned short seqno, const unsigned char *id,
1836 unsigned short hop_count)
1837{
1838 int rc, v4, pb, len;
1839
1840 /* Make sure any buffered updates go out before this request. */
1841 flushupdates(neigh->ifp);
1842
1843 debugf(BABEL_DEBUG_COMMON,"Sending multi-hop request to %s for %s (%d hops).",
1844 format_address(neigh->address),
1845 format_prefix(prefix, plen), hop_count);
1846 v4 = plen >= 96 && v4mapped(prefix);
1847 pb = v4 ? ((plen - 96) + 7) / 8 : (plen + 7) / 8;
1848 len = 6 + 8 + pb;
1849
1850 rc = start_unicast_message(neigh, MESSAGE_MH_REQUEST, len);
1851 if(rc < 0) return;
1852 accumulate_unicast_byte(neigh, v4 ? 1 : 2);
1853 accumulate_unicast_byte(neigh, v4 ? plen - 96 : plen);
1854 accumulate_unicast_short(neigh, seqno);
1855 accumulate_unicast_byte(neigh, hop_count);
1856 accumulate_unicast_byte(neigh, 0);
1857 accumulate_unicast_bytes(neigh, id, 8);
1858 if(prefix) {
1859 if(v4)
1860 accumulate_unicast_bytes(neigh, prefix + 12, pb);
1861 else
1862 accumulate_unicast_bytes(neigh, prefix, pb);
1863 }
1864 end_unicast_message(neigh, MESSAGE_MH_REQUEST, len);
1865}
1866
1867void
1868send_request_resend(struct neighbour *neigh,
1869 const unsigned char *prefix, unsigned char plen,
1870 unsigned short seqno, unsigned char *id)
1871{
1872 if(neigh)
1873 send_unicast_multihop_request(neigh, prefix, plen, seqno, id, 127);
1874 else
1875 send_multihop_request(NULL, prefix, plen, seqno, id, 127);
1876
1877 record_resend(RESEND_REQUEST, prefix, plen, seqno, id,
1878 neigh ? neigh->ifp : NULL, resend_delay);
1879}
1880
1881void
1882handle_request(struct neighbour *neigh, const unsigned char *prefix,
1883 unsigned char plen, unsigned char hop_count,
1884 unsigned short seqno, const unsigned char *id)
1885{
1886 struct xroute *xroute;
1887 struct babel_route *route;
1888 struct neighbour *successor = NULL;
1889
1890 xroute = find_xroute(prefix, plen);
1891 route = find_installed_route(prefix, plen);
1892
1893 if(xroute && (!route || xroute->metric <= kernel_metric)) {
1894 if(hop_count > 0 && memcmp(id, myid, 8) == 0) {
1895 if(seqno_compare(seqno, myseqno) > 0) {
1896 if(seqno_minus(seqno, myseqno) > 100) {
1897 /* Hopelessly out-of-date request */
1898 return;
1899 }
1900 update_myseqno();
1901 }
1902 }
1903 send_update(neigh->ifp, 1, prefix, plen);
1904 return;
1905 }
1906
1907 if(route &&
1908 (memcmp(id, route->src->id, 8) != 0 ||
1909 seqno_compare(seqno, route->seqno) <= 0)) {
1910 send_update(neigh->ifp, 1, prefix, plen);
1911 return;
1912 }
1913
1914 if(hop_count <= 1)
1915 return;
1916
1917 if(route && memcmp(id, route->src->id, 8) == 0 &&
1918 seqno_minus(seqno, route->seqno) > 100) {
1919 /* Hopelessly out-of-date */
1920 return;
1921 }
1922
1923 if(request_redundant(neigh->ifp, prefix, plen, seqno, id))
1924 return;
1925
1926 /* Let's try to forward this request. */
1927 if(route && route_metric(route) < INFINITY)
1928 successor = route->neigh;
1929
1930 if(!successor || successor == neigh) {
1931 /* We were about to forward a request to its requestor. Try to
1932 find a different neighbour to forward the request to. */
1933 struct babel_route *other_route;
1934
1935 other_route = find_best_route(prefix, plen, 0, neigh);
1936 if(other_route && route_metric(other_route) < INFINITY)
1937 successor = other_route->neigh;
1938 }
1939
1940 if(!successor || successor == neigh)
1941 /* Give up */
1942 return;
1943
1944 send_unicast_multihop_request(successor, prefix, plen, seqno, id,
1945 hop_count - 1);
1946 record_resend(RESEND_REQUEST, prefix, plen, seqno, id,
1947 neigh->ifp, 0);
1948}