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

/**
 * @ingroup ematch
 * @defgroup em_text Text Search
 *
 * @{
 */

#include "nl-default.h"

#include <linux/tc_ematch/tc_em_text.h>

#include <netlink/netlink.h>
#include <netlink/route/cls/ematch.h>
#include <netlink/route/cls/ematch/text.h>

struct text_data
{
	struct tcf_em_text	cfg;
	char *			pattern;
};

void rtnl_ematch_text_set_from(struct rtnl_ematch *e, uint8_t layer,
			       uint16_t offset)
{
	struct text_data *t = rtnl_ematch_data(e);
	t->cfg.from_offset = offset;
	t->cfg.from_layer = layer;
}

uint16_t rtnl_ematch_text_get_from_offset(struct rtnl_ematch *e)
{
	return ((struct text_data *) rtnl_ematch_data(e))->cfg.from_offset;
}

uint8_t rtnl_ematch_text_get_from_layer(struct rtnl_ematch *e)
{
	return ((struct text_data *) rtnl_ematch_data(e))->cfg.from_layer;
}

void rtnl_ematch_text_set_to(struct rtnl_ematch *e, uint8_t layer,
			       uint16_t offset)
{
	struct text_data *t = rtnl_ematch_data(e);
	t->cfg.to_offset = offset;
	t->cfg.to_layer = layer;
}

uint16_t rtnl_ematch_text_get_to_offset(struct rtnl_ematch *e)
{
	return ((struct text_data *) rtnl_ematch_data(e))->cfg.to_offset;
}

uint8_t rtnl_ematch_text_get_to_layer(struct rtnl_ematch *e)
{
	return ((struct text_data *) rtnl_ematch_data(e))->cfg.to_layer;
}

void rtnl_ematch_text_set_pattern(struct rtnl_ematch *e,
				  char *pattern, size_t len)
{
	struct text_data *t = rtnl_ematch_data(e);

	if (t->pattern)
		free(t->pattern);

	t->pattern = pattern;
	t->cfg.pattern_len = len;
}

char *rtnl_ematch_text_get_pattern(struct rtnl_ematch *e)
{
	return ((struct text_data *) rtnl_ematch_data(e))->pattern;
}

size_t rtnl_ematch_text_get_len(struct rtnl_ematch *e)
{
	return ((struct text_data *) rtnl_ematch_data(e))->cfg.pattern_len;
}

void rtnl_ematch_text_set_algo(struct rtnl_ematch *e, const char *algo)
{
	struct text_data *t = rtnl_ematch_data(e);

	_nl_strncpy_trunc(t->cfg.algo, algo, sizeof(t->cfg.algo));
}

char *rtnl_ematch_text_get_algo(struct rtnl_ematch *e)
{
	struct text_data *t = rtnl_ematch_data(e);

	return t->cfg.algo[0] ? t->cfg.algo : NULL;
}

static int text_parse(struct rtnl_ematch *e, void *data, size_t len)
{
	struct text_data *t = rtnl_ematch_data(e);
	size_t hdrlen = sizeof(struct tcf_em_text);
	size_t plen = len - hdrlen;

	memcpy(&t->cfg, data, hdrlen);

	if (t->cfg.pattern_len > plen)
		return -NLE_INVAL;

	if (t->cfg.pattern_len > 0) {
		if (!(t->pattern = calloc(1, t->cfg.pattern_len)))
			return -NLE_NOMEM;

		memcpy(t->pattern, (char *) data + hdrlen, t->cfg.pattern_len);
	}

	return 0;
}

static void text_dump(struct rtnl_ematch *e, struct nl_dump_params *p)
{
	struct text_data *t = rtnl_ematch_data(e);
	char buf[64];

	nl_dump(p, "text(%s \"%s\"",
		t->cfg.algo[0] ? t->cfg.algo : "no-algo",
		t->pattern ? t->pattern : "no-pattern");

	if (t->cfg.from_layer || t->cfg.from_offset) {
		nl_dump(p, " from %s",
			rtnl_ematch_offset2txt(t->cfg.from_layer,
					       t->cfg.from_offset,
					       buf, sizeof(buf)));
	}

	if (t->cfg.to_layer || t->cfg.to_offset) {
		nl_dump(p, " to %s",
			rtnl_ematch_offset2txt(t->cfg.to_layer,
					       t->cfg.to_offset,
					       buf, sizeof(buf)));
	}

	nl_dump(p, ")");
}

static int text_fill(struct rtnl_ematch *e, struct nl_msg *msg)
{
	struct text_data *t = rtnl_ematch_data(e);
	int err;

	if ((err = nlmsg_append(msg, &t->cfg, sizeof(t->cfg), 0)) < 0)
		return err;

	return nlmsg_append(msg, t->pattern, t->cfg.pattern_len, 0);
}

static void text_free(struct rtnl_ematch *e)
{
	struct text_data *t = rtnl_ematch_data(e);
	free(t->pattern);
}

static struct rtnl_ematch_ops text_ops = {
	.eo_kind	= TCF_EM_TEXT,
	.eo_name	= "text",
	.eo_minlen	= sizeof(struct tcf_em_text),
	.eo_datalen	= sizeof(struct text_data),
	.eo_parse	= text_parse,
	.eo_dump	= text_dump,
	.eo_fill	= text_fill,
	.eo_free	= text_free,
};

static void _nl_init text_init(void)
{
	rtnl_ematch_register(&text_ops);
}

/** @} */
