Merge tag 'net-6.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 10 Nov 2023 01:09:35 +0000 (17:09 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 10 Nov 2023 01:09:35 +0000 (17:09 -0800)
Pull networking fixes from Jakub Kicinski:
 "Including fixes from netfilter and bpf.

  Current release - regressions:

   - sched: fix SKB_NOT_DROPPED_YET splat under debug config

  Current release - new code bugs:

   - tcp:
       - fix usec timestamps with TCP fastopen
       - fix possible out-of-bounds reads in tcp_hash_fail()
       - fix SYN option room calculation for TCP-AO

   - tcp_sigpool: fix some off by one bugs

   - bpf: fix compilation error without CGROUPS

   - ptp:
       - ptp_read() should not release queue
       - fix tsevqs corruption

  Previous releases - regressions:

   - llc: verify mac len before reading mac header

  Previous releases - always broken:

   - bpf:
       - fix check_stack_write_fixed_off() to correctly spill imm
       - fix precision tracking for BPF_ALU | BPF_TO_BE | BPF_END
       - check map->usercnt after timer->timer is assigned

   - dsa: lan9303: consequently nested-lock physical MDIO

   - dccp/tcp: call security_inet_conn_request() after setting IP addr

   - tg3: fix the TX ring stall due to incorrect full ring handling

   - phylink: initialize carrier state at creation

   - ice: fix direction of VF rules in switchdev mode

  Misc:

   - fill in a bunch of missing MODULE_DESCRIPTION()s, more to come"

* tag 'net-6.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (84 commits)
  net: ti: icss-iep: fix setting counter value
  ptp: fix corrupted list in ptp_open
  ptp: ptp_read should not release queue
  net_sched: sch_fq: better validate TCA_FQ_WEIGHTS and TCA_FQ_PRIOMAP
  net: kcm: fill in MODULE_DESCRIPTION()
  net/sched: act_ct: Always fill offloading tuple iifidx
  netfilter: nat: fix ipv6 nat redirect with mapped and scoped addresses
  netfilter: xt_recent: fix (increase) ipv6 literal buffer length
  ipvs: add missing module descriptions
  netfilter: nf_tables: remove catchall element in GC sync path
  netfilter: add missing module descriptions
  drivers/net/ppp: use standard array-copy-function
  net: enetc: shorten enetc_setup_xdp_prog() error message to fit NETLINK_MAX_FMTMSG_LEN
  virtio/vsock: Fix uninit-value in virtio_transport_recv_pkt()
  r8169: respect userspace disabling IFF_MULTICAST
  selftests/bpf: get trusted cgrp from bpf_iter__cgroup directly
  bpf: Let verifier consider {task,cgroup} is trusted in bpf_iter_reg
  net: phylink: initialize carrier state at creation
  test/vsock: add dobule bind connect test
  test/vsock: refactor vsock_accept
  ...

178 files changed:
Documentation/bpf/kfuncs.rst
Documentation/netlink/specs/devlink.yaml
Documentation/networking/smc-sysctl.rst
drivers/net/dsa/lan9303_mdio.c
drivers/net/ethernet/broadcom/tg3.c
drivers/net/ethernet/freescale/enetc/enetc.c
drivers/net/ethernet/intel/i40e/i40e_devlink.c
drivers/net/ethernet/intel/i40e/i40e_main.c
drivers/net/ethernet/intel/ice/ice_lag.c
drivers/net/ethernet/intel/ice/ice_tc_lib.c
drivers/net/ethernet/intel/idpf/idpf_txrx.c
drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
drivers/net/ethernet/marvell/octeontx2/nic/otx2_struct.h
drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
drivers/net/ethernet/realtek/r8169_main.c
drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
drivers/net/ethernet/ti/am65-cpsw-nuss.c
drivers/net/ethernet/ti/icssg/icss_iep.c
drivers/net/ethernet/xscale/ixp4xx_eth.c
drivers/net/mdio/acpi_mdio.c
drivers/net/mdio/fwnode_mdio.c
drivers/net/mdio/mdio-aspeed.c
drivers/net/mdio/mdio-bitbang.c
drivers/net/mdio/of_mdio.c
drivers/net/phy/bcm-phy-ptp.c
drivers/net/phy/bcm87xx.c
drivers/net/phy/phylink.c
drivers/net/phy/sfp.c
drivers/net/ppp/ppp_generic.c
drivers/ptp/ptp_chardev.c
drivers/ptp/ptp_clock.c
drivers/ptp/ptp_private.h
drivers/s390/net/qeth_core_main.c
include/linux/btf.h
include/linux/ethtool.h
include/linux/idr.h
include/linux/tcp.h
include/net/flow.h
include/net/netfilter/nf_conntrack_act_ct.h
include/net/tcp_ao.h
include/uapi/linux/nfsd_netlink.h
kernel/bpf/bpf_iter.c
kernel/bpf/cgroup_iter.c
kernel/bpf/cpumask.c
kernel/bpf/helpers.c
kernel/bpf/map_iter.c
kernel/bpf/task_iter.c
kernel/bpf/verifier.c
kernel/cgroup/rstat.c
kernel/trace/bpf_trace.c
net/bpf/test_run.c
net/bridge/netfilter/ebtable_broute.c
net/bridge/netfilter/ebtable_filter.c
net/bridge/netfilter/ebtable_nat.c
net/bridge/netfilter/ebtables.c
net/bridge/netfilter/nf_conntrack_bridge.c
net/core/filter.c
net/core/page_pool.c
net/core/xdp.c
net/dccp/ipv4.c
net/dccp/ipv6.c
net/devlink/netlink_gen.c
net/hsr/hsr_forward.c
net/ipv4/fou_bpf.c
net/ipv4/netfilter/iptable_nat.c
net/ipv4/netfilter/iptable_raw.c
net/ipv4/netfilter/nf_defrag_ipv4.c
net/ipv4/netfilter/nf_reject_ipv4.c
net/ipv4/syncookies.c
net/ipv4/tcp_ao.c
net/ipv4/tcp_input.c
net/ipv4/tcp_output.c
net/ipv4/tcp_sigpool.c
net/ipv6/netfilter/ip6table_nat.c
net/ipv6/netfilter/ip6table_raw.c
net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
net/ipv6/netfilter/nf_reject_ipv6.c
net/ipv6/syncookies.c
net/kcm/kcmsock.c
net/llc/llc_input.c
net/llc/llc_s_ac.c
net/llc/llc_station.c
net/netfilter/ipvs/ip_vs_core.c
net/netfilter/ipvs/ip_vs_dh.c
net/netfilter/ipvs/ip_vs_fo.c
net/netfilter/ipvs/ip_vs_ftp.c
net/netfilter/ipvs/ip_vs_lblc.c
net/netfilter/ipvs/ip_vs_lblcr.c
net/netfilter/ipvs/ip_vs_lc.c
net/netfilter/ipvs/ip_vs_nq.c
net/netfilter/ipvs/ip_vs_ovf.c
net/netfilter/ipvs/ip_vs_pe_sip.c
net/netfilter/ipvs/ip_vs_rr.c
net/netfilter/ipvs/ip_vs_sed.c
net/netfilter/ipvs/ip_vs_sh.c
net/netfilter/ipvs/ip_vs_twos.c
net/netfilter/ipvs/ip_vs_wlc.c
net/netfilter/ipvs/ip_vs_wrr.c
net/netfilter/nf_conntrack_bpf.c
net/netfilter/nf_conntrack_broadcast.c
net/netfilter/nf_conntrack_netlink.c
net/netfilter/nf_conntrack_proto.c
net/netfilter/nf_nat_bpf.c
net/netfilter/nf_nat_core.c
net/netfilter/nf_nat_redirect.c
net/netfilter/nf_tables_api.c
net/netfilter/nfnetlink_osf.c
net/netfilter/nft_chain_nat.c
net/netfilter/nft_fib.c
net/netfilter/nft_fwd_netdev.c
net/netfilter/xt_recent.c
net/netlink/diag.c
net/openvswitch/conntrack.c
net/rxrpc/conn_object.c
net/rxrpc/local_object.c
net/sched/act_api.c
net/sched/act_ct.c
net/sched/act_gate.c
net/sched/cls_api.c
net/sched/cls_basic.c
net/sched/cls_cgroup.c
net/sched/cls_fw.c
net/sched/cls_route.c
net/sched/cls_u32.c
net/sched/sch_cbs.c
net/sched/sch_choke.c
net/sched/sch_drr.c
net/sched/sch_etf.c
net/sched/sch_ets.c
net/sched/sch_fifo.c
net/sched/sch_fq.c
net/sched/sch_gred.c
net/sched/sch_hfsc.c
net/sched/sch_htb.c
net/sched/sch_ingress.c
net/sched/sch_mqprio.c
net/sched/sch_mqprio_lib.c
net/sched/sch_multiq.c
net/sched/sch_netem.c
net/sched/sch_plug.c
net/sched/sch_prio.c
net/sched/sch_qfq.c
net/sched/sch_red.c
net/sched/sch_sfq.c
net/sched/sch_skbprio.c
net/sched/sch_taprio.c
net/sched/sch_tbf.c
net/sched/sch_teql.c
net/smc/af_smc.c
net/smc/smc.h
net/smc/smc_cdc.c
net/smc/smc_close.c
net/socket.c
net/tipc/netlink.c
net/vmw_vsock/virtio_transport_common.c
net/xfrm/xfrm_interface_bpf.c
tools/net/ynl/generated/devlink-user.c
tools/net/ynl/generated/nfsd-user.c
tools/net/ynl/generated/nfsd-user.h
tools/net/ynl/ynl-gen-c.py
tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
tools/testing/selftests/bpf/map_tests/map_percpu_stats.c
tools/testing/selftests/bpf/prog_tests/cgroup_iter.c
tools/testing/selftests/bpf/prog_tests/iters.c
tools/testing/selftests/bpf/prog_tests/test_bpffs.c
tools/testing/selftests/bpf/prog_tests/verifier.c
tools/testing/selftests/bpf/progs/iters_css_task.c
tools/testing/selftests/bpf/progs/iters_task_failure.c
tools/testing/selftests/bpf/progs/verifier_precision.c [new file with mode: 0644]
tools/testing/selftests/bpf/verifier/bpf_st_mem.c
tools/testing/selftests/bpf/xdp_hw_metadata.c
tools/testing/selftests/net/pmtu.sh
tools/testing/vsock/util.c
tools/testing/vsock/util.h
tools/testing/vsock/vsock_test.c

index 0d2647f..723408e 100644 (file)
@@ -37,16 +37,14 @@ prototype in a header for the wrapper kfunc.
 An example is given below::
 
         /* Disables missing prototype warnings */
-        __diag_push();
-        __diag_ignore_all("-Wmissing-prototypes",
-                          "Global kfuncs as their definitions will be in BTF");
+        __bpf_kfunc_start_defs();
 
         __bpf_kfunc struct task_struct *bpf_find_get_task_by_vpid(pid_t nr)
         {
                 return find_get_task_by_vpid(nr);
         }
 
-        __diag_pop();
+        __bpf_kfunc_end_defs();
 
 A wrapper kfunc is often needed when we need to annotate parameters of the
 kfunc. Otherwise one may directly make the kfunc visible to the BPF program by
index c6ba488..572d83a 100644 (file)
@@ -71,6 +71,10 @@ definitions:
         name: roce-bit
       -
         name: migratable-bit
+      -
+        name: ipsec-crypto-bit
+      -
+        name: ipsec-packet-bit
   -
     type: enum
     name: sb-threshold-type
index 6d8acdb..769149d 100644 (file)
@@ -44,18 +44,16 @@ smcr_testlink_time - INTEGER
 
 wmem - INTEGER
        Initial size of send buffer used by SMC sockets.
-       The default value inherits from net.ipv4.tcp_wmem[1].
 
        The minimum value is 16KiB and there is no hard limit for max value, but
        only allowed 512KiB for SMC-R and 1MiB for SMC-D.
 
-       Default: 16K
+       Default: 64KiB
 
 rmem - INTEGER
        Initial size of receive buffer (RMB) used by SMC sockets.
-       The default value inherits from net.ipv4.tcp_rmem[1].
 
        The minimum value is 16KiB and there is no hard limit for max value, but
        only allowed 512KiB for SMC-R and 1MiB for SMC-D.
 
-       Default: 128K
+       Default: 64KiB
index d8ab2b7..167a86f 100644 (file)
@@ -32,7 +32,7 @@ static int lan9303_mdio_write(void *ctx, uint32_t reg, uint32_t val)
        struct lan9303_mdio *sw_dev = (struct lan9303_mdio *)ctx;
 
        reg <<= 2; /* reg num to offset */
-       mutex_lock(&sw_dev->device->bus->mdio_lock);
+       mutex_lock_nested(&sw_dev->device->bus->mdio_lock, MDIO_MUTEX_NESTED);
        lan9303_mdio_real_write(sw_dev->device, reg, val & 0xffff);
        lan9303_mdio_real_write(sw_dev->device, reg + 2, (val >> 16) & 0xffff);
        mutex_unlock(&sw_dev->device->bus->mdio_lock);
@@ -50,7 +50,7 @@ static int lan9303_mdio_read(void *ctx, uint32_t reg, uint32_t *val)
        struct lan9303_mdio *sw_dev = (struct lan9303_mdio *)ctx;
 
        reg <<= 2; /* reg num to offset */
-       mutex_lock(&sw_dev->device->bus->mdio_lock);
+       mutex_lock_nested(&sw_dev->device->bus->mdio_lock, MDIO_MUTEX_NESTED);
        *val = lan9303_mdio_real_read(sw_dev->device, reg);
        *val |= (lan9303_mdio_real_read(sw_dev->device, reg + 2) << 16);
        mutex_unlock(&sw_dev->device->bus->mdio_lock);
index 5665d0c..1dee273 100644 (file)
@@ -6647,9 +6647,9 @@ static void tg3_tx(struct tg3_napi *tnapi)
 
        tnapi->tx_cons = sw_idx;
 
-       /* Need to make the tx_cons update visible to tg3_start_xmit()
+       /* Need to make the tx_cons update visible to __tg3_start_xmit()
         * before checking for netif_queue_stopped().  Without the
-        * memory barrier, there is a small possibility that tg3_start_xmit()
+        * memory barrier, there is a small possibility that __tg3_start_xmit()
         * will miss it and cause the queue to be stopped forever.
         */
        smp_mb();
@@ -7889,7 +7889,7 @@ static bool tg3_tso_bug_gso_check(struct tg3_napi *tnapi, struct sk_buff *skb)
        return skb_shinfo(skb)->gso_segs < tnapi->tx_pending / 3;
 }
 
-static netdev_tx_t tg3_start_xmit(struct sk_buff *, struct net_device *);
+static netdev_tx_t __tg3_start_xmit(struct sk_buff *, struct net_device *);
 
 /* Use GSO to workaround all TSO packets that meet HW bug conditions
  * indicated in tg3_tx_frag_set()
@@ -7923,7 +7923,7 @@ static int tg3_tso_bug(struct tg3 *tp, struct tg3_napi *tnapi,
 
        skb_list_walk_safe(segs, seg, next) {
                skb_mark_not_on_list(seg);
-               tg3_start_xmit(seg, tp->dev);
+               __tg3_start_xmit(seg, tp->dev);
        }
 
 tg3_tso_bug_end:
@@ -7933,7 +7933,7 @@ tg3_tso_bug_end:
 }
 
 /* hard_start_xmit for all devices */
-static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t __tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct tg3 *tp = netdev_priv(dev);
        u32 len, entry, base_flags, mss, vlan = 0;
@@ -8182,11 +8182,6 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
                        netif_tx_wake_queue(txq);
        }
 
-       if (!netdev_xmit_more() || netif_xmit_stopped(txq)) {
-               /* Packets are ready, update Tx producer idx on card. */
-               tw32_tx_mbox(tnapi->prodmbox, entry);
-       }
-
        return NETDEV_TX_OK;
 
 dma_error:
@@ -8199,6 +8194,42 @@ drop_nofree:
        return NETDEV_TX_OK;
 }
 
+static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+       struct netdev_queue *txq;
+       u16 skb_queue_mapping;
+       netdev_tx_t ret;
+
+       skb_queue_mapping = skb_get_queue_mapping(skb);
+       txq = netdev_get_tx_queue(dev, skb_queue_mapping);
+
+       ret = __tg3_start_xmit(skb, dev);
+
+       /* Notify the hardware that packets are ready by updating the TX ring
+        * tail pointer. We respect netdev_xmit_more() thus avoiding poking
+        * the hardware for every packet. To guarantee forward progress the TX
+        * ring must be drained when it is full as indicated by
+        * netif_xmit_stopped(). This needs to happen even when the current
+        * skb was dropped or rejected with NETDEV_TX_BUSY. Otherwise packets
+        * queued by previous __tg3_start_xmit() calls might get stuck in
+        * the queue forever.
+        */
+       if (!netdev_xmit_more() || netif_xmit_stopped(txq)) {
+               struct tg3_napi *tnapi;
+               struct tg3 *tp;
+
+               tp = netdev_priv(dev);
+               tnapi = &tp->napi[skb_queue_mapping];
+
+               if (tg3_flag(tp, ENABLE_TSS))
+                       tnapi++;
+
+               tw32_tx_mbox(tnapi->prodmbox, tnapi->tx_prod);
+       }
+
+       return ret;
+}
+
 static void tg3_mac_loopback(struct tg3 *tp, bool enable)
 {
        if (enable) {
@@ -17729,7 +17760,7 @@ static int tg3_init_one(struct pci_dev *pdev,
         * device behind the EPB cannot support DMA addresses > 40-bit.
         * On 64-bit systems with IOMMU, use 40-bit dma_mask.
         * On 64-bit systems without IOMMU, use 64-bit dma_mask and
-        * do DMA address check in tg3_start_xmit().
+        * do DMA address check in __tg3_start_xmit().
         */
        if (tg3_flag(tp, IS_5788))
                persist_dma_mask = dma_mask = DMA_BIT_MASK(32);
@@ -18127,7 +18158,8 @@ static void tg3_shutdown(struct pci_dev *pdev)
        if (netif_running(dev))
                dev_close(dev);
 
-       tg3_power_down(tp);
+       if (system_state == SYSTEM_POWER_OFF)
+               tg3_power_down(tp);
 
        rtnl_unlock();
 
index 30bec47..cffbf27 100644 (file)
@@ -2769,7 +2769,7 @@ static int enetc_setup_xdp_prog(struct net_device *ndev, struct bpf_prog *prog,
        if (priv->min_num_stack_tx_queues + num_xdp_tx_queues >
            priv->num_tx_rings) {
                NL_SET_ERR_MSG_FMT_MOD(extack,
-                                      "Reserving %d XDP TXQs does not leave a minimum of %d TXQs for network stack (total %d available)",
+                                      "Reserving %d XDP TXQs does not leave a minimum of %d for stack (total %d)",
                                       num_xdp_tx_queues,
                                       priv->min_num_stack_tx_queues,
                                       priv->num_tx_rings);
index 74bc111..cc4e9e2 100644 (file)
@@ -231,6 +231,5 @@ int i40e_devlink_create_port(struct i40e_pf *pf)
  **/
 void i40e_devlink_destroy_port(struct i40e_pf *pf)
 {
-       devlink_port_type_clear(&pf->devlink_port);
        devlink_port_unregister(&pf->devlink_port);
 }
index 3157d14..f7a332e 100644 (file)
@@ -14213,8 +14213,7 @@ int i40e_vsi_release(struct i40e_vsi *vsi)
        }
        set_bit(__I40E_VSI_RELEASING, vsi->state);
        uplink_seid = vsi->uplink_seid;
-       if (vsi->type == I40E_VSI_MAIN)
-               i40e_devlink_destroy_port(pf);
+
        if (vsi->type != I40E_VSI_SRIOV) {
                if (vsi->netdev_registered) {
                        vsi->netdev_registered = false;
@@ -14228,6 +14227,9 @@ int i40e_vsi_release(struct i40e_vsi *vsi)
                i40e_vsi_disable_irq(vsi);
        }
 
+       if (vsi->type == I40E_VSI_MAIN)
+               i40e_devlink_destroy_port(pf);
+
        spin_lock_bh(&vsi->mac_filter_hash_lock);
 
        /* clear the sync flag on all filters */
@@ -14402,14 +14404,14 @@ static struct i40e_vsi *i40e_vsi_reinit_setup(struct i40e_vsi *vsi)
 
 err_rings:
        i40e_vsi_free_q_vectors(vsi);
-       if (vsi->type == I40E_VSI_MAIN)
-               i40e_devlink_destroy_port(pf);
        if (vsi->netdev_registered) {
                vsi->netdev_registered = false;
                unregister_netdev(vsi->netdev);
                free_netdev(vsi->netdev);
                vsi->netdev = NULL;
        }
+       if (vsi->type == I40E_VSI_MAIN)
+               i40e_devlink_destroy_port(pf);
        i40e_aq_delete_element(&pf->hw, vsi->seid, NULL);
 err_vsi:
        i40e_vsi_clear(vsi);
index b980f89..cd065ec 100644 (file)
@@ -628,7 +628,7 @@ void ice_lag_move_new_vf_nodes(struct ice_vf *vf)
                INIT_LIST_HEAD(&ndlist.node);
                rcu_read_lock();
                for_each_netdev_in_bond_rcu(lag->upper_netdev, tmp_nd) {
-                       nl = kzalloc(sizeof(*nl), GFP_KERNEL);
+                       nl = kzalloc(sizeof(*nl), GFP_ATOMIC);
                        if (!nl)
                                break;
 
@@ -1555,18 +1555,12 @@ static void ice_lag_chk_disabled_bond(struct ice_lag *lag, void *ptr)
  */
 static void ice_lag_disable_sriov_bond(struct ice_lag *lag)
 {
-       struct ice_lag_netdev_list *entry;
        struct ice_netdev_priv *np;
-       struct net_device *netdev;
        struct ice_pf *pf;
 
-       list_for_each_entry(entry, lag->netdev_head, node) {
-               netdev = entry->netdev;
-               np = netdev_priv(netdev);
-               pf = np->vsi->back;
-
-               ice_clear_feature_support(pf, ICE_F_SRIOV_LAG);
-       }
+       np = netdev_priv(lag->netdev);
+       pf = np->vsi->back;
+       ice_clear_feature_support(pf, ICE_F_SRIOV_LAG);
 }
 
 /**
@@ -1698,7 +1692,7 @@ ice_lag_event_handler(struct notifier_block *notif_blk, unsigned long event,
 
                rcu_read_lock();
                for_each_netdev_in_bond_rcu(upper_netdev, tmp_nd) {
-                       nd_list = kzalloc(sizeof(*nd_list), GFP_KERNEL);
+                       nd_list = kzalloc(sizeof(*nd_list), GFP_ATOMIC);
                        if (!nd_list)
                                break;
 
@@ -2075,7 +2069,7 @@ void ice_lag_rebuild(struct ice_pf *pf)
                INIT_LIST_HEAD(&ndlist.node);
                rcu_read_lock();
                for_each_netdev_in_bond_rcu(lag->upper_netdev, tmp_nd) {
-                       nl = kzalloc(sizeof(*nl), GFP_KERNEL);
+                       nl = kzalloc(sizeof(*nl), GFP_ATOMIC);
                        if (!nl)
                                break;
 
index 37b54db..dd03cb6 100644 (file)
@@ -630,32 +630,83 @@ bool ice_is_tunnel_supported(struct net_device *dev)
        return ice_tc_tun_get_type(dev) != TNL_LAST;
 }
 
-static int
-ice_eswitch_tc_parse_action(struct ice_tc_flower_fltr *fltr,
-                           struct flow_action_entry *act)
+static bool ice_tc_is_dev_uplink(struct net_device *dev)
+{
+       return netif_is_ice(dev) || ice_is_tunnel_supported(dev);
+}
+
+static int ice_tc_setup_redirect_action(struct net_device *filter_dev,
+                                       struct ice_tc_flower_fltr *fltr,
+                                       struct net_device *target_dev)
 {
        struct ice_repr *repr;
 
+       fltr->action.fltr_act = ICE_FWD_TO_VSI;
+
+       if (ice_is_port_repr_netdev(filter_dev) &&
+           ice_is_port_repr_netdev(target_dev)) {
+               repr = ice_netdev_to_repr(target_dev);
+
+               fltr->dest_vsi = repr->src_vsi;
+               fltr->direction = ICE_ESWITCH_FLTR_EGRESS;
+       } else if (ice_is_port_repr_netdev(filter_dev) &&
+                  ice_tc_is_dev_uplink(target_dev)) {
+               repr = ice_netdev_to_repr(filter_dev);
+
+               fltr->dest_vsi = repr->src_vsi->back->switchdev.uplink_vsi;
+               fltr->direction = ICE_ESWITCH_FLTR_EGRESS;
+       } else if (ice_tc_is_dev_uplink(filter_dev) &&
+                  ice_is_port_repr_netdev(target_dev)) {
+               repr = ice_netdev_to_repr(target_dev);
+
+               fltr->dest_vsi = repr->src_vsi;
+               fltr->direction = ICE_ESWITCH_FLTR_INGRESS;
+       } else {
+               NL_SET_ERR_MSG_MOD(fltr->extack,
+                                  "Unsupported netdevice in switchdev mode");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int
+ice_tc_setup_drop_action(struct net_device *filter_dev,
+                        struct ice_tc_flower_fltr *fltr)
+{
+       fltr->action.fltr_act = ICE_DROP_PACKET;
+
+       if (ice_is_port_repr_netdev(filter_dev)) {
+               fltr->direction = ICE_ESWITCH_FLTR_EGRESS;
+       } else if (ice_tc_is_dev_uplink(filter_dev)) {
+               fltr->direction = ICE_ESWITCH_FLTR_INGRESS;
+       } else {
+               NL_SET_ERR_MSG_MOD(fltr->extack,
+                                  "Unsupported netdevice in switchdev mode");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int ice_eswitch_tc_parse_action(struct net_device *filter_dev,
+                                      struct ice_tc_flower_fltr *fltr,
+                                      struct flow_action_entry *act)
+{
+       int err;
+
        switch (act->id) {
        case FLOW_ACTION_DROP:
-               fltr->action.fltr_act = ICE_DROP_PACKET;
+               err = ice_tc_setup_drop_action(filter_dev, fltr);
+               if (err)
+                       return err;
+
                break;
 
        case FLOW_ACTION_REDIRECT:
-               fltr->action.fltr_act = ICE_FWD_TO_VSI;
-
-               if (ice_is_port_repr_netdev(act->dev)) {
-                       repr = ice_netdev_to_repr(act->dev);
-
-                       fltr->dest_vsi = repr->src_vsi;
-                       fltr->direction = ICE_ESWITCH_FLTR_INGRESS;
-               } else if (netif_is_ice(act->dev) ||
-                          ice_is_tunnel_supported(act->dev)) {
-                       fltr->direction = ICE_ESWITCH_FLTR_EGRESS;
-               } else {
-                       NL_SET_ERR_MSG_MOD(fltr->extack, "Unsupported netdevice in switchdev mode");
-                       return -EINVAL;
-               }
+               err = ice_tc_setup_redirect_action(filter_dev, fltr, act->dev);
+               if (err)
+                       return err;
 
                break;
 
@@ -696,10 +747,6 @@ ice_eswitch_add_tc_fltr(struct ice_vsi *vsi, struct ice_tc_flower_fltr *fltr)
                goto exit;
        }
 
-       /* egress traffic is always redirect to uplink */
-       if (fltr->direction == ICE_ESWITCH_FLTR_EGRESS)
-               fltr->dest_vsi = vsi->back->switchdev.uplink_vsi;
-
        rule_info.sw_act.fltr_act = fltr->action.fltr_act;
        if (fltr->action.fltr_act != ICE_DROP_PACKET)
                rule_info.sw_act.vsi_handle = fltr->dest_vsi->idx;
@@ -713,13 +760,21 @@ ice_eswitch_add_tc_fltr(struct ice_vsi *vsi, struct ice_tc_flower_fltr *fltr)
        rule_info.flags_info.act_valid = true;
 
        if (fltr->direction == ICE_ESWITCH_FLTR_INGRESS) {
+               /* Uplink to VF */
                rule_info.sw_act.flag |= ICE_FLTR_RX;
                rule_info.sw_act.src = hw->pf_id;
                rule_info.flags_info.act = ICE_SINGLE_ACT_LB_ENABLE;
-       } else {
+       } else if (fltr->direction == ICE_ESWITCH_FLTR_EGRESS &&
+                  fltr->dest_vsi == vsi->back->switchdev.uplink_vsi) {
+               /* VF to Uplink */
                rule_info.sw_act.flag |= ICE_FLTR_TX;
                rule_info.sw_act.src = vsi->idx;
                rule_info.flags_info.act = ICE_SINGLE_ACT_LAN_ENABLE;
+       } else {
+               /* VF to VF */
+               rule_info.sw_act.flag |= ICE_FLTR_TX;
+               rule_info.sw_act.src = vsi->idx;
+               rule_info.flags_info.act = ICE_SINGLE_ACT_LB_ENABLE;
        }
 
        /* specify the cookie as filter_rule_id */
@@ -1745,16 +1800,17 @@ ice_tc_parse_action(struct ice_vsi *vsi, struct ice_tc_flower_fltr *fltr,
 
 /**
  * ice_parse_tc_flower_actions - Parse the actions for a TC filter
+ * @filter_dev: Pointer to device on which filter is being added
  * @vsi: Pointer to VSI
  * @cls_flower: Pointer to TC flower offload structure
  * @fltr: Pointer to TC flower filter structure
  *
  * Parse the actions for a TC filter
  */
-static int
-ice_parse_tc_flower_actions(struct ice_vsi *vsi,
-                           struct flow_cls_offload *cls_flower,
-                           struct ice_tc_flower_fltr *fltr)
+static int ice_parse_tc_flower_actions(struct net_device *filter_dev,
+                                      struct ice_vsi *vsi,
+                                      struct flow_cls_offload *cls_flower,
+                                      struct ice_tc_flower_fltr *fltr)
 {
        struct flow_rule *rule = flow_cls_offload_flow_rule(cls_flower);
        struct flow_action *flow_action = &rule->action;
@@ -1769,7 +1825,7 @@ ice_parse_tc_flower_actions(struct ice_vsi *vsi,
 
        flow_action_for_each(i, act, flow_action) {
                if (ice_is_eswitch_mode_switchdev(vsi->back))
-                       err = ice_eswitch_tc_parse_action(fltr, act);
+                       err = ice_eswitch_tc_parse_action(filter_dev, fltr, act);
                else
                        err = ice_tc_parse_action(vsi, fltr, act);
                if (err)
@@ -1856,7 +1912,7 @@ ice_add_tc_fltr(struct net_device *netdev, struct ice_vsi *vsi,
        if (err < 0)
                goto err;
 
-       err = ice_parse_tc_flower_actions(vsi, f, fltr);
+       err = ice_parse_tc_flower_actions(netdev, vsi, f, fltr);
        if (err < 0)
                goto err;
 
index 5e1ef70..1f728a9 100644 (file)
@@ -2365,7 +2365,7 @@ static void idpf_tx_splitq_map(struct idpf_queue *tx_q,
  */
 int idpf_tso(struct sk_buff *skb, struct idpf_tx_offload_params *off)
 {
-       const struct skb_shared_info *shinfo = skb_shinfo(skb);
+       const struct skb_shared_info *shinfo;
        union {
                struct iphdr *v4;
                struct ipv6hdr *v6;
@@ -2379,13 +2379,15 @@ int idpf_tso(struct sk_buff *skb, struct idpf_tx_offload_params *off)
        u32 paylen, l4_start;
        int err;
 
-       if (!shinfo->gso_size)
+       if (!skb_is_gso(skb))
                return 0;
 
        err = skb_cow_head(skb, 0);
        if (err < 0)
                return err;
 
+       shinfo = skb_shinfo(skb);
+
        ip.hdr = skb_network_header(skb);
        l4.hdr = skb_transport_header(skb);
 
index 1a42bfd..7ca6941 100644 (file)
@@ -818,7 +818,6 @@ void otx2_sqb_flush(struct otx2_nic *pfvf)
        int qidx, sqe_tail, sqe_head;
        struct otx2_snd_queue *sq;
        u64 incr, *ptr, val;
-       int timeout = 1000;
 
        ptr = (u64 *)otx2_get_regaddr(pfvf, NIX_LF_SQ_OP_STATUS);
        for (qidx = 0; qidx < otx2_get_total_tx_queues(pfvf); qidx++) {
@@ -827,15 +826,11 @@ void otx2_sqb_flush(struct otx2_nic *pfvf)
                        continue;
 
                incr = (u64)qidx << 32;
-               while (timeout) {
-                       val = otx2_atomic64_add(incr, ptr);
-                       sqe_head = (val >> 20) & 0x3F;
-                       sqe_tail = (val >> 28) & 0x3F;
-                       if (sqe_head == sqe_tail)
-                               break;
-                       usleep_range(1, 3);
-                       timeout--;
-               }
+               val = otx2_atomic64_add(incr, ptr);
+               sqe_head = (val >> 20) & 0x3F;
+               sqe_tail = (val >> 28) & 0x3F;
+               if (sqe_head != sqe_tail)
+                       usleep_range(50, 60);
        }
 }
 
index c04a8ee..e7c69b5 100644 (file)
@@ -977,6 +977,7 @@ int otx2_txschq_config(struct otx2_nic *pfvf, int lvl, int prio, bool pfc_en);
 int otx2_txsch_alloc(struct otx2_nic *pfvf);
 void otx2_txschq_stop(struct otx2_nic *pfvf);
 void otx2_txschq_free_one(struct otx2_nic *pfvf, u16 lvl, u16 schq);
+void otx2_free_pending_sqe(struct otx2_nic *pfvf);
 void otx2_sqb_flush(struct otx2_nic *pfvf);
 int otx2_alloc_rbuf(struct otx2_nic *pfvf, struct otx2_pool *pool,
                    dma_addr_t *dma);
index 6daf4d5..91b99fd 100644 (file)
@@ -1193,31 +1193,32 @@ static char *nix_mnqerr_e_str[NIX_MNQERR_MAX] = {
 };
 
 static char *nix_snd_status_e_str[NIX_SND_STATUS_MAX] =  {
-       "NIX_SND_STATUS_GOOD",
-       "NIX_SND_STATUS_SQ_CTX_FAULT",
-       "NIX_SND_STATUS_SQ_CTX_POISON",
-       "NIX_SND_STATUS_SQB_FAULT",
-       "NIX_SND_STATUS_SQB_POISON",
-       "NIX_SND_STATUS_HDR_ERR",
-       "NIX_SND_STATUS_EXT_ERR",
-       "NIX_SND_STATUS_JUMP_FAULT",
-       "NIX_SND_STATUS_JUMP_POISON",
-       "NIX_SND_STATUS_CRC_ERR",
-       "NIX_SND_STATUS_IMM_ERR",
-       "NIX_SND_STATUS_SG_ERR",
-       "NIX_SND_STATUS_MEM_ERR",
-       "NIX_SND_STATUS_INVALID_SUBDC",
-       "NIX_SND_STATUS_SUBDC_ORDER_ERR",
-       "NIX_SND_STATUS_DATA_FAULT",
-       "NIX_SND_STATUS_DATA_POISON",
-       "NIX_SND_STATUS_NPC_DROP_ACTION",
-       "NIX_SND_STATUS_LOCK_VIOL",
-       "NIX_SND_STATUS_NPC_UCAST_CHAN_ERR",
-       "NIX_SND_STATUS_NPC_MCAST_CHAN_ERR",
-       "NIX_SND_STATUS_NPC_MCAST_ABORT",
-       "NIX_SND_STATUS_NPC_VTAG_PTR_ERR",
-       "NIX_SND_STATUS_NPC_VTAG_SIZE_ERR",
-       "NIX_SND_STATUS_SEND_STATS_ERR",
+       [NIX_SND_STATUS_GOOD] = "NIX_SND_STATUS_GOOD",
+       [NIX_SND_STATUS_SQ_CTX_FAULT] = "NIX_SND_STATUS_SQ_CTX_FAULT",
+       [NIX_SND_STATUS_SQ_CTX_POISON] = "NIX_SND_STATUS_SQ_CTX_POISON",
+       [NIX_SND_STATUS_SQB_FAULT] = "NIX_SND_STATUS_SQB_FAULT",
+       [NIX_SND_STATUS_SQB_POISON] = "NIX_SND_STATUS_SQB_POISON",
+       [NIX_SND_STATUS_HDR_ERR] = "NIX_SND_STATUS_HDR_ERR",
+       [NIX_SND_STATUS_EXT_ERR] = "NIX_SND_STATUS_EXT_ERR",
+       [NIX_SND_STATUS_JUMP_FAULT] = "NIX_SND_STATUS_JUMP_FAULT",
+       [NIX_SND_STATUS_JUMP_POISON] = "NIX_SND_STATUS_JUMP_POISON",
+       [NIX_SND_STATUS_CRC_ERR] = "NIX_SND_STATUS_CRC_ERR",
+       [NIX_SND_STATUS_IMM_ERR] = "NIX_SND_STATUS_IMM_ERR",
+       [NIX_SND_STATUS_SG_ERR] = "NIX_SND_STATUS_SG_ERR",
+       [NIX_SND_STATUS_MEM_ERR] = "NIX_SND_STATUS_MEM_ERR",
+       [NIX_SND_STATUS_INVALID_SUBDC] = "NIX_SND_STATUS_INVALID_SUBDC",
+       [NIX_SND_STATUS_SUBDC_ORDER_ERR] = "NIX_SND_STATUS_SUBDC_ORDER_ERR",
+       [NIX_SND_STATUS_DATA_FAULT] = "NIX_SND_STATUS_DATA_FAULT",
+       [NIX_SND_STATUS_DATA_POISON] = "NIX_SND_STATUS_DATA_POISON",
+       [NIX_SND_STATUS_NPC_DROP_ACTION] = "NIX_SND_STATUS_NPC_DROP_ACTION",
+       [NIX_SND_STATUS_LOCK_VIOL] = "NIX_SND_STATUS_LOCK_VIOL",
+       [NIX_SND_STATUS_NPC_UCAST_CHAN_ERR] = "NIX_SND_STAT_NPC_UCAST_CHAN_ERR",
+       [NIX_SND_STATUS_NPC_MCAST_CHAN_ERR] = "NIX_SND_STAT_NPC_MCAST_CHAN_ERR",
+       [NIX_SND_STATUS_NPC_MCAST_ABORT] = "NIX_SND_STATUS_NPC_MCAST_ABORT",
+       [NIX_SND_STATUS_NPC_VTAG_PTR_ERR] = "NIX_SND_STATUS_NPC_VTAG_PTR_ERR",
+       [NIX_SND_STATUS_NPC_VTAG_SIZE_ERR] = "NIX_SND_STATUS_NPC_VTAG_SIZE_ERR",
+       [NIX_SND_STATUS_SEND_MEM_FAULT] = "NIX_SND_STATUS_SEND_MEM_FAULT",
+       [NIX_SND_STATUS_SEND_STATS_ERR] = "NIX_SND_STATUS_SEND_STATS_ERR",
 };
 
 static irqreturn_t otx2_q_intr_handler(int irq, void *data)
@@ -1238,14 +1239,16 @@ static irqreturn_t otx2_q_intr_handler(int irq, void *data)
                        continue;
 
                if (val & BIT_ULL(42)) {
-                       netdev_err(pf->netdev, "CQ%lld: error reading NIX_LF_CQ_OP_INT, NIX_LF_ERR_INT 0x%llx\n",
+                       netdev_err(pf->netdev,
+                                  "CQ%lld: error reading NIX_LF_CQ_OP_INT, NIX_LF_ERR_INT 0x%llx\n",
                                   qidx, otx2_read64(pf, NIX_LF_ERR_INT));
                } else {
                        if (val & BIT_ULL(NIX_CQERRINT_DOOR_ERR))
                                netdev_err(pf->netdev, "CQ%lld: Doorbell error",
                                           qidx);
                        if (val & BIT_ULL(NIX_CQERRINT_CQE_FAULT))
-                               netdev_err(pf->netdev, "CQ%lld: Memory fault on CQE write to LLC/DRAM",
+                               netdev_err(pf->netdev,
+                                          "CQ%lld: Memory fault on CQE write to LLC/DRAM",
                                           qidx);
                }
 
@@ -1272,7 +1275,8 @@ static irqreturn_t otx2_q_intr_handler(int irq, void *data)
                             (val & NIX_SQINT_BITS));
 
                if (val & BIT_ULL(42)) {
-                       netdev_err(pf->netdev, "SQ%lld: error reading NIX_LF_SQ_OP_INT, NIX_LF_ERR_INT 0x%llx\n",
+                       netdev_err(pf->netdev,
+                                  "SQ%lld: error reading NIX_LF_SQ_OP_INT, NIX_LF_ERR_INT 0x%llx\n",
                                   qidx, otx2_read64(pf, NIX_LF_ERR_INT));
                        goto done;
                }
@@ -1282,8 +1286,11 @@ static irqreturn_t otx2_q_intr_handler(int irq, void *data)
                        goto chk_mnq_err_dbg;
 
                sq_op_err_code = FIELD_GET(GENMASK(7, 0), sq_op_err_dbg);
-               netdev_err(pf->netdev, "SQ%lld: NIX_LF_SQ_OP_ERR_DBG(%llx)  err=%s\n",
-                          qidx, sq_op_err_dbg, nix_sqoperr_e_str[sq_op_err_code]);
+               netdev_err(pf->netdev,
+                          "SQ%lld: NIX_LF_SQ_OP_ERR_DBG(0x%llx)  err=%s(%#x)\n",
+                          qidx, sq_op_err_dbg,
+                          nix_sqoperr_e_str[sq_op_err_code],
+                          sq_op_err_code);
 
                otx2_write64(pf, NIX_LF_SQ_OP_ERR_DBG, BIT_ULL(44));
 
@@ -1300,16 +1307,21 @@ chk_mnq_err_dbg:
                        goto chk_snd_err_dbg;
 
                mnq_err_code = FIELD_GET(GENMASK(7, 0), mnq_err_dbg);
-               netdev_err(pf->netdev, "SQ%lld: NIX_LF_MNQ_ERR_DBG(%llx)  err=%s\n",
-                          qidx, mnq_err_dbg,  nix_mnqerr_e_str[mnq_err_code]);
+               netdev_err(pf->netdev,
+                          "SQ%lld: NIX_LF_MNQ_ERR_DBG(0x%llx)  err=%s(%#x)\n",
+                          qidx, mnq_err_dbg,  nix_mnqerr_e_str[mnq_err_code],
+                          mnq_err_code);
                otx2_write64(pf, NIX_LF_MNQ_ERR_DBG, BIT_ULL(44));
 
 chk_snd_err_dbg:
                snd_err_dbg = otx2_read64(pf, NIX_LF_SEND_ERR_DBG);
                if (snd_err_dbg & BIT(44)) {
                        snd_err_code = FIELD_GET(GENMASK(7, 0), snd_err_dbg);
-                       netdev_err(pf->netdev, "SQ%lld: NIX_LF_SND_ERR_DBG:0x%llx err=%s\n",
-                                  qidx, snd_err_dbg, nix_snd_status_e_str[snd_err_code]);
+                       netdev_err(pf->netdev,
+                                  "SQ%lld: NIX_LF_SND_ERR_DBG:0x%llx err=%s(%#x)\n",
+                                  qidx, snd_err_dbg,
+                                  nix_snd_status_e_str[snd_err_code],
+                                  snd_err_code);
                        otx2_write64(pf, NIX_LF_SEND_ERR_DBG, BIT_ULL(44));
                }
 
@@ -1589,6 +1601,7 @@ static void otx2_free_hw_resources(struct otx2_nic *pf)
                else
                        otx2_cleanup_tx_cqes(pf, cq);
        }
+       otx2_free_pending_sqe(pf);
 
        otx2_free_sq_res(pf);
 
index fa37b9f..4e5899d 100644 (file)
@@ -318,23 +318,23 @@ enum nix_snd_status_e {
        NIX_SND_STATUS_EXT_ERR = 0x6,
        NIX_SND_STATUS_JUMP_FAULT = 0x7,
        NIX_SND_STATUS_JUMP_POISON = 0x8,
-       NIX_SND_STATUS_CRC_ERR = 0x9,
-       NIX_SND_STATUS_IMM_ERR = 0x10,
-       NIX_SND_STATUS_SG_ERR = 0x11,
-       NIX_SND_STATUS_MEM_ERR = 0x12,
-       NIX_SND_STATUS_INVALID_SUBDC = 0x13,
-       NIX_SND_STATUS_SUBDC_ORDER_ERR = 0x14,
-       NIX_SND_STATUS_DATA_FAULT = 0x15,
-       NIX_SND_STATUS_DATA_POISON = 0x16,
-       NIX_SND_STATUS_NPC_DROP_ACTION = 0x17,
-       NIX_SND_STATUS_LOCK_VIOL = 0x18,
-       NIX_SND_STATUS_NPC_UCAST_CHAN_ERR = 0x19,
-       NIX_SND_STATUS_NPC_MCAST_CHAN_ERR = 0x20,
-       NIX_SND_STATUS_NPC_MCAST_ABORT = 0x21,
-       NIX_SND_STATUS_NPC_VTAG_PTR_ERR = 0x22,
-       NIX_SND_STATUS_NPC_VTAG_SIZE_ERR = 0x23,
-       NIX_SND_STATUS_SEND_MEM_FAULT = 0x24,
-       NIX_SND_STATUS_SEND_STATS_ERR = 0x25,
+       NIX_SND_STATUS_CRC_ERR = 0x10,
+       NIX_SND_STATUS_IMM_ERR = 0x11,
+       NIX_SND_STATUS_SG_ERR = 0x12,
+       NIX_SND_STATUS_MEM_ERR = 0x13,
+       NIX_SND_STATUS_INVALID_SUBDC = 0x14,
+       NIX_SND_STATUS_SUBDC_ORDER_ERR = 0x15,
+       NIX_SND_STATUS_DATA_FAULT = 0x16,
+       NIX_SND_STATUS_DATA_POISON = 0x17,
+       NIX_SND_STATUS_NPC_DROP_ACTION = 0x20,
+       NIX_SND_STATUS_LOCK_VIOL = 0x21,
+       NIX_SND_STATUS_NPC_UCAST_CHAN_ERR = 0x22,
+       NIX_SND_STATUS_NPC_MCAST_CHAN_ERR = 0x23,
+       NIX_SND_STATUS_NPC_MCAST_ABORT = 0x24,
+       NIX_SND_STATUS_NPC_VTAG_PTR_ERR = 0x25,
+       NIX_SND_STATUS_NPC_VTAG_SIZE_ERR = 0x26,
+       NIX_SND_STATUS_SEND_MEM_FAULT = 0x27,
+       NIX_SND_STATUS_SEND_STATS_ERR = 0x28,
        NIX_SND_STATUS_MAX,
 };
 
index 53b2a4e..6ee15f3 100644 (file)
@@ -1247,9 +1247,11 @@ void otx2_cleanup_rx_cqes(struct otx2_nic *pfvf, struct otx2_cq_queue *cq, int q
 
 void otx2_cleanup_tx_cqes(struct otx2_nic *pfvf, struct otx2_cq_queue *cq)
 {
+       int tx_pkts = 0, tx_bytes = 0;
        struct sk_buff *skb = NULL;
        struct otx2_snd_queue *sq;
        struct nix_cqe_tx_s *cqe;
+       struct netdev_queue *txq;
        int processed_cqe = 0;
        struct sg_list *sg;
        int qidx;
@@ -1270,12 +1272,20 @@ void otx2_cleanup_tx_cqes(struct otx2_nic *pfvf, struct otx2_cq_queue *cq)
                sg = &sq->sg[cqe->comp.sqe_id];
                skb = (struct sk_buff *)sg->skb;
                if (skb) {
+                       tx_bytes += skb->len;
+                       tx_pkts++;
                        otx2_dma_unmap_skb_frags(pfvf, sg);
                        dev_kfree_skb_any(skb);
                        sg->skb = (u64)NULL;
                }
        }
 
+       if (likely(tx_pkts)) {
+               if (qidx >= pfvf->hw.tx_queues)
+                       qidx -= pfvf->hw.xdp_queues;
+               txq = netdev_get_tx_queue(pfvf->netdev, qidx);
+               netdev_tx_completed_queue(txq, tx_pkts, tx_bytes);
+       }
        /* Free CQEs to HW */
        otx2_write64(pfvf, NIX_LF_CQ_OP_DOOR,
                     ((u64)cq->cq_idx << 32) | processed_cqe);
@@ -1302,6 +1312,38 @@ int otx2_rxtx_enable(struct otx2_nic *pfvf, bool enable)
        return err;
 }
 
+void otx2_free_pending_sqe(struct otx2_nic *pfvf)
+{
+       int tx_pkts = 0, tx_bytes = 0;
+       struct sk_buff *skb = NULL;
+       struct otx2_snd_queue *sq;
+       struct netdev_queue *txq;
+       struct sg_list *sg;
+       int sq_idx, sqe;
+
+       for (sq_idx = 0; sq_idx < pfvf->hw.tx_queues; sq_idx++) {
+               sq = &pfvf->qset.sq[sq_idx];
+               for (sqe = 0; sqe < sq->sqe_cnt; sqe++) {
+                       sg = &sq->sg[sqe];
+                       skb = (struct sk_buff *)sg->skb;
+                       if (skb) {
+                               tx_bytes += skb->len;
+                               tx_pkts++;
+                               otx2_dma_unmap_skb_frags(pfvf, sg);
+                               dev_kfree_skb_any(skb);
+                               sg->skb = (u64)NULL;
+                       }
+               }
+
+               if (!tx_pkts)
+                       continue;
+               txq = netdev_get_tx_queue(pfvf->netdev, sq_idx);
+               netdev_tx_completed_queue(txq, tx_pkts, tx_bytes);
+               tx_pkts = 0;
+               tx_bytes = 0;
+       }
+}
+
 static void otx2_xdp_sqe_add_sg(struct otx2_snd_queue *sq, u64 dma_addr,
                                int len, int *offset)
 {
index a987def..0c76c16 100644 (file)
@@ -2582,9 +2582,13 @@ static void rtl_set_rx_mode(struct net_device *dev)
 
        if (dev->flags & IFF_PROMISC) {
                rx_mode |= AcceptAllPhys;
+       } else if (!(dev->flags & IFF_MULTICAST)) {
+               rx_mode &= ~AcceptMulticast;
        } else if (netdev_mc_count(dev) > MC_FILTER_LIMIT ||
                   dev->flags & IFF_ALLMULTI ||
-                  tp->mac_version == RTL_GIGA_MAC_VER_35) {
+                  tp->mac_version == RTL_GIGA_MAC_VER_35 ||
+                  tp->mac_version == RTL_GIGA_MAC_VER_46 ||
+                  tp->mac_version == RTL_GIGA_MAC_VER_48) {
                /* accept all multicasts */
        } else if (netdev_mc_empty(dev)) {
                rx_mode &= ~AcceptMulticast;
index 7a8f47e..a4e8b49 100644 (file)
        ((val) << XGMAC_PPS_MINIDX(x))
 #define XGMAC_PPSCMD_START             0x2
 #define XGMAC_PPSCMD_STOP              0x5
-#define XGMAC_PPSEN0                   BIT(4)
+#define XGMAC_PPSENx(x)                        BIT(4 + (x) * 8)
 #define XGMAC_PPSx_TARGET_TIME_SEC(x)  (0x00000d80 + (x) * 0x10)
 #define XGMAC_PPSx_TARGET_TIME_NSEC(x) (0x00000d84 + (x) * 0x10)
 #define XGMAC_TRGTBUSY0                        BIT(31)
index f352be2..453e88b 100644 (file)
@@ -1178,7 +1178,19 @@ static int dwxgmac2_flex_pps_config(void __iomem *ioaddr, int index,
 
        val |= XGMAC_PPSCMDx(index, XGMAC_PPSCMD_START);
        val |= XGMAC_TRGTMODSELx(index, XGMAC_PPSCMD_START);
-       val |= XGMAC_PPSEN0;
+
+       /* XGMAC Core has 4 PPS outputs at most.
+        *
+        * Prior XGMAC Core 3.20, Fixed mode or Flexible mode are selectable for
+        * PPS0 only via PPSEN0. PPS{1,2,3} are in Flexible mode by default,
+        * and can not be switched to Fixed mode, since PPSEN{1,2,3} are
+        * read-only reserved to 0.
+        * But we always set PPSEN{1,2,3} do not make things worse ;-)
+        *
+        * From XGMAC Core 3.20 and later, PPSEN{0,1,2,3} are writable and must
+        * be set, or the PPS outputs stay in Fixed PPS mode by default.
+        */
+       val |= XGMAC_PPSENx(index);
 
        writel(cfg->start.tv_sec, ioaddr + XGMAC_PPSx_TARGET_TIME_SEC(index));
 
index 2412060..ece9f8d 100644 (file)
@@ -1588,10 +1588,10 @@ static void am65_cpsw_nuss_mac_link_up(struct phylink_config *config, struct phy
 
        /* rx_pause/tx_pause */
        if (rx_pause)
-               mac_control |= CPSW_SL_CTL_RX_FLOW_EN;
+               mac_control |= CPSW_SL_CTL_TX_FLOW_EN;
 
        if (tx_pause)
-               mac_control |= CPSW_SL_CTL_TX_FLOW_EN;
+               mac_control |= CPSW_SL_CTL_RX_FLOW_EN;
 
        cpsw_sl_ctl_set(port->slave.mac_sl, mac_control);
 
index 4cf2a52..3025e9c 100644 (file)
@@ -177,7 +177,7 @@ static void icss_iep_set_counter(struct icss_iep *iep, u64 ns)
        if (iep->plat_data->flags & ICSS_IEP_64BIT_COUNTER_SUPPORT)
                writel(upper_32_bits(ns), iep->base +
                       iep->plat_data->reg_offs[ICSS_IEP_COUNT_REG1]);
-       writel(upper_32_bits(ns), iep->base + iep->plat_data->reg_offs[ICSS_IEP_COUNT_REG0]);
+       writel(lower_32_bits(ns), iep->base + iep->plat_data->reg_offs[ICSS_IEP_COUNT_REG0]);
 }
 
 static void icss_iep_update_to_next_boundary(struct icss_iep *iep, u64 start_ns);
index 531bf91..e0d2614 100644 (file)
@@ -163,7 +163,6 @@ typedef void buffer_t;
 
 /* Information about built-in Ethernet MAC interfaces */
 struct eth_plat_info {
-       u8 phy;         /* MII PHY ID, 0 - 31 */
        u8 rxq;         /* configurable, currently 0 - 31 only */
        u8 txreadyq;
        u8 hwaddr[ETH_ALEN];
@@ -1583,7 +1582,7 @@ static int ixp4xx_eth_probe(struct platform_device *pdev)
        if ((err = register_netdev(ndev)))
                goto err_phy_dis;
 
-       netdev_info(ndev, "%s: MII PHY %i on %s\n", ndev->name, plat->phy,
+       netdev_info(ndev, "%s: MII PHY %s on %s\n", ndev->name, phydev_name(phydev),
                    npe_name(port->npe));
 
        return 0;
index 4630dde..5d0f11f 100644 (file)
@@ -16,6 +16,7 @@
 
 MODULE_AUTHOR("Calvin Johnson <calvin.johnson@oss.nxp.com>");
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ACPI MDIO bus (Ethernet PHY) accessors");
 
 /**
  * __acpi_mdiobus_register - Register mii_bus and create PHYs from the ACPI ASL.
index 1183ef5..fd02f5c 100644 (file)
@@ -14,6 +14,7 @@
 
 MODULE_AUTHOR("Calvin Johnson <calvin.johnson@oss.nxp.com>");
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("FWNODE MDIO bus (Ethernet PHY) accessors");
 
 static struct pse_control *
 fwnode_find_pse_control(struct fwnode_handle *fwnode)
index 70edeeb..c217065 100644 (file)
@@ -205,3 +205,4 @@ module_platform_driver(aspeed_mdio_driver);
 
 MODULE_AUTHOR("Andrew Jeffery <andrew@aj.id.au>");
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ASPEED MDIO bus controller");
index 81b7748..f886392 100644 (file)
@@ -263,3 +263,4 @@ void free_mdio_bitbang(struct mii_bus *bus)
 EXPORT_SYMBOL(free_mdio_bitbang);
 
 MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Bitbanged MDIO buses");
index 7eb32eb..64ebcb6 100644 (file)
@@ -25,6 +25,7 @@
 
 MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("OpenFirmware MDIO bus (Ethernet PHY) accessors");
 
 /* Extract the clause 22 phy ID from the compatible string of the form
  * ethernet-phy-idAAAA.BBBB */
index ef00d61..cb4b91a 100644 (file)
@@ -942,3 +942,4 @@ struct bcm_ptp_private *bcm_ptp_probe(struct phy_device *phydev)
 EXPORT_SYMBOL_GPL(bcm_ptp_probe);
 
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Broadcom PHY PTP driver");
index cc28581..e81404b 100644 (file)
@@ -223,3 +223,4 @@ static struct phy_driver bcm87xx_driver[] = {
 module_phy_driver(bcm87xx_driver);
 
 MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Broadcom BCM87xx PHY driver");
index 6712883..25c1949 100644 (file)
@@ -1616,6 +1616,7 @@ struct phylink *phylink_create(struct phylink_config *config,
        pl->config = config;
        if (config->type == PHYLINK_NETDEV) {
                pl->netdev = to_net_dev(config->dev);
+               netif_carrier_off(pl->netdev);
        } else if (config->type == PHYLINK_DEV) {
                pl->dev = config->dev;
        } else {
@@ -3726,3 +3727,4 @@ static int __init phylink_init(void)
 module_init(phylink_init);
 
 MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("phylink models the MAC to optional PHY connection");
index b8c0961..5468bd2 100644 (file)
@@ -3153,3 +3153,4 @@ module_exit(sfp_exit);
 MODULE_ALIAS("platform:sfp");
 MODULE_AUTHOR("Russell King");
 MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("SFP cage support");
index a9beacd..0193af2 100644 (file)
@@ -570,8 +570,8 @@ static struct bpf_prog *get_filter(struct sock_fprog *uprog)
 
        /* uprog->len is unsigned short, so no overflow here */
        fprog.len = uprog->len;
-       fprog.filter = memdup_user(uprog->filter,
-                                  uprog->len * sizeof(struct sock_filter));
+       fprog.filter = memdup_array_user(uprog->filter,
+                                        uprog->len, sizeof(struct sock_filter));
        if (IS_ERR(fprog.filter))
                return ERR_CAST(fprog.filter);
 
index 282cd7d..3f7a747 100644 (file)
@@ -108,6 +108,7 @@ int ptp_open(struct posix_clock_context *pccontext, fmode_t fmode)
                container_of(pccontext->clk, struct ptp_clock, clock);
        struct timestamp_event_queue *queue;
        char debugfsname[32];
+       unsigned long flags;
 
        queue = kzalloc(sizeof(*queue), GFP_KERNEL);
        if (!queue)
@@ -119,7 +120,9 @@ int ptp_open(struct posix_clock_context *pccontext, fmode_t fmode)
        }
        bitmap_set(queue->mask, 0, PTP_MAX_CHANNELS);
        spin_lock_init(&queue->lock);
+       spin_lock_irqsave(&ptp->tsevqs_lock, flags);
        list_add_tail(&queue->qlist, &ptp->tsevqs);
+       spin_unlock_irqrestore(&ptp->tsevqs_lock, flags);
        pccontext->private_clkdata = queue;
 
        /* Debugfs contents */
@@ -139,16 +142,16 @@ int ptp_release(struct posix_clock_context *pccontext)
 {
        struct timestamp_event_queue *queue = pccontext->private_clkdata;
        unsigned long flags;
+       struct ptp_clock *ptp =
+               container_of(pccontext->clk, struct ptp_clock, clock);
 
-       if (queue) {
-               debugfs_remove(queue->debugfs_instance);
-               pccontext->private_clkdata = NULL;
-               spin_lock_irqsave(&queue->lock, flags);
-               list_del(&queue->qlist);
-               spin_unlock_irqrestore(&queue->lock, flags);
-               bitmap_free(queue->mask);
-               kfree(queue);
-       }
+       debugfs_remove(queue->debugfs_instance);
+       pccontext->private_clkdata = NULL;
+       spin_lock_irqsave(&ptp->tsevqs_lock, flags);
+       list_del(&queue->qlist);
+       spin_unlock_irqrestore(&ptp->tsevqs_lock, flags);
+       bitmap_free(queue->mask);
+       kfree(queue);
        return 0;
 }
 
@@ -585,7 +588,5 @@ ssize_t ptp_read(struct posix_clock_context *pccontext, uint rdflags,
 free_event:
        kfree(event);
 exit:
-       if (result < 0)
-               ptp_release(pccontext);
        return result;
 }
index 3d1b0a9..3134568 100644 (file)
@@ -179,11 +179,11 @@ static void ptp_clock_release(struct device *dev)
        mutex_destroy(&ptp->pincfg_mux);
        mutex_destroy(&ptp->n_vclocks_mux);
        /* Delete first entry */
+       spin_lock_irqsave(&ptp->tsevqs_lock, flags);
        tsevq = list_first_entry(&ptp->tsevqs, struct timestamp_event_queue,
                                 qlist);
-       spin_lock_irqsave(&tsevq->lock, flags);
        list_del(&tsevq->qlist);
-       spin_unlock_irqrestore(&tsevq->lock, flags);
+       spin_unlock_irqrestore(&ptp->tsevqs_lock, flags);
        bitmap_free(tsevq->mask);
        kfree(tsevq);
        debugfs_remove(ptp->debugfs_root);
@@ -247,6 +247,7 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info,
        if (!queue)
                goto no_memory_queue;
        list_add_tail(&queue->qlist, &ptp->tsevqs);
+       spin_lock_init(&ptp->tsevqs_lock);
        queue->mask = bitmap_alloc(PTP_MAX_CHANNELS, GFP_KERNEL);
        if (!queue->mask)
                goto no_memory_bitmap;
@@ -407,6 +408,7 @@ void ptp_clock_event(struct ptp_clock *ptp, struct ptp_clock_event *event)
 {
        struct timestamp_event_queue *tsevq;
        struct pps_event_time evt;
+       unsigned long flags;
 
        switch (event->type) {
 
@@ -415,10 +417,12 @@ void ptp_clock_event(struct ptp_clock *ptp, struct ptp_clock_event *event)
 
        case PTP_CLOCK_EXTTS:
                /* Enqueue timestamp on selected queues */
+               spin_lock_irqsave(&ptp->tsevqs_lock, flags);
                list_for_each_entry(tsevq, &ptp->tsevqs, qlist) {
                        if (test_bit((unsigned int)event->index, tsevq->mask))
                                enqueue_external_timestamp(tsevq, event);
                }
+               spin_unlock_irqrestore(&ptp->tsevqs_lock, flags);
                wake_up_interruptible(&ptp->tsev_wq);
                break;
 
index 52f87e3..35fde0a 100644 (file)
@@ -44,6 +44,7 @@ struct ptp_clock {
        struct pps_device *pps_source;
        long dialed_frequency; /* remembers the frequency adjustment */
        struct list_head tsevqs; /* timestamp fifo list */
+       spinlock_t tsevqs_lock; /* protects tsevqs from concurrent access */
        struct mutex pincfg_mux; /* protect concurrent info->pin_config access */
        wait_queue_head_t tsev_wq;
        int defunct; /* tells readers to go away when clock is being removed */
index 6af2511..cf8506d 100644 (file)
@@ -3675,7 +3675,7 @@ static void qeth_flush_queue(struct qeth_qdio_out_q *queue)
 static void qeth_check_outbound_queue(struct qeth_qdio_out_q *queue)
 {
        /*
-        * check if weed have to switch to non-packing mode or if
+        * check if we have to switch to non-packing mode or if
         * we have to get a pci flag out on the queue
         */
        if ((atomic_read(&queue->used_buffers) <= QETH_LOW_WATERMARK_PACK) ||
index c2231c6..59d404e 100644 (file)
  */
 #define __bpf_kfunc __used noinline
 
+#define __bpf_kfunc_start_defs()                                              \
+       __diag_push();                                                         \
+       __diag_ignore_all("-Wmissing-declarations",                            \
+                         "Global kfuncs as their definitions will be in BTF");\
+       __diag_ignore_all("-Wmissing-prototypes",                              \
+                         "Global kfuncs as their definitions will be in BTF")
+
+#define __bpf_kfunc_end_defs() __diag_pop()
+#define __bpf_hook_start() __bpf_kfunc_start_defs()
+#define __bpf_hook_end() __bpf_kfunc_end_defs()
+
 /*
  * Return the name of the passed struct, if exists, or halt the build if for
  * example the structure gets renamed. In this way, developers have to revisit
index 226a36e..6890282 100644 (file)
@@ -1045,10 +1045,10 @@ static inline int ethtool_mm_frag_size_min_to_add(u32 val_min, u32 *val_add,
 
 /**
  * ethtool_sprintf - Write formatted string to ethtool string data
- * @data: Pointer to start of string to update
+ * @data: Pointer to a pointer to the start of string to update
  * @fmt: Format of string to write
  *
- * Write formatted string to data. Update data to point at start of
+ * Write formatted string to *data. Update *data to point at start of
  * next string.
  */
 extern __printf(2, 3) void ethtool_sprintf(u8 **data, const char *fmt, ...);
index a0dce14..da5f5fa 100644 (file)
@@ -200,7 +200,7 @@ static inline void idr_preload_end(void)
  */
 #define idr_for_each_entry_ul(idr, entry, tmp, id)                     \
        for (tmp = 0, id = 0;                                           \
-            tmp <= id && ((entry) = idr_get_next_ul(idr, &(id))) != NULL; \
+            ((entry) = tmp <= id ? idr_get_next_ul(idr, &(id)) : NULL) != NULL; \
             tmp = id, ++id)
 
 /**
@@ -224,10 +224,12 @@ static inline void idr_preload_end(void)
  * @id: Entry ID.
  *
  * Continue to iterate over entries, continuing after the current position.
+ * After normal termination @entry is left with the value NULL.  This
+ * is convenient for a "not found" value.
  */
 #define idr_for_each_entry_continue_ul(idr, entry, tmp, id)            \
        for (tmp = id;                                                  \
-            tmp <= id && ((entry) = idr_get_next_ul(idr, &(id))) != NULL; \
+            ((entry) = tmp <= id ? idr_get_next_ul(idr, &(id)) : NULL) != NULL; \
             tmp = id, ++id)
 
 /*
index ec4e936..68f3d31 100644 (file)
@@ -152,7 +152,7 @@ struct tcp_request_sock {
        u64                             snt_synack; /* first SYNACK sent time */
        bool                            tfo_listener;
        bool                            is_mptcp;
-       s8                              req_usec_ts;
+       bool                            req_usec_ts;
 #if IS_ENABLED(CONFIG_MPTCP)
        bool                            drop_req;
 #endif
index 7f0adda..335bbc5 100644 (file)
@@ -40,8 +40,8 @@ struct flowi_common {
 #define FLOWI_FLAG_KNOWN_NH            0x02
        __u32   flowic_secid;
        kuid_t  flowic_uid;
-       struct flowi_tunnel flowic_tun_key;
        __u32           flowic_multipath_hash;
+       struct flowi_tunnel flowic_tun_key;
 };
 
 union flowi_uli {
index 078d3c5..e5f2f0b 100644 (file)
@@ -20,7 +20,22 @@ static inline struct nf_conn_act_ct_ext *nf_conn_act_ct_ext_find(const struct nf
 #endif
 }
 
-static inline struct nf_conn_act_ct_ext *nf_conn_act_ct_ext_add(struct nf_conn *ct)
+static inline void nf_conn_act_ct_ext_fill(struct sk_buff *skb, struct nf_conn *ct,
+                                          enum ip_conntrack_info ctinfo)
+{
+#if IS_ENABLED(CONFIG_NET_ACT_CT)
+       struct nf_conn_act_ct_ext *act_ct_ext;
+
+       act_ct_ext = nf_conn_act_ct_ext_find(ct);
+       if (dev_net(skb->dev) == &init_net && act_ct_ext)
+               act_ct_ext->ifindex[CTINFO2DIR(ctinfo)] = skb->dev->ifindex;
+#endif
+}
+
+static inline struct
+nf_conn_act_ct_ext *nf_conn_act_ct_ext_add(struct sk_buff *skb,
+                                          struct nf_conn *ct,
+                                          enum ip_conntrack_info ctinfo)
 {
 #if IS_ENABLED(CONFIG_NET_ACT_CT)
        struct nf_conn_act_ct_ext *act_ct = nf_ct_ext_find(ct, NF_CT_EXT_ACT_CT);
@@ -29,22 +44,11 @@ static inline struct nf_conn_act_ct_ext *nf_conn_act_ct_ext_add(struct nf_conn *
                return act_ct;
 
        act_ct = nf_ct_ext_add(ct, NF_CT_EXT_ACT_CT, GFP_ATOMIC);
+       nf_conn_act_ct_ext_fill(skb, ct, ctinfo);
        return act_ct;
 #else
        return NULL;
 #endif
 }
 
-static inline void nf_conn_act_ct_ext_fill(struct sk_buff *skb, struct nf_conn *ct,
-                                          enum ip_conntrack_info ctinfo)
-{
-#if IS_ENABLED(CONFIG_NET_ACT_CT)
-       struct nf_conn_act_ct_ext *act_ct_ext;
-
-       act_ct_ext = nf_conn_act_ct_ext_find(ct);
-       if (dev_net(skb->dev) == &init_net && act_ct_ext)
-               act_ct_ext->ifindex[CTINFO2DIR(ctinfo)] = skb->dev->ifindex;
-#endif
-}
-
 #endif /* _NF_CONNTRACK_ACT_CT_H */
index a375a17..b56be10 100644 (file)
@@ -124,7 +124,7 @@ struct tcp_ao_info {
 #define tcp_hash_fail(msg, family, skb, fmt, ...)                      \
 do {                                                                   \
        const struct tcphdr *th = tcp_hdr(skb);                         \
-       char hdr_flags[5] = {};                                         \
+       char hdr_flags[6];                                              \
        char *f = hdr_flags;                                            \
                                                                        \
        if (th->fin)                                                    \
@@ -133,17 +133,18 @@ do {                                                                      \
                *f++ = 'S';                                             \
        if (th->rst)                                                    \
                *f++ = 'R';                                             \
+       if (th->psh)                                                    \
+               *f++ = 'P';                                             \
        if (th->ack)                                                    \
-               *f++ = 'A';                                             \
-       if (f != hdr_flags)                                             \
-               *f = ' ';                                               \
+               *f++ = '.';                                             \
+       *f = 0;                                                         \
        if ((family) == AF_INET) {                                      \
-               net_info_ratelimited("%s for (%pI4, %d)->(%pI4, %d) %s" fmt "\n", \
+               net_info_ratelimited("%s for %pI4.%d->%pI4.%d [%s] " fmt "\n", \
                                msg, &ip_hdr(skb)->saddr, ntohs(th->source), \
                                &ip_hdr(skb)->daddr, ntohs(th->dest),   \
                                hdr_flags, ##__VA_ARGS__);              \
        } else {                                                        \
-               net_info_ratelimited("%s for [%pI6c]:%u->[%pI6c]:%u %s" fmt "\n", \
+               net_info_ratelimited("%s for [%pI6c].%d->[%pI6c].%d [%s]" fmt "\n", \
                                msg, &ipv6_hdr(skb)->saddr, ntohs(th->source), \
                                &ipv6_hdr(skb)->daddr, ntohs(th->dest), \
                                hdr_flags, ##__VA_ARGS__);              \
index c8ae724..3cd044e 100644 (file)
@@ -3,8 +3,8 @@
 /*     Documentation/netlink/specs/nfsd.yaml */
 /* YNL-GEN uapi header */
 
-#ifndef _UAPI_LINUX_NFSD_H
-#define _UAPI_LINUX_NFSD_H
+#ifndef _UAPI_LINUX_NFSD_NETLINK_H
+#define _UAPI_LINUX_NFSD_NETLINK_H
 
 #define NFSD_FAMILY_NAME       "nfsd"
 #define NFSD_FAMILY_VERSION    1
@@ -36,4 +36,4 @@ enum {
        NFSD_CMD_MAX = (__NFSD_CMD_MAX - 1)
 };
 
-#endif /* _UAPI_LINUX_NFSD_H */
+#endif /* _UAPI_LINUX_NFSD_NETLINK_H */
index 833faa0..0fae791 100644 (file)
@@ -782,9 +782,7 @@ struct bpf_iter_num_kern {
        int end; /* final value, exclusive */
 } __aligned(8);
 
-__diag_push();
-__diag_ignore_all("-Wmissing-prototypes",
-                 "Global functions as their definitions will be in vmlinux BTF");
+__bpf_kfunc_start_defs();
 
 __bpf_kfunc int bpf_iter_num_new(struct bpf_iter_num *it, int start, int end)
 {
@@ -843,4 +841,4 @@ __bpf_kfunc void bpf_iter_num_destroy(struct bpf_iter_num *it)
        s->cur = s->end = 0;
 }
 
-__diag_pop();
+__bpf_kfunc_end_defs();
index 209e513..f04a468 100644 (file)
@@ -282,7 +282,7 @@ static struct bpf_iter_reg bpf_cgroup_reg_info = {
        .ctx_arg_info_size      = 1,
        .ctx_arg_info           = {
                { offsetof(struct bpf_iter__cgroup, cgroup),
-                 PTR_TO_BTF_ID_OR_NULL },
+                 PTR_TO_BTF_ID_OR_NULL | PTR_TRUSTED },
        },
        .seq_info               = &cgroup_iter_seq_info,
 };
@@ -305,9 +305,7 @@ struct bpf_iter_css_kern {
        unsigned int flags;
 } __attribute__((aligned(8)));
 
-__diag_push();
-__diag_ignore_all("-Wmissing-prototypes",
-               "Global functions as their definitions will be in vmlinux BTF");
+__bpf_kfunc_start_defs();
 
 __bpf_kfunc int bpf_iter_css_new(struct bpf_iter_css *it,
                struct cgroup_subsys_state *start, unsigned int flags)
@@ -358,4 +356,4 @@ __bpf_kfunc void bpf_iter_css_destroy(struct bpf_iter_css *it)
 {
 }
 
-__diag_pop();
\ No newline at end of file
+__bpf_kfunc_end_defs();
index 6983af8..e01c741 100644 (file)
@@ -34,9 +34,7 @@ static bool cpu_valid(u32 cpu)
        return cpu < nr_cpu_ids;
 }
 
-__diag_push();
-__diag_ignore_all("-Wmissing-prototypes",
-                 "Global kfuncs as their definitions will be in BTF");
+__bpf_kfunc_start_defs();
 
 /**
  * bpf_cpumask_create() - Create a mutable BPF cpumask.
@@ -407,7 +405,7 @@ __bpf_kfunc u32 bpf_cpumask_any_and_distribute(const struct cpumask *src1,
        return cpumask_any_and_distribute(src1, src2);
 }
 
-__diag_pop();
+__bpf_kfunc_end_defs();
 
 BTF_SET8_START(cpumask_kfunc_btf_ids)
 BTF_ID_FLAGS(func, bpf_cpumask_create, KF_ACQUIRE | KF_RET_NULL)
index e46ac28..56b0c1f 100644 (file)
@@ -1177,13 +1177,6 @@ BPF_CALL_3(bpf_timer_init, struct bpf_timer_kern *, timer, struct bpf_map *, map
                ret = -EBUSY;
                goto out;
        }
-       if (!atomic64_read(&map->usercnt)) {
-               /* maps with timers must be either held by user space
-                * or pinned in bpffs.
-                */
-               ret = -EPERM;
-               goto out;
-       }
        /* allocate hrtimer via map_kmalloc to use memcg accounting */
        t = bpf_map_kmalloc_node(map, sizeof(*t), GFP_ATOMIC, map->numa_node);
        if (!t) {
@@ -1196,7 +1189,21 @@ BPF_CALL_3(bpf_timer_init, struct bpf_timer_kern *, timer, struct bpf_map *, map
        rcu_assign_pointer(t->callback_fn, NULL);
        hrtimer_init(&t->timer, clockid, HRTIMER_MODE_REL_SOFT);
        t->timer.function = bpf_timer_cb;
-       timer->timer = t;
+       WRITE_ONCE(timer->timer, t);
+       /* Guarantee the order between timer->timer and map->usercnt. So
+        * when there are concurrent uref release and bpf timer init, either
+        * bpf_timer_cancel_and_free() called by uref release reads a no-NULL
+        * timer or atomic64_read() below returns a zero usercnt.
+        */
+       smp_mb();
+       if (!atomic64_read(&map->usercnt)) {
+               /* maps with timers must be either held by user space
+                * or pinned in bpffs.
+                */
+               WRITE_ONCE(timer->timer, NULL);
+               kfree(t);
+               ret = -EPERM;
+       }
 out:
        __bpf_spin_unlock_irqrestore(&timer->lock);
        return ret;
@@ -1374,7 +1381,7 @@ void bpf_timer_cancel_and_free(void *val)
        /* The subsequent bpf_timer_start/cancel() helpers won't be able to use
         * this timer, since it won't be initialized.
         */
-       timer->timer = NULL;
+       WRITE_ONCE(timer->timer, NULL);
 out:
        __bpf_spin_unlock_irqrestore(&timer->lock);
        if (!t)
@@ -1886,9 +1893,7 @@ void bpf_rb_root_free(const struct btf_field *field, void *rb_root,
        }
 }
 
-__diag_push();
-__diag_ignore_all("-Wmissing-prototypes",
-                 "Global functions as their definitions will be in vmlinux BTF");
+__bpf_kfunc_start_defs();
 
 __bpf_kfunc void *bpf_obj_new_impl(u64 local_type_id__k, void *meta__ign)
 {
@@ -2505,7 +2510,7 @@ __bpf_kfunc void bpf_throw(u64 cookie)
        WARN(1, "A call to BPF exception callback should never return\n");
 }
 
-__diag_pop();
+__bpf_kfunc_end_defs();
 
 BTF_SET8_START(generic_btf_ids)
 #ifdef CONFIG_KEXEC_CORE
@@ -2564,15 +2569,17 @@ BTF_ID_FLAGS(func, bpf_iter_num_destroy, KF_ITER_DESTROY)
 BTF_ID_FLAGS(func, bpf_iter_task_vma_new, KF_ITER_NEW | KF_RCU)
 BTF_ID_FLAGS(func, bpf_iter_task_vma_next, KF_ITER_NEXT | KF_RET_NULL)
 BTF_ID_FLAGS(func, bpf_iter_task_vma_destroy, KF_ITER_DESTROY)
+#ifdef CONFIG_CGROUPS
 BTF_ID_FLAGS(func, bpf_iter_css_task_new, KF_ITER_NEW | KF_TRUSTED_ARGS)
 BTF_ID_FLAGS(func, bpf_iter_css_task_next, KF_ITER_NEXT | KF_RET_NULL)
 BTF_ID_FLAGS(func, bpf_iter_css_task_destroy, KF_ITER_DESTROY)
-BTF_ID_FLAGS(func, bpf_iter_task_new, KF_ITER_NEW | KF_TRUSTED_ARGS | KF_RCU_PROTECTED)
-BTF_ID_FLAGS(func, bpf_iter_task_next, KF_ITER_NEXT | KF_RET_NULL)
-BTF_ID_FLAGS(func, bpf_iter_task_destroy, KF_ITER_DESTROY)
 BTF_ID_FLAGS(func, bpf_iter_css_new, KF_ITER_NEW | KF_TRUSTED_ARGS | KF_RCU_PROTECTED)
 BTF_ID_FLAGS(func, bpf_iter_css_next, KF_ITER_NEXT | KF_RET_NULL)
 BTF_ID_FLAGS(func, bpf_iter_css_destroy, KF_ITER_DESTROY)
+#endif
+BTF_ID_FLAGS(func, bpf_iter_task_new, KF_ITER_NEW | KF_TRUSTED_ARGS | KF_RCU_PROTECTED)
+BTF_ID_FLAGS(func, bpf_iter_task_next, KF_ITER_NEXT | KF_RET_NULL)
+BTF_ID_FLAGS(func, bpf_iter_task_destroy, KF_ITER_DESTROY)
 BTF_ID_FLAGS(func, bpf_dynptr_adjust)
 BTF_ID_FLAGS(func, bpf_dynptr_is_null)
 BTF_ID_FLAGS(func, bpf_dynptr_is_rdonly)
index 6fc9dae..6abd7c5 100644 (file)
@@ -193,9 +193,7 @@ static int __init bpf_map_iter_init(void)
 
 late_initcall(bpf_map_iter_init);
 
-__diag_push();
-__diag_ignore_all("-Wmissing-prototypes",
-                 "Global functions as their definitions will be in vmlinux BTF");
+__bpf_kfunc_start_defs();
 
 __bpf_kfunc s64 bpf_map_sum_elem_count(const struct bpf_map *map)
 {
@@ -213,7 +211,7 @@ __bpf_kfunc s64 bpf_map_sum_elem_count(const struct bpf_map *map)
        return ret;
 }
 
-__diag_pop();
+__bpf_kfunc_end_defs();
 
 BTF_SET8_START(bpf_map_iter_kfunc_ids)
 BTF_ID_FLAGS(func, bpf_map_sum_elem_count, KF_TRUSTED_ARGS)
index 654601d..26082b9 100644 (file)
@@ -704,7 +704,7 @@ static struct bpf_iter_reg task_reg_info = {
        .ctx_arg_info_size      = 1,
        .ctx_arg_info           = {
                { offsetof(struct bpf_iter__task, task),
-                 PTR_TO_BTF_ID_OR_NULL },
+                 PTR_TO_BTF_ID_OR_NULL | PTR_TRUSTED },
        },
        .seq_info               = &task_seq_info,
        .fill_link_info         = bpf_iter_fill_link_info,
@@ -822,9 +822,7 @@ struct bpf_iter_task_vma_kern {
        struct bpf_iter_task_vma_kern_data *data;
 } __attribute__((aligned(8)));
 
-__diag_push();
-__diag_ignore_all("-Wmissing-prototypes",
-                 "Global functions as their definitions will be in vmlinux BTF");
+__bpf_kfunc_start_defs();
 
 __bpf_kfunc int bpf_iter_task_vma_new(struct bpf_iter_task_vma *it,
                                      struct task_struct *task, u64 addr)
@@ -890,7 +888,9 @@ __bpf_kfunc void bpf_iter_task_vma_destroy(struct bpf_iter_task_vma *it)
        }
 }
 
-__diag_pop();
+__bpf_kfunc_end_defs();
+
+#ifdef CONFIG_CGROUPS
 
 struct bpf_iter_css_task {
        __u64 __opaque[1];
@@ -900,9 +900,7 @@ struct bpf_iter_css_task_kern {
        struct css_task_iter *css_it;
 } __attribute__((aligned(8)));
 
-__diag_push();
-__diag_ignore_all("-Wmissing-prototypes",
-                 "Global functions as their definitions will be in vmlinux BTF");
+__bpf_kfunc_start_defs();
 
 __bpf_kfunc int bpf_iter_css_task_new(struct bpf_iter_css_task *it,
                struct cgroup_subsys_state *css, unsigned int flags)
@@ -948,7 +946,9 @@ __bpf_kfunc void bpf_iter_css_task_destroy(struct bpf_iter_css_task *it)
        bpf_mem_free(&bpf_global_ma, kit->css_it);
 }
 
-__diag_pop();
+__bpf_kfunc_end_defs();
+
+#endif /* CONFIG_CGROUPS */
 
 struct bpf_iter_task {
        __u64 __opaque[3];
@@ -969,9 +969,7 @@ enum {
        BPF_TASK_ITER_PROC_THREADS
 };
 
-__diag_push();
-__diag_ignore_all("-Wmissing-prototypes",
-                 "Global functions as their definitions will be in vmlinux BTF");
+__bpf_kfunc_start_defs();
 
 __bpf_kfunc int bpf_iter_task_new(struct bpf_iter_task *it,
                struct task_struct *task__nullable, unsigned int flags)
@@ -1041,7 +1039,7 @@ __bpf_kfunc void bpf_iter_task_destroy(struct bpf_iter_task *it)
 {
 }
 
-__diag_pop();
+__bpf_kfunc_end_defs();
 
 DEFINE_PER_CPU(struct mmap_unlock_irq_work, mmap_unlock_work);
 
index 857d766..bd1c42e 100644 (file)
@@ -3742,7 +3742,12 @@ static int backtrack_insn(struct bpf_verifier_env *env, int idx, int subseq_idx,
        if (class == BPF_ALU || class == BPF_ALU64) {
                if (!bt_is_reg_set(bt, dreg))
                        return 0;
-               if (opcode == BPF_MOV) {
+               if (opcode == BPF_END || opcode == BPF_NEG) {
+                       /* sreg is reserved and unused
+                        * dreg still need precision before this insn
+                        */
+                       return 0;
+               } else if (opcode == BPF_MOV) {
                        if (BPF_SRC(insn->code) == BPF_X) {
                                /* dreg = sreg or dreg = (s8, s16, s32)sreg
                                 * dreg needs precision after this insn
@@ -4674,7 +4679,7 @@ static int check_stack_write_fixed_off(struct bpf_verifier_env *env,
                   insn->imm != 0 && env->bpf_capable) {
                struct bpf_reg_state fake_reg = {};
 
-               __mark_reg_known(&fake_reg, (u32)insn->imm);
+               __mark_reg_known(&fake_reg, insn->imm);
                fake_reg.type = SCALAR_VALUE;
                save_register_state(state, spi, &fake_reg, size);
        } else if (reg && is_spillable_regtype(reg->type)) {
@@ -5388,7 +5393,9 @@ static bool in_rcu_cs(struct bpf_verifier_env *env)
 /* Once GCC supports btf_type_tag the following mechanism will be replaced with tag check */
 BTF_SET_START(rcu_protected_types)
 BTF_ID(struct, prog_test_ref_kfunc)
+#ifdef CONFIG_CGROUPS
 BTF_ID(struct, cgroup)
+#endif
 BTF_ID(struct, bpf_cpumask)
 BTF_ID(struct, task_struct)
 BTF_SET_END(rcu_protected_types)
@@ -10835,7 +10842,9 @@ BTF_ID(func, bpf_dynptr_clone)
 BTF_ID(func, bpf_percpu_obj_new_impl)
 BTF_ID(func, bpf_percpu_obj_drop_impl)
 BTF_ID(func, bpf_throw)
+#ifdef CONFIG_CGROUPS
 BTF_ID(func, bpf_iter_css_task_new)
+#endif
 BTF_SET_END(special_kfunc_set)
 
 BTF_ID_LIST(special_kfunc_list)
@@ -10861,7 +10870,11 @@ BTF_ID(func, bpf_dynptr_clone)
 BTF_ID(func, bpf_percpu_obj_new_impl)
 BTF_ID(func, bpf_percpu_obj_drop_impl)
 BTF_ID(func, bpf_throw)
+#ifdef CONFIG_CGROUPS
 BTF_ID(func, bpf_iter_css_task_new)
+#else
+BTF_ID_UNUSED
+#endif
 
 static bool is_kfunc_ret_null(struct bpf_kfunc_call_arg_meta *meta)
 {
@@ -11394,6 +11407,12 @@ static int process_kf_arg_ptr_to_rbtree_node(struct bpf_verifier_env *env,
                                                  &meta->arg_rbtree_root.field);
 }
 
+/*
+ * css_task iter allowlist is needed to avoid dead locking on css_set_lock.
+ * LSM hooks and iters (both sleepable and non-sleepable) are safe.
+ * Any sleepable progs are also safe since bpf_check_attach_target() enforce
+ * them can only be attached to some specific hook points.
+ */
 static bool check_css_task_iter_allowlist(struct bpf_verifier_env *env)
 {
        enum bpf_prog_type prog_type = resolve_prog_type(env->prog);
@@ -11401,10 +11420,12 @@ static bool check_css_task_iter_allowlist(struct bpf_verifier_env *env)
        switch (prog_type) {
        case BPF_PROG_TYPE_LSM:
                return true;
-       case BPF_TRACE_ITER:
-               return env->prog->aux->sleepable;
+       case BPF_PROG_TYPE_TRACING:
+               if (env->prog->expected_attach_type == BPF_TRACE_ITER)
+                       return true;
+               fallthrough;
        default:
-               return false;
+               return env->prog->aux->sleepable;
        }
 }
 
@@ -11663,7 +11684,7 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_kfunc_call_
                case KF_ARG_PTR_TO_ITER:
                        if (meta->func_id == special_kfunc_list[KF_bpf_iter_css_task_new]) {
                                if (!check_css_task_iter_allowlist(env)) {
-                                       verbose(env, "css_task_iter is only allowed in bpf_lsm and bpf iter-s\n");
+                                       verbose(env, "css_task_iter is only allowed in bpf_lsm, bpf_iter and sleepable progs\n");
                                        return -EINVAL;
                                }
                        }
index d80d7a6..c0adb72 100644 (file)
@@ -156,19 +156,16 @@ static struct cgroup *cgroup_rstat_cpu_pop_updated(struct cgroup *pos,
  * optimize away the callsite. Therefore, __weak is needed to ensure that the
  * call is still emitted, by telling the compiler that we don't know what the
  * function might eventually be.
- *
- * __diag_* below are needed to dismiss the missing prototype warning.
  */
-__diag_push();
-__diag_ignore_all("-Wmissing-prototypes",
-                 "kfuncs which will be used in BPF programs");
+
+__bpf_hook_start();
 
 __weak noinline void bpf_rstat_flush(struct cgroup *cgrp,
                                     struct cgroup *parent, int cpu)
 {
 }
 
-__diag_pop();
+__bpf_hook_end();
 
 /* see cgroup_rstat_flush() */
 static void cgroup_rstat_flush_locked(struct cgroup *cgrp)
index df697c7..84e8a0f 100644 (file)
@@ -1252,9 +1252,7 @@ static const struct bpf_func_proto bpf_get_func_arg_cnt_proto = {
 };
 
 #ifdef CONFIG_KEYS
-__diag_push();
-__diag_ignore_all("-Wmissing-prototypes",
-                 "kfuncs which will be used in BPF programs");
+__bpf_kfunc_start_defs();
 
 /**
  * bpf_lookup_user_key - lookup a key by its serial
@@ -1404,7 +1402,7 @@ __bpf_kfunc int bpf_verify_pkcs7_signature(struct bpf_dynptr_kern *data_ptr,
 }
 #endif /* CONFIG_SYSTEM_DATA_VERIFICATION */
 
-__diag_pop();
+__bpf_kfunc_end_defs();
 
 BTF_SET8_START(key_sig_kfunc_set)
 BTF_ID_FLAGS(func, bpf_lookup_user_key, KF_ACQUIRE | KF_RET_NULL | KF_SLEEPABLE)
index 0841f8d..c9fdcc5 100644 (file)
@@ -503,9 +503,8 @@ out:
  * architecture dependent calling conventions. 7+ can be supported in the
  * future.
  */
-__diag_push();
-__diag_ignore_all("-Wmissing-prototypes",
-                 "Global functions as their definitions will be in vmlinux BTF");
+__bpf_kfunc_start_defs();
+
 __bpf_kfunc int bpf_fentry_test1(int a)
 {
        return a + 1;
@@ -605,7 +604,7 @@ __bpf_kfunc void bpf_kfunc_call_memb_release(struct prog_test_member *p)
 {
 }
 
-__diag_pop();
+__bpf_kfunc_end_defs();
 
 BTF_SET8_START(bpf_test_modify_return_ids)
 BTF_ID_FLAGS(func, bpf_modify_return_test)
index 8f19253..7413602 100644 (file)
@@ -135,3 +135,4 @@ static void __exit ebtable_broute_fini(void)
 module_init(ebtable_broute_init);
 module_exit(ebtable_broute_fini);
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Force packets to be routed instead of bridged");
index 278f324..dacd81b 100644 (file)
@@ -116,3 +116,4 @@ static void __exit ebtable_filter_fini(void)
 module_init(ebtable_filter_init);
 module_exit(ebtable_filter_fini);
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ebtables legacy filter table");
index 9066f7f..0f2a8c6 100644 (file)
@@ -116,3 +116,4 @@ static void __exit ebtable_nat_fini(void)
 module_init(ebtable_nat_init);
 module_exit(ebtable_nat_fini);
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ebtables legacy stateless nat table");
index aa23479..99d8267 100644 (file)
@@ -2595,3 +2595,4 @@ EXPORT_SYMBOL(ebt_do_table);
 module_init(ebtables_init);
 module_exit(ebtables_fini);
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ebtables legacy core");
index 71056ee..b5c406a 100644 (file)
@@ -416,3 +416,4 @@ module_exit(nf_conntrack_l3proto_bridge_fini);
 
 MODULE_ALIAS("nf_conntrack-" __stringify(AF_BRIDGE));
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Bridge IPv4 and IPv6 connection tracking");
index 21d7510..383f96b 100644 (file)
@@ -11767,9 +11767,7 @@ bpf_sk_base_func_proto(enum bpf_func_id func_id)
        return func;
 }
 
-__diag_push();
-__diag_ignore_all("-Wmissing-prototypes",
-                 "Global functions as their definitions will be in vmlinux BTF");
+__bpf_kfunc_start_defs();
 __bpf_kfunc int bpf_dynptr_from_skb(struct sk_buff *skb, u64 flags,
                                    struct bpf_dynptr_kern *ptr__uninit)
 {
@@ -11816,7 +11814,7 @@ __bpf_kfunc int bpf_sock_addr_set_sun_path(struct bpf_sock_addr_kern *sa_kern,
 
        return 0;
 }
-__diag_pop();
+__bpf_kfunc_end_defs();
 
 int bpf_dynptr_from_skb_rdonly(struct sk_buff *skb, u64 flags,
                               struct bpf_dynptr_kern *ptr__uninit)
@@ -11879,10 +11877,7 @@ static int __init bpf_kfunc_init(void)
 }
 late_initcall(bpf_kfunc_init);
 
-/* Disables missing prototype warnings */
-__diag_push();
-__diag_ignore_all("-Wmissing-prototypes",
-                 "Global functions as their definitions will be in vmlinux BTF");
+__bpf_kfunc_start_defs();
 
 /* bpf_sock_destroy: Destroy the given socket with ECONNABORTED error code.
  *
@@ -11916,7 +11911,7 @@ __bpf_kfunc int bpf_sock_destroy(struct sock_common *sock)
        return sk->sk_prot->diag_destroy(sk, ECONNABORTED);
 }
 
-__diag_pop()
+__bpf_kfunc_end_defs();
 
 BTF_SET8_START(bpf_sk_iter_kfunc_ids)
 BTF_ID_FLAGS(func, bpf_sock_destroy, KF_TRUSTED_ARGS)
index 5e409b9..dec5443 100644 (file)
@@ -217,8 +217,12 @@ static int page_pool_init(struct page_pool *pool,
                return -ENOMEM;
 #endif
 
-       if (ptr_ring_init(&pool->ring, ring_qsize, GFP_KERNEL) < 0)
+       if (ptr_ring_init(&pool->ring, ring_qsize, GFP_KERNEL) < 0) {
+#ifdef CONFIG_PAGE_POOL_STATS
+               free_percpu(pool->recycle_stats);
+#endif
                return -ENOMEM;
+       }
 
        atomic_set(&pool->pages_state_release_cnt, 0);
 
index df4789a..b6f1d6d 100644 (file)
@@ -696,9 +696,7 @@ struct xdp_frame *xdpf_clone(struct xdp_frame *xdpf)
        return nxdpf;
 }
 
-__diag_push();
-__diag_ignore_all("-Wmissing-prototypes",
-                 "Global functions as their definitions will be in vmlinux BTF");
+__bpf_kfunc_start_defs();
 
 /**
  * bpf_xdp_metadata_rx_timestamp - Read XDP frame RX timestamp.
@@ -738,7 +736,7 @@ __bpf_kfunc int bpf_xdp_metadata_rx_hash(const struct xdp_md *ctx, u32 *hash,
        return -EOPNOTSUPP;
 }
 
-__diag_pop();
+__bpf_kfunc_end_defs();
 
 BTF_SET8_START(xdp_metadata_kfunc_ids)
 #define XDP_METADATA_KFUNC(_, __, name, ___) BTF_ID_FLAGS(func, name, KF_TRUSTED_ARGS)
index 1b8cbfd..44b033f 100644 (file)
@@ -629,9 +629,6 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
        if (dccp_parse_options(sk, dreq, skb))
                goto drop_and_free;
 
-       if (security_inet_conn_request(sk, skb, req))
-               goto drop_and_free;
-
        ireq = inet_rsk(req);
        sk_rcv_saddr_set(req_to_sk(req), ip_hdr(skb)->daddr);
        sk_daddr_set(req_to_sk(req), ip_hdr(skb)->saddr);
@@ -639,6 +636,9 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
        ireq->ireq_family = AF_INET;
        ireq->ir_iif = READ_ONCE(sk->sk_bound_dev_if);
 
+       if (security_inet_conn_request(sk, skb, req))
+               goto drop_and_free;
+
        /*
         * Step 3: Process LISTEN state
         *
index 8d344b2..4550b68 100644 (file)
@@ -360,15 +360,15 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
        if (dccp_parse_options(sk, dreq, skb))
                goto drop_and_free;
 
-       if (security_inet_conn_request(sk, skb, req))
-               goto drop_and_free;
-
        ireq = inet_rsk(req);
        ireq->ir_v6_rmt_addr = ipv6_hdr(skb)->saddr;
        ireq->ir_v6_loc_addr = ipv6_hdr(skb)->daddr;
        ireq->ireq_family = AF_INET6;
        ireq->ir_mark = inet_request_mark(sk, skb);
 
+       if (security_inet_conn_request(sk, skb, req))
+               goto drop_and_free;
+
        if (ipv6_opt_accepted(sk, skb, IP6CB(skb)) ||
            np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo ||
            np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) {
index 9cbae01..788dfdc 100644 (file)
@@ -15,7 +15,7 @@ const struct nla_policy devlink_dl_port_function_nl_policy[DEVLINK_PORT_FN_ATTR_
        [DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR] = { .type = NLA_BINARY, },
        [DEVLINK_PORT_FN_ATTR_STATE] = NLA_POLICY_MAX(NLA_U8, 1),
        [DEVLINK_PORT_FN_ATTR_OPSTATE] = NLA_POLICY_MAX(NLA_U8, 1),
-       [DEVLINK_PORT_FN_ATTR_CAPS] = NLA_POLICY_BITFIELD32(3),
+       [DEVLINK_PORT_FN_ATTR_CAPS] = NLA_POLICY_BITFIELD32(15),
 };
 
 const struct nla_policy devlink_dl_selftest_id_nl_policy[DEVLINK_ATTR_SELFTEST_ID_FLASH + 1] = {
index b71dab6..80cdc6f 100644 (file)
@@ -342,9 +342,7 @@ struct sk_buff *prp_create_tagged_frame(struct hsr_frame_info *frame,
        skb = skb_copy_expand(frame->skb_std, 0,
                              skb_tailroom(frame->skb_std) + HSR_HLEN,
                              GFP_ATOMIC);
-       prp_fill_rct(skb, frame, port);
-
-       return skb;
+       return prp_fill_rct(skb, frame, port);
 }
 
 static void hsr_deliver_master(struct sk_buff *skb, struct net_device *dev,
index 3760a14..4da03bf 100644 (file)
@@ -22,9 +22,7 @@ enum bpf_fou_encap_type {
        FOU_BPF_ENCAP_GUE,
 };
 
-__diag_push();
-__diag_ignore_all("-Wmissing-prototypes",
-                 "Global functions as their definitions will be in BTF");
+__bpf_kfunc_start_defs();
 
 /* bpf_skb_set_fou_encap - Set FOU encap parameters
  *
@@ -100,7 +98,7 @@ __bpf_kfunc int bpf_skb_get_fou_encap(struct __sk_buff *skb_ctx,
        return 0;
 }
 
-__diag_pop()
+__bpf_kfunc_end_defs();
 
 BTF_SET8_START(fou_kfunc_set)
 BTF_ID_FLAGS(func, bpf_skb_set_fou_encap)
index 56f6ecc..4d42d07 100644 (file)
@@ -170,3 +170,4 @@ module_init(iptable_nat_init);
 module_exit(iptable_nat_exit);
 
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("iptables legacy nat table");
index ca5e5b2..0e7f539 100644 (file)
@@ -108,3 +108,4 @@ static void __exit iptable_raw_fini(void)
 module_init(iptable_raw_init);
 module_exit(iptable_raw_fini);
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("iptables legacy raw table");
index 265b39b..482e733 100644 (file)
@@ -186,3 +186,4 @@ module_init(nf_defrag_init);
 module_exit(nf_defrag_fini);
 
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("IPv4 defragmentation support");
index f33aeab..f01b038 100644 (file)
@@ -336,3 +336,4 @@ void nf_send_unreach(struct sk_buff *skb_in, int code, int hook)
 EXPORT_SYMBOL_GPL(nf_send_unreach);
 
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("IPv4 packet rejection core");
index 98b25e5..d37282c 100644 (file)
@@ -306,7 +306,7 @@ struct request_sock *cookie_tcp_reqsk_alloc(const struct request_sock_ops *ops,
        treq->af_specific = af_ops;
 
        treq->syn_tos = TCP_SKB_CB(skb)->ip_dsfield;
-       treq->req_usec_ts = -1;
+       treq->req_usec_ts = false;
 
 #if IS_ENABLED(CONFIG_MPTCP)
        treq->is_mptcp = sk_is_mptcp(sk);
index ef5472e..7696417 100644 (file)
@@ -1315,7 +1315,8 @@ static int tcp_ao_parse_crypto(struct tcp_ao_add *cmd, struct tcp_ao_key *key)
        key->maclen = cmd->maclen ?: 12; /* 12 is the default in RFC5925 */
 
        /* Check: maclen + tcp-ao header <= (MAX_TCP_OPTION_SPACE - mss
-        *                                      - tstamp - wscale - sackperm),
+        *                                      - tstamp (including sackperm)
+        *                                      - wscale),
         * see tcp_syn_options(), tcp_synack_options(), commit 33ad798c924b.
         *
         * In order to allow D-SACK with TCP-AO, the header size should be:
@@ -1342,9 +1343,9 @@ static int tcp_ao_parse_crypto(struct tcp_ao_add *cmd, struct tcp_ao_key *key)
         * large to leave sufficient option space.
         */
        syn_tcp_option_space = MAX_TCP_OPTION_SPACE;
+       syn_tcp_option_space -= TCPOLEN_MSS_ALIGNED;
        syn_tcp_option_space -= TCPOLEN_TSTAMP_ALIGNED;
        syn_tcp_option_space -= TCPOLEN_WSCALE_ALIGNED;
-       syn_tcp_option_space -= TCPOLEN_SACKPERM_ALIGNED;
        if (tcp_ao_len(key) > syn_tcp_option_space) {
                err = -EMSGSIZE;
                goto err_kfree;
index 50aaa15..bcb55d9 100644 (file)
@@ -7115,7 +7115,7 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops,
        req->syncookie = want_cookie;
        tcp_rsk(req)->af_specific = af_ops;
        tcp_rsk(req)->ts_off = 0;
-       tcp_rsk(req)->req_usec_ts = -1;
+       tcp_rsk(req)->req_usec_ts = false;
 #if IS_ENABLED(CONFIG_MPTCP)
        tcp_rsk(req)->is_mptcp = 0;
 #endif
@@ -7143,9 +7143,10 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops,
        if (!dst)
                goto drop_and_free;
 
-       if (tmp_opt.tstamp_ok)
+       if (tmp_opt.tstamp_ok) {
+               tcp_rsk(req)->req_usec_ts = dst_tcp_usec_ts(dst);
                tcp_rsk(req)->ts_off = af_ops->init_ts_off(net, skb);
-
+       }
        if (!want_cookie && !isn) {
                int max_syn_backlog = READ_ONCE(net->ipv4.sysctl_max_syn_backlog);
 
index f558c05..eb13a55 100644 (file)
@@ -601,6 +601,44 @@ static void bpf_skops_write_hdr_opt(struct sock *sk, struct sk_buff *skb,
 }
 #endif
 
+static __be32 *process_tcp_ao_options(struct tcp_sock *tp,
+                                     const struct tcp_request_sock *tcprsk,
+                                     struct tcp_out_options *opts,
+                                     struct tcp_key *key, __be32 *ptr)
+{
+#ifdef CONFIG_TCP_AO
+       u8 maclen = tcp_ao_maclen(key->ao_key);
+
+       if (tcprsk) {
+               u8 aolen = maclen + sizeof(struct tcp_ao_hdr);
+
+               *ptr++ = htonl((TCPOPT_AO << 24) | (aolen << 16) |
+                              (tcprsk->ao_keyid << 8) |
+                              (tcprsk->ao_rcv_next));
+       } else {
+               struct tcp_ao_key *rnext_key;
+               struct tcp_ao_info *ao_info;
+
+               ao_info = rcu_dereference_check(tp->ao_info,
+                       lockdep_sock_is_held(&tp->inet_conn.icsk_inet.sk));
+               rnext_key = READ_ONCE(ao_info->rnext_key);
+               if (WARN_ON_ONCE(!rnext_key))
+                       return ptr;
+               *ptr++ = htonl((TCPOPT_AO << 24) |
+                              (tcp_ao_len(key->ao_key) << 16) |
+                              (key->ao_key->sndid << 8) |
+                              (rnext_key->rcvid));
+       }
+       opts->hash_location = (__u8 *)ptr;
+       ptr += maclen / sizeof(*ptr);
+       if (unlikely(maclen % sizeof(*ptr))) {
+               memset(ptr, TCPOPT_NOP, sizeof(*ptr));
+               ptr++;
+       }
+#endif
+       return ptr;
+}
+
 /* Write previously computed TCP options to the packet.
  *
  * Beware: Something in the Internet is very sensitive to the ordering of
@@ -629,37 +667,7 @@ static void tcp_options_write(struct tcphdr *th, struct tcp_sock *tp,
                opts->hash_location = (__u8 *)ptr;
                ptr += 4;
        } else if (tcp_key_is_ao(key)) {
-#ifdef CONFIG_TCP_AO
-               u8 maclen = tcp_ao_maclen(key->ao_key);
-
-               if (tcprsk) {
-                       u8 aolen = maclen + sizeof(struct tcp_ao_hdr);
-
-                       *ptr++ = htonl((TCPOPT_AO << 24) | (aolen << 16) |
-                                      (tcprsk->ao_keyid << 8) |
-                                      (tcprsk->ao_rcv_next));
-               } else {
-                       struct tcp_ao_key *rnext_key;
-                       struct tcp_ao_info *ao_info;
-
-                       ao_info = rcu_dereference_check(tp->ao_info,
-                               lockdep_sock_is_held(&tp->inet_conn.icsk_inet.sk));
-                       rnext_key = READ_ONCE(ao_info->rnext_key);
-                       if (WARN_ON_ONCE(!rnext_key))
-                               goto out_ao;
-                       *ptr++ = htonl((TCPOPT_AO << 24) |
-                                      (tcp_ao_len(key->ao_key) << 16) |
-                                      (key->ao_key->sndid << 8) |
-                                      (rnext_key->rcvid));
-               }
-               opts->hash_location = (__u8 *)ptr;
-               ptr += maclen / sizeof(*ptr);
-               if (unlikely(maclen % sizeof(*ptr))) {
-                       memset(ptr, TCPOPT_NOP, sizeof(*ptr));
-                       ptr++;
-               }
-out_ao:
-#endif
+               ptr = process_tcp_ao_options(tp, tcprsk, opts, key, ptr);
        }
        if (unlikely(opts->mss)) {
                *ptr++ = htonl((TCPOPT_MSS << 24) |
@@ -3693,8 +3701,6 @@ struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst,
        mss = tcp_mss_clamp(tp, dst_metric_advmss(dst));
 
        memset(&opts, 0, sizeof(opts));
-       if (tcp_rsk(req)->req_usec_ts < 0)
-               tcp_rsk(req)->req_usec_ts = dst_tcp_usec_ts(dst);
        now = tcp_clock_ns();
 #ifdef CONFIG_SYN_COOKIES
        if (unlikely(synack_type == TCP_SYNACK_COOKIE && ireq->tstamp_ok))
index 65a8eaa..55b310a 100644 (file)
@@ -231,7 +231,7 @@ static void cpool_schedule_cleanup(struct kref *kref)
  */
 void tcp_sigpool_release(unsigned int id)
 {
-       if (WARN_ON_ONCE(id > cpool_populated || !cpool[id].alg))
+       if (WARN_ON_ONCE(id >= cpool_populated || !cpool[id].alg))
                return;
 
        /* slow-path */
@@ -245,7 +245,7 @@ EXPORT_SYMBOL_GPL(tcp_sigpool_release);
  */
 void tcp_sigpool_get(unsigned int id)
 {
-       if (WARN_ON_ONCE(id > cpool_populated || !cpool[id].alg))
+       if (WARN_ON_ONCE(id >= cpool_populated || !cpool[id].alg))
                return;
        kref_get(&cpool[id].kref);
 }
@@ -256,7 +256,7 @@ int tcp_sigpool_start(unsigned int id, struct tcp_sigpool *c) __cond_acquires(RC
        struct crypto_ahash *hash;
 
        rcu_read_lock_bh();
-       if (WARN_ON_ONCE(id > cpool_populated || !cpool[id].alg)) {
+       if (WARN_ON_ONCE(id >= cpool_populated || !cpool[id].alg)) {
                rcu_read_unlock_bh();
                return -EINVAL;
        }
@@ -301,7 +301,7 @@ EXPORT_SYMBOL_GPL(tcp_sigpool_end);
  */
 size_t tcp_sigpool_algo(unsigned int id, char *buf, size_t buf_len)
 {
-       if (WARN_ON_ONCE(id > cpool_populated || !cpool[id].alg))
+       if (WARN_ON_ONCE(id >= cpool_populated || !cpool[id].alg))
                return -EINVAL;
 
        return strscpy(buf, cpool[id].alg, buf_len);
index bf3cb3a..52cf104 100644 (file)
@@ -170,3 +170,4 @@ module_init(ip6table_nat_init);
 module_exit(ip6table_nat_exit);
 
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Ip6tables legacy nat table");
index 08861d5..fc9f675 100644 (file)
@@ -106,3 +106,4 @@ static void __exit ip6table_raw_fini(void)
 module_init(ip6table_raw_init);
 module_exit(ip6table_raw_fini);
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Ip6tables legacy raw table");
index d59b296..be7817f 100644 (file)
@@ -182,3 +182,4 @@ module_init(nf_defrag_init);
 module_exit(nf_defrag_fini);
 
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("IPv6 defragmentation support");
index 58ccdb0..d45bc54 100644 (file)
@@ -413,3 +413,4 @@ void nf_send_unreach6(struct net *net, struct sk_buff *skb_in,
 EXPORT_SYMBOL_GPL(nf_send_unreach6);
 
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("IPv6 packet rejection core");
index 500f6ed..12eedc6 100644 (file)
@@ -181,14 +181,15 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
        treq = tcp_rsk(req);
        treq->tfo_listener = false;
 
-       if (security_inet_conn_request(sk, skb, req))
-               goto out_free;
-
        req->mss = mss;
        ireq->ir_rmt_port = th->source;
        ireq->ir_num = ntohs(th->dest);
        ireq->ir_v6_rmt_addr = ipv6_hdr(skb)->saddr;
        ireq->ir_v6_loc_addr = ipv6_hdr(skb)->daddr;
+
+       if (security_inet_conn_request(sk, skb, req))
+               goto out_free;
+
        if (ipv6_opt_accepted(sk, skb, &TCP_SKB_CB(skb)->header.h6) ||
            np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo ||
            np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) {
index dd1d8ff..65d1f67 100644 (file)
@@ -1946,4 +1946,5 @@ module_init(kcm_init);
 module_exit(kcm_exit);
 
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("KCM (Kernel Connection Multiplexor) sockets");
 MODULE_ALIAS_NETPROTO(PF_KCM);
index 7cac441..51bccfb 100644 (file)
@@ -127,8 +127,14 @@ static inline int llc_fixup_skb(struct sk_buff *skb)
        skb->transport_header += llc_len;
        skb_pull(skb, llc_len);
        if (skb->protocol == htons(ETH_P_802_2)) {
-               __be16 pdulen = eth_hdr(skb)->h_proto;
-               s32 data_size = ntohs(pdulen) - llc_len;
+               __be16 pdulen;
+               s32 data_size;
+
+               if (skb->mac_len < ETH_HLEN)
+                       return 0;
+
+               pdulen = eth_hdr(skb)->h_proto;
+               data_size = ntohs(pdulen) - llc_len;
 
                if (data_size < 0 ||
                    !pskb_may_pull(skb, data_size))
index 79d1cef..06fb8e6 100644 (file)
@@ -153,6 +153,9 @@ int llc_sap_action_send_test_r(struct llc_sap *sap, struct sk_buff *skb)
        int rc = 1;
        u32 data_size;
 
+       if (skb->mac_len < ETH_HLEN)
+               return 1;
+
        llc_pdu_decode_sa(skb, mac_da);
        llc_pdu_decode_da(skb, mac_sa);
        llc_pdu_decode_ssap(skb, &dsap);
index 05c6ae0..f506542 100644 (file)
@@ -76,6 +76,9 @@ static int llc_station_ac_send_test_r(struct sk_buff *skb)
        u32 data_size;
        struct sk_buff *nskb;
 
+       if (skb->mac_len < ETH_HLEN)
+               goto out;
+
        /* The test request command is type U (llc_len = 3) */
        data_size = ntohs(eth_hdr(skb)->h_proto) - 3;
        nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U, data_size);
index 3230506..a2c16b5 100644 (file)
@@ -2450,3 +2450,4 @@ static void __exit ip_vs_cleanup(void)
 module_init(ip_vs_init);
 module_exit(ip_vs_cleanup);
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("IP Virtual Server");
index 5e6ec32..75f4c23 100644 (file)
@@ -270,3 +270,4 @@ static void __exit ip_vs_dh_cleanup(void)
 module_init(ip_vs_dh_init);
 module_exit(ip_vs_dh_cleanup);
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ipvs destination hashing scheduler");
index b846cc3..ab117e5 100644 (file)
@@ -72,3 +72,4 @@ static void __exit ip_vs_fo_cleanup(void)
 module_init(ip_vs_fo_init);
 module_exit(ip_vs_fo_cleanup);
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ipvs weighted failover scheduler");
index ef1f45e..f53899d 100644 (file)
@@ -635,3 +635,4 @@ static void __exit ip_vs_ftp_exit(void)
 module_init(ip_vs_ftp_init);
 module_exit(ip_vs_ftp_exit);
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ipvs ftp helper");
index cf78ba4..8ceec7a 100644 (file)
@@ -632,3 +632,4 @@ static void __exit ip_vs_lblc_cleanup(void)
 module_init(ip_vs_lblc_init);
 module_exit(ip_vs_lblc_cleanup);
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ipvs locality-based least-connection scheduler");
index 9eddf11..0fb6470 100644 (file)
@@ -817,3 +817,4 @@ static void __exit ip_vs_lblcr_cleanup(void)
 module_init(ip_vs_lblcr_init);
 module_exit(ip_vs_lblcr_cleanup);
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ipvs locality-based least-connection with replication scheduler");
index 9d34d81..c276450 100644 (file)
@@ -86,3 +86,4 @@ static void __exit ip_vs_lc_cleanup(void)
 module_init(ip_vs_lc_init);
 module_exit(ip_vs_lc_cleanup);
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ipvs least connection scheduler");
index f56862a..ed7f5c8 100644 (file)
@@ -136,3 +136,4 @@ static void __exit ip_vs_nq_cleanup(void)
 module_init(ip_vs_nq_init);
 module_exit(ip_vs_nq_cleanup);
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ipvs never queue scheduler");
index c03066f..c7708b8 100644 (file)
@@ -79,3 +79,4 @@ static void __exit ip_vs_ovf_cleanup(void)
 module_init(ip_vs_ovf_init);
 module_exit(ip_vs_ovf_cleanup);
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ipvs overflow connection scheduler");
index 0ac6705..e4ce1d9 100644 (file)
@@ -185,3 +185,4 @@ static void __exit ip_vs_sip_cleanup(void)
 module_init(ip_vs_sip_init);
 module_exit(ip_vs_sip_cleanup);
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ipvs sip helper");
index 38495c6..6baa34d 100644 (file)
@@ -122,4 +122,5 @@ static void __exit ip_vs_rr_cleanup(void)
 
 module_init(ip_vs_rr_init);
 module_exit(ip_vs_rr_cleanup);
+MODULE_DESCRIPTION("ipvs round-robin scheduler");
 MODULE_LICENSE("GPL");
index 7663288..a46f99a 100644 (file)
@@ -137,3 +137,4 @@ static void __exit ip_vs_sed_cleanup(void)
 module_init(ip_vs_sed_init);
 module_exit(ip_vs_sed_cleanup);
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ipvs shortest expected delay scheduler");
index c2028e4..92e77d7 100644 (file)
@@ -376,3 +376,4 @@ static void __exit ip_vs_sh_cleanup(void)
 module_init(ip_vs_sh_init);
 module_exit(ip_vs_sh_cleanup);
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ipvs source hashing scheduler");
index 3308e4c..8d5419e 100644 (file)
@@ -137,3 +137,4 @@ static void __exit ip_vs_twos_cleanup(void)
 module_init(ip_vs_twos_init);
 module_exit(ip_vs_twos_cleanup);
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ipvs power of twos choice scheduler");
index 09f584b..9fa5009 100644 (file)
@@ -109,3 +109,4 @@ static void __exit ip_vs_wlc_cleanup(void)
 module_init(ip_vs_wlc_init);
 module_exit(ip_vs_wlc_cleanup);
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ipvs weighted least connection scheduler");
index 1bc7a07..85ce0d0 100644 (file)
@@ -263,3 +263,4 @@ static void __exit ip_vs_wrr_cleanup(void)
 module_init(ip_vs_wrr_init);
 module_exit(ip_vs_wrr_cleanup);
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ipvs weighted round-robin scheduler");
index b21799d..475358e 100644 (file)
@@ -230,9 +230,7 @@ static int _nf_conntrack_btf_struct_access(struct bpf_verifier_log *log,
        return 0;
 }
 
-__diag_push();
-__diag_ignore_all("-Wmissing-prototypes",
-                 "Global functions as their definitions will be in nf_conntrack BTF");
+__bpf_kfunc_start_defs();
 
 /* bpf_xdp_ct_alloc - Allocate a new CT entry
  *
@@ -467,7 +465,7 @@ __bpf_kfunc int bpf_ct_change_status(struct nf_conn *nfct, u32 status)
        return nf_ct_change_status_common(nfct, status);
 }
 
-__diag_pop()
+__bpf_kfunc_end_defs();
 
 BTF_SET8_START(nf_ct_kfunc_set)
 BTF_ID_FLAGS(func, bpf_xdp_ct_alloc, KF_ACQUIRE | KF_RET_NULL)
index 9fb9b80..cfa0fe0 100644 (file)
@@ -82,3 +82,4 @@ out:
 EXPORT_SYMBOL_GPL(nf_conntrack_broadcast_help);
 
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Broadcast connection tracking helper");
index 334db22..fb0ae15 100644 (file)
@@ -57,6 +57,7 @@
 #include "nf_internals.h"
 
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("List and change connection tracking table");
 
 struct ctnetlink_list_dump_ctx {
        struct nf_conn *last;
index c928ff6..f36727e 100644 (file)
@@ -699,3 +699,4 @@ MODULE_ALIAS("ip_conntrack");
 MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET));
 MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET6));
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("IPv4 and IPv6 connection tracking");
index 141ee77..6e3b2f5 100644 (file)
@@ -12,9 +12,7 @@
 #include <net/netfilter/nf_conntrack_core.h>
 #include <net/netfilter/nf_nat.h>
 
-__diag_push();
-__diag_ignore_all("-Wmissing-prototypes",
-                 "Global functions as their definitions will be in nf_nat BTF");
+__bpf_kfunc_start_defs();
 
 /* bpf_ct_set_nat_info - Set source or destination nat address
  *
@@ -54,7 +52,7 @@ __bpf_kfunc int bpf_ct_set_nat_info(struct nf_conn___init *nfct,
        return nf_nat_setup_info(ct, &range, manip) == NF_DROP ? -ENOMEM : 0;
 }
 
-__diag_pop()
+__bpf_kfunc_end_defs();
 
 BTF_SET8_START(nf_nat_kfunc_set)
 BTF_ID_FLAGS(func, bpf_ct_set_nat_info, KF_TRUSTED_ARGS)
index c4e0516..c3d7ecb 100644 (file)
@@ -1263,6 +1263,7 @@ static void __exit nf_nat_cleanup(void)
 }
 
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Network address translation core");
 
 module_init(nf_nat_init);
 module_exit(nf_nat_cleanup);
index 6616ba5..5b37487 100644 (file)
@@ -80,6 +80,26 @@ EXPORT_SYMBOL_GPL(nf_nat_redirect_ipv4);
 
 static const struct in6_addr loopback_addr = IN6ADDR_LOOPBACK_INIT;
 
+static bool nf_nat_redirect_ipv6_usable(const struct inet6_ifaddr *ifa, unsigned int scope)
+{
+       unsigned int ifa_addr_type = ipv6_addr_type(&ifa->addr);
+
+       if (ifa_addr_type & IPV6_ADDR_MAPPED)
+               return false;
+
+       if ((ifa->flags & IFA_F_TENTATIVE) && (!(ifa->flags & IFA_F_OPTIMISTIC)))
+               return false;
+
+       if (scope) {
+               unsigned int ifa_scope = ifa_addr_type & IPV6_ADDR_SCOPE_MASK;
+
+               if (!(scope & ifa_scope))
+                       return false;
+       }
+
+       return true;
+}
+
 unsigned int
 nf_nat_redirect_ipv6(struct sk_buff *skb, const struct nf_nat_range2 *range,
                     unsigned int hooknum)
@@ -89,14 +109,19 @@ nf_nat_redirect_ipv6(struct sk_buff *skb, const struct nf_nat_range2 *range,
        if (hooknum == NF_INET_LOCAL_OUT) {
                newdst.in6 = loopback_addr;
        } else {
+               unsigned int scope = ipv6_addr_scope(&ipv6_hdr(skb)->daddr);
                struct inet6_dev *idev;
-               struct inet6_ifaddr *ifa;
                bool addr = false;
 
                idev = __in6_dev_get(skb->dev);
                if (idev != NULL) {
+                       const struct inet6_ifaddr *ifa;
+
                        read_lock_bh(&idev->lock);
                        list_for_each_entry(ifa, &idev->addr_list, if_list) {
+                               if (!nf_nat_redirect_ipv6_usable(ifa, scope))
+                                       continue;
+
                                newdst.in6 = ifa->addr;
                                addr = true;
                                break;
index 3c1fd82..a761ee6 100644 (file)
@@ -6520,6 +6520,12 @@ static int nft_setelem_deactivate(const struct net *net,
        return ret;
 }
 
+static void nft_setelem_catchall_destroy(struct nft_set_elem_catchall *catchall)
+{
+       list_del_rcu(&catchall->list);
+       kfree_rcu(catchall, rcu);
+}
+
 static void nft_setelem_catchall_remove(const struct net *net,
                                        const struct nft_set *set,
                                        struct nft_elem_priv *elem_priv)
@@ -6528,8 +6534,7 @@ static void nft_setelem_catchall_remove(const struct net *net,
 
        list_for_each_entry_safe(catchall, next, &set->catchall_list, list) {
                if (catchall->elem == elem_priv) {
-                       list_del_rcu(&catchall->list);
-                       kfree_rcu(catchall, rcu);
+                       nft_setelem_catchall_destroy(catchall);
                        break;
                }
        }
@@ -9678,11 +9683,12 @@ static struct nft_trans_gc *nft_trans_gc_catchall(struct nft_trans_gc *gc,
                                                  unsigned int gc_seq,
                                                  bool sync)
 {
-       struct nft_set_elem_catchall *catchall;
+       struct nft_set_elem_catchall *catchall, *next;
        const struct nft_set *set = gc->set;
+       struct nft_elem_priv *elem_priv;
        struct nft_set_ext *ext;
 
-       list_for_each_entry_rcu(catchall, &set->catchall_list, list) {
+       list_for_each_entry_safe(catchall, next, &set->catchall_list, list) {
                ext = nft_set_elem_ext(set, catchall->elem);
 
                if (!nft_set_elem_expired(ext))
@@ -9700,7 +9706,13 @@ dead_elem:
                if (!gc)
                        return NULL;
 
-               nft_trans_gc_elem_add(gc, catchall->elem);
+               elem_priv = catchall->elem;
+               if (sync) {
+                       nft_setelem_data_deactivate(gc->net, gc->set, elem_priv);
+                       nft_setelem_catchall_destroy(catchall);
+               }
+
+               nft_trans_gc_elem_add(gc, elem_priv);
        }
 
        return gc;
@@ -11386,4 +11398,5 @@ module_exit(nf_tables_module_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
+MODULE_DESCRIPTION("Framework for packet filtering and classification");
 MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_NFTABLES);
index 50723ba..c0fc431 100644 (file)
@@ -447,4 +447,5 @@ module_init(nfnl_osf_init);
 module_exit(nfnl_osf_fini);
 
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Passive OS fingerprint matching");
 MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_OSF);
index 98e4946..40e230d 100644 (file)
@@ -137,6 +137,7 @@ module_init(nft_chain_nat_init);
 module_exit(nft_chain_nat_exit);
 
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("nftables network address translation support");
 #ifdef CONFIG_NF_TABLES_IPV4
 MODULE_ALIAS_NFT_CHAIN(AF_INET, "nat");
 #endif
index 04b51f2..1bfe258 100644 (file)
@@ -204,4 +204,5 @@ bool nft_fib_reduce(struct nft_regs_track *track,
 EXPORT_SYMBOL_GPL(nft_fib_reduce);
 
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Query routing table from nftables");
 MODULE_AUTHOR("Florian Westphal <fw@strlen.de>");
index a5268e6..358e742 100644 (file)
@@ -270,4 +270,5 @@ module_exit(nft_fwd_netdev_module_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");
+MODULE_DESCRIPTION("nftables netdev packet forwarding support");
 MODULE_ALIAS_NFT_AF_EXPR(5, "fwd");
index 7ddb9a7..ef93e0d 100644 (file)
@@ -561,7 +561,7 @@ recent_mt_proc_write(struct file *file, const char __user *input,
 {
        struct recent_table *t = pde_data(file_inode(file));
        struct recent_entry *e;
-       char buf[sizeof("+b335:1d35:1e55:dead:c0de:1715:5afe:c0de")];
+       char buf[sizeof("+b335:1d35:1e55:dead:c0de:1715:255.255.255.255")];
        const char *c = buf;
        union nf_inet_addr addr = {};
        u_int16_t family;
index 9c4f231..1eeff94 100644 (file)
@@ -257,5 +257,6 @@ static void __exit netlink_diag_exit(void)
 
 module_init(netlink_diag_init);
 module_exit(netlink_diag_exit);
+MODULE_DESCRIPTION("Netlink-based socket monitoring/diagnostic interface (sock_diag)");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_NETLINK, NETLINK_SOCK_DIAG, 16 /* AF_NETLINK */);
index 0b9a785..3019a44 100644 (file)
@@ -985,7 +985,7 @@ static int ovs_ct_commit(struct net *net, struct sw_flow_key *key,
                if (err)
                        return err;
 
-               nf_conn_act_ct_ext_add(ct);
+               nf_conn_act_ct_ext_add(skb, ct, ctinfo);
        } else if (IS_ENABLED(CONFIG_NF_CONNTRACK_LABELS) &&
                   labels_nonzero(&info->labels.mask)) {
                err = ovs_ct_set_labels(ct, key, &info->labels.value,
index ac85d46..df8a271 100644 (file)
@@ -212,7 +212,7 @@ void rxrpc_disconnect_call(struct rxrpc_call *call)
                conn->idle_timestamp = jiffies;
                if (atomic_dec_and_test(&conn->active))
                        rxrpc_set_service_reap_timer(conn->rxnet,
-                                                    jiffies + rxrpc_connection_expiry);
+                                                    jiffies + rxrpc_connection_expiry * HZ);
        }
 
        rxrpc_put_call(call, rxrpc_call_put_io_thread);
index 7d910ae..c553a30 100644 (file)
@@ -87,7 +87,7 @@ static void rxrpc_client_conn_reap_timeout(struct timer_list *timer)
        struct rxrpc_local *local =
                container_of(timer, struct rxrpc_local, client_conn_reap_timer);
 
-       if (local->kill_all_client_conns &&
+       if (!local->kill_all_client_conns &&
            test_and_set_bit(RXRPC_CLIENT_CONN_REAP_TIMER, &local->client_conn_flags))
                rxrpc_wake_up_io_thread(local);
 }
index 9d3f26b..c39252d 100644 (file)
@@ -1098,7 +1098,7 @@ repeat:
                        }
                } else if (TC_ACT_EXT_CMP(ret, TC_ACT_GOTO_CHAIN)) {
                        if (unlikely(!rcu_access_pointer(a->goto_chain))) {
-                               net_warn_ratelimited("can't go to NULL chain!\n");
+                               tcf_set_drop_reason(res, SKB_DROP_REASON_TC_ERROR);
                                return TC_ACT_SHOT;
                        }
                        tcf_action_goto_chain_exec(a, res);
index 9583645..0db0ecf 100644 (file)
@@ -376,6 +376,17 @@ static void tcf_ct_flow_tc_ifidx(struct flow_offload *entry,
        entry->tuplehash[dir].tuple.tc.iifidx = act_ct_ext->ifindex[dir];
 }
 
+static void tcf_ct_flow_ct_ext_ifidx_update(struct flow_offload *entry)
+{
+       struct nf_conn_act_ct_ext *act_ct_ext;
+
+       act_ct_ext = nf_conn_act_ct_ext_find(entry->ct);
+       if (act_ct_ext) {
+               tcf_ct_flow_tc_ifidx(entry, act_ct_ext, FLOW_OFFLOAD_DIR_ORIGINAL);
+               tcf_ct_flow_tc_ifidx(entry, act_ct_ext, FLOW_OFFLOAD_DIR_REPLY);
+       }
+}
+
 static void tcf_ct_flow_table_add(struct tcf_ct_flow_table *ct_ft,
                                  struct nf_conn *ct,
                                  bool tcp, bool bidirectional)
@@ -671,6 +682,8 @@ static bool tcf_ct_flow_table_lookup(struct tcf_ct_params *p,
        else
                ctinfo = IP_CT_ESTABLISHED_REPLY;
 
+       nf_conn_act_ct_ext_fill(skb, ct, ctinfo);
+       tcf_ct_flow_ct_ext_ifidx_update(flow);
        flow_offload_refresh(nf_ft, flow, force_refresh);
        if (!test_bit(IPS_ASSURED_BIT, &ct->status)) {
                /* Process this flow in SW to allow promoting to ASSURED */
@@ -1034,7 +1047,7 @@ do_nat:
                tcf_ct_act_set_labels(ct, p->labels, p->labels_mask);
 
                if (!nf_ct_is_confirmed(ct))
-                       nf_conn_act_ct_ext_add(ct);
+                       nf_conn_act_ct_ext_add(skb, ct, ctinfo);
 
                /* This will take care of sending queued events
                 * even if the connection is already confirmed.
index c9a811f..393b787 100644 (file)
@@ -677,4 +677,5 @@ static void __exit gate_cleanup_module(void)
 
 module_init(gate_init_module);
 module_exit(gate_cleanup_module);
+MODULE_DESCRIPTION("TC gate action");
 MODULE_LICENSE("GPL v2");
index 1daeb21..1976bd1 100644 (file)
@@ -1658,6 +1658,7 @@ static inline int __tcf_classify(struct sk_buff *skb,
                                 int act_index,
                                 u32 *last_executed_chain)
 {
+       u32 orig_reason = res->drop_reason;
 #ifdef CONFIG_NET_CLS_ACT
        const int max_reclassify_loop = 16;
        const struct tcf_proto *first_tp;
@@ -1712,8 +1713,14 @@ reclassify:
                        goto reset;
                }
 #endif
-               if (err >= 0)
+               if (err >= 0) {
+                       /* Policy drop or drop reason is over-written by
+                        * classifiers with a bogus value(0) */
+                       if (err == TC_ACT_SHOT &&
+                           res->drop_reason == SKB_NOT_DROPPED_YET)
+                               tcf_set_drop_reason(res, orig_reason);
                        return err;
+               }
        }
 
        if (unlikely(n)) {
index 1b92c33..a1f5693 100644 (file)
@@ -341,4 +341,5 @@ static void __exit exit_basic(void)
 
 module_init(init_basic)
 module_exit(exit_basic)
+MODULE_DESCRIPTION("TC basic classifier");
 MODULE_LICENSE("GPL");
index bd9322d..7ee8dbf 100644 (file)
@@ -222,4 +222,5 @@ static void __exit exit_cgroup_cls(void)
 
 module_init(init_cgroup_cls);
 module_exit(exit_cgroup_cls);
+MODULE_DESCRIPTION("TC cgroup classifier");
 MODULE_LICENSE("GPL");
index c49d6af..afc534e 100644 (file)
@@ -446,4 +446,5 @@ static void __exit exit_fw(void)
 
 module_init(init_fw)
 module_exit(exit_fw)
+MODULE_DESCRIPTION("SKB mark based TC classifier");
 MODULE_LICENSE("GPL");
index 1424bfe..12a505d 100644 (file)
@@ -684,4 +684,5 @@ static void __exit exit_route4(void)
 
 module_init(init_route4)
 module_exit(exit_route4)
+MODULE_DESCRIPTION("Routing table realm based TC classifier");
 MODULE_LICENSE("GPL");
index 6663e97..d5bdfd4 100644 (file)
@@ -1489,4 +1489,5 @@ static void __exit exit_u32(void)
 
 module_init(init_u32)
 module_exit(exit_u32)
+MODULE_DESCRIPTION("Universal 32bit based TC Classifier");
 MODULE_LICENSE("GPL");
index cac870e..9a0b851 100644 (file)
@@ -574,3 +574,4 @@ static void __exit cbs_module_exit(void)
 module_init(cbs_module_init)
 module_exit(cbs_module_exit)
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Credit Based shaper");
index 19c8511..ae1da08 100644 (file)
@@ -513,3 +513,4 @@ module_init(choke_module_init)
 module_exit(choke_module_exit)
 
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Choose and keep responsive flows scheduler");
index 19901e7..097740a 100644 (file)
@@ -495,3 +495,4 @@ static void __exit drr_exit(void)
 module_init(drr_init);
 module_exit(drr_exit);
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Deficit Round Robin scheduler");
index 61d1f0e..4808159 100644 (file)
@@ -513,3 +513,4 @@ static void __exit etf_module_exit(void)
 module_init(etf_module_init)
 module_exit(etf_module_exit)
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Earliest TxTime First (ETF) qdisc");
index b10efea..f7c8849 100644 (file)
@@ -826,3 +826,4 @@ static void __exit ets_exit(void)
 module_init(ets_init);
 module_exit(ets_exit);
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Enhanced Transmission Selection(ETS) scheduler");
index e104042..450f5c6 100644 (file)
@@ -269,3 +269,4 @@ struct Qdisc *fifo_create_dflt(struct Qdisc *sch, struct Qdisc_ops *ops,
        return q ? : ERR_PTR(err);
 }
 EXPORT_SYMBOL(fifo_create_dflt);
+MODULE_DESCRIPTION("Single queue packet and byte based First In First Out(P/BFIFO) scheduler");
index 0fd18c3..3a31c47 100644 (file)
@@ -919,14 +919,8 @@ static const struct nla_policy fq_policy[TCA_FQ_MAX + 1] = {
        [TCA_FQ_TIMER_SLACK]            = { .type = NLA_U32 },
        [TCA_FQ_HORIZON]                = { .type = NLA_U32 },
        [TCA_FQ_HORIZON_DROP]           = { .type = NLA_U8 },
-       [TCA_FQ_PRIOMAP]                = {
-                       .type = NLA_BINARY,
-                       .len = sizeof(struct tc_prio_qopt),
-               },
-       [TCA_FQ_WEIGHTS]                = {
-                       .type = NLA_BINARY,
-                       .len = FQ_BANDS * sizeof(s32),
-               },
+       [TCA_FQ_PRIOMAP]                = NLA_POLICY_EXACT_LEN(sizeof(struct tc_prio_qopt)),
+       [TCA_FQ_WEIGHTS]                = NLA_POLICY_EXACT_LEN(FQ_BANDS * sizeof(s32)),
 };
 
 /* compress a u8 array with all elems <= 3 to an array of 2-bit fields */
index 872d127..8c61eb3 100644 (file)
@@ -945,3 +945,4 @@ module_init(gred_module_init)
 module_exit(gred_module_exit)
 
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Generic Random Early Detection qdisc");
index 880c5f1..16c45da 100644 (file)
@@ -1693,5 +1693,6 @@ hfsc_cleanup(void)
 }
 
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Hierarchical Fair Service Curve scheduler");
 module_init(hfsc_init);
 module_exit(hfsc_cleanup);
index 0d94741..7349233 100644 (file)
@@ -2179,3 +2179,4 @@ static void __exit htb_module_exit(void)
 module_init(htb_module_init)
 module_exit(htb_module_exit)
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Hierarchical Token Bucket scheduler");
index a463a63..5fa9eaa 100644 (file)
@@ -370,3 +370,4 @@ module_exit(ingress_module_exit);
 
 MODULE_ALIAS("sch_clsact");
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Ingress and clsact based ingress and egress qdiscs");
index 793009f..43e53ee 100644 (file)
@@ -789,3 +789,4 @@ module_init(mqprio_module_init);
 module_exit(mqprio_module_exit);
 
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Classful multiqueue prio qdisc");
index 83b3793..b3a5572 100644 (file)
@@ -129,3 +129,4 @@ void mqprio_fp_to_offload(u32 fp[TC_QOPT_MAX_QUEUE],
 EXPORT_SYMBOL_GPL(mqprio_fp_to_offload);
 
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Shared mqprio qdisc code currently between taprio and mqprio");
index 75c9c86..d66d5f0 100644 (file)
@@ -410,3 +410,4 @@ module_init(multiq_module_init)
 module_exit(multiq_module_exit)
 
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Multi queue to hardware queue mapping qdisc");
index 6ba2dc1..fa678eb 100644 (file)
@@ -1307,3 +1307,4 @@ static void __exit netem_module_exit(void)
 module_init(netem_module_init)
 module_exit(netem_module_exit)
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Network characteristics emulator qdisc");
index 35f49ed..992f0c8 100644 (file)
@@ -226,3 +226,4 @@ static void __exit plug_module_exit(void)
 module_init(plug_module_init)
 module_exit(plug_module_exit)
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Qdisc to plug and unplug traffic via netlink control");
index fdc5ef5..8ecdd3e 100644 (file)
@@ -433,3 +433,4 @@ module_init(prio_module_init)
 module_exit(prio_module_exit)
 
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Simple 3-band priority qdisc");
index 2831516..48a604c 100644 (file)
@@ -1535,3 +1535,4 @@ static void __exit qfq_exit(void)
 module_init(qfq_init);
 module_exit(qfq_exit);
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Quick Fair Queueing Plus qdisc");
index 16277b6..607b6c8 100644 (file)
@@ -563,3 +563,4 @@ module_init(red_module_init)
 module_exit(red_module_exit)
 
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Random Early Detection qdisc");
index 66dcb18..eb77558 100644 (file)
@@ -937,3 +937,4 @@ static void __exit sfq_module_exit(void)
 module_init(sfq_module_init)
 module_exit(sfq_module_exit)
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Stochastic Fairness qdisc");
index 5df2dac..28beb11 100644 (file)
@@ -307,3 +307,4 @@ module_init(skbprio_module_init)
 module_exit(skbprio_module_exit)
 
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("SKB priority based scheduling qdisc");
index 2e1949d..31a8252 100644 (file)
@@ -2572,3 +2572,4 @@ static void __exit taprio_module_exit(void)
 module_init(taprio_module_init);
 module_exit(taprio_module_exit);
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Time Aware Priority qdisc");
index 17d2d00..dd6b1a7 100644 (file)
@@ -621,3 +621,4 @@ static void __exit tbf_module_exit(void)
 module_init(tbf_module_init)
 module_exit(tbf_module_exit)
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Token Bucket Filter qdisc");
index 7721239..5930461 100644 (file)
@@ -523,3 +523,4 @@ module_init(teql_init);
 module_exit(teql_exit);
 
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("True (or trivial) link equalizer qdisc");
index abd2667..da97f94 100644 (file)
@@ -275,7 +275,7 @@ static int __smc_release(struct smc_sock *smc)
 
        if (!smc->use_fallback) {
                rc = smc_close_active(smc);
-               sock_set_flag(sk, SOCK_DEAD);
+               smc_sock_set_flag(sk, SOCK_DEAD);
                sk->sk_shutdown |= SHUTDOWN_MASK;
        } else {
                if (sk->sk_state != SMC_CLOSED) {
@@ -1743,7 +1743,7 @@ static int smc_clcsock_accept(struct smc_sock *lsmc, struct smc_sock **new_smc)
                if (new_clcsock)
                        sock_release(new_clcsock);
                new_sk->sk_state = SMC_CLOSED;
-               sock_set_flag(new_sk, SOCK_DEAD);
+               smc_sock_set_flag(new_sk, SOCK_DEAD);
                sock_put(new_sk); /* final */
                *new_smc = NULL;
                goto out;
index 24745fd..e377980 100644 (file)
@@ -377,4 +377,9 @@ int smc_nl_dump_hs_limitation(struct sk_buff *skb, struct netlink_callback *cb);
 int smc_nl_enable_hs_limitation(struct sk_buff *skb, struct genl_info *info);
 int smc_nl_disable_hs_limitation(struct sk_buff *skb, struct genl_info *info);
 
+static inline void smc_sock_set_flag(struct sock *sk, enum sock_flags flag)
+{
+       set_bit(flag, &sk->sk_flags);
+}
+
 #endif /* __SMC_H */
index 89105e9..3c06625 100644 (file)
@@ -28,13 +28,15 @@ static void smc_cdc_tx_handler(struct smc_wr_tx_pend_priv *pnd_snd,
 {
        struct smc_cdc_tx_pend *cdcpend = (struct smc_cdc_tx_pend *)pnd_snd;
        struct smc_connection *conn = cdcpend->conn;
+       struct smc_buf_desc *sndbuf_desc;
        struct smc_sock *smc;
        int diff;
 
+       sndbuf_desc = conn->sndbuf_desc;
        smc = container_of(conn, struct smc_sock, conn);
        bh_lock_sock(&smc->sk);
-       if (!wc_status) {
-               diff = smc_curs_diff(cdcpend->conn->sndbuf_desc->len,
+       if (!wc_status && sndbuf_desc) {
+               diff = smc_curs_diff(sndbuf_desc->len,
                                     &cdcpend->conn->tx_curs_fin,
                                     &cdcpend->cursor);
                /* sndbuf_space is decreased in smc_sendmsg */
@@ -114,9 +116,6 @@ int smc_cdc_msg_send(struct smc_connection *conn,
        union smc_host_cursor cfed;
        int rc;
 
-       if (unlikely(!READ_ONCE(conn->sndbuf_desc)))
-               return -ENOBUFS;
-
        smc_cdc_add_pending_send(conn, pend);
 
        conn->tx_cdc_seq++;
@@ -385,7 +384,7 @@ static void smc_cdc_msg_recv_action(struct smc_sock *smc,
                smc->sk.sk_shutdown |= RCV_SHUTDOWN;
                if (smc->clcsock && smc->clcsock->sk)
                        smc->clcsock->sk->sk_shutdown |= RCV_SHUTDOWN;
-               sock_set_flag(&smc->sk, SOCK_DONE);
+               smc_sock_set_flag(&smc->sk, SOCK_DONE);
                sock_hold(&smc->sk); /* sock_put in close_work */
                if (!queue_work(smc_close_wq, &conn->close_work))
                        sock_put(&smc->sk);
index dbdf03e..10219f5 100644 (file)
@@ -116,7 +116,8 @@ static void smc_close_cancel_work(struct smc_sock *smc)
        struct sock *sk = &smc->sk;
 
        release_sock(sk);
-       cancel_work_sync(&smc->conn.close_work);
+       if (cancel_work_sync(&smc->conn.close_work))
+               sock_put(sk);
        cancel_delayed_work_sync(&smc->conn.tx_work);
        lock_sock(sk);
 }
@@ -173,7 +174,7 @@ void smc_close_active_abort(struct smc_sock *smc)
                break;
        }
 
-       sock_set_flag(sk, SOCK_DEAD);
+       smc_sock_set_flag(sk, SOCK_DEAD);
        sk->sk_state_change(sk);
 
        if (release_clcsock) {
index 0d1c4e7..3379c64 100644 (file)
@@ -1685,20 +1685,16 @@ struct file *__sys_socket_file(int family, int type, int protocol)
  *     Therefore, __weak is needed to ensure that the call is still
  *     emitted, by telling the compiler that we don't know what the
  *     function might eventually be.
- *
- *     __diag_* below are needed to dismiss the missing prototype warning.
  */
 
-__diag_push();
-__diag_ignore_all("-Wmissing-prototypes",
-                 "A fmod_ret entry point for BPF programs");
+__bpf_hook_start();
 
 __weak noinline int update_socket_protocol(int family, int type, int protocol)
 {
        return protocol;
 }
 
-__diag_pop();
+__bpf_hook_end();
 
 int __sys_socket(int family, int type, int protocol)
 {
index e8fd257..1a9a5bd 100644 (file)
@@ -88,7 +88,7 @@ const struct nla_policy tipc_nl_net_policy[TIPC_NLA_NET_MAX + 1] = {
 
 const struct nla_policy tipc_nl_link_policy[TIPC_NLA_LINK_MAX + 1] = {
        [TIPC_NLA_LINK_UNSPEC]          = { .type = NLA_UNSPEC },
-       [TIPC_NLA_LINK_NAME]            = { .type = NLA_STRING,
+       [TIPC_NLA_LINK_NAME]            = { .type = NLA_NUL_STRING,
                                            .len = TIPC_MAX_LINK_NAME },
        [TIPC_NLA_LINK_MTU]             = { .type = NLA_U32 },
        [TIPC_NLA_LINK_BROADCAST]       = { .type = NLA_FLAG },
@@ -125,7 +125,7 @@ const struct nla_policy tipc_nl_prop_policy[TIPC_NLA_PROP_MAX + 1] = {
 
 const struct nla_policy tipc_nl_bearer_policy[TIPC_NLA_BEARER_MAX + 1] = {
        [TIPC_NLA_BEARER_UNSPEC]        = { .type = NLA_UNSPEC },
-       [TIPC_NLA_BEARER_NAME]          = { .type = NLA_STRING,
+       [TIPC_NLA_BEARER_NAME]          = { .type = NLA_NUL_STRING,
                                            .len = TIPC_MAX_BEARER_NAME },
        [TIPC_NLA_BEARER_PROP]          = { .type = NLA_NESTED },
        [TIPC_NLA_BEARER_DOMAIN]        = { .type = NLA_U32 }
index e22c814..f6dc896 100644 (file)
@@ -130,6 +130,8 @@ static void virtio_transport_init_hdr(struct sk_buff *skb,
        hdr->dst_port   = cpu_to_le32(dst_port);
        hdr->flags      = cpu_to_le32(info->flags);
        hdr->len        = cpu_to_le32(payload_len);
+       hdr->buf_alloc  = cpu_to_le32(0);
+       hdr->fwd_cnt    = cpu_to_le32(0);
 }
 
 static void virtio_transport_copy_nonlinear_skb(const struct sk_buff *skb,
@@ -1369,11 +1371,17 @@ virtio_transport_recv_connected(struct sock *sk,
                        vsk->peer_shutdown |= RCV_SHUTDOWN;
                if (le32_to_cpu(hdr->flags) & VIRTIO_VSOCK_SHUTDOWN_SEND)
                        vsk->peer_shutdown |= SEND_SHUTDOWN;
-               if (vsk->peer_shutdown == SHUTDOWN_MASK &&
-                   vsock_stream_has_data(vsk) <= 0 &&
-                   !sock_flag(sk, SOCK_DONE)) {
-                       (void)virtio_transport_reset(vsk, NULL);
-                       virtio_transport_do_close(vsk, true);
+               if (vsk->peer_shutdown == SHUTDOWN_MASK) {
+                       if (vsock_stream_has_data(vsk) <= 0 && !sock_flag(sk, SOCK_DONE)) {
+                               (void)virtio_transport_reset(vsk, NULL);
+                               virtio_transport_do_close(vsk, true);
+                       }
+                       /* Remove this socket anyway because the remote peer sent
+                        * the shutdown. This way a new connection will succeed
+                        * if the remote peer uses the same source port,
+                        * even if the old socket is still unreleased, but now disconnected.
+                        */
+                       vsock_remove_sock(vsk);
                }
                if (le32_to_cpu(virtio_vsock_hdr(skb)->flags))
                        sk->sk_state_change(sk);
index d74f3fd..7d5e920 100644 (file)
@@ -27,9 +27,7 @@ struct bpf_xfrm_info {
        int link;
 };
 
-__diag_push();
-__diag_ignore_all("-Wmissing-prototypes",
-                 "Global functions as their definitions will be in xfrm_interface BTF");
+__bpf_kfunc_start_defs();
 
 /* bpf_skb_get_xfrm_info - Get XFRM metadata
  *
@@ -93,7 +91,7 @@ __bpf_kfunc int bpf_skb_set_xfrm_info(struct __sk_buff *skb_ctx, const struct bp
        return 0;
 }
 
-__diag_pop()
+__bpf_kfunc_end_defs();
 
 BTF_SET8_START(xfrm_ifc_kfunc_set)
 BTF_ID_FLAGS(func, bpf_skb_get_xfrm_info)
index 75b744b..bc5065b 100644 (file)
@@ -121,6 +121,8 @@ const char *devlink_port_fn_opstate_str(enum devlink_port_fn_opstate value)
 static const char * const devlink_port_fn_attr_cap_strmap[] = {
        [0] = "roce-bit",
        [1] = "migratable-bit",
+       [2] = "ipsec-crypto-bit",
+       [3] = "ipsec-packet-bit",
 };
 
 const char *devlink_port_fn_attr_cap_str(enum devlink_port_fn_attr_cap value)
index fec6828..360b644 100644 (file)
@@ -50,9 +50,116 @@ struct ynl_policy_nest nfsd_rpc_status_nest = {
 /* Common nested types */
 /* ============== NFSD_CMD_RPC_STATUS_GET ============== */
 /* NFSD_CMD_RPC_STATUS_GET - dump */
-void nfsd_rpc_status_get_list_free(struct nfsd_rpc_status_get_list *rsp)
+int nfsd_rpc_status_get_rsp_dump_parse(const struct nlmsghdr *nlh, void *data)
 {
-       struct nfsd_rpc_status_get_list *next = rsp;
+       struct nfsd_rpc_status_get_rsp_dump *dst;
+       struct ynl_parse_arg *yarg = data;
+       unsigned int n_compound_ops = 0;
+       const struct nlattr *attr;
+       int i;
+
+       dst = yarg->data;
+
+       if (dst->compound_ops)
+               return ynl_error_parse(yarg, "attribute already present (rpc-status.compound-ops)");
+
+       mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
+               unsigned int type = mnl_attr_get_type(attr);
+
+               if (type == NFSD_A_RPC_STATUS_XID) {
+                       if (ynl_attr_validate(yarg, attr))
+                               return MNL_CB_ERROR;
+                       dst->_present.xid = 1;
+                       dst->xid = mnl_attr_get_u32(attr);
+               } else if (type == NFSD_A_RPC_STATUS_FLAGS) {
+                       if (ynl_attr_validate(yarg, attr))
+                               return MNL_CB_ERROR;
+                       dst->_present.flags = 1;
+                       dst->flags = mnl_attr_get_u32(attr);
+               } else if (type == NFSD_A_RPC_STATUS_PROG) {
+                       if (ynl_attr_validate(yarg, attr))
+                               return MNL_CB_ERROR;
+                       dst->_present.prog = 1;
+                       dst->prog = mnl_attr_get_u32(attr);
+               } else if (type == NFSD_A_RPC_STATUS_VERSION) {
+                       if (ynl_attr_validate(yarg, attr))
+                               return MNL_CB_ERROR;
+                       dst->_present.version = 1;
+                       dst->version = mnl_attr_get_u8(attr);
+               } else if (type == NFSD_A_RPC_STATUS_PROC) {
+                       if (ynl_attr_validate(yarg, attr))
+                               return MNL_CB_ERROR;
+                       dst->_present.proc = 1;
+                       dst->proc = mnl_attr_get_u32(attr);
+               } else if (type == NFSD_A_RPC_STATUS_SERVICE_TIME) {
+                       if (ynl_attr_validate(yarg, attr))
+                               return MNL_CB_ERROR;
+                       dst->_present.service_time = 1;
+                       dst->service_time = mnl_attr_get_u64(attr);
+               } else if (type == NFSD_A_RPC_STATUS_SADDR4) {
+                       if (ynl_attr_validate(yarg, attr))
+                               return MNL_CB_ERROR;
+                       dst->_present.saddr4 = 1;
+                       dst->saddr4 = mnl_attr_get_u32(attr);
+               } else if (type == NFSD_A_RPC_STATUS_DADDR4) {
+                       if (ynl_attr_validate(yarg, attr))
+                               return MNL_CB_ERROR;
+                       dst->_present.daddr4 = 1;
+                       dst->daddr4 = mnl_attr_get_u32(attr);
+               } else if (type == NFSD_A_RPC_STATUS_SADDR6) {
+                       unsigned int len;
+
+                       if (ynl_attr_validate(yarg, attr))
+                               return MNL_CB_ERROR;
+
+                       len = mnl_attr_get_payload_len(attr);
+                       dst->_present.saddr6_len = len;
+                       dst->saddr6 = malloc(len);
+                       memcpy(dst->saddr6, mnl_attr_get_payload(attr), len);
+               } else if (type == NFSD_A_RPC_STATUS_DADDR6) {
+                       unsigned int len;
+
+                       if (ynl_attr_validate(yarg, attr))
+                               return MNL_CB_ERROR;
+
+                       len = mnl_attr_get_payload_len(attr);
+                       dst->_present.daddr6_len = len;
+                       dst->daddr6 = malloc(len);
+                       memcpy(dst->daddr6, mnl_attr_get_payload(attr), len);
+               } else if (type == NFSD_A_RPC_STATUS_SPORT) {
+                       if (ynl_attr_validate(yarg, attr))
+                               return MNL_CB_ERROR;
+                       dst->_present.sport = 1;
+                       dst->sport = mnl_attr_get_u16(attr);
+               } else if (type == NFSD_A_RPC_STATUS_DPORT) {
+                       if (ynl_attr_validate(yarg, attr))
+                               return MNL_CB_ERROR;
+                       dst->_present.dport = 1;
+                       dst->dport = mnl_attr_get_u16(attr);
+               } else if (type == NFSD_A_RPC_STATUS_COMPOUND_OPS) {
+                       n_compound_ops++;
+               }
+       }
+
+       if (n_compound_ops) {
+               dst->compound_ops = calloc(n_compound_ops, sizeof(*dst->compound_ops));
+               dst->n_compound_ops = n_compound_ops;
+               i = 0;
+               mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
+                       if (mnl_attr_get_type(attr) == NFSD_A_RPC_STATUS_COMPOUND_OPS) {
+                               dst->compound_ops[i] = mnl_attr_get_u32(attr);
+                               i++;
+                       }
+               }
+       }
+
+       return MNL_CB_OK;
+}
+
+void
+nfsd_rpc_status_get_rsp_list_free(struct nfsd_rpc_status_get_rsp_list *rsp)
+{
+       struct nfsd_rpc_status_get_rsp_list *next = rsp;
 
        while ((void *)next != YNL_LIST_END) {
                rsp = next;
@@ -65,15 +172,16 @@ void nfsd_rpc_status_get_list_free(struct nfsd_rpc_status_get_list *rsp)
        }
 }
 
-struct nfsd_rpc_status_get_list *nfsd_rpc_status_get_dump(struct ynl_sock *ys)
+struct nfsd_rpc_status_get_rsp_list *
+nfsd_rpc_status_get_dump(struct ynl_sock *ys)
 {
        struct ynl_dump_state yds = {};
        struct nlmsghdr *nlh;
        int err;
 
        yds.ys = ys;
-       yds.alloc_sz = sizeof(struct nfsd_rpc_status_get_list);
-       yds.cb = nfsd_rpc_status_get_rsp_parse;
+       yds.alloc_sz = sizeof(struct nfsd_rpc_status_get_rsp_list);
+       yds.cb = nfsd_rpc_status_get_rsp_dump_parse;
        yds.rsp_cmd = NFSD_CMD_RPC_STATUS_GET;
        yds.rsp_policy = &nfsd_rpc_status_nest;
 
@@ -86,7 +194,7 @@ struct nfsd_rpc_status_get_list *nfsd_rpc_status_get_dump(struct ynl_sock *ys)
        return yds.first;
 
 free_list:
-       nfsd_rpc_status_get_list_free(yds.first);
+       nfsd_rpc_status_get_rsp_list_free(yds.first);
        return NULL;
 }
 
index b6b6950..989c6e2 100644 (file)
@@ -21,13 +21,47 @@ const char *nfsd_op_str(int op);
 /* Common nested types */
 /* ============== NFSD_CMD_RPC_STATUS_GET ============== */
 /* NFSD_CMD_RPC_STATUS_GET - dump */
-struct nfsd_rpc_status_get_list {
-       struct nfsd_rpc_status_get_list *next;
-       struct nfsd_rpc_status_get_rsp obj __attribute__ ((aligned (8)));
+struct nfsd_rpc_status_get_rsp_dump {
+       struct {
+               __u32 xid:1;
+               __u32 flags:1;
+               __u32 prog:1;
+               __u32 version:1;
+               __u32 proc:1;
+               __u32 service_time:1;
+               __u32 saddr4:1;
+               __u32 daddr4:1;
+               __u32 saddr6_len;
+               __u32 daddr6_len;
+               __u32 sport:1;
+               __u32 dport:1;
+       } _present;
+
+       __u32 xid /* big-endian */;
+       __u32 flags;
+       __u32 prog;
+       __u8 version;
+       __u32 proc;
+       __s64 service_time;
+       __u32 saddr4 /* big-endian */;
+       __u32 daddr4 /* big-endian */;
+       void *saddr6;
+       void *daddr6;
+       __u16 sport /* big-endian */;
+       __u16 dport /* big-endian */;
+       unsigned int n_compound_ops;
+       __u32 *compound_ops;
+};
+
+struct nfsd_rpc_status_get_rsp_list {
+       struct nfsd_rpc_status_get_rsp_list *next;
+       struct nfsd_rpc_status_get_rsp_dump obj __attribute__((aligned(8)));
 };
 
-void nfsd_rpc_status_get_list_free(struct nfsd_rpc_status_get_list *rsp);
+void
+nfsd_rpc_status_get_rsp_list_free(struct nfsd_rpc_status_get_rsp_list *rsp);
 
-struct nfsd_rpc_status_get_list *nfsd_rpc_status_get_dump(struct ynl_sock *ys);
+struct nfsd_rpc_status_get_rsp_list *
+nfsd_rpc_status_get_dump(struct ynl_sock *ys);
 
 #endif /* _LINUX_NFSD_GEN_H */
index 1342743..c4003a8 100755 (executable)
@@ -3,6 +3,7 @@
 
 import argparse
 import collections
+import filecmp
 import os
 import re
 import shutil
@@ -1168,7 +1169,7 @@ class CodeWriter:
         if out_file is None:
             self._out = os.sys.stdout
         else:
-            self._out = tempfile.TemporaryFile('w+')
+            self._out = tempfile.NamedTemporaryFile('w+')
             self._out_file = out_file
 
     def __del__(self):
@@ -1177,6 +1178,10 @@ class CodeWriter:
     def close_out_file(self):
         if self._out == os.sys.stdout:
             return
+        # Avoid modifying the file if contents didn't change
+        self._out.flush()
+        if os.path.isfile(self._out_file) and filecmp.cmp(self._out.name, self._out_file, shallow=False):
+            return
         with open(self._out_file, 'w+') as out_file:
             self._out.seek(0)
             shutil.copyfileobj(self._out, out_file)
index a5e246f..91907b3 100644 (file)
@@ -39,9 +39,7 @@ struct bpf_testmod_struct_arg_4 {
        int b;
 };
 
-__diag_push();
-__diag_ignore_all("-Wmissing-prototypes",
-                 "Global functions as their definitions will be in bpf_testmod.ko BTF");
+__bpf_hook_start();
 
 noinline int
 bpf_testmod_test_struct_arg_1(struct bpf_testmod_struct_arg_2 a, int b, int c) {
@@ -335,7 +333,7 @@ noinline int bpf_fentry_shadow_test(int a)
 }
 EXPORT_SYMBOL_GPL(bpf_fentry_shadow_test);
 
-__diag_pop();
+__bpf_hook_end();
 
 static struct bin_attribute bin_attr_bpf_testmod_file __ro_after_init = {
        .attr = { .name = "bpf_testmod", .mode = 0666, },
index 1a9eeef..8bf497a 100644 (file)
@@ -326,20 +326,14 @@ static int map_create(__u32 type, const char *name, struct bpf_map_create_opts *
 
 static int create_hash(void)
 {
-       struct bpf_map_create_opts map_opts = {
-               .sz = sizeof(map_opts),
-               .map_flags = BPF_F_NO_PREALLOC,
-       };
+       LIBBPF_OPTS(bpf_map_create_opts, map_opts, .map_flags = BPF_F_NO_PREALLOC);
 
        return map_create(BPF_MAP_TYPE_HASH, "hash", &map_opts);
 }
 
 static int create_percpu_hash(void)
 {
-       struct bpf_map_create_opts map_opts = {
-               .sz = sizeof(map_opts),
-               .map_flags = BPF_F_NO_PREALLOC,
-       };
+       LIBBPF_OPTS(bpf_map_create_opts, map_opts, .map_flags = BPF_F_NO_PREALLOC);
 
        return map_create(BPF_MAP_TYPE_PERCPU_HASH, "percpu_hash", &map_opts);
 }
@@ -356,21 +350,17 @@ static int create_percpu_hash_prealloc(void)
 
 static int create_lru_hash(__u32 type, __u32 map_flags)
 {
-       struct bpf_map_create_opts map_opts = {
-               .sz = sizeof(map_opts),
-               .map_flags = map_flags,
-       };
+       LIBBPF_OPTS(bpf_map_create_opts, map_opts, .map_flags = map_flags);
 
        return map_create(type, "lru_hash", &map_opts);
 }
 
 static int create_hash_of_maps(void)
 {
-       struct bpf_map_create_opts map_opts = {
-               .sz = sizeof(map_opts),
+       LIBBPF_OPTS(bpf_map_create_opts, map_opts,
                .map_flags = BPF_F_NO_PREALLOC,
                .inner_map_fd = create_small_hash(),
-       };
+       );
        int ret;
 
        ret = map_create_opts(BPF_MAP_TYPE_HASH_OF_MAPS, "hash_of_maps",
index e02feb5..574d9a0 100644 (file)
@@ -4,6 +4,7 @@
 #include <test_progs.h>
 #include <bpf/libbpf.h>
 #include <bpf/btf.h>
+#include "iters_css_task.skel.h"
 #include "cgroup_iter.skel.h"
 #include "cgroup_helpers.h"
 
@@ -263,6 +264,35 @@ close_cgrp:
        close(cgrp_fd);
 }
 
+static void test_walk_self_only_css_task(void)
+{
+       struct iters_css_task *skel;
+       int err;
+
+       skel = iters_css_task__open();
+       if (!ASSERT_OK_PTR(skel, "skel_open"))
+               return;
+
+       bpf_program__set_autoload(skel->progs.cgroup_id_printer, true);
+
+       err = iters_css_task__load(skel);
+       if (!ASSERT_OK(err, "skel_load"))
+               goto cleanup;
+
+       err = join_cgroup(cg_path[CHILD2]);
+       if (!ASSERT_OK(err, "join_cgroup"))
+               goto cleanup;
+
+       skel->bss->target_pid = getpid();
+       snprintf(expected_output, sizeof(expected_output),
+               PROLOGUE "%8llu\n" EPILOGUE, cg_id[CHILD2]);
+       read_from_cgroup_iter(skel->progs.cgroup_id_printer, cg_fd[CHILD2],
+               BPF_CGROUP_ITER_SELF_ONLY, "test_walk_self_only_css_task");
+       ASSERT_EQ(skel->bss->css_task_cnt, 1, "css_task_cnt");
+cleanup:
+       iters_css_task__destroy(skel);
+}
+
 void test_cgroup_iter(void)
 {
        struct cgroup_iter *skel = NULL;
@@ -293,6 +323,9 @@ void test_cgroup_iter(void)
                test_walk_self_only(skel);
        if (test__start_subtest("cgroup_iter__dead_self_only"))
                test_walk_dead_self_only(skel);
+       if (test__start_subtest("cgroup_iter__self_only_css_task"))
+               test_walk_self_only_css_task();
+
 out:
        cgroup_iter__destroy(skel);
        cleanup_cgroups();
index c242579..bf84d4a 100644 (file)
@@ -294,6 +294,7 @@ void test_iters(void)
        RUN_TESTS(iters_state_safety);
        RUN_TESTS(iters_looping);
        RUN_TESTS(iters);
+       RUN_TESTS(iters_css_task);
 
        if (env.has_testmod)
                RUN_TESTS(iters_testmod_seq);
index 214d9f4..ea933fd 100644 (file)
@@ -8,7 +8,8 @@
 #include <sys/types.h>
 #include <test_progs.h>
 
-#define TDIR "/sys/kernel/debug"
+/* TDIR must be in a location we can create a directory in. */
+#define TDIR "/tmp/test_bpffs_testdir"
 
 static int read_iter(char *file)
 {
@@ -43,8 +44,11 @@ static int fn(void)
        if (!ASSERT_OK(err, "mount /"))
                goto out;
 
-       err = umount(TDIR);
-       if (!ASSERT_OK(err, "umount " TDIR))
+       err =  mkdir(TDIR, 0777);
+       /* If the directory already exists we can carry on. It may be left over
+        * from a previous run.
+        */
+       if ((err && errno != EEXIST) && !ASSERT_OK(err, "mkdir " TDIR))
                goto out;
 
        err = mount("none", TDIR, "tmpfs", 0, NULL);
@@ -138,6 +142,7 @@ out:
        rmdir(TDIR "/fs1");
        rmdir(TDIR "/fs2");
        umount(TDIR);
+       rmdir(TDIR);
        exit(err);
 }
 
index e3e68c9..e5c61aa 100644 (file)
@@ -46,6 +46,7 @@
 #include "verifier_movsx.skel.h"
 #include "verifier_netfilter_ctx.skel.h"
 #include "verifier_netfilter_retcode.skel.h"
+#include "verifier_precision.skel.h"
 #include "verifier_prevent_map_lookup.skel.h"
 #include "verifier_raw_stack.skel.h"
 #include "verifier_raw_tp_writable.skel.h"
@@ -153,6 +154,7 @@ void test_verifier_meta_access(void)          { RUN(verifier_meta_access); }
 void test_verifier_movsx(void)                 { RUN(verifier_movsx); }
 void test_verifier_netfilter_ctx(void)        { RUN(verifier_netfilter_ctx); }
 void test_verifier_netfilter_retcode(void)    { RUN(verifier_netfilter_retcode); }
+void test_verifier_precision(void)            { RUN(verifier_precision); }
 void test_verifier_prevent_map_lookup(void)   { RUN(verifier_prevent_map_lookup); }
 void test_verifier_raw_stack(void)            { RUN(verifier_raw_stack); }
 void test_verifier_raw_tp_writable(void)      { RUN(verifier_raw_tp_writable); }
index 5089ce3..9ac7586 100644 (file)
@@ -10,6 +10,7 @@
 
 char _license[] SEC("license") = "GPL";
 
+struct cgroup *bpf_cgroup_acquire(struct cgroup *p) __ksym;
 struct cgroup *bpf_cgroup_from_id(u64 cgid) __ksym;
 void bpf_cgroup_release(struct cgroup *p) __ksym;
 
@@ -45,3 +46,57 @@ int BPF_PROG(iter_css_task_for_each, struct vm_area_struct *vma,
 
        return -EPERM;
 }
+
+static inline u64 cgroup_id(struct cgroup *cgrp)
+{
+       return cgrp->kn->id;
+}
+
+SEC("?iter/cgroup")
+int cgroup_id_printer(struct bpf_iter__cgroup *ctx)
+{
+       struct seq_file *seq = ctx->meta->seq;
+       struct cgroup *cgrp = ctx->cgroup;
+       struct cgroup_subsys_state *css;
+       struct task_struct *task;
+
+       /* epilogue */
+       if (cgrp == NULL) {
+               BPF_SEQ_PRINTF(seq, "epilogue\n");
+               return 0;
+       }
+
+       /* prologue */
+       if (ctx->meta->seq_num == 0)
+               BPF_SEQ_PRINTF(seq, "prologue\n");
+
+       BPF_SEQ_PRINTF(seq, "%8llu\n", cgroup_id(cgrp));
+
+       css = &cgrp->self;
+       css_task_cnt = 0;
+       bpf_for_each(css_task, task, css, CSS_TASK_ITER_PROCS) {
+               if (task->pid == target_pid)
+                       css_task_cnt++;
+       }
+
+       return 0;
+}
+
+SEC("?fentry.s/" SYS_PREFIX "sys_getpgid")
+int BPF_PROG(iter_css_task_for_each_sleep)
+{
+       u64 cgrp_id = bpf_get_current_cgroup_id();
+       struct cgroup *cgrp = bpf_cgroup_from_id(cgrp_id);
+       struct cgroup_subsys_state *css;
+       struct task_struct *task;
+
+       if (cgrp == NULL)
+               return 0;
+       css = &cgrp->self;
+
+       bpf_for_each(css_task, task, css, CSS_TASK_ITER_PROCS) {
+
+       }
+       bpf_cgroup_release(cgrp);
+       return 0;
+}
index c3bf96a..6b1588d 100644 (file)
@@ -84,8 +84,8 @@ int BPF_PROG(iter_css_lock_and_unlock)
        return 0;
 }
 
-SEC("?fentry.s/" SYS_PREFIX "sys_getpgid")
-__failure __msg("css_task_iter is only allowed in bpf_lsm and bpf iter-s")
+SEC("?fentry/" SYS_PREFIX "sys_getpgid")
+__failure __msg("css_task_iter is only allowed in bpf_lsm, bpf_iter and sleepable progs")
 int BPF_PROG(iter_css_task_for_each)
 {
        u64 cg_id = bpf_get_current_cgroup_id();
diff --git a/tools/testing/selftests/bpf/progs/verifier_precision.c b/tools/testing/selftests/bpf/progs/verifier_precision.c
new file mode 100644 (file)
index 0000000..193c0f8
--- /dev/null
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (C) 2023 SUSE LLC */
+#include <linux/bpf.h>
+#include <bpf/bpf_helpers.h>
+#include "bpf_misc.h"
+
+SEC("?raw_tp")
+__success __log_level(2)
+__msg("mark_precise: frame0: regs=r2 stack= before 3: (bf) r1 = r10")
+__msg("mark_precise: frame0: regs=r2 stack= before 2: (55) if r2 != 0xfffffff8 goto pc+2")
+__msg("mark_precise: frame0: regs=r2 stack= before 1: (87) r2 = -r2")
+__msg("mark_precise: frame0: regs=r2 stack= before 0: (b7) r2 = 8")
+__naked int bpf_neg(void)
+{
+       asm volatile (
+               "r2 = 8;"
+               "r2 = -r2;"
+               "if r2 != -8 goto 1f;"
+               "r1 = r10;"
+               "r1 += r2;"
+       "1:"
+               "r0 = 0;"
+               "exit;"
+               ::: __clobber_all);
+}
+
+SEC("?raw_tp")
+__success __log_level(2)
+__msg("mark_precise: frame0: regs=r2 stack= before 3: (bf) r1 = r10")
+__msg("mark_precise: frame0: regs=r2 stack= before 2: (55) if r2 != 0x0 goto pc+2")
+__msg("mark_precise: frame0: regs=r2 stack= before 1: (d4) r2 = le16 r2")
+__msg("mark_precise: frame0: regs=r2 stack= before 0: (b7) r2 = 0")
+__naked int bpf_end_to_le(void)
+{
+       asm volatile (
+               "r2 = 0;"
+               "r2 = le16 r2;"
+               "if r2 != 0 goto 1f;"
+               "r1 = r10;"
+               "r1 += r2;"
+       "1:"
+               "r0 = 0;"
+               "exit;"
+               ::: __clobber_all);
+}
+
+
+SEC("?raw_tp")
+__success __log_level(2)
+__msg("mark_precise: frame0: regs=r2 stack= before 3: (bf) r1 = r10")
+__msg("mark_precise: frame0: regs=r2 stack= before 2: (55) if r2 != 0x0 goto pc+2")
+__msg("mark_precise: frame0: regs=r2 stack= before 1: (dc) r2 = be16 r2")
+__msg("mark_precise: frame0: regs=r2 stack= before 0: (b7) r2 = 0")
+__naked int bpf_end_to_be(void)
+{
+       asm volatile (
+               "r2 = 0;"
+               "r2 = be16 r2;"
+               "if r2 != 0 goto 1f;"
+               "r1 = r10;"
+               "r1 += r2;"
+       "1:"
+               "r0 = 0;"
+               "exit;"
+               ::: __clobber_all);
+}
+
+#if (defined(__TARGET_ARCH_arm64) || defined(__TARGET_ARCH_x86) || \
+       (defined(__TARGET_ARCH_riscv) && __riscv_xlen == 64) || \
+       defined(__TARGET_ARCH_arm) || defined(__TARGET_ARCH_s390)) && \
+       __clang_major__ >= 18
+
+SEC("?raw_tp")
+__success __log_level(2)
+__msg("mark_precise: frame0: regs=r2 stack= before 3: (bf) r1 = r10")
+__msg("mark_precise: frame0: regs=r2 stack= before 2: (55) if r2 != 0x0 goto pc+2")
+__msg("mark_precise: frame0: regs=r2 stack= before 1: (d7) r2 = bswap16 r2")
+__msg("mark_precise: frame0: regs=r2 stack= before 0: (b7) r2 = 0")
+__naked int bpf_end_bswap(void)
+{
+       asm volatile (
+               "r2 = 0;"
+               "r2 = bswap16 r2;"
+               "if r2 != 0 goto 1f;"
+               "r1 = r10;"
+               "r1 += r2;"
+       "1:"
+               "r0 = 0;"
+               "exit;"
+               ::: __clobber_all);
+}
+
+#endif /* v4 instruction */
index 3af2501..b616575 100644 (file)
        .expected_attach_type = BPF_SK_LOOKUP,
        .runs = -1,
 },
+{
+       "BPF_ST_MEM stack imm sign",
+       /* Check if verifier correctly reasons about sign of an
+        * immediate spilled to stack by BPF_ST instruction.
+        *
+        *   fp[-8] = -44;
+        *   r0 = fp[-8];
+        *   if r0 s< 0 goto ret0;
+        *   r0 = -1;
+        *   exit;
+        * ret0:
+        *   r0 = 0;
+        *   exit;
+        */
+       .insns = {
+       BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, -44),
+       BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
+       BPF_JMP_IMM(BPF_JSLT, BPF_REG_0, 0, 2),
+       BPF_MOV64_IMM(BPF_REG_0, -1),
+       BPF_EXIT_INSN(),
+       BPF_MOV64_IMM(BPF_REG_0, 0),
+       BPF_EXIT_INSN(),
+       },
+       /* Use prog type that requires return value in range [0, 1] */
+       .prog_type = BPF_PROG_TYPE_SK_LOOKUP,
+       .expected_attach_type = BPF_SK_LOOKUP,
+       .result = VERBOSE_ACCEPT,
+       .runs = -1,
+       .errstr = "0: (7a) *(u64 *)(r10 -8) = -44        ; R10=fp0 fp-8_w=-44\
+       2: (c5) if r0 s< 0x0 goto pc+2\
+       R0_w=-44",
+},
index 17c0f92..c3ba40d 100644 (file)
@@ -430,7 +430,7 @@ static void print_usage(void)
 
 static void read_args(int argc, char *argv[])
 {
-       char opt;
+       int opt;
 
        while ((opt = getopt(argc, argv, "mh")) != -1) {
                switch (opt) {
index f838dd3..b3b2dc5 100755 (executable)
@@ -2048,7 +2048,7 @@ run_test() {
        case $ret in
                0)
                        all_skipped=false
-                       [ $exitcode=$ksft_skip ] && exitcode=0
+                       [ $exitcode -eq $ksft_skip ] && exitcode=0
                ;;
                $ksft_skip)
                        [ $all_skipped = true ] && exitcode=$ksft_skip
index 9233672..ae2b33c 100644 (file)
@@ -85,6 +85,48 @@ void vsock_wait_remote_close(int fd)
        close(epollfd);
 }
 
+/* Bind to <bind_port>, connect to <cid, port> and return the file descriptor. */
+int vsock_bind_connect(unsigned int cid, unsigned int port, unsigned int bind_port, int type)
+{
+       struct sockaddr_vm sa_client = {
+               .svm_family = AF_VSOCK,
+               .svm_cid = VMADDR_CID_ANY,
+               .svm_port = bind_port,
+       };
+       struct sockaddr_vm sa_server = {
+               .svm_family = AF_VSOCK,
+               .svm_cid = cid,
+               .svm_port = port,
+       };
+
+       int client_fd, ret;
+
+       client_fd = socket(AF_VSOCK, type, 0);
+       if (client_fd < 0) {
+               perror("socket");
+               exit(EXIT_FAILURE);
+       }
+
+       if (bind(client_fd, (struct sockaddr *)&sa_client, sizeof(sa_client))) {
+               perror("bind");
+               exit(EXIT_FAILURE);
+       }
+
+       timeout_begin(TIMEOUT);
+       do {
+               ret = connect(client_fd, (struct sockaddr *)&sa_server, sizeof(sa_server));
+               timeout_check("connect");
+       } while (ret < 0 && errno == EINTR);
+       timeout_end();
+
+       if (ret < 0) {
+               perror("connect");
+               exit(EXIT_FAILURE);
+       }
+
+       return client_fd;
+}
+
 /* Connect to <cid, port> and return the file descriptor. */
 static int vsock_connect(unsigned int cid, unsigned int port, int type)
 {
@@ -104,6 +146,10 @@ static int vsock_connect(unsigned int cid, unsigned int port, int type)
        control_expectln("LISTENING");
 
        fd = socket(AF_VSOCK, type, 0);
+       if (fd < 0) {
+               perror("socket");
+               exit(EXIT_FAILURE);
+       }
 
        timeout_begin(TIMEOUT);
        do {
@@ -132,11 +178,8 @@ int vsock_seqpacket_connect(unsigned int cid, unsigned int port)
        return vsock_connect(cid, port, SOCK_SEQPACKET);
 }
 
-/* Listen on <cid, port> and return the first incoming connection.  The remote
- * address is stored to clientaddrp.  clientaddrp may be NULL.
- */
-static int vsock_accept(unsigned int cid, unsigned int port,
-                       struct sockaddr_vm *clientaddrp, int type)
+/* Listen on <cid, port> and return the file descriptor. */
+static int vsock_listen(unsigned int cid, unsigned int port, int type)
 {
        union {
                struct sockaddr sa;
@@ -148,16 +191,13 @@ static int vsock_accept(unsigned int cid, unsigned int port,
                        .svm_cid = cid,
                },
        };
-       union {
-               struct sockaddr sa;
-               struct sockaddr_vm svm;
-       } clientaddr;
-       socklen_t clientaddr_len = sizeof(clientaddr.svm);
        int fd;
-       int client_fd;
-       int old_errno;
 
        fd = socket(AF_VSOCK, type, 0);
+       if (fd < 0) {
+               perror("socket");
+               exit(EXIT_FAILURE);
+       }
 
        if (bind(fd, &addr.sa, sizeof(addr.svm)) < 0) {
                perror("bind");
@@ -169,6 +209,24 @@ static int vsock_accept(unsigned int cid, unsigned int port,
                exit(EXIT_FAILURE);
        }
 
+       return fd;
+}
+
+/* Listen on <cid, port> and return the first incoming connection.  The remote
+ * address is stored to clientaddrp.  clientaddrp may be NULL.
+ */
+static int vsock_accept(unsigned int cid, unsigned int port,
+                       struct sockaddr_vm *clientaddrp, int type)
+{
+       union {
+               struct sockaddr sa;
+               struct sockaddr_vm svm;
+       } clientaddr;
+       socklen_t clientaddr_len = sizeof(clientaddr.svm);
+       int fd, client_fd, old_errno;
+
+       fd = vsock_listen(cid, port, type);
+
        control_writeln("LISTENING");
 
        timeout_begin(TIMEOUT);
@@ -207,6 +265,11 @@ int vsock_stream_accept(unsigned int cid, unsigned int port,
        return vsock_accept(cid, port, clientaddrp, SOCK_STREAM);
 }
 
+int vsock_stream_listen(unsigned int cid, unsigned int port)
+{
+       return vsock_listen(cid, port, SOCK_STREAM);
+}
+
 int vsock_seqpacket_accept(unsigned int cid, unsigned int port,
                           struct sockaddr_vm *clientaddrp)
 {
index a77175d..03c88d0 100644 (file)
@@ -36,9 +36,12 @@ struct test_case {
 void init_signals(void);
 unsigned int parse_cid(const char *str);
 int vsock_stream_connect(unsigned int cid, unsigned int port);
+int vsock_bind_connect(unsigned int cid, unsigned int port,
+                      unsigned int bind_port, int type);
 int vsock_seqpacket_connect(unsigned int cid, unsigned int port);
 int vsock_stream_accept(unsigned int cid, unsigned int port,
                        struct sockaddr_vm *clientaddrp);
+int vsock_stream_listen(unsigned int cid, unsigned int port);
 int vsock_seqpacket_accept(unsigned int cid, unsigned int port,
                           struct sockaddr_vm *clientaddrp);
 void vsock_wait_remote_close(int fd);
index c1f7bc9..5b0e93f 100644 (file)
@@ -1180,6 +1180,51 @@ static void test_stream_shutrd_server(const struct test_opts *opts)
        close(fd);
 }
 
+static void test_double_bind_connect_server(const struct test_opts *opts)
+{
+       int listen_fd, client_fd, i;
+       struct sockaddr_vm sa_client;
+       socklen_t socklen_client = sizeof(sa_client);
+
+       listen_fd = vsock_stream_listen(VMADDR_CID_ANY, 1234);
+
+       for (i = 0; i < 2; i++) {
+               control_writeln("LISTENING");
+
+               timeout_begin(TIMEOUT);
+               do {
+                       client_fd = accept(listen_fd, (struct sockaddr *)&sa_client,
+                                          &socklen_client);
+                       timeout_check("accept");
+               } while (client_fd < 0 && errno == EINTR);
+               timeout_end();
+
+               if (client_fd < 0) {
+                       perror("accept");
+                       exit(EXIT_FAILURE);
+               }
+
+               /* Waiting for remote peer to close connection */
+               vsock_wait_remote_close(client_fd);
+       }
+
+       close(listen_fd);
+}
+
+static void test_double_bind_connect_client(const struct test_opts *opts)
+{
+       int i, client_fd;
+
+       for (i = 0; i < 2; i++) {
+               /* Wait until server is ready to accept a new connection */
+               control_expectln("LISTENING");
+
+               client_fd = vsock_bind_connect(opts->peer_cid, 1234, 4321, SOCK_STREAM);
+
+               close(client_fd);
+       }
+}
+
 static struct test_case test_cases[] = {
        {
                .name = "SOCK_STREAM connection reset",
@@ -1285,6 +1330,11 @@ static struct test_case test_cases[] = {
                .run_client = test_stream_msgzcopy_empty_errq_client,
                .run_server = test_stream_msgzcopy_empty_errq_server,
        },
+       {
+               .name = "SOCK_STREAM double bind connect",
+               .run_client = test_double_bind_connect_client,
+               .run_server = test_double_bind_connect_server,
+       },
        {},
 };