82 |
|
|
83 |
/************************* ADDRESS GROUP HANDLER *************************/ |
/************************* ADDRESS GROUP HANDLER *************************/ |
84 |
|
|
85 |
static LIST_HEAD(address_group_list); |
static LIST1_HEAD(address_group_list); |
86 |
|
|
87 |
static int AddAddressGroupEntry(const char *group_name, const bool is_ipv6, const u16 *min_address, const u16 *max_address, const bool is_delete) |
static int AddAddressGroupEntry(const char *group_name, const bool is_ipv6, const u16 *min_address, const u16 *max_address, const bool is_delete) |
88 |
{ |
{ |
97 |
if ((saved_group_name = SaveName(group_name)) == NULL) return -ENOMEM; |
if ((saved_group_name = SaveName(group_name)) == NULL) return -ENOMEM; |
98 |
if (is_ipv6) { |
if (is_ipv6) { |
99 |
if ((saved_min_address = SaveIPv6Address((struct in6_addr *) min_address)) == NULL |
if ((saved_min_address = SaveIPv6Address((struct in6_addr *) min_address)) == NULL |
100 |
|| (saved_max_address = SaveIPv6Address((struct in6_addr *) max_address))) return -ENOMEM; |
|| (saved_max_address = SaveIPv6Address((struct in6_addr *) max_address)) == NULL) return -ENOMEM; |
101 |
} |
} |
102 |
mutex_lock(&lock); |
mutex_lock(&lock); |
103 |
list_for_each_entry(group, &address_group_list, list) { |
list1_for_each_entry(group, &address_group_list, list) { |
104 |
if (saved_group_name != group->group_name) continue; |
if (saved_group_name != group->group_name) continue; |
105 |
list_for_each_entry(member, &group->address_group_member_list, list) { |
list1_for_each_entry(member, &group->address_group_member_list, list) { |
106 |
if (member->is_ipv6 != is_ipv6) continue; |
if (member->is_ipv6 != is_ipv6) continue; |
107 |
if (is_ipv6) { |
if (is_ipv6) { |
108 |
if (member->min.ipv6 != saved_min_address || member->max.ipv6 != saved_max_address) continue; |
if (member->min.ipv6 != saved_min_address || member->max.ipv6 != saved_max_address) continue; |
122 |
} |
} |
123 |
if (!found) { |
if (!found) { |
124 |
if ((new_group = alloc_element(sizeof(*new_group))) == NULL) goto out; |
if ((new_group = alloc_element(sizeof(*new_group))) == NULL) goto out; |
125 |
INIT_LIST_HEAD(&new_group->address_group_member_list); |
INIT_LIST1_HEAD(&new_group->address_group_member_list); |
126 |
new_group->group_name = saved_group_name; |
new_group->group_name = saved_group_name; |
127 |
list_add_tail_mb(&new_group->list, &address_group_list); |
list1_add_tail_mb(&new_group->list, &address_group_list); |
128 |
group = new_group; |
group = new_group; |
129 |
} |
} |
130 |
if ((new_member = alloc_element(sizeof(*new_member))) == NULL) goto out; |
if ((new_member = alloc_element(sizeof(*new_member))) == NULL) goto out; |
136 |
new_member->min.ipv4 = * (u32 *) min_address; |
new_member->min.ipv4 = * (u32 *) min_address; |
137 |
new_member->max.ipv4 = * (u32 *) max_address; |
new_member->max.ipv4 = * (u32 *) max_address; |
138 |
} |
} |
139 |
list_add_tail_mb(&new_member->list, &group->address_group_member_list); |
list1_add_tail_mb(&new_member->list, &group->address_group_member_list); |
140 |
error = 0; |
error = 0; |
141 |
out: |
out: |
142 |
mutex_unlock(&lock); |
mutex_unlock(&lock); |
181 |
int i; |
int i; |
182 |
struct address_group_entry *group; |
struct address_group_entry *group; |
183 |
for (i = 0; i <= 1; i++) { |
for (i = 0; i <= 1; i++) { |
184 |
list_for_each_entry(group, &address_group_list, list) { |
list1_for_each_entry(group, &address_group_list, list) { |
185 |
if (strcmp(group_name, group->group_name->name) == 0) return group; |
if (strcmp(group_name, group->group_name->name) == 0) return group; |
186 |
} |
} |
187 |
if (i == 0) { |
if (i == 0) { |
197 |
{ |
{ |
198 |
struct address_group_member *member; |
struct address_group_member *member; |
199 |
const u32 ip = ntohl(*address); |
const u32 ip = ntohl(*address); |
200 |
list_for_each_entry(member, &group->address_group_member_list, list) { |
list1_for_each_entry(member, &group->address_group_member_list, list) { |
201 |
if (member->is_deleted) continue; |
if (member->is_deleted) continue; |
202 |
if (member->is_ipv6) { |
if (member->is_ipv6) { |
203 |
if (is_ipv6 && memcmp(member->min.ipv6, address, 16) <= 0 && memcmp(address, member->max.ipv6, 16) <= 0) return 1; |
if (is_ipv6 && memcmp(member->min.ipv6, address, 16) <= 0 && memcmp(address, member->max.ipv6, 16) <= 0) return 1; |
210 |
|
|
211 |
int ReadAddressGroupPolicy(struct io_buffer *head) |
int ReadAddressGroupPolicy(struct io_buffer *head) |
212 |
{ |
{ |
213 |
struct list_head *gpos; |
struct list1_head *gpos; |
214 |
struct list_head *mpos; |
struct list1_head *mpos; |
215 |
list_for_each_cookie(gpos, head->read_var1, &address_group_list) { |
list1_for_each_cookie(gpos, head->read_var1, &address_group_list) { |
216 |
struct address_group_entry *group; |
struct address_group_entry *group; |
217 |
group = list_entry(gpos, struct address_group_entry, list); |
group = list1_entry(gpos, struct address_group_entry, list); |
218 |
list_for_each_cookie(mpos, head->read_var2, &group->address_group_member_list) { |
list1_for_each_cookie(mpos, head->read_var2, &group->address_group_member_list) { |
219 |
char buf[128]; |
char buf[128]; |
220 |
struct address_group_member *member; |
struct address_group_member *member; |
221 |
member = list_entry(mpos, struct address_group_member, list); |
member = list1_entry(mpos, struct address_group_member, list); |
222 |
if (member->is_deleted) continue; |
if (member->is_deleted) continue; |
223 |
if (member->is_ipv6) { |
if (member->is_ipv6) { |
224 |
const struct in6_addr *min_address = member->min.ipv6, *max_address = member->max.ipv6; |
const struct in6_addr *min_address = member->min.ipv6, *max_address = member->max.ipv6; |
306 |
if (!domain) return -EINVAL; |
if (!domain) return -EINVAL; |
307 |
if (record_type == IP_RECORD_TYPE_IPv6) { |
if (record_type == IP_RECORD_TYPE_IPv6) { |
308 |
if ((saved_min_address = SaveIPv6Address((struct in6_addr *) min_address)) == NULL |
if ((saved_min_address = SaveIPv6Address((struct in6_addr *) min_address)) == NULL |
309 |
|| (saved_max_address = SaveIPv6Address((struct in6_addr *) max_address))) return -ENOMEM; |
|| (saved_max_address = SaveIPv6Address((struct in6_addr *) max_address)) == NULL) return -ENOMEM; |
310 |
} |
} |
311 |
mutex_lock(&domain_acl_lock); |
mutex_lock(&domain_acl_lock); |
312 |
if (!is_delete) { |
if (!is_delete) { |
313 |
list_for_each_entry(ptr, &domain->acl_info_list, list) { |
list1_for_each_entry(ptr, &domain->acl_info_list, list) { |
314 |
acl = container_of(ptr, struct ip_network_acl_record, head); |
acl = container_of(ptr, struct ip_network_acl_record, head); |
315 |
if (ptr->type == TYPE_IP_NETWORK_ACL && acl->operation_type == operation && acl->record_type == record_type && ptr->cond == condition && acl->min_port == min_port && max_port == acl->max_port) { |
if (ptr->type == TYPE_IP_NETWORK_ACL && acl->operation_type == operation && acl->record_type == record_type && ptr->cond == condition && acl->min_port == min_port && max_port == acl->max_port) { |
316 |
if (record_type == IP_RECORD_TYPE_ADDRESS_GROUP) { |
if (record_type == IP_RECORD_TYPE_ADDRESS_GROUP) { |
357 |
error = AddDomainACL(domain, &acl->head); |
error = AddDomainACL(domain, &acl->head); |
358 |
} else { |
} else { |
359 |
error = -ENOENT; |
error = -ENOENT; |
360 |
list_for_each_entry(ptr, &domain->acl_info_list, list) { |
list1_for_each_entry(ptr, &domain->acl_info_list, list) { |
361 |
acl = container_of(ptr, struct ip_network_acl_record, head); |
acl = container_of(ptr, struct ip_network_acl_record, head); |
362 |
if (ptr->type != TYPE_IP_NETWORK_ACL || ptr->is_deleted || acl->operation_type != operation || acl->record_type != record_type || ptr->cond != condition || acl->min_port != min_port || acl->max_port != max_port) continue; |
if (ptr->type != TYPE_IP_NETWORK_ACL || ptr->is_deleted || acl->operation_type != operation || acl->record_type != record_type || ptr->cond != condition || acl->min_port != min_port || acl->max_port != max_port) continue; |
363 |
if (record_type == IP_RECORD_TYPE_ADDRESS_GROUP) { |
if (record_type == IP_RECORD_TYPE_ADDRESS_GROUP) { |
385 |
const u32 ip = ntohl(*address); /* using host byte order to allow u32 comparison than memcmp().*/ |
const u32 ip = ntohl(*address); /* using host byte order to allow u32 comparison than memcmp().*/ |
386 |
bool found = 0; |
bool found = 0; |
387 |
if (!CheckCCSFlags(CCS_TOMOYO_MAC_FOR_NETWORK)) return 0; |
if (!CheckCCSFlags(CCS_TOMOYO_MAC_FOR_NETWORK)) return 0; |
388 |
list_for_each_entry(ptr, &domain->acl_info_list, list) { |
list1_for_each_entry(ptr, &domain->acl_info_list, list) { |
389 |
struct ip_network_acl_record *acl; |
struct ip_network_acl_record *acl; |
390 |
acl = container_of(ptr, struct ip_network_acl_record, head); |
acl = container_of(ptr, struct ip_network_acl_record, head); |
391 |
if (ptr->type != TYPE_IP_NETWORK_ACL || ptr->is_deleted || acl->operation_type != operation || port < acl->min_port || acl->max_port < port || CheckCondition(ptr->cond, NULL)) continue; |
if (ptr->type != TYPE_IP_NETWORK_ACL || ptr->is_deleted || acl->operation_type != operation || port < acl->min_port || acl->max_port < port || CheckCondition(ptr->cond, NULL)) continue; |