aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Luebbe <jluebbe@debian.org>2018-02-14 14:05:27 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2018-02-20 19:43:32 +0100
commite789c3bea18181723c4ae7d761ec30926d182cfb (patch)
treea1d5abfc03412982db4d538c0ad424a46c91f4ac
parent79cda9522ad390f1bdb7ba1025b1c81bbd1613e6 (diff)
downloadbusybox-w32-e789c3bea18181723c4ae7d761ec30926d182cfb.tar.gz
busybox-w32-e789c3bea18181723c4ae7d761ec30926d182cfb.tar.bz2
busybox-w32-e789c3bea18181723c4ae7d761ec30926d182cfb.zip
iplink: implement support for selecting a master interface
Attaching an interface to a VRF is done by setting the interface's master. Besides VRF, this can also be used for bridges. function old new delta set_master - 142 +142 do_iplink 1262 1357 +95 packed_usage 32546 32539 -7 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 1/1 up/down: 237/-7) Total: 230 bytes Signed-off-by: Jan Luebbe <jluebbe@debian.org> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--networking/ip.c3
-rw-r--r--networking/libiproute/iplink.c38
-rw-r--r--networking/tcpudp.c2
3 files changed, 41 insertions, 2 deletions
diff --git a/networking/ip.c b/networking/ip.c
index 665f9bcce..accf90759 100644
--- a/networking/ip.c
+++ b/networking/ip.c
@@ -156,7 +156,8 @@
156//--------------123456789.123456789.123456789.123456789.123456789.123456789.123456789.123....79 156//--------------123456789.123456789.123456789.123456789.123456789.123456789.123456789.123....79
157//usage:#define iplink_trivial_usage 157//usage:#define iplink_trivial_usage
158//usage: /*Usage:iplink*/"set IFACE [up|down] [arp on|off] [multicast on|off]\n" 158//usage: /*Usage:iplink*/"set IFACE [up|down] [arp on|off] [multicast on|off]\n"
159//usage: " [promisc on|off] [mtu NUM] [name NAME] [qlen NUM] [address MAC]" 159//usage: " [promisc on|off] [mtu NUM] [name NAME] [qlen NUM] [address MAC]\n"
160//usage: " [master IFACE | nomaster]\n"
160// * short help shows only "set" command, long help continues (with just one "\n") 161// * short help shows only "set" command, long help continues (with just one "\n")
161// * and shows all other commands: 162// * and shows all other commands:
162//usage:#define iplink_full_usage "\n" 163//usage:#define iplink_full_usage "\n"
diff --git a/networking/libiproute/iplink.c b/networking/libiproute/iplink.c
index 312283318..2aa8b683b 100644
--- a/networking/libiproute/iplink.c
+++ b/networking/libiproute/iplink.c
@@ -128,6 +128,31 @@ static void set_mtu(char *dev, int mtu)
128} 128}
129 129
130/* Exits on error */ 130/* Exits on error */
131static void set_master(char *dev, int master)
132{
133 struct rtnl_handle rth;
134 struct {
135 struct nlmsghdr n;
136 struct ifinfomsg i;
137 char buf[1024];
138 } req;
139
140 memset(&req, 0, sizeof(req));
141
142 req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
143 req.n.nlmsg_flags = NLM_F_REQUEST;
144 req.n.nlmsg_type = RTM_NEWLINK;
145 req.i.ifi_family = preferred_family;
146
147 xrtnl_open(&rth);
148 req.i.ifi_index = xll_name_to_index(dev);
149 //printf("master %i for %i\n", master, req.i.ifi_index);
150 addattr_l(&req.n, sizeof(req), IFLA_MASTER, &master, 4);
151 if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0)
152 xfunc_die();
153}
154
155/* Exits on error */
131static int get_address(char *dev, int *htype) 156static int get_address(char *dev, int *htype)
132{ 157{
133 struct ifreq ifr; 158 struct ifreq ifr;
@@ -200,6 +225,7 @@ static int do_set(char **argv)
200 uint32_t flags = 0; 225 uint32_t flags = 0;
201 int qlen = -1; 226 int qlen = -1;
202 int mtu = -1; 227 int mtu = -1;
228 int master = -1;
203 char *newaddr = NULL; 229 char *newaddr = NULL;
204 char *newbrd = NULL; 230 char *newbrd = NULL;
205 struct ifreq ifr0, ifr1; 231 struct ifreq ifr0, ifr1;
@@ -209,9 +235,11 @@ static int do_set(char **argv)
209 static const char keywords[] ALIGN1 = 235 static const char keywords[] ALIGN1 =
210 "up\0""down\0""name\0""mtu\0""qlen\0""multicast\0" 236 "up\0""down\0""name\0""mtu\0""qlen\0""multicast\0"
211 "arp\0""promisc\0""address\0" 237 "arp\0""promisc\0""address\0"
238 "master\0""nomaster\0"
212 "dev\0" /* must be last */; 239 "dev\0" /* must be last */;
213 enum { ARG_up = 0, ARG_down, ARG_name, ARG_mtu, ARG_qlen, ARG_multicast, 240 enum { ARG_up = 0, ARG_down, ARG_name, ARG_mtu, ARG_qlen, ARG_multicast,
214 ARG_arp, ARG_promisc, ARG_addr, 241 ARG_arp, ARG_promisc, ARG_addr,
242 ARG_master, ARG_nomaster,
215 ARG_dev }; 243 ARG_dev };
216 enum { PARM_on = 0, PARM_off }; 244 enum { PARM_on = 0, PARM_off };
217 smalluint key; 245 smalluint key;
@@ -243,6 +271,11 @@ static int do_set(char **argv)
243 } else if (key == ARG_addr) { 271 } else if (key == ARG_addr) {
244 NEXT_ARG(); 272 NEXT_ARG();
245 newaddr = *argv; 273 newaddr = *argv;
274 } else if (key == ARG_master) {
275 NEXT_ARG();
276 master = xll_name_to_index(*argv);
277 } else if (key == ARG_nomaster) {
278 master = 0;
246 } else if (key >= ARG_dev) { 279 } else if (key >= ARG_dev) {
247 /* ^^^^^^ ">=" here results in "dev IFACE" treated as default */ 280 /* ^^^^^^ ">=" here results in "dev IFACE" treated as default */
248 if (key == ARG_dev) { 281 if (key == ARG_dev) {
@@ -427,6 +460,9 @@ static int do_set(char **argv)
427 if (mtu != -1) { 460 if (mtu != -1) {
428 set_mtu(dev, mtu); 461 set_mtu(dev, mtu);
429 } 462 }
463 if (master != -1) {
464 set_master(dev, master);
465 }
430 if (mask) 466 if (mask)
431 do_chflags(dev, flags, mask); 467 do_chflags(dev, flags, mask);
432 return 0; 468 return 0;
@@ -673,6 +709,8 @@ int FAST_FUNC do_iplink(char **argv)
673{ 709{
674 static const char keywords[] ALIGN1 = 710 static const char keywords[] ALIGN1 =
675 "add\0""delete\0""set\0""show\0""lst\0""list\0"; 711 "add\0""delete\0""set\0""show\0""lst\0""list\0";
712
713 xfunc_error_retval = 2; //TODO: move up to "ip"? Is it the common rule for all "ip" tools?
676 if (*argv) { 714 if (*argv) {
677 int key = index_in_substrings(keywords, *argv); 715 int key = index_in_substrings(keywords, *argv);
678 if (key < 0) /* invalid argument */ 716 if (key < 0) /* invalid argument */
diff --git a/networking/tcpudp.c b/networking/tcpudp.c
index d4c69e0f7..2feb63a01 100644
--- a/networking/tcpudp.c
+++ b/networking/tcpudp.c
@@ -318,7 +318,7 @@ int tcpudpsvd_main(int argc UNUSED_PARAM, char **argv)
318 sslser = user; 318 sslser = user;
319 client = 0; 319 client = 0;
320 if ((getuid() == 0) && !(opts & OPT_u)) { 320 if ((getuid() == 0) && !(opts & OPT_u)) {
321 xfunc_exitcode = 100; 321 xfunc_error_retval = 100;
322 bb_error_msg_and_die(bb_msg_you_must_be_root); 322 bb_error_msg_and_die(bb_msg_you_must_be_root);
323 } 323 }
324 if (opts & OPT_u) 324 if (opts & OPT_u)