// gcc main.c -o libnl-test -I/usr/include/libnl3/ -lnl-3 -lnl-route-3
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>

#include <netlink/netlink.h>
#include <netlink/cache.h>
#include <netlink/route/link.h>

#define log(_fmt, args...) printf(_fmt"\n", ##args)

#define err(_fmt, args...) do { \
	fprintf(stderr, _fmt"\n", ##args); \
	return EXIT_FAILURE; \
} while (0)

#define ITF1_NAME "dummy_itf666"
#define ITF2_NAME "dummy_itf42"

static void evt(struct nl_cache *l, struct nl_object *o, int e, void *d)
{
	log("stub !!!");
}

void cleanup(void)
{
	system("ip l del "ITF1_NAME);
}

int main(int argc, char *argv[])
{
	int ret;
	struct nl_sock *sk;
	struct rtnl_link *link_1;
	struct rtnl_link *link_2;
	struct nl_cache_mngr *mngr;
	struct nl_cache *cache;

	/* initialize libnl */
	sk = nl_socket_alloc();
	if (sk == NULL)
		err("nl_socket_alloc failed");
	ret = nl_cache_mngr_alloc(sk, NETLINK_ROUTE, NL_AUTO_PROVIDE, &mngr);
	if (ret != 0)
		err("nl_socket_alloc: %s", nl_geterror(ret));

	/* create link cache iif any argument is provided */
	if (argc > 1) {
		log("create link cache");
		ret = nl_cache_mngr_add(mngr, "route/link", evt, NULL, &cache);
		if (ret != 0)
			err("nl_cache_mngr_add: %s", nl_geterror(ret));
	}

	/* create a dummy link */
	link_1 = rtnl_link_alloc();
	if (link_1 == NULL)
		err("nl_socket_alloc 1 failed");
	ret = rtnl_link_set_type(link_1, "dummy");
	if (ret < 0)
		err("rtnl_link_set_type: %s", nl_geterror(ret));
	rtnl_link_set_name(link_1, ITF1_NAME);
	ret = rtnl_link_add(sk, link_1, NLM_F_CREATE);
	if (ret < 0)
		err("rtnl_link_add: %s", nl_geterror(ret));
	atexit(cleanup);

	/* delete another link which doesn't exist */
	link_2 = rtnl_link_alloc();
	if (link_2 == NULL)
		err("nl_socket_alloc 2 failed");
	rtnl_link_set_name(link_2, ITF2_NAME);
	ret = rtnl_link_delete(sk, link_2);

	/* here I espect rtnl_link_delete to return consistently -NLE_NODEV */
	log("return of rtnl_link_delete is %d: %s", ret, nl_geterror(ret));

	return EXIT_SUCCESS;
}
