mirror of
https://git.proxmox.com/git/mirror_iproute2
synced 2025-12-16 23:54:25 +00:00
Merge branch 'iproute2-master' into iproute2-next
Conflicts: bridge/mdb.c misc/ss.c tc/tc.c Signed-off-by: David Ahern <dsahern@gmail.com>
This commit is contained in:
commit
2c62a64d60
@ -1 +1 @@
|
|||||||
static const char SNAPSHOT[] = "180129";
|
static const char SNAPSHOT[] = "180402";
|
||||||
|
|||||||
14
ip/iplink.c
14
ip/iplink.c
@ -1127,7 +1127,7 @@ static int do_chflags(const char *dev, __u32 flags, __u32 mask)
|
|||||||
int fd;
|
int fd;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
strncpy(ifr.ifr_name, dev, IFNAMSIZ);
|
strlcpy(ifr.ifr_name, dev, IFNAMSIZ);
|
||||||
fd = get_ctl_fd();
|
fd = get_ctl_fd();
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return -1;
|
return -1;
|
||||||
@ -1154,8 +1154,8 @@ static int do_changename(const char *dev, const char *newdev)
|
|||||||
int fd;
|
int fd;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
strncpy(ifr.ifr_name, dev, IFNAMSIZ);
|
strlcpy(ifr.ifr_name, dev, IFNAMSIZ);
|
||||||
strncpy(ifr.ifr_newname, newdev, IFNAMSIZ);
|
strlcpy(ifr.ifr_newname, newdev, IFNAMSIZ);
|
||||||
fd = get_ctl_fd();
|
fd = get_ctl_fd();
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return -1;
|
return -1;
|
||||||
@ -1178,7 +1178,7 @@ static int set_qlen(const char *dev, int qlen)
|
|||||||
if (s < 0)
|
if (s < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
strncpy(ifr.ifr_name, dev, IFNAMSIZ);
|
strlcpy(ifr.ifr_name, dev, IFNAMSIZ);
|
||||||
if (ioctl(s, SIOCSIFTXQLEN, &ifr) < 0) {
|
if (ioctl(s, SIOCSIFTXQLEN, &ifr) < 0) {
|
||||||
perror("SIOCSIFXQLEN");
|
perror("SIOCSIFXQLEN");
|
||||||
close(s);
|
close(s);
|
||||||
@ -1198,7 +1198,7 @@ static int set_mtu(const char *dev, int mtu)
|
|||||||
if (s < 0)
|
if (s < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
strncpy(ifr.ifr_name, dev, IFNAMSIZ);
|
strlcpy(ifr.ifr_name, dev, IFNAMSIZ);
|
||||||
if (ioctl(s, SIOCSIFMTU, &ifr) < 0) {
|
if (ioctl(s, SIOCSIFMTU, &ifr) < 0) {
|
||||||
perror("SIOCSIFMTU");
|
perror("SIOCSIFMTU");
|
||||||
close(s);
|
close(s);
|
||||||
@ -1225,7 +1225,7 @@ static int get_address(const char *dev, int *htype)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
strncpy(ifr.ifr_name, dev, IFNAMSIZ);
|
strlcpy(ifr.ifr_name, dev, IFNAMSIZ);
|
||||||
if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
|
if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
|
||||||
perror("SIOCGIFINDEX");
|
perror("SIOCGIFINDEX");
|
||||||
close(s);
|
close(s);
|
||||||
@ -1256,7 +1256,7 @@ static int parse_address(const char *dev, int hatype, int halen,
|
|||||||
int alen;
|
int alen;
|
||||||
|
|
||||||
memset(ifr, 0, sizeof(*ifr));
|
memset(ifr, 0, sizeof(*ifr));
|
||||||
strncpy(ifr->ifr_name, dev, IFNAMSIZ);
|
strlcpy(ifr->ifr_name, dev, IFNAMSIZ);
|
||||||
ifr->ifr_hwaddr.sa_family = hatype;
|
ifr->ifr_hwaddr.sa_family = hatype;
|
||||||
alen = ll_addr_a2n(ifr->ifr_hwaddr.sa_data, 14, lla);
|
alen = ll_addr_a2n(ifr->ifr_hwaddr.sa_data, 14, lla);
|
||||||
if (alen < 0)
|
if (alen < 0)
|
||||||
|
|||||||
65
ip/iproute.c
65
ip/iproute.c
@ -190,20 +190,42 @@ static int filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len)
|
|||||||
return 0;
|
return 0;
|
||||||
if ((filter.tos^r->rtm_tos)&filter.tosmask)
|
if ((filter.tos^r->rtm_tos)&filter.tosmask)
|
||||||
return 0;
|
return 0;
|
||||||
if (filter.rdst.family &&
|
if (filter.rdst.family) {
|
||||||
(r->rtm_family != filter.rdst.family || filter.rdst.bitlen > r->rtm_dst_len))
|
if (r->rtm_family != filter.rdst.family ||
|
||||||
return 0;
|
filter.rdst.bitlen > r->rtm_dst_len)
|
||||||
if (filter.mdst.family &&
|
return 0;
|
||||||
(r->rtm_family != filter.mdst.family ||
|
} else if (filter.rdst.flags & PREFIXLEN_SPECIFIED) {
|
||||||
(filter.mdst.bitlen >= 0 && filter.mdst.bitlen < r->rtm_dst_len)))
|
if (filter.rdst.bitlen > r->rtm_dst_len)
|
||||||
return 0;
|
return 0;
|
||||||
if (filter.rsrc.family &&
|
}
|
||||||
(r->rtm_family != filter.rsrc.family || filter.rsrc.bitlen > r->rtm_src_len))
|
if (filter.mdst.family) {
|
||||||
return 0;
|
if (r->rtm_family != filter.mdst.family ||
|
||||||
if (filter.msrc.family &&
|
(filter.mdst.bitlen >= 0 &&
|
||||||
(r->rtm_family != filter.msrc.family ||
|
filter.mdst.bitlen < r->rtm_dst_len))
|
||||||
(filter.msrc.bitlen >= 0 && filter.msrc.bitlen < r->rtm_src_len)))
|
return 0;
|
||||||
return 0;
|
} else if (filter.mdst.flags & PREFIXLEN_SPECIFIED) {
|
||||||
|
if (filter.mdst.bitlen >= 0 &&
|
||||||
|
filter.mdst.bitlen < r->rtm_dst_len)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (filter.rsrc.family) {
|
||||||
|
if (r->rtm_family != filter.rsrc.family ||
|
||||||
|
filter.rsrc.bitlen > r->rtm_src_len)
|
||||||
|
return 0;
|
||||||
|
} else if (filter.rsrc.flags & PREFIXLEN_SPECIFIED) {
|
||||||
|
if (filter.rsrc.bitlen > r->rtm_src_len)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (filter.msrc.family) {
|
||||||
|
if (r->rtm_family != filter.msrc.family ||
|
||||||
|
(filter.msrc.bitlen >= 0 &&
|
||||||
|
filter.msrc.bitlen < r->rtm_src_len))
|
||||||
|
return 0;
|
||||||
|
} else if (filter.msrc.flags & PREFIXLEN_SPECIFIED) {
|
||||||
|
if (filter.msrc.bitlen >= 0 &&
|
||||||
|
filter.msrc.bitlen < r->rtm_src_len)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
if (filter.rvia.family) {
|
if (filter.rvia.family) {
|
||||||
int family = r->rtm_family;
|
int family = r->rtm_family;
|
||||||
|
|
||||||
@ -220,7 +242,9 @@ static int filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len)
|
|||||||
|
|
||||||
if (tb[RTA_DST])
|
if (tb[RTA_DST])
|
||||||
memcpy(&dst.data, RTA_DATA(tb[RTA_DST]), (r->rtm_dst_len+7)/8);
|
memcpy(&dst.data, RTA_DATA(tb[RTA_DST]), (r->rtm_dst_len+7)/8);
|
||||||
if (filter.rsrc.family || filter.msrc.family) {
|
if (filter.rsrc.family || filter.msrc.family ||
|
||||||
|
filter.rsrc.flags & PREFIXLEN_SPECIFIED ||
|
||||||
|
filter.msrc.flags & PREFIXLEN_SPECIFIED) {
|
||||||
if (tb[RTA_SRC])
|
if (tb[RTA_SRC])
|
||||||
memcpy(&src.data, RTA_DATA(tb[RTA_SRC]), (r->rtm_src_len+7)/8);
|
memcpy(&src.data, RTA_DATA(tb[RTA_SRC]), (r->rtm_src_len+7)/8);
|
||||||
}
|
}
|
||||||
@ -240,15 +264,18 @@ static int filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len)
|
|||||||
memcpy(&prefsrc.data, RTA_DATA(tb[RTA_PREFSRC]), host_len/8);
|
memcpy(&prefsrc.data, RTA_DATA(tb[RTA_PREFSRC]), host_len/8);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filter.rdst.family && inet_addr_match(&dst, &filter.rdst, filter.rdst.bitlen))
|
if ((filter.rdst.family || filter.rdst.flags & PREFIXLEN_SPECIFIED) &&
|
||||||
|
inet_addr_match(&dst, &filter.rdst, filter.rdst.bitlen))
|
||||||
return 0;
|
return 0;
|
||||||
if (filter.mdst.family && filter.mdst.bitlen >= 0 &&
|
if ((filter.mdst.family || filter.mdst.flags & PREFIXLEN_SPECIFIED) &&
|
||||||
inet_addr_match(&dst, &filter.mdst, r->rtm_dst_len))
|
inet_addr_match(&dst, &filter.mdst, r->rtm_dst_len))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (filter.rsrc.family && inet_addr_match(&src, &filter.rsrc, filter.rsrc.bitlen))
|
if ((filter.rsrc.family || filter.rsrc.flags & PREFIXLEN_SPECIFIED) &&
|
||||||
|
inet_addr_match(&src, &filter.rsrc, filter.rsrc.bitlen))
|
||||||
return 0;
|
return 0;
|
||||||
if (filter.msrc.family && filter.msrc.bitlen >= 0 &&
|
if ((filter.msrc.family || filter.msrc.flags & PREFIXLEN_SPECIFIED) &&
|
||||||
|
filter.msrc.bitlen >= 0 &&
|
||||||
inet_addr_match(&src, &filter.msrc, r->rtm_src_len))
|
inet_addr_match(&src, &filter.msrc, r->rtm_src_len))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|||||||
12
ip/tunnel.c
12
ip/tunnel.c
@ -65,7 +65,7 @@ int tnl_get_ioctl(const char *basedev, void *p)
|
|||||||
int fd;
|
int fd;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
strncpy(ifr.ifr_name, basedev, IFNAMSIZ);
|
strlcpy(ifr.ifr_name, basedev, IFNAMSIZ);
|
||||||
ifr.ifr_ifru.ifru_data = (void *)p;
|
ifr.ifr_ifru.ifru_data = (void *)p;
|
||||||
|
|
||||||
fd = socket(preferred_family, SOCK_DGRAM, 0);
|
fd = socket(preferred_family, SOCK_DGRAM, 0);
|
||||||
@ -90,9 +90,9 @@ int tnl_add_ioctl(int cmd, const char *basedev, const char *name, void *p)
|
|||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (cmd == SIOCCHGTUNNEL && name[0])
|
if (cmd == SIOCCHGTUNNEL && name[0])
|
||||||
strncpy(ifr.ifr_name, name, IFNAMSIZ);
|
strlcpy(ifr.ifr_name, name, IFNAMSIZ);
|
||||||
else
|
else
|
||||||
strncpy(ifr.ifr_name, basedev, IFNAMSIZ);
|
strlcpy(ifr.ifr_name, basedev, IFNAMSIZ);
|
||||||
ifr.ifr_ifru.ifru_data = p;
|
ifr.ifr_ifru.ifru_data = p;
|
||||||
|
|
||||||
fd = socket(preferred_family, SOCK_DGRAM, 0);
|
fd = socket(preferred_family, SOCK_DGRAM, 0);
|
||||||
@ -116,9 +116,9 @@ int tnl_del_ioctl(const char *basedev, const char *name, void *p)
|
|||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (name[0])
|
if (name[0])
|
||||||
strncpy(ifr.ifr_name, name, IFNAMSIZ);
|
strlcpy(ifr.ifr_name, name, IFNAMSIZ);
|
||||||
else
|
else
|
||||||
strncpy(ifr.ifr_name, basedev, IFNAMSIZ);
|
strlcpy(ifr.ifr_name, basedev, IFNAMSIZ);
|
||||||
|
|
||||||
ifr.ifr_ifru.ifru_data = p;
|
ifr.ifr_ifru.ifru_data = p;
|
||||||
|
|
||||||
@ -143,7 +143,7 @@ static int tnl_gen_ioctl(int cmd, const char *name,
|
|||||||
int fd;
|
int fd;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
strncpy(ifr.ifr_name, name, IFNAMSIZ);
|
strlcpy(ifr.ifr_name, name, IFNAMSIZ);
|
||||||
ifr.ifr_ifru.ifru_data = p;
|
ifr.ifr_ifru.ifru_data = p;
|
||||||
|
|
||||||
fd = socket(preferred_family, SOCK_DGRAM, 0);
|
fd = socket(preferred_family, SOCK_DGRAM, 0);
|
||||||
|
|||||||
@ -2593,7 +2593,7 @@ bpf_map_set_send(int fd, struct sockaddr_un *addr, unsigned int addr_len,
|
|||||||
char *amsg_buf;
|
char *amsg_buf;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
strncpy(msg.aux.obj_name, aux->obj, sizeof(msg.aux.obj_name));
|
strlcpy(msg.aux.obj_name, aux->obj, sizeof(msg.aux.obj_name));
|
||||||
memcpy(&msg.aux.obj_st, aux->st, sizeof(msg.aux.obj_st));
|
memcpy(&msg.aux.obj_st, aux->st, sizeof(msg.aux.obj_st));
|
||||||
|
|
||||||
cmsg_buf = bpf_map_set_init(&msg, addr, addr_len);
|
cmsg_buf = bpf_map_set_init(&msg, addr, addr_len);
|
||||||
@ -2682,7 +2682,7 @@ int bpf_send_map_fds(const char *path, const char *obj)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
strncpy(addr.sun_path, path, sizeof(addr.sun_path));
|
strlcpy(addr.sun_path, path, sizeof(addr.sun_path));
|
||||||
|
|
||||||
ret = connect(fd, (struct sockaddr *)&addr, sizeof(addr));
|
ret = connect(fd, (struct sockaddr *)&addr, sizeof(addr));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@ -2715,7 +2715,7 @@ int bpf_recv_map_fds(const char *path, int *fds, struct bpf_map_aux *aux,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
strncpy(addr.sun_path, path, sizeof(addr.sun_path));
|
strlcpy(addr.sun_path, path, sizeof(addr.sun_path));
|
||||||
|
|
||||||
ret = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
|
ret = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
|||||||
@ -17,12 +17,15 @@
|
|||||||
|
|
||||||
static void bind_etc(const char *name)
|
static void bind_etc(const char *name)
|
||||||
{
|
{
|
||||||
char etc_netns_path[PATH_MAX];
|
char etc_netns_path[sizeof(NETNS_ETC_DIR) + NAME_MAX];
|
||||||
char netns_name[PATH_MAX];
|
char netns_name[PATH_MAX];
|
||||||
char etc_name[PATH_MAX];
|
char etc_name[PATH_MAX];
|
||||||
struct dirent *entry;
|
struct dirent *entry;
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
|
|
||||||
|
if (strlen(name) >= NAME_MAX)
|
||||||
|
return;
|
||||||
|
|
||||||
snprintf(etc_netns_path, sizeof(etc_netns_path), "%s/%s", NETNS_ETC_DIR, name);
|
snprintf(etc_netns_path, sizeof(etc_netns_path), "%s/%s", NETNS_ETC_DIR, name);
|
||||||
dir = opendir(etc_netns_path);
|
dir = opendir(etc_netns_path);
|
||||||
if (!dir)
|
if (!dir)
|
||||||
|
|||||||
13
lib/utils.c
13
lib/utils.c
@ -695,19 +695,6 @@ int get_prefix_1(inet_prefix *dst, char *arg, int family)
|
|||||||
char *slash;
|
char *slash;
|
||||||
int err, bitlen, flags;
|
int err, bitlen, flags;
|
||||||
|
|
||||||
memset(dst, 0, sizeof(*dst));
|
|
||||||
|
|
||||||
if (strcmp(arg, "default") == 0 ||
|
|
||||||
strcmp(arg, "any") == 0 ||
|
|
||||||
strcmp(arg, "all") == 0) {
|
|
||||||
if ((family == AF_DECnet) || (family == AF_MPLS))
|
|
||||||
return -1;
|
|
||||||
dst->family = family;
|
|
||||||
dst->bytelen = 0;
|
|
||||||
dst->bitlen = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
slash = strchr(arg, '/');
|
slash = strchr(arg, '/');
|
||||||
if (slash)
|
if (slash)
|
||||||
*slash = 0;
|
*slash = 0;
|
||||||
|
|||||||
@ -19,7 +19,7 @@ devlink \- Devlink tool
|
|||||||
|
|
||||||
.ti -8
|
.ti -8
|
||||||
.IR OBJECT " := { "
|
.IR OBJECT " := { "
|
||||||
.BR dev " | " port " | " monitor " }"
|
.BR dev " | " port " | " monitor " | " sb " | " resource " }"
|
||||||
.sp
|
.sp
|
||||||
|
|
||||||
.ti -8
|
.ti -8
|
||||||
@ -74,6 +74,14 @@ When combined with -j generate a pretty JSON output.
|
|||||||
.B monitor
|
.B monitor
|
||||||
- watch for netlink messages.
|
- watch for netlink messages.
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.B sb
|
||||||
|
- devlink shared buffer configuration.
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.B resource
|
||||||
|
- devlink device resource configuration.
|
||||||
|
|
||||||
.SS
|
.SS
|
||||||
.I COMMAND
|
.I COMMAND
|
||||||
|
|
||||||
|
|||||||
@ -30,7 +30,7 @@ rdma-link \- rdma link configuration
|
|||||||
|
|
||||||
.PP
|
.PP
|
||||||
.I "DEV/PORT_INDEX"
|
.I "DEV/PORT_INDEX"
|
||||||
- specifies the RDMa link to show.
|
- specifies the RDMA link to show.
|
||||||
If this argument is omitted all links are listed.
|
If this argument is omitted all links are listed.
|
||||||
|
|
||||||
.SH "EXAMPLES"
|
.SH "EXAMPLES"
|
||||||
|
|||||||
@ -49,7 +49,7 @@ If there were any errors during execution of the commands, the application retur
|
|||||||
|
|
||||||
.TP
|
.TP
|
||||||
.BR "\-d" , " --details"
|
.BR "\-d" , " --details"
|
||||||
Otuput detailed information.
|
Output detailed information.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.BR "\-p" , " --pretty"
|
.BR "\-p" , " --pretty"
|
||||||
|
|||||||
@ -317,7 +317,10 @@ Currently the following families are supported: unix, inet, inet6, link, netlink
|
|||||||
List of socket tables to dump, separated by commas. The following identifiers
|
List of socket tables to dump, separated by commas. The following identifiers
|
||||||
are understood: all, inet, tcp, udp, raw, unix, packet, netlink, unix_dgram,
|
are understood: all, inet, tcp, udp, raw, unix, packet, netlink, unix_dgram,
|
||||||
unix_stream, unix_seqpacket, packet_raw, packet_dgram, dccp, sctp,
|
unix_stream, unix_seqpacket, packet_raw, packet_dgram, dccp, sctp,
|
||||||
vsock_stream, vsock_dgram.
|
vsock_stream, vsock_dgram. Any item in the list may optionally be prefixed by
|
||||||
|
an exclamation mark
|
||||||
|
.RB ( ! )
|
||||||
|
to exclude that socket table from being dumped.
|
||||||
.TP
|
.TP
|
||||||
.B \-D FILE, \-\-diag=FILE
|
.B \-D FILE, \-\-diag=FILE
|
||||||
Do not display anything, just dump raw information about TCP sockets to FILE after applying filters. If FILE is - stdout is used.
|
Do not display anything, just dump raw information about TCP sockets to FILE after applying filters. If FILE is - stdout is used.
|
||||||
@ -380,6 +383,9 @@ Find all local processes connected to X server.
|
|||||||
.TP
|
.TP
|
||||||
.B ss -o state fin-wait-1 '( sport = :http or sport = :https )' dst 193.233.7/24
|
.B ss -o state fin-wait-1 '( sport = :http or sport = :https )' dst 193.233.7/24
|
||||||
List all the tcp sockets in state FIN-WAIT-1 for our apache to network 193.233.7/24 and look at their timers.
|
List all the tcp sockets in state FIN-WAIT-1 for our apache to network 193.233.7/24 and look at their timers.
|
||||||
|
.TP
|
||||||
|
.B ss -a -A 'all,!tcp'
|
||||||
|
List sockets in all states from all socket tables but TCP.
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.BR ip (8),
|
.BR ip (8),
|
||||||
.br
|
.br
|
||||||
|
|||||||
@ -177,12 +177,12 @@ static int count_spaces(const char *line)
|
|||||||
|
|
||||||
static void load_ugly_table(FILE *fp)
|
static void load_ugly_table(FILE *fp)
|
||||||
{
|
{
|
||||||
char buf[4096];
|
char buf[2048];
|
||||||
struct nstat_ent *db = NULL;
|
struct nstat_ent *db = NULL;
|
||||||
struct nstat_ent *n;
|
struct nstat_ent *n;
|
||||||
|
|
||||||
while (fgets(buf, sizeof(buf), fp) != NULL) {
|
while (fgets(buf, sizeof(buf), fp) != NULL) {
|
||||||
char idbuf[sizeof(buf)];
|
char idbuf[4096];
|
||||||
int off;
|
int off;
|
||||||
char *p;
|
char *p;
|
||||||
int count1, count2, skip = 0;
|
int count1, count2, skip = 0;
|
||||||
|
|||||||
152
misc/ss.c
152
misc/ss.c
@ -344,13 +344,72 @@ static const struct filter default_afs[AF_MAX] = {
|
|||||||
static int do_default = 1;
|
static int do_default = 1;
|
||||||
static struct filter current_filter;
|
static struct filter current_filter;
|
||||||
|
|
||||||
static void filter_db_set(struct filter *f, int db)
|
static void filter_db_set(struct filter *f, int db, bool enable)
|
||||||
{
|
{
|
||||||
f->states |= default_dbs[db].states;
|
if (enable) {
|
||||||
f->dbs |= 1 << db;
|
f->states |= default_dbs[db].states;
|
||||||
|
f->dbs |= 1 << db;
|
||||||
|
} else {
|
||||||
|
f->dbs &= ~(1 << db);
|
||||||
|
}
|
||||||
do_default = 0;
|
do_default = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int filter_db_parse(struct filter *f, const char *s)
|
||||||
|
{
|
||||||
|
const struct {
|
||||||
|
const char *name;
|
||||||
|
int dbs[MAX_DB + 1];
|
||||||
|
} db_name_tbl[] = {
|
||||||
|
#define ENTRY(name, ...) { #name, { __VA_ARGS__, MAX_DB } }
|
||||||
|
ENTRY(all, UDP_DB, DCCP_DB, TCP_DB, RAW_DB,
|
||||||
|
UNIX_ST_DB, UNIX_DG_DB, UNIX_SQ_DB,
|
||||||
|
PACKET_R_DB, PACKET_DG_DB, NETLINK_DB,
|
||||||
|
SCTP_DB, VSOCK_ST_DB, VSOCK_DG_DB),
|
||||||
|
ENTRY(inet, UDP_DB, DCCP_DB, TCP_DB, SCTP_DB, RAW_DB),
|
||||||
|
ENTRY(udp, UDP_DB),
|
||||||
|
ENTRY(dccp, DCCP_DB),
|
||||||
|
ENTRY(tcp, TCP_DB),
|
||||||
|
ENTRY(sctp, SCTP_DB),
|
||||||
|
ENTRY(raw, RAW_DB),
|
||||||
|
ENTRY(unix, UNIX_ST_DB, UNIX_DG_DB, UNIX_SQ_DB),
|
||||||
|
ENTRY(unix_stream, UNIX_ST_DB),
|
||||||
|
ENTRY(u_str, UNIX_ST_DB), /* alias for unix_stream */
|
||||||
|
ENTRY(unix_dgram, UNIX_DG_DB),
|
||||||
|
ENTRY(u_dgr, UNIX_DG_DB), /* alias for unix_dgram */
|
||||||
|
ENTRY(unix_seqpacket, UNIX_SQ_DB),
|
||||||
|
ENTRY(u_seq, UNIX_SQ_DB), /* alias for unix_seqpacket */
|
||||||
|
ENTRY(packet, PACKET_R_DB, PACKET_DG_DB),
|
||||||
|
ENTRY(packet_raw, PACKET_R_DB),
|
||||||
|
ENTRY(p_raw, PACKET_R_DB), /* alias for packet_raw */
|
||||||
|
ENTRY(packet_dgram, PACKET_DG_DB),
|
||||||
|
ENTRY(p_dgr, PACKET_DG_DB), /* alias for packet_dgram */
|
||||||
|
ENTRY(netlink, NETLINK_DB),
|
||||||
|
ENTRY(vsock, VSOCK_ST_DB, VSOCK_DG_DB),
|
||||||
|
ENTRY(vsock_stream, VSOCK_ST_DB),
|
||||||
|
ENTRY(v_str, VSOCK_ST_DB), /* alias for vsock_stream */
|
||||||
|
ENTRY(vsock_dgram, VSOCK_DG_DB),
|
||||||
|
ENTRY(v_dgr, VSOCK_DG_DB), /* alias for vsock_dgram */
|
||||||
|
#undef ENTRY
|
||||||
|
};
|
||||||
|
bool enable = true;
|
||||||
|
unsigned int i;
|
||||||
|
const int *dbp;
|
||||||
|
|
||||||
|
if (s[0] == '!') {
|
||||||
|
enable = false;
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
for (i = 0; i < ARRAY_SIZE(db_name_tbl); i++) {
|
||||||
|
if (strcmp(s, db_name_tbl[i].name))
|
||||||
|
continue;
|
||||||
|
for (dbp = db_name_tbl[i].dbs; *dbp != MAX_DB; dbp++)
|
||||||
|
filter_db_set(f, *dbp, enable);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
static void filter_af_set(struct filter *f, int af)
|
static void filter_af_set(struct filter *f, int af)
|
||||||
{
|
{
|
||||||
f->states |= default_afs[af].states;
|
f->states |= default_afs[af].states;
|
||||||
@ -364,24 +423,6 @@ static int filter_af_get(struct filter *f, int af)
|
|||||||
return !!(f->families & FAMILY_MASK(af));
|
return !!(f->families & FAMILY_MASK(af));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void filter_default_dbs(struct filter *f)
|
|
||||||
{
|
|
||||||
filter_db_set(f, UDP_DB);
|
|
||||||
filter_db_set(f, DCCP_DB);
|
|
||||||
filter_db_set(f, TCP_DB);
|
|
||||||
filter_db_set(f, RAW_DB);
|
|
||||||
filter_db_set(f, UNIX_ST_DB);
|
|
||||||
filter_db_set(f, UNIX_DG_DB);
|
|
||||||
filter_db_set(f, UNIX_SQ_DB);
|
|
||||||
filter_db_set(f, PACKET_R_DB);
|
|
||||||
filter_db_set(f, PACKET_DG_DB);
|
|
||||||
filter_db_set(f, NETLINK_DB);
|
|
||||||
filter_db_set(f, SCTP_DB);
|
|
||||||
filter_db_set(f, VSOCK_ST_DB);
|
|
||||||
filter_db_set(f, VSOCK_DG_DB);
|
|
||||||
filter_db_set(f, TIPC_DB);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void filter_states_set(struct filter *f, int states)
|
static void filter_states_set(struct filter *f, int states)
|
||||||
{
|
{
|
||||||
if (states)
|
if (states)
|
||||||
@ -4097,7 +4138,7 @@ static int netlink_show_one(struct filter *f,
|
|||||||
|
|
||||||
if (!pid) {
|
if (!pid) {
|
||||||
done = 1;
|
done = 1;
|
||||||
strncpy(procname, "kernel", 6);
|
strncpy(procname, "kernel", 7);
|
||||||
} else if (pid > 0) {
|
} else if (pid > 0) {
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
|
||||||
@ -4865,19 +4906,19 @@ int main(int argc, char *argv[])
|
|||||||
follow_events = 1;
|
follow_events = 1;
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
filter_db_set(¤t_filter, DCCP_DB);
|
filter_db_set(¤t_filter, DCCP_DB, true);
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
filter_db_set(¤t_filter, TCP_DB);
|
filter_db_set(¤t_filter, TCP_DB, true);
|
||||||
break;
|
break;
|
||||||
case 'S':
|
case 'S':
|
||||||
filter_db_set(¤t_filter, SCTP_DB);
|
filter_db_set(¤t_filter, SCTP_DB, true);
|
||||||
break;
|
break;
|
||||||
case 'u':
|
case 'u':
|
||||||
filter_db_set(¤t_filter, UDP_DB);
|
filter_db_set(¤t_filter, UDP_DB, true);
|
||||||
break;
|
break;
|
||||||
case 'w':
|
case 'w':
|
||||||
filter_db_set(¤t_filter, RAW_DB);
|
filter_db_set(¤t_filter, RAW_DB, true);
|
||||||
break;
|
break;
|
||||||
case 'x':
|
case 'x':
|
||||||
filter_af_set(¤t_filter, AF_UNIX);
|
filter_af_set(¤t_filter, AF_UNIX);
|
||||||
@ -4941,60 +4982,7 @@ int main(int argc, char *argv[])
|
|||||||
do {
|
do {
|
||||||
if ((p1 = strchr(p, ',')) != NULL)
|
if ((p1 = strchr(p, ',')) != NULL)
|
||||||
*p1 = 0;
|
*p1 = 0;
|
||||||
if (strcmp(p, "all") == 0) {
|
if (filter_db_parse(¤t_filter, p)) {
|
||||||
filter_default_dbs(¤t_filter);
|
|
||||||
} else if (strcmp(p, "inet") == 0) {
|
|
||||||
filter_db_set(¤t_filter, UDP_DB);
|
|
||||||
filter_db_set(¤t_filter, DCCP_DB);
|
|
||||||
filter_db_set(¤t_filter, TCP_DB);
|
|
||||||
filter_db_set(¤t_filter, SCTP_DB);
|
|
||||||
filter_db_set(¤t_filter, RAW_DB);
|
|
||||||
} else if (strcmp(p, "udp") == 0) {
|
|
||||||
filter_db_set(¤t_filter, UDP_DB);
|
|
||||||
} else if (strcmp(p, "dccp") == 0) {
|
|
||||||
filter_db_set(¤t_filter, DCCP_DB);
|
|
||||||
} else if (strcmp(p, "tcp") == 0) {
|
|
||||||
filter_db_set(¤t_filter, TCP_DB);
|
|
||||||
} else if (strcmp(p, "sctp") == 0) {
|
|
||||||
filter_db_set(¤t_filter, SCTP_DB);
|
|
||||||
} else if (strcmp(p, "raw") == 0) {
|
|
||||||
filter_db_set(¤t_filter, RAW_DB);
|
|
||||||
} else if (strcmp(p, "unix") == 0) {
|
|
||||||
filter_db_set(¤t_filter, UNIX_ST_DB);
|
|
||||||
filter_db_set(¤t_filter, UNIX_DG_DB);
|
|
||||||
filter_db_set(¤t_filter, UNIX_SQ_DB);
|
|
||||||
} else if (strcasecmp(p, "unix_stream") == 0 ||
|
|
||||||
strcmp(p, "u_str") == 0) {
|
|
||||||
filter_db_set(¤t_filter, UNIX_ST_DB);
|
|
||||||
} else if (strcasecmp(p, "unix_dgram") == 0 ||
|
|
||||||
strcmp(p, "u_dgr") == 0) {
|
|
||||||
filter_db_set(¤t_filter, UNIX_DG_DB);
|
|
||||||
} else if (strcasecmp(p, "unix_seqpacket") == 0 ||
|
|
||||||
strcmp(p, "u_seq") == 0) {
|
|
||||||
filter_db_set(¤t_filter, UNIX_SQ_DB);
|
|
||||||
} else if (strcmp(p, "packet") == 0) {
|
|
||||||
filter_db_set(¤t_filter, PACKET_R_DB);
|
|
||||||
filter_db_set(¤t_filter, PACKET_DG_DB);
|
|
||||||
} else if (strcmp(p, "packet_raw") == 0 ||
|
|
||||||
strcmp(p, "p_raw") == 0) {
|
|
||||||
filter_db_set(¤t_filter, PACKET_R_DB);
|
|
||||||
} else if (strcmp(p, "packet_dgram") == 0 ||
|
|
||||||
strcmp(p, "p_dgr") == 0) {
|
|
||||||
filter_db_set(¤t_filter, PACKET_DG_DB);
|
|
||||||
} else if (strcmp(p, "netlink") == 0) {
|
|
||||||
filter_db_set(¤t_filter, NETLINK_DB);
|
|
||||||
} else if (strcmp(p, "vsock") == 0) {
|
|
||||||
filter_db_set(¤t_filter, VSOCK_ST_DB);
|
|
||||||
filter_db_set(¤t_filter, VSOCK_DG_DB);
|
|
||||||
} else if (strcmp(p, "vsock_stream") == 0 ||
|
|
||||||
strcmp(p, "v_str") == 0) {
|
|
||||||
filter_db_set(¤t_filter, VSOCK_ST_DB);
|
|
||||||
} else if (strcmp(p, "vsock_dgram") == 0 ||
|
|
||||||
strcmp(p, "v_dgr") == 0) {
|
|
||||||
filter_db_set(¤t_filter, VSOCK_DG_DB);
|
|
||||||
} else if (strcmp(optarg, "tipc") == 0) {
|
|
||||||
filter_db_set(¤t_filter, TIPC_DB);
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "ss: \"%s\" is illegal socket table id\n", p);
|
fprintf(stderr, "ss: \"%s\" is illegal socket table id\n", p);
|
||||||
usage();
|
usage();
|
||||||
}
|
}
|
||||||
@ -5089,7 +5077,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (do_default) {
|
if (do_default) {
|
||||||
state_filter = state_filter ? state_filter : SS_CONN;
|
state_filter = state_filter ? state_filter : SS_CONN;
|
||||||
filter_default_dbs(¤t_filter);
|
filter_db_parse(¤t_filter, "all");
|
||||||
}
|
}
|
||||||
|
|
||||||
filter_states_set(¤t_filter, state_filter);
|
filter_states_set(¤t_filter, state_filter);
|
||||||
|
|||||||
@ -161,7 +161,7 @@ static struct ematch_util *get_ematch_kind(char *kind)
|
|||||||
|
|
||||||
static struct ematch_util *get_ematch_kind_num(__u16 kind)
|
static struct ematch_util *get_ematch_kind_num(__u16 kind)
|
||||||
{
|
{
|
||||||
char name[32];
|
char name[513];
|
||||||
|
|
||||||
if (lookup_map(kind, name, sizeof(name), EMATCH_MAP) < 0)
|
if (lookup_map(kind, name, sizeof(name), EMATCH_MAP) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
@ -168,6 +168,9 @@ print_nat(struct action_util *au, FILE * f, struct rtattr *arg)
|
|||||||
format_host_r(AF_INET, 4, &sel->new_addr, buf2, sizeof(buf2)));
|
format_host_r(AF_INET, 4, &sel->new_addr, buf2, sizeof(buf2)));
|
||||||
print_action_control(f, " ", sel->action, "");
|
print_action_control(f, " ", sel->action, "");
|
||||||
|
|
||||||
|
fprintf(f, "\n\t index %u ref %d bind %d",
|
||||||
|
sel->index, sel->refcnt, sel->bindcnt);
|
||||||
|
|
||||||
if (show_stats) {
|
if (show_stats) {
|
||||||
if (tb[TCA_NAT_TM]) {
|
if (tb[TCA_NAT_TM]) {
|
||||||
struct tcf_t *tm = RTA_DATA(tb[TCA_NAT_TM]);
|
struct tcf_t *tm = RTA_DATA(tb[TCA_NAT_TM]);
|
||||||
@ -176,6 +179,8 @@ print_nat(struct action_util *au, FILE * f, struct rtattr *arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fprintf(f, "\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -111,7 +111,7 @@ reg:
|
|||||||
noexist:
|
noexist:
|
||||||
p = calloc(1, sizeof(*p));
|
p = calloc(1, sizeof(*p));
|
||||||
if (p) {
|
if (p) {
|
||||||
strncpy(p->id, str, sizeof(p->id) - 1);
|
strlcpy(p->id, str, sizeof(p->id));
|
||||||
p->parse_peopt = pedit_parse_nopopt;
|
p->parse_peopt = pedit_parse_nopopt;
|
||||||
goto reg;
|
goto reg;
|
||||||
}
|
}
|
||||||
|
|||||||
43
tc/tc.c
43
tc/tc.c
@ -62,10 +62,13 @@ static int print_noqopt(struct qdisc_util *qu, FILE *f,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_noqopt(struct qdisc_util *qu, int argc, char **argv, struct nlmsghdr *n, const char *dev)
|
static int parse_noqopt(struct qdisc_util *qu, int argc, char **argv,
|
||||||
|
struct nlmsghdr *n, const char *dev)
|
||||||
{
|
{
|
||||||
if (argc) {
|
if (argc) {
|
||||||
fprintf(stderr, "Unknown qdisc \"%s\", hence option \"%s\" is unparsable\n", qu->id, *argv);
|
fprintf(stderr,
|
||||||
|
"Unknown qdisc \"%s\", hence option \"%s\" is unparsable\n",
|
||||||
|
qu->id, *argv);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -81,12 +84,15 @@ static int print_nofopt(struct filter_util *qu, FILE *f, struct rtattr *opt, __u
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_nofopt(struct filter_util *qu, char *fhandle, int argc, char **argv, struct nlmsghdr *n)
|
static int parse_nofopt(struct filter_util *qu, char *fhandle,
|
||||||
|
int argc, char **argv, struct nlmsghdr *n)
|
||||||
{
|
{
|
||||||
__u32 handle;
|
__u32 handle;
|
||||||
|
|
||||||
if (argc) {
|
if (argc) {
|
||||||
fprintf(stderr, "Unknown filter \"%s\", hence option \"%s\" is unparsable\n", qu->id, *argv);
|
fprintf(stderr,
|
||||||
|
"Unknown filter \"%s\", hence option \"%s\" is unparsable\n",
|
||||||
|
qu->id, *argv);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (fhandle) {
|
if (fhandle) {
|
||||||
@ -188,12 +194,14 @@ noexist:
|
|||||||
|
|
||||||
static void usage(void)
|
static void usage(void)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Usage: tc [ OPTIONS ] OBJECT { COMMAND | help }\n"
|
fprintf(stderr,
|
||||||
|
"Usage: tc [ OPTIONS ] OBJECT { COMMAND | help }\n"
|
||||||
" tc [-force] -batch filename\n"
|
" tc [-force] -batch filename\n"
|
||||||
"where OBJECT := { qdisc | class | filter | action | monitor | exec }\n"
|
"where OBJECT := { qdisc | class | filter | action | monitor | exec }\n"
|
||||||
" OPTIONS := { -s[tatistics] | -d[etails] | -r[aw] | -b[atch] [filename] | -n[etns] name |\n"
|
" OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[aw] |\n"
|
||||||
" -nm | -nam[es] | { -cf | -conf } path } |\n"
|
" -o[neline] | -j[son] | -p[retty] | -c[olor]\n"
|
||||||
" -o[neline] -j[son] -p[retty] -c[olor]\n");
|
" -b[atch] [filename] | -n[etns] name |\n"
|
||||||
|
" -nm | -nam[es] | { -cf | -conf } path }\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_cmd(int argc, char **argv, void *buf, size_t buflen)
|
static int do_cmd(int argc, char **argv, void *buf, size_t buflen)
|
||||||
@ -227,8 +235,8 @@ static bool batchsize_enabled(int argc, char *argv[])
|
|||||||
char *c;
|
char *c;
|
||||||
char *subc[TC_MAX_SUBC];
|
char *subc[TC_MAX_SUBC];
|
||||||
} table[] = {
|
} table[] = {
|
||||||
{"filter", {"add", "delete", "change", "replace", NULL}},
|
{ "filter", { "add", "delete", "change", "replace", NULL} },
|
||||||
{"actions", {"add", "change", "replace", NULL}},
|
{ "actions", { "add", "change", "replace", NULL} },
|
||||||
{ NULL },
|
{ NULL },
|
||||||
}, *iter;
|
}, *iter;
|
||||||
char *s;
|
char *s;
|
||||||
@ -265,11 +273,11 @@ static struct batch_buf *get_batch_buf(struct batch_buf **pool,
|
|||||||
struct batch_buf *buf;
|
struct batch_buf *buf;
|
||||||
|
|
||||||
if (*pool == NULL)
|
if (*pool == NULL)
|
||||||
buf = calloc(1, sizeof (struct batch_buf));
|
buf = calloc(1, sizeof(struct batch_buf));
|
||||||
else {
|
else {
|
||||||
buf = *pool;
|
buf = *pool;
|
||||||
*pool = (*pool)->next;
|
*pool = (*pool)->next;
|
||||||
memset(buf, 0, sizeof (struct batch_buf));
|
memset(buf, 0, sizeof(struct batch_buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*head == NULL)
|
if (*head == NULL)
|
||||||
@ -328,7 +336,8 @@ static int batch(const char *name)
|
|||||||
batch_mode = 1;
|
batch_mode = 1;
|
||||||
if (name && strcmp(name, "-") != 0) {
|
if (name && strcmp(name, "-") != 0) {
|
||||||
if (freopen(name, "r", stdin) == NULL) {
|
if (freopen(name, "r", stdin) == NULL) {
|
||||||
fprintf(stderr, "Cannot open file \"%s\" for reading: %s\n",
|
fprintf(stderr,
|
||||||
|
"Cannot open file \"%s\" for reading: %s\n",
|
||||||
name, strerror(errno));
|
name, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -391,7 +400,7 @@ static int batch(const char *name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret = do_cmd(largc, largv, tail == NULL ? NULL : tail->buf,
|
ret = do_cmd(largc, largv, tail == NULL ? NULL : tail->buf,
|
||||||
tail == NULL ? 0 : sizeof (tail->buf));
|
tail == NULL ? 0 : sizeof(tail->buf));
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
fprintf(stderr, "Command failed %s:%d\n", name,
|
fprintf(stderr, "Command failed %s:%d\n", name,
|
||||||
cmdlineno - 1);
|
cmdlineno - 1);
|
||||||
@ -407,7 +416,7 @@ static int batch(const char *name)
|
|||||||
struct batch_buf *buf;
|
struct batch_buf *buf;
|
||||||
struct nlmsghdr *n;
|
struct nlmsghdr *n;
|
||||||
|
|
||||||
iov = iovs = malloc(batchsize * sizeof (struct iovec));
|
iov = iovs = malloc(batchsize * sizeof(struct iovec));
|
||||||
for (buf = head; buf != NULL; buf = buf->next, ++iov) {
|
for (buf = head; buf != NULL; buf = buf->next, ++iov) {
|
||||||
n = (struct nlmsghdr *)&buf->buf;
|
n = (struct nlmsghdr *)&buf->buf;
|
||||||
iov->iov_base = n;
|
iov->iov_base = n;
|
||||||
@ -492,7 +501,9 @@ int main(int argc, char **argv)
|
|||||||
} else if (matches(argv[1], "-oneline") == 0) {
|
} else if (matches(argv[1], "-oneline") == 0) {
|
||||||
++oneline;
|
++oneline;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Option \"%s\" is unknown, try \"tc -help\".\n", argv[1]);
|
fprintf(stderr,
|
||||||
|
"Option \"%s\" is unknown, try \"tc -help\".\n",
|
||||||
|
argv[1]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
argc--; argv++;
|
argc--; argv++;
|
||||||
|
|||||||
@ -218,7 +218,7 @@ static void graph_cls_show(FILE *fp, char *buf, struct hlist_head *root_list,
|
|||||||
char cls_id_str[256] = {};
|
char cls_id_str[256] = {};
|
||||||
struct rtattr *tb[TCA_MAX + 1];
|
struct rtattr *tb[TCA_MAX + 1];
|
||||||
struct qdisc_util *q;
|
struct qdisc_util *q;
|
||||||
char str[100] = {};
|
char str[300] = {};
|
||||||
|
|
||||||
hlist_for_each_safe(n, tmp_cls, root_list) {
|
hlist_for_each_safe(n, tmp_cls, root_list) {
|
||||||
struct hlist_node *c, *tmp_chld;
|
struct hlist_node *c, *tmp_chld;
|
||||||
@ -241,7 +241,8 @@ static void graph_cls_show(FILE *fp, char *buf, struct hlist_head *root_list,
|
|||||||
graph_indent(buf, cls, 0, 0);
|
graph_indent(buf, cls, 0, 0);
|
||||||
|
|
||||||
print_tc_classid(cls_id_str, sizeof(cls_id_str), cls->id);
|
print_tc_classid(cls_id_str, sizeof(cls_id_str), cls->id);
|
||||||
sprintf(str, "+---(%s)", cls_id_str);
|
snprintf(str, sizeof(str),
|
||||||
|
"+---(%s)", cls_id_str);
|
||||||
strcat(buf, str);
|
strcat(buf, str);
|
||||||
|
|
||||||
parse_rtattr(tb, TCA_MAX, (struct rtattr *)cls->data,
|
parse_rtattr(tb, TCA_MAX, (struct rtattr *)cls->data,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user