X-Git-Url: https://git.ozlabs.org/?a=blobdiff_plain;f=pppd%2Fplugins%2Frp-pppoe%2Fplugin.c;h=c89be94250bc660203beb0a163776fddbb5d074b;hb=1cadc16803b43f7841f5e67aaa7bc12a7b59fdd9;hp=97011aaab938cc5066281846113ebf1bac32921a;hpb=fd1dcdf758418f040da3ed801ab001b5e46854e7;p=ppp.git diff --git a/pppd/plugins/rp-pppoe/plugin.c b/pppd/plugins/rp-pppoe/plugin.c index 97011aa..c89be94 100644 --- a/pppd/plugins/rp-pppoe/plugin.c +++ b/pppd/plugins/rp-pppoe/plugin.c @@ -49,7 +49,6 @@ static char const RCSID[] = #include #include #include -#include #include #ifndef _ROOT_PATH @@ -133,6 +132,17 @@ PPPOEConnectDevice(void) struct ifreq ifr; int s; + /* Open session socket before discovery phase, to avoid losing session */ + /* packets sent by peer just after PADS packet (noted on some Cisco */ + /* server equipment). */ + /* Opening this socket just before waitForPADS in the discovery() */ + /* function would be more appropriate, but it would mess-up the code */ + conn->sessionSocket = socket(AF_PPPOX, SOCK_STREAM, PX_PROTO_OE); + if (conn->sessionSocket < 0) { + error("Failed to create PPPoE socket: %m"); + return -1; + } + /* Restore configuration */ lcp_allowoptions[0].mru = conn->mtu; lcp_wantoptions[0].mru = conn->mru; @@ -172,23 +182,18 @@ PPPOEConnectDevice(void) conn->peerEth[i] = (unsigned char) mac[i]; } } else { + conn->discoverySocket = + openInterface(conn->ifName, Eth_PPPOE_Discovery, conn->myEth); discovery(conn); if (conn->discoveryState != STATE_SESSION) { error("Unable to complete PPPoE Discovery"); - return -1; + goto errout; } } /* Set PPPoE session-number for further consumption */ ppp_session_number = ntohs(conn->session); - /* Make the session socket */ - conn->sessionSocket = socket(AF_PPPOX, SOCK_STREAM, PX_PROTO_OE); - if (conn->sessionSocket < 0) { - error("Failed to create PPPoE socket: %m"); - goto errout; - } - sp.sa_family = AF_PPPOX; sp.sa_protocol = PX_PROTO_OE; sp.sa_addr.pppoe.sid = conn->session; @@ -218,7 +223,6 @@ PPPOEConnectDevice(void) if (connect(conn->sessionSocket, (struct sockaddr *) &sp, sizeof(struct sockaddr_pppox)) < 0) { error("Failed to connect PPPoE socket: %d %m", errno); - close(conn->sessionSocket); goto errout; } @@ -230,6 +234,7 @@ PPPOEConnectDevice(void) close(conn->discoverySocket); conn->discoverySocket = -1; } + close(conn->sessionSocket); return -1; } @@ -265,12 +270,13 @@ PPPOEDisconnectDevice(void) memcpy(sp.sa_addr.pppoe.dev, conn->ifName, IFNAMSIZ); memcpy(sp.sa_addr.pppoe.remote, conn->peerEth, ETH_ALEN); if (connect(conn->sessionSocket, (struct sockaddr *) &sp, - sizeof(struct sockaddr_pppox)) < 0) + sizeof(struct sockaddr_pppox)) < 0 && errno != EALREADY) error("Failed to disconnect PPPoE socket: %d %m", errno); close(conn->sessionSocket); - /* don't send PADT?? */ - if (conn->discoverySocket >= 0) + if (conn->discoverySocket >= 0) { + sendPADT(conn, NULL); close(conn->discoverySocket); + } } static void