net: add the check for the add and delete IP operation

To properly return the error case when adding an existing
IP or delete a not existed IP. Proper test case is also
updated.

This is also to fix below issue:
https://github.com/spdk/spdk/issues/992

Change-Id: Ia4d3af8cc86d9bdb66b18a165510cd08f9bfa555
Signed-off-by: GangCao <gang.cao@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/476543
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
GangCao 2019-12-03 15:48:22 -05:00 committed by Tomasz Zawadzki
parent a34d7d7b2f
commit 5d106e75e0
3 changed files with 102 additions and 10 deletions

View File

@ -304,20 +304,19 @@ exit:
return ret;
}
static int spdk_interface_available(uint32_t ifc_index)
static struct spdk_interface *
spdk_interface_find_by_index(uint32_t ifc_index)
{
struct spdk_interface *ifc_entry;
pthread_mutex_lock(&interface_lock);
/* Mutex must has benn held by the caller */
TAILQ_FOREACH(ifc_entry, &g_interface_head, tailq) {
if (ifc_entry->index == ifc_index) {
pthread_mutex_unlock(&interface_lock);
return 0;
return ifc_entry;
}
}
pthread_mutex_unlock(&interface_lock);
return -1;
return NULL;
}
static int netlink_addr_msg(uint32_t ifc_idx, uint32_t ip_address, uint32_t create)
@ -335,10 +334,6 @@ static int netlink_addr_msg(uint32_t ifc_idx, uint32_t ip_address, uint32_t crea
} req;
struct rtattr *rta;
if (spdk_interface_available(ifc_idx)) {
return -ENODEV;
}
fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
if (fd < 0) {
SPDK_ERRLOG("socket failed!\n");
@ -421,6 +416,43 @@ static void spdk_interface_ip_update(void)
pthread_mutex_unlock(&interface_lock);
}
static int
spdk_interface_is_ip_address_in_use(int ifc_index, uint32_t addr, bool add)
{
struct spdk_interface *ifc_entry;
bool in_use = false;
uint32_t idx = 0;
spdk_interface_ip_update();
pthread_mutex_lock(&interface_lock);
ifc_entry = spdk_interface_find_by_index(ifc_index);
if (ifc_entry == NULL) {
pthread_mutex_unlock(&interface_lock);
return -ENODEV;
}
for (idx = 0; idx < ifc_entry->num_ip_addresses; idx++) {
if (ifc_entry->ip_address[idx] == addr) {
in_use = true;
break;
}
}
pthread_mutex_unlock(&interface_lock);
/* The IP address to add is alerady in use */
if (add == true && in_use == true) {
return -EADDRINUSE;
}
/* The IP address to delete is not in use */
if (add == false && in_use == false) {
return -ENXIO;
}
return 0;
}
int
spdk_interface_init(void)
{
@ -451,8 +483,15 @@ int
spdk_interface_net_interface_add_ip_address(int ifc_index, char *ip_addr)
{
uint32_t addr;
int ret;
addr = inet_addr(ip_addr);
ret = spdk_interface_is_ip_address_in_use(ifc_index, addr, true);
if (ret < 0) {
return ret;
}
return netlink_addr_msg(ifc_index, addr, 1);
}
@ -460,8 +499,15 @@ int
spdk_interface_net_interface_delete_ip_address(int ifc_index, char *ip_addr)
{
uint32_t addr;
int ret;
addr = inet_addr(ip_addr);
ret = spdk_interface_is_ip_address_in_use(ifc_index, addr, false);
if (ret < 0) {
return ret;
}
return netlink_addr_msg(ifc_index, addr, 0);
}

View File

@ -79,6 +79,10 @@ spdk_rpc_net_interface_add_ip_address(struct spdk_jsonrpc_request *request,
if (ret_val == -ENODEV) {
spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_STATE,
"Interface %d not available", req.ifc_index);
} else if (ret_val == -EADDRINUSE) {
spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"IP address %s is already added to interface %d",
req.ip_address, req.ifc_index);
} else {
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
strerror(ret_val));
@ -122,6 +126,10 @@ spdk_rpc_net_interface_delete_ip_address(struct spdk_jsonrpc_request *request,
if (ret_val == -ENODEV) {
spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_STATE,
"Interface %d not available", req.ifc_index);
} else if (ret_val == -ENXIO) {
spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"IP address %s is not found in interface %d",
req.ip_address, req.ifc_index);
} else {
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
strerror(ret_val));

View File

@ -32,10 +32,47 @@ function rpc_config() {
$rpc_py -s $1 bdev_malloc_create 64 512
}
function rpc_validate_ip() {
# Always delete the IP first in case it is there already
cmd="$rpc_py -s $1 net_interface_delete_ip_address 1 $MIGRATION_ADDRESS"
if $cmd; then
echo "Delete existing IP succeeded."
else
echo "Ignore the failure as IP did not exist."
fi
cmd="$rpc_py -s $1 net_interface_add_ip_address 1 $MIGRATION_ADDRESS"
if $cmd; then
echo "Add new IP succeeded."
else
echo "Add new IP failed. Expected to succeed..."
exit 1;
fi
# Add same IP again
if $cmd; then
echo "Same IP existed. Expected to fail..."
exit 1;
fi
cmd="$rpc_py -s $1 net_interface_delete_ip_address 1 $MIGRATION_ADDRESS"
if $cmd; then
echo "Delete existing IP succeeded."
else
echo "Delete existing IP failed. Expected to succeed..."
exit 1;
fi
# Delete same IP again
if $cmd; then
echo "No required IP existed. Expected to fail..."
exit 1;
fi
}
function rpc_add_target_node() {
$rpc_py -s $1 net_interface_add_ip_address 1 $MIGRATION_ADDRESS
$rpc_py -s $1 iscsi_create_portal_group $PORTAL_TAG $MIGRATION_ADDRESS:$ISCSI_PORT
$rpc_py -s $1 iscsi_create_target_node target1 target1_alias 'Malloc0:0' $PORTAL_TAG:$INITIATOR_TAG 64 -d
$rpc_py -s $1 net_interface_delete_ip_address 1 $MIGRATION_ADDRESS
}
timing_enter ip_migration
@ -66,6 +103,7 @@ for ((i = 0; i < 2; i++)); do
done
rpc_first_addr="/var/tmp/spdk0.sock"
rpc_validate_ip $rpc_first_addr
rpc_add_target_node $rpc_first_addr
sleep 1