aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/udp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/udp.c')
-rw-r--r--net/ipv6/udp.c154
1 files changed, 81 insertions, 73 deletions
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 5acb3560ff15..328985c40883 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -54,8 +54,8 @@ int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2)
54{ 54{
55 const struct in6_addr *sk_rcv_saddr6 = &inet6_sk(sk)->rcv_saddr; 55 const struct in6_addr *sk_rcv_saddr6 = &inet6_sk(sk)->rcv_saddr;
56 const struct in6_addr *sk2_rcv_saddr6 = inet6_rcv_saddr(sk2); 56 const struct in6_addr *sk2_rcv_saddr6 = inet6_rcv_saddr(sk2);
57 __be32 sk1_rcv_saddr = inet_sk(sk)->inet_rcv_saddr; 57 __be32 sk1_rcv_saddr = sk_rcv_saddr(sk);
58 __be32 sk2_rcv_saddr = inet_rcv_saddr(sk2); 58 __be32 sk2_rcv_saddr = sk_rcv_saddr(sk2);
59 int sk_ipv6only = ipv6_only_sock(sk); 59 int sk_ipv6only = ipv6_only_sock(sk);
60 int sk2_ipv6only = inet_v6_ipv6only(sk2); 60 int sk2_ipv6only = inet_v6_ipv6only(sk2);
61 int addr_type = ipv6_addr_type(sk_rcv_saddr6); 61 int addr_type = ipv6_addr_type(sk_rcv_saddr6);
@@ -122,8 +122,8 @@ static void udp_v6_rehash(struct sock *sk)
122 122
123static inline int compute_score(struct sock *sk, struct net *net, 123static inline int compute_score(struct sock *sk, struct net *net,
124 unsigned short hnum, 124 unsigned short hnum,
125 struct in6_addr *saddr, __be16 sport, 125 const struct in6_addr *saddr, __be16 sport,
126 struct in6_addr *daddr, __be16 dport, 126 const struct in6_addr *daddr, __be16 dport,
127 int dif) 127 int dif)
128{ 128{
129 int score = -1; 129 int score = -1;
@@ -227,7 +227,7 @@ begin:
227 227
228 if (result) { 228 if (result) {
229exact_match: 229exact_match:
230 if (unlikely(!atomic_inc_not_zero(&result->sk_refcnt))) 230 if (unlikely(!atomic_inc_not_zero_hint(&result->sk_refcnt, 2)))
231 result = NULL; 231 result = NULL;
232 else if (unlikely(compute_score2(result, net, saddr, sport, 232 else if (unlikely(compute_score2(result, net, saddr, sport,
233 daddr, hnum, dif) < badness)) { 233 daddr, hnum, dif) < badness)) {
@@ -239,8 +239,8 @@ exact_match:
239} 239}
240 240
241static struct sock *__udp6_lib_lookup(struct net *net, 241static struct sock *__udp6_lib_lookup(struct net *net,
242 struct in6_addr *saddr, __be16 sport, 242 const struct in6_addr *saddr, __be16 sport,
243 struct in6_addr *daddr, __be16 dport, 243 const struct in6_addr *daddr, __be16 dport,
244 int dif, struct udp_table *udptable) 244 int dif, struct udp_table *udptable)
245{ 245{
246 struct sock *sk, *result; 246 struct sock *sk, *result;
@@ -294,7 +294,7 @@ begin:
294 goto begin; 294 goto begin;
295 295
296 if (result) { 296 if (result) {
297 if (unlikely(!atomic_inc_not_zero(&result->sk_refcnt))) 297 if (unlikely(!atomic_inc_not_zero_hint(&result->sk_refcnt, 2)))
298 result = NULL; 298 result = NULL;
299 else if (unlikely(compute_score(result, net, hnum, saddr, sport, 299 else if (unlikely(compute_score(result, net, hnum, saddr, sport,
300 daddr, dport, dif) < badness)) { 300 daddr, dport, dif) < badness)) {
@@ -311,7 +311,7 @@ static struct sock *__udp6_lib_lookup_skb(struct sk_buff *skb,
311 struct udp_table *udptable) 311 struct udp_table *udptable)
312{ 312{
313 struct sock *sk; 313 struct sock *sk;
314 struct ipv6hdr *iph = ipv6_hdr(skb); 314 const struct ipv6hdr *iph = ipv6_hdr(skb);
315 315
316 if (unlikely(sk = skb_steal_sock(skb))) 316 if (unlikely(sk = skb_steal_sock(skb)))
317 return sk; 317 return sk;
@@ -320,6 +320,14 @@ static struct sock *__udp6_lib_lookup_skb(struct sk_buff *skb,
320 udptable); 320 udptable);
321} 321}
322 322
323struct sock *udp6_lib_lookup(struct net *net, const struct in6_addr *saddr, __be16 sport,
324 const struct in6_addr *daddr, __be16 dport, int dif)
325{
326 return __udp6_lib_lookup(net, saddr, sport, daddr, dport, dif, &udp_table);
327}
328EXPORT_SYMBOL_GPL(udp6_lib_lookup);
329
330
323/* 331/*
324 * This should be easy, if there is something there we 332 * This should be easy, if there is something there we
325 * return it, otherwise we block. 333 * return it, otherwise we block.
@@ -445,8 +453,11 @@ csum_copy_err:
445 } 453 }
446 unlock_sock_fast(sk, slow); 454 unlock_sock_fast(sk, slow);
447 455
448 if (flags & MSG_DONTWAIT) 456 if (noblock)
449 return -EAGAIN; 457 return -EAGAIN;
458
459 /* starting over for a new packet */
460 msg->msg_flags &= ~MSG_TRUNC;
450 goto try_again; 461 goto try_again;
451} 462}
452 463
@@ -455,9 +466,9 @@ void __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
455 struct udp_table *udptable) 466 struct udp_table *udptable)
456{ 467{
457 struct ipv6_pinfo *np; 468 struct ipv6_pinfo *np;
458 struct ipv6hdr *hdr = (struct ipv6hdr*)skb->data; 469 const struct ipv6hdr *hdr = (const struct ipv6hdr *)skb->data;
459 struct in6_addr *saddr = &hdr->saddr; 470 const struct in6_addr *saddr = &hdr->saddr;
460 struct in6_addr *daddr = &hdr->daddr; 471 const struct in6_addr *daddr = &hdr->daddr;
461 struct udphdr *uh = (struct udphdr*)(skb->data+offset); 472 struct udphdr *uh = (struct udphdr*)(skb->data+offset);
462 struct sock *sk; 473 struct sock *sk;
463 int err; 474 int err;
@@ -497,6 +508,9 @@ int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
497 int rc; 508 int rc;
498 int is_udplite = IS_UDPLITE(sk); 509 int is_udplite = IS_UDPLITE(sk);
499 510
511 if (!ipv6_addr_any(&inet6_sk(sk)->daddr))
512 sock_rps_save_rxhash(sk, skb->rxhash);
513
500 if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) 514 if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
501 goto drop; 515 goto drop;
502 516
@@ -519,7 +533,7 @@ int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
519 } 533 }
520 } 534 }
521 535
522 if (sk->sk_filter) { 536 if (rcu_dereference_raw(sk->sk_filter)) {
523 if (udp_lib_checksum_complete(skb)) 537 if (udp_lib_checksum_complete(skb))
524 goto drop; 538 goto drop;
525 } 539 }
@@ -542,8 +556,8 @@ drop_no_sk_drops_inc:
542} 556}
543 557
544static struct sock *udp_v6_mcast_next(struct net *net, struct sock *sk, 558static struct sock *udp_v6_mcast_next(struct net *net, struct sock *sk,
545 __be16 loc_port, struct in6_addr *loc_addr, 559 __be16 loc_port, const struct in6_addr *loc_addr,
546 __be16 rmt_port, struct in6_addr *rmt_addr, 560 __be16 rmt_port, const struct in6_addr *rmt_addr,
547 int dif) 561 int dif)
548{ 562{
549 struct hlist_nulls_node *node; 563 struct hlist_nulls_node *node;
@@ -594,7 +608,7 @@ static void flush_stack(struct sock **stack, unsigned int count,
594 608
595 sk = stack[i]; 609 sk = stack[i];
596 if (skb1) { 610 if (skb1) {
597 if (sk_rcvqueues_full(sk, skb)) { 611 if (sk_rcvqueues_full(sk, skb1)) {
598 kfree_skb(skb1); 612 kfree_skb(skb1);
599 goto drop; 613 goto drop;
600 } 614 }
@@ -622,7 +636,7 @@ drop:
622 * so we don't need to lock the hashes. 636 * so we don't need to lock the hashes.
623 */ 637 */
624static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb, 638static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
625 struct in6_addr *saddr, struct in6_addr *daddr, 639 const struct in6_addr *saddr, const struct in6_addr *daddr,
626 struct udp_table *udptable) 640 struct udp_table *udptable)
627{ 641{
628 struct sock *sk, *stack[256 / sizeof(struct sock *)]; 642 struct sock *sk, *stack[256 / sizeof(struct sock *)];
@@ -705,7 +719,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
705 struct net *net = dev_net(skb->dev); 719 struct net *net = dev_net(skb->dev);
706 struct sock *sk; 720 struct sock *sk;
707 struct udphdr *uh; 721 struct udphdr *uh;
708 struct in6_addr *saddr, *daddr; 722 const struct in6_addr *saddr, *daddr;
709 u32 ulen = 0; 723 u32 ulen = 0;
710 724
711 if (!pskb_may_pull(skb, sizeof(struct udphdr))) 725 if (!pskb_may_pull(skb, sizeof(struct udphdr)))
@@ -878,7 +892,7 @@ static int udp_v6_push_pending_frames(struct sock *sk)
878 struct udphdr *uh; 892 struct udphdr *uh;
879 struct udp_sock *up = udp_sk(sk); 893 struct udp_sock *up = udp_sk(sk);
880 struct inet_sock *inet = inet_sk(sk); 894 struct inet_sock *inet = inet_sk(sk);
881 struct flowi *fl = &inet->cork.fl; 895 struct flowi6 *fl6 = &inet->cork.fl.u.ip6;
882 int err = 0; 896 int err = 0;
883 int is_udplite = IS_UDPLITE(sk); 897 int is_udplite = IS_UDPLITE(sk);
884 __wsum csum = 0; 898 __wsum csum = 0;
@@ -891,23 +905,23 @@ static int udp_v6_push_pending_frames(struct sock *sk)
891 * Create a UDP header 905 * Create a UDP header
892 */ 906 */
893 uh = udp_hdr(skb); 907 uh = udp_hdr(skb);
894 uh->source = fl->fl_ip_sport; 908 uh->source = fl6->fl6_sport;
895 uh->dest = fl->fl_ip_dport; 909 uh->dest = fl6->fl6_dport;
896 uh->len = htons(up->len); 910 uh->len = htons(up->len);
897 uh->check = 0; 911 uh->check = 0;
898 912
899 if (is_udplite) 913 if (is_udplite)
900 csum = udplite_csum_outgoing(sk, skb); 914 csum = udplite_csum_outgoing(sk, skb);
901 else if (skb->ip_summed == CHECKSUM_PARTIAL) { /* UDP hardware csum */ 915 else if (skb->ip_summed == CHECKSUM_PARTIAL) { /* UDP hardware csum */
902 udp6_hwcsum_outgoing(sk, skb, &fl->fl6_src, &fl->fl6_dst, 916 udp6_hwcsum_outgoing(sk, skb, &fl6->saddr, &fl6->daddr,
903 up->len); 917 up->len);
904 goto send; 918 goto send;
905 } else 919 } else
906 csum = udp_csum_outgoing(sk, skb); 920 csum = udp_csum_outgoing(sk, skb);
907 921
908 /* add protocol-dependent pseudo-header */ 922 /* add protocol-dependent pseudo-header */
909 uh->check = csum_ipv6_magic(&fl->fl6_src, &fl->fl6_dst, 923 uh->check = csum_ipv6_magic(&fl6->saddr, &fl6->daddr,
910 up->len, fl->proto, csum ); 924 up->len, fl6->flowi6_proto, csum);
911 if (uh->check == 0) 925 if (uh->check == 0)
912 uh->check = CSUM_MANGLED_0; 926 uh->check = CSUM_MANGLED_0;
913 927
@@ -939,7 +953,7 @@ int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk,
939 struct in6_addr *daddr, *final_p, final; 953 struct in6_addr *daddr, *final_p, final;
940 struct ipv6_txoptions *opt = NULL; 954 struct ipv6_txoptions *opt = NULL;
941 struct ip6_flowlabel *flowlabel = NULL; 955 struct ip6_flowlabel *flowlabel = NULL;
942 struct flowi fl; 956 struct flowi6 fl6;
943 struct dst_entry *dst; 957 struct dst_entry *dst;
944 int addr_len = msg->msg_namelen; 958 int addr_len = msg->msg_namelen;
945 int ulen = len; 959 int ulen = len;
@@ -1022,19 +1036,19 @@ do_udp_sendmsg:
1022 } 1036 }
1023 ulen += sizeof(struct udphdr); 1037 ulen += sizeof(struct udphdr);
1024 1038
1025 memset(&fl, 0, sizeof(fl)); 1039 memset(&fl6, 0, sizeof(fl6));
1026 1040
1027 if (sin6) { 1041 if (sin6) {
1028 if (sin6->sin6_port == 0) 1042 if (sin6->sin6_port == 0)
1029 return -EINVAL; 1043 return -EINVAL;
1030 1044
1031 fl.fl_ip_dport = sin6->sin6_port; 1045 fl6.fl6_dport = sin6->sin6_port;
1032 daddr = &sin6->sin6_addr; 1046 daddr = &sin6->sin6_addr;
1033 1047
1034 if (np->sndflow) { 1048 if (np->sndflow) {
1035 fl.fl6_flowlabel = sin6->sin6_flowinfo&IPV6_FLOWINFO_MASK; 1049 fl6.flowlabel = sin6->sin6_flowinfo&IPV6_FLOWINFO_MASK;
1036 if (fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) { 1050 if (fl6.flowlabel&IPV6_FLOWLABEL_MASK) {
1037 flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel); 1051 flowlabel = fl6_sock_lookup(sk, fl6.flowlabel);
1038 if (flowlabel == NULL) 1052 if (flowlabel == NULL)
1039 return -EINVAL; 1053 return -EINVAL;
1040 daddr = &flowlabel->dst; 1054 daddr = &flowlabel->dst;
@@ -1052,38 +1066,38 @@ do_udp_sendmsg:
1052 if (addr_len >= sizeof(struct sockaddr_in6) && 1066 if (addr_len >= sizeof(struct sockaddr_in6) &&
1053 sin6->sin6_scope_id && 1067 sin6->sin6_scope_id &&
1054 ipv6_addr_type(daddr)&IPV6_ADDR_LINKLOCAL) 1068 ipv6_addr_type(daddr)&IPV6_ADDR_LINKLOCAL)
1055 fl.oif = sin6->sin6_scope_id; 1069 fl6.flowi6_oif = sin6->sin6_scope_id;
1056 } else { 1070 } else {
1057 if (sk->sk_state != TCP_ESTABLISHED) 1071 if (sk->sk_state != TCP_ESTABLISHED)
1058 return -EDESTADDRREQ; 1072 return -EDESTADDRREQ;
1059 1073
1060 fl.fl_ip_dport = inet->inet_dport; 1074 fl6.fl6_dport = inet->inet_dport;
1061 daddr = &np->daddr; 1075 daddr = &np->daddr;
1062 fl.fl6_flowlabel = np->flow_label; 1076 fl6.flowlabel = np->flow_label;
1063 connected = 1; 1077 connected = 1;
1064 } 1078 }
1065 1079
1066 if (!fl.oif) 1080 if (!fl6.flowi6_oif)
1067 fl.oif = sk->sk_bound_dev_if; 1081 fl6.flowi6_oif = sk->sk_bound_dev_if;
1068 1082
1069 if (!fl.oif) 1083 if (!fl6.flowi6_oif)
1070 fl.oif = np->sticky_pktinfo.ipi6_ifindex; 1084 fl6.flowi6_oif = np->sticky_pktinfo.ipi6_ifindex;
1071 1085
1072 fl.mark = sk->sk_mark; 1086 fl6.flowi6_mark = sk->sk_mark;
1073 1087
1074 if (msg->msg_controllen) { 1088 if (msg->msg_controllen) {
1075 opt = &opt_space; 1089 opt = &opt_space;
1076 memset(opt, 0, sizeof(struct ipv6_txoptions)); 1090 memset(opt, 0, sizeof(struct ipv6_txoptions));
1077 opt->tot_len = sizeof(*opt); 1091 opt->tot_len = sizeof(*opt);
1078 1092
1079 err = datagram_send_ctl(sock_net(sk), msg, &fl, opt, &hlimit, 1093 err = datagram_send_ctl(sock_net(sk), msg, &fl6, opt, &hlimit,
1080 &tclass, &dontfrag); 1094 &tclass, &dontfrag);
1081 if (err < 0) { 1095 if (err < 0) {
1082 fl6_sock_release(flowlabel); 1096 fl6_sock_release(flowlabel);
1083 return err; 1097 return err;
1084 } 1098 }
1085 if ((fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) && !flowlabel) { 1099 if ((fl6.flowlabel&IPV6_FLOWLABEL_MASK) && !flowlabel) {
1086 flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel); 1100 flowlabel = fl6_sock_lookup(sk, fl6.flowlabel);
1087 if (flowlabel == NULL) 1101 if (flowlabel == NULL)
1088 return -EINVAL; 1102 return -EINVAL;
1089 } 1103 }
@@ -1097,42 +1111,35 @@ do_udp_sendmsg:
1097 opt = fl6_merge_options(&opt_space, flowlabel, opt); 1111 opt = fl6_merge_options(&opt_space, flowlabel, opt);
1098 opt = ipv6_fixup_options(&opt_space, opt); 1112 opt = ipv6_fixup_options(&opt_space, opt);
1099 1113
1100 fl.proto = sk->sk_protocol; 1114 fl6.flowi6_proto = sk->sk_protocol;
1101 if (!ipv6_addr_any(daddr)) 1115 if (!ipv6_addr_any(daddr))
1102 ipv6_addr_copy(&fl.fl6_dst, daddr); 1116 ipv6_addr_copy(&fl6.daddr, daddr);
1103 else 1117 else
1104 fl.fl6_dst.s6_addr[15] = 0x1; /* :: means loopback (BSD'ism) */ 1118 fl6.daddr.s6_addr[15] = 0x1; /* :: means loopback (BSD'ism) */
1105 if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr)) 1119 if (ipv6_addr_any(&fl6.saddr) && !ipv6_addr_any(&np->saddr))
1106 ipv6_addr_copy(&fl.fl6_src, &np->saddr); 1120 ipv6_addr_copy(&fl6.saddr, &np->saddr);
1107 fl.fl_ip_sport = inet->inet_sport; 1121 fl6.fl6_sport = inet->inet_sport;
1108 1122
1109 final_p = fl6_update_dst(&fl, opt, &final); 1123 final_p = fl6_update_dst(&fl6, opt, &final);
1110 if (final_p) 1124 if (final_p)
1111 connected = 0; 1125 connected = 0;
1112 1126
1113 if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst)) { 1127 if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr)) {
1114 fl.oif = np->mcast_oif; 1128 fl6.flowi6_oif = np->mcast_oif;
1115 connected = 0; 1129 connected = 0;
1116 } 1130 }
1117 1131
1118 security_sk_classify_flow(sk, &fl); 1132 security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
1119 1133
1120 err = ip6_sk_dst_lookup(sk, &dst, &fl); 1134 dst = ip6_sk_dst_lookup_flow(sk, &fl6, final_p, true);
1121 if (err) 1135 if (IS_ERR(dst)) {
1136 err = PTR_ERR(dst);
1137 dst = NULL;
1122 goto out; 1138 goto out;
1123 if (final_p)
1124 ipv6_addr_copy(&fl.fl6_dst, final_p);
1125
1126 err = __xfrm_lookup(sock_net(sk), &dst, &fl, sk, XFRM_LOOKUP_WAIT);
1127 if (err < 0) {
1128 if (err == -EREMOTE)
1129 err = ip6_dst_blackhole(sk, &dst, &fl);
1130 if (err < 0)
1131 goto out;
1132 } 1139 }
1133 1140
1134 if (hlimit < 0) { 1141 if (hlimit < 0) {
1135 if (ipv6_addr_is_multicast(&fl.fl6_dst)) 1142 if (ipv6_addr_is_multicast(&fl6.daddr))
1136 hlimit = np->mcast_hops; 1143 hlimit = np->mcast_hops;
1137 else 1144 else
1138 hlimit = np->hop_limit; 1145 hlimit = np->hop_limit;
@@ -1167,7 +1174,7 @@ do_append_data:
1167 up->len += ulen; 1174 up->len += ulen;
1168 getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag; 1175 getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag;
1169 err = ip6_append_data(sk, getfrag, msg->msg_iov, ulen, 1176 err = ip6_append_data(sk, getfrag, msg->msg_iov, ulen,
1170 sizeof(struct udphdr), hlimit, tclass, opt, &fl, 1177 sizeof(struct udphdr), hlimit, tclass, opt, &fl6,
1171 (struct rt6_info*)dst, 1178 (struct rt6_info*)dst,
1172 corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags, dontfrag); 1179 corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags, dontfrag);
1173 if (err) 1180 if (err)
@@ -1180,10 +1187,10 @@ do_append_data:
1180 if (dst) { 1187 if (dst) {
1181 if (connected) { 1188 if (connected) {
1182 ip6_dst_store(sk, dst, 1189 ip6_dst_store(sk, dst,
1183 ipv6_addr_equal(&fl.fl6_dst, &np->daddr) ? 1190 ipv6_addr_equal(&fl6.daddr, &np->daddr) ?
1184 &np->daddr : NULL, 1191 &np->daddr : NULL,
1185#ifdef CONFIG_IPV6_SUBTREES 1192#ifdef CONFIG_IPV6_SUBTREES
1186 ipv6_addr_equal(&fl.fl6_src, &np->saddr) ? 1193 ipv6_addr_equal(&fl6.saddr, &np->saddr) ?
1187 &np->saddr : 1194 &np->saddr :
1188#endif 1195#endif
1189 NULL); 1196 NULL);
@@ -1274,7 +1281,7 @@ int compat_udpv6_getsockopt(struct sock *sk, int level, int optname,
1274 1281
1275static int udp6_ufo_send_check(struct sk_buff *skb) 1282static int udp6_ufo_send_check(struct sk_buff *skb)
1276{ 1283{
1277 struct ipv6hdr *ipv6h; 1284 const struct ipv6hdr *ipv6h;
1278 struct udphdr *uh; 1285 struct udphdr *uh;
1279 1286
1280 if (!pskb_may_pull(skb, sizeof(*uh))) 1287 if (!pskb_may_pull(skb, sizeof(*uh)))
@@ -1291,7 +1298,7 @@ static int udp6_ufo_send_check(struct sk_buff *skb)
1291 return 0; 1298 return 0;
1292} 1299}
1293 1300
1294static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, int features) 1301static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, u32 features)
1295{ 1302{
1296 struct sk_buff *segs = ERR_PTR(-EINVAL); 1303 struct sk_buff *segs = ERR_PTR(-EINVAL);
1297 unsigned int mss; 1304 unsigned int mss;
@@ -1324,14 +1331,14 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, int features)
1324 /* Do software UFO. Complete and fill in the UDP checksum as HW cannot 1331 /* Do software UFO. Complete and fill in the UDP checksum as HW cannot
1325 * do checksum of UDP packets sent as multiple IP fragments. 1332 * do checksum of UDP packets sent as multiple IP fragments.
1326 */ 1333 */
1327 offset = skb->csum_start - skb_headroom(skb); 1334 offset = skb_checksum_start_offset(skb);
1328 csum = skb_checksum(skb, offset, skb->len- offset, 0); 1335 csum = skb_checksum(skb, offset, skb->len- offset, 0);
1329 offset += skb->csum_offset; 1336 offset += skb->csum_offset;
1330 *(__sum16 *)(skb->data + offset) = csum_fold(csum); 1337 *(__sum16 *)(skb->data + offset) = csum_fold(csum);
1331 skb->ip_summed = CHECKSUM_NONE; 1338 skb->ip_summed = CHECKSUM_NONE;
1332 1339
1333 /* Check if there is enough headroom to insert fragment header. */ 1340 /* Check if there is enough headroom to insert fragment header. */
1334 if ((skb_headroom(skb) < frag_hdr_sz) && 1341 if ((skb_mac_header(skb) < skb->head + frag_hdr_sz) &&
1335 pskb_expand_head(skb, frag_hdr_sz, 0, GFP_ATOMIC)) 1342 pskb_expand_head(skb, frag_hdr_sz, 0, GFP_ATOMIC))
1336 goto out; 1343 goto out;
1337 1344
@@ -1378,7 +1385,7 @@ static void udp6_sock_seq_show(struct seq_file *seq, struct sock *sp, int bucket
1378{ 1385{
1379 struct inet_sock *inet = inet_sk(sp); 1386 struct inet_sock *inet = inet_sk(sp);
1380 struct ipv6_pinfo *np = inet6_sk(sp); 1387 struct ipv6_pinfo *np = inet6_sk(sp);
1381 struct in6_addr *dest, *src; 1388 const struct in6_addr *dest, *src;
1382 __u16 destp, srcp; 1389 __u16 destp, srcp;
1383 1390
1384 dest = &np->daddr; 1391 dest = &np->daddr;
@@ -1387,7 +1394,7 @@ static void udp6_sock_seq_show(struct seq_file *seq, struct sock *sp, int bucket
1387 srcp = ntohs(inet->inet_sport); 1394 srcp = ntohs(inet->inet_sport);
1388 seq_printf(seq, 1395 seq_printf(seq,
1389 "%5d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X " 1396 "%5d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
1390 "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d\n", 1397 "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %pK %d\n",
1391 bucket, 1398 bucket,
1392 src->s6_addr32[0], src->s6_addr32[1], 1399 src->s6_addr32[0], src->s6_addr32[1],
1393 src->s6_addr32[2], src->s6_addr32[3], srcp, 1400 src->s6_addr32[2], src->s6_addr32[3], srcp,
@@ -1469,6 +1476,7 @@ struct proto udpv6_prot = {
1469 .compat_setsockopt = compat_udpv6_setsockopt, 1476 .compat_setsockopt = compat_udpv6_setsockopt,
1470 .compat_getsockopt = compat_udpv6_getsockopt, 1477 .compat_getsockopt = compat_udpv6_getsockopt,
1471#endif 1478#endif
1479 .clear_sk = sk_prot_clear_portaddr_nulls,
1472}; 1480};
1473 1481
1474static struct inet_protosw udpv6_protosw = { 1482static struct inet_protosw udpv6_protosw = {