Worked on multilink support.

Event/action code should be finished soon.

TODO for libkernelppp.a:
- reports
- redial
- PPPInterface::Up()/Down()
- all other classes (not very much work)
- LCP protocol
- MRU and protocol-field-compression (needs some addition to PPPInterface, too) option handlers


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4071 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Waldemar Kornewald
2003-07-25 11:43:22 +00:00
parent 34d6a0f784
commit 7335f587be
5 changed files with 92 additions and 58 deletions
@@ -52,10 +52,14 @@ class PPPEncapsulator {
virtual bool Up() = 0; virtual bool Up() = 0;
virtual bool Down() = 0; virtual bool Down() = 0;
virtual bool Reset() = 0;
// reset to initial (down) state without sending something
bool IsUp() const bool IsUp() const
{ return fIsUp; } { return fConnectionStatus == PPP_ESTABLISHED_PHASE; }
bool IsDown const
{ return fConectionStatus == PPP_DOWN_PHASE; }
bool IsGoingUp() const
{ return fConnectionStatus == PPP_ESTABLISHMENT_PHASE; }
bool IsGoingDown() const
{ return fConnectionStatus == PPP_TERMINATION_PHASE; }
virtual status_t Send(mbuf *packet, uint16 protocol) = 0; virtual status_t Send(mbuf *packet, uint16 protocol) = 0;
virtual status_t Receive(mbuf *packet, uint16 protocol) = 0; virtual status_t Receive(mbuf *packet, uint16 protocol) = 0;
@@ -89,7 +93,7 @@ class PPPEncapsulator {
bool fEnabled; bool fEnabled;
bool fUpRequested; bool fUpRequested;
bool fIsUp; PPP_PHASE fConnectionStatus;
}: }:
@@ -42,10 +42,14 @@ class PPPProtocol {
virtual bool Up() = 0; virtual bool Up() = 0;
virtual bool Down() = 0; virtual bool Down() = 0;
virtual bool Reset() = 0;
// reset to initial (down) state without sending something
bool IsUp() const bool IsUp() const
{ return fIsUp; } { return fConnectionStatus == PPP_ESTABLISHED_PHASE; }
bool IsDown const
{ return fConectionStatus == PPP_DOWN_PHASE; }
bool IsGoingUp() const
{ return fConnectionStatus == PPP_ESTABLISHMENT_PHASE; }
bool IsGoingDown() const
{ return fConnectionStatus == PPP_TERMINATION_PHASE; }
virtual status_t Send(mbuf *packet) = 0; virtual status_t Send(mbuf *packet) = 0;
virtual status_t Receive(mbuf *packet) = 0; virtual status_t Receive(mbuf *packet) = 0;
@@ -69,7 +73,7 @@ class PPPProtocol {
bool fEnabled; bool fEnabled;
bool fUpRequested; bool fUpRequested;
bool fIsUp; PPP_PHASE fConnectionStatus;
}; };
@@ -93,7 +93,7 @@ class PPPStateMachine {
void RCNEvent(mbuf *packet); void RCNEvent(mbuf *packet);
void RTREvent(mbuf *packet); void RTREvent(mbuf *packet);
void RTAEvent(mbuf *packet); void RTAEvent(mbuf *packet);
void RUCEvent(mbuf *packet, uint16 protocol, uint8 type); void RUCEvent(mbuf *packet, uint16 protocol, uint8 type = PPP_PROTOCOL_REJECT);
void RXJGoodEvent(mbuf *packet); void RXJGoodEvent(mbuf *packet);
void RXJBadEvent(mbuf *packet); void RXJBadEvent(mbuf *packet);
void RXREvent(mbuf *packet); void RXREvent(mbuf *packet);
+11 -10
View File
@@ -75,12 +75,11 @@ PPPInterface::PPPInterface(driver_settings *settings, PPPInterface *parent = NUL
PPPInterface::~PPPInterface() PPPInterface::~PPPInterface()
{ {
put_module((module_info**) &fManager);
// TODO: // TODO:
// remove our iface, so that nobody will access it: // remove our iface, so that nobody will access it:
// go down if up // go down if up
// unregister from ppp_manager // unregister from ppp_manager
// delete children
// destroy and remove: // destroy and remove:
// device // device
// protocols // protocols
@@ -88,6 +87,8 @@ PPPInterface::~PPPInterface()
// option handlers // option handlers
// put all modules (in fModules) // put all modules (in fModules)
put_module((module_info**) &fManager);
} }
@@ -405,7 +406,7 @@ PPPInterface::RemoveChild(PPPInterface *child)
child->SetParent(NULL); child->SetParent(NULL);
// parents cannot exist without their children // parents cannot exist without their children
if(CountChildren() == 0 && fManager) if(CountChildren() == 0 && fManager && Ifnet())
fManager->delete_interface(this); fManager->delete_interface(this);
CalculateMRU(); CalculateMRU();
@@ -479,6 +480,12 @@ PPPInterface::Down()
// TODO: // TODO:
// Add one-time connection report request. // Add one-time connection report request.
// All attempts to connect have failed.
if(!DoesDialOnDemand())
fManager->delete_interface(this);
return false; return false;
} }
@@ -488,13 +495,7 @@ PPPInterface::IsUp() const
{ {
LockerHelper locker(fGeneralLock); LockerHelper locker(fGeneralLock);
return StateMachine().Phase() == PPP_ESTABLISHED_PHASE;
// set running flag if successful
if(Ifnet())
return Ifnet()->if_flags & IFF_RUNNING;
return false;
} }
+64 -39
View File
@@ -70,6 +70,7 @@ PPPStateMachine::AuthenticationRequested()
fAuthenticationStatus = PPP_AUTHENTICATING; fAuthenticationStatus = PPP_AUTHENTICATING;
free(fAuthenticationName); free(fAuthenticationName);
fAuthenticationName = NULL;
} }
@@ -111,6 +112,7 @@ PPPStateMachine::PeerAuthenticationRequested()
fPeerAuthenticationStatus = PPP_AUTHENTICATING; fPeerAuthenticationStatus = PPP_AUTHENTICATING;
free(fPeerAuthenticationName); free(fPeerAuthenticationName);
fPeerAuthenticationName = NULL;
} }
@@ -156,20 +158,27 @@ PPPStateMachine::UpFailedEvent(PPPInterface *interface)
void void
PPPStateMachine::UpEvent(PPPInterface *interface) PPPStateMachine::UpEvent(PPPInterface *interface)
{ {
if(Phase() < PPP_ESTABLISHMENT_PHASE) { LockerHelper locker(fLock);
Interface()->UnregisterInterface();
if(Phase() <= PPP_TERMINATION_PHASE || State() != PPP_STARTING_STATE) {
interface->Down();
return; return;
} }
if(Interface()->IsMultilink() && !Interface()->Parent()) NewState(PPP_OPENED_STATE);
Interface()->RegisterInterface(); if(Phase() == PPP_ESTABLISHMENT_PHASE) {
NewPhase(PPP_AUTHENTICATION_PHASE);
ThisLayerUp();
}
} }
void void
PPPStateMachine::DownEvent(PPPInterface *interface) PPPStateMachine::DownEvent(PPPInterface *interface)
{ {
// when all children are down we should not be registered LockerHelper locker(fLock);
// when all children are down we should not be running
if(Interface()->IsMultilink() && !Interface()->Parent()) { if(Interface()->IsMultilink() && !Interface()->Parent()) {
uint32 count = 0; uint32 count = 0;
PPPInterface *child; PPPInterface *child;
@@ -180,8 +189,8 @@ PPPStateMachine::DownEvent(PPPInterface *interface)
++count; ++count;
} }
if(count == 0) if(count == 0 && Interface()->Ifnet())
Interface()->UnregisterInterface(); Interface()->Ifnet()->if_flags &= ~IFF_RUNNING;
} }
} }
@@ -315,7 +324,7 @@ PPPStateMachine::UpEvent()
LockerHelper locker(fLock); LockerHelper locker(fLock);
if(!Device()->IsUp()) if(!Interface()->Device() || !Interface()->Device->IsUp())
return; return;
// it is not our device that went up... // it is not our device that went up...
@@ -364,23 +373,18 @@ PPPStateMachine::DownEvent()
{ {
LockerHelper locker(fLock); LockerHelper locker(fLock);
// TODO: NewPhase(PPP_DOWN_PHASE);
// ResetProtocols();
// ResetEncapsulators();
// ResetOptionHandlers();
switch(State()) { switch(State()) {
case PPP_CLOSED_STATE: case PPP_CLOSED_STATE:
case PPP_CLOSING_STATE: case PPP_CLOSING_STATE:
NewState(PPP_INITIAL_STATE); NewState(PPP_INITIAL_STATE);
NewPhase(PPP_DOWN_PHASE);
break; break;
case PPP_STOPPED_STATE: case PPP_STOPPED_STATE:
// The RFC says we should reconnect, but our implementation // The RFC says we should reconnect, but our implementation
// will only do this if auto-redial is enabled (only clients). // will only do this if auto-redial is enabled (only clients).
NewStatus(PPP_STARTING_STATE); NewStatus(PPP_STARTING_STATE);
NewPhase(PPP_DOWN_PHASE);
// TODO: // TODO:
// report that we lost the connection // report that we lost the connection
@@ -392,7 +396,6 @@ PPPStateMachine::DownEvent()
case PPP_STOPPING_STATE: case PPP_STOPPING_STATE:
NewStatus(PPP_STARTING_STATE); NewStatus(PPP_STARTING_STATE);
NewPhase(PPP_DOWN_PHASE);
// TODO: // TODO:
// report that we lost the connection // report that we lost the connection
@@ -403,7 +406,6 @@ PPPStateMachine::DownEvent()
case PPP_ACK_RCVD_STATE: case PPP_ACK_RCVD_STATE:
case PPP_ACK_SENT_STATE: case PPP_ACK_SENT_STATE:
NewStatus(PPP_STARTING_STATE); NewStatus(PPP_STARTING_STATE);
NewPhase(PPP_DOWN_PHASE);
// TODO: // TODO:
// report that we lost the connection // report that we lost the connection
@@ -413,7 +415,6 @@ PPPStateMachine::DownEvent()
case PPP_OPENED_STATE: case PPP_OPENED_STATE:
// tld/1 // tld/1
NewStatus(PPP_STARTING_STATE); NewStatus(PPP_STARTING_STATE);
NewPhase(PPP_DOWN_PHASE);
// TODO: // TODO:
// report that we lost the connection // report that we lost the connection
@@ -424,6 +425,11 @@ PPPStateMachine::DownEvent()
IllegalEvent(PPP_DOWN_EVENT); IllegalEvent(PPP_DOWN_EVENT);
} }
// TODO:
// DownProtocols();
// DownEncapsulators();
// ResetOptionHandlers();
// maybe we need to redial // maybe we need to redial
if(State() == PPP_STARTING_STATE) { if(State() == PPP_STARTING_STATE) {
if(Interface()->DoesAutoRedial()) { if(Interface()->DoesAutoRedial()) {
@@ -449,8 +455,14 @@ PPPStateMachine::OpenEvent()
switch(State()) { switch(State()) {
case PPP_INITIAL_STATE: case PPP_INITIAL_STATE:
NewState(PPP_STARTING_STATE); NewState(PPP_STARTING_STATE);
locker.UnlockNow(); if(Interface()->IsMultilink() && !Interface()->Parent()) {
ThisLayerStarted(); NewPhase(PPP_ESTABLISHMENT_PHASE);
for(int32 i = 0; i < Interface()->CountChildren(); i++)
Interface()->ChildAt(i)->Up();
} else {
locker.UnlockNow();
ThisLayerStarted();
}
break; break;
case PPP_CLOSED_STATE: case PPP_CLOSED_STATE:
@@ -477,6 +489,18 @@ PPPStateMachine::CloseEvent()
{ {
LockerHelper locker(fLock); LockerHelper locker(fLock);
if(Interface()->IsMultilink() && !Interface()->Parent()) {
NewState(PPP_INITIAL_STATE);
NewPhase(PPP_DOWN_PHASE);
ThisLayerDown();
for(int32 i = 0; i < Interface()->CountChildren(); i++)
Interface()->ChildAt(i)->Down();
return;
}
switch(State()) { switch(State()) {
case PPP_OPENED_STATE: case PPP_OPENED_STATE:
ThisLayerDown(); ThisLayerDown();
@@ -494,10 +518,9 @@ PPPStateMachine::CloseEvent()
case PPP_STARTING_STATE: case PPP_STARTING_STATE:
NewState(PPP_INITIAL_STATE); NewState(PPP_INITIAL_STATE);
// if Device()->TLS() has not been called
// TLSNotify() will know that we were faster because we // TLSNotify() will know that we were faster because we
// are in PPP_INITIAL_STATE now // are in PPP_INITIAL_STATE now
if(Phase() == PPP_ESTABLISHMENT_PHASE) { if(Phase() == PPP_ESTABLISHMENT_PHASE && Interface()->Parent()) {
// the device is already up // the device is already up
NewPhase(PPP_DOWN_PHASE); NewPhase(PPP_DOWN_PHASE);
// this says the following DownEvent() was not caused by // this says the following DownEvent() was not caused by
@@ -582,9 +605,6 @@ PPPStateMachine::RCRGoodEvent(mbuf *packet)
{ {
LockerHelper locker(fLock); LockerHelper locker(fLock);
if(fRequestID == mtod(packet, lcp_packet*)->id)
fRequestID -= 128;
switch(State()) { switch(State()) {
case PPP_INITIAL_STATE: case PPP_INITIAL_STATE:
case PPP_STARTING_STATE: case PPP_STARTING_STATE:
@@ -619,6 +639,8 @@ PPPStateMachine::RCRGoodEvent(mbuf *packet)
case PPP_OPENED_STATE: case PPP_OPENED_STATE:
// tld,scr,sca/8 // tld,scr,sca/8
NewState(PPP_ACK_SENT_STATE); NewState(PPP_ACK_SENT_STATE);
NewPhase(PPP_ESTABLISHMENT_PHASE);
// tell handlers that we are reconfiguring
locker.UnlockNow(); locker.UnlockNow();
SendConfigureRequest(); SendConfigureRequest();
SendConfigureAck(packet); SendConfigureAck(packet);
@@ -634,10 +656,6 @@ PPPStateMachine::RCRBadEvent(mbuf *nak, mbuf *reject)
{ {
LockerHelper locker(fLock); LockerHelper locker(fLock);
// we should not use the same ID as the peer
if(fRequestID == mtod(packet, lcp_packet*)->id)
fRequestID -= 128;
switch(State()) { switch(State()) {
case PPP_INITIAL_STATE: case PPP_INITIAL_STATE:
case PPP_STARTING_STATE: case PPP_STARTING_STATE:
@@ -805,8 +823,8 @@ PPPStateMachine::RTREvent(mbuf *packet)
LockerHelper locker(fLock); LockerHelper locker(fLock);
// we should not use the same ID as the peer // we should not use the same ID as the peer
if(fTerminateID == mtod(packet, lcp_packet*)->id) if(fID == mtod(packet, lcp_packet*)->id)
fTerminateID -= 128; fID -= 128;
switch(State()) { switch(State()) {
case PPP_INITIAL_STATE: case PPP_INITIAL_STATE:
@@ -884,7 +902,7 @@ PPPStateMachine::RTAEvent(mbuf *packet)
// receive unknown code // receive unknown code
void void
PPPStateMachine::RUCEvent(mbuf *packet, uint16 protocol, uint8 type) PPPStateMachine::RUCEvent(mbuf *packet, uint16 protocol, uint8 type = PPP_PROTOCOL_REJECT)
{ {
LockerHelper locker(fLock); LockerHelper locker(fLock);
@@ -1022,6 +1040,10 @@ PPPStateMachine::RCREvent(mbuf *packet)
reject(PPP_CONFIGURE_REJECT); reject(PPP_CONFIGURE_REJECT);
PPPOptionHandler *handler; PPPOptionHandler *handler;
// we should not use the same id as the peer
if(fID == mtod(packet, lcp_packet*)->id)
fID -= 128;
nak.SetID(request.ID()); nak.SetID(request.ID());
reject.SetID(request.ID()); reject.SetID(request.ID());
@@ -1073,10 +1095,13 @@ PPPStateMachine::RXJEvent(mbuf *packet)
{ {
lcp_packet *reject mtod(packet, lcp_packet*); lcp_packet *reject mtod(packet, lcp_packet*);
if(reject->code == PPP_CODE_REJECT) if(reject->code == PPP_CODE_REJECT) {
RXJBadEvent(packet); // we only have basic codes, so there must be something wrong
// we only have basic codes, so there must be something wrong if(Interface()->IsMultilink() && !Interface()->Parent())
else if(reject->code == PPP_PROTOCOL_REJECT) { CloseEvent();
else
RXJBadEvent(packet);
} else if(reject->code == PPP_PROTOCOL_REJECT) {
// disable all handlers for rejected protocol type // disable all handlers for rejected protocol type
uint16 rejected = *((uint16*) reject->data); uint16 rejected = *((uint16*) reject->data);
// rejected protocol number // rejected protocol number
@@ -1141,8 +1166,6 @@ PPPStateMachine::ThisLayerDown()
// TODO: // TODO:
// DownProtocols(); // DownProtocols();
// DownEncapsulators(); // DownEncapsulators();
// ResetProtocols();
// ResetEncapsulators();
// If there are protocols/encapsulators with PPP_DOWN_NEEDED flag // If there are protocols/encapsulators with PPP_DOWN_NEEDED flag
// wait until they report a DownEvent() (or until all of them are down). // wait until they report a DownEvent() (or until all of them are down).
} }
@@ -1160,8 +1183,8 @@ void
PPPStateMachine::ThisLayerFinished() PPPStateMachine::ThisLayerFinished()
{ {
// TODO: // TODO:
// ResetProtocols(); // DownProtocols();
// ResetEncapsulators(); // DownEncapsulators();
if(Interface()->Device()) if(Interface()->Device())
Interface()->Device()->Down(); Interface()->Device()->Down();
@@ -1313,6 +1336,8 @@ PPPStateMachine::BringHandlersUp()
// TODO: // TODO:
// Report(PPP_CONNECTION_REPORT, PPP_UP_SUCCESSFUL, NULL, 0); // Report(PPP_CONNECTION_REPORT, PPP_UP_SUCCESSFUL, NULL, 0);
if(Interface()->Ifnet())
Interface()->Ifnet()->if_flags |= IFF_RUNNING;
} else } else
NewPhase(Phase() + 1); NewPhase(Phase() + 1);
} }