Updated: 2022/Sep/29

Please read Privacy Policy. It's for your privacy.

PPPOE(4)                     Device Drivers Manual                    PPPOE(4)

     pppoe - PPP over Ethernet protocol network interface

     pseudo-device pppoe

     The pppoe interface encapsulates Point-to-Point Protocol (PPP) packets
     inside Ethernet frames as defined by RFC2516.

     This is often used to connect a router via a DSL modem to an access
     concentrator.  The pppoe interface does not by itself transmit or receive
     frames, but needs an Ethernet interface to do so.  This Ethernet
     interface is connected to the pppoe interface via pppoectl(8).  The
     Ethernet interface needs to be marked UP, but does not need to have an IP

     There are two basic modes of operation, controlled via the link1 switch.
     The default mode, link1 not being set, tries to keep the configured
     session open all the time.  If the session is disconnected, a new
     connection attempt is started immediately.  The "dial on demand" mode,
     selected by setting link1, only establishes a connection when data is
     being sent to the interface.

     If the kernel is compiled with options PPPOE_SERVER, there are two modes
     of connection, controlled via the link0 switch.  The default mode, link0
     not being set, is client mode.  The "PPPoE server" mode, selected by
     setting link0, is to wait for incoming PPPoE session.

     Before a pppoe interface is usable, it needs to be configured.  The
     following steps are necessary:

        Create the interface.

        Connect an Ethernet interface.  This interface is used for the
         physical communication.  As noted above it must be marked UP, but
         need not have an IP address.

        Configure authentication.  The PPP session needs to identify the
         client to the peer.  For more details on the available options see

     This all is typically accomplished using an /etc/ifconfig.pppoe0 file.

   MSS/MTU problems
     If you are using a pppoe interface, you will have an unusually low MTU
     for today's Internet.  Combined with a lot of misconfigured sites (host
     using path MTU discovery behind a router blocking all ICMP traffic) this
     will often cause problems.  Connections to these servers will only work
     if your system advertises the right MSS in the TCP three way handshake.
     To get the right MSS, you need to set

           # Obey interface MTUs when calculating MSS

     in your /etc/sysctl.conf file.  This causes the calculated MSS to be
     based on the MTU of the interface via which the packet is sent.  This is
     always the right value if you are sure the answer to this packet will be
     received on the same interface (i.e., you only have one interface
     connected to the Internet.)

     Unfortunately this sysctl does not fix the MSS advertised by hosts in the
     network behind a pppoe connected router.  To fix this you need
     MSS-clamping, explained below.

   Setting up NAT with MSS-clamping
     Some systems behind misconfigured firewalls try to use Path-MTU-
     Discovery, while their firewall blocks all ICMP messages.  This is an
     illegal, but not uncommon, setup.  Typically you will have no chance to
     fix this (remote, outside of your control) setup.  And sometimes you will
     have to use such remote systems (to download data from them, or to do
     your online banking).

     Without special care systems as described above will not be able to send
     larger chunks of data to a system connected via pppoe.  But there is a
     workaround (some may call it cheating): pretend to not be able to handle
     large packets, by sending a small MSS (maximum segment size) option
     during initial TCP handshake.

     For connections originating from your pppoe connected machines, this is
     accomplished by setting the sysctl variable net.inet.tcp.mss_ifmtu to 1
     (see above).  For connections originating from systems behind your pppoe
     router, you need to set the mssclamp options in your NAT rules, like in
     this example of /etc/ipnat.conf:

           map pppoe0 -> 0/32 portmap tcp/udp 44000:49999 mssclamp 1440
           map pppoe0 -> 0/32 mssclamp 1440

     If you do not use NAT, you need to set up a 1:1 NAT rule, just to get the

           map pppoe0 x.x.x.x/24 -> 0/0 mssclamp 1440

     The above examples assume a MTU of 1492 bytes.  If the MTU on your PPPoE
     connection is smaller use the MTU - 52 bytes for clamping e.g. 1408 bytes
     for a MTU of 1460 bytes.  Note: The theoretically correct value for the
     above example would be 1452 bytes (it accounts for the smaller PPPoE MTU,
     the TCP header and the maximum of 0x40 bytes of TCP options) but it seems
     to not be sufficient in some cases.  Experiments conducted by various
     people have shown that clamping to the MSS values suggested above works

     A typical /etc/ifconfig.pppoe0 file looks like this:

           ! /sbin/ifconfig ne0 up
           ! /sbin/pppoectl -e ne0 $int
           ! /sbin/pppoectl $int myauthproto=pap myauthname=testcaller myauthsecret=donttell
           inet netmask 0xffffffff
           #! /sbin/route add default -iface
     The commented out call to route(8) may be omitted and the route added in
     the ip-up script called by ifwatchd(8) when the real IP address is known.
     This is easy in the "connect always" mode (link1 not set), but hard to
     accomplish in the "dial on demand" mode (link1 set).  In the latter case
     adding an iface route is an easy workaround.

     The pppoe interfaces operate completely inside the kernel, without any
     userland support.  Because of this, a special daemon is used to fire ip-
     up or down scripts to execute arbitrary code when the PPP session is
     established and addresses of the interface become available.  To enable
     the usage of /etc/ppp/ip-up and /etc/ppp/ip-down for this purpose, simply


     to /etc/rc.conf.  See ifwatchd(8) for details and parameters passed to
     these scripts.

     Since this is a PPP interface, the addresses assigned to the interface
     may change during PPP negotiation.  There is no fine grained control
     available for deciding which addresses are acceptable and which are not.
     For the local side and the remote address there is exactly one choice:
     hard coded address or wildcard.  If a real address is assigned to one
     side of the connection, PPP negotiation will only agree to exactly this
     address.  If one side is wildcarded, every address suggested by the peer
     will be accepted.

     To wildcard the local address set it to, to wildcard the remote
     address set it to  Wildcarding is not available (nor necessary)
     for IPv6 operation.

     A pppoe enabled kernel will not interfere with other PPPoE
     implementations running on the same machine.  Under special circumstances
     (details below) this is not desirable, so the pppoe driver can be told to
     kill all unknown PPPoE sessions received by the Ethernet interface used
     for a configured pppoe interface.  To do this, add the following to your
     kernel config file:


     and set the value of sysctl(7) variable net.pppoe.term_unknown to true.

     Note that this will break all userland PPPoE implementations using the
     same Ethernet interface!

     This option is only useful if you have a static IP address assigned and
     your ISP does not use LCP echo requests to monitor the link status.
     After a crash or power failure the peer device still tries to send data
     to the no longer active session on your computer, and might refuse to
     reestablish a new connection, because there already is an open session.
     On receipt of such packets, the pppoe driver with this option set will
     send a PADT packet (request to terminate the session).  The peer will
     immediately disconnect the orphaned session and allow a new one to be

     To enable pppoe server support in the kernel, use

           options PPPOE_SERVER

     As described above, this allows pppoe interfaces to be created and
     configured for incoming connections by setting the "link0" flag with

     ifwatchd(8), pppoectl(8)

     A Method for Transmitting PPP Over Ethernet (PPPoE), RFC, 2516, February

     Accommodating a Maximum Transit Unit/Maximum Receive Unit (MTU/MRU)
     Greater Than 1492 in the Point-to-Point Protocol over Ethernet (PPPoE),
     RFC, 4638, September 2006.

     The pppoe device appeared in NetBSD 1.6.

     The original PPPoE standard, RFC2516, requires a maximal MTU of 1492
     octets.  This value is the maximum conservative value possible, based on
     the PPPoE header size and the minimum frame size Ethernet interfaces are
     required to support.

     In practice most modern Ethernet interfaces support bigger frames, and
     many PPPoE services allow the use of (slightly) larger MTUs, to avoid the
     problems described above.

     This implementation allows MTU values as large as possible with the
     actual MTU of the used Ethernet interface and conforms to the enhancement
     to the PPPoE standard, RFC4638, to request the use of this larger MTU
     value with the PPPoE server.

     When using the wildcard address (as described above) it is
     important to specify the proper "netmask" to ifconfig(8), in most setups
     "0xffffffff".  If the netmask is unspecified, it will be set to 8 when is configured to the interface, and it will persist after

NetBSD 9.99                     August 7, 2016                     NetBSD 9.99