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"; 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 13d9c465..2aa5fbfb 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) { @@ -892,18 +983,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) @@ -936,6 +1029,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, @@ -1018,6 +1114,7 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, } } fprintf(fp, "\n"); +brief_exit: fflush(fp); return 0; } @@ -1078,6 +1175,10 @@ static int print_selected_addrinfo(struct ifinfomsg *ifi, print_addrinfo(NULL, n, fp); } + if (brief) { + fprintf(fp, "\n"); + fflush(fp); + } return 0; } @@ -1539,9 +1640,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 8bc9f497..97f46cde 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"); @@ -106,7 +106,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; } @@ -268,6 +270,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); @@ -276,19 +279,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(); @@ -297,10 +300,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), @@ -324,6 +328,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; @@ -336,6 +341,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; @@ -348,6 +354,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; @@ -391,7 +398,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]; @@ -432,15 +440,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); @@ -458,7 +466,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); @@ -467,54 +476,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) @@ -526,6 +541,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) @@ -534,16 +550,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(); @@ -564,6 +582,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) @@ -571,6 +590,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) @@ -596,6 +616,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) @@ -626,9 +647,9 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, addattr8(&req->n, sizeof(*req), IFLA_PROTO_DOWN, proto_down); } else { - if (strcmp(*argv, "dev") == 0) { + if (strcmp(*argv, "dev") == 0) NEXT_ARG(); - } + if (matches(*argv, "help") == 0) usage(); if (*dev) @@ -823,7 +844,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; } @@ -966,14 +990,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; @@ -1064,63 +1088,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; @@ -1184,11 +1215,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 @@ -1203,35 +1233,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); } diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in index 2f689eda..1896eb6f 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" @@ -351,10 +352,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 @@ -1098,7 +1119,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 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"