Hi,
the current release 2014.0.0 made some problems for me because Debian the new function "rtnl_open" conflicted with libnl-3.0. libnl-3.0 was used in the Debian package to follow the Debian policy chapter 4 about duplicated code.
Using libnl should not be a problem for any linux system because everyone uses it when wireless configuration is done. For example libnl-tiny is already used by the normal OpenWrt system in base system packages:
* netifd * swconfig * authsae * hostapd * iproute2 * iw * iwinfo
So it is nearly impossible to not have installed ;)
An additional benefit is the already tested code, better type checks and more linear code instead of lot of loops to parse the data.
The Makefile is written in such a way that it:
* tries to find pkg-config (can be overwritten by setting PKG_CONFIG as environment variable/make parameter) * tries to find the libnl CFLAGS + LDLIBS (can be avoided by setting LIBNL_CFLAGS/LIBNL_LDLIBS as environment variable/make parameter) ** the search for the CFLAGS + LDLIBS is done using pkg-config using the library name libnl-3.0 (this can be changed by setting LIBNL_NAME as environment variable/make parameter)
Kind regards, Sven
libnl is used in Debian to avoid code duplication which should be avoided to reduce maintenance and security risks. This library already provides a function called rtnl_open and therefore has a name clash with the self defined function.
Signed-off-by: Sven Eckelmann sven@narfation.org --- functions.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/functions.c b/functions.c index 8894df4..10a7f86 100644 --- a/functions.c +++ b/functions.c @@ -499,13 +499,13 @@ static void request_mac_resolve(int ai_family, const void *l3addr) }
/** - * rtnl_open - open a socket to rtnl and send a request + * batadv_rtnl_open - open a socket to rtnl and send a request * @nh: the header of the request to send * @protocol: the protocol to use when opening the socket * * Return 0 on success or a negative error code otherwise */ -static int rtnl_open(void *req, int protocol) +static int batadv_rtnl_open(void *req, int protocol) { static uint32_t nr_call = 0; uint32_t pid = (++nr_call + getpid()) & 0x3FFFFF; @@ -555,7 +555,7 @@ static int resolve_mac_from_cache_open(int ai_family) nlreq.hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP; nlreq.msg.ndm_family = ai_family;
- return rtnl_open(&nlreq, NETLINK_ROUTE); + return batadv_rtnl_open(&nlreq, NETLINK_ROUTE); }
static ssize_t resolve_mac_from_cache_dump(int sock, void **buf, size_t *buflen) @@ -890,7 +890,7 @@ static int vlan_get_link_open(const char *ifname) nlreq.ifi.ifi_family = AF_UNSPEC; nlreq.ifi.ifi_index = if_nametoindex(ifname);
- return rtnl_open(&nlreq, 0); + return batadv_rtnl_open(&nlreq, 0); }
/**
It is not necessary to have code duplicated which is already available in libraries like libnl-3.0 or libnl-tiny. This is done to reduce maintenance and security risks.
Signed-off-by: Sven Eckelmann sven@narfation.org --- Makefile | 18 ++++ functions.c | 312 +++++++++++++++++++++++++----------------------------------- 2 files changed, 149 insertions(+), 181 deletions(-)
diff --git a/Makefile b/Makefile index fc0925d..0eb71a1 100755 --- a/Makefile +++ b/Makefile @@ -43,6 +43,24 @@ ifndef V endif endif
+ifeq ($(origin PKG_CONFIG), undefined) + PKG_CONFIG = pkg-config + ifeq ($(shell which $(PKG_CONFIG) 2>/dev/null),) + $(error $(PKG_CONFIG) not found) + endif +endif + +ifeq ($(origin LIBNL_CFLAGS) $(origin LIBNL_LDLIBS), undefined undefined) + LIBNL_NAME ?= libnl-3.0 + ifeq ($(shell $(PKG_CONFIG) --modversion $(LIBNL_NAME) 2>/dev/null),) + $(error No $(LIBNL_NAME) development libraries found!) + endif + LIBNL_CFLAGS += $(shell $(PKG_CONFIG) --cflags $(LIBNL_NAME)) + LIBNL_LDLIBS += $(shell $(PKG_CONFIG) --libs $(LIBNL_NAME)) +endif +CFLAGS += $(LIBNL_CFLAGS) +LDLIBS += $(LIBNL_LDLIBS) + # standard build tools ifeq ($(CONFIG_BATCTL_BISECT),y) OBJ += $(OBJ_BISECT) diff --git a/functions.c b/functions.c index 10a7f86..c21431c 100644 --- a/functions.c +++ b/functions.c @@ -38,9 +38,13 @@ #include <net/ethernet.h> #include <linux/rtnetlink.h> #include <linux/neighbour.h> -#include <sys/uio.h> #include <errno.h> #include <net/if.h> +#include <netlink/socket.h> +#include <netlink/netlink.h> +#include <netlink/handlers.h> +#include <netlink/msg.h> +#include <netlink/attr.h>
#include "main.h" #include "functions.h" @@ -457,47 +461,6 @@ static int resolve_l3addr(int ai_family, const char *asc, void *l3addr) return ret; }
-static void request_mac_resolve(int ai_family, const void *l3addr) -{ - const struct sockaddr *sockaddr; - struct sockaddr_in inet4; - struct sockaddr_in6 inet6; - size_t sockaddr_len; - int sock; - char t = 0; - - sock = socket(ai_family, SOCK_DGRAM, IPPROTO_UDP); - if (sock < 0) - return; - - switch (ai_family) { - case AF_INET: - memset(&inet4, 0, sizeof(inet4)); - inet4.sin_family = ai_family; - inet4.sin_port = htons(9); - memcpy(&inet4.sin_addr.s_addr, l3addr, - sizeof(inet4.sin_addr.s_addr)); - sockaddr = (const struct sockaddr *)&inet4; - sockaddr_len = sizeof(inet4); - break; - case AF_INET6: - memset(&inet6, 0, sizeof(inet6)); - inet6.sin6_family = ai_family; - inet6.sin6_port = htons(9); - memcpy(&inet6.sin6_addr.s6_addr, l3addr, - sizeof(inet6.sin6_addr.s6_addr)); - sockaddr = (const struct sockaddr *)&inet6; - sockaddr_len = sizeof(inet6); - break; - default: - close(sock); - return; - } - - sendto(sock, &t, sizeof(t), 0, sockaddr, sockaddr_len); - close(sock); -} - /** * batadv_rtnl_open - open a socket to rtnl and send a request * @nh: the header of the request to send @@ -542,178 +505,165 @@ outclose: return ret; }
-static int resolve_mac_from_cache_open(int ai_family) +static void request_mac_resolve(int ai_family, const void *l3addr) { - struct { - struct nlmsghdr hdr; - struct ndmsg msg; - } nlreq; - - memset(&nlreq, 0, sizeof(nlreq)); - nlreq.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(nlreq.msg)); - nlreq.hdr.nlmsg_type = RTM_GETNEIGH; - nlreq.hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP; - nlreq.msg.ndm_family = ai_family; + const struct sockaddr *sockaddr; + struct sockaddr_in inet4; + struct sockaddr_in6 inet6; + size_t sockaddr_len; + int sock; + char t = 0;
- return batadv_rtnl_open(&nlreq, NETLINK_ROUTE); -} + sock = socket(ai_family, SOCK_DGRAM, IPPROTO_UDP); + if (sock < 0) + return;
-static ssize_t resolve_mac_from_cache_dump(int sock, void **buf, size_t *buflen) -{ - struct iovec iov; - struct msghdr msg; - ssize_t ret = -1; - int flags = MSG_PEEK | MSG_TRUNC; + switch (ai_family) { + case AF_INET: + memset(&inet4, 0, sizeof(inet4)); + inet4.sin_family = ai_family; + inet4.sin_port = htons(9); + memcpy(&inet4.sin_addr.s_addr, l3addr, + sizeof(inet4.sin_addr.s_addr)); + sockaddr = (const struct sockaddr *)&inet4; + sockaddr_len = sizeof(inet4); + break; + case AF_INET6: + memset(&inet6, 0, sizeof(inet6)); + inet6.sin6_family = ai_family; + inet6.sin6_port = htons(9); + memcpy(&inet6.sin6_addr.s6_addr, l3addr, + sizeof(inet6.sin6_addr.s6_addr)); + sockaddr = (const struct sockaddr *)&inet6; + sockaddr_len = sizeof(inet6); + break; + default: + close(sock); + return; + }
- memset(&msg, 0, sizeof(msg)); - memset(&iov, 0, sizeof(iov)); + sendto(sock, &t, sizeof(t), 0, sockaddr, sockaddr_len); + close(sock); +}
- msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_controllen = 0; - msg.msg_control = NULL; - msg.msg_flags = 0; +struct resolve_mac_nl_arg { + int ai_family; + const void *l3addr; + struct ether_addr *mac_result; + int found; +};
- iov.iov_len = *buflen; - iov.iov_base = *buf; +static struct nla_policy neigh_policy[NDA_MAX+1] = { + [NDA_CACHEINFO] = { .minlen = sizeof(struct nda_cacheinfo) }, + [NDA_PROBES] = { .type = NLA_U32 }, +};
- ret = recvmsg(sock, &msg, flags); +static int resolve_mac_from_parse(struct nl_msg *msg, void *arg) +{ + struct nlattr *tb[NDA_MAX + 1]; + struct ndmsg *nm; + int ret; + int l3_len; + struct resolve_mac_nl_arg *nl_arg = arg; + uint8_t *mac; + uint8_t *l3addr; + + nm = nlmsg_data(nlmsg_hdr(msg)); + ret = nlmsg_parse(nlmsg_hdr(msg), sizeof(*nm), tb, NDA_MAX, + neigh_policy); if (ret < 0) goto err;
- if (msg.msg_flags & MSG_TRUNC) { - if ((size_t)ret <= *buflen) { - ret = -ENOBUFS; - goto err; - } - - while (*buflen <= (size_t)ret) { - if (*buflen == 0) - *buflen = 1; - *buflen *= 2; - } + if (nl_arg->ai_family != nm->ndm_family) + goto err;
- *buf = realloc(*buf, *buflen); - if (!*buf) { - ret = -ENOMEM; - *buflen = 0; - goto err; - } + switch (nl_arg->ai_family) { + case AF_INET: + l3_len = 4; + break; + case AF_INET6: + l3_len = 16; + break; + default: + l3_len = 0; } - flags = 0;
- ret = recvmsg(sock, &msg, flags); - if (ret < 0) + if (l3_len == 0) goto err;
- return ret; -err: - free(*buf); - *buf = NULL; - return ret; -} + if (!tb[NDA_LLADDR] || !tb[NDA_DST]) + goto err;
-static int resolve_mac_from_cache_parse(struct ndmsg *ndmsg, size_t len_payload, - struct ether_addr *mac_addr, - uint8_t *l3addr, - size_t l3_len) -{ - int l3found, llfound; - struct rtattr *rtattr; - struct ether_addr mac_empty; - - l3found = 0; - llfound = 0; - memset(&mac_empty, 0, sizeof(mac_empty)); - - for (rtattr = RTM_RTA(ndmsg); RTA_OK(rtattr, len_payload); - rtattr = RTA_NEXT(rtattr, len_payload)) { - switch (rtattr->rta_type) { - case NDA_DST: - memcpy(l3addr, RTA_DATA(rtattr), l3_len); - l3found = 1; - break; - case NDA_LLADDR: - memcpy(mac_addr, RTA_DATA(rtattr), ETH_ALEN); - if (memcmp(mac_addr, &mac_empty, - sizeof(mac_empty)) == 0) - llfound = 0; - else - llfound = 1; - break; - } + if (nla_len(tb[NDA_LLADDR]) != ETH_ALEN) + goto err; + + if (nla_len(tb[NDA_DST]) != l3_len) + goto err; + + mac = nla_data(tb[NDA_LLADDR]); + l3addr = nla_data(tb[NDA_DST]); + + if (memcmp(nl_arg->l3addr, l3addr, l3_len) == 0) { + memcpy(nl_arg->mac_result, mac, ETH_ALEN); + nl_arg->found = 1; }
- return l3found && llfound; +err: + if (nl_arg->found) + return NL_STOP; + else + return NL_OK; }
static struct ether_addr *resolve_mac_from_cache(int ai_family, const void *l3addr) { - uint8_t l3addr_tmp[16]; - static struct ether_addr mac_tmp; + struct nl_sock *sock; struct ether_addr *mac_result = NULL; - void *buf = NULL; - size_t buflen; - struct nlmsghdr *nh; - ssize_t len; - size_t l3_len, mlen; - int socknl; - int parsed; - int finished = 0; - - switch (ai_family) { - case AF_INET: - l3_len = 4; - break; - case AF_INET6: - l3_len = 16; - break; - default: - l3_len = 0; - } - - buflen = 8192; - buf = malloc(buflen); - if (!buf) + static struct ether_addr mac_tmp; + int ret; + struct rtgenmsg gmsg = { + .rtgen_family = ai_family, + }; + struct nl_cb *cb = NULL; + struct resolve_mac_nl_arg arg = { + .ai_family = ai_family, + .l3addr = l3addr, + .mac_result = &mac_tmp, + .found = 0, + }; + + sock = nl_socket_alloc(); + if (!sock) goto err;
- socknl = resolve_mac_from_cache_open(ai_family); - if (socknl < 0) + ret = nl_connect(sock, NETLINK_ROUTE); + if (ret < 0) goto err;
+ ret = nl_send_simple(sock, RTM_GETNEIGH, NLM_F_REQUEST | NLM_F_DUMP, + &gmsg, sizeof(gmsg)); + if (ret < 0) + goto err;
- while (!finished) { - len = resolve_mac_from_cache_dump(socknl, &buf, &buflen); - if (len < 0) - goto err_sock; - mlen = len; + cb = nl_cb_alloc(NL_CB_DEFAULT); + if (!cb) + goto err;
- for (nh = buf; NLMSG_OK(nh, mlen); nh = NLMSG_NEXT(nh, mlen)) { - if (nh->nlmsg_type == NLMSG_DONE) { - finished = 1; - break; - } + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, resolve_mac_from_parse, &arg); + ret = nl_recvmsgs(sock, cb); + if (ret < 0) + goto err;
- parsed = resolve_mac_from_cache_parse(NLMSG_DATA(nh), - RTM_PAYLOAD(nh), - &mac_tmp, - l3addr_tmp, - l3_len); - if (parsed) { - if (memcmp(&l3addr_tmp, l3addr, l3_len) == 0) { - mac_result = &mac_tmp; - finished = 1; - break; - } - } - } - } + if (arg.found) + mac_result = &mac_tmp;
-err_sock: - close(socknl); err: - free(buf); + if (cb) + nl_cb_put(cb); + if (sock) + nl_socket_free(sock); + return mac_result; }
On Monday 06 January 2014 20:37:23 Sven Eckelmann wrote:
It is not necessary to have code duplicated which is already available in libraries like libnl-3.0 or libnl-tiny. This is done to reduce maintenance and security risks.
Signed-off-by: Sven Eckelmann sven@narfation.org
Makefile | 18 ++++ functions.c | 312 +++++++++++++++++++++++++----------------------------------- 2 files changed, 149 insertions(+), 181 deletions(-)
Applied in revision 6212797.
Cheers, Marek
It is not necessary to have code duplicated which is already available in libraries like libnl-3.0 or libnl-tiny. This is done to reduce maintenance and security risks.
Signed-off-by: Sven Eckelmann sven@narfation.org --- functions.c | 274 ++++++++++++++++++++++++------------------------------------ 1 file changed, 110 insertions(+), 164 deletions(-)
diff --git a/functions.c b/functions.c index c21431c..36804bd 100644 --- a/functions.c +++ b/functions.c @@ -461,50 +461,6 @@ static int resolve_l3addr(int ai_family, const char *asc, void *l3addr) return ret; }
-/** - * batadv_rtnl_open - open a socket to rtnl and send a request - * @nh: the header of the request to send - * @protocol: the protocol to use when opening the socket - * - * Return 0 on success or a negative error code otherwise - */ -static int batadv_rtnl_open(void *req, int protocol) -{ - static uint32_t nr_call = 0; - uint32_t pid = (++nr_call + getpid()) & 0x3FFFFF; - struct sockaddr_nl addrnl; - struct nlmsghdr *nh; - int socknl; - int ret; - - memset(&addrnl, 0, sizeof(addrnl)); - addrnl.nl_family = AF_NETLINK; - addrnl.nl_pid = pid; - addrnl.nl_groups = 0; - - socknl = socket(AF_NETLINK, SOCK_RAW, protocol); - if (socknl < 0) - goto out; - - ret = bind(socknl, (struct sockaddr*)&addrnl, sizeof(addrnl)); - if (ret < 0) - goto outclose; - - /* the nlmsghdr object must always be the first member in the req - * structure - */ - nh = (struct nlmsghdr *)req; - - ret = send(socknl, nh, nh->nlmsg_len, 0); - if (ret < 0) - goto outclose; -out: - return socknl; -outclose: - close(socknl); - return ret; -} - static void request_mac_resolve(int ai_family, const void *l3addr) { const struct sockaddr *sockaddr; @@ -722,125 +678,95 @@ out: return mac_result; }
+struct vlan_get_link_nl_arg { + char *iface; + int vid; +}; + +static struct nla_policy info_data_link_policy[IFLA_MAX + 1] = { + [IFLA_LINKINFO] = { .type = NLA_NESTED }, + [IFLA_LINK] = { .type = NLA_U32 }, +}; + +static struct nla_policy info_data_link_info_policy[IFLA_INFO_MAX + 1] = { + [IFLA_INFO_DATA] = { .type = NLA_NESTED }, +}; + +static struct nla_policy vlan_policy[IFLA_VLAN_MAX + 1] = { + [IFLA_VLAN_ID] = { .type = NLA_U16 }, +}; + /** * vlan_get_link_parse - parse a get_link rtnl message and extract the important * data - * @nh: the reply header - * @iface: pointer to the buffer where the link interface has to be stored (it - * is allocated by this function) + * @msg: the reply msg + * @arg: pointer to the buffer which will store the return values * - * Return the vid in case of success or -1 otherwise + * Saves the vid in arg::vid in case of success or -1 otherwise */ -static int vlan_get_link_parse(struct nlmsghdr *nh, char **iface) +static int vlan_get_link_parse(struct nl_msg *msg, void *arg) { - struct ifinfomsg *ifi = NLMSG_DATA(nh); - size_t vlan_len, info_len, len = nh->nlmsg_len; - struct rtattr *rta, *info, *vlan; - int idx = -1, vid = -1; - - *iface = NULL; - - rta = IFLA_RTA(ifi); - while (RTA_OK(rta, len)) { - /* check if the interface is a vlan */ - if (rta->rta_type == IFLA_LINKINFO) { - info = RTA_DATA(rta); - info_len = RTA_PAYLOAD(rta); - - while (RTA_OK(info, info_len)) { - if (info->rta_type == IFLA_INFO_KIND && - strcmp(RTA_DATA(info), "vlan")) - goto err; - - if (info->rta_type == IFLA_INFO_DATA) { - vlan = RTA_DATA(info); - vlan_len = RTA_PAYLOAD(info); - - while (RTA_OK(vlan, vlan_len)) { - if (vlan->rta_type == IFLA_VLAN_ID) - vid = *(int *)RTA_DATA(vlan); - vlan = RTA_NEXT(vlan, vlan_len); - } - } - info = RTA_NEXT(info, info_len); - } - } + struct vlan_get_link_nl_arg *nl_arg = arg; + struct nlmsghdr *n = nlmsg_hdr(msg); + struct nlattr *tb[IFLA_MAX + 1]; + struct nlattr *li[IFLA_INFO_MAX + 1]; + struct nlattr *vi[IFLA_VLAN_MAX + 1]; + int ret; + int idx;
- /* extract the name of the "link" interface */ - if (rta->rta_type == IFLA_LINK) { - idx = *(int *)RTA_DATA(rta); + if (!nlmsg_valid_hdr(n, sizeof(struct ifinfomsg))) + return -NLE_MSG_TOOSHORT;
- *iface = malloc(IFNAMSIZ + 1); - if (!if_indextoname(idx, *iface)) - goto err; - } - rta = RTA_NEXT(rta, len); - } + ret = nlmsg_parse(n, sizeof(struct ifinfomsg), tb, IFLA_MAX, + info_data_link_policy); + if (ret < 0) + return ret;
- if (vid == -1) - goto err; + if (!tb[IFLA_LINK]) + return -NLE_MISSING_ATTR;
- if (idx <= 0) - goto err; + /* parse subattributes linkinfo */ + if (!tb[IFLA_LINKINFO]) + return -NLE_MISSING_ATTR;
- return vid; -err: - free(*iface); - return -1; -} + ret = nla_parse_nested(li, IFLA_INFO_MAX, tb[IFLA_LINKINFO], + info_data_link_info_policy); + if (ret < 0) + return ret;
-/** - * vlan_get_link_dump - receive and dump a get_link rtnl reply - * @sock: the socket to listen for the reply on - * @buf: buffer where the reply has to be dumped to - * @buflen: length of the buffer - * - * Returns the amount of dumped bytes - */ -static ssize_t vlan_get_link_dump(int sock, void *buf, size_t buflen) -{ - struct sockaddr_nl nladdr; - struct msghdr msg; - struct iovec iov; + if (!li[IFLA_INFO_KIND]) + return -NLE_MISSING_ATTR;
- memset(&msg, 0, sizeof(msg)); - memset(&iov, 0, sizeof(iov)); + if (strcmp(nla_data(li[IFLA_INFO_KIND]), "vlan") != 0) + goto err;
- msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_controllen = 0; - msg.msg_control = NULL; - msg.msg_flags = 0; - msg.msg_name = &nladdr; - msg.msg_namelen = sizeof(nladdr); + /* parse subattributes info_data for vlan */ + if (!li[IFLA_INFO_DATA]) + return -NLE_MISSING_ATTR;
- iov.iov_len = buflen; - iov.iov_base = buf; + ret = nla_parse_nested(vi, IFLA_VLAN_MAX, li[IFLA_INFO_DATA], + vlan_policy); + if (ret < 0) + return ret;
- return recvmsg(sock, &msg, 0); -} + if (!vi[IFLA_VLAN_ID]) + return -NLE_MISSING_ATTR;
-/** - * vlan_get_link_open - send a get_link request - * @ifname: the interface to query - * - * Returns 0 in case of success or a negative error code otherwise - */ -static int vlan_get_link_open(const char *ifname) -{ - struct { - struct nlmsghdr hdr; - struct ifinfomsg ifi; - } nlreq; - - memset(&nlreq, 0, sizeof(nlreq)); - nlreq.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(nlreq.ifi)); - nlreq.hdr.nlmsg_type = RTM_GETLINK; - nlreq.hdr.nlmsg_flags = NLM_F_REQUEST; - nlreq.ifi.ifi_family = AF_UNSPEC; - nlreq.ifi.ifi_index = if_nametoindex(ifname); - - return batadv_rtnl_open(&nlreq, 0); + /* get parent link name */ + idx = *(int *)nla_data(tb[IFLA_LINK]); + free(nl_arg->iface); + nl_arg->iface = malloc(IFNAMSIZ + 1); + if (!if_indextoname(idx, nl_arg->iface)) + goto err; + + /* get the corresponding vid */ + nl_arg->vid = *(int *)nla_data(vi[IFLA_VLAN_ID]); + +err: + if (nl_arg->vid >= 0) + return NL_STOP; + else + return NL_OK; }
/** @@ -853,29 +779,49 @@ static int vlan_get_link_open(const char *ifname) */ int vlan_get_link(const char *ifname, char **parent) { - int vid = -1, socknl; - void *buf = NULL; - size_t buflen; - ssize_t len; - - buflen = 8192; - buf = malloc(buflen); - if (!buf) + struct nl_sock *sock; + int ret; + struct ifinfomsg ifinfo = { + .ifi_family = AF_UNSPEC, + .ifi_index = if_nametoindex(ifname), + }; + struct nl_cb *cb = NULL; + struct vlan_get_link_nl_arg arg = { + .iface = NULL, + .vid = -1, + }; + + *parent = NULL; + + sock = nl_socket_alloc(); + if (!sock) + goto err; + + ret = nl_connect(sock, NETLINK_ROUTE); + if (ret < 0) + goto err; + + ret = nl_send_simple(sock, RTM_GETLINK, NLM_F_REQUEST, + &ifinfo, sizeof(ifinfo)); + if (ret < 0) goto err;
- socknl = vlan_get_link_open(ifname); - if (socknl < 0) + cb = nl_cb_alloc(NL_CB_DEFAULT); + if (!cb) goto err;
- len = vlan_get_link_dump(socknl, buf, buflen); - if (len < 0) - goto err_sock; + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, vlan_get_link_parse, &arg); + ret = nl_recvmsgs(sock, cb); + if (ret < 0) + goto err;
- vid = vlan_get_link_parse(buf, parent); + *parent = arg.iface;
-err_sock: - close(socknl); err: - free(buf); - return vid; + if (cb) + nl_cb_put(cb); + if (sock) + nl_socket_free(sock); + + return arg.vid; }
On Monday 06 January 2014 20:37:24 Sven Eckelmann wrote:
It is not necessary to have code duplicated which is already available in libraries like libnl-3.0 or libnl-tiny. This is done to reduce maintenance and security risks.
Signed-off-by: Sven Eckelmann sven@narfation.org
functions.c | 274 ++++++++++++++++++++++++------------------------------------ 1 file changed, 110 insertions(+), 164 deletions(-)
Applied in revision b8eaea8.
Thanks, Marek
On Monday 06 January 2014 20:37:22 Sven Eckelmann wrote:
libnl is used in Debian to avoid code duplication which should be avoided to reduce maintenance and security risks. This library already provides a function called rtnl_open and therefore has a name clash with the self defined function.
Signed-off-by: Sven Eckelmann sven@narfation.org
functions.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
Applied in revision f8eb19d.
Thanks, Marek
Hi Sven,
On 06/01/14 20:35, Sven Eckelmann wrote:
Hi,
the current release 2014.0.0 made some problems for me because Debian the new function "rtnl_open" conflicted with libnl-3.0. libnl-3.0 was used in the Debian package to follow the Debian policy chapter 4 about duplicated code.
Using libnl should not be a problem for any linux system because everyone uses it when wireless configuration is done. For example libnl-tiny is already used by the normal OpenWrt system in base system packages:
I think that it may still be the case that we want to compile batctl on an host without libnl.
In the end batman-adv can run on Ethernet and we may have an embedded system with no wifi which has no libnl at all.
I was wondering....what if we check if libnl is installed or not and in case it is missing we disable the address translation and vlan operations? In this way we can add the dependency to libnl and avoid code duplication but at the same time we keep libnl-free users happy.
I think batctl can be useful for many things, also if libnl is not installed.
What do you think?
Cheers,
On Thursday 16 January 2014 22:11:38 Antonio Quartulli wrote:
I think that it may still be the case that we want to compile batctl on an host without libnl.
We == "I have this use case"?
In the end batman-adv can run on Ethernet and we may have an embedded system with no wifi which has no libnl at all.
(Now a little bit sarcasm): batctl can also run without batman-adv, please allow to drop the useless sysfs/debugfs stuff ;)
I was wondering....what if we check if libnl is installed or not and in case it is missing we disable the address translation and vlan operations? In this way we can add the dependency to libnl and avoid code duplication but at the same time we keep libnl-free users happy.
I agree that it is possible but would like to avoid to provide a "fallback" because it justs adds more complexity without an actual use case (please correct me but I don't see it right now).
If you still think it is necessary then please feel free to add it later.
Kind regards, Sven
On 17/01/14 10:37, Sven Eckelmann wrote:
On Thursday 16 January 2014 22:11:38 Antonio Quartulli wrote:
I think that it may still be the case that we want to compile batctl on an host without libnl.
We == "I have this use case"?
In the end batman-adv can run on Ethernet and we may have an embedded system with no wifi which has no libnl at all.
(Now a little bit sarcasm): batctl can also run without batman-adv, please allow to drop the useless sysfs/debugfs stuff ;)
I was wondering....what if we check if libnl is installed or not and in case it is missing we disable the address translation and vlan operations? In this way we can add the dependency to libnl and avoid code duplication but at the same time we keep libnl-free users happy.
I agree that it is possible but would like to avoid to provide a "fallback" because it justs adds more complexity without an actual use case (please correct me but I don't see it right now).
My use case was only about an embedded device (e.g. raspberry pi) having an Eth connection but no wireless at all, thus it may not have libnl.
If you still think it is necessary then please feel free to add it later.
Anyway I agree with you: that requires too much complexity for a very little gain.
I like this patchset as it is.
Thanks.
Cheers,
b.a.t.m.a.n@lists.open-mesh.org