/* SPDX-License-Identifier: LGPL-2.1-only */
/*
 * Copyright (c) 2008-2013 Thomas Graf <tgraf@suug.ch>
 */

/**
 * @ingroup tc
 * @defgroup pktloc Packet Location Aliasing
 * Packet Location Aliasing
 *
 * The packet location aliasing interface eases the use of offset definitions
 * inside packets by allowing them to be referenced by name. Known positions
 * of protocol fields are stored in a configuration file and associated with
 * a name for later reference. The configuration file is distributed with the
 * library and provides a well defined set of definitions for most common
 * protocol fields.
 *
 * @section pktloc_examples Examples
 * @par Example 1.1 Looking up a packet location
 * @code
 * struct rtnl_pktloc *loc;
 *
 * rtnl_pktloc_lookup("ip.src", &loc);
 * @endcode
 * @{
 */

#include "nl-default.h"

#include <sys/stat.h>

#include <netlink/netlink.h>
#include <netlink/utils.h>
#include <netlink/route/pktloc.h>

#include "nl-route.h"

#include "pktloc_syntax.h"
#include "pktloc_grammar.h"

/** @cond SKIP */
#define PKTLOC_NAME_HT_SIZ 256

static struct nl_list_head pktloc_name_ht[PKTLOC_NAME_HT_SIZ];

/* djb2 */
static unsigned int pktloc_hash(const char *str)
{
	unsigned long hash = 5381;
	int c;

	while ((c = *str++))
		hash = ((hash << 5) + hash) + c; /* hash * 33 + c */

	return hash % PKTLOC_NAME_HT_SIZ;
}

static int __pktloc_lookup(const char *name, struct rtnl_pktloc **result)
{
	struct rtnl_pktloc *loc;
	int hash;

	hash = pktloc_hash(name);
	nl_list_for_each_entry(loc, &pktloc_name_ht[hash], list) {
		if (!strcasecmp(loc->name, name)) {
			loc->refcnt++;
			*result = loc;
			return 0;
		}
	}

	return -NLE_OBJ_NOTFOUND;
}

extern int pktloc_parse(void *scanner);

static void rtnl_pktloc_free(struct rtnl_pktloc *loc)
{
	if (!loc)
		return;

	free(loc->name);
	free(loc);
}

static int read_pktlocs(void)
{
	YY_BUFFER_STATE buf = NULL;
	yyscan_t scanner = NULL;
	static time_t last_read;
	struct stat st;
	char *path;
	int i, err;
	FILE *fd;

	if (build_sysconf_path(&path, "pktloc") < 0)
		return -NLE_NOMEM;

	/* if stat fails, just try to read the file */
	if (stat(path, &st) == 0) {
		/* Don't re-read file if file is unchanged */
		if (last_read == st.st_mtime) {
			err = 0;
			goto errout;
		}
	}

	NL_DBG(2, "Reading packet location file \"%s\"\n", path);

	if (!(fd = fopen(path, "re"))) {
		err = -NLE_PKTLOC_FILE;
		goto errout;
	}

	for (i = 0; i < PKTLOC_NAME_HT_SIZ; i++) {
		struct rtnl_pktloc *loc, *n;

		nl_list_for_each_entry_safe(loc, n, &pktloc_name_ht[i], list)
			rtnl_pktloc_put(loc);

		nl_init_list_head(&pktloc_name_ht[i]);
	}

	if (pktloc_lex_init(&scanner) < 0) {
		err = -NLE_FAILURE;
		goto errout_close;
	}

	buf = pktloc__create_buffer(fd, YY_BUF_SIZE, scanner);
	pktloc__switch_to_buffer(buf, scanner);

	if ((err = pktloc_parse(scanner)) != 0) {
		pktloc__delete_buffer(buf, scanner);
		err = -NLE_PARSE_ERR;
		goto errout_scanner;
	}

	last_read = st.st_mtime;

errout_scanner:
	pktloc_lex_destroy(scanner);
errout_close:
	fclose(fd);
errout:
	free(path);

	return err;
}

/** @endcond */

/**
 * Lookup packet location alias
 * @arg name		Name of packet location.
 * @arg result		Result pointer
 *
 * Tries to find a matching packet location alias for the supplied
 * packet location name.
 *
 * The file containing the packet location definitions is automatically
 * re-read if its modification time has changed since the last call.
 *
 * The returned packet location has to be returned after use by calling
 * rtnl_pktloc_put() in order to allow freeing its memory after the last
 * user has abandoned it.
 *
 * @return 0 on success or a negative error code.
 * @retval NLE_PKTLOC_FILE Unable to open packet location file.
 * @retval NLE_OBJ_NOTFOUND No matching packet location alias found.
 */
int rtnl_pktloc_lookup(const char *name, struct rtnl_pktloc **result)
{
	int err;

	if ((err = read_pktlocs()) < 0)
		return err;
	
	return __pktloc_lookup(name, result);
}

/**
 * Allocate packet location object
 */
struct rtnl_pktloc *rtnl_pktloc_alloc(void)
{
	struct rtnl_pktloc *loc;

	if (!(loc = calloc(1, sizeof(*loc))))
		return NULL;

	loc->refcnt = 1;
	nl_init_list_head(&loc->list);

	return loc;
}

/**
 * Return reference of a packet location
 * @arg loc		packet location object.
 */
void rtnl_pktloc_put(struct rtnl_pktloc *loc)
{
	if (!loc)
		return;

	loc->refcnt--;
	if (loc->refcnt <= 0)
		rtnl_pktloc_free(loc);
}

/**
 * Add a packet location to the hash table
 * @arg loc		packet location object
 *
 * @return 0 on success or a negative error code.
 */
int rtnl_pktloc_add(struct rtnl_pktloc *loc)
{
	struct rtnl_pktloc *l;

	if (__pktloc_lookup(loc->name, &l) == 0) {
		rtnl_pktloc_put(l);
		return -NLE_EXIST;
	}

	NL_DBG(2, "New packet location entry \"%s\" align=%u layer=%u "
		  "offset=%u mask=%#x shift=%u refnt=%u\n",
		  loc->name, loc->align, loc->layer, loc->offset,
		  loc->mask, loc->shift, loc->refcnt);

	nl_list_add_tail(&loc->list, &pktloc_name_ht[pktloc_hash(loc->name)]);

	return 0;
}

void rtnl_pktloc_foreach(void (*cb)(struct rtnl_pktloc *, void *), void *arg)
{
	struct rtnl_pktloc *loc;
	int i;

	/* ignore errors */
	read_pktlocs();

	for (i = 0; i < PKTLOC_NAME_HT_SIZ; i++)
		nl_list_for_each_entry(loc, &pktloc_name_ht[i], list)
			cb(loc, arg);
}

static int _nl_init pktloc_init(void)
{
	int i;

	for (i = 0; i < PKTLOC_NAME_HT_SIZ; i++)
		nl_init_list_head(&pktloc_name_ht[i]);
	
	return 0;
}

/** @} */
