[ovs-dev] [IPv6 IV: A New Hope 5/6] nicira-ext: Support matching IPv6 traffic.

Justin Pettit jpettit at nicira.com
Tue Feb 1 22:25:24 UTC 2011


On Feb 1, 2011, at 1:23 PM, Ben Pfaff wrote:

> On Tue, Feb 01, 2011 at 12:53:52AM -0800, Justin Pettit wrote:
>> Provides ability to match over IPv6 traffic in the same manner as IPv4.
>> Currently, the matching fields include:
>> 
>>    - IPv6 source and destination addresses (ipv6_src and ipv6_dst)
>>    - Traffic Class (nw_tos)
>>    - Next Header (nw_proto)
>>    - ICMPv6 Type and Code (icmp_type and icmp_code)
>>    - TCP and UDP Ports over IPv6 (tp_src and tp_dst)
>> 
>> When defining IPv6 rules, the Nicira Extensible Match (NXM) extension to
>> OVS must be used.
>> 
>> Signed-off-by: Justin Pettit <jpettit at nicira.com>
> 
> One omission I just noticed is that this does not update
> hash_symmetric_l4() in multipath.c to spread IPv6 flows across the
> links.

Isn't that single IPv6 flow on the Internet already self-balancing?  I kid, I kid.

I totally missed that, so thanks for pointing that out.  Below is a diff that I plan to fold into this patch, if it looks reasonable.  I took out the code that sets unused values to zero, since the entire field is now being memset to zero.

--Justin


-=-=-=-=-=-=-=-=-=-=-=-


diff --git a/lib/multipath.c b/lib/multipath.c
index 83df680..5dd4b5d 100644
--- a/lib/multipath.c
+++ b/lib/multipath.c
@@ -90,7 +90,10 @@ static uint32_t
 hash_symmetric_l4(const struct flow *flow, uint16_t basis)
 {
     struct {
-        ovs_be32 ip_addr;
+        union {
+            ovs_be32 ipv4_addr;
+            struct in6_addr ipv6_addr;
+        };
         ovs_be16 eth_type;
         ovs_be16 vlan_tci;
         ovs_be16 tp_addr;
@@ -107,17 +110,23 @@ hash_symmetric_l4(const struct flow *flow, uint16_t basis)
     fields.vlan_tci = flow->vlan_tci & htons(VLAN_VID_MASK);
     fields.eth_type = flow->dl_type;
     if (fields.eth_type == htons(ETH_TYPE_IP)) {
-        fields.ip_addr = flow->nw_src ^ flow->nw_dst;
+        fields.ipv4_addr = flow->nw_src ^ flow->nw_dst;
+        fields.ip_proto = flow->nw_proto;
+        if (fields.ip_proto == IP_TYPE_TCP || fields.ip_proto == IP_TYPE_UDP) {
+            fields.tp_addr = flow->tp_src ^ flow->tp_dst;
+        }
+    } else if (fields.eth_type == htons(ETH_TYPE_IPV6)) {
+        const uint8_t *a = &flow->ipv6_src.s6_addr[0];
+        const uint8_t *b = &flow->ipv6_dst.s6_addr[0];
+        uint8_t *ipv6_addr = &fields.ipv6_addr.s6_addr[0];
+
+        for (i=0; i<16; i++) {
+            ipv6_addr[i] = a[i] ^ b[i];
+        }
         fields.ip_proto = flow->nw_proto;
         if (fields.ip_proto == IP_TYPE_TCP || fields.ip_proto == IP_TYPE_UDP) {
             fields.tp_addr = flow->tp_src ^ flow->tp_dst;
-        } else {
-            fields.tp_addr = htons(0);
         }
-    } else {
-        fields.ip_addr = htonl(0);
-        fields.ip_proto = 0;
-        fields.tp_addr = htons(0);
     }
     return hash_bytes(&fields, sizeof fields, basis);
 }






More information about the dev mailing list