aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMahesh Bandewar <maheshb@google.com>2016-02-20 22:31:32 -0500
committerDavid S. Miller <davem@davemloft.net>2016-02-21 22:43:24 -0500
commitc3aaa06d5a63609641b7ad62ee0956f3de86c1cd (patch)
treeaa5355c96761db9149a163adfec2ce5285eb4168
parent86310cc42ddf300a9482c613720e7811abec2c4c (diff)
ipvlan: scrub skb before routing in L3 mode.
Scrub skb before hitting the iptable hooks to ensure packets hit these hooks. Set the xnet param only when the packet is crossing the ns boundry so if the IPvlan slave and master belong to the same ns, the param will be set to false. Signed-off-by: Mahesh Bandewar <maheshb@google.com> CC: Cong Wang <xiyou.wangcong@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ipvlan/ipvlan_core.c19
1 files changed, 10 insertions, 9 deletions
diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c
index 8c48bb2a94ea..4e60c6bbdb6e 100644
--- a/drivers/net/ipvlan/ipvlan_core.c
+++ b/drivers/net/ipvlan/ipvlan_core.c
@@ -342,7 +342,7 @@ static struct ipvl_addr *ipvlan_addr_lookup(struct ipvl_port *port,
342 return addr; 342 return addr;
343} 343}
344 344
345static int ipvlan_process_v4_outbound(struct sk_buff *skb) 345static int ipvlan_process_v4_outbound(struct sk_buff *skb, bool xnet)
346{ 346{
347 const struct iphdr *ip4h = ip_hdr(skb); 347 const struct iphdr *ip4h = ip_hdr(skb);
348 struct net_device *dev = skb->dev; 348 struct net_device *dev = skb->dev;
@@ -365,7 +365,7 @@ static int ipvlan_process_v4_outbound(struct sk_buff *skb)
365 ip_rt_put(rt); 365 ip_rt_put(rt);
366 goto err; 366 goto err;
367 } 367 }
368 skb_dst_drop(skb); 368 skb_scrub_packet(skb, xnet);
369 skb_dst_set(skb, &rt->dst); 369 skb_dst_set(skb, &rt->dst);
370 err = ip_local_out(net, skb->sk, skb); 370 err = ip_local_out(net, skb->sk, skb);
371 if (unlikely(net_xmit_eval(err))) 371 if (unlikely(net_xmit_eval(err)))
@@ -380,7 +380,7 @@ out:
380 return ret; 380 return ret;
381} 381}
382 382
383static int ipvlan_process_v6_outbound(struct sk_buff *skb) 383static int ipvlan_process_v6_outbound(struct sk_buff *skb, bool xnet)
384{ 384{
385 const struct ipv6hdr *ip6h = ipv6_hdr(skb); 385 const struct ipv6hdr *ip6h = ipv6_hdr(skb);
386 struct net_device *dev = skb->dev; 386 struct net_device *dev = skb->dev;
@@ -403,7 +403,7 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb)
403 dst_release(dst); 403 dst_release(dst);
404 goto err; 404 goto err;
405 } 405 }
406 skb_dst_drop(skb); 406 skb_scrub_packet(skb, xnet);
407 skb_dst_set(skb, dst); 407 skb_dst_set(skb, dst);
408 err = ip6_local_out(net, skb->sk, skb); 408 err = ip6_local_out(net, skb->sk, skb);
409 if (unlikely(net_xmit_eval(err))) 409 if (unlikely(net_xmit_eval(err)))
@@ -418,8 +418,7 @@ out:
418 return ret; 418 return ret;
419} 419}
420 420
421static int ipvlan_process_outbound(struct sk_buff *skb, 421static int ipvlan_process_outbound(struct sk_buff *skb, bool xnet)
422 const struct ipvl_dev *ipvlan)
423{ 422{
424 struct ethhdr *ethh = eth_hdr(skb); 423 struct ethhdr *ethh = eth_hdr(skb);
425 int ret = NET_XMIT_DROP; 424 int ret = NET_XMIT_DROP;
@@ -443,9 +442,9 @@ static int ipvlan_process_outbound(struct sk_buff *skb,
443 } 442 }
444 443
445 if (skb->protocol == htons(ETH_P_IPV6)) 444 if (skb->protocol == htons(ETH_P_IPV6))
446 ret = ipvlan_process_v6_outbound(skb); 445 ret = ipvlan_process_v6_outbound(skb, xnet);
447 else if (skb->protocol == htons(ETH_P_IP)) 446 else if (skb->protocol == htons(ETH_P_IP))
448 ret = ipvlan_process_v4_outbound(skb); 447 ret = ipvlan_process_v4_outbound(skb, xnet);
449 else { 448 else {
450 pr_warn_ratelimited("Dropped outbound packet type=%x\n", 449 pr_warn_ratelimited("Dropped outbound packet type=%x\n",
451 ntohs(skb->protocol)); 450 ntohs(skb->protocol));
@@ -481,6 +480,7 @@ static int ipvlan_xmit_mode_l3(struct sk_buff *skb, struct net_device *dev)
481 void *lyr3h; 480 void *lyr3h;
482 struct ipvl_addr *addr; 481 struct ipvl_addr *addr;
483 int addr_type; 482 int addr_type;
483 bool xnet;
484 484
485 lyr3h = ipvlan_get_L3_hdr(skb, &addr_type); 485 lyr3h = ipvlan_get_L3_hdr(skb, &addr_type);
486 if (!lyr3h) 486 if (!lyr3h)
@@ -491,8 +491,9 @@ static int ipvlan_xmit_mode_l3(struct sk_buff *skb, struct net_device *dev)
491 return ipvlan_rcv_frame(addr, &skb, true); 491 return ipvlan_rcv_frame(addr, &skb, true);
492 492
493out: 493out:
494 xnet = !net_eq(dev_net(skb->dev), dev_net(ipvlan->phy_dev));
494 skb->dev = ipvlan->phy_dev; 495 skb->dev = ipvlan->phy_dev;
495 return ipvlan_process_outbound(skb, ipvlan); 496 return ipvlan_process_outbound(skb, xnet);
496} 497}
497 498
498static int ipvlan_xmit_mode_l2(struct sk_buff *skb, struct net_device *dev) 499static int ipvlan_xmit_mode_l2(struct sk_buff *skb, struct net_device *dev)