* [net-next PATCH 1/5] etherdev: Fix sparse error, make test usable by other functions
2015-05-04 21:33 [net-next PATCH 0/5] Add eth_proto_is_802_3 to provide improved means of checking Ethertype Alexander Duyck
@ 2015-05-04 21:33 ` Alexander Duyck
2015-05-04 21:33 ` [net-next PATCH 2/5] ebtables: Use eth_proto_is_802_3 Alexander Duyck
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Alexander Duyck @ 2015-05-04 21:33 UTC (permalink / raw)
To: netdev; +Cc: stephen, pshelar, davem
This change does two things. First it fixes a sparse error for the fact
that the __be16 degrades to an integer. Since that is actually what I am
kind of doing I am simply working around that by forcing both sides of the
comparison to u16.
Also I realized on some compilers I was generating another instruction for
big endian systems such as PowerPC since it was masking the value before
doing the comparison. So to resolve that I have simply pulled the mask out
and wrapped it in an #ifndef __BIG_ENDIAN.
Lastly I pulled this all out into its own function. I notices there are
similar checks in a number of other places so this function can be reused
there to help reduce overhead in these paths as well.
Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com>
---
include/linux/etherdevice.h | 18 ++++++++++++++++++
net/ethernet/eth.c | 2 +-
2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h
index c4a10f991fe0..9012f8775208 100644
--- a/include/linux/etherdevice.h
+++ b/include/linux/etherdevice.h
@@ -191,6 +191,24 @@ static inline bool is_valid_ether_addr(const u8 *addr)
}
/**
+ * eth_proto_is_802_3 - Determine if a given Ethertype/length is a protocol
+ * @proto: Ethertype/length value to be tested
+ *
+ * Check that the value from the Ethertype/length field is a valid Ethertype.
+ *
+ * Return true if the valid is an 802.3 supported Ethertype.
+ */
+static inline bool eth_proto_is_802_3(__be16 proto)
+{
+#ifndef __BIG_ENDIAN
+ /* if CPU is little endian mask off bits representing LSB */
+ proto &= htons(0xFF00);
+#endif
+ /* cast both to u16 and compare since LSB can be ignored */
+ return (__force u16)proto >= (__force u16)htons(ETH_P_802_3_MIN);
+}
+
+/**
* eth_random_addr - Generate software assigned random Ethernet address
* @addr: Pointer to a six-byte array containing the Ethernet address
*
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index 314e4c5a5a5e..9045e2a1108f 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -179,7 +179,7 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev)
if (unlikely(netdev_uses_dsa(dev)))
return htons(ETH_P_XDSA);
- if (likely((eth->h_proto & htons(0xFF00)) >= htons(ETH_P_802_3_MIN)))
+ if (likely(eth_proto_is_802_3(eth->h_proto)))
return eth->h_proto;
/*
^ permalink raw reply related [flat|nested] 7+ messages in thread* [net-next PATCH 2/5] ebtables: Use eth_proto_is_802_3
2015-05-04 21:33 [net-next PATCH 0/5] Add eth_proto_is_802_3 to provide improved means of checking Ethertype Alexander Duyck
2015-05-04 21:33 ` [net-next PATCH 1/5] etherdev: Fix sparse error, make test usable by other functions Alexander Duyck
@ 2015-05-04 21:33 ` Alexander Duyck
2015-05-04 21:33 ` [net-next PATCH 3/5] ipv4/ip_tunnel_core: " Alexander Duyck
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Alexander Duyck @ 2015-05-04 21:33 UTC (permalink / raw)
To: netdev; +Cc: stephen, pshelar, davem
Replace "ntohs(proto) >= ETH_P_802_3_MIN" w/ eth_proto_is_802_3(proto).
Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com>
---
net/bridge/netfilter/ebtables.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index 91180a7fc943..5149d9e71114 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -139,7 +139,7 @@ ebt_basic_match(const struct ebt_entry *e, const struct sk_buff *skb,
ethproto = h->h_proto;
if (e->bitmask & EBT_802_3) {
- if (FWINV2(ntohs(ethproto) >= ETH_P_802_3_MIN, EBT_IPROTO))
+ if (FWINV2(eth_proto_is_802_3(ethproto), EBT_IPROTO))
return 1;
} else if (!(e->bitmask & EBT_NOPROTO) &&
FWINV2(e->ethproto != ethproto, EBT_IPROTO))
^ permalink raw reply related [flat|nested] 7+ messages in thread* [net-next PATCH 3/5] ipv4/ip_tunnel_core: Use eth_proto_is_802_3
2015-05-04 21:33 [net-next PATCH 0/5] Add eth_proto_is_802_3 to provide improved means of checking Ethertype Alexander Duyck
2015-05-04 21:33 ` [net-next PATCH 1/5] etherdev: Fix sparse error, make test usable by other functions Alexander Duyck
2015-05-04 21:33 ` [net-next PATCH 2/5] ebtables: Use eth_proto_is_802_3 Alexander Duyck
@ 2015-05-04 21:33 ` Alexander Duyck
2015-05-04 21:34 ` [net-next PATCH 4/5] openvswitch: " Alexander Duyck
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Alexander Duyck @ 2015-05-04 21:33 UTC (permalink / raw)
To: netdev; +Cc: stephen, pshelar, davem
Replace "ntohs(proto) >= ETH_P_802_3_MIN" w/ eth_proto_is_802_3(proto).
Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com>
---
net/ipv4/ip_tunnel_core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c
index ce63ab21b6cd..3998b1822d85 100644
--- a/net/ipv4/ip_tunnel_core.c
+++ b/net/ipv4/ip_tunnel_core.c
@@ -98,7 +98,7 @@ int iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto)
return -ENOMEM;
eh = (struct ethhdr *)skb->data;
- if (likely(ntohs(eh->h_proto) >= ETH_P_802_3_MIN))
+ if (likely(eth_proto_is_802_3(eh->h_proto)))
skb->protocol = eh->h_proto;
else
skb->protocol = htons(ETH_P_802_2);
^ permalink raw reply related [flat|nested] 7+ messages in thread* [net-next PATCH 4/5] openvswitch: Use eth_proto_is_802_3
2015-05-04 21:33 [net-next PATCH 0/5] Add eth_proto_is_802_3 to provide improved means of checking Ethertype Alexander Duyck
` (2 preceding siblings ...)
2015-05-04 21:33 ` [net-next PATCH 3/5] ipv4/ip_tunnel_core: " Alexander Duyck
@ 2015-05-04 21:34 ` Alexander Duyck
2015-05-04 21:34 ` [net-next PATCH 5/5] vlan: " Alexander Duyck
2015-05-05 23:24 ` [net-next PATCH 0/5] Add eth_proto_is_802_3 to provide improved means of checking Ethertype David Miller
5 siblings, 0 replies; 7+ messages in thread
From: Alexander Duyck @ 2015-05-04 21:34 UTC (permalink / raw)
To: netdev; +Cc: stephen, pshelar, davem
Replace "ntohs(proto) >= ETH_P_802_3_MIN" w/ eth_proto_is_802_3(proto).
Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com>
---
net/openvswitch/datapath.c | 2 +-
net/openvswitch/flow.c | 4 ++--
net/openvswitch/flow_netlink.c | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index 096c6276e6b9..3b90461317ec 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -545,7 +545,7 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
/* Normally, setting the skb 'protocol' field would be handled by a
* call to eth_type_trans(), but it assumes there's a sending
* device, which we may not have. */
- if (ntohs(eth->h_proto) >= ETH_P_802_3_MIN)
+ if (eth_proto_is_802_3(eth->h_proto))
packet->protocol = eth->h_proto;
else
packet->protocol = htons(ETH_P_802_2);
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c
index 2dacc7b5af23..bc7b0aba994a 100644
--- a/net/openvswitch/flow.c
+++ b/net/openvswitch/flow.c
@@ -332,7 +332,7 @@ static __be16 parse_ethertype(struct sk_buff *skb)
proto = *(__be16 *) skb->data;
__skb_pull(skb, sizeof(__be16));
- if (ntohs(proto) >= ETH_P_802_3_MIN)
+ if (eth_proto_is_802_3(proto))
return proto;
if (skb->len < sizeof(struct llc_snap_hdr))
@@ -349,7 +349,7 @@ static __be16 parse_ethertype(struct sk_buff *skb)
__skb_pull(skb, sizeof(struct llc_snap_hdr));
- if (ntohs(llc->ethertype) >= ETH_P_802_3_MIN)
+ if (eth_proto_is_802_3(llc->ethertype))
return llc->ethertype;
return htons(ETH_P_802_2);
diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
index c691b1a1eee0..624e41c4267f 100644
--- a/net/openvswitch/flow_netlink.c
+++ b/net/openvswitch/flow_netlink.c
@@ -816,7 +816,7 @@ static int ovs_key_from_nlattrs(struct sw_flow_match *match, u64 attrs,
if (is_mask) {
/* Always exact match EtherType. */
eth_type = htons(0xffff);
- } else if (ntohs(eth_type) < ETH_P_802_3_MIN) {
+ } else if (!eth_proto_is_802_3(eth_type)) {
OVS_NLERR(log, "EtherType %x is less than min %x",
ntohs(eth_type), ETH_P_802_3_MIN);
return -EINVAL;
^ permalink raw reply related [flat|nested] 7+ messages in thread* [net-next PATCH 5/5] vlan: Use eth_proto_is_802_3
2015-05-04 21:33 [net-next PATCH 0/5] Add eth_proto_is_802_3 to provide improved means of checking Ethertype Alexander Duyck
` (3 preceding siblings ...)
2015-05-04 21:34 ` [net-next PATCH 4/5] openvswitch: " Alexander Duyck
@ 2015-05-04 21:34 ` Alexander Duyck
2015-05-05 23:24 ` [net-next PATCH 0/5] Add eth_proto_is_802_3 to provide improved means of checking Ethertype David Miller
5 siblings, 0 replies; 7+ messages in thread
From: Alexander Duyck @ 2015-05-04 21:34 UTC (permalink / raw)
To: netdev; +Cc: stephen, pshelar, davem
Replace "ntohs(proto) >= ETH_P_802_3_MIN" w/ eth_proto_is_802_3(proto).
Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com>
---
include/linux/if_vlan.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index 920e4457ce6e..b9ab677c0c0a 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -539,7 +539,7 @@ static inline void vlan_set_encap_proto(struct sk_buff *skb,
*/
proto = vhdr->h_vlan_encapsulated_proto;
- if (ntohs(proto) >= ETH_P_802_3_MIN) {
+ if (eth_proto_is_802_3(proto)) {
skb->protocol = proto;
return;
}
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [net-next PATCH 0/5] Add eth_proto_is_802_3 to provide improved means of checking Ethertype
2015-05-04 21:33 [net-next PATCH 0/5] Add eth_proto_is_802_3 to provide improved means of checking Ethertype Alexander Duyck
` (4 preceding siblings ...)
2015-05-04 21:34 ` [net-next PATCH 5/5] vlan: " Alexander Duyck
@ 2015-05-05 23:24 ` David Miller
5 siblings, 0 replies; 7+ messages in thread
From: David Miller @ 2015-05-05 23:24 UTC (permalink / raw)
To: alexander.h.duyck; +Cc: netdev, stephen, pshelar
From: Alexander Duyck <alexander.h.duyck@redhat.com>
Date: Mon, 04 May 2015 14:33:42 -0700
> This patch series implements and makes use of eth_proto_is_802_3(). The
> idea behind the function is to provide an optimized means of testing to
> determine if a given Ethertype value is a length or 802.3 protocol number.
> The standard path for this was to use ntohs(proto) and then perform a
> comparison. This adds a slight cost as it usually requires either a 16b
> rotate or byte swap which can cost 1 cycle or more depending on the
> processor.
>
> I had previously addressed this for eth_type_trans, however in doing so I had
> overlooked checking with sparse and had introduced a couple sparse warnings.
> The first patch in this series fixes those sparse warnings as well as does
> some additional optimization for big endian systems. In addition it pushes
> the code out into a separate function which can then be used in the other
> patches to reduce the instruction count/processing time in those functions
> as well.
Series applied, thanks!
^ permalink raw reply [flat|nested] 7+ messages in thread