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 *)
#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)
#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)
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;