Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'net-7.1-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net

Pull networking fixes from Paolo Abeni:
"Including fixes from netfilter.

Current release - regressions:

- ipmr: free mr_table after RCU grace period.

Previous releases - regressions:

- core: add net_iov_init() and use it to initialize ->page_type

- sched: taprio: fix NULL pointer dereference in class dump

- netfilter: nf_tables:
- use list_del_rcu for netlink hooks
- fix strict mode inbound policy matching

- tcp: make probe0 timer handle expired user timeout

- vrf: fix a potential NPD when removing a port from a VRF

- eth: ice:
- fix NULL pointer dereference in ice_reset_all_vfs()
- fix infinite recursion in ice_cfg_tx_topo via ice_init_dev_hw

Previous releases - always broken:

- page_pool: fix memory-provider leak in error path

- sched: sch_cake: annotate data-races in cake_dump_stats()

- mptcp: fix scheduling with atomic in timestamp sockopt

- psp: check for device unregister when creating assoc

- tls: fix strparser anchor skb leak on offload RX setup failure

- eth:
- stmmac: prevent NULL deref when RX memory exhausted
- airoha: do not read uninitialized fragment address
- rtl8150: fix use-after-free in rtl8150_start_xmit()

Misc:

- add Ido Schimmel as IPv4/IPv6 maintainer

- add David Heidelberg as NFC subsystem maintainer"

* tag 'net-7.1-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (79 commits)
net/sched: cls_flower: revert unintended changes
sfc: fix error code in efx_devlink_info_running_versions()
net: tls: fix strparser anchor skb leak on offload RX setup failure
ice: add dpll peer notification for paired SMA and U.FL pins
ice: fix missing dpll notifications for SW pins
dpll: export __dpll_pin_change_ntf() for use under dpll_lock
ice: fix SMA and U.FL pin state changes affecting paired pin
ice: fix missing SMA pin initialization in DPLL subsystem
ice: fix infinite recursion in ice_cfg_tx_topo via ice_init_dev_hw
ice: fix NULL pointer dereference in ice_reset_all_vfs()
iavf: add VIRTCHNL_OP_ADD_VLAN to success completion handler
iavf: wait for PF confirmation before removing VLAN filters
iavf: stop removing VLAN filters from PF on interface down
iavf: rename IAVF_VLAN_IS_NEW to IAVF_VLAN_ADDING
page_pool: fix memory-provider leak in page_pool_create_percpu() error path
bonding: 3ad: implement proper RCU rules for port->aggregator
net: airoha: Do not return err in ndo_stop() callback
hv_sock: fix ARM64 support
MAINTAINERS: update the IPv4/IPv6 entry and add Ido Schimmel
selftests: drv-net: clarify linters and frameworks in README
...

+1351 -603
+2
Documentation/netlink/specs/psp.yaml
··· 188 188 name: dev-set 189 189 doc: Set the configuration of a PSP device. 190 190 attribute-set: dev 191 + flags: [admin-perm] 191 192 do: 192 193 request: 193 194 attributes: ··· 208 207 name: key-rotate 209 208 doc: Rotate the device key. 210 209 attribute-set: dev 210 + flags: [admin-perm] 211 211 do: 212 212 request: 213 213 attributes:
+52 -18
MAINTAINERS
··· 18672 18672 F: tools/testing/selftests/net/ipsec.c 18673 18673 18674 18674 NETWORKING [IPv4/IPv6] 18675 - M: "David S. Miller" <davem@davemloft.net> 18676 18675 M: David Ahern <dsahern@kernel.org> 18676 + M: Ido Schimmel <idosch@nvidia.com> 18677 18677 L: netdev@vger.kernel.org 18678 18678 S: Maintained 18679 - T: git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git 18680 - F: arch/x86/net/* 18681 - F: include/linux/ip.h 18682 - F: include/linux/ipv6* 18679 + F: Documentation/netlink/specs/rt-addr.yaml 18680 + F: Documentation/netlink/specs/rt-neigh.yaml 18681 + F: Documentation/netlink/specs/rt-route.yaml 18682 + F: Documentation/netlink/specs/rt-rule.yaml 18683 + F: include/linux/inetdevice.h 18684 + F: include/linux/mroute* 18685 + F: include/net/addrconf.h 18686 + F: include/net/arp.h 18683 18687 F: include/net/fib* 18688 + F: include/net/if_inet6.h 18689 + F: include/net/inetpeer.h 18684 18690 F: include/net/ip* 18691 + F: include/net/lwtunnel.h 18692 + F: include/net/ndisc.h 18693 + F: include/net/netns/nexthop.h 18694 + F: include/net/nexthop.h 18685 18695 F: include/net/route.h 18686 - F: net/ipv4/ 18687 - F: net/ipv6/ 18696 + F: include/uapi/linux/fib_rules.h 18697 + F: include/uapi/linux/in_route.h 18698 + F: include/uapi/linux/mroute* 18699 + F: include/uapi/linux/nexthop.h 18700 + F: net/core/fib* 18701 + F: net/core/lwtunnel.c 18702 + F: net/ipv4/arp.c 18703 + F: net/ipv4/devinet.c 18704 + F: net/ipv4/fib* 18705 + F: net/ipv4/icmp.c 18706 + F: net/ipv4/igmp.c 18707 + F: net/ipv4/inet_fragment.c 18708 + F: net/ipv4/inetpeer.c 18709 + F: net/ipv4/ip* 18710 + F: net/ipv4/metrics.c 18711 + F: net/ipv4/netlink.c 18712 + F: net/ipv4/nexthop.c 18713 + F: net/ipv4/route.c 18714 + F: net/ipv6/addr* 18715 + F: net/ipv6/anycast.c 18716 + F: net/ipv6/exthdrs.c 18717 + F: net/ipv6/exthdrs_core.c 18718 + F: net/ipv6/fib* 18719 + F: net/ipv6/icmp.c 18720 + F: net/ipv6/ip* 18721 + F: net/ipv6/mcast* 18722 + F: net/ipv6/ndisc.c 18723 + F: net/ipv6/output_core.c 18724 + F: net/ipv6/reassembly.c 18725 + F: net/ipv6/route.c 18726 + F: tools/testing/selftests/net/fib* 18727 + F: tools/testing/selftests/net/forwarding/ 18688 18728 18689 18729 NETWORKING [LABELED] (NetLabel, Labeled IPsec, SECMARK) 18690 18730 M: Paul Moore <paul@paul-moore.com> ··· 18859 18819 F: drivers/net/net_failover.c 18860 18820 F: include/net/net_failover.h 18861 18821 18862 - NEXTHOP 18863 - M: David Ahern <dsahern@kernel.org> 18864 - L: netdev@vger.kernel.org 18865 - S: Maintained 18866 - F: include/net/netns/nexthop.h 18867 - F: include/net/nexthop.h 18868 - F: include/uapi/linux/nexthop.h 18869 - F: net/ipv4/nexthop.c 18870 - 18871 18822 NFC SUBSYSTEM 18872 - L: netdev@vger.kernel.org 18873 - S: Orphan 18823 + M: David Heidelberg <david+nfc@ixit.cz> 18824 + L: oe-linux-nfc@lists.linux.dev 18825 + S: Maintained 18826 + T: git https://codeberg.org/linux-nfc/linux.git 18874 18827 F: Documentation/devicetree/bindings/net/nfc/ 18875 18828 F: drivers/nfc/ 18876 18829 F: include/net/nfc/ ··· 20807 20774 S: Odd Fixes 20808 20775 T: git git://git.kernel.org/pub/scm/linux/kernel/git/brodo/linux.git 20809 20776 F: Documentation/pcmcia/ 20777 + F: drivers/net/ethernet/8390/pcnet_cs.c 20810 20778 F: drivers/pcmcia/ 20811 20779 F: include/pcmcia/ 20812 20780 F: tools/pcmcia/
+10
drivers/dpll/dpll_netlink.c
··· 900 900 return dpll_pin_event_send(DPLL_CMD_PIN_DELETE_NTF, pin); 901 901 } 902 902 903 + /** 904 + * __dpll_pin_change_ntf - notify that the pin has been changed 905 + * @pin: registered pin pointer 906 + * 907 + * Context: caller must hold dpll_lock. Suitable for use inside pin 908 + * callbacks which are already invoked under dpll_lock. 909 + * Return: 0 if succeeds, error code otherwise. 910 + */ 903 911 int __dpll_pin_change_ntf(struct dpll_pin *pin) 904 912 { 913 + lockdep_assert_held(&dpll_lock); 905 914 dpll_pin_notify(pin, DPLL_PIN_CHANGED); 906 915 return dpll_pin_event_send(DPLL_CMD_PIN_CHANGE_NTF, pin); 907 916 } 917 + EXPORT_SYMBOL_GPL(__dpll_pin_change_ntf); 908 918 909 919 /** 910 920 * dpll_pin_change_ntf - notify that the pin has been changed
-2
drivers/dpll/dpll_netlink.h
··· 11 11 int dpll_pin_create_ntf(struct dpll_pin *pin); 12 12 13 13 int dpll_pin_delete_ntf(struct dpll_pin *pin); 14 - 15 - int __dpll_pin_change_ntf(struct dpll_pin *pin);
+3
drivers/net/bareudp.c
··· 529 529 struct in6_addr saddr; 530 530 struct socket *sock = rcu_dereference(bareudp->sock); 531 531 532 + if (!sock) 533 + return -ESHUTDOWN; 534 + 532 535 dst = udp_tunnel6_dst_lookup(skb, dev, bareudp->net, sock, 533 536 0, &saddr, &info->key, 534 537 sport, bareudp->port, info->key.tos,
+60 -49
drivers/net/bonding/bond_3ad.c
··· 1029 1029 static void ad_mux_machine(struct port *port, bool *update_slave_arr) 1030 1030 { 1031 1031 struct bonding *bond = __get_bond_by_port(port); 1032 + struct aggregator *aggregator; 1032 1033 mux_states_t last_state; 1033 1034 1034 1035 /* keep current State Machine state to compare later if it was ··· 1037 1036 */ 1038 1037 last_state = port->sm_mux_state; 1039 1038 1039 + aggregator = rcu_dereference(port->aggregator); 1040 1040 if (port->sm_vars & AD_PORT_BEGIN) { 1041 1041 port->sm_mux_state = AD_MUX_DETACHED; 1042 1042 } else { ··· 1057 1055 * cycle to update ready variable, we check 1058 1056 * READY_N and update READY here 1059 1057 */ 1060 - __set_agg_ports_ready(port->aggregator, __agg_ports_are_ready(port->aggregator)); 1058 + __set_agg_ports_ready(aggregator, __agg_ports_are_ready(aggregator)); 1061 1059 port->sm_mux_state = AD_MUX_DETACHED; 1062 1060 break; 1063 1061 } ··· 1072 1070 * update ready variable, we check READY_N and update 1073 1071 * READY here 1074 1072 */ 1075 - __set_agg_ports_ready(port->aggregator, __agg_ports_are_ready(port->aggregator)); 1073 + __set_agg_ports_ready(aggregator, __agg_ports_are_ready(aggregator)); 1076 1074 1077 1075 /* if the wait_while_timer expired, and the port is 1078 1076 * in READY state, move to ATTACHED state ··· 1088 1086 if ((port->sm_vars & AD_PORT_SELECTED) && 1089 1087 (port->partner_oper.port_state & LACP_STATE_SYNCHRONIZATION) && 1090 1088 !__check_agg_selection_timer(port)) { 1091 - if (port->aggregator->is_active) { 1089 + if (aggregator->is_active) { 1092 1090 int state = AD_MUX_COLLECTING_DISTRIBUTING; 1093 1091 1094 1092 if (!bond->params.coupled_control) ··· 1104 1102 * cycle to update ready variable, we check 1105 1103 * READY_N and update READY here 1106 1104 */ 1107 - __set_agg_ports_ready(port->aggregator, __agg_ports_are_ready(port->aggregator)); 1105 + __set_agg_ports_ready(aggregator, __agg_ports_are_ready(aggregator)); 1108 1106 port->sm_mux_state = AD_MUX_DETACHED; 1109 - } else if (port->aggregator->is_active) { 1107 + } else if (aggregator->is_active) { 1110 1108 port->actor_oper_port_state |= 1111 1109 LACP_STATE_SYNCHRONIZATION; 1112 1110 } ··· 1117 1115 * sure that a collecting distributing 1118 1116 * port in an active aggregator is enabled 1119 1117 */ 1120 - if (port->aggregator->is_active && 1118 + if (aggregator->is_active && 1121 1119 !__port_is_collecting_distributing(port)) { 1122 1120 __enable_port(port); 1123 1121 *update_slave_arr = true; ··· 1136 1134 */ 1137 1135 struct slave *slave = port->slave; 1138 1136 1139 - if (port->aggregator->is_active && 1137 + if (aggregator->is_active && 1140 1138 bond_is_slave_rx_disabled(slave)) { 1141 1139 ad_enable_collecting(port); 1142 1140 *update_slave_arr = true; ··· 1156 1154 * sure that a collecting distributing 1157 1155 * port in an active aggregator is enabled 1158 1156 */ 1159 - if (port->aggregator && 1160 - port->aggregator->is_active && 1157 + if (aggregator && 1158 + aggregator->is_active && 1161 1159 !__port_is_collecting_distributing(port)) { 1162 1160 __enable_port(port); 1163 1161 *update_slave_arr = true; ··· 1189 1187 port->sm_mux_timer_counter = __ad_timer_to_ticks(AD_WAIT_WHILE_TIMER, 0); 1190 1188 break; 1191 1189 case AD_MUX_ATTACHED: 1192 - if (port->aggregator->is_active) 1190 + if (aggregator->is_active) 1193 1191 port->actor_oper_port_state |= 1194 1192 LACP_STATE_SYNCHRONIZATION; 1195 1193 else ··· 1563 1561 bond = __get_bond_by_port(port); 1564 1562 1565 1563 /* if the port is connected to other aggregator, detach it */ 1566 - if (port->aggregator) { 1564 + temp_aggregator = rcu_dereference(port->aggregator); 1565 + if (temp_aggregator) { 1567 1566 /* detach the port from its former aggregator */ 1568 - temp_aggregator = port->aggregator; 1569 1567 for (curr_port = temp_aggregator->lag_ports; curr_port; 1570 1568 last_port = curr_port, 1571 1569 curr_port = curr_port->next_port_in_aggregator) { ··· 1588 1586 /* clear the port's relations to this 1589 1587 * aggregator 1590 1588 */ 1591 - port->aggregator = NULL; 1589 + RCU_INIT_POINTER(port->aggregator, NULL); 1592 1590 port->next_port_in_aggregator = NULL; 1593 1591 port->actor_port_aggregator_identifier = 0; 1594 1592 ··· 1611 1609 port->slave->bond->dev->name, 1612 1610 port->slave->dev->name, 1613 1611 port->actor_port_number, 1614 - port->aggregator->aggregator_identifier); 1612 + temp_aggregator->aggregator_identifier); 1615 1613 } 1616 1614 } 1617 1615 /* search on all aggregators for a suitable aggregator for this port */ ··· 1635 1633 ) 1636 1634 ) { 1637 1635 /* attach to the founded aggregator */ 1638 - port->aggregator = aggregator; 1636 + rcu_assign_pointer(port->aggregator, aggregator); 1639 1637 port->actor_port_aggregator_identifier = 1640 - port->aggregator->aggregator_identifier; 1638 + aggregator->aggregator_identifier; 1641 1639 port->next_port_in_aggregator = aggregator->lag_ports; 1642 - port->aggregator->num_of_ports++; 1640 + aggregator->num_of_ports++; 1643 1641 aggregator->lag_ports = port; 1644 1642 slave_dbg(bond->dev, slave->dev, "Port %d joined LAG %d (existing LAG)\n", 1645 1643 port->actor_port_number, 1646 - port->aggregator->aggregator_identifier); 1644 + aggregator->aggregator_identifier); 1647 1645 1648 1646 /* mark this port as selected */ 1649 1647 port->sm_vars |= AD_PORT_SELECTED; ··· 1658 1656 if (!found) { 1659 1657 if (free_aggregator) { 1660 1658 /* assign port a new aggregator */ 1661 - port->aggregator = free_aggregator; 1662 1659 port->actor_port_aggregator_identifier = 1663 - port->aggregator->aggregator_identifier; 1660 + free_aggregator->aggregator_identifier; 1664 1661 1665 1662 /* update the new aggregator's parameters 1666 1663 * if port was responsed from the end-user 1667 1664 */ 1668 1665 if (port->actor_oper_port_key & AD_DUPLEX_KEY_MASKS) 1669 1666 /* if port is full duplex */ 1670 - port->aggregator->is_individual = false; 1667 + free_aggregator->is_individual = false; 1671 1668 else 1672 - port->aggregator->is_individual = true; 1669 + free_aggregator->is_individual = true; 1673 1670 1674 - port->aggregator->actor_admin_aggregator_key = 1671 + free_aggregator->actor_admin_aggregator_key = 1675 1672 port->actor_admin_port_key; 1676 - port->aggregator->actor_oper_aggregator_key = 1673 + free_aggregator->actor_oper_aggregator_key = 1677 1674 port->actor_oper_port_key; 1678 - port->aggregator->partner_system = 1675 + free_aggregator->partner_system = 1679 1676 port->partner_oper.system; 1680 - port->aggregator->partner_system_priority = 1677 + free_aggregator->partner_system_priority = 1681 1678 port->partner_oper.system_priority; 1682 - port->aggregator->partner_oper_aggregator_key = port->partner_oper.key; 1683 - port->aggregator->receive_state = 1; 1684 - port->aggregator->transmit_state = 1; 1685 - port->aggregator->lag_ports = port; 1686 - port->aggregator->num_of_ports++; 1679 + free_aggregator->partner_oper_aggregator_key = port->partner_oper.key; 1680 + free_aggregator->receive_state = 1; 1681 + free_aggregator->transmit_state = 1; 1682 + free_aggregator->lag_ports = port; 1683 + free_aggregator->num_of_ports++; 1684 + 1685 + rcu_assign_pointer(port->aggregator, free_aggregator); 1687 1686 1688 1687 /* mark this port as selected */ 1689 1688 port->sm_vars |= AD_PORT_SELECTED; 1690 1689 1691 1690 slave_dbg(bond->dev, port->slave->dev, "Port %d joined LAG %d (new LAG)\n", 1692 1691 port->actor_port_number, 1693 - port->aggregator->aggregator_identifier); 1692 + free_aggregator->aggregator_identifier); 1694 1693 } else { 1695 1694 slave_err(bond->dev, port->slave->dev, 1696 1695 "Port %d did not find a suitable aggregator\n", ··· 1703 1700 * in all aggregator's ports, else set ready=FALSE in all 1704 1701 * aggregator's ports 1705 1702 */ 1706 - __set_agg_ports_ready(port->aggregator, 1707 - __agg_ports_are_ready(port->aggregator)); 1703 + aggregator = rcu_dereference(port->aggregator); 1704 + __set_agg_ports_ready(aggregator, __agg_ports_are_ready(aggregator)); 1708 1705 1709 - aggregator = __get_first_agg(port); 1710 - ad_agg_selection_logic(aggregator, update_slave_arr); 1706 + ad_agg_selection_logic(__get_first_agg(port), update_slave_arr); 1711 1707 1712 - if (!port->aggregator->is_active) 1708 + if (!aggregator->is_active) 1713 1709 port->actor_oper_port_state &= ~LACP_STATE_SYNCHRONIZATION; 1714 1710 } 1715 1711 ··· 2077 2075 */ 2078 2076 static void ad_enable_collecting(struct port *port) 2079 2077 { 2080 - if (port->aggregator->is_active) { 2078 + struct aggregator *aggregator = rcu_dereference(port->aggregator); 2079 + 2080 + if (aggregator->is_active) { 2081 2081 struct slave *slave = port->slave; 2082 2082 2083 2083 slave_dbg(slave->bond->dev, slave->dev, 2084 2084 "Enabling collecting on port %d (LAG %d)\n", 2085 2085 port->actor_port_number, 2086 - port->aggregator->aggregator_identifier); 2086 + aggregator->aggregator_identifier); 2087 2087 __enable_collecting_port(port); 2088 2088 } 2089 2089 } ··· 2097 2093 */ 2098 2094 static void ad_disable_distributing(struct port *port, bool *update_slave_arr) 2099 2095 { 2100 - if (port->aggregator && __agg_has_partner(port->aggregator)) { 2096 + struct aggregator *aggregator = rcu_dereference(port->aggregator); 2097 + 2098 + if (aggregator && __agg_has_partner(aggregator)) { 2101 2099 slave_dbg(port->slave->bond->dev, port->slave->dev, 2102 2100 "Disabling distributing on port %d (LAG %d)\n", 2103 2101 port->actor_port_number, 2104 - port->aggregator->aggregator_identifier); 2102 + aggregator->aggregator_identifier); 2105 2103 __disable_distributing_port(port); 2106 2104 /* Slave array needs an update */ 2107 2105 *update_slave_arr = true; ··· 2120 2114 static void ad_enable_collecting_distributing(struct port *port, 2121 2115 bool *update_slave_arr) 2122 2116 { 2123 - if (port->aggregator->is_active) { 2117 + struct aggregator *aggregator = rcu_dereference(port->aggregator); 2118 + 2119 + if (aggregator->is_active) { 2124 2120 slave_dbg(port->slave->bond->dev, port->slave->dev, 2125 2121 "Enabling port %d (LAG %d)\n", 2126 2122 port->actor_port_number, 2127 - port->aggregator->aggregator_identifier); 2123 + aggregator->aggregator_identifier); 2128 2124 __enable_port(port); 2129 2125 /* Slave array needs update */ 2130 2126 *update_slave_arr = true; ··· 2143 2135 static void ad_disable_collecting_distributing(struct port *port, 2144 2136 bool *update_slave_arr) 2145 2137 { 2146 - if (port->aggregator && __agg_has_partner(port->aggregator)) { 2138 + struct aggregator *aggregator = rcu_dereference(port->aggregator); 2139 + 2140 + if (aggregator && __agg_has_partner(aggregator)) { 2147 2141 slave_dbg(port->slave->bond->dev, port->slave->dev, 2148 2142 "Disabling port %d (LAG %d)\n", 2149 2143 port->actor_port_number, 2150 - port->aggregator->aggregator_identifier); 2144 + aggregator->aggregator_identifier); 2151 2145 __disable_port(port); 2152 2146 /* Slave array needs an update */ 2153 2147 *update_slave_arr = true; ··· 2389 2379 */ 2390 2380 for (temp_port = aggregator->lag_ports; temp_port; 2391 2381 temp_port = temp_port->next_port_in_aggregator) { 2392 - temp_port->aggregator = new_aggregator; 2382 + rcu_assign_pointer(temp_port->aggregator, new_aggregator); 2393 2383 temp_port->actor_port_aggregator_identifier = new_aggregator->aggregator_identifier; 2394 2384 } 2395 2385 ··· 2858 2848 int __bond_3ad_get_active_agg_info(struct bonding *bond, 2859 2849 struct ad_info *ad_info) 2860 2850 { 2861 - struct aggregator *aggregator = NULL; 2851 + struct aggregator *aggregator = NULL, *tmp; 2862 2852 struct list_head *iter; 2863 2853 struct slave *slave; 2864 2854 struct port *port; 2865 2855 2866 2856 bond_for_each_slave_rcu(bond, slave, iter) { 2867 2857 port = &(SLAVE_AD_INFO(slave)->port); 2868 - if (port->aggregator && port->aggregator->is_active) { 2869 - aggregator = port->aggregator; 2858 + tmp = rcu_dereference(port->aggregator); 2859 + if (tmp && tmp->is_active) { 2860 + aggregator = tmp; 2870 2861 break; 2871 2862 } 2872 2863 }
+5 -3
drivers/net/bonding/bond_main.c
··· 1433 1433 1434 1434 if (BOND_MODE(bond) == BOND_MODE_8023AD) { 1435 1435 struct aggregator *agg = 1436 - SLAVE_AD_INFO(slave)->port.aggregator; 1436 + rcu_dereference(SLAVE_AD_INFO(slave)->port.aggregator); 1437 1437 1438 1438 if (agg && 1439 1439 agg->aggregator_identifier != ad_info.aggregator_id) ··· 5179 5179 spin_unlock_bh(&bond->mode_lock); 5180 5180 agg_id = ad_info.aggregator_id; 5181 5181 } 5182 + rcu_read_lock(); 5182 5183 bond_for_each_slave(bond, slave, iter) { 5183 5184 if (skipslave == slave) 5184 5185 continue; 5185 5186 5186 5187 all_slaves->arr[all_slaves->count++] = slave; 5187 5188 if (BOND_MODE(bond) == BOND_MODE_8023AD) { 5188 - struct aggregator *agg; 5189 + const struct aggregator *agg; 5189 5190 5190 - agg = SLAVE_AD_INFO(slave)->port.aggregator; 5191 + agg = rcu_dereference(SLAVE_AD_INFO(slave)->port.aggregator); 5191 5192 if (!agg || agg->aggregator_identifier != agg_id) 5192 5193 continue; 5193 5194 } ··· 5200 5199 5201 5200 usable_slaves->arr[usable_slaves->count++] = slave; 5202 5201 } 5202 + rcu_read_unlock(); 5203 5203 5204 5204 bond_set_slave_arr(bond, usable_slaves, all_slaves); 5205 5205 return ret;
+10 -6
drivers/net/bonding/bond_netlink.c
··· 66 66 const struct port *ad_port; 67 67 68 68 ad_port = &SLAVE_AD_INFO(slave)->port; 69 - agg = SLAVE_AD_INFO(slave)->port.aggregator; 69 + rcu_read_lock(); 70 + agg = rcu_dereference(SLAVE_AD_INFO(slave)->port.aggregator); 70 71 if (agg) { 71 72 if (nla_put_u16(skb, IFLA_BOND_SLAVE_AD_AGGREGATOR_ID, 72 73 agg->aggregator_identifier)) 73 - goto nla_put_failure; 74 + goto nla_put_failure_rcu; 74 75 if (nla_put_u8(skb, 75 76 IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE, 76 77 ad_port->actor_oper_port_state)) 77 - goto nla_put_failure; 78 + goto nla_put_failure_rcu; 78 79 if (nla_put_u16(skb, 79 80 IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE, 80 81 ad_port->partner_oper.port_state)) 81 - goto nla_put_failure; 82 + goto nla_put_failure_rcu; 82 83 83 84 if (nla_put_u8(skb, IFLA_BOND_SLAVE_AD_CHURN_ACTOR_STATE, 84 85 ad_port->sm_churn_actor_state)) 85 - goto nla_put_failure; 86 + goto nla_put_failure_rcu; 86 87 if (nla_put_u8(skb, IFLA_BOND_SLAVE_AD_CHURN_PARTNER_STATE, 87 88 ad_port->sm_churn_partner_state)) 88 - goto nla_put_failure; 89 + goto nla_put_failure_rcu; 89 90 } 91 + rcu_read_unlock(); 90 92 91 93 if (nla_put_u16(skb, IFLA_BOND_SLAVE_ACTOR_PORT_PRIO, 92 94 SLAVE_AD_INFO(slave)->port_priority)) ··· 97 95 98 96 return 0; 99 97 98 + nla_put_failure_rcu: 99 + rcu_read_unlock(); 100 100 nla_put_failure: 101 101 return -EMSGSIZE; 102 102 }
+2 -1
drivers/net/bonding/bond_procfs.c
··· 188 188 } 189 189 } 190 190 191 + /* Note: runs under rcu_read_lock() */ 191 192 static void bond_info_show_slave(struct seq_file *seq, 192 193 const struct slave *slave) 193 194 { ··· 215 214 216 215 if (BOND_MODE(bond) == BOND_MODE_8023AD) { 217 216 const struct port *port = &SLAVE_AD_INFO(slave)->port; 218 - const struct aggregator *agg = port->aggregator; 217 + const struct aggregator *agg = rcu_dereference(port->aggregator); 219 218 220 219 if (agg) { 221 220 seq_printf(seq, "Aggregator ID: %d\n",
+11 -6
drivers/net/bonding/bond_sysfs_slave.c
··· 62 62 const struct aggregator *agg; 63 63 64 64 if (BOND_MODE(slave->bond) == BOND_MODE_8023AD) { 65 - agg = SLAVE_AD_INFO(slave)->port.aggregator; 66 - if (agg) 67 - return sysfs_emit(buf, "%d\n", 68 - agg->aggregator_identifier); 65 + rcu_read_lock(); 66 + agg = rcu_dereference(SLAVE_AD_INFO(slave)->port.aggregator); 67 + if (agg) { 68 + ssize_t res = sysfs_emit(buf, "%d\n", 69 + agg->aggregator_identifier); 70 + rcu_read_unlock(); 71 + return res; 72 + } 73 + rcu_read_unlock(); 69 74 } 70 75 71 76 return sysfs_emit(buf, "N/A\n"); ··· 83 78 84 79 if (BOND_MODE(slave->bond) == BOND_MODE_8023AD) { 85 80 ad_port = &SLAVE_AD_INFO(slave)->port; 86 - if (ad_port->aggregator) 81 + if (rcu_access_pointer(ad_port->aggregator)) 87 82 return sysfs_emit(buf, "%u\n", 88 83 ad_port->actor_oper_port_state); 89 84 } ··· 98 93 99 94 if (BOND_MODE(slave->bond) == BOND_MODE_8023AD) { 100 95 ad_port = &SLAVE_AD_INFO(slave)->port; 101 - if (ad_port->aggregator) 96 + if (rcu_access_pointer(ad_port->aggregator)) 102 97 return sysfs_emit(buf, "%u\n", 103 98 ad_port->partner_oper.port_state); 104 99 }
+30 -21
drivers/net/ethernet/airoha/airoha_eth.c
··· 847 847 { 848 848 struct airoha_qdma *qdma = q->qdma; 849 849 struct airoha_eth *eth = qdma->eth; 850 - int i; 850 + int i, qid = q - &qdma->q_tx[0]; 851 851 852 852 for (i = 0; i < ARRAY_SIZE(eth->ports); i++) { 853 853 struct airoha_gdm_port *port = eth->ports[i]; 854 + int j; 854 855 855 - if (port && port->qdma == qdma) 856 - netif_tx_wake_all_queues(port->dev); 856 + if (!port) 857 + continue; 858 + 859 + if (port->qdma != qdma) 860 + continue; 861 + 862 + for (j = 0; j < port->dev->num_tx_queues; j++) { 863 + if (airoha_qdma_get_txq(qdma, j) != qid) 864 + continue; 865 + 866 + netif_wake_subqueue(port->dev, j); 867 + } 857 868 } 858 869 q->txq_stopped = false; 859 870 } ··· 940 929 q->queued--; 941 930 942 931 if (skb) { 943 - u16 queue = skb_get_queue_mapping(skb); 944 932 struct netdev_queue *txq; 945 933 946 - txq = netdev_get_tx_queue(skb->dev, queue); 934 + txq = skb_get_tx_queue(skb->dev, skb); 947 935 netdev_tx_completed_queue(txq, 1, skb->len); 948 936 dev_kfree_skb_any(skb); 949 937 } ··· 1747 1737 { 1748 1738 struct airoha_gdm_port *port = netdev_priv(dev); 1749 1739 struct airoha_qdma *qdma = port->qdma; 1750 - int i, err; 1740 + int i; 1751 1741 1752 1742 netif_tx_disable(dev); 1753 - err = airoha_set_vip_for_gdm_port(port, false); 1754 - if (err) 1755 - return err; 1756 - 1757 - for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) 1743 + airoha_set_vip_for_gdm_port(port, false); 1744 + for (i = 0; i < dev->num_tx_queues; i++) 1758 1745 netdev_tx_reset_subqueue(dev, i); 1759 1746 1760 1747 airoha_set_gdm_port_fwd_cfg(qdma->eth, REG_GDM_FWD_CFG(port->id), ··· 2004 1997 struct netdev_queue *txq; 2005 1998 struct airoha_queue *q; 2006 1999 LIST_HEAD(tx_list); 2000 + int i = 0, qid; 2007 2001 void *data; 2008 - int i, qid; 2009 2002 u16 index; 2010 2003 u8 fport; 2011 2004 2012 - qid = skb_get_queue_mapping(skb) % ARRAY_SIZE(qdma->q_tx); 2005 + qid = airoha_qdma_get_txq(qdma, skb_get_queue_mapping(skb)); 2013 2006 tag = airoha_get_dsa_tag(skb, dev); 2014 2007 2015 2008 msg0 = FIELD_PREP(QDMA_ETH_TXMSG_CHAN_MASK, ··· 2046 2039 2047 2040 spin_lock_bh(&q->lock); 2048 2041 2049 - txq = netdev_get_tx_queue(dev, qid); 2042 + txq = skb_get_tx_queue(dev, skb); 2050 2043 nr_frags = 1 + skb_shinfo(skb)->nr_frags; 2051 2044 2052 2045 if (q->queued + nr_frags >= q->ndesc) { ··· 2064 2057 list); 2065 2058 index = e - q->entry; 2066 2059 2067 - for (i = 0; i < nr_frags; i++) { 2060 + while (true) { 2068 2061 struct airoha_qdma_desc *desc = &q->desc[index]; 2069 2062 skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 2070 2063 dma_addr_t addr; ··· 2076 2069 goto error_unmap; 2077 2070 2078 2071 list_move_tail(&e->list, &tx_list); 2079 - e->skb = i ? NULL : skb; 2072 + e->skb = i == nr_frags - 1 ? skb : NULL; 2080 2073 e->dma_addr = addr; 2081 2074 e->dma_len = len; 2082 2075 ··· 2095 2088 WRITE_ONCE(desc->msg1, cpu_to_le32(msg1)); 2096 2089 WRITE_ONCE(desc->msg2, cpu_to_le32(0xffff)); 2097 2090 2091 + if (++i == nr_frags) 2092 + break; 2093 + 2098 2094 data = skb_frag_address(frag); 2099 2095 len = skb_frag_size(frag); 2100 2096 } ··· 2105 2095 2106 2096 skb_tx_timestamp(skb); 2107 2097 netdev_tx_sent_queue(txq, skb->len); 2098 + if (q->ndesc - q->queued < q->free_thr) { 2099 + netif_tx_stop_queue(txq); 2100 + q->txq_stopped = true; 2101 + } 2108 2102 2109 2103 if (netif_xmit_stopped(txq) || !netdev_xmit_more()) 2110 2104 airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid), 2111 2105 TX_RING_CPU_IDX_MASK, 2112 2106 FIELD_PREP(TX_RING_CPU_IDX_MASK, index)); 2113 - 2114 - if (q->ndesc - q->queued < q->free_thr) { 2115 - netif_tx_stop_queue(txq); 2116 - q->txq_stopped = true; 2117 - } 2118 2107 2119 2108 spin_unlock_bh(&q->lock); 2120 2109
+5
drivers/net/ethernet/airoha/airoha_eth.h
··· 631 631 #define airoha_qdma_clear(qdma, offset, val) \ 632 632 airoha_rmw((qdma)->regs, (offset), (val), 0) 633 633 634 + static inline u16 airoha_qdma_get_txq(struct airoha_qdma *qdma, u16 qid) 635 + { 636 + return qid % ARRAY_SIZE(qdma->q_tx); 637 + } 638 + 634 639 static inline bool airoha_is_lan_gdm_port(struct airoha_gdm_port *port) 635 640 { 636 641 /* GDM1 port on EN7581 SoC is connected to the lan dsa switch.
+22
drivers/net/ethernet/ibm/ibmveth.c
··· 1756 1756 return 0; 1757 1757 } 1758 1758 1759 + static netdev_features_t ibmveth_features_check(struct sk_buff *skb, 1760 + struct net_device *dev, 1761 + netdev_features_t features) 1762 + { 1763 + /* Some physical adapters do not support segmentation offload with 1764 + * MSS < 224. Disable GSO for such packets to avoid adapter freeze. 1765 + * Note: Single-segment packets (gso_segs == 1) don't need this check 1766 + * as they bypass the LSO path and are transmitted without segmentation. 1767 + */ 1768 + if (skb_is_gso(skb)) { 1769 + if (skb_shinfo(skb)->gso_size < IBMVETH_MIN_LSO_MSS) { 1770 + netdev_warn_once(dev, 1771 + "MSS %u too small for LSO, disabling GSO\n", 1772 + skb_shinfo(skb)->gso_size); 1773 + features &= ~NETIF_F_GSO_MASK; 1774 + } 1775 + } 1776 + 1777 + return vlan_features_check(skb, features); 1778 + } 1779 + 1759 1780 static const struct net_device_ops ibmveth_netdev_ops = { 1760 1781 .ndo_open = ibmveth_open, 1761 1782 .ndo_stop = ibmveth_close, ··· 1788 1767 .ndo_set_features = ibmveth_set_features, 1789 1768 .ndo_validate_addr = eth_validate_addr, 1790 1769 .ndo_set_mac_address = ibmveth_set_mac_addr, 1770 + .ndo_features_check = ibmveth_features_check, 1791 1771 #ifdef CONFIG_NET_POLL_CONTROLLER 1792 1772 .ndo_poll_controller = ibmveth_poll_controller, 1793 1773 #endif
+1
drivers/net/ethernet/ibm/ibmveth.h
··· 37 37 #define IBMVETH_ILLAN_IPV4_TCP_CSUM 0x0000000000000002UL 38 38 #define IBMVETH_ILLAN_ACTIVE_TRUNK 0x0000000000000001UL 39 39 40 + #define IBMVETH_MIN_LSO_MSS 224 /* Minimum MSS for LSO */ 40 41 /* hcall macros */ 41 42 #define h_register_logical_lan(ua, buflst, rxq, fltlst, mac) \ 42 43 plpar_hcall_norets(H_REGISTER_LOGICAL_LAN, ua, buflst, rxq, fltlst, mac)
+4 -5
drivers/net/ethernet/intel/iavf/iavf.h
··· 158 158 enum iavf_vlan_state_t { 159 159 IAVF_VLAN_INVALID, 160 160 IAVF_VLAN_ADD, /* filter needs to be added */ 161 - IAVF_VLAN_IS_NEW, /* filter is new, wait for PF answer */ 162 - IAVF_VLAN_ACTIVE, /* filter is accepted by PF */ 163 - IAVF_VLAN_DISABLE, /* filter needs to be deleted by PF, then marked INACTIVE */ 164 - IAVF_VLAN_INACTIVE, /* filter is inactive, we are in IFF_DOWN */ 165 - IAVF_VLAN_REMOVE, /* filter needs to be removed from list */ 161 + IAVF_VLAN_ADDING, /* ADD sent to PF, waiting for response */ 162 + IAVF_VLAN_ACTIVE, /* PF confirmed, filter is in HW */ 163 + IAVF_VLAN_REMOVE, /* filter queued for DEL from PF */ 164 + IAVF_VLAN_REMOVING, /* DEL sent to PF, waiting for response */ 166 165 }; 167 166 168 167 struct iavf_vlan_filter {
+12 -40
drivers/net/ethernet/intel/iavf/iavf_main.c
··· 757 757 adapter->num_vlan_filters++; 758 758 iavf_schedule_aq_request(adapter, IAVF_FLAG_AQ_ADD_VLAN_FILTER); 759 759 } else if (f->state == IAVF_VLAN_REMOVE) { 760 - /* Re-add the filter since we cannot tell whether the 761 - * pending delete has already been processed by the PF. 762 - * A duplicate add is harmless. 763 - */ 760 + /* DEL not yet sent to PF, cancel it */ 761 + f->state = IAVF_VLAN_ACTIVE; 762 + } else if (f->state == IAVF_VLAN_REMOVING) { 763 + /* DEL already sent to PF, re-add after completion */ 764 764 f->state = IAVF_VLAN_ADD; 765 765 iavf_schedule_aq_request(adapter, 766 766 IAVF_FLAG_AQ_ADD_VLAN_FILTER); ··· 791 791 list_del(&f->list); 792 792 kfree(f); 793 793 adapter->num_vlan_filters--; 794 - } else { 794 + } else if (f->state != IAVF_VLAN_REMOVING) { 795 795 f->state = IAVF_VLAN_REMOVE; 796 796 iavf_schedule_aq_request(adapter, 797 797 IAVF_FLAG_AQ_DEL_VLAN_FILTER); 798 798 } 799 + /* If REMOVING, DEL is already sent to PF; completion 800 + * handler will free the filter when PF confirms. 801 + */ 799 802 } 800 803 801 804 spin_unlock_bh(&adapter->mac_vlan_list_lock); 802 805 } 803 806 804 - /** 805 - * iavf_restore_filters 806 - * @adapter: board private structure 807 - * 808 - * Restore existing non MAC filters when VF netdev comes back up 809 - **/ 810 - static void iavf_restore_filters(struct iavf_adapter *adapter) 811 - { 812 - struct iavf_vlan_filter *f; 813 - 814 - /* re-add all VLAN filters */ 815 - spin_lock_bh(&adapter->mac_vlan_list_lock); 816 - 817 - list_for_each_entry(f, &adapter->vlan_filter_list, list) { 818 - if (f->state == IAVF_VLAN_INACTIVE) 819 - f->state = IAVF_VLAN_ADD; 820 - } 821 - 822 - spin_unlock_bh(&adapter->mac_vlan_list_lock); 823 - adapter->aq_required |= IAVF_FLAG_AQ_ADD_VLAN_FILTER; 824 - } 825 807 826 808 /** 827 809 * iavf_get_num_vlans_added - get number of VLANs added ··· 1228 1246 } 1229 1247 1230 1248 /** 1231 - * iavf_clear_mac_vlan_filters - Remove mac and vlan filters not sent to PF 1232 - * yet and mark other to be removed. 1249 + * iavf_clear_mac_filters - Remove MAC filters not sent to PF yet and mark 1250 + * others to be removed. 1233 1251 * @adapter: board private structure 1234 1252 **/ 1235 - static void iavf_clear_mac_vlan_filters(struct iavf_adapter *adapter) 1253 + static void iavf_clear_mac_filters(struct iavf_adapter *adapter) 1236 1254 { 1237 - struct iavf_vlan_filter *vlf, *vlftmp; 1238 1255 struct iavf_mac_filter *f, *ftmp; 1239 1256 1240 1257 spin_lock_bh(&adapter->mac_vlan_list_lock); ··· 1251 1270 f->remove = true; 1252 1271 } 1253 1272 } 1254 - 1255 - /* disable all VLAN filters */ 1256 - list_for_each_entry_safe(vlf, vlftmp, &adapter->vlan_filter_list, 1257 - list) 1258 - vlf->state = IAVF_VLAN_DISABLE; 1259 1273 1260 1274 spin_unlock_bh(&adapter->mac_vlan_list_lock); 1261 1275 } ··· 1347 1371 iavf_napi_disable_all(adapter); 1348 1372 iavf_irq_disable(adapter); 1349 1373 1350 - iavf_clear_mac_vlan_filters(adapter); 1374 + iavf_clear_mac_filters(adapter); 1351 1375 iavf_clear_cloud_filters(adapter); 1352 1376 iavf_clear_fdir_filters(adapter); 1353 1377 iavf_clear_adv_rss_conf(adapter); ··· 1364 1388 */ 1365 1389 if (!list_empty(&adapter->mac_filter_list)) 1366 1390 adapter->aq_required |= IAVF_FLAG_AQ_DEL_MAC_FILTER; 1367 - if (!list_empty(&adapter->vlan_filter_list)) 1368 - adapter->aq_required |= IAVF_FLAG_AQ_DEL_VLAN_FILTER; 1369 1391 if (!list_empty(&adapter->cloud_filter_list)) 1370 1392 adapter->aq_required |= IAVF_FLAG_AQ_DEL_CLOUD_FILTER; 1371 1393 if (!list_empty(&adapter->fdir_list_head)) ··· 4468 4494 iavf_add_filter(adapter, adapter->hw.mac.addr); 4469 4495 spin_unlock_bh(&adapter->mac_vlan_list_lock); 4470 4496 4471 - /* Restore filters that were removed with IFF_DOWN */ 4472 - iavf_restore_filters(adapter); 4473 4497 iavf_restore_fdir_filters(adapter); 4474 4498 4475 4499 iavf_configure(adapter);
+36 -40
drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
··· 746 746 747 747 spin_lock_bh(&adapter->mac_vlan_list_lock); 748 748 list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, list) { 749 - if (f->state == IAVF_VLAN_IS_NEW) { 749 + if (f->state == IAVF_VLAN_ADDING) { 750 750 list_del(&f->list); 751 751 kfree(f); 752 752 adapter->num_vlan_filters--; ··· 812 812 if (f->state == IAVF_VLAN_ADD) { 813 813 vvfl->vlan_id[i] = f->vlan.vid; 814 814 i++; 815 - f->state = IAVF_VLAN_IS_NEW; 815 + f->state = IAVF_VLAN_ADDING; 816 816 if (i == count) 817 817 break; 818 818 } ··· 874 874 vlan->tpid = f->vlan.tpid; 875 875 876 876 i++; 877 - f->state = IAVF_VLAN_IS_NEW; 877 + f->state = IAVF_VLAN_ADDING; 878 878 } 879 879 } 880 880 ··· 911 911 spin_lock_bh(&adapter->mac_vlan_list_lock); 912 912 913 913 list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, list) { 914 - /* since VLAN capabilities are not allowed, we dont want to send 915 - * a VLAN delete request because it will most likely fail and 916 - * create unnecessary errors/noise, so just free the VLAN 917 - * filters marked for removal to enable bailing out before 918 - * sending a virtchnl message 919 - */ 920 914 if (f->state == IAVF_VLAN_REMOVE && 921 915 !VLAN_FILTERING_ALLOWED(adapter)) { 922 916 list_del(&f->list); 923 917 kfree(f); 924 918 adapter->num_vlan_filters--; 925 - } else if (f->state == IAVF_VLAN_DISABLE && 926 - !VLAN_FILTERING_ALLOWED(adapter)) { 927 - f->state = IAVF_VLAN_INACTIVE; 928 - } else if (f->state == IAVF_VLAN_REMOVE || 929 - f->state == IAVF_VLAN_DISABLE) { 919 + } else if (f->state == IAVF_VLAN_REMOVE) { 930 920 count++; 931 921 } 932 922 } ··· 948 958 949 959 vvfl->vsi_id = adapter->vsi_res->vsi_id; 950 960 vvfl->num_elements = count; 951 - list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, list) { 952 - if (f->state == IAVF_VLAN_DISABLE) { 961 + list_for_each_entry(f, &adapter->vlan_filter_list, list) { 962 + if (f->state == IAVF_VLAN_REMOVE) { 953 963 vvfl->vlan_id[i] = f->vlan.vid; 954 - f->state = IAVF_VLAN_INACTIVE; 955 - i++; 956 - if (i == count) 957 - break; 958 - } else if (f->state == IAVF_VLAN_REMOVE) { 959 - vvfl->vlan_id[i] = f->vlan.vid; 960 - list_del(&f->list); 961 - kfree(f); 962 - adapter->num_vlan_filters--; 964 + f->state = IAVF_VLAN_REMOVING; 963 965 i++; 964 966 if (i == count) 965 967 break; ··· 988 1006 989 1007 vvfl_v2->vport_id = adapter->vsi_res->vsi_id; 990 1008 vvfl_v2->num_elements = count; 991 - list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, list) { 992 - if (f->state == IAVF_VLAN_DISABLE || 993 - f->state == IAVF_VLAN_REMOVE) { 1009 + list_for_each_entry(f, &adapter->vlan_filter_list, list) { 1010 + if (f->state == IAVF_VLAN_REMOVE) { 994 1011 struct virtchnl_vlan_supported_caps *filtering_support = 995 1012 &adapter->vlan_v2_caps.filtering.filtering_support; 996 1013 struct virtchnl_vlan *vlan; ··· 1003 1022 vlan->tci = f->vlan.vid; 1004 1023 vlan->tpid = f->vlan.tpid; 1005 1024 1006 - if (f->state == IAVF_VLAN_DISABLE) { 1007 - f->state = IAVF_VLAN_INACTIVE; 1008 - } else { 1009 - list_del(&f->list); 1010 - kfree(f); 1011 - adapter->num_vlan_filters--; 1012 - } 1025 + f->state = IAVF_VLAN_REMOVING; 1013 1026 i++; 1014 1027 if (i == count) 1015 1028 break; ··· 2366 2391 ether_addr_copy(adapter->hw.mac.addr, netdev->dev_addr); 2367 2392 wake_up(&adapter->vc_waitqueue); 2368 2393 break; 2369 - case VIRTCHNL_OP_DEL_VLAN: 2370 - dev_err(&adapter->pdev->dev, "Failed to delete VLAN filter, error %s\n", 2371 - iavf_stat_str(&adapter->hw, v_retval)); 2372 - break; 2373 2394 case VIRTCHNL_OP_DEL_ETH_ADDR: 2374 2395 dev_err(&adapter->pdev->dev, "Failed to delete MAC filter, error %s\n", 2375 2396 iavf_stat_str(&adapter->hw, v_retval)); ··· 2876 2905 spin_unlock_bh(&adapter->adv_rss_lock); 2877 2906 } 2878 2907 break; 2908 + case VIRTCHNL_OP_ADD_VLAN: 2879 2909 case VIRTCHNL_OP_ADD_VLAN_V2: { 2880 2910 struct iavf_vlan_filter *f; 2881 2911 2912 + if (v_retval) 2913 + break; 2914 + 2882 2915 spin_lock_bh(&adapter->mac_vlan_list_lock); 2883 2916 list_for_each_entry(f, &adapter->vlan_filter_list, list) { 2884 - if (f->state == IAVF_VLAN_IS_NEW) 2917 + if (f->state == IAVF_VLAN_ADDING) 2885 2918 f->state = IAVF_VLAN_ACTIVE; 2919 + } 2920 + spin_unlock_bh(&adapter->mac_vlan_list_lock); 2921 + } 2922 + break; 2923 + case VIRTCHNL_OP_DEL_VLAN: 2924 + case VIRTCHNL_OP_DEL_VLAN_V2: { 2925 + struct iavf_vlan_filter *f, *ftmp; 2926 + 2927 + spin_lock_bh(&adapter->mac_vlan_list_lock); 2928 + list_for_each_entry_safe(f, ftmp, &adapter->vlan_filter_list, 2929 + list) { 2930 + if (f->state == IAVF_VLAN_REMOVING) { 2931 + if (v_retval) { 2932 + /* PF rejected DEL, keep filter */ 2933 + f->state = IAVF_VLAN_ACTIVE; 2934 + } else { 2935 + list_del(&f->list); 2936 + kfree(f); 2937 + adapter->num_vlan_filters--; 2938 + } 2939 + } 2886 2940 } 2887 2941 spin_unlock_bh(&adapter->mac_vlan_list_lock); 2888 2942 }
+2
drivers/net/ethernet/intel/ice/devlink/devlink.c
··· 1245 1245 return err; 1246 1246 } 1247 1247 1248 + ice_init_dev_hw(pf); 1249 + 1248 1250 /* load MSI-X values */ 1249 1251 ice_set_min_max_msix(pf); 1250 1252
-2
drivers/net/ethernet/intel/ice/ice_common.c
··· 1126 1126 if (status) 1127 1127 goto err_unroll_fltr_mgmt_struct; 1128 1128 1129 - ice_init_dev_hw(hw->back); 1130 - 1131 1129 mutex_init(&hw->tnl_lock); 1132 1130 ice_init_chk_recipe_reuse_support(hw); 1133 1131
+134 -12
drivers/net/ethernet/intel/ice/ice_dpll.c
··· 1155 1155 } 1156 1156 1157 1157 /** 1158 + * ice_dpll_sw_pin_notify_peer - notify the paired SW pin after a state change 1159 + * @d: pointer to dplls struct 1160 + * @changed: the SW pin that was explicitly changed (already notified by dpll core) 1161 + * 1162 + * SMA and U.FL pins share physical signal paths in pairs (SMA1/U.FL1 and 1163 + * SMA2/U.FL2). When one pin's routing changes via the PCA9575 GPIO 1164 + * expander, the paired pin's state may also change. Send a change 1165 + * notification for the peer pin so userspace consumers monitoring the 1166 + * peer via dpll netlink learn about the update. 1167 + * 1168 + * Context: Called from dpll_pin_ops callbacks after pf->dplls.lock is 1169 + * released. Uses __dpll_pin_change_ntf() because dpll_lock is 1170 + * still held by the dpll netlink layer. 1171 + */ 1172 + static void ice_dpll_sw_pin_notify_peer(struct ice_dplls *d, 1173 + struct ice_dpll_pin *changed) 1174 + { 1175 + struct ice_dpll_pin *peer; 1176 + 1177 + peer = (changed >= d->sma && changed < d->sma + ICE_DPLL_PIN_SW_NUM) ? 1178 + &d->ufl[changed->idx] : &d->sma[changed->idx]; 1179 + if (peer->pin) 1180 + __dpll_pin_change_ntf(peer->pin); 1181 + } 1182 + 1183 + /** 1158 1184 * ice_dpll_sma_direction_set - set direction of SMA pin 1159 1185 * @p: pointer to a pin 1160 1186 * @direction: requested direction of the pin ··· 1197 1171 enum dpll_pin_direction direction, 1198 1172 struct netlink_ext_ack *extack) 1199 1173 { 1174 + struct ice_dplls *d = &p->pf->dplls; 1175 + struct ice_dpll_pin *peer; 1200 1176 u8 data; 1201 1177 int ret; 1202 1178 ··· 1217 1189 case ICE_DPLL_PIN_SW_2_IDX: 1218 1190 if (direction == DPLL_PIN_DIRECTION_INPUT) { 1219 1191 data &= ~ICE_SMA2_DIR_EN; 1192 + data |= ICE_SMA2_UFL2_RX_DIS; 1220 1193 } else { 1221 - data &= ~ICE_SMA2_TX_EN; 1194 + data &= ~(ICE_SMA2_TX_EN | ICE_SMA2_UFL2_RX_DIS); 1222 1195 data |= ICE_SMA2_DIR_EN; 1223 1196 } 1224 1197 break; ··· 1231 1202 ret = ice_dpll_pin_state_update(p->pf, p, 1232 1203 ICE_DPLL_PIN_TYPE_SOFTWARE, 1233 1204 extack); 1205 + if (ret) 1206 + return ret; 1207 + 1208 + /* When a direction change activates the paired U.FL pin, enable 1209 + * its backing CGU pin so the pin reports as connected. Without 1210 + * this the U.FL routing is correct but the CGU pin stays disabled 1211 + * and userspace sees the pin as disconnected. Do not disable the 1212 + * backing pin when U.FL becomes inactive because the SMA pin may 1213 + * still be using it. 1214 + */ 1215 + peer = &d->ufl[p->idx]; 1216 + if (peer->active) { 1217 + struct ice_dpll_pin *target; 1218 + enum ice_dpll_pin_type type; 1219 + 1220 + if (peer->output) { 1221 + target = peer->output; 1222 + type = ICE_DPLL_PIN_TYPE_OUTPUT; 1223 + } else { 1224 + target = peer->input; 1225 + type = ICE_DPLL_PIN_TYPE_INPUT; 1226 + } 1227 + ret = ice_dpll_pin_enable(&p->pf->hw, target, 1228 + d->eec.dpll_idx, type, extack); 1229 + if (!ret) 1230 + ret = ice_dpll_pin_state_update(p->pf, target, 1231 + type, extack); 1232 + } 1234 1233 1235 1234 return ret; 1236 1235 } ··· 1310 1253 data &= ~ICE_SMA1_MASK; 1311 1254 enable = true; 1312 1255 } else if (state == DPLL_PIN_STATE_DISCONNECTED) { 1256 + /* Skip if U.FL1 is not active, setting TX_EN 1257 + * while DIR_EN is set would also deactivate 1258 + * the paired SMA1 output. 1259 + */ 1260 + if (data & (ICE_SMA1_DIR_EN | ICE_SMA1_TX_EN)) { 1261 + ret = 0; 1262 + goto unlock; 1263 + } 1313 1264 data |= ICE_SMA1_TX_EN; 1314 1265 enable = false; 1315 1266 } else { ··· 1332 1267 data &= ~ICE_SMA2_UFL2_RX_DIS; 1333 1268 enable = true; 1334 1269 } else if (state == DPLL_PIN_STATE_DISCONNECTED) { 1270 + /* Skip if U.FL2 is not active, setting 1271 + * UFL2_RX_DIS could also disable the paired 1272 + * SMA2 input. 1273 + */ 1274 + if (!(data & ICE_SMA2_DIR_EN) || 1275 + (data & ICE_SMA2_UFL2_RX_DIS)) { 1276 + ret = 0; 1277 + goto unlock; 1278 + } 1335 1279 data |= ICE_SMA2_UFL2_RX_DIS; 1336 1280 enable = false; 1337 1281 } else { ··· 1370 1296 1371 1297 unlock: 1372 1298 mutex_unlock(&pf->dplls.lock); 1299 + if (!ret) 1300 + ice_dpll_sw_pin_notify_peer(&pf->dplls, p); 1373 1301 1374 1302 return ret; 1375 1303 } ··· 1490 1414 1491 1415 unlock: 1492 1416 mutex_unlock(&pf->dplls.lock); 1417 + if (!ret) 1418 + ice_dpll_sw_pin_notify_peer(&pf->dplls, sma); 1493 1419 1494 1420 return ret; 1495 1421 } ··· 1687 1609 mutex_lock(&pf->dplls.lock); 1688 1610 ret = ice_dpll_sma_direction_set(p, direction, extack); 1689 1611 mutex_unlock(&pf->dplls.lock); 1612 + if (!ret) 1613 + ice_dpll_sw_pin_notify_peer(&pf->dplls, p); 1690 1614 1691 1615 return ret; 1692 1616 } ··· 1995 1915 d->active_input == p->input->pin)) 1996 1916 *phase_offset = d->phase_offset * ICE_DPLL_PHASE_OFFSET_FACTOR; 1997 1917 else if (d->phase_offset_monitor_period) 1998 - *phase_offset = p->phase_offset * ICE_DPLL_PHASE_OFFSET_FACTOR; 1918 + *phase_offset = (p->input && 1919 + p->direction == DPLL_PIN_DIRECTION_INPUT ? 1920 + p->input->phase_offset : 1921 + p->phase_offset) * ICE_DPLL_PHASE_OFFSET_FACTOR; 1999 1922 else 2000 1923 *phase_offset = 0; 2001 1924 mutex_unlock(&pf->dplls.lock); ··· 2693 2610 } 2694 2611 2695 2612 /** 2613 + * ice_dpll_pin_ntf - notify pin change including any SW pin wrappers 2614 + * @dplls: pointer to dplls struct 2615 + * @pin: the dpll_pin that changed 2616 + * 2617 + * Send a change notification for @pin and for any registered SMA/U.FL pin 2618 + * whose backing CGU input matches @pin. 2619 + */ 2620 + static void ice_dpll_pin_ntf(struct ice_dplls *dplls, struct dpll_pin *pin) 2621 + { 2622 + dpll_pin_change_ntf(pin); 2623 + for (int i = 0; i < ICE_DPLL_PIN_SW_NUM; i++) { 2624 + if (dplls->sma[i].pin && dplls->sma[i].input && 2625 + dplls->sma[i].input->pin == pin) 2626 + dpll_pin_change_ntf(dplls->sma[i].pin); 2627 + if (dplls->ufl[i].pin && dplls->ufl[i].input && 2628 + dplls->ufl[i].input->pin == pin) 2629 + dpll_pin_change_ntf(dplls->ufl[i].pin); 2630 + } 2631 + } 2632 + 2633 + /** 2696 2634 * ice_dpll_notify_changes - notify dpll subsystem about changes 2697 2635 * @d: pointer do dpll 2698 2636 * ··· 2721 2617 */ 2722 2618 static void ice_dpll_notify_changes(struct ice_dpll *d) 2723 2619 { 2620 + struct ice_dplls *dplls = &d->pf->dplls; 2724 2621 bool pin_notified = false; 2725 2622 2726 2623 if (d->prev_dpll_state != d->dpll_state) { ··· 2730 2625 } 2731 2626 if (d->prev_input != d->active_input) { 2732 2627 if (d->prev_input) 2733 - dpll_pin_change_ntf(d->prev_input); 2628 + ice_dpll_pin_ntf(dplls, d->prev_input); 2734 2629 d->prev_input = d->active_input; 2735 2630 if (d->active_input) { 2736 - dpll_pin_change_ntf(d->active_input); 2631 + ice_dpll_pin_ntf(dplls, d->active_input); 2737 2632 pin_notified = true; 2738 2633 } 2739 2634 } 2740 2635 if (d->prev_phase_offset != d->phase_offset) { 2741 2636 d->prev_phase_offset = d->phase_offset; 2742 2637 if (!pin_notified && d->active_input) 2743 - dpll_pin_change_ntf(d->active_input); 2638 + ice_dpll_pin_ntf(dplls, d->active_input); 2744 2639 } 2745 2640 } 2746 2641 ··· 2769 2664 2770 2665 /** 2771 2666 * ice_dpll_pins_notify_mask - notify dpll subsystem about bulk pin changes 2667 + * @dplls: pointer to dplls struct 2772 2668 * @pins: array of ice_dpll_pin pointers registered within dpll subsystem 2773 2669 * @pin_num: number of pins 2774 2670 * @phase_offset_ntf_mask: bitmask of pin indexes to notify ··· 2779 2673 * 2780 2674 * Context: Must be called while pf->dplls.lock is released. 2781 2675 */ 2782 - static void ice_dpll_pins_notify_mask(struct ice_dpll_pin *pins, 2676 + static void ice_dpll_pins_notify_mask(struct ice_dplls *dplls, 2677 + struct ice_dpll_pin *pins, 2783 2678 u8 pin_num, 2784 2679 u32 phase_offset_ntf_mask) 2785 2680 { 2786 - int i = 0; 2787 - 2788 - for (i = 0; i < pin_num; i++) 2789 - if (phase_offset_ntf_mask & (1 << i)) 2790 - dpll_pin_change_ntf(pins[i].pin); 2681 + for (int i = 0; i < pin_num; i++) 2682 + if (phase_offset_ntf_mask & BIT(i)) 2683 + ice_dpll_pin_ntf(dplls, pins[i].pin); 2791 2684 } 2792 2685 2793 2686 /** ··· 2962 2857 ice_dpll_notify_changes(de); 2963 2858 ice_dpll_notify_changes(dp); 2964 2859 if (phase_offset_ntf) 2965 - ice_dpll_pins_notify_mask(d->inputs, d->num_inputs, 2860 + ice_dpll_pins_notify_mask(d, d->inputs, d->num_inputs, 2966 2861 phase_offset_ntf); 2967 2862 2968 2863 resched: ··· 4119 4014 struct ice_dpll_pin *pin; 4120 4015 u32 phase_adj_max, caps; 4121 4016 int i, ret; 4017 + u8 data; 4122 4018 4123 4019 if (pf->hw.device_id == ICE_DEV_ID_E810C_QSFP) 4124 4020 input_idx_offset = ICE_E810_RCLK_PINS_NUM; ··· 4179 4073 } 4180 4074 ice_dpll_phase_range_set(&pin->prop.phase_range, phase_adj_max); 4181 4075 } 4076 + 4077 + /* Initialize the SMA control register to a known-good default state. 4078 + * Without this write the PCA9575 GPIO expander retains its power-on 4079 + * default (all outputs high) which makes all SW pins appear inactive. 4080 + * Set SMA1 and SMA2 as active inputs, disable U.FL1 output and 4081 + * U.FL2 input. 4082 + */ 4083 + ret = ice_read_sma_ctrl(&pf->hw, &data); 4084 + if (ret) 4085 + return ret; 4086 + data &= ~ICE_ALL_SMA_MASK; 4087 + data |= ICE_SMA1_TX_EN | ICE_SMA2_TX_EN | ICE_SMA2_UFL2_RX_DIS; 4088 + ret = ice_write_sma_ctrl(&pf->hw, data); 4089 + if (ret) 4090 + return ret; 4091 + 4182 4092 ret = ice_dpll_pin_state_update(pf, pin, ICE_DPLL_PIN_TYPE_SOFTWARE, 4183 4093 NULL); 4184 4094 if (ret)
+2
drivers/net/ethernet/intel/ice/ice_main.c
··· 5245 5245 return err; 5246 5246 } 5247 5247 5248 + ice_init_dev_hw(pf); 5249 + 5248 5250 adapter = ice_adapter_get(pdev); 5249 5251 if (IS_ERR(adapter)) { 5250 5252 err = PTR_ERR(adapter);
+6 -1
drivers/net/ethernet/intel/ice/ice_vf_lib.c
··· 804 804 ice_vf_ctrl_invalidate_vsi(vf); 805 805 806 806 ice_vf_pre_vsi_rebuild(vf); 807 - ice_vf_rebuild_vsi(vf); 807 + if (ice_vf_rebuild_vsi(vf)) { 808 + dev_err(dev, "VF %u VSI rebuild failed, leaving VF disabled\n", 809 + vf->vf_id); 810 + mutex_unlock(&vf->cfg_lock); 811 + continue; 812 + } 808 813 ice_vf_post_vsi_rebuild(vf); 809 814 810 815 ice_eswitch_attach_vf(pf, vf);
+1 -1
drivers/net/ethernet/sfc/efx_devlink.c
··· 531 531 if (rc || outlength < MC_CMD_GET_VERSION_OUT_LEN) { 532 532 netif_err(efx, drv, efx->net_dev, 533 533 "mcdi MC_CMD_GET_VERSION failed\n"); 534 - return rc; 534 + return rc ?: -EIO; 535 535 } 536 536 537 537 /* Handle previous output */
+12 -7
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
··· 5549 5549 break; 5550 5550 5551 5551 /* Prefetch the next RX descriptor */ 5552 - rx_q->cur_rx = STMMAC_NEXT_ENTRY(rx_q->cur_rx, 5553 - priv->dma_conf.dma_rx_size); 5554 - next_entry = rx_q->cur_rx; 5552 + next_entry = STMMAC_NEXT_ENTRY(rx_q->cur_rx, 5553 + priv->dma_conf.dma_rx_size); 5554 + if (unlikely(next_entry == rx_q->dirty_rx)) 5555 + break; 5556 + 5557 + rx_q->cur_rx = next_entry; 5555 5558 5556 5559 np = stmmac_get_rx_desc(priv, rx_q, next_entry); 5557 5560 ··· 5689 5686 5690 5687 dma_dir = page_pool_get_dma_dir(rx_q->page_pool); 5691 5688 bufsz = DIV_ROUND_UP(priv->dma_conf.dma_buf_sz, PAGE_SIZE) * PAGE_SIZE; 5692 - limit = min(priv->dma_conf.dma_rx_size - 1, (unsigned int)limit); 5693 5689 5694 5690 if (netif_msg_rx_status(priv)) { 5695 5691 void *rx_head = stmmac_get_rx_desc(priv, rx_q, 0); ··· 5735 5733 if (unlikely(status & dma_own)) 5736 5734 break; 5737 5735 5738 - rx_q->cur_rx = STMMAC_NEXT_ENTRY(rx_q->cur_rx, 5739 - priv->dma_conf.dma_rx_size); 5740 - next_entry = rx_q->cur_rx; 5736 + next_entry = STMMAC_NEXT_ENTRY(rx_q->cur_rx, 5737 + priv->dma_conf.dma_rx_size); 5738 + if (unlikely(next_entry == rx_q->dirty_rx)) 5739 + break; 5740 + 5741 + rx_q->cur_rx = next_entry; 5741 5742 5742 5743 np = stmmac_get_rx_desc(priv, rx_q, next_entry); 5743 5744
+2 -2
drivers/net/mctp/mctp-i2c.c
··· 496 496 u8 *pecp; 497 497 int rc; 498 498 499 - fs = mctp_i2c_get_tx_flow_state(midev, skb); 500 - 501 499 hdr = (void *)skb_mac_header(skb); 502 500 /* Sanity check that packet contents matches skb length, 503 501 * and can't exceed MCTP_I2C_BUFSZ ··· 506 508 hdr->byte_count + 3, skb->len); 507 509 return; 508 510 } 511 + 512 + fs = mctp_i2c_get_tx_flow_state(midev, skb); 509 513 510 514 if (skb_tailroom(skb) >= 1) { 511 515 /* Linear case with space, we can just append the PEC */
+30 -19
drivers/net/netconsole.c
··· 752 752 unregister_netcons_consoles(); 753 753 } 754 754 755 - ret = strnlen(buf, count); 755 + ret = count; 756 756 /* Deferred cleanup */ 757 757 netconsole_process_cleanups(); 758 758 out_unlock: ··· 781 781 782 782 nt->release = release; 783 783 784 - ret = strnlen(buf, count); 784 + ret = count; 785 785 out_unlock: 786 786 dynamic_netconsole_mutex_unlock(); 787 787 return ret; ··· 807 807 goto out_unlock; 808 808 809 809 nt->extended = extended; 810 - ret = strnlen(buf, count); 810 + ret = count; 811 811 out_unlock: 812 812 dynamic_netconsole_mutex_unlock(); 813 813 return ret; ··· 817 817 size_t count) 818 818 { 819 819 struct netconsole_target *nt = to_target(item); 820 + size_t len = count; 821 + 822 + /* Account for a trailing newline appended by tools like echo */ 823 + if (len && buf[len - 1] == '\n') 824 + len--; 825 + if (len >= IFNAMSIZ) 826 + return -ENAMETOOLONG; 820 827 821 828 dynamic_netconsole_mutex_lock(); 822 829 if (nt->state == STATE_ENABLED) { ··· 837 830 trim_newline(nt->np.dev_name, IFNAMSIZ); 838 831 839 832 dynamic_netconsole_mutex_unlock(); 840 - return strnlen(buf, count); 833 + return count; 841 834 } 842 835 843 836 static ssize_t local_port_store(struct config_item *item, const char *buf, ··· 856 849 ret = kstrtou16(buf, 10, &nt->np.local_port); 857 850 if (ret < 0) 858 851 goto out_unlock; 859 - ret = strnlen(buf, count); 852 + ret = count; 860 853 out_unlock: 861 854 dynamic_netconsole_mutex_unlock(); 862 855 return ret; ··· 878 871 ret = kstrtou16(buf, 10, &nt->np.remote_port); 879 872 if (ret < 0) 880 873 goto out_unlock; 881 - ret = strnlen(buf, count); 874 + ret = count; 882 875 out_unlock: 883 876 dynamic_netconsole_mutex_unlock(); 884 877 return ret; ··· 903 896 goto out_unlock; 904 897 nt->np.ipv6 = !!ipv6; 905 898 906 - ret = strnlen(buf, count); 899 + ret = count; 907 900 out_unlock: 908 901 dynamic_netconsole_mutex_unlock(); 909 902 return ret; ··· 928 921 goto out_unlock; 929 922 nt->np.ipv6 = !!ipv6; 930 923 931 - ret = strnlen(buf, count); 924 + ret = count; 932 925 out_unlock: 933 926 dynamic_netconsole_mutex_unlock(); 934 927 return ret; ··· 964 957 goto out_unlock; 965 958 memcpy(nt->np.remote_mac, remote_mac, ETH_ALEN); 966 959 967 - ret = strnlen(buf, count); 960 + ret = count; 968 961 out_unlock: 969 962 dynamic_netconsole_mutex_unlock(); 970 963 return ret; ··· 1079 1072 size_t count) 1080 1073 { 1081 1074 struct userdatum *udm = to_userdatum(item); 1075 + char old_value[MAX_EXTRADATA_VALUE_LEN]; 1082 1076 struct netconsole_target *nt; 1083 1077 struct userdata *ud; 1084 1078 ssize_t ret; 1085 1079 1086 - if (count > MAX_EXTRADATA_VALUE_LEN) 1080 + if (count >= MAX_EXTRADATA_VALUE_LEN) 1087 1081 return -EMSGSIZE; 1088 1082 1089 1083 mutex_lock(&netconsole_subsys.su_mutex); 1090 1084 dynamic_netconsole_mutex_lock(); 1091 - 1092 - ret = strscpy(udm->value, buf, sizeof(udm->value)); 1093 - if (ret < 0) 1094 - goto out_unlock; 1085 + /* Snapshot for rollback if update_userdata() fails below */ 1086 + strscpy(old_value, udm->value, sizeof(old_value)); 1087 + /* count is bounded above, so strscpy() cannot truncate here */ 1088 + strscpy(udm->value, buf, sizeof(udm->value)); 1095 1089 trim_newline(udm->value, sizeof(udm->value)); 1096 1090 1097 1091 ud = to_userdata(item->ci_parent); 1098 1092 nt = userdata_to_target(ud); 1099 1093 ret = update_userdata(nt); 1100 - if (ret < 0) 1094 + if (ret < 0) { 1095 + /* Restore the previous value so it matches the live payload */ 1096 + strscpy(udm->value, old_value, sizeof(udm->value)); 1101 1097 goto out_unlock; 1098 + } 1102 1099 ret = count; 1103 1100 out_unlock: 1104 1101 dynamic_netconsole_mutex_unlock(); ··· 1144 1133 disable_sysdata_feature(nt, SYSDATA_MSGID); 1145 1134 1146 1135 unlock_ok: 1147 - ret = strnlen(buf, count); 1136 + ret = count; 1148 1137 dynamic_netconsole_mutex_unlock(); 1149 1138 mutex_unlock(&netconsole_subsys.su_mutex); 1150 1139 return ret; ··· 1173 1162 disable_sysdata_feature(nt, SYSDATA_RELEASE); 1174 1163 1175 1164 unlock_ok: 1176 - ret = strnlen(buf, count); 1165 + ret = count; 1177 1166 dynamic_netconsole_mutex_unlock(); 1178 1167 mutex_unlock(&netconsole_subsys.su_mutex); 1179 1168 return ret; ··· 1202 1191 disable_sysdata_feature(nt, SYSDATA_TASKNAME); 1203 1192 1204 1193 unlock_ok: 1205 - ret = strnlen(buf, count); 1194 + ret = count; 1206 1195 dynamic_netconsole_mutex_unlock(); 1207 1196 mutex_unlock(&netconsole_subsys.su_mutex); 1208 1197 return ret; ··· 1236 1225 disable_sysdata_feature(nt, SYSDATA_CPU_NR); 1237 1226 1238 1227 unlock_ok: 1239 - ret = strnlen(buf, count); 1228 + ret = count; 1240 1229 dynamic_netconsole_mutex_unlock(); 1241 1230 mutex_unlock(&netconsole_subsys.su_mutex); 1242 1231 return ret;
+1 -1
drivers/net/netdevsim/dev.c
··· 829 829 skb->protocol = htons(ETH_P_IP); 830 830 831 831 skb_set_network_header(skb, skb->len); 832 - iph = skb_put(skb, sizeof(struct iphdr)); 832 + iph = skb_put_zero(skb, sizeof(struct iphdr)); 833 833 iph->protocol = IPPROTO_UDP; 834 834 iph->saddr = in_aton("192.0.2.1"); 835 835 iph->daddr = in_aton("198.51.100.1");
+12 -1
drivers/net/phy/dp83869.c
··· 31 31 #define DP83869_RGMIICTL 0x0032 32 32 #define DP83869_STRAP_STS1 0x006e 33 33 #define DP83869_RGMIIDCTL 0x0086 34 + #define DP83869_ANA_PLL_PROG_PI 0x00c6 34 35 #define DP83869_RXFCFG 0x0134 35 36 #define DP83869_RXFPMD1 0x0136 36 37 #define DP83869_RXFPMD2 0x0137 ··· 827 826 dp83869_config_port_mirroring(phydev); 828 827 829 828 /* Clock output selection if muxing property is set */ 830 - if (dp83869->clk_output_sel != DP83869_CLK_O_SEL_REF_CLK) 829 + if (dp83869->clk_output_sel != DP83869_CLK_O_SEL_REF_CLK) { 830 + /* 831 + * Table 7-121 in datasheet says we have to set register 0xc6 832 + * to value 0x10 before CLK_O_SEL can be modified. 833 + */ 834 + ret = phy_write_mmd(phydev, DP83869_DEVADDR, 835 + DP83869_ANA_PLL_PROG_PI, 0x10); 836 + if (ret) 837 + return ret; 838 + 831 839 ret = phy_modify_mmd(phydev, 832 840 DP83869_DEVADDR, DP83869_IO_MUX_CFG, 833 841 DP83869_IO_MUX_CFG_CLK_O_SEL_MASK, 834 842 dp83869->clk_output_sel << 835 843 DP83869_IO_MUX_CFG_CLK_O_SEL_SHIFT); 844 + } 836 845 837 846 if (phy_interface_is_rgmii(phydev)) { 838 847 ret = phy_write_mmd(phydev, DP83869_DEVADDR, DP83869_RGMIIDCTL,
+11 -1
drivers/net/usb/rtl8150.c
··· 683 683 struct net_device *netdev) 684 684 { 685 685 rtl8150_t *dev = netdev_priv(netdev); 686 + unsigned int skb_len; 686 687 int count, res; 687 688 688 689 /* pad the frame and ensure terminating USB packet, datasheet 9.2.3 */ ··· 694 693 netdev->stats.tx_dropped++; 695 694 return NETDEV_TX_OK; 696 695 } 696 + 697 + skb_len = skb->len; 697 698 698 699 netif_stop_queue(netdev); 699 700 dev->tx_skb = skb; ··· 710 707 netdev->stats.tx_errors++; 711 708 netif_start_queue(netdev); 712 709 } 710 + /* 711 + * The URB was not submitted, so write_bulk_callback() will 712 + * never run to free dev->tx_skb. Drop the skb here and 713 + * clear tx_skb to avoid leaving a stale pointer. 714 + */ 715 + dev->tx_skb = NULL; 716 + dev_kfree_skb_any(skb); 713 717 } else { 714 718 netdev->stats.tx_packets++; 715 - netdev->stats.tx_bytes += skb->len; 719 + netdev->stats.tx_bytes += skb_len; 716 720 netif_trans_update(netdev); 717 721 } 718 722
+11 -4
drivers/net/vrf.c
··· 1034 1034 1035 1035 err: 1036 1036 port_dev->priv_flags &= ~IFF_L3MDEV_SLAVE; 1037 + synchronize_net(); 1037 1038 return ret; 1038 1039 } 1039 1040 ··· 1054 1053 } 1055 1054 1056 1055 /* inverse of do_vrf_add_slave */ 1057 - static int do_vrf_del_slave(struct net_device *dev, struct net_device *port_dev) 1056 + static int do_vrf_del_slave(struct net_device *dev, struct net_device *port_dev, 1057 + bool needs_sync) 1058 1058 { 1059 1059 netdev_upper_dev_unlink(port_dev, dev); 1060 1060 port_dev->priv_flags &= ~IFF_L3MDEV_SLAVE; 1061 + /* Make sure that concurrent RCU readers that identified the device 1062 + * as a VRF port see a VRF master or no master at all. 1063 + */ 1064 + if (needs_sync) 1065 + synchronize_net(); 1061 1066 1062 1067 cycle_netdev(port_dev, NULL); 1063 1068 ··· 1072 1065 1073 1066 static int vrf_del_slave(struct net_device *dev, struct net_device *port_dev) 1074 1067 { 1075 - return do_vrf_del_slave(dev, port_dev); 1068 + return do_vrf_del_slave(dev, port_dev, true); 1076 1069 } 1077 1070 1078 1071 static void vrf_dev_uninit(struct net_device *dev) ··· 1626 1619 struct list_head *iter; 1627 1620 1628 1621 netdev_for_each_lower_dev(dev, port_dev, iter) 1629 - vrf_del_slave(dev, port_dev); 1622 + do_vrf_del_slave(dev, port_dev, false); 1630 1623 1631 1624 vrf_map_unregister_dev(dev); 1632 1625 ··· 1758 1751 goto out; 1759 1752 1760 1753 vrf_dev = netdev_master_upper_dev_get(dev); 1761 - vrf_del_slave(vrf_dev, dev); 1754 + do_vrf_del_slave(vrf_dev, dev, false); 1762 1755 } 1763 1756 out: 1764 1757 return NOTIFY_DONE;
+2 -1
drivers/nfc/trf7970a.c
··· 317 317 #define TRF7970A_RSSI_OSC_STATUS_RSSI_MASK (BIT(2) | BIT(1) | BIT(0)) 318 318 #define TRF7970A_RSSI_OSC_STATUS_RSSI_X_MASK (BIT(5) | BIT(4) | BIT(3)) 319 319 #define TRF7970A_RSSI_OSC_STATUS_RSSI_OSC_OK BIT(6) 320 + #define TRF7970A_RSSI_OSC_STATUS_RSSI_NOISE_LEVEL 1 320 321 321 322 #define TRF7970A_SPECIAL_FCN_REG1_COL_7_6 BIT(0) 322 323 #define TRF7970A_SPECIAL_FCN_REG1_14_ANTICOLL BIT(1) ··· 1301 1300 if (ret) 1302 1301 return ret; 1303 1302 1304 - if (rssi & TRF7970A_RSSI_OSC_STATUS_RSSI_MASK) 1303 + if ((rssi & TRF7970A_RSSI_OSC_STATUS_RSSI_MASK) > TRF7970A_RSSI_OSC_STATUS_RSSI_NOISE_LEVEL) 1305 1304 *is_rf_field = true; 1306 1305 else 1307 1306 *is_rf_field = false;
+1
include/linux/dpll.h
··· 286 286 287 287 int dpll_device_change_ntf(struct dpll_device *dpll); 288 288 289 + int __dpll_pin_change_ntf(struct dpll_pin *pin); 289 290 int dpll_pin_change_ntf(struct dpll_pin *pin); 290 291 291 292 int register_dpll_notifier(struct notifier_block *nb);
+3
include/linux/mroute_base.h
··· 226 226 227 227 /** 228 228 * struct mr_table - a multicast routing table 229 + * @work: used for table destruction 229 230 * @list: entry within a list of multicast routing tables 230 231 * @net: net where this table belongs 231 232 * @ops: protocol specific operations ··· 244 243 * @mroute_reg_vif_num: PIM-device vif index 245 244 */ 246 245 struct mr_table { 246 + struct rcu_work work; 247 247 struct list_head list; 248 248 possible_net_t net; 249 249 struct mr_table_ops ops; ··· 276 274 unsigned short flags, 277 275 unsigned short get_iflink_mask); 278 276 277 + void mr_table_free(struct mr_table *mrt); 279 278 struct mr_table * 280 279 mr_table_alloc(struct net *net, u32 id, 281 280 struct mr_table_ops *ops,
+29
include/linux/rculist.h
··· 261 261 old->prev = LIST_POISON2; 262 262 } 263 263 264 + static inline void __list_splice_rcu(struct list_head *list, 265 + struct list_head *prev, 266 + struct list_head *next) 267 + { 268 + struct list_head *first = list->next; 269 + struct list_head *last = list->prev; 270 + 271 + last->next = next; 272 + first->prev = prev; 273 + next->prev = last; 274 + rcu_assign_pointer(list_next_rcu(prev), first); 275 + } 276 + 277 + /** 278 + * list_splice_rcu - splice a non-RCU list into an RCU-protected list, 279 + * designed for stacks. 280 + * @list: the non RCU-protected list to splice 281 + * @head: the place in the existing RCU-protected list to splice 282 + * 283 + * The list pointed to by @head can be RCU-read traversed concurrently with 284 + * this function. 285 + */ 286 + static inline void list_splice_rcu(struct list_head *list, 287 + struct list_head *head) 288 + { 289 + if (!list_empty(list)) 290 + __list_splice_rcu(list, head, head->next); 291 + } 292 + 264 293 /** 265 294 * __list_splice_init_rcu - join an RCU-protected list into an existing list. 266 295 * @list: the RCU-protected list to splice
+1 -1
include/net/bond_3ad.h
··· 243 243 churn_state_t sm_churn_actor_state; 244 244 churn_state_t sm_churn_partner_state; 245 245 struct slave *slave; /* pointer to the bond slave that this port belongs to */ 246 - struct aggregator *aggregator; /* pointer to an aggregator that this port related to */ 246 + struct aggregator __rcu *aggregator; /* pointer to an aggregator that this port related to */ 247 247 struct port *next_port_in_aggregator; /* Next port on the linked list of the parent aggregator */ 248 248 u32 transaction_id; /* continuous number for identification of Marker PDU's; */ 249 249 struct lacpdu lacpdu; /* the lacpdu that will be sent for this port */
+13
include/net/netfilter/nf_tables.h
··· 1204 1204 struct u64_stats_sync syncp; 1205 1205 }; 1206 1206 1207 + #define NFT_HOOK_REMOVE (1 << 0) 1208 + 1207 1209 struct nft_hook { 1208 1210 struct list_head list; 1209 1211 struct list_head ops_list; 1210 1212 struct rcu_head rcu; 1211 1213 char ifname[IFNAMSIZ]; 1212 1214 u8 ifnamelen; 1215 + u8 flags; 1213 1216 }; 1214 1217 1215 1218 struct nf_hook_ops *nft_hook_find_ops(const struct nft_hook *hook, ··· 1665 1662 u16 flags; 1666 1663 u8 report:1; 1667 1664 u8 put_net:1; 1665 + }; 1666 + 1667 + /** 1668 + * struct nft_trans_hook - nf_tables hook update in transaction 1669 + * @list: used internally 1670 + * @hook: struct nft_hook with the device hook 1671 + */ 1672 + struct nft_trans_hook { 1673 + struct list_head list; 1674 + struct nft_hook *hook; 1668 1675 }; 1669 1676 1670 1677 /**
+15
include/net/netmem.h
··· 127 127 return niov - net_iov_owner(niov)->niovs; 128 128 } 129 129 130 + /* Initialize a niov: stamp the owning area, the memory provider type, 131 + * and the page_type "no type" sentinel expected by the page-type API 132 + * (see PAGE_TYPE_OPS in <linux/page-flags.h>) so that 133 + * page_pool_set_pp_info() can later call __SetPageNetpp() on a niov 134 + * cast to struct page. 135 + */ 136 + static inline void net_iov_init(struct net_iov *niov, 137 + struct net_iov_area *owner, 138 + enum net_iov_type type) 139 + { 140 + niov->owner = owner; 141 + niov->type = type; 142 + niov->page_type = UINT_MAX; 143 + } 144 + 130 145 /* netmem */ 131 146 132 147 /**
+1 -2
io_uring/zcrx.c
··· 495 495 for (i = 0; i < nr_iovs; i++) { 496 496 struct net_iov *niov = &area->nia.niovs[i]; 497 497 498 - niov->owner = &area->nia; 498 + net_iov_init(niov, &area->nia, NET_IOV_IOURING); 499 499 area->freelist[i] = i; 500 500 atomic_set(&area->user_refs[i], 0); 501 - niov->type = NET_IOV_IOURING; 502 501 } 503 502 504 503 if (ifq->dev) {
+1 -2
net/core/devmem.c
··· 297 297 298 298 for (i = 0; i < owner->area.num_niovs; i++) { 299 299 niov = &owner->area.niovs[i]; 300 - niov->type = NET_IOV_DMABUF; 301 - niov->owner = &owner->area; 300 + net_iov_init(niov, &owner->area, NET_IOV_DMABUF); 302 301 page_pool_set_dma_addr_netmem(net_iov_to_netmem(niov), 303 302 net_devmem_get_dma_addr(niov)); 304 303 if (direction == DMA_TO_DEVICE)
+5 -5
net/core/neighbour.c
··· 3210 3210 3211 3211 rcu_read_lock(); 3212 3212 tbl = rcu_dereference(neigh_tables[index]); 3213 - if (!tbl) 3214 - goto out_unlock; 3213 + if (!tbl) { 3214 + rcu_read_unlock(); 3215 + goto out_kfree_skb; 3216 + } 3215 3217 if (index == NEIGH_ARP_TABLE) { 3216 3218 u32 key = *((u32 *)addr); 3217 3219 ··· 3229 3227 goto out_kfree_skb; 3230 3228 } 3231 3229 err = READ_ONCE(neigh->output)(neigh, skb); 3232 - out_unlock: 3233 3230 rcu_read_unlock(); 3234 3231 } 3235 3232 else if (index == NEIGH_LINK_TABLE) { ··· 3238 3237 goto out_kfree_skb; 3239 3238 err = dev_queue_xmit(skb); 3240 3239 } 3241 - out: 3242 3240 return err; 3243 3241 out_kfree_skb: 3244 3242 kfree_skb(skb); 3245 - goto out; 3243 + return err; 3246 3244 } 3247 3245 EXPORT_SYMBOL(neigh_xmit); 3248 3246
+18 -1
net/core/netpoll.c
··· 704 704 return 0; 705 705 } 706 706 707 + /* 708 + * Test whether the caller left np->local_ip unset, so that 709 + * netpoll_setup() should auto-populate it from the egress device. 710 + * 711 + * np->local_ip is a union of __be32 (IPv4) and struct in6_addr (IPv6), 712 + * so an IPv6 address whose first 4 bytes are zero (e.g. ::1, ::2, 713 + * IPv4-mapped ::ffff:a.b.c.d) must not be tested via the IPv4 arm — 714 + * doing so would misclassify a caller-supplied address as unset and 715 + * silently overwrite it with whatever address the device exposes. 716 + */ 717 + static bool netpoll_local_ip_unset(const struct netpoll *np) 718 + { 719 + if (np->ipv6) 720 + return ipv6_addr_any(&np->local_ip.in6); 721 + return !np->local_ip.ip; 722 + } 723 + 707 724 int netpoll_setup(struct netpoll *np) 708 725 { 709 726 struct net *net = current->nsproxy->net_ns; ··· 764 747 rtnl_lock(); 765 748 } 766 749 767 - if (!np->local_ip.ip) { 750 + if (netpoll_local_ip_unset(np)) { 768 751 if (!np->ipv6) { 769 752 err = netpoll_take_ipv4(np, ndev); 770 753 if (err)
+5 -5
net/core/page_pool.c
··· 327 327 if (!pool->system) 328 328 free_percpu(pool->recycle_stats); 329 329 #endif 330 + 331 + if (pool->mp_ops) { 332 + pool->mp_ops->destroy(pool); 333 + static_branch_dec(&page_pool_mem_providers); 334 + } 330 335 } 331 336 332 337 /** ··· 1150 1145 1151 1146 page_pool_unlist(pool); 1152 1147 page_pool_uninit(pool); 1153 - 1154 - if (pool->mp_ops) { 1155 - pool->mp_ops->destroy(pool); 1156 - static_branch_dec(&page_pool_mem_providers); 1157 - } 1158 1148 1159 1149 kfree(pool); 1160 1150 }
+58 -50
net/ipv4/ipmr.c
··· 151 151 return NULL; 152 152 } 153 153 154 - static struct mr_table *ipmr_get_table(struct net *net, u32 id) 155 - { 156 - struct mr_table *mrt; 157 - 158 - rcu_read_lock(); 159 - mrt = __ipmr_get_table(net, id); 160 - rcu_read_unlock(); 161 - return mrt; 162 - } 163 - 164 154 static int ipmr_fib_lookup(struct net *net, struct flowi4 *flp4, 165 155 struct mr_table **mrt) 166 156 { ··· 283 293 struct mr_table *mrt, *next; 284 294 285 295 list_for_each_entry_safe(mrt, next, &net->ipv4.mr_tables, list) { 286 - list_del(&mrt->list); 296 + list_del_rcu(&mrt->list); 287 297 ipmr_free_table(mrt, dev_kill_list); 288 298 } 289 299 } ··· 305 315 } 306 316 EXPORT_SYMBOL(ipmr_rule_default); 307 317 #else 308 - #define ipmr_for_each_table(mrt, net) \ 309 - for (mrt = net->ipv4.mrt; mrt; mrt = NULL) 310 - 311 318 static struct mr_table *ipmr_mr_table_iter(struct net *net, 312 319 struct mr_table *mrt) 313 320 { 314 321 if (!mrt) 315 - return net->ipv4.mrt; 322 + return rcu_dereference(net->ipv4.mrt); 316 323 return NULL; 317 324 } 318 325 319 - static struct mr_table *ipmr_get_table(struct net *net, u32 id) 326 + static struct mr_table *__ipmr_get_table(struct net *net, u32 id) 320 327 { 321 - return net->ipv4.mrt; 328 + return rcu_dereference_check(net->ipv4.mrt, 329 + lockdep_rtnl_is_held() || 330 + !rcu_access_pointer(net->ipv4.mrt)); 322 331 } 323 332 324 - #define __ipmr_get_table ipmr_get_table 333 + #define ipmr_for_each_table(mrt, net) \ 334 + for (mrt = __ipmr_get_table(net, 0); mrt; mrt = NULL) 325 335 326 336 static int ipmr_fib_lookup(struct net *net, struct flowi4 *flp4, 327 337 struct mr_table **mrt) 328 338 { 329 - *mrt = net->ipv4.mrt; 339 + *mrt = rcu_dereference(net->ipv4.mrt); 340 + if (!*mrt) 341 + return -EAGAIN; 330 342 return 0; 331 343 } 332 344 ··· 339 347 mrt = ipmr_new_table(net, RT_TABLE_DEFAULT); 340 348 if (IS_ERR(mrt)) 341 349 return PTR_ERR(mrt); 342 - net->ipv4.mrt = mrt; 350 + 351 + rcu_assign_pointer(net->ipv4.mrt, mrt); 343 352 return 0; 344 353 } 345 354 ··· 351 358 static void __net_exit ipmr_rules_exit_rtnl(struct net *net, 352 359 struct list_head *dev_kill_list) 353 360 { 354 - ipmr_free_table(net->ipv4.mrt, dev_kill_list); 361 + struct mr_table *mrt = rcu_dereference_protected(net->ipv4.mrt, 1); 355 362 356 - net->ipv4.mrt = NULL; 363 + RCU_INIT_POINTER(net->ipv4.mrt, NULL); 364 + ipmr_free_table(mrt, dev_kill_list); 357 365 } 358 366 359 367 static int ipmr_rules_dump(struct net *net, struct notifier_block *nb, ··· 374 380 } 375 381 EXPORT_SYMBOL(ipmr_rule_default); 376 382 #endif 383 + 384 + static struct mr_table *ipmr_get_table(struct net *net, u32 id) 385 + { 386 + struct mr_table *mrt; 387 + 388 + rcu_read_lock(); 389 + mrt = __ipmr_get_table(net, id); 390 + rcu_read_unlock(); 391 + 392 + return mrt; 393 + } 377 394 378 395 static inline int ipmr_hash_cmp(struct rhashtable_compare_arg *arg, 379 396 const void *ptr) ··· 446 441 447 442 WARN_ON_ONCE(!mr_can_free_table(net)); 448 443 449 - timer_shutdown_sync(&mrt->ipmr_expire_timer); 450 444 mroute_clean_tables(mrt, MRT_FLUSH_VIFS | MRT_FLUSH_VIFS_STATIC | 451 445 MRT_FLUSH_MFC | MRT_FLUSH_MFC_STATIC, 452 446 &ipmr_dev_kill_list); 453 - rhltable_destroy(&mrt->mfc_hash); 454 - kfree(mrt); 447 + timer_shutdown_sync(&mrt->ipmr_expire_timer); 448 + mr_table_free(mrt); 455 449 456 450 WARN_ON_ONCE(!net_initialized(net) && !list_empty(&ipmr_dev_kill_list)); 457 451 list_splice(&ipmr_dev_kill_list, dev_kill_list); ··· 1139 1135 static int ipmr_cache_unresolved(struct mr_table *mrt, vifi_t vifi, 1140 1136 struct sk_buff *skb, struct net_device *dev) 1141 1137 { 1138 + struct net *net = read_pnet(&mrt->net); 1142 1139 const struct iphdr *iph = ip_hdr(skb); 1143 - struct mfc_cache *c; 1140 + struct mfc_cache *c = NULL; 1144 1141 bool found = false; 1145 1142 int err; 1146 1143 1147 1144 spin_lock_bh(&mfc_unres_lock); 1145 + 1146 + if (!check_net(net)) { 1147 + err = -EINVAL; 1148 + goto err; 1149 + } 1150 + 1148 1151 list_for_each_entry(c, &mrt->mfc_unres_queue, _c.list) { 1149 1152 if (c->mfc_mcastgrp == iph->daddr && 1150 1153 c->mfc_origin == iph->saddr) { ··· 1164 1153 /* Create a new entry if allowable */ 1165 1154 c = ipmr_cache_alloc_unres(); 1166 1155 if (!c) { 1167 - spin_unlock_bh(&mfc_unres_lock); 1168 - 1169 - kfree_skb(skb); 1170 - return -ENOBUFS; 1156 + err = -ENOBUFS; 1157 + goto err; 1171 1158 } 1172 1159 1173 1160 /* Fill in the new cache entry */ ··· 1175 1166 1176 1167 /* Reflect first query at mrouted. */ 1177 1168 err = ipmr_cache_report(mrt, skb, vifi, IGMPMSG_NOCACHE); 1178 - 1179 - if (err < 0) { 1180 - /* If the report failed throw the cache entry 1181 - out - Brad Parker 1182 - */ 1183 - spin_unlock_bh(&mfc_unres_lock); 1184 - 1185 - ipmr_cache_free(c); 1186 - kfree_skb(skb); 1187 - return err; 1188 - } 1169 + if (err < 0) 1170 + goto err; 1189 1171 1190 1172 atomic_inc(&mrt->cache_resolve_queue_len); 1191 1173 list_add(&c->_c.list, &mrt->mfc_unres_queue); ··· 1189 1189 1190 1190 /* See if we can append the packet */ 1191 1191 if (c->_c.mfc_un.unres.unresolved.qlen > 3) { 1192 - kfree_skb(skb); 1192 + c = NULL; 1193 1193 err = -ENOBUFS; 1194 - } else { 1195 - if (dev) { 1196 - skb->dev = dev; 1197 - skb->skb_iif = dev->ifindex; 1198 - } 1199 - skb_queue_tail(&c->_c.mfc_un.unres.unresolved, skb); 1200 - err = 0; 1194 + goto err; 1201 1195 } 1202 1196 1197 + if (dev) { 1198 + skb->dev = dev; 1199 + skb->skb_iif = dev->ifindex; 1200 + } 1201 + 1202 + skb_queue_tail(&c->_c.mfc_un.unres.unresolved, skb); 1203 + 1203 1204 spin_unlock_bh(&mfc_unres_lock); 1205 + return 0; 1206 + 1207 + err: 1208 + spin_unlock_bh(&mfc_unres_lock); 1209 + if (c) 1210 + ipmr_cache_free(c); 1211 + kfree_skb(skb); 1204 1212 return err; 1205 1213 } 1206 1214 ··· 1354 1346 } 1355 1347 1356 1348 if (flags & MRT_FLUSH_MFC) { 1357 - if (atomic_read(&mrt->cache_resolve_queue_len) != 0) { 1349 + if (atomic_read(&mrt->cache_resolve_queue_len) != 0 || !check_net(net)) { 1358 1350 spin_lock_bh(&mfc_unres_lock); 1359 1351 list_for_each_entry_safe(c, tmp, &mrt->mfc_unres_queue, list) { 1360 1352 list_del(&c->list);
+16
net/ipv4/ipmr_base.c
··· 28 28 v->link = dev->ifindex; 29 29 } 30 30 31 + static void __mr_free_table(struct work_struct *work) 32 + { 33 + struct mr_table *mrt = container_of(to_rcu_work(work), 34 + struct mr_table, work); 35 + 36 + rhltable_destroy(&mrt->mfc_hash); 37 + kfree(mrt); 38 + } 39 + 40 + void mr_table_free(struct mr_table *mrt) 41 + { 42 + queue_rcu_work(system_unbound_wq, &mrt->work); 43 + } 44 + 31 45 struct mr_table * 32 46 mr_table_alloc(struct net *net, u32 id, 33 47 struct mr_table_ops *ops, ··· 64 50 kfree(mrt); 65 51 return ERR_PTR(err); 66 52 } 53 + 54 + INIT_RCU_WORK(&mrt->work, __mr_free_table); 67 55 INIT_LIST_HEAD(&mrt->mfc_cache_list); 68 56 INIT_LIST_HEAD(&mrt->mfc_unres_queue); 69 57
+15 -3
net/ipv4/netfilter/arp_tables.c
··· 110 110 arpptr += dev->addr_len; 111 111 memcpy(&src_ipaddr, arpptr, sizeof(u32)); 112 112 arpptr += sizeof(u32); 113 - tgt_devaddr = arpptr; 114 - arpptr += dev->addr_len; 113 + 114 + if (IS_ENABLED(CONFIG_FIREWIRE_NET) && dev->type == ARPHRD_IEEE1394) { 115 + if (unlikely(memchr_inv(arpinfo->tgt_devaddr.mask, 0, 116 + sizeof(arpinfo->tgt_devaddr.mask)))) 117 + return 0; 118 + 119 + tgt_devaddr = NULL; 120 + } else { 121 + tgt_devaddr = arpptr; 122 + arpptr += dev->addr_len; 123 + } 115 124 memcpy(&tgt_ipaddr, arpptr, sizeof(u32)); 116 125 117 126 if (NF_INVF(arpinfo, ARPT_INV_SRCDEVADDR, 118 127 arp_devaddr_compare(&arpinfo->src_devaddr, src_devaddr, 119 - dev->addr_len)) || 128 + dev->addr_len))) 129 + return 0; 130 + 131 + if (tgt_devaddr && 120 132 NF_INVF(arpinfo, ARPT_INV_TGTDEVADDR, 121 133 arp_devaddr_compare(&arpinfo->tgt_devaddr, tgt_devaddr, 122 134 dev->addr_len)))
+8
net/ipv4/netfilter/arpt_mangle.c
··· 40 40 } 41 41 arpptr += pln; 42 42 if (mangle->flags & ARPT_MANGLE_TDEV) { 43 + if (unlikely(IS_ENABLED(CONFIG_FIREWIRE_NET) && 44 + skb->dev->type == ARPHRD_IEEE1394)) 45 + return NF_DROP; 46 + 43 47 if (ARPT_DEV_ADDR_LEN_MAX < hln || 44 48 (arpptr + hln > skb_tail_pointer(skb))) 45 49 return NF_DROP; ··· 51 47 } 52 48 arpptr += hln; 53 49 if (mangle->flags & ARPT_MANGLE_TIP) { 50 + if (unlikely(IS_ENABLED(CONFIG_FIREWIRE_NET) && 51 + skb->dev->type == ARPHRD_IEEE1394)) 52 + return NF_DROP; 53 + 54 54 if (ARPT_MANGLE_ADDR_LEN_MAX < pln || 55 55 (arpptr + pln > skb_tail_pointer(skb))) 56 56 return NF_DROP;
+3 -2
net/ipv4/tcp_timer.c
··· 50 50 u32 tcp_clamp_probe0_to_user_timeout(const struct sock *sk, u32 when) 51 51 { 52 52 const struct inet_connection_sock *icsk = inet_csk(sk); 53 - u32 remaining, user_timeout; 53 + u32 user_timeout; 54 + s32 remaining; 54 55 s32 elapsed; 55 56 56 57 user_timeout = READ_ONCE(icsk->icsk_user_timeout); ··· 62 61 if (unlikely(elapsed < 0)) 63 62 elapsed = 0; 64 63 remaining = msecs_to_jiffies(user_timeout) - elapsed; 65 - remaining = max_t(u32, remaining, TCP_TIMEOUT_MIN); 64 + remaining = max_t(int, remaining, TCP_TIMEOUT_MIN); 66 65 67 66 return min_t(u32, remaining, when); 68 67 }
+6 -3
net/ipv6/exthdrs.c
··· 491 491 struct net *net = dev_net(skb->dev); 492 492 struct inet6_dev *idev; 493 493 struct ipv6hdr *oldhdr; 494 + unsigned int chdr_len; 494 495 unsigned char *buf; 495 496 int accept_rpl_seg; 496 497 int i, err; ··· 593 592 skb_pull(skb, ((hdr->hdrlen + 1) << 3)); 594 593 skb_postpull_rcsum(skb, oldhdr, 595 594 sizeof(struct ipv6hdr) + ((hdr->hdrlen + 1) << 3)); 596 - if (unlikely(!hdr->segments_left)) { 597 - if (pskb_expand_head(skb, sizeof(struct ipv6hdr) + ((chdr->hdrlen + 1) << 3), 0, 595 + chdr_len = sizeof(struct ipv6hdr) + ((chdr->hdrlen + 1) << 3); 596 + if (unlikely(!hdr->segments_left || 597 + skb_headroom(skb) < chdr_len + skb->mac_len)) { 598 + if (pskb_expand_head(skb, chdr_len + skb->mac_len, 0, 598 599 GFP_ATOMIC)) { 599 600 __IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_OUTDISCARDS); 600 601 kfree_skb(skb); ··· 606 603 607 604 oldhdr = ipv6_hdr(skb); 608 605 } 609 - skb_push(skb, ((chdr->hdrlen + 1) << 3) + sizeof(struct ipv6hdr)); 606 + skb_push(skb, chdr_len); 610 607 skb_reset_network_header(skb); 611 608 skb_mac_header_rebuild(skb); 612 609 skb_set_transport_header(skb, sizeof(struct ipv6hdr));
+9
net/ipv6/rpl_iptunnel.c
··· 287 287 288 288 if (!dst) { 289 289 ip6_route_input(skb); 290 + 291 + /* ip6_route_input() sets a NOREF dst; force a refcount on it 292 + * before caching or further use. 293 + */ 294 + skb_dst_force(skb); 290 295 dst = skb_dst(skb); 296 + if (unlikely(!dst)) { 297 + err = -ENETUNREACH; 298 + goto drop; 299 + } 291 300 292 301 /* cache only if we don't create a dst reference loop */ 293 302 if (!dst->error && lwtst != dst->lwtstate) {
+9
net/ipv6/seg6_iptunnel.c
··· 515 515 516 516 if (!dst) { 517 517 ip6_route_input(skb); 518 + 519 + /* ip6_route_input() sets a NOREF dst; force a refcount on it 520 + * before caching or further use. 521 + */ 522 + skb_dst_force(skb); 518 523 dst = skb_dst(skb); 524 + if (unlikely(!dst)) { 525 + err = -ENETUNREACH; 526 + goto drop; 527 + } 519 528 520 529 /* cache only if we don't create a dst reference loop */ 521 530 if (!dst->error && lwtst != dst->lwtstate) {
+1
net/mptcp/pm_kernel.c
··· 1278 1278 WRITE_ONCE(pernet->endp_signal_max, 0); 1279 1279 WRITE_ONCE(pernet->endp_subflow_max, 0); 1280 1280 WRITE_ONCE(pernet->endp_laminar_max, 0); 1281 + WRITE_ONCE(pernet->endp_fullmesh_max, 0); 1281 1282 pernet->endpoints = 0; 1282 1283 } 1283 1284
+2 -1
net/mptcp/protocol.c
··· 3302 3302 goto cleanup; 3303 3303 } 3304 3304 3305 - if (mptcp_data_avail(msk) || timeout < 0) { 3305 + if (mptcp_data_avail(msk) || timeout < 0 || 3306 + (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime)) { 3306 3307 /* If the msk has read data, or the caller explicitly ask it, 3307 3308 * do the MPTCP equivalent of TCP reset, aka MPTCP fastclose 3308 3309 */
+6 -6
net/mptcp/sockopt.c
··· 159 159 lock_sock(sk); 160 160 mptcp_for_each_subflow(msk, subflow) { 161 161 struct sock *ssk = mptcp_subflow_tcp_sock(subflow); 162 - bool slow = lock_sock_fast(ssk); 163 162 164 - sock_set_timestamp(sk, optname, !!val); 165 - unlock_sock_fast(ssk, slow); 163 + lock_sock(ssk); 164 + sock_set_timestamp(ssk, optname, !!val); 165 + release_sock(ssk); 166 166 } 167 167 168 168 release_sock(sk); ··· 235 235 236 236 mptcp_for_each_subflow(msk, subflow) { 237 237 struct sock *ssk = mptcp_subflow_tcp_sock(subflow); 238 - bool slow = lock_sock_fast(ssk); 239 238 240 - sock_set_timestamping(sk, optname, timestamping); 241 - unlock_sock_fast(ssk, slow); 239 + lock_sock(ssk); 240 + sock_set_timestamping(ssk, optname, timestamping); 241 + release_sock(ssk); 242 242 } 243 243 244 244 release_sock(sk);
+7 -3
net/netfilter/nf_conntrack_proto_sctp.c
··· 466 466 if (!ih) 467 467 goto out_unlock; 468 468 469 - if (ct->proto.sctp.init[dir] && ct->proto.sctp.init[!dir]) 470 - ct->proto.sctp.init[!dir] = 0; 471 - ct->proto.sctp.init[dir] = 1; 469 + /* Do not record INIT matching peer vtag (stale or retransmitted INIT). */ 470 + if (old_state == SCTP_CONNTRACK_NONE || 471 + ct->proto.sctp.vtag[!dir] != ih->init_tag) { 472 + if (ct->proto.sctp.init[dir] && ct->proto.sctp.init[!dir]) 473 + ct->proto.sctp.init[!dir] = 0; 474 + ct->proto.sctp.init[dir] = 1; 475 + } 472 476 473 477 pr_debug("Setting vtag %x for dir %d\n", ih->init_tag, !dir); 474 478 ct->proto.sctp.vtag[!dir] = ih->init_tag;
+118 -34
net/netfilter/nf_conntrack_sip.c
··· 181 181 return 1; 182 182 } 183 183 184 + /* Parse optional port number after IP address. 185 + * Returns false on malformed input, true otherwise. 186 + * If port is non-NULL, stores parsed port in network byte order. 187 + * If no port is present, sets *port to default SIP port. 188 + */ 189 + static bool sip_parse_port(const char *dptr, const char **endp, 190 + const char *limit, __be16 *port) 191 + { 192 + unsigned int p = 0; 193 + int len = 0; 194 + 195 + if (dptr >= limit) 196 + return false; 197 + 198 + if (*dptr != ':') { 199 + if (port) 200 + *port = htons(SIP_PORT); 201 + if (endp) 202 + *endp = dptr; 203 + return true; 204 + } 205 + 206 + dptr++; /* skip ':' */ 207 + 208 + while (dptr < limit && isdigit(*dptr)) { 209 + p = p * 10 + (*dptr - '0'); 210 + dptr++; 211 + len++; 212 + if (len > 5) /* max "65535" */ 213 + return false; 214 + } 215 + 216 + if (len == 0) 217 + return false; 218 + 219 + /* reached limit while parsing port */ 220 + if (dptr >= limit) 221 + return false; 222 + 223 + if (p < 1024 || p > 65535) 224 + return false; 225 + 226 + if (port) 227 + *port = htons(p); 228 + 229 + if (endp) 230 + *endp = dptr; 231 + 232 + return true; 233 + } 234 + 184 235 /* skip ip address. returns its length. */ 185 236 static int epaddr_len(const struct nf_conn *ct, const char *dptr, 186 237 const char *limit, int *shift) ··· 244 193 return 0; 245 194 } 246 195 247 - /* Port number */ 248 - if (*dptr == ':') { 249 - dptr++; 250 - dptr += digits_len(ct, dptr, limit, shift); 251 - } 196 + if (!sip_parse_port(dptr, &dptr, limit, NULL)) 197 + return 0; 252 198 return dptr - aux; 253 199 } 254 200 ··· 276 228 return epaddr_len(ct, dptr, limit, shift); 277 229 } 278 230 231 + /* simple_strtoul stops after first non-number character. 232 + * But as we're not dealing with c-strings, we can't rely on 233 + * hitting \r,\n,\0 etc. before moving past end of buffer. 234 + * 235 + * This is a variant of simple_strtoul, but doesn't require 236 + * a c-string. 237 + * 238 + * If value exceeds UINT_MAX, 0 is returned. 239 + */ 240 + static unsigned int sip_strtouint(const char *cp, unsigned int len, char **endp) 241 + { 242 + const unsigned int max = sizeof("4294967295"); 243 + unsigned int olen = len; 244 + const char *s = cp; 245 + u64 result = 0; 246 + 247 + if (len > max) 248 + len = max; 249 + 250 + while (olen > 0 && isdigit(*s)) { 251 + unsigned int value; 252 + 253 + if (len == 0) 254 + goto err; 255 + 256 + value = *s - '0'; 257 + result = result * 10 + value; 258 + 259 + if (result > UINT_MAX) 260 + goto err; 261 + s++; 262 + len--; 263 + olen--; 264 + } 265 + 266 + if (endp) 267 + *endp = (char *)s; 268 + 269 + return result; 270 + err: 271 + if (endp) 272 + *endp = (char *)cp; 273 + return 0; 274 + } 275 + 279 276 /* Parse a SIP request line of the form: 280 277 * 281 278 * Request-Line = Method SP Request-URI SP SIP-Version CRLF ··· 334 241 { 335 242 const char *start = dptr, *limit = dptr + datalen, *end; 336 243 unsigned int mlen; 337 - unsigned int p; 338 244 int shift = 0; 339 245 340 246 /* Skip method and following whitespace */ ··· 359 267 360 268 if (!sip_parse_addr(ct, dptr, &end, addr, limit, true)) 361 269 return -1; 362 - if (end < limit && *end == ':') { 363 - end++; 364 - p = simple_strtoul(end, (char **)&end, 10); 365 - if (p < 1024 || p > 65535) 366 - return -1; 367 - *port = htons(p); 368 - } else 369 - *port = htons(SIP_PORT); 270 + if (!sip_parse_port(end, &end, limit, port)) 271 + return -1; 370 272 371 273 if (end == dptr) 372 274 return 0; ··· 595 509 union nf_inet_addr *addr, __be16 *port) 596 510 { 597 511 const char *c, *limit = dptr + datalen; 598 - unsigned int p; 599 512 int ret; 600 513 601 514 ret = ct_sip_walk_headers(ct, dptr, dataoff ? *dataoff : 0, datalen, ··· 605 520 606 521 if (!sip_parse_addr(ct, dptr + *matchoff, &c, addr, limit, true)) 607 522 return -1; 608 - if (*c == ':') { 609 - c++; 610 - p = simple_strtoul(c, (char **)&c, 10); 611 - if (p < 1024 || p > 65535) 612 - return -1; 613 - *port = htons(p); 614 - } else 615 - *port = htons(SIP_PORT); 523 + if (!sip_parse_port(c, &c, limit, port)) 524 + return -1; 616 525 617 526 if (dataoff) 618 527 *dataoff = c - dptr; ··· 688 609 return 0; 689 610 690 611 start += strlen(name); 691 - *val = simple_strtoul(start, &end, 0); 612 + *val = sip_strtouint(start, limit - start, (char **)&end); 692 613 if (start == end) 693 614 return -1; 694 615 if (matchoff && matchlen) { ··· 1143 1064 1144 1065 mediaoff = sdpoff; 1145 1066 for (i = 0; i < ARRAY_SIZE(sdp_media_types); ) { 1067 + char *end; 1068 + 1146 1069 if (ct_sip_get_sdp_header(ct, *dptr, mediaoff, *datalen, 1147 1070 SDP_HDR_MEDIA, SDP_HDR_UNSPEC, 1148 1071 &mediaoff, &medialen) <= 0) ··· 1160 1079 mediaoff += t->len; 1161 1080 medialen -= t->len; 1162 1081 1163 - port = simple_strtoul(*dptr + mediaoff, NULL, 10); 1164 - if (port == 0) 1082 + port = sip_strtouint(*dptr + mediaoff, *datalen - mediaoff, (char **)&end); 1083 + if (port == 0 || *dptr + mediaoff == end) 1165 1084 continue; 1166 1085 if (port < 1024 || port > 65535) { 1167 1086 nf_ct_helper_log(skb, ct, "wrong port %u", port); ··· 1335 1254 */ 1336 1255 if (ct_sip_get_header(ct, *dptr, 0, *datalen, SIP_HDR_EXPIRES, 1337 1256 &matchoff, &matchlen) > 0) 1338 - expires = simple_strtoul(*dptr + matchoff, NULL, 10); 1257 + expires = sip_strtouint(*dptr + matchoff, *datalen - matchoff, NULL); 1339 1258 1340 1259 ret = ct_sip_parse_header_uri(ct, *dptr, NULL, *datalen, 1341 1260 SIP_HDR_CONTACT, NULL, ··· 1439 1358 1440 1359 if (ct_sip_get_header(ct, *dptr, 0, *datalen, SIP_HDR_EXPIRES, 1441 1360 &matchoff, &matchlen) > 0) 1442 - expires = simple_strtoul(*dptr + matchoff, NULL, 10); 1361 + expires = sip_strtouint(*dptr + matchoff, *datalen - matchoff, NULL); 1443 1362 1444 1363 while (1) { 1445 1364 unsigned int c_expires = expires; ··· 1499 1418 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 1500 1419 unsigned int matchoff, matchlen, matchend; 1501 1420 unsigned int code, cseq, i; 1421 + char *end; 1502 1422 1503 1423 if (*datalen < strlen("SIP/2.0 200")) 1504 1424 return NF_ACCEPT; 1505 - code = simple_strtoul(*dptr + strlen("SIP/2.0 "), NULL, 10); 1425 + code = sip_strtouint(*dptr + strlen("SIP/2.0 "), 1426 + *datalen - strlen("SIP/2.0 "), NULL); 1506 1427 if (!code) { 1507 1428 nf_ct_helper_log(skb, ct, "cannot get code"); 1508 1429 return NF_DROP; ··· 1515 1432 nf_ct_helper_log(skb, ct, "cannot parse cseq"); 1516 1433 return NF_DROP; 1517 1434 } 1518 - cseq = simple_strtoul(*dptr + matchoff, NULL, 10); 1519 - if (!cseq && *(*dptr + matchoff) != '0') { 1435 + cseq = sip_strtouint(*dptr + matchoff, *datalen - matchoff, (char **)&end); 1436 + if (*dptr + matchoff == end) { 1520 1437 nf_ct_helper_log(skb, ct, "cannot get cseq"); 1521 1438 return NF_DROP; 1522 1439 } ··· 1565 1482 1566 1483 for (i = 0; i < ARRAY_SIZE(sip_handlers); i++) { 1567 1484 const struct sip_handler *handler; 1485 + char *end; 1568 1486 1569 1487 handler = &sip_handlers[i]; 1570 1488 if (handler->request == NULL) ··· 1582 1498 nf_ct_helper_log(skb, ct, "cannot parse cseq"); 1583 1499 return NF_DROP; 1584 1500 } 1585 - cseq = simple_strtoul(*dptr + matchoff, NULL, 10); 1586 - if (!cseq && *(*dptr + matchoff) != '0') { 1501 + cseq = sip_strtouint(*dptr + matchoff, *datalen - matchoff, (char **)&end); 1502 + if (*dptr + matchoff == end) { 1587 1503 nf_ct_helper_log(skb, ct, "cannot get cseq"); 1588 1504 return NF_DROP; 1589 1505 } ··· 1659 1575 &matchoff, &matchlen) <= 0) 1660 1576 break; 1661 1577 1662 - clen = simple_strtoul(dptr + matchoff, (char **)&end, 10); 1578 + clen = sip_strtouint(dptr + matchoff, datalen - matchoff, (char **)&end); 1663 1579 if (dptr + matchoff == end) 1664 1580 break; 1665 1581
+1
net/netfilter/nf_nat_sip.c
··· 246 246 if (ct_sip_parse_numerical_param(ct, *dptr, matchend, *datalen, 247 247 "rport=", &poff, &plen, 248 248 &n) > 0 && 249 + n >= 1024 && n <= 65535 && 249 250 htons(n) == ct->tuplehash[dir].tuple.dst.u.udp.port && 250 251 htons(n) != ct->tuplehash[!dir].tuple.src.u.udp.port) { 251 252 __be16 p = ct->tuplehash[!dir].tuple.src.u.udp.port;
+225 -89
net/netfilter/nf_tables_api.c
··· 374 374 call_rcu(&hook->rcu, __nft_netdev_hook_free_rcu); 375 375 } 376 376 377 + static void nft_netdev_hook_unlink_free_rcu(struct nft_hook *hook) 378 + { 379 + list_del_rcu(&hook->list); 380 + nft_netdev_hook_free_rcu(hook); 381 + } 382 + 383 + static void nft_trans_hook_destroy(struct nft_trans_hook *trans_hook) 384 + { 385 + list_del(&trans_hook->list); 386 + kfree(trans_hook); 387 + } 388 + 389 + static void nft_netdev_unregister_trans_hook(struct net *net, 390 + const struct nft_table *table, 391 + struct list_head *hook_list) 392 + { 393 + struct nft_trans_hook *trans_hook, *next; 394 + struct nf_hook_ops *ops; 395 + struct nft_hook *hook; 396 + 397 + list_for_each_entry_safe(trans_hook, next, hook_list, list) { 398 + hook = trans_hook->hook; 399 + 400 + if (!(table->flags & NFT_TABLE_F_DORMANT)) { 401 + list_for_each_entry(ops, &hook->ops_list, list) 402 + nf_unregister_net_hook(net, ops); 403 + } 404 + nft_netdev_hook_unlink_free_rcu(hook); 405 + nft_trans_hook_destroy(trans_hook); 406 + } 407 + } 408 + 377 409 static void nft_netdev_unregister_hooks(struct net *net, 378 410 struct list_head *hook_list, 379 411 bool release_netdev) ··· 416 384 list_for_each_entry_safe(hook, next, hook_list, list) { 417 385 list_for_each_entry(ops, &hook->ops_list, list) 418 386 nf_unregister_net_hook(net, ops); 419 - if (release_netdev) { 420 - list_del(&hook->list); 421 - nft_netdev_hook_free_rcu(hook); 422 - } 387 + if (release_netdev) 388 + nft_netdev_hook_unlink_free_rcu(hook); 423 389 } 424 390 } 425 391 ··· 1972 1942 return nla_put_string(skb, attr, hook->ifname); 1973 1943 } 1974 1944 1945 + struct nft_hook_dump_ctx { 1946 + struct nft_hook *first; 1947 + int n; 1948 + }; 1949 + 1950 + static int nft_dump_basechain_hook_one(struct sk_buff *skb, 1951 + struct nft_hook *hook, 1952 + struct nft_hook_dump_ctx *dump_ctx) 1953 + { 1954 + if (!dump_ctx->first) 1955 + dump_ctx->first = hook; 1956 + 1957 + if (nft_nla_put_hook_dev(skb, hook)) 1958 + return -1; 1959 + 1960 + dump_ctx->n++; 1961 + 1962 + return 0; 1963 + } 1964 + 1965 + static int nft_dump_basechain_hook_list(struct sk_buff *skb, 1966 + const struct net *net, 1967 + const struct list_head *hook_list, 1968 + struct nft_hook_dump_ctx *dump_ctx) 1969 + { 1970 + struct nft_hook *hook; 1971 + int err; 1972 + 1973 + list_for_each_entry_rcu(hook, hook_list, list, 1974 + lockdep_commit_lock_is_held(net)) { 1975 + err = nft_dump_basechain_hook_one(skb, hook, dump_ctx); 1976 + if (err < 0) 1977 + return err; 1978 + } 1979 + 1980 + return 0; 1981 + } 1982 + 1983 + static int nft_dump_basechain_trans_hook_list(struct sk_buff *skb, 1984 + const struct list_head *trans_hook_list, 1985 + struct nft_hook_dump_ctx *dump_ctx) 1986 + { 1987 + struct nft_trans_hook *trans_hook; 1988 + int err; 1989 + 1990 + list_for_each_entry(trans_hook, trans_hook_list, list) { 1991 + err = nft_dump_basechain_hook_one(skb, trans_hook->hook, dump_ctx); 1992 + if (err < 0) 1993 + return err; 1994 + } 1995 + 1996 + return 0; 1997 + } 1998 + 1975 1999 static int nft_dump_basechain_hook(struct sk_buff *skb, 1976 2000 const struct net *net, int family, 1977 2001 const struct nft_base_chain *basechain, 1978 - const struct list_head *hook_list) 2002 + const struct list_head *hook_list, 2003 + const struct list_head *trans_hook_list) 1979 2004 { 1980 2005 const struct nf_hook_ops *ops = &basechain->ops; 1981 - struct nft_hook *hook, *first = NULL; 2006 + struct nft_hook_dump_ctx dump_hook_ctx = {}; 1982 2007 struct nlattr *nest, *nest_devs; 1983 - int n = 0; 1984 2008 1985 2009 nest = nla_nest_start_noflag(skb, NFTA_CHAIN_HOOK); 1986 2010 if (nest == NULL) ··· 2049 1965 if (!nest_devs) 2050 1966 goto nla_put_failure; 2051 1967 2052 - if (!hook_list) 1968 + if (!hook_list && !trans_hook_list) 2053 1969 hook_list = &basechain->hook_list; 2054 1970 2055 - list_for_each_entry_rcu(hook, hook_list, list, 2056 - lockdep_commit_lock_is_held(net)) { 2057 - if (!first) 2058 - first = hook; 2059 - 2060 - if (nft_nla_put_hook_dev(skb, hook)) 2061 - goto nla_put_failure; 2062 - n++; 1971 + if (hook_list && 1972 + nft_dump_basechain_hook_list(skb, net, hook_list, &dump_hook_ctx)) { 1973 + goto nla_put_failure; 1974 + } else if (trans_hook_list && 1975 + nft_dump_basechain_trans_hook_list(skb, trans_hook_list, 1976 + &dump_hook_ctx)) { 1977 + goto nla_put_failure; 2063 1978 } 1979 + 2064 1980 nla_nest_end(skb, nest_devs); 2065 1981 2066 - if (n == 1 && 2067 - !hook_is_prefix(first) && 2068 - nla_put_string(skb, NFTA_HOOK_DEV, first->ifname)) 1982 + if (dump_hook_ctx.n == 1 && 1983 + !hook_is_prefix(dump_hook_ctx.first) && 1984 + nla_put_string(skb, NFTA_HOOK_DEV, dump_hook_ctx.first->ifname)) 2069 1985 goto nla_put_failure; 2070 1986 } 2071 1987 nla_nest_end(skb, nest); ··· 2079 1995 u32 portid, u32 seq, int event, u32 flags, 2080 1996 int family, const struct nft_table *table, 2081 1997 const struct nft_chain *chain, 2082 - const struct list_head *hook_list) 1998 + const struct list_head *hook_list, 1999 + const struct list_head *trans_hook_list) 2083 2000 { 2084 2001 struct nlmsghdr *nlh; 2085 2002 ··· 2096 2011 NFTA_CHAIN_PAD)) 2097 2012 goto nla_put_failure; 2098 2013 2099 - if (!hook_list && 2014 + if (!hook_list && !trans_hook_list && 2100 2015 (event == NFT_MSG_DELCHAIN || 2101 2016 event == NFT_MSG_DESTROYCHAIN)) { 2102 2017 nlmsg_end(skb, nlh); ··· 2107 2022 const struct nft_base_chain *basechain = nft_base_chain(chain); 2108 2023 struct nft_stats __percpu *stats; 2109 2024 2110 - if (nft_dump_basechain_hook(skb, net, family, basechain, hook_list)) 2025 + if (nft_dump_basechain_hook(skb, net, family, basechain, 2026 + hook_list, trans_hook_list)) 2111 2027 goto nla_put_failure; 2112 2028 2113 2029 if (nla_put_be32(skb, NFTA_CHAIN_POLICY, ··· 2144 2058 } 2145 2059 2146 2060 static void nf_tables_chain_notify(const struct nft_ctx *ctx, int event, 2147 - const struct list_head *hook_list) 2061 + const struct list_head *hook_list, 2062 + const struct list_head *trans_hook_list) 2148 2063 { 2149 2064 struct nftables_pernet *nft_net; 2150 2065 struct sk_buff *skb; ··· 2165 2078 2166 2079 err = nf_tables_fill_chain_info(skb, ctx->net, ctx->portid, ctx->seq, 2167 2080 event, flags, ctx->family, ctx->table, 2168 - ctx->chain, hook_list); 2081 + ctx->chain, hook_list, trans_hook_list); 2169 2082 if (err < 0) { 2170 2083 kfree_skb(skb); 2171 2084 goto err; ··· 2211 2124 NFT_MSG_NEWCHAIN, 2212 2125 NLM_F_MULTI, 2213 2126 table->family, table, 2214 - chain, NULL) < 0) 2127 + chain, NULL, NULL) < 0) 2215 2128 goto done; 2216 2129 2217 2130 nl_dump_check_consistent(cb, nlmsg_hdr(skb)); ··· 2265 2178 2266 2179 err = nf_tables_fill_chain_info(skb2, net, NETLINK_CB(skb).portid, 2267 2180 info->nlh->nlmsg_seq, NFT_MSG_NEWCHAIN, 2268 - 0, family, table, chain, NULL); 2181 + 0, family, table, chain, NULL, NULL); 2269 2182 if (err < 0) 2270 2183 goto err_fill_chain_info; 2271 2184 ··· 2358 2271 2359 2272 if (nft_base_chain_netdev(table->family, basechain->ops.hooknum)) { 2360 2273 list_for_each_entry_safe(hook, next, 2361 - &basechain->hook_list, list) { 2362 - list_del_rcu(&hook->list); 2363 - nft_netdev_hook_free_rcu(hook); 2364 - } 2274 + &basechain->hook_list, list) 2275 + nft_netdev_hook_unlink_free_rcu(hook); 2365 2276 } 2366 2277 module_put(basechain->type->owner); 2367 2278 if (rcu_access_pointer(basechain->stats)) { ··· 2428 2343 2429 2344 list_for_each_entry(hook, hook_list, list) { 2430 2345 if (!strncmp(hook->ifname, this->ifname, 2431 - min(hook->ifnamelen, this->ifnamelen))) 2346 + min(hook->ifnamelen, this->ifnamelen))) { 2347 + if (hook->flags & NFT_HOOK_REMOVE) 2348 + continue; 2349 + 2432 2350 return hook; 2351 + } 2433 2352 } 2434 2353 2435 2354 return NULL; ··· 3063 2974 list_for_each_entry(ops, &h->ops_list, list) 3064 2975 nf_unregister_net_hook(ctx->net, ops); 3065 2976 } 2977 + /* hook.list is on stack, no need for list_del_rcu() */ 3066 2978 list_del(&h->list); 3067 2979 nft_netdev_hook_free_rcu(h); 3068 2980 } ··· 3192 3102 return nf_tables_addchain(&ctx, family, policy, flags, extack); 3193 3103 } 3194 3104 3105 + static int nft_trans_delhook(struct nft_hook *hook, 3106 + struct list_head *del_list) 3107 + { 3108 + struct nft_trans_hook *trans_hook; 3109 + 3110 + trans_hook = kmalloc_obj(*trans_hook, GFP_KERNEL); 3111 + if (!trans_hook) 3112 + return -ENOMEM; 3113 + 3114 + trans_hook->hook = hook; 3115 + list_add_tail(&trans_hook->list, del_list); 3116 + hook->flags |= NFT_HOOK_REMOVE; 3117 + 3118 + return 0; 3119 + } 3120 + 3121 + static void nft_trans_delhook_abort(struct list_head *del_list) 3122 + { 3123 + struct nft_trans_hook *trans_hook, *next; 3124 + 3125 + list_for_each_entry_safe(trans_hook, next, del_list, list) { 3126 + trans_hook->hook->flags &= ~NFT_HOOK_REMOVE; 3127 + nft_trans_hook_destroy(trans_hook); 3128 + } 3129 + } 3130 + 3195 3131 static int nft_delchain_hook(struct nft_ctx *ctx, 3196 3132 struct nft_base_chain *basechain, 3197 3133 struct netlink_ext_ack *extack) ··· 3244 3128 err = -ENOENT; 3245 3129 goto err_chain_del_hook; 3246 3130 } 3247 - list_move(&hook->list, &chain_del_list); 3131 + if (nft_trans_delhook(hook, &chain_del_list) < 0) { 3132 + err = -ENOMEM; 3133 + goto err_chain_del_hook; 3134 + } 3248 3135 } 3249 3136 3250 3137 trans = nft_trans_alloc_chain(ctx, NFT_MSG_DELCHAIN); ··· 3267 3148 return 0; 3268 3149 3269 3150 err_chain_del_hook: 3270 - list_splice(&chain_del_list, &basechain->hook_list); 3151 + nft_trans_delhook_abort(&chain_del_list); 3271 3152 nft_chain_release_hook(&chain_hook); 3272 3153 3273 3154 return err; ··· 8971 8852 list_for_each_entry_safe(hook, next, hook_list, list) { 8972 8853 list_for_each_entry(ops, &hook->ops_list, list) 8973 8854 nft_unregister_flowtable_ops(net, flowtable, ops); 8974 - if (release_netdev) { 8975 - list_del(&hook->list); 8976 - nft_netdev_hook_free_rcu(hook); 8977 - } 8855 + if (release_netdev) 8856 + nft_netdev_hook_unlink_free_rcu(hook); 8978 8857 } 8979 8858 } 8980 8859 ··· 9043 8926 9044 8927 nft_unregister_flowtable_ops(net, flowtable, ops); 9045 8928 } 9046 - list_del_rcu(&hook->list); 9047 - nft_netdev_hook_free_rcu(hook); 8929 + nft_netdev_hook_unlink_free_rcu(hook); 9048 8930 } 9049 8931 9050 8932 return err; ··· 9053 8937 { 9054 8938 struct nft_hook *hook, *next; 9055 8939 9056 - list_for_each_entry_safe(hook, next, hook_list, list) { 9057 - list_del_rcu(&hook->list); 9058 - nft_netdev_hook_free_rcu(hook); 8940 + list_for_each_entry_safe(hook, next, hook_list, list) 8941 + nft_netdev_hook_unlink_free_rcu(hook); 8942 + } 8943 + 8944 + static void nft_flowtable_unregister_trans_hook(struct net *net, 8945 + struct nft_flowtable *flowtable, 8946 + struct list_head *hook_list) 8947 + { 8948 + struct nft_trans_hook *trans_hook, *next; 8949 + struct nf_hook_ops *ops; 8950 + struct nft_hook *hook; 8951 + 8952 + list_for_each_entry_safe(trans_hook, next, hook_list, list) { 8953 + hook = trans_hook->hook; 8954 + list_for_each_entry(ops, &hook->ops_list, list) 8955 + nft_unregister_flowtable_ops(net, flowtable, ops); 8956 + 8957 + nft_netdev_hook_unlink_free_rcu(hook); 8958 + nft_trans_hook_destroy(trans_hook); 9059 8959 } 9060 8960 } 9061 8961 ··· 9160 9028 nft_unregister_flowtable_ops(ctx->net, 9161 9029 flowtable, ops); 9162 9030 } 9163 - list_del_rcu(&hook->list); 9164 - nft_netdev_hook_free_rcu(hook); 9031 + nft_netdev_hook_unlink_free_rcu(hook); 9165 9032 } 9166 9033 9167 9034 return err; ··· 9333 9202 err = -ENOENT; 9334 9203 goto err_flowtable_del_hook; 9335 9204 } 9336 - list_move(&hook->list, &flowtable_del_list); 9205 + if (nft_trans_delhook(hook, &flowtable_del_list) < 0) { 9206 + err = -ENOMEM; 9207 + goto err_flowtable_del_hook; 9208 + } 9337 9209 } 9338 9210 9339 9211 trans = nft_trans_alloc(ctx, NFT_MSG_DELFLOWTABLE, ··· 9357 9223 return 0; 9358 9224 9359 9225 err_flowtable_del_hook: 9360 - list_splice(&flowtable_del_list, &flowtable->hook_list); 9226 + nft_trans_delhook_abort(&flowtable_del_list); 9361 9227 nft_flowtable_hook_release(&flowtable_hook); 9362 9228 9363 9229 return err; ··· 9422 9288 u32 portid, u32 seq, int event, 9423 9289 u32 flags, int family, 9424 9290 struct nft_flowtable *flowtable, 9425 - struct list_head *hook_list) 9291 + struct list_head *hook_list, 9292 + struct list_head *trans_hook_list) 9426 9293 { 9294 + struct nft_trans_hook *trans_hook; 9427 9295 struct nlattr *nest, *nest_devs; 9428 9296 struct nft_hook *hook; 9429 9297 struct nlmsghdr *nlh; ··· 9442 9306 NFTA_FLOWTABLE_PAD)) 9443 9307 goto nla_put_failure; 9444 9308 9445 - if (!hook_list && 9309 + if (!hook_list && !trans_hook_list && 9446 9310 (event == NFT_MSG_DELFLOWTABLE || 9447 9311 event == NFT_MSG_DESTROYFLOWTABLE)) { 9448 9312 nlmsg_end(skb, nlh); ··· 9464 9328 if (!nest_devs) 9465 9329 goto nla_put_failure; 9466 9330 9467 - if (!hook_list) 9331 + if (!hook_list && !trans_hook_list) 9468 9332 hook_list = &flowtable->hook_list; 9469 9333 9470 - list_for_each_entry_rcu(hook, hook_list, list, 9471 - lockdep_commit_lock_is_held(net)) { 9472 - if (nft_nla_put_hook_dev(skb, hook)) 9473 - goto nla_put_failure; 9334 + if (hook_list) { 9335 + list_for_each_entry_rcu(hook, hook_list, list, 9336 + lockdep_commit_lock_is_held(net)) { 9337 + if (nft_nla_put_hook_dev(skb, hook)) 9338 + goto nla_put_failure; 9339 + } 9340 + } else if (trans_hook_list) { 9341 + list_for_each_entry(trans_hook, trans_hook_list, list) { 9342 + if (nft_nla_put_hook_dev(skb, trans_hook->hook)) 9343 + goto nla_put_failure; 9344 + } 9474 9345 } 9475 9346 nla_nest_end(skb, nest_devs); 9476 9347 nla_nest_end(skb, nest); ··· 9531 9388 NFT_MSG_NEWFLOWTABLE, 9532 9389 NLM_F_MULTI | NLM_F_APPEND, 9533 9390 table->family, 9534 - flowtable, NULL) < 0) 9391 + flowtable, NULL, NULL) < 0) 9535 9392 goto done; 9536 9393 9537 9394 nl_dump_check_consistent(cb, nlmsg_hdr(skb)); ··· 9631 9488 err = nf_tables_fill_flowtable_info(skb2, net, NETLINK_CB(skb).portid, 9632 9489 info->nlh->nlmsg_seq, 9633 9490 NFT_MSG_NEWFLOWTABLE, 0, family, 9634 - flowtable, NULL); 9491 + flowtable, NULL, NULL); 9635 9492 if (err < 0) 9636 9493 goto err_fill_flowtable_info; 9637 9494 ··· 9644 9501 9645 9502 static void nf_tables_flowtable_notify(struct nft_ctx *ctx, 9646 9503 struct nft_flowtable *flowtable, 9647 - struct list_head *hook_list, int event) 9504 + struct list_head *hook_list, 9505 + struct list_head *trans_hook_list, 9506 + int event) 9648 9507 { 9649 9508 struct nftables_pernet *nft_net = nft_pernet(ctx->net); 9650 9509 struct sk_buff *skb; ··· 9666 9521 9667 9522 err = nf_tables_fill_flowtable_info(skb, ctx->net, ctx->portid, 9668 9523 ctx->seq, event, flags, 9669 - ctx->family, flowtable, hook_list); 9524 + ctx->family, flowtable, 9525 + hook_list, trans_hook_list); 9670 9526 if (err < 0) { 9671 9527 kfree_skb(skb); 9672 9528 goto err; ··· 9681 9535 9682 9536 static void nf_tables_flowtable_destroy(struct nft_flowtable *flowtable) 9683 9537 { 9684 - struct nft_hook *hook, *next; 9685 - 9686 9538 flowtable->data.type->free(&flowtable->data); 9687 - list_for_each_entry_safe(hook, next, &flowtable->hook_list, list) { 9688 - list_del_rcu(&hook->list); 9689 - nft_netdev_hook_free_rcu(hook); 9690 - } 9539 + nft_hooks_destroy(&flowtable->hook_list); 9691 9540 kfree(flowtable->name); 9692 9541 module_put(flowtable->data.type->owner); 9693 9542 kfree(flowtable); ··· 10201 10060 break; 10202 10061 case NFT_MSG_DELCHAIN: 10203 10062 case NFT_MSG_DESTROYCHAIN: 10204 - if (nft_trans_chain_update(trans)) 10205 - nft_hooks_destroy(&nft_trans_chain_hooks(trans)); 10206 - else 10063 + if (!nft_trans_chain_update(trans)) 10207 10064 nf_tables_chain_destroy(nft_trans_chain(trans)); 10208 10065 break; 10209 10066 case NFT_MSG_DELRULE: ··· 10222 10083 break; 10223 10084 case NFT_MSG_DELFLOWTABLE: 10224 10085 case NFT_MSG_DESTROYFLOWTABLE: 10225 - if (nft_trans_flowtable_update(trans)) 10226 - nft_hooks_destroy(&nft_trans_flowtable_hooks(trans)); 10227 - else 10086 + if (!nft_trans_flowtable_update(trans)) 10228 10087 nf_tables_flowtable_destroy(nft_trans_flowtable(trans)); 10229 10088 break; 10230 10089 } ··· 10982 10845 if (nft_trans_chain_update(trans)) { 10983 10846 nft_chain_commit_update(nft_trans_container_chain(trans)); 10984 10847 nf_tables_chain_notify(&ctx, NFT_MSG_NEWCHAIN, 10985 - &nft_trans_chain_hooks(trans)); 10986 - list_splice(&nft_trans_chain_hooks(trans), 10987 - &nft_trans_basechain(trans)->hook_list); 10848 + &nft_trans_chain_hooks(trans), NULL); 10849 + list_splice_rcu(&nft_trans_chain_hooks(trans), 10850 + &nft_trans_basechain(trans)->hook_list); 10988 10851 /* trans destroyed after rcu grace period */ 10989 10852 } else { 10990 10853 nft_chain_commit_drop_policy(nft_trans_container_chain(trans)); 10991 10854 nft_clear(net, nft_trans_chain(trans)); 10992 - nf_tables_chain_notify(&ctx, NFT_MSG_NEWCHAIN, NULL); 10855 + nf_tables_chain_notify(&ctx, NFT_MSG_NEWCHAIN, NULL, NULL); 10993 10856 nft_trans_destroy(trans); 10994 10857 } 10995 10858 break; 10996 10859 case NFT_MSG_DELCHAIN: 10997 10860 case NFT_MSG_DESTROYCHAIN: 10998 10861 if (nft_trans_chain_update(trans)) { 10999 - nf_tables_chain_notify(&ctx, NFT_MSG_DELCHAIN, 10862 + nf_tables_chain_notify(&ctx, NFT_MSG_DELCHAIN, NULL, 11000 10863 &nft_trans_chain_hooks(trans)); 11001 - if (!(table->flags & NFT_TABLE_F_DORMANT)) { 11002 - nft_netdev_unregister_hooks(net, 11003 - &nft_trans_chain_hooks(trans), 11004 - true); 11005 - } 10864 + nft_netdev_unregister_trans_hook(net, table, 10865 + &nft_trans_chain_hooks(trans)); 11006 10866 } else { 11007 10867 nft_chain_del(nft_trans_chain(trans)); 11008 10868 nf_tables_chain_notify(&ctx, NFT_MSG_DELCHAIN, 11009 - NULL); 10869 + NULL, NULL); 11010 10870 nf_tables_unregister_hook(ctx.net, ctx.table, 11011 10871 nft_trans_chain(trans)); 11012 10872 } ··· 11109 10975 nf_tables_flowtable_notify(&ctx, 11110 10976 nft_trans_flowtable(trans), 11111 10977 &nft_trans_flowtable_hooks(trans), 10978 + NULL, 11112 10979 NFT_MSG_NEWFLOWTABLE); 11113 - list_splice(&nft_trans_flowtable_hooks(trans), 11114 - &nft_trans_flowtable(trans)->hook_list); 10980 + list_splice_rcu(&nft_trans_flowtable_hooks(trans), 10981 + &nft_trans_flowtable(trans)->hook_list); 11115 10982 } else { 11116 10983 nft_clear(net, nft_trans_flowtable(trans)); 11117 10984 nf_tables_flowtable_notify(&ctx, 11118 10985 nft_trans_flowtable(trans), 10986 + NULL, 11119 10987 NULL, 11120 10988 NFT_MSG_NEWFLOWTABLE); 11121 10989 } ··· 11128 10992 if (nft_trans_flowtable_update(trans)) { 11129 10993 nf_tables_flowtable_notify(&ctx, 11130 10994 nft_trans_flowtable(trans), 10995 + NULL, 11131 10996 &nft_trans_flowtable_hooks(trans), 11132 10997 trans->msg_type); 11133 - nft_unregister_flowtable_net_hooks(net, 11134 - nft_trans_flowtable(trans), 11135 - &nft_trans_flowtable_hooks(trans)); 10998 + nft_flowtable_unregister_trans_hook(net, 10999 + nft_trans_flowtable(trans), 11000 + &nft_trans_flowtable_hooks(trans)); 11136 11001 } else { 11137 11002 list_del_rcu(&nft_trans_flowtable(trans)->list); 11138 11003 nf_tables_flowtable_notify(&ctx, 11139 11004 nft_trans_flowtable(trans), 11005 + NULL, 11140 11006 NULL, 11141 11007 trans->msg_type); 11142 11008 nft_unregister_flowtable_net_hooks(net, ··· 11303 11165 case NFT_MSG_DELCHAIN: 11304 11166 case NFT_MSG_DESTROYCHAIN: 11305 11167 if (nft_trans_chain_update(trans)) { 11306 - list_splice(&nft_trans_chain_hooks(trans), 11307 - &nft_trans_basechain(trans)->hook_list); 11168 + nft_trans_delhook_abort(&nft_trans_chain_hooks(trans)); 11308 11169 } else { 11309 11170 nft_use_inc_restore(&table->use); 11310 11171 nft_clear(trans->net, nft_trans_chain(trans)); ··· 11417 11280 case NFT_MSG_DELFLOWTABLE: 11418 11281 case NFT_MSG_DESTROYFLOWTABLE: 11419 11282 if (nft_trans_flowtable_update(trans)) { 11420 - list_splice(&nft_trans_flowtable_hooks(trans), 11421 - &nft_trans_flowtable(trans)->hook_list); 11283 + nft_trans_delhook_abort(&nft_trans_flowtable_hooks(trans)); 11422 11284 } else { 11423 11285 nft_use_inc_restore(&table->use); 11424 11286 nft_clear(trans->net, nft_trans_flowtable(trans));
+2 -1
net/netfilter/nft_bitwise.c
··· 196 196 if (err < 0) 197 197 return err; 198 198 199 - if (priv->data.data[0] >= BITS_PER_TYPE(u32)) { 199 + if (!priv->data.data[0] || 200 + priv->data.data[0] >= BITS_PER_TYPE(u32)) { 200 201 nft_data_release(&priv->data, desc.type); 201 202 return -EINVAL; 202 203 }
+1 -1
net/netfilter/xt_policy.c
··· 63 63 return 0; 64 64 65 65 for (i = sp->len - 1; i >= 0; i--) { 66 - pos = strict ? i - sp->len + 1 : 0; 66 + pos = strict ? sp->len - i - 1 : 0; 67 67 if (pos >= info->len) 68 68 return 0; 69 69 e = &info->pol[pos];
+8 -2
net/phonet/socket.c
··· 208 208 sa.spn_family = AF_PHONET; 209 209 err = pn_socket_bind(sock, (struct sockaddr_unsized *)&sa, 210 210 sizeof(struct sockaddr_pn)); 211 - if (err != -EINVAL) 211 + /* 212 + * pn_socket_bind() also returns -EINVAL when sk_state != TCP_CLOSE 213 + * without a prior bind, so -EINVAL alone is not sufficient to infer 214 + * that the socket was already bound. Only treat it as "already 215 + * bound" when the port is non-zero; otherwise propagate the error 216 + * instead of crashing the kernel. 217 + */ 218 + if (err != -EINVAL || unlikely(!pn_port(pn_sk(sock->sk)->sobject))) 212 219 return err; 213 - BUG_ON(!pn_port(pn_sk(sock->sk)->sobject)); 214 220 return 0; /* socket was already bound */ 215 221 } 216 222
+2 -2
net/psp/psp-nl-gen.c
··· 76 76 .post_doit = psp_device_unlock, 77 77 .policy = psp_dev_set_nl_policy, 78 78 .maxattr = PSP_A_DEV_PSP_VERSIONS_ENA, 79 - .flags = GENL_CMD_CAP_DO, 79 + .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO, 80 80 }, 81 81 { 82 82 .cmd = PSP_CMD_KEY_ROTATE, ··· 85 85 .post_doit = psp_device_unlock, 86 86 .policy = psp_key_rotate_nl_policy, 87 87 .maxattr = PSP_A_DEV_ID, 88 - .flags = GENL_CMD_CAP_DO, 88 + .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO, 89 89 }, 90 90 { 91 91 .cmd = PSP_CMD_RX_ASSOC,
+7 -3
net/psp/psp_nl.c
··· 305 305 306 306 psd = psp_dev_get_for_sock(socket->sk); 307 307 if (psd) { 308 - err = psp_dev_check_access(psd, genl_info_net(info)); 309 - if (err) { 308 + /* Extra care needed here, psp_dev_get_for_sock() only gives 309 + * us access to struct psp_dev's memory, which is quite weak. 310 + */ 311 + mutex_lock(&psd->lock); 312 + if (!psp_dev_is_registered(psd) || 313 + psp_dev_check_access(psd, genl_info_net(info))) { 314 + mutex_unlock(&psd->lock); 310 315 psp_dev_put(psd); 311 316 psd = NULL; 312 317 } ··· 324 319 325 320 id = info->attrs[PSP_A_ASSOC_DEV_ID]; 326 321 if (psd) { 327 - mutex_lock(&psd->lock); 328 322 if (id && psd->id != nla_get_u32(id)) { 329 323 mutex_unlock(&psd->lock); 330 324 NL_SET_ERR_MSG_ATTR(info->extack, id,
+113 -104
net/sched/sch_cake.c
··· 813 813 i++, k = (k + 1) % CAKE_SET_WAYS) { 814 814 if (q->tags[outer_hash + k] == flow_hash) { 815 815 if (i) 816 - q->way_hits++; 816 + WRITE_ONCE(q->way_hits, q->way_hits + 1); 817 817 818 818 if (!q->flows[outer_hash + k].set) { 819 819 /* need to increment host refcnts */ ··· 831 831 for (i = 0; i < CAKE_SET_WAYS; 832 832 i++, k = (k + 1) % CAKE_SET_WAYS) { 833 833 if (!q->flows[outer_hash + k].set) { 834 - q->way_misses++; 834 + WRITE_ONCE(q->way_misses, q->way_misses + 1); 835 835 allocate_src = cake_dsrc(flow_mode); 836 836 allocate_dst = cake_ddst(flow_mode); 837 837 goto found; ··· 841 841 /* With no empty queues, default to the original 842 842 * queue, accept the collision, update the host tags. 843 843 */ 844 - q->way_collisions++; 844 + WRITE_ONCE(q->way_collisions, q->way_collisions + 1); 845 845 allocate_src = cake_dsrc(flow_mode); 846 846 allocate_dst = cake_ddst(flow_mode); 847 847 ··· 1379 1379 len -= off; 1380 1380 1381 1381 if (qd->max_netlen < len) 1382 - qd->max_netlen = len; 1382 + WRITE_ONCE(qd->max_netlen, len); 1383 1383 if (qd->min_netlen > len) 1384 - qd->min_netlen = len; 1384 + WRITE_ONCE(qd->min_netlen, len); 1385 1385 1386 1386 len += q->rate_overhead; 1387 1387 ··· 1401 1401 } 1402 1402 1403 1403 if (qd->max_adjlen < len) 1404 - qd->max_adjlen = len; 1404 + WRITE_ONCE(qd->max_adjlen, len); 1405 1405 if (qd->min_adjlen > len) 1406 - qd->min_adjlen = len; 1406 + WRITE_ONCE(qd->min_adjlen, len); 1407 1407 1408 1408 return len; 1409 1409 } ··· 1416 1416 u16 segs = qdisc_pkt_segs(skb); 1417 1417 u32 len = qdisc_pkt_len(skb); 1418 1418 1419 - q->avg_netoff = cake_ewma(q->avg_netoff, off << 16, 8); 1419 + WRITE_ONCE(q->avg_netoff, cake_ewma(q->avg_netoff, off << 16, 8)); 1420 1420 1421 1421 if (segs == 1) 1422 1422 return cake_calc_overhead(q, len, off); ··· 1590 1590 } 1591 1591 1592 1592 if (cobalt_queue_full(&flow->cvars, &b->cparams, now)) 1593 - b->unresponsive_flow_count++; 1593 + WRITE_ONCE(b->unresponsive_flow_count, 1594 + b->unresponsive_flow_count + 1); 1594 1595 1595 1596 len = qdisc_pkt_len(skb); 1596 1597 q->buffer_used -= skb->truesize; 1597 1598 b->backlogs[idx] -= len; 1598 - b->tin_backlog -= len; 1599 + WRITE_ONCE(b->tin_backlog, b->tin_backlog - len); 1599 1600 sch->qstats.backlog -= len; 1600 1601 1601 1602 flow->dropped++; 1602 - b->tin_dropped++; 1603 + WRITE_ONCE(b->tin_dropped, b->tin_dropped + 1); 1603 1604 1604 1605 if (q->config->rate_flags & CAKE_FLAG_INGRESS) 1605 1606 cake_advance_shaper(q, b, skb, now, true); ··· 1796 1795 } 1797 1796 1798 1797 if (unlikely(len > b->max_skblen)) 1799 - b->max_skblen = len; 1798 + WRITE_ONCE(b->max_skblen, len); 1800 1799 1801 1800 if (qdisc_pkt_segs(skb) > 1 && q->config->rate_flags & CAKE_FLAG_SPLIT_GSO) { 1802 1801 struct sk_buff *segs, *nskb; ··· 1820 1819 numsegs++; 1821 1820 slen += segs->len; 1822 1821 q->buffer_used += segs->truesize; 1823 - b->packets++; 1822 + WRITE_ONCE(b->packets, b->packets + 1); 1824 1823 } 1825 1824 1826 1825 /* stats */ 1827 - b->bytes += slen; 1828 1826 b->backlogs[idx] += slen; 1829 - b->tin_backlog += slen; 1830 1827 sch->qstats.backlog += slen; 1831 1828 q->avg_window_bytes += slen; 1829 + WRITE_ONCE(b->bytes, b->bytes + slen); 1830 + WRITE_ONCE(b->tin_backlog, b->tin_backlog + slen); 1832 1831 1833 1832 qdisc_tree_reduce_backlog(sch, 1-numsegs, len-slen); 1834 1833 consume_skb(skb); ··· 1844 1843 ack = cake_ack_filter(q, flow); 1845 1844 1846 1845 if (ack) { 1847 - b->ack_drops++; 1846 + WRITE_ONCE(b->ack_drops, b->ack_drops + 1); 1848 1847 sch->qstats.drops++; 1849 1848 ack_pkt_len = qdisc_pkt_len(ack); 1850 - b->bytes += ack_pkt_len; 1849 + WRITE_ONCE(b->bytes, b->bytes + ack_pkt_len); 1851 1850 q->buffer_used += skb->truesize - ack->truesize; 1852 1851 if (q->config->rate_flags & CAKE_FLAG_INGRESS) 1853 1852 cake_advance_shaper(q, b, ack, now, true); ··· 1860 1859 } 1861 1860 1862 1861 /* stats */ 1863 - b->packets++; 1864 - b->bytes += len - ack_pkt_len; 1862 + WRITE_ONCE(b->packets, b->packets + 1); 1865 1863 b->backlogs[idx] += len - ack_pkt_len; 1866 - b->tin_backlog += len - ack_pkt_len; 1867 1864 sch->qstats.backlog += len - ack_pkt_len; 1868 1865 q->avg_window_bytes += len - ack_pkt_len; 1866 + WRITE_ONCE(b->bytes, b->bytes + len - ack_pkt_len); 1867 + WRITE_ONCE(b->tin_backlog, b->tin_backlog + len - ack_pkt_len); 1869 1868 } 1870 1869 1871 1870 if (q->overflow_timeout) ··· 1895 1894 u64 b = q->avg_window_bytes * (u64)NSEC_PER_SEC; 1896 1895 1897 1896 b = div64_u64(b, window_interval); 1898 - q->avg_peak_bandwidth = 1899 - cake_ewma(q->avg_peak_bandwidth, b, 1900 - b > q->avg_peak_bandwidth ? 2 : 8); 1897 + WRITE_ONCE(q->avg_peak_bandwidth, 1898 + cake_ewma(q->avg_peak_bandwidth, b, 1899 + b > q->avg_peak_bandwidth ? 2 : 8)); 1901 1900 q->avg_window_bytes = 0; 1902 1901 q->avg_window_begin = now; 1903 1902 ··· 1918 1917 if (!flow->set) { 1919 1918 list_add_tail(&flow->flowchain, &b->new_flows); 1920 1919 } else { 1921 - b->decaying_flow_count--; 1920 + WRITE_ONCE(b->decaying_flow_count, b->decaying_flow_count - 1); 1922 1921 list_move_tail(&flow->flowchain, &b->new_flows); 1923 1922 } 1924 1923 flow->set = CAKE_SET_SPARSE; 1925 - b->sparse_flow_count++; 1924 + WRITE_ONCE(b->sparse_flow_count, b->sparse_flow_count + 1); 1926 1925 1927 1926 flow->deficit = cake_get_flow_quantum(b, flow, q->config->flow_mode); 1928 1927 } else if (flow->set == CAKE_SET_SPARSE_WAIT) { ··· 1930 1929 * in the bulk rotation. 1931 1930 */ 1932 1931 flow->set = CAKE_SET_BULK; 1933 - b->sparse_flow_count--; 1934 - b->bulk_flow_count++; 1932 + WRITE_ONCE(b->sparse_flow_count, b->sparse_flow_count - 1); 1933 + WRITE_ONCE(b->bulk_flow_count, b->bulk_flow_count + 1); 1935 1934 1936 1935 cake_inc_srchost_bulk_flow_count(b, flow, q->config->flow_mode); 1937 1936 cake_inc_dsthost_bulk_flow_count(b, flow, q->config->flow_mode); 1938 1937 } 1939 1938 1940 1939 if (q->buffer_used > q->buffer_max_used) 1941 - q->buffer_max_used = q->buffer_used; 1940 + WRITE_ONCE(q->buffer_max_used, q->buffer_used); 1942 1941 1943 1942 if (q->buffer_used <= q->buffer_limit) 1944 1943 return NET_XMIT_SUCCESS; ··· 1978 1977 skb = dequeue_head(flow); 1979 1978 len = qdisc_pkt_len(skb); 1980 1979 b->backlogs[q->cur_flow] -= len; 1981 - b->tin_backlog -= len; 1980 + WRITE_ONCE(b->tin_backlog, b->tin_backlog - len); 1982 1981 sch->qstats.backlog -= len; 1983 1982 q->buffer_used -= skb->truesize; 1984 1983 sch->q.qlen--; ··· 2043 2042 2044 2043 cake_configure_rates(sch, new_rate, true); 2045 2044 q->last_checked_active = now; 2046 - q->active_queues = num_active_qs; 2045 + WRITE_ONCE(q->active_queues, num_active_qs); 2047 2046 } 2048 2047 2049 2048 begin: ··· 2150 2149 */ 2151 2150 if (flow->set == CAKE_SET_SPARSE) { 2152 2151 if (flow->head) { 2153 - b->sparse_flow_count--; 2154 - b->bulk_flow_count++; 2152 + WRITE_ONCE(b->sparse_flow_count, b->sparse_flow_count - 1); 2153 + WRITE_ONCE(b->bulk_flow_count, b->bulk_flow_count + 1); 2155 2154 2156 2155 cake_inc_srchost_bulk_flow_count(b, flow, q->config->flow_mode); 2157 2156 cake_inc_dsthost_bulk_flow_count(b, flow, q->config->flow_mode); ··· 2178 2177 if (!skb) { 2179 2178 /* this queue was actually empty */ 2180 2179 if (cobalt_queue_empty(&flow->cvars, &b->cparams, now)) 2181 - b->unresponsive_flow_count--; 2180 + WRITE_ONCE(b->unresponsive_flow_count, 2181 + b->unresponsive_flow_count - 1); 2182 2182 2183 2183 if (flow->cvars.p_drop || flow->cvars.count || 2184 2184 ktime_before(now, flow->cvars.drop_next)) { ··· 2189 2187 list_move_tail(&flow->flowchain, 2190 2188 &b->decaying_flows); 2191 2189 if (flow->set == CAKE_SET_BULK) { 2192 - b->bulk_flow_count--; 2190 + WRITE_ONCE(b->bulk_flow_count, b->bulk_flow_count - 1); 2193 2191 2194 2192 cake_dec_srchost_bulk_flow_count(b, flow, q->config->flow_mode); 2195 2193 cake_dec_dsthost_bulk_flow_count(b, flow, q->config->flow_mode); 2196 2194 2197 - b->decaying_flow_count++; 2195 + WRITE_ONCE(b->decaying_flow_count, b->decaying_flow_count + 1); 2198 2196 } else if (flow->set == CAKE_SET_SPARSE || 2199 2197 flow->set == CAKE_SET_SPARSE_WAIT) { 2200 - b->sparse_flow_count--; 2201 - b->decaying_flow_count++; 2198 + WRITE_ONCE(b->sparse_flow_count, b->sparse_flow_count - 1); 2199 + WRITE_ONCE(b->decaying_flow_count, b->decaying_flow_count + 1); 2202 2200 } 2203 2201 flow->set = CAKE_SET_DECAYING; 2204 2202 } else { 2205 2203 /* remove empty queue from the flowchain */ 2206 2204 list_del_init(&flow->flowchain); 2207 2205 if (flow->set == CAKE_SET_SPARSE || 2208 - flow->set == CAKE_SET_SPARSE_WAIT) 2209 - b->sparse_flow_count--; 2210 - else if (flow->set == CAKE_SET_BULK) { 2211 - b->bulk_flow_count--; 2206 + flow->set == CAKE_SET_SPARSE_WAIT) { 2207 + WRITE_ONCE(b->sparse_flow_count, b->sparse_flow_count - 1); 2208 + } else if (flow->set == CAKE_SET_BULK) { 2209 + WRITE_ONCE(b->bulk_flow_count, b->bulk_flow_count - 1); 2212 2210 2213 2211 cake_dec_srchost_bulk_flow_count(b, flow, q->config->flow_mode); 2214 2212 cake_dec_dsthost_bulk_flow_count(b, flow, q->config->flow_mode); 2215 - } else 2216 - b->decaying_flow_count--; 2217 - 2213 + } else { 2214 + WRITE_ONCE(b->decaying_flow_count, b->decaying_flow_count - 1); 2215 + } 2218 2216 flow->set = CAKE_SET_NONE; 2219 2217 } 2220 2218 goto begin; ··· 2236 2234 b->tin_deficit -= len; 2237 2235 } 2238 2236 flow->dropped++; 2239 - b->tin_dropped++; 2237 + WRITE_ONCE(b->tin_dropped, b->tin_dropped + 1); 2240 2238 qdisc_tree_reduce_backlog(sch, 1, qdisc_pkt_len(skb)); 2241 2239 qdisc_qstats_drop(sch); 2242 2240 qdisc_dequeue_drop(sch, skb, reason); ··· 2244 2242 goto retry; 2245 2243 } 2246 2244 2247 - b->tin_ecn_mark += !!flow->cvars.ecn_marked; 2245 + WRITE_ONCE(b->tin_ecn_mark, b->tin_ecn_mark + !!flow->cvars.ecn_marked); 2248 2246 qdisc_bstats_update(sch, skb); 2249 2247 WRITE_ONCE(q->last_active, now); 2250 2248 2251 2249 /* collect delay stats */ 2252 2250 delay = ktime_to_ns(ktime_sub(now, cobalt_get_enqueue_time(skb))); 2253 - b->avge_delay = cake_ewma(b->avge_delay, delay, 8); 2254 - b->peak_delay = cake_ewma(b->peak_delay, delay, 2255 - delay > b->peak_delay ? 2 : 8); 2256 - b->base_delay = cake_ewma(b->base_delay, delay, 2257 - delay < b->base_delay ? 2 : 8); 2251 + WRITE_ONCE(b->avge_delay, cake_ewma(b->avge_delay, delay, 8)); 2252 + WRITE_ONCE(b->peak_delay, 2253 + cake_ewma(b->peak_delay, delay, 2254 + delay > b->peak_delay ? 2 : 8)); 2255 + WRITE_ONCE(b->base_delay, 2256 + cake_ewma(b->base_delay, delay, 2257 + delay < b->base_delay ? 2 : 8)); 2258 2258 2259 2259 len = cake_advance_shaper(q, b, skb, now, false); 2260 2260 flow->deficit -= len; ··· 2333 2329 u8 rate_shft = 0; 2334 2330 u64 rate_ns = 0; 2335 2331 2336 - b->flow_quantum = 1514; 2337 2332 if (rate) { 2338 - b->flow_quantum = max(min(rate >> 12, 1514ULL), 300ULL); 2333 + WRITE_ONCE(b->flow_quantum, 2334 + max(min(rate >> 12, 1514ULL), 300ULL)); 2339 2335 rate_shft = 34; 2340 2336 rate_ns = ((u64)NSEC_PER_SEC) << rate_shft; 2341 2337 rate_ns = div64_u64(rate_ns, max(MIN_RATE, rate)); ··· 2343 2339 rate_ns >>= 1; 2344 2340 rate_shft--; 2345 2341 } 2346 - } /* else unlimited, ie. zero delay */ 2347 - 2348 - b->tin_rate_bps = rate; 2342 + } else { 2343 + /* else unlimited, ie. zero delay */ 2344 + WRITE_ONCE(b->flow_quantum, 1514); 2345 + } 2346 + WRITE_ONCE(b->tin_rate_bps, rate); 2349 2347 b->tin_rate_ns = rate_ns; 2350 2348 b->tin_rate_shft = rate_shft; 2351 2349 ··· 2356 2350 2357 2351 byte_target_ns = (byte_target * rate_ns) >> rate_shft; 2358 2352 2359 - b->cparams.target = max((byte_target_ns * 3) / 2, target_ns); 2360 - b->cparams.interval = max(rtt_est_ns + 2361 - b->cparams.target - target_ns, 2362 - b->cparams.target * 2); 2353 + WRITE_ONCE(b->cparams.target, 2354 + max((byte_target_ns * 3) / 2, target_ns)); 2355 + WRITE_ONCE(b->cparams.interval, 2356 + max(rtt_est_ns + b->cparams.target - target_ns, 2357 + b->cparams.target * 2)); 2363 2358 b->cparams.mtu_time = byte_target_ns; 2364 2359 b->cparams.p_inc = 1 << 24; /* 1/256 */ 2365 2360 b->cparams.p_dec = 1 << 20; /* 1/4096 */ ··· 2618 2611 { 2619 2612 struct cake_sched_data *qd = qdisc_priv(sch); 2620 2613 struct cake_sched_config *q = qd->config; 2614 + u32 buffer_limit; 2621 2615 2622 2616 cake_configure_rates(sch, qd->config->rate_bps, false); 2623 2617 2624 2618 if (q->buffer_config_limit) { 2625 - qd->buffer_limit = q->buffer_config_limit; 2619 + buffer_limit = q->buffer_config_limit; 2626 2620 } else if (q->rate_bps) { 2627 2621 u64 t = q->rate_bps * q->interval; 2628 2622 2629 2623 do_div(t, USEC_PER_SEC / 4); 2630 - qd->buffer_limit = max_t(u32, t, 4U << 20); 2624 + buffer_limit = max_t(u32, t, 4U << 20); 2631 2625 } else { 2632 - qd->buffer_limit = ~0; 2626 + buffer_limit = ~0; 2633 2627 } 2634 2628 2635 2629 sch->flags &= ~TCQ_F_CAN_BYPASS; 2636 2630 2637 - qd->buffer_limit = min(qd->buffer_limit, 2638 - max(sch->limit * psched_mtu(qdisc_dev(sch)), 2639 - q->buffer_config_limit)); 2631 + WRITE_ONCE(qd->buffer_limit, 2632 + min(buffer_limit, 2633 + max(sch->limit * psched_mtu(qdisc_dev(sch)), 2634 + q->buffer_config_limit))); 2640 2635 } 2641 2636 2642 2637 static int cake_config_change(struct cake_sched_config *q, struct nlattr *opt, ··· 2783 2774 return ret; 2784 2775 2785 2776 if (overhead_changed) { 2786 - qd->max_netlen = 0; 2787 - qd->max_adjlen = 0; 2788 - qd->min_netlen = ~0; 2789 - qd->min_adjlen = ~0; 2777 + WRITE_ONCE(qd->max_netlen, 0); 2778 + WRITE_ONCE(qd->max_adjlen, 0); 2779 + WRITE_ONCE(qd->min_netlen, ~0); 2780 + WRITE_ONCE(qd->min_adjlen, ~0); 2790 2781 } 2791 2782 2792 2783 if (qd->tins) { ··· 3004 2995 goto nla_put_failure; \ 3005 2996 } while (0) 3006 2997 3007 - PUT_STAT_U64(CAPACITY_ESTIMATE64, q->avg_peak_bandwidth); 3008 - PUT_STAT_U32(MEMORY_LIMIT, q->buffer_limit); 3009 - PUT_STAT_U32(MEMORY_USED, q->buffer_max_used); 3010 - PUT_STAT_U32(AVG_NETOFF, ((q->avg_netoff + 0x8000) >> 16)); 3011 - PUT_STAT_U32(MAX_NETLEN, q->max_netlen); 3012 - PUT_STAT_U32(MAX_ADJLEN, q->max_adjlen); 3013 - PUT_STAT_U32(MIN_NETLEN, q->min_netlen); 3014 - PUT_STAT_U32(MIN_ADJLEN, q->min_adjlen); 3015 - PUT_STAT_U32(ACTIVE_QUEUES, q->active_queues); 2998 + PUT_STAT_U64(CAPACITY_ESTIMATE64, READ_ONCE(q->avg_peak_bandwidth)); 2999 + PUT_STAT_U32(MEMORY_LIMIT, READ_ONCE(q->buffer_limit)); 3000 + PUT_STAT_U32(MEMORY_USED, READ_ONCE(q->buffer_max_used)); 3001 + PUT_STAT_U32(AVG_NETOFF, ((READ_ONCE(q->avg_netoff) + 0x8000) >> 16)); 3002 + PUT_STAT_U32(MAX_NETLEN, READ_ONCE(q->max_netlen)); 3003 + PUT_STAT_U32(MAX_ADJLEN, READ_ONCE(q->max_adjlen)); 3004 + PUT_STAT_U32(MIN_NETLEN, READ_ONCE(q->min_netlen)); 3005 + PUT_STAT_U32(MIN_ADJLEN, READ_ONCE(q->min_adjlen)); 3006 + PUT_STAT_U32(ACTIVE_QUEUES, READ_ONCE(q->active_queues)); 3016 3007 3017 3008 #undef PUT_STAT_U32 3018 3009 #undef PUT_STAT_U64 ··· 3038 3029 if (!ts) 3039 3030 goto nla_put_failure; 3040 3031 3041 - PUT_TSTAT_U64(THRESHOLD_RATE64, b->tin_rate_bps); 3042 - PUT_TSTAT_U64(SENT_BYTES64, b->bytes); 3043 - PUT_TSTAT_U32(BACKLOG_BYTES, b->tin_backlog); 3032 + PUT_TSTAT_U64(THRESHOLD_RATE64, READ_ONCE(b->tin_rate_bps)); 3033 + PUT_TSTAT_U64(SENT_BYTES64, READ_ONCE(b->bytes)); 3034 + PUT_TSTAT_U32(BACKLOG_BYTES, READ_ONCE(b->tin_backlog)); 3044 3035 3045 3036 PUT_TSTAT_U32(TARGET_US, 3046 - ktime_to_us(ns_to_ktime(b->cparams.target))); 3037 + ktime_to_us(ns_to_ktime(READ_ONCE(b->cparams.target)))); 3047 3038 PUT_TSTAT_U32(INTERVAL_US, 3048 - ktime_to_us(ns_to_ktime(b->cparams.interval))); 3039 + ktime_to_us(ns_to_ktime(READ_ONCE(b->cparams.interval)))); 3049 3040 3050 - PUT_TSTAT_U32(SENT_PACKETS, b->packets); 3051 - PUT_TSTAT_U32(DROPPED_PACKETS, b->tin_dropped); 3052 - PUT_TSTAT_U32(ECN_MARKED_PACKETS, b->tin_ecn_mark); 3053 - PUT_TSTAT_U32(ACKS_DROPPED_PACKETS, b->ack_drops); 3041 + PUT_TSTAT_U32(SENT_PACKETS, READ_ONCE(b->packets)); 3042 + PUT_TSTAT_U32(DROPPED_PACKETS, READ_ONCE(b->tin_dropped)); 3043 + PUT_TSTAT_U32(ECN_MARKED_PACKETS, READ_ONCE(b->tin_ecn_mark)); 3044 + PUT_TSTAT_U32(ACKS_DROPPED_PACKETS, READ_ONCE(b->ack_drops)); 3054 3045 3055 3046 PUT_TSTAT_U32(PEAK_DELAY_US, 3056 - ktime_to_us(ns_to_ktime(b->peak_delay))); 3047 + ktime_to_us(ns_to_ktime(READ_ONCE(b->peak_delay)))); 3057 3048 PUT_TSTAT_U32(AVG_DELAY_US, 3058 - ktime_to_us(ns_to_ktime(b->avge_delay))); 3049 + ktime_to_us(ns_to_ktime(READ_ONCE(b->avge_delay)))); 3059 3050 PUT_TSTAT_U32(BASE_DELAY_US, 3060 - ktime_to_us(ns_to_ktime(b->base_delay))); 3051 + ktime_to_us(ns_to_ktime(READ_ONCE(b->base_delay)))); 3061 3052 3062 - PUT_TSTAT_U32(WAY_INDIRECT_HITS, b->way_hits); 3063 - PUT_TSTAT_U32(WAY_MISSES, b->way_misses); 3064 - PUT_TSTAT_U32(WAY_COLLISIONS, b->way_collisions); 3053 + PUT_TSTAT_U32(WAY_INDIRECT_HITS, READ_ONCE(b->way_hits)); 3054 + PUT_TSTAT_U32(WAY_MISSES, READ_ONCE(b->way_misses)); 3055 + PUT_TSTAT_U32(WAY_COLLISIONS, READ_ONCE(b->way_collisions)); 3065 3056 3066 - PUT_TSTAT_U32(SPARSE_FLOWS, b->sparse_flow_count + 3067 - b->decaying_flow_count); 3068 - PUT_TSTAT_U32(BULK_FLOWS, b->bulk_flow_count); 3069 - PUT_TSTAT_U32(UNRESPONSIVE_FLOWS, b->unresponsive_flow_count); 3070 - PUT_TSTAT_U32(MAX_SKBLEN, b->max_skblen); 3057 + PUT_TSTAT_U32(SPARSE_FLOWS, READ_ONCE(b->sparse_flow_count) + 3058 + READ_ONCE(b->decaying_flow_count)); 3059 + PUT_TSTAT_U32(BULK_FLOWS, READ_ONCE(b->bulk_flow_count)); 3060 + PUT_TSTAT_U32(UNRESPONSIVE_FLOWS, READ_ONCE(b->unresponsive_flow_count)); 3061 + PUT_TSTAT_U32(MAX_SKBLEN, READ_ONCE(b->max_skblen)); 3071 3062 3072 - PUT_TSTAT_U32(FLOW_QUANTUM, b->flow_quantum); 3063 + PUT_TSTAT_U32(FLOW_QUANTUM, READ_ONCE(b->flow_quantum)); 3073 3064 nla_nest_end(d->skb, ts); 3074 3065 } 3075 3066 ··· 3307 3298 struct cake_sched_data *qd = qdisc_priv(chld); 3308 3299 3309 3300 if (overhead_changed) { 3310 - qd->max_netlen = 0; 3311 - qd->max_adjlen = 0; 3312 - qd->min_netlen = ~0; 3313 - qd->min_adjlen = ~0; 3301 + WRITE_ONCE(qd->max_netlen, 0); 3302 + WRITE_ONCE(qd->max_adjlen, 0); 3303 + WRITE_ONCE(qd->min_netlen, ~0); 3304 + WRITE_ONCE(qd->min_adjlen, ~0); 3314 3305 } 3315 3306 3316 3307 if (qd->tins) {
+16 -10
net/sched/sch_choke.c
··· 229 229 230 230 /* Draw a packet at random from queue and compare flow */ 231 231 if (choke_match_random(q, skb, &idx)) { 232 - q->stats.matched++; 232 + WRITE_ONCE(q->stats.matched, q->stats.matched + 1); 233 233 choke_drop_by_idx(sch, idx, to_free); 234 234 goto congestion_drop; 235 235 } ··· 241 241 qdisc_qstats_overlimit(sch); 242 242 if (use_harddrop(q) || !use_ecn(q) || 243 243 !INET_ECN_set_ce(skb)) { 244 - q->stats.forced_drop++; 244 + WRITE_ONCE(q->stats.forced_drop, 245 + q->stats.forced_drop + 1); 245 246 goto congestion_drop; 246 247 } 247 248 248 - q->stats.forced_mark++; 249 + WRITE_ONCE(q->stats.forced_mark, 250 + q->stats.forced_mark + 1); 249 251 } else if (++q->vars.qcount) { 250 252 if (red_mark_probability(p, &q->vars, q->vars.qavg)) { 251 253 q->vars.qcount = 0; ··· 255 253 256 254 qdisc_qstats_overlimit(sch); 257 255 if (!use_ecn(q) || !INET_ECN_set_ce(skb)) { 258 - q->stats.prob_drop++; 256 + WRITE_ONCE(q->stats.prob_drop, 257 + q->stats.prob_drop + 1); 259 258 goto congestion_drop; 260 259 } 261 260 262 - q->stats.prob_mark++; 261 + WRITE_ONCE(q->stats.prob_mark, 262 + q->stats.prob_mark + 1); 263 263 } 264 264 } else 265 265 q->vars.qR = red_random(p); ··· 276 272 return NET_XMIT_SUCCESS; 277 273 } 278 274 279 - q->stats.pdrop++; 275 + WRITE_ONCE(q->stats.pdrop, q->stats.pdrop + 1); 280 276 return qdisc_drop(skb, sch, to_free); 281 277 282 278 congestion_drop: ··· 465 461 { 466 462 struct choke_sched_data *q = qdisc_priv(sch); 467 463 struct tc_choke_xstats st = { 468 - .early = q->stats.prob_drop + q->stats.forced_drop, 469 - .marked = q->stats.prob_mark + q->stats.forced_mark, 470 - .pdrop = q->stats.pdrop, 471 - .matched = q->stats.matched, 464 + .early = READ_ONCE(q->stats.prob_drop) + 465 + READ_ONCE(q->stats.forced_drop), 466 + .marked = READ_ONCE(q->stats.prob_mark) + 467 + READ_ONCE(q->stats.forced_mark), 468 + .pdrop = READ_ONCE(q->stats.pdrop), 469 + .matched = READ_ONCE(q->stats.matched), 472 470 }; 473 471 474 472 return gnet_stats_copy_app(d, &st, sizeof(st));
+10 -9
net/sched/sch_fq_pie.c
··· 509 509 static int fq_pie_dump_stats(struct Qdisc *sch, struct gnet_dump *d) 510 510 { 511 511 struct fq_pie_sched_data *q = qdisc_priv(sch); 512 - struct tc_fq_pie_xstats st = { 513 - .packets_in = q->stats.packets_in, 514 - .overlimit = q->stats.overlimit, 515 - .overmemory = q->overmemory, 516 - .dropped = q->stats.dropped, 517 - .ecn_mark = q->stats.ecn_mark, 518 - .new_flow_count = q->new_flow_count, 519 - .memory_usage = q->memory_usage, 520 - }; 512 + struct tc_fq_pie_xstats st = { 0 }; 521 513 struct list_head *pos; 522 514 523 515 sch_tree_lock(sch); 516 + 517 + st.packets_in = q->stats.packets_in; 518 + st.overlimit = q->stats.overlimit; 519 + st.overmemory = q->overmemory; 520 + st.dropped = q->stats.dropped; 521 + st.ecn_mark = q->stats.ecn_mark; 522 + st.new_flow_count = q->new_flow_count; 523 + st.memory_usage = q->memory_usage; 524 + 524 525 list_for_each(pos, &q->new_flows) 525 526 st.new_flows_len++; 526 527
+64 -12
net/sched/sch_netem.c
··· 227 227 if (rnd < clg->a4) { 228 228 clg->state = LOST_IN_GAP_PERIOD; 229 229 return true; 230 - } else if (clg->a4 < rnd && rnd < clg->a1 + clg->a4) { 230 + } else if (rnd < clg->a1 + clg->a4) { 231 231 clg->state = LOST_IN_BURST_PERIOD; 232 232 return true; 233 - } else if (clg->a1 + clg->a4 < rnd) { 233 + } else { 234 234 clg->state = TX_IN_GAP_PERIOD; 235 235 } 236 236 ··· 247 247 case LOST_IN_BURST_PERIOD: 248 248 if (rnd < clg->a3) 249 249 clg->state = TX_IN_BURST_PERIOD; 250 - else if (clg->a3 < rnd && rnd < clg->a2 + clg->a3) { 250 + else if (rnd < clg->a2 + clg->a3) { 251 251 clg->state = TX_IN_GAP_PERIOD; 252 - } else if (clg->a2 + clg->a3 < rnd) { 252 + } else { 253 253 clg->state = LOST_IN_BURST_PERIOD; 254 254 return true; 255 255 } ··· 524 524 1 << get_random_u32_below(8); 525 525 } 526 526 527 - if (unlikely(q->t_len >= sch->limit)) { 527 + if (unlikely(sch->q.qlen >= sch->limit)) { 528 528 /* re-link segs, so that qdisc_drop_all() frees them all */ 529 529 skb->next = segs; 530 530 qdisc_drop_all(skb, sch, to_free); ··· 659 659 660 660 if (!q->slot_dist) 661 661 next_delay = q->slot_config.min_delay + 662 - (get_random_u32() * 663 - (q->slot_config.max_delay - 664 - q->slot_config.min_delay) >> 32); 662 + mul_u64_u32_shr(q->slot_config.max_delay - q->slot_config.min_delay, 663 + get_random_u32(), 32); 665 664 else 666 665 next_delay = tabledist(q->slot_config.dist_delay, 667 666 (s32)(q->slot_config.dist_jitter), ··· 823 824 d->table[i] = data[i]; 824 825 825 826 *tbl = d; 827 + return 0; 828 + } 829 + 830 + static int validate_time(const struct nlattr *attr, const char *name, 831 + struct netlink_ext_ack *extack) 832 + { 833 + if (nla_get_s64(attr) < 0) { 834 + NL_SET_ERR_MSG_ATTR_FMT(extack, attr, "negative %s", name); 835 + return -EINVAL; 836 + } 837 + return 0; 838 + } 839 + 840 + static int validate_slot(const struct nlattr *attr, struct netlink_ext_ack *extack) 841 + { 842 + const struct tc_netem_slot *c = nla_data(attr); 843 + 844 + if (c->min_delay < 0 || c->max_delay < 0) { 845 + NL_SET_ERR_MSG_ATTR(extack, attr, "negative slot delay"); 846 + return -EINVAL; 847 + } 848 + if (c->min_delay > c->max_delay) { 849 + NL_SET_ERR_MSG_ATTR(extack, attr, "slot min delay greater than max delay"); 850 + return -EINVAL; 851 + } 852 + if (c->dist_delay < 0 || c->dist_jitter < 0) { 853 + NL_SET_ERR_MSG_ATTR(extack, attr, "negative dist delay"); 854 + return -EINVAL; 855 + } 856 + if (c->max_packets < 0 || c->max_bytes < 0) { 857 + NL_SET_ERR_MSG_ATTR(extack, attr, "negative slot limit"); 858 + return -EINVAL; 859 + } 826 860 return 0; 827 861 } 828 862 ··· 1072 1040 goto table_free; 1073 1041 } 1074 1042 1043 + if (tb[TCA_NETEM_SLOT]) { 1044 + ret = validate_slot(tb[TCA_NETEM_SLOT], extack); 1045 + if (ret) 1046 + goto table_free; 1047 + } 1048 + 1049 + if (tb[TCA_NETEM_LATENCY64]) { 1050 + ret = validate_time(tb[TCA_NETEM_LATENCY64], "latency", extack); 1051 + if (ret) 1052 + goto table_free; 1053 + } 1054 + 1055 + if (tb[TCA_NETEM_JITTER64]) { 1056 + ret = validate_time(tb[TCA_NETEM_JITTER64], "jitter", extack); 1057 + if (ret) 1058 + goto table_free; 1059 + } 1060 + 1075 1061 sch_tree_lock(sch); 1076 1062 /* backup q->clg and q->loss_model */ 1077 1063 old_clg = q->clg; ··· 1162 1112 /* capping jitter to the range acceptable by tabledist() */ 1163 1113 q->jitter = min_t(s64, abs(q->jitter), INT_MAX); 1164 1114 1165 - if (tb[TCA_NETEM_PRNG_SEED]) 1115 + if (tb[TCA_NETEM_PRNG_SEED]) { 1166 1116 q->prng.seed = nla_get_u64(tb[TCA_NETEM_PRNG_SEED]); 1167 - else 1168 - q->prng.seed = get_random_u64(); 1169 - prandom_seed_state(&q->prng.prng_state, q->prng.seed); 1117 + prandom_seed_state(&q->prng.prng_state, q->prng.seed); 1118 + } 1170 1119 1171 1120 unlock: 1172 1121 sch_tree_unlock(sch); ··· 1188 1139 return -EINVAL; 1189 1140 1190 1141 q->loss_model = CLG_RANDOM; 1142 + q->prng.seed = get_random_u64(); 1143 + prandom_seed_state(&q->prng.prng_state, q->prng.seed); 1144 + 1191 1145 ret = netem_change(sch, opt, extack); 1192 1146 if (ret) 1193 1147 pr_info("netem: change failed\n");
+8 -5
net/sched/sch_taprio.c
··· 634 634 queue = skb_get_queue_mapping(skb); 635 635 636 636 child = q->qdiscs[queue]; 637 - if (unlikely(!child)) 637 + if (unlikely(child == &noop_qdisc)) 638 638 return qdisc_drop(skb, sch, to_free); 639 639 640 640 if (taprio_skb_exceeds_queue_max_sdu(sch, skb)) { ··· 717 717 int len; 718 718 u8 tc; 719 719 720 - if (unlikely(!child)) 720 + if (unlikely(child == &noop_qdisc)) 721 721 return NULL; 722 722 723 723 if (TXTIME_ASSIST_IS_ENABLED(q->flags)) ··· 2184 2184 if (!dev_queue) 2185 2185 return -EINVAL; 2186 2186 2187 + if (!new) 2188 + new = &noop_qdisc; 2189 + 2187 2190 if (dev->flags & IFF_UP) 2188 2191 dev_deactivate(dev, false); 2189 2192 ··· 2200 2197 *old = q->qdiscs[cl - 1]; 2201 2198 if (FULL_OFFLOAD_IS_ENABLED(q->flags)) { 2202 2199 WARN_ON_ONCE(dev_graft_qdisc(dev_queue, new) != *old); 2203 - if (new) 2200 + if (new != &noop_qdisc) 2204 2201 qdisc_refcount_inc(new); 2205 - if (*old) 2202 + if (*old && *old != &noop_qdisc) 2206 2203 qdisc_put(*old); 2207 2204 } 2208 2205 2209 2206 q->qdiscs[cl - 1] = new; 2210 - if (new) 2207 + if (new != &noop_qdisc) 2211 2208 new->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT; 2212 2209 2213 2210 if (dev->flags & IFF_UP)
+6
net/sctp/sm_statefuns.c
··· 1556 1556 /* Tag the variable length parameters. */ 1557 1557 chunk->param_hdr.v = skb_pull(chunk->skb, sizeof(struct sctp_inithdr)); 1558 1558 1559 + if (asoc->state >= SCTP_STATE_ESTABLISHED) { 1560 + /* Discard INIT matching peer vtag after handshake completion (stale INIT). */ 1561 + if (ntohl(chunk->subh.init_hdr->init_tag) == asoc->peer.i.init_tag) 1562 + return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); 1563 + } 1564 + 1559 1565 /* Verify the INIT chunk before processing it. */ 1560 1566 err_chunk = NULL; 1561 1567 if (!sctp_verify_init(net, ep, asoc, chunk->chunk_hdr->type,
+1
net/tls/tls.h
··· 188 188 void tls_strp_dev_exit(void); 189 189 190 190 void tls_strp_done(struct tls_strparser *strp); 191 + void __tls_strp_done(struct tls_strparser *strp); 191 192 void tls_strp_stop(struct tls_strparser *strp); 192 193 int tls_strp_init(struct tls_strparser *strp, struct sock *sk); 193 194 void tls_strp_data_ready(struct tls_strparser *strp);
+6
net/tls/tls_strp.c
··· 624 624 WARN_ON(!strp->stopped); 625 625 626 626 cancel_work_sync(&strp->work); 627 + __tls_strp_done(strp); 628 + } 629 + 630 + /* For setup error paths where the strparser was initialized but never armed. */ 631 + void __tls_strp_done(struct tls_strparser *strp) 632 + { 627 633 tls_strp_anchor_free(strp); 628 634 } 629 635
+4
net/tls/tls_sw.c
··· 2624 2624 void tls_sw_free_resources_rx(struct sock *sk) 2625 2625 { 2626 2626 struct tls_context *tls_ctx = tls_get_ctx(sk); 2627 + struct tls_sw_context_rx *ctx; 2628 + 2629 + ctx = tls_sw_ctx_rx(tls_ctx); 2627 2630 2628 2631 tls_sw_release_resources_rx(sk); 2632 + __tls_strp_done(&ctx->strp); 2629 2633 tls_sw_free_ctx_rx(tls_ctx); 2630 2634 } 2631 2635
+2 -2
net/vmw_vsock/hyperv_transport.c
··· 375 375 } else { 376 376 sndbuf = max_t(int, sk->sk_sndbuf, RINGBUFFER_HVS_SND_SIZE); 377 377 sndbuf = min_t(int, sndbuf, RINGBUFFER_HVS_MAX_SIZE); 378 - sndbuf = ALIGN(sndbuf, HV_HYP_PAGE_SIZE); 378 + sndbuf = VMBUS_RING_SIZE(sndbuf); 379 379 rcvbuf = max_t(int, sk->sk_rcvbuf, RINGBUFFER_HVS_RCV_SIZE); 380 380 rcvbuf = min_t(int, rcvbuf, RINGBUFFER_HVS_MAX_SIZE); 381 - rcvbuf = ALIGN(rcvbuf, HV_HYP_PAGE_SIZE); 381 + rcvbuf = VMBUS_RING_SIZE(rcvbuf); 382 382 } 383 383 384 384 chan->max_pkt_size = HVS_MAX_PKT_SIZE;
+8 -2
tools/testing/selftests/drivers/net/README.rst
··· 211 211 212 212 Test files should be relatively self contained. The libraries should 213 213 only include very core or non-trivial code. 214 - It may be tempting to "factor out" the common code, but fight that urge. 215 - Library code increases the barrier of entry, and complexity in general. 214 + It may be tempting to "factor out" the common code to lib/py/, but fight that 215 + urge. Library code increases the barrier of entry, and complexity in general. 216 216 217 217 Avoid mixing test code and boilerplate 218 218 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ··· 289 289 @ksft_variants(_gro_variants()) 290 290 def test(cfg, mode, protocol): 291 291 pass 292 + 293 + Linters 294 + ~~~~~~~ 295 + 296 + We expect clean ``ruff check`` and ``pylint --disable=R``. 297 + The code should be clean, avoid disabling pylint warnings explicitly! 292 298 293 299 Running tests CI-style 294 300 ======================
+26
tools/testing/selftests/tc-testing/tc-tests/qdiscs/taprio.json
··· 302 302 "$TC qdisc del dev $ETH root", 303 303 "echo \"1\" > /sys/bus/netdevsim/del_device" 304 304 ] 305 + }, 306 + { 307 + "id": "c7e1", 308 + "name": "Class dump after graft and delete of explicit child qdisc", 309 + "category": [ 310 + "qdisc", 311 + "taprio" 312 + ], 313 + "plugins": { 314 + "requires": "nsPlugin" 315 + }, 316 + "setup": [ 317 + "echo \"1 1 8\" > /sys/bus/netdevsim/new_device", 318 + "$TC qdisc replace dev $ETH handle 8001: parent root taprio num_tc 8 map 0 1 2 3 4 5 6 7 queues 1@0 1@1 1@2 1@3 1@4 1@5 1@6 1@7 base-time 0 sched-entry S ff 20000000 clockid CLOCK_TAI", 319 + "$TC qdisc add dev $ETH parent 8001:1 handle 8002: pfifo", 320 + "$TC qdisc del dev $ETH parent 8001:1 handle 8002:" 321 + ], 322 + "cmdUnderTest": "$TC class show dev $ETH", 323 + "expExitCode": "0", 324 + "verifyCmd": "$TC class show dev $ETH", 325 + "matchPattern": "class taprio 8001:[0-9]+ root", 326 + "matchCount": "8", 327 + "teardown": [ 328 + "$TC qdisc del dev $ETH root", 329 + "echo \"1\" > /sys/bus/netdevsim/del_device" 330 + ] 305 331 } 306 332 ]