Skip to content
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

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions include/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,7 @@
GHashTable *
create_hashtable_from_ip_list(const char *[], int);

GHashTable *
create_hashtable_from_ct_zones_list(const char *[], int);

#endif /* COMMON_H */
17 changes: 11 additions & 6 deletions include/conntrack.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,22 @@
* the conntrack events.
*/
struct ct_events_targs {
pthread_t tid; // thread ID
GHashTable *ips_to_migrate; // IPs for which CT events needs to be listened
bool *stop_flag; // Flag when True, stop listening for CT events
bool is_src; // Flag indicating whether the args are for src based events
pthread_t tid; // thread ID
GHashTable *ips_to_migrate; // IPs for which CT events needs to be
// listened
GHashTable *ct_zones_to_migrate; // CT Zones for which events needs to
// be listened
bool *stop_flag; // Flag when True, stop listening for
// CT events
bool is_src; // Flag indicating whether the args are
// for src based events
};

int
get_conntrack_dump(struct nfct_handle *, GHashTable *);
get_conntrack_dump(struct nfct_handle *, struct ct_events_targs *);

int
listen_for_conntrack_events(struct mnl_socket *, GHashTable *, bool, bool *);
listen_for_conntrack_events(struct mnl_socket *, struct ct_events_targs *);

void
append_ct_to_batch(char *, struct nf_conntrack *, uint32_t *, int);
Expand Down
9 changes: 9 additions & 0 deletions include/lmct_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@

#include "log.h"


enum filter_type {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing documentation.

FILTER_BY_CT_ZONE,
FILTER_BY_IP
};
Copy link
Collaborator

Choose a reason for hiding this comment

The 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.
*/
Expand All @@ -29,7 +34,11 @@ struct lmct_config {

extern struct lmct_config lmct_conf;

extern enum filter_type fltr_type;
void
init_lmct_config();

void
Copy link
Collaborator

Choose a reason for hiding this comment

The 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.

lmct_config is basically something which is read from the conf file and populated.
filter_type is read from args instead.

populate_filter_type(enum filter_type);

#endif /* LMCT_CONFIG_H */
35 changes: 35 additions & 0 deletions src/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -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__,
Copy link
Collaborator

Choose a reason for hiding this comment

The 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])
and reuse in L101 and L103

atoi(ct_zones_list[i]));
g_hash_table_insert(ht, GUINT_TO_POINTER(atoi(ct_zones_list[i])),
GINT_TO_POINTER(1));
}

return ht;
}
131 changes: 79 additions & 52 deletions src/conntrack.c
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand Down Expand Up @@ -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) {
Copy link
Collaborator

Choose a reason for hiding this comment

The 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;
Expand All @@ -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
Expand All @@ -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);
Copy link
Collaborator

Choose a reason for hiding this comment

The 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);
Expand Down Expand Up @@ -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;
Expand All @@ -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.
Expand All @@ -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;
}
Expand Down Expand Up @@ -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 ){
Copy link
Collaborator

Choose a reason for hiding this comment

The 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.
Expand All @@ -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;
}

Expand Down Expand Up @@ -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];
Expand All @@ -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__,
Expand Down Expand Up @@ -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;
Expand Down
6 changes: 3 additions & 3 deletions src/conntrack_store.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ conntrack_store_insert(struct conntrack_store *conn_store,
{
uint32_t ct_id;
struct conntrack_entry *ct_entry;

Copy link
Collaborator

Choose a reason for hiding this comment

The 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__);
Expand All @@ -116,8 +115,6 @@ conntrack_store_insert(struct conntrack_store *conn_store,
}

/**
* Deletes the entry from the conntrack_store.
Copy link
Collaborator

Choose a reason for hiding this comment

The 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.
Expand Down Expand Up @@ -161,6 +158,7 @@ static void
handle_new_event(struct conntrack_store *conn_store,
struct nf_conntrack *ct)
{
LOG(INFO, "Mansi: %s", __func__);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove from everywhere.

conntrack_store_insert(conn_store, ct);
}

Expand All @@ -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__);
Expand Down Expand Up @@ -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__);
Expand Down
Loading
Loading