On 01/02/2016 12:30, "Chandran, Sugesh" <sugesh.chand...@intel.com> wrote:

>Hi Daniele,
>
>Thank you for sending out the patch.
>The proposal looks fine for me and also I verified that the performance
>is restored with the patch.

Thanks!

>
>One suggestion is , Do we really have to pass two parameters to the
>"dp_netdev_input" to init and validate the metadata.?
>Can we use  the pointer to the port_id/dp_netdev_port. This way there
>wont be a dependency between arguments to a function.
>What do you think?? Does it make more complicated??

I've sent a new version with some suggestions from Andy that
avoids passing two parameters when calling the function
(or at least it hides it).

http://openvswitch.org/pipermail/dev/2016-February/065441.html

What do you think?

Thanks,

Daniele

>
>
>
>Regards
>_Sugesh
>
>
>> -----Original Message-----
>> From: Daniele Di Proietto [mailto:diproiet...@vmware.com]
>> Sent: Friday, January 29, 2016 2:01 AM
>> To: Chandran, Sugesh <sugesh.chand...@intel.com>; jb...@redhat.com;
>> casca...@redhat.com
>> Cc: dev@openvswitch.org
>> Subject: Re: [ovs-dev] [PATCH v3] ipv6 tunneling: Fix for performance
>>drop
>> introduced by ipv6 tunnel support.
>> 
>> Hi Sugesh,
>> 
>> Sorry for the delay, I've been trying to test different approaches.
>> 
>> I tested the patch and I see that the performance is up again. I'm not
>>sure
>> whether introducing the 'dl_type' flag is going to be very easy to
>>maintain,
>> since we have to remember to update when we touch the structure.
>> Unfortunately that structure is used everywhere in OVS, not just in the
>>fast
>> path.
>> 
>> I have prepared a workaround to speed up the metadata initialization
>>here:
>> 
>> http://openvswitch.org/pipermail/dev/2016-January/065263.html
>> 
>> In my setup it restores the throughput to the same numbers. It
>>complicates
>> the code slightly, but the modifications are local to dpif-netdev.
>> 
>> What do you think?
>> 
>> Thanks,
>> 
>> Daniele
>> 
>> On 19/01/2016 09:23, "Sugesh Chandran" <sugesh.chand...@intel.com>
>> wrote:
>> 
>> >Adding a new field called dl_type in flow tunnel structure to verify
>> >the validity of tunnel metadata. This field avoids the need of
>> >resetting and validating the entire ipv4/ipv6 tunnel destination
>> >address which caused a serious performance drop.
>> >
>> >Fixes: 3ae91c019019 ("tunneling: add IPv6 support to
>> >netdev_tunnel_config")
>> >Signed-off-by: Sugesh Chandran <sugesh.chand...@intel.com>
>> >---
>> > lib/flow.c                   |  7 ++---
>> > lib/match.c                  | 12 ++++----
>> > lib/meta-flow.c              | 10 +++++--
>> > lib/netdev-vport.c           | 10 +++----
>> > lib/odp-util.c               | 10 +++----
>> > lib/packets.c                |  7 ++++-
>> > lib/packets.h                | 69
>> >++++++++++++++++++++++++++++++++------------
>> > ofproto/ofproto-dpif-ipfix.c |  3 +-
>> > ofproto/ofproto-dpif-rid.c   |  3 +-
>> > ofproto/ofproto-dpif-sflow.c |  6 ++--
>> > ofproto/tunnel.c             | 12 ++++----
>> > 11 files changed, 96 insertions(+), 53 deletions(-)
>> >
>> >diff --git a/lib/flow.c b/lib/flow.c
>> >index 5668d0c..33aadd1 100644
>> >--- a/lib/flow.c
>> >+++ b/lib/flow.c
>> >@@ -818,15 +818,14 @@ flow_get_metadata(const struct flow *flow,
>> struct
>> >match *flow_metadata)
>> >     if (flow->tunnel.ip_src) {
>> >         match_set_tun_src(flow_metadata, flow->tunnel.ip_src);
>> >     }
>> >-    if (flow->tunnel.ip_dst) {
>> >+    if (flow->tunnel.dl_type == htons(ETH_TYPE_IP)) {
>> >         match_set_tun_dst(flow_metadata, flow->tunnel.ip_dst);
>> >+    } else if (flow->tunnel.dl_type == htons(ETH_TYPE_IPV6)) {
>> >+        match_set_tun_ipv6_dst(flow_metadata, &flow->tunnel.ipv6_dst);
>> >     }
>> >     if (ipv6_addr_is_set(&flow->tunnel.ipv6_src)) {
>> >         match_set_tun_ipv6_src(flow_metadata, &flow->tunnel.ipv6_src);
>> >     }
>> >-    if (ipv6_addr_is_set(&flow->tunnel.ipv6_dst)) {
>> >-        match_set_tun_ipv6_dst(flow_metadata, &flow->tunnel.ipv6_dst);
>> >-    }
>> >     if (flow->tunnel.gbp_id != htons(0)) {
>> >         match_set_tun_gbp_id(flow_metadata, flow->tunnel.gbp_id);
>> >     }
>> >diff --git a/lib/match.c b/lib/match.c
>> >index 95d34bc..97a623e 100644
>> >--- a/lib/match.c
>> >+++ b/lib/match.c
>> >@@ -186,8 +186,8 @@ match_set_tun_dst(struct match *match, ovs_be32
>> >dst)  void  match_set_tun_dst_masked(struct match *match, ovs_be32 dst,
>> >ovs_be32
>> >mask)
>> > {
>> >-    match->wc.masks.tunnel.ip_dst = mask;
>> >-    match->flow.tunnel.ip_dst = dst & mask;
>> >+    set_ipv4_dst_tnl(&match->wc.masks.tunnel, mask);
>> >+    set_ipv4_dst_tnl(&match->flow.tunnel, dst & mask);
>> > }
>> >
>> > void
>> >@@ -208,16 +208,16 @@ match_set_tun_ipv6_src_masked(struct match
>> >*match, const struct in6_addr *src,  void
>> >match_set_tun_ipv6_dst(struct match *match, const struct in6_addr *dst)
>> >{
>> >-    match->flow.tunnel.ipv6_dst = *dst;
>> >-    match->wc.masks.tunnel.ipv6_dst = in6addr_exact;
>> >+    set_ipv6_dst_tnl(&match->flow.tunnel, *dst);
>> >+    set_ipv6_dst_tnl(&match->wc.masks.tunnel, in6addr_exact);
>> > }
>> >
>> > void
>> > match_set_tun_ipv6_dst_masked(struct match *match, const struct
>> >in6_addr *dst,
>> >                               const struct in6_addr *mask)  {
>> >-    match->flow.tunnel.ipv6_dst = ipv6_addr_bitand(dst, mask);
>> >-    match->wc.masks.tunnel.ipv6_dst = *mask;
>> >+    set_ipv6_dst_tnl(&match->flow.tunnel, ipv6_addr_bitand(dst,
>>mask));
>> >+    set_ipv6_dst_tnl(&match->wc.masks.tunnel, *mask);
>> > }
>> >
>> > void
>> >diff --git a/lib/meta-flow.c b/lib/meta-flow.c index 6bd0b99..9d939be
>> >100644
>> >--- a/lib/meta-flow.c
>> >+++ b/lib/meta-flow.c
>> >@@ -1180,13 +1180,13 @@ mf_set_flow_value(const struct mf_field *mf,
>> >         flow->tunnel.ip_src = value->be32;
>> >         break;
>> >     case MFF_TUN_DST:
>> >-        flow->tunnel.ip_dst = value->be32;
>> >+        set_ipv4_dst_tnl(&flow->tunnel, value->be32);
>> >         break;
>> >     case MFF_TUN_IPV6_SRC:
>> >         flow->tunnel.ipv6_src = value->ipv6;
>> >         break;
>> >     case MFF_TUN_IPV6_DST:
>> >-        flow->tunnel.ipv6_dst = value->ipv6;
>> >+        set_ipv6_dst_tnl(&flow->tunnel, value->ipv6);
>> >         break;
>> >     case MFF_TUN_FLAGS:
>> >         flow->tunnel.flags = (flow->tunnel.flags &
>> > ~FLOW_TNL_PUB_F_MASK)
>> >|
>> >@@ -1503,6 +1503,12 @@ mf_set_wild(const struct mf_field *mf, struct
>> >match *match, char **err_str)
>> >                sizeof match->wc.masks.tunnel.ipv6_dst);
>> >         memset(&match->flow.tunnel.ipv6_dst, 0,
>> >                sizeof match->flow.tunnel.ipv6_dst);
>> >+        /* What if flow have a valid ipv4 tunnel data??
>> >+         * Reset the dl_type only if thats not the case.
>> >+         */
>> >+        match->wc.masks.tunnel.dl_type =
>> >+ (match->wc.masks.tunnel.dl_type
>> >==
>> >+                                          htons(ETH_TYPE_IP)) ?
>> >+
>> >+ match->wc.masks.tunnel.dl_type
>> >: 0;
>> >         break;
>> >     case MFF_TUN_FLAGS:
>> >         match_set_tun_flags_masked(match, 0, 0); diff --git
>> >a/lib/netdev-vport.c b/lib/netdev-vport.c index 88f5022..94ddf59 100644
>> >--- a/lib/netdev-vport.c
>> >+++ b/lib/netdev-vport.c
>> >@@ -877,7 +877,7 @@ ip_extract_tnl_md(struct dp_packet *packet, struct
>> >flow_tnl *tnl,  {
>> >     void *nh;
>> >     struct ip_header *ip;
>> >-    struct ovs_16aligned_ip6_hdr *ip6;
>> >+    struct ip6_hdr *ip6;
>> >     void *l4;
>> >     int l3_size;
>> >
>> >@@ -919,19 +919,19 @@ ip_extract_tnl_md(struct dp_packet *packet,
>> >struct flow_tnl *tnl,
>> >         ip_dst = get_16aligned_be32(&ip->ip_dst);
>> >
>> >         tnl->ip_src = ip_src;
>> >-        tnl->ip_dst = ip_dst;
>> >         tnl->ip_tos = ip->ip_tos;
>> >         tnl->ip_ttl = ip->ip_ttl;
>> >+        set_ipv4_dst_tnl(tnl, ip_dst);
>> >
>> >         *hlen += IP_HEADER_LEN;
>> >
>> >     } else if (IP_VER(ip->ip_ihl_ver) == 6) {
>> >
>> >-        memcpy(tnl->ipv6_src.s6_addr, ip6->ip6_src.be16, sizeof
>> >ip6->ip6_src);
>> >-        memcpy(tnl->ipv6_dst.s6_addr, ip6->ip6_dst.be16, sizeof
>> >ip6->ip6_dst);
>> >+        memcpy(tnl->ipv6_src.s6_addr, ip6->ip6_src.s6_addr,
>> >+               sizeof ip6->ip6_src);
>> >         tnl->ip_tos = 0;
>> >         tnl->ip_ttl = ip6->ip6_hlim;
>> >-
>> >+        set_ipv6_dst_tnl(tnl, *(struct in6_addr *)&ip6->ip6_dst);
>> >         *hlen += IPV6_HEADER_LEN;
>> >
>> >     } else {
>> >diff --git a/lib/odp-util.c b/lib/odp-util.c index f16e113..309bb9c
>> >100644
>> >--- a/lib/odp-util.c
>> >+++ b/lib/odp-util.c
>> >@@ -510,7 +510,7 @@ format_odp_tnl_push_header(struct ds *ds, struct
>> >ovs_action_push_tnl *data)
>> >                       gnh->oam ? "oam," : "",
>> >                       gnh->critical ? "crit," : "",
>> >                       ntohl(get_16aligned_be32(&gnh->vni)) >> 8);
>> >-
>> >+
>> >         if (gnh->opt_len) {
>> >             ds_put_cstr(ds, ",options(");
>> >             format_geneve_opts(gnh->options, NULL, gnh->opt_len * 4,
>> >@@ -1864,13 +1864,13 @@ odp_tun_key_from_attr__(const struct nlattr
>> *attr,
>> >             tun->ip_src = nl_attr_get_be32(a);
>> >             break;
>> >         case OVS_TUNNEL_KEY_ATTR_IPV4_DST:
>> >-            tun->ip_dst = nl_attr_get_be32(a);
>> >+            set_ipv4_dst_tnl(tun, nl_attr_get_be32(a));
>> >             break;
>> >         case OVS_TUNNEL_KEY_ATTR_IPV6_SRC:
>> >             tun->ipv6_src = nl_attr_get_in6_addr(a);
>> >             break;
>> >         case OVS_TUNNEL_KEY_ATTR_IPV6_DST:
>> >-            tun->ipv6_dst = nl_attr_get_in6_addr(a);
>> >+            set_ipv6_dst_tnl(tun, nl_attr_get_in6_addr(a));
>> >             break;
>> >         case OVS_TUNNEL_KEY_ATTR_TOS:
>> >             tun->ip_tos = nl_attr_get_u8(a); @@ -1961,13 +1961,13 @@
>> >tun_key_to_attr(struct ofpbuf *a, const struct flow_tnl *tun_key,
>> >     if (tun_key->ip_src) {
>> >         nl_msg_put_be32(a, OVS_TUNNEL_KEY_ATTR_IPV4_SRC,
>> >tun_key->ip_src);
>> >     }
>> >-    if (tun_key->ip_dst) {
>> >+    if (tun_key->dl_type == htons(ETH_TYPE_IP)) {
>> >         nl_msg_put_be32(a, OVS_TUNNEL_KEY_ATTR_IPV4_DST,
>> >tun_key->ip_dst);
>> >     }
>> >     if (ipv6_addr_is_set(&tun_key->ipv6_src)) {
>> >         nl_msg_put_in6_addr(a, OVS_TUNNEL_KEY_ATTR_IPV6_SRC,
>> >&tun_key->ipv6_src);
>> >     }
>> >-    if (ipv6_addr_is_set(&tun_key->ipv6_dst)) {
>> >+    if (tun_key->dl_type == htons(ETH_TYPE_IPV6)) {
>> >         nl_msg_put_in6_addr(a, OVS_TUNNEL_KEY_ATTR_IPV6_DST,
>> >&tun_key->ipv6_dst);
>> >     }
>> >     if (tun_key->ip_tos) {
>> >diff --git a/lib/packets.c b/lib/packets.c index d82341d..4f00c0e
>> >100644
>> >--- a/lib/packets.c
>> >+++ b/lib/packets.c
>> >@@ -39,7 +39,12 @@ const struct in6_addr in6addr_all_hosts =
>> >IN6ADDR_ALL_HOSTS_INIT;  struct in6_addr  flow_tnl_dst(const struct
>> >flow_tnl *tnl)  {
>> >-    return tnl->ip_dst ? in6_addr_mapped_ipv4(tnl->ip_dst) :
>> >tnl->ipv6_dst;
>> >+    if (tnl->dl_type == htons(ETH_TYPE_IP)) {
>> >+        return in6_addr_mapped_ipv4(tnl->ip_dst);
>> >+    } else if (tnl->dl_type == htons(ETH_TYPE_IPV6)) {
>> >+        return tnl->ipv6_dst;
>> >+    }
>> >+    return in6addr_any;
>> > }
>> >
>> > struct in6_addr
>> >diff --git a/lib/packets.h b/lib/packets.h index 834e8a4..7e8dd91
>> >100644
>> >--- a/lib/packets.h
>> >+++ b/lib/packets.h
>> >@@ -35,8 +35,26 @@
>> > struct dp_packet;
>> > struct ds;
>> >
>> >+#define ETH_TYPE_IP            0x0800
>> >+#define ETH_TYPE_ARP           0x0806
>> >+#define ETH_TYPE_TEB           0x6558
>> >+#define ETH_TYPE_VLAN_8021Q    0x8100
>> >+#define ETH_TYPE_VLAN          ETH_TYPE_VLAN_8021Q
>> >+#define ETH_TYPE_VLAN_8021AD   0x88a8
>> >+#define ETH_TYPE_IPV6          0x86dd
>> >+#define ETH_TYPE_LACP          0x8809
>> >+#define ETH_TYPE_RARP          0x8035
>> >+#define ETH_TYPE_MPLS          0x8847
>> >+#define ETH_TYPE_MPLS_MCAST    0x8848
>> >+
>> > /* Tunnel information used in flow key and metadata. */ struct
>> > flow_tnl {
>> >+    /* The tunnel destination ip/ipv6 address are not initializing to
>> >zero
>> >+     * due to the performance constrains. the ethernet type field
>> >'dl_type' is
>> >+     * used to validate the destination addresses. 'dl_type' is set to
>> >zero
>> >+     * for a invalid flow_tnl entry.
>> >+     */
>> >+    ovs_be16 dl_type;
>> >     ovs_be32 ip_dst;
>> >     struct in6_addr ipv6_dst;
>> >     ovs_be32 ip_src;
>> >@@ -49,7 +67,7 @@ struct flow_tnl {
>> >     ovs_be16 tp_dst;
>> >     ovs_be16 gbp_id;
>> >     uint8_t  gbp_flags;
>> >-    uint8_t  pad1[5];        /* Pad to 64 bits. */
>> >+    uint8_t  pad1[1];        /* Pad to 64 bits. */
>> >     struct tun_metadata metadata;
>> > };
>> >
>> >@@ -76,10 +94,36 @@ struct flow_tnl {
>> >
>> > static inline bool ipv6_addr_is_set(const struct in6_addr *addr);
>> >
>> >+static inline void
>> >+set_ipv4_dst_tnl(struct flow_tnl *tnl, ovs_be32 ip_dst) {
>> >+    if (tnl) {
>> >+        tnl->ip_dst = ip_dst;
>> >+        if (tnl->ip_dst) {
>> >+            tnl->dl_type = htons(ETH_TYPE_IP);
>> >+        } else {
>> >+            tnl->dl_type = 0;
>> >+        }
>> >+    }
>> >+}
>> >+
>> >+static inline void
>> >+set_ipv6_dst_tnl(struct flow_tnl *tnl, struct in6_addr ipv6_dst) {
>> >+    if (tnl) {
>> >+        tnl->ipv6_dst = ipv6_dst;
>> >+        if (ipv6_addr_is_set(&tnl->ipv6_dst)) {
>> >+            tnl->dl_type = htons(ETH_TYPE_IPV6);
>> >+        } else {
>> >+            tnl->dl_type = 0;
>> >+        }
>> >+    }
>> >+}
>> >+
>> > static inline bool
>> > flow_tnl_dst_is_set(const struct flow_tnl *tnl)  {
>> >-    return tnl->ip_dst || ipv6_addr_is_set(&tnl->ipv6_dst);
>> >+    return (tnl->dl_type != 0);
>> > }
>> >
>> > struct in6_addr flow_tnl_dst(const struct flow_tnl *tnl); @@ -90,8
>> >+134,8 @@ static inline size_t  flow_tnl_size(const struct flow_tnl
>> >*src)  {
>> >     if (!flow_tnl_dst_is_set(src)) {
>> >-        /* Covers ip_dst and ipv6_dst only. */
>> >-        return offsetof(struct flow_tnl, ip_src);
>> >+        /* Covers dl_type field only. */
>> >+        return offsetof(struct flow_tnl, ip_dst);
>> >     }
>> >     if (src->flags & FLOW_TNL_F_UDPIF) {
>> >         /* Datapath format, cover all options we have. */ @@ -154,11
>> >+198,10 @@ static inline void  pkt_metadata_init(struct pkt_metadata
>> >*md, odp_port_t port)  {
>> >     /* It can be expensive to zero out all of the tunnel metadata.
>> >However,
>> >-     * we can just zero out ip_dst and the rest of the data will
>>never be
>> >+     * we can just zero out dl_type and the rest of the data will
>> >+ never
>> >be
>> >      * looked at. */
>> >     memset(md, 0, offsetof(struct pkt_metadata, in_port));
>> >-    md->tunnel.ip_dst = 0;
>> >-    md->tunnel.ipv6_dst = in6addr_any;
>> >+    md->tunnel.dl_type = 0;
>> >
>> >     md->in_port.odp_port = port;
>> > }
>> >@@ -347,18 +390,6 @@ ovs_be32 set_mpls_lse_values(uint8_t ttl, uint8_t
>> >tc, uint8_t bos,  #define ETH_ADDR_SCAN_ARGS(EA) \
>> >     &(EA).ea[0], &(EA).ea[1], &(EA).ea[2], &(EA).ea[3], &(EA).ea[4],
>> >&(EA).ea[5]
>> >
>> >-#define ETH_TYPE_IP            0x0800
>> >-#define ETH_TYPE_ARP           0x0806
>> >-#define ETH_TYPE_TEB           0x6558
>> >-#define ETH_TYPE_VLAN_8021Q    0x8100
>> >-#define ETH_TYPE_VLAN          ETH_TYPE_VLAN_8021Q
>> >-#define ETH_TYPE_VLAN_8021AD   0x88a8
>> >-#define ETH_TYPE_IPV6          0x86dd
>> >-#define ETH_TYPE_LACP          0x8809
>> >-#define ETH_TYPE_RARP          0x8035
>> >-#define ETH_TYPE_MPLS          0x8847
>> >-#define ETH_TYPE_MPLS_MCAST    0x8848
>> >-
>> > static inline bool eth_type_mpls(ovs_be16 eth_type)  {
>> >     return eth_type == htons(ETH_TYPE_MPLS) || diff --git
>> >a/ofproto/ofproto-dpif-ipfix.c b/ofproto/ofproto-dpif-ipfix.c index
>> >a610c53..ca06583 100644
>> >--- a/ofproto/ofproto-dpif-ipfix.c
>> >+++ b/ofproto/ofproto-dpif-ipfix.c
>> >@@ -1721,7 +1721,8 @@ dpif_ipfix_bridge_sample(struct dpif_ipfix *di,
>> >const struct dp_packet *packet,
>> >      * of matched packets. */
>> >     packet_delta_count = UINT32_MAX / di->bridge_exporter.probability;
>> >     if (di->bridge_exporter.options->enable_tunnel_sampling) {
>> >-        if (output_odp_port == ODPP_NONE && flow->tunnel.ip_dst) {
>> >+        if (output_odp_port == ODPP_NONE &&
>> >+                flow->tunnel.dl_type == htons(ETH_TYPE_IP)) {
>> >             /* Input tunnel. */
>> >             tunnel_key = &flow->tunnel;
>> >             tunnel_port = dpif_ipfix_find_port(di, input_odp_port);
>> >diff --git a/ofproto/ofproto-dpif-rid.c b/ofproto/ofproto-dpif-rid.c
>> >index d142933..735b5f3 100644
>> >--- a/ofproto/ofproto-dpif-rid.c
>> >+++ b/ofproto/ofproto-dpif-rid.c
>> >@@ -297,8 +297,7 @@ uint32_t
>> > recirc_alloc_id(struct ofproto_dpif *ofproto)  {
>> >     struct flow_tnl tunnel;
>> >-    tunnel.ip_dst = htonl(0);
>> >-    tunnel.ipv6_dst = in6addr_any;
>> >+    tunnel.dl_type = 0;
>> >     struct recirc_state state = {
>> >         .table_id = TBL_INTERNAL,
>> >         .ofproto = ofproto,
>> >diff --git a/ofproto/ofproto-dpif-sflow.c
>> >b/ofproto/ofproto-dpif-sflow.c index f11699c..ea21a1a 100644
>> >--- a/ofproto/ofproto-dpif-sflow.c
>> >+++ b/ofproto/ofproto-dpif-sflow.c
>> >@@ -899,7 +899,7 @@ sflow_read_tnl_push_action(const struct nlattr
>> *attr,
>> >     /* IPv4 */
>> >     /* Cannot assume alignment so just use memcpy. */
>> >     sflow_actions->tunnel.ip_src = get_16aligned_be32(&ip->ip_src);
>> >-    sflow_actions->tunnel.ip_dst = get_16aligned_be32(&ip->ip_dst);
>> >+    set_ipv4_dst_tnl(&sflow_actions->tunnel,
>> >get_16aligned_be32(&ip->ip_dst));
>> >     sflow_actions->tunnel.ip_tos = ip->ip_tos;
>> >     sflow_actions->tunnel.ip_ttl = ip->ip_ttl;
>> >     /* The tnl_push action can supply the ip_protocol too. */ @@
>> >-991,7 +991,7 @@ sflow_read_set_action(const struct nlattr *attr,
>> >                 sflow_actions->tunnel.ip_src = key->ipv4_src;
>> >             }
>> >             if (key->ipv4_dst) {
>> >-                sflow_actions->tunnel.ip_dst = key->ipv4_dst;
>> >+                set_ipv4_dst_tnl(&sflow_actions->tunnel,
>> >+ key->ipv4_dst);
>> >             }
>> >             if (key->ipv4_proto) {
>> >                 sflow_actions->tunnel_ipproto = key->ipv4_proto; @@
>> >-1287,7 +1287,7 @@ dpif_sflow_received(struct dpif_sflow *ds, const
>> >struct dp_packet *packet,
>> >     fs.output = cookie->sflow.output;
>> >
>> >     /* Input tunnel. */
>> >-    if (flow->tunnel.ip_dst) {
>> >+    if (flow->tunnel.dl_type == htons(ETH_TYPE_IP)) {
>> >    memset(&tnlInElem, 0, sizeof(tnlInElem));
>> >    tnlInElem.tag = SFLFLOW_EX_IPV4_TUNNEL_INGRESS;
>> >    tnlInProto = dpif_sflow_tunnel_proto(in_dsp->tunnel_type);
>> >diff --git a/ofproto/tunnel.c b/ofproto/tunnel.c index 5cf6c75..b2bd254
>> >100644
>> >--- a/ofproto/tunnel.c
>> >+++ b/ofproto/tunnel.c
>> >@@ -362,12 +362,12 @@ tnl_wc_init(struct flow *flow, struct
>> >flow_wildcards *wc)  {
>> >     if (tnl_port_should_receive(flow)) {
>> >         wc->masks.tunnel.tun_id = OVS_BE64_MAX;
>> >-        if (flow->tunnel.ip_dst) {
>> >+        if (flow->tunnel.dl_type == htons(ETH_TYPE_IP)) {
>> >             wc->masks.tunnel.ip_src = OVS_BE32_MAX;
>> >-            wc->masks.tunnel.ip_dst = OVS_BE32_MAX;
>> >-        } else {
>> >+            set_ipv4_dst_tnl(&wc->masks.tunnel, OVS_BE32_MAX);
>> >+        } else if (flow->tunnel.dl_type == htons(ETH_TYPE_IPV6)) {
>> >             wc->masks.tunnel.ipv6_src = in6addr_exact;
>> >-            wc->masks.tunnel.ipv6_dst = in6addr_exact;
>> >+            set_ipv6_dst_tnl(&wc->masks.tunnel, in6addr_exact);
>> >         }
>> >         wc->masks.tunnel.flags = (FLOW_TNL_F_DONT_FRAGMENT |
>> >                                   FLOW_TNL_F_CSUM | @@ -424,7 +424,9
>> >@@ tnl_port_send(const struct ofport_dpif *ofport, struct flow *flow,
>> >     if (!cfg->ip_dst_flow) {
>> >         flow->tunnel.ip_dst =
>> >in6_addr_get_mapped_ipv4(&tnl_port->match.ipv6_dst);
>> >         if (!flow->tunnel.ip_dst) {
>> >-            flow->tunnel.ipv6_dst = tnl_port->match.ipv6_dst;
>> >+            set_ipv6_dst_tnl(&flow->tunnel, tnl_port->match.ipv6_dst);
>> >+        } else {
>> >+            set_ipv4_dst_tnl(&flow->tunnel, flow->tunnel.ip_dst);
>> >         }
>> >     }
>> >     flow->pkt_mark = tnl_port->match.pkt_mark;
>> >--
>> >1.9.1
>> >
>> >_______________________________________________
>> >dev mailing list
>> >dev@openvswitch.org
>> >http://openvswitch.org/mailman/listinfo/dev
>

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to