ipv4: add a sock pointer to dst->output() path.
In the dst->output() path for ipv4, the code assumes the skb it has to
transmit is attached to an inet socket, specifically via
ip_mc_output() : The sk_mc_loop() test triggers a WARN_ON() when the
provider of the packet is an AF_PACKET socket.
The dst->output() method gets an additional 'struct sock *sk'
parameter. This needs a cascade of changes so that this parameter can
be propagated from vxlan to final consumer.
Fixes: 8f646c922d
("vxlan: keep original skb ownership")
Reported-by: lucien xin <lucien.xin@gmail.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
b0270e9101
commit
aad88724c9
@@ -132,7 +132,7 @@ static int ip6_finish_output(struct sk_buff *skb)
|
||||
return ip6_finish_output2(skb);
|
||||
}
|
||||
|
||||
int ip6_output(struct sk_buff *skb)
|
||||
int ip6_output(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
struct net_device *dev = skb_dst(skb)->dev;
|
||||
struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
|
||||
|
@@ -84,9 +84,9 @@ static void ip6_dst_ifdown(struct dst_entry *,
|
||||
static int ip6_dst_gc(struct dst_ops *ops);
|
||||
|
||||
static int ip6_pkt_discard(struct sk_buff *skb);
|
||||
static int ip6_pkt_discard_out(struct sk_buff *skb);
|
||||
static int ip6_pkt_discard_out(struct sock *sk, struct sk_buff *skb);
|
||||
static int ip6_pkt_prohibit(struct sk_buff *skb);
|
||||
static int ip6_pkt_prohibit_out(struct sk_buff *skb);
|
||||
static int ip6_pkt_prohibit_out(struct sock *sk, struct sk_buff *skb);
|
||||
static void ip6_link_failure(struct sk_buff *skb);
|
||||
static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
|
||||
struct sk_buff *skb, u32 mtu);
|
||||
@@ -290,7 +290,7 @@ static const struct rt6_info ip6_blk_hole_entry_template = {
|
||||
.obsolete = DST_OBSOLETE_FORCE_CHK,
|
||||
.error = -EINVAL,
|
||||
.input = dst_discard,
|
||||
.output = dst_discard,
|
||||
.output = dst_discard_sk,
|
||||
},
|
||||
.rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP),
|
||||
.rt6i_protocol = RTPROT_KERNEL,
|
||||
@@ -1058,7 +1058,7 @@ struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_ori
|
||||
|
||||
new->__use = 1;
|
||||
new->input = dst_discard;
|
||||
new->output = dst_discard;
|
||||
new->output = dst_discard_sk;
|
||||
|
||||
if (dst_metrics_read_only(&ort->dst))
|
||||
new->_metrics = ort->dst._metrics;
|
||||
@@ -1577,7 +1577,7 @@ int ip6_route_add(struct fib6_config *cfg)
|
||||
switch (cfg->fc_type) {
|
||||
case RTN_BLACKHOLE:
|
||||
rt->dst.error = -EINVAL;
|
||||
rt->dst.output = dst_discard;
|
||||
rt->dst.output = dst_discard_sk;
|
||||
rt->dst.input = dst_discard;
|
||||
break;
|
||||
case RTN_PROHIBIT:
|
||||
@@ -2129,7 +2129,7 @@ static int ip6_pkt_discard(struct sk_buff *skb)
|
||||
return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_INNOROUTES);
|
||||
}
|
||||
|
||||
static int ip6_pkt_discard_out(struct sk_buff *skb)
|
||||
static int ip6_pkt_discard_out(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
skb->dev = skb_dst(skb)->dev;
|
||||
return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_OUTNOROUTES);
|
||||
@@ -2140,7 +2140,7 @@ static int ip6_pkt_prohibit(struct sk_buff *skb)
|
||||
return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_INNOROUTES);
|
||||
}
|
||||
|
||||
static int ip6_pkt_prohibit_out(struct sk_buff *skb)
|
||||
static int ip6_pkt_prohibit_out(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
skb->dev = skb_dst(skb)->dev;
|
||||
return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES);
|
||||
|
@@ -974,8 +974,9 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = iptunnel_xmit(rt, skb, fl4.saddr, fl4.daddr, IPPROTO_IPV6, tos,
|
||||
ttl, df, !net_eq(tunnel->net, dev_net(dev)));
|
||||
err = iptunnel_xmit(skb->sk, rt, skb, fl4.saddr, fl4.daddr,
|
||||
IPPROTO_IPV6, tos, ttl, df,
|
||||
!net_eq(tunnel->net, dev_net(dev)));
|
||||
iptunnel_xmit_stats(err, &dev->stats, dev->tstats);
|
||||
return NETDEV_TX_OK;
|
||||
|
||||
|
@@ -163,7 +163,7 @@ static int __xfrm6_output(struct sk_buff *skb)
|
||||
return x->outer_mode->afinfo->output_finish(skb);
|
||||
}
|
||||
|
||||
int xfrm6_output(struct sk_buff *skb)
|
||||
int xfrm6_output(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
return NF_HOOK(NFPROTO_IPV6, NF_INET_POST_ROUTING, skb, NULL,
|
||||
skb_dst(skb)->dev, __xfrm6_output);
|
||||
|
Reference in New Issue
Block a user