diff options
author | Hannes Frederic Sowa <hannes@stressinduktion.org> | 2013-08-26 19:36:51 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-08-29 15:32:08 -0400 |
commit | b800c3b966bcf004bd8592293a49ed5cb7ea67a9 (patch) | |
tree | e10eef87a5dc18bc16745adde12dae6ff104240b /net/ipv6 | |
parent | a3a975b1dfe999f3e5d38d38f2387894c4332d96 (diff) |
ipv6: drop fragmented ndisc packets by default (RFC 6980)
This patch implements RFC6980: Drop fragmented ndisc packets by
default. If a fragmented ndisc packet is received the user is informed
that it is possible to disable the check.
Cc: Fernando Gont <fernando@gont.com.ar>
Cc: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/addrconf.c | 10 | ||||
-rw-r--r-- | net/ipv6/ndisc.c | 17 |
2 files changed, 27 insertions, 0 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 2d6d1793bbfe..a7183fc9bbc2 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -204,6 +204,7 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = { | |||
204 | .accept_source_route = 0, /* we do not accept RH0 by default. */ | 204 | .accept_source_route = 0, /* we do not accept RH0 by default. */ |
205 | .disable_ipv6 = 0, | 205 | .disable_ipv6 = 0, |
206 | .accept_dad = 1, | 206 | .accept_dad = 1, |
207 | .suppress_frag_ndisc = 1, | ||
207 | }; | 208 | }; |
208 | 209 | ||
209 | static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = { | 210 | static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = { |
@@ -241,6 +242,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = { | |||
241 | .accept_source_route = 0, /* we do not accept RH0 by default. */ | 242 | .accept_source_route = 0, /* we do not accept RH0 by default. */ |
242 | .disable_ipv6 = 0, | 243 | .disable_ipv6 = 0, |
243 | .accept_dad = 1, | 244 | .accept_dad = 1, |
245 | .suppress_frag_ndisc = 1, | ||
244 | }; | 246 | }; |
245 | 247 | ||
246 | /* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */ | 248 | /* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */ |
@@ -4188,6 +4190,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, | |||
4188 | array[DEVCONF_ACCEPT_DAD] = cnf->accept_dad; | 4190 | array[DEVCONF_ACCEPT_DAD] = cnf->accept_dad; |
4189 | array[DEVCONF_FORCE_TLLAO] = cnf->force_tllao; | 4191 | array[DEVCONF_FORCE_TLLAO] = cnf->force_tllao; |
4190 | array[DEVCONF_NDISC_NOTIFY] = cnf->ndisc_notify; | 4192 | array[DEVCONF_NDISC_NOTIFY] = cnf->ndisc_notify; |
4193 | array[DEVCONF_SUPPRESS_FRAG_NDISC] = cnf->suppress_frag_ndisc; | ||
4191 | } | 4194 | } |
4192 | 4195 | ||
4193 | static inline size_t inet6_ifla6_size(void) | 4196 | static inline size_t inet6_ifla6_size(void) |
@@ -5002,6 +5005,13 @@ static struct addrconf_sysctl_table | |||
5002 | .proc_handler = proc_dointvec | 5005 | .proc_handler = proc_dointvec |
5003 | }, | 5006 | }, |
5004 | { | 5007 | { |
5008 | .procname = "suppress_frag_ndisc", | ||
5009 | .data = &ipv6_devconf.suppress_frag_ndisc, | ||
5010 | .maxlen = sizeof(int), | ||
5011 | .mode = 0644, | ||
5012 | .proc_handler = proc_dointvec | ||
5013 | }, | ||
5014 | { | ||
5005 | /* sentinel */ | 5015 | /* sentinel */ |
5006 | } | 5016 | } |
5007 | }, | 5017 | }, |
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 04d31c2fbef1..41720feeaa64 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
@@ -1519,10 +1519,27 @@ static void pndisc_redo(struct sk_buff *skb) | |||
1519 | kfree_skb(skb); | 1519 | kfree_skb(skb); |
1520 | } | 1520 | } |
1521 | 1521 | ||
1522 | static bool ndisc_suppress_frag_ndisc(struct sk_buff *skb) | ||
1523 | { | ||
1524 | struct inet6_dev *idev = __in6_dev_get(skb->dev); | ||
1525 | |||
1526 | if (!idev) | ||
1527 | return true; | ||
1528 | if (IP6CB(skb)->flags & IP6SKB_FRAGMENTED && | ||
1529 | idev->cnf.suppress_frag_ndisc) { | ||
1530 | net_warn_ratelimited("Received fragmented ndisc packet. Carefully consider disabling suppress_frag_ndisc.\n"); | ||
1531 | return true; | ||
1532 | } | ||
1533 | return false; | ||
1534 | } | ||
1535 | |||
1522 | int ndisc_rcv(struct sk_buff *skb) | 1536 | int ndisc_rcv(struct sk_buff *skb) |
1523 | { | 1537 | { |
1524 | struct nd_msg *msg; | 1538 | struct nd_msg *msg; |
1525 | 1539 | ||
1540 | if (ndisc_suppress_frag_ndisc(skb)) | ||
1541 | return 0; | ||
1542 | |||
1526 | if (skb_linearize(skb)) | 1543 | if (skb_linearize(skb)) |
1527 | return 0; | 1544 | return 0; |
1528 | 1545 | ||