summaryrefslogtreecommitdiffstats
path: root/python-ethtool/netlink-address.c
diff options
context:
space:
mode:
authorDavid Sommerseth <davids@redhat.com>2013-09-13 20:18:57 +0200
committerDavid Sommerseth <davids@redhat.com>2013-09-13 20:18:57 +0200
commitd3f5fd74bdb903c032eca8ab4e391172d3162c76 (patch)
tree89da2c01762ecf0bb8cee3b195b36ecc329abb28 /python-ethtool/netlink-address.c
parentf8b0e05c03add3d0bd7736c3e3f81e8eb28bc7c3 (diff)
downloadpython-ethtool-d3f5fd74bdb903c032eca8ab4e391172d3162c76.tar.gz
python-ethtool-d3f5fd74bdb903c032eca8ab4e391172d3162c76.tar.xz
python-ethtool-d3f5fd74bdb903c032eca8ab4e391172d3162c76.zip
Merge PyNetlinkIPv4Address and PyNetlinkIPv6Address classes
Simplify the overall implementation by reusing code more efficiently. The differences between the IPv4 and IPv6 implementation in libnl is minimal and can more easily be differentiated those few places its needed instead. Signed-off-by: David Sommerseth <davids@redhat.com>
Diffstat (limited to 'python-ethtool/netlink-address.c')
-rw-r--r--python-ethtool/netlink-address.c222
1 files changed, 94 insertions, 128 deletions
diff --git a/python-ethtool/netlink-address.c b/python-ethtool/netlink-address.c
index 95c1c86..50a96d7 100644
--- a/python-ethtool/netlink-address.c
+++ b/python-ethtool/netlink-address.c
@@ -24,135 +24,60 @@
#include "etherinfo_struct.h"
#include "etherinfo.h"
-/* IPv6 Addresses: */
+
+/* IP Address parsing: */
static PyObject *
-PyNetlinkIPv6Address_from_rtnl_addr(struct rtnl_addr *addr)
+PyNetlinkIPaddress_from_rtnl_addr(struct rtnl_addr *addr)
{
- PyNetlinkIPv6Address *py_obj;
+ PyNetlinkIPaddress *py_obj;
char buf[INET6_ADDRSTRLEN+1];
+ struct nl_addr *peer_addr = NULL, *brdcst = NULL;
- py_obj = PyObject_New(PyNetlinkIPv6Address,
- &ethtool_netlink_ipv6_address_Type);
+ py_obj = PyObject_New(PyNetlinkIPaddress,
+ &ethtool_netlink_ip_address_Type);
if (!py_obj) {
return NULL;
}
- /* Set ipv6_address: */
- memset(&buf, 0, sizeof(buf));
- if (!inet_ntop(AF_INET6, nl_addr_get_binary_addr(rtnl_addr_get_local(addr)),
- buf, sizeof(buf))) {
- PyErr_SetFromErrno(PyExc_RuntimeError);
- goto error;
- }
- py_obj->ipv6_address = PyString_FromString(buf);
- if (!py_obj->ipv6_address) {
+ /* Set IP address family. Only AF_INET and AF_INET6 is supported */
+ py_obj->family = rtnl_addr_get_family(addr);
+ if (py_obj->family != AF_INET && py_obj->family != AF_INET6) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "Only IPv4 (AF_INET) and IPv6 (AF_INET6) address types are supported");
goto error;
}
- /* Set ipv6_netmask: */
- py_obj->ipv6_netmask = rtnl_addr_get_prefixlen(addr);
-
-
- /* Set ipv6_scope: */
+ /* Set local IP address: */
memset(&buf, 0, sizeof(buf));
- rtnl_scope2str(rtnl_addr_get_scope(addr), buf, sizeof(buf));
- py_obj->ipv6_scope = PyString_FromString(buf);
-
- return (PyObject*)py_obj;
-
- error:
- Py_DECREF(py_obj);
- return NULL;
-}
-
-static void
-netlink_ipv6_address_dealloc(PyNetlinkIPv6Address *obj)
-{
- Py_DECREF(obj->ipv6_address);
- Py_DECREF(obj->ipv6_scope);
-
- /* We can call PyObject_Del directly rather than calling through
- tp_free since the type is not subtypable (Py_TPFLAGS_BASETYPE is
- not set): */
- PyObject_Del(obj);
-}
-
-static PyObject*
-netlink_ipv6_address_repr(PyNetlinkIPv6Address *obj)
-{
- PyObject *result = PyString_FromString("ethtool.NetlinkIPv6Address(address='");
- PyString_Concat(&result, obj->ipv6_address);
- PyString_ConcatAndDel(&result,
- PyString_FromFormat("/%d', scope=",
- obj->ipv6_netmask));
- PyString_Concat(&result, obj->ipv6_scope);
- PyString_ConcatAndDel(&result, PyString_FromString(")"));
- return result;
-}
-
-static PyMemberDef _ethtool_netlink_ipv6_address_members[] = {
- {"address",
- T_OBJECT_EX,
- offsetof(PyNetlinkIPv6Address, ipv6_address),
- 0,
- NULL},
- {"netmask",
- T_INT,
- offsetof(PyNetlinkIPv6Address, ipv6_netmask),
- 0,
- NULL},
- {"scope",
- T_OBJECT_EX,
- offsetof(PyNetlinkIPv6Address, ipv6_scope),
- 0,
- NULL},
- {NULL} /* End of member list */
-};
-
-PyTypeObject ethtool_netlink_ipv6_address_Type = {
- PyVarObject_HEAD_INIT(0, 0)
- .tp_name = "ethtool.NetlinkIPv6Address",
- .tp_basicsize = sizeof(PyNetlinkIPv6Address),
- .tp_dealloc = (destructor)netlink_ipv6_address_dealloc,
- .tp_repr = (reprfunc)netlink_ipv6_address_repr,
- .tp_members = _ethtool_netlink_ipv6_address_members,
-};
-
-
-
-/* IPv4 Addresses: */
-static PyObject *
-PyNetlinkIPv4Address_from_rtnl_addr(struct rtnl_addr *addr)
-{
- PyNetlinkIPv4Address *py_obj;
- char buf[INET_ADDRSTRLEN+1];
- struct nl_addr *brdcst;
-
- py_obj = PyObject_New(PyNetlinkIPv4Address,
- &ethtool_netlink_ipv4_address_Type);
- if (!py_obj) {
- return NULL;
- }
-
- /* Set ipv4_address: */
- memset(&buf, 0, sizeof(buf));
- if (!inet_ntop(AF_INET, nl_addr_get_binary_addr(rtnl_addr_get_local(addr)),
+ if (!inet_ntop(py_obj->family, nl_addr_get_binary_addr(rtnl_addr_get_local(addr)),
buf, sizeof(buf))) {
PyErr_SetFromErrno(PyExc_RuntimeError);
goto error;
}
- py_obj->ipv4_address = PyString_FromString(buf);
- if (!py_obj->ipv4_address) {
+ py_obj->local = PyString_FromString(buf);
+ if (!py_obj->local) {
goto error;
}
- /* Set ipv4_netmask: */
- py_obj->ipv4_netmask = rtnl_addr_get_prefixlen(addr);
+ /* Set peer IP address: */
+ memset(&buf, 0, sizeof(buf));
+ if ((peer_addr = rtnl_addr_get_peer(addr))) {
+ nl_addr2str(peer_addr, buf, sizeof(buf));
+ py_obj->peer = PyString_FromString(buf);
+ if (!py_obj->local) {
+ goto error;
+ }
+ } else {
+ py_obj->peer = NULL;
+ }
+
+ /* Set IP address prefix length (netmask): */
+ py_obj->prefixlen = rtnl_addr_get_prefixlen(addr);
/* Set ipv4_broadcast: */
py_obj->ipv4_broadcast = NULL;
brdcst = rtnl_addr_get_broadcast(addr);
- if( brdcst ) {
+ if( py_obj->family == AF_INET && brdcst ) {
memset(&buf, 0, sizeof(buf));
if (!inet_ntop(AF_INET, nl_addr_get_binary_addr(brdcst),
buf, sizeof(buf))) {
@@ -165,6 +90,11 @@ PyNetlinkIPv4Address_from_rtnl_addr(struct rtnl_addr *addr)
}
}
+ /* Set IP address scope: */
+ memset(&buf, 0, sizeof(buf));
+ rtnl_scope2str(rtnl_addr_get_scope(addr), buf, sizeof(buf));
+ py_obj->scope = PyString_FromString(buf);
+
return (PyObject*)py_obj;
error:
@@ -173,10 +103,12 @@ PyNetlinkIPv4Address_from_rtnl_addr(struct rtnl_addr *addr)
}
static void
-netlink_ipv4_address_dealloc(PyNetlinkIPv4Address *obj)
+netlink_ip_address_dealloc(PyNetlinkIPaddress *obj)
{
- Py_DECREF(obj->ipv4_address);
+ Py_DECREF(obj->local);
+ Py_XDECREF(obj->peer);
Py_XDECREF(obj->ipv4_broadcast);
+ Py_XDECREF(obj->scope);
/* We can call PyObject_Del directly rather than calling through
tp_free since the type is not subtypable (Py_TPFLAGS_BASETYPE is
@@ -185,51 +117,87 @@ netlink_ipv4_address_dealloc(PyNetlinkIPv4Address *obj)
}
static PyObject*
-netlink_ipv4_address_repr(PyNetlinkIPv4Address *obj)
+netlink_ip_address_repr(PyNetlinkIPaddress *obj)
{
- PyObject *result = PyString_FromString("ethtool.NetlinkIPv4Address(address='");
- PyString_Concat(&result, obj->ipv4_address);
+ PyObject *result = PyString_FromString("ethtool.NetlinkIPaddress(family=");
+ char buf[256];
+
+ memset(&buf, 0, sizeof(buf));
+ nl_af2str(obj->family, buf, sizeof(buf));
PyString_ConcatAndDel(&result,
- PyString_FromFormat("', netmask=%d",
- obj->ipv4_netmask));
- if (obj->ipv4_broadcast) {
+ PyString_FromFormat("%s, address='", buf));
+ PyString_Concat(&result, obj->local);
+
+ if (obj->family == AF_INET) {
+ PyString_ConcatAndDel(&result,
+ PyString_FromFormat("', netmask=%d",
+ obj->prefixlen));
+ } else if (obj->family == AF_INET6) {
+ PyString_ConcatAndDel(&result,
+ PyString_FromFormat("/%d'",
+ obj->prefixlen));
+ }
+
+ if (obj->peer) {
+ PyString_ConcatAndDel(&result, PyString_FromString(", peer_address='"));
+ PyString_Concat(&result, obj->peer);
+ PyString_ConcatAndDel(&result, PyString_FromString("'"));
+ }
+
+ if (obj->family == AF_INET && obj->ipv4_broadcast) {
PyString_ConcatAndDel(&result, PyString_FromString(", broadcast='"));
PyString_Concat(&result, obj->ipv4_broadcast);
PyString_ConcatAndDel(&result, PyString_FromString("'"));
}
+
+ PyString_ConcatAndDel(&result, PyString_FromString(", scope="));
+ PyString_Concat(&result, obj->scope);
+
PyString_ConcatAndDel(&result, PyString_FromString(")"));
+
return result;
}
-static PyMemberDef _ethtool_netlink_ipv4_address_members[] = {
+
+static PyMemberDef _ethtool_netlink_ip_address_members[] = {
{"address",
T_OBJECT_EX,
- offsetof(PyNetlinkIPv4Address, ipv4_address),
+ offsetof(PyNetlinkIPaddress, local),
+ 0,
+ NULL},
+ {"peer_address",
+ T_OBJECT_EX,
+ offsetof(PyNetlinkIPaddress, peer),
0,
NULL},
{"netmask",
T_INT,
- offsetof(PyNetlinkIPv4Address, ipv4_netmask),
+ offsetof(PyNetlinkIPaddress, prefixlen),
0,
NULL},
{"broadcast",
T_OBJECT, /* can be NULL */
- offsetof(PyNetlinkIPv4Address, ipv4_broadcast),
+ offsetof(PyNetlinkIPaddress, ipv4_broadcast),
+ 0,
+ NULL},
+ {"scope",
+ T_OBJECT_EX,
+ offsetof(PyNetlinkIPaddress, scope),
0,
NULL},
{NULL} /* End of member list */
};
-PyTypeObject ethtool_netlink_ipv4_address_Type = {
+PyTypeObject ethtool_netlink_ip_address_Type = {
PyVarObject_HEAD_INIT(0, 0)
- .tp_name = "ethtool.NetlinkIPv4Address",
- .tp_basicsize = sizeof(PyNetlinkIPv4Address),
- .tp_dealloc = (destructor)netlink_ipv4_address_dealloc,
- .tp_repr = (reprfunc)netlink_ipv4_address_repr,
- .tp_members = _ethtool_netlink_ipv4_address_members,
+ .tp_name = "ethtool.NetlinkIPaddress",
+ .tp_basicsize = sizeof(PyNetlinkIPaddress),
+ .tp_dealloc = (destructor)netlink_ip_address_dealloc,
+ .tp_repr = (reprfunc)netlink_ip_address_repr,
+ .tp_members = _ethtool_netlink_ip_address_members,
};
-/* Factory function, in case we want to generalize this to add IPv6 support */
+
PyObject *
make_python_address_from_rtnl_addr(struct rtnl_addr *addr)
{
@@ -238,10 +206,8 @@ make_python_address_from_rtnl_addr(struct rtnl_addr *addr)
switch( rtnl_addr_get_family(addr) ) {
case AF_INET:
- return PyNetlinkIPv4Address_from_rtnl_addr(addr);
-
case AF_INET6:
- return PyNetlinkIPv6Address_from_rtnl_addr(addr);
+ return PyNetlinkIPaddress_from_rtnl_addr(addr);
default:
return PyErr_SetFromErrno(PyExc_RuntimeError);