summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Sommerseth <davids@redhat.com>2013-09-12 17:01:59 +0200
committerDavid Sommerseth <davids@redhat.com>2013-09-12 17:01:59 +0200
commitd9922c0cf642da50794c3d23b61dcdd49684af8e (patch)
treef569204632cb7f7fd5b32198f1842438372e1542
parentc61363e517154548f0b85772e1f83186dff898bc (diff)
downloadpython-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.c104
-rw-r--r--python-ethtool/etherinfo.h7
-rw-r--r--python-ethtool/etherinfo_struct.h9
-rw-r--r--python-ethtool/ethtool.c6
-rw-r--r--python-ethtool/netlink-address.c22
-rw-r--r--setup.py5
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.
diff --git a/setup.py b/setup.py
index 99dc718..6bf992d 100644
--- a/setup.py
+++ b/setup.py
@@ -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',