[ovs-dev] [RFC PATCH 2/5] odp-util: Enable communicating outer tunnel to/from the kernel.

Jesse Gross jesse at nicira.com
Fri Sep 28 18:12:22 UTC 2012


Now that both the kernel and userspace can handle information about
the tunnel outer headers this adds userspace support for communicating
between the two.  At the moment userspace doesn't know how to do
anything with the extra information on receive and will only generate
actions containing tun_id.  However, both sides know how to ignore the
extra information.

Signed-off-by: Jesse Gross <jesse at nicira.com>
---
 NEWS                  |    2 ++
 lib/odp-util.c        |   75 +++++++++++++++++++++++++++++++++++++++++--------
 tests/odp.at          |   12 ++++----
 tests/ofproto-dpif.at |    2 +-
 4 files changed, 73 insertions(+), 18 deletions(-)

diff --git a/NEWS b/NEWS
index 71b2e29..6cd2947 100644
--- a/NEWS
+++ b/NEWS
@@ -37,6 +37,8 @@ post-v1.8.0
         - The autopath action.
         - Interface type "null".
         - Numeric values for reserved ports (see "ovs-ofctl" note above).
+    - Tunneling requires the version of the kernel module paired with this
+      release (or a newer release).
 
 
 v1.8.0 - xx xxx xxxx
diff --git a/lib/odp-util.c b/lib/odp-util.c
index f4b30e9..d46189f 100644
--- a/lib/odp-util.c
+++ b/lib/odp-util.c
@@ -925,6 +925,30 @@ parse_odp_key_attr(const char *s, const struct simap *port_names,
     }
 
     {
+        char tun_id_s[32];
+        unsigned long long int flags;
+        int tos, ttl;
+        struct ovs_key_ipv4_tunnel tun_key;
+        int n = -1;
+
+        if (sscanf(s, "ipv4_tunnel(tun_id=%31[x0123456789abcdefABCDEF],"
+                   "flags=%lli,src="IP_SCAN_FMT",dst="IP_SCAN_FMT
+                   ",tos=%i,ttl=%i)%n", tun_id_s, &flags,
+                    IP_SCAN_ARGS(&tun_key.ipv4_src),
+                    IP_SCAN_ARGS(&tun_key.ipv4_dst), &tos, &ttl,
+                    &n) > 0 && n > 0) {
+            tun_key.tun_id = htonll(strtoull(tun_id_s, NULL, 0));
+            tun_key.tun_flags = flags;
+            tun_key.ipv4_tos = tos;
+            tun_key.ipv4_ttl = ttl;
+            memset(&tun_key.pad, 0, sizeof tun_key.pad);
+            nl_msg_put_unspec(key, OVS_KEY_ATTR_IPV4_TUNNEL, &tun_key,
+                              sizeof tun_key);
+            return n;
+        }
+    }
+
+    {
         unsigned long long int in_port;
         int n = -1;
 
@@ -1273,8 +1297,18 @@ odp_flow_key_from_flow(struct ofpbuf *buf, const struct flow *flow)
         nl_msg_put_u32(buf, OVS_KEY_ATTR_PRIORITY, flow->skb_priority);
     }
 
-    if (flow->tunnel.tun_id != htonll(0)) {
-        nl_msg_put_be64(buf, OVS_KEY_ATTR_TUN_ID, flow->tunnel.tun_id);
+    if (flow->tunnel.ip_dst != 0) {
+        struct ovs_key_ipv4_tunnel *tun_key;
+
+        tun_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_IPV4_TUNNEL,
+                                           sizeof *tun_key);
+        tun_key->tun_id = flow->tunnel.tun_id;
+        tun_key->ipv4_src = flow->tunnel.ip_src;
+        tun_key->ipv4_dst = flow->tunnel.ip_dst;
+        tun_key->tun_flags = 0; // XXX: Need flags
+        tun_key->ipv4_tos = flow->tunnel.ip_tos;
+        tun_key->ipv4_ttl = flow->tunnel.ip_ttl;
+        memset(&tun_key->pad, 0, sizeof tun_key->pad);
     }
 
     if (flow->in_port != OFPP_NONE && flow->in_port != OFPP_CONTROLLER) {
@@ -1765,9 +1799,17 @@ odp_flow_key_to_flow(const struct nlattr *key, size_t key_len,
         expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_PRIORITY;
     }
 
-    if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_TUN_ID)) {
-        flow->tunnel.tun_id = nl_attr_get_be64(attrs[OVS_KEY_ATTR_TUN_ID]);
-        expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_TUN_ID;
+    if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_IPV4_TUNNEL)) {
+        const struct ovs_key_ipv4_tunnel *tun_key;
+
+        tun_key = nl_attr_get(attrs[OVS_KEY_ATTR_IPV4_TUNNEL]);
+        flow->tunnel.tun_id = tun_key->tun_id;
+        flow->tunnel.ip_src = tun_key->ipv4_src;
+        flow->tunnel.ip_dst = tun_key->ipv4_dst;
+        flow->tunnel.flags = 0; // XXX need flags
+        flow->tunnel.ip_tos = tun_key->ipv4_tos;
+        flow->tunnel.ip_ttl = tun_key->ipv4_ttl;
+        expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_IPV4_TUNNEL;
     }
 
     if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_IN_PORT)) {
@@ -1858,16 +1900,27 @@ commit_set_action(struct ofpbuf *odp_actions, enum ovs_key_attr key_type,
 }
 
 static void
-commit_set_tun_id_action(const struct flow *flow, struct flow *base,
+commit_set_tunnel_action(const struct flow *flow, struct flow *base,
                          struct ofpbuf *odp_actions)
 {
-    if (base->tunnel.tun_id == flow->tunnel.tun_id) {
+    struct ovs_key_ipv4_tunnel tun_key;
+
+    if (!memcmp(&base->tunnel, &flow->tunnel, sizeof base->tunnel)) {
         return;
     }
-    base->tunnel.tun_id = flow->tunnel.tun_id;
 
-    commit_set_action(odp_actions, OVS_KEY_ATTR_TUN_ID,
-                      &base->tunnel.tun_id, sizeof(base->tunnel.tun_id));
+    memcpy(&base->tunnel, &flow->tunnel, sizeof base->tunnel);
+
+    tun_key.tun_id = base->tunnel.tun_id;
+    tun_key.ipv4_src = base->tunnel.ip_src;
+    tun_key.ipv4_dst = base->tunnel.ip_dst;
+    tun_key.tun_flags = 0; // XXX: Need flags
+    tun_key.ipv4_tos = base->tunnel.ip_tos;
+    tun_key.ipv4_ttl = base->tunnel.ip_ttl;
+    memset(&tun_key.pad, 0, sizeof tun_key.pad);
+
+    commit_set_action(odp_actions, OVS_KEY_ATTR_IPV4_TUNNEL,
+                      &tun_key, sizeof tun_key);
 }
 
 static void
@@ -2038,7 +2091,7 @@ void
 commit_odp_actions(const struct flow *flow, struct flow *base,
                    struct ofpbuf *odp_actions)
 {
-    commit_set_tun_id_action(flow, base, odp_actions);
+    commit_set_tunnel_action(flow, base, odp_actions);
     commit_set_ether_addr_action(flow, base, odp_actions);
     commit_vlan_action(flow, base, odp_actions);
     commit_set_nw_action(flow, base, odp_actions);
diff --git a/tests/odp.at b/tests/odp.at
index 9617af2..3eb163e 100644
--- a/tests/odp.at
+++ b/tests/odp.at
@@ -30,8 +30,8 @@ in_port(1),eth(src=00:01:02:03:04:05,dst=10:11:12:13:14:15),eth_type(0x0806),arp
  cat odp-base.txt
 
  echo
- echo '# Valid forms with tun_id header.'
- sed 's/^/tun_id(0x7f10354),/' odp-base.txt
+ echo '# Valid forms with tunnel header.'
+ sed 's/^/ipv4_tunnel(tun_id=0x7f10354,flags=0x0,src=10.10.10.10,dst=20.20.20.20,tos=0x0,ttl=64),/' odp-base.txt
 
  echo
  echo '# Valid forms with VLAN header.'
@@ -43,14 +43,14 @@ s/$/)/' odp-base.txt
  sed 's/^/priority(1234),/' odp-base.txt
 
  echo
- echo '# Valid forms with tun_id and VLAN headers.'
- sed 's/^/tun_id(0xfedcba9876543210),/
+ echo '# Valid forms with tunnel and VLAN headers.'
+ sed 's/^/ipv4_tunnel(tun_id=0xfedcba9876543210,flags=0x0,src=10.0.0.1,dst=10.0.0.2,tos=0x8,ttl=128),/
 s/\(eth([[^)]]*)\),*/\1,eth_type(0x8100),vlan(vid=99,pcp=7),encap(/
 s/$/)/' odp-base.txt
 
  echo
- echo '# Valid forms with QOS priority, tun_id, and VLAN headers.'
- sed 's/^/priority(1234),tun_id(0xfedcba9876543210),/
+ echo '# Valid forms with QOS priority, tunnel, and VLAN headers.'
+ sed 's/^/priority(1234),ipv4_tunnel(tun_id=0xfedcba9876543210,flags=0x0,src=10.0.0.1,dst=10.0.0.2,tos=0x8,ttl=128),/
 s/\(eth([[^)]]*)\),*/\1,eth_type(0x8100),vlan(vid=99,pcp=7),encap(/
 s/$/)/' odp-base.txt
 
diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at
index 7a31216..5a2e2a1 100644
--- a/tests/ofproto-dpif.at
+++ b/tests/ofproto-dpif.at
@@ -227,7 +227,7 @@ in_port=5 actions=set_tunnel:5
 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
 AT_CHECK([ovs-appctl ofproto/trace br0 'tun_id(0x1),in_port(90),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)'], [0], [stdout])
 AT_CHECK([tail -1 stdout], [0],
-  [Datapath actions: set(tun_id(0x1)),1,2,set(tun_id(0x3)),3,4
+  [Datapath actions: set(ipv4_tunnel(tun_id=0x1,flags=0x0,src=0.0.0.0,dst=0.0.0.0,tos=0x0,ttl=0)),1,2,set(ipv4_tunnel(tun_id=0x3,flags=0x0,src=0.0.0.0,dst=0.0.0.0,tos=0x0,ttl=0)),3,4
 ])
 OVS_VSWITCHD_STOP
 AT_CLEANUP
-- 
1.7.9.5




More information about the dev mailing list