mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-27 04:22:58 +00:00
Merge tag 'net-6.3-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Pull networking fixes from Jakub Kicinski:
"Including fixes from netfilter, wifi and ipsec.
A little more changes than usual, but it's pretty normal for us that
the rc3/rc4 PRs are oversized as people start testing in earnest.
Possibly an extra boost from people deploying the 6.1 LTS but that's
more of an unscientific hunch.
Current release - regressions:
- phy: mscc: fix deadlock in phy_ethtool_{get,set}_wol()
- virtio: vsock: don't use skbuff state to account credit
- virtio: vsock: don't drop skbuff on copy failure
- virtio_net: fix page_to_skb() miscalculating the memory size
Current release - new code bugs:
- eth: correct xdp_features after device reconfig
- wifi: nl80211: fix the puncturing bitmap policy
- net/mlx5e: flower:
- fix raw counter initialization
- fix missing error code
- fix cloned flow attribute
- ipa:
- fix some register validity checks
- fix a surprising number of bad offsets
- kill FILT_ROUT_CACHE_CFG IPA register
Previous releases - regressions:
- tcp: fix bind() conflict check for dual-stack wildcard address
- veth: fix use after free in XDP_REDIRECT when skb headroom is small
- ipv4: fix incorrect table ID in IOCTL path
- ipvlan: make skb->skb_iif track skb->dev for l3s mode
- mptcp:
- fix possible deadlock in subflow_error_report
- fix UaFs when destroying unaccepted and listening sockets
- dsa: mv88e6xxx: fix max_mtu of 1492 on 6165, 6191, 6220, 6250, 6290
Previous releases - always broken:
- tcp: tcp_make_synack() can be called from process context, don't
assume preemption is disabled when updating stats
- netfilter: correct length for loading protocol registers
- virtio_net: add checking sq is full inside xdp xmit
- bonding: restore IFF_MASTER/SLAVE flags on bond enslave Ethertype
change
- phy: nxp-c45-tja11xx: fix MII_BASIC_CONFIG_REV bit number
- eth: i40e: fix crash during reboot when adapter is in recovery mode
- eth: ice: avoid deadlock on rtnl lock when auxiliary device
plug/unplug meets bonding
- dsa: mt7530:
- remove now incorrect comment regarding port 5
- set PLL frequency and trgmii only when trgmii is used
- eth: mtk_eth_soc: reset PCS state when changing interface types
Misc:
- ynl: another license adjustment
- move the TCA_EXT_WARN_MSG attribute for tc action"
* tag 'net-6.3-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (108 commits)
selftests: bonding: add tests for ether type changes
bonding: restore bond's IFF_SLAVE flag if a non-eth dev enslave fails
bonding: restore IFF_MASTER/SLAVE flags on bond enslave ether type change
net: renesas: rswitch: Fix GWTSDIE register handling
net: renesas: rswitch: Fix the output value of quote from rswitch_rx()
ethernet: sun: add check for the mdesc_grab()
net: ipa: fix some register validity checks
net: ipa: kill FILT_ROUT_CACHE_CFG IPA register
net: ipa: add two missing declarations
net: ipa: reg: include <linux/bug.h>
net: xdp: don't call notifiers during driver init
net/sched: act_api: add specific EXT_WARN_MSG for tc action
Revert "net/sched: act_api: move TCA_EXT_WARN_MSG to the correct hierarchy"
net: dsa: microchip: fix RGMII delay configuration on KSZ8765/KSZ8794/KSZ8795
ynl: make the tooling check the license
ynl: broaden the license even more
tools: ynl: make definitions optional again
hsr: ratelimit only when errors are printed
qed/qed_mng_tlv: correctly zero out ->min instead of ->hour
selftests: net: devlink_port_split.py: skip test if no suitable device available
...
This commit is contained in:
@@ -8,7 +8,8 @@ TEST_PROGS := \
|
||||
dev_addr_lists.sh \
|
||||
mode-1-recovery-updelay.sh \
|
||||
mode-2-recovery-updelay.sh \
|
||||
option_prio.sh
|
||||
option_prio.sh \
|
||||
bond-eth-type-change.sh
|
||||
|
||||
TEST_FILES := \
|
||||
lag_lib.sh \
|
||||
|
||||
85
tools/testing/selftests/drivers/net/bonding/bond-eth-type-change.sh
Executable file
85
tools/testing/selftests/drivers/net/bonding/bond-eth-type-change.sh
Executable file
@@ -0,0 +1,85 @@
|
||||
#!/bin/bash
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
#
|
||||
# Test bond device ether type changing
|
||||
#
|
||||
|
||||
ALL_TESTS="
|
||||
bond_test_unsuccessful_enslave_type_change
|
||||
bond_test_successful_enslave_type_change
|
||||
"
|
||||
REQUIRE_MZ=no
|
||||
NUM_NETIFS=0
|
||||
lib_dir=$(dirname "$0")
|
||||
source "$lib_dir"/net_forwarding_lib.sh
|
||||
|
||||
bond_check_flags()
|
||||
{
|
||||
local bonddev=$1
|
||||
|
||||
ip -d l sh dev "$bonddev" | grep -q "MASTER"
|
||||
check_err $? "MASTER flag is missing from the bond device"
|
||||
|
||||
ip -d l sh dev "$bonddev" | grep -q "SLAVE"
|
||||
check_err $? "SLAVE flag is missing from the bond device"
|
||||
}
|
||||
|
||||
# test enslaved bond dev type change from ARPHRD_ETHER and back
|
||||
# this allows us to test both MASTER and SLAVE flags at once
|
||||
bond_test_enslave_type_change()
|
||||
{
|
||||
local test_success=$1
|
||||
local devbond0="test-bond0"
|
||||
local devbond1="test-bond1"
|
||||
local devbond2="test-bond2"
|
||||
local nonethdev="test-noneth0"
|
||||
|
||||
# create a non-ARPHRD_ETHER device for testing (e.g. nlmon type)
|
||||
ip link add name "$nonethdev" type nlmon
|
||||
check_err $? "could not create a non-ARPHRD_ETHER device (nlmon)"
|
||||
ip link add name "$devbond0" type bond
|
||||
if [ $test_success -eq 1 ]; then
|
||||
# we need devbond0 in active-backup mode to successfully enslave nonethdev
|
||||
ip link set dev "$devbond0" type bond mode active-backup
|
||||
check_err $? "could not change bond mode to active-backup"
|
||||
fi
|
||||
ip link add name "$devbond1" type bond
|
||||
ip link add name "$devbond2" type bond
|
||||
ip link set dev "$devbond0" master "$devbond1"
|
||||
check_err $? "could not enslave $devbond0 to $devbond1"
|
||||
# change bond type to non-ARPHRD_ETHER
|
||||
ip link set dev "$nonethdev" master "$devbond0" 1>/dev/null 2>/dev/null
|
||||
ip link set dev "$nonethdev" nomaster 1>/dev/null 2>/dev/null
|
||||
# restore ARPHRD_ETHER type by enslaving such device
|
||||
ip link set dev "$devbond2" master "$devbond0"
|
||||
check_err $? "could not enslave $devbond2 to $devbond0"
|
||||
ip link set dev "$devbond1" nomaster
|
||||
|
||||
bond_check_flags "$devbond0"
|
||||
|
||||
# clean up
|
||||
ip link del dev "$devbond0"
|
||||
ip link del dev "$devbond1"
|
||||
ip link del dev "$devbond2"
|
||||
ip link del dev "$nonethdev"
|
||||
}
|
||||
|
||||
bond_test_unsuccessful_enslave_type_change()
|
||||
{
|
||||
RET=0
|
||||
|
||||
bond_test_enslave_type_change 0
|
||||
log_test "Change ether type of an enslaved bond device with unsuccessful enslave"
|
||||
}
|
||||
|
||||
bond_test_successful_enslave_type_change()
|
||||
{
|
||||
RET=0
|
||||
|
||||
bond_test_enslave_type_change 1
|
||||
log_test "Change ether type of an enslaved bond device with successful enslave"
|
||||
}
|
||||
|
||||
tests_run
|
||||
|
||||
exit "$EXIT_STATUS"
|
||||
1
tools/testing/selftests/net/.gitignore
vendored
1
tools/testing/selftests/net/.gitignore
vendored
@@ -1,6 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
bind_bhash
|
||||
bind_timewait
|
||||
bind_wildcard
|
||||
csum
|
||||
cmsg_sender
|
||||
diag_uid
|
||||
|
||||
@@ -80,6 +80,7 @@ TEST_GEN_FILES += sctp_hello
|
||||
TEST_GEN_FILES += csum
|
||||
TEST_GEN_FILES += nat6to4.o
|
||||
TEST_GEN_FILES += ip_local_port_range
|
||||
TEST_GEN_FILES += bind_wildcard
|
||||
|
||||
TEST_FILES := settings
|
||||
|
||||
|
||||
114
tools/testing/selftests/net/bind_wildcard.c
Normal file
114
tools/testing/selftests/net/bind_wildcard.c
Normal file
@@ -0,0 +1,114 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright Amazon.com Inc. or its affiliates. */
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "../kselftest_harness.h"
|
||||
|
||||
FIXTURE(bind_wildcard)
|
||||
{
|
||||
struct sockaddr_in addr4;
|
||||
struct sockaddr_in6 addr6;
|
||||
int expected_errno;
|
||||
};
|
||||
|
||||
FIXTURE_VARIANT(bind_wildcard)
|
||||
{
|
||||
const __u32 addr4_const;
|
||||
const struct in6_addr *addr6_const;
|
||||
};
|
||||
|
||||
FIXTURE_VARIANT_ADD(bind_wildcard, v4_any_v6_any)
|
||||
{
|
||||
.addr4_const = INADDR_ANY,
|
||||
.addr6_const = &in6addr_any,
|
||||
};
|
||||
|
||||
FIXTURE_VARIANT_ADD(bind_wildcard, v4_any_v6_local)
|
||||
{
|
||||
.addr4_const = INADDR_ANY,
|
||||
.addr6_const = &in6addr_loopback,
|
||||
};
|
||||
|
||||
FIXTURE_VARIANT_ADD(bind_wildcard, v4_local_v6_any)
|
||||
{
|
||||
.addr4_const = INADDR_LOOPBACK,
|
||||
.addr6_const = &in6addr_any,
|
||||
};
|
||||
|
||||
FIXTURE_VARIANT_ADD(bind_wildcard, v4_local_v6_local)
|
||||
{
|
||||
.addr4_const = INADDR_LOOPBACK,
|
||||
.addr6_const = &in6addr_loopback,
|
||||
};
|
||||
|
||||
FIXTURE_SETUP(bind_wildcard)
|
||||
{
|
||||
self->addr4.sin_family = AF_INET;
|
||||
self->addr4.sin_port = htons(0);
|
||||
self->addr4.sin_addr.s_addr = htonl(variant->addr4_const);
|
||||
|
||||
self->addr6.sin6_family = AF_INET6;
|
||||
self->addr6.sin6_port = htons(0);
|
||||
self->addr6.sin6_addr = *variant->addr6_const;
|
||||
|
||||
if (variant->addr6_const == &in6addr_any)
|
||||
self->expected_errno = EADDRINUSE;
|
||||
else
|
||||
self->expected_errno = 0;
|
||||
}
|
||||
|
||||
FIXTURE_TEARDOWN(bind_wildcard)
|
||||
{
|
||||
}
|
||||
|
||||
void bind_sockets(struct __test_metadata *_metadata,
|
||||
FIXTURE_DATA(bind_wildcard) *self,
|
||||
struct sockaddr *addr1, socklen_t addrlen1,
|
||||
struct sockaddr *addr2, socklen_t addrlen2)
|
||||
{
|
||||
int fd[2];
|
||||
int ret;
|
||||
|
||||
fd[0] = socket(addr1->sa_family, SOCK_STREAM, 0);
|
||||
ASSERT_GT(fd[0], 0);
|
||||
|
||||
ret = bind(fd[0], addr1, addrlen1);
|
||||
ASSERT_EQ(ret, 0);
|
||||
|
||||
ret = getsockname(fd[0], addr1, &addrlen1);
|
||||
ASSERT_EQ(ret, 0);
|
||||
|
||||
((struct sockaddr_in *)addr2)->sin_port = ((struct sockaddr_in *)addr1)->sin_port;
|
||||
|
||||
fd[1] = socket(addr2->sa_family, SOCK_STREAM, 0);
|
||||
ASSERT_GT(fd[1], 0);
|
||||
|
||||
ret = bind(fd[1], addr2, addrlen2);
|
||||
if (self->expected_errno) {
|
||||
ASSERT_EQ(ret, -1);
|
||||
ASSERT_EQ(errno, self->expected_errno);
|
||||
} else {
|
||||
ASSERT_EQ(ret, 0);
|
||||
}
|
||||
|
||||
close(fd[1]);
|
||||
close(fd[0]);
|
||||
}
|
||||
|
||||
TEST_F(bind_wildcard, v4_v6)
|
||||
{
|
||||
bind_sockets(_metadata, self,
|
||||
(struct sockaddr *)&self->addr4, sizeof(self->addr6),
|
||||
(struct sockaddr *)&self->addr6, sizeof(self->addr6));
|
||||
}
|
||||
|
||||
TEST_F(bind_wildcard, v6_v4)
|
||||
{
|
||||
bind_sockets(_metadata, self,
|
||||
(struct sockaddr *)&self->addr6, sizeof(self->addr6),
|
||||
(struct sockaddr *)&self->addr4, sizeof(self->addr4));
|
||||
}
|
||||
|
||||
TEST_HARNESS_MAIN
|
||||
@@ -59,6 +59,8 @@ class devlink_ports(object):
|
||||
assert stderr == ""
|
||||
ports = json.loads(stdout)['port']
|
||||
|
||||
validate_devlink_output(ports, 'flavour')
|
||||
|
||||
for port in ports:
|
||||
if dev in port:
|
||||
if ports[port]['flavour'] == 'physical':
|
||||
@@ -220,6 +222,27 @@ def split_splittable_port(port, k, lanes, dev):
|
||||
unsplit(port.bus_info)
|
||||
|
||||
|
||||
def validate_devlink_output(devlink_data, target_property=None):
|
||||
"""
|
||||
Determine if test should be skipped by checking:
|
||||
1. devlink_data contains values
|
||||
2. The target_property exist in devlink_data
|
||||
"""
|
||||
skip_reason = None
|
||||
if any(devlink_data.values()):
|
||||
if target_property:
|
||||
skip_reason = "{} not found in devlink output, test skipped".format(target_property)
|
||||
for key in devlink_data:
|
||||
if target_property in devlink_data[key]:
|
||||
skip_reason = None
|
||||
else:
|
||||
skip_reason = 'devlink output is empty, test skipped'
|
||||
|
||||
if skip_reason:
|
||||
print(skip_reason)
|
||||
sys.exit(KSFT_SKIP)
|
||||
|
||||
|
||||
def make_parser():
|
||||
parser = argparse.ArgumentParser(description='A test for port splitting.')
|
||||
parser.add_argument('--dev',
|
||||
@@ -240,12 +263,9 @@ def main(cmdline=None):
|
||||
stdout, stderr = run_command(cmd)
|
||||
assert stderr == ""
|
||||
|
||||
validate_devlink_output(json.loads(stdout))
|
||||
devs = json.loads(stdout)['dev']
|
||||
if devs:
|
||||
dev = list(devs.keys())[0]
|
||||
else:
|
||||
print("no devlink device was found, test skipped")
|
||||
sys.exit(KSFT_SKIP)
|
||||
dev = list(devs.keys())[0]
|
||||
|
||||
cmd = "devlink dev show %s" % dev
|
||||
stdout, stderr = run_command(cmd)
|
||||
@@ -255,6 +275,7 @@ def main(cmdline=None):
|
||||
|
||||
ports = devlink_ports(dev)
|
||||
|
||||
found_max_lanes = False
|
||||
for port in ports.if_names:
|
||||
max_lanes = get_max_lanes(port.name)
|
||||
|
||||
@@ -277,6 +298,11 @@ def main(cmdline=None):
|
||||
split_splittable_port(port, lane, max_lanes, dev)
|
||||
|
||||
lane //= 2
|
||||
found_max_lanes = True
|
||||
|
||||
if not found_max_lanes:
|
||||
print(f"Test not started, no port of device {dev} reports max_lanes")
|
||||
sys.exit(KSFT_SKIP)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -240,7 +240,7 @@ check_expected_one()
|
||||
fi
|
||||
|
||||
stdbuf -o0 -e0 printf "\tExpected value for '%s': '%s', got '%s'.\n" \
|
||||
"${var}" "${!var}" "${!exp}"
|
||||
"${var}" "${!exp}" "${!var}"
|
||||
return 1
|
||||
}
|
||||
|
||||
|
||||
@@ -860,6 +860,114 @@ static void test_stream_poll_rcvlowat_client(const struct test_opts *opts)
|
||||
close(fd);
|
||||
}
|
||||
|
||||
#define INV_BUF_TEST_DATA_LEN 512
|
||||
|
||||
static void test_inv_buf_client(const struct test_opts *opts, bool stream)
|
||||
{
|
||||
unsigned char data[INV_BUF_TEST_DATA_LEN] = {0};
|
||||
ssize_t ret;
|
||||
int fd;
|
||||
|
||||
if (stream)
|
||||
fd = vsock_stream_connect(opts->peer_cid, 1234);
|
||||
else
|
||||
fd = vsock_seqpacket_connect(opts->peer_cid, 1234);
|
||||
|
||||
if (fd < 0) {
|
||||
perror("connect");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
control_expectln("SENDDONE");
|
||||
|
||||
/* Use invalid buffer here. */
|
||||
ret = recv(fd, NULL, sizeof(data), 0);
|
||||
if (ret != -1) {
|
||||
fprintf(stderr, "expected recv(2) failure, got %zi\n", ret);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (errno != ENOMEM) {
|
||||
fprintf(stderr, "unexpected recv(2) errno %d\n", errno);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ret = recv(fd, data, sizeof(data), MSG_DONTWAIT);
|
||||
|
||||
if (stream) {
|
||||
/* For SOCK_STREAM we must continue reading. */
|
||||
if (ret != sizeof(data)) {
|
||||
fprintf(stderr, "expected recv(2) success, got %zi\n", ret);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
/* Don't check errno in case of success. */
|
||||
} else {
|
||||
/* For SOCK_SEQPACKET socket's queue must be empty. */
|
||||
if (ret != -1) {
|
||||
fprintf(stderr, "expected recv(2) failure, got %zi\n", ret);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (errno != EAGAIN) {
|
||||
fprintf(stderr, "unexpected recv(2) errno %d\n", errno);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
control_writeln("DONE");
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
static void test_inv_buf_server(const struct test_opts *opts, bool stream)
|
||||
{
|
||||
unsigned char data[INV_BUF_TEST_DATA_LEN] = {0};
|
||||
ssize_t res;
|
||||
int fd;
|
||||
|
||||
if (stream)
|
||||
fd = vsock_stream_accept(VMADDR_CID_ANY, 1234, NULL);
|
||||
else
|
||||
fd = vsock_seqpacket_accept(VMADDR_CID_ANY, 1234, NULL);
|
||||
|
||||
if (fd < 0) {
|
||||
perror("accept");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
res = send(fd, data, sizeof(data), 0);
|
||||
if (res != sizeof(data)) {
|
||||
fprintf(stderr, "unexpected send(2) result %zi\n", res);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
control_writeln("SENDDONE");
|
||||
|
||||
control_expectln("DONE");
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
static void test_stream_inv_buf_client(const struct test_opts *opts)
|
||||
{
|
||||
test_inv_buf_client(opts, true);
|
||||
}
|
||||
|
||||
static void test_stream_inv_buf_server(const struct test_opts *opts)
|
||||
{
|
||||
test_inv_buf_server(opts, true);
|
||||
}
|
||||
|
||||
static void test_seqpacket_inv_buf_client(const struct test_opts *opts)
|
||||
{
|
||||
test_inv_buf_client(opts, false);
|
||||
}
|
||||
|
||||
static void test_seqpacket_inv_buf_server(const struct test_opts *opts)
|
||||
{
|
||||
test_inv_buf_server(opts, false);
|
||||
}
|
||||
|
||||
static struct test_case test_cases[] = {
|
||||
{
|
||||
.name = "SOCK_STREAM connection reset",
|
||||
@@ -920,6 +1028,16 @@ static struct test_case test_cases[] = {
|
||||
.run_client = test_seqpacket_bigmsg_client,
|
||||
.run_server = test_seqpacket_bigmsg_server,
|
||||
},
|
||||
{
|
||||
.name = "SOCK_STREAM test invalid buffer",
|
||||
.run_client = test_stream_inv_buf_client,
|
||||
.run_server = test_stream_inv_buf_server,
|
||||
},
|
||||
{
|
||||
.name = "SOCK_SEQPACKET test invalid buffer",
|
||||
.run_client = test_seqpacket_inv_buf_client,
|
||||
.run_server = test_seqpacket_inv_buf_server,
|
||||
},
|
||||
{},
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user