iplink.c revision 909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5
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 36aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 37aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic void usage(void) __attribute__((noreturn)); 38aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 39aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingervoid iplink_usage(void) 40aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 41d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger fprintf(stderr, "Usage: ip link set DEVICE { up | down |\n"); 42d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger fprintf(stderr, " arp { on | off } |\n"); 43aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, " dynamic { on | off } |\n"); 44d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger fprintf(stderr, " multicast { on | off } |\n"); 45d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger fprintf(stderr, " allmulticast { on | off } |\n"); 46d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger fprintf(stderr, " promisc { on | off } |\n"); 47d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger fprintf(stderr, " trailers { on | off } |\n"); 48d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger fprintf(stderr, " txqueuelen PACKETS |\n"); 49aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, " name NEWNAME |\n"); 50aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, " address LLADDR | broadcast LLADDR |\n"); 51aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, " mtu MTU }\n"); 52aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, " ip link show [ DEVICE ]\n"); 53aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(-1); 54aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 55aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 56aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic void usage(void) 57aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 58aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger iplink_usage(); 59aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 60aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 61aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int on_off(char *msg) 62aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 63aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Error: argument of \"%s\" must be \"on\" or \"off\"\n", msg); 64aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 65aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 66aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 671d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardystatic void *BODY; /* cached dlopen(NULL) handle */ 681d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardystatic struct link_util *linkutil_list; 691d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 701d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardystruct link_util *get_link_kind(const char *id) 711d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy{ 721d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy void *dlh; 731d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy char buf[256]; 741d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy struct link_util *l; 751d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 761d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy for (l = linkutil_list; l; l = l->next) 771d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (strcmp(l->id, id) == 0) 781d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return l; 791d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 801d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy snprintf(buf, sizeof(buf), "/usr/lib/ip/link_%s.so", id); 811d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy dlh = dlopen(buf, RTLD_LAZY); 821d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (dlh == NULL) { 831d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy /* look in current binary, only open once */ 841d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy dlh = BODY; 851d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (dlh == NULL) { 861d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy dlh = BODY = dlopen(NULL, RTLD_LAZY); 871d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (dlh == NULL) 881d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return NULL; 891d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } 901d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } 911d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 921d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy snprintf(buf, sizeof(buf), "%s_link_util", id); 931d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy l = dlsym(dlh, buf); 941d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (l == NULL) 951d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return NULL; 961d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 971d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy l->next = linkutil_list; 981d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy linkutil_list = l; 991d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return l; 1001d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy} 1011d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 1021d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy#if IPLINK_IOCTL_COMPAT 1031d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardystatic int have_rtnl_newlink = -1; 1041d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 1051d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardystatic int accept_msg(const struct sockaddr_nl *who, 1061d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy struct nlmsghdr *n, void *arg) 1071d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy{ 1081d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy struct nlmsgerr *err = (struct nlmsgerr *)NLMSG_DATA(n); 1091d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 11066e529f579f45351828fc82d6ba2629cc6eb3dddPatrick McHardy if (n->nlmsg_type == NLMSG_ERROR && 11166e529f579f45351828fc82d6ba2629cc6eb3dddPatrick McHardy (err->error == -EOPNOTSUPP || err->error == -EINVAL)) 1121d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy have_rtnl_newlink = 0; 1131d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy else 1141d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy have_rtnl_newlink = 1; 1151d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return -1; 1161d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy} 1171d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 1181d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardystatic int iplink_have_newlink(void) 1191d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy{ 1201d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy struct { 1211d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy struct nlmsghdr n; 1221d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy struct ifinfomsg i; 1231d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy char buf[1024]; 1241d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } req; 1251d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 1261d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (have_rtnl_newlink < 0) { 1271d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy memset(&req, 0, sizeof(req)); 1281d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 1291d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); 1301d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy req.n.nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK; 1311d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy req.n.nlmsg_type = RTM_NEWLINK; 1321d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy req.i.ifi_family = AF_UNSPEC; 1331d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 1341d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy rtnl_send(&rth, (char *)&req.n, req.n.nlmsg_len); 1351d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy rtnl_listen(&rth, accept_msg, NULL); 1361d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } 1371d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return have_rtnl_newlink; 1381d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy} 1391d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy#else /* IPLINK_IOCTL_COMPAT */ 1401d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardystatic int iplink_have_newlink(void) 1411d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy{ 1421d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return 1; 1431d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy} 1441d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy#endif /* ! IPLINK_IOCTL_COMPAT */ 1451d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 146909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanovstruct iplink_req { 147909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov struct nlmsghdr n; 148909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov struct ifinfomsg i; 149909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov char buf[1024]; 150909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov}; 151909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov 152909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanovint iplink_parse(int argc, char **argv, struct iplink_req *req, 153909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov char **name, char **type, char **link, char **dev) 1541d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy{ 155909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov int ret, len; 156909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov char abuf[32]; 1571d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy int qlen = -1; 1581d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy int mtu = -1; 1591d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 160909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov ret = argc; 1611d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 1621d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy while (argc > 0) { 1631d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (strcmp(*argv, "up") == 0) { 164909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_change |= IFF_UP; 165909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_flags |= IFF_UP; 1661d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (strcmp(*argv, "down") == 0) { 167909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_change |= IFF_UP; 168909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_flags &= ~IFF_UP; 1691d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (strcmp(*argv, "name") == 0) { 1701d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy NEXT_ARG(); 171909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov *name = *argv; 1721d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (matches(*argv, "link") == 0) { 1731d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy NEXT_ARG(); 174909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov *link = *argv; 1751d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (matches(*argv, "address") == 0) { 1761d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy NEXT_ARG(); 1771d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy len = ll_addr_a2n(abuf, sizeof(abuf), *argv); 178909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov addattr_l(&req->n, sizeof(*req), IFLA_ADDRESS, abuf, len); 1791d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (matches(*argv, "broadcast") == 0 || 180909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov strcmp(*argv, "brd") == 0) { 1811d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy NEXT_ARG(); 1821d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy len = ll_addr_a2n(abuf, sizeof(abuf), *argv); 183909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov addattr_l(&req->n, sizeof(*req), IFLA_BROADCAST, abuf, len); 1841d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (matches(*argv, "txqueuelen") == 0 || 185909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov strcmp(*argv, "qlen") == 0 || 186909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov matches(*argv, "txqlen") == 0) { 1871d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy NEXT_ARG(); 1881d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (qlen != -1) 1891d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy duparg("txqueuelen", *argv); 1901d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (get_integer(&qlen, *argv, 0)) 1911d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy invarg("Invalid \"txqueuelen\" value\n", *argv); 192909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov addattr_l(&req->n, sizeof(*req), IFLA_TXQLEN, &qlen, 4); 1931d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (strcmp(*argv, "mtu") == 0) { 1941d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy NEXT_ARG(); 1951d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (mtu != -1) 1961d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy duparg("mtu", *argv); 1971d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (get_integer(&mtu, *argv, 0)) 1981d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy invarg("Invalid \"mtu\" value\n", *argv); 199909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov addattr_l(&req->n, sizeof(*req), IFLA_MTU, &mtu, 4); 2001d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (strcmp(*argv, "multicast") == 0) { 2011d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy NEXT_ARG(); 202909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_change |= IFF_MULTICAST; 2031d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (strcmp(*argv, "on") == 0) { 204909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_flags |= IFF_MULTICAST; 2051d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (strcmp(*argv, "off") == 0) { 206909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_flags &= ~IFF_MULTICAST; 2071d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else 2081d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return on_off("multicast"); 2091d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (strcmp(*argv, "allmulticast") == 0) { 2101d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy NEXT_ARG(); 211909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_change |= IFF_ALLMULTI; 2121d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (strcmp(*argv, "on") == 0) { 213909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_flags |= IFF_ALLMULTI; 2141d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (strcmp(*argv, "off") == 0) { 215909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_flags &= ~IFF_ALLMULTI; 2161d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else 2171d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return on_off("allmulticast"); 2181d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (strcmp(*argv, "promisc") == 0) { 2191d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy NEXT_ARG(); 220909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_change |= IFF_PROMISC; 2211d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (strcmp(*argv, "on") == 0) { 222909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_flags |= IFF_PROMISC; 2231d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (strcmp(*argv, "off") == 0) { 224909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_flags &= ~IFF_PROMISC; 2251d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else 2261d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return on_off("promisc"); 2271d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (strcmp(*argv, "trailers") == 0) { 2281d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy NEXT_ARG(); 229909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_change |= IFF_NOTRAILERS; 2301d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (strcmp(*argv, "off") == 0) { 231909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_flags |= IFF_NOTRAILERS; 2321d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (strcmp(*argv, "on") == 0) { 233909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_flags &= ~IFF_NOTRAILERS; 2341d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else 2351d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return on_off("trailers"); 2361d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (strcmp(*argv, "arp") == 0) { 2371d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy NEXT_ARG(); 238909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_change |= IFF_NOARP; 2391d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (strcmp(*argv, "on") == 0) { 240909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_flags &= ~IFF_NOARP; 2411d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (strcmp(*argv, "off") == 0) { 242909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_flags |= IFF_NOARP; 2431d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else 2441d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return on_off("noarp"); 2451d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy#ifdef IFF_DYNAMIC 2461d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (matches(*argv, "dynamic") == 0) { 2471d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy NEXT_ARG(); 248909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_change |= IFF_DYNAMIC; 2491d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (strcmp(*argv, "on") == 0) { 250909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_flags |= IFF_DYNAMIC; 2511d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (strcmp(*argv, "off") == 0) { 252909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req->i.ifi_flags &= ~IFF_DYNAMIC; 2531d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else 2541d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return on_off("dynamic"); 2551d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy#endif 2561d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (matches(*argv, "type") == 0) { 2571d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy NEXT_ARG(); 258909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov *type = *argv; 2591d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy argc--; argv++; 2601d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy break; 2611d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else { 262909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov if (strcmp(*argv, "dev") == 0) { 2631d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy NEXT_ARG(); 2641d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } 265909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov if (*dev) 2661d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy duparg2("dev", *argv); 267909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov *dev = *argv; 2681d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } 2691d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy argc--; argv++; 2701d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } 2711d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 272909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov return ret - argc; 273909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov} 274909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov 275909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanovstatic int iplink_modify(int cmd, unsigned int flags, int argc, char **argv) 276909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov{ 277909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov int len; 278909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov char *dev = NULL; 279909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov char *name = NULL; 280909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov char *link = NULL; 281909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov char *type = NULL; 282909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov struct link_util *lu = NULL; 283909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov struct iplink_req req; 284909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov int ret; 285909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov 286909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov memset(&req, 0, sizeof(req)); 287909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov 288909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); 289909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req.n.nlmsg_flags = NLM_F_REQUEST|flags; 290909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req.n.nlmsg_type = cmd; 291909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov req.i.ifi_family = preferred_family; 292909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov 293909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov ret = iplink_parse(argc, argv, &req, &name, &type, &link, &dev); 294909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov if (ret < 0) 295909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov return ret; 296909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov 297909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov argc -= ret; 298909dfe2c7ebcfe853b2fe4f995be1c4681d5a2a5Pavel Emelyanov argv += ret; 2991d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy ll_init_map(&rth); 3001d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 3011d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (type) { 3021d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy struct rtattr *linkinfo = NLMSG_TAIL(&req.n); 3031d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy addattr_l(&req.n, sizeof(req), IFLA_LINKINFO, NULL, 0); 3041d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy addattr_l(&req.n, sizeof(req), IFLA_INFO_KIND, type, 3051d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy strlen(type)); 3061d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 3071d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy lu = get_link_kind(type); 3081d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (lu && argc) { 3091d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy struct rtattr * data = NLMSG_TAIL(&req.n); 3101d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy addattr_l(&req.n, sizeof(req), IFLA_INFO_DATA, NULL, 0); 3111d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 3121d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (lu->parse_opt && 3131d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy lu->parse_opt(lu, argc, argv, &req.n)) 3141d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return -1; 3151d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 3161d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy data->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)data; 3171d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else if (argc) { 3181d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (matches(*argv, "help") == 0) 3191d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy usage(); 3201d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy fprintf(stderr, "Garbage instead of arguments \"%s ...\". " 3211d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy "Try \"ip link help\".\n", *argv); 3221d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return -1; 3231d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } 3241d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy linkinfo->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)linkinfo; 3251d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } 3261d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 3271d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (!(flags & NLM_F_CREATE)) { 3281d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (!dev) { 3291d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy fprintf(stderr, "Not enough information: \"dev\" " 3301d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy "argument is required.\n"); 3311d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy exit(-1); 3321d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } 3331d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 3341d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy req.i.ifi_index = ll_name_to_index(dev); 3351d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (req.i.ifi_index == 0) { 3361d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy fprintf(stderr, "Cannot find device \"%s\"\n", dev); 3371d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return -1; 3381d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } 3391d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else { 3401d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy /* Allow "ip link add dev" and "ip link add name" */ 3411d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (!name) 3421d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy name = dev; 3431d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 3441d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (link) { 3451d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy int ifindex; 3461d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 3471d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy ifindex = ll_name_to_index(link); 3481d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (ifindex == 0) { 3491d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy fprintf(stderr, "Cannot find device \"%s\"\n", 3501d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy link); 3511d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return -1; 3521d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } 3531d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy addattr_l(&req.n, sizeof(req), IFLA_LINK, &ifindex, 4); 3541d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } 3551d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } 3561d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 3571d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (name) { 3581d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy len = strlen(name) + 1; 359ca78b0e7d4042be7f7283d551d433b76da7f312bPatrick McHardy if (len == 1) 360ca78b0e7d4042be7f7283d551d433b76da7f312bPatrick McHardy invarg("\"\" is not a valid device identifier\n", "name"); 3611d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (len > IFNAMSIZ) 362ca78b0e7d4042be7f7283d551d433b76da7f312bPatrick McHardy invarg("\"name\" too long\n", name); 3631d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy addattr_l(&req.n, sizeof(req), IFLA_IFNAME, name, len); 3641d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } 3651d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 3661d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) 3671d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy exit(2); 3681d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 3691d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return 0; 3701d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy} 3711d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy 3721d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy#if IPLINK_IOCTL_COMPAT 373aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int get_ctl_fd(void) 374aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 375aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int s_errno; 376aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int fd; 377aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 378aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fd = socket(PF_INET, SOCK_DGRAM, 0); 379aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (fd >= 0) 380aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return fd; 381aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger s_errno = errno; 382aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fd = socket(PF_PACKET, SOCK_DGRAM, 0); 383aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (fd >= 0) 384aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return fd; 385aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fd = socket(PF_INET6, SOCK_DGRAM, 0); 386aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (fd >= 0) 387aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return fd; 388aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger errno = s_errno; 389aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("Cannot create control socket"); 390aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 391aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 392aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 39371058eb8ef128aa99666dc4e6664e7632e12a1b9osdl.net!shemmingerstatic int do_chflags(const char *dev, __u32 flags, __u32 mask) 394aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 395aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct ifreq ifr; 396aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int fd; 397aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int err; 398aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 39971058eb8ef128aa99666dc4e6664e7632e12a1b9osdl.net!shemminger strncpy(ifr.ifr_name, dev, IFNAMSIZ); 400aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fd = get_ctl_fd(); 401aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (fd < 0) 402aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 403aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger err = ioctl(fd, SIOCGIFFLAGS, &ifr); 404aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (err) { 405aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("SIOCGIFFLAGS"); 406aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(fd); 407aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 408aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 409aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if ((ifr.ifr_flags^flags)&mask) { 410aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ifr.ifr_flags &= ~mask; 411aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ifr.ifr_flags |= mask&flags; 412aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger err = ioctl(fd, SIOCSIFFLAGS, &ifr); 413aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (err) 414aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("SIOCSIFFLAGS"); 415aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 416aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(fd); 417aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return err; 418aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 419aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 42071058eb8ef128aa99666dc4e6664e7632e12a1b9osdl.net!shemmingerstatic int do_changename(const char *dev, const char *newdev) 421aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 422aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct ifreq ifr; 423aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int fd; 424aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int err; 425aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 42671058eb8ef128aa99666dc4e6664e7632e12a1b9osdl.net!shemminger strncpy(ifr.ifr_name, dev, IFNAMSIZ); 42771058eb8ef128aa99666dc4e6664e7632e12a1b9osdl.net!shemminger strncpy(ifr.ifr_newname, newdev, IFNAMSIZ); 428aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fd = get_ctl_fd(); 429aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (fd < 0) 430aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 431aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger err = ioctl(fd, SIOCSIFNAME, &ifr); 432aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (err) { 433aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("SIOCSIFNAME"); 434aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(fd); 435aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 436aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 437aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(fd); 438aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return err; 439aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 440aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 44171058eb8ef128aa99666dc4e6664e7632e12a1b9osdl.net!shemmingerstatic int set_qlen(const char *dev, int qlen) 442aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 443aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct ifreq ifr; 444aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int s; 445aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 446aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger s = get_ctl_fd(); 447aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (s < 0) 448aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 449aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 450aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(&ifr, 0, sizeof(ifr)); 451ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger strncpy(ifr.ifr_name, dev, IFNAMSIZ); 452ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger ifr.ifr_qlen = qlen; 453aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (ioctl(s, SIOCSIFTXQLEN, &ifr) < 0) { 454aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("SIOCSIFXQLEN"); 455aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(s); 456aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 457aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 458aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(s); 459aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 460ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger return 0; 461aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 462aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 46371058eb8ef128aa99666dc4e6664e7632e12a1b9osdl.net!shemmingerstatic int set_mtu(const char *dev, int mtu) 464aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 465aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct ifreq ifr; 466aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int s; 467aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 468aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger s = get_ctl_fd(); 469aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (s < 0) 470aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 471aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 472aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(&ifr, 0, sizeof(ifr)); 473ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger strncpy(ifr.ifr_name, dev, IFNAMSIZ); 474ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger ifr.ifr_mtu = mtu; 475aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (ioctl(s, SIOCSIFMTU, &ifr) < 0) { 476aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("SIOCSIFMTU"); 477aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(s); 478aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 479aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 480aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(s); 481aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 482ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger return 0; 483aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 484aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 48571058eb8ef128aa99666dc4e6664e7632e12a1b9osdl.net!shemmingerstatic int get_address(const char *dev, int *htype) 486aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 487aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct ifreq ifr; 488aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct sockaddr_ll me; 489f332d169246447bd5e258ac03d5ee840a70adb1eshemminger socklen_t alen; 490aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int s; 491aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 492aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger s = socket(PF_PACKET, SOCK_DGRAM, 0); 493ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger if (s < 0) { 494aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("socket(PF_PACKET)"); 495aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 496aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 497aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 498aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(&ifr, 0, sizeof(ifr)); 49971058eb8ef128aa99666dc4e6664e7632e12a1b9osdl.net!shemminger strncpy(ifr.ifr_name, dev, IFNAMSIZ); 500aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) { 501aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("SIOCGIFINDEX"); 502aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(s); 503aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 504aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 505aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 506aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(&me, 0, sizeof(me)); 507aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger me.sll_family = AF_PACKET; 508aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger me.sll_ifindex = ifr.ifr_ifindex; 509aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger me.sll_protocol = htons(ETH_P_LOOP); 510aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (bind(s, (struct sockaddr*)&me, sizeof(me)) == -1) { 511aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("bind"); 512aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(s); 513aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 514aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 515aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 516aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger alen = sizeof(me); 517aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (getsockname(s, (struct sockaddr*)&me, &alen) == -1) { 518aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("getsockname"); 519aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(s); 520aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 521aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 522aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(s); 523aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *htype = me.sll_hatype; 524aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return me.sll_halen; 525aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 526aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 527ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemmingerstatic int parse_address(const char *dev, int hatype, int halen, 5287b5657545dc246ae37690d660597e8fa37040205shemminger char *lla, struct ifreq *ifr) 529aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 530aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int alen; 531aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 532aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger memset(ifr, 0, sizeof(*ifr)); 53371058eb8ef128aa99666dc4e6664e7632e12a1b9osdl.net!shemminger strncpy(ifr->ifr_name, dev, IFNAMSIZ); 534aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ifr->ifr_hwaddr.sa_family = hatype; 535aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger alen = ll_addr_a2n(ifr->ifr_hwaddr.sa_data, 14, lla); 536aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (alen < 0) 537aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 538aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (alen != halen) { 539aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Wrong address (%s) length: expected %d bytes\n", lla, halen); 540aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 541aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 542ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger return 0; 543aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 544aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 545aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int set_address(struct ifreq *ifr, int brd) 546aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 547aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int s; 548aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 549aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger s = get_ctl_fd(); 550aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (s < 0) 551aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 552aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (ioctl(s, brd?SIOCSIFHWBROADCAST:SIOCSIFHWADDR, ifr) < 0) { 553aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror(brd?"SIOCSIFHWBROADCAST":"SIOCSIFHWADDR"); 554aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(s); 555aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 556aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 557aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger close(s); 558ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger return 0; 559aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 560aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 561aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 562aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int do_set(int argc, char **argv) 563aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 564aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char *dev = NULL; 565aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger __u32 mask = 0; 566aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger __u32 flags = 0; 567aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int qlen = -1; 568aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int mtu = -1; 569aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char *newaddr = NULL; 570aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char *newbrd = NULL; 571aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct ifreq ifr0, ifr1; 572aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char *newname = NULL; 573aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int htype, halen; 574aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 575aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger while (argc > 0) { 576aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (strcmp(*argv, "up") == 0) { 577aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger mask |= IFF_UP; 578aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger flags |= IFF_UP; 579aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "down") == 0) { 580aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger mask |= IFF_UP; 581aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger flags &= ~IFF_UP; 582aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "name") == 0) { 583aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 584aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger newname = *argv; 585aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (matches(*argv, "address") == 0) { 586aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 587aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger newaddr = *argv; 588aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (matches(*argv, "broadcast") == 0 || 589aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger strcmp(*argv, "brd") == 0) { 590aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 591aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger newbrd = *argv; 592aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (matches(*argv, "txqueuelen") == 0 || 593aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger strcmp(*argv, "qlen") == 0 || 594aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger matches(*argv, "txqlen") == 0) { 595aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 596aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (qlen != -1) 597aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger duparg("txqueuelen", *argv); 598aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (get_integer(&qlen, *argv, 0)) 599aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger invarg("Invalid \"txqueuelen\" value\n", *argv); 600aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "mtu") == 0) { 601aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 602aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (mtu != -1) 603aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger duparg("mtu", *argv); 604aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (get_integer(&mtu, *argv, 0)) 605aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger invarg("Invalid \"mtu\" value\n", *argv); 606aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "multicast") == 0) { 607aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 608aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger mask |= IFF_MULTICAST; 609aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (strcmp(*argv, "on") == 0) { 610aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger flags |= IFF_MULTICAST; 611aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "off") == 0) { 612aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger flags &= ~IFF_MULTICAST; 613aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else 614aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return on_off("multicast"); 615d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger } else if (strcmp(*argv, "allmulticast") == 0) { 616d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger NEXT_ARG(); 617d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger mask |= IFF_ALLMULTI; 618d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger if (strcmp(*argv, "on") == 0) { 619d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger flags |= IFF_ALLMULTI; 620d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger } else if (strcmp(*argv, "off") == 0) { 621d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger flags &= ~IFF_ALLMULTI; 622d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger } else 623d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger return on_off("allmulticast"); 624d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger } else if (strcmp(*argv, "promisc") == 0) { 625d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger NEXT_ARG(); 626d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger mask |= IFF_PROMISC; 627d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger if (strcmp(*argv, "on") == 0) { 628d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger flags |= IFF_PROMISC; 629d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger } else if (strcmp(*argv, "off") == 0) { 630d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger flags &= ~IFF_PROMISC; 631d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger } else 632d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger return on_off("promisc"); 633d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger } else if (strcmp(*argv, "trailers") == 0) { 634d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger NEXT_ARG(); 635d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger mask |= IFF_NOTRAILERS; 636d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger if (strcmp(*argv, "off") == 0) { 637d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger flags |= IFF_NOTRAILERS; 638d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger } else if (strcmp(*argv, "on") == 0) { 639d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger flags &= ~IFF_NOTRAILERS; 640d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger } else 641d27b1b5b41659d7b62f2e9f5213ffcefcad9753cnet[shemminger]!shemminger return on_off("trailers"); 642aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "arp") == 0) { 643aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 644aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger mask |= IFF_NOARP; 645aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (strcmp(*argv, "on") == 0) { 646aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger flags &= ~IFF_NOARP; 647aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "off") == 0) { 648aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger flags |= IFF_NOARP; 649aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else 650aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return on_off("noarp"); 651aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#ifdef IFF_DYNAMIC 652aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (matches(*argv, "dynamic") == 0) { 653aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 654aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger mask |= IFF_DYNAMIC; 655aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (strcmp(*argv, "on") == 0) { 656aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger flags |= IFF_DYNAMIC; 657aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(*argv, "off") == 0) { 658aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger flags &= ~IFF_DYNAMIC; 659aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else 660aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return on_off("dynamic"); 661aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#endif 662aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else { 663aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (strcmp(*argv, "dev") == 0) { 664aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger NEXT_ARG(); 665aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 666aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (matches(*argv, "help") == 0) 667aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger usage(); 668aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (dev) 669aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger duparg2("dev", *argv); 670aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dev = *argv; 671aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 672aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger argc--; argv++; 673aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 674aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 675aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (!dev) { 676aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Not enough of information: \"dev\" argument is required.\n"); 677aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(-1); 678aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 679aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 680aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (newaddr || newbrd) { 681aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger halen = get_address(dev, &htype); 682aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (halen < 0) 683aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 684aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (newaddr) { 685aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (parse_address(dev, htype, halen, newaddr, &ifr0) < 0) 686aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 687aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 688aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (newbrd) { 689aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (parse_address(dev, htype, halen, newbrd, &ifr1) < 0) 690ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger return -1; 691aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 692aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 693aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 694aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (newname && strcmp(dev, newname)) { 695ca78b0e7d4042be7f7283d551d433b76da7f312bPatrick McHardy if (strlen(newname) == 0) 696ca78b0e7d4042be7f7283d551d433b76da7f312bPatrick McHardy invarg("\"\" is not a valid device identifier\n", "name"); 697aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (do_changename(dev, newname) < 0) 698aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 699aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger dev = newname; 700aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 701ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger if (qlen != -1) { 702aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (set_qlen(dev, qlen) < 0) 703ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger return -1; 704aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 705ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger if (mtu != -1) { 706aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (set_mtu(dev, mtu) < 0) 707ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger return -1; 708aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 709aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (newaddr || newbrd) { 710aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (newbrd) { 711aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (set_address(&ifr1, 1) < 0) 712ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger return -1; 713aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 714aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (newaddr) { 715aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (set_address(&ifr0, 0) < 0) 716aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return -1; 717aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 718aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 719aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (mask) 720aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return do_chflags(dev, flags, mask); 721aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 722aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 7231d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy#endif /* IPLINK_IOCTL_COMPAT */ 724aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 725aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint do_iplink(int argc, char **argv) 726aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 727aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (argc > 0) { 7281d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (iplink_have_newlink()) { 7291d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (matches(*argv, "add") == 0) 7301d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return iplink_modify(RTM_NEWLINK, 7311d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy NLM_F_CREATE|NLM_F_EXCL, 7321d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy argc-1, argv+1); 7331d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (matches(*argv, "set") == 0 || 7341d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy matches(*argv, "change") == 0) 7351d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return iplink_modify(RTM_NEWLINK, 0, 7361d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy argc-1, argv+1); 7371d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (matches(*argv, "replace") == 0) 7381d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return iplink_modify(RTM_NEWLINK, 7391d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy NLM_F_CREATE|NLM_F_REPLACE, 7401d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy argc-1, argv+1); 7411d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (matches(*argv, "delete") == 0) 7421d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return iplink_modify(RTM_DELLINK, 0, 7431d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy argc-1, argv+1); 7441d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } else { 7451d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy#if IPLINK_IOCTL_COMPAT 7461d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy if (matches(*argv, "set") == 0) 7471d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy return do_set(argc-1, argv+1); 7481d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy#endif 7491d93483985f0aa2d2afc72dde5179ff3f79a0999Patrick McHardy } 750aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (matches(*argv, "show") == 0 || 751aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger matches(*argv, "lst") == 0 || 752aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger matches(*argv, "list") == 0) 753aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return ipaddr_list_link(argc-1, argv+1); 754aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (matches(*argv, "help") == 0) 755aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger usage(); 756aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else 757aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return ipaddr_list_link(0, NULL); 758aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 759aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Command \"%s\" is unknown, try \"ip link help\".\n", *argv); 760aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(-1); 761aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 762