aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/dev.c
diff options
context:
space:
mode:
authorJoe Eykholt <jre@nuovasystems.com>2008-07-02 21:22:01 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-08-07 03:59:59 -0400
commit0d7a3681232f545c6a59f77e60f7667673ef0e93 (patch)
tree95a59cbd3350bab4b0ec4fcef577a52a88ef5b13 /net/core/dev.c
parentcc9bd5cebc0825e0fabc0186ab85806a0891104f (diff)
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/core/dev.c')
-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)
2165{ 2165{
2166 struct packet_type *ptype, *pt_prev; 2166 struct packet_type *ptype, *pt_prev;
2167 struct net_device *orig_dev; 2167 struct net_device *orig_dev;
2168 struct net_device *null_or_orig;
2168 int ret = NET_RX_DROP; 2169 int ret = NET_RX_DROP;
2169 __be16 type; 2170 __be16 type;
2170 2171
@@ -2178,13 +2179,13 @@ int netif_receive_skb(struct sk_buff *skb)
2178 if (!skb->iif) 2179 if (!skb->iif)
2179 skb->iif = skb->dev->ifindex; 2180 skb->iif = skb->dev->ifindex;
2180 2181
2182 null_or_orig = NULL;
2181 orig_dev = skb->dev; 2183 orig_dev = skb->dev;
2182 if (orig_dev->master) { 2184 if (orig_dev->master) {
2183 if (skb_bond_should_drop(skb)) { 2185 if (skb_bond_should_drop(skb))
2184 kfree_skb(skb); 2186 null_or_orig = orig_dev; /* deliver only exact match */
2185 return NET_RX_DROP; 2187 else
2186 } 2188 skb->dev = orig_dev->master;
2187 skb->dev = orig_dev->master;
2188 } 2189 }
2189 2190
2190 __get_cpu_var(netdev_rx_stat).total++; 2191 __get_cpu_var(netdev_rx_stat).total++;
@@ -2209,7 +2210,7 @@ int netif_receive_skb(struct sk_buff *skb)
2209#endif 2210#endif
2210 2211
2211 list_for_each_entry_rcu(ptype, &ptype_all, list) { 2212 list_for_each_entry_rcu(ptype, &ptype_all, list) {
2212 if (!ptype->dev || ptype->dev == skb->dev) { 2213 if (ptype->dev == null_or_orig || ptype->dev == skb->dev) {
2213 if (pt_prev) 2214 if (pt_prev)
2214 ret = deliver_skb(skb, pt_prev, orig_dev); 2215 ret = deliver_skb(skb, pt_prev, orig_dev);
2215 pt_prev = ptype; 2216 pt_prev = ptype;
@@ -2234,7 +2235,7 @@ ncls:
2234 list_for_each_entry_rcu(ptype, 2235 list_for_each_entry_rcu(ptype,
2235 &ptype_base[ntohs(type) & PTYPE_HASH_MASK], list) { 2236 &ptype_base[ntohs(type) & PTYPE_HASH_MASK], list) {
2236 if (ptype->type == type && 2237 if (ptype->type == type &&
2237 (!ptype->dev || ptype->dev == skb->dev)) { 2238 (ptype->dev == null_or_orig || ptype->dev == skb->dev)) {
2238 if (pt_prev) 2239 if (pt_prev)
2239 ret = deliver_skb(skb, pt_prev, orig_dev); 2240 ret = deliver_skb(skb, pt_prev, orig_dev);
2240 pt_prev = ptype; 2241 pt_prev = ptype;