netfilter pull request 24-07-17
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEN9lkrMBJgcdVAPub1V2XiooUIOQFAmaYOsUACgkQ1V2XiooU IOSZfhAAiylt0bXfNLh2dGFpigNqejO0y7uJG/lNALA6kbhqkfdaXyiEGI+ZyIUM qtkpk0BUDEhCtpspOVLNtDYcZkKuH7zzt6MsA9BcNm/5AS4XPB56buPsZ94ic3Uk LZB8X/+q+gT+HC3RF4hf92rfJP6WKvt3mO8GGLstg0r6orGX6DywfwD+jCAIS/HS CgDot0SXS0MQZpTUoMugRpGF8wWBANLjUvLYNjIQhV5vLpRvX/Fal+St1+AsFnzq hdtMDOmqJHy0GNwrOdWX5muK+3X5Fg1rHUIgA1SqALd52lpsv62U9JHN6cvV8nqG h24u3v17rtHg82zbKz4pBVHwurDyIT3TM3Pmp8v+b8ZnYmWsyXLr3lqv3GU5Rx14 HWsEi+FL/ND2mfWF+GOn4JqkWy/97eZ78VkekuuWXfzuNAXedp7OUw7RgfhCl5Pr DZPus0rrnl3nCOeQyXGpo0RacFDOhKESa0EBjHS0+S8nv4vpzS+5XbiZctM0FlSu QhwZM2Q+M6Klr0LWkLYyS99s5Cra3z5z/Oud7xtnlBOp81r0O9YVBYopoV6MM0kV b6IHvOvs+5W+dj8RmH6Chq9D+EmFuYGwPoa5uv6zdSn/2ZeXqKeGq/HnlXuqct37 RCbuV8S1IzJi5EgtwbU0uxBclKkiyCtkhqSNrdjSHxLwf7wgI2s= =I/g9 -----END PGP SIGNATURE----- Merge tag 'nf-24-07-17' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf Pablo Neira Ayuso says: ==================== Netfilter/IPVS fixes for net The following patchset contains Netfilter/IPVS fixes for net: 1) Call nf_expect_get_id() to delete expectation by ID. By trial and error it is possible to leak the LSB of the expectation address on x86_64. This bug is a leftover when converting the existing code to use nf_expect_get_id(). 2) Incorrect initialization in pipapo set backend leads to packet mismatches. From Florian Westphal. 3) Extend netfilter's selftests to cover for the pipapo set backend, also from Florian. 4) Fix sparse warning in IPVS when adding service, from Chen Hanxiao. netfilter pull request 24-07-17 * tag 'nf-24-07-17' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf: ipvs: properly dereference pe in ip_vs_add_service selftests: netfilter: add test case for recent mismatch bug netfilter: nf_set_pipapo: fix initial map fill netfilter: ctnetlink: use helper function to calculate expect ID ==================== Link: https://patch.msgid.link/20240717215214.225394-1-pablo@netfilter.org Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
commit
a1b7dbca14
@ -1459,18 +1459,18 @@ ip_vs_add_service(struct netns_ipvs *ipvs, struct ip_vs_service_user_kern *u,
|
||||
if (ret < 0)
|
||||
goto out_err;
|
||||
|
||||
/* Bind the ct retriever */
|
||||
RCU_INIT_POINTER(svc->pe, pe);
|
||||
pe = NULL;
|
||||
|
||||
/* Update the virtual service counters */
|
||||
if (svc->port == FTPPORT)
|
||||
atomic_inc(&ipvs->ftpsvc_counter);
|
||||
else if (svc->port == 0)
|
||||
atomic_inc(&ipvs->nullsvc_counter);
|
||||
if (svc->pe && svc->pe->conn_out)
|
||||
if (pe && pe->conn_out)
|
||||
atomic_inc(&ipvs->conn_out_counter);
|
||||
|
||||
/* Bind the ct retriever */
|
||||
RCU_INIT_POINTER(svc->pe, pe);
|
||||
pe = NULL;
|
||||
|
||||
/* Count only IPv4 services for old get/setsockopt interface */
|
||||
if (svc->af == AF_INET)
|
||||
ipvs->num_services++;
|
||||
|
@ -3420,7 +3420,8 @@ static int ctnetlink_del_expect(struct sk_buff *skb,
|
||||
|
||||
if (cda[CTA_EXPECT_ID]) {
|
||||
__be32 id = nla_get_be32(cda[CTA_EXPECT_ID]);
|
||||
if (ntohl(id) != (u32)(unsigned long)exp) {
|
||||
|
||||
if (id != nf_expect_get_id(exp)) {
|
||||
nf_ct_expect_put(exp);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
@ -434,7 +434,7 @@ bool nft_pipapo_lookup(const struct net *net, const struct nft_set *set,
|
||||
res_map = scratch->map + (map_index ? m->bsize_max : 0);
|
||||
fill_map = scratch->map + (map_index ? 0 : m->bsize_max);
|
||||
|
||||
memset(res_map, 0xff, m->bsize_max * sizeof(*res_map));
|
||||
pipapo_resmap_init(m, res_map);
|
||||
|
||||
nft_pipapo_for_each_field(f, i, m) {
|
||||
bool last = i == m->field_count - 1;
|
||||
@ -542,7 +542,7 @@ static struct nft_pipapo_elem *pipapo_get(const struct net *net,
|
||||
goto out;
|
||||
}
|
||||
|
||||
memset(res_map, 0xff, m->bsize_max * sizeof(*res_map));
|
||||
pipapo_resmap_init(m, res_map);
|
||||
|
||||
nft_pipapo_for_each_field(f, i, m) {
|
||||
bool last = i == m->field_count - 1;
|
||||
|
@ -278,4 +278,25 @@ static u64 pipapo_estimate_size(const struct nft_set_desc *desc)
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* pipapo_resmap_init() - Initialise result map before first use
|
||||
* @m: Matching data, including mapping table
|
||||
* @res_map: Result map
|
||||
*
|
||||
* Initialize all bits covered by the first field to one, so that after
|
||||
* the first step, only the matching bits of the first bit group remain.
|
||||
*
|
||||
* If other fields have a large bitmap, set remainder of res_map to 0.
|
||||
*/
|
||||
static inline void pipapo_resmap_init(const struct nft_pipapo_match *m, unsigned long *res_map)
|
||||
{
|
||||
const struct nft_pipapo_field *f = m->f;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < f->bsize; i++)
|
||||
res_map[i] = ULONG_MAX;
|
||||
|
||||
for (i = f->bsize; i < m->bsize_max; i++)
|
||||
res_map[i] = 0ul;
|
||||
}
|
||||
#endif /* _NFT_SET_PIPAPO_H */
|
||||
|
@ -1036,6 +1036,7 @@ nothing:
|
||||
|
||||
/**
|
||||
* nft_pipapo_avx2_lookup_slow() - Fallback function for uncommon field sizes
|
||||
* @mdata: Matching data, including mapping table
|
||||
* @map: Previous match result, used as initial bitmap
|
||||
* @fill: Destination bitmap to be filled with current match result
|
||||
* @f: Field, containing lookup and mapping tables
|
||||
@ -1051,7 +1052,8 @@ nothing:
|
||||
* Return: -1 on no match, rule index of match if @last, otherwise first long
|
||||
* word index to be checked next (i.e. first filled word).
|
||||
*/
|
||||
static int nft_pipapo_avx2_lookup_slow(unsigned long *map, unsigned long *fill,
|
||||
static int nft_pipapo_avx2_lookup_slow(const struct nft_pipapo_match *mdata,
|
||||
unsigned long *map, unsigned long *fill,
|
||||
const struct nft_pipapo_field *f,
|
||||
int offset, const u8 *pkt,
|
||||
bool first, bool last)
|
||||
@ -1060,7 +1062,7 @@ static int nft_pipapo_avx2_lookup_slow(unsigned long *map, unsigned long *fill,
|
||||
int i, ret = -1, b;
|
||||
|
||||
if (first)
|
||||
memset(map, 0xff, bsize * sizeof(*map));
|
||||
pipapo_resmap_init(mdata, map);
|
||||
|
||||
for (i = offset; i < bsize; i++) {
|
||||
if (f->bb == 8)
|
||||
@ -1186,7 +1188,7 @@ next_match:
|
||||
} else if (f->groups == 16) {
|
||||
NFT_SET_PIPAPO_AVX2_LOOKUP(8, 16);
|
||||
} else {
|
||||
ret = nft_pipapo_avx2_lookup_slow(res, fill, f,
|
||||
ret = nft_pipapo_avx2_lookup_slow(m, res, fill, f,
|
||||
ret, rp,
|
||||
first, last);
|
||||
}
|
||||
@ -1202,7 +1204,7 @@ next_match:
|
||||
} else if (f->groups == 32) {
|
||||
NFT_SET_PIPAPO_AVX2_LOOKUP(4, 32);
|
||||
} else {
|
||||
ret = nft_pipapo_avx2_lookup_slow(res, fill, f,
|
||||
ret = nft_pipapo_avx2_lookup_slow(m, res, fill, f,
|
||||
ret, rp,
|
||||
first, last);
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ TYPES="net_port port_net net6_port port_proto net6_port_mac net6_port_mac_proto
|
||||
net6_port_net6_port net_port_mac_proto_net"
|
||||
|
||||
# Reported bugs, also described by TYPE_ variables below
|
||||
BUGS="flush_remove_add reload"
|
||||
BUGS="flush_remove_add reload net_port_proto_match"
|
||||
|
||||
# List of possible paths to pktgen script from kernel tree for performance tests
|
||||
PKTGEN_SCRIPT_PATHS="
|
||||
@ -371,6 +371,22 @@ race_repeat 0
|
||||
perf_duration 0
|
||||
"
|
||||
|
||||
TYPE_net_port_proto_match="
|
||||
display net,port,proto
|
||||
type_spec ipv4_addr . inet_service . inet_proto
|
||||
chain_spec ip daddr . udp dport . meta l4proto
|
||||
dst addr4 port proto
|
||||
src
|
||||
start 1
|
||||
count 9
|
||||
src_delta 9
|
||||
tools sendip bash
|
||||
proto udp
|
||||
|
||||
race_repeat 0
|
||||
|
||||
perf_duration 0
|
||||
"
|
||||
# Set template for all tests, types and rules are filled in depending on test
|
||||
set_template='
|
||||
flush ruleset
|
||||
@ -1555,6 +1571,64 @@ test_bug_reload() {
|
||||
nft flush ruleset
|
||||
}
|
||||
|
||||
# - add ranged element, check that packets match it
|
||||
# - delete element again, check it is gone
|
||||
test_bug_net_port_proto_match() {
|
||||
setup veth send_"${proto}" set || return ${ksft_skip}
|
||||
rstart=${start}
|
||||
|
||||
range_size=1
|
||||
for i in $(seq 1 10); do
|
||||
for j in $(seq 1 20) ; do
|
||||
elem=$(printf "10.%d.%d.0/24 . %d1-%d0 . 6-17 " ${i} ${j} ${i} "$((i+1))")
|
||||
|
||||
nft "add element inet filter test { $elem }" || return 1
|
||||
nft "get element inet filter test { $elem }" | grep -q "$elem"
|
||||
if [ $? -ne 0 ];then
|
||||
local got=$(nft "get element inet filter test { $elem }")
|
||||
err "post-add: should have returned $elem but got $got"
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
# recheck after set was filled
|
||||
for i in $(seq 1 10); do
|
||||
for j in $(seq 1 20) ; do
|
||||
elem=$(printf "10.%d.%d.0/24 . %d1-%d0 . 6-17 " ${i} ${j} ${i} "$((i+1))")
|
||||
|
||||
nft "get element inet filter test { $elem }" | grep -q "$elem"
|
||||
if [ $? -ne 0 ];then
|
||||
local got=$(nft "get element inet filter test { $elem }")
|
||||
err "post-fill: should have returned $elem but got $got"
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
# random del and re-fetch
|
||||
for i in $(seq 1 10); do
|
||||
for j in $(seq 1 20) ; do
|
||||
local rnd=$((RANDOM%10))
|
||||
local got=""
|
||||
|
||||
elem=$(printf "10.%d.%d.0/24 . %d1-%d0 . 6-17 " ${i} ${j} ${i} "$((i+1))")
|
||||
if [ $rnd -gt 0 ];then
|
||||
continue
|
||||
fi
|
||||
|
||||
nft "delete element inet filter test { $elem }"
|
||||
got=$(nft "get element inet filter test { $elem }" 2>/dev/null)
|
||||
if [ $? -eq 0 ];then
|
||||
err "post-delete: query for $elem returned $got instead of error."
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
nft flush ruleset
|
||||
}
|
||||
|
||||
test_reported_issues() {
|
||||
eval test_bug_"${subtest}"
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user