Also add a new 'protocol' field that holds the outer protocol.

Signed-off-by: Jiri Benc <jb...@redhat.com>
---
 ofproto/tunnel.c | 66 +++++++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 53 insertions(+), 13 deletions(-)

diff --git a/ofproto/tunnel.c b/ofproto/tunnel.c
index ccef40a59668..116ba061bb6c 100644
--- a/ofproto/tunnel.c
+++ b/ofproto/tunnel.c
@@ -49,8 +49,11 @@ struct tnl_match {
     ovs_be64 in_key;
     ovs_be32 ip_src;
     ovs_be32 ip_dst;
+    struct in6_addr ipv6_src;
+    struct in6_addr ipv6_dst;
     odp_port_t odp_port;
     uint32_t pkt_mark;
+    uint16_t protocol;
     bool in_key_flow;
     bool ip_src_flow;
     bool ip_dst_flow;
@@ -163,6 +166,9 @@ tnl_port_add__(const struct ofport_dpif *ofport, const 
struct netdev *netdev,
     tnl_port->match.in_key = cfg->in_key;
     tnl_port->match.ip_src = cfg->ip_src;
     tnl_port->match.ip_dst = cfg->ip_dst;
+    tnl_port->match.ipv6_src = cfg->ipv6_src;
+    tnl_port->match.ipv6_dst = cfg->ipv6_dst;
+    tnl_port->match.protocol = cfg->protocol;
     tnl_port->match.ip_src_flow = cfg->ip_src_flow;
     tnl_port->match.ip_dst_flow = cfg->ip_dst_flow;
     tnl_port->match.pkt_mark = cfg->ipsec ? IPSEC_MARK : 0;
@@ -423,10 +429,18 @@ tnl_port_send(const struct ofport_dpif *ofport, struct 
flow *flow,
     }
 
     if (!cfg->ip_src_flow) {
-        flow->tunnel.ip_src = tnl_port->match.ip_src;
+        if (cfg->protocol == ETH_TYPE_IPV6) {
+            flow->tunnel.ipv6_src = tnl_port->match.ipv6_src;
+        } else {
+            flow->tunnel.ip_src = tnl_port->match.ip_src;
+        }
     }
     if (!cfg->ip_dst_flow) {
-        flow->tunnel.ip_dst = tnl_port->match.ip_dst;
+        if (cfg->protocol == ETH_TYPE_IPV6) {
+            flow->tunnel.ipv6_dst = tnl_port->match.ipv6_dst;
+        } else {
+            flow->tunnel.ip_dst = tnl_port->match.ip_dst;
+        }
     }
     flow->pkt_mark = tnl_port->match.pkt_mark;
 
@@ -526,8 +540,10 @@ tnl_find(const struct flow *flow) OVS_REQ_RDLOCK(rwlock)
     enum ip_src_type ip_src;
     int in_key_flow;
     int ip_dst_flow;
+    bool ipv6;
     int i;
 
+    ipv6 = ipv6_addr_is_set(&flow->tunnel.ipv6_dst);
     i = 0;
     for (in_key_flow = 0; in_key_flow < 2; in_key_flow++) {
         for (ip_dst_flow = 0; ip_dst_flow < 2; ip_dst_flow++) {
@@ -546,12 +562,23 @@ tnl_find(const struct flow *flow) OVS_REQ_RDLOCK(rwlock)
                      * here as a description of how to treat received
                      * packets. */
                     match.in_key = in_key_flow ? 0 : flow->tunnel.tun_id;
-                    match.ip_src = (ip_src == IP_SRC_CFG
-                                    ? flow->tunnel.ip_dst
-                                    : 0);
-                    match.ip_dst = ip_dst_flow ? 0 : flow->tunnel.ip_src;
+                    if (ip_src == IP_SRC_CFG) {
+                        if (!ipv6) {
+                            match.ip_src = flow->tunnel.ip_dst;
+                        } else {
+                            match.ipv6_src = flow->tunnel.ipv6_dst;
+                        }
+                    }
+                    if (!ip_dst_flow) {
+                        if (!ipv6) {
+                            match.ip_dst = flow->tunnel.ip_src;
+                        } else {
+                            match.ipv6_dst = flow->tunnel.ipv6_src;
+                        }
+                    }
                     match.odp_port = flow->in_port.odp_port;
                     match.pkt_mark = flow->pkt_mark;
+                    match.protocol = ipv6 ? ETH_TYPE_IPV6 : ETH_TYPE_IP;
                     match.in_key_flow = in_key_flow;
                     match.ip_dst_flow = ip_dst_flow;
                     match.ip_src_flow = ip_src == IP_SRC_FLOW;
@@ -578,7 +605,7 @@ tnl_match_map(const struct tnl_match *m)
     enum ip_src_type ip_src;
 
     ip_src = (m->ip_src_flow ? IP_SRC_FLOW
-              : m->ip_src ? IP_SRC_CFG
+              : (m->ip_src || ipv6_addr_is_set(&m->ipv6_src)) ? IP_SRC_CFG
               : IP_SRC_ANY);
 
     return &tnl_match_maps[6 * m->in_key_flow + 3 * m->ip_dst_flow + ip_src];
@@ -588,13 +615,26 @@ static void
 tnl_match_fmt(const struct tnl_match *match, struct ds *ds)
     OVS_REQ_RDLOCK(rwlock)
 {
-    if (!match->ip_dst_flow) {
-        ds_put_format(ds, IP_FMT"->"IP_FMT, IP_ARGS(match->ip_src),
-                      IP_ARGS(match->ip_dst));
-    } else if (!match->ip_src_flow) {
-        ds_put_format(ds, IP_FMT"->flow", IP_ARGS(match->ip_src));
+    if (match->protocol == ETH_TYPE_IP) {
+        if (!match->ip_dst_flow) {
+            ds_put_format(ds, IP_FMT"->"IP_FMT, IP_ARGS(match->ip_src),
+                          IP_ARGS(match->ip_dst));
+        } else if (!match->ip_src_flow) {
+            ds_put_format(ds, IP_FMT"->flow", IP_ARGS(match->ip_src));
+        } else {
+            ds_put_cstr(ds, "flow->flow");
+        }
     } else {
-        ds_put_cstr(ds, "flow->flow");
+        if (!match->ip_dst_flow) {
+            ds_put_in6_addr(ds, &match->ipv6_src);
+            ds_put_cstr(ds, "->");
+            ds_put_in6_addr(ds, &match->ipv6_dst);
+        } else if (!match->ip_src_flow) {
+            ds_put_in6_addr(ds, &match->ipv6_src);
+            ds_put_cstr(ds, "->flow6");
+        } else {
+            ds_put_cstr(ds, "flow6->flow6");
+        }
     }
 
     if (match->in_key_flow) {
-- 
1.8.3.1

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

Reply via email to