Commit c3aaa06d authored by Mahesh Bandewar's avatar Mahesh Bandewar Committed by David S. Miller

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: default avatarMahesh Bandewar <maheshb@google.com>
CC: Cong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 86310cc4
...@@ -342,7 +342,7 @@ static struct ipvl_addr *ipvlan_addr_lookup(struct ipvl_port *port, ...@@ -342,7 +342,7 @@ static struct ipvl_addr *ipvlan_addr_lookup(struct ipvl_port *port,
return addr; return addr;
} }
static int ipvlan_process_v4_outbound(struct sk_buff *skb) static int ipvlan_process_v4_outbound(struct sk_buff *skb, bool xnet)
{ {
const struct iphdr *ip4h = ip_hdr(skb); const struct iphdr *ip4h = ip_hdr(skb);
struct net_device *dev = skb->dev; struct net_device *dev = skb->dev;
...@@ -365,7 +365,7 @@ static int ipvlan_process_v4_outbound(struct sk_buff *skb) ...@@ -365,7 +365,7 @@ static int ipvlan_process_v4_outbound(struct sk_buff *skb)
ip_rt_put(rt); ip_rt_put(rt);
goto err; goto err;
} }
skb_dst_drop(skb); skb_scrub_packet(skb, xnet);
skb_dst_set(skb, &rt->dst); skb_dst_set(skb, &rt->dst);
err = ip_local_out(net, skb->sk, skb); err = ip_local_out(net, skb->sk, skb);
if (unlikely(net_xmit_eval(err))) if (unlikely(net_xmit_eval(err)))
...@@ -380,7 +380,7 @@ static int ipvlan_process_v4_outbound(struct sk_buff *skb) ...@@ -380,7 +380,7 @@ static int ipvlan_process_v4_outbound(struct sk_buff *skb)
return ret; return ret;
} }
static int ipvlan_process_v6_outbound(struct sk_buff *skb) static int ipvlan_process_v6_outbound(struct sk_buff *skb, bool xnet)
{ {
const struct ipv6hdr *ip6h = ipv6_hdr(skb); const struct ipv6hdr *ip6h = ipv6_hdr(skb);
struct net_device *dev = skb->dev; struct net_device *dev = skb->dev;
...@@ -403,7 +403,7 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb) ...@@ -403,7 +403,7 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb)
dst_release(dst); dst_release(dst);
goto err; goto err;
} }
skb_dst_drop(skb); skb_scrub_packet(skb, xnet);
skb_dst_set(skb, dst); skb_dst_set(skb, dst);
err = ip6_local_out(net, skb->sk, skb); err = ip6_local_out(net, skb->sk, skb);
if (unlikely(net_xmit_eval(err))) if (unlikely(net_xmit_eval(err)))
...@@ -418,8 +418,7 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb) ...@@ -418,8 +418,7 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb)
return ret; return ret;
} }
static int ipvlan_process_outbound(struct sk_buff *skb, static int ipvlan_process_outbound(struct sk_buff *skb, bool xnet)
const struct ipvl_dev *ipvlan)
{ {
struct ethhdr *ethh = eth_hdr(skb); struct ethhdr *ethh = eth_hdr(skb);
int ret = NET_XMIT_DROP; int ret = NET_XMIT_DROP;
...@@ -443,9 +442,9 @@ static int ipvlan_process_outbound(struct sk_buff *skb, ...@@ -443,9 +442,9 @@ static int ipvlan_process_outbound(struct sk_buff *skb,
} }
if (skb->protocol == htons(ETH_P_IPV6)) if (skb->protocol == htons(ETH_P_IPV6))
ret = ipvlan_process_v6_outbound(skb); ret = ipvlan_process_v6_outbound(skb, xnet);
else if (skb->protocol == htons(ETH_P_IP)) else if (skb->protocol == htons(ETH_P_IP))
ret = ipvlan_process_v4_outbound(skb); ret = ipvlan_process_v4_outbound(skb, xnet);
else { else {
pr_warn_ratelimited("Dropped outbound packet type=%x\n", pr_warn_ratelimited("Dropped outbound packet type=%x\n",
ntohs(skb->protocol)); ntohs(skb->protocol));
...@@ -481,6 +480,7 @@ static int ipvlan_xmit_mode_l3(struct sk_buff *skb, struct net_device *dev) ...@@ -481,6 +480,7 @@ static int ipvlan_xmit_mode_l3(struct sk_buff *skb, struct net_device *dev)
void *lyr3h; void *lyr3h;
struct ipvl_addr *addr; struct ipvl_addr *addr;
int addr_type; int addr_type;
bool xnet;
lyr3h = ipvlan_get_L3_hdr(skb, &addr_type); lyr3h = ipvlan_get_L3_hdr(skb, &addr_type);
if (!lyr3h) if (!lyr3h)
...@@ -491,8 +491,9 @@ static int ipvlan_xmit_mode_l3(struct sk_buff *skb, struct net_device *dev) ...@@ -491,8 +491,9 @@ static int ipvlan_xmit_mode_l3(struct sk_buff *skb, struct net_device *dev)
return ipvlan_rcv_frame(addr, &skb, true); return ipvlan_rcv_frame(addr, &skb, true);
out: out:
xnet = !net_eq(dev_net(skb->dev), dev_net(ipvlan->phy_dev));
skb->dev = ipvlan->phy_dev; skb->dev = ipvlan->phy_dev;
return ipvlan_process_outbound(skb, ipvlan); return ipvlan_process_outbound(skb, xnet);
} }
static int ipvlan_xmit_mode_l2(struct sk_buff *skb, struct net_device *dev) static int ipvlan_xmit_mode_l2(struct sk_buff *skb, struct net_device *dev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment