aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/usage.h32
-rw-r--r--networking/Config.in11
-rw-r--r--networking/ifupdown.c69
-rw-r--r--networking/libiproute/ipaddress.c83
-rw-r--r--networking/libiproute/iplink.c2
5 files changed, 170 insertions, 27 deletions
diff --git a/include/usage.h b/include/usage.h
index da4fad886..0a0948bdd 100644
--- a/include/usage.h
+++ b/include/usage.h
@@ -878,28 +878,28 @@
878#define ifup_full_usage \ 878#define ifup_full_usage \
879 "Usage: ifup <options> <ifaces...>\n\n" \ 879 "Usage: ifup <options> <ifaces...>\n\n" \
880 "Options:\n" \ 880 "Options:\n" \
881 "\t-h, --help\t\tthis help\n" \ 881 "\t-h\tthis help\n" \
882 "\t-a, --all\t\tde/configure all interfaces automatically\n" \ 882 "\t-a\tde/configure all interfaces automatically\n" \
883 "\t-i, --interfaces FILE\tuse FILE for interface definitions\n" \ 883 "\t-i FILE\tuse FILE for interface definitions\n" \
884 "\t-n, --no-act\t\tprint out what would happen, but don't do it\n" \ 884 "\t-n\tprint out what would happen, but don't do it\n" \
885 "\t\t\t\t(note that this option doesn't disable mappings)\n" \ 885 "\t\t\t(note that this option doesn't disable mappings)\n" \
886 "\t-v, --verbose\t\tprint out what would happen before doing it\n" \ 886 "\t-v\tprint out what would happen before doing it\n" \
887 "\t--no-mappings\t\tdon't run any mappings\n" \ 887 "\t-m\tdon't run any mappings\n" \
888 "\t--force\t\t\tforce de/configuration\n" 888 "\t-f\tforce de/configuration\n"
889 889
890#define ifdown_trivial_usage \ 890#define ifdown_trivial_usage \
891 "<-ahinv> <ifaces...>" 891 "<-ahinv> <ifaces...>"
892#define ifdown_full_usage \ 892#define ifdown_full_usage \
893 "Usage: ifdown <options> <ifaces...>\n\n" \ 893 "Usage: ifdown <options> <ifaces...>\n\n" \
894 "Options:\n" \ 894 "Options:\n" \
895 "\t-h, --help\t\tthis help\n" \ 895 "\t-h\tthis help\n" \
896 "\t-a, --all\t\tde/configure all interfaces automatically\n" \ 896 "\t-a\tde/configure all interfaces automatically\n" \
897 "\t-i, --interfaces FILE\tuse FILE for interface definitions\n" \ 897 "\t-i FILE\tuse FILE for interface definitions\n" \
898 "\t-n, --no-act\t\tprint out what would happen, but don't do it\n" \ 898 "\t-n\tprint out what would happen, but don't do it\n" \
899 "\t\t\t\t(note that this option doesn't disable mappings)\n" \ 899 "\t\t(note that this option doesn't disable mappings)\n" \
900 "\t-v, --verbose\t\tprint out what would happen before doing it\n" \ 900 "\t-v\tprint out what would happen before doing it\n" \
901 "\t--no-mappings\t\tdon't run any mappings\n" \ 901 "\t-m\tdon't run any mappings\n" \
902 "\t--force\t\t\tforce de/configuration\n" 902 "\t-f\tforce de/configuration\n"
903 903
904#define init_trivial_usage \ 904#define init_trivial_usage \
905 "" 905 ""
diff --git a/networking/Config.in b/networking/Config.in
index 42dd06e50..bc1178007 100644
--- a/networking/Config.in
+++ b/networking/Config.in
@@ -96,6 +96,13 @@ config CONFIG_IFUPDOWN
96 help 96 help
97 Please submit a patch to add help text for this item. 97 Please submit a patch to add help text for this item.
98 98
99config CONFIG_FEATURE_IFUPDOWN_IP
100 bool " Use ip applet"
101 default n
102 depends on CONFIG_IFUPDOWN && CONFIG_IP && CONFIG_FEATURE_IP_ADDRESS && CONFIG_FEATURE_IP_LINK && CONFIG_FEATURE_IP_ROUTE
103 help
104 Please submit a patch to add help text for this item.
105
99config CONFIG_FEATURE_IFUPDOWN_IPV4 106config CONFIG_FEATURE_IFUPDOWN_IPV4
100 bool " Enable support for IPv4" 107 bool " Enable support for IPv4"
101 default y 108 default y
@@ -104,14 +111,14 @@ config CONFIG_FEATURE_IFUPDOWN_IPV4
104 Please submit a patch to add help text for this item. 111 Please submit a patch to add help text for this item.
105 112
106config CONFIG_FEATURE_IFUPDOWN_IPV6 113config CONFIG_FEATURE_IFUPDOWN_IPV6
107 bool " Enable support for IPv6 (requires ip command)" 114 bool " Enable support for IPv6"
108 default n 115 default n
109 depends on CONFIG_IFUPDOWN 116 depends on CONFIG_IFUPDOWN
110 help 117 help
111 Please submit a patch to add help text for this item. 118 Please submit a patch to add help text for this item.
112 119
113config CONFIG_FEATURE_IFUPDOWN_IPX 120config CONFIG_FEATURE_IFUPDOWN_IPX
114 bool " Enable support for IPX (requires ipx_interface command)" 121 bool " Enable support for IPX"
115 default n 122 default n
116 depends on CONFIG_IFUPDOWN 123 depends on CONFIG_IFUPDOWN
117 help 124 help
diff --git a/networking/ifupdown.c b/networking/ifupdown.c
index 37185327b..665e527cc 100644
--- a/networking/ifupdown.c
+++ b/networking/ifupdown.c
@@ -307,22 +307,40 @@ address_family_t addr_ipx = {
307#ifdef CONFIG_FEATURE_IFUPDOWN_IPV6 307#ifdef CONFIG_FEATURE_IFUPDOWN_IPV6
308static int loopback_up6(interface_defn_t *ifd, execfn *exec) 308static int loopback_up6(interface_defn_t *ifd, execfn *exec)
309{ 309{
310 if (!execute("ifconfig %iface% add ::1", ifd, exec)) { 310#ifdef CONFIG_FEATURE_IFUPDOWN_IP
311 if (!execute("ip link set %iface% up", ifd, exec))
311 return(0); 312 return(0);
312 } 313 if (!execute("ip addr add ::1 dev %iface%", ifd, exec))
314 return(0);
315#else
316 if (!execute("ifconfig %iface% add ::1", ifd, exec))
317 return(0);
318#endif
313 return(1); 319 return(1);
314} 320}
315 321
316static int loopback_down6(interface_defn_t *ifd, execfn *exec) 322static int loopback_down6(interface_defn_t *ifd, execfn *exec)
317{ 323{
318 if (!execute("ifconfig %iface% del ::1", ifd, exec)) { 324#ifdef CONFIG_FEATURE_IFUPDOWN_IP
325 if (!execute("ip link set %iface% down", ifd, exec))
319 return(0); 326 return(0);
320 } 327#else
328 if (!execute("ifconfig %iface% del ::1", ifd, exec))
329 return(0);
330#endif
321 return(1); 331 return(1);
322} 332}
323 333
324static int static_up6(interface_defn_t *ifd, execfn *exec) 334static int static_up6(interface_defn_t *ifd, execfn *exec)
325{ 335{
336#ifdef CONFIG_FEATURE_IFUPDOWN_IP
337 if (!execute("ip link set %iface% up", ifd, exec))
338 return(0);
339 if (!execute("ip addr add %address%/%netmask% dev %iface%", ifd, exec))
340 return(0);
341 if (!execute("[[ ip route add ::/0 via %gateway% ]]", ifd, exec))
342 return(0);
343#else
326 if (!execute("ifconfig %iface% [[media %media%]] [[hw %hwaddress%]] [[mtu %mtu%]] up", ifd, exec)) { 344 if (!execute("ifconfig %iface% [[media %media%]] [[hw %hwaddress%]] [[mtu %mtu%]] up", ifd, exec)) {
327 return(0); 345 return(0);
328 } 346 }
@@ -332,17 +350,24 @@ static int static_up6(interface_defn_t *ifd, execfn *exec)
332 if (!execute("[[ route -A inet6 add ::/0 gw %gateway% ]]", ifd, exec)) { 350 if (!execute("[[ route -A inet6 add ::/0 gw %gateway% ]]", ifd, exec)) {
333 return(0); 351 return(0);
334 } 352 }
353#endif
335 return(1); 354 return(1);
336} 355}
337 356
338static int static_down6(interface_defn_t *ifd, execfn *exec) 357static int static_down6(interface_defn_t *ifd, execfn *exec)
339{ 358{
359#ifdef CONFIG_FEATURE_IFUPDOWN_IP
360 if (!execute("ip link set %iface% down", ifd, exec))
361 return(0);
362#else
340 if (!execute("ifconfig %iface% down", ifd, exec)) { 363 if (!execute("ifconfig %iface% down", ifd, exec)) {
341 return(0); 364 return(0);
342 } 365 }
366#endif
343 return(1); 367 return(1);
344} 368}
345 369
370#ifdef CONFIG_FEATURE_IFUPDOWN_IP
346static int v4tunnel_up(interface_defn_t *ifd, execfn *exec) 371static int v4tunnel_up(interface_defn_t *ifd, execfn *exec)
347{ 372{
348 if (!execute("ip tunnel add %iface% mode sit remote %endpoint% [[local %local%]] [[ttl %ttl%]]", ifd, exec)) { 373 if (!execute("ip tunnel add %iface% mode sit remote %endpoint% [[local %local%]] [[ttl %ttl%]]", ifd, exec)) {
@@ -367,9 +392,12 @@ static int v4tunnel_down(interface_defn_t * ifd, execfn * exec)
367 } 392 }
368 return(1); 393 return(1);
369} 394}
395#endif
370 396
371static method_t methods6[] = { 397static method_t methods6[] = {
398#ifdef CONFIG_FEATURE_IFUPDOWN_IP
372 { "v4tunnel", v4tunnel_up, v4tunnel_down, }, 399 { "v4tunnel", v4tunnel_up, v4tunnel_down, },
400#endif
373 { "static", static_up6, static_down6, }, 401 { "static", static_up6, static_down6, },
374 { "loopback", loopback_up6, loopback_down6, }, 402 { "loopback", loopback_up6, loopback_down6, },
375}; 403};
@@ -384,22 +412,44 @@ address_family_t addr_inet6 = {
384#ifdef CONFIG_FEATURE_IFUPDOWN_IPV4 412#ifdef CONFIG_FEATURE_IFUPDOWN_IPV4
385static int loopback_up(interface_defn_t *ifd, execfn *exec) 413static int loopback_up(interface_defn_t *ifd, execfn *exec)
386{ 414{
415#ifdef CONFIG_FEATURE_IFUPDOWN_IP
416 if (!execute("ip link set %iface% up", ifd, exec))
417 return(0);
418 if (!execute("ip addr add 127.0.0.1 dev %iface%", ifd, exec))
419 return(0);
420#else
387 if (!execute("ifconfig %iface% 127.0.0.1 up", ifd, exec)) { 421 if (!execute("ifconfig %iface% 127.0.0.1 up", ifd, exec)) {
388 return(0); 422 return(0);
389 } 423 }
424#endif
390 return(1); 425 return(1);
391} 426}
392 427
393static int loopback_down(interface_defn_t *ifd, execfn *exec) 428static int loopback_down(interface_defn_t *ifd, execfn *exec)
394{ 429{
430#ifdef CONFIG_FEATURE_IFUPDOWN_IP
431 if (!execute("ip -f inet addr flush dev %iface%", ifd, exec))
432 return(0);
433 if (!execute("ip link set %iface% down", ifd, exec))
434 return(0);
435#else
395 if (!execute("ifconfig %iface% 127.0.0.1 down", ifd, exec)) { 436 if (!execute("ifconfig %iface% 127.0.0.1 down", ifd, exec)) {
396 return(0); 437 return(0);
397 } 438 }
439#endif
398 return(1); 440 return(1);
399} 441}
400 442
401static int static_up(interface_defn_t *ifd, execfn *exec) 443static int static_up(interface_defn_t *ifd, execfn *exec)
402{ 444{
445#ifdef CONFIG_FEATURE_IFUPDOWN_IP
446 if (!execute("ip link set %iface% up", ifd, exec))
447 return(0);
448 if (!execute("ip addr add %address%/%netmask% dev %iface%", ifd, exec))
449 return(0);
450 if (!execute("[[ ip route add default via %gateway% dev %iface% ]]", ifd, exec))
451 return(0);
452#else
403 if (!execute("ifconfig %iface% %address% netmask %netmask% [[broadcast %broadcast%]] [[pointopoint %pointopoint%]] [[media %media%]] [[mtu %mtu%]] [[hw %hwaddress%]] up", 453 if (!execute("ifconfig %iface% %address% netmask %netmask% [[broadcast %broadcast%]] [[pointopoint %pointopoint%]] [[media %media%]] [[mtu %mtu%]] [[hw %hwaddress%]] up",
404 ifd, exec)) { 454 ifd, exec)) {
405 return(0); 455 return(0);
@@ -407,17 +457,27 @@ static int static_up(interface_defn_t *ifd, execfn *exec)
407 if (!execute("[[ route add default gw %gateway% %iface% ]]", ifd, exec)) { 457 if (!execute("[[ route add default gw %gateway% %iface% ]]", ifd, exec)) {
408 return(0); 458 return(0);
409 } 459 }
460#endif
410 return(1); 461 return(1);
411} 462}
412 463
413static int static_down(interface_defn_t *ifd, execfn *exec) 464static int static_down(interface_defn_t *ifd, execfn *exec)
414{ 465{
466#ifdef CONFIG_FEATURE_IFUPDOWN_IP
467 if (!execute("[[ ip route del default via %gateway% dev %iface% ]]", ifd, exec))
468 return(0);
469 if (!execute("ip -f inet addr flush dev %iface%", ifd, exec))
470 return(0);
471 if (!execute("ip link set %iface% down", ifd, exec))
472 return(0);
473#else
415 if (!execute("[[ route del default gw %gateway% %iface% ]]", ifd, exec)) { 474 if (!execute("[[ route del default gw %gateway% %iface% ]]", ifd, exec)) {
416 return(0); 475 return(0);
417 } 476 }
418 if (!execute("ifconfig %iface% down", ifd, exec)) { 477 if (!execute("ifconfig %iface% down", ifd, exec)) {
419 return(0); 478 return(0);
420 } 479 }
480#endif
421 return(1); 481 return(1);
422} 482}
423 483
@@ -936,7 +996,6 @@ static int doit(char *str)
936 case 0: /* child */ 996 case 0: /* child */
937 execle("/bin/sh", "/bin/sh", "-c", str, NULL, environ); 997 execle("/bin/sh", "/bin/sh", "-c", str, NULL, environ);
938 exit(127); 998 exit(127);
939 default: /* parent */
940 } 999 }
941 waitpid(child, &status, 0); 1000 waitpid(child, &status, 0);
942 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { 1001 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
diff --git a/networking/libiproute/ipaddress.c b/networking/libiproute/ipaddress.c
index 2821f2e8d..77368fb3c 100644
--- a/networking/libiproute/ipaddress.c
+++ b/networking/libiproute/ipaddress.c
@@ -42,6 +42,10 @@ static struct
42 int flags, flagmask; 42 int flags, flagmask;
43 int up; 43 int up;
44 char *label; 44 char *label;
45 int flushed;
46 char *flushb;
47 int flushp;
48 int flushe;
45 struct rtnl_handle *rth; 49 struct rtnl_handle *rth;
46} filter; 50} filter;
47 51
@@ -191,6 +195,16 @@ static int print_linkinfo(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg
191 return 0; 195 return 0;
192} 196}
193 197
198static int flush_update(void)
199{
200 if (rtnl_send(filter.rth, filter.flushb, filter.flushp) < 0) {
201 perror("Failed to send flush request\n");
202 return -1;
203 }
204 filter.flushp = 0;
205 return 0;
206}
207
194static int print_addrinfo(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) 208static int print_addrinfo(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
195{ 209{
196 FILE *fp = (FILE*)arg; 210 FILE *fp = (FILE*)arg;
@@ -208,6 +222,9 @@ static int print_addrinfo(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg
208 return -1; 222 return -1;
209 } 223 }
210 224
225 if (filter.flushb && n->nlmsg_type != RTM_NEWADDR)
226 return 0;
227
211 memset(rta_tb, 0, sizeof(rta_tb)); 228 memset(rta_tb, 0, sizeof(rta_tb));
212 parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(ifa), n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa))); 229 parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(ifa), n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa)));
213 230
@@ -242,6 +259,22 @@ static int print_addrinfo(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg
242 } 259 }
243 } 260 }
244 261
262 if (filter.flushb) {
263 struct nlmsghdr *fn;
264 if (NLMSG_ALIGN(filter.flushp) + n->nlmsg_len > filter.flushe) {
265 if (flush_update())
266 return -1;
267 }
268 fn = (struct nlmsghdr*)(filter.flushb + NLMSG_ALIGN(filter.flushp));
269 memcpy(fn, n, n->nlmsg_len);
270 fn->nlmsg_type = RTM_DELADDR;
271 fn->nlmsg_flags = NLM_F_REQUEST;
272 fn->nlmsg_seq = ++filter.rth->seq;
273 filter.flushp = (((char*)fn) + n->nlmsg_len) - filter.flushb;
274 filter.flushed++;
275 return 0;
276 }
277
245 if (n->nlmsg_type == RTM_DELADDR) 278 if (n->nlmsg_type == RTM_DELADDR)
246 fprintf(fp, "Deleted "); 279 fprintf(fp, "Deleted ");
247 280
@@ -382,7 +415,7 @@ static void ipaddr_reset_filter(int _oneline)
382 filter.oneline = _oneline; 415 filter.oneline = _oneline;
383} 416}
384 417
385extern int ipaddr_list(int argc, char **argv) 418extern int ipaddr_list_or_flush(int argc, char **argv, int flush)
386{ 419{
387 const char *option[] = { "to", "scope", "up", "label", "dev", 0 }; 420 const char *option[] = { "to", "scope", "up", "label", "dev", 0 };
388 struct nlmsg_list *linfo = NULL; 421 struct nlmsg_list *linfo = NULL;
@@ -398,6 +431,17 @@ extern int ipaddr_list(int argc, char **argv)
398 if (filter.family == AF_UNSPEC) 431 if (filter.family == AF_UNSPEC)
399 filter.family = preferred_family; 432 filter.family = preferred_family;
400 433
434 if (flush) {
435 if (argc <= 0) {
436 fprintf(stderr, "Flush requires arguments.\n");
437 return -1;
438 }
439 if (filter.family == AF_PACKET) {
440 fprintf(stderr, "Cannot flush link addresses.\n");
441 return -1;
442 }
443 }
444
401 while (argc > 0) { 445 while (argc > 0) {
402 const unsigned short option_num = compare_string_array(option, *argv); 446 const unsigned short option_num = compare_string_array(option, *argv);
403 switch (option_num) { 447 switch (option_num) {
@@ -461,6 +505,37 @@ extern int ipaddr_list(int argc, char **argv)
461 } 505 }
462 } 506 }
463 507
508 if (flush) {
509 int round = 0;
510 char flushb[4096-512];
511
512 filter.flushb = flushb;
513 filter.flushp = 0;
514 filter.flushe = sizeof(flushb);
515 filter.rth = &rth;
516
517 for (;;) {
518 if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) {
519 perror("Cannot send dump request");
520 exit(1);
521 }
522 filter.flushed = 0;
523 if (rtnl_dump_filter(&rth, print_addrinfo, stdout, NULL, NULL) < 0) {
524 fprintf(stderr, "Flush terminated\n");
525 exit(1);
526 }
527 if (filter.flushed == 0) {
528 if (round == 0)
529 fprintf(stderr, "Nothing to flush.\n");
530 fflush(stdout);
531 return 0;
532 }
533 round++;
534 if (flush_update() < 0)
535 exit(1);
536 }
537 }
538
464 if (filter.family != AF_PACKET) { 539 if (filter.family != AF_PACKET) {
465 if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) { 540 if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) {
466 perror_msg_and_die("Cannot send dump request"); 541 perror_msg_and_die("Cannot send dump request");
@@ -727,7 +802,7 @@ static int ipaddr_modify(int cmd, int argc, char **argv)
727 802
728extern int do_ipaddr(int argc, char **argv) 803extern int do_ipaddr(int argc, char **argv)
729{ 804{
730 const char *commands[] = { "add", "delete", "list", "show", "lst", 0 }; 805 const char *commands[] = { "add", "delete", "list", "show", "lst", "flush", 0 };
731 unsigned short command_num = 2; 806 unsigned short command_num = 2;
732 807
733 if (*argv) { 808 if (*argv) {
@@ -741,7 +816,9 @@ extern int do_ipaddr(int argc, char **argv)
741 case 2: /* list */ 816 case 2: /* list */
742 case 3: /* show */ 817 case 3: /* show */
743 case 4: /* lst */ 818 case 4: /* lst */
744 return ipaddr_list(argc-1, argv+1); 819 return ipaddr_list_or_flush(argc-1, argv+1, 0);
820 case 5: /* flush */
821 return ipaddr_list_or_flush(argc-1, argv+1, 1);
745 } 822 }
746 error_msg_and_die("Unknown command %s", *argv); 823 error_msg_and_die("Unknown command %s", *argv);
747} 824}
diff --git a/networking/libiproute/iplink.c b/networking/libiproute/iplink.c
index ef4d6b9a5..3b2f4dac1 100644
--- a/networking/libiproute/iplink.c
+++ b/networking/libiproute/iplink.c
@@ -334,7 +334,7 @@ static int ipaddr_list_link(int argc, char **argv)
334{ 334{
335 preferred_family = AF_PACKET; 335 preferred_family = AF_PACKET;
336 do_link = 1; 336 do_link = 1;
337 return ipaddr_list(argc, argv); 337 return ipaddr_list_or_flush(argc, argv, 0);
338} 338}
339 339
340int do_iplink(int argc, char **argv) 340int do_iplink(int argc, char **argv)