mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-30 06:42:17 +00:00
lib: pretty ip_masklen and masklen2ip
nonwithstanding any desire for optimisation, these versions are shorter and more concise. reading the comments, they might even be easier to understand. I've tested them on i686 and x86_64, and checked that correct assembler code is emitted for ARM, MIPS and PowerPC. IPv6 is left as an exercise for another day, none of the ideas I had led to a "yes, this is the one to go with" solution. Signed-off-by: David Lamparter <equinox@diac24.net>
This commit is contained in:
parent
a3537862f3
commit
e96b312150
128
lib/prefix.c
128
lib/prefix.c
@ -31,79 +31,6 @@
|
||||
/* Maskbit. */
|
||||
static const u_char maskbit[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0,
|
||||
0xf8, 0xfc, 0xfe, 0xff};
|
||||
static const u_int32_t maskbytes_big_endian[] =
|
||||
{
|
||||
0x00000000, /* /0 0.0.0.0 */
|
||||
0x80000000, /* /1 128.0.0.0 */
|
||||
0xc0000000, /* /2 192.0.0.0 */
|
||||
0xe0000000, /* /3 224.0.0.0 */
|
||||
0xf0000000, /* /4 240.0.0.0 */
|
||||
0xf8000000, /* /5 248.0.0.0 */
|
||||
0xfc000000, /* /6 252.0.0.0 */
|
||||
0xfe000000, /* /7 254.0.0.0 */
|
||||
0xff000000, /* /8 255.0.0.0 */
|
||||
0xff800000, /* /9 255.128.0.0 */
|
||||
0xffc00000, /* /10 255.192.0.0 */
|
||||
0xffe00000, /* /11 255.224.0.0 */
|
||||
0xfff00000, /* /12 255.240.0.0 */
|
||||
0xfff80000, /* /13 255.248.0.0 */
|
||||
0xfffc0000, /* /14 255.252.0.0 */
|
||||
0xfffe0000, /* /15 255.254.0.0 */
|
||||
0xffff0000, /* /16 255.255.0.0 */
|
||||
0xffff8000, /* /17 255.255.128.0 */
|
||||
0xffffc000, /* /18 255.255.192.0 */
|
||||
0xffffe000, /* /19 255.255.224.0 */
|
||||
0xfffff000, /* /20 255.255.240.0 */
|
||||
0xfffff800, /* /21 255.255.248.0 */
|
||||
0xfffffc00, /* /22 255.255.252.0 */
|
||||
0xfffffe00, /* /23 255.255.254.0 */
|
||||
0xffffff00, /* /24 255.255.255.0 */
|
||||
0xffffff80, /* /25 255.255.255.128 */
|
||||
0xffffffc0, /* /26 255.255.255.192 */
|
||||
0xffffffe0, /* /27 255.255.255.224 */
|
||||
0xfffffff0, /* /28 255.255.255.240 */
|
||||
0xfffffff8, /* /29 255.255.255.248 */
|
||||
0xfffffffc, /* /30 255.255.255.252 */
|
||||
0xfffffffe, /* /31 255.255.255.254 */
|
||||
0xffffffff /* /32 255.255.255.255 */
|
||||
};
|
||||
|
||||
static const u_int32_t maskbytes_little_endian[] =
|
||||
{
|
||||
0x00000000, /* /0 0.0.0.0 */
|
||||
0x00000080, /* /1 128.0.0.0 */
|
||||
0x000000c0, /* /2 192.0.0.0 */
|
||||
0x000000e0, /* /3 224.0.0.0 */
|
||||
0x000000f0, /* /4 240.0.0.0 */
|
||||
0x000000f8, /* /5 248.0.0.0 */
|
||||
0x000000fc, /* /6 252.0.0.0 */
|
||||
0x000000fe, /* /7 254.0.0.0 */
|
||||
0x000000ff, /* /8 255.0.0.0 */
|
||||
0x000080ff, /* /9 255.128.0.0 */
|
||||
0x0000c0ff, /* /10 255.192.0.0 */
|
||||
0x0000e0ff, /* /11 255.224.0.0 */
|
||||
0x0000f0ff, /* /12 255.240.0.0 */
|
||||
0x0000f8ff, /* /13 255.248.0.0 */
|
||||
0x0000fcff, /* /14 255.252.0.0 */
|
||||
0x0000feff, /* /15 255.254.0.0 */
|
||||
0x0000ffff, /* /16 255.255.0.0 */
|
||||
0x0080ffff, /* /17 255.255.128.0 */
|
||||
0x00c0ffff, /* /18 255.255.192.0 */
|
||||
0x00e0ffff, /* /19 255.255.224.0 */
|
||||
0x00f0ffff, /* /20 255.255.240.0 */
|
||||
0x00f8ffff, /* /21 255.255.248.0 */
|
||||
0x00fcffff, /* /22 255.255.252.0 */
|
||||
0x00feffff, /* /23 255.255.254.0 */
|
||||
0x00ffffff, /* /24 255.255.255.0 */
|
||||
0x80ffffff, /* /25 255.255.255.128 */
|
||||
0xc0ffffff, /* /26 255.255.255.192 */
|
||||
0xe0ffffff, /* /27 255.255.255.224 */
|
||||
0xf0ffffff, /* /28 255.255.255.240 */
|
||||
0xf8ffffff, /* /29 255.255.255.248 */
|
||||
0xfcffffff, /* /30 255.255.255.252 */
|
||||
0xfeffffff, /* /31 255.255.255.254 */
|
||||
0xffffffff /* /32 255.255.255.255 */
|
||||
};
|
||||
|
||||
static const struct in6_addr maskbytes6[] =
|
||||
{
|
||||
@ -527,11 +454,15 @@ void
|
||||
masklen2ip (const int masklen, struct in_addr *netmask)
|
||||
{
|
||||
assert (masklen >= 0 && masklen <= IPV4_MAX_BITLEN);
|
||||
#if (BYTE_ORDER == LITTLE_ENDIAN)
|
||||
netmask->s_addr = maskbytes_little_endian[masklen];
|
||||
#elif (BYTE_ORDER == BIG_ENDIAN)
|
||||
netmask->s_addr = maskbytes_big_endian[masklen];
|
||||
#endif
|
||||
|
||||
/* left shift is only defined for less than the size of the type.
|
||||
* we unconditionally use long long in case the target platform
|
||||
* has defined behaviour for << 32 (or has a 64-bit left shift) */
|
||||
|
||||
if (sizeof(unsigned long long) > 4)
|
||||
netmask->s_addr = htonl(0xffffffffULL << (32 - masklen));
|
||||
else
|
||||
netmask->s_addr = htonl(masklen ? 0xffffffffU << (32 - masklen) : 0);
|
||||
}
|
||||
|
||||
/* Convert IP address's netmask into integer. We assume netmask is
|
||||
@ -539,43 +470,22 @@ masklen2ip (const int masklen, struct in_addr *netmask)
|
||||
u_char
|
||||
ip_masklen (struct in_addr netmask)
|
||||
{
|
||||
u_char len;
|
||||
u_char *pnt;
|
||||
u_char *end;
|
||||
u_char val;
|
||||
|
||||
len = 0;
|
||||
pnt = (u_char *) &netmask;
|
||||
end = pnt + 4;
|
||||
|
||||
while ((pnt < end) && (*pnt == 0xff))
|
||||
{
|
||||
len+= 8;
|
||||
pnt++;
|
||||
}
|
||||
|
||||
if (pnt < end)
|
||||
{
|
||||
val = *pnt;
|
||||
while (val)
|
||||
{
|
||||
len++;
|
||||
val <<= 1;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
uint32_t tmp = ~ntohl(netmask.s_addr);
|
||||
if (tmp)
|
||||
/* clz: count leading zeroes. sadly, the behaviour of this builtin
|
||||
* is undefined for a 0 argument, even though most CPUs give 32 */
|
||||
return __builtin_clz(tmp);
|
||||
else
|
||||
return 32;
|
||||
}
|
||||
|
||||
/* Apply mask to IPv4 prefix (network byte order). */
|
||||
void
|
||||
apply_mask_ipv4 (struct prefix_ipv4 *p)
|
||||
{
|
||||
assert (p->prefixlen >= 0 && p->prefixlen <= IPV4_MAX_BITLEN);
|
||||
#if (BYTE_ORDER == LITTLE_ENDIAN)
|
||||
p->prefix.s_addr &= maskbytes_little_endian[p->prefixlen];
|
||||
#elif (BYTE_ORDER == BIG_ENDIAN)
|
||||
p->prefix.s_addr &= maskbytes_big_endian[p->prefixlen];
|
||||
#endif
|
||||
struct in_addr mask;
|
||||
masklen2ip(p->prefixlen, &mask);
|
||||
p->prefix.s_addr &= mask.s_addr;
|
||||
}
|
||||
|
||||
/* If prefix is 0.0.0.0/0 then return 1 else return 0. */
|
||||
|
Loading…
Reference in New Issue
Block a user