diff options
Diffstat (limited to 'drivers/net/tun.c')
| -rw-r--r-- | drivers/net/tun.c | 25 |
1 files changed, 9 insertions, 16 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 8c8dc16839a7..10f9e4021b5a 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
| @@ -65,7 +65,6 @@ | |||
| 65 | #include <linux/nsproxy.h> | 65 | #include <linux/nsproxy.h> |
| 66 | #include <linux/virtio_net.h> | 66 | #include <linux/virtio_net.h> |
| 67 | #include <linux/rcupdate.h> | 67 | #include <linux/rcupdate.h> |
| 68 | #include <net/ipv6.h> | ||
| 69 | #include <net/net_namespace.h> | 68 | #include <net/net_namespace.h> |
| 70 | #include <net/netns/generic.h> | 69 | #include <net/netns/generic.h> |
| 71 | #include <net/rtnetlink.h> | 70 | #include <net/rtnetlink.h> |
| @@ -187,7 +186,7 @@ struct tun_struct { | |||
| 187 | struct net_device *dev; | 186 | struct net_device *dev; |
| 188 | netdev_features_t set_features; | 187 | netdev_features_t set_features; |
| 189 | #define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \ | 188 | #define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \ |
| 190 | NETIF_F_TSO6) | 189 | NETIF_F_TSO6|NETIF_F_UFO) |
| 191 | 190 | ||
| 192 | int vnet_hdr_sz; | 191 | int vnet_hdr_sz; |
| 193 | int sndbuf; | 192 | int sndbuf; |
| @@ -1167,8 +1166,6 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, | |||
| 1167 | break; | 1166 | break; |
| 1168 | } | 1167 | } |
| 1169 | 1168 | ||
| 1170 | skb_reset_network_header(skb); | ||
| 1171 | |||
| 1172 | if (gso.gso_type != VIRTIO_NET_HDR_GSO_NONE) { | 1169 | if (gso.gso_type != VIRTIO_NET_HDR_GSO_NONE) { |
| 1173 | pr_debug("GSO!\n"); | 1170 | pr_debug("GSO!\n"); |
| 1174 | switch (gso.gso_type & ~VIRTIO_NET_HDR_GSO_ECN) { | 1171 | switch (gso.gso_type & ~VIRTIO_NET_HDR_GSO_ECN) { |
| @@ -1179,20 +1176,8 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, | |||
| 1179 | skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6; | 1176 | skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6; |
| 1180 | break; | 1177 | break; |
| 1181 | case VIRTIO_NET_HDR_GSO_UDP: | 1178 | case VIRTIO_NET_HDR_GSO_UDP: |
| 1182 | { | ||
| 1183 | static bool warned; | ||
| 1184 | |||
| 1185 | if (!warned) { | ||
| 1186 | warned = true; | ||
| 1187 | netdev_warn(tun->dev, | ||
| 1188 | "%s: using disabled UFO feature; please fix this program\n", | ||
| 1189 | current->comm); | ||
| 1190 | } | ||
| 1191 | skb_shinfo(skb)->gso_type = SKB_GSO_UDP; | 1179 | skb_shinfo(skb)->gso_type = SKB_GSO_UDP; |
| 1192 | if (skb->protocol == htons(ETH_P_IPV6)) | ||
| 1193 | ipv6_proxy_select_ident(skb); | ||
| 1194 | break; | 1180 | break; |
| 1195 | } | ||
| 1196 | default: | 1181 | default: |
| 1197 | tun->dev->stats.rx_frame_errors++; | 1182 | tun->dev->stats.rx_frame_errors++; |
| 1198 | kfree_skb(skb); | 1183 | kfree_skb(skb); |
| @@ -1221,6 +1206,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, | |||
| 1221 | skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG; | 1206 | skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG; |
| 1222 | } | 1207 | } |
| 1223 | 1208 | ||
| 1209 | skb_reset_network_header(skb); | ||
| 1224 | skb_probe_transport_header(skb, 0); | 1210 | skb_probe_transport_header(skb, 0); |
| 1225 | 1211 | ||
| 1226 | rxhash = skb_get_hash(skb); | 1212 | rxhash = skb_get_hash(skb); |
| @@ -1298,6 +1284,8 @@ static ssize_t tun_put_user(struct tun_struct *tun, | |||
| 1298 | gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV4; | 1284 | gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV4; |
| 1299 | else if (sinfo->gso_type & SKB_GSO_TCPV6) | 1285 | else if (sinfo->gso_type & SKB_GSO_TCPV6) |
| 1300 | gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV6; | 1286 | gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV6; |
| 1287 | else if (sinfo->gso_type & SKB_GSO_UDP) | ||
| 1288 | gso.gso_type = VIRTIO_NET_HDR_GSO_UDP; | ||
| 1301 | else { | 1289 | else { |
| 1302 | pr_err("unexpected GSO type: " | 1290 | pr_err("unexpected GSO type: " |
| 1303 | "0x%x, gso_size %d, hdr_len %d\n", | 1291 | "0x%x, gso_size %d, hdr_len %d\n", |
| @@ -1746,6 +1734,11 @@ static int set_offload(struct tun_struct *tun, unsigned long arg) | |||
| 1746 | features |= NETIF_F_TSO6; | 1734 | features |= NETIF_F_TSO6; |
| 1747 | arg &= ~(TUN_F_TSO4|TUN_F_TSO6); | 1735 | arg &= ~(TUN_F_TSO4|TUN_F_TSO6); |
| 1748 | } | 1736 | } |
| 1737 | |||
| 1738 | if (arg & TUN_F_UFO) { | ||
| 1739 | features |= NETIF_F_UFO; | ||
| 1740 | arg &= ~TUN_F_UFO; | ||
| 1741 | } | ||
| 1749 | } | 1742 | } |
| 1750 | 1743 | ||
| 1751 | /* This gives the user a way to test for new features in future by | 1744 | /* This gives the user a way to test for new features in future by |
