Message ID | 20200203164659.3799-1-nicolas.dichtel@6wind.com |
---|---|
State | Awaiting Upstream |
Delegated to: | David Miller |
Headers | show |
Series | [ipsec] vti[6]: fix packet tx through bpf_redirect() in XinY cases | expand |
Hi Nicolas, Thank you for the patch! Yet something to improve: [auto build test ERROR on ipsec/master] [also build test ERROR on v5.5 next-20200203] [cannot apply to ipsec-next/master sparc-next/master] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system. BTW, we also suggest to use '--base' option to specify the base tree in git format-patch, please see https://stackoverflow.com/a/37406982] url: https://github.com/0day-ci/linux/commits/Nicolas-Dichtel/vti-6-fix-packet-tx-through-bpf_redirect-in-XinY-cases/20200204-072439 base: https://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec.git master config: x86_64-randconfig-s2-20200204 (attached as .config) compiler: gcc-4.9 (Debian 4.9.2-10+deb8u1) 4.9.2 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 If you fix the issue, kindly add following tag Reported-by: kbuild test robot <lkp@intel.com> All error/warnings (new ones prefixed by >>): net//ipv4/ip_vti.c: In function 'vti_xmit': >> net//ipv4/ip_vti.c:208:4: error: implicit declaration of function 'ip6_route_output' [-Werror=implicit-function-declaration] dst = ip6_route_output(dev_net(dev), NULL, &fl->u.ip6); ^ >> net//ipv4/ip_vti.c:208:8: warning: assignment makes pointer from integer without a cast dst = ip6_route_output(dev_net(dev), NULL, &fl->u.ip6); ^ cc1: some warnings being treated as errors vim +/ip6_route_output +208 net//ipv4/ip_vti.c 177 178 static netdev_tx_t vti_xmit(struct sk_buff *skb, struct net_device *dev, 179 struct flowi *fl) 180 { 181 struct ip_tunnel *tunnel = netdev_priv(dev); 182 struct ip_tunnel_parm *parms = &tunnel->parms; 183 struct dst_entry *dst = skb_dst(skb); 184 struct net_device *tdev; /* Device to other host */ 185 int pkt_len = skb->len; 186 int err; 187 int mtu; 188 189 if (!dst) { 190 switch (skb->protocol) { 191 case htons(ETH_P_IP): { 192 struct rtable *rt; 193 194 fl->u.ip4.flowi4_oif = dev->ifindex; 195 fl->u.ip4.flowi4_flags |= FLOWI_FLAG_ANYSRC; 196 rt = __ip_route_output_key(dev_net(dev), &fl->u.ip4); 197 if (IS_ERR(rt)) { 198 dev->stats.tx_carrier_errors++; 199 goto tx_error_icmp; 200 } 201 dst = &rt->dst; 202 skb_dst_set(skb, dst); 203 break; 204 } 205 case htons(ETH_P_IPV6): 206 fl->u.ip6.flowi6_oif = dev->ifindex; 207 fl->u.ip6.flowi6_flags |= FLOWI_FLAG_ANYSRC; > 208 dst = ip6_route_output(dev_net(dev), NULL, &fl->u.ip6); 209 if (dst->error) { 210 dst_release(dst); 211 dst = NULL; 212 dev->stats.tx_carrier_errors++; 213 goto tx_error_icmp; 214 } 215 skb_dst_set(skb, dst); 216 break; 217 default: 218 dev->stats.tx_carrier_errors++; 219 goto tx_error_icmp; 220 } 221 } 222 223 dst_hold(dst); 224 dst = xfrm_lookup(tunnel->net, dst, fl, NULL, 0); 225 if (IS_ERR(dst)) { 226 dev->stats.tx_carrier_errors++; 227 goto tx_error_icmp; 228 } 229 230 if (!vti_state_check(dst->xfrm, parms->iph.daddr, parms->iph.saddr)) { 231 dev->stats.tx_carrier_errors++; 232 dst_release(dst); 233 goto tx_error_icmp; 234 } 235 236 tdev = dst->dev; 237 238 if (tdev == dev) { 239 dst_release(dst); 240 dev->stats.collisions++; 241 goto tx_error; 242 } 243 244 mtu = dst_mtu(dst); 245 if (skb->len > mtu) { 246 skb_dst_update_pmtu_no_confirm(skb, mtu); 247 if (skb->protocol == htons(ETH_P_IP)) { 248 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, 249 htonl(mtu)); 250 } else { 251 if (mtu < IPV6_MIN_MTU) 252 mtu = IPV6_MIN_MTU; 253 254 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); 255 } 256 257 dst_release(dst); 258 goto tx_error; 259 } 260 261 skb_scrub_packet(skb, !net_eq(tunnel->net, dev_net(dev))); 262 skb_dst_set(skb, dst); 263 skb->dev = skb_dst(skb)->dev; 264 265 err = dst_output(tunnel->net, skb->sk, skb); 266 if (net_xmit_eval(err) == 0) 267 err = pkt_len; 268 iptunnel_xmit_stats(dev, err); 269 return NETDEV_TX_OK; 270 271 tx_error_icmp: 272 dst_link_failure(skb); 273 tx_error: 274 dev->stats.tx_errors++; 275 kfree_skb(skb); 276 return NETDEV_TX_OK; 277 } 278 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org Intel Corporation
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c index 37cddd18f282..a86b60c4e995 100644 --- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c @@ -187,17 +187,37 @@ static netdev_tx_t vti_xmit(struct sk_buff *skb, struct net_device *dev, int mtu; if (!dst) { - struct rtable *rt; - - fl->u.ip4.flowi4_oif = dev->ifindex; - fl->u.ip4.flowi4_flags |= FLOWI_FLAG_ANYSRC; - rt = __ip_route_output_key(dev_net(dev), &fl->u.ip4); - if (IS_ERR(rt)) { + switch (skb->protocol) { + case htons(ETH_P_IP): { + struct rtable *rt; + + fl->u.ip4.flowi4_oif = dev->ifindex; + fl->u.ip4.flowi4_flags |= FLOWI_FLAG_ANYSRC; + rt = __ip_route_output_key(dev_net(dev), &fl->u.ip4); + if (IS_ERR(rt)) { + dev->stats.tx_carrier_errors++; + goto tx_error_icmp; + } + dst = &rt->dst; + skb_dst_set(skb, dst); + break; + } + case htons(ETH_P_IPV6): + fl->u.ip6.flowi6_oif = dev->ifindex; + fl->u.ip6.flowi6_flags |= FLOWI_FLAG_ANYSRC; + dst = ip6_route_output(dev_net(dev), NULL, &fl->u.ip6); + if (dst->error) { + dst_release(dst); + dst = NULL; + dev->stats.tx_carrier_errors++; + goto tx_error_icmp; + } + skb_dst_set(skb, dst); + break; + default: dev->stats.tx_carrier_errors++; goto tx_error_icmp; } - dst = &rt->dst; - skb_dst_set(skb, dst); } dst_hold(dst); diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c index 524006aa0d78..56e642efefff 100644 --- a/net/ipv6/ip6_vti.c +++ b/net/ipv6/ip6_vti.c @@ -450,15 +450,33 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl) int mtu; if (!dst) { - fl->u.ip6.flowi6_oif = dev->ifindex; - fl->u.ip6.flowi6_flags |= FLOWI_FLAG_ANYSRC; - dst = ip6_route_output(dev_net(dev), NULL, &fl->u.ip6); - if (dst->error) { - dst_release(dst); - dst = NULL; + switch (skb->protocol) { + case htons(ETH_P_IP): { + struct rtable *rt; + + fl->u.ip4.flowi4_oif = dev->ifindex; + fl->u.ip4.flowi4_flags |= FLOWI_FLAG_ANYSRC; + rt = __ip_route_output_key(dev_net(dev), &fl->u.ip4); + if (IS_ERR(rt)) + goto tx_err_link_failure; + dst = &rt->dst; + skb_dst_set(skb, dst); + break; + } + case htons(ETH_P_IPV6): + fl->u.ip6.flowi6_oif = dev->ifindex; + fl->u.ip6.flowi6_flags |= FLOWI_FLAG_ANYSRC; + dst = ip6_route_output(dev_net(dev), NULL, &fl->u.ip6); + if (dst->error) { + dst_release(dst); + dst = NULL; + goto tx_err_link_failure; + } + skb_dst_set(skb, dst); + break; + default: goto tx_err_link_failure; } - skb_dst_set(skb, dst); } dst_hold(dst);
I forgot the 4in6/6in4 cases in my previous patch. Let's fix them. Fixes: 95224166a903 ("vti[6]: fix packet tx through bpf_redirect()") Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> --- net/ipv4/ip_vti.c | 36 ++++++++++++++++++++++++++++-------- net/ipv6/ip6_vti.c | 32 +++++++++++++++++++++++++------- 2 files changed, 53 insertions(+), 15 deletions(-)