[BusyBox-cvs] busybox/networking/libiproute iproute.c,1.8,1.9

Glenn McGrath bug1 at busybox.net
Sat Feb 15 11:50:36 UTC 2003


Update of /var/cvs/busybox/networking/libiproute
In directory winder:/tmp/cvs-serv6050/networking/libiproute

Modified Files:
	iproute.c 
Log Message:
Patch from Bastian Blank
 - ip route flush
 - different usage for telnetd in inetd mode
 - changes for the default flags of the ip features
 - if no /usr requested, udhcpc should use the script also without /usr.


Index: iproute.c
===================================================================
RCS file: /var/cvs/busybox/networking/libiproute/iproute.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- iproute.c	16 Dec 2002 07:37:20 -0000	1.8
+++ iproute.c	15 Feb 2003 11:50:32 -0000	1.9
@@ -19,6 +19,8 @@
 
 #include <stdlib.h>
 #include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
 
 #include "rt_names.h"
 #include "utils.h"
@@ -33,6 +35,8 @@
 static struct
 {
 	int tb;
+	int flushed;
+	char *flushb;
 	int flushp;
 	int flushe;
 	struct rtnl_handle *rth;
@@ -51,6 +55,16 @@
 	inet_prefix msrc;
 } filter;
 
+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_route(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 {
 	FILE *fp = (FILE*)arg;
@@ -67,6 +81,8 @@
 			n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
 		return 0;
 	}
+	if (filter.flushb && n->nlmsg_type != RTM_NEWROUTE)
+		return 0;
 	len -= NLMSG_LENGTH(sizeof(*r));
 	if (len < 0) {
 		error_msg("wrong nlmsg len %d", len);
@@ -128,6 +144,30 @@
 	memset(tb, 0, sizeof(tb));
 	parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
 
+	if (filter.flushb &&
+	    r->rtm_family == AF_INET6 &&
+	    r->rtm_dst_len == 0 &&
+	    r->rtm_type == RTN_UNREACHABLE &&
+	    tb[RTA_PRIORITY] &&
+	    *(int*)RTA_DATA(tb[RTA_PRIORITY]) == -1)
+		return 0;
+
+	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_DELROUTE;
+		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_DELROUTE) {
 		fprintf(fp, "Deleted ");
 	}
@@ -393,6 +433,29 @@
 	return sendto(rth->fd, (void*)&req, sizeof(req), 0, (struct sockaddr*)&nladdr, sizeof(nladdr));
 }
 
+static int iproute_flush_cache(void)
+{
+#define ROUTE_FLUSH_PATH "/proc/sys/net/ipv4/route/flush"
+
+	int len;
+	int flush_fd = open (ROUTE_FLUSH_PATH, O_WRONLY);
+	char *buffer = "-1";
+
+	if (flush_fd < 0) {
+		fprintf (stderr, "Cannot open \"%s\"\n", ROUTE_FLUSH_PATH);
+		return -1;
+	}
+
+	len = strlen (buffer);
+
+	if ((write (flush_fd, (void *)buffer, len)) < len) {
+		fprintf (stderr, "Cannot flush routing cache\n");
+		return -1;
+	}
+	close(flush_fd);
+	return 0;
+}
+
 static void iproute_reset_filter(void)
 {
 	memset(&filter, 0, sizeof(filter));
@@ -400,7 +463,7 @@
 	filter.msrc.bitlen = -1;
 }
 
-static int iproute_list(int argc, char **argv)
+static int iproute_list_or_flush(int argc, char **argv, int flush)
 {
 	int do_ipv6 = preferred_family;
 	struct rtnl_handle rth;
@@ -410,6 +473,11 @@
 	iproute_reset_filter();
 	filter.tb = RT_TABLE_MAIN;
 
+	if (flush && argc <= 0) {
+		fprintf(stderr, "\"ip route flush\" requires arguments.\n");
+		return -1;
+	}
+
 	while (argc > 0) {
 		if (matches(*argv, "protocol") == 0) {
 			int prot = 0;
@@ -496,6 +564,46 @@
 		}
 	}
 
+	if (flush) {
+		int round = 0;
+		char flushb[4096-512];
+
+		if (filter.tb == -1) {
+			if (do_ipv6 != AF_INET6)
+				iproute_flush_cache();
+			if (do_ipv6 == AF_INET)
+				return 0;
+		}
+
+		filter.flushb = flushb;
+		filter.flushp = 0;
+		filter.flushe = sizeof(flushb);
+		filter.rth = &rth;
+
+		for (;;) {
+			if (rtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE) < 0) {
+				perror("Cannot send dump request");
+				return -1;
+			}
+			filter.flushed = 0;
+			if (rtnl_dump_filter(&rth, print_route, stdout, NULL, NULL) < 0) {
+				error_msg("Flush terminated\n");
+				return -1;
+			}
+			if (filter.flushed == 0) {
+				if (round == 0) {
+					if (filter.tb != -1 || do_ipv6 == AF_INET6)
+						fprintf(stderr, "Nothing to flush.\n");
+				}
+				fflush(stdout);
+				return 0;
+			}
+			round++;
+			if (flush_update() < 0)
+				exit(1);
+		}
+	}
+
 	if (filter.tb != -1) {
 		if (rtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE) < 0) {
 			perror_msg_and_die("Cannot send dump request");
@@ -686,7 +794,7 @@
 int do_iproute(int argc, char **argv)
 {
 	const char *ip_route_commands[] = { "add", "append", "change", "chg",
-		"delete", "get", "list", "show", "prepend", "replace", "test", 0 };
+		"delete", "get", "list", "show", "prepend", "replace", "test", "flush", 0 };
 	unsigned short command_num = 6;
 	unsigned int flags = 0;
 	int cmd = RTM_NEWROUTE;
@@ -712,13 +820,15 @@
 			return iproute_get(argc-1, argv+1);
 		case 6: /* list */
 		case 7: /* show */
-			return iproute_list(argc-1, argv+1);
+			return iproute_list_or_flush(argc-1, argv+1, 0);
 		case 8: /* prepend */
 			flags = NLM_F_CREATE;
 		case 9: /* replace */
 			flags = NLM_F_CREATE|NLM_F_REPLACE;
 		case 10: /* test */
 			flags = NLM_F_EXCL;
+		case 11: /* flush */
+			return iproute_list_or_flush(argc-1, argv+1, 1);
 		default:
 			error_msg_and_die("Unknown command %s", *argv);
 	}




More information about the busybox-cvs mailing list