#include <stdio.h>
#include <xtables.h>
#include <linux/netfilter/xt_rpfilter.h>

enum {
	O_RPF_LOOSE = 0,
	O_RPF_VMARK = 1,
	O_RPF_ACCEPT_LOCAL = 2,
	O_RPF_INVERT = 3,
};

static void rpfilter_help(void)
{
	printf(
"rpfilter match options:\n"
"    --loose          permit reverse path via any interface\n"
"    --validmark      use skb nfmark when performing route lookup\n"
"    --accept-local   do not reject packets with a local source address\n"
"    --invert         match packets that failed the reverse path test\n"
	);
}

static const struct xt_option_entry rpfilter_opts[] = {
	{.name = "loose", .id = O_RPF_LOOSE, .type = XTTYPE_NONE, },
	{.name = "validmark", .id = O_RPF_VMARK, .type = XTTYPE_NONE, },
	{.name = "accept-local", .id = O_RPF_ACCEPT_LOCAL, .type = XTTYPE_NONE, },
	{.name = "invert", .id = O_RPF_INVERT, .type = XTTYPE_NONE, },
	XTOPT_TABLEEND,
};

static void rpfilter_parse(struct xt_option_call *cb)
{
	struct xt_rpfilter_info *rpfinfo = cb->data;

	xtables_option_parse(cb);
	switch (cb->entry->id) {
	case O_RPF_LOOSE:
		rpfinfo->flags |= XT_RPFILTER_LOOSE;
		break;
	case O_RPF_VMARK:
		rpfinfo->flags |= XT_RPFILTER_VALID_MARK;
		break;
	case O_RPF_ACCEPT_LOCAL:
		rpfinfo->flags |= XT_RPFILTER_ACCEPT_LOCAL;
		break;
	case O_RPF_INVERT:
		rpfinfo->flags |= XT_RPFILTER_INVERT;
		break;
	}
}

static void
rpfilter_print_prefix(const void *ip, const void *matchinfo,
			const char *prefix)
{
	const struct xt_rpfilter_info *info = matchinfo;
	if (info->flags & XT_RPFILTER_LOOSE)
		printf(" %s%s", prefix, rpfilter_opts[O_RPF_LOOSE].name);
	if (info->flags & XT_RPFILTER_VALID_MARK)
		printf(" %s%s", prefix, rpfilter_opts[O_RPF_VMARK].name);
	if (info->flags & XT_RPFILTER_ACCEPT_LOCAL)
		printf(" %s%s", prefix, rpfilter_opts[O_RPF_ACCEPT_LOCAL].name);
	if (info->flags & XT_RPFILTER_INVERT)
		printf(" %s%s", prefix, rpfilter_opts[O_RPF_INVERT].name);
}


static void
rpfilter_print(const void *ip, const struct xt_entry_match *match, int numeric)
{
	printf(" rpfilter");
	return rpfilter_print_prefix(ip, match->data, "");
}

static void rpfilter_save(const void *ip, const struct xt_entry_match *match)
{
	return rpfilter_print_prefix(ip, match->data, "--");
}

static int rpfilter_xlate(struct xt_xlate *xl,
			  const struct xt_xlate_mt_params *params)
{
	const struct xt_rpfilter_info *info = (void *)params->match->data;
	bool invert = info->flags & XT_RPFILTER_INVERT;

	if (info->flags & XT_RPFILTER_ACCEPT_LOCAL) {
		if (invert)
			xt_xlate_add(xl, "fib saddr type != local ");
		else
			return 0;
	}

	xt_xlate_add(xl, "fib saddr ");

	if (info->flags & XT_RPFILTER_VALID_MARK)
		xt_xlate_add(xl, ". mark ");
	if (!(info->flags & XT_RPFILTER_LOOSE))
		xt_xlate_add(xl, ". iif ");

	xt_xlate_add(xl, "oif %s0", invert ? "" : "!= ");

	return 1;
}

static struct xtables_match rpfilter_match = {
	.family		= NFPROTO_UNSPEC,
	.name		= "rpfilter",
	.version	= XTABLES_VERSION,
	.size		= XT_ALIGN(sizeof(struct xt_rpfilter_info)),
	.userspacesize	= XT_ALIGN(sizeof(struct xt_rpfilter_info)),
	.help		= rpfilter_help,
	.print		= rpfilter_print,
	.save		= rpfilter_save,
	.x6_parse	= rpfilter_parse,
	.x6_options	= rpfilter_opts,
	.xlate		= rpfilter_xlate,
};

void _init(void)
{
	xtables_register_match(&rpfilter_match);
}
