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