Changed PPP interface manager API to support interface names and profiles.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6280 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -3,6 +3,7 @@ SubDir OBOS_TOP src add-ons kernel network interfaces ppp ;
|
|||||||
UsePrivateHeaders net ;
|
UsePrivateHeaders net ;
|
||||||
UsePrivateHeaders [ FDirName kernel ] ;
|
UsePrivateHeaders [ FDirName kernel ] ;
|
||||||
UsePrivateHeaders [ FDirName kernel util ] ;
|
UsePrivateHeaders [ FDirName kernel util ] ;
|
||||||
|
UseHeaders [ FDirName $(OBOS_TOP) src add-ons kernel network ppp shared libkernelppp ] ;
|
||||||
UseHeaders [ FDirName $(OBOS_TOP) src add-ons kernel network ppp shared libkernelppp headers ] ;
|
UseHeaders [ FDirName $(OBOS_TOP) src add-ons kernel network ppp shared libkernelppp headers ] ;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,9 +5,12 @@
|
|||||||
// Copyright (c) 2003-2004 Waldemar Kornewald, [email protected]
|
// Copyright (c) 2003-2004 Waldemar Kornewald, [email protected]
|
||||||
//-----------------------------------------------------------------------
|
//-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
#include "PPPManager.h"
|
#include "PPPManager.h"
|
||||||
#include <PPPControl.h>
|
#include <PPPControl.h>
|
||||||
#include <KPPPUtils.h>
|
#include <KPPPUtils.h>
|
||||||
|
#include <settings_tools.h>
|
||||||
|
|
||||||
#include <LockerHelper.h>
|
#include <LockerHelper.h>
|
||||||
|
|
||||||
@@ -15,7 +18,7 @@
|
|||||||
#include <sys/sockio.h>
|
#include <sys/sockio.h>
|
||||||
|
|
||||||
|
|
||||||
static const char sPPPIfNameBase[] = "ppp";
|
static const char sKPPPIfNameBase[] = "ppp";
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
@@ -191,7 +194,7 @@ PPPManager::Output(ifnet *ifp, struct mbuf *buf, struct sockaddr *dst,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32 result = B_ERROR;
|
int32 result = B_ERROR;
|
||||||
PPPProtocol *protocol = entry->interface->FirstProtocol();
|
KPPPProtocol *protocol = entry->interface->FirstProtocol();
|
||||||
for(; protocol; protocol = protocol->NextProtocol()) {
|
for(; protocol; protocol = protocol->NextProtocol()) {
|
||||||
if(!protocol->IsEnabled() || protocol->AddressFamily() != dst->sa_family)
|
if(!protocol->IsEnabled() || protocol->AddressFamily() != dst->sa_family)
|
||||||
continue;
|
continue;
|
||||||
@@ -254,54 +257,39 @@ PPPManager::Control(ifnet *ifp, ulong cmd, caddr_t data)
|
|||||||
|
|
||||||
ppp_interface_id
|
ppp_interface_id
|
||||||
PPPManager::CreateInterface(const driver_settings *settings,
|
PPPManager::CreateInterface(const driver_settings *settings,
|
||||||
|
const driver_settings *profile = NULL,
|
||||||
ppp_interface_id parentID = PPP_UNDEFINED_INTERFACE_ID)
|
ppp_interface_id parentID = PPP_UNDEFINED_INTERFACE_ID)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
return _CreateInterface(NULL, settings, profile, parentID);
|
||||||
dprintf("PPPManager: CreateInterface()\n");
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
LockerHelper locker(fLock);
|
ppp_interface_id
|
||||||
|
PPPManager::CreateInterfaceWithName(const char *name,
|
||||||
ppp_interface_entry *parentEntry = EntryFor(parentID);
|
const driver_settings *profile = NULL,
|
||||||
if(parentID != PPP_UNDEFINED_INTERFACE_ID && !parentEntry)
|
ppp_interface_id parentID = PPP_UNDEFINED_INTERFACE_ID)
|
||||||
|
{
|
||||||
|
if(!name)
|
||||||
return PPP_UNDEFINED_INTERFACE_ID;
|
return PPP_UNDEFINED_INTERFACE_ID;
|
||||||
|
|
||||||
// the day when NextID() returns 0 will come, be prepared! ;)
|
char path[B_PATH_NAME_LENGTH];
|
||||||
ppp_interface_id id = NextID();
|
sprintf(path, "pppidf/%s", name);
|
||||||
if(id == PPP_UNDEFINED_INTERFACE_ID)
|
// XXX: TODO: change base path to "/etc/ppp" when settings API supports it
|
||||||
id = NextID();
|
|
||||||
|
|
||||||
ppp_interface_entry *entry = new ppp_interface_entry;
|
void *handle = load_driver_settings(path);
|
||||||
entry->accessing = 1;
|
if(!handle)
|
||||||
entry->deleting = false;
|
return PPP_UNDEFINED_INTERFACE_ID;
|
||||||
fEntries.AddItem(entry);
|
|
||||||
// nothing bad can happen because we are in a locked section here
|
|
||||||
|
|
||||||
new PPPInterface(entry, id, settings, parentEntry ? parentEntry->interface : NULL);
|
const driver_settings *settings = get_driver_settings(handle);
|
||||||
// PPPInterface will add itself to the entry (no need to do it here)
|
if(!settings) {
|
||||||
if(entry->interface->InitCheck() != B_OK) {
|
unload_driver_settings(handle);
|
||||||
delete entry->interface;
|
|
||||||
delete entry;
|
|
||||||
return PPP_UNDEFINED_INTERFACE_ID;
|
return PPP_UNDEFINED_INTERFACE_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
locker.UnlockNow();
|
ppp_interface_id result = _CreateInterface(name, settings, profile, parentID);
|
||||||
// it is safe to access the manager from userland
|
unload_driver_settings(handle);
|
||||||
|
|
||||||
if(!Report(PPP_MANAGER_REPORT, PPP_REPORT_INTERFACE_CREATED,
|
return result;
|
||||||
&id, sizeof(ppp_interface_id))) {
|
|
||||||
DeleteInterface(id);
|
|
||||||
--entry->accessing;
|
|
||||||
return PPP_UNDEFINED_INTERFACE_ID;
|
|
||||||
}
|
|
||||||
|
|
||||||
// notify handlers that interface has been created and they can initialize it now
|
|
||||||
entry->interface->StateMachine().DownProtocols();
|
|
||||||
entry->interface->StateMachine().ResetLCPHandlers();
|
|
||||||
|
|
||||||
--entry->accessing;
|
|
||||||
|
|
||||||
return id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -376,7 +364,7 @@ PPPManager::RegisterInterface(ppp_interface_id ID)
|
|||||||
memset(ifp, 0, sizeof(ifnet));
|
memset(ifp, 0, sizeof(ifnet));
|
||||||
ifp->devid = -1;
|
ifp->devid = -1;
|
||||||
ifp->if_type = IFT_PPP;
|
ifp->if_type = IFT_PPP;
|
||||||
ifp->name = sPPPIfNameBase;
|
ifp->name = sKPPPIfNameBase;
|
||||||
ifp->if_unit = FindUnit();
|
ifp->if_unit = FindUnit();
|
||||||
ifp->if_flags = IFF_POINTOPOINT;
|
ifp->if_flags = IFF_POINTOPOINT;
|
||||||
ifp->rx_thread = ifp->tx_thread = -1;
|
ifp->rx_thread = ifp->tx_thread = -1;
|
||||||
@@ -428,14 +416,29 @@ PPPManager::Control(uint32 op, void *data, size_t length)
|
|||||||
|
|
||||||
switch(op) {
|
switch(op) {
|
||||||
case PPPC_CREATE_INTERFACE: {
|
case PPPC_CREATE_INTERFACE: {
|
||||||
if(length < sizeof(ppp_interface_settings_info) || !data)
|
if(length < sizeof(ppp_interface_description_info) || !data)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
ppp_interface_settings_info *info = (ppp_interface_settings_info*) data;
|
ppp_interface_description_info *info
|
||||||
if(!info->settings)
|
= (ppp_interface_description_info*) data;
|
||||||
|
if(!info->u.settings)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
info->interface = CreateInterface(info->settings);
|
info->interface = CreateInterface(info->u.settings, info->profile);
|
||||||
|
// parents cannot be set from userland
|
||||||
|
return info->interface != PPP_UNDEFINED_INTERFACE_ID ? B_OK : B_ERROR;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case PPPC_CREATE_INTERFACE_WITH_NAME: {
|
||||||
|
if(length < sizeof(ppp_interface_description_info) || !data)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
ppp_interface_description_info *info
|
||||||
|
= (ppp_interface_description_info*) data;
|
||||||
|
if(!info->u.name)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
info->interface = CreateInterfaceWithName(info->u.name, info->profile);
|
||||||
// parents cannot be set from userland
|
// parents cannot be set from userland
|
||||||
return info->interface != PPP_UNDEFINED_INTERFACE_ID ? B_OK : B_ERROR;
|
return info->interface != PPP_UNDEFINED_INTERFACE_ID ? B_OK : B_ERROR;
|
||||||
} break;
|
} break;
|
||||||
@@ -513,6 +516,24 @@ PPPManager::Control(uint32 op, void *data, size_t length)
|
|||||||
return CountInterfaces(*(ppp_interface_filter*)data);
|
return CountInterfaces(*(ppp_interface_filter*)data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PPPC_FIND_INTERFACE_WITH_SETTINGS: {
|
||||||
|
if(length < sizeof(ppp_interface_description_info) || !data)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
ppp_interface_description_info *info
|
||||||
|
= (ppp_interface_description_info*) data;
|
||||||
|
if(!info->u.settings)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
ppp_interface_entry *entry = EntryFor(info->u.settings);
|
||||||
|
if(entry)
|
||||||
|
info->interface = entry->interface->ID();
|
||||||
|
else {
|
||||||
|
info->interface = PPP_UNDEFINED_INTERFACE_ID;
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
case PPPC_ENABLE_REPORTS: {
|
case PPPC_ENABLE_REPORTS: {
|
||||||
if(length < sizeof(ppp_report_request) || !data)
|
if(length < sizeof(ppp_report_request) || !data)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
@@ -688,6 +709,27 @@ PPPManager::EntryFor(ifnet *ifp, int32 *saveIndex = NULL) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ppp_interface_entry*
|
||||||
|
PPPManager::EntryFor(const driver_settings *settings) const
|
||||||
|
{
|
||||||
|
if(!settings)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
dprintf("PPPManager: EntryFor(settings)\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ppp_interface_entry *entry;
|
||||||
|
for(int32 index = 0; index < fEntries.CountItems(); index++) {
|
||||||
|
entry = fEntries.ItemAt(index);
|
||||||
|
if(entry && equal_interface_settings(entry->interface->Settings(), settings))
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
int
|
int
|
||||||
greater(const void *a, const void *b)
|
greater(const void *a, const void *b)
|
||||||
@@ -696,6 +738,61 @@ greater(const void *a, const void *b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// used by the public CreateInterface() methods
|
||||||
|
ppp_interface_id
|
||||||
|
PPPManager::_CreateInterface(const char *name, const driver_settings *settings,
|
||||||
|
const driver_settings *profile, ppp_interface_id parentID)
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
dprintf("PPPManager: CreateInterface(%s)\n", name ? name : "Unnamed");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
LockerHelper locker(fLock);
|
||||||
|
|
||||||
|
ppp_interface_entry *parentEntry = EntryFor(parentID);
|
||||||
|
if(parentID != PPP_UNDEFINED_INTERFACE_ID && !parentEntry)
|
||||||
|
return PPP_UNDEFINED_INTERFACE_ID;
|
||||||
|
|
||||||
|
// the day when NextID() returns 0 will come, be prepared! ;)
|
||||||
|
ppp_interface_id id = NextID();
|
||||||
|
if(id == PPP_UNDEFINED_INTERFACE_ID)
|
||||||
|
id = NextID();
|
||||||
|
|
||||||
|
ppp_interface_entry *entry = new ppp_interface_entry;
|
||||||
|
entry->accessing = 1;
|
||||||
|
entry->deleting = false;
|
||||||
|
fEntries.AddItem(entry);
|
||||||
|
// nothing bad can happen because we are in a locked section here
|
||||||
|
|
||||||
|
new KPPPInterface(name, entry, id, settings, profile,
|
||||||
|
parentEntry ? parentEntry->interface : NULL);
|
||||||
|
// KPPPInterface will add itself to the entry (no need to do it here)
|
||||||
|
if(entry->interface->InitCheck() != B_OK) {
|
||||||
|
delete entry->interface;
|
||||||
|
delete entry;
|
||||||
|
return PPP_UNDEFINED_INTERFACE_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
locker.UnlockNow();
|
||||||
|
// it is safe to access the manager from userland
|
||||||
|
|
||||||
|
if(!Report(PPP_MANAGER_REPORT, PPP_REPORT_INTERFACE_CREATED,
|
||||||
|
&id, sizeof(ppp_interface_id))) {
|
||||||
|
DeleteInterface(id);
|
||||||
|
--entry->accessing;
|
||||||
|
return PPP_UNDEFINED_INTERFACE_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
// notify handlers that interface has been created and they can initialize it now
|
||||||
|
entry->interface->StateMachine().DownProtocols();
|
||||||
|
entry->interface->StateMachine().ResetLCPHandlers();
|
||||||
|
|
||||||
|
--entry->accessing;
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int32
|
int32
|
||||||
PPPManager::FindUnit() const
|
PPPManager::FindUnit() const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -31,6 +31,10 @@ class PPPManager {
|
|||||||
int32 Control(ifnet *ifp, ulong cmd, caddr_t data);
|
int32 Control(ifnet *ifp, ulong cmd, caddr_t data);
|
||||||
|
|
||||||
ppp_interface_id CreateInterface(const driver_settings *settings,
|
ppp_interface_id CreateInterface(const driver_settings *settings,
|
||||||
|
const driver_settings *profile = NULL,
|
||||||
|
ppp_interface_id parentID = PPP_UNDEFINED_INTERFACE_ID);
|
||||||
|
ppp_interface_id CreateInterfaceWithName(const char *name,
|
||||||
|
const driver_settings *profile = NULL,
|
||||||
ppp_interface_id parentID = PPP_UNDEFINED_INTERFACE_ID);
|
ppp_interface_id parentID = PPP_UNDEFINED_INTERFACE_ID);
|
||||||
bool DeleteInterface(ppp_interface_id ID);
|
bool DeleteInterface(ppp_interface_id ID);
|
||||||
bool RemoveInterface(ppp_interface_id ID);
|
bool RemoveInterface(ppp_interface_id ID);
|
||||||
@@ -46,14 +50,16 @@ class PPPManager {
|
|||||||
ppp_interface_filter filter = PPP_REGISTERED_INTERFACES);
|
ppp_interface_filter filter = PPP_REGISTERED_INTERFACES);
|
||||||
int32 CountInterfaces(ppp_interface_filter filter = PPP_REGISTERED_INTERFACES);
|
int32 CountInterfaces(ppp_interface_filter filter = PPP_REGISTERED_INTERFACES);
|
||||||
|
|
||||||
PPPReportManager& ReportManager()
|
KPPPReportManager& ReportManager()
|
||||||
{ return fReportManager; }
|
{ return fReportManager; }
|
||||||
bool Report(ppp_report_type type, int32 code, void *data, int32 length)
|
bool Report(ppp_report_type type, int32 code, void *data, int32 length)
|
||||||
{ return ReportManager().Report(type, code, data, length); }
|
{ return ReportManager().Report(type, code, data, length); }
|
||||||
// returns false if reply was bad (or an error occured)
|
// returns false if reply was bad (or an error occured)
|
||||||
|
|
||||||
ppp_interface_entry *EntryFor(ppp_interface_id ID, int32 *saveIndex = NULL) const;
|
ppp_interface_entry *EntryFor(ppp_interface_id ID,
|
||||||
|
int32 *saveIndex = NULL) const;
|
||||||
ppp_interface_entry *EntryFor(ifnet *ifp, int32 *saveIndex = NULL) const;
|
ppp_interface_entry *EntryFor(ifnet *ifp, int32 *saveIndex = NULL) const;
|
||||||
|
ppp_interface_entry *EntryFor(const driver_settings *settings) const;
|
||||||
|
|
||||||
ppp_interface_id NextID()
|
ppp_interface_id NextID()
|
||||||
{ return (ppp_interface_id) atomic_add((int32*) &fNextID, 1); }
|
{ return (ppp_interface_id) atomic_add((int32*) &fNextID, 1); }
|
||||||
@@ -62,11 +68,14 @@ class PPPManager {
|
|||||||
void Pulse();
|
void Pulse();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
ppp_interface_id _CreateInterface(const char *name,
|
||||||
|
const driver_settings *settings, const driver_settings *profile,
|
||||||
|
ppp_interface_id parentID);
|
||||||
int32 FindUnit() const;
|
int32 FindUnit() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BLocker fLock, fReportLock;
|
BLocker fLock, fReportLock;
|
||||||
PPPReportManager fReportManager;
|
KPPPReportManager fReportManager;
|
||||||
TemplateList<ppp_interface_entry*> fEntries;
|
TemplateList<ppp_interface_entry*> fEntries;
|
||||||
ppp_interface_id fNextID;
|
ppp_interface_id fNextID;
|
||||||
thread_id fDeleterThread, fPulseTimer;
|
thread_id fDeleterThread, fPulseTimer;
|
||||||
|
|||||||
@@ -88,10 +88,23 @@ ppp_control(uint32 op, void *data, size_t length)
|
|||||||
|
|
||||||
static
|
static
|
||||||
ppp_interface_id
|
ppp_interface_id
|
||||||
CreateInterface(const driver_settings *settings, ppp_interface_id parent)
|
CreateInterface(const driver_settings *settings, const driver_settings *profile,
|
||||||
|
ppp_interface_id parent)
|
||||||
{
|
{
|
||||||
if(sManager)
|
if(sManager)
|
||||||
return sManager->CreateInterface(settings, parent);
|
return sManager->CreateInterface(settings, profile, parent);
|
||||||
|
else
|
||||||
|
return PPP_UNDEFINED_INTERFACE_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
ppp_interface_id
|
||||||
|
CreateInterfaceWithName(const char *name, const driver_settings *profile,
|
||||||
|
ppp_interface_id parent)
|
||||||
|
{
|
||||||
|
if(sManager)
|
||||||
|
return sManager->CreateInterfaceWithName(name, profile, parent);
|
||||||
else
|
else
|
||||||
return PPP_UNDEFINED_INTERFACE_ID;
|
return PPP_UNDEFINED_INTERFACE_ID;
|
||||||
}
|
}
|
||||||
@@ -216,6 +229,7 @@ ppp_interface_module_info ppp_interface_module = {
|
|||||||
ppp_control
|
ppp_control
|
||||||
},
|
},
|
||||||
CreateInterface,
|
CreateInterface,
|
||||||
|
CreateInterfaceWithName,
|
||||||
DeleteInterface,
|
DeleteInterface,
|
||||||
RemoveInterface,
|
RemoveInterface,
|
||||||
RegisterInterface,
|
RegisterInterface,
|
||||||
|
|||||||
Reference in New Issue
Block a user