1
0
mirror of https://github.com/systemd/systemd.git synced 2025-03-19 22:50:17 +03:00

add ipv6 range element creation test cases

The nft set backend doesn't support network masks, it works with
ranges.  Inputs like dead::/64 thus need to be translated to two
'start' and 'end' elements.

The 'start' element is the first element in the range (i.e., dead::).
The 'stop' element is the first element *past* the range, (dead:0:0100::
in the example).

This adds a few test cases.
This commit is contained in:
Florian Westphal 2020-12-22 12:57:00 +01:00
parent f4fca22ad4
commit 79dd224093
2 changed files with 67 additions and 2 deletions

View File

@ -30,6 +30,9 @@
#define UDP_DPORT_OFFSET 2
void nft_in6addr_to_range(const union in_addr_union *source, unsigned int prefixlen,
struct in6_addr *start, struct in6_addr *end);
static int nfnl_netlink_sendv(sd_netlink *nfnl,
sd_netlink_message *messages[],
size_t msgcount) {
@ -845,8 +848,8 @@ static int fw_nftables_recreate_table(sd_netlink *nfnl, int af, sd_netlink_messa
return 0;
}
static void nft_in6addr_to_range(const union in_addr_union *source, unsigned int prefixlen,
struct in6_addr *ret_start, struct in6_addr *ret_end) {
void nft_in6addr_to_range(const union in_addr_union *source, unsigned int prefixlen,
struct in6_addr *ret_start, struct in6_addr *ret_end) {
uint8_t carry = 0;
int i, j;

View File

@ -9,10 +9,25 @@
#define MAKE_IN_ADDR_UNION(a,b,c,d) (union in_addr_union) { .in.s_addr = htobe32((uint32_t) (a) << 24 | (uint32_t) (b) << 16 | (uint32_t) (c) << 8 | (uint32_t) (d))}
void nft_in6addr_to_range(const union in_addr_union *source, unsigned int prefixlen,
struct in6_addr *start, struct in6_addr *end);
static void make_in6_addr_union(const char *addr, union in_addr_union *u) {
assert_se(inet_pton(AF_INET6, addr, &u->in6) >= 0);
}
static bool test_in6_eq(const char *addr, const union in_addr_union *u) {
union in_addr_union tmp;
make_in6_addr_union(addr, &tmp);
return memcmp(&tmp.in6, &u->in6, sizeof(tmp.in6)) == 0;
}
static void assert_in6_eq(const union in_addr_union *a, const union in_addr_union *b) {
assert_se(memcmp(&a->in6, &b->in6, sizeof(a->in6)) == 0);
}
static void test_v6(FirewallContext **ctx) {
union in_addr_union u = {}, u2 = {};
uint8_t prefixlen;
@ -62,6 +77,52 @@ static void test_v6(FirewallContext **ctx) {
log_error_errno(r, "Failed to modify ipv6 firewall: %m");
}
static void test_v6_range(void) {
unsigned int prefixlen = 64;
union in_addr_union a, b, s;
make_in6_addr_union("dead:0:0:beef::", &s);
nft_in6addr_to_range(&s, prefixlen, &a.in6, &b.in6);
assert_in6_eq(&s, &a);
assert_se(test_in6_eq("dead:0:0:bef0::", &b));
make_in6_addr_union("2001::", &s);
prefixlen = 56;
nft_in6addr_to_range(&s, prefixlen, &a.in6, &b.in6);
assert_in6_eq(&s, &a);
assert_se(test_in6_eq("2001:0:0:0100::", &b));
prefixlen = 48;
nft_in6addr_to_range(&s, prefixlen, &a.in6, &b.in6);
assert_in6_eq(&s, &a);
assert_se(test_in6_eq("2001:0:0001::", &b));
prefixlen = 65;
nft_in6addr_to_range(&s, prefixlen, &a.in6, &b.in6);
assert_se(test_in6_eq("2001::", &a));
assert_se(test_in6_eq("2001::8000:0:0:0", &b));
prefixlen = 66;
nft_in6addr_to_range(&s, prefixlen, &a.in6, &b.in6);
assert_in6_eq(&s, &a);
assert_se(test_in6_eq("2001::4000:0:0:0", &b));
prefixlen = 127;
nft_in6addr_to_range(&s, prefixlen, &a.in6, &b.in6);
assert_in6_eq(&s, &a);
assert_se(test_in6_eq("2001::0002", &b));
make_in6_addr_union("dead:beef::1", &s);
prefixlen = 64;
nft_in6addr_to_range(&s, prefixlen, &a.in6, &b.in6);
assert_se(test_in6_eq("dead:beef::", &a));
}
int main(int argc, char *argv[]) {
_cleanup_(fw_ctx_freep) FirewallContext *ctx;
int r;
@ -114,6 +175,7 @@ int main(int argc, char *argv[]) {
log_error_errno(r, "Failed to modify firewall: %m");
test_v6(&ctx);
test_v6_range();
return 0;
}