Skip to content

Commit d100556

Browse files
author
David Sommerseth
committed
Get rid of the internal IP address lists
With the new structure, these pointers are of no use. Kick them out. The result of this is that get_etherinfo_address() now returns a Python object which contains a list of IP address objects. Signed-off-by: David Sommerseth <davids@redhat.com>
1 parent 52b17fc commit d100556

File tree

4 files changed

+41
-85
lines changed

4 files changed

+41
-85
lines changed

python-ethtool/etherinfo.c

Lines changed: 16 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,6 @@ void free_etherinfo(struct etherinfo *ptr)
5555
free(ptr->device);
5656

5757
Py_XDECREF(ptr->hwaddress);
58-
Py_XDECREF(ptr->ipv4_addresses);
59-
Py_XDECREF(ptr->ipv6_addresses);
6058

6159
free(ptr);
6260
}
@@ -219,18 +217,17 @@ int get_etherinfo_link(etherinfo_py *self)
219217
* @param nlc Pointer to the libnl handle, which is used for the query against NETLINK
220218
* @param query What to query for. Must be NLQRY_ADDR4 or NLQRY_ADDR6.
221219
*
222-
* @return Returns 1 on success, otherwise 0.
220+
* @return Returns a Python list containing PyNetlinkIPaddress objects on success, otherwise NULL
223221
*/
224-
int get_etherinfo_address(etherinfo_py *self, nlQuery query)
222+
PyObject * get_etherinfo_address(etherinfo_py *self, nlQuery query)
225223
{
226224
struct nl_cache *addr_cache;
227225
struct rtnl_addr *addr;
228226
struct etherinfo *ethinf = NULL;
229227
PyObject *addrlist = NULL;
230-
int ret = 0;
231228

232229
if( !self || !self->ethinfo ) {
233-
return 0;
230+
return NULL;
234231
}
235232
ethinf = self->ethinfo;
236233

@@ -239,19 +236,19 @@ int get_etherinfo_address(etherinfo_py *self, nlQuery query)
239236
PyErr_Format(PyExc_RuntimeError,
240237
"Could not open a NETLINK connection for %s",
241238
ethinf->device);
242-
return 0;
239+
return NULL;
243240
}
244241

245242
if( _set_device_index(ethinf) != 1) {
246-
return 0;
243+
return NULL;
247244
}
248245

249246
/* Query the for requested info via NETLINK */
250247

251248
/* Extract IP address information */
252249
if( rtnl_addr_alloc_cache(get_nlc(), &addr_cache) < 0) {
253250
nl_cache_free(addr_cache);
254-
return 0;
251+
return NULL;
255252
}
256253
addr = rtnl_addr_alloc();
257254
/* FIXME: Error handling? */
@@ -260,46 +257,24 @@ int get_etherinfo_address(etherinfo_py *self, nlQuery query)
260257
switch( query ) {
261258
case NLQRY_ADDR4:
262259
rtnl_addr_set_family(addr, AF_INET);
263-
264-
/* Make sure we don't have any old IPv4 addresses saved */
265-
Py_XDECREF(ethinf->ipv4_addresses);
266-
ethinf->ipv4_addresses = PyList_New(0);
267-
if (!ethinf->ipv4_addresses) {
268-
rtnl_addr_put(addr);
269-
nl_cache_free(addr_cache);
270-
return 0;
271-
}
272-
assert(ethinf->ipv4_addresses);
273-
addrlist = ethinf->ipv4_addresses;
274-
ret = 1;
275260
break;
276261

277262
case NLQRY_ADDR6:
278263
rtnl_addr_set_family(addr, AF_INET6);
279-
280-
/* Likewise for IPv6 addresses: */
281-
Py_XDECREF(ethinf->ipv6_addresses);
282-
ethinf->ipv6_addresses = PyList_New(0);
283-
if (!ethinf->ipv6_addresses) {
284-
rtnl_addr_put(addr);
285-
nl_cache_free(addr_cache);
286-
return 0;
287-
}
288-
assert(ethinf->ipv6_addresses);
289-
addrlist = ethinf->ipv6_addresses;
290-
ret = 1;
291264
break;
292265

293266
default:
294-
ret = 0;
267+
return NULL;
295268
}
296269

297-
if( ret == 1 ) {
298-
/* Retrieve all address information - common code for NLQRY_ADDR4 and NLQRY_ADDR6*/
299-
nl_cache_foreach_filter(addr_cache, OBJ_CAST(addr), callback_nl_address, addrlist);
300-
rtnl_addr_put(addr);
301-
nl_cache_free(addr_cache);
302-
}
270+
/* Retrieve all address information */
271+
addrlist = PyList_New(0); /* The list where to put the address object */
272+
assert(addrlist);
273+
274+
/* Loop through all configured addresses */
275+
nl_cache_foreach_filter(addr_cache, OBJ_CAST(addr), callback_nl_address, addrlist);
276+
rtnl_addr_put(addr);
277+
nl_cache_free(addr_cache);
303278

304-
return ret;
279+
return addrlist;
305280
}

python-ethtool/etherinfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
typedef enum {NLQRY_ADDR4, NLQRY_ADDR6} nlQuery; /**< Supported query types in the etherinfo code */
2121

2222
int get_etherinfo_link(etherinfo_py *data);
23-
int get_etherinfo_address(etherinfo_py *data, nlQuery query);
23+
PyObject * get_etherinfo_address(etherinfo_py *self, nlQuery query);
2424
void free_etherinfo(struct etherinfo *ptr);
2525

2626
int open_netlink(etherinfo_py *);

python-ethtool/etherinfo_obj.c

Lines changed: 24 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -96,26 +96,23 @@ int _ethtool_etherinfo_init(etherinfo_py *self, PyObject *args, PyObject *kwds)
9696
9797
The return value is a *borrowed reference* (or NULL)
9898
*/
99-
static PyNetlinkIPaddress * get_last_ipv4_address(etherinfo_py *self)
99+
static PyNetlinkIPaddress * get_last_ipv4_address(PyObject *addrlist)
100100
{
101101
Py_ssize_t size;
102-
PyObject *list;
103102

104-
assert(self);
105-
list = self->ethinfo->ipv4_addresses;
106-
if (!list) {
103+
if (!addrlist) {
107104
return NULL;
108105
}
109106

110-
if (!PyList_Check(list)) {
107+
if (!PyList_Check(addrlist)) {
111108
return NULL;
112109
}
113110

114-
size = PyList_Size(list);
111+
size = PyList_Size(addrlist);
115112
if (size > 0) {
116-
PyObject *item = PyList_GetItem(list, size - 1);
113+
PyNetlinkIPaddress *item = (PyNetlinkIPaddress *)PyList_GetItem(addrlist, size - 1);
117114
if (Py_TYPE(item) == &ethtool_netlink_ip_address_Type) {
118-
return (PyNetlinkIPaddress*)item;
115+
return item;
119116
}
120117
}
121118

@@ -134,6 +131,7 @@ PyObject *_ethtool_etherinfo_getter(etherinfo_py *self, PyObject *attr_o)
134131
{
135132
char *attr = PyString_AsString(attr_o);
136133
PyNetlinkIPaddress *py_addr;
134+
PyObject *addrlist = NULL;
137135

138136
if( !self || !self->ethinfo ) {
139137
PyErr_SetString(PyExc_AttributeError, "No data available");
@@ -151,9 +149,9 @@ PyObject *_ethtool_etherinfo_getter(etherinfo_py *self, PyObject *attr_o)
151149
Py_INCREF(self->ethinfo->hwaddress);
152150
return self->ethinfo->hwaddress;
153151
} else if( strcmp(attr, "ipv4_address") == 0 ) {
154-
get_etherinfo_address(self, NLQRY_ADDR4);
152+
addrlist = get_etherinfo_address(self, NLQRY_ADDR4);
155153
/* For compatiblity with old approach, return last IPv4 address: */
156-
py_addr = get_last_ipv4_address(self);
154+
py_addr = get_last_ipv4_address(addrlist);
157155
if (py_addr) {
158156
if (py_addr->local) {
159157
Py_INCREF(py_addr->local);
@@ -162,15 +160,15 @@ PyObject *_ethtool_etherinfo_getter(etherinfo_py *self, PyObject *attr_o)
162160
}
163161
Py_RETURN_NONE;
164162
} else if( strcmp(attr, "ipv4_netmask") == 0 ) {
165-
get_etherinfo_address(self, NLQRY_ADDR4);
166-
py_addr = get_last_ipv4_address(self);
163+
addrlist = get_etherinfo_address(self, NLQRY_ADDR4);
164+
py_addr = get_last_ipv4_address(addrlist);
167165
if (py_addr) {
168166
return PyInt_FromLong(py_addr->prefixlen);
169167
}
170168
return PyInt_FromLong(0);
171169
} else if( strcmp(attr, "ipv4_broadcast") == 0 ) {
172-
get_etherinfo_address(self, NLQRY_ADDR4);
173-
py_addr = get_last_ipv4_address(self);
170+
addrlist = get_etherinfo_address(self, NLQRY_ADDR4);
171+
py_addr = get_last_ipv4_address(addrlist);
174172
if (py_addr) {
175173
if (py_addr->ipv4_broadcast) {
176174
Py_INCREF(py_addr->ipv4_broadcast);
@@ -210,15 +208,14 @@ int _ethtool_etherinfo_setter(etherinfo_py *self, PyObject *attr_o, PyObject *va
210208
PyObject *_ethtool_etherinfo_str(etherinfo_py *self)
211209
{
212210
PyObject *ret = NULL;
211+
PyObject *ipv4addrs = NULL, *ipv6addrs = NULL;
213212

214213
if( !self || !self->ethinfo ) {
215214
PyErr_SetString(PyExc_AttributeError, "No data available");
216215
return NULL;
217216
}
218217

219218
get_etherinfo_link(self);
220-
get_etherinfo_address(self, NLQRY_ADDR4);
221-
get_etherinfo_address(self, NLQRY_ADDR6);
222219

223220
ret = PyString_FromFormat("Device %s:\n", self->ethinfo->device);
224221
if( self->ethinfo->hwaddress ) {
@@ -227,10 +224,11 @@ PyObject *_ethtool_etherinfo_str(etherinfo_py *self)
227224
PyString_ConcatAndDel(&ret, PyString_FromString("\n"));
228225
}
229226

230-
if( self->ethinfo->ipv4_addresses ) {
227+
ipv4addrs = get_etherinfo_address(self, NLQRY_ADDR4);
228+
if( ipv4addrs ) {
231229
Py_ssize_t i;
232-
for (i = 0; i < PyList_Size(self->ethinfo->ipv4_addresses); i++) {
233-
PyNetlinkIPaddress *py_addr = (PyNetlinkIPaddress *)PyList_GetItem(self->ethinfo->ipv4_addresses, i);
230+
for (i = 0; i < PyList_Size(ipv4addrs); i++) {
231+
PyNetlinkIPaddress *py_addr = (PyNetlinkIPaddress *)PyList_GetItem(ipv4addrs, i);
234232
PyObject *tmp = PyString_FromFormat("\tIPv4 address: ");
235233
PyString_Concat(&tmp, py_addr->local);
236234
PyString_ConcatAndDel(&tmp, PyString_FromFormat("/%d", py_addr->prefixlen));
@@ -244,10 +242,11 @@ PyObject *_ethtool_etherinfo_str(etherinfo_py *self)
244242
}
245243
}
246244

247-
if( self->ethinfo->ipv6_addresses ) {
245+
ipv6addrs = get_etherinfo_address(self, NLQRY_ADDR6);
246+
if( ipv6addrs ) {
248247
Py_ssize_t i;
249-
for (i = 0; i < PyList_Size(self->ethinfo->ipv6_addresses); i++) {
250-
PyNetlinkIPaddress *py_addr = (PyNetlinkIPaddress *)PyList_GetItem(self->ethinfo->ipv6_addresses, i);
248+
for (i = 0; i < PyList_Size(ipv6addrs); i++) {
249+
PyNetlinkIPaddress *py_addr = (PyNetlinkIPaddress *)PyList_GetItem(ipv6addrs, i);
251250
PyObject *tmp = PyString_FromFormat("\tIPv6 address: [");
252251
PyString_Concat(&tmp, py_addr->scope);
253252
PyString_ConcatAndDel(&tmp, PyString_FromString("] "));
@@ -270,20 +269,12 @@ PyObject *_ethtool_etherinfo_str(etherinfo_py *self)
270269
* @return Returns a Python tuple list of NetlinkIP4Address objects
271270
*/
272271
static PyObject *_ethtool_etherinfo_get_ipv4_addresses(etherinfo_py *self, PyObject *notused) {
273-
PyObject *ret;
274-
275272
if( !self || !self->ethinfo ) {
276273
PyErr_SetString(PyExc_AttributeError, "No data available");
277274
return NULL;
278275
}
279276

280-
get_etherinfo_address(self, NLQRY_ADDR4);
281-
282-
/* Transfer ownership of reference: */
283-
ret = self->ethinfo->ipv4_addresses;
284-
self->ethinfo->ipv4_addresses = NULL;
285-
286-
return ret;
277+
return get_etherinfo_address(self, NLQRY_ADDR4);
287278
}
288279

289280

@@ -296,20 +287,12 @@ static PyObject *_ethtool_etherinfo_get_ipv4_addresses(etherinfo_py *self, PyObj
296287
* @return Returns a Python tuple list of NetlinkIP6Address objects
297288
*/
298289
static PyObject *_ethtool_etherinfo_get_ipv6_addresses(etherinfo_py *self, PyObject *notused) {
299-
PyObject *ret;
300-
301290
if( !self || !self->ethinfo ) {
302291
PyErr_SetString(PyExc_AttributeError, "No data available");
303292
return NULL;
304293
}
305294

306-
get_etherinfo_address(self, NLQRY_ADDR6);
307-
308-
/* Transfer ownership of reference: */
309-
ret = self->ethinfo->ipv6_addresses;
310-
self->ethinfo->ipv6_addresses = NULL;
311-
312-
return ret;
295+
return get_etherinfo_address(self, NLQRY_ADDR6);
313296
}
314297

315298

python-ethtool/etherinfo_struct.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@ struct etherinfo {
3434
char *device; /**< Device name */
3535
int index; /**< NETLINK index reference */
3636
PyObject *hwaddress; /**< string: HW address / MAC address of device */
37-
PyObject *ipv4_addresses; /**< list of PyNetlinkIPv4Address instances */
38-
PyObject *ipv6_addresses; /**< list of PyNetlinkIPv6Addresses instances */
3937
};
4038

4139
/* Python object containing data baked from a (struct rtnl_addr) */

0 commit comments

Comments
 (0)