@@ -1791,13 +1791,14 @@ int mptcp_nl_fill_addr(struct sk_buff *skb,
return -EMSGSIZE;
}
-static int mptcp_pm_nl_get_addr(u8 id, struct genl_info *info)
+static int mptcp_pm_nl_get_addr(u8 id, struct mptcp_pm_addr_entry *addr,
+ struct genl_info *info)
{
struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
struct mptcp_pm_addr_entry *entry;
struct sk_buff *msg;
+ int ret = -EINVAL;
void *reply;
- int ret;
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!msg)
@@ -1813,34 +1814,36 @@ static int mptcp_pm_nl_get_addr(u8 id, struct genl_info *info)
spin_lock_bh(&pernet->lock);
entry = __lookup_addr_by_id(pernet, id);
- if (!entry) {
+ if (entry) {
+ *addr = *entry;
+ ret = 0;
+ }
+ spin_unlock_bh(&pernet->lock);
+
+ if (ret) {
GENL_SET_ERR_MSG(info, "address not found");
- ret = -EINVAL;
- goto unlock_fail;
+ goto fail;
}
- ret = mptcp_nl_fill_addr(msg, entry);
+ ret = mptcp_nl_fill_addr(msg, addr);
if (ret)
- goto unlock_fail;
+ goto fail;
genlmsg_end(msg, reply);
ret = genlmsg_reply(msg, info);
- spin_unlock_bh(&pernet->lock);
return ret;
-unlock_fail:
- spin_unlock_bh(&pernet->lock);
-
fail:
nlmsg_free(msg);
return ret;
}
-static int mptcp_pm_get_addr(u8 id, struct genl_info *info)
+static int mptcp_pm_get_addr(u8 id, struct mptcp_pm_addr_entry *addr,
+ struct genl_info *info)
{
if (info->attrs[MPTCP_PM_ATTR_TOKEN])
- return mptcp_userspace_pm_get_addr(id, info);
- return mptcp_pm_nl_get_addr(id, info);
+ return mptcp_userspace_pm_get_addr(id, addr, info);
+ return mptcp_pm_nl_get_addr(id, addr, info);
}
int mptcp_pm_nl_get_addr_doit(struct sk_buff *skb, struct genl_info *info)
@@ -1853,7 +1856,7 @@ int mptcp_pm_nl_get_addr_doit(struct sk_buff *skb, struct genl_info *info)
if (ret < 0)
return ret;
- ret = mptcp_pm_get_addr(addr.addr.id, info);
+ ret = mptcp_pm_get_addr(addr.addr.id, &addr, info);
return ret;
}
@@ -629,7 +629,8 @@ int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
return ret;
}
-int mptcp_userspace_pm_get_addr(u8 id, struct genl_info *info)
+int mptcp_userspace_pm_get_addr(u8 id, struct mptcp_pm_addr_entry *addr,
+ struct genl_info *info)
{
struct mptcp_pm_addr_entry *entry;
struct mptcp_sock *msk;
@@ -661,26 +662,27 @@ int mptcp_userspace_pm_get_addr(u8 id, struct genl_info *info)
lock_sock(sk);
spin_lock_bh(&msk->pm.lock);
entry = mptcp_userspace_pm_lookup_addr_by_id(msk, id);
- if (!entry) {
+ if (entry) {
+ *addr = *entry;
+ ret = 0;
+ }
+ spin_unlock_bh(&msk->pm.lock);
+ release_sock(sk);
+
+ if (ret) {
GENL_SET_ERR_MSG(info, "address not found");
- ret = -EINVAL;
- goto unlock_fail;
+ goto fail;
}
- ret = mptcp_nl_fill_addr(msg, entry);
+ ret = mptcp_nl_fill_addr(msg, addr);
if (ret)
- goto unlock_fail;
+ goto fail;
genlmsg_end(msg, reply);
ret = genlmsg_reply(msg, info);
- spin_unlock_bh(&msk->pm.lock);
- release_sock(sk);
sock_put(sk);
return ret;
-unlock_fail:
- spin_unlock_bh(&msk->pm.lock);
- release_sock(sk);
fail:
nlmsg_free(msg);
out:
@@ -1127,7 +1127,8 @@ bool mptcp_pm_nl_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc);
int mptcp_userspace_pm_dump_addr(struct sk_buff *msg,
struct netlink_callback *cb);
-int mptcp_userspace_pm_get_addr(u8 id, struct genl_info *info);
+int mptcp_userspace_pm_get_addr(u8 id, struct mptcp_pm_addr_entry *addr,
+ struct genl_info *info);
static inline u8 subflow_get_local_id(const struct mptcp_subflow_context *subflow)
{