From: David Lamparter Date: Fri, 14 Jan 2022 13:57:21 +0000 (+0100) Subject: pim6d: prepare IPv6 address encoding functions X-Git-Tag: pim6-testing-20220430~322^2~12 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=16763d77a39ae0cd84e6fcf4b3f6a05f10d94c38;p=matthieu%2Ffrr.git pim6d: prepare IPv6 address encoding functions Signed-off-by: David Lamparter --- diff --git a/pimd/pim_join.c b/pimd/pim_join.c index fa2d8d462b..22890dc372 100644 --- a/pimd/pim_join.c +++ b/pimd/pim_join.c @@ -516,7 +516,7 @@ int pim_joinprune_send(struct pim_rpf *rpf, struct list *groups) grp = &msg->groups[0]; curr_ptr = (uint8_t *)grp; packet_size = sizeof(struct pim_msg_header); - packet_size += sizeof(struct pim_encoded_ipv4_unicast); + packet_size += sizeof(pim_encoded_unicast); packet_size += 4; // reserved (1) + groups (1) + holdtime (2) @@ -564,7 +564,7 @@ int pim_joinprune_send(struct pim_rpf *rpf, struct list *groups) grp = &msg->groups[0]; curr_ptr = (uint8_t *)grp; packet_size = sizeof(struct pim_msg_header); - packet_size += sizeof(struct pim_encoded_ipv4_unicast); + packet_size += sizeof(pim_encoded_unicast); packet_size += 4; // reserved (1) + groups (1) + holdtime (2) diff --git a/pimd/pim_msg.c b/pimd/pim_msg.c index c493ded0c6..e25cf11549 100644 --- a/pimd/pim_msg.c +++ b/pimd/pim_msg.c @@ -97,6 +97,68 @@ uint8_t *pim_msg_addr_encode_ipv4_source(uint8_t *buf, struct in_addr addr, 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. @@ -109,10 +171,10 @@ size_t pim_msg_get_jp_group_size(struct list *sources) 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) { @@ -137,8 +199,7 @@ size_t pim_msg_get_jp_group_size(struct list *sources) 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) @@ -156,8 +217,7 @@ size_t pim_msg_get_jp_group_size(struct list *sources) * 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) @@ -179,12 +239,12 @@ size_t pim_msg_build_jp_groups(struct pim_jp_groups *grp, 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 */ @@ -198,7 +258,7 @@ size_t pim_msg_build_jp_groups(struct pim_jp_groups *grp, 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; @@ -207,8 +267,8 @@ size_t pim_msg_build_jp_groups(struct pim_jp_groups *grp, 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++; } @@ -218,11 +278,11 @@ size_t pim_msg_build_jp_groups(struct pim_jp_groups *grp, 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); diff --git a/pimd/pim_msg.h b/pimd/pim_msg.h index 2d69a4b03a..522e94504a 100644 --- a/pimd/pim_msg.h +++ b/pimd/pim_msg.h @@ -75,6 +75,12 @@ struct pim_encoded_ipv4_unicast { 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 @@ -103,6 +109,23 @@ struct pim_encoded_group_ipv4 { 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 @@ -122,16 +145,36 @@ struct pim_encoded_source_ipv4 { 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; @@ -149,6 +192,14 @@ uint8_t *pim_msg_addr_encode_ipv4_group(uint8_t *buf, struct in_addr addr); 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,