Change in libosmocore[master]: Integrate libmnl (minimal netlink) library with libosmocore select loop

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

laforge gerrit-no-reply at lists.osmocom.org
Wed Dec 2 21:04:51 UTC 2020


laforge has submitted this change. ( https://gerrit.osmocom.org/c/libosmocore/+/21457 )

Change subject: Integrate libmnl (minimal netlink) library with libosmocore select loop
......................................................................

Integrate libmnl (minimal netlink) library with libosmocore select loop

This adds an easy way to listen to netlink events form the Linux kernel
from within libosmocore applications.

The new dependency can be disabled via the "--disable-lbimnl" configure flag.

Change-Id: I4f787ee68f0d6d04f0a5655eb57d55b3b326a42f
---
M configure.ac
M contrib/jenkins_arm.sh
M contrib/libosmocore.spec.in
M debian/control
M include/Makefile.am
A include/osmocom/core/mnl.h
M src/Makefile.am
M src/gb/gprs_ns2_internal.h
A src/mnl.c
9 files changed, 165 insertions(+), 1 deletion(-)

Approvals:
  laforge: Looks good to me, approved
  pespin: Looks good to me, but someone else must approve
  Jenkins Builder: Verified



diff --git a/configure.ac b/configure.ac
index 7de495b..10fb496 100644
--- a/configure.ac
+++ b/configure.ac
@@ -194,6 +194,19 @@
 AM_CONDITIONAL(ENABLE_SYSTEMD_LOGGING, test "x$systemd_logging" = "xyes")
 AC_SUBST(ENABLE_SYSTEMD_LOGGING)
 
+AC_ARG_ENABLE([libmnl],
+	[AS_HELP_STRING(
+		[--disable-libmnl],
+		[Build without netlink socket support via libmnl]
+	)],
+	[mnl=$enableval], [mnl="yes"])
+AS_IF([test "x$mnl" = "xyes"], [
+	PKG_CHECK_MODULES(LIBMNL, libmnl)
+	AC_DEFINE([ENABLE_LIBMNL], [1], [Enable netlink socket support via libmnl])
+])
+AM_CONDITIONAL(ENABLE_LIBMNL, test "x$mnl" = "xyes")
+AC_SUBST(ENABLE_LIBMNL)
+
 AC_ARG_ENABLE([libsctp], [AS_HELP_STRING([--disable-libsctp], [Do not enable socket multiaddr APIs requiring libsctp])],
 	[ENABLE_LIBSCTP=$enableval], [ENABLE_LIBSCTP="yes"])
 AM_CONDITIONAL(ENABLE_LIBSCTP, test x"$ENABLE_LIBSCTP" = x"yes")
diff --git a/contrib/jenkins_arm.sh b/contrib/jenkins_arm.sh
index c9cd922..e7df37d 100755
--- a/contrib/jenkins_arm.sh
+++ b/contrib/jenkins_arm.sh
@@ -20,6 +20,7 @@
 	--disable-shared \
 	--disable-libsctp \
 	--disable-libusb \
+	--disable-libmnl \
 	--enable-external-tests \
 	CFLAGS="-Os -ffunction-sections -fdata-sections -nostartfiles -nodefaultlibs $WERROR_FLAGS"
 
diff --git a/contrib/libosmocore.spec.in b/contrib/libosmocore.spec.in
index fb45516..728a0fb 100644
--- a/contrib/libosmocore.spec.in
+++ b/contrib/libosmocore.spec.in
@@ -30,6 +30,7 @@
 BuildRequires:  pkgconfig(libpcsclite)
 BuildRequires:  pkgconfig(libusb-1.0)
 BuildRequires:  pkgconfig(talloc) >= 2.0.1
+BuildRequires:  pkgconfig(libmnl)
 
 %description
 libosmocore is a package with various utility functions that were
diff --git a/debian/control b/debian/control
index 381e291..24e729a 100644
--- a/debian/control
+++ b/debian/control
@@ -17,6 +17,7 @@
                libtalloc-dev,
                libsctp-dev,
                libusb-1.0-0-dev,
+               libmnl-dev,
                python3:native
 Standards-Version: 3.9.8
 Vcs-Git: git://git.osmocom.org/libosmocore.git
diff --git a/include/Makefile.am b/include/Makefile.am
index 3173290..71171a4 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -32,6 +32,7 @@
                        osmocom/core/linuxrbtree.h \
                        osmocom/core/logging.h \
                        osmocom/core/loggingrb.h \
+                       osmocom/core/mnl.h \
                        osmocom/core/stats.h \
                        osmocom/core/macaddr.h \
                        osmocom/core/msgb.h \
diff --git a/include/osmocom/core/mnl.h b/include/osmocom/core/mnl.h
new file mode 100644
index 0000000..11c8353
--- /dev/null
+++ b/include/osmocom/core/mnl.h
@@ -0,0 +1,22 @@
+/*! \file select.h
+ *  libmnl integration
+ */
+#pragma once
+
+#include <osmocom/core/select.h>
+#include <libmnl/libmnl.h>
+
+/*! osmocom wrapper around libmnl abstraction of netlink socket */
+struct osmo_mnl {
+	/*! osmo-wrapped netlink file descriptor */
+	struct osmo_fd ofd;
+	/*! libmnl socket abstraction */
+	struct mnl_socket *mnls;
+	/*! call-back called for received netlink messages */
+	mnl_cb_t mnl_cb;
+	/*! opaque data provided by user */
+	void *priv;
+};
+
+struct osmo_mnl *osmo_mnl_init(void *ctx, int bus, unsigned int groups, mnl_cb_t mnl_cb, void *priv);
+void osmo_mnl_destroy(struct osmo_mnl *omnl);
diff --git a/src/Makefile.am b/src/Makefile.am
index b2c9204..5ff1a42 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -4,7 +4,7 @@
 LIBVERSION=16:0:0
 
 AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include
-AM_CFLAGS = -Wall $(TALLOC_CFLAGS) $(PTHREAD_CFLAGS) $(LIBSCTP_CFLAGS)
+AM_CFLAGS = -Wall $(TALLOC_CFLAGS) $(PTHREAD_CFLAGS) $(LIBSCTP_CFLAGS) $(LIBMNL_CFLAGS)
 
 if ENABLE_PSEUDOTALLOC
 AM_CPPFLAGS += -I$(top_srcdir)/src/pseudotalloc
@@ -76,5 +76,10 @@
 libosmocore_la_LIBADD += $(SYSTEMD_LIBS)
 endif
 
+if ENABLE_LIBMNL
+libosmocore_la_SOURCES += mnl.c
+libosmocore_la_LIBADD += $(LIBMNL_LIBS)
+endif
+
 crc%gen.c: crcXXgen.c.tpl
 	$(AM_V_GEN)sed -e's/XX/$*/g' $< > $@
diff --git a/src/gb/gprs_ns2_internal.h b/src/gb/gprs_ns2_internal.h
index 08ffac2..e72deff 100644
--- a/src/gb/gprs_ns2_internal.h
+++ b/src/gb/gprs_ns2_internal.h
@@ -95,8 +95,12 @@
 
 	/*! workaround for rate counter until rate counter accepts char str as index */
 	uint32_t rate_ctr_idx;
+
+	/*! libmnl netlink socket for link state monitoring */
+	struct osmo_mnl *linkmon_mnl;
 };
 
+
 /*! Structure repesenting a NSE. The BSS/PCU will only have a single NSE, while SGSN has one for each BSS/PCU */
 struct gprs_ns2_nse {
 	uint16_t nsei;
diff --git a/src/mnl.c b/src/mnl.c
new file mode 100644
index 0000000..13d9c9e
--- /dev/null
+++ b/src/mnl.c
@@ -0,0 +1,116 @@
+/*! \file mnl.c
+ *
+ * This code integrates libmnl (minimal netlink library) into the osmocom select
+ * loop abstraction.  It allows other osmocom libraries or application code to
+ * create netlink sockets and subscribe to netlink events via libmnl.  The completion
+ * handler / callbacks are dispatched via libosmocore select loop handling.
+ */
+
+/*
+ * (C) 2020 by Harald Welte <laforge at gnumonks.org>
+ * All Rights Reserverd.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301, USA.
+ */
+
+#include <osmocom/core/select.h>
+#include <osmocom/core/talloc.h>
+#include <osmocom/core/logging.h>
+#include <osmocom/core/mnl.h>
+
+#include <libmnl/libmnl.h>
+
+#include <errno.h>
+#include <string.h>
+
+/* osmo_fd call-back for when RTNL socket is readable */
+static int osmo_mnl_fd_cb(struct osmo_fd *ofd, unsigned int what)
+{
+	uint8_t buf[MNL_SOCKET_BUFFER_SIZE];
+	struct osmo_mnl *omnl = ofd->data;
+	int rc;
+
+	if (!(what & OSMO_FD_READ))
+		return 0;
+
+	rc = mnl_socket_recvfrom(omnl->mnls, buf, sizeof(buf));
+	if (rc <= 0) {
+		LOGP(DLGLOBAL, LOGL_ERROR, "Error in mnl_socket_recvfrom(): %s\n",
+			strerror(errno));
+		return -EIO;
+	}
+
+	return mnl_cb_run(buf, rc, 0, 0, omnl->mnl_cb, omnl);
+}
+
+/*! create an osmocom-wrapped limnl netlink socket.
+ *  \parma[in] ctx talloc context from which to allocate
+ *  \param[in] bus netlink socket bus ID (see NETLINK_* constants)
+ *  \param[in] groups groups of messages to bind/subscribe to
+ *  \param[in] mnl_cb callback function called for each incoming message
+ *  \param[in] priv opaque private user data
+ *  \returns newly-allocated osmo_mnl or NULL in case of error. */
+struct osmo_mnl *osmo_mnl_init(void *ctx, int bus, unsigned int groups, mnl_cb_t mnl_cb, void *priv)
+{
+	struct osmo_mnl *olm = talloc_zero(ctx, struct osmo_mnl);
+
+	if (!olm)
+		return NULL;
+
+	olm->priv = priv;
+	olm->mnl_cb = mnl_cb;
+	olm->mnls = mnl_socket_open2(bus, SOCK_CLOEXEC);
+	if (!olm->mnls) {
+		LOGP(DLGLOBAL, LOGL_ERROR, "Error creating netlink socket for bus %d: %s\n",
+			bus, strerror(errno));
+		goto out_free;
+	}
+
+	if (mnl_socket_bind(olm->mnls, groups, MNL_SOCKET_AUTOPID) < 0) {
+		LOGP(DLGLOBAL, LOGL_ERROR, "Error binding netlink socket for bus %d to groups 0x%x: %s\n",
+			bus, groups, strerror(errno));
+		goto out_close;
+	}
+
+	osmo_fd_setup(&olm->ofd, mnl_socket_get_fd(olm->mnls), OSMO_FD_READ, osmo_mnl_fd_cb, olm, 0);
+
+	if (osmo_fd_register(&olm->ofd)) {
+		LOGP(DLGLOBAL, LOGL_ERROR, "Error registering netlinks socket\n");
+		goto out_close;
+	}
+
+	return olm;
+
+out_close:
+	mnl_socket_close(olm->mnls);
+out_free:
+	talloc_free(olm);
+	return NULL;
+}
+
+/*! destroy an existing osmocom-wrapped mnl netlink socket: Unregister + close + free.
+ *  \param[in] omnl osmo_mnl socket previously returned by osmo_mnl_init() */
+void osmo_mnl_destroy(struct osmo_mnl *omnl)
+{
+	if (!omnl)
+		return;
+
+	osmo_fd_unregister(&omnl->ofd);
+	mnl_socket_close(omnl->mnls);
+	talloc_free(omnl);
+}

-- 
To view, visit https://gerrit.osmocom.org/c/libosmocore/+/21457
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Change-Id: I4f787ee68f0d6d04f0a5655eb57d55b3b326a42f
Gerrit-Change-Number: 21457
Gerrit-PatchSet: 5
Gerrit-Owner: laforge <laforge at osmocom.org>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge at osmocom.org>
Gerrit-Reviewer: pespin <pespin at sysmocom.de>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20201202/a8119d21/attachment.htm>


More information about the gerrit-log mailing list