Commit 1fd09d0b authored by Michael Tremer's avatar Michael Tremer

network: Pass prefix in native length

When creating an IPv4 subnet, the prefix had to be mapped to the mapped
syntax (i.e. add 96). This doesn't seem too intuitive to me.
Signed-off-by: default avatarMichael Tremer <michael.tremer@ipfire.org>
parent 5b72642c
......@@ -33,6 +33,34 @@ static inline int loc_address_family(const struct in6_addr* address) {
return AF_INET6;
}
static inline unsigned int loc_address_family_bit_length(const int family) {
switch (family) {
case AF_INET6:
return 128;
case AF_INET:
return 32;
default:
return 0;
}
}
/*
Checks whether prefix is valid for the given address
*/
static inline int loc_address_valid_prefix(const struct in6_addr* address, unsigned int prefix) {
const int family = loc_address_family(address);
// What is the largest possible prefix?
const unsigned int bit_length = loc_address_family_bit_length(family);
if (prefix <= bit_length)
return 1;
return 0;
}
static inline int loc_address_cmp(const struct in6_addr* a1, const struct in6_addr* a2) {
for (unsigned int i = 0; i < 16; i++) {
if (a1->s6_addr[i] > a2->s6_addr[i])
......@@ -247,19 +275,6 @@ static inline void loc_address_decrement(struct in6_addr* address) {
}
}
static inline int loc_address_family_bit_length(const int family) {
switch (family) {
case AF_INET6:
return 128;
case AF_INET:
return 32;
default:
return -1;
}
}
static inline int loc_address_all_zeroes(const struct in6_addr* address) {
struct in6_addr all_zeroes = IN6ADDR_ANY_INIT;
......
......@@ -358,7 +358,7 @@ int loc_network_list_summarize(struct loc_ctx* ctx,
int bits = (bits1 > bits2) ? bits2 : bits1;
// Create a network
r = loc_network_new(ctx, &network, &start, 128 - bits);
r = loc_network_new(ctx, &network, &start, family_bit_length - bits);
if (r)
return r;
......
......@@ -47,22 +47,10 @@ struct loc_network {
enum loc_network_flags flags;
};
static int valid_prefix(struct in6_addr* address, unsigned int prefix) {
// The prefix cannot be larger than 128 bits
if (prefix > 128)
return 1;
// For IPv4-mapped addresses the prefix has to be 96 or lager
if (IN6_IS_ADDR_V4MAPPED(address) && prefix <= 96)
return 1;
return 0;
}
LOC_EXPORT int loc_network_new(struct loc_ctx* ctx, struct loc_network** network,
struct in6_addr* address, unsigned int prefix) {
// Validate the prefix
if (valid_prefix(address, prefix) != 0) {
if (!loc_address_valid_prefix(address, prefix)) {
ERROR(ctx, "Invalid prefix: %u\n", prefix);
errno = EINVAL;
return 1;
......@@ -78,7 +66,10 @@ LOC_EXPORT int loc_network_new(struct loc_ctx* ctx, struct loc_network** network
n->refcount = 1;
// Store the prefix
n->prefix = prefix;
if (IN6_IS_ADDR_V4MAPPED(address))
n->prefix = prefix + 96;
else
n->prefix = prefix;
// Convert the prefix into a bitmask
struct in6_addr bitmask = loc_prefix_to_bitmask(n->prefix);
......@@ -129,10 +120,6 @@ LOC_EXPORT int loc_network_new_from_string(struct loc_ctx* ctx, struct loc_netwo
DEBUG(ctx, "The prefix was not parsable: %s\n", prefix_string);
goto FAIL;
}
// Map the prefix to IPv6 if needed
if (IN6_IS_ADDR_V4MAPPED(&first_address))
prefix += 96;
}
FAIL:
......@@ -425,7 +412,7 @@ LOC_EXPORT int loc_network_subnets(struct loc_network* network,
unsigned int prefix = network->prefix + 1;
// Check if the new prefix is valid
if (valid_prefix(&network->first_address, prefix))
if (!loc_address_valid_prefix(&network->first_address, prefix))
return -1;
// Create the first half of the network
......@@ -685,6 +672,10 @@ int loc_network_new_from_database_v1(struct loc_ctx* ctx, struct loc_network** n
struct in6_addr* address, unsigned int prefix, const struct loc_database_network_v1* dbobj) {
char country_code[3] = "\0\0";
// Adjust prefix for IPv4
if (IN6_IS_ADDR_V4MAPPED(address))
prefix -= 96;
int r = loc_network_new(ctx, network, address, prefix);
if (r) {
ERROR(ctx, "Could not allocate a new network: %s", strerror(-r));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment