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>
This commit is contained in:
parent
79cda9522a
commit
e789c3bea1
@ -156,7 +156,8 @@
|
||||
//--------------123456789.123456789.123456789.123456789.123456789.123456789.123456789.123....79
|
||||
//usage:#define iplink_trivial_usage
|
||||
//usage: /*Usage:iplink*/"set IFACE [up|down] [arp on|off] [multicast on|off]\n"
|
||||
//usage: " [promisc on|off] [mtu NUM] [name NAME] [qlen NUM] [address MAC]"
|
||||
//usage: " [promisc on|off] [mtu NUM] [name NAME] [qlen NUM] [address MAC]\n"
|
||||
//usage: " [master IFACE | nomaster]\n"
|
||||
// * short help shows only "set" command, long help continues (with just one "\n")
|
||||
// * and shows all other commands:
|
||||
//usage:#define iplink_full_usage "\n"
|
||||
|
@ -127,6 +127,31 @@ static void set_mtu(char *dev, int mtu)
|
||||
close(s);
|
||||
}
|
||||
|
||||
/* Exits on error */
|
||||
static void set_master(char *dev, int master)
|
||||
{
|
||||
struct rtnl_handle rth;
|
||||
struct {
|
||||
struct nlmsghdr n;
|
||||
struct ifinfomsg i;
|
||||
char buf[1024];
|
||||
} req;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
|
||||
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
|
||||
req.n.nlmsg_flags = NLM_F_REQUEST;
|
||||
req.n.nlmsg_type = RTM_NEWLINK;
|
||||
req.i.ifi_family = preferred_family;
|
||||
|
||||
xrtnl_open(&rth);
|
||||
req.i.ifi_index = xll_name_to_index(dev);
|
||||
//printf("master %i for %i\n", master, req.i.ifi_index);
|
||||
addattr_l(&req.n, sizeof(req), IFLA_MASTER, &master, 4);
|
||||
if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0)
|
||||
xfunc_die();
|
||||
}
|
||||
|
||||
/* Exits on error */
|
||||
static int get_address(char *dev, int *htype)
|
||||
{
|
||||
@ -200,6 +225,7 @@ static int do_set(char **argv)
|
||||
uint32_t flags = 0;
|
||||
int qlen = -1;
|
||||
int mtu = -1;
|
||||
int master = -1;
|
||||
char *newaddr = NULL;
|
||||
char *newbrd = NULL;
|
||||
struct ifreq ifr0, ifr1;
|
||||
@ -209,9 +235,11 @@ static int do_set(char **argv)
|
||||
static const char keywords[] ALIGN1 =
|
||||
"up\0""down\0""name\0""mtu\0""qlen\0""multicast\0"
|
||||
"arp\0""promisc\0""address\0"
|
||||
"master\0""nomaster\0"
|
||||
"dev\0" /* must be last */;
|
||||
enum { ARG_up = 0, ARG_down, ARG_name, ARG_mtu, ARG_qlen, ARG_multicast,
|
||||
ARG_arp, ARG_promisc, ARG_addr,
|
||||
ARG_master, ARG_nomaster,
|
||||
ARG_dev };
|
||||
enum { PARM_on = 0, PARM_off };
|
||||
smalluint key;
|
||||
@ -243,6 +271,11 @@ static int do_set(char **argv)
|
||||
} else if (key == ARG_addr) {
|
||||
NEXT_ARG();
|
||||
newaddr = *argv;
|
||||
} else if (key == ARG_master) {
|
||||
NEXT_ARG();
|
||||
master = xll_name_to_index(*argv);
|
||||
} else if (key == ARG_nomaster) {
|
||||
master = 0;
|
||||
} else if (key >= ARG_dev) {
|
||||
/* ^^^^^^ ">=" here results in "dev IFACE" treated as default */
|
||||
if (key == ARG_dev) {
|
||||
@ -427,6 +460,9 @@ static int do_set(char **argv)
|
||||
if (mtu != -1) {
|
||||
set_mtu(dev, mtu);
|
||||
}
|
||||
if (master != -1) {
|
||||
set_master(dev, master);
|
||||
}
|
||||
if (mask)
|
||||
do_chflags(dev, flags, mask);
|
||||
return 0;
|
||||
@ -673,6 +709,8 @@ int FAST_FUNC do_iplink(char **argv)
|
||||
{
|
||||
static const char keywords[] ALIGN1 =
|
||||
"add\0""delete\0""set\0""show\0""lst\0""list\0";
|
||||
|
||||
xfunc_error_retval = 2; //TODO: move up to "ip"? Is it the common rule for all "ip" tools?
|
||||
if (*argv) {
|
||||
int key = index_in_substrings(keywords, *argv);
|
||||
if (key < 0) /* invalid argument */
|
||||
|
@ -318,7 +318,7 @@ int tcpudpsvd_main(int argc UNUSED_PARAM, char **argv)
|
||||
sslser = user;
|
||||
client = 0;
|
||||
if ((getuid() == 0) && !(opts & OPT_u)) {
|
||||
xfunc_exitcode = 100;
|
||||
xfunc_error_retval = 100;
|
||||
bb_error_msg_and_die(bb_msg_you_must_be_root);
|
||||
}
|
||||
if (opts & OPT_u)
|
||||
|
Loading…
Reference in New Issue
Block a user