Date: Mon, 17 Feb 2003 10:14:55 -0300 (BRT) From: Fabio Vilan Dias <fabio@isec.com.br> To: FreeBSD-gnats-submit@FreeBSD.org Subject: bin/48378: [PATCH] User-PPP MTU/MRU - LCP Problem Message-ID: <200302171314.h1HDEtvN001044@astral.home.isec.com.br>
next in thread | raw e-mail | index | archive | help
>Number: 48378 >Category: bin >Synopsis: [PATCH] User-PPP MTU/MRU - LCP Problem >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Mon Feb 17 05:20:06 PST 2003 >Closed-Date: >Last-Modified: >Originator: Fabio Vilan Dias <fabio@isec.com.br> >Release: FreeBSD 4.7-STABLE i386 >Organization: ISec.com.br >Environment: System: FreeBSD astral.home.isec.com.br 4.7-STABLE FreeBSD 4.7-STABLE #0: Mon Feb 10 02:03:52 BRST 2003 root@astral.home.isec.com.br:/usr/obj/usr/src/sys/ASTRAL i386 >Description: There is a very specific bug in user-ppp LCP negotiation that if the peer NAKs and REJs our requested MRU and if it doesn't ask for any specific MRU, the standard compiled default MRU (1500) is assigned to the peer mru (variable lcp->his_mru in lcp.c), but if we're using PPPoE, for example, the his_mru will never be updated to the new 1492 value, so the tun0 MTU will be incorrectly set to 1500 instead of 1492. Even setting "set mru max 1492" and "set mtu max 1492" won't fix the problem and you'll end up with a tun0 mtu of 1500. You can see a ppp.log of this problem here: http://www.isec.com.br/ppp-lcp-bug/ppp-broken-mtu-1500.log >How-To-Repeat: Just try to simulate a LCP negotiation only NAKing and REJing the peer MRU request, and don't ask for any specific MRU value. Or you can follow the source code in lcp.c and see that when this behavior exists, the variable lcp->his_mru will be wrong if you have PPPoE (or use the "set mru max" and/or "set mtu max" command) because it's supposed to be updated when : a) you ack a peer req, b) you nak a peer req, c) your peer ack your req. But those things may not happen at all if the peer NAKs an REJk only, and if it doesn't ask for any MRU at all. >Fix: Here's a simple patch that checks if the lcp->his_mru is less than the mru after a MRU Reject, if so, we update the lcp->his_mru because it'll be used to set the tun0 MTU in bundle.c, so it MUST be updated to the proper value. Remember, again, that this bug will only happen if the peer only NAK, REJ and doesn't ask for any MRU from us... if it does, there's already some code that will update the lcp->his_mru to the proper value and the bug won't happen. Anyway this MUST be fixed. *** lcp.c.orig Mon Jan 6 15:51:17 2003 --- lcp.c Mon Feb 17 08:35:47 2003 *************** *** 786,791 **** --- 786,795 ---- lcp->want_mru = mru; break; case MODE_REJ: + /* Fabio Vilan: Fix his_mru if the peer has never ACK or REQ any MRU */ + if (lcp->his_mru > mru) + lcp->his_mru = mru; + lcp->his_reject |= (1 << opt->hdr.id); break; } >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200302171314.h1HDEtvN001044>