diff options
Diffstat (limited to 'drivers/net/ipvlan/ipvlan_core.c')
-rw-r--r-- | drivers/net/ipvlan/ipvlan_core.c | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c index d50887e3df6d..8c48bb2a94ea 100644 --- a/drivers/net/ipvlan/ipvlan_core.c +++ b/drivers/net/ipvlan/ipvlan_core.c | |||
@@ -254,7 +254,7 @@ acct: | |||
254 | } | 254 | } |
255 | } | 255 | } |
256 | 256 | ||
257 | static int ipvlan_rcv_frame(struct ipvl_addr *addr, struct sk_buff *skb, | 257 | static int ipvlan_rcv_frame(struct ipvl_addr *addr, struct sk_buff **pskb, |
258 | bool local) | 258 | bool local) |
259 | { | 259 | { |
260 | struct ipvl_dev *ipvlan = addr->master; | 260 | struct ipvl_dev *ipvlan = addr->master; |
@@ -262,6 +262,7 @@ static int ipvlan_rcv_frame(struct ipvl_addr *addr, struct sk_buff *skb, | |||
262 | unsigned int len; | 262 | unsigned int len; |
263 | rx_handler_result_t ret = RX_HANDLER_CONSUMED; | 263 | rx_handler_result_t ret = RX_HANDLER_CONSUMED; |
264 | bool success = false; | 264 | bool success = false; |
265 | struct sk_buff *skb = *pskb; | ||
265 | 266 | ||
266 | len = skb->len + ETH_HLEN; | 267 | len = skb->len + ETH_HLEN; |
267 | if (unlikely(!(dev->flags & IFF_UP))) { | 268 | if (unlikely(!(dev->flags & IFF_UP))) { |
@@ -273,6 +274,7 @@ static int ipvlan_rcv_frame(struct ipvl_addr *addr, struct sk_buff *skb, | |||
273 | if (!skb) | 274 | if (!skb) |
274 | goto out; | 275 | goto out; |
275 | 276 | ||
277 | *pskb = skb; | ||
276 | skb->dev = dev; | 278 | skb->dev = dev; |
277 | skb->pkt_type = PACKET_HOST; | 279 | skb->pkt_type = PACKET_HOST; |
278 | 280 | ||
@@ -486,7 +488,7 @@ static int ipvlan_xmit_mode_l3(struct sk_buff *skb, struct net_device *dev) | |||
486 | 488 | ||
487 | addr = ipvlan_addr_lookup(ipvlan->port, lyr3h, addr_type, true); | 489 | addr = ipvlan_addr_lookup(ipvlan->port, lyr3h, addr_type, true); |
488 | if (addr) | 490 | if (addr) |
489 | return ipvlan_rcv_frame(addr, skb, true); | 491 | return ipvlan_rcv_frame(addr, &skb, true); |
490 | 492 | ||
491 | out: | 493 | out: |
492 | skb->dev = ipvlan->phy_dev; | 494 | skb->dev = ipvlan->phy_dev; |
@@ -506,7 +508,7 @@ static int ipvlan_xmit_mode_l2(struct sk_buff *skb, struct net_device *dev) | |||
506 | if (lyr3h) { | 508 | if (lyr3h) { |
507 | addr = ipvlan_addr_lookup(ipvlan->port, lyr3h, addr_type, true); | 509 | addr = ipvlan_addr_lookup(ipvlan->port, lyr3h, addr_type, true); |
508 | if (addr) | 510 | if (addr) |
509 | return ipvlan_rcv_frame(addr, skb, true); | 511 | return ipvlan_rcv_frame(addr, &skb, true); |
510 | } | 512 | } |
511 | skb = skb_share_check(skb, GFP_ATOMIC); | 513 | skb = skb_share_check(skb, GFP_ATOMIC); |
512 | if (!skb) | 514 | if (!skb) |
@@ -589,7 +591,7 @@ static rx_handler_result_t ipvlan_handle_mode_l3(struct sk_buff **pskb, | |||
589 | 591 | ||
590 | addr = ipvlan_addr_lookup(port, lyr3h, addr_type, true); | 592 | addr = ipvlan_addr_lookup(port, lyr3h, addr_type, true); |
591 | if (addr) | 593 | if (addr) |
592 | ret = ipvlan_rcv_frame(addr, skb, false); | 594 | ret = ipvlan_rcv_frame(addr, pskb, false); |
593 | 595 | ||
594 | out: | 596 | out: |
595 | return ret; | 597 | return ret; |
@@ -626,7 +628,7 @@ static rx_handler_result_t ipvlan_handle_mode_l2(struct sk_buff **pskb, | |||
626 | 628 | ||
627 | addr = ipvlan_addr_lookup(port, lyr3h, addr_type, true); | 629 | addr = ipvlan_addr_lookup(port, lyr3h, addr_type, true); |
628 | if (addr) | 630 | if (addr) |
629 | ret = ipvlan_rcv_frame(addr, skb, false); | 631 | ret = ipvlan_rcv_frame(addr, pskb, false); |
630 | } | 632 | } |
631 | 633 | ||
632 | return ret; | 634 | return ret; |
@@ -651,5 +653,5 @@ rx_handler_result_t ipvlan_handle_frame(struct sk_buff **pskb) | |||
651 | WARN_ONCE(true, "ipvlan_handle_frame() called for mode = [%hx]\n", | 653 | WARN_ONCE(true, "ipvlan_handle_frame() called for mode = [%hx]\n", |
652 | port->mode); | 654 | port->mode); |
653 | kfree_skb(skb); | 655 | kfree_skb(skb); |
654 | return NET_RX_DROP; | 656 | return RX_HANDLER_CONSUMED; |
655 | } | 657 | } |