Change in libosmocore[master]: gprs_ns2_fr: Monitor the kernel net-device link state

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 14:25:44 UTC 2020


laforge has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmocore/+/21458 )


Change subject: gprs_ns2_fr: Monitor the kernel net-device link state
......................................................................

gprs_ns2_fr: Monitor the kernel net-device link state

We use the newly-introduced libmnl integration of libosmocore in order
to receive netlink events from the kernel on link state changes.

If one of "our" interfaces changed link state, we report this in the log
and also store it within the "bind".

Change-Id: I779556991bfc88b7751b2be17bb81c329cfb9e01
---
M src/gb/gprs_ns2_fr.c
1 file changed, 100 insertions(+), 2 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/58/21458/1

diff --git a/src/gb/gprs_ns2_fr.c b/src/gb/gprs_ns2_fr.c
index 4140171..7e01848 100644
--- a/src/gb/gprs_ns2_fr.c
+++ b/src/gb/gprs_ns2_fr.c
@@ -51,8 +51,10 @@
 #include <osmocom/core/select.h>
 #include <osmocom/core/socket.h>
 #include <osmocom/core/talloc.h>
+#include <osmocom/core/mnl.h>
 #include <osmocom/gprs/gprs_ns2.h>
 
+#include "config.h"
 #include "common_vty.h"
 #include "gprs_ns2_internal.h"
 
@@ -82,6 +84,7 @@
 	struct osmo_fd fd;
 	char netif[IF_NAMESIZE];
 	struct osmo_fr_link *link;
+	bool if_running;
 };
 
 struct priv_vc {
@@ -113,8 +116,8 @@
 	priv = bind->priv;
 	fr_link = priv->link;
 
-	vty_out(vty, "FR bind: %s, role: %s%s", priv->netif,
-		osmo_fr_role_str(fr_link->role), VTY_NEWLINE);
+	vty_out(vty, "FR bind: %s, role: %s, link: %s%s", priv->netif,
+		osmo_fr_role_str(fr_link->role), priv->if_running ? "UP" : "DOWN", VTY_NEWLINE);
 
 	llist_for_each_entry(nsvc, &bind->nsvc, blist) {
 		vty_out(vty, "    NSVCI %05u: %s%s", nsvc->nsvci, gprs_ns2_ll_str(nsvc), VTY_NEWLINE);
@@ -335,6 +338,96 @@
 	return fd;
 }
 
+#ifdef ENABLE_LIBMNL
+
+#include <osmocom/core/mnl.h>
+#include <linux/if.h>
+#include <linux/if_link.h>
+#include <linux/rtnetlink.h>
+
+#ifndef ARPHRD_FRAD
+#define ARPHRD_FRAD  770
+#endif
+
+/* validate the netlink attributes */
+static int data_attr_cb(const struct nlattr *attr, void *data)
+{
+	const struct nlattr **tb = data;
+	int type = mnl_attr_get_type(attr);
+
+	if (mnl_attr_type_valid(attr, IFLA_MAX) < 0)
+		return MNL_CB_OK;
+
+	switch (type) {
+	case IFLA_MTU:
+		if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
+			return MNL_CB_ERROR;
+		break;
+	case IFLA_IFNAME:
+		if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
+			return MNL_CB_ERROR;
+		break;
+	}
+	tb[type] = attr;
+	return MNL_CB_OK;
+}
+
+/* find the bind for the netdev (if any) */
+static struct gprs_ns2_vc_bind *bind4netdev(struct gprs_ns2_inst *nsi, const char *ifname)
+{
+	struct gprs_ns2_vc_bind *bind;
+
+	llist_for_each_entry(bind, &nsi->binding, list) {
+		struct priv_bind *bpriv = bind->priv;
+		if (!strcmp(bpriv->netif, ifname))
+			return bind;
+	}
+
+	return NULL;
+}
+
+/* handle a single netlink message received via libmnl */
+static int linkmon_mnl_cb(const struct nlmsghdr *nlh, void *data)
+{
+	struct osmo_mnl *omnl = data;
+	struct gprs_ns2_vc_bind *bind;
+	struct nlattr *tb[IFLA_MAX+1] = {};
+	struct ifinfomsg *ifm = mnl_nlmsg_get_payload(nlh);
+	struct gprs_ns2_inst *nsi;
+	const char *ifname;
+	bool if_running;
+
+	OSMO_ASSERT(omnl);
+	OSMO_ASSERT(ifm);
+
+	nsi = omnl->priv;
+
+	if (ifm->ifi_type != ARPHRD_FRAD)
+		return 0;
+
+	mnl_attr_parse(nlh, sizeof(*ifm), data_attr_cb, tb);
+
+	if (!tb[IFLA_IFNAME])
+		return 0;
+	ifname = mnl_attr_get_str(tb[IFLA_IFNAME]);
+	if_running = !!(ifm->ifi_flags & IFF_RUNNING);
+
+	bind = bind4netdev(nsi, ifname);
+	if (bind) {
+		struct priv_bind *bpriv = bind->priv;
+		if (bpriv->if_running != if_running) {
+			/* update running state */
+			LOGP(DLNS, LOGL_NOTICE, "FR net-device '%s': Physical link state changed: %s\n",
+			     ifname, if_running ? "UP" : "DOWN");
+			bpriv->if_running = if_running;
+		}
+	}
+
+	return 0;
+}
+#endif /* LIBMNL */
+
+
 /*! Create a new bind for NS over FR.
  *  \param[in] nsi NS instance in which to create the bind
  *  \param[in] netif Network interface to bind to
@@ -402,6 +495,11 @@
 	INIT_LLIST_HEAD(&bind->nsvc);
 	llist_add(&bind->list, &nsi->binding);
 
+#ifdef ENABLE_LIBMNL
+	if (!nsi->linkmon_mnl)
+		nsi->linkmon_mnl = osmo_mnl_init(nsi, NETLINK_ROUTE, RTMGRP_LINK, linkmon_mnl_cb, nsi);
+#endif
+
 	return rc;
 
 err_fd:

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

Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Change-Id: I779556991bfc88b7751b2be17bb81c329cfb9e01
Gerrit-Change-Number: 21458
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <laforge at osmocom.org>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20201202/026b00b7/attachment.htm>


More information about the gerrit-log mailing list