mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/
synced 2025-04-19 20:58:31 +09:00
Including fixes from netfilter.
Current release - regressions: - 4 fixes for the netdev per-instance locking Current release - new code bugs: - consolidate more code between existing Rx zero-copy and uring so that the latter doesn't miss / have to duplicate the safety checks Previous releases - regressions: - ipv6: fix omitted Netlink attributes when using SKIP_STATS Previous releases - always broken: - net: fix geneve_opt length integer overflow - udp: fix multiple wrap arounds of sk->sk_rmem_alloc when it approaches INT_MAX - dsa: mvpp2: add a lock to avoid corruption of the shared TCAM - dsa: airoha: fix issues with traffic QoS configuration / offload, and flow table offload Misc: - touch up the Netlink YAML specs of old families to make them usable for user space C codegen Signed-off-by: Jakub Kicinski <kuba@kernel.org> -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE6jPA+I1ugmIBA4hXMUZtbf5SIrsFAmfv+nEACgkQMUZtbf5S Irs01A//d20bpdDVz2sRLdAzzIaGDLdOmw4T92e9eW7WkhUSGNAG7vZCv5lanIxq toQMLAahyJrMdizGPLfhH+csz3eQMwYUwlIRXNfJTEdk9o/+naWdtzbPDJdjcAu/ jRwOKx44JtbXIwmzFe/vNwP8ex+JMZqjvdcCZcJONc4XVpHeAeKbPsd9c8aX8DR2 pSMR/3mpAHXFd54mFVUSEDXCZBClpAT0sjZ4RMt3pZKELp+8N2AAi0nFt9r0W+YB ZPhYX2hSJ+msuUa24jeBHWhrxvV/PVbKDg7S58F6+Us2hDKyYx9k6IEQeadntd9c EzZSboSgzjf1ew6Yuitv1o9b/C1NCdzflES7kXgibFGUJ+6bP2pv5bgOc4mDhTz4 zeY9EqxguN1dpFX+Y7gyCQcUe/6UACi6Y4h1aCmdZkCoenf9FsJPoeSWWqmttDNN 5DEx3szJZKY+O4okmfpCFJ1SnfEe9E4Ek/+s6aIWNXu6C3EsnX6Q8Kj4Qz74UuLP LpGFCqRwpDLyfqZIEaX6Ed6sWykLg6TWU0/B2jWmFyQ/KQCCjhL79iaDllAMOOoT hN5sJAUiHk1QoMBW37nEu/WYWX5vqCVhltJBfPVtVS9dgJQChDCp/mrJ9ZJi3wof FyPeLaOh9N6IhR+L4Iipvuu/94dfPHtj8o5dnPkrh1fwxueUFFI= =phQZ -----END PGP SIGNATURE----- Merge tag 'net-6.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net Pull networking fixes from Jakub Kicinski: "Including fixes from netfilter. Current release - regressions: - four fixes for the netdev per-instance locking Current release - new code bugs: - consolidate more code between existing Rx zero-copy and uring so that the latter doesn't miss / have to duplicate the safety checks Previous releases - regressions: - ipv6: fix omitted Netlink attributes when using SKIP_STATS Previous releases - always broken: - net: fix geneve_opt length integer overflow - udp: fix multiple wrap arounds of sk->sk_rmem_alloc when it approaches INT_MAX - dsa: mvpp2: add a lock to avoid corruption of the shared TCAM - dsa: airoha: fix issues with traffic QoS configuration / offload, and flow table offload Misc: - touch up the Netlink YAML specs of old families to make them usable for user space C codegen" * tag 'net-6.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (56 commits) selftests: net: amt: indicate progress in the stress test netlink: specs: rt_route: pull the ifa- prefix out of the names netlink: specs: rt_addr: pull the ifa- prefix out of the names netlink: specs: rt_addr: fix get multi command name netlink: specs: rt_addr: fix the spec format / schema failures net: avoid false positive warnings in __net_mp_close_rxq() net: move mp dev config validation to __net_mp_open_rxq() net: ibmveth: make veth_pool_store stop hanging arcnet: Add NULL check in com20020pci_probe() ipv6: Do not consider link down nexthops in path selection ipv6: Start path selection from the first nexthop usbnet:fix NPE during rx_complete net: octeontx2: Handle XDP_ABORTED and XDP invalid as XDP_DROP net: fix geneve_opt length integer overflow io_uring/zcrx: fix selftests w/ updated netdev Python helpers selftests: net: use netdevsim in netns test docs: net: document netdev notifier expectations net: dummy: request ops lock netdevsim: add dummy device notifiers net: rename rtnl_net_debug to lock_debug ...
This commit is contained in:
commit
61f96e684e
4
CREDITS
4
CREDITS
@ -3670,6 +3670,10 @@ S: 149 Union St.
|
||||
S: Kingston, Ontario
|
||||
S: Canada K7L 2P4
|
||||
|
||||
N: Pravin B Shelar
|
||||
E: pshelar@ovn.org
|
||||
D: Open vSwitch maintenance and contributions
|
||||
|
||||
N: John Shifflett
|
||||
E: john@geolog.com
|
||||
E: jshiffle@netcom.com
|
||||
|
@ -78,45 +78,46 @@ definitions:
|
||||
attribute-sets:
|
||||
-
|
||||
name: addr-attrs
|
||||
name-prefix: ifa-
|
||||
attributes:
|
||||
-
|
||||
name: ifa-address
|
||||
name: address
|
||||
type: binary
|
||||
display-hint: ipv4
|
||||
-
|
||||
name: ifa-local
|
||||
name: local
|
||||
type: binary
|
||||
display-hint: ipv4
|
||||
-
|
||||
name: ifa-label
|
||||
name: label
|
||||
type: string
|
||||
-
|
||||
name: ifa-broadcast
|
||||
name: broadcast
|
||||
type: binary
|
||||
display-hint: ipv4
|
||||
-
|
||||
name: ifa-anycast
|
||||
name: anycast
|
||||
type: binary
|
||||
-
|
||||
name: ifa-cacheinfo
|
||||
name: cacheinfo
|
||||
type: binary
|
||||
struct: ifa-cacheinfo
|
||||
-
|
||||
name: ifa-multicast
|
||||
name: multicast
|
||||
type: binary
|
||||
-
|
||||
name: ifa-flags
|
||||
name: flags
|
||||
type: u32
|
||||
enum: ifa-flags
|
||||
enum-as-flags: true
|
||||
-
|
||||
name: ifa-rt-priority
|
||||
name: rt-priority
|
||||
type: u32
|
||||
-
|
||||
name: ifa-target-netnsid
|
||||
name: target-netnsid
|
||||
type: binary
|
||||
-
|
||||
name: ifa-proto
|
||||
name: proto
|
||||
type: u8
|
||||
|
||||
|
||||
@ -137,10 +138,10 @@ operations:
|
||||
- ifa-prefixlen
|
||||
- ifa-scope
|
||||
- ifa-index
|
||||
- ifa-address
|
||||
- ifa-label
|
||||
- ifa-local
|
||||
- ifa-cacheinfo
|
||||
- address
|
||||
- label
|
||||
- local
|
||||
- cacheinfo
|
||||
-
|
||||
name: deladdr
|
||||
doc: Remove address
|
||||
@ -154,8 +155,8 @@ operations:
|
||||
- ifa-prefixlen
|
||||
- ifa-scope
|
||||
- ifa-index
|
||||
- ifa-address
|
||||
- ifa-local
|
||||
- address
|
||||
- local
|
||||
-
|
||||
name: getaddr
|
||||
doc: Dump address information.
|
||||
@ -169,7 +170,7 @@ operations:
|
||||
value: 20
|
||||
attributes: *ifaddr-all
|
||||
-
|
||||
name: getmaddrs
|
||||
name: getmulticast
|
||||
doc: Get / dump IPv4/IPv6 multicast addresses.
|
||||
attribute-set: addr-attrs
|
||||
fixed-header: ifaddrmsg
|
||||
@ -182,11 +183,12 @@ operations:
|
||||
reply:
|
||||
value: 58
|
||||
attributes: &mcaddr-attrs
|
||||
- ifa-multicast
|
||||
- ifa-cacheinfo
|
||||
- multicast
|
||||
- cacheinfo
|
||||
dump:
|
||||
request:
|
||||
value: 58
|
||||
attributes:
|
||||
- ifa-family
|
||||
reply:
|
||||
value: 58
|
||||
|
@ -80,165 +80,167 @@ definitions:
|
||||
attribute-sets:
|
||||
-
|
||||
name: route-attrs
|
||||
name-prefix: rta-
|
||||
attributes:
|
||||
-
|
||||
name: rta-dst
|
||||
name: dst
|
||||
type: binary
|
||||
display-hint: ipv4
|
||||
-
|
||||
name: rta-src
|
||||
name: src
|
||||
type: binary
|
||||
display-hint: ipv4
|
||||
-
|
||||
name: rta-iif
|
||||
name: iif
|
||||
type: u32
|
||||
-
|
||||
name: rta-oif
|
||||
name: oif
|
||||
type: u32
|
||||
-
|
||||
name: rta-gateway
|
||||
name: gateway
|
||||
type: binary
|
||||
display-hint: ipv4
|
||||
-
|
||||
name: rta-priority
|
||||
name: priority
|
||||
type: u32
|
||||
-
|
||||
name: rta-prefsrc
|
||||
name: prefsrc
|
||||
type: binary
|
||||
display-hint: ipv4
|
||||
-
|
||||
name: rta-metrics
|
||||
name: metrics
|
||||
type: nest
|
||||
nested-attributes: rta-metrics
|
||||
nested-attributes: metrics
|
||||
-
|
||||
name: rta-multipath
|
||||
name: multipath
|
||||
type: binary
|
||||
-
|
||||
name: rta-protoinfo # not used
|
||||
name: protoinfo # not used
|
||||
type: binary
|
||||
-
|
||||
name: rta-flow
|
||||
name: flow
|
||||
type: u32
|
||||
-
|
||||
name: rta-cacheinfo
|
||||
name: cacheinfo
|
||||
type: binary
|
||||
struct: rta-cacheinfo
|
||||
-
|
||||
name: rta-session # not used
|
||||
name: session # not used
|
||||
type: binary
|
||||
-
|
||||
name: rta-mp-algo # not used
|
||||
name: mp-algo # not used
|
||||
type: binary
|
||||
-
|
||||
name: rta-table
|
||||
name: table
|
||||
type: u32
|
||||
-
|
||||
name: rta-mark
|
||||
name: mark
|
||||
type: u32
|
||||
-
|
||||
name: rta-mfc-stats
|
||||
name: mfc-stats
|
||||
type: binary
|
||||
-
|
||||
name: rta-via
|
||||
name: via
|
||||
type: binary
|
||||
-
|
||||
name: rta-newdst
|
||||
name: newdst
|
||||
type: binary
|
||||
-
|
||||
name: rta-pref
|
||||
name: pref
|
||||
type: u8
|
||||
-
|
||||
name: rta-encap-type
|
||||
name: encap-type
|
||||
type: u16
|
||||
-
|
||||
name: rta-encap
|
||||
name: encap
|
||||
type: binary # tunnel specific nest
|
||||
-
|
||||
name: rta-expires
|
||||
name: expires
|
||||
type: u32
|
||||
-
|
||||
name: rta-pad
|
||||
name: pad
|
||||
type: binary
|
||||
-
|
||||
name: rta-uid
|
||||
name: uid
|
||||
type: u32
|
||||
-
|
||||
name: rta-ttl-propagate
|
||||
name: ttl-propagate
|
||||
type: u8
|
||||
-
|
||||
name: rta-ip-proto
|
||||
name: ip-proto
|
||||
type: u8
|
||||
-
|
||||
name: rta-sport
|
||||
name: sport
|
||||
type: u16
|
||||
-
|
||||
name: rta-dport
|
||||
name: dport
|
||||
type: u16
|
||||
-
|
||||
name: rta-nh-id
|
||||
name: nh-id
|
||||
type: u32
|
||||
-
|
||||
name: rta-flowlabel
|
||||
name: flowlabel
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
display-hint: hex
|
||||
-
|
||||
name: rta-metrics
|
||||
name: metrics
|
||||
name-prefix: rtax-
|
||||
attributes:
|
||||
-
|
||||
name: rtax-unspec
|
||||
name: unspec
|
||||
type: unused
|
||||
value: 0
|
||||
-
|
||||
name: rtax-lock
|
||||
name: lock
|
||||
type: u32
|
||||
-
|
||||
name: rtax-mtu
|
||||
name: mtu
|
||||
type: u32
|
||||
-
|
||||
name: rtax-window
|
||||
name: window
|
||||
type: u32
|
||||
-
|
||||
name: rtax-rtt
|
||||
name: rtt
|
||||
type: u32
|
||||
-
|
||||
name: rtax-rttvar
|
||||
name: rttvar
|
||||
type: u32
|
||||
-
|
||||
name: rtax-ssthresh
|
||||
name: ssthresh
|
||||
type: u32
|
||||
-
|
||||
name: rtax-cwnd
|
||||
name: cwnd
|
||||
type: u32
|
||||
-
|
||||
name: rtax-advmss
|
||||
name: advmss
|
||||
type: u32
|
||||
-
|
||||
name: rtax-reordering
|
||||
name: reordering
|
||||
type: u32
|
||||
-
|
||||
name: rtax-hoplimit
|
||||
name: hoplimit
|
||||
type: u32
|
||||
-
|
||||
name: rtax-initcwnd
|
||||
name: initcwnd
|
||||
type: u32
|
||||
-
|
||||
name: rtax-features
|
||||
name: features
|
||||
type: u32
|
||||
-
|
||||
name: rtax-rto-min
|
||||
name: rto-min
|
||||
type: u32
|
||||
-
|
||||
name: rtax-initrwnd
|
||||
name: initrwnd
|
||||
type: u32
|
||||
-
|
||||
name: rtax-quickack
|
||||
name: quickack
|
||||
type: u32
|
||||
-
|
||||
name: rtax-cc-algo
|
||||
name: cc-algo
|
||||
type: string
|
||||
-
|
||||
name: rtax-fastopen-no-cookie
|
||||
name: fastopen-no-cookie
|
||||
type: u32
|
||||
|
||||
operations:
|
||||
@ -254,18 +256,18 @@ operations:
|
||||
value: 26
|
||||
attributes:
|
||||
- rtm-family
|
||||
- rta-src
|
||||
- src
|
||||
- rtm-src-len
|
||||
- rta-dst
|
||||
- dst
|
||||
- rtm-dst-len
|
||||
- rta-iif
|
||||
- rta-oif
|
||||
- rta-ip-proto
|
||||
- rta-sport
|
||||
- rta-dport
|
||||
- rta-mark
|
||||
- rta-uid
|
||||
- rta-flowlabel
|
||||
- iif
|
||||
- oif
|
||||
- ip-proto
|
||||
- sport
|
||||
- dport
|
||||
- mark
|
||||
- uid
|
||||
- flowlabel
|
||||
reply:
|
||||
value: 24
|
||||
attributes: &all-route-attrs
|
||||
@ -278,34 +280,34 @@ operations:
|
||||
- rtm-scope
|
||||
- rtm-type
|
||||
- rtm-flags
|
||||
- rta-dst
|
||||
- rta-src
|
||||
- rta-iif
|
||||
- rta-oif
|
||||
- rta-gateway
|
||||
- rta-priority
|
||||
- rta-prefsrc
|
||||
- rta-metrics
|
||||
- rta-multipath
|
||||
- rta-flow
|
||||
- rta-cacheinfo
|
||||
- rta-table
|
||||
- rta-mark
|
||||
- rta-mfc-stats
|
||||
- rta-via
|
||||
- rta-newdst
|
||||
- rta-pref
|
||||
- rta-encap-type
|
||||
- rta-encap
|
||||
- rta-expires
|
||||
- rta-pad
|
||||
- rta-uid
|
||||
- rta-ttl-propagate
|
||||
- rta-ip-proto
|
||||
- rta-sport
|
||||
- rta-dport
|
||||
- rta-nh-id
|
||||
- rta-flowlabel
|
||||
- dst
|
||||
- src
|
||||
- iif
|
||||
- oif
|
||||
- gateway
|
||||
- priority
|
||||
- prefsrc
|
||||
- metrics
|
||||
- multipath
|
||||
- flow
|
||||
- cacheinfo
|
||||
- table
|
||||
- mark
|
||||
- mfc-stats
|
||||
- via
|
||||
- newdst
|
||||
- pref
|
||||
- encap-type
|
||||
- encap
|
||||
- expires
|
||||
- pad
|
||||
- uid
|
||||
- ttl-propagate
|
||||
- ip-proto
|
||||
- sport
|
||||
- dport
|
||||
- nh-id
|
||||
- flowlabel
|
||||
dump:
|
||||
request:
|
||||
value: 26
|
||||
|
@ -343,6 +343,29 @@ there are two sets of interfaces: ``dev_xxx`` and ``netif_xxx`` (e.g.,
|
||||
acquiring the instance lock themselves, while the ``netif_xxx`` functions
|
||||
assume that the driver has already acquired the instance lock.
|
||||
|
||||
Notifiers and netdev instance lock
|
||||
==================================
|
||||
|
||||
For device drivers that implement shaping or queue management APIs,
|
||||
some of the notifiers (``enum netdev_cmd``) are running under the netdev
|
||||
instance lock.
|
||||
|
||||
For devices with locked ops, currently only the following notifiers are
|
||||
running under the lock:
|
||||
* ``NETDEV_REGISTER``
|
||||
* ``NETDEV_UP``
|
||||
|
||||
The following notifiers are running without the lock:
|
||||
* ``NETDEV_UNREGISTER``
|
||||
|
||||
There are no clear expectations for the remaining notifiers. Notifiers not on
|
||||
the list may run with or without the instance lock, potentially even invoking
|
||||
the same notifier type with and without the lock from different code paths.
|
||||
The goal is to eventually ensure that all (or most, with a few documented
|
||||
exceptions) notifiers run under the instance lock. Please extend this
|
||||
documentation whenever you make explicit assumption about lock being held
|
||||
from a notifier.
|
||||
|
||||
NETDEV_INTERNAL symbol namespace
|
||||
================================
|
||||
|
||||
|
10
MAINTAINERS
10
MAINTAINERS
@ -18131,7 +18131,9 @@ F: drivers/irqchip/irq-ompic.c
|
||||
F: drivers/irqchip/irq-or1k-*
|
||||
|
||||
OPENVSWITCH
|
||||
M: Pravin B Shelar <pshelar@ovn.org>
|
||||
M: Aaron Conole <aconole@redhat.com>
|
||||
M: Eelco Chaudron <echaudro@redhat.com>
|
||||
M: Ilya Maximets <i.maximets@ovn.org>
|
||||
L: netdev@vger.kernel.org
|
||||
L: dev@openvswitch.org
|
||||
S: Maintained
|
||||
@ -19903,7 +19905,7 @@ F: Documentation/devicetree/bindings/i2c/qcom,i2c-geni-qcom.yaml
|
||||
F: drivers/i2c/busses/i2c-qcom-geni.c
|
||||
|
||||
QUALCOMM I2C CCI DRIVER
|
||||
M: Loic Poulain <loic.poulain@linaro.org>
|
||||
M: Loic Poulain <loic.poulain@oss.qualcomm.com>
|
||||
M: Robert Foss <rfoss@kernel.org>
|
||||
L: linux-i2c@vger.kernel.org
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
@ -20036,7 +20038,7 @@ F: Documentation/devicetree/bindings/media/*venus*
|
||||
F: drivers/media/platform/qcom/venus/
|
||||
|
||||
QUALCOMM WCN36XX WIRELESS DRIVER
|
||||
M: Loic Poulain <loic.poulain@linaro.org>
|
||||
M: Loic Poulain <loic.poulain@oss.qualcomm.com>
|
||||
L: wcn36xx@lists.infradead.org
|
||||
S: Supported
|
||||
W: https://wireless.wiki.kernel.org/en/users/Drivers/wcn36xx
|
||||
@ -26075,7 +26077,7 @@ F: kernel/workqueue.c
|
||||
F: kernel/workqueue_internal.h
|
||||
|
||||
WWAN DRIVERS
|
||||
M: Loic Poulain <loic.poulain@linaro.org>
|
||||
M: Loic Poulain <loic.poulain@oss.qualcomm.com>
|
||||
M: Sergey Ryazanov <ryazanov.s.a@gmail.com>
|
||||
R: Johannes Berg <johannes@sipsolutions.net>
|
||||
L: netdev@vger.kernel.org
|
||||
|
@ -251,18 +251,33 @@ static int com20020pci_probe(struct pci_dev *pdev,
|
||||
card->tx_led.default_trigger = devm_kasprintf(&pdev->dev,
|
||||
GFP_KERNEL, "arc%d-%d-tx",
|
||||
dev->dev_id, i);
|
||||
if (!card->tx_led.default_trigger) {
|
||||
ret = -ENOMEM;
|
||||
goto err_free_arcdev;
|
||||
}
|
||||
card->tx_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
|
||||
"pci:green:tx:%d-%d",
|
||||
dev->dev_id, i);
|
||||
|
||||
if (!card->tx_led.name) {
|
||||
ret = -ENOMEM;
|
||||
goto err_free_arcdev;
|
||||
}
|
||||
card->tx_led.dev = &dev->dev;
|
||||
card->recon_led.brightness_set = led_recon_set;
|
||||
card->recon_led.default_trigger = devm_kasprintf(&pdev->dev,
|
||||
GFP_KERNEL, "arc%d-%d-recon",
|
||||
dev->dev_id, i);
|
||||
if (!card->recon_led.default_trigger) {
|
||||
ret = -ENOMEM;
|
||||
goto err_free_arcdev;
|
||||
}
|
||||
card->recon_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
|
||||
"pci:red:recon:%d-%d",
|
||||
dev->dev_id, i);
|
||||
if (!card->recon_led.name) {
|
||||
ret = -ENOMEM;
|
||||
goto err_free_arcdev;
|
||||
}
|
||||
card->recon_led.dev = &dev->dev;
|
||||
|
||||
ret = devm_led_classdev_register(&pdev->dev, &card->tx_led);
|
||||
|
@ -7350,13 +7350,13 @@ static int mv88e6xxx_probe(struct mdio_device *mdiodev)
|
||||
err = mv88e6xxx_switch_reset(chip);
|
||||
mv88e6xxx_reg_unlock(chip);
|
||||
if (err)
|
||||
goto out;
|
||||
goto out_phy;
|
||||
|
||||
if (np) {
|
||||
chip->irq = of_irq_get(np, 0);
|
||||
if (chip->irq == -EPROBE_DEFER) {
|
||||
err = chip->irq;
|
||||
goto out;
|
||||
goto out_phy;
|
||||
}
|
||||
}
|
||||
|
||||
@ -7375,7 +7375,7 @@ static int mv88e6xxx_probe(struct mdio_device *mdiodev)
|
||||
mv88e6xxx_reg_unlock(chip);
|
||||
|
||||
if (err)
|
||||
goto out;
|
||||
goto out_phy;
|
||||
|
||||
if (chip->info->g2_irqs > 0) {
|
||||
err = mv88e6xxx_g2_irq_setup(chip);
|
||||
@ -7409,6 +7409,8 @@ out_g1_irq:
|
||||
mv88e6xxx_g1_irq_free(chip);
|
||||
else
|
||||
mv88e6xxx_irq_poll_free(chip);
|
||||
out_phy:
|
||||
mv88e6xxx_phy_destroy(chip);
|
||||
out:
|
||||
if (pdata)
|
||||
dev_put(pdata->netdev);
|
||||
@ -7431,7 +7433,6 @@ static void mv88e6xxx_remove(struct mdio_device *mdiodev)
|
||||
mv88e6xxx_ptp_free(chip);
|
||||
}
|
||||
|
||||
mv88e6xxx_phy_destroy(chip);
|
||||
mv88e6xxx_unregister_switch(chip);
|
||||
|
||||
mv88e6xxx_g1_vtu_prob_irq_free(chip);
|
||||
@ -7444,6 +7445,8 @@ static void mv88e6xxx_remove(struct mdio_device *mdiodev)
|
||||
mv88e6xxx_g1_irq_free(chip);
|
||||
else
|
||||
mv88e6xxx_irq_poll_free(chip);
|
||||
|
||||
mv88e6xxx_phy_destroy(chip);
|
||||
}
|
||||
|
||||
static void mv88e6xxx_shutdown(struct mdio_device *mdiodev)
|
||||
|
@ -229,7 +229,10 @@ static void mv88e6xxx_phy_ppu_state_init(struct mv88e6xxx_chip *chip)
|
||||
|
||||
static void mv88e6xxx_phy_ppu_state_destroy(struct mv88e6xxx_chip *chip)
|
||||
{
|
||||
mutex_lock(&chip->ppu_mutex);
|
||||
del_timer_sync(&chip->ppu_timer);
|
||||
cancel_work_sync(&chip->ppu_work);
|
||||
mutex_unlock(&chip->ppu_mutex);
|
||||
}
|
||||
|
||||
int mv88e6185_phy_ppu_read(struct mv88e6xxx_chip *chip, struct mii_bus *bus,
|
||||
|
@ -105,6 +105,7 @@ static void dummy_setup(struct net_device *dev)
|
||||
dev->netdev_ops = &dummy_netdev_ops;
|
||||
dev->ethtool_ops = &dummy_ethtool_ops;
|
||||
dev->needs_free_netdev = true;
|
||||
dev->request_ops_lock = true;
|
||||
|
||||
/* Fill in device structure with ethernet-generic values. */
|
||||
dev->flags |= IFF_NOARP;
|
||||
|
@ -2028,7 +2028,7 @@ static int airoha_qdma_set_tx_ets_sched(struct airoha_gdm_port *port,
|
||||
struct tc_ets_qopt_offload_replace_params *p = &opt->replace_params;
|
||||
enum tx_sched_mode mode = TC_SCH_SP;
|
||||
u16 w[AIROHA_NUM_QOS_QUEUES] = {};
|
||||
int i, nstrict = 0, nwrr, qidx;
|
||||
int i, nstrict = 0;
|
||||
|
||||
if (p->bands > AIROHA_NUM_QOS_QUEUES)
|
||||
return -EINVAL;
|
||||
@ -2046,17 +2046,17 @@ static int airoha_qdma_set_tx_ets_sched(struct airoha_gdm_port *port,
|
||||
* lowest priorities with respect to SP ones.
|
||||
* e.g: WRR0, WRR1, .., WRRm, SP0, SP1, .., SPn
|
||||
*/
|
||||
nwrr = p->bands - nstrict;
|
||||
qidx = nstrict && nwrr ? nstrict : 0;
|
||||
for (i = 1; i <= p->bands; i++) {
|
||||
if (p->priomap[i % AIROHA_NUM_QOS_QUEUES] != qidx)
|
||||
for (i = 0; i < nstrict; i++) {
|
||||
if (p->priomap[p->bands - i - 1] != i)
|
||||
return -EINVAL;
|
||||
|
||||
qidx = i == nwrr ? 0 : qidx + 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < nwrr; i++)
|
||||
for (i = 0; i < p->bands - nstrict; i++) {
|
||||
if (p->priomap[i] != nstrict + i)
|
||||
return -EINVAL;
|
||||
|
||||
w[i] = p->weights[nstrict + i];
|
||||
}
|
||||
|
||||
if (!nstrict)
|
||||
mode = TC_SCH_WRR8;
|
||||
@ -2358,7 +2358,7 @@ static int airoha_tc_get_htb_get_leaf_queue(struct airoha_gdm_port *port,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
opt->qid = channel;
|
||||
opt->qid = AIROHA_NUM_TX_RING + channel;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -2454,6 +2454,19 @@ static void airoha_metadata_dst_free(struct airoha_gdm_port *port)
|
||||
}
|
||||
}
|
||||
|
||||
bool airoha_is_valid_gdm_port(struct airoha_eth *eth,
|
||||
struct airoha_gdm_port *port)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
||||
if (eth->ports[i] == port)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int airoha_alloc_gdm_port(struct airoha_eth *eth,
|
||||
struct device_node *np, int index)
|
||||
{
|
||||
|
@ -532,6 +532,9 @@ u32 airoha_rmw(void __iomem *base, u32 offset, u32 mask, u32 val);
|
||||
#define airoha_qdma_clear(qdma, offset, val) \
|
||||
airoha_rmw((qdma)->regs, (offset), (val), 0)
|
||||
|
||||
bool airoha_is_valid_gdm_port(struct airoha_eth *eth,
|
||||
struct airoha_gdm_port *port);
|
||||
|
||||
void airoha_ppe_check_skb(struct airoha_ppe *ppe, u16 hash);
|
||||
int airoha_ppe_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
|
||||
void *cb_priv);
|
||||
|
@ -197,7 +197,8 @@ static int airoha_get_dsa_port(struct net_device **dev)
|
||||
#endif
|
||||
}
|
||||
|
||||
static int airoha_ppe_foe_entry_prepare(struct airoha_foe_entry *hwe,
|
||||
static int airoha_ppe_foe_entry_prepare(struct airoha_eth *eth,
|
||||
struct airoha_foe_entry *hwe,
|
||||
struct net_device *dev, int type,
|
||||
struct airoha_flow_data *data,
|
||||
int l4proto)
|
||||
@ -225,6 +226,9 @@ static int airoha_ppe_foe_entry_prepare(struct airoha_foe_entry *hwe,
|
||||
struct airoha_gdm_port *port = netdev_priv(dev);
|
||||
u8 pse_port;
|
||||
|
||||
if (!airoha_is_valid_gdm_port(eth, port))
|
||||
return -EINVAL;
|
||||
|
||||
if (dsa_port >= 0)
|
||||
pse_port = port->id == 4 ? FE_PSE_PORT_GDM4 : port->id;
|
||||
else
|
||||
@ -633,7 +637,7 @@ static int airoha_ppe_flow_offload_replace(struct airoha_gdm_port *port,
|
||||
!is_valid_ether_addr(data.eth.h_dest))
|
||||
return -EINVAL;
|
||||
|
||||
err = airoha_ppe_foe_entry_prepare(&hwe, odev, offload_type,
|
||||
err = airoha_ppe_foe_entry_prepare(eth, &hwe, odev, offload_type,
|
||||
&data, l4proto);
|
||||
if (err)
|
||||
return err;
|
||||
|
@ -15909,7 +15909,7 @@ static int bnxt_queue_start(struct net_device *dev, void *qmem, int idx)
|
||||
goto err_reset;
|
||||
}
|
||||
|
||||
napi_enable(&bnapi->napi);
|
||||
napi_enable_locked(&bnapi->napi);
|
||||
bnxt_db_nq_arm(bp, &cpr->cp_db, cpr->cp_raw_cons);
|
||||
|
||||
for (i = 0; i < bp->nr_vnics; i++) {
|
||||
@ -15931,7 +15931,7 @@ static int bnxt_queue_start(struct net_device *dev, void *qmem, int idx)
|
||||
err_reset:
|
||||
netdev_err(bp->dev, "Unexpected HWRM error during queue start rc: %d\n",
|
||||
rc);
|
||||
napi_enable(&bnapi->napi);
|
||||
napi_enable_locked(&bnapi->napi);
|
||||
bnxt_db_nq_arm(bp, &cpr->cp_db, cpr->cp_raw_cons);
|
||||
bnxt_reset_task(bp, true);
|
||||
return rc;
|
||||
@ -15971,7 +15971,7 @@ static int bnxt_queue_stop(struct net_device *dev, void *qmem, int idx)
|
||||
* completion is handled in NAPI to guarantee no more DMA on that ring
|
||||
* after seeing the completion.
|
||||
*/
|
||||
napi_disable(&bnapi->napi);
|
||||
napi_disable_locked(&bnapi->napi);
|
||||
|
||||
if (bp->tph_mode) {
|
||||
bnxt_hwrm_cp_ring_free(bp, rxr->rx_cpr);
|
||||
|
@ -392,7 +392,9 @@ gve_get_ethtool_stats(struct net_device *netdev,
|
||||
*/
|
||||
data[i++] = 0;
|
||||
data[i++] = 0;
|
||||
data[i++] = tx->dqo_tx.tail - tx->dqo_tx.head;
|
||||
data[i++] =
|
||||
(tx->dqo_tx.tail - tx->dqo_tx.head) &
|
||||
tx->mask;
|
||||
}
|
||||
do {
|
||||
start =
|
||||
|
@ -1802,18 +1802,22 @@ static ssize_t veth_pool_store(struct kobject *kobj, struct attribute *attr,
|
||||
long value = simple_strtol(buf, NULL, 10);
|
||||
long rc;
|
||||
|
||||
rtnl_lock();
|
||||
|
||||
if (attr == &veth_active_attr) {
|
||||
if (value && !pool->active) {
|
||||
if (netif_running(netdev)) {
|
||||
if (ibmveth_alloc_buffer_pool(pool)) {
|
||||
netdev_err(netdev,
|
||||
"unable to alloc pool\n");
|
||||
return -ENOMEM;
|
||||
rc = -ENOMEM;
|
||||
goto unlock_err;
|
||||
}
|
||||
pool->active = 1;
|
||||
ibmveth_close(netdev);
|
||||
if ((rc = ibmveth_open(netdev)))
|
||||
return rc;
|
||||
rc = ibmveth_open(netdev);
|
||||
if (rc)
|
||||
goto unlock_err;
|
||||
} else {
|
||||
pool->active = 1;
|
||||
}
|
||||
@ -1833,48 +1837,59 @@ static ssize_t veth_pool_store(struct kobject *kobj, struct attribute *attr,
|
||||
|
||||
if (i == IBMVETH_NUM_BUFF_POOLS) {
|
||||
netdev_err(netdev, "no active pool >= MTU\n");
|
||||
return -EPERM;
|
||||
rc = -EPERM;
|
||||
goto unlock_err;
|
||||
}
|
||||
|
||||
if (netif_running(netdev)) {
|
||||
ibmveth_close(netdev);
|
||||
pool->active = 0;
|
||||
if ((rc = ibmveth_open(netdev)))
|
||||
return rc;
|
||||
rc = ibmveth_open(netdev);
|
||||
if (rc)
|
||||
goto unlock_err;
|
||||
}
|
||||
pool->active = 0;
|
||||
}
|
||||
} else if (attr == &veth_num_attr) {
|
||||
if (value <= 0 || value > IBMVETH_MAX_POOL_COUNT) {
|
||||
return -EINVAL;
|
||||
rc = -EINVAL;
|
||||
goto unlock_err;
|
||||
} else {
|
||||
if (netif_running(netdev)) {
|
||||
ibmveth_close(netdev);
|
||||
pool->size = value;
|
||||
if ((rc = ibmveth_open(netdev)))
|
||||
return rc;
|
||||
rc = ibmveth_open(netdev);
|
||||
if (rc)
|
||||
goto unlock_err;
|
||||
} else {
|
||||
pool->size = value;
|
||||
}
|
||||
}
|
||||
} else if (attr == &veth_size_attr) {
|
||||
if (value <= IBMVETH_BUFF_OH || value > IBMVETH_MAX_BUF_SIZE) {
|
||||
return -EINVAL;
|
||||
rc = -EINVAL;
|
||||
goto unlock_err;
|
||||
} else {
|
||||
if (netif_running(netdev)) {
|
||||
ibmveth_close(netdev);
|
||||
pool->buff_size = value;
|
||||
if ((rc = ibmveth_open(netdev)))
|
||||
return rc;
|
||||
rc = ibmveth_open(netdev);
|
||||
if (rc)
|
||||
goto unlock_err;
|
||||
} else {
|
||||
pool->buff_size = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
rtnl_unlock();
|
||||
|
||||
/* kick the interrupt handler to allocate/deallocate pools */
|
||||
ibmveth_interrupt(netdev->irq, netdev);
|
||||
return count;
|
||||
|
||||
unlock_err:
|
||||
rtnl_unlock();
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
@ -803,4 +803,7 @@
|
||||
/* SerDes Control */
|
||||
#define E1000_GEN_POLL_TIMEOUT 640
|
||||
|
||||
#define E1000_FEXTNVM12_PHYPD_CTRL_MASK 0x00C00000
|
||||
#define E1000_FEXTNVM12_PHYPD_CTRL_P1 0x00800000
|
||||
|
||||
#endif /* _E1000_DEFINES_H_ */
|
||||
|
@ -285,6 +285,45 @@ static void e1000_toggle_lanphypc_pch_lpt(struct e1000_hw *hw)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_reconfigure_k1_exit_timeout - reconfigure K1 exit timeout to
|
||||
* align to MTP and later platform requirements.
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Context: PHY semaphore must be held by caller.
|
||||
* Return: 0 on success, negative on failure
|
||||
*/
|
||||
static s32 e1000_reconfigure_k1_exit_timeout(struct e1000_hw *hw)
|
||||
{
|
||||
u16 phy_timeout;
|
||||
u32 fextnvm12;
|
||||
s32 ret_val;
|
||||
|
||||
if (hw->mac.type < e1000_pch_mtp)
|
||||
return 0;
|
||||
|
||||
/* Change Kumeran K1 power down state from P0s to P1 */
|
||||
fextnvm12 = er32(FEXTNVM12);
|
||||
fextnvm12 &= ~E1000_FEXTNVM12_PHYPD_CTRL_MASK;
|
||||
fextnvm12 |= E1000_FEXTNVM12_PHYPD_CTRL_P1;
|
||||
ew32(FEXTNVM12, fextnvm12);
|
||||
|
||||
/* Wait for the interface the settle */
|
||||
usleep_range(1000, 1100);
|
||||
|
||||
/* Change K1 exit timeout */
|
||||
ret_val = e1e_rphy_locked(hw, I217_PHY_TIMEOUTS_REG,
|
||||
&phy_timeout);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
phy_timeout &= ~I217_PHY_TIMEOUTS_K1_EXIT_TO_MASK;
|
||||
phy_timeout |= 0xF00;
|
||||
|
||||
return e1e_wphy_locked(hw, I217_PHY_TIMEOUTS_REG,
|
||||
phy_timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_init_phy_workarounds_pchlan - PHY initialization workarounds
|
||||
* @hw: pointer to the HW structure
|
||||
@ -327,15 +366,22 @@ static s32 e1000_init_phy_workarounds_pchlan(struct e1000_hw *hw)
|
||||
* LANPHYPC Value bit to force the interconnect to PCIe mode.
|
||||
*/
|
||||
switch (hw->mac.type) {
|
||||
case e1000_pch_mtp:
|
||||
case e1000_pch_lnp:
|
||||
case e1000_pch_ptp:
|
||||
case e1000_pch_nvp:
|
||||
/* At this point the PHY might be inaccessible so don't
|
||||
* propagate the failure
|
||||
*/
|
||||
if (e1000_reconfigure_k1_exit_timeout(hw))
|
||||
e_dbg("Failed to reconfigure K1 exit timeout\n");
|
||||
|
||||
fallthrough;
|
||||
case e1000_pch_lpt:
|
||||
case e1000_pch_spt:
|
||||
case e1000_pch_cnp:
|
||||
case e1000_pch_tgp:
|
||||
case e1000_pch_adp:
|
||||
case e1000_pch_mtp:
|
||||
case e1000_pch_lnp:
|
||||
case e1000_pch_ptp:
|
||||
case e1000_pch_nvp:
|
||||
if (e1000_phy_is_accessible_pchlan(hw))
|
||||
break;
|
||||
|
||||
@ -419,8 +465,20 @@ static s32 e1000_init_phy_workarounds_pchlan(struct e1000_hw *hw)
|
||||
* the PHY is in.
|
||||
*/
|
||||
ret_val = hw->phy.ops.check_reset_block(hw);
|
||||
if (ret_val)
|
||||
if (ret_val) {
|
||||
e_err("ME blocked access to PHY after reset\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (hw->mac.type >= e1000_pch_mtp) {
|
||||
ret_val = hw->phy.ops.acquire(hw);
|
||||
if (ret_val) {
|
||||
e_err("Failed to reconfigure K1 exit timeout\n");
|
||||
goto out;
|
||||
}
|
||||
ret_val = e1000_reconfigure_k1_exit_timeout(hw);
|
||||
hw->phy.ops.release(hw);
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
@ -4888,6 +4946,18 @@ static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw)
|
||||
u16 i;
|
||||
|
||||
e1000_initialize_hw_bits_ich8lan(hw);
|
||||
if (hw->mac.type >= e1000_pch_mtp) {
|
||||
ret_val = hw->phy.ops.acquire(hw);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
ret_val = e1000_reconfigure_k1_exit_timeout(hw);
|
||||
hw->phy.ops.release(hw);
|
||||
if (ret_val) {
|
||||
e_dbg("Error failed to reconfigure K1 exit timeout\n");
|
||||
return ret_val;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize identification LED */
|
||||
ret_val = mac->ops.id_led_init(hw);
|
||||
|
@ -219,6 +219,10 @@
|
||||
#define I217_PLL_CLOCK_GATE_REG PHY_REG(772, 28)
|
||||
#define I217_PLL_CLOCK_GATE_MASK 0x07FF
|
||||
|
||||
/* PHY Timeouts */
|
||||
#define I217_PHY_TIMEOUTS_REG PHY_REG(770, 21)
|
||||
#define I217_PHY_TIMEOUTS_K1_EXIT_TO_MASK 0x0FC0
|
||||
|
||||
#define SW_FLAG_TIMEOUT 1000 /* SW Semaphore flag timeout in ms */
|
||||
|
||||
/* Inband Control */
|
||||
|
@ -87,7 +87,11 @@ destroy_wqs:
|
||||
*/
|
||||
static void idpf_shutdown(struct pci_dev *pdev)
|
||||
{
|
||||
idpf_remove(pdev);
|
||||
struct idpf_adapter *adapter = pci_get_drvdata(pdev);
|
||||
|
||||
cancel_delayed_work_sync(&adapter->vc_event_task);
|
||||
idpf_vc_core_deinit(adapter);
|
||||
idpf_deinit_dflt_mbx(adapter);
|
||||
|
||||
if (system_state == SYSTEM_POWER_OFF)
|
||||
pci_set_power_state(pdev, PCI_D3hot);
|
||||
|
@ -337,8 +337,6 @@ struct igc_adapter {
|
||||
struct igc_led_classdev *leds;
|
||||
};
|
||||
|
||||
void igc_set_queue_napi(struct igc_adapter *adapter, int q_idx,
|
||||
struct napi_struct *napi);
|
||||
void igc_up(struct igc_adapter *adapter);
|
||||
void igc_down(struct igc_adapter *adapter);
|
||||
int igc_open(struct net_device *netdev);
|
||||
|
@ -3042,7 +3042,7 @@ static void igc_xdp_xmit_zc(struct igc_ring *ring)
|
||||
* descriptors. Therefore, to be safe, we always ensure we have at least
|
||||
* 4 descriptors available.
|
||||
*/
|
||||
while (xsk_tx_peek_desc(pool, &xdp_desc) && budget >= 4) {
|
||||
while (budget >= 4 && xsk_tx_peek_desc(pool, &xdp_desc)) {
|
||||
struct igc_metadata_request meta_req;
|
||||
struct xsk_tx_metadata *meta = NULL;
|
||||
struct igc_tx_buffer *bi;
|
||||
@ -5022,8 +5022,8 @@ static int igc_sw_init(struct igc_adapter *adapter)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void igc_set_queue_napi(struct igc_adapter *adapter, int vector,
|
||||
struct napi_struct *napi)
|
||||
static void igc_set_queue_napi(struct igc_adapter *adapter, int vector,
|
||||
struct napi_struct *napi)
|
||||
{
|
||||
struct igc_q_vector *q_vector = adapter->q_vector[vector];
|
||||
|
||||
|
@ -97,7 +97,6 @@ static int igc_xdp_enable_pool(struct igc_adapter *adapter,
|
||||
napi_disable(napi);
|
||||
}
|
||||
|
||||
igc_set_queue_napi(adapter, queue_id, NULL);
|
||||
set_bit(IGC_RING_FLAG_AF_XDP_ZC, &rx_ring->flags);
|
||||
set_bit(IGC_RING_FLAG_AF_XDP_ZC, &tx_ring->flags);
|
||||
|
||||
@ -147,7 +146,6 @@ static int igc_xdp_disable_pool(struct igc_adapter *adapter, u16 queue_id)
|
||||
xsk_pool_dma_unmap(pool, IGC_RX_DMA_ATTR);
|
||||
clear_bit(IGC_RING_FLAG_AF_XDP_ZC, &rx_ring->flags);
|
||||
clear_bit(IGC_RING_FLAG_AF_XDP_ZC, &tx_ring->flags);
|
||||
igc_set_queue_napi(adapter, queue_id, napi);
|
||||
|
||||
if (needs_reset) {
|
||||
napi_enable(napi);
|
||||
|
@ -1453,9 +1453,11 @@ enum ixgbe_media_type ixgbe_get_media_type_e610(struct ixgbe_hw *hw)
|
||||
hw->link.link_info.phy_type_low = 0;
|
||||
} else {
|
||||
highest_bit = fls64(le64_to_cpu(pcaps.phy_type_low));
|
||||
if (highest_bit)
|
||||
if (highest_bit) {
|
||||
hw->link.link_info.phy_type_low =
|
||||
BIT_ULL(highest_bit - 1);
|
||||
hw->link.link_info.phy_type_high = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1113,6 +1113,9 @@ struct mvpp2 {
|
||||
|
||||
/* Spinlocks for CM3 shared memory configuration */
|
||||
spinlock_t mss_spinlock;
|
||||
|
||||
/* Spinlock for shared PRS parser memory and shadow table */
|
||||
spinlock_t prs_spinlock;
|
||||
};
|
||||
|
||||
struct mvpp2_pcpu_stats {
|
||||
|
@ -7723,8 +7723,9 @@ static int mvpp2_probe(struct platform_device *pdev)
|
||||
if (mvpp2_read(priv, MVPP2_VER_ID_REG) == MVPP2_VER_PP23)
|
||||
priv->hw_version = MVPP23;
|
||||
|
||||
/* Init mss lock */
|
||||
/* Init locks for shared packet processor resources */
|
||||
spin_lock_init(&priv->mss_spinlock);
|
||||
spin_lock_init(&priv->prs_spinlock);
|
||||
|
||||
/* Initialize network controller */
|
||||
err = mvpp2_init(pdev, priv);
|
||||
|
@ -23,6 +23,8 @@ static int mvpp2_prs_hw_write(struct mvpp2 *priv, struct mvpp2_prs_entry *pe)
|
||||
{
|
||||
int i;
|
||||
|
||||
lockdep_assert_held(&priv->prs_spinlock);
|
||||
|
||||
if (pe->index > MVPP2_PRS_TCAM_SRAM_SIZE - 1)
|
||||
return -EINVAL;
|
||||
|
||||
@ -43,11 +45,13 @@ static int mvpp2_prs_hw_write(struct mvpp2 *priv, struct mvpp2_prs_entry *pe)
|
||||
}
|
||||
|
||||
/* Initialize tcam entry from hw */
|
||||
int mvpp2_prs_init_from_hw(struct mvpp2 *priv, struct mvpp2_prs_entry *pe,
|
||||
int tid)
|
||||
static int __mvpp2_prs_init_from_hw(struct mvpp2 *priv,
|
||||
struct mvpp2_prs_entry *pe, int tid)
|
||||
{
|
||||
int i;
|
||||
|
||||
lockdep_assert_held(&priv->prs_spinlock);
|
||||
|
||||
if (tid > MVPP2_PRS_TCAM_SRAM_SIZE - 1)
|
||||
return -EINVAL;
|
||||
|
||||
@ -73,6 +77,18 @@ int mvpp2_prs_init_from_hw(struct mvpp2 *priv, struct mvpp2_prs_entry *pe,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mvpp2_prs_init_from_hw(struct mvpp2 *priv, struct mvpp2_prs_entry *pe,
|
||||
int tid)
|
||||
{
|
||||
int err;
|
||||
|
||||
spin_lock_bh(&priv->prs_spinlock);
|
||||
err = __mvpp2_prs_init_from_hw(priv, pe, tid);
|
||||
spin_unlock_bh(&priv->prs_spinlock);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Invalidate tcam hw entry */
|
||||
static void mvpp2_prs_hw_inv(struct mvpp2 *priv, int index)
|
||||
{
|
||||
@ -374,7 +390,7 @@ static int mvpp2_prs_flow_find(struct mvpp2 *priv, int flow)
|
||||
priv->prs_shadow[tid].lu != MVPP2_PRS_LU_FLOWS)
|
||||
continue;
|
||||
|
||||
mvpp2_prs_init_from_hw(priv, &pe, tid);
|
||||
__mvpp2_prs_init_from_hw(priv, &pe, tid);
|
||||
bits = mvpp2_prs_sram_ai_get(&pe);
|
||||
|
||||
/* Sram store classification lookup ID in AI bits [5:0] */
|
||||
@ -441,7 +457,7 @@ static void mvpp2_prs_mac_drop_all_set(struct mvpp2 *priv, int port, bool add)
|
||||
|
||||
if (priv->prs_shadow[MVPP2_PE_DROP_ALL].valid) {
|
||||
/* Entry exist - update port only */
|
||||
mvpp2_prs_init_from_hw(priv, &pe, MVPP2_PE_DROP_ALL);
|
||||
__mvpp2_prs_init_from_hw(priv, &pe, MVPP2_PE_DROP_ALL);
|
||||
} else {
|
||||
/* Entry doesn't exist - create new */
|
||||
memset(&pe, 0, sizeof(pe));
|
||||
@ -469,14 +485,17 @@ static void mvpp2_prs_mac_drop_all_set(struct mvpp2 *priv, int port, bool add)
|
||||
}
|
||||
|
||||
/* Set port to unicast or multicast promiscuous mode */
|
||||
void mvpp2_prs_mac_promisc_set(struct mvpp2 *priv, int port,
|
||||
enum mvpp2_prs_l2_cast l2_cast, bool add)
|
||||
static void __mvpp2_prs_mac_promisc_set(struct mvpp2 *priv, int port,
|
||||
enum mvpp2_prs_l2_cast l2_cast,
|
||||
bool add)
|
||||
{
|
||||
struct mvpp2_prs_entry pe;
|
||||
unsigned char cast_match;
|
||||
unsigned int ri;
|
||||
int tid;
|
||||
|
||||
lockdep_assert_held(&priv->prs_spinlock);
|
||||
|
||||
if (l2_cast == MVPP2_PRS_L2_UNI_CAST) {
|
||||
cast_match = MVPP2_PRS_UCAST_VAL;
|
||||
tid = MVPP2_PE_MAC_UC_PROMISCUOUS;
|
||||
@ -489,7 +508,7 @@ void mvpp2_prs_mac_promisc_set(struct mvpp2 *priv, int port,
|
||||
|
||||
/* promiscuous mode - Accept unknown unicast or multicast packets */
|
||||
if (priv->prs_shadow[tid].valid) {
|
||||
mvpp2_prs_init_from_hw(priv, &pe, tid);
|
||||
__mvpp2_prs_init_from_hw(priv, &pe, tid);
|
||||
} else {
|
||||
memset(&pe, 0, sizeof(pe));
|
||||
mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MAC);
|
||||
@ -522,6 +541,14 @@ void mvpp2_prs_mac_promisc_set(struct mvpp2 *priv, int port,
|
||||
mvpp2_prs_hw_write(priv, &pe);
|
||||
}
|
||||
|
||||
void mvpp2_prs_mac_promisc_set(struct mvpp2 *priv, int port,
|
||||
enum mvpp2_prs_l2_cast l2_cast, bool add)
|
||||
{
|
||||
spin_lock_bh(&priv->prs_spinlock);
|
||||
__mvpp2_prs_mac_promisc_set(priv, port, l2_cast, add);
|
||||
spin_unlock_bh(&priv->prs_spinlock);
|
||||
}
|
||||
|
||||
/* Set entry for dsa packets */
|
||||
static void mvpp2_prs_dsa_tag_set(struct mvpp2 *priv, int port, bool add,
|
||||
bool tagged, bool extend)
|
||||
@ -539,7 +566,7 @@ static void mvpp2_prs_dsa_tag_set(struct mvpp2 *priv, int port, bool add,
|
||||
|
||||
if (priv->prs_shadow[tid].valid) {
|
||||
/* Entry exist - update port only */
|
||||
mvpp2_prs_init_from_hw(priv, &pe, tid);
|
||||
__mvpp2_prs_init_from_hw(priv, &pe, tid);
|
||||
} else {
|
||||
/* Entry doesn't exist - create new */
|
||||
memset(&pe, 0, sizeof(pe));
|
||||
@ -610,7 +637,7 @@ static void mvpp2_prs_dsa_tag_ethertype_set(struct mvpp2 *priv, int port,
|
||||
|
||||
if (priv->prs_shadow[tid].valid) {
|
||||
/* Entry exist - update port only */
|
||||
mvpp2_prs_init_from_hw(priv, &pe, tid);
|
||||
__mvpp2_prs_init_from_hw(priv, &pe, tid);
|
||||
} else {
|
||||
/* Entry doesn't exist - create new */
|
||||
memset(&pe, 0, sizeof(pe));
|
||||
@ -673,7 +700,7 @@ static int mvpp2_prs_vlan_find(struct mvpp2 *priv, unsigned short tpid, int ai)
|
||||
priv->prs_shadow[tid].lu != MVPP2_PRS_LU_VLAN)
|
||||
continue;
|
||||
|
||||
mvpp2_prs_init_from_hw(priv, &pe, tid);
|
||||
__mvpp2_prs_init_from_hw(priv, &pe, tid);
|
||||
match = mvpp2_prs_tcam_data_cmp(&pe, 0, tpid);
|
||||
if (!match)
|
||||
continue;
|
||||
@ -726,7 +753,7 @@ static int mvpp2_prs_vlan_add(struct mvpp2 *priv, unsigned short tpid, int ai,
|
||||
priv->prs_shadow[tid_aux].lu != MVPP2_PRS_LU_VLAN)
|
||||
continue;
|
||||
|
||||
mvpp2_prs_init_from_hw(priv, &pe, tid_aux);
|
||||
__mvpp2_prs_init_from_hw(priv, &pe, tid_aux);
|
||||
ri_bits = mvpp2_prs_sram_ri_get(&pe);
|
||||
if ((ri_bits & MVPP2_PRS_RI_VLAN_MASK) ==
|
||||
MVPP2_PRS_RI_VLAN_DOUBLE)
|
||||
@ -760,7 +787,7 @@ static int mvpp2_prs_vlan_add(struct mvpp2 *priv, unsigned short tpid, int ai,
|
||||
|
||||
mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_VLAN);
|
||||
} else {
|
||||
mvpp2_prs_init_from_hw(priv, &pe, tid);
|
||||
__mvpp2_prs_init_from_hw(priv, &pe, tid);
|
||||
}
|
||||
/* Update ports' mask */
|
||||
mvpp2_prs_tcam_port_map_set(&pe, port_map);
|
||||
@ -800,7 +827,7 @@ static int mvpp2_prs_double_vlan_find(struct mvpp2 *priv, unsigned short tpid1,
|
||||
priv->prs_shadow[tid].lu != MVPP2_PRS_LU_VLAN)
|
||||
continue;
|
||||
|
||||
mvpp2_prs_init_from_hw(priv, &pe, tid);
|
||||
__mvpp2_prs_init_from_hw(priv, &pe, tid);
|
||||
|
||||
match = mvpp2_prs_tcam_data_cmp(&pe, 0, tpid1) &&
|
||||
mvpp2_prs_tcam_data_cmp(&pe, 4, tpid2);
|
||||
@ -849,7 +876,7 @@ static int mvpp2_prs_double_vlan_add(struct mvpp2 *priv, unsigned short tpid1,
|
||||
priv->prs_shadow[tid_aux].lu != MVPP2_PRS_LU_VLAN)
|
||||
continue;
|
||||
|
||||
mvpp2_prs_init_from_hw(priv, &pe, tid_aux);
|
||||
__mvpp2_prs_init_from_hw(priv, &pe, tid_aux);
|
||||
ri_bits = mvpp2_prs_sram_ri_get(&pe);
|
||||
ri_bits &= MVPP2_PRS_RI_VLAN_MASK;
|
||||
if (ri_bits == MVPP2_PRS_RI_VLAN_SINGLE ||
|
||||
@ -880,7 +907,7 @@ static int mvpp2_prs_double_vlan_add(struct mvpp2 *priv, unsigned short tpid1,
|
||||
|
||||
mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_VLAN);
|
||||
} else {
|
||||
mvpp2_prs_init_from_hw(priv, &pe, tid);
|
||||
__mvpp2_prs_init_from_hw(priv, &pe, tid);
|
||||
}
|
||||
|
||||
/* Update ports' mask */
|
||||
@ -1213,8 +1240,8 @@ static void mvpp2_prs_mac_init(struct mvpp2 *priv)
|
||||
/* Create dummy entries for drop all and promiscuous modes */
|
||||
mvpp2_prs_drop_fc(priv);
|
||||
mvpp2_prs_mac_drop_all_set(priv, 0, false);
|
||||
mvpp2_prs_mac_promisc_set(priv, 0, MVPP2_PRS_L2_UNI_CAST, false);
|
||||
mvpp2_prs_mac_promisc_set(priv, 0, MVPP2_PRS_L2_MULTI_CAST, false);
|
||||
__mvpp2_prs_mac_promisc_set(priv, 0, MVPP2_PRS_L2_UNI_CAST, false);
|
||||
__mvpp2_prs_mac_promisc_set(priv, 0, MVPP2_PRS_L2_MULTI_CAST, false);
|
||||
}
|
||||
|
||||
/* Set default entries for various types of dsa packets */
|
||||
@ -1533,12 +1560,6 @@ static int mvpp2_prs_vlan_init(struct platform_device *pdev, struct mvpp2 *priv)
|
||||
struct mvpp2_prs_entry pe;
|
||||
int err;
|
||||
|
||||
priv->prs_double_vlans = devm_kcalloc(&pdev->dev, sizeof(bool),
|
||||
MVPP2_PRS_DBL_VLANS_MAX,
|
||||
GFP_KERNEL);
|
||||
if (!priv->prs_double_vlans)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Double VLAN: 0x88A8, 0x8100 */
|
||||
err = mvpp2_prs_double_vlan_add(priv, ETH_P_8021AD, ETH_P_8021Q,
|
||||
MVPP2_PRS_PORT_MASK);
|
||||
@ -1941,7 +1962,7 @@ static int mvpp2_prs_vid_range_find(struct mvpp2_port *port, u16 vid, u16 mask)
|
||||
port->priv->prs_shadow[tid].lu != MVPP2_PRS_LU_VID)
|
||||
continue;
|
||||
|
||||
mvpp2_prs_init_from_hw(port->priv, &pe, tid);
|
||||
__mvpp2_prs_init_from_hw(port->priv, &pe, tid);
|
||||
|
||||
mvpp2_prs_tcam_data_byte_get(&pe, 2, &byte[0], &enable[0]);
|
||||
mvpp2_prs_tcam_data_byte_get(&pe, 3, &byte[1], &enable[1]);
|
||||
@ -1970,6 +1991,8 @@ int mvpp2_prs_vid_entry_add(struct mvpp2_port *port, u16 vid)
|
||||
|
||||
memset(&pe, 0, sizeof(pe));
|
||||
|
||||
spin_lock_bh(&priv->prs_spinlock);
|
||||
|
||||
/* Scan TCAM and see if entry with this <vid,port> already exist */
|
||||
tid = mvpp2_prs_vid_range_find(port, vid, mask);
|
||||
|
||||
@ -1988,8 +2011,10 @@ int mvpp2_prs_vid_entry_add(struct mvpp2_port *port, u16 vid)
|
||||
MVPP2_PRS_VLAN_FILT_MAX_ENTRY);
|
||||
|
||||
/* There isn't room for a new VID filter */
|
||||
if (tid < 0)
|
||||
if (tid < 0) {
|
||||
spin_unlock_bh(&priv->prs_spinlock);
|
||||
return tid;
|
||||
}
|
||||
|
||||
mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_VID);
|
||||
pe.index = tid;
|
||||
@ -1997,7 +2022,7 @@ int mvpp2_prs_vid_entry_add(struct mvpp2_port *port, u16 vid)
|
||||
/* Mask all ports */
|
||||
mvpp2_prs_tcam_port_map_set(&pe, 0);
|
||||
} else {
|
||||
mvpp2_prs_init_from_hw(priv, &pe, tid);
|
||||
__mvpp2_prs_init_from_hw(priv, &pe, tid);
|
||||
}
|
||||
|
||||
/* Enable the current port */
|
||||
@ -2019,6 +2044,7 @@ int mvpp2_prs_vid_entry_add(struct mvpp2_port *port, u16 vid)
|
||||
mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_VID);
|
||||
mvpp2_prs_hw_write(priv, &pe);
|
||||
|
||||
spin_unlock_bh(&priv->prs_spinlock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2028,15 +2054,16 @@ void mvpp2_prs_vid_entry_remove(struct mvpp2_port *port, u16 vid)
|
||||
struct mvpp2 *priv = port->priv;
|
||||
int tid;
|
||||
|
||||
/* Scan TCAM and see if entry with this <vid,port> already exist */
|
||||
spin_lock_bh(&priv->prs_spinlock);
|
||||
|
||||
/* Invalidate TCAM entry with this <vid,port>, if it exists */
|
||||
tid = mvpp2_prs_vid_range_find(port, vid, 0xfff);
|
||||
if (tid >= 0) {
|
||||
mvpp2_prs_hw_inv(priv, tid);
|
||||
priv->prs_shadow[tid].valid = false;
|
||||
}
|
||||
|
||||
/* No such entry */
|
||||
if (tid < 0)
|
||||
return;
|
||||
|
||||
mvpp2_prs_hw_inv(priv, tid);
|
||||
priv->prs_shadow[tid].valid = false;
|
||||
spin_unlock_bh(&priv->prs_spinlock);
|
||||
}
|
||||
|
||||
/* Remove all existing VID filters on this port */
|
||||
@ -2045,6 +2072,8 @@ void mvpp2_prs_vid_remove_all(struct mvpp2_port *port)
|
||||
struct mvpp2 *priv = port->priv;
|
||||
int tid;
|
||||
|
||||
spin_lock_bh(&priv->prs_spinlock);
|
||||
|
||||
for (tid = MVPP2_PRS_VID_PORT_FIRST(port->id);
|
||||
tid <= MVPP2_PRS_VID_PORT_LAST(port->id); tid++) {
|
||||
if (priv->prs_shadow[tid].valid) {
|
||||
@ -2052,6 +2081,8 @@ void mvpp2_prs_vid_remove_all(struct mvpp2_port *port)
|
||||
priv->prs_shadow[tid].valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock_bh(&priv->prs_spinlock);
|
||||
}
|
||||
|
||||
/* Remove VID filering entry for this port */
|
||||
@ -2060,10 +2091,14 @@ void mvpp2_prs_vid_disable_filtering(struct mvpp2_port *port)
|
||||
unsigned int tid = MVPP2_PRS_VID_PORT_DFLT(port->id);
|
||||
struct mvpp2 *priv = port->priv;
|
||||
|
||||
spin_lock_bh(&priv->prs_spinlock);
|
||||
|
||||
/* Invalidate the guard entry */
|
||||
mvpp2_prs_hw_inv(priv, tid);
|
||||
|
||||
priv->prs_shadow[tid].valid = false;
|
||||
|
||||
spin_unlock_bh(&priv->prs_spinlock);
|
||||
}
|
||||
|
||||
/* Add guard entry that drops packets when no VID is matched on this port */
|
||||
@ -2079,6 +2114,8 @@ void mvpp2_prs_vid_enable_filtering(struct mvpp2_port *port)
|
||||
|
||||
memset(&pe, 0, sizeof(pe));
|
||||
|
||||
spin_lock_bh(&priv->prs_spinlock);
|
||||
|
||||
pe.index = tid;
|
||||
|
||||
reg_val = mvpp2_read(priv, MVPP2_MH_REG(port->id));
|
||||
@ -2111,6 +2148,8 @@ void mvpp2_prs_vid_enable_filtering(struct mvpp2_port *port)
|
||||
/* Update shadow table */
|
||||
mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_VID);
|
||||
mvpp2_prs_hw_write(priv, &pe);
|
||||
|
||||
spin_unlock_bh(&priv->prs_spinlock);
|
||||
}
|
||||
|
||||
/* Parser default initialization */
|
||||
@ -2118,6 +2157,20 @@ int mvpp2_prs_default_init(struct platform_device *pdev, struct mvpp2 *priv)
|
||||
{
|
||||
int err, index, i;
|
||||
|
||||
priv->prs_shadow = devm_kcalloc(&pdev->dev, MVPP2_PRS_TCAM_SRAM_SIZE,
|
||||
sizeof(*priv->prs_shadow),
|
||||
GFP_KERNEL);
|
||||
if (!priv->prs_shadow)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->prs_double_vlans = devm_kcalloc(&pdev->dev, sizeof(bool),
|
||||
MVPP2_PRS_DBL_VLANS_MAX,
|
||||
GFP_KERNEL);
|
||||
if (!priv->prs_double_vlans)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_bh(&priv->prs_spinlock);
|
||||
|
||||
/* Enable tcam table */
|
||||
mvpp2_write(priv, MVPP2_PRS_TCAM_CTRL_REG, MVPP2_PRS_TCAM_EN_MASK);
|
||||
|
||||
@ -2136,12 +2189,6 @@ int mvpp2_prs_default_init(struct platform_device *pdev, struct mvpp2 *priv)
|
||||
for (index = 0; index < MVPP2_PRS_TCAM_SRAM_SIZE; index++)
|
||||
mvpp2_prs_hw_inv(priv, index);
|
||||
|
||||
priv->prs_shadow = devm_kcalloc(&pdev->dev, MVPP2_PRS_TCAM_SRAM_SIZE,
|
||||
sizeof(*priv->prs_shadow),
|
||||
GFP_KERNEL);
|
||||
if (!priv->prs_shadow)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Always start from lookup = 0 */
|
||||
for (index = 0; index < MVPP2_MAX_PORTS; index++)
|
||||
mvpp2_prs_hw_port_init(priv, index, MVPP2_PRS_LU_MH,
|
||||
@ -2158,26 +2205,13 @@ int mvpp2_prs_default_init(struct platform_device *pdev, struct mvpp2 *priv)
|
||||
mvpp2_prs_vid_init(priv);
|
||||
|
||||
err = mvpp2_prs_etype_init(priv);
|
||||
if (err)
|
||||
return err;
|
||||
err = err ? : mvpp2_prs_vlan_init(pdev, priv);
|
||||
err = err ? : mvpp2_prs_pppoe_init(priv);
|
||||
err = err ? : mvpp2_prs_ip6_init(priv);
|
||||
err = err ? : mvpp2_prs_ip4_init(priv);
|
||||
|
||||
err = mvpp2_prs_vlan_init(pdev, priv);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = mvpp2_prs_pppoe_init(priv);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = mvpp2_prs_ip6_init(priv);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = mvpp2_prs_ip4_init(priv);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
spin_unlock_bh(&priv->prs_spinlock);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Compare MAC DA with tcam entry data */
|
||||
@ -2217,7 +2251,7 @@ mvpp2_prs_mac_da_range_find(struct mvpp2 *priv, int pmap, const u8 *da,
|
||||
(priv->prs_shadow[tid].udf != udf_type))
|
||||
continue;
|
||||
|
||||
mvpp2_prs_init_from_hw(priv, &pe, tid);
|
||||
__mvpp2_prs_init_from_hw(priv, &pe, tid);
|
||||
entry_pmap = mvpp2_prs_tcam_port_map_get(&pe);
|
||||
|
||||
if (mvpp2_prs_mac_range_equals(&pe, da, mask) &&
|
||||
@ -2229,7 +2263,8 @@ mvpp2_prs_mac_da_range_find(struct mvpp2 *priv, int pmap, const u8 *da,
|
||||
}
|
||||
|
||||
/* Update parser's mac da entry */
|
||||
int mvpp2_prs_mac_da_accept(struct mvpp2_port *port, const u8 *da, bool add)
|
||||
static int __mvpp2_prs_mac_da_accept(struct mvpp2_port *port,
|
||||
const u8 *da, bool add)
|
||||
{
|
||||
unsigned char mask[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||
struct mvpp2 *priv = port->priv;
|
||||
@ -2261,7 +2296,7 @@ int mvpp2_prs_mac_da_accept(struct mvpp2_port *port, const u8 *da, bool add)
|
||||
/* Mask all ports */
|
||||
mvpp2_prs_tcam_port_map_set(&pe, 0);
|
||||
} else {
|
||||
mvpp2_prs_init_from_hw(priv, &pe, tid);
|
||||
__mvpp2_prs_init_from_hw(priv, &pe, tid);
|
||||
}
|
||||
|
||||
mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MAC);
|
||||
@ -2317,6 +2352,17 @@ int mvpp2_prs_mac_da_accept(struct mvpp2_port *port, const u8 *da, bool add)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mvpp2_prs_mac_da_accept(struct mvpp2_port *port, const u8 *da, bool add)
|
||||
{
|
||||
int err;
|
||||
|
||||
spin_lock_bh(&port->priv->prs_spinlock);
|
||||
err = __mvpp2_prs_mac_da_accept(port, da, add);
|
||||
spin_unlock_bh(&port->priv->prs_spinlock);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int mvpp2_prs_update_mac_da(struct net_device *dev, const u8 *da)
|
||||
{
|
||||
struct mvpp2_port *port = netdev_priv(dev);
|
||||
@ -2345,6 +2391,8 @@ void mvpp2_prs_mac_del_all(struct mvpp2_port *port)
|
||||
unsigned long pmap;
|
||||
int index, tid;
|
||||
|
||||
spin_lock_bh(&priv->prs_spinlock);
|
||||
|
||||
for (tid = MVPP2_PE_MAC_RANGE_START;
|
||||
tid <= MVPP2_PE_MAC_RANGE_END; tid++) {
|
||||
unsigned char da[ETH_ALEN], da_mask[ETH_ALEN];
|
||||
@ -2354,7 +2402,7 @@ void mvpp2_prs_mac_del_all(struct mvpp2_port *port)
|
||||
(priv->prs_shadow[tid].udf != MVPP2_PRS_UDF_MAC_DEF))
|
||||
continue;
|
||||
|
||||
mvpp2_prs_init_from_hw(priv, &pe, tid);
|
||||
__mvpp2_prs_init_from_hw(priv, &pe, tid);
|
||||
|
||||
pmap = mvpp2_prs_tcam_port_map_get(&pe);
|
||||
|
||||
@ -2375,14 +2423,17 @@ void mvpp2_prs_mac_del_all(struct mvpp2_port *port)
|
||||
continue;
|
||||
|
||||
/* Remove entry from TCAM */
|
||||
mvpp2_prs_mac_da_accept(port, da, false);
|
||||
__mvpp2_prs_mac_da_accept(port, da, false);
|
||||
}
|
||||
|
||||
spin_unlock_bh(&priv->prs_spinlock);
|
||||
}
|
||||
|
||||
int mvpp2_prs_tag_mode_set(struct mvpp2 *priv, int port, int type)
|
||||
{
|
||||
switch (type) {
|
||||
case MVPP2_TAG_TYPE_EDSA:
|
||||
spin_lock_bh(&priv->prs_spinlock);
|
||||
/* Add port to EDSA entries */
|
||||
mvpp2_prs_dsa_tag_set(priv, port, true,
|
||||
MVPP2_PRS_TAGGED, MVPP2_PRS_EDSA);
|
||||
@ -2393,9 +2444,11 @@ int mvpp2_prs_tag_mode_set(struct mvpp2 *priv, int port, int type)
|
||||
MVPP2_PRS_TAGGED, MVPP2_PRS_DSA);
|
||||
mvpp2_prs_dsa_tag_set(priv, port, false,
|
||||
MVPP2_PRS_UNTAGGED, MVPP2_PRS_DSA);
|
||||
spin_unlock_bh(&priv->prs_spinlock);
|
||||
break;
|
||||
|
||||
case MVPP2_TAG_TYPE_DSA:
|
||||
spin_lock_bh(&priv->prs_spinlock);
|
||||
/* Add port to DSA entries */
|
||||
mvpp2_prs_dsa_tag_set(priv, port, true,
|
||||
MVPP2_PRS_TAGGED, MVPP2_PRS_DSA);
|
||||
@ -2406,10 +2459,12 @@ int mvpp2_prs_tag_mode_set(struct mvpp2 *priv, int port, int type)
|
||||
MVPP2_PRS_TAGGED, MVPP2_PRS_EDSA);
|
||||
mvpp2_prs_dsa_tag_set(priv, port, false,
|
||||
MVPP2_PRS_UNTAGGED, MVPP2_PRS_EDSA);
|
||||
spin_unlock_bh(&priv->prs_spinlock);
|
||||
break;
|
||||
|
||||
case MVPP2_TAG_TYPE_MH:
|
||||
case MVPP2_TAG_TYPE_NONE:
|
||||
spin_lock_bh(&priv->prs_spinlock);
|
||||
/* Remove port form EDSA and DSA entries */
|
||||
mvpp2_prs_dsa_tag_set(priv, port, false,
|
||||
MVPP2_PRS_TAGGED, MVPP2_PRS_DSA);
|
||||
@ -2419,6 +2474,7 @@ int mvpp2_prs_tag_mode_set(struct mvpp2 *priv, int port, int type)
|
||||
MVPP2_PRS_TAGGED, MVPP2_PRS_EDSA);
|
||||
mvpp2_prs_dsa_tag_set(priv, port, false,
|
||||
MVPP2_PRS_UNTAGGED, MVPP2_PRS_EDSA);
|
||||
spin_unlock_bh(&priv->prs_spinlock);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -2437,11 +2493,15 @@ int mvpp2_prs_add_flow(struct mvpp2 *priv, int flow, u32 ri, u32 ri_mask)
|
||||
|
||||
memset(&pe, 0, sizeof(pe));
|
||||
|
||||
spin_lock_bh(&priv->prs_spinlock);
|
||||
|
||||
tid = mvpp2_prs_tcam_first_free(priv,
|
||||
MVPP2_PE_LAST_FREE_TID,
|
||||
MVPP2_PE_FIRST_FREE_TID);
|
||||
if (tid < 0)
|
||||
if (tid < 0) {
|
||||
spin_unlock_bh(&priv->prs_spinlock);
|
||||
return tid;
|
||||
}
|
||||
|
||||
pe.index = tid;
|
||||
|
||||
@ -2461,6 +2521,7 @@ int mvpp2_prs_add_flow(struct mvpp2 *priv, int flow, u32 ri, u32 ri_mask)
|
||||
mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);
|
||||
mvpp2_prs_hw_write(priv, &pe);
|
||||
|
||||
spin_unlock_bh(&priv->prs_spinlock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2472,6 +2533,8 @@ int mvpp2_prs_def_flow(struct mvpp2_port *port)
|
||||
|
||||
memset(&pe, 0, sizeof(pe));
|
||||
|
||||
spin_lock_bh(&port->priv->prs_spinlock);
|
||||
|
||||
tid = mvpp2_prs_flow_find(port->priv, port->id);
|
||||
|
||||
/* Such entry not exist */
|
||||
@ -2480,8 +2543,10 @@ int mvpp2_prs_def_flow(struct mvpp2_port *port)
|
||||
tid = mvpp2_prs_tcam_first_free(port->priv,
|
||||
MVPP2_PE_LAST_FREE_TID,
|
||||
MVPP2_PE_FIRST_FREE_TID);
|
||||
if (tid < 0)
|
||||
if (tid < 0) {
|
||||
spin_unlock_bh(&port->priv->prs_spinlock);
|
||||
return tid;
|
||||
}
|
||||
|
||||
pe.index = tid;
|
||||
|
||||
@ -2492,13 +2557,14 @@ int mvpp2_prs_def_flow(struct mvpp2_port *port)
|
||||
/* Update shadow table */
|
||||
mvpp2_prs_shadow_set(port->priv, pe.index, MVPP2_PRS_LU_FLOWS);
|
||||
} else {
|
||||
mvpp2_prs_init_from_hw(port->priv, &pe, tid);
|
||||
__mvpp2_prs_init_from_hw(port->priv, &pe, tid);
|
||||
}
|
||||
|
||||
mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_FLOWS);
|
||||
mvpp2_prs_tcam_port_map_set(&pe, (1 << port->id));
|
||||
mvpp2_prs_hw_write(port->priv, &pe);
|
||||
|
||||
spin_unlock_bh(&port->priv->prs_spinlock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2509,11 +2575,14 @@ int mvpp2_prs_hits(struct mvpp2 *priv, int index)
|
||||
if (index > MVPP2_PRS_TCAM_SRAM_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_bh(&priv->prs_spinlock);
|
||||
|
||||
mvpp2_write(priv, MVPP2_PRS_TCAM_HIT_IDX_REG, index);
|
||||
|
||||
val = mvpp2_read(priv, MVPP2_PRS_TCAM_HIT_CNT_REG);
|
||||
|
||||
val &= MVPP2_PRS_TCAM_HIT_CNT_MASK;
|
||||
|
||||
spin_unlock_bh(&priv->prs_spinlock);
|
||||
return val;
|
||||
}
|
||||
|
@ -1559,12 +1559,11 @@ handle_xdp_verdict:
|
||||
break;
|
||||
default:
|
||||
bpf_warn_invalid_xdp_action(pfvf->netdev, prog, act);
|
||||
break;
|
||||
fallthrough;
|
||||
case XDP_ABORTED:
|
||||
if (xsk_buff)
|
||||
xsk_buff_free(xsk_buff);
|
||||
trace_xdp_exception(pfvf->netdev, prog, act);
|
||||
break;
|
||||
if (act == XDP_ABORTED)
|
||||
trace_xdp_exception(pfvf->netdev, prog, act);
|
||||
fallthrough;
|
||||
case XDP_DROP:
|
||||
cq->pool_ptrs++;
|
||||
if (xsk_buff) {
|
||||
|
@ -7,6 +7,7 @@ config MLX4_EN
|
||||
tristate "Mellanox Technologies 1/10/40Gbit Ethernet support"
|
||||
depends on PCI && NETDEVICES && ETHERNET && INET
|
||||
depends on PTP_1588_CLOCK_OPTIONAL
|
||||
select PAGE_POOL
|
||||
select MLX4_CORE
|
||||
help
|
||||
This driver supports Mellanox Technologies ConnectX Ethernet
|
||||
|
@ -450,8 +450,9 @@ int ef100_probe_netdev(struct efx_probe_data *probe_data)
|
||||
net_dev->hw_enc_features |= efx->type->offload_features;
|
||||
net_dev->vlan_features |= NETIF_F_HW_CSUM | NETIF_F_SG |
|
||||
NETIF_F_HIGHDMA | NETIF_F_ALL_TSO;
|
||||
netif_set_tso_max_segs(net_dev,
|
||||
ESE_EF100_DP_GZ_TSO_MAX_HDR_NUM_SEGS_DEFAULT);
|
||||
nic_data = efx->nic_data;
|
||||
netif_set_tso_max_size(efx->net_dev, nic_data->tso_max_payload_len);
|
||||
netif_set_tso_max_segs(efx->net_dev, nic_data->tso_max_payload_num_segs);
|
||||
|
||||
rc = efx_ef100_init_datapath_caps(efx);
|
||||
if (rc < 0)
|
||||
@ -477,7 +478,6 @@ int ef100_probe_netdev(struct efx_probe_data *probe_data)
|
||||
/* Don't fail init if RSS setup doesn't work. */
|
||||
efx_mcdi_push_default_indir_table(efx, efx->n_rx_channels);
|
||||
|
||||
nic_data = efx->nic_data;
|
||||
rc = ef100_get_mac_address(efx, net_dev->perm_addr, CLIENT_HANDLE_SELF,
|
||||
efx->type->is_vf);
|
||||
if (rc)
|
||||
|
@ -887,8 +887,7 @@ static int ef100_process_design_param(struct efx_nic *efx,
|
||||
case ESE_EF100_DP_GZ_TSO_MAX_HDR_NUM_SEGS:
|
||||
/* We always put HDR_NUM_SEGS=1 in our TSO descriptors */
|
||||
if (!reader->value) {
|
||||
netif_err(efx, probe, efx->net_dev,
|
||||
"TSO_MAX_HDR_NUM_SEGS < 1\n");
|
||||
pci_err(efx->pci_dev, "TSO_MAX_HDR_NUM_SEGS < 1\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
return 0;
|
||||
@ -901,32 +900,28 @@ static int ef100_process_design_param(struct efx_nic *efx,
|
||||
*/
|
||||
if (!reader->value || reader->value > EFX_MIN_DMAQ_SIZE ||
|
||||
EFX_MIN_DMAQ_SIZE % (u32)reader->value) {
|
||||
netif_err(efx, probe, efx->net_dev,
|
||||
"%s size granularity is %llu, can't guarantee safety\n",
|
||||
reader->type == ESE_EF100_DP_GZ_RXQ_SIZE_GRANULARITY ? "RXQ" : "TXQ",
|
||||
reader->value);
|
||||
pci_err(efx->pci_dev,
|
||||
"%s size granularity is %llu, can't guarantee safety\n",
|
||||
reader->type == ESE_EF100_DP_GZ_RXQ_SIZE_GRANULARITY ? "RXQ" : "TXQ",
|
||||
reader->value);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
return 0;
|
||||
case ESE_EF100_DP_GZ_TSO_MAX_PAYLOAD_LEN:
|
||||
nic_data->tso_max_payload_len = min_t(u64, reader->value,
|
||||
GSO_LEGACY_MAX_SIZE);
|
||||
netif_set_tso_max_size(efx->net_dev,
|
||||
nic_data->tso_max_payload_len);
|
||||
return 0;
|
||||
case ESE_EF100_DP_GZ_TSO_MAX_PAYLOAD_NUM_SEGS:
|
||||
nic_data->tso_max_payload_num_segs = min_t(u64, reader->value, 0xffff);
|
||||
netif_set_tso_max_segs(efx->net_dev,
|
||||
nic_data->tso_max_payload_num_segs);
|
||||
return 0;
|
||||
case ESE_EF100_DP_GZ_TSO_MAX_NUM_FRAMES:
|
||||
nic_data->tso_max_frames = min_t(u64, reader->value, 0xffff);
|
||||
return 0;
|
||||
case ESE_EF100_DP_GZ_COMPAT:
|
||||
if (reader->value) {
|
||||
netif_err(efx, probe, efx->net_dev,
|
||||
"DP_COMPAT has unknown bits %#llx, driver not compatible with this hw\n",
|
||||
reader->value);
|
||||
pci_err(efx->pci_dev,
|
||||
"DP_COMPAT has unknown bits %#llx, driver not compatible with this hw\n",
|
||||
reader->value);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
return 0;
|
||||
@ -946,10 +941,10 @@ static int ef100_process_design_param(struct efx_nic *efx,
|
||||
* So the value of this shouldn't matter.
|
||||
*/
|
||||
if (reader->value != ESE_EF100_DP_GZ_VI_STRIDES_DEFAULT)
|
||||
netif_dbg(efx, probe, efx->net_dev,
|
||||
"NIC has other than default VI_STRIDES (mask "
|
||||
"%#llx), early probing might use wrong one\n",
|
||||
reader->value);
|
||||
pci_dbg(efx->pci_dev,
|
||||
"NIC has other than default VI_STRIDES (mask "
|
||||
"%#llx), early probing might use wrong one\n",
|
||||
reader->value);
|
||||
return 0;
|
||||
case ESE_EF100_DP_GZ_RX_MAX_RUNT:
|
||||
/* Driver doesn't look at L2_STATUS:LEN_ERR bit, so we don't
|
||||
@ -961,9 +956,9 @@ static int ef100_process_design_param(struct efx_nic *efx,
|
||||
/* Host interface says "Drivers should ignore design parameters
|
||||
* that they do not recognise."
|
||||
*/
|
||||
netif_dbg(efx, probe, efx->net_dev,
|
||||
"Ignoring unrecognised design parameter %u\n",
|
||||
reader->type);
|
||||
pci_dbg(efx->pci_dev,
|
||||
"Ignoring unrecognised design parameter %u\n",
|
||||
reader->type);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -999,13 +994,13 @@ static int ef100_check_design_params(struct efx_nic *efx)
|
||||
*/
|
||||
if (reader.state != EF100_TLV_TYPE) {
|
||||
if (reader.state == EF100_TLV_TYPE_CONT)
|
||||
netif_err(efx, probe, efx->net_dev,
|
||||
"truncated design parameter (incomplete type %u)\n",
|
||||
reader.type);
|
||||
pci_err(efx->pci_dev,
|
||||
"truncated design parameter (incomplete type %u)\n",
|
||||
reader.type);
|
||||
else
|
||||
netif_err(efx, probe, efx->net_dev,
|
||||
"truncated design parameter %u\n",
|
||||
reader.type);
|
||||
pci_err(efx->pci_dev,
|
||||
"truncated design parameter %u\n",
|
||||
reader.type);
|
||||
rc = -EIO;
|
||||
}
|
||||
out:
|
||||
|
@ -939,6 +939,7 @@ static int nsim_init_netdevsim(struct netdevsim *ns)
|
||||
ns->netdev->netdev_ops = &nsim_netdev_ops;
|
||||
ns->netdev->stat_ops = &nsim_stat_ops;
|
||||
ns->netdev->queue_mgmt_ops = &nsim_queue_mgmt_ops;
|
||||
netdev_lockdep_set_classes(ns->netdev);
|
||||
|
||||
err = nsim_udp_tunnels_info_create(ns->nsim_dev, ns->netdev);
|
||||
if (err)
|
||||
@ -960,6 +961,14 @@ static int nsim_init_netdevsim(struct netdevsim *ns)
|
||||
if (err)
|
||||
goto err_ipsec_teardown;
|
||||
rtnl_unlock();
|
||||
|
||||
if (IS_ENABLED(CONFIG_DEBUG_NET)) {
|
||||
ns->nb.notifier_call = netdev_debug_event;
|
||||
if (register_netdevice_notifier_dev_net(ns->netdev, &ns->nb,
|
||||
&ns->nn))
|
||||
ns->nb.notifier_call = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_ipsec_teardown:
|
||||
@ -1043,6 +1052,10 @@ void nsim_destroy(struct netdevsim *ns)
|
||||
debugfs_remove(ns->qr_dfs);
|
||||
debugfs_remove(ns->pp_dfs);
|
||||
|
||||
if (ns->nb.notifier_call)
|
||||
unregister_netdevice_notifier_dev_net(ns->netdev, &ns->nb,
|
||||
&ns->nn);
|
||||
|
||||
rtnl_lock();
|
||||
peer = rtnl_dereference(ns->peer);
|
||||
if (peer)
|
||||
|
@ -144,6 +144,9 @@ struct netdevsim {
|
||||
|
||||
struct nsim_ethtool ethtool;
|
||||
struct netdevsim __rcu *peer;
|
||||
|
||||
struct notifier_block nb;
|
||||
struct netdev_net_notifier nn;
|
||||
};
|
||||
|
||||
struct netdevsim *
|
||||
|
@ -530,7 +530,8 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)
|
||||
netif_device_present (dev->net) &&
|
||||
test_bit(EVENT_DEV_OPEN, &dev->flags) &&
|
||||
!test_bit (EVENT_RX_HALT, &dev->flags) &&
|
||||
!test_bit (EVENT_DEV_ASLEEP, &dev->flags)) {
|
||||
!test_bit (EVENT_DEV_ASLEEP, &dev->flags) &&
|
||||
!usbnet_going_away(dev)) {
|
||||
switch (retval = usb_submit_urb (urb, GFP_ATOMIC)) {
|
||||
case -EPIPE:
|
||||
usbnet_defer_kevent (dev, EVENT_RX_HALT);
|
||||
@ -551,8 +552,7 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)
|
||||
tasklet_schedule (&dev->bh);
|
||||
break;
|
||||
case 0:
|
||||
if (!usbnet_going_away(dev))
|
||||
__usbnet_queue_skb(&dev->rxq, skb, rx_start);
|
||||
__usbnet_queue_skb(&dev->rxq, skb, rx_start);
|
||||
}
|
||||
} else {
|
||||
netif_dbg(dev, ifdown, dev->net, "rx: stopped\n");
|
||||
|
@ -4192,7 +4192,7 @@ int dev_change_flags(struct net_device *dev, unsigned int flags,
|
||||
int netif_set_alias(struct net_device *dev, const char *alias, size_t len);
|
||||
int dev_set_alias(struct net_device *, const char *, size_t);
|
||||
int dev_get_alias(const struct net_device *, char *, size_t);
|
||||
int netif_change_net_namespace(struct net_device *dev, struct net *net,
|
||||
int __dev_change_net_namespace(struct net_device *dev, struct net *net,
|
||||
const char *pat, int new_ifindex,
|
||||
struct netlink_ext_ack *extack);
|
||||
int dev_change_net_namespace(struct net_device *dev, struct net *net,
|
||||
|
@ -667,14 +667,6 @@ static inline void ip_ipgre_mc_map(__be32 naddr, const unsigned char *broadcast,
|
||||
memcpy(buf, &naddr, sizeof(naddr));
|
||||
}
|
||||
|
||||
#if IS_MODULE(CONFIG_IPV6)
|
||||
#define EXPORT_IPV6_MOD(X) EXPORT_SYMBOL(X)
|
||||
#define EXPORT_IPV6_MOD_GPL(X) EXPORT_SYMBOL_GPL(X)
|
||||
#else
|
||||
#define EXPORT_IPV6_MOD(X)
|
||||
#define EXPORT_IPV6_MOD_GPL(X)
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
#include <linux/ipv6.h>
|
||||
#endif
|
||||
@ -694,6 +686,14 @@ static __inline__ void inet_reset_saddr(struct sock *sk)
|
||||
|
||||
#endif
|
||||
|
||||
#if IS_MODULE(CONFIG_IPV6)
|
||||
#define EXPORT_IPV6_MOD(X) EXPORT_SYMBOL(X)
|
||||
#define EXPORT_IPV6_MOD_GPL(X) EXPORT_SYMBOL_GPL(X)
|
||||
#else
|
||||
#define EXPORT_IPV6_MOD(X)
|
||||
#define EXPORT_IPV6_MOD_GPL(X)
|
||||
#endif
|
||||
|
||||
static inline unsigned int ipv4_addr_hash(__be32 ip)
|
||||
{
|
||||
return (__force unsigned int) ip;
|
||||
|
@ -98,4 +98,7 @@ static inline int netdev_lock_cmp_fn(const struct lockdep_map *a,
|
||||
&qdisc_xmit_lock_key); \
|
||||
}
|
||||
|
||||
int netdev_debug_event(struct notifier_block *nb, unsigned long event,
|
||||
void *ptr);
|
||||
|
||||
#endif
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <net/page_pool/types.h>
|
||||
|
||||
struct netdev_rx_queue;
|
||||
struct netlink_ext_ack;
|
||||
struct sk_buff;
|
||||
|
||||
struct memory_provider_ops {
|
||||
@ -24,8 +25,13 @@ void net_mp_niov_clear_page_pool(struct net_iov *niov);
|
||||
|
||||
int net_mp_open_rxq(struct net_device *dev, unsigned ifq_idx,
|
||||
struct pp_memory_provider_params *p);
|
||||
int __net_mp_open_rxq(struct net_device *dev, unsigned int rxq_idx,
|
||||
const struct pp_memory_provider_params *p,
|
||||
struct netlink_ext_ack *extack);
|
||||
void net_mp_close_rxq(struct net_device *dev, unsigned ifq_idx,
|
||||
struct pp_memory_provider_params *old_p);
|
||||
void __net_mp_close_rxq(struct net_device *dev, unsigned int rxq_idx,
|
||||
const struct pp_memory_provider_params *old_p);
|
||||
|
||||
/**
|
||||
* net_mp_netmem_place_in_cache() - give a netmem to a page pool
|
||||
|
@ -45,5 +45,5 @@ obj-$(CONFIG_BPF_SYSCALL) += bpf_sk_storage.o
|
||||
obj-$(CONFIG_OF) += of_net.o
|
||||
obj-$(CONFIG_NET_TEST) += net_test.o
|
||||
obj-$(CONFIG_NET_DEVMEM) += devmem.o
|
||||
obj-$(CONFIG_DEBUG_NET_SMALL_RTNL) += rtnl_net_debug.o
|
||||
obj-$(CONFIG_DEBUG_NET) += lock_debug.o
|
||||
obj-$(CONFIG_FAIL_SKB_REALLOC) += skb_fault_injection.o
|
||||
|
@ -1771,6 +1771,7 @@ void netif_disable_lro(struct net_device *dev)
|
||||
netdev_unlock_ops(lower_dev);
|
||||
}
|
||||
}
|
||||
EXPORT_IPV6_MOD(netif_disable_lro);
|
||||
|
||||
/**
|
||||
* dev_disable_gro_hw - disable HW Generic Receive Offload on a device
|
||||
@ -1858,7 +1859,9 @@ static int call_netdevice_register_net_notifiers(struct notifier_block *nb,
|
||||
int err;
|
||||
|
||||
for_each_netdev(net, dev) {
|
||||
netdev_lock_ops(dev);
|
||||
err = call_netdevice_register_notifiers(nb, dev);
|
||||
netdev_unlock_ops(dev);
|
||||
if (err)
|
||||
goto rollback;
|
||||
}
|
||||
@ -10284,7 +10287,9 @@ int bpf_xdp_link_attach(const union bpf_attr *attr, struct bpf_prog *prog)
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
netdev_lock_ops(dev);
|
||||
err = dev_xdp_attach_link(dev, &extack, link);
|
||||
netdev_unlock_ops(dev);
|
||||
rtnl_unlock();
|
||||
|
||||
if (err) {
|
||||
@ -11045,7 +11050,9 @@ int register_netdevice(struct net_device *dev)
|
||||
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
|
||||
|
||||
/* Notify protocols, that a new device appeared. */
|
||||
netdev_lock_ops(dev);
|
||||
ret = call_netdevice_notifiers(NETDEV_REGISTER, dev);
|
||||
netdev_unlock_ops(dev);
|
||||
ret = notifier_to_errno(ret);
|
||||
if (ret) {
|
||||
/* Expect explicit free_netdev() on failure */
|
||||
@ -12057,7 +12064,7 @@ void unregister_netdev(struct net_device *dev)
|
||||
}
|
||||
EXPORT_SYMBOL(unregister_netdev);
|
||||
|
||||
int netif_change_net_namespace(struct net_device *dev, struct net *net,
|
||||
int __dev_change_net_namespace(struct net_device *dev, struct net *net,
|
||||
const char *pat, int new_ifindex,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
@ -12142,11 +12149,12 @@ int netif_change_net_namespace(struct net_device *dev, struct net *net,
|
||||
* And now a mini version of register_netdevice unregister_netdevice.
|
||||
*/
|
||||
|
||||
netdev_lock_ops(dev);
|
||||
/* If device is running close it first. */
|
||||
netif_close(dev);
|
||||
|
||||
/* And unlink it from device chain */
|
||||
unlist_netdevice(dev);
|
||||
netdev_unlock_ops(dev);
|
||||
|
||||
synchronize_net();
|
||||
|
||||
@ -12208,11 +12216,12 @@ int netif_change_net_namespace(struct net_device *dev, struct net *net,
|
||||
err = netdev_change_owner(dev, net_old, net);
|
||||
WARN_ON(err);
|
||||
|
||||
netdev_lock_ops(dev);
|
||||
/* Add the device back in the hashes */
|
||||
list_netdevice(dev);
|
||||
|
||||
/* Notify protocols, that a new device appeared. */
|
||||
call_netdevice_notifiers(NETDEV_REGISTER, dev);
|
||||
netdev_unlock_ops(dev);
|
||||
|
||||
/*
|
||||
* Prevent userspace races by waiting until the network
|
||||
|
@ -117,13 +117,7 @@ EXPORT_SYMBOL(dev_set_mac_address_user);
|
||||
int dev_change_net_namespace(struct net_device *dev, struct net *net,
|
||||
const char *pat)
|
||||
{
|
||||
int ret;
|
||||
|
||||
netdev_lock_ops(dev);
|
||||
ret = netif_change_net_namespace(dev, net, pat, 0, NULL);
|
||||
netdev_unlock_ops(dev);
|
||||
|
||||
return ret;
|
||||
return __dev_change_net_namespace(dev, net, pat, 0, NULL);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dev_change_net_namespace);
|
||||
|
||||
|
@ -8,7 +8,6 @@
|
||||
*/
|
||||
|
||||
#include <linux/dma-buf.h>
|
||||
#include <linux/ethtool_netlink.h>
|
||||
#include <linux/genalloc.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/netdevice.h>
|
||||
@ -117,21 +116,19 @@ void net_devmem_unbind_dmabuf(struct net_devmem_dmabuf_binding *binding)
|
||||
struct netdev_rx_queue *rxq;
|
||||
unsigned long xa_idx;
|
||||
unsigned int rxq_idx;
|
||||
int err;
|
||||
|
||||
if (binding->list.next)
|
||||
list_del(&binding->list);
|
||||
|
||||
xa_for_each(&binding->bound_rxqs, xa_idx, rxq) {
|
||||
WARN_ON(rxq->mp_params.mp_priv != binding);
|
||||
|
||||
rxq->mp_params.mp_priv = NULL;
|
||||
rxq->mp_params.mp_ops = NULL;
|
||||
const struct pp_memory_provider_params mp_params = {
|
||||
.mp_priv = binding,
|
||||
.mp_ops = &dmabuf_devmem_ops,
|
||||
};
|
||||
|
||||
rxq_idx = get_netdev_rx_queue_index(rxq);
|
||||
|
||||
err = netdev_rx_queue_restart(binding->dev, rxq_idx);
|
||||
WARN_ON(err && err != -ENETDOWN);
|
||||
__net_mp_close_rxq(binding->dev, rxq_idx, &mp_params);
|
||||
}
|
||||
|
||||
xa_erase(&net_devmem_dmabuf_bindings, binding->id);
|
||||
@ -143,57 +140,28 @@ int net_devmem_bind_dmabuf_to_queue(struct net_device *dev, u32 rxq_idx,
|
||||
struct net_devmem_dmabuf_binding *binding,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct pp_memory_provider_params mp_params = {
|
||||
.mp_priv = binding,
|
||||
.mp_ops = &dmabuf_devmem_ops,
|
||||
};
|
||||
struct netdev_rx_queue *rxq;
|
||||
u32 xa_idx;
|
||||
int err;
|
||||
|
||||
if (rxq_idx >= dev->real_num_rx_queues) {
|
||||
NL_SET_ERR_MSG(extack, "rx queue index out of range");
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
if (dev->cfg->hds_config != ETHTOOL_TCP_DATA_SPLIT_ENABLED) {
|
||||
NL_SET_ERR_MSG(extack, "tcp-data-split is disabled");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (dev->cfg->hds_thresh) {
|
||||
NL_SET_ERR_MSG(extack, "hds-thresh is not zero");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rxq = __netif_get_rx_queue(dev, rxq_idx);
|
||||
if (rxq->mp_params.mp_ops) {
|
||||
NL_SET_ERR_MSG(extack, "designated queue already memory provider bound");
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_XDP_SOCKETS
|
||||
if (rxq->pool) {
|
||||
NL_SET_ERR_MSG(extack, "designated queue already in use by AF_XDP");
|
||||
return -EBUSY;
|
||||
}
|
||||
#endif
|
||||
|
||||
err = xa_alloc(&binding->bound_rxqs, &xa_idx, rxq, xa_limit_32b,
|
||||
GFP_KERNEL);
|
||||
err = __net_mp_open_rxq(dev, rxq_idx, &mp_params, extack);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
rxq->mp_params.mp_priv = binding;
|
||||
rxq->mp_params.mp_ops = &dmabuf_devmem_ops;
|
||||
|
||||
err = netdev_rx_queue_restart(dev, rxq_idx);
|
||||
rxq = __netif_get_rx_queue(dev, rxq_idx);
|
||||
err = xa_alloc(&binding->bound_rxqs, &xa_idx, rxq, xa_limit_32b,
|
||||
GFP_KERNEL);
|
||||
if (err)
|
||||
goto err_xa_erase;
|
||||
goto err_close_rxq;
|
||||
|
||||
return 0;
|
||||
|
||||
err_xa_erase:
|
||||
rxq->mp_params.mp_priv = NULL;
|
||||
rxq->mp_params.mp_ops = NULL;
|
||||
xa_erase(&binding->bound_rxqs, xa_idx);
|
||||
|
||||
err_close_rxq:
|
||||
__net_mp_close_rxq(dev, rxq_idx, &mp_params);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -165,6 +165,14 @@ static void dst_count_dec(struct dst_entry *dst)
|
||||
void dst_release(struct dst_entry *dst)
|
||||
{
|
||||
if (dst && rcuref_put(&dst->__rcuref)) {
|
||||
#ifdef CONFIG_DST_CACHE
|
||||
if (dst->flags & DST_METADATA) {
|
||||
struct metadata_dst *md_dst = (struct metadata_dst *)dst;
|
||||
|
||||
if (md_dst->type == METADATA_IP_TUNNEL)
|
||||
dst_cache_reset_now(&md_dst->u.tun_info.dst_cache);
|
||||
}
|
||||
#endif
|
||||
dst_count_dec(dst);
|
||||
call_rcu_hurry(&dst->rcu_head, dst_destroy_rcu);
|
||||
}
|
||||
|
@ -6,10 +6,11 @@
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <net/net_namespace.h>
|
||||
#include <net/netdev_lock.h>
|
||||
#include <net/netns/generic.h>
|
||||
|
||||
static int rtnl_net_debug_event(struct notifier_block *nb,
|
||||
unsigned long event, void *ptr)
|
||||
int netdev_debug_event(struct notifier_block *nb, unsigned long event,
|
||||
void *ptr)
|
||||
{
|
||||
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
|
||||
struct net *net = dev_net(dev);
|
||||
@ -17,11 +18,13 @@ static int rtnl_net_debug_event(struct notifier_block *nb,
|
||||
|
||||
/* Keep enum and don't add default to trigger -Werror=switch */
|
||||
switch (cmd) {
|
||||
case NETDEV_REGISTER:
|
||||
case NETDEV_UP:
|
||||
netdev_ops_assert_locked(dev);
|
||||
fallthrough;
|
||||
case NETDEV_DOWN:
|
||||
case NETDEV_REBOOT:
|
||||
case NETDEV_CHANGE:
|
||||
case NETDEV_REGISTER:
|
||||
case NETDEV_UNREGISTER:
|
||||
case NETDEV_CHANGEMTU:
|
||||
case NETDEV_CHANGEADDR:
|
||||
@ -66,6 +69,7 @@ static int rtnl_net_debug_event(struct notifier_block *nb,
|
||||
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(netdev_debug_event, "NETDEV_INTERNAL");
|
||||
|
||||
static int rtnl_net_debug_net_id;
|
||||
|
||||
@ -74,7 +78,7 @@ static int __net_init rtnl_net_debug_net_init(struct net *net)
|
||||
struct notifier_block *nb;
|
||||
|
||||
nb = net_generic(net, rtnl_net_debug_net_id);
|
||||
nb->notifier_call = rtnl_net_debug_event;
|
||||
nb->notifier_call = netdev_debug_event;
|
||||
|
||||
return register_netdevice_notifier_net(net, nb);
|
||||
}
|
||||
@ -95,14 +99,14 @@ static struct pernet_operations rtnl_net_debug_net_ops __net_initdata = {
|
||||
};
|
||||
|
||||
static struct notifier_block rtnl_net_debug_block = {
|
||||
.notifier_call = rtnl_net_debug_event,
|
||||
.notifier_call = netdev_debug_event,
|
||||
};
|
||||
|
||||
static int __init rtnl_net_debug_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = register_pernet_device(&rtnl_net_debug_net_ops);
|
||||
ret = register_pernet_subsys(&rtnl_net_debug_net_ops);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -874,12 +874,6 @@ int netdev_nl_bind_rx_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
goto err_unlock;
|
||||
}
|
||||
|
||||
if (dev_xdp_prog_count(netdev)) {
|
||||
NL_SET_ERR_MSG(info->extack, "unable to bind dmabuf to device with XDP program attached");
|
||||
err = -EEXIST;
|
||||
goto err_unlock;
|
||||
}
|
||||
|
||||
binding = net_devmem_bind_dmabuf(netdev, dmabuf_fd, info->extack);
|
||||
if (IS_ERR(binding)) {
|
||||
err = PTR_ERR(binding);
|
||||
|
@ -1,5 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <linux/ethtool_netlink.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <net/netdev_lock.h>
|
||||
#include <net/netdev_queues.h>
|
||||
@ -86,8 +87,9 @@ err_free_new_mem:
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(netdev_rx_queue_restart, "NETDEV_INTERNAL");
|
||||
|
||||
static int __net_mp_open_rxq(struct net_device *dev, unsigned ifq_idx,
|
||||
struct pp_memory_provider_params *p)
|
||||
int __net_mp_open_rxq(struct net_device *dev, unsigned int rxq_idx,
|
||||
const struct pp_memory_provider_params *p,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct netdev_rx_queue *rxq;
|
||||
int ret;
|
||||
@ -95,16 +97,41 @@ static int __net_mp_open_rxq(struct net_device *dev, unsigned ifq_idx,
|
||||
if (!netdev_need_ops_lock(dev))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (ifq_idx >= dev->real_num_rx_queues)
|
||||
if (rxq_idx >= dev->real_num_rx_queues)
|
||||
return -EINVAL;
|
||||
ifq_idx = array_index_nospec(ifq_idx, dev->real_num_rx_queues);
|
||||
rxq_idx = array_index_nospec(rxq_idx, dev->real_num_rx_queues);
|
||||
|
||||
rxq = __netif_get_rx_queue(dev, ifq_idx);
|
||||
if (rxq->mp_params.mp_ops)
|
||||
if (rxq_idx >= dev->real_num_rx_queues) {
|
||||
NL_SET_ERR_MSG(extack, "rx queue index out of range");
|
||||
return -ERANGE;
|
||||
}
|
||||
if (dev->cfg->hds_config != ETHTOOL_TCP_DATA_SPLIT_ENABLED) {
|
||||
NL_SET_ERR_MSG(extack, "tcp-data-split is disabled");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (dev->cfg->hds_thresh) {
|
||||
NL_SET_ERR_MSG(extack, "hds-thresh is not zero");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (dev_xdp_prog_count(dev)) {
|
||||
NL_SET_ERR_MSG(extack, "unable to custom memory provider to device with XDP program attached");
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
rxq = __netif_get_rx_queue(dev, rxq_idx);
|
||||
if (rxq->mp_params.mp_ops) {
|
||||
NL_SET_ERR_MSG(extack, "designated queue already memory provider bound");
|
||||
return -EEXIST;
|
||||
}
|
||||
#ifdef CONFIG_XDP_SOCKETS
|
||||
if (rxq->pool) {
|
||||
NL_SET_ERR_MSG(extack, "designated queue already in use by AF_XDP");
|
||||
return -EBUSY;
|
||||
}
|
||||
#endif
|
||||
|
||||
rxq->mp_params = *p;
|
||||
ret = netdev_rx_queue_restart(dev, ifq_idx);
|
||||
ret = netdev_rx_queue_restart(dev, rxq_idx);
|
||||
if (ret) {
|
||||
rxq->mp_params.mp_ops = NULL;
|
||||
rxq->mp_params.mp_priv = NULL;
|
||||
@ -112,21 +139,22 @@ static int __net_mp_open_rxq(struct net_device *dev, unsigned ifq_idx,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int net_mp_open_rxq(struct net_device *dev, unsigned ifq_idx,
|
||||
int net_mp_open_rxq(struct net_device *dev, unsigned int rxq_idx,
|
||||
struct pp_memory_provider_params *p)
|
||||
{
|
||||
int ret;
|
||||
|
||||
netdev_lock(dev);
|
||||
ret = __net_mp_open_rxq(dev, ifq_idx, p);
|
||||
ret = __net_mp_open_rxq(dev, rxq_idx, p, NULL);
|
||||
netdev_unlock(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __net_mp_close_rxq(struct net_device *dev, unsigned ifq_idx,
|
||||
struct pp_memory_provider_params *old_p)
|
||||
void __net_mp_close_rxq(struct net_device *dev, unsigned int ifq_idx,
|
||||
const struct pp_memory_provider_params *old_p)
|
||||
{
|
||||
struct netdev_rx_queue *rxq;
|
||||
int err;
|
||||
|
||||
if (WARN_ON_ONCE(ifq_idx >= dev->real_num_rx_queues))
|
||||
return;
|
||||
@ -146,7 +174,8 @@ static void __net_mp_close_rxq(struct net_device *dev, unsigned ifq_idx,
|
||||
|
||||
rxq->mp_params.mp_ops = NULL;
|
||||
rxq->mp_params.mp_priv = NULL;
|
||||
WARN_ON(netdev_rx_queue_restart(dev, ifq_idx));
|
||||
err = netdev_rx_queue_restart(dev, ifq_idx);
|
||||
WARN_ON(err && err != -ENETDOWN);
|
||||
}
|
||||
|
||||
void net_mp_close_rxq(struct net_device *dev, unsigned ifq_idx,
|
||||
|
@ -3025,8 +3025,6 @@ static int do_setlink(const struct sk_buff *skb, struct net_device *dev,
|
||||
char ifname[IFNAMSIZ];
|
||||
int err;
|
||||
|
||||
netdev_lock_ops(dev);
|
||||
|
||||
err = validate_linkmsg(dev, tb, extack);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
@ -3042,14 +3040,16 @@ static int do_setlink(const struct sk_buff *skb, struct net_device *dev,
|
||||
|
||||
new_ifindex = nla_get_s32_default(tb[IFLA_NEW_IFINDEX], 0);
|
||||
|
||||
err = netif_change_net_namespace(dev, tgt_net, pat,
|
||||
err = __dev_change_net_namespace(dev, tgt_net, pat,
|
||||
new_ifindex, extack);
|
||||
if (err)
|
||||
goto errout;
|
||||
return err;
|
||||
|
||||
status |= DO_SETLINK_MODIFIED;
|
||||
}
|
||||
|
||||
netdev_lock_ops(dev);
|
||||
|
||||
if (tb[IFLA_MAP]) {
|
||||
struct rtnl_link_ifmap *u_map;
|
||||
struct ifmap k_map;
|
||||
|
@ -281,7 +281,7 @@ static struct in_device *inetdev_init(struct net_device *dev)
|
||||
if (!in_dev->arp_parms)
|
||||
goto out_kfree;
|
||||
if (IPV4_DEVCONF(in_dev->cnf, FORWARDING))
|
||||
dev_disable_lro(dev);
|
||||
netif_disable_lro(dev);
|
||||
/* Reference in_dev->dev */
|
||||
netdev_hold(dev, &in_dev->dev_tracker, GFP_KERNEL);
|
||||
/* Account for reference dev->ip_ptr (below) */
|
||||
|
@ -416,7 +416,7 @@ int skb_tunnel_check_pmtu(struct sk_buff *skb, struct dst_entry *encap_dst,
|
||||
|
||||
skb_dst_update_pmtu_no_confirm(skb, mtu);
|
||||
|
||||
if (!reply || skb->pkt_type == PACKET_HOST)
|
||||
if (!reply)
|
||||
return 0;
|
||||
|
||||
if (skb->protocol == htons(ETH_P_IP))
|
||||
@ -451,7 +451,7 @@ static const struct nla_policy
|
||||
geneve_opt_policy[LWTUNNEL_IP_OPT_GENEVE_MAX + 1] = {
|
||||
[LWTUNNEL_IP_OPT_GENEVE_CLASS] = { .type = NLA_U16 },
|
||||
[LWTUNNEL_IP_OPT_GENEVE_TYPE] = { .type = NLA_U8 },
|
||||
[LWTUNNEL_IP_OPT_GENEVE_DATA] = { .type = NLA_BINARY, .len = 128 },
|
||||
[LWTUNNEL_IP_OPT_GENEVE_DATA] = { .type = NLA_BINARY, .len = 127 },
|
||||
};
|
||||
|
||||
static const struct nla_policy
|
||||
|
@ -1625,12 +1625,12 @@ static bool udp_skb_has_head_state(struct sk_buff *skb)
|
||||
}
|
||||
|
||||
/* fully reclaim rmem/fwd memory allocated for skb */
|
||||
static void udp_rmem_release(struct sock *sk, int size, int partial,
|
||||
bool rx_queue_lock_held)
|
||||
static void udp_rmem_release(struct sock *sk, unsigned int size,
|
||||
int partial, bool rx_queue_lock_held)
|
||||
{
|
||||
struct udp_sock *up = udp_sk(sk);
|
||||
struct sk_buff_head *sk_queue;
|
||||
int amt;
|
||||
unsigned int amt;
|
||||
|
||||
if (likely(partial)) {
|
||||
up->forward_deficit += size;
|
||||
@ -1650,10 +1650,8 @@ static void udp_rmem_release(struct sock *sk, int size, int partial,
|
||||
if (!rx_queue_lock_held)
|
||||
spin_lock(&sk_queue->lock);
|
||||
|
||||
|
||||
sk_forward_alloc_add(sk, size);
|
||||
amt = (sk->sk_forward_alloc - partial) & ~(PAGE_SIZE - 1);
|
||||
sk_forward_alloc_add(sk, -amt);
|
||||
amt = (size + sk->sk_forward_alloc - partial) & ~(PAGE_SIZE - 1);
|
||||
sk_forward_alloc_add(sk, size - amt);
|
||||
|
||||
if (amt)
|
||||
__sk_mem_reduce_allocated(sk, amt >> PAGE_SHIFT);
|
||||
@ -1725,17 +1723,25 @@ static int udp_rmem_schedule(struct sock *sk, int size)
|
||||
int __udp_enqueue_schedule_skb(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
struct sk_buff_head *list = &sk->sk_receive_queue;
|
||||
int rmem, err = -ENOMEM;
|
||||
unsigned int rmem, rcvbuf;
|
||||
spinlock_t *busy = NULL;
|
||||
int size, rcvbuf;
|
||||
int size, err = -ENOMEM;
|
||||
|
||||
/* Immediately drop when the receive queue is full.
|
||||
* Always allow at least one packet.
|
||||
*/
|
||||
rmem = atomic_read(&sk->sk_rmem_alloc);
|
||||
rcvbuf = READ_ONCE(sk->sk_rcvbuf);
|
||||
if (rmem > rcvbuf)
|
||||
goto drop;
|
||||
size = skb->truesize;
|
||||
|
||||
/* Immediately drop when the receive queue is full.
|
||||
* Cast to unsigned int performs the boundary check for INT_MAX.
|
||||
*/
|
||||
if (rmem + size > rcvbuf) {
|
||||
if (rcvbuf > INT_MAX >> 1)
|
||||
goto drop;
|
||||
|
||||
/* Always allow at least one packet for small buffer. */
|
||||
if (rmem > rcvbuf)
|
||||
goto drop;
|
||||
}
|
||||
|
||||
/* Under mem pressure, it might be helpful to help udp_recvmsg()
|
||||
* having linear skbs :
|
||||
@ -1745,10 +1751,10 @@ int __udp_enqueue_schedule_skb(struct sock *sk, struct sk_buff *skb)
|
||||
*/
|
||||
if (rmem > (rcvbuf >> 1)) {
|
||||
skb_condense(skb);
|
||||
|
||||
size = skb->truesize;
|
||||
busy = busylock_acquire(sk);
|
||||
}
|
||||
size = skb->truesize;
|
||||
|
||||
udp_set_dev_scratch(skb);
|
||||
|
||||
atomic_add(size, &sk->sk_rmem_alloc);
|
||||
@ -1835,7 +1841,7 @@ EXPORT_IPV6_MOD_GPL(skb_consume_udp);
|
||||
|
||||
static struct sk_buff *__first_packet_length(struct sock *sk,
|
||||
struct sk_buff_head *rcvq,
|
||||
int *total)
|
||||
unsigned int *total)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
@ -1868,8 +1874,8 @@ static int first_packet_length(struct sock *sk)
|
||||
{
|
||||
struct sk_buff_head *rcvq = &udp_sk(sk)->reader_queue;
|
||||
struct sk_buff_head *sk_queue = &sk->sk_receive_queue;
|
||||
unsigned int total = 0;
|
||||
struct sk_buff *skb;
|
||||
int total = 0;
|
||||
int res;
|
||||
|
||||
spin_lock_bh(&rcvq->lock);
|
||||
|
@ -80,6 +80,7 @@
|
||||
#include <net/netlink.h>
|
||||
#include <net/pkt_sched.h>
|
||||
#include <net/l3mdev.h>
|
||||
#include <net/netdev_lock.h>
|
||||
#include <linux/if_tunnel.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/netconf.h>
|
||||
@ -377,6 +378,7 @@ static struct inet6_dev *ipv6_add_dev(struct net_device *dev)
|
||||
int err = -ENOMEM;
|
||||
|
||||
ASSERT_RTNL();
|
||||
netdev_ops_assert_locked(dev);
|
||||
|
||||
if (dev->mtu < IPV6_MIN_MTU && dev != blackhole_netdev)
|
||||
return ERR_PTR(-EINVAL);
|
||||
@ -402,7 +404,7 @@ static struct inet6_dev *ipv6_add_dev(struct net_device *dev)
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
if (ndev->cnf.forwarding)
|
||||
dev_disable_lro(dev);
|
||||
netif_disable_lro(dev);
|
||||
/* We refer to the device */
|
||||
netdev_hold(dev, &ndev->dev_tracker, GFP_KERNEL);
|
||||
|
||||
@ -3152,10 +3154,12 @@ int addrconf_add_ifaddr(struct net *net, void __user *arg)
|
||||
|
||||
rtnl_net_lock(net);
|
||||
dev = __dev_get_by_index(net, ireq.ifr6_ifindex);
|
||||
netdev_lock_ops(dev);
|
||||
if (dev)
|
||||
err = inet6_addr_add(net, dev, &cfg, 0, 0, NULL);
|
||||
else
|
||||
err = -ENODEV;
|
||||
netdev_unlock_ops(dev);
|
||||
rtnl_net_unlock(net);
|
||||
return err;
|
||||
}
|
||||
@ -5026,9 +5030,10 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||
if (!dev) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Unable to find the interface");
|
||||
err = -ENODEV;
|
||||
goto unlock;
|
||||
goto unlock_rtnl;
|
||||
}
|
||||
|
||||
netdev_lock_ops(dev);
|
||||
idev = ipv6_find_idev(dev);
|
||||
if (IS_ERR(idev)) {
|
||||
err = PTR_ERR(idev);
|
||||
@ -5065,6 +5070,8 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||
|
||||
in6_ifa_put(ifa);
|
||||
unlock:
|
||||
netdev_unlock_ops(dev);
|
||||
unlock_rtnl:
|
||||
rtnl_net_unlock(net);
|
||||
|
||||
return err;
|
||||
@ -5784,6 +5791,27 @@ static void snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype,
|
||||
}
|
||||
}
|
||||
|
||||
static int inet6_fill_ifla6_stats_attrs(struct sk_buff *skb,
|
||||
struct inet6_dev *idev)
|
||||
{
|
||||
struct nlattr *nla;
|
||||
|
||||
nla = nla_reserve(skb, IFLA_INET6_STATS, IPSTATS_MIB_MAX * sizeof(u64));
|
||||
if (!nla)
|
||||
goto nla_put_failure;
|
||||
snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_STATS, nla_len(nla));
|
||||
|
||||
nla = nla_reserve(skb, IFLA_INET6_ICMP6STATS, ICMP6_MIB_MAX * sizeof(u64));
|
||||
if (!nla)
|
||||
goto nla_put_failure;
|
||||
snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_ICMP6STATS, nla_len(nla));
|
||||
|
||||
return 0;
|
||||
|
||||
nla_put_failure:
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
static int inet6_fill_ifla6_attrs(struct sk_buff *skb, struct inet6_dev *idev,
|
||||
u32 ext_filter_mask)
|
||||
{
|
||||
@ -5806,18 +5834,10 @@ static int inet6_fill_ifla6_attrs(struct sk_buff *skb, struct inet6_dev *idev,
|
||||
|
||||
/* XXX - MC not implemented */
|
||||
|
||||
if (ext_filter_mask & RTEXT_FILTER_SKIP_STATS)
|
||||
return 0;
|
||||
|
||||
nla = nla_reserve(skb, IFLA_INET6_STATS, IPSTATS_MIB_MAX * sizeof(u64));
|
||||
if (!nla)
|
||||
goto nla_put_failure;
|
||||
snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_STATS, nla_len(nla));
|
||||
|
||||
nla = nla_reserve(skb, IFLA_INET6_ICMP6STATS, ICMP6_MIB_MAX * sizeof(u64));
|
||||
if (!nla)
|
||||
goto nla_put_failure;
|
||||
snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_ICMP6STATS, nla_len(nla));
|
||||
if (!(ext_filter_mask & RTEXT_FILTER_SKIP_STATS)) {
|
||||
if (inet6_fill_ifla6_stats_attrs(skb, idev) < 0)
|
||||
goto nla_put_failure;
|
||||
}
|
||||
|
||||
nla = nla_reserve(skb, IFLA_INET6_TOKEN, sizeof(struct in6_addr));
|
||||
if (!nla)
|
||||
@ -6503,7 +6523,9 @@ static int addrconf_sysctl_addr_gen_mode(const struct ctl_table *ctl, int write,
|
||||
|
||||
if (idev->cnf.addr_gen_mode != new_val) {
|
||||
WRITE_ONCE(idev->cnf.addr_gen_mode, new_val);
|
||||
netdev_lock_ops(idev->dev);
|
||||
addrconf_init_auto_addrs(idev->dev);
|
||||
netdev_unlock_ops(idev->dev);
|
||||
}
|
||||
} else if (&net->ipv6.devconf_all->addr_gen_mode == ctl->data) {
|
||||
struct net_device *dev;
|
||||
@ -6515,7 +6537,9 @@ static int addrconf_sysctl_addr_gen_mode(const struct ctl_table *ctl, int write,
|
||||
idev->cnf.addr_gen_mode != new_val) {
|
||||
WRITE_ONCE(idev->cnf.addr_gen_mode,
|
||||
new_val);
|
||||
netdev_lock_ops(idev->dev);
|
||||
addrconf_init_auto_addrs(idev->dev);
|
||||
netdev_unlock_ops(idev->dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1072,8 +1072,13 @@ static int calipso_sock_getattr(struct sock *sk,
|
||||
struct ipv6_opt_hdr *hop;
|
||||
int opt_len, len, ret_val = -ENOMSG, offset;
|
||||
unsigned char *opt;
|
||||
struct ipv6_txoptions *txopts = txopt_get(inet6_sk(sk));
|
||||
struct ipv6_pinfo *pinfo = inet6_sk(sk);
|
||||
struct ipv6_txoptions *txopts;
|
||||
|
||||
if (!pinfo)
|
||||
return -EAFNOSUPPORT;
|
||||
|
||||
txopts = txopt_get(pinfo);
|
||||
if (!txopts || !txopts->hopopt)
|
||||
goto done;
|
||||
|
||||
@ -1125,8 +1130,13 @@ static int calipso_sock_setattr(struct sock *sk,
|
||||
{
|
||||
int ret_val;
|
||||
struct ipv6_opt_hdr *old, *new;
|
||||
struct ipv6_txoptions *txopts = txopt_get(inet6_sk(sk));
|
||||
struct ipv6_pinfo *pinfo = inet6_sk(sk);
|
||||
struct ipv6_txoptions *txopts;
|
||||
|
||||
if (!pinfo)
|
||||
return -EAFNOSUPPORT;
|
||||
|
||||
txopts = txopt_get(pinfo);
|
||||
old = NULL;
|
||||
if (txopts)
|
||||
old = txopts->hopopt;
|
||||
@ -1153,8 +1163,13 @@ static int calipso_sock_setattr(struct sock *sk,
|
||||
static void calipso_sock_delattr(struct sock *sk)
|
||||
{
|
||||
struct ipv6_opt_hdr *new_hop;
|
||||
struct ipv6_txoptions *txopts = txopt_get(inet6_sk(sk));
|
||||
struct ipv6_pinfo *pinfo = inet6_sk(sk);
|
||||
struct ipv6_txoptions *txopts;
|
||||
|
||||
if (!pinfo)
|
||||
return;
|
||||
|
||||
txopts = txopt_get(pinfo);
|
||||
if (!txopts || !txopts->hopopt)
|
||||
goto done;
|
||||
|
||||
|
@ -412,12 +412,37 @@ static bool rt6_check_expired(const struct rt6_info *rt)
|
||||
return false;
|
||||
}
|
||||
|
||||
static struct fib6_info *
|
||||
rt6_multipath_first_sibling_rcu(const struct fib6_info *rt)
|
||||
{
|
||||
struct fib6_info *iter;
|
||||
struct fib6_node *fn;
|
||||
|
||||
fn = rcu_dereference(rt->fib6_node);
|
||||
if (!fn)
|
||||
goto out;
|
||||
iter = rcu_dereference(fn->leaf);
|
||||
if (!iter)
|
||||
goto out;
|
||||
|
||||
while (iter) {
|
||||
if (iter->fib6_metric == rt->fib6_metric &&
|
||||
rt6_qualify_for_ecmp(iter))
|
||||
return iter;
|
||||
iter = rcu_dereference(iter->fib6_next);
|
||||
}
|
||||
|
||||
out:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void fib6_select_path(const struct net *net, struct fib6_result *res,
|
||||
struct flowi6 *fl6, int oif, bool have_oif_match,
|
||||
const struct sk_buff *skb, int strict)
|
||||
{
|
||||
struct fib6_info *match = res->f6i;
|
||||
struct fib6_info *first, *match = res->f6i;
|
||||
struct fib6_info *sibling;
|
||||
int hash;
|
||||
|
||||
if (!match->nh && (!match->fib6_nsiblings || have_oif_match))
|
||||
goto out;
|
||||
@ -440,16 +465,25 @@ void fib6_select_path(const struct net *net, struct fib6_result *res,
|
||||
return;
|
||||
}
|
||||
|
||||
if (fl6->mp_hash <= atomic_read(&match->fib6_nh->fib_nh_upper_bound))
|
||||
first = rt6_multipath_first_sibling_rcu(match);
|
||||
if (!first)
|
||||
goto out;
|
||||
|
||||
list_for_each_entry_rcu(sibling, &match->fib6_siblings,
|
||||
hash = fl6->mp_hash;
|
||||
if (hash <= atomic_read(&first->fib6_nh->fib_nh_upper_bound) &&
|
||||
rt6_score_route(first->fib6_nh, first->fib6_flags, oif,
|
||||
strict) >= 0) {
|
||||
match = first;
|
||||
goto out;
|
||||
}
|
||||
|
||||
list_for_each_entry_rcu(sibling, &first->fib6_siblings,
|
||||
fib6_siblings) {
|
||||
const struct fib6_nh *nh = sibling->fib6_nh;
|
||||
int nh_upper_bound;
|
||||
|
||||
nh_upper_bound = atomic_read(&nh->fib_nh_upper_bound);
|
||||
if (fl6->mp_hash > nh_upper_bound)
|
||||
if (hash > nh_upper_bound)
|
||||
continue;
|
||||
if (rt6_score_route(nh, sibling->fib6_flags, oif, strict) < 0)
|
||||
break;
|
||||
|
@ -2839,11 +2839,11 @@ static int nf_tables_updchain(struct nft_ctx *ctx, u8 genmask, u8 policy,
|
||||
err = nft_netdev_register_hooks(ctx->net, &hook.list);
|
||||
if (err < 0)
|
||||
goto err_hooks;
|
||||
|
||||
unregister = true;
|
||||
}
|
||||
}
|
||||
|
||||
unregister = true;
|
||||
|
||||
if (nla[NFTA_CHAIN_COUNTERS]) {
|
||||
if (!nft_is_base_chain(chain)) {
|
||||
err = -EOPNOTSUPP;
|
||||
|
@ -309,7 +309,8 @@ static bool nft_rhash_expr_needs_gc_run(const struct nft_set *set,
|
||||
|
||||
nft_setelem_expr_foreach(expr, elem_expr, size) {
|
||||
if (expr->ops->gc &&
|
||||
expr->ops->gc(read_pnet(&set->net), expr))
|
||||
expr->ops->gc(read_pnet(&set->net), expr) &&
|
||||
set->flags & NFT_SET_EVAL)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -335,13 +335,13 @@ static int nft_tunnel_obj_erspan_init(const struct nlattr *attr,
|
||||
static const struct nla_policy nft_tunnel_opts_geneve_policy[NFTA_TUNNEL_KEY_GENEVE_MAX + 1] = {
|
||||
[NFTA_TUNNEL_KEY_GENEVE_CLASS] = { .type = NLA_U16 },
|
||||
[NFTA_TUNNEL_KEY_GENEVE_TYPE] = { .type = NLA_U8 },
|
||||
[NFTA_TUNNEL_KEY_GENEVE_DATA] = { .type = NLA_BINARY, .len = 128 },
|
||||
[NFTA_TUNNEL_KEY_GENEVE_DATA] = { .type = NLA_BINARY, .len = 127 },
|
||||
};
|
||||
|
||||
static int nft_tunnel_obj_geneve_init(const struct nlattr *attr,
|
||||
struct nft_tunnel_opts *opts)
|
||||
{
|
||||
struct geneve_opt *opt = (struct geneve_opt *)opts->u.data + opts->len;
|
||||
struct geneve_opt *opt = (struct geneve_opt *)(opts->u.data + opts->len);
|
||||
struct nlattr *tb[NFTA_TUNNEL_KEY_GENEVE_MAX + 1];
|
||||
int err, data_len;
|
||||
|
||||
@ -625,7 +625,7 @@ static int nft_tunnel_opts_dump(struct sk_buff *skb,
|
||||
if (!inner)
|
||||
goto failure;
|
||||
while (opts->len > offset) {
|
||||
opt = (struct geneve_opt *)opts->u.data + offset;
|
||||
opt = (struct geneve_opt *)(opts->u.data + offset);
|
||||
if (nla_put_be16(skb, NFTA_TUNNEL_KEY_GENEVE_CLASS,
|
||||
opt->opt_class) ||
|
||||
nla_put_u8(skb, NFTA_TUNNEL_KEY_GENEVE_TYPE,
|
||||
|
@ -947,12 +947,6 @@ static void do_output(struct datapath *dp, struct sk_buff *skb, int out_port,
|
||||
pskb_trim(skb, ovs_mac_header_len(key));
|
||||
}
|
||||
|
||||
/* Need to set the pkt_type to involve the routing layer. The
|
||||
* packet movement through the OVS datapath doesn't generally
|
||||
* use routing, but this is needed for tunnel cases.
|
||||
*/
|
||||
skb->pkt_type = PACKET_OUTGOING;
|
||||
|
||||
if (likely(!mru ||
|
||||
(skb->len <= mru + vport->dev->hard_header_len))) {
|
||||
ovs_vport_send(vport, skb, ovs_key_mac_proto(key));
|
||||
|
@ -68,7 +68,7 @@ geneve_opt_policy[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX + 1] = {
|
||||
[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_CLASS] = { .type = NLA_U16 },
|
||||
[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_TYPE] = { .type = NLA_U8 },
|
||||
[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA] = { .type = NLA_BINARY,
|
||||
.len = 128 },
|
||||
.len = 127 },
|
||||
};
|
||||
|
||||
static const struct nla_policy
|
||||
|
@ -766,7 +766,7 @@ geneve_opt_policy[TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX + 1] = {
|
||||
[TCA_FLOWER_KEY_ENC_OPT_GENEVE_CLASS] = { .type = NLA_U16 },
|
||||
[TCA_FLOWER_KEY_ENC_OPT_GENEVE_TYPE] = { .type = NLA_U8 },
|
||||
[TCA_FLOWER_KEY_ENC_OPT_GENEVE_DATA] = { .type = NLA_BINARY,
|
||||
.len = 128 },
|
||||
.len = 127 },
|
||||
};
|
||||
|
||||
static const struct nla_policy
|
||||
|
@ -123,8 +123,6 @@ static int skbprio_enqueue(struct sk_buff *skb, struct Qdisc *sch,
|
||||
/* Check to update highest and lowest priorities. */
|
||||
if (skb_queue_empty(lp_qdisc)) {
|
||||
if (q->lowest_prio == q->highest_prio) {
|
||||
/* The incoming packet is the only packet in queue. */
|
||||
BUG_ON(sch->q.qlen != 1);
|
||||
q->lowest_prio = prio;
|
||||
q->highest_prio = prio;
|
||||
} else {
|
||||
@ -156,7 +154,6 @@ static struct sk_buff *skbprio_dequeue(struct Qdisc *sch)
|
||||
/* Update highest priority field. */
|
||||
if (skb_queue_empty(hpq)) {
|
||||
if (q->lowest_prio == q->highest_prio) {
|
||||
BUG_ON(sch->q.qlen);
|
||||
q->highest_prio = 0;
|
||||
q->lowest_prio = SKBPRIO_MAX_PRIORITY - 1;
|
||||
} else {
|
||||
|
@ -525,6 +525,8 @@ static int proc_sctp_do_auth(const struct ctl_table *ctl, int write,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static DEFINE_MUTEX(sctp_sysctl_mutex);
|
||||
|
||||
static int proc_sctp_do_udp_port(const struct ctl_table *ctl, int write,
|
||||
void *buffer, size_t *lenp, loff_t *ppos)
|
||||
{
|
||||
@ -549,6 +551,7 @@ static int proc_sctp_do_udp_port(const struct ctl_table *ctl, int write,
|
||||
if (new_value > max || new_value < min)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&sctp_sysctl_mutex);
|
||||
net->sctp.udp_port = new_value;
|
||||
sctp_udp_sock_stop(net);
|
||||
if (new_value) {
|
||||
@ -561,6 +564,7 @@ static int proc_sctp_do_udp_port(const struct ctl_table *ctl, int write,
|
||||
lock_sock(sk);
|
||||
sctp_sk(sk)->udp_port = htons(net->sctp.udp_port);
|
||||
release_sock(sk);
|
||||
mutex_unlock(&sctp_sysctl_mutex);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -1551,7 +1551,11 @@ static int vsock_connect(struct socket *sock, struct sockaddr *addr,
|
||||
timeout = vsk->connect_timeout;
|
||||
prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
|
||||
|
||||
while (sk->sk_state != TCP_ESTABLISHED && sk->sk_err == 0) {
|
||||
/* If the socket is already closing or it is in an error state, there
|
||||
* is no point in waiting.
|
||||
*/
|
||||
while (sk->sk_state != TCP_ESTABLISHED &&
|
||||
sk->sk_state != TCP_CLOSING && sk->sk_err == 0) {
|
||||
if (flags & O_NONBLOCK) {
|
||||
/* If we're not going to block, we schedule a timeout
|
||||
* function to generate a timeout on the connection
|
||||
|
@ -27,7 +27,7 @@ def _set_flow_rule(cfg, chan):
|
||||
|
||||
|
||||
def test_zcrx(cfg) -> None:
|
||||
cfg.require_v6()
|
||||
cfg.require_ipver('6')
|
||||
|
||||
combined_chans = _get_combined_channels(cfg)
|
||||
if combined_chans < 2:
|
||||
@ -40,7 +40,7 @@ def test_zcrx(cfg) -> None:
|
||||
flow_rule_id = _set_flow_rule(cfg, combined_chans - 1)
|
||||
|
||||
rx_cmd = f"{cfg.bin_remote} -s -p 9999 -i {cfg.ifname} -q {combined_chans - 1}"
|
||||
tx_cmd = f"{cfg.bin_local} -c -h {cfg.remote_v6} -p 9999 -l 12840"
|
||||
tx_cmd = f"{cfg.bin_local} -c -h {cfg.remote_addr_v['6']} -p 9999 -l 12840"
|
||||
with bkg(rx_cmd, host=cfg.remote, exit_wait=True):
|
||||
wait_port_listen(9999, proto="tcp", host=cfg.remote)
|
||||
cmd(tx_cmd)
|
||||
@ -51,7 +51,7 @@ def test_zcrx(cfg) -> None:
|
||||
|
||||
|
||||
def test_zcrx_oneshot(cfg) -> None:
|
||||
cfg.require_v6()
|
||||
cfg.require_ipver('6')
|
||||
|
||||
combined_chans = _get_combined_channels(cfg)
|
||||
if combined_chans < 2:
|
||||
@ -64,7 +64,7 @@ def test_zcrx_oneshot(cfg) -> None:
|
||||
flow_rule_id = _set_flow_rule(cfg, combined_chans - 1)
|
||||
|
||||
rx_cmd = f"{cfg.bin_remote} -s -p 9999 -i {cfg.ifname} -q {combined_chans - 1} -o 4"
|
||||
tx_cmd = f"{cfg.bin_local} -c -h {cfg.remote_v6} -p 9999 -l 4096 -z 16384"
|
||||
tx_cmd = f"{cfg.bin_local} -c -h {cfg.remote_addr_v['6']} -p 9999 -l 4096 -z 16384"
|
||||
with bkg(rx_cmd, host=cfg.remote, exit_wait=True):
|
||||
wait_port_listen(9999, proto="tcp", host=cfg.remote)
|
||||
cmd(tx_cmd)
|
||||
|
@ -194,15 +194,21 @@ test_remote_ip()
|
||||
|
||||
send_mcast_torture4()
|
||||
{
|
||||
ip netns exec "${SOURCE}" bash -c \
|
||||
'cat /dev/urandom | head -c 1G | nc -w 1 -u 239.0.0.1 4001'
|
||||
for i in `seq 10`; do
|
||||
ip netns exec "${SOURCE}" bash -c \
|
||||
'cat /dev/urandom | head -c 100M | nc -w 1 -u 239.0.0.1 4001'
|
||||
echo -n "."
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
send_mcast_torture6()
|
||||
{
|
||||
ip netns exec "${SOURCE}" bash -c \
|
||||
'cat /dev/urandom | head -c 1G | nc -w 1 -u ff0e::5:6 6001'
|
||||
for i in `seq 10`; do
|
||||
ip netns exec "${SOURCE}" bash -c \
|
||||
'cat /dev/urandom | head -c 100M | nc -w 1 -u ff0e::5:6 6001'
|
||||
echo -n "."
|
||||
done
|
||||
}
|
||||
|
||||
check_features()
|
||||
@ -278,10 +284,12 @@ wait $pid || err=$?
|
||||
if [ $err -eq 1 ]; then
|
||||
ERR=1
|
||||
fi
|
||||
printf "TEST: %-50s" "IPv4 amt traffic forwarding torture"
|
||||
send_mcast_torture4
|
||||
printf "TEST: %-60s [ OK ]\n" "IPv4 amt traffic forwarding torture"
|
||||
printf " [ OK ]\n"
|
||||
printf "TEST: %-50s" "IPv6 amt traffic forwarding torture"
|
||||
send_mcast_torture6
|
||||
printf "TEST: %-60s [ OK ]\n" "IPv6 amt traffic forwarding torture"
|
||||
printf " [ OK ]\n"
|
||||
sleep 5
|
||||
if [ "${ERR}" -eq 1 ]; then
|
||||
echo "Some tests failed." >&2
|
||||
|
@ -222,6 +222,31 @@ setup_ns()
|
||||
NS_LIST+=("${ns_list[@]}")
|
||||
}
|
||||
|
||||
# Create netdevsim with given id and net namespace.
|
||||
create_netdevsim() {
|
||||
local id="$1"
|
||||
local ns="$2"
|
||||
|
||||
modprobe netdevsim &> /dev/null
|
||||
udevadm settle
|
||||
|
||||
echo "$id 1" | ip netns exec $ns tee /sys/bus/netdevsim/new_device >/dev/null
|
||||
local dev=$(ip netns exec $ns ls /sys/bus/netdevsim/devices/netdevsim$id/net)
|
||||
ip -netns $ns link set dev $dev name nsim$id
|
||||
ip -netns $ns link set dev nsim$id up
|
||||
|
||||
echo nsim$id
|
||||
}
|
||||
|
||||
# Remove netdevsim with given id.
|
||||
cleanup_netdevsim() {
|
||||
local id="$1"
|
||||
|
||||
if [ -d "/sys/bus/netdevsim/devices/netdevsim$id/net" ]; then
|
||||
echo "$id" > /sys/bus/netdevsim/del_device
|
||||
fi
|
||||
}
|
||||
|
||||
tc_rule_stats_get()
|
||||
{
|
||||
local dev=$1; shift
|
||||
|
@ -7,10 +7,12 @@ set -o pipefail
|
||||
DEV=dummy-dev0
|
||||
DEV2=dummy-dev1
|
||||
ALT_NAME=some-alt-name
|
||||
NSIM_ADDR=2025
|
||||
|
||||
RET_CODE=0
|
||||
|
||||
cleanup() {
|
||||
cleanup_netdevsim $NSIM_ADDR
|
||||
cleanup_ns $NS $test_ns
|
||||
}
|
||||
|
||||
@ -25,12 +27,15 @@ setup_ns NS test_ns
|
||||
|
||||
#
|
||||
# Test basic move without a rename
|
||||
# Use netdevsim because it has extra asserts for notifiers.
|
||||
#
|
||||
ip -netns $NS link add name $DEV type dummy || fail
|
||||
ip -netns $NS link set dev $DEV netns $test_ns ||
|
||||
|
||||
nsim=$(create_netdevsim $NSIM_ADDR $NS)
|
||||
ip -netns $NS link set dev $nsim netns $test_ns ||
|
||||
fail "Can't perform a netns move"
|
||||
ip -netns $test_ns link show dev $DEV >> /dev/null || fail "Device not found after move"
|
||||
ip -netns $test_ns link del $DEV || fail
|
||||
ip -netns $test_ns link show dev $nsim >> /dev/null ||
|
||||
fail "Device not found after move"
|
||||
cleanup_netdevsim $NSIM_ADDR
|
||||
|
||||
#
|
||||
# Test move with a conflict
|
||||
|
@ -12,10 +12,10 @@ def dump_mcaddr_check(rtnl: RtnlAddrFamily) -> None:
|
||||
At least the loopback interface should have this address.
|
||||
"""
|
||||
|
||||
addresses = rtnl.getmaddrs({"ifa-family": socket.AF_INET}, dump=True)
|
||||
addresses = rtnl.getmulticast({"ifa-family": socket.AF_INET}, dump=True)
|
||||
|
||||
all_host_multicasts = [
|
||||
addr for addr in addresses if addr['ifa-multicast'] == IPV4_ALL_HOSTS_MULTICAST
|
||||
addr for addr in addresses if addr['multicast'] == IPV4_ALL_HOSTS_MULTICAST
|
||||
]
|
||||
|
||||
ksft_ge(len(all_host_multicasts), 1,
|
||||
|
@ -16,6 +16,9 @@ static void __setup_lo_intf(const char *lo_intf,
|
||||
|
||||
if (link_set_up(lo_intf))
|
||||
test_error("Failed to bring %s up", lo_intf);
|
||||
|
||||
if (ip_route_add(lo_intf, TEST_FAMILY, local_addr, local_addr))
|
||||
test_error("Failed to add a local route %s", lo_intf);
|
||||
}
|
||||
|
||||
static void setup_lo_intf(const char *lo_intf)
|
||||
|
@ -305,7 +305,7 @@
|
||||
"cmdUnderTest": "$TC actions add action nat ingress default 10.10.10.1 index 12",
|
||||
"expExitCode": "0",
|
||||
"verifyCmd": "$TC actions get action nat index 12",
|
||||
"matchPattern": "action order [0-9]+: nat ingress 0.0.0.0/32 10.10.10.1 pass.*index 12 ref",
|
||||
"matchPattern": "action order [0-9]+: nat ingress 0.0.0.0/0 10.10.10.1 pass.*index 12 ref",
|
||||
"matchCount": "1",
|
||||
"teardown": [
|
||||
"$TC actions flush action nat"
|
||||
@ -332,7 +332,7 @@
|
||||
"cmdUnderTest": "$TC actions add action nat ingress any 10.10.10.1 index 12",
|
||||
"expExitCode": "0",
|
||||
"verifyCmd": "$TC actions get action nat index 12",
|
||||
"matchPattern": "action order [0-9]+: nat ingress 0.0.0.0/32 10.10.10.1 pass.*index 12 ref",
|
||||
"matchPattern": "action order [0-9]+: nat ingress 0.0.0.0/0 10.10.10.1 pass.*index 12 ref",
|
||||
"matchCount": "1",
|
||||
"teardown": [
|
||||
"$TC actions flush action nat"
|
||||
@ -359,7 +359,7 @@
|
||||
"cmdUnderTest": "$TC actions add action nat ingress all 10.10.10.1 index 12",
|
||||
"expExitCode": "0",
|
||||
"verifyCmd": "$TC actions get action nat index 12",
|
||||
"matchPattern": "action order [0-9]+: nat ingress 0.0.0.0/32 10.10.10.1 pass.*index 12 ref",
|
||||
"matchPattern": "action order [0-9]+: nat ingress 0.0.0.0/0 10.10.10.1 pass.*index 12 ref",
|
||||
"matchCount": "1",
|
||||
"teardown": [
|
||||
"$TC actions flush action nat"
|
||||
@ -548,7 +548,7 @@
|
||||
"cmdUnderTest": "$TC actions add action nat egress default 20.20.20.1 pipe index 10",
|
||||
"expExitCode": "0",
|
||||
"verifyCmd": "$TC actions get action nat index 10",
|
||||
"matchPattern": "action order [0-9]+: nat egress 0.0.0.0/32 20.20.20.1 pipe.*index 10 ref",
|
||||
"matchPattern": "action order [0-9]+: nat egress 0.0.0.0/0 20.20.20.1 pipe.*index 10 ref",
|
||||
"matchCount": "1",
|
||||
"teardown": [
|
||||
"$TC actions flush action nat"
|
||||
@ -575,7 +575,7 @@
|
||||
"cmdUnderTest": "$TC actions add action nat egress any 20.20.20.1 pipe index 10",
|
||||
"expExitCode": "0",
|
||||
"verifyCmd": "$TC actions get action nat index 10",
|
||||
"matchPattern": "action order [0-9]+: nat egress 0.0.0.0/32 20.20.20.1 pipe.*index 10 ref",
|
||||
"matchPattern": "action order [0-9]+: nat egress 0.0.0.0/0 20.20.20.1 pipe.*index 10 ref",
|
||||
"matchCount": "1",
|
||||
"teardown": [
|
||||
"$TC actions flush action nat"
|
||||
@ -602,7 +602,7 @@
|
||||
"cmdUnderTest": "$TC actions add action nat egress all 20.20.20.1 pipe index 10",
|
||||
"expExitCode": "0",
|
||||
"verifyCmd": "$TC actions get action nat index 10",
|
||||
"matchPattern": "action order [0-9]+: nat egress 0.0.0.0/32 20.20.20.1 pipe.*index 10 ref",
|
||||
"matchPattern": "action order [0-9]+: nat egress 0.0.0.0/0 20.20.20.1 pipe.*index 10 ref",
|
||||
"matchCount": "1",
|
||||
"teardown": [
|
||||
"$TC actions flush action nat"
|
||||
@ -629,7 +629,7 @@
|
||||
"cmdUnderTest": "$TC actions add action nat egress all 20.20.20.1 pipe index 10 cookie aa1bc2d3eeff112233445566778800a1",
|
||||
"expExitCode": "0",
|
||||
"verifyCmd": "$TC actions get action nat index 10",
|
||||
"matchPattern": "action order [0-9]+: nat egress 0.0.0.0/32 20.20.20.1 pipe.*index 10 ref.*cookie aa1bc2d3eeff112233445566778800a1",
|
||||
"matchPattern": "action order [0-9]+: nat egress 0.0.0.0/0 20.20.20.1 pipe.*index 10 ref.*cookie aa1bc2d3eeff112233445566778800a1",
|
||||
"matchCount": "1",
|
||||
"teardown": [
|
||||
"$TC actions flush action nat"
|
||||
|
@ -126,5 +126,37 @@
|
||||
"$TC qdisc del dev $DUMMY root handle 1: drr",
|
||||
"$IP addr del 10.10.10.10/24 dev $DUMMY"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "c024",
|
||||
"name": "Test TBF with SKBPRIO - catch qlen corner cases",
|
||||
"category": [
|
||||
"qdisc",
|
||||
"tbf",
|
||||
"skbprio"
|
||||
],
|
||||
"plugins": {
|
||||
"requires": "nsPlugin"
|
||||
},
|
||||
"setup": [
|
||||
"$IP link set dev $DUMMY up || true",
|
||||
"$IP addr add 10.10.10.10/24 dev $DUMMY || true",
|
||||
"$TC qdisc add dev $DUMMY handle 1: root tbf rate 100bit burst 2000 limit 1000",
|
||||
"$TC qdisc add dev $DUMMY parent 1: handle 10: skbprio limit 1",
|
||||
"ping -c 1 -W 0.1 -Q 0x00 -s 1400 -I $DUMMY 10.10.10.1 > /dev/null || true",
|
||||
"ping -c 1 -W 0.1 -Q 0x1c -s 1400 -I $DUMMY 10.10.10.1 > /dev/null || true",
|
||||
"ping -c 1 -W 0.1 -Q 0x00 -s 1400 -I $DUMMY 10.10.10.1 > /dev/null || true",
|
||||
"ping -c 1 -W 0.1 -Q 0x1c -s 1400 -I $DUMMY 10.10.10.1 > /dev/null || true",
|
||||
"sleep 0.5"
|
||||
],
|
||||
"cmdUnderTest": "$TC -s qdisc show dev $DUMMY",
|
||||
"expExitCode": "0",
|
||||
"verifyCmd": "$TC -s qdisc show dev $DUMMY | grep -A 5 'qdisc skbprio'",
|
||||
"matchPattern": "dropped [1-9][0-9]*",
|
||||
"matchCount": "1",
|
||||
"teardown": [
|
||||
"$TC qdisc del dev $DUMMY handle 1: root",
|
||||
"$IP addr del 10.10.10.10/24 dev $DUMMY || true"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
Loading…
x
Reference in New Issue
Block a user