diff options
Diffstat (limited to 'net/ipv6/udp.c')
| -rw-r--r-- | net/ipv6/udp.c | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 71e259e866a1..8b48512ebf6a 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
| @@ -138,6 +138,7 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk, | |||
| 138 | int peeked; | 138 | int peeked; |
| 139 | int err; | 139 | int err; |
| 140 | int is_udplite = IS_UDPLITE(sk); | 140 | int is_udplite = IS_UDPLITE(sk); |
| 141 | int is_udp4; | ||
| 141 | 142 | ||
| 142 | if (addr_len) | 143 | if (addr_len) |
| 143 | *addr_len=sizeof(struct sockaddr_in6); | 144 | *addr_len=sizeof(struct sockaddr_in6); |
| @@ -158,6 +159,8 @@ try_again: | |||
| 158 | else if (copied < ulen) | 159 | else if (copied < ulen) |
| 159 | msg->msg_flags |= MSG_TRUNC; | 160 | msg->msg_flags |= MSG_TRUNC; |
| 160 | 161 | ||
| 162 | is_udp4 = (skb->protocol == htons(ETH_P_IP)); | ||
| 163 | |||
| 161 | /* | 164 | /* |
| 162 | * If checksum is needed at all, try to do it while copying the | 165 | * If checksum is needed at all, try to do it while copying the |
| 163 | * data. If the data is truncated, or if we only want a partial | 166 | * data. If the data is truncated, or if we only want a partial |
| @@ -180,9 +183,14 @@ try_again: | |||
| 180 | if (err) | 183 | if (err) |
| 181 | goto out_free; | 184 | goto out_free; |
| 182 | 185 | ||
| 183 | if (!peeked) | 186 | if (!peeked) { |
| 184 | UDP6_INC_STATS_USER(sock_net(sk), | 187 | if (is_udp4) |
| 185 | UDP_MIB_INDATAGRAMS, is_udplite); | 188 | UDP_INC_STATS_USER(sock_net(sk), |
| 189 | UDP_MIB_INDATAGRAMS, is_udplite); | ||
| 190 | else | ||
| 191 | UDP6_INC_STATS_USER(sock_net(sk), | ||
| 192 | UDP_MIB_INDATAGRAMS, is_udplite); | ||
| 193 | } | ||
| 186 | 194 | ||
| 187 | sock_recv_timestamp(msg, sk, skb); | 195 | sock_recv_timestamp(msg, sk, skb); |
| 188 | 196 | ||
| @@ -196,7 +204,7 @@ try_again: | |||
| 196 | sin6->sin6_flowinfo = 0; | 204 | sin6->sin6_flowinfo = 0; |
| 197 | sin6->sin6_scope_id = 0; | 205 | sin6->sin6_scope_id = 0; |
| 198 | 206 | ||
| 199 | if (skb->protocol == htons(ETH_P_IP)) | 207 | if (is_udp4) |
| 200 | ipv6_addr_set(&sin6->sin6_addr, 0, 0, | 208 | ipv6_addr_set(&sin6->sin6_addr, 0, 0, |
| 201 | htonl(0xffff), ip_hdr(skb)->saddr); | 209 | htonl(0xffff), ip_hdr(skb)->saddr); |
| 202 | else { | 210 | else { |
| @@ -207,7 +215,7 @@ try_again: | |||
| 207 | } | 215 | } |
| 208 | 216 | ||
| 209 | } | 217 | } |
| 210 | if (skb->protocol == htons(ETH_P_IP)) { | 218 | if (is_udp4) { |
| 211 | if (inet->cmsg_flags) | 219 | if (inet->cmsg_flags) |
| 212 | ip_cmsg_recv(msg, skb); | 220 | ip_cmsg_recv(msg, skb); |
| 213 | } else { | 221 | } else { |
| @@ -228,8 +236,14 @@ out: | |||
| 228 | 236 | ||
| 229 | csum_copy_err: | 237 | csum_copy_err: |
| 230 | lock_sock(sk); | 238 | lock_sock(sk); |
| 231 | if (!skb_kill_datagram(sk, skb, flags)) | 239 | if (!skb_kill_datagram(sk, skb, flags)) { |
| 232 | UDP6_INC_STATS_USER(sock_net(sk), UDP_MIB_INERRORS, is_udplite); | 240 | if (is_udp4) |
| 241 | UDP_INC_STATS_USER(sock_net(sk), | ||
| 242 | UDP_MIB_INERRORS, is_udplite); | ||
| 243 | else | ||
| 244 | UDP6_INC_STATS_USER(sock_net(sk), | ||
| 245 | UDP_MIB_INERRORS, is_udplite); | ||
| 246 | } | ||
| 233 | release_sock(sk); | 247 | release_sock(sk); |
| 234 | 248 | ||
| 235 | if (flags & MSG_DONTWAIT) | 249 | if (flags & MSG_DONTWAIT) |
