Skip to content

Commit

Permalink
net-procfs: show net devices bound packet types
Browse files Browse the repository at this point in the history
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: 7866a62 ("dev: add per net_device packet type chains")
Signed-off-by: Jianguo Wu <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
Jianguo Wu authored and davem330 committed Jan 24, 2022
1 parent aa60346 commit 1d10f8a
Showing 1 changed file with 32 additions and 3 deletions.
35 changes: 32 additions & 3 deletions net/core/net-procfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down

0 comments on commit 1d10f8a

Please sign in to comment.