Commit a7f2f24c authored by Tatyana Nikolova's avatar Tatyana Nikolova Committed by Doug Ledford

RDMA/core: Fixes for port mapper client registration

Fixes to allow clients to make remove mapping requests, after
they have provided the user space service with the mapping
information, they are using when the service is restarted.

1) Adding IWPM_REG_VALID, IWPM_REG_INCOMPL and IWPM_REG_UNDEF
   registration types for the port mapper clients and functions
   to set/check the registration type.
2) If the port mapper user space service is not available to register
   the client, then its registration stays IWPM_REG_UNDEF and the
   registration isn't checked until the service becomes available
   (no mappings are possible, if the user space service isn't running).
3) After the service is restarted, the user space port mapper pid is set
   to valid and the client registration is set to IWPM_REG_INCOMPL
   to allow the client to make remove mapping requests.
Signed-off-by: default avatarTatyana Nikolova <Tatyana.E.Nikolova@intel.com>
Reviewed-by: default avatarSteve Wise <swise@opengridcomputing.com>
Tested-by: default avatarSteve Wise <swise@opengridcomputing.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent 58e9cc90
...@@ -67,7 +67,8 @@ int iwpm_register_pid(struct iwpm_dev_data *pm_msg, u8 nl_client) ...@@ -67,7 +67,8 @@ int iwpm_register_pid(struct iwpm_dev_data *pm_msg, u8 nl_client)
err_str = "Invalid port mapper client"; err_str = "Invalid port mapper client";
goto pid_query_error; goto pid_query_error;
} }
if (iwpm_registered_client(nl_client)) if (iwpm_check_registration(nl_client, IWPM_REG_VALID) ||
iwpm_user_pid == IWPM_PID_UNAVAILABLE)
return 0; return 0;
skb = iwpm_create_nlmsg(RDMA_NL_IWPM_REG_PID, &nlh, nl_client); skb = iwpm_create_nlmsg(RDMA_NL_IWPM_REG_PID, &nlh, nl_client);
if (!skb) { if (!skb) {
...@@ -106,7 +107,6 @@ int iwpm_register_pid(struct iwpm_dev_data *pm_msg, u8 nl_client) ...@@ -106,7 +107,6 @@ int iwpm_register_pid(struct iwpm_dev_data *pm_msg, u8 nl_client)
ret = ibnl_multicast(skb, nlh, RDMA_NL_GROUP_IWPM, GFP_KERNEL); ret = ibnl_multicast(skb, nlh, RDMA_NL_GROUP_IWPM, GFP_KERNEL);
if (ret) { if (ret) {
skb = NULL; /* skb is freed in the netlink send-op handling */ skb = NULL; /* skb is freed in the netlink send-op handling */
iwpm_set_registered(nl_client, 1);
iwpm_user_pid = IWPM_PID_UNAVAILABLE; iwpm_user_pid = IWPM_PID_UNAVAILABLE;
err_str = "Unable to send a nlmsg"; err_str = "Unable to send a nlmsg";
goto pid_query_error; goto pid_query_error;
...@@ -144,12 +144,12 @@ int iwpm_add_mapping(struct iwpm_sa_data *pm_msg, u8 nl_client) ...@@ -144,12 +144,12 @@ int iwpm_add_mapping(struct iwpm_sa_data *pm_msg, u8 nl_client)
err_str = "Invalid port mapper client"; err_str = "Invalid port mapper client";
goto add_mapping_error; goto add_mapping_error;
} }
if (!iwpm_registered_client(nl_client)) { if (!iwpm_valid_pid())
return 0;
if (!iwpm_check_registration(nl_client, IWPM_REG_VALID)) {
err_str = "Unregistered port mapper client"; err_str = "Unregistered port mapper client";
goto add_mapping_error; goto add_mapping_error;
} }
if (!iwpm_valid_pid())
return 0;
skb = iwpm_create_nlmsg(RDMA_NL_IWPM_ADD_MAPPING, &nlh, nl_client); skb = iwpm_create_nlmsg(RDMA_NL_IWPM_ADD_MAPPING, &nlh, nl_client);
if (!skb) { if (!skb) {
err_str = "Unable to create a nlmsg"; err_str = "Unable to create a nlmsg";
...@@ -214,12 +214,12 @@ int iwpm_add_and_query_mapping(struct iwpm_sa_data *pm_msg, u8 nl_client) ...@@ -214,12 +214,12 @@ int iwpm_add_and_query_mapping(struct iwpm_sa_data *pm_msg, u8 nl_client)
err_str = "Invalid port mapper client"; err_str = "Invalid port mapper client";
goto query_mapping_error; goto query_mapping_error;
} }
if (!iwpm_registered_client(nl_client)) { if (!iwpm_valid_pid())
return 0;
if (!iwpm_check_registration(nl_client, IWPM_REG_VALID)) {
err_str = "Unregistered port mapper client"; err_str = "Unregistered port mapper client";
goto query_mapping_error; goto query_mapping_error;
} }
if (!iwpm_valid_pid())
return 0;
ret = -ENOMEM; ret = -ENOMEM;
skb = iwpm_create_nlmsg(RDMA_NL_IWPM_QUERY_MAPPING, &nlh, nl_client); skb = iwpm_create_nlmsg(RDMA_NL_IWPM_QUERY_MAPPING, &nlh, nl_client);
if (!skb) { if (!skb) {
...@@ -288,12 +288,12 @@ int iwpm_remove_mapping(struct sockaddr_storage *local_addr, u8 nl_client) ...@@ -288,12 +288,12 @@ int iwpm_remove_mapping(struct sockaddr_storage *local_addr, u8 nl_client)
err_str = "Invalid port mapper client"; err_str = "Invalid port mapper client";
goto remove_mapping_error; goto remove_mapping_error;
} }
if (!iwpm_registered_client(nl_client)) { if (!iwpm_valid_pid())
return 0;
if (iwpm_check_registration(nl_client, IWPM_REG_UNDEF)) {
err_str = "Unregistered port mapper client"; err_str = "Unregistered port mapper client";
goto remove_mapping_error; goto remove_mapping_error;
} }
if (!iwpm_valid_pid())
return 0;
skb = iwpm_create_nlmsg(RDMA_NL_IWPM_REMOVE_MAPPING, &nlh, nl_client); skb = iwpm_create_nlmsg(RDMA_NL_IWPM_REMOVE_MAPPING, &nlh, nl_client);
if (!skb) { if (!skb) {
ret = -ENOMEM; ret = -ENOMEM;
...@@ -388,7 +388,7 @@ int iwpm_register_pid_cb(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -388,7 +388,7 @@ int iwpm_register_pid_cb(struct sk_buff *skb, struct netlink_callback *cb)
pr_debug("%s: iWarp Port Mapper (pid = %d) is available!\n", pr_debug("%s: iWarp Port Mapper (pid = %d) is available!\n",
__func__, iwpm_user_pid); __func__, iwpm_user_pid);
if (iwpm_valid_client(nl_client)) if (iwpm_valid_client(nl_client))
iwpm_set_registered(nl_client, 1); iwpm_set_registration(nl_client, IWPM_REG_VALID);
register_pid_response_exit: register_pid_response_exit:
nlmsg_request->request_done = 1; nlmsg_request->request_done = 1;
/* always for found nlmsg_request */ /* always for found nlmsg_request */
...@@ -644,7 +644,6 @@ int iwpm_mapping_info_cb(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -644,7 +644,6 @@ int iwpm_mapping_info_cb(struct sk_buff *skb, struct netlink_callback *cb)
{ {
struct nlattr *nltb[IWPM_NLA_MAPINFO_REQ_MAX]; struct nlattr *nltb[IWPM_NLA_MAPINFO_REQ_MAX];
const char *msg_type = "Mapping Info response"; const char *msg_type = "Mapping Info response";
int iwpm_pid;
u8 nl_client; u8 nl_client;
char *iwpm_name; char *iwpm_name;
u16 iwpm_version; u16 iwpm_version;
...@@ -669,14 +668,14 @@ int iwpm_mapping_info_cb(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -669,14 +668,14 @@ int iwpm_mapping_info_cb(struct sk_buff *skb, struct netlink_callback *cb)
__func__, nl_client); __func__, nl_client);
return ret; return ret;
} }
iwpm_set_registered(nl_client, 0); iwpm_set_registration(nl_client, IWPM_REG_INCOMPL);
atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq); atomic_set(&echo_nlmsg_seq, cb->nlh->nlmsg_seq);
iwpm_user_pid = cb->nlh->nlmsg_pid;
if (!iwpm_mapinfo_available()) if (!iwpm_mapinfo_available())
return 0; return 0;
iwpm_pid = cb->nlh->nlmsg_pid;
pr_debug("%s: iWarp Port Mapper (pid = %d) is available!\n", pr_debug("%s: iWarp Port Mapper (pid = %d) is available!\n",
__func__, iwpm_pid); __func__, iwpm_user_pid);
ret = iwpm_send_mapinfo(nl_client, iwpm_pid); ret = iwpm_send_mapinfo(nl_client, iwpm_user_pid);
return ret; return ret;
} }
EXPORT_SYMBOL(iwpm_mapping_info_cb); EXPORT_SYMBOL(iwpm_mapping_info_cb);
......
...@@ -78,6 +78,7 @@ int iwpm_init(u8 nl_client) ...@@ -78,6 +78,7 @@ int iwpm_init(u8 nl_client)
mutex_unlock(&iwpm_admin_lock); mutex_unlock(&iwpm_admin_lock);
if (!ret) { if (!ret) {
iwpm_set_valid(nl_client, 1); iwpm_set_valid(nl_client, 1);
iwpm_set_registration(nl_client, IWPM_REG_UNDEF);
pr_debug("%s: Mapinfo and reminfo tables are created\n", pr_debug("%s: Mapinfo and reminfo tables are created\n",
__func__); __func__);
} }
...@@ -106,6 +107,7 @@ int iwpm_exit(u8 nl_client) ...@@ -106,6 +107,7 @@ int iwpm_exit(u8 nl_client)
} }
mutex_unlock(&iwpm_admin_lock); mutex_unlock(&iwpm_admin_lock);
iwpm_set_valid(nl_client, 0); iwpm_set_valid(nl_client, 0);
iwpm_set_registration(nl_client, IWPM_REG_UNDEF);
return 0; return 0;
} }
EXPORT_SYMBOL(iwpm_exit); EXPORT_SYMBOL(iwpm_exit);
...@@ -397,17 +399,23 @@ void iwpm_set_valid(u8 nl_client, int valid) ...@@ -397,17 +399,23 @@ void iwpm_set_valid(u8 nl_client, int valid)
} }
/* valid client */ /* valid client */
int iwpm_registered_client(u8 nl_client) u32 iwpm_get_registration(u8 nl_client)
{ {
return iwpm_admin.reg_list[nl_client]; return iwpm_admin.reg_list[nl_client];
} }
/* valid client */ /* valid client */
void iwpm_set_registered(u8 nl_client, int reg) void iwpm_set_registration(u8 nl_client, u32 reg)
{ {
iwpm_admin.reg_list[nl_client] = reg; iwpm_admin.reg_list[nl_client] = reg;
} }
/* valid client */
u32 iwpm_check_registration(u8 nl_client, u32 reg)
{
return (iwpm_get_registration(nl_client) & reg);
}
int iwpm_compare_sockaddr(struct sockaddr_storage *a_sockaddr, int iwpm_compare_sockaddr(struct sockaddr_storage *a_sockaddr,
struct sockaddr_storage *b_sockaddr) struct sockaddr_storage *b_sockaddr)
{ {
......
...@@ -58,6 +58,10 @@ ...@@ -58,6 +58,10 @@
#define IWPM_PID_UNDEFINED -1 #define IWPM_PID_UNDEFINED -1
#define IWPM_PID_UNAVAILABLE -2 #define IWPM_PID_UNAVAILABLE -2
#define IWPM_REG_UNDEF 0x01
#define IWPM_REG_VALID 0x02
#define IWPM_REG_INCOMPL 0x04
struct iwpm_nlmsg_request { struct iwpm_nlmsg_request {
struct list_head inprocess_list; struct list_head inprocess_list;
__u32 nlmsg_seq; __u32 nlmsg_seq;
...@@ -88,7 +92,7 @@ struct iwpm_admin_data { ...@@ -88,7 +92,7 @@ struct iwpm_admin_data {
atomic_t refcount; atomic_t refcount;
atomic_t nlmsg_seq; atomic_t nlmsg_seq;
int client_list[RDMA_NL_NUM_CLIENTS]; int client_list[RDMA_NL_NUM_CLIENTS];
int reg_list[RDMA_NL_NUM_CLIENTS]; u32 reg_list[RDMA_NL_NUM_CLIENTS];
}; };
/** /**
...@@ -159,19 +163,31 @@ int iwpm_valid_client(u8 nl_client); ...@@ -159,19 +163,31 @@ int iwpm_valid_client(u8 nl_client);
void iwpm_set_valid(u8 nl_client, int valid); void iwpm_set_valid(u8 nl_client, int valid);
/** /**
* iwpm_registered_client - Check if the port mapper client is registered * iwpm_check_registration - Check if the client registration
* matches the given one
* @nl_client: The index of the netlink client * @nl_client: The index of the netlink client
* @reg: The given registration type to compare with
* *
* Call iwpm_register_pid() to register a client * Call iwpm_register_pid() to register a client
* Returns true if the client registration matches reg,
* otherwise returns false
*/
u32 iwpm_check_registration(u8 nl_client, u32 reg);
/**
* iwpm_set_registration - Set the client registration
* @nl_client: The index of the netlink client
* @reg: Registration type to set
*/ */
int iwpm_registered_client(u8 nl_client); void iwpm_set_registration(u8 nl_client, u32 reg);
/** /**
* iwpm_set_registered - Set the port mapper client to registered or not * iwpm_get_registration
* @nl_client: The index of the netlink client * @nl_client: The index of the netlink client
* @reg: 1 if registered or 0 if not *
* Returns the client registration type
*/ */
void iwpm_set_registered(u8 nl_client, int reg); u32 iwpm_get_registration(u8 nl_client);
/** /**
* iwpm_send_mapinfo - Send local and mapped IPv4/IPv6 address info of * iwpm_send_mapinfo - Send local and mapped IPv4/IPv6 address info of
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment