|
@@ -65,10 +65,12 @@ static struct l2tp_session *l2tp_nl_session_get(struct genl_info *info,
|
|
|
(info->attrs[L2TP_ATTR_CONN_ID])) {
|
|
|
tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]);
|
|
|
session_id = nla_get_u32(info->attrs[L2TP_ATTR_SESSION_ID]);
|
|
|
- tunnel = l2tp_tunnel_find(net, tunnel_id);
|
|
|
- if (tunnel)
|
|
|
+ tunnel = l2tp_tunnel_get(net, tunnel_id);
|
|
|
+ if (tunnel) {
|
|
|
session = l2tp_session_get(net, tunnel, session_id,
|
|
|
do_ref);
|
|
|
+ l2tp_tunnel_dec_refcount(tunnel);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
return session;
|
|
@@ -271,8 +273,8 @@ static int l2tp_nl_cmd_tunnel_delete(struct sk_buff *skb, struct genl_info *info
|
|
|
}
|
|
|
tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]);
|
|
|
|
|
|
- tunnel = l2tp_tunnel_find(net, tunnel_id);
|
|
|
- if (tunnel == NULL) {
|
|
|
+ tunnel = l2tp_tunnel_get(net, tunnel_id);
|
|
|
+ if (!tunnel) {
|
|
|
ret = -ENODEV;
|
|
|
goto out;
|
|
|
}
|
|
@@ -282,6 +284,8 @@ static int l2tp_nl_cmd_tunnel_delete(struct sk_buff *skb, struct genl_info *info
|
|
|
|
|
|
(void) l2tp_tunnel_delete(tunnel);
|
|
|
|
|
|
+ l2tp_tunnel_dec_refcount(tunnel);
|
|
|
+
|
|
|
out:
|
|
|
return ret;
|
|
|
}
|
|
@@ -299,8 +303,8 @@ static int l2tp_nl_cmd_tunnel_modify(struct sk_buff *skb, struct genl_info *info
|
|
|
}
|
|
|
tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]);
|
|
|
|
|
|
- tunnel = l2tp_tunnel_find(net, tunnel_id);
|
|
|
- if (tunnel == NULL) {
|
|
|
+ tunnel = l2tp_tunnel_get(net, tunnel_id);
|
|
|
+ if (!tunnel) {
|
|
|
ret = -ENODEV;
|
|
|
goto out;
|
|
|
}
|
|
@@ -311,6 +315,8 @@ static int l2tp_nl_cmd_tunnel_modify(struct sk_buff *skb, struct genl_info *info
|
|
|
ret = l2tp_tunnel_notify(&l2tp_nl_family, info,
|
|
|
tunnel, L2TP_CMD_TUNNEL_MODIFY);
|
|
|
|
|
|
+ l2tp_tunnel_dec_refcount(tunnel);
|
|
|
+
|
|
|
out:
|
|
|
return ret;
|
|
|
}
|
|
@@ -438,34 +444,37 @@ static int l2tp_nl_cmd_tunnel_get(struct sk_buff *skb, struct genl_info *info)
|
|
|
|
|
|
if (!info->attrs[L2TP_ATTR_CONN_ID]) {
|
|
|
ret = -EINVAL;
|
|
|
- goto out;
|
|
|
+ goto err;
|
|
|
}
|
|
|
|
|
|
tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]);
|
|
|
|
|
|
- tunnel = l2tp_tunnel_find(net, tunnel_id);
|
|
|
- if (tunnel == NULL) {
|
|
|
- ret = -ENODEV;
|
|
|
- goto out;
|
|
|
- }
|
|
|
-
|
|
|
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
|
|
if (!msg) {
|
|
|
ret = -ENOMEM;
|
|
|
- goto out;
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+
|
|
|
+ tunnel = l2tp_tunnel_get(net, tunnel_id);
|
|
|
+ if (!tunnel) {
|
|
|
+ ret = -ENODEV;
|
|
|
+ goto err_nlmsg;
|
|
|
}
|
|
|
|
|
|
ret = l2tp_nl_tunnel_send(msg, info->snd_portid, info->snd_seq,
|
|
|
NLM_F_ACK, tunnel, L2TP_CMD_TUNNEL_GET);
|
|
|
if (ret < 0)
|
|
|
- goto err_out;
|
|
|
+ goto err_nlmsg_tunnel;
|
|
|
+
|
|
|
+ l2tp_tunnel_dec_refcount(tunnel);
|
|
|
|
|
|
return genlmsg_unicast(net, msg, info->snd_portid);
|
|
|
|
|
|
-err_out:
|
|
|
+err_nlmsg_tunnel:
|
|
|
+ l2tp_tunnel_dec_refcount(tunnel);
|
|
|
+err_nlmsg:
|
|
|
nlmsg_free(msg);
|
|
|
-
|
|
|
-out:
|
|
|
+err:
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
@@ -509,8 +518,9 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf
|
|
|
ret = -EINVAL;
|
|
|
goto out;
|
|
|
}
|
|
|
+
|
|
|
tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]);
|
|
|
- tunnel = l2tp_tunnel_find(net, tunnel_id);
|
|
|
+ tunnel = l2tp_tunnel_get(net, tunnel_id);
|
|
|
if (!tunnel) {
|
|
|
ret = -ENODEV;
|
|
|
goto out;
|
|
@@ -518,24 +528,24 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf
|
|
|
|
|
|
if (!info->attrs[L2TP_ATTR_SESSION_ID]) {
|
|
|
ret = -EINVAL;
|
|
|
- goto out;
|
|
|
+ goto out_tunnel;
|
|
|
}
|
|
|
session_id = nla_get_u32(info->attrs[L2TP_ATTR_SESSION_ID]);
|
|
|
|
|
|
if (!info->attrs[L2TP_ATTR_PEER_SESSION_ID]) {
|
|
|
ret = -EINVAL;
|
|
|
- goto out;
|
|
|
+ goto out_tunnel;
|
|
|
}
|
|
|
peer_session_id = nla_get_u32(info->attrs[L2TP_ATTR_PEER_SESSION_ID]);
|
|
|
|
|
|
if (!info->attrs[L2TP_ATTR_PW_TYPE]) {
|
|
|
ret = -EINVAL;
|
|
|
- goto out;
|
|
|
+ goto out_tunnel;
|
|
|
}
|
|
|
cfg.pw_type = nla_get_u16(info->attrs[L2TP_ATTR_PW_TYPE]);
|
|
|
if (cfg.pw_type >= __L2TP_PWTYPE_MAX) {
|
|
|
ret = -EINVAL;
|
|
|
- goto out;
|
|
|
+ goto out_tunnel;
|
|
|
}
|
|
|
|
|
|
if (tunnel->version > 2) {
|
|
@@ -557,7 +567,7 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf
|
|
|
u16 len = nla_len(info->attrs[L2TP_ATTR_COOKIE]);
|
|
|
if (len > 8) {
|
|
|
ret = -EINVAL;
|
|
|
- goto out;
|
|
|
+ goto out_tunnel;
|
|
|
}
|
|
|
cfg.cookie_len = len;
|
|
|
memcpy(&cfg.cookie[0], nla_data(info->attrs[L2TP_ATTR_COOKIE]), len);
|
|
@@ -566,7 +576,7 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf
|
|
|
u16 len = nla_len(info->attrs[L2TP_ATTR_PEER_COOKIE]);
|
|
|
if (len > 8) {
|
|
|
ret = -EINVAL;
|
|
|
- goto out;
|
|
|
+ goto out_tunnel;
|
|
|
}
|
|
|
cfg.peer_cookie_len = len;
|
|
|
memcpy(&cfg.peer_cookie[0], nla_data(info->attrs[L2TP_ATTR_PEER_COOKIE]), len);
|
|
@@ -609,7 +619,7 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf
|
|
|
if ((l2tp_nl_cmd_ops[cfg.pw_type] == NULL) ||
|
|
|
(l2tp_nl_cmd_ops[cfg.pw_type]->session_create == NULL)) {
|
|
|
ret = -EPROTONOSUPPORT;
|
|
|
- goto out;
|
|
|
+ goto out_tunnel;
|
|
|
}
|
|
|
|
|
|
/* Check that pseudowire-specific params are present */
|
|
@@ -619,7 +629,7 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf
|
|
|
case L2TP_PWTYPE_ETH_VLAN:
|
|
|
if (!info->attrs[L2TP_ATTR_VLAN_ID]) {
|
|
|
ret = -EINVAL;
|
|
|
- goto out;
|
|
|
+ goto out_tunnel;
|
|
|
}
|
|
|
break;
|
|
|
case L2TP_PWTYPE_ETH:
|
|
@@ -647,6 +657,8 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+out_tunnel:
|
|
|
+ l2tp_tunnel_dec_refcount(tunnel);
|
|
|
out:
|
|
|
return ret;
|
|
|
}
|