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:
parent
a34d7d7b2f
commit
5d106e75e0
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user