/* * 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 #include #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 */