^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * net/tipc/link.c: TIPC link code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 1996-2007, 2012-2016, Ericsson AB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2004-2007, 2010-2013, Wind River Systems
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Redistribution and use in source and binary forms, with or without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * modification, are permitted provided that the following conditions are met:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * 1. Redistributions of source code must retain the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * notice, this list of conditions and the following disclaimer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * 2. Redistributions in binary form must reproduce the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * notice, this list of conditions and the following disclaimer in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * documentation and/or other materials provided with the distribution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * 3. Neither the names of the copyright holders nor the names of its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * contributors may be used to endorse or promote products derived from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * this software without specific prior written permission.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * Alternatively, this software may be distributed under the terms of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * GNU General Public License ("GPL") version 2 as published by the Free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * Software Foundation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * POSSIBILITY OF SUCH DAMAGE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include "core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include "subscr.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include "link.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include "bcast.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include "socket.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include "name_distr.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include "discover.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include "netlink.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include "monitor.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include "trace.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include "crypto.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <linux/pkt_sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct tipc_stats {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) u32 sent_pkts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) u32 recv_pkts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) u32 sent_states;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) u32 recv_states;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) u32 sent_probes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) u32 recv_probes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) u32 sent_nacks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) u32 recv_nacks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) u32 sent_acks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) u32 sent_bundled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) u32 sent_bundles;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) u32 recv_bundled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) u32 recv_bundles;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) u32 retransmitted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) u32 sent_fragmented;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) u32 sent_fragments;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) u32 recv_fragmented;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) u32 recv_fragments;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) u32 link_congs; /* # port sends blocked by congestion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) u32 deferred_recv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) u32 duplicates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) u32 max_queue_sz; /* send queue size high water mark */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) u32 accu_queue_sz; /* used for send queue size profiling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) u32 queue_sz_counts; /* used for send queue size profiling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) u32 msg_length_counts; /* used for message length profiling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) u32 msg_lengths_total; /* used for message length profiling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) u32 msg_length_profile[7]; /* used for msg. length profiling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * struct tipc_link - TIPC link data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * @addr: network address of link's peer node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * @name: link name character string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * @media_addr: media address to use when sending messages over link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * @timer: link timer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * @net: pointer to namespace struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * @refcnt: reference counter for permanent references (owner node & timer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * @peer_session: link session # being used by peer end of link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * @peer_bearer_id: bearer id used by link's peer endpoint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * @bearer_id: local bearer id used by link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * @tolerance: minimum link continuity loss needed to reset link [in ms]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * @abort_limit: # of unacknowledged continuity probes needed to reset link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * @state: current state of link FSM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * @peer_caps: bitmap describing capabilities of peer node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * @silent_intv_cnt: # of timer intervals without any reception from peer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * @proto_msg: template for control messages generated by link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * @pmsg: convenience pointer to "proto_msg" field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * @priority: current link priority
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * @net_plane: current link network plane ('A' through 'H')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * @mon_state: cookie with information needed by link monitor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * @backlog_limit: backlog queue congestion thresholds (indexed by importance)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * @exp_msg_count: # of tunnelled messages expected during link changeover
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * @reset_rcv_checkpt: seq # of last acknowledged message at time of link reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * @mtu: current maximum packet size for this link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * @advertised_mtu: advertised own mtu when link is being established
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * @transmitq: queue for sent, non-acked messages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * @backlogq: queue for messages waiting to be sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * @snt_nxt: next sequence number to use for outbound messages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * @ackers: # of peers that needs to ack each packet before it can be released
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * @acked: # last packet acked by a certain peer. Used for broadcast.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * @rcv_nxt: next sequence number to expect for inbound messages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * @deferred_queue: deferred queue saved OOS b'cast message received from node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * @unacked_window: # of inbound messages rx'd without ack'ing back to peer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * @inputq: buffer queue for messages to be delivered upwards
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * @namedq: buffer queue for name table messages to be delivered upwards
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * @next_out: ptr to first unsent outbound message in queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * @wakeupq: linked list of wakeup msgs waiting for link congestion to abate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * @long_msg_seq_no: next identifier to use for outbound fragmented messages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * @reasm_buf: head of partially reassembled inbound message fragments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * @bc_rcvr: marks that this is a broadcast receiver link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * @stats: collects statistics regarding link activity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) struct tipc_link {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) u32 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) char name[TIPC_MAX_LINK_NAME];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct net *net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) /* Management and link supervision data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) u16 peer_session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) u16 session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) u16 snd_nxt_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) u16 rcv_nxt_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) u32 peer_bearer_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) u32 bearer_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) u32 tolerance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) u32 abort_limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) u32 state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) u16 peer_caps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) bool in_session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) bool active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) u32 silent_intv_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) char if_name[TIPC_MAX_IF_NAME];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) u32 priority;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) char net_plane;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) struct tipc_mon_state mon_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) u16 rst_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /* Failover/synch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) u16 drop_point;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) struct sk_buff *failover_reasm_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) struct sk_buff_head failover_deferdq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) /* Max packet negotiation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) u16 mtu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) u16 advertised_mtu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) /* Sending */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) struct sk_buff_head transmq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) struct sk_buff_head backlogq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) u16 limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) struct sk_buff *target_bskb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) } backlog[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) u16 snd_nxt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) /* Reception */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) u16 rcv_nxt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) u32 rcv_unacked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) struct sk_buff_head deferdq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct sk_buff_head *inputq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) struct sk_buff_head *namedq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) /* Congestion handling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) struct sk_buff_head wakeupq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) u16 window;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) u16 min_win;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) u16 ssthresh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) u16 max_win;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) u16 cong_acks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) u16 checkpoint;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) /* Fragmentation/reassembly */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) struct sk_buff *reasm_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) struct sk_buff *reasm_tnlmsg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) /* Broadcast */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) u16 ackers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) u16 acked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) u16 last_gap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) struct tipc_gap_ack_blks *last_ga;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) struct tipc_link *bc_rcvlink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) struct tipc_link *bc_sndlink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) u8 nack_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) bool bc_peer_is_up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) /* Statistics */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) struct tipc_stats stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * Error message prefixes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) static const char *link_co_err = "Link tunneling error, ";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) static const char *link_rst_msg = "Resetting link ";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) /* Send states for broadcast NACKs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) BC_NACK_SND_CONDITIONAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) BC_NACK_SND_UNCONDITIONAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) BC_NACK_SND_SUPPRESS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) #define TIPC_BC_RETR_LIM (jiffies + msecs_to_jiffies(10))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) #define TIPC_UC_RETR_TIME (jiffies + msecs_to_jiffies(1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) /* Link FSM states:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) LINK_ESTABLISHED = 0xe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) LINK_ESTABLISHING = 0xe << 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) LINK_RESET = 0x1 << 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) LINK_RESETTING = 0x2 << 12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) LINK_PEER_RESET = 0xd << 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) LINK_FAILINGOVER = 0xf << 20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) LINK_SYNCHING = 0xc << 24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) /* Link FSM state checking routines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) static int link_is_up(struct tipc_link *l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return l->state & (LINK_ESTABLISHED | LINK_SYNCHING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) struct sk_buff_head *xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) static void tipc_link_build_proto_msg(struct tipc_link *l, int mtyp, bool probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) bool probe_reply, u16 rcvgap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) int tolerance, int priority,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) struct sk_buff_head *xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static void link_print(struct tipc_link *l, const char *str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) static int tipc_link_build_nack_msg(struct tipc_link *l,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) struct sk_buff_head *xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) static void tipc_link_build_bc_init_msg(struct tipc_link *l,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) struct sk_buff_head *xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) static u8 __tipc_build_gap_ack_blks(struct tipc_gap_ack_blks *ga,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) struct tipc_link *l, u8 start_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) static u16 tipc_build_gap_ack_blks(struct tipc_link *l, struct tipc_msg *hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) static int tipc_link_advance_transmq(struct tipc_link *l, struct tipc_link *r,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) u16 acked, u16 gap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) struct tipc_gap_ack_blks *ga,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) struct sk_buff_head *xmitq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) bool *retransmitted, int *rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) static void tipc_link_update_cwin(struct tipc_link *l, int released,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) bool retransmitted);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * Simple non-static link routines (i.e. referenced outside this file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) bool tipc_link_is_up(struct tipc_link *l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) return link_is_up(l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) bool tipc_link_peer_is_down(struct tipc_link *l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) return l->state == LINK_PEER_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) bool tipc_link_is_reset(struct tipc_link *l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) return l->state & (LINK_RESET | LINK_FAILINGOVER | LINK_ESTABLISHING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) bool tipc_link_is_establishing(struct tipc_link *l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) return l->state == LINK_ESTABLISHING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) bool tipc_link_is_synching(struct tipc_link *l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) return l->state == LINK_SYNCHING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) bool tipc_link_is_failingover(struct tipc_link *l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return l->state == LINK_FAILINGOVER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) bool tipc_link_is_blocked(struct tipc_link *l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return l->state & (LINK_RESETTING | LINK_PEER_RESET | LINK_FAILINGOVER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) static bool link_is_bc_sndlink(struct tipc_link *l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) return !l->bc_sndlink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) static bool link_is_bc_rcvlink(struct tipc_link *l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) return ((l->bc_rcvlink == l) && !link_is_bc_sndlink(l));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) void tipc_link_set_active(struct tipc_link *l, bool active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) l->active = active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) u32 tipc_link_id(struct tipc_link *l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return l->peer_bearer_id << 16 | l->bearer_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) int tipc_link_min_win(struct tipc_link *l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) return l->min_win;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) int tipc_link_max_win(struct tipc_link *l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return l->max_win;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) int tipc_link_prio(struct tipc_link *l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) return l->priority;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) unsigned long tipc_link_tolerance(struct tipc_link *l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) return l->tolerance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) struct sk_buff_head *tipc_link_inputq(struct tipc_link *l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return l->inputq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) char tipc_link_plane(struct tipc_link *l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) return l->net_plane;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) void tipc_link_update_caps(struct tipc_link *l, u16 capabilities)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) l->peer_caps = capabilities;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) void tipc_link_add_bc_peer(struct tipc_link *snd_l,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) struct tipc_link *uc_l,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) struct sk_buff_head *xmitq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) struct tipc_link *rcv_l = uc_l->bc_rcvlink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) snd_l->ackers++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) rcv_l->acked = snd_l->snd_nxt - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) snd_l->state = LINK_ESTABLISHED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) tipc_link_build_bc_init_msg(uc_l, xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) void tipc_link_remove_bc_peer(struct tipc_link *snd_l,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) struct tipc_link *rcv_l,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) struct sk_buff_head *xmitq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) u16 ack = snd_l->snd_nxt - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) snd_l->ackers--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) rcv_l->bc_peer_is_up = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) rcv_l->state = LINK_ESTABLISHED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) tipc_link_bc_ack_rcv(rcv_l, ack, 0, NULL, xmitq, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) trace_tipc_link_reset(rcv_l, TIPC_DUMP_ALL, "bclink removed!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) tipc_link_reset(rcv_l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) rcv_l->state = LINK_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (!snd_l->ackers) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) trace_tipc_link_reset(snd_l, TIPC_DUMP_ALL, "zero ackers!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) tipc_link_reset(snd_l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) snd_l->state = LINK_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) __skb_queue_purge(xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) int tipc_link_bc_peers(struct tipc_link *l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) return l->ackers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) static u16 link_bc_rcv_gap(struct tipc_link *l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) struct sk_buff *skb = skb_peek(&l->deferdq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) u16 gap = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (more(l->snd_nxt, l->rcv_nxt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) gap = l->snd_nxt - l->rcv_nxt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) gap = buf_seqno(skb) - l->rcv_nxt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) return gap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) void tipc_link_set_mtu(struct tipc_link *l, int mtu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) l->mtu = mtu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) int tipc_link_mtu(struct tipc_link *l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) return l->mtu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) int tipc_link_mss(struct tipc_link *l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) #ifdef CONFIG_TIPC_CRYPTO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) return l->mtu - INT_H_SIZE - EMSG_OVERHEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) return l->mtu - INT_H_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) u16 tipc_link_rcv_nxt(struct tipc_link *l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) return l->rcv_nxt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) u16 tipc_link_acked(struct tipc_link *l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) return l->acked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) char *tipc_link_name(struct tipc_link *l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) return l->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) u32 tipc_link_state(struct tipc_link *l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) return l->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) * tipc_link_create - create a new link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) * @net: pointer to associated network namespace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) * @if_name: associated interface name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) * @bearer_id: id (index) of associated bearer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) * @tolerance: link tolerance to be used by link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) * @net_plane: network plane (A,B,c..) this link belongs to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) * @mtu: mtu to be advertised by link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) * @priority: priority to be used by link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) * @min_win: minimal send window to be used by link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) * @max_win: maximal send window to be used by link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) * @session: session to be used by link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) * @ownnode: identity of own node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) * @peer: node id of peer node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) * @peer_caps: bitmap describing peer node capabilities
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) * @bc_sndlink: the namespace global link used for broadcast sending
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) * @bc_rcvlink: the peer specific link used for broadcast reception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) * @inputq: queue to put messages ready for delivery
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) * @namedq: queue to put binding table update messages ready for delivery
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) * @link: return value, pointer to put the created link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) * Returns true if link was created, otherwise false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) bool tipc_link_create(struct net *net, char *if_name, int bearer_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) int tolerance, char net_plane, u32 mtu, int priority,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) u32 min_win, u32 max_win, u32 session, u32 self,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) u32 peer, u8 *peer_id, u16 peer_caps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) struct tipc_link *bc_sndlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) struct tipc_link *bc_rcvlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) struct sk_buff_head *inputq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) struct sk_buff_head *namedq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) struct tipc_link **link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) char peer_str[NODE_ID_STR_LEN] = {0,};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) char self_str[NODE_ID_STR_LEN] = {0,};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) struct tipc_link *l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) l = kzalloc(sizeof(*l), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) if (!l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) *link = l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) l->session = session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) /* Set link name for unicast links only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) if (peer_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) tipc_nodeid2string(self_str, tipc_own_id(net));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (strlen(self_str) > 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) sprintf(self_str, "%x", self);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) tipc_nodeid2string(peer_str, peer_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if (strlen(peer_str) > 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) sprintf(peer_str, "%x", peer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) /* Peer i/f name will be completed by reset/activate message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) snprintf(l->name, sizeof(l->name), "%s:%s-%s:unknown",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) self_str, if_name, peer_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) strcpy(l->if_name, if_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) l->addr = peer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) l->peer_caps = peer_caps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) l->net = net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) l->in_session = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) l->bearer_id = bearer_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) l->tolerance = tolerance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (bc_rcvlink)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) bc_rcvlink->tolerance = tolerance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) l->net_plane = net_plane;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) l->advertised_mtu = mtu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) l->mtu = mtu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) l->priority = priority;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) tipc_link_set_queue_limits(l, min_win, max_win);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) l->ackers = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) l->bc_sndlink = bc_sndlink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) l->bc_rcvlink = bc_rcvlink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) l->inputq = inputq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) l->namedq = namedq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) l->state = LINK_RESETTING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) __skb_queue_head_init(&l->transmq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) __skb_queue_head_init(&l->backlogq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) __skb_queue_head_init(&l->deferdq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) __skb_queue_head_init(&l->failover_deferdq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) skb_queue_head_init(&l->wakeupq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) skb_queue_head_init(l->inputq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) * tipc_link_bc_create - create new link to be used for broadcast
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) * @net: pointer to associated network namespace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) * @mtu: mtu to be used initially if no peers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) * @min_win: minimal send window to be used by link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) * @max_win: maximal send window to be used by link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) * @inputq: queue to put messages ready for delivery
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) * @namedq: queue to put binding table update messages ready for delivery
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) * @link: return value, pointer to put the created link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) * Returns true if link was created, otherwise false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) bool tipc_link_bc_create(struct net *net, u32 ownnode, u32 peer, u8 *peer_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) int mtu, u32 min_win, u32 max_win, u16 peer_caps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) struct sk_buff_head *inputq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) struct sk_buff_head *namedq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) struct tipc_link *bc_sndlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) struct tipc_link **link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) struct tipc_link *l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) if (!tipc_link_create(net, "", MAX_BEARERS, 0, 'Z', mtu, 0, min_win,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) max_win, 0, ownnode, peer, NULL, peer_caps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) bc_sndlink, NULL, inputq, namedq, link))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) l = *link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (peer_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) char peer_str[NODE_ID_STR_LEN] = {0,};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) tipc_nodeid2string(peer_str, peer_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) if (strlen(peer_str) > 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) sprintf(peer_str, "%x", peer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) /* Broadcast receiver link name: "broadcast-link:<peer>" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) snprintf(l->name, sizeof(l->name), "%s:%s", tipc_bclink_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) peer_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) strcpy(l->name, tipc_bclink_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) trace_tipc_link_reset(l, TIPC_DUMP_ALL, "bclink created!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) tipc_link_reset(l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) l->state = LINK_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) l->ackers = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) l->bc_rcvlink = l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) /* Broadcast send link is always up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) if (link_is_bc_sndlink(l))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) l->state = LINK_ESTABLISHED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) /* Disable replicast if even a single peer doesn't support it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) if (link_is_bc_rcvlink(l) && !(peer_caps & TIPC_BCAST_RCAST))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) tipc_bcast_toggle_rcast(net, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) * tipc_link_fsm_evt - link finite state machine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) * @l: pointer to link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) * @evt: state machine event to be processed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) int tipc_link_fsm_evt(struct tipc_link *l, int evt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) int old_state = l->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) switch (l->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) case LINK_RESETTING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) switch (evt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) case LINK_PEER_RESET_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) l->state = LINK_PEER_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) case LINK_RESET_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) l->state = LINK_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) case LINK_FAILURE_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) case LINK_FAILOVER_BEGIN_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) case LINK_ESTABLISH_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) case LINK_FAILOVER_END_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) case LINK_SYNCH_BEGIN_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) case LINK_SYNCH_END_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) goto illegal_evt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) case LINK_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) switch (evt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) case LINK_PEER_RESET_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) l->state = LINK_ESTABLISHING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) case LINK_FAILOVER_BEGIN_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) l->state = LINK_FAILINGOVER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) case LINK_FAILURE_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) case LINK_RESET_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) case LINK_ESTABLISH_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) case LINK_FAILOVER_END_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) case LINK_SYNCH_BEGIN_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) case LINK_SYNCH_END_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) goto illegal_evt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) case LINK_PEER_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) switch (evt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) case LINK_RESET_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) l->state = LINK_ESTABLISHING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) case LINK_PEER_RESET_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) case LINK_ESTABLISH_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) case LINK_FAILURE_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) case LINK_SYNCH_BEGIN_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) case LINK_SYNCH_END_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) case LINK_FAILOVER_BEGIN_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) case LINK_FAILOVER_END_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) goto illegal_evt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) case LINK_FAILINGOVER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) switch (evt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) case LINK_FAILOVER_END_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) l->state = LINK_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) case LINK_PEER_RESET_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) case LINK_RESET_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) case LINK_ESTABLISH_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) case LINK_FAILURE_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) case LINK_FAILOVER_BEGIN_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) case LINK_SYNCH_BEGIN_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) case LINK_SYNCH_END_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) goto illegal_evt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) case LINK_ESTABLISHING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) switch (evt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) case LINK_ESTABLISH_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) l->state = LINK_ESTABLISHED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) case LINK_FAILOVER_BEGIN_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) l->state = LINK_FAILINGOVER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) case LINK_RESET_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) l->state = LINK_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) case LINK_FAILURE_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) case LINK_PEER_RESET_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) case LINK_SYNCH_BEGIN_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) case LINK_FAILOVER_END_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) case LINK_SYNCH_END_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) goto illegal_evt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) case LINK_ESTABLISHED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) switch (evt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) case LINK_PEER_RESET_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) l->state = LINK_PEER_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) rc |= TIPC_LINK_DOWN_EVT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) case LINK_FAILURE_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) l->state = LINK_RESETTING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) rc |= TIPC_LINK_DOWN_EVT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) case LINK_RESET_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) l->state = LINK_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) case LINK_ESTABLISH_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) case LINK_SYNCH_END_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) case LINK_SYNCH_BEGIN_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) l->state = LINK_SYNCHING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) case LINK_FAILOVER_BEGIN_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) case LINK_FAILOVER_END_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) goto illegal_evt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) case LINK_SYNCHING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) switch (evt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) case LINK_PEER_RESET_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) l->state = LINK_PEER_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) rc |= TIPC_LINK_DOWN_EVT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) case LINK_FAILURE_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) l->state = LINK_RESETTING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) rc |= TIPC_LINK_DOWN_EVT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) case LINK_RESET_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) l->state = LINK_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) case LINK_ESTABLISH_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) case LINK_SYNCH_BEGIN_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) case LINK_SYNCH_END_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) l->state = LINK_ESTABLISHED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) case LINK_FAILOVER_BEGIN_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) case LINK_FAILOVER_END_EVT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) goto illegal_evt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) pr_err("Unknown FSM state %x in %s\n", l->state, l->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) trace_tipc_link_fsm(l->name, old_state, l->state, evt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) illegal_evt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) pr_err("Illegal FSM event %x in state %x on link %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) evt, l->state, l->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) trace_tipc_link_fsm(l->name, old_state, l->state, evt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) /* link_profile_stats - update statistical profiling of traffic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) static void link_profile_stats(struct tipc_link *l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) struct tipc_msg *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) int length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) /* Update counters used in statistical profiling of send traffic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) l->stats.accu_queue_sz += skb_queue_len(&l->transmq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) l->stats.queue_sz_counts++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) skb = skb_peek(&l->transmq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) msg = buf_msg(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) length = msg_size(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) if (msg_user(msg) == MSG_FRAGMENTER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) if (msg_type(msg) != FIRST_FRAGMENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) length = msg_size(msg_inner_hdr(msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) l->stats.msg_lengths_total += length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) l->stats.msg_length_counts++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) if (length <= 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) l->stats.msg_length_profile[0]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) else if (length <= 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) l->stats.msg_length_profile[1]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) else if (length <= 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) l->stats.msg_length_profile[2]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) else if (length <= 4096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) l->stats.msg_length_profile[3]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) else if (length <= 16384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) l->stats.msg_length_profile[4]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) else if (length <= 32768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) l->stats.msg_length_profile[5]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) l->stats.msg_length_profile[6]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) * tipc_link_too_silent - check if link is "too silent"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) * @l: tipc link to be checked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) * Returns true if the link 'silent_intv_cnt' is about to reach the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) * 'abort_limit' value, otherwise false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) bool tipc_link_too_silent(struct tipc_link *l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) return (l->silent_intv_cnt + 2 > l->abort_limit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) /* tipc_link_timeout - perform periodic task as instructed from node timeout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) int tipc_link_timeout(struct tipc_link *l, struct sk_buff_head *xmitq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) int mtyp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) bool state = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) bool probe = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) bool setup = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) u16 bc_snt = l->bc_sndlink->snd_nxt - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) u16 bc_acked = l->bc_rcvlink->acked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) struct tipc_mon_state *mstate = &l->mon_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) trace_tipc_link_timeout(l, TIPC_DUMP_NONE, " ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) trace_tipc_link_too_silent(l, TIPC_DUMP_ALL, " ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) switch (l->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) case LINK_ESTABLISHED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) case LINK_SYNCHING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) mtyp = STATE_MSG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) link_profile_stats(l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) tipc_mon_get_state(l->net, l->addr, mstate, l->bearer_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) if (mstate->reset || (l->silent_intv_cnt > l->abort_limit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) return tipc_link_fsm_evt(l, LINK_FAILURE_EVT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) state = bc_acked != bc_snt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) state |= l->bc_rcvlink->rcv_unacked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) state |= l->rcv_unacked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) state |= !skb_queue_empty(&l->transmq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) probe = mstate->probing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) probe |= l->silent_intv_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) if (probe || mstate->monitoring)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) l->silent_intv_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) probe |= !skb_queue_empty(&l->deferdq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) if (l->snd_nxt == l->checkpoint) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) tipc_link_update_cwin(l, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) probe = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) l->checkpoint = l->snd_nxt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) case LINK_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) setup = l->rst_cnt++ <= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) setup |= !(l->rst_cnt % 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) mtyp = RESET_MSG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) case LINK_ESTABLISHING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) setup = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) mtyp = ACTIVATE_MSG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) case LINK_PEER_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) case LINK_RESETTING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) case LINK_FAILINGOVER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) if (state || probe || setup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) tipc_link_build_proto_msg(l, mtyp, probe, 0, 0, 0, 0, xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) * link_schedule_user - schedule a message sender for wakeup after congestion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) * @l: congested link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) * @hdr: header of message that is being sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) * Create pseudo msg to send back to user when congestion abates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) static int link_schedule_user(struct tipc_link *l, struct tipc_msg *hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) u32 dnode = tipc_own_addr(l->net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) u32 dport = msg_origport(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) /* Create and schedule wakeup pseudo message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) skb = tipc_msg_create(SOCK_WAKEUP, 0, INT_H_SIZE, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) dnode, l->addr, dport, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) msg_set_dest_droppable(buf_msg(skb), true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) TIPC_SKB_CB(skb)->chain_imp = msg_importance(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) skb_queue_tail(&l->wakeupq, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) l->stats.link_congs++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) trace_tipc_link_conges(l, TIPC_DUMP_ALL, "wakeup scheduled!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) return -ELINKCONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) * link_prepare_wakeup - prepare users for wakeup after congestion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) * @l: congested link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) * Wake up a number of waiting users, as permitted by available space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) * in the send queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) static void link_prepare_wakeup(struct tipc_link *l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) struct sk_buff_head *wakeupq = &l->wakeupq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) struct sk_buff_head *inputq = l->inputq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) struct sk_buff *skb, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) struct sk_buff_head tmpq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) int avail[5] = {0,};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) int imp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) __skb_queue_head_init(&tmpq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) for (; imp <= TIPC_SYSTEM_IMPORTANCE; imp++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) avail[imp] = l->backlog[imp].limit - l->backlog[imp].len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) skb_queue_walk_safe(wakeupq, skb, tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) imp = TIPC_SKB_CB(skb)->chain_imp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) if (avail[imp] <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) avail[imp]--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) __skb_unlink(skb, wakeupq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) __skb_queue_tail(&tmpq, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) spin_lock_bh(&inputq->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) skb_queue_splice_tail(&tmpq, inputq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) spin_unlock_bh(&inputq->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) * tipc_link_set_skb_retransmit_time - set the time at which retransmission of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) * the given skb should be next attempted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) * @skb: skb to set a future retransmission time for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) * @l: link the skb will be transmitted on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) static void tipc_link_set_skb_retransmit_time(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) struct tipc_link *l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) if (link_is_bc_sndlink(l))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) TIPC_SKB_CB(skb)->nxt_retr = TIPC_BC_RETR_LIM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) TIPC_SKB_CB(skb)->nxt_retr = TIPC_UC_RETR_TIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) void tipc_link_reset(struct tipc_link *l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) struct sk_buff_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) u32 imp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) __skb_queue_head_init(&list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) l->in_session = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) /* Force re-synch of peer session number before establishing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) l->peer_session--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) l->session++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) l->mtu = l->advertised_mtu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) spin_lock_bh(&l->wakeupq.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) skb_queue_splice_init(&l->wakeupq, &list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) spin_unlock_bh(&l->wakeupq.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) spin_lock_bh(&l->inputq->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) skb_queue_splice_init(&list, l->inputq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) spin_unlock_bh(&l->inputq->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) __skb_queue_purge(&l->transmq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) __skb_queue_purge(&l->deferdq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) __skb_queue_purge(&l->backlogq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) __skb_queue_purge(&l->failover_deferdq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) for (imp = 0; imp <= TIPC_SYSTEM_IMPORTANCE; imp++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) l->backlog[imp].len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) l->backlog[imp].target_bskb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) kfree_skb(l->reasm_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) kfree_skb(l->reasm_tnlmsg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) kfree_skb(l->failover_reasm_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) l->reasm_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) l->reasm_tnlmsg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) l->failover_reasm_skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) l->rcv_unacked = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) l->snd_nxt = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) l->rcv_nxt = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) l->snd_nxt_state = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) l->rcv_nxt_state = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) l->acked = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) l->last_gap = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) kfree(l->last_ga);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) l->last_ga = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) l->silent_intv_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) l->rst_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) l->bc_peer_is_up = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) memset(&l->mon_state, 0, sizeof(l->mon_state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) tipc_link_reset_stats(l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) * tipc_link_xmit(): enqueue buffer list according to queue situation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) * @l: link to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) * @list: chain of buffers containing message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) * @xmitq: returned list of packets to be sent by caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) * Consumes the buffer chain.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) * Returns 0 if success, or errno: -ELINKCONG, -EMSGSIZE or -ENOBUFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) * Messages at TIPC_SYSTEM_IMPORTANCE are always accepted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) int tipc_link_xmit(struct tipc_link *l, struct sk_buff_head *list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) struct sk_buff_head *xmitq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) struct sk_buff_head *backlogq = &l->backlogq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) struct sk_buff_head *transmq = &l->transmq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) struct sk_buff *skb, *_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) u16 bc_ack = l->bc_rcvlink->rcv_nxt - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) u16 ack = l->rcv_nxt - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) u16 seqno = l->snd_nxt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) int pkt_cnt = skb_queue_len(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) unsigned int mss = tipc_link_mss(l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) unsigned int cwin = l->window;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) unsigned int mtu = l->mtu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) struct tipc_msg *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) bool new_bundle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) int imp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) if (pkt_cnt <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) hdr = buf_msg(skb_peek(list));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) if (unlikely(msg_size(hdr) > mtu)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) pr_warn("Too large msg, purging xmit list %d %d %d %d %d!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) skb_queue_len(list), msg_user(hdr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) msg_type(hdr), msg_size(hdr), mtu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) __skb_queue_purge(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) imp = msg_importance(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) /* Allow oversubscription of one data msg per source at congestion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) if (unlikely(l->backlog[imp].len >= l->backlog[imp].limit)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) if (imp == TIPC_SYSTEM_IMPORTANCE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) pr_warn("%s<%s>, link overflow", link_rst_msg, l->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) rc = link_schedule_user(l, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) if (pkt_cnt > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) l->stats.sent_fragmented++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) l->stats.sent_fragments += pkt_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) /* Prepare each packet for sending, and add to relevant queue: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) while ((skb = __skb_dequeue(list))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) if (likely(skb_queue_len(transmq) < cwin)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) hdr = buf_msg(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) msg_set_seqno(hdr, seqno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) msg_set_ack(hdr, ack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) msg_set_bcast_ack(hdr, bc_ack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) _skb = skb_clone(skb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) if (!_skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) __skb_queue_purge(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) __skb_queue_tail(transmq, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) tipc_link_set_skb_retransmit_time(skb, l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) __skb_queue_tail(xmitq, _skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) TIPC_SKB_CB(skb)->ackers = l->ackers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) l->rcv_unacked = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) l->stats.sent_pkts++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) seqno++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) if (tipc_msg_try_bundle(l->backlog[imp].target_bskb, &skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) mss, l->addr, &new_bundle)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) if (skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) /* Keep a ref. to the skb for next try */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) l->backlog[imp].target_bskb = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) l->backlog[imp].len++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) __skb_queue_tail(backlogq, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) if (new_bundle) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) l->stats.sent_bundles++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) l->stats.sent_bundled++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) l->stats.sent_bundled++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) l->backlog[imp].target_bskb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) l->backlog[imp].len += (1 + skb_queue_len(list));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) __skb_queue_tail(backlogq, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) skb_queue_splice_tail_init(list, backlogq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) l->snd_nxt = seqno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) static void tipc_link_update_cwin(struct tipc_link *l, int released,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) bool retransmitted)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) int bklog_len = skb_queue_len(&l->backlogq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) struct sk_buff_head *txq = &l->transmq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) int txq_len = skb_queue_len(txq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) u16 cwin = l->window;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) /* Enter fast recovery */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) if (unlikely(retransmitted)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) l->ssthresh = max_t(u16, l->window / 2, 300);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) l->window = min_t(u16, l->ssthresh, l->window);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) /* Enter slow start */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) if (unlikely(!released)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) l->ssthresh = max_t(u16, l->window / 2, 300);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) l->window = l->min_win;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) /* Don't increase window if no pressure on the transmit queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) if (txq_len + bklog_len < cwin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) /* Don't increase window if there are holes the transmit queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) if (txq_len && l->snd_nxt - buf_seqno(skb_peek(txq)) != txq_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) l->cong_acks += released;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) /* Slow start */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) if (cwin <= l->ssthresh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) l->window = min_t(u16, cwin + released, l->max_win);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) /* Congestion avoidance */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) if (l->cong_acks < cwin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) l->window = min_t(u16, ++cwin, l->max_win);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) l->cong_acks = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) static void tipc_link_advance_backlog(struct tipc_link *l,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) struct sk_buff_head *xmitq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) u16 bc_ack = l->bc_rcvlink->rcv_nxt - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) struct sk_buff_head *txq = &l->transmq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) struct sk_buff *skb, *_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) u16 ack = l->rcv_nxt - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) u16 seqno = l->snd_nxt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) struct tipc_msg *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) u16 cwin = l->window;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) u32 imp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) while (skb_queue_len(txq) < cwin) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) skb = skb_peek(&l->backlogq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) _skb = skb_clone(skb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) if (!_skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) __skb_dequeue(&l->backlogq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) hdr = buf_msg(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) imp = msg_importance(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) l->backlog[imp].len--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) if (unlikely(skb == l->backlog[imp].target_bskb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) l->backlog[imp].target_bskb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) __skb_queue_tail(&l->transmq, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) tipc_link_set_skb_retransmit_time(skb, l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) __skb_queue_tail(xmitq, _skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) TIPC_SKB_CB(skb)->ackers = l->ackers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) msg_set_seqno(hdr, seqno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) msg_set_ack(hdr, ack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) msg_set_bcast_ack(hdr, bc_ack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) l->rcv_unacked = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) l->stats.sent_pkts++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) seqno++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) l->snd_nxt = seqno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) * link_retransmit_failure() - Detect repeated retransmit failures
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) * @l: tipc link sender
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) * @r: tipc link receiver (= l in case of unicast)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) * @rc: returned code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) * Return: true if the repeated retransmit failures happens, otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) * false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) static bool link_retransmit_failure(struct tipc_link *l, struct tipc_link *r,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) int *rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) struct sk_buff *skb = skb_peek(&l->transmq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) struct tipc_msg *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) if (!TIPC_SKB_CB(skb)->retr_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) if (!time_after(jiffies, TIPC_SKB_CB(skb)->retr_stamp +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) msecs_to_jiffies(r->tolerance * 10)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) hdr = buf_msg(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) if (link_is_bc_sndlink(l) && !less(r->acked, msg_seqno(hdr)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) pr_warn("Retransmission failure on link <%s>\n", l->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) link_print(l, "State of link ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) pr_info("Failed msg: usr %u, typ %u, len %u, err %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) msg_user(hdr), msg_type(hdr), msg_size(hdr), msg_errcode(hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) pr_info("sqno %u, prev: %x, dest: %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) msg_seqno(hdr), msg_prevnode(hdr), msg_destnode(hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) pr_info("retr_stamp %d, retr_cnt %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) jiffies_to_msecs(TIPC_SKB_CB(skb)->retr_stamp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) TIPC_SKB_CB(skb)->retr_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) trace_tipc_list_dump(&l->transmq, true, "retrans failure!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) trace_tipc_link_dump(l, TIPC_DUMP_NONE, "retrans failure!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) trace_tipc_link_dump(r, TIPC_DUMP_NONE, "retrans failure!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) if (link_is_bc_sndlink(l)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) r->state = LINK_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) *rc |= TIPC_LINK_DOWN_EVT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) *rc |= tipc_link_fsm_evt(l, LINK_FAILURE_EVT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) /* tipc_data_input - deliver data and name distr msgs to upper layer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) * Consumes buffer if message is of right type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) * Node lock must be held
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) static bool tipc_data_input(struct tipc_link *l, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) struct sk_buff_head *inputq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) struct sk_buff_head *mc_inputq = l->bc_rcvlink->inputq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) struct tipc_msg *hdr = buf_msg(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) switch (msg_user(hdr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) case TIPC_LOW_IMPORTANCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) case TIPC_MEDIUM_IMPORTANCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) case TIPC_HIGH_IMPORTANCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) case TIPC_CRITICAL_IMPORTANCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) if (unlikely(msg_in_group(hdr) || msg_mcast(hdr))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) skb_queue_tail(mc_inputq, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) case CONN_MANAGER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) skb_queue_tail(inputq, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) case GROUP_PROTOCOL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) skb_queue_tail(mc_inputq, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) case NAME_DISTRIBUTOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) l->bc_rcvlink->state = LINK_ESTABLISHED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) skb_queue_tail(l->namedq, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) case MSG_BUNDLER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) case TUNNEL_PROTOCOL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) case MSG_FRAGMENTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) case BCAST_PROTOCOL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) #ifdef CONFIG_TIPC_CRYPTO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) case MSG_CRYPTO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) if (TIPC_SKB_CB(skb)->decrypted) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) tipc_crypto_msg_rcv(l->net, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) pr_warn("Dropping received illegal msg type\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) /* tipc_link_input - process packet that has passed link protocol check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) * Consumes buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) static int tipc_link_input(struct tipc_link *l, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) struct sk_buff_head *inputq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) struct sk_buff **reasm_skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) struct tipc_msg *hdr = buf_msg(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) struct sk_buff *iskb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) struct sk_buff_head tmpq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) int usr = msg_user(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) int pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) if (usr == MSG_BUNDLER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) skb_queue_head_init(&tmpq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) l->stats.recv_bundles++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) l->stats.recv_bundled += msg_msgcnt(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) while (tipc_msg_extract(skb, &iskb, &pos))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) tipc_data_input(l, iskb, &tmpq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) tipc_skb_queue_splice_tail(&tmpq, inputq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) } else if (usr == MSG_FRAGMENTER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) l->stats.recv_fragments++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) if (tipc_buf_append(reasm_skb, &skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) l->stats.recv_fragmented++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) tipc_data_input(l, skb, inputq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) } else if (!*reasm_skb && !link_is_bc_rcvlink(l)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) pr_warn_ratelimited("Unable to build fragment list\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) return tipc_link_fsm_evt(l, LINK_FAILURE_EVT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) } else if (usr == BCAST_PROTOCOL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) tipc_bcast_lock(l->net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) tipc_link_bc_init_rcv(l->bc_rcvlink, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) tipc_bcast_unlock(l->net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) /* tipc_link_tnl_rcv() - receive TUNNEL_PROTOCOL message, drop or process the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) * inner message along with the ones in the old link's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) * deferdq
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) * @l: tunnel link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) * @skb: TUNNEL_PROTOCOL message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) * @inputq: queue to put messages ready for delivery
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) static int tipc_link_tnl_rcv(struct tipc_link *l, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) struct sk_buff_head *inputq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) struct sk_buff **reasm_skb = &l->failover_reasm_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) struct sk_buff **reasm_tnlmsg = &l->reasm_tnlmsg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) struct sk_buff_head *fdefq = &l->failover_deferdq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) struct tipc_msg *hdr = buf_msg(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) struct sk_buff *iskb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) int ipos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) u16 seqno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) if (msg_type(hdr) == SYNCH_MSG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) /* Not a fragment? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) if (likely(!msg_nof_fragms(hdr))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) if (unlikely(!tipc_msg_extract(skb, &iskb, &ipos))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) pr_warn_ratelimited("Unable to extract msg, defq: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) skb_queue_len(fdefq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) /* Set fragment type for buf_append */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) if (msg_fragm_no(hdr) == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) msg_set_type(hdr, FIRST_FRAGMENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) else if (msg_fragm_no(hdr) < msg_nof_fragms(hdr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) msg_set_type(hdr, FRAGMENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) msg_set_type(hdr, LAST_FRAGMENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) if (!tipc_buf_append(reasm_tnlmsg, &skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) /* Successful but non-complete reassembly? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) if (*reasm_tnlmsg || link_is_bc_rcvlink(l))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) pr_warn_ratelimited("Unable to reassemble tunnel msg\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) return tipc_link_fsm_evt(l, LINK_FAILURE_EVT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) iskb = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) seqno = buf_seqno(iskb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) if (unlikely(less(seqno, l->drop_point))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) kfree_skb(iskb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) if (unlikely(seqno != l->drop_point)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) __tipc_skb_queue_sorted(fdefq, seqno, iskb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) l->drop_point++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) if (!tipc_data_input(l, iskb, inputq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) rc |= tipc_link_input(l, iskb, inputq, reasm_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) if (unlikely(rc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) } while ((iskb = __tipc_skb_dequeue(fdefq, l->drop_point)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) * tipc_get_gap_ack_blks - get Gap ACK blocks from PROTOCOL/STATE_MSG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) * @ga: returned pointer to the Gap ACK blocks if any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) * @l: the tipc link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) * @hdr: the PROTOCOL/STATE_MSG header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) * @uc: desired Gap ACK blocks type, i.e. unicast (= 1) or broadcast (= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) * Return: the total Gap ACK blocks size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) u16 tipc_get_gap_ack_blks(struct tipc_gap_ack_blks **ga, struct tipc_link *l,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) struct tipc_msg *hdr, bool uc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) struct tipc_gap_ack_blks *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) u16 sz = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) /* Does peer support the Gap ACK blocks feature? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) if (l->peer_caps & TIPC_GAP_ACK_BLOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) p = (struct tipc_gap_ack_blks *)msg_data(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) sz = ntohs(p->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) /* Sanity check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) if (sz == struct_size(p, gacks, p->ugack_cnt + p->bgack_cnt)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) /* Good, check if the desired type exists */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) if ((uc && p->ugack_cnt) || (!uc && p->bgack_cnt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) goto ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) /* Backward compatible: peer might not support bc, but uc? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) } else if (uc && sz == struct_size(p, gacks, p->ugack_cnt)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) if (p->ugack_cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) p->bgack_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) goto ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) /* Other cases: ignore! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) p = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) ok:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) *ga = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) return sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) static u8 __tipc_build_gap_ack_blks(struct tipc_gap_ack_blks *ga,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) struct tipc_link *l, u8 start_index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) struct tipc_gap_ack *gacks = &ga->gacks[start_index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) struct sk_buff *skb = skb_peek(&l->deferdq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) u16 expect, seqno = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) u8 n = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) expect = buf_seqno(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) skb_queue_walk(&l->deferdq, skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) seqno = buf_seqno(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) if (unlikely(more(seqno, expect))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) gacks[n].ack = htons(expect - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) gacks[n].gap = htons(seqno - expect);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) if (++n >= MAX_GAP_ACK_BLKS / 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) pr_info_ratelimited("Gacks on %s: %d, ql: %d!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) l->name, n,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) skb_queue_len(&l->deferdq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) return n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) } else if (unlikely(less(seqno, expect))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) pr_warn("Unexpected skb in deferdq!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) expect = seqno + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) /* last block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) gacks[n].ack = htons(seqno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) gacks[n].gap = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) n++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) return n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) /* tipc_build_gap_ack_blks - build Gap ACK blocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) * @l: tipc unicast link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) * @hdr: the tipc message buffer to store the Gap ACK blocks after built
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) * The function builds Gap ACK blocks for both the unicast & broadcast receiver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) * links of a certain peer, the buffer after built has the network data format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) * as found at the struct tipc_gap_ack_blks definition.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) * returns the actual allocated memory size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) static u16 tipc_build_gap_ack_blks(struct tipc_link *l, struct tipc_msg *hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) struct tipc_link *bcl = l->bc_rcvlink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) struct tipc_gap_ack_blks *ga;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) ga = (struct tipc_gap_ack_blks *)msg_data(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) /* Start with broadcast link first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) tipc_bcast_lock(bcl->net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) msg_set_bcast_ack(hdr, bcl->rcv_nxt - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) msg_set_bc_gap(hdr, link_bc_rcv_gap(bcl));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) ga->bgack_cnt = __tipc_build_gap_ack_blks(ga, bcl, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) tipc_bcast_unlock(bcl->net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) /* Now for unicast link, but an explicit NACK only (???) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) ga->ugack_cnt = (msg_seq_gap(hdr)) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) __tipc_build_gap_ack_blks(ga, l, ga->bgack_cnt) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) /* Total len */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) len = struct_size(ga, gacks, ga->bgack_cnt + ga->ugack_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) ga->len = htons(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) /* tipc_link_advance_transmq - advance TIPC link transmq queue by releasing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) * acked packets, also doing retransmissions if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) * gaps found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) * @l: tipc link with transmq queue to be advanced
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) * @r: tipc link "receiver" i.e. in case of broadcast (= "l" if unicast)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) * @acked: seqno of last packet acked by peer without any gaps before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) * @gap: # of gap packets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) * @ga: buffer pointer to Gap ACK blocks from peer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) * @xmitq: queue for accumulating the retransmitted packets if any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) * @retransmitted: returned boolean value if a retransmission is really issued
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) * @rc: returned code e.g. TIPC_LINK_DOWN_EVT if a repeated retransmit failures
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) * happens (- unlikely case)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) * Return: the number of packets released from the link transmq
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) static int tipc_link_advance_transmq(struct tipc_link *l, struct tipc_link *r,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) u16 acked, u16 gap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) struct tipc_gap_ack_blks *ga,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) struct sk_buff_head *xmitq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) bool *retransmitted, int *rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) struct tipc_gap_ack_blks *last_ga = r->last_ga, *this_ga = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) struct tipc_gap_ack *gacks = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) struct sk_buff *skb, *_skb, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) struct tipc_msg *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) u32 qlen = skb_queue_len(&l->transmq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) u16 nacked = acked, ngap = gap, gack_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) u16 bc_ack = l->bc_rcvlink->rcv_nxt - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) u16 ack = l->rcv_nxt - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) u16 seqno, n = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) u16 end = r->acked, start = end, offset = r->last_gap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) u16 si = (last_ga) ? last_ga->start_index : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) bool is_uc = !link_is_bc_sndlink(l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) bool bc_has_acked = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) trace_tipc_link_retrans(r, acked + 1, acked + gap, &l->transmq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) /* Determine Gap ACK blocks if any for the particular link */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) if (ga && is_uc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) /* Get the Gap ACKs, uc part */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) gack_cnt = ga->ugack_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) gacks = &ga->gacks[ga->bgack_cnt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) } else if (ga) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) /* Copy the Gap ACKs, bc part, for later renewal if needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) this_ga = kmemdup(ga, struct_size(ga, gacks, ga->bgack_cnt),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) if (likely(this_ga)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) this_ga->start_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) /* Start with the bc Gap ACKs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) gack_cnt = this_ga->bgack_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) gacks = &this_ga->gacks[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) /* Hmm, we can get in trouble..., simply ignore it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) pr_warn_ratelimited("Ignoring bc Gap ACKs, no memory\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) /* Advance the link transmq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) skb_queue_walk_safe(&l->transmq, skb, tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) seqno = buf_seqno(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) next_gap_ack:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) if (less_eq(seqno, nacked)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) if (is_uc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) goto release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) /* Skip packets peer has already acked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) if (!more(seqno, r->acked))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) /* Get the next of last Gap ACK blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) while (more(seqno, end)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) if (!last_ga || si >= last_ga->bgack_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) start = end + offset + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) end = ntohs(last_ga->gacks[si].ack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) offset = ntohs(last_ga->gacks[si].gap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) si++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) WARN_ONCE(more(start, end) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) (!offset &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) si < last_ga->bgack_cnt) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) si > MAX_GAP_ACK_BLKS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) "Corrupted Gap ACK: %d %d %d %d %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) start, end, offset, si,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) last_ga->bgack_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) /* Check against the last Gap ACK block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) if (in_range(seqno, start, end))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) /* Update/release the packet peer is acking */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) bc_has_acked = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) if (--TIPC_SKB_CB(skb)->ackers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) release:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) /* release skb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) __skb_unlink(skb, &l->transmq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) } else if (less_eq(seqno, nacked + ngap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) /* First gap: check if repeated retrans failures? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) if (unlikely(seqno == acked + 1 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) link_retransmit_failure(l, r, rc))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) /* Ignore this bc Gap ACKs if any */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) kfree(this_ga);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) this_ga = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) /* retransmit skb if unrestricted*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) if (time_before(jiffies, TIPC_SKB_CB(skb)->nxt_retr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) tipc_link_set_skb_retransmit_time(skb, l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) _skb = pskb_copy(skb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) if (!_skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) hdr = buf_msg(_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) msg_set_ack(hdr, ack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) msg_set_bcast_ack(hdr, bc_ack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) _skb->priority = TC_PRIO_CONTROL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) __skb_queue_tail(xmitq, _skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) l->stats.retransmitted++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) if (!is_uc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) r->stats.retransmitted++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) *retransmitted = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) /* Increase actual retrans counter & mark first time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) if (!TIPC_SKB_CB(skb)->retr_cnt++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) TIPC_SKB_CB(skb)->retr_stamp = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) /* retry with Gap ACK blocks if any */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) if (n >= gack_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) nacked = ntohs(gacks[n].ack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) ngap = ntohs(gacks[n].gap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) n++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) goto next_gap_ack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) /* Renew last Gap ACK blocks for bc if needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) if (bc_has_acked) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) if (this_ga) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) kfree(last_ga);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) r->last_ga = this_ga;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) r->last_gap = gap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) } else if (last_ga) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) if (less(acked, start)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) si--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) offset = start - acked - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) } else if (less(acked, end)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) acked = end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) if (si < last_ga->bgack_cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) last_ga->start_index = si;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) r->last_gap = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) kfree(last_ga);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) r->last_ga = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) r->last_gap = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) r->last_gap = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) r->acked = acked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) kfree(this_ga);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) return qlen - skb_queue_len(&l->transmq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) /* tipc_link_build_state_msg: prepare link state message for transmission
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) * Note that sending of broadcast ack is coordinated among nodes, to reduce
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) * risk of ack storms towards the sender
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) int tipc_link_build_state_msg(struct tipc_link *l, struct sk_buff_head *xmitq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) if (!l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) /* Broadcast ACK must be sent via a unicast link => defer to caller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) if (link_is_bc_rcvlink(l)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) if (((l->rcv_nxt ^ tipc_own_addr(l->net)) & 0xf) != 0xf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) l->rcv_unacked = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) /* Use snd_nxt to store peer's snd_nxt in broadcast rcv link */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) l->snd_nxt = l->rcv_nxt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) return TIPC_LINK_SND_STATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) /* Unicast ACK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) l->rcv_unacked = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) l->stats.sent_acks++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) tipc_link_build_proto_msg(l, STATE_MSG, 0, 0, 0, 0, 0, xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) /* tipc_link_build_reset_msg: prepare link RESET or ACTIVATE message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) void tipc_link_build_reset_msg(struct tipc_link *l, struct sk_buff_head *xmitq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) int mtyp = RESET_MSG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) if (l->state == LINK_ESTABLISHING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) mtyp = ACTIVATE_MSG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) tipc_link_build_proto_msg(l, mtyp, 0, 0, 0, 0, 0, xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) /* Inform peer that this endpoint is going down if applicable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) skb = skb_peek_tail(xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) if (skb && (l->state == LINK_RESET))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) msg_set_peer_stopping(buf_msg(skb), 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) /* tipc_link_build_nack_msg: prepare link nack message for transmission
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) * Note that sending of broadcast NACK is coordinated among nodes, to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) * reduce the risk of NACK storms towards the sender
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) static int tipc_link_build_nack_msg(struct tipc_link *l,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) struct sk_buff_head *xmitq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) u32 def_cnt = ++l->stats.deferred_recv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) struct sk_buff_head *dfq = &l->deferdq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) u32 defq_len = skb_queue_len(dfq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) int match1, match2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) if (link_is_bc_rcvlink(l)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) match1 = def_cnt & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) match2 = tipc_own_addr(l->net) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) if (match1 == match2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) return TIPC_LINK_SND_STATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) if (defq_len >= 3 && !((defq_len - 3) % 16)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) u16 rcvgap = buf_seqno(skb_peek(dfq)) - l->rcv_nxt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) tipc_link_build_proto_msg(l, STATE_MSG, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) rcvgap, 0, 0, xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) /* tipc_link_rcv - process TIPC packets/messages arriving from off-node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) * @l: the link that should handle the message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) * @skb: TIPC packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) * @xmitq: queue to place packets to be sent after this call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) int tipc_link_rcv(struct tipc_link *l, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) struct sk_buff_head *xmitq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) struct sk_buff_head *defq = &l->deferdq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) struct tipc_msg *hdr = buf_msg(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) u16 seqno, rcv_nxt, win_lim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) int released = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) /* Verify and update link state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) if (unlikely(msg_user(hdr) == LINK_PROTOCOL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) return tipc_link_proto_rcv(l, skb, xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) /* Don't send probe at next timeout expiration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) l->silent_intv_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) hdr = buf_msg(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) seqno = msg_seqno(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) rcv_nxt = l->rcv_nxt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) win_lim = rcv_nxt + TIPC_MAX_LINK_WIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) if (unlikely(!link_is_up(l))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) if (l->state == LINK_ESTABLISHING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) rc = TIPC_LINK_UP_EVT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) /* Drop if outside receive window */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) if (unlikely(less(seqno, rcv_nxt) || more(seqno, win_lim))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) l->stats.duplicates++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) released += tipc_link_advance_transmq(l, l, msg_ack(hdr), 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) NULL, NULL, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) /* Defer delivery if sequence gap */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) if (unlikely(seqno != rcv_nxt)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) if (!__tipc_skb_queue_sorted(defq, seqno, skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) l->stats.duplicates++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) rc |= tipc_link_build_nack_msg(l, xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) /* Deliver packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) l->rcv_nxt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) l->stats.recv_pkts++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) if (unlikely(msg_user(hdr) == TUNNEL_PROTOCOL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) rc |= tipc_link_tnl_rcv(l, skb, l->inputq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) else if (!tipc_data_input(l, skb, l->inputq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) rc |= tipc_link_input(l, skb, l->inputq, &l->reasm_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) if (unlikely(++l->rcv_unacked >= TIPC_MIN_LINK_WIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) rc |= tipc_link_build_state_msg(l, xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) if (unlikely(rc & ~TIPC_LINK_SND_STATE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) } while ((skb = __tipc_skb_dequeue(defq, l->rcv_nxt)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) /* Forward queues and wake up waiting users */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) if (released) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) tipc_link_update_cwin(l, released, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) tipc_link_advance_backlog(l, xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) if (unlikely(!skb_queue_empty(&l->wakeupq)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) link_prepare_wakeup(l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) static void tipc_link_build_proto_msg(struct tipc_link *l, int mtyp, bool probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) bool probe_reply, u16 rcvgap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) int tolerance, int priority,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) struct sk_buff_head *xmitq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) struct tipc_mon_state *mstate = &l->mon_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) struct sk_buff_head *dfq = &l->deferdq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) struct tipc_link *bcl = l->bc_rcvlink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) struct tipc_msg *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) bool node_up = link_is_up(bcl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) u16 glen = 0, bc_rcvgap = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) int dlen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) void *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) /* Don't send protocol message during reset or link failover */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) if (tipc_link_is_blocked(l))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) if (!tipc_link_is_up(l) && (mtyp == STATE_MSG))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) if ((probe || probe_reply) && !skb_queue_empty(dfq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) rcvgap = buf_seqno(skb_peek(dfq)) - l->rcv_nxt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) skb = tipc_msg_create(LINK_PROTOCOL, mtyp, INT_H_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) tipc_max_domain_size + MAX_GAP_ACK_BLKS_SZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) l->addr, tipc_own_addr(l->net), 0, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) hdr = buf_msg(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) data = msg_data(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) msg_set_session(hdr, l->session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) msg_set_bearer_id(hdr, l->bearer_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) msg_set_net_plane(hdr, l->net_plane);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) msg_set_next_sent(hdr, l->snd_nxt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) msg_set_ack(hdr, l->rcv_nxt - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) msg_set_bcast_ack(hdr, bcl->rcv_nxt - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) msg_set_bc_ack_invalid(hdr, !node_up);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) msg_set_last_bcast(hdr, l->bc_sndlink->snd_nxt - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) msg_set_link_tolerance(hdr, tolerance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) msg_set_linkprio(hdr, priority);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) msg_set_redundant_link(hdr, node_up);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) msg_set_seq_gap(hdr, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) msg_set_seqno(hdr, l->snd_nxt + U16_MAX / 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) if (mtyp == STATE_MSG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) if (l->peer_caps & TIPC_LINK_PROTO_SEQNO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) msg_set_seqno(hdr, l->snd_nxt_state++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) msg_set_seq_gap(hdr, rcvgap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) bc_rcvgap = link_bc_rcv_gap(bcl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) msg_set_bc_gap(hdr, bc_rcvgap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) msg_set_probe(hdr, probe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) msg_set_is_keepalive(hdr, probe || probe_reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) if (l->peer_caps & TIPC_GAP_ACK_BLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) glen = tipc_build_gap_ack_blks(l, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) tipc_mon_prep(l->net, data + glen, &dlen, mstate, l->bearer_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) msg_set_size(hdr, INT_H_SIZE + glen + dlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) skb_trim(skb, INT_H_SIZE + glen + dlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) l->stats.sent_states++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) l->rcv_unacked = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) /* RESET_MSG or ACTIVATE_MSG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) if (mtyp == ACTIVATE_MSG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) msg_set_dest_session_valid(hdr, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) msg_set_dest_session(hdr, l->peer_session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) msg_set_max_pkt(hdr, l->advertised_mtu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) strcpy(data, l->if_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) msg_set_size(hdr, INT_H_SIZE + TIPC_MAX_IF_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) skb_trim(skb, INT_H_SIZE + TIPC_MAX_IF_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) if (probe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) l->stats.sent_probes++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) if (rcvgap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) l->stats.sent_nacks++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) if (bc_rcvgap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) bcl->stats.sent_nacks++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) skb->priority = TC_PRIO_CONTROL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) __skb_queue_tail(xmitq, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) trace_tipc_proto_build(skb, false, l->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) void tipc_link_create_dummy_tnl_msg(struct tipc_link *l,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) struct sk_buff_head *xmitq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) u32 onode = tipc_own_addr(l->net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) struct tipc_msg *hdr, *ihdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) struct sk_buff_head tnlq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) u32 dnode = l->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) __skb_queue_head_init(&tnlq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) skb = tipc_msg_create(TUNNEL_PROTOCOL, FAILOVER_MSG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) INT_H_SIZE, BASIC_H_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) dnode, onode, 0, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) if (!skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) pr_warn("%sunable to create tunnel packet\n", link_co_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) hdr = buf_msg(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) msg_set_msgcnt(hdr, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) msg_set_bearer_id(hdr, l->peer_bearer_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) ihdr = (struct tipc_msg *)msg_data(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) tipc_msg_init(onode, ihdr, TIPC_LOW_IMPORTANCE, TIPC_DIRECT_MSG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) BASIC_H_SIZE, dnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) msg_set_errcode(ihdr, TIPC_ERR_NO_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) __skb_queue_tail(&tnlq, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) tipc_link_xmit(l, &tnlq, xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) /* tipc_link_tnl_prepare(): prepare and return a list of tunnel packets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) * with contents of the link's transmit and backlog queues.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) void tipc_link_tnl_prepare(struct tipc_link *l, struct tipc_link *tnl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) int mtyp, struct sk_buff_head *xmitq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) struct sk_buff_head *fdefq = &tnl->failover_deferdq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) struct sk_buff *skb, *tnlskb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) struct tipc_msg *hdr, tnlhdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) struct sk_buff_head *queue = &l->transmq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) struct sk_buff_head tmpxq, tnlq, frags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) u16 pktlen, pktcnt, seqno = l->snd_nxt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) bool pktcnt_need_update = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) u16 syncpt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) if (!tnl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) __skb_queue_head_init(&tnlq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) /* Link Synching:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) * From now on, send only one single ("dummy") SYNCH message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) * to peer. The SYNCH message does not contain any data, just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) * a header conveying the synch point to the peer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) if (mtyp == SYNCH_MSG && (tnl->peer_caps & TIPC_TUNNEL_ENHANCED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) tnlskb = tipc_msg_create(TUNNEL_PROTOCOL, SYNCH_MSG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) INT_H_SIZE, 0, l->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) tipc_own_addr(l->net),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) 0, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) if (!tnlskb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) pr_warn("%sunable to create dummy SYNCH_MSG\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) link_co_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) hdr = buf_msg(tnlskb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) syncpt = l->snd_nxt + skb_queue_len(&l->backlogq) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) msg_set_syncpt(hdr, syncpt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) msg_set_bearer_id(hdr, l->peer_bearer_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) __skb_queue_tail(&tnlq, tnlskb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) tipc_link_xmit(tnl, &tnlq, xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) __skb_queue_head_init(&tmpxq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) __skb_queue_head_init(&frags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) /* At least one packet required for safe algorithm => add dummy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) skb = tipc_msg_create(TIPC_LOW_IMPORTANCE, TIPC_DIRECT_MSG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) BASIC_H_SIZE, 0, l->addr, tipc_own_addr(l->net),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) 0, 0, TIPC_ERR_NO_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) if (!skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) pr_warn("%sunable to create tunnel packet\n", link_co_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) __skb_queue_tail(&tnlq, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) tipc_link_xmit(l, &tnlq, &tmpxq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) __skb_queue_purge(&tmpxq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) /* Initialize reusable tunnel packet header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) tipc_msg_init(tipc_own_addr(l->net), &tnlhdr, TUNNEL_PROTOCOL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) mtyp, INT_H_SIZE, l->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) if (mtyp == SYNCH_MSG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) pktcnt = l->snd_nxt - buf_seqno(skb_peek(&l->transmq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) pktcnt = skb_queue_len(&l->transmq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) pktcnt += skb_queue_len(&l->backlogq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) msg_set_msgcnt(&tnlhdr, pktcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) msg_set_bearer_id(&tnlhdr, l->peer_bearer_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) tnl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) /* Wrap each packet into a tunnel packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) skb_queue_walk(queue, skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) hdr = buf_msg(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) if (queue == &l->backlogq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) msg_set_seqno(hdr, seqno++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) pktlen = msg_size(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) /* Tunnel link MTU is not large enough? This could be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) * due to:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) * 1) Link MTU has just changed or set differently;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) * 2) Or FAILOVER on the top of a SYNCH message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) * The 2nd case should not happen if peer supports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) * TIPC_TUNNEL_ENHANCED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) if (pktlen > tnl->mtu - INT_H_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) if (mtyp == FAILOVER_MSG &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) (tnl->peer_caps & TIPC_TUNNEL_ENHANCED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) rc = tipc_msg_fragment(skb, &tnlhdr, tnl->mtu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) &frags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) pr_warn("%sunable to frag msg: rc %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) link_co_err, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) pktcnt += skb_queue_len(&frags) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) pktcnt_need_update = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) skb_queue_splice_tail_init(&frags, &tnlq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) /* Unluckily, peer doesn't have TIPC_TUNNEL_ENHANCED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) * => Just warn it and return!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) pr_warn_ratelimited("%stoo large msg <%d, %d>: %d!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) link_co_err, msg_user(hdr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) msg_type(hdr), msg_size(hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) msg_set_size(&tnlhdr, pktlen + INT_H_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) tnlskb = tipc_buf_acquire(pktlen + INT_H_SIZE, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) if (!tnlskb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) pr_warn("%sunable to send packet\n", link_co_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) skb_copy_to_linear_data(tnlskb, &tnlhdr, INT_H_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) skb_copy_to_linear_data_offset(tnlskb, INT_H_SIZE, hdr, pktlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) __skb_queue_tail(&tnlq, tnlskb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) if (queue != &l->backlogq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) queue = &l->backlogq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) goto tnl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) if (pktcnt_need_update)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) skb_queue_walk(&tnlq, skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) hdr = buf_msg(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) msg_set_msgcnt(hdr, pktcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) tipc_link_xmit(tnl, &tnlq, xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) if (mtyp == FAILOVER_MSG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) tnl->drop_point = l->rcv_nxt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) tnl->failover_reasm_skb = l->reasm_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) l->reasm_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) /* Failover the link's deferdq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) if (unlikely(!skb_queue_empty(fdefq))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) pr_warn("Link failover deferdq not empty: %d!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) skb_queue_len(fdefq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) __skb_queue_purge(fdefq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) skb_queue_splice_init(&l->deferdq, fdefq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) * tipc_link_failover_prepare() - prepare tnl for link failover
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) * This is a special version of the precursor - tipc_link_tnl_prepare(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) * see the tipc_node_link_failover() for details
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) * @l: failover link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) * @tnl: tunnel link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) * @xmitq: queue for messages to be xmited
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) void tipc_link_failover_prepare(struct tipc_link *l, struct tipc_link *tnl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) struct sk_buff_head *xmitq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) struct sk_buff_head *fdefq = &tnl->failover_deferdq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) tipc_link_create_dummy_tnl_msg(tnl, xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) /* This failover link endpoint was never established before,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) * so it has not received anything from peer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) * Otherwise, it must be a normal failover situation or the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) * node has entered SELF_DOWN_PEER_LEAVING and both peer nodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) * would have to start over from scratch instead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) tnl->drop_point = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) tnl->failover_reasm_skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) /* Initiate the link's failover deferdq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) if (unlikely(!skb_queue_empty(fdefq))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) pr_warn("Link failover deferdq not empty: %d!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) skb_queue_len(fdefq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) __skb_queue_purge(fdefq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) /* tipc_link_validate_msg(): validate message against current link state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) * Returns true if message should be accepted, otherwise false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) bool tipc_link_validate_msg(struct tipc_link *l, struct tipc_msg *hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) u16 curr_session = l->peer_session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) u16 session = msg_session(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) int mtyp = msg_type(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) if (msg_user(hdr) != LINK_PROTOCOL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) switch (mtyp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) case RESET_MSG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) if (!l->in_session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) /* Accept only RESET with new session number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) return more(session, curr_session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) case ACTIVATE_MSG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) if (!l->in_session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) /* Accept only ACTIVATE with new or current session number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) return !less(session, curr_session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) case STATE_MSG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) /* Accept only STATE with current session number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) if (!l->in_session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) if (session != curr_session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) /* Extra sanity check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) if (!link_is_up(l) && msg_ack(hdr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) if (!(l->peer_caps & TIPC_LINK_PROTO_SEQNO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) /* Accept only STATE with new sequence number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) return !less(msg_seqno(hdr), l->rcv_nxt_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) /* tipc_link_proto_rcv(): receive link level protocol message :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) * Note that network plane id propagates through the network, and may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) * change at any time. The node with lowest numerical id determines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) * network plane
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) struct sk_buff_head *xmitq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) struct tipc_msg *hdr = buf_msg(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) struct tipc_gap_ack_blks *ga = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) bool reply = msg_probe(hdr), retransmitted = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) u32 dlen = msg_data_sz(hdr), glen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) u16 peers_snd_nxt = msg_next_sent(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) u16 peers_tol = msg_link_tolerance(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) u16 peers_prio = msg_linkprio(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) u16 gap = msg_seq_gap(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) u16 ack = msg_ack(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) u16 rcv_nxt = l->rcv_nxt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) u16 rcvgap = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) int mtyp = msg_type(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) int rc = 0, released;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) char *if_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) void *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) trace_tipc_proto_rcv(skb, false, l->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) if (dlen > U16_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) if (tipc_link_is_blocked(l) || !xmitq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) if (tipc_own_addr(l->net) > msg_prevnode(hdr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) l->net_plane = msg_net_plane(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) skb_linearize(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) hdr = buf_msg(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) data = msg_data(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) if (!tipc_link_validate_msg(l, hdr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) trace_tipc_skb_dump(skb, false, "PROTO invalid (1)!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) trace_tipc_link_dump(l, TIPC_DUMP_NONE, "PROTO invalid (1)!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) switch (mtyp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) case RESET_MSG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) case ACTIVATE_MSG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) /* Complete own link name with peer's interface name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) if_name = strrchr(l->name, ':') + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) if (sizeof(l->name) - (if_name - l->name) <= TIPC_MAX_IF_NAME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) if (msg_data_sz(hdr) < TIPC_MAX_IF_NAME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) strncpy(if_name, data, TIPC_MAX_IF_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) /* Update own tolerance if peer indicates a non-zero value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) if (in_range(peers_tol, TIPC_MIN_LINK_TOL, TIPC_MAX_LINK_TOL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) l->tolerance = peers_tol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) l->bc_rcvlink->tolerance = peers_tol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) /* Update own priority if peer's priority is higher */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) if (in_range(peers_prio, l->priority + 1, TIPC_MAX_LINK_PRI))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) l->priority = peers_prio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) /* If peer is going down we want full re-establish cycle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) if (msg_peer_stopping(hdr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) rc = tipc_link_fsm_evt(l, LINK_FAILURE_EVT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) /* If this endpoint was re-created while peer was ESTABLISHING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) * it doesn't know current session number. Force re-synch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) if (mtyp == ACTIVATE_MSG && msg_dest_session_valid(hdr) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) l->session != msg_dest_session(hdr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) if (less(l->session, msg_dest_session(hdr)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) l->session = msg_dest_session(hdr) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) /* ACTIVATE_MSG serves as PEER_RESET if link is already down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) if (mtyp == RESET_MSG || !link_is_up(l))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) rc = tipc_link_fsm_evt(l, LINK_PEER_RESET_EVT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) /* ACTIVATE_MSG takes up link if it was already locally reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) if (mtyp == ACTIVATE_MSG && l->state == LINK_ESTABLISHING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) rc = TIPC_LINK_UP_EVT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) l->peer_session = msg_session(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) l->in_session = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) l->peer_bearer_id = msg_bearer_id(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) if (l->mtu > msg_max_pkt(hdr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) l->mtu = msg_max_pkt(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) case STATE_MSG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) /* Validate Gap ACK blocks, drop if invalid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) glen = tipc_get_gap_ack_blks(&ga, l, hdr, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) if (glen > dlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) l->rcv_nxt_state = msg_seqno(hdr) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) /* Update own tolerance if peer indicates a non-zero value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) if (in_range(peers_tol, TIPC_MIN_LINK_TOL, TIPC_MAX_LINK_TOL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) l->tolerance = peers_tol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) l->bc_rcvlink->tolerance = peers_tol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) /* Update own prio if peer indicates a different value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) if ((peers_prio != l->priority) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) in_range(peers_prio, 1, TIPC_MAX_LINK_PRI)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) l->priority = peers_prio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) rc = tipc_link_fsm_evt(l, LINK_FAILURE_EVT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) l->silent_intv_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) l->stats.recv_states++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) if (msg_probe(hdr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) l->stats.recv_probes++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) if (!link_is_up(l)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) if (l->state == LINK_ESTABLISHING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) rc = TIPC_LINK_UP_EVT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) tipc_mon_rcv(l->net, data + glen, dlen - glen, l->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) &l->mon_state, l->bearer_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) /* Send NACK if peer has sent pkts we haven't received yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) if ((reply || msg_is_keepalive(hdr)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) more(peers_snd_nxt, rcv_nxt) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) !tipc_link_is_synching(l) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) skb_queue_empty(&l->deferdq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) rcvgap = peers_snd_nxt - l->rcv_nxt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) if (rcvgap || reply)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) tipc_link_build_proto_msg(l, STATE_MSG, 0, reply,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) rcvgap, 0, 0, xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) released = tipc_link_advance_transmq(l, l, ack, gap, ga, xmitq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) &retransmitted, &rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) if (gap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) l->stats.recv_nacks++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) if (released || retransmitted)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) tipc_link_update_cwin(l, released, retransmitted);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) if (released)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) tipc_link_advance_backlog(l, xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) if (unlikely(!skb_queue_empty(&l->wakeupq)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) link_prepare_wakeup(l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) /* tipc_link_build_bc_proto_msg() - create broadcast protocol message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) static bool tipc_link_build_bc_proto_msg(struct tipc_link *l, bool bcast,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) u16 peers_snd_nxt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) struct sk_buff_head *xmitq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) struct tipc_msg *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) struct sk_buff *dfrd_skb = skb_peek(&l->deferdq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) u16 ack = l->rcv_nxt - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) u16 gap_to = peers_snd_nxt - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) skb = tipc_msg_create(BCAST_PROTOCOL, STATE_MSG, INT_H_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) 0, l->addr, tipc_own_addr(l->net), 0, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) hdr = buf_msg(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) msg_set_last_bcast(hdr, l->bc_sndlink->snd_nxt - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) msg_set_bcast_ack(hdr, ack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) msg_set_bcgap_after(hdr, ack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) if (dfrd_skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) gap_to = buf_seqno(dfrd_skb) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) msg_set_bcgap_to(hdr, gap_to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) msg_set_non_seq(hdr, bcast);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) __skb_queue_tail(xmitq, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) /* tipc_link_build_bc_init_msg() - synchronize broadcast link endpoints.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) * Give a newly added peer node the sequence number where it should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) * start receiving and acking broadcast packets.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) static void tipc_link_build_bc_init_msg(struct tipc_link *l,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) struct sk_buff_head *xmitq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) struct sk_buff_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) __skb_queue_head_init(&list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) if (!tipc_link_build_bc_proto_msg(l->bc_rcvlink, false, 0, &list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) msg_set_bc_ack_invalid(buf_msg(skb_peek(&list)), true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) tipc_link_xmit(l, &list, xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) /* tipc_link_bc_init_rcv - receive initial broadcast synch data from peer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) void tipc_link_bc_init_rcv(struct tipc_link *l, struct tipc_msg *hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) int mtyp = msg_type(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) u16 peers_snd_nxt = msg_bc_snd_nxt(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) if (link_is_up(l))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) if (msg_user(hdr) == BCAST_PROTOCOL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) l->rcv_nxt = peers_snd_nxt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) l->state = LINK_ESTABLISHED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) if (l->peer_caps & TIPC_BCAST_SYNCH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) if (msg_peer_node_is_up(hdr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) /* Compatibility: accept older, less safe initial synch data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) if ((mtyp == RESET_MSG) || (mtyp == ACTIVATE_MSG))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) l->rcv_nxt = peers_snd_nxt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) /* tipc_link_bc_sync_rcv - update rcv link according to peer's send state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) int tipc_link_bc_sync_rcv(struct tipc_link *l, struct tipc_msg *hdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) struct sk_buff_head *xmitq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) u16 peers_snd_nxt = msg_bc_snd_nxt(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) if (!link_is_up(l))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) if (!msg_peer_node_is_up(hdr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) /* Open when peer ackowledges our bcast init msg (pkt #1) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) if (msg_ack(hdr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) l->bc_peer_is_up = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) if (!l->bc_peer_is_up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) /* Ignore if peers_snd_nxt goes beyond receive window */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) if (more(peers_snd_nxt, l->rcv_nxt + l->window))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) l->snd_nxt = peers_snd_nxt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) if (link_bc_rcv_gap(l))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) rc |= TIPC_LINK_SND_STATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) /* Return now if sender supports nack via STATE messages */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) if (l->peer_caps & TIPC_BCAST_STATE_NACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) /* Otherwise, be backwards compatible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) if (!more(peers_snd_nxt, l->rcv_nxt)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) l->nack_state = BC_NACK_SND_CONDITIONAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) /* Don't NACK if one was recently sent or peeked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) if (l->nack_state == BC_NACK_SND_SUPPRESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) l->nack_state = BC_NACK_SND_UNCONDITIONAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) /* Conditionally delay NACK sending until next synch rcv */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) if (l->nack_state == BC_NACK_SND_CONDITIONAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) l->nack_state = BC_NACK_SND_UNCONDITIONAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) if ((peers_snd_nxt - l->rcv_nxt) < TIPC_MIN_LINK_WIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) /* Send NACK now but suppress next one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) tipc_link_build_bc_proto_msg(l, true, peers_snd_nxt, xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) l->nack_state = BC_NACK_SND_SUPPRESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) int tipc_link_bc_ack_rcv(struct tipc_link *r, u16 acked, u16 gap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) struct tipc_gap_ack_blks *ga,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) struct sk_buff_head *xmitq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) struct sk_buff_head *retrq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) struct tipc_link *l = r->bc_sndlink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) bool unused = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) if (!link_is_up(r) || !r->bc_peer_is_up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) if (gap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) l->stats.recv_nacks++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) r->stats.recv_nacks++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) if (less(acked, r->acked) || (acked == r->acked && !gap && !ga))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) trace_tipc_link_bc_ack(r, acked, gap, &l->transmq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) tipc_link_advance_transmq(l, r, acked, gap, ga, retrq, &unused, &rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) tipc_link_advance_backlog(l, xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) if (unlikely(!skb_queue_empty(&l->wakeupq)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) link_prepare_wakeup(l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) /* tipc_link_bc_nack_rcv(): receive broadcast nack message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) * This function is here for backwards compatibility, since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) * no BCAST_PROTOCOL/STATE messages occur from TIPC v2.5.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) int tipc_link_bc_nack_rcv(struct tipc_link *l, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) struct sk_buff_head *xmitq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) struct tipc_msg *hdr = buf_msg(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) u32 dnode = msg_destnode(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) int mtyp = msg_type(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) u16 acked = msg_bcast_ack(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) u16 from = acked + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) u16 to = msg_bcgap_to(hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) u16 peers_snd_nxt = to + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) if (!tipc_link_is_up(l) || !l->bc_peer_is_up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) if (mtyp != STATE_MSG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) if (dnode == tipc_own_addr(l->net)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) rc = tipc_link_bc_ack_rcv(l, acked, to - acked, NULL, xmitq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) l->stats.recv_nacks++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) /* Msg for other node => suppress own NACK at next sync if applicable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) if (more(peers_snd_nxt, l->rcv_nxt) && !less(l->rcv_nxt, from))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) l->nack_state = BC_NACK_SND_SUPPRESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) void tipc_link_set_queue_limits(struct tipc_link *l, u32 min_win, u32 max_win)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) int max_bulk = TIPC_MAX_PUBL / (l->mtu / ITEM_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) l->min_win = min_win;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) l->ssthresh = max_win;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) l->max_win = max_win;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) l->window = min_win;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) l->backlog[TIPC_LOW_IMPORTANCE].limit = min_win * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) l->backlog[TIPC_MEDIUM_IMPORTANCE].limit = min_win * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) l->backlog[TIPC_HIGH_IMPORTANCE].limit = min_win * 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) l->backlog[TIPC_CRITICAL_IMPORTANCE].limit = min_win * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) l->backlog[TIPC_SYSTEM_IMPORTANCE].limit = max_bulk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) * link_reset_stats - reset link statistics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) * @l: pointer to link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) void tipc_link_reset_stats(struct tipc_link *l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) memset(&l->stats, 0, sizeof(l->stats));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) static void link_print(struct tipc_link *l, const char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) struct sk_buff *hskb = skb_peek(&l->transmq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) u16 head = hskb ? msg_seqno(buf_msg(hskb)) : l->snd_nxt - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) u16 tail = l->snd_nxt - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) pr_info("%s Link <%s> state %x\n", str, l->name, l->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) pr_info("XMTQ: %u [%u-%u], BKLGQ: %u, SNDNX: %u, RCVNX: %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) skb_queue_len(&l->transmq), head, tail,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) skb_queue_len(&l->backlogq), l->snd_nxt, l->rcv_nxt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) /* Parse and validate nested (link) properties valid for media, bearer and link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) int tipc_nl_parse_link_prop(struct nlattr *prop, struct nlattr *props[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) err = nla_parse_nested_deprecated(props, TIPC_NLA_PROP_MAX, prop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) tipc_nl_prop_policy, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) if (props[TIPC_NLA_PROP_PRIO]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) u32 prio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) prio = nla_get_u32(props[TIPC_NLA_PROP_PRIO]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) if (prio > TIPC_MAX_LINK_PRI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) if (props[TIPC_NLA_PROP_TOL]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) u32 tol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) tol = nla_get_u32(props[TIPC_NLA_PROP_TOL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) if ((tol < TIPC_MIN_LINK_TOL) || (tol > TIPC_MAX_LINK_TOL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) if (props[TIPC_NLA_PROP_WIN]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) u32 max_win;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) max_win = nla_get_u32(props[TIPC_NLA_PROP_WIN]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) if (max_win < TIPC_DEF_LINK_WIN || max_win > TIPC_MAX_LINK_WIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) static int __tipc_nl_add_stats(struct sk_buff *skb, struct tipc_stats *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) struct nlattr *stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) struct nla_map {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) u32 key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) struct nla_map map[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) {TIPC_NLA_STATS_RX_INFO, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) {TIPC_NLA_STATS_RX_FRAGMENTS, s->recv_fragments},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) {TIPC_NLA_STATS_RX_FRAGMENTED, s->recv_fragmented},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) {TIPC_NLA_STATS_RX_BUNDLES, s->recv_bundles},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) {TIPC_NLA_STATS_RX_BUNDLED, s->recv_bundled},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) {TIPC_NLA_STATS_TX_INFO, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) {TIPC_NLA_STATS_TX_FRAGMENTS, s->sent_fragments},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) {TIPC_NLA_STATS_TX_FRAGMENTED, s->sent_fragmented},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) {TIPC_NLA_STATS_TX_BUNDLES, s->sent_bundles},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) {TIPC_NLA_STATS_TX_BUNDLED, s->sent_bundled},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) {TIPC_NLA_STATS_MSG_PROF_TOT, (s->msg_length_counts) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) s->msg_length_counts : 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) {TIPC_NLA_STATS_MSG_LEN_CNT, s->msg_length_counts},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) {TIPC_NLA_STATS_MSG_LEN_TOT, s->msg_lengths_total},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) {TIPC_NLA_STATS_MSG_LEN_P0, s->msg_length_profile[0]},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) {TIPC_NLA_STATS_MSG_LEN_P1, s->msg_length_profile[1]},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) {TIPC_NLA_STATS_MSG_LEN_P2, s->msg_length_profile[2]},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) {TIPC_NLA_STATS_MSG_LEN_P3, s->msg_length_profile[3]},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) {TIPC_NLA_STATS_MSG_LEN_P4, s->msg_length_profile[4]},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) {TIPC_NLA_STATS_MSG_LEN_P5, s->msg_length_profile[5]},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) {TIPC_NLA_STATS_MSG_LEN_P6, s->msg_length_profile[6]},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) {TIPC_NLA_STATS_RX_STATES, s->recv_states},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) {TIPC_NLA_STATS_RX_PROBES, s->recv_probes},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) {TIPC_NLA_STATS_RX_NACKS, s->recv_nacks},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) {TIPC_NLA_STATS_RX_DEFERRED, s->deferred_recv},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) {TIPC_NLA_STATS_TX_STATES, s->sent_states},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) {TIPC_NLA_STATS_TX_PROBES, s->sent_probes},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) {TIPC_NLA_STATS_TX_NACKS, s->sent_nacks},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) {TIPC_NLA_STATS_TX_ACKS, s->sent_acks},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) {TIPC_NLA_STATS_RETRANSMITTED, s->retransmitted},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) {TIPC_NLA_STATS_DUPLICATES, s->duplicates},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) {TIPC_NLA_STATS_LINK_CONGS, s->link_congs},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) {TIPC_NLA_STATS_MAX_QUEUE, s->max_queue_sz},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) {TIPC_NLA_STATS_AVG_QUEUE, s->queue_sz_counts ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) (s->accu_queue_sz / s->queue_sz_counts) : 0}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) stats = nla_nest_start_noflag(skb, TIPC_NLA_LINK_STATS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) if (!stats)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) for (i = 0; i < ARRAY_SIZE(map); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) if (nla_put_u32(skb, map[i].key, map[i].val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) goto msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) nla_nest_end(skb, stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) msg_full:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) nla_nest_cancel(skb, stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) /* Caller should hold appropriate locks to protect the link */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) int __tipc_nl_add_link(struct net *net, struct tipc_nl_msg *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) struct tipc_link *link, int nlflags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) u32 self = tipc_own_addr(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) struct nlattr *attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) struct nlattr *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) nlflags, TIPC_NL_LINK_GET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) attrs = nla_nest_start_noflag(msg->skb, TIPC_NLA_LINK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) if (!attrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) goto msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) if (nla_put_string(msg->skb, TIPC_NLA_LINK_NAME, link->name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) goto attr_msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) if (nla_put_u32(msg->skb, TIPC_NLA_LINK_DEST, tipc_cluster_mask(self)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) goto attr_msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) if (nla_put_u32(msg->skb, TIPC_NLA_LINK_MTU, link->mtu))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) goto attr_msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) if (nla_put_u32(msg->skb, TIPC_NLA_LINK_RX, link->stats.recv_pkts))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) goto attr_msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) if (nla_put_u32(msg->skb, TIPC_NLA_LINK_TX, link->stats.sent_pkts))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) goto attr_msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) if (tipc_link_is_up(link))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) if (nla_put_flag(msg->skb, TIPC_NLA_LINK_UP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) goto attr_msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) if (link->active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) if (nla_put_flag(msg->skb, TIPC_NLA_LINK_ACTIVE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) goto attr_msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) prop = nla_nest_start_noflag(msg->skb, TIPC_NLA_LINK_PROP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) if (!prop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) goto attr_msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) if (nla_put_u32(msg->skb, TIPC_NLA_PROP_PRIO, link->priority))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) goto prop_msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) if (nla_put_u32(msg->skb, TIPC_NLA_PROP_TOL, link->tolerance))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) goto prop_msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) if (nla_put_u32(msg->skb, TIPC_NLA_PROP_WIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) link->window))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) goto prop_msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) if (nla_put_u32(msg->skb, TIPC_NLA_PROP_PRIO, link->priority))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) goto prop_msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) nla_nest_end(msg->skb, prop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) err = __tipc_nl_add_stats(msg->skb, &link->stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) goto attr_msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) nla_nest_end(msg->skb, attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) genlmsg_end(msg->skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) prop_msg_full:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) nla_nest_cancel(msg->skb, prop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) attr_msg_full:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) nla_nest_cancel(msg->skb, attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) msg_full:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) genlmsg_cancel(msg->skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) static int __tipc_nl_add_bc_link_stat(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) struct tipc_stats *stats)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) struct nlattr *nest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) struct nla_map {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) __u32 key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) __u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) struct nla_map map[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) {TIPC_NLA_STATS_RX_INFO, stats->recv_pkts},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) {TIPC_NLA_STATS_RX_FRAGMENTS, stats->recv_fragments},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) {TIPC_NLA_STATS_RX_FRAGMENTED, stats->recv_fragmented},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) {TIPC_NLA_STATS_RX_BUNDLES, stats->recv_bundles},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) {TIPC_NLA_STATS_RX_BUNDLED, stats->recv_bundled},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) {TIPC_NLA_STATS_TX_INFO, stats->sent_pkts},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) {TIPC_NLA_STATS_TX_FRAGMENTS, stats->sent_fragments},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) {TIPC_NLA_STATS_TX_FRAGMENTED, stats->sent_fragmented},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) {TIPC_NLA_STATS_TX_BUNDLES, stats->sent_bundles},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) {TIPC_NLA_STATS_TX_BUNDLED, stats->sent_bundled},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) {TIPC_NLA_STATS_RX_NACKS, stats->recv_nacks},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) {TIPC_NLA_STATS_RX_DEFERRED, stats->deferred_recv},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) {TIPC_NLA_STATS_TX_NACKS, stats->sent_nacks},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) {TIPC_NLA_STATS_TX_ACKS, stats->sent_acks},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) {TIPC_NLA_STATS_RETRANSMITTED, stats->retransmitted},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) {TIPC_NLA_STATS_DUPLICATES, stats->duplicates},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) {TIPC_NLA_STATS_LINK_CONGS, stats->link_congs},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) {TIPC_NLA_STATS_MAX_QUEUE, stats->max_queue_sz},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) {TIPC_NLA_STATS_AVG_QUEUE, stats->queue_sz_counts ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) (stats->accu_queue_sz / stats->queue_sz_counts) : 0}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) nest = nla_nest_start_noflag(skb, TIPC_NLA_LINK_STATS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) if (!nest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) for (i = 0; i < ARRAY_SIZE(map); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) if (nla_put_u32(skb, map[i].key, map[i].val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) goto msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) nla_nest_end(skb, nest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) msg_full:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) nla_nest_cancel(skb, nest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) int tipc_nl_add_bc_link(struct net *net, struct tipc_nl_msg *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) struct tipc_link *bcl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) struct nlattr *attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) struct nlattr *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) u32 bc_mode = tipc_bcast_get_mode(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) u32 bc_ratio = tipc_bcast_get_broadcast_ratio(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) if (!bcl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) tipc_bcast_lock(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) NLM_F_MULTI, TIPC_NL_LINK_GET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) if (!hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) tipc_bcast_unlock(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) attrs = nla_nest_start_noflag(msg->skb, TIPC_NLA_LINK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) if (!attrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) goto msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) /* The broadcast link is always up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) if (nla_put_flag(msg->skb, TIPC_NLA_LINK_UP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) goto attr_msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) if (nla_put_flag(msg->skb, TIPC_NLA_LINK_BROADCAST))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) goto attr_msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) if (nla_put_string(msg->skb, TIPC_NLA_LINK_NAME, bcl->name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) goto attr_msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) if (nla_put_u32(msg->skb, TIPC_NLA_LINK_RX, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) goto attr_msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) if (nla_put_u32(msg->skb, TIPC_NLA_LINK_TX, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) goto attr_msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) prop = nla_nest_start_noflag(msg->skb, TIPC_NLA_LINK_PROP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) if (!prop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) goto attr_msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) if (nla_put_u32(msg->skb, TIPC_NLA_PROP_WIN, bcl->max_win))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) goto prop_msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) if (nla_put_u32(msg->skb, TIPC_NLA_PROP_BROADCAST, bc_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) goto prop_msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) if (bc_mode & BCLINK_MODE_SEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) if (nla_put_u32(msg->skb, TIPC_NLA_PROP_BROADCAST_RATIO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) bc_ratio))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) goto prop_msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) nla_nest_end(msg->skb, prop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) err = __tipc_nl_add_bc_link_stat(msg->skb, &bcl->stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) goto attr_msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) tipc_bcast_unlock(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) nla_nest_end(msg->skb, attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) genlmsg_end(msg->skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) prop_msg_full:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) nla_nest_cancel(msg->skb, prop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) attr_msg_full:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) nla_nest_cancel(msg->skb, attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) msg_full:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) tipc_bcast_unlock(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) genlmsg_cancel(msg->skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) void tipc_link_set_tolerance(struct tipc_link *l, u32 tol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) struct sk_buff_head *xmitq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) l->tolerance = tol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) if (l->bc_rcvlink)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) l->bc_rcvlink->tolerance = tol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) if (link_is_up(l))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) tipc_link_build_proto_msg(l, STATE_MSG, 0, 0, 0, tol, 0, xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) void tipc_link_set_prio(struct tipc_link *l, u32 prio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) struct sk_buff_head *xmitq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) l->priority = prio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) tipc_link_build_proto_msg(l, STATE_MSG, 0, 0, 0, 0, prio, xmitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) void tipc_link_set_abort_limit(struct tipc_link *l, u32 limit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) l->abort_limit = limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) * tipc_link_dump - dump TIPC link data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) * @l: tipc link to be dumped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) * @dqueues: bitmask to decide if any link queue to be dumped?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) * - TIPC_DUMP_NONE: don't dump link queues
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) * - TIPC_DUMP_TRANSMQ: dump link transmq queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) * - TIPC_DUMP_BACKLOGQ: dump link backlog queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) * - TIPC_DUMP_DEFERDQ: dump link deferd queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) * - TIPC_DUMP_INPUTQ: dump link input queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) * - TIPC_DUMP_WAKEUP: dump link wakeup queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) * - TIPC_DUMP_ALL: dump all the link queues above
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) * @buf: returned buffer of dump data in format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) int tipc_link_dump(struct tipc_link *l, u16 dqueues, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) size_t sz = (dqueues) ? LINK_LMAX : LINK_LMIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) struct sk_buff_head *list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) struct sk_buff *hskb, *tskb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) u32 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) if (!l) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) i += scnprintf(buf, sz, "link data: (null)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) i += scnprintf(buf, sz, "link data: %x", l->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) i += scnprintf(buf + i, sz - i, " %x", l->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) i += scnprintf(buf + i, sz - i, " %u", l->in_session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) i += scnprintf(buf + i, sz - i, " %u", l->session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) i += scnprintf(buf + i, sz - i, " %u", l->peer_session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) i += scnprintf(buf + i, sz - i, " %u", l->snd_nxt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) i += scnprintf(buf + i, sz - i, " %u", l->rcv_nxt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) i += scnprintf(buf + i, sz - i, " %u", l->snd_nxt_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) i += scnprintf(buf + i, sz - i, " %u", l->rcv_nxt_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) i += scnprintf(buf + i, sz - i, " %x", l->peer_caps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) i += scnprintf(buf + i, sz - i, " %u", l->silent_intv_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) i += scnprintf(buf + i, sz - i, " %u", l->rst_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) i += scnprintf(buf + i, sz - i, " %u", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) i += scnprintf(buf + i, sz - i, " %u", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) i += scnprintf(buf + i, sz - i, " %u", l->acked);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) list = &l->transmq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) len = skb_queue_len(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) hskb = skb_peek(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) tskb = skb_peek_tail(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) i += scnprintf(buf + i, sz - i, " | %u %u %u", len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) (hskb) ? msg_seqno(buf_msg(hskb)) : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) (tskb) ? msg_seqno(buf_msg(tskb)) : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) list = &l->deferdq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) len = skb_queue_len(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) hskb = skb_peek(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) tskb = skb_peek_tail(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) i += scnprintf(buf + i, sz - i, " | %u %u %u", len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) (hskb) ? msg_seqno(buf_msg(hskb)) : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) (tskb) ? msg_seqno(buf_msg(tskb)) : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) list = &l->backlogq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) len = skb_queue_len(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) hskb = skb_peek(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) tskb = skb_peek_tail(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) i += scnprintf(buf + i, sz - i, " | %u %u %u", len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) (hskb) ? msg_seqno(buf_msg(hskb)) : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) (tskb) ? msg_seqno(buf_msg(tskb)) : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) list = l->inputq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) len = skb_queue_len(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) hskb = skb_peek(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) tskb = skb_peek_tail(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) i += scnprintf(buf + i, sz - i, " | %u %u %u\n", len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) (hskb) ? msg_seqno(buf_msg(hskb)) : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) (tskb) ? msg_seqno(buf_msg(tskb)) : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) if (dqueues & TIPC_DUMP_TRANSMQ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) i += scnprintf(buf + i, sz - i, "transmq: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) i += tipc_list_dump(&l->transmq, false, buf + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) if (dqueues & TIPC_DUMP_BACKLOGQ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) i += scnprintf(buf + i, sz - i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) "backlogq: <%u %u %u %u %u>, ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) l->backlog[TIPC_LOW_IMPORTANCE].len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) l->backlog[TIPC_MEDIUM_IMPORTANCE].len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) l->backlog[TIPC_HIGH_IMPORTANCE].len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) l->backlog[TIPC_CRITICAL_IMPORTANCE].len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) l->backlog[TIPC_SYSTEM_IMPORTANCE].len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) i += tipc_list_dump(&l->backlogq, false, buf + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) if (dqueues & TIPC_DUMP_DEFERDQ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) i += scnprintf(buf + i, sz - i, "deferdq: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) i += tipc_list_dump(&l->deferdq, false, buf + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) if (dqueues & TIPC_DUMP_INPUTQ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) i += scnprintf(buf + i, sz - i, "inputq: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) i += tipc_list_dump(l->inputq, false, buf + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) if (dqueues & TIPC_DUMP_WAKEUP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) i += scnprintf(buf + i, sz - i, "wakeup: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) i += tipc_list_dump(&l->wakeupq, false, buf + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) }