diff options
Diffstat (limited to 'net/tipc/node.c')
-rw-r--r-- | net/tipc/node.c | 54 |
1 files changed, 30 insertions, 24 deletions
diff --git a/net/tipc/node.c b/net/tipc/node.c index 27753325e06e..4512e83652b1 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c | |||
@@ -1172,7 +1172,7 @@ msg_full: | |||
1172 | * @list: chain of buffers containing message | 1172 | * @list: chain of buffers containing message |
1173 | * @dnode: address of destination node | 1173 | * @dnode: address of destination node |
1174 | * @selector: a number used for deterministic link selection | 1174 | * @selector: a number used for deterministic link selection |
1175 | * Consumes the buffer chain, except when returning -ELINKCONG | 1175 | * Consumes the buffer chain. |
1176 | * Returns 0 if success, otherwise: -ELINKCONG,-EHOSTUNREACH,-EMSGSIZE,-ENOBUF | 1176 | * Returns 0 if success, otherwise: -ELINKCONG,-EHOSTUNREACH,-EMSGSIZE,-ENOBUF |
1177 | */ | 1177 | */ |
1178 | int tipc_node_xmit(struct net *net, struct sk_buff_head *list, | 1178 | int tipc_node_xmit(struct net *net, struct sk_buff_head *list, |
@@ -1211,10 +1211,10 @@ int tipc_node_xmit(struct net *net, struct sk_buff_head *list, | |||
1211 | spin_unlock_bh(&le->lock); | 1211 | spin_unlock_bh(&le->lock); |
1212 | tipc_node_read_unlock(n); | 1212 | tipc_node_read_unlock(n); |
1213 | 1213 | ||
1214 | if (likely(rc == 0)) | 1214 | if (unlikely(rc == -ENOBUFS)) |
1215 | tipc_bearer_xmit(net, bearer_id, &xmitq, &le->maddr); | ||
1216 | else if (rc == -ENOBUFS) | ||
1217 | tipc_node_link_down(n, bearer_id, false); | 1215 | tipc_node_link_down(n, bearer_id, false); |
1216 | else | ||
1217 | tipc_bearer_xmit(net, bearer_id, &xmitq, &le->maddr); | ||
1218 | 1218 | ||
1219 | tipc_node_put(n); | 1219 | tipc_node_put(n); |
1220 | 1220 | ||
@@ -1226,20 +1226,15 @@ int tipc_node_xmit(struct net *net, struct sk_buff_head *list, | |||
1226 | * messages, which will not be rejected | 1226 | * messages, which will not be rejected |
1227 | * The only exception is datagram messages rerouted after secondary | 1227 | * The only exception is datagram messages rerouted after secondary |
1228 | * lookup, which are rare and safe to dispose of anyway. | 1228 | * lookup, which are rare and safe to dispose of anyway. |
1229 | * TODO: Return real return value, and let callers use | ||
1230 | * tipc_wait_for_sendpkt() where applicable | ||
1231 | */ | 1229 | */ |
1232 | int tipc_node_xmit_skb(struct net *net, struct sk_buff *skb, u32 dnode, | 1230 | int tipc_node_xmit_skb(struct net *net, struct sk_buff *skb, u32 dnode, |
1233 | u32 selector) | 1231 | u32 selector) |
1234 | { | 1232 | { |
1235 | struct sk_buff_head head; | 1233 | struct sk_buff_head head; |
1236 | int rc; | ||
1237 | 1234 | ||
1238 | skb_queue_head_init(&head); | 1235 | skb_queue_head_init(&head); |
1239 | __skb_queue_tail(&head, skb); | 1236 | __skb_queue_tail(&head, skb); |
1240 | rc = tipc_node_xmit(net, &head, dnode, selector); | 1237 | tipc_node_xmit(net, &head, dnode, selector); |
1241 | if (rc == -ELINKCONG) | ||
1242 | kfree_skb(skb); | ||
1243 | return 0; | 1238 | return 0; |
1244 | } | 1239 | } |
1245 | 1240 | ||
@@ -1267,6 +1262,19 @@ void tipc_node_broadcast(struct net *net, struct sk_buff *skb) | |||
1267 | kfree_skb(skb); | 1262 | kfree_skb(skb); |
1268 | } | 1263 | } |
1269 | 1264 | ||
1265 | static void tipc_node_mcast_rcv(struct tipc_node *n) | ||
1266 | { | ||
1267 | struct tipc_bclink_entry *be = &n->bc_entry; | ||
1268 | |||
1269 | /* 'arrvq' is under inputq2's lock protection */ | ||
1270 | spin_lock_bh(&be->inputq2.lock); | ||
1271 | spin_lock_bh(&be->inputq1.lock); | ||
1272 | skb_queue_splice_tail_init(&be->inputq1, &be->arrvq); | ||
1273 | spin_unlock_bh(&be->inputq1.lock); | ||
1274 | spin_unlock_bh(&be->inputq2.lock); | ||
1275 | tipc_sk_mcast_rcv(n->net, &be->arrvq, &be->inputq2); | ||
1276 | } | ||
1277 | |||
1270 | static void tipc_node_bc_sync_rcv(struct tipc_node *n, struct tipc_msg *hdr, | 1278 | static void tipc_node_bc_sync_rcv(struct tipc_node *n, struct tipc_msg *hdr, |
1271 | int bearer_id, struct sk_buff_head *xmitq) | 1279 | int bearer_id, struct sk_buff_head *xmitq) |
1272 | { | 1280 | { |
@@ -1340,15 +1348,8 @@ static void tipc_node_bc_rcv(struct net *net, struct sk_buff *skb, int bearer_id | |||
1340 | if (!skb_queue_empty(&xmitq)) | 1348 | if (!skb_queue_empty(&xmitq)) |
1341 | tipc_bearer_xmit(net, bearer_id, &xmitq, &le->maddr); | 1349 | tipc_bearer_xmit(net, bearer_id, &xmitq, &le->maddr); |
1342 | 1350 | ||
1343 | /* Deliver. 'arrvq' is under inputq2's lock protection */ | 1351 | if (!skb_queue_empty(&be->inputq1)) |
1344 | if (!skb_queue_empty(&be->inputq1)) { | 1352 | tipc_node_mcast_rcv(n); |
1345 | spin_lock_bh(&be->inputq2.lock); | ||
1346 | spin_lock_bh(&be->inputq1.lock); | ||
1347 | skb_queue_splice_tail_init(&be->inputq1, &be->arrvq); | ||
1348 | spin_unlock_bh(&be->inputq1.lock); | ||
1349 | spin_unlock_bh(&be->inputq2.lock); | ||
1350 | tipc_sk_mcast_rcv(net, &be->arrvq, &be->inputq2); | ||
1351 | } | ||
1352 | 1353 | ||
1353 | if (rc & TIPC_LINK_DOWN_EVT) { | 1354 | if (rc & TIPC_LINK_DOWN_EVT) { |
1354 | /* Reception reassembly failure => reset all links to peer */ | 1355 | /* Reception reassembly failure => reset all links to peer */ |
@@ -1504,19 +1505,21 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b) | |||
1504 | { | 1505 | { |
1505 | struct sk_buff_head xmitq; | 1506 | struct sk_buff_head xmitq; |
1506 | struct tipc_node *n; | 1507 | struct tipc_node *n; |
1507 | struct tipc_msg *hdr = buf_msg(skb); | 1508 | struct tipc_msg *hdr; |
1508 | int usr = msg_user(hdr); | ||
1509 | int bearer_id = b->identity; | 1509 | int bearer_id = b->identity; |
1510 | struct tipc_link_entry *le; | 1510 | struct tipc_link_entry *le; |
1511 | u16 bc_ack = msg_bcast_ack(hdr); | ||
1512 | u32 self = tipc_own_addr(net); | 1511 | u32 self = tipc_own_addr(net); |
1513 | int rc = 0; | 1512 | int usr, rc = 0; |
1513 | u16 bc_ack; | ||
1514 | 1514 | ||
1515 | __skb_queue_head_init(&xmitq); | 1515 | __skb_queue_head_init(&xmitq); |
1516 | 1516 | ||
1517 | /* Ensure message is well-formed */ | 1517 | /* Ensure message is well-formed before touching the header */ |
1518 | if (unlikely(!tipc_msg_validate(skb))) | 1518 | if (unlikely(!tipc_msg_validate(skb))) |
1519 | goto discard; | 1519 | goto discard; |
1520 | hdr = buf_msg(skb); | ||
1521 | usr = msg_user(hdr); | ||
1522 | bc_ack = msg_bcast_ack(hdr); | ||
1520 | 1523 | ||
1521 | /* Handle arrival of discovery or broadcast packet */ | 1524 | /* Handle arrival of discovery or broadcast packet */ |
1522 | if (unlikely(msg_non_seq(hdr))) { | 1525 | if (unlikely(msg_non_seq(hdr))) { |
@@ -1575,6 +1578,9 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b) | |||
1575 | if (unlikely(!skb_queue_empty(&n->bc_entry.namedq))) | 1578 | if (unlikely(!skb_queue_empty(&n->bc_entry.namedq))) |
1576 | tipc_named_rcv(net, &n->bc_entry.namedq); | 1579 | tipc_named_rcv(net, &n->bc_entry.namedq); |
1577 | 1580 | ||
1581 | if (unlikely(!skb_queue_empty(&n->bc_entry.inputq1))) | ||
1582 | tipc_node_mcast_rcv(n); | ||
1583 | |||
1578 | if (!skb_queue_empty(&le->inputq)) | 1584 | if (!skb_queue_empty(&le->inputq)) |
1579 | tipc_sk_rcv(net, &le->inputq); | 1585 | tipc_sk_rcv(net, &le->inputq); |
1580 | 1586 | ||