Allow ovs_tunnel_info to be initialized also from an IPv6 header.

Signed-off-by: Jiri Benc <[email protected]>
---
 net/openvswitch/flow.h         | 50 ++++++++++++++++++++++++++++++++++--------
 net/openvswitch/vport-geneve.c |  2 +-
 net/openvswitch/vport-gre.c    |  2 +-
 net/openvswitch/vport-vxlan.c  |  2 +-
 net/openvswitch/vport.c        |  3 ++-
 5 files changed, 46 insertions(+), 13 deletions(-)

diff --git a/net/openvswitch/flow.h b/net/openvswitch/flow.h
index d36cc6ce5332..767bfe4d1db9 100644
--- a/net/openvswitch/flow.h
+++ b/net/openvswitch/flow.h
@@ -69,7 +69,6 @@ struct ovs_tunnel_info {
        ((void *)((flow_key)->tun_opts + TUN_METADATA_OFFSET(opt_len)))
 
 static inline void __ovs_flow_tun_info_init(struct ovs_tunnel_info *tun_info,
-                                           __be32 saddr, __be32 daddr,
                                            u8 tos, u8 ttl,
                                            __be16 tp_src,
                                            __be16 tp_dst,
@@ -79,11 +78,6 @@ static inline void __ovs_flow_tun_info_init(struct 
ovs_tunnel_info *tun_info,
                                            u8 opts_len)
 {
        tun_info->tunnel.tun_id = tun_id;
-       tun_info->tunnel.ipv4_src = saddr;
-       tun_info->tunnel.ipv4_dst = daddr;
-       memset(&tun_info->tunnel.ipv6_src, 0,
-              offsetof(struct ovs_key_ip_tunnel, tun_flags) -
-              offsetof(struct ovs_key_ip_tunnel, ipv6_src));
        tun_info->tunnel.tos = tos;
        tun_info->tunnel.ttl = ttl;
        tun_info->tunnel.tun_flags = tun_flags;
@@ -104,8 +98,30 @@ static inline void __ovs_flow_tun_info_init(struct 
ovs_tunnel_info *tun_info,
        tun_info->options_len = opts_len;
 }
 
+static inline void __ovs_flow_tun_info_set_ipv4(struct ovs_tunnel_info 
*tun_info,
+                                               __be32 saddr, __be32 daddr)
+{
+       tun_info->tunnel.ipv4_src = saddr;
+       tun_info->tunnel.ipv4_dst = daddr;
+       memset(&tun_info->tunnel.ipv6_src, 0,
+              offsetof(struct ovs_key_ip_tunnel, tun_flags) -
+              offsetof(struct ovs_key_ip_tunnel, ipv6_src));
+}
+
+static inline void __ovs_flow_tun_info_set_ipv6(struct ovs_tunnel_info 
*tun_info,
+                                               const struct in6_addr *saddr,
+                                               const struct in6_addr *daddr)
+{
+       tun_info->tunnel.ipv6_src = *saddr;
+       tun_info->tunnel.ipv6_dst = *daddr;
+       memset(&tun_info->tunnel.ipv4_src, 0,
+              offsetof(struct ovs_key_ip_tunnel, ipv6_src) -
+              offsetof(struct ovs_key_ip_tunnel, ipv4_src));
+}
+
 static inline void ovs_flow_tun_info_init(struct ovs_tunnel_info *tun_info,
-                                         const struct iphdr *iph,
+                                         const void *iph,
+                                         bool ipv6,
                                          __be16 tp_src,
                                          __be16 tp_dst,
                                          __be64 tun_id,
@@ -113,11 +129,27 @@ static inline void ovs_flow_tun_info_init(struct 
ovs_tunnel_info *tun_info,
                                          const void *opts,
                                          u8 opts_len)
 {
-       __ovs_flow_tun_info_init(tun_info, iph->saddr, iph->daddr,
-                                iph->tos, iph->ttl,
+       const struct iphdr *ip4h = iph;
+       const struct ipv6hdr *ip6h = iph;
+       u8 tos, ttl;
+
+       if (!ipv6) {
+               tos = ip4h->tos;
+               ttl = ip4h->ttl;
+       } else {
+               tos = ipv6_get_dsfield(ip6h);
+               ttl = ip6h->hop_limit;
+       }
+       __ovs_flow_tun_info_init(tun_info, tos, ttl,
                                 tp_src, tp_dst,
                                 tun_id, tun_flags,
                                 opts, opts_len);
+       if (!ipv6)
+               __ovs_flow_tun_info_set_ipv4(tun_info,
+                                            ip4h->saddr, ip4h->daddr);
+       else
+               __ovs_flow_tun_info_set_ipv6(tun_info,
+                                            &ip6h->saddr, &ip6h->daddr);
 }
 
 #define OVS_SW_FLOW_KEY_METADATA_SIZE                  \
diff --git a/net/openvswitch/vport-geneve.c b/net/openvswitch/vport-geneve.c
index d22078012aca..78c9e1f89d66 100644
--- a/net/openvswitch/vport-geneve.c
+++ b/net/openvswitch/vport-geneve.c
@@ -90,7 +90,7 @@ static void geneve_rcv(struct geneve_sock *gs, struct sk_buff 
*skb)
 
        key = vni_to_tunnel_id(geneveh->vni);
 
-       ovs_flow_tun_info_init(&tun_info, ip_hdr(skb),
+       ovs_flow_tun_info_init(&tun_info, ip_hdr(skb), false,
                               udp_hdr(skb)->source, udp_hdr(skb)->dest,
                               key, flags,
                               geneveh->options, opts_len);
diff --git a/net/openvswitch/vport-gre.c b/net/openvswitch/vport-gre.c
index 45c7cde96867..38f54797b45c 100644
--- a/net/openvswitch/vport-gre.c
+++ b/net/openvswitch/vport-gre.c
@@ -108,7 +108,7 @@ static int gre_rcv(struct sk_buff *skb,
                return PACKET_REJECT;
 
        key = key_to_tunnel_id(tpi->key, tpi->seq);
-       ovs_flow_tun_info_init(&tun_info, ip_hdr(skb), 0, 0, key,
+       ovs_flow_tun_info_init(&tun_info, ip_hdr(skb), false, 0, 0, key,
                               filter_tnl_flags(tpi->flags), NULL, 0);
 
        ovs_vport_receive(vport, skb, &tun_info);
diff --git a/net/openvswitch/vport-vxlan.c b/net/openvswitch/vport-vxlan.c
index a01bc2343d35..6ff9f2befbac 100644
--- a/net/openvswitch/vport-vxlan.c
+++ b/net/openvswitch/vport-vxlan.c
@@ -82,7 +82,7 @@ static void vxlan_rcv(struct vxlan_sock *vs, struct sk_buff 
*skb,
        /* Save outer tunnel values */
        iph = ip_hdr(skb);
        key = cpu_to_be64(ntohl(md->vni) >> 8);
-       ovs_flow_tun_info_init(&tun_info, iph,
+       ovs_flow_tun_info_init(&tun_info, iph, false,
                               udp_hdr(skb)->source, udp_hdr(skb)->dest,
                               key, flags, &opts, sizeof(opts));
 
diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c
index a1af8a9a9f5d..d21e3387916a 100644
--- a/net/openvswitch/vport.c
+++ b/net/openvswitch/vport.c
@@ -603,7 +603,6 @@ int ovs_tunnel_get_egress_info(struct ovs_tunnel_info 
*egress_tun_info,
         * saddr, tp_src and tp_dst
         */
        __ovs_flow_tun_info_init(egress_tun_info,
-                                fl.saddr, tun_key->ipv4_dst,
                                 tun_key->tos,
                                 tun_key->ttl,
                                 tp_src, tp_dst,
@@ -611,6 +610,8 @@ int ovs_tunnel_get_egress_info(struct ovs_tunnel_info 
*egress_tun_info,
                                 tun_key->tun_flags,
                                 tun_info->options,
                                 tun_info->options_len);
+       __ovs_flow_tun_info_set_ipv4(egress_tun_info,
+                                    fl.saddr, tun_key->ipv4_dst);
 
        return 0;
 }
-- 
1.8.3.1

_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev

Reply via email to