iplink.c revision 4f2fdd44b6694f713aa638cc2222a2d7d17dfe5f
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 13582499282b27c82a25448dc40948920950c9a6936Stephen Hemmingerint get_link_mode(const char *mode) 13682499282b27c82a25448dc40948920950c9a6936Stephen Hemminger{ 13782499282b27c82a25448dc40948920950c9a6936Stephen Hemminger if (strcmp(mode, "default") == 0) 13882499282b27c82a25448dc40948920950c9a6936Stephen Hemminger return IF_LINK_MODE_DEFAULT; 13982499282b27c82a25448dc40948920950c9a6936Stephen Hemminger if (strcmp(mode, "dormant") == 0) 14082499282b27c82a25448dc40948920950c9a6936Stephen Hemminger return IF_LINK_MODE_DORMANT; 14182499282b27c82a25448dc40948920950c9a6936Stephen Hemminger return -1; 14282499282b27c82a25448dc40948920950c9a6936Stephen Hemminger} 14382499282b27c82a25448dc40948920950c9a6936Stephen Hemminger 1441d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy#if IPLINK_IOCTL_COMPAT 1451d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardystatic int have_rtnl_newlink = -1; 1461d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 1471d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardystatic int accept_msg(const struct sockaddr_nl *who, 1481d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy struct nlmsghdr *n, void *arg) 1491d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy{ 1501d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy struct nlmsgerr *err = (struct nlmsgerr *)NLMSG_DATA(n); 1511d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 15266e529f579f45351828fc82d6ba2629cc6eb3dddPatrick McHardy if (n->nlmsg_type == NLMSG_ERROR && 15366e529f579f45351828fc82d6ba2629cc6eb3dddPatrick McHardy (err->error == -EOPNOTSUPP || err->error == -EINVAL)) 1541d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy have_rtnl_newlink = 0; 1551d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy else 1561d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy have_rtnl_newlink = 1; 1571d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return -1; 1581d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy} 1591d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 1601d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardystatic int iplink_have_newlink(void) 1611d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy{ 1621d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy struct { 1631d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy struct nlmsghdr n; 1641d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy struct ifinfomsg i; 1651d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy char buf[1024]; 1661d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } req; 1671d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 1681d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (have_rtnl_newlink < 0) { 1691d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy memset(&req, 0, sizeof(req)); 1701d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 1711d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); 1721d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy req.n.nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK; 1731d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy req.n.nlmsg_type = RTM_NEWLINK; 1741d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy req.i.ifi_family = AF_UNSPEC; 1751d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 1766cf8398f5f487762586801c25539d8fe5bb33b39Stephen Hemminger rtnl_send(&rth, &req.n, req.n.nlmsg_len); 1771d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy rtnl_listen(&rth, accept_msg, NULL); 1781d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } 1791d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return have_rtnl_newlink; 1801d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy} 1811d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy#else /* IPLINK_IOCTL_COMPAT */ 1821d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardystatic int iplink_have_newlink(void) 1831d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy{ 1841d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return 1; 1851d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy} 1861d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy#endif /* ! IPLINK_IOCTL_COMPAT */ 1871d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 188909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanovstruct iplink_req { 189909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov struct nlmsghdr n; 190909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov struct ifinfomsg i; 191909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov char buf[1024]; 192909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov}; 193909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov 1941598b9ef7b6704af5126d632e324323703ca8112Stephen Hemmingerint iplink_parse_vf(int vf, int *argcp, char ***argvp, 1951598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger struct iplink_req *req) 1963fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright{ 1973fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright int len, argc = *argcp; 1983fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright char **argv = *argvp; 1993fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright struct rtattr *vfinfo; 2001598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger 2011598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger vfinfo = addattr_nest(&req->n, sizeof(*req), IFLA_VF_INFO); 2023fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright 2033fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright while (NEXT_ARG_OK()) { 2043fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright NEXT_ARG(); 2051598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger if (matches(*argv, "mac") == 0) { 2061598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger struct ifla_vf_mac ivm; 2073fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright NEXT_ARG(); 2081598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger ivm.vf = vf; 2091598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger len = ll_addr_a2n((char *)ivm.mac, 32, *argv); 2101598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger if (len < 0) 2111598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger return -1; 2121598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger addattr_l(&req->n, sizeof(*req), IFLA_VF_MAC, &ivm, sizeof(ivm)); 2133fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright } else if (matches(*argv, "vlan") == 0) { 2141598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger struct ifla_vf_vlan ivv; 2153fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright NEXT_ARG(); 2161598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger if (get_unsigned(&ivv.vlan, *argv, 0)) { 2171598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger invarg("Invalid \"vlan\" value\n", *argv); 2181598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger } 2191598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger ivv.vf = vf; 2201598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger ivv.qos = 0; 2213fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright if (NEXT_ARG_OK()) { 2223fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright NEXT_ARG(); 2233fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright if (matches(*argv, "qos") == 0) { 2243fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright NEXT_ARG(); 2251598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger if (get_unsigned(&ivv.qos, *argv, 0)) { 2261598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger invarg("Invalid \"qos\" value\n", *argv); 2271598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger } 2283fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright } else { 2293fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright /* rewind arg */ 2303fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright PREV_ARG(); 2313fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright } 2323fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright } 2331598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger addattr_l(&req->n, sizeof(*req), IFLA_VF_VLAN, &ivv, sizeof(ivv)); 2343fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright } else if (matches(*argv, "rate") == 0) { 2351598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger struct ifla_vf_tx_rate ivt; 2363fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright NEXT_ARG(); 2371598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger if (get_unsigned(&ivt.rate, *argv, 0)) { 2381598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger invarg("Invalid \"rate\" value\n", *argv); 2391598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger } 2401598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger ivt.vf = vf; 2411598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger addattr_l(&req->n, sizeof(*req), IFLA_VF_TX_RATE, &ivt, sizeof(ivt)); 2421598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger 2437b8179c780a1abd547e5002c4e6fba898c6d72bbGreg Rose } else if (matches(*argv, "spoofchk") == 0) { 2447b8179c780a1abd547e5002c4e6fba898c6d72bbGreg Rose struct ifla_vf_spoofchk ivs; 2457b8179c780a1abd547e5002c4e6fba898c6d72bbGreg Rose NEXT_ARG(); 2467b8179c780a1abd547e5002c4e6fba898c6d72bbGreg Rose if (matches(*argv, "on") == 0) 2477b8179c780a1abd547e5002c4e6fba898c6d72bbGreg Rose ivs.setting = 1; 2487b8179c780a1abd547e5002c4e6fba898c6d72bbGreg Rose else if (matches(*argv, "off") == 0) 2497b8179c780a1abd547e5002c4e6fba898c6d72bbGreg Rose ivs.setting = 0; 2507b8179c780a1abd547e5002c4e6fba898c6d72bbGreg Rose else 2517b8179c780a1abd547e5002c4e6fba898c6d72bbGreg Rose invarg("Invalid \"spoofchk\" value\n", *argv); 2527b8179c780a1abd547e5002c4e6fba898c6d72bbGreg Rose ivs.vf = vf; 2537b8179c780a1abd547e5002c4e6fba898c6d72bbGreg Rose addattr_l(&req->n, sizeof(*req), IFLA_VF_SPOOFCHK, &ivs, sizeof(ivs)); 2547b8179c780a1abd547e5002c4e6fba898c6d72bbGreg Rose 2553fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright } else { 2563fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright /* rewind arg */ 2573fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright PREV_ARG(); 2583fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright break; 2593fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright } 2603fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright } 2613fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright 2623fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright if (argc == *argcp) 2633fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright incomplete_command(); 2643fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright 2651598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger addattr_nest_end(&req->n, vfinfo); 2663fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright 2673fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright *argcp = argc; 2683fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright *argvp = argv; 2691598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger return 0; 2703fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright} 2713fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright 2723fd86630876aed8a23e4f2c2d72e68cbb2ee331aChris Wright 273909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanovint iplink_parse(int argc, char **argv, struct iplink_req *req, 274db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru char **name, char **type, char **link, char **dev, int *group) 2751d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy{ 276909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov int ret, len; 277909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov char abuf[32]; 2781d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy int qlen = -1; 2791d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy int mtu = -1; 280e2613dc8605e56dbc53890ebbae263f93610bd41Benjamin Thery int netns = -1; 281ae7229d5f99ed9d7fd6ae11bcc726b80e8f8cb87Williams, Mitch A int vf = -1; 2821d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 283db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru *group = -1; 284909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov ret = argc; 2851d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 2861d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy while (argc > 0) { 2871d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (strcmp(*argv, "up") == 0) { 288909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_change |= IFF_UP; 289909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_flags |= IFF_UP; 2901d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (strcmp(*argv, "down") == 0) { 291909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_change |= IFF_UP; 292909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_flags &= ~IFF_UP; 2931d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (strcmp(*argv, "name") == 0) { 2941d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy NEXT_ARG(); 295909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov *name = *argv; 2961d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (matches(*argv, "link") == 0) { 2971d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy NEXT_ARG(); 298909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov *link = *argv; 2991d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (matches(*argv, "address") == 0) { 3001d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy NEXT_ARG(); 3011d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy len = ll_addr_a2n(abuf, sizeof(abuf), *argv); 302cb2eb9997a0292a144968d117f4d831c155ca71dAndreas Henriksson if (len < 0) 303cb2eb9997a0292a144968d117f4d831c155ca71dAndreas Henriksson return -1; 304909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov addattr_l(&req->n, sizeof(*req), IFLA_ADDRESS, abuf, len); 3051d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (matches(*argv, "broadcast") == 0 || 306909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov strcmp(*argv, "brd") == 0) { 3071d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy NEXT_ARG(); 3081d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy len = ll_addr_a2n(abuf, sizeof(abuf), *argv); 309cb2eb9997a0292a144968d117f4d831c155ca71dAndreas Henriksson if (len < 0) 310cb2eb9997a0292a144968d117f4d831c155ca71dAndreas Henriksson return -1; 311909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov addattr_l(&req->n, sizeof(*req), IFLA_BROADCAST, abuf, len); 3121d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (matches(*argv, "txqueuelen") == 0 || 313909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov strcmp(*argv, "qlen") == 0 || 314909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov matches(*argv, "txqlen") == 0) { 3151d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy NEXT_ARG(); 3161d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (qlen != -1) 3171d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy duparg("txqueuelen", *argv); 3181d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (get_integer(&qlen, *argv, 0)) 3191d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy invarg("Invalid \"txqueuelen\" value\n", *argv); 320909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov addattr_l(&req->n, sizeof(*req), IFLA_TXQLEN, &qlen, 4); 3211d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (strcmp(*argv, "mtu") == 0) { 3221d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy NEXT_ARG(); 3231d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (mtu != -1) 3241d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy duparg("mtu", *argv); 3251d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (get_integer(&mtu, *argv, 0)) 3261d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy invarg("Invalid \"mtu\" value\n", *argv); 327909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov addattr_l(&req->n, sizeof(*req), IFLA_MTU, &mtu, 4); 328e2613dc8605e56dbc53890ebbae263f93610bd41Benjamin Thery } else if (strcmp(*argv, "netns") == 0) { 329e2613dc8605e56dbc53890ebbae263f93610bd41Benjamin Thery NEXT_ARG(); 330e2613dc8605e56dbc53890ebbae263f93610bd41Benjamin Thery if (netns != -1) 331e2613dc8605e56dbc53890ebbae263f93610bd41Benjamin Thery duparg("netns", *argv); 3320dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman if ((netns = get_netns_fd(*argv)) >= 0) 3330dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman addattr_l(&req->n, sizeof(*req), IFLA_NET_NS_FD, &netns, 4); 3340dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman else if (get_integer(&netns, *argv, 0) == 0) 3350dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman addattr_l(&req->n, sizeof(*req), IFLA_NET_NS_PID, &netns, 4); 3360dc34c7713bb7055378fe5cbc720d63d0db572a1Eric W. Biederman else 337e2613dc8605e56dbc53890ebbae263f93610bd41Benjamin Thery invarg("Invalid \"netns\" value\n", *argv); 3381d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (strcmp(*argv, "multicast") == 0) { 3391d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy NEXT_ARG(); 340909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_change |= IFF_MULTICAST; 3411d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (strcmp(*argv, "on") == 0) { 342909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_flags |= IFF_MULTICAST; 3431d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (strcmp(*argv, "off") == 0) { 344909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_flags &= ~IFF_MULTICAST; 3451d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else 3461d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return on_off("multicast"); 3471d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (strcmp(*argv, "allmulticast") == 0) { 3481d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy NEXT_ARG(); 349909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_change |= IFF_ALLMULTI; 3501d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (strcmp(*argv, "on") == 0) { 351909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_flags |= IFF_ALLMULTI; 3521d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (strcmp(*argv, "off") == 0) { 353909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_flags &= ~IFF_ALLMULTI; 3541d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else 3551d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return on_off("allmulticast"); 3561d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (strcmp(*argv, "promisc") == 0) { 3571d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy NEXT_ARG(); 358909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_change |= IFF_PROMISC; 3591d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (strcmp(*argv, "on") == 0) { 360909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_flags |= IFF_PROMISC; 3611d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (strcmp(*argv, "off") == 0) { 362909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_flags &= ~IFF_PROMISC; 3631d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else 3641d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return on_off("promisc"); 3651d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (strcmp(*argv, "trailers") == 0) { 3661d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy NEXT_ARG(); 367909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_change |= IFF_NOTRAILERS; 3681d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (strcmp(*argv, "off") == 0) { 369909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_flags |= IFF_NOTRAILERS; 3701d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (strcmp(*argv, "on") == 0) { 371909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_flags &= ~IFF_NOTRAILERS; 3721d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else 3731d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return on_off("trailers"); 3741d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (strcmp(*argv, "arp") == 0) { 3751d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy NEXT_ARG(); 376909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_change |= IFF_NOARP; 3771d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (strcmp(*argv, "on") == 0) { 378909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_flags &= ~IFF_NOARP; 3791d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (strcmp(*argv, "off") == 0) { 380909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_flags |= IFF_NOARP; 3811d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else 3821d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return on_off("noarp"); 383ae7229d5f99ed9d7fd6ae11bcc726b80e8f8cb87Williams, Mitch A } else if (strcmp(*argv, "vf") == 0) { 3841598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger struct rtattr *vflist; 385ae7229d5f99ed9d7fd6ae11bcc726b80e8f8cb87Williams, Mitch A NEXT_ARG(); 386ae7229d5f99ed9d7fd6ae11bcc726b80e8f8cb87Williams, Mitch A if (get_integer(&vf, *argv, 0)) { 387ae7229d5f99ed9d7fd6ae11bcc726b80e8f8cb87Williams, Mitch A invarg("Invalid \"vf\" value\n", *argv); 388ae7229d5f99ed9d7fd6ae11bcc726b80e8f8cb87Williams, Mitch A } 3891598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger vflist = addattr_nest(&req->n, sizeof(*req), 3901598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger IFLA_VFINFO_LIST); 3911598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger len = iplink_parse_vf(vf, &argc, &argv, req); 3921598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger if (len < 0) 3931598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger return -1; 3941598b9ef7b6704af5126d632e324323703ca8112Stephen Hemminger addattr_nest_end(&req->n, vflist); 395a1e191b90c35f5ef5d7dfba5ad8b5b7a7f57a421Jiri Pirko } else if (matches(*argv, "master") == 0) { 396a1e191b90c35f5ef5d7dfba5ad8b5b7a7f57a421Jiri Pirko int ifindex; 397a1e191b90c35f5ef5d7dfba5ad8b5b7a7f57a421Jiri Pirko NEXT_ARG(); 398a1e191b90c35f5ef5d7dfba5ad8b5b7a7f57a421Jiri Pirko ifindex = ll_name_to_index(*argv); 399a1e191b90c35f5ef5d7dfba5ad8b5b7a7f57a421Jiri Pirko if (!ifindex) 400a1e191b90c35f5ef5d7dfba5ad8b5b7a7f57a421Jiri Pirko invarg("Device does not exist\n", *argv); 401a1e191b90c35f5ef5d7dfba5ad8b5b7a7f57a421Jiri Pirko addattr_l(&req->n, sizeof(*req), IFLA_MASTER, 402a1e191b90c35f5ef5d7dfba5ad8b5b7a7f57a421Jiri Pirko &ifindex, 4); 403a1e191b90c35f5ef5d7dfba5ad8b5b7a7f57a421Jiri Pirko } else if (matches(*argv, "nomaster") == 0) { 404a1e191b90c35f5ef5d7dfba5ad8b5b7a7f57a421Jiri Pirko int ifindex = 0; 405a1e191b90c35f5ef5d7dfba5ad8b5b7a7f57a421Jiri Pirko addattr_l(&req->n, sizeof(*req), IFLA_MASTER, 406a1e191b90c35f5ef5d7dfba5ad8b5b7a7f57a421Jiri Pirko &ifindex, 4); 4071d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (matches(*argv, "dynamic") == 0) { 4081d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy NEXT_ARG(); 409909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_change |= IFF_DYNAMIC; 4101d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (strcmp(*argv, "on") == 0) { 411909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_flags |= IFF_DYNAMIC; 4121d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (strcmp(*argv, "off") == 0) { 413909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_flags &= ~IFF_DYNAMIC; 4141d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else 4151d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return on_off("dynamic"); 4161d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (matches(*argv, "type") == 0) { 4171d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy NEXT_ARG(); 418909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov *type = *argv; 4191d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy argc--; argv++; 4201d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy break; 421ace9c96121b10ff8f91d79b7486bb8a5520c12dfStephen Hemminger } else if (matches(*argv, "alias") == 0) { 422ace9c96121b10ff8f91d79b7486bb8a5520c12dfStephen Hemminger NEXT_ARG(); 423ace9c96121b10ff8f91d79b7486bb8a5520c12dfStephen Hemminger addattr_l(&req->n, sizeof(*req), IFLA_IFALIAS, 424ace9c96121b10ff8f91d79b7486bb8a5520c12dfStephen Hemminger *argv, strlen(*argv)); 425ace9c96121b10ff8f91d79b7486bb8a5520c12dfStephen Hemminger argc--; argv++; 426ace9c96121b10ff8f91d79b7486bb8a5520c12dfStephen Hemminger break; 427db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru } else if (strcmp(*argv, "group") == 0) { 428db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru NEXT_ARG(); 429db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru if (*group != -1) 430db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru duparg("group", *argv); 431db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru if (rtnl_group_a2n(group, *argv)) 432db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru invarg("Invalid \"group\" value\n", *argv); 43382499282b27c82a25448dc40948920950c9a6936Stephen Hemminger } else if (strcmp(*argv, "mode") == 0) { 43482499282b27c82a25448dc40948920950c9a6936Stephen Hemminger int mode; 43582499282b27c82a25448dc40948920950c9a6936Stephen Hemminger NEXT_ARG(); 4364f2fdd44b6694f713aa638cc2222a2d7d17dfe5fStephen Hemminger mode = get_link_mode(*argv); 43782499282b27c82a25448dc40948920950c9a6936Stephen Hemminger if (mode < 0) 43882499282b27c82a25448dc40948920950c9a6936Stephen Hemminger invarg("Invalid link mode\n", *argv); 43982499282b27c82a25448dc40948920950c9a6936Stephen Hemminger addattr8(&req->n, sizeof(*req), IFLA_LINKMODE, mode); 4404f2fdd44b6694f713aa638cc2222a2d7d17dfe5fStephen Hemminger } else if (strcmp(*argv, "state") == 0) { 4414f2fdd44b6694f713aa638cc2222a2d7d17dfe5fStephen Hemminger int state; 4424f2fdd44b6694f713aa638cc2222a2d7d17dfe5fStephen Hemminger NEXT_ARG(); 4434f2fdd44b6694f713aa638cc2222a2d7d17dfe5fStephen Hemminger state = get_operstate(*argv); 4444f2fdd44b6694f713aa638cc2222a2d7d17dfe5fStephen Hemminger if (state < 0) 4454f2fdd44b6694f713aa638cc2222a2d7d17dfe5fStephen Hemminger invarg("Invalid operstate\n", *argv); 4464f2fdd44b6694f713aa638cc2222a2d7d17dfe5fStephen Hemminger 4474f2fdd44b6694f713aa638cc2222a2d7d17dfe5fStephen Hemminger addattr8(&req->n, sizeof(*req), IFLA_OPERSTATE, state); 4481d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else { 449909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov if (strcmp(*argv, "dev") == 0) { 4501d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy NEXT_ARG(); 4511d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } 452053255520216654c6914e84b0a37e86c542898bdPatrick McHardy if (matches(*argv, "help") == 0) 453053255520216654c6914e84b0a37e86c542898bdPatrick McHardy usage(); 454909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov if (*dev) 4551d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy duparg2("dev", *argv); 456909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov *dev = *argv; 4571d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } 4581d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy argc--; argv++; 4591d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } 4601d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 461909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov return ret - argc; 462909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov} 463909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov 464909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanovstatic int iplink_modify(int cmd, unsigned int flags, int argc, char **argv) 465909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov{ 466909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov int len; 467909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov char *dev = NULL; 468909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov char *name = NULL; 469909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov char *link = NULL; 470909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov char *type = NULL; 471db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru int group; 472909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov struct link_util *lu = NULL; 473909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov struct iplink_req req; 474909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov int ret; 475909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov 476909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov memset(&req, 0, sizeof(req)); 477909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov 478909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); 479909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req.n.nlmsg_flags = NLM_F_REQUEST|flags; 480909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req.n.nlmsg_type = cmd; 481909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req.i.ifi_family = preferred_family; 482909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov 483db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru ret = iplink_parse(argc, argv, &req, &name, &type, &link, &dev, &group); 484909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov if (ret < 0) 485909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov return ret; 486909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov 487909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov argc -= ret; 488909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov argv += ret; 489db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru 490db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru if (group != -1) { 491db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru if (dev) 492db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru addattr_l(&req.n, sizeof(req), IFLA_GROUP, 493db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru &group, sizeof(group)); 494db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru else { 495db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru if (argc) { 496db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru fprintf(stderr, "Garbage instead of arguments " 497db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru "\"%s ...\". Try \"ip link " 498db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru "help\".\n", *argv); 499db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru return -1; 500db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru } 501db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru if (flags & NLM_F_CREATE) { 502db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru fprintf(stderr, "group cannot be used when " 503db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru "creating devices.\n"); 504db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru return -1; 505db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru } 506db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru 507db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru req.i.ifi_index = 0; 508db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru addattr32(&req.n, sizeof(req), IFLA_GROUP, group); 509cd70f3f522e04b4d2fa80ae10292379bf223a53bStephen Hemminger if (rtnl_talk(&rth, &req.n, 0, 0, NULL) < 0) 510db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru exit(2); 511db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru return 0; 512db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru } 513db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru } 514db02608b6f408998ea8c823fb791cead3e574f50Vlad Dogaru 5151d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy ll_init_map(&rth); 5161d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 5171d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (!(flags & NLM_F_CREATE)) { 5181d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (!dev) { 5191d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy fprintf(stderr, "Not enough information: \"dev\" " 5201d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy "argument is required.\n"); 5211d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy exit(-1); 5221d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } 5231d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 5241d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy req.i.ifi_index = ll_name_to_index(dev); 5251d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (req.i.ifi_index == 0) { 5261d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy fprintf(stderr, "Cannot find device \"%s\"\n", dev); 5271d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return -1; 5281d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } 5291d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else { 5301d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy /* Allow "ip link add dev" and "ip link add name" */ 5311d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (!name) 5321d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy name = dev; 5331d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 5341d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (link) { 5351d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy int ifindex; 5361d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 5371d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy ifindex = ll_name_to_index(link); 5381d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (ifindex == 0) { 5391d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy fprintf(stderr, "Cannot find device \"%s\"\n", 5401d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy link); 5411d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return -1; 5421d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } 5431d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy addattr_l(&req.n, sizeof(req), IFLA_LINK, &ifindex, 4); 5441d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } 5451d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } 5461d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 5471d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (name) { 5481d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy len = strlen(name) + 1; 549ca78b0e7d4042be7f7283d551d433b76da7f312bPatrick McHardy if (len == 1) 550ca78b0e7d4042be7f7283d551d433b76da7f312bPatrick McHardy invarg("\"\" is not a valid device identifier\n", "name"); 5511d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (len > IFNAMSIZ) 552ca78b0e7d4042be7f7283d551d433b76da7f312bPatrick McHardy invarg("\"name\" too long\n", name); 5531d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy addattr_l(&req.n, sizeof(req), IFLA_IFNAME, name, len); 5541d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } 5551d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 55609fa32794154a69d4a6fbc58c1ee02dbe26a99e9Stephen Hemminger if (type) { 55709fa32794154a69d4a6fbc58c1ee02dbe26a99e9Stephen Hemminger struct rtattr *linkinfo = NLMSG_TAIL(&req.n); 55809fa32794154a69d4a6fbc58c1ee02dbe26a99e9Stephen Hemminger addattr_l(&req.n, sizeof(req), IFLA_LINKINFO, NULL, 0); 55909fa32794154a69d4a6fbc58c1ee02dbe26a99e9Stephen Hemminger addattr_l(&req.n, sizeof(req), IFLA_INFO_KIND, type, 56009fa32794154a69d4a6fbc58c1ee02dbe26a99e9Stephen Hemminger strlen(type)); 56109fa32794154a69d4a6fbc58c1ee02dbe26a99e9Stephen Hemminger 56209fa32794154a69d4a6fbc58c1ee02dbe26a99e9Stephen Hemminger lu = get_link_kind(type); 56309fa32794154a69d4a6fbc58c1ee02dbe26a99e9Stephen Hemminger if (lu && argc) { 56409fa32794154a69d4a6fbc58c1ee02dbe26a99e9Stephen Hemminger struct rtattr * data = NLMSG_TAIL(&req.n); 56509fa32794154a69d4a6fbc58c1ee02dbe26a99e9Stephen Hemminger addattr_l(&req.n, sizeof(req), IFLA_INFO_DATA, NULL, 0); 56609fa32794154a69d4a6fbc58c1ee02dbe26a99e9Stephen Hemminger 56709fa32794154a69d4a6fbc58c1ee02dbe26a99e9Stephen Hemminger if (lu->parse_opt && 56809fa32794154a69d4a6fbc58c1ee02dbe26a99e9Stephen Hemminger lu->parse_opt(lu, argc, argv, &req.n)) 56909fa32794154a69d4a6fbc58c1ee02dbe26a99e9Stephen Hemminger return -1; 57009fa32794154a69d4a6fbc58c1ee02dbe26a99e9Stephen Hemminger 57109fa32794154a69d4a6fbc58c1ee02dbe26a99e9Stephen Hemminger data->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)data; 57209fa32794154a69d4a6fbc58c1ee02dbe26a99e9Stephen Hemminger } else if (argc) { 57309fa32794154a69d4a6fbc58c1ee02dbe26a99e9Stephen Hemminger if (matches(*argv, "help") == 0) 57409fa32794154a69d4a6fbc58c1ee02dbe26a99e9Stephen Hemminger usage(); 57509fa32794154a69d4a6fbc58c1ee02dbe26a99e9Stephen Hemminger fprintf(stderr, "Garbage instead of arguments \"%s ...\". " 57609fa32794154a69d4a6fbc58c1ee02dbe26a99e9Stephen Hemminger "Try \"ip link help\".\n", *argv); 57709fa32794154a69d4a6fbc58c1ee02dbe26a99e9Stephen Hemminger return -1; 57809fa32794154a69d4a6fbc58c1ee02dbe26a99e9Stephen Hemminger } 57909fa32794154a69d4a6fbc58c1ee02dbe26a99e9Stephen Hemminger linkinfo->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)linkinfo; 58009fa32794154a69d4a6fbc58c1ee02dbe26a99e9Stephen Hemminger } else if (flags & NLM_F_CREATE) { 58109fa32794154a69d4a6fbc58c1ee02dbe26a99e9Stephen Hemminger fprintf(stderr, "Not enough information: \"type\" argument " 58209fa32794154a69d4a6fbc58c1ee02dbe26a99e9Stephen Hemminger "is required\n"); 58309fa32794154a69d4a6fbc58c1ee02dbe26a99e9Stephen Hemminger return -1; 58409fa32794154a69d4a6fbc58c1ee02dbe26a99e9Stephen Hemminger } 58509fa32794154a69d4a6fbc58c1ee02dbe26a99e9Stephen Hemminger 586cd70f3f522e04b4d2fa80ae10292379bf223a53bStephen Hemminger if (rtnl_talk(&rth, &req.n, 0, 0, NULL) < 0) 5871d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy exit(2); 5881d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 5891d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return 0; 5901d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy} 5911d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 5921d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy#if IPLINK_IOCTL_COMPAT 593aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int get_ctl_fd(void) 594aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 595aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int s_errno; 596aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int fd; 597aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 598aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fd = socket(PF_INET, SOCK_DGRAM, 0); 599aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (fd >= 0) 600aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return fd; 601aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger s_errno = errno; 602aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fd = socket(PF_PACKET, SOCK_DGRAM, 0); 603aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (fd >= 0) 604aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return fd; 605aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fd = socket(PF_INET6, SOCK_DGRAM, 0); 606aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (fd >= 0) 607aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return fd; 608aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger errno = s_errno; 609aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("Cannot create control socket"); 610aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 611aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 612aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 61371058eb8ef128aa99666dc4e6664e7632e12a1b9osdl.net!shemmingerstatic int do_chflags(const char *dev, __u32 flags, __u32 mask) 614aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 615aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct ifreq ifr; 616aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int fd; 617aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int err; 618aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 61971058eb8ef128aa99666dc4e6664e7632e12a1b9osdl.net!shemminger strncpy(ifr.ifr_name, dev, IFNAMSIZ); 620aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fd = get_ctl_fd(); 621aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (fd < 0) 622aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 623aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger err = ioctl(fd, SIOCGIFFLAGS, &ifr); 624aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (err) { 625aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("SIOCGIFFLAGS"); 626aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(fd); 627aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 628aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 629aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if ((ifr.ifr_flags^flags)&mask) { 630aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ifr.ifr_flags &= ~mask; 631aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ifr.ifr_flags |= mask&flags; 632aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger err = ioctl(fd, SIOCSIFFLAGS, &ifr); 633aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (err) 634aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("SIOCSIFFLAGS"); 635aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 636aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(fd); 637aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return err; 638aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 639aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 64071058eb8ef128aa99666dc4e6664e7632e12a1b9osdl.net!shemmingerstatic int do_changename(const char *dev, const char *newdev) 641aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 642aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct ifreq ifr; 643aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int fd; 644aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int err; 645aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 64671058eb8ef128aa99666dc4e6664e7632e12a1b9osdl.net!shemminger strncpy(ifr.ifr_name, dev, IFNAMSIZ); 64771058eb8ef128aa99666dc4e6664e7632e12a1b9osdl.net!shemminger strncpy(ifr.ifr_newname, newdev, IFNAMSIZ); 648aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fd = get_ctl_fd(); 649aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (fd < 0) 650aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 651aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger err = ioctl(fd, SIOCSIFNAME, &ifr); 652aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (err) { 653aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("SIOCSIFNAME"); 654aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(fd); 655aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 656aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 657aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(fd); 658aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return err; 659aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 660aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 66171058eb8ef128aa99666dc4e6664e7632e12a1b9osdl.net!shemmingerstatic int set_qlen(const char *dev, int qlen) 662aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 663aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct ifreq ifr; 664aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int s; 665aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 666aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger s = get_ctl_fd(); 667aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (s < 0) 668aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 669aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 670aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(&ifr, 0, sizeof(ifr)); 671ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger strncpy(ifr.ifr_name, dev, IFNAMSIZ); 672ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger ifr.ifr_qlen = qlen; 673aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (ioctl(s, SIOCSIFTXQLEN, &ifr) < 0) { 674aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("SIOCSIFXQLEN"); 675aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(s); 676aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 677aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 678aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(s); 679aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 680ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger return 0; 681aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 682aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 68371058eb8ef128aa99666dc4e6664e7632e12a1b9osdl.net!shemmingerstatic int set_mtu(const char *dev, int mtu) 684aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 685aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct ifreq ifr; 686aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int s; 687aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 688aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger s = get_ctl_fd(); 689aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (s < 0) 690aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 691aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 692aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(&ifr, 0, sizeof(ifr)); 693ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger strncpy(ifr.ifr_name, dev, IFNAMSIZ); 694ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger ifr.ifr_mtu = mtu; 695aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (ioctl(s, SIOCSIFMTU, &ifr) < 0) { 696aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("SIOCSIFMTU"); 697aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(s); 698aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 699aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 700aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(s); 701aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 702ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger return 0; 703aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 704aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 70571058eb8ef128aa99666dc4e6664e7632e12a1b9osdl.net!shemmingerstatic int get_address(const char *dev, int *htype) 706aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 707aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct ifreq ifr; 708aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct sockaddr_ll me; 709f332d169246447bd5e258ac03d5ee840a70adb1eshemminger socklen_t alen; 710aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int s; 711aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 712aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger s = socket(PF_PACKET, SOCK_DGRAM, 0); 713ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger if (s < 0) { 714aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("socket(PF_PACKET)"); 715aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 716aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 717aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 718aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(&ifr, 0, sizeof(ifr)); 71971058eb8ef128aa99666dc4e6664e7632e12a1b9osdl.net!shemminger strncpy(ifr.ifr_name, dev, IFNAMSIZ); 720aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) { 721aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("SIOCGIFINDEX"); 722aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(s); 723aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 724aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 725aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 726aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(&me, 0, sizeof(me)); 727aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger me.sll_family = AF_PACKET; 728aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger me.sll_ifindex = ifr.ifr_ifindex; 729aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger me.sll_protocol = htons(ETH_P_LOOP); 730aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (bind(s, (struct sockaddr*)&me, sizeof(me)) == -1) { 731aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("bind"); 732aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(s); 733aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 734aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 735aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 736aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger alen = sizeof(me); 737aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (getsockname(s, (struct sockaddr*)&me, &alen) == -1) { 738aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("getsockname"); 739aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(s); 740aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 741aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 742aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(s); 743aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *htype = me.sll_hatype; 744aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return me.sll_halen; 745aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 746aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 747ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemmingerstatic int parse_address(const char *dev, int hatype, int halen, 7487b5657545dc246ae37690d660597e8fa37040205shemminger char *lla, struct ifreq *ifr) 749aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 750aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int alen; 751aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 752aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(ifr, 0, sizeof(*ifr)); 75371058eb8ef128aa99666dc4e6664e7632e12a1b9osdl.net!shemminger strncpy(ifr->ifr_name, dev, IFNAMSIZ); 754aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ifr->ifr_hwaddr.sa_family = hatype; 755aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger alen = ll_addr_a2n(ifr->ifr_hwaddr.sa_data, 14, lla); 756aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (alen < 0) 757aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 758aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (alen != halen) { 759aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Wrong address (%s) length: expected %d bytes\n", lla, halen); 760aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 761aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 762ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger return 0; 763aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 764aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 765aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int set_address(struct ifreq *ifr, int brd) 766aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 767aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int s; 768aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 769aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger s = get_ctl_fd(); 770aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (s < 0) 771aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 772aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (ioctl(s, brd?SIOCSIFHWBROADCAST:SIOCSIFHWADDR, ifr) < 0) { 773aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror(brd?"SIOCSIFHWBROADCAST":"SIOCSIFHWADDR"); 774aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(s); 775aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 776aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 777aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(s); 778ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger return 0; 779aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 780aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 781aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 782aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int do_set(int argc, char **argv) 783aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 784aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char *dev = NULL; 785aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger __u32 mask = 0; 786aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger __u32 flags = 0; 787aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int qlen = -1; 788aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int mtu = -1; 789aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char *newaddr = NULL; 790aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char *newbrd = NULL; 791aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct ifreq ifr0, ifr1; 792aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char *newname = NULL; 793aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int htype, halen; 794aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 795aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger while (argc > 0) { 796aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (strcmp(*argv, "up") == 0) { 797aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger mask |= IFF_UP; 798aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger flags |= IFF_UP; 799aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "down") == 0) { 800aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger mask |= IFF_UP; 801aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger flags &= ~IFF_UP; 802aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "name") == 0) { 803aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 804aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger newname = *argv; 805aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (matches(*argv, "address") == 0) { 806aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 807aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger newaddr = *argv; 808aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (matches(*argv, "broadcast") == 0 || 809aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger strcmp(*argv, "brd") == 0) { 810aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 811aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger newbrd = *argv; 812aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (matches(*argv, "txqueuelen") == 0 || 813aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger strcmp(*argv, "qlen") == 0 || 814aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger matches(*argv, "txqlen") == 0) { 815aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 816aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (qlen != -1) 817aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger duparg("txqueuelen", *argv); 818aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (get_integer(&qlen, *argv, 0)) 819aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger invarg("Invalid \"txqueuelen\" value\n", *argv); 820aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "mtu") == 0) { 821aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 822aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (mtu != -1) 823aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger duparg("mtu", *argv); 824aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (get_integer(&mtu, *argv, 0)) 825aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger invarg("Invalid \"mtu\" value\n", *argv); 826aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "multicast") == 0) { 827aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 828aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger mask |= IFF_MULTICAST; 829aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (strcmp(*argv, "on") == 0) { 830aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger flags |= IFF_MULTICAST; 831aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "off") == 0) { 832aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger flags &= ~IFF_MULTICAST; 833aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else 834aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return on_off("multicast"); 835d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger } else if (strcmp(*argv, "allmulticast") == 0) { 836d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger NEXT_ARG(); 837d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger mask |= IFF_ALLMULTI; 838d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger if (strcmp(*argv, "on") == 0) { 839d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger flags |= IFF_ALLMULTI; 840d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger } else if (strcmp(*argv, "off") == 0) { 841d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger flags &= ~IFF_ALLMULTI; 842d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger } else 843d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger return on_off("allmulticast"); 844d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger } else if (strcmp(*argv, "promisc") == 0) { 845d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger NEXT_ARG(); 846d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger mask |= IFF_PROMISC; 847d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger if (strcmp(*argv, "on") == 0) { 848d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger flags |= IFF_PROMISC; 849d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger } else if (strcmp(*argv, "off") == 0) { 850d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger flags &= ~IFF_PROMISC; 851d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger } else 852d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger return on_off("promisc"); 853d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger } else if (strcmp(*argv, "trailers") == 0) { 854d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger NEXT_ARG(); 855d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger mask |= IFF_NOTRAILERS; 856d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger if (strcmp(*argv, "off") == 0) { 857d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger flags |= IFF_NOTRAILERS; 858d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger } else if (strcmp(*argv, "on") == 0) { 859d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger flags &= ~IFF_NOTRAILERS; 860d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger } else 861d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger return on_off("trailers"); 862aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "arp") == 0) { 863aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 864aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger mask |= IFF_NOARP; 865aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (strcmp(*argv, "on") == 0) { 866aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger flags &= ~IFF_NOARP; 867aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "off") == 0) { 868aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger flags |= IFF_NOARP; 869aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else 870aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return on_off("noarp"); 871aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (matches(*argv, "dynamic") == 0) { 872aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 873aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger mask |= IFF_DYNAMIC; 874aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (strcmp(*argv, "on") == 0) { 875aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger flags |= IFF_DYNAMIC; 876aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "off") == 0) { 877aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger flags &= ~IFF_DYNAMIC; 878aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else 879aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return on_off("dynamic"); 880aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else { 881aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (strcmp(*argv, "dev") == 0) { 882aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 883aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 884aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (matches(*argv, "help") == 0) 885aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger usage(); 886aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (dev) 887aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger duparg2("dev", *argv); 888aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dev = *argv; 889aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 890aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger argc--; argv++; 891aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 892aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 893aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (!dev) { 894aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Not enough of information: \"dev\" argument is required.\n"); 895aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(-1); 896aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 897aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 898aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (newaddr || newbrd) { 899aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger halen = get_address(dev, &htype); 900aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (halen < 0) 901aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 902aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (newaddr) { 903aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (parse_address(dev, htype, halen, newaddr, &ifr0) < 0) 904aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 905aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 906aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (newbrd) { 907aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (parse_address(dev, htype, halen, newbrd, &ifr1) < 0) 908ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger return -1; 909aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 910aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 911aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 912aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (newname && strcmp(dev, newname)) { 913ca78b0e7d4042be7f7283d551d433b76da7f312bPatrick McHardy if (strlen(newname) == 0) 914ca78b0e7d4042be7f7283d551d433b76da7f312bPatrick McHardy invarg("\"\" is not a valid device identifier\n", "name"); 915aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (do_changename(dev, newname) < 0) 916aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 917aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dev = newname; 918aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 919ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger if (qlen != -1) { 920aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (set_qlen(dev, qlen) < 0) 921ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger return -1; 922aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 923ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger if (mtu != -1) { 924aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (set_mtu(dev, mtu) < 0) 925ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger return -1; 926aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 927aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (newaddr || newbrd) { 928aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (newbrd) { 929aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (set_address(&ifr1, 1) < 0) 930ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger return -1; 931aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 932aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (newaddr) { 933aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (set_address(&ifr0, 0) < 0) 934aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 935aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 936aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 937aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (mask) 938aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return do_chflags(dev, flags, mask); 939aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 940aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 9411d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy#endif /* IPLINK_IOCTL_COMPAT */ 942aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 943aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint do_iplink(int argc, char **argv) 944aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 945aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (argc > 0) { 9461d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (iplink_have_newlink()) { 9471d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (matches(*argv, "add") == 0) 9481d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return iplink_modify(RTM_NEWLINK, 9491d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy NLM_F_CREATE|NLM_F_EXCL, 9501d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy argc-1, argv+1); 9511d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (matches(*argv, "set") == 0 || 9521d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy matches(*argv, "change") == 0) 9531d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return iplink_modify(RTM_NEWLINK, 0, 9541d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy argc-1, argv+1); 9551d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (matches(*argv, "replace") == 0) 9561d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return iplink_modify(RTM_NEWLINK, 9571d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy NLM_F_CREATE|NLM_F_REPLACE, 9581d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy argc-1, argv+1); 9591d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (matches(*argv, "delete") == 0) 9601d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return iplink_modify(RTM_DELLINK, 0, 9611d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy argc-1, argv+1); 9621d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else { 9631d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy#if IPLINK_IOCTL_COMPAT 9641d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (matches(*argv, "set") == 0) 9651d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return do_set(argc-1, argv+1); 9661d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy#endif 9671d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } 968aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (matches(*argv, "show") == 0 || 969aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger matches(*argv, "lst") == 0 || 970aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger matches(*argv, "list") == 0) 971aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return ipaddr_list_link(argc-1, argv+1); 972aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (matches(*argv, "help") == 0) 973aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger usage(); 974aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else 975aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return ipaddr_list_link(0, NULL); 976aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 977aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Command \"%s\" is unknown, try \"ip link help\".\n", *argv); 978aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(-1); 979aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 980