/* Simple Osmocom System Monitor (osysmon): Support for monitoring net-devices */

/* (C) 2018 by Harald Welte <laforge@gnumonks.org>
 * All Rights Reserved.
 *
 * 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 <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <arpa/inet.h>

#include <linux/if.h>
#include <linux/if_link.h>
#include <linux/rtnetlink.h>

#include <libmnl/libmnl.h>
#include <talloc.h>

#include "value_node.h"
#include "osysmon.h"

struct rtnl_client_state {
	struct mnl_socket *nl;
};


struct netdev {
	struct llist_head list;
	struct {
		const char *name;
	} cfg;
};

static struct netdev *netdev_find(struct osysmon_state *os, const char *name)
{
	struct netdev *nd;
	llist_for_each_entry(nd, &os->netdevs, list) {
		if (!strcmp(name, nd->cfg.name))
			return nd;
	}
	return NULL;
}

static struct netdev *netdev_create(struct osysmon_state *os, const char *name)
{
	struct netdev *nd;

	if (netdev_find(os, name))
		return NULL;

	nd = talloc_zero(os, struct netdev);
	if (!nd)
		return NULL;
	nd->cfg.name = talloc_strdup(os, name);
	llist_add_tail(&nd->list, &os->netdevs);
	return nd;
}

static void netdev_destroy(struct netdev *nd)
{
	llist_del(&nd->list);
	talloc_free(nd);
}

/***********************************************************************
 * VTY
 ***********************************************************************/

static struct cmd_node netdev_node = {
	NETDEV_NODE,
	"%s(config-netdev)# ",
	1,
};

int osysmon_netdev_go_parent(struct vty *vty)
{
	switch (vty->node) {
	case NETDEV_NODE:
		vty->node = CONFIG_NODE;
		vty->index = NULL;
		break;
	default:
		break;
	}
	return vty->node;
}

DEFUN(cfg_netdev, cfg_netdev_cmd,
	"netdev NAME",
	"")
{
	struct netdev *nd;
	nd = netdev_find(g_oss, argv[0]);
	if (!nd)
		nd = netdev_create(g_oss, argv[0]);
	OSMO_ASSERT(nd);

	return CMD_SUCCESS;
}

DEFUN(cfg_no_netdev, cfg_no_netdev_cmd,
	"no netdev NAME",
	"")
{
	struct netdev *nd;
	nd = netdev_find(g_oss, argv[0]);
	if (!nd) {
		vty_out(vty, "Netdev %s doesn't exist in configuration%s", argv[0], VTY_NEWLINE);
		return CMD_WARNING;
	}
	netdev_destroy(nd);
	return CMD_SUCCESS;
}

static void write_one_netdev(struct vty *vty, struct netdev *nd)
{
	vty_out(vty, "netdev %s%s", nd->cfg.name, VTY_NEWLINE);
}

static int config_write_netdev(struct vty *vty)
{
	struct netdev *nd;

	llist_for_each_entry(nd, &g_oss->netdevs, list)
		write_one_netdev(vty, nd);
	return CMD_SUCCESS;
}

static void osysmon_rtnl_vty_init(void)
{
	install_element(CONFIG_NODE, &cfg_netdev_cmd);
	install_element(CONFIG_NODE, &cfg_no_netdev_cmd);
	install_node(&netdev_node, config_write_netdev);
}


/***********************************************************************
 * Interface Level
 ***********************************************************************/

static int if_attr_cb(const struct nlattr *attr, void *data)
{
	const struct nlattr **tb = data;
	int type = mnl_attr_get_type(attr);

	/* skip unsupported attribute in user-space */
	if (mnl_attr_type_valid(attr, IFLA_MAX) < 0)
		return MNL_CB_OK;

	switch(type) {
	case IFLA_ADDRESS:
		if (mnl_attr_validate(attr, MNL_TYPE_BINARY) < 0) {
			perror("mnl_attr_validate");
			return MNL_CB_ERROR;
		}
		break;
	case IFLA_MTU:
		if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
			perror("mnl_attr_validate");
			return MNL_CB_ERROR;
		}
		break;
	case IFLA_IFNAME:
		if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) {
			perror("mnl_attr_validate");
			return MNL_CB_ERROR;
		}
		break;
	}
	tb[type] = attr;
	return MNL_CB_OK;
}

static int data_cb(const struct nlmsghdr *nlh, void *data)
{
	struct ifinfomsg *ifm = mnl_nlmsg_get_payload(nlh);
	struct value_node *parent = data;
	struct value_node *vn_if;
	const char *name;
	char buf[32];

	struct nlattr *tb[IFLA_MAX+1] = {};
	mnl_attr_parse(nlh, sizeof(*ifm), if_attr_cb, tb);
	if (!tb[IFLA_IFNAME])
		return MNL_CB_OK;
	name = mnl_attr_get_str(tb[IFLA_IFNAME]);

	/* skip any non-configured interface names */
	if (!netdev_find(g_oss, name))
		return MNL_CB_OK;

	vn_if = value_node_find_or_add(parent, talloc_strdup(parent, name));
	OSMO_ASSERT(vn_if);
	vn_if->idx = ifm->ifi_index;

	if (tb[IFLA_ADDRESS] && mnl_attr_get_payload_len(tb[IFLA_ADDRESS]) == 6) {
		uint8_t *hwaddr = mnl_attr_get_payload(tb[IFLA_ADDRESS]);
		snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x",
			 hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]);
		value_node_add(vn_if, vn_if, "hwaddr", buf);
	}
	if (ifm->ifi_flags & IFF_RUNNING) 
		value_node_add(vn_if, vn_if, "running", "true");
	else
		value_node_add(vn_if, vn_if, "running", "false");

	if (ifm->ifi_flags & IFF_UP)
		value_node_add(vn_if, vn_if, "up", "true");
	else
		value_node_add(vn_if, vn_if, "up", "false");

	return MNL_CB_OK;
}

static int rtnl_update_link(struct rtnl_client_state *rcs, struct value_node *parent)
{
	char buf[MNL_SOCKET_BUFFER_SIZE];
	struct nlmsghdr *nlh;
	struct rtgenmsg *rt;
	int ret;
	unsigned int seq, portid;

	nlh = mnl_nlmsg_put_header(buf);
	nlh->nlmsg_type	= RTM_GETLINK;
	nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
	nlh->nlmsg_seq = seq = time(NULL);
	rt = mnl_nlmsg_put_extra_header(nlh, sizeof(struct rtgenmsg));
	rt->rtgen_family = AF_PACKET;

	portid = mnl_socket_get_portid(rcs->nl);

	if (mnl_socket_sendto(rcs->nl, nlh, nlh->nlmsg_len) < 0) {
		perror("mnl_socket_sendto");
		exit(EXIT_FAILURE);
	}

	ret = mnl_socket_recvfrom(rcs->nl, buf, sizeof(buf));
	while (ret > 0) {
		ret = mnl_cb_run(buf, ret, seq, portid, data_cb, parent);
		if (ret <= MNL_CB_STOP)
			break;
		ret = mnl_socket_recvfrom(rcs->nl, buf, sizeof(buf));
	}
	if (ret == -1) {
		perror("error");
		return -1;
	}
	return 0;
}



/***********************************************************************
 * L3 Address Level
 ***********************************************************************/

static int inet_attr_cb(const struct nlattr *attr, void *data)
{
	const struct nlattr **tb = data;
	int type = mnl_attr_get_type(attr);

	/* skip unsupported attribute in user-space */
	if (mnl_attr_type_valid(attr, IFA_MAX) < 0)
		return MNL_CB_OK;

	switch(type) {
	case IFA_ADDRESS:
		if (mnl_attr_validate(attr, MNL_TYPE_BINARY) < 0) {
			perror("mnl_attr_validate");
			return MNL_CB_ERROR;
		}
		break;
	}
	tb[type] = attr;
	return MNL_CB_OK;
}

static int inet_data_cb(const struct nlmsghdr *nlh, void *data)
{
	struct ifaddrmsg *ifa = mnl_nlmsg_get_payload(nlh);
	struct nlattr *tb[IFA_MAX + 1] = {};
	struct value_node *parent = data;
	struct value_node *vn_if;

	vn_if = value_node_find_by_idx(parent, ifa->ifa_index);
	if (!vn_if)
		return MNL_CB_OK;

	if (ifa->ifa_family != AF_INET)
		return MNL_CB_OK;

	mnl_attr_parse(nlh, sizeof(*ifa), inet_attr_cb, tb);
	if (tb[IFA_ADDRESS]) {
		struct in_addr *addr = mnl_attr_get_payload(tb[IFA_ADDRESS]);
		char out[INET_ADDRSTRLEN+32];
		snprintf(out, sizeof(out), "%s/%u", inet_ntoa(*addr), ifa->ifa_prefixlen);
		value_node_add(vn_if, vn_if, "ip", out);
	}

	return MNL_CB_OK;
}

static int rtnl_update_addr(struct rtnl_client_state *rcs, struct value_node *parent)
{
	char buf[MNL_SOCKET_BUFFER_SIZE];
	struct nlmsghdr *nlh;
	struct rtgenmsg *rt;
	int ret;
	unsigned int seq, portid;

	nlh = mnl_nlmsg_put_header(buf);
	nlh->nlmsg_type	= RTM_GETADDR;
	nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
	nlh->nlmsg_seq = seq = time(NULL);
	rt = mnl_nlmsg_put_extra_header(nlh, sizeof(struct rtgenmsg));
	rt->rtgen_family = AF_INET;

	portid = mnl_socket_get_portid(rcs->nl);

	if (mnl_socket_sendto(rcs->nl, nlh, nlh->nlmsg_len) < 0) {
		perror("mnl_socket_sendto");
		exit(EXIT_FAILURE);
	}

	ret = mnl_socket_recvfrom(rcs->nl, buf, sizeof(buf));
	while (ret > 0) {
		ret = mnl_cb_run(buf, ret, seq, portid, inet_data_cb, parent);
		if (ret <= MNL_CB_STOP)
			break;
		ret = mnl_socket_recvfrom(rcs->nl, buf, sizeof(buf));
	}
	if (ret == -1) {
		perror("error");
		return -1;
	}

	return 0;
}



/***********************************************************************
 * Common Code / API
 ***********************************************************************/

int osysmon_rtnl_init()
{
	osysmon_rtnl_vty_init();
	return 0;
}



struct rtnl_client_state *rtnl_init(void *ctx)
{
	struct mnl_socket *nl;
	struct rtnl_client_state *rcs;

	nl = mnl_socket_open(NETLINK_ROUTE);
	if (nl == NULL) {
		perror("mnl_socket_open");
		return NULL;
	}
	if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
		perror("mnl_socket_bind");
		mnl_socket_close(nl);
		return NULL;
	}

	rcs = talloc_zero(ctx, struct rtnl_client_state);
	if (!rcs) {
		mnl_socket_close(nl);
		return NULL;
	}

	rcs->nl = nl;

	return rcs;
}

int osysmon_rtnl_poll(struct value_node *parent)
{
	struct value_node *vn_net;

	if (!g_oss->rcs)
		g_oss->rcs = rtnl_init(NULL);

	vn_net = value_node_add(parent, parent, "netdev", NULL);

	if (!g_oss->rcs)
		return -1;

	rtnl_update_link(g_oss->rcs, vn_net);
	rtnl_update_addr(g_oss->rcs, vn_net);

	return 0;
}
