PPP links with MPD5 - Success! (was PPP overhaul?)

  • Hi,
    I'm inclined to do some work on the PPP configuration and management php
    code. Right now it's done outside the framework/style that is used for
    PPPoE, PPTP, DHCP, etc. and I'll take a crack at making it look the same and
    work mostly the same as those other protocols.

    What do you think? Can I have the blessing of the dev@ people to start on

    One reason I think it is a good idea is that I had a WAN PPP link configured
    at my home and then I got DSL so I tried to change the WAN to use PPPoE and
    it was a nightmare. I resorted to deleting ALL the PPP configs and the WAN
    link still persisted to think it was a "serial" link. I got so frustrated I
    reinstalled from scratch, and we don't want that . . . . :) Making it all
    consistent will also improve readability and maintainability.

    I'm also going to test mpd5 for PPP purposes.



    Case in point illustrating what I'm talking about from interfaces.inc. I
    think ppp links should have a "case" in the switch statement instead of
    being handled outside it. I would set up the interfaces_ppp_edit.php so that
    it writes "ppp" into the "ipaddr" field in the config.xml file. This is just
    one of many places I'm thinking of fixing.

            switch ($ifcfg['ipaddr']) {
            case "pppoe":
            case "pptp":
            case "carpdev-dhcp":
                     * NB: When carpdev gets enabled it would be better to be handled as all
                     *         other interfaces! 
            case "dhcp":
                    $pid = find_dhclient_process($realif);
                            mwexec("kill {$pid}");
                    if(does_interface_exist("$realif")) {
                            mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " delete", true);
                            mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " down");
                            mwexec("/usr/sbin/arp -d -i {$realif} -a");
                    if(does_interface_exist("$realif")) {
                            mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " delete", true);
                            mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " down");
                            mwexec("/usr/sbin/arp -d -i {$realif} -a");

  • You're welcome to start a clone at rcs.pfsense.org and start work there.

    Ermal should comment on this in general, he did most of the PPP work and most of the interfaces work. It does work as is for the things we're currently deploying it in production for, hence I'm hesitant to change anything to avoid regressions. If he doesn't post here in the next day or so, email him with a pointer to this thread (eri at pfsense dot org).

    We've tried mpd in the past for PPP, it didn't work with some 3G cards for some reason, not sure on details.

  • Yeah no objection from me to work on it on a clone.
    Try it out. Please with mpd5 because mpd4 is not that suited for such things.

  • UPDATE: I think I've found the beginning of the problem with mpd5 and ppp connections.

    I've filed a bug with the mpd project: http://sourceforge.net/tracker/?func=detail&aid=2971135&group_id=14145&atid=114145

    I've also changed the
    #if NGM_TTY_COOKIE < 1226109660

    statement so that the code jumps the the #else portion and recompiled mpd v5.5, and then I run into this -> (MODEM: can't connect async node) as seen below.
    I'm not sure why this is happening. I looked at the source but don't know netgraph well enough to know what's going on ??

    [2.0-BETA1][root@pfsense.local]/root(1): mpd5 -d /conf/
    Multi-link PPP daemon for FreeBSD

    process 25977 started, version 5.5 (root@ 13:07 17-Mar-2010)
    [L1] [L1] Link: OPEN event
    [L1] LCP: Open event
    [L1] LCP: state change Initial –> Starting
    [L1] LCP: LayerStart
    [L1] can't create tee node at ".:"->"l0": No such file or directory
    [L1] chat: Detected Hayes compatible modem.
    [L1] chat: Dialing server at *99#…
    [L1] chat: Connected at 7200000.
    [L1] MODEM: chat script succeeded
    [L1] MODEM: can't connect async node
    [L1] can't shutdown "[a]:hook": Bad file descriptor
    [L1] can't shutdown "[a]:": Bad file descriptor
    [L1] Link: DOWN event
    [L1] LCP: Close event
    [L1] LCP: state change Starting –> Initial
    [L1] LCP: LayerFinish
    [L1] LCP: Down event
    caught fatal signal int
    [B1] Bundle: Shutdown
    [L1] Link: Shutdown
    process 25977 terminated

  • What is this nanobsd or full install.
    Seem the kernel is missing ng_async nodes of netgraph.
    Either copy the modules from a FreeBSD iso or get a new snapshot.

  • This is nanobsd. I'll try to get it from the ISO.

  • SUCCESS! brining up a 3G PPP connection with mpd5.

    Once I loaded the ng_async.ko and ng_tee.ko modules into /book/kernel I was able to connect to the ISP successfully. I'm using mpd5.5 with the small change to the source to make the code skip the statements inside the #if NGM_TTY_COOKIE < 1226109660 statements (as I mentioned above). I haven't tested with 5.3 but I'm guessing it will work.

    Here's my mpd.conf file attached. I used the default mpd.script.sample for my mpd.script file, and although my ISP doesn't require a username/password, I still had to have a mpd.secret file and "set auth authname XXX" in the mpd.conf file or the connection negotiation failed.



  • What modem is that?

  • Nice, we would very much like to dump ppp in favor of mpd.  I know that ADSL bonding is a common request from ISPs in Canada which apparently requires MPD.

  • Can you test with latest snapshots.
    I patched mpd5 to have the NGM_TTY_COOKIE code fixed

  • The modem is the Compass 885 from Sierra Wireless/AT&T. I also have a Novatel Ovation MC950D which works as well.

    I'd very much like to dump ppp too. I haven't explored the source, but just experience using it makes me think it's not a great implementation.

  • Hi All,
    I'm making some nice progress on the work to use mpd5 for serial PPP connections (3G modems, normal modems).

    I've only worked on interfaces.inc so far. I have it generating the mpd.conf file and the mpd.secret file, and the linkup and linkdown scripts for one or more configured PPP links.
    Ermal, I copied the style and file placements from the pppoe configuration function since you said awhile back that you wanted it all to be the same.

    mpd has a huge default script file that works without modification for my 3G modem, but I don't have to set the APN, so I hope to modify it slightly and then save it statically somewhere and copy it to /var/etc/ when the ppp interface_configure function is called.

    I haven't done anything to support modems that require you to set an APN, but I'll work on that tomorrow.

    Is there a demand from pfsense users to support multilink PPP with serial based devices?
    I'll also work on multilink PPP configs too if that seems to be a demand.

    Questions for Ermal, Scott . . .
    1. Does /usr/local/sbin/ppp-linkup script work for pppoe users to set their dns servers? It seems like it wouldn't work b/c the script is called with 'dns1' as a single field according to the docs and in the script it's assumed that 'dns1' and '' correlate to two separate fields. And what is the result of sending the interface name to /tmp/rc.newwanip and creating /tmp/<int>up? And what is the facility that caused the desired result?

    2. The current PPP code in the snapshots doesn't set the PPP dns servers properly in /var/etc/resolv.conf. How the heck does setting dns servers from dynamic interfaces like PPP and pppoe work? Or, how is it supposed to work? And how is pfsense supposed to un-set them once the interface comes down?

    This code from system.inc doesn't work as intended . . . the "ls" call isn't formated correctly. Here's the result when file(s) named nameserver_* do exist in that directory.
    [root@pfsense.local]/root(115): ls /var/etc/nameserver_* 2 > /dev/null
    ls: 2: No such file or directory

    function get_nameservers() {
    	global $config, $g;
    	$master_list = array();
    	// Read in dhclient nameservers
    	$dns_lists = split("\n", `ls /var/etc/nameserver_* 2>/dev/null`);
    	if(is_array($dns_lists)) {
    		foreach($dns_lists as $dns) {

    I don't know how to fix setting override DNS servers from dynamic interfaces . I tried, alot. I noticed that it was an option to put nameserver IP's in /var/etc/nameservers.conf so I tried that too. Still, the IP's don't ever get into /var/etc/resolv.conf.  I tried to make and call an rc script that called system_resolvconf_generate(), and still no success.  ???

    The only way they ever get into resolv.conf is by clicking the "Save" button on the system.php page, and then they never get erased even when the link goes down, and back up again. So you notice missing nameservers the first time the link comes up, you go check the system.php page and Save it, and viola, they stick until the next reboot. :) Probably not intended behavior. :)

    3. Next, how about that "set iface name pppoeX" command in the pppoe mpd.conf file? That's not documented anywhere I can see. Is that a custom patch from pfsense dev team?

    4. Where should the mpd.script file for dialing modems live? /usr/local/sbin ? /etc/ppp/ ?

    I've included a patch file of my changes to interfaces.inc so far that you guys can review if you like. I don't recommend committing it yet because it will break PPP for users that need to set the APN on their 3G modem.



  • Answers for the point raised:
    4- You do not need a mpd.script just use set auth name/password directives.
    3- It is a local patch use it the same way it is used for pppoe, just after the create bundle.
    2- It is done with the help of iface-up
    1- It works as it should please reread the code.

  • Hi Ermal,

    Thanks for the answers. I wrote that when I was stuck, and figured most of it out in the meantime.

    I have PPP with mpd5 working really well now, including setting the APN and APN Number. Yes! Your patched mpd5 in recent snapshots works great.
    Still no work on multilink PPP with serial port links.

    Right now the code creates the mpd.secret file but I'll test and change to your suggestion in a couple days if it works as you say.

    And PPP for modems does need the mpd.script file. It's the chat script file for the link establishment, so where do you want it? Right now it has to be in /etc/ppp/mpd.script, and it's copied to /var/etc/. when ppp is first configured.

    I also took away the "Dialcmd" field in the PPP setup page (and a couple others) because the script is rather comprehensive and is designed to handle any modem. I just added the APN stuff to it.

    The code is currently writing custom ppp-linkup/down files to /var/etc/ for ppp links because it's the only way I know how to associate an interface with a ppp definition later on. I'll test your custom "set iface name XXX". I actually tested it already, but it didn't work, probably because I set the mpd.conf file to use bundle templates instead of static bundles. So, I'll test it out and make more changes and if it works, we can get rid of the custom linkup/down scripts and just use the same one that you're using for pppoe (I think.)

    And still no uptime tracking yet. I'm submitting the patches to coreteam@. Please review and commit.


  • Hi,

    Incidentally, I noticed that it takes a long time for this to happen (see log), and I don't know why. I haven't looked at check_reload_status past noting that it's a binary file.

    See the first entry is at 14:17:12 and the next is at 14:17:44. Long time.

    Mar 23 14:17:12 check_reload_status: rc.newwanip starting
    Mar 23 14:17:44 php: : rc.newwanip: Informational is starting ng0.
    Mar 23 14:17:45 php: : rc.newwanip: on (IP address: (interface: wan) (real interface: ng0).
    Mar 23 14:17:49 dnsmasq[24251]: reading /etc/resolv.conf
    Mar 23 14:17:49 dnsmasq[24251]: using nameserver
    Mar 23 14:17:49 dnsmasq[24251]: using nameserver
    Mar 23 14:17:52 check_reload_status: reloading filter
    Mar 23 14:18:44 check_reload_status: updating dyndns

  • Can you please modify it to take a pin if available?!

    It needs 30 secs minimum i never got to modify it to require less.

  • Two more notes . . .

    1. I called mpd with the -s flag to tell it to log to syslog as "ppp" so I didn't have to change the syslog configs. Update both if you want it more clean, but it's sort of nice b/c the webgui already splits ppp out to a separate log.

    2. It would be nice to display some sort of progress indication in the web gui when users click on the Connect button for PPP. Sometimes it takes more time than people expect, and the webpage reloads immediately, and then of course they go clicking again and again. Yeah or Nay? If yes, I'm not sure I can do it.


  • I submitted a new patch set to coreteam@ . . . It seems stable. I tested it for a few hours to work out little issues.

    I implemented interface renaming and that simplified the new code a lot, so that's nice. Now ppp interfaces start with ppp0 and go up as you add more.

    Also, the ppp-linkdown script is an open issue. This patch refers to the script that Ermal wrote in the /usr/local/sbin/ directory, but I couldn't test it b/c my mpd5 binary doesn't pass the DNS servers the same way the newly(and previously) patched binary does(did).

    And the uptime tracking is still an open issue. I've figured out how to do it, but haven't done anything yet. This patch set is getting big and taking time to manage all the parts so I decided to cut it here and do the uptime stuff in the next round.

    I'll do the SIM pin thing too in the next set. I just need a break for a day. :)

    I'm already experiencing much smother conditions with mpd5 for PPP on 3G than I was with userland ppp. It's very nice.

    I also thought there might be a worthy use case for implementing a check box for "dial-on-demand" and text field for "idle timeout."


  • Can you put the patch here or in a ticket on redmine.pfsense.org.
    It is easier to track and can get more review.

    Regarding dns i modified mpd5 to restore old behaviour to pass dns1 $ip as different arguments, it should be on updated snapshots.

  • Hi Ermal,
    I'm curious why you modified them mpd5 code to change the behavior of the dns servers being passed as two fields.

    The ppp-linkup script is easy enough to modify, and then the mpd5 behavior doesn't conflict with the documented mpd5 behavior. Anyone in the future who touches that code in the future is now going to be confused b/c of the inconsistency with the documentation.
    For what it's worth, I vote for keeping the behavior consistent with the docs, and modifying the scripts.


  • Patches accpeted.

  • As someone who very idly tinkered with a hsdpa modem, my thanks to gnhb for these efforts….

  • Hey guys,

    I understand there has been some overhaul of the ppp implementation recently.  After much work, I was able to get the 2.0 beta (prior to recent changes) to work with my Aircard 881 HSPA modem using both AT&T and T-Mobile providers.  I am attempting to test the newest beta build, which includes the changes to PPP, and I cannot get a connection.

    Only reason I am testing the new build is because the DynDns service doesn't update as it should when using 3G as WAN (and only  gateway to internet) on the old 2.0 beta I am currently running.  The only way I can get DynDns to update (without dropping to a command line) is manually via the web interface by opening the Dynamic DNS config page and just simply hitting "save" again.  Otherwise, it will just sit and show an old IP address in red.  Reboots have no affect.  ALSO, if I do update manually and the IP address changes in the future, it still won't update on it's own.

    On the prior implementation, I only had to define the "dial command", "phone number", and "line speed" fields.  They were defined as follows:

    PHONE NUMBER:  *99#
    LINE SPEED:        921600

    Given the simple config required to successfully connect on the old implementation of PPP, why am I having so much trouble getting it to work on the new implementation?  I wish there were an easy way to see the actual/live config from behind the scenes without having to drop to a command line.  (For example, being able to see what is ACTUALLY being sent to the modem for dial string, etc.)

  • The DynDNS issues you noted have all been resolved. All the 3G cards we have access to still work. Paste your PPP logs.

  • Hi,
    If you only filled in Dial cmd, phone, and line speed on the old config then all you have to fill in on the new config page is phone number. That's it! (well, except to select the correct serial port.)

    Check your logs. They will tell you if the chat script doesn't succeed and on what command it fails, otherwise it will look like this (bottom line is first):

    May 1 22:00:16 wan: [lnkwan] MODEM: chat script succeeded
    May 1 22:00:16 wan: [lnkwan] chat: Connected at 7200000.
    May 1 22:00:16 wan: [lnkwan] chat: Dialing server at *99#…
    May 1 22:00:16 wan: [lnkwan] chat: Detected Sierra Wireless Compass C885 USB 3G modem.

  • The FIX lies in the port config.  In the old config, I had to use cuaU0.0.  In the new config, I have to use cuaU0.2.

    Has the driver changed in the new beta as well?  I would not have thought that the data/command ports would have shifted for the same device, unless the driver changed.  Does the new ppp program use a different port config than the last one?

  • Those ports only change if you have more than one USB 3G modem plugged into your box simultaneously. If your device presents 2 ports to the OS, then the first one you plug in will get cuaU0.0 and cuaU0.1 and the second will get cuaU0.2 and cuaU0.3.

    In rare cases, I've seen the OS fail to remove the cuaX ports when a device is unplugged and the next time you insert it it will get the next higher port numbers. I only saw this in testing during development when netgraph was still hanging onto the cuaU.X ports even when I removed the device (because I was misconfiguring mpd5), so I wouldn't expect to see this in normal operation b/c I'm pretty sure I ironed out most of the bugs. :)

    If you reboot, check the port assignments again.

  • There were no hardware changes between changing from the previous 2.0 beta to the current one.  And I have changed it back and forth twice, each time wiping the drive and installing fresh.  Although I backed up the config, I did not restore it.  I configured everything from scratch.

    There is only one 3G device (also no other modems or usb devices) installed in the entire system and it is that Aircard 881.  It is cardbus, but my understanding is that the card has an internal usb controller and the modem connects to that.

    With the old beta on this box, the following ports were listed in the PPP webgui:

    With the new beta on this box, the following ports are listed in the PPP webgui:

    After reboots, everything is the same as it should be.

  • @sgray:

    The FIX lies in the port config.  In the old config, I had to use cuaU0.0.  In the new config, I have to use cuaU0.2.

    Has the driver changed in the new beta as well?

    Depends on what version you started with. In January we moved from FreeBSD 8.0 to RELENG_8 (8.1).

  • @cmb:

    Depends on what version you started with. In January we moved from FreeBSD 8.0 to RELENG_8 (8.1).

    I have been running build 20100322.  Before that, I was running 20091212.  I had no issues in the switch to 20100322 and the same ports were still present and cuaU0.0 was still the port that worked.  The switch from 20100322 to one from a few days ago required me to use cuaU0.2.

  • There have been several date bumps on RELENG_8 between March and now, something must have changed there in FreeBSD for your card.

Log in to reply