diff options
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/ip_sockglue.c | 73 |
1 files changed, 36 insertions, 37 deletions
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 43c05854d752..21b0187123d6 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c | |||
@@ -157,38 +157,39 @@ void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb) | |||
157 | /* Ordered by supposed usage frequency */ | 157 | /* Ordered by supposed usage frequency */ |
158 | if (flags & 1) | 158 | if (flags & 1) |
159 | ip_cmsg_recv_pktinfo(msg, skb); | 159 | ip_cmsg_recv_pktinfo(msg, skb); |
160 | if ((flags>>=1) == 0) | 160 | if ((flags >>= 1) == 0) |
161 | return; | 161 | return; |
162 | 162 | ||
163 | if (flags & 1) | 163 | if (flags & 1) |
164 | ip_cmsg_recv_ttl(msg, skb); | 164 | ip_cmsg_recv_ttl(msg, skb); |
165 | if ((flags>>=1) == 0) | 165 | if ((flags >>= 1) == 0) |
166 | return; | 166 | return; |
167 | 167 | ||
168 | if (flags & 1) | 168 | if (flags & 1) |
169 | ip_cmsg_recv_tos(msg, skb); | 169 | ip_cmsg_recv_tos(msg, skb); |
170 | if ((flags>>=1) == 0) | 170 | if ((flags >>= 1) == 0) |
171 | return; | 171 | return; |
172 | 172 | ||
173 | if (flags & 1) | 173 | if (flags & 1) |
174 | ip_cmsg_recv_opts(msg, skb); | 174 | ip_cmsg_recv_opts(msg, skb); |
175 | if ((flags>>=1) == 0) | 175 | if ((flags >>= 1) == 0) |
176 | return; | 176 | return; |
177 | 177 | ||
178 | if (flags & 1) | 178 | if (flags & 1) |
179 | ip_cmsg_recv_retopts(msg, skb); | 179 | ip_cmsg_recv_retopts(msg, skb); |
180 | if ((flags>>=1) == 0) | 180 | if ((flags >>= 1) == 0) |
181 | return; | 181 | return; |
182 | 182 | ||
183 | if (flags & 1) | 183 | if (flags & 1) |
184 | ip_cmsg_recv_security(msg, skb); | 184 | ip_cmsg_recv_security(msg, skb); |
185 | 185 | ||
186 | if ((flags>>=1) == 0) | 186 | if ((flags >>= 1) == 0) |
187 | return; | 187 | return; |
188 | if (flags & 1) | 188 | if (flags & 1) |
189 | ip_cmsg_recv_dstaddr(msg, skb); | 189 | ip_cmsg_recv_dstaddr(msg, skb); |
190 | 190 | ||
191 | } | 191 | } |
192 | EXPORT_SYMBOL(ip_cmsg_recv); | ||
192 | 193 | ||
193 | int ip_cmsg_send(struct net *net, struct msghdr *msg, struct ipcm_cookie *ipc) | 194 | int ip_cmsg_send(struct net *net, struct msghdr *msg, struct ipcm_cookie *ipc) |
194 | { | 195 | { |
@@ -203,7 +204,8 @@ int ip_cmsg_send(struct net *net, struct msghdr *msg, struct ipcm_cookie *ipc) | |||
203 | switch (cmsg->cmsg_type) { | 204 | switch (cmsg->cmsg_type) { |
204 | case IP_RETOPTS: | 205 | case IP_RETOPTS: |
205 | err = cmsg->cmsg_len - CMSG_ALIGN(sizeof(struct cmsghdr)); | 206 | err = cmsg->cmsg_len - CMSG_ALIGN(sizeof(struct cmsghdr)); |
206 | err = ip_options_get(net, &ipc->opt, CMSG_DATA(cmsg), err < 40 ? err : 40); | 207 | err = ip_options_get(net, &ipc->opt, CMSG_DATA(cmsg), |
208 | err < 40 ? err : 40); | ||
207 | if (err) | 209 | if (err) |
208 | return err; | 210 | return err; |
209 | break; | 211 | break; |
@@ -238,7 +240,8 @@ int ip_cmsg_send(struct net *net, struct msghdr *msg, struct ipcm_cookie *ipc) | |||
238 | struct ip_ra_chain *ip_ra_chain; | 240 | struct ip_ra_chain *ip_ra_chain; |
239 | DEFINE_RWLOCK(ip_ra_lock); | 241 | DEFINE_RWLOCK(ip_ra_lock); |
240 | 242 | ||
241 | int ip_ra_control(struct sock *sk, unsigned char on, void (*destructor)(struct sock *)) | 243 | int ip_ra_control(struct sock *sk, unsigned char on, |
244 | void (*destructor)(struct sock *)) | ||
242 | { | 245 | { |
243 | struct ip_ra_chain *ra, *new_ra, **rap; | 246 | struct ip_ra_chain *ra, *new_ra, **rap; |
244 | 247 | ||
@@ -248,7 +251,7 @@ int ip_ra_control(struct sock *sk, unsigned char on, void (*destructor)(struct s | |||
248 | new_ra = on ? kmalloc(sizeof(*new_ra), GFP_KERNEL) : NULL; | 251 | new_ra = on ? kmalloc(sizeof(*new_ra), GFP_KERNEL) : NULL; |
249 | 252 | ||
250 | write_lock_bh(&ip_ra_lock); | 253 | write_lock_bh(&ip_ra_lock); |
251 | for (rap = &ip_ra_chain; (ra=*rap) != NULL; rap = &ra->next) { | 254 | for (rap = &ip_ra_chain; (ra = *rap) != NULL; rap = &ra->next) { |
252 | if (ra->sk == sk) { | 255 | if (ra->sk == sk) { |
253 | if (on) { | 256 | if (on) { |
254 | write_unlock_bh(&ip_ra_lock); | 257 | write_unlock_bh(&ip_ra_lock); |
@@ -416,7 +419,8 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len) | |||
416 | /* Reset and regenerate socket error */ | 419 | /* Reset and regenerate socket error */ |
417 | spin_lock_bh(&sk->sk_error_queue.lock); | 420 | spin_lock_bh(&sk->sk_error_queue.lock); |
418 | sk->sk_err = 0; | 421 | sk->sk_err = 0; |
419 | if ((skb2 = skb_peek(&sk->sk_error_queue)) != NULL) { | 422 | skb2 = skb_peek(&sk->sk_error_queue); |
423 | if (skb2 != NULL) { | ||
420 | sk->sk_err = SKB_EXT_ERR(skb2)->ee.ee_errno; | 424 | sk->sk_err = SKB_EXT_ERR(skb2)->ee.ee_errno; |
421 | spin_unlock_bh(&sk->sk_error_queue.lock); | 425 | spin_unlock_bh(&sk->sk_error_queue.lock); |
422 | sk->sk_error_report(sk); | 426 | sk->sk_error_report(sk); |
@@ -431,8 +435,8 @@ out: | |||
431 | 435 | ||
432 | 436 | ||
433 | /* | 437 | /* |
434 | * Socket option code for IP. This is the end of the line after any TCP,UDP etc options on | 438 | * Socket option code for IP. This is the end of the line after any |
435 | * an IP socket. | 439 | * TCP,UDP etc options on an IP socket. |
436 | */ | 440 | */ |
437 | 441 | ||
438 | static int do_ip_setsockopt(struct sock *sk, int level, | 442 | static int do_ip_setsockopt(struct sock *sk, int level, |
@@ -474,7 +478,7 @@ static int do_ip_setsockopt(struct sock *sk, int level, | |||
474 | switch (optname) { | 478 | switch (optname) { |
475 | case IP_OPTIONS: | 479 | case IP_OPTIONS: |
476 | { | 480 | { |
477 | struct ip_options * opt = NULL; | 481 | struct ip_options *opt = NULL; |
478 | if (optlen > 40 || optlen < 0) | 482 | if (optlen > 40 || optlen < 0) |
479 | goto e_inval; | 483 | goto e_inval; |
480 | err = ip_options_get_from_user(sock_net(sk), &opt, | 484 | err = ip_options_get_from_user(sock_net(sk), &opt, |
@@ -556,9 +560,9 @@ static int do_ip_setsockopt(struct sock *sk, int level, | |||
556 | } | 560 | } |
557 | break; | 561 | break; |
558 | case IP_TTL: | 562 | case IP_TTL: |
559 | if (optlen<1) | 563 | if (optlen < 1) |
560 | goto e_inval; | 564 | goto e_inval; |
561 | if (val != -1 && (val < 1 || val>255)) | 565 | if (val != -1 && (val < 0 || val > 255)) |
562 | goto e_inval; | 566 | goto e_inval; |
563 | inet->uc_ttl = val; | 567 | inet->uc_ttl = val; |
564 | break; | 568 | break; |
@@ -570,7 +574,7 @@ static int do_ip_setsockopt(struct sock *sk, int level, | |||
570 | inet->hdrincl = val ? 1 : 0; | 574 | inet->hdrincl = val ? 1 : 0; |
571 | break; | 575 | break; |
572 | case IP_MTU_DISCOVER: | 576 | case IP_MTU_DISCOVER: |
573 | if (val<0 || val>3) | 577 | if (val < 0 || val > 3) |
574 | goto e_inval; | 578 | goto e_inval; |
575 | inet->pmtudisc = val; | 579 | inet->pmtudisc = val; |
576 | break; | 580 | break; |
@@ -582,7 +586,7 @@ static int do_ip_setsockopt(struct sock *sk, int level, | |||
582 | case IP_MULTICAST_TTL: | 586 | case IP_MULTICAST_TTL: |
583 | if (sk->sk_type == SOCK_STREAM) | 587 | if (sk->sk_type == SOCK_STREAM) |
584 | goto e_inval; | 588 | goto e_inval; |
585 | if (optlen<1) | 589 | if (optlen < 1) |
586 | goto e_inval; | 590 | goto e_inval; |
587 | if (val == -1) | 591 | if (val == -1) |
588 | val = 1; | 592 | val = 1; |
@@ -591,7 +595,7 @@ static int do_ip_setsockopt(struct sock *sk, int level, | |||
591 | inet->mc_ttl = val; | 595 | inet->mc_ttl = val; |
592 | break; | 596 | break; |
593 | case IP_MULTICAST_LOOP: | 597 | case IP_MULTICAST_LOOP: |
594 | if (optlen<1) | 598 | if (optlen < 1) |
595 | goto e_inval; | 599 | goto e_inval; |
596 | inet->mc_loop = !!val; | 600 | inet->mc_loop = !!val; |
597 | break; | 601 | break; |
@@ -613,7 +617,8 @@ static int do_ip_setsockopt(struct sock *sk, int level, | |||
613 | } else { | 617 | } else { |
614 | memset(&mreq, 0, sizeof(mreq)); | 618 | memset(&mreq, 0, sizeof(mreq)); |
615 | if (optlen >= sizeof(struct in_addr) && | 619 | if (optlen >= sizeof(struct in_addr) && |
616 | copy_from_user(&mreq.imr_address, optval, sizeof(struct in_addr))) | 620 | copy_from_user(&mreq.imr_address, optval, |
621 | sizeof(struct in_addr))) | ||
617 | break; | 622 | break; |
618 | } | 623 | } |
619 | 624 | ||
@@ -677,7 +682,6 @@ static int do_ip_setsockopt(struct sock *sk, int level, | |||
677 | } | 682 | } |
678 | case IP_MSFILTER: | 683 | case IP_MSFILTER: |
679 | { | 684 | { |
680 | extern int sysctl_igmp_max_msf; | ||
681 | struct ip_msfilter *msf; | 685 | struct ip_msfilter *msf; |
682 | 686 | ||
683 | if (optlen < IP_MSFILTER_SIZE(0)) | 687 | if (optlen < IP_MSFILTER_SIZE(0)) |
@@ -831,7 +835,6 @@ static int do_ip_setsockopt(struct sock *sk, int level, | |||
831 | } | 835 | } |
832 | case MCAST_MSFILTER: | 836 | case MCAST_MSFILTER: |
833 | { | 837 | { |
834 | extern int sysctl_igmp_max_msf; | ||
835 | struct sockaddr_in *psin; | 838 | struct sockaddr_in *psin; |
836 | struct ip_msfilter *msf = NULL; | 839 | struct ip_msfilter *msf = NULL; |
837 | struct group_filter *gsf = NULL; | 840 | struct group_filter *gsf = NULL; |
@@ -849,9 +852,9 @@ static int do_ip_setsockopt(struct sock *sk, int level, | |||
849 | break; | 852 | break; |
850 | } | 853 | } |
851 | err = -EFAULT; | 854 | err = -EFAULT; |
852 | if (copy_from_user(gsf, optval, optlen)) { | 855 | if (copy_from_user(gsf, optval, optlen)) |
853 | goto mc_msf_out; | 856 | goto mc_msf_out; |
854 | } | 857 | |
855 | /* numsrc >= (4G-140)/128 overflow in 32 bits */ | 858 | /* numsrc >= (4G-140)/128 overflow in 32 bits */ |
856 | if (gsf->gf_numsrc >= 0x1ffffff || | 859 | if (gsf->gf_numsrc >= 0x1ffffff || |
857 | gsf->gf_numsrc > sysctl_igmp_max_msf) { | 860 | gsf->gf_numsrc > sysctl_igmp_max_msf) { |
@@ -879,7 +882,7 @@ static int do_ip_setsockopt(struct sock *sk, int level, | |||
879 | msf->imsf_fmode = gsf->gf_fmode; | 882 | msf->imsf_fmode = gsf->gf_fmode; |
880 | msf->imsf_numsrc = gsf->gf_numsrc; | 883 | msf->imsf_numsrc = gsf->gf_numsrc; |
881 | err = -EADDRNOTAVAIL; | 884 | err = -EADDRNOTAVAIL; |
882 | for (i=0; i<gsf->gf_numsrc; ++i) { | 885 | for (i = 0; i < gsf->gf_numsrc; ++i) { |
883 | psin = (struct sockaddr_in *)&gsf->gf_slist[i]; | 886 | psin = (struct sockaddr_in *)&gsf->gf_slist[i]; |
884 | 887 | ||
885 | if (psin->sin_family != AF_INET) | 888 | if (psin->sin_family != AF_INET) |
@@ -890,7 +893,7 @@ static int do_ip_setsockopt(struct sock *sk, int level, | |||
890 | gsf = NULL; | 893 | gsf = NULL; |
891 | 894 | ||
892 | err = ip_mc_msfilter(sk, msf, ifindex); | 895 | err = ip_mc_msfilter(sk, msf, ifindex); |
893 | mc_msf_out: | 896 | mc_msf_out: |
894 | kfree(msf); | 897 | kfree(msf); |
895 | kfree(gsf); | 898 | kfree(gsf); |
896 | break; | 899 | break; |
@@ -900,7 +903,7 @@ static int do_ip_setsockopt(struct sock *sk, int level, | |||
900 | break; | 903 | break; |
901 | 904 | ||
902 | case IP_FREEBIND: | 905 | case IP_FREEBIND: |
903 | if (optlen<1) | 906 | if (optlen < 1) |
904 | goto e_inval; | 907 | goto e_inval; |
905 | inet->freebind = !!val; | 908 | inet->freebind = !!val; |
906 | break; | 909 | break; |
@@ -957,6 +960,7 @@ int ip_setsockopt(struct sock *sk, int level, | |||
957 | #endif | 960 | #endif |
958 | return err; | 961 | return err; |
959 | } | 962 | } |
963 | EXPORT_SYMBOL(ip_setsockopt); | ||
960 | 964 | ||
961 | #ifdef CONFIG_COMPAT | 965 | #ifdef CONFIG_COMPAT |
962 | int compat_ip_setsockopt(struct sock *sk, int level, int optname, | 966 | int compat_ip_setsockopt(struct sock *sk, int level, int optname, |
@@ -986,13 +990,12 @@ int compat_ip_setsockopt(struct sock *sk, int level, int optname, | |||
986 | #endif | 990 | #endif |
987 | return err; | 991 | return err; |
988 | } | 992 | } |
989 | |||
990 | EXPORT_SYMBOL(compat_ip_setsockopt); | 993 | EXPORT_SYMBOL(compat_ip_setsockopt); |
991 | #endif | 994 | #endif |
992 | 995 | ||
993 | /* | 996 | /* |
994 | * Get the options. Note for future reference. The GET of IP options gets the | 997 | * Get the options. Note for future reference. The GET of IP options gets |
995 | * _received_ ones. The set sets the _sent_ ones. | 998 | * the _received_ ones. The set sets the _sent_ ones. |
996 | */ | 999 | */ |
997 | 1000 | ||
998 | static int do_ip_getsockopt(struct sock *sk, int level, int optname, | 1001 | static int do_ip_getsockopt(struct sock *sk, int level, int optname, |
@@ -1143,7 +1146,8 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname, | |||
1143 | return -EFAULT; | 1146 | return -EFAULT; |
1144 | } | 1147 | } |
1145 | err = ip_mc_gsfget(sk, &gsf, | 1148 | err = ip_mc_gsfget(sk, &gsf, |
1146 | (struct group_filter __user *)optval, optlen); | 1149 | (struct group_filter __user *)optval, |
1150 | optlen); | ||
1147 | release_sock(sk); | 1151 | release_sock(sk); |
1148 | return err; | 1152 | return err; |
1149 | } | 1153 | } |
@@ -1187,7 +1191,7 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname, | |||
1187 | } | 1191 | } |
1188 | release_sock(sk); | 1192 | release_sock(sk); |
1189 | 1193 | ||
1190 | if (len < sizeof(int) && len > 0 && val>=0 && val<=255) { | 1194 | if (len < sizeof(int) && len > 0 && val >= 0 && val <= 255) { |
1191 | unsigned char ucval = (unsigned char)val; | 1195 | unsigned char ucval = (unsigned char)val; |
1192 | len = 1; | 1196 | len = 1; |
1193 | if (put_user(len, optlen)) | 1197 | if (put_user(len, optlen)) |
@@ -1230,6 +1234,7 @@ int ip_getsockopt(struct sock *sk, int level, | |||
1230 | #endif | 1234 | #endif |
1231 | return err; | 1235 | return err; |
1232 | } | 1236 | } |
1237 | EXPORT_SYMBOL(ip_getsockopt); | ||
1233 | 1238 | ||
1234 | #ifdef CONFIG_COMPAT | 1239 | #ifdef CONFIG_COMPAT |
1235 | int compat_ip_getsockopt(struct sock *sk, int level, int optname, | 1240 | int compat_ip_getsockopt(struct sock *sk, int level, int optname, |
@@ -1262,11 +1267,5 @@ int compat_ip_getsockopt(struct sock *sk, int level, int optname, | |||
1262 | #endif | 1267 | #endif |
1263 | return err; | 1268 | return err; |
1264 | } | 1269 | } |
1265 | |||
1266 | EXPORT_SYMBOL(compat_ip_getsockopt); | 1270 | EXPORT_SYMBOL(compat_ip_getsockopt); |
1267 | #endif | 1271 | #endif |
1268 | |||
1269 | EXPORT_SYMBOL(ip_cmsg_recv); | ||
1270 | |||
1271 | EXPORT_SYMBOL(ip_getsockopt); | ||
1272 | EXPORT_SYMBOL(ip_setsockopt); | ||