summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/birdlib.h6
-rw-r--r--lib/ip.h6
-rw-r--r--lib/net.c27
-rw-r--r--lib/net.h31
4 files changed, 53 insertions, 17 deletions
diff --git a/lib/birdlib.h b/lib/birdlib.h
index 16f437ef..5fec6c7a 100644
--- a/lib/birdlib.h
+++ b/lib/birdlib.h
@@ -35,6 +35,12 @@
#define DELTA(a,b) (((a)>=(b))?(a)-(b):(b)-(a))
#define ARRAY_SIZE(a) (sizeof(a)/sizeof(*(a)))
+static inline int uint_cmp(uint i1, uint i2)
+{ return (int)(i1 > i2) - (int)(i1 < i2); }
+
+static inline int u64_cmp(u64 i1, u64 i2)
+{ return (int)(i1 > i2) - (int)(i1 < i2); }
+
/* Bitfield macros */
diff --git a/lib/ip.h b/lib/ip.h
index 9706b397..1834db4f 100644
--- a/lib/ip.h
+++ b/lib/ip.h
@@ -492,10 +492,4 @@ int ip6_pton(const char *a, ip6_addr *o);
char *ip_scope_text(uint);
-struct prefix {
- ip_addr addr;
- uint len;
-};
-
-
#endif
diff --git a/lib/net.c b/lib/net.c
index 21486a9b..e2765995 100644
--- a/lib/net.c
+++ b/lib/net.c
@@ -58,23 +58,30 @@ net_pxmask(const net_addr *a)
}
}
-
-static inline int net_validate_ip4(const net_addr_ip4 *n)
+int
+net_compare(const net_addr *a, const net_addr *b)
{
- return (n->pxlen <= IP4_MAX_PREFIX_LENGTH) &&
- ip4_zero(ip4_and(n->prefix, ip4_not(ip4_mkmask(n->pxlen))));
-}
+ if (a->type != b->type)
+ return uint_cmp(a->type, b->type);
-static inline int net_validate_ip6(const net_addr_ip6 *n)
-{
- return (n->pxlen <= IP6_MAX_PREFIX_LENGTH) &&
- ip6_zero(ip6_and(n->prefix, ip6_not(ip6_mkmask(n->pxlen))));
+ switch (a->type)
+ {
+ case NET_IP4:
+ return net_compare_ip4((const net_addr_ip4 *) a, (const net_addr_ip4 *) b);
+ case NET_IP6:
+ return net_compare_ip6((const net_addr_ip6 *) a, (const net_addr_ip6 *) b);
+ case NET_VPN4:
+ return net_compare_vpn4((const net_addr_vpn4 *) a, (const net_addr_vpn4 *) b);
+ case NET_VPN6:
+ return net_compare_vpn6((const net_addr_vpn6 *) a, (const net_addr_vpn6 *) b);
+ }
+ return 0;
}
int
net_validate(const net_addr *N)
{
- switch (a->type)
+ switch (N->type)
{
case NET_IP4:
case NET_VPN4:
diff --git a/lib/net.h b/lib/net.h
index bc1233bf..c9ca349f 100644
--- a/lib/net.h
+++ b/lib/net.h
@@ -162,6 +162,21 @@ static inline int net_zero_vpn6(const net_addr_vpn6 *a)
{ return !a->pxlen && ip6_zero(a->prefix) && !a->rd; }
+static inline int net_compare_ip4(const net_addr_ip4 *a, const net_addr_ip4 *b)
+{ return ip4_compare(a->prefix, b->prefix) ?: uint_cmp(a->pxlen, b->pxlen); }
+
+static inline int net_compare_ip6(const net_addr_ip6 *a, const net_addr_ip6 *b)
+{ return ip6_compare(a->prefix, b->prefix) ?: uint_cmp(a->pxlen, b->pxlen); }
+
+static inline int net_compare_vpn4(const net_addr_vpn4 *a, const net_addr_vpn4 *b)
+{ return u64_cmp(a->rd, b->rd) ?: ip4_compare(a->prefix, b->prefix) ?: uint_cmp(a->pxlen, b->pxlen); }
+
+static inline int net_compare_vpn6(const net_addr_vpn6 *a, const net_addr_vpn6 *b)
+{ return u64_cmp(a->rd, b->rd) ?: ip6_compare(a->prefix, b->prefix) ?: uint_cmp(a->pxlen, b->pxlen); }
+
+int net_compare(const net_addr *a, const net_addr *b);
+
+
static inline void net_copy(net_addr *dst, const net_addr *src)
{ memcpy(dst, src, src->length); }
@@ -195,6 +210,21 @@ static inline u32 net_hash_vpn6(const net_addr_vpn6 *n)
{ return ip6_hash(n->prefix) ^ ((u32) n->pxlen << 26) ^ u64_hash(n->rd); }
+static inline int net_validate_ip4(const net_addr_ip4 *n)
+{
+ return (n->pxlen <= IP4_MAX_PREFIX_LENGTH) &&
+ ip4_zero(ip4_and(n->prefix, ip4_not(ip4_mkmask(n->pxlen))));
+}
+
+static inline int net_validate_ip6(const net_addr_ip6 *n)
+{
+ return (n->pxlen <= IP6_MAX_PREFIX_LENGTH) &&
+ ip6_zero(ip6_and(n->prefix, ip6_not(ip6_mkmask(n->pxlen))));
+}
+
+int net_validate(const net_addr *N);
+
+
static inline void net_normalize_ip4(net_addr_ip4 *n)
{ n->prefix = ip4_and(n->prefix, ip4_mkmask(n->pxlen)); }
@@ -203,7 +233,6 @@ static inline void net_normalize_ip6(net_addr_ip6 *n)
void net_normalize(net_addr *N);
-int net_validate(const net_addr *N);
int net_classify(const net_addr *N);
int net_format(const net_addr *N, char *buf, int buflen);