Skip to content

Commit 64ac5f5

Browse files
Jon Maloydavem330
authored andcommitted
tipc: refactor function filter_rcv()
In the following commits we will need to handle multiple incoming and rejected/returned buffers in the function socket.c::filter_rcv(). As a preparation for this, we generalize the function by handling buffer queues instead of individual buffers. We also introduce a help function tipc_skb_reject(), and rename filter_rcv() to tipc_sk_filter_rcv() in line with other functions in socket.c. Signed-off-by: Jon Maloy <[email protected]> Acked-by: Ying Xue <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 38077b8 commit 64ac5f5

File tree

3 files changed

+89
-81
lines changed

3 files changed

+89
-81
lines changed

net/tipc/msg.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,3 +666,10 @@ void __tipc_skb_queue_sorted(struct sk_buff_head *list, u16 seqno,
666666
}
667667
kfree_skb(skb);
668668
}
669+
670+
void tipc_skb_reject(struct net *net, int err, struct sk_buff *skb,
671+
struct sk_buff_head *xmitq)
672+
{
673+
if (tipc_msg_reverse(tipc_own_addr(net), &skb, err))
674+
__skb_queue_tail(xmitq, skb);
675+
}

net/tipc/msg.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -819,6 +819,8 @@ static inline bool msg_is_reset(struct tipc_msg *hdr)
819819
struct sk_buff *tipc_buf_acquire(u32 size, gfp_t gfp);
820820
bool tipc_msg_validate(struct sk_buff *skb);
821821
bool tipc_msg_reverse(u32 own_addr, struct sk_buff **skb, int err);
822+
void tipc_skb_reject(struct net *net, int err, struct sk_buff *skb,
823+
struct sk_buff_head *xmitq);
822824
void tipc_msg_init(u32 own_addr, struct tipc_msg *m, u32 user, u32 type,
823825
u32 hsize, u32 destnode);
824826
struct sk_buff *tipc_msg_create(uint user, uint type, uint hdr_sz,

net/tipc/socket.c

Lines changed: 80 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ struct tipc_sock {
111111
struct rcu_head rcu;
112112
};
113113

114-
static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb);
114+
static int tipc_sk_backlog_rcv(struct sock *sk, struct sk_buff *skb);
115115
static void tipc_data_ready(struct sock *sk);
116116
static void tipc_write_space(struct sock *sk);
117117
static void tipc_sock_destruct(struct sock *sk);
@@ -453,7 +453,7 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
453453
msg_set_origport(msg, tsk->portid);
454454
setup_timer(&sk->sk_timer, tipc_sk_timeout, (unsigned long)tsk);
455455
sk->sk_shutdown = 0;
456-
sk->sk_backlog_rcv = tipc_backlog_rcv;
456+
sk->sk_backlog_rcv = tipc_sk_backlog_rcv;
457457
sk->sk_rcvbuf = sysctl_tipc_rmem[1];
458458
sk->sk_data_ready = tipc_data_ready;
459459
sk->sk_write_space = tipc_write_space;
@@ -850,16 +850,16 @@ void tipc_sk_mcast_rcv(struct net *net, struct sk_buff_head *arrvq,
850850
}
851851

852852
/**
853-
* tipc_sk_proto_rcv - receive a connection mng protocol message
853+
* tipc_sk_conn_proto_rcv - receive a connection mng protocol message
854854
* @tsk: receiving socket
855855
* @skb: pointer to message buffer.
856856
*/
857-
static void tipc_sk_proto_rcv(struct tipc_sock *tsk, struct sk_buff *skb,
858-
struct sk_buff_head *xmitq)
857+
static void tipc_sk_conn_proto_rcv(struct tipc_sock *tsk, struct sk_buff *skb,
858+
struct sk_buff_head *xmitq)
859859
{
860-
struct sock *sk = &tsk->sk;
861-
u32 onode = tsk_own_node(tsk);
862860
struct tipc_msg *hdr = buf_msg(skb);
861+
u32 onode = tsk_own_node(tsk);
862+
struct sock *sk = &tsk->sk;
863863
int mtyp = msg_type(hdr);
864864
bool conn_cong;
865865

@@ -1536,14 +1536,41 @@ static void tipc_sock_destruct(struct sock *sk)
15361536
__skb_queue_purge(&sk->sk_receive_queue);
15371537
}
15381538

1539+
static void tipc_sk_proto_rcv(struct sock *sk,
1540+
struct sk_buff_head *inputq,
1541+
struct sk_buff_head *xmitq)
1542+
{
1543+
struct sk_buff *skb = __skb_dequeue(inputq);
1544+
struct tipc_sock *tsk = tipc_sk(sk);
1545+
struct tipc_msg *hdr = buf_msg(skb);
1546+
1547+
switch (msg_user(hdr)) {
1548+
case CONN_MANAGER:
1549+
tipc_sk_conn_proto_rcv(tsk, skb, xmitq);
1550+
return;
1551+
case SOCK_WAKEUP:
1552+
u32_del(&tsk->cong_links, msg_orignode(hdr));
1553+
tsk->cong_link_cnt--;
1554+
sk->sk_write_space(sk);
1555+
break;
1556+
case TOP_SRV:
1557+
tipc_sk_top_evt(tsk, (void *)msg_data(hdr));
1558+
break;
1559+
default:
1560+
break;
1561+
}
1562+
1563+
kfree_skb(skb);
1564+
}
1565+
15391566
/**
1540-
* filter_connect - Handle all incoming messages for a connection-based socket
1567+
* tipc_filter_connect - Handle incoming message for a connection-based socket
15411568
* @tsk: TIPC socket
15421569
* @skb: pointer to message buffer. Set to NULL if buffer is consumed
15431570
*
15441571
* Returns true if everything ok, false otherwise
15451572
*/
1546-
static bool filter_connect(struct tipc_sock *tsk, struct sk_buff *skb)
1573+
static bool tipc_sk_filter_connect(struct tipc_sock *tsk, struct sk_buff *skb)
15471574
{
15481575
struct sock *sk = &tsk->sk;
15491576
struct net *net = sock_net(sk);
@@ -1657,7 +1684,7 @@ static unsigned int rcvbuf_limit(struct sock *sk, struct sk_buff *skb)
16571684
}
16581685

16591686
/**
1660-
* filter_rcv - validate incoming message
1687+
* tipc_sk_filter_rcv - validate incoming message
16611688
* @sk: socket
16621689
* @skb: pointer to message.
16631690
*
@@ -1666,103 +1693,75 @@ static unsigned int rcvbuf_limit(struct sock *sk, struct sk_buff *skb)
16661693
*
16671694
* Called with socket lock already taken
16681695
*
1669-
* Returns true if message was added to socket receive queue, otherwise false
16701696
*/
1671-
static bool filter_rcv(struct sock *sk, struct sk_buff *skb,
1672-
struct sk_buff_head *xmitq)
1697+
static void tipc_sk_filter_rcv(struct sock *sk, struct sk_buff *skb,
1698+
struct sk_buff_head *xmitq)
16731699
{
1700+
bool sk_conn = !tipc_sk_type_connectionless(sk);
16741701
struct tipc_sock *tsk = tipc_sk(sk);
16751702
struct tipc_msg *hdr = buf_msg(skb);
1676-
unsigned int limit = rcvbuf_limit(sk, skb);
1677-
int err = TIPC_OK;
1703+
struct net *net = sock_net(sk);
1704+
struct sk_buff_head inputq;
1705+
int limit, err = TIPC_OK;
16781706

1679-
if (unlikely(!msg_isdata(hdr))) {
1680-
switch (msg_user(hdr)) {
1681-
case CONN_MANAGER:
1682-
tipc_sk_proto_rcv(tsk, skb, xmitq);
1683-
return false;
1684-
case SOCK_WAKEUP:
1685-
u32_del(&tsk->cong_links, msg_orignode(hdr));
1686-
tsk->cong_link_cnt--;
1687-
sk->sk_write_space(sk);
1688-
break;
1689-
case TOP_SRV:
1690-
tipc_sk_top_evt(tsk, (void *)msg_data(hdr));
1691-
break;
1692-
default:
1693-
break;
1694-
}
1695-
kfree_skb(skb);
1696-
return false;
1697-
}
1707+
TIPC_SKB_CB(skb)->bytes_read = 0;
1708+
__skb_queue_head_init(&inputq);
1709+
__skb_queue_tail(&inputq, skb);
16981710

1699-
/* Drop if illegal message type */
1700-
if (unlikely(msg_type(hdr) > TIPC_DIRECT_MSG)) {
1701-
kfree_skb(skb);
1702-
return false;
1703-
}
1711+
if (unlikely(!msg_isdata(hdr)))
1712+
tipc_sk_proto_rcv(sk, &inputq, xmitq);
1713+
else if (unlikely(msg_type(hdr) > TIPC_DIRECT_MSG))
1714+
return kfree_skb(skb);
17041715

1705-
/* Reject if wrong message type for current socket state */
1706-
if (tipc_sk_type_connectionless(sk)) {
1707-
if (msg_connected(hdr)) {
1716+
/* Validate and add to receive buffer if there is space */
1717+
while ((skb = __skb_dequeue(&inputq))) {
1718+
hdr = buf_msg(skb);
1719+
limit = rcvbuf_limit(sk, skb);
1720+
if ((sk_conn && !tipc_sk_filter_connect(tsk, skb)) ||
1721+
(!sk_conn && msg_connected(hdr)))
17081722
err = TIPC_ERR_NO_PORT;
1709-
goto reject;
1710-
}
1711-
} else if (unlikely(!filter_connect(tsk, skb))) {
1712-
err = TIPC_ERR_NO_PORT;
1713-
goto reject;
1714-
}
1723+
else if (sk_rmem_alloc_get(sk) + skb->truesize >= limit)
1724+
err = TIPC_ERR_OVERLOAD;
17151725

1716-
/* Reject message if there isn't room to queue it */
1717-
if (unlikely(sk_rmem_alloc_get(sk) + skb->truesize >= limit)) {
1718-
err = TIPC_ERR_OVERLOAD;
1719-
goto reject;
1726+
if (unlikely(err)) {
1727+
tipc_skb_reject(net, err, skb, xmitq);
1728+
err = TIPC_OK;
1729+
continue;
1730+
}
1731+
__skb_queue_tail(&sk->sk_receive_queue, skb);
1732+
skb_set_owner_r(skb, sk);
1733+
sk->sk_data_ready(sk);
17201734
}
1721-
1722-
/* Enqueue message */
1723-
TIPC_SKB_CB(skb)->bytes_read = 0;
1724-
__skb_queue_tail(&sk->sk_receive_queue, skb);
1725-
skb_set_owner_r(skb, sk);
1726-
1727-
sk->sk_data_ready(sk);
1728-
return true;
1729-
1730-
reject:
1731-
if (tipc_msg_reverse(tsk_own_node(tsk), &skb, err))
1732-
__skb_queue_tail(xmitq, skb);
1733-
return false;
17341735
}
17351736

17361737
/**
1737-
* tipc_backlog_rcv - handle incoming message from backlog queue
1738+
* tipc_sk_backlog_rcv - handle incoming message from backlog queue
17381739
* @sk: socket
17391740
* @skb: message
17401741
*
17411742
* Caller must hold socket lock
17421743
*
17431744
* Returns 0
17441745
*/
1745-
static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb)
1746+
static int tipc_sk_backlog_rcv(struct sock *sk, struct sk_buff *skb)
17461747
{
1747-
unsigned int truesize = skb->truesize;
1748+
unsigned int before = sk_rmem_alloc_get(sk);
17481749
struct sk_buff_head xmitq;
17491750
u32 dnode, selector;
1751+
unsigned int added;
17501752

17511753
__skb_queue_head_init(&xmitq);
17521754

1753-
if (likely(filter_rcv(sk, skb, &xmitq))) {
1754-
atomic_add(truesize, &tipc_sk(sk)->dupl_rcvcnt);
1755-
return 0;
1756-
}
1757-
1758-
if (skb_queue_empty(&xmitq))
1759-
return 0;
1755+
tipc_sk_filter_rcv(sk, skb, &xmitq);
1756+
added = sk_rmem_alloc_get(sk) - before;
1757+
atomic_add(added, &tipc_sk(sk)->dupl_rcvcnt);
17601758

1761-
/* Send response/rejected message */
1762-
skb = __skb_dequeue(&xmitq);
1763-
dnode = msg_destnode(buf_msg(skb));
1764-
selector = msg_origport(buf_msg(skb));
1765-
tipc_node_xmit_skb(sock_net(sk), skb, dnode, selector);
1759+
/* Send pending response/rejected messages, if any */
1760+
while ((skb = __skb_dequeue(&xmitq))) {
1761+
selector = msg_origport(buf_msg(skb));
1762+
dnode = msg_destnode(buf_msg(skb));
1763+
tipc_node_xmit_skb(sock_net(sk), skb, dnode, selector);
1764+
}
17661765
return 0;
17671766
}
17681767

@@ -1794,7 +1793,7 @@ static void tipc_sk_enqueue(struct sk_buff_head *inputq, struct sock *sk,
17941793

17951794
/* Add message directly to receive queue if possible */
17961795
if (!sock_owned_by_user(sk)) {
1797-
filter_rcv(sk, skb, xmitq);
1796+
tipc_sk_filter_rcv(sk, skb, xmitq);
17981797
continue;
17991798
}
18001799

0 commit comments

Comments
 (0)