NetBSD Documentation: Steps to connect via PPPoE (DSL)
- Check your kernel
- Do a manual test connection
- Setup a permanent connection
- Setup a line that is always connected
- Setup a line connecting only on demand
- Setup NAT with MSS-clamping
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
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.
Before you can use PPPoE, you will need support for it in your kernel. To check it is there, run
and look for "pppoe" in the output. If it is not there, you need to add
to your kernel config file.
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 0.0.0.0 0.0.0.1 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
XXX is your username and
YYY is your password.
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
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
-s option to pppoectl) or an access concentrator name (via
-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 pppoe0: flags=8851<UP,POINTOPOINT,RUNNING,SIMPLEX,MULTICAST> mtu 1492 inet 220.127.116.11 -> 18.104.22.168 netmask 0xff000000
This is a working connection, as we got a local (22.214.171.124) and a remote (126.96.36.199) 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.
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.
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:
create # 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. 0.0.0.0 0.0.0.1 up
Make sure this file is only readable by root.
#! /bin/sh /sbin/route add default $5
and make this file executable by root.
#! /bin/sh /sbin/route delete default $5
and make this file executable by root too.
Finally, add this line to
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
/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
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
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
link1flag 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
create # 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. 0.0.0.0 0.0.0.1 link1 up ! /sbin/route add default -iface 0.0.0.1
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
See the permanent connection case for an
example (but do not change the default route).
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 net.inet.tcp.mss_ifmtu=1
/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
map pppoe0 192.168.1.0/24 -> 0/32 portmap tcp/udp 44000:49999 mssclamp 1440 map pppoe0 192.168.1.0/24 -> 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.
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.
Your login name at T-Online consists of three parts, glued together:
Anschlußkennung: 12 digit number (AAAAAAAAAAAA), e.g. 000120123456
T-Online Nr: 12 digit number (TTTTTTTTTTTT), e.g. 3200123456. Often starts with "32"; if yours is less than 12 digits, add a '#')
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.
In the chat-script, you need to pay attention to send a "
." after the modem reported a
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.
If you want to use T-Online with T-DSL, be sure to append "
@t-online.de" 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):
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 10.3.3.1 and your client to use 10.3.3.2, use "10.3.3.1 10.3.3.2 up" as last line of your /etc/ifconfig.pppoe0 file, instead of "0.0.0.0 0.0.0.1 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:
create # Server: link0 # ! /sbin/ifconfig re1 up ! /sbin/pppoectl -e re1 $int ! /sbin/pppoectl $int hisauthproto=pap firstname.lastname@example.org' hisauthsecret='oink' myauthproto=none 10.3.3.1 10.3.3.3 up
Here is the matching client's /etc/ifconfig.pppoe0 file:
create ! /sbin/ifconfig re1 up ! /sbin/pppoectl -e re1 $int ! /sbin/pppoectl $int myauthproto=pap 'email@example.com' 'myauthsecret=oink' hisauthproto=none 0.0.0.0 0.0.0.1 up