diff options
Diffstat (limited to 'drivers/net/tun.c')
-rw-r--r-- | drivers/net/tun.c | 25 |
1 files changed, 16 insertions, 9 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 186ce541c657..7302398f0b1f 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -65,6 +65,7 @@ | |||
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> | ||
68 | #include <net/net_namespace.h> | 69 | #include <net/net_namespace.h> |
69 | #include <net/netns/generic.h> | 70 | #include <net/netns/generic.h> |
70 | #include <net/rtnetlink.h> | 71 | #include <net/rtnetlink.h> |
@@ -174,7 +175,7 @@ struct tun_struct { | |||
174 | struct net_device *dev; | 175 | struct net_device *dev; |
175 | netdev_features_t set_features; | 176 | netdev_features_t set_features; |
176 | #define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \ | 177 | #define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \ |
177 | NETIF_F_TSO6|NETIF_F_UFO) | 178 | NETIF_F_TSO6) |
178 | 179 | ||
179 | int vnet_hdr_sz; | 180 | int vnet_hdr_sz; |
180 | int sndbuf; | 181 | int sndbuf; |
@@ -1139,6 +1140,8 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, | |||
1139 | break; | 1140 | break; |
1140 | } | 1141 | } |
1141 | 1142 | ||
1143 | skb_reset_network_header(skb); | ||
1144 | |||
1142 | if (gso.gso_type != VIRTIO_NET_HDR_GSO_NONE) { | 1145 | if (gso.gso_type != VIRTIO_NET_HDR_GSO_NONE) { |
1143 | pr_debug("GSO!\n"); | 1146 | pr_debug("GSO!\n"); |
1144 | switch (gso.gso_type & ~VIRTIO_NET_HDR_GSO_ECN) { | 1147 | switch (gso.gso_type & ~VIRTIO_NET_HDR_GSO_ECN) { |
@@ -1149,8 +1152,20 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, | |||
1149 | skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6; | 1152 | skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6; |
1150 | break; | 1153 | break; |
1151 | case VIRTIO_NET_HDR_GSO_UDP: | 1154 | case VIRTIO_NET_HDR_GSO_UDP: |
1155 | { | ||
1156 | static bool warned; | ||
1157 | |||
1158 | if (!warned) { | ||
1159 | warned = true; | ||
1160 | netdev_warn(tun->dev, | ||
1161 | "%s: using disabled UFO feature; please fix this program\n", | ||
1162 | current->comm); | ||
1163 | } | ||
1152 | skb_shinfo(skb)->gso_type = SKB_GSO_UDP; | 1164 | skb_shinfo(skb)->gso_type = SKB_GSO_UDP; |
1165 | if (skb->protocol == htons(ETH_P_IPV6)) | ||
1166 | ipv6_proxy_select_ident(skb); | ||
1153 | break; | 1167 | break; |
1168 | } | ||
1154 | default: | 1169 | default: |
1155 | tun->dev->stats.rx_frame_errors++; | 1170 | tun->dev->stats.rx_frame_errors++; |
1156 | kfree_skb(skb); | 1171 | kfree_skb(skb); |
@@ -1179,7 +1194,6 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, | |||
1179 | skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG; | 1194 | skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG; |
1180 | } | 1195 | } |
1181 | 1196 | ||
1182 | skb_reset_network_header(skb); | ||
1183 | skb_probe_transport_header(skb, 0); | 1197 | skb_probe_transport_header(skb, 0); |
1184 | 1198 | ||
1185 | rxhash = skb_get_hash(skb); | 1199 | rxhash = skb_get_hash(skb); |
@@ -1251,8 +1265,6 @@ static ssize_t tun_put_user(struct tun_struct *tun, | |||
1251 | gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV4; | 1265 | gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV4; |
1252 | else if (sinfo->gso_type & SKB_GSO_TCPV6) | 1266 | else if (sinfo->gso_type & SKB_GSO_TCPV6) |
1253 | gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV6; | 1267 | gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV6; |
1254 | else if (sinfo->gso_type & SKB_GSO_UDP) | ||
1255 | gso.gso_type = VIRTIO_NET_HDR_GSO_UDP; | ||
1256 | else { | 1268 | else { |
1257 | pr_err("unexpected GSO type: " | 1269 | pr_err("unexpected GSO type: " |
1258 | "0x%x, gso_size %d, hdr_len %d\n", | 1270 | "0x%x, gso_size %d, hdr_len %d\n", |
@@ -1762,11 +1774,6 @@ static int set_offload(struct tun_struct *tun, unsigned long arg) | |||
1762 | features |= NETIF_F_TSO6; | 1774 | features |= NETIF_F_TSO6; |
1763 | arg &= ~(TUN_F_TSO4|TUN_F_TSO6); | 1775 | arg &= ~(TUN_F_TSO4|TUN_F_TSO6); |
1764 | } | 1776 | } |
1765 | |||
1766 | if (arg & TUN_F_UFO) { | ||
1767 | features |= NETIF_F_UFO; | ||
1768 | arg &= ~TUN_F_UFO; | ||
1769 | } | ||
1770 | } | 1777 | } |
1771 | 1778 | ||
1772 | /* This gives the user a way to test for new features in future by | 1779 | /* This gives the user a way to test for new features in future by |