]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - net/rxrpc/input.c
regulator: tps65910: fix a missing check of return value
[mirror_ubuntu-bionic-kernel.git] / net / rxrpc / input.c
index 6fc61400337fb3e8a96658ed685efa9a8280f70e..5a84d62a7209f7dd1ce0c9f8e71c6c1411236596 100644 (file)
@@ -216,10 +216,11 @@ static void rxrpc_send_ping(struct rxrpc_call *call, struct sk_buff *skb,
 /*
  * Apply a hard ACK by advancing the Tx window.
  */
-static void rxrpc_rotate_tx_window(struct rxrpc_call *call, rxrpc_seq_t to,
+static bool rxrpc_rotate_tx_window(struct rxrpc_call *call, rxrpc_seq_t to,
                                   struct rxrpc_ack_summary *summary)
 {
        struct sk_buff *skb, *list = NULL;
+       bool rot_last = false;
        int ix;
        u8 annotation;
 
@@ -243,15 +244,17 @@ static void rxrpc_rotate_tx_window(struct rxrpc_call *call, rxrpc_seq_t to,
                skb->next = list;
                list = skb;
 
-               if (annotation & RXRPC_TX_ANNO_LAST)
+               if (annotation & RXRPC_TX_ANNO_LAST) {
                        set_bit(RXRPC_CALL_TX_LAST, &call->flags);
+                       rot_last = true;
+               }
                if ((annotation & RXRPC_TX_ANNO_MASK) != RXRPC_TX_ANNO_ACK)
                        summary->nr_rot_new_acks++;
        }
 
        spin_unlock(&call->lock);
 
-       trace_rxrpc_transmit(call, (test_bit(RXRPC_CALL_TX_LAST, &call->flags) ?
+       trace_rxrpc_transmit(call, (rot_last ?
                                    rxrpc_transmit_rotate_last :
                                    rxrpc_transmit_rotate));
        wake_up(&call->waitq);
@@ -262,6 +265,8 @@ static void rxrpc_rotate_tx_window(struct rxrpc_call *call, rxrpc_seq_t to,
                skb->next = NULL;
                rxrpc_free_skb(skb, rxrpc_skb_tx_freed);
        }
+
+       return rot_last;
 }
 
 /*
@@ -273,23 +278,26 @@ static void rxrpc_rotate_tx_window(struct rxrpc_call *call, rxrpc_seq_t to,
 static bool rxrpc_end_tx_phase(struct rxrpc_call *call, bool reply_begun,
                               const char *abort_why)
 {
+       unsigned int state;
 
        ASSERT(test_bit(RXRPC_CALL_TX_LAST, &call->flags));
 
        write_lock(&call->state_lock);
 
-       switch (call->state) {
+       state = call->state;
+       switch (state) {
        case RXRPC_CALL_CLIENT_SEND_REQUEST:
        case RXRPC_CALL_CLIENT_AWAIT_REPLY:
                if (reply_begun)
-                       call->state = RXRPC_CALL_CLIENT_RECV_REPLY;
+                       call->state = state = RXRPC_CALL_CLIENT_RECV_REPLY;
                else
-                       call->state = RXRPC_CALL_CLIENT_AWAIT_REPLY;
+                       call->state = state = RXRPC_CALL_CLIENT_AWAIT_REPLY;
                break;
 
        case RXRPC_CALL_SERVER_AWAIT_ACK:
                __rxrpc_call_completed(call);
                rxrpc_notify_socket(call);
+               state = call->state;
                break;
 
        default:
@@ -297,11 +305,10 @@ static bool rxrpc_end_tx_phase(struct rxrpc_call *call, bool reply_begun,
        }
 
        write_unlock(&call->state_lock);
-       if (call->state == RXRPC_CALL_CLIENT_AWAIT_REPLY) {
+       if (state == RXRPC_CALL_CLIENT_AWAIT_REPLY)
                trace_rxrpc_transmit(call, rxrpc_transmit_await_reply);
-       } else {
+       else
                trace_rxrpc_transmit(call, rxrpc_transmit_end);
-       }
        _leave(" = ok");
        return true;
 
@@ -332,11 +339,11 @@ static bool rxrpc_receiving_reply(struct rxrpc_call *call)
                trace_rxrpc_timer(call, rxrpc_timer_init_for_reply, now);
        }
 
-       if (!test_bit(RXRPC_CALL_TX_LAST, &call->flags))
-               rxrpc_rotate_tx_window(call, top, &summary);
        if (!test_bit(RXRPC_CALL_TX_LAST, &call->flags)) {
-               rxrpc_proto_abort("TXL", call, top);
-               return false;
+               if (!rxrpc_rotate_tx_window(call, top, &summary)) {
+                       rxrpc_proto_abort("TXL", call, top);
+                       return false;
+               }
        }
        if (!rxrpc_end_tx_phase(call, true, "ETD"))
                return false;
@@ -854,6 +861,16 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb,
                                  rxrpc_propose_ack_respond_to_ack);
        }
 
+       /* Discard any out-of-order or duplicate ACKs. */
+       if (before_eq(sp->hdr.serial, call->acks_latest)) {
+               _debug("discard ACK %d <= %d",
+                      sp->hdr.serial, call->acks_latest);
+               return;
+       }
+       call->acks_latest_ts = skb->tstamp;
+       call->acks_latest = sp->hdr.serial;
+
+       /* Parse rwind and mtu sizes if provided. */
        ioffset = offset + nr_acks + 3;
        if (skb->len >= ioffset + sizeof(buf.info)) {
                if (skb_copy_bits(skb, ioffset, &buf.info, sizeof(buf.info)) < 0)
@@ -875,23 +892,18 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb,
                return;
        }
 
-       /* Discard any out-of-order or duplicate ACKs. */
-       if (before_eq(sp->hdr.serial, call->acks_latest)) {
-               _debug("discard ACK %d <= %d",
-                      sp->hdr.serial, call->acks_latest);
-               return;
-       }
-       call->acks_latest_ts = skb->tstamp;
-       call->acks_latest = sp->hdr.serial;
-
        if (before(hard_ack, call->tx_hard_ack) ||
            after(hard_ack, call->tx_top))
                return rxrpc_proto_abort("AKW", call, 0);
        if (nr_acks > call->tx_top - hard_ack)
                return rxrpc_proto_abort("AKN", call, 0);
 
-       if (after(hard_ack, call->tx_hard_ack))
-               rxrpc_rotate_tx_window(call, hard_ack, &summary);
+       if (after(hard_ack, call->tx_hard_ack)) {
+               if (rxrpc_rotate_tx_window(call, hard_ack, &summary)) {
+                       rxrpc_end_tx_phase(call, false, "ETA");
+                       return;
+               }
+       }
 
        if (nr_acks > 0) {
                if (skb_copy_bits(skb, offset, buf.acks, nr_acks) < 0)
@@ -900,11 +912,6 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb,
                                      &summary);
        }
 
-       if (test_bit(RXRPC_CALL_TX_LAST, &call->flags)) {
-               rxrpc_end_tx_phase(call, false, "ETA");
-               return;
-       }
-
        if (call->rxtx_annotations[call->tx_top & RXRPC_RXTX_BUFF_MASK] &
            RXRPC_TX_ANNO_LAST &&
            summary.nr_acks == call->tx_top - hard_ack &&
@@ -926,8 +933,7 @@ static void rxrpc_input_ackall(struct rxrpc_call *call, struct sk_buff *skb)
 
        _proto("Rx ACKALL %%%u", sp->hdr.serial);
 
-       rxrpc_rotate_tx_window(call, call->tx_top, &summary);
-       if (test_bit(RXRPC_CALL_TX_LAST, &call->flags))
+       if (rxrpc_rotate_tx_window(call, call->tx_top, &summary))
                rxrpc_end_tx_phase(call, false, "ETL");
 }
 
@@ -971,7 +977,7 @@ static void rxrpc_input_call_packet(struct rxrpc_call *call,
        if (timo) {
                unsigned long now = jiffies, expect_rx_by;
 
-               expect_rx_by = jiffies + timo;
+               expect_rx_by = now + timo;
                WRITE_ONCE(call->expect_rx_by, expect_rx_by);
                rxrpc_reduce_call_timer(call, expect_rx_by, now,
                                        rxrpc_timer_set_for_normal);
@@ -1171,10 +1177,6 @@ void rxrpc_data_ready(struct sock *udp_sk)
 
        trace_rxrpc_rx_packet(sp);
 
-       _net("Rx RxRPC %s ep=%x call=%x:%x",
-            sp->hdr.flags & RXRPC_CLIENT_INITIATED ? "ToServer" : "ToClient",
-            sp->hdr.epoch, sp->hdr.cid, sp->hdr.callNumber);
-
        if (sp->hdr.type >= RXRPC_N_PACKET_TYPES ||
            !((RXRPC_SUPPORTED_PACKET_TYPES >> sp->hdr.type) & 1)) {
                _proto("Rx Bad Packet Type %u", sp->hdr.type);
@@ -1183,11 +1185,13 @@ void rxrpc_data_ready(struct sock *udp_sk)
 
        switch (sp->hdr.type) {
        case RXRPC_PACKET_TYPE_VERSION:
+               if (rxrpc_to_client(sp))
+                       goto discard;
                rxrpc_post_packet_to_local(local, skb);
                goto out;
 
        case RXRPC_PACKET_TYPE_BUSY:
-               if (sp->hdr.flags & RXRPC_CLIENT_INITIATED)
+               if (rxrpc_to_server(sp))
                        goto discard;
                /* Fall through */
 
@@ -1240,16 +1244,19 @@ void rxrpc_data_ready(struct sock *udp_sk)
                        goto discard_unlock;
 
                if (sp->hdr.callNumber == chan->last_call) {
-                       /* For the previous service call, if completed successfully, we
-                        * discard all further packets.
+                       if (chan->call ||
+                           sp->hdr.type == RXRPC_PACKET_TYPE_ABORT)
+                               goto discard_unlock;
+
+                       /* For the previous service call, if completed
+                        * successfully, we discard all further packets.
                         */
                        if (rxrpc_conn_is_service(conn) &&
-                           (chan->last_type == RXRPC_PACKET_TYPE_ACK ||
-                            sp->hdr.type == RXRPC_PACKET_TYPE_ABORT))
+                           chan->last_type == RXRPC_PACKET_TYPE_ACK)
                                goto discard_unlock;
 
-                       /* But otherwise we need to retransmit the final packet from
-                        * data cached in the connection record.
+                       /* But otherwise we need to retransmit the final packet
+                        * from data cached in the connection record.
                         */
                        rxrpc_post_packet_to_conn(conn, skb);
                        goto out_unlock;
@@ -1258,7 +1265,7 @@ void rxrpc_data_ready(struct sock *udp_sk)
                call = rcu_dereference(chan->call);
 
                if (sp->hdr.callNumber > chan->call_id) {
-                       if (!(sp->hdr.flags & RXRPC_CLIENT_INITIATED)) {
+                       if (rxrpc_to_client(sp)) {
                                rcu_read_unlock();
                                goto reject_packet;
                        }
@@ -1275,7 +1282,7 @@ void rxrpc_data_ready(struct sock *udp_sk)
        }
 
        if (!call || atomic_read(&call->usage) == 0) {
-               if (!(sp->hdr.type & RXRPC_CLIENT_INITIATED) ||
+               if (rxrpc_to_client(sp) ||
                    sp->hdr.callNumber == 0 ||
                    sp->hdr.type != RXRPC_PACKET_TYPE_DATA)
                        goto bad_message_unlock;