mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-29 07:36:46 +00:00
pim6d: prepare IPv6 address encoding functions
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
This commit is contained in:
parent
883052c6f9
commit
16763d77a3
@ -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)
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user