mirror of
https://github.com/openvswitch/ovs
synced 2025-08-22 09:58:01 +00:00
A flow may be modified after its initial offload failed. In this case, according to [1], the modification is handled as a flow add. For a vport flow "add", the orig_in_port should be provided. Keep that field in the flow struct, so it can be provided in the flow modification use case. [1] 0d25621e4d9f ("dpif-netdev: Fix flow modification after failure.") Fixes: b5e6f6f6bfbe ("dpif-netdev: Provide orig_in_port in metadata for tunneled packets.") Signed-off-by: Eli Britstein <elibr@nvidia.com> Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
168 lines
5.7 KiB
C
168 lines
5.7 KiB
C
/*
|
|
* Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2015 Nicira, Inc.
|
|
* Copyright (c) 2019, 2020, 2021 Intel Corporation.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at:
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#ifndef DPIF_NETDEV_PRIVATE_FLOW_H
|
|
#define DPIF_NETDEV_PRIVATE_FLOW_H 1
|
|
|
|
#include "dpif.h"
|
|
#include "dpif-netdev-private-dpcls.h"
|
|
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
|
|
#include "cmap.h"
|
|
#include "openvswitch/thread.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/* Contained by struct dp_netdev_flow's 'stats' member. */
|
|
struct dp_netdev_flow_stats {
|
|
atomic_llong used; /* Last used time, in monotonic msecs. */
|
|
atomic_ullong packet_count; /* Number of packets matched. */
|
|
atomic_ullong byte_count; /* Number of bytes matched. */
|
|
atomic_uint16_t tcp_flags; /* Bitwise-OR of seen tcp_flags values. */
|
|
};
|
|
|
|
/* Contained by struct dp_netdev_flow's 'last_attrs' member. */
|
|
struct dp_netdev_flow_attrs {
|
|
atomic_bool offloaded; /* True if flow is offloaded to HW. */
|
|
ATOMIC(const char *) dp_layer; /* DP layer the flow is handled in. */
|
|
};
|
|
|
|
/* A flow in 'dp_netdev_pmd_thread's 'flow_table'.
|
|
*
|
|
*
|
|
* Thread-safety
|
|
* =============
|
|
*
|
|
* Except near the beginning or ending of its lifespan, rule 'rule' belongs to
|
|
* its pmd thread's classifier. The text below calls this classifier 'cls'.
|
|
*
|
|
* Motivation
|
|
* ----------
|
|
*
|
|
* The thread safety rules described here for "struct dp_netdev_flow" are
|
|
* motivated by two goals:
|
|
*
|
|
* - Prevent threads that read members of "struct dp_netdev_flow" from
|
|
* reading bad data due to changes by some thread concurrently modifying
|
|
* those members.
|
|
*
|
|
* - Prevent two threads making changes to members of a given "struct
|
|
* dp_netdev_flow" from interfering with each other.
|
|
*
|
|
*
|
|
* Rules
|
|
* -----
|
|
*
|
|
* A flow 'flow' may be accessed without a risk of being freed during an RCU
|
|
* grace period. Code that needs to hold onto a flow for a while
|
|
* should try incrementing 'flow->ref_cnt' with dp_netdev_flow_ref().
|
|
*
|
|
* 'flow->ref_cnt' protects 'flow' from being freed. It doesn't protect the
|
|
* flow from being deleted from 'cls' and it doesn't protect members of 'flow'
|
|
* from modification.
|
|
*
|
|
* Some members, marked 'const', are immutable. Accessing other members
|
|
* requires synchronization, as noted in more detail below.
|
|
*/
|
|
struct dp_netdev_flow {
|
|
const struct flow flow; /* Unmasked flow that created this entry. */
|
|
/* Hash table index by unmasked flow. */
|
|
const struct cmap_node node; /* In owning dp_netdev_pmd_thread's */
|
|
/* 'flow_table'. */
|
|
const struct cmap_node simple_match_node; /* In dp_netdev_pmd_thread's
|
|
'simple_match_table'. */
|
|
const struct cmap_node mark_node; /* In owning flow_mark's mark_to_flow */
|
|
const ovs_u128 ufid; /* Unique flow identifier. */
|
|
const ovs_u128 mega_ufid; /* Unique mega flow identifier. */
|
|
const unsigned pmd_id; /* The 'core_id' of pmd thread owning this */
|
|
/* flow. */
|
|
|
|
/* Number of references.
|
|
* The classifier owns one reference.
|
|
* Any thread trying to keep a rule from being freed should hold its own
|
|
* reference. */
|
|
struct ovs_refcount ref_cnt;
|
|
|
|
bool dead;
|
|
uint32_t mark; /* Unique flow mark for netdev offloading. */
|
|
uint64_t simple_match_mark; /* Unique flow mark for the simple match. */
|
|
odp_port_t orig_in_port;
|
|
|
|
/* Statistics. */
|
|
struct dp_netdev_flow_stats stats;
|
|
|
|
/* Statistics and attributes received from the netdev offload provider. */
|
|
atomic_int netdev_flow_get_result;
|
|
struct dp_netdev_flow_stats last_stats;
|
|
struct dp_netdev_flow_attrs last_attrs;
|
|
|
|
/* Actions. */
|
|
OVSRCU_TYPE(struct dp_netdev_actions *) actions;
|
|
|
|
/* While processing a group of input packets, the datapath uses the next
|
|
* member to store a pointer to the output batch for the flow. It is
|
|
* reset after the batch has been sent out (See dp_netdev_queue_batches(),
|
|
* packet_batch_per_flow_init() and packet_batch_per_flow_execute()). */
|
|
struct packet_batch_per_flow *batch;
|
|
|
|
/* Packet classification. */
|
|
char *dp_extra_info; /* String to return in a flow dump/get. */
|
|
struct dpcls_rule cr; /* In owning dp_netdev's 'cls'. */
|
|
/* 'cr' must be the last member. */
|
|
};
|
|
|
|
static inline uint32_t
|
|
dp_netdev_flow_hash(const ovs_u128 *ufid)
|
|
{
|
|
return ufid->u32[0];
|
|
}
|
|
|
|
/* Given the number of bits set in miniflow's maps, returns the size of the
|
|
* 'netdev_flow_key.mf' */
|
|
static inline size_t
|
|
netdev_flow_key_size(size_t flow_u64s)
|
|
{
|
|
return sizeof(struct miniflow) + MINIFLOW_VALUES_SIZE(flow_u64s);
|
|
}
|
|
|
|
/* forward declaration required for EMC to unref flows */
|
|
void dp_netdev_flow_unref(struct dp_netdev_flow *);
|
|
|
|
/* A set of datapath actions within a "struct dp_netdev_flow".
|
|
*
|
|
*
|
|
* Thread-safety
|
|
* =============
|
|
*
|
|
* A struct dp_netdev_actions 'actions' is protected with RCU. */
|
|
struct dp_netdev_actions {
|
|
/* These members are immutable: they do not change during the struct's
|
|
* lifetime. */
|
|
unsigned int size; /* Size of 'actions', in bytes. */
|
|
struct nlattr actions[]; /* Sequence of OVS_ACTION_ATTR_* attributes. */
|
|
};
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* dpif-netdev-private-flow.h */
|