Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rtnl_link_get_info_type return NULL on Fedora 20 #1

Open
celebdor opened this issue Jan 13, 2014 · 1 comment
Open

rtnl_link_get_info_type return NULL on Fedora 20 #1

celebdor opened this issue Jan 13, 2014 · 1 comment

Comments

@celebdor
Copy link

Using the following ctypes wrapping of the library:

from collections import namedtuple
from contextlib import contextmanager
import ctypes


NETLINK_ROUTE = 0
AF_UNSPEC = 0
LIBNL = ctypes.cdll.LoadLibrary('libnl.so')
LIBNL3_ROUTE = ctypes.cdll.LoadLibrary('libnl-route-3.so')

Link = namedtuple('Link',
                  'index name address type flags mtu qdisc master state')


def link_info(link):
    index = LIBNL.rtnl_link_get_ifindex(link)
    name = ctypes.cast(LIBNL.rtnl_link_get_name(link), ctypes.c_char_p).value
    nl_addr = LIBNL.rtnl_link_get_addr(link)
    address = (ctypes.c_char * 32)()
    if nl_addr:
        LIBNL.nl_addr2str(nl_addr, ctypes.byref(address),
                          ctypes.sizeof(address))
        address = address.value
    else:
        address = 'none'
    link_type = ctypes.cast(LIBNL.rtnl_link_get_info_type(link),
                            ctypes.c_char_p).value
    flags = LIBNL.rtnl_link_get_flags(link)
    qdisc = ctypes.cast(LIBNL.rtnl_link_get_qdisc(link), ctypes.c_char_p).value
    mtu = LIBNL.rtnl_link_get_mtu(link)
    master = LIBNL.rtnl_link_get_master(link)
    if master < 1:
        master = None

    state = LIBNL.rtnl_link_get_operstate(link)
    operstate = (ctypes.c_char * 16)()
    LIBNL.rtnl_link_operstate2str(state, operstate, ctypes.sizeof(operstate))
    return Link(index, name, address, link_type, flags, mtu, qdisc,
                master, operstate.value)


def getLinks():
    with nl_link_cache() as cache:
        link = LIBNL.nl_cache_get_first(cache)
        links = []
        while link:
            info = link_info(link)
            links.append(info)
            link = LIBNL.nl_cache_get_next(link)

    return links


@contextmanager
def open_nl_socket():
    handle = LIBNL.nl_handle_alloc()
    if handle is None:
        raise IOError(ctypes.get_errno(), 'Failed to allocate netlink handle')
    try:
        err = LIBNL.nl_connect(handle, NETLINK_ROUTE)
        if err:
            raise IOError(err, 'Failed to connect to netlink socket.')
        yield handle
    finally:
        # handle is closed automatically on destroy.
        LIBNL.nl_handle_destroy(handle)


@contextmanager
def nl_link_cache():
    """Provides a link cache and frees it and its links upon exit."""
    with open_nl_socket() as sock:
        cache = LIBNL.rtnl_link_alloc_cache(sock)
        if cache is None:
            raise IOError('Failed to allocate link cache.')
        try:
            yield cache
        finally:
            LIBNL.nl_cache_free(cache)


if __name__ == '__main__':
    for link in getLinks():
        print link

The type is always reported as Null for any device. As seen here:

Link(index=1, name='lo', address='00:00:00:00:00:00', type=None, flags=65609, mtu=65536, qdisc='noqueue', master=None, state='unknown')
Link(index=2, name='bond0', address='a2:28:ca:6b:ec:3a', type=None, flags=5123, mtu=1500, qdisc='noqueue', master=None, state='down')
Link(index=3, name='em1', address='f0:de:f1:da:f8:e7', type=None, flags=4099, mtu=1500, qdisc='pfifo_fast', master=None, state='down')
Link(index=4, name='wlp3s0', address='24:77:03:5b:a7:80', type=None, flags=69699, mtu=1500, qdisc='mq', master=None, state='up')
Link(index=5, name=';vdsmdummy;', address='ca:0e:20:f2:ca:22', type=None, flags=4098, mtu=1500, qdisc='noop', master=None, state='down')
Link(index=23, name='tun0', address='none', type=None, flags=69841, mtu=1412, qdisc='pfifo_fast', master=None, state='unknown')
@celebdor
Copy link
Author

Additionally the code:

link_type = ctypes.cast(LIBNL.rtnl_link_get_info_type(link),
                            ctypes.c_char_p).value

generates a segmentation fault when used with a vlanned device over a bond 'bond777.555'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant