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
semanage_ibpkey_modify_local(semanage_handle_t * handle,const semanage_ibpkey_key_t * key,const semanage_ibpkey_t * data)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
semanage_ibpkey_del_local(semanage_handle_t * handle,const semanage_ibpkey_key_t * key)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
semanage_ibpkey_query_local(semanage_handle_t * handle,const semanage_ibpkey_key_t * key,semanage_ibpkey_t ** response)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
semanage_ibpkey_exists_local(semanage_handle_t * handle,const semanage_ibpkey_key_t * key,int * response)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
semanage_ibpkey_count_local(semanage_handle_t * handle,unsigned int * response)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
semanage_ibpkey_iterate_local(semanage_handle_t * handle,int (* handler)(const semanage_ibpkey_t * record,void * varg),void * handler_arg)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
semanage_ibpkey_list_local(semanage_handle_t * handle,semanage_ibpkey_t *** records,unsigned int * count)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
hidden_def(semanage_ibpkey_list_local)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