Bug 199144

Summary: [patch] ppp(8): spontaneous connectivity losses when using MPPE in the stateless mode
Product: Base System Reporter: Alexander Zagrebin <alex>
Component: binAssignee: freebsd-bugs (Nobody) <bugs>
Status: New ---    
Severity: Affects Some People Keywords: patch
Priority: ---    
Version: 10.1-RELEASE   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
patch none

Description Alexander Zagrebin 2015-04-03 10:19:33 UTC
Created attachment 155154 [details]
patch

I'm using PPPoE connection to my ISP.
I've noticed, that there are spontaneous connectivity losses, when MPPE in
the stateless mode is used for data encryption. During such losses the ppp.log
contains a tons of messages like:
...
ppp[83292]: tun0: Phase: Unknown protocol 0xd198 (unrecognised protocol)
ppp[83292]: tun0: Phase: Unknown protocol 0xfbd7 (unrecognised protocol)
ppp[83292]: tun0: Phase: Unknown protocol 0x600e (unrecognised protocol)
ppp[83292]: tun0: Phase: Unknown protocol 0x4aef (unrecognised protocol)
ppp[83292]: tun0: Phase: Unknown protocol 0x2ed7 (unrecognised protocol)
ppp[83292]: tun0: Phase: Unknown protocol 0xc6a1 (unrecognised protocol)
ppp[83292]: tun0: Phase: Unknown protocol 0x4511 (unrecognised protocol)
ppp[83292]: tun0: Phase: Unknown protocol 0x0166 (unrecognised protocol)
ppp[83292]: tun0: Phase: Unknown protocol 0x36a2 (unrecognised protocol)
ppp[83292]: tun0: Phase: Unknown protocol 0xa294 (unrecognised protocol)
...
At the same time the ppp peers successfuly exchanges with a LCP keepalive
packets, so formally the link is alive and there is the one workaround only -
to restart ppp.

After doing some debugging I've found that this issue occurs because MPPE
keys, used for encryption/decryption, goes out of sync.
To ensure that a keys are synchronized, ppp tracks the coherency count,
which is a part of a MPPE-encrypted packet. When packet with an unexpected
coherency count is received, ppp assumes that some packets are lost and
performs a corresponding number of key changes to synchronize the key.
This approach works fine for serial link, but for PPPoE there is another
problem: packets reordering. For example: if packet with coherency count
N-1 is delayed and it was received after the packet with coherency count N,
then ppp will assume that 4094 packet are lost (a coherency count's size
is 12 bit) and will perform 4095 [unnecessary] key changes to synchronize key.
So the MPPE key goes out of sync.

To fix this issue I've written the patch (see attached file).
With this patch applied, ppp(8) distinguishes lost and delayed packets.
To have the chance to decrypt a delayed packets, it keeps small history
of MPPE keys (I think that 64 is a reasonable value).