From a7976ff92948abd04ee3f4b4ec67a1539ea680ec Mon Sep 17 00:00:00 2001 From: Mansi Sharma Date: Mon, 16 Sep 2024 06:26:38 +0000 Subject: [PATCH 1/2] add source host changes --- include/common.h | 3 + include/conntrack.h | 17 ++- include/lmct_config.h | 9 ++ src/common.c | 35 ++++++ src/conntrack.c | 131 +++++++++++++-------- src/conntrack_store.c | 6 +- src/lmct_config.c | 6 + src/main.c | 263 +++++++++++++++++++++++++++++++++--------- 8 files changed, 357 insertions(+), 113 deletions(-) diff --git a/include/common.h b/include/common.h index 69019d9..f986625 100644 --- a/include/common.h +++ b/include/common.h @@ -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 */ diff --git a/include/conntrack.h b/include/conntrack.h index 910da99..e65ed19 100644 --- a/include/conntrack.h +++ b/include/conntrack.h @@ -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); diff --git a/include/lmct_config.h b/include/lmct_config.h index c6d3f6c..97849ba 100644 --- a/include/lmct_config.h +++ b/include/lmct_config.h @@ -19,6 +19,11 @@ #include "log.h" + +enum filter_type { + FILTER_BY_CT_ZONE, + FILTER_BY_IP +}; /** * 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 +populate_filter_type(enum filter_type); + #endif /* LMCT_CONFIG_H */ diff --git a/src/common.c b/src/common.c index e79ee3b..ef88044 100644 --- a/src/common.c +++ b/src/common.c @@ -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__, + atoi(ct_zones_list[i])); + g_hash_table_insert(ht, GUINT_TO_POINTER(atoi(ct_zones_list[i])), + GINT_TO_POINTER(1)); + } + + return ht; +} diff --git a/src/conntrack.c b/src/conntrack.c index 5097675..6fa2c32 100644 --- a/src/conntrack.c +++ b/src/conntrack.c @@ -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) { + 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,21 +147,32 @@ 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); + LOG(INFO, "Mansi: %s %s", __func__, is_entry_useful ? "true": false); + } else { + zone = nfct_get_attr_u16(ct, ATTR_ZONE); + 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) { + LOG(INFO, "Mansi: adding for zone %u %s", zone, __func__); update_conntrack_store(conn_store, ct, type); } @@ -208,18 +222,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 +250,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 +264,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 +297,27 @@ conntrack_events_callback(const struct nlmsghdr *nlh, void *data) return MNL_CB_OK; } - update_conntrack_store(conn_store, ct, type); + uint16_t zone; + zone = nfct_get_attr_u16(ct, ATTR_ZONE); + + bool add_to_conntrack_store = true; + if( fltr_type == FILTER_BY_CT_ZONE && + !g_hash_table_contains(ct_zones_to_migrate, GUINT_TO_POINTER(zone))){ + add_to_conntrack_store = false; + } + + if (add_to_conntrack_store){ + LOG(INFO, "%s : Updating zone %u entry in conntrack store", __func__, + zone); + 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. @@ -306,31 +331,36 @@ create_nfct_filter(GHashTable *ips, bool is_src_filter) 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) { + LOG(INFO, "Mansi: Setting filter for IPS %s", __func__); + 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); + LOG(INFO, "adding ip into filter %u %s", key, __func__); + 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 +389,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 +406,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 +457,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; diff --git a/src/conntrack_store.c b/src/conntrack_store.c index c677955..2db3efe 100644 --- a/src/conntrack_store.c +++ b/src/conntrack_store.c @@ -95,7 +95,6 @@ conntrack_store_insert(struct conntrack_store *conn_store, { uint32_t ct_id; struct conntrack_entry *ct_entry; - 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. - * * 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__); 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__); diff --git a/src/lmct_config.c b/src/lmct_config.c index fae27a0..cbe760e 100644 --- a/src/lmct_config.c +++ b/src/lmct_config.c @@ -31,6 +31,7 @@ struct lmct_config lmct_conf = { .max_entries_to_migrate = MAX_ENTRIES_TO_MIGRATE }; +enum filter_type fltr_type; /** * Validate the level option read from config file. * @@ -132,6 +133,11 @@ populate_max_entries_to_migrate(GKeyFile *key_file, struct lmct_config *conf) conf->max_entries_to_migrate = MAX_ENTRIES_TO_MIGRATE; } +void +populate_filter_type(enum filter_type ft) { + fltr_type = ft; +} + /** * Reads the configuration file and initialises the config options for the * application. diff --git a/src/main.c b/src/main.c index 725105e..bb2c787 100644 --- a/src/main.c +++ b/src/main.c @@ -59,6 +59,8 @@ #define HELPER_ID_ARG_INDEX 2 #define NUM_IP_ADDR_ARG_INDEX 3 #define IP_ADDR_LIST_ARG_INDEX 4 +#define NUM_CT_ZONES_ARG_INDEX 4 +#define CT_ZONES_LIST_ARG_INDEX 5 #define MAX_IP_ADDRESSES_SUPPORTED 127 @@ -114,8 +116,7 @@ pthread_wrapper_ct_events(void *data) return NULL; } - listen_for_conntrack_events(nl, targs->ips_to_migrate, - targs->is_src, targs->stop_flag); + listen_for_conntrack_events(nl, targs); mnl_socket_close(nl); LOG(INFO, "%s: Finished conntrack events. is_src = %d", __func__, @@ -130,9 +131,10 @@ pthread_wrapper_ct_events(void *data) * * Args: * @ips_to_migrate IP addresses used to filter the required CT entries. + * @ct_zones_to_migrate CT Zones used to filter the required CT entries. */ static void -dump_conntrack(GHashTable *ips_to_migrate) +dump_conntrack(struct ct_events_targs *ct_events_targs) { struct nfct_handle *handle; @@ -143,36 +145,105 @@ dump_conntrack(GHashTable *ips_to_migrate) LOG(ERROR, "%s: nfct_open failed. %s", __func__, strerror(errno)); return; } - get_conntrack_dump(handle, ips_to_migrate); + get_conntrack_dump(handle, ct_events_targs); nfct_close(handle); } /** - * Start threads required for save mode of operation. - * - * Following things are performed in the save mode: - * 1. Conntrack delete thread is started which waits till Clear IPC is called. - * 2. Conntrack events threads are started to filter events for the IP - * addresses present in the ips_to_migrate. If any update is received for a - * non-exisitent entry, it is treated as NEW since it contains the base five - * tuple information required to identify flow. Similarly, if a destroy - * event is received for a non-existent entry, it is ignored. - * 3. Finally, Conntrack dump is taken from the kernel to get all the live - * flows in the system. - * - * The above workflow is used to maintain a local copy of the CT entries for - * the VM. - * - * Args: - * @ips_to_migrate Hashtable of IP addresses for which CT entries - * have to be migrated. - * @stop_flag flag used by thread to exit after dbus operations. - * - * Returns: - * 0 in case of success, -1 otherwise - */ +* Start threads required for save mode of operation when filter type is +* FILTER_BY_CT_ZONE. +* +* Following things are performed in the save mode: +* 1. Conntrack events threads are started to filter events for the CT +* zones present in the ct_zones_to_migrate. If any update is received for a +* non-exisitent entry, it is treated as NEW since it contains the base five +* tuple information required to identify flow. Similarly, if a destroy +* event is received for a non-existent entry, it is ignored. +* 2. Finally, Conntrack dump is taken from the kernel to get all the live +* flows in the system. +* +* The above workflow is used to maintain a local copy of the CT entries for +* the VM. +* +* Args: +* @ct_zones_to_migrate Hashtable of CT zones for which CT entries +* have to be migrated. +* @stop_flag flag used by thread to exit after dbus operations. +* +* Returns: +* 0 in case of success, -1 otherwise +*/ static int -start_in_save_mode(GHashTable *ips_to_migrate, bool *stop_flag) +start_in_save_mode_for_ct_zones(GHashTable *ct_zones_to_migrate, + bool *stop_flag) +{ + int ret; + uint32_t num_ct_zones; + struct ct_events_targs *targs; + + num_ct_zones = g_hash_table_size(ct_zones_to_migrate); + + if (num_ct_zones == 0) { + LOG(INFO, "%s: Not starting any save mode threads since number of" + "ct-zones is 0", __func__); + return 0; + } + + targs = g_malloc0(sizeof(struct ct_events_targs)); + targs->ct_zones_to_migrate = ct_zones_to_migrate; + targs->stop_flag = stop_flag; + targs->is_src = true; + ret = pthread_create(&targs->tid, NULL, &pthread_wrapper_ct_events, + (void *)targs); + if (ret != 0) { + LOG(ERROR, "%s: src events thread creation failed. %s", __func__, + strerror(ret)); + return -1; + } + ret = pthread_setname_np(targs->tid, "ct_events_src"); + if (ret != 0) { + LOG(WARNING, "%s: Failed to set thread name \"ct_events_src\". %s", + __func__, strerror(ret)); + } + + dump_conntrack(targs); + + // Wait for all the threads to be stopped. + pthread_join(targs->tid, NULL); + + g_free(targs); + + return 0; +} + + +/** +* Start threads required for save mode of operation when filter type is +* FILTER_BY_IP. +* +* Following things are performed in the save mode: +* 1. Conntrack delete thread is started which waits till Clear IPC is called. +* 2. Conntrack events threads are started to filter events for the IP +* addresses present in the ips_to_migrate. If any update is received for a +* non-exisitent entry, it is treated as NEW since it contains the base five +* tuple information required to identify flow. Similarly, if a destroy +* event is received for a non-existent entry, it is ignored. +* 3. Finally, Conntrack dump is taken from the kernel to get all the live +* flows in the system. +* +* The above workflow is used to maintain a local copy of the CT entries for +* the VM. +* +* Args: +* @ips_to_migrate Hashtable of IP addresses for which CT entries +* have to be migrated. +* @stop_flag flag used by thread to exit after dbus operations. +* +* Returns: +* 0 in case of success, -1 otherwise +*/ +static int +start_in_save_mode_for_ip(GHashTable *ips_to_migrate, bool *stop_flag) { int ret; uint32_t num_ips; @@ -257,7 +328,9 @@ start_in_save_mode(GHashTable *ips_to_migrate, bool *stop_flag) } // Get all the conntrack entries for the given ip address. - dump_conntrack(ips_to_migrate); + // Because ips_to_migrate is same in case of src/dst targs we can use any + // one of them. + dump_conntrack(src_targs); // Wait for all the threads to be stopped. pthread_join(src_targs->tid, NULL); @@ -271,30 +344,66 @@ start_in_save_mode(GHashTable *ips_to_migrate, bool *stop_flag) } /** - * Creates hashtable of IP addresses from CLI arguments. + * Start threads required for save mode of operation. + * The workflow is used to maintain a local copy of the CT entries for + * the VM. + * + * Args: + * @ips_to_migrate Hashtable of IP addresses for which CT entries + * have to be migrated. + * @ct_zones_to_migrate Hashtable of Ct zones for which CT entries have to be + * migrated. + * @stop_flag flag used by thread to exit after dbus operations. + * + * Returns: + * 0 in case of success, -1 otherwise + */ +static int +start_in_save_mode(GHashTable *ips_to_migrate, GHashTable *ct_zones_to_migrate, + bool *stop_flag) +{ + if ( fltr_type == FILTER_BY_IP ) { + return start_in_save_mode_for_ip(ips_to_migrate, stop_flag); + } + + return start_in_save_mode_for_ct_zones(ct_zones_to_migrate, stop_flag); +} + + +/** + * Creates hashtable of IP addresses/ CT Zones from CLI arguments. * * Args: * @argv array of CLI args. * * Returns: - * Resulting hashtable containing IP address(uint32_t) as key. + * Resulting hashtable containing IP address/CT zones(uint32_t) as key. */ -static GHashTable * -create_ips_ht_from_args(char *argv[]) +GHashTable * +get_entity_ht_from_args(char *argv[]) { - int num_ips; - GHashTable *ht; - - num_ips = atoi(argv[NUM_IP_ADDR_ARG_INDEX]); - const char **ips = (const char **)(argv + IP_ADDR_LIST_ARG_INDEX); + if (fltr_type == FILTER_BY_IP) { + int num_ips; + GHashTable *ips_to_migrate; + num_ips = atoi(argv[NUM_IP_ADDR_ARG_INDEX]); + const char **ip_list = (const char **)(argv + IP_ADDR_LIST_ARG_INDEX); + ips_to_migrate = create_hashtable_from_ip_list(ip_list, num_ips); + if (ips_to_migrate == NULL) { + LOG(ERROR, "%s: Hashtable creation failed.", __func__); + } + return ips_to_migrate; + } - ht = create_hashtable_from_ip_list(ips, num_ips); - if (ht == NULL) { + int num_zones; + GHashTable *ct_zones_to_migrate; + num_zones = atoi(argv[NUM_CT_ZONES_ARG_INDEX]); + const char **zone_list = (const char **)(argv + CT_ZONES_LIST_ARG_INDEX); + ct_zones_to_migrate = create_hashtable_from_ct_zones_list(zone_list, + num_zones); + if (ct_zones_to_migrate == NULL) { LOG(ERROR, "%s: Hashtable creation failed.", __func__); - return NULL; } - - return ht; + return ct_zones_to_migrate; } /** @@ -333,7 +442,14 @@ dmain(int argc, char *argv[]) // set the logging level read from config. set_log_level(lmct_conf.log_lvl); + int i; + for (i = 0; i < argc; i++) { + LOG(INFO, "Mansi: Argument %d: %s\n", i, argv[i]); + } + LOG(INFO, "%s: Starting in mode %s", __func__, mode_to_string[mode]); + LOG(INFO, "%s: Starting in filter on basis of %s", __func__, + fltr_type == FILTER_BY_IP ? "IP Addresses" : "CT Zones"); LOG(INFO, "%s: dbus address %s", __func__, getenv("DBUS_SYSTEM_BUS_ADDRESS")); LOG(INFO, "%s: helper id: %s", __func__, helper_id); @@ -367,19 +483,26 @@ dmain(int argc, char *argv[]) // Start save mode threads. if (mode == SAVE_MODE) { - GHashTable *ips_to_migrate; - ips_to_migrate = create_ips_ht_from_args(argv); - if (ips_to_migrate == NULL) { - return EINVAL; + GHashTable *ips_to_migrate = NULL; + GHashTable *ct_zones_to_migrate = NULL; + + if (fltr_type == FILTER_BY_IP) { + ips_to_migrate = get_entity_ht_from_args(argv); + } else { + ct_zones_to_migrate = get_entity_ht_from_args(argv); } - ret = start_in_save_mode(ips_to_migrate, &stop_flag); + if (ips_to_migrate == NULL && ct_zones_to_migrate == NULL) { + return EINVAL; + } + ret = start_in_save_mode(ips_to_migrate, ct_zones_to_migrate, + &stop_flag); g_hash_table_destroy(ips_to_migrate); + g_hash_table_destroy(ct_zones_to_migrate); if (ret != 0) { return EAGAIN; } } - pthread_join(dbus_server_args.tid, NULL); conntrack_store_destroy(conn_store); close_log(); @@ -447,16 +570,46 @@ check_dbus_address_env(void) static void check_save_mode_args(int argc, char *argv[]) { - int num_ip_addr; + if (fltr_type == FILTER_BY_IP) { + int num_ip_addr; + num_ip_addr = atoi(argv[NUM_IP_ADDR_ARG_INDEX]); + if (num_ip_addr < 0 || num_ip_addr > (argc - IP_ADDR_LIST_ARG_INDEX)) { + errx(EXIT_FAILURE, "Invalid argument for number of IP addresses"); + } + } else if (fltr_type == FILTER_BY_CT_ZONE) { + int num_ct_zones; + num_ct_zones = atoi(argv[NUM_CT_ZONES_ARG_INDEX]); + if (num_ct_zones < 0 || num_ct_zones > (argc - CT_ZONES_LIST_ARG_INDEX)) { + errx(EXIT_FAILURE, "Invalid argument for number of CT Zones"); + } + } else { + errx(EXIT_FAILURE, "Filter type not set properly"); + } + return; +} + +static void +set_filter_type(int argc, char * argv[]){ if (argc < 4) { - errx(EXIT_FAILURE, "Number of IP addresses not present in args"); + errx(EXIT_FAILURE, "Number of IP addresses/ ct-zones not present in args"); } + // Deciding filterting type - ct_zone/ip_addr, on value + // of NUM_IP_ADDR_ARG_INDEX if this -1 then ct zone else + // it will be no of ip addr provided. This hack is to support + // older versions. + int num_ip_addr; num_ip_addr = atoi(argv[NUM_IP_ADDR_ARG_INDEX]); - if (num_ip_addr < 0 || num_ip_addr > (argc - IP_ADDR_LIST_ARG_INDEX)) { - errx(EXIT_FAILURE, "Invalid argument for number of IP addresses"); + if (num_ip_addr >= 0) { + populate_filter_type(FILTER_BY_IP); + } else if (num_ip_addr == -1){ + populate_filter_type(FILTER_BY_CT_ZONE); + } else { + errx(EXIT_FAILURE, "Number of IP addresses/ ct-zones not present" + "in args"); } + return; } /** @@ -480,11 +633,13 @@ check_args(int argc, char *argv[]) err_usage(); } - check_dbus_address_env(); + //check_dbus_address_env(); mode = atoi(argv[MODE_ARG_INDEX]); check_mode(mode); + set_filter_type(argc, argv); + if (mode == SAVE_MODE) { check_save_mode_args(argc, argv); } From 5b99531b12fb4cdf3dcfbf04fe632a5e2397a045 Mon Sep 17 00:00:00 2001 From: Mansi Sharma Date: Tue, 17 Sep 2024 08:47:02 +0000 Subject: [PATCH 2/2] clean up code for ip based filtering --- src/conntrack.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/conntrack.c b/src/conntrack.c index 6fa2c32..bc21bc9 100644 --- a/src/conntrack.c +++ b/src/conntrack.c @@ -163,7 +163,6 @@ conntrack_dump_callback(enum nf_conntrack_msg_type type, is_entry_useful = is_src_or_dst_in_hashtable(src_addr, dst_addr, ips_to_migrate); - LOG(INFO, "Mansi: %s %s", __func__, is_entry_useful ? "true": false); } else { zone = nfct_get_attr_u16(ct, ATTR_ZONE); ct_zones_to_migrate = (GHashTable *)cb_args->ct_zones_to_migrate; @@ -172,7 +171,6 @@ conntrack_dump_callback(enum nf_conntrack_msg_type type, } if (is_entry_useful) { - LOG(INFO, "Mansi: adding for zone %u %s", zone, __func__); update_conntrack_store(conn_store, ct, type); } @@ -297,18 +295,20 @@ conntrack_events_callback(const struct nlmsghdr *nlh, void *data) return MNL_CB_OK; } - uint16_t zone; - zone = nfct_get_attr_u16(ct, ATTR_ZONE); - bool add_to_conntrack_store = true; - if( fltr_type == FILTER_BY_CT_ZONE && - !g_hash_table_contains(ct_zones_to_migrate, GUINT_TO_POINTER(zone))){ - add_to_conntrack_store = false; + if( fltr_type == FILTER_BY_CT_ZONE ){ + 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 zone %u entry in conntrack store", __func__, - zone); + LOG(INFO, "%s : Updating entry in conntrack store", __func__); update_conntrack_store(conn_store, ct, type); } nfct_destroy(ct); @@ -326,8 +326,6 @@ 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) { @@ -337,14 +335,12 @@ create_nfct_filter(GHashTable *ips, bool is_src_filter) } if (fltr_type == FILTER_BY_IP) { - LOG(INFO, "Mansi: Setting filter for IPS %s", __func__); 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); - LOG(INFO, "adding ip into filter %u %s", key, __func__); struct nfct_filter_ipv4 filter_ipv4 = { .addr = ntohl(ip), .mask = 0xffffffff,