144d362409d5469aed47d19e7908d19bd194493aThomas Graf/*
244d362409d5469aed47d19e7908d19bd194493aThomas Graf * src/nl-neigh-delete.c     Delete a neighbour
344d362409d5469aed47d19e7908d19bd194493aThomas Graf *
444d362409d5469aed47d19e7908d19bd194493aThomas Graf *	This library is free software; you can redistribute it and/or
544d362409d5469aed47d19e7908d19bd194493aThomas Graf *	modify it under the terms of the GNU Lesser General Public
644d362409d5469aed47d19e7908d19bd194493aThomas Graf *	License as published by the Free Software Foundation version 2.1
744d362409d5469aed47d19e7908d19bd194493aThomas Graf *	of the License.
844d362409d5469aed47d19e7908d19bd194493aThomas Graf *
98808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf * Copyright (c) 2003-2009 Thomas Graf <tgraf@suug.ch>
1044d362409d5469aed47d19e7908d19bd194493aThomas Graf */
1144d362409d5469aed47d19e7908d19bd194493aThomas Graf
128808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf#include <netlink/cli/utils.h>
138808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf#include <netlink/cli/neigh.h>
148808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf#include <netlink/cli/link.h>
1544d362409d5469aed47d19e7908d19bd194493aThomas Graf
1610cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Grafstatic int quiet = 0, default_yes = 0, deleted = 0, interactive = 0;
1710cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Grafstruct nl_sock *sock;
1810cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf
1910cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Grafstatic void print_usage(void)
2044d362409d5469aed47d19e7908d19bd194493aThomas Graf{
2110cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf	printf(
2210cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf	"Usage: nl-neigh-delete [OPTION]... [NEIGHBOUR]\n"
2310cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf	"\n"
2410cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf	"Options\n"
2510cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf	" -i, --interactive     Run interactively\n"
2610cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf	"     --yes             Set default answer to yes\n"
2710cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf	" -q, --quiet           Do not print informal notifications\n"
2810cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf	" -h, --help            Show this help\n"
2910cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf	" -v, --version         Show versioning information\n"
3010cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf	"\n"
3110cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf	"Neighbour Options\n"
3210cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf	" -a, --addr=ADDR       Destination address of neighbour\n"
3310cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf	" -l, --lladdr=ADDR     Link layer address of neighbour\n"
3410cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf	" -d, --dev=DEV         Device the neighbour is connected to\n"
3510cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf	"     --family=FAMILY   Destination address family\n"
3610cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf	"     --state=STATE     Neighbour state, (default = permanent)\n"
3710cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf	);
3844d362409d5469aed47d19e7908d19bd194493aThomas Graf
3910cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf	exit(0);
4010cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf}
4144d362409d5469aed47d19e7908d19bd194493aThomas Graf
4210cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Grafstatic void delete_cb(struct nl_object *obj, void *arg)
4310cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf{
4410cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf	struct rtnl_neigh *neigh = nl_object_priv(obj);
4510cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf	struct nl_dump_params params = {
46d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf		.dp_type = NL_DUMP_LINE,
4710cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf		.dp_fd = stdout,
4810cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf	};
4910cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf	int err;
5044d362409d5469aed47d19e7908d19bd194493aThomas Graf
518808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf	if (interactive && !nl_cli_confirm(obj, &params, default_yes))
5210cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf		return;
5344d362409d5469aed47d19e7908d19bd194493aThomas Graf
5410cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf	if ((err = rtnl_neigh_delete(sock, neigh, 0)) < 0)
558808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf		nl_cli_fatal(err, "Unable to delete neighbour: %s\n",
568808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf			     nl_geterror(err));
5744d362409d5469aed47d19e7908d19bd194493aThomas Graf
5810cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf	if (!quiet) {
5910cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf		printf("Deleted ");
6010cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf		nl_object_dump(obj, &params);
6144d362409d5469aed47d19e7908d19bd194493aThomas Graf	}
6244d362409d5469aed47d19e7908d19bd194493aThomas Graf
6310cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf	deleted++;
6410cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf}
6510cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf
6610cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Grafint main(int argc, char *argv[])
6710cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf{
6810cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf	struct rtnl_neigh *neigh;
6910cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf	struct nl_cache *link_cache, *neigh_cache;
7010cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf
718808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf	sock = nl_cli_alloc_socket();
728808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf	nl_cli_connect(sock, NETLINK_ROUTE);
738808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf	link_cache = nl_cli_link_alloc_cache(sock);
748808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf	neigh_cache = nl_cli_neigh_alloc_cache(sock);
758808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf 	neigh = nl_cli_neigh_alloc();
7610cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf
7710cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf	for (;;) {
7810cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf		int c, optidx = 0;
7910cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf		enum {
8010cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf			ARG_FAMILY = 257,
8110cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf			ARG_STATE = 258,
8210cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf			ARG_YES,
8310cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf		};
8410cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf		static struct option long_opts[] = {
8510cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf			{ "interactive", 0, 0, 'i' },
8610cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf			{ "yes", 0, 0, ARG_YES },
8710cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf			{ "quiet", 0, 0, 'q' },
8810cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf			{ "help", 0, 0, 'h' },
8910cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf			{ "version", 0, 0, 'v' },
9010cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf			{ "addr", 1, 0, 'a' },
9110cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf			{ "lladdr", 1, 0, 'l' },
9210cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf			{ "dev", 1, 0, 'd' },
9310cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf			{ "family", 1, 0, ARG_FAMILY },
9410cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf			{ "state", 1, 0, ARG_STATE },
9510cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf			{ 0, 0, 0, 0 }
9610cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf		};
9710cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf
9810cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf		c = getopt_long(argc, argv, "qhva:l:d:", long_opts, &optidx);
9910cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf		if (c == -1)
10010cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf			break;
10144d362409d5469aed47d19e7908d19bd194493aThomas Graf
10210cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf		switch (c) {
10310cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf		case 'i': interactive = 1; break;
10410cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf		case ARG_YES: default_yes = 1; break;
10510cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf		case 'q': quiet = 1; break;
10610cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf		case 'h': print_usage(); break;
1078808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf		case 'v': nl_cli_print_version(); break;
1088808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf		case 'a': nl_cli_neigh_parse_dst(neigh, optarg); break;
1098808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf		case 'l': nl_cli_neigh_parse_lladdr(neigh, optarg); break;
1108808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf		case 'd': nl_cli_neigh_parse_dev(neigh, link_cache, optarg); break;
1118808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf		case ARG_FAMILY: nl_cli_neigh_parse_family(neigh, optarg); break;
1128808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf		case ARG_STATE: nl_cli_neigh_parse_state(neigh, optarg); break;
11310cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf		}
11410cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf 	}
11544d362409d5469aed47d19e7908d19bd194493aThomas Graf
11610cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf	nl_cache_foreach_filter(neigh_cache, OBJ_CAST(neigh), delete_cb, NULL);
11744d362409d5469aed47d19e7908d19bd194493aThomas Graf
11810cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf	if (!quiet)
11910cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf		printf("Deleted %d neighbours\n", deleted);
12044d362409d5469aed47d19e7908d19bd194493aThomas Graf
12110cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf	return 0;
12244d362409d5469aed47d19e7908d19bd194493aThomas Graf}
123