Commit f1e225be authored by Stephen Hemminger's avatar Stephen Hemminger

Merge branch 'master' into net-next

parents 15faa0a3 ec4ef6ae
static const char SNAPSHOT[] = "150626"; static const char SNAPSHOT[] = "150831";
...@@ -19,6 +19,7 @@ extern int show_details; ...@@ -19,6 +19,7 @@ extern int show_details;
extern int show_raw; extern int show_raw;
extern int resolve_hosts; extern int resolve_hosts;
extern int oneline; extern int oneline;
extern int brief;
extern int timestamp; extern int timestamp;
extern int timestamp_short; extern int timestamp_short;
extern const char * _SL_; extern const char * _SL_;
......
...@@ -32,6 +32,7 @@ int show_stats; ...@@ -32,6 +32,7 @@ int show_stats;
int show_details; int show_details;
int resolve_hosts; int resolve_hosts;
int oneline; int oneline;
int brief;
int timestamp; int timestamp;
const char *_SL_; const char *_SL_;
int force; int force;
...@@ -55,7 +56,7 @@ static void usage(void) ...@@ -55,7 +56,7 @@ static void usage(void)
" -h[uman-readable] | -iec |\n" " -h[uman-readable] | -iec |\n"
" -f[amily] { inet | inet6 | ipx | dnet | mpls | bridge | link } |\n" " -f[amily] { inet | inet6 | ipx | dnet | mpls | bridge | link } |\n"
" -4 | -6 | -I | -D | -B | -0 |\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" " -o[neline] | -t[imestamp] | -ts[hort] | -b[atch] [filename] |\n"
" -rc[vbuf] [size] | -n[etns] name | -a[ll] | -c[olor]}\n"); " -rc[vbuf] [size] | -n[etns] name | -a[ll] | -c[olor]}\n");
exit(-1); exit(-1);
...@@ -250,6 +251,8 @@ int main(int argc, char **argv) ...@@ -250,6 +251,8 @@ int main(int argc, char **argv)
if (argc <= 1) if (argc <= 1)
usage(); usage();
batch_file = argv[1]; batch_file = argv[1];
} else if (matches(opt, "-brief") == 0) {
++brief;
} else if (matches(opt, "-rcvbuf") == 0) { } else if (matches(opt, "-rcvbuf") == 0) {
unsigned int size; unsigned int size;
......
...@@ -2,6 +2,9 @@ extern int get_operstate(const char *name); ...@@ -2,6 +2,9 @@ extern int get_operstate(const char *name);
extern int print_linkinfo(const struct sockaddr_nl *who, extern int print_linkinfo(const struct sockaddr_nl *who,
struct nlmsghdr *n, struct nlmsghdr *n,
void *arg); 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, extern int print_addrinfo(const struct sockaddr_nl *who,
struct nlmsghdr *n, struct nlmsghdr *n,
void *arg); void *arg);
......
...@@ -138,6 +138,14 @@ static void print_operstate(FILE *f, __u8 state) ...@@ -138,6 +138,14 @@ static void print_operstate(FILE *f, __u8 state)
if (state >= sizeof(oper_states)/sizeof(oper_states[0])) if (state >= sizeof(oper_states)/sizeof(oper_states[0]))
fprintf(f, "state %#x ", state); fprintf(f, "state %#x ", state);
else { else {
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 "); fprintf(f, "state ");
if (strcmp(oper_states[state], "UP") == 0) if (strcmp(oper_states[state], "UP") == 0)
color_fprintf(f, COLOR_OPERSTATE_UP, "%s ", oper_states[state]); color_fprintf(f, COLOR_OPERSTATE_UP, "%s ", oper_states[state]);
...@@ -146,6 +154,7 @@ static void print_operstate(FILE *f, __u8 state) ...@@ -146,6 +154,7 @@ static void print_operstate(FILE *f, __u8 state)
else else
fprintf(f, "%s ", oper_states[state]); fprintf(f, "%s ", oper_states[state]);
} }
}
} }
int get_operstate(const char *name) int get_operstate(const char *name)
...@@ -590,6 +599,88 @@ static void print_link_stats(FILE *fp, struct nlmsghdr *n) ...@@ -590,6 +599,88 @@ static void print_link_stats(FILE *fp, struct nlmsghdr *n)
fprintf(fp, "%s", _SL_); 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]) : "<nil>");
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, int print_linkinfo(const struct sockaddr_nl *who,
struct nlmsghdr *n, void *arg) struct nlmsghdr *n, void *arg)
{ {
...@@ -892,6 +983,7 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, ...@@ -892,6 +983,7 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n,
if (n->nlmsg_type == RTM_DELADDR) if (n->nlmsg_type == RTM_DELADDR)
fprintf(fp, "Deleted "); fprintf(fp, "Deleted ");
if (!brief) {
if (filter.oneline || filter.flushb) if (filter.oneline || filter.flushb)
fprintf(fp, "%u: %s", ifa->ifa_index, ll_index_to_name(ifa->ifa_index)); fprintf(fp, "%u: %s", ifa->ifa_index, ll_index_to_name(ifa->ifa_index));
if (ifa->ifa_family == AF_INET) if (ifa->ifa_family == AF_INET)
...@@ -904,6 +996,7 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, ...@@ -904,6 +996,7 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n,
fprintf(fp, " ipx "); fprintf(fp, " ipx ");
else else
fprintf(fp, " family %d ", ifa->ifa_family); fprintf(fp, " family %d ", ifa->ifa_family);
}
if (rta_tb[IFA_LOCAL]) { if (rta_tb[IFA_LOCAL]) {
if (ifa->ifa_family == AF_INET) if (ifa->ifa_family == AF_INET)
...@@ -936,6 +1029,9 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, ...@@ -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]) { if (rta_tb[IFA_BROADCAST]) {
fprintf(fp, "brd %s ", fprintf(fp, "brd %s ",
format_host(ifa->ifa_family, format_host(ifa->ifa_family,
...@@ -1018,6 +1114,7 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, ...@@ -1018,6 +1114,7 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n,
} }
} }
fprintf(fp, "\n"); fprintf(fp, "\n");
brief_exit:
fflush(fp); fflush(fp);
return 0; return 0;
} }
...@@ -1078,6 +1175,10 @@ static int print_selected_addrinfo(struct ifinfomsg *ifi, ...@@ -1078,6 +1175,10 @@ static int print_selected_addrinfo(struct ifinfomsg *ifi,
print_addrinfo(NULL, n, fp); print_addrinfo(NULL, n, fp);
} }
if (brief) {
fprintf(fp, "\n");
fflush(fp);
}
return 0; return 0;
} }
...@@ -1539,9 +1640,16 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action) ...@@ -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) { for (l = linfo.head; l; l = l->next) {
int res = 0; int res = 0;
if (no_link || (res = print_linkinfo(NULL, &l->h, stdout)) >= 0) {
struct ifinfomsg *ifi = NLMSG_DATA(&l->h); 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) if (filter.family != AF_PACKET)
print_selected_addrinfo(ifi, print_selected_addrinfo(ifi,
ainfo.head, stdout); ainfo.head, stdout);
......
...@@ -77,10 +77,10 @@ void iplink_usage(void) ...@@ -77,10 +77,10 @@ void iplink_usage(void)
fprintf(stderr, " [ vf NUM [ mac LLADDR ]\n"); fprintf(stderr, " [ vf NUM [ mac LLADDR ]\n");
fprintf(stderr, " [ vlan VLANID [ qos VLAN-QOS ] ]\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, " [ spoofchk { on | off} ] ]\n");
fprintf(stderr, " [ query_rss { on | off} ] ] \n"); fprintf(stderr, " [ query_rss { on | off} ] ]\n");
fprintf(stderr, " [ state { auto | enable | disable} ] ]\n"); fprintf(stderr, " [ state { auto | enable | disable} ] ]\n");
fprintf(stderr, " [ master DEVICE ]\n"); fprintf(stderr, " [ master DEVICE ]\n");
fprintf(stderr, " [ nomaster ]\n"); fprintf(stderr, " [ nomaster ]\n");
...@@ -106,7 +106,9 @@ static void usage(void) ...@@ -106,7 +106,9 @@ static void usage(void)
static int on_off(const char *msg, const char *realval) 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; return -1;
} }
...@@ -268,6 +270,7 @@ static int iplink_parse_vf(int vf, int *argcp, char ***argvp, ...@@ -268,6 +270,7 @@ static int iplink_parse_vf(int vf, int *argcp, char ***argvp,
NEXT_ARG(); NEXT_ARG();
if (matches(*argv, "mac") == 0) { if (matches(*argv, "mac") == 0) {
struct ifla_vf_mac ivm; struct ifla_vf_mac ivm;
NEXT_ARG(); NEXT_ARG();
ivm.vf = vf; ivm.vf = vf;
len = ll_addr_a2n((char *)ivm.mac, 32, *argv); len = ll_addr_a2n((char *)ivm.mac, 32, *argv);
...@@ -276,19 +279,19 @@ static int iplink_parse_vf(int vf, int *argcp, char ***argvp, ...@@ -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)); addattr_l(&req->n, sizeof(*req), IFLA_VF_MAC, &ivm, sizeof(ivm));
} else if (matches(*argv, "vlan") == 0) { } else if (matches(*argv, "vlan") == 0) {
struct ifla_vf_vlan ivv; struct ifla_vf_vlan ivv;
NEXT_ARG(); NEXT_ARG();
if (get_unsigned(&ivv.vlan, *argv, 0)) { if (get_unsigned(&ivv.vlan, *argv, 0))
invarg("Invalid \"vlan\" value\n", *argv); invarg("Invalid \"vlan\" value\n", *argv);
}
ivv.vf = vf; ivv.vf = vf;
ivv.qos = 0; ivv.qos = 0;
if (NEXT_ARG_OK()) { if (NEXT_ARG_OK()) {
NEXT_ARG(); NEXT_ARG();
if (matches(*argv, "qos") == 0) { if (matches(*argv, "qos") == 0) {
NEXT_ARG(); NEXT_ARG();
if (get_unsigned(&ivv.qos, *argv, 0)) { if (get_unsigned(&ivv.qos, *argv, 0))
invarg("Invalid \"qos\" value\n", *argv); invarg("Invalid \"qos\" value\n", *argv);
}
} else { } else {
/* rewind arg */ /* rewind arg */
PREV_ARG(); PREV_ARG();
...@@ -297,10 +300,11 @@ static int iplink_parse_vf(int vf, int *argcp, char ***argvp, ...@@ -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)); addattr_l(&req->n, sizeof(*req), IFLA_VF_VLAN, &ivv, sizeof(ivv));
} else if (matches(*argv, "rate") == 0) { } else if (matches(*argv, "rate") == 0) {
struct ifla_vf_tx_rate ivt; struct ifla_vf_tx_rate ivt;
NEXT_ARG(); NEXT_ARG();
if (get_unsigned(&ivt.rate, *argv, 0)) { if (get_unsigned(&ivt.rate, *argv, 0))
invarg("Invalid \"rate\" value\n", *argv); invarg("Invalid \"rate\" value\n", *argv);
}
ivt.vf = vf; ivt.vf = vf;
if (!new_rate_api) if (!new_rate_api)
addattr_l(&req->n, sizeof(*req), addattr_l(&req->n, sizeof(*req),
...@@ -324,6 +328,7 @@ static int iplink_parse_vf(int vf, int *argcp, char ***argvp, ...@@ -324,6 +328,7 @@ static int iplink_parse_vf(int vf, int *argcp, char ***argvp,
} else if (matches(*argv, "spoofchk") == 0) { } else if (matches(*argv, "spoofchk") == 0) {
struct ifla_vf_spoofchk ivs; struct ifla_vf_spoofchk ivs;
NEXT_ARG(); NEXT_ARG();
if (matches(*argv, "on") == 0) if (matches(*argv, "on") == 0)
ivs.setting = 1; ivs.setting = 1;
...@@ -336,6 +341,7 @@ static int iplink_parse_vf(int vf, int *argcp, char ***argvp, ...@@ -336,6 +341,7 @@ static int iplink_parse_vf(int vf, int *argcp, char ***argvp,
} else if (matches(*argv, "query_rss") == 0) { } else if (matches(*argv, "query_rss") == 0) {
struct ifla_vf_rss_query_en ivs; struct ifla_vf_rss_query_en ivs;
NEXT_ARG(); NEXT_ARG();
if (matches(*argv, "on") == 0) if (matches(*argv, "on") == 0)
ivs.setting = 1; ivs.setting = 1;
...@@ -348,6 +354,7 @@ static int iplink_parse_vf(int vf, int *argcp, char ***argvp, ...@@ -348,6 +354,7 @@ static int iplink_parse_vf(int vf, int *argcp, char ***argvp,
} else if (matches(*argv, "state") == 0) { } else if (matches(*argv, "state") == 0) {
struct ifla_vf_link_state ivl; struct ifla_vf_link_state ivl;
NEXT_ARG(); NEXT_ARG();
if (matches(*argv, "auto") == 0) if (matches(*argv, "auto") == 0)
ivl.link_state = IFLA_VF_LINK_STATE_AUTO; ivl.link_state = IFLA_VF_LINK_STATE_AUTO;
...@@ -391,7 +398,8 @@ static int iplink_parse_vf(int vf, int *argcp, char ***argvp, ...@@ -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, 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; int ret, len;
char abuf[32]; char abuf[32];
...@@ -458,7 +466,8 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, ...@@ -458,7 +466,8 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req,
NEXT_ARG(); NEXT_ARG();
if (netns != -1) if (netns != -1)
duparg("netns", *argv); 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); addattr_l(&req->n, sizeof(*req), IFLA_NET_NS_FD, &netns, 4);
else if (get_integer(&netns, *argv, 0) == 0) else if (get_integer(&netns, *argv, 0) == 0)
addattr_l(&req->n, sizeof(*req), IFLA_NET_NS_PID, &netns, 4); 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, ...@@ -467,54 +476,60 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req,
} else if (strcmp(*argv, "multicast") == 0) { } else if (strcmp(*argv, "multicast") == 0) {
NEXT_ARG(); NEXT_ARG();
req->i.ifi_change |= IFF_MULTICAST; req->i.ifi_change |= IFF_MULTICAST;
if (strcmp(*argv, "on") == 0) {
if (strcmp(*argv, "on") == 0)
req->i.ifi_flags |= IFF_MULTICAST; req->i.ifi_flags |= IFF_MULTICAST;
} else if (strcmp(*argv, "off") == 0) { else if (strcmp(*argv, "off") == 0)
req->i.ifi_flags &= ~IFF_MULTICAST; req->i.ifi_flags &= ~IFF_MULTICAST;
} else else
return on_off("multicast", *argv); return on_off("multicast", *argv);
} else if (strcmp(*argv, "allmulticast") == 0) { } else if (strcmp(*argv, "allmulticast") == 0) {
NEXT_ARG(); NEXT_ARG();
req->i.ifi_change |= IFF_ALLMULTI; req->i.ifi_change |= IFF_ALLMULTI;
if (strcmp(*argv, "on") == 0) {
if (strcmp(*argv, "on") == 0)
req->i.ifi_flags |= IFF_ALLMULTI; req->i.ifi_flags |= IFF_ALLMULTI;
} else if (strcmp(*argv, "off") == 0) { else if (strcmp(*argv, "off") == 0)
req->i.ifi_flags &= ~IFF_ALLMULTI; req->i.ifi_flags &= ~IFF_ALLMULTI;
} else else
return on_off("allmulticast", *argv); return on_off("allmulticast", *argv);
} else if (strcmp(*argv, "promisc") == 0) { } else if (strcmp(*argv, "promisc") == 0) {
NEXT_ARG(); NEXT_ARG();
req->i.ifi_change |= IFF_PROMISC; req->i.ifi_change |= IFF_PROMISC;
if (strcmp(*argv, "on") == 0) {
if (strcmp(*argv, "on") == 0)
req->i.ifi_flags |= IFF_PROMISC; req->i.ifi_flags |= IFF_PROMISC;
} else if (strcmp(*argv, "off") == 0) { else if (strcmp(*argv, "off") == 0)
req->i.ifi_flags &= ~IFF_PROMISC; req->i.ifi_flags &= ~IFF_PROMISC;
} else else
return on_off("promisc", *argv); return on_off("promisc", *argv);
} else if (strcmp(*argv, "trailers") == 0) { } else if (strcmp(*argv, "trailers") == 0) {
NEXT_ARG(); NEXT_ARG();
req->i.ifi_change |= IFF_NOTRAILERS; req->i.ifi_change |= IFF_NOTRAILERS;
if (strcmp(*argv, "off") == 0) {
if (strcmp(*argv, "off") == 0)
req->i.ifi_flags |= IFF_NOTRAILERS; req->i.ifi_flags |= IFF_NOTRAILERS;
} else if (strcmp(*argv, "on") == 0) { else if (strcmp(*argv, "on") == 0)
req->i.ifi_flags &= ~IFF_NOTRAILERS; req->i.ifi_flags &= ~IFF_NOTRAILERS;
} else else
return on_off("trailers", *argv); return on_off("trailers", *argv);
} else if (strcmp(*argv, "arp") == 0) { } else if (strcmp(*argv, "arp") == 0) {
NEXT_ARG(); NEXT_ARG();
req->i.ifi_change |= IFF_NOARP; req->i.ifi_change |= IFF_NOARP;
if (strcmp(*argv, "on") == 0) {
if (strcmp(*argv, "on") == 0)
req->i.ifi_flags &= ~IFF_NOARP; req->i.ifi_flags &= ~IFF_NOARP;
} else if (strcmp(*argv, "off") == 0) { else if (strcmp(*argv, "off") == 0)
req->i.ifi_flags |= IFF_NOARP; req->i.ifi_flags |= IFF_NOARP;
} else else
return on_off("arp", *argv); return on_off("arp", *argv);
} else if (strcmp(*argv, "vf") == 0) { } else if (strcmp(*argv, "vf") == 0) {
struct rtattr *vflist; struct rtattr *vflist;
NEXT_ARG(); NEXT_ARG();
if (get_integer(&vf, *argv, 0)) { if (get_integer(&vf, *argv, 0))
invarg("Invalid \"vf\" value\n", *argv); invarg("Invalid \"vf\" value\n", *argv);
}
vflist = addattr_nest(&req->n, sizeof(*req), vflist = addattr_nest(&req->n, sizeof(*req),
IFLA_VFINFO_LIST); IFLA_VFINFO_LIST);
if (dev_index == 0) if (dev_index == 0)
...@@ -526,6 +541,7 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, ...@@ -526,6 +541,7 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req,
addattr_nest_end(&req->n, vflist); addattr_nest_end(&req->n, vflist);
} else if (matches(*argv, "master") == 0) { } else if (matches(*argv, "master") == 0) {
int ifindex; int ifindex;
NEXT_ARG(); NEXT_ARG();
ifindex = ll_name_to_index(*argv); ifindex = ll_name_to_index(*argv);
if (!ifindex) if (!ifindex)
...@@ -534,16 +550,18 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, ...@@ -534,16 +550,18 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req,
&ifindex, 4); &ifindex, 4);
} else if (matches(*argv, "nomaster") == 0) { } else if (matches(*argv, "nomaster") == 0) {
int ifindex = 0; int ifindex = 0;
addattr_l(&req->n, sizeof(*req), IFLA_MASTER, addattr_l(&req->n, sizeof(*req), IFLA_MASTER,
&ifindex, 4); &ifindex, 4);
} else if (matches(*argv, "dynamic") == 0) { } else if (matches(*argv, "dynamic") == 0) {
NEXT_ARG(); NEXT_ARG();
req->i.ifi_change |= IFF_DYNAMIC; req->i.ifi_change |= IFF_DYNAMIC;
if (strcmp(*argv, "on") == 0) {
if (strcmp(*argv, "on") == 0)
req->i.ifi_flags |= IFF_DYNAMIC; req->i.ifi_flags |= IFF_DYNAMIC;
} else if (strcmp(*argv, "off") == 0) { else if (strcmp(*argv, "off") == 0)
req->i.ifi_flags &= ~IFF_DYNAMIC; req->i.ifi_flags &= ~IFF_DYNAMIC;
} else else
return on_off("dynamic", *argv); return on_off("dynamic", *argv);
} else if (matches(*argv, "type") == 0) { } else if (matches(*argv, "type") == 0) {
NEXT_ARG(); NEXT_ARG();
...@@ -564,6 +582,7 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, ...@@ -564,6 +582,7 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req,
invarg("Invalid \"group\" value\n", *argv); invarg("Invalid \"group\" value\n", *argv);
} else if (strcmp(*argv, "mode") == 0) { } else if (strcmp(*argv, "mode") == 0) {
int mode; int mode;
NEXT_ARG(); NEXT_ARG();
mode = get_link_mode(*argv); mode = get_link_mode(*argv);
if (mode < 0) if (mode < 0)
...@@ -571,6 +590,7 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, ...@@ -571,6 +590,7 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req,
addattr8(&req->n, sizeof(*req), IFLA_LINKMODE, mode); addattr8(&req->n, sizeof(*req), IFLA_LINKMODE, mode);
} else if (strcmp(*argv, "state") == 0) { } else if (strcmp(*argv, "state") == 0) {
int state; int state;
NEXT_ARG(); NEXT_ARG();
state = get_operstate(*argv); state = get_operstate(*argv);
if (state < 0) if (state < 0)
...@@ -596,6 +616,7 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, ...@@ -596,6 +616,7 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req,
} else if (matches(*argv, "addrgenmode") == 0) { } else if (matches(*argv, "addrgenmode") == 0) {
struct rtattr *afs, *afs6; struct rtattr *afs, *afs6;
int mode; int mode;
NEXT_ARG(); NEXT_ARG();
mode = get_addr_gen_mode(*argv); mode = get_addr_gen_mode(*argv);
if (mode < 0) if (mode < 0)
...@@ -626,9 +647,9 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, ...@@ -626,9 +647,9 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req,
addattr8(&req->n, sizeof(*req), IFLA_PROTO_DOWN, addattr8(&req->n, sizeof(*req), IFLA_PROTO_DOWN,
proto_down); proto_down);
} else { } else {
if (strcmp(*argv, "dev") == 0) { if (strcmp(*argv, "dev") == 0)
NEXT_ARG(); NEXT_ARG();
}
if (matches(*argv, "help") == 0) if (matches(*argv, "help") == 0)
usage(); usage();
if (*dev) if (*dev)
...@@ -823,6 +844,9 @@ int iplink_get(unsigned int flags, char *name, __u32 filt_mask) ...@@ -823,6 +844,9 @@ int iplink_get(unsigned int flags, char *name, __u32 filt_mask)
if (rtnl_talk(&rth, &req.n, &answer.n, sizeof(answer)) < 0) if (rtnl_talk(&rth, &req.n, &answer.n, sizeof(answer)) < 0)
return -2; return -2;
if (brief)
print_linkinfo_brief(NULL, &answer.n, stdout);
else
print_linkinfo(NULL, &answer.n, stdout); print_linkinfo(NULL, &answer.n, stdout);
return 0; return 0;
...@@ -966,14 +990,14 @@ static int get_address(const char *dev, int *htype) ...@@ -966,14 +990,14 @@ static int get_address(const char *dev, int *htype)
me.sll_family = AF_PACKET; me.sll_family = AF_PACKET;
me.sll_ifindex = ifr.ifr_ifindex; me.sll_ifindex = ifr.ifr_ifindex;
me.sll_protocol = htons(ETH_P_LOOP); 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"); perror("bind");
close(s); close(s);
return -1; return -1;
} }
alen = sizeof(me); alen = sizeof(me);
if (getsockname(s, (struct sockaddr*)&me, &alen) == -1) { if (getsockname(s, (struct sockaddr *)&me, &alen) == -1) {
perror("getsockname"); perror("getsockname");
close(s); close(s);
return -1; return -1;
...@@ -1064,63 +1088,70 @@ static int do_set(int argc, char **argv) ...@@ -1064,63 +1088,70 @@ static int do_set(int argc, char **argv)
} else if (strcmp(*argv, "multicast") == 0) { } else if (strcmp(*argv, "multicast") == 0) {
NEXT_ARG(); NEXT_ARG();
mask |= IFF_MULTICAST; mask |= IFF_MULTICAST;
if (strcmp(*argv, "on") == 0) {
if (strcmp(*argv, "on") == 0)
flags |= IFF_MULTICAST; flags |= IFF_MULTICAST;
} else if (strcmp(*argv, "off") == 0) { else if (strcmp(*argv, "off") == 0)
flags &= ~IFF_MULTICAST; flags &= ~IFF_MULTICAST;
} else else
return on_off("multicast", *argv); return on_off("multicast", *argv);
} else if (strcmp(*argv, "allmulticast") == 0) { } else if (strcmp(*argv, "allmulticast") == 0) {
NEXT_ARG(); NEXT_ARG();
mask |= IFF_ALLMULTI; mask |= IFF_ALLMULTI;
if (strcmp(*argv, "on") == 0) {
if (strcmp(*argv, "on") == 0)
flags |= IFF_ALLMULTI; flags |= IFF_ALLMULTI;
} else if (strcmp(*argv, "off") == 0) { else if (strcmp(*argv, "off") == 0)
flags &= ~IFF_ALLMULTI; flags &= ~IFF_ALLMULTI;
} else else
return on_off("allmulticast", *argv); return on_off("allmulticast", *argv);
} else if (strcmp(*argv, "promisc") == 0) { } else if (strcmp(*argv, "promisc") == 0) {
NEXT_ARG(); NEXT_ARG();
mask |= IFF_PROMISC; mask |= IFF_PROMISC;
if (strcmp(*argv, "on") == 0) {
if (strcmp(*argv, "on") == 0)
flags |= IFF_PROMISC; flags |= IFF_PROMISC;
} else if (strcmp(*argv, "off") == 0) { else if (strcmp(*argv, "off") == 0)
flags &= ~IFF_PROMISC; flags &= ~IFF_PROMISC;
} else else
return on_off("promisc", *argv); return on_off("promisc", *argv);
} else if (strcmp(*argv, "trailers") == 0) { } else if (strcmp(*argv, "trailers") == 0) {
NEXT_ARG(); NEXT_ARG();
mask |= IFF_NOTRAILERS; mask |= IFF_NOTRAILERS;
if (strcmp(*argv, "off") == 0) {
if (strcmp(*argv, "off") == 0)
flags |= IFF_NOTRAILERS; flags |= IFF_NOTRAILERS;
} else if (strcmp(*argv, "on") == 0) { else if (strcmp(*argv, "on") == 0)
flags &= ~IFF_NOTRAILERS; flags &= ~IFF_NOTRAILERS;
} else else
return on_off("trailers", *argv); return on_off("trailers", *argv);
} else if (strcmp(*argv, "arp") == 0) { } else if (strcmp(*argv, "arp") == 0) {
NEXT_ARG(); NEXT_ARG();
mask |= IFF_NOARP; mask |= IFF_NOARP;
if (strcmp(*argv, "on") == 0) {
if (strcmp(*argv, "on") == 0)
flags &= ~IFF_NOARP; flags &= ~IFF_NOARP;
} else if (strcmp(*argv, "off") == 0) { else if (strcmp(*argv, "off") == 0)
flags |= IFF_NOARP; flags |= IFF_NOARP;
} else else
return on_off("arp", *argv); return on_off("arp", *argv);
} else if (matches(*argv, "dynamic") == 0) { } else if (matches(*argv, "dynamic") == 0) {
NEXT_ARG(); NEXT_ARG();
mask |= IFF_DYNAMIC; mask |= IFF_DYNAMIC;
if (strcmp(*argv, "on") == 0) {
if (strcmp(*argv, "on") == 0)
flags |= IFF_DYNAMIC; flags |= IFF_DYNAMIC;
} else if (strcmp(*argv, "off") == 0) { else if (strcmp(*argv, "off") == 0)
flags &= ~IFF_DYNAMIC; flags &= ~IFF_DYNAMIC;
} else else
return on_off("dynamic", *argv); return on_off("dynamic", *argv);
} else { } else {
if (strcmp(*argv, "dev") == 0) { if (strcmp(*argv, "dev") == 0)
NEXT_ARG(); NEXT_ARG();
}
if (matches(*argv, "help") == 0) if (matches(*argv, "help") == 0)
usage(); usage();
if (dev) if (dev)
duparg2("dev", *argv); duparg2("dev", *argv);
dev = *argv; dev = *argv;
...@@ -1184,11 +1215,10 @@ static void do_help(int argc, char **argv) ...@@ -1184,11 +1215,10 @@ static void do_help(int argc, char **argv)
if (argc <= 0) { if (argc <= 0) {
usage(); usage();
return ; return;
} }
lu = get_link_kind(*argv); lu = get_link_kind(*argv);
if (lu && lu->print_help) if (lu && lu->print_help)
lu->print_help(lu, argc-1, argv+1, stdout); lu->print_help(lu, argc-1, argv+1, stdout);
else else
...@@ -1222,10 +1252,12 @@ int do_iplink(int argc, char **argv) ...@@ -1222,10 +1252,12 @@ int do_iplink(int argc, char **argv)
return do_set(argc-1, argv+1); return do_set(argc-1, argv+1);
#endif #endif
} }
if (matches(*argv, "show") == 0 || if (matches(*argv, "show") == 0 ||
matches(*argv, "lst") == 0 || matches(*argv, "lst") == 0 ||
matches(*argv, "list") == 0) matches(*argv, "list") == 0)
return ipaddr_list_link(argc-1, argv+1); return ipaddr_list_link(argc-1, argv+1);
if (matches(*argv, "help") == 0) { if (matches(*argv, "help") == 0) {
do_help(argc-1, argv+1); do_help(argc-1, argv+1);
return 0; return 0;
......
...@@ -21,7 +21,8 @@ ip-link \- network device configuration ...@@ -21,7 +21,8 @@ ip-link \- network device configuration
\fB\-r\fR[\fIesolve\fR] | \fB\-r\fR[\fIesolve\fR] |
\fB\-f\fR[\fIamily\fR] { \fB\-f\fR[\fIamily\fR] {
.BR inet " | " inet6 " | " ipx " | " dnet " | " link " } | " .BR inet " | " inet6 " | " ipx " | " dnet " | " link " } | "
\fB\-o\fR[\fIneline\fR] } \fB\-o\fR[\fIneline\fR] |
\fB\-br\fR[\fIief\fR] }
.ti -8 .ti -8
.BI "ip link add" .BI "ip link add"
...@@ -351,10 +352,30 @@ where <phy_dev> is the physical device to which VLAN device is bound. ...@@ -351,10 +352,30 @@ where <phy_dev> is the physical device to which VLAN device is bound.
- specifies whether the VLAN device state is bound to the physical device state. - specifies whether the VLAN device state is bound to the physical device state.
.BI ingress-qos-map " QOS-MAP " .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 " .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 .in -8
.TP .TP
...@@ -1098,7 +1119,8 @@ IEEE 802.15.4 device wpan0. ...@@ -1098,7 +1119,8 @@ IEEE 802.15.4 device wpan0.
.br .br
.BR ip (8), .BR ip (8),
.BR ip-netns (8), .BR ip-netns (8),
.BR ethtool (8) .BR ethtool (8),
.BR iptables (8)
.SH AUTHOR .SH AUTHOR
Original Manpage by Michail Litvak <mci@owl.openwall.com> Original Manpage by Michail Litvak <mci@owl.openwall.com>
...@@ -6,14 +6,12 @@ ip-tunnel - tunnel configuration ...@@ -6,14 +6,12 @@ ip-tunnel - tunnel configuration
.ad l .ad l
.in +8 .in +8
.ti -8 .ti -8
.B ip .B ip tunnel help
.RI "[ " OPTIONS " ]"
.B tunnel
.RI " { " COMMAND " | "
.BR help " }"
.sp .sp
.ti -8 .ti -8
.BR "ip tunnel" " { " add " | " change " | " del " | " show " | " prl " }" .BR "ip "
.RI "[ " OPTIONS " ]"
.BR "tunnel" " { " add " | " change " | " del " | " show " | " prl " }"
.RI "[ " NAME " ]" .RI "[ " NAME " ]"
.br .br
.RB "[ " mode .RB "[ " mode
...@@ -29,7 +27,7 @@ ip-tunnel - tunnel configuration ...@@ -29,7 +27,7 @@ ip-tunnel - tunnel configuration
.br .br
.RB "[ " encaplimit .RB "[ " encaplimit
.IR ELIM " ]" .IR ELIM " ]"
.RB "[ " ttl .RB "[ " ttl "|" hoplimit
.IR TTL " ]" .IR TTL " ]"
.br .br
.RB "[ " tos .RB "[ " tos
...@@ -50,7 +48,7 @@ ip-tunnel - tunnel configuration ...@@ -50,7 +48,7 @@ ip-tunnel - tunnel configuration
.ti -8 .ti -8
.IR MODE " := " .IR MODE " := "
.RB " { " ipip " | " gre " | " sit " | " isatap " | " ip6ip6 " | " ipip6 " | " ip6gre " | " any " }" .RB " { " ipip " | " gre " | " sit " | " isatap " | " vti " | " ip6ip6 " | " ipip6 " | " ip6gre " | " vti6 " | " any " }"
.ti -8 .ti -8
.IR ADDR " := { " IP_ADDRESS " |" .IR ADDR " := { " IP_ADDRESS " |"
...@@ -107,10 +105,10 @@ select the tunnel device name. ...@@ -107,10 +105,10 @@ select the tunnel device name.
set the tunnel mode. Available modes depend on the encapsulating address family. set the tunnel mode. Available modes depend on the encapsulating address family.
.br .br
Modes for IPv4 encapsulation available: Modes for IPv4 encapsulation available:
.BR ipip ", " sit ", " isatap " and " gre "." .BR ipip ", " sit ", " isatap ", " vti ", and " gre "."
.br .br
Modes for IPv6 encapsulation available: Modes for IPv6 encapsulation available:
.BR ip6ip6 ", " ipip6 ", " ip6gre ", and " any "." .BR ip6ip6 ", " ipip6 ", " ip6gre ", " vti6 ", and " any "."
.TP .TP
.BI remote " ADDRESS" .BI remote " ADDRESS"
...@@ -123,7 +121,9 @@ It must be an address on another interface of this host. ...@@ -123,7 +121,9 @@ It must be an address on another interface of this host.
.TP .TP
.BI ttl " N" .BI ttl " N"
set a fixed TTL .TP
.BI hoplimit " N"
set a fixed TTL (IPv4) or hoplimit (IPv6)
.I N .I N
on tunneled packets. on tunneled packets.
.I N .I N
...@@ -218,7 +218,7 @@ The ...@@ -218,7 +218,7 @@ The
.B seq .B seq
flag is equivalent to the combination flag is equivalent to the combination
.BR "iseq oseq" . .BR "iseq oseq" .
.B It isn't work. Don't use it. .B It doesn't work. Don't use it.
.TP .TP
.BI encaplim " ELIM" .BI encaplim " ELIM"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment