return buf + PIM_ENCODED_IPV4_SOURCE_SIZE;
}
+uint8_t *pim_msg_addr_encode_ipv6_source(uint8_t *buf, struct in6_addr addr,
+ uint8_t bits)
+{
+ buf[0] = PIM_MSG_ADDRESS_FAMILY_IPV6; /* addr family */
+ buf[1] = '\0'; /* native encoding */
+ buf[2] = bits;
+ buf[3] = 128; /* mask len */
+ buf += 4;
+
+ memcpy(buf, &addr, sizeof(addr));
+ buf += sizeof(addr);
+
+ return buf;
+}
+
+uint8_t *pim_msg_addr_encode_ipv6_ucast(uint8_t *buf, struct in6_addr addr)
+{
+ buf[0] = PIM_MSG_ADDRESS_FAMILY_IPV6; /* addr family */
+ buf[1] = '\0'; /* native encoding */
+ buf += 2;
+
+ memcpy(buf, &addr, sizeof(addr));
+ buf += sizeof(addr);
+
+ return buf;
+}
+
+uint8_t *pim_msg_addr_encode_ipv6_group(uint8_t *buf, struct in6_addr addr)
+{
+ buf[0] = PIM_MSG_ADDRESS_FAMILY_IPV6; /* addr family */
+ buf[1] = '\0'; /* native encoding */
+ buf[2] = '\0'; /* reserved */
+ buf[3] = 128; /* mask len */
+ buf += 4;
+
+ memcpy(buf, &addr, sizeof(addr));
+ buf += sizeof(addr);
+
+ return buf;
+}
+
+#if PIM_IPV == 4 || !defined(PIM_V6_TEMP_BREAK)
+#define pim_msg_addr_encode(what) pim_msg_addr_encode_ipv4_##what
+#else
+#define pim_msg_addr_encode(what) pim_msg_addr_encode_ipv6_##what
+#endif
+
+uint8_t *pim_msg_addr_encode_ucast(uint8_t *buf, pim_addr addr)
+{
+ return pim_msg_addr_encode(ucast)(buf, addr);
+}
+
+uint8_t *pim_msg_addr_encode_group(uint8_t *buf, pim_addr addr)
+{
+ return pim_msg_addr_encode(group)(buf, addr);
+}
+
+uint8_t *pim_msg_addr_encode_source(uint8_t *buf, pim_addr addr, uint8_t bits)
+{
+ return pim_msg_addr_encode(source)(buf, addr, bits);
+}
+
/*
* For the given 'struct pim_jp_sources' list
* determine the size_t it would take up.
if (!sources)
return 0;
- size += sizeof(struct pim_encoded_group_ipv4);
+ size += sizeof(pim_encoded_group);
size += 4; // Joined sources (2) + Pruned Sources (2)
- size += sizeof(struct pim_encoded_source_ipv4) * sources->count;
+ size += sizeof(pim_encoded_source) * sources->count;
js = listgetdata(listhead(sources));
if (js && pim_addr_is_any(js->up->sg.src) && js->is_join) {
if (child->rpf.source_nexthop.interface &&
!pim_rpf_is_same(&up->rpf,
&child->rpf)) {
- size += sizeof(
- struct pim_encoded_source_ipv4);
+ size += sizeof(pim_encoded_source);
PIM_UPSTREAM_FLAG_SET_SEND_SG_RPT_PRUNE(
child->flags);
if (PIM_DEBUG_PIM_PACKETS)
* but it's inherited OIL is empty. So just
* prune it off.
*/
- size += sizeof(
- struct pim_encoded_source_ipv4);
+ size += sizeof(pim_encoded_source);
PIM_UPSTREAM_FLAG_SET_SEND_SG_RPT_PRUNE(
child->flags);
if (PIM_DEBUG_PIM_PACKETS)
struct listnode *node, *nnode;
struct pim_jp_sources *source;
struct pim_upstream *up = NULL;
- struct in_addr stosend;
+ pim_addr stosend;
uint8_t bits;
uint8_t tgroups = 0;
memset(grp, 0, size);
- pim_msg_addr_encode_ipv4_group((uint8_t *)&grp->g, sgs->group);
+ pim_msg_addr_encode_group((uint8_t *)&grp->g, sgs->group);
for (ALL_LIST_ELEMENTS(sgs->sources, node, nnode, source)) {
/* number of joined/pruned sources */
struct pim_rpf *rpf = pim_rp_g(pim, source->up->sg.grp);
bits = PIM_ENCODE_SPARSE_BIT | PIM_ENCODE_WC_BIT
| PIM_ENCODE_RPT_BIT;
- stosend = rpf->rpf_addr.u.prefix4;
+ stosend = pim_addr_from_prefix(&rpf->rpf_addr);
/* Only Send SGRpt in case of *,G Join */
if (source->is_join)
up = source->up;
stosend = source->up->sg.src;
}
- pim_msg_addr_encode_ipv4_source((uint8_t *)&grp->s[tgroups],
- stosend, bits);
+ pim_msg_addr_encode_source((uint8_t *)&grp->s[tgroups], stosend,
+ bits);
tgroups++;
}
for (ALL_LIST_ELEMENTS(up->sources, node, nnode, child)) {
if (PIM_UPSTREAM_FLAG_TEST_SEND_SG_RPT_PRUNE(
child->flags)) {
- pim_msg_addr_encode_ipv4_source(
+ pim_msg_addr_encode_source(
(uint8_t *)&grp->s[tgroups],
child->sg.src,
- PIM_ENCODE_SPARSE_BIT
- | PIM_ENCODE_RPT_BIT);
+ PIM_ENCODE_SPARSE_BIT |
+ PIM_ENCODE_RPT_BIT);
tgroups++;
PIM_UPSTREAM_FLAG_UNSET_SEND_SG_RPT_PRUNE(
child->flags);
struct in_addr addr;
} __attribute__((packed));
+struct pim_encoded_ipv6_unicast {
+ uint8_t family;
+ uint8_t reserved;
+ struct in6_addr addr;
+} __attribute__((packed));
+
/*
* Encoded Group format. RFC 4601 Sec 4.9.1
* 0 1 2 3
struct in_addr addr;
} __attribute__((packed));
+struct pim_encoded_group_ipv6 {
+ uint8_t family;
+ uint8_t ne;
+#if (BYTE_ORDER == LITTLE_ENDIAN)
+ uint8_t sz : 1; /* scope zone bit */
+ uint8_t reserved : 6; /* Reserved */
+ uint8_t bidir : 1; /* Bidir bit */
+#elif (BYTE_ORDER == BIG_ENDIAN)
+ uint8_t bidir : 1; /* Bidir bit */
+ uint8_t reserved : 6; /* Reserved */
+ uint8_t sz : 1; /* scope zone bit */
+#else
+#error "Please set byte order"
+#endif
+ uint8_t mask;
+ struct in6_addr addr;
+} __attribute__((packed));
/*
* Encoded Source format. RFC 4601 Sec 4.9.1
struct in_addr addr;
} __attribute__((packed));
+struct pim_encoded_source_ipv6 {
+ uint8_t family;
+ uint8_t ne;
+ uint8_t bits;
+ uint8_t mask;
+ struct in6_addr addr;
+} __attribute__((packed));
+
+/* clang-format off */
+#if PIM_IPV == 4
+typedef struct pim_encoded_ipv4_unicast pim_encoded_unicast;
+typedef struct pim_encoded_group_ipv4 pim_encoded_group;
+typedef struct pim_encoded_source_ipv4 pim_encoded_source;
+#else
+typedef struct pim_encoded_ipv6_unicast pim_encoded_unicast;
+typedef struct pim_encoded_group_ipv6 pim_encoded_group;
+typedef struct pim_encoded_source_ipv6 pim_encoded_source;
+#endif
+/* clang-format on */
+
struct pim_jp_groups {
- struct pim_encoded_group_ipv4 g;
+ pim_encoded_group g;
uint16_t joins;
uint16_t prunes;
- struct pim_encoded_source_ipv4 s[1];
+ pim_encoded_source s[1];
} __attribute__((packed));
struct pim_jp {
struct pim_msg_header header;
- struct pim_encoded_ipv4_unicast addr;
+ pim_encoded_unicast addr;
uint8_t reserved;
uint8_t num_groups;
uint16_t holdtime;
uint8_t *pim_msg_addr_encode_ipv4_source(uint8_t *buf, struct in_addr addr,
uint8_t bits);
+uint8_t *pim_msg_addr_encode_ipv6_ucast(uint8_t *buf, struct in6_addr addr);
+uint8_t *pim_msg_addr_encode_ipv6_group(uint8_t *buf, struct in6_addr addr);
+uint8_t *pim_msg_addr_encode_ipv6_source(uint8_t *buf, struct in6_addr addr,
+ uint8_t bits);
+
+uint8_t *pim_msg_addr_encode_ucast(uint8_t *buf, pim_addr addr);
+uint8_t *pim_msg_addr_encode_group(uint8_t *buf, pim_addr addr);
+uint8_t *pim_msg_addr_encode_source(uint8_t *buf, pim_addr addr, uint8_t bits);
size_t pim_msg_get_jp_group_size(struct list *sources);
size_t pim_msg_build_jp_groups(struct pim_jp_groups *grp,