1/* Copyright (C) 2017 Mellanox Technologies Inc. */ 2 3struct semanage_ibpkey; 4struct semanage_ibpkey_key; 5typedef struct semanage_ibpkey_key record_key_t; 6typedef struct semanage_ibpkey record_t; 7#define DBASE_RECORD_DEFINED 8 9#include <stdlib.h> 10#include <string.h> 11#include <netinet/in.h> 12#include "ibpkey_internal.h" 13#include "debug.h" 14#include "handle.h" 15#include "database.h" 16 17int semanage_ibpkey_modify_local(semanage_handle_t *handle, 18 const semanage_ibpkey_key_t *key, 19 const semanage_ibpkey_t *data) 20{ 21 dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle); 22 23 return dbase_modify(handle, dconfig, key, data); 24} 25 26int semanage_ibpkey_del_local(semanage_handle_t *handle, 27 const semanage_ibpkey_key_t *key) 28{ 29 dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle); 30 31 return dbase_del(handle, dconfig, key); 32} 33 34int semanage_ibpkey_query_local(semanage_handle_t *handle, 35 const semanage_ibpkey_key_t *key, 36 semanage_ibpkey_t **response) 37{ 38 dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle); 39 40 return dbase_query(handle, dconfig, key, response); 41} 42 43int semanage_ibpkey_exists_local(semanage_handle_t *handle, 44 const semanage_ibpkey_key_t *key, 45 int *response) 46{ 47 dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle); 48 49 return dbase_exists(handle, dconfig, key, response); 50} 51 52int semanage_ibpkey_count_local(semanage_handle_t *handle, 53 unsigned int *response) 54{ 55 dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle); 56 57 return dbase_count(handle, dconfig, response); 58} 59 60int semanage_ibpkey_iterate_local(semanage_handle_t *handle, 61 int (*handler)(const semanage_ibpkey_t *record, 62 void *varg), void *handler_arg) 63{ 64 dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle); 65 66 return dbase_iterate(handle, dconfig, handler, handler_arg); 67} 68 69int semanage_ibpkey_list_local(semanage_handle_t *handle, 70 semanage_ibpkey_t ***records, unsigned int *count) 71{ 72 dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle); 73 74 return dbase_list(handle, dconfig, records, count); 75} 76 77hidden_def(semanage_ibpkey_list_local) 78 79int hidden semanage_ibpkey_validate_local(semanage_handle_t *handle) 80{ 81 semanage_ibpkey_t **ibpkeys = NULL; 82 unsigned int nibpkeys = 0; 83 unsigned int i = 0, j = 0; 84 uint64_t subnet_prefix; 85 uint64_t subnet_prefix2; 86 char *subnet_prefix_str; 87 char *subnet_prefix_str2; 88 int low, high; 89 int low2, high2; 90 91 /* List and sort the ibpkeys */ 92 if (semanage_ibpkey_list_local(handle, &ibpkeys, &nibpkeys) < 0) 93 goto err; 94 95 qsort(ibpkeys, nibpkeys, sizeof(semanage_ibpkey_t *), 96 (int (*)(const void *, const void *)) 97 &semanage_ibpkey_compare2_qsort); 98 99 /* Test each ibpkey for overlap */ 100 while (i < nibpkeys) { 101 if (STATUS_SUCCESS != semanage_ibpkey_get_subnet_prefix(handle, 102 ibpkeys[i], 103 &subnet_prefix_str)) { 104 ERR(handle, "Couldn't get subnet prefix string"); 105 goto err; 106 } 107 108 subnet_prefix = semanage_ibpkey_get_subnet_prefix_bytes(ibpkeys[i]); 109 low = semanage_ibpkey_get_low(ibpkeys[i]); 110 high = semanage_ibpkey_get_high(ibpkeys[i]); 111 112 /* Find the first ibpkey with matching 113 * subnet_prefix to compare against 114 */ 115 do { 116 if (j == nibpkeys - 1) 117 goto next; 118 j++; 119 120 if (STATUS_SUCCESS != 121 semanage_ibpkey_get_subnet_prefix(handle, 122 ibpkeys[j], 123 &subnet_prefix_str2)) { 124 ERR(handle, "Couldn't get subnet prefix string"); 125 goto err; 126 } 127 subnet_prefix2 = semanage_ibpkey_get_subnet_prefix_bytes(ibpkeys[j]); 128 low2 = semanage_ibpkey_get_low(ibpkeys[j]); 129 high2 = semanage_ibpkey_get_high(ibpkeys[j]); 130 } while (subnet_prefix != subnet_prefix2); 131 132 /* Overlap detected */ 133 if (low2 <= high) { 134 ERR(handle, "ibpkey overlap between ranges " 135 "(%s) %u - %u <--> (%s) %u - %u.", 136 subnet_prefix_str, low, high, 137 subnet_prefix_str2, low2, high2); 138 goto invalid; 139 } 140 141 /* If closest ibpkey of matching subnet prefix doesn't overlap 142 * with test ibpkey, neither do the rest of them, because that's 143 * how the sort function works on ibpkeys - lower bound 144 * ibpkeys come first 145 */ 146next: 147 i++; 148 j = i; 149 } 150 151 for (i = 0; i < nibpkeys; i++) 152 semanage_ibpkey_free(ibpkeys[i]); 153 free(ibpkeys); 154 return STATUS_SUCCESS; 155 156err: 157 ERR(handle, "could not complete ibpkeys validity check"); 158 159invalid: 160 for (i = 0; i < nibpkeys; i++) 161 semanage_ibpkey_free(ibpkeys[i]); 162 free(ibpkeys); 163 return STATUS_ERR; 164} 165