those are not used just yet.
Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
#include "transports.h"
#include "host.h"
#include "threads_common.h"
+#include "links_acl.h"
+
+static void _link_del_all_acl(knet_handle_t knet_h, int sock)
+{
+ check_rmall(&knet_h->knet_transport_fd_tracker[sock].match_entry);
+}
+
+static int _link_add_default_acl(knet_handle_t knet_h, struct knet_link *kh_link)
+{
+ int err = -1;
+
+ switch(transport_get_proto(knet_h, kh_link->transport_type)) {
+ case LOOPBACK:
+ /*
+ * loopback does not require access lists
+ */
+ err = 0;
+ break;
+ case IP_PROTO:
+ err = ipcheck_addip(&knet_h->knet_transport_fd_tracker[kh_link->outsock].match_entry,
+ &kh_link->dst_addr, &kh_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT);
+ break;
+ default:
+ break;
+ }
+
+ return err;
+}
+
+static int _link_rm_default_acl(knet_handle_t knet_h, struct knet_link *kh_link)
+{
+ int err = -1;
+
+ switch(transport_get_proto(knet_h, kh_link->transport_type)) {
+ case LOOPBACK:
+ /*
+ * loopback does not require access lists
+ */
+ err = 0;
+ break;
+ case IP_PROTO:
+ err = ipcheck_rmip(&knet_h->knet_transport_fd_tracker[kh_link->outsock].match_entry,
+ &kh_link->dst_addr, &kh_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT);
+ break;
+ default:
+ break;
+ }
+
+ return err;
+}
int _link_updown(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_id,
unsigned int enabled, unsigned int connected)
err = -1;
goto exit_unlock;
}
+
+ /*
+ * we can only configure default access lists if we know both endpoints
+ */
+ if (link->dynamic == KNET_LINK_STATIC) {
+ log_debug(knet_h, KNET_SUB_LINK, "Configuring default access lists for host: %u link: %u",
+ host_id, link_id);
+ if (_link_add_default_acl(knet_h, link) < 0) {
+ log_warn(knet_h, KNET_SUB_LINK, "Failed to configure default access lists for host: %u link: %u", host_id, link_id);
+ savederrno = errno;
+ err = -1;
+ goto exit_unlock;
+ }
+ }
+
link->configured = 1;
log_debug(knet_h, KNET_SUB_LINK, "host: %u link: %u is configured",
host_id, link_id);
int savederrno = 0, err = 0;
struct knet_host *host;
struct knet_link *link;
+ int sock;
if (!knet_h) {
errno = EINVAL;
goto exit_unlock;
}
+ /*
+ * remove well known access lists here.
+ * After the transport has done clearing the config,
+ * then we can remove any leftover access lists if the link
+ * is no longer in use.
+ */
+ if (link->dynamic == KNET_LINK_STATIC) {
+ if (_link_rm_default_acl(knet_h, link) < 0) {
+ err = -1;
+ savederrno = EBUSY;
+ log_err(knet_h, KNET_SUB_LINK, "Host %u link %u: unable to remove default access list",
+ host_id, link_id);
+ goto exit_unlock;
+ }
+ }
+
+ /*
+ * cache it for later as we don't know if the transport
+ * will clear link info during clear_config.
+ */
+ sock = link->outsock;
+
if ((transport_link_clear_config(knet_h, link) < 0) &&
(errno != EBUSY)) {
savederrno = errno;
goto exit_unlock;
}
+ /*
+ * remove any other access lists when the socket is no
+ * longer in use by the transport.
+ */
+ if (knet_h->knet_transport_fd_tracker[sock].transport == KNET_MAX_TRANSPORTS) {
+ _link_del_all_acl(knet_h, sock);
+ }
+
memset(link, 0, sizeof(struct knet_link));
link->link_id = link_id;
* Routines to manuipulate access lists
*/
-void ipcheck_clear(struct acl_match_entry **match_entry_head)
+void check_rmall(struct acl_match_entry **match_entry_head)
{
struct acl_match_entry *next_match_entry;
struct acl_match_entry *match_entry = *match_entry_head;
*match_entry_head = NULL;
}
+static struct acl_match_entry *ipcheck_findmatch(struct acl_match_entry **match_entry_head,
+ struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
+ check_type_t type, check_acceptreject_t acceptreject)
+{
+ struct acl_match_entry *match_entry = *match_entry_head;
+
+ while (match_entry) {
+ if ((!memcmp(&match_entry->addr1, ip1, sizeof(struct sockaddr_storage))) &&
+ (!memcmp(&match_entry->addr2, ip2, sizeof(struct sockaddr_storage))) &&
+ (match_entry->type == type) &&
+ (match_entry->acceptreject == acceptreject)) {
+ return match_entry;
+ }
+ match_entry = match_entry->next;
+ }
+
+ return NULL;
+}
+
+int ipcheck_rmip(struct acl_match_entry **match_entry_head,
+ struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
+ check_type_t type, check_acceptreject_t acceptreject)
+{
+ struct acl_match_entry *next_match_entry = NULL;
+ struct acl_match_entry *rm_match_entry;
+ struct acl_match_entry *match_entry = *match_entry_head;
+
+ rm_match_entry = ipcheck_findmatch(match_entry_head, ip1, ip2, type, acceptreject);
+ if (!rm_match_entry) {
+ return -1;
+ }
+
+ while (match_entry) {
+ next_match_entry = match_entry->next;
+ /*
+ * we are removing the list head, be careful
+ */
+ if (rm_match_entry == match_entry) {
+ *match_entry_head = next_match_entry;
+ free(match_entry);
+ break;
+ }
+ /*
+ * the next one is the one we need to remove
+ */
+ if (rm_match_entry == next_match_entry) {
+ match_entry->next = next_match_entry->next;
+ free(next_match_entry);
+ break;
+ }
+ match_entry = next_match_entry;
+ }
+
+ return 0;
+}
+
int ipcheck_addip(struct acl_match_entry **match_entry_head,
struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
check_type_t type, check_acceptreject_t acceptreject)
(ip1->ss_family != ip2->ss_family))
return -1;
+ if (ipcheck_findmatch(match_entry_head, ip1, ip2, type, acceptreject) != NULL) {
+ return -1;
+ }
+
new_match_entry = malloc(sizeof(struct acl_match_entry));
if (!new_match_entry)
return -1;
int ipcheck_validate(struct acl_match_entry **match_entry_head, struct sockaddr_storage *checkip);
-void ipcheck_clear(struct acl_match_entry **match_entry_head);
-
int ipcheck_addip(struct acl_match_entry **match_entry_head,
struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
check_type_t type, check_acceptreject_t acceptreject);
+int ipcheck_rmip(struct acl_match_entry **match_entry_head,
+ struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
+ check_type_t type, check_acceptreject_t acceptreject);
+
+void check_rmall(struct acl_match_entry **match_entry_head);
#endif
struct sockaddr_storage addr1;
struct sockaddr_storage addr2;
- ipcheck_clear(&match_entry_v4);
- ipcheck_clear(&match_entry_v6);
+ check_rmall(&match_entry_v4);
+ check_rmall(&match_entry_v6);
filterfile = fopen("int_links_acl.txt", "r");
if (!filterfile) {
}
}
- ipcheck_clear(&match_entry_v4);
- ipcheck_clear(&match_entry_v6);
+ check_rmall(&match_entry_v4);
+ check_rmall(&match_entry_v6);
return 0;
}