net-procfs: show net devices bound packet types
commit1d10f8a1f4
upstream. 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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Родитель
d7396948cf
Коммит
d70d2aa49a
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче