]> git.puffer.fish Git - matthieu/frr.git/commitdiff
lib, pimd: add a bunch of address helpers
authorDavid Lamparter <equinox@opensourcerouting.org>
Thu, 7 Apr 2022 11:47:37 +0000 (13:47 +0200)
committerDavid Lamparter <equinox@opensourcerouting.org>
Thu, 7 Apr 2022 12:00:36 +0000 (14:00 +0200)
Just simple helpers to get a scope value, never-forward, and is-SSM for
a given address.

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
lib/prefix.h
pimd/pim_addr.h

index 816a1517e17a15c49f0ea5b3a282bbd581136820..5e03a7b4f5c51a3b2b06d7fc6afe19b2d0a34c52 100644 (file)
@@ -585,6 +585,71 @@ static inline int is_default_host_route(const struct prefix *p)
        return 0;
 }
 
+/* IPv6 scope values, usable for IPv4 too (cf. below) */
+/* clang-format off */
+enum {
+       /* 0: reserved */
+       MCAST_SCOPE_IFACE  = 0x1,
+       MCAST_SCOPE_LINK   = 0x2,
+       MCAST_SCOPE_REALM  = 0x3,
+       MCAST_SCOPE_ADMIN  = 0x4,
+       MCAST_SCOPE_SITE   = 0x5,
+       /* 6-7: unassigned */
+       MCAST_SCOPE_ORG    = 0x8,
+       /* 9-d: unassigned */
+       MCAST_SCOPE_GLOBAL = 0xe,
+       /* f: reserved */
+};
+/* clang-format on */
+
+static inline uint8_t ipv6_mcast_scope(const struct in6_addr *addr)
+{
+       return addr->s6_addr[1] & 0xf;
+}
+
+static inline bool ipv6_mcast_nofwd(const struct in6_addr *addr)
+{
+       return (addr->s6_addr[1] & 0xf) <= MCAST_SCOPE_LINK;
+}
+
+static inline bool ipv6_mcast_ssm(const struct in6_addr *addr)
+{
+       uint32_t bits = ntohl(addr->s6_addr32[0]);
+
+       /* ff3x:0000::/32 */
+       return (bits & 0xfff0ffff) == 0xff300000;
+}
+
+static inline uint8_t ipv4_mcast_scope(const struct in_addr *addr)
+{
+       uint32_t bits = ntohl(addr->s_addr);
+
+       /* 224.0.0.0/24 - link scope */
+       if ((bits & 0xffffff00) == 0xe0000000)
+               return MCAST_SCOPE_LINK;
+       /* 239.0.0.0/8 - org scope */
+       if ((bits & 0xff000000) == 0xef000000)
+               return MCAST_SCOPE_ORG;
+
+       return MCAST_SCOPE_GLOBAL;
+}
+
+static inline bool ipv4_mcast_nofwd(const struct in_addr *addr)
+{
+       uint32_t bits = ntohl(addr->s_addr);
+
+       /* 224.0.0.0/24 */
+       return (bits & 0xffffff00) == 0xe0000000;
+}
+
+static inline bool ipv4_mcast_ssm(const struct in_addr *addr)
+{
+       uint32_t bits = ntohl(addr->s_addr);
+
+       /* 232.0.0.0/8 */
+       return (bits & 0xff000000) == 0xe8000000;
+}
+
 #ifdef _FRR_ATTRIBUTE_PRINTFRR
 #pragma FRR printfrr_ext "%pEA"  (struct ethaddr *)
 
index e422a2e2da4364f27c0343c279def0bddf7a6a52..eca907da371e996a4ee1ee60cab6cf0bfb7c09ca 100644 (file)
@@ -34,6 +34,8 @@ typedef struct in_addr pim_addr;
 #define PIM_MAX_BITLEN IPV4_MAX_BITLEN
 #define PIM_AF_NAME     "ip"
 
+#define PIM_ADDR_FUNCNAME(name) ipv4_##name
+
 union pimprefixptr {
        prefixtype(pimprefixptr, struct prefix,      p)
        prefixtype(pimprefixptr, struct prefix_ipv4, p4)
@@ -53,6 +55,8 @@ typedef struct in6_addr pim_addr;
 #define PIM_MAX_BITLEN IPV6_MAX_BITLEN
 #define PIM_AF_NAME     "ipv6"
 
+#define PIM_ADDR_FUNCNAME(name) ipv6_##name
+
 union pimprefixptr {
        prefixtype(pimprefixptr, struct prefix,      p)
        prefixtype(pimprefixptr, struct prefix_ipv6, p6)
@@ -101,6 +105,21 @@ static inline pim_addr pim_addr_from_prefix(union pimprefixconstptr in)
        return ret;
 }
 
+static inline uint8_t pim_addr_scope(const pim_addr addr)
+{
+       return PIM_ADDR_FUNCNAME(mcast_scope)(&addr);
+}
+
+static inline bool pim_addr_nofwd(const pim_addr addr)
+{
+       return PIM_ADDR_FUNCNAME(mcast_nofwd)(&addr);
+}
+
+static inline bool pim_addr_ssm(const pim_addr addr)
+{
+       return PIM_ADDR_FUNCNAME(mcast_ssm)(&addr);
+}
+
 /* don't use this struct directly, use the pim_sgaddr typedef */
 struct _pim_sgaddr {
        pim_addr grp;