diff options
author | David Sommerseth <davids@redhat.com> | 2013-09-12 17:01:59 +0200 |
---|---|---|
committer | David Sommerseth <davids@redhat.com> | 2013-09-12 17:01:59 +0200 |
commit | d9922c0cf642da50794c3d23b61dcdd49684af8e (patch) | |
tree | f569204632cb7f7fd5b32198f1842438372e1542 | |
parent | c61363e517154548f0b85772e1f83186dff898bc (diff) | |
download | python-ethtool-d9922c0cf642da50794c3d23b61dcdd49684af8e.tar.gz python-ethtool-d9922c0cf642da50794c3d23b61dcdd49684af8e.tar.xz python-ethtool-d9922c0cf642da50794c3d23b61dcdd49684af8e.zip |
Migrated from libnl-1 to libnl-3
This ports the current functionality from libnl-1 to libnl-3.0.
At the current stage, it should be functional but more patches
cleaning up the code will come.
Signed-off-by: David Sommerseth <davids@redhat.com>
-rw-r--r-- | python-ethtool/etherinfo.c | 104 | ||||
-rw-r--r-- | python-ethtool/etherinfo.h | 7 | ||||
-rw-r--r-- | python-ethtool/etherinfo_struct.h | 9 | ||||
-rw-r--r-- | python-ethtool/ethtool.c | 6 | ||||
-rw-r--r-- | python-ethtool/netlink-address.c | 22 | ||||
-rw-r--r-- | setup.py | 5 |
6 files changed, 71 insertions, 82 deletions
diff --git a/python-ethtool/etherinfo.c b/python-ethtool/etherinfo.c index 3f2a3e6..75e4cc2 100644 --- a/python-ethtool/etherinfo.c +++ b/python-ethtool/etherinfo.c @@ -1,6 +1,6 @@ /* etherinfo.c - Retrieve ethernet interface info via NETLINK * - * Copyright (C) 2009-2011 Red Hat Inc. + * Copyright (C) 2009-2013 Red Hat Inc. * * David Sommerseth <davids@redhat.com> * Parts of this code is based on ideas and solutions in iproute2 @@ -25,6 +25,13 @@ #include <stdlib.h> #include <asm/types.h> #include <sys/socket.h> +#include <arpa/inet.h> +#include <netlink/netlink.h> +#include <netlink/socket.h> +#include <netlink/cache.h> +#include <netlink/addr.h> +#include <netlink/route/addr.h> +#include <netlink/route/link.h> #include <netlink/route/rtnl.h> #include <assert.h> #include <errno.h> @@ -111,19 +118,29 @@ void free_etherinfo(struct etherinfo *ptr) * * @return Returns a new pointer to the chain containing the new element */ -struct ipv6address * etherinfo_add_ipv6(struct ipv6address *addrptr, const char *addr, int netmask, int scope) { +struct ipv6address * etherinfo_add_ipv6(struct ipv6address *addrptr, struct rtnl_addr *addr) { struct ipv6address *newaddr = NULL; + char buf[INET6_ADDRSTRLEN+2]; + int af_family; + + af_family = rtnl_addr_get_family(addr); + if( af_family != AF_INET && af_family != AF_INET6 ) { + return addrptr; + } + + memset(&buf, 0, sizeof(buf)); + inet_ntop(af_family, nl_addr_get_binary_addr(rtnl_addr_get_local(addr)), buf, sizeof(buf)); newaddr = calloc(1, sizeof(struct ipv6address)+2); if( !newaddr ) { fprintf(stderr, "** ERROR ** Could not allocate memory for a new IPv6 address record (%s/%i [%i])", - addr, netmask, scope); + buf, rtnl_addr_get_prefixlen(addr), rtnl_addr_get_scope(addr)); return addrptr; } - SET_STR_VALUE(newaddr->address, addr); - newaddr->netmask = netmask; - newaddr->scope = scope; + SET_STR_VALUE(newaddr->address, buf); + newaddr->netmask = rtnl_addr_get_prefixlen(addr); + newaddr->scope = rtnl_addr_get_scope(addr); newaddr->next = addrptr; return newaddr; } @@ -140,30 +157,14 @@ static void callback_nl_link(struct nl_object *obj, void *arg) { struct etherinfo *ethi = (struct etherinfo *) arg; struct rtnl_link *link = (struct rtnl_link *) obj; - struct nl_addr *addr = rtnl_link_get_addr(link); - unsigned int i, len; - unsigned char *binaddr; - char hwaddr[130], *ptr; + char hwaddr[130]; - if( (ethi == NULL) || (ethi->hwaddress != NULL) || (addr == NULL) ) { + if( (ethi == NULL) || (ethi->hwaddress != NULL) ) { return; } - binaddr = nl_addr_get_binary_addr(addr); memset(&hwaddr, 0, 130); - len = 20; - ptr = (char *)&hwaddr; - for( i = 0; i < 6; i++ ) { - if( i == 0 ) { - snprintf(ptr, len, "%02X", *(binaddr+i)); - len -= 2; - ptr += 2; - } else { - snprintf(ptr, len, ":%02X", *(binaddr+i)); - len -= 3; - ptr += 3; - } - } + nl_addr2str(rtnl_link_get_addr(link), hwaddr, sizeof(hwaddr)); SET_STR_VALUE(ethi->hwaddress, hwaddr); } @@ -173,7 +174,6 @@ static void callback_nl_link(struct nl_object *obj, void *arg) */ static int append_object_for_netlink_address(struct etherinfo *ethi, - struct nl_object *obj, struct rtnl_addr *addr) { PyObject *addr_obj; @@ -182,7 +182,7 @@ append_object_for_netlink_address(struct etherinfo *ethi, assert(ethi->ipv4_addresses); assert(addr); - addr_obj = make_python_address_from_rtnl_addr(obj, addr); + addr_obj = make_python_address_from_rtnl_addr(addr); if (!addr_obj) { return -1; } @@ -208,30 +208,18 @@ append_object_for_netlink_address(struct etherinfo *ethi, static void callback_nl_address(struct nl_object *obj, void *arg) { struct etherinfo *ethi = (struct etherinfo *) arg; - struct nl_addr *addr; - char ip_str[66]; - int family; + struct rtnl_addr *rtaddr = (struct rtnl_addr *) obj; if( ethi == NULL ) { return; } - addr = rtnl_addr_get_local((struct rtnl_addr *)obj); - family = nl_addr_get_family(addr); - switch( family ) { + switch( rtnl_addr_get_family(rtaddr) ) { case AF_INET: + append_object_for_netlink_address(ethi, rtaddr); + return; case AF_INET6: - memset(&ip_str, 0, 66); - inet_ntop(family, nl_addr_get_binary_addr(addr), (char *)&ip_str, 64); - - if( family == AF_INET ) { - (void)append_object_for_netlink_address(ethi, obj, (struct rtnl_addr*) addr); - } else { - ethi->ipv6_addresses = etherinfo_add_ipv6(ethi->ipv6_addresses, - ip_str, - rtnl_addr_get_prefixlen((struct rtnl_addr*) obj), - rtnl_addr_get_scope((struct rtnl_addr*) obj)); - } + ethi->ipv6_addresses = etherinfo_add_ipv6(ethi->ipv6_addresses, rtaddr); return; default: return; @@ -326,8 +314,16 @@ int get_etherinfo(struct etherinfo_obj_data *data, nlQuery query) * interface index if we have that */ if( ethinf->index < 0 ) { - link_cache = rtnl_link_alloc_cache(*data->nlc); - ethinf->index = rtnl_link_name2i(link_cache, ethinf->device); + if( rtnl_link_alloc_cache(*data->nlc, AF_UNSPEC, &link_cache) < 0) { + return 0; + } + + link = rtnl_link_get_by_name(link_cache, ethinf->device); + if( !link ) { + return 0; + } + + ethinf->index = rtnl_link_get_ifindex(link); if( ethinf->index < 0 ) { return 0; } @@ -338,10 +334,12 @@ int get_etherinfo(struct etherinfo_obj_data *data, nlQuery query) switch( query ) { case NLQRY_LINK: /* Extract MAC/hardware address of the interface */ - link_cache = rtnl_link_alloc_cache(*data->nlc); + if( rtnl_link_alloc_cache(*data->nlc, AF_UNSPEC, &link_cache) < 0) { + return 0; + } link = rtnl_link_alloc(); rtnl_link_set_ifindex(link, ethinf->index); - nl_cache_foreach_filter(link_cache, (struct nl_object *)link, callback_nl_link, ethinf); + nl_cache_foreach_filter(link_cache, OBJ_CAST(link), callback_nl_link, ethinf); rtnl_link_put(link); nl_cache_free(link_cache); ret = 1; @@ -349,7 +347,9 @@ int get_etherinfo(struct etherinfo_obj_data *data, nlQuery query) case NLQRY_ADDR: /* Extract IP address information */ - addr_cache = rtnl_addr_alloc_cache(*data->nlc); + if( rtnl_addr_alloc_cache(*data->nlc, &addr_cache) < 0) { + return 0; + } addr = rtnl_addr_alloc(); rtnl_addr_set_ifindex(addr, ethinf->index); @@ -367,7 +367,7 @@ int get_etherinfo(struct etherinfo_obj_data *data, nlQuery query) } /* Retrieve all address information */ - nl_cache_foreach_filter(addr_cache, (struct nl_object *)addr, callback_nl_address, ethinf); + nl_cache_foreach_filter(addr_cache, OBJ_CAST(addr), callback_nl_address, ethinf); rtnl_addr_put(addr); nl_cache_free(addr_cache); ret = 1; @@ -408,7 +408,7 @@ int open_netlink(struct etherinfo_obj_data *data) } /* No earlier connections exists, establish a new one */ - *data->nlc = nl_handle_alloc(); + *data->nlc = nl_socket_alloc(); nl_connect(*data->nlc, NETLINK_ROUTE); if( (*data->nlc != NULL) ) { /* Force O_CLOEXEC flag on the NETLINK socket */ @@ -455,6 +455,6 @@ void close_netlink(struct etherinfo_obj_data *data) /* Close NETLINK connection */ nl_close(*data->nlc); - nl_handle_destroy(*data->nlc); + nl_socket_free(*data->nlc); *data->nlc = NULL; } diff --git a/python-ethtool/etherinfo.h b/python-ethtool/etherinfo.h index 5e1056a..8e98b0a 100644 --- a/python-ethtool/etherinfo.h +++ b/python-ethtool/etherinfo.h @@ -17,13 +17,6 @@ #ifndef _ETHERINFO_H #define _ETHERINFO_H -#include <netlink/addr.h> -#include <netlink/netlink.h> -#include <netlink/handlers.h> -#include <netlink/route/link.h> -#include <netlink/route/addr.h> -#include <arpa/inet.h> - typedef enum {NLQRY_LINK, NLQRY_ADDR} nlQuery; /**< Supported query types in the etherinfo code */ int get_etherinfo(struct etherinfo_obj_data *data, nlQuery query); diff --git a/python-ethtool/etherinfo_struct.h b/python-ethtool/etherinfo_struct.h index bcb692d..f9c1306 100644 --- a/python-ethtool/etherinfo_struct.h +++ b/python-ethtool/etherinfo_struct.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2011 Red Hat Inc. + * Copyright (C) 2009-2013 Red Hat Inc. * * David Sommerseth <davids@redhat.com> * @@ -13,7 +13,6 @@ * General Public License for more details. */ -#include <netlink/route/addr.h> /** * @file etherinfo_struct.h @@ -66,7 +65,7 @@ struct ipv6address { * */ struct etherinfo_obj_data { - struct nl_handle **nlc; /**< Contains NETLINK connection info (global) */ + struct nl_sock **nlc; /**< Contains NETLINK connection info (global) */ unsigned int *nlc_users; /**< Resource counter for the NETLINK connection (global) */ unsigned short nlc_active; /**< Is this instance using NETLINK? */ struct etherinfo *ethinfo; /**< Contains info about our current interface */ @@ -99,9 +98,7 @@ typedef struct { */ #define RETURN_STRING(str) (str ? PyString_FromString(str) : (Py_INCREF(Py_None), Py_None)) -PyObject * -make_python_address_from_rtnl_addr(struct nl_object *obj, - struct rtnl_addr *addr); +PyObject * make_python_address_from_rtnl_addr(struct rtnl_addr *addr); #endif diff --git a/python-ethtool/ethtool.c b/python-ethtool/ethtool.c index afa14dc..8f64be7 100644 --- a/python-ethtool/ethtool.c +++ b/python-ethtool/ethtool.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2011 Red Hat Inc. + * Copyright (C) 2008-2013 Red Hat Inc. * * Arnaldo Carvalho de Melo <acme@redhat.com> * David Sommerseth <davids@redhat.com> @@ -22,17 +22,17 @@ #include <stdint.h> #include <unistd.h> #include <sys/socket.h> -#include <net/if.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <sys/types.h> #include <ifaddrs.h> +#include <netlink/route/addr.h> #include "etherinfo_struct.h" #include "etherinfo_obj.h" #include "etherinfo.h" -static struct nl_handle *nlconnection = NULL; +static struct nl_sock *nlconnection = NULL; unsigned int nlconnection_users = 0; /* How many NETLINK users are active? */ extern PyTypeObject ethtool_etherinfoType; extern PyTypeObject ethtool_etherinfoIPv6Type; diff --git a/python-ethtool/netlink-address.c b/python-ethtool/netlink-address.c index 21976be..35c0849 100644 --- a/python-ethtool/netlink-address.c +++ b/python-ethtool/netlink-address.c @@ -17,13 +17,15 @@ #include <Python.h> #include "structmember.h" -#include <netlink/route/rtnl.h> +#include <arpa/inet.h> +#include <netlink/addr.h> +#include <netlink/route/addr.h> #include "etherinfo_struct.h" #include "etherinfo.h" /* IPv4 Addresses: */ static PyObject * -PyNetlinkIPv4Address_from_rtnl_addr(struct nl_object *nl_obj, struct rtnl_addr *addr) +PyNetlinkIPv4Address_from_rtnl_addr(struct rtnl_addr *addr) { PyNetlinkIPv4Address *py_obj; char buf[INET_ADDRSTRLEN+1]; @@ -37,7 +39,7 @@ PyNetlinkIPv4Address_from_rtnl_addr(struct nl_object *nl_obj, struct rtnl_addr * /* Set ipv4_address: */ memset(&buf, 0, sizeof(buf)); - if (!inet_ntop(AF_INET, nl_addr_get_binary_addr((struct nl_addr *)addr), + if (!inet_ntop(AF_INET, nl_addr_get_binary_addr(rtnl_addr_get_local(addr)), buf, sizeof(buf))) { PyErr_SetFromErrno(PyExc_RuntimeError); goto error; @@ -48,11 +50,11 @@ PyNetlinkIPv4Address_from_rtnl_addr(struct nl_object *nl_obj, struct rtnl_addr * } /* Set ipv4_netmask: */ - py_obj->ipv4_netmask = rtnl_addr_get_prefixlen((struct rtnl_addr*)nl_obj); + py_obj->ipv4_netmask = rtnl_addr_get_prefixlen(addr); /* Set ipv4_broadcast: */ py_obj->ipv4_broadcast = NULL; - brdcst = rtnl_addr_get_broadcast((struct rtnl_addr*)nl_obj); + brdcst = rtnl_addr_get_broadcast(addr); if( brdcst ) { memset(&buf, 0, sizeof(buf)); if (!inet_ntop(AF_INET, nl_addr_get_binary_addr(brdcst), @@ -132,18 +134,14 @@ PyTypeObject ethtool_netlink_ipv4_address_Type = { /* Factory function, in case we want to generalize this to add IPv6 support */ PyObject * -make_python_address_from_rtnl_addr(struct nl_object *obj, - struct rtnl_addr *addr) +make_python_address_from_rtnl_addr(struct rtnl_addr *addr) { - int family; assert(addr); - family = nl_addr_get_family((struct nl_addr *)addr); - - switch( family ) { + switch( rtnl_addr_get_family(addr) ) { case AF_INET: - return PyNetlinkIPv4Address_from_rtnl_addr(obj, addr); + return PyNetlinkIPv4Address_from_rtnl_addr(addr); /* For now, we just support IPv4 addresses. @@ -4,7 +4,7 @@ from distutils.core import setup, Extension import commands import sys -version = '0.8' +version = '0.9' def pkgconfig(pkg): def _str2list(pkgstr, onlystr): @@ -43,7 +43,8 @@ def pkgconfig(pkg): } -libnl = pkgconfig('libnl-1') +libnl = pkgconfig('libnl-3.0') +libnl['libs'].append('nl-route-3') # don't reformat this line, Makefile parses it setup(name='ethtool', |