commit 5e52e54c147b631e555294e6446d9c2d609207f2 Author: Patrick McHardy Date: Tue Oct 7 17:15:13 2008 +0200 [IPROUTE]: Fix up "ip link" help text Show help for "ip link add" in case its supported by the kernel. Also fix up the "ip link set" help text: - the flags are not mutually exclusive as suggested by the current text, up/down states and on/off are mutually exclusive. - txqueuelen, name etc. have nothing to do with the flags and on/off states at all and are certainly not mutually exclusive, fix formatting and make it conform the other helptexts better. Signed-off-by: Patrick McHardy diff --git a/ip/iplink.c b/ip/iplink.c index 6e9ac71..a99115a 100644 --- a/ip/iplink.c +++ b/ip/iplink.c @@ -37,23 +37,85 @@ #define LIBDIR "/usr/lib/" #endif +#if IPLINK_IOCTL_COMPAT +static int have_rtnl_newlink = -1; + +static int accept_msg(const struct sockaddr_nl *who, + struct nlmsghdr *n, void *arg) +{ + struct nlmsgerr *err = (struct nlmsgerr *)NLMSG_DATA(n); + + if (n->nlmsg_type == NLMSG_ERROR && + (err->error == -EOPNOTSUPP || err->error == -EINVAL)) + have_rtnl_newlink = 0; + else + have_rtnl_newlink = 1; + return -1; +} + +static int iplink_have_newlink(void) +{ + struct { + struct nlmsghdr n; + struct ifinfomsg i; + char buf[1024]; + } req; + + if (have_rtnl_newlink < 0) { + memset(&req, 0, sizeof(req)); + + req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); + req.n.nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK; + req.n.nlmsg_type = RTM_NEWLINK; + req.i.ifi_family = AF_UNSPEC; + + rtnl_send(&rth, (char *)&req.n, req.n.nlmsg_len); + rtnl_listen(&rth, accept_msg, NULL); + } + return have_rtnl_newlink; +} +#else /* IPLINK_IOCTL_COMPAT */ +static int iplink_have_newlink(void) +{ + return 1; +} +#endif /* ! IPLINK_IOCTL_COMPAT */ + static void usage(void) __attribute__((noreturn)); void iplink_usage(void) { - fprintf(stderr, "Usage: ip link set DEVICE { up | down |\n"); - fprintf(stderr, " arp { on | off } |\n"); - fprintf(stderr, " dynamic { on | off } |\n"); - fprintf(stderr, " multicast { on | off } |\n"); - fprintf(stderr, " allmulticast { on | off } |\n"); - fprintf(stderr, " promisc { on | off } |\n"); - fprintf(stderr, " trailers { on | off } |\n"); - fprintf(stderr, " txqueuelen PACKETS |\n"); - fprintf(stderr, " name NEWNAME |\n"); - fprintf(stderr, " address LLADDR | broadcast LLADDR |\n"); - fprintf(stderr, " mtu MTU }\n"); - fprintf(stderr, " netns PID }\n"); + if (iplink_have_newlink()) { + fprintf(stderr, "Usage: ip link add [ link DEV ] [ name ] NAME\n"); + fprintf(stderr, " [ txqueuelen PACKETS ]\n"); + fprintf(stderr, " [ address LLADDR ]\n"); + fprintf(stderr, " [ broadcast LLADDR ]\n"); + fprintf(stderr, " [ mtu MTU ]\n"); + fprintf(stderr, " type TYPE [ ARGS ]\n"); + fprintf(stderr, "\n"); + fprintf(stderr, " ip link set DEVICE [ { up | down } ]\n"); + } else + fprintf(stderr, "Usage: ip link set DEVICE [ { up | down } ]\n"); + + fprintf(stderr, " [ arp { on | off } ]\n"); + fprintf(stderr, " [ dynamic { on | off } ]\n"); + fprintf(stderr, " [ multicast { on | off } ]\n"); + fprintf(stderr, " [ allmulticast { on | off } ]\n"); + fprintf(stderr, " [ promisc { on | off } ]\n"); + fprintf(stderr, " [ trailers { on | off } ]\n"); + fprintf(stderr, " [ txqueuelen PACKETS ]\n"); + fprintf(stderr, " [ name NEWNAME ]\n"); + fprintf(stderr, " [ address LLADDR ]\n"); + fprintf(stderr, " [ broadcast LLADDR ]\n"); + fprintf(stderr, " [ mtu MTU ]\n"); + fprintf(stderr, " [ netns PID ]\n"); fprintf(stderr, " ip link show [ DEVICE ]\n"); + + if (iplink_have_newlink()) { + fprintf(stderr, "\n"); + fprintf(stderr, "TYPE := { vlan | veth | dummy | ifb | macvlan }\n"); + } + exit(-1); } @@ -103,50 +165,6 @@ struct link_util *get_link_kind(const char *id) return l; } -#if IPLINK_IOCTL_COMPAT -static int have_rtnl_newlink = -1; - -static int accept_msg(const struct sockaddr_nl *who, - struct nlmsghdr *n, void *arg) -{ - struct nlmsgerr *err = (struct nlmsgerr *)NLMSG_DATA(n); - - if (n->nlmsg_type == NLMSG_ERROR && - (err->error == -EOPNOTSUPP || err->error == -EINVAL)) - have_rtnl_newlink = 0; - else - have_rtnl_newlink = 1; - return -1; -} - -static int iplink_have_newlink(void) -{ - struct { - struct nlmsghdr n; - struct ifinfomsg i; - char buf[1024]; - } req; - - if (have_rtnl_newlink < 0) { - memset(&req, 0, sizeof(req)); - - req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); - req.n.nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK; - req.n.nlmsg_type = RTM_NEWLINK; - req.i.ifi_family = AF_UNSPEC; - - rtnl_send(&rth, (char *)&req.n, req.n.nlmsg_len); - rtnl_listen(&rth, accept_msg, NULL); - } - return have_rtnl_newlink; -} -#else /* IPLINK_IOCTL_COMPAT */ -static int iplink_have_newlink(void) -{ - return 1; -} -#endif /* ! IPLINK_IOCTL_COMPAT */ - struct iplink_req { struct nlmsghdr n; struct ifinfomsg i;