• Simon Horman's avatar
    rocker: do not delete fdb entries in rocker_port_fdb_flush() when preparing transactions · 3098ac39
    Simon Horman authored
    rocker_port_fdb_flush() is called by rocker_port_stp_update() which in
    turn may be called with trans == SWITCHDEV_TRANS_PREPARE and then
    trans == SWITCHDEV_TRANS_COMMIT from switchdev_port_attr_set() via
    br_set_state().
    
    When rocker_port_fdb_flush() is called with trans == SWITCHDEV_TRANS_PREPARE
    it calls rocker_port_fdb_learn() for each entry in the FDB table which in
    turn calls rocker_flow_tbl_bridge() which will allocate memory using
    rocker_port_kzalloc(). rocker_port_fdb_learn() will then remove the entry
    from the FDB table.
    
    Then when rocker_port_fdb_learn() is called with
    trans == SWITCHDEV_TRANS_PREPARE no calls are made to rocker_port_fdb_learn()
    because there are no longer any entries present in the FDB table. Thus the
    memory previously allocated by rocker_port_fdb_learn() is leaked resulting
    in the kernel BUG() below.
    
    Furthermore, it looks like the driver ends up with an incorrect view of the
    fdb table as the FDB entries are purged from the driver's table but not the
    hardware's table.
    
    ip link add br0 type bridge
    ip link set up dev eth0
    sleep 1
    ip link set dev eth0 master br0
    [    3.704360] ------------[ cut here ]------------
    [    3.704611] kernel BUG at drivers/net/ethernet/rocker/rocker.c:4289!
    [    3.704962] invalid opcode: 0000 [#1] SMP
    [    3.705537] Modules linked in:
    [    3.705919] CPU: 0 PID: 63 Comm: ip Not tainted 4.1.0-rc3-01046-gb9fbe709 #1044
    [    3.706191] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.8.0-0-g4c59f5d-20150219_092859-nilsson.home.kraxel.org 04/01/2014
    [    3.706820] task: ffff880019f70150 ti: ffff88001f92c000 task.ti: ffff88001f92c000
    [    3.707138] RIP: 0010:[<ffffffff811f0080>]  [<ffffffff811f0080>] rocker_port_attr_set+0xe0/0xf0
    [    3.707990] RSP: 0018:ffff88001f92f808  EFLAGS: 00000212
    [    3.708200] RAX: ffff880019d4fa68 RBX: ffff880019d4f000 RCX: 0000000000000000
    [    3.708471] RDX: 000000000000000c RSI: ffff88001f92f890 RDI: ffff880019d4f680
    [    3.708740] RBP: 0000000000000001 R08: 0000000000000000 R09: 0000000000000004
    [    3.708999] R10: ffff880000034024 R11: 0000000000000000 R12: ffff88001f92f890
    [    3.709276] R13: ffff88001f8f1c00 R14: 000000000000000b R15: 0000000000000000
    [    3.709303] FS:  00007f8ab66bd700(0000) GS:ffff88001b000000(0000) knlGS:0000000000000000
    [    3.709303] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    [    3.709303] CR2: 0000000000654988 CR3: 000000001f8f3000 CR4: 00000000000006b0
    [    3.709303] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
    [    3.709303] DR3: 0000000000000000 DR6: 0000000000000000 DR7: 0000000000000000
    [    3.709303] Stack:
    [    3.709303]  ffff88001f8f1c00 000000000000000b ffff88001f92f890 ffff880019d4f000
    [    3.709303]  ffff88001f92f890 ffffffff813332f5 ffff88001f92f880 0000000000000000
    [    3.709303]  ffff88001f92f890 0000000000000001 ffff880019d4f000 ffffffff81333627
    [    3.709303] Call Trace:
    [    3.709303]  [<ffffffff813332f5>] ? __switchdev_port_attr_set+0x25/0x90
    [    3.709303]  [<ffffffff81333627>] ? switchdev_port_attr_set+0x27/0x120
    [    3.709303]  [<ffffffff81318e86>] ? br_set_state+0x36/0x50
    [    3.709303]  [<ffffffff8131795c>] ? br_add_if+0x37c/0x400
    [    3.709303]  [<ffffffff81238ce1>] ? do_setlink+0x7e1/0x800
    [    3.709303]  [<ffffffff8111f980>] ? radix_tree_lookup_slot+0x10/0x30
    [    3.709303]  [<ffffffff81136fba>] ? nla_parse+0xaa/0x110
    [    3.709303]  [<ffffffff81239c98>] ? rtnl_newlink+0x548/0x870
    [    3.709303]  [<ffffffff8111f900>] ? __radix_tree_lookup+0x40/0xb0
    [    3.709303]  [<ffffffff81136f3e>] ? nla_parse+0x2e/0x110
    [    3.709303]  [<ffffffff81237d7e>] ? rtnetlink_rcv_msg+0x7e/0x250
    [    3.709303]  [<ffffffff8121d1be>] ? __skb_recv_datagram+0xfe/0x4b0
    [    3.709303]  [<ffffffff81237d00>] ? rtnetlink_rcv+0x30/0x30
    [    3.709303]  [<ffffffff81247948>] ? netlink_rcv_skb+0xa8/0xd0
    [    3.709303]  [<ffffffff81237cef>] ? rtnetlink_rcv+0x1f/0x30
    [    3.709303]  [<ffffffff81247210>] ? netlink_unicast+0x150/0x200
    [    3.709303]  [<ffffffff81247704>] ? netlink_sendmsg+0x374/0x3e0
    [    3.709303]  [<ffffffff8120f8cf>] ? sock_sendmsg+0xf/0x30
    [    3.709303]  [<ffffffff8120ffc3>] ? ___sys_sendmsg+0x1f3/0x200
    [    3.709303]  [<ffffffff812100d5>] ? ___sys_recvmsg+0x105/0x140
    [    3.709303]  [<ffffffff812228d9>] ? dev_get_by_name_rcu+0x69/0x90
    [    3.709303]  [<ffffffff812228d9>] ? dev_get_by_name_rcu+0x69/0x90
    [    3.709303]  [<ffffffff81217b7d>] ? skb_dequeue+0x4d/0x60
    [    3.709303]  [<ffffffff81217bb0>] ? skb_queue_purge+0x20/0x30
    [    3.709303]  [<ffffffff810ebdcf>] ? __inode_wait_for_writeback+0x5f/0xb0
    [    3.709303]  [<ffffffff810648b0>] ? autoremove_wake_function+0x30/0x30
    [    3.709303]  [<ffffffff81210ee9>] ? __sys_sendmsg+0x39/0x70
    [    3.709303]  [<ffffffff8133e097>] ? system_call_fastpath+0x12/0x6a
    [    3.709303] Code: bb 90 06 00 00 48 c7 04 24 00 00 00 00 45 31 c9 45 31 c0 48 c7 c1 c0 b7 1e 81 89 ea e8 da da ff ff eb 95 0f 1f 84 00 00 00 00 00 <0f> 0b 66 66 66 66 66 2e 0f 1f 84 00 00 00 00 00 48 83 fe 15 75
    [    3.709303] RIP  [<ffffffff811f0080>] rocker_port_attr_set+0xe0/0xf0
    [    3.709303]  RSP <ffff88001f92f808>
    [    3.721409] ---[ end trace b7481fcb7cb032aa ]---
    Segmentation fault
    
    Fixes: c4f20321 ("rocker: support prepare-commit transaction model")
    Acked-by: default avatarScott Feldman <sfeldma@gmail.com>
    Acked-by: default avatarJiri Pirko <jiri@resnulli.us>
    Signed-off-by: default avatarSimon Horman <simon.horman@netronome.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    3098ac39
rocker.c 141 KB