Skip to content

Commit d8b7393

Browse files
author
David Sommerseth
committed
Split out the link info from get_etherinfo()
This is a needed step for the next move, where we'll query the interfaces for IP address at as late as possible. Signed-off-by: David Sommerseth <davids@redhat.com>
1 parent e3036b2 commit d8b7393

File tree

3 files changed

+87
-44
lines changed

3 files changed

+87
-44
lines changed

python-ethtool/etherinfo.c

Lines changed: 84 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -125,32 +125,108 @@ static void callback_nl_address(struct nl_object *obj, void *arg)
125125
}
126126

127127

128+
/**
129+
* Sets the etherinfo.index member to the corresponding device set in etherinfo.device
130+
*
131+
* @param ethinf A pointer a struct etherinfo element which contains the device name
132+
* and a place to save the corresponding index value.
133+
*
134+
* @return Returns 1 on success, otherwise 0.
135+
*/
136+
static int _set_device_index(struct etherinfo *ethinf)
137+
{
138+
struct nl_cache *link_cache;
139+
struct rtnl_link *link;
140+
141+
/* Find the interface index we're looking up.
142+
* As we don't expect it to change, we're reusing a "cached"
143+
* interface index if we have that
144+
*/
145+
if( ethinf->index < 0 ) {
146+
if( rtnl_link_alloc_cache(get_nlc(), AF_UNSPEC, &link_cache) < 0) {
147+
return 0;
148+
}
149+
150+
link = rtnl_link_get_by_name(link_cache, ethinf->device);
151+
if( !link ) {
152+
nl_cache_free(link_cache);
153+
return 0;
154+
}
155+
156+
ethinf->index = rtnl_link_get_ifindex(link);
157+
if( ethinf->index < 0 ) {
158+
rtnl_link_put(link);
159+
nl_cache_free(link_cache);
160+
return 0;
161+
}
162+
rtnl_link_put(link);
163+
nl_cache_free(link_cache);
164+
}
165+
return 1;
166+
}
167+
128168

129169
/*
130170
*
131171
* Exported functions - API frontend
132172
*
133173
*/
134174

175+
int get_etherinfo_link(etherinfo_py *self)
176+
{
177+
struct nl_cache *link_cache;
178+
struct rtnl_link *link;
179+
struct etherinfo *ethinf = NULL;
180+
181+
if( !self || !self->ethinfo ) {
182+
return 0;
183+
}
184+
ethinf = self->ethinfo;
185+
186+
/* Open a NETLINK connection on-the-fly */
187+
if( !open_netlink(self) ) {
188+
PyErr_Format(PyExc_RuntimeError,
189+
"Could not open a NETLINK connection for %s",
190+
ethinf->device);
191+
return 0;
192+
}
193+
194+
if( _set_device_index(ethinf) != 1) {
195+
return 0;
196+
}
197+
198+
/* Extract MAC/hardware address of the interface */
199+
if( rtnl_link_alloc_cache(get_nlc(), AF_UNSPEC, &link_cache) < 0) {
200+
return 0;
201+
}
202+
link = rtnl_link_alloc();
203+
/* FIXME: Error handling? */
204+
rtnl_link_set_ifindex(link, ethinf->index);
205+
nl_cache_foreach_filter(link_cache, OBJ_CAST(link), callback_nl_link, ethinf);
206+
rtnl_link_put(link);
207+
nl_cache_free(link_cache);
208+
209+
return 1;
210+
}
211+
212+
213+
135214
/**
136-
* Query NETLINK for ethernet configuration
215+
* Query NETLINK for device IP address configuration
137216
*
138217
* @param ethinf Pointer to an available struct etherinfo element. The 'device' member
139218
* must contain a valid string to the device to query for information
140219
* @param nlc Pointer to the libnl handle, which is used for the query against NETLINK
141-
* @param query What to query for. Must be NLQRY_LINK or NLQRY_ADDR.
220+
* @param query What to query for. Must be NLQRY_ADDR4 or NLQRY_ADDR6.
142221
*
143222
* @return Returns 1 on success, otherwise 0.
144223
*/
145224
int get_etherinfo(etherinfo_py *self, nlQuery query)
146225
{
147-
struct nl_cache *link_cache;
148226
struct nl_cache *addr_cache;
149227
struct rtnl_addr *addr;
150-
struct rtnl_link *link;
151228
struct etherinfo *ethinf = NULL;
152229
PyObject *addrlist = NULL;
153-
154230
int ret = 0;
155231

156232
if( !self || !self->ethinfo ) {
@@ -166,46 +242,12 @@ int get_etherinfo(etherinfo_py *self, nlQuery query)
166242
return 0;
167243
}
168244

169-
/* Find the interface index we're looking up.
170-
* As we don't expect it to change, we're reusing a "cached"
171-
* interface index if we have that
172-
*/
173-
if( ethinf->index < 0 ) {
174-
if( rtnl_link_alloc_cache(get_nlc(), AF_UNSPEC, &link_cache) < 0) {
175-
return 0;
176-
}
177-
178-
link = rtnl_link_get_by_name(link_cache, ethinf->device);
179-
if( !link ) {
180-
nl_cache_free(link_cache);
181-
return 0;
182-
}
183-
184-
ethinf->index = rtnl_link_get_ifindex(link);
185-
if( ethinf->index < 0 ) {
186-
rtnl_link_put(link);
187-
nl_cache_free(link_cache);
188-
return 0;
189-
}
190-
rtnl_link_put(link);
191-
nl_cache_free(link_cache);
192-
}
245+
if( _set_device_index(ethinf) != 1) {
246+
return 0;
247+
}
193248

194249
/* Query the for requested info vai NETLINK */
195250
switch( query ) {
196-
case NLQRY_LINK:
197-
/* Extract MAC/hardware address of the interface */
198-
if( rtnl_link_alloc_cache(get_nlc(), AF_UNSPEC, &link_cache) < 0) {
199-
return 0;
200-
}
201-
link = rtnl_link_alloc();
202-
rtnl_link_set_ifindex(link, ethinf->index);
203-
nl_cache_foreach_filter(link_cache, OBJ_CAST(link), callback_nl_link, ethinf);
204-
rtnl_link_put(link);
205-
nl_cache_free(link_cache);
206-
ret = 1;
207-
break;
208-
209251
case NLQRY_ADDR4:
210252
case NLQRY_ADDR6:
211253
/* Extract IP address information */

python-ethtool/etherinfo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
typedef enum {NLQRY_LINK, NLQRY_ADDR4, NLQRY_ADDR6} nlQuery; /**< Supported query types in the etherinfo code */
2121

22+
int get_etherinfo_link(etherinfo_py *data);
2223
int get_etherinfo(etherinfo_py *data, nlQuery query);
2324
void free_etherinfo(struct etherinfo *ptr);
2425

python-ethtool/etherinfo_obj.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ PyObject *_ethtool_etherinfo_getter(etherinfo_py *self, PyObject *attr_o)
147147
return Py_INCREF(Py_None), Py_None;
148148
}
149149
} else if( strcmp(attr, "mac_address") == 0 ) {
150-
get_etherinfo(self, NLQRY_LINK);
150+
get_etherinfo_link(self);
151151
Py_INCREF(self->ethinfo->hwaddress);
152152
return self->ethinfo->hwaddress;
153153
} else if( strcmp(attr, "ipv4_address") == 0 ) {
@@ -216,7 +216,7 @@ PyObject *_ethtool_etherinfo_str(etherinfo_py *self)
216216
return NULL;
217217
}
218218

219-
get_etherinfo(self, NLQRY_LINK);
219+
get_etherinfo_link(self);
220220
get_etherinfo(self, NLQRY_ADDR4);
221221
get_etherinfo(self, NLQRY_ADDR6);
222222

0 commit comments

Comments
 (0)