On Fri, Aug 16, 2019 at 10:23:55AM +0200, Eric Dumazet wrote: > > > On 8/16/19 5:24 AM, Hangbin Liu wrote: > > Hi Eric, > > > > Thanks for the review. > > On Thu, Aug 15, 2019 at 11:16:58AM +0200, Eric Dumazet wrote: > >>> diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c > >>> index 38c02bb62e2c..c6713c7287df 100644 > >>> --- a/net/ipv4/ip_tunnel.c > >>> +++ b/net/ipv4/ip_tunnel.c > >>> @@ -597,6 +597,9 @@ void ip_md_tunnel_xmit(struct sk_buff *skb, struct > >>> net_device *dev, > >>> goto tx_error; > >>> } > >>> > >>> + if (skb_dst(skb) && !skb_dst(skb)->dev) > >>> + skb_dst(skb)->dev = rt->dst.dev; > >>> + > >> > >> > >> IMO this looks wrong. > >> This dst seems shared. > > > > If the dst is shared, it may cause some problem. Could you point me where > > the > > dst may be shared possibly? > > > > dst are inherently shared. > > This is why we have a refcount on them. > > Only when the dst has been allocated by the current thread we can make > changes on them. >
OK, I see now. Then how about fix the issue in __icmp_send and decode_session{4,6}. The fix in there is safe, as in __icmp_send() we only want to get net, dev_net(skb_in->dev) could also do the work, just as icmp6_send() does. For decode_session{4,6} the oif is also not needed in this scenario as this is called by xfrm_decode_session_reverse(), we only need the skb_iif fl4->flowi4_oif = reverse ? skb->skb_iif : oif; I also need to check more code in OVS.. diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 1510e951f451..95d803543df5 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -582,7 +582,11 @@ void __icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info, if (!rt) goto out; - net = dev_net(rt->dst.dev); + + if (skb_in->dev) + net = dev_net(skb_in->dev); + else + goto out; /* * Find the original header. It is expected to be valid, of course. diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 8ca637a72697..ec94f5795ea4 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -3269,7 +3269,7 @@ decode_session4(struct sk_buff *skb, struct flowi *fl, bool reverse) struct flowi4 *fl4 = &fl->u.ip4; int oif = 0; - if (skb_dst(skb)) + if (skb_dst(skb) && skb_dst(skb)->dev) oif = skb_dst(skb)->dev->ifindex; memset(fl4, 0, sizeof(struct flowi4)); @@ -3387,7 +3387,7 @@ decode_session6(struct sk_buff *skb, struct flowi *fl, bool reverse) nexthdr = nh[nhoff]; - if (skb_dst(skb)) + if (skb_dst(skb) && skb_dst(skb)->dev) oif = skb_dst(skb)->dev->ifindex; memset(fl6, 0, sizeof(struct flowi6)); Thanks Hangbin