diff options
Diffstat (limited to 'drivers/net/xen-netback/netback.c')
-rw-r--r-- | drivers/net/xen-netback/netback.c | 379 |
1 files changed, 302 insertions, 77 deletions
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index f3e591c611de..e884ee1fe7ed 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/udp.h> | 39 | #include <linux/udp.h> |
40 | 40 | ||
41 | #include <net/tcp.h> | 41 | #include <net/tcp.h> |
42 | #include <net/ip6_checksum.h> | ||
42 | 43 | ||
43 | #include <xen/xen.h> | 44 | #include <xen/xen.h> |
44 | #include <xen/events.h> | 45 | #include <xen/events.h> |
@@ -109,15 +110,12 @@ static inline unsigned long idx_to_kaddr(struct xenvif *vif, | |||
109 | return (unsigned long)pfn_to_kaddr(idx_to_pfn(vif, idx)); | 110 | return (unsigned long)pfn_to_kaddr(idx_to_pfn(vif, idx)); |
110 | } | 111 | } |
111 | 112 | ||
112 | /* | 113 | /* This is a miniumum size for the linear area to avoid lots of |
113 | * This is the amount of packet we copy rather than map, so that the | 114 | * calls to __pskb_pull_tail() as we set up checksum offsets. The |
114 | * guest can't fiddle with the contents of the headers while we do | 115 | * value 128 was chosen as it covers all IPv4 and most likely |
115 | * packet processing on them (netfilter, routing, etc). | 116 | * IPv6 headers. |
116 | */ | 117 | */ |
117 | #define PKT_PROT_LEN (ETH_HLEN + \ | 118 | #define PKT_PROT_LEN 128 |
118 | VLAN_HLEN + \ | ||
119 | sizeof(struct iphdr) + MAX_IPOPTLEN + \ | ||
120 | sizeof(struct tcphdr) + MAX_TCP_OPTION_SPACE) | ||
121 | 119 | ||
122 | static u16 frag_get_pending_idx(skb_frag_t *frag) | 120 | static u16 frag_get_pending_idx(skb_frag_t *frag) |
123 | { | 121 | { |
@@ -145,7 +143,7 @@ static int max_required_rx_slots(struct xenvif *vif) | |||
145 | int max = DIV_ROUND_UP(vif->dev->mtu, PAGE_SIZE); | 143 | int max = DIV_ROUND_UP(vif->dev->mtu, PAGE_SIZE); |
146 | 144 | ||
147 | /* XXX FIXME: RX path dependent on MAX_SKB_FRAGS */ | 145 | /* XXX FIXME: RX path dependent on MAX_SKB_FRAGS */ |
148 | if (vif->can_sg || vif->gso || vif->gso_prefix) | 146 | if (vif->can_sg || vif->gso_mask || vif->gso_prefix_mask) |
149 | max += MAX_SKB_FRAGS + 1; /* extra_info + frags */ | 147 | max += MAX_SKB_FRAGS + 1; /* extra_info + frags */ |
150 | 148 | ||
151 | return max; | 149 | return max; |
@@ -317,6 +315,7 @@ static struct xenvif_rx_meta *get_next_rx_buffer(struct xenvif *vif, | |||
317 | req = RING_GET_REQUEST(&vif->rx, vif->rx.req_cons++); | 315 | req = RING_GET_REQUEST(&vif->rx, vif->rx.req_cons++); |
318 | 316 | ||
319 | meta = npo->meta + npo->meta_prod++; | 317 | meta = npo->meta + npo->meta_prod++; |
318 | meta->gso_type = XEN_NETIF_GSO_TYPE_NONE; | ||
320 | meta->gso_size = 0; | 319 | meta->gso_size = 0; |
321 | meta->size = 0; | 320 | meta->size = 0; |
322 | meta->id = req->id; | 321 | meta->id = req->id; |
@@ -339,6 +338,7 @@ static void xenvif_gop_frag_copy(struct xenvif *vif, struct sk_buff *skb, | |||
339 | struct gnttab_copy *copy_gop; | 338 | struct gnttab_copy *copy_gop; |
340 | struct xenvif_rx_meta *meta; | 339 | struct xenvif_rx_meta *meta; |
341 | unsigned long bytes; | 340 | unsigned long bytes; |
341 | int gso_type; | ||
342 | 342 | ||
343 | /* Data must not cross a page boundary. */ | 343 | /* Data must not cross a page boundary. */ |
344 | BUG_ON(size + offset > PAGE_SIZE<<compound_order(page)); | 344 | BUG_ON(size + offset > PAGE_SIZE<<compound_order(page)); |
@@ -397,7 +397,14 @@ static void xenvif_gop_frag_copy(struct xenvif *vif, struct sk_buff *skb, | |||
397 | } | 397 | } |
398 | 398 | ||
399 | /* Leave a gap for the GSO descriptor. */ | 399 | /* Leave a gap for the GSO descriptor. */ |
400 | if (*head && skb_shinfo(skb)->gso_size && !vif->gso_prefix) | 400 | if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4) |
401 | gso_type = XEN_NETIF_GSO_TYPE_TCPV4; | ||
402 | else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) | ||
403 | gso_type = XEN_NETIF_GSO_TYPE_TCPV6; | ||
404 | else | ||
405 | gso_type = XEN_NETIF_GSO_TYPE_NONE; | ||
406 | |||
407 | if (*head && ((1 << gso_type) & vif->gso_mask)) | ||
401 | vif->rx.req_cons++; | 408 | vif->rx.req_cons++; |
402 | 409 | ||
403 | *head = 0; /* There must be something in this buffer now. */ | 410 | *head = 0; /* There must be something in this buffer now. */ |
@@ -428,14 +435,28 @@ static int xenvif_gop_skb(struct sk_buff *skb, | |||
428 | unsigned char *data; | 435 | unsigned char *data; |
429 | int head = 1; | 436 | int head = 1; |
430 | int old_meta_prod; | 437 | int old_meta_prod; |
438 | int gso_type; | ||
439 | int gso_size; | ||
431 | 440 | ||
432 | old_meta_prod = npo->meta_prod; | 441 | old_meta_prod = npo->meta_prod; |
433 | 442 | ||
443 | if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4) { | ||
444 | gso_type = XEN_NETIF_GSO_TYPE_TCPV4; | ||
445 | gso_size = skb_shinfo(skb)->gso_size; | ||
446 | } else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) { | ||
447 | gso_type = XEN_NETIF_GSO_TYPE_TCPV6; | ||
448 | gso_size = skb_shinfo(skb)->gso_size; | ||
449 | } else { | ||
450 | gso_type = XEN_NETIF_GSO_TYPE_NONE; | ||
451 | gso_size = 0; | ||
452 | } | ||
453 | |||
434 | /* Set up a GSO prefix descriptor, if necessary */ | 454 | /* Set up a GSO prefix descriptor, if necessary */ |
435 | if (skb_shinfo(skb)->gso_size && vif->gso_prefix) { | 455 | if ((1 << gso_type) & vif->gso_prefix_mask) { |
436 | req = RING_GET_REQUEST(&vif->rx, vif->rx.req_cons++); | 456 | req = RING_GET_REQUEST(&vif->rx, vif->rx.req_cons++); |
437 | meta = npo->meta + npo->meta_prod++; | 457 | meta = npo->meta + npo->meta_prod++; |
438 | meta->gso_size = skb_shinfo(skb)->gso_size; | 458 | meta->gso_type = gso_type; |
459 | meta->gso_size = gso_size; | ||
439 | meta->size = 0; | 460 | meta->size = 0; |
440 | meta->id = req->id; | 461 | meta->id = req->id; |
441 | } | 462 | } |
@@ -443,10 +464,13 @@ static int xenvif_gop_skb(struct sk_buff *skb, | |||
443 | req = RING_GET_REQUEST(&vif->rx, vif->rx.req_cons++); | 464 | req = RING_GET_REQUEST(&vif->rx, vif->rx.req_cons++); |
444 | meta = npo->meta + npo->meta_prod++; | 465 | meta = npo->meta + npo->meta_prod++; |
445 | 466 | ||
446 | if (!vif->gso_prefix) | 467 | if ((1 << gso_type) & vif->gso_mask) { |
447 | meta->gso_size = skb_shinfo(skb)->gso_size; | 468 | meta->gso_type = gso_type; |
448 | else | 469 | meta->gso_size = gso_size; |
470 | } else { | ||
471 | meta->gso_type = XEN_NETIF_GSO_TYPE_NONE; | ||
449 | meta->gso_size = 0; | 472 | meta->gso_size = 0; |
473 | } | ||
450 | 474 | ||
451 | meta->size = 0; | 475 | meta->size = 0; |
452 | meta->id = req->id; | 476 | meta->id = req->id; |
@@ -592,7 +616,8 @@ void xenvif_rx_action(struct xenvif *vif) | |||
592 | 616 | ||
593 | vif = netdev_priv(skb->dev); | 617 | vif = netdev_priv(skb->dev); |
594 | 618 | ||
595 | if (vif->meta[npo.meta_cons].gso_size && vif->gso_prefix) { | 619 | if ((1 << vif->meta[npo.meta_cons].gso_type) & |
620 | vif->gso_prefix_mask) { | ||
596 | resp = RING_GET_RESPONSE(&vif->rx, | 621 | resp = RING_GET_RESPONSE(&vif->rx, |
597 | vif->rx.rsp_prod_pvt++); | 622 | vif->rx.rsp_prod_pvt++); |
598 | 623 | ||
@@ -629,7 +654,8 @@ void xenvif_rx_action(struct xenvif *vif) | |||
629 | vif->meta[npo.meta_cons].size, | 654 | vif->meta[npo.meta_cons].size, |
630 | flags); | 655 | flags); |
631 | 656 | ||
632 | if (vif->meta[npo.meta_cons].gso_size && !vif->gso_prefix) { | 657 | if ((1 << vif->meta[npo.meta_cons].gso_type) & |
658 | vif->gso_mask) { | ||
633 | struct xen_netif_extra_info *gso = | 659 | struct xen_netif_extra_info *gso = |
634 | (struct xen_netif_extra_info *) | 660 | (struct xen_netif_extra_info *) |
635 | RING_GET_RESPONSE(&vif->rx, | 661 | RING_GET_RESPONSE(&vif->rx, |
@@ -637,8 +663,8 @@ void xenvif_rx_action(struct xenvif *vif) | |||
637 | 663 | ||
638 | resp->flags |= XEN_NETRXF_extra_info; | 664 | resp->flags |= XEN_NETRXF_extra_info; |
639 | 665 | ||
666 | gso->u.gso.type = vif->meta[npo.meta_cons].gso_type; | ||
640 | gso->u.gso.size = vif->meta[npo.meta_cons].gso_size; | 667 | gso->u.gso.size = vif->meta[npo.meta_cons].gso_size; |
641 | gso->u.gso.type = XEN_NETIF_GSO_TYPE_TCPV4; | ||
642 | gso->u.gso.pad = 0; | 668 | gso->u.gso.pad = 0; |
643 | gso->u.gso.features = 0; | 669 | gso->u.gso.features = 0; |
644 | 670 | ||
@@ -1101,15 +1127,20 @@ static int xenvif_set_skb_gso(struct xenvif *vif, | |||
1101 | return -EINVAL; | 1127 | return -EINVAL; |
1102 | } | 1128 | } |
1103 | 1129 | ||
1104 | /* Currently only TCPv4 S.O. is supported. */ | 1130 | switch (gso->u.gso.type) { |
1105 | if (gso->u.gso.type != XEN_NETIF_GSO_TYPE_TCPV4) { | 1131 | case XEN_NETIF_GSO_TYPE_TCPV4: |
1132 | skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4; | ||
1133 | break; | ||
1134 | case XEN_NETIF_GSO_TYPE_TCPV6: | ||
1135 | skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6; | ||
1136 | break; | ||
1137 | default: | ||
1106 | netdev_err(vif->dev, "Bad GSO type %d.\n", gso->u.gso.type); | 1138 | netdev_err(vif->dev, "Bad GSO type %d.\n", gso->u.gso.type); |
1107 | xenvif_fatal_tx_err(vif); | 1139 | xenvif_fatal_tx_err(vif); |
1108 | return -EINVAL; | 1140 | return -EINVAL; |
1109 | } | 1141 | } |
1110 | 1142 | ||
1111 | skb_shinfo(skb)->gso_size = gso->u.gso.size; | 1143 | skb_shinfo(skb)->gso_size = gso->u.gso.size; |
1112 | skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4; | ||
1113 | 1144 | ||
1114 | /* Header must be checked, and gso_segs computed. */ | 1145 | /* Header must be checked, and gso_segs computed. */ |
1115 | skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY; | 1146 | skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY; |
@@ -1118,62 +1149,233 @@ static int xenvif_set_skb_gso(struct xenvif *vif, | |||
1118 | return 0; | 1149 | return 0; |
1119 | } | 1150 | } |
1120 | 1151 | ||
1121 | static int checksum_setup(struct xenvif *vif, struct sk_buff *skb) | 1152 | static inline int maybe_pull_tail(struct sk_buff *skb, unsigned int len, |
1153 | unsigned int max) | ||
1122 | { | 1154 | { |
1123 | struct iphdr *iph; | 1155 | if (skb_headlen(skb) >= len) |
1124 | int err = -EPROTO; | 1156 | return 0; |
1125 | int recalculate_partial_csum = 0; | ||
1126 | 1157 | ||
1127 | /* | 1158 | /* If we need to pullup then pullup to the max, so we |
1128 | * A GSO SKB must be CHECKSUM_PARTIAL. However some buggy | 1159 | * won't need to do it again. |
1129 | * peers can fail to set NETRXF_csum_blank when sending a GSO | ||
1130 | * frame. In this case force the SKB to CHECKSUM_PARTIAL and | ||
1131 | * recalculate the partial checksum. | ||
1132 | */ | 1160 | */ |
1133 | if (skb->ip_summed != CHECKSUM_PARTIAL && skb_is_gso(skb)) { | 1161 | if (max > skb->len) |
1134 | vif->rx_gso_checksum_fixup++; | 1162 | max = skb->len; |
1135 | skb->ip_summed = CHECKSUM_PARTIAL; | ||
1136 | recalculate_partial_csum = 1; | ||
1137 | } | ||
1138 | 1163 | ||
1139 | /* A non-CHECKSUM_PARTIAL SKB does not require setup. */ | 1164 | if (__pskb_pull_tail(skb, max - skb_headlen(skb)) == NULL) |
1140 | if (skb->ip_summed != CHECKSUM_PARTIAL) | 1165 | return -ENOMEM; |
1141 | return 0; | 1166 | |
1167 | if (skb_headlen(skb) < len) | ||
1168 | return -EPROTO; | ||
1169 | |||
1170 | return 0; | ||
1171 | } | ||
1142 | 1172 | ||
1143 | if (skb->protocol != htons(ETH_P_IP)) | 1173 | /* This value should be large enough to cover a tagged ethernet header plus |
1174 | * maximally sized IP and TCP or UDP headers. | ||
1175 | */ | ||
1176 | #define MAX_IP_HDR_LEN 128 | ||
1177 | |||
1178 | static int checksum_setup_ip(struct xenvif *vif, struct sk_buff *skb, | ||
1179 | int recalculate_partial_csum) | ||
1180 | { | ||
1181 | unsigned int off; | ||
1182 | bool fragment; | ||
1183 | int err; | ||
1184 | |||
1185 | fragment = false; | ||
1186 | |||
1187 | err = maybe_pull_tail(skb, | ||
1188 | sizeof(struct iphdr), | ||
1189 | MAX_IP_HDR_LEN); | ||
1190 | if (err < 0) | ||
1144 | goto out; | 1191 | goto out; |
1145 | 1192 | ||
1146 | iph = (void *)skb->data; | 1193 | if (ip_hdr(skb)->frag_off & htons(IP_OFFSET | IP_MF)) |
1147 | switch (iph->protocol) { | 1194 | fragment = true; |
1195 | |||
1196 | off = ip_hdrlen(skb); | ||
1197 | |||
1198 | err = -EPROTO; | ||
1199 | |||
1200 | switch (ip_hdr(skb)->protocol) { | ||
1148 | case IPPROTO_TCP: | 1201 | case IPPROTO_TCP: |
1149 | if (!skb_partial_csum_set(skb, 4 * iph->ihl, | 1202 | err = maybe_pull_tail(skb, |
1203 | off + sizeof(struct tcphdr), | ||
1204 | MAX_IP_HDR_LEN); | ||
1205 | if (err < 0) | ||
1206 | goto out; | ||
1207 | |||
1208 | if (!skb_partial_csum_set(skb, off, | ||
1150 | offsetof(struct tcphdr, check))) | 1209 | offsetof(struct tcphdr, check))) |
1151 | goto out; | 1210 | goto out; |
1152 | 1211 | ||
1153 | if (recalculate_partial_csum) { | 1212 | if (recalculate_partial_csum) |
1154 | struct tcphdr *tcph = tcp_hdr(skb); | 1213 | tcp_hdr(skb)->check = |
1155 | tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, | 1214 | ~csum_tcpudp_magic(ip_hdr(skb)->saddr, |
1156 | skb->len - iph->ihl*4, | 1215 | ip_hdr(skb)->daddr, |
1157 | IPPROTO_TCP, 0); | 1216 | skb->len - off, |
1158 | } | 1217 | IPPROTO_TCP, 0); |
1159 | break; | 1218 | break; |
1160 | case IPPROTO_UDP: | 1219 | case IPPROTO_UDP: |
1161 | if (!skb_partial_csum_set(skb, 4 * iph->ihl, | 1220 | err = maybe_pull_tail(skb, |
1221 | off + sizeof(struct udphdr), | ||
1222 | MAX_IP_HDR_LEN); | ||
1223 | if (err < 0) | ||
1224 | goto out; | ||
1225 | |||
1226 | if (!skb_partial_csum_set(skb, off, | ||
1162 | offsetof(struct udphdr, check))) | 1227 | offsetof(struct udphdr, check))) |
1163 | goto out; | 1228 | goto out; |
1164 | 1229 | ||
1165 | if (recalculate_partial_csum) { | 1230 | if (recalculate_partial_csum) |
1166 | struct udphdr *udph = udp_hdr(skb); | 1231 | udp_hdr(skb)->check = |
1167 | udph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, | 1232 | ~csum_tcpudp_magic(ip_hdr(skb)->saddr, |
1168 | skb->len - iph->ihl*4, | 1233 | ip_hdr(skb)->daddr, |
1169 | IPPROTO_UDP, 0); | 1234 | skb->len - off, |
1235 | IPPROTO_UDP, 0); | ||
1236 | break; | ||
1237 | default: | ||
1238 | goto out; | ||
1239 | } | ||
1240 | |||
1241 | err = 0; | ||
1242 | |||
1243 | out: | ||
1244 | return err; | ||
1245 | } | ||
1246 | |||
1247 | /* This value should be large enough to cover a tagged ethernet header plus | ||
1248 | * an IPv6 header, all options, and a maximal TCP or UDP header. | ||
1249 | */ | ||
1250 | #define MAX_IPV6_HDR_LEN 256 | ||
1251 | |||
1252 | #define OPT_HDR(type, skb, off) \ | ||
1253 | (type *)(skb_network_header(skb) + (off)) | ||
1254 | |||
1255 | static int checksum_setup_ipv6(struct xenvif *vif, struct sk_buff *skb, | ||
1256 | int recalculate_partial_csum) | ||
1257 | { | ||
1258 | int err; | ||
1259 | u8 nexthdr; | ||
1260 | unsigned int off; | ||
1261 | unsigned int len; | ||
1262 | bool fragment; | ||
1263 | bool done; | ||
1264 | |||
1265 | fragment = false; | ||
1266 | done = false; | ||
1267 | |||
1268 | off = sizeof(struct ipv6hdr); | ||
1269 | |||
1270 | err = maybe_pull_tail(skb, off, MAX_IPV6_HDR_LEN); | ||
1271 | if (err < 0) | ||
1272 | goto out; | ||
1273 | |||
1274 | nexthdr = ipv6_hdr(skb)->nexthdr; | ||
1275 | |||
1276 | len = sizeof(struct ipv6hdr) + ntohs(ipv6_hdr(skb)->payload_len); | ||
1277 | while (off <= len && !done) { | ||
1278 | switch (nexthdr) { | ||
1279 | case IPPROTO_DSTOPTS: | ||
1280 | case IPPROTO_HOPOPTS: | ||
1281 | case IPPROTO_ROUTING: { | ||
1282 | struct ipv6_opt_hdr *hp; | ||
1283 | |||
1284 | err = maybe_pull_tail(skb, | ||
1285 | off + | ||
1286 | sizeof(struct ipv6_opt_hdr), | ||
1287 | MAX_IPV6_HDR_LEN); | ||
1288 | if (err < 0) | ||
1289 | goto out; | ||
1290 | |||
1291 | hp = OPT_HDR(struct ipv6_opt_hdr, skb, off); | ||
1292 | nexthdr = hp->nexthdr; | ||
1293 | off += ipv6_optlen(hp); | ||
1294 | break; | ||
1295 | } | ||
1296 | case IPPROTO_AH: { | ||
1297 | struct ip_auth_hdr *hp; | ||
1298 | |||
1299 | err = maybe_pull_tail(skb, | ||
1300 | off + | ||
1301 | sizeof(struct ip_auth_hdr), | ||
1302 | MAX_IPV6_HDR_LEN); | ||
1303 | if (err < 0) | ||
1304 | goto out; | ||
1305 | |||
1306 | hp = OPT_HDR(struct ip_auth_hdr, skb, off); | ||
1307 | nexthdr = hp->nexthdr; | ||
1308 | off += ipv6_authlen(hp); | ||
1309 | break; | ||
1310 | } | ||
1311 | case IPPROTO_FRAGMENT: { | ||
1312 | struct frag_hdr *hp; | ||
1313 | |||
1314 | err = maybe_pull_tail(skb, | ||
1315 | off + | ||
1316 | sizeof(struct frag_hdr), | ||
1317 | MAX_IPV6_HDR_LEN); | ||
1318 | if (err < 0) | ||
1319 | goto out; | ||
1320 | |||
1321 | hp = OPT_HDR(struct frag_hdr, skb, off); | ||
1322 | |||
1323 | if (hp->frag_off & htons(IP6_OFFSET | IP6_MF)) | ||
1324 | fragment = true; | ||
1325 | |||
1326 | nexthdr = hp->nexthdr; | ||
1327 | off += sizeof(struct frag_hdr); | ||
1328 | break; | ||
1329 | } | ||
1330 | default: | ||
1331 | done = true; | ||
1332 | break; | ||
1170 | } | 1333 | } |
1334 | } | ||
1335 | |||
1336 | err = -EPROTO; | ||
1337 | |||
1338 | if (!done || fragment) | ||
1339 | goto out; | ||
1340 | |||
1341 | switch (nexthdr) { | ||
1342 | case IPPROTO_TCP: | ||
1343 | err = maybe_pull_tail(skb, | ||
1344 | off + sizeof(struct tcphdr), | ||
1345 | MAX_IPV6_HDR_LEN); | ||
1346 | if (err < 0) | ||
1347 | goto out; | ||
1348 | |||
1349 | if (!skb_partial_csum_set(skb, off, | ||
1350 | offsetof(struct tcphdr, check))) | ||
1351 | goto out; | ||
1352 | |||
1353 | if (recalculate_partial_csum) | ||
1354 | tcp_hdr(skb)->check = | ||
1355 | ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, | ||
1356 | &ipv6_hdr(skb)->daddr, | ||
1357 | skb->len - off, | ||
1358 | IPPROTO_TCP, 0); | ||
1359 | break; | ||
1360 | case IPPROTO_UDP: | ||
1361 | err = maybe_pull_tail(skb, | ||
1362 | off + sizeof(struct udphdr), | ||
1363 | MAX_IPV6_HDR_LEN); | ||
1364 | if (err < 0) | ||
1365 | goto out; | ||
1366 | |||
1367 | if (!skb_partial_csum_set(skb, off, | ||
1368 | offsetof(struct udphdr, check))) | ||
1369 | goto out; | ||
1370 | |||
1371 | if (recalculate_partial_csum) | ||
1372 | udp_hdr(skb)->check = | ||
1373 | ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, | ||
1374 | &ipv6_hdr(skb)->daddr, | ||
1375 | skb->len - off, | ||
1376 | IPPROTO_UDP, 0); | ||
1171 | break; | 1377 | break; |
1172 | default: | 1378 | default: |
1173 | if (net_ratelimit()) | ||
1174 | netdev_err(vif->dev, | ||
1175 | "Attempting to checksum a non-TCP/UDP packet, dropping a protocol %d packet\n", | ||
1176 | iph->protocol); | ||
1177 | goto out; | 1379 | goto out; |
1178 | } | 1380 | } |
1179 | 1381 | ||
@@ -1183,11 +1385,38 @@ out: | |||
1183 | return err; | 1385 | return err; |
1184 | } | 1386 | } |
1185 | 1387 | ||
1388 | static int checksum_setup(struct xenvif *vif, struct sk_buff *skb) | ||
1389 | { | ||
1390 | int err = -EPROTO; | ||
1391 | int recalculate_partial_csum = 0; | ||
1392 | |||
1393 | /* A GSO SKB must be CHECKSUM_PARTIAL. However some buggy | ||
1394 | * peers can fail to set NETRXF_csum_blank when sending a GSO | ||
1395 | * frame. In this case force the SKB to CHECKSUM_PARTIAL and | ||
1396 | * recalculate the partial checksum. | ||
1397 | */ | ||
1398 | if (skb->ip_summed != CHECKSUM_PARTIAL && skb_is_gso(skb)) { | ||
1399 | vif->rx_gso_checksum_fixup++; | ||
1400 | skb->ip_summed = CHECKSUM_PARTIAL; | ||
1401 | recalculate_partial_csum = 1; | ||
1402 | } | ||
1403 | |||
1404 | /* A non-CHECKSUM_PARTIAL SKB does not require setup. */ | ||
1405 | if (skb->ip_summed != CHECKSUM_PARTIAL) | ||
1406 | return 0; | ||
1407 | |||
1408 | if (skb->protocol == htons(ETH_P_IP)) | ||
1409 | err = checksum_setup_ip(vif, skb, recalculate_partial_csum); | ||
1410 | else if (skb->protocol == htons(ETH_P_IPV6)) | ||
1411 | err = checksum_setup_ipv6(vif, skb, recalculate_partial_csum); | ||
1412 | |||
1413 | return err; | ||
1414 | } | ||
1415 | |||
1186 | static bool tx_credit_exceeded(struct xenvif *vif, unsigned size) | 1416 | static bool tx_credit_exceeded(struct xenvif *vif, unsigned size) |
1187 | { | 1417 | { |
1188 | unsigned long now = jiffies; | 1418 | u64 now = get_jiffies_64(); |
1189 | unsigned long next_credit = | 1419 | u64 next_credit = vif->credit_window_start + |
1190 | vif->credit_timeout.expires + | ||
1191 | msecs_to_jiffies(vif->credit_usec / 1000); | 1420 | msecs_to_jiffies(vif->credit_usec / 1000); |
1192 | 1421 | ||
1193 | /* Timer could already be pending in rare cases. */ | 1422 | /* Timer could already be pending in rare cases. */ |
@@ -1195,8 +1424,8 @@ static bool tx_credit_exceeded(struct xenvif *vif, unsigned size) | |||
1195 | return true; | 1424 | return true; |
1196 | 1425 | ||
1197 | /* Passed the point where we can replenish credit? */ | 1426 | /* Passed the point where we can replenish credit? */ |
1198 | if (time_after_eq(now, next_credit)) { | 1427 | if (time_after_eq64(now, next_credit)) { |
1199 | vif->credit_timeout.expires = now; | 1428 | vif->credit_window_start = now; |
1200 | tx_add_credit(vif); | 1429 | tx_add_credit(vif); |
1201 | } | 1430 | } |
1202 | 1431 | ||
@@ -1208,6 +1437,7 @@ static bool tx_credit_exceeded(struct xenvif *vif, unsigned size) | |||
1208 | tx_credit_callback; | 1437 | tx_credit_callback; |
1209 | mod_timer(&vif->credit_timeout, | 1438 | mod_timer(&vif->credit_timeout, |
1210 | next_credit); | 1439 | next_credit); |
1440 | vif->credit_window_start = next_credit; | ||
1211 | 1441 | ||
1212 | return true; | 1442 | return true; |
1213 | } | 1443 | } |
@@ -1215,14 +1445,15 @@ static bool tx_credit_exceeded(struct xenvif *vif, unsigned size) | |||
1215 | return false; | 1445 | return false; |
1216 | } | 1446 | } |
1217 | 1447 | ||
1218 | static unsigned xenvif_tx_build_gops(struct xenvif *vif) | 1448 | static unsigned xenvif_tx_build_gops(struct xenvif *vif, int budget) |
1219 | { | 1449 | { |
1220 | struct gnttab_copy *gop = vif->tx_copy_ops, *request_gop; | 1450 | struct gnttab_copy *gop = vif->tx_copy_ops, *request_gop; |
1221 | struct sk_buff *skb; | 1451 | struct sk_buff *skb; |
1222 | int ret; | 1452 | int ret; |
1223 | 1453 | ||
1224 | while ((nr_pending_reqs(vif) + XEN_NETBK_LEGACY_SLOTS_MAX | 1454 | while ((nr_pending_reqs(vif) + XEN_NETBK_LEGACY_SLOTS_MAX |
1225 | < MAX_PENDING_REQS)) { | 1455 | < MAX_PENDING_REQS) && |
1456 | (skb_queue_len(&vif->tx_queue) < budget)) { | ||
1226 | struct xen_netif_tx_request txreq; | 1457 | struct xen_netif_tx_request txreq; |
1227 | struct xen_netif_tx_request txfrags[XEN_NETBK_LEGACY_SLOTS_MAX]; | 1458 | struct xen_netif_tx_request txfrags[XEN_NETBK_LEGACY_SLOTS_MAX]; |
1228 | struct page *page; | 1459 | struct page *page; |
@@ -1244,7 +1475,7 @@ static unsigned xenvif_tx_build_gops(struct xenvif *vif) | |||
1244 | continue; | 1475 | continue; |
1245 | } | 1476 | } |
1246 | 1477 | ||
1247 | RING_FINAL_CHECK_FOR_REQUESTS(&vif->tx, work_to_do); | 1478 | work_to_do = RING_HAS_UNCONSUMED_REQUESTS(&vif->tx); |
1248 | if (!work_to_do) | 1479 | if (!work_to_do) |
1249 | break; | 1480 | break; |
1250 | 1481 | ||
@@ -1384,14 +1615,13 @@ static unsigned xenvif_tx_build_gops(struct xenvif *vif) | |||
1384 | } | 1615 | } |
1385 | 1616 | ||
1386 | 1617 | ||
1387 | static int xenvif_tx_submit(struct xenvif *vif, int budget) | 1618 | static int xenvif_tx_submit(struct xenvif *vif) |
1388 | { | 1619 | { |
1389 | struct gnttab_copy *gop = vif->tx_copy_ops; | 1620 | struct gnttab_copy *gop = vif->tx_copy_ops; |
1390 | struct sk_buff *skb; | 1621 | struct sk_buff *skb; |
1391 | int work_done = 0; | 1622 | int work_done = 0; |
1392 | 1623 | ||
1393 | while (work_done < budget && | 1624 | while ((skb = __skb_dequeue(&vif->tx_queue)) != NULL) { |
1394 | (skb = __skb_dequeue(&vif->tx_queue)) != NULL) { | ||
1395 | struct xen_netif_tx_request *txp; | 1625 | struct xen_netif_tx_request *txp; |
1396 | u16 pending_idx; | 1626 | u16 pending_idx; |
1397 | unsigned data_len; | 1627 | unsigned data_len; |
@@ -1428,12 +1658,7 @@ static int xenvif_tx_submit(struct xenvif *vif, int budget) | |||
1428 | 1658 | ||
1429 | xenvif_fill_frags(vif, skb); | 1659 | xenvif_fill_frags(vif, skb); |
1430 | 1660 | ||
1431 | /* | 1661 | if (skb_is_nonlinear(skb) && skb_headlen(skb) < PKT_PROT_LEN) { |
1432 | * If the initial fragment was < PKT_PROT_LEN then | ||
1433 | * pull through some bytes from the other fragments to | ||
1434 | * increase the linear region to PKT_PROT_LEN bytes. | ||
1435 | */ | ||
1436 | if (skb_headlen(skb) < PKT_PROT_LEN && skb_is_nonlinear(skb)) { | ||
1437 | int target = min_t(int, skb->len, PKT_PROT_LEN); | 1662 | int target = min_t(int, skb->len, PKT_PROT_LEN); |
1438 | __pskb_pull_tail(skb, target - skb_headlen(skb)); | 1663 | __pskb_pull_tail(skb, target - skb_headlen(skb)); |
1439 | } | 1664 | } |
@@ -1471,14 +1696,14 @@ int xenvif_tx_action(struct xenvif *vif, int budget) | |||
1471 | if (unlikely(!tx_work_todo(vif))) | 1696 | if (unlikely(!tx_work_todo(vif))) |
1472 | return 0; | 1697 | return 0; |
1473 | 1698 | ||
1474 | nr_gops = xenvif_tx_build_gops(vif); | 1699 | nr_gops = xenvif_tx_build_gops(vif, budget); |
1475 | 1700 | ||
1476 | if (nr_gops == 0) | 1701 | if (nr_gops == 0) |
1477 | return 0; | 1702 | return 0; |
1478 | 1703 | ||
1479 | gnttab_batch_copy(vif->tx_copy_ops, nr_gops); | 1704 | gnttab_batch_copy(vif->tx_copy_ops, nr_gops); |
1480 | 1705 | ||
1481 | work_done = xenvif_tx_submit(vif, nr_gops); | 1706 | work_done = xenvif_tx_submit(vif); |
1482 | 1707 | ||
1483 | return work_done; | 1708 | return work_done; |
1484 | } | 1709 | } |