diff options
author | David Sommerseth <davids@redhat.com> | 2013-12-10 14:29:52 +0100 |
---|---|---|
committer | David Sommerseth <davids@redhat.com> | 2013-12-10 14:29:52 +0100 |
commit | d345876e7d52b4f743a37cfe5b390067bad0a956 (patch) | |
tree | 12923d74843566d33a79906fe740b25baa67c967 /python-ethtool/netlink.c | |
parent | 3d7572b4de88a5f21a52dc64bdbde19f5ce5c9b0 (diff) | |
download | python-ethtool-d345876e7d52b4f743a37cfe5b390067bad0a956.tar.gz python-ethtool-d345876e7d52b4f743a37cfe5b390067bad0a956.tar.xz python-ethtool-d345876e7d52b4f743a37cfe5b390067bad0a956.zip |
Split out generic NETLINK functions from etherinfo.c to netlink.c
Primarily just to clean up the code
Signed-off-by: David Sommerseth <davids@redhat.com>
Diffstat (limited to 'python-ethtool/netlink.c')
-rw-r--r-- | python-ethtool/netlink.c | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/python-ethtool/netlink.c b/python-ethtool/netlink.c new file mode 100644 index 0000000..f80ebd4 --- /dev/null +++ b/python-ethtool/netlink.c @@ -0,0 +1,113 @@ +/* netlink.c - Generic NETLINK API functions + * + * Copyright (C) 2009-2013 Red Hat Inc. + * + * David Sommerseth <davids@redhat.com> + * + * This application is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; version 2. + * + * This application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include <Python.h> +#include <pthread.h> +#include <unistd.h> +#include <fcntl.h> +#include <netlink/netlink.h> +#include <netlink/socket.h> + +#include "etherinfo_struct.h" + +pthread_mutex_t nlc_counter_mtx = PTHREAD_MUTEX_INITIALIZER; + + +/** + * Connects to the NETLINK interface. This will be called + * for each etherinfo object being generated, and it will + * keep a separate file descriptor open for each object + * + * @param data etherinfo_obj_data structure + * + * @return Returns 1 on success, otherwise 0. + */ +int open_netlink(struct etherinfo_obj_data *data) +{ + if( !data ) { + return 0; + } + + /* Reuse already established NETLINK connection, if a connection exists */ + if( *data->nlc ) { + /* If this object has not used NETLINK earlier, tag it as a user */ + if( !data->nlc_active ) { + pthread_mutex_lock(&nlc_counter_mtx); + (*data->nlc_users)++; + pthread_mutex_unlock(&nlc_counter_mtx); + } + data->nlc_active = 1; + return 1; + } + + /* No earlier connections exists, establish a new one */ + *data->nlc = nl_socket_alloc(); + nl_connect(*data->nlc, NETLINK_ROUTE); + if( (*data->nlc != NULL) ) { + /* Force O_CLOEXEC flag on the NETLINK socket */ + if( fcntl(nl_socket_get_fd(*data->nlc), F_SETFD, FD_CLOEXEC) == -1 ) { + fprintf(stderr, + "**WARNING** Failed to set O_CLOEXEC on NETLINK socket: %s\n", + strerror(errno)); + } + + /* Tag this object as an active user */ + pthread_mutex_lock(&nlc_counter_mtx); + (*data->nlc_users)++; + pthread_mutex_unlock(&nlc_counter_mtx); + data->nlc_active = 1; + return 1; + } else { + return 0; + } +} + + +/** + * Closes the NETLINK connection. This should be called automatically whenever + * the corresponding etherinfo object is deleted. + * + * @param ptr Pointer to the pointer of struct nl_handle, which contains the NETLINK connection + */ +void close_netlink(struct etherinfo_obj_data *data) +{ + if( !data || !(*data->nlc) ) { + return; + } + + /* Untag this object as a NETLINK user */ + data->nlc_active = 0; + pthread_mutex_lock(&nlc_counter_mtx); + (*data->nlc_users)--; + pthread_mutex_unlock(&nlc_counter_mtx); + + /* Don't close the connection if there are more users */ + if( *data->nlc_users > 0) { + return; + } + + /* Close NETLINK connection */ + nl_close(*data->nlc); + nl_socket_free(*data->nlc); + *data->nlc = NULL; +} + +/* +Local variables: +c-basic-offset: 8 +indent-tabs-mode: y +End: +*/ |