-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add ct-zone filtering inat src host #16
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,11 @@ | |
|
||
#include "log.h" | ||
|
||
|
||
enum filter_type { | ||
FILTER_BY_CT_ZONE, | ||
FILTER_BY_IP | ||
}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: add line after this line. |
||
/** | ||
* Represents the config options which are used globally in the application. | ||
*/ | ||
|
@@ -29,7 +34,11 @@ struct lmct_config { | |
|
||
extern struct lmct_config lmct_conf; | ||
|
||
extern enum filter_type fltr_type; | ||
void | ||
init_lmct_config(); | ||
|
||
void | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. on another note, let us move this to common.h and the corresponding implementation in common.c instead.
|
||
populate_filter_type(enum filter_type); | ||
|
||
#endif /* LMCT_CONFIG_H */ |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -71,3 +71,38 @@ create_hashtable_from_ip_list(const char *ip_list[], int num_ips) | |
|
||
return ht; | ||
} | ||
|
||
/** | ||
* Creates hashtable from CT Zones list. | ||
* | ||
* This function allocates a hashtable which converts the string | ||
* based ct zones into uint32_t format and store them into hashtable | ||
* for fast lookup operations. They key for the hashtable is the uint32_t | ||
* ct zones, and value is ignored (kept as 1). | ||
* | ||
* Args: | ||
* @ct_zones_list list of string CT Zones | ||
* @num_ct_zones number of CT Zones in the list | ||
* | ||
* Returns: | ||
* Resulting hashtable containing CT Zones as key | ||
* In case memory allocation fails, the process is terminated. | ||
* NULL, in case an invalid IP address is present in the ip_list. | ||
*/ | ||
GHashTable * | ||
create_hashtable_from_ct_zones_list(const char *ct_zones_list[], | ||
int num_ct_zones) | ||
{ | ||
int i; | ||
GHashTable *ht; | ||
|
||
ht = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL); | ||
for (i = 0; i < num_ct_zones; i++) { | ||
LOG(VERBOSE, "%s : Trying to insert %u ct_zone into ht", __func__, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you can remove this log. or define: int ct_zone = atoi(ct_zones_list[i]) |
||
atoi(ct_zones_list[i])); | ||
g_hash_table_insert(ht, GUINT_TO_POINTER(atoi(ct_zones_list[i])), | ||
GINT_TO_POINTER(1)); | ||
} | ||
|
||
return ht; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,6 +34,7 @@ | |
#include "conntrack_entry.h" | ||
#include "conntrack_store.h" | ||
#include "ct_delete_args.h" | ||
#include "lmct_config.h" | ||
#include "log.h" | ||
|
||
/* Type definition for CT dump callbacks. */ | ||
|
@@ -105,10 +106,12 @@ validate_ct_entry(enum nf_conntrack_msg_type type, struct nf_conntrack *ct) | |
return false; | ||
} | ||
|
||
if (nfct_attr_is_set(ct, ATTR_ZONE) > 0 || | ||
nfct_attr_is_set(ct, ATTR_ORIG_ZONE) > 0 || | ||
nfct_attr_is_set(ct, ATTR_REPL_ZONE) > 0) { | ||
return false; | ||
if(fltr_type == FILTER_BY_IP) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit space after if |
||
if (nfct_attr_is_set(ct, ATTR_ZONE) > 0 || | ||
nfct_attr_is_set(ct, ATTR_ORIG_ZONE) > 0 || | ||
nfct_attr_is_set(ct, ATTR_REPL_ZONE) > 0) { | ||
return false; | ||
} | ||
} | ||
|
||
return true; | ||
|
@@ -131,7 +134,7 @@ validate_ct_entry(enum nf_conntrack_msg_type type, struct nf_conntrack *ct) | |
* @type nf message type. | ||
* @ct pointer to the conntrack entry received. | ||
* @data pointer to the data sent to the callback. In this case it is | ||
* ips_to_migrate hashtable. | ||
* struct ct_events_targs. | ||
* | ||
* Returns: | ||
* NFCT_CB_CONTINUE representing continue processing of | ||
|
@@ -144,19 +147,28 @@ conntrack_dump_callback(enum nf_conntrack_msg_type type, | |
{ | ||
bool is_entry_useful; | ||
GHashTable *ips_to_migrate; | ||
GHashTable *ct_zones_to_migrate; | ||
struct in_addr *src_addr, *dst_addr; | ||
|
||
ips_to_migrate = data; | ||
struct ct_events_targs *cb_args = (struct ct_events_targs *)data; | ||
uint16_t zone; | ||
|
||
if (!validate_ct_entry(type, ct)) { | ||
return NFCT_CB_CONTINUE; | ||
} | ||
|
||
src_addr = (struct in_addr *)nfct_get_attr(ct, ATTR_ORIG_IPV4_SRC); | ||
dst_addr = (struct in_addr *)nfct_get_attr(ct, ATTR_ORIG_IPV4_DST); | ||
|
||
is_entry_useful = is_src_or_dst_in_hashtable(src_addr, dst_addr, | ||
ips_to_migrate); | ||
if (fltr_type == FILTER_BY_IP) { | ||
ips_to_migrate = (GHashTable *)cb_args->ips_to_migrate; | ||
src_addr = (struct in_addr *)nfct_get_attr(ct, ATTR_ORIG_IPV4_SRC); | ||
dst_addr = (struct in_addr *)nfct_get_attr(ct, ATTR_ORIG_IPV4_DST); | ||
|
||
is_entry_useful = is_src_or_dst_in_hashtable(src_addr, dst_addr, | ||
ips_to_migrate); | ||
} else { | ||
zone = nfct_get_attr_u16(ct, ATTR_ZONE); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you need to first check if the zone is actually present in the entry. |
||
ct_zones_to_migrate = (GHashTable *)cb_args->ct_zones_to_migrate; | ||
is_entry_useful = g_hash_table_contains(ct_zones_to_migrate, | ||
GUINT_TO_POINTER(zone)); | ||
} | ||
|
||
if (is_entry_useful) { | ||
update_conntrack_store(conn_store, ct, type); | ||
|
@@ -208,18 +220,19 @@ _conntrack_dump(struct nfct_handle *h, dump_cb cb, void *cb_args) | |
* | ||
* Args: | ||
* @handle handle to the netlink socket. | ||
* @ips_to_migrate IP addresses to be used for filtering the CT entries. | ||
* @struct ct_events_targs struct ct_events_targs ct_zones_to_migrate or | ||
* ips_to_migrate need to be present depending upon filtr_type set. | ||
* | ||
* Returns: | ||
* 0 if the operation was successful. -1 otherwise. | ||
*/ | ||
int | ||
get_conntrack_dump(struct nfct_handle *handle, GHashTable *ips_to_migrate) | ||
get_conntrack_dump(struct nfct_handle *handle, struct ct_events_targs *data) | ||
{ | ||
int ret; | ||
|
||
LOG(INFO, "%s: Conntrack dump start", __func__); | ||
ret = _conntrack_dump(handle, conntrack_dump_callback, ips_to_migrate); | ||
ret = _conntrack_dump(handle, conntrack_dump_callback, data); | ||
LOG(INFO, "%s: Conntrack dump end", __func__); | ||
|
||
return ret; | ||
|
@@ -235,8 +248,8 @@ get_conntrack_dump(struct nfct_handle *handle, GHashTable *ips_to_migrate) | |
* | ||
* Args: | ||
* @nlh pointer to the netlink message header. | ||
* @data pointer to the data sent to the callback. Here it's the | ||
* stop_flag which indicates whether to stop processing further events. | ||
* @data pointer to the data sent to the callback. Here it's the struct | ||
* ct_events_targs. | ||
* | ||
* Returns: | ||
* - MNL_CB_STOP if we need to stop further event processing. | ||
|
@@ -249,8 +262,10 @@ conntrack_events_callback(const struct nlmsghdr *nlh, void *data) | |
enum nf_conntrack_msg_type type = NFCT_T_UNKNOWN; | ||
struct nf_conntrack *ct; | ||
bool *stop_flag; | ||
|
||
stop_flag = (bool *)data; | ||
GHashTable *ct_zones_to_migrate; | ||
struct ct_events_targs *cb_args = (struct ct_events_targs *)data; | ||
stop_flag = (bool *)cb_args->stop_flag; | ||
ct_zones_to_migrate = (GHashTable *)cb_args->ct_zones_to_migrate; | ||
if (*stop_flag) { | ||
return MNL_CB_STOP; | ||
} | ||
|
@@ -280,19 +295,29 @@ conntrack_events_callback(const struct nlmsghdr *nlh, void *data) | |
return MNL_CB_OK; | ||
} | ||
|
||
update_conntrack_store(conn_store, ct, type); | ||
bool add_to_conntrack_store = true; | ||
if( fltr_type == FILTER_BY_CT_ZONE ){ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fix spacing. |
||
uint16_t zone; | ||
zone = nfct_get_attr_u16(ct, ATTR_ZONE); | ||
gboolean ct_contains_zone; | ||
ct_contains_zone = g_hash_table_contains(ct_zones_to_migrate, | ||
GUINT_TO_POINTER(zone)); | ||
if (!ct_contains_zone) { | ||
add_to_conntrack_store = false; | ||
} | ||
} | ||
|
||
if (add_to_conntrack_store){ | ||
LOG(INFO, "%s : Updating entry in conntrack store", __func__); | ||
update_conntrack_store(conn_store, ct, type); | ||
} | ||
nfct_destroy(ct); | ||
|
||
return MNL_CB_OK; | ||
} | ||
|
||
/** | ||
* Creates a nfct_filter for the IP addresses to migrate. | ||
* | ||
* Args: | ||
* @ips pointer to the GHashTable containing IP addresses. | ||
* @is_src_filter bool representing if filter is to be applied on the | ||
* src field of CT entries. | ||
* Creates a nfct_filter depending upin nfct_filter. | ||
* | ||
* Returns: | ||
* pointer to the nfct_filter if success, NULL otherwise. | ||
|
@@ -301,36 +326,37 @@ static struct nfct_filter * | |
create_nfct_filter(GHashTable *ips, bool is_src_filter) | ||
{ | ||
struct nfct_filter *filter; | ||
GHashTableIter iter; | ||
gpointer key = NULL; | ||
|
||
filter = nfct_filter_create(); | ||
if (filter == NULL) { | ||
LOG(ERROR, "%s: Failed to create a filter. %s", __func__, | ||
LOG(ERROR, "%s: Failed to create a filter for ct zones. %s", __func__, | ||
strerror(errno)); | ||
exit(EXIT_FAILURE); | ||
} | ||
|
||
g_hash_table_iter_init(&iter, ips); | ||
while (g_hash_table_iter_next(&iter, &key, NULL)) { | ||
uint32_t ip = GPOINTER_TO_UINT(key); | ||
|
||
struct nfct_filter_ipv4 filter_ipv4 = { | ||
.addr = ntohl(ip), | ||
.mask = 0xffffffff, | ||
}; | ||
if (fltr_type == FILTER_BY_IP) { | ||
GHashTableIter iter; | ||
gpointer key; | ||
|
||
g_hash_table_iter_init(&iter, ips); | ||
while (g_hash_table_iter_next(&iter, &key, NULL)) { | ||
uint32_t ip = GPOINTER_TO_UINT(key); | ||
struct nfct_filter_ipv4 filter_ipv4 = { | ||
.addr = ntohl(ip), | ||
.mask = 0xffffffff, | ||
}; | ||
|
||
enum nfct_filter_attr filter_type; | ||
if (is_src_filter) { | ||
filter_type = NFCT_FILTER_SRC_IPV4; | ||
} else { | ||
filter_type = NFCT_FILTER_DST_IPV4; | ||
} | ||
|
||
enum nfct_filter_attr filter_type; | ||
if (is_src_filter) { | ||
filter_type = NFCT_FILTER_SRC_IPV4; | ||
} else { | ||
filter_type = NFCT_FILTER_DST_IPV4; | ||
nfct_filter_add_attr(filter, filter_type, &filter_ipv4); | ||
nfct_filter_set_logic(filter, filter_type, NFCT_FILTER_LOGIC_POSITIVE); | ||
} | ||
|
||
nfct_filter_add_attr(filter, filter_type, &filter_ipv4); | ||
nfct_filter_set_logic(filter, filter_type, NFCT_FILTER_LOGIC_POSITIVE); | ||
} | ||
|
||
return filter; | ||
} | ||
|
||
|
@@ -359,10 +385,11 @@ create_nfct_filter(GHashTable *ips, bool is_src_filter) | |
*/ | ||
int | ||
listen_for_conntrack_events(struct mnl_socket *nl, | ||
GHashTable *ips_to_migrate, | ||
bool is_src_filter, | ||
bool *stop_flag) | ||
struct ct_events_targs *ct_events_targs) | ||
{ | ||
GHashTable *ips_to_migrate = ct_events_targs->ips_to_migrate; | ||
bool is_src_filter = ct_events_targs->is_src; | ||
bool *stop_flag = ct_events_targs->stop_flag; | ||
int ret = 0; | ||
int fd; | ||
char buf[MNL_SOCKET_BUFFER_SIZE]; | ||
|
@@ -375,9 +402,8 @@ listen_for_conntrack_events(struct mnl_socket *nl, | |
}; | ||
|
||
fd = mnl_socket_get_fd(nl); | ||
|
||
// Attach the IP based filter to the socket. | ||
filter = create_nfct_filter(ips_to_migrate, is_src_filter); | ||
// Attach the filter to the socket. | ||
filter_attach_ret = nfct_filter_attach(fd, filter); | ||
if (filter_attach_ret == -1) { | ||
LOG(ERROR, "%s: Failed to attach filter to the socket. %s", __func__, | ||
|
@@ -427,7 +453,8 @@ listen_for_conntrack_events(struct mnl_socket *nl, | |
break; | ||
} | ||
|
||
ret = mnl_cb_run(buf, ret, 0, 0, conntrack_events_callback, stop_flag); | ||
ret = mnl_cb_run(buf, ret, 0, 0, conntrack_events_callback, | ||
ct_events_targs); | ||
if (ret == MNL_CB_STOP) { | ||
LOG(INFO, "%s: Stopping the callback", __func__); | ||
break; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -95,7 +95,6 @@ conntrack_store_insert(struct conntrack_store *conn_store, | |
{ | ||
uint32_t ct_id; | ||
struct conntrack_entry *ct_entry; | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. unrelated. |
||
ct_id = nfct_get_attr_u32(ct, ATTR_ID); | ||
if (ct_id == 0) { | ||
LOG(WARNING, "%s: CT with ID = 0 received!", __func__); | ||
|
@@ -116,8 +115,6 @@ conntrack_store_insert(struct conntrack_store *conn_store, | |
} | ||
|
||
/** | ||
* Deletes the entry from the conntrack_store. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ??? |
||
* | ||
* This function extracts the ctid from the ct argument and then removes the | ||
* entry corresponding to the Ctid from the hashtable. Even if the entry is | ||
* not present in hashtable, the function treats it as a success. | ||
|
@@ -161,6 +158,7 @@ static void | |
handle_new_event(struct conntrack_store *conn_store, | ||
struct nf_conntrack *ct) | ||
{ | ||
LOG(INFO, "Mansi: %s", __func__); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove from everywhere. |
||
conntrack_store_insert(conn_store, ct); | ||
} | ||
|
||
|
@@ -185,6 +183,7 @@ handle_update_event(struct conntrack_store *conn_store, | |
struct conntrack_entry *ct_entry; | ||
struct conntrack_entry *res_ct_entry; | ||
|
||
LOG(INFO, "Mansi: %s", __func__); | ||
ct_id = nfct_get_attr_u32(ct, ATTR_ID); | ||
if (ct_id == 0) { | ||
LOG(WARNING, "%s: ct entry with 0 id received. Skipping.", __func__); | ||
|
@@ -223,6 +222,7 @@ static void | |
handle_destroy_event(struct conntrack_store *conn_store, | ||
struct nf_conntrack *ct) | ||
{ | ||
LOG(INFO, "Mansi: %s", __func__); | ||
int ret = conntrack_store_remove(conn_store, ct); | ||
if (ret == -1) { | ||
LOG(WARNING, "%s: CT entry with 0 id received. Skipping.", __func__); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing documentation.