diff options
Diffstat (limited to 'net/ipv4/ip_sockglue.c')
-rw-r--r-- | net/ipv4/ip_sockglue.c | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index e982b5c1ee17..1e64dabbd232 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/icmp.h> | 23 | #include <linux/icmp.h> |
24 | #include <linux/inetdevice.h> | 24 | #include <linux/inetdevice.h> |
25 | #include <linux/netdevice.h> | 25 | #include <linux/netdevice.h> |
26 | #include <linux/slab.h> | ||
26 | #include <net/sock.h> | 27 | #include <net/sock.h> |
27 | #include <net/ip.h> | 28 | #include <net/ip.h> |
28 | #include <net/icmp.h> | 29 | #include <net/icmp.h> |
@@ -245,7 +246,7 @@ int ip_ra_control(struct sock *sk, unsigned char on, | |||
245 | { | 246 | { |
246 | struct ip_ra_chain *ra, *new_ra, **rap; | 247 | struct ip_ra_chain *ra, *new_ra, **rap; |
247 | 248 | ||
248 | if (sk->sk_type != SOCK_RAW || inet_sk(sk)->num == IPPROTO_RAW) | 249 | if (sk->sk_type != SOCK_RAW || inet_sk(sk)->inet_num == IPPROTO_RAW) |
249 | return -EINVAL; | 250 | return -EINVAL; |
250 | 251 | ||
251 | new_ra = on ? kmalloc(sizeof(*new_ra), GFP_KERNEL) : NULL; | 252 | new_ra = on ? kmalloc(sizeof(*new_ra), GFP_KERNEL) : NULL; |
@@ -451,7 +452,8 @@ static int do_ip_setsockopt(struct sock *sk, int level, | |||
451 | (1<<IP_TTL) | (1<<IP_HDRINCL) | | 452 | (1<<IP_TTL) | (1<<IP_HDRINCL) | |
452 | (1<<IP_MTU_DISCOVER) | (1<<IP_RECVERR) | | 453 | (1<<IP_MTU_DISCOVER) | (1<<IP_RECVERR) | |
453 | (1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) | | 454 | (1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) | |
454 | (1<<IP_PASSSEC) | (1<<IP_TRANSPARENT))) || | 455 | (1<<IP_PASSSEC) | (1<<IP_TRANSPARENT) | |
456 | (1<<IP_MINTTL))) || | ||
455 | optname == IP_MULTICAST_TTL || | 457 | optname == IP_MULTICAST_TTL || |
456 | optname == IP_MULTICAST_ALL || | 458 | optname == IP_MULTICAST_ALL || |
457 | optname == IP_MULTICAST_LOOP || | 459 | optname == IP_MULTICAST_LOOP || |
@@ -480,7 +482,7 @@ static int do_ip_setsockopt(struct sock *sk, int level, | |||
480 | case IP_OPTIONS: | 482 | case IP_OPTIONS: |
481 | { | 483 | { |
482 | struct ip_options *opt = NULL; | 484 | struct ip_options *opt = NULL; |
483 | if (optlen > 40 || optlen < 0) | 485 | if (optlen > 40) |
484 | goto e_inval; | 486 | goto e_inval; |
485 | err = ip_options_get_from_user(sock_net(sk), &opt, | 487 | err = ip_options_get_from_user(sock_net(sk), &opt, |
486 | optval, optlen); | 488 | optval, optlen); |
@@ -492,7 +494,7 @@ static int do_ip_setsockopt(struct sock *sk, int level, | |||
492 | if (sk->sk_family == PF_INET || | 494 | if (sk->sk_family == PF_INET || |
493 | (!((1 << sk->sk_state) & | 495 | (!((1 << sk->sk_state) & |
494 | (TCPF_LISTEN | TCPF_CLOSE)) && | 496 | (TCPF_LISTEN | TCPF_CLOSE)) && |
495 | inet->daddr != LOOPBACK4_IPV6)) { | 497 | inet->inet_daddr != LOOPBACK4_IPV6)) { |
496 | #endif | 498 | #endif |
497 | if (inet->opt) | 499 | if (inet->opt) |
498 | icsk->icsk_ext_hdr_len -= inet->opt->optlen; | 500 | icsk->icsk_ext_hdr_len -= inet->opt->optlen; |
@@ -575,7 +577,7 @@ static int do_ip_setsockopt(struct sock *sk, int level, | |||
575 | inet->hdrincl = val ? 1 : 0; | 577 | inet->hdrincl = val ? 1 : 0; |
576 | break; | 578 | break; |
577 | case IP_MTU_DISCOVER: | 579 | case IP_MTU_DISCOVER: |
578 | if (val < 0 || val > 3) | 580 | if (val < IP_PMTUDISC_DONT || val > IP_PMTUDISC_PROBE) |
579 | goto e_inval; | 581 | goto e_inval; |
580 | inet->pmtudisc = val; | 582 | inet->pmtudisc = val; |
581 | break; | 583 | break; |
@@ -936,6 +938,14 @@ mc_msf_out: | |||
936 | inet->transparent = !!val; | 938 | inet->transparent = !!val; |
937 | break; | 939 | break; |
938 | 940 | ||
941 | case IP_MINTTL: | ||
942 | if (optlen < 1) | ||
943 | goto e_inval; | ||
944 | if (val < 0 || val > 255) | ||
945 | goto e_inval; | ||
946 | inet->min_ttl = val; | ||
947 | break; | ||
948 | |||
939 | default: | 949 | default: |
940 | err = -ENOPROTOOPT; | 950 | err = -ENOPROTOOPT; |
941 | break; | 951 | break; |
@@ -1180,8 +1190,8 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname, | |||
1180 | if (inet->cmsg_flags & IP_CMSG_PKTINFO) { | 1190 | if (inet->cmsg_flags & IP_CMSG_PKTINFO) { |
1181 | struct in_pktinfo info; | 1191 | struct in_pktinfo info; |
1182 | 1192 | ||
1183 | info.ipi_addr.s_addr = inet->rcv_saddr; | 1193 | info.ipi_addr.s_addr = inet->inet_rcv_saddr; |
1184 | info.ipi_spec_dst.s_addr = inet->rcv_saddr; | 1194 | info.ipi_spec_dst.s_addr = inet->inet_rcv_saddr; |
1185 | info.ipi_ifindex = inet->mc_index; | 1195 | info.ipi_ifindex = inet->mc_index; |
1186 | put_cmsg(&msg, SOL_IP, IP_PKTINFO, sizeof(info), &info); | 1196 | put_cmsg(&msg, SOL_IP, IP_PKTINFO, sizeof(info), &info); |
1187 | } | 1197 | } |
@@ -1198,6 +1208,9 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname, | |||
1198 | case IP_TRANSPARENT: | 1208 | case IP_TRANSPARENT: |
1199 | val = inet->transparent; | 1209 | val = inet->transparent; |
1200 | break; | 1210 | break; |
1211 | case IP_MINTTL: | ||
1212 | val = inet->min_ttl; | ||
1213 | break; | ||
1201 | default: | 1214 | default: |
1202 | release_sock(sk); | 1215 | release_sock(sk); |
1203 | return -ENOPROTOOPT; | 1216 | return -ENOPROTOOPT; |