3939#include <linux/udp.h>
4040
4141#include <net/tcp.h>
42- #include <net/ip6_checksum.h>
4342
4443#include <xen/xen.h>
4544#include <xen/events.h>
@@ -1051,257 +1050,9 @@ static int xenvif_set_skb_gso(struct xenvif *vif,
10511050 return 0 ;
10521051}
10531052
1054- static inline int maybe_pull_tail (struct sk_buff * skb , unsigned int len ,
1055- unsigned int max )
1056- {
1057- if (skb_headlen (skb ) >= len )
1058- return 0 ;
1059-
1060- /* If we need to pullup then pullup to the max, so we
1061- * won't need to do it again.
1062- */
1063- if (max > skb -> len )
1064- max = skb -> len ;
1065-
1066- if (__pskb_pull_tail (skb , max - skb_headlen (skb )) == NULL )
1067- return - ENOMEM ;
1068-
1069- if (skb_headlen (skb ) < len )
1070- return - EPROTO ;
1071-
1072- return 0 ;
1073- }
1074-
1075- /* This value should be large enough to cover a tagged ethernet header plus
1076- * maximally sized IP and TCP or UDP headers.
1077- */
1078- #define MAX_IP_HDR_LEN 128
1079-
1080- static int checksum_setup_ip (struct xenvif * vif , struct sk_buff * skb ,
1081- int recalculate_partial_csum )
1082- {
1083- unsigned int off ;
1084- bool fragment ;
1085- int err ;
1086-
1087- fragment = false;
1088-
1089- err = maybe_pull_tail (skb ,
1090- sizeof (struct iphdr ),
1091- MAX_IP_HDR_LEN );
1092- if (err < 0 )
1093- goto out ;
1094-
1095- if (ip_hdr (skb )-> frag_off & htons (IP_OFFSET | IP_MF ))
1096- fragment = true;
1097-
1098- off = ip_hdrlen (skb );
1099-
1100- err = - EPROTO ;
1101-
1102- if (fragment )
1103- goto out ;
1104-
1105- switch (ip_hdr (skb )-> protocol ) {
1106- case IPPROTO_TCP :
1107- err = maybe_pull_tail (skb ,
1108- off + sizeof (struct tcphdr ),
1109- MAX_IP_HDR_LEN );
1110- if (err < 0 )
1111- goto out ;
1112-
1113- if (!skb_partial_csum_set (skb , off ,
1114- offsetof(struct tcphdr , check ))) {
1115- err = - EPROTO ;
1116- goto out ;
1117- }
1118-
1119- if (recalculate_partial_csum )
1120- tcp_hdr (skb )-> check =
1121- ~csum_tcpudp_magic (ip_hdr (skb )-> saddr ,
1122- ip_hdr (skb )-> daddr ,
1123- skb -> len - off ,
1124- IPPROTO_TCP , 0 );
1125- break ;
1126- case IPPROTO_UDP :
1127- err = maybe_pull_tail (skb ,
1128- off + sizeof (struct udphdr ),
1129- MAX_IP_HDR_LEN );
1130- if (err < 0 )
1131- goto out ;
1132-
1133- if (!skb_partial_csum_set (skb , off ,
1134- offsetof(struct udphdr , check ))) {
1135- err = - EPROTO ;
1136- goto out ;
1137- }
1138-
1139- if (recalculate_partial_csum )
1140- udp_hdr (skb )-> check =
1141- ~csum_tcpudp_magic (ip_hdr (skb )-> saddr ,
1142- ip_hdr (skb )-> daddr ,
1143- skb -> len - off ,
1144- IPPROTO_UDP , 0 );
1145- break ;
1146- default :
1147- goto out ;
1148- }
1149-
1150- err = 0 ;
1151-
1152- out :
1153- return err ;
1154- }
1155-
1156- /* This value should be large enough to cover a tagged ethernet header plus
1157- * an IPv6 header, all options, and a maximal TCP or UDP header.
1158- */
1159- #define MAX_IPV6_HDR_LEN 256
1160-
1161- #define OPT_HDR (type , skb , off ) \
1162- (type *)(skb_network_header(skb) + (off))
1163-
1164- static int checksum_setup_ipv6 (struct xenvif * vif , struct sk_buff * skb ,
1165- int recalculate_partial_csum )
1166- {
1167- int err ;
1168- u8 nexthdr ;
1169- unsigned int off ;
1170- unsigned int len ;
1171- bool fragment ;
1172- bool done ;
1173-
1174- fragment = false;
1175- done = false;
1176-
1177- off = sizeof (struct ipv6hdr );
1178-
1179- err = maybe_pull_tail (skb , off , MAX_IPV6_HDR_LEN );
1180- if (err < 0 )
1181- goto out ;
1182-
1183- nexthdr = ipv6_hdr (skb )-> nexthdr ;
1184-
1185- len = sizeof (struct ipv6hdr ) + ntohs (ipv6_hdr (skb )-> payload_len );
1186- while (off <= len && !done ) {
1187- switch (nexthdr ) {
1188- case IPPROTO_DSTOPTS :
1189- case IPPROTO_HOPOPTS :
1190- case IPPROTO_ROUTING : {
1191- struct ipv6_opt_hdr * hp ;
1192-
1193- err = maybe_pull_tail (skb ,
1194- off +
1195- sizeof (struct ipv6_opt_hdr ),
1196- MAX_IPV6_HDR_LEN );
1197- if (err < 0 )
1198- goto out ;
1199-
1200- hp = OPT_HDR (struct ipv6_opt_hdr , skb , off );
1201- nexthdr = hp -> nexthdr ;
1202- off += ipv6_optlen (hp );
1203- break ;
1204- }
1205- case IPPROTO_AH : {
1206- struct ip_auth_hdr * hp ;
1207-
1208- err = maybe_pull_tail (skb ,
1209- off +
1210- sizeof (struct ip_auth_hdr ),
1211- MAX_IPV6_HDR_LEN );
1212- if (err < 0 )
1213- goto out ;
1214-
1215- hp = OPT_HDR (struct ip_auth_hdr , skb , off );
1216- nexthdr = hp -> nexthdr ;
1217- off += ipv6_authlen (hp );
1218- break ;
1219- }
1220- case IPPROTO_FRAGMENT : {
1221- struct frag_hdr * hp ;
1222-
1223- err = maybe_pull_tail (skb ,
1224- off +
1225- sizeof (struct frag_hdr ),
1226- MAX_IPV6_HDR_LEN );
1227- if (err < 0 )
1228- goto out ;
1229-
1230- hp = OPT_HDR (struct frag_hdr , skb , off );
1231-
1232- if (hp -> frag_off & htons (IP6_OFFSET | IP6_MF ))
1233- fragment = true;
1234-
1235- nexthdr = hp -> nexthdr ;
1236- off += sizeof (struct frag_hdr );
1237- break ;
1238- }
1239- default :
1240- done = true;
1241- break ;
1242- }
1243- }
1244-
1245- err = - EPROTO ;
1246-
1247- if (!done || fragment )
1248- goto out ;
1249-
1250- switch (nexthdr ) {
1251- case IPPROTO_TCP :
1252- err = maybe_pull_tail (skb ,
1253- off + sizeof (struct tcphdr ),
1254- MAX_IPV6_HDR_LEN );
1255- if (err < 0 )
1256- goto out ;
1257-
1258- if (!skb_partial_csum_set (skb , off ,
1259- offsetof(struct tcphdr , check ))) {
1260- err = - EPROTO ;
1261- goto out ;
1262- }
1263-
1264- if (recalculate_partial_csum )
1265- tcp_hdr (skb )-> check =
1266- ~csum_ipv6_magic (& ipv6_hdr (skb )-> saddr ,
1267- & ipv6_hdr (skb )-> daddr ,
1268- skb -> len - off ,
1269- IPPROTO_TCP , 0 );
1270- break ;
1271- case IPPROTO_UDP :
1272- err = maybe_pull_tail (skb ,
1273- off + sizeof (struct udphdr ),
1274- MAX_IPV6_HDR_LEN );
1275- if (err < 0 )
1276- goto out ;
1277-
1278- if (!skb_partial_csum_set (skb , off ,
1279- offsetof(struct udphdr , check ))) {
1280- err = - EPROTO ;
1281- goto out ;
1282- }
1283-
1284- if (recalculate_partial_csum )
1285- udp_hdr (skb )-> check =
1286- ~csum_ipv6_magic (& ipv6_hdr (skb )-> saddr ,
1287- & ipv6_hdr (skb )-> daddr ,
1288- skb -> len - off ,
1289- IPPROTO_UDP , 0 );
1290- break ;
1291- default :
1292- goto out ;
1293- }
1294-
1295- err = 0 ;
1296-
1297- out :
1298- return err ;
1299- }
1300-
13011053static int checksum_setup (struct xenvif * vif , struct sk_buff * skb )
13021054{
1303- int err = - EPROTO ;
1304- int recalculate_partial_csum = 0 ;
1055+ bool recalculate_partial_csum = false;
13051056
13061057 /* A GSO SKB must be CHECKSUM_PARTIAL. However some buggy
13071058 * peers can fail to set NETRXF_csum_blank when sending a GSO
@@ -1311,19 +1062,14 @@ static int checksum_setup(struct xenvif *vif, struct sk_buff *skb)
13111062 if (skb -> ip_summed != CHECKSUM_PARTIAL && skb_is_gso (skb )) {
13121063 vif -> rx_gso_checksum_fixup ++ ;
13131064 skb -> ip_summed = CHECKSUM_PARTIAL ;
1314- recalculate_partial_csum = 1 ;
1065+ recalculate_partial_csum = true ;
13151066 }
13161067
13171068 /* A non-CHECKSUM_PARTIAL SKB does not require setup. */
13181069 if (skb -> ip_summed != CHECKSUM_PARTIAL )
13191070 return 0 ;
13201071
1321- if (skb -> protocol == htons (ETH_P_IP ))
1322- err = checksum_setup_ip (vif , skb , recalculate_partial_csum );
1323- else if (skb -> protocol == htons (ETH_P_IPV6 ))
1324- err = checksum_setup_ipv6 (vif , skb , recalculate_partial_csum );
1325-
1326- return err ;
1072+ return skb_checksum_setup (skb , recalculate_partial_csum );
13271073}
13281074
13291075static bool tx_credit_exceeded (struct xenvif * vif , unsigned size )
0 commit comments