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;
|
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;
|
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) {
|
TAILQ_FOREACH(ifc_entry, &g_interface_head, tailq) {
|
||||||
if (ifc_entry->index == ifc_index) {
|
if (ifc_entry->index == ifc_index) {
|
||||||
pthread_mutex_unlock(&interface_lock);
|
return ifc_entry;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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)
|
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;
|
} req;
|
||||||
struct rtattr *rta;
|
struct rtattr *rta;
|
||||||
|
|
||||||
if (spdk_interface_available(ifc_idx)) {
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
|
fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
SPDK_ERRLOG("socket failed!\n");
|
SPDK_ERRLOG("socket failed!\n");
|
||||||
@ -421,6 +416,43 @@ static void spdk_interface_ip_update(void)
|
|||||||
pthread_mutex_unlock(&interface_lock);
|
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
|
int
|
||||||
spdk_interface_init(void)
|
spdk_interface_init(void)
|
||||||
{
|
{
|
||||||
@ -451,8 +483,15 @@ int
|
|||||||
spdk_interface_net_interface_add_ip_address(int ifc_index, char *ip_addr)
|
spdk_interface_net_interface_add_ip_address(int ifc_index, char *ip_addr)
|
||||||
{
|
{
|
||||||
uint32_t addr;
|
uint32_t addr;
|
||||||
|
int ret;
|
||||||
|
|
||||||
addr = inet_addr(ip_addr);
|
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);
|
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)
|
spdk_interface_net_interface_delete_ip_address(int ifc_index, char *ip_addr)
|
||||||
{
|
{
|
||||||
uint32_t addr;
|
uint32_t addr;
|
||||||
|
int ret;
|
||||||
|
|
||||||
addr = inet_addr(ip_addr);
|
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);
|
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) {
|
if (ret_val == -ENODEV) {
|
||||||
spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_STATE,
|
spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_STATE,
|
||||||
"Interface %d not available", req.ifc_index);
|
"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 {
|
} else {
|
||||||
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
|
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
|
||||||
strerror(ret_val));
|
strerror(ret_val));
|
||||||
@ -122,6 +126,10 @@ spdk_rpc_net_interface_delete_ip_address(struct spdk_jsonrpc_request *request,
|
|||||||
if (ret_val == -ENODEV) {
|
if (ret_val == -ENODEV) {
|
||||||
spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_STATE,
|
spdk_jsonrpc_send_error_response_fmt(request, SPDK_JSONRPC_ERROR_INVALID_STATE,
|
||||||
"Interface %d not available", req.ifc_index);
|
"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 {
|
} else {
|
||||||
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
|
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
|
||||||
strerror(ret_val));
|
strerror(ret_val));
|
||||||
|
@ -32,10 +32,47 @@ function rpc_config() {
|
|||||||
$rpc_py -s $1 bdev_malloc_create 64 512
|
$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() {
|
function rpc_add_target_node() {
|
||||||
$rpc_py -s $1 net_interface_add_ip_address 1 $MIGRATION_ADDRESS
|
$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_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 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
|
timing_enter ip_migration
|
||||||
@ -66,6 +103,7 @@ for ((i = 0; i < 2; i++)); do
|
|||||||
done
|
done
|
||||||
|
|
||||||
rpc_first_addr="/var/tmp/spdk0.sock"
|
rpc_first_addr="/var/tmp/spdk0.sock"
|
||||||
|
rpc_validate_ip $rpc_first_addr
|
||||||
rpc_add_target_node $rpc_first_addr
|
rpc_add_target_node $rpc_first_addr
|
||||||
|
|
||||||
sleep 1
|
sleep 1
|
||||||
|
Loading…
Reference in New Issue
Block a user