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 git://git.kernel.org/pub/scm/linux/kernel/git/davem/net

Pull networking fixes from David Miller:
"The iwlwifi firmware compat fix is in here as well as some other
stuff:

1) Fix request socket leak introduced by BPF deadlock fix, from Eric
Dumazet.

2) Fix VLAN handling with TXQs in mac80211, from Johannes Berg.

3) Missing __qdisc_drop conversions in prio and qfq schedulers, from
Gao Feng.

4) Use after free in netlink nlk groups handling, from Xin Long.

5) Handle MTU update properly in ipv6 gre tunnels, from Xin Long.

6) Fix leak of ipv6 fib tables on netns teardown, from Sabrina Dubroca
with follow-on fix from Eric Dumazet.

7) Need RCU and preemption disabled during generic XDP data patch,
from John Fastabend"

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (54 commits)
bpf: make error reporting in bpf_warn_invalid_xdp_action more clear
Revert "mdio_bus: Remove unneeded gpiod NULL check"
bpf: devmap, use cond_resched instead of cpu_relax
bpf: add support for sockmap detach programs
net: rcu lock and preempt disable missing around generic xdp
bpf: don't select potentially stale ri->map from buggy xdp progs
net: tulip: Constify tulip_tbl
net: ethernet: ti: netcp_core: no need in netif_napi_del
davicom: Display proper debug level up to 6
net: phy: sfp: rename dt properties to match the binding
dt-binding: net: sfp binding documentation
dt-bindings: add SFF vendor prefix
dt-bindings: net: don't confuse with generic PHY property
ip6_tunnel: fix setting hop_limit value for ipv6 tunnel
ip_tunnel: fix setting ttl and tos value in collect_md mode
ipv6: fix typo in fib6_net_exit()
tcp: fix a request socket leak
sctp: fix missing wake ups in some situations
netfilter: xt_hashlimit: fix build error caused by 64bit division
netfilter: xt_hashlimit: alloc hashtable with right size
...

+535 -233
+4
Documentation/devicetree/bindings/net/ethernet.txt
··· 1 1 The following properties are common to the Ethernet controllers: 2 2 3 + NOTE: All 'phy*' properties documented below are Ethernet specific. For the 4 + generic PHY 'phys' property, see 5 + Documentation/devicetree/bindings/phy/phy-bindings.txt. 6 + 3 7 - local-mac-address: array of 6 bytes, specifies the MAC address that was 4 8 assigned to the network device; 5 9 - mac-address: array of 6 bytes, specifies the MAC address that was last used by
+76
Documentation/devicetree/bindings/net/sff,sfp.txt
··· 1 + Small Form Factor (SFF) Committee Small Form-factor Pluggable (SFP) 2 + Transceiver 3 + 4 + Required properties: 5 + 6 + - compatible : must be "sff,sfp" 7 + 8 + Optional Properties: 9 + 10 + - i2c-bus : phandle of an I2C bus controller for the SFP two wire serial 11 + interface 12 + 13 + - mod-def0-gpios : GPIO phandle and a specifier of the MOD-DEF0 (AKA Mod_ABS) 14 + module presence input gpio signal, active (module absent) high 15 + 16 + - los-gpios : GPIO phandle and a specifier of the Receiver Loss of Signal 17 + Indication input gpio signal, active (signal lost) high 18 + 19 + - tx-fault-gpios : GPIO phandle and a specifier of the Module Transmitter 20 + Fault input gpio signal, active (fault condition) high 21 + 22 + - tx-disable-gpios : GPIO phandle and a specifier of the Transmitter Disable 23 + output gpio signal, active (Tx disable) high 24 + 25 + - rate-select0-gpios : GPIO phandle and a specifier of the Rx Signaling Rate 26 + Select (AKA RS0) output gpio signal, low: low Rx rate, high: high Rx rate 27 + 28 + - rate-select1-gpios : GPIO phandle and a specifier of the Tx Signaling Rate 29 + Select (AKA RS1) output gpio signal (SFP+ only), low: low Tx rate, high: 30 + high Tx rate 31 + 32 + Example #1: Direct serdes to SFP connection 33 + 34 + sfp_eth3: sfp-eth3 { 35 + compatible = "sff,sfp"; 36 + i2c-bus = <&sfp_1g_i2c>; 37 + los-gpios = <&cpm_gpio2 22 GPIO_ACTIVE_HIGH>; 38 + mod-def0-gpios = <&cpm_gpio2 21 GPIO_ACTIVE_LOW>; 39 + pinctrl-names = "default"; 40 + pinctrl-0 = <&cpm_sfp_1g_pins &cps_sfp_1g_pins>; 41 + tx-disable-gpios = <&cps_gpio1 24 GPIO_ACTIVE_HIGH>; 42 + tx-fault-gpios = <&cpm_gpio2 19 GPIO_ACTIVE_HIGH>; 43 + }; 44 + 45 + &cps_emac3 { 46 + phy-names = "comphy"; 47 + phys = <&cps_comphy5 0>; 48 + sfp = <&sfp_eth3>; 49 + }; 50 + 51 + Example #2: Serdes to PHY to SFP connection 52 + 53 + sfp_eth0: sfp-eth0 { 54 + compatible = "sff,sfp"; 55 + i2c-bus = <&sfpp0_i2c>; 56 + los-gpios = <&cps_gpio1 28 GPIO_ACTIVE_HIGH>; 57 + mod-def0-gpios = <&cps_gpio1 27 GPIO_ACTIVE_LOW>; 58 + pinctrl-names = "default"; 59 + pinctrl-0 = <&cps_sfpp0_pins>; 60 + tx-disable-gpios = <&cps_gpio1 29 GPIO_ACTIVE_HIGH>; 61 + tx-fault-gpios = <&cps_gpio1 26 GPIO_ACTIVE_HIGH>; 62 + }; 63 + 64 + p0_phy: ethernet-phy@0 { 65 + compatible = "ethernet-phy-ieee802.3-c45"; 66 + pinctrl-names = "default"; 67 + pinctrl-0 = <&cpm_phy0_pins &cps_phy0_pins>; 68 + reg = <0>; 69 + interrupt = <&cpm_gpio2 18 IRQ_TYPE_EDGE_FALLING>; 70 + sfp = <&sfp_eth0>; 71 + }; 72 + 73 + &cpm_eth0 { 74 + phy = <&p0_phy>; 75 + phy-mode = "10gbase-kr"; 76 + };
+3 -1
Documentation/devicetree/bindings/phy/phy-bindings.txt
··· 34 34 ============= 35 35 36 36 Required Properties: 37 - phys : the phandle for the PHY device (used by the PHY subsystem) 37 + phys : the phandle for the PHY device (used by the PHY subsystem; not to be 38 + confused with the Ethernet specific 'phy' and 'phy-handle' properties, 39 + see Documentation/devicetree/bindings/net/ethernet.txt for these) 38 40 phy-names : the names of the PHY corresponding to the PHYs present in the 39 41 *phys* phandle 40 42
+1
Documentation/devicetree/bindings/vendor-prefixes.txt
··· 292 292 seagate Seagate Technology PLC 293 293 semtech Semtech Corporation 294 294 sensirion Sensirion AG 295 + sff Small Form Factor Committee 295 296 sgx SGX Sensortech 296 297 sharp Sharp Corporation 297 298 si-en Si-En Technology Ltd.
+1 -1
drivers/isdn/isdnloop/isdnloop.c
··· 409 409 return -EINVAL; 410 410 } 411 411 if (len) { 412 - if (!(card->flags & (channel) ? ISDNLOOP_FLAGS_B2ACTIVE : ISDNLOOP_FLAGS_B1ACTIVE)) 412 + if (!(card->flags & (channel ? ISDNLOOP_FLAGS_B2ACTIVE : ISDNLOOP_FLAGS_B1ACTIVE))) 413 413 return 0; 414 414 if (card->sndcount[channel] > ISDNLOOP_MAX_SQUEUE) 415 415 return 0;
+1 -1
drivers/net/ethernet/davicom/dm9000.c
··· 65 65 */ 66 66 static int debug; 67 67 module_param(debug, int, 0644); 68 - MODULE_PARM_DESC(debug, "dm9000 debug level (0-4)"); 68 + MODULE_PARM_DESC(debug, "dm9000 debug level (0-6)"); 69 69 70 70 /* DM9000 register address locking. 71 71 *
+1 -1
drivers/net/ethernet/dec/tulip/tulip.h
··· 515 515 extern int tulip_debug; 516 516 extern const char * const medianame[]; 517 517 extern const char tulip_media_cap[]; 518 - extern struct tulip_chip_table tulip_tbl[]; 518 + extern const struct tulip_chip_table tulip_tbl[]; 519 519 void oom_timer(unsigned long data); 520 520 extern u8 t21040_csr13[]; 521 521
+1 -1
drivers/net/ethernet/dec/tulip/tulip_core.c
··· 138 138 * It is indexed via the values in 'enum chips' 139 139 */ 140 140 141 - struct tulip_chip_table tulip_tbl[] = { 141 + const struct tulip_chip_table tulip_tbl[] = { 142 142 { }, /* placeholder for array, slot unused currently */ 143 143 { }, /* placeholder for array, slot unused currently */ 144 144
-1
drivers/net/ethernet/ti/netcp_core.c
··· 2145 2145 2146 2146 of_node_put(netcp->node_interface); 2147 2147 unregister_netdev(ndev); 2148 - netif_napi_del(&netcp->rx_napi); 2149 2148 free_netdev(ndev); 2150 2149 } 2151 2150
+4 -2
drivers/net/phy/mdio_bus.c
··· 399 399 } 400 400 401 401 /* Put PHYs in RESET to save power */ 402 - gpiod_set_value_cansleep(bus->reset_gpiod, 1); 402 + if (bus->reset_gpiod) 403 + gpiod_set_value_cansleep(bus->reset_gpiod, 1); 403 404 404 405 device_del(&bus->dev); 405 406 return err; ··· 425 424 } 426 425 427 426 /* Put PHYs in RESET to save power */ 428 - gpiod_set_value_cansleep(bus->reset_gpiod, 1); 427 + if (bus->reset_gpiod) 428 + gpiod_set_value_cansleep(bus->reset_gpiod, 1); 429 429 430 430 device_del(&bus->dev); 431 431 }
+2 -2
drivers/net/phy/sfp.c
··· 58 58 }; 59 59 60 60 static const char *gpio_of_names[] = { 61 - "moddef0", 61 + "mod-def0", 62 62 "los", 63 63 "tx-fault", 64 64 "tx-disable", 65 - "rate-select", 65 + "rate-select0", 66 66 }; 67 67 68 68 static const enum gpiod_flags gpio_flags[] = {
+2 -1
drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
··· 159 159 160 160 brcmf_feat_firmware_capabilities(ifp); 161 161 memset(&gscan_cfg, 0, sizeof(gscan_cfg)); 162 - if (drvr->bus_if->chip != BRCM_CC_43430_CHIP_ID) 162 + if (drvr->bus_if->chip != BRCM_CC_43430_CHIP_ID && 163 + drvr->bus_if->chip != BRCM_CC_4345_CHIP_ID) 163 164 brcmf_feat_iovar_data_set(ifp, BRCMF_FEAT_GSCAN, 164 165 "pfn_gscan_cfg", 165 166 &gscan_cfg, sizeof(gscan_cfg));
+1
drivers/net/wireless/intel/iwlwifi/fw/file.h
··· 378 378 IWL_UCODE_TLV_CAPA_EXTEND_SHARED_MEM_CFG = (__force iwl_ucode_tlv_capa_t)80, 379 379 IWL_UCODE_TLV_CAPA_LQM_SUPPORT = (__force iwl_ucode_tlv_capa_t)81, 380 380 IWL_UCODE_TLV_CAPA_TX_POWER_ACK = (__force iwl_ucode_tlv_capa_t)84, 381 + IWL_UCODE_TLV_CAPA_LED_CMD_SUPPORT = (__force iwl_ucode_tlv_capa_t)86, 381 382 IWL_UCODE_TLV_CAPA_MLME_OFFLOAD = (__force iwl_ucode_tlv_capa_t)96, 382 383 383 384 NUM_IWL_UCODE_TLV_CAPA
+2 -1
drivers/net/wireless/intel/iwlwifi/mvm/led.c
··· 92 92 93 93 static void iwl_mvm_led_set(struct iwl_mvm *mvm, bool on) 94 94 { 95 - if (mvm->cfg->device_family >= IWL_DEVICE_FAMILY_8000) { 95 + if (fw_has_capa(&mvm->fw->ucode_capa, 96 + IWL_UCODE_TLV_CAPA_LED_CMD_SUPPORT)) { 96 97 iwl_mvm_send_led_fw_cmd(mvm, on); 97 98 return; 98 99 }
-2
drivers/net/wireless/mac80211_hwsim.c
··· 1362 1362 txi->control.rates, 1363 1363 ARRAY_SIZE(txi->control.rates)); 1364 1364 1365 - txi->rate_driver_data[0] = channel; 1366 - 1367 1365 if (skb->len >= 24 + 8 && 1368 1366 ieee80211_is_probe_resp(hdr->frame_control)) { 1369 1367 /* fake header transmission time */
+4 -1
drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b2ant.c
··· 1183 1183 } 1184 1184 1185 1185 /* fixed internal switch S1->WiFi, S0->BT */ 1186 - btcoexist->btc_write_4byte(btcoexist, 0x948, 0x0); 1186 + if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT) 1187 + btcoexist->btc_write_2byte(btcoexist, 0x948, 0x0); 1188 + else 1189 + btcoexist->btc_write_2byte(btcoexist, 0x948, 0x280); 1187 1190 1188 1191 switch (antpos_type) { 1189 1192 case BTC_ANT_WIFI_AT_MAIN:
+16 -7
drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
··· 173 173 174 174 u8 rtl_get_hwpg_single_ant_path(struct rtl_priv *rtlpriv) 175 175 { 176 + struct rtl_mod_params *mod_params = rtlpriv->cfg->mod_params; 177 + 178 + /* override ant_num / ant_path */ 179 + if (mod_params->ant_sel) { 180 + rtlpriv->btcoexist.btc_info.ant_num = 181 + (mod_params->ant_sel == 1 ? ANT_X2 : ANT_X1); 182 + 183 + rtlpriv->btcoexist.btc_info.single_ant_path = 184 + (mod_params->ant_sel == 1 ? 0 : 1); 185 + } 176 186 return rtlpriv->btcoexist.btc_info.single_ant_path; 177 187 } 178 188 ··· 193 183 194 184 u8 rtl_get_hwpg_ant_num(struct rtl_priv *rtlpriv) 195 185 { 186 + struct rtl_mod_params *mod_params = rtlpriv->cfg->mod_params; 196 187 u8 num; 197 188 198 189 if (rtlpriv->btcoexist.btc_info.ant_num == ANT_X2) 199 190 num = 2; 200 191 else 201 192 num = 1; 193 + 194 + /* override ant_num / ant_path */ 195 + if (mod_params->ant_sel) 196 + num = (mod_params->ant_sel == 1 ? ANT_X2 : ANT_X1) + 1; 202 197 203 198 return num; 204 199 } ··· 891 876 { 892 877 struct btc_coexist *btcoexist = &gl_bt_coexist; 893 878 struct rtl_priv *rtlpriv = adapter; 894 - u8 ant_num = 2, chip_type, single_ant_path = 0; 879 + u8 ant_num = 2, chip_type; 895 880 896 881 if (btcoexist->binded) 897 882 return false; ··· 925 910 exhalbtc_set_chip_type(chip_type); 926 911 ant_num = rtl_get_hwpg_ant_num(rtlpriv); 927 912 exhalbtc_set_ant_num(rtlpriv, BT_COEX_ANT_TYPE_PG, ant_num); 928 - 929 - /* set default antenna position to main port */ 930 - btcoexist->board_info.btdm_ant_pos = BTC_ANTENNA_AT_MAIN_PORT; 931 - 932 - single_ant_path = rtl_get_hwpg_single_ant_path(rtlpriv); 933 - exhalbtc_set_single_ant_path(single_ant_path); 934 913 935 914 if (rtl_get_hwpg_package_type(rtlpriv) == 0) 936 915 btcoexist->board_info.tfbga_package = false;
+4 -4
include/linux/bpf.h
··· 385 385 386 386 #if defined(CONFIG_STREAM_PARSER) && defined(CONFIG_BPF_SYSCALL) 387 387 struct sock *__sock_map_lookup_elem(struct bpf_map *map, u32 key); 388 - int sock_map_attach_prog(struct bpf_map *map, struct bpf_prog *prog, u32 type); 388 + int sock_map_prog(struct bpf_map *map, struct bpf_prog *prog, u32 type); 389 389 #else 390 390 static inline struct sock *__sock_map_lookup_elem(struct bpf_map *map, u32 key) 391 391 { 392 392 return NULL; 393 393 } 394 394 395 - static inline int sock_map_attach_prog(struct bpf_map *map, 396 - struct bpf_prog *prog, 397 - u32 type) 395 + static inline int sock_map_prog(struct bpf_map *map, 396 + struct bpf_prog *prog, 397 + u32 type) 398 398 { 399 399 return -EOPNOTSUPP; 400 400 }
+1 -1
include/linux/skbuff.h
··· 958 958 void kfree_skb_list(struct sk_buff *segs); 959 959 void skb_tx_error(struct sk_buff *skb); 960 960 void consume_skb(struct sk_buff *skb); 961 - void consume_stateless_skb(struct sk_buff *skb); 961 + void __consume_stateless_skb(struct sk_buff *skb); 962 962 void __kfree_skb(struct sk_buff *skb); 963 963 extern struct kmem_cache *skbuff_head_cache; 964 964
+2 -13
include/net/mac80211.h
··· 919 919 unsigned long jiffies; 920 920 }; 921 921 /* NB: vif can be NULL for injected frames */ 922 - union { 923 - /* NB: vif can be NULL for injected frames */ 924 - struct ieee80211_vif *vif; 925 - 926 - /* When packets are enqueued on txq it's easy 927 - * to re-construct the vif pointer. There's no 928 - * more space in tx_info so it can be used to 929 - * store the necessary enqueue time for packet 930 - * sojourn time computation. 931 - */ 932 - codel_time_t enqueue_time; 933 - }; 922 + struct ieee80211_vif *vif; 934 923 struct ieee80211_key_conf *hw_key; 935 924 u32 flags; 936 - /* 4 bytes free */ 925 + codel_time_t enqueue_time; 937 926 } control; 938 927 struct { 939 928 u64 cookie;
+1 -2
include/net/netfilter/nf_conntrack.h
··· 17 17 #include <linux/bitops.h> 18 18 #include <linux/compiler.h> 19 19 #include <linux/atomic.h> 20 - #include <linux/rhashtable.h> 21 20 22 21 #include <linux/netfilter/nf_conntrack_tcp.h> 23 22 #include <linux/netfilter/nf_conntrack_dccp.h> ··· 76 77 possible_net_t ct_net; 77 78 78 79 #if IS_ENABLED(CONFIG_NF_NAT) 79 - struct rhlist_head nat_bysource; 80 + struct hlist_node nat_bysource; 80 81 #endif 81 82 /* all members below initialized via memset */ 82 83 u8 __nfct_init_offset[0];
-1
include/net/netfilter/nf_nat.h
··· 1 1 #ifndef _NF_NAT_H 2 2 #define _NF_NAT_H 3 - #include <linux/rhashtable.h> 4 3 #include <linux/netfilter_ipv4.h> 5 4 #include <linux/netfilter/nf_nat.h> 6 5 #include <net/netfilter/nf_conntrack_tuple.h>
+2 -2
include/uapi/linux/bpf.h
··· 766 766 767 767 /* User return codes for XDP prog type. 768 768 * A valid XDP program must return one of these defined values. All other 769 - * return codes are reserved for future use. Unknown return codes will result 770 - * in packet drop. 769 + * return codes are reserved for future use. Unknown return codes will 770 + * result in packet drops and a warning via bpf_warn_invalid_xdp_action(). 771 771 */ 772 772 enum xdp_action { 773 773 XDP_ABORTED = 0,
+1 -1
kernel/bpf/devmap.c
··· 159 159 unsigned long *bitmap = per_cpu_ptr(dtab->flush_needed, cpu); 160 160 161 161 while (!bitmap_empty(bitmap, dtab->map.max_entries)) 162 - cpu_relax(); 162 + cond_resched(); 163 163 } 164 164 165 165 for (i = 0; i < dtab->map.max_entries; i++) {
+1 -1
kernel/bpf/sockmap.c
··· 792 792 return err; 793 793 } 794 794 795 - int sock_map_attach_prog(struct bpf_map *map, struct bpf_prog *prog, u32 type) 795 + int sock_map_prog(struct bpf_map *map, struct bpf_prog *prog, u32 type) 796 796 { 797 797 struct bpf_stab *stab = container_of(map, struct bpf_stab, map); 798 798 struct bpf_prog *orig;
+17 -10
kernel/bpf/syscall.c
··· 1096 1096 1097 1097 #define BPF_PROG_ATTACH_LAST_FIELD attach_flags 1098 1098 1099 - static int sockmap_get_from_fd(const union bpf_attr *attr) 1099 + static int sockmap_get_from_fd(const union bpf_attr *attr, bool attach) 1100 1100 { 1101 + struct bpf_prog *prog = NULL; 1101 1102 int ufd = attr->target_fd; 1102 - struct bpf_prog *prog; 1103 1103 struct bpf_map *map; 1104 1104 struct fd f; 1105 1105 int err; ··· 1109 1109 if (IS_ERR(map)) 1110 1110 return PTR_ERR(map); 1111 1111 1112 - prog = bpf_prog_get_type(attr->attach_bpf_fd, BPF_PROG_TYPE_SK_SKB); 1113 - if (IS_ERR(prog)) { 1114 - fdput(f); 1115 - return PTR_ERR(prog); 1112 + if (attach) { 1113 + prog = bpf_prog_get_type(attr->attach_bpf_fd, 1114 + BPF_PROG_TYPE_SK_SKB); 1115 + if (IS_ERR(prog)) { 1116 + fdput(f); 1117 + return PTR_ERR(prog); 1118 + } 1116 1119 } 1117 1120 1118 - err = sock_map_attach_prog(map, prog, attr->attach_type); 1121 + err = sock_map_prog(map, prog, attr->attach_type); 1119 1122 if (err) { 1120 1123 fdput(f); 1121 - bpf_prog_put(prog); 1124 + if (prog) 1125 + bpf_prog_put(prog); 1122 1126 return err; 1123 1127 } 1124 1128 ··· 1159 1155 break; 1160 1156 case BPF_SK_SKB_STREAM_PARSER: 1161 1157 case BPF_SK_SKB_STREAM_VERDICT: 1162 - return sockmap_get_from_fd(attr); 1158 + return sockmap_get_from_fd(attr, true); 1163 1159 default: 1164 1160 return -EINVAL; 1165 1161 } ··· 1208 1204 ret = cgroup_bpf_update(cgrp, NULL, attr->attach_type, false); 1209 1205 cgroup_put(cgrp); 1210 1206 break; 1211 - 1207 + case BPF_SK_SKB_STREAM_PARSER: 1208 + case BPF_SK_SKB_STREAM_VERDICT: 1209 + ret = sockmap_get_from_fd(attr, false); 1210 + break; 1212 1211 default: 1213 1212 return -EINVAL; 1214 1213 }
+16
kernel/bpf/verifier.c
··· 4203 4203 continue; 4204 4204 } 4205 4205 4206 + if (insn->imm == BPF_FUNC_redirect_map) { 4207 + u64 addr = (unsigned long)prog; 4208 + struct bpf_insn r4_ld[] = { 4209 + BPF_LD_IMM64(BPF_REG_4, addr), 4210 + *insn, 4211 + }; 4212 + cnt = ARRAY_SIZE(r4_ld); 4213 + 4214 + new_prog = bpf_patch_insn_data(env, i + delta, r4_ld, cnt); 4215 + if (!new_prog) 4216 + return -ENOMEM; 4217 + 4218 + delta += cnt - 1; 4219 + env->prog = prog = new_prog; 4220 + insn = new_prog->insnsi + i + delta; 4221 + } 4206 4222 patch_call_imm: 4207 4223 fn = prog->aux->ops->get_func_proto(insn->imm); 4208 4224 /* all functions that have prototype and verifier allowed
+16 -9
net/core/dev.c
··· 3981 3981 trace_netif_rx(skb); 3982 3982 3983 3983 if (static_key_false(&generic_xdp_needed)) { 3984 - int ret = do_xdp_generic(rcu_dereference(skb->dev->xdp_prog), 3985 - skb); 3984 + int ret; 3985 + 3986 + preempt_disable(); 3987 + rcu_read_lock(); 3988 + ret = do_xdp_generic(rcu_dereference(skb->dev->xdp_prog), skb); 3989 + rcu_read_unlock(); 3990 + preempt_enable(); 3986 3991 3987 3992 /* Consider XDP consuming the packet a success from 3988 3993 * the netdev point of view we do not want to count ··· 4505 4500 if (skb_defer_rx_timestamp(skb)) 4506 4501 return NET_RX_SUCCESS; 4507 4502 4508 - rcu_read_lock(); 4509 - 4510 4503 if (static_key_false(&generic_xdp_needed)) { 4511 - int ret = do_xdp_generic(rcu_dereference(skb->dev->xdp_prog), 4512 - skb); 4504 + int ret; 4513 4505 4514 - if (ret != XDP_PASS) { 4515 - rcu_read_unlock(); 4506 + preempt_disable(); 4507 + rcu_read_lock(); 4508 + ret = do_xdp_generic(rcu_dereference(skb->dev->xdp_prog), skb); 4509 + rcu_read_unlock(); 4510 + preempt_enable(); 4511 + 4512 + if (ret != XDP_PASS) 4516 4513 return NET_RX_DROP; 4517 - } 4518 4514 } 4519 4515 4516 + rcu_read_lock(); 4520 4517 #ifdef CONFIG_RPS 4521 4518 if (static_key_false(&rps_needed)) { 4522 4519 struct rps_dev_flow voidflow, *rflow = &voidflow;
+24 -3
net/core/filter.c
··· 1794 1794 u32 flags; 1795 1795 struct bpf_map *map; 1796 1796 struct bpf_map *map_to_flush; 1797 + const struct bpf_prog *map_owner; 1797 1798 }; 1798 1799 1799 1800 static DEFINE_PER_CPU(struct redirect_info, redirect_info); ··· 1808 1807 1809 1808 ri->ifindex = ifindex; 1810 1809 ri->flags = flags; 1811 - ri->map = NULL; 1812 1810 1813 1811 return TC_ACT_REDIRECT; 1814 1812 } ··· 2504 2504 struct bpf_prog *xdp_prog) 2505 2505 { 2506 2506 struct redirect_info *ri = this_cpu_ptr(&redirect_info); 2507 + const struct bpf_prog *map_owner = ri->map_owner; 2507 2508 struct bpf_map *map = ri->map; 2508 2509 u32 index = ri->ifindex; 2509 2510 struct net_device *fwd; ··· 2512 2511 2513 2512 ri->ifindex = 0; 2514 2513 ri->map = NULL; 2514 + ri->map_owner = NULL; 2515 + 2516 + /* This is really only caused by a deliberately crappy 2517 + * BPF program, normally we would never hit that case, 2518 + * so no need to inform someone via tracepoints either, 2519 + * just bail out. 2520 + */ 2521 + if (unlikely(map_owner != xdp_prog)) 2522 + return -EINVAL; 2515 2523 2516 2524 fwd = __dev_map_lookup_elem(map, index); 2517 2525 if (!fwd) { ··· 2617 2607 2618 2608 ri->ifindex = ifindex; 2619 2609 ri->flags = flags; 2610 + ri->map = NULL; 2611 + ri->map_owner = NULL; 2620 2612 2621 2613 return XDP_REDIRECT; 2622 2614 } ··· 2631 2619 .arg2_type = ARG_ANYTHING, 2632 2620 }; 2633 2621 2634 - BPF_CALL_3(bpf_xdp_redirect_map, struct bpf_map *, map, u32, ifindex, u64, flags) 2622 + BPF_CALL_4(bpf_xdp_redirect_map, struct bpf_map *, map, u32, ifindex, u64, flags, 2623 + const struct bpf_prog *, map_owner) 2635 2624 { 2636 2625 struct redirect_info *ri = this_cpu_ptr(&redirect_info); 2637 2626 ··· 2642 2629 ri->ifindex = ifindex; 2643 2630 ri->flags = flags; 2644 2631 ri->map = map; 2632 + ri->map_owner = map_owner; 2645 2633 2646 2634 return XDP_REDIRECT; 2647 2635 } 2648 2636 2637 + /* Note, arg4 is hidden from users and populated by the verifier 2638 + * with the right pointer. 2639 + */ 2649 2640 static const struct bpf_func_proto bpf_xdp_redirect_map_proto = { 2650 2641 .func = bpf_xdp_redirect_map, 2651 2642 .gpl_only = false, ··· 3609 3592 3610 3593 void bpf_warn_invalid_xdp_action(u32 act) 3611 3594 { 3612 - WARN_ONCE(1, "Illegal XDP return value %u, expect packet loss\n", act); 3595 + const u32 act_max = XDP_REDIRECT; 3596 + 3597 + WARN_ONCE(1, "%s XDP return value %u, expect packet loss!\n", 3598 + act > act_max ? "Illegal" : "Driver unsupported", 3599 + act); 3613 3600 } 3614 3601 EXPORT_SYMBOL_GPL(bpf_warn_invalid_xdp_action); 3615 3602
+3 -6
net/core/skbuff.c
··· 710 710 * consume_stateless_skb - free an skbuff, assuming it is stateless 711 711 * @skb: buffer to free 712 712 * 713 - * Works like consume_skb(), but this variant assumes that all the head 714 - * states have been already dropped. 713 + * Alike consume_skb(), but this variant assumes that this is the last 714 + * skb reference and all the head states have been already dropped 715 715 */ 716 - void consume_stateless_skb(struct sk_buff *skb) 716 + void __consume_stateless_skb(struct sk_buff *skb) 717 717 { 718 - if (!skb_unref(skb)) 719 - return; 720 - 721 718 trace_consume_skb(skb); 722 719 skb_release_data(skb); 723 720 kfree_skbmem(skb);
+2 -2
net/ipv4/ip_tunnel.c
··· 618 618 ip_rt_put(rt); 619 619 goto tx_dropped; 620 620 } 621 - iptunnel_xmit(NULL, rt, skb, fl4.saddr, fl4.daddr, proto, key->tos, 622 - key->ttl, df, !net_eq(tunnel->net, dev_net(dev))); 621 + iptunnel_xmit(NULL, rt, skb, fl4.saddr, fl4.daddr, proto, tos, ttl, 622 + df, !net_eq(tunnel->net, dev_net(dev))); 623 623 return; 624 624 tx_error: 625 625 dev->stats.tx_errors++;
+1
net/ipv4/netfilter/arp_tables.c
··· 629 629 630 630 ADD_COUNTER(counters[i], bcnt, pcnt); 631 631 ++i; 632 + cond_resched(); 632 633 } 633 634 } 634 635 }
+1
net/ipv4/netfilter/ip_tables.c
··· 776 776 777 777 ADD_COUNTER(counters[i], bcnt, pcnt); 778 778 ++i; /* macro does multi eval of i */ 779 + cond_resched(); 779 780 } 780 781 } 781 782 }
+3 -3
net/ipv4/tcp_ipv4.c
··· 1669 1669 */ 1670 1670 sock_hold(sk); 1671 1671 refcounted = true; 1672 - if (tcp_filter(sk, skb)) 1673 - goto discard_and_relse; 1674 - nsk = tcp_check_req(sk, skb, req, false); 1672 + nsk = NULL; 1673 + if (!tcp_filter(sk, skb)) 1674 + nsk = tcp_check_req(sk, skb, req, false); 1675 1675 if (!nsk) { 1676 1676 reqsk_put(req); 1677 1677 goto discard_and_relse;
+4 -1
net/ipv4/udp.c
··· 1397 1397 unlock_sock_fast(sk, slow); 1398 1398 } 1399 1399 1400 + if (!skb_unref(skb)) 1401 + return; 1402 + 1400 1403 /* In the more common cases we cleared the head states previously, 1401 1404 * see __udp_queue_rcv_skb(). 1402 1405 */ 1403 1406 if (unlikely(udp_skb_has_head_state(skb))) 1404 1407 skb_release_head_state(skb); 1405 - consume_stateless_skb(skb); 1408 + __consume_stateless_skb(skb); 1406 1409 } 1407 1410 EXPORT_SYMBOL_GPL(skb_consume_udp); 1408 1411
+19 -6
net/ipv6/ip6_fib.c
··· 191 191 } 192 192 EXPORT_SYMBOL_GPL(rt6_free_pcpu); 193 193 194 + static void fib6_free_table(struct fib6_table *table) 195 + { 196 + inetpeer_invalidate_tree(&table->tb6_peers); 197 + kfree(table); 198 + } 199 + 194 200 static void fib6_link_table(struct net *net, struct fib6_table *tb) 195 201 { 196 202 unsigned int h; ··· 2028 2022 2029 2023 static void fib6_net_exit(struct net *net) 2030 2024 { 2025 + unsigned int i; 2026 + 2031 2027 rt6_ifdown(net, NULL); 2032 2028 del_timer_sync(&net->ipv6.ip6_fib_timer); 2033 2029 2034 - #ifdef CONFIG_IPV6_MULTIPLE_TABLES 2035 - inetpeer_invalidate_tree(&net->ipv6.fib6_local_tbl->tb6_peers); 2036 - kfree(net->ipv6.fib6_local_tbl); 2037 - #endif 2038 - inetpeer_invalidate_tree(&net->ipv6.fib6_main_tbl->tb6_peers); 2039 - kfree(net->ipv6.fib6_main_tbl); 2030 + for (i = 0; i < FIB6_TABLE_HASHSZ; i++) { 2031 + struct hlist_head *head = &net->ipv6.fib_table_hash[i]; 2032 + struct hlist_node *tmp; 2033 + struct fib6_table *tb; 2034 + 2035 + hlist_for_each_entry_safe(tb, tmp, head, tb6_hlist) { 2036 + hlist_del(&tb->tb6_hlist); 2037 + fib6_free_table(tb); 2038 + } 2039 + } 2040 + 2040 2041 kfree(net->ipv6.fib_table_hash); 2041 2042 kfree(net->ipv6.rt6_stats); 2042 2043 fib6_notifier_exit(net);
+3 -1
net/ipv6/ip6_gre.c
··· 432 432 } 433 433 break; 434 434 case ICMPV6_PKT_TOOBIG: 435 - mtu = be32_to_cpu(info) - offset; 435 + mtu = be32_to_cpu(info) - offset - t->tun_hlen; 436 + if (t->dev->type == ARPHRD_ETHER) 437 + mtu -= ETH_HLEN; 436 438 if (mtu < IPV6_MIN_MTU) 437 439 mtu = IPV6_MIN_MTU; 438 440 t->dev->mtu = mtu;
+1
net/ipv6/ip6_tunnel.c
··· 1184 1184 init_tel_txopt(&opt, encap_limit); 1185 1185 ipv6_push_frag_opts(skb, &opt.ops, &proto); 1186 1186 } 1187 + hop_limit = hop_limit ? : ip6_dst_hoplimit(dst); 1187 1188 1188 1189 /* Calculate max headroom for all the headers and adjust 1189 1190 * needed_headroom if necessary.
+1
net/ipv6/netfilter/ip6_tables.c
··· 795 795 796 796 ADD_COUNTER(counters[i], bcnt, pcnt); 797 797 ++i; 798 + cond_resched(); 798 799 } 799 800 } 800 801 }
+3 -3
net/ipv6/tcp_ipv6.c
··· 1460 1460 } 1461 1461 sock_hold(sk); 1462 1462 refcounted = true; 1463 - if (tcp_filter(sk, skb)) 1464 - goto discard_and_relse; 1465 - nsk = tcp_check_req(sk, skb, req, false); 1463 + nsk = NULL; 1464 + if (!tcp_filter(sk, skb)) 1465 + nsk = tcp_check_req(sk, skb, req, false); 1466 1466 if (!nsk) { 1467 1467 reqsk_put(req); 1468 1468 goto discard_and_relse;
+21 -11
net/mac80211/agg-rx.c
··· 245 245 ieee80211_tx_skb(sdata, skb); 246 246 } 247 247 248 - void __ieee80211_start_rx_ba_session(struct sta_info *sta, 249 - u8 dialog_token, u16 timeout, 250 - u16 start_seq_num, u16 ba_policy, u16 tid, 251 - u16 buf_size, bool tx, bool auto_seq) 248 + void ___ieee80211_start_rx_ba_session(struct sta_info *sta, 249 + u8 dialog_token, u16 timeout, 250 + u16 start_seq_num, u16 ba_policy, u16 tid, 251 + u16 buf_size, bool tx, bool auto_seq) 252 252 { 253 253 struct ieee80211_local *local = sta->sdata->local; 254 254 struct tid_ampdu_rx *tid_agg_rx; ··· 267 267 ht_dbg(sta->sdata, 268 268 "STA %pM requests BA session on unsupported tid %d\n", 269 269 sta->sta.addr, tid); 270 - goto end_no_lock; 270 + goto end; 271 271 } 272 272 273 273 if (!sta->sta.ht_cap.ht_supported) { ··· 275 275 "STA %pM erroneously requests BA session on tid %d w/o QoS\n", 276 276 sta->sta.addr, tid); 277 277 /* send a response anyway, it's an error case if we get here */ 278 - goto end_no_lock; 278 + goto end; 279 279 } 280 280 281 281 if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) { 282 282 ht_dbg(sta->sdata, 283 283 "Suspend in progress - Denying ADDBA request (%pM tid %d)\n", 284 284 sta->sta.addr, tid); 285 - goto end_no_lock; 285 + goto end; 286 286 } 287 287 288 288 /* sanity check for incoming parameters: ··· 296 296 ht_dbg_ratelimited(sta->sdata, 297 297 "AddBA Req with bad params from %pM on tid %u. policy %d, buffer size %d\n", 298 298 sta->sta.addr, tid, ba_policy, buf_size); 299 - goto end_no_lock; 299 + goto end; 300 300 } 301 301 /* determine default buffer size */ 302 302 if (buf_size == 0) ··· 311 311 buf_size, sta->sta.addr); 312 312 313 313 /* examine state machine */ 314 - mutex_lock(&sta->ampdu_mlme.mtx); 314 + lockdep_assert_held(&sta->ampdu_mlme.mtx); 315 315 316 316 if (test_bit(tid, sta->ampdu_mlme.agg_session_valid)) { 317 317 if (sta->ampdu_mlme.tid_rx_token[tid] == dialog_token) { ··· 415 415 __clear_bit(tid, sta->ampdu_mlme.unexpected_agg); 416 416 sta->ampdu_mlme.tid_rx_token[tid] = dialog_token; 417 417 } 418 - mutex_unlock(&sta->ampdu_mlme.mtx); 419 418 420 - end_no_lock: 421 419 if (tx) 422 420 ieee80211_send_addba_resp(sta->sdata, sta->sta.addr, tid, 423 421 dialog_token, status, 1, buf_size, 424 422 timeout); 423 + } 424 + 425 + void __ieee80211_start_rx_ba_session(struct sta_info *sta, 426 + u8 dialog_token, u16 timeout, 427 + u16 start_seq_num, u16 ba_policy, u16 tid, 428 + u16 buf_size, bool tx, bool auto_seq) 429 + { 430 + mutex_lock(&sta->ampdu_mlme.mtx); 431 + ___ieee80211_start_rx_ba_session(sta, dialog_token, timeout, 432 + start_seq_num, ba_policy, tid, 433 + buf_size, tx, auto_seq); 434 + mutex_unlock(&sta->ampdu_mlme.mtx); 425 435 } 426 436 427 437 void ieee80211_process_addba_request(struct ieee80211_local *local,
+6 -2
net/mac80211/agg-tx.c
··· 226 226 clear_bit(IEEE80211_TXQ_AMPDU, &txqi->flags); 227 227 228 228 clear_bit(IEEE80211_TXQ_STOP, &txqi->flags); 229 + local_bh_disable(); 230 + rcu_read_lock(); 229 231 drv_wake_tx_queue(sta->sdata->local, txqi); 232 + rcu_read_unlock(); 233 + local_bh_enable(); 230 234 } 231 235 232 236 /* ··· 440 436 test_bit(HT_AGG_STATE_RESPONSE_RECEIVED, &tid_tx->state)) { 441 437 rcu_read_unlock(); 442 438 ht_dbg(sta->sdata, 443 - "timer expired on %pM tid %d but we are not (or no longer) expecting addBA response there\n", 439 + "timer expired on %pM tid %d not expecting addBA response\n", 444 440 sta->sta.addr, tid); 445 441 return; 446 442 } ··· 643 639 time_before(jiffies, sta->ampdu_mlme.last_addba_req_time[tid] + 644 640 HT_AGG_RETRIES_PERIOD)) { 645 641 ht_dbg(sdata, 646 - "BA request denied - waiting a grace period after %d failed requests on %pM tid %u\n", 642 + "BA request denied - %d failed requests on %pM tid %u\n", 647 643 sta->ampdu_mlme.addba_req_num[tid], sta->sta.addr, tid); 648 644 ret = -EBUSY; 649 645 goto err_unlock_sta;
+21 -3
net/mac80211/ht.c
··· 300 300 301 301 /* stopping might queue the work again - so cancel only afterwards */ 302 302 cancel_work_sync(&sta->ampdu_mlme.work); 303 + 304 + /* 305 + * In case the tear down is part of a reconfigure due to HW restart 306 + * request, it is possible that the low level driver requested to stop 307 + * the BA session, so handle it to properly clean tid_tx data. 308 + */ 309 + mutex_lock(&sta->ampdu_mlme.mtx); 310 + for (i = 0; i < IEEE80211_NUM_TIDS; i++) { 311 + struct tid_ampdu_tx *tid_tx = 312 + rcu_dereference_protected_tid_tx(sta, i); 313 + 314 + if (!tid_tx) 315 + continue; 316 + 317 + if (test_and_clear_bit(HT_AGG_STATE_STOP_CB, &tid_tx->state)) 318 + ieee80211_stop_tx_ba_cb(sta, i, tid_tx); 319 + } 320 + mutex_unlock(&sta->ampdu_mlme.mtx); 303 321 } 304 322 305 323 void ieee80211_ba_session_work(struct work_struct *work) ··· 351 333 352 334 if (test_and_clear_bit(tid, 353 335 sta->ampdu_mlme.tid_rx_manage_offl)) 354 - __ieee80211_start_rx_ba_session(sta, 0, 0, 0, 1, tid, 355 - IEEE80211_MAX_AMPDU_BUF, 356 - false, true); 336 + ___ieee80211_start_rx_ba_session(sta, 0, 0, 0, 1, tid, 337 + IEEE80211_MAX_AMPDU_BUF, 338 + false, true); 357 339 358 340 if (test_and_clear_bit(tid + IEEE80211_NUM_TIDS, 359 341 sta->ampdu_mlme.tid_rx_manage_offl))
+4
net/mac80211/ieee80211_i.h
··· 1760 1760 u8 dialog_token, u16 timeout, 1761 1761 u16 start_seq_num, u16 ba_policy, u16 tid, 1762 1762 u16 buf_size, bool tx, bool auto_seq); 1763 + void ___ieee80211_start_rx_ba_session(struct sta_info *sta, 1764 + u8 dialog_token, u16 timeout, 1765 + u16 start_seq_num, u16 ba_policy, u16 tid, 1766 + u16 buf_size, bool tx, bool auto_seq); 1763 1767 void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, 1764 1768 enum ieee80211_agg_stop_reason reason); 1765 1769 void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
+17 -3
net/mac80211/iface.c
··· 731 731 sdata->vif.type == NL80211_IFTYPE_AP_VLAN || 732 732 local->ops->wake_tx_queue) { 733 733 /* XXX: for AP_VLAN, actually track AP queues */ 734 - netif_tx_start_all_queues(dev); 734 + if (dev) 735 + netif_tx_start_all_queues(dev); 735 736 } else if (dev) { 736 737 unsigned long flags; 737 738 int n_acs = IEEE80211_NUM_ACS; ··· 793 792 static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, 794 793 bool going_down) 795 794 { 795 + struct ieee80211_sub_if_data *txq_sdata = sdata; 796 796 struct ieee80211_local *local = sdata->local; 797 797 struct fq *fq = &local->fq; 798 798 unsigned long flags; ··· 939 937 940 938 switch (sdata->vif.type) { 941 939 case NL80211_IFTYPE_AP_VLAN: 940 + txq_sdata = container_of(sdata->bss, 941 + struct ieee80211_sub_if_data, u.ap); 942 + 942 943 mutex_lock(&local->mtx); 943 944 list_del(&sdata->u.vlan.list); 944 945 mutex_unlock(&local->mtx); ··· 1012 1007 } 1013 1008 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 1014 1009 1015 - if (sdata->vif.txq) { 1016 - struct txq_info *txqi = to_txq_info(sdata->vif.txq); 1010 + if (txq_sdata->vif.txq) { 1011 + struct txq_info *txqi = to_txq_info(txq_sdata->vif.txq); 1012 + 1013 + /* 1014 + * FIXME FIXME 1015 + * 1016 + * We really shouldn't purge the *entire* txqi since that 1017 + * contains frames for the other AP_VLANs (and possibly 1018 + * the AP itself) as well, but there's no API in FQ now 1019 + * to be able to filter. 1020 + */ 1017 1021 1018 1022 spin_lock_bh(&fq->lock); 1019 1023 ieee80211_txq_purge(local, txqi);
+1 -1
net/mac80211/mlme.c
··· 3155 3155 if (len < 24 + 6) 3156 3156 return; 3157 3157 3158 - reassoc = ieee80211_is_reassoc_req(mgmt->frame_control); 3158 + reassoc = ieee80211_is_reassoc_resp(mgmt->frame_control); 3159 3159 capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info); 3160 3160 status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code); 3161 3161 aid = le16_to_cpu(mgmt->u.assoc_resp.aid);
+2
net/mac80211/offchannel.c
··· 707 707 if (!cookie) 708 708 return -ENOENT; 709 709 710 + flush_work(&local->hw_roc_start); 711 + 710 712 mutex_lock(&local->mtx); 711 713 list_for_each_entry_safe(roc, tmp, &local->roc_list, list) { 712 714 if (!mgmt_tx && roc->cookie != cookie)
+29 -7
net/mac80211/tx.c
··· 1276 1276 IEEE80211_SKB_CB(skb)->control.enqueue_time = codel_get_time(); 1277 1277 } 1278 1278 1279 - static void ieee80211_set_skb_vif(struct sk_buff *skb, struct txq_info *txqi) 1280 - { 1281 - IEEE80211_SKB_CB(skb)->control.vif = txqi->txq.vif; 1282 - } 1283 - 1284 1279 static u32 codel_skb_len_func(const struct sk_buff *skb) 1285 1280 { 1286 1281 return skb->len; ··· 3409 3414 struct ieee80211_tx_info *info; 3410 3415 struct ieee80211_tx_data tx; 3411 3416 ieee80211_tx_result r; 3417 + struct ieee80211_vif *vif; 3412 3418 3413 3419 spin_lock_bh(&fq->lock); 3414 3420 ··· 3425 3429 skb = fq_tin_dequeue(fq, tin, fq_tin_dequeue_func); 3426 3430 if (!skb) 3427 3431 goto out; 3428 - 3429 - ieee80211_set_skb_vif(skb, txqi); 3430 3432 3431 3433 hdr = (struct ieee80211_hdr *)skb->data; 3432 3434 info = IEEE80211_SKB_CB(skb); ··· 3482 3488 } 3483 3489 } 3484 3490 3491 + switch (tx.sdata->vif.type) { 3492 + case NL80211_IFTYPE_MONITOR: 3493 + if (tx.sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) { 3494 + vif = &tx.sdata->vif; 3495 + break; 3496 + } 3497 + tx.sdata = rcu_dereference(local->monitor_sdata); 3498 + if (tx.sdata) { 3499 + vif = &tx.sdata->vif; 3500 + info->hw_queue = 3501 + vif->hw_queue[skb_get_queue_mapping(skb)]; 3502 + } else if (ieee80211_hw_check(&local->hw, QUEUE_CONTROL)) { 3503 + ieee80211_free_txskb(&local->hw, skb); 3504 + goto begin; 3505 + } else { 3506 + vif = NULL; 3507 + } 3508 + break; 3509 + case NL80211_IFTYPE_AP_VLAN: 3510 + tx.sdata = container_of(tx.sdata->bss, 3511 + struct ieee80211_sub_if_data, u.ap); 3512 + /* fall through */ 3513 + default: 3514 + vif = &tx.sdata->vif; 3515 + break; 3516 + } 3517 + 3518 + IEEE80211_SKB_CB(skb)->control.vif = vif; 3485 3519 out: 3486 3520 spin_unlock_bh(&fq->lock); 3487 3521
+1 -1
net/mac80211/util.c
··· 1436 1436 WLAN_EID_SSID_LIST, 1437 1437 WLAN_EID_CHANNEL_USAGE, 1438 1438 WLAN_EID_INTERWORKING, 1439 - /* mesh ID can't happen here */ 1439 + WLAN_EID_MESH_ID, 1440 1440 /* 60 GHz can't happen here right now */ 1441 1441 }; 1442 1442 noffset = ieee80211_ie_split(ie, ie_len,
+1 -1
net/netfilter/core.c
··· 215 215 if (skip == hook_entries) 216 216 goto out_assign; 217 217 218 - if (WARN_ON(skip == 0)) 218 + if (skip == 0) 219 219 return NULL; 220 220 221 221 hook_entries -= skip;
+6 -2
net/netfilter/ipvs/ip_vs_proto_sctp.c
··· 24 24 if (sh) { 25 25 sch = skb_header_pointer(skb, iph->len + sizeof(_sctph), 26 26 sizeof(_schunkh), &_schunkh); 27 - if (sch && (sch->type == SCTP_CID_INIT || 28 - sysctl_sloppy_sctp(ipvs))) 27 + if (sch) { 28 + if (sch->type == SCTP_CID_ABORT || 29 + !(sysctl_sloppy_sctp(ipvs) || 30 + sch->type == SCTP_CID_INIT)) 31 + return 1; 29 32 ports = &sh->source; 33 + } 30 34 } 31 35 } else { 32 36 ports = skb_header_pointer(
+66 -76
net/netfilter/nf_nat_core.c
··· 30 30 #include <net/netfilter/nf_conntrack_zones.h> 31 31 #include <linux/netfilter/nf_nat.h> 32 32 33 + static spinlock_t nf_nat_locks[CONNTRACK_LOCKS]; 34 + 33 35 static DEFINE_MUTEX(nf_nat_proto_mutex); 34 36 static const struct nf_nat_l3proto __rcu *nf_nat_l3protos[NFPROTO_NUMPROTO] 35 37 __read_mostly; 36 38 static const struct nf_nat_l4proto __rcu **nf_nat_l4protos[NFPROTO_NUMPROTO] 37 39 __read_mostly; 38 40 39 - struct nf_nat_conn_key { 40 - const struct net *net; 41 - const struct nf_conntrack_tuple *tuple; 42 - const struct nf_conntrack_zone *zone; 43 - }; 44 - 45 - static struct rhltable nf_nat_bysource_table; 41 + static struct hlist_head *nf_nat_bysource __read_mostly; 42 + static unsigned int nf_nat_htable_size __read_mostly; 43 + static unsigned int nf_nat_hash_rnd __read_mostly; 46 44 47 45 inline const struct nf_nat_l3proto * 48 46 __nf_nat_l3proto_find(u8 family) ··· 116 118 EXPORT_SYMBOL(nf_xfrm_me_harder); 117 119 #endif /* CONFIG_XFRM */ 118 120 119 - static u32 nf_nat_bysource_hash(const void *data, u32 len, u32 seed) 121 + /* We keep an extra hash for each conntrack, for fast searching. */ 122 + static unsigned int 123 + hash_by_src(const struct net *n, const struct nf_conntrack_tuple *tuple) 120 124 { 121 - const struct nf_conntrack_tuple *t; 122 - const struct nf_conn *ct = data; 125 + unsigned int hash; 123 126 124 - t = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; 127 + get_random_once(&nf_nat_hash_rnd, sizeof(nf_nat_hash_rnd)); 128 + 125 129 /* Original src, to ensure we map it consistently if poss. */ 130 + hash = jhash2((u32 *)&tuple->src, sizeof(tuple->src) / sizeof(u32), 131 + tuple->dst.protonum ^ nf_nat_hash_rnd ^ net_hash_mix(n)); 126 132 127 - seed ^= net_hash_mix(nf_ct_net(ct)); 128 - return jhash2((const u32 *)&t->src, sizeof(t->src) / sizeof(u32), 129 - t->dst.protonum ^ seed); 133 + return reciprocal_scale(hash, nf_nat_htable_size); 130 134 } 131 135 132 136 /* Is this tuple already taken? (not by us) */ ··· 184 184 t->src.u.all == tuple->src.u.all); 185 185 } 186 186 187 - static int nf_nat_bysource_cmp(struct rhashtable_compare_arg *arg, 188 - const void *obj) 189 - { 190 - const struct nf_nat_conn_key *key = arg->key; 191 - const struct nf_conn *ct = obj; 192 - 193 - if (!same_src(ct, key->tuple) || 194 - !net_eq(nf_ct_net(ct), key->net) || 195 - !nf_ct_zone_equal(ct, key->zone, IP_CT_DIR_ORIGINAL)) 196 - return 1; 197 - 198 - return 0; 199 - } 200 - 201 - static struct rhashtable_params nf_nat_bysource_params = { 202 - .head_offset = offsetof(struct nf_conn, nat_bysource), 203 - .obj_hashfn = nf_nat_bysource_hash, 204 - .obj_cmpfn = nf_nat_bysource_cmp, 205 - .nelem_hint = 256, 206 - .min_size = 1024, 207 - }; 208 - 209 187 /* Only called for SRC manip */ 210 188 static int 211 189 find_appropriate_src(struct net *net, ··· 194 216 struct nf_conntrack_tuple *result, 195 217 const struct nf_nat_range *range) 196 218 { 219 + unsigned int h = hash_by_src(net, tuple); 197 220 const struct nf_conn *ct; 198 - struct nf_nat_conn_key key = { 199 - .net = net, 200 - .tuple = tuple, 201 - .zone = zone 202 - }; 203 - struct rhlist_head *hl, *h; 204 221 205 - hl = rhltable_lookup(&nf_nat_bysource_table, &key, 206 - nf_nat_bysource_params); 222 + hlist_for_each_entry_rcu(ct, &nf_nat_bysource[h], nat_bysource) { 223 + if (same_src(ct, tuple) && 224 + net_eq(net, nf_ct_net(ct)) && 225 + nf_ct_zone_equal(ct, zone, IP_CT_DIR_ORIGINAL)) { 226 + /* Copy source part from reply tuple. */ 227 + nf_ct_invert_tuplepr(result, 228 + &ct->tuplehash[IP_CT_DIR_REPLY].tuple); 229 + result->dst = tuple->dst; 207 230 208 - rhl_for_each_entry_rcu(ct, h, hl, nat_bysource) { 209 - nf_ct_invert_tuplepr(result, 210 - &ct->tuplehash[IP_CT_DIR_REPLY].tuple); 211 - result->dst = tuple->dst; 212 - 213 - if (in_range(l3proto, l4proto, result, range)) 214 - return 1; 231 + if (in_range(l3proto, l4proto, result, range)) 232 + return 1; 233 + } 215 234 } 216 - 217 235 return 0; 218 236 } 219 237 ··· 382 408 const struct nf_nat_range *range, 383 409 enum nf_nat_manip_type maniptype) 384 410 { 411 + struct net *net = nf_ct_net(ct); 385 412 struct nf_conntrack_tuple curr_tuple, new_tuple; 386 413 387 414 /* Can't setup nat info for confirmed ct. */ ··· 391 416 392 417 WARN_ON(maniptype != NF_NAT_MANIP_SRC && 393 418 maniptype != NF_NAT_MANIP_DST); 394 - BUG_ON(nf_nat_initialized(ct, maniptype)); 419 + 420 + if (WARN_ON(nf_nat_initialized(ct, maniptype))) 421 + return NF_DROP; 395 422 396 423 /* What we've got will look like inverse of reply. Normally 397 424 * this is what is in the conntrack, except for prior ··· 424 447 } 425 448 426 449 if (maniptype == NF_NAT_MANIP_SRC) { 427 - struct nf_nat_conn_key key = { 428 - .net = nf_ct_net(ct), 429 - .tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple, 430 - .zone = nf_ct_zone(ct), 431 - }; 432 - int err; 450 + unsigned int srchash; 451 + spinlock_t *lock; 433 452 434 - err = rhltable_insert_key(&nf_nat_bysource_table, 435 - &key, 436 - &ct->nat_bysource, 437 - nf_nat_bysource_params); 438 - if (err) 439 - return NF_DROP; 453 + srchash = hash_by_src(net, 454 + &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); 455 + lock = &nf_nat_locks[srchash % ARRAY_SIZE(nf_nat_locks)]; 456 + spin_lock_bh(lock); 457 + hlist_add_head_rcu(&ct->nat_bysource, 458 + &nf_nat_bysource[srchash]); 459 + spin_unlock_bh(lock); 440 460 } 441 461 442 462 /* It's done. */ ··· 527 553 return i->status & IPS_NAT_MASK ? 1 : 0; 528 554 } 529 555 556 + static void __nf_nat_cleanup_conntrack(struct nf_conn *ct) 557 + { 558 + unsigned int h; 559 + 560 + h = hash_by_src(nf_ct_net(ct), &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); 561 + spin_lock_bh(&nf_nat_locks[h % ARRAY_SIZE(nf_nat_locks)]); 562 + hlist_del_rcu(&ct->nat_bysource); 563 + spin_unlock_bh(&nf_nat_locks[h % ARRAY_SIZE(nf_nat_locks)]); 564 + } 565 + 530 566 static int nf_nat_proto_clean(struct nf_conn *ct, void *data) 531 567 { 532 568 if (nf_nat_proto_remove(ct, data)) ··· 552 568 * will delete entry from already-freed table. 553 569 */ 554 570 clear_bit(IPS_SRC_NAT_DONE_BIT, &ct->status); 555 - rhltable_remove(&nf_nat_bysource_table, &ct->nat_bysource, 556 - nf_nat_bysource_params); 571 + __nf_nat_cleanup_conntrack(ct); 557 572 558 573 /* don't delete conntrack. Although that would make things a lot 559 574 * simpler, we'd end up flushing all conntracks on nat rmmod. ··· 681 698 static void nf_nat_cleanup_conntrack(struct nf_conn *ct) 682 699 { 683 700 if (ct->status & IPS_SRC_NAT_DONE) 684 - rhltable_remove(&nf_nat_bysource_table, &ct->nat_bysource, 685 - nf_nat_bysource_params); 701 + __nf_nat_cleanup_conntrack(ct); 686 702 } 687 703 688 704 static struct nf_ct_ext_type nat_extend __read_mostly = { ··· 803 821 804 822 static int __init nf_nat_init(void) 805 823 { 806 - int ret; 824 + int ret, i; 807 825 808 - ret = rhltable_init(&nf_nat_bysource_table, &nf_nat_bysource_params); 809 - if (ret) 810 - return ret; 826 + /* Leave them the same for the moment. */ 827 + nf_nat_htable_size = nf_conntrack_htable_size; 828 + if (nf_nat_htable_size < ARRAY_SIZE(nf_nat_locks)) 829 + nf_nat_htable_size = ARRAY_SIZE(nf_nat_locks); 830 + 831 + nf_nat_bysource = nf_ct_alloc_hashtable(&nf_nat_htable_size, 0); 832 + if (!nf_nat_bysource) 833 + return -ENOMEM; 811 834 812 835 ret = nf_ct_extend_register(&nat_extend); 813 836 if (ret < 0) { 814 - rhltable_destroy(&nf_nat_bysource_table); 837 + nf_ct_free_hashtable(nf_nat_bysource, nf_nat_htable_size); 815 838 printk(KERN_ERR "nf_nat_core: Unable to register extension\n"); 816 839 return ret; 817 840 } 841 + 842 + for (i = 0; i < ARRAY_SIZE(nf_nat_locks); i++) 843 + spin_lock_init(&nf_nat_locks[i]); 818 844 819 845 nf_ct_helper_expectfn_register(&follow_master_nat); 820 846 ··· 853 863 854 864 for (i = 0; i < NFPROTO_NUMPROTO; i++) 855 865 kfree(nf_nat_l4protos[i]); 856 - 857 - rhltable_destroy(&nf_nat_bysource_table); 866 + synchronize_net(); 867 + nf_ct_free_hashtable(nf_nat_bysource, nf_nat_htable_size); 858 868 } 859 869 860 870 MODULE_LICENSE("GPL");
+9 -7
net/netfilter/xt_hashlimit.c
··· 35 35 #include <linux/netfilter_ipv6/ip6_tables.h> 36 36 #include <linux/netfilter/xt_hashlimit.h> 37 37 #include <linux/mutex.h> 38 + #include <linux/kernel.h> 38 39 39 40 MODULE_LICENSE("GPL"); 40 41 MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); ··· 280 279 size = cfg->size; 281 280 } else { 282 281 size = (totalram_pages << PAGE_SHIFT) / 16384 / 283 - sizeof(struct list_head); 282 + sizeof(struct hlist_head); 284 283 if (totalram_pages > 1024 * 1024 * 1024 / PAGE_SIZE) 285 284 size = 8192; 286 285 if (size < 16) ··· 288 287 } 289 288 /* FIXME: don't use vmalloc() here or anywhere else -HW */ 290 289 hinfo = vmalloc(sizeof(struct xt_hashlimit_htable) + 291 - sizeof(struct list_head) * size); 290 + sizeof(struct hlist_head) * size); 292 291 if (hinfo == NULL) 293 292 return -ENOMEM; 294 293 *out_hinfo = hinfo; ··· 528 527 } 529 528 } 530 529 531 - static u64 user2rate_bytes(u64 user) 530 + static u64 user2rate_bytes(u32 user) 532 531 { 533 532 u64 r; 534 533 535 - r = user ? 0xFFFFFFFFULL / user : 0xFFFFFFFFULL; 536 - r = (r - 1) << 4; 534 + r = user ? U32_MAX / user : U32_MAX; 535 + r = (r - 1) << XT_HASHLIMIT_BYTE_SHIFT; 537 536 return r; 538 537 } 539 538 ··· 589 588 dh->rateinfo.prev_window = 0; 590 589 dh->rateinfo.current_rate = 0; 591 590 if (hinfo->cfg.mode & XT_HASHLIMIT_BYTES) { 592 - dh->rateinfo.rate = user2rate_bytes(hinfo->cfg.avg); 591 + dh->rateinfo.rate = 592 + user2rate_bytes((u32)hinfo->cfg.avg); 593 593 if (hinfo->cfg.burst) 594 594 dh->rateinfo.burst = 595 595 hinfo->cfg.burst * dh->rateinfo.rate; ··· 872 870 873 871 /* Check for overflow. */ 874 872 if (revision >= 3 && cfg->mode & XT_HASHLIMIT_RATE_MATCH) { 875 - if (cfg->avg == 0) { 873 + if (cfg->avg == 0 || cfg->avg > U32_MAX) { 876 874 pr_info("hashlimit invalid rate\n"); 877 875 return -ERANGE; 878 876 }
+15 -7
net/netlink/af_netlink.c
··· 691 691 struct netlink_sock *nlk = container_of(head, struct netlink_sock, rcu); 692 692 struct sock *sk = &nlk->sk; 693 693 694 + kfree(nlk->groups); 695 + nlk->groups = NULL; 696 + 694 697 if (!refcount_dec_and_test(&sk->sk_refcnt)) 695 698 return; 696 699 ··· 771 768 } 772 769 netlink_table_ungrab(); 773 770 } 774 - 775 - kfree(nlk->groups); 776 - nlk->groups = NULL; 777 771 778 772 local_bh_disable(); 779 773 sock_prot_inuse_add(sock_net(sk), &netlink_proto, -1); ··· 955 955 struct net *net = sock_net(sk); 956 956 struct netlink_sock *nlk = nlk_sk(sk); 957 957 struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr; 958 - int err; 958 + int err = 0; 959 959 long unsigned int groups = nladdr->nl_groups; 960 960 bool bound; 961 961 ··· 983 983 return -EINVAL; 984 984 } 985 985 986 + netlink_lock_table(); 986 987 if (nlk->netlink_bind && groups) { 987 988 int group; 988 989 ··· 994 993 if (!err) 995 994 continue; 996 995 netlink_undo_bind(group, groups, sk); 997 - return err; 996 + goto unlock; 998 997 } 999 998 } 1000 999 ··· 1007 1006 netlink_autobind(sock); 1008 1007 if (err) { 1009 1008 netlink_undo_bind(nlk->ngroups, groups, sk); 1010 - return err; 1009 + goto unlock; 1011 1010 } 1012 1011 } 1013 1012 1014 1013 if (!groups && (nlk->groups == NULL || !(u32)nlk->groups[0])) 1015 - return 0; 1014 + goto unlock; 1015 + netlink_unlock_table(); 1016 1016 1017 1017 netlink_table_grab(); 1018 1018 netlink_update_subscriptions(sk, nlk->subscriptions + ··· 1024 1022 netlink_table_ungrab(); 1025 1023 1026 1024 return 0; 1025 + 1026 + unlock: 1027 + netlink_unlock_table(); 1028 + return err; 1027 1029 } 1028 1030 1029 1031 static int netlink_connect(struct socket *sock, struct sockaddr *addr, ··· 1085 1079 nladdr->nl_groups = netlink_group_mask(nlk->dst_group); 1086 1080 } else { 1087 1081 nladdr->nl_pid = nlk->portid; 1082 + netlink_lock_table(); 1088 1083 nladdr->nl_groups = nlk->groups ? nlk->groups[0] : 0; 1084 + netlink_unlock_table(); 1089 1085 } 1090 1086 return 0; 1091 1087 }
+7 -3
net/rds/send.c
··· 428 428 * some work and we will skip our goto 429 429 */ 430 430 if (ret == 0) { 431 + bool raced; 432 + 431 433 smp_mb(); 434 + raced = send_gen != READ_ONCE(cp->cp_send_gen); 435 + 432 436 if ((test_bit(0, &conn->c_map_queued) || 433 - !list_empty(&cp->cp_send_queue)) && 434 - send_gen == READ_ONCE(cp->cp_send_gen)) { 435 - rds_stats_inc(s_send_lock_queue_raced); 437 + !list_empty(&cp->cp_send_queue)) && !raced) { 436 438 if (batch_count < send_batch_count) 437 439 goto restart; 438 440 queue_delayed_work(rds_wq, &cp->cp_send_w, 1); 441 + } else if (raced) { 442 + rds_stats_inc(s_send_lock_queue_raced); 439 443 } 440 444 } 441 445 out:
+9 -9
net/sched/cls_api.c
··· 182 182 list_add_tail(&chain->list, &block->chain_list); 183 183 chain->block = block; 184 184 chain->index = chain_index; 185 - chain->refcnt = 1; 185 + chain->refcnt = 0; 186 186 return chain; 187 187 } 188 188 ··· 217 217 struct tcf_chain *chain; 218 218 219 219 list_for_each_entry(chain, &block->chain_list, list) { 220 - if (chain->index == chain_index) { 221 - chain->refcnt++; 222 - return chain; 223 - } 220 + if (chain->index == chain_index) 221 + goto incref; 224 222 } 225 - if (create) 226 - return tcf_chain_create(block, chain_index); 227 - else 228 - return NULL; 223 + chain = create ? tcf_chain_create(block, chain_index) : NULL; 224 + 225 + incref: 226 + if (chain) 227 + chain->refcnt++; 228 + return chain; 229 229 } 230 230 EXPORT_SYMBOL(tcf_chain_get); 231 231
+1 -1
net/sched/sch_prio.c
··· 80 80 81 81 if (ret & __NET_XMIT_BYPASS) 82 82 qdisc_qstats_drop(sch); 83 - kfree_skb(skb); 83 + __qdisc_drop(skb, to_free); 84 84 return ret; 85 85 } 86 86 #endif
+1 -1
net/sched/sch_qfq.c
··· 1215 1215 if (cl == NULL) { 1216 1216 if (err & __NET_XMIT_BYPASS) 1217 1217 qdisc_qstats_drop(sch); 1218 - kfree_skb(skb); 1218 + __qdisc_drop(skb, to_free); 1219 1219 return err; 1220 1220 } 1221 1221 pr_debug("qfq_enqueue: cl = %x\n", cl->common.classid);
+2 -1
net/sctp/ulpqueue.c
··· 265 265 sctp_ulpq_clear_pd(ulpq); 266 266 267 267 if (queue == &sk->sk_receive_queue && !sp->data_ready_signalled) { 268 - sp->data_ready_signalled = 1; 268 + if (!sock_owned_by_user(sk)) 269 + sp->data_ready_signalled = 1; 269 270 sk->sk_data_ready(sk); 270 271 } 271 272 return 1;
+1 -1
net/tipc/bearer.c
··· 637 637 break; 638 638 case NETDEV_UNREGISTER: 639 639 case NETDEV_CHANGENAME: 640 - bearer_disable(dev_net(dev), b); 640 + bearer_disable(net, b); 641 641 break; 642 642 } 643 643 return NOTIFY_OK;
+2 -2
net/wireless/nl80211.c
··· 3791 3791 static void nl80211_calculate_ap_params(struct cfg80211_ap_settings *params) 3792 3792 { 3793 3793 const struct cfg80211_beacon_data *bcn = &params->beacon; 3794 - size_t ies_len = bcn->beacon_ies_len; 3795 - const u8 *ies = bcn->beacon_ies; 3794 + size_t ies_len = bcn->tail_len; 3795 + const u8 *ies = bcn->tail; 3796 3796 const u8 *rates; 3797 3797 const u8 *cap; 3798 3798
+18 -2
net/wireless/reg.c
··· 4 4 * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> 5 5 * Copyright 2008-2011 Luis R. Rodriguez <mcgrof@qca.qualcomm.com> 6 6 * Copyright 2013-2014 Intel Mobile Communications GmbH 7 + * Copyright 2017 Intel Deutschland GmbH 7 8 * 8 9 * Permission to use, copy, modify, and/or distribute this software for any 9 10 * purpose with or without fee is hereby granted, provided that the above ··· 1484 1483 { 1485 1484 struct ieee80211_supported_band *sband = wiphy->bands[channel->band]; 1486 1485 struct ieee80211_channel *channel_before = NULL, *channel_after = NULL; 1486 + const struct ieee80211_regdomain *regd; 1487 1487 unsigned int i; 1488 + u32 flags; 1488 1489 1489 1490 if (!is_ht40_allowed(channel)) { 1490 1491 channel->flags |= IEEE80211_CHAN_NO_HT40; ··· 1506 1503 channel_after = c; 1507 1504 } 1508 1505 1506 + flags = 0; 1507 + regd = get_wiphy_regdom(wiphy); 1508 + if (regd) { 1509 + const struct ieee80211_reg_rule *reg_rule = 1510 + freq_reg_info_regd(MHZ_TO_KHZ(channel->center_freq), 1511 + regd, MHZ_TO_KHZ(20)); 1512 + 1513 + if (!IS_ERR(reg_rule)) 1514 + flags = reg_rule->flags; 1515 + } 1516 + 1509 1517 /* 1510 1518 * Please note that this assumes target bandwidth is 20 MHz, 1511 1519 * if that ever changes we also need to change the below logic 1512 1520 * to include that as well. 1513 1521 */ 1514 - if (!is_ht40_allowed(channel_before)) 1522 + if (!is_ht40_allowed(channel_before) || 1523 + flags & NL80211_RRF_NO_HT40MINUS) 1515 1524 channel->flags |= IEEE80211_CHAN_NO_HT40MINUS; 1516 1525 else 1517 1526 channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS; 1518 1527 1519 - if (!is_ht40_allowed(channel_after)) 1528 + if (!is_ht40_allowed(channel_after) || 1529 + flags & NL80211_RRF_NO_HT40PLUS) 1520 1530 channel->flags |= IEEE80211_CHAN_NO_HT40PLUS; 1521 1531 else 1522 1532 channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
+50 -1
tools/testing/selftests/bpf/test_maps.c
··· 558 558 } 559 559 } 560 560 561 - /* Test attaching bad fds */ 561 + /* Test attaching/detaching bad fds */ 562 562 err = bpf_prog_attach(-1, fd, BPF_SK_SKB_STREAM_PARSER, 0); 563 563 if (!err) { 564 564 printf("Failed invalid parser prog attach\n"); ··· 568 568 err = bpf_prog_attach(-1, fd, BPF_SK_SKB_STREAM_VERDICT, 0); 569 569 if (!err) { 570 570 printf("Failed invalid verdict prog attach\n"); 571 + goto out_sockmap; 572 + } 573 + 574 + err = bpf_prog_attach(-1, fd, __MAX_BPF_ATTACH_TYPE, 0); 575 + if (!err) { 576 + printf("Failed unknown prog attach\n"); 577 + goto out_sockmap; 578 + } 579 + 580 + err = bpf_prog_detach(fd, BPF_SK_SKB_STREAM_PARSER); 581 + if (err) { 582 + printf("Failed empty parser prog detach\n"); 583 + goto out_sockmap; 584 + } 585 + 586 + err = bpf_prog_detach(fd, BPF_SK_SKB_STREAM_VERDICT); 587 + if (err) { 588 + printf("Failed empty verdict prog detach\n"); 589 + goto out_sockmap; 590 + } 591 + 592 + err = bpf_prog_detach(fd, __MAX_BPF_ATTACH_TYPE); 593 + if (!err) { 594 + printf("Detach invalid prog successful\n"); 571 595 goto out_sockmap; 572 596 } 573 597 ··· 664 640 BPF_SK_SKB_STREAM_VERDICT, 0); 665 641 if (err) { 666 642 printf("Failed stream verdict bpf prog attach\n"); 643 + goto out_sockmap; 644 + } 645 + 646 + err = bpf_prog_attach(verdict_prog, map_fd_rx, 647 + __MAX_BPF_ATTACH_TYPE, 0); 648 + if (!err) { 649 + printf("Attached unknown bpf prog\n"); 667 650 goto out_sockmap; 668 651 } 669 652 ··· 838 807 839 808 assert(waitpid(pid[i], &status, 0) == pid[i]); 840 809 assert(status == 0); 810 + } 811 + 812 + err = bpf_prog_detach(map_fd_rx, __MAX_BPF_ATTACH_TYPE); 813 + if (!err) { 814 + printf("Detached an invalid prog type.\n"); 815 + goto out_sockmap; 816 + } 817 + 818 + err = bpf_prog_detach(map_fd_rx, BPF_SK_SKB_STREAM_PARSER); 819 + if (err) { 820 + printf("Failed parser prog detach\n"); 821 + goto out_sockmap; 822 + } 823 + 824 + err = bpf_prog_detach(map_fd_rx, BPF_SK_SKB_STREAM_VERDICT); 825 + if (err) { 826 + printf("Failed parser prog detach\n"); 827 + goto out_sockmap; 841 828 } 842 829 843 830 /* Test map close sockets */