summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJoe Eykholt <jre@nuovasystems.com>2008-07-02 18:22:01 -0700
committerJeff Garzik <jgarzik@redhat.com>2008-08-07 03:59:59 -0400
commit0d7a3681232f545c6a59f77e60f7667673ef0e93 (patch)
tree95a59cbd3350bab4b0ec4fcef577a52a88ef5b13 /net
parentcc9bd5cebc0825e0fabc0186ab85806a0891104f (diff)
downloadlinux-0d7a3681232f545c6a59f77e60f7667673ef0e93.tar.gz
linux-0d7a3681232f545c6a59f77e60f7667673ef0e93.tar.bz2
linux-0d7a3681232f545c6a59f77e60f7667673ef0e93.zip
net/core: Allow certain receives on inactive slave.
Allow a packet_type that specifies the exact device to receive even on an inactive bonding slave devices. This is important for some L2 protocols such as LLDP and FCoE. This can eventually be used for the bonding special cases as well. Signed-off-by: Joe Eykholt <jre@nuovasystems.com> Signed-off-by: Jay Vosburgh <fubar@us.ibm.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'net')
-rw-r--r--net/core/dev.c15
1 files changed, 8 insertions, 7 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index 4a09833331f1..dab97c7cf275 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2165,6 +2165,7 @@ int netif_receive_skb(struct sk_buff *skb)
{
struct packet_type *ptype, *pt_prev;
struct net_device *orig_dev;
+ struct net_device *null_or_orig;
int ret = NET_RX_DROP;
__be16 type;
@@ -2178,13 +2179,13 @@ int netif_receive_skb(struct sk_buff *skb)
if (!skb->iif)
skb->iif = skb->dev->ifindex;
+ null_or_orig = NULL;
orig_dev = skb->dev;
if (orig_dev->master) {
- if (skb_bond_should_drop(skb)) {
- kfree_skb(skb);
- return NET_RX_DROP;
- }
- skb->dev = orig_dev->master;
+ if (skb_bond_should_drop(skb))
+ null_or_orig = orig_dev; /* deliver only exact match */
+ else
+ skb->dev = orig_dev->master;
}
__get_cpu_var(netdev_rx_stat).total++;
@@ -2209,7 +2210,7 @@ int netif_receive_skb(struct sk_buff *skb)
#endif
list_for_each_entry_rcu(ptype, &ptype_all, list) {
- if (!ptype->dev || ptype->dev == skb->dev) {
+ if (ptype->dev == null_or_orig || ptype->dev == skb->dev) {
if (pt_prev)
ret = deliver_skb(skb, pt_prev, orig_dev);
pt_prev = ptype;
@@ -2234,7 +2235,7 @@ ncls:
list_for_each_entry_rcu(ptype,
&ptype_base[ntohs(type) & PTYPE_HASH_MASK], list) {
if (ptype->type == type &&
- (!ptype->dev || ptype->dev == skb->dev)) {
+ (ptype->dev == null_or_orig || ptype->dev == skb->dev)) {
if (pt_prev)
ret = deliver_skb(skb, pt_prev, orig_dev);
pt_prev = ptype;