Skip to content

Commit 71a5041

Browse files
committed
Merge tag 'linux-can-fixes-for-5.9-20200815' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can
Marc Kleine-Budde says: ==================== pull-request: can 2020-08-15 this is a pull request of 4 patches for net/master. All patches are by Zhang Changzhong and fix broadcast related problems in the j1939 CAN networking stack. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 55eff0e + 0ae18a8 commit 71a5041

File tree

1 file changed

+36
-12
lines changed

1 file changed

+36
-12
lines changed

net/can/j1939/transport.c

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -723,10 +723,12 @@ static int j1939_session_tx_rts(struct j1939_session *session)
723723
return ret;
724724

725725
session->last_txcmd = dat[0];
726-
if (dat[0] == J1939_TP_CMD_BAM)
726+
if (dat[0] == J1939_TP_CMD_BAM) {
727727
j1939_tp_schedule_txtimer(session, 50);
728-
729-
j1939_tp_set_rxtimeout(session, 1250);
728+
j1939_tp_set_rxtimeout(session, 250);
729+
} else {
730+
j1939_tp_set_rxtimeout(session, 1250);
731+
}
730732

731733
netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session);
732734

@@ -1074,9 +1076,9 @@ static void __j1939_session_cancel(struct j1939_session *session,
10741076
lockdep_assert_held(&session->priv->active_session_list_lock);
10751077

10761078
session->err = j1939_xtp_abort_to_errno(priv, err);
1079+
session->state = J1939_SESSION_WAITING_ABORT;
10771080
/* do not send aborts on incoming broadcasts */
10781081
if (!j1939_cb_is_broadcast(&session->skcb)) {
1079-
session->state = J1939_SESSION_WAITING_ABORT;
10801082
j1939_xtp_tx_abort(priv, &session->skcb,
10811083
!session->transmission,
10821084
err, session->skcb.addr.pgn);
@@ -1673,8 +1675,12 @@ static void j1939_xtp_rx_rts(struct j1939_priv *priv, struct sk_buff *skb,
16731675
return;
16741676
}
16751677
session = j1939_xtp_rx_rts_session_new(priv, skb);
1676-
if (!session)
1678+
if (!session) {
1679+
if (cmd == J1939_TP_CMD_BAM && j1939_sk_recv_match(priv, skcb))
1680+
netdev_info(priv->ndev, "%s: failed to create TP BAM session\n",
1681+
__func__);
16771682
return;
1683+
}
16781684
} else {
16791685
if (j1939_xtp_rx_rts_session_active(session, skb)) {
16801686
j1939_session_put(session);
@@ -1683,11 +1689,15 @@ static void j1939_xtp_rx_rts(struct j1939_priv *priv, struct sk_buff *skb,
16831689
}
16841690
session->last_cmd = cmd;
16851691

1686-
j1939_tp_set_rxtimeout(session, 1250);
1687-
1688-
if (cmd != J1939_TP_CMD_BAM && !session->transmission) {
1689-
j1939_session_txtimer_cancel(session);
1690-
j1939_tp_schedule_txtimer(session, 0);
1692+
if (cmd == J1939_TP_CMD_BAM) {
1693+
if (!session->transmission)
1694+
j1939_tp_set_rxtimeout(session, 750);
1695+
} else {
1696+
if (!session->transmission) {
1697+
j1939_session_txtimer_cancel(session);
1698+
j1939_tp_schedule_txtimer(session, 0);
1699+
}
1700+
j1939_tp_set_rxtimeout(session, 1250);
16911701
}
16921702

16931703
j1939_session_put(session);
@@ -1738,6 +1748,7 @@ static void j1939_xtp_rx_dat_one(struct j1939_session *session,
17381748
int offset;
17391749
int nbytes;
17401750
bool final = false;
1751+
bool remain = false;
17411752
bool do_cts_eoma = false;
17421753
int packet;
17431754

@@ -1813,14 +1824,20 @@ static void j1939_xtp_rx_dat_one(struct j1939_session *session,
18131824
j1939_cb_is_broadcast(&session->skcb)) {
18141825
if (session->pkt.rx >= session->pkt.total)
18151826
final = true;
1827+
else
1828+
remain = true;
18161829
} else {
18171830
/* never final, an EOMA must follow */
18181831
if (session->pkt.rx >= session->pkt.last)
18191832
do_cts_eoma = true;
18201833
}
18211834

18221835
if (final) {
1836+
j1939_session_timers_cancel(session);
18231837
j1939_session_completed(session);
1838+
} else if (remain) {
1839+
if (!session->transmission)
1840+
j1939_tp_set_rxtimeout(session, 750);
18241841
} else if (do_cts_eoma) {
18251842
j1939_tp_set_rxtimeout(session, 1250);
18261843
if (!session->transmission)
@@ -1865,6 +1882,13 @@ static void j1939_xtp_rx_dat(struct j1939_priv *priv, struct sk_buff *skb)
18651882
else
18661883
j1939_xtp_rx_dat_one(session, skb);
18671884
}
1885+
1886+
if (j1939_cb_is_broadcast(skcb)) {
1887+
session = j1939_session_get_by_addr(priv, &skcb->addr, false,
1888+
false);
1889+
if (session)
1890+
j1939_xtp_rx_dat_one(session, skb);
1891+
}
18681892
}
18691893

18701894
/* j1939 main intf */
@@ -1956,7 +1980,7 @@ static void j1939_tp_cmd_recv(struct j1939_priv *priv, struct sk_buff *skb)
19561980
if (j1939_tp_im_transmitter(skcb))
19571981
j1939_xtp_rx_rts(priv, skb, true);
19581982

1959-
if (j1939_tp_im_receiver(skcb))
1983+
if (j1939_tp_im_receiver(skcb) || j1939_cb_is_broadcast(skcb))
19601984
j1939_xtp_rx_rts(priv, skb, false);
19611985

19621986
break;
@@ -2020,7 +2044,7 @@ int j1939_tp_recv(struct j1939_priv *priv, struct sk_buff *skb)
20202044
{
20212045
struct j1939_sk_buff_cb *skcb = j1939_skb_to_cb(skb);
20222046

2023-
if (!j1939_tp_im_involved_anydir(skcb))
2047+
if (!j1939_tp_im_involved_anydir(skcb) && !j1939_cb_is_broadcast(skcb))
20242048
return 0;
20252049

20262050
switch (skcb->addr.pgn) {

0 commit comments

Comments
 (0)