aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/core/dev.c')
-rw-r--r--net/core/dev.c35
1 files changed, 19 insertions, 16 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index faf59b02c4bf..e1cc162bf295 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1058,7 +1058,7 @@ void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
1058 1058
1059 skb2->h.raw = skb2->nh.raw; 1059 skb2->h.raw = skb2->nh.raw;
1060 skb2->pkt_type = PACKET_OUTGOING; 1060 skb2->pkt_type = PACKET_OUTGOING;
1061 ptype->func(skb2, skb->dev, ptype); 1061 ptype->func(skb2, skb->dev, ptype, skb->dev);
1062 } 1062 }
1063 } 1063 }
1064 rcu_read_unlock(); 1064 rcu_read_unlock();
@@ -1425,14 +1425,14 @@ int netif_rx_ni(struct sk_buff *skb)
1425 1425
1426EXPORT_SYMBOL(netif_rx_ni); 1426EXPORT_SYMBOL(netif_rx_ni);
1427 1427
1428static __inline__ void skb_bond(struct sk_buff *skb) 1428static inline struct net_device *skb_bond(struct sk_buff *skb)
1429{ 1429{
1430 struct net_device *dev = skb->dev; 1430 struct net_device *dev = skb->dev;
1431 1431
1432 if (dev->master) { 1432 if (dev->master)
1433 skb->real_dev = skb->dev;
1434 skb->dev = dev->master; 1433 skb->dev = dev->master;
1435 } 1434
1435 return dev;
1436} 1436}
1437 1437
1438static void net_tx_action(struct softirq_action *h) 1438static void net_tx_action(struct softirq_action *h)
@@ -1482,10 +1482,11 @@ static void net_tx_action(struct softirq_action *h)
1482} 1482}
1483 1483
1484static __inline__ int deliver_skb(struct sk_buff *skb, 1484static __inline__ int deliver_skb(struct sk_buff *skb,
1485 struct packet_type *pt_prev) 1485 struct packet_type *pt_prev,
1486 struct net_device *orig_dev)
1486{ 1487{
1487 atomic_inc(&skb->users); 1488 atomic_inc(&skb->users);
1488 return pt_prev->func(skb, skb->dev, pt_prev); 1489 return pt_prev->func(skb, skb->dev, pt_prev, orig_dev);
1489} 1490}
1490 1491
1491#if defined(CONFIG_BRIDGE) || defined (CONFIG_BRIDGE_MODULE) 1492#if defined(CONFIG_BRIDGE) || defined (CONFIG_BRIDGE_MODULE)
@@ -1496,7 +1497,8 @@ struct net_bridge_fdb_entry *(*br_fdb_get_hook)(struct net_bridge *br,
1496void (*br_fdb_put_hook)(struct net_bridge_fdb_entry *ent); 1497void (*br_fdb_put_hook)(struct net_bridge_fdb_entry *ent);
1497 1498
1498static __inline__ int handle_bridge(struct sk_buff **pskb, 1499static __inline__ int handle_bridge(struct sk_buff **pskb,
1499 struct packet_type **pt_prev, int *ret) 1500 struct packet_type **pt_prev, int *ret,
1501 struct net_device *orig_dev)
1500{ 1502{
1501 struct net_bridge_port *port; 1503 struct net_bridge_port *port;
1502 1504
@@ -1505,14 +1507,14 @@ static __inline__ int handle_bridge(struct sk_buff **pskb,
1505 return 0; 1507 return 0;
1506 1508
1507 if (*pt_prev) { 1509 if (*pt_prev) {
1508 *ret = deliver_skb(*pskb, *pt_prev); 1510 *ret = deliver_skb(*pskb, *pt_prev, orig_dev);
1509 *pt_prev = NULL; 1511 *pt_prev = NULL;
1510 } 1512 }
1511 1513
1512 return br_handle_frame_hook(port, pskb); 1514 return br_handle_frame_hook(port, pskb);
1513} 1515}
1514#else 1516#else
1515#define handle_bridge(skb, pt_prev, ret) (0) 1517#define handle_bridge(skb, pt_prev, ret, orig_dev) (0)
1516#endif 1518#endif
1517 1519
1518#ifdef CONFIG_NET_CLS_ACT 1520#ifdef CONFIG_NET_CLS_ACT
@@ -1559,6 +1561,7 @@ static int ing_filter(struct sk_buff *skb)
1559int netif_receive_skb(struct sk_buff *skb) 1561int netif_receive_skb(struct sk_buff *skb)
1560{ 1562{
1561 struct packet_type *ptype, *pt_prev; 1563 struct packet_type *ptype, *pt_prev;
1564 struct net_device *orig_dev;
1562 int ret = NET_RX_DROP; 1565 int ret = NET_RX_DROP;
1563 unsigned short type; 1566 unsigned short type;
1564 1567
@@ -1569,7 +1572,7 @@ int netif_receive_skb(struct sk_buff *skb)
1569 if (!skb->stamp.tv_sec) 1572 if (!skb->stamp.tv_sec)
1570 net_timestamp(&skb->stamp); 1573 net_timestamp(&skb->stamp);
1571 1574
1572 skb_bond(skb); 1575 orig_dev = skb_bond(skb);
1573 1576
1574 __get_cpu_var(netdev_rx_stat).total++; 1577 __get_cpu_var(netdev_rx_stat).total++;
1575 1578
@@ -1590,14 +1593,14 @@ int netif_receive_skb(struct sk_buff *skb)
1590 list_for_each_entry_rcu(ptype, &ptype_all, list) { 1593 list_for_each_entry_rcu(ptype, &ptype_all, list) {
1591 if (!ptype->dev || ptype->dev == skb->dev) { 1594 if (!ptype->dev || ptype->dev == skb->dev) {
1592 if (pt_prev) 1595 if (pt_prev)
1593 ret = deliver_skb(skb, pt_prev); 1596 ret = deliver_skb(skb, pt_prev, orig_dev);
1594 pt_prev = ptype; 1597 pt_prev = ptype;
1595 } 1598 }
1596 } 1599 }
1597 1600
1598#ifdef CONFIG_NET_CLS_ACT 1601#ifdef CONFIG_NET_CLS_ACT
1599 if (pt_prev) { 1602 if (pt_prev) {
1600 ret = deliver_skb(skb, pt_prev); 1603 ret = deliver_skb(skb, pt_prev, orig_dev);
1601 pt_prev = NULL; /* noone else should process this after*/ 1604 pt_prev = NULL; /* noone else should process this after*/
1602 } else { 1605 } else {
1603 skb->tc_verd = SET_TC_OK2MUNGE(skb->tc_verd); 1606 skb->tc_verd = SET_TC_OK2MUNGE(skb->tc_verd);
@@ -1616,7 +1619,7 @@ ncls:
1616 1619
1617 handle_diverter(skb); 1620 handle_diverter(skb);
1618 1621
1619 if (handle_bridge(&skb, &pt_prev, &ret)) 1622 if (handle_bridge(&skb, &pt_prev, &ret, orig_dev))
1620 goto out; 1623 goto out;
1621 1624
1622 type = skb->protocol; 1625 type = skb->protocol;
@@ -1624,13 +1627,13 @@ ncls:
1624 if (ptype->type == type && 1627 if (ptype->type == type &&
1625 (!ptype->dev || ptype->dev == skb->dev)) { 1628 (!ptype->dev || ptype->dev == skb->dev)) {
1626 if (pt_prev) 1629 if (pt_prev)
1627 ret = deliver_skb(skb, pt_prev); 1630 ret = deliver_skb(skb, pt_prev, orig_dev);
1628 pt_prev = ptype; 1631 pt_prev = ptype;
1629 } 1632 }
1630 } 1633 }
1631 1634
1632 if (pt_prev) { 1635 if (pt_prev) {
1633 ret = pt_prev->func(skb, skb->dev, pt_prev); 1636 ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev);
1634 } else { 1637 } else {
1635 kfree_skb(skb); 1638 kfree_skb(skb);
1636 /* Jamal, now you will not able to escape explaining 1639 /* Jamal, now you will not able to escape explaining