diff options
| author | Donald Sharp <sharpd@cumulusnetworks.com> | 2017-02-14 21:32:16 -0500 |
|---|---|---|
| committer | Donald Sharp <sharpd@cumulusnetworks.com> | 2017-03-02 08:13:03 -0500 |
| commit | 982bff8972e0b387a1c3e466d584d2880175a5e3 (patch) | |
| tree | f1fe009e73fd377006bbebb2ff7b279c6ba0d7ff /pimd/pim_msg.c | |
| parent | 338988d9cd38a8314647ec8f769a9eb8462564d4 (diff) | |
pimd: Join/Prune Aggregation
Add the ability for PIM to send Join/Prunes as an
aggregated message instead of individual messages
for each S,G.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Diffstat (limited to 'pimd/pim_msg.c')
| -rw-r--r-- | pimd/pim_msg.c | 175 |
1 files changed, 50 insertions, 125 deletions
diff --git a/pimd/pim_msg.c b/pimd/pim_msg.c index e6b13f3121..4018fd639e 100644 --- a/pimd/pim_msg.c +++ b/pimd/pim_msg.c @@ -36,6 +36,7 @@ #include "pim_rp.h" #include "pim_rpf.h" #include "pim_register.h" +#include "pim_jp_agg.h" void pim_msg_build_header(uint8_t *pim_msg, size_t pim_msg_size, uint8_t pim_msg_type) { @@ -93,36 +94,62 @@ pim_msg_addr_encode_ipv4_source(uint8_t *buf, return buf + PIM_ENCODED_IPV4_SOURCE_SIZE; } -static size_t -pim_msg_build_jp_groups (struct pim_jp_groups *grp, struct pim_upstream *up, int is_join) +/* + * For the given 'struct pim_jp_sources' list + * determine the size_t it would take up. + */ +size_t +pim_msg_get_jp_group_size (struct list *sources) +{ + size_t size = 0; + + size += sizeof (struct pim_encoded_group_ipv4); + size += 4; // Joined sources (2) + Pruned Sources (2) + + size += sizeof (struct pim_encoded_source_ipv4) * sources->count; + + return size; +} + +size_t +pim_msg_build_jp_groups (struct pim_jp_groups *grp, struct pim_jp_agg_group *sgs) { + struct listnode *node, *nnode; + struct pim_jp_sources *source; struct in_addr stosend; uint8_t bits; + size_t size = pim_msg_get_jp_group_size (sgs->sources); + uint8_t tgroups = 0; - /* number of joined/pruned sources */ - grp->joins = htons(is_join ? 1 : 0); - grp->prunes = htons(is_join ? 0 : 1); + memset (grp, 0, size); + pim_msg_addr_encode_ipv4_group ((uint8_t *)&grp->g, sgs->group); - if (up->sg.src.s_addr == INADDR_ANY) - { - struct pim_rpf *rpf = pim_rp_g (up->sg.grp); - bits = PIM_ENCODE_SPARSE_BIT | PIM_ENCODE_WC_BIT | PIM_ENCODE_RPT_BIT; - stosend = rpf->rpf_addr.u.prefix4; - } - else + for (ALL_LIST_ELEMENTS(sgs->sources, node, nnode, source)) { - bits = PIM_ENCODE_SPARSE_BIT; - stosend = up->sg.src; - } + /* number of joined/pruned sources */ + if (source->is_join) + grp->joins++; + else + grp->prunes++; - if (!pim_msg_addr_encode_ipv4_source ((uint8_t *)&grp->s[0], stosend, bits)) { - char source_str[INET_ADDRSTRLEN]; - pim_inet4_dump("<src?>", up->sg.src, source_str, sizeof(source_str)); - zlog_warn("%s: failure encoding source address %s", - __PRETTY_FUNCTION__, source_str); - return 0; - } + if (source->up->sg.src.s_addr == INADDR_ANY) + { + struct pim_rpf *rpf = pim_rp_g (source->up->sg.grp); + bits = PIM_ENCODE_SPARSE_BIT | PIM_ENCODE_WC_BIT | PIM_ENCODE_RPT_BIT; + stosend = rpf->rpf_addr.u.prefix4; + } + else + { + bits = PIM_ENCODE_SPARSE_BIT; + stosend = source->up->sg.src; + } + + pim_msg_addr_encode_ipv4_source ((uint8_t *)&grp->s[tgroups], stosend, bits); + tgroups++; + } + grp->joins = htons(grp->joins); + grp->prunes = htons(grp->prunes); /* * This is not implemented correctly at this point in time * Make it stop. @@ -190,107 +217,5 @@ pim_msg_build_jp_groups (struct pim_jp_groups *grp, struct pim_upstream *up, int } #endif - return sizeof (*grp); -} - -/* - * J/P Message Format - * - * While the RFC clearly states that this is 32 bits wide, it - * is cheating. These fields: - * Encoded-Unicast format (6 bytes MIN) - * Encoded-Group format (8 bytes MIN) - * Encoded-Source format (8 bytes MIN) - * are *not* 32 bits wide. - * - * Nor does the RFC explicitly call out the size for: - * Reserved (1 byte) - * Num Groups (1 byte) - * Holdtime (2 bytes) - * Number of Joined Sources (2 bytes) - * Number of Pruned Sources (2 bytes) - * - * This leads to a missleading representation from casual - * reading and making assumptions. Be careful! - * - * 0 1 2 3 - * 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 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * |PIM Ver| Type | Reserved | Checksum | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Upstream Neighbor Address (Encoded-Unicast format) | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Reserved | Num groups | Holdtime | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Multicast Group Address 1 (Encoded-Group format) | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Number of Joined Sources | Number of Pruned Sources | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Joined Source Address 1 (Encoded-Source format) | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | . | - * | . | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Joined Source Address n (Encoded-Source format) | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Pruned Source Address 1 (Encoded-Source format) | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | . | - * | . | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Pruned Source Address n (Encoded-Source format) | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Multicast Group Address m (Encoded-Group format) | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Number of Joined Sources | Number of Pruned Sources | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Joined Source Address 1 (Encoded-Source format) | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | . | - * | . | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Joined Source Address n (Encoded-Source format) | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Pruned Source Address 1 (Encoded-Source format) | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | . | - * | . | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Pruned Source Address n (Encoded-Source format) | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - */ -int -pim_msg_join_prune_encode (uint8_t *buf, size_t buf_size, int is_join, - struct pim_upstream *up, - struct in_addr upstream, int holdtime) -{ - struct pim_jp *msg = (struct pim_jp *)buf; - - assert(buf_size > sizeof (struct pim_jp)); - - if (!pim_msg_addr_encode_ipv4_ucast ((uint8_t *)&msg->addr, upstream)) { - char dst_str[INET_ADDRSTRLEN]; - pim_inet4_dump("<dst?>", upstream, dst_str, sizeof(dst_str)); - zlog_warn("%s: failure encoding destination address %s", - __PRETTY_FUNCTION__, dst_str); - return -3; - } - - msg->reserved = 0; - msg->num_groups = 1; - msg->holdtime = htons(holdtime); - - if (!pim_msg_addr_encode_ipv4_group ((uint8_t *)&msg->groups[0].g, up->sg.grp)) { - char group_str[INET_ADDRSTRLEN]; - pim_inet4_dump("<grp?>", up->sg.grp, group_str, sizeof(group_str)); - zlog_warn("%s: failure encoding group address %s", - __PRETTY_FUNCTION__, group_str); - return -5; - } - - pim_msg_build_jp_groups (&msg->groups[0], up, is_join); - - pim_msg_build_header (buf, sizeof (struct pim_jp), PIM_MSG_TYPE_JOIN_PRUNE); - - return sizeof (struct pim_jp); + return size; } |
