NetBSD Documentation: Steps to connect via PPPoE (DSL)

Steps to connect via PPPoE (DSL)

Various notes

Steps to connect via PPPoE (DSL)


This document will describe a simple setup to connect via PPPoE (often used by DSL providers) to the Internet.

This document relates to NetBSD 1.6 and beyond, earlier releases do not include kernel PPPoE support. If you are using an older release of NetBSD, we suggest you install the net/rp-pppoe package from pkgsrc. This includes a command called adsl-setup that will set everything up for you.

PPPoE is an acronym for Point-to-Point Protocol over Ethernet. The typical setup is a DSL modem (which talks via the DSL line to your providers router, called Access Concentrator) and connects to your machine via a standard Ethernet. So you need an Ethernet interface, dedicated to talk to your DSL modem. Over this Ethernet interface a PPP connection is established.

At closer look this is weird. You got an Ethernet connection - why does your provider not run IP on top of it? Some do this (similar to cable modem connections), using DHCP to assign IP numbers to your system. Most providers do not do it, as PPPoE makes their lives a bit easier. It will make your live a bit harder, since PPPoE has an unusual small MTU, which prevents many systems behind misconfigured firewalls on the Internet to connect to you. A workaround is described below.

For the following examples we pick ne0 as the interface name for our Ethernet interface connecting to the DSL modem. Any other interface will do, of course.

Check your kernel

Before you can use PPPoE, you will need support for it in your kernel. To check it is there, run

 ifconfig -C 

and look for "pppoe" in the output. If it is not there, you need to add

  pseudo-device pppoe

to your kernel config file.

Do a manual test connection

Before setting up your machine to automatically connect, you should do a manual test connection. If anything fails, this will be the easy way to debug your setup.

First we create the pppoe interface itself and assign dummy IP numbers to it, which will be replaced later during PPP negotiation. For now we keep the interface marked down, as it is not ready yet:

  ifconfig pppoe0 create
  ifconfig pppoe0 inet down

Next we attach the pppoe interface to the Ethernet interface used to connect the DSL modem. This interface needs to be marked UP, but it does not need an IP address assigned.

  ifconfig ne0 up
  pppoectl -e ne0 pppoe0

Now you need your authentication data. Most providers offer some documentation how that data has to be formatted for Linux users, as the windows software often plays tricks and ask for provider specific things. Enter the authentication data via a command like this (note that you may need to protect special characters from the shell by using single quotes):

  pppoectl pppoe0 myauthproto=pap 'myauthname=XXX' 'myauthsecret=YYY' hisauthproto=none

where XXX is your username and YYY is your password. The hisauthproto=none prevents PPP from forcing the peer to authenticate, something many providers will refuse to do. If your provider supports the CHAP protocol, you may set myauthproto=chap.

We are now ready to test a first connection. Since something may be wrong, we will restrict retries for now:

  pppoectl pppoe0 max-auth-failure=1

Now activate the interface:

  ifconfig pppoe0 up

Nothing will happen (we have not enabled extended debugging messages). If everything works your PPPoE session will get connected, which you can verify with:

  # pppoectl -d pppoe0
  pppoe0: state = session
          Session ID: 0x254f
          PADI retries: 0
          PADR retries: 0

This example output shows a working setup. The PPPoE session has been established and is still in use (state = session). If the output shows non session state, you either have your authentication data wrong (see below) or the access concentrator did not answer or establish a session, which will show up as PADI or PADR retries. This means either your DSL setup is not working at all, or you need to specify a service name (via the -s option to pppoectl) or an access concentrator name (via the -a option to pppoectl). Your provider should have documented this need. See pppoectl(8) for details.

Assuming your PPPoE session got up, we can now check the IP negotiation of PPP:

  # ifconfig pppoe0
          inet -> netmask 0xff000000

This is a working connection, as we got a local ( and a remote ( IP address assigned (of course you will see different IP numbers). If you do not get a similar display, your PPP authentication data are wrong. Double check them and possibly correct them, by repeating the pppoectl setting them and starting again from there.

Setup a permanent connection

Now that you verified it works, you will want to configure the machine to start the connection automatically.

To have your machine connect automatically on boot, the things you tried before in the manual setup need to be encoded in some scripts and configuration files.

Depending on the contract you have you will choose a connection that is always on, used if you have a flat rate charging model.

If you pay for connection time, you will prefer an on demand connection.

Regardless, your ISP should have provided you with the IP addresses of your nameservers, which you should enter in /etc/resolv.conf. See resolv.conf(5) and the Networking FAQ for details.

Setup a line that is always connected

The aim of this setup is to keep the line open as long as possible, and in the event of disconnections (for whatever reason) to reconnect as soon as possible. This is the default mode of operation. Filling in the authentication data you used in the manual test connection above, create this files:

In /etc/ifconfig.pppoe0 put:

# Mark the physical interface used by this PPPoE interface up
! /sbin/ifconfig ne0 up
# Let $int use ne0 as its Ethernet interface
! /sbin/pppoectl -e ne0 $int
# Configure authentication
! /sbin/pppoectl $int myauthproto=pap 'myauthname=XXX' 'myauthsecret=YYY' hisauthproto=none
# Configure the PPPoE interface itself. These addresses are magic
# meaning we don't care about either address and let the remote
# ppp choose them. up

Make sure this file is only readable by root.

In /etc/ppp/ip-up put:

#! /bin/sh
/sbin/route add default $5

and make this file executable by root.

In /etc/ppp/ip-down put:

#! /bin/sh
/sbin/route delete default $5

and make this file executable by root too.

Finally, add this line to /etc/rc.conf:


You are done. Due to the missing link1 flag of the pppoe0 interface the connection will be established as soon as possible, and reestablished immediately after failure. Every time the connection comes up, the script /etc/ppp/ip-up will be executed, and every time it goes down /etc/ppp/ip-down. You can use these scripts for further cleanup (i.e., pruning stale NAT connections after the line dropped and you will be assigned a new dynamic IP number on reconnect) or kicking servers that need to know about that the connection is working again (i.e., a forwarding and caching named).

Note that on system boot the ifwatchd daemon (which executes the ip-up and ip-down scripts) is probably run quite late. The PPPoE connection will be established as soon as the ifconfig.pppoe0 file is run, early on network startup. The connection will come up immediately, but the /etc/ppp/ip-up script will not yet be run. When ifwatchd(8) starts, it will execute the ip-up script if the connection is already up. Many network daemons will start in between, and due to the missing default route not be able to connect to the outside Internet. Kicking these daemons in the ip-up script is a good idea (and will take care of most problems those daemons cause when using dynamic IP addresses as well). A typical example is to flush all NAT connections and restart named and ntpd:

#! /bin/sh
/sbin/route add default $5
/etc/rc.d/ntpd restart
/etc/rc.d/named restart

Setup a line connecting only on demand

This connection setup will establish the PPPoE connection only when traffic tries to use it. It will disconnect automatically after a configurable idle period.

The main differences to a permanent connection configuration are

  • The link1 flag on the pppoe0 interface

  • The idle timeout (set to 60 seconds in the example below) to make the line drop after some time without traffic

  • The routing configuration, as you need to root packets to the pppoe0 interface even when the connection is not established.

Put this in /etc/ifconfig.pppoe0:

# Mark the physical interface used by this PPPoE interface up
! /sbin/ifconfig ne0 up
# Let $int use ne0 as its Ethernet interface
! /sbin/pppoectl -e ne0 $int
# Configure authentication
! /sbin/pppoectl $int idle-timeout=60 myauthproto=pap 'myauthname=XXX' 'myauthsecret=YYY' hisauthproto=none
# Configure the PPPoE interface itself. These addresses are magic
# meaning we don't care about either address and let the remote
# ppp choose them. link1 up
! /sbin/route add default -iface

It is not necessary to use ifwatchd in this configuration, as the default route is a permanent one already set by above config file. If you need notifications of changing IP addresses or the connection dropping or reestablishing, you may configure ifwatchd and use /etc/ppp/ip-up and /etc/ppp/ip-down. See the permanent connection case for an example (but do not change the default route).

Setup 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, i.e. by adding this

# Obey interface MTUs when calculating MSS

to /etc/sysctl.conf. For connections originating from systems behind your PPPoE router, you need to set the mssclamp options in your NAT rules, like in this example /etc/ipnat.conf:

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

See the NetBSD Networking FAQ for more information about configuring NAT.

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

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 best.

Various notes

General information on T-Online account names

If you want to dial-in into the german ISP T-Online, the two most tricky things are getting the correct username, and using a proper chat-script. See the NetBSD Network FAQ for a general description of how to set up PPP.

  1. Your login name at T-Online consists of three parts, glued together:

    1. Anschlußkennung: 12 digit number (AAAAAAAAAAAA), e.g. 000120123456

    2. T-Online Nr: 12 digit number (TTTTTTTTTTTT), e.g. 3200123456. Often starts with "32"; if yours is less than 12 digits, add a '#')

    3. Mitbenutzer-Nummer, usually "0001" (MMMM), e.g. 0001

    Your login is now all three parts put in a row, with no separator ("AAAAAAAAAAAATTTTTTTTTTTTMMMM"), e.g. 0001201234563200123456#0001. Use this for the "user"-line in your PPP options file.

  2. In the chat-script, you need to pay attention to send a "." after the modem reported a CONNECT:

    ABORT BUSY    '' AT
                  OK ATZ
                  OK ATL1
                  OK ATD0191011
                  CONNECT '.'

    Without this trailing dot, you may be disconnected immediately without an answer from the T-Online dialin server after your side has sent out the first LCP ConfReq frame.

  3. If you want to use T-Online with T-DSL, be sure to append "" for the login, e.g. "".

Here are some (german language) links with more information (don't let yourself distract that most of them are not for NetBSD - being just another Unix-like operating system, these tips usually apply to NetBSD as well):

Setting up a PPPoE server

What do you do if you want to test PPPoE, but don't have a DSL line handy? You set up your own PPPoE server, of course. The pppoe(4) manpage contains pretty much all the information needed:

  • Make sure you have "options PPPOE_SERVER" in your kernel

  • On the server, set the link0 flag on the pppoe0 interface

  • For the local and remote IP address, set what you want to use locally and remote. For example, if you want your server to use and your client to use, use " up" as last line of your /etc/ifconfig.pppoe0 file, instead of " up".

  • For authentication, be sure to replace the "my" from the client with "his" on the server - "myauthproto" on the client has to match "hisauthprot" on the server, and so on.

Here is a full server /etc/ifconfig.pppoe0 file:

# Server:
! /sbin/ifconfig re1 up
! /sbin/pppoectl -e re1 $int
! /sbin/pppoectl $int hisauthproto=pap hisauthname='' hisauthsecret='oink' myauthproto=none up

Here is the matching client's /etc/ifconfig.pppoe0 file:

! /sbin/ifconfig re1 up
! /sbin/pppoectl -e re1 $int
! /sbin/pppoectl $int myauthproto=pap '' 'myauthsecret=oink' hisauthproto=none up