From owner-freebsd-bugs@FreeBSD.ORG Wed Sep 18 19:30:01 2013 Return-Path: Delivered-To: freebsd-bugs@smarthost.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id 66AAFFF6 for ; Wed, 18 Sep 2013 19:30:01 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:1900:2254:206c::16:87]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 45A2F2102 for ; Wed, 18 Sep 2013 19:30:01 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.7/8.14.7) with ESMTP id r8IJU1Gc075447 for ; Wed, 18 Sep 2013 19:30:01 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.7/8.14.7/Submit) id r8IJU1Se075446; Wed, 18 Sep 2013 19:30:01 GMT (envelope-from gnats) Resent-Date: Wed, 18 Sep 2013 19:30:01 GMT Resent-Message-Id: <201309181930.r8IJU1Se075446@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Eugene Grosbein Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id 67E08E1D for ; Wed, 18 Sep 2013 19:22:27 +0000 (UTC) (envelope-from eugen@eg.sd.rdtc.ru) Received: from eg.sd.rdtc.ru (eg.sd.rdtc.ru [IPv6:2a03:3100:c:13::5]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id B11EC20C3 for ; Wed, 18 Sep 2013 19:22:25 +0000 (UTC) Received: from eg.sd.rdtc.ru (localhost [127.0.0.1]) by eg.sd.rdtc.ru (8.14.7/8.14.7) with ESMTP id r8IJMLPQ064603; Thu, 19 Sep 2013 02:22:21 +0700 (NOVT) (envelope-from eugen@eg.sd.rdtc.ru) Received: (from eugen@localhost) by eg.sd.rdtc.ru (8.14.7/8.14.7/Submit) id r8IJMFOV064602; Thu, 19 Sep 2013 02:22:15 +0700 (NOVT) (envelope-from eugen) Message-Id: <201309181922.r8IJMFOV064602@eg.sd.rdtc.ru> Date: Thu, 19 Sep 2013 02:22:15 +0700 (NOVT) From: Eugene Grosbein To: FreeBSD-gnats-submit@freebsd.org X-Send-Pr-Version: 3.114 Subject: kern/182212: [patch] [ng_mppc] ng_mppc(4) blocks on network errors unconditionaly X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 18 Sep 2013 19:30:01 -0000 >Number: 182212 >Category: kern >Synopsis: [patch] [ng_mppc] ng_mppc(4) blocks on network errors unconditionaly >Confidential: no >Severity: serious >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Wed Sep 18 19:30:00 UTC 2013 >Closed-Date: >Last-Modified: >Originator: Eugene Grosbein >Release: FreeBSD 8.4-STABLE amd64 >Organization: RDTC JSC >Environment: System: FreeBSD eg.sd.rdtc.ru 8.4-STABLE FreeBSD 8.4-STABLE #2 r251830M: Mon Jun 17 18:05:24 NOVT 2013 root@eg.sd.rdtc.ru:/usr/local/obj/usr/local/src/sys/EG amd64 >Description: Netgraph node ng_mppc(4) is used by mpd daemon to implement MPPC/MPPE for Compression Control Protocol (CCP) used with various PPP tunnels (pptp/l2tp/etc.) This node blocks itself when "too many" packets got dropped in between PPP peers and MPPE should do "re-keying". The threshold is hardcoded in its code. The code considers "re-keying" as too CPU intensive task. Thus, it tries to protect the box from DoS. This code dates back to year 2000. When such event occcurs, PPP tunnel hangs: CCP does not get reset, IP packets cannot pass tunnel anymore but system interface "looks fine". These days mpd runs on multi-MHZ and GHZ boxes and may be used not for BRAS'es with lots of tunnels but to form VPN between a pair of routers. In the latter case, manual reset of mpd link is required to revive VPN tunnel. >How-To-Repeat: Run PPtP or L2TP tunnel between two mpd servers over WAN link with non-zero amount of packet drops and/or packet rearrangements having MPPC/MPPE enabled. Soon, you will get a message in the dmesg buffer similar to: ng_mppc_decompress: too many (4094) packets dropped, disabling node 0xc7020900! Then tunnel just hangs until manually restarted as LCP echos cannot detect this problem. >Fix: Let's system administrator decides if such behavour is needed. The following patch introduces new sysctl subtree "net.graph.mppe" with three read/write sysctls (each one is loader tunnable too): net.graph.mppe.block_on_max_rekey - non-zero value means current behavour, zero disables node block; net.graph.mppe.mppe_log_max_rekey - non-zero value permits to write messages to the log to notify of described event; net.graph.mppe.max_rekey - allows to change the threshold. By default, node block is prohibited and mpd just resets CCP and tunnel continues to work. Mpd writes a line like this to its log: CCP: SendResetReq #3 link 0 (Opened) At the another side, next line is written to mpd log: CCP: rec'd Reset Request #3 (Opened) --- sys/netgraph/ng_mppc.c.orig 2013-04-07 01:07:27.000000000 +0700 +++ sys/netgraph/ng_mppc.c 2013-09-19 01:54:54.000000000 +0700 @@ -55,6 +55,7 @@ #include #include #include +#include #include #include @@ -107,6 +108,23 @@ */ #define MPPE_MAX_REKEY 1000 +SYSCTL_NODE(_net_graph, OID_AUTO, mppe, CTLFLAG_RW, 0, "MPPE"); + +static int mppe_block_on_max_rekey = 0; +TUNABLE_INT("net.graph.mppe.block_on_max_rekey", &mppe_block_on_max_rekey); +SYSCTL_INT(_net_graph_mppe, OID_AUTO, block_on_max_rekey, CTLFLAG_RW, + &mppe_block_on_max_rekey, 0, "Block node on max MPPE key re-calculations"); + +static int mppe_log_max_rekey = 1; +TUNABLE_INT("net.graph.mppe.log_max_rekey", &mppe_log_max_rekey); +SYSCTL_INT(_net_graph_mppe, OID_AUTO, log_max_rekey, CTLFLAG_RW, + &mppe_log_max_rekey, 0, "Log max MPPE key re-calculations event"); + +static int mppe_max_rekey = MPPE_MAX_REKEY; +TUNABLE_INT("net.graph.mppe.max_rekey", &mppe_max_rekey); +SYSCTL_INT(_net_graph_mppe, OID_AUTO, max_rekey, CTLFLAG_RW, + &mppe_max_rekey, 0, "Maximum number of MPPE key re-calculations"); + /* MPPC packet header bits */ #define MPPC_FLAG_FLUSHED 0x8000 /* xmitter reset state */ #define MPPC_FLAG_RESTART 0x4000 /* compress history restart */ @@ -651,12 +669,23 @@ /* How many times are we going to have to re-key? */ rekey = ((d->cfg.bits & MPPE_STATELESS) != 0) ? numLost : (numLost / (MPPE_UPDATE_MASK + 1)); - if (rekey > MPPE_MAX_REKEY) { - log(LOG_ERR, "%s: too many (%d) packets" - " dropped, disabling node %p!", - __func__, numLost, node); + if (rekey > mppe_max_rekey) { + if (mppe_block_on_max_rekey) { + if (mppe_log_max_rekey) { + log(LOG_ERR, "%s: too many (%d) packets" + " dropped, disabling node %p!\n", + __func__, numLost, node); + } priv->recv.cfg.enable = 0; goto failed; + } else { + if (mppe_log_max_rekey) { + log(LOG_ERR, "%s: %d packets" + " dropped, node %p\n", + __func__, numLost, node); + } + goto failed; + } } /* Re-key as necessary to catch up to peer */ >Release-Note: >Audit-Trail: >Unformatted: