Merge branch 'iproute2-master' into iproute2-next
Signed-off-by: David Ahern <dsahern@gmail.com>
This commit is contained in:
commit
c4e0ea8e9b
2
Makefile
2
Makefile
|
|
@ -96,7 +96,7 @@ snapshot:
|
|||
> include/SNAPSHOT.h
|
||||
|
||||
clean:
|
||||
@for i in $(SUBDIRS); \
|
||||
@for i in $(SUBDIRS) testsuite; \
|
||||
do $(MAKE) $(MFLAGS) -C $$i clean; done
|
||||
|
||||
clobber:
|
||||
|
|
|
|||
|
|
@ -6,20 +6,20 @@
|
|||
#define MDB_RTR_RTA(r) \
|
||||
((struct rtattr *)(((char *)(r)) + RTA_ALIGN(sizeof(__u32))))
|
||||
|
||||
extern void print_vlan_info(FILE *fp, struct rtattr *tb);
|
||||
extern int print_linkinfo(const struct sockaddr_nl *who,
|
||||
void print_vlan_info(FILE *fp, struct rtattr *tb);
|
||||
int print_linkinfo(const struct sockaddr_nl *who,
|
||||
struct nlmsghdr *n,
|
||||
void *arg);
|
||||
extern int print_fdb(const struct sockaddr_nl *who,
|
||||
int print_fdb(const struct sockaddr_nl *who,
|
||||
struct nlmsghdr *n, void *arg);
|
||||
extern int print_mdb(const struct sockaddr_nl *who,
|
||||
int print_mdb(const struct sockaddr_nl *who,
|
||||
struct nlmsghdr *n, void *arg);
|
||||
|
||||
extern int do_fdb(int argc, char **argv);
|
||||
extern int do_mdb(int argc, char **argv);
|
||||
extern int do_monitor(int argc, char **argv);
|
||||
extern int do_vlan(int argc, char **argv);
|
||||
extern int do_link(int argc, char **argv);
|
||||
int do_fdb(int argc, char **argv);
|
||||
int do_mdb(int argc, char **argv);
|
||||
int do_monitor(int argc, char **argv);
|
||||
int do_vlan(int argc, char **argv);
|
||||
int do_link(int argc, char **argv);
|
||||
|
||||
extern int preferred_family;
|
||||
extern int show_stats;
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ static void usage(void)
|
|||
"where OBJECT := { link | fdb | mdb | vlan | monitor }\n"
|
||||
" OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] |\n"
|
||||
" -o[neline] | -t[imestamp] | -n[etns] name |\n"
|
||||
" -c[ompressvlans] -color -p[retty] -j{son} }\n");
|
||||
" -c[ompressvlans] -color -p[retty] -j[son] }\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
|
@ -173,8 +173,7 @@ main(int argc, char **argv)
|
|||
NEXT_ARG();
|
||||
if (netns_switch(argv[1]))
|
||||
exit(-1);
|
||||
} else if (matches(opt, "-color") == 0) {
|
||||
++color;
|
||||
} else if (matches_color(opt, &color)) {
|
||||
} else if (matches(opt, "-compressvlans") == 0) {
|
||||
++compress_vlans;
|
||||
} else if (matches(opt, "-force") == 0) {
|
||||
|
|
|
|||
|
|
@ -5426,7 +5426,7 @@ static void help(void)
|
|||
pr_err("Usage: devlink [ OPTIONS ] OBJECT { COMMAND | help }\n"
|
||||
" devlink [ -f[orce] ] -b[atch] filename\n"
|
||||
"where OBJECT := { dev | port | sb | monitor | dpipe | resource | region }\n"
|
||||
" OPTIONS := { -V[ersion] | -n[no-nice-names] | -j[json] | -p[pretty] | -v[verbose] }\n");
|
||||
" OPTIONS := { -V[ersion] | -n[o-nice-names] | -j[son] | -p[retty] | -v[erbose] }\n");
|
||||
}
|
||||
|
||||
static int dl_cmd(struct dl *dl, int argc, char **argv)
|
||||
|
|
|
|||
30
genl/genl.c
30
genl/genl.c
|
|
@ -26,12 +26,12 @@
|
|||
#include "utils.h"
|
||||
#include "genl_utils.h"
|
||||
|
||||
int show_stats = 0;
|
||||
int show_details = 0;
|
||||
int show_raw = 0;
|
||||
int show_stats;
|
||||
int show_details;
|
||||
int show_raw;
|
||||
|
||||
static void *BODY;
|
||||
static struct genl_util * genl_list;
|
||||
static struct genl_util *genl_list;
|
||||
|
||||
|
||||
static int print_nofopt(const struct sockaddr_nl *who, struct nlmsghdr *n,
|
||||
|
|
@ -44,8 +44,9 @@ static int print_nofopt(const struct sockaddr_nl *who, struct nlmsghdr *n,
|
|||
static int parse_nofopt(struct genl_util *f, int argc, char **argv)
|
||||
{
|
||||
if (argc) {
|
||||
fprintf(stderr, "Unknown genl \"%s\", hence option \"%s\" "
|
||||
"is unparsable\n", f->name, *argv);
|
||||
fprintf(stderr,
|
||||
"Unknown genl \"%s\", hence option \"%s\" is unparsable\n",
|
||||
f->name, *argv);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -98,9 +99,10 @@ static void usage(void) __attribute__((noreturn));
|
|||
|
||||
static void usage(void)
|
||||
{
|
||||
fprintf(stderr, "Usage: genl [ OPTIONS ] OBJECT | help }\n"
|
||||
"where OBJECT := { ctrl etc }\n"
|
||||
" OPTIONS := { -s[tatistics] | -d[etails] | -r[aw] }\n");
|
||||
fprintf(stderr,
|
||||
"Usage: genl [ OPTIONS ] OBJECT [help] }\n"
|
||||
"where OBJECT := { ctrl etc }\n"
|
||||
" OPTIONS := { -s[tatistics] | -d[etails] | -r[aw] | -V[ersion] | -h[elp] }\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
|
@ -122,19 +124,21 @@ int main(int argc, char **argv)
|
|||
} else if (matches(argv[1], "-help") == 0) {
|
||||
usage();
|
||||
} else {
|
||||
fprintf(stderr, "Option \"%s\" is unknown, try "
|
||||
"\"genl -help\".\n", argv[1]);
|
||||
fprintf(stderr,
|
||||
"Option \"%s\" is unknown, try \"genl -help\".\n",
|
||||
argv[1]);
|
||||
exit(-1);
|
||||
}
|
||||
argc--; argv++;
|
||||
}
|
||||
|
||||
if (argc > 1) {
|
||||
struct genl_util *a;
|
||||
int ret;
|
||||
struct genl_util *a = NULL;
|
||||
|
||||
a = get_genl_kind(argv[1]);
|
||||
if (!a) {
|
||||
fprintf(stderr,"bad genl %s\n", argv[1]);
|
||||
fprintf(stderr, "bad genl %s\n", argv[1]);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,9 +10,10 @@ struct genl_util
|
|||
struct genl_util *next;
|
||||
char name[16];
|
||||
int (*parse_genlopt)(struct genl_util *fu, int argc, char **argv);
|
||||
int (*print_genlopt)(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg);
|
||||
int (*print_genlopt)(const struct sockaddr_nl *who,
|
||||
struct nlmsghdr *n, void *arg);
|
||||
};
|
||||
|
||||
extern int genl_ctrl_resolve_family(const char *family);
|
||||
int genl_ctrl_resolve_family(const char *family);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
#ifndef __COLOR_H__
|
||||
#define __COLOR_H__ 1
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
enum color_attr {
|
||||
COLOR_IFNAME,
|
||||
COLOR_MAC,
|
||||
|
|
@ -12,8 +14,15 @@ enum color_attr {
|
|||
COLOR_NONE
|
||||
};
|
||||
|
||||
enum color_opt {
|
||||
COLOR_OPT_NEVER = 0,
|
||||
COLOR_OPT_AUTO = 1,
|
||||
COLOR_OPT_ALWAYS = 2
|
||||
};
|
||||
|
||||
void enable_color(void);
|
||||
int check_enable_color(int color, int json);
|
||||
bool check_enable_color(int color, int json);
|
||||
bool matches_color(const char *arg, int *val);
|
||||
void set_color_palette(void);
|
||||
int color_fprintf(FILE *fp, enum color_attr attr, const char *fmt, ...);
|
||||
enum color_attr ifa_family_color(__u8 ifa_family);
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ void jsonw_pretty(json_writer_t *self, bool on);
|
|||
void jsonw_name(json_writer_t *self, const char *name);
|
||||
|
||||
/* Add value */
|
||||
__attribute__((format(printf, 2, 3)))
|
||||
void jsonw_printf(json_writer_t *self, const char *fmt, ...);
|
||||
void jsonw_string(json_writer_t *self, const char *value);
|
||||
void jsonw_bool(json_writer_t *self, bool value);
|
||||
|
|
@ -59,8 +60,6 @@ void jsonw_luint_field(json_writer_t *self, const char *prop,
|
|||
unsigned long int num);
|
||||
void jsonw_lluint_field(json_writer_t *self, const char *prop,
|
||||
unsigned long long int num);
|
||||
void jsonw_float_field_fmt(json_writer_t *self, const char *prop,
|
||||
const char *fmt, double val);
|
||||
|
||||
/* Collections */
|
||||
void jsonw_start_object(json_writer_t *self);
|
||||
|
|
|
|||
|
|
@ -126,6 +126,7 @@ enum bpf_map_type {
|
|||
BPF_MAP_TYPE_XSKMAP,
|
||||
BPF_MAP_TYPE_SOCKHASH,
|
||||
BPF_MAP_TYPE_CGROUP_STORAGE,
|
||||
BPF_MAP_TYPE_REUSEPORT_SOCKARRAY,
|
||||
};
|
||||
|
||||
enum bpf_prog_type {
|
||||
|
|
@ -150,6 +151,7 @@ enum bpf_prog_type {
|
|||
BPF_PROG_TYPE_CGROUP_SOCK_ADDR,
|
||||
BPF_PROG_TYPE_LWT_SEG6LOCAL,
|
||||
BPF_PROG_TYPE_LIRC_MODE2,
|
||||
BPF_PROG_TYPE_SK_REUSEPORT,
|
||||
};
|
||||
|
||||
enum bpf_attach_type {
|
||||
|
|
@ -2091,6 +2093,24 @@ union bpf_attr {
|
|||
* Return
|
||||
* The id is returned or 0 in case the id could not be retrieved.
|
||||
*
|
||||
* u64 bpf_skb_ancestor_cgroup_id(struct sk_buff *skb, int ancestor_level)
|
||||
* Description
|
||||
* Return id of cgroup v2 that is ancestor of cgroup associated
|
||||
* with the *skb* at the *ancestor_level*. The root cgroup is at
|
||||
* *ancestor_level* zero and each step down the hierarchy
|
||||
* increments the level. If *ancestor_level* == level of cgroup
|
||||
* associated with *skb*, then return value will be same as that
|
||||
* of **bpf_skb_cgroup_id**\ ().
|
||||
*
|
||||
* The helper is useful to implement policies based on cgroups
|
||||
* that are upper in hierarchy than immediate cgroup associated
|
||||
* with *skb*.
|
||||
*
|
||||
* The format of returned id and helper limitations are same as in
|
||||
* **bpf_skb_cgroup_id**\ ().
|
||||
* Return
|
||||
* The id is returned or 0 in case the id could not be retrieved.
|
||||
*
|
||||
* u64 bpf_get_current_cgroup_id(void)
|
||||
* Return
|
||||
* A 64-bit integer containing the current cgroup id based
|
||||
|
|
@ -2113,6 +2133,14 @@ union bpf_attr {
|
|||
* the shared data.
|
||||
* Return
|
||||
* Pointer to the local storage area.
|
||||
*
|
||||
* int bpf_sk_select_reuseport(struct sk_reuseport_md *reuse, struct bpf_map *map, void *key, u64 flags)
|
||||
* Description
|
||||
* Select a SO_REUSEPORT sk from a BPF_MAP_TYPE_REUSEPORT_ARRAY map
|
||||
* It checks the selected sk is matching the incoming
|
||||
* request in the skb.
|
||||
* Return
|
||||
* 0 on success, or a negative error in case of failure.
|
||||
*/
|
||||
#define __BPF_FUNC_MAPPER(FN) \
|
||||
FN(unspec), \
|
||||
|
|
@ -2196,7 +2224,9 @@ union bpf_attr {
|
|||
FN(rc_keydown), \
|
||||
FN(skb_cgroup_id), \
|
||||
FN(get_current_cgroup_id), \
|
||||
FN(get_local_storage),
|
||||
FN(get_local_storage), \
|
||||
FN(sk_select_reuseport), \
|
||||
FN(skb_ancestor_cgroup_id),
|
||||
|
||||
/* integer value in 'imm' field of BPF_CALL instruction selects which helper
|
||||
* function eBPF program intends to call
|
||||
|
|
@ -2413,6 +2443,30 @@ struct sk_msg_md {
|
|||
__u32 local_port; /* stored in host byte order */
|
||||
};
|
||||
|
||||
struct sk_reuseport_md {
|
||||
/*
|
||||
* Start of directly accessible data. It begins from
|
||||
* the tcp/udp header.
|
||||
*/
|
||||
void *data;
|
||||
void *data_end; /* End of directly accessible data */
|
||||
/*
|
||||
* Total length of packet (starting from the tcp/udp header).
|
||||
* Note that the directly accessible bytes (data_end - data)
|
||||
* could be less than this "len". Those bytes could be
|
||||
* indirectly read by a helper "bpf_skb_load_bytes()".
|
||||
*/
|
||||
__u32 len;
|
||||
/*
|
||||
* Eth protocol in the mac header (network byte order). e.g.
|
||||
* ETH_P_IP(0x0800) and ETH_P_IPV6(0x86DD)
|
||||
*/
|
||||
__u32 eth_protocol;
|
||||
__u32 ip_protocol; /* IP protocol. e.g. IPPROTO_TCP, IPPROTO_UDP */
|
||||
__u32 bind_inany; /* Is sock bound to an INANY address? */
|
||||
__u32 hash; /* A hash of the packet 4 tuples */
|
||||
};
|
||||
|
||||
#define BPF_TAG_SIZE 8
|
||||
|
||||
struct bpf_prog_info {
|
||||
|
|
|
|||
5
ip/ip.c
5
ip/ip.c
|
|
@ -55,7 +55,7 @@ static void usage(void)
|
|||
" OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |\n"
|
||||
" -h[uman-readable] | -iec | -j[son] | -p[retty] |\n"
|
||||
" -f[amily] { inet | inet6 | ipx | dnet | mpls | bridge | link } |\n"
|
||||
" -4 | -6 | -I | -D | -B | -0 |\n"
|
||||
" -4 | -6 | -I | -D | -M | -B | -0 |\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");
|
||||
|
|
@ -283,8 +283,7 @@ int main(int argc, char **argv)
|
|||
exit(-1);
|
||||
}
|
||||
rcvbuf = size;
|
||||
} else if (matches(opt, "-color") == 0) {
|
||||
++color;
|
||||
} else if (matches_color(opt, &color)) {
|
||||
} else if (matches(opt, "-help") == 0) {
|
||||
usage();
|
||||
} else if (matches(opt, "-netns") == 0) {
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ int do_netns(int argc, char **argv);
|
|||
int do_xfrm(int argc, char **argv);
|
||||
int do_ipl2tp(int argc, char **argv);
|
||||
int do_ipfou(int argc, char **argv);
|
||||
extern int do_ipila(int argc, char **argv);
|
||||
int do_ipila(int argc, char **argv);
|
||||
int do_tcp_metrics(int argc, char **argv);
|
||||
int do_ipnetconf(int argc, char **argv);
|
||||
int do_iptoken(int argc, char **argv);
|
||||
|
|
|
|||
|
|
@ -316,11 +316,14 @@ static void can_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
|
|||
struct can_bittiming *bt = RTA_DATA(tb[IFLA_CAN_BITTIMING]);
|
||||
|
||||
if (is_json_context()) {
|
||||
json_writer_t *jw;
|
||||
|
||||
open_json_object("bittiming");
|
||||
print_int(PRINT_ANY, "bitrate", NULL, bt->bitrate);
|
||||
jsonw_float_field_fmt(get_json_writer(),
|
||||
"sample_point", "%.3f",
|
||||
(float) bt->sample_point / 1000.);
|
||||
jw = get_json_writer();
|
||||
jsonw_name(jw, "sample_point");
|
||||
jsonw_printf(jw, "%.3f",
|
||||
(float) bt->sample_point / 1000);
|
||||
print_int(PRINT_ANY, "tq", NULL, bt->tq);
|
||||
print_int(PRINT_ANY, "prop_seg", NULL, bt->prop_seg);
|
||||
print_int(PRINT_ANY, "phase_seg1",
|
||||
|
|
@ -415,12 +418,14 @@ static void can_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
|
|||
RTA_DATA(tb[IFLA_CAN_DATA_BITTIMING]);
|
||||
|
||||
if (is_json_context()) {
|
||||
json_writer_t *jw;
|
||||
|
||||
open_json_object("data_bittiming");
|
||||
print_int(PRINT_JSON, "bitrate", NULL, dbt->bitrate);
|
||||
jsonw_float_field_fmt(get_json_writer(),
|
||||
"sample_point",
|
||||
"%.3f",
|
||||
(float) dbt->sample_point / 1000.);
|
||||
jw = get_json_writer();
|
||||
jsonw_name(jw, "sample_point");
|
||||
jsonw_printf(jw, "%.3f",
|
||||
(float) dbt->sample_point / 1000.);
|
||||
print_int(PRINT_JSON, "tq", NULL, dbt->tq);
|
||||
print_int(PRINT_JSON, "prop_seg", NULL, dbt->prop_seg);
|
||||
print_int(PRINT_JSON, "phase_seg1",
|
||||
|
|
|
|||
13
ip/ipmaddr.c
13
ip/ipmaddr.c
|
|
@ -289,6 +289,7 @@ static int multiaddr_list(int argc, char **argv)
|
|||
static int multiaddr_modify(int cmd, int argc, char **argv)
|
||||
{
|
||||
struct ifreq ifr = {};
|
||||
int family;
|
||||
int fd;
|
||||
|
||||
if (cmd == RTM_NEWADDR)
|
||||
|
|
@ -324,7 +325,17 @@ static int multiaddr_modify(int cmd, int argc, char **argv)
|
|||
exit(-1);
|
||||
}
|
||||
|
||||
fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
switch (preferred_family) {
|
||||
case AF_INET6:
|
||||
case AF_PACKET:
|
||||
case AF_INET:
|
||||
family = preferred_family;
|
||||
break;
|
||||
default:
|
||||
family = AF_INET;
|
||||
}
|
||||
|
||||
fd = socket(family, SOCK_DGRAM, 0);
|
||||
if (fd < 0) {
|
||||
perror("Cannot create socket");
|
||||
exit(1);
|
||||
|
|
|
|||
|
|
@ -58,7 +58,9 @@ static int accept_msg(const struct sockaddr_nl *who,
|
|||
{
|
||||
FILE *fp = (FILE *)arg;
|
||||
|
||||
if (n->nlmsg_type == RTM_NEWROUTE || n->nlmsg_type == RTM_DELROUTE) {
|
||||
switch (n->nlmsg_type) {
|
||||
case RTM_NEWROUTE:
|
||||
case RTM_DELROUTE: {
|
||||
struct rtmsg *r = NLMSG_DATA(n);
|
||||
int len = n->nlmsg_len - NLMSG_LENGTH(sizeof(*r));
|
||||
|
||||
|
|
@ -82,24 +84,28 @@ static int accept_msg(const struct sockaddr_nl *who,
|
|||
}
|
||||
}
|
||||
|
||||
if (n->nlmsg_type == RTM_NEWLINK || n->nlmsg_type == RTM_DELLINK) {
|
||||
case RTM_NEWLINK:
|
||||
case RTM_DELLINK:
|
||||
ll_remember_index(who, n, NULL);
|
||||
print_headers(fp, "[LINK]", ctrl);
|
||||
print_linkinfo(who, n, arg);
|
||||
return 0;
|
||||
}
|
||||
if (n->nlmsg_type == RTM_NEWADDR || n->nlmsg_type == RTM_DELADDR) {
|
||||
|
||||
case RTM_NEWADDR:
|
||||
case RTM_DELADDR:
|
||||
print_headers(fp, "[ADDR]", ctrl);
|
||||
print_addrinfo(who, n, arg);
|
||||
return 0;
|
||||
}
|
||||
if (n->nlmsg_type == RTM_NEWADDRLABEL || n->nlmsg_type == RTM_DELADDRLABEL) {
|
||||
|
||||
case RTM_NEWADDRLABEL:
|
||||
case RTM_DELADDRLABEL:
|
||||
print_headers(fp, "[ADDRLABEL]", ctrl);
|
||||
print_addrlabel(who, n, arg);
|
||||
return 0;
|
||||
}
|
||||
if (n->nlmsg_type == RTM_NEWNEIGH || n->nlmsg_type == RTM_DELNEIGH ||
|
||||
n->nlmsg_type == RTM_GETNEIGH) {
|
||||
|
||||
case RTM_NEWNEIGH:
|
||||
case RTM_DELNEIGH:
|
||||
case RTM_GETNEIGH:
|
||||
if (preferred_family) {
|
||||
struct ndmsg *r = NLMSG_DATA(n);
|
||||
|
||||
|
|
@ -110,34 +116,42 @@ static int accept_msg(const struct sockaddr_nl *who,
|
|||
print_headers(fp, "[NEIGH]", ctrl);
|
||||
print_neigh(who, n, arg);
|
||||
return 0;
|
||||
}
|
||||
if (n->nlmsg_type == RTM_NEWPREFIX) {
|
||||
|
||||
case RTM_NEWPREFIX:
|
||||
print_headers(fp, "[PREFIX]", ctrl);
|
||||
print_prefix(who, n, arg);
|
||||
return 0;
|
||||
}
|
||||
if (n->nlmsg_type == RTM_NEWRULE || n->nlmsg_type == RTM_DELRULE) {
|
||||
|
||||
case RTM_NEWRULE:
|
||||
case RTM_DELRULE:
|
||||
print_headers(fp, "[RULE]", ctrl);
|
||||
print_rule(who, n, arg);
|
||||
return 0;
|
||||
}
|
||||
if (n->nlmsg_type == RTM_NEWNETCONF) {
|
||||
|
||||
case NLMSG_TSTAMP:
|
||||
print_nlmsg_timestamp(fp, n);
|
||||
return 0;
|
||||
|
||||
case RTM_NEWNETCONF:
|
||||
case RTM_DELNETCONF:
|
||||
print_headers(fp, "[NETCONF]", ctrl);
|
||||
print_netconf(who, ctrl, n, arg);
|
||||
return 0;
|
||||
}
|
||||
if (n->nlmsg_type == NLMSG_TSTAMP) {
|
||||
print_nlmsg_timestamp(fp, n);
|
||||
return 0;
|
||||
}
|
||||
if (n->nlmsg_type == RTM_NEWNSID || n->nlmsg_type == RTM_DELNSID) {
|
||||
|
||||
case RTM_DELNSID:
|
||||
case RTM_NEWNSID:
|
||||
print_headers(fp, "[NSID]", ctrl);
|
||||
print_nsid(who, n, arg);
|
||||
return 0;
|
||||
}
|
||||
if (n->nlmsg_type != NLMSG_ERROR && n->nlmsg_type != NLMSG_NOOP &&
|
||||
n->nlmsg_type != NLMSG_DONE) {
|
||||
fprintf(fp, "Unknown message: type=0x%08x(%d) flags=0x%08x(%d)len=0x%08x(%d)\n",
|
||||
|
||||
case NLMSG_ERROR:
|
||||
case NLMSG_NOOP:
|
||||
case NLMSG_DONE:
|
||||
break; /* ignore */
|
||||
|
||||
default:
|
||||
fprintf(stderr,
|
||||
"Unknown message: type=0x%08x(%d) flags=0x%08x(%d) len=0x%08x(%d)\n",
|
||||
n->nlmsg_type, n->nlmsg_type,
|
||||
n->nlmsg_flags, n->nlmsg_flags, n->nlmsg_len,
|
||||
n->nlmsg_len);
|
||||
|
|
|
|||
|
|
@ -66,8 +66,10 @@ int print_netconf(const struct sockaddr_nl *who, struct rtnl_ctrl_data *ctrl,
|
|||
|
||||
if (n->nlmsg_type == NLMSG_ERROR)
|
||||
return -1;
|
||||
if (n->nlmsg_type != RTM_NEWNETCONF) {
|
||||
fprintf(stderr, "Not RTM_NEWNETCONF: %08x %08x %08x\n",
|
||||
|
||||
if (n->nlmsg_type != RTM_NEWNETCONF &&
|
||||
n->nlmsg_type != RTM_DELNETCONF) {
|
||||
fprintf(stderr, "Not a netconf message: %08x %08x %08x\n",
|
||||
n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
|
||||
|
||||
return -1;
|
||||
|
|
@ -91,6 +93,9 @@ int print_netconf(const struct sockaddr_nl *who, struct rtnl_ctrl_data *ctrl,
|
|||
return 0;
|
||||
|
||||
open_json_object(NULL);
|
||||
if (n->nlmsg_type == RTM_DELNETCONF)
|
||||
print_bool(PRINT_ANY, "deleted", "Deleted ", true);
|
||||
|
||||
print_string(PRINT_ANY, "family",
|
||||
"%s ", family_name(ncm->ncm_family));
|
||||
|
||||
|
|
|
|||
|
|
@ -239,7 +239,7 @@ int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
|
|||
|
||||
print_string(PRINT_FP, NULL, "to ", NULL);
|
||||
print_color_string(PRINT_ANY, ifa_family_color(frh->family),
|
||||
"dst", "%s ", dst);
|
||||
"dst", "%s", dst);
|
||||
if (frh->dst_len != host_len)
|
||||
print_uint(PRINT_ANY, "dstlen", "/%u ", frh->dst_len);
|
||||
else
|
||||
|
|
|
|||
|
|
@ -63,7 +63,9 @@ static int dump_msg2(const struct sockaddr_nl *who,
|
|||
|
||||
static void usage(void)
|
||||
{
|
||||
fprintf(stderr, "Usage: rtmon file FILE [ all | LISTofOBJECTS]\n");
|
||||
fprintf(stderr, "Usage: rtmon [ OPTIONS ] file FILE [ all | LISTofOBJECTS ]\n");
|
||||
fprintf(stderr, "OPTIONS := { -f[amily] { inet | inet6 | link | help } |\n"
|
||||
" -4 | -6 | -0 | -V[ersion] }\n");
|
||||
fprintf(stderr, "LISTofOBJECTS := [ link ] [ address ] [ route ]\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
|
|
|||
40
lib/color.c
40
lib/color.c
|
|
@ -3,11 +3,13 @@
|
|||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <linux/if.h>
|
||||
|
||||
#include "color.h"
|
||||
#include "utils.h"
|
||||
|
||||
enum color {
|
||||
C_RED,
|
||||
|
|
@ -77,13 +79,42 @@ void enable_color(void)
|
|||
set_color_palette();
|
||||
}
|
||||
|
||||
int check_enable_color(int color, int json)
|
||||
bool check_enable_color(int color, int json)
|
||||
{
|
||||
if (color && !json) {
|
||||
if (json || color == COLOR_OPT_NEVER)
|
||||
return false;
|
||||
|
||||
if (color == COLOR_OPT_ALWAYS || isatty(fileno(stdout))) {
|
||||
enable_color();
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
return 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool matches_color(const char *arg, int *val)
|
||||
{
|
||||
char *dup, *p;
|
||||
|
||||
if (!val)
|
||||
return false;
|
||||
|
||||
dup = strdupa(arg);
|
||||
p = strchrnul(dup, '=');
|
||||
if (*p)
|
||||
*(p++) = '\0';
|
||||
|
||||
if (matches(dup, "-color"))
|
||||
return false;
|
||||
|
||||
if (*p == '\0' || !strcmp(p, "always"))
|
||||
*val = COLOR_OPT_ALWAYS;
|
||||
else if (!strcmp(p, "auto"))
|
||||
*val = COLOR_OPT_AUTO;
|
||||
else if (!strcmp(p, "never"))
|
||||
*val = COLOR_OPT_NEVER;
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void set_color_palette(void)
|
||||
|
|
@ -101,6 +132,7 @@ void set_color_palette(void)
|
|||
is_dark_bg = 1;
|
||||
}
|
||||
|
||||
__attribute__((format(printf, 3, 4)))
|
||||
int color_fprintf(FILE *fp, enum color_attr attr, const char *fmt, ...)
|
||||
{
|
||||
int ret = 0;
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ void close_json_array(enum output_type type, const char *str)
|
|||
* functions handling different types
|
||||
*/
|
||||
#define _PRINT_FUNC(type_name, type) \
|
||||
__attribute__((format(printf, 4, 0))) \
|
||||
void print_color_##type_name(enum output_type t, \
|
||||
enum color_attr color, \
|
||||
const char *key, \
|
||||
|
|
|
|||
|
|
@ -152,6 +152,7 @@ void jsonw_name(json_writer_t *self, const char *name)
|
|||
putc(' ', self->out);
|
||||
}
|
||||
|
||||
__attribute__((format(printf, 2, 3)))
|
||||
void jsonw_printf(json_writer_t *self, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
|
@ -205,11 +206,6 @@ void jsonw_null(json_writer_t *self)
|
|||
jsonw_printf(self, "null");
|
||||
}
|
||||
|
||||
void jsonw_float_fmt(json_writer_t *self, const char *fmt, double num)
|
||||
{
|
||||
jsonw_printf(self, fmt, num);
|
||||
}
|
||||
|
||||
void jsonw_float(json_writer_t *self, double num)
|
||||
{
|
||||
jsonw_printf(self, "%g", num);
|
||||
|
|
@ -274,15 +270,6 @@ void jsonw_float_field(json_writer_t *self, const char *prop, double val)
|
|||
jsonw_float(self, val);
|
||||
}
|
||||
|
||||
void jsonw_float_field_fmt(json_writer_t *self,
|
||||
const char *prop,
|
||||
const char *fmt,
|
||||
double val)
|
||||
{
|
||||
jsonw_name(self, prop);
|
||||
jsonw_float_fmt(self, fmt, val);
|
||||
}
|
||||
|
||||
void jsonw_uint_field(json_writer_t *self, const char *prop, unsigned int num)
|
||||
{
|
||||
jsonw_name(self, prop);
|
||||
|
|
|
|||
|
|
@ -24,7 +24,8 @@ bridge \- show / manipulate bridge addresses and devices
|
|||
\fB\-b\fR[\fIatch\fR] filename |
|
||||
\fB\-c\fR[\folor\fR] |
|
||||
\fB\-p\fR[\fIretty\fR] |
|
||||
\fB\-j\fR[\fIson\fR] }
|
||||
\fB\-j\fR[\fIson\fR] |
|
||||
\fB\-o\fR[\fIneline\fr] }
|
||||
|
||||
.ti -8
|
||||
.BR "bridge link set"
|
||||
|
|
@ -171,8 +172,17 @@ If there were any errors during execution of the commands, the application
|
|||
return code will be non zero.
|
||||
|
||||
.TP
|
||||
.BR "\-c" , " -color"
|
||||
Use color output.
|
||||
.BR \-c [ color ][ = { always | auto | never }
|
||||
Configure color output. If parameter is omitted or
|
||||
.BR always ,
|
||||
color output is enabled regardless of stdout state. If parameter is
|
||||
.BR auto ,
|
||||
stdout is checked to be a terminal before enabling color output. If parameter is
|
||||
.BR never ,
|
||||
color output is disabled. If specified multiple times, the last one takes
|
||||
precedence. This flag is ignored if
|
||||
.B \-json
|
||||
is also given.
|
||||
|
||||
.TP
|
||||
.BR "\-j", " \-json"
|
||||
|
|
@ -182,6 +192,18 @@ Output results in JavaScript Object Notation (JSON).
|
|||
.BR "\-p", " \-pretty"
|
||||
When combined with -j generate a pretty JSON output.
|
||||
|
||||
.TP
|
||||
.BR "\-o", " \-oneline"
|
||||
output each record on a single line, replacing line feeds
|
||||
with the
|
||||
.B '\e'
|
||||
character. This is convenient when you want to count records
|
||||
with
|
||||
.BR wc (1)
|
||||
or to
|
||||
.BR grep (1)
|
||||
the output.
|
||||
|
||||
|
||||
.SH BRIDGE - COMMAND SYNTAX
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,10 @@ Generate JSON output.
|
|||
.BR "\-p" , " --pretty"
|
||||
When combined with -j generate a pretty JSON output.
|
||||
|
||||
.TP
|
||||
.BR "\-v" , " --verbose"
|
||||
Turn on verbose output.
|
||||
|
||||
.SS
|
||||
.I OBJECT
|
||||
|
||||
|
|
|
|||
|
|
@ -48,6 +48,14 @@ Report average over the last SECS seconds.
|
|||
.B \-z, \-\-zeros
|
||||
Show entries with zero activity.
|
||||
.TP
|
||||
.B \-j, \-\-json
|
||||
Display results in JSON format
|
||||
.TP
|
||||
.B \-p, \-\-pretty
|
||||
If combined with
|
||||
.BR \-\-json ,
|
||||
pretty print the output.
|
||||
.TP
|
||||
.B \-x, \-\-extended=TYPE
|
||||
Show extended stats of TYPE. Supported types are:
|
||||
|
||||
|
|
|
|||
|
|
@ -187,8 +187,17 @@ to
|
|||
executes specified command over all objects, it depends if command supports this option.
|
||||
|
||||
.TP
|
||||
.BR "\-c" , " -color"
|
||||
Use color output.
|
||||
.BR \-c [ color ][ = { always | auto | never }
|
||||
Configure color output. If parameter is omitted or
|
||||
.BR always ,
|
||||
color output is enabled regardless of stdout state. If parameter is
|
||||
.BR auto ,
|
||||
stdout is checked to be a terminal before enabling color output. If parameter is
|
||||
.BR never ,
|
||||
color output is disabled. If specified multiple times, the last one takes
|
||||
precedence. This flag is ignored if
|
||||
.B \-json
|
||||
is also given.
|
||||
|
||||
.TP
|
||||
.BR "\-t" , " \-timestamp"
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
nstat, rtacct - network statistics tools.
|
||||
|
||||
.SH SYNOPSIS
|
||||
Usage: nstat [ -h?vVzrnasd:t: ] [ PATTERN [ PATTERN ] ]
|
||||
Usage: nstat [ -h?vVzrnasd:t:jp ] [ PATTERN [ PATTERN ] ]
|
||||
.br
|
||||
Usage: rtacct [ -h?vVzrnasd:t: ] [ ListOfRealms ]
|
||||
|
||||
|
|
@ -21,7 +21,7 @@ Print help
|
|||
.B \-V, \-\-version
|
||||
Print version
|
||||
.TP
|
||||
.B \-z, \-\-zero
|
||||
.B \-z, \-\-zeros
|
||||
Dump zero counters too. By default they are not shown.
|
||||
.TP
|
||||
.B \-r, \-\-reset
|
||||
|
|
@ -39,12 +39,16 @@ Do not update history, so that the next time you will see counters including val
|
|||
.B \-j, \-\-json
|
||||
Display results in JSON format.
|
||||
.TP
|
||||
.B \-d, \-\-interval <INTERVAL>
|
||||
.B \-p, \-\-pretty
|
||||
When combined with
|
||||
.BR \-\-json ,
|
||||
pretty print the output.
|
||||
.TP
|
||||
.B \-d, \-\-scan <INTERVAL>
|
||||
Run in daemon mode collecting statistics. <INTERVAL> is interval between measurements in seconds.
|
||||
.TP
|
||||
|
||||
.B \-t, \-\-interval <INTERVAL>
|
||||
Time interval to average rates. Default value is 60 seconds.
|
||||
.TP
|
||||
|
||||
.SH SEE ALSO
|
||||
lnstat(8)
|
||||
|
|
|
|||
|
|
@ -242,6 +242,9 @@ Print summary statistics. This option does not parse socket lists obtaining
|
|||
summary from various sources. It is useful when amount of sockets is so huge
|
||||
that parsing /proc/net/tcp is painful.
|
||||
.TP
|
||||
.B \-E, \-\-events
|
||||
Continually display sockets as they are destroyed
|
||||
.TP
|
||||
.B \-Z, \-\-context
|
||||
As the
|
||||
.B \-p
|
||||
|
|
|
|||
|
|
@ -569,6 +569,61 @@ possible latency. At link speeds higher than 10 Gbps, setting the
|
|||
no-split-gso parameter can increase the maximum achievable throughput by
|
||||
retaining the full GSO packets.
|
||||
|
||||
.SH OVERRIDING CLASSIFICATION WITH TC FILTERS
|
||||
|
||||
CAKE supports overriding of its internal classification of packets through the
|
||||
tc filter mechanism. Packets can be assigned to different priority tins by
|
||||
setting the
|
||||
.B priority
|
||||
field on the skb, and the flow hashing can be overridden by setting the
|
||||
.B classid
|
||||
parameter.
|
||||
|
||||
.PP
|
||||
.B Tin override
|
||||
|
||||
.br
|
||||
To assign a priority tin, the major number of the priority field needs
|
||||
to match the qdisc handle of the cake instance; if it does, the minor number
|
||||
will be interpreted as the tin index. For example, to classify all ICMP packets
|
||||
as 'bulk', the following filter can be used:
|
||||
|
||||
.br
|
||||
# tc qdisc replace dev eth0 handle 1: root cake diffserv3
|
||||
# tc filter add dev eth0 parent 1: protocol ip prio 1 \\
|
||||
u32 match icmp type 0 0 action skbedit priority 1:1
|
||||
|
||||
.PP
|
||||
.B Flow hash override
|
||||
|
||||
.br
|
||||
To override flow hashing, the classid can be set. CAKE will interpret
|
||||
the major number of the classid as the host hash used in host isolation mode,
|
||||
and the minor number as the flow hash used for flow-based queueing. One or both
|
||||
of those can be set, and will be used if the relevant flow isolation parameter
|
||||
is set (i.e., the major number will be ignored if CAKE is not configured in
|
||||
hosts mode, and the minor number will be ignored if CAKE is not configured in
|
||||
flows mode).
|
||||
|
||||
.br
|
||||
This example will assign all ICMP packets to the first queue:
|
||||
|
||||
.br
|
||||
# tc qdisc replace dev eth0 handle 1: root cake
|
||||
# tc filter add dev eth0 parent 1: protocol ip prio 1 \\
|
||||
u32 match icmp type 0 0 classid 0:1
|
||||
|
||||
.br
|
||||
If only one of the host and flow overrides is set, CAKE will compute the other
|
||||
hash from the packet as normal. Note, however, that the host isolation mode
|
||||
works by assigning a host ID to the flow queue; so if overriding both host and
|
||||
flow, the same flow cannot have more than one host assigned. In addition, it is
|
||||
not possible to assign different source and destination host IDs through the
|
||||
override mechanism; if a host ID is assigned, it will be used as both source and
|
||||
destination host.
|
||||
|
||||
|
||||
|
||||
.SH EXAMPLES
|
||||
# tc qdisc delete root dev eth0
|
||||
.br
|
||||
|
|
|
|||
|
|
@ -755,8 +755,17 @@ option was specified. Classes can be filtered only by
|
|||
option.
|
||||
|
||||
.TP
|
||||
.BR "\ -color"
|
||||
Use color output.
|
||||
.BR \-c [ color ][ = { always | auto | never }
|
||||
Configure color output. If parameter is omitted or
|
||||
.BR always ,
|
||||
color output is enabled regardless of stdout state. If parameter is
|
||||
.BR auto ,
|
||||
stdout is checked to be a terminal before enabling color output. If parameter is
|
||||
.BR never ,
|
||||
color output is disabled. If specified multiple times, the last one takes
|
||||
precedence. This flag is ignored if
|
||||
.B \-json
|
||||
is also given.
|
||||
|
||||
.TP
|
||||
.BR "\-j", " \-json"
|
||||
|
|
|
|||
21
misc/ss.c
21
misc/ss.c
|
|
@ -16,6 +16,7 @@
|
|||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/sysmacros.h>
|
||||
#include <netinet/in.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
|
@ -976,6 +977,7 @@ static int buf_update(int len)
|
|||
}
|
||||
|
||||
/* Append content to buffer as part of the current field */
|
||||
__attribute__((format(printf, 1, 2)))
|
||||
static void out(const char *fmt, ...)
|
||||
{
|
||||
struct column *f = current_field;
|
||||
|
|
@ -1093,7 +1095,7 @@ static void print_header(void)
|
|||
{
|
||||
while (!field_is_last(current_field)) {
|
||||
if (!current_field->disabled)
|
||||
out(current_field->header);
|
||||
out("%s", current_field->header);
|
||||
field_next();
|
||||
}
|
||||
}
|
||||
|
|
@ -3604,6 +3606,21 @@ static int unix_show_sock(const struct sockaddr_nl *addr, struct nlmsghdr *nlh,
|
|||
out(" %c-%c",
|
||||
mask & 1 ? '-' : '<', mask & 2 ? '-' : '>');
|
||||
}
|
||||
if (tb[UNIX_DIAG_VFS]) {
|
||||
struct unix_diag_vfs *uv = RTA_DATA(tb[UNIX_DIAG_VFS]);
|
||||
|
||||
out(" ino:%u dev:%u/%u", uv->udiag_vfs_ino, major(uv->udiag_vfs_dev),
|
||||
minor(uv->udiag_vfs_dev));
|
||||
}
|
||||
if (tb[UNIX_DIAG_ICONS]) {
|
||||
int len = RTA_PAYLOAD(tb[UNIX_DIAG_ICONS]);
|
||||
__u32 *peers = RTA_DATA(tb[UNIX_DIAG_ICONS]);
|
||||
int i;
|
||||
|
||||
out(" peers:");
|
||||
for (i = 0; i < len / sizeof(__u32); i++)
|
||||
out(" %u", peers[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -3641,6 +3658,8 @@ static int unix_show_netlink(struct filter *f)
|
|||
req.r.udiag_show = UDIAG_SHOW_NAME | UDIAG_SHOW_PEER | UDIAG_SHOW_RQLEN;
|
||||
if (show_mem)
|
||||
req.r.udiag_show |= UDIAG_SHOW_MEMINFO;
|
||||
if (show_details)
|
||||
req.r.udiag_show |= UDIAG_SHOW_VFS | UDIAG_SHOW_ICONS;
|
||||
|
||||
return handle_netlink_request(f, &req.nlh, sizeof(req), unix_show_sock);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -277,6 +277,7 @@ static int flatten_tree(struct ematch *head, struct ematch *tree)
|
|||
return count;
|
||||
}
|
||||
|
||||
__attribute__((format(printf, 5, 6)))
|
||||
int em_parse_error(int err, struct bstr *args, struct bstr *carg,
|
||||
struct ematch_util *e, char *fmt, ...)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -12,17 +12,16 @@
|
|||
|
||||
#define EMATCHKINDSIZ 16
|
||||
|
||||
struct bstr
|
||||
{
|
||||
struct bstr {
|
||||
char *data;
|
||||
unsigned int len;
|
||||
int quoted;
|
||||
struct bstr *next;
|
||||
};
|
||||
|
||||
extern struct bstr * bstr_alloc(const char *text);
|
||||
struct bstr *bstr_alloc(const char *text);
|
||||
|
||||
static inline struct bstr * bstr_new(char *data, unsigned int len)
|
||||
static inline struct bstr *bstr_new(char *data, unsigned int len)
|
||||
{
|
||||
struct bstr *b = calloc(1, sizeof(*b));
|
||||
|
||||
|
|
@ -35,7 +34,7 @@ static inline struct bstr * bstr_new(char *data, unsigned int len)
|
|||
return b;
|
||||
}
|
||||
|
||||
static inline int bstrcmp(struct bstr *b, const char *text)
|
||||
static inline int bstrcmp(const struct bstr *b, const char *text)
|
||||
{
|
||||
int len = strlen(text);
|
||||
int d = b->len - len;
|
||||
|
|
@ -51,12 +50,10 @@ static inline struct bstr *bstr_next(struct bstr *b)
|
|||
return b->next;
|
||||
}
|
||||
|
||||
extern unsigned long bstrtoul(const struct bstr *b);
|
||||
extern void bstr_print(FILE *fd, const struct bstr *b, int ascii);
|
||||
unsigned long bstrtoul(const struct bstr *b);
|
||||
void bstr_print(FILE *fd, const struct bstr *b, int ascii);
|
||||
|
||||
|
||||
struct ematch
|
||||
{
|
||||
struct ematch {
|
||||
struct bstr *args;
|
||||
int index;
|
||||
int inverted;
|
||||
|
|
@ -66,7 +63,7 @@ struct ematch
|
|||
struct ematch *next;
|
||||
};
|
||||
|
||||
static inline struct ematch * new_ematch(struct bstr *args, int inverted)
|
||||
static inline struct ematch *new_ematch(struct bstr *args, int inverted)
|
||||
{
|
||||
struct ematch *e = calloc(1, sizeof(*e));
|
||||
|
||||
|
|
@ -79,14 +76,12 @@ static inline struct ematch * new_ematch(struct bstr *args, int inverted)
|
|||
return e;
|
||||
}
|
||||
|
||||
extern void print_ematch_tree(const struct ematch *tree);
|
||||
void print_ematch_tree(const struct ematch *tree);
|
||||
|
||||
|
||||
struct ematch_util
|
||||
{
|
||||
struct ematch_util {
|
||||
char kind[EMATCHKINDSIZ];
|
||||
int kind_num;
|
||||
int (*parse_eopt)(struct nlmsghdr *,struct tcf_ematch_hdr *,
|
||||
int (*parse_eopt)(struct nlmsghdr *, struct tcf_ematch_hdr *,
|
||||
struct bstr *);
|
||||
int (*parse_eopt_argv)(struct nlmsghdr *, struct tcf_ematch_hdr *,
|
||||
int, char **);
|
||||
|
|
@ -95,7 +90,7 @@ struct ematch_util
|
|||
struct ematch_util *next;
|
||||
};
|
||||
|
||||
static inline int parse_layer(struct bstr *b)
|
||||
static inline int parse_layer(const struct bstr *b)
|
||||
{
|
||||
if (*((char *) b->data) == 'l')
|
||||
return TCF_LAYER_LINK;
|
||||
|
|
@ -107,9 +102,10 @@ static inline int parse_layer(struct bstr *b)
|
|||
return INT_MAX;
|
||||
}
|
||||
|
||||
extern int em_parse_error(int err, struct bstr *args, struct bstr *carg,
|
||||
__attribute__((format(printf, 5, 6)))
|
||||
int em_parse_error(int err, struct bstr *args, struct bstr *carg,
|
||||
struct ematch_util *, char *fmt, ...);
|
||||
extern int print_ematch(FILE *, const struct rtattr *);
|
||||
extern int parse_ematch(int *, char ***, int, struct nlmsghdr *);
|
||||
int print_ematch(FILE *, const struct rtattr *);
|
||||
int parse_ematch(int *, char ***, int, struct nlmsghdr *);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
31
tc/m_pedit.h
31
tc/m_pedit.h
|
|
@ -71,23 +71,22 @@ struct m_pedit_util {
|
|||
struct m_pedit_key *tkey);
|
||||
};
|
||||
|
||||
extern int pack_key(struct m_pedit_sel *sel, struct m_pedit_key *tkey);
|
||||
extern int pack_key32(__u32 retain, struct m_pedit_sel *sel,
|
||||
struct m_pedit_key *tkey);
|
||||
extern int pack_key16(__u32 retain, struct m_pedit_sel *sel,
|
||||
struct m_pedit_key *tkey);
|
||||
extern int pack_key8(__u32 retain, struct m_pedit_sel *sel,
|
||||
int pack_key(struct m_pedit_sel *sel, struct m_pedit_key *tkey);
|
||||
int pack_key32(__u32 retain, struct m_pedit_sel *sel,
|
||||
struct m_pedit_key *tkey);
|
||||
int pack_key16(__u32 retain, struct m_pedit_sel *sel,
|
||||
struct m_pedit_key *tkey);
|
||||
int pack_key8(__u32 retain, struct m_pedit_sel *sel,
|
||||
struct m_pedit_key *tkey);
|
||||
extern int parse_val(int *argc_p, char ***argv_p, __u32 *val, int type);
|
||||
extern int parse_cmd(int *argc_p, char ***argv_p, __u32 len, int type,
|
||||
__u32 retain,
|
||||
struct m_pedit_sel *sel, struct m_pedit_key *tkey);
|
||||
extern int parse_offset(int *argc_p, char ***argv_p,
|
||||
struct m_pedit_sel *sel, struct m_pedit_key *tkey);
|
||||
int parse_val(int *argc_p, char ***argv_p, __u32 *val, int type);
|
||||
int parse_cmd(int *argc_p, char ***argv_p, __u32 len, int type,
|
||||
__u32 retain,
|
||||
struct m_pedit_sel *sel, struct m_pedit_key *tkey);
|
||||
int parse_offset(int *argc_p, char ***argv_p,
|
||||
struct m_pedit_sel *sel, struct m_pedit_key *tkey);
|
||||
int parse_pedit(struct action_util *a, int *argc_p, char ***argv_p,
|
||||
int tca_id, struct nlmsghdr *n);
|
||||
extern int print_pedit(struct action_util *au, FILE *f, struct rtattr *arg);
|
||||
extern int pedit_print_xstats(struct action_util *au, FILE *f,
|
||||
struct rtattr *xstats);
|
||||
|
||||
int print_pedit(struct action_util *au, FILE *f, struct rtattr *arg);
|
||||
int pedit_print_xstats(struct action_util *au, FILE *f,
|
||||
struct rtattr *xstats);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -109,7 +109,6 @@ static int htb_parse_opt(struct qdisc_util *qu, int argc,
|
|||
|
||||
static int htb_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n, const char *dev)
|
||||
{
|
||||
int ok = 0;
|
||||
struct tc_htb_opt opt = {};
|
||||
__u32 rtab[256], ctab[256];
|
||||
unsigned buffer = 0, cbuffer = 0;
|
||||
|
|
@ -127,7 +126,6 @@ static int htb_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, str
|
|||
if (get_u32(&opt.prio, *argv, 10)) {
|
||||
explain1("prio"); return -1;
|
||||
}
|
||||
ok++;
|
||||
} else if (matches(*argv, "mtu") == 0) {
|
||||
NEXT_ARG();
|
||||
if (get_u32(&mtu, *argv, 10)) {
|
||||
|
|
@ -161,7 +159,6 @@ static int htb_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, str
|
|||
explain1("buffer");
|
||||
return -1;
|
||||
}
|
||||
ok++;
|
||||
} else if (matches(*argv, "cburst") == 0 ||
|
||||
strcmp(*argv, "cbuffer") == 0 ||
|
||||
strcmp(*argv, "cmaxburst") == 0) {
|
||||
|
|
@ -170,7 +167,6 @@ static int htb_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, str
|
|||
explain1("cbuffer");
|
||||
return -1;
|
||||
}
|
||||
ok++;
|
||||
} else if (strcmp(*argv, "ceil") == 0) {
|
||||
NEXT_ARG();
|
||||
if (ceil64) {
|
||||
|
|
@ -186,7 +182,6 @@ static int htb_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, str
|
|||
explain1("ceil");
|
||||
return -1;
|
||||
}
|
||||
ok++;
|
||||
} else if (strcmp(*argv, "rate") == 0) {
|
||||
NEXT_ARG();
|
||||
if (rate64) {
|
||||
|
|
@ -202,7 +197,6 @@ static int htb_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, str
|
|||
explain1("rate");
|
||||
return -1;
|
||||
}
|
||||
ok++;
|
||||
} else if (strcmp(*argv, "help") == 0) {
|
||||
explain();
|
||||
return -1;
|
||||
|
|
@ -214,9 +208,6 @@ static int htb_parse_class_opt(struct qdisc_util *qu, int argc, char **argv, str
|
|||
argc--; argv++;
|
||||
}
|
||||
|
||||
/* if (!ok)
|
||||
return 0;*/
|
||||
|
||||
if (!rate64) {
|
||||
fprintf(stderr, "\"rate\" is required.\n");
|
||||
return -1;
|
||||
|
|
|
|||
3
tc/tc.c
3
tc/tc.c
|
|
@ -496,8 +496,7 @@ int main(int argc, char **argv)
|
|||
matches(argv[1], "-conf") == 0) {
|
||||
NEXT_ARG();
|
||||
conf_file = argv[1];
|
||||
} else if (matches(argv[1], "-color") == 0) {
|
||||
++color;
|
||||
} else if (matches_color(argv[1], &color)) {
|
||||
} else if (matches(argv[1], "-timestamp") == 0) {
|
||||
timestamp++;
|
||||
} else if (matches(argv[1], "-tshort") == 0) {
|
||||
|
|
|
|||
|
|
@ -5,26 +5,26 @@
|
|||
|
||||
extern struct rtnl_handle rth;
|
||||
|
||||
extern int do_qdisc(int argc, char **argv);
|
||||
extern int do_class(int argc, char **argv);
|
||||
extern int do_filter(int argc, char **argv, void *buf, size_t buflen);
|
||||
extern int do_chain(int argc, char **argv, void *buf, size_t buflen);
|
||||
extern int do_action(int argc, char **argv, void *buf, size_t buflen);
|
||||
extern int do_tcmonitor(int argc, char **argv);
|
||||
extern int do_exec(int argc, char **argv);
|
||||
int do_qdisc(int argc, char **argv);
|
||||
int do_class(int argc, char **argv);
|
||||
int do_filter(int argc, char **argv, void *buf, size_t buflen);
|
||||
int do_chain(int argc, char **argv, void *buf, size_t buflen);
|
||||
int do_action(int argc, char **argv, void *buf, size_t buflen);
|
||||
int do_tcmonitor(int argc, char **argv);
|
||||
int do_exec(int argc, char **argv);
|
||||
|
||||
extern int print_action(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg);
|
||||
extern int print_filter(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg);
|
||||
extern int print_qdisc(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg);
|
||||
extern int print_class(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg);
|
||||
extern void print_size_table(FILE *fp, const char *prefix, struct rtattr *rta);
|
||||
int print_action(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg);
|
||||
int print_filter(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg);
|
||||
int print_qdisc(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg);
|
||||
int print_class(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg);
|
||||
void print_size_table(FILE *fp, const char *prefix, struct rtattr *rta);
|
||||
|
||||
struct tc_estimator;
|
||||
extern int parse_estimator(int *p_argc, char ***p_argv, struct tc_estimator *est);
|
||||
int parse_estimator(int *p_argc, char ***p_argv, struct tc_estimator *est);
|
||||
|
||||
struct tc_sizespec;
|
||||
extern int parse_size_table(int *p_argc, char ***p_argv, struct tc_sizespec *s);
|
||||
extern int check_size_table_opts(struct tc_sizespec *s);
|
||||
int parse_size_table(int *p_argc, char ***p_argv, struct tc_sizespec *s);
|
||||
int check_size_table_opts(struct tc_sizespec *s);
|
||||
|
||||
extern int show_graph;
|
||||
extern bool use_names;
|
||||
|
|
|
|||
|
|
@ -2,8 +2,9 @@
|
|||
#ifndef _TC_RED_H_
|
||||
#define _TC_RED_H_ 1
|
||||
|
||||
extern int tc_red_eval_P(unsigned qmin, unsigned qmax, double prob);
|
||||
extern int tc_red_eval_ewma(unsigned qmin, unsigned burst, unsigned avpkt);
|
||||
extern int tc_red_eval_idle_damping(int wlog, unsigned avpkt, unsigned bandwidth, __u8 *sbuf);
|
||||
int tc_red_eval_P(unsigned qmin, unsigned qmax, double prob);
|
||||
int tc_red_eval_ewma(unsigned qmin, unsigned burst, unsigned avpkt);
|
||||
int tc_red_eval_idle_damping(int wlog, unsigned avpkt, unsigned bandwidth,
|
||||
__u8 *sbuf);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -14,15 +14,13 @@ TESTS_DIR := $(dir $(TESTS))
|
|||
|
||||
IPVERS := $(filter-out iproute2/Makefile,$(wildcard iproute2/*))
|
||||
|
||||
KENVFN := $(shell mktemp /tmp/tc_testkenv.XXXXXX)
|
||||
ifneq (,$(wildcard /proc/config.gz))
|
||||
KENV := $(shell cat /proc/config.gz | gunzip | grep ^CONFIG)
|
||||
KCPATH := /proc/config.gz
|
||||
else
|
||||
KVER := $(shell uname -r)
|
||||
KCPATHS := /lib/modules/$(KVER)/config /boot/config-$(KVER)
|
||||
KCPATH := $(firstword $(wildcard $(KCPATHS)))
|
||||
ifneq (,$(KCPATH))
|
||||
KENV := $(shell cat ${KCPATH} | grep ^CONFIG)
|
||||
endif
|
||||
endif
|
||||
|
||||
.PHONY: compile listtests alltests configure $(TESTS)
|
||||
|
|
@ -32,6 +30,7 @@ configure:
|
|||
|
||||
compile: configure
|
||||
echo "Entering iproute2" && cd iproute2 && $(MAKE) && cd ..;
|
||||
$(MAKE) -C tools
|
||||
|
||||
listtests:
|
||||
@for t in $(TESTS); do \
|
||||
|
|
@ -43,6 +42,9 @@ alltests: $(TESTS)
|
|||
clean:
|
||||
@echo "Removing $(RESULTS_DIR) dir ..."
|
||||
@rm -rf $(RESULTS_DIR)
|
||||
@rm -f iproute2/iproute2-this
|
||||
@rm -f tests/ip/link/dev_wo_vf_rate.nl
|
||||
$(MAKE) -C tools clean
|
||||
|
||||
distclean: clean
|
||||
echo "Entering iproute2" && cd iproute2 && $(MAKE) distclean && cd ..;
|
||||
|
|
@ -59,14 +61,22 @@ endif
|
|||
mkdir -p $(RESULTS_DIR)/$$d; \
|
||||
done
|
||||
|
||||
@if [ "$(KCPATH)" = "/proc/config.gz" ]; then \
|
||||
gunzip -c $(KCPATH) >$(KENVFN); \
|
||||
elif [ "$(KCPATH)" != "" ]; then \
|
||||
cat $(KCPATH) >$(KENVFN); \
|
||||
fi
|
||||
@sed -i -e 's/^CONFIG_/export CONFIG_/' $(KENVFN)
|
||||
|
||||
@for i in $(IPVERS); do \
|
||||
o=`echo $$i | sed -e 's/iproute2\///'`; \
|
||||
echo -n "Running $@ [$$o/`uname -r`]: "; \
|
||||
TMP_ERR=`mktemp /tmp/tc_testsuite.XXXXXX`; \
|
||||
TMP_OUT=`mktemp /tmp/tc_testsuite.XXXXXX`; \
|
||||
. $(KENVFN); \
|
||||
STD_ERR="$$TMP_ERR" STD_OUT="$$TMP_OUT" \
|
||||
TC="$$i/tc/tc" IP="$$i/ip/ip" SS=$$i/misc/ss DEV="$(DEV)" IPVER="$@" SNAME="$$i" \
|
||||
ERRF="$(RESULTS_DIR)/$@.$$o.err" $(KENV) $(PREFIX) tests/$@ > $(RESULTS_DIR)/$@.$$o.out; \
|
||||
ERRF="$(RESULTS_DIR)/$@.$$o.err" $(PREFIX) tests/$@ > $(RESULTS_DIR)/$@.$$o.out; \
|
||||
if [ "$$?" = "127" ]; then \
|
||||
echo "SKIPPED"; \
|
||||
elif [ -e "$(RESULTS_DIR)/$@.$$o.err" ]; then \
|
||||
|
|
@ -75,5 +85,5 @@ endif
|
|||
echo "PASS"; \
|
||||
fi; \
|
||||
rm "$$TMP_ERR" "$$TMP_OUT"; \
|
||||
dmesg > $(RESULTS_DIR)/$@.$$o.dmesg; \
|
||||
sudo dmesg > $(RESULTS_DIR)/$@.$$o.dmesg; \
|
||||
done
|
||||
|
|
|
|||
|
|
@ -1,3 +1,8 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
include ../../config.mk
|
||||
|
||||
generate_nlmsg: generate_nlmsg.c ../../lib/libnetlink.c
|
||||
$(CC) -o $@ $^
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDLIBS) $(EXTRA_CFLAGS) -I../../include -include../../include/uapi/linux/netlink.h -o $@ $^
|
||||
|
||||
clean:
|
||||
rm -f generate_nlmsg
|
||||
|
|
|
|||
Loading…
Reference in New Issue