summaryrefslogtreecommitdiff
path: root/net/can/j1939
diff options
context:
space:
mode:
Diffstat (limited to 'net/can/j1939')
-rw-r--r--net/can/j1939/socket.c16
-rw-r--r--net/can/j1939/transport.c39
2 files changed, 41 insertions, 14 deletions
diff --git a/net/can/j1939/socket.c b/net/can/j1939/socket.c
index ff9c4fd7b433..0502b030d238 100644
--- a/net/can/j1939/socket.c
+++ b/net/can/j1939/socket.c
@@ -17,6 +17,7 @@
#include <linux/can/skb.h>
#include <linux/errqueue.h>
#include <linux/if_arp.h>
+#include <net/can.h>
#include "j1939-priv.h"
@@ -884,20 +885,25 @@ static struct sk_buff *j1939_sk_alloc_skb(struct net_device *ndev,
struct j1939_sock *jsk = j1939_sk(sk);
struct j1939_sk_buff_cb *skcb;
struct sk_buff *skb;
+ struct can_skb_ext *csx;
int ret;
skb = sock_alloc_send_skb(sk,
size +
sizeof(struct can_frame) -
- sizeof(((struct can_frame *)NULL)->data) +
- sizeof(struct can_skb_priv),
+ sizeof(((struct can_frame *)NULL)->data),
msg->msg_flags & MSG_DONTWAIT, &ret);
if (!skb)
goto failure;
- can_skb_reserve(skb);
- can_skb_prv(skb)->ifindex = ndev->ifindex;
- can_skb_prv(skb)->skbcnt = 0;
+ csx = can_skb_ext_add(skb);
+ if (!csx) {
+ kfree_skb(skb);
+ ret = -ENOMEM;
+ goto failure;
+ }
+
+ csx->can_iif = ndev->ifindex;
skb_reserve(skb, offsetof(struct can_frame, data));
ret = memcpy_from_msg(skb_put(skb, size), msg, size);
diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c
index 8656ab388c83..2cbe94fc487a 100644
--- a/net/can/j1939/transport.c
+++ b/net/can/j1939/transport.c
@@ -9,6 +9,7 @@
// Oleksij Rempel <kernel@pengutronix.de>
#include <linux/can/skb.h>
+#include <net/can.h>
#include "j1939-priv.h"
@@ -591,17 +592,21 @@ sk_buff *j1939_tp_tx_dat_new(struct j1939_priv *priv,
bool swap_src_dst)
{
struct sk_buff *skb;
+ struct can_skb_ext *csx;
struct j1939_sk_buff_cb *skcb;
- skb = alloc_skb(sizeof(struct can_frame) + sizeof(struct can_skb_priv),
- GFP_ATOMIC);
+ skb = alloc_skb(sizeof(struct can_frame), GFP_ATOMIC);
if (unlikely(!skb))
return ERR_PTR(-ENOMEM);
+ csx = can_skb_ext_add(skb);
+ if (!csx) {
+ kfree_skb(skb);
+ return ERR_PTR(-ENOMEM);
+ }
+
skb->dev = priv->ndev;
- can_skb_reserve(skb);
- can_skb_prv(skb)->ifindex = priv->ndev->ifindex;
- can_skb_prv(skb)->skbcnt = 0;
+ csx->can_iif = priv->ndev->ifindex;
/* reserve CAN header */
skb_reserve(skb, offsetof(struct can_frame, data));
@@ -1052,6 +1057,17 @@ static int j1939_simple_txnext(struct j1939_session *session)
goto out_free;
}
+ /* the cloned skb points to the skb extension of the original se_skb
+ * with an increased refcount. skb_ext_add() creates a copy to
+ * separate the skb extension data which is needed to modify the
+ * can_framelen in can_put_echo_skb().
+ */
+ if (!skb_ext_add(skb, SKB_EXT_CAN)) {
+ kfree_skb(skb);
+ ret = -ENOMEM;
+ goto out_free;
+ }
+
can_skb_set_owner(skb, se_skb->sk);
j1939_tp_set_rxtimeout(session, J1939_SIMPLE_ECHO_TIMEOUT_MS);
@@ -1526,17 +1542,22 @@ j1939_session *j1939_session_fresh_new(struct j1939_priv *priv,
const struct j1939_sk_buff_cb *rel_skcb)
{
struct sk_buff *skb;
+ struct can_skb_ext *csx;
struct j1939_sk_buff_cb *skcb;
struct j1939_session *session;
- skb = alloc_skb(size + sizeof(struct can_skb_priv), GFP_ATOMIC);
+ skb = alloc_skb(size, GFP_ATOMIC);
if (unlikely(!skb))
return NULL;
+ csx = can_skb_ext_add(skb);
+ if (!csx) {
+ kfree_skb(skb);
+ return NULL;
+ }
+
skb->dev = priv->ndev;
- can_skb_reserve(skb);
- can_skb_prv(skb)->ifindex = priv->ndev->ifindex;
- can_skb_prv(skb)->skbcnt = 0;
+ csx->can_iif = priv->ndev->ifindex;
skcb = j1939_skb_to_cb(skb);
memcpy(skcb, rel_skcb, sizeof(*skcb));