1 /* Copyright (C) 2017 Mellanox Technologies Inc. */ 2 3 struct semanage_ibpkey; 4 struct semanage_ibpkey_key; 5 typedef struct semanage_ibpkey_key record_key_t; 6 typedef 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 17 int 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 26 int 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 34 int 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 43 int 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 52 int 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 60 int 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 69 int 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 77 hidden_def(semanage_ibpkey_list_local) 78 79 int 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 */ 146 next: 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 156 err: 157 ERR(handle, "could not complete ibpkeys validity check"); 158 159 invalid: 160 for (i = 0; i < nibpkeys; i++) 161 semanage_ibpkey_free(ibpkeys[i]); 162 free(ibpkeys); 163 return STATUS_ERR; 164 } 165