NAME
pppoe —
PPP over Ethernet protocol
network interface
SYNOPSIS
pseudo-device pppoe
DESCRIPTION
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 address.
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 pppoectl(8).
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
net.inet.tcp.mss_ifmtu=1
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 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
If you do not use NAT, you need to set up 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.
EXAMPLES
A typical
/etc/ifconfig.pppoe0 file looks like this:
create
! /sbin/ifconfig ne0 up
! /sbin/pppoectl -e ne0 $int
! /sbin/pppoectl $int myauthproto=pap myauthname=testcaller myauthsecret=donttell
inet 0.0.0.0 0.0.0.1 netmask 0xffffffff
#! /sbin/route add default -iface 0.0.0.1
up
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 add
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 0.0.0.0, to wildcard the remote address
set it to 0.0.0.1. Wildcarding is not available (nor necessary) for IPv6
operation.
OPTIONS
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:
options
PPPOE_TERM_UNKNOWN_SESSIONS
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 established.
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
ifconfig(8).
SEE ALSO
ifwatchd(8),
pppoectl(8)
A Method for Transmitting PPP Over Ethernet
(PPPoE), RFC, 2516,
February 1999.
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.
HISTORY
The
pppoe device appeared in
NetBSD
1.6.
DEVIATIONS FROM STANDARD
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.
BUGS
When using the wildcard address 0.0.0.0 (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 0.0.0.0 is configured to the interface,
and it will persist after negotiation.