From d66370cd7329d7d1022644c0a8213147adf8e016 Mon Sep 17 00:00:00 2001 From: Glenn L McGrath Date: Mon, 13 Jan 2003 21:40:38 +0000 Subject: Option to allow ifupdown use ip commands instead of ifconfig, add flush command to ipaddr, patch by Bastian Blank --- networking/libiproute/ipaddress.c | 83 +++++++++++++++++++++++++++++++++++++-- networking/libiproute/iplink.c | 2 +- 2 files changed, 81 insertions(+), 4 deletions(-) (limited to 'networking/libiproute') diff --git a/networking/libiproute/ipaddress.c b/networking/libiproute/ipaddress.c index 2821f2e..77368fb 100644 --- a/networking/libiproute/ipaddress.c +++ b/networking/libiproute/ipaddress.c @@ -42,6 +42,10 @@ static struct int flags, flagmask; int up; char *label; + int flushed; + char *flushb; + int flushp; + int flushe; struct rtnl_handle *rth; } filter; @@ -191,6 +195,16 @@ static int print_linkinfo(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg return 0; } +static int flush_update(void) +{ + if (rtnl_send(filter.rth, filter.flushb, filter.flushp) < 0) { + perror("Failed to send flush request\n"); + return -1; + } + filter.flushp = 0; + return 0; +} + static int print_addrinfo(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) { FILE *fp = (FILE*)arg; @@ -208,6 +222,9 @@ static int print_addrinfo(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg return -1; } + if (filter.flushb && n->nlmsg_type != RTM_NEWADDR) + return 0; + memset(rta_tb, 0, sizeof(rta_tb)); parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(ifa), n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa))); @@ -242,6 +259,22 @@ static int print_addrinfo(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg } } + if (filter.flushb) { + struct nlmsghdr *fn; + if (NLMSG_ALIGN(filter.flushp) + n->nlmsg_len > filter.flushe) { + if (flush_update()) + return -1; + } + fn = (struct nlmsghdr*)(filter.flushb + NLMSG_ALIGN(filter.flushp)); + memcpy(fn, n, n->nlmsg_len); + fn->nlmsg_type = RTM_DELADDR; + fn->nlmsg_flags = NLM_F_REQUEST; + fn->nlmsg_seq = ++filter.rth->seq; + filter.flushp = (((char*)fn) + n->nlmsg_len) - filter.flushb; + filter.flushed++; + return 0; + } + if (n->nlmsg_type == RTM_DELADDR) fprintf(fp, "Deleted "); @@ -382,7 +415,7 @@ static void ipaddr_reset_filter(int _oneline) filter.oneline = _oneline; } -extern int ipaddr_list(int argc, char **argv) +extern int ipaddr_list_or_flush(int argc, char **argv, int flush) { const char *option[] = { "to", "scope", "up", "label", "dev", 0 }; struct nlmsg_list *linfo = NULL; @@ -398,6 +431,17 @@ extern int ipaddr_list(int argc, char **argv) if (filter.family == AF_UNSPEC) filter.family = preferred_family; + if (flush) { + if (argc <= 0) { + fprintf(stderr, "Flush requires arguments.\n"); + return -1; + } + if (filter.family == AF_PACKET) { + fprintf(stderr, "Cannot flush link addresses.\n"); + return -1; + } + } + while (argc > 0) { const unsigned short option_num = compare_string_array(option, *argv); switch (option_num) { @@ -461,6 +505,37 @@ extern int ipaddr_list(int argc, char **argv) } } + if (flush) { + int round = 0; + char flushb[4096-512]; + + filter.flushb = flushb; + filter.flushp = 0; + filter.flushe = sizeof(flushb); + filter.rth = &rth; + + for (;;) { + if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) { + perror("Cannot send dump request"); + exit(1); + } + filter.flushed = 0; + if (rtnl_dump_filter(&rth, print_addrinfo, stdout, NULL, NULL) < 0) { + fprintf(stderr, "Flush terminated\n"); + exit(1); + } + if (filter.flushed == 0) { + if (round == 0) + fprintf(stderr, "Nothing to flush.\n"); + fflush(stdout); + return 0; + } + round++; + if (flush_update() < 0) + exit(1); + } + } + if (filter.family != AF_PACKET) { if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) { perror_msg_and_die("Cannot send dump request"); @@ -727,7 +802,7 @@ static int ipaddr_modify(int cmd, int argc, char **argv) extern int do_ipaddr(int argc, char **argv) { - const char *commands[] = { "add", "delete", "list", "show", "lst", 0 }; + const char *commands[] = { "add", "delete", "list", "show", "lst", "flush", 0 }; unsigned short command_num = 2; if (*argv) { @@ -741,7 +816,9 @@ extern int do_ipaddr(int argc, char **argv) case 2: /* list */ case 3: /* show */ case 4: /* lst */ - return ipaddr_list(argc-1, argv+1); + return ipaddr_list_or_flush(argc-1, argv+1, 0); + case 5: /* flush */ + return ipaddr_list_or_flush(argc-1, argv+1, 1); } error_msg_and_die("Unknown command %s", *argv); } diff --git a/networking/libiproute/iplink.c b/networking/libiproute/iplink.c index ef4d6b9..3b2f4da 100644 --- a/networking/libiproute/iplink.c +++ b/networking/libiproute/iplink.c @@ -334,7 +334,7 @@ static int ipaddr_list_link(int argc, char **argv) { preferred_family = AF_PACKET; do_link = 1; - return ipaddr_list(argc, argv); + return ipaddr_list_or_flush(argc, argv, 0); } int do_iplink(int argc, char **argv) -- cgit v1.1