aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
authorJon Paul Maloy <jon.maloy@ericsson.com>2015-05-14 10:46:14 -0400
committerDavid S. Miller <davem@davemloft.net>2015-05-14 12:24:46 -0400
commite4bf4f76962b0869d1048ac6c52a46e7d90eb46f (patch)
treeae6a57dd200627e3a3226652700a4a3d6c3a59b3 /net/tipc
parenta6bf70f792963b32e410e5c3d2f96903265b090a (diff)
tipc: simplify packet sequence number handling
Although the sequence number in the TIPC protocol is 16 bits, we have until now stored it internally as an unsigned 32 bits integer. We got around this by always doing explicit modulo-65535 operations whenever we need to access a sequence number. We now make the incoming and outgoing sequence numbers to unsigned 16-bit integers, and remove the modulo operations where applicable. We also move the arithmetic inline functions for 16 bit integers to core.h, and the function buf_seqno() to msg.h, so they can easily be accessed from anywhere in the code. Reviewed-by: Erik Hugne <erik.hugne@ericsson.com> Reviewed-by: Ying Xue <ying.xue@windriver.com> Signed-off-by: Jon Maloy <jon.maloy@ericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/core.h20
-rw-r--r--net/tipc/link.c37
-rw-r--r--net/tipc/link.h41
-rw-r--r--net/tipc/msg.h17
4 files changed, 53 insertions, 62 deletions
diff --git a/net/tipc/core.h b/net/tipc/core.h
index 53e8146b14e0..0fcf133d5cb7 100644
--- a/net/tipc/core.h
+++ b/net/tipc/core.h
@@ -109,6 +109,26 @@ struct tipc_net {
109 atomic_t subscription_count; 109 atomic_t subscription_count;
110}; 110};
111 111
112static inline u16 mod(u16 x)
113{
114 return x & 0xffffu;
115}
116
117static inline int less_eq(u16 left, u16 right)
118{
119 return mod(right - left) < 32768u;
120}
121
122static inline int more(u16 left, u16 right)
123{
124 return !less_eq(left, right);
125}
126
127static inline int less(u16 left, u16 right)
128{
129 return less_eq(left, right) && (mod(right) != mod(left));
130}
131
112#ifdef CONFIG_SYSCTL 132#ifdef CONFIG_SYSCTL
113int tipc_register_sysctl(void); 133int tipc_register_sysctl(void);
114void tipc_unregister_sysctl(void); 134void tipc_unregister_sysctl(void);
diff --git a/net/tipc/link.c b/net/tipc/link.c
index d71e83d0959b..391a96f0efc7 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -685,9 +685,9 @@ int __tipc_link_xmit(struct net *net, struct tipc_link *link,
685 unsigned int maxwin = link->window; 685 unsigned int maxwin = link->window;
686 unsigned int imp = msg_importance(msg); 686 unsigned int imp = msg_importance(msg);
687 uint mtu = link->mtu; 687 uint mtu = link->mtu;
688 uint ack = mod(link->next_in_no - 1); 688 u16 ack = mod(link->next_in_no - 1);
689 uint seqno = link->next_out_no; 689 u16 seqno = link->next_out_no;
690 uint bc_last_in = link->owner->bclink.last_in; 690 u16 bc_last_in = link->owner->bclink.last_in;
691 struct tipc_media_addr *addr = &link->media_addr; 691 struct tipc_media_addr *addr = &link->media_addr;
692 struct sk_buff_head *transmq = &link->transmq; 692 struct sk_buff_head *transmq = &link->transmq;
693 struct sk_buff_head *backlogq = &link->backlogq; 693 struct sk_buff_head *backlogq = &link->backlogq;
@@ -859,7 +859,7 @@ void tipc_link_push_packets(struct tipc_link *link)
859{ 859{
860 struct sk_buff *skb; 860 struct sk_buff *skb;
861 struct tipc_msg *msg; 861 struct tipc_msg *msg;
862 unsigned int ack = mod(link->next_in_no - 1); 862 u16 ack = mod(link->next_in_no - 1);
863 863
864 while (skb_queue_len(&link->transmq) < link->window) { 864 while (skb_queue_len(&link->transmq) < link->window) {
865 skb = __skb_dequeue(&link->backlogq); 865 skb = __skb_dequeue(&link->backlogq);
@@ -998,13 +998,13 @@ synched:
998static void link_retrieve_defq(struct tipc_link *link, 998static void link_retrieve_defq(struct tipc_link *link,
999 struct sk_buff_head *list) 999 struct sk_buff_head *list)
1000{ 1000{
1001 u32 seq_no; 1001 u16 seq_no;
1002 1002
1003 if (skb_queue_empty(&link->deferdq)) 1003 if (skb_queue_empty(&link->deferdq))
1004 return; 1004 return;
1005 1005
1006 seq_no = buf_seqno(skb_peek(&link->deferdq)); 1006 seq_no = buf_seqno(skb_peek(&link->deferdq));
1007 if (seq_no == mod(link->next_in_no)) 1007 if (seq_no == link->next_in_no)
1008 skb_queue_splice_tail_init(&link->deferdq, list); 1008 skb_queue_splice_tail_init(&link->deferdq, list);
1009} 1009}
1010 1010
@@ -1025,8 +1025,8 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b_ptr)
1025 struct tipc_link *l_ptr; 1025 struct tipc_link *l_ptr;
1026 struct sk_buff *skb1, *tmp; 1026 struct sk_buff *skb1, *tmp;
1027 struct tipc_msg *msg; 1027 struct tipc_msg *msg;
1028 u32 seq_no; 1028 u16 seq_no;
1029 u32 ackd; 1029 u16 ackd;
1030 u32 released; 1030 u32 released;
1031 1031
1032 skb2list(skb, &head); 1032 skb2list(skb, &head);
@@ -1119,7 +1119,7 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b_ptr)
1119 } 1119 }
1120 1120
1121 /* Link is now in state WORKING_WORKING */ 1121 /* Link is now in state WORKING_WORKING */
1122 if (unlikely(seq_no != mod(l_ptr->next_in_no))) { 1122 if (unlikely(seq_no != l_ptr->next_in_no)) {
1123 link_handle_out_of_seq_msg(l_ptr, skb); 1123 link_handle_out_of_seq_msg(l_ptr, skb);
1124 link_retrieve_defq(l_ptr, &head); 1124 link_retrieve_defq(l_ptr, &head);
1125 skb = NULL; 1125 skb = NULL;
@@ -1250,7 +1250,7 @@ static void tipc_link_input(struct tipc_link *link, struct sk_buff *skb)
1250u32 tipc_link_defer_pkt(struct sk_buff_head *list, struct sk_buff *skb) 1250u32 tipc_link_defer_pkt(struct sk_buff_head *list, struct sk_buff *skb)
1251{ 1251{
1252 struct sk_buff *skb1; 1252 struct sk_buff *skb1;
1253 u32 seq_no = buf_seqno(skb); 1253 u16 seq_no = buf_seqno(skb);
1254 1254
1255 /* Empty queue ? */ 1255 /* Empty queue ? */
1256 if (skb_queue_empty(list)) { 1256 if (skb_queue_empty(list)) {
@@ -1266,7 +1266,7 @@ u32 tipc_link_defer_pkt(struct sk_buff_head *list, struct sk_buff *skb)
1266 1266
1267 /* Locate insertion point in queue, then insert; discard if duplicate */ 1267 /* Locate insertion point in queue, then insert; discard if duplicate */
1268 skb_queue_walk(list, skb1) { 1268 skb_queue_walk(list, skb1) {
1269 u32 curr_seqno = buf_seqno(skb1); 1269 u16 curr_seqno = buf_seqno(skb1);
1270 1270
1271 if (seq_no == curr_seqno) { 1271 if (seq_no == curr_seqno) {
1272 kfree_skb(skb); 1272 kfree_skb(skb);
@@ -1301,7 +1301,7 @@ static void link_handle_out_of_seq_msg(struct tipc_link *l_ptr,
1301 * Discard packet if a duplicate; otherwise add it to deferred queue 1301 * Discard packet if a duplicate; otherwise add it to deferred queue
1302 * and notify peer of gap as per protocol specification 1302 * and notify peer of gap as per protocol specification
1303 */ 1303 */
1304 if (less(seq_no, mod(l_ptr->next_in_no))) { 1304 if (less(seq_no, l_ptr->next_in_no)) {
1305 l_ptr->stats.duplicates++; 1305 l_ptr->stats.duplicates++;
1306 kfree_skb(buf); 1306 kfree_skb(buf);
1307 return; 1307 return;
@@ -1326,6 +1326,7 @@ void tipc_link_proto_xmit(struct tipc_link *l_ptr, u32 msg_typ, int probe_msg,
1326 struct tipc_msg *msg = l_ptr->pmsg; 1326 struct tipc_msg *msg = l_ptr->pmsg;
1327 u32 msg_size = sizeof(l_ptr->proto_msg); 1327 u32 msg_size = sizeof(l_ptr->proto_msg);
1328 int r_flag; 1328 int r_flag;
1329 u16 last_rcv;
1329 1330
1330 /* Don't send protocol message during link failover */ 1331 /* Don't send protocol message during link failover */
1331 if (l_ptr->flags & LINK_FAILINGOVER) 1332 if (l_ptr->flags & LINK_FAILINGOVER)
@@ -1342,7 +1343,7 @@ void tipc_link_proto_xmit(struct tipc_link *l_ptr, u32 msg_typ, int probe_msg,
1342 msg_set_last_bcast(msg, tipc_bclink_get_last_sent(l_ptr->owner->net)); 1343 msg_set_last_bcast(msg, tipc_bclink_get_last_sent(l_ptr->owner->net));
1343 1344
1344 if (msg_typ == STATE_MSG) { 1345 if (msg_typ == STATE_MSG) {
1345 u32 next_sent = mod(l_ptr->next_out_no); 1346 u16 next_sent = l_ptr->next_out_no;
1346 1347
1347 if (!tipc_link_is_up(l_ptr)) 1348 if (!tipc_link_is_up(l_ptr))
1348 return; 1349 return;
@@ -1350,8 +1351,8 @@ void tipc_link_proto_xmit(struct tipc_link *l_ptr, u32 msg_typ, int probe_msg,
1350 next_sent = buf_seqno(skb_peek(&l_ptr->backlogq)); 1351 next_sent = buf_seqno(skb_peek(&l_ptr->backlogq));
1351 msg_set_next_sent(msg, next_sent); 1352 msg_set_next_sent(msg, next_sent);
1352 if (!skb_queue_empty(&l_ptr->deferdq)) { 1353 if (!skb_queue_empty(&l_ptr->deferdq)) {
1353 u32 rec = buf_seqno(skb_peek(&l_ptr->deferdq)); 1354 last_rcv = buf_seqno(skb_peek(&l_ptr->deferdq));
1354 gap = mod(rec - mod(l_ptr->next_in_no)); 1355 gap = mod(last_rcv - l_ptr->next_in_no);
1355 } 1356 }
1356 msg_set_seq_gap(msg, gap); 1357 msg_set_seq_gap(msg, gap);
1357 if (gap) 1358 if (gap)
@@ -1485,10 +1486,8 @@ static void tipc_link_proto_rcv(struct tipc_link *l_ptr,
1485 if (link_reset_unknown(l_ptr)) 1486 if (link_reset_unknown(l_ptr))
1486 break; 1487 break;
1487 1488
1488 if (less_eq(mod(l_ptr->next_in_no), msg_next_sent(msg))) { 1489 if (less_eq(l_ptr->next_in_no, msg_next_sent(msg)))
1489 rec_gap = mod(msg_next_sent(msg) - 1490 rec_gap = mod(msg_next_sent(msg) - l_ptr->next_in_no);
1490 mod(l_ptr->next_in_no));
1491 }
1492 1491
1493 if (msg_probe(msg)) 1492 if (msg_probe(msg))
1494 l_ptr->stats.recv_probes++; 1493 l_ptr->stats.recv_probes++;
diff --git a/net/tipc/link.h b/net/tipc/link.h
index dc27bb62b1f5..a65770bf647c 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -151,7 +151,7 @@ struct tipc_link {
151 151
152 /* Management and link supervision data */ 152 /* Management and link supervision data */
153 unsigned int flags; 153 unsigned int flags;
154 u32 checkpoint; 154 u16 checkpoint;
155 u32 peer_session; 155 u32 peer_session;
156 u32 peer_bearer_id; 156 u32 peer_bearer_id;
157 u32 bearer_id; 157 u32 bearer_id;
@@ -185,13 +185,13 @@ struct tipc_link {
185 u16 len; 185 u16 len;
186 u16 limit; 186 u16 limit;
187 } backlog[5]; 187 } backlog[5];
188 u32 next_out_no; 188 u16 next_out_no;
189 u16 last_retransmitted;
189 u32 window; 190 u32 window;
190 u32 last_retransmitted;
191 u32 stale_count; 191 u32 stale_count;
192 192
193 /* Reception */ 193 /* Reception */
194 u32 next_in_no; 194 u16 next_in_no;
195 u32 rcv_unacked; 195 u32 rcv_unacked;
196 struct sk_buff_head deferdq; 196 struct sk_buff_head deferdq;
197 struct sk_buff_head inputq; 197 struct sk_buff_head inputq;
@@ -245,39 +245,6 @@ int tipc_nl_link_reset_stats(struct sk_buff *skb, struct genl_info *info);
245int tipc_nl_parse_link_prop(struct nlattr *prop, struct nlattr *props[]); 245int tipc_nl_parse_link_prop(struct nlattr *prop, struct nlattr *props[]);
246void link_prepare_wakeup(struct tipc_link *l); 246void link_prepare_wakeup(struct tipc_link *l);
247 247
248/*
249 * Link sequence number manipulation routines (uses modulo 2**16 arithmetic)
250 */
251static inline u32 buf_seqno(struct sk_buff *buf)
252{
253 return msg_seqno(buf_msg(buf));
254}
255
256static inline u32 mod(u32 x)
257{
258 return x & 0xffffu;
259}
260
261static inline int less_eq(u32 left, u32 right)
262{
263 return mod(right - left) < 32768u;
264}
265
266static inline int more(u32 left, u32 right)
267{
268 return !less_eq(left, right);
269}
270
271static inline int less(u32 left, u32 right)
272{
273 return less_eq(left, right) && (mod(right) != mod(left));
274}
275
276static inline u32 lesser(u32 left, u32 right)
277{
278 return less_eq(left, right) ? left : right;
279}
280
281static inline u32 link_own_addr(struct tipc_link *l) 248static inline u32 link_own_addr(struct tipc_link *l)
282{ 249{
283 return msg_prevnode(l->pmsg); 250 return msg_prevnode(l->pmsg);
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index e1d3595e2ee9..6ca2366f3a53 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -313,12 +313,12 @@ static inline void msg_set_lookup_scope(struct tipc_msg *m, u32 n)
313 msg_set_bits(m, 1, 19, 0x3, n); 313 msg_set_bits(m, 1, 19, 0x3, n);
314} 314}
315 315
316static inline u32 msg_bcast_ack(struct tipc_msg *m) 316static inline u16 msg_bcast_ack(struct tipc_msg *m)
317{ 317{
318 return msg_bits(m, 1, 0, 0xffff); 318 return msg_bits(m, 1, 0, 0xffff);
319} 319}
320 320
321static inline void msg_set_bcast_ack(struct tipc_msg *m, u32 n) 321static inline void msg_set_bcast_ack(struct tipc_msg *m, u16 n)
322{ 322{
323 msg_set_bits(m, 1, 0, 0xffff, n); 323 msg_set_bits(m, 1, 0, 0xffff, n);
324} 324}
@@ -327,22 +327,22 @@ static inline void msg_set_bcast_ack(struct tipc_msg *m, u32 n)
327/* 327/*
328 * Word 2 328 * Word 2
329 */ 329 */
330static inline u32 msg_ack(struct tipc_msg *m) 330static inline u16 msg_ack(struct tipc_msg *m)
331{ 331{
332 return msg_bits(m, 2, 16, 0xffff); 332 return msg_bits(m, 2, 16, 0xffff);
333} 333}
334 334
335static inline void msg_set_ack(struct tipc_msg *m, u32 n) 335static inline void msg_set_ack(struct tipc_msg *m, u16 n)
336{ 336{
337 msg_set_bits(m, 2, 16, 0xffff, n); 337 msg_set_bits(m, 2, 16, 0xffff, n);
338} 338}
339 339
340static inline u32 msg_seqno(struct tipc_msg *m) 340static inline u16 msg_seqno(struct tipc_msg *m)
341{ 341{
342 return msg_bits(m, 2, 0, 0xffff); 342 return msg_bits(m, 2, 0, 0xffff);
343} 343}
344 344
345static inline void msg_set_seqno(struct tipc_msg *m, u32 n) 345static inline void msg_set_seqno(struct tipc_msg *m, u16 n)
346{ 346{
347 msg_set_bits(m, 2, 0, 0xffff, n); 347 msg_set_bits(m, 2, 0, 0xffff, n);
348} 348}
@@ -782,6 +782,11 @@ bool tipc_msg_lookup_dest(struct net *net, struct sk_buff *skb, u32 *dnode,
782 int *err); 782 int *err);
783struct sk_buff *tipc_msg_reassemble(struct sk_buff_head *list); 783struct sk_buff *tipc_msg_reassemble(struct sk_buff_head *list);
784 784
785static inline u16 buf_seqno(struct sk_buff *skb)
786{
787 return msg_seqno(buf_msg(skb));
788}
789
785/* tipc_skb_peek(): peek and reserve first buffer in list 790/* tipc_skb_peek(): peek and reserve first buffer in list
786 * @list: list to be peeked in 791 * @list: list to be peeked in
787 * Returns pointer to first buffer in list, if any 792 * Returns pointer to first buffer in list, if any