net-procfs: show net devices bound packet types
After commit:7866a621043f ("dev: add per net_device packet type chains"),
we can not get packet types that are bound to a specified net device by
/proc/net/ptype, this patch fix the regression.
Run "tcpdump -i ens192 udp -nns0" Before and after apply this patch:
Before:
[root@localhost ~]# cat /proc/net/ptype
Type Device Function
0800 ip_rcv
0806 arp_rcv
86dd ipv6_rcv
After:
[root@localhost ~]# cat /proc/net/ptype
Type Device Function
ALL ens192 tpacket_rcv
0800 ip_rcv
0806 arp_rcv
86dd ipv6_rcv
v1 -> v2:
- fix the regression rather than adding new /proc API as
suggested by Stephen Hemminger.
Fixes: 7866a62104
("dev: add per net_device packet type chains")
Signed-off-by: Jianguo Wu <wujianguo@chinatelecom.cn>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
aa6034678e
commit
1d10f8a1f4
|
@ -190,12 +190,23 @@ static const struct seq_operations softnet_seq_ops = {
|
|||
.show = softnet_seq_show,
|
||||
};
|
||||
|
||||
static void *ptype_get_idx(loff_t pos)
|
||||
static void *ptype_get_idx(struct seq_file *seq, loff_t pos)
|
||||
{
|
||||
struct list_head *ptype_list = NULL;
|
||||
struct packet_type *pt = NULL;
|
||||
struct net_device *dev;
|
||||
loff_t i = 0;
|
||||
int t;
|
||||
|
||||
for_each_netdev_rcu(seq_file_net(seq), dev) {
|
||||
ptype_list = &dev->ptype_all;
|
||||
list_for_each_entry_rcu(pt, ptype_list, list) {
|
||||
if (i == pos)
|
||||
return pt;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
list_for_each_entry_rcu(pt, &ptype_all, list) {
|
||||
if (i == pos)
|
||||
return pt;
|
||||
|
@ -216,22 +227,40 @@ static void *ptype_seq_start(struct seq_file *seq, loff_t *pos)
|
|||
__acquires(RCU)
|
||||
{
|
||||
rcu_read_lock();
|
||||
return *pos ? ptype_get_idx(*pos - 1) : SEQ_START_TOKEN;
|
||||
return *pos ? ptype_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
|
||||
}
|
||||
|
||||
static void *ptype_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
||||
{
|
||||
struct net_device *dev;
|
||||
struct packet_type *pt;
|
||||
struct list_head *nxt;
|
||||
int hash;
|
||||
|
||||
++*pos;
|
||||
if (v == SEQ_START_TOKEN)
|
||||
return ptype_get_idx(0);
|
||||
return ptype_get_idx(seq, 0);
|
||||
|
||||
pt = v;
|
||||
nxt = pt->list.next;
|
||||
if (pt->dev) {
|
||||
if (nxt != &pt->dev->ptype_all)
|
||||
goto found;
|
||||
|
||||
dev = pt->dev;
|
||||
for_each_netdev_continue_rcu(seq_file_net(seq), dev) {
|
||||
if (!list_empty(&dev->ptype_all)) {
|
||||
nxt = dev->ptype_all.next;
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
|
||||
nxt = ptype_all.next;
|
||||
goto ptype_all;
|
||||
}
|
||||
|
||||
if (pt->type == htons(ETH_P_ALL)) {
|
||||
ptype_all:
|
||||
if (nxt != &ptype_all)
|
||||
goto found;
|
||||
hash = 0;
|
||||
|
|
Loading…
Reference in New Issue