mirror of
https://github.com/openvswitch/ovs
synced 2025-08-31 06:15:47 +00:00
userspace: add erspan tunnel support.
ERSPAN is a tunneling protocol based on GRE tunnel. The patch add erspan tunnel support for ovs-vswitchd with userspace datapath. Configuring erspan tunnel is similar to gre tunnel, but with additional erspan's parameters. Matching a flow on erspan's metadata is also supported, see ovs-fields for more details. Signed-off-by: William Tu <u9012063@gmail.com> Signed-off-by: Greg Rose <gvrose8192@gmail.com> Signed-off-by: Ben Pfaff <blp@ovn.org>
This commit is contained in:
32
lib/flow.c
32
lib/flow.c
@@ -126,7 +126,7 @@ struct mf_ctx {
|
||||
* away. Some GCC versions gave warnings on ALWAYS_INLINE, so these are
|
||||
* defined as macros. */
|
||||
|
||||
#if (FLOW_WC_SEQ != 40)
|
||||
#if (FLOW_WC_SEQ != 41)
|
||||
#define MINIFLOW_ASSERT(X) ovs_assert(X)
|
||||
BUILD_MESSAGE("FLOW_WC_SEQ changed: miniflow_extract() will have runtime "
|
||||
"assertions enabled. Consider updating FLOW_WC_SEQ after "
|
||||
@@ -1014,7 +1014,7 @@ flow_get_metadata(const struct flow *flow, struct match *flow_metadata)
|
||||
{
|
||||
int i;
|
||||
|
||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 40);
|
||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 41);
|
||||
|
||||
match_init_catchall(flow_metadata);
|
||||
if (flow->tunnel.tun_id != htonll(0)) {
|
||||
@@ -1042,6 +1042,18 @@ flow_get_metadata(const struct flow *flow, struct match *flow_metadata)
|
||||
if (flow->tunnel.gbp_flags) {
|
||||
match_set_tun_gbp_flags(flow_metadata, flow->tunnel.gbp_flags);
|
||||
}
|
||||
if (flow->tunnel.erspan_ver) {
|
||||
match_set_tun_erspan_ver(flow_metadata, flow->tunnel.erspan_ver);
|
||||
}
|
||||
if (flow->tunnel.erspan_idx) {
|
||||
match_set_tun_erspan_idx(flow_metadata, flow->tunnel.erspan_idx);
|
||||
}
|
||||
if (flow->tunnel.erspan_dir) {
|
||||
match_set_tun_erspan_dir(flow_metadata, flow->tunnel.erspan_dir);
|
||||
}
|
||||
if (flow->tunnel.erspan_hwid) {
|
||||
match_set_tun_erspan_hwid(flow_metadata, flow->tunnel.erspan_hwid);
|
||||
}
|
||||
tun_metadata_get_fmd(&flow->tunnel, flow_metadata);
|
||||
if (flow->metadata != htonll(0)) {
|
||||
match_set_metadata(flow_metadata, flow->metadata);
|
||||
@@ -1581,7 +1593,7 @@ flow_wildcards_init_for_packet(struct flow_wildcards *wc,
|
||||
memset(&wc->masks, 0x0, sizeof wc->masks);
|
||||
|
||||
/* Update this function whenever struct flow changes. */
|
||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 40);
|
||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 41);
|
||||
|
||||
if (flow_tnl_dst_is_set(&flow->tunnel)) {
|
||||
if (flow->tunnel.flags & FLOW_TNL_F_KEY) {
|
||||
@@ -1598,6 +1610,10 @@ flow_wildcards_init_for_packet(struct flow_wildcards *wc,
|
||||
WC_MASK_FIELD(wc, tunnel.tp_dst);
|
||||
WC_MASK_FIELD(wc, tunnel.gbp_id);
|
||||
WC_MASK_FIELD(wc, tunnel.gbp_flags);
|
||||
WC_MASK_FIELD(wc, tunnel.erspan_ver);
|
||||
WC_MASK_FIELD(wc, tunnel.erspan_idx);
|
||||
WC_MASK_FIELD(wc, tunnel.erspan_dir);
|
||||
WC_MASK_FIELD(wc, tunnel.erspan_hwid);
|
||||
|
||||
if (!(flow->tunnel.flags & FLOW_TNL_F_UDPIF)) {
|
||||
if (flow->tunnel.metadata.present.map) {
|
||||
@@ -1728,7 +1744,7 @@ void
|
||||
flow_wc_map(const struct flow *flow, struct flowmap *map)
|
||||
{
|
||||
/* Update this function whenever struct flow changes. */
|
||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 40);
|
||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 41);
|
||||
|
||||
flowmap_init(map);
|
||||
|
||||
@@ -1829,7 +1845,7 @@ void
|
||||
flow_wildcards_clear_non_packet_fields(struct flow_wildcards *wc)
|
||||
{
|
||||
/* Update this function whenever struct flow changes. */
|
||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 40);
|
||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 41);
|
||||
|
||||
memset(&wc->masks.metadata, 0, sizeof wc->masks.metadata);
|
||||
memset(&wc->masks.regs, 0, sizeof wc->masks.regs);
|
||||
@@ -1973,7 +1989,7 @@ flow_wildcards_set_xxreg_mask(struct flow_wildcards *wc, int idx,
|
||||
uint32_t
|
||||
miniflow_hash_5tuple(const struct miniflow *flow, uint32_t basis)
|
||||
{
|
||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 40);
|
||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 41);
|
||||
uint32_t hash = basis;
|
||||
|
||||
if (flow) {
|
||||
@@ -2020,7 +2036,7 @@ ASSERT_SEQUENTIAL(ipv6_src, ipv6_dst);
|
||||
uint32_t
|
||||
flow_hash_5tuple(const struct flow *flow, uint32_t basis)
|
||||
{
|
||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 40);
|
||||
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 41);
|
||||
uint32_t hash = basis;
|
||||
|
||||
if (flow) {
|
||||
@@ -2609,7 +2625,7 @@ flow_push_mpls(struct flow *flow, int n, ovs_be16 mpls_eth_type,
|
||||
|
||||
if (clear_flow_L3) {
|
||||
/* Clear all L3 and L4 fields and dp_hash. */
|
||||
BUILD_ASSERT(FLOW_WC_SEQ == 40);
|
||||
BUILD_ASSERT(FLOW_WC_SEQ == 41);
|
||||
memset((char *) flow + FLOW_SEGMENT_2_ENDS_AT, 0,
|
||||
sizeof(struct flow) - FLOW_SEGMENT_2_ENDS_AT);
|
||||
flow->dp_hash = 0;
|
||||
|
Reference in New Issue
Block a user