1. 09 12月, 2020 1 次提交
    • T
      xdp: Remove the xdp_attachment_flags_ok() callback · 998f1729
      Toke Høiland-Jørgensen 提交于
      Since commit 7f0a8382 ("bpf, xdp: Maintain info on attached XDP BPF
      programs in net_device"), the XDP program attachment info is now maintained
      in the core code. This interacts badly with the xdp_attachment_flags_ok()
      check that prevents unloading an XDP program with different load flags than
      it was loaded with. In practice, two kinds of failures are seen:
      
      - An XDP program loaded without specifying a mode (and which then ends up
        in driver mode) cannot be unloaded if the program mode is specified on
        unload.
      
      - The dev_xdp_uninstall() hook always calls the driver callback with the
        mode set to the type of the program but an empty flags argument, which
        means the flags_ok() check prevents the program from being removed,
        leading to bpf prog reference leaks.
      
      The original reason this check was added was to avoid ambiguity when
      multiple programs were loaded. With the way the checks are done in the core
      now, this is quite simple to enforce in the core code, so let's add a check
      there and get rid of the xdp_attachment_flags_ok() callback entirely.
      
      Fixes: 7f0a8382 ("bpf, xdp: Maintain info on attached XDP BPF programs in net_device")
      Signed-off-by: NToke Høiland-Jørgensen <toke@redhat.com>
      Signed-off-by: NDaniel Borkmann <daniel@iogearbox.net>
      Acked-by: NJakub Kicinski <kuba@kernel.org>
      Link: https://lore.kernel.org/bpf/160752225751.110217.10267659521308669050.stgit@toke.dk
      998f1729
  2. 25 11月, 2020 1 次提交
  3. 25 10月, 2020 1 次提交
    • W
      random32: add noise from network and scheduling activity · 3744741a
      Willy Tarreau 提交于
      With the removal of the interrupt perturbations in previous random32
      change (random32: make prandom_u32() output unpredictable), the PRNG
      has become 100% deterministic again. While SipHash is expected to be
      way more robust against brute force than the previous Tausworthe LFSR,
      there's still the risk that whoever has even one temporary access to
      the PRNG's internal state is able to predict all subsequent draws till
      the next reseed (roughly every minute). This may happen through a side
      channel attack or any data leak.
      
      This patch restores the spirit of commit f227e3ec ("random32: update
      the net random state on interrupt and activity") in that it will perturb
      the internal PRNG's statee using externally collected noise, except that
      it will not pick that noise from the random pool's bits nor upon
      interrupt, but will rather combine a few elements along the Tx path
      that are collectively hard to predict, such as dev, skb and txq
      pointers, packet length and jiffies values. These ones are combined
      using a single round of SipHash into a single long variable that is
      mixed with the net_rand_state upon each invocation.
      
      The operation was inlined because it produces very small and efficient
      code, typically 3 xor, 2 add and 2 rol. The performance was measured
      to be the same (even very slightly better) than before the switch to
      SipHash; on a 6-core 12-thread Core i7-8700k equipped with a 40G NIC
      (i40e), the connection rate dropped from 556k/s to 555k/s while the
      SYN cookie rate grew from 5.38 Mpps to 5.45 Mpps.
      
      Link: https://lore.kernel.org/netdev/20200808152628.GA27941@SDF.ORG/
      Cc: George Spelvin <lkml@sdf.org>
      Cc: Amit Klein <aksecurity@gmail.com>
      Cc: Eric Dumazet <edumazet@google.com>
      Cc: "Jason A. Donenfeld" <Jason@zx2c4.com>
      Cc: Andy Lutomirski <luto@kernel.org>
      Cc: Kees Cook <keescook@chromium.org>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Cc: Peter Zijlstra <peterz@infradead.org>
      Cc: Linus Torvalds <torvalds@linux-foundation.org>
      Cc: tytso@mit.edu
      Cc: Florian Westphal <fw@strlen.de>
      Cc: Marc Plumb <lkml.mplumb@gmail.com>
      Tested-by: NSedat Dilek <sedat.dilek@gmail.com>
      Signed-off-by: NWilly Tarreau <w@1wt.eu>
      3744741a
  4. 19 10月, 2020 1 次提交
    • T
      net: core: use list_del_init() instead of list_del() in netdev_run_todo() · 0e8b8d6a
      Taehee Yoo 提交于
      dev->unlink_list is reused unless dev is deleted.
      So, list_del() should not be used.
      Due to using list_del(), dev->unlink_list can't be reused so that
      dev->nested_level update logic doesn't work.
      In order to fix this bug, list_del_init() should be used instead
      of list_del().
      
      Test commands:
          ip link add bond0 type bond
          ip link add bond1 type bond
          ip link set bond0 master bond1
          ip link set bond0 nomaster
          ip link set bond1 master bond0
          ip link set bond1 nomaster
      
      Splat looks like:
      [  255.750458][ T1030] ============================================
      [  255.751967][ T1030] WARNING: possible recursive locking detected
      [  255.753435][ T1030] 5.9.0-rc8+ #772 Not tainted
      [  255.754553][ T1030] --------------------------------------------
      [  255.756047][ T1030] ip/1030 is trying to acquire lock:
      [  255.757304][ T1030] ffff88811782a280 (&dev_addr_list_lock_key/1){+...}-{2:2}, at: dev_mc_sync_multiple+0xc2/0x150
      [  255.760056][ T1030]
      [  255.760056][ T1030] but task is already holding lock:
      [  255.761862][ T1030] ffff88811130a280 (&dev_addr_list_lock_key/1){+...}-{2:2}, at: bond_enslave+0x3d4d/0x43e0 [bonding]
      [  255.764581][ T1030]
      [  255.764581][ T1030] other info that might help us debug this:
      [  255.766645][ T1030]  Possible unsafe locking scenario:
      [  255.766645][ T1030]
      [  255.768566][ T1030]        CPU0
      [  255.769415][ T1030]        ----
      [  255.770259][ T1030]   lock(&dev_addr_list_lock_key/1);
      [  255.771629][ T1030]   lock(&dev_addr_list_lock_key/1);
      [  255.772994][ T1030]
      [  255.772994][ T1030]  *** DEADLOCK ***
      [  255.772994][ T1030]
      [  255.775091][ T1030]  May be due to missing lock nesting notation
      [  255.775091][ T1030]
      [  255.777182][ T1030] 2 locks held by ip/1030:
      [  255.778299][ T1030]  #0: ffffffffb1f63250 (rtnl_mutex){+.+.}-{3:3}, at: rtnetlink_rcv_msg+0x2e4/0x8b0
      [  255.780600][ T1030]  #1: ffff88811130a280 (&dev_addr_list_lock_key/1){+...}-{2:2}, at: bond_enslave+0x3d4d/0x43e0 [bonding]
      [  255.783411][ T1030]
      [  255.783411][ T1030] stack backtrace:
      [  255.784874][ T1030] CPU: 7 PID: 1030 Comm: ip Not tainted 5.9.0-rc8+ #772
      [  255.786595][ T1030] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1ubuntu1 04/01/2014
      [  255.789030][ T1030] Call Trace:
      [  255.789850][ T1030]  dump_stack+0x99/0xd0
      [  255.790882][ T1030]  __lock_acquire.cold.71+0x166/0x3cc
      [  255.792285][ T1030]  ? register_lock_class+0x1a30/0x1a30
      [  255.793619][ T1030]  ? rcu_read_lock_sched_held+0x91/0xc0
      [  255.794963][ T1030]  ? rcu_read_lock_bh_held+0xa0/0xa0
      [  255.796246][ T1030]  lock_acquire+0x1b8/0x850
      [  255.797332][ T1030]  ? dev_mc_sync_multiple+0xc2/0x150
      [  255.798624][ T1030]  ? bond_enslave+0x3d4d/0x43e0 [bonding]
      [  255.800039][ T1030]  ? check_flags+0x50/0x50
      [  255.801143][ T1030]  ? lock_contended+0xd80/0xd80
      [  255.802341][ T1030]  _raw_spin_lock_nested+0x2e/0x70
      [  255.803592][ T1030]  ? dev_mc_sync_multiple+0xc2/0x150
      [  255.804897][ T1030]  dev_mc_sync_multiple+0xc2/0x150
      [  255.806168][ T1030]  bond_enslave+0x3d58/0x43e0 [bonding]
      [  255.807542][ T1030]  ? __lock_acquire+0xe53/0x51b0
      [  255.808824][ T1030]  ? bond_update_slave_arr+0xdc0/0xdc0 [bonding]
      [  255.810451][ T1030]  ? check_chain_key+0x236/0x5e0
      [  255.811742][ T1030]  ? mutex_is_locked+0x13/0x50
      [  255.812910][ T1030]  ? rtnl_is_locked+0x11/0x20
      [  255.814061][ T1030]  ? netdev_master_upper_dev_get+0xf/0x120
      [  255.815553][ T1030]  do_setlink+0x94c/0x3040
      [ ... ]
      
      Reported-by: syzbot+4a0f7bc34e3997a6c7df@syzkaller.appspotmail.com
      Fixes: 1fc70edb ("net: core: add nested_level variable in net_device")
      Signed-off-by: NTaehee Yoo <ap420073@gmail.com>
      Link: https://lore.kernel.org/r/20201015162606.9377-1-ap420073@gmail.comSigned-off-by: NJakub Kicinski <kuba@kernel.org>
      0e8b8d6a
  5. 14 10月, 2020 1 次提交
  6. 12 10月, 2020 1 次提交
    • D
      bpf: Add redirect_peer helper · 9aa1206e
      Daniel Borkmann 提交于
      Add an efficient ingress to ingress netns switch that can be used out of tc BPF
      programs in order to redirect traffic from host ns ingress into a container
      veth device ingress without having to go via CPU backlog queue [0]. For local
      containers this can also be utilized and path via CPU backlog queue only needs
      to be taken once, not twice. On a high level this borrows from ipvlan which does
      similar switch in __netif_receive_skb_core() and then iterates via another_round.
      This helps to reduce latency for mentioned use cases.
      
      Pod to remote pod with redirect(), TCP_RR [1]:
      
        # percpu_netperf 10.217.1.33
                RT_LATENCY:         122.450         (per CPU:         122.666         122.401         122.333         122.401 )
              MEAN_LATENCY:         121.210         (per CPU:         121.100         121.260         121.320         121.160 )
            STDDEV_LATENCY:         120.040         (per CPU:         119.420         119.910         125.460         115.370 )
               MIN_LATENCY:          46.500         (per CPU:          47.000          47.000          47.000          45.000 )
               P50_LATENCY:         118.500         (per CPU:         118.000         119.000         118.000         119.000 )
               P90_LATENCY:         127.500         (per CPU:         127.000         128.000         127.000         128.000 )
               P99_LATENCY:         130.750         (per CPU:         131.000         131.000         129.000         132.000 )
      
          TRANSACTION_RATE:       32666.400         (per CPU:        8152.200        8169.842        8174.439        8169.897 )
      
      Pod to remote pod with redirect_peer(), TCP_RR:
      
        # percpu_netperf 10.217.1.33
                RT_LATENCY:          44.449         (per CPU:          43.767          43.127          45.279          45.622 )
              MEAN_LATENCY:          45.065         (per CPU:          44.030          45.530          45.190          45.510 )
            STDDEV_LATENCY:          84.823         (per CPU:          66.770          97.290          84.380          90.850 )
               MIN_LATENCY:          33.500         (per CPU:          33.000          33.000          34.000          34.000 )
               P50_LATENCY:          43.250         (per CPU:          43.000          43.000          43.000          44.000 )
               P90_LATENCY:          46.750         (per CPU:          46.000          47.000          47.000          47.000 )
               P99_LATENCY:          52.750         (per CPU:          51.000          54.000          53.000          53.000 )
      
          TRANSACTION_RATE:       90039.500         (per CPU:       22848.186       23187.089       22085.077       21919.130 )
      
        [0] https://linuxplumbersconf.org/event/7/contributions/674/attachments/568/1002/plumbers_2020_cilium_load_balancer.pdf
        [1] https://github.com/borkmann/netperf_scripts/blob/master/percpu_netperfSigned-off-by: NDaniel Borkmann <daniel@iogearbox.net>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/bpf/20201010234006.7075-3-daniel@iogearbox.net
      9aa1206e
  7. 30 9月, 2020 1 次提交
    • S
      net: Add netif_rx_any_context() · c11171a4
      Sebastian Andrzej Siewior 提交于
      Quite some drivers make conditional decisions based on in_interrupt() to
      invoke either netif_rx() or netif_rx_ni().
      
      Conditionals based on in_interrupt() or other variants of preempt count
      checks in drivers should not exist for various reasons and Linus clearly
      requested to either split the code pathes or pass an argument to the
      common functions which provides the context.
      
      This is obviously the correct solution, but for some of the affected
      drivers this needs a major rewrite due to their convoluted structure.
      
      As in_interrupt() usage in drivers needs to be phased out, provide
      netif_rx_any_context() as a stop gap for these drivers.
      
      This confines the in_interrupt() conditional to core code which in turn
      allows to remove the access to this check for driver code and provides one
      central place to do further modifications once the driver maze is cleaned
      up.
      Suggested-by: NThomas Gleixner <tglx@linutronix.de>
      Signed-off-by: NSebastian Andrzej Siewior <bigeasy@linutronix.de>
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      c11171a4
  8. 29 9月, 2020 3 次提交
    • T
      net: core: add nested_level variable in net_device · 1fc70edb
      Taehee Yoo 提交于
      This patch is to add a new variable 'nested_level' into the net_device
      structure.
      This variable will be used as a parameter of spin_lock_nested() of
      dev->addr_list_lock.
      
      netif_addr_lock() can be called recursively so spin_lock_nested() is
      used instead of spin_lock() and dev->lower_level is used as a parameter
      of spin_lock_nested().
      But, dev->lower_level value can be updated while it is being used.
      So, lockdep would warn a possible deadlock scenario.
      
      When a stacked interface is deleted, netif_{uc | mc}_sync() is
      called recursively.
      So, spin_lock_nested() is called recursively too.
      At this moment, the dev->lower_level variable is used as a parameter of it.
      dev->lower_level value is updated when interfaces are being unlinked/linked
      immediately.
      Thus, After unlinking, dev->lower_level shouldn't be a parameter of
      spin_lock_nested().
      
          A (macvlan)
          |
          B (vlan)
          |
          C (bridge)
          |
          D (macvlan)
          |
          E (vlan)
          |
          F (bridge)
      
          A->lower_level : 6
          B->lower_level : 5
          C->lower_level : 4
          D->lower_level : 3
          E->lower_level : 2
          F->lower_level : 1
      
      When an interface 'A' is removed, it releases resources.
      At this moment, netif_addr_lock() would be called.
      Then, netdev_upper_dev_unlink() is called recursively.
      Then dev->lower_level is updated.
      There is no problem.
      
      But, when the bridge module is removed, 'C' and 'F' interfaces
      are removed at once.
      If 'F' is removed first, a lower_level value is like below.
          A->lower_level : 5
          B->lower_level : 4
          C->lower_level : 3
          D->lower_level : 2
          E->lower_level : 1
          F->lower_level : 1
      
      Then, 'C' is removed. at this moment, netif_addr_lock() is called
      recursively.
      The ordering is like this.
      C(3)->D(2)->E(1)->F(1)
      At this moment, the lower_level value of 'E' and 'F' are the same.
      So, lockdep warns a possible deadlock scenario.
      
      In order to avoid this problem, a new variable 'nested_level' is added.
      This value is the same as dev->lower_level - 1.
      But this value is updated in rtnl_unlock().
      So, this variable can be used as a parameter of spin_lock_nested() safely
      in the rtnl context.
      
      Test commands:
         ip link add br0 type bridge vlan_filtering 1
         ip link add vlan1 link br0 type vlan id 10
         ip link add macvlan2 link vlan1 type macvlan
         ip link add br3 type bridge vlan_filtering 1
         ip link set macvlan2 master br3
         ip link add vlan4 link br3 type vlan id 10
         ip link add macvlan5 link vlan4 type macvlan
         ip link add br6 type bridge vlan_filtering 1
         ip link set macvlan5 master br6
         ip link add vlan7 link br6 type vlan id 10
         ip link add macvlan8 link vlan7 type macvlan
      
         ip link set br0 up
         ip link set vlan1 up
         ip link set macvlan2 up
         ip link set br3 up
         ip link set vlan4 up
         ip link set macvlan5 up
         ip link set br6 up
         ip link set vlan7 up
         ip link set macvlan8 up
         modprobe -rv bridge
      
      Splat looks like:
      [   36.057436][  T744] WARNING: possible recursive locking detected
      [   36.058848][  T744] 5.9.0-rc6+ #728 Not tainted
      [   36.059959][  T744] --------------------------------------------
      [   36.061391][  T744] ip/744 is trying to acquire lock:
      [   36.062590][  T744] ffff8c4767509280 (&vlan_netdev_addr_lock_key){+...}-{2:2}, at: dev_set_rx_mode+0x19/0x30
      [   36.064922][  T744]
      [   36.064922][  T744] but task is already holding lock:
      [   36.066626][  T744] ffff8c4767769280 (&vlan_netdev_addr_lock_key){+...}-{2:2}, at: dev_uc_add+0x1e/0x60
      [   36.068851][  T744]
      [   36.068851][  T744] other info that might help us debug this:
      [   36.070731][  T744]  Possible unsafe locking scenario:
      [   36.070731][  T744]
      [   36.072497][  T744]        CPU0
      [   36.073238][  T744]        ----
      [   36.074007][  T744]   lock(&vlan_netdev_addr_lock_key);
      [   36.075290][  T744]   lock(&vlan_netdev_addr_lock_key);
      [   36.076590][  T744]
      [   36.076590][  T744]  *** DEADLOCK ***
      [   36.076590][  T744]
      [   36.078515][  T744]  May be due to missing lock nesting notation
      [   36.078515][  T744]
      [   36.080491][  T744] 3 locks held by ip/744:
      [   36.081471][  T744]  #0: ffffffff98571df0 (rtnl_mutex){+.+.}-{3:3}, at: rtnetlink_rcv_msg+0x236/0x490
      [   36.083614][  T744]  #1: ffff8c4767769280 (&vlan_netdev_addr_lock_key){+...}-{2:2}, at: dev_uc_add+0x1e/0x60
      [   36.085942][  T744]  #2: ffff8c476c8da280 (&bridge_netdev_addr_lock_key/4){+...}-{2:2}, at: dev_uc_sync+0x39/0x80
      [   36.088400][  T744]
      [   36.088400][  T744] stack backtrace:
      [   36.089772][  T744] CPU: 6 PID: 744 Comm: ip Not tainted 5.9.0-rc6+ #728
      [   36.091364][  T744] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1ubuntu1 04/01/2014
      [   36.093630][  T744] Call Trace:
      [   36.094416][  T744]  dump_stack+0x77/0x9b
      [   36.095385][  T744]  __lock_acquire+0xbc3/0x1f40
      [   36.096522][  T744]  lock_acquire+0xb4/0x3b0
      [   36.097540][  T744]  ? dev_set_rx_mode+0x19/0x30
      [   36.098657][  T744]  ? rtmsg_ifinfo+0x1f/0x30
      [   36.099711][  T744]  ? __dev_notify_flags+0xa5/0xf0
      [   36.100874][  T744]  ? rtnl_is_locked+0x11/0x20
      [   36.101967][  T744]  ? __dev_set_promiscuity+0x7b/0x1a0
      [   36.103230][  T744]  _raw_spin_lock_bh+0x38/0x70
      [   36.104348][  T744]  ? dev_set_rx_mode+0x19/0x30
      [   36.105461][  T744]  dev_set_rx_mode+0x19/0x30
      [   36.106532][  T744]  dev_set_promiscuity+0x36/0x50
      [   36.107692][  T744]  __dev_set_promiscuity+0x123/0x1a0
      [   36.108929][  T744]  dev_set_promiscuity+0x1e/0x50
      [   36.110093][  T744]  br_port_set_promisc+0x1f/0x40 [bridge]
      [   36.111415][  T744]  br_manage_promisc+0x8b/0xe0 [bridge]
      [   36.112728][  T744]  __dev_set_promiscuity+0x123/0x1a0
      [   36.113967][  T744]  ? __hw_addr_sync_one+0x23/0x50
      [   36.115135][  T744]  __dev_set_rx_mode+0x68/0x90
      [   36.116249][  T744]  dev_uc_sync+0x70/0x80
      [   36.117244][  T744]  dev_uc_add+0x50/0x60
      [   36.118223][  T744]  macvlan_open+0x18e/0x1f0 [macvlan]
      [   36.119470][  T744]  __dev_open+0xd6/0x170
      [   36.120470][  T744]  __dev_change_flags+0x181/0x1d0
      [   36.121644][  T744]  dev_change_flags+0x23/0x60
      [   36.122741][  T744]  do_setlink+0x30a/0x11e0
      [   36.123778][  T744]  ? __lock_acquire+0x92c/0x1f40
      [   36.124929][  T744]  ? __nla_validate_parse.part.6+0x45/0x8e0
      [   36.126309][  T744]  ? __lock_acquire+0x92c/0x1f40
      [   36.127457][  T744]  __rtnl_newlink+0x546/0x8e0
      [   36.128560][  T744]  ? lock_acquire+0xb4/0x3b0
      [   36.129623][  T744]  ? deactivate_slab.isra.85+0x6a1/0x850
      [   36.130946][  T744]  ? __lock_acquire+0x92c/0x1f40
      [   36.132102][  T744]  ? lock_acquire+0xb4/0x3b0
      [   36.133176][  T744]  ? is_bpf_text_address+0x5/0xe0
      [   36.134364][  T744]  ? rtnl_newlink+0x2e/0x70
      [   36.135445][  T744]  ? rcu_read_lock_sched_held+0x32/0x60
      [   36.136771][  T744]  ? kmem_cache_alloc_trace+0x2d8/0x380
      [   36.138070][  T744]  ? rtnl_newlink+0x2e/0x70
      [   36.139164][  T744]  rtnl_newlink+0x47/0x70
      [ ... ]
      
      Fixes: 845e0ebb ("net: change addr_list_lock back to static key")
      Signed-off-by: NTaehee Yoo <ap420073@gmail.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      1fc70edb
    • T
      net: core: introduce struct netdev_nested_priv for nested interface infrastructure · eff74233
      Taehee Yoo 提交于
      Functions related to nested interface infrastructure such as
      netdev_walk_all_{ upper | lower }_dev() pass both private functions
      and "data" pointer to handle their own things.
      At this point, the data pointer type is void *.
      In order to make it easier to expand common variables and functions,
      this new netdev_nested_priv structure is added.
      
      In the following patch, a new member variable will be added into this
      struct to fix the lockdep issue.
      Signed-off-by: NTaehee Yoo <ap420073@gmail.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      eff74233
    • T
      net: core: add __netdev_upper_dev_unlink() · fe8300fd
      Taehee Yoo 提交于
      The netdev_upper_dev_unlink() has to work differently according to flags.
      This idea is the same with __netdev_upper_dev_link().
      
      In the following patches, new flags will be added.
      Signed-off-by: NTaehee Yoo <ap420073@gmail.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      fe8300fd
  9. 24 9月, 2020 1 次提交
  10. 19 9月, 2020 2 次提交
    • R
      net: core: delete duplicated words · 4250b75b
      Randy Dunlap 提交于
      Drop repeated words in net/core/.
      Signed-off-by: NRandy Dunlap <rdunlap@infradead.org>
      Cc: "David S. Miller" <davem@davemloft.net>
      Cc: Jakub Kicinski <kuba@kernel.org>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      4250b75b
    • F
      net: use exponential backoff in netdev_wait_allrefs · 0e4be9e5
      Francesco Ruggeri 提交于
      The combination of aca_free_rcu, introduced in commit 2384d025
      ("net/ipv6: Add anycast addresses to a global hashtable"), and
      fib6_info_destroy_rcu, introduced in commit 9b0a8da8 ("net/ipv6:
      respect rcu grace period before freeing fib6_info"), can result in
      an extra rcu grace period being needed when deleting an interface,
      with the result that netdev_wait_allrefs ends up hitting the msleep(250),
      which is considerably longer than the required grace period.
      This can result in long delays when deleting a large number of interfaces,
      and it can be observed with this script:
      
      ns=dummy-ns
      NIFS=100
      
      ip netns add $ns
      ip netns exec $ns ip link set lo up
      ip netns exec $ns sysctl net.ipv6.conf.default.disable_ipv6=0
      ip netns exec $ns sysctl net.ipv6.conf.default.forwarding=1
      
      for ((i=0; i<$NIFS; i++))
      do
              if=eth$i
              ip netns exec $ns ip link add $if type dummy
              ip netns exec $ns ip link set $if up
              ip netns exec $ns ip -6 addr add 2021:$i::1/120 dev $if
      done
      
      for ((i=0; i<$NIFS; i++))
      do
              if=eth$i
              ip netns exec $ns ip link del $if
      done
      
      ip netns del $ns
      
      Instead of using a fixed msleep(250), this patch tries an extra
      rcu_barrier() followed by an exponential backoff.
      
      Time with this patch on a 5.4 kernel:
      
      real	0m7.704s
      user	0m0.385s
      sys	0m1.230s
      
      Time without this patch:
      
      real    0m31.522s
      user    0m0.438s
      sys     0m1.156s
      
      v2: use exponential backoff instead of trying to wake up
          netdev_wait_allrefs.
      v3: preserve reverse christmas tree ordering of local variables
      v4: try an extra rcu_barrier before the backoff, plus some
          cosmetic changes.
      Signed-off-by: NFrancesco Ruggeri <fruggeri@arista.com>
      Reviewed-by: NEric Dumazet <edumazet@google.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      0e4be9e5
  11. 16 9月, 2020 1 次提交
  12. 15 9月, 2020 2 次提交
    • V
      __netif_receive_skb_core: don't untag vlan from skb on DSA master · b14a9fc4
      Vladimir Oltean 提交于
      A DSA master interface has upper network devices, each representing an
      Ethernet switch port attached to it. Demultiplexing the source ports and
      setting skb->dev accordingly is done through the catch-all ETH_P_XDSA
      packet_type handler. Catch-all because DSA vendors have various header
      implementations, which can be placed anywhere in the frame: before the
      DMAC, before the EtherType, before the FCS, etc. So, the ETH_P_XDSA
      handler acts like an rx_handler more than anything.
      
      It is unlikely for the DSA master interface to have any other upper than
      the DSA switch interfaces themselves. Only maybe a bridge upper*, but it
      is very likely that the DSA master will have no 8021q upper. So
      __netif_receive_skb_core() will try to untag the VLAN, despite the fact
      that the DSA switch interface might have an 8021q upper. So the skb will
      never reach that.
      
      So far, this hasn't been a problem because most of the possible
      placements of the DSA switch header mentioned in the first paragraph
      will displace the VLAN header when the DSA master receives the frame, so
      __netif_receive_skb_core() will not actually execute any VLAN-specific
      code for it. This only becomes a problem when the DSA switch header does
      not displace the VLAN header (for example with a tail tag).
      
      What the patch does is it bypasses the untagging of the skb when there
      is a DSA switch attached to this net device. So, DSA is the only
      packet_type handler which requires seeing the VLAN header. Once skb->dev
      will be changed, __netif_receive_skb_core() will be invoked again and
      untagging, or delivery to an 8021q upper, will happen in the RX of the
      DSA switch interface itself.
      
      *see commit 9eb8eff0 ("net: bridge: allow enslaving some DSA master
      network devices". This is actually the reason why I prefer keeping DSA
      as a packet_type handler of ETH_P_XDSA rather than converting to an
      rx_handler. Currently the rx_handler code doesn't support chaining, and
      this is a problem because a DSA master might be bridged.
      Signed-off-by: NVladimir Oltean <olteanv@gmail.com>
      Reviewed-by: NFlorian Fainelli <f.fainelli@gmail.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      b14a9fc4
    • P
      net: try to avoid unneeded backlog flush · 2de79ee2
      Paolo Abeni 提交于
      flush_all_backlogs() may cause deadlock on systems
      running processes with FIFO scheduling policy.
      
      The above is critical in -RT scenarios, where user-space
      specifically ensure no network activity is scheduled on
      the CPU running the mentioned FIFO process, but still get
      stuck.
      
      This commit tries to address the problem checking the
      backlog status on the remote CPUs before scheduling the
      flush operation. If the backlog is empty, we can skip it.
      
      v1 -> v2:
       - explicitly clear flushed cpu mask - Eric
      Signed-off-by: NPaolo Abeni <pabeni@redhat.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      2de79ee2
  13. 11 9月, 2020 4 次提交
    • I
      net: Fix bridge enslavement failure · e1b9efe6
      Ido Schimmel 提交于
      When a netdev is enslaved to a bridge, its parent identifier is queried.
      This is done so that packets that were already forwarded in hardware
      will not be forwarded again by the bridge device between netdevs
      belonging to the same hardware instance.
      
      The operation fails when the netdev is an upper of netdevs with
      different parent identifiers.
      
      Instead of failing the enslavement, have dev_get_port_parent_id() return
      '-EOPNOTSUPP' which will signal the bridge to skip the query operation.
      Other callers of the function are not affected by this change.
      
      Fixes: 7e1146e8 ("net: devlink: introduce devlink_compat_switch_id_get() helper")
      Signed-off-by: NIdo Schimmel <idosch@nvidia.com>
      Reported-by: NVasundhara Volam <vasundhara-v.volam@broadcom.com>
      Reviewed-by: NJiri Pirko <jiri@nvidia.com>
      Reviewed-by: NNikolay Aleksandrov <nikolay@nvidia.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      e1b9efe6
    • J
      net: make sure napi_list is safe for RCU traversal · 5251ef82
      Jakub Kicinski 提交于
      netpoll needs to traverse dev->napi_list under RCU, make
      sure it uses the right iterator and that removal from this
      list is handled safely.
      Signed-off-by: NJakub Kicinski <kuba@kernel.org>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      5251ef82
    • J
      net: manage napi add/del idempotence explicitly · 4d092dd2
      Jakub Kicinski 提交于
      To RCUify napi->dev_list we need to replace list_del_init()
      with list_del_rcu(). There is no _init() version for RCU for
      obvious reasons. Up until now netif_napi_del() was idempotent
      so to make sure it remains such add a bit which is set when
      NAPI is listed, and cleared when it removed. Since we don't
      expect multiple calls to netif_napi_add() to be correct,
      add a warning on that side.
      
      Now that napi_hash_add / napi_hash_del are only called by
      napi_add / del we can actually steal its bit. We just need
      to make sure hash node is initialized correctly.
      Signed-off-by: NJakub Kicinski <kuba@kernel.org>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      4d092dd2
    • J
      net: remove napi_hash_del() from driver-facing API · 5198d545
      Jakub Kicinski 提交于
      We allow drivers to call napi_hash_del() before calling
      netif_napi_del() to batch RCU grace periods. This makes
      the API asymmetric and leaks internal implementation details.
      Soon we will want the grace period to protect more than just
      the NAPI hash table.
      
      Restructure the API and have drivers call a new function -
      __netif_napi_del() if they want to take care of RCU waits.
      
      Note that only core was checking the return status from
      napi_hash_del() so the new helper does not report if the
      NAPI was actually deleted.
      
      Some notes on driver oddness:
       - veth observed the grace period before calling netif_napi_del()
         but that should not matter
       - myri10ge observed normal RCU flavor
       - bnx2x and enic did not actually observe the grace period
         (unless they did so implicitly)
       - virtio_net and enic only unhashed Rx NAPIs
      
      The last two points seem to indicate that the calls to
      napi_hash_del() were a left over rather than an optimization.
      Regardless, it's easy enough to correct them.
      
      This patch may introduce extra synchronize_net() calls for
      interfaces which set NAPI_STATE_NO_BUSY_POLL and depend on
      free_netdev() to call netif_napi_del(). This seems inevitable
      since we want to use RCU for netpoll dev->napi_list traversal,
      and almost no drivers set IFF_DISABLE_NETPOLL.
      Signed-off-by: NJakub Kicinski <kuba@kernel.org>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      5198d545
  14. 07 9月, 2020 1 次提交
  15. 27 8月, 2020 1 次提交
    • J
      net: disable netpoll on fresh napis · 96e97bc0
      Jakub Kicinski 提交于
      napi_disable() makes sure to set the NAPI_STATE_NPSVC bit to prevent
      netpoll from accessing rings before init is complete. However, the
      same is not done for fresh napi instances in netif_napi_add(),
      even though we expect NAPI instances to be added as disabled.
      
      This causes crashes during driver reconfiguration (enabling XDP,
      changing the channel count) - if there is any printk() after
      netif_napi_add() but before napi_enable().
      
      To ensure memory ordering is correct we need to use RCU accessors.
      Reported-by: NRob Sherwood <rsher@fb.com>
      Fixes: 2d8bff12 ("netpoll: Close race condition between poll_one_napi and napi_disable")
      Signed-off-by: NJakub Kicinski <kuba@kernel.org>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      96e97bc0
  16. 24 8月, 2020 1 次提交
  17. 21 8月, 2020 1 次提交
  18. 18 8月, 2020 1 次提交
  19. 17 8月, 2020 1 次提交
    • J
      net: xdp: pull ethernet header off packet after computing skb->protocol · f8414a8d
      Jason A. Donenfeld 提交于
      When an XDP program changes the ethernet header protocol field,
      eth_type_trans is used to recalculate skb->protocol. In order for
      eth_type_trans to work correctly, the ethernet header must actually be
      part of the skb data segment, so the code first pushes that onto the
      head of the skb. However, it subsequently forgets to pull it back off,
      making the behavior of the passed-on packet inconsistent between the
      protocol modifying case and the static protocol case. This patch fixes
      the issue by simply pulling the ethernet header back off of the skb
      head.
      
      Fixes: 29724956 ("net: fix generic XDP to handle if eth header was mangled")
      Cc: Jesper Dangaard Brouer <brouer@redhat.com>
      Cc: David S. Miller <davem@davemloft.net>
      Signed-off-by: NJason A. Donenfeld <Jason@zx2c4.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      f8414a8d
  20. 13 8月, 2020 1 次提交
  21. 02 8月, 2020 1 次提交
  22. 01 8月, 2020 2 次提交
    • R
      rtnetlink: add support for protodown reason · 829eb208
      Roopa Prabhu 提交于
      netdev protodown is a mechanism that allows protocols to
      hold an interface down. It was initially introduced in
      the kernel to hold links down by a multihoming protocol.
      There was also an attempt to introduce protodown
      reason at the time but was rejected. protodown and protodown reason
      is supported by almost every switching and routing platform.
      It was ok for a while to live without a protodown reason.
      But, its become more critical now given more than
      one protocol may need to keep a link down on a system
      at the same time. eg: vrrp peer node, port security,
      multihoming protocol. Its common for Network operators and
      protocol developers to look for such a reason on a networking
      box (Its also known as errDisable by most networking operators)
      
      This patch adds support for link protodown reason
      attribute. There are two ways to maintain protodown
      reasons.
      (a) enumerate every possible reason code in kernel
          - A protocol developer has to make a request and
            have that appear in a certain kernel version
      (b) provide the bits in the kernel, and allow user-space
      (sysadmin or NOS distributions) to manage the bit-to-reasonname
      map.
      	- This makes extending reason codes easier (kind of like
            the iproute2 table to vrf-name map /etc/iproute2/rt_tables.d/)
      
      This patch takes approach (b).
      
      a few things about the patch:
      - It treats the protodown reason bits as counter to indicate
      active protodown users
      - Since protodown attribute is already an exposed UAPI,
      the reason is not enforced on a protodown set. Its a no-op
      if not used.
      the patch follows the below algorithm:
        - presence of reason bits set indicates protodown
          is in use
        - user can set protodown and protodown reason in a
          single or multiple setlink operations
        - setlink operation to clear protodown, will return -EBUSY
          if there are active protodown reason bits
        - reason is not included in link dumps if not used
      
      example with patched iproute2:
      $cat /etc/iproute2/protodown_reasons.d/r.conf
      0 mlag
      1 evpn
      2 vrrp
      3 psecurity
      
      $ip link set dev vxlan0 protodown on protodown_reason vrrp on
      $ip link set dev vxlan0 protodown_reason mlag on
      $ip link show
      14: vxlan0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode
      DEFAULT group default qlen 1000
          link/ether f6:06:be:17:91:e7 brd ff:ff:ff:ff:ff:ff protodown on <mlag,vrrp>
      
      $ip link set dev vxlan0 protodown_reason mlag off
      $ip link set dev vxlan0 protodown off protodown_reason vrrp off
      Signed-off-by: NRoopa Prabhu <roopa@cumulusnetworks.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      829eb208
    • M
      net: Pass NULL to skb_network_protocol() when we don't care about vlan depth · 9fc95f50
      Miaohe Lin 提交于
      When we don't care about vlan depth, we could pass NULL instead of the
      address of a unused local variable to skb_network_protocol() as a param.
      Signed-off-by: NMiaohe Lin <linmiaohe@huawei.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      9fc95f50
  23. 26 7月, 2020 6 次提交
  24. 25 7月, 2020 1 次提交
  25. 24 7月, 2020 1 次提交
    • V
      net: dsa: stop overriding master's ndo_get_phys_port_name · 5df5661a
      Vladimir Oltean 提交于
      The purpose of this override is to give the user an indication of what
      the number of the CPU port is (in DSA, the CPU port is a hardware
      implementation detail and not a network interface capable of traffic).
      
      However, it has always failed (by design) at providing this information
      to the user in a reliable fashion.
      
      Prior to commit 3369afba ("net: Call into DSA netdevice_ops
      wrappers"), the behavior was to only override this callback if it was
      not provided by the DSA master.
      
      That was its first failure: if the DSA master itself was a DSA port or a
      switchdev, then the user would not see the number of the CPU port in
      /sys/class/net/eth0/phys_port_name, but the number of the DSA master
      port within its respective physical switch.
      
      But that was actually ok in a way. The commit mentioned above changed
      that behavior, and now overrides the master's ndo_get_phys_port_name
      unconditionally. That comes with problems of its own, which are worse in
      a way.
      
      The idea is that it's typical for switchdev users to have udev rules for
      consistent interface naming. These are based, among other things, on
      the phys_port_name attribute. If we let the DSA switch at the bottom
      to start randomly overriding ndo_get_phys_port_name with its own CPU
      port, we basically lose any predictability in interface naming, or even
      uniqueness, for that matter.
      
      So, there are reasons to let DSA override the master's callback (to
      provide a consistent interface, a number which has a clear meaning and
      must not be interpreted according to context), and there are reasons to
      not let DSA override it (it breaks udev matching for the DSA master).
      
      But, there is an alternative method for users to retrieve the number of
      the CPU port of each DSA switch in the system:
      
        $ devlink port
        pci/0000:00:00.5/0: type eth netdev swp0 flavour physical port 0
        pci/0000:00:00.5/2: type eth netdev swp2 flavour physical port 2
        pci/0000:00:00.5/4: type notset flavour cpu port 4
        spi/spi2.0/0: type eth netdev sw0p0 flavour physical port 0
        spi/spi2.0/1: type eth netdev sw0p1 flavour physical port 1
        spi/spi2.0/2: type eth netdev sw0p2 flavour physical port 2
        spi/spi2.0/4: type notset flavour cpu port 4
        spi/spi2.1/0: type eth netdev sw1p0 flavour physical port 0
        spi/spi2.1/1: type eth netdev sw1p1 flavour physical port 1
        spi/spi2.1/2: type eth netdev sw1p2 flavour physical port 2
        spi/spi2.1/3: type eth netdev sw1p3 flavour physical port 3
        spi/spi2.1/4: type notset flavour cpu port 4
      
      So remove this duplicated, unreliable and troublesome method. From this
      patch on, the phys_port_name attribute of the DSA master will only
      contain information about itself (if at all). If the users need reliable
      information about the CPU port they're probably using devlink anyway.
      Signed-off-by: NVladimir Oltean <olteanv@gmail.com>
      Acked-by: Nflorian Fainelli <f.fainelli@gmail.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      5df5661a
  26. 21 7月, 2020 1 次提交
  27. 17 7月, 2020 1 次提交