Home | History | Annotate | Download | only in src
      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