Skip to content

Commit 5e07e1a

Browse files
committed
Merge: openvswitch: stable backport for 10.2 phase 1
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-10/-/merge_requests/1712 JIRA: https://issues.redhat.com/browse/RHEL-115600 * 914ab2142079 selftests: openvswitch: add a simple test for tunnel metadata * 6a4a8eaacaea net: openvswitch: Use for_each_cpu() where appropriate * 1064d9113034 net: openvswitch: fix kernel-doc warnings in internal headers * 586eb64215eb Revert "openvswitch: switch to per-action label counting in conntrack" Signed-off-by: Adrian Moreno <amorenoz@redhat.com> Approved-by: Eelco Chaudron <echaudro@redhat.com> Approved-by: Antoine Tenart <atenart@redhat.com> Approved-by: Paolo Valerio <pvalerio@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: Jan Stancek <jstancek@redhat.com>
2 parents 279ebaa + ef6ac6d commit 5e07e1a

File tree

6 files changed

+130
-35
lines changed

6 files changed

+130
-35
lines changed

net/openvswitch/conntrack.c

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1368,8 +1368,11 @@ bool ovs_ct_verify(struct net *net, enum ovs_key_attr attr)
13681368
attr == OVS_KEY_ATTR_CT_MARK)
13691369
return true;
13701370
if (IS_ENABLED(CONFIG_NF_CONNTRACK_LABELS) &&
1371-
attr == OVS_KEY_ATTR_CT_LABELS)
1372-
return true;
1371+
attr == OVS_KEY_ATTR_CT_LABELS) {
1372+
struct ovs_net *ovs_net = net_generic(net, ovs_net_id);
1373+
1374+
return ovs_net->xt_label;
1375+
}
13731376

13741377
return false;
13751378
}
@@ -1378,7 +1381,6 @@ int ovs_ct_copy_action(struct net *net, const struct nlattr *attr,
13781381
const struct sw_flow_key *key,
13791382
struct sw_flow_actions **sfa, bool log)
13801383
{
1381-
unsigned int n_bits = sizeof(struct ovs_key_ct_labels) * BITS_PER_BYTE;
13821384
struct ovs_conntrack_info ct_info;
13831385
const char *helper = NULL;
13841386
u16 family;
@@ -1407,12 +1409,6 @@ int ovs_ct_copy_action(struct net *net, const struct nlattr *attr,
14071409
return -ENOMEM;
14081410
}
14091411

1410-
if (nf_connlabels_get(net, n_bits - 1)) {
1411-
nf_ct_tmpl_free(ct_info.ct);
1412-
OVS_NLERR(log, "Failed to set connlabel length");
1413-
return -EOPNOTSUPP;
1414-
}
1415-
14161412
if (ct_info.timeout[0]) {
14171413
if (nf_ct_set_timeout(net, ct_info.ct, family, key->ip.proto,
14181414
ct_info.timeout))
@@ -1581,7 +1577,6 @@ static void __ovs_ct_free_action(struct ovs_conntrack_info *ct_info)
15811577
if (ct_info->ct) {
15821578
if (ct_info->timeout[0])
15831579
nf_ct_destroy_timeout(ct_info->ct);
1584-
nf_connlabels_put(nf_ct_net(ct_info->ct));
15851580
nf_ct_tmpl_free(ct_info->ct);
15861581
}
15871582
}
@@ -2006,9 +2001,17 @@ struct genl_family dp_ct_limit_genl_family __ro_after_init = {
20062001

20072002
int ovs_ct_init(struct net *net)
20082003
{
2009-
#if IS_ENABLED(CONFIG_NETFILTER_CONNCOUNT)
2004+
unsigned int n_bits = sizeof(struct ovs_key_ct_labels) * BITS_PER_BYTE;
20102005
struct ovs_net *ovs_net = net_generic(net, ovs_net_id);
20112006

2007+
if (nf_connlabels_get(net, n_bits - 1)) {
2008+
ovs_net->xt_label = false;
2009+
OVS_NLERR(true, "Failed to set connlabel length");
2010+
} else {
2011+
ovs_net->xt_label = true;
2012+
}
2013+
2014+
#if IS_ENABLED(CONFIG_NETFILTER_CONNCOUNT)
20122015
return ovs_ct_limit_init(net, ovs_net);
20132016
#else
20142017
return 0;
@@ -2017,9 +2020,12 @@ int ovs_ct_init(struct net *net)
20172020

20182021
void ovs_ct_exit(struct net *net)
20192022
{
2020-
#if IS_ENABLED(CONFIG_NETFILTER_CONNCOUNT)
20212023
struct ovs_net *ovs_net = net_generic(net, ovs_net_id);
20222024

2025+
#if IS_ENABLED(CONFIG_NETFILTER_CONNCOUNT)
20232026
ovs_ct_limit_exit(net, ovs_net);
20242027
#endif
2028+
2029+
if (ovs_net->xt_label)
2030+
nf_connlabels_put(net);
20252031
}

net/openvswitch/datapath.h

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@
2929
* datapath.
3030
* @n_hit: Number of received packets for which a matching flow was found in
3131
* the flow table.
32-
* @n_miss: Number of received packets that had no matching flow in the flow
33-
* table. The sum of @n_hit and @n_miss is the number of packets that have
32+
* @n_missed: Number of received packets that had no matching flow in the flow
33+
* table. The sum of @n_hit and @n_missed is the number of packets that have
3434
* been received by the datapath.
3535
* @n_lost: Number of received packets that had no matching flow in the flow
3636
* table that could not be sent to userspace (normally due to an overflow in
@@ -40,6 +40,7 @@
4040
* up per packet.
4141
* @n_cache_hit: The number of received packets that had their mask found using
4242
* the mask cache.
43+
* @syncp: Synchronization point for 64bit counters.
4344
*/
4445
struct dp_stats_percpu {
4546
u64 n_hit;
@@ -74,8 +75,10 @@ struct dp_nlsk_pids {
7475
* ovs_mutex and RCU.
7576
* @stats_percpu: Per-CPU datapath statistics.
7677
* @net: Reference to net namespace.
77-
* @max_headroom: the maximum headroom of all vports in this datapath; it will
78+
* @user_features: Bitmap of enabled %OVS_DP_F_* features.
79+
* @max_headroom: The maximum headroom of all vports in this datapath; it will
7880
* be used by all the internal vports in this dp.
81+
* @meter_tbl: Meter table.
7982
* @upcall_portids: RCU protected 'struct dp_nlsk_pids'.
8083
*
8184
* Context: See the comment on locking at the top of datapath.c for additional
@@ -131,10 +134,13 @@ struct ovs_skb_cb {
131134
#define OVS_CB(skb) ((struct ovs_skb_cb *)(skb)->cb)
132135

133136
/**
134-
* struct dp_upcall - metadata to include with a packet to send to userspace
137+
* struct dp_upcall_info - metadata to include with a packet sent to userspace
135138
* @cmd: One of %OVS_PACKET_CMD_*.
136139
* @userdata: If nonnull, its variable-length value is passed to userspace as
137140
* %OVS_PACKET_ATTR_USERDATA.
141+
* @actions: If nonnull, its variable-length value is passed to userspace as
142+
* %OVS_PACKET_ATTR_ACTIONS.
143+
* @actions_len: The length of the @actions.
138144
* @portid: Netlink portid to which packet should be sent. If @portid is 0
139145
* then no packet is sent and the packet is accounted in the datapath's @n_lost
140146
* counter.
@@ -155,6 +161,10 @@ struct dp_upcall_info {
155161
* struct ovs_net - Per net-namespace data for ovs.
156162
* @dps: List of datapaths to enable dumping them all out.
157163
* Protected by genl_mutex.
164+
* @dp_notify_work: A work notifier to handle port unregistering.
165+
* @masks_rebalance: A work to periodically optimize flow table caches.
166+
* @ct_limit_info: A hash table of conntrack zone connection limits.
167+
* @xt_label: Whether connlables are configured for the network or not.
158168
*/
159169
struct ovs_net {
160170
struct list_head dps;
@@ -163,6 +173,7 @@ struct ovs_net {
163173
#if IS_ENABLED(CONFIG_NETFILTER_CONNCOUNT)
164174
struct ovs_ct_limit_info *ct_limit_info;
165175
#endif
176+
bool xt_label;
166177
};
167178

168179
/**

net/openvswitch/flow.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -129,15 +129,13 @@ void ovs_flow_stats_get(const struct sw_flow *flow,
129129
struct ovs_flow_stats *ovs_stats,
130130
unsigned long *used, __be16 *tcp_flags)
131131
{
132-
int cpu;
132+
unsigned int cpu;
133133

134134
*used = 0;
135135
*tcp_flags = 0;
136136
memset(ovs_stats, 0, sizeof(*ovs_stats));
137137

138-
/* We open code this to make sure cpu 0 is always considered */
139-
for (cpu = 0; cpu < nr_cpu_ids;
140-
cpu = cpumask_next(cpu, flow->cpu_used_mask)) {
138+
for_each_cpu(cpu, flow->cpu_used_mask) {
141139
struct sw_flow_stats *stats = rcu_dereference_ovsl(flow->stats[cpu]);
142140

143141
if (stats) {
@@ -158,11 +156,9 @@ void ovs_flow_stats_get(const struct sw_flow *flow,
158156
/* Called with ovs_mutex. */
159157
void ovs_flow_stats_clear(struct sw_flow *flow)
160158
{
161-
int cpu;
159+
unsigned int cpu;
162160

163-
/* We open code this to make sure cpu 0 is always considered */
164-
for (cpu = 0; cpu < nr_cpu_ids;
165-
cpu = cpumask_next(cpu, flow->cpu_used_mask)) {
161+
for_each_cpu(cpu, flow->cpu_used_mask) {
166162
struct sw_flow_stats *stats = ovsl_dereference(flow->stats[cpu]);
167163

168164
if (stats) {

net/openvswitch/flow_table.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,16 +107,15 @@ int ovs_flow_tbl_count(const struct flow_table *table)
107107

108108
static void flow_free(struct sw_flow *flow)
109109
{
110-
int cpu;
110+
unsigned int cpu;
111111

112112
if (ovs_identifier_is_key(&flow->id))
113113
kfree(flow->id.unmasked_key);
114114
if (flow->sf_acts)
115115
ovs_nla_free_flow_actions((struct sw_flow_actions __force *)
116116
flow->sf_acts);
117-
/* We open code this to make sure cpu 0 is always considered */
118-
for (cpu = 0; cpu < nr_cpu_ids;
119-
cpu = cpumask_next(cpu, flow->cpu_used_mask)) {
117+
118+
for_each_cpu(cpu, flow->cpu_used_mask) {
120119
if (flow->stats[cpu])
121120
kmem_cache_free(flow_stats_cache,
122121
(struct sw_flow_stats __force *)flow->stats[cpu]);

net/openvswitch/vport.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ struct vport {
9797
* @desired_ifindex: New vport's ifindex.
9898
* @dp: New vport's datapath.
9999
* @port_no: New vport's port number.
100+
* @upcall_portids: %OVS_VPORT_ATTR_UPCALL_PID attribute from Netlink message,
101+
* %NULL if none was supplied.
100102
*/
101103
struct vport_parms {
102104
const char *name;
@@ -125,6 +127,8 @@ struct vport_parms {
125127
* have any configuration.
126128
* @send: Send a packet on the device.
127129
* zero for dropped packets or negative for error.
130+
* @owner: Module that implements this vport type.
131+
* @list: List entry in the global list of vport types.
128132
*/
129133
struct vport_ops {
130134
enum ovs_vport_type type;
@@ -144,6 +148,7 @@ struct vport_ops {
144148
/**
145149
* struct vport_upcall_stats_percpu - per-cpu packet upcall statistics for
146150
* a given vport.
151+
* @syncp: Synchronization point for 64bit counters.
147152
* @n_success: Number of packets that upcall to userspace succeed.
148153
* @n_fail: Number of packets that upcall to userspace failed.
149154
*/
@@ -164,6 +169,8 @@ void ovs_vport_free(struct vport *);
164169
*
165170
* @vport: vport to access
166171
*
172+
* Returns: A void pointer to a private data allocated in the @vport.
173+
*
167174
* If a nonzero size was passed in priv_size of vport_alloc() a private data
168175
* area was allocated on creation. This allows that area to be accessed and
169176
* used for any purpose needed by the vport implementer.
@@ -178,6 +185,8 @@ static inline void *vport_priv(const struct vport *vport)
178185
*
179186
* @priv: Start of private data area.
180187
*
188+
* Returns: A reference to a vport structure that contains @priv.
189+
*
181190
* It is sometimes useful to translate from a pointer to the private data
182191
* area to the vport, such as in the case where the private data pointer is
183192
* the result of a hash table lookup. @priv must point to the start of the

tools/testing/selftests/net/openvswitch/openvswitch.sh

Lines changed: 81 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ tests="
2525
nat_related_v4 ip4-nat-related: ICMP related matches work with SNAT
2626
netlink_checks ovsnl: validate netlink attrs and settings
2727
upcall_interfaces ovs: test the upcall interfaces
28+
tunnel_metadata ovs: test extraction of tunnel metadata
2829
drop_reason drop: test drop reasons are emitted
2930
psample psample: Sampling packets with psample"
3031

@@ -113,13 +114,13 @@ ovs_add_dp () {
113114
}
114115

115116
ovs_add_if () {
116-
info "Adding IF to DP: br:$2 if:$3"
117-
if [ "$4" != "-u" ]; then
118-
ovs_sbx "$1" python3 $ovs_base/ovs-dpctl.py add-if "$2" "$3" \
119-
|| return 1
117+
info "Adding IF to DP: br:$3 if:$4 ($2)"
118+
if [ "$5" != "-u" ]; then
119+
ovs_sbx "$1" python3 $ovs_base/ovs-dpctl.py add-if \
120+
-t "$2" "$3" "$4" || return 1
120121
else
121122
python3 $ovs_base/ovs-dpctl.py add-if \
122-
-u "$2" "$3" >$ovs_dir/$3.out 2>$ovs_dir/$3.err &
123+
-u -t "$2" "$3" "$4" >$ovs_dir/$4.out 2>$ovs_dir/$4.err &
123124
pid=$!
124125
on_exit "ovs_sbx $1 kill -TERM $pid 2>/dev/null"
125126
fi
@@ -166,9 +167,9 @@ ovs_add_netns_and_veths () {
166167
fi
167168

168169
if [ "$7" != "-u" ]; then
169-
ovs_add_if "$1" "$2" "$4" || return 1
170+
ovs_add_if "$1" "netdev" "$2" "$4" || return 1
170171
else
171-
ovs_add_if "$1" "$2" "$4" -u || return 1
172+
ovs_add_if "$1" "netdev" "$2" "$4" -u || return 1
172173
fi
173174

174175
if [ $TRACING -eq 1 ]; then
@@ -756,6 +757,79 @@ test_upcall_interfaces() {
756757
return 0
757758
}
758759

760+
ovs_add_kernel_tunnel() {
761+
local sbxname=$1; shift
762+
local ns=$1; shift
763+
local tnl_type=$1; shift
764+
local name=$1; shift
765+
local addr=$1; shift
766+
767+
info "setting up kernel ${tnl_type} tunnel ${name}"
768+
ovs_sbx "${sbxname}" ip -netns ${ns} link add dev ${name} type ${tnl_type} $* || return 1
769+
on_exit "ovs_sbx ${sbxname} ip -netns ${ns} link del ${name} >/dev/null 2>&1"
770+
ovs_sbx "${sbxname}" ip -netns ${ns} addr add dev ${name} ${addr} || return 1
771+
ovs_sbx "${sbxname}" ip -netns ${ns} link set dev ${name} mtu 1450 up || return 1
772+
}
773+
774+
test_tunnel_metadata() {
775+
which arping >/dev/null 2>&1 || return $ksft_skip
776+
777+
sbxname="test_tunnel_metadata"
778+
sbx_add "${sbxname}" || return 1
779+
780+
info "setting up new DP"
781+
ovs_add_dp "${sbxname}" tdp0 -V 2:1 || return 1
782+
783+
ovs_add_netns_and_veths "${sbxname}" tdp0 tns left0 l0 \
784+
172.31.110.1/24 || return 1
785+
786+
info "removing veth interface from openvswitch and setting IP"
787+
ovs_del_if "${sbxname}" tdp0 left0 || return 1
788+
ovs_sbx "${sbxname}" ip addr add 172.31.110.2/24 dev left0 || return 1
789+
ovs_sbx "${sbxname}" ip link set left0 up || return 1
790+
791+
info "setting up tunnel port in openvswitch"
792+
ovs_add_if "${sbxname}" "vxlan" tdp0 ovs-vxlan0 -u || return 1
793+
on_exit "ovs_sbx ${sbxname} ip link del ovs-vxlan0"
794+
ovs_wait ip link show ovs-vxlan0 &>/dev/null || return 1
795+
ovs_sbx "${sbxname}" ip link set ovs-vxlan0 up || return 1
796+
797+
configs=$(echo '
798+
1 172.31.221.1/24 1155332 32 set udpcsum flags\(df\|csum\)
799+
2 172.31.222.1/24 1234567 45 set noudpcsum flags\(df\)
800+
3 172.31.223.1/24 1020304 23 unset udpcsum flags\(csum\)
801+
4 172.31.224.1/24 1357986 15 unset noudpcsum' | sed '/^$/d')
802+
803+
while read -r i addr id ttl df csum flags; do
804+
ovs_add_kernel_tunnel "${sbxname}" tns vxlan vxlan${i} ${addr} \
805+
remote 172.31.110.2 id ${id} dstport 4789 \
806+
ttl ${ttl} df ${df} ${csum} || return 1
807+
done <<< "${configs}"
808+
809+
ovs_wait grep -q 'listening on upcall packet handler' \
810+
${ovs_dir}/ovs-vxlan0.out || return 1
811+
812+
info "sending arping"
813+
for i in 1 2 3 4; do
814+
ovs_sbx "${sbxname}" ip netns exec tns \
815+
arping -I vxlan${i} 172.31.22${i}.2 -c 1 \
816+
>${ovs_dir}/arping.stdout 2>${ovs_dir}/arping.stderr
817+
done
818+
819+
info "checking that received decapsulated packets carry correct metadata"
820+
while read -r i addr id ttl df csum flags; do
821+
arp_hdr="arp\\(sip=172.31.22${i}.1,tip=172.31.22${i}.2,op=1,sha="
822+
addrs="src=172.31.110.1,dst=172.31.110.2"
823+
ports="tp_src=[0-9]*,tp_dst=4789"
824+
tnl_md="tunnel\\(tun_id=${id},${addrs},ttl=${ttl},${ports},${flags}\\)"
825+
826+
ovs_sbx "${sbxname}" grep -qE "MISS upcall.*${tnl_md}.*${arp_hdr}" \
827+
${ovs_dir}/ovs-vxlan0.out || return 1
828+
done <<< "${configs}"
829+
830+
return 0
831+
}
832+
759833
run_test() {
760834
(
761835
tname="$1"

0 commit comments

Comments
 (0)