/* Copyright (C) 2017 Mellanox Technologies Inc. */ struct semanage_ibpkey; struct semanage_ibpkey_key; typedef struct semanage_ibpkey_key record_key_t; typedef struct semanage_ibpkey record_t; #define DBASE_RECORD_DEFINED #include #include #include #include "ibpkey_internal.h" #include "debug.h" #include "handle.h" #include "database.h" int semanage_ibpkey_modify_local(semanage_handle_t *handle, const semanage_ibpkey_key_t *key, const semanage_ibpkey_t *data) { dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle); return dbase_modify(handle, dconfig, key, data); } int semanage_ibpkey_del_local(semanage_handle_t *handle, const semanage_ibpkey_key_t *key) { dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle); return dbase_del(handle, dconfig, key); } int semanage_ibpkey_query_local(semanage_handle_t *handle, const semanage_ibpkey_key_t *key, semanage_ibpkey_t **response) { dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle); return dbase_query(handle, dconfig, key, response); } int semanage_ibpkey_exists_local(semanage_handle_t *handle, const semanage_ibpkey_key_t *key, int *response) { dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle); return dbase_exists(handle, dconfig, key, response); } int semanage_ibpkey_count_local(semanage_handle_t *handle, unsigned int *response) { dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle); return dbase_count(handle, dconfig, response); } int semanage_ibpkey_iterate_local(semanage_handle_t *handle, int (*handler)(const semanage_ibpkey_t *record, void *varg), void *handler_arg) { dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle); return dbase_iterate(handle, dconfig, handler, handler_arg); } int semanage_ibpkey_list_local(semanage_handle_t *handle, semanage_ibpkey_t ***records, unsigned int *count) { dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle); return dbase_list(handle, dconfig, records, count); } hidden_def(semanage_ibpkey_list_local) int hidden semanage_ibpkey_validate_local(semanage_handle_t *handle) { semanage_ibpkey_t **ibpkeys = NULL; unsigned int nibpkeys = 0; unsigned int i = 0, j = 0; uint64_t subnet_prefix; uint64_t subnet_prefix2; char *subnet_prefix_str; char *subnet_prefix_str2; int low, high; int low2, high2; /* List and sort the ibpkeys */ if (semanage_ibpkey_list_local(handle, &ibpkeys, &nibpkeys) < 0) goto err; qsort(ibpkeys, nibpkeys, sizeof(semanage_ibpkey_t *), (int (*)(const void *, const void *)) &semanage_ibpkey_compare2_qsort); /* Test each ibpkey for overlap */ while (i < nibpkeys) { if (STATUS_SUCCESS != semanage_ibpkey_get_subnet_prefix(handle, ibpkeys[i], &subnet_prefix_str)) { ERR(handle, "Couldn't get subnet prefix string"); goto err; } subnet_prefix = semanage_ibpkey_get_subnet_prefix_bytes(ibpkeys[i]); low = semanage_ibpkey_get_low(ibpkeys[i]); high = semanage_ibpkey_get_high(ibpkeys[i]); /* Find the first ibpkey with matching * subnet_prefix to compare against */ do { if (j == nibpkeys - 1) goto next; j++; if (STATUS_SUCCESS != semanage_ibpkey_get_subnet_prefix(handle, ibpkeys[j], &subnet_prefix_str2)) { ERR(handle, "Couldn't get subnet prefix string"); goto err; } subnet_prefix2 = semanage_ibpkey_get_subnet_prefix_bytes(ibpkeys[j]); low2 = semanage_ibpkey_get_low(ibpkeys[j]); high2 = semanage_ibpkey_get_high(ibpkeys[j]); } while (subnet_prefix != subnet_prefix2); /* Overlap detected */ if (low2 <= high) { ERR(handle, "ibpkey overlap between ranges " "(%s) %u - %u <--> (%s) %u - %u.", subnet_prefix_str, low, high, subnet_prefix_str2, low2, high2); goto invalid; } /* If closest ibpkey of matching subnet prefix doesn't overlap * with test ibpkey, neither do the rest of them, because that's * how the sort function works on ibpkeys - lower bound * ibpkeys come first */ next: i++; j = i; } for (i = 0; i < nibpkeys; i++) semanage_ibpkey_free(ibpkeys[i]); free(ibpkeys); return STATUS_SUCCESS; err: ERR(handle, "could not complete ibpkeys validity check"); invalid: for (i = 0; i < nibpkeys; i++) semanage_ibpkey_free(ibpkeys[i]); free(ibpkeys); return STATUS_ERR; }