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