From abab733a87025960acee7dd0a2c029e679a502a8 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Fri, 13 Sep 2013 18:16:26 +0200 Subject: Rip out the old IPv6 implementation completely The whole IPv6 support will be re-implemented using a simliar strategy as the newer IPv4 support uses. Signed-off-by: David Sommerseth --- python-ethtool/etherinfo.c | 118 +----------------- python-ethtool/etherinfo.h | 3 - python-ethtool/etherinfo_ipv6_obj.c | 230 ------------------------------------ python-ethtool/etherinfo_obj.c | 84 ------------- python-ethtool/etherinfo_struct.h | 21 ---- python-ethtool/ethtool.c | 8 +- setup.py | 1 - 7 files changed, 3 insertions(+), 462 deletions(-) delete mode 100644 python-ethtool/etherinfo_ipv6_obj.c diff --git a/python-ethtool/etherinfo.c b/python-ethtool/etherinfo.c index 75e4cc2..538bcb5 100644 --- a/python-ethtool/etherinfo.c +++ b/python-ethtool/etherinfo.c @@ -61,30 +61,8 @@ pthread_mutex_t nlc_counter_mtx = PTHREAD_MUTEX_INITIALIZER; dst = strdup(src); \ } - -/** - * Frees the memory used by a struct ipv6address pointer chain. All elements are freed - * - * @param ptr Pointer to a struct ipv6address chain. - */ -void free_ipv6addresses(struct ipv6address *ptr) { - struct ipv6address *ipv6ptr = ptr; - - while( ipv6ptr ) { - struct ipv6address *tmp = ipv6ptr->next; - - if( ipv6ptr->address ) { - free(ipv6ptr->address); - ipv6ptr->address = NULL; - } - memset(ipv6ptr, 0, sizeof(struct ipv6address)); - free(ipv6ptr); - ipv6ptr = tmp; - } -} - /** - * Frees the memory used by struct etherinfo, including all struct ipv6address children. + * Frees the memory used by struct etherinfo * * @param ptr Pointer to a struct etherninfo element */ @@ -101,51 +79,10 @@ void free_etherinfo(struct etherinfo *ptr) } Py_XDECREF(ptr->ipv4_addresses); - if( ptr->ipv6_addresses ) { - free_ipv6addresses(ptr->ipv6_addresses); - } free(ptr); } -/** - * Add a new IPv6 address record to a struct ipv6address chain - * - * @param addrptr Pointer to the current IPv6 address chain. - * @param addr IPv6 address, represented as char * string - * @param netmask IPv6 netmask, as returned by libnl rtnl_addr_get_prefixlen() - * @param scope IPV6 address scope, as returned by libnl rtnl_addr_get_scope() - * - * @return Returns a new pointer to the chain containing the new element - */ -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])", - buf, rtnl_addr_get_prefixlen(addr), rtnl_addr_get_scope(addr)); - return addrptr; - } - - 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; -} - - /** * libnl callback function. Does the real parsing of a record returned by NETLINK. This function * parses LINK related packets @@ -218,9 +155,6 @@ static void callback_nl_address(struct nl_object *obj, void *arg) case AF_INET: append_object_for_netlink_address(ethi, rtaddr); return; - case AF_INET6: - ethi->ipv6_addresses = etherinfo_add_ipv6(ethi->ipv6_addresses, rtaddr); - return; default: return; } @@ -234,48 +168,6 @@ static void callback_nl_address(struct nl_object *obj, void *arg) * */ -/** - * Dumps the contents of a struct etherinfo element to file - * - * @param fp FILE pointer where to dump - * @param ptr Pointer to a struct etherinfo element - */ -void dump_etherinfo(FILE *fp, struct etherinfo *ptr) -{ - - fprintf(fp, "*** Interface [%i] %s ", ptr->index, ptr->device); - if( ptr->hwaddress ) { - fprintf(fp, "MAC address: %s", ptr->hwaddress); - } - fprintf(fp, "\n"); - if( ptr->ipv4_addresses ) { - Py_ssize_t i; - for (i = 0; i < PyList_Size(ptr->ipv4_addresses); i++) { - PyNetlinkIPv4Address *addr = (PyNetlinkIPv4Address *)PyList_GetItem(ptr->ipv4_addresses, i); - fprintf(fp, "\tIPv4 Address: %s/%i", - PyString_AsString(addr->ipv4_address), - addr->ipv4_netmask); - if( addr->ipv4_broadcast ) { - fprintf(fp, " - Broadcast: %s", PyString_AsString(addr->ipv4_broadcast)); - } - fprintf(fp, "\n"); - } - } - if( ptr->ipv6_addresses ) { - struct ipv6address *ipv6 = ptr->ipv6_addresses; - - fprintf(fp, "\tIPv6 addresses:\n"); - for(; ipv6; ipv6 = ipv6->next) { - char scope[66]; - - rtnl_scope2str(ipv6->scope, scope, 64); - fprintf(fp, "\t [%s] %s/%i\n", - scope, ipv6->address, ipv6->netmask); - } - } - fprintf(fp, "\n"); -} - /** * Query NETLINK for ethernet configuration @@ -353,13 +245,7 @@ int get_etherinfo(struct etherinfo_obj_data *data, nlQuery query) addr = rtnl_addr_alloc(); rtnl_addr_set_ifindex(addr, ethinf->index); - /* Make sure we don't have any old IPv6 addresses saved */ - if( ethinf->ipv6_addresses ) { - free_ipv6addresses(ethinf->ipv6_addresses); - ethinf->ipv6_addresses = NULL; - } - - /* Likewise for IPv4 addresses: */ + /* Make sure we don't have any old IPv4 addresses saved */ Py_XDECREF(ethinf->ipv4_addresses); ethinf->ipv4_addresses = PyList_New(0); if (!ethinf->ipv4_addresses) { diff --git a/python-ethtool/etherinfo.h b/python-ethtool/etherinfo.h index 8e98b0a..4265e10 100644 --- a/python-ethtool/etherinfo.h +++ b/python-ethtool/etherinfo.h @@ -21,9 +21,6 @@ typedef enum {NLQRY_LINK, NLQRY_ADDR} nlQuery; /**< Supported query types in th int get_etherinfo(struct etherinfo_obj_data *data, nlQuery query); void free_etherinfo(struct etherinfo *ptr); -void dump_etherinfo(FILE *, struct etherinfo *); - -void free_ipv6addresses(struct ipv6address *ptr); int open_netlink(struct etherinfo_obj_data *); void close_netlink(struct etherinfo_obj_data *); diff --git a/python-ethtool/etherinfo_ipv6_obj.c b/python-ethtool/etherinfo_ipv6_obj.c deleted file mode 100644 index fb751d4..0000000 --- a/python-ethtool/etherinfo_ipv6_obj.c +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright (C) 2009-2010 Red Hat Inc. - * - * David Sommerseth - * - * 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. - */ - -/** - * @file etherinfo_ipv6_obj.c - * @author David Sommerseth - * @date Thu Jul 29 17:51:28 2010 - * - * @brief Python ethtool.etherinfo class functions. - * - */ - -#include -#include "structmember.h" - -#include -#include "etherinfo_struct.h" -#include "etherinfo.h" - - -/** - * ethtool.etherinfo_ipv6addr deallocator - cleans up when a object is deleted - * - * @param self etherinfo_ipv6addr_py object structure - */ -void _ethtool_etherinfo_ipv6_dealloc(etherinfo_ipv6addr_py *self) -{ - if( self->addrdata ) { - free_ipv6addresses(self->addrdata); - } - self->ob_type->tp_free((PyObject*)self); -} - - -/** - * ethtool.etherinfo_ipv6addr function, creating a new etherinfo object - * - * @param type - * @param args - * @param kwds - * - * @return Returns in PyObject with the new object on success, otherwise NULL - */ -PyObject *_ethtool_etherinfo_ipv6_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - etherinfo_ipv6addr_py *self; - - self = (etherinfo_ipv6addr_py *)type->tp_alloc(type, 0); - return (PyObject *)self; -} - - -/** - * ethtool.etherinfo_ipv6addr init (constructor) method. Makes sure the object is initialised correctly. - * - * @param self - * @param args - * @param kwds - * - * @return Returns 0 on success. - */ -int _ethtool_etherinfo_ipv6_init(etherinfo_ipv6addr_py *self, PyObject *args, PyObject *kwds) -{ - static char *etherinfo_kwlist[] = {"etherinfo_ipv6_ptr", NULL}; - PyObject *ethinf_ptr = NULL; - - if( !PyArg_ParseTupleAndKeywords(args, kwds, "O", etherinfo_kwlist, ðinf_ptr)) { - PyErr_SetString(PyExc_AttributeError, "Invalid data pointer to constructor"); - return -1; - } - self->addrdata = (struct ipv6address *) PyCObject_AsVoidPtr(ethinf_ptr); - return 0; -} - -/** - * ethtool.etherinfo_ipv6addr function for retrieving data from a Python object. - * - * @param self - * @param attr_o contains the object member request (which element to return) - * - * @return Returns a PyObject with the value requested on success, otherwise NULL - */ -PyObject *_ethtool_etherinfo_ipv6_getter(etherinfo_ipv6addr_py *self, PyObject *attr_o) -{ - PyObject *ret; - char *attr = PyString_AsString(attr_o); - - if( !self || !self->addrdata ) { - PyErr_SetString(PyExc_AttributeError, "No data available"); - return NULL; - } - - if( strcmp(attr, "address") == 0 ) { - ret = RETURN_STRING(self->addrdata->address); - } else if( strcmp(attr, "netmask") == 0 ) { - ret = PyInt_FromLong(self->addrdata->netmask); - } else if( strcmp(attr, "scope") == 0 ) { - char scope[66]; - - rtnl_scope2str(self->addrdata->scope, scope, 66); - ret = PyString_FromString(scope); - } else { - ret = PyObject_GenericGetAttr((PyObject *)self, attr_o); - } - return ret; -} - - -/** - * ethtool.etherinfo_ipv6addr function for setting a value to a object member. This feature is - * disabled by always returning -1, as the values are read-only by the user. - * - * @param self - * @param attr_o - * @param val_o - * - * @return Returns always -1 (failure). - */ -int _ethtool_etherinfo_ipv6_setter(etherinfo_ipv6addr_py *self, PyObject *attr_o, PyObject *val_o) -{ - PyErr_SetString(PyExc_AttributeError, "etherinfo_ipv6addr member values are read-only."); - return -1; -} - - -/** - * Creates a human readable format of the information when object is being treated as a string - * - * @param self - * - * @return Returns a PyObject with a string with all of the information - */ -PyObject *_ethtool_etherinfo_ipv6_str(etherinfo_ipv6addr_py *self) -{ - char scope[66]; - - if( !self || !self->addrdata ) { - PyErr_SetString(PyExc_AttributeError, "No data available"); - return NULL; - } - - rtnl_scope2str(self->addrdata->scope, scope, 64); - return PyString_FromFormat("[%s] %s/%i", - scope, - self->addrdata->address, - self->addrdata->netmask); -} - - -/** - * This is required by Python, which lists all accessible methods - * in the object. But no methods are provided. - * - */ -static PyMethodDef _ethtool_etherinfo_ipv6_methods[] = { - {NULL} /**< No methods defined */ -}; - -/** - * Defines all accessible object members - * - */ -static PyMemberDef _ethtool_etherinfo_ipv6_members[] = { - {"address", T_OBJECT_EX, offsetof(etherinfo_ipv6addr_py, addrdata), 0, - "IPv6 address"}, - {"netmask", T_OBJECT_EX, offsetof(etherinfo_ipv6addr_py, addrdata), 0, - "IPv6 netmask"}, - {"scope", T_OBJECT_EX, offsetof(etherinfo_ipv6addr_py, addrdata), 0, - "IPv6 IP address scope"}, - {NULL} /* End of member list */ -}; - -/** - * Definition of the functions a Python class/object requires. - * - */ -PyTypeObject ethtool_etherinfoIPv6Type = { - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ - "ethtool.etherinfo_ipv6addr", /*tp_name*/ - sizeof(etherinfo_ipv6addr_py), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)_ethtool_etherinfo_ipv6_dealloc,/*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - (reprfunc)_ethtool_etherinfo_ipv6_str, /*tp_str*/ - (getattrofunc)_ethtool_etherinfo_ipv6_getter, /*tp_getattro*/ - (setattrofunc)_ethtool_etherinfo_ipv6_setter, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - "IPv6 address information", /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - _ethtool_etherinfo_ipv6_methods, /* tp_methods */ - _ethtool_etherinfo_ipv6_members, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)_ethtool_etherinfo_ipv6_init, /* tp_init */ - 0, /* tp_alloc */ - _ethtool_etherinfo_ipv6_new, /* tp_new */ -}; - diff --git a/python-ethtool/etherinfo_obj.c b/python-ethtool/etherinfo_obj.c index dad426b..c6ebacc 100644 --- a/python-ethtool/etherinfo_obj.c +++ b/python-ethtool/etherinfo_obj.c @@ -242,21 +242,6 @@ PyObject *_ethtool_etherinfo_str(etherinfo_py *self) } } - if( self->data->ethinfo->ipv6_addresses ) { - struct ipv6address *ipv6 = self->data->ethinfo->ipv6_addresses; - PyObject *tmp = PyString_FromFormat("\tIPv6 addresses:\n"); - PyString_Concat(&ret, tmp); - Py_DECREF(tmp); - for( ; ipv6; ipv6 = ipv6->next) { - char scope[66]; - - rtnl_scope2str(ipv6->scope, scope, 64); - PyObject *addr = PyString_FromFormat("\t [%s] %s/%i\n", - scope, ipv6->address, ipv6->netmask); - PyString_Concat(&ret, addr); - Py_DECREF(addr); - } - } return ret; } @@ -279,73 +264,6 @@ _ethtool_etherinfo_get_ipv4_addresses(etherinfo_py *self, PyObject *notused) { } -/** - * Returns a tuple list of ethertool.etherinfo_ipv6addr objects, containing configured - * IPv6 addresses - * - * @param self - * @param notused - * - * @return Returns a Python tuple list of ethertool.etherinfo_ipv6addr objects - */ -PyObject * _ethtool_etherinfo_get_ipv6_addresses(etherinfo_py *self, PyObject *notused) { - PyObject *ret; - struct ipv6address *ipv6 = NULL; - int i = 0; - - if( !self || !self->data ) { - PyErr_SetString(PyExc_AttributeError, "No data available"); - return NULL; - } - - get_etherinfo(self->data, NLQRY_ADDR); - ipv6 = self->data->ethinfo->ipv6_addresses; - ret = PyTuple_New(1); - if( !ret ) { - PyErr_SetString(PyExc_MemoryError, - "[INTERNAL] Failed to allocate tuple list for " - "IPv6 address objects"); - return NULL; - } - while( ipv6 ) { - PyObject *ipv6_pyobj = NULL, *ipv6_pydata = NULL, *args = NULL; - struct ipv6address *next = ipv6->next; - - ipv6->next = NULL; - ipv6_pydata = PyCObject_FromVoidPtr(ipv6, NULL); - if( !ipv6_pydata ) { - PyErr_SetString(PyExc_MemoryError, - "[INTERNAL] Failed to create python object " - "containing IPv6 address"); - return NULL; - } - args = PyTuple_New(1); - if( !args ) { - PyErr_SetString(PyExc_MemoryError, - "[INTERNAL] Failed to allocate argument list " - "a new IPv6 address object"); - return NULL; - } - PyTuple_SetItem(args, 0, ipv6_pydata); - ipv6_pyobj = PyObject_CallObject((PyObject *)ðtool_etherinfoIPv6Type, args); - Py_DECREF(args); - if( ipv6_pyobj ) { - PyTuple_SetItem(ret, i++, ipv6_pyobj); - _PyTuple_Resize(&ret, i+1); - } else { - PyErr_SetString(PyExc_RuntimeError, - "[INTERNAL] Failed to initialise the new " - "IPv6 address object"); - return NULL; - } - ipv6 = next; - } - _PyTuple_Resize(&ret, i); - self->data->ethinfo->ipv6_addresses = NULL; - return ret; -} - - /** * Defines all available methods in the ethtool.etherinfo class * @@ -353,8 +271,6 @@ PyObject * _ethtool_etherinfo_get_ipv6_addresses(etherinfo_py *self, PyObject *n static PyMethodDef _ethtool_etherinfo_methods[] = { {"get_ipv4_addresses", (PyCFunction)_ethtool_etherinfo_get_ipv4_addresses, METH_NOARGS, "Retrieve configured IPv4 addresses. Returns a list of NetlinkIP4Address objects"}, - {"get_ipv6_addresses", (PyCFunction)_ethtool_etherinfo_get_ipv6_addresses, METH_NOARGS, - "Retrieve configured IPv6 addresses. Returns a tuple list of etherinfo_ipv6addr objects"}, {NULL} /**< No methods defined */ }; diff --git a/python-ethtool/etherinfo_struct.h b/python-ethtool/etherinfo_struct.h index f9c1306..6ae4d78 100644 --- a/python-ethtool/etherinfo_struct.h +++ b/python-ethtool/etherinfo_struct.h @@ -35,7 +35,6 @@ struct etherinfo { int index; /**< NETLINK index reference */ char *hwaddress; /**< HW address / MAC address of device */ PyObject *ipv4_addresses; /**< list of PyNetlinkIPv4Address instances */ - struct ipv6address *ipv6_addresses; /**< Configured IPv6 addresses (as a pointer chain) */ }; /* Python object containing data baked from a (struct rtnl_addr) */ @@ -47,18 +46,6 @@ typedef struct PyNetlinkIPv4Address { } PyNetlinkIPv4Address; extern PyTypeObject ethtool_netlink_ipv4_address_Type; -/** - * Pointer chain with IPv6 addresses associated with a ethernet interface. Used - * by struct etherinfo - */ -struct ipv6address { - char *address; /**< Configured IPv6 address */ - int netmask; /**< Configured IPv6 netmask */ - int scope; /**< Scope for the IPv6 address */ - struct ipv6address *next; /**< Pointer to next configured IPv6 address */ -}; - - /** * Contains the internal data structure of the * ethtool.etherinfo object. @@ -80,14 +67,6 @@ typedef struct { struct etherinfo_obj_data *data; /* IPv4 and IPv6 address information, only one element used */ } etherinfo_py; -/** - * A Python object of struct ipv6address - * - */ -typedef struct { - PyObject_HEAD - struct ipv6address *addrdata; /**< IPv6 address, only one element is used in this case */ -} etherinfo_ipv6addr_py; /** * NULL safe PyString_FromString() wrapper. If input string is NULL, None will be returned diff --git a/python-ethtool/ethtool.c b/python-ethtool/ethtool.c index 8f64be7..4701308 100644 --- a/python-ethtool/ethtool.c +++ b/python-ethtool/ethtool.c @@ -35,7 +35,6 @@ 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; #ifndef IFF_DYNAMIC #define IFF_DYNAMIC 0x8000 /* dialup device with changing addresses*/ @@ -963,12 +962,7 @@ PyMODINIT_FUNC initethtool(void) Py_INCREF(ðtool_etherinfoType); PyModule_AddObject(m, "etherinfo", (PyObject *)ðtool_etherinfoType); - // Prepare the ethtool.etherinfo_ipv6addr class - if (PyType_Ready(ðtool_etherinfoIPv6Type) < 0) - return; - Py_INCREF(ðtool_etherinfoIPv6Type); - PyModule_AddObject(m, "etherinfo_ipv6addr", (PyObject *)ðtool_etherinfoIPv6Type); - + // Prepare the ethtool IPv4 address types if (PyType_Ready(ðtool_netlink_ipv4_address_Type)) return; diff --git a/setup.py b/setup.py index 6bf992d..826b15d 100644 --- a/setup.py +++ b/setup.py @@ -60,7 +60,6 @@ setup(name='ethtool', 'python-ethtool/ethtool.c', 'python-ethtool/etherinfo.c', 'python-ethtool/etherinfo_obj.c', - 'python-ethtool/etherinfo_ipv6_obj.c', 'python-ethtool/netlink-address.c'], include_dirs = libnl['include'], library_dirs = libnl['libdirs'], -- cgit