#include <fcntl.h>
#include <string.h>
#include <sys/time.h>
-#include <net/if.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include "ip_common.h"
#define NUD_VALID (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE|NUD_PROBE|NUD_STALE|NUD_DELAY)
+#define MAX_ROUNDS 10
static struct
{
char *flushb;
int flushp;
int flushe;
- struct rtnl_handle *rth;
} filter;
static void usage(void) __attribute__((noreturn));
static int flush_update(void)
{
- if (rtnl_send(filter.rth, filter.flushb, filter.flushp) < 0) {
- perror("Failed to send flush request\n");
+ if (rtnl_send_check(&rth, filter.flushb, filter.flushp) < 0) {
+ perror("Failed to send flush request");
return -1;
}
filter.flushp = 0;
static int ipneigh_modify(int cmd, int flags, int argc, char **argv)
{
- struct rtnl_handle rth;
struct {
struct nlmsghdr n;
struct ndmsg ndm;
addattr_l(&req.n, sizeof(req), NDA_DST, &dst.data, dst.bytelen);
if (lla && strcmp(lla, "null")) {
- __u8 llabuf[16];
+ char llabuf[20];
int l;
l = ll_addr_a2n(llabuf, sizeof(llabuf), lla);
addattr_l(&req.n, sizeof(req), NDA_LLADDR, llabuf, l);
}
- if (rtnl_open(&rth, 0) < 0)
- exit(1);
-
ll_init_map(&rth);
if ((req.ndm.ndm_ifindex = ll_name_to_index(d)) == 0) {
if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0)
exit(2);
- exit(0);
+ return 0;
}
if (n->nlmsg_type != RTM_NEWNEIGH && n->nlmsg_type != RTM_DELNEIGH) {
fprintf(stderr, "Not RTM_NEWNEIGH: %08x %08x %08x\n",
n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
-
+
return 0;
}
len -= NLMSG_LENGTH(sizeof(*r));
memcpy(fn, n, n->nlmsg_len);
fn->nlmsg_type = RTM_DELNEIGH;
fn->nlmsg_flags = NLM_F_REQUEST;
- fn->nlmsg_seq = ++filter.rth->seq;
+ fn->nlmsg_seq = ++rth.seq;
filter.flushp = (((char*)fn) + n->nlmsg_len) - filter.flushb;
filter.flushed++;
if (show_stats < 2)
}
if (tb[NDA_DST]) {
- fprintf(fp, "%s ",
+ fprintf(fp, "%s ",
format_host(r->ndm_family,
RTA_PAYLOAD(tb[NDA_DST]),
RTA_DATA(tb[NDA_DST]),
fprintf(fp, " router");
}
if (tb[NDA_CACHEINFO] && show_stats) {
- static int hz;
struct nda_cacheinfo *ci = RTA_DATA(tb[NDA_CACHEINFO]);
- if (!hz)
- hz = get_hz();
+ int hz = get_user_hz();
+
if (ci->ndm_refcnt)
printf(" ref %d", ci->ndm_refcnt);
fprintf(fp, " used %d/%d/%d", ci->ndm_used/hz,
int do_show_or_flush(int argc, char **argv, int flush)
{
char *filter_dev = NULL;
- struct rtnl_handle rth;
int state_given = 0;
ipneigh_reset_filter();
argc--; argv++;
}
- if (rtnl_open(&rth, 0) < 0)
- exit(1);
-
ll_init_map(&rth);
if (filter_dev) {
filter.flushb = flushb;
filter.flushp = 0;
filter.flushe = sizeof(flushb);
- filter.rth = &rth;
filter.state &= ~NUD_FAILED;
- for (;;) {
+ while (round < MAX_ROUNDS) {
if (rtnl_wilddump_request(&rth, filter.family, RTM_GETNEIGH) < 0) {
perror("Cannot send dump request");
exit(1);
exit(1);
}
if (filter.flushed == 0) {
- if (round == 0) {
- fprintf(stderr, "Nothing to flush.\n");
- } else if (show_stats)
- printf("*** Flush is complete after %d round%s ***\n", round, round>1?"s":"");
+ if (show_stats) {
+ if (round == 0)
+ printf("Nothing to flush.\n");
+ else
+ printf("*** Flush is complete after %d round%s ***\n", round, round>1?"s":"");
+ }
fflush(stdout);
return 0;
}
fflush(stdout);
}
}
+ printf("*** Flush not complete bailing out after %d rounds\n",
+ MAX_ROUNDS);
+ return 1;
}
if (rtnl_wilddump_request(&rth, filter.family, RTM_GETNEIGH) < 0) {