char *flushb;
int flushp;
int flushe;
- struct rtnl_handle *rth;
} filter;
static int do_link;
static int flush_update(void)
{
- if (rtnl_send(filter.rth, filter.flushb, filter.flushp) < 0) {
+ if (rtnl_send(&rth, filter.flushb, filter.flushp) < 0) {
perror("Failed to send flush request\n");
return -1;
}
memcpy(fn, n, n->nlmsg_len);
fn->nlmsg_type = RTM_DELADDR;
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)
{
struct nlmsg_list *linfo = NULL;
struct nlmsg_list *ainfo = NULL;
- struct nlmsg_list *l;
- struct rtnl_handle rth;
+ struct nlmsg_list *l, *n;
char *filter_dev = NULL;
int no_link = 0;
if (filter.family == AF_UNSPEC)
filter.family = filter.pfx.family;
} else if (strcmp(*argv, "scope") == 0) {
- int scope = 0;
+ unsigned scope = 0;
NEXT_ARG();
filter.scopemask = -1;
if (rtnl_rtscope_a2n(&scope, *argv)) {
argv++; argc--;
}
- if (rtnl_open(&rth, 0) < 0)
- exit(1);
-
if (rtnl_wilddump_request(&rth, preferred_family, RTM_GETLINK) < 0) {
perror("Cannot send dump request");
exit(1);
filter.flushb = flushb;
filter.flushp = 0;
filter.flushe = sizeof(flushb);
- filter.rth = &rth;
for (;;) {
if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) {
}
round++;
if (flush_update() < 0)
- exit(1);
+ return 1;
+
if (show_stats) {
printf("\n*** Round %d, deleting %d addresses ***\n", round, filter.flushed);
fflush(stdout);
}
}
- for (l=linfo; l; l = l->next) {
+ for (l=linfo; l; l = n) {
+ n = l->next;
if (no_link || print_linkinfo(NULL, &l->h, stdout) == 0) {
struct ifinfomsg *ifi = NLMSG_DATA(&l->h);
if (filter.family != AF_PACKET)
print_selected_addrinfo(ifi->ifi_index, ainfo, stdout);
}
fflush(stdout);
+ free(l);
}
- exit(0);
+ return 0;
}
int ipaddr_list_link(int argc, char **argv)
int ipaddr_modify(int cmd, int argc, char **argv)
{
- struct rtnl_handle rth;
struct {
struct nlmsghdr n;
struct ifaddrmsg ifa;
} req;
char *d = NULL;
char *l = NULL;
+ char *lcl_arg = NULL;
inet_prefix lcl;
inet_prefix peer;
int local_len = 0;
addattr_l(&req.n, sizeof(req), IFA_ANYCAST, &addr.data, addr.bytelen);
any_len = addr.bytelen;
} else if (strcmp(*argv, "scope") == 0) {
- int scope = 0;
+ unsigned scope = 0;
NEXT_ARG();
if (rtnl_rtscope_a2n(&scope, *argv))
invarg(*argv, "invalid scope value.");
usage();
if (local_len)
duparg2("local", *argv);
+ lcl_arg = *argv;
get_prefix(&lcl, *argv, req.ifa.ifa_family);
if (req.ifa.ifa_family == AF_UNSPEC)
req.ifa.ifa_family = lcl.family;
exit(1);
}
- if (peer_len == 0 && local_len && cmd != RTM_DELADDR) {
- peer = lcl;
- addattr_l(&req.n, sizeof(req), IFA_ADDRESS, &lcl.data, lcl.bytelen);
+ if (peer_len == 0 && local_len) {
+ if (cmd == RTM_DELADDR && lcl.family == AF_INET && !(lcl.flags & PREFIXLEN_SPECIFIED)) {
+ fprintf(stderr,
+ "Warning: Executing wildcard deletion to stay compatible with old scripts.\n" \
+ " Explicitly specify the prefix length (%s/%d) to avoid this warning.\n" \
+ " This special behaviour is likely to disappear in further releases,\n" \
+ " fix your scripts!\n", lcl_arg, local_len*8);
+ } else {
+ peer = lcl;
+ addattr_l(&req.n, sizeof(req), IFA_ADDRESS, &lcl.data, lcl.bytelen);
+ }
}
if (req.ifa.ifa_prefixlen == 0)
req.ifa.ifa_prefixlen = lcl.bitlen;
if (!scoped && cmd != RTM_DELADDR)
req.ifa.ifa_scope = default_scope(&lcl);
- if (rtnl_open(&rth, 0) < 0)
- exit(1);
-
ll_init_map(&rth);
if ((req.ifa.ifa_index = ll_name_to_index(d)) == 0) {
if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0)
exit(2);
- exit(0);
+ return 0;
}
int do_ipaddr(int argc, char **argv)