From ab872442bd61ca49e5fbd778fdc5f4ed7c1943b5 Mon Sep 17 00:00:00 2001 From: Vadim Kochan Date: Mon, 24 Aug 2015 17:57:06 +0300 Subject: [PATCH 1/5] man ip-link: Add little explanations about VLAN qos map Add little more info about how to manually set priority by iptables, and some little clarifications about ingress/egress QoS mapping. Signed-off-by: Vadim Kochan --- man/man8/ip-link.8.in | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in index b9137fbe..2283b710 100644 --- a/man/man8/ip-link.8.in +++ b/man/man8/ip-link.8.in @@ -349,10 +349,30 @@ where is the physical device to which VLAN device is bound. - specifies whether the VLAN device state is bound to the physical device state. .BI ingress-qos-map " QOS-MAP " -- defines a mapping between priority code points on incoming frames. The format is FROM:TO with multiple mappings separated by spaces. +- defines a mapping of VLAN header prio field to the Linux internal packet +priority on incoming frames. The format is FROM:TO with multiple mappings +separated by spaces. .BI egress-qos-map " QOS-MAP " -- the same as ingress-qos-map but for outgoing frames. +- defines a mapping of Linux internal packet priority to VLAN header prio field +but for outgoing frames. The format is the same as for ingress-qos-map. +.in +4 + +Linux packet priority can be set by +.BR iptables "(8)": +.in +4 +.sp +.B iptables +-t mangle -A POSTROUTING [...] -j CLASSIFY --set-class 0:4 +.sp +.in -4 +and this "4" priority can be used in the egress qos mapping to set VLAN prio "5": +.sp +.in +4 +.B ip +link set veth0.10 type vlan egress 4:5 +.in -4 +.in -4 .in -8 .TP @@ -1090,7 +1110,8 @@ IEEE 802.15.4 device wpan0. .br .BR ip (8), .BR ip-netns (8), -.BR ethtool (8) +.BR ethtool (8), +.BR iptables (8) .SH AUTHOR Original Manpage by Michail Litvak From 6c5ffb9a2c3db46fdb94cf4c454005ec829db509 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 25 Aug 2015 15:57:04 -0700 Subject: [PATCH 2/5] iplink: cleanup whitespace and checkpatch issues Mostly just use of {} and whitespace. --- ip/iplink.c | 171 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 100 insertions(+), 71 deletions(-) diff --git a/ip/iplink.c b/ip/iplink.c index 504aa74e..cdb3f73e 100644 --- a/ip/iplink.c +++ b/ip/iplink.c @@ -77,10 +77,10 @@ void iplink_usage(void) fprintf(stderr, " [ vf NUM [ mac LLADDR ]\n"); fprintf(stderr, " [ vlan VLANID [ qos VLAN-QOS ] ]\n"); - fprintf(stderr, " [ rate TXRATE ] ] \n"); + fprintf(stderr, " [ rate TXRATE ] ]\n"); - fprintf(stderr, " [ spoofchk { on | off} ] ] \n"); - fprintf(stderr, " [ query_rss { on | off} ] ] \n"); + fprintf(stderr, " [ spoofchk { on | off} ] ]\n"); + fprintf(stderr, " [ query_rss { on | off} ] ]\n"); fprintf(stderr, " [ state { auto | enable | disable} ] ]\n"); fprintf(stderr, " [ master DEVICE ]\n"); fprintf(stderr, " [ nomaster ]\n"); @@ -105,7 +105,9 @@ static void usage(void) static int on_off(const char *msg, const char *realval) { - fprintf(stderr, "Error: argument of \"%s\" must be \"on\" or \"off\", not \"%s\"\n", msg, realval); + fprintf(stderr, + "Error: argument of \"%s\" must be \"on\" or \"off\", not \"%s\"\n", + msg, realval); return -1; } @@ -267,6 +269,7 @@ static int iplink_parse_vf(int vf, int *argcp, char ***argvp, NEXT_ARG(); if (matches(*argv, "mac") == 0) { struct ifla_vf_mac ivm; + NEXT_ARG(); ivm.vf = vf; len = ll_addr_a2n((char *)ivm.mac, 32, *argv); @@ -275,19 +278,19 @@ static int iplink_parse_vf(int vf, int *argcp, char ***argvp, addattr_l(&req->n, sizeof(*req), IFLA_VF_MAC, &ivm, sizeof(ivm)); } else if (matches(*argv, "vlan") == 0) { struct ifla_vf_vlan ivv; + NEXT_ARG(); - if (get_unsigned(&ivv.vlan, *argv, 0)) { + if (get_unsigned(&ivv.vlan, *argv, 0)) invarg("Invalid \"vlan\" value\n", *argv); - } + ivv.vf = vf; ivv.qos = 0; if (NEXT_ARG_OK()) { NEXT_ARG(); if (matches(*argv, "qos") == 0) { NEXT_ARG(); - if (get_unsigned(&ivv.qos, *argv, 0)) { + if (get_unsigned(&ivv.qos, *argv, 0)) invarg("Invalid \"qos\" value\n", *argv); - } } else { /* rewind arg */ PREV_ARG(); @@ -296,10 +299,11 @@ static int iplink_parse_vf(int vf, int *argcp, char ***argvp, addattr_l(&req->n, sizeof(*req), IFLA_VF_VLAN, &ivv, sizeof(ivv)); } else if (matches(*argv, "rate") == 0) { struct ifla_vf_tx_rate ivt; + NEXT_ARG(); - if (get_unsigned(&ivt.rate, *argv, 0)) { + if (get_unsigned(&ivt.rate, *argv, 0)) invarg("Invalid \"rate\" value\n", *argv); - } + ivt.vf = vf; if (!new_rate_api) addattr_l(&req->n, sizeof(*req), @@ -323,6 +327,7 @@ static int iplink_parse_vf(int vf, int *argcp, char ***argvp, } else if (matches(*argv, "spoofchk") == 0) { struct ifla_vf_spoofchk ivs; + NEXT_ARG(); if (matches(*argv, "on") == 0) ivs.setting = 1; @@ -335,6 +340,7 @@ static int iplink_parse_vf(int vf, int *argcp, char ***argvp, } else if (matches(*argv, "query_rss") == 0) { struct ifla_vf_rss_query_en ivs; + NEXT_ARG(); if (matches(*argv, "on") == 0) ivs.setting = 1; @@ -347,6 +353,7 @@ static int iplink_parse_vf(int vf, int *argcp, char ***argvp, } else if (matches(*argv, "state") == 0) { struct ifla_vf_link_state ivl; + NEXT_ARG(); if (matches(*argv, "auto") == 0) ivl.link_state = IFLA_VF_LINK_STATE_AUTO; @@ -390,7 +397,8 @@ static int iplink_parse_vf(int vf, int *argcp, char ***argvp, } int iplink_parse(int argc, char **argv, struct iplink_req *req, - char **name, char **type, char **link, char **dev, int *group, int *index) + char **name, char **type, char **link, char **dev, + int *group, int *index) { int ret, len; char abuf[32]; @@ -431,15 +439,15 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, return -1; addattr_l(&req->n, sizeof(*req), IFLA_ADDRESS, abuf, len); } else if (matches(*argv, "broadcast") == 0 || - strcmp(*argv, "brd") == 0) { + strcmp(*argv, "brd") == 0) { NEXT_ARG(); len = ll_addr_a2n(abuf, sizeof(abuf), *argv); if (len < 0) return -1; addattr_l(&req->n, sizeof(*req), IFLA_BROADCAST, abuf, len); } else if (matches(*argv, "txqueuelen") == 0 || - strcmp(*argv, "qlen") == 0 || - matches(*argv, "txqlen") == 0) { + strcmp(*argv, "qlen") == 0 || + matches(*argv, "txqlen") == 0) { NEXT_ARG(); if (qlen != -1) duparg("txqueuelen", *argv); @@ -457,7 +465,8 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, NEXT_ARG(); if (netns != -1) duparg("netns", *argv); - if ((netns = netns_get_fd(*argv)) >= 0) + netns = netns_get_fd(*argv); + if (netns >= 0) addattr_l(&req->n, sizeof(*req), IFLA_NET_NS_FD, &netns, 4); else if (get_integer(&netns, *argv, 0) == 0) addattr_l(&req->n, sizeof(*req), IFLA_NET_NS_PID, &netns, 4); @@ -466,54 +475,60 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, } else if (strcmp(*argv, "multicast") == 0) { NEXT_ARG(); req->i.ifi_change |= IFF_MULTICAST; - if (strcmp(*argv, "on") == 0) { + + if (strcmp(*argv, "on") == 0) req->i.ifi_flags |= IFF_MULTICAST; - } else if (strcmp(*argv, "off") == 0) { + else if (strcmp(*argv, "off") == 0) req->i.ifi_flags &= ~IFF_MULTICAST; - } else + else return on_off("multicast", *argv); } else if (strcmp(*argv, "allmulticast") == 0) { NEXT_ARG(); req->i.ifi_change |= IFF_ALLMULTI; - if (strcmp(*argv, "on") == 0) { + + if (strcmp(*argv, "on") == 0) req->i.ifi_flags |= IFF_ALLMULTI; - } else if (strcmp(*argv, "off") == 0) { + else if (strcmp(*argv, "off") == 0) req->i.ifi_flags &= ~IFF_ALLMULTI; - } else + else return on_off("allmulticast", *argv); } else if (strcmp(*argv, "promisc") == 0) { NEXT_ARG(); req->i.ifi_change |= IFF_PROMISC; - if (strcmp(*argv, "on") == 0) { + + if (strcmp(*argv, "on") == 0) req->i.ifi_flags |= IFF_PROMISC; - } else if (strcmp(*argv, "off") == 0) { + else if (strcmp(*argv, "off") == 0) req->i.ifi_flags &= ~IFF_PROMISC; - } else + else return on_off("promisc", *argv); } else if (strcmp(*argv, "trailers") == 0) { NEXT_ARG(); req->i.ifi_change |= IFF_NOTRAILERS; - if (strcmp(*argv, "off") == 0) { + + if (strcmp(*argv, "off") == 0) req->i.ifi_flags |= IFF_NOTRAILERS; - } else if (strcmp(*argv, "on") == 0) { + else if (strcmp(*argv, "on") == 0) req->i.ifi_flags &= ~IFF_NOTRAILERS; - } else + else return on_off("trailers", *argv); } else if (strcmp(*argv, "arp") == 0) { NEXT_ARG(); req->i.ifi_change |= IFF_NOARP; - if (strcmp(*argv, "on") == 0) { + + if (strcmp(*argv, "on") == 0) req->i.ifi_flags &= ~IFF_NOARP; - } else if (strcmp(*argv, "off") == 0) { + else if (strcmp(*argv, "off") == 0) req->i.ifi_flags |= IFF_NOARP; - } else + else return on_off("arp", *argv); } else if (strcmp(*argv, "vf") == 0) { struct rtattr *vflist; + NEXT_ARG(); - if (get_integer(&vf, *argv, 0)) { + if (get_integer(&vf, *argv, 0)) invarg("Invalid \"vf\" value\n", *argv); - } + vflist = addattr_nest(&req->n, sizeof(*req), IFLA_VFINFO_LIST); if (dev_index == 0) @@ -525,6 +540,7 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, addattr_nest_end(&req->n, vflist); } else if (matches(*argv, "master") == 0) { int ifindex; + NEXT_ARG(); ifindex = ll_name_to_index(*argv); if (!ifindex) @@ -533,16 +549,18 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, &ifindex, 4); } else if (matches(*argv, "nomaster") == 0) { int ifindex = 0; + addattr_l(&req->n, sizeof(*req), IFLA_MASTER, &ifindex, 4); } else if (matches(*argv, "dynamic") == 0) { NEXT_ARG(); req->i.ifi_change |= IFF_DYNAMIC; - if (strcmp(*argv, "on") == 0) { + + if (strcmp(*argv, "on") == 0) req->i.ifi_flags |= IFF_DYNAMIC; - } else if (strcmp(*argv, "off") == 0) { + else if (strcmp(*argv, "off") == 0) req->i.ifi_flags &= ~IFF_DYNAMIC; - } else + else return on_off("dynamic", *argv); } else if (matches(*argv, "type") == 0) { NEXT_ARG(); @@ -563,6 +581,7 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, invarg("Invalid \"group\" value\n", *argv); } else if (strcmp(*argv, "mode") == 0) { int mode; + NEXT_ARG(); mode = get_link_mode(*argv); if (mode < 0) @@ -570,6 +589,7 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, addattr8(&req->n, sizeof(*req), IFLA_LINKMODE, mode); } else if (strcmp(*argv, "state") == 0) { int state; + NEXT_ARG(); state = get_operstate(*argv); if (state < 0) @@ -595,6 +615,7 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, } else if (matches(*argv, "addrgenmode") == 0) { struct rtattr *afs, *afs6; int mode; + NEXT_ARG(); mode = get_addr_gen_mode(*argv); if (mode < 0) @@ -613,9 +634,9 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, addattr32(&req->n, sizeof(*req), IFLA_LINK_NETNSID, link_netnsid); } else { - if (strcmp(*argv, "dev") == 0) { + if (strcmp(*argv, "dev") == 0) NEXT_ARG(); - } + if (matches(*argv, "help") == 0) usage(); if (*dev) @@ -953,14 +974,14 @@ static int get_address(const char *dev, int *htype) me.sll_family = AF_PACKET; me.sll_ifindex = ifr.ifr_ifindex; me.sll_protocol = htons(ETH_P_LOOP); - if (bind(s, (struct sockaddr*)&me, sizeof(me)) == -1) { + if (bind(s, (struct sockaddr *)&me, sizeof(me)) == -1) { perror("bind"); close(s); return -1; } alen = sizeof(me); - if (getsockname(s, (struct sockaddr*)&me, &alen) == -1) { + if (getsockname(s, (struct sockaddr *)&me, &alen) == -1) { perror("getsockname"); close(s); return -1; @@ -1051,63 +1072,70 @@ static int do_set(int argc, char **argv) } else if (strcmp(*argv, "multicast") == 0) { NEXT_ARG(); mask |= IFF_MULTICAST; - if (strcmp(*argv, "on") == 0) { + + if (strcmp(*argv, "on") == 0) flags |= IFF_MULTICAST; - } else if (strcmp(*argv, "off") == 0) { + else if (strcmp(*argv, "off") == 0) flags &= ~IFF_MULTICAST; - } else + else return on_off("multicast", *argv); } else if (strcmp(*argv, "allmulticast") == 0) { NEXT_ARG(); mask |= IFF_ALLMULTI; - if (strcmp(*argv, "on") == 0) { + + if (strcmp(*argv, "on") == 0) flags |= IFF_ALLMULTI; - } else if (strcmp(*argv, "off") == 0) { + else if (strcmp(*argv, "off") == 0) flags &= ~IFF_ALLMULTI; - } else + else return on_off("allmulticast", *argv); } else if (strcmp(*argv, "promisc") == 0) { NEXT_ARG(); mask |= IFF_PROMISC; - if (strcmp(*argv, "on") == 0) { + + if (strcmp(*argv, "on") == 0) flags |= IFF_PROMISC; - } else if (strcmp(*argv, "off") == 0) { + else if (strcmp(*argv, "off") == 0) flags &= ~IFF_PROMISC; - } else + else return on_off("promisc", *argv); } else if (strcmp(*argv, "trailers") == 0) { NEXT_ARG(); mask |= IFF_NOTRAILERS; - if (strcmp(*argv, "off") == 0) { + + if (strcmp(*argv, "off") == 0) flags |= IFF_NOTRAILERS; - } else if (strcmp(*argv, "on") == 0) { + else if (strcmp(*argv, "on") == 0) flags &= ~IFF_NOTRAILERS; - } else + else return on_off("trailers", *argv); } else if (strcmp(*argv, "arp") == 0) { NEXT_ARG(); mask |= IFF_NOARP; - if (strcmp(*argv, "on") == 0) { + + if (strcmp(*argv, "on") == 0) flags &= ~IFF_NOARP; - } else if (strcmp(*argv, "off") == 0) { + else if (strcmp(*argv, "off") == 0) flags |= IFF_NOARP; - } else + else return on_off("arp", *argv); } else if (matches(*argv, "dynamic") == 0) { NEXT_ARG(); mask |= IFF_DYNAMIC; - if (strcmp(*argv, "on") == 0) { + + if (strcmp(*argv, "on") == 0) flags |= IFF_DYNAMIC; - } else if (strcmp(*argv, "off") == 0) { + else if (strcmp(*argv, "off") == 0) flags &= ~IFF_DYNAMIC; - } else + else return on_off("dynamic", *argv); } else { - if (strcmp(*argv, "dev") == 0) { + if (strcmp(*argv, "dev") == 0) NEXT_ARG(); - } + if (matches(*argv, "help") == 0) usage(); + if (dev) duparg2("dev", *argv); dev = *argv; @@ -1171,11 +1199,10 @@ static void do_help(int argc, char **argv) if (argc <= 0) { usage(); - return ; + return; } lu = get_link_kind(*argv); - if (lu && lu->print_help) lu->print_help(lu, argc-1, argv+1, stdout); else @@ -1190,35 +1217,37 @@ int do_iplink(int argc, char **argv) if (iplink_have_newlink()) { if (matches(*argv, "add") == 0) return iplink_modify(RTM_NEWLINK, - NLM_F_CREATE|NLM_F_EXCL, - argc-1, argv+1); + NLM_F_CREATE|NLM_F_EXCL, + argc-1, argv+1); if (matches(*argv, "set") == 0 || - matches(*argv, "change") == 0) + matches(*argv, "change") == 0) return iplink_modify(RTM_NEWLINK, 0, - argc-1, argv+1); + argc-1, argv+1); if (matches(*argv, "replace") == 0) return iplink_modify(RTM_NEWLINK, - NLM_F_CREATE|NLM_F_REPLACE, - argc-1, argv+1); + NLM_F_CREATE|NLM_F_REPLACE, + argc-1, argv+1); if (matches(*argv, "delete") == 0) return iplink_modify(RTM_DELLINK, 0, - argc-1, argv+1); + argc-1, argv+1); } else { #if IPLINK_IOCTL_COMPAT if (matches(*argv, "set") == 0) return do_set(argc-1, argv+1); #endif } + if (matches(*argv, "show") == 0 || - matches(*argv, "lst") == 0 || - matches(*argv, "list") == 0) + matches(*argv, "lst") == 0 || + matches(*argv, "list") == 0) return ipaddr_list_link(argc-1, argv+1); + if (matches(*argv, "help") == 0) { do_help(argc-1, argv+1); return 0; } fprintf(stderr, "Command \"%s\" is unknown, try \"ip link help\".\n", - *argv); + *argv); exit(-1); } From 5d295bb8e1af491bc3de1d2506cbb2bd6bbd9da1 Mon Sep 17 00:00:00 2001 From: Andy Gospodarek Date: Fri, 28 Aug 2015 13:45:41 -0400 Subject: [PATCH 3/5] add support for brief output for link and addresses This adds support for slightly less output than is normally provided by 'ip link show' and 'ip addr show'. This is a bit better when you have a host with lots of interfaces. Sample output: $ ip -br link show lo UNKNOWN 00:00:00:00:00:00 p2p1 UP 08:00:27:ee:0b:3b p7p1 UP 08:00:27:9d:62:9f p8p1 DOWN 08:00:27:dc:d8:ca p9p1 UP 08:00:27:76:d9:75 p7p1.100@p7p1 UP 08:00:27:9d:62:9f $ ip -br -4 addr show lo UNKNOWN 127.0.0.1/8 p2p1 UP 192.168.56.2/24 p7p1 UP 70.0.0.1/24 p8p1 DOWN 80.0.0.1/24 p9p1 UP 10.0.5.15/24 p7p1.100@p7p1 UP 200.0.0.1/24 $ ip -br -6 addr show lo UNKNOWN ::1/128 p2p1 UP fe80::a00:27ff:feee:b3b/64 p7p1 UP 7000::1/8 fe80::a00:27ff:fe9d:629f/64 p8p1 DOWN 8000::1/8 p9p1 UP fe80::a00:27ff:fe76:d975/64 p7p1.100@p7p1 UP fe80::a00:27ff:fe9d:629f/64 $ ip -br addr show p7p1 p7p1 UP 70.0.0.1/24 7000::1/8 fe80::a00:27ff:fe9d:629f/64 v2: Now with color support! v3: Better field width estimation (except netdev names to keep output at a decent width) and whitespace fixup. Signed-off-by: Andy Gospodarek --- include/utils.h | 1 + ip/ip.c | 5 +- ip/ip_common.h | 3 + ip/ipaddress.c | 150 ++++++++++++++++++++++++++++++++++++------ ip/iplink.c | 5 +- man/man8/ip-link.8.in | 3 +- 6 files changed, 143 insertions(+), 24 deletions(-) diff --git a/include/utils.h b/include/utils.h index 0c57ccdc..f77edeb0 100644 --- a/include/utils.h +++ b/include/utils.h @@ -19,6 +19,7 @@ extern int show_details; extern int show_raw; extern int resolve_hosts; extern int oneline; +extern int brief; extern int timestamp; extern int timestamp_short; extern const char * _SL_; diff --git a/ip/ip.c b/ip/ip.c index e75447e1..eea00b82 100644 --- a/ip/ip.c +++ b/ip/ip.c @@ -32,6 +32,7 @@ int show_stats; int show_details; int resolve_hosts; int oneline; +int brief; int timestamp; const char *_SL_; int force; @@ -55,7 +56,7 @@ static void usage(void) " -h[uman-readable] | -iec |\n" " -f[amily] { inet | inet6 | ipx | dnet | mpls | bridge | link } |\n" " -4 | -6 | -I | -D | -B | -0 |\n" -" -l[oops] { maximum-addr-flush-attempts } |\n" +" -l[oops] { maximum-addr-flush-attempts } | -br[ief] |\n" " -o[neline] | -t[imestamp] | -ts[hort] | -b[atch] [filename] |\n" " -rc[vbuf] [size] | -n[etns] name | -a[ll] | -c[olor]}\n"); exit(-1); @@ -250,6 +251,8 @@ int main(int argc, char **argv) if (argc <= 1) usage(); batch_file = argv[1]; + } else if (matches(opt, "-brief") == 0) { + ++brief; } else if (matches(opt, "-rcvbuf") == 0) { unsigned int size; diff --git a/ip/ip_common.h b/ip/ip_common.h index f120f5b9..f74face6 100644 --- a/ip/ip_common.h +++ b/ip/ip_common.h @@ -2,6 +2,9 @@ extern int get_operstate(const char *name); extern int print_linkinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg); +extern int print_linkinfo_brief(const struct sockaddr_nl *who, + struct nlmsghdr *n, + void *arg); extern int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg); diff --git a/ip/ipaddress.c b/ip/ipaddress.c index 177b65a9..5dad5d6f 100644 --- a/ip/ipaddress.c +++ b/ip/ipaddress.c @@ -138,13 +138,22 @@ static void print_operstate(FILE *f, __u8 state) if (state >= sizeof(oper_states)/sizeof(oper_states[0])) fprintf(f, "state %#x ", state); else { - fprintf(f, "state "); - if (strcmp(oper_states[state], "UP") == 0) - color_fprintf(f, COLOR_OPERSTATE_UP, "%s ", oper_states[state]); - else if (strcmp(oper_states[state], "DOWN") == 0) - color_fprintf(f, COLOR_OPERSTATE_DOWN, "%s ", oper_states[state]); - else - fprintf(f, "%s ", oper_states[state]); + if (brief) { + if (strcmp(oper_states[state], "UP") == 0) + color_fprintf(f, COLOR_OPERSTATE_UP, "%-14s ", oper_states[state]); + else if (strcmp(oper_states[state], "DOWN") == 0) + color_fprintf(f, COLOR_OPERSTATE_DOWN, "%-14s ", oper_states[state]); + else + fprintf(f, "%-14s ", oper_states[state]); + } else { + fprintf(f, "state "); + if (strcmp(oper_states[state], "UP") == 0) + color_fprintf(f, COLOR_OPERSTATE_UP, "%s ", oper_states[state]); + else if (strcmp(oper_states[state], "DOWN") == 0) + color_fprintf(f, COLOR_OPERSTATE_DOWN, "%s ", oper_states[state]); + else + fprintf(f, "%s ", oper_states[state]); + } } } @@ -590,6 +599,88 @@ static void print_link_stats(FILE *fp, struct nlmsghdr *n) fprintf(fp, "%s", _SL_); } +int print_linkinfo_brief(const struct sockaddr_nl *who, + struct nlmsghdr *n, void *arg) +{ + FILE *fp = (FILE*)arg; + struct ifinfomsg *ifi = NLMSG_DATA(n); + struct rtattr * tb[IFLA_MAX+1]; + int len = n->nlmsg_len; + char *name; + char buf[32] = { 0, }; + unsigned m_flag = 0; + + if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK) + return -1; + + len -= NLMSG_LENGTH(sizeof(*ifi)); + if (len < 0) + return -1; + + if (filter.ifindex && ifi->ifi_index != filter.ifindex) + return -1; + if (filter.up && !(ifi->ifi_flags&IFF_UP)) + return -1; + + parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len); + if (tb[IFLA_IFNAME] == NULL) { + fprintf(stderr, "BUG: device with ifindex %d has nil ifname\n", ifi->ifi_index); + } + if (filter.label && + (!filter.family || filter.family == AF_PACKET) && + fnmatch(filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0)) + return -1; + + if (tb[IFLA_GROUP]) { + int group = *(int*)RTA_DATA(tb[IFLA_GROUP]); + if (filter.group != -1 && group != filter.group) + return -1; + } + + if (n->nlmsg_type == RTM_DELLINK) + fprintf(fp, "Deleted "); + + name = (char *)(tb[IFLA_IFNAME] ? rta_getattr_str(tb[IFLA_IFNAME]) : ""); + + if (tb[IFLA_LINK]) { + SPRINT_BUF(b1); + int iflink = *(int*)RTA_DATA(tb[IFLA_LINK]); + if (iflink == 0) + snprintf(buf, sizeof(buf), "%s@NONE", name); + else { + snprintf(buf, sizeof(buf), + "%s@%s", name, ll_idx_n2a(iflink, b1)); + m_flag = ll_index_to_flags(iflink); + m_flag = !(m_flag & IFF_UP); + } + } else + snprintf(buf, sizeof(buf), "%s", name); + + fprintf(fp, "%-16s ", buf); + + if (tb[IFLA_OPERSTATE]) + print_operstate(fp, rta_getattr_u8(tb[IFLA_OPERSTATE])); + + if (filter.family == AF_PACKET) { + SPRINT_BUF(b1); + if (tb[IFLA_ADDRESS]) { + color_fprintf(fp, COLOR_MAC, "%s ", + ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]), + RTA_PAYLOAD(tb[IFLA_ADDRESS]), + ifi->ifi_type, + b1, sizeof(b1))); + } + } + + if (filter.family == AF_PACKET) + print_link_flags(fp, ifi->ifi_flags, m_flag); + + if (filter.family == AF_PACKET) + fprintf(fp, "\n"); + fflush(fp); + return 0; +} + int print_linkinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) { @@ -887,18 +978,20 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, if (n->nlmsg_type == RTM_DELADDR) fprintf(fp, "Deleted "); - if (filter.oneline || filter.flushb) - fprintf(fp, "%u: %s", ifa->ifa_index, ll_index_to_name(ifa->ifa_index)); - if (ifa->ifa_family == AF_INET) - fprintf(fp, " inet "); - else if (ifa->ifa_family == AF_INET6) - fprintf(fp, " inet6 "); - else if (ifa->ifa_family == AF_DECnet) - fprintf(fp, " dnet "); - else if (ifa->ifa_family == AF_IPX) - fprintf(fp, " ipx "); - else - fprintf(fp, " family %d ", ifa->ifa_family); + if (!brief) { + if (filter.oneline || filter.flushb) + fprintf(fp, "%u: %s", ifa->ifa_index, ll_index_to_name(ifa->ifa_index)); + if (ifa->ifa_family == AF_INET) + fprintf(fp, " inet "); + else if (ifa->ifa_family == AF_INET6) + fprintf(fp, " inet6 "); + else if (ifa->ifa_family == AF_DECnet) + fprintf(fp, " dnet "); + else if (ifa->ifa_family == AF_IPX) + fprintf(fp, " ipx "); + else + fprintf(fp, " family %d ", ifa->ifa_family); + } if (rta_tb[IFA_LOCAL]) { if (ifa->ifa_family == AF_INET) @@ -931,6 +1024,9 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, } } + if (brief) + goto brief_exit; + if (rta_tb[IFA_BROADCAST]) { fprintf(fp, "brd %s ", format_host(ifa->ifa_family, @@ -1013,6 +1109,7 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, } } fprintf(fp, "\n"); +brief_exit: fflush(fp); return 0; } @@ -1073,6 +1170,10 @@ static int print_selected_addrinfo(struct ifinfomsg *ifi, print_addrinfo(NULL, n, fp); } + if (brief) { + fprintf(fp, "\n"); + fflush(fp); + } return 0; } @@ -1534,9 +1635,16 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action) for (l = linfo.head; l; l = l->next) { int res = 0; + struct ifinfomsg *ifi = NLMSG_DATA(&l->h); - if (no_link || (res = print_linkinfo(NULL, &l->h, stdout)) >= 0) { - struct ifinfomsg *ifi = NLMSG_DATA(&l->h); + if (brief) { + if (print_linkinfo_brief(NULL, &l->h, stdout) == 0) + if (filter.family != AF_PACKET) + print_selected_addrinfo(ifi, + ainfo.head, + stdout); + } else if (no_link || + (res = print_linkinfo(NULL, &l->h, stdout)) >= 0) { if (filter.family != AF_PACKET) print_selected_addrinfo(ifi, ainfo.head, stdout); diff --git a/ip/iplink.c b/ip/iplink.c index cdb3f73e..5361c2f9 100644 --- a/ip/iplink.c +++ b/ip/iplink.c @@ -831,7 +831,10 @@ int iplink_get(unsigned int flags, char *name, __u32 filt_mask) if (rtnl_talk(&rth, &req.n, &answer.n, sizeof(answer)) < 0) return -2; - print_linkinfo(NULL, &answer.n, stdout); + if (brief) + print_linkinfo_brief(NULL, &answer.n, stdout); + else + print_linkinfo(NULL, &answer.n, stdout); return 0; } diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in index 2283b710..81c48920 100644 --- a/man/man8/ip-link.8.in +++ b/man/man8/ip-link.8.in @@ -21,7 +21,8 @@ ip-link \- network device configuration \fB\-r\fR[\fIesolve\fR] | \fB\-f\fR[\fIamily\fR] { .BR inet " | " inet6 " | " ipx " | " dnet " | " link " } | " -\fB\-o\fR[\fIneline\fR] } +\fB\-o\fR[\fIneline\fR] | +\fB\-br\fR[\fIief\fR] } .ti -8 .BI "ip link add" From 6eca32ec6fa682491bece81b91fd44de3de4afc4 Mon Sep 17 00:00:00 2001 From: Konstantin Shemyak Date: Sat, 29 Aug 2015 21:36:32 +0300 Subject: [PATCH 4/5] add 'vti'/'vti6' tunnel modes to ip-tunnel manual page * "vti" and "vti6" tunnel modes added to ip-tunnel.8 manual page * Added "hoplimit" terminology for IPv6 * Corrected usage line * Minor language fix --- man/man8/ip-tunnel.8 | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/man/man8/ip-tunnel.8 b/man/man8/ip-tunnel.8 index c97c28ca..8b746cb0 100644 --- a/man/man8/ip-tunnel.8 +++ b/man/man8/ip-tunnel.8 @@ -6,14 +6,12 @@ ip-tunnel - tunnel configuration .ad l .in +8 .ti -8 -.B ip -.RI "[ " OPTIONS " ]" -.B tunnel -.RI " { " COMMAND " | " -.BR help " }" +.B ip tunnel help .sp .ti -8 -.BR "ip tunnel" " { " add " | " change " | " del " | " show " | " prl " }" +.BR "ip " +.RI "[ " OPTIONS " ]" +.BR "tunnel" " { " add " | " change " | " del " | " show " | " prl " }" .RI "[ " NAME " ]" .br .RB "[ " mode @@ -29,7 +27,7 @@ ip-tunnel - tunnel configuration .br .RB "[ " encaplimit .IR ELIM " ]" -.RB "[ " ttl +.RB "[ " ttl "|" hoplimit .IR TTL " ]" .br .RB "[ " tos @@ -50,7 +48,7 @@ ip-tunnel - tunnel configuration .ti -8 .IR MODE " := " -.RB " { " ipip " | " gre " | " sit " | " isatap " | " ip6ip6 " | " ipip6 " | " ip6gre " | " any " }" +.RB " { " ipip " | " gre " | " sit " | " isatap " | " vti " | " ip6ip6 " | " ipip6 " | " ip6gre " | " vti6 " | " any " }" .ti -8 .IR ADDR " := { " IP_ADDRESS " |" @@ -107,10 +105,10 @@ select the tunnel device name. set the tunnel mode. Available modes depend on the encapsulating address family. .br Modes for IPv4 encapsulation available: -.BR ipip ", " sit ", " isatap " and " gre "." +.BR ipip ", " sit ", " isatap ", " vti ", and " gre "." .br Modes for IPv6 encapsulation available: -.BR ip6ip6 ", " ipip6 ", " ip6gre ", and " any "." +.BR ip6ip6 ", " ipip6 ", " ip6gre ", " vti6 ", and " any "." .TP .BI remote " ADDRESS" @@ -123,7 +121,9 @@ It must be an address on another interface of this host. .TP .BI ttl " N" -set a fixed TTL +.TP +.BI hoplimit " N" +set a fixed TTL (IPv4) or hoplimit (IPv6) .I N on tunneled packets. .I N @@ -218,7 +218,7 @@ The .B seq flag is equivalent to the combination .BR "iseq oseq" . -.B It isn't work. Don't use it. +.B It doesn't work. Don't use it. .TP .BI encaplim " ELIM" From ec4ef6aebd5a52ab1acf1f5be1749320b3188659 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 31 Aug 2015 16:31:15 -0700 Subject: [PATCH 5/5] v4.2.0 --- include/SNAPSHOT.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/SNAPSHOT.h b/include/SNAPSHOT.h index bfbaaecf..68dc6b43 100644 --- a/include/SNAPSHOT.h +++ b/include/SNAPSHOT.h @@ -1 +1 @@ -static const char SNAPSHOT[] = "150626"; +static const char SNAPSHOT[] = "150831";