iplink.c revision 7b8179c780a1abd547e5002c4e6fba898c6d72bb
1aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger/*
2aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * iplink.c		"ip link".
3aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *
4aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *		This program is free software; you can redistribute it and/or
5aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *		modify it under the terms of the GNU General Public License
6aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *		as published by the Free Software Foundation; either version
7aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *		2 of the License, or (at your option) any later version.
8aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *
9aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * Authors:	Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
10aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *
11aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger */
12aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
13aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <stdio.h>
14aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <stdlib.h>
15aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <unistd.h>
16aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <syslog.h>
17aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <fcntl.h>
181d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy#include <dlfcn.h>
19aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <errno.h>
20aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <sys/socket.h>
21aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <linux/if.h>
22aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <linux/if_packet.h>
23aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <linux/if_ether.h>
24aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <linux/sockios.h>
25aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <netinet/in.h>
26aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <arpa/inet.h>
27aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <string.h>
28aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <sys/ioctl.h>
29aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <linux/sockios.h>
30aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
31aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "rt_names.h"
32aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "utils.h"
33aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "ip_common.h"
34aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
351d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy#define IPLINK_IOCTL_COMPAT	1
365e3bb534ae179be141a92eb1a4e2eb48094193b7Andreas Henriksson#ifndef LIBDIR
375e3bb534ae179be141a92eb1a4e2eb48094193b7Andreas Henriksson#define LIBDIR "/usr/lib/"
38b514b3587ee56552fcc87a066c955a7ff4f55d6fRafael Almeida#endif
39aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
40aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic void usage(void) __attribute__((noreturn));
41750a405a5a6f6cdae7d14609b49051e59738177eStephen Hemmingerstatic int iplink_have_newlink(void);
42aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
43aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingervoid iplink_usage(void)
44aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
45750a405a5a6f6cdae7d14609b49051e59738177eStephen Hemminger	if (iplink_have_newlink()) {
46a22e92951d21d0f796040d0d6c00d59a1e188bcaSridhar Samudrala		fprintf(stderr, "Usage: ip link add [link DEV] [ name ] NAME\n");
47750a405a5a6f6cdae7d14609b49051e59738177eStephen Hemminger		fprintf(stderr, "                   [ txqueuelen PACKETS ]\n");
48750a405a5a6f6cdae7d14609b49051e59738177eStephen Hemminger		fprintf(stderr, "                   [ address LLADDR ]\n");
49750a405a5a6f6cdae7d14609b49051e59738177eStephen Hemminger		fprintf(stderr, "                   [ broadcast LLADDR ]\n");
50750a405a5a6f6cdae7d14609b49051e59738177eStephen Hemminger		fprintf(stderr, "                   [ mtu MTU ]\n");
51750a405a5a6f6cdae7d14609b49051e59738177eStephen Hemminger		fprintf(stderr, "                   type TYPE [ ARGS ]\n");
52750a405a5a6f6cdae7d14609b49051e59738177eStephen Hemminger		fprintf(stderr, "       ip link delete DEV type TYPE [ ARGS ]\n");
53750a405a5a6f6cdae7d14609b49051e59738177eStephen Hemminger		fprintf(stderr, "\n");
54db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru		fprintf(stderr, "       ip link set { dev DEVICE | group DEVGROUP } [ { up | down } ]\n");
55750a405a5a6f6cdae7d14609b49051e59738177eStephen Hemminger	} else
56750a405a5a6f6cdae7d14609b49051e59738177eStephen Hemminger		fprintf(stderr, "Usage: ip link set DEVICE [ { up | down } ]\n");
57750a405a5a6f6cdae7d14609b49051e59738177eStephen Hemminger
58750a405a5a6f6cdae7d14609b49051e59738177eStephen Hemminger	fprintf(stderr, "	                  [ arp { on | off } ]\n");
59750a405a5a6f6cdae7d14609b49051e59738177eStephen Hemminger	fprintf(stderr, "	                  [ dynamic { on | off } ]\n");
60750a405a5a6f6cdae7d14609b49051e59738177eStephen Hemminger	fprintf(stderr, "	                  [ multicast { on | off } ]\n");
61750a405a5a6f6cdae7d14609b49051e59738177eStephen Hemminger	fprintf(stderr, "	                  [ allmulticast { on | off } ]\n");
62750a405a5a6f6cdae7d14609b49051e59738177eStephen Hemminger	fprintf(stderr, "	                  [ promisc { on | off } ]\n");
63750a405a5a6f6cdae7d14609b49051e59738177eStephen Hemminger	fprintf(stderr, "	                  [ trailers { on | off } ]\n");
64750a405a5a6f6cdae7d14609b49051e59738177eStephen Hemminger	fprintf(stderr, "	                  [ txqueuelen PACKETS ]\n");
65750a405a5a6f6cdae7d14609b49051e59738177eStephen Hemminger	fprintf(stderr, "	                  [ name NEWNAME ]\n");
66750a405a5a6f6cdae7d14609b49051e59738177eStephen Hemminger	fprintf(stderr, "	                  [ address LLADDR ]\n");
67750a405a5a6f6cdae7d14609b49051e59738177eStephen Hemminger	fprintf(stderr, "	                  [ broadcast LLADDR ]\n");
68750a405a5a6f6cdae7d14609b49051e59738177eStephen Hemminger	fprintf(stderr, "	                  [ mtu MTU ]\n");
69750a405a5a6f6cdae7d14609b49051e59738177eStephen Hemminger	fprintf(stderr, "	                  [ netns PID ]\n");
700dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman	fprintf(stderr, "	                  [ netns NAME ]\n");
71ace9c96121b10ff8f91d79b7486bb8a5520c12dfStephen Hemminger	fprintf(stderr, "			  [ alias NAME ]\n");
72ae7229d5f99ed9d7fd6ae11bcc726b80e8f8cb87Williams, Mitch A	fprintf(stderr, "	                  [ vf NUM [ mac LLADDR ]\n");
73ae7229d5f99ed9d7fd6ae11bcc726b80e8f8cb87Williams, Mitch A	fprintf(stderr, "				   [ vlan VLANID [ qos VLAN-QOS ] ]\n");
747b8179c780a1abd547e5002c4e6fba898c6d72bbGreg Rose
751598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger	fprintf(stderr, "				   [ rate TXRATE ] ] \n");
767b8179c780a1abd547e5002c4e6fba898c6d72bbGreg Rose
777b8179c780a1abd547e5002c4e6fba898c6d72bbGreg Rose	fprintf(stderr, "				   [ spoofchk { on | off} ] ] \n");
78a1e191b90c35f5ef5d7dfba5ad8b5b7a7f57a421Jiri Pirko	fprintf(stderr, "			  [ master DEVICE ]\n");
79a1e191b90c35f5ef5d7dfba5ad8b5b7a7f57a421Jiri Pirko	fprintf(stderr, "			  [ nomaster ]\n");
80f960c92aac1838e0f336c0ca0f657bb55a42d8e9Vlad Dogaru	fprintf(stderr, "       ip link show [ DEVICE | group GROUP ]\n");
81750a405a5a6f6cdae7d14609b49051e59738177eStephen Hemminger
82750a405a5a6f6cdae7d14609b49051e59738177eStephen Hemminger	if (iplink_have_newlink()) {
83750a405a5a6f6cdae7d14609b49051e59738177eStephen Hemminger		fprintf(stderr, "\n");
84a22e92951d21d0f796040d0d6c00d59a1e188bcaSridhar Samudrala		fprintf(stderr, "TYPE := { vlan | veth | vcan | dummy | ifb | macvlan | can | bridge }\n");
85750a405a5a6f6cdae7d14609b49051e59738177eStephen Hemminger	}
86aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	exit(-1);
87aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
88aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
89aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic void usage(void)
90aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
91aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	iplink_usage();
92aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
93aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
94aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int on_off(char *msg)
95aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
96aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fprintf(stderr, "Error: argument of \"%s\" must be \"on\" or \"off\"\n", msg);
97aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return -1;
98aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
99aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
1001d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardystatic void *BODY;		/* cached dlopen(NULL) handle */
1011d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardystatic struct link_util *linkutil_list;
1021d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy
1031d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardystruct link_util *get_link_kind(const char *id)
1041d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy{
1051d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy	void *dlh;
1061d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy	char buf[256];
1071d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy	struct link_util *l;
1081d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy
1091d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy	for (l = linkutil_list; l; l = l->next)
1101d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		if (strcmp(l->id, id) == 0)
1111d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			return l;
1121d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy
1135e3bb534ae179be141a92eb1a4e2eb48094193b7Andreas Henriksson	snprintf(buf, sizeof(buf), LIBDIR "/ip/link_%s.so", id);
1141d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy	dlh = dlopen(buf, RTLD_LAZY);
1151d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy	if (dlh == NULL) {
1161d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		/* look in current binary, only open once */
1171d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		dlh = BODY;
1181d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		if (dlh == NULL) {
1191d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			dlh = BODY = dlopen(NULL, RTLD_LAZY);
1201d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			if (dlh == NULL)
1211d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy				return NULL;
1221d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		}
1231d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy	}
1241d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy
1251d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy	snprintf(buf, sizeof(buf), "%s_link_util", id);
1261d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy	l = dlsym(dlh, buf);
1271d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy	if (l == NULL)
1281d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		return NULL;
1291d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy
1301d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy	l->next = linkutil_list;
1311d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy	linkutil_list = l;
1321d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy	return l;
1331d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy}
1341d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy
1351d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy#if IPLINK_IOCTL_COMPAT
1361d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardystatic int have_rtnl_newlink = -1;
1371d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy
1381d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardystatic int accept_msg(const struct sockaddr_nl *who,
1391d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		      struct nlmsghdr *n, void *arg)
1401d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy{
1411d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy	struct nlmsgerr *err = (struct nlmsgerr *)NLMSG_DATA(n);
1421d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy
14366e529f579f45351828fc82d6ba2629cc6eb3dddPatrick McHardy	if (n->nlmsg_type == NLMSG_ERROR &&
14466e529f579f45351828fc82d6ba2629cc6eb3dddPatrick McHardy	    (err->error == -EOPNOTSUPP || err->error == -EINVAL))
1451d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		have_rtnl_newlink = 0;
1461d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy	else
1471d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		have_rtnl_newlink = 1;
1481d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy	return -1;
1491d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy}
1501d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy
1511d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardystatic int iplink_have_newlink(void)
1521d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy{
1531d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy	struct {
1541d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		struct nlmsghdr		n;
1551d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		struct ifinfomsg	i;
1561d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		char			buf[1024];
1571d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy	} req;
1581d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy
1591d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy	if (have_rtnl_newlink < 0) {
1601d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		memset(&req, 0, sizeof(req));
1611d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy
1621d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
1631d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		req.n.nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK;
1641d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		req.n.nlmsg_type = RTM_NEWLINK;
1651d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		req.i.ifi_family = AF_UNSPEC;
1661d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy
1671d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		rtnl_send(&rth, (char *)&req.n, req.n.nlmsg_len);
1681d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		rtnl_listen(&rth, accept_msg, NULL);
1691d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy	}
1701d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy	return have_rtnl_newlink;
1711d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy}
1721d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy#else /* IPLINK_IOCTL_COMPAT */
1731d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardystatic int iplink_have_newlink(void)
1741d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy{
1751d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy	return 1;
1761d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy}
1771d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy#endif /* ! IPLINK_IOCTL_COMPAT */
1781d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy
179909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanovstruct iplink_req {
180909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov	struct nlmsghdr		n;
181909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov	struct ifinfomsg	i;
182909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov	char			buf[1024];
183909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov};
184909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov
1851598b9ef7b6704af5126d632e324323703ca8112Stephen Hemmingerint iplink_parse_vf(int vf, int *argcp, char ***argvp,
1861598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger			   struct iplink_req *req)
1873fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright{
1883fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright	int len, argc = *argcp;
1893fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright	char **argv = *argvp;
1903fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright	struct rtattr *vfinfo;
1911598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger
1921598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger	vfinfo = addattr_nest(&req->n, sizeof(*req), IFLA_VF_INFO);
1933fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright
1943fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright	while (NEXT_ARG_OK()) {
1953fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright		NEXT_ARG();
1961598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger		if (matches(*argv, "mac") == 0) {
1971598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger			struct ifla_vf_mac ivm;
1983fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright			NEXT_ARG();
1991598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger			ivm.vf = vf;
2001598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger			len = ll_addr_a2n((char *)ivm.mac, 32, *argv);
2011598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger			if (len < 0)
2021598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger				return -1;
2031598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger			addattr_l(&req->n, sizeof(*req), IFLA_VF_MAC, &ivm, sizeof(ivm));
2043fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright		} else if (matches(*argv, "vlan") == 0) {
2051598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger			struct ifla_vf_vlan ivv;
2063fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright			NEXT_ARG();
2071598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger			if (get_unsigned(&ivv.vlan, *argv, 0)) {
2081598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger				invarg("Invalid \"vlan\" value\n", *argv);
2091598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger			}
2101598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger			ivv.vf = vf;
2111598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger			ivv.qos = 0;
2123fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright			if (NEXT_ARG_OK()) {
2133fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright				NEXT_ARG();
2143fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright				if (matches(*argv, "qos") == 0) {
2153fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright					NEXT_ARG();
2161598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger					if (get_unsigned(&ivv.qos, *argv, 0)) {
2171598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger						invarg("Invalid \"qos\" value\n", *argv);
2181598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger					}
2193fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright				} else {
2203fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright					/* rewind arg */
2213fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright					PREV_ARG();
2223fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright				}
2233fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright			}
2241598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger			addattr_l(&req->n, sizeof(*req), IFLA_VF_VLAN, &ivv, sizeof(ivv));
2253fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright		} else if (matches(*argv, "rate") == 0) {
2261598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger			struct ifla_vf_tx_rate ivt;
2273fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright			NEXT_ARG();
2281598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger			if (get_unsigned(&ivt.rate, *argv, 0)) {
2291598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger				invarg("Invalid \"rate\" value\n", *argv);
2301598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger			}
2311598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger			ivt.vf = vf;
2321598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger			addattr_l(&req->n, sizeof(*req), IFLA_VF_TX_RATE, &ivt, sizeof(ivt));
2331598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger
2347b8179c780a1abd547e5002c4e6fba898c6d72bbGreg Rose		} else if (matches(*argv, "spoofchk") == 0) {
2357b8179c780a1abd547e5002c4e6fba898c6d72bbGreg Rose			struct ifla_vf_spoofchk ivs;
2367b8179c780a1abd547e5002c4e6fba898c6d72bbGreg Rose			NEXT_ARG();
2377b8179c780a1abd547e5002c4e6fba898c6d72bbGreg Rose			if (matches(*argv, "on") == 0)
2387b8179c780a1abd547e5002c4e6fba898c6d72bbGreg Rose				ivs.setting = 1;
2397b8179c780a1abd547e5002c4e6fba898c6d72bbGreg Rose			else if (matches(*argv, "off") == 0)
2407b8179c780a1abd547e5002c4e6fba898c6d72bbGreg Rose				ivs.setting = 0;
2417b8179c780a1abd547e5002c4e6fba898c6d72bbGreg Rose			else
2427b8179c780a1abd547e5002c4e6fba898c6d72bbGreg Rose				invarg("Invalid \"spoofchk\" value\n", *argv);
2437b8179c780a1abd547e5002c4e6fba898c6d72bbGreg Rose			ivs.vf = vf;
2447b8179c780a1abd547e5002c4e6fba898c6d72bbGreg Rose			addattr_l(&req->n, sizeof(*req), IFLA_VF_SPOOFCHK, &ivs, sizeof(ivs));
2457b8179c780a1abd547e5002c4e6fba898c6d72bbGreg Rose
2463fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright		} else {
2473fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright			/* rewind arg */
2483fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright			PREV_ARG();
2493fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright			break;
2503fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright		}
2513fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright	}
2523fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright
2533fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright	if (argc == *argcp)
2543fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright		incomplete_command();
2553fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright
2561598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger	addattr_nest_end(&req->n, vfinfo);
2573fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright
2583fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright	*argcp = argc;
2593fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright	*argvp = argv;
2601598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger	return 0;
2613fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright}
2623fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright
2633fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright
264909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanovint iplink_parse(int argc, char **argv, struct iplink_req *req,
265db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru		char **name, char **type, char **link, char **dev, int *group)
2661d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy{
267909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov	int ret, len;
268909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov	char abuf[32];
2691d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy	int qlen = -1;
2701d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy	int mtu = -1;
271e2613dc8605e56dbc53890ebbae263f93610bd41Benjamin Thery	int netns = -1;
272ae7229d5f99ed9d7fd6ae11bcc726b80e8f8cb87Williams, Mitch A	int vf = -1;
2731d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy
274db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru	*group = -1;
275909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov	ret = argc;
2761d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy
2771d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy	while (argc > 0) {
2781d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		if (strcmp(*argv, "up") == 0) {
279909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov			req->i.ifi_change |= IFF_UP;
280909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov			req->i.ifi_flags |= IFF_UP;
2811d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		} else if (strcmp(*argv, "down") == 0) {
282909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov			req->i.ifi_change |= IFF_UP;
283909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov			req->i.ifi_flags &= ~IFF_UP;
2841d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		} else if (strcmp(*argv, "name") == 0) {
2851d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			NEXT_ARG();
286909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov			*name = *argv;
2871d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		} else if (matches(*argv, "link") == 0) {
2881d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			NEXT_ARG();
289909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov			*link = *argv;
2901d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		} else if (matches(*argv, "address") == 0) {
2911d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			NEXT_ARG();
2921d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			len = ll_addr_a2n(abuf, sizeof(abuf), *argv);
293cb2eb9997a0292a144968d117f4d831c155ca71dAndreas Henriksson			if (len < 0)
294cb2eb9997a0292a144968d117f4d831c155ca71dAndreas Henriksson				return -1;
295909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov			addattr_l(&req->n, sizeof(*req), IFLA_ADDRESS, abuf, len);
2961d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		} else if (matches(*argv, "broadcast") == 0 ||
297909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov				strcmp(*argv, "brd") == 0) {
2981d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			NEXT_ARG();
2991d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			len = ll_addr_a2n(abuf, sizeof(abuf), *argv);
300cb2eb9997a0292a144968d117f4d831c155ca71dAndreas Henriksson			if (len < 0)
301cb2eb9997a0292a144968d117f4d831c155ca71dAndreas Henriksson				return -1;
302909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov			addattr_l(&req->n, sizeof(*req), IFLA_BROADCAST, abuf, len);
3031d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		} else if (matches(*argv, "txqueuelen") == 0 ||
304909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov				strcmp(*argv, "qlen") == 0 ||
305909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov				matches(*argv, "txqlen") == 0) {
3061d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			NEXT_ARG();
3071d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			if (qlen != -1)
3081d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy				duparg("txqueuelen", *argv);
3091d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			if (get_integer(&qlen,  *argv, 0))
3101d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy				invarg("Invalid \"txqueuelen\" value\n", *argv);
311909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov			addattr_l(&req->n, sizeof(*req), IFLA_TXQLEN, &qlen, 4);
3121d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		} else if (strcmp(*argv, "mtu") == 0) {
3131d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			NEXT_ARG();
3141d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			if (mtu != -1)
3151d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy				duparg("mtu", *argv);
3161d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			if (get_integer(&mtu, *argv, 0))
3171d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy				invarg("Invalid \"mtu\" value\n", *argv);
318909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov			addattr_l(&req->n, sizeof(*req), IFLA_MTU, &mtu, 4);
319e2613dc8605e56dbc53890ebbae263f93610bd41Benjamin Thery                } else if (strcmp(*argv, "netns") == 0) {
320e2613dc8605e56dbc53890ebbae263f93610bd41Benjamin Thery                        NEXT_ARG();
321e2613dc8605e56dbc53890ebbae263f93610bd41Benjamin Thery                        if (netns != -1)
322e2613dc8605e56dbc53890ebbae263f93610bd41Benjamin Thery                                duparg("netns", *argv);
3230dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman			if ((netns = get_netns_fd(*argv)) >= 0)
3240dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman				addattr_l(&req->n, sizeof(*req), IFLA_NET_NS_FD, &netns, 4);
3250dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman			else if (get_integer(&netns, *argv, 0) == 0)
3260dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman				addattr_l(&req->n, sizeof(*req), IFLA_NET_NS_PID, &netns, 4);
3270dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman			else
328e2613dc8605e56dbc53890ebbae263f93610bd41Benjamin Thery                                invarg("Invalid \"netns\" value\n", *argv);
3291d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		} else if (strcmp(*argv, "multicast") == 0) {
3301d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			NEXT_ARG();
331909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov			req->i.ifi_change |= IFF_MULTICAST;
3321d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			if (strcmp(*argv, "on") == 0) {
333909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov				req->i.ifi_flags |= IFF_MULTICAST;
3341d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			} else if (strcmp(*argv, "off") == 0) {
335909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov				req->i.ifi_flags &= ~IFF_MULTICAST;
3361d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			} else
3371d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy				return on_off("multicast");
3381d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		} else if (strcmp(*argv, "allmulticast") == 0) {
3391d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			NEXT_ARG();
340909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov			req->i.ifi_change |= IFF_ALLMULTI;
3411d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			if (strcmp(*argv, "on") == 0) {
342909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov				req->i.ifi_flags |= IFF_ALLMULTI;
3431d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			} else if (strcmp(*argv, "off") == 0) {
344909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov				req->i.ifi_flags &= ~IFF_ALLMULTI;
3451d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			} else
3461d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy				return on_off("allmulticast");
3471d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		} else if (strcmp(*argv, "promisc") == 0) {
3481d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			NEXT_ARG();
349909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov			req->i.ifi_change |= IFF_PROMISC;
3501d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			if (strcmp(*argv, "on") == 0) {
351909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov				req->i.ifi_flags |= IFF_PROMISC;
3521d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			} else if (strcmp(*argv, "off") == 0) {
353909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov				req->i.ifi_flags &= ~IFF_PROMISC;
3541d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			} else
3551d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy				return on_off("promisc");
3561d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		} else if (strcmp(*argv, "trailers") == 0) {
3571d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			NEXT_ARG();
358909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov			req->i.ifi_change |= IFF_NOTRAILERS;
3591d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			if (strcmp(*argv, "off") == 0) {
360909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov				req->i.ifi_flags |= IFF_NOTRAILERS;
3611d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			} else if (strcmp(*argv, "on") == 0) {
362909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov				req->i.ifi_flags &= ~IFF_NOTRAILERS;
3631d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			} else
3641d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy				return on_off("trailers");
3651d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		} else if (strcmp(*argv, "arp") == 0) {
3661d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			NEXT_ARG();
367909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov			req->i.ifi_change |= IFF_NOARP;
3681d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			if (strcmp(*argv, "on") == 0) {
369909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov				req->i.ifi_flags &= ~IFF_NOARP;
3701d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			} else if (strcmp(*argv, "off") == 0) {
371909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov				req->i.ifi_flags |= IFF_NOARP;
3721d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			} else
3731d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy				return on_off("noarp");
374ae7229d5f99ed9d7fd6ae11bcc726b80e8f8cb87Williams, Mitch A		} else if (strcmp(*argv, "vf") == 0) {
3751598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger			struct rtattr *vflist;
376ae7229d5f99ed9d7fd6ae11bcc726b80e8f8cb87Williams, Mitch A			NEXT_ARG();
377ae7229d5f99ed9d7fd6ae11bcc726b80e8f8cb87Williams, Mitch A			if (get_integer(&vf,  *argv, 0)) {
378ae7229d5f99ed9d7fd6ae11bcc726b80e8f8cb87Williams, Mitch A				invarg("Invalid \"vf\" value\n", *argv);
379ae7229d5f99ed9d7fd6ae11bcc726b80e8f8cb87Williams, Mitch A			}
3801598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger			vflist = addattr_nest(&req->n, sizeof(*req),
3811598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger					      IFLA_VFINFO_LIST);
3821598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger			len = iplink_parse_vf(vf, &argc, &argv, req);
3831598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger			if (len < 0)
3841598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger				return -1;
3851598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger			addattr_nest_end(&req->n, vflist);
386a1e191b90c35f5ef5d7dfba5ad8b5b7a7f57a421Jiri Pirko		} else if (matches(*argv, "master") == 0) {
387a1e191b90c35f5ef5d7dfba5ad8b5b7a7f57a421Jiri Pirko			int ifindex;
388a1e191b90c35f5ef5d7dfba5ad8b5b7a7f57a421Jiri Pirko			NEXT_ARG();
389a1e191b90c35f5ef5d7dfba5ad8b5b7a7f57a421Jiri Pirko			ifindex = ll_name_to_index(*argv);
390a1e191b90c35f5ef5d7dfba5ad8b5b7a7f57a421Jiri Pirko			if (!ifindex)
391a1e191b90c35f5ef5d7dfba5ad8b5b7a7f57a421Jiri Pirko				invarg("Device does not exist\n", *argv);
392a1e191b90c35f5ef5d7dfba5ad8b5b7a7f57a421Jiri Pirko			addattr_l(&req->n, sizeof(*req), IFLA_MASTER,
393a1e191b90c35f5ef5d7dfba5ad8b5b7a7f57a421Jiri Pirko				  &ifindex, 4);
394a1e191b90c35f5ef5d7dfba5ad8b5b7a7f57a421Jiri Pirko		} else if (matches(*argv, "nomaster") == 0) {
395a1e191b90c35f5ef5d7dfba5ad8b5b7a7f57a421Jiri Pirko			int ifindex = 0;
396a1e191b90c35f5ef5d7dfba5ad8b5b7a7f57a421Jiri Pirko			addattr_l(&req->n, sizeof(*req), IFLA_MASTER,
397a1e191b90c35f5ef5d7dfba5ad8b5b7a7f57a421Jiri Pirko				  &ifindex, 4);
3981d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		} else if (matches(*argv, "dynamic") == 0) {
3991d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			NEXT_ARG();
400909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov			req->i.ifi_change |= IFF_DYNAMIC;
4011d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			if (strcmp(*argv, "on") == 0) {
402909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov				req->i.ifi_flags |= IFF_DYNAMIC;
4031d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			} else if (strcmp(*argv, "off") == 0) {
404909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov				req->i.ifi_flags &= ~IFF_DYNAMIC;
4051d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			} else
4061d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy				return on_off("dynamic");
4071d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		} else if (matches(*argv, "type") == 0) {
4081d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			NEXT_ARG();
409909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov			*type = *argv;
4101d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			argc--; argv++;
4111d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			break;
412ace9c96121b10ff8f91d79b7486bb8a5520c12dfStephen Hemminger		} else if (matches(*argv, "alias") == 0) {
413ace9c96121b10ff8f91d79b7486bb8a5520c12dfStephen Hemminger			NEXT_ARG();
414ace9c96121b10ff8f91d79b7486bb8a5520c12dfStephen Hemminger			addattr_l(&req->n, sizeof(*req), IFLA_IFALIAS,
415ace9c96121b10ff8f91d79b7486bb8a5520c12dfStephen Hemminger				  *argv, strlen(*argv));
416ace9c96121b10ff8f91d79b7486bb8a5520c12dfStephen Hemminger			argc--; argv++;
417ace9c96121b10ff8f91d79b7486bb8a5520c12dfStephen Hemminger			break;
418db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru		} else if (strcmp(*argv, "group") == 0) {
419db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru			NEXT_ARG();
420db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru			if (*group != -1)
421db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru				duparg("group", *argv);
422db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru			if (rtnl_group_a2n(group, *argv))
423db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru				invarg("Invalid \"group\" value\n", *argv);
4241d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		} else {
425909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov			if (strcmp(*argv, "dev") == 0) {
4261d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy				NEXT_ARG();
4271d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			}
428053255520216654c6914e84b0a37e86c542898bdPatrick McHardy			if (matches(*argv, "help") == 0)
429053255520216654c6914e84b0a37e86c542898bdPatrick McHardy				usage();
430909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov			if (*dev)
4311d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy				duparg2("dev", *argv);
432909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov			*dev = *argv;
4331d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		}
4341d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		argc--; argv++;
4351d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy	}
4361d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy
437909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov	return ret - argc;
438909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov}
439909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov
440909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanovstatic int iplink_modify(int cmd, unsigned int flags, int argc, char **argv)
441909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov{
442909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov	int len;
443909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov	char *dev = NULL;
444909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov	char *name = NULL;
445909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov	char *link = NULL;
446909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov	char *type = NULL;
447db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru	int group;
448909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov	struct link_util *lu = NULL;
449909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov	struct iplink_req req;
450909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov	int ret;
451909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov
452909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov	memset(&req, 0, sizeof(req));
453909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov
454909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
455909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov	req.n.nlmsg_flags = NLM_F_REQUEST|flags;
456909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov	req.n.nlmsg_type = cmd;
457909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov	req.i.ifi_family = preferred_family;
458909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov
459db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru	ret = iplink_parse(argc, argv, &req, &name, &type, &link, &dev, &group);
460909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov	if (ret < 0)
461909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov		return ret;
462909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov
463909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov	argc -= ret;
464909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov	argv += ret;
465db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru
466db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru	if (group != -1) {
467db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru		if (dev)
468db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru			addattr_l(&req.n, sizeof(req), IFLA_GROUP,
469db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru					&group, sizeof(group));
470db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru		else {
471db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru			if (argc) {
472db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru				fprintf(stderr, "Garbage instead of arguments "
473db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru						"\"%s ...\". Try \"ip link "
474db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru						"help\".\n", *argv);
475db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru				return -1;
476db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru			}
477db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru			if (flags & NLM_F_CREATE) {
478db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru				fprintf(stderr, "group cannot be used when "
479db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru						"creating devices.\n");
480db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru				return -1;
481db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru			}
482db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru
483db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru			req.i.ifi_index = 0;
484db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru			addattr32(&req.n, sizeof(req), IFLA_GROUP, group);
485db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru			if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0)
486db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru				exit(2);
487db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru			return 0;
488db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru		}
489db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru	}
490db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru
4911d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy	ll_init_map(&rth);
4921d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy
4931d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy	if (type) {
4941d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		struct rtattr *linkinfo = NLMSG_TAIL(&req.n);
4951d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		addattr_l(&req.n, sizeof(req), IFLA_LINKINFO, NULL, 0);
4961d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		addattr_l(&req.n, sizeof(req), IFLA_INFO_KIND, type,
4971d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			 strlen(type));
4981d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy
4991d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		lu = get_link_kind(type);
5001d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		if (lu && argc) {
5011d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			struct rtattr * data = NLMSG_TAIL(&req.n);
5021d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			addattr_l(&req.n, sizeof(req), IFLA_INFO_DATA, NULL, 0);
5031d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy
5041d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			if (lu->parse_opt &&
5051d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			    lu->parse_opt(lu, argc, argv, &req.n))
5061d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy				return -1;
5071d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy
5081d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			data->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)data;
5091d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		} else if (argc) {
5101d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			if (matches(*argv, "help") == 0)
5111d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy				usage();
5121d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			fprintf(stderr, "Garbage instead of arguments \"%s ...\". "
5131d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy					"Try \"ip link help\".\n", *argv);
5141d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			return -1;
5151d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		}
5161d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		linkinfo->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)linkinfo;
5173ef0c8594283d4891e84b4b8d7d04901416aeae0Patrick McHardy	} else if (flags & NLM_F_CREATE) {
5183ef0c8594283d4891e84b4b8d7d04901416aeae0Patrick McHardy		fprintf(stderr, "Not enough information: \"type\" argument "
5193ef0c8594283d4891e84b4b8d7d04901416aeae0Patrick McHardy				"is required\n");
5203ef0c8594283d4891e84b4b8d7d04901416aeae0Patrick McHardy		return -1;
5211d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy	}
5221d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy
5231d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy	if (!(flags & NLM_F_CREATE)) {
5241d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		if (!dev) {
5251d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			fprintf(stderr, "Not enough information: \"dev\" "
5261d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy					"argument is required.\n");
5271d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			exit(-1);
5281d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		}
5291d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy
5301d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		req.i.ifi_index = ll_name_to_index(dev);
5311d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		if (req.i.ifi_index == 0) {
5321d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			fprintf(stderr, "Cannot find device \"%s\"\n", dev);
5331d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			return -1;
5341d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		}
5351d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy	} else {
5361d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		/* Allow "ip link add dev" and "ip link add name" */
5371d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		if (!name)
5381d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			name = dev;
5391d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy
5401d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		if (link) {
5411d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			int ifindex;
5421d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy
5431d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			ifindex = ll_name_to_index(link);
5441d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			if (ifindex == 0) {
5451d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy				fprintf(stderr, "Cannot find device \"%s\"\n",
5461d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy					link);
5471d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy				return -1;
5481d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			}
5491d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			addattr_l(&req.n, sizeof(req), IFLA_LINK, &ifindex, 4);
5501d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		}
5511d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy	}
5521d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy
5531d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy	if (name) {
5541d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		len = strlen(name) + 1;
555ca78b0e7d4042be7f7283d551d433b76da7f312bPatrick McHardy		if (len == 1)
556ca78b0e7d4042be7f7283d551d433b76da7f312bPatrick McHardy			invarg("\"\" is not a valid device identifier\n", "name");
5571d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		if (len > IFNAMSIZ)
558ca78b0e7d4042be7f7283d551d433b76da7f312bPatrick McHardy			invarg("\"name\" too long\n", name);
5591d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		addattr_l(&req.n, sizeof(req), IFLA_IFNAME, name, len);
5601d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy	}
5611d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy
5621d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy	if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0)
5631d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		exit(2);
5641d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy
5651d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy	return 0;
5661d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy}
5671d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy
5681d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy#if IPLINK_IOCTL_COMPAT
569aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int get_ctl_fd(void)
570aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
571aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int s_errno;
572aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int fd;
573aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
574aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fd = socket(PF_INET, SOCK_DGRAM, 0);
575aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (fd >= 0)
576aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return fd;
577aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	s_errno = errno;
578aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fd = socket(PF_PACKET, SOCK_DGRAM, 0);
579aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (fd >= 0)
580aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return fd;
581aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fd = socket(PF_INET6, SOCK_DGRAM, 0);
582aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (fd >= 0)
583aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return fd;
584aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	errno = s_errno;
585aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	perror("Cannot create control socket");
586aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return -1;
587aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
588aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
58971058eb8ef128aa99666dc4e6664e7632e12a1b9osdl.net!shemmingerstatic int do_chflags(const char *dev, __u32 flags, __u32 mask)
590aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
591aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	struct ifreq ifr;
592aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int fd;
593aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int err;
594aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
59571058eb8ef128aa99666dc4e6664e7632e12a1b9osdl.net!shemminger	strncpy(ifr.ifr_name, dev, IFNAMSIZ);
596aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fd = get_ctl_fd();
597aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (fd < 0)
598aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
599aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	err = ioctl(fd, SIOCGIFFLAGS, &ifr);
600aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (err) {
601aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		perror("SIOCGIFFLAGS");
602aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		close(fd);
603aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
604aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
605aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if ((ifr.ifr_flags^flags)&mask) {
606aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		ifr.ifr_flags &= ~mask;
607aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		ifr.ifr_flags |= mask&flags;
608aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		err = ioctl(fd, SIOCSIFFLAGS, &ifr);
609aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (err)
610aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			perror("SIOCSIFFLAGS");
611aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
612aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	close(fd);
613aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return err;
614aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
615aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
61671058eb8ef128aa99666dc4e6664e7632e12a1b9osdl.net!shemmingerstatic int do_changename(const char *dev, const char *newdev)
617aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
618aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	struct ifreq ifr;
619aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int fd;
620aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int err;
621aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
62271058eb8ef128aa99666dc4e6664e7632e12a1b9osdl.net!shemminger	strncpy(ifr.ifr_name, dev, IFNAMSIZ);
62371058eb8ef128aa99666dc4e6664e7632e12a1b9osdl.net!shemminger	strncpy(ifr.ifr_newname, newdev, IFNAMSIZ);
624aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fd = get_ctl_fd();
625aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (fd < 0)
626aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
627aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	err = ioctl(fd, SIOCSIFNAME, &ifr);
628aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (err) {
629aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		perror("SIOCSIFNAME");
630aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		close(fd);
631aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
632aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
633aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	close(fd);
634aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return err;
635aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
636aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
63771058eb8ef128aa99666dc4e6664e7632e12a1b9osdl.net!shemmingerstatic int set_qlen(const char *dev, int qlen)
638aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
639aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	struct ifreq ifr;
640aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int s;
641aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
642aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	s = get_ctl_fd();
643aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (s < 0)
644aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
645aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
646aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	memset(&ifr, 0, sizeof(ifr));
647ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger	strncpy(ifr.ifr_name, dev, IFNAMSIZ);
648ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger	ifr.ifr_qlen = qlen;
649aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (ioctl(s, SIOCSIFTXQLEN, &ifr) < 0) {
650aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		perror("SIOCSIFXQLEN");
651aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		close(s);
652aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
653aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
654aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	close(s);
655aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
656ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger	return 0;
657aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
658aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
65971058eb8ef128aa99666dc4e6664e7632e12a1b9osdl.net!shemmingerstatic int set_mtu(const char *dev, int mtu)
660aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
661aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	struct ifreq ifr;
662aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int s;
663aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
664aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	s = get_ctl_fd();
665aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (s < 0)
666aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
667aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
668aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	memset(&ifr, 0, sizeof(ifr));
669ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger	strncpy(ifr.ifr_name, dev, IFNAMSIZ);
670ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger	ifr.ifr_mtu = mtu;
671aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (ioctl(s, SIOCSIFMTU, &ifr) < 0) {
672aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		perror("SIOCSIFMTU");
673aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		close(s);
674aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
675aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
676aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	close(s);
677aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
678ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger	return 0;
679aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
680aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
68171058eb8ef128aa99666dc4e6664e7632e12a1b9osdl.net!shemmingerstatic int get_address(const char *dev, int *htype)
682aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
683aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	struct ifreq ifr;
684aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	struct sockaddr_ll me;
685f332d169246447bd5e258ac03d5ee840a70adb1eshemminger	socklen_t alen;
686aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int s;
687aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
688aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	s = socket(PF_PACKET, SOCK_DGRAM, 0);
689ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger	if (s < 0) {
690aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		perror("socket(PF_PACKET)");
691aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
692aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
693aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
694aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	memset(&ifr, 0, sizeof(ifr));
69571058eb8ef128aa99666dc4e6664e7632e12a1b9osdl.net!shemminger	strncpy(ifr.ifr_name, dev, IFNAMSIZ);
696aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
697aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		perror("SIOCGIFINDEX");
698aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		close(s);
699aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
700aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
701aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
702aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	memset(&me, 0, sizeof(me));
703aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	me.sll_family = AF_PACKET;
704aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	me.sll_ifindex = ifr.ifr_ifindex;
705aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	me.sll_protocol = htons(ETH_P_LOOP);
706aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (bind(s, (struct sockaddr*)&me, sizeof(me)) == -1) {
707aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		perror("bind");
708aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		close(s);
709aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
710aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
711aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
712aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	alen = sizeof(me);
713aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (getsockname(s, (struct sockaddr*)&me, &alen) == -1) {
714aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		perror("getsockname");
715aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		close(s);
716aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
717aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
718aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	close(s);
719aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	*htype = me.sll_hatype;
720aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return me.sll_halen;
721aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
722aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
723ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemmingerstatic int parse_address(const char *dev, int hatype, int halen,
7247b5657545dc246ae37690d660597e8fa37040205shemminger		char *lla, struct ifreq *ifr)
725aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
726aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int alen;
727aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
728aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	memset(ifr, 0, sizeof(*ifr));
72971058eb8ef128aa99666dc4e6664e7632e12a1b9osdl.net!shemminger	strncpy(ifr->ifr_name, dev, IFNAMSIZ);
730aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	ifr->ifr_hwaddr.sa_family = hatype;
731aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	alen = ll_addr_a2n(ifr->ifr_hwaddr.sa_data, 14, lla);
732aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (alen < 0)
733aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
734aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (alen != halen) {
735aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		fprintf(stderr, "Wrong address (%s) length: expected %d bytes\n", lla, halen);
736aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
737aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
738ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger	return 0;
739aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
740aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
741aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int set_address(struct ifreq *ifr, int brd)
742aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
743aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int s;
744aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
745aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	s = get_ctl_fd();
746aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (s < 0)
747aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
748aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (ioctl(s, brd?SIOCSIFHWBROADCAST:SIOCSIFHWADDR, ifr) < 0) {
749aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		perror(brd?"SIOCSIFHWBROADCAST":"SIOCSIFHWADDR");
750aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		close(s);
751aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
752aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
753aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	close(s);
754ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger	return 0;
755aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
756aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
757aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
758aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int do_set(int argc, char **argv)
759aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
760aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	char *dev = NULL;
761aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	__u32 mask = 0;
762aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	__u32 flags = 0;
763aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int qlen = -1;
764aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int mtu = -1;
765aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	char *newaddr = NULL;
766aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	char *newbrd = NULL;
767aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	struct ifreq ifr0, ifr1;
768aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	char *newname = NULL;
769aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int htype, halen;
770aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
771aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	while (argc > 0) {
772aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (strcmp(*argv, "up") == 0) {
773aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			mask |= IFF_UP;
774aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			flags |= IFF_UP;
775aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (strcmp(*argv, "down") == 0) {
776aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			mask |= IFF_UP;
777aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			flags &= ~IFF_UP;
778aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (strcmp(*argv, "name") == 0) {
779aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			NEXT_ARG();
780aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			newname = *argv;
781aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (matches(*argv, "address") == 0) {
782aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			NEXT_ARG();
783aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			newaddr = *argv;
784aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (matches(*argv, "broadcast") == 0 ||
785aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			   strcmp(*argv, "brd") == 0) {
786aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			NEXT_ARG();
787aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			newbrd = *argv;
788aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (matches(*argv, "txqueuelen") == 0 ||
789aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			   strcmp(*argv, "qlen") == 0 ||
790aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			   matches(*argv, "txqlen") == 0) {
791aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			NEXT_ARG();
792aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (qlen != -1)
793aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				duparg("txqueuelen", *argv);
794aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (get_integer(&qlen,  *argv, 0))
795aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				invarg("Invalid \"txqueuelen\" value\n", *argv);
796aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (strcmp(*argv, "mtu") == 0) {
797aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			NEXT_ARG();
798aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (mtu != -1)
799aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				duparg("mtu", *argv);
800aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (get_integer(&mtu, *argv, 0))
801aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				invarg("Invalid \"mtu\" value\n", *argv);
802aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (strcmp(*argv, "multicast") == 0) {
803aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			NEXT_ARG();
804aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			mask |= IFF_MULTICAST;
805aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (strcmp(*argv, "on") == 0) {
806aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				flags |= IFF_MULTICAST;
807aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			} else if (strcmp(*argv, "off") == 0) {
808aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				flags &= ~IFF_MULTICAST;
809aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			} else
810aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				return on_off("multicast");
811d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger		} else if (strcmp(*argv, "allmulticast") == 0) {
812d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger			NEXT_ARG();
813d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger			mask |= IFF_ALLMULTI;
814d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger			if (strcmp(*argv, "on") == 0) {
815d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger				flags |= IFF_ALLMULTI;
816d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger			} else if (strcmp(*argv, "off") == 0) {
817d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger				flags &= ~IFF_ALLMULTI;
818d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger			} else
819d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger				return on_off("allmulticast");
820d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger		} else if (strcmp(*argv, "promisc") == 0) {
821d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger			NEXT_ARG();
822d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger			mask |= IFF_PROMISC;
823d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger			if (strcmp(*argv, "on") == 0) {
824d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger				flags |= IFF_PROMISC;
825d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger			} else if (strcmp(*argv, "off") == 0) {
826d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger				flags &= ~IFF_PROMISC;
827d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger			} else
828d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger				return on_off("promisc");
829d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger		} else if (strcmp(*argv, "trailers") == 0) {
830d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger			NEXT_ARG();
831d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger			mask |= IFF_NOTRAILERS;
832d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger			if (strcmp(*argv, "off") == 0) {
833d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger				flags |= IFF_NOTRAILERS;
834d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger			} else if (strcmp(*argv, "on") == 0) {
835d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger				flags &= ~IFF_NOTRAILERS;
836d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger			} else
837d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger				return on_off("trailers");
838aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (strcmp(*argv, "arp") == 0) {
839aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			NEXT_ARG();
840aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			mask |= IFF_NOARP;
841aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (strcmp(*argv, "on") == 0) {
842aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				flags &= ~IFF_NOARP;
843aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			} else if (strcmp(*argv, "off") == 0) {
844aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				flags |= IFF_NOARP;
845aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			} else
846aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				return on_off("noarp");
847aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (matches(*argv, "dynamic") == 0) {
848aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			NEXT_ARG();
849aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			mask |= IFF_DYNAMIC;
850aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (strcmp(*argv, "on") == 0) {
851aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				flags |= IFF_DYNAMIC;
852aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			} else if (strcmp(*argv, "off") == 0) {
853aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				flags &= ~IFF_DYNAMIC;
854aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			} else
855aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				return on_off("dynamic");
856aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else {
857aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger                        if (strcmp(*argv, "dev") == 0) {
858aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				NEXT_ARG();
859aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			}
860aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (matches(*argv, "help") == 0)
861aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				usage();
862aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (dev)
863aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				duparg2("dev", *argv);
864aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			dev = *argv;
865aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
866aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		argc--; argv++;
867aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
868aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
869aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (!dev) {
870aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		fprintf(stderr, "Not enough of information: \"dev\" argument is required.\n");
871aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		exit(-1);
872aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
873aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
874aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (newaddr || newbrd) {
875aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		halen = get_address(dev, &htype);
876aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (halen < 0)
877aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			return -1;
878aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (newaddr) {
879aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (parse_address(dev, htype, halen, newaddr, &ifr0) < 0)
880aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				return -1;
881aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
882aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (newbrd) {
883aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (parse_address(dev, htype, halen, newbrd, &ifr1) < 0)
884ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger				return -1;
885aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
886aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
887aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
888aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (newname && strcmp(dev, newname)) {
889ca78b0e7d4042be7f7283d551d433b76da7f312bPatrick McHardy		if (strlen(newname) == 0)
890ca78b0e7d4042be7f7283d551d433b76da7f312bPatrick McHardy			invarg("\"\" is not a valid device identifier\n", "name");
891aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (do_changename(dev, newname) < 0)
892aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			return -1;
893aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		dev = newname;
894aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
895ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger	if (qlen != -1) {
896aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (set_qlen(dev, qlen) < 0)
897ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger			return -1;
898aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
899ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger	if (mtu != -1) {
900aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (set_mtu(dev, mtu) < 0)
901ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger			return -1;
902aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
903aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (newaddr || newbrd) {
904aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (newbrd) {
905aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (set_address(&ifr1, 1) < 0)
906ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger				return -1;
907aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
908aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (newaddr) {
909aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (set_address(&ifr0, 0) < 0)
910aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				return -1;
911aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
912aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
913aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (mask)
914aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return do_chflags(dev, flags, mask);
915aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return 0;
916aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
9171d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy#endif /* IPLINK_IOCTL_COMPAT */
918aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
919aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint do_iplink(int argc, char **argv)
920aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
921aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (argc > 0) {
9221d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		if (iplink_have_newlink()) {
9231d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			if (matches(*argv, "add") == 0)
9241d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy				return iplink_modify(RTM_NEWLINK,
9251d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy						     NLM_F_CREATE|NLM_F_EXCL,
9261d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy						     argc-1, argv+1);
9271d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			if (matches(*argv, "set") == 0 ||
9281d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			    matches(*argv, "change") == 0)
9291d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy				return iplink_modify(RTM_NEWLINK, 0,
9301d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy						     argc-1, argv+1);
9311d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			if (matches(*argv, "replace") == 0)
9321d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy				return iplink_modify(RTM_NEWLINK,
9331d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy						     NLM_F_CREATE|NLM_F_REPLACE,
9341d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy						     argc-1, argv+1);
9351d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			if (matches(*argv, "delete") == 0)
9361d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy				return iplink_modify(RTM_DELLINK, 0,
9371d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy						     argc-1, argv+1);
9381d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		} else {
9391d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy#if IPLINK_IOCTL_COMPAT
9401d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy			if (matches(*argv, "set") == 0)
9411d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy				return do_set(argc-1, argv+1);
9421d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy#endif
9431d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy		}
944aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (matches(*argv, "show") == 0 ||
945aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		    matches(*argv, "lst") == 0 ||
946aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		    matches(*argv, "list") == 0)
947aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			return ipaddr_list_link(argc-1, argv+1);
948aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (matches(*argv, "help") == 0)
949aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			usage();
950aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	} else
951aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return ipaddr_list_link(0, NULL);
952aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
953aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fprintf(stderr, "Command \"%s\" is unknown, try \"ip link help\".\n", *argv);
954aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	exit(-1);
955aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
956