[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