tnl-ports: Generate mask with correct prerequisites.
authorDaniele Di Proietto <diproiettod@vmware.com>
Mon, 23 Nov 2015 23:37:46 +0000 (15:37 -0800)
committerDaniele Di Proietto <diproiettod@vmware.com>
Fri, 11 Dec 2015 01:38:23 +0000 (17:38 -0800)
We should match on the transport ports only if the tunnel has a UDP
header.  It doesn't make sense to match on transport port for GRE
tunnels.

Also, to match on fragment bits we should use FLOW_NW_FRAG_MASK instead
of 0xFF.  FLOW_NW_FRAG_MASK is what we get if we convert to the ODP
netlink format and back.

Adding the correct masks in the tunnel router classifier helps in making
sure that the translation generates masks that respect prerequisites.

If the mask has some fields that do not respect prerequisites, the flow
will get deleted by revalidation, because translating to ODP format and
back will generate a more generic mask, which will be perceived as too
generic (compared with the one generated by the translation).

lib/tnl-ports.c

index 3006a8b..e7f2066 100644 (file)
@@ -126,8 +126,14 @@ map_insert(odp_port_t port, struct eth_addr mac, struct in6_addr *addr,
 
         match.wc.masks.dl_type = OVS_BE16_MAX;
         match.wc.masks.nw_proto = 0xff;
-        match.wc.masks.nw_frag = 0xff;      /* XXX: No fragments support. */
-        match.wc.masks.tp_dst = OVS_BE16_MAX;
+         /* XXX: No fragments support. */
+        match.wc.masks.nw_frag = FLOW_NW_FRAG_MASK;
+
+        /* 'udp_port' is zero for non-UDP tunnels (e.g. GRE). In this case it
+         * doesn't make sense to match on UDP port numbers. */
+        if (udp_port) {
+            match.wc.masks.tp_dst = OVS_BE16_MAX;
+        }
         if (IN6_IS_ADDR_V4MAPPED(addr)) {
             match.wc.masks.nw_dst = OVS_BE32_MAX;
         } else {