diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/prefix.h | 65 |
1 files changed, 65 insertions, 0 deletions
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 *) |
