lkml.org 
[lkml]   [2022]   [Jan]   [31]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.15 095/171] net-procfs: show net devices bound packet types
    Date
    From: Jianguo Wu <wujianguo@chinatelecom.cn>

    commit 1d10f8a1f40b965d449e8f2d5ed7b96a7c138b77 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: 7866a621043f ("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>
    ---
    net/core/net-procfs.c | 35 ++++++++++++++++++++++++++++++++---
    1 file changed, 32 insertions(+), 3 deletions(-)

    --- a/net/core/net-procfs.c
    +++ b/net/core/net-procfs.c
    @@ -190,12 +190,23 @@ static const struct seq_operations softn
    .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_
    __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;

    \
     
     \ /
      Last update: 2022-01-31 12:40    [W:4.325 / U:1.068 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site