From 18543a643fae694982c7d89c22436885f3506497 Mon Sep 17 00:00:00 2001 From: Guillaume Chazarain Date: Sat, 6 Nov 2010 06:39:32 +0000 Subject: net: Detect and ignore netif_stop_queue() calls before register_netdev() After e6484930d7c73d324bccda7d43d131088da697b9: net: allocate tx queues in register_netdevice These calls make net drivers oops at load time, so let's avoid people git-bisect'ing known problems. Signed-off-by: Guillaume Chazarain Signed-off-by: David S. Miller --- include/linux/netdevice.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 072652d94d9f..d8fd2c23a1b9 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1554,6 +1554,11 @@ static inline void netif_tx_wake_all_queues(struct net_device *dev) static inline void netif_tx_stop_queue(struct netdev_queue *dev_queue) { + if (WARN_ON(!dev_queue)) { + printk(KERN_INFO "netif_stop_queue() cannot be called before " + "register_netdev()"); + return; + } set_bit(__QUEUE_STATE_XOFF, &dev_queue->state); } -- cgit v1.2.3 From ac5aa2e3332ec04889074afdbd1479424d0227a5 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Fri, 12 Nov 2010 08:26:06 +0100 Subject: netfilter: NF_HOOK_COND has wrong conditional The NF_HOOK_COND returns 0 when it shouldn't due to what I believe to be an error in the code as the order of operations is not what was intended. C will evalutate == before =. Which means ret is getting set to the bool result, rather than the return value of the function call. The code says if (ret = function() == 1) when it meant to say: if ((ret = function()) == 1) Normally the compiler would warn, but it doesn't notice it because its a actually complex conditional and so the wrong code is wrapped in an explict set of () [exactly what the compiler wants you to do if this was intentional]. Fixing this means that errors when netfilter denies a packet get propagated back up the stack rather than lost. Problem introduced by commit 2249065f (netfilter: get rid of the grossness in netfilter.h). Signed-off-by: Eric Paris Cc: stable@kernel.org Signed-off-by: Patrick McHardy --- include/linux/netfilter.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h index 89341c32631a..03317c8d4077 100644 --- a/include/linux/netfilter.h +++ b/include/linux/netfilter.h @@ -215,7 +215,7 @@ NF_HOOK_COND(uint8_t pf, unsigned int hook, struct sk_buff *skb, int ret; if (!cond || - (ret = nf_hook_thresh(pf, hook, skb, in, out, okfn, INT_MIN) == 1)) + ((ret = nf_hook_thresh(pf, hook, skb, in, out, okfn, INT_MIN)) == 1)) ret = okfn(skb); return ret; } -- cgit v1.2.3 From 0a85df004667c99efc31fab07386823eefce3be5 Mon Sep 17 00:00:00 2001 From: Hao Zheng Date: Thu, 11 Nov 2010 13:47:57 +0000 Subject: vlan: Add function to retrieve EtherType from vlan packets. Depending on how a packet is vlan tagged (i.e. hardware accelerated or not), the encapsulated protocol is stored in different locations. This provides a consistent method of accessing that protocol, which is needed by drivers, security checks, etc. Signed-off-by: Hao Zheng Signed-off-by: Jesse Gross Signed-off-by: David S. Miller --- include/linux/if_vlan.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'include/linux') diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index c2f3a72712ce..635e1faec412 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -339,6 +339,31 @@ static inline int vlan_get_tag(const struct sk_buff *skb, u16 *vlan_tci) } } +/** + * vlan_get_protocol - get protocol EtherType. + * @skb: skbuff to query + * + * Returns the EtherType of the packet, regardless of whether it is + * vlan encapsulated (normal or hardware accelerated) or not. + */ +static inline __be16 vlan_get_protocol(const struct sk_buff *skb) +{ + __be16 protocol = 0; + + if (vlan_tx_tag_present(skb) || + skb->protocol != cpu_to_be16(ETH_P_8021Q)) + protocol = skb->protocol; + else { + __be16 proto, *protop; + protop = skb_header_pointer(skb, offsetof(struct vlan_ethhdr, + h_vlan_encapsulated_proto), + sizeof(proto), &proto); + if (likely(protop)) + protocol = *protop; + } + + return protocol; +} #endif /* __KERNEL__ */ /* VLAN IOCTLs are found in sockios.h */ -- cgit v1.2.3