summaryrefslogtreecommitdiff
path: root/pimd/pim_msg.c
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2017-02-14 21:32:16 -0500
committerDonald Sharp <sharpd@cumulusnetworks.com>2017-03-02 08:13:03 -0500
commit982bff8972e0b387a1c3e466d584d2880175a5e3 (patch)
treef1fe009e73fd377006bbebb2ff7b279c6ba0d7ff /pimd/pim_msg.c
parent338988d9cd38a8314647ec8f769a9eb8462564d4 (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.c175
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;
}