From 4b2f13a25133b115eb56771bd4a8e71a82aea968 Mon Sep 17 00:00:00 2001 From: Jeff Kirsher Date: Fri, 6 Dec 2013 06:28:48 -0800 Subject: sctp: Fix FSF address in file headers Several files refer to an old address for the Free Software Foundation in the file header comment. Resolve by replacing the address with the URL so that we do not have to keep updating the header comments anytime the address changes. CC: Vlad Yasevich CC: Neil Horman Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- net/sctp/protocol.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'net/sctp/protocol.c') diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 5e17092f4ad..19bd4c5bdae 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -23,9 +23,8 @@ * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with GNU CC; see the file COPYING. If not, write to - * the Free Software Foundation, 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * along with GNU CC; see the file COPYING. If not, see + * . * * Please send any bug reports or fixes you make to the * email address(es): -- cgit v1.2.3-70-g09d2 From 8d72651d86e9c702d37dd9ef9f084ce027af90a7 Mon Sep 17 00:00:00 2001 From: wangweidong Date: Mon, 23 Dec 2013 12:16:53 +0800 Subject: sctp: fix checkpatch errors with open brace '{' and trailing statements fix checkpatch errors below: ERROR: that open brace { should be on the previous line ERROR: open brace '{' following function declarations go on the next line ERROR: trailing statements should be on next line Signed-off-by: Wang Weidong Signed-off-by: David S. Miller --- net/sctp/auth.c | 3 +-- net/sctp/input.c | 6 ++---- net/sctp/protocol.c | 4 ++-- net/sctp/socket.c | 3 ++- net/sctp/ulpqueue.c | 3 ++- 5 files changed, 9 insertions(+), 10 deletions(-) (limited to 'net/sctp/protocol.c') diff --git a/net/sctp/auth.c b/net/sctp/auth.c index a594b3ca583..683c7d1b130 100644 --- a/net/sctp/auth.c +++ b/net/sctp/auth.c @@ -499,8 +499,7 @@ void sctp_auth_destroy_hmacs(struct crypto_hash *auth_hmacs[]) if (!auth_hmacs) return; - for (i = 0; i < SCTP_AUTH_NUM_HMACS; i++) - { + for (i = 0; i < SCTP_AUTH_NUM_HMACS; i++) { if (auth_hmacs[i]) crypto_free_hash(auth_hmacs[i]); } diff --git a/net/sctp/input.c b/net/sctp/input.c index b67e3d83b48..1f4eeb43fbd 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c @@ -180,8 +180,7 @@ int sctp_rcv(struct sk_buff *skb) * If a frame arrives on an interface and the receiving socket is * bound to another interface, via SO_BINDTODEVICE, treat it as OOTB */ - if (sk->sk_bound_dev_if && (sk->sk_bound_dev_if != af->skb_iif(skb))) - { + if (sk->sk_bound_dev_if && (sk->sk_bound_dev_if != af->skb_iif(skb))) { if (asoc) { sctp_association_put(asoc); asoc = NULL; @@ -610,8 +609,7 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info) if (ICMP_FRAG_NEEDED == code) { sctp_icmp_frag_needed(sk, asoc, transport, info); goto out_unlock; - } - else { + } else { if (ICMP_PROT_UNREACH == code) { sctp_icmp_proto_unreachable(sk, asoc, transport); diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 19bd4c5bdae..34b7726bcd7 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -1065,8 +1065,8 @@ static struct sctp_af sctp_af_inet = { #endif }; -struct sctp_pf *sctp_get_pf_specific(sa_family_t family) { - +struct sctp_pf *sctp_get_pf_specific(sa_family_t family) +{ switch (family) { case PF_INET: return sctp_pf_inet_specific; diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 9f42c605bfa..2df55647d4a 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -5443,7 +5443,8 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len, return -EFAULT; num: len = sizeof(struct sctp_authchunks) + num_chunks; - if (put_user(len, optlen)) return -EFAULT; + if (put_user(len, optlen)) + return -EFAULT; if (put_user(num_chunks, &p->gauth_number_of_chunks)) return -EFAULT; return 0; diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c index c700369d11f..5dc94117e9d 100644 --- a/net/sctp/ulpqueue.c +++ b/net/sctp/ulpqueue.c @@ -336,7 +336,8 @@ static struct sctp_ulpevent *sctp_make_reassembled_event(struct net *net, pos = f_frag->next; /* Get the last skb in the f_frag's frag_list if present. */ - for (last = list; list; last = list, list = list->next); + for (last = list; list; last = list, list = list->next) + ; /* Add the list of remaining fragments to the first fragments * frag_list. -- cgit v1.2.3-70-g09d2 From 8ed1dc44d3e9e8387a104b1ae8f92e9a3fbf1b1e Mon Sep 17 00:00:00 2001 From: Hannes Frederic Sowa Date: Thu, 9 Jan 2014 10:01:17 +0100 Subject: ipv4: introduce hardened ip_no_pmtu_disc mode This new ip_no_pmtu_disc mode only allowes fragmentation-needed errors to be honored by protocols which do more stringent validation on the ICMP's packet payload. This knob is useful for people who e.g. want to run an unmodified DNS server in a namespace where they need to use pmtu for TCP connections (as they are used for zone transfers or fallback for requests) but don't want to use possibly spoofed UDP pmtu information. Currently the whitelisted protocols are TCP, SCTP and DCCP as they check if the returned packet is in the window or if the association is valid. Cc: Eric Dumazet Cc: David Miller Cc: John Heffner Suggested-by: Florian Weimer Signed-off-by: Hannes Frederic Sowa Signed-off-by: David S. Miller --- Documentation/networking/ip-sysctl.txt | 13 ++++++++++++- include/net/protocol.h | 7 ++++++- net/dccp/ipv4.c | 1 + net/ipv4/af_inet.c | 1 + net/ipv4/icmp.c | 28 ++++++++++++++++++++++++---- net/sctp/protocol.c | 1 + 6 files changed, 45 insertions(+), 6 deletions(-) (limited to 'net/sctp/protocol.c') diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index 0d71fa962d8..c97932c88ea 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -26,7 +26,18 @@ ip_no_pmtu_disc - INTEGER discarded. Outgoing frames are handled the same as in mode 1, implicitly setting IP_PMTUDISC_DONT on every created socket. - Possible values: 0-2 + Mode 3 is a hardend pmtu discover mode. The kernel will only + accept fragmentation-needed errors if the underlying protocol + can verify them besides a plain socket lookup. Current + protocols for which pmtu events will be honored are TCP, SCTP + and DCCP as they verify e.g. the sequence number or the + association. This mode should not be enabled globally but is + only intended to secure e.g. name servers in namespaces where + TCP path mtu must still work but path MTU information of other + protocols should be discarded. If enabled globally this mode + could break other protocols. + + Possible values: 0-3 Default: FALSE min_pmtu - INTEGER diff --git a/include/net/protocol.h b/include/net/protocol.h index fbf7676c9a0..0e5f8665d7f 100644 --- a/include/net/protocol.h +++ b/include/net/protocol.h @@ -43,7 +43,12 @@ struct net_protocol { int (*handler)(struct sk_buff *skb); void (*err_handler)(struct sk_buff *skb, u32 info); unsigned int no_policy:1, - netns_ok:1; + netns_ok:1, + /* does the protocol do more stringent + * icmp tag validation than simple + * socket lookup? + */ + icmp_strict_tag_validation:1; }; #if IS_ENABLED(CONFIG_IPV6) diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index 88299c29101..22b5d818b20 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c @@ -989,6 +989,7 @@ static const struct net_protocol dccp_v4_protocol = { .err_handler = dccp_v4_err, .no_policy = 1, .netns_ok = 1, + .icmp_strict_tag_validation = 1, }; static const struct proto_ops inet_dccp_ops = { diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 6268a4751e6..ecd2c3f245c 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -1545,6 +1545,7 @@ static const struct net_protocol tcp_protocol = { .err_handler = tcp_v4_err, .no_policy = 1, .netns_ok = 1, + .icmp_strict_tag_validation = 1, }; static const struct net_protocol udp_protocol = { diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index fb3c5637199..0134663fdbc 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -668,6 +668,16 @@ static void icmp_socket_deliver(struct sk_buff *skb, u32 info) rcu_read_unlock(); } +static bool icmp_tag_validation(int proto) +{ + bool ok; + + rcu_read_lock(); + ok = rcu_dereference(inet_protos[proto])->icmp_strict_tag_validation; + rcu_read_unlock(); + return ok; +} + /* * Handle ICMP_DEST_UNREACH, ICMP_TIME_EXCEED, ICMP_QUENCH, and * ICMP_PARAMETERPROB. @@ -705,12 +715,22 @@ static void icmp_unreach(struct sk_buff *skb) case ICMP_PORT_UNREACH: break; case ICMP_FRAG_NEEDED: - if (net->ipv4.sysctl_ip_no_pmtu_disc == 2) { - goto out; - } else if (net->ipv4.sysctl_ip_no_pmtu_disc) { + /* for documentation of the ip_no_pmtu_disc + * values please see + * Documentation/networking/ip-sysctl.txt + */ + switch (net->ipv4.sysctl_ip_no_pmtu_disc) { + default: LIMIT_NETDEBUG(KERN_INFO pr_fmt("%pI4: fragmentation needed and DF set\n"), &iph->daddr); - } else { + break; + case 2: + goto out; + case 3: + if (!icmp_tag_validation(iph->protocol)) + goto out; + /* fall through */ + case 0: info = ntohs(icmph->un.frag.mtu); if (!info) goto out; diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 34b7726bcd7..7c161084f24 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -1030,6 +1030,7 @@ static const struct net_protocol sctp_protocol = { .err_handler = sctp_v4_err, .no_policy = 1, .netns_ok = 1, + .icmp_strict_tag_validation = 1, }; /* IPv4 address related functions. */ -- cgit v1.2.3-70-g09d2 From abfce3ef58b6a6c95de389f9d20047a05b10e484 Mon Sep 17 00:00:00 2001 From: wangweidong Date: Thu, 16 Jan 2014 16:25:19 +0800 Subject: sctp: remove the unnecessary assignment When go the right path, the status is 0, no need to assign it again. So just remove the assignment. Signed-off-by: Wang Weidong Acked-by: Neil Horman Signed-off-by: David S. Miller --- net/sctp/protocol.c | 1 - 1 file changed, 1 deletion(-) (limited to 'net/sctp/protocol.c') diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 7c161084f24..d6934dc8dcb 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -1461,7 +1461,6 @@ static __init int sctp_init(void) if (status) goto err_v6_add_protocol; - status = 0; out: return status; err_v6_add_protocol: -- cgit v1.2.3-70-g09d2 From 5bc1d1b4a261a865cbde65b1561748df5b9c724b Mon Sep 17 00:00:00 2001 From: wangweidong Date: Tue, 21 Jan 2014 15:44:12 +0800 Subject: sctp: remove macros sctp_bh_[un]lock_sock Redefined bh_[un]lock_sock to sctp_bh[un]lock_sock for user space friendly code which we haven't use in years, so removing them. Signed-off-by: Wang Weidong Signed-off-by: David S. Miller --- include/net/sctp/sctp.h | 4 ---- net/sctp/input.c | 18 +++++++++--------- net/sctp/protocol.c | 4 ++-- net/sctp/sm_sideeffect.c | 16 ++++++++-------- net/sctp/socket.c | 4 ++-- 5 files changed, 21 insertions(+), 25 deletions(-) (limited to 'net/sctp/protocol.c') diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h index ec18d306bad..a3353f45ef9 100644 --- a/include/net/sctp/sctp.h +++ b/include/net/sctp/sctp.h @@ -170,10 +170,6 @@ extern struct kmem_cache *sctp_bucket_cachep __read_mostly; * Section: Macros, externs, and inlines */ -/* sock lock wrappers. */ -#define sctp_bh_lock_sock(sk) bh_lock_sock(sk) -#define sctp_bh_unlock_sock(sk) bh_unlock_sock(sk) - /* SCTP SNMP MIB stats handlers */ #define SCTP_INC_STATS(net, field) SNMP_INC_STATS((net)->sctp.sctp_statistics, field) #define SCTP_INC_STATS_BH(net, field) SNMP_INC_STATS_BH((net)->sctp.sctp_statistics, field) diff --git a/net/sctp/input.c b/net/sctp/input.c index 94f7f44049a..f2e2cbd2d75 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c @@ -238,7 +238,7 @@ int sctp_rcv(struct sk_buff *skb) * bottom halves on this lock, but a user may be in the lock too, * so check if it is busy. */ - sctp_bh_lock_sock(sk); + bh_lock_sock(sk); if (sk != rcvr->sk) { /* Our cached sk is different from the rcvr->sk. This is @@ -248,14 +248,14 @@ int sctp_rcv(struct sk_buff *skb) * be doing something with the new socket. Switch our veiw * of the current sk. */ - sctp_bh_unlock_sock(sk); + bh_unlock_sock(sk); sk = rcvr->sk; - sctp_bh_lock_sock(sk); + bh_lock_sock(sk); } if (sock_owned_by_user(sk)) { if (sctp_add_backlog(sk, skb)) { - sctp_bh_unlock_sock(sk); + bh_unlock_sock(sk); sctp_chunk_free(chunk); skb = NULL; /* sctp_chunk_free already freed the skb */ goto discard_release; @@ -266,7 +266,7 @@ int sctp_rcv(struct sk_buff *skb) sctp_inq_push(&chunk->rcvr->inqueue, chunk); } - sctp_bh_unlock_sock(sk); + bh_unlock_sock(sk); /* Release the asoc/ep ref we took in the lookup calls. */ if (asoc) @@ -327,7 +327,7 @@ int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb) */ sk = rcvr->sk; - sctp_bh_lock_sock(sk); + bh_lock_sock(sk); if (sock_owned_by_user(sk)) { if (sk_add_backlog(sk, skb, sk->sk_rcvbuf)) @@ -337,7 +337,7 @@ int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb) } else sctp_inq_push(inqueue, chunk); - sctp_bh_unlock_sock(sk); + bh_unlock_sock(sk); /* If the chunk was backloged again, don't drop refs */ if (backloged) @@ -522,7 +522,7 @@ struct sock *sctp_err_lookup(struct net *net, int family, struct sk_buff *skb, goto out; } - sctp_bh_lock_sock(sk); + bh_lock_sock(sk); /* If too many ICMPs get dropped on busy * servers this needs to be solved differently. @@ -542,7 +542,7 @@ out: /* Common cleanup code for icmp/icmpv6 error handler. */ void sctp_err_finish(struct sock *sk, struct sctp_association *asoc) { - sctp_bh_unlock_sock(sk); + bh_unlock_sock(sk); sctp_association_put(asoc); } diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index d6934dc8dcb..4e1d0fcb028 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -634,10 +634,10 @@ static void sctp_addr_wq_timeout_handler(unsigned long arg) /* ignore bound-specific endpoints */ if (!sctp_is_ep_boundall(sk)) continue; - sctp_bh_lock_sock(sk); + bh_lock_sock(sk); if (sctp_asconf_mgmt(sp, addrw) < 0) pr_debug("%s: sctp_asconf_mgmt failed\n", __func__); - sctp_bh_unlock_sock(sk); + bh_unlock_sock(sk); } #if IS_ENABLED(CONFIG_IPV6) free_next: diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index ded6db66fb2..bd859154000 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c @@ -248,7 +248,7 @@ void sctp_generate_t3_rtx_event(unsigned long peer) /* Check whether a task is in the sock. */ - sctp_bh_lock_sock(asoc->base.sk); + bh_lock_sock(asoc->base.sk); if (sock_owned_by_user(asoc->base.sk)) { pr_debug("%s: sock is busy\n", __func__); @@ -275,7 +275,7 @@ void sctp_generate_t3_rtx_event(unsigned long peer) asoc->base.sk->sk_err = -error; out_unlock: - sctp_bh_unlock_sock(asoc->base.sk); + bh_unlock_sock(asoc->base.sk); sctp_transport_put(transport); } @@ -288,7 +288,7 @@ static void sctp_generate_timeout_event(struct sctp_association *asoc, struct net *net = sock_net(asoc->base.sk); int error = 0; - sctp_bh_lock_sock(asoc->base.sk); + bh_lock_sock(asoc->base.sk); if (sock_owned_by_user(asoc->base.sk)) { pr_debug("%s: sock is busy: timer %d\n", __func__, timeout_type); @@ -315,7 +315,7 @@ static void sctp_generate_timeout_event(struct sctp_association *asoc, asoc->base.sk->sk_err = -error; out_unlock: - sctp_bh_unlock_sock(asoc->base.sk); + bh_unlock_sock(asoc->base.sk); sctp_association_put(asoc); } @@ -367,7 +367,7 @@ void sctp_generate_heartbeat_event(unsigned long data) struct sctp_association *asoc = transport->asoc; struct net *net = sock_net(asoc->base.sk); - sctp_bh_lock_sock(asoc->base.sk); + bh_lock_sock(asoc->base.sk); if (sock_owned_by_user(asoc->base.sk)) { pr_debug("%s: sock is busy\n", __func__); @@ -392,7 +392,7 @@ void sctp_generate_heartbeat_event(unsigned long data) asoc->base.sk->sk_err = -error; out_unlock: - sctp_bh_unlock_sock(asoc->base.sk); + bh_unlock_sock(asoc->base.sk); sctp_transport_put(transport); } @@ -405,7 +405,7 @@ void sctp_generate_proto_unreach_event(unsigned long data) struct sctp_association *asoc = transport->asoc; struct net *net = sock_net(asoc->base.sk); - sctp_bh_lock_sock(asoc->base.sk); + bh_lock_sock(asoc->base.sk); if (sock_owned_by_user(asoc->base.sk)) { pr_debug("%s: sock is busy\n", __func__); @@ -427,7 +427,7 @@ void sctp_generate_proto_unreach_event(unsigned long data) asoc->state, asoc->ep, asoc, transport, GFP_ATOMIC); out_unlock: - sctp_bh_unlock_sock(asoc->base.sk); + bh_unlock_sock(asoc->base.sk); sctp_association_put(asoc); } diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 893aa56c91c..9e91d6e5df6 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -1511,7 +1511,7 @@ static void sctp_close(struct sock *sk, long timeout) * the net layers still may. */ local_bh_disable(); - sctp_bh_lock_sock(sk); + bh_lock_sock(sk); /* Hold the sock, since sk_common_release() will put sock_put() * and we have just a little more cleanup. @@ -1519,7 +1519,7 @@ static void sctp_close(struct sock *sk, long timeout) sock_hold(sk); sk_common_release(sk); - sctp_bh_unlock_sock(sk); + bh_unlock_sock(sk); local_bh_enable(); sock_put(sk); -- cgit v1.2.3-70-g09d2