.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * Linux NET3: IP/IP protocol decoder. |
---|
3 | 4 | * |
---|
.. | .. |
---|
16 | 17 | * Carlos Picoto : GRE over IP support |
---|
17 | 18 | * Alexey Kuznetsov: Reworked. Really, now it is truncated version of ipv4/ip_gre.c. |
---|
18 | 19 | * I do not want to merge them together. |
---|
19 | | - * |
---|
20 | | - * This program is free software; you can redistribute it and/or |
---|
21 | | - * modify it under the terms of the GNU General Public License |
---|
22 | | - * as published by the Free Software Foundation; either version |
---|
23 | | - * 2 of the License, or (at your option) any later version. |
---|
24 | | - * |
---|
25 | 20 | */ |
---|
26 | 21 | |
---|
27 | 22 | /* tunnel.c: an IP tunnel driver |
---|
.. | .. |
---|
140 | 135 | struct ip_tunnel *t; |
---|
141 | 136 | int err = 0; |
---|
142 | 137 | |
---|
| 138 | + t = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY, |
---|
| 139 | + iph->daddr, iph->saddr, 0); |
---|
| 140 | + if (!t) { |
---|
| 141 | + err = -ENOENT; |
---|
| 142 | + goto out; |
---|
| 143 | + } |
---|
| 144 | + |
---|
143 | 145 | switch (type) { |
---|
144 | 146 | case ICMP_DEST_UNREACH: |
---|
145 | 147 | switch (code) { |
---|
.. | .. |
---|
167 | 169 | goto out; |
---|
168 | 170 | } |
---|
169 | 171 | |
---|
170 | | - t = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY, |
---|
171 | | - iph->daddr, iph->saddr, 0); |
---|
172 | | - if (!t) { |
---|
173 | | - err = -ENOENT; |
---|
174 | | - goto out; |
---|
175 | | - } |
---|
176 | | - |
---|
177 | 172 | if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) { |
---|
178 | | - ipv4_update_pmtu(skb, net, info, t->parms.link, 0, |
---|
179 | | - iph->protocol, 0); |
---|
| 173 | + ipv4_update_pmtu(skb, net, info, t->parms.link, iph->protocol); |
---|
180 | 174 | goto out; |
---|
181 | 175 | } |
---|
182 | 176 | |
---|
183 | 177 | if (type == ICMP_REDIRECT) { |
---|
184 | | - ipv4_redirect(skb, net, t->parms.link, 0, iph->protocol, 0); |
---|
| 178 | + ipv4_redirect(skb, net, t->parms.link, iph->protocol); |
---|
185 | 179 | goto out; |
---|
186 | 180 | } |
---|
187 | 181 | |
---|
.. | .. |
---|
306 | 300 | skb_set_inner_ipproto(skb, ipproto); |
---|
307 | 301 | |
---|
308 | 302 | if (tunnel->collect_md) |
---|
309 | | - ip_md_tunnel_xmit(skb, dev, ipproto); |
---|
| 303 | + ip_md_tunnel_xmit(skb, dev, ipproto, 0); |
---|
310 | 304 | else |
---|
311 | 305 | ip_tunnel_xmit(skb, dev, tiph, ipproto); |
---|
312 | 306 | return NETDEV_TX_OK; |
---|
.. | .. |
---|
333 | 327 | } |
---|
334 | 328 | |
---|
335 | 329 | static int |
---|
336 | | -ipip_tunnel_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) |
---|
| 330 | +ipip_tunnel_ctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd) |
---|
337 | 331 | { |
---|
338 | | - int err = 0; |
---|
339 | | - struct ip_tunnel_parm p; |
---|
340 | | - |
---|
341 | | - if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) |
---|
342 | | - return -EFAULT; |
---|
343 | | - |
---|
344 | 332 | if (cmd == SIOCADDTUNNEL || cmd == SIOCCHGTUNNEL) { |
---|
345 | | - if (p.iph.version != 4 || |
---|
346 | | - !ipip_tunnel_ioctl_verify_protocol(p.iph.protocol) || |
---|
347 | | - p.iph.ihl != 5 || (p.iph.frag_off&htons(~IP_DF))) |
---|
| 333 | + if (p->iph.version != 4 || |
---|
| 334 | + !ipip_tunnel_ioctl_verify_protocol(p->iph.protocol) || |
---|
| 335 | + p->iph.ihl != 5 || (p->iph.frag_off & htons(~IP_DF))) |
---|
348 | 336 | return -EINVAL; |
---|
349 | 337 | } |
---|
350 | 338 | |
---|
351 | | - p.i_key = p.o_key = 0; |
---|
352 | | - p.i_flags = p.o_flags = 0; |
---|
353 | | - err = ip_tunnel_ioctl(dev, &p, cmd); |
---|
354 | | - if (err) |
---|
355 | | - return err; |
---|
356 | | - |
---|
357 | | - if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p))) |
---|
358 | | - return -EFAULT; |
---|
359 | | - |
---|
360 | | - return 0; |
---|
| 339 | + p->i_key = p->o_key = 0; |
---|
| 340 | + p->i_flags = p->o_flags = 0; |
---|
| 341 | + return ip_tunnel_ctl(dev, p, cmd); |
---|
361 | 342 | } |
---|
362 | 343 | |
---|
363 | 344 | static const struct net_device_ops ipip_netdev_ops = { |
---|
364 | 345 | .ndo_init = ipip_tunnel_init, |
---|
365 | 346 | .ndo_uninit = ip_tunnel_uninit, |
---|
366 | 347 | .ndo_start_xmit = ipip_tunnel_xmit, |
---|
367 | | - .ndo_do_ioctl = ipip_tunnel_ioctl, |
---|
| 348 | + .ndo_do_ioctl = ip_tunnel_ioctl, |
---|
368 | 349 | .ndo_change_mtu = ip_tunnel_change_mtu, |
---|
369 | 350 | .ndo_get_stats64 = ip_tunnel_get_stats64, |
---|
370 | 351 | .ndo_get_iflink = ip_tunnel_get_iflink, |
---|
| 352 | + .ndo_tunnel_ctl = ipip_tunnel_ctl, |
---|
371 | 353 | }; |
---|
372 | 354 | |
---|
373 | 355 | #define IPIP_FEATURES (NETIF_F_SG | \ |
---|
.. | .. |
---|
379 | 361 | static void ipip_tunnel_setup(struct net_device *dev) |
---|
380 | 362 | { |
---|
381 | 363 | dev->netdev_ops = &ipip_netdev_ops; |
---|
| 364 | + dev->header_ops = &ip_tunnel_header_ops; |
---|
382 | 365 | |
---|
383 | 366 | dev->type = ARPHRD_TUNNEL; |
---|
384 | 367 | dev->flags = IFF_NOARP; |
---|