<p>laforge has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/libosmocore/+/21457">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Integrate libmnl (minimal netlink) library with libosmocore select loop<br><br>This adds an easy way to listen to netlink events form the Linux kernel<br>from within libosmocore applications.<br><br>The new dependency can be disabled via the "--disable-lbimnl" configure flag.<br><br>Change-Id: I4f787ee68f0d6d04f0a5655eb57d55b3b326a42f<br>---<br>M configure.ac<br>M contrib/jenkins_arm.sh<br>M contrib/libosmocore.spec.in<br>M debian/control<br>M src/Makefile.am<br>M src/gb/gprs_ns2_internal.h<br>A src/mnl.c<br>7 files changed, 109 insertions(+), 1 deletion(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/57/21457/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/configure.ac b/configure.ac</span><br><span>index 7de495b..10fb496 100644</span><br><span>--- a/configure.ac</span><br><span>+++ b/configure.ac</span><br><span>@@ -194,6 +194,19 @@</span><br><span> AM_CONDITIONAL(ENABLE_SYSTEMD_LOGGING, test "x$systemd_logging" = "xyes")</span><br><span> AC_SUBST(ENABLE_SYSTEMD_LOGGING)</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+AC_ARG_ENABLE([libmnl],</span><br><span style="color: hsl(120, 100%, 40%);">+  [AS_HELP_STRING(</span><br><span style="color: hsl(120, 100%, 40%);">+              [--disable-libmnl],</span><br><span style="color: hsl(120, 100%, 40%);">+           [Build without netlink socket support via libmnl]</span><br><span style="color: hsl(120, 100%, 40%);">+     )],</span><br><span style="color: hsl(120, 100%, 40%);">+   [mnl=$enableval], [mnl="yes"])</span><br><span style="color: hsl(120, 100%, 40%);">+AS_IF([test "x$mnl" = "xyes"], [</span><br><span style="color: hsl(120, 100%, 40%);">+        PKG_CHECK_MODULES(LIBMNL, libmnl)</span><br><span style="color: hsl(120, 100%, 40%);">+     AC_DEFINE([ENABLE_LIBMNL], [1], [Enable netlink socket support via libmnl])</span><br><span style="color: hsl(120, 100%, 40%);">+])</span><br><span style="color: hsl(120, 100%, 40%);">+AM_CONDITIONAL(ENABLE_LIBMNL, test "x$mnl" = "xyes")</span><br><span style="color: hsl(120, 100%, 40%);">+AC_SUBST(ENABLE_LIBMNL)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> AC_ARG_ENABLE([libsctp], [AS_HELP_STRING([--disable-libsctp], [Do not enable socket multiaddr APIs requiring libsctp])],</span><br><span>     [ENABLE_LIBSCTP=$enableval], [ENABLE_LIBSCTP="yes"])</span><br><span> AM_CONDITIONAL(ENABLE_LIBSCTP, test x"$ENABLE_LIBSCTP" = x"yes")</span><br><span>diff --git a/contrib/jenkins_arm.sh b/contrib/jenkins_arm.sh</span><br><span>index c9cd922..e7df37d 100755</span><br><span>--- a/contrib/jenkins_arm.sh</span><br><span>+++ b/contrib/jenkins_arm.sh</span><br><span>@@ -20,6 +20,7 @@</span><br><span>      --disable-shared \</span><br><span>   --disable-libsctp \</span><br><span>  --disable-libusb \</span><br><span style="color: hsl(120, 100%, 40%);">+    --disable-libmnl \</span><br><span>   --enable-external-tests \</span><br><span>    CFLAGS="-Os -ffunction-sections -fdata-sections -nostartfiles -nodefaultlibs $WERROR_FLAGS"</span><br><span> </span><br><span>diff --git a/contrib/libosmocore.spec.in b/contrib/libosmocore.spec.in</span><br><span>index fb45516..728a0fb 100644</span><br><span>--- a/contrib/libosmocore.spec.in</span><br><span>+++ b/contrib/libosmocore.spec.in</span><br><span>@@ -30,6 +30,7 @@</span><br><span> BuildRequires:  pkgconfig(libpcsclite)</span><br><span> BuildRequires:  pkgconfig(libusb-1.0)</span><br><span> BuildRequires:  pkgconfig(talloc) >= 2.0.1</span><br><span style="color: hsl(120, 100%, 40%);">+BuildRequires:  pkgconfig(libmnl)</span><br><span> </span><br><span> %description</span><br><span> libosmocore is a package with various utility functions that were</span><br><span>diff --git a/debian/control b/debian/control</span><br><span>index 381e291..24e729a 100644</span><br><span>--- a/debian/control</span><br><span>+++ b/debian/control</span><br><span>@@ -17,6 +17,7 @@</span><br><span>                libtalloc-dev,</span><br><span>                libsctp-dev,</span><br><span>                libusb-1.0-0-dev,</span><br><span style="color: hsl(120, 100%, 40%);">+               libmnl-dev,</span><br><span>                python3:native</span><br><span> Standards-Version: 3.9.8</span><br><span> Vcs-Git: git://git.osmocom.org/libosmocore.git</span><br><span>diff --git a/src/Makefile.am b/src/Makefile.am</span><br><span>index b2c9204..5ff1a42 100644</span><br><span>--- a/src/Makefile.am</span><br><span>+++ b/src/Makefile.am</span><br><span>@@ -4,7 +4,7 @@</span><br><span> LIBVERSION=16:0:0</span><br><span> </span><br><span> AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include</span><br><span style="color: hsl(0, 100%, 40%);">-AM_CFLAGS = -Wall $(TALLOC_CFLAGS) $(PTHREAD_CFLAGS) $(LIBSCTP_CFLAGS)</span><br><span style="color: hsl(120, 100%, 40%);">+AM_CFLAGS = -Wall $(TALLOC_CFLAGS) $(PTHREAD_CFLAGS) $(LIBSCTP_CFLAGS) $(LIBMNL_CFLAGS)</span><br><span> </span><br><span> if ENABLE_PSEUDOTALLOC</span><br><span> AM_CPPFLAGS += -I$(top_srcdir)/src/pseudotalloc</span><br><span>@@ -76,5 +76,10 @@</span><br><span> libosmocore_la_LIBADD += $(SYSTEMD_LIBS)</span><br><span> endif</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+if ENABLE_LIBMNL</span><br><span style="color: hsl(120, 100%, 40%);">+libosmocore_la_SOURCES += mnl.c</span><br><span style="color: hsl(120, 100%, 40%);">+libosmocore_la_LIBADD += $(LIBMNL_LIBS)</span><br><span style="color: hsl(120, 100%, 40%);">+endif</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> crc%gen.c: crcXXgen.c.tpl</span><br><span>        $(AM_V_GEN)sed -e's/XX/$*/g' $< > $@</span><br><span>diff --git a/src/gb/gprs_ns2_internal.h b/src/gb/gprs_ns2_internal.h</span><br><span>index 08ffac2..e72deff 100644</span><br><span>--- a/src/gb/gprs_ns2_internal.h</span><br><span>+++ b/src/gb/gprs_ns2_internal.h</span><br><span>@@ -95,8 +95,12 @@</span><br><span> </span><br><span>     /*! workaround for rate counter until rate counter accepts char str as index */</span><br><span>      uint32_t rate_ctr_idx;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /*! libmnl netlink socket for link state monitoring */</span><br><span style="color: hsl(120, 100%, 40%);">+        struct osmo_mnl *linkmon_mnl;</span><br><span> };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! Structure repesenting a NSE. The BSS/PCU will only have a single NSE, while SGSN has one for each BSS/PCU */</span><br><span> struct gprs_ns2_nse {</span><br><span>       uint16_t nsei;</span><br><span>diff --git a/src/mnl.c b/src/mnl.c</span><br><span>new file mode 100644</span><br><span>index 0000000..abde74b</span><br><span>--- /dev/null</span><br><span>+++ b/src/mnl.c</span><br><span>@@ -0,0 +1,83 @@</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/select.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/talloc.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/logging.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/mnl.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <libmnl/libmnl.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <errno.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <string.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* osmo_fd call-back for when RTNL socket is readable */</span><br><span style="color: hsl(120, 100%, 40%);">+static int osmo_mnl_fd_cb(struct osmo_fd *ofd, unsigned int what)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t buf[MNL_SOCKET_BUFFER_SIZE];</span><br><span style="color: hsl(120, 100%, 40%);">+  struct osmo_mnl *omnl = ofd->data;</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!(what & OSMO_FD_READ))</span><br><span style="color: hsl(120, 100%, 40%);">+               return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   rc = mnl_socket_recvfrom(omnl->mnls, buf, sizeof(buf));</span><br><span style="color: hsl(120, 100%, 40%);">+    if (rc <= 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+             LOGP(DLGLOBAL, LOGL_ERROR, "Error in mnl_socket_recvfrom(): %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                  strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+             return -EIO;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return mnl_cb_run(buf, rc, 0, 0, omnl->mnl_cb, omnl);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! create an osmocom-wrapped limnl netlink socket.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \parma[in] ctx talloc context from which to allocate</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] bus netlink socket bus ID (see NETLINK_* constants)</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] groups groups of messages to bind/subscribe to</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] mnl_cb callback function called for each incoming message</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns newly-allocated osmo_mnl or NULL in case of error. */</span><br><span style="color: hsl(120, 100%, 40%);">+struct osmo_mnl *osmo_mnl_init(void *ctx, int bus, unsigned int groups, mnl_cb_t mnl_cb, void *priv)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        struct osmo_mnl *olm = talloc_zero(ctx, struct osmo_mnl);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!olm)</span><br><span style="color: hsl(120, 100%, 40%);">+             return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        olm->priv = priv;</span><br><span style="color: hsl(120, 100%, 40%);">+  olm->mnl_cb = mnl_cb;</span><br><span style="color: hsl(120, 100%, 40%);">+      olm->mnls = mnl_socket_open2(bus, SOCK_CLOEXEC);</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!olm->mnls) {</span><br><span style="color: hsl(120, 100%, 40%);">+          LOGP(DLGLOBAL, LOGL_ERROR, "Error creating netlink socket for bus %d: %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                        bus, strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+                goto out_free;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (mnl_socket_bind(olm->mnls, groups, MNL_SOCKET_AUTOPID) < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+               LOGP(DLGLOBAL, LOGL_ERROR, "Error binding netlink socket for bus %d to groups 0x%x: %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                  bus, groups, strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+                goto out_close;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   osmo_fd_setup(&olm->ofd, mnl_socket_get_fd(olm->mnls), OSMO_FD_READ, osmo_mnl_fd_cb, olm, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (osmo_fd_register(&olm->ofd)) {</span><br><span style="color: hsl(120, 100%, 40%);">+             LOGP(DLGLOBAL, LOGL_ERROR, "Error registering netlinks socket\n");</span><br><span style="color: hsl(120, 100%, 40%);">+          goto out_close;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return olm;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+out_close:</span><br><span style="color: hsl(120, 100%, 40%);">+     mnl_socket_close(olm->mnls);</span><br><span style="color: hsl(120, 100%, 40%);">+out_free:</span><br><span style="color: hsl(120, 100%, 40%);">+    talloc_free(olm);</span><br><span style="color: hsl(120, 100%, 40%);">+     return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void osmo_mnl_destroy(struct osmo_mnl *omnl)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!omnl)</span><br><span style="color: hsl(120, 100%, 40%);">+            return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     osmo_fd_unregister(&omnl->ofd);</span><br><span style="color: hsl(120, 100%, 40%);">+        mnl_socket_close(omnl->mnls);</span><br><span style="color: hsl(120, 100%, 40%);">+      talloc_free(omnl);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/libosmocore/+/21457">change 21457</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/libosmocore/+/21457"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: libosmocore </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I4f787ee68f0d6d04f0a5655eb57d55b3b326a42f </div>
<div style="display:none"> Gerrit-Change-Number: 21457 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>