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

#include "nl-default.h"

#include <linux/netlink.h>
#include <linux/if_ether.h>

#include <netlink/attr.h>
#include <netlink/msg.h>
#include <netlink/route/cls/u32.h>

#include "cksuite-all.h"
#include "nl-aux-route/nl-route.h"

START_TEST(attr_size)
{
	ck_assert_msg(nla_attr_size(0) == NLA_HDRLEN,
		      "Length of empty attribute should match header size");
	ck_assert_msg(nla_attr_size(1) == NLA_HDRLEN + 1,
		      "Length of 1 bytes payload should be NLA_HDRLEN + 1");
	ck_assert_msg(nla_attr_size(2) == NLA_HDRLEN + 2,
		      "Length of 2 bytes payload should be NLA_HDRLEN + 2");
	ck_assert_msg(nla_attr_size(3) == NLA_HDRLEN + 3,
		      "Length of 3 bytes payload should be NLA_HDRLEN + 3");
	ck_assert_msg(nla_attr_size(4) == NLA_HDRLEN + 4,
		      "Length of 4 bytes payload should be NLA_HDRLEN + 4");

	ck_assert_msg(nla_total_size(1) == NLA_HDRLEN + 4,
		      "Total size of 1 bytes payload should result in 8 bytes");
	ck_assert_msg(nla_total_size(2) == NLA_HDRLEN + 4,
		      "Total size of 2 bytes payload should result in 8 bytes");
	ck_assert_msg(nla_total_size(3) == NLA_HDRLEN + 4,
		      "Total size of 3 bytes payload should result in 8 bytes");
	ck_assert_msg(nla_total_size(4) == NLA_HDRLEN + 4,
		      "Total size of 4 bytes payload should result in 8 bytes");

	ck_assert_msg(nla_padlen(1) == 3,
		      "2 bytes of payload should result in 3 padding bytes");
	ck_assert_msg(nla_padlen(2) == 2,
		      "2 bytes of payload should result in 2 padding bytes");
	ck_assert_msg(nla_padlen(3) == 1,
		      "3 bytes of payload should result in 1 padding bytes");
	ck_assert_msg(nla_padlen(4) == 0,
		      "4 bytes of payload should result in 0 padding bytes");
	ck_assert_msg(nla_padlen(5) == 3,
		      "5 bytes of payload should result in 3 padding bytes");
}
END_TEST

START_TEST(msg_construct)
{
	struct nl_msg *msg;
	struct nlmsghdr *nlh;
	struct nlattr *a;
	int i, rem;

	msg = nlmsg_alloc();
	ck_assert_msg(msg, "Unable to allocate netlink message");

	for (i = 1; i < 256; i++) {
		ck_assert_msg(nla_put_u32(msg, i, i + 1) == 0,
			      "Unable to add attribute %d", i);
	}

	nlh = nlmsg_hdr(msg);
	i = 1;
	nlmsg_for_each_attr(a, nlh, 0, rem) {
		ck_assert_msg(nla_type(a) == i, "Expected attribute %d", i);
		i++;
		ck_assert_msg(nla_get_u32(a) == (unsigned)i,
			      "Expected attribute value %d", i);
	}

	nlmsg_free(msg);
}
END_TEST

START_TEST(clone_cls_u32)
{
	_nl_auto_rtnl_link struct rtnl_link *link = NULL;
	_nl_auto_rtnl_cls struct rtnl_cls *cls = NULL;
	_nl_auto_rtnl_cls struct rtnl_cls *cls2 = NULL;
	int r;
	const uint32_t direction = 16;

	link = rtnl_link_alloc();
	ck_assert(link);

	rtnl_link_set_ifindex(link, 5);

	cls = rtnl_cls_alloc();
	ck_assert(cls);

	rtnl_tc_set_link(TC_CAST(cls), link);

	r = rtnl_tc_set_kind(TC_CAST(cls), "u32");
	ck_assert(r == 0);

	rtnl_cls_set_prio(cls, 1);
	rtnl_cls_set_protocol(cls, ETH_P_IP);

	rtnl_tc_set_parent(TC_CAST(cls), TC_HANDLE(1, 0));

	rtnl_u32_set_hashtable(cls, 5);

	rtnl_u32_add_key_uint32(cls, 0x0a000914, 0xffffffff, direction, 0);

	rtnl_u32_set_hashmask(cls, 0xff000000, direction);

	rtnl_u32_add_mark(cls, 55, 66);

	rtnl_u32_set_link(cls, 44);

	cls2 = (struct rtnl_cls *)nl_object_clone((struct nl_object *)cls);
	ck_assert(cls2);
}
END_TEST

/*****************************************************************************/

START_TEST(test_nltst_strtok)
{
#define _assert_strtok(str, ...)                                               \
	do {                                                                   \
		const char *const _expected[] = { NULL, ##__VA_ARGS__, NULL }; \
		_nltst_auto_strfreev char **_tokens = NULL;                    \
                                                                               \
		_tokens = _nltst_strtokv(str);                                 \
		_nltst_assert_strv_equal(_tokens, &_expected[1]);              \
	} while (0)

	_assert_strtok("");
	_assert_strtok("    \n");
	_assert_strtok("a", "a");
	_assert_strtok(" a ", "a");
	_assert_strtok(" a\\  b", "a\\ ", "b");
	_assert_strtok(" a\\  b   cc\\d", "a\\ ", "b", "cc\\d");
	_assert_strtok(" a\\  b\\   cc\\d", "a\\ ", "b\\ ", "cc\\d");
}
END_TEST

/*****************************************************************************/

START_TEST(test_nltst_select_route)
{
	/* This is a unit test for testing the unit-test helper function
	 * _nltst_select_route_parse(). */

#define _check(str, exp_addr_family, exp_addr_pattern, exp_plen)               \
	do {                                                                   \
		const char *_str = (str);                                      \
		const int _exp_addr_family = (exp_addr_family);                \
		const char *const _exp_addr_pattern = (exp_addr_pattern);      \
		const int _exp_plen = (exp_plen);                              \
		_nltst_auto_clear_select_route NLTstSelectRoute                \
			_select_route = { 0 };                                 \
		_nltst_auto_clear_select_route NLTstSelectRoute                \
			_select_route2 = { 0 };                                \
		_nl_auto_free char *_str2 = NULL;                              \
                                                                               \
		_nltst_select_route_parse(_str, &_select_route);               \
		ck_assert_int_eq(_exp_addr_family, _select_route.addr_family); \
		if (_nltst_inet_valid(AF_UNSPEC, _exp_addr_pattern)) {         \
			ck_assert_str_eq(_exp_addr_pattern,                    \
					 _select_route.addr);                  \
			ck_assert_ptr_null(_select_route.addr_pattern);        \
		} else {                                                       \
			ck_assert_str_eq(_exp_addr_pattern,                    \
					 _select_route.addr_pattern);          \
			ck_assert_ptr_null(_select_route.addr);                \
		}                                                              \
		ck_assert_int_eq(_exp_plen, _select_route.plen);               \
                                                                               \
		_nltst_assert_select_route(&_select_route);                    \
                                                                               \
		_str2 = _nltst_select_route_to_string(&_select_route);         \
		ck_assert_ptr_nonnull(_str2);                                  \
                                                                               \
		_nltst_select_route_parse(_str2, &_select_route2);             \
                                                                               \
		ck_assert(_nltst_select_route_equal(&_select_route,            \
						    &_select_route2));         \
	} while (0)

	_check("0.0.0.0", AF_INET, "0.0.0.0", -1);
	_check("4 0.0.0.0/0", AF_INET, "0.0.0.0", 0);
	_check(" 6\n 0:0::/0", AF_INET6, "::", 0);
	_check(" \n 0:0::/100", AF_INET6, "::", 100);
	_check("6 0:0::*/0   ", AF_INET6, "0:0::*", 0);
	_check("6 0:0::*/128   ", AF_INET6, "0:0::*", 128);
	_check("6 0:0::*   ", AF_INET6, "0:0::*", -1);

#undef _check
}

/*****************************************************************************/

Suite *make_nl_attr_suite(void)
{
	Suite *suite = suite_create("Netlink attributes");
	TCase *tc = tcase_create("Core");

	tcase_add_test(tc, attr_size);
	tcase_add_test(tc, msg_construct);
	tcase_add_test(tc, clone_cls_u32);
	tcase_add_test(tc, test_nltst_strtok);
	tcase_add_test(tc, test_nltst_select_route);
	suite_add_tcase(suite, tc);

	return suite;
}
