From: David Lamparter Date: Thu, 7 Apr 2022 11:47:37 +0000 (+0200) Subject: lib, pimd: add a bunch of address helpers X-Git-Tag: pim6-testing-20220430~89^2~1 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=eeec41124402192108baa0830ad0b7fb8aa8c4ac;p=mirror%2Ffrr.git lib, pimd: add a bunch of address helpers Just simple helpers to get a scope value, never-forward, and is-SSM for a given address. Signed-off-by: David Lamparter --- diff --git a/lib/prefix.h b/lib/prefix.h index 816a1517e1..5e03a7b4f5 100644 --- a/lib/prefix.h +++ b/lib/prefix.h @@ -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 *) diff --git a/pimd/pim_addr.h b/pimd/pim_addr.h index e422a2e2da..eca907da37 100644 --- a/pimd/pim_addr.h +++ b/pimd/pim_addr.h @@ -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;