]> git.proxmox.com Git - mirror_frr.git/blob - pimd/pim_tlv.c
*: Replace `sizeof something` to sizeof(something)
[mirror_frr.git] / pimd / pim_tlv.c
1 /*
2 * PIM for Quagga
3 * Copyright (C) 2008 Everton da Silva Marques
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; see the file COPYING; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #include <zebra.h>
21
22 #include "log.h"
23 #include "prefix.h"
24 #include "if.h"
25
26 #include "pimd.h"
27 #include "pim_int.h"
28 #include "pim_tlv.h"
29 #include "pim_str.h"
30 #include "pim_msg.h"
31
32 uint8_t *pim_tlv_append_uint16(uint8_t *buf, const uint8_t *buf_pastend,
33 uint16_t option_type, uint16_t option_value)
34 {
35 uint16_t option_len = 2;
36
37 if ((buf + PIM_TLV_OPTION_SIZE(option_len)) > buf_pastend)
38 return NULL;
39
40 *(uint16_t *)buf = htons(option_type);
41 buf += 2;
42 *(uint16_t *)buf = htons(option_len);
43 buf += 2;
44 *(uint16_t *)buf = htons(option_value);
45 buf += option_len;
46
47 return buf;
48 }
49
50 uint8_t *pim_tlv_append_2uint16(uint8_t *buf, const uint8_t *buf_pastend,
51 uint16_t option_type, uint16_t option_value1,
52 uint16_t option_value2)
53 {
54 uint16_t option_len = 4;
55
56 if ((buf + PIM_TLV_OPTION_SIZE(option_len)) > buf_pastend)
57 return NULL;
58
59 *(uint16_t *)buf = htons(option_type);
60 buf += 2;
61 *(uint16_t *)buf = htons(option_len);
62 buf += 2;
63 *(uint16_t *)buf = htons(option_value1);
64 buf += 2;
65 *(uint16_t *)buf = htons(option_value2);
66 buf += 2;
67
68 return buf;
69 }
70
71 uint8_t *pim_tlv_append_uint32(uint8_t *buf, const uint8_t *buf_pastend,
72 uint16_t option_type, uint32_t option_value)
73 {
74 uint16_t option_len = 4;
75
76 if ((buf + PIM_TLV_OPTION_SIZE(option_len)) > buf_pastend)
77 return NULL;
78
79 *(uint16_t *)buf = htons(option_type);
80 buf += 2;
81 *(uint16_t *)buf = htons(option_len);
82 buf += 2;
83 pim_write_uint32(buf, option_value);
84 buf += option_len;
85
86 return buf;
87 }
88
89 #define ucast_ipv4_encoding_len (2 + sizeof(struct in_addr))
90 #define ucast_ipv6_encoding_len (2 + sizeof(struct in6_addr))
91
92 /*
93 * An Encoded-Unicast address takes the following format:
94 *
95 * 0 1 2 3
96 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
97 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
98 * | Addr Family | Encoding Type | Unicast Address
99 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+...
100 *
101 * Addr Family
102 * The PIM address family of the 'Unicast Address' field of this
103 * address.
104 *
105 * Values 0-127 are as assigned by the IANA for Internet Address *
106 * Families in [7]. Values 128-250 are reserved to be assigned by
107 * the IANA for PIM-specific Address Families. Values 251 though
108 * 255 are designated for private use. As there is no assignment
109 * authority for this space, collisions should be expected.
110 *
111 * Encoding Type
112 * The type of encoding used within a specific Address Family. The
113 * value '0' is reserved for this field and represents the native
114 * encoding of the Address Family.
115 *
116 * Unicast Address
117 * The unicast address as represented by the given Address Family
118 * and Encoding Type.
119 */
120 int pim_encode_addr_ucast(uint8_t *buf, struct prefix *p)
121 {
122 switch (p->family) {
123 case AF_INET:
124 *(uint8_t *)buf =
125 PIM_MSG_ADDRESS_FAMILY_IPV4; /* notice: AF_INET !=
126 PIM_MSG_ADDRESS_FAMILY_IPV4
127 */
128 ++buf;
129 *(uint8_t *)buf = 0; /* ucast IPv4 native encoding type (RFC
130 4601: 4.9.1) */
131 ++buf;
132 memcpy(buf, &p->u.prefix4, sizeof(struct in_addr));
133 return ucast_ipv4_encoding_len;
134 case AF_INET6:
135 *(uint8_t *)buf = PIM_MSG_ADDRESS_FAMILY_IPV6;
136 ++buf;
137 *(uint8_t *)buf = 0;
138 ++buf;
139 memcpy(buf, &p->u.prefix6, sizeof(struct in6_addr));
140 return ucast_ipv6_encoding_len;
141 default:
142 return 0;
143 }
144 }
145
146 #define group_ipv4_encoding_len (4 + sizeof(struct in_addr))
147
148 /*
149 * Encoded-Group addresses take the following format:
150 *
151 * 0 1 2 3
152 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
153 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
154 * | Addr Family | Encoding Type |B| Reserved |Z| Mask Len |
155 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
156 * | Group multicast Address
157 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+...
158 *
159 * Addr Family
160 * Described above.
161 *
162 * Encoding Type
163 * Described above.
164 *
165 * [B]idirectional PIM
166 * Indicates the group range should use Bidirectional PIM [13].
167 * For PIM-SM defined in this specification, this bit MUST be zero.
168 *
169 * Reserved
170 * Transmitted as zero. Ignored upon receipt.
171 *
172 * Admin Scope [Z]one
173 * indicates the group range is an admin scope zone. This is used
174 * in the Bootstrap Router Mechanism [11] only. For all other
175 * purposes, this bit is set to zero and ignored on receipt.
176 *
177 * Mask Len
178 * The Mask length field is 8 bits. The value is the number of
179 * contiguous one bits that are left justified and used as a mask;
180 * when combined with the group address, it describes a range of
181 * groups. It is less than or equal to the address length in bits
182 * for the given Address Family and Encoding Type. If the message
183 * is sent for a single group, then the Mask length must equal the
184 * address length in bits for the given Address Family and Encoding
185 * Type (e.g., 32 for IPv4 native encoding, 128 for IPv6 native
186 * encoding).
187 *
188 * Group multicast Address
189 * Contains the group address.
190 */
191 int pim_encode_addr_group(uint8_t *buf, afi_t afi, int bidir, int scope,
192 struct in_addr group)
193 {
194 uint8_t flags = 0;
195
196 flags |= bidir << 8;
197 flags |= scope;
198
199 switch (afi) {
200 case AFI_IP:
201 *(uint8_t *)buf = PIM_MSG_ADDRESS_FAMILY_IPV4;
202 ++buf;
203 *(uint8_t *)buf = 0;
204 ++buf;
205 *(uint8_t *)buf = flags;
206 ++buf;
207 *(uint8_t *)buf = 32;
208 ++buf;
209 memcpy(buf, &group, sizeof(struct in_addr));
210 return group_ipv4_encoding_len;
211 default:
212 return 0;
213 }
214 }
215
216 uint8_t *pim_tlv_append_addrlist_ucast(uint8_t *buf, const uint8_t *buf_pastend,
217 struct list *ifconnected, int family)
218 {
219 struct listnode *node;
220 uint16_t option_len = 0;
221 uint8_t *curr;
222 size_t uel;
223
224 node = listhead(ifconnected);
225
226 /* Empty address list ? */
227 if (!node) {
228 return buf;
229 }
230
231 if (family == AF_INET)
232 uel = ucast_ipv4_encoding_len;
233 else
234 uel = ucast_ipv6_encoding_len;
235
236 /* Scan secondary address list */
237 curr = buf + 4; /* skip T and L */
238 for (; node; node = listnextnode(node)) {
239 struct connected *ifc = listgetdata(node);
240 struct prefix *p = ifc->address;
241 int l_encode;
242
243 if (!CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY))
244 continue;
245
246 if ((curr + uel) > buf_pastend)
247 return 0;
248
249 if (p->family != family)
250 continue;
251
252 l_encode = pim_encode_addr_ucast(curr, p);
253 curr += l_encode;
254 option_len += l_encode;
255 }
256
257 if (PIM_DEBUG_PIM_TRACE_DETAIL) {
258 zlog_debug(
259 "%s: number of encoded secondary unicast IPv4 addresses: %zu",
260 __func__, option_len / uel);
261 }
262
263 if (option_len < 1) {
264 /* Empty secondary unicast IPv4 address list */
265 return buf;
266 }
267
268 /*
269 * Write T and L
270 */
271 *(uint16_t *)buf = htons(PIM_MSG_OPTION_TYPE_ADDRESS_LIST);
272 *(uint16_t *)(buf + 2) = htons(option_len);
273
274 return curr;
275 }
276
277 static int check_tlv_length(const char *label, const char *tlv_name,
278 const char *ifname, struct in_addr src_addr,
279 int correct_len, int option_len)
280 {
281 if (option_len != correct_len) {
282 char src_str[INET_ADDRSTRLEN];
283 pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
284 zlog_warn(
285 "%s: PIM hello %s TLV with incorrect value size=%d correct=%d from %s on interface %s",
286 label, tlv_name, option_len, correct_len, src_str,
287 ifname);
288 return -1;
289 }
290
291 return 0;
292 }
293
294 static void check_tlv_redefinition_uint16(
295 const char *label, const char *tlv_name, const char *ifname,
296 struct in_addr src_addr, pim_hello_options options,
297 pim_hello_options opt_mask, uint16_t new, uint16_t old)
298 {
299 if (PIM_OPTION_IS_SET(options, opt_mask)) {
300 char src_str[INET_ADDRSTRLEN];
301 pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
302 zlog_warn(
303 "%s: PIM hello TLV redefined %s=%u old=%u from %s on interface %s",
304 label, tlv_name, new, old, src_str, ifname);
305 }
306 }
307
308 static void check_tlv_redefinition_uint32(
309 const char *label, const char *tlv_name, const char *ifname,
310 struct in_addr src_addr, pim_hello_options options,
311 pim_hello_options opt_mask, uint32_t new, uint32_t old)
312 {
313 if (PIM_OPTION_IS_SET(options, opt_mask)) {
314 char src_str[INET_ADDRSTRLEN];
315 pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
316 zlog_warn(
317 "%s: PIM hello TLV redefined %s=%u old=%u from %s on interface %s",
318 label, tlv_name, new, old, src_str, ifname);
319 }
320 }
321
322 static void check_tlv_redefinition_uint32_hex(
323 const char *label, const char *tlv_name, const char *ifname,
324 struct in_addr src_addr, pim_hello_options options,
325 pim_hello_options opt_mask, uint32_t new, uint32_t old)
326 {
327 if (PIM_OPTION_IS_SET(options, opt_mask)) {
328 char src_str[INET_ADDRSTRLEN];
329 pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
330 zlog_warn(
331 "%s: PIM hello TLV redefined %s=%08x old=%08x from %s on interface %s",
332 label, tlv_name, new, old, src_str, ifname);
333 }
334 }
335
336 int pim_tlv_parse_holdtime(const char *ifname, struct in_addr src_addr,
337 pim_hello_options *hello_options,
338 uint16_t *hello_option_holdtime, uint16_t option_len,
339 const uint8_t *tlv_curr)
340 {
341 const char *label = "holdtime";
342
343 if (check_tlv_length(__func__, label, ifname, src_addr,
344 sizeof(uint16_t), option_len)) {
345 return -1;
346 }
347
348 check_tlv_redefinition_uint16(__func__, label, ifname, src_addr,
349 *hello_options, PIM_OPTION_MASK_HOLDTIME,
350 PIM_TLV_GET_HOLDTIME(tlv_curr),
351 *hello_option_holdtime);
352
353 PIM_OPTION_SET(*hello_options, PIM_OPTION_MASK_HOLDTIME);
354
355 *hello_option_holdtime = PIM_TLV_GET_HOLDTIME(tlv_curr);
356
357 return 0;
358 }
359
360 int pim_tlv_parse_lan_prune_delay(const char *ifname, struct in_addr src_addr,
361 pim_hello_options *hello_options,
362 uint16_t *hello_option_propagation_delay,
363 uint16_t *hello_option_override_interval,
364 uint16_t option_len, const uint8_t *tlv_curr)
365 {
366 if (check_tlv_length(__func__, "lan_prune_delay", ifname, src_addr,
367 sizeof(uint32_t), option_len)) {
368 return -1;
369 }
370
371 check_tlv_redefinition_uint16(__func__, "propagation_delay", ifname,
372 src_addr, *hello_options,
373 PIM_OPTION_MASK_LAN_PRUNE_DELAY,
374 PIM_TLV_GET_PROPAGATION_DELAY(tlv_curr),
375 *hello_option_propagation_delay);
376
377 PIM_OPTION_SET(*hello_options, PIM_OPTION_MASK_LAN_PRUNE_DELAY);
378
379 *hello_option_propagation_delay =
380 PIM_TLV_GET_PROPAGATION_DELAY(tlv_curr);
381 if (PIM_TLV_GET_CAN_DISABLE_JOIN_SUPPRESSION(tlv_curr)) {
382 PIM_OPTION_SET(*hello_options,
383 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION);
384 } else {
385 PIM_OPTION_UNSET(*hello_options,
386 PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION);
387 }
388 ++tlv_curr;
389 ++tlv_curr;
390 *hello_option_override_interval =
391 PIM_TLV_GET_OVERRIDE_INTERVAL(tlv_curr);
392
393 return 0;
394 }
395
396 int pim_tlv_parse_dr_priority(const char *ifname, struct in_addr src_addr,
397 pim_hello_options *hello_options,
398 uint32_t *hello_option_dr_priority,
399 uint16_t option_len, const uint8_t *tlv_curr)
400 {
401 const char *label = "dr_priority";
402
403 if (check_tlv_length(__func__, label, ifname, src_addr,
404 sizeof(uint32_t), option_len)) {
405 return -1;
406 }
407
408 check_tlv_redefinition_uint32(
409 __func__, label, ifname, src_addr, *hello_options,
410 PIM_OPTION_MASK_DR_PRIORITY, PIM_TLV_GET_DR_PRIORITY(tlv_curr),
411 *hello_option_dr_priority);
412
413 PIM_OPTION_SET(*hello_options, PIM_OPTION_MASK_DR_PRIORITY);
414
415 *hello_option_dr_priority = PIM_TLV_GET_DR_PRIORITY(tlv_curr);
416
417 return 0;
418 }
419
420 int pim_tlv_parse_generation_id(const char *ifname, struct in_addr src_addr,
421 pim_hello_options *hello_options,
422 uint32_t *hello_option_generation_id,
423 uint16_t option_len, const uint8_t *tlv_curr)
424 {
425 const char *label = "generation_id";
426
427 if (check_tlv_length(__func__, label, ifname, src_addr,
428 sizeof(uint32_t), option_len)) {
429 return -1;
430 }
431
432 check_tlv_redefinition_uint32_hex(__func__, label, ifname, src_addr,
433 *hello_options,
434 PIM_OPTION_MASK_GENERATION_ID,
435 PIM_TLV_GET_GENERATION_ID(tlv_curr),
436 *hello_option_generation_id);
437
438 PIM_OPTION_SET(*hello_options, PIM_OPTION_MASK_GENERATION_ID);
439
440 *hello_option_generation_id = PIM_TLV_GET_GENERATION_ID(tlv_curr);
441
442 return 0;
443 }
444
445 int pim_parse_addr_ucast(struct prefix *p, const uint8_t *buf, int buf_size)
446 {
447 const int ucast_encoding_min_len = 3; /* 1 family + 1 type + 1 addr */
448 const uint8_t *addr;
449 const uint8_t *pastend;
450 int family;
451 int type;
452
453 if (buf_size < ucast_encoding_min_len) {
454 zlog_warn(
455 "%s: unicast address encoding overflow: left=%d needed=%d",
456 __func__, buf_size, ucast_encoding_min_len);
457 return -1;
458 }
459
460 addr = buf;
461 pastend = buf + buf_size;
462
463 family = *addr++;
464 type = *addr++;
465
466 if (type) {
467 zlog_warn("%s: unknown unicast address encoding type=%d",
468 __func__, type);
469 return -2;
470 }
471
472 switch (family) {
473 case PIM_MSG_ADDRESS_FAMILY_IPV4:
474 if ((addr + sizeof(struct in_addr)) > pastend) {
475 zlog_warn(
476 "%s: IPv4 unicast address overflow: left=%zd needed=%zu",
477 __func__, pastend - addr,
478 sizeof(struct in_addr));
479 return -3;
480 }
481
482 p->family = AF_INET; /* notice: AF_INET !=
483 PIM_MSG_ADDRESS_FAMILY_IPV4 */
484 memcpy(&p->u.prefix4, addr, sizeof(struct in_addr));
485 p->prefixlen = IPV4_MAX_PREFIXLEN;
486 addr += sizeof(struct in_addr);
487
488 break;
489 case PIM_MSG_ADDRESS_FAMILY_IPV6:
490 if ((addr + sizeof(struct in6_addr)) > pastend) {
491 zlog_warn(
492 "%s: IPv6 unicast address overflow: left=%zd needed %zu",
493 __func__, pastend - addr,
494 sizeof(struct in6_addr));
495 return -3;
496 }
497
498 p->family = AF_INET6;
499 p->prefixlen = IPV6_MAX_PREFIXLEN;
500 memcpy(&p->u.prefix6, addr, sizeof(struct in6_addr));
501 addr += sizeof(struct in6_addr);
502
503 break;
504 default: {
505 zlog_warn("%s: unknown unicast address encoding family=%d from",
506 __func__, family);
507 return -4;
508 }
509 }
510
511 return addr - buf;
512 }
513
514 int pim_parse_addr_group(struct prefix_sg *sg, const uint8_t *buf, int buf_size)
515 {
516 const int grp_encoding_min_len =
517 4; /* 1 family + 1 type + 1 reserved + 1 addr */
518 const uint8_t *addr;
519 const uint8_t *pastend;
520 int family;
521 int type;
522 int mask_len;
523
524 if (buf_size < grp_encoding_min_len) {
525 zlog_warn(
526 "%s: group address encoding overflow: left=%d needed=%d",
527 __func__, buf_size, grp_encoding_min_len);
528 return -1;
529 }
530
531 addr = buf;
532 pastend = buf + buf_size;
533
534 family = *addr++;
535 type = *addr++;
536 //++addr;
537 ++addr; /* skip b_reserved_z fields */
538 mask_len = *addr++;
539
540 switch (family) {
541 case PIM_MSG_ADDRESS_FAMILY_IPV4:
542 if (type) {
543 zlog_warn(
544 "%s: unknown group address encoding type=%d from",
545 __func__, type);
546 return -2;
547 }
548
549 if ((addr + sizeof(struct in_addr)) > pastend) {
550 zlog_warn(
551 "%s: IPv4 group address overflow: left=%zd needed=%zu from",
552 __func__, pastend - addr,
553 sizeof(struct in_addr));
554 return -3;
555 }
556
557 memcpy(&sg->grp.s_addr, addr, sizeof(struct in_addr));
558
559 addr += sizeof(struct in_addr);
560
561 break;
562 default: {
563 zlog_warn(
564 "%s: unknown group address encoding family=%d mask_len=%d from",
565 __func__, family, mask_len);
566 return -4;
567 }
568 }
569
570 return addr - buf;
571 }
572
573 int pim_parse_addr_source(struct prefix_sg *sg, uint8_t *flags,
574 const uint8_t *buf, int buf_size)
575 {
576 const int src_encoding_min_len =
577 4; /* 1 family + 1 type + 1 reserved + 1 addr */
578 const uint8_t *addr;
579 const uint8_t *pastend;
580 int family;
581 int type;
582 int mask_len;
583
584 if (buf_size < src_encoding_min_len) {
585 zlog_warn(
586 "%s: source address encoding overflow: left=%d needed=%d",
587 __func__, buf_size, src_encoding_min_len);
588 return -1;
589 }
590
591 addr = buf;
592 pastend = buf + buf_size;
593
594 family = *addr++;
595 type = *addr++;
596 *flags = *addr++;
597 mask_len = *addr++;
598
599 if (type) {
600 zlog_warn(
601 "%s: unknown source address encoding type=%d: %02x%02x%02x%02x",
602 __func__, type, buf[0], buf[1], buf[2], buf[3]);
603 return -2;
604 }
605
606 switch (family) {
607 case PIM_MSG_ADDRESS_FAMILY_IPV4:
608 if ((addr + sizeof(struct in_addr)) > pastend) {
609 zlog_warn(
610 "%s: IPv4 source address overflow: left=%zd needed=%zu",
611 __func__, pastend - addr,
612 sizeof(struct in_addr));
613 return -3;
614 }
615
616 memcpy(&sg->src, addr, sizeof(struct in_addr));
617
618 /*
619 RFC 4601: 4.9.1 Encoded Source and Group Address Formats
620
621 Encoded-Source Address
622
623 The mask length MUST be equal to the mask length in bits for
624 the given Address Family and Encoding Type (32 for IPv4
625 native
626 and 128 for IPv6 native). A router SHOULD ignore any
627 messages
628 received with any other mask length.
629 */
630 if (mask_len != 32) {
631 zlog_warn("%s: IPv4 bad source address mask: %d",
632 __func__, mask_len);
633 return -4;
634 }
635
636 addr += sizeof(struct in_addr);
637
638 break;
639 default: {
640 zlog_warn(
641 "%s: unknown source address encoding family=%d: %02x%02x%02x%02x",
642 __func__, family, buf[0], buf[1], buf[2], buf[3]);
643 return -5;
644 }
645 }
646
647 return addr - buf;
648 }
649
650 #define FREE_ADDR_LIST(hello_option_addr_list) \
651 { \
652 if (hello_option_addr_list) { \
653 list_delete(&hello_option_addr_list); \
654 hello_option_addr_list = 0; \
655 } \
656 }
657
658 int pim_tlv_parse_addr_list(const char *ifname, struct in_addr src_addr,
659 pim_hello_options *hello_options,
660 struct list **hello_option_addr_list,
661 uint16_t option_len, const uint8_t *tlv_curr)
662 {
663 const uint8_t *addr;
664 const uint8_t *pastend;
665
666 zassert(hello_option_addr_list);
667
668 /*
669 Scan addr list
670 */
671 addr = tlv_curr;
672 pastend = tlv_curr + option_len;
673 while (addr < pastend) {
674 struct prefix tmp;
675 int addr_offset;
676
677 /*
678 Parse ucast addr
679 */
680 addr_offset = pim_parse_addr_ucast(&tmp, addr, pastend - addr);
681 if (addr_offset < 1) {
682 char src_str[INET_ADDRSTRLEN];
683 pim_inet4_dump("<src?>", src_addr, src_str,
684 sizeof(src_str));
685 zlog_warn(
686 "%s: pim_parse_addr_ucast() failure: from %s on %s",
687 __func__, src_str, ifname);
688 FREE_ADDR_LIST(*hello_option_addr_list);
689 return -1;
690 }
691 addr += addr_offset;
692
693 /*
694 Debug
695 */
696 if (PIM_DEBUG_PIM_TRACE) {
697 switch (tmp.family) {
698 case AF_INET: {
699 char addr_str[INET_ADDRSTRLEN];
700 char src_str[INET_ADDRSTRLEN];
701 pim_inet4_dump("<addr?>", tmp.u.prefix4,
702 addr_str, sizeof(addr_str));
703 pim_inet4_dump("<src?>", src_addr, src_str,
704 sizeof(src_str));
705 zlog_debug(
706 "%s: PIM hello TLV option: list_old_size=%d IPv4 address %s from %s on %s",
707 __func__,
708 *hello_option_addr_list
709 ? ((int)listcount(
710 *hello_option_addr_list))
711 : -1,
712 addr_str, src_str, ifname);
713 } break;
714 case AF_INET6:
715 break;
716 default: {
717 char src_str[INET_ADDRSTRLEN];
718 pim_inet4_dump("<src?>", src_addr, src_str,
719 sizeof(src_str));
720 zlog_debug(
721 "%s: PIM hello TLV option: list_old_size=%d UNKNOWN address family from %s on %s",
722 __func__,
723 *hello_option_addr_list
724 ? ((int)listcount(
725 *hello_option_addr_list))
726 : -1,
727 src_str, ifname);
728 }
729 }
730 }
731
732 /*
733 Exclude neighbor's primary address if incorrectly included in
734 the secondary address list
735 */
736 if (tmp.family == AF_INET) {
737 if (tmp.u.prefix4.s_addr == src_addr.s_addr) {
738 char src_str[INET_ADDRSTRLEN];
739 pim_inet4_dump("<src?>", src_addr, src_str,
740 sizeof(src_str));
741 zlog_warn(
742 "%s: ignoring primary address in secondary list from %s on %s",
743 __func__, src_str, ifname);
744 continue;
745 }
746 }
747
748 /*
749 Allocate list if needed
750 */
751 if (!*hello_option_addr_list) {
752 *hello_option_addr_list = list_new();
753 (*hello_option_addr_list)->del = prefix_free_lists;
754 }
755
756 /*
757 Attach addr to list
758 */
759 {
760 struct prefix *p;
761 p = prefix_new();
762 prefix_copy(p, &tmp);
763 listnode_add(*hello_option_addr_list, p);
764 }
765
766 } /* while (addr < pastend) */
767
768 /*
769 Mark hello option
770 */
771 PIM_OPTION_SET(*hello_options, PIM_OPTION_MASK_ADDRESS_LIST);
772
773 return 0;
774 }