diff options
author | Chinh Tran <chinht@quicinc.com> | 2010-02-19 10:19:28 -0800 |
---|---|---|
committer | Chinh Tran <chinht@quicinc.com> | 2010-03-02 09:01:40 -0800 |
commit | 5cb9e15b1067eb0523f1016d997dddd35f229d58 (patch) | |
tree | e386325b6ad8699935b6e4d4ae80df3ac45953f4 | |
parent | 9850d1b062e7a5832bc3b66b814369cb57867093 (diff) | |
download | android_external_connectivity-5cb9e15b1067eb0523f1016d997dddd35f229d58.tar.gz android_external_connectivity-5cb9e15b1067eb0523f1016d997dddd35f229d58.tar.bz2 android_external_connectivity-5cb9e15b1067eb0523f1016d997dddd35f229d58.zip |
external/connectivity/(CNE): Fix SPM init problem, multiple default entries in main routing table, dynamic loading Cne/RefCne
Add APIs to delete duplicate entries in main routing table. Do not check data pointer and datalength for non-data commmand.
CRs-fixed: 227375, 227511
-rw-r--r-- | cnd/inc/cnd_event.h | 7 | ||||
-rw-r--r-- | cnd/src/Android.mk | 1 | ||||
-rw-r--r-- | cnd/src/cnd_event.cpp | 50 | ||||
-rw-r--r-- | cnd/src/cnd_iproute2.cpp | 657 | ||||
-rw-r--r-- | cnd/src/cnd_process.cpp | 32 |
5 files changed, 419 insertions, 328 deletions
diff --git a/cnd/inc/cnd_event.h b/cnd/inc/cnd_event.h index 45a6f74..8c47ee1 100644 --- a/cnd/inc/cnd_event.h +++ b/cnd/inc/cnd_event.h @@ -1,3 +1,5 @@ +#ifndef CNE_EVENT_H +#define CNE_EVENT_H /* ** Copyright 2006, The Android Open Source Project ** Copyright (c) 2010, Code Aurora Forum. All rights reserved. @@ -14,11 +16,15 @@ ** See the License for the specific language governing permissions and ** limitations under the License. */ +#include "cne.h" // Max number of fd's we watch at any one time. Increase if necessary. #define MAX_FD_EVENTS 8 typedef void (*cnd_event_cb)(int fd, void *userdata); +typedef int (*cneIntFnType)(void); +typedef void (*cneProcessCmdFnType)(int, void*,size_t); +typedef void (*cneRegMsgCbFnType)(cne_messageCbType); struct cnd_event { struct cnd_event *next; @@ -51,3 +57,4 @@ void cnd_event_loop(); // Dump watch table for debugging void cnd_dump_watch_table(); +#endif /* CNE_EVENT_H */ diff --git a/cnd/src/Android.mk b/cnd/src/Android.mk index 3de8b35..836debd 100644 --- a/cnd/src/Android.mk +++ b/cnd/src/Android.mk @@ -19,7 +19,6 @@ LOCAL_SHARED_LIBRARIES := \ libutils \ libcutils \ libhardware_legacy \ - librefcne LOCAL_C_INCLUDES := \ external/connectivity/cnd/inc \ diff --git a/cnd/src/cnd_event.cpp b/cnd/src/cnd_event.cpp index a35794f..2002242 100644 --- a/cnd/src/cnd_event.cpp +++ b/cnd/src/cnd_event.cpp @@ -27,6 +27,9 @@ #include <sys/time.h> #include <time.h> #include <pthread.h> +#include <dlfcn.h> +#include "cutils/properties.h" +#include "cne.h" static pthread_mutex_t listMutex; #define MUTEX_ACQUIRE() pthread_mutex_lock(&listMutex) @@ -34,7 +37,8 @@ static pthread_mutex_t listMutex; #define MUTEX_INIT() pthread_mutex_init(&listMutex, NULL) #define MUTEX_DESTROY() pthread_mutex_destroy(&listMutex) -extern "C" int cne_svc_init(void); +cneProcessCmdFnType cne_processCommand; +cneRegMsgCbFnType cne_regMessageCb; static fd_set readFds; static int nfds = 0; @@ -144,7 +148,49 @@ int cnd_event_init() FD_ZERO(&readFds); init_list(&pending_list); memset(watch_table, 0, sizeof(watch_table)); - return(cne_svc_init()); + + void* cneLibHandle; + cneIntFnType cne_svc_init = NULL; + char prop_value[PROPERTY_VALUE_MAX] = {'\0'}; + int len = property_get("persist.cne.loadVendorCne", prop_value, "FALSE"); + prop_value[len] = '\0'; + if((strcmp(prop_value, "TRUE") == 0) ||(strcmp(prop_value, "true") == 0)) + { + LOGI("loading cne library!!"); + cneLibHandle = dlopen("/system/lib/libcne.so",RTLD_NOW); + } + else + { + LOGI("loading refcne library!!"); + cneLibHandle = dlopen("/system/lib/librefcne.so",RTLD_NOW); + } + + if(cneLibHandle != NULL) + { + cne_svc_init = (cneIntFnType)dlsym(cneLibHandle, "cne_svc_init"); + cne_processCommand = (cneProcessCmdFnType)dlsym(cneLibHandle, + "cne_processCommand"); + cne_regMessageCb = (cneRegMsgCbFnType)dlsym(cneLibHandle, + "cne_regMessageCb"); + } + else + { + LOGE("cne library load failed.!!"); + } + if(cne_svc_init == NULL || cne_processCommand == NULL || + cne_regMessageCb == NULL) + { + LOGE("dlsym ret'd cne_svc_init=%x cne_processCommand=%x cne_regMessageCb=%x", + cne_svc_init, + cne_processCommand, + cne_regMessageCb); + } + else + { + return(cne_svc_init()); + } + + return CNE_SERVICE_DISABLED; } // Initialize an event diff --git a/cnd/src/cnd_iproute2.cpp b/cnd/src/cnd_iproute2.cpp index 6596c92..1b71f7d 100644 --- a/cnd/src/cnd_iproute2.cpp +++ b/cnd/src/cnd_iproute2.cpp @@ -33,12 +33,13 @@ iproute2 in order to set up and take down routing tables. These calls are made indirectly over the command line by using a call to the C++ system() function. For each routing device - visible to the kernel, CneIproute2 allows one table. Each - table contains one entry, a path to the gateway address of the + visible to the kernel, cnd_iproute2 allows one table. Each + table contains one entry, a default path to the inputted routing device. A source address or network prefix is also required in order to instantiate a table, so that packets from - that ip address are routed through the device. - + that ip address are routed through the device. A gateway + address can also be inputted optionally for a newly added + routing table. DEPENDENCIES: None ============================================================================*/ @@ -59,7 +60,7 @@ using namespace std; * Preprocessor Definitions and Constants * -------------------------------------------------------------------------*/ #undef LOG_TAG -#define LOG_TAG "CNDIPROUTE2" +#define LOG_TAG "CND_IPROUTE2" /*---------------------------------------------------------------------------- * Type Declarations @@ -75,12 +76,20 @@ enum Cmd_line_actions ACTIONS_SHOW_ENUM }; +// Comparator function for use in the map of active interfaces. +struct deviceMapComparator { + bool operator() (const uint8_t *string1, const uint8_t *string2) const + { + return (strcmp((char *)string1, (char *)string2) < 0); + } +}; + /** Stores information needed to create a routing table and a rule. This -* allows the calling class to delete that table without needing to -* keep track of any characteristics of the device other than its name. -* Assumes that there can only be 1 rule associated with any defined -* table. -*/ + * allows the calling class to delete that table without needing to + * keep track of any characteristics of the device other than its name. + * Assumes that there can only be 1 rule associated with any defined + * table. + */ class DeviceInfo { private: @@ -93,6 +102,32 @@ class DeviceInfo uint8_t *sourcePrefix; int32_t priorityNumber; + // Copies inputted pointer to permanent storage, returning the pointer to + // the newly allocated space. + uint8_t *storeDeviceInformation(uint8_t *parameterPtr) + { + + if(parameterPtr == NULL) + { + LOGE("storeDeviceInformation: invalid parameter"); + return NULL; + } + uint8_t *deviceInfoPtr = + new (nothrow) uint8_t[strlen((char*)parameterPtr) + 1]; + + if (deviceInfoPtr == NULL ) + { + LOGE("storeDeviceInformation: unable to allocate memory"); + return NULL; + } + int newByteLength = strlen((char *)parameterPtr) * sizeof(uint8_t); + + memcpy(deviceInfoPtr, parameterPtr, newByteLength + 1); + deviceInfoPtr[newByteLength] = '\0'; + + return deviceInfoPtr; + } + public: DeviceInfo ( @@ -103,30 +138,32 @@ class DeviceInfo int32_t priorityNumber ) { - DeviceInfo::deviceName = deviceName; + DeviceInfo::deviceName = storeDeviceInformation(deviceName); DeviceInfo::tableNumber = tableNumber; - DeviceInfo::gatewayAddress = gatewayAddress; - DeviceInfo::sourcePrefix = sourcePrefix; + if (('\0' != gatewayAddress) && (NULL != gatewayAddress)) + { + DeviceInfo::gatewayAddress = storeDeviceInformation(gatewayAddress); + } + + else + { + DeviceInfo::gatewayAddress = '\0'; + } + + DeviceInfo::sourcePrefix = storeDeviceInformation(sourcePrefix); DeviceInfo::priorityNumber = priorityNumber; } - DeviceInfo - ( - uint8_t *deviceName, - int32_t tableNumber, - uint8_t *sourcePrefix, - int32_t priorityNumber - ) + ~DeviceInfo() { - DeviceInfo::deviceName = deviceName; - DeviceInfo::tableNumber = tableNumber; - DeviceInfo::gatewayAddress = '\0'; - DeviceInfo::sourcePrefix = sourcePrefix; - DeviceInfo::priorityNumber = priorityNumber; + delete [] DeviceInfo::deviceName; + delete [] DeviceInfo::sourcePrefix; + if (('\0' != DeviceInfo::gatewayAddress) && (NULL != gatewayAddress)) + { + delete [] DeviceInfo::gatewayAddress; + } } - ~DeviceInfo(); - uint8_t* getDeviceName(void) { return deviceName; @@ -151,17 +188,33 @@ class DeviceInfo { return tableNumber; } + + void setGatewayAddress(uint8_t *gatewayAddress) + { + if (('\0' != DeviceInfo::gatewayAddress) && (NULL != gatewayAddress)) + { + delete [] DeviceInfo::gatewayAddress; + } + + DeviceInfo::gatewayAddress = storeDeviceInformation(gatewayAddress); + } + + void setSourcePrefix(uint8_t *sourcePrefix) + { + delete [] DeviceInfo::sourcePrefix; + DeviceInfo::sourcePrefix = storeDeviceInformation(sourcePrefix); + } }; /*---------------------------------------------------------------------------- * Global Data Definitions * -------------------------------------------------------------------------*/ -//Set of all table numbers currently being used. Cannot contain more than -//MAX_TABLE_SIZE - MIN_TABLE_SIZE elements +// Set of all table numbers currently being used. Cannot contain more than +// MAX_TABLE_NUMBER - MIN_TABLE_NUMBER elements set<int32_t> tableNumberSet; // Maps the name of a device to its corresponding routing characteristics -map<uint8_t*, DeviceInfo*> deviceMap; +map<uint8_t*, DeviceInfo*, deviceMapComparator> deviceMap; // If a packet does not have an associated rule, it will go to the main // routing table and be routed to the following device by default @@ -175,7 +228,7 @@ static const uint8_t *ROUTING_CMD = (uint8_t *)"ip route"; static const uint8_t *RULE_CMD = (uint8_t *)"ip rule"; // List of all actions supported from iproute2. These should match values in -// above enumeration 'Cnd_line_actions' +// above enumeration 'Cmd_line_actions' static const uint8_t *ACTIONS_ADD_STR = (uint8_t *)"add"; static const uint8_t *ACTIONS_DELETE_STR = (uint8_t *)"delete"; static const uint8_t *ACTIONS_FLUSH_STR = (uint8_t *)"flush"; @@ -204,10 +257,10 @@ static const int32_t MAX_TABLE_NUMBER = 252; // Priority number 32766 diverts packets to the main table (Table #254) static const int32_t MAX_PRIORITY_NUMBER = 32765; -//Max number of digits in a table number is 3 +// Max number of digits in a table number is 3 static const int32_t MAX_DIGITS_TABLE_NUMBER = 3; -//Max number of digits in a priority number is 5 +// Max number of digits in a priority number is 5 static const int32_t MAX_DIGITS_PRIORITY_NUMBER = 5; cnd_iproute2* cnd_iproute2::instancePtr = NULL; @@ -245,21 +298,6 @@ bool modifyRule Cmd_line_actions commandAction ); -bool displayAllRoutingTables -( - void -); - -bool displayRoutingTable -( - uint8_t *deviceName -); - -bool displayRules -( - void -); - bool cmdLineCaller ( const uint8_t* cmdLineFirstWord, @@ -359,14 +397,17 @@ void flushCache * FUNCTION modifyDefaultRoute * DESCRIPTION Changes the default route given the name of the device that - will be either the new or old default. The default case - occurs if a packet is sent from some source address not - associated with a defined table. When this occurs, the main - table will route these undefined source addresses to the - gateway of the defined default device. This function will - add or delete that default route in the main table. - - * DEPENDENCIES commandAction should be either ADD OR DELETE + will be the new default. The default case occurs if a packet + is sent from some source address not associated with a defined + table. When this occurs, the main table will route these + undefined source addresses to the gateway of the defined + default device. This function will add or delete that default + route in the main table. If a default route is being deleted, + no input is required for deviceName. The 'replace' command + will change the default entry already existing in the main + routing table, or add the entry if it does not exist. + + * DEPENDENCIES commandAction should be either REPLACE OR DELETE * RETURN VALUE bool - True if function is successful. False otherwise. @@ -378,34 +419,26 @@ bool modifyDefaultRoute Cmd_line_actions commandAction ) { - if ('\0' == deviceName) - { - LOGE("A null device name was passed while changing the default table. "); - return false; - } - - // If the upcoming command line call fails, revert to last default device - DeviceInfo *lastDefaultDevice = defaultDevice; - uint8_t *gatewayAddress; switch(commandAction) { - case ACTIONS_ADD_ENUM: - { - LOGE("Cannot add a routing table directly. Most use 'replace'"); - return false; - } case ACTIONS_REPLACE_ENUM: { - // No need to perform function if the default device will not change - if (('\0' != defaultDevice) && + if (('\0' == deviceName) || (NULL == deviceName)) + { + LOGE("A null device name was passed while replacing the default table"); + return false; + } + + // Case where the default device known by cnd is the same as the new + // device that is replacing it. + if (('\0' != defaultDevice) && (NULL != defaultDevice) && (0 == strcmp((char *)defaultDevice->getDeviceName(), (char *)deviceName))) { - LOGW("The new default interface %s is the same as the old.", + LOGW("The new default interface %s is the same as the one known by cnd", deviceName); - return true; } LOGI("Replacing default routing table with %s", deviceName); @@ -420,8 +453,15 @@ bool modifyDefaultRoute return false; } + if (deviceMapIter->second == NULL) { + LOGE("Adding a default table with no known device information"); + return false; + } + defaultDevice = deviceMapIter->second; - LOGI("Default device has a stored name of %s.", defaultDevice->getDeviceName()); + + LOGI("Default device has a stored name of %s.", + defaultDevice->getDeviceName()); break; } @@ -429,9 +469,9 @@ bool modifyDefaultRoute { // The following case should only be entered if the default table is // being deleted when no tables exist - if ('\0' == defaultDevice) + if (('\0' == defaultDevice) || (NULL == defaultDevice)) { - LOGE("Cannot delete a default table when none exists."); + LOGE("No stored default device; use deleteDefaultEntryFromMainTable."); return false; } @@ -449,40 +489,34 @@ bool modifyDefaultRoute gatewayAddress = defaultDevice->getGatewayAddress(); - if ('\0' == gatewayAddress) + // These commands may fail if the kernel has already executed an operation on + // its own. Treat a call to modify the main table as if was successful. + if (('\0' == gatewayAddress) || (NULL == gatewayAddress)) { - if (!cmdLineCaller(ROUTING_CMD, - cmdLineActionEnumToString(commandAction), - DEFAULT_ADDRESS, - CMD_LINE_DEVICE_NAME, - defaultDevice->getDeviceName(), - NULL)) - { - defaultDevice = lastDefaultDevice; - return false; - } + cmdLineCaller(ROUTING_CMD, + cmdLineActionEnumToString(commandAction), + DEFAULT_ADDRESS, + CMD_LINE_DEVICE_NAME, + defaultDevice->getDeviceName(), + NULL); } else { - if (!cmdLineCaller(ROUTING_CMD, - cmdLineActionEnumToString(commandAction), - DEFAULT_ADDRESS, - CMD_LINE_GATEWAY_ADDRESS, - gatewayAddress, - CMD_LINE_DEVICE_NAME, - defaultDevice->getDeviceName(), - NULL)) - { - defaultDevice = lastDefaultDevice; - return false; - } + cmdLineCaller(ROUTING_CMD, + cmdLineActionEnumToString(commandAction), + DEFAULT_ADDRESS, + CMD_LINE_GATEWAY_ADDRESS, + gatewayAddress, + CMD_LINE_DEVICE_NAME, + defaultDevice->getDeviceName(), + NULL); } if (ACTIONS_DELETE_ENUM == commandAction) { - // After a deletion, there should be default device defined - // in the main routing table - defaultDevice = '\0'; + // After a deletion, there should be no default device defined in the main + // routing table + defaultDevice = NULL; } flushCache(); @@ -494,12 +528,13 @@ bool modifyDefaultRoute * FUNCTION modifyRoutingTable * DESCRIPTION Adds or deletes a routing table given the name of the device - associated with that table. This routing table has one route, - which will route all packets to some gateway address from - some inputted source address. Once the table has been - modified, modifyRoutingTable will call another function to - create or delete a rule that maps some source address' - packets to this table. + This routing table has one route, which will route all packets + to the device with the inputted name. This route can + optionally be set up to send packets through an inputted + gateway address. Once the table has been modified, + modifyRoutingTable will call another function to create or + delete a rule that maps some source address' packets to this + table. * DEPENDENCIES commandAction should be either ADD OR DELETE @@ -515,12 +550,6 @@ bool modifyRoutingTable Cmd_line_actions commandAction ) { - if ('\0' == deviceName) - { - LOGE("A null device name was passed while modifying a routing table"); - return false; - } - int32_t tableNumber; int32_t priorityNumber; @@ -528,69 +557,106 @@ bool modifyRoutingTable map<uint8_t*, DeviceInfo*>::iterator deviceMapIter; set<int32_t>::iterator tableNumberSetIter; + if (('\0' == deviceName) || (NULL == deviceName)) + { + LOGE("A null device name was passed while modifying a routing table"); + return false; + } + switch(commandAction) { case ACTIONS_ADD_ENUM: { LOGI("Adding a routing table for interface %s", deviceName); - if ('\0' == sourcePrefix) + if (('\0' == sourcePrefix) || (NULL == sourcePrefix)) { LOGE("A null source prefix was passed when adding the %s table", deviceName); return false; } - if ('\0' == gatewayAddress) + if (('\0' == gatewayAddress) || (NULL == gatewayAddress)) { - LOGW("A null gateway address was passed when adding the %s table", + LOGI("A null gateway address was passed when adding the %s table", deviceName); - //return false; } deviceMapIter = deviceMap.find(deviceName); + if ((deviceMapIter != deviceMap.end()) && + (NULL == deviceMapIter->second)) + { + LOGW("Adding duplicate routing table with corrupt device information"); + deviceMap.erase(deviceName); + } + // If a call to add a routing table overwrites an existing table, the // new source and gateway addresses will overwrite the old ones. // However, calls to add a duplicate table, where the source and - // gateway addresses do not change, are ignored and will not be - // considered a fatal error. - if (deviceMapIter != deviceMap.end()) + // gateway addresses do not change, are ignored and will simply return + // true. + else if (deviceMapIter != deviceMap.end()) { DeviceInfo *existingDevice = deviceMapIter->second; - // if ((('\0' != (char *)existingDevice->getGatewayAddress()) && - // ('\0' == (char *)gatewayAddress)) || - // (('\0' == (char *)existingDevice->getGatewayAddress()) && - // ('\0' != (char *)gatewayAddress)) || - // (0 != strcmp((char *)existingDevice->getGatewayAddress(), - // (char *)gatewayAddress)) || + int isNewSourcePrefix = strcmp((char *)existingDevice->getSourcePrefix(), + (char *)sourcePrefix); - //Check for differences between gateway addresses. - if (0 != strcmp((char *)existingDevice->getSourcePrefix(), - (char *)sourcePrefix)) - { - //Delete existing device with the same name - modifyRoutingTable(deviceName, '\0', '\0', ACTIONS_DELETE_ENUM); + uint8_t *existingGateway = existingDevice->getGatewayAddress(); - //Delete default device that will be overwritten. New default will - //be added later - if (('\0' != defaultDevice) && (defaultDevice == existingDevice)) + // Because the gateway address is an optional parameter, must account + // for cases where the gateway address changes from null to non-null or + // vice-versa + if ( !(('\0' == existingGateway) || (NULL == existingGateway)) && + (('\0' == gatewayAddress) || (NULL == gatewayAddress)) ) + { + if ( ('\0' == gatewayAddress) || (NULL == gatewayAddress) || + ('\0' == existingGateway) || (NULL == existingGateway) || + (0 != strcmp((char *)existingGateway, + (char *)gatewayAddress))) { - modifyDefaultRoute('\0', ACTIONS_DELETE_ENUM); + // Replace active table and rule with changes to gateway address and + // possibly the source prefix, if it has changed. + commandAction = ACTIONS_REPLACE_ENUM; + + modifyRule(existingDevice, ACTIONS_DELETE_ENUM); + + existingDevice->setGatewayAddress(gatewayAddress); + + if (0 != isNewSourcePrefix) + { + existingDevice->setSourcePrefix(sourcePrefix); + } + + tableNumber = existingDevice->getTableNumber(); + + break; } } + // Check for differences between source addresses. If a change in the + // gateway address has already been detected, this step of modifying the + // rule will be done implicitly. + else if (0 != isNewSourcePrefix) + { + modifyRule(existingDevice, ACTIONS_DELETE_ENUM); + existingDevice->setSourcePrefix(sourcePrefix); + modifyRule(existingDevice, ACTIONS_ADD_ENUM); + + return true; + } + else { - if ('\0' == gatewayAddress) + if (('\0' == gatewayAddress) || (NULL == gatewayAddress)) { - LOGW("Adding a duplicate %s table with source %s", + LOGI("Adding a duplicate %s table with source %s.", deviceName, sourcePrefix); return true; } else { - LOGW("Adding a duplicate %s table with gateway %s and source %s", + LOGI("Adding a duplicate %s table with gateway %s and source %s.", deviceName, sourcePrefix, gatewayAddress); return true; } @@ -626,21 +692,22 @@ bool modifyRoutingTable // reuse of priority numbers. priorityNumber = MAX_PRIORITY_NUMBER - tableNumber + 1; - if ('\0' == gatewayAddress) - { - currentDevice = new DeviceInfo(deviceName, - tableNumber, - sourcePrefix, - priorityNumber); - } - - else + currentDevice = new DeviceInfo(deviceName, + tableNumber, + gatewayAddress, + sourcePrefix, + priorityNumber); + + // Gateway address may be null, which is allowed. However, if an + // optional gateway address was inputted, it will be lost in the + // iproute2 call + if ((NULL == currentDevice) || + (NULL == currentDevice->getDeviceName()) || + (NULL == currentDevice->getSourcePrefix())) { - currentDevice = new DeviceInfo(deviceName, - tableNumber, - gatewayAddress, - sourcePrefix, - priorityNumber); + LOGE("Failed to allocate new device information while adding table %s.", + deviceName); + return false; } break; @@ -665,6 +732,12 @@ bool modifyRoutingTable } currentDevice = deviceMapIter->second; + if (currentDevice == NULL) + { + LOGE("Deleting table with a stored name and null value"); + return false; + } + gatewayAddress = currentDevice->getGatewayAddress(); tableNumber = currentDevice->getTableNumber(); break; @@ -677,7 +750,7 @@ bool modifyRoutingTable } } - //Convert table number int to string, null-terminating the result + // Convert table number int to string, null-terminating the result char tableNumberString[MAX_DIGITS_TABLE_NUMBER+1]; int32_t numberOfDigits = snprintf(tableNumberString, MAX_DIGITS_TABLE_NUMBER+1, @@ -685,48 +758,47 @@ bool modifyRoutingTable tableNumber); tableNumberString[numberOfDigits] = '\0'; - if ('\0' == gatewayAddress) + if (('\0' == gatewayAddress) || (NULL == gatewayAddress)) { - if (!cmdLineCaller(ROUTING_CMD, - cmdLineActionEnumToString(commandAction), - DEFAULT_ADDRESS, - CMD_LINE_DEVICE_NAME, - deviceName, - CMD_LINE_TABLE_NUMBER, - (uint8_t *)tableNumberString, - NULL)) - { - return false; - } + cmdLineCaller(ROUTING_CMD, + cmdLineActionEnumToString(commandAction), + DEFAULT_ADDRESS, + CMD_LINE_DEVICE_NAME, + deviceName, + CMD_LINE_TABLE_NUMBER, + (uint8_t *)tableNumberString, + NULL); } else { - if (!cmdLineCaller(ROUTING_CMD, - cmdLineActionEnumToString(commandAction), - DEFAULT_ADDRESS, - CMD_LINE_GATEWAY_ADDRESS, - gatewayAddress, - CMD_LINE_DEVICE_NAME, - deviceName, - CMD_LINE_TABLE_NUMBER, - (uint8_t *)tableNumberString, - NULL)) - { - return false; - } + cmdLineCaller(ROUTING_CMD, + cmdLineActionEnumToString(commandAction), + DEFAULT_ADDRESS, + CMD_LINE_GATEWAY_ADDRESS, + gatewayAddress, + CMD_LINE_DEVICE_NAME, + deviceName, + CMD_LINE_TABLE_NUMBER, + (uint8_t *)tableNumberString, + NULL); } switch(commandAction) { + // This case should not break to account for common code with the replace + // command. case ACTIONS_ADD_ENUM: { - deviceMap.insert(make_pair(deviceName, currentDevice)); + deviceMap.insert(make_pair(currentDevice->getDeviceName(),currentDevice)); tableNumberSet.insert(tableNumber); + } + case ACTIONS_REPLACE_ENUM: + { // If there is no default table, the new device should be the default. if ('\0' == defaultDevice) { - LOGI("Adding default table when no default exists"); + LOGI("Routing table added when no default exists. Adding new default."); modifyDefaultRoute(deviceName, ACTIONS_REPLACE_ENUM); } @@ -741,7 +813,7 @@ bool modifyRoutingTable // If there are no more tables, then there should be no default device. if (0 == tableNumberSet.size()) { - LOGI("Removing default table when no devices are up"); + LOGI("Removing default table after no devices are known to be up"); modifyDefaultRoute('\0', ACTIONS_DELETE_ENUM); } @@ -752,7 +824,6 @@ bool modifyRoutingTable uint8_t *newDefaultName = deviceMap.begin()->first; LOGI("Replacing old default device with %s", newDefaultName); - //modifyDefaultRoute('\0', ACTIONS_DELETE_ENUM); modifyDefaultRoute(newDefaultName, ACTIONS_REPLACE_ENUM); } @@ -763,7 +834,21 @@ bool modifyRoutingTable break; } - return modifyRule(currentDevice, commandAction); + // There is no 'ip rule replace' command. When a gateway address is changed, + // must delete the rule and add it back. + if (ACTIONS_REPLACE_ENUM == commandAction) { + commandAction = ACTIONS_ADD_ENUM; + } + + bool modifyRuleRetValue = modifyRule(currentDevice, commandAction); + + // Delete device information that will no longer be used + if (ACTIONS_DELETE_ENUM == commandAction) + { + delete currentDevice; + } + + return modifyRuleRetValue; } /*---------------------------------------------------------------------------- @@ -790,7 +875,7 @@ bool modifyRule Cmd_line_actions commandAction ) { - if ('\0' == currentDevice) + if (('\0' == currentDevice) || (NULL == currentDevice)) { LOGE("A null device was passed while modifying a rule"); return false; @@ -803,7 +888,7 @@ bool modifyRule // If a rule is being added, its corresponding table should exist in the map // of all routing tables. if ((ACTIONS_ADD_ENUM == commandAction) && - (deviceMapIter == deviceMap.end())) + (deviceMapIter == deviceMap.end())) { LOGE("Cannot %s a rule for nonexistant table %s", cmdLineActionEnumToString(commandAction), @@ -815,8 +900,8 @@ bool modifyRule int32_t priorityNumber = currentDevice->getPriorityNumber(); uint8_t *sourcePrefix = currentDevice->getSourcePrefix(); - //Convert table number & priority number ints to string, null-terminating - //the results + // Convert table number & priority number ints to string, null-terminating + // the results char tableNumberString[MAX_DIGITS_TABLE_NUMBER+1]; char priorityNumberString[MAX_DIGITS_PRIORITY_NUMBER+1]; @@ -832,18 +917,15 @@ bool modifyRule priorityNumber); priorityNumberString[numberOfDigits] = '\0'; - if (!cmdLineCaller(RULE_CMD, - cmdLineActionEnumToString(commandAction), - CMD_LINE_SOURCE_PREFIX, - sourcePrefix, - CMD_LINE_TABLE_NUMBER, - (uint8_t *)tableNumberString, - CMD_LINE_PRIORITY_NUMBER, - (uint8_t *)priorityNumberString, - NULL)) - { - return false; - } + cmdLineCaller(RULE_CMD, + cmdLineActionEnumToString(commandAction), + CMD_LINE_SOURCE_PREFIX, + sourcePrefix, + CMD_LINE_TABLE_NUMBER, + (uint8_t *)tableNumberString, + CMD_LINE_PRIORITY_NUMBER, + (uint8_t *)priorityNumberString, + NULL); flushCache(); @@ -851,89 +933,15 @@ bool modifyRule } /*---------------------------------------------------------------------------- - * FUNCTION displayAllRoutingTables - - * DESCRIPTION Displays contents of all routing tables - - * DEPENDENCIES None - - * RETURN VALUE bool - True if function is successful. False otherwise. - - * SIDE EFFECTS None - *--------------------------------------------------------------------------*/ -bool displayAllRoutingTables -( - void -) -{ - return cmdLineCaller(ROUTING_CMD, - cmdLineActionEnumToString(ACTIONS_SHOW_ENUM), - CMD_LINE_TABLE_NUMBER, - ALL_TABLES, - NULL); -} - -/*---------------------------------------------------------------------------- - * FUNCTION displayRoutingTable - - * DESCRIPTION Displays contents of the inputted routing table - - * DEPENDENCIES None - - * RETURN VALUE bool - True if function is successful. False otherwise. - - * SIDE EFFECTS None - *--------------------------------------------------------------------------*/ -bool displayRoutingTable -( - uint8_t *deviceName -) -{ - if ('\0' == deviceName) - { - LOGE("A null argument was passed while displaying table %s.", - deviceName); - return false; - } - - return cmdLineCaller(ROUTING_CMD, - cmdLineActionEnumToString(ACTIONS_SHOW_ENUM), - CMD_LINE_TABLE_NUMBER, - deviceName, - NULL); -} - -/*---------------------------------------------------------------------------- - * FUNCTION displayRules - - * DESCRIPTION Displays all rules currently entered in the system - - * DEPENDENCIES None - - * RETURN VALUE bool - True if function is successful. False otherwise. - - * SIDE EFFECTS None - *--------------------------------------------------------------------------*/ -bool displayRules -( - void -) -{ - return cmdLineCaller(RULE_CMD, - cmdLineActionEnumToString(ACTIONS_SHOW_ENUM), - NULL); -} - -/*---------------------------------------------------------------------------- * FUNCTION cmdLineCaller * DESCRIPTION Sends a call to iproute2 over the command line. This function takes in a list of an arbitrary number of words, which is parsed together into one final string. This string is sent - over the command line using the C routine 'system'. Two - readers are instantiated to monitor any standard error and - standard output messages sent out by iproute2. These messages - are then passed to the Android log. + over the command line using the C routine 'system'. To see + the standard output of a failed command in the ADB logs, the + 'logwrapper' utility must be used while instantiating the cnd + process. * DEPENDENCIES Should not be any spaces in any inputted argument @@ -954,19 +962,18 @@ bool cmdLineCaller uint8_t *nextWord; char *cmdLineString; - if ('\0' == cmdLineFirstWord) + if (('\0' == cmdLineFirstWord) || (NULL == cmdLineFirstWord)) { LOGE("No actual command passed to build a command line."); return false; } - //Find length of overall command line string to determine how much - //space to allocate for it + // Find length of overall command line string to determine how much + // space to allocate for it byteLength = strlen((char *)cmdLineFirstWord); va_start(cmdLineWordList, cmdLineFirstWord); - while(((nextWord = va_arg(cmdLineWordList,uint8_t*)) != NULL) && - (nextWord != '\0')) + while((nextWord = va_arg(cmdLineWordList,uint8_t*)) != NULL) { byteLength += strlen((char *)nextWord); numberOfSpaces++; @@ -974,11 +981,11 @@ bool cmdLineCaller va_end(cmdLineWordList); - //Allocate command line string, which is number of bytes in inputted words - //plus the null character, plus the number of white spaces. - cmdLineString = new (nothrow) char[byteLength+numberOfSpaces+1]; + // Allocate command line string, which is number of bytes in inputted words + // plus the null character, plus the number of white spaces. + cmdLineString = new (nothrow) char[byteLength + numberOfSpaces + 1]; - if (cmdLineString == '\0') + if (NULL == cmdLineString) { LOGE("Could not allocate memory to build command line string."); return false; @@ -994,13 +1001,12 @@ bool cmdLineCaller return false; } - //Build command line string containing each inputted word. + // Build command line string containing each inputted word. va_start(cmdLineWordList, cmdLineFirstWord); - while(((nextWord = va_arg(cmdLineWordList,uint8_t*)) != NULL) && - (*nextWord != '\0')) + while((nextWord = va_arg(cmdLineWordList,uint8_t*)) != NULL) { - //Add white space + // Add white space memLength = strlcat(cmdLineString, " ", strlen(cmdLineString) * sizeof(char) + @@ -1009,10 +1015,11 @@ bool cmdLineCaller { LOGE("Failure adding whitespace to command line string."); delete [] cmdLineString; + va_end(cmdLineWordList); return false; } - //Add next word + // Add next word memLength = strlcat(cmdLineString, (char *)nextWord, strlen(cmdLineString) * sizeof(char) + @@ -1022,13 +1029,14 @@ bool cmdLineCaller { LOGE("Failure adding next word to command line string."); delete [] cmdLineString; + va_end(cmdLineWordList); return false; } } va_end(cmdLineWordList); - cmdLineString[byteLength+numberOfSpaces] = '\0'; + cmdLineString[byteLength + numberOfSpaces] = '\0'; LOGI("Iproute2 will be called with: %s", cmdLineString); @@ -1052,9 +1060,10 @@ bool cmdLineCaller * FUNCTION addRoutingTable * DESCRIPTION Adds a routing table to the system that contains a single - default entry, a route to the gateway address of a device. - It also adds a rule to route a given source network prefix or - address to the new table. + default entry, a route to the device with the inputted name, + which will optionally route through an inputted gateway + address. It also adds a rule to route a given source network + prefix or address to the new table. The parameter deviceName refers to the name of the device whose table will be added (Such as wlan or wwan) @@ -1098,7 +1107,8 @@ bool cnd_iproute2::addRoutingTable must have been added through addRoutingTable() before it can be the default. - * DEPENDENCIES None + * DEPENDENCIES The new default table must have already been added via the + addRoutingTable API. * RETURN VALUE bool - True if function is successful. False otherwise. @@ -1123,7 +1133,8 @@ bool cnd_iproute2::changeDefaultTable * DESCRIPTION Deletes a routing table from the system along with the rule corresponding to that table. - * DEPENDENCIES None + * DEPENDENCIES The table must have already been added via the addRoutingTable + API. * RETURN VALUE bool - True if function is successful. False otherwise. @@ -1159,21 +1170,21 @@ bool cnd_iproute2::deleteDefaultEntryFromMainTable uint8_t *deviceName ) { - LOGI("Deleting %s interface from main table.", deviceName); + LOGI("Deleting %s interface from main table.", deviceName); - if (!cmdLineCaller(ROUTING_CMD, - cmdLineActionEnumToString(ACTIONS_DELETE_ENUM), - DEFAULT_ADDRESS, - CMD_LINE_DEVICE_NAME, - deviceName, - NULL)) - { - return false; - } + if (!cmdLineCaller(ROUTING_CMD, + cmdLineActionEnumToString(ACTIONS_DELETE_ENUM), + DEFAULT_ADDRESS, + CMD_LINE_DEVICE_NAME, + deviceName, + NULL)) + { + return false; + } - flushCache(); + flushCache(); - return true; + return true; } /*---------------------------------------------------------------------------- * FUNCTION showAllRoutingTables @@ -1192,7 +1203,11 @@ bool cnd_iproute2::showAllRoutingTables void ) { - return displayAllRoutingTables(); + return cmdLineCaller(ROUTING_CMD, + cmdLineActionEnumToString(ACTIONS_SHOW_ENUM), + CMD_LINE_TABLE_NUMBER, + ALL_TABLES, + NULL); } /*---------------------------------------------------------------------------- @@ -1212,7 +1227,17 @@ bool cnd_iproute2::showRoutingTable uint8_t *deviceName ) { - return displayRoutingTable(deviceName); + if (('\0' == deviceName) || (NULL == deviceName)) + { + LOGE("A null device name was passed while displaying a table."); + return false; + } + + return cmdLineCaller(ROUTING_CMD, + cmdLineActionEnumToString(ACTIONS_SHOW_ENUM), + CMD_LINE_TABLE_NUMBER, + deviceName, + NULL); } /*---------------------------------------------------------------------------- @@ -1232,5 +1257,7 @@ bool cnd_iproute2::showRules void ) { - return displayRules(); + return cmdLineCaller(RULE_CMD, + cmdLineActionEnumToString(ACTIONS_SHOW_ENUM), + NULL); } diff --git a/cnd/src/cnd_process.cpp b/cnd/src/cnd_process.cpp index baf48c6..7d57e8f 100644 --- a/cnd/src/cnd_process.cpp +++ b/cnd/src/cnd_process.cpp @@ -159,8 +159,8 @@ static int checkAndDequeueRequestInfo(struct RequestInfo *pRI); static void cnd_commandComplete(CND_Token t, CND_Errno e, void *response, size_t responselen); extern "C" const char * requestToString(int request); -extern "C" void cne_processCommand (int command, void *data, size_t datalen); -extern "C" void cne_regMessageCb(cne_messageCbType cbFn); +extern "C" cneProcessCmdFnType cne_processCommand; +extern "C" cneRegMsgCbFnType cne_regMessageCb; /** Index == commandNumber */ static CommandInfo s_commands[] = { @@ -197,12 +197,6 @@ processCommand (int command, void *data, size_t datalen, CND_Token t) LOGD ("processCommand: command=%d, datalen=%d", command, datalen); - if ((data == NULL) || (datalen == 0)) { - - LOGE ("processCommand: invalid data"); - return; - } - /* Special handling for iproute2 command to setup iproute2 table */ if ((command == CNE_REQUEST_CONFIG_IPROUTE2_CMD) && (cneServiceEnabled)) { @@ -212,6 +206,10 @@ processCommand (int command, void *data, size_t datalen, CND_Token t) unsigned char *gatewayAddr = NULL; unsigned char *ifName = NULL; + if ((data == NULL) || (datalen ==0)) { + LOGE ("processCommand: invalid data"); + return; + } cmd = ((int *)data)[0]; ifName = ((unsigned char **)data)[1]; @@ -238,7 +236,14 @@ processCommand (int command, void *data, size_t datalen, CND_Token t) } - cne_processCommand(command, data, datalen); + if(cne_processCommand != NULL) + { + cne_processCommand(command, data, datalen); + } + else + { + LOGE("cne_processCommand is NULL"); + } cnd_commandComplete(t, CND_E_SUCCESS, NULL, 0); return; } @@ -1128,7 +1133,14 @@ cnd_init (void) s_registerCalled = 1; cneServiceEnabled = cnd_event_init(); - cne_regMessageCb(cnd_sendUnsolicitedMsg); + if(cne_regMessageCb != NULL) + { + cne_regMessageCb(cnd_sendUnsolicitedMsg); + } + else + { + LOGE("cne_regMessageCb is NULL"); + } s_fdListen = android_get_control_socket(SOCKET_NAME_CND); if (s_fdListen < 0) { |