Commit f4fd77fd authored by Zhang Changzhong's avatar Zhang Changzhong Committed by Marc Kleine-Budde

can: j1939: fix support for multipacket broadcast message

Currently j1939_tp_im_involved_anydir() in j1939_tp_recv() check the previously
set flags J1939_ECU_LOCAL_DST and J1939_ECU_LOCAL_SRC of incoming skb, thus
multipacket broadcast message was aborted by receive side because it may come
from remote ECUs and have no exact dst address. Similarly, j1939_tp_cmd_recv()
and j1939_xtp_rx_dat() didn't process broadcast message.

So fix it by checking and process broadcast message in j1939_tp_recv(),
j1939_tp_cmd_recv() and j1939_xtp_rx_dat().

Fixes: 9d71dd0c ("can: add support of SAE J1939 protocol")
Signed-off-by: default avatarZhang Changzhong <zhangchangzhong@huawei.com>
Link: https://lore.kernel.org/r/1596599425-5534-2-git-send-email-zhangchangzhong@huawei.comAcked-by: default avatarOleksij Rempel <o.rempel@pengutronix.de>
Signed-off-by: default avatarMarc Kleine-Budde <mkl@pengutronix.de>
parent 4ca0d9ac
...@@ -1673,8 +1673,12 @@ static void j1939_xtp_rx_rts(struct j1939_priv *priv, struct sk_buff *skb, ...@@ -1673,8 +1673,12 @@ static void j1939_xtp_rx_rts(struct j1939_priv *priv, struct sk_buff *skb,
return; return;
} }
session = j1939_xtp_rx_rts_session_new(priv, skb); session = j1939_xtp_rx_rts_session_new(priv, skb);
if (!session) if (!session) {
if (cmd == J1939_TP_CMD_BAM && j1939_sk_recv_match(priv, skcb))
netdev_info(priv->ndev, "%s: failed to create TP BAM session\n",
__func__);
return; return;
}
} else { } else {
if (j1939_xtp_rx_rts_session_active(session, skb)) { if (j1939_xtp_rx_rts_session_active(session, skb)) {
j1939_session_put(session); j1939_session_put(session);
...@@ -1865,6 +1869,13 @@ static void j1939_xtp_rx_dat(struct j1939_priv *priv, struct sk_buff *skb) ...@@ -1865,6 +1869,13 @@ static void j1939_xtp_rx_dat(struct j1939_priv *priv, struct sk_buff *skb)
else else
j1939_xtp_rx_dat_one(session, skb); j1939_xtp_rx_dat_one(session, skb);
} }
if (j1939_cb_is_broadcast(skcb)) {
session = j1939_session_get_by_addr(priv, &skcb->addr, false,
false);
if (session)
j1939_xtp_rx_dat_one(session, skb);
}
} }
/* j1939 main intf */ /* j1939 main intf */
...@@ -1956,7 +1967,7 @@ static void j1939_tp_cmd_recv(struct j1939_priv *priv, struct sk_buff *skb) ...@@ -1956,7 +1967,7 @@ static void j1939_tp_cmd_recv(struct j1939_priv *priv, struct sk_buff *skb)
if (j1939_tp_im_transmitter(skcb)) if (j1939_tp_im_transmitter(skcb))
j1939_xtp_rx_rts(priv, skb, true); j1939_xtp_rx_rts(priv, skb, true);
if (j1939_tp_im_receiver(skcb)) if (j1939_tp_im_receiver(skcb) || j1939_cb_is_broadcast(skcb))
j1939_xtp_rx_rts(priv, skb, false); j1939_xtp_rx_rts(priv, skb, false);
break; break;
...@@ -2020,7 +2031,7 @@ int j1939_tp_recv(struct j1939_priv *priv, struct sk_buff *skb) ...@@ -2020,7 +2031,7 @@ int j1939_tp_recv(struct j1939_priv *priv, struct sk_buff *skb)
{ {
struct j1939_sk_buff_cb *skcb = j1939_skb_to_cb(skb); struct j1939_sk_buff_cb *skcb = j1939_skb_to_cb(skb);
if (!j1939_tp_im_involved_anydir(skcb)) if (!j1939_tp_im_involved_anydir(skcb) && !j1939_cb_is_broadcast(skcb))
return 0; return 0;
switch (skcb->addr.pgn) { switch (skcb->addr.pgn) {
......
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