[ovs-dev] [#8024v2 4/5] Support matching and modifying IP TTL.

Justin Pettit jpettit at nicira.com
Wed Nov 9 19:21:07 UTC 2011


On Nov 8, 2011, at 10:52 PM, Jesse Gross wrote:

> I got a whitespace error:
> Applying: Support matching and modifying IP TTL.
> /home/jesse/openvswitch/.git/rebase-apply/patch:977: trailing whitespace.
> Matches IP TTL or IPv6 hop limit value \fIttl\fR, which is
> warning: 1 line adds whitespace errors.

Fixed.

>> diff --git a/include/linux/openvswitch.h b/include/linux/openvswitch.h
>> index c2b4285..7236628 100644
>> --- a/include/linux/openvswitch.h
>> +++ b/include/linux/openvswitch.h
>> @@ -316,6 +316,7 @@ struct ovs_key_ipv4 {
>>        __be32 ipv4_dst;
>>        __u8   ipv4_proto;
>>        __u8   ipv4_tos;
>> +       __u8   ipv4_ttl;
>>        __u8   ipv4_frag;       /* One of OVS_FRAG_TYPE_*. */
>>  };
> 
> Now that the IPv4 and v6 structs no longer have padding at the end, we
> can remove the memsets when both userspace and kernel serialize them
> to Netlink and when userspace generates actions.

Good point.  Updated.

>> @@ -325,6 +326,7 @@ struct ovs_key_ipv6 {
>>        __be32 ipv6_label;
>>        __u8   ipv6_proto;
>>        __u8   ipv6_tos;
>> +       __u8   ipv6_ttl;
> 
> Given that this is an IPv6 specific struct, I think it's better to
> actually call it hop limit.  I guess the same also applied to tos
> (traffic class).

Good point.  I'll send a follow-up patch for the IPv6 traffic class, since it doesn't cleanly fit into this series.

>> diff --git a/include/openflow/nicira-ext.h b/include/openflow/nicira-ext.h
>> index d0c4602..6a34268 100644
>> --- a/include/openflow/nicira-ext.h
>> +++ b/include/openflow/nicira-ext.h
>> @@ -1632,6 +1632,15 @@ OFP_ASSERT(sizeof(struct nx_action_output_reg) == 24);
>>  * Masking: Not maskable. */
>>  #define NXM_NX_IP_ECN      NXM_HEADER  (0x0001, 28, 1)
>> 
>> +/* The time-to-live/next hop of the IP header.
> 
> Was this supposes to be hop limit?

Whoops.  Thanks.

>> @@ -71,22 +71,23 @@ struct flow {
>>     uint8_t dl_dst[6];          /* Ethernet destination address. */
>>     uint8_t nw_proto;           /* IP protocol or low 8 bits of ARP opcode. */
>>     uint8_t tos;                /* IP ToS. */
>> +    uint8_t nw_ttl;             /* IP TTL/Hop Limit. */
>>     uint8_t frag;               /* FLOW_FRAG_*. */
> 
> Is there any policy on the prefixes for these fields?  Some seem to
> have nw_ but others don't.

Apparently not--I noticed the same thing.  Ben, would you be opposed to my adding a "nw_" prefix to "tos" and "frag"?

> We should implement this in the userspace datapath as well.


Thanks.  I've added support.

An incremental is at the end of this message.

--Justin


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

diff --git a/datapath/flow.c b/datapath/flow.c
index e8d887d..61e7e43 100644
--- a/datapath/flow.c
+++ b/datapath/flow.c
@@ -979,7 +979,7 @@ int flow_from_nlattrs(struct sw_flow_key *swkey, int *key_le
                        swkey->ipv6.label = ipv6_key->ipv6_label;
                        swkey->ip.proto = ipv6_key->ipv6_proto;
                        swkey->ip.tos = ipv6_key->ipv6_tos;
-                       swkey->ip.ttl = ipv6_key->ipv6_ttl;
+                       swkey->ip.ttl = ipv6_key->ipv6_hop_limit;
                        swkey->ip.frag = ipv6_key->ipv6_frag;
                        memcpy(&swkey->ipv6.addr.src, ipv6_key->ipv6_src,
                                        sizeof(swkey->ipv6.addr.src));
@@ -1244,7 +1244,6 @@ int flow_to_nlattrs(const struct sw_flow_key *swkey, struc
                if (!nla)
                        goto nla_put_failure;
                ipv4_key = nla_data(nla);
-               memset(ipv4_key, 0, sizeof(struct ovs_key_ipv4));
                ipv4_key->ipv4_src = swkey->ipv4.addr.src;
                ipv4_key->ipv4_dst = swkey->ipv4.addr.dst;
                ipv4_key->ipv4_proto = swkey->ip.proto;
@@ -1258,7 +1257,6 @@ int flow_to_nlattrs(const struct sw_flow_key *swkey, struc
                if (!nla)
                        goto nla_put_failure;
                ipv6_key = nla_data(nla);
-               memset(ipv6_key, 0, sizeof(struct ovs_key_ipv6));
                memcpy(ipv6_key->ipv6_src, &swkey->ipv6.addr.src,
                                sizeof(ipv6_key->ipv6_src));
                memcpy(ipv6_key->ipv6_dst, &swkey->ipv6.addr.dst,
@@ -1266,7 +1264,7 @@ int flow_to_nlattrs(const struct sw_flow_key *swkey, struc
                ipv6_key->ipv6_label = swkey->ipv6.label;
                ipv6_key->ipv6_proto = swkey->ip.proto;
                ipv6_key->ipv6_tos = swkey->ip.tos;
-               ipv6_key->ipv6_ttl = swkey->ip.ttl;
+               ipv6_key->ipv6_hop_limit = swkey->ip.ttl;
                ipv6_key->ipv6_frag = swkey->ip.frag;
        } else if (swkey->eth.type == htons(ETH_P_ARP)) {
                struct ovs_key_arp *arp_key;
diff --git a/include/linux/openvswitch.h b/include/linux/openvswitch.h
index 43e094d..cb6e6bb 100644
--- a/include/linux/openvswitch.h
+++ b/include/linux/openvswitch.h
@@ -326,7 +326,7 @@ struct ovs_key_ipv6 {
        __be32 ipv6_label;      /* 20-bits in least-significant bits. */
        __u8   ipv6_proto;
        __u8   ipv6_tos;
-       __u8   ipv6_ttl;
+       __u8   ipv6_hop_limit;
        __u8   ipv6_frag;       /* One of OVS_FRAG_TYPE_*. */
 };
diff --git a/include/openflow/nicira-ext.h b/include/openflow/nicira-ext.h
index 6d3c402..06b9035 100644
--- a/include/openflow/nicira-ext.h
+++ b/include/openflow/nicira-ext.h
@@ -1632,7 +1632,7 @@ OFP_ASSERT(sizeof(struct nx_action_output_reg) == 24);
  * Masking: Not maskable. */
 #define NXM_NX_IP_ECN      NXM_HEADER  (0x0001, 28, 1)
 
-/* The time-to-live/next hop of the IP header.
+/* The time-to-live/hop limit of the IP header.
  *
  * Prereqs: NXM_OF_ETH_TYPE must be either 0x0800 or 0x86dd.
  *
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index d776899..27125d3 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -1092,6 +1092,16 @@ dp_netdev_set_ip_tos(struct ip_header *nh, uint8_t new_to
 }
 
 static void
+dp_netdev_set_ip_ttl(struct ip_header *nh, uint8_t new_ttl)
+{
+    uint8_t *field = &nh->ip_ttl;
+
+    nh->ip_csum = recalc_csum16(nh->ip_csum, htons(*field << 8),
+                                   htons(new_ttl << 8));
+    *field = new_ttl;
+}
+
+static void
 dp_netdev_set_ipv4(struct ofpbuf *packet, const struct ovs_key_ipv4 *ipv4_key)
 {
     struct ip_header *nh = packet->l3;
@@ -1105,6 +1115,9 @@ dp_netdev_set_ipv4(struct ofpbuf *packet, const struct ovs
     if (nh->ip_tos != ipv4_key->ipv4_tos) {
         dp_netdev_set_ip_tos(nh, ipv4_key->ipv4_tos);
     }
+    if (nh->ip_ttl != ipv4_key->ipv4_ttl) {
+        dp_netdev_set_ip_ttl(nh, ipv4_key->ipv4_ttl);
+    }
 }
 
 static void
diff --git a/lib/odp-util.c b/lib/odp-util.c
index 3703844..4b0cee4 100644
--- a/lib/odp-util.c
+++ b/lib/odp-util.c
@@ -390,7 +390,7 @@ format_odp_key_attr(const struct nlattr *a, struct ds *ds)
                       ",tos=%#"PRIx8",ttl=%"PRIu8",frag=%s)",
                       src_str, dst_str, ntohl(ipv6_key->ipv6_label),
                       ipv6_key->ipv6_proto, ipv6_key->ipv6_tos,
-                      ipv6_key->ipv6_ttl,
+                      ipv6_key->ipv6_hop_limit,
                       ovs_frag_type_to_string(ipv6_key->ipv6_frag));
         break;
     }
@@ -621,7 +621,6 @@ parse_odp_key_attr(const char *s, struct ofpbuf *key)
             && ovs_frag_type_from_string(frag, &ipv4_frag)) {
             struct ovs_key_ipv4 ipv4_key;
 
-            memset(&ipv4_key, 0, sizeof ipv4_key);
             ipv4_key.ipv4_src = ipv4_src;
             ipv4_key.ipv4_dst = ipv4_dst;
             ipv4_key.ipv4_proto = ipv4_proto;
@@ -640,7 +639,7 @@ parse_odp_key_attr(const char *s, struct ofpbuf *key)
         int ipv6_label;
         int ipv6_proto;
         int ipv6_tos;
-        int ipv6_ttl;
+        int ipv6_hop_limit;
         char frag[8];
         enum ovs_frag_type ipv6_frag;
         int n = -1;
@@ -648,12 +647,11 @@ parse_odp_key_attr(const char *s, struct ofpbuf *key)
         if (sscanf(s, "ipv6(src="IPV6_SCAN_FMT",dst="IPV6_SCAN_FMT","
                    "label=%i,proto=%i,tos=%i,ttl=%i,frag=%7[a-z])%n",
                    ipv6_src_s, ipv6_dst_s, &ipv6_label,
-                   &ipv6_proto, &ipv6_tos, &ipv6_ttl, frag, &n) > 0
+                   &ipv6_proto, &ipv6_tos, &ipv6_hop_limit, frag, &n) > 0
             && n > 0
             && ovs_frag_type_from_string(frag, &ipv6_frag)) {
             struct ovs_key_ipv6 ipv6_key;
 
-            memset(&ipv6_key, 0, sizeof ipv6_key);
             if (inet_pton(AF_INET6, ipv6_src_s, &ipv6_key.ipv6_src) != 1 ||
                 inet_pton(AF_INET6, ipv6_dst_s, &ipv6_key.ipv6_dst) != 1) {
                 return -EINVAL;
@@ -661,7 +659,7 @@ parse_odp_key_attr(const char *s, struct ofpbuf *key)
             ipv6_key.ipv6_label = htonl(ipv6_label);
             ipv6_key.ipv6_proto = ipv6_proto;
             ipv6_key.ipv6_tos = ipv6_tos;
-            ipv6_key.ipv6_ttl = ipv6_ttl;
+            ipv6_key.ipv6_hop_limit = ipv6_hop_limit;
             ipv6_key.ipv6_frag = ipv6_frag;
             nl_msg_put_unspec(key, OVS_KEY_ATTR_IPV6,
                               &ipv6_key, sizeof ipv6_key);
@@ -878,7 +876,6 @@ odp_flow_key_from_flow(struct ofpbuf *buf, const struct flow
 
         ipv4_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_IPV4,
                                             sizeof *ipv4_key);
-        memset(ipv4_key, 0, sizeof *ipv4_key);
         ipv4_key->ipv4_src = flow->nw_src;
         ipv4_key->ipv4_dst = flow->nw_dst;
         ipv4_key->ipv4_proto = flow->nw_proto;
@@ -890,13 +887,12 @@ odp_flow_key_from_flow(struct ofpbuf *buf, const struct fl
 
         ipv6_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_IPV6,
                                             sizeof *ipv6_key);
-        memset(ipv6_key, 0, sizeof *ipv6_key);
         memcpy(ipv6_key->ipv6_src, &flow->ipv6_src, sizeof ipv6_key->ipv6_src);
         memcpy(ipv6_key->ipv6_dst, &flow->ipv6_dst, sizeof ipv6_key->ipv6_dst);
         ipv6_key->ipv6_label = flow->ipv6_label;
         ipv6_key->ipv6_proto = flow->nw_proto;
         ipv6_key->ipv6_tos = flow->tos;
-        ipv6_key->ipv6_ttl = flow->nw_ttl;
+        ipv6_key->ipv6_hop_limit = flow->nw_ttl;
         ipv6_key->ipv6_frag = ovs_to_odp_frag(flow->frag);
     } else if (flow->dl_type == htons(ETH_TYPE_ARP)) {
         struct ovs_key_arp *arp_key;
@@ -1085,7 +1081,7 @@ odp_flow_key_to_flow(const struct nlattr *key, size_t key_
             flow->ipv6_label = ipv6_key->ipv6_label;
             flow->nw_proto = ipv6_key->ipv6_proto;
             flow->tos = ipv6_key->ipv6_tos;
-            flow->nw_ttl = ipv6_key->ipv6_ttl;
+            flow->nw_ttl = ipv6_key->ipv6_hop_limit;
             if (!odp_to_ovs_frag(ipv6_key->ipv6_frag, flow)) {
                 return EINVAL;
             }
diff --git a/lib/odp-util.h b/lib/odp-util.h
index 73c3362..0f4f9e6 100644
--- a/lib/odp-util.h
+++ b/lib/odp-util.h
@@ -72,7 +72,7 @@ void format_odp_actions(struct ds *, const struct nlattr *odp_
  *  OVS_KEY_ATTR_ETHERNET     12    --     4     16
  *  OVS_KEY_ATTR_8021Q         4    --     4      8
  *  OVS_KEY_ATTR_ETHERTYPE     2     2     4      8
- *  OVS_KEY_ATTR_IPV6         39     1     4     44
+ *  OVS_KEY_ATTR_IPV6         40    --     4     44
  *  OVS_KEY_ATTR_ICMPV6        2     2     4      8
  *  OVS_KEY_ATTR_ND           28    --     4     32
  *  -------------------------------------------------
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 58c00f4..f6eee59 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -3676,8 +3676,6 @@ commit_set_nw_action(const struct flow *flow, struct flow 
         return;
     }
 
-
-    memset(&ipv4_key, 0, sizeof(ipv4_key));
     ipv4_key.ipv4_src = base->nw_src = flow->nw_src;
     ipv4_key.ipv4_dst = base->nw_dst = flow->nw_dst;
     ipv4_key.ipv4_proto = base->nw_proto;
diff --git a/utilities/ovs-ofctl.8.in b/utilities/ovs-ofctl.8.in
index 2f9a0a3..cd8d4f2 100644
--- a/utilities/ovs-ofctl.8.in
+++ b/utilities/ovs-ofctl.8.in
@@ -417,7 +417,7 @@ When \fBdl_type\fR is wildcarded or set to a value other tha
 above).
 .
 .IP \fBnw_ttl=\fIttl\fR
-Matches IP TTL or IPv6 hop limit value \fIttl\fR, which is 
+Matches IP TTL or IPv6 hop limit value \fIttl\fR, which is
 specified as a decimal number between 0 and 255, inclusive.
 .IP
 When \fBdl_type\fR is wildcarded or set to a value other than 0x0800 or


 




More information about the dev mailing list