Pull networking fixes from Jakub Kicinski: "Including fixes from BPF, netfilter, bluetooth and CAN. Current release - regressions: - eth: r8169: multiple fixes for PCIe ASPM-related problems - vrf: fix RCU lockdep splat in output path Previous releases - regressions: - gso: fall back to SW segmenting with GSO_UDP_L4 dodgy bit set - dsa: mv88e6xxx: do a final check before timing out when polling - nf_tables: fix sleep in atomic in nft_chain_validate Previous releases - always broken: - sched: fix undoing tcf_bind_filter() in multiple classifiers - bpf, arm64: fix BTI type used for freplace attached functions - can: gs_usb: fix time stamp counter initialization - nft_set_pipapo: fix improper element removal (leading to UAF) Misc: - net: support STP on bridge in non-root netns, STP prevents packet loops so not supporting it results in freezing systems of unsuspecting users, and in turn very upset noises being made - fix kdoc warnings - annotate various bits of TCP state to prevent data races" * tag 'net-6.5-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (95 commits) net: phy: prevent stale pointer dereference in phy_init() tcp: annotate data-races around fastopenq.max_qlen tcp: annotate data-races around icsk->icsk_user_timeout tcp: annotate data-races around tp->notsent_lowat tcp: annotate data-races around rskq_defer_accept tcp: annotate data-races around tp->linger2 tcp: annotate data-races around icsk->icsk_syn_retries tcp: annotate data-races around tp->keepalive_probes tcp: annotate data-races around tp->keepalive_intvl tcp: annotate data-races around tp->keepalive_time tcp: annotate data-races around tp->tsoffset tcp: annotate data-races around tp->tcp_tx_delay Bluetooth: MGMT: Use correct address for memcpy() Bluetooth: btusb: Fix bluetooth on Intel Macbook 2014 Bluetooth: SCO: fix sco_conn related locking and validity issues Bluetooth: hci_conn: return ERR_PTR instead of NULL when there is no link Bluetooth: hci_sync: Avoid use-after-free in dbg for hci_remove_adv_monitor() Bluetooth: coredump: fix building with coredump disabled Bluetooth: ISO: fix iso_conn related locking and validity issues Bluetooth: hci_event: call disconnect callback before deleting conn ...
Unified · Split
| @@ -241,6 +241,7 @@ Jisheng Zhang <jszhang@kernel.org> <Jisheng.Zhang@synaptics.com> · 240 unmodified lines | |||
| 241 | Johan Hovold <johan@kernel.org> <jhovold@gmail.com> | 241 | Johan Hovold <johan@kernel.org> <jhovold@gmail.com> |
| 242 | Johan Hovold <johan@kernel.org> <johan@hovoldconsulting.com> | 242 | Johan Hovold <johan@kernel.org> <johan@hovoldconsulting.com> |
| 243 | John Crispin <john@phrozen.org> <blogic@openwrt.org> | 243 | John Crispin <john@phrozen.org> <blogic@openwrt.org> |
| 244 | John Fastabend <john.fastabend@gmail.com> <john.r.fastabend@intel.com> | ||
| 244 | John Keeping <john@keeping.me.uk> <john@metanate.com> | 245 | John Keeping <john@keeping.me.uk> <john@metanate.com> |
| 245 | John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de> | 246 | John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de> |
| 246 | John Stultz <johnstul@us.ibm.com> | 247 | John Stultz <johnstul@us.ibm.com> |
| @@ -454,6 +455,8 @@ Sebastian Reichel <sre@kernel.org> <sre@debian.org> · 207 unmodified lines | |||
| 454 | Sedat Dilek <sedat.dilek@gmail.com> <sedat.dilek@credativ.de> | 455 | Sedat Dilek <sedat.dilek@gmail.com> <sedat.dilek@credativ.de> |
| 455 | Seth Forshee <sforshee@kernel.org> <seth.forshee@canonical.com> | 456 | Seth Forshee <sforshee@kernel.org> <seth.forshee@canonical.com> |
| 456 | Shannon Nelson <shannon.nelson@amd.com> <snelson@pensando.io> | 457 | Shannon Nelson <shannon.nelson@amd.com> <snelson@pensando.io> |
| 458 | Shannon Nelson <shannon.nelson@amd.com> <shannon.nelson@intel.com> | ||
| 459 | Shannon Nelson <shannon.nelson@amd.com> <shannon.nelson@oracle.com> | ||
| 457 | Shiraz Hashim <shiraz.linux.kernel@gmail.com> <shiraz.hashim@st.com> | 460 | Shiraz Hashim <shiraz.linux.kernel@gmail.com> <shiraz.hashim@st.com> |
| 458 | Shuah Khan <shuah@kernel.org> <shuahkhan@gmail.com> | 461 | Shuah Khan <shuah@kernel.org> <shuahkhan@gmail.com> |
| 459 | Shuah Khan <shuah@kernel.org> <shuah.khan@hp.com> | 462 | Shuah Khan <shuah@kernel.org> <shuah.khan@hp.com> |
| @@ -322,7 +322,13 @@ static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf) · 321 unmodified lines | |||
| 322 | * | 322 | * |
| 323 | */ | 323 | */ |
| 324 | 324 | ||
| 325 | emit_bti(A64_BTI_C, ctx); | 325 | /* bpf function may be invoked by 3 instruction types: |
| 326 | * 1. bl, attached via freplace to bpf prog via short jump | ||
| 327 | * 2. br, attached via freplace to bpf prog via long jump | ||
| 328 | * 3. blr, working as a function pointer, used by emit_call. | ||
| 329 | * So BTI_JC should used here to support both br and blr. | ||
| 330 | */ | ||
| 331 | emit_bti(A64_BTI_JC, ctx); | ||
| 326 | 332 | ||
| 327 | emit(A64_MOV(1, A64_R(9), A64_LR), ctx); | 333 | emit(A64_MOV(1, A64_R(9), A64_LR), ctx); |
| 328 | emit(A64_NOP, ctx); | 334 | emit(A64_NOP, ctx); |
| @@ -4104,6 +4104,7 @@ static int btusb_probe(struct usb_interface *intf, · 4103 unmodified lines | |||
| 4104 | BT_DBG("intf %p id %p", intf, id); | 4104 | BT_DBG("intf %p id %p", intf, id); |
| 4105 | 4105 | ||
| 4106 | if ((id->driver_info & BTUSB_IFNUM_2) && | 4106 | if ((id->driver_info & BTUSB_IFNUM_2) && |
| 4107 | (intf->cur_altsetting->desc.bInterfaceNumber != 0) && | ||
| 4107 | (intf->cur_altsetting->desc.bInterfaceNumber != 2)) | 4108 | (intf->cur_altsetting->desc.bInterfaceNumber != 2)) |
| 4108 | return -ENODEV; | 4109 | return -ENODEV; |
| 4109 | 4110 | ||
| @@ -227,6 +227,8 @@ static int · 226 unmodified lines | |||
| 227 | __mcp251xfd_chip_set_mode(const struct mcp251xfd_priv *priv, | 227 | __mcp251xfd_chip_set_mode(const struct mcp251xfd_priv *priv, |
| 228 | const u8 mode_req, bool nowait) | 228 | const u8 mode_req, bool nowait) |
| 229 | { | 229 | { |
| 230 | const struct can_bittiming *bt = &priv->can.bittiming; | ||
| 231 | unsigned long timeout_us = MCP251XFD_POLL_TIMEOUT_US; | ||
| 230 | u32 con = 0, con_reqop, osc = 0; | 232 | u32 con = 0, con_reqop, osc = 0; |
| 231 | u8 mode; | 233 | u8 mode; |
| 232 | int err; | 234 | int err; |
| @@ -246,12 +248,16 @@ __mcp251xfd_chip_set_mode(const struct mcp251xfd_priv *priv, · 13 unmodified lines | |||
| 246 | if (mode_req == MCP251XFD_REG_CON_MODE_SLEEP || nowait) | 248 | if (mode_req == MCP251XFD_REG_CON_MODE_SLEEP || nowait) |
| 247 | return 0; | 249 | return 0; |
| 248 | 250 | ||
| 251 | if (bt->bitrate) | ||
| 252 | timeout_us = max_t(unsigned long, timeout_us, | ||
| 253 | MCP251XFD_FRAME_LEN_MAX_BITS * USEC_PER_SEC / | ||
| 254 | bt->bitrate); | ||
| 255 | |||
| 249 | err = regmap_read_poll_timeout(priv->map_reg, MCP251XFD_REG_CON, con, | 256 | err = regmap_read_poll_timeout(priv->map_reg, MCP251XFD_REG_CON, con, |
| 250 | !mcp251xfd_reg_invalid(con) && | 257 | !mcp251xfd_reg_invalid(con) && |
| 251 | FIELD_GET(MCP251XFD_REG_CON_OPMOD_MASK, | 258 | FIELD_GET(MCP251XFD_REG_CON_OPMOD_MASK, |
| 252 | con) == mode_req, | 259 | con) == mode_req, |
| 253 | MCP251XFD_POLL_SLEEP_US, | 260 | MCP251XFD_POLL_SLEEP_US, timeout_us); |
| 254 | MCP251XFD_POLL_TIMEOUT_US); | ||
| 255 | if (err != -ETIMEDOUT && err != -EBADMSG) | 261 | if (err != -ETIMEDOUT && err != -EBADMSG) |
| 256 | return err; | 262 | return err; |
| 257 | 263 | ||
| @@ -387,6 +387,7 @@ static_assert(MCP251XFD_TIMESTAMP_WORK_DELAY_SEC < · 386 unmodified lines | |||
| 387 | #define MCP251XFD_OSC_STAB_TIMEOUT_US (10 * MCP251XFD_OSC_STAB_SLEEP_US) | 387 | #define MCP251XFD_OSC_STAB_TIMEOUT_US (10 * MCP251XFD_OSC_STAB_SLEEP_US) |
| 388 | #define MCP251XFD_POLL_SLEEP_US (10) | 388 | #define MCP251XFD_POLL_SLEEP_US (10) |
| 389 | #define MCP251XFD_POLL_TIMEOUT_US (USEC_PER_MSEC) | 389 | #define MCP251XFD_POLL_TIMEOUT_US (USEC_PER_MSEC) |
| 390 | #define MCP251XFD_FRAME_LEN_MAX_BITS (736) | ||
| 390 | 391 | ||
| 391 | /* Misc */ | 392 | /* Misc */ |
| 392 | #define MCP251XFD_NAPI_WEIGHT 32 | 393 | #define MCP251XFD_NAPI_WEIGHT 32 |
| @@ -303,12 +303,6 @@ struct gs_can { · 302 unmodified lines | |||
| 303 | struct can_bittiming_const bt_const, data_bt_const; | 303 | struct can_bittiming_const bt_const, data_bt_const; |
| 304 | unsigned int channel; /* channel number */ | 304 | unsigned int channel; /* channel number */ |
| 305 | 305 | ||
| 306 | /* time counter for hardware timestamps */ | ||
| 307 | struct cyclecounter cc; | ||
| 308 | struct timecounter tc; | ||
| 309 | spinlock_t tc_lock; /* spinlock to guard access tc->cycle_last */ | ||
| 310 | struct delayed_work timestamp; | ||
| 311 | |||
| 312 | u32 feature; | 306 | u32 feature; |
| 313 | unsigned int hf_size_tx; | 307 | unsigned int hf_size_tx; |
| 314 | 308 | ||
| @@ -325,6 +319,13 @@ struct gs_usb { · 10 unmodified lines | |||
| 325 | struct gs_can *canch[GS_MAX_INTF]; | 319 | struct gs_can *canch[GS_MAX_INTF]; |
| 326 | struct usb_anchor rx_submitted; | 320 | struct usb_anchor rx_submitted; |
| 327 | struct usb_device *udev; | 321 | struct usb_device *udev; |
| 322 | |||
| 323 | /* time counter for hardware timestamps */ | ||
| 324 | struct cyclecounter cc; | ||
| 325 | struct timecounter tc; | ||
| 326 | spinlock_t tc_lock; /* spinlock to guard access tc->cycle_last */ | ||
| 327 | struct delayed_work timestamp; | ||
| 328 | |||
| 328 | unsigned int hf_size_rx; | 329 | unsigned int hf_size_rx; |
| 329 | u8 active_channels; | 330 | u8 active_channels; |
| 330 | }; | 331 | }; |
| @@ -388,15 +389,15 @@ static int gs_cmd_reset(struct gs_can *dev) · 57 unmodified lines | |||
| 388 | GFP_KERNEL); | 389 | GFP_KERNEL); |
| 389 | } | 390 | } |
| 390 | 391 | ||
| 391 | static inline int gs_usb_get_timestamp(const struct gs_can *dev, | 392 | static inline int gs_usb_get_timestamp(const struct gs_usb *parent, |
| 392 | u32 *timestamp_p) | 393 | u32 *timestamp_p) |
| 393 | { | 394 | { |
| 394 | __le32 timestamp; | 395 | __le32 timestamp; |
| 395 | int rc; | 396 | int rc; |
| 396 | 397 | ||
| 397 | rc = usb_control_msg_recv(dev->udev, 0, GS_USB_BREQ_TIMESTAMP, | 398 | rc = usb_control_msg_recv(parent->udev, 0, GS_USB_BREQ_TIMESTAMP, |
| 398 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, | 399 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, |
| 399 | dev->channel, 0, | 400 | 0, 0, |
| 400 | ×tamp, sizeof(timestamp), | 401 | ×tamp, sizeof(timestamp), |
| 401 | USB_CTRL_GET_TIMEOUT, | 402 | USB_CTRL_GET_TIMEOUT, |
| 402 | GFP_KERNEL); | 403 | GFP_KERNEL); |
| @@ -410,20 +411,20 @@ static inline int gs_usb_get_timestamp(const struct gs_can *dev, · 7 unmodified lines | |||
| 410 | 411 | ||
| 411 | static u64 gs_usb_timestamp_read(const struct cyclecounter *cc) __must_hold(&dev->tc_lock) | 412 | static u64 gs_usb_timestamp_read(const struct cyclecounter *cc) __must_hold(&dev->tc_lock) |
| 412 | { | 413 | { |
| 413 | struct gs_can *dev = container_of(cc, struct gs_can, cc); | 414 | struct gs_usb *parent = container_of(cc, struct gs_usb, cc); |
| 414 | u32 timestamp = 0; | 415 | u32 timestamp = 0; |
| 415 | int err; | 416 | int err; |
| 416 | 417 | ||
| 417 | lockdep_assert_held(&dev->tc_lock); | 418 | lockdep_assert_held(&parent->tc_lock); |
| 418 | 419 | ||
| 419 | /* drop lock for synchronous USB transfer */ | 420 | /* drop lock for synchronous USB transfer */ |
| 420 | spin_unlock_bh(&dev->tc_lock); | 421 | spin_unlock_bh(&parent->tc_lock); |
| 421 | err = gs_usb_get_timestamp(dev, ×tamp); | 422 | err = gs_usb_get_timestamp(parent, ×tamp); |
| 422 | spin_lock_bh(&dev->tc_lock); | 423 | spin_lock_bh(&parent->tc_lock); |
| 423 | if (err) | 424 | if (err) |
| 424 | netdev_err(dev->netdev, | 425 | dev_err(&parent->udev->dev, |
| 425 | "Error %d while reading timestamp. HW timestamps may be inaccurate.", | 426 | "Error %d while reading timestamp. HW timestamps may be inaccurate.", |
| 426 | err); | 427 | err); |
| 427 | 428 | ||
| 428 | return timestamp; | 429 | return timestamp; |
| 429 | } | 430 | } |
| @@ -431,14 +432,14 @@ static u64 gs_usb_timestamp_read(const struct cyclecounter *cc) __must_hold(&dev · 1 unmodified line | |||
| 431 | static void gs_usb_timestamp_work(struct work_struct *work) | 432 | static void gs_usb_timestamp_work(struct work_struct *work) |
| 432 | { | 433 | { |
| 433 | struct delayed_work *delayed_work = to_delayed_work(work); | 434 | struct delayed_work *delayed_work = to_delayed_work(work); |
| 434 | struct gs_can *dev; | 435 | struct gs_usb *parent; |
| 435 | 436 | ||
| 436 | dev = container_of(delayed_work, struct gs_can, timestamp); | 437 | parent = container_of(delayed_work, struct gs_usb, timestamp); |
| 437 | spin_lock_bh(&dev->tc_lock); | 438 | spin_lock_bh(&parent->tc_lock); |
| 438 | timecounter_read(&dev->tc); | 439 | timecounter_read(&parent->tc); |
| 439 | spin_unlock_bh(&dev->tc_lock); | 440 | spin_unlock_bh(&parent->tc_lock); |
| 440 | 441 | ||
| 441 | schedule_delayed_work(&dev->timestamp, | 442 | schedule_delayed_work(&parent->timestamp, |
| 442 | GS_USB_TIMESTAMP_WORK_DELAY_SEC * HZ); | 443 | GS_USB_TIMESTAMP_WORK_DELAY_SEC * HZ); |
| 443 | } | 444 | } |
| 444 | 445 | ||
| @@ -446,37 +447,38 @@ static void gs_usb_skb_set_timestamp(struct gs_can *dev, · 1 unmodified line | |||
| 446 | struct sk_buff *skb, u32 timestamp) | 447 | struct sk_buff *skb, u32 timestamp) |
| 447 | { | 448 | { |
| 448 | struct skb_shared_hwtstamps *hwtstamps = skb_hwtstamps(skb); | 449 | struct skb_shared_hwtstamps *hwtstamps = skb_hwtstamps(skb); |
| 450 | struct gs_usb *parent = dev->parent; | ||
| 449 | u64 ns; | 451 | u64 ns; |
| 450 | 452 | ||
| 451 | spin_lock_bh(&dev->tc_lock); | 453 | spin_lock_bh(&parent->tc_lock); |
| 452 | ns = timecounter_cyc2time(&dev->tc, timestamp); | 454 | ns = timecounter_cyc2time(&parent->tc, timestamp); |
| 453 | spin_unlock_bh(&dev->tc_lock); | 455 | spin_unlock_bh(&parent->tc_lock); |
| 454 | 456 | ||
| 455 | hwtstamps->hwtstamp = ns_to_ktime(ns); | 457 | hwtstamps->hwtstamp = ns_to_ktime(ns); |
| 456 | } | 458 | } |
| 457 | 459 | ||
| 458 | static void gs_usb_timestamp_init(struct gs_can *dev) | 460 | static void gs_usb_timestamp_init(struct gs_usb *parent) |
| 459 | { | 461 | { |
| 460 | struct cyclecounter *cc = &dev->cc; | 462 | struct cyclecounter *cc = &parent->cc; |
| 461 | 463 | ||
| 462 | cc->read = gs_usb_timestamp_read; | 464 | cc->read = gs_usb_timestamp_read; |
| 463 | cc->mask = CYCLECOUNTER_MASK(32); | 465 | cc->mask = CYCLECOUNTER_MASK(32); |
| 464 | cc->shift = 32 - bits_per(NSEC_PER_SEC / GS_USB_TIMESTAMP_TIMER_HZ); | 466 | cc->shift = 32 - bits_per(NSEC_PER_SEC / GS_USB_TIMESTAMP_TIMER_HZ); |
| 465 | cc->mult = clocksource_hz2mult(GS_USB_TIMESTAMP_TIMER_HZ, cc->shift); | 467 | cc->mult = clocksource_hz2mult(GS_USB_TIMESTAMP_TIMER_HZ, cc->shift); |
| 466 | 468 | ||
| 467 | spin_lock_init(&dev->tc_lock); | 469 | spin_lock_init(&parent->tc_lock); |
| 468 | spin_lock_bh(&dev->tc_lock); | 470 | spin_lock_bh(&parent->tc_lock); |
| 469 | timecounter_init(&dev->tc, &dev->cc, ktime_get_real_ns()); | 471 | timecounter_init(&parent->tc, &parent->cc, ktime_get_real_ns()); |
| 470 | spin_unlock_bh(&dev->tc_lock); | 472 | spin_unlock_bh(&parent->tc_lock); |
| 471 | 473 | ||
| 472 | INIT_DELAYED_WORK(&dev->timestamp, gs_usb_timestamp_work); | 474 | INIT_DELAYED_WORK(&parent->timestamp, gs_usb_timestamp_work); |
| 473 | schedule_delayed_work(&dev->timestamp, | 475 | schedule_delayed_work(&parent->timestamp, |
| 474 | GS_USB_TIMESTAMP_WORK_DELAY_SEC * HZ); | 476 | GS_USB_TIMESTAMP_WORK_DELAY_SEC * HZ); |
| 475 | } | 477 | } |
| 476 | 478 | ||
| 477 | static void gs_usb_timestamp_stop(struct gs_can *dev) | 479 | static void gs_usb_timestamp_stop(struct gs_usb *parent) |
| 478 | { | 480 | { |
| 479 | cancel_delayed_work_sync(&dev->timestamp); | 481 | cancel_delayed_work_sync(&parent->timestamp); |
| 480 | } | 482 | } |
| 481 | 483 | ||
| 482 | static void gs_update_state(struct gs_can *dev, struct can_frame *cf) | 484 | static void gs_update_state(struct gs_can *dev, struct can_frame *cf) |
| @@ -560,6 +562,9 @@ static void gs_usb_receive_bulk_callback(struct urb *urb) · 77 unmodified lines | |||
| 560 | if (!netif_device_present(netdev)) | 562 | if (!netif_device_present(netdev)) |
| 561 | return; | 563 | return; |
| 562 | 564 | ||
| 565 | if (!netif_running(netdev)) | ||
| 566 | goto resubmit_urb; | ||
| 567 | |||
| 563 | if (hf->echo_id == -1) { /* normal rx */ | 568 | if (hf->echo_id == -1) { /* normal rx */ |
| 564 | if (hf->flags & GS_CAN_FLAG_FD) { | 569 | if (hf->flags & GS_CAN_FLAG_FD) { |
| 565 | skb = alloc_canfd_skb(dev->netdev, &cfd); | 570 | skb = alloc_canfd_skb(dev->netdev, &cfd); |
| @@ -833,6 +838,7 @@ static int gs_can_open(struct net_device *netdev) · 267 unmodified lines | |||
| 833 | .mode = cpu_to_le32(GS_CAN_MODE_START), | 838 | .mode = cpu_to_le32(GS_CAN_MODE_START), |
| 834 | }; | 839 | }; |
| 835 | struct gs_host_frame *hf; | 840 | struct gs_host_frame *hf; |
| 841 | struct urb *urb = NULL; | ||
| 836 | u32 ctrlmode; | 842 | u32 ctrlmode; |
| 837 | u32 flags = 0; | 843 | u32 flags = 0; |
| 838 | int rc, i; | 844 | int rc, i; |
| @@ -855,14 +861,18 @@ static int gs_can_open(struct net_device *netdev) · 16 unmodified lines | |||
| 855 | } | 861 | } |
| 856 | 862 | ||
| 857 | if (!parent->active_channels) { | 863 | if (!parent->active_channels) { |
| 864 | if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP) | ||
| 865 | gs_usb_timestamp_init(parent); | ||
| 866 | |||
| 858 | for (i = 0; i < GS_MAX_RX_URBS; i++) { | 867 | for (i = 0; i < GS_MAX_RX_URBS; i++) { |
| 859 | struct urb *urb; | ||
| 860 | u8 *buf; | 868 | u8 *buf; |
| 861 | 869 | ||
| 862 | /* alloc rx urb */ | 870 | /* alloc rx urb */ |
| 863 | urb = usb_alloc_urb(0, GFP_KERNEL); | 871 | urb = usb_alloc_urb(0, GFP_KERNEL); |
| 864 | if (!urb) | 872 | if (!urb) { |
| 865 | return -ENOMEM; | 873 | rc = -ENOMEM; |
| 874 | goto out_usb_kill_anchored_urbs; | ||
| 875 | } | ||
| 866 | 876 | ||
| 867 | /* alloc rx buffer */ | 877 | /* alloc rx buffer */ |
| 868 | buf = kmalloc(dev->parent->hf_size_rx, | 878 | buf = kmalloc(dev->parent->hf_size_rx, |
| @@ -870,8 +880,8 @@ static int gs_can_open(struct net_device *netdev) · 1 unmodified line | |||
| 870 | if (!buf) { | 880 | if (!buf) { |
| 871 | netdev_err(netdev, | 881 | netdev_err(netdev, |
| 872 | "No memory left for USB buffer\n"); | 882 | "No memory left for USB buffer\n"); |
| 873 | usb_free_urb(urb); | 883 | rc = -ENOMEM; |
| 874 | return -ENOMEM; | 884 | goto out_usb_free_urb; |
| 875 | } | 885 | } |
| 876 | 886 | ||
| 877 | /* fill, anchor, and submit rx urb */ | 887 | /* fill, anchor, and submit rx urb */ |
| @@ -894,9 +904,7 @@ static int gs_can_open(struct net_device *netdev) · 16 unmodified lines | |||
| 894 | netdev_err(netdev, | 904 | netdev_err(netdev, |
| 895 | "usb_submit failed (err=%d)\n", rc); | 905 | "usb_submit failed (err=%d)\n", rc); |
| 896 | 906 | ||
| 897 | usb_unanchor_urb(urb); | 907 | goto out_usb_unanchor_urb; |
| 898 | usb_free_urb(urb); | ||
| 899 | break; | ||
| 900 | } | 908 | } |
| 901 | 909 | ||
| 902 | /* Drop reference, | 910 | /* Drop reference, |
| @@ -926,13 +934,9 @@ static int gs_can_open(struct net_device *netdev) · 23 unmodified lines | |||
| 926 | flags |= GS_CAN_MODE_FD; | 934 | flags |= GS_CAN_MODE_FD; |
| 927 | 935 | ||
| 928 | /* if hardware supports timestamps, enable it */ | 936 | /* if hardware supports timestamps, enable it */ |
| 929 | if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP) { | 937 | if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP) |
| 930 | flags |= GS_CAN_MODE_HW_TIMESTAMP; | 938 | flags |= GS_CAN_MODE_HW_TIMESTAMP; |
| 931 | 939 | ||
| 932 | /* start polling timestamp */ | ||
| 933 | gs_usb_timestamp_init(dev); | ||
| 934 | } | ||
| 935 | |||
| 936 | /* finally start device */ | 940 | /* finally start device */ |
| 937 | dev->can.state = CAN_STATE_ERROR_ACTIVE; | 941 | dev->can.state = CAN_STATE_ERROR_ACTIVE; |
| 938 | dm.flags = cpu_to_le32(flags); | 942 | dm.flags = cpu_to_le32(flags); |
| @@ -942,10 +946,9 @@ static int gs_can_open(struct net_device *netdev) · 3 unmodified lines | |||
| 942 | GFP_KERNEL); | 946 | GFP_KERNEL); |
| 943 | if (rc) { | 947 | if (rc) { |
| 944 | netdev_err(netdev, "Couldn't start device (err=%d)\n", rc); | 948 | netdev_err(netdev, "Couldn't start device (err=%d)\n", rc); |
| 945 | if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP) | ||
| 946 | gs_usb_timestamp_stop(dev); | ||
| 947 | dev->can.state = CAN_STATE_STOPPED; | 949 | dev->can.state = CAN_STATE_STOPPED; |
| 948 | return rc; | 950 | |
| 951 | goto out_usb_kill_anchored_urbs; | ||
| 949 | } | 952 | } |
| 950 | 953 | ||
| 951 | parent->active_channels++; | 954 | parent->active_channels++; |
| @@ -953,6 +956,22 @@ static int gs_can_open(struct net_device *netdev) · 1 unmodified line | |||
| 953 | netif_start_queue(netdev); | 956 | netif_start_queue(netdev); |
| 954 | 957 | ||
| 955 | return 0; | 958 | return 0; |
| 959 | |||
| 960 | out_usb_unanchor_urb: | ||
| 961 | usb_unanchor_urb(urb); | ||
| 962 | out_usb_free_urb: | ||
| 963 | usb_free_urb(urb); | ||
| 964 | out_usb_kill_anchored_urbs: | ||
| 965 | if (!parent->active_channels) { | ||
| 966 | usb_kill_anchored_urbs(&dev->tx_submitted); | ||
| 967 | |||
| 968 | if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP) | ||
| 969 | gs_usb_timestamp_stop(parent); | ||
| 970 | } | ||
| 971 | |||
| 972 | close_candev(netdev); | ||
| 973 | |||
| 974 | return rc; | ||
| 956 | } | 975 | } |
| 957 | 976 | ||
| 958 | static int gs_usb_get_state(const struct net_device *netdev, | 977 | static int gs_usb_get_state(const struct net_device *netdev, |
| @@ -998,14 +1017,13 @@ static int gs_can_close(struct net_device *netdev) · 39 unmodified lines | |||
| 998 | 1017 | ||
| 999 | netif_stop_queue(netdev); | 1018 | netif_stop_queue(netdev); |
| 1000 | 1019 | ||
| 1001 | /* stop polling timestamp */ | ||
| 1002 | if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP) | ||
| 1003 | gs_usb_timestamp_stop(dev); | ||
| 1004 | |||
| 1005 | /* Stop polling */ | 1020 | /* Stop polling */ |
| 1006 | parent->active_channels--; | 1021 | parent->active_channels--; |
| 1007 | if (!parent->active_channels) { | 1022 | if (!parent->active_channels) { |
| 1008 | usb_kill_anchored_urbs(&parent->rx_submitted); | 1023 | usb_kill_anchored_urbs(&parent->rx_submitted); |
| 1024 | |||
| 1025 | if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP) | ||
| 1026 | gs_usb_timestamp_stop(parent); | ||
| 1009 | } | 1027 | } |
| 1010 | 1028 | ||
| 1011 | /* Stop sending URBs */ | 1029 | /* Stop sending URBs */ |
| @@ -506,7 +506,13 @@ static int ksz8_r_sta_mac_table(struct ksz_device *dev, u16 addr, · 505 unmodified lines | |||
| 506 | (data_hi & masks[STATIC_MAC_TABLE_FWD_PORTS]) >> | 506 | (data_hi & masks[STATIC_MAC_TABLE_FWD_PORTS]) >> |
| 507 | shifts[STATIC_MAC_FWD_PORTS]; | 507 | shifts[STATIC_MAC_FWD_PORTS]; |
| 508 | alu->is_override = (data_hi & masks[STATIC_MAC_TABLE_OVERRIDE]) ? 1 : 0; | 508 | alu->is_override = (data_hi & masks[STATIC_MAC_TABLE_OVERRIDE]) ? 1 : 0; |
| 509 | data_hi >>= 1; | 509 | |
| 510 | /* KSZ8795 family switches have STATIC_MAC_TABLE_USE_FID and | ||
| 511 | * STATIC_MAC_TABLE_FID definitions off by 1 when doing read on the | ||
| 512 | * static MAC table compared to doing write. | ||
| 513 | */ | ||
| 514 | if (ksz_is_ksz87xx(dev)) | ||
| 515 | data_hi >>= 1; | ||
| 510 | alu->is_static = true; | 516 | alu->is_static = true; |
| 511 | alu->is_use_fid = (data_hi & masks[STATIC_MAC_TABLE_USE_FID]) ? 1 : 0; | 517 | alu->is_use_fid = (data_hi & masks[STATIC_MAC_TABLE_USE_FID]) ? 1 : 0; |
| 512 | alu->fid = (data_hi & masks[STATIC_MAC_TABLE_FID]) >> | 518 | alu->fid = (data_hi & masks[STATIC_MAC_TABLE_FID]) >> |
| @@ -331,13 +331,13 @@ static const u32 ksz8795_masks[] = { · 330 unmodified lines | |||
| 331 | [STATIC_MAC_TABLE_VALID] = BIT(21), | 331 | [STATIC_MAC_TABLE_VALID] = BIT(21), |
| 332 | [STATIC_MAC_TABLE_USE_FID] = BIT(23), | 332 | [STATIC_MAC_TABLE_USE_FID] = BIT(23), |
| 333 | [STATIC_MAC_TABLE_FID] = GENMASK(30, 24), | 333 | [STATIC_MAC_TABLE_FID] = GENMASK(30, 24), |
| 334 | [STATIC_MAC_TABLE_OVERRIDE] = BIT(26), | 334 | [STATIC_MAC_TABLE_OVERRIDE] = BIT(22), |
| 335 | [STATIC_MAC_TABLE_FWD_PORTS] = GENMASK(24, 20), | 335 | [STATIC_MAC_TABLE_FWD_PORTS] = GENMASK(20, 16), |
| 336 | [DYNAMIC_MAC_TABLE_ENTRIES_H] = GENMASK(6, 0), | 336 | [DYNAMIC_MAC_TABLE_ENTRIES_H] = GENMASK(6, 0), |
| 337 | [DYNAMIC_MAC_TABLE_MAC_EMPTY] = BIT(8), | 337 | [DYNAMIC_MAC_TABLE_MAC_EMPTY] = BIT(7), |
| 338 | [DYNAMIC_MAC_TABLE_NOT_READY] = BIT(7), | 338 | [DYNAMIC_MAC_TABLE_NOT_READY] = BIT(7), |
| 339 | [DYNAMIC_MAC_TABLE_ENTRIES] = GENMASK(31, 29), | 339 | [DYNAMIC_MAC_TABLE_ENTRIES] = GENMASK(31, 29), |
| 340 | [DYNAMIC_MAC_TABLE_FID] = GENMASK(26, 20), | 340 | [DYNAMIC_MAC_TABLE_FID] = GENMASK(22, 16), |
| 341 | [DYNAMIC_MAC_TABLE_SRC_PORT] = GENMASK(26, 24), | 341 | [DYNAMIC_MAC_TABLE_SRC_PORT] = GENMASK(26, 24), |
| 342 | [DYNAMIC_MAC_TABLE_TIMESTAMP] = GENMASK(28, 27), | 342 | [DYNAMIC_MAC_TABLE_TIMESTAMP] = GENMASK(28, 27), |
| 343 | [P_MII_TX_FLOW_CTRL] = BIT(5), | 343 | [P_MII_TX_FLOW_CTRL] = BIT(5), |
| @@ -601,6 +601,13 @@ static inline void ksz_regmap_unlock(void *__mtx) · 600 unmodified lines | |||
| 601 | mutex_unlock(mtx); | 601 | mutex_unlock(mtx); |
| 602 | } | 602 | } |
| 603 | 603 | ||
| 604 | static inline bool ksz_is_ksz87xx(struct ksz_device *dev) | ||
| 605 | { | ||
| 606 | return dev->chip_id == KSZ8795_CHIP_ID || | ||
| 607 | dev->chip_id == KSZ8794_CHIP_ID || | ||
| 608 | dev->chip_id == KSZ8765_CHIP_ID; | ||
| 609 | } | ||
| 610 | |||
| 604 | static inline bool ksz_is_ksz88x3(struct ksz_device *dev) | 611 | static inline bool ksz_is_ksz88x3(struct ksz_device *dev) |
| 605 | { | 612 | { |
| 606 | return dev->chip_id == KSZ8830_CHIP_ID; | 613 | return dev->chip_id == KSZ8830_CHIP_ID; |
| @@ -109,6 +109,13 @@ int mv88e6xxx_wait_mask(struct mv88e6xxx_chip *chip, int addr, int reg, · 108 unmodified lines | |||
| 109 | usleep_range(1000, 2000); | 109 | usleep_range(1000, 2000); |
| 110 | } | 110 | } |
| 111 | 111 | ||
| 112 | err = mv88e6xxx_read(chip, addr, reg, &data); | ||
| 113 | if (err) | ||
| 114 | return err; | ||
| 115 | |||
| 116 | if ((data & mask) == val) | ||
| 117 | return 0; | ||
| 118 | |||
| 112 | dev_err(chip->dev, "Timeout while waiting for switch\n"); | 119 | dev_err(chip->dev, "Timeout while waiting for switch\n"); |
| 113 | return -ETIMEDOUT; | 120 | return -ETIMEDOUT; |
| 114 | } | 121 | } |
| @@ -1002,6 +1002,8 @@ static const struct regmap_config ar9331_mdio_regmap_config = { · 1001 unmodified lines | |||
| 1002 | .val_bits = 32, | 1002 | .val_bits = 32, |
| 1003 | .reg_stride = 4, | 1003 | .reg_stride = 4, |
| 1004 | .max_register = AR9331_SW_REG_PAGE, | 1004 | .max_register = AR9331_SW_REG_PAGE, |
| 1005 | .use_single_read = true, | ||
| 1006 | .use_single_write = true, | ||
| 1005 | 1007 | ||
| 1006 | .ranges = ar9331_regmap_range, | 1008 | .ranges = ar9331_regmap_range, |
| 1007 | .num_ranges = ARRAY_SIZE(ar9331_regmap_range), | 1009 | .num_ranges = ARRAY_SIZE(ar9331_regmap_range), |
| @@ -1018,8 +1020,6 @@ static struct regmap_bus ar9331_sw_bus = { · 10 unmodified lines | |||
| 1018 | .val_format_endian_default = REGMAP_ENDIAN_NATIVE, | 1020 | .val_format_endian_default = REGMAP_ENDIAN_NATIVE, |
| 1019 | .read = ar9331_mdio_read, | 1021 | .read = ar9331_mdio_read, |
| 1020 | .write = ar9331_sw_bus_write, | 1022 | .write = ar9331_sw_bus_write, |
| 1021 | .max_raw_read = 4, | ||
| 1022 | .max_raw_write = 4, | ||
| 1023 | }; | 1023 | }; |
| 1024 | 1024 | ||
| 1025 | static int ar9331_sw_probe(struct mdio_device *mdiodev) | 1025 | static int ar9331_sw_probe(struct mdio_device *mdiodev) |
| @@ -512,11 +512,6 @@ bnad_debugfs_init(struct bnad *bnad) · 511 unmodified lines | |||
| 512 | if (!bnad->port_debugfs_root) { | 512 | if (!bnad->port_debugfs_root) { |
| 513 | bnad->port_debugfs_root = | 513 | bnad->port_debugfs_root = |
| 514 | debugfs_create_dir(name, bna_debugfs_root); | 514 | debugfs_create_dir(name, bna_debugfs_root); |
| 515 | if (!bnad->port_debugfs_root) { | ||
| 516 | netdev_warn(bnad->netdev, | ||
| 517 | "debugfs root dir creation failed\n"); | ||
| 518 | return; | ||
| 519 | } | ||
| 520 | 515 | ||
| 521 | atomic_inc(&bna_debugfs_port_count); | 516 | atomic_inc(&bna_debugfs_port_count); |
| 522 | 517 | ||
| @@ -255,8 +255,10 @@ struct iavf_adapter { · 254 unmodified lines | |||
| 255 | struct workqueue_struct *wq; | 255 | struct workqueue_struct *wq; |
| 256 | struct work_struct reset_task; | 256 | struct work_struct reset_task; |
| 257 | struct work_struct adminq_task; | 257 | struct work_struct adminq_task; |
| 258 | struct work_struct finish_config; | ||
| 258 | struct delayed_work client_task; | 259 | struct delayed_work client_task; |
| 259 | wait_queue_head_t down_waitqueue; | 260 | wait_queue_head_t down_waitqueue; |
| 261 | wait_queue_head_t reset_waitqueue; | ||
| 260 | wait_queue_head_t vc_waitqueue; | 262 | wait_queue_head_t vc_waitqueue; |
| 261 | struct iavf_q_vector *q_vectors; | 263 | struct iavf_q_vector *q_vectors; |
| 262 | struct list_head vlan_filter_list; | 264 | struct list_head vlan_filter_list; |
| @@ -518,8 +520,9 @@ int iavf_up(struct iavf_adapter *adapter); · 255 unmodified lines | |||
| 518 | void iavf_down(struct iavf_adapter *adapter); | 520 | void iavf_down(struct iavf_adapter *adapter); |
| 519 | int iavf_process_config(struct iavf_adapter *adapter); | 521 | int iavf_process_config(struct iavf_adapter *adapter); |
| 520 | int iavf_parse_vf_resource_msg(struct iavf_adapter *adapter); | 522 | int iavf_parse_vf_resource_msg(struct iavf_adapter *adapter); |
| 521 | void iavf_schedule_reset(struct iavf_adapter *adapter); | 523 | void iavf_schedule_reset(struct iavf_adapter *adapter, u64 flags); |
| 522 | void iavf_schedule_request_stats(struct iavf_adapter *adapter); | 524 | void iavf_schedule_request_stats(struct iavf_adapter *adapter); |
| 525 | void iavf_schedule_finish_config(struct iavf_adapter *adapter); | ||
| 523 | void iavf_reset(struct iavf_adapter *adapter); | 526 | void iavf_reset(struct iavf_adapter *adapter); |
| 524 | void iavf_set_ethtool_ops(struct net_device *netdev); | 527 | void iavf_set_ethtool_ops(struct net_device *netdev); |
| 525 | void iavf_update_stats(struct iavf_adapter *adapter); | 528 | void iavf_update_stats(struct iavf_adapter *adapter); |
| @@ -582,4 +585,5 @@ void iavf_add_adv_rss_cfg(struct iavf_adapter *adapter); · 56 unmodified lines | |||
| 582 | void iavf_del_adv_rss_cfg(struct iavf_adapter *adapter); | 585 | void iavf_del_adv_rss_cfg(struct iavf_adapter *adapter); |
| 583 | struct iavf_mac_filter *iavf_add_filter(struct iavf_adapter *adapter, | 586 | struct iavf_mac_filter *iavf_add_filter(struct iavf_adapter *adapter, |
| 584 | const u8 *macaddr); | 587 | const u8 *macaddr); |
| 588 | int iavf_wait_for_reset(struct iavf_adapter *adapter); | ||
| 585 | #endif /* _IAVF_H_ */ | 589 | #endif /* _IAVF_H_ */ |
| @@ -484,6 +484,7 @@ static int iavf_set_priv_flags(struct net_device *netdev, u32 flags) · 483 unmodified lines | |||
| 484 | { | 484 | { |
| 485 | struct iavf_adapter *adapter = netdev_priv(netdev); | 485 | struct iavf_adapter *adapter = netdev_priv(netdev); |
| 486 | u32 orig_flags, new_flags, changed_flags; | 486 | u32 orig_flags, new_flags, changed_flags; |
| 487 | int ret = 0; | ||
| 487 | u32 i; | 488 | u32 i; |
| 488 | 489 | ||
| 489 | orig_flags = READ_ONCE(adapter->flags); | 490 | orig_flags = READ_ONCE(adapter->flags); |
| @@ -531,12 +532,14 @@ static int iavf_set_priv_flags(struct net_device *netdev, u32 flags) · 41 unmodified lines | |||
| 531 | /* issue a reset to force legacy-rx change to take effect */ | 532 | /* issue a reset to force legacy-rx change to take effect */ |
| 532 | if (changed_flags & IAVF_FLAG_LEGACY_RX) { | 533 | if (changed_flags & IAVF_FLAG_LEGACY_RX) { |
| 533 | if (netif_running(netdev)) { | 534 | if (netif_running(netdev)) { |
| 534 | adapter->flags |= IAVF_FLAG_RESET_NEEDED; | 535 | iavf_schedule_reset(adapter, IAVF_FLAG_RESET_NEEDED); |
| 535 | queue_work(adapter->wq, &adapter->reset_task); | 536 | ret = iavf_wait_for_reset(adapter); |
| 537 | if (ret) | ||
| 538 | netdev_warn(netdev, "Changing private flags timeout or interrupted waiting for reset"); | ||
| 536 | } | 539 | } |
| 537 | } | 540 | } |
| 538 | 541 | ||
| 539 | return 0; | 542 | return ret; |
| 540 | } | 543 | } |
| 541 | 544 | ||
| 542 | /** | 545 | /** |
| @@ -627,6 +630,7 @@ static int iavf_set_ringparam(struct net_device *netdev, · 84 unmodified lines | |||
| 627 | { | 630 | { |
| 628 | struct iavf_adapter *adapter = netdev_priv(netdev); | 631 | struct iavf_adapter *adapter = netdev_priv(netdev); |
| 629 | u32 new_rx_count, new_tx_count; | 632 | u32 new_rx_count, new_tx_count; |
| 633 | int ret = 0; | ||
| 630 | 634 | ||
| 631 | if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) | 635 | if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) |
| 632 | return -EINVAL; | 636 | return -EINVAL; |
| @@ -671,11 +675,13 @@ static int iavf_set_ringparam(struct net_device *netdev, · 38 unmodified lines | |||
| 671 | } | 675 | } |
| 672 | 676 | ||
| 673 | if (netif_running(netdev)) { | 677 | if (netif_running(netdev)) { |
| 674 | adapter->flags |= IAVF_FLAG_RESET_NEEDED; | 678 | iavf_schedule_reset(adapter, IAVF_FLAG_RESET_NEEDED); |
| 675 | queue_work(adapter->wq, &adapter->reset_task); | 679 | ret = iavf_wait_for_reset(adapter); |
| 680 | if (ret) | ||
| 681 | netdev_warn(netdev, "Changing ring parameters timeout or interrupted waiting for reset"); | ||
| 676 | } | 682 | } |
| 677 | 683 | ||
| 678 | return 0; | 684 | return ret; |
| 679 | } | 685 | } |
| 680 | 686 | ||
| 681 | /** | 687 | /** |
| @@ -1830,7 +1836,7 @@ static int iavf_set_channels(struct net_device *netdev, · 1148 unmodified lines | |||
| 1830 | { | 1836 | { |
| 1831 | struct iavf_adapter *adapter = netdev_priv(netdev); | 1837 | struct iavf_adapter *adapter = netdev_priv(netdev); |
| 1832 | u32 num_req = ch->combined_count; | 1838 | u32 num_req = ch->combined_count; |
| 1833 | int i; | 1839 | int ret = 0; |
| 1834 | 1840 | ||
| 1835 | if ((adapter->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_ADQ) && | 1841 | if ((adapter->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_ADQ) && |
| 1836 | adapter->num_tc) { | 1842 | adapter->num_tc) { |
| @@ -1852,22 +1858,13 @@ static int iavf_set_channels(struct net_device *netdev, · 15 unmodified lines | |||
| 1852 | 1858 | ||
| 1853 | adapter->num_req_queues = num_req; | 1859 | adapter->num_req_queues = num_req; |
| 1854 | adapter->flags |= IAVF_FLAG_REINIT_ITR_NEEDED; | 1860 | adapter->flags |= IAVF_FLAG_REINIT_ITR_NEEDED; |
| 1855 | iavf_schedule_reset(adapter); | 1861 | iavf_schedule_reset(adapter, IAVF_FLAG_RESET_NEEDED); |
| 1856 | 1862 | ||
| 1857 | /* wait for the reset is done */ | 1863 | ret = iavf_wait_for_reset(adapter); |
| 1858 | for (i = 0; i < IAVF_RESET_WAIT_COMPLETE_COUNT; i++) { | 1864 | if (ret) |
| 1859 | msleep(IAVF_RESET_WAIT_MS); | 1865 | netdev_warn(netdev, "Changing channel count timeout or interrupted waiting for reset"); |
| 1860 | if (adapter->flags & IAVF_FLAG_RESET_PENDING) | ||
| 1861 | continue; | ||
| 1862 | break; | ||
| 1863 | } | ||
| 1864 | if (i == IAVF_RESET_WAIT_COMPLETE_COUNT) { | ||
| 1865 | adapter->flags &= ~IAVF_FLAG_REINIT_ITR_NEEDED; | ||
| 1866 | adapter->num_active_queues = num_req; | ||
| 1867 | return -EOPNOTSUPP; | ||
| 1868 | } | ||
| 1869 | 1866 | ||
| 1870 | return 0; | 1867 | return ret; |
| 1871 | } | 1868 | } |
| 1872 | 1869 | ||
| 1873 | /** | 1870 | /** |
| @@ -166,6 +166,45 @@ static struct iavf_adapter *iavf_pdev_to_adapter(struct pci_dev *pdev) · 165 unmodified lines | |||
| 166 | return netdev_priv(pci_get_drvdata(pdev)); | 166 | return netdev_priv(pci_get_drvdata(pdev)); |
| 167 | } | 167 | } |
| 168 | 168 | ||
| 169 | /** | ||
| 170 | * iavf_is_reset_in_progress - Check if a reset is in progress | ||
| 171 | * @adapter: board private structure | ||
| 172 | */ | ||
| 173 | static bool iavf_is_reset_in_progress(struct iavf_adapter *adapter) | ||
| 174 | { | ||
| 175 | if (adapter->state == __IAVF_RESETTING || | ||
| 176 | adapter->flags & (IAVF_FLAG_RESET_PENDING | | ||
| 177 | IAVF_FLAG_RESET_NEEDED)) | ||
| 178 | return true; | ||
| 179 | |||
| 180 | return false; | ||
| 181 | } | ||
| 182 | |||
| 183 | /** | ||
| 184 | * iavf_wait_for_reset - Wait for reset to finish. | ||
| 185 | * @adapter: board private structure | ||
| 186 | * | ||
| 187 | * Returns 0 if reset finished successfully, negative on timeout or interrupt. | ||
| 188 | */ | ||
| 189 | int iavf_wait_for_reset(struct iavf_adapter *adapter) | ||
| 190 | { | ||
| 191 | int ret = wait_event_interruptible_timeout(adapter->reset_waitqueue, | ||
| 192 | !iavf_is_reset_in_progress(adapter), | ||
| 193 | msecs_to_jiffies(5000)); | ||
| 194 | |||
| 195 | /* If ret < 0 then it means wait was interrupted. | ||
| 196 | * If ret == 0 then it means we got a timeout while waiting | ||
| 197 | * for reset to finish. | ||
| 198 | * If ret > 0 it means reset has finished. | ||
| 199 | */ | ||
| 200 | if (ret > 0) | ||
| 201 | return 0; | ||
| 202 | else if (ret < 0) | ||
| 203 | return -EINTR; | ||
| 204 | else | ||
| 205 | return -EBUSY; | ||
| 206 | } | ||
| 207 | |||
| 169 | /** | 208 | /** |
| 170 | * iavf_allocate_dma_mem_d - OS specific memory alloc for shared code | 209 | * iavf_allocate_dma_mem_d - OS specific memory alloc for shared code |
| 171 | * @hw: pointer to the HW structure | 210 | * @hw: pointer to the HW structure |
| @@ -262,12 +301,14 @@ static int iavf_lock_timeout(struct mutex *lock, unsigned int msecs) · 90 unmodified lines | |||
| 262 | /** | 301 | /** |
| 263 | * iavf_schedule_reset - Set the flags and schedule a reset event | 302 | * iavf_schedule_reset - Set the flags and schedule a reset event |
| 264 | * @adapter: board private structure | 303 | * @adapter: board private structure |
| 304 | * @flags: IAVF_FLAG_RESET_PENDING or IAVF_FLAG_RESET_NEEDED | ||
| 265 | **/ | 305 | **/ |
| 266 | void iavf_schedule_reset(struct iavf_adapter *adapter) | 306 | void iavf_schedule_reset(struct iavf_adapter *adapter, u64 flags) |
| 267 | { | 307 | { |
| 268 | if (!(adapter->flags & | 308 | if (!test_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section) && |
| 269 | (IAVF_FLAG_RESET_PENDING | IAVF_FLAG_RESET_NEEDED))) { | 309 | !(adapter->flags & |
| 270 | adapter->flags |= IAVF_FLAG_RESET_NEEDED; | 310 | (IAVF_FLAG_RESET_PENDING | IAVF_FLAG_RESET_NEEDED))) { |
| 311 | adapter->flags |= flags; | ||
| 271 | queue_work(adapter->wq, &adapter->reset_task); | 312 | queue_work(adapter->wq, &adapter->reset_task); |
| 272 | } | 313 | } |
| 273 | } | 314 | } |
| @@ -295,7 +336,7 @@ static void iavf_tx_timeout(struct net_device *netdev, unsigned int txqueue) · 21 unmodified lines | |||
| 295 | struct iavf_adapter *adapter = netdev_priv(netdev); | 336 | struct iavf_adapter *adapter = netdev_priv(netdev); |
| 296 | 337 | ||
| 297 | adapter->tx_timeout_count++; | 338 | adapter->tx_timeout_count++; |
| 298 | iavf_schedule_reset(adapter); | 339 | iavf_schedule_reset(adapter, IAVF_FLAG_RESET_NEEDED); |
| 299 | } | 340 | } |
| 300 | 341 | ||
| 301 | /** | 342 | /** |
| @@ -1651,10 +1692,10 @@ static int iavf_set_interrupt_capability(struct iavf_adapter *adapter) · 1349 unmodified lines | |||
| 1651 | adapter->msix_entries[vector].entry = vector; | 1692 | adapter->msix_entries[vector].entry = vector; |
| 1652 | 1693 | ||
| 1653 | err = iavf_acquire_msix_vectors(adapter, v_budget); | 1694 | err = iavf_acquire_msix_vectors(adapter, v_budget); |
| 1695 | if (!err) | ||
| 1696 | iavf_schedule_finish_config(adapter); | ||
| 1654 | 1697 | ||
| 1655 | out: | 1698 | out: |
| 1656 | netif_set_real_num_rx_queues(adapter->netdev, pairs); | ||
| 1657 | netif_set_real_num_tx_queues(adapter->netdev, pairs); | ||
| 1658 | return err; | 1699 | return err; |
| 1659 | } | 1700 | } |
| 1660 | 1701 | ||
| @@ -1828,19 +1869,16 @@ static int iavf_alloc_q_vectors(struct iavf_adapter *adapter) · 167 unmodified lines | |||
| 1828 | static void iavf_free_q_vectors(struct iavf_adapter *adapter) | 1869 | static void iavf_free_q_vectors(struct iavf_adapter *adapter) |
| 1829 | { | 1870 | { |
| 1830 | int q_idx, num_q_vectors; | 1871 | int q_idx, num_q_vectors; |
| 1831 | int napi_vectors; | ||
| 1832 | 1872 | ||
| 1833 | if (!adapter->q_vectors) | 1873 | if (!adapter->q_vectors) |
| 1834 | return; | 1874 | return; |
| 1835 | 1875 | ||
| 1836 | num_q_vectors = adapter->num_msix_vectors - NONQ_VECS; | 1876 | num_q_vectors = adapter->num_msix_vectors - NONQ_VECS; |
| 1837 | napi_vectors = adapter->num_active_queues; | ||
| 1838 | 1877 | ||
| 1839 | for (q_idx = 0; q_idx < num_q_vectors; q_idx++) { | 1878 | for (q_idx = 0; q_idx < num_q_vectors; q_idx++) { |
| 1840 | struct iavf_q_vector *q_vector = &adapter->q_vectors[q_idx]; | 1879 | struct iavf_q_vector *q_vector = &adapter->q_vectors[q_idx]; |
| 1841 | 1880 | ||
| 1842 | if (q_idx < napi_vectors) | 1881 | netif_napi_del(&q_vector->napi); |
| 1843 | netif_napi_del(&q_vector->napi); | ||
| 1844 | } | 1882 | } |
| 1845 | kfree(adapter->q_vectors); | 1883 | kfree(adapter->q_vectors); |
| 1846 | adapter->q_vectors = NULL; | 1884 | adapter->q_vectors = NULL; |
| @@ -1877,9 +1915,7 @@ static int iavf_init_interrupt_scheme(struct iavf_adapter *adapter) · 30 unmodified lines | |||
| 1877 | goto err_alloc_queues; | 1915 | goto err_alloc_queues; |
| 1878 | } | 1916 | } |
| 1879 | 1917 | ||
| 1880 | rtnl_lock(); | ||
| 1881 | err = iavf_set_interrupt_capability(adapter); | 1918 | err = iavf_set_interrupt_capability(adapter); |
| 1882 | rtnl_unlock(); | ||
| 1883 | if (err) { | 1919 | if (err) { |
| 1884 | dev_err(&adapter->pdev->dev, | 1920 | dev_err(&adapter->pdev->dev, |
| 1885 | "Unable to setup interrupt capabilities\n"); | 1921 | "Unable to setup interrupt capabilities\n"); |
| @@ -1932,15 +1968,16 @@ static void iavf_free_rss(struct iavf_adapter *adapter) · 46 unmodified lines | |||
| 1932 | /** | 1968 | /** |
| 1933 | * iavf_reinit_interrupt_scheme - Reallocate queues and vectors | 1969 | * iavf_reinit_interrupt_scheme - Reallocate queues and vectors |
| 1934 | * @adapter: board private structure | 1970 | * @adapter: board private structure |
| 1971 | * @running: true if adapter->state == __IAVF_RUNNING | ||
| 1935 | * | 1972 | * |
| 1936 | * Returns 0 on success, negative on failure | 1973 | * Returns 0 on success, negative on failure |
| 1937 | **/ | 1974 | **/ |
| 1938 | static int iavf_reinit_interrupt_scheme(struct iavf_adapter *adapter) | 1975 | static int iavf_reinit_interrupt_scheme(struct iavf_adapter *adapter, bool running) |
| 1939 | { | 1976 | { |
| 1940 | struct net_device *netdev = adapter->netdev; | 1977 | struct net_device *netdev = adapter->netdev; |
| 1941 | int err; | 1978 | int err; |
| 1942 | 1979 | ||
| 1943 | if (netif_running(netdev)) | 1980 | if (running) |
| 1944 | iavf_free_traffic_irqs(adapter); | 1981 | iavf_free_traffic_irqs(adapter); |
| 1945 | iavf_free_misc_irq(adapter); | 1982 | iavf_free_misc_irq(adapter); |
| 1946 | iavf_reset_interrupt_capability(adapter); | 1983 | iavf_reset_interrupt_capability(adapter); |
| @@ -1964,6 +2001,78 @@ err: · 17 unmodified lines | |||
| 1964 | return err; | 2001 | return err; |
| 1965 | } | 2002 | } |
| 1966 | 2003 | ||
| 2004 | /** | ||
| 2005 | * iavf_finish_config - do all netdev work that needs RTNL | ||
| 2006 | * @work: our work_struct | ||
| 2007 | * | ||
| 2008 | * Do work that needs both RTNL and crit_lock. | ||
| 2009 | **/ | ||
| 2010 | static void iavf_finish_config(struct work_struct *work) | ||
| 2011 | { | ||
| 2012 | struct iavf_adapter *adapter; | ||
| 2013 | int pairs, err; | ||
| 2014 | |||
| 2015 | adapter = container_of(work, struct iavf_adapter, finish_config); | ||
| 2016 | |||
| 2017 | /* Always take RTNL first to prevent circular lock dependency */ | ||
| 2018 | rtnl_lock(); | ||
| 2019 | mutex_lock(&adapter->crit_lock); | ||
| 2020 | |||
| 2021 | if ((adapter->flags & IAVF_FLAG_SETUP_NETDEV_FEATURES) && | ||
| 2022 | adapter->netdev_registered && | ||
| 2023 | !test_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section)) { | ||
| 2024 | netdev_update_features(adapter->netdev); | ||
| 2025 | adapter->flags &= ~IAVF_FLAG_SETUP_NETDEV_FEATURES; | ||
| 2026 | } | ||
| 2027 | |||
| 2028 | switch (adapter->state) { | ||
| 2029 | case __IAVF_DOWN: | ||
| 2030 | if (!adapter->netdev_registered) { | ||
| 2031 | err = register_netdevice(adapter->netdev); | ||
| 2032 | if (err) { | ||
| 2033 | dev_err(&adapter->pdev->dev, "Unable to register netdev (%d)\n", | ||
| 2034 | err); | ||
| 2035 | |||
| 2036 | /* go back and try again.*/ | ||
| 2037 | iavf_free_rss(adapter); | ||
| 2038 | iavf_free_misc_irq(adapter); | ||
| 2039 | iavf_reset_interrupt_capability(adapter); | ||
| 2040 | iavf_change_state(adapter, | ||
| 2041 | __IAVF_INIT_CONFIG_ADAPTER); | ||
| 2042 | goto out; | ||
| 2043 | } | ||
| 2044 | adapter->netdev_registered = true; | ||
| 2045 | } | ||
| 2046 | |||
| 2047 | /* Set the real number of queues when reset occurs while | ||
| 2048 | * state == __IAVF_DOWN | ||
| 2049 | */ | ||
| 2050 | fallthrough; | ||
| 2051 | case __IAVF_RUNNING: | ||
| 2052 | pairs = adapter->num_active_queues; | ||
| 2053 | netif_set_real_num_rx_queues(adapter->netdev, pairs); | ||
| 2054 | netif_set_real_num_tx_queues(adapter->netdev, pairs); | ||
| 2055 | break; | ||
| 2056 | |||
| 2057 | default: | ||
| 2058 | break; | ||
| 2059 | } | ||
| 2060 | |||
| 2061 | out: | ||
| 2062 | mutex_unlock(&adapter->crit_lock); | ||
| 2063 | rtnl_unlock(); | ||
| 2064 | } | ||
| 2065 | |||
| 2066 | /** | ||
| 2067 | * iavf_schedule_finish_config - Set the flags and schedule a reset event | ||
| 2068 | * @adapter: board private structure | ||
| 2069 | **/ | ||
| 2070 | void iavf_schedule_finish_config(struct iavf_adapter *adapter) | ||
| 2071 | { | ||
| 2072 | if (!test_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section)) | ||
| 2073 | queue_work(adapter->wq, &adapter->finish_config); | ||
| 2074 | } | ||
| 2075 | |||
| 1967 | /** | 2076 | /** |
| 1968 | * iavf_process_aq_command - process aq_required flags | 2077 | * iavf_process_aq_command - process aq_required flags |
| 1969 | * and sends aq command | 2078 | * and sends aq command |
| @@ -2371,7 +2480,7 @@ int iavf_parse_vf_resource_msg(struct iavf_adapter *adapter) · 401 unmodified lines | |||
| 2371 | adapter->vsi_res->num_queue_pairs); | 2480 | adapter->vsi_res->num_queue_pairs); |
| 2372 | adapter->flags |= IAVF_FLAG_REINIT_MSIX_NEEDED; | 2481 | adapter->flags |= IAVF_FLAG_REINIT_MSIX_NEEDED; |
| 2373 | adapter->num_req_queues = adapter->vsi_res->num_queue_pairs; | 2482 | adapter->num_req_queues = adapter->vsi_res->num_queue_pairs; |
| 2374 | iavf_schedule_reset(adapter); | 2483 | iavf_schedule_reset(adapter, IAVF_FLAG_RESET_NEEDED); |
| 2375 | 2484 | ||
| 2376 | return -EAGAIN; | 2485 | return -EAGAIN; |
| 2377 | } | 2486 | } |
| @@ -2601,22 +2710,8 @@ static void iavf_init_config_adapter(struct iavf_adapter *adapter) · 223 unmodified lines | |||
| 2601 | 2710 | ||
| 2602 | netif_carrier_off(netdev); | 2711 | netif_carrier_off(netdev); |
| 2603 | adapter->link_up = false; | 2712 | adapter->link_up = false; |
| 2604 | |||
| 2605 | /* set the semaphore to prevent any callbacks after device registration | ||
| 2606 | * up to time when state of driver will be set to __IAVF_DOWN | ||
| 2607 | */ | ||
| 2608 | rtnl_lock(); | ||
| 2609 | if (!adapter->netdev_registered) { | ||
| 2610 | err = register_netdevice(netdev); | ||
| 2611 | if (err) { | ||
| 2612 | rtnl_unlock(); | ||
| 2613 | goto err_register; | ||
| 2614 | } | ||
| 2615 | } | ||
| 2616 | |||
| 2617 | adapter->netdev_registered = true; | ||
| 2618 | |||
| 2619 | netif_tx_stop_all_queues(netdev); | 2713 | netif_tx_stop_all_queues(netdev); |
| 2714 | |||
| 2620 | if (CLIENT_ALLOWED(adapter)) { | 2715 | if (CLIENT_ALLOWED(adapter)) { |
| 2621 | err = iavf_lan_add_device(adapter); | 2716 | err = iavf_lan_add_device(adapter); |
| 2622 | if (err) | 2717 | if (err) |
| @@ -2629,7 +2724,6 @@ static void iavf_init_config_adapter(struct iavf_adapter *adapter) · 6 unmodified lines | |||
| 2629 | 2724 | ||
| 2630 | iavf_change_state(adapter, __IAVF_DOWN); | 2725 | iavf_change_state(adapter, __IAVF_DOWN); |
| 2631 | set_bit(__IAVF_VSI_DOWN, adapter->vsi.state); | 2726 | set_bit(__IAVF_VSI_DOWN, adapter->vsi.state); |
| 2632 | rtnl_unlock(); | ||
| 2633 | 2727 | ||
| 2634 | iavf_misc_irq_enable(adapter); | 2728 | iavf_misc_irq_enable(adapter); |
| 2635 | wake_up(&adapter->down_waitqueue); | 2729 | wake_up(&adapter->down_waitqueue); |
| @@ -2649,10 +2743,11 @@ static void iavf_init_config_adapter(struct iavf_adapter *adapter) · 13 unmodified lines | |||
| 2649 | /* request initial VLAN offload settings */ | 2743 | /* request initial VLAN offload settings */ |
| 2650 | iavf_set_vlan_offload_features(adapter, 0, netdev->features); | 2744 | iavf_set_vlan_offload_features(adapter, 0, netdev->features); |
| 2651 | 2745 | ||
| 2746 | iavf_schedule_finish_config(adapter); | ||
| 2652 | return; | 2747 | return; |
| 2748 | |||
| 2653 | err_mem: | 2749 | err_mem: |
| 2654 | iavf_free_rss(adapter); | 2750 | iavf_free_rss(adapter); |
| 2655 | err_register: | ||
| 2656 | iavf_free_misc_irq(adapter); | 2751 | iavf_free_misc_irq(adapter); |
| 2657 | err_sw_init: | 2752 | err_sw_init: |
| 2658 | iavf_reset_interrupt_capability(adapter); | 2753 | iavf_reset_interrupt_capability(adapter); |
| @@ -2679,26 +2774,9 @@ static void iavf_watchdog_task(struct work_struct *work) · 20 unmodified lines | |||
| 2679 | goto restart_watchdog; | 2774 | goto restart_watchdog; |
| 2680 | } | 2775 | } |
| 2681 | 2776 | ||
| 2682 | if ((adapter->flags & IAVF_FLAG_SETUP_NETDEV_FEATURES) && | ||
| 2683 | adapter->netdev_registered && | ||
| 2684 | !test_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section) && | ||
| 2685 | rtnl_trylock()) { | ||
| 2686 | netdev_update_features(adapter->netdev); | ||
| 2687 | rtnl_unlock(); | ||
| 2688 | adapter->flags &= ~IAVF_FLAG_SETUP_NETDEV_FEATURES; | ||
| 2689 | } | ||
| 2690 | |||
| 2691 | if (adapter->flags & IAVF_FLAG_PF_COMMS_FAILED) | 2777 | if (adapter->flags & IAVF_FLAG_PF_COMMS_FAILED) |
| 2692 | iavf_change_state(adapter, __IAVF_COMM_FAILED); | 2778 | iavf_change_state(adapter, __IAVF_COMM_FAILED); |
| 2693 | 2779 | ||
| 2694 | if (adapter->flags & IAVF_FLAG_RESET_NEEDED) { | ||
| 2695 | adapter->aq_required = 0; | ||
| 2696 | adapter->current_op = VIRTCHNL_OP_UNKNOWN; | ||
| 2697 | mutex_unlock(&adapter->crit_lock); | ||
| 2698 | queue_work(adapter->wq, &adapter->reset_task); | ||
| 2699 | return; | ||
| 2700 | } | ||
| 2701 | |||
| 2702 | switch (adapter->state) { | 2780 | switch (adapter->state) { |
| 2703 | case __IAVF_STARTUP: | 2781 | case __IAVF_STARTUP: |
| 2704 | iavf_startup(adapter); | 2782 | iavf_startup(adapter); |
| @@ -2826,11 +2904,10 @@ static void iavf_watchdog_task(struct work_struct *work) · 121 unmodified lines | |||
| 2826 | /* check for hw reset */ | 2904 | /* check for hw reset */ |
| 2827 | reg_val = rd32(hw, IAVF_VF_ARQLEN1) & IAVF_VF_ARQLEN1_ARQENABLE_MASK; | 2905 | reg_val = rd32(hw, IAVF_VF_ARQLEN1) & IAVF_VF_ARQLEN1_ARQENABLE_MASK; |
| 2828 | if (!reg_val) { | 2906 | if (!reg_val) { |
| 2829 | adapter->flags |= IAVF_FLAG_RESET_PENDING; | ||
| 2830 | adapter->aq_required = 0; | 2907 | adapter->aq_required = 0; |
| 2831 | adapter->current_op = VIRTCHNL_OP_UNKNOWN; | 2908 | adapter->current_op = VIRTCHNL_OP_UNKNOWN; |
| 2832 | dev_err(&adapter->pdev->dev, "Hardware reset detected\n"); | 2909 | dev_err(&adapter->pdev->dev, "Hardware reset detected\n"); |
| 2833 | queue_work(adapter->wq, &adapter->reset_task); | 2910 | iavf_schedule_reset(adapter, IAVF_FLAG_RESET_PENDING); |
| 2834 | mutex_unlock(&adapter->crit_lock); | 2911 | mutex_unlock(&adapter->crit_lock); |
| 2835 | queue_delayed_work(adapter->wq, | 2912 | queue_delayed_work(adapter->wq, |
| 2836 | &adapter->watchdog_task, HZ * 2); | 2913 | &adapter->watchdog_task, HZ * 2); |
| @@ -2940,11 +3017,6 @@ static void iavf_reset_task(struct work_struct *work) · 103 unmodified lines | |||
| 2940 | int i = 0, err; | 3017 | int i = 0, err; |
| 2941 | bool running; | 3018 | bool running; |
| 2942 | 3019 | ||
| 2943 | /* Detach interface to avoid subsequent NDO callbacks */ | ||
| 2944 | rtnl_lock(); | ||
| 2945 | netif_device_detach(netdev); | ||
| 2946 | rtnl_unlock(); | ||
| 2947 | |||
| 2948 | /* When device is being removed it doesn't make sense to run the reset | 3020 | /* When device is being removed it doesn't make sense to run the reset |
| 2949 | * task, just return in such a case. | 3021 | * task, just return in such a case. |
| 2950 | */ | 3022 | */ |
| @@ -2952,7 +3024,7 @@ static void iavf_reset_task(struct work_struct *work) · 1 unmodified line | |||
| 2952 | if (adapter->state != __IAVF_REMOVE) | 3024 | if (adapter->state != __IAVF_REMOVE) |
| 2953 | queue_work(adapter->wq, &adapter->reset_task); | 3025 | queue_work(adapter->wq, &adapter->reset_task); |
| 2954 | 3026 | ||
| 2955 | goto reset_finish; | 3027 | return; |
| 2956 | } | 3028 | } |
| 2957 | 3029 | ||
| 2958 | while (!mutex_trylock(&adapter->client_lock)) | 3030 | while (!mutex_trylock(&adapter->client_lock)) |
| @@ -3010,11 +3082,6 @@ static void iavf_reset_task(struct work_struct *work) · 51 unmodified lines | |||
| 3010 | iavf_disable_vf(adapter); | 3082 | iavf_disable_vf(adapter); |
| 3011 | mutex_unlock(&adapter->client_lock); | 3083 | mutex_unlock(&adapter->client_lock); |
| 3012 | mutex_unlock(&adapter->crit_lock); | 3084 | mutex_unlock(&adapter->crit_lock); |
| 3013 | if (netif_running(netdev)) { | ||
| 3014 | rtnl_lock(); | ||
| 3015 | dev_close(netdev); | ||
| 3016 | rtnl_unlock(); | ||
| 3017 | } | ||
| 3018 | return; /* Do not attempt to reinit. It's dead, Jim. */ | 3085 | return; /* Do not attempt to reinit. It's dead, Jim. */ |
| 3019 | } | 3086 | } |
| 3020 | 3087 | ||
| @@ -3056,7 +3123,7 @@ continue_reset: · 35 unmodified lines | |||
| 3056 | 3123 | ||
| 3057 | if ((adapter->flags & IAVF_FLAG_REINIT_MSIX_NEEDED) || | 3124 | if ((adapter->flags & IAVF_FLAG_REINIT_MSIX_NEEDED) || |
| 3058 | (adapter->flags & IAVF_FLAG_REINIT_ITR_NEEDED)) { | 3125 | (adapter->flags & IAVF_FLAG_REINIT_ITR_NEEDED)) { |
| 3059 | err = iavf_reinit_interrupt_scheme(adapter); | 3126 | err = iavf_reinit_interrupt_scheme(adapter, running); |
| 3060 | if (err) | 3127 | if (err) |
| 3061 | goto reset_err; | 3128 | goto reset_err; |
| 3062 | } | 3129 | } |
| @@ -3151,10 +3218,11 @@ continue_reset: · 88 unmodified lines | |||
| 3151 | 3218 | ||
| 3152 | adapter->flags &= ~IAVF_FLAG_REINIT_ITR_NEEDED; | 3219 | adapter->flags &= ~IAVF_FLAG_REINIT_ITR_NEEDED; |
| 3153 | 3220 | ||
| 3221 | wake_up(&adapter->reset_waitqueue); | ||
| 3154 | mutex_unlock(&adapter->client_lock); | 3222 | mutex_unlock(&adapter->client_lock); |
| 3155 | mutex_unlock(&adapter->crit_lock); | 3223 | mutex_unlock(&adapter->crit_lock); |
| 3156 | 3224 | ||
| 3157 | goto reset_finish; | 3225 | return; |
| 3158 | reset_err: | 3226 | reset_err: |
| 3159 | if (running) { | 3227 | if (running) { |
| 3160 | set_bit(__IAVF_VSI_DOWN, adapter->vsi.state); | 3228 | set_bit(__IAVF_VSI_DOWN, adapter->vsi.state); |
| @@ -3164,21 +3232,7 @@ reset_err: · 3 unmodified lines | |||
| 3164 | 3232 | ||
| 3165 | mutex_unlock(&adapter->client_lock); | 3233 | mutex_unlock(&adapter->client_lock); |
| 3166 | mutex_unlock(&adapter->crit_lock); | 3234 | mutex_unlock(&adapter->crit_lock); |
| 3167 | |||
| 3168 | if (netif_running(netdev)) { | ||
| 3169 | /* Close device to ensure that Tx queues will not be started | ||
| 3170 | * during netif_device_attach() at the end of the reset task. | ||
| 3171 | */ | ||
| 3172 | rtnl_lock(); | ||
| 3173 | dev_close(netdev); | ||
| 3174 | rtnl_unlock(); | ||
| 3175 | } | ||
| 3176 | |||
| 3177 | dev_err(&adapter->pdev->dev, "failed to allocate resources during reinit\n"); | 3235 | dev_err(&adapter->pdev->dev, "failed to allocate resources during reinit\n"); |
| 3178 | reset_finish: | ||
| 3179 | rtnl_lock(); | ||
| 3180 | netif_device_attach(netdev); | ||
| 3181 | rtnl_unlock(); | ||
| 3182 | } | 3236 | } |
| 3183 | 3237 | ||
| 3184 | /** | 3238 | /** |
| @@ -3227,9 +3281,7 @@ static void iavf_adminq_task(struct work_struct *work) · 42 unmodified lines | |||
| 3227 | } while (pending); | 3281 | } while (pending); |
| 3228 | mutex_unlock(&adapter->crit_lock); | 3282 | mutex_unlock(&adapter->crit_lock); |
| 3229 | 3283 | ||
| 3230 | if ((adapter->flags & | 3284 | if (iavf_is_reset_in_progress(adapter)) |
| 3231 | (IAVF_FLAG_RESET_PENDING | IAVF_FLAG_RESET_NEEDED)) || | ||
| 3232 | adapter->state == __IAVF_RESETTING) | ||
| 3233 | goto freedom; | 3285 | goto freedom; |
| 3234 | 3286 | ||
| 3235 | /* check for error indications */ | 3287 | /* check for error indications */ |
| @@ -4315,6 +4367,7 @@ static int iavf_close(struct net_device *netdev) · 1079 unmodified lines | |||
| 4315 | static int iavf_change_mtu(struct net_device *netdev, int new_mtu) | 4367 | static int iavf_change_mtu(struct net_device *netdev, int new_mtu) |
| 4316 | { | 4368 | { |
| 4317 | struct iavf_adapter *adapter = netdev_priv(netdev); | 4369 | struct iavf_adapter *adapter = netdev_priv(netdev); |
| 4370 | int ret = 0; | ||
| 4318 | 4371 | ||
| 4319 | netdev_dbg(netdev, "changing MTU from %d to %d\n", | 4372 | netdev_dbg(netdev, "changing MTU from %d to %d\n", |
| 4320 | netdev->mtu, new_mtu); | 4373 | netdev->mtu, new_mtu); |
| @@ -4325,11 +4378,15 @@ static int iavf_change_mtu(struct net_device *netdev, int new_mtu) · 4 unmodified lines | |||
| 4325 | } | 4378 | } |
| 4326 | 4379 | ||
| 4327 | if (netif_running(netdev)) { | 4380 | if (netif_running(netdev)) { |
| 4328 | adapter->flags |= IAVF_FLAG_RESET_NEEDED; | 4381 | iavf_schedule_reset(adapter, IAVF_FLAG_RESET_NEEDED); |
| 4329 | queue_work(adapter->wq, &adapter->reset_task); | 4382 | ret = iavf_wait_for_reset(adapter); |
| 4383 | if (ret < 0) | ||
| 4384 | netdev_warn(netdev, "MTU change interrupted waiting for reset"); | ||
| 4385 | else if (ret) | ||
| 4386 | netdev_warn(netdev, "MTU change timed out waiting for reset"); | ||
| 4330 | } | 4387 | } |
| 4331 | 4388 | ||
| 4332 | return 0; | 4389 | return ret; |
| 4333 | } | 4390 | } |
| 4334 | 4391 | ||
| 4335 | #define NETIF_VLAN_OFFLOAD_FEATURES (NETIF_F_HW_VLAN_CTAG_RX | \ | 4392 | #define NETIF_VLAN_OFFLOAD_FEATURES (NETIF_F_HW_VLAN_CTAG_RX | \ |
| @@ -4922,6 +4979,7 @@ static int iavf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 586 unmodified lines | |||
| 4922 | 4979 | ||
| 4923 | INIT_WORK(&adapter->reset_task, iavf_reset_task); | 4980 | INIT_WORK(&adapter->reset_task, iavf_reset_task); |
| 4924 | INIT_WORK(&adapter->adminq_task, iavf_adminq_task); | 4981 | INIT_WORK(&adapter->adminq_task, iavf_adminq_task); |
| 4982 | INIT_WORK(&adapter->finish_config, iavf_finish_config); | ||
| 4925 | INIT_DELAYED_WORK(&adapter->watchdog_task, iavf_watchdog_task); | 4983 | INIT_DELAYED_WORK(&adapter->watchdog_task, iavf_watchdog_task); |
| 4926 | INIT_DELAYED_WORK(&adapter->client_task, iavf_client_task); | 4984 | INIT_DELAYED_WORK(&adapter->client_task, iavf_client_task); |
| 4927 | queue_delayed_work(adapter->wq, &adapter->watchdog_task, | 4985 | queue_delayed_work(adapter->wq, &adapter->watchdog_task, |
| @@ -4930,6 +4988,9 @@ static int iavf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 2 unmodified lines | |||
| 4930 | /* Setup the wait queue for indicating transition to down status */ | 4988 | /* Setup the wait queue for indicating transition to down status */ |
| 4931 | init_waitqueue_head(&adapter->down_waitqueue); | 4989 | init_waitqueue_head(&adapter->down_waitqueue); |
| 4932 | 4990 | ||
| 4991 | /* Setup the wait queue for indicating transition to running state */ | ||
| 4992 | init_waitqueue_head(&adapter->reset_waitqueue); | ||
| 4993 | |||
| 4933 | /* Setup the wait queue for indicating virtchannel events */ | 4994 | /* Setup the wait queue for indicating virtchannel events */ |
| 4934 | init_waitqueue_head(&adapter->vc_waitqueue); | 4995 | init_waitqueue_head(&adapter->vc_waitqueue); |
| 4935 | 4996 | ||
| @@ -5061,13 +5122,15 @@ static void iavf_remove(struct pci_dev *pdev) · 125 unmodified lines | |||
| 5061 | usleep_range(500, 1000); | 5122 | usleep_range(500, 1000); |
| 5062 | } | 5123 | } |
| 5063 | cancel_delayed_work_sync(&adapter->watchdog_task); | 5124 | cancel_delayed_work_sync(&adapter->watchdog_task); |
| 5125 | cancel_work_sync(&adapter->finish_config); | ||
| 5064 | 5126 | ||
| 5127 | rtnl_lock(); | ||
| 5065 | if (adapter->netdev_registered) { | 5128 | if (adapter->netdev_registered) { |
| 5066 | rtnl_lock(); | ||
| 5067 | unregister_netdevice(netdev); | 5129 | unregister_netdevice(netdev); |
| 5068 | adapter->netdev_registered = false; | 5130 | adapter->netdev_registered = false; |
| 5069 | rtnl_unlock(); | ||
| 5070 | } | 5131 | } |
| 5132 | rtnl_unlock(); | ||
| 5133 | |||
| 5071 | if (CLIENT_ALLOWED(adapter)) { | 5134 | if (CLIENT_ALLOWED(adapter)) { |
| 5072 | err = iavf_lan_del_device(adapter); | 5135 | err = iavf_lan_del_device(adapter); |
| 5073 | if (err) | 5136 | if (err) |
| @@ -1961,9 +1961,8 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter, · 1960 unmodified lines | |||
| 1961 | case VIRTCHNL_EVENT_RESET_IMPENDING: | 1961 | case VIRTCHNL_EVENT_RESET_IMPENDING: |
| 1962 | dev_info(&adapter->pdev->dev, "Reset indication received from the PF\n"); | 1962 | dev_info(&adapter->pdev->dev, "Reset indication received from the PF\n"); |
| 1963 | if (!(adapter->flags & IAVF_FLAG_RESET_PENDING)) { | 1963 | if (!(adapter->flags & IAVF_FLAG_RESET_PENDING)) { |
| 1964 | adapter->flags |= IAVF_FLAG_RESET_PENDING; | ||
| 1965 | dev_info(&adapter->pdev->dev, "Scheduling reset task\n"); | 1964 | dev_info(&adapter->pdev->dev, "Scheduling reset task\n"); |
| 1966 | queue_work(adapter->wq, &adapter->reset_task); | 1965 | iavf_schedule_reset(adapter, IAVF_FLAG_RESET_PENDING); |
| 1967 | } | 1966 | } |
| 1968 | break; | 1967 | break; |
| 1969 | default: | 1968 | default: |
| @@ -2237,6 +2236,7 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter, · 267 unmodified lines | |||
| 2237 | 2236 | ||
| 2238 | iavf_process_config(adapter); | 2237 | iavf_process_config(adapter); |
| 2239 | adapter->flags |= IAVF_FLAG_SETUP_NETDEV_FEATURES; | 2238 | adapter->flags |= IAVF_FLAG_SETUP_NETDEV_FEATURES; |
| 2239 | iavf_schedule_finish_config(adapter); | ||
| 2240 | 2240 | ||
| 2241 | iavf_set_queue_vlan_tag_loc(adapter); | 2241 | iavf_set_queue_vlan_tag_loc(adapter); |
| 2242 | 2242 | ||
| @@ -2285,6 +2285,7 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter, · 42 unmodified lines | |||
| 2285 | case VIRTCHNL_OP_ENABLE_QUEUES: | 2285 | case VIRTCHNL_OP_ENABLE_QUEUES: |
| 2286 | /* enable transmits */ | 2286 | /* enable transmits */ |
| 2287 | iavf_irq_enable(adapter, true); | 2287 | iavf_irq_enable(adapter, true); |
| 2288 | wake_up(&adapter->reset_waitqueue); | ||
| 2288 | adapter->flags &= ~IAVF_FLAG_QUEUES_DISABLED; | 2289 | adapter->flags &= ~IAVF_FLAG_QUEUES_DISABLED; |
| 2289 | break; | 2290 | break; |
| 2290 | case VIRTCHNL_OP_DISABLE_QUEUES: | 2291 | case VIRTCHNL_OP_DISABLE_QUEUES: |
| @@ -800,6 +800,8 @@ void ice_vsi_free_q_vectors(struct ice_vsi *vsi) · 799 unmodified lines | |||
| 800 | 800 | ||
| 801 | ice_for_each_q_vector(vsi, v_idx) | 801 | ice_for_each_q_vector(vsi, v_idx) |
| 802 | ice_free_q_vector(vsi, v_idx); | 802 | ice_free_q_vector(vsi, v_idx); |
| 803 | |||
| 804 | vsi->num_q_vectors = 0; | ||
| 803 | } | 805 | } |
| 804 | 806 | ||
| 805 | /** | 807 | /** |
| @@ -2681,8 +2681,13 @@ ice_get_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring, · 2680 unmodified lines | |||
| 2681 | 2681 | ||
| 2682 | ring->rx_max_pending = ICE_MAX_NUM_DESC; | 2682 | ring->rx_max_pending = ICE_MAX_NUM_DESC; |
| 2683 | ring->tx_max_pending = ICE_MAX_NUM_DESC; | 2683 | ring->tx_max_pending = ICE_MAX_NUM_DESC; |
| 2684 | ring->rx_pending = vsi->rx_rings[0]->count; | 2684 | if (vsi->tx_rings && vsi->rx_rings) { |
| 2685 | ring->tx_pending = vsi->tx_rings[0]->count; | 2685 | ring->rx_pending = vsi->rx_rings[0]->count; |
| 2686 | ring->tx_pending = vsi->tx_rings[0]->count; | ||
| 2687 | } else { | ||
| 2688 | ring->rx_pending = 0; | ||
| 2689 | ring->tx_pending = 0; | ||
| 2690 | } | ||
| 2686 | 2691 | ||
| 2687 | /* Rx mini and jumbo rings are not supported */ | 2692 | /* Rx mini and jumbo rings are not supported */ |
| 2688 | ring->rx_mini_max_pending = 0; | 2693 | ring->rx_mini_max_pending = 0; |
| @@ -2716,6 +2721,10 @@ ice_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring, · 27 unmodified lines | |||
| 2716 | return -EINVAL; | 2721 | return -EINVAL; |
| 2717 | } | 2722 | } |
| 2718 | 2723 | ||
| 2724 | /* Return if there is no rings (device is reloading) */ | ||
| 2725 | if (!vsi->tx_rings || !vsi->rx_rings) | ||
| 2726 | return -EBUSY; | ||
| 2727 | |||
| 2719 | new_tx_cnt = ALIGN(ring->tx_pending, ICE_REQ_DESC_MULTIPLE); | 2728 | new_tx_cnt = ALIGN(ring->tx_pending, ICE_REQ_DESC_MULTIPLE); |
| 2720 | if (new_tx_cnt != ring->tx_pending) | 2729 | if (new_tx_cnt != ring->tx_pending) |
| 2721 | netdev_info(netdev, "Requested Tx descriptor count rounded up to %d\n", | 2730 | netdev_info(netdev, "Requested Tx descriptor count rounded up to %d\n", |
| @@ -2972,39 +2972,12 @@ int ice_vsi_release(struct ice_vsi *vsi) · 2971 unmodified lines | |||
| 2972 | return -ENODEV; | 2972 | return -ENODEV; |
| 2973 | pf = vsi->back; | 2973 | pf = vsi->back; |
| 2974 | 2974 | ||
| 2975 | /* do not unregister while driver is in the reset recovery pending | ||
| 2976 | * state. Since reset/rebuild happens through PF service task workqueue, | ||
| 2977 | * it's not a good idea to unregister netdev that is associated to the | ||
| 2978 | * PF that is running the work queue items currently. This is done to | ||
| 2979 | * avoid check_flush_dependency() warning on this wq | ||
| 2980 | */ | ||
| 2981 | if (vsi->netdev && !ice_is_reset_in_progress(pf->state) && | ||
| 2982 | (test_bit(ICE_VSI_NETDEV_REGISTERED, vsi->state))) { | ||
| 2983 | unregister_netdev(vsi->netdev); | ||
| 2984 | clear_bit(ICE_VSI_NETDEV_REGISTERED, vsi->state); | ||
| 2985 | } | ||
| 2986 | |||
| 2987 | if (vsi->type == ICE_VSI_PF) | ||
| 2988 | ice_devlink_destroy_pf_port(pf); | ||
| 2989 | |||
| 2990 | if (test_bit(ICE_FLAG_RSS_ENA, pf->flags)) | 2975 | if (test_bit(ICE_FLAG_RSS_ENA, pf->flags)) |
| 2991 | ice_rss_clean(vsi); | 2976 | ice_rss_clean(vsi); |
| 2992 | 2977 | ||
| 2993 | ice_vsi_close(vsi); | 2978 | ice_vsi_close(vsi); |
| 2994 | ice_vsi_decfg(vsi); | 2979 | ice_vsi_decfg(vsi); |
| 2995 | 2980 | ||
| 2996 | if (vsi->netdev) { | ||
| 2997 | if (test_bit(ICE_VSI_NETDEV_REGISTERED, vsi->state)) { | ||
| 2998 | unregister_netdev(vsi->netdev); | ||
| 2999 | clear_bit(ICE_VSI_NETDEV_REGISTERED, vsi->state); | ||
| 3000 | } | ||
| 3001 | if (test_bit(ICE_VSI_NETDEV_ALLOCD, vsi->state)) { | ||
| 3002 | free_netdev(vsi->netdev); | ||
| 3003 | vsi->netdev = NULL; | ||
| 3004 | clear_bit(ICE_VSI_NETDEV_ALLOCD, vsi->state); | ||
| 3005 | } | ||
| 3006 | } | ||
| 3007 | |||
| 3008 | /* retain SW VSI data structure since it is needed to unregister and | 2981 | /* retain SW VSI data structure since it is needed to unregister and |
| 3009 | * free VSI netdev when PF is not in reset recovery pending state,\ | 2982 | * free VSI netdev when PF is not in reset recovery pending state,\ |
| 3010 | * for ex: during rmmod. | 2983 | * for ex: during rmmod. |
| @@ -4430,9 +4430,9 @@ static int ice_start_eth(struct ice_vsi *vsi) · 4429 unmodified lines | |||
| 4430 | if (err) | 4430 | if (err) |
| 4431 | return err; | 4431 | return err; |
| 4432 | 4432 | ||
| 4433 | rtnl_lock(); | ||
| 4434 | err = ice_vsi_open(vsi); | 4433 | err = ice_vsi_open(vsi); |
| 4435 | rtnl_unlock(); | 4434 | if (err) |
| 4435 | ice_fltr_remove_all(vsi); | ||
| 4436 | 4436 | ||
| 4437 | return err; | 4437 | return err; |
| 4438 | } | 4438 | } |
| @@ -4895,6 +4895,7 @@ int ice_load(struct ice_pf *pf) · 456 unmodified lines | |||
| 4895 | params = ice_vsi_to_params(vsi); | 4895 | params = ice_vsi_to_params(vsi); |
| 4896 | params.flags = ICE_VSI_FLAG_INIT; | 4896 | params.flags = ICE_VSI_FLAG_INIT; |
| 4897 | 4897 | ||
| 4898 | rtnl_lock(); | ||
| 4898 | err = ice_vsi_cfg(vsi, ¶ms); | 4899 | err = ice_vsi_cfg(vsi, ¶ms); |
| 4899 | if (err) | 4900 | if (err) |
| 4900 | goto err_vsi_cfg; | 4901 | goto err_vsi_cfg; |
| @@ -4902,6 +4903,7 @@ int ice_load(struct ice_pf *pf) · 1 unmodified line | |||
| 4902 | err = ice_start_eth(ice_get_main_vsi(pf)); | 4903 | err = ice_start_eth(ice_get_main_vsi(pf)); |
| 4903 | if (err) | 4904 | if (err) |
| 4904 | goto err_start_eth; | 4905 | goto err_start_eth; |
| 4906 | rtnl_unlock(); | ||
| 4905 | 4907 | ||
| 4906 | err = ice_init_rdma(pf); | 4908 | err = ice_init_rdma(pf); |
| 4907 | if (err) | 4909 | if (err) |
| @@ -4916,9 +4918,11 @@ int ice_load(struct ice_pf *pf) · 8 unmodified lines | |||
| 4916 | 4918 | ||
| 4917 | err_init_rdma: | 4919 | err_init_rdma: |
| 4918 | ice_vsi_close(ice_get_main_vsi(pf)); | 4920 | ice_vsi_close(ice_get_main_vsi(pf)); |
| 4921 | rtnl_lock(); | ||
| 4919 | err_start_eth: | 4922 | err_start_eth: |
| 4920 | ice_vsi_decfg(ice_get_main_vsi(pf)); | 4923 | ice_vsi_decfg(ice_get_main_vsi(pf)); |
| 4921 | err_vsi_cfg: | 4924 | err_vsi_cfg: |
| 4925 | rtnl_unlock(); | ||
| 4922 | ice_deinit_dev(pf); | 4926 | ice_deinit_dev(pf); |
| 4923 | return err; | 4927 | return err; |
| 4924 | } | 4928 | } |
| @@ -4931,8 +4935,10 @@ void ice_unload(struct ice_pf *pf) · 6 unmodified lines | |||
| 4931 | { | 4935 | { |
| 4932 | ice_deinit_features(pf); | 4936 | ice_deinit_features(pf); |
| 4933 | ice_deinit_rdma(pf); | 4937 | ice_deinit_rdma(pf); |
| 4938 | rtnl_lock(); | ||
| 4934 | ice_stop_eth(ice_get_main_vsi(pf)); | 4939 | ice_stop_eth(ice_get_main_vsi(pf)); |
| 4935 | ice_vsi_decfg(ice_get_main_vsi(pf)); | 4940 | ice_vsi_decfg(ice_get_main_vsi(pf)); |
| 4941 | rtnl_unlock(); | ||
| 4936 | ice_deinit_dev(pf); | 4942 | ice_deinit_dev(pf); |
| 4937 | } | 4943 | } |
| 4938 | 4944 | ||
| @@ -2828,9 +2828,8 @@ static void igc_xdp_xmit_zc(struct igc_ring *ring) · 2827 unmodified lines | |||
| 2828 | struct netdev_queue *nq = txring_txq(ring); | 2828 | struct netdev_queue *nq = txring_txq(ring); |
| 2829 | union igc_adv_tx_desc *tx_desc = NULL; | 2829 | union igc_adv_tx_desc *tx_desc = NULL; |
| 2830 | int cpu = smp_processor_id(); | 2830 | int cpu = smp_processor_id(); |
| 2831 | u16 ntu = ring->next_to_use; | ||
| 2832 | struct xdp_desc xdp_desc; | 2831 | struct xdp_desc xdp_desc; |
| 2833 | u16 budget; | 2832 | u16 budget, ntu; |
| 2834 | 2833 | ||
| 2835 | if (!netif_carrier_ok(ring->netdev)) | 2834 | if (!netif_carrier_ok(ring->netdev)) |
| 2836 | return; | 2835 | return; |
| @@ -2840,6 +2839,7 @@ static void igc_xdp_xmit_zc(struct igc_ring *ring) · 3 unmodified lines | |||
| 2840 | /* Avoid transmit queue timeout since we share it with the slow path */ | 2839 | /* Avoid transmit queue timeout since we share it with the slow path */ |
| 2841 | txq_trans_cond_update(nq); | 2840 | txq_trans_cond_update(nq); |
| 2842 | 2841 | ||
| 2842 | ntu = ring->next_to_use; | ||
| 2843 | budget = igc_desc_unused(ring); | 2843 | budget = igc_desc_unused(ring); |
| 2844 | 2844 | ||
| 2845 | while (xsk_tx_peek_desc(pool, &xdp_desc) && budget--) { | 2845 | while (xsk_tx_peek_desc(pool, &xdp_desc) && budget--) { |
| @@ -4,6 +4,7 @@ · 3 unmodified lines | |||
| 4 | * Copyright (C) 2022 Marvell. | 4 | * Copyright (C) 2022 Marvell. |
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | #include <crypto/skcipher.h> | ||
| 7 | #include <linux/rtnetlink.h> | 8 | #include <linux/rtnetlink.h> |
| 8 | #include <linux/bitfield.h> | 9 | #include <linux/bitfield.h> |
| 9 | #include "otx2_common.h" | 10 | #include "otx2_common.h" |
| @@ -42,6 +43,56 @@ · 32 unmodified lines | |||
| 42 | #define MCS_TCI_E 0x08 /* encryption */ | 43 | #define MCS_TCI_E 0x08 /* encryption */ |
| 43 | #define MCS_TCI_C 0x04 /* changed text */ | 44 | #define MCS_TCI_C 0x04 /* changed text */ |
| 44 | 45 | ||
| 46 | #define CN10K_MAX_HASH_LEN 16 | ||
| 47 | #define CN10K_MAX_SAK_LEN 32 | ||
| 48 | |||
| 49 | static int cn10k_ecb_aes_encrypt(struct otx2_nic *pfvf, u8 *sak, | ||
| 50 | u16 sak_len, u8 *hash) | ||
| 51 | { | ||
| 52 | u8 data[CN10K_MAX_HASH_LEN] = { 0 }; | ||
| 53 | struct skcipher_request *req = NULL; | ||
| 54 | struct scatterlist sg_src, sg_dst; | ||
| 55 | struct crypto_skcipher *tfm; | ||
| 56 | DECLARE_CRYPTO_WAIT(wait); | ||
| 57 | int err; | ||
| 58 | |||
| 59 | tfm = crypto_alloc_skcipher("ecb(aes)", 0, 0); | ||
| 60 | if (IS_ERR(tfm)) { | ||
| 61 | dev_err(pfvf->dev, "failed to allocate transform for ecb-aes\n"); | ||
| 62 | return PTR_ERR(tfm); | ||
| 63 | } | ||
| 64 | |||
| 65 | req = skcipher_request_alloc(tfm, GFP_KERNEL); | ||
| 66 | if (!req) { | ||
| 67 | dev_err(pfvf->dev, "failed to allocate request for skcipher\n"); | ||
| 68 | err = -ENOMEM; | ||
| 69 | goto free_tfm; | ||
| 70 | } | ||
| 71 | |||
| 72 | err = crypto_skcipher_setkey(tfm, sak, sak_len); | ||
| 73 | if (err) { | ||
| 74 | dev_err(pfvf->dev, "failed to set key for skcipher\n"); | ||
| 75 | goto free_req; | ||
| 76 | } | ||
| 77 | |||
| 78 | /* build sg list */ | ||
| 79 | sg_init_one(&sg_src, data, CN10K_MAX_HASH_LEN); | ||
| 80 | sg_init_one(&sg_dst, hash, CN10K_MAX_HASH_LEN); | ||
| 81 | |||
| 82 | skcipher_request_set_callback(req, 0, crypto_req_done, &wait); | ||
| 83 | skcipher_request_set_crypt(req, &sg_src, &sg_dst, | ||
| 84 | CN10K_MAX_HASH_LEN, NULL); | ||
| 85 | |||
| 86 | err = crypto_skcipher_encrypt(req); | ||
| 87 | err = crypto_wait_req(err, &wait); | ||
| 88 | |||
| 89 | free_req: | ||
| 90 | skcipher_request_free(req); | ||
| 91 | free_tfm: | ||
| 92 | crypto_free_skcipher(tfm); | ||
| 93 | return err; | ||
| 94 | } | ||
| 95 | |||
| 45 | static struct cn10k_mcs_txsc *cn10k_mcs_get_txsc(struct cn10k_mcs_cfg *cfg, | 96 | static struct cn10k_mcs_txsc *cn10k_mcs_get_txsc(struct cn10k_mcs_cfg *cfg, |
| 46 | struct macsec_secy *secy) | 97 | struct macsec_secy *secy) |
| 47 | { | 98 | { |
| @@ -330,19 +381,53 @@ fail: · 282 unmodified lines | |||
| 330 | return ret; | 381 | return ret; |
| 331 | } | 382 | } |
| 332 | 383 | ||
| 384 | static int cn10k_mcs_write_keys(struct otx2_nic *pfvf, | ||
| 385 | struct macsec_secy *secy, | ||
| 386 | struct mcs_sa_plcy_write_req *req, | ||
| 387 | u8 *sak, u8 *salt, ssci_t ssci) | ||
| 388 | { | ||
| 389 | u8 hash_rev[CN10K_MAX_HASH_LEN]; | ||
| 390 | u8 sak_rev[CN10K_MAX_SAK_LEN]; | ||
| 391 | u8 salt_rev[MACSEC_SALT_LEN]; | ||
| 392 | u8 hash[CN10K_MAX_HASH_LEN]; | ||
| 393 | u32 ssci_63_32; | ||
| 394 | int err, i; | ||
| 395 | |||
| 396 | err = cn10k_ecb_aes_encrypt(pfvf, sak, secy->key_len, hash); | ||
| 397 | if (err) { | ||
| 398 | dev_err(pfvf->dev, "Generating hash using ECB(AES) failed\n"); | ||
| 399 | return err; | ||
| 400 | } | ||
| 401 | |||
| 402 | for (i = 0; i < secy->key_len; i++) | ||
| 403 | sak_rev[i] = sak[secy->key_len - 1 - i]; | ||
| 404 | |||
| 405 | for (i = 0; i < CN10K_MAX_HASH_LEN; i++) | ||
| 406 | hash_rev[i] = hash[CN10K_MAX_HASH_LEN - 1 - i]; | ||
| 407 | |||
| 408 | for (i = 0; i < MACSEC_SALT_LEN; i++) | ||
| 409 | salt_rev[i] = salt[MACSEC_SALT_LEN - 1 - i]; | ||
| 410 | |||
| 411 | ssci_63_32 = (__force u32)cpu_to_be32((__force u32)ssci); | ||
| 412 | |||
| 413 | memcpy(&req->plcy[0][0], sak_rev, secy->key_len); | ||
| 414 | memcpy(&req->plcy[0][4], hash_rev, CN10K_MAX_HASH_LEN); | ||
| 415 | memcpy(&req->plcy[0][6], salt_rev, MACSEC_SALT_LEN); | ||
| 416 | req->plcy[0][7] |= (u64)ssci_63_32 << 32; | ||
| 417 | |||
| 418 | return 0; | ||
| 419 | } | ||
| 420 | |||
| 333 | static int cn10k_mcs_write_rx_sa_plcy(struct otx2_nic *pfvf, | 421 | static int cn10k_mcs_write_rx_sa_plcy(struct otx2_nic *pfvf, |
| 334 | struct macsec_secy *secy, | 422 | struct macsec_secy *secy, |
| 335 | struct cn10k_mcs_rxsc *rxsc, | 423 | struct cn10k_mcs_rxsc *rxsc, |
| 336 | u8 assoc_num, bool sa_in_use) | 424 | u8 assoc_num, bool sa_in_use) |
| 337 | { | 425 | { |
| 338 | unsigned char *src = rxsc->sa_key[assoc_num]; | ||
| 339 | struct mcs_sa_plcy_write_req *plcy_req; | 426 | struct mcs_sa_plcy_write_req *plcy_req; |
| 340 | u8 *salt_p = rxsc->salt[assoc_num]; | 427 | u8 *sak = rxsc->sa_key[assoc_num]; |
| 428 | u8 *salt = rxsc->salt[assoc_num]; | ||
| 341 | struct mcs_rx_sc_sa_map *map_req; | 429 | struct mcs_rx_sc_sa_map *map_req; |
| 342 | struct mbox *mbox = &pfvf->mbox; | 430 | struct mbox *mbox = &pfvf->mbox; |
| 343 | u64 ssci_salt_95_64 = 0; | ||
| 344 | u8 reg, key_len; | ||
| 345 | u64 salt_63_0; | ||
| 346 | int ret; | 431 | int ret; |
| 347 | 432 | ||
| 348 | mutex_lock(&mbox->lock); | 433 | mutex_lock(&mbox->lock); |
| @@ -360,20 +445,10 @@ static int cn10k_mcs_write_rx_sa_plcy(struct otx2_nic *pfvf, · 11 unmodified lines | |||
| 360 | goto fail; | 445 | goto fail; |
| 361 | } | 446 | } |
| 362 | 447 | ||
| 363 | for (reg = 0, key_len = 0; key_len < secy->key_len; key_len += 8) { | 448 | ret = cn10k_mcs_write_keys(pfvf, secy, plcy_req, sak, |
| 364 | memcpy((u8 *)&plcy_req->plcy[0][reg], | 449 | salt, rxsc->ssci[assoc_num]); |
| 365 | (src + reg * 8), 8); | 450 | if (ret) |
| 366 | reg++; | 451 | goto fail; |
| 367 | } | ||
| 368 | |||
| 369 | if (secy->xpn) { | ||
| 370 | memcpy((u8 *)&salt_63_0, salt_p, 8); | ||
| 371 | memcpy((u8 *)&ssci_salt_95_64, salt_p + 8, 4); | ||
| 372 | ssci_salt_95_64 |= (__force u64)rxsc->ssci[assoc_num] << 32; | ||
| 373 | |||
| 374 | plcy_req->plcy[0][6] = salt_63_0; | ||
| 375 | plcy_req->plcy[0][7] = ssci_salt_95_64; | ||
| 376 | } | ||
| 377 | 452 | ||
| 378 | plcy_req->sa_index[0] = rxsc->hw_sa_id[assoc_num]; | 453 | plcy_req->sa_index[0] = rxsc->hw_sa_id[assoc_num]; |
| 379 | plcy_req->sa_cnt = 1; | 454 | plcy_req->sa_cnt = 1; |
| @@ -586,13 +661,10 @@ static int cn10k_mcs_write_tx_sa_plcy(struct otx2_nic *pfvf, · 206 unmodified lines | |||
| 586 | struct cn10k_mcs_txsc *txsc, | 661 | struct cn10k_mcs_txsc *txsc, |
| 587 | u8 assoc_num) | 662 | u8 assoc_num) |
| 588 | { | 663 | { |
| 589 | unsigned char *src = txsc->sa_key[assoc_num]; | ||
| 590 | struct mcs_sa_plcy_write_req *plcy_req; | 664 | struct mcs_sa_plcy_write_req *plcy_req; |
| 591 | u8 *salt_p = txsc->salt[assoc_num]; | 665 | u8 *sak = txsc->sa_key[assoc_num]; |
| 666 | u8 *salt = txsc->salt[assoc_num]; | ||
| 592 | struct mbox *mbox = &pfvf->mbox; | 667 | struct mbox *mbox = &pfvf->mbox; |
| 593 | u64 ssci_salt_95_64 = 0; | ||
| 594 | u8 reg, key_len; | ||
| 595 | u64 salt_63_0; | ||
| 596 | int ret; | 668 | int ret; |
| 597 | 669 | ||
| 598 | mutex_lock(&mbox->lock); | 670 | mutex_lock(&mbox->lock); |
| @@ -603,19 +675,10 @@ static int cn10k_mcs_write_tx_sa_plcy(struct otx2_nic *pfvf, · 4 unmodified lines | |||
| 603 | goto fail; | 675 | goto fail; |
| 604 | } | 676 | } |
| 605 | 677 | ||
| 606 | for (reg = 0, key_len = 0; key_len < secy->key_len; key_len += 8) { | 678 | ret = cn10k_mcs_write_keys(pfvf, secy, plcy_req, sak, |
| 607 | memcpy((u8 *)&plcy_req->plcy[0][reg], (src + reg * 8), 8); | 679 | salt, txsc->ssci[assoc_num]); |
| 608 | reg++; | 680 | if (ret) |
| 609 | } | 681 | goto fail; |
| 610 | |||
| 611 | if (secy->xpn) { | ||
| 612 | memcpy((u8 *)&salt_63_0, salt_p, 8); | ||
| 613 | memcpy((u8 *)&ssci_salt_95_64, salt_p + 8, 4); | ||
| 614 | ssci_salt_95_64 |= (__force u64)txsc->ssci[assoc_num] << 32; | ||
| 615 | |||
| 616 | plcy_req->plcy[0][6] = salt_63_0; | ||
| 617 | plcy_req->plcy[0][7] = ssci_salt_95_64; | ||
| 618 | } | ||
| 619 | 682 | ||
| 620 | plcy_req->plcy[0][8] = assoc_num; | 683 | plcy_req->plcy[0][8] = assoc_num; |
| 621 | plcy_req->sa_index[0] = txsc->hw_sa_id[assoc_num]; | 684 | plcy_req->sa_index[0] = txsc->hw_sa_id[assoc_num]; |
| @@ -1454,8 +1454,9 @@ static int otx2_init_hw_resources(struct otx2_nic *pf) · 1453 unmodified lines | |||
| 1454 | if (err) | 1454 | if (err) |
| 1455 | goto err_free_npa_lf; | 1455 | goto err_free_npa_lf; |
| 1456 | 1456 | ||
| 1457 | /* Enable backpressure */ | 1457 | /* Enable backpressure for CGX mapped PF/VFs */ |
| 1458 | otx2_nix_config_bp(pf, true); | 1458 | if (!is_otx2_lbkvf(pf->pdev)) |
| 1459 | otx2_nix_config_bp(pf, true); | ||
| 1459 | 1460 | ||
| 1460 | /* Init Auras and pools used by NIX RQ, for free buffer ptrs */ | 1461 | /* Init Auras and pools used by NIX RQ, for free buffer ptrs */ |
| 1461 | err = otx2_rq_aura_pool_init(pf); | 1462 | err = otx2_rq_aura_pool_init(pf); |
| @@ -3846,23 +3846,6 @@ static int mtk_hw_deinit(struct mtk_eth *eth) · 3845 unmodified lines | |||
| 3846 | return 0; | 3846 | return 0; |
| 3847 | } | 3847 | } |
| 3848 | 3848 | ||
| 3849 | static int __init mtk_init(struct net_device *dev) | ||
| 3850 | { | ||
| 3851 | struct mtk_mac *mac = netdev_priv(dev); | ||
| 3852 | struct mtk_eth *eth = mac->hw; | ||
| 3853 | int ret; | ||
| 3854 | |||
| 3855 | ret = of_get_ethdev_address(mac->of_node, dev); | ||
| 3856 | if (ret) { | ||
| 3857 | /* If the mac address is invalid, use random mac address */ | ||
| 3858 | eth_hw_addr_random(dev); | ||
| 3859 | dev_err(eth->dev, "generated random MAC address %pM\n", | ||
| 3860 | dev->dev_addr); | ||
| 3861 | } | ||
| 3862 | |||
| 3863 | return 0; | ||
| 3864 | } | ||
| 3865 | |||
| 3866 | static void mtk_uninit(struct net_device *dev) | 3849 | static void mtk_uninit(struct net_device *dev) |
| 3867 | { | 3850 | { |
| 3868 | struct mtk_mac *mac = netdev_priv(dev); | 3851 | struct mtk_mac *mac = netdev_priv(dev); |
| @@ -4278,7 +4261,6 @@ static const struct ethtool_ops mtk_ethtool_ops = { · 409 unmodified lines | |||
| 4278 | }; | 4261 | }; |
| 4279 | 4262 | ||
| 4280 | static const struct net_device_ops mtk_netdev_ops = { | 4263 | static const struct net_device_ops mtk_netdev_ops = { |
| 4281 | .ndo_init = mtk_init, | ||
| 4282 | .ndo_uninit = mtk_uninit, | 4264 | .ndo_uninit = mtk_uninit, |
| 4283 | .ndo_open = mtk_open, | 4265 | .ndo_open = mtk_open, |
| 4284 | .ndo_stop = mtk_stop, | 4266 | .ndo_stop = mtk_stop, |
| @@ -4340,6 +4322,17 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) · 55 unmodified lines | |||
| 4340 | mac->hw = eth; | 4322 | mac->hw = eth; |
| 4341 | mac->of_node = np; | 4323 | mac->of_node = np; |
| 4342 | 4324 | ||
| 4325 | err = of_get_ethdev_address(mac->of_node, eth->netdev[id]); | ||
| 4326 | if (err == -EPROBE_DEFER) | ||
| 4327 | return err; | ||
| 4328 | |||
| 4329 | if (err) { | ||
| 4330 | /* If the mac address is invalid, use random mac address */ | ||
| 4331 | eth_hw_addr_random(eth->netdev[id]); | ||
| 4332 | dev_err(eth->dev, "generated random MAC address %pM\n", | ||
| 4333 | eth->netdev[id]->dev_addr); | ||
| 4334 | } | ||
| 4335 | |||
| 4343 | memset(mac->hwlro_ip, 0, sizeof(mac->hwlro_ip)); | 4336 | memset(mac->hwlro_ip, 0, sizeof(mac->hwlro_ip)); |
| 4344 | mac->hwlro_ip_cnt = 0; | 4337 | mac->hwlro_ip_cnt = 0; |
| 4345 | 4338 | ||
| @@ -98,7 +98,7 @@ mtk_ppe_debugfs_foe_show(struct seq_file *m, void *private, bool bind) · 97 unmodified lines | |||
| 98 | 98 | ||
| 99 | acct = mtk_foe_entry_get_mib(ppe, i, NULL); | 99 | acct = mtk_foe_entry_get_mib(ppe, i, NULL); |
| 100 | 100 | ||
| 101 | type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1); | 101 | type = mtk_get_ib1_pkt_type(ppe->eth, entry->ib1); |
| 102 | seq_printf(m, "%05x %s %7s", i, | 102 | seq_printf(m, "%05x %s %7s", i, |
| 103 | mtk_foe_entry_state_str(state), | 103 | mtk_foe_entry_state_str(state), |
| 104 | mtk_foe_pkt_type_str(type)); | 104 | mtk_foe_pkt_type_str(type)); |
| @@ -368,7 +368,8 @@ static bool ocelot_fdma_receive_skb(struct ocelot *ocelot, struct sk_buff *skb) · 367 unmodified lines | |||
| 368 | if (unlikely(!ndev)) | 368 | if (unlikely(!ndev)) |
| 369 | return false; | 369 | return false; |
| 370 | 370 | ||
| 371 | pskb_trim(skb, skb->len - ETH_FCS_LEN); | 371 | if (pskb_trim(skb, skb->len - ETH_FCS_LEN)) |
| 372 | return false; | ||
| 372 | 373 | ||
| 373 | skb->dev = ndev; | 374 | skb->dev = ndev; |
| 374 | skb->protocol = eth_type_trans(skb, skb->dev); | 375 | skb->protocol = eth_type_trans(skb, skb->dev); |
| @@ -1260,8 +1260,11 @@ static int emac_tso_csum(struct emac_adapter *adpt, · 1259 unmodified lines | |||
| 1260 | if (skb->protocol == htons(ETH_P_IP)) { | 1260 | if (skb->protocol == htons(ETH_P_IP)) { |
| 1261 | u32 pkt_len = ((unsigned char *)ip_hdr(skb) - skb->data) | 1261 | u32 pkt_len = ((unsigned char *)ip_hdr(skb) - skb->data) |
| 1262 | + ntohs(ip_hdr(skb)->tot_len); | 1262 | + ntohs(ip_hdr(skb)->tot_len); |
| 1263 | if (skb->len > pkt_len) | 1263 | if (skb->len > pkt_len) { |
| 1264 | pskb_trim(skb, pkt_len); | 1264 | ret = pskb_trim(skb, pkt_len); |
| 1265 | if (unlikely(ret)) | ||
| 1266 | return ret; | ||
| 1267 | } | ||
| 1265 | } | 1268 | } |
| 1266 | 1269 | ||
| 1267 | hdr_len = skb_tcp_all_headers(skb); | 1270 | hdr_len = skb_tcp_all_headers(skb); |
| @@ -623,6 +623,7 @@ struct rtl8169_private { · 622 unmodified lines | |||
| 623 | int cfg9346_usage_count; | 623 | int cfg9346_usage_count; |
| 624 | 624 | ||
| 625 | unsigned supports_gmii:1; | 625 | unsigned supports_gmii:1; |
| 626 | unsigned aspm_manageable:1; | ||
| 626 | dma_addr_t counters_phys_addr; | 627 | dma_addr_t counters_phys_addr; |
| 627 | struct rtl8169_counters *counters; | 628 | struct rtl8169_counters *counters; |
| 628 | struct rtl8169_tc_offsets tc_offset; | 629 | struct rtl8169_tc_offsets tc_offset; |
| @@ -2746,7 +2747,15 @@ static void rtl_hw_aspm_clkreq_enable(struct rtl8169_private *tp, bool enable) · 2117 unmodified lines | |||
| 2746 | if (tp->mac_version < RTL_GIGA_MAC_VER_32) | 2747 | if (tp->mac_version < RTL_GIGA_MAC_VER_32) |
| 2747 | return; | 2748 | return; |
| 2748 | 2749 | ||
| 2749 | if (enable) { | 2750 | /* Don't enable ASPM in the chip if OS can't control ASPM */ |
| 2751 | if (enable && tp->aspm_manageable) { | ||
| 2752 | /* On these chip versions ASPM can even harm | ||
| 2753 | * bus communication of other PCI devices. | ||
| 2754 | */ | ||
| 2755 | if (tp->mac_version == RTL_GIGA_MAC_VER_42 || | ||
| 2756 | tp->mac_version == RTL_GIGA_MAC_VER_43) | ||
| 2757 | return; | ||
| 2758 | |||
| 2750 | rtl_mod_config5(tp, 0, ASPM_en); | 2759 | rtl_mod_config5(tp, 0, ASPM_en); |
| 2751 | rtl_mod_config2(tp, 0, ClkReqEn); | 2760 | rtl_mod_config2(tp, 0, ClkReqEn); |
| 2752 | 2761 | ||
| @@ -4514,10 +4523,6 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) · 1761 unmodified lines | |||
| 4514 | } | 4523 | } |
| 4515 | 4524 | ||
| 4516 | if (napi_schedule_prep(&tp->napi)) { | 4525 | if (napi_schedule_prep(&tp->napi)) { |
| 4517 | rtl_unlock_config_regs(tp); | ||
| 4518 | rtl_hw_aspm_clkreq_enable(tp, false); | ||
| 4519 | rtl_lock_config_regs(tp); | ||
| 4520 | |||
| 4521 | rtl_irq_disable(tp); | 4526 | rtl_irq_disable(tp); |
| 4522 | __napi_schedule(&tp->napi); | 4527 | __napi_schedule(&tp->napi); |
| 4523 | } | 4528 | } |
| @@ -4577,14 +4582,9 @@ static int rtl8169_poll(struct napi_struct *napi, int budget) · 53 unmodified lines | |||
| 4577 | 4582 | ||
| 4578 | work_done = rtl_rx(dev, tp, budget); | 4583 | work_done = rtl_rx(dev, tp, budget); |
| 4579 | 4584 | ||
| 4580 | if (work_done < budget && napi_complete_done(napi, work_done)) { | 4585 | if (work_done < budget && napi_complete_done(napi, work_done)) |
| 4581 | rtl_irq_enable(tp); | 4586 | rtl_irq_enable(tp); |
| 4582 | 4587 | ||
| 4583 | rtl_unlock_config_regs(tp); | ||
| 4584 | rtl_hw_aspm_clkreq_enable(tp, true); | ||
| 4585 | rtl_lock_config_regs(tp); | ||
| 4586 | } | ||
| 4587 | |||
| 4588 | return work_done; | 4588 | return work_done; |
| 4589 | } | 4589 | } |
| 4590 | 4590 | ||
| @@ -5158,6 +5158,16 @@ done: · 567 unmodified lines | |||
| 5158 | rtl_rar_set(tp, mac_addr); | 5158 | rtl_rar_set(tp, mac_addr); |
| 5159 | } | 5159 | } |
| 5160 | 5160 | ||
| 5161 | /* register is set if system vendor successfully tested ASPM 1.2 */ | ||
| 5162 | static bool rtl_aspm_is_safe(struct rtl8169_private *tp) | ||
| 5163 | { | ||
| 5164 | if (tp->mac_version >= RTL_GIGA_MAC_VER_61 && | ||
| 5165 | r8168_mac_ocp_read(tp, 0xc0b2) & 0xf) | ||
| 5166 | return true; | ||
| 5167 | |||
| 5168 | return false; | ||
| 5169 | } | ||
| 5170 | |||
| 5161 | static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | 5171 | static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
| 5162 | { | 5172 | { |
| 5163 | struct rtl8169_private *tp; | 5173 | struct rtl8169_private *tp; |
| @@ -5227,6 +5237,19 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) · 63 unmodified lines | |||
| 5227 | xid); | 5237 | xid); |
| 5228 | tp->mac_version = chipset; | 5238 | tp->mac_version = chipset; |
| 5229 | 5239 | ||
| 5240 | /* Disable ASPM L1 as that cause random device stop working | ||
| 5241 | * problems as well as full system hangs for some PCIe devices users. | ||
| 5242 | * Chips from RTL8168h partially have issues with L1.2, but seem | ||
| 5243 | * to work fine with L1 and L1.1. | ||
| 5244 | */ | ||
| 5245 | if (rtl_aspm_is_safe(tp)) | ||
| 5246 | rc = 0; | ||
| 5247 | else if (tp->mac_version >= RTL_GIGA_MAC_VER_46) | ||
| 5248 | rc = pci_disable_link_state(pdev, PCIE_LINK_STATE_L1_2); | ||
| 5249 | else | ||
| 5250 | rc = pci_disable_link_state(pdev, PCIE_LINK_STATE_L1); | ||
| 5251 | tp->aspm_manageable = !rc; | ||
| 5252 | |||
| 5230 | tp->dash_type = rtl_check_dash(tp); | 5253 | tp->dash_type = rtl_check_dash(tp); |
| 5231 | 5254 | ||
| 5232 | tp->cp_cmd = RTL_R16(tp, CPlusCmd) & CPCMD_MASK; | 5255 | tp->cp_cmd = RTL_R16(tp, CPlusCmd) & CPCMD_MASK; |
| @@ -106,23 +106,37 @@ struct cpsw_ale_dev_id { · 105 unmodified lines | |||
| 106 | 106 | ||
| 107 | static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits) | 107 | static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits) |
| 108 | { | 108 | { |
| 109 | int idx; | 109 | int idx, idx2; |
| 110 | u32 hi_val = 0; | ||
| 110 | 111 | ||
| 111 | idx = start / 32; | 112 | idx = start / 32; |
| 113 | idx2 = (start + bits - 1) / 32; | ||
| 114 | /* Check if bits to be fetched exceed a word */ | ||
| 115 | if (idx != idx2) { | ||
| 116 | idx2 = 2 - idx2; /* flip */ | ||
| 117 | hi_val = ale_entry[idx2] << ((idx2 * 32) - start); | ||
| 118 | } | ||
| 112 | start -= idx * 32; | 119 | start -= idx * 32; |
| 113 | idx = 2 - idx; /* flip */ | 120 | idx = 2 - idx; /* flip */ |
| 114 | return (ale_entry[idx] >> start) & BITMASK(bits); | 121 | return (hi_val + (ale_entry[idx] >> start)) & BITMASK(bits); |
| 115 | } | 122 | } |
| 116 | 123 | ||
| 117 | static inline void cpsw_ale_set_field(u32 *ale_entry, u32 start, u32 bits, | 124 | static inline void cpsw_ale_set_field(u32 *ale_entry, u32 start, u32 bits, |
| 118 | u32 value) | 125 | u32 value) |
| 119 | { | 126 | { |
| 120 | int idx; | 127 | int idx, idx2; |
| 121 | 128 | ||
| 122 | value &= BITMASK(bits); | 129 | value &= BITMASK(bits); |
| 123 | idx = start / 32; | 130 | idx = start / 32; |
| 131 | idx2 = (start + bits - 1) / 32; | ||
| 132 | /* Check if bits to be set exceed a word */ | ||
| 133 | if (idx != idx2) { | ||
| 134 | idx2 = 2 - idx2; /* flip */ | ||
| 135 | ale_entry[idx2] &= ~(BITMASK(bits + start - (idx2 * 32))); | ||
| 136 | ale_entry[idx2] |= (value >> ((idx2 * 32) - start)); | ||
| 137 | } | ||
| 124 | start -= idx * 32; | 138 | start -= idx * 32; |
| 125 | idx = 2 - idx; /* flip */ | 139 | idx = 2 - idx; /* flip */ |
| 126 | ale_entry[idx] &= ~(BITMASK(bits) << start); | 140 | ale_entry[idx] &= ~(BITMASK(bits) << start); |
| 127 | ale_entry[idx] |= (value << start); | 141 | ale_entry[idx] |= (value << start); |
| 128 | } | 142 | } |
| @@ -1511,7 +1511,6 @@ static void wx_configure_rx(struct wx *wx) · 1510 unmodified lines | |||
| 1511 | psrtype = WX_RDB_PL_CFG_L4HDR | | 1511 | psrtype = WX_RDB_PL_CFG_L4HDR | |
| 1512 | WX_RDB_PL_CFG_L3HDR | | 1512 | WX_RDB_PL_CFG_L3HDR | |
| 1513 | WX_RDB_PL_CFG_L2HDR | | 1513 | WX_RDB_PL_CFG_L2HDR | |
| 1514 | WX_RDB_PL_CFG_TUN_TUNHDR | | ||
| 1515 | WX_RDB_PL_CFG_TUN_TUNHDR; | 1514 | WX_RDB_PL_CFG_TUN_TUNHDR; |
| 1516 | wr32(wx, WX_RDB_PL_CFG(0), psrtype); | 1515 | wr32(wx, WX_RDB_PL_CFG(0), psrtype); |
| 1517 | 1516 | ||
| @@ -3451,23 +3451,30 @@ static int __init phy_init(void) · 3450 unmodified lines | |||
| 3451 | { | 3451 | { |
| 3452 | int rc; | 3452 | int rc; |
| 3453 | 3453 | ||
| 3454 | ethtool_set_ethtool_phy_ops(&phy_ethtool_phy_ops); | ||
| 3455 | |||
| 3454 | rc = mdio_bus_init(); | 3456 | rc = mdio_bus_init(); |
| 3455 | if (rc) | 3457 | if (rc) |
| 3456 | return rc; | 3458 | goto err_ethtool_phy_ops; |
| 3457 | 3459 | ||
| 3458 | ethtool_set_ethtool_phy_ops(&phy_ethtool_phy_ops); | ||
| 3459 | features_init(); | 3460 | features_init(); |
| 3460 | 3461 | ||
| 3461 | rc = phy_driver_register(&genphy_c45_driver, THIS_MODULE); | 3462 | rc = phy_driver_register(&genphy_c45_driver, THIS_MODULE); |
| 3462 | if (rc) | 3463 | if (rc) |
| 3463 | goto err_c45; | 3464 | goto err_mdio_bus; |
| 3464 | 3465 | ||
| 3465 | rc = phy_driver_register(&genphy_driver, THIS_MODULE); | 3466 | rc = phy_driver_register(&genphy_driver, THIS_MODULE); |
| 3466 | if (rc) { | 3467 | if (rc) |
| 3467 | phy_driver_unregister(&genphy_c45_driver); | 3468 | goto err_c45; |
| 3469 | |||
| 3470 | return 0; | ||
| 3471 | |||
| 3468 | err_c45: | 3472 | err_c45: |
| 3469 | mdio_bus_exit(); | 3473 | phy_driver_unregister(&genphy_c45_driver); |
| 3470 | } | 3474 | err_mdio_bus: |
| 3475 | mdio_bus_exit(); | ||
| 3476 | err_ethtool_phy_ops: | ||
| 3477 | ethtool_set_ethtool_phy_ops(NULL); | ||
| 3471 | 3478 | ||
| 3472 | return rc; | 3479 | return rc; |
| 3473 | } | 3480 | } |
| @@ -1775,6 +1775,10 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) · 1774 unmodified lines | |||
| 1775 | } else if (!info->in || !info->out) | 1775 | } else if (!info->in || !info->out) |
| 1776 | status = usbnet_get_endpoints (dev, udev); | 1776 | status = usbnet_get_endpoints (dev, udev); |
| 1777 | else { | 1777 | else { |
| 1778 | u8 ep_addrs[3] = { | ||
| 1779 | info->in + USB_DIR_IN, info->out + USB_DIR_OUT, 0 | ||
| 1780 | }; | ||
| 1781 | |||
| 1778 | dev->in = usb_rcvbulkpipe (xdev, info->in); | 1782 | dev->in = usb_rcvbulkpipe (xdev, info->in); |
| 1779 | dev->out = usb_sndbulkpipe (xdev, info->out); | 1783 | dev->out = usb_sndbulkpipe (xdev, info->out); |
| 1780 | if (!(info->flags & FLAG_NO_SETINT)) | 1784 | if (!(info->flags & FLAG_NO_SETINT)) |
| @@ -1784,6 +1788,8 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) · 3 unmodified lines | |||
| 1784 | else | 1788 | else |
| 1785 | status = 0; | 1789 | status = 0; |
| 1786 | 1790 | ||
| 1791 | if (status == 0 && !usb_check_bulk_endpoints(udev, ep_addrs)) | ||
| 1792 | status = -EINVAL; | ||
| 1787 | } | 1793 | } |
| 1788 | if (status >= 0 && dev->status) | 1794 | if (status >= 0 && dev->status) |
| 1789 | status = init_status (dev, udev); | 1795 | status = init_status (dev, udev); |
| @@ -664,7 +664,7 @@ static int vrf_finish_output6(struct net *net, struct sock *sk, · 663 unmodified lines | |||
| 664 | skb->protocol = htons(ETH_P_IPV6); | 664 | skb->protocol = htons(ETH_P_IPV6); |
| 665 | skb->dev = dev; | 665 | skb->dev = dev; |
| 666 | 666 | ||
| 667 | rcu_read_lock_bh(); | 667 | rcu_read_lock(); |
| 668 | nexthop = rt6_nexthop((struct rt6_info *)dst, &ipv6_hdr(skb)->daddr); | 668 | nexthop = rt6_nexthop((struct rt6_info *)dst, &ipv6_hdr(skb)->daddr); |
| 669 | neigh = __ipv6_neigh_lookup_noref(dst->dev, nexthop); | 669 | neigh = __ipv6_neigh_lookup_noref(dst->dev, nexthop); |
| 670 | if (unlikely(!neigh)) | 670 | if (unlikely(!neigh)) |
| @@ -672,10 +672,10 @@ static int vrf_finish_output6(struct net *net, struct sock *sk, · 1 unmodified line | |||
| 672 | if (!IS_ERR(neigh)) { | 672 | if (!IS_ERR(neigh)) { |
| 673 | sock_confirm_neigh(skb, neigh); | 673 | sock_confirm_neigh(skb, neigh); |
| 674 | ret = neigh_output(neigh, skb, false); | 674 | ret = neigh_output(neigh, skb, false); |
| 675 | rcu_read_unlock_bh(); | 675 | rcu_read_unlock(); |
| 676 | return ret; | 676 | return ret; |
| 677 | } | 677 | } |
| 678 | rcu_read_unlock_bh(); | 678 | rcu_read_unlock(); |
| 679 | 679 | ||
| 680 | IP6_INC_STATS(dev_net(dst->dev), | 680 | IP6_INC_STATS(dev_net(dst->dev), |
| 681 | ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); | 681 | ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); |
| @@ -889,7 +889,7 @@ static int vrf_finish_output(struct net *net, struct sock *sk, struct sk_buff *s · 207 unmodified lines | |||
| 889 | } | 889 | } |
| 890 | } | 890 | } |
| 891 | 891 | ||
| 892 | rcu_read_lock_bh(); | 892 | rcu_read_lock(); |
| 893 | 893 | ||
| 894 | neigh = ip_neigh_for_gw(rt, skb, &is_v6gw); | 894 | neigh = ip_neigh_for_gw(rt, skb, &is_v6gw); |
| 895 | if (!IS_ERR(neigh)) { | 895 | if (!IS_ERR(neigh)) { |
| @@ -898,11 +898,11 @@ static int vrf_finish_output(struct net *net, struct sock *sk, struct sk_buff *s · 2 unmodified lines | |||
| 898 | sock_confirm_neigh(skb, neigh); | 898 | sock_confirm_neigh(skb, neigh); |
| 899 | /* if crossing protocols, can not use the cached header */ | 899 | /* if crossing protocols, can not use the cached header */ |
| 900 | ret = neigh_output(neigh, skb, is_v6gw); | 900 | ret = neigh_output(neigh, skb, is_v6gw); |
| 901 | rcu_read_unlock_bh(); | 901 | rcu_read_unlock(); |
| 902 | return ret; | 902 | return ret; |
| 903 | } | 903 | } |
| 904 | 904 | ||
| 905 | rcu_read_unlock_bh(); | 905 | rcu_read_unlock(); |
| 906 | vrf_tx_error(skb->dev, skb); | 906 | vrf_tx_error(skb->dev, skb); |
| 907 | return -EINVAL; | 907 | return -EINVAL; |
| 908 | } | 908 | } |
| @@ -513,7 +513,7 @@ static inline void fastopen_queue_tune(struct sock *sk, int backlog) · 512 unmodified lines | |||
| 513 | struct request_sock_queue *queue = &inet_csk(sk)->icsk_accept_queue; | 513 | struct request_sock_queue *queue = &inet_csk(sk)->icsk_accept_queue; |
| 514 | int somaxconn = READ_ONCE(sock_net(sk)->core.sysctl_somaxconn); | 514 | int somaxconn = READ_ONCE(sock_net(sk)->core.sysctl_somaxconn); |
| 515 | 515 | ||
| 516 | queue->fastopenq.max_qlen = min_t(unsigned int, backlog, somaxconn); | 516 | WRITE_ONCE(queue->fastopenq.max_qlen, min_t(unsigned int, backlog, somaxconn)); |
| 517 | } | 517 | } |
| 518 | 518 | ||
| 519 | static inline void tcp_move_syn(struct tcp_sock *tp, | 519 | static inline void tcp_move_syn(struct tcp_sock *tp, |
| @@ -593,9 +593,7 @@ struct hci_dev { · 592 unmodified lines | |||
| 593 | const char *fw_info; | 593 | const char *fw_info; |
| 594 | struct dentry *debugfs; | 594 | struct dentry *debugfs; |
| 595 | 595 | ||
| 596 | #ifdef CONFIG_DEV_COREDUMP | ||
| 597 | struct hci_devcoredump dump; | 596 | struct hci_devcoredump dump; |
| 598 | #endif | ||
| 599 | 597 | ||
| 600 | struct device dev; | 598 | struct device dev; |
| 601 | 599 | ||
| @@ -822,6 +820,7 @@ struct hci_conn_params { · 220 unmodified lines | |||
| 822 | 820 | ||
| 823 | struct hci_conn *conn; | 821 | struct hci_conn *conn; |
| 824 | bool explicit_connect; | 822 | bool explicit_connect; |
| 823 | /* Accessed without hdev->lock: */ | ||
| 825 | hci_conn_flags_t flags; | 824 | hci_conn_flags_t flags; |
| 826 | u8 privacy_mode; | 825 | u8 privacy_mode; |
| 827 | }; | 826 | }; |
| @@ -1573,7 +1572,11 @@ struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev, · 745 unmodified lines | |||
| 1573 | bdaddr_t *addr, u8 addr_type); | 1572 | bdaddr_t *addr, u8 addr_type); |
| 1574 | void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type); | 1573 | void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type); |
| 1575 | void hci_conn_params_clear_disabled(struct hci_dev *hdev); | 1574 | void hci_conn_params_clear_disabled(struct hci_dev *hdev); |
| 1575 | void hci_conn_params_free(struct hci_conn_params *param); | ||
| 1576 | 1576 | ||
| 1577 | void hci_pend_le_list_del_init(struct hci_conn_params *param); | ||
| 1578 | void hci_pend_le_list_add(struct hci_conn_params *param, | ||
| 1579 | struct list_head *list); | ||
| 1577 | struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list, | 1580 | struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list, |
| 1578 | bdaddr_t *addr, | 1581 | bdaddr_t *addr, |
| 1579 | u8 addr_type); | 1582 | u8 addr_type); |
| @@ -277,7 +277,7 @@ struct bond_vlan_tag { · 276 unmodified lines | |||
| 277 | unsigned short vlan_id; | 277 | unsigned short vlan_id; |
| 278 | }; | 278 | }; |
| 279 | 279 | ||
| 280 | /** | 280 | /* |
| 281 | * Returns NULL if the net_device does not belong to any of the bond's slaves | 281 | * Returns NULL if the net_device does not belong to any of the bond's slaves |
| 282 | * | 282 | * |
| 283 | * Caller must hold bond lock for read | 283 | * Caller must hold bond lock for read |
| @@ -170,7 +170,8 @@ wpan_phy_cca_cmp(const struct wpan_phy_cca *a, const struct wpan_phy_cca *b) · 169 unmodified lines | |||
| 170 | } | 170 | } |
| 171 | 171 | ||
| 172 | /** | 172 | /** |
| 173 | * @WPAN_PHY_FLAG_TRANSMIT_POWER: Indicates that transceiver will support | 173 | * enum wpan_phy_flags - WPAN PHY state flags |
| 174 | * @WPAN_PHY_FLAG_TXPOWER: Indicates that transceiver will support | ||
| 174 | * transmit power setting. | 175 | * transmit power setting. |
| 175 | * @WPAN_PHY_FLAG_CCA_ED_LEVEL: Indicates that transceiver will support cca ed | 176 | * @WPAN_PHY_FLAG_CCA_ED_LEVEL: Indicates that transceiver will support cca ed |
| 176 | * level setting. | 177 | * level setting. |
| @@ -145,8 +145,8 @@ struct codel_vars { · 144 unmodified lines | |||
| 145 | * @maxpacket: largest packet we've seen so far | 145 | * @maxpacket: largest packet we've seen so far |
| 146 | * @drop_count: temp count of dropped packets in dequeue() | 146 | * @drop_count: temp count of dropped packets in dequeue() |
| 147 | * @drop_len: bytes of dropped packets in dequeue() | 147 | * @drop_len: bytes of dropped packets in dequeue() |
| 148 | * ecn_mark: number of packets we ECN marked instead of dropping | 148 | * @ecn_mark: number of packets we ECN marked instead of dropping |
| 149 | * ce_mark: number of packets CE marked because sojourn time was above ce_threshold | 149 | * @ce_mark: number of packets CE marked because sojourn time was above ce_threshold |
| 150 | */ | 150 | */ |
| 151 | struct codel_stats { | 151 | struct codel_stats { |
| 152 | u32 maxpacket; | 152 | u32 maxpacket; |
| @@ -221,7 +221,7 @@ struct devlink_dpipe_field { · 220 unmodified lines | |||
| 221 | /** | 221 | /** |
| 222 | * struct devlink_dpipe_header - dpipe header object | 222 | * struct devlink_dpipe_header - dpipe header object |
| 223 | * @name: header name | 223 | * @name: header name |
| 224 | * @id: index, global/local detrmined by global bit | 224 | * @id: index, global/local determined by global bit |
| 225 | * @fields: fields | 225 | * @fields: fields |
| 226 | * @fields_count: number of fields | 226 | * @fields_count: number of fields |
| 227 | * @global: indicates if header is shared like most protocol header | 227 | * @global: indicates if header is shared like most protocol header |
| @@ -241,7 +241,7 @@ struct devlink_dpipe_header { · 13 unmodified lines | |||
| 241 | * @header_index: header index (packets can have several headers of same | 241 | * @header_index: header index (packets can have several headers of same |
| 242 | * type like in case of tunnels) | 242 | * type like in case of tunnels) |
| 243 | * @header: header | 243 | * @header: header |
| 244 | * @fieled_id: field index | 244 | * @field_id: field index |
| 245 | */ | 245 | */ |
| 246 | struct devlink_dpipe_match { | 246 | struct devlink_dpipe_match { |
| 247 | enum devlink_dpipe_match_type type; | 247 | enum devlink_dpipe_match_type type; |
| @@ -256,7 +256,7 @@ struct devlink_dpipe_match { · 8 unmodified lines | |||
| 256 | * @header_index: header index (packets can have several headers of same | 256 | * @header_index: header index (packets can have several headers of same |
| 257 | * type like in case of tunnels) | 257 | * type like in case of tunnels) |
| 258 | * @header: header | 258 | * @header: header |
| 259 | * @fieled_id: field index | 259 | * @field_id: field index |
| 260 | */ | 260 | */ |
| 261 | struct devlink_dpipe_action { | 261 | struct devlink_dpipe_action { |
| 262 | enum devlink_dpipe_action_type type; | 262 | enum devlink_dpipe_action_type type; |
| @@ -292,7 +292,7 @@ struct devlink_dpipe_value { · 29 unmodified lines | |||
| 292 | * struct devlink_dpipe_entry - table entry object | 292 | * struct devlink_dpipe_entry - table entry object |
| 293 | * @index: index of the entry in the table | 293 | * @index: index of the entry in the table |
| 294 | * @match_values: match values | 294 | * @match_values: match values |
| 295 | * @matche_values_count: count of matches tuples | 295 | * @match_values_count: count of matches tuples |
| 296 | * @action_values: actions values | 296 | * @action_values: actions values |
| 297 | * @action_values_count: count of actions values | 297 | * @action_values_count: count of actions values |
| 298 | * @counter: value of counter | 298 | * @counter: value of counter |
| @@ -342,7 +342,9 @@ struct devlink_dpipe_table_ops; · 43 unmodified lines | |||
| 342 | */ | 342 | */ |
| 343 | struct devlink_dpipe_table { | 343 | struct devlink_dpipe_table { |
| 344 | void *priv; | 344 | void *priv; |
| 345 | /* private: */ | ||
| 345 | struct list_head list; | 346 | struct list_head list; |
| 347 | /* public: */ | ||
| 346 | const char *name; | 348 | const char *name; |
| 347 | bool counters_enabled; | 349 | bool counters_enabled; |
| 348 | bool counter_control_extern; | 350 | bool counter_control_extern; |
| @@ -355,13 +357,13 @@ struct devlink_dpipe_table { · 6 unmodified lines | |||
| 355 | 357 | ||
| 356 | /** | 358 | /** |
| 357 | * struct devlink_dpipe_table_ops - dpipe_table ops | 359 | * struct devlink_dpipe_table_ops - dpipe_table ops |
| 358 | * @actions_dump - dumps all tables actions | 360 | * @actions_dump: dumps all tables actions |
| 359 | * @matches_dump - dumps all tables matches | 361 | * @matches_dump: dumps all tables matches |
| 360 | * @entries_dump - dumps all active entries in the table | 362 | * @entries_dump: dumps all active entries in the table |
| 361 | * @counters_set_update - when changing the counter status hardware sync | 363 | * @counters_set_update: when changing the counter status hardware sync |
| 362 | * maybe needed to allocate/free counter related | 364 | * maybe needed to allocate/free counter related |
| 363 | * resources | 365 | * resources |
| 364 | * @size_get - get size | 366 | * @size_get: get size |
| 365 | */ | 367 | */ |
| 366 | struct devlink_dpipe_table_ops { | 368 | struct devlink_dpipe_table_ops { |
| 367 | int (*actions_dump)(void *priv, struct sk_buff *skb); | 369 | int (*actions_dump)(void *priv, struct sk_buff *skb); |
| @@ -374,8 +376,8 @@ struct devlink_dpipe_table_ops { · 6 unmodified lines | |||
| 374 | 376 | ||
| 375 | /** | 377 | /** |
| 376 | * struct devlink_dpipe_headers - dpipe headers | 378 | * struct devlink_dpipe_headers - dpipe headers |
| 377 | * @headers - header array can be shared (global bit) or driver specific | 379 | * @headers: header array can be shared (global bit) or driver specific |
| 378 | * @headers_count - count of headers | 380 | * @headers_count: count of headers |
| 379 | */ | 381 | */ |
| 380 | struct devlink_dpipe_headers { | 382 | struct devlink_dpipe_headers { |
| 381 | struct devlink_dpipe_header **headers; | 383 | struct devlink_dpipe_header **headers; |
| @@ -387,7 +389,7 @@ struct devlink_dpipe_headers { · 5 unmodified lines | |||
| 387 | * @size_min: minimum size which can be set | 389 | * @size_min: minimum size which can be set |
| 388 | * @size_max: maximum size which can be set | 390 | * @size_max: maximum size which can be set |
| 389 | * @size_granularity: size granularity | 391 | * @size_granularity: size granularity |
| 390 | * @size_unit: resource's basic unit | 392 | * @unit: resource's basic unit |
| 391 | */ | 393 | */ |
| 392 | struct devlink_resource_size_params { | 394 | struct devlink_resource_size_params { |
| 393 | u64 size_min; | 395 | u64 size_min; |
| @@ -457,6 +459,7 @@ struct devlink_flash_notify { · 63 unmodified lines | |||
| 457 | 459 | ||
| 458 | /** | 460 | /** |
| 459 | * struct devlink_param - devlink configuration parameter data | 461 | * struct devlink_param - devlink configuration parameter data |
| 462 | * @id: devlink parameter id number | ||
| 460 | * @name: name of the parameter | 463 | * @name: name of the parameter |
| 461 | * @generic: indicates if the parameter is generic or driver specific | 464 | * @generic: indicates if the parameter is generic or driver specific |
| 462 | * @type: parameter type | 465 | * @type: parameter type |
| @@ -632,6 +635,7 @@ enum devlink_param_generic_id { · 169 unmodified lines | |||
| 632 | * struct devlink_flash_update_params - Flash Update parameters | 635 | * struct devlink_flash_update_params - Flash Update parameters |
| 633 | * @fw: pointer to the firmware data to update from | 636 | * @fw: pointer to the firmware data to update from |
| 634 | * @component: the flash component to update | 637 | * @component: the flash component to update |
| 638 | * @overwrite_mask: which types of flash update are supported (may be %0) | ||
| 635 | * | 639 | * |
| 636 | * With the exception of fw, drivers must opt-in to parameters by | 640 | * With the exception of fw, drivers must opt-in to parameters by |
| 637 | * setting the appropriate bit in the supported_flash_update_params field in | 641 | * setting the appropriate bit in the supported_flash_update_params field in |
| @@ -29,7 +29,7 @@ struct fqdir { · 28 unmodified lines | |||
| 29 | }; | 29 | }; |
| 30 | 30 | ||
| 31 | /** | 31 | /** |
| 32 | * fragment queue flags | 32 | * enum: fragment queue flags |
| 33 | * | 33 | * |
| 34 | * @INET_FRAG_FIRST_IN: first fragment has arrived | 34 | * @INET_FRAG_FIRST_IN: first fragment has arrived |
| 35 | * @INET_FRAG_LAST_IN: final fragment has arrived | 35 | * @INET_FRAG_LAST_IN: final fragment has arrived |
| @@ -111,7 +111,7 @@ void llc_conn_resend_i_pdu_as_cmd(struct sock *sk, u8 nr, u8 first_p_bit); · 110 unmodified lines | |||
| 111 | void llc_conn_resend_i_pdu_as_rsp(struct sock *sk, u8 nr, u8 first_f_bit); | 111 | void llc_conn_resend_i_pdu_as_rsp(struct sock *sk, u8 nr, u8 first_f_bit); |
| 112 | int llc_conn_remove_acked_pdus(struct sock *conn, u8 nr, u16 *how_many_unacked); | 112 | int llc_conn_remove_acked_pdus(struct sock *conn, u8 nr, u16 *how_many_unacked); |
| 113 | struct sock *llc_lookup_established(struct llc_sap *sap, struct llc_addr *daddr, | 113 | struct sock *llc_lookup_established(struct llc_sap *sap, struct llc_addr *daddr, |
| 114 | struct llc_addr *laddr); | 114 | struct llc_addr *laddr, const struct net *net); |
| 115 | void llc_sap_add_socket(struct llc_sap *sap, struct sock *sk); | 115 | void llc_sap_add_socket(struct llc_sap *sap, struct sock *sk); |
| 116 | void llc_sap_remove_socket(struct llc_sap *sap, struct sock *sk); | 116 | void llc_sap_remove_socket(struct llc_sap *sap, struct sock *sk); |
| 117 | 117 | ||
| @@ -269,7 +269,7 @@ static inline void llc_pdu_decode_sa(struct sk_buff *skb, u8 *sa) · 268 unmodified lines | |||
| 269 | /** | 269 | /** |
| 270 | * llc_pdu_decode_da - extracts dest address of input frame | 270 | * llc_pdu_decode_da - extracts dest address of input frame |
| 271 | * @skb: input skb that destination address must be extracted from it | 271 | * @skb: input skb that destination address must be extracted from it |
| 272 | * @sa: pointer to destination address (6 byte array). | 272 | * @da: pointer to destination address (6 byte array). |
| 273 | * | 273 | * |
| 274 | * This function extracts destination address(MAC) of input frame. | 274 | * This function extracts destination address(MAC) of input frame. |
| 275 | */ | 275 | */ |
| @@ -321,7 +321,7 @@ static inline void llc_pdu_init_as_ui_cmd(struct sk_buff *skb) · 45 unmodified lines | |||
| 321 | 321 | ||
| 322 | /** | 322 | /** |
| 323 | * llc_pdu_init_as_test_cmd - sets PDU as TEST | 323 | * llc_pdu_init_as_test_cmd - sets PDU as TEST |
| 324 | * @skb - Address of the skb to build | 324 | * @skb: Address of the skb to build |
| 325 | * | 325 | * |
| 326 | * Sets a PDU as TEST | 326 | * Sets a PDU as TEST |
| 327 | */ | 327 | */ |
| @@ -369,6 +369,8 @@ struct llc_xid_info { · 41 unmodified lines | |||
| 369 | /** | 369 | /** |
| 370 | * llc_pdu_init_as_xid_cmd - sets bytes 3, 4 & 5 of LLC header as XID | 370 | * llc_pdu_init_as_xid_cmd - sets bytes 3, 4 & 5 of LLC header as XID |
| 371 | * @skb: input skb that header must be set into it. | 371 | * @skb: input skb that header must be set into it. |
| 372 | * @svcs_supported: The class of the LLC (I or II) | ||
| 373 | * @rx_window: The size of the receive window of the LLC | ||
| 372 | * | 374 | * |
| 373 | * This function sets third,fourth,fifth and sixth bytes of LLC header as | 375 | * This function sets third,fourth,fifth and sixth bytes of LLC header as |
| 374 | * a XID PDU. | 376 | * a XID PDU. |
| @@ -192,7 +192,7 @@ · 191 unmodified lines | |||
| 192 | 192 | ||
| 193 | /** | 193 | /** |
| 194 | * struct nsh_md1_ctx - Keeps track of NSH context data | 194 | * struct nsh_md1_ctx - Keeps track of NSH context data |
| 195 | * @nshc<1-4>: NSH Contexts. | 195 | * @context: NSH Contexts. |
| 196 | */ | 196 | */ |
| 197 | struct nsh_md1_ctx { | 197 | struct nsh_md1_ctx { |
| 198 | __be32 context[4]; | 198 | __be32 context[4]; |
| @@ -17,7 +17,7 @@ · 16 unmodified lines | |||
| 17 | /** | 17 | /** |
| 18 | * struct pie_params - contains pie parameters | 18 | * struct pie_params - contains pie parameters |
| 19 | * @target: target delay in pschedtime | 19 | * @target: target delay in pschedtime |
| 20 | * @tudpate: interval at which drop probability is calculated | 20 | * @tupdate: interval at which drop probability is calculated |
| 21 | * @limit: total number of packets that can be in the queue | 21 | * @limit: total number of packets that can be in the queue |
| 22 | * @alpha: parameter to control drop probability | 22 | * @alpha: parameter to control drop probability |
| 23 | * @beta: parameter to control drop probability | 23 | * @beta: parameter to control drop probability |
| @@ -1,4 +1,4 @@ | |||
| 1 | /** | 1 | /* |
| 2 | * Copyright (c) 2017 Redpine Signals Inc. | 2 | * Copyright (c) 2017 Redpine Signals Inc. |
| 3 | * | 3 | * |
| 4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
| @@ -1509,25 +1509,38 @@ void tcp_leave_memory_pressure(struct sock *sk); · 1508 unmodified lines | |||
| 1509 | static inline int keepalive_intvl_when(const struct tcp_sock *tp) | 1509 | static inline int keepalive_intvl_when(const struct tcp_sock *tp) |
| 1510 | { | 1510 | { |
| 1511 | struct net *net = sock_net((struct sock *)tp); | 1511 | struct net *net = sock_net((struct sock *)tp); |
| 1512 | int val; | ||
| 1512 | 1513 | ||
| 1513 | return tp->keepalive_intvl ? : | 1514 | /* Paired with WRITE_ONCE() in tcp_sock_set_keepintvl() |
| 1514 | READ_ONCE(net->ipv4.sysctl_tcp_keepalive_intvl); | 1515 | * and do_tcp_setsockopt(). |
| 1516 | */ | ||
| 1517 | val = READ_ONCE(tp->keepalive_intvl); | ||
| 1518 | |||
| 1519 | return val ? : READ_ONCE(net->ipv4.sysctl_tcp_keepalive_intvl); | ||
| 1515 | } | 1520 | } |
| 1516 | 1521 | ||
| 1517 | static inline int keepalive_time_when(const struct tcp_sock *tp) | 1522 | static inline int keepalive_time_when(const struct tcp_sock *tp) |
| 1518 | { | 1523 | { |
| 1519 | struct net *net = sock_net((struct sock *)tp); | 1524 | struct net *net = sock_net((struct sock *)tp); |
| 1525 | int val; | ||
| 1520 | 1526 | ||
| 1521 | return tp->keepalive_time ? : | 1527 | /* Paired with WRITE_ONCE() in tcp_sock_set_keepidle_locked() */ |
| 1522 | READ_ONCE(net->ipv4.sysctl_tcp_keepalive_time); | 1528 | val = READ_ONCE(tp->keepalive_time); |
| 1529 | |||
| 1530 | return val ? : READ_ONCE(net->ipv4.sysctl_tcp_keepalive_time); | ||
| 1523 | } | 1531 | } |
| 1524 | 1532 | ||
| 1525 | static inline int keepalive_probes(const struct tcp_sock *tp) | 1533 | static inline int keepalive_probes(const struct tcp_sock *tp) |
| 1526 | { | 1534 | { |
| 1527 | struct net *net = sock_net((struct sock *)tp); | 1535 | struct net *net = sock_net((struct sock *)tp); |
| 1536 | int val; | ||
| 1528 | 1537 | ||
| 1529 | return tp->keepalive_probes ? : | 1538 | /* Paired with WRITE_ONCE() in tcp_sock_set_keepcnt() |
| 1530 | READ_ONCE(net->ipv4.sysctl_tcp_keepalive_probes); | 1539 | * and do_tcp_setsockopt(). |
| 1540 | */ | ||
| 1541 | val = READ_ONCE(tp->keepalive_probes); | ||
| 1542 | |||
| 1543 | return val ? : READ_ONCE(net->ipv4.sysctl_tcp_keepalive_probes); | ||
| 1531 | } | 1544 | } |
| 1532 | 1545 | ||
| 1533 | static inline u32 keepalive_time_elapsed(const struct tcp_sock *tp) | 1546 | static inline u32 keepalive_time_elapsed(const struct tcp_sock *tp) |
| @@ -2048,7 +2061,11 @@ void __tcp_v4_send_check(struct sk_buff *skb, __be32 saddr, __be32 daddr); · 514 unmodified lines | |||
| 2048 | static inline u32 tcp_notsent_lowat(const struct tcp_sock *tp) | 2061 | static inline u32 tcp_notsent_lowat(const struct tcp_sock *tp) |
| 2049 | { | 2062 | { |
| 2050 | struct net *net = sock_net((struct sock *)tp); | 2063 | struct net *net = sock_net((struct sock *)tp); |
| 2051 | return tp->notsent_lowat ?: READ_ONCE(net->ipv4.sysctl_tcp_notsent_lowat); | 2064 | u32 val; |
| 2065 | |||
| 2066 | val = READ_ONCE(tp->notsent_lowat); | ||
| 2067 | |||
| 2068 | return val ?: READ_ONCE(net->ipv4.sysctl_tcp_notsent_lowat); | ||
| 2052 | } | 2069 | } |
| 2053 | 2070 | ||
| 2054 | bool tcp_stream_memory_free(const struct sock *sk, int wake); | 2071 | bool tcp_stream_memory_free(const struct sock *sk, int wake); |
| @@ -5573,16 +5573,17 @@ static int update_stack_depth(struct bpf_verifier_env *env, · 5572 unmodified lines | |||
| 5573 | * Since recursion is prevented by check_cfg() this algorithm | 5573 | * Since recursion is prevented by check_cfg() this algorithm |
| 5574 | * only needs a local stack of MAX_CALL_FRAMES to remember callsites | 5574 | * only needs a local stack of MAX_CALL_FRAMES to remember callsites |
| 5575 | */ | 5575 | */ |
| 5576 | static int check_max_stack_depth(struct bpf_verifier_env *env) | 5576 | static int check_max_stack_depth_subprog(struct bpf_verifier_env *env, int idx) |
| 5577 | { | 5577 | { |
| 5578 | int depth = 0, frame = 0, idx = 0, i = 0, subprog_end; | ||
| 5579 | struct bpf_subprog_info *subprog = env->subprog_info; | 5578 | struct bpf_subprog_info *subprog = env->subprog_info; |
| 5580 | struct bpf_insn *insn = env->prog->insnsi; | 5579 | struct bpf_insn *insn = env->prog->insnsi; |
| 5580 | int depth = 0, frame = 0, i, subprog_end; | ||
| 5581 | bool tail_call_reachable = false; | 5581 | bool tail_call_reachable = false; |
| 5582 | int ret_insn[MAX_CALL_FRAMES]; | 5582 | int ret_insn[MAX_CALL_FRAMES]; |
| 5583 | int ret_prog[MAX_CALL_FRAMES]; | 5583 | int ret_prog[MAX_CALL_FRAMES]; |
| 5584 | int j; | 5584 | int j; |
| 5585 | 5585 | ||
| 5586 | i = subprog[idx].start; | ||
| 5586 | process_func: | 5587 | process_func: |
| 5587 | /* protect against potential stack overflow that might happen when | 5588 | /* protect against potential stack overflow that might happen when |
| 5588 | * bpf2bpf calls get combined with tailcalls. Limit the caller's stack | 5589 | * bpf2bpf calls get combined with tailcalls. Limit the caller's stack |
| @@ -5621,7 +5622,7 @@ process_func: · 32 unmodified lines | |||
| 5621 | continue_func: | 5622 | continue_func: |
| 5622 | subprog_end = subprog[idx + 1].start; | 5623 | subprog_end = subprog[idx + 1].start; |
| 5623 | for (; i < subprog_end; i++) { | 5624 | for (; i < subprog_end; i++) { |
| 5624 | int next_insn; | 5625 | int next_insn, sidx; |
| 5625 | 5626 | ||
| 5626 | if (!bpf_pseudo_call(insn + i) && !bpf_pseudo_func(insn + i)) | 5627 | if (!bpf_pseudo_call(insn + i) && !bpf_pseudo_func(insn + i)) |
| 5627 | continue; | 5628 | continue; |
| @@ -5631,14 +5632,14 @@ continue_func: · 3 unmodified lines | |||
| 5631 | 5632 | ||
| 5632 | /* find the callee */ | 5633 | /* find the callee */ |
| 5633 | next_insn = i + insn[i].imm + 1; | 5634 | next_insn = i + insn[i].imm + 1; |
| 5634 | idx = find_subprog(env, next_insn); | 5635 | sidx = find_subprog(env, next_insn); |
| 5635 | if (idx < 0) { | 5636 | if (sidx < 0) { |
| 5636 | WARN_ONCE(1, "verifier bug. No program starts at insn %d\n", | 5637 | WARN_ONCE(1, "verifier bug. No program starts at insn %d\n", |
| 5637 | next_insn); | 5638 | next_insn); |
| 5638 | return -EFAULT; | 5639 | return -EFAULT; |
| 5639 | } | 5640 | } |
| 5640 | if (subprog[idx].is_async_cb) { | 5641 | if (subprog[sidx].is_async_cb) { |
| 5641 | if (subprog[idx].has_tail_call) { | 5642 | if (subprog[sidx].has_tail_call) { |
| 5642 | verbose(env, "verifier bug. subprog has tail_call and async cb\n"); | 5643 | verbose(env, "verifier bug. subprog has tail_call and async cb\n"); |
| 5643 | return -EFAULT; | 5644 | return -EFAULT; |
| 5644 | } | 5645 | } |
| @@ -5647,6 +5648,7 @@ continue_func: · 2 unmodified lines | |||
| 5647 | continue; | 5648 | continue; |
| 5648 | } | 5649 | } |
| 5649 | i = next_insn; | 5650 | i = next_insn; |
| 5651 | idx = sidx; | ||
| 5650 | 5652 | ||
| 5651 | if (subprog[idx].has_tail_call) | 5653 | if (subprog[idx].has_tail_call) |
| 5652 | tail_call_reachable = true; | 5654 | tail_call_reachable = true; |
| @@ -5682,6 +5684,22 @@ continue_func: · 29 unmodified lines | |||
| 5682 | goto continue_func; | 5684 | goto continue_func; |
| 5683 | } | 5685 | } |
| 5684 | 5686 | ||
| 5687 | static int check_max_stack_depth(struct bpf_verifier_env *env) | ||
| 5688 | { | ||
| 5689 | struct bpf_subprog_info *si = env->subprog_info; | ||
| 5690 | int ret; | ||
| 5691 | |||
| 5692 | for (int i = 0; i < env->subprog_cnt; i++) { | ||
| 5693 | if (!i || si[i].is_async_cb) { | ||
| 5694 | ret = check_max_stack_depth_subprog(env, i); | ||
| 5695 | if (ret < 0) | ||
| 5696 | return ret; | ||
| 5697 | } | ||
| 5698 | continue; | ||
| 5699 | } | ||
| 5700 | return 0; | ||
| 5701 | } | ||
| 5702 | |||
| 5685 | #ifndef CONFIG_BPF_JIT_ALWAYS_ON | 5703 | #ifndef CONFIG_BPF_JIT_ALWAYS_ON |
| 5686 | static int get_callee_stack_depth(struct bpf_verifier_env *env, | 5704 | static int get_callee_stack_depth(struct bpf_verifier_env *env, |
| 5687 | const struct bpf_insn *insn, int idx) | 5705 | const struct bpf_insn *insn, int idx) |
| @@ -118,7 +118,7 @@ static void hci_connect_le_scan_cleanup(struct hci_conn *conn, u8 status) · 117 unmodified lines | |||
| 118 | */ | 118 | */ |
| 119 | params->explicit_connect = false; | 119 | params->explicit_connect = false; |
| 120 | 120 | ||
| 121 | list_del_init(¶ms->action); | 121 | hci_pend_le_list_del_init(params); |
| 122 | 122 | ||
| 123 | switch (params->auto_connect) { | 123 | switch (params->auto_connect) { |
| 124 | case HCI_AUTO_CONN_EXPLICIT: | 124 | case HCI_AUTO_CONN_EXPLICIT: |
| @@ -127,10 +127,10 @@ static void hci_connect_le_scan_cleanup(struct hci_conn *conn, u8 status) · 2 unmodified lines | |||
| 127 | return; | 127 | return; |
| 128 | case HCI_AUTO_CONN_DIRECT: | 128 | case HCI_AUTO_CONN_DIRECT: |
| 129 | case HCI_AUTO_CONN_ALWAYS: | 129 | case HCI_AUTO_CONN_ALWAYS: |
| 130 | list_add(¶ms->action, &hdev->pend_le_conns); | 130 | hci_pend_le_list_add(params, &hdev->pend_le_conns); |
| 131 | break; | 131 | break; |
| 132 | case HCI_AUTO_CONN_REPORT: | 132 | case HCI_AUTO_CONN_REPORT: |
| 133 | list_add(¶ms->action, &hdev->pend_le_reports); | 133 | hci_pend_le_list_add(params, &hdev->pend_le_reports); |
| 134 | break; | 134 | break; |
| 135 | default: | 135 | default: |
| 136 | break; | 136 | break; |
| @@ -1426,8 +1426,8 @@ static int hci_explicit_conn_params_set(struct hci_dev *hdev, · 1289 unmodified lines | |||
| 1426 | if (params->auto_connect == HCI_AUTO_CONN_DISABLED || | 1426 | if (params->auto_connect == HCI_AUTO_CONN_DISABLED || |
| 1427 | params->auto_connect == HCI_AUTO_CONN_REPORT || | 1427 | params->auto_connect == HCI_AUTO_CONN_REPORT || |
| 1428 | params->auto_connect == HCI_AUTO_CONN_EXPLICIT) { | 1428 | params->auto_connect == HCI_AUTO_CONN_EXPLICIT) { |
| 1429 | list_del_init(¶ms->action); | 1429 | hci_pend_le_list_del_init(params); |
| 1430 | list_add(¶ms->action, &hdev->pend_le_conns); | 1430 | hci_pend_le_list_add(params, &hdev->pend_le_conns); |
| 1431 | } | 1431 | } |
| 1432 | 1432 | ||
| 1433 | params->explicit_connect = true; | 1433 | params->explicit_connect = true; |
| @@ -1684,7 +1684,7 @@ struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst, · 250 unmodified lines | |||
| 1684 | if (!link) { | 1684 | if (!link) { |
| 1685 | hci_conn_drop(acl); | 1685 | hci_conn_drop(acl); |
| 1686 | hci_conn_drop(sco); | 1686 | hci_conn_drop(sco); |
| 1687 | return NULL; | 1687 | return ERR_PTR(-ENOLINK); |
| 1688 | } | 1688 | } |
| 1689 | 1689 | ||
| 1690 | sco->setting = setting; | 1690 | sco->setting = setting; |
| @@ -2254,7 +2254,7 @@ struct hci_conn *hci_connect_cis(struct hci_dev *hdev, bdaddr_t *dst, · 563 unmodified lines | |||
| 2254 | if (!link) { | 2254 | if (!link) { |
| 2255 | hci_conn_drop(le); | 2255 | hci_conn_drop(le); |
| 2256 | hci_conn_drop(cis); | 2256 | hci_conn_drop(cis); |
| 2257 | return NULL; | 2257 | return ERR_PTR(-ENOLINK); |
| 2258 | } | 2258 | } |
| 2259 | 2259 | ||
| 2260 | /* If LE is already connected and CIS handle is already set proceed to | 2260 | /* If LE is already connected and CIS handle is already set proceed to |
| @@ -1972,6 +1972,7 @@ static int hci_remove_adv_monitor(struct hci_dev *hdev, · 1971 unmodified lines | |||
| 1972 | struct adv_monitor *monitor) | 1972 | struct adv_monitor *monitor) |
| 1973 | { | 1973 | { |
| 1974 | int status = 0; | 1974 | int status = 0; |
| 1975 | int handle; | ||
| 1975 | 1976 | ||
| 1976 | switch (hci_get_adv_monitor_offload_ext(hdev)) { | 1977 | switch (hci_get_adv_monitor_offload_ext(hdev)) { |
| 1977 | case HCI_ADV_MONITOR_EXT_NONE: /* also goes here when powered off */ | 1978 | case HCI_ADV_MONITOR_EXT_NONE: /* also goes here when powered off */ |
| @@ -1980,9 +1981,10 @@ static int hci_remove_adv_monitor(struct hci_dev *hdev, · 2 unmodified lines | |||
| 1980 | goto free_monitor; | 1981 | goto free_monitor; |
| 1981 | 1982 | ||
| 1982 | case HCI_ADV_MONITOR_EXT_MSFT: | 1983 | case HCI_ADV_MONITOR_EXT_MSFT: |
| 1984 | handle = monitor->handle; | ||
| 1983 | status = msft_remove_monitor(hdev, monitor); | 1985 | status = msft_remove_monitor(hdev, monitor); |
| 1984 | bt_dev_dbg(hdev, "%s remove monitor %d msft status %d", | 1986 | bt_dev_dbg(hdev, "%s remove monitor %d msft status %d", |
| 1985 | hdev->name, monitor->handle, status); | 1987 | hdev->name, handle, status); |
| 1986 | break; | 1988 | break; |
| 1987 | } | 1989 | } |
| 1988 | 1990 | ||
| @@ -2249,21 +2251,45 @@ struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev, · 260 unmodified lines | |||
| 2249 | return NULL; | 2251 | return NULL; |
| 2250 | } | 2252 | } |
| 2251 | 2253 | ||
| 2252 | /* This function requires the caller holds hdev->lock */ | 2254 | /* This function requires the caller holds hdev->lock or rcu_read_lock */ |
| 2253 | struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list, | 2255 | struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list, |
| 2254 | bdaddr_t *addr, u8 addr_type) | 2256 | bdaddr_t *addr, u8 addr_type) |
| 2255 | { | 2257 | { |
| 2256 | struct hci_conn_params *param; | 2258 | struct hci_conn_params *param; |
| 2257 | 2259 | ||
| 2258 | list_for_each_entry(param, list, action) { | 2260 | rcu_read_lock(); |
| 2261 | |||
| 2262 | list_for_each_entry_rcu(param, list, action) { | ||
| 2259 | if (bacmp(¶m->addr, addr) == 0 && | 2263 | if (bacmp(¶m->addr, addr) == 0 && |
| 2260 | param->addr_type == addr_type) | 2264 | param->addr_type == addr_type) { |
| 2265 | rcu_read_unlock(); | ||
| 2261 | return param; | 2266 | return param; |
| 2267 | } | ||
| 2262 | } | 2268 | } |
| 2263 | 2269 | ||
| 2270 | rcu_read_unlock(); | ||
| 2271 | |||
| 2264 | return NULL; | 2272 | return NULL; |
| 2265 | } | 2273 | } |
| 2266 | 2274 | ||
| 2275 | /* This function requires the caller holds hdev->lock */ | ||
| 2276 | void hci_pend_le_list_del_init(struct hci_conn_params *param) | ||
| 2277 | { | ||
| 2278 | if (list_empty(¶m->action)) | ||
| 2279 | return; | ||
| 2280 | |||
| 2281 | list_del_rcu(¶m->action); | ||
| 2282 | synchronize_rcu(); | ||
| 2283 | INIT_LIST_HEAD(¶m->action); | ||
| 2284 | } | ||
| 2285 | |||
| 2286 | /* This function requires the caller holds hdev->lock */ | ||
| 2287 | void hci_pend_le_list_add(struct hci_conn_params *param, | ||
| 2288 | struct list_head *list) | ||
| 2289 | { | ||
| 2290 | list_add_rcu(¶m->action, list); | ||
| 2291 | } | ||
| 2292 | |||
| 2267 | /* This function requires the caller holds hdev->lock */ | 2293 | /* This function requires the caller holds hdev->lock */ |
| 2268 | struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev, | 2294 | struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev, |
| 2269 | bdaddr_t *addr, u8 addr_type) | 2295 | bdaddr_t *addr, u8 addr_type) |
| @@ -2297,14 +2323,15 @@ struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev, · 27 unmodified lines | |||
| 2297 | return params; | 2323 | return params; |
| 2298 | } | 2324 | } |
| 2299 | 2325 | ||
| 2300 | static void hci_conn_params_free(struct hci_conn_params *params) | 2326 | void hci_conn_params_free(struct hci_conn_params *params) |
| 2301 | { | 2327 | { |
| 2328 | hci_pend_le_list_del_init(params); | ||
| 2329 | |||
| 2302 | if (params->conn) { | 2330 | if (params->conn) { |
| 2303 | hci_conn_drop(params->conn); | 2331 | hci_conn_drop(params->conn); |
| 2304 | hci_conn_put(params->conn); | 2332 | hci_conn_put(params->conn); |
| 2305 | } | 2333 | } |
| 2306 | 2334 | ||
| 2307 | list_del(¶ms->action); | ||
| 2308 | list_del(¶ms->list); | 2335 | list_del(¶ms->list); |
| 2309 | kfree(params); | 2336 | kfree(params); |
| 2310 | } | 2337 | } |
| @@ -2342,8 +2369,7 @@ void hci_conn_params_clear_disabled(struct hci_dev *hdev) · 31 unmodified lines | |||
| 2342 | continue; | 2369 | continue; |
| 2343 | } | 2370 | } |
| 2344 | 2371 | ||
| 2345 | list_del(¶ms->list); | 2372 | hci_conn_params_free(params); |
| 2346 | kfree(params); | ||
| 2347 | } | 2373 | } |
| 2348 | 2374 | ||
| 2349 | BT_DBG("All LE disabled connection parameters were removed"); | 2375 | BT_DBG("All LE disabled connection parameters were removed"); |
| @@ -1564,7 +1564,7 @@ static u8 hci_cc_le_set_privacy_mode(struct hci_dev *hdev, void *data, · 1563 unmodified lines | |||
| 1564 | 1564 | ||
| 1565 | params = hci_conn_params_lookup(hdev, &cp->bdaddr, cp->bdaddr_type); | 1565 | params = hci_conn_params_lookup(hdev, &cp->bdaddr, cp->bdaddr_type); |
| 1566 | if (params) | 1566 | if (params) |
| 1567 | params->privacy_mode = cp->mode; | 1567 | WRITE_ONCE(params->privacy_mode, cp->mode); |
| 1568 | 1568 | ||
| 1569 | hci_dev_unlock(hdev); | 1569 | hci_dev_unlock(hdev); |
| 1570 | 1570 | ||
| @@ -2784,6 +2784,9 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 status) · 1213 unmodified lines | |||
| 2784 | hci_enable_advertising(hdev); | 2784 | hci_enable_advertising(hdev); |
| 2785 | } | 2785 | } |
| 2786 | 2786 | ||
| 2787 | /* Inform sockets conn is gone before we delete it */ | ||
| 2788 | hci_disconn_cfm(conn, HCI_ERROR_UNSPECIFIED); | ||
| 2789 | |||
| 2787 | goto done; | 2790 | goto done; |
| 2788 | } | 2791 | } |
| 2789 | 2792 | ||
| @@ -2804,8 +2807,8 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 status) · 14 unmodified lines | |||
| 2804 | 2807 | ||
| 2805 | case HCI_AUTO_CONN_DIRECT: | 2808 | case HCI_AUTO_CONN_DIRECT: |
| 2806 | case HCI_AUTO_CONN_ALWAYS: | 2809 | case HCI_AUTO_CONN_ALWAYS: |
| 2807 | list_del_init(¶ms->action); | 2810 | hci_pend_le_list_del_init(params); |
| 2808 | list_add(¶ms->action, &hdev->pend_le_conns); | 2811 | hci_pend_le_list_add(params, &hdev->pend_le_conns); |
| 2809 | break; | 2812 | break; |
| 2810 | 2813 | ||
| 2811 | default: | 2814 | default: |
| @@ -3423,8 +3426,8 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, void *data, · 611 unmodified lines | |||
| 3423 | 3426 | ||
| 3424 | case HCI_AUTO_CONN_DIRECT: | 3427 | case HCI_AUTO_CONN_DIRECT: |
| 3425 | case HCI_AUTO_CONN_ALWAYS: | 3428 | case HCI_AUTO_CONN_ALWAYS: |
| 3426 | list_del_init(¶ms->action); | 3429 | hci_pend_le_list_del_init(params); |
| 3427 | list_add(¶ms->action, &hdev->pend_le_conns); | 3430 | hci_pend_le_list_add(params, &hdev->pend_le_conns); |
| 3428 | hci_update_passive_scan(hdev); | 3431 | hci_update_passive_scan(hdev); |
| 3429 | break; | 3432 | break; |
| 3430 | 3433 | ||
| @@ -5962,7 +5965,7 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status, · 2531 unmodified lines | |||
| 5962 | params = hci_pend_le_action_lookup(&hdev->pend_le_conns, &conn->dst, | 5965 | params = hci_pend_le_action_lookup(&hdev->pend_le_conns, &conn->dst, |
| 5963 | conn->dst_type); | 5966 | conn->dst_type); |
| 5964 | if (params) { | 5967 | if (params) { |
| 5965 | list_del_init(¶ms->action); | 5968 | hci_pend_le_list_del_init(params); |
| 5966 | if (params->conn) { | 5969 | if (params->conn) { |
| 5967 | hci_conn_drop(params->conn); | 5970 | hci_conn_drop(params->conn); |
| 5968 | hci_conn_put(params->conn); | 5971 | hci_conn_put(params->conn); |
| @@ -2160,15 +2160,23 @@ static int hci_le_del_accept_list_sync(struct hci_dev *hdev, · 2159 unmodified lines | |||
| 2160 | return 0; | 2160 | return 0; |
| 2161 | } | 2161 | } |
| 2162 | 2162 | ||
| 2163 | struct conn_params { | ||
| 2164 | bdaddr_t addr; | ||
| 2165 | u8 addr_type; | ||
| 2166 | hci_conn_flags_t flags; | ||
| 2167 | u8 privacy_mode; | ||
| 2168 | }; | ||
| 2169 | |||
| 2163 | /* Adds connection to resolve list if needed. | 2170 | /* Adds connection to resolve list if needed. |
| 2164 | * Setting params to NULL programs local hdev->irk | 2171 | * Setting params to NULL programs local hdev->irk |
| 2165 | */ | 2172 | */ |
| 2166 | static int hci_le_add_resolve_list_sync(struct hci_dev *hdev, | 2173 | static int hci_le_add_resolve_list_sync(struct hci_dev *hdev, |
| 2167 | struct hci_conn_params *params) | 2174 | struct conn_params *params) |
| 2168 | { | 2175 | { |
| 2169 | struct hci_cp_le_add_to_resolv_list cp; | 2176 | struct hci_cp_le_add_to_resolv_list cp; |
| 2170 | struct smp_irk *irk; | 2177 | struct smp_irk *irk; |
| 2171 | struct bdaddr_list_with_irk *entry; | 2178 | struct bdaddr_list_with_irk *entry; |
| 2179 | struct hci_conn_params *p; | ||
| 2172 | 2180 | ||
| 2173 | if (!use_ll_privacy(hdev)) | 2181 | if (!use_ll_privacy(hdev)) |
| 2174 | return 0; | 2182 | return 0; |
| @@ -2203,6 +2211,16 @@ static int hci_le_add_resolve_list_sync(struct hci_dev *hdev, · 28 unmodified lines | |||
| 2203 | /* Default privacy mode is always Network */ | 2211 | /* Default privacy mode is always Network */ |
| 2204 | params->privacy_mode = HCI_NETWORK_PRIVACY; | 2212 | params->privacy_mode = HCI_NETWORK_PRIVACY; |
| 2205 | 2213 | ||
| 2214 | rcu_read_lock(); | ||
| 2215 | p = hci_pend_le_action_lookup(&hdev->pend_le_conns, | ||
| 2216 | ¶ms->addr, params->addr_type); | ||
| 2217 | if (!p) | ||
| 2218 | p = hci_pend_le_action_lookup(&hdev->pend_le_reports, | ||
| 2219 | ¶ms->addr, params->addr_type); | ||
| 2220 | if (p) | ||
| 2221 | WRITE_ONCE(p->privacy_mode, HCI_NETWORK_PRIVACY); | ||
| 2222 | rcu_read_unlock(); | ||
| 2223 | |||
| 2206 | done: | 2224 | done: |
| 2207 | if (hci_dev_test_flag(hdev, HCI_PRIVACY)) | 2225 | if (hci_dev_test_flag(hdev, HCI_PRIVACY)) |
| 2208 | memcpy(cp.local_irk, hdev->irk, 16); | 2226 | memcpy(cp.local_irk, hdev->irk, 16); |
| @@ -2215,7 +2233,7 @@ done: · 6 unmodified lines | |||
| 2215 | 2233 | ||
| 2216 | /* Set Device Privacy Mode. */ | 2234 | /* Set Device Privacy Mode. */ |
| 2217 | static int hci_le_set_privacy_mode_sync(struct hci_dev *hdev, | 2235 | static int hci_le_set_privacy_mode_sync(struct hci_dev *hdev, |
| 2218 | struct hci_conn_params *params) | 2236 | struct conn_params *params) |
| 2219 | { | 2237 | { |
| 2220 | struct hci_cp_le_set_privacy_mode cp; | 2238 | struct hci_cp_le_set_privacy_mode cp; |
| 2221 | struct smp_irk *irk; | 2239 | struct smp_irk *irk; |
| @@ -2240,6 +2258,8 @@ static int hci_le_set_privacy_mode_sync(struct hci_dev *hdev, · 18 unmodified lines | |||
| 2240 | bacpy(&cp.bdaddr, &irk->bdaddr); | 2258 | bacpy(&cp.bdaddr, &irk->bdaddr); |
| 2241 | cp.mode = HCI_DEVICE_PRIVACY; | 2259 | cp.mode = HCI_DEVICE_PRIVACY; |
| 2242 | 2260 | ||
| 2261 | /* Note: params->privacy_mode is not updated since it is a copy */ | ||
| 2262 | |||
| 2243 | return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_PRIVACY_MODE, | 2263 | return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_PRIVACY_MODE, |
| 2244 | sizeof(cp), &cp, HCI_CMD_TIMEOUT); | 2264 | sizeof(cp), &cp, HCI_CMD_TIMEOUT); |
| 2245 | } | 2265 | } |
| @@ -2249,7 +2269,7 @@ static int hci_le_set_privacy_mode_sync(struct hci_dev *hdev, · 3 unmodified lines | |||
| 2249 | * properly set the privacy mode. | 2269 | * properly set the privacy mode. |
| 2250 | */ | 2270 | */ |
| 2251 | static int hci_le_add_accept_list_sync(struct hci_dev *hdev, | 2271 | static int hci_le_add_accept_list_sync(struct hci_dev *hdev, |
| 2252 | struct hci_conn_params *params, | 2272 | struct conn_params *params, |
| 2253 | u8 *num_entries) | 2273 | u8 *num_entries) |
| 2254 | { | 2274 | { |
| 2255 | struct hci_cp_le_add_to_accept_list cp; | 2275 | struct hci_cp_le_add_to_accept_list cp; |
| @@ -2447,6 +2467,52 @@ struct sk_buff *hci_read_local_oob_data_sync(struct hci_dev *hdev, · 191 unmodified lines | |||
| 2447 | return __hci_cmd_sync_sk(hdev, opcode, 0, NULL, 0, HCI_CMD_TIMEOUT, sk); | 2467 | return __hci_cmd_sync_sk(hdev, opcode, 0, NULL, 0, HCI_CMD_TIMEOUT, sk); |
| 2448 | } | 2468 | } |
| 2449 | 2469 | ||
| 2470 | static struct conn_params *conn_params_copy(struct list_head *list, size_t *n) | ||
| 2471 | { | ||
| 2472 | struct hci_conn_params *params; | ||
| 2473 | struct conn_params *p; | ||
| 2474 | size_t i; | ||
| 2475 | |||
| 2476 | rcu_read_lock(); | ||
| 2477 | |||
| 2478 | i = 0; | ||
| 2479 | list_for_each_entry_rcu(params, list, action) | ||
| 2480 | ++i; | ||
| 2481 | *n = i; | ||
| 2482 | |||
| 2483 | rcu_read_unlock(); | ||
| 2484 | |||
| 2485 | p = kvcalloc(*n, sizeof(struct conn_params), GFP_KERNEL); | ||
| 2486 | if (!p) | ||
| 2487 | return NULL; | ||
| 2488 | |||
| 2489 | rcu_read_lock(); | ||
| 2490 | |||
| 2491 | i = 0; | ||
| 2492 | list_for_each_entry_rcu(params, list, action) { | ||
| 2493 | /* Racing adds are handled in next scan update */ | ||
| 2494 | if (i >= *n) | ||
| 2495 | break; | ||
| 2496 | |||
| 2497 | /* No hdev->lock, but: addr, addr_type are immutable. | ||
| 2498 | * privacy_mode is only written by us or in | ||
| 2499 | * hci_cc_le_set_privacy_mode that we wait for. | ||
| 2500 | * We should be idempotent so MGMT updating flags | ||
| 2501 | * while we are processing is OK. | ||
| 2502 | */ | ||
| 2503 | bacpy(&p[i].addr, ¶ms->addr); | ||
| 2504 | p[i].addr_type = params->addr_type; | ||
| 2505 | p[i].flags = READ_ONCE(params->flags); | ||
| 2506 | p[i].privacy_mode = READ_ONCE(params->privacy_mode); | ||
| 2507 | ++i; | ||
| 2508 | } | ||
| 2509 | |||
| 2510 | rcu_read_unlock(); | ||
| 2511 | |||
| 2512 | *n = i; | ||
| 2513 | return p; | ||
| 2514 | } | ||
| 2515 | |||
| 2450 | /* Device must not be scanning when updating the accept list. | 2516 | /* Device must not be scanning when updating the accept list. |
| 2451 | * | 2517 | * |
| 2452 | * Update is done using the following sequence: | 2518 | * Update is done using the following sequence: |
| @@ -2466,11 +2532,12 @@ struct sk_buff *hci_read_local_oob_data_sync(struct hci_dev *hdev, · 13 unmodified lines | |||
| 2466 | */ | 2532 | */ |
| 2467 | static u8 hci_update_accept_list_sync(struct hci_dev *hdev) | 2533 | static u8 hci_update_accept_list_sync(struct hci_dev *hdev) |
| 2468 | { | 2534 | { |
| 2469 | struct hci_conn_params *params; | 2535 | struct conn_params *params; |
| 2470 | struct bdaddr_list *b, *t; | 2536 | struct bdaddr_list *b, *t; |
| 2471 | u8 num_entries = 0; | 2537 | u8 num_entries = 0; |
| 2472 | bool pend_conn, pend_report; | 2538 | bool pend_conn, pend_report; |
| 2473 | u8 filter_policy; | 2539 | u8 filter_policy; |
| 2540 | size_t i, n; | ||
| 2474 | int err; | 2541 | int err; |
| 2475 | 2542 | ||
| 2476 | /* Pause advertising if resolving list can be used as controllers | 2543 | /* Pause advertising if resolving list can be used as controllers |
| @@ -2504,6 +2571,7 @@ static u8 hci_update_accept_list_sync(struct hci_dev *hdev) · 27 unmodified lines | |||
| 2504 | if (hci_conn_hash_lookup_le(hdev, &b->bdaddr, b->bdaddr_type)) | 2571 | if (hci_conn_hash_lookup_le(hdev, &b->bdaddr, b->bdaddr_type)) |
| 2505 | continue; | 2572 | continue; |
| 2506 | 2573 | ||
| 2574 | /* Pointers not dereferenced, no locks needed */ | ||
| 2507 | pend_conn = hci_pend_le_action_lookup(&hdev->pend_le_conns, | 2575 | pend_conn = hci_pend_le_action_lookup(&hdev->pend_le_conns, |
| 2508 | &b->bdaddr, | 2576 | &b->bdaddr, |
| 2509 | b->bdaddr_type); | 2577 | b->bdaddr_type); |
| @@ -2532,23 +2600,50 @@ static u8 hci_update_accept_list_sync(struct hci_dev *hdev) · 22 unmodified lines | |||
| 2532 | * available accept list entries in the controller, then | 2600 | * available accept list entries in the controller, then |
| 2533 | * just abort and return filer policy value to not use the | 2601 | * just abort and return filer policy value to not use the |
| 2534 | * accept list. | 2602 | * accept list. |
| 2603 | * | ||
| 2604 | * The list and params may be mutated while we wait for events, | ||
| 2605 | * so make a copy and iterate it. | ||
| 2535 | */ | 2606 | */ |
| 2536 | list_for_each_entry(params, &hdev->pend_le_conns, action) { | 2607 | |
| 2537 | err = hci_le_add_accept_list_sync(hdev, params, &num_entries); | 2608 | params = conn_params_copy(&hdev->pend_le_conns, &n); |
| 2538 | if (err) | 2609 | if (!params) { |
| 2610 | err = -ENOMEM; | ||
| 2611 | goto done; | ||
| 2612 | } | ||
| 2613 | |||
| 2614 | for (i = 0; i < n; ++i) { | ||
| 2615 | err = hci_le_add_accept_list_sync(hdev, ¶ms[i], | ||
| 2616 | &num_entries); | ||
| 2617 | if (err) { | ||
| 2618 | kvfree(params); | ||
| 2539 | goto done; | 2619 | goto done; |
| 2620 | } | ||
| 2540 | } | 2621 | } |
| 2541 | 2622 | ||
| 2623 | kvfree(params); | ||
| 2624 | |||
| 2542 | /* After adding all new pending connections, walk through | 2625 | /* After adding all new pending connections, walk through |
| 2543 | * the list of pending reports and also add these to the | 2626 | * the list of pending reports and also add these to the |
| 2544 | * accept list if there is still space. Abort if space runs out. | 2627 | * accept list if there is still space. Abort if space runs out. |
| 2545 | */ | 2628 | */ |
| 2546 | list_for_each_entry(params, &hdev->pend_le_reports, action) { | 2629 | |
| 2547 | err = hci_le_add_accept_list_sync(hdev, params, &num_entries); | 2630 | params = conn_params_copy(&hdev->pend_le_reports, &n); |
| 2548 | if (err) | 2631 | if (!params) { |
| 2632 | err = -ENOMEM; | ||
| 2633 | goto done; | ||
| 2634 | } | ||
| 2635 | |||
| 2636 | for (i = 0; i < n; ++i) { | ||
| 2637 | err = hci_le_add_accept_list_sync(hdev, ¶ms[i], | ||
| 2638 | &num_entries); | ||
| 2639 | if (err) { | ||
| 2640 | kvfree(params); | ||
| 2549 | goto done; | 2641 | goto done; |
| 2642 | } | ||
| 2550 | } | 2643 | } |
| 2551 | 2644 | ||
| 2645 | kvfree(params); | ||
| 2646 | |||
| 2552 | /* Use the allowlist unless the following conditions are all true: | 2647 | /* Use the allowlist unless the following conditions are all true: |
| 2553 | * - We are not currently suspending | 2648 | * - We are not currently suspending |
| 2554 | * - There are 1 or more ADV monitors registered and it's not offloaded | 2649 | * - There are 1 or more ADV monitors registered and it's not offloaded |
| @@ -4837,12 +4932,12 @@ static void hci_pend_le_actions_clear(struct hci_dev *hdev) · 2282 unmodified lines | |||
| 4837 | struct hci_conn_params *p; | 4932 | struct hci_conn_params *p; |
| 4838 | 4933 | ||
| 4839 | list_for_each_entry(p, &hdev->le_conn_params, list) { | 4934 | list_for_each_entry(p, &hdev->le_conn_params, list) { |
| 4935 | hci_pend_le_list_del_init(p); | ||
| 4840 | if (p->conn) { | 4936 | if (p->conn) { |
| 4841 | hci_conn_drop(p->conn); | 4937 | hci_conn_drop(p->conn); |
| 4842 | hci_conn_put(p->conn); | 4938 | hci_conn_put(p->conn); |
| 4843 | p->conn = NULL; | 4939 | p->conn = NULL; |
| 4844 | } | 4940 | } |
| 4845 | list_del_init(&p->action); | ||
| 4846 | } | 4941 | } |
| 4847 | 4942 | ||
| 4848 | BT_DBG("All LE pending actions cleared"); | 4943 | BT_DBG("All LE pending actions cleared"); |
| @@ -123,8 +123,11 @@ static struct iso_conn *iso_conn_add(struct hci_conn *hcon) · 122 unmodified lines | |||
| 123 | { | 123 | { |
| 124 | struct iso_conn *conn = hcon->iso_data; | 124 | struct iso_conn *conn = hcon->iso_data; |
| 125 | 125 | ||
| 126 | if (conn) | 126 | if (conn) { |
| 127 | if (!conn->hcon) | ||
| 128 | conn->hcon = hcon; | ||
| 127 | return conn; | 129 | return conn; |
| 130 | } | ||
| 128 | 131 | ||
| 129 | conn = kzalloc(sizeof(*conn), GFP_KERNEL); | 132 | conn = kzalloc(sizeof(*conn), GFP_KERNEL); |
| 130 | if (!conn) | 133 | if (!conn) |
| @@ -300,14 +303,13 @@ static int iso_connect_bis(struct sock *sk) · 169 unmodified lines | |||
| 300 | goto unlock; | 303 | goto unlock; |
| 301 | } | 304 | } |
| 302 | 305 | ||
| 303 | hci_dev_unlock(hdev); | 306 | lock_sock(sk); |
| 304 | hci_dev_put(hdev); | ||
| 305 | 307 | ||
| 306 | err = iso_chan_add(conn, sk, NULL); | 308 | err = iso_chan_add(conn, sk, NULL); |
| 307 | if (err) | 309 | if (err) { |
| 308 | return err; | 310 | release_sock(sk); |
| 309 | 311 | goto unlock; | |
| 310 | lock_sock(sk); | 312 | } |
| 311 | 313 | ||
| 312 | /* Update source addr of the socket */ | 314 | /* Update source addr of the socket */ |
| 313 | bacpy(&iso_pi(sk)->src, &hcon->src); | 315 | bacpy(&iso_pi(sk)->src, &hcon->src); |
| @@ -321,7 +323,6 @@ static int iso_connect_bis(struct sock *sk) · 7 unmodified lines | |||
| 321 | } | 323 | } |
| 322 | 324 | ||
| 323 | release_sock(sk); | 325 | release_sock(sk); |
| 324 | return err; | ||
| 325 | 326 | ||
| 326 | unlock: | 327 | unlock: |
| 327 | hci_dev_unlock(hdev); | 328 | hci_dev_unlock(hdev); |
| @@ -389,14 +390,13 @@ static int iso_connect_cis(struct sock *sk) · 61 unmodified lines | |||
| 389 | goto unlock; | 390 | goto unlock; |
| 390 | } | 391 | } |
| 391 | 392 | ||
| 392 | hci_dev_unlock(hdev); | 393 | lock_sock(sk); |
| 393 | hci_dev_put(hdev); | ||
| 394 | 394 | ||
| 395 | err = iso_chan_add(conn, sk, NULL); | 395 | err = iso_chan_add(conn, sk, NULL); |
| 396 | if (err) | 396 | if (err) { |
| 397 | return err; | 397 | release_sock(sk); |
| 398 | 398 | goto unlock; | |
| 399 | lock_sock(sk); | 399 | } |
| 400 | 400 | ||
| 401 | /* Update source addr of the socket */ | 401 | /* Update source addr of the socket */ |
| 402 | bacpy(&iso_pi(sk)->src, &hcon->src); | 402 | bacpy(&iso_pi(sk)->src, &hcon->src); |
| @@ -413,7 +413,6 @@ static int iso_connect_cis(struct sock *sk) · 10 unmodified lines | |||
| 413 | } | 413 | } |
| 414 | 414 | ||
| 415 | release_sock(sk); | 415 | release_sock(sk); |
| 416 | return err; | ||
| 417 | 416 | ||
| 418 | unlock: | 417 | unlock: |
| 419 | hci_dev_unlock(hdev); | 418 | hci_dev_unlock(hdev); |
| @@ -1072,8 +1071,8 @@ static int iso_sock_sendmsg(struct socket *sock, struct msghdr *msg, · 652 unmodified lines | |||
| 1072 | size_t len) | 1071 | size_t len) |
| 1073 | { | 1072 | { |
| 1074 | struct sock *sk = sock->sk; | 1073 | struct sock *sk = sock->sk; |
| 1075 | struct iso_conn *conn = iso_pi(sk)->conn; | ||
| 1076 | struct sk_buff *skb, **frag; | 1074 | struct sk_buff *skb, **frag; |
| 1075 | size_t mtu; | ||
| 1077 | int err; | 1076 | int err; |
| 1078 | 1077 | ||
| 1079 | BT_DBG("sock %p, sk %p", sock, sk); | 1078 | BT_DBG("sock %p, sk %p", sock, sk); |
| @@ -1085,11 +1084,18 @@ static int iso_sock_sendmsg(struct socket *sock, struct msghdr *msg, · 5 unmodified lines | |||
| 1085 | if (msg->msg_flags & MSG_OOB) | 1084 | if (msg->msg_flags & MSG_OOB) |
| 1086 | return -EOPNOTSUPP; | 1085 | return -EOPNOTSUPP; |
| 1087 | 1086 | ||
| 1088 | if (sk->sk_state != BT_CONNECTED) | 1087 | lock_sock(sk); |
| 1088 | |||
| 1089 | if (sk->sk_state != BT_CONNECTED) { | ||
| 1090 | release_sock(sk); | ||
| 1089 | return -ENOTCONN; | 1091 | return -ENOTCONN; |
| 1092 | } | ||
| 1093 | |||
| 1094 | mtu = iso_pi(sk)->conn->hcon->hdev->iso_mtu; | ||
| 1095 | |||
| 1096 | release_sock(sk); | ||
| 1090 | 1097 | ||
| 1091 | skb = bt_skb_sendmsg(sk, msg, len, conn->hcon->hdev->iso_mtu, | 1098 | skb = bt_skb_sendmsg(sk, msg, len, mtu, HCI_ISO_DATA_HDR_SIZE, 0); |
| 1092 | HCI_ISO_DATA_HDR_SIZE, 0); | ||
| 1093 | if (IS_ERR(skb)) | 1099 | if (IS_ERR(skb)) |
| 1094 | return PTR_ERR(skb); | 1100 | return PTR_ERR(skb); |
| 1095 | 1101 | ||
| @@ -1102,8 +1108,7 @@ static int iso_sock_sendmsg(struct socket *sock, struct msghdr *msg, · 6 unmodified lines | |||
| 1102 | while (len) { | 1108 | while (len) { |
| 1103 | struct sk_buff *tmp; | 1109 | struct sk_buff *tmp; |
| 1104 | 1110 | ||
| 1105 | tmp = bt_skb_sendmsg(sk, msg, len, conn->hcon->hdev->iso_mtu, | 1111 | tmp = bt_skb_sendmsg(sk, msg, len, mtu, 0, 0); |
| 1106 | 0, 0); | ||
| 1107 | if (IS_ERR(tmp)) { | 1112 | if (IS_ERR(tmp)) { |
| 1108 | kfree_skb(skb); | 1113 | kfree_skb(skb); |
| 1109 | return PTR_ERR(tmp); | 1114 | return PTR_ERR(tmp); |
| @@ -1158,15 +1163,19 @@ static int iso_sock_recvmsg(struct socket *sock, struct msghdr *msg, · 48 unmodified lines | |||
| 1158 | BT_DBG("sk %p", sk); | 1163 | BT_DBG("sk %p", sk); |
| 1159 | 1164 | ||
| 1160 | if (test_and_clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) { | 1165 | if (test_and_clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) { |
| 1166 | lock_sock(sk); | ||
| 1161 | switch (sk->sk_state) { | 1167 | switch (sk->sk_state) { |
| 1162 | case BT_CONNECT2: | 1168 | case BT_CONNECT2: |
| 1163 | lock_sock(sk); | ||
| 1164 | iso_conn_defer_accept(pi->conn->hcon); | 1169 | iso_conn_defer_accept(pi->conn->hcon); |
| 1165 | sk->sk_state = BT_CONFIG; | 1170 | sk->sk_state = BT_CONFIG; |
| 1166 | release_sock(sk); | 1171 | release_sock(sk); |
| 1167 | return 0; | 1172 | return 0; |
| 1168 | case BT_CONNECT: | 1173 | case BT_CONNECT: |
| 1174 | release_sock(sk); | ||
| 1169 | return iso_connect_cis(sk); | 1175 | return iso_connect_cis(sk); |
| 1176 | default: | ||
| 1177 | release_sock(sk); | ||
| 1178 | break; | ||
| 1170 | } | 1179 | } |
| 1171 | } | 1180 | } |
| 1172 | 1181 | ||
| @@ -1297,15 +1297,15 @@ static void restart_le_actions(struct hci_dev *hdev) · 1296 unmodified lines | |||
| 1297 | /* Needed for AUTO_OFF case where might not "really" | 1297 | /* Needed for AUTO_OFF case where might not "really" |
| 1298 | * have been powered off. | 1298 | * have been powered off. |
| 1299 | */ | 1299 | */ |
| 1300 | list_del_init(&p->action); | 1300 | hci_pend_le_list_del_init(p); |
| 1301 | 1301 | ||
| 1302 | switch (p->auto_connect) { | 1302 | switch (p->auto_connect) { |
| 1303 | case HCI_AUTO_CONN_DIRECT: | 1303 | case HCI_AUTO_CONN_DIRECT: |
| 1304 | case HCI_AUTO_CONN_ALWAYS: | 1304 | case HCI_AUTO_CONN_ALWAYS: |
| 1305 | list_add(&p->action, &hdev->pend_le_conns); | 1305 | hci_pend_le_list_add(p, &hdev->pend_le_conns); |
| 1306 | break; | 1306 | break; |
| 1307 | case HCI_AUTO_CONN_REPORT: | 1307 | case HCI_AUTO_CONN_REPORT: |
| 1308 | list_add(&p->action, &hdev->pend_le_reports); | 1308 | hci_pend_le_list_add(p, &hdev->pend_le_reports); |
| 1309 | break; | 1309 | break; |
| 1310 | default: | 1310 | default: |
| 1311 | break; | 1311 | break; |
| @@ -5169,7 +5169,7 @@ static int set_device_flags(struct sock *sk, struct hci_dev *hdev, void *data, · 3857 unmodified lines | |||
| 5169 | goto unlock; | 5169 | goto unlock; |
| 5170 | } | 5170 | } |
| 5171 | 5171 | ||
| 5172 | params->flags = current_flags; | 5172 | WRITE_ONCE(params->flags, current_flags); |
| 5173 | status = MGMT_STATUS_SUCCESS; | 5173 | status = MGMT_STATUS_SUCCESS; |
| 5174 | 5174 | ||
| 5175 | /* Update passive scan if HCI_CONN_FLAG_DEVICE_PRIVACY | 5175 | /* Update passive scan if HCI_CONN_FLAG_DEVICE_PRIVACY |
| @@ -7285,7 +7285,7 @@ static void get_conn_info_complete(struct hci_dev *hdev, void *data, int err) · 2109 unmodified lines | |||
| 7285 | 7285 | ||
| 7286 | bt_dev_dbg(hdev, "err %d", err); | 7286 | bt_dev_dbg(hdev, "err %d", err); |
| 7287 | 7287 | ||
| 7288 | memcpy(&rp.addr, &cp->addr.bdaddr, sizeof(rp.addr)); | 7288 | memcpy(&rp.addr, &cp->addr, sizeof(rp.addr)); |
| 7289 | 7289 | ||
| 7290 | status = mgmt_status(err); | 7290 | status = mgmt_status(err); |
| 7291 | if (status == MGMT_STATUS_SUCCESS) { | 7291 | if (status == MGMT_STATUS_SUCCESS) { |
| @@ -7580,7 +7580,7 @@ static int hci_conn_params_set(struct hci_dev *hdev, bdaddr_t *addr, · 288 unmodified lines | |||
| 7580 | if (params->auto_connect == auto_connect) | 7580 | if (params->auto_connect == auto_connect) |
| 7581 | return 0; | 7581 | return 0; |
| 7582 | 7582 | ||
| 7583 | list_del_init(¶ms->action); | 7583 | hci_pend_le_list_del_init(params); |
| 7584 | 7584 | ||
| 7585 | switch (auto_connect) { | 7585 | switch (auto_connect) { |
| 7586 | case HCI_AUTO_CONN_DISABLED: | 7586 | case HCI_AUTO_CONN_DISABLED: |
| @@ -7589,18 +7589,18 @@ static int hci_conn_params_set(struct hci_dev *hdev, bdaddr_t *addr, · 2 unmodified lines | |||
| 7589 | * connect to device, keep connecting. | 7589 | * connect to device, keep connecting. |
| 7590 | */ | 7590 | */ |
| 7591 | if (params->explicit_connect) | 7591 | if (params->explicit_connect) |
| 7592 | list_add(¶ms->action, &hdev->pend_le_conns); | 7592 | hci_pend_le_list_add(params, &hdev->pend_le_conns); |
| 7593 | break; | 7593 | break; |
| 7594 | case HCI_AUTO_CONN_REPORT: | 7594 | case HCI_AUTO_CONN_REPORT: |
| 7595 | if (params->explicit_connect) | 7595 | if (params->explicit_connect) |
| 7596 | list_add(¶ms->action, &hdev->pend_le_conns); | 7596 | hci_pend_le_list_add(params, &hdev->pend_le_conns); |
| 7597 | else | 7597 | else |
| 7598 | list_add(¶ms->action, &hdev->pend_le_reports); | 7598 | hci_pend_le_list_add(params, &hdev->pend_le_reports); |
| 7599 | break; | 7599 | break; |
| 7600 | case HCI_AUTO_CONN_DIRECT: | 7600 | case HCI_AUTO_CONN_DIRECT: |
| 7601 | case HCI_AUTO_CONN_ALWAYS: | 7601 | case HCI_AUTO_CONN_ALWAYS: |
| 7602 | if (!is_connected(hdev, addr, addr_type)) | 7602 | if (!is_connected(hdev, addr, addr_type)) |
| 7603 | list_add(¶ms->action, &hdev->pend_le_conns); | 7603 | hci_pend_le_list_add(params, &hdev->pend_le_conns); |
| 7604 | break; | 7604 | break; |
| 7605 | } | 7605 | } |
| 7606 | 7606 | ||
| @@ -7823,9 +7823,7 @@ static int remove_device(struct sock *sk, struct hci_dev *hdev, · 216 unmodified lines | |||
| 7823 | goto unlock; | 7823 | goto unlock; |
| 7824 | } | 7824 | } |
| 7825 | 7825 | ||
| 7826 | list_del(¶ms->action); | 7826 | hci_conn_params_free(params); |
| 7827 | list_del(¶ms->list); | ||
| 7828 | kfree(params); | ||
| 7829 | 7827 | ||
| 7830 | device_removed(sk, hdev, &cp->addr.bdaddr, cp->addr.type); | 7828 | device_removed(sk, hdev, &cp->addr.bdaddr, cp->addr.type); |
| 7831 | } else { | 7829 | } else { |
| @@ -7856,9 +7854,7 @@ static int remove_device(struct sock *sk, struct hci_dev *hdev, · 24 unmodified lines | |||
| 7856 | p->auto_connect = HCI_AUTO_CONN_EXPLICIT; | 7854 | p->auto_connect = HCI_AUTO_CONN_EXPLICIT; |
| 7857 | continue; | 7855 | continue; |
| 7858 | } | 7856 | } |
| 7859 | list_del(&p->action); | 7857 | hci_conn_params_free(p); |
| 7860 | list_del(&p->list); | ||
| 7861 | kfree(p); | ||
| 7862 | } | 7858 | } |
| 7863 | 7859 | ||
| 7864 | bt_dev_dbg(hdev, "All LE connection parameters were removed"); | 7860 | bt_dev_dbg(hdev, "All LE connection parameters were removed"); |
| @@ -126,8 +126,11 @@ static struct sco_conn *sco_conn_add(struct hci_conn *hcon) · 125 unmodified lines | |||
| 126 | struct hci_dev *hdev = hcon->hdev; | 126 | struct hci_dev *hdev = hcon->hdev; |
| 127 | struct sco_conn *conn = hcon->sco_data; | 127 | struct sco_conn *conn = hcon->sco_data; |
| 128 | 128 | ||
| 129 | if (conn) | 129 | if (conn) { |
| 130 | if (!conn->hcon) | ||
| 131 | conn->hcon = hcon; | ||
| 130 | return conn; | 132 | return conn; |
| 133 | } | ||
| 131 | 134 | ||
| 132 | conn = kzalloc(sizeof(struct sco_conn), GFP_KERNEL); | 135 | conn = kzalloc(sizeof(struct sco_conn), GFP_KERNEL); |
| 133 | if (!conn) | 136 | if (!conn) |
| @@ -268,21 +271,21 @@ static int sco_connect(struct sock *sk) · 134 unmodified lines | |||
| 268 | goto unlock; | 271 | goto unlock; |
| 269 | } | 272 | } |
| 270 | 273 | ||
| 271 | hci_dev_unlock(hdev); | ||
| 272 | hci_dev_put(hdev); | ||
| 273 | |||
| 274 | conn = sco_conn_add(hcon); | 274 | conn = sco_conn_add(hcon); |
| 275 | if (!conn) { | 275 | if (!conn) { |
| 276 | hci_conn_drop(hcon); | 276 | hci_conn_drop(hcon); |
| 277 | return -ENOMEM; | 277 | err = -ENOMEM; |
| 278 | goto unlock; | ||
| 278 | } | 279 | } |
| 279 | 280 | ||
| 280 | err = sco_chan_add(conn, sk, NULL); | ||
| 281 | if (err) | ||
| 282 | return err; | ||
| 283 | |||
| 284 | lock_sock(sk); | 281 | lock_sock(sk); |
| 285 | 282 | ||
| 283 | err = sco_chan_add(conn, sk, NULL); | ||
| 284 | if (err) { | ||
| 285 | release_sock(sk); | ||
| 286 | goto unlock; | ||
| 287 | } | ||
| 288 | |||
| 286 | /* Update source addr of the socket */ | 289 | /* Update source addr of the socket */ |
| 287 | bacpy(&sco_pi(sk)->src, &hcon->src); | 290 | bacpy(&sco_pi(sk)->src, &hcon->src); |
| 288 | 291 | ||
| @@ -296,8 +299,6 @@ static int sco_connect(struct sock *sk) · 7 unmodified lines | |||
| 296 | 299 | ||
| 297 | release_sock(sk); | 300 | release_sock(sk); |
| 298 | 301 | ||
| 299 | return err; | ||
| 300 | |||
| 301 | unlock: | 302 | unlock: |
| 302 | hci_dev_unlock(hdev); | 303 | hci_dev_unlock(hdev); |
| 303 | hci_dev_put(hdev); | 304 | hci_dev_put(hdev); |
| @@ -1526,6 +1526,12 @@ static int bcm_release(struct socket *sock) · 1525 unmodified lines | |||
| 1526 | 1526 | ||
| 1527 | lock_sock(sk); | 1527 | lock_sock(sk); |
| 1528 | 1528 | ||
| 1529 | #if IS_ENABLED(CONFIG_PROC_FS) | ||
| 1530 | /* remove procfs entry */ | ||
| 1531 | if (net->can.bcmproc_dir && bo->bcm_proc_read) | ||
| 1532 | remove_proc_entry(bo->procname, net->can.bcmproc_dir); | ||
| 1533 | #endif /* CONFIG_PROC_FS */ | ||
| 1534 | |||
| 1529 | list_for_each_entry_safe(op, next, &bo->tx_ops, list) | 1535 | list_for_each_entry_safe(op, next, &bo->tx_ops, list) |
| 1530 | bcm_remove_op(op); | 1536 | bcm_remove_op(op); |
| 1531 | 1537 | ||
| @@ -1561,12 +1567,6 @@ static int bcm_release(struct socket *sock) · 29 unmodified lines | |||
| 1561 | list_for_each_entry_safe(op, next, &bo->rx_ops, list) | 1567 | list_for_each_entry_safe(op, next, &bo->rx_ops, list) |
| 1562 | bcm_remove_op(op); | 1568 | bcm_remove_op(op); |
| 1563 | 1569 | ||
| 1564 | #if IS_ENABLED(CONFIG_PROC_FS) | ||
| 1565 | /* remove procfs entry */ | ||
| 1566 | if (net->can.bcmproc_dir && bo->bcm_proc_read) | ||
| 1567 | remove_proc_entry(bo->procname, net->can.bcmproc_dir); | ||
| 1568 | #endif /* CONFIG_PROC_FS */ | ||
| 1569 | |||
| 1570 | /* remove device reference */ | 1570 | /* remove device reference */ |
| 1571 | if (bo->bound) { | 1571 | if (bo->bound) { |
| 1572 | bo->bound = 0; | 1572 | bo->bound = 0; |
| @@ -84,6 +84,7 @@ struct raw_sock { · 83 unmodified lines | |||
| 84 | struct sock sk; | 84 | struct sock sk; |
| 85 | int bound; | 85 | int bound; |
| 86 | int ifindex; | 86 | int ifindex; |
| 87 | struct net_device *dev; | ||
| 87 | struct list_head notifier; | 88 | struct list_head notifier; |
| 88 | int loopback; | 89 | int loopback; |
| 89 | int recv_own_msgs; | 90 | int recv_own_msgs; |
| @@ -277,7 +278,7 @@ static void raw_notify(struct raw_sock *ro, unsigned long msg, · 187 unmodified lines | |||
| 277 | if (!net_eq(dev_net(dev), sock_net(sk))) | 278 | if (!net_eq(dev_net(dev), sock_net(sk))) |
| 278 | return; | 279 | return; |
| 279 | 280 | ||
| 280 | if (ro->ifindex != dev->ifindex) | 281 | if (ro->dev != dev) |
| 281 | return; | 282 | return; |
| 282 | 283 | ||
| 283 | switch (msg) { | 284 | switch (msg) { |
| @@ -292,6 +293,7 @@ static void raw_notify(struct raw_sock *ro, unsigned long msg, · 8 unmodified lines | |||
| 292 | 293 | ||
| 293 | ro->ifindex = 0; | 294 | ro->ifindex = 0; |
| 294 | ro->bound = 0; | 295 | ro->bound = 0; |
| 296 | ro->dev = NULL; | ||
| 295 | ro->count = 0; | 297 | ro->count = 0; |
| 296 | release_sock(sk); | 298 | release_sock(sk); |
| 297 | 299 | ||
| @@ -337,6 +339,7 @@ static int raw_init(struct sock *sk) · 39 unmodified lines | |||
| 337 | 339 | ||
| 338 | ro->bound = 0; | 340 | ro->bound = 0; |
| 339 | ro->ifindex = 0; | 341 | ro->ifindex = 0; |
| 342 | ro->dev = NULL; | ||
| 340 | 343 | ||
| 341 | /* set default filter to single entry dfilter */ | 344 | /* set default filter to single entry dfilter */ |
| 342 | ro->dfilter.can_id = 0; | 345 | ro->dfilter.can_id = 0; |
| @@ -385,19 +388,13 @@ static int raw_release(struct socket *sock) · 42 unmodified lines | |||
| 385 | 388 | ||
| 386 | lock_sock(sk); | 389 | lock_sock(sk); |
| 387 | 390 | ||
| 391 | rtnl_lock(); | ||
| 388 | /* remove current filters & unregister */ | 392 | /* remove current filters & unregister */ |
| 389 | if (ro->bound) { | 393 | if (ro->bound) { |
| 390 | if (ro->ifindex) { | 394 | if (ro->dev) |
| 391 | struct net_device *dev; | 395 | raw_disable_allfilters(dev_net(ro->dev), ro->dev, sk); |
| 392 | 396 | else | |
| 393 | dev = dev_get_by_index(sock_net(sk), ro->ifindex); | ||
| 394 | if (dev) { | ||
| 395 | raw_disable_allfilters(dev_net(dev), dev, sk); | ||
| 396 | dev_put(dev); | ||
| 397 | } | ||
| 398 | } else { | ||
| 399 | raw_disable_allfilters(sock_net(sk), NULL, sk); | 397 | raw_disable_allfilters(sock_net(sk), NULL, sk); |
| 400 | } | ||
| 401 | } | 398 | } |
| 402 | 399 | ||
| 403 | if (ro->count > 1) | 400 | if (ro->count > 1) |
| @@ -405,8 +402,10 @@ static int raw_release(struct socket *sock) · 1 unmodified line | |||
| 405 | 402 | ||
| 406 | ro->ifindex = 0; | 403 | ro->ifindex = 0; |
| 407 | ro->bound = 0; | 404 | ro->bound = 0; |
| 405 | ro->dev = NULL; | ||
| 408 | ro->count = 0; | 406 | ro->count = 0; |
| 409 | free_percpu(ro->uniq); | 407 | free_percpu(ro->uniq); |
| 408 | rtnl_unlock(); | ||
| 410 | 409 | ||
| 411 | sock_orphan(sk); | 410 | sock_orphan(sk); |
| 412 | sock->sk = NULL; | 411 | sock->sk = NULL; |
| @@ -422,6 +421,7 @@ static int raw_bind(struct socket *sock, struct sockaddr *uaddr, int len) · 9 unmodified lines | |||
| 422 | struct sockaddr_can *addr = (struct sockaddr_can *)uaddr; | 421 | struct sockaddr_can *addr = (struct sockaddr_can *)uaddr; |
| 423 | struct sock *sk = sock->sk; | 422 | struct sock *sk = sock->sk; |
| 424 | struct raw_sock *ro = raw_sk(sk); | 423 | struct raw_sock *ro = raw_sk(sk); |
| 424 | struct net_device *dev = NULL; | ||
| 425 | int ifindex; | 425 | int ifindex; |
| 426 | int err = 0; | 426 | int err = 0; |
| 427 | int notify_enetdown = 0; | 427 | int notify_enetdown = 0; |
| @@ -431,14 +431,13 @@ static int raw_bind(struct socket *sock, struct sockaddr *uaddr, int len) · 3 unmodified lines | |||
| 431 | if (addr->can_family != AF_CAN) | 431 | if (addr->can_family != AF_CAN) |
| 432 | return -EINVAL; | 432 | return -EINVAL; |
| 433 | 433 | ||
| 434 | rtnl_lock(); | ||
| 434 | lock_sock(sk); | 435 | lock_sock(sk); |
| 435 | 436 | ||
| 436 | if (ro->bound && addr->can_ifindex == ro->ifindex) | 437 | if (ro->bound && addr->can_ifindex == ro->ifindex) |
| 437 | goto out; | 438 | goto out; |
| 438 | 439 | ||
| 439 | if (addr->can_ifindex) { | 440 | if (addr->can_ifindex) { |
| 440 | struct net_device *dev; | ||
| 441 | |||
| 442 | dev = dev_get_by_index(sock_net(sk), addr->can_ifindex); | 441 | dev = dev_get_by_index(sock_net(sk), addr->can_ifindex); |
| 443 | if (!dev) { | 442 | if (!dev) { |
| 444 | err = -ENODEV; | 443 | err = -ENODEV; |
| @@ -467,26 +466,20 @@ static int raw_bind(struct socket *sock, struct sockaddr *uaddr, int len) · 22 unmodified lines | |||
| 467 | if (!err) { | 466 | if (!err) { |
| 468 | if (ro->bound) { | 467 | if (ro->bound) { |
| 469 | /* unregister old filters */ | 468 | /* unregister old filters */ |
| 470 | if (ro->ifindex) { | 469 | if (ro->dev) |
| 471 | struct net_device *dev; | 470 | raw_disable_allfilters(dev_net(ro->dev), |
| 472 | 471 | ro->dev, sk); | |
| 473 | dev = dev_get_by_index(sock_net(sk), | 472 | else |
| 474 | ro->ifindex); | ||
| 475 | if (dev) { | ||
| 476 | raw_disable_allfilters(dev_net(dev), | ||
| 477 | dev, sk); | ||
| 478 | dev_put(dev); | ||
| 479 | } | ||
| 480 | } else { | ||
| 481 | raw_disable_allfilters(sock_net(sk), NULL, sk); | 473 | raw_disable_allfilters(sock_net(sk), NULL, sk); |
| 482 | } | ||
| 483 | } | 474 | } |
| 484 | ro->ifindex = ifindex; | 475 | ro->ifindex = ifindex; |
| 485 | ro->bound = 1; | 476 | ro->bound = 1; |
| 477 | ro->dev = dev; | ||
| 486 | } | 478 | } |
| 487 | 479 | ||
| 488 | out: | 480 | out: |
| 489 | release_sock(sk); | 481 | release_sock(sk); |
| 482 | rtnl_unlock(); | ||
| 490 | 483 | ||
| 491 | if (notify_enetdown) { | 484 | if (notify_enetdown) { |
| 492 | sk->sk_err = ENETDOWN; | 485 | sk->sk_err = ENETDOWN; |
| @@ -553,9 +546,9 @@ static int raw_setsockopt(struct socket *sock, int level, int optname, · 60 unmodified lines | |||
| 553 | rtnl_lock(); | 546 | rtnl_lock(); |
| 554 | lock_sock(sk); | 547 | lock_sock(sk); |
| 555 | 548 | ||
| 556 | if (ro->bound && ro->ifindex) { | 549 | dev = ro->dev; |
| 557 | dev = dev_get_by_index(sock_net(sk), ro->ifindex); | 550 | if (ro->bound && dev) { |
| 558 | if (!dev) { | 551 | if (dev->reg_state != NETREG_REGISTERED) { |
| 559 | if (count > 1) | 552 | if (count > 1) |
| 560 | kfree(filter); | 553 | kfree(filter); |
| 561 | err = -ENODEV; | 554 | err = -ENODEV; |
| @@ -596,7 +589,6 @@ static int raw_setsockopt(struct socket *sock, int level, int optname, · 34 unmodified lines | |||
| 596 | ro->count = count; | 589 | ro->count = count; |
| 597 | 590 | ||
| 598 | out_fil: | 591 | out_fil: |
| 599 | dev_put(dev); | ||
| 600 | release_sock(sk); | 592 | release_sock(sk); |
| 601 | rtnl_unlock(); | 593 | rtnl_unlock(); |
| 602 | 594 | ||
| @@ -614,9 +606,9 @@ static int raw_setsockopt(struct socket *sock, int level, int optname, · 11 unmodified lines | |||
| 614 | rtnl_lock(); | 606 | rtnl_lock(); |
| 615 | lock_sock(sk); | 607 | lock_sock(sk); |
| 616 | 608 | ||
| 617 | if (ro->bound && ro->ifindex) { | 609 | dev = ro->dev; |
| 618 | dev = dev_get_by_index(sock_net(sk), ro->ifindex); | 610 | if (ro->bound && dev) { |
| 619 | if (!dev) { | 611 | if (dev->reg_state != NETREG_REGISTERED) { |
| 620 | err = -ENODEV; | 612 | err = -ENODEV; |
| 621 | goto out_err; | 613 | goto out_err; |
| 622 | } | 614 | } |
| @@ -640,7 +632,6 @@ static int raw_setsockopt(struct socket *sock, int level, int optname, · 17 unmodified lines | |||
| 640 | ro->err_mask = err_mask; | 632 | ro->err_mask = err_mask; |
| 641 | 633 | ||
| 642 | out_err: | 634 | out_err: |
| 643 | dev_put(dev); | ||
| 644 | release_sock(sk); | 635 | release_sock(sk); |
| 645 | rtnl_unlock(); | 636 | rtnl_unlock(); |
| 646 | 637 | ||
| @@ -1132,7 +1132,7 @@ static int esp_init_authenc(struct xfrm_state *x, · 1131 unmodified lines | |||
| 1132 | err = crypto_aead_setkey(aead, key, keylen); | 1132 | err = crypto_aead_setkey(aead, key, keylen); |
| 1133 | 1133 | ||
| 1134 | free_key: | 1134 | free_key: |
| 1135 | kfree(key); | 1135 | kfree_sensitive(key); |
| 1136 | 1136 | ||
| 1137 | error: | 1137 | error: |
| 1138 | return err; | 1138 | return err; |
| @@ -1019,7 +1019,7 @@ static void reqsk_timer_handler(struct timer_list *t) · 1018 unmodified lines | |||
| 1019 | 1019 | ||
| 1020 | icsk = inet_csk(sk_listener); | 1020 | icsk = inet_csk(sk_listener); |
| 1021 | net = sock_net(sk_listener); | 1021 | net = sock_net(sk_listener); |
| 1022 | max_syn_ack_retries = icsk->icsk_syn_retries ? : | 1022 | max_syn_ack_retries = READ_ONCE(icsk->icsk_syn_retries) ? : |
| 1023 | READ_ONCE(net->ipv4.sysctl_tcp_synack_retries); | 1023 | READ_ONCE(net->ipv4.sysctl_tcp_synack_retries); |
| 1024 | /* Normally all the openreqs are young and become mature | 1024 | /* Normally all the openreqs are young and become mature |
| 1025 | * (i.e. converted to established socket) for first timeout. | 1025 | * (i.e. converted to established socket) for first timeout. |
| @@ -650,20 +650,8 @@ bool inet_ehash_insert(struct sock *sk, struct sock *osk, bool *found_dup_sk) · 649 unmodified lines | |||
| 650 | spin_lock(lock); | 650 | spin_lock(lock); |
| 651 | if (osk) { | 651 | if (osk) { |
| 652 | WARN_ON_ONCE(sk->sk_hash != osk->sk_hash); | 652 | WARN_ON_ONCE(sk->sk_hash != osk->sk_hash); |
| 653 | ret = sk_hashed(osk); | 653 | ret = sk_nulls_del_node_init_rcu(osk); |
| 654 | if (ret) { | 654 | } else if (found_dup_sk) { |
| 655 | /* Before deleting the node, we insert a new one to make | ||
| 656 | * sure that the look-up-sk process would not miss either | ||
| 657 | * of them and that at least one node would exist in ehash | ||
| 658 | * table all the time. Otherwise there's a tiny chance | ||
| 659 | * that lookup process could find nothing in ehash table. | ||
| 660 | */ | ||
| 661 | __sk_nulls_add_node_tail_rcu(sk, list); | ||
| 662 | sk_nulls_del_node_init_rcu(osk); | ||
| 663 | } | ||
| 664 | goto unlock; | ||
| 665 | } | ||
| 666 | if (found_dup_sk) { | ||
| 667 | *found_dup_sk = inet_ehash_lookup_by_sk(sk, list); | 655 | *found_dup_sk = inet_ehash_lookup_by_sk(sk, list); |
| 668 | if (*found_dup_sk) | 656 | if (*found_dup_sk) |
| 669 | ret = false; | 657 | ret = false; |
| @@ -672,7 +660,6 @@ bool inet_ehash_insert(struct sock *sk, struct sock *osk, bool *found_dup_sk) · 2 unmodified lines | |||
| 672 | if (ret) | 660 | if (ret) |
| 673 | __sk_nulls_add_node_rcu(sk, list); | 661 | __sk_nulls_add_node_rcu(sk, list); |
| 674 | 662 | ||
| 675 | unlock: | ||
| 676 | spin_unlock(lock); | 663 | spin_unlock(lock); |
| 677 | 664 | ||
| 678 | return ret; | 665 | return ret; |
| @@ -88,10 +88,10 @@ void inet_twsk_put(struct inet_timewait_sock *tw) · 87 unmodified lines | |||
| 88 | } | 88 | } |
| 89 | EXPORT_SYMBOL_GPL(inet_twsk_put); | 89 | EXPORT_SYMBOL_GPL(inet_twsk_put); |
| 90 | 90 | ||
| 91 | static void inet_twsk_add_node_tail_rcu(struct inet_timewait_sock *tw, | 91 | static void inet_twsk_add_node_rcu(struct inet_timewait_sock *tw, |
| 92 | struct hlist_nulls_head *list) | 92 | struct hlist_nulls_head *list) |
| 93 | { | 93 | { |
| 94 | hlist_nulls_add_tail_rcu(&tw->tw_node, list); | 94 | hlist_nulls_add_head_rcu(&tw->tw_node, list); |
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | static void inet_twsk_add_bind_node(struct inet_timewait_sock *tw, | 97 | static void inet_twsk_add_bind_node(struct inet_timewait_sock *tw, |
| @@ -144,7 +144,7 @@ void inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk, · 46 unmodified lines | |||
| 144 | 144 | ||
| 145 | spin_lock(lock); | 145 | spin_lock(lock); |
| 146 | 146 | ||
| 147 | inet_twsk_add_node_tail_rcu(tw, &ehead->chain); | 147 | inet_twsk_add_node_rcu(tw, &ehead->chain); |
| 148 | 148 | ||
| 149 | /* Step 3: Remove SK from hash chain */ | 149 | /* Step 3: Remove SK from hash chain */ |
| 150 | if (__sk_nulls_del_node_init_rcu(sk)) | 150 | if (__sk_nulls_del_node_init_rcu(sk)) |
| @@ -548,7 +548,8 @@ static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev) · 547 unmodified lines | |||
| 548 | goto err_free_skb; | 548 | goto err_free_skb; |
| 549 | 549 | ||
| 550 | if (skb->len > dev->mtu + dev->hard_header_len) { | 550 | if (skb->len > dev->mtu + dev->hard_header_len) { |
| 551 | pskb_trim(skb, dev->mtu + dev->hard_header_len); | 551 | if (pskb_trim(skb, dev->mtu + dev->hard_header_len)) |
| 552 | goto err_free_skb; | ||
| 552 | truncate = true; | 553 | truncate = true; |
| 553 | } | 554 | } |
| 554 | 555 | ||
| @@ -689,7 +690,8 @@ static netdev_tx_t erspan_xmit(struct sk_buff *skb, · 134 unmodified lines | |||
| 689 | goto free_skb; | 690 | goto free_skb; |
| 690 | 691 | ||
| 691 | if (skb->len > dev->mtu + dev->hard_header_len) { | 692 | if (skb->len > dev->mtu + dev->hard_header_len) { |
| 692 | pskb_trim(skb, dev->mtu + dev->hard_header_len); | 693 | if (pskb_trim(skb, dev->mtu + dev->hard_header_len)) |
| 694 | goto free_skb; | ||
| 693 | truncate = true; | 695 | truncate = true; |
| 694 | } | 696 | } |
| 695 | 697 | ||
| @@ -3291,7 +3291,7 @@ int tcp_sock_set_syncnt(struct sock *sk, int val) · 3290 unmodified lines | |||
| 3291 | return -EINVAL; | 3291 | return -EINVAL; |
| 3292 | 3292 | ||
| 3293 | lock_sock(sk); | 3293 | lock_sock(sk); |
| 3294 | inet_csk(sk)->icsk_syn_retries = val; | 3294 | WRITE_ONCE(inet_csk(sk)->icsk_syn_retries, val); |
| 3295 | release_sock(sk); | 3295 | release_sock(sk); |
| 3296 | return 0; | 3296 | return 0; |
| 3297 | } | 3297 | } |
| @@ -3300,7 +3300,7 @@ EXPORT_SYMBOL(tcp_sock_set_syncnt); · 2 unmodified lines | |||
| 3300 | void tcp_sock_set_user_timeout(struct sock *sk, u32 val) | 3300 | void tcp_sock_set_user_timeout(struct sock *sk, u32 val) |
| 3301 | { | 3301 | { |
| 3302 | lock_sock(sk); | 3302 | lock_sock(sk); |
| 3303 | inet_csk(sk)->icsk_user_timeout = val; | 3303 | WRITE_ONCE(inet_csk(sk)->icsk_user_timeout, val); |
| 3304 | release_sock(sk); | 3304 | release_sock(sk); |
| 3305 | } | 3305 | } |
| 3306 | EXPORT_SYMBOL(tcp_sock_set_user_timeout); | 3306 | EXPORT_SYMBOL(tcp_sock_set_user_timeout); |
| @@ -3312,7 +3312,8 @@ int tcp_sock_set_keepidle_locked(struct sock *sk, int val) · 5 unmodified lines | |||
| 3312 | if (val < 1 || val > MAX_TCP_KEEPIDLE) | 3312 | if (val < 1 || val > MAX_TCP_KEEPIDLE) |
| 3313 | return -EINVAL; | 3313 | return -EINVAL; |
| 3314 | 3314 | ||
| 3315 | tp->keepalive_time = val * HZ; | 3315 | /* Paired with WRITE_ONCE() in keepalive_time_when() */ |
| 3316 | WRITE_ONCE(tp->keepalive_time, val * HZ); | ||
| 3316 | if (sock_flag(sk, SOCK_KEEPOPEN) && | 3317 | if (sock_flag(sk, SOCK_KEEPOPEN) && |
| 3317 | !((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) { | 3318 | !((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) { |
| 3318 | u32 elapsed = keepalive_time_elapsed(tp); | 3319 | u32 elapsed = keepalive_time_elapsed(tp); |
| @@ -3344,7 +3345,7 @@ int tcp_sock_set_keepintvl(struct sock *sk, int val) · 25 unmodified lines | |||
| 3344 | return -EINVAL; | 3345 | return -EINVAL; |
| 3345 | 3346 | ||
| 3346 | lock_sock(sk); | 3347 | lock_sock(sk); |
| 3347 | tcp_sk(sk)->keepalive_intvl = val * HZ; | 3348 | WRITE_ONCE(tcp_sk(sk)->keepalive_intvl, val * HZ); |
| 3348 | release_sock(sk); | 3349 | release_sock(sk); |
| 3349 | return 0; | 3350 | return 0; |
| 3350 | } | 3351 | } |
| @@ -3356,7 +3357,8 @@ int tcp_sock_set_keepcnt(struct sock *sk, int val) · 5 unmodified lines | |||
| 3356 | return -EINVAL; | 3357 | return -EINVAL; |
| 3357 | 3358 | ||
| 3358 | lock_sock(sk); | 3359 | lock_sock(sk); |
| 3359 | tcp_sk(sk)->keepalive_probes = val; | 3360 | /* Paired with READ_ONCE() in keepalive_probes() */ |
| 3361 | WRITE_ONCE(tcp_sk(sk)->keepalive_probes, val); | ||
| 3360 | release_sock(sk); | 3362 | release_sock(sk); |
| 3361 | return 0; | 3363 | return 0; |
| 3362 | } | 3364 | } |
| @@ -3558,19 +3560,19 @@ int do_tcp_setsockopt(struct sock *sk, int level, int optname, · 195 unmodified lines | |||
| 3558 | if (val < 1 || val > MAX_TCP_KEEPINTVL) | 3560 | if (val < 1 || val > MAX_TCP_KEEPINTVL) |
| 3559 | err = -EINVAL; | 3561 | err = -EINVAL; |
| 3560 | else | 3562 | else |
| 3561 | tp->keepalive_intvl = val * HZ; | 3563 | WRITE_ONCE(tp->keepalive_intvl, val * HZ); |
| 3562 | break; | 3564 | break; |
| 3563 | case TCP_KEEPCNT: | 3565 | case TCP_KEEPCNT: |
| 3564 | if (val < 1 || val > MAX_TCP_KEEPCNT) | 3566 | if (val < 1 || val > MAX_TCP_KEEPCNT) |
| 3565 | err = -EINVAL; | 3567 | err = -EINVAL; |
| 3566 | else | 3568 | else |
| 3567 | tp->keepalive_probes = val; | 3569 | WRITE_ONCE(tp->keepalive_probes, val); |
| 3568 | break; | 3570 | break; |
| 3569 | case TCP_SYNCNT: | 3571 | case TCP_SYNCNT: |
| 3570 | if (val < 1 || val > MAX_TCP_SYNCNT) | 3572 | if (val < 1 || val > MAX_TCP_SYNCNT) |
| 3571 | err = -EINVAL; | 3573 | err = -EINVAL; |
| 3572 | else | 3574 | else |
| 3573 | icsk->icsk_syn_retries = val; | 3575 | WRITE_ONCE(icsk->icsk_syn_retries, val); |
| 3574 | break; | 3576 | break; |
| 3575 | 3577 | ||
| 3576 | case TCP_SAVE_SYN: | 3578 | case TCP_SAVE_SYN: |
| @@ -3583,18 +3585,18 @@ int do_tcp_setsockopt(struct sock *sk, int level, int optname, · 6 unmodified lines | |||
| 3583 | 3585 | ||
| 3584 | case TCP_LINGER2: | 3586 | case TCP_LINGER2: |
| 3585 | if (val < 0) | 3587 | if (val < 0) |
| 3586 | tp->linger2 = -1; | 3588 | WRITE_ONCE(tp->linger2, -1); |
| 3587 | else if (val > TCP_FIN_TIMEOUT_MAX / HZ) | 3589 | else if (val > TCP_FIN_TIMEOUT_MAX / HZ) |
| 3588 | tp->linger2 = TCP_FIN_TIMEOUT_MAX; | 3590 | WRITE_ONCE(tp->linger2, TCP_FIN_TIMEOUT_MAX); |
| 3589 | else | 3591 | else |
| 3590 | tp->linger2 = val * HZ; | 3592 | WRITE_ONCE(tp->linger2, val * HZ); |
| 3591 | break; | 3593 | break; |
| 3592 | 3594 | ||
| 3593 | case TCP_DEFER_ACCEPT: | 3595 | case TCP_DEFER_ACCEPT: |
| 3594 | /* Translate value in seconds to number of retransmits */ | 3596 | /* Translate value in seconds to number of retransmits */ |
| 3595 | icsk->icsk_accept_queue.rskq_defer_accept = | 3597 | WRITE_ONCE(icsk->icsk_accept_queue.rskq_defer_accept, |
| 3596 | secs_to_retrans(val, TCP_TIMEOUT_INIT / HZ, | 3598 | secs_to_retrans(val, TCP_TIMEOUT_INIT / HZ, |
| 3597 | TCP_RTO_MAX / HZ); | 3599 | TCP_RTO_MAX / HZ)); |
| 3598 | break; | 3600 | break; |
| 3599 | 3601 | ||
| 3600 | case TCP_WINDOW_CLAMP: | 3602 | case TCP_WINDOW_CLAMP: |
| @@ -3618,7 +3620,7 @@ int do_tcp_setsockopt(struct sock *sk, int level, int optname, · 17 unmodified lines | |||
| 3618 | if (val < 0) | 3620 | if (val < 0) |
| 3619 | err = -EINVAL; | 3621 | err = -EINVAL; |
| 3620 | else | 3622 | else |
| 3621 | icsk->icsk_user_timeout = val; | 3623 | WRITE_ONCE(icsk->icsk_user_timeout, val); |
| 3622 | break; | 3624 | break; |
| 3623 | 3625 | ||
| 3624 | case TCP_FASTOPEN: | 3626 | case TCP_FASTOPEN: |
| @@ -3656,13 +3658,13 @@ int do_tcp_setsockopt(struct sock *sk, int level, int optname, · 31 unmodified lines | |||
| 3656 | if (!tp->repair) | 3658 | if (!tp->repair) |
| 3657 | err = -EPERM; | 3659 | err = -EPERM; |
| 3658 | else | 3660 | else |
| 3659 | tp->tsoffset = val - tcp_time_stamp_raw(); | 3661 | WRITE_ONCE(tp->tsoffset, val - tcp_time_stamp_raw()); |
| 3660 | break; | 3662 | break; |
| 3661 | case TCP_REPAIR_WINDOW: | 3663 | case TCP_REPAIR_WINDOW: |
| 3662 | err = tcp_repair_set_window(tp, optval, optlen); | 3664 | err = tcp_repair_set_window(tp, optval, optlen); |
| 3663 | break; | 3665 | break; |
| 3664 | case TCP_NOTSENT_LOWAT: | 3666 | case TCP_NOTSENT_LOWAT: |
| 3665 | tp->notsent_lowat = val; | 3667 | WRITE_ONCE(tp->notsent_lowat, val); |
| 3666 | sk->sk_write_space(sk); | 3668 | sk->sk_write_space(sk); |
| 3667 | break; | 3669 | break; |
| 3668 | case TCP_INQ: | 3670 | case TCP_INQ: |
| @@ -3674,7 +3676,7 @@ int do_tcp_setsockopt(struct sock *sk, int level, int optname, · 5 unmodified lines | |||
| 3674 | case TCP_TX_DELAY: | 3676 | case TCP_TX_DELAY: |
| 3675 | if (val) | 3677 | if (val) |
| 3676 | tcp_enable_tx_delay(); | 3678 | tcp_enable_tx_delay(); |
| 3677 | tp->tcp_tx_delay = val; | 3679 | WRITE_ONCE(tp->tcp_tx_delay, val); |
| 3678 | break; | 3680 | break; |
| 3679 | default: | 3681 | default: |
| 3680 | err = -ENOPROTOOPT; | 3682 | err = -ENOPROTOOPT; |
| @@ -3991,17 +3993,18 @@ int do_tcp_getsockopt(struct sock *sk, int level, · 310 unmodified lines | |||
| 3991 | val = keepalive_probes(tp); | 3993 | val = keepalive_probes(tp); |
| 3992 | break; | 3994 | break; |
| 3993 | case TCP_SYNCNT: | 3995 | case TCP_SYNCNT: |
| 3994 | val = icsk->icsk_syn_retries ? : | 3996 | val = READ_ONCE(icsk->icsk_syn_retries) ? : |
| 3995 | READ_ONCE(net->ipv4.sysctl_tcp_syn_retries); | 3997 | READ_ONCE(net->ipv4.sysctl_tcp_syn_retries); |
| 3996 | break; | 3998 | break; |
| 3997 | case TCP_LINGER2: | 3999 | case TCP_LINGER2: |
| 3998 | val = tp->linger2; | 4000 | val = READ_ONCE(tp->linger2); |
| 3999 | if (val >= 0) | 4001 | if (val >= 0) |
| 4000 | val = (val ? : READ_ONCE(net->ipv4.sysctl_tcp_fin_timeout)) / HZ; | 4002 | val = (val ? : READ_ONCE(net->ipv4.sysctl_tcp_fin_timeout)) / HZ; |
| 4001 | break; | 4003 | break; |
| 4002 | case TCP_DEFER_ACCEPT: | 4004 | case TCP_DEFER_ACCEPT: |
| 4003 | val = retrans_to_secs(icsk->icsk_accept_queue.rskq_defer_accept, | 4005 | val = READ_ONCE(icsk->icsk_accept_queue.rskq_defer_accept); |
| 4004 | TCP_TIMEOUT_INIT / HZ, TCP_RTO_MAX / HZ); | 4006 | val = retrans_to_secs(val, TCP_TIMEOUT_INIT / HZ, |
| 4007 | TCP_RTO_MAX / HZ); | ||
| 4005 | break; | 4008 | break; |
| 4006 | case TCP_WINDOW_CLAMP: | 4009 | case TCP_WINDOW_CLAMP: |
| 4007 | val = tp->window_clamp; | 4010 | val = tp->window_clamp; |
| @@ -4138,11 +4141,11 @@ int do_tcp_getsockopt(struct sock *sk, int level, · 130 unmodified lines | |||
| 4138 | break; | 4141 | break; |
| 4139 | 4142 | ||
| 4140 | case TCP_USER_TIMEOUT: | 4143 | case TCP_USER_TIMEOUT: |
| 4141 | val = icsk->icsk_user_timeout; | 4144 | val = READ_ONCE(icsk->icsk_user_timeout); |
| 4142 | break; | 4145 | break; |
| 4143 | 4146 | ||
| 4144 | case TCP_FASTOPEN: | 4147 | case TCP_FASTOPEN: |
| 4145 | val = icsk->icsk_accept_queue.fastopenq.max_qlen; | 4148 | val = READ_ONCE(icsk->icsk_accept_queue.fastopenq.max_qlen); |
| 4146 | break; | 4149 | break; |
| 4147 | 4150 | ||
| 4148 | case TCP_FASTOPEN_CONNECT: | 4151 | case TCP_FASTOPEN_CONNECT: |
| @@ -4154,14 +4157,14 @@ int do_tcp_getsockopt(struct sock *sk, int level, · 5 unmodified lines | |||
| 4154 | break; | 4157 | break; |
| 4155 | 4158 | ||
| 4156 | case TCP_TX_DELAY: | 4159 | case TCP_TX_DELAY: |
| 4157 | val = tp->tcp_tx_delay; | 4160 | val = READ_ONCE(tp->tcp_tx_delay); |
| 4158 | break; | 4161 | break; |
| 4159 | 4162 | ||
| 4160 | case TCP_TIMESTAMP: | 4163 | case TCP_TIMESTAMP: |
| 4161 | val = tcp_time_stamp_raw() + tp->tsoffset; | 4164 | val = tcp_time_stamp_raw() + READ_ONCE(tp->tsoffset); |
| 4162 | break; | 4165 | break; |
| 4163 | case TCP_NOTSENT_LOWAT: | 4166 | case TCP_NOTSENT_LOWAT: |
| 4164 | val = tp->notsent_lowat; | 4167 | val = READ_ONCE(tp->notsent_lowat); |
| 4165 | break; | 4168 | break; |
| 4166 | case TCP_INQ: | 4169 | case TCP_INQ: |
| 4167 | val = tp->recvmsg_inq; | 4170 | val = tp->recvmsg_inq; |
| @@ -296,6 +296,7 @@ static struct sock *tcp_fastopen_create_child(struct sock *sk, · 295 unmodified lines | |||
| 296 | static bool tcp_fastopen_queue_check(struct sock *sk) | 296 | static bool tcp_fastopen_queue_check(struct sock *sk) |
| 297 | { | 297 | { |
| 298 | struct fastopen_queue *fastopenq; | 298 | struct fastopen_queue *fastopenq; |
| 299 | int max_qlen; | ||
| 299 | 300 | ||
| 300 | /* Make sure the listener has enabled fastopen, and we don't | 301 | /* Make sure the listener has enabled fastopen, and we don't |
| 301 | * exceed the max # of pending TFO requests allowed before trying | 302 | * exceed the max # of pending TFO requests allowed before trying |
| @@ -308,10 +309,11 @@ static bool tcp_fastopen_queue_check(struct sock *sk) · 6 unmodified lines | |||
| 308 | * temporarily vs a server not supporting Fast Open at all. | 309 | * temporarily vs a server not supporting Fast Open at all. |
| 309 | */ | 310 | */ |
| 310 | fastopenq = &inet_csk(sk)->icsk_accept_queue.fastopenq; | 311 | fastopenq = &inet_csk(sk)->icsk_accept_queue.fastopenq; |
| 311 | if (fastopenq->max_qlen == 0) | 312 | max_qlen = READ_ONCE(fastopenq->max_qlen); |
| 313 | if (max_qlen == 0) | ||
| 312 | return false; | 314 | return false; |
| 313 | 315 | ||
| 314 | if (fastopenq->qlen >= fastopenq->max_qlen) { | 316 | if (fastopenq->qlen >= max_qlen) { |
| 315 | struct request_sock *req1; | 317 | struct request_sock *req1; |
| 316 | spin_lock(&fastopenq->lock); | 318 | spin_lock(&fastopenq->lock); |
| 317 | req1 = fastopenq->rskq_rst_head; | 319 | req1 = fastopenq->rskq_rst_head; |
| @@ -307,8 +307,9 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) · 306 unmodified lines | |||
| 307 | inet->inet_daddr, | 307 | inet->inet_daddr, |
| 308 | inet->inet_sport, | 308 | inet->inet_sport, |
| 309 | usin->sin_port)); | 309 | usin->sin_port)); |
| 310 | tp->tsoffset = secure_tcp_ts_off(net, inet->inet_saddr, | 310 | WRITE_ONCE(tp->tsoffset, |
| 311 | inet->inet_daddr); | 311 | secure_tcp_ts_off(net, inet->inet_saddr, |
| 312 | inet->inet_daddr)); | ||
| 312 | } | 313 | } |
| 313 | 314 | ||
| 314 | inet->inet_id = get_random_u16(); | 315 | inet->inet_id = get_random_u16(); |
| @@ -988,11 +989,12 @@ static void tcp_v4_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, · 673 unmodified lines | |||
| 988 | tcp_rsk(req)->rcv_nxt, | 989 | tcp_rsk(req)->rcv_nxt, |
| 989 | req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale, | 990 | req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale, |
| 990 | tcp_time_stamp_raw() + tcp_rsk(req)->ts_off, | 991 | tcp_time_stamp_raw() + tcp_rsk(req)->ts_off, |
| 991 | req->ts_recent, | 992 | READ_ONCE(req->ts_recent), |
| 992 | 0, | 993 | 0, |
| 993 | tcp_md5_do_lookup(sk, l3index, addr, AF_INET), | 994 | tcp_md5_do_lookup(sk, l3index, addr, AF_INET), |
| 994 | inet_rsk(req)->no_srccheck ? IP_REPLY_ARG_NOSRCCHECK : 0, | 995 | inet_rsk(req)->no_srccheck ? IP_REPLY_ARG_NOSRCCHECK : 0, |
| 995 | ip_hdr(skb)->tos, tcp_rsk(req)->txhash); | 996 | ip_hdr(skb)->tos, |
| 997 | READ_ONCE(tcp_rsk(req)->txhash)); | ||
| 996 | } | 998 | } |
| 997 | 999 | ||
| 998 | /* | 1000 | /* |
| @@ -528,7 +528,7 @@ struct sock *tcp_create_openreq_child(const struct sock *sk, · 527 unmodified lines | |||
| 528 | newicsk->icsk_ack.lrcvtime = tcp_jiffies32; | 528 | newicsk->icsk_ack.lrcvtime = tcp_jiffies32; |
| 529 | 529 | ||
| 530 | newtp->lsndtime = tcp_jiffies32; | 530 | newtp->lsndtime = tcp_jiffies32; |
| 531 | newsk->sk_txhash = treq->txhash; | 531 | newsk->sk_txhash = READ_ONCE(treq->txhash); |
| 532 | newtp->total_retrans = req->num_retrans; | 532 | newtp->total_retrans = req->num_retrans; |
| 533 | 533 | ||
| 534 | tcp_init_xmit_timers(newsk); | 534 | tcp_init_xmit_timers(newsk); |
| @@ -555,7 +555,7 @@ struct sock *tcp_create_openreq_child(const struct sock *sk, · 20 unmodified lines | |||
| 555 | newtp->max_window = newtp->snd_wnd; | 555 | newtp->max_window = newtp->snd_wnd; |
| 556 | 556 | ||
| 557 | if (newtp->rx_opt.tstamp_ok) { | 557 | if (newtp->rx_opt.tstamp_ok) { |
| 558 | newtp->rx_opt.ts_recent = req->ts_recent; | 558 | newtp->rx_opt.ts_recent = READ_ONCE(req->ts_recent); |
| 559 | newtp->rx_opt.ts_recent_stamp = ktime_get_seconds(); | 559 | newtp->rx_opt.ts_recent_stamp = ktime_get_seconds(); |
| 560 | newtp->tcp_header_len = sizeof(struct tcphdr) + TCPOLEN_TSTAMP_ALIGNED; | 560 | newtp->tcp_header_len = sizeof(struct tcphdr) + TCPOLEN_TSTAMP_ALIGNED; |
| 561 | } else { | 561 | } else { |
| @@ -619,7 +619,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, · 57 unmodified lines | |||
| 619 | tcp_parse_options(sock_net(sk), skb, &tmp_opt, 0, NULL); | 619 | tcp_parse_options(sock_net(sk), skb, &tmp_opt, 0, NULL); |
| 620 | 620 | ||
| 621 | if (tmp_opt.saw_tstamp) { | 621 | if (tmp_opt.saw_tstamp) { |
| 622 | tmp_opt.ts_recent = req->ts_recent; | 622 | tmp_opt.ts_recent = READ_ONCE(req->ts_recent); |
| 623 | if (tmp_opt.rcv_tsecr) | 623 | if (tmp_opt.rcv_tsecr) |
| 624 | tmp_opt.rcv_tsecr -= tcp_rsk(req)->ts_off; | 624 | tmp_opt.rcv_tsecr -= tcp_rsk(req)->ts_off; |
| 625 | /* We do not store true stamp, but it is not required, | 625 | /* We do not store true stamp, but it is not required, |
| @@ -758,8 +758,11 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, · 132 unmodified lines | |||
| 758 | 758 | ||
| 759 | /* In sequence, PAWS is OK. */ | 759 | /* In sequence, PAWS is OK. */ |
| 760 | 760 | ||
| 761 | /* TODO: We probably should defer ts_recent change once | ||
| 762 | * we take ownership of @req. | ||
| 763 | */ | ||
| 761 | if (tmp_opt.saw_tstamp && !after(TCP_SKB_CB(skb)->seq, tcp_rsk(req)->rcv_nxt)) | 764 | if (tmp_opt.saw_tstamp && !after(TCP_SKB_CB(skb)->seq, tcp_rsk(req)->rcv_nxt)) |
| 762 | req->ts_recent = tmp_opt.rcv_tsval; | 765 | WRITE_ONCE(req->ts_recent, tmp_opt.rcv_tsval); |
| 763 | 766 | ||
| 764 | if (TCP_SKB_CB(skb)->seq == tcp_rsk(req)->rcv_isn) { | 767 | if (TCP_SKB_CB(skb)->seq == tcp_rsk(req)->rcv_isn) { |
| 765 | /* Truncate SYN, it is out of window starting | 768 | /* Truncate SYN, it is out of window starting |
| @@ -878,7 +878,7 @@ static unsigned int tcp_synack_options(const struct sock *sk, · 877 unmodified lines | |||
| 878 | if (likely(ireq->tstamp_ok)) { | 878 | if (likely(ireq->tstamp_ok)) { |
| 879 | opts->options |= OPTION_TS; | 879 | opts->options |= OPTION_TS; |
| 880 | opts->tsval = tcp_skb_timestamp(skb) + tcp_rsk(req)->ts_off; | 880 | opts->tsval = tcp_skb_timestamp(skb) + tcp_rsk(req)->ts_off; |
| 881 | opts->tsecr = req->ts_recent; | 881 | opts->tsecr = READ_ONCE(req->ts_recent); |
| 882 | remaining -= TCPOLEN_TSTAMP_ALIGNED; | 882 | remaining -= TCPOLEN_TSTAMP_ALIGNED; |
| 883 | } | 883 | } |
| 884 | if (likely(ireq->sack_ok)) { | 884 | if (likely(ireq->sack_ok)) { |
| @@ -3660,7 +3660,7 @@ struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst, · 2775 unmodified lines | |||
| 3660 | rcu_read_lock(); | 3660 | rcu_read_lock(); |
| 3661 | md5 = tcp_rsk(req)->af_specific->req_md5_lookup(sk, req_to_sk(req)); | 3661 | md5 = tcp_rsk(req)->af_specific->req_md5_lookup(sk, req_to_sk(req)); |
| 3662 | #endif | 3662 | #endif |
| 3663 | skb_set_hash(skb, tcp_rsk(req)->txhash, PKT_HASH_TYPE_L4); | 3663 | skb_set_hash(skb, READ_ONCE(tcp_rsk(req)->txhash), PKT_HASH_TYPE_L4); |
| 3664 | /* bpf program will be interested in the tcp_flags */ | 3664 | /* bpf program will be interested in the tcp_flags */ |
| 3665 | TCP_SKB_CB(skb)->tcp_flags = TCPHDR_SYN | TCPHDR_ACK; | 3665 | TCP_SKB_CB(skb)->tcp_flags = TCPHDR_SYN | TCPHDR_ACK; |
| 3666 | tcp_header_size = tcp_synack_options(sk, req, mss, skb, &opts, md5, | 3666 | tcp_header_size = tcp_synack_options(sk, req, mss, skb, &opts, md5, |
| @@ -4210,7 +4210,7 @@ int tcp_rtx_synack(const struct sock *sk, struct request_sock *req) · 543 unmodified lines | |||
| 4210 | 4210 | ||
| 4211 | /* Paired with WRITE_ONCE() in sock_setsockopt() */ | 4211 | /* Paired with WRITE_ONCE() in sock_setsockopt() */ |
| 4212 | if (READ_ONCE(sk->sk_txrehash) == SOCK_TXREHASH_ENABLED) | 4212 | if (READ_ONCE(sk->sk_txrehash) == SOCK_TXREHASH_ENABLED) |
| 4213 | tcp_rsk(req)->txhash = net_tx_rndhash(); | 4213 | WRITE_ONCE(tcp_rsk(req)->txhash, net_tx_rndhash()); |
| 4214 | res = af_ops->send_synack(sk, NULL, &fl, req, NULL, TCP_SYNACK_NORMAL, | 4214 | res = af_ops->send_synack(sk, NULL, &fl, req, NULL, TCP_SYNACK_NORMAL, |
| 4215 | NULL); | 4215 | NULL); |
| 4216 | if (!res) { | 4216 | if (!res) { |
| @@ -274,13 +274,20 @@ struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb, · 273 unmodified lines | |||
| 274 | __sum16 check; | 274 | __sum16 check; |
| 275 | __be16 newlen; | 275 | __be16 newlen; |
| 276 | 276 | ||
| 277 | if (skb_shinfo(gso_skb)->gso_type & SKB_GSO_FRAGLIST) | ||
| 278 | return __udp_gso_segment_list(gso_skb, features, is_ipv6); | ||
| 279 | |||
| 280 | mss = skb_shinfo(gso_skb)->gso_size; | 277 | mss = skb_shinfo(gso_skb)->gso_size; |
| 281 | if (gso_skb->len <= sizeof(*uh) + mss) | 278 | if (gso_skb->len <= sizeof(*uh) + mss) |
| 282 | return ERR_PTR(-EINVAL); | 279 | return ERR_PTR(-EINVAL); |
| 283 | 280 | ||
| 281 | if (skb_gso_ok(gso_skb, features | NETIF_F_GSO_ROBUST)) { | ||
| 282 | /* Packet is from an untrusted source, reset gso_segs. */ | ||
| 283 | skb_shinfo(gso_skb)->gso_segs = DIV_ROUND_UP(gso_skb->len - sizeof(*uh), | ||
| 284 | mss); | ||
| 285 | return NULL; | ||
| 286 | } | ||
| 287 | |||
| 288 | if (skb_shinfo(gso_skb)->gso_type & SKB_GSO_FRAGLIST) | ||
| 289 | return __udp_gso_segment_list(gso_skb, features, is_ipv6); | ||
| 290 | |||
| 284 | skb_pull(gso_skb, sizeof(*uh)); | 291 | skb_pull(gso_skb, sizeof(*uh)); |
| 285 | 292 | ||
| 286 | /* clear destructor to avoid skb_segment assigning it to tail */ | 293 | /* clear destructor to avoid skb_segment assigning it to tail */ |
| @@ -388,8 +395,7 @@ static struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb, · 101 unmodified lines | |||
| 388 | if (!pskb_may_pull(skb, sizeof(struct udphdr))) | 395 | if (!pskb_may_pull(skb, sizeof(struct udphdr))) |
| 389 | goto out; | 396 | goto out; |
| 390 | 397 | ||
| 391 | if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4 && | 398 | if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4) |
| 392 | !skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) | ||
| 393 | return __udp_gso_segment(skb, features, false); | 399 | return __udp_gso_segment(skb, features, false); |
| 394 | 400 | ||
| 395 | mss = skb_shinfo(skb)->gso_size; | 401 | mss = skb_shinfo(skb)->gso_size; |
| @@ -955,7 +955,8 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb, · 954 unmodified lines | |||
| 955 | goto tx_err; | 955 | goto tx_err; |
| 956 | 956 | ||
| 957 | if (skb->len > dev->mtu + dev->hard_header_len) { | 957 | if (skb->len > dev->mtu + dev->hard_header_len) { |
| 958 | pskb_trim(skb, dev->mtu + dev->hard_header_len); | 958 | if (pskb_trim(skb, dev->mtu + dev->hard_header_len)) |
| 959 | goto tx_err; | ||
| 959 | truncate = true; | 960 | truncate = true; |
| 960 | } | 961 | } |
| 961 | 962 | ||
| @@ -1126,10 +1126,10 @@ static void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, · 1125 unmodified lines | |||
| 1126 | tcp_rsk(req)->rcv_nxt, | 1126 | tcp_rsk(req)->rcv_nxt, |
| 1127 | req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale, | 1127 | req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale, |
| 1128 | tcp_time_stamp_raw() + tcp_rsk(req)->ts_off, | 1128 | tcp_time_stamp_raw() + tcp_rsk(req)->ts_off, |
| 1129 | req->ts_recent, sk->sk_bound_dev_if, | 1129 | READ_ONCE(req->ts_recent), sk->sk_bound_dev_if, |
| 1130 | tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->saddr, l3index), | 1130 | tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->saddr, l3index), |
| 1131 | ipv6_get_dsfield(ipv6_hdr(skb)), 0, sk->sk_priority, | 1131 | ipv6_get_dsfield(ipv6_hdr(skb)), 0, sk->sk_priority, |
| 1132 | tcp_rsk(req)->txhash); | 1132 | READ_ONCE(tcp_rsk(req)->txhash)); |
| 1133 | } | 1133 | } |
| 1134 | 1134 | ||
| 1135 | 1135 | ||
| @@ -43,8 +43,7 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, · 42 unmodified lines | |||
| 43 | if (!pskb_may_pull(skb, sizeof(struct udphdr))) | 43 | if (!pskb_may_pull(skb, sizeof(struct udphdr))) |
| 44 | goto out; | 44 | goto out; |
| 45 | 45 | ||
| 46 | if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4 && | 46 | if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4) |
| 47 | !skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) | ||
| 48 | return __udp_gso_segment(skb, features, true); | 47 | return __udp_gso_segment(skb, features, true); |
| 49 | 48 | ||
| 50 | mss = skb_shinfo(skb)->gso_size; | 49 | mss = skb_shinfo(skb)->gso_size; |
| @@ -402,7 +402,7 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen) · 401 unmodified lines | |||
| 402 | memcpy(laddr.mac, addr->sllc_mac, IFHWADDRLEN); | 402 | memcpy(laddr.mac, addr->sllc_mac, IFHWADDRLEN); |
| 403 | laddr.lsap = addr->sllc_sap; | 403 | laddr.lsap = addr->sllc_sap; |
| 404 | rc = -EADDRINUSE; /* mac + sap clash. */ | 404 | rc = -EADDRINUSE; /* mac + sap clash. */ |
| 405 | ask = llc_lookup_established(sap, &daddr, &laddr); | 405 | ask = llc_lookup_established(sap, &daddr, &laddr, &init_net); |
| 406 | if (ask) { | 406 | if (ask) { |
| 407 | sock_put(ask); | 407 | sock_put(ask); |
| 408 | goto out_put; | 408 | goto out_put; |
| @@ -453,11 +453,13 @@ static int llc_exec_conn_trans_actions(struct sock *sk, · 452 unmodified lines | |||
| 453 | static inline bool llc_estab_match(const struct llc_sap *sap, | 453 | static inline bool llc_estab_match(const struct llc_sap *sap, |
| 454 | const struct llc_addr *daddr, | 454 | const struct llc_addr *daddr, |
| 455 | const struct llc_addr *laddr, | 455 | const struct llc_addr *laddr, |
| 456 | const struct sock *sk) | 456 | const struct sock *sk, |
| 457 | const struct net *net) | ||
| 457 | { | 458 | { |
| 458 | struct llc_sock *llc = llc_sk(sk); | 459 | struct llc_sock *llc = llc_sk(sk); |
| 459 | 460 | ||
| 460 | return llc->laddr.lsap == laddr->lsap && | 461 | return net_eq(sock_net(sk), net) && |
| 462 | llc->laddr.lsap == laddr->lsap && | ||
| 461 | llc->daddr.lsap == daddr->lsap && | 463 | llc->daddr.lsap == daddr->lsap && |
| 462 | ether_addr_equal(llc->laddr.mac, laddr->mac) && | 464 | ether_addr_equal(llc->laddr.mac, laddr->mac) && |
| 463 | ether_addr_equal(llc->daddr.mac, daddr->mac); | 465 | ether_addr_equal(llc->daddr.mac, daddr->mac); |
| @@ -468,6 +470,7 @@ static inline bool llc_estab_match(const struct llc_sap *sap, · 4 unmodified lines | |||
| 468 | * @sap: SAP | 470 | * @sap: SAP |
| 469 | * @daddr: address of remote LLC (MAC + SAP) | 471 | * @daddr: address of remote LLC (MAC + SAP) |
| 470 | * @laddr: address of local LLC (MAC + SAP) | 472 | * @laddr: address of local LLC (MAC + SAP) |
| 473 | * @net: netns to look up a socket in | ||
| 471 | * | 474 | * |
| 472 | * Search connection list of the SAP and finds connection using the remote | 475 | * Search connection list of the SAP and finds connection using the remote |
| 473 | * mac, remote sap, local mac, and local sap. Returns pointer for | 476 | * mac, remote sap, local mac, and local sap. Returns pointer for |
| @@ -476,7 +479,8 @@ static inline bool llc_estab_match(const struct llc_sap *sap, · 2 unmodified lines | |||
| 476 | */ | 479 | */ |
| 477 | static struct sock *__llc_lookup_established(struct llc_sap *sap, | 480 | static struct sock *__llc_lookup_established(struct llc_sap *sap, |
| 478 | struct llc_addr *daddr, | 481 | struct llc_addr *daddr, |
| 479 | struct llc_addr *laddr) | 482 | struct llc_addr *laddr, |
| 483 | const struct net *net) | ||
| 480 | { | 484 | { |
| 481 | struct sock *rc; | 485 | struct sock *rc; |
| 482 | struct hlist_nulls_node *node; | 486 | struct hlist_nulls_node *node; |
| @@ -486,12 +490,12 @@ static struct sock *__llc_lookup_established(struct llc_sap *sap, · 3 unmodified lines | |||
| 486 | rcu_read_lock(); | 490 | rcu_read_lock(); |
| 487 | again: | 491 | again: |
| 488 | sk_nulls_for_each_rcu(rc, node, laddr_hb) { | 492 | sk_nulls_for_each_rcu(rc, node, laddr_hb) { |
| 489 | if (llc_estab_match(sap, daddr, laddr, rc)) { | 493 | if (llc_estab_match(sap, daddr, laddr, rc, net)) { |
| 490 | /* Extra checks required by SLAB_TYPESAFE_BY_RCU */ | 494 | /* Extra checks required by SLAB_TYPESAFE_BY_RCU */ |
| 491 | if (unlikely(!refcount_inc_not_zero(&rc->sk_refcnt))) | 495 | if (unlikely(!refcount_inc_not_zero(&rc->sk_refcnt))) |
| 492 | goto again; | 496 | goto again; |
| 493 | if (unlikely(llc_sk(rc)->sap != sap || | 497 | if (unlikely(llc_sk(rc)->sap != sap || |
| 494 | !llc_estab_match(sap, daddr, laddr, rc))) { | 498 | !llc_estab_match(sap, daddr, laddr, rc, net))) { |
| 495 | sock_put(rc); | 499 | sock_put(rc); |
| 496 | continue; | 500 | continue; |
| 497 | } | 501 | } |
| @@ -513,29 +517,33 @@ found: · 15 unmodified lines | |||
| 513 | 517 | ||
| 514 | struct sock *llc_lookup_established(struct llc_sap *sap, | 518 | struct sock *llc_lookup_established(struct llc_sap *sap, |
| 515 | struct llc_addr *daddr, | 519 | struct llc_addr *daddr, |
| 516 | struct llc_addr *laddr) | 520 | struct llc_addr *laddr, |
| 521 | const struct net *net) | ||
| 517 | { | 522 | { |
| 518 | struct sock *sk; | 523 | struct sock *sk; |
| 519 | 524 | ||
| 520 | local_bh_disable(); | 525 | local_bh_disable(); |
| 521 | sk = __llc_lookup_established(sap, daddr, laddr); | 526 | sk = __llc_lookup_established(sap, daddr, laddr, net); |
| 522 | local_bh_enable(); | 527 | local_bh_enable(); |
| 523 | return sk; | 528 | return sk; |
| 524 | } | 529 | } |
| 525 | 530 | ||
| 526 | static inline bool llc_listener_match(const struct llc_sap *sap, | 531 | static inline bool llc_listener_match(const struct llc_sap *sap, |
| 527 | const struct llc_addr *laddr, | 532 | const struct llc_addr *laddr, |
| 528 | const struct sock *sk) | 533 | const struct sock *sk, |
| 534 | const struct net *net) | ||
| 529 | { | 535 | { |
| 530 | struct llc_sock *llc = llc_sk(sk); | 536 | struct llc_sock *llc = llc_sk(sk); |
| 531 | 537 | ||
| 532 | return sk->sk_type == SOCK_STREAM && sk->sk_state == TCP_LISTEN && | 538 | return net_eq(sock_net(sk), net) && |
| 539 | sk->sk_type == SOCK_STREAM && sk->sk_state == TCP_LISTEN && | ||
| 533 | llc->laddr.lsap == laddr->lsap && | 540 | llc->laddr.lsap == laddr->lsap && |
| 534 | ether_addr_equal(llc->laddr.mac, laddr->mac); | 541 | ether_addr_equal(llc->laddr.mac, laddr->mac); |
| 535 | } | 542 | } |
| 536 | 543 | ||
| 537 | static struct sock *__llc_lookup_listener(struct llc_sap *sap, | 544 | static struct sock *__llc_lookup_listener(struct llc_sap *sap, |
| 538 | struct llc_addr *laddr) | 545 | struct llc_addr *laddr, |
| 546 | const struct net *net) | ||
| 539 | { | 547 | { |
| 540 | struct sock *rc; | 548 | struct sock *rc; |
| 541 | struct hlist_nulls_node *node; | 549 | struct hlist_nulls_node *node; |
| @@ -545,12 +553,12 @@ static struct sock *__llc_lookup_listener(struct llc_sap *sap, · 3 unmodified lines | |||
| 545 | rcu_read_lock(); | 553 | rcu_read_lock(); |
| 546 | again: | 554 | again: |
| 547 | sk_nulls_for_each_rcu(rc, node, laddr_hb) { | 555 | sk_nulls_for_each_rcu(rc, node, laddr_hb) { |
| 548 | if (llc_listener_match(sap, laddr, rc)) { | 556 | if (llc_listener_match(sap, laddr, rc, net)) { |
| 549 | /* Extra checks required by SLAB_TYPESAFE_BY_RCU */ | 557 | /* Extra checks required by SLAB_TYPESAFE_BY_RCU */ |
| 550 | if (unlikely(!refcount_inc_not_zero(&rc->sk_refcnt))) | 558 | if (unlikely(!refcount_inc_not_zero(&rc->sk_refcnt))) |
| 551 | goto again; | 559 | goto again; |
| 552 | if (unlikely(llc_sk(rc)->sap != sap || | 560 | if (unlikely(llc_sk(rc)->sap != sap || |
| 553 | !llc_listener_match(sap, laddr, rc))) { | 561 | !llc_listener_match(sap, laddr, rc, net))) { |
| 554 | sock_put(rc); | 562 | sock_put(rc); |
| 555 | continue; | 563 | continue; |
| 556 | } | 564 | } |
| @@ -574,6 +582,7 @@ found: · 17 unmodified lines | |||
| 574 | * llc_lookup_listener - Finds listener for local MAC + SAP | 582 | * llc_lookup_listener - Finds listener for local MAC + SAP |
| 575 | * @sap: SAP | 583 | * @sap: SAP |
| 576 | * @laddr: address of local LLC (MAC + SAP) | 584 | * @laddr: address of local LLC (MAC + SAP) |
| 585 | * @net: netns to look up a socket in | ||
| 577 | * | 586 | * |
| 578 | * Search connection list of the SAP and finds connection listening on | 587 | * Search connection list of the SAP and finds connection listening on |
| 579 | * local mac, and local sap. Returns pointer for parent socket found, | 588 | * local mac, and local sap. Returns pointer for parent socket found, |
| @@ -581,24 +590,26 @@ found: · 1 unmodified line | |||
| 581 | * Caller has to make sure local_bh is disabled. | 590 | * Caller has to make sure local_bh is disabled. |
| 582 | */ | 591 | */ |
| 583 | static struct sock *llc_lookup_listener(struct llc_sap *sap, | 592 | static struct sock *llc_lookup_listener(struct llc_sap *sap, |
| 584 | struct llc_addr *laddr) | 593 | struct llc_addr *laddr, |
| 594 | const struct net *net) | ||
| 585 | { | 595 | { |
| 596 | struct sock *rc = __llc_lookup_listener(sap, laddr, net); | ||
| 586 | static struct llc_addr null_addr; | 597 | static struct llc_addr null_addr; |
| 587 | struct sock *rc = __llc_lookup_listener(sap, laddr); | ||
| 588 | 598 | ||
| 589 | if (!rc) | 599 | if (!rc) |
| 590 | rc = __llc_lookup_listener(sap, &null_addr); | 600 | rc = __llc_lookup_listener(sap, &null_addr, net); |
| 591 | 601 | ||
| 592 | return rc; | 602 | return rc; |
| 593 | } | 603 | } |
| 594 | 604 | ||
| 595 | static struct sock *__llc_lookup(struct llc_sap *sap, | 605 | static struct sock *__llc_lookup(struct llc_sap *sap, |
| 596 | struct llc_addr *daddr, | 606 | struct llc_addr *daddr, |
| 597 | struct llc_addr *laddr) | 607 | struct llc_addr *laddr, |
| 608 | const struct net *net) | ||
| 598 | { | 609 | { |
| 599 | struct sock *sk = __llc_lookup_established(sap, daddr, laddr); | 610 | struct sock *sk = __llc_lookup_established(sap, daddr, laddr, net); |
| 600 | 611 | ||
| 601 | return sk ? : llc_lookup_listener(sap, laddr); | 612 | return sk ? : llc_lookup_listener(sap, laddr, net); |
| 602 | } | 613 | } |
| 603 | 614 | ||
| 604 | /** | 615 | /** |
| @@ -776,7 +787,7 @@ void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb) · 171 unmodified lines | |||
| 776 | llc_pdu_decode_da(skb, daddr.mac); | 787 | llc_pdu_decode_da(skb, daddr.mac); |
| 777 | llc_pdu_decode_dsap(skb, &daddr.lsap); | 788 | llc_pdu_decode_dsap(skb, &daddr.lsap); |
| 778 | 789 | ||
| 779 | sk = __llc_lookup(sap, &saddr, &daddr); | 790 | sk = __llc_lookup(sap, &saddr, &daddr, dev_net(skb->dev)); |
| 780 | if (!sk) | 791 | if (!sk) |
| 781 | goto drop; | 792 | goto drop; |
| 782 | 793 | ||
| @@ -92,7 +92,7 @@ int llc_establish_connection(struct sock *sk, const u8 *lmac, u8 *dmac, u8 dsap) · 91 unmodified lines | |||
| 92 | daddr.lsap = dsap; | 92 | daddr.lsap = dsap; |
| 93 | memcpy(daddr.mac, dmac, sizeof(daddr.mac)); | 93 | memcpy(daddr.mac, dmac, sizeof(daddr.mac)); |
| 94 | memcpy(laddr.mac, lmac, sizeof(laddr.mac)); | 94 | memcpy(laddr.mac, lmac, sizeof(laddr.mac)); |
| 95 | existing = llc_lookup_established(llc->sap, &daddr, &laddr); | 95 | existing = llc_lookup_established(llc->sap, &daddr, &laddr, sock_net(sk)); |
| 96 | if (existing) { | 96 | if (existing) { |
| 97 | if (existing->sk_state == TCP_ESTABLISHED) { | 97 | if (existing->sk_state == TCP_ESTABLISHED) { |
| 98 | sk = existing; | 98 | sk = existing; |
| @@ -163,9 +163,6 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev, · 162 unmodified lines | |||
| 163 | void (*sta_handler)(struct sk_buff *skb); | 163 | void (*sta_handler)(struct sk_buff *skb); |
| 164 | void (*sap_handler)(struct llc_sap *sap, struct sk_buff *skb); | 164 | void (*sap_handler)(struct llc_sap *sap, struct sk_buff *skb); |
| 165 | 165 | ||
| 166 | if (!net_eq(dev_net(dev), &init_net)) | ||
| 167 | goto drop; | ||
| 168 | |||
| 169 | /* | 166 | /* |
| 170 | * When the interface is in promisc. mode, drop all the crap that it | 167 | * When the interface is in promisc. mode, drop all the crap that it |
| 171 | * receives, do not try to analyse it. | 168 | * receives, do not try to analyse it. |
| @@ -294,25 +294,29 @@ static void llc_sap_rcv(struct llc_sap *sap, struct sk_buff *skb, · 293 unmodified lines | |||
| 294 | 294 | ||
| 295 | static inline bool llc_dgram_match(const struct llc_sap *sap, | 295 | static inline bool llc_dgram_match(const struct llc_sap *sap, |
| 296 | const struct llc_addr *laddr, | 296 | const struct llc_addr *laddr, |
| 297 | const struct sock *sk) | 297 | const struct sock *sk, |
| 298 | const struct net *net) | ||
| 298 | { | 299 | { |
| 299 | struct llc_sock *llc = llc_sk(sk); | 300 | struct llc_sock *llc = llc_sk(sk); |
| 300 | 301 | ||
| 301 | return sk->sk_type == SOCK_DGRAM && | 302 | return sk->sk_type == SOCK_DGRAM && |
| 302 | llc->laddr.lsap == laddr->lsap && | 303 | net_eq(sock_net(sk), net) && |
| 303 | ether_addr_equal(llc->laddr.mac, laddr->mac); | 304 | llc->laddr.lsap == laddr->lsap && |
| 305 | ether_addr_equal(llc->laddr.mac, laddr->mac); | ||
| 304 | } | 306 | } |
| 305 | 307 | ||
| 306 | /** | 308 | /** |
| 307 | * llc_lookup_dgram - Finds dgram socket for the local sap/mac | 309 | * llc_lookup_dgram - Finds dgram socket for the local sap/mac |
| 308 | * @sap: SAP | 310 | * @sap: SAP |
| 309 | * @laddr: address of local LLC (MAC + SAP) | 311 | * @laddr: address of local LLC (MAC + SAP) |
| 312 | * @net: netns to look up a socket in | ||
| 310 | * | 313 | * |
| 311 | * Search socket list of the SAP and finds connection using the local | 314 | * Search socket list of the SAP and finds connection using the local |
| 312 | * mac, and local sap. Returns pointer for socket found, %NULL otherwise. | 315 | * mac, and local sap. Returns pointer for socket found, %NULL otherwise. |
| 313 | */ | 316 | */ |
| 314 | static struct sock *llc_lookup_dgram(struct llc_sap *sap, | 317 | static struct sock *llc_lookup_dgram(struct llc_sap *sap, |
| 315 | const struct llc_addr *laddr) | 318 | const struct llc_addr *laddr, |
| 319 | const struct net *net) | ||
| 316 | { | 320 | { |
| 317 | struct sock *rc; | 321 | struct sock *rc; |
| 318 | struct hlist_nulls_node *node; | 322 | struct hlist_nulls_node *node; |
| @@ -322,12 +326,12 @@ static struct sock *llc_lookup_dgram(struct llc_sap *sap, · 3 unmodified lines | |||
| 322 | rcu_read_lock_bh(); | 326 | rcu_read_lock_bh(); |
| 323 | again: | 327 | again: |
| 324 | sk_nulls_for_each_rcu(rc, node, laddr_hb) { | 328 | sk_nulls_for_each_rcu(rc, node, laddr_hb) { |
| 325 | if (llc_dgram_match(sap, laddr, rc)) { | 329 | if (llc_dgram_match(sap, laddr, rc, net)) { |
| 326 | /* Extra checks required by SLAB_TYPESAFE_BY_RCU */ | 330 | /* Extra checks required by SLAB_TYPESAFE_BY_RCU */ |
| 327 | if (unlikely(!refcount_inc_not_zero(&rc->sk_refcnt))) | 331 | if (unlikely(!refcount_inc_not_zero(&rc->sk_refcnt))) |
| 328 | goto again; | 332 | goto again; |
| 329 | if (unlikely(llc_sk(rc)->sap != sap || | 333 | if (unlikely(llc_sk(rc)->sap != sap || |
| 330 | !llc_dgram_match(sap, laddr, rc))) { | 334 | !llc_dgram_match(sap, laddr, rc, net))) { |
| 331 | sock_put(rc); | 335 | sock_put(rc); |
| 332 | continue; | 336 | continue; |
| 333 | } | 337 | } |
| @@ -429,7 +433,7 @@ void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb) · 95 unmodified lines | |||
| 429 | llc_sap_mcast(sap, &laddr, skb); | 433 | llc_sap_mcast(sap, &laddr, skb); |
| 430 | kfree_skb(skb); | 434 | kfree_skb(skb); |
| 431 | } else { | 435 | } else { |
| 432 | struct sock *sk = llc_lookup_dgram(sap, &laddr); | 436 | struct sock *sk = llc_lookup_dgram(sap, &laddr, dev_net(skb->dev)); |
| 433 | if (sk) { | 437 | if (sk) { |
| 434 | llc_sap_rcv(sap, skb, sk); | 438 | llc_sap_rcv(sap, skb, sk); |
| 435 | sock_put(sk); | 439 | sock_put(sk); |
| @@ -3685,8 +3685,6 @@ int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain) · 3684 unmodified lines | |||
| 3685 | if (err < 0) | 3685 | if (err < 0) |
| 3686 | return err; | 3686 | return err; |
| 3687 | } | 3687 | } |
| 3688 | |||
| 3689 | cond_resched(); | ||
| 3690 | } | 3688 | } |
| 3691 | 3689 | ||
| 3692 | return 0; | 3690 | return 0; |
| @@ -3710,6 +3708,8 @@ static int nft_table_validate(struct net *net, const struct nft_table *table) · 17 unmodified lines | |||
| 3710 | err = nft_chain_validate(&ctx, chain); | 3708 | err = nft_chain_validate(&ctx, chain); |
| 3711 | if (err < 0) | 3709 | if (err < 0) |
| 3712 | return err; | 3710 | return err; |
| 3711 | |||
| 3712 | cond_resched(); | ||
| 3713 | } | 3713 | } |
| 3714 | 3714 | ||
| 3715 | return 0; | 3715 | return 0; |
| @@ -4087,6 +4087,8 @@ static int nf_tables_delrule(struct sk_buff *skb, const struct nfnl_info *info, · 371 unmodified lines | |||
| 4087 | list_for_each_entry(chain, &table->chains, list) { | 4087 | list_for_each_entry(chain, &table->chains, list) { |
| 4088 | if (!nft_is_active_next(net, chain)) | 4088 | if (!nft_is_active_next(net, chain)) |
| 4089 | continue; | 4089 | continue; |
| 4090 | if (nft_chain_is_bound(chain)) | ||
| 4091 | continue; | ||
| 4090 | 4092 | ||
| 4091 | ctx.chain = chain; | 4093 | ctx.chain = chain; |
| 4092 | err = nft_delrule_by_chain(&ctx); | 4094 | err = nft_delrule_by_chain(&ctx); |
| @@ -10517,6 +10519,9 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data, · 6424 unmodified lines | |||
| 10517 | 10519 | ||
| 10518 | if (!tb[NFTA_VERDICT_CODE]) | 10520 | if (!tb[NFTA_VERDICT_CODE]) |
| 10519 | return -EINVAL; | 10521 | return -EINVAL; |
| 10522 | |||
| 10523 | /* zero padding hole for memcmp */ | ||
| 10524 | memset(data, 0, sizeof(*data)); | ||
| 10520 | data->verdict.code = ntohl(nla_get_be32(tb[NFTA_VERDICT_CODE])); | 10525 | data->verdict.code = ntohl(nla_get_be32(tb[NFTA_VERDICT_CODE])); |
| 10521 | 10526 | ||
| 10522 | switch (data->verdict.code) { | 10527 | switch (data->verdict.code) { |
| @@ -10799,6 +10804,9 @@ static void __nft_release_table(struct net *net, struct nft_table *table) · 276 unmodified lines | |||
| 10799 | ctx.family = table->family; | 10804 | ctx.family = table->family; |
| 10800 | ctx.table = table; | 10805 | ctx.table = table; |
| 10801 | list_for_each_entry(chain, &table->chains, list) { | 10806 | list_for_each_entry(chain, &table->chains, list) { |
| 10807 | if (nft_chain_is_bound(chain)) | ||
| 10808 | continue; | ||
| 10809 | |||
| 10802 | ctx.chain = chain; | 10810 | ctx.chain = chain; |
| 10803 | list_for_each_entry_safe(rule, nr, &chain->rules, list) { | 10811 | list_for_each_entry_safe(rule, nr, &chain->rules, list) { |
| 10804 | list_del(&rule->list); | 10812 | list_del(&rule->list); |
| @@ -1929,7 +1929,11 @@ static void nft_pipapo_remove(const struct net *net, const struct nft_set *set, · 1928 unmodified lines | |||
| 1929 | int i, start, rules_fx; | 1929 | int i, start, rules_fx; |
| 1930 | 1930 | ||
| 1931 | match_start = data; | 1931 | match_start = data; |
| 1932 | match_end = (const u8 *)nft_set_ext_key_end(&e->ext)->data; | 1932 | |
| 1933 | if (nft_set_ext_exists(&e->ext, NFT_SET_EXT_KEY_END)) | ||
| 1934 | match_end = (const u8 *)nft_set_ext_key_end(&e->ext)->data; | ||
| 1935 | else | ||
| 1936 | match_end = data; | ||
| 1933 | 1937 | ||
| 1934 | start = first_rule; | 1938 | start = first_rule; |
| 1935 | rules_fx = rules_f0; | 1939 | rules_fx = rules_f0; |
| @@ -406,56 +406,6 @@ static int cls_bpf_prog_from_efd(struct nlattr **tb, struct cls_bpf_prog *prog, · 405 unmodified lines | |||
| 406 | return 0; | 406 | return 0; |
| 407 | } | 407 | } |
| 408 | 408 | ||
| 409 | static int cls_bpf_set_parms(struct net *net, struct tcf_proto *tp, | ||
| 410 | struct cls_bpf_prog *prog, unsigned long base, | ||
| 411 | struct nlattr **tb, struct nlattr *est, u32 flags, | ||
| 412 | struct netlink_ext_ack *extack) | ||
| 413 | { | ||
| 414 | bool is_bpf, is_ebpf, have_exts = false; | ||
| 415 | u32 gen_flags = 0; | ||
| 416 | int ret; | ||
| 417 | |||
| 418 | is_bpf = tb[TCA_BPF_OPS_LEN] && tb[TCA_BPF_OPS]; | ||
| 419 | is_ebpf = tb[TCA_BPF_FD]; | ||
| 420 | if ((!is_bpf && !is_ebpf) || (is_bpf && is_ebpf)) | ||
| 421 | return -EINVAL; | ||
| 422 | |||
| 423 | ret = tcf_exts_validate(net, tp, tb, est, &prog->exts, flags, | ||
| 424 | extack); | ||
| 425 | if (ret < 0) | ||
| 426 | return ret; | ||
| 427 | |||
| 428 | if (tb[TCA_BPF_FLAGS]) { | ||
| 429 | u32 bpf_flags = nla_get_u32(tb[TCA_BPF_FLAGS]); | ||
| 430 | |||
| 431 | if (bpf_flags & ~TCA_BPF_FLAG_ACT_DIRECT) | ||
| 432 | return -EINVAL; | ||
| 433 | |||
| 434 | have_exts = bpf_flags & TCA_BPF_FLAG_ACT_DIRECT; | ||
| 435 | } | ||
| 436 | if (tb[TCA_BPF_FLAGS_GEN]) { | ||
| 437 | gen_flags = nla_get_u32(tb[TCA_BPF_FLAGS_GEN]); | ||
| 438 | if (gen_flags & ~CLS_BPF_SUPPORTED_GEN_FLAGS || | ||
| 439 | !tc_flags_valid(gen_flags)) | ||
| 440 | return -EINVAL; | ||
| 441 | } | ||
| 442 | |||
| 443 | prog->exts_integrated = have_exts; | ||
| 444 | prog->gen_flags = gen_flags; | ||
| 445 | |||
| 446 | ret = is_bpf ? cls_bpf_prog_from_ops(tb, prog) : | ||
| 447 | cls_bpf_prog_from_efd(tb, prog, gen_flags, tp); | ||
| 448 | if (ret < 0) | ||
| 449 | return ret; | ||
| 450 | |||
| 451 | if (tb[TCA_BPF_CLASSID]) { | ||
| 452 | prog->res.classid = nla_get_u32(tb[TCA_BPF_CLASSID]); | ||
| 453 | tcf_bind_filter(tp, &prog->res, base); | ||
| 454 | } | ||
| 455 | |||
| 456 | return 0; | ||
| 457 | } | ||
| 458 | |||
| 459 | static int cls_bpf_change(struct net *net, struct sk_buff *in_skb, | 409 | static int cls_bpf_change(struct net *net, struct sk_buff *in_skb, |
| 460 | struct tcf_proto *tp, unsigned long base, | 410 | struct tcf_proto *tp, unsigned long base, |
| 461 | u32 handle, struct nlattr **tca, | 411 | u32 handle, struct nlattr **tca, |
| @@ -463,9 +413,12 @@ static int cls_bpf_change(struct net *net, struct sk_buff *in_skb, · 1 unmodified line | |||
| 463 | struct netlink_ext_ack *extack) | 413 | struct netlink_ext_ack *extack) |
| 464 | { | 414 | { |
| 465 | struct cls_bpf_head *head = rtnl_dereference(tp->root); | 415 | struct cls_bpf_head *head = rtnl_dereference(tp->root); |
| 416 | bool is_bpf, is_ebpf, have_exts = false; | ||
| 466 | struct cls_bpf_prog *oldprog = *arg; | 417 | struct cls_bpf_prog *oldprog = *arg; |
| 467 | struct nlattr *tb[TCA_BPF_MAX + 1]; | 418 | struct nlattr *tb[TCA_BPF_MAX + 1]; |
| 419 | bool bound_to_filter = false; | ||
| 468 | struct cls_bpf_prog *prog; | 420 | struct cls_bpf_prog *prog; |
| 421 | u32 gen_flags = 0; | ||
| 469 | int ret; | 422 | int ret; |
| 470 | 423 | ||
| 471 | if (tca[TCA_OPTIONS] == NULL) | 424 | if (tca[TCA_OPTIONS] == NULL) |
| @@ -504,11 +457,51 @@ static int cls_bpf_change(struct net *net, struct sk_buff *in_skb, · 32 unmodified lines | |||
| 504 | goto errout; | 457 | goto errout; |
| 505 | prog->handle = handle; | 458 | prog->handle = handle; |
| 506 | 459 | ||
| 507 | ret = cls_bpf_set_parms(net, tp, prog, base, tb, tca[TCA_RATE], flags, | 460 | is_bpf = tb[TCA_BPF_OPS_LEN] && tb[TCA_BPF_OPS]; |
| 508 | extack); | 461 | is_ebpf = tb[TCA_BPF_FD]; |
| 462 | if ((!is_bpf && !is_ebpf) || (is_bpf && is_ebpf)) { | ||
| 463 | ret = -EINVAL; | ||
| 464 | goto errout_idr; | ||
| 465 | } | ||
| 466 | |||
| 467 | ret = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &prog->exts, | ||
| 468 | flags, extack); | ||
| 469 | if (ret < 0) | ||
| 470 | goto errout_idr; | ||
| 471 | |||
| 472 | if (tb[TCA_BPF_FLAGS]) { | ||
| 473 | u32 bpf_flags = nla_get_u32(tb[TCA_BPF_FLAGS]); | ||
| 474 | |||
| 475 | if (bpf_flags & ~TCA_BPF_FLAG_ACT_DIRECT) { | ||
| 476 | ret = -EINVAL; | ||
| 477 | goto errout_idr; | ||
| 478 | } | ||
| 479 | |||
| 480 | have_exts = bpf_flags & TCA_BPF_FLAG_ACT_DIRECT; | ||
| 481 | } | ||
| 482 | if (tb[TCA_BPF_FLAGS_GEN]) { | ||
| 483 | gen_flags = nla_get_u32(tb[TCA_BPF_FLAGS_GEN]); | ||
| 484 | if (gen_flags & ~CLS_BPF_SUPPORTED_GEN_FLAGS || | ||
| 485 | !tc_flags_valid(gen_flags)) { | ||
| 486 | ret = -EINVAL; | ||
| 487 | goto errout_idr; | ||
| 488 | } | ||
| 489 | } | ||
| 490 | |||
| 491 | prog->exts_integrated = have_exts; | ||
| 492 | prog->gen_flags = gen_flags; | ||
| 493 | |||
| 494 | ret = is_bpf ? cls_bpf_prog_from_ops(tb, prog) : | ||
| 495 | cls_bpf_prog_from_efd(tb, prog, gen_flags, tp); | ||
| 509 | if (ret < 0) | 496 | if (ret < 0) |
| 510 | goto errout_idr; | 497 | goto errout_idr; |
| 511 | 498 | ||
| 499 | if (tb[TCA_BPF_CLASSID]) { | ||
| 500 | prog->res.classid = nla_get_u32(tb[TCA_BPF_CLASSID]); | ||
| 501 | tcf_bind_filter(tp, &prog->res, base); | ||
| 502 | bound_to_filter = true; | ||
| 503 | } | ||
| 504 | |||
| 512 | ret = cls_bpf_offload(tp, prog, oldprog, extack); | 505 | ret = cls_bpf_offload(tp, prog, oldprog, extack); |
| 513 | if (ret) | 506 | if (ret) |
| 514 | goto errout_parms; | 507 | goto errout_parms; |
| @@ -530,6 +523,8 @@ static int cls_bpf_change(struct net *net, struct sk_buff *in_skb, · 15 unmodified lines | |||
| 530 | return 0; | 523 | return 0; |
| 531 | 524 | ||
| 532 | errout_parms: | 525 | errout_parms: |
| 526 | if (bound_to_filter) | ||
| 527 | tcf_unbind_filter(tp, &prog->res); | ||
| 533 | cls_bpf_free_parms(prog); | 528 | cls_bpf_free_parms(prog); |
| 534 | errout_idr: | 529 | errout_idr: |
| 535 | if (!oldprog) | 530 | if (!oldprog) |
| @@ -2173,53 +2173,6 @@ static bool fl_needs_tc_skb_ext(const struct fl_flow_key *mask) · 2172 unmodified lines | |||
| 2173 | return mask->meta.l2_miss; | 2173 | return mask->meta.l2_miss; |
| 2174 | } | 2174 | } |
| 2175 | 2175 | ||
| 2176 | static int fl_set_parms(struct net *net, struct tcf_proto *tp, | ||
| 2177 | struct cls_fl_filter *f, struct fl_flow_mask *mask, | ||
| 2178 | unsigned long base, struct nlattr **tb, | ||
| 2179 | struct nlattr *est, | ||
| 2180 | struct fl_flow_tmplt *tmplt, | ||
| 2181 | u32 flags, u32 fl_flags, | ||
| 2182 | struct netlink_ext_ack *extack) | ||
| 2183 | { | ||
| 2184 | int err; | ||
| 2185 | |||
| 2186 | err = tcf_exts_validate_ex(net, tp, tb, est, &f->exts, flags, | ||
| 2187 | fl_flags, extack); | ||
| 2188 | if (err < 0) | ||
| 2189 | return err; | ||
| 2190 | |||
| 2191 | if (tb[TCA_FLOWER_CLASSID]) { | ||
| 2192 | f->res.classid = nla_get_u32(tb[TCA_FLOWER_CLASSID]); | ||
| 2193 | if (flags & TCA_ACT_FLAGS_NO_RTNL) | ||
| 2194 | rtnl_lock(); | ||
| 2195 | tcf_bind_filter(tp, &f->res, base); | ||
| 2196 | if (flags & TCA_ACT_FLAGS_NO_RTNL) | ||
| 2197 | rtnl_unlock(); | ||
| 2198 | } | ||
| 2199 | |||
| 2200 | err = fl_set_key(net, tb, &f->key, &mask->key, extack); | ||
| 2201 | if (err) | ||
| 2202 | return err; | ||
| 2203 | |||
| 2204 | fl_mask_update_range(mask); | ||
| 2205 | fl_set_masked_key(&f->mkey, &f->key, mask); | ||
| 2206 | |||
| 2207 | if (!fl_mask_fits_tmplt(tmplt, mask)) { | ||
| 2208 | NL_SET_ERR_MSG_MOD(extack, "Mask does not fit the template"); | ||
| 2209 | return -EINVAL; | ||
| 2210 | } | ||
| 2211 | |||
| 2212 | /* Enable tc skb extension if filter matches on data extracted from | ||
| 2213 | * this extension. | ||
| 2214 | */ | ||
| 2215 | if (fl_needs_tc_skb_ext(&mask->key)) { | ||
| 2216 | f->needs_tc_skb_ext = 1; | ||
| 2217 | tc_skb_ext_tc_enable(); | ||
| 2218 | } | ||
| 2219 | |||
| 2220 | return 0; | ||
| 2221 | } | ||
| 2222 | |||
| 2223 | static int fl_ht_insert_unique(struct cls_fl_filter *fnew, | 2176 | static int fl_ht_insert_unique(struct cls_fl_filter *fnew, |
| 2224 | struct cls_fl_filter *fold, | 2177 | struct cls_fl_filter *fold, |
| 2225 | bool *in_ht) | 2178 | bool *in_ht) |
| @@ -2251,6 +2204,7 @@ static int fl_change(struct net *net, struct sk_buff *in_skb, · 25 unmodified lines | |||
| 2251 | struct cls_fl_head *head = fl_head_dereference(tp); | 2204 | struct cls_fl_head *head = fl_head_dereference(tp); |
| 2252 | bool rtnl_held = !(flags & TCA_ACT_FLAGS_NO_RTNL); | 2205 | bool rtnl_held = !(flags & TCA_ACT_FLAGS_NO_RTNL); |
| 2253 | struct cls_fl_filter *fold = *arg; | 2206 | struct cls_fl_filter *fold = *arg; |
| 2207 | bool bound_to_filter = false; | ||
| 2254 | struct cls_fl_filter *fnew; | 2208 | struct cls_fl_filter *fnew; |
| 2255 | struct fl_flow_mask *mask; | 2209 | struct fl_flow_mask *mask; |
| 2256 | struct nlattr **tb; | 2210 | struct nlattr **tb; |
| @@ -2335,15 +2289,46 @@ static int fl_change(struct net *net, struct sk_buff *in_skb, · 78 unmodified lines | |||
| 2335 | if (err < 0) | 2289 | if (err < 0) |
| 2336 | goto errout_idr; | 2290 | goto errout_idr; |
| 2337 | 2291 | ||
| 2338 | err = fl_set_parms(net, tp, fnew, mask, base, tb, tca[TCA_RATE], | 2292 | err = tcf_exts_validate_ex(net, tp, tb, tca[TCA_RATE], |
| 2339 | tp->chain->tmplt_priv, flags, fnew->flags, | 2293 | &fnew->exts, flags, fnew->flags, |
| 2340 | extack); | 2294 | extack); |
| 2341 | if (err) | 2295 | if (err < 0) |
| 2342 | goto errout_idr; | 2296 | goto errout_idr; |
| 2343 | 2297 | ||
| 2298 | if (tb[TCA_FLOWER_CLASSID]) { | ||
| 2299 | fnew->res.classid = nla_get_u32(tb[TCA_FLOWER_CLASSID]); | ||
| 2300 | if (flags & TCA_ACT_FLAGS_NO_RTNL) | ||
| 2301 | rtnl_lock(); | ||
| 2302 | tcf_bind_filter(tp, &fnew->res, base); | ||
| 2303 | if (flags & TCA_ACT_FLAGS_NO_RTNL) | ||
| 2304 | rtnl_unlock(); | ||
| 2305 | bound_to_filter = true; | ||
| 2306 | } | ||
| 2307 | |||
| 2308 | err = fl_set_key(net, tb, &fnew->key, &mask->key, extack); | ||
| 2309 | if (err) | ||
| 2310 | goto unbind_filter; | ||
| 2311 | |||
| 2312 | fl_mask_update_range(mask); | ||
| 2313 | fl_set_masked_key(&fnew->mkey, &fnew->key, mask); | ||
| 2314 | |||
| 2315 | if (!fl_mask_fits_tmplt(tp->chain->tmplt_priv, mask)) { | ||
| 2316 | NL_SET_ERR_MSG_MOD(extack, "Mask does not fit the template"); | ||
| 2317 | err = -EINVAL; | ||
| 2318 | goto unbind_filter; | ||
| 2319 | } | ||
| 2320 | |||
| 2321 | /* Enable tc skb extension if filter matches on data extracted from | ||
| 2322 | * this extension. | ||
| 2323 | */ | ||
| 2324 | if (fl_needs_tc_skb_ext(&mask->key)) { | ||
| 2325 | fnew->needs_tc_skb_ext = 1; | ||
| 2326 | tc_skb_ext_tc_enable(); | ||
| 2327 | } | ||
| 2328 | |||
| 2344 | err = fl_check_assign_mask(head, fnew, fold, mask); | 2329 | err = fl_check_assign_mask(head, fnew, fold, mask); |
| 2345 | if (err) | 2330 | if (err) |
| 2346 | goto errout_idr; | 2331 | goto unbind_filter; |
| 2347 | 2332 | ||
| 2348 | err = fl_ht_insert_unique(fnew, fold, &in_ht); | 2333 | err = fl_ht_insert_unique(fnew, fold, &in_ht); |
| 2349 | if (err) | 2334 | if (err) |
| @@ -2434,6 +2419,16 @@ errout_hw: · 84 unmodified lines | |||
| 2434 | fnew->mask->filter_ht_params); | 2419 | fnew->mask->filter_ht_params); |
| 2435 | errout_mask: | 2420 | errout_mask: |
| 2436 | fl_mask_put(head, fnew->mask); | 2421 | fl_mask_put(head, fnew->mask); |
| 2422 | |||
| 2423 | unbind_filter: | ||
| 2424 | if (bound_to_filter) { | ||
| 2425 | if (flags & TCA_ACT_FLAGS_NO_RTNL) | ||
| 2426 | rtnl_lock(); | ||
| 2427 | tcf_unbind_filter(tp, &fnew->res); | ||
| 2428 | if (flags & TCA_ACT_FLAGS_NO_RTNL) | ||
| 2429 | rtnl_unlock(); | ||
| 2430 | } | ||
| 2431 | |||
| 2437 | errout_idr: | 2432 | errout_idr: |
| 2438 | if (!fold) | 2433 | if (!fold) |
| 2439 | idr_remove(&head->handle_idr, fnew->handle); | 2434 | idr_remove(&head->handle_idr, fnew->handle); |
| @@ -159,26 +159,6 @@ static const struct nla_policy mall_policy[TCA_MATCHALL_MAX + 1] = { · 158 unmodified lines | |||
| 159 | [TCA_MATCHALL_FLAGS] = { .type = NLA_U32 }, | 159 | [TCA_MATCHALL_FLAGS] = { .type = NLA_U32 }, |
| 160 | }; | 160 | }; |
| 161 | 161 | ||
| 162 | static int mall_set_parms(struct net *net, struct tcf_proto *tp, | ||
| 163 | struct cls_mall_head *head, | ||
| 164 | unsigned long base, struct nlattr **tb, | ||
| 165 | struct nlattr *est, u32 flags, u32 fl_flags, | ||
| 166 | struct netlink_ext_ack *extack) | ||
| 167 | { | ||
| 168 | int err; | ||
| 169 | |||
| 170 | err = tcf_exts_validate_ex(net, tp, tb, est, &head->exts, flags, | ||
| 171 | fl_flags, extack); | ||
| 172 | if (err < 0) | ||
| 173 | return err; | ||
| 174 | |||
| 175 | if (tb[TCA_MATCHALL_CLASSID]) { | ||
| 176 | head->res.classid = nla_get_u32(tb[TCA_MATCHALL_CLASSID]); | ||
| 177 | tcf_bind_filter(tp, &head->res, base); | ||
| 178 | } | ||
| 179 | return 0; | ||
| 180 | } | ||
| 181 | |||
| 182 | static int mall_change(struct net *net, struct sk_buff *in_skb, | 162 | static int mall_change(struct net *net, struct sk_buff *in_skb, |
| 183 | struct tcf_proto *tp, unsigned long base, | 163 | struct tcf_proto *tp, unsigned long base, |
| 184 | u32 handle, struct nlattr **tca, | 164 | u32 handle, struct nlattr **tca, |
| @@ -187,6 +167,7 @@ static int mall_change(struct net *net, struct sk_buff *in_skb, · 2 unmodified lines | |||
| 187 | { | 167 | { |
| 188 | struct cls_mall_head *head = rtnl_dereference(tp->root); | 168 | struct cls_mall_head *head = rtnl_dereference(tp->root); |
| 189 | struct nlattr *tb[TCA_MATCHALL_MAX + 1]; | 169 | struct nlattr *tb[TCA_MATCHALL_MAX + 1]; |
| 170 | bool bound_to_filter = false; | ||
| 190 | struct cls_mall_head *new; | 171 | struct cls_mall_head *new; |
| 191 | u32 userflags = 0; | 172 | u32 userflags = 0; |
| 192 | int err; | 173 | int err; |
| @@ -226,11 +207,17 @@ static int mall_change(struct net *net, struct sk_buff *in_skb, · 33 unmodified lines | |||
| 226 | goto err_alloc_percpu; | 207 | goto err_alloc_percpu; |
| 227 | } | 208 | } |
| 228 | 209 | ||
| 229 | err = mall_set_parms(net, tp, new, base, tb, tca[TCA_RATE], | 210 | err = tcf_exts_validate_ex(net, tp, tb, tca[TCA_RATE], |
| 230 | flags, new->flags, extack); | 211 | &new->exts, flags, new->flags, extack); |
| 231 | if (err) | 212 | if (err < 0) |
| 232 | goto err_set_parms; | 213 | goto err_set_parms; |
| 233 | 214 | ||
| 215 | if (tb[TCA_MATCHALL_CLASSID]) { | ||
| 216 | new->res.classid = nla_get_u32(tb[TCA_MATCHALL_CLASSID]); | ||
| 217 | tcf_bind_filter(tp, &new->res, base); | ||
| 218 | bound_to_filter = true; | ||
| 219 | } | ||
| 220 | |||
| 234 | if (!tc_skip_hw(new->flags)) { | 221 | if (!tc_skip_hw(new->flags)) { |
| 235 | err = mall_replace_hw_filter(tp, new, (unsigned long)new, | 222 | err = mall_replace_hw_filter(tp, new, (unsigned long)new, |
| 236 | extack); | 223 | extack); |
| @@ -246,6 +233,8 @@ static int mall_change(struct net *net, struct sk_buff *in_skb, · 9 unmodified lines | |||
| 246 | return 0; | 233 | return 0; |
| 247 | 234 | ||
| 248 | err_replace_hw_filter: | 235 | err_replace_hw_filter: |
| 236 | if (bound_to_filter) | ||
| 237 | tcf_unbind_filter(tp, &new->res); | ||
| 249 | err_set_parms: | 238 | err_set_parms: |
| 250 | free_percpu(new->pf); | 239 | free_percpu(new->pf); |
| 251 | err_alloc_percpu: | 240 | err_alloc_percpu: |
| @@ -712,8 +712,23 @@ static const struct nla_policy u32_policy[TCA_U32_MAX + 1] = { · 711 unmodified lines | |||
| 712 | [TCA_U32_FLAGS] = { .type = NLA_U32 }, | 712 | [TCA_U32_FLAGS] = { .type = NLA_U32 }, |
| 713 | }; | 713 | }; |
| 714 | 714 | ||
| 715 | static void u32_unbind_filter(struct tcf_proto *tp, struct tc_u_knode *n, | ||
| 716 | struct nlattr **tb) | ||
| 717 | { | ||
| 718 | if (tb[TCA_U32_CLASSID]) | ||
| 719 | tcf_unbind_filter(tp, &n->res); | ||
| 720 | } | ||
| 721 | |||
| 722 | static void u32_bind_filter(struct tcf_proto *tp, struct tc_u_knode *n, | ||
| 723 | unsigned long base, struct nlattr **tb) | ||
| 724 | { | ||
| 725 | if (tb[TCA_U32_CLASSID]) { | ||
| 726 | n->res.classid = nla_get_u32(tb[TCA_U32_CLASSID]); | ||
| 727 | tcf_bind_filter(tp, &n->res, base); | ||
| 728 | } | ||
| 729 | } | ||
| 730 | |||
| 715 | static int u32_set_parms(struct net *net, struct tcf_proto *tp, | 731 | static int u32_set_parms(struct net *net, struct tcf_proto *tp, |
| 716 | unsigned long base, | ||
| 717 | struct tc_u_knode *n, struct nlattr **tb, | 732 | struct tc_u_knode *n, struct nlattr **tb, |
| 718 | struct nlattr *est, u32 flags, u32 fl_flags, | 733 | struct nlattr *est, u32 flags, u32 fl_flags, |
| 719 | struct netlink_ext_ack *extack) | 734 | struct netlink_ext_ack *extack) |
| @@ -760,10 +775,6 @@ static int u32_set_parms(struct net *net, struct tcf_proto *tp, · 40 unmodified lines | |||
| 760 | if (ht_old) | 775 | if (ht_old) |
| 761 | ht_old->refcnt--; | 776 | ht_old->refcnt--; |
| 762 | } | 777 | } |
| 763 | if (tb[TCA_U32_CLASSID]) { | ||
| 764 | n->res.classid = nla_get_u32(tb[TCA_U32_CLASSID]); | ||
| 765 | tcf_bind_filter(tp, &n->res, base); | ||
| 766 | } | ||
| 767 | 778 | ||
| 768 | if (ifindex >= 0) | 779 | if (ifindex >= 0) |
| 769 | n->ifindex = ifindex; | 780 | n->ifindex = ifindex; |
| @@ -903,17 +914,27 @@ static int u32_change(struct net *net, struct sk_buff *in_skb, · 133 unmodified lines | |||
| 903 | if (!new) | 914 | if (!new) |
| 904 | return -ENOMEM; | 915 | return -ENOMEM; |
| 905 | 916 | ||
| 906 | err = u32_set_parms(net, tp, base, new, tb, | 917 | err = u32_set_parms(net, tp, new, tb, tca[TCA_RATE], |
| 907 | tca[TCA_RATE], flags, new->flags, | 918 | flags, new->flags, extack); |
| 908 | extack); | ||
| 909 | 919 | ||
| 910 | if (err) { | 920 | if (err) { |
| 911 | __u32_destroy_key(new); | 921 | __u32_destroy_key(new); |
| 912 | return err; | 922 | return err; |
| 913 | } | 923 | } |
| 914 | 924 | ||
| 925 | u32_bind_filter(tp, new, base, tb); | ||
| 926 | |||
| 915 | err = u32_replace_hw_knode(tp, new, flags, extack); | 927 | err = u32_replace_hw_knode(tp, new, flags, extack); |
| 916 | if (err) { | 928 | if (err) { |
| 929 | u32_unbind_filter(tp, new, tb); | ||
| 930 | |||
| 931 | if (tb[TCA_U32_LINK]) { | ||
| 932 | struct tc_u_hnode *ht_old; | ||
| 933 | |||
| 934 | ht_old = rtnl_dereference(n->ht_down); | ||
| 935 | if (ht_old) | ||
| 936 | ht_old->refcnt++; | ||
| 937 | } | ||
| 917 | __u32_destroy_key(new); | 938 | __u32_destroy_key(new); |
| 918 | return err; | 939 | return err; |
| 919 | } | 940 | } |
| @@ -1074,15 +1095,18 @@ static int u32_change(struct net *net, struct sk_buff *in_skb, · 154 unmodified lines | |||
| 1074 | } | 1095 | } |
| 1075 | #endif | 1096 | #endif |
| 1076 | 1097 | ||
| 1077 | err = u32_set_parms(net, tp, base, n, tb, tca[TCA_RATE], | 1098 | err = u32_set_parms(net, tp, n, tb, tca[TCA_RATE], |
| 1078 | flags, n->flags, extack); | 1099 | flags, n->flags, extack); |
| 1100 | |||
| 1101 | u32_bind_filter(tp, n, base, tb); | ||
| 1102 | |||
| 1079 | if (err == 0) { | 1103 | if (err == 0) { |
| 1080 | struct tc_u_knode __rcu **ins; | 1104 | struct tc_u_knode __rcu **ins; |
| 1081 | struct tc_u_knode *pins; | 1105 | struct tc_u_knode *pins; |
| 1082 | 1106 | ||
| 1083 | err = u32_replace_hw_knode(tp, n, flags, extack); | 1107 | err = u32_replace_hw_knode(tp, n, flags, extack); |
| 1084 | if (err) | 1108 | if (err) |
| 1085 | goto errhw; | 1109 | goto errunbind; |
| 1086 | 1110 | ||
| 1087 | if (!tc_in_hw(n->flags)) | 1111 | if (!tc_in_hw(n->flags)) |
| 1088 | n->flags |= TCA_CLS_FLAGS_NOT_IN_HW; | 1112 | n->flags |= TCA_CLS_FLAGS_NOT_IN_HW; |
| @@ -1100,7 +1124,9 @@ static int u32_change(struct net *net, struct sk_buff *in_skb, · 11 unmodified lines | |||
| 1100 | return 0; | 1124 | return 0; |
| 1101 | } | 1125 | } |
| 1102 | 1126 | ||
| 1103 | errhw: | 1127 | errunbind: |
| 1128 | u32_unbind_filter(tp, n, tb); | ||
| 1129 | |||
| 1104 | #ifdef CONFIG_CLS_U32_MARK | 1130 | #ifdef CONFIG_CLS_U32_MARK |
| 1105 | free_percpu(n->pcpu_success); | 1131 | free_percpu(n->pcpu_success); |
| 1106 | #endif | 1132 | #endif |
| @@ -22,9 +22,16 @@ static int timer_cb(void *map, int *key, struct bpf_timer *timer) · 21 unmodified lines | |||
| 22 | return buf[69]; | 22 | return buf[69]; |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | __attribute__((noinline)) | ||
| 26 | static int bad_timer_cb(void *map, int *key, struct bpf_timer *timer) | ||
| 27 | { | ||
| 28 | volatile char buf[300] = {}; | ||
| 29 | return buf[255] + timer_cb(NULL, NULL, NULL); | ||
| 30 | } | ||
| 31 | |||
| 25 | SEC("tc") | 32 | SEC("tc") |
| 26 | __failure __msg("combined stack size of 2 calls") | 33 | __failure __msg("combined stack size of 2 calls is 576. Too large") |
| 27 | int prog(struct __sk_buff *ctx) | 34 | int pseudo_call_check(struct __sk_buff *ctx) |
| 28 | { | 35 | { |
| 29 | struct hmap_elem *elem; | 36 | struct hmap_elem *elem; |
| 30 | volatile char buf[256] = {}; | 37 | volatile char buf[256] = {}; |
| @@ -37,4 +44,18 @@ int prog(struct __sk_buff *ctx) · 6 unmodified lines | |||
| 37 | return bpf_timer_set_callback(&elem->timer, timer_cb) + buf[0]; | 44 | return bpf_timer_set_callback(&elem->timer, timer_cb) + buf[0]; |
| 38 | } | 45 | } |
| 39 | 46 | ||
| 47 | SEC("tc") | ||
| 48 | __failure __msg("combined stack size of 2 calls is 608. Too large") | ||
| 49 | int async_call_root_check(struct __sk_buff *ctx) | ||
| 50 | { | ||
| 51 | struct hmap_elem *elem; | ||
| 52 | volatile char buf[256] = {}; | ||
| 53 | |||
| 54 | elem = bpf_map_lookup_elem(&hmap, &(int){0}); | ||
| 55 | if (!elem) | ||
| 56 | return 0; | ||
| 57 | |||
| 58 | return bpf_timer_set_callback(&elem->timer, bad_timer_cb) + buf[0]; | ||
| 59 | } | ||
| 60 | |||
| 40 | char _license[] SEC("license") = "GPL"; | 61 | char _license[] SEC("license") = "GPL"; |
| @@ -5,6 +5,8 @@ CONFIG_NF_CONNTRACK=m · 4 unmodified lines | |||
| 5 | CONFIG_NF_CONNTRACK_MARK=y | 5 | CONFIG_NF_CONNTRACK_MARK=y |
| 6 | CONFIG_NF_CONNTRACK_ZONES=y | 6 | CONFIG_NF_CONNTRACK_ZONES=y |
| 7 | CONFIG_NF_CONNTRACK_LABELS=y | 7 | CONFIG_NF_CONNTRACK_LABELS=y |
| 8 | CONFIG_NF_CONNTRACK_PROCFS=y | ||
| 9 | CONFIG_NF_FLOW_TABLE=m | ||
| 8 | CONFIG_NF_NAT=m | 10 | CONFIG_NF_NAT=m |
| 9 | CONFIG_NETFILTER_XT_TARGET_LOG=m | 11 | CONFIG_NETFILTER_XT_TARGET_LOG=m |
| 10 | 12 | ||
| @@ -0,0 +1 @@ | |||
| 1 | timeout=900 | ||