]> git.puffer.fish Git - matthieu/frr.git/commitdiff
pim6d: prepare IPv6 address encoding functions
authorDavid Lamparter <equinox@opensourcerouting.org>
Fri, 14 Jan 2022 13:57:21 +0000 (14:57 +0100)
committerDavid Lamparter <equinox@opensourcerouting.org>
Mon, 14 Feb 2022 05:45:03 +0000 (06:45 +0100)
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
pimd/pim_join.c
pimd/pim_msg.c
pimd/pim_msg.h

index fa2d8d462b193f1ba6c9d8c38c3f310a9931f9d4..22890dc3721a163e99d20450d0a8656f7e693a9e 100644 (file)
@@ -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)
 
index c493ded0c6c7253eb847f7f2b6ab005d9100ce8e..e25cf11549401d84e79bcc2e0e82a3a823155946 100644 (file)
@@ -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);
index 2d69a4b03af6008c57dc219a67a315c4637e89b8..522e94504a8bfa616d088f4bf1e534a6bfecbff0 100644 (file)
@@ -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,