Ejemplo n.º 1
0
//caller will acquire ofrw_htbl lock
cc_of_ret
add_upd_ofrw_rwsocket(int add_fd, adpoll_thread_mgr_t  *thr_mgr_p,
                      L4_type_e layer4_proto,
                      cc_ofdev_key_t key, struct sockaddr_in *client_addr)
{
    cc_ofrw_key_t *ofrw_key;
    cc_ofrw_info_t *ofrw_info;
    gboolean new_entry;
    cc_of_ret rc;
    CC_LOG_DEBUG("%s(%d)", __FUNCTION__, __LINE__);    
    ofrw_key = (cc_ofrw_key_t *)malloc(sizeof(cc_ofrw_key_t));
    ofrw_info = (cc_ofrw_info_t *)malloc(sizeof(cc_ofrw_info_t));

    ofrw_key->rw_sockfd = add_fd;
    ofrw_info->state = CC_OF_RW_DOWN;
    ofrw_info->thr_mgr_p = thr_mgr_p;
    memcpy(&(ofrw_info->dev_key), &key, sizeof(cc_ofdev_key_t));
    if (client_addr)
        memcpy(&(ofrw_info->client_addr), client_addr, sizeof(struct sockaddr_in));
    ofrw_info->layer4_proto = layer4_proto;

    rc = update_global_htbl_lockfree(OFRW, ADD,
                                     ofrw_key, ofrw_info,
                                     &new_entry);
    
    if (!new_entry) {
        free(ofrw_key);
    } else {
        CC_LOG_DEBUG("%s(%d): new entry %d", __FUNCTION__, __LINE__,
                     add_fd);
        print_ofrw_htbl();
    }
    return rc;
}
Ejemplo n.º 2
0
void
print_ofdev_htbl(void)
{
    GHashTableIter ofdev_iter;
    cc_ofdev_key_t *dev_key = NULL;
    cc_ofdev_info_t *dev_info = NULL;
    g_hash_table_iter_init(&ofdev_iter, cc_of_global.ofdev_htbl);
    GList *list_elem = NULL;
    int n;

    n = g_hash_table_size(cc_of_global.ofdev_htbl);
    CC_LOG_DEBUG("Printing ofdev Hash Table with %d entries", n);

    if (n) {
        while (g_hash_table_iter_next(&ofdev_iter,
                                      (gpointer *)&dev_key,
                                      (gpointer *)&dev_info)) {
            CC_LOG_DEBUG("key: controller ip: 0x%x "
                        "key: switch ip: 0x%x "
                        "key: l4 port: %d",
                        dev_key->controller_ip_addr,
                        dev_key->switch_ip_addr,
                        dev_key->controller_L4_port);
        }
        
        //Iterate through the sockets in dev info
        list_elem = g_list_first(dev_info->ofrw_socket_list);
        while (list_elem) {
            CC_LOG_DEBUG("sockfd: %d",*(int *)(list_elem->data));
            list_elem = g_list_next(list_elem);
        }
    }
    
}
Ejemplo n.º 3
0
void
print_ofchann_htbl(void)
{
    GHashTableIter ofch_iter;
    cc_ofchannel_key_t *ch_key = NULL;
    cc_ofchannel_info_t *ch_info = NULL;
    int n;
    g_hash_table_iter_init(&ofch_iter, cc_of_global.ofchannel_htbl);

    n = g_hash_table_size(cc_of_global.ofchannel_htbl);
    CC_LOG_DEBUG("Printing ofchannel Hash Table with %d entries",n);

    if (n) {
        while (g_hash_table_iter_next(&ofch_iter,
                                      (gpointer *)&ch_key,
                                      (gpointer *)&ch_info)) {
            CC_LOG_DEBUG("key: dp id: %lu "
                        "key: aux id: %hu "
                        "info: socket: %d",
                        ch_key->dp_id,
                        ch_key->aux_id,
                        ch_info->rw_sockfd);
        }
    }
}
Ejemplo n.º 4
0
static int Calculator_impl2_split(
    struct cc_server_Calculator *instance, double value, int32_t *whole, int32_t *fraction)
{
    CC_LOG_DEBUG("invoked method Calculator_impl1_split()\n");
    CC_LOG_DEBUG("with value=%g\n", value);
    assert(instance);
    assert(whole);
    assert(fraction);
    *whole = -1;
    *fraction = -2;
    CC_LOG_DEBUG("returning whole=%d, fraction=%d\n", *whole, *fraction);
    return 0;
}
Ejemplo n.º 5
0
int cc_client_Ball_new(const char *address, void *data, struct cc_client_Ball **instance)
{
    int result;
    struct cc_client_Ball *ii;

    CC_LOG_DEBUG("invoked cc_client_Ball_new\n");
    assert(address);
    assert(instance);

    ii = (struct cc_client_Ball *) calloc(1, sizeof(*ii));
    if (!ii) {
        CC_LOG_ERROR("failed to allocate instance memory\n");
        return -ENOMEM;
    }

    result = cc_instance_new(address, false, &ii->instance);
    if (result < 0) {
        CC_LOG_ERROR("failed to create instance: %s\n", strerror(-result));
        goto fail;
    }
    ii->data = data;

    *instance = ii;
    return 0;

fail:
    ii = cc_client_Ball_free(ii);
    return result;
}
Ejemplo n.º 6
0
int cc_Ball_drop(struct cc_client_Ball *instance)
{
    int result = 0;
    struct cc_instance *i;
    sd_bus_message *message = NULL;

    CC_LOG_DEBUG("invoked cc_Ball_drop()\n");
    assert(instance);
    i = instance->instance;
    assert(i && i->backend && i->backend->bus);
    assert(i->service && i->path && i->interface);

    result = sd_bus_message_new_method_call(
        i->backend->bus, &message, i->service, i->path, i->interface, "drop");
    if (result < 0) {
        CC_LOG_ERROR("unable to create message: %s\n", strerror(-result));
        goto fail;
    }
    result = sd_bus_message_set_expect_reply(message, 0);
    if (result < 0) {
        CC_LOG_ERROR("unable to flag message no-reply-expected: %s\n", strerror(-result));
        goto fail;
    }
    /* Setting cookie=NULL in sd_bus_send() call makes the previous one redundant */
    result = sd_bus_send(i->backend->bus, message, NULL);
    if (result < 0) {
        CC_LOG_ERROR("unable to send message: %s\n", strerror(-result));
        goto fail;
    }

fail:
    message = sd_bus_message_unref(message);

    return result;
}
Ejemplo n.º 7
0
static int setup_signals(sd_event *event)
{
    sigset_t signals;
    int result;

    CC_LOG_DEBUG("invoked setup_signals()\n");
    assert(event);
    sigemptyset(&signals);
    sigaddset(&signals, SIGTERM);
    sigaddset(&signals, SIGINT);
    result = sigprocmask(SIG_BLOCK, &signals, NULL);
    if (result != 0) {
        CC_LOG_ERROR("unable to block signals: %s\n", strerror(result));
        return -result;
    }
    result = sd_event_add_signal(event, NULL, SIGTERM, &signal_handler, event);
    if (result < 0) {
        CC_LOG_ERROR("unable to setup SIGTERM handler: %s\n", strerror(-result));
        return result;
    }
    result = sd_event_add_signal(event, NULL, SIGINT, &signal_handler, event);
    if (result < 0) {
        CC_LOG_ERROR("unable to setup SIGINT handler: %s\n", strerror(-result));
        return result;
    }

    return 0;
}
Ejemplo n.º 8
0
static int cc_Smartie_hangup_thunk(
    CC_IGNORE_BUS_ARG sd_bus_message *m, void *userdata, sd_bus_error *error)
{
    int result = 0;
    struct cc_server_Smartie *ii = (struct cc_server_Smartie *) userdata;
    int32_t status;

    CC_LOG_DEBUG("invoked cc_Smartie_hangup_thunk()\n");
    assert(m);
    assert(ii && ii->impl);
    CC_LOG_DEBUG("with path='%s'\n", sd_bus_message_get_path(m));

    result = sd_bus_message_read(m, "");
    if (result < 0) {
        CC_LOG_ERROR("unable to read method parameters: %s\n", strerror(-result));
        return result;
    }
    if (!ii->impl->hangup) {
        CC_LOG_ERROR("unsupported method invoked: %s\n", "Smartie.hangup");
        sd_bus_error_set(
            error, SD_BUS_ERROR_NOT_SUPPORTED,
            "instance does not support method Smartie.hangup");
        sd_bus_reply_method_error(m, error);
        return -ENOTSUP;
    }
    result = ii->impl->hangup(ii, &status);
    if (result < 0) {
        CC_LOG_ERROR("failed to execute method: %s\n", strerror(-result));
        sd_bus_error_setf(
            error, SD_BUS_ERROR_FAILED,
            "method implementation failed with error=%d", result);
        sd_bus_reply_method_error(m, error);
        return result;
    }
    result = sd_bus_reply_method_return(m, "i", status);
    if (result < 0) {
        CC_LOG_ERROR("unable to send method reply: %s\n", strerror(-result));
        return result;
    }

    /* Successful method invocation must return >0 */
    return 1;
}
Ejemplo n.º 9
0
int cc_Ball_grab(struct cc_client_Ball *instance, bool *success)
{
    int result = 0;
    struct cc_instance *i;
    sd_bus_message *message = NULL;
    sd_bus_message *reply = NULL;
    sd_bus_error error = SD_BUS_ERROR_NULL;
    int success_int;

    CC_LOG_DEBUG("invoked cc_Ball_grab()\n");
    assert(instance);
    i = instance->instance;
    assert(i && i->backend && i->backend->bus);
    assert(i->service && i->path && i->interface);

    if (instance->grab_reply_slot) {
        CC_LOG_ERROR("unable to call method with already pending reply\n");
        return -EBUSY;
    }
    assert(!instance->grab_reply_callback);

    result = sd_bus_call_method(
        i->backend->bus, i->service, i->path, i->interface, "grab", &error, &reply, "");
    if (result < 0) {
        CC_LOG_ERROR("unable to call method: %s\n", strerror(-result));
        goto fail;
    }
    result = sd_bus_message_read(reply, "b", &success_int);
    if (result < 0) {
        CC_LOG_ERROR("unable to get reply value: %s\n", strerror(-result));
        goto fail;
    }
    *success = !!success_int;
    CC_LOG_DEBUG("returning success=%d\n", (int) *success);

fail:
    sd_bus_error_free(&error);
    reply = sd_bus_message_unref(reply);
    message = sd_bus_message_unref(message);

    return result;
}
Ejemplo n.º 10
0
int cc_Calculator_split(
    struct cc_client_Calculator *instance, double value, int32_t *whole, int32_t *fraction)
{
    int result = 0;
    struct cc_instance *i;
    sd_bus_message *message = NULL;
    sd_bus_message *reply = NULL;
    sd_bus_error error = SD_BUS_ERROR_NULL;

    CC_LOG_DEBUG("invoked cc_Calculator_split()\n");
    assert(instance);
    i = instance->instance;
    assert(i && i->backend && i->backend->bus);
    assert(i->service && i->path && i->interface);

    if (instance->split_reply_slot) {
        CC_LOG_ERROR("unable to call method with already pending reply\n");
        return -EBUSY;
    }
    assert(!instance->split_reply_callback);

    result = sd_bus_call_method(
        i->backend->bus, i->service, i->path, i->interface,
        "split", &error, &reply, "d", value);
    if (result < 0) {
        CC_LOG_ERROR("unable to call method: %s\n", strerror(-result));
        goto fail;
    }
    result = sd_bus_message_read(reply, "ii", whole, fraction);
    if (result < 0) {
        CC_LOG_ERROR("unable to get reply value: %s\n", strerror(-result));
        goto fail;
    }
    CC_LOG_DEBUG("returning whole=%" PRId32 ", fraction=%" PRId32 "\n", *whole, *fraction);

fail:
    sd_bus_error_free(&error);
    reply = sd_bus_message_unref(reply);
    message = sd_bus_message_unref(message);

    return result;
}
Ejemplo n.º 11
0
struct cc_client_Ball *cc_client_Ball_free(struct cc_client_Ball *instance)
{
    CC_LOG_DEBUG("invoked cc_client_Ball_free()\n");
    if (instance) {
        instance->grab_reply_slot = sd_bus_slot_unref(instance->grab_reply_slot);
        instance->instance = cc_instance_free(instance->instance);
        /* User is responsible for memory management of data. */
        free(instance);
    }
    return NULL;
}
Ejemplo n.º 12
0
struct cc_server_Smartie *cc_server_Smartie_free(struct cc_server_Smartie *instance)
{
    CC_LOG_DEBUG("invoked cc_server_Smartie_free()\n");
    if (instance) {
        instance->vtable_slot = sd_bus_slot_unref(instance->vtable_slot);
        instance->instance = cc_instance_free(instance->instance);
        /* User is resposible for memory management of impl and data. */
        free(instance);
    }
    return NULL;
}
Ejemplo n.º 13
0
void
print_ofrw_htbl(void)
{
    GHashTableIter ofrw_iter;
    cc_ofrw_key_t *rw_key = NULL;
    cc_ofrw_info_t *rw_info = NULL;
    gpointer rkey = NULL, rinfo = NULL;
    g_hash_table_iter_init(&ofrw_iter, cc_of_global.ofrw_htbl);
    int n;

    n = g_hash_table_size(cc_of_global.ofrw_htbl);
    
    CC_LOG_DEBUG("Printing ofrw Hash Table with %d entries", n);
    if (n) {
        while (g_hash_table_iter_next(&ofrw_iter,
                                      &rkey, &rinfo)) {
            rw_info = (cc_ofrw_info_t *)rinfo;
            rw_key = (cc_ofrw_key_t *)rkey;
            if (rw_info->thr_mgr_p == NULL) {
                CC_LOG_ERROR("%s(%d): no polling thread for %d",
                             __FUNCTION__, __LINE__, rw_key->rw_sockfd);
            } else {
                CC_LOG_DEBUG("key: rw_sockfd: %d "
                            "info: layer4_proto: %s "
                            "info: poll thread name: %s"
                            "info: devkey controller ip: 0x%x"
                            "info: devkey switch ip: 0x%x"
                            "info: devkey l4port: %d",
                            rw_key->rw_sockfd,
                            (rw_info->layer4_proto == TCP)? "TCP":"UDP",
                            rw_info->thr_mgr_p->tname,
                            rw_info->dev_key.controller_ip_addr,
                            rw_info->dev_key.switch_ip_addr,
                            rw_info->dev_key.controller_L4_port);
            }
        }
    }
}
Ejemplo n.º 14
0
static int cc_Calculator_split_reply_thunk(
    CC_IGNORE_BUS_ARG sd_bus_message *message, void *userdata, sd_bus_error *ret_error)
{
    int result = 0;
    sd_bus *bus;
    struct cc_client_Calculator *ii = (struct cc_client_Calculator *) userdata;
    int32_t whole;
    int32_t fraction;
    (void) ret_error;

    CC_LOG_DEBUG("invoked cc_Calculator_split_reply_thunk()\n");
    assert(message);
    bus = sd_bus_message_get_bus(message);
    assert(bus);
    assert(ii);
    assert(ii->split_reply_callback);
    assert(ii->split_reply_slot == sd_bus_get_current_slot(bus));
    result = sd_bus_message_get_errno(message);
    if (result != 0) {
        CC_LOG_ERROR("failed to receive response: %s\n", strerror(result));
        goto finish;
    }
    result = sd_bus_message_read(message, "ii", &whole, &fraction);
    if (result < 0) {
        CC_LOG_ERROR("unable to get reply value: %s\n", strerror(-result));
        goto finish;
    }
    CC_LOG_DEBUG("invoking callback in cc_Calculator_split_reply_thunk()\n");
    CC_LOG_DEBUG("with whole=%" PRId32 ", fraction=%" PRId32 "\n", whole, fraction);
    ii->split_reply_callback(ii, whole, fraction);
    result = 1;

finish:
    ii->split_reply_callback = NULL;
    ii->split_reply_slot = sd_bus_slot_unref(ii->split_reply_slot);

    return result;
}
Ejemplo n.º 15
0
static int cc_Ball_grab_reply_thunk(
    CC_IGNORE_BUS_ARG sd_bus_message *message, void *userdata, sd_bus_error *ret_error)
{
    int result = 0;
    sd_bus *bus;
    struct cc_client_Ball *ii = (struct cc_client_Ball *) userdata;
    int success_int;

    CC_LOG_DEBUG("invoked cc_Ball_grab_reply_thunk()\n");
    assert(message);
    bus = sd_bus_message_get_bus(message);
    assert(bus);
    assert(ii);
    assert(ii->grab_reply_callback);
    assert(ii->grab_reply_slot == sd_bus_get_current_slot(bus));
    result = sd_bus_message_get_errno(message);
    if (result != 0) {
        CC_LOG_ERROR("failed to receive response: %s\n", strerror(result));
        goto finish;
    }
    result = sd_bus_message_read(message, "b", &success_int);
    if (result < 0) {
        CC_LOG_ERROR("unable to get reply value: %s\n", strerror(-result));
        goto finish;
    }
    CC_LOG_DEBUG("invoking callback in cc_Ball_grab_reply_thunk()\n");
    CC_LOG_DEBUG("with success=%d\n", !!success_int);
    ii->grab_reply_callback(ii, !!success_int);
    result = 1;

finish:
    ii->grab_reply_callback = NULL;
    ii->grab_reply_slot = sd_bus_slot_unref(ii->grab_reply_slot);

    return result;
}
Ejemplo n.º 16
0
static int signal_handler(
    sd_event_source *source, const struct signalfd_siginfo *signal_info, void *user_data)
{
    sd_event *event = (sd_event *) user_data;
    int result;

    CC_LOG_DEBUG("invoked signal_handler() with signal %d\n", signal_info->ssi_signo);
    assert(event);
    assert(signal_info->ssi_signo == SIGTERM || signal_info->ssi_signo == SIGINT);

    result = sd_event_exit(event, 0);
    if (result < 0)
        CC_LOG_ERROR("unable to exit event loop: %s\n", strerror(-result));

    return result;
}
Ejemplo n.º 17
0
int cc_Calculator_split_async(
    struct cc_client_Calculator *instance, double value,
    cc_Calculator_split_reply_t callback)
{
    int result = 0;
    struct cc_instance *i;
    sd_bus_message *message = NULL;

    CC_LOG_DEBUG("invoked cc_Calculator_split_async()\n");
    assert(instance);
    assert(callback);
    i = instance->instance;
    assert(i && i->backend && i->backend->bus);
    assert(i->service && i->path && i->interface);

    if (instance->split_reply_slot) {
        CC_LOG_ERROR("unable to call method with already pending reply\n");
        return -EBUSY;
    }
    assert(!instance->split_reply_callback);

    result = sd_bus_message_new_method_call(
        i->backend->bus, &message, i->service, i->path, i->interface, "split");
    if (result < 0) {
        CC_LOG_ERROR("unable to create message: %s\n", strerror(-result));
        goto fail;
    }
    result = sd_bus_message_append(message, "d", value);
    if (result < 0) {
        CC_LOG_ERROR("unable to append message method arguments: %s\n", strerror(-result));
        goto fail;
    }

    result = sd_bus_call_async(
        i->backend->bus, &instance->split_reply_slot, message,
        &cc_Calculator_split_reply_thunk, instance, CC_DBUS_ASYNC_CALL_TIMEOUT_USEC);
    if (result < 0) {
        CC_LOG_ERROR("unable to issue method call: %s\n", strerror(-result));
        goto fail;
    }
    instance->split_reply_callback = callback;

fail:
    message = sd_bus_message_unref(message);

    return result;
}
Ejemplo n.º 18
0
gboolean cc_ofrw_htbl_equal_func(gconstpointer a, gconstpointer b)
{
    cc_ofrw_key_t *a_rw, *b_rw;
    a_rw = (cc_ofrw_key_t *)a;
    b_rw = (cc_ofrw_key_t *)b;

    CC_LOG_DEBUG("%s: a rw_sockfd %d b is %d",
                 __FUNCTION__,
                 a_rw->rw_sockfd,
                 b_rw->rw_sockfd);
    
    if (a_rw->rw_sockfd == b_rw->rw_sockfd) {
	    return TRUE;
    } else {
	    return FALSE;
    }
}
Ejemplo n.º 19
0
gboolean cc_ofchannel_htbl_equal_func(gconstpointer a, gconstpointer b)
{
    cc_ofchannel_key_t *a_chan, *b_chan;
    a_chan = (cc_ofchannel_key_t *)a;
    b_chan = (cc_ofchannel_key_t *)b;

    CC_LOG_DEBUG("%s: a dp/aux %lu/%hu b is %lu/%hu",
                 __FUNCTION__,
                 a_chan->dp_id, a_chan->aux_id,
                 b_chan->dp_id, b_chan->aux_id);
    
    if ((a_chan->dp_id == b_chan->dp_id) &&
        (a_chan->aux_id == b_chan->aux_id)) {
         return TRUE;
     } else {
         return FALSE;
    }
}
Ejemplo n.º 20
0
gboolean cc_ofdev_htbl_equal_func(gconstpointer a, gconstpointer b)
{
    cc_ofdev_key_t *a_dev, *b_dev;
    a_dev = (cc_ofdev_key_t *)a;
    b_dev = (cc_ofdev_key_t *)b;
    CC_LOG_DEBUG("%s: a controller ip addr 0x%x b is 0x%x",
                 __FUNCTION__,
                a_dev->controller_ip_addr,
                b_dev->controller_ip_addr);
    
    if ((a_dev->controller_ip_addr == b_dev->controller_ip_addr) && 
	    (a_dev->switch_ip_addr == b_dev->switch_ip_addr) &&
        (a_dev->controller_L4_port == b_dev->controller_L4_port)) {
	    return TRUE;
    } else {
	    return FALSE;
    }
}
Ejemplo n.º 21
0
int cc_server_Smartie_new(
    const char *address, const struct cc_server_Smartie_impl *impl, void *data,
    struct cc_server_Smartie **instance)
{
    int result;
    struct cc_server_Smartie *ii;
    struct cc_instance *i;

    CC_LOG_DEBUG("invoked cc_server_Smartie_new\n");
    assert(address);
    assert(impl);
    assert(instance);

    ii = (struct cc_server_Smartie *) calloc(1, sizeof(*ii));
    if (!ii) {
        CC_LOG_ERROR("failed to allocate instance memory\n");
        return -ENOMEM;
    }

    result = cc_instance_new(address, true, &i);
    if (result < 0) {
        CC_LOG_ERROR("failed to create instance: %s\n", strerror(-result));
        goto fail;
    }
    ii->instance = i;
    ii->impl = impl;
    ii->data = data;

    result = sd_bus_add_object_vtable(
        i->backend->bus, &ii->vtable_slot, i->path, i->interface, vtable_Smartie, ii);
    if (result < 0) {
        CC_LOG_ERROR("unable to initialize instance vtable: %s\n", strerror(-result));
        goto fail;
    }

    *instance = ii;
    return 0;

fail:
    ii = cc_server_Smartie_free(ii);
    return result;
}
Ejemplo n.º 22
0
//ofrw_htbl_lock acqured by callee
cc_of_ret
find_thrmgr_rwsocket(int sockfd, 
                     adpoll_thread_mgr_t **tmgr) {
    cc_of_ret status = CC_OF_OK;
    cc_ofrw_key_t rwkey;
    cc_ofrw_info_t *rwinfo = NULL;
    
    rwkey.rw_sockfd = sockfd;
    g_mutex_lock(&cc_of_global.ofrw_htbl_lock);
    CC_LOG_DEBUG("%s(%d)", __FUNCTION__, __LINE__);
    print_ofrw_htbl();
    rwinfo = g_hash_table_lookup(cc_of_global.ofrw_htbl, &rwkey);
    if (rwinfo == NULL) {
        CC_LOG_ERROR("%s(%d): could not find rwsock %d in ofrw_htbl",
                     __FUNCTION__, __LINE__, rwkey.rw_sockfd);
        g_mutex_unlock(&cc_of_global.ofrw_htbl_lock);
        return CC_OF_EHTBL;
    }
    
    *tmgr = rwinfo->thr_mgr_p;
    g_mutex_unlock(&cc_of_global.ofrw_htbl_lock);    
    return status;
}
Ejemplo n.º 23
0
// Caller will acquire htbl locks
cc_of_ret
update_global_htbl_lockfree(htbl_type_e htbl_type,
                            htbl_update_ops_e htbl_op,
                            gpointer htbl_key,
                            gpointer htbl_data,
                            gboolean *new_entry)
{
    GHashTable *cc_htbl;
    gpointer key, info_data;

    *new_entry = FALSE;
    guint old_count;

   switch(htbl_type) {
     case OFDEV:
        cc_htbl = cc_of_global.ofdev_htbl;
        if ((htbl_op == ADD) &&
            (g_hash_table_contains(cc_htbl, htbl_key))) {
            htbl_op = UPD;
            /* create a new key. the insert operation will free this */
            key = malloc(sizeof(cc_ofdev_key_t));
            memcpy(key, htbl_key, sizeof(cc_ofdev_key_t));
            info_data = malloc(sizeof(cc_ofdev_info_t));
            memcpy(info_data, htbl_data, sizeof(cc_ofdev_info_t));
        }
        break;
      case OFRW:
        cc_htbl = cc_of_global.ofrw_htbl;
        if ((htbl_op == ADD) &&
            (g_hash_table_contains(cc_htbl, htbl_key))) {
            htbl_op = UPD;
            /* create a new key. the insert operation will free ths */
            key = malloc(sizeof(cc_ofrw_key_t));
            memcpy(key, htbl_key, sizeof(cc_ofrw_key_t));
            info_data = malloc(sizeof(cc_ofrw_info_t));
            memcpy(info_data, htbl_data, sizeof(cc_ofrw_info_t));
        }
        break;
      case OFCHANN:
        cc_htbl = cc_of_global.ofchannel_htbl;
        if ((htbl_op == ADD) &&
            (g_hash_table_contains(cc_htbl, htbl_key))) {
            /* create a new key. the insert operation will free this */
            key = malloc(sizeof(cc_ofchannel_key_t));
            memcpy(key, htbl_key, sizeof(cc_ofchannel_key_t));
            info_data = malloc(sizeof(cc_ofchannel_info_t));
            memcpy(info_data, htbl_data, sizeof(cc_ofchannel_info_t));
        }
        break;
      default:
        CC_LOG_ERROR("%s(%d): invalid htbl type %d",
                     __FUNCTION__, __LINE__, htbl_type);
    }

    if (htbl_op == ADD) {

        old_count = g_hash_table_size(cc_htbl);
        CC_LOG_DEBUG("%s(%d): insert operation for htbl_type %s",
                     __FUNCTION__, __LINE__,
                     (htbl_type == OFDEV)? "OFDEV":
                     ((htbl_type == OFRW)?"OFRW":"OFCHANN"));
        if (htbl_type == OFDEV) {
            CC_LOG_DEBUG("%s(%d) key has controller ip 0x%x, switch ip 0x%x and port %d",
                         __FUNCTION__, __LINE__,
                         ((cc_ofdev_key_t *)htbl_key)->controller_ip_addr,
                         ((cc_ofdev_key_t *)htbl_key)->switch_ip_addr,
                         ((cc_ofdev_key_t *)htbl_key)->controller_L4_port);
        } else if (htbl_type == OFRW) {
            CC_LOG_DEBUG("%s(%d) insert key has socket %d",
                         __FUNCTION__, __LINE__,
                         ((cc_ofrw_key_t *)htbl_key)->rw_sockfd);

            CC_LOG_DEBUG("%s(%d) insert info has l4 proto %s",
                         __FUNCTION__, __LINE__,
                         (((cc_ofrw_info_t *)htbl_data)->layer4_proto == TCP)?
                         "TCP":((((cc_ofrw_info_t *)htbl_data)->layer4_proto
                                 == UDP)? "UDP":"INVALID"));

            if (g_hash_table_contains(cc_htbl, htbl_key)) {
                CC_LOG_DEBUG("(%s(%d): OFRW htbl already contains %d",
                             __FUNCTION__, __LINE__,
                             ((cc_ofrw_key_t *)htbl_key)->rw_sockfd);
            }
        } else if (htbl_type == OFCHANN) {
            CC_LOG_DEBUG("%s(%d) ofchannel key dp/aux %lu/%hu",
                         __FUNCTION__, __LINE__,
                         ((cc_ofchannel_key_t *)htbl_key)->dp_id,
                         ((cc_ofchannel_key_t *)htbl_key)->aux_id);
        }


        g_hash_table_insert(cc_htbl, htbl_key, htbl_data);

        if (htbl_type == OFDEV) {
        } else if (htbl_type == OFRW) {
            gpointer rwht_key = NULL, rwht_info = NULL;
            if (g_hash_table_contains(cc_htbl, htbl_key)) {
                CC_LOG_DEBUG("(%s(%d): OFRW htbl contains %d",
                             __FUNCTION__, __LINE__,
                             ((cc_ofrw_key_t *)htbl_key)->rw_sockfd);
            }
            CC_LOG_DEBUG("OFRW htbl size after insert of %d: %d",
                         ((cc_ofrw_key_t *)htbl_key)->rw_sockfd,
                         g_hash_table_size(cc_htbl));

            if (g_hash_table_lookup_extended(cc_of_global.ofrw_htbl,
                                             htbl_key,
                                             &rwht_key, &rwht_info)
                == FALSE) {
                CC_LOG_DEBUG("extended lookup failed");
            } else {
                cc_ofrw_key_t *rw_key =  NULL;
                cc_ofrw_info_t *rw_info = NULL;
                rw_key = (cc_ofrw_key_t *)rwht_key;
                rw_info = (cc_ofrw_info_t *)rwht_info;
                CC_LOG_DEBUG("extended lookup passed");
                CC_LOG_DEBUG("key: rw_sockfd: %d "
                            "info: layer4_proto: %s "
                            "info: poll thread name: %s"
                            "info: devkey controller ip: 0x%x"
                            "info: devkey switch ip: 0x%x"
                            "info: devkey l4port: %d",
                            rw_key->rw_sockfd,
                            (rw_info->layer4_proto == TCP)? "TCP":"UDP",
                            rw_info->thr_mgr_p->tname,
                            rw_info->dev_key.controller_ip_addr,
                            rw_info->dev_key.switch_ip_addr,
                            rw_info->dev_key.controller_L4_port);
                
            }
            CC_LOG_DEBUG("%s(%d) key has socket %d",
                         __FUNCTION__, __LINE__,
                         ((cc_ofrw_key_t *)htbl_key)->rw_sockfd);
        }
        
        if (g_hash_table_size(cc_htbl) > old_count) {
            *new_entry = TRUE;
        }
        
    } else if (htbl_op == DEL) {
        CC_LOG_DEBUG("%s(%d).. HTBL DEL ", __FUNCTION__, __LINE__);
        if (g_hash_table_contains(cc_htbl, htbl_key)) {
            CC_LOG_DEBUG("%s(%d) DEL operation found entry",
                         __FUNCTION__, __LINE__);
        }
        if (g_hash_table_remove(cc_htbl, htbl_key) == FALSE) {
            CC_LOG_DEBUG("%s(%d) DEL unsuccessful",
                         __FUNCTION__, __LINE__);
            
            return CC_OF_EHTBL;
        }

    } else if (htbl_op == UPD) {
        old_count = g_hash_table_size(cc_htbl);
        CC_LOG_DEBUG("%s(%d): replace existing entry operation", __FUNCTION__, __LINE__);
        if (htbl_type == OFDEV) {
            CC_LOG_DEBUG("%s(%d) key has controller ip 0x%x, switch ip 0x%x and port %d",
                         __FUNCTION__, __LINE__,
                         ((cc_ofdev_key_t *)key)->controller_ip_addr,
                         ((cc_ofdev_key_t *)key)->switch_ip_addr,
                         ((cc_ofdev_key_t *)key)->controller_L4_port);
        }
        g_hash_table_insert(cc_htbl, key, info_data);

        if (htbl_type == OFDEV) {        
        } else if (htbl_type == OFCHANN) {
        } else if (htbl_type == OFRW) {
            gpointer rwht_key = NULL, rwht_info = NULL;
            if (g_hash_table_contains(cc_htbl, htbl_key)) {
                CC_LOG_DEBUG("(%s(%d): OFRW htbl contains %d",
                             __FUNCTION__, __LINE__,
                             ((cc_ofrw_key_t *)htbl_key)->rw_sockfd);
            }
            CC_LOG_DEBUG("OFRW htbl size after insert of %d: %d",
                         ((cc_ofrw_key_t *)htbl_key)->rw_sockfd,
                         g_hash_table_size(cc_htbl));
            
            if (g_hash_table_lookup_extended(cc_of_global.ofrw_htbl,
                                             htbl_key,
                                             &rwht_key, &rwht_info)
                == FALSE) {
                CC_LOG_DEBUG("extended lookup failed");
            } else {
                cc_ofrw_key_t *rw_key =  NULL;
                cc_ofrw_info_t *rw_info = NULL;
                rw_key = (cc_ofrw_key_t *)rwht_key;
                rw_info = (cc_ofrw_info_t *)rwht_info;
                CC_LOG_DEBUG("extended lookup passed");
                CC_LOG_DEBUG("key: rw_sockfd: %d "
                            "info: layer4_proto: %s "
                            "info: poll thread name: %s"
                            "info: devkey controller ip: 0x%x"
                            "info: devkey switch ip: 0x%x"
                            "info: devkey l4port: %d",
                            rw_key->rw_sockfd,
                            (rw_info->layer4_proto == TCP)? "TCP":"UDP",
                            rw_info->thr_mgr_p->tname,
                            rw_info->dev_key.controller_ip_addr,
                            rw_info->dev_key.switch_ip_addr,
                            rw_info->dev_key.controller_L4_port);
                
            }
        }
        
        if (g_hash_table_size(cc_htbl) > old_count) {
            *new_entry = TRUE;
        }

    }
    
    return CC_OF_OK;
}