Networking fixes for 5.10-rc3, including fixes from wireless, can,
and netfilter subtrees. Current release - bugs in new features: - can: isotp: isotp_rcv_cf(): enable RX timeout handling in listen-only mode Previous release - regressions: - mac80211: - don't require VHT elements for HE on 2.4 GHz - fix regression where EAPOL frames were sent in plaintext - netfilter: - ipset: Update byte and packet counters regardless of whether they match - ip_tunnel: fix over-mtu packet send by allowing fragmenting even if inner packet has IP_DF (don't fragment) set in its header (when TUNNEL_DONT_FRAGMENT flag is not set on the tunnel dev) - net: fec: fix MDIO probing for some FEC hardware blocks - ip6_tunnel: set inner ipproto before ip6_tnl_encap to un-break gso support - sctp: Fix COMM_LOST/CANT_STR_ASSOC err reporting on big-endian platforms, sparse-related fix used the wrong integer size Previous release - always broken: - netfilter: use actual socket sk rather than skb sk when routing harder - r8169: work around short packet hw bug on RTL8125 by padding frames - net: ethernet: ti: cpsw: disable PTPv1 hw timestamping advertisement, the hardware does not support it - chelsio/chtls: fix always leaking ctrl_skb and another leak caused by a race condition - fix drivers incorrectly writing into skbs on TX: - cadence: force nonlinear buffers to be cloned - gianfar: Account for Tx PTP timestamp in the skb headroom - gianfar: Replace skb_realloc_headroom with skb_cow_head for PTP - can: flexcan: - remove FLEXCAN_QUIRK_DISABLE_MECR quirk for LS1021A - add ECC initialization for VF610 and LX2160A - flexcan_remove(): disable wakeup completely - can: fix packet echo functionality: - peak_canfd: fix echo management when loopback is on - make sure skbs are not freed in IRQ context in case they need to be dropped - always clone the skbs to make sure they have a reference on the socket, and prevent it from disappearing - fix real payload length return value for RTR frames - can: j1939: return failure on bind if netdev is down, rather than waiting indefinitely Misc: - IPv6: reply ICMP error if the first fragment don't include all headers to improve compliance with RFC 8200 Signed-off-by: Jakub Kicinski <kuba@kernel.org> -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE6jPA+I1ugmIBA4hXMUZtbf5SIrsFAl+kTDcACgkQMUZtbf5S IrtC9A//f9rwNFI7sRaz9FYi6ljtWY7paPxdOxy3pWRoNzbfffjTGSPheNvy1pQb IPaLsNwRrckQNSEPTbQqlUYcjzk1W74ffvq0sQOan4kNKxjX3uf78E6RuWARJsRC dLqfcJctO6bFi6sEMwIFZ2tLOO5lUIA+Pd0GbjhSdObWzl3uqJ26v7wC6vVk29vS 116Mmhe8/TDVtCOzwlZnBPHqBJkTAirB+MAEX4Sp6FB9YirlcNZbWyHX5L6ejGqC WQVjU2tPBBugeo0j72tc+y0mD3iK0aLcPL+dk0EQQYHRDMVTebl+gxNPUXCo9Out HGe5z4e4qrR4Rx1W6MQ3pKwTYuCdwKjMRGd72JAi428/l4NN3y9W/HkI2Zuppd2l 7ifURkNQllYjGCSoHBviJbajyFBeA1nkFJgMSJiRs4T167K3zTbsyjNnfa4LnsvS B3SrYMGqIH+oR20R9EoV8prVX+Alj1hh/jX02J8zsCcHmBqF2yZi17NarVAWoarm v/AAqehlP+D1vjAmbCG9DeborrjaNi+v6zFTKK6ZadvLXRJX/N+wEPIpG4KjiK8W DWKIVlee0R+kgCXE1n9AuZaZLWb7VwrAjkG1Pmfi3vkZhWeAhOW4X98ehhi/hVR/ Gq+e48ZECW5yuOA1q4hbsCYkGr2qAn/LPbsXxhEmW8qwkJHZYkI= =5R2w -----END PGP SIGNATURE----- Merge tag 'net-5.10-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net Pull networking fixes from Jakub Kicinski: "Networking fixes for 5.10-rc3, including fixes from wireless, can, and netfilter subtrees. Current merge window - bugs in new features: - can: isotp: isotp_rcv_cf(): enable RX timeout handling in listen-only mode Previous releases - regressions: - mac80211: - don't require VHT elements for HE on 2.4 GHz - fix regression where EAPOL frames were sent in plaintext - netfilter: - ipset: Update byte and packet counters regardless of whether they match - ip_tunnel: fix over-mtu packet send by allowing fragmenting even if inner packet has IP_DF (don't fragment) set in its header (when TUNNEL_DONT_FRAGMENT flag is not set on the tunnel dev) - net: fec: fix MDIO probing for some FEC hardware blocks - ip6_tunnel: set inner ipproto before ip6_tnl_encap to un-break gso support - sctp: Fix COMM_LOST/CANT_STR_ASSOC err reporting on big-endian platforms, sparse-related fix used the wrong integer size Previous releases - always broken: - netfilter: use actual socket sk rather than skb sk when routing harder - r8169: work around short packet hw bug on RTL8125 by padding frames - net: ethernet: ti: cpsw: disable PTPv1 hw timestamping advertisement, the hardware does not support it - chelsio/chtls: fix always leaking ctrl_skb and another leak caused by a race condition - fix drivers incorrectly writing into skbs on TX: - cadence: force nonlinear buffers to be cloned - gianfar: Account for Tx PTP timestamp in the skb headroom - gianfar: Replace skb_realloc_headroom with skb_cow_head for PTP - can: flexcan: - remove FLEXCAN_QUIRK_DISABLE_MECR quirk for LS1021A - add ECC initialization for VF610 and LX2160A - flexcan_remove(): disable wakeup completely - can: fix packet echo functionality: - peak_canfd: fix echo management when loopback is on - make sure skbs are not freed in IRQ context in case they need to be dropped - always clone the skbs to make sure they have a reference on the socket, and prevent it from disappearing - fix real payload length return value for RTR frames - can: j1939: return failure on bind if netdev is down, rather than waiting indefinitely Misc: - IPv6: reply ICMP error if the first fragment don't include all headers to improve compliance with RFC 8200" * tag 'net-5.10-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (66 commits) ionic: check port ptr before use r8169: work around short packet hw bug on RTL8125 net: openvswitch: silence suspicious RCU usage warning chelsio/chtls: fix always leaking ctrl_skb chelsio/chtls: fix memory leaks caused by a race can: flexcan: flexcan_remove(): disable wakeup completely can: flexcan: add ECC initialization for VF610 can: flexcan: add ECC initialization for LX2160A can: flexcan: remove FLEXCAN_QUIRK_DISABLE_MECR quirk for LS1021A can: mcp251xfd: remove unneeded break can: mcp251xfd: mcp251xfd_regmap_nocrc_read(): fix semicolon.cocci warnings can: mcp251xfd: mcp251xfd_regmap_crc_read(): increase severity of CRC read error messages can: peak_canfd: pucan_handle_can_rx(): fix echo management when loopback is on can: peak_usb: peak_usb_get_ts_time(): fix timestamp wrapping can: peak_usb: add range checking in decode operations can: xilinx_can: handle failure cases of pm_runtime_get_sync can: ti_hecc: ti_hecc_probe(): add missed clk_disable_unprepare() in error path can: isotp: padlen(): make const array static, makes object smaller can: isotp: isotp_rcv_cf(): enable RX timeout handling in listen-only mode can: isotp: Explain PDU in CAN_ISOTP help text ...
This commit is contained in:
commit
41f1653024
|
@ -0,0 +1,18 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/can/can-controller.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: CAN Controller Generic Binding
|
||||
|
||||
maintainers:
|
||||
- Marc Kleine-Budde <mkl@pengutronix.de>
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^can(@.*)?$"
|
||||
|
||||
additionalProperties: true
|
||||
|
||||
...
|
|
@ -0,0 +1,135 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/can/fsl,flexcan.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title:
|
||||
Flexcan CAN controller on Freescale's ARM and PowerPC system-on-a-chip (SOC).
|
||||
|
||||
maintainers:
|
||||
- Marc Kleine-Budde <mkl@pengutronix.de>
|
||||
|
||||
allOf:
|
||||
- $ref: can-controller.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- enum:
|
||||
- fsl,imx8qm-flexcan
|
||||
- fsl,imx8mp-flexcan
|
||||
- fsl,imx6q-flexcan
|
||||
- fsl,imx53-flexcan
|
||||
- fsl,imx35-flexcan
|
||||
- fsl,imx28-flexcan
|
||||
- fsl,imx25-flexcan
|
||||
- fsl,p1010-flexcan
|
||||
- fsl,vf610-flexcan
|
||||
- fsl,ls1021ar2-flexcan
|
||||
- fsl,lx2160ar1-flexcan
|
||||
- items:
|
||||
- enum:
|
||||
- fsl,imx7d-flexcan
|
||||
- fsl,imx6ul-flexcan
|
||||
- fsl,imx6sx-flexcan
|
||||
- const: fsl,imx6q-flexcan
|
||||
- items:
|
||||
- enum:
|
||||
- fsl,ls1028ar1-flexcan
|
||||
- const: fsl,lx2160ar1-flexcan
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 2
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: ipg
|
||||
- const: per
|
||||
|
||||
clock-frequency:
|
||||
description: |
|
||||
The oscillator frequency driving the flexcan device, filled in by the
|
||||
boot loader. This property should only be used the used operating system
|
||||
doesn't support the clocks and clock-names property.
|
||||
|
||||
xceiver-supply:
|
||||
description: Regulator that powers the CAN transceiver.
|
||||
|
||||
big-endian:
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
description: |
|
||||
This means the registers of FlexCAN controller are big endian. This is
|
||||
optional property.i.e. if this property is not present in device tree
|
||||
node then controller is assumed to be little endian. If this property is
|
||||
present then controller is assumed to be big endian.
|
||||
|
||||
fsl,stop-mode:
|
||||
description: |
|
||||
Register bits of stop mode control.
|
||||
|
||||
The format should be as follows:
|
||||
<gpr req_gpr req_bit>
|
||||
gpr is the phandle to general purpose register node.
|
||||
req_gpr is the gpr register offset of CAN stop request.
|
||||
req_bit is the bit offset of CAN stop request.
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
items:
|
||||
- description: The 'gpr' is the phandle to general purpose register node.
|
||||
- description: The 'req_gpr' is the gpr register offset of CAN stop request.
|
||||
maximum: 0xff
|
||||
- description: The 'req_bit' is the bit offset of CAN stop request.
|
||||
maximum: 0x1f
|
||||
|
||||
fsl,clk-source:
|
||||
description: |
|
||||
Select the clock source to the CAN Protocol Engine (PE). It's SoC
|
||||
implementation dependent. Refer to RM for detailed definition. If this
|
||||
property is not set in device tree node then driver selects clock source 1
|
||||
by default.
|
||||
0: clock source 0 (oscillator clock)
|
||||
1: clock source 1 (peripheral clock)
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
default: 1
|
||||
minimum: 0
|
||||
maximum: 1
|
||||
|
||||
wakeup-source:
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
description:
|
||||
Enable CAN remote wakeup.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
can@1c000 {
|
||||
compatible = "fsl,p1010-flexcan";
|
||||
reg = <0x1c000 0x1000>;
|
||||
interrupts = <48 0x2>;
|
||||
interrupt-parent = <&mpic>;
|
||||
clock-frequency = <200000000>;
|
||||
fsl,clk-source = <0>;
|
||||
};
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
can@2090000 {
|
||||
compatible = "fsl,imx6q-flexcan";
|
||||
reg = <0x02090000 0x4000>;
|
||||
interrupts = <0 110 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&clks 1>, <&clks 2>;
|
||||
clock-names = "ipg", "per";
|
||||
fsl,stop-mode = <&gpr 0x34 28>;
|
||||
};
|
|
@ -1,57 +0,0 @@
|
|||
Flexcan CAN controller on Freescale's ARM and PowerPC system-on-a-chip (SOC).
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : Should be "fsl,<processor>-flexcan"
|
||||
|
||||
where <processor> is imx8qm, imx6q, imx28, imx53, imx35, imx25, p1010,
|
||||
vf610, ls1021ar2, lx2160ar1, ls1028ar1.
|
||||
|
||||
The ls1028ar1 must be followed by lx2160ar1, e.g.
|
||||
- "fsl,ls1028ar1-flexcan", "fsl,lx2160ar1-flexcan"
|
||||
|
||||
An implementation should also claim any of the following compatibles
|
||||
that it is fully backwards compatible with:
|
||||
|
||||
- fsl,p1010-flexcan
|
||||
|
||||
- reg : Offset and length of the register set for this device
|
||||
- interrupts : Interrupt tuple for this device
|
||||
|
||||
Optional properties:
|
||||
|
||||
- clock-frequency : The oscillator frequency driving the flexcan device
|
||||
|
||||
- xceiver-supply: Regulator that powers the CAN transceiver
|
||||
|
||||
- big-endian: This means the registers of FlexCAN controller are big endian.
|
||||
This is optional property.i.e. if this property is not present in
|
||||
device tree node then controller is assumed to be little endian.
|
||||
if this property is present then controller is assumed to be big
|
||||
endian.
|
||||
|
||||
- fsl,stop-mode: register bits of stop mode control, the format is
|
||||
<&gpr req_gpr req_bit>.
|
||||
gpr is the phandle to general purpose register node.
|
||||
req_gpr is the gpr register offset of CAN stop request.
|
||||
req_bit is the bit offset of CAN stop request.
|
||||
|
||||
- fsl,clk-source: Select the clock source to the CAN Protocol Engine (PE).
|
||||
It's SoC Implementation dependent. Refer to RM for detailed
|
||||
definition. If this property is not set in device tree node
|
||||
then driver selects clock source 1 by default.
|
||||
0: clock source 0 (oscillator clock)
|
||||
1: clock source 1 (peripheral clock)
|
||||
|
||||
- wakeup-source: enable CAN remote wakeup
|
||||
|
||||
Example:
|
||||
|
||||
can@1c000 {
|
||||
compatible = "fsl,p1010-flexcan";
|
||||
reg = <0x1c000 0x1000>;
|
||||
interrupts = <48 0x2>;
|
||||
interrupt-parent = <&mpic>;
|
||||
clock-frequency = <200000000>; // filled in by bootloader
|
||||
fsl,clk-source = <0>; // select clock source 0 for PE
|
||||
};
|
|
@ -10,9 +10,9 @@ Overview / What Is J1939
|
|||
SAE J1939 defines a higher layer protocol on CAN. It implements a more
|
||||
sophisticated addressing scheme and extends the maximum packet size above 8
|
||||
bytes. Several derived specifications exist, which differ from the original
|
||||
J1939 on the application level, like MilCAN A, NMEA2000 and especially
|
||||
J1939 on the application level, like MilCAN A, NMEA2000, and especially
|
||||
ISO-11783 (ISOBUS). This last one specifies the so-called ETP (Extended
|
||||
Transport Protocol) which is has been included in this implementation. This
|
||||
Transport Protocol), which has been included in this implementation. This
|
||||
results in a maximum packet size of ((2 ^ 24) - 1) * 7 bytes == 111 MiB.
|
||||
|
||||
Specifications used
|
||||
|
@ -32,15 +32,15 @@ sockets, we found some reasons to justify a kernel implementation for the
|
|||
addressing and transport methods used by J1939.
|
||||
|
||||
* **Addressing:** when a process on an ECU communicates via J1939, it should
|
||||
not necessarily know its source address. Although at least one process per
|
||||
not necessarily know its source address. Although, at least one process per
|
||||
ECU should know the source address. Other processes should be able to reuse
|
||||
that address. This way, address parameters for different processes
|
||||
cooperating for the same ECU, are not duplicated. This way of working is
|
||||
closely related to the UNIX concept where programs do just one thing, and do
|
||||
closely related to the UNIX concept, where programs do just one thing and do
|
||||
it well.
|
||||
|
||||
* **Dynamic addressing:** Address Claiming in J1939 is time critical.
|
||||
Furthermore data transport should be handled properly during the address
|
||||
Furthermore, data transport should be handled properly during the address
|
||||
negotiation. Putting this functionality in the kernel eliminates it as a
|
||||
requirement for _every_ user space process that communicates via J1939. This
|
||||
results in a consistent J1939 bus with proper addressing.
|
||||
|
@ -58,7 +58,7 @@ Therefore, these parts are left to user space.
|
|||
|
||||
The J1939 sockets operate on CAN network devices (see SocketCAN). Any J1939
|
||||
user space library operating on CAN raw sockets will still operate properly.
|
||||
Since such library does not communicate with the in-kernel implementation, care
|
||||
Since such a library does not communicate with the in-kernel implementation, care
|
||||
must be taken that these two do not interfere. In practice, this means they
|
||||
cannot share ECU addresses. A single ECU (or virtual ECU) address is used by
|
||||
the library exclusively, or by the in-kernel system exclusively.
|
||||
|
@ -77,13 +77,13 @@ is composed as follows:
|
|||
8 bits : PS (PDU Specific)
|
||||
|
||||
In J1939-21 distinction is made between PDU1 format (where PF < 240) and PDU2
|
||||
format (where PF >= 240). Furthermore, when using PDU2 format, the PS-field
|
||||
format (where PF >= 240). Furthermore, when using the PDU2 format, the PS-field
|
||||
contains a so-called Group Extension, which is part of the PGN. When using PDU2
|
||||
format, the Group Extension is set in the PS-field.
|
||||
|
||||
On the other hand, when using PDU1 format, the PS-field contains a so-called
|
||||
Destination Address, which is _not_ part of the PGN. When communicating a PGN
|
||||
from user space to kernel (or visa versa) and PDU2 format is used, the PS-field
|
||||
from user space to kernel (or vice versa) and PDU2 format is used, the PS-field
|
||||
of the PGN shall be set to zero. The Destination Address shall be set
|
||||
elsewhere.
|
||||
|
||||
|
@ -96,15 +96,15 @@ Addressing
|
|||
|
||||
Both static and dynamic addressing methods can be used.
|
||||
|
||||
For static addresses, no extra checks are made by the kernel, and provided
|
||||
For static addresses, no extra checks are made by the kernel and provided
|
||||
addresses are considered right. This responsibility is for the OEM or system
|
||||
integrator.
|
||||
|
||||
For dynamic addressing, so-called Address Claiming, extra support is foreseen
|
||||
in the kernel. In J1939 any ECU is known by it's 64-bit NAME. At the moment of
|
||||
in the kernel. In J1939 any ECU is known by its 64-bit NAME. At the moment of
|
||||
a successful address claim, the kernel keeps track of both NAME and source
|
||||
address being claimed. This serves as a base for filter schemes. By default,
|
||||
packets with a destination that is not locally, will be rejected.
|
||||
packets with a destination that is not locally will be rejected.
|
||||
|
||||
Mixed mode packets (from a static to a dynamic address or vice versa) are
|
||||
allowed. The BSD sockets define separate API calls for getting/setting the
|
||||
|
@ -131,31 +131,31 @@ API Calls
|
|||
---------
|
||||
|
||||
On CAN, you first need to open a socket for communicating over a CAN network.
|
||||
To use J1939, #include <linux/can/j1939.h>. From there, <linux/can.h> will be
|
||||
To use J1939, ``#include <linux/can/j1939.h>``. From there, ``<linux/can.h>`` will be
|
||||
included too. To open a socket, use:
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
s = socket(PF_CAN, SOCK_DGRAM, CAN_J1939);
|
||||
|
||||
J1939 does use SOCK_DGRAM sockets. In the J1939 specification, connections are
|
||||
J1939 does use ``SOCK_DGRAM`` sockets. In the J1939 specification, connections are
|
||||
mentioned in the context of transport protocol sessions. These still deliver
|
||||
packets to the other end (using several CAN packets). SOCK_STREAM is not
|
||||
packets to the other end (using several CAN packets). ``SOCK_STREAM`` is not
|
||||
supported.
|
||||
|
||||
After the successful creation of the socket, you would normally use the bind(2)
|
||||
and/or connect(2) system call to bind the socket to a CAN interface. After
|
||||
binding and/or connecting the socket, you can read(2) and write(2) from/to the
|
||||
socket or use send(2), sendto(2), sendmsg(2) and the recv*() counterpart
|
||||
After the successful creation of the socket, you would normally use the ``bind(2)``
|
||||
and/or ``connect(2)`` system call to bind the socket to a CAN interface. After
|
||||
binding and/or connecting the socket, you can ``read(2)`` and ``write(2)`` from/to the
|
||||
socket or use ``send(2)``, ``sendto(2)``, ``sendmsg(2)`` and the ``recv*()`` counterpart
|
||||
operations on the socket as usual. There are also J1939 specific socket options
|
||||
described below.
|
||||
|
||||
In order to send data, a bind(2) must have been successful. bind(2) assigns a
|
||||
In order to send data, a ``bind(2)`` must have been successful. ``bind(2)`` assigns a
|
||||
local address to a socket.
|
||||
|
||||
Different from CAN is that the payload data is just the data that get send,
|
||||
without it's header info. The header info is derived from the sockaddr supplied
|
||||
to bind(2), connect(2), sendto(2) and recvfrom(2). A write(2) with size 4 will
|
||||
Different from CAN is that the payload data is just the data that get sends,
|
||||
without its header info. The header info is derived from the sockaddr supplied
|
||||
to ``bind(2)``, ``connect(2)``, ``sendto(2)`` and ``recvfrom(2)``. A ``write(2)`` with size 4 will
|
||||
result in a packet with 4 bytes.
|
||||
|
||||
The sockaddr structure has extensions for use with J1939 as specified below:
|
||||
|
@ -180,47 +180,47 @@ The sockaddr structure has extensions for use with J1939 as specified below:
|
|||
} can_addr;
|
||||
}
|
||||
|
||||
can_family & can_ifindex serve the same purpose as for other SocketCAN sockets.
|
||||
``can_family`` & ``can_ifindex`` serve the same purpose as for other SocketCAN sockets.
|
||||
|
||||
can_addr.j1939.pgn specifies the PGN (max 0x3ffff). Individual bits are
|
||||
``can_addr.j1939.pgn`` specifies the PGN (max 0x3ffff). Individual bits are
|
||||
specified above.
|
||||
|
||||
can_addr.j1939.name contains the 64-bit J1939 NAME.
|
||||
``can_addr.j1939.name`` contains the 64-bit J1939 NAME.
|
||||
|
||||
can_addr.j1939.addr contains the address.
|
||||
``can_addr.j1939.addr`` contains the address.
|
||||
|
||||
The bind(2) system call assigns the local address, i.e. the source address when
|
||||
sending packages. If a PGN during bind(2) is set, it's used as a RX filter.
|
||||
I.e. only packets with a matching PGN are received. If an ADDR or NAME is set
|
||||
The ``bind(2)`` system call assigns the local address, i.e. the source address when
|
||||
sending packages. If a PGN during ``bind(2)`` is set, it's used as a RX filter.
|
||||
I.e. only packets with a matching PGN are received. If an ADDR or NAME is set
|
||||
it is used as a receive filter, too. It will match the destination NAME or ADDR
|
||||
of the incoming packet. The NAME filter will work only if appropriate Address
|
||||
Claiming for this name was done on the CAN bus and registered/cached by the
|
||||
kernel.
|
||||
|
||||
On the other hand connect(2) assigns the remote address, i.e. the destination
|
||||
address. The PGN from connect(2) is used as the default PGN when sending
|
||||
On the other hand ``connect(2)`` assigns the remote address, i.e. the destination
|
||||
address. The PGN from ``connect(2)`` is used as the default PGN when sending
|
||||
packets. If ADDR or NAME is set it will be used as the default destination ADDR
|
||||
or NAME. Further a set ADDR or NAME during connect(2) is used as a receive
|
||||
or NAME. Further a set ADDR or NAME during ``connect(2)`` is used as a receive
|
||||
filter. It will match the source NAME or ADDR of the incoming packet.
|
||||
|
||||
Both write(2) and send(2) will send a packet with local address from bind(2) and
|
||||
the remote address from connect(2). Use sendto(2) to overwrite the destination
|
||||
Both ``write(2)`` and ``send(2)`` will send a packet with local address from ``bind(2)`` and the
|
||||
remote address from ``connect(2)``. Use ``sendto(2)`` to overwrite the destination
|
||||
address.
|
||||
|
||||
If can_addr.j1939.name is set (!= 0) the NAME is looked up by the kernel and
|
||||
the corresponding ADDR is used. If can_addr.j1939.name is not set (== 0),
|
||||
can_addr.j1939.addr is used.
|
||||
If ``can_addr.j1939.name`` is set (!= 0) the NAME is looked up by the kernel and
|
||||
the corresponding ADDR is used. If ``can_addr.j1939.name`` is not set (== 0),
|
||||
``can_addr.j1939.addr`` is used.
|
||||
|
||||
When creating a socket, reasonable defaults are set. Some options can be
|
||||
modified with setsockopt(2) & getsockopt(2).
|
||||
modified with ``setsockopt(2)`` & ``getsockopt(2)``.
|
||||
|
||||
RX path related options:
|
||||
|
||||
- SO_J1939_FILTER - configure array of filters
|
||||
- SO_J1939_PROMISC - disable filters set by bind(2) and connect(2)
|
||||
- ``SO_J1939_FILTER`` - configure array of filters
|
||||
- ``SO_J1939_PROMISC`` - disable filters set by ``bind(2)`` and ``connect(2)``
|
||||
|
||||
By default no broadcast packets can be send or received. To enable sending or
|
||||
receiving broadcast packets use the socket option SO_BROADCAST:
|
||||
receiving broadcast packets use the socket option ``SO_BROADCAST``:
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
|
@ -261,26 +261,26 @@ The following diagram illustrates the RX path:
|
|||
+---------------------------+
|
||||
|
||||
TX path related options:
|
||||
SO_J1939_SEND_PRIO - change default send priority for the socket
|
||||
``SO_J1939_SEND_PRIO`` - change default send priority for the socket
|
||||
|
||||
Message Flags during send() and Related System Calls
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
send(2), sendto(2) and sendmsg(2) take a 'flags' argument. Currently
|
||||
``send(2)``, ``sendto(2)`` and ``sendmsg(2)`` take a 'flags' argument. Currently
|
||||
supported flags are:
|
||||
|
||||
* MSG_DONTWAIT, i.e. non-blocking operation.
|
||||
* ``MSG_DONTWAIT``, i.e. non-blocking operation.
|
||||
|
||||
recvmsg(2)
|
||||
^^^^^^^^^^
|
||||
|
||||
In most cases recvmsg(2) is needed if you want to extract more information than
|
||||
recvfrom(2) can provide. For example package priority and timestamp. The
|
||||
In most cases ``recvmsg(2)`` is needed if you want to extract more information than
|
||||
``recvfrom(2)`` can provide. For example package priority and timestamp. The
|
||||
Destination Address, name and packet priority (if applicable) are attached to
|
||||
the msghdr in the recvmsg(2) call. They can be extracted using cmsg(3) macros,
|
||||
with cmsg_level == SOL_J1939 && cmsg_type == SCM_J1939_DEST_ADDR,
|
||||
SCM_J1939_DEST_NAME or SCM_J1939_PRIO. The returned data is a uint8_t for
|
||||
priority and dst_addr, and uint64_t for dst_name.
|
||||
the msghdr in the ``recvmsg(2)`` call. They can be extracted using ``cmsg(3)`` macros,
|
||||
with ``cmsg_level == SOL_J1939 && cmsg_type == SCM_J1939_DEST_ADDR``,
|
||||
``SCM_J1939_DEST_NAME`` or ``SCM_J1939_PRIO``. The returned data is a ``uint8_t`` for
|
||||
``priority`` and ``dst_addr``, and ``uint64_t`` for ``dst_name``.
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
|
@ -305,12 +305,12 @@ Dynamic Addressing
|
|||
|
||||
Distinction has to be made between using the claimed address and doing an
|
||||
address claim. To use an already claimed address, one has to fill in the
|
||||
j1939.name member and provide it to bind(2). If the name had claimed an address
|
||||
``j1939.name`` member and provide it to ``bind(2)``. If the name had claimed an address
|
||||
earlier, all further messages being sent will use that address. And the
|
||||
j1939.addr member will be ignored.
|
||||
``j1939.addr`` member will be ignored.
|
||||
|
||||
An exception on this is PGN 0x0ee00. This is the "Address Claim/Cannot Claim
|
||||
Address" message and the kernel will use the j1939.addr member for that PGN if
|
||||
Address" message and the kernel will use the ``j1939.addr`` member for that PGN if
|
||||
necessary.
|
||||
|
||||
To claim an address following code example can be used:
|
||||
|
@ -371,12 +371,12 @@ NAME can send packets.
|
|||
|
||||
If another ECU claims the address, the kernel will mark the NAME-SA expired.
|
||||
No socket bound to the NAME can send packets (other than address claims). To
|
||||
claim another address, some socket bound to NAME, must bind(2) again, but with
|
||||
only j1939.addr changed to the new SA, and must then send a valid address claim
|
||||
claim another address, some socket bound to NAME, must ``bind(2)`` again, but with
|
||||
only ``j1939.addr`` changed to the new SA, and must then send a valid address claim
|
||||
packet. This restarts the state machine in the kernel (and any other
|
||||
participant on the bus) for this NAME.
|
||||
|
||||
can-utils also include the jacd tool, so it can be used as code example or as
|
||||
``can-utils`` also include the ``j1939acd`` tool, so it can be used as code example or as
|
||||
default Address Claiming daemon.
|
||||
|
||||
Send Examples
|
||||
|
@ -403,8 +403,8 @@ Bind:
|
|||
|
||||
bind(sock, (struct sockaddr *)&baddr, sizeof(baddr));
|
||||
|
||||
Now, the socket 'sock' is bound to the SA 0x20. Since no connect(2) was called,
|
||||
at this point we can use only sendto(2) or sendmsg(2).
|
||||
Now, the socket 'sock' is bound to the SA 0x20. Since no ``connect(2)`` was called,
|
||||
at this point we can use only ``sendto(2)`` or ``sendmsg(2)``.
|
||||
|
||||
Send:
|
||||
|
||||
|
@ -414,8 +414,8 @@ Send:
|
|||
.can_family = AF_CAN,
|
||||
.can_addr.j1939 = {
|
||||
.name = J1939_NO_NAME;
|
||||
.pgn = 0x30,
|
||||
.addr = 0x12300,
|
||||
.addr = 0x30,
|
||||
.pgn = 0x12300,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -512,9 +512,13 @@ __can_get_echo_skb(struct net_device *dev, unsigned int idx, u8 *len_ptr)
|
|||
*/
|
||||
struct sk_buff *skb = priv->echo_skb[idx];
|
||||
struct canfd_frame *cf = (struct canfd_frame *)skb->data;
|
||||
u8 len = cf->len;
|
||||
|
||||
*len_ptr = len;
|
||||
/* get the real payload length for netdev statistics */
|
||||
if (cf->can_id & CAN_RTR_FLAG)
|
||||
*len_ptr = 0;
|
||||
else
|
||||
*len_ptr = cf->len;
|
||||
|
||||
priv->echo_skb[idx] = NULL;
|
||||
|
||||
return skb;
|
||||
|
@ -538,7 +542,11 @@ unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx)
|
|||
if (!skb)
|
||||
return 0;
|
||||
|
||||
netif_rx(skb);
|
||||
skb_get(skb);
|
||||
if (netif_rx(skb) == NET_RX_SUCCESS)
|
||||
dev_consume_skb_any(skb);
|
||||
else
|
||||
dev_kfree_skb_any(skb);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
|
|
@ -217,7 +217,7 @@
|
|||
* MX8MP FlexCAN3 03.00.17.01 yes yes no yes yes yes
|
||||
* VF610 FlexCAN3 ? no yes no yes yes? no
|
||||
* LS1021A FlexCAN2 03.00.04.00 no yes no no yes no
|
||||
* LX2160A FlexCAN3 03.00.23.00 no yes no no yes yes
|
||||
* LX2160A FlexCAN3 03.00.23.00 no yes no yes yes yes
|
||||
*
|
||||
* Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected.
|
||||
*/
|
||||
|
@ -400,19 +400,19 @@ static struct flexcan_devtype_data fsl_imx8mp_devtype_data = {
|
|||
static const struct flexcan_devtype_data fsl_vf610_devtype_data = {
|
||||
.quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS |
|
||||
FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_USE_OFF_TIMESTAMP |
|
||||
FLEXCAN_QUIRK_BROKEN_PERR_STATE,
|
||||
FLEXCAN_QUIRK_BROKEN_PERR_STATE | FLEXCAN_QUIRK_SUPPORT_ECC,
|
||||
};
|
||||
|
||||
static const struct flexcan_devtype_data fsl_ls1021a_r2_devtype_data = {
|
||||
.quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS |
|
||||
FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_BROKEN_PERR_STATE |
|
||||
FLEXCAN_QUIRK_USE_OFF_TIMESTAMP,
|
||||
FLEXCAN_QUIRK_BROKEN_PERR_STATE | FLEXCAN_QUIRK_USE_OFF_TIMESTAMP,
|
||||
};
|
||||
|
||||
static const struct flexcan_devtype_data fsl_lx2160a_r1_devtype_data = {
|
||||
.quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS |
|
||||
FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_BROKEN_PERR_STATE |
|
||||
FLEXCAN_QUIRK_USE_OFF_TIMESTAMP | FLEXCAN_QUIRK_SUPPORT_FD,
|
||||
FLEXCAN_QUIRK_USE_OFF_TIMESTAMP | FLEXCAN_QUIRK_SUPPORT_FD |
|
||||
FLEXCAN_QUIRK_SUPPORT_ECC,
|
||||
};
|
||||
|
||||
static const struct can_bittiming_const flexcan_bittiming_const = {
|
||||
|
@ -2062,6 +2062,8 @@ static int flexcan_remove(struct platform_device *pdev)
|
|||
{
|
||||
struct net_device *dev = platform_get_drvdata(pdev);
|
||||
|
||||
device_set_wakeup_enable(&pdev->dev, false);
|
||||
device_set_wakeup_capable(&pdev->dev, false);
|
||||
unregister_flexcandev(dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
free_candev(dev);
|
||||
|
|
|
@ -262,8 +262,7 @@ static int pucan_handle_can_rx(struct peak_canfd_priv *priv,
|
|||
cf_len = get_can_dlc(pucan_msg_get_dlc(msg));
|
||||
|
||||
/* if this frame is an echo, */
|
||||
if ((rx_msg_flags & PUCAN_MSG_LOOPED_BACK) &&
|
||||
!(rx_msg_flags & PUCAN_MSG_SELF_RECEIVE)) {
|
||||
if (rx_msg_flags & PUCAN_MSG_LOOPED_BACK) {
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&priv->echo_lock, flags);
|
||||
|
@ -277,7 +276,13 @@ static int pucan_handle_can_rx(struct peak_canfd_priv *priv,
|
|||
netif_wake_queue(priv->ndev);
|
||||
|
||||
spin_unlock_irqrestore(&priv->echo_lock, flags);
|
||||
return 0;
|
||||
|
||||
/* if this frame is only an echo, stop here. Otherwise,
|
||||
* continue to push this application self-received frame into
|
||||
* its own rx queue.
|
||||
*/
|
||||
if (!(rx_msg_flags & PUCAN_MSG_SELF_RECEIVE))
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* otherwise, it should be pushed into rx fifo */
|
||||
|
|
|
@ -245,7 +245,7 @@ int can_rx_offload_queue_sorted(struct can_rx_offload *offload,
|
|||
|
||||
if (skb_queue_len(&offload->skb_queue) >
|
||||
offload->skb_queue_len_max) {
|
||||
kfree_skb(skb);
|
||||
dev_kfree_skb_any(skb);
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
|
@ -290,7 +290,7 @@ int can_rx_offload_queue_tail(struct can_rx_offload *offload,
|
|||
{
|
||||
if (skb_queue_len(&offload->skb_queue) >
|
||||
offload->skb_queue_len_max) {
|
||||
kfree_skb(skb);
|
||||
dev_kfree_skb_any(skb);
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
|
|
|
@ -75,11 +75,11 @@ static const char *__mcp251xfd_get_model_str(enum mcp251xfd_model model)
|
|||
{
|
||||
switch (model) {
|
||||
case MCP251XFD_MODEL_MCP2517FD:
|
||||
return "MCP2517FD"; break;
|
||||
return "MCP2517FD";
|
||||
case MCP251XFD_MODEL_MCP2518FD:
|
||||
return "MCP2518FD"; break;
|
||||
return "MCP2518FD";
|
||||
case MCP251XFD_MODEL_MCP251XFD:
|
||||
return "MCP251xFD"; break;
|
||||
return "MCP251xFD";
|
||||
}
|
||||
|
||||
return "<unknown>";
|
||||
|
@ -95,21 +95,21 @@ static const char *mcp251xfd_get_mode_str(const u8 mode)
|
|||
{
|
||||
switch (mode) {
|
||||
case MCP251XFD_REG_CON_MODE_MIXED:
|
||||
return "Mixed (CAN FD/CAN 2.0)"; break;
|
||||
return "Mixed (CAN FD/CAN 2.0)";
|
||||
case MCP251XFD_REG_CON_MODE_SLEEP:
|
||||
return "Sleep"; break;
|
||||
return "Sleep";
|
||||
case MCP251XFD_REG_CON_MODE_INT_LOOPBACK:
|
||||
return "Internal Loopback"; break;
|
||||
return "Internal Loopback";
|
||||
case MCP251XFD_REG_CON_MODE_LISTENONLY:
|
||||
return "Listen Only"; break;
|
||||
return "Listen Only";
|
||||
case MCP251XFD_REG_CON_MODE_CONFIG:
|
||||
return "Configuration"; break;
|
||||
return "Configuration";
|
||||
case MCP251XFD_REG_CON_MODE_EXT_LOOPBACK:
|
||||
return "External Loopback"; break;
|
||||
return "External Loopback";
|
||||
case MCP251XFD_REG_CON_MODE_CAN2_0:
|
||||
return "CAN 2.0"; break;
|
||||
return "CAN 2.0";
|
||||
case MCP251XFD_REG_CON_MODE_RESTRICTED:
|
||||
return "Restricted Operation"; break;
|
||||
return "Restricted Operation";
|
||||
}
|
||||
|
||||
return "<unknown>";
|
||||
|
|
|
@ -173,7 +173,7 @@ mcp251xfd_regmap_nocrc_read(void *context,
|
|||
memcpy(&buf_tx->cmd, reg, sizeof(buf_tx->cmd));
|
||||
if (MCP251XFD_SANITIZE_SPI)
|
||||
memset(buf_tx->data, 0x0, val_len);
|
||||
};
|
||||
}
|
||||
|
||||
err = spi_sync(spi, &msg);
|
||||
if (err)
|
||||
|
@ -330,17 +330,17 @@ mcp251xfd_regmap_crc_read(void *context,
|
|||
goto out;
|
||||
}
|
||||
|
||||
netdev_dbg(priv->ndev,
|
||||
"CRC read error at address 0x%04x (length=%zd, data=%*ph, CRC=0x%04x) retrying.\n",
|
||||
reg, val_len, (int)val_len, buf_rx->data,
|
||||
get_unaligned_be16(buf_rx->data + val_len));
|
||||
netdev_info(priv->ndev,
|
||||
"CRC read error at address 0x%04x (length=%zd, data=%*ph, CRC=0x%04x) retrying.\n",
|
||||
reg, val_len, (int)val_len, buf_rx->data,
|
||||
get_unaligned_be16(buf_rx->data + val_len));
|
||||
}
|
||||
|
||||
if (err) {
|
||||
netdev_info(priv->ndev,
|
||||
"CRC read error at address 0x%04x (length=%zd, data=%*ph, CRC=0x%04x).\n",
|
||||
reg, val_len, (int)val_len, buf_rx->data,
|
||||
get_unaligned_be16(buf_rx->data + val_len));
|
||||
netdev_err(priv->ndev,
|
||||
"CRC read error at address 0x%04x (length=%zd, data=%*ph, CRC=0x%04x).\n",
|
||||
reg, val_len, (int)val_len, buf_rx->data,
|
||||
get_unaligned_be16(buf_rx->data + val_len));
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -933,7 +933,7 @@ static int ti_hecc_probe(struct platform_device *pdev)
|
|||
err = clk_prepare_enable(priv->clk);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "clk_prepare_enable() failed\n");
|
||||
goto probe_exit_clk;
|
||||
goto probe_exit_release_clk;
|
||||
}
|
||||
|
||||
priv->offload.mailbox_read = ti_hecc_mailbox_read;
|
||||
|
@ -942,7 +942,7 @@ static int ti_hecc_probe(struct platform_device *pdev)
|
|||
err = can_rx_offload_add_timestamp(ndev, &priv->offload);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "can_rx_offload_add_timestamp() failed\n");
|
||||
goto probe_exit_clk;
|
||||
goto probe_exit_disable_clk;
|
||||
}
|
||||
|
||||
err = register_candev(ndev);
|
||||
|
@ -960,7 +960,9 @@ static int ti_hecc_probe(struct platform_device *pdev)
|
|||
|
||||
probe_exit_offload:
|
||||
can_rx_offload_del(&priv->offload);
|
||||
probe_exit_clk:
|
||||
probe_exit_disable_clk:
|
||||
clk_disable_unprepare(priv->clk);
|
||||
probe_exit_release_clk:
|
||||
clk_put(priv->clk);
|
||||
probe_exit_candev:
|
||||
free_candev(ndev);
|
||||
|
|
|
@ -130,14 +130,55 @@ void peak_usb_get_ts_time(struct peak_time_ref *time_ref, u32 ts, ktime_t *time)
|
|||
/* protect from getting time before setting now */
|
||||
if (ktime_to_ns(time_ref->tv_host)) {
|
||||
u64 delta_us;
|
||||
s64 delta_ts = 0;
|
||||
|
||||
delta_us = ts - time_ref->ts_dev_2;
|
||||
if (ts < time_ref->ts_dev_2)
|
||||
delta_us &= (1 << time_ref->adapter->ts_used_bits) - 1;
|
||||
/* General case: dev_ts_1 < dev_ts_2 < ts, with:
|
||||
*
|
||||
* - dev_ts_1 = previous sync timestamp
|
||||
* - dev_ts_2 = last sync timestamp
|
||||
* - ts = event timestamp
|
||||
* - ts_period = known sync period (theoretical)
|
||||
* ~ dev_ts2 - dev_ts1
|
||||
* *but*:
|
||||
*
|
||||
* - time counters wrap (see adapter->ts_used_bits)
|
||||
* - sometimes, dev_ts_1 < ts < dev_ts2
|
||||
*
|
||||
* "normal" case (sync time counters increase):
|
||||
* must take into account case when ts wraps (tsw)
|
||||
*
|
||||
* < ts_period > < >
|
||||
* | | |
|
||||
* ---+--------+----+-------0-+--+-->
|
||||
* ts_dev_1 | ts_dev_2 |
|
||||
* ts tsw
|
||||
*/
|
||||
if (time_ref->ts_dev_1 < time_ref->ts_dev_2) {
|
||||
/* case when event time (tsw) wraps */
|
||||
if (ts < time_ref->ts_dev_1)
|
||||
delta_ts = 1 << time_ref->adapter->ts_used_bits;
|
||||
|
||||
delta_us += time_ref->ts_total;
|
||||
/* Otherwise, sync time counter (ts_dev_2) has wrapped:
|
||||
* handle case when event time (tsn) hasn't.
|
||||
*
|
||||
* < ts_period > < >
|
||||
* | | |
|
||||
* ---+--------+--0-+---------+--+-->
|
||||
* ts_dev_1 | ts_dev_2 |
|
||||
* tsn ts
|
||||
*/
|
||||
} else if (time_ref->ts_dev_1 < ts) {
|
||||
delta_ts = -(1 << time_ref->adapter->ts_used_bits);
|
||||
}
|
||||
|
||||
delta_us *= time_ref->adapter->us_per_ts_scale;
|
||||
/* add delay between last sync and event timestamps */
|
||||
delta_ts += (signed int)(ts - time_ref->ts_dev_2);
|
||||
|
||||
/* add time from beginning to last sync */
|
||||
delta_ts += time_ref->ts_total;
|
||||
|
||||
/* convert ticks number into microseconds */
|
||||
delta_us = delta_ts * time_ref->adapter->us_per_ts_scale;
|
||||
delta_us >>= time_ref->adapter->us_per_ts_shift;
|
||||
|
||||
*time = ktime_add_us(time_ref->tv_host_0, delta_us);
|
||||
|
|
|
@ -468,12 +468,18 @@ static int pcan_usb_fd_decode_canmsg(struct pcan_usb_fd_if *usb_if,
|
|||
struct pucan_msg *rx_msg)
|
||||
{
|
||||
struct pucan_rx_msg *rm = (struct pucan_rx_msg *)rx_msg;
|
||||
struct peak_usb_device *dev = usb_if->dev[pucan_msg_get_channel(rm)];
|
||||
struct net_device *netdev = dev->netdev;
|
||||
struct peak_usb_device *dev;
|
||||
struct net_device *netdev;
|
||||
struct canfd_frame *cfd;
|
||||
struct sk_buff *skb;
|
||||
const u16 rx_msg_flags = le16_to_cpu(rm->flags);
|
||||
|
||||
if (pucan_msg_get_channel(rm) >= ARRAY_SIZE(usb_if->dev))
|
||||
return -ENOMEM;
|
||||
|
||||
dev = usb_if->dev[pucan_msg_get_channel(rm)];
|
||||
netdev = dev->netdev;
|
||||
|
||||
if (rx_msg_flags & PUCAN_MSG_EXT_DATA_LEN) {
|
||||
/* CANFD frame case */
|
||||
skb = alloc_canfd_skb(netdev, &cfd);
|
||||
|
@ -519,15 +525,21 @@ static int pcan_usb_fd_decode_status(struct pcan_usb_fd_if *usb_if,
|
|||
struct pucan_msg *rx_msg)
|
||||
{
|
||||
struct pucan_status_msg *sm = (struct pucan_status_msg *)rx_msg;
|
||||
struct peak_usb_device *dev = usb_if->dev[pucan_stmsg_get_channel(sm)];
|
||||
struct pcan_usb_fd_device *pdev =
|
||||
container_of(dev, struct pcan_usb_fd_device, dev);
|
||||
struct pcan_usb_fd_device *pdev;
|
||||
enum can_state new_state = CAN_STATE_ERROR_ACTIVE;
|
||||
enum can_state rx_state, tx_state;
|
||||
struct net_device *netdev = dev->netdev;
|
||||
struct peak_usb_device *dev;
|
||||
struct net_device *netdev;
|
||||
struct can_frame *cf;
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (pucan_stmsg_get_channel(sm) >= ARRAY_SIZE(usb_if->dev))
|
||||
return -ENOMEM;
|
||||
|
||||
dev = usb_if->dev[pucan_stmsg_get_channel(sm)];
|
||||
pdev = container_of(dev, struct pcan_usb_fd_device, dev);
|
||||
netdev = dev->netdev;
|
||||
|
||||
/* nothing should be sent while in BUS_OFF state */
|
||||
if (dev->can.state == CAN_STATE_BUS_OFF)
|
||||
return 0;
|
||||
|
@ -579,9 +591,14 @@ static int pcan_usb_fd_decode_error(struct pcan_usb_fd_if *usb_if,
|
|||
struct pucan_msg *rx_msg)
|
||||
{
|
||||
struct pucan_error_msg *er = (struct pucan_error_msg *)rx_msg;
|
||||
struct peak_usb_device *dev = usb_if->dev[pucan_ermsg_get_channel(er)];
|
||||
struct pcan_usb_fd_device *pdev =
|
||||
container_of(dev, struct pcan_usb_fd_device, dev);
|
||||
struct pcan_usb_fd_device *pdev;
|
||||
struct peak_usb_device *dev;
|
||||
|
||||
if (pucan_ermsg_get_channel(er) >= ARRAY_SIZE(usb_if->dev))
|
||||
return -EINVAL;
|
||||
|
||||
dev = usb_if->dev[pucan_ermsg_get_channel(er)];
|
||||
pdev = container_of(dev, struct pcan_usb_fd_device, dev);
|
||||
|
||||
/* keep a trace of tx and rx error counters for later use */
|
||||
pdev->bec.txerr = er->tx_err_cnt;
|
||||
|
@ -595,11 +612,17 @@ static int pcan_usb_fd_decode_overrun(struct pcan_usb_fd_if *usb_if,
|
|||
struct pucan_msg *rx_msg)
|
||||
{
|
||||
struct pcan_ufd_ovr_msg *ov = (struct pcan_ufd_ovr_msg *)rx_msg;
|
||||
struct peak_usb_device *dev = usb_if->dev[pufd_omsg_get_channel(ov)];
|
||||
struct net_device *netdev = dev->netdev;
|
||||
struct peak_usb_device *dev;
|
||||
struct net_device *netdev;
|
||||
struct can_frame *cf;
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (pufd_omsg_get_channel(ov) >= ARRAY_SIZE(usb_if->dev))
|
||||
return -EINVAL;
|
||||
|
||||
dev = usb_if->dev[pufd_omsg_get_channel(ov)];
|
||||
netdev = dev->netdev;
|
||||
|
||||
/* allocate an skb to store the error frame */
|
||||
skb = alloc_can_err_skb(netdev, &cf);
|
||||
if (!skb)
|
||||
|
@ -716,6 +739,9 @@ static int pcan_usb_fd_encode_msg(struct peak_usb_device *dev,
|
|||
u16 tx_msg_size, tx_msg_flags;
|
||||
u8 can_dlc;
|
||||
|
||||
if (cfd->len > CANFD_MAX_DLEN)
|
||||
return -EINVAL;
|
||||
|
||||
tx_msg_size = ALIGN(sizeof(struct pucan_tx_msg) + cfd->len, 4);
|
||||
tx_msg->size = cpu_to_le16(tx_msg_size);
|
||||
tx_msg->type = cpu_to_le16(PUCAN_MSG_CAN_TX);
|
||||
|
|
|
@ -1395,7 +1395,7 @@ static int xcan_open(struct net_device *ndev)
|
|||
if (ret < 0) {
|
||||
netdev_err(ndev, "%s: pm_runtime_get failed(%d)\n",
|
||||
__func__, ret);
|
||||
return ret;
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = request_irq(ndev->irq, xcan_interrupt, priv->irq_flags,
|
||||
|
@ -1479,6 +1479,7 @@ static int xcan_get_berr_counter(const struct net_device *ndev,
|
|||
if (ret < 0) {
|
||||
netdev_err(ndev, "%s: pm_runtime_get failed(%d)\n",
|
||||
__func__, ret);
|
||||
pm_runtime_put(priv->dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1793,7 +1794,7 @@ static int xcan_probe(struct platform_device *pdev)
|
|||
if (ret < 0) {
|
||||
netdev_err(ndev, "%s: pm_runtime_get failed(%d)\n",
|
||||
__func__, ret);
|
||||
goto err_pmdisable;
|
||||
goto err_disableclks;
|
||||
}
|
||||
|
||||
if (priv->read_reg(priv, XCAN_SR_OFFSET) != XCAN_SR_CONFIG_MASK) {
|
||||
|
@ -1828,7 +1829,6 @@ static int xcan_probe(struct platform_device *pdev)
|
|||
|
||||
err_disableclks:
|
||||
pm_runtime_put(priv->dev);
|
||||
err_pmdisable:
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
err_free:
|
||||
free_candev(ndev);
|
||||
|
|
|
@ -1219,8 +1219,8 @@ qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
|
|||
priv->port_mtu[port] = new_mtu;
|
||||
|
||||
for (i = 0; i < QCA8K_NUM_PORTS; i++)
|
||||
if (priv->port_mtu[port] > mtu)
|
||||
mtu = priv->port_mtu[port];
|
||||
if (priv->port_mtu[i] > mtu)
|
||||
mtu = priv->port_mtu[i];
|
||||
|
||||
/* Include L2 header / FCS length */
|
||||
qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, mtu + ETH_HLEN + ETH_FCS_LEN);
|
||||
|
|
|
@ -1929,7 +1929,8 @@ static inline int macb_clear_csum(struct sk_buff *skb)
|
|||
|
||||
static int macb_pad_and_fcs(struct sk_buff **skb, struct net_device *ndev)
|
||||
{
|
||||
bool cloned = skb_cloned(*skb) || skb_header_cloned(*skb);
|
||||
bool cloned = skb_cloned(*skb) || skb_header_cloned(*skb) ||
|
||||
skb_is_nonlinear(*skb);
|
||||
int padlen = ETH_ZLEN - (*skb)->len;
|
||||
int headroom = skb_headroom(*skb);
|
||||
int tailroom = skb_tailroom(*skb);
|
||||
|
|
|
@ -212,7 +212,7 @@ static struct sk_buff *alloc_ctrl_skb(struct sk_buff *skb, int len)
|
|||
{
|
||||
if (likely(skb && !skb_shared(skb) && !skb_cloned(skb))) {
|
||||
__skb_trim(skb, 0);
|
||||
refcount_add(2, &skb->users);
|
||||
refcount_inc(&skb->users);
|
||||
} else {
|
||||
skb = alloc_skb(len, GFP_KERNEL | __GFP_NOFAIL);
|
||||
}
|
||||
|
|
|
@ -383,6 +383,9 @@ int chtls_setkey(struct chtls_sock *csk, u32 keylen,
|
|||
if (ret)
|
||||
goto out_notcb;
|
||||
|
||||
if (unlikely(csk_flag(sk, CSK_ABORT_SHUTDOWN)))
|
||||
goto out_notcb;
|
||||
|
||||
set_wr_txq(skb, CPL_PRIORITY_DATA, csk->tlshws.txqid);
|
||||
csk->wr_credits -= DIV_ROUND_UP(len, 16);
|
||||
csk->wr_unacked += DIV_ROUND_UP(len, 16);
|
||||
|
|
|
@ -174,12 +174,17 @@ MODULE_PARM_DESC(tx_timeout, "The Tx timeout in ms");
|
|||
#define DPAA_PARSE_RESULTS_SIZE sizeof(struct fman_prs_result)
|
||||
#define DPAA_TIME_STAMP_SIZE 8
|
||||
#define DPAA_HASH_RESULTS_SIZE 8
|
||||
#ifdef CONFIG_DPAA_ERRATUM_A050385
|
||||
#define DPAA_RX_PRIV_DATA_SIZE (DPAA_A050385_ALIGN - (DPAA_PARSE_RESULTS_SIZE\
|
||||
+ DPAA_TIME_STAMP_SIZE + DPAA_HASH_RESULTS_SIZE))
|
||||
#else
|
||||
#define DPAA_RX_PRIV_DATA_SIZE (u16)(DPAA_TX_PRIV_DATA_SIZE + \
|
||||
#define DPAA_HWA_SIZE (DPAA_PARSE_RESULTS_SIZE + DPAA_TIME_STAMP_SIZE \
|
||||
+ DPAA_HASH_RESULTS_SIZE)
|
||||
#define DPAA_RX_PRIV_DATA_DEFAULT_SIZE (DPAA_TX_PRIV_DATA_SIZE + \
|
||||
dpaa_rx_extra_headroom)
|
||||
#ifdef CONFIG_DPAA_ERRATUM_A050385
|
||||
#define DPAA_RX_PRIV_DATA_A050385_SIZE (DPAA_A050385_ALIGN - DPAA_HWA_SIZE)
|
||||
#define DPAA_RX_PRIV_DATA_SIZE (fman_has_errata_a050385() ? \
|
||||
DPAA_RX_PRIV_DATA_A050385_SIZE : \
|
||||
DPAA_RX_PRIV_DATA_DEFAULT_SIZE)
|
||||
#else
|
||||
#define DPAA_RX_PRIV_DATA_SIZE DPAA_RX_PRIV_DATA_DEFAULT_SIZE
|
||||
#endif
|
||||
|
||||
#define DPAA_ETH_PCD_RXQ_NUM 128
|
||||
|
@ -2840,7 +2845,8 @@ out_error:
|
|||
return err;
|
||||
}
|
||||
|
||||
static inline u16 dpaa_get_headroom(struct dpaa_buffer_layout *bl)
|
||||
static u16 dpaa_get_headroom(struct dpaa_buffer_layout *bl,
|
||||
enum port_type port)
|
||||
{
|
||||
u16 headroom;
|
||||
|
||||
|
@ -2854,10 +2860,12 @@ static inline u16 dpaa_get_headroom(struct dpaa_buffer_layout *bl)
|
|||
*
|
||||
* Also make sure the headroom is a multiple of data_align bytes
|
||||
*/
|
||||
headroom = (u16)(bl->priv_data_size + DPAA_PARSE_RESULTS_SIZE +
|
||||
DPAA_TIME_STAMP_SIZE + DPAA_HASH_RESULTS_SIZE);
|
||||
headroom = (u16)(bl[port].priv_data_size + DPAA_HWA_SIZE);
|
||||
|
||||
return ALIGN(headroom, DPAA_FD_DATA_ALIGNMENT);
|
||||
if (port == RX)
|
||||
return ALIGN(headroom, DPAA_FD_RX_DATA_ALIGNMENT);
|
||||
else
|
||||
return ALIGN(headroom, DPAA_FD_DATA_ALIGNMENT);
|
||||
}
|
||||
|
||||
static int dpaa_eth_probe(struct platform_device *pdev)
|
||||
|
@ -3025,8 +3033,8 @@ static int dpaa_eth_probe(struct platform_device *pdev)
|
|||
goto free_dpaa_fqs;
|
||||
}
|
||||
|
||||
priv->tx_headroom = dpaa_get_headroom(&priv->buf_layout[TX]);
|
||||
priv->rx_headroom = dpaa_get_headroom(&priv->buf_layout[RX]);
|
||||
priv->tx_headroom = dpaa_get_headroom(priv->buf_layout, TX);
|
||||
priv->rx_headroom = dpaa_get_headroom(priv->buf_layout, RX);
|
||||
|
||||
/* All real interfaces need their ports initialized */
|
||||
err = dpaa_eth_init_ports(mac_dev, dpaa_bp, &port_fqs,
|
||||
|
|
|
@ -456,6 +456,12 @@ struct bufdesc_ex {
|
|||
*/
|
||||
#define FEC_QUIRK_HAS_FRREG (1 << 16)
|
||||
|
||||
/* Some FEC hardware blocks need the MMFR cleared at setup time to avoid
|
||||
* the generation of an MII event. This must be avoided in the older
|
||||
* FEC blocks where it will stop MII events being generated.
|
||||
*/
|
||||
#define FEC_QUIRK_CLEAR_SETUP_MII (1 << 17)
|
||||
|
||||
struct bufdesc_prop {
|
||||
int qid;
|
||||
/* Address of Rx and Tx buffers */
|
||||
|
|
|
@ -100,14 +100,14 @@ static const struct fec_devinfo fec_imx27_info = {
|
|||
static const struct fec_devinfo fec_imx28_info = {
|
||||
.quirks = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME |
|
||||
FEC_QUIRK_SINGLE_MDIO | FEC_QUIRK_HAS_RACC |
|
||||
FEC_QUIRK_HAS_FRREG,
|
||||
FEC_QUIRK_HAS_FRREG | FEC_QUIRK_CLEAR_SETUP_MII,
|
||||
};
|
||||
|
||||
static const struct fec_devinfo fec_imx6q_info = {
|
||||
.quirks = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT |
|
||||
FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
|
||||
FEC_QUIRK_HAS_VLAN | FEC_QUIRK_ERR006358 |
|
||||
FEC_QUIRK_HAS_RACC,
|
||||
FEC_QUIRK_HAS_RACC | FEC_QUIRK_CLEAR_SETUP_MII,
|
||||
};
|
||||
|
||||
static const struct fec_devinfo fec_mvf600_info = {
|
||||
|
@ -119,7 +119,8 @@ static const struct fec_devinfo fec_imx6x_info = {
|
|||
FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
|
||||
FEC_QUIRK_HAS_VLAN | FEC_QUIRK_HAS_AVB |
|
||||
FEC_QUIRK_ERR007885 | FEC_QUIRK_BUG_CAPTURE |
|
||||
FEC_QUIRK_HAS_RACC | FEC_QUIRK_HAS_COALESCE,
|
||||
FEC_QUIRK_HAS_RACC | FEC_QUIRK_HAS_COALESCE |
|
||||
FEC_QUIRK_CLEAR_SETUP_MII,
|
||||
};
|
||||
|
||||
static const struct fec_devinfo fec_imx6ul_info = {
|
||||
|
@ -127,7 +128,7 @@ static const struct fec_devinfo fec_imx6ul_info = {
|
|||
FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
|
||||
FEC_QUIRK_HAS_VLAN | FEC_QUIRK_ERR007885 |
|
||||
FEC_QUIRK_BUG_CAPTURE | FEC_QUIRK_HAS_RACC |
|
||||
FEC_QUIRK_HAS_COALESCE,
|
||||
FEC_QUIRK_HAS_COALESCE | FEC_QUIRK_CLEAR_SETUP_MII,
|
||||
};
|
||||
|
||||
static struct platform_device_id fec_devtype[] = {
|
||||
|
@ -2134,15 +2135,17 @@ static int fec_enet_mii_init(struct platform_device *pdev)
|
|||
if (suppress_preamble)
|
||||
fep->phy_speed |= BIT(7);
|
||||
|
||||
/* Clear MMFR to avoid to generate MII event by writing MSCR.
|
||||
* MII event generation condition:
|
||||
* - writing MSCR:
|
||||
* - mmfr[31:0]_not_zero & mscr[7:0]_is_zero &
|
||||
* mscr_reg_data_in[7:0] != 0
|
||||
* - writing MMFR:
|
||||
* - mscr[7:0]_not_zero
|
||||
*/
|
||||
writel(0, fep->hwp + FEC_MII_DATA);
|
||||
if (fep->quirks & FEC_QUIRK_CLEAR_SETUP_MII) {
|
||||
/* Clear MMFR to avoid to generate MII event by writing MSCR.
|
||||
* MII event generation condition:
|
||||
* - writing MSCR:
|
||||
* - mmfr[31:0]_not_zero & mscr[7:0]_is_zero &
|
||||
* mscr_reg_data_in[7:0] != 0
|
||||
* - writing MMFR:
|
||||
* - mscr[7:0]_not_zero
|
||||
*/
|
||||
writel(0, fep->hwp + FEC_MII_DATA);
|
||||
}
|
||||
|
||||
writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
|
||||
|
||||
|
|
|
@ -1829,20 +1829,12 @@ static netdev_tx_t gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
fcb_len = GMAC_FCB_LEN + GMAC_TXPAL_LEN;
|
||||
|
||||
/* make space for additional header when fcb is needed */
|
||||
if (fcb_len && unlikely(skb_headroom(skb) < fcb_len)) {
|
||||
struct sk_buff *skb_new;
|
||||
|
||||
skb_new = skb_realloc_headroom(skb, fcb_len);
|
||||
if (!skb_new) {
|
||||
if (fcb_len) {
|
||||
if (unlikely(skb_cow_head(skb, fcb_len))) {
|
||||
dev->stats.tx_errors++;
|
||||
dev_kfree_skb_any(skb);
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
if (skb->sk)
|
||||
skb_set_owner_w(skb_new, skb->sk);
|
||||
dev_consume_skb_any(skb);
|
||||
skb = skb_new;
|
||||
}
|
||||
|
||||
/* total number of fragments in the SKB */
|
||||
|
@ -3380,7 +3372,7 @@ static int gfar_probe(struct platform_device *ofdev)
|
|||
|
||||
if (dev->features & NETIF_F_IP_CSUM ||
|
||||
priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER)
|
||||
dev->needed_headroom = GMAC_FCB_LEN;
|
||||
dev->needed_headroom = GMAC_FCB_LEN + GMAC_TXPAL_LEN;
|
||||
|
||||
/* Initializing some of the rx/tx queue level parameters */
|
||||
for (i = 0; i < priv->num_tx_queues; i++) {
|
||||
|
|
|
@ -1185,18 +1185,27 @@ static int ibmvnic_open(struct net_device *netdev)
|
|||
if (adapter->state != VNIC_CLOSED) {
|
||||
rc = ibmvnic_login(netdev);
|
||||
if (rc)
|
||||
return rc;
|
||||
goto out;
|
||||
|
||||
rc = init_resources(adapter);
|
||||
if (rc) {
|
||||
netdev_err(netdev, "failed to initialize resources\n");
|
||||
release_resources(adapter);
|
||||
return rc;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
rc = __ibmvnic_open(netdev);
|
||||
|
||||
out:
|
||||
/*
|
||||
* If open fails due to a pending failover, set device state and
|
||||
* return. Device operation will be handled by reset routine.
|
||||
*/
|
||||
if (rc && adapter->failover_pending) {
|
||||
adapter->state = VNIC_OPEN;
|
||||
rc = 0;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -1922,6 +1931,13 @@ static int do_reset(struct ibmvnic_adapter *adapter,
|
|||
rwi->reset_reason);
|
||||
|
||||
rtnl_lock();
|
||||
/*
|
||||
* Now that we have the rtnl lock, clear any pending failover.
|
||||
* This will ensure ibmvnic_open() has either completed or will
|
||||
* block until failover is complete.
|
||||
*/
|
||||
if (rwi->reset_reason == VNIC_RESET_FAILOVER)
|
||||
adapter->failover_pending = false;
|
||||
|
||||
netif_carrier_off(netdev);
|
||||
adapter->reset_reason = rwi->reset_reason;
|
||||
|
@ -2202,6 +2218,13 @@ static void __ibmvnic_reset(struct work_struct *work)
|
|||
/* CHANGE_PARAM requestor holds rtnl_lock */
|
||||
rc = do_change_param_reset(adapter, rwi, reset_state);
|
||||
} else if (adapter->force_reset_recovery) {
|
||||
/*
|
||||
* Since we are doing a hard reset now, clear the
|
||||
* failover_pending flag so we don't ignore any
|
||||
* future MOBILITY or other resets.
|
||||
*/
|
||||
adapter->failover_pending = false;
|
||||
|
||||
/* Transport event occurred during previous reset */
|
||||
if (adapter->wait_for_reset) {
|
||||
/* Previous was CHANGE_PARAM; caller locked */
|
||||
|
@ -2266,9 +2289,15 @@ static int ibmvnic_reset(struct ibmvnic_adapter *adapter,
|
|||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* If failover is pending don't schedule any other reset.
|
||||
* Instead let the failover complete. If there is already a
|
||||
* a failover reset scheduled, we will detect and drop the
|
||||
* duplicate reset when walking the ->rwi_list below.
|
||||
*/
|
||||
if (adapter->state == VNIC_REMOVING ||
|
||||
adapter->state == VNIC_REMOVED ||
|
||||
adapter->failover_pending) {
|
||||
(adapter->failover_pending && reason != VNIC_RESET_FAILOVER)) {
|
||||
ret = EBUSY;
|
||||
netdev_dbg(netdev, "Adapter removing or pending failover, skipping reset\n");
|
||||
goto err;
|
||||
|
@ -4713,7 +4742,6 @@ static void ibmvnic_handle_crq(union ibmvnic_crq *crq,
|
|||
case IBMVNIC_CRQ_INIT:
|
||||
dev_info(dev, "Partner initialized\n");
|
||||
adapter->from_passive_init = true;
|
||||
adapter->failover_pending = false;
|
||||
if (!completion_done(&adapter->init_done)) {
|
||||
complete(&adapter->init_done);
|
||||
adapter->init_done_rc = -EIO;
|
||||
|
|
|
@ -126,6 +126,11 @@ static int ionic_get_link_ksettings(struct net_device *netdev,
|
|||
|
||||
ethtool_link_ksettings_zero_link_mode(ks, supported);
|
||||
|
||||
if (!idev->port_info) {
|
||||
netdev_err(netdev, "port_info not initialized\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
/* The port_info data is found in a DMA space that the NIC keeps
|
||||
* up-to-date, so there's no need to request the data from the
|
||||
* NIC, we already have it in our memory space.
|
||||
|
|
|
@ -4080,9 +4080,17 @@ err_out:
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
static bool rtl_test_hw_pad_bug(struct rtl8169_private *tp, struct sk_buff *skb)
|
||||
static bool rtl_test_hw_pad_bug(struct rtl8169_private *tp)
|
||||
{
|
||||
return skb->len < ETH_ZLEN && tp->mac_version == RTL_GIGA_MAC_VER_34;
|
||||
switch (tp->mac_version) {
|
||||
case RTL_GIGA_MAC_VER_34:
|
||||
case RTL_GIGA_MAC_VER_60:
|
||||
case RTL_GIGA_MAC_VER_61:
|
||||
case RTL_GIGA_MAC_VER_63:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static void rtl8169_tso_csum_v1(struct sk_buff *skb, u32 *opts)
|
||||
|
@ -4154,7 +4162,7 @@ static bool rtl8169_tso_csum_v2(struct rtl8169_private *tp,
|
|||
|
||||
opts[1] |= transport_offset << TCPHO_SHIFT;
|
||||
} else {
|
||||
if (unlikely(rtl_test_hw_pad_bug(tp, skb)))
|
||||
if (unlikely(skb->len < ETH_ZLEN && rtl_test_hw_pad_bug(tp)))
|
||||
return !eth_skb_pad(skb);
|
||||
}
|
||||
|
||||
|
|
|
@ -625,13 +625,6 @@ static int intel_eth_pci_probe(struct pci_dev *pdev,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (plat->eee_usecs_rate > 0) {
|
||||
u32 tx_lpi_usec;
|
||||
|
||||
tx_lpi_usec = (plat->eee_usecs_rate / 1000000) - 1;
|
||||
writel(tx_lpi_usec, res.addr + GMAC_1US_TIC_COUNTER);
|
||||
}
|
||||
|
||||
ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
@ -641,6 +634,13 @@ static int intel_eth_pci_probe(struct pci_dev *pdev,
|
|||
res.wol_irq = pci_irq_vector(pdev, 0);
|
||||
res.irq = pci_irq_vector(pdev, 0);
|
||||
|
||||
if (plat->eee_usecs_rate > 0) {
|
||||
u32 tx_lpi_usec;
|
||||
|
||||
tx_lpi_usec = (plat->eee_usecs_rate / 1000000) - 1;
|
||||
writel(tx_lpi_usec, res.addr + GMAC_1US_TIC_COUNTER);
|
||||
}
|
||||
|
||||
ret = stmmac_dvr_probe(&pdev->dev, plat, &res);
|
||||
if (ret) {
|
||||
pci_free_irq_vectors(pdev);
|
||||
|
|
|
@ -4757,6 +4757,7 @@ static void stmmac_napi_add(struct net_device *dev)
|
|||
|
||||
ch->priv_data = priv;
|
||||
ch->index = queue;
|
||||
spin_lock_init(&ch->lock);
|
||||
|
||||
if (queue < priv->plat->rx_queues_to_use) {
|
||||
netif_napi_add(dev, &ch->rx_napi, stmmac_napi_poll_rx,
|
||||
|
|
|
@ -728,7 +728,6 @@ int cpsw_get_ts_info(struct net_device *ndev, struct ethtool_ts_info *info)
|
|||
(1 << HWTSTAMP_TX_ON);
|
||||
info->rx_filters =
|
||||
(1 << HWTSTAMP_FILTER_NONE) |
|
||||
(1 << HWTSTAMP_FILTER_PTP_V1_L4_EVENT) |
|
||||
(1 << HWTSTAMP_FILTER_PTP_V2_EVENT);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -639,13 +639,10 @@ static int cpsw_hwtstamp_set(struct net_device *dev, struct ifreq *ifr)
|
|||
break;
|
||||
case HWTSTAMP_FILTER_ALL:
|
||||
case HWTSTAMP_FILTER_NTP_ALL:
|
||||
return -ERANGE;
|
||||
case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
|
||||
case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
|
||||
case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
|
||||
priv->rx_ts_enabled = HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
|
||||
cfg.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
|
||||
break;
|
||||
return -ERANGE;
|
||||
case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
|
||||
case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
|
||||
case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
|
||||
|
|
|
@ -2389,7 +2389,8 @@ static int sfp_probe(struct platform_device *pdev)
|
|||
continue;
|
||||
|
||||
sfp->gpio_irq[i] = gpiod_to_irq(sfp->gpio[i]);
|
||||
if (!sfp->gpio_irq[i]) {
|
||||
if (sfp->gpio_irq[i] < 0) {
|
||||
sfp->gpio_irq[i] = 0;
|
||||
sfp->need_poll = true;
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -1309,6 +1309,7 @@ static const struct usb_device_id products[] = {
|
|||
{QMI_FIXED_INTF(0x1bc7, 0x1101, 3)}, /* Telit ME910 dual modem */
|
||||
{QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */
|
||||
{QMI_QUIRK_SET_DTR(0x1bc7, 0x1201, 2)}, /* Telit LE920, LE920A4 */
|
||||
{QMI_QUIRK_SET_DTR(0x1bc7, 0x1230, 2)}, /* Telit LE910Cx */
|
||||
{QMI_QUIRK_SET_DTR(0x1bc7, 0x1260, 2)}, /* Telit LE910Cx */
|
||||
{QMI_QUIRK_SET_DTR(0x1bc7, 0x1261, 2)}, /* Telit LE910Cx */
|
||||
{QMI_QUIRK_SET_DTR(0x1bc7, 0x1900, 1)}, /* Telit LN940 series */
|
||||
|
|
|
@ -61,21 +61,17 @@ static inline void can_skb_set_owner(struct sk_buff *skb, struct sock *sk)
|
|||
*/
|
||||
static inline struct sk_buff *can_create_echo_skb(struct sk_buff *skb)
|
||||
{
|
||||
if (skb_shared(skb)) {
|
||||
struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC);
|
||||
struct sk_buff *nskb;
|
||||
|
||||
if (likely(nskb)) {
|
||||
can_skb_set_owner(nskb, skb->sk);
|
||||
consume_skb(skb);
|
||||
return nskb;
|
||||
} else {
|
||||
kfree_skb(skb);
|
||||
return NULL;
|
||||
}
|
||||
nskb = skb_clone(skb, GFP_ATOMIC);
|
||||
if (unlikely(!nskb)) {
|
||||
kfree_skb(skb);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* we can assume to have an unshared skb with proper owner */
|
||||
return skb;
|
||||
can_skb_set_owner(nskb, skb->sk);
|
||||
consume_skb(skb);
|
||||
return nskb;
|
||||
}
|
||||
|
||||
#endif /* !_CAN_SKB_H */
|
||||
|
|
|
@ -24,6 +24,12 @@ struct nfnl_callback {
|
|||
const u_int16_t attr_count; /* number of nlattr's */
|
||||
};
|
||||
|
||||
enum nfnl_abort_action {
|
||||
NFNL_ABORT_NONE = 0,
|
||||
NFNL_ABORT_AUTOLOAD,
|
||||
NFNL_ABORT_VALIDATE,
|
||||
};
|
||||
|
||||
struct nfnetlink_subsystem {
|
||||
const char *name;
|
||||
__u8 subsys_id; /* nfnetlink subsystem ID */
|
||||
|
@ -31,7 +37,8 @@ struct nfnetlink_subsystem {
|
|||
const struct nfnl_callback *cb; /* callback for individual types */
|
||||
struct module *owner;
|
||||
int (*commit)(struct net *net, struct sk_buff *skb);
|
||||
int (*abort)(struct net *net, struct sk_buff *skb, bool autoload);
|
||||
int (*abort)(struct net *net, struct sk_buff *skb,
|
||||
enum nfnl_abort_action action);
|
||||
void (*cleanup)(struct net *net);
|
||||
bool (*valid_genid)(struct net *net, u32 genid);
|
||||
};
|
||||
|
|
|
@ -16,7 +16,7 @@ struct ip_rt_info {
|
|||
u_int32_t mark;
|
||||
};
|
||||
|
||||
int ip_route_me_harder(struct net *net, struct sk_buff *skb, unsigned addr_type);
|
||||
int ip_route_me_harder(struct net *net, struct sock *sk, struct sk_buff *skb, unsigned addr_type);
|
||||
|
||||
struct nf_queue_entry;
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ struct nf_ipv6_ops {
|
|||
#if IS_MODULE(CONFIG_IPV6)
|
||||
int (*chk_addr)(struct net *net, const struct in6_addr *addr,
|
||||
const struct net_device *dev, int strict);
|
||||
int (*route_me_harder)(struct net *net, struct sk_buff *skb);
|
||||
int (*route_me_harder)(struct net *net, struct sock *sk, struct sk_buff *skb);
|
||||
int (*dev_get_saddr)(struct net *net, const struct net_device *dev,
|
||||
const struct in6_addr *daddr, unsigned int srcprefs,
|
||||
struct in6_addr *saddr);
|
||||
|
@ -143,9 +143,9 @@ static inline int nf_br_ip6_fragment(struct net *net, struct sock *sk,
|
|||
#endif
|
||||
}
|
||||
|
||||
int ip6_route_me_harder(struct net *net, struct sk_buff *skb);
|
||||
int ip6_route_me_harder(struct net *net, struct sock *sk, struct sk_buff *skb);
|
||||
|
||||
static inline int nf_ip6_route_me_harder(struct net *net, struct sk_buff *skb)
|
||||
static inline int nf_ip6_route_me_harder(struct net *net, struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
#if IS_MODULE(CONFIG_IPV6)
|
||||
const struct nf_ipv6_ops *v6_ops = nf_get_ipv6_ops();
|
||||
|
@ -153,9 +153,9 @@ static inline int nf_ip6_route_me_harder(struct net *net, struct sk_buff *skb)
|
|||
if (!v6_ops)
|
||||
return -EHOSTUNREACH;
|
||||
|
||||
return v6_ops->route_me_harder(net, skb);
|
||||
return v6_ops->route_me_harder(net, sk, skb);
|
||||
#elif IS_BUILTIN(CONFIG_IPV6)
|
||||
return ip6_route_me_harder(net, skb);
|
||||
return ip6_route_me_harder(net, sk, skb);
|
||||
#else
|
||||
return -EHOSTUNREACH;
|
||||
#endif
|
||||
|
|
|
@ -1444,7 +1444,7 @@ int cfg80211_check_station_change(struct wiphy *wiphy,
|
|||
enum cfg80211_station_type statype);
|
||||
|
||||
/**
|
||||
* enum station_info_rate_flags - bitrate info flags
|
||||
* enum rate_info_flags - bitrate info flags
|
||||
*
|
||||
* Used by the driver to indicate the specific rate transmission
|
||||
* type for 802.11n transmissions.
|
||||
|
@ -1517,7 +1517,7 @@ struct rate_info {
|
|||
};
|
||||
|
||||
/**
|
||||
* enum station_info_rate_flags - bitrate info flags
|
||||
* enum bss_param_flags - bitrate info flags
|
||||
*
|
||||
* Used by the driver to indicate the specific rate transmission
|
||||
* type for 802.11n transmissions.
|
||||
|
@ -6467,7 +6467,8 @@ void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid,
|
|||
struct ieee80211_channel *channel, gfp_t gfp);
|
||||
|
||||
/**
|
||||
* cfg80211_notify_new_candidate - notify cfg80211 of a new mesh peer candidate
|
||||
* cfg80211_notify_new_peer_candidate - notify cfg80211 of a new mesh peer
|
||||
* candidate
|
||||
*
|
||||
* @dev: network device
|
||||
* @macaddr: the MAC address of the new candidate
|
||||
|
@ -7606,7 +7607,7 @@ u32 cfg80211_calculate_bitrate(struct rate_info *rate);
|
|||
void cfg80211_unregister_wdev(struct wireless_dev *wdev);
|
||||
|
||||
/**
|
||||
* struct cfg80211_ft_event - FT Information Elements
|
||||
* struct cfg80211_ft_event_params - FT Information Elements
|
||||
* @ies: FT IEs
|
||||
* @ies_len: length of the FT IE in bytes
|
||||
* @target_ap: target AP's MAC address
|
||||
|
|
|
@ -3311,7 +3311,7 @@ enum ieee80211_roc_type {
|
|||
};
|
||||
|
||||
/**
|
||||
* enum ieee80211_reconfig_complete_type - reconfig type
|
||||
* enum ieee80211_reconfig_type - reconfig type
|
||||
*
|
||||
* This enum is used by the reconfig_complete() callback to indicate what
|
||||
* reconfiguration type was completed.
|
||||
|
@ -6334,7 +6334,8 @@ bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw,
|
|||
int band, struct ieee80211_sta **sta);
|
||||
|
||||
/**
|
||||
* Sanity-check and parse the radiotap header of injected frames
|
||||
* ieee80211_parse_tx_radiotap - Sanity-check and parse the radiotap header
|
||||
* of injected frames
|
||||
* @skb: packet injected by userspace
|
||||
* @dev: the &struct device of this 802.11 device
|
||||
*/
|
||||
|
@ -6389,7 +6390,7 @@ int ieee80211_parse_p2p_noa(const struct ieee80211_p2p_noa_attr *attr,
|
|||
void ieee80211_update_p2p_noa(struct ieee80211_noa_data *data, u32 tsf);
|
||||
|
||||
/**
|
||||
* ieee80211_tdls_oper - request userspace to perform a TDLS operation
|
||||
* ieee80211_tdls_oper_request - request userspace to perform a TDLS operation
|
||||
* @vif: virtual interface
|
||||
* @peer: the peer's destination address
|
||||
* @oper: the requested TDLS operation
|
||||
|
|
|
@ -138,6 +138,7 @@ struct icmp6hdr {
|
|||
#define ICMPV6_HDR_FIELD 0
|
||||
#define ICMPV6_UNK_NEXTHDR 1
|
||||
#define ICMPV6_UNK_OPTION 2
|
||||
#define ICMPV6_HDR_INCOMP 3
|
||||
|
||||
/*
|
||||
* constants for (set|get)sockopt
|
||||
|
|
|
@ -954,9 +954,8 @@ static void *lec_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
|||
{
|
||||
struct lec_state *state = seq->private;
|
||||
|
||||
v = lec_get_idx(state, 1);
|
||||
*pos += !!PTR_ERR(v);
|
||||
return v;
|
||||
++*pos;
|
||||
return lec_get_idx(state, 1);
|
||||
}
|
||||
|
||||
static int lec_seq_show(struct seq_file *seq, void *v)
|
||||
|
|
|
@ -62,8 +62,9 @@ config CAN_ISOTP
|
|||
communication between CAN nodes via two defined CAN Identifiers.
|
||||
As CAN frames can only transport a small amount of data bytes
|
||||
(max. 8 bytes for 'classic' CAN and max. 64 bytes for CAN FD) this
|
||||
segmentation is needed to transport longer PDUs as needed e.g. for
|
||||
vehicle diagnosis (UDS, ISO 14229) or IP-over-CAN traffic.
|
||||
segmentation is needed to transport longer Protocol Data Units (PDU)
|
||||
as needed e.g. for vehicle diagnosis (UDS, ISO 14229) or IP-over-CAN
|
||||
traffic.
|
||||
This protocol driver implements data transfers according to
|
||||
ISO 15765-2:2016 for 'classic' CAN and CAN FD frame types.
|
||||
If you want to perform automotive vehicle diagnostic services (UDS),
|
||||
|
|
|
@ -252,14 +252,16 @@ static void isotp_rcv_skb(struct sk_buff *skb, struct sock *sk)
|
|||
|
||||
static u8 padlen(u8 datalen)
|
||||
{
|
||||
const u8 plen[] = {8, 8, 8, 8, 8, 8, 8, 8, 8, /* 0 - 8 */
|
||||
12, 12, 12, 12, /* 9 - 12 */
|
||||
16, 16, 16, 16, /* 13 - 16 */
|
||||
20, 20, 20, 20, /* 17 - 20 */
|
||||
24, 24, 24, 24, /* 21 - 24 */
|
||||
32, 32, 32, 32, 32, 32, 32, 32, /* 25 - 32 */
|
||||
48, 48, 48, 48, 48, 48, 48, 48, /* 33 - 40 */
|
||||
48, 48, 48, 48, 48, 48, 48, 48}; /* 41 - 48 */
|
||||
static const u8 plen[] = {
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, /* 0 - 8 */
|
||||
12, 12, 12, 12, /* 9 - 12 */
|
||||
16, 16, 16, 16, /* 13 - 16 */
|
||||
20, 20, 20, 20, /* 17 - 20 */
|
||||
24, 24, 24, 24, /* 21 - 24 */
|
||||
32, 32, 32, 32, 32, 32, 32, 32, /* 25 - 32 */
|
||||
48, 48, 48, 48, 48, 48, 48, 48, /* 33 - 40 */
|
||||
48, 48, 48, 48, 48, 48, 48, 48 /* 41 - 48 */
|
||||
};
|
||||
|
||||
if (datalen > 48)
|
||||
return 64;
|
||||
|
@ -569,10 +571,6 @@ static int isotp_rcv_cf(struct sock *sk, struct canfd_frame *cf, int ae,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* no creation of flow control frames */
|
||||
if (so->opt.flags & CAN_ISOTP_LISTEN_MODE)
|
||||
return 0;
|
||||
|
||||
/* perform blocksize handling, if enabled */
|
||||
if (!so->rxfc.bs || ++so->rx.bs < so->rxfc.bs) {
|
||||
/* start rx timeout watchdog */
|
||||
|
@ -581,6 +579,10 @@ static int isotp_rcv_cf(struct sock *sk, struct canfd_frame *cf, int ae,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* no creation of flow control frames */
|
||||
if (so->opt.flags & CAN_ISOTP_LISTEN_MODE)
|
||||
return 0;
|
||||
|
||||
/* we reached the specified blocksize so->rxfc.bs */
|
||||
isotp_send_fc(sk, ae, ISOTP_FC_CTS);
|
||||
return 0;
|
||||
|
|
|
@ -475,6 +475,12 @@ static int j1939_sk_bind(struct socket *sock, struct sockaddr *uaddr, int len)
|
|||
goto out_release_sock;
|
||||
}
|
||||
|
||||
if (!(ndev->flags & IFF_UP)) {
|
||||
dev_put(ndev);
|
||||
ret = -ENETDOWN;
|
||||
goto out_release_sock;
|
||||
}
|
||||
|
||||
priv = j1939_netdev_start(ndev);
|
||||
dev_put(ndev);
|
||||
if (IS_ERR(priv)) {
|
||||
|
|
|
@ -462,6 +462,9 @@ void can_init_proc(struct net *net)
|
|||
*/
|
||||
void can_remove_proc(struct net *net)
|
||||
{
|
||||
if (!net->can.proc_dir)
|
||||
return;
|
||||
|
||||
if (net->can.pde_stats)
|
||||
remove_proc_entry(CAN_PROC_STATS, net->can.proc_dir);
|
||||
|
||||
|
@ -486,6 +489,5 @@ void can_remove_proc(struct net *net)
|
|||
if (net->can.pde_rcvlist_sff)
|
||||
remove_proc_entry(CAN_PROC_RCVLIST_SFF, net->can.proc_dir);
|
||||
|
||||
if (net->can.proc_dir)
|
||||
remove_proc_entry("can", net->proc_net);
|
||||
remove_proc_entry("can", net->proc_net);
|
||||
}
|
||||
|
|
|
@ -608,9 +608,6 @@ void ip_md_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
|
|||
ttl = ip4_dst_hoplimit(&rt->dst);
|
||||
}
|
||||
|
||||
if (!df && skb->protocol == htons(ETH_P_IP))
|
||||
df = inner_iph->frag_off & htons(IP_DF);
|
||||
|
||||
headroom += LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len;
|
||||
if (headroom > dev->needed_headroom)
|
||||
dev->needed_headroom = headroom;
|
||||
|
|
|
@ -17,17 +17,19 @@
|
|||
#include <net/netfilter/nf_queue.h>
|
||||
|
||||
/* route_me_harder function, used by iptable_nat, iptable_mangle + ip_queue */
|
||||
int ip_route_me_harder(struct net *net, struct sk_buff *skb, unsigned int addr_type)
|
||||
int ip_route_me_harder(struct net *net, struct sock *sk, struct sk_buff *skb, unsigned int addr_type)
|
||||
{
|
||||
const struct iphdr *iph = ip_hdr(skb);
|
||||
struct rtable *rt;
|
||||
struct flowi4 fl4 = {};
|
||||
__be32 saddr = iph->saddr;
|
||||
const struct sock *sk = skb_to_full_sk(skb);
|
||||
__u8 flags = sk ? inet_sk_flowi_flags(sk) : 0;
|
||||
__u8 flags;
|
||||
struct net_device *dev = skb_dst(skb)->dev;
|
||||
unsigned int hh_len;
|
||||
|
||||
sk = sk_to_full_sk(sk);
|
||||
flags = sk ? inet_sk_flowi_flags(sk) : 0;
|
||||
|
||||
if (addr_type == RTN_UNSPEC)
|
||||
addr_type = inet_addr_type_dev_table(net, dev, saddr);
|
||||
if (addr_type == RTN_LOCAL || addr_type == RTN_UNICAST)
|
||||
|
|
|
@ -62,7 +62,7 @@ ipt_mangle_out(struct sk_buff *skb, const struct nf_hook_state *state)
|
|||
iph->daddr != daddr ||
|
||||
skb->mark != mark ||
|
||||
iph->tos != tos) {
|
||||
err = ip_route_me_harder(state->net, skb, RTN_UNSPEC);
|
||||
err = ip_route_me_harder(state->net, state->sk, skb, RTN_UNSPEC);
|
||||
if (err < 0)
|
||||
ret = NF_DROP_ERR(err);
|
||||
}
|
||||
|
|
|
@ -145,7 +145,7 @@ void nf_send_reset(struct net *net, struct sk_buff *oldskb, int hook)
|
|||
ip4_dst_hoplimit(skb_dst(nskb)));
|
||||
nf_reject_ip_tcphdr_put(nskb, oldskb, oth);
|
||||
|
||||
if (ip_route_me_harder(net, nskb, RTN_UNSPEC))
|
||||
if (ip_route_me_harder(net, nskb->sk, nskb, RTN_UNSPEC))
|
||||
goto free_nskb;
|
||||
|
||||
niph = ip_hdr(nskb);
|
||||
|
|
|
@ -64,14 +64,14 @@ static int xfrm_tunnel_err(struct sk_buff *skb, u32 info)
|
|||
static struct xfrm_tunnel xfrm_tunnel_handler __read_mostly = {
|
||||
.handler = xfrm_tunnel_rcv,
|
||||
.err_handler = xfrm_tunnel_err,
|
||||
.priority = 3,
|
||||
.priority = 4,
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
static struct xfrm_tunnel xfrm64_tunnel_handler __read_mostly = {
|
||||
.handler = xfrm_tunnel_rcv,
|
||||
.err_handler = xfrm_tunnel_err,
|
||||
.priority = 2,
|
||||
.priority = 3,
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
|
@ -158,7 +158,13 @@ static bool is_ineligible(const struct sk_buff *skb)
|
|||
tp = skb_header_pointer(skb,
|
||||
ptr+offsetof(struct icmp6hdr, icmp6_type),
|
||||
sizeof(_type), &_type);
|
||||
if (!tp || !(*tp & ICMPV6_INFOMSG_MASK))
|
||||
|
||||
/* Based on RFC 8200, Section 4.5 Fragment Header, return
|
||||
* false if this is a fragment packet with no icmp header info.
|
||||
*/
|
||||
if (!tp && frag_off != 0)
|
||||
return false;
|
||||
else if (!tp || !(*tp & ICMPV6_INFOMSG_MASK))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -1271,6 +1271,8 @@ route_lookup:
|
|||
if (max_headroom > dev->needed_headroom)
|
||||
dev->needed_headroom = max_headroom;
|
||||
|
||||
skb_set_inner_ipproto(skb, proto);
|
||||
|
||||
err = ip6_tnl_encap(skb, t, &proto, fl6);
|
||||
if (err)
|
||||
return err;
|
||||
|
@ -1280,8 +1282,6 @@ route_lookup:
|
|||
ipv6_push_frag_opts(skb, &opt.ops, &proto);
|
||||
}
|
||||
|
||||
skb_set_inner_ipproto(skb, proto);
|
||||
|
||||
skb_push(skb, sizeof(struct ipv6hdr));
|
||||
skb_reset_network_header(skb);
|
||||
ipv6h = ipv6_hdr(skb);
|
||||
|
|
|
@ -20,10 +20,10 @@
|
|||
#include <net/netfilter/ipv6/nf_defrag_ipv6.h>
|
||||
#include "../bridge/br_private.h"
|
||||
|
||||
int ip6_route_me_harder(struct net *net, struct sk_buff *skb)
|
||||
int ip6_route_me_harder(struct net *net, struct sock *sk_partial, struct sk_buff *skb)
|
||||
{
|
||||
const struct ipv6hdr *iph = ipv6_hdr(skb);
|
||||
struct sock *sk = sk_to_full_sk(skb->sk);
|
||||
struct sock *sk = sk_to_full_sk(sk_partial);
|
||||
unsigned int hh_len;
|
||||
struct dst_entry *dst;
|
||||
int strict = (ipv6_addr_type(&iph->daddr) &
|
||||
|
@ -84,7 +84,7 @@ static int nf_ip6_reroute(struct sk_buff *skb,
|
|||
if (!ipv6_addr_equal(&iph->daddr, &rt_info->daddr) ||
|
||||
!ipv6_addr_equal(&iph->saddr, &rt_info->saddr) ||
|
||||
skb->mark != rt_info->mark)
|
||||
return ip6_route_me_harder(entry->state.net, skb);
|
||||
return ip6_route_me_harder(entry->state.net, entry->state.sk, skb);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ ip6t_mangle_out(struct sk_buff *skb, const struct nf_hook_state *state)
|
|||
skb->mark != mark ||
|
||||
ipv6_hdr(skb)->hop_limit != hop_limit ||
|
||||
flowlabel != *((u_int32_t *)ipv6_hdr(skb)))) {
|
||||
err = ip6_route_me_harder(state->net, skb);
|
||||
err = ip6_route_me_harder(state->net, state->sk, skb);
|
||||
if (err < 0)
|
||||
ret = NF_DROP_ERR(err);
|
||||
}
|
||||
|
|
|
@ -42,6 +42,8 @@
|
|||
#include <linux/skbuff.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/tcp.h>
|
||||
#include <linux/udp.h>
|
||||
|
||||
#include <net/sock.h>
|
||||
#include <net/snmp.h>
|
||||
|
@ -322,7 +324,9 @@ static int ipv6_frag_rcv(struct sk_buff *skb)
|
|||
struct frag_queue *fq;
|
||||
const struct ipv6hdr *hdr = ipv6_hdr(skb);
|
||||
struct net *net = dev_net(skb_dst(skb)->dev);
|
||||
int iif;
|
||||
__be16 frag_off;
|
||||
int iif, offset;
|
||||
u8 nexthdr;
|
||||
|
||||
if (IP6CB(skb)->flags & IP6SKB_FRAGMENTED)
|
||||
goto fail_hdr;
|
||||
|
@ -351,6 +355,33 @@ static int ipv6_frag_rcv(struct sk_buff *skb)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* RFC 8200, Section 4.5 Fragment Header:
|
||||
* If the first fragment does not include all headers through an
|
||||
* Upper-Layer header, then that fragment should be discarded and
|
||||
* an ICMP Parameter Problem, Code 3, message should be sent to
|
||||
* the source of the fragment, with the Pointer field set to zero.
|
||||
*/
|
||||
nexthdr = hdr->nexthdr;
|
||||
offset = ipv6_skip_exthdr(skb, skb_transport_offset(skb), &nexthdr, &frag_off);
|
||||
if (offset >= 0) {
|
||||
/* Check some common protocols' header */
|
||||
if (nexthdr == IPPROTO_TCP)
|
||||
offset += sizeof(struct tcphdr);
|
||||
else if (nexthdr == IPPROTO_UDP)
|
||||
offset += sizeof(struct udphdr);
|
||||
else if (nexthdr == IPPROTO_ICMPV6)
|
||||
offset += sizeof(struct icmp6hdr);
|
||||
else
|
||||
offset += 1;
|
||||
|
||||
if (!(frag_off & htons(IP6_OFFSET)) && offset > skb->len) {
|
||||
__IP6_INC_STATS(net, __in6_dev_get_safely(skb->dev),
|
||||
IPSTATS_MIB_INHDRERRORS);
|
||||
icmpv6_param_prob(skb, ICMPV6_HDR_INCOMP, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
iif = skb->dev ? skb->dev->ifindex : 0;
|
||||
fq = fq_find(net, fhdr->identification, hdr, iif);
|
||||
if (fq) {
|
||||
|
|
|
@ -303,13 +303,13 @@ static const struct xfrm_type xfrm6_tunnel_type = {
|
|||
static struct xfrm6_tunnel xfrm6_tunnel_handler __read_mostly = {
|
||||
.handler = xfrm6_tunnel_rcv,
|
||||
.err_handler = xfrm6_tunnel_err,
|
||||
.priority = 2,
|
||||
.priority = 3,
|
||||
};
|
||||
|
||||
static struct xfrm6_tunnel xfrm46_tunnel_handler __read_mostly = {
|
||||
.handler = xfrm6_tunnel_rcv,
|
||||
.err_handler = xfrm6_tunnel_err,
|
||||
.priority = 2,
|
||||
.priority = 3,
|
||||
};
|
||||
|
||||
static int __net_init xfrm6_tunnel_net_init(struct net *net)
|
||||
|
|
|
@ -5464,6 +5464,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
|
|||
struct cfg80211_assoc_request *req)
|
||||
{
|
||||
bool is_6ghz = req->bss->channel->band == NL80211_BAND_6GHZ;
|
||||
bool is_5ghz = req->bss->channel->band == NL80211_BAND_5GHZ;
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
|
||||
struct ieee80211_bss *bss = (void *)req->bss->priv;
|
||||
|
@ -5616,7 +5617,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
|
|||
if (vht_ie && vht_ie[1] >= sizeof(struct ieee80211_vht_cap))
|
||||
memcpy(&assoc_data->ap_vht_cap, vht_ie + 2,
|
||||
sizeof(struct ieee80211_vht_cap));
|
||||
else if (!is_6ghz)
|
||||
else if (is_5ghz)
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_VHT |
|
||||
IEEE80211_STA_DISABLE_HE;
|
||||
rcu_read_unlock();
|
||||
|
|
|
@ -258,6 +258,24 @@ struct sta_info *sta_info_get_by_idx(struct ieee80211_sub_if_data *sdata,
|
|||
*/
|
||||
void sta_info_free(struct ieee80211_local *local, struct sta_info *sta)
|
||||
{
|
||||
/*
|
||||
* If we had used sta_info_pre_move_state() then we might not
|
||||
* have gone through the state transitions down again, so do
|
||||
* it here now (and warn if it's inserted).
|
||||
*
|
||||
* This will clear state such as fast TX/RX that may have been
|
||||
* allocated during state transitions.
|
||||
*/
|
||||
while (sta->sta_state > IEEE80211_STA_NONE) {
|
||||
int ret;
|
||||
|
||||
WARN_ON_ONCE(test_sta_flag(sta, WLAN_STA_INSERTED));
|
||||
|
||||
ret = sta_info_move_state(sta, sta->sta_state - 1);
|
||||
if (WARN_ONCE(ret, "sta_info_move_state() returned %d\n", ret))
|
||||
break;
|
||||
}
|
||||
|
||||
if (sta->rate_ctrl)
|
||||
rate_control_free_sta(sta);
|
||||
|
||||
|
|
|
@ -785,7 +785,7 @@ int sta_info_init(struct ieee80211_local *local);
|
|||
void sta_info_stop(struct ieee80211_local *local);
|
||||
|
||||
/**
|
||||
* sta_info_flush - flush matching STA entries from the STA table
|
||||
* __sta_info_flush - flush matching STA entries from the STA table
|
||||
*
|
||||
* Returns the number of removed STA entries.
|
||||
*
|
||||
|
@ -794,6 +794,13 @@ void sta_info_stop(struct ieee80211_local *local);
|
|||
*/
|
||||
int __sta_info_flush(struct ieee80211_sub_if_data *sdata, bool vlans);
|
||||
|
||||
/**
|
||||
* sta_info_flush - flush matching STA entries from the STA table
|
||||
*
|
||||
* Returns the number of removed STA entries.
|
||||
*
|
||||
* @sdata: sdata to remove all stations from
|
||||
*/
|
||||
static inline int sta_info_flush(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
return __sta_info_flush(sdata, false);
|
||||
|
|
|
@ -1942,19 +1942,24 @@ static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata,
|
|||
|
||||
/* device xmit handlers */
|
||||
|
||||
enum ieee80211_encrypt {
|
||||
ENCRYPT_NO,
|
||||
ENCRYPT_MGMT,
|
||||
ENCRYPT_DATA,
|
||||
};
|
||||
|
||||
static int ieee80211_skb_resize(struct ieee80211_sub_if_data *sdata,
|
||||
struct sk_buff *skb,
|
||||
int head_need, bool may_encrypt)
|
||||
int head_need,
|
||||
enum ieee80211_encrypt encrypt)
|
||||
{
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct ieee80211_hdr *hdr;
|
||||
bool enc_tailroom;
|
||||
int tail_need = 0;
|
||||
|
||||
hdr = (struct ieee80211_hdr *) skb->data;
|
||||
enc_tailroom = may_encrypt &&
|
||||
(sdata->crypto_tx_tailroom_needed_cnt ||
|
||||
ieee80211_is_mgmt(hdr->frame_control));
|
||||
enc_tailroom = encrypt == ENCRYPT_MGMT ||
|
||||
(encrypt == ENCRYPT_DATA &&
|
||||
sdata->crypto_tx_tailroom_needed_cnt);
|
||||
|
||||
if (enc_tailroom) {
|
||||
tail_need = IEEE80211_ENCRYPT_TAILROOM;
|
||||
|
@ -1985,23 +1990,29 @@ void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
|
|||
{
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
struct ieee80211_hdr *hdr;
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
|
||||
int headroom;
|
||||
bool may_encrypt;
|
||||
enum ieee80211_encrypt encrypt;
|
||||
|
||||
may_encrypt = !(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT);
|
||||
if (info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)
|
||||
encrypt = ENCRYPT_NO;
|
||||
else if (ieee80211_is_mgmt(hdr->frame_control))
|
||||
encrypt = ENCRYPT_MGMT;
|
||||
else
|
||||
encrypt = ENCRYPT_DATA;
|
||||
|
||||
headroom = local->tx_headroom;
|
||||
if (may_encrypt)
|
||||
if (encrypt != ENCRYPT_NO)
|
||||
headroom += sdata->encrypt_headroom;
|
||||
headroom -= skb_headroom(skb);
|
||||
headroom = max_t(int, 0, headroom);
|
||||
|
||||
if (ieee80211_skb_resize(sdata, skb, headroom, may_encrypt)) {
|
||||
if (ieee80211_skb_resize(sdata, skb, headroom, encrypt)) {
|
||||
ieee80211_free_txskb(&local->hw, skb);
|
||||
return;
|
||||
}
|
||||
|
||||
/* reload after potential resize */
|
||||
hdr = (struct ieee80211_hdr *) skb->data;
|
||||
info->control.vif = &sdata->vif;
|
||||
|
||||
|
@ -2828,7 +2839,7 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
|
|||
head_need += sdata->encrypt_headroom;
|
||||
head_need += local->tx_headroom;
|
||||
head_need = max_t(int, 0, head_need);
|
||||
if (ieee80211_skb_resize(sdata, skb, head_need, true)) {
|
||||
if (ieee80211_skb_resize(sdata, skb, head_need, ENCRYPT_DATA)) {
|
||||
ieee80211_free_txskb(&local->hw, skb);
|
||||
skb = NULL;
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
@ -3502,7 +3513,7 @@ static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata,
|
|||
if (unlikely(ieee80211_skb_resize(sdata, skb,
|
||||
max_t(int, extra_head + hw_headroom -
|
||||
skb_headroom(skb), 0),
|
||||
false))) {
|
||||
ENCRYPT_NO))) {
|
||||
kfree_skb(skb);
|
||||
return true;
|
||||
}
|
||||
|
@ -3619,13 +3630,14 @@ begin:
|
|||
tx.skb = skb;
|
||||
tx.sdata = vif_to_sdata(info->control.vif);
|
||||
|
||||
if (txq->sta && !(info->flags & IEEE80211_TX_CTL_INJECTED)) {
|
||||
if (txq->sta) {
|
||||
tx.sta = container_of(txq->sta, struct sta_info, sta);
|
||||
/*
|
||||
* Drop unicast frames to unauthorised stations unless they are
|
||||
* EAPOL frames from the local station.
|
||||
* injected frames or EAPOL frames from the local station.
|
||||
*/
|
||||
if (unlikely(ieee80211_is_data(hdr->frame_control) &&
|
||||
if (unlikely(!(info->flags & IEEE80211_TX_CTL_INJECTED) &&
|
||||
ieee80211_is_data(hdr->frame_control) &&
|
||||
!ieee80211_vif_is_mesh(&tx.sdata->vif) &&
|
||||
tx.sdata->vif.type != NL80211_IFTYPE_OCB &&
|
||||
!is_multicast_ether_addr(hdr->addr1) &&
|
||||
|
|
|
@ -291,7 +291,7 @@ struct mptcp_sock *mptcp_token_iter_next(const struct net *net, long *s_slot,
|
|||
{
|
||||
struct mptcp_sock *ret = NULL;
|
||||
struct hlist_nulls_node *pos;
|
||||
int slot, num;
|
||||
int slot, num = 0;
|
||||
|
||||
for (slot = *s_slot; slot <= token_mask; *s_num = 0, slot++) {
|
||||
struct token_bucket *bucket = &token_hash[slot];
|
||||
|
|
|
@ -637,13 +637,14 @@ ip_set_match_extensions(struct ip_set *set, const struct ip_set_ext *ext,
|
|||
if (SET_WITH_COUNTER(set)) {
|
||||
struct ip_set_counter *counter = ext_counter(data, set);
|
||||
|
||||
ip_set_update_counter(counter, ext, flags);
|
||||
|
||||
if (flags & IPSET_FLAG_MATCH_COUNTERS &&
|
||||
!(ip_set_match_counter(ip_set_get_packets(counter),
|
||||
mext->packets, mext->packets_op) &&
|
||||
ip_set_match_counter(ip_set_get_bytes(counter),
|
||||
mext->bytes, mext->bytes_op)))
|
||||
return false;
|
||||
ip_set_update_counter(counter, ext, flags);
|
||||
}
|
||||
if (SET_WITH_SKBINFO(set))
|
||||
ip_set_get_skbinfo(ext_skbinfo(data, set),
|
||||
|
|
|
@ -742,12 +742,12 @@ static int ip_vs_route_me_harder(struct netns_ipvs *ipvs, int af,
|
|||
struct dst_entry *dst = skb_dst(skb);
|
||||
|
||||
if (dst->dev && !(dst->dev->flags & IFF_LOOPBACK) &&
|
||||
ip6_route_me_harder(ipvs->net, skb) != 0)
|
||||
ip6_route_me_harder(ipvs->net, skb->sk, skb) != 0)
|
||||
return 1;
|
||||
} else
|
||||
#endif
|
||||
if (!(skb_rtable(skb)->rt_flags & RTCF_LOCAL) &&
|
||||
ip_route_me_harder(ipvs->net, skb, RTN_LOCAL) != 0)
|
||||
ip_route_me_harder(ipvs->net, skb->sk, skb, RTN_LOCAL) != 0)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -715,7 +715,7 @@ nf_nat_ipv4_local_fn(void *priv, struct sk_buff *skb,
|
|||
|
||||
if (ct->tuplehash[dir].tuple.dst.u3.ip !=
|
||||
ct->tuplehash[!dir].tuple.src.u3.ip) {
|
||||
err = ip_route_me_harder(state->net, skb, RTN_UNSPEC);
|
||||
err = ip_route_me_harder(state->net, state->sk, skb, RTN_UNSPEC);
|
||||
if (err < 0)
|
||||
ret = NF_DROP_ERR(err);
|
||||
}
|
||||
|
@ -953,7 +953,7 @@ nf_nat_ipv6_local_fn(void *priv, struct sk_buff *skb,
|
|||
|
||||
if (!nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.dst.u3,
|
||||
&ct->tuplehash[!dir].tuple.src.u3)) {
|
||||
err = nf_ip6_route_me_harder(state->net, skb);
|
||||
err = nf_ip6_route_me_harder(state->net, state->sk, skb);
|
||||
if (err < 0)
|
||||
ret = NF_DROP_ERR(err);
|
||||
}
|
||||
|
|
|
@ -446,7 +446,7 @@ synproxy_send_tcp(struct net *net,
|
|||
|
||||
skb_dst_set_noref(nskb, skb_dst(skb));
|
||||
nskb->protocol = htons(ETH_P_IP);
|
||||
if (ip_route_me_harder(net, nskb, RTN_UNSPEC))
|
||||
if (ip_route_me_harder(net, nskb->sk, nskb, RTN_UNSPEC))
|
||||
goto free_nskb;
|
||||
|
||||
if (nfct) {
|
||||
|
|
|
@ -7137,7 +7137,7 @@ static void nf_tables_flowtable_notify(struct nft_ctx *ctx,
|
|||
GFP_KERNEL);
|
||||
kfree(buf);
|
||||
|
||||
if (ctx->report &&
|
||||
if (!ctx->report &&
|
||||
!nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
|
||||
return;
|
||||
|
||||
|
@ -7259,7 +7259,7 @@ static void nf_tables_gen_notify(struct net *net, struct sk_buff *skb,
|
|||
audit_log_nfcfg("?:0;?:0", 0, net->nft.base_seq,
|
||||
AUDIT_NFT_OP_GEN_REGISTER, GFP_KERNEL);
|
||||
|
||||
if (nlmsg_report(nlh) &&
|
||||
if (!nlmsg_report(nlh) &&
|
||||
!nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
|
||||
return;
|
||||
|
||||
|
@ -8053,12 +8053,16 @@ static void nf_tables_abort_release(struct nft_trans *trans)
|
|||
kfree(trans);
|
||||
}
|
||||
|
||||
static int __nf_tables_abort(struct net *net, bool autoload)
|
||||
static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action)
|
||||
{
|
||||
struct nft_trans *trans, *next;
|
||||
struct nft_trans_elem *te;
|
||||
struct nft_hook *hook;
|
||||
|
||||
if (action == NFNL_ABORT_VALIDATE &&
|
||||
nf_tables_validate(net) < 0)
|
||||
return -EAGAIN;
|
||||
|
||||
list_for_each_entry_safe_reverse(trans, next, &net->nft.commit_list,
|
||||
list) {
|
||||
switch (trans->msg_type) {
|
||||
|
@ -8190,7 +8194,7 @@ static int __nf_tables_abort(struct net *net, bool autoload)
|
|||
nf_tables_abort_release(trans);
|
||||
}
|
||||
|
||||
if (autoload)
|
||||
if (action == NFNL_ABORT_AUTOLOAD)
|
||||
nf_tables_module_autoload(net);
|
||||
else
|
||||
nf_tables_module_autoload_cleanup(net);
|
||||
|
@ -8203,9 +8207,10 @@ static void nf_tables_cleanup(struct net *net)
|
|||
nft_validate_state_update(net, NFT_VALIDATE_SKIP);
|
||||
}
|
||||
|
||||
static int nf_tables_abort(struct net *net, struct sk_buff *skb, bool autoload)
|
||||
static int nf_tables_abort(struct net *net, struct sk_buff *skb,
|
||||
enum nfnl_abort_action action)
|
||||
{
|
||||
int ret = __nf_tables_abort(net, autoload);
|
||||
int ret = __nf_tables_abort(net, action);
|
||||
|
||||
mutex_unlock(&net->nft.commit_mutex);
|
||||
|
||||
|
@ -8836,7 +8841,7 @@ static void __net_exit nf_tables_exit_net(struct net *net)
|
|||
{
|
||||
mutex_lock(&net->nft.commit_mutex);
|
||||
if (!list_empty(&net->nft.commit_list))
|
||||
__nf_tables_abort(net, false);
|
||||
__nf_tables_abort(net, NFNL_ABORT_NONE);
|
||||
__nft_release_tables(net);
|
||||
mutex_unlock(&net->nft.commit_mutex);
|
||||
WARN_ON_ONCE(!list_empty(&net->nft.tables));
|
||||
|
|
|
@ -333,7 +333,7 @@ static void nfnetlink_rcv_batch(struct sk_buff *skb, struct nlmsghdr *nlh,
|
|||
return netlink_ack(skb, nlh, -EINVAL, NULL);
|
||||
replay:
|
||||
status = 0;
|
||||
|
||||
replay_abort:
|
||||
skb = netlink_skb_clone(oskb, GFP_KERNEL);
|
||||
if (!skb)
|
||||
return netlink_ack(oskb, nlh, -ENOMEM, NULL);
|
||||
|
@ -499,7 +499,7 @@ ack:
|
|||
}
|
||||
done:
|
||||
if (status & NFNL_BATCH_REPLAY) {
|
||||
ss->abort(net, oskb, true);
|
||||
ss->abort(net, oskb, NFNL_ABORT_AUTOLOAD);
|
||||
nfnl_err_reset(&err_list);
|
||||
kfree_skb(skb);
|
||||
module_put(ss->owner);
|
||||
|
@ -510,11 +510,25 @@ done:
|
|||
status |= NFNL_BATCH_REPLAY;
|
||||
goto done;
|
||||
} else if (err) {
|
||||
ss->abort(net, oskb, false);
|
||||
ss->abort(net, oskb, NFNL_ABORT_NONE);
|
||||
netlink_ack(oskb, nlmsg_hdr(oskb), err, NULL);
|
||||
}
|
||||
} else {
|
||||
ss->abort(net, oskb, false);
|
||||
enum nfnl_abort_action abort_action;
|
||||
|
||||
if (status & NFNL_BATCH_FAILURE)
|
||||
abort_action = NFNL_ABORT_NONE;
|
||||
else
|
||||
abort_action = NFNL_ABORT_VALIDATE;
|
||||
|
||||
err = ss->abort(net, oskb, abort_action);
|
||||
if (err == -EAGAIN) {
|
||||
nfnl_err_reset(&err_list);
|
||||
kfree_skb(skb);
|
||||
module_put(ss->owner);
|
||||
status |= NFNL_BATCH_FAILURE;
|
||||
goto replay_abort;
|
||||
}
|
||||
}
|
||||
if (ss->cleanup)
|
||||
ss->cleanup(net);
|
||||
|
|
|
@ -42,7 +42,7 @@ static unsigned int nf_route_table_hook4(void *priv,
|
|||
iph->daddr != daddr ||
|
||||
skb->mark != mark ||
|
||||
iph->tos != tos) {
|
||||
err = ip_route_me_harder(state->net, skb, RTN_UNSPEC);
|
||||
err = ip_route_me_harder(state->net, state->sk, skb, RTN_UNSPEC);
|
||||
if (err < 0)
|
||||
ret = NF_DROP_ERR(err);
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ static unsigned int nf_route_table_hook6(void *priv,
|
|||
skb->mark != mark ||
|
||||
ipv6_hdr(skb)->hop_limit != hop_limit ||
|
||||
flowlabel != *((u32 *)ipv6_hdr(skb)))) {
|
||||
err = nf_ip6_route_me_harder(state->net, skb);
|
||||
err = nf_ip6_route_me_harder(state->net, state->sk, skb);
|
||||
if (err < 0)
|
||||
ret = NF_DROP_ERR(err);
|
||||
}
|
||||
|
|
|
@ -191,8 +191,8 @@ static int nf_ip_reroute(struct sk_buff *skb, const struct nf_queue_entry *entry
|
|||
skb->mark == rt_info->mark &&
|
||||
iph->daddr == rt_info->daddr &&
|
||||
iph->saddr == rt_info->saddr))
|
||||
return ip_route_me_harder(entry->state.net, skb,
|
||||
RTN_UNSPEC);
|
||||
return ip_route_me_harder(entry->state.net, entry->state.sk,
|
||||
skb, RTN_UNSPEC);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
|
|
|
@ -1703,13 +1703,13 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
|
|||
parms.port_no = OVSP_LOCAL;
|
||||
parms.upcall_portids = a[OVS_DP_ATTR_UPCALL_PID];
|
||||
|
||||
err = ovs_dp_change(dp, a);
|
||||
if (err)
|
||||
goto err_destroy_meters;
|
||||
|
||||
/* So far only local changes have been made, now need the lock. */
|
||||
ovs_lock();
|
||||
|
||||
err = ovs_dp_change(dp, a);
|
||||
if (err)
|
||||
goto err_unlock_and_destroy_meters;
|
||||
|
||||
vport = new_vport(&parms);
|
||||
if (IS_ERR(vport)) {
|
||||
err = PTR_ERR(vport);
|
||||
|
@ -1725,8 +1725,7 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
|
|||
ovs_dp_reset_user_features(skb, info);
|
||||
}
|
||||
|
||||
ovs_unlock();
|
||||
goto err_destroy_meters;
|
||||
goto err_unlock_and_destroy_meters;
|
||||
}
|
||||
|
||||
err = ovs_dp_cmd_fill_info(dp, reply, info->snd_portid,
|
||||
|
@ -1741,7 +1740,8 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
|
|||
ovs_notify(&dp_datapath_genl_family, reply, info);
|
||||
return 0;
|
||||
|
||||
err_destroy_meters:
|
||||
err_unlock_and_destroy_meters:
|
||||
ovs_unlock();
|
||||
ovs_meters_exit(dp);
|
||||
err_destroy_ports:
|
||||
kfree(dp->ports);
|
||||
|
|
|
@ -390,7 +390,7 @@ static struct mask_cache *tbl_mask_cache_alloc(u32 size)
|
|||
}
|
||||
int ovs_flow_tbl_masks_cache_resize(struct flow_table *table, u32 size)
|
||||
{
|
||||
struct mask_cache *mc = rcu_dereference(table->mask_cache);
|
||||
struct mask_cache *mc = rcu_dereference_ovsl(table->mask_cache);
|
||||
struct mask_cache *new;
|
||||
|
||||
if (size == mc->cache_size)
|
||||
|
|
|
@ -1601,12 +1601,12 @@ static int sctp_cmd_interpreter(enum sctp_event_type event_type,
|
|||
break;
|
||||
|
||||
case SCTP_CMD_INIT_FAILED:
|
||||
sctp_cmd_init_failed(commands, asoc, cmd->obj.u32);
|
||||
sctp_cmd_init_failed(commands, asoc, cmd->obj.u16);
|
||||
break;
|
||||
|
||||
case SCTP_CMD_ASSOC_FAILED:
|
||||
sctp_cmd_assoc_failed(commands, asoc, event_type,
|
||||
subtype, chunk, cmd->obj.u32);
|
||||
subtype, chunk, cmd->obj.u16);
|
||||
break;
|
||||
|
||||
case SCTP_CMD_INIT_COUNTER_INC:
|
||||
|
|
|
@ -1250,8 +1250,7 @@ void cfg80211_stop_iface(struct wiphy *wiphy, struct wireless_dev *wdev,
|
|||
}
|
||||
EXPORT_SYMBOL(cfg80211_stop_iface);
|
||||
|
||||
void cfg80211_init_wdev(struct cfg80211_registered_device *rdev,
|
||||
struct wireless_dev *wdev)
|
||||
void cfg80211_init_wdev(struct wireless_dev *wdev)
|
||||
{
|
||||
mutex_init(&wdev->mtx);
|
||||
INIT_LIST_HEAD(&wdev->event_list);
|
||||
|
@ -1262,6 +1261,30 @@ void cfg80211_init_wdev(struct cfg80211_registered_device *rdev,
|
|||
spin_lock_init(&wdev->pmsr_lock);
|
||||
INIT_WORK(&wdev->pmsr_free_wk, cfg80211_pmsr_free_wk);
|
||||
|
||||
#ifdef CONFIG_CFG80211_WEXT
|
||||
wdev->wext.default_key = -1;
|
||||
wdev->wext.default_mgmt_key = -1;
|
||||
wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
|
||||
#endif
|
||||
|
||||
if (wdev->wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT)
|
||||
wdev->ps = true;
|
||||
else
|
||||
wdev->ps = false;
|
||||
/* allow mac80211 to determine the timeout */
|
||||
wdev->ps_timeout = -1;
|
||||
|
||||
if ((wdev->iftype == NL80211_IFTYPE_STATION ||
|
||||
wdev->iftype == NL80211_IFTYPE_P2P_CLIENT ||
|
||||
wdev->iftype == NL80211_IFTYPE_ADHOC) && !wdev->use_4addr)
|
||||
wdev->netdev->priv_flags |= IFF_DONT_BRIDGE;
|
||||
|
||||
INIT_WORK(&wdev->disconnect_wk, cfg80211_autodisconnect_wk);
|
||||
}
|
||||
|
||||
void cfg80211_register_wdev(struct cfg80211_registered_device *rdev,
|
||||
struct wireless_dev *wdev)
|
||||
{
|
||||
/*
|
||||
* We get here also when the interface changes network namespaces,
|
||||
* as it's registered into the new one, but we don't want it to
|
||||
|
@ -1295,6 +1318,11 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
|
|||
switch (state) {
|
||||
case NETDEV_POST_INIT:
|
||||
SET_NETDEV_DEVTYPE(dev, &wiphy_type);
|
||||
wdev->netdev = dev;
|
||||
/* can only change netns with wiphy */
|
||||
dev->features |= NETIF_F_NETNS_LOCAL;
|
||||
|
||||
cfg80211_init_wdev(wdev);
|
||||
break;
|
||||
case NETDEV_REGISTER:
|
||||
/*
|
||||
|
@ -1302,35 +1330,12 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
|
|||
* called within code protected by it when interfaces
|
||||
* are added with nl80211.
|
||||
*/
|
||||
/* can only change netns with wiphy */
|
||||
dev->features |= NETIF_F_NETNS_LOCAL;
|
||||
|
||||
if (sysfs_create_link(&dev->dev.kobj, &rdev->wiphy.dev.kobj,
|
||||
"phy80211")) {
|
||||
pr_err("failed to add phy80211 symlink to netdev!\n");
|
||||
}
|
||||
wdev->netdev = dev;
|
||||
#ifdef CONFIG_CFG80211_WEXT
|
||||
wdev->wext.default_key = -1;
|
||||
wdev->wext.default_mgmt_key = -1;
|
||||
wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
|
||||
#endif
|
||||
|
||||
if (wdev->wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT)
|
||||
wdev->ps = true;
|
||||
else
|
||||
wdev->ps = false;
|
||||
/* allow mac80211 to determine the timeout */
|
||||
wdev->ps_timeout = -1;
|
||||
|
||||
if ((wdev->iftype == NL80211_IFTYPE_STATION ||
|
||||
wdev->iftype == NL80211_IFTYPE_P2P_CLIENT ||
|
||||
wdev->iftype == NL80211_IFTYPE_ADHOC) && !wdev->use_4addr)
|
||||
dev->priv_flags |= IFF_DONT_BRIDGE;
|
||||
|
||||
INIT_WORK(&wdev->disconnect_wk, cfg80211_autodisconnect_wk);
|
||||
|
||||
cfg80211_init_wdev(rdev, wdev);
|
||||
cfg80211_register_wdev(rdev, wdev);
|
||||
break;
|
||||
case NETDEV_GOING_DOWN:
|
||||
cfg80211_leave(rdev, wdev);
|
||||
|
|
|
@ -209,8 +209,9 @@ struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx);
|
|||
int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
|
||||
struct net *net);
|
||||
|
||||
void cfg80211_init_wdev(struct cfg80211_registered_device *rdev,
|
||||
struct wireless_dev *wdev);
|
||||
void cfg80211_init_wdev(struct wireless_dev *wdev);
|
||||
void cfg80211_register_wdev(struct cfg80211_registered_device *rdev,
|
||||
struct wireless_dev *wdev);
|
||||
|
||||
static inline void wdev_lock(struct wireless_dev *wdev)
|
||||
__acquires(wdev)
|
||||
|
|
|
@ -3885,7 +3885,8 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
|
|||
* P2P Device and NAN do not have a netdev, so don't go
|
||||
* through the netdev notifier and must be added here
|
||||
*/
|
||||
cfg80211_init_wdev(rdev, wdev);
|
||||
cfg80211_init_wdev(wdev);
|
||||
cfg80211_register_wdev(rdev, wdev);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -3616,7 +3616,7 @@ static void print_rd_rules(const struct ieee80211_regdomain *rd)
|
|||
power_rule = ®_rule->power_rule;
|
||||
|
||||
if (reg_rule->flags & NL80211_RRF_AUTO_BW)
|
||||
snprintf(bw, sizeof(bw), "%d KHz, %d KHz AUTO",
|
||||
snprintf(bw, sizeof(bw), "%d KHz, %u KHz AUTO",
|
||||
freq_range->max_bandwidth_khz,
|
||||
reg_get_max_bandwidth(rd, reg_rule));
|
||||
else
|
||||
|
|
|
@ -803,14 +803,14 @@ static struct xfrm6_tunnel xfrmi_ipv6_handler __read_mostly = {
|
|||
.handler = xfrmi6_rcv_tunnel,
|
||||
.cb_handler = xfrmi_rcv_cb,
|
||||
.err_handler = xfrmi6_err,
|
||||
.priority = -1,
|
||||
.priority = 2,
|
||||
};
|
||||
|
||||
static struct xfrm6_tunnel xfrmi_ip6ip_handler __read_mostly = {
|
||||
.handler = xfrmi6_rcv_tunnel,
|
||||
.cb_handler = xfrmi_rcv_cb,
|
||||
.err_handler = xfrmi6_err,
|
||||
.priority = -1,
|
||||
.priority = 2,
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -848,14 +848,14 @@ static struct xfrm_tunnel xfrmi_ipip_handler __read_mostly = {
|
|||
.handler = xfrmi4_rcv_tunnel,
|
||||
.cb_handler = xfrmi_rcv_cb,
|
||||
.err_handler = xfrmi4_err,
|
||||
.priority = -1,
|
||||
.priority = 3,
|
||||
};
|
||||
|
||||
static struct xfrm_tunnel xfrmi_ipip6_handler __read_mostly = {
|
||||
.handler = xfrmi4_rcv_tunnel,
|
||||
.cb_handler = xfrmi_rcv_cb,
|
||||
.err_handler = xfrmi4_err,
|
||||
.priority = -1,
|
||||
.priority = 2,
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
|
@ -2004,6 +2004,7 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
|
|||
int err = -ENOENT;
|
||||
__be32 minspi = htonl(low);
|
||||
__be32 maxspi = htonl(high);
|
||||
__be32 newspi = 0;
|
||||
u32 mark = x->mark.v & x->mark.m;
|
||||
|
||||
spin_lock_bh(&x->lock);
|
||||
|
@ -2022,21 +2023,22 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
|
|||
xfrm_state_put(x0);
|
||||
goto unlock;
|
||||
}
|
||||
x->id.spi = minspi;
|
||||
newspi = minspi;
|
||||
} else {
|
||||
u32 spi = 0;
|
||||
for (h = 0; h < high-low+1; h++) {
|
||||
spi = low + prandom_u32()%(high-low+1);
|
||||
x0 = xfrm_state_lookup(net, mark, &x->id.daddr, htonl(spi), x->id.proto, x->props.family);
|
||||
if (x0 == NULL) {
|
||||
x->id.spi = htonl(spi);
|
||||
newspi = htonl(spi);
|
||||
break;
|
||||
}
|
||||
xfrm_state_put(x0);
|
||||
}
|
||||
}
|
||||
if (x->id.spi) {
|
||||
if (newspi) {
|
||||
spin_lock_bh(&net->xfrm.xfrm_state_lock);
|
||||
x->id.spi = newspi;
|
||||
h = xfrm_spi_hash(net, &x->id.daddr, x->id.spi, x->id.proto, x->props.family);
|
||||
hlist_add_head_rcu(&x->byspi, net->xfrm.state_byspi + h);
|
||||
spin_unlock_bh(&net->xfrm.xfrm_state_lock);
|
||||
|
|
|
@ -316,6 +316,14 @@ pp sleep 3
|
|||
n2 ping -W 1 -c 1 192.168.241.1
|
||||
n1 wg set wg0 peer "$pub2" persistent-keepalive 0
|
||||
|
||||
# Test that sk_bound_dev_if works
|
||||
n1 ping -I wg0 -c 1 -W 1 192.168.241.2
|
||||
# What about when the mark changes and the packet must be rerouted?
|
||||
n1 iptables -t mangle -I OUTPUT -j MARK --set-xmark 1
|
||||
n1 ping -c 1 -W 1 192.168.241.2 # First the boring case
|
||||
n1 ping -I wg0 -c 1 -W 1 192.168.241.2 # Then the sk_bound_dev_if case
|
||||
n1 iptables -t mangle -D OUTPUT -j MARK --set-xmark 1
|
||||
|
||||
# Test that onion routing works, even when it loops
|
||||
n1 wg set wg0 peer "$pub3" allowed-ips 192.168.242.2/32 endpoint 192.168.241.2:5
|
||||
ip1 addr add 192.168.242.1/24 dev wg0
|
||||
|
|
|
@ -18,10 +18,12 @@ CONFIG_NF_NAT=y
|
|||
CONFIG_NETFILTER_XTABLES=y
|
||||
CONFIG_NETFILTER_XT_NAT=y
|
||||
CONFIG_NETFILTER_XT_MATCH_LENGTH=y
|
||||
CONFIG_NETFILTER_XT_MARK=y
|
||||
CONFIG_NF_CONNTRACK_IPV4=y
|
||||
CONFIG_NF_NAT_IPV4=y
|
||||
CONFIG_IP_NF_IPTABLES=y
|
||||
CONFIG_IP_NF_FILTER=y
|
||||
CONFIG_IP_NF_MANGLE=y
|
||||
CONFIG_IP_NF_NAT=y
|
||||
CONFIG_IP_ADVANCED_ROUTER=y
|
||||
CONFIG_IP_MULTIPLE_TABLES=y
|
||||
|
|
Loading…
Reference in New Issue