2016-09-14 16:51:27 -07:00
|
|
|
/* Copyright (c) 2016 Nicira, Inc.
|
|
|
|
*
|
|
|
|
* 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 OFPROTO_DPIF_XLATE_CACHE_H
|
|
|
|
#define OFPROTO_DPIF_XLATE_CACHE_H 1
|
|
|
|
|
|
|
|
#include <net/if.h>
|
|
|
|
#include <sys/socket.h>
|
2017-11-06 14:42:32 -08:00
|
|
|
#include <sys/types.h>
|
2016-09-14 16:51:27 -07:00
|
|
|
#include <netinet/in.h>
|
|
|
|
|
|
|
|
#include "openvswitch/types.h"
|
|
|
|
#include "dp-packet.h"
|
|
|
|
#include "odp-util.h"
|
|
|
|
#include "ofproto/ofproto-dpif-mirror.h"
|
|
|
|
#include "openvswitch/ofpbuf.h"
|
|
|
|
|
|
|
|
struct bfd;
|
|
|
|
struct bond;
|
|
|
|
struct dpif_flow_stats;
|
|
|
|
struct flow;
|
|
|
|
struct group_dpif;
|
|
|
|
struct mbridge;
|
|
|
|
struct netdev;
|
|
|
|
struct netflow;
|
|
|
|
struct ofpbuf;
|
|
|
|
struct ofproto_dpif;
|
|
|
|
struct ofputil_bucket;
|
|
|
|
struct ofputil_flow_mod;
|
|
|
|
struct rule_dpif;
|
|
|
|
|
|
|
|
enum xc_type {
|
2016-09-14 16:51:27 -07:00
|
|
|
XC_TABLE,
|
2016-09-14 16:51:27 -07:00
|
|
|
XC_RULE,
|
|
|
|
XC_BOND,
|
|
|
|
XC_NETDEV,
|
|
|
|
XC_NETFLOW,
|
|
|
|
XC_MIRROR,
|
2016-09-14 16:51:27 -07:00
|
|
|
XC_LEARN, /* Calls back to ofproto. */
|
2016-09-14 16:51:27 -07:00
|
|
|
XC_NORMAL,
|
2016-09-14 16:51:27 -07:00
|
|
|
XC_FIN_TIMEOUT, /* Calls back to ofproto. */
|
2016-09-14 16:51:27 -07:00
|
|
|
XC_GROUP,
|
|
|
|
XC_TNL_NEIGH,
|
2017-07-19 14:46:03 +01:00
|
|
|
XC_TUNNEL_HEADER,
|
2016-09-14 16:51:27 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
/* xlate_cache entries hold enough information to perform the side effects of
|
|
|
|
* xlate_actions() for a rule, without needing to perform rule translation
|
|
|
|
* from scratch. The primary usage of these is to submit statistics to objects
|
|
|
|
* that a flow relates to, although they may be used for other effects as well
|
|
|
|
* (for instance, refreshing hard timeouts for learned flows).
|
|
|
|
*
|
ofproto: Add refcount to ofproto to fix ofproto use-after-free.
From hepeng:
https://patchwork.ozlabs.org/project/openvswitch/patch/20200717015041.82746-1-hepeng.0320@bytedance.com/#2487473
also from guohongzhi <guohongzhi1@huawei.com>:
http://patchwork.ozlabs.org/project/openvswitch/patch/20200306130555.19884-1-guohongzhi1@huawei.com/
also from a discussion about the mixing use of RCU and refcount in the mail
list with Ilya Maximets, William Tu, Ben Pfaf, and Gaëtan Rivet.
A summary, as quoted from Ilya:
"
RCU for ofproto was introduced for one
and only one reason - to avoid freeing ofproto while rules are still
alive. This was done in commit f416c8d61601 ("ofproto: RCU postpone
rule destruction."). The goal was to allow using rules without
refcounting them within a single grace period. And that forced us
to postpone destruction of the ofproto for a single grace period.
Later commit 39c9459355b6 ("Use classifier versioning.") made it
possible for rules to be alive for more than one grace period, so
the commit made ofproto wait for 2 grace periods by double postponing.
As we can see now, that wasn't enough and we have to wait for more
than 2 grace periods in certain cases.
"
In a short, the ofproto should have a longer life time than rule, if
the rule lasts for more than 2 grace periods, the ofproto should live
longer to ensure rule->ofproto is valid. It's hard to predict how long
a ofproto should live, thus we need to use refcount on ofproto to make
things easy. The controversial part is that we have already used RCU postpone
to delay ofproto destrution, if we have to add refcount, is it simpler to
use just refcount without RCU postpone?
IMO, I think going back to the pure refcount solution is more
complicated than mixing using both.
Gaëtan Rive asks some questions on guohongzhi's v2 patch:
during ofproto_rule_create, should we use ofproto_ref
or ofproto_try_ref? how can we make sure the ofproto is alive?
By using RCU, ofproto has three states:
state 1: alive, with refcount >= 1
state 2: dying, with refcount == 0, however pointer is valid
state 3: died, memory freed, pointer might be dangling.
Without using RCU, there is no state 2, thus, we have to be very careful
every time we see a ofproto pointer. In contrast, with RCU, we can be sure
that it's alive at least in this grace peroid, so we can just check if
it is dying by ofproto_try_ref.
This shows that by mixing use of RCU and refcount we can save a lot of work
worrying if ofproto is dangling.
In short, the RCU part makes sure the ofproto is alive when we use it,
and the refcount part makes sure it lives longer enough.
In this patch, I have merged guohongzhi's patch and mine, and fixes
accoring to the previous comments.
Acked-by: Adrian Moreno <amorenoz@redhat.com>
Acked-by: Gaetan Rivet <grive@u256.net>
Acked-by: Mike Pattrick <mkp@redhat.com>
Acked-by: Alin-Gabriel Serdean <aserdean@ovn.org>
Tested-by: Alin-Gabriel Serdean <aserdean@ovn.org>
Signed-off-by: Peng He <hepeng.0320@bytedance.com>
Co-authored-by: Hongzhi Guo <guohongzhi1@huawei.com>
Signed-off-by: Hongzhi Guo <guohongzhi1@huawei.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
2022-02-19 03:26:07 +00:00
|
|
|
* An explicit reference is taken to all pointers.
|
|
|
|
*/
|
2016-09-14 16:51:27 -07:00
|
|
|
struct xc_entry {
|
|
|
|
enum xc_type type;
|
|
|
|
union {
|
2016-09-14 16:51:27 -07:00
|
|
|
struct {
|
|
|
|
struct ofproto_dpif *ofproto;
|
|
|
|
uint8_t id;
|
|
|
|
bool match; /* or miss. */
|
|
|
|
} table;
|
2016-09-14 16:51:27 -07:00
|
|
|
struct rule_dpif *rule;
|
|
|
|
struct {
|
|
|
|
struct netdev *tx;
|
|
|
|
struct netdev *rx;
|
|
|
|
struct bfd *bfd;
|
|
|
|
} dev;
|
|
|
|
struct {
|
|
|
|
struct netflow *netflow;
|
|
|
|
struct flow *flow;
|
|
|
|
ofp_port_t iface;
|
|
|
|
} nf;
|
|
|
|
struct {
|
|
|
|
struct mbridge *mbridge;
|
|
|
|
mirror_mask_t mirrors;
|
|
|
|
} mirror;
|
|
|
|
struct {
|
|
|
|
struct bond *bond;
|
|
|
|
struct flow *flow;
|
|
|
|
uint16_t vid;
|
|
|
|
} bond;
|
|
|
|
struct {
|
2016-09-14 16:51:27 -07:00
|
|
|
struct ofproto_flow_mod *ofm;
|
2017-03-10 15:44:40 -08:00
|
|
|
unsigned limit;
|
2016-09-14 16:51:27 -07:00
|
|
|
} learn;
|
|
|
|
struct {
|
|
|
|
struct ofproto_dpif *ofproto;
|
|
|
|
ofp_port_t in_port;
|
|
|
|
struct eth_addr dl_src;
|
|
|
|
int vlan;
|
|
|
|
bool is_gratuitous_arp;
|
|
|
|
} normal;
|
|
|
|
struct {
|
|
|
|
struct rule_dpif *rule;
|
|
|
|
uint16_t idle;
|
|
|
|
uint16_t hard;
|
|
|
|
} fin;
|
|
|
|
struct {
|
|
|
|
struct group_dpif *group;
|
|
|
|
struct ofputil_bucket *bucket;
|
|
|
|
} group;
|
|
|
|
struct {
|
|
|
|
char br_name[IFNAMSIZ];
|
|
|
|
struct in6_addr d_ipv6;
|
|
|
|
} tnl_neigh_cache;
|
2016-09-14 16:51:27 -07:00
|
|
|
struct {
|
|
|
|
struct ofproto_dpif *ofproto;
|
|
|
|
struct ofproto_async_msg *am;
|
|
|
|
} controller;
|
2017-07-19 14:46:03 +01:00
|
|
|
struct {
|
|
|
|
enum {
|
|
|
|
ADD,
|
|
|
|
REMOVE,
|
|
|
|
} operation;
|
|
|
|
uint16_t hdr_size;
|
|
|
|
} tunnel_hdr;
|
2016-09-14 16:51:27 -07:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
#define XC_ENTRY_FOR_EACH(ENTRY, ENTRIES) \
|
|
|
|
for (ENTRY = ofpbuf_try_pull(ENTRIES, sizeof *ENTRY); \
|
|
|
|
ENTRY; \
|
|
|
|
ENTRY = ofpbuf_try_pull(ENTRIES, sizeof *ENTRY))
|
|
|
|
|
|
|
|
struct xlate_cache {
|
|
|
|
struct ofpbuf entries;
|
|
|
|
};
|
|
|
|
|
2016-09-14 16:51:27 -07:00
|
|
|
void xlate_cache_init(struct xlate_cache *);
|
2016-09-14 16:51:27 -07:00
|
|
|
struct xlate_cache *xlate_cache_new(void);
|
|
|
|
struct xc_entry *xlate_cache_add_entry(struct xlate_cache *, enum xc_type);
|
Add offload packets statistics
Add argument '--offload-stats' for command ovs-appctl bridge/dump-flows
to display the offloaded packets statistics.
The commands display as below:
orignal command:
ovs-appctl bridge/dump-flows br0
duration=574s, n_packets=1152, n_bytes=110768, priority=0,actions=NORMAL
table_id=254, duration=574s, n_packets=0, n_bytes=0, priority=2,recirc_id=0,actions=drop
table_id=254, duration=574s, n_packets=0, n_bytes=0, priority=0,reg0=0x1,actions=controller(reason=)
table_id=254, duration=574s, n_packets=0, n_bytes=0, priority=0,reg0=0x2,actions=drop
table_id=254, duration=574s, n_packets=0, n_bytes=0, priority=0,reg0=0x3,actions=drop
new command with argument '--offload-stats'
Notice: 'n_offload_packets' are a subset of n_packets and 'n_offload_bytes' are
a subset of n_bytes.
ovs-appctl bridge/dump-flows --offload-stats br0
duration=582s, n_packets=1152, n_bytes=110768, n_offload_packets=1107, n_offload_bytes=107992, priority=0,actions=NORMAL
table_id=254, duration=582s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=2,recirc_id=0,actions=drop
table_id=254, duration=582s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=0,reg0=0x1,actions=controller(reason=)
table_id=254, duration=582s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=0,reg0=0x2,actions=drop
table_id=254, duration=582s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=0,reg0=0x3,actions=drop
Signed-off-by: zhaozhanxu <zhaozhanxu@163.com>
Signed-off-by: Simon Horman <simon.horman@netronome.com>
2019-12-05 14:26:25 +08:00
|
|
|
void xlate_push_stats_entry(struct xc_entry *, struct dpif_flow_stats *,
|
|
|
|
bool);
|
|
|
|
void xlate_push_stats(struct xlate_cache *, struct dpif_flow_stats *,
|
|
|
|
bool);
|
2016-09-14 16:51:27 -07:00
|
|
|
void xlate_cache_clear_entry(struct xc_entry *);
|
|
|
|
void xlate_cache_clear(struct xlate_cache *);
|
2016-09-14 16:51:27 -07:00
|
|
|
void xlate_cache_uninit(struct xlate_cache *);
|
2016-09-14 16:51:27 -07:00
|
|
|
void xlate_cache_delete(struct xlate_cache *);
|
2017-07-19 14:46:03 +01:00
|
|
|
void xlate_cache_steal_entries(struct xlate_cache *, struct xlate_cache *);
|
2016-09-14 16:51:27 -07:00
|
|
|
|
ofproto: Add ofproto/detrace command to map UFIDs to OpenFlow.
It improves the debugging experience if we can easily get a list of
OpenFlow rules and groups that contribute to the creation of a datapath
flow.
The suggested workflow is:
a. dump datapath flows (along with UUIDs), this also prints the core IDs
(PMD IDs) when applicable.
$ ovs-appctl dpctl/dump-flows -m
flow-dump from pmd on cpu core: 7
ufid:7460db8f..., recirc_id(0), ....
b. dump related OpenFlow rules and groups:
$ ovs-appctl ofproto/detrace ufid:7460db8f... pmd=7
cookie=0x12345678, table=0 priority=100,ip,in_port=2,nw_dst=10.0.0.2,actions=resubmit(,1)
cookie=0x0, table=1 priority=200,actions=group:1
group_id=1,bucket=bucket_id:0,actions=ct(commit,table=2,nat(dst=20.0.0.2))
cookie=0x0, table=2 actions=output:1
The new command only shows rules and groups attached to ukeys that are
in states UKEY_VISIBLE or UKEY_OPERATIONAL. That should be fine as all
other ukeys should not be relevant for the use case presented above.
This commit tries to mimic the output format of the ovs-ofctl
dump-flows/dump-groups commands.
Signed-off-by: Dumitru Ceara <dceara@redhat.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
2024-07-12 15:47:55 +02:00
|
|
|
void xlate_xcache_format(struct ds *, const struct xlate_cache *);
|
|
|
|
|
2016-09-14 16:51:27 -07:00
|
|
|
#endif /* ofproto-dpif-xlate-cache.h */
|