diff options
-rw-r--r-- | Documentation/networking/ip-sysctl.txt | 4 | ||||
-rw-r--r-- | include/linux/ipv6.h | 2 | ||||
-rw-r--r-- | net/ipv6/addrconf.c | 11 | ||||
-rw-r--r-- | net/ipv6/ip6_input.c | 3 | ||||
-rw-r--r-- | net/ipv6/ip6_output.c | 7 |
5 files changed, 26 insertions, 1 deletions
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index 71c7bea97160..dae980e8f1b9 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt | |||
@@ -1025,6 +1025,10 @@ max_addresses - INTEGER | |||
1025 | autoconfigured addresses. | 1025 | autoconfigured addresses. |
1026 | Default: 16 | 1026 | Default: 16 |
1027 | 1027 | ||
1028 | disable_ipv6 - BOOLEAN | ||
1029 | Disable IPv6 operation. | ||
1030 | Default: FALSE (enable IPv6 operation) | ||
1031 | |||
1028 | icmp/*: | 1032 | icmp/*: |
1029 | ratelimit - INTEGER | 1033 | ratelimit - INTEGER |
1030 | Limit the maximal rates for sending ICMPv6 packets. | 1034 | Limit the maximal rates for sending ICMPv6 packets. |
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index cde056e08181..d9d7f9b69eb4 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h | |||
@@ -163,6 +163,7 @@ struct ipv6_devconf { | |||
163 | #ifdef CONFIG_IPV6_MROUTE | 163 | #ifdef CONFIG_IPV6_MROUTE |
164 | __s32 mc_forwarding; | 164 | __s32 mc_forwarding; |
165 | #endif | 165 | #endif |
166 | __s32 disable_ipv6; | ||
166 | void *sysctl; | 167 | void *sysctl; |
167 | }; | 168 | }; |
168 | 169 | ||
@@ -194,6 +195,7 @@ enum { | |||
194 | DEVCONF_OPTIMISTIC_DAD, | 195 | DEVCONF_OPTIMISTIC_DAD, |
195 | DEVCONF_ACCEPT_SOURCE_ROUTE, | 196 | DEVCONF_ACCEPT_SOURCE_ROUTE, |
196 | DEVCONF_MC_FORWARDING, | 197 | DEVCONF_MC_FORWARDING, |
198 | DEVCONF_DISABLE_IPV6, | ||
197 | DEVCONF_MAX | 199 | DEVCONF_MAX |
198 | }; | 200 | }; |
199 | 201 | ||
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 8b6875f02039..8c5cff50bbed 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -183,6 +183,7 @@ struct ipv6_devconf ipv6_devconf __read_mostly = { | |||
183 | #endif | 183 | #endif |
184 | .proxy_ndp = 0, | 184 | .proxy_ndp = 0, |
185 | .accept_source_route = 0, /* we do not accept RH0 by default. */ | 185 | .accept_source_route = 0, /* we do not accept RH0 by default. */ |
186 | .disable_ipv6 = 0, | ||
186 | }; | 187 | }; |
187 | 188 | ||
188 | static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = { | 189 | static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = { |
@@ -215,6 +216,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = { | |||
215 | #endif | 216 | #endif |
216 | .proxy_ndp = 0, | 217 | .proxy_ndp = 0, |
217 | .accept_source_route = 0, /* we do not accept RH0 by default. */ | 218 | .accept_source_route = 0, /* we do not accept RH0 by default. */ |
219 | .disable_ipv6 = 0, | ||
218 | }; | 220 | }; |
219 | 221 | ||
220 | /* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */ | 222 | /* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */ |
@@ -3657,6 +3659,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, | |||
3657 | #ifdef CONFIG_IPV6_MROUTE | 3659 | #ifdef CONFIG_IPV6_MROUTE |
3658 | array[DEVCONF_MC_FORWARDING] = cnf->mc_forwarding; | 3660 | array[DEVCONF_MC_FORWARDING] = cnf->mc_forwarding; |
3659 | #endif | 3661 | #endif |
3662 | array[DEVCONF_DISABLE_IPV6] = cnf->disable_ipv6; | ||
3660 | } | 3663 | } |
3661 | 3664 | ||
3662 | static inline size_t inet6_if_nlmsg_size(void) | 3665 | static inline size_t inet6_if_nlmsg_size(void) |
@@ -4216,6 +4219,14 @@ static struct addrconf_sysctl_table | |||
4216 | }, | 4219 | }, |
4217 | #endif | 4220 | #endif |
4218 | { | 4221 | { |
4222 | .ctl_name = CTL_UNNUMBERED, | ||
4223 | .procname = "disable_ipv6", | ||
4224 | .data = &ipv6_devconf.disable_ipv6, | ||
4225 | .maxlen = sizeof(int), | ||
4226 | .mode = 0644, | ||
4227 | .proc_handler = &proc_dointvec, | ||
4228 | }, | ||
4229 | { | ||
4219 | .ctl_name = 0, /* sentinel */ | 4230 | .ctl_name = 0, /* sentinel */ |
4220 | } | 4231 | } |
4221 | }, | 4232 | }, |
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c index 34e5a96623ae..ea81c614dde2 100644 --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c | |||
@@ -71,7 +71,8 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt | |||
71 | 71 | ||
72 | IP6_INC_STATS_BH(idev, IPSTATS_MIB_INRECEIVES); | 72 | IP6_INC_STATS_BH(idev, IPSTATS_MIB_INRECEIVES); |
73 | 73 | ||
74 | if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) { | 74 | if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL || |
75 | !idev || unlikely(idev->cnf.disable_ipv6)) { | ||
75 | IP6_INC_STATS_BH(idev, IPSTATS_MIB_INDISCARDS); | 76 | IP6_INC_STATS_BH(idev, IPSTATS_MIB_INDISCARDS); |
76 | rcu_read_unlock(); | 77 | rcu_read_unlock(); |
77 | goto out; | 78 | goto out; |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 871bdec09edb..0981c1ef3057 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -173,6 +173,13 @@ static inline int ip6_skb_dst_mtu(struct sk_buff *skb) | |||
173 | 173 | ||
174 | int ip6_output(struct sk_buff *skb) | 174 | int ip6_output(struct sk_buff *skb) |
175 | { | 175 | { |
176 | struct inet6_dev *idev = ip6_dst_idev(skb->dst); | ||
177 | if (unlikely(idev->cnf.disable_ipv6)) { | ||
178 | IP6_INC_STATS(idev, IPSTATS_MIB_OUTDISCARDS); | ||
179 | kfree_skb(skb); | ||
180 | return 0; | ||
181 | } | ||
182 | |||
176 | if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) || | 183 | if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) || |
177 | dst_allfrag(skb->dst)) | 184 | dst_allfrag(skb->dst)) |
178 | return ip6_fragment(skb, ip6_output2); | 185 | return ip6_fragment(skb, ip6_output2); |