Skip to content

Commit 0ff9275

Browse files
committed
Merge branch 'tipc-next'
Jon Maloy says: ==================== tipc: new unicast transmission code As a step towards making the data transmission code more maintainable and performant, we introduce a number of new functions, both for building, sending and rejecting messages. The new functions will eventually be used for alla data transmission, user data unicast, service internal messaging, and multicast/broadcast. We start with this series, where we introduce the functions, and let user data unicast and the internal connection protocol use them. The remaining users will come in a later series. There are only minor changes to data structures, and no protocol changes, so the older functions can still be used in parallel for some time. Until the old functions are removed, we use temporary names for the new functions, such as tipc_build_msg2, tipc_link_xmit2. It should be noted that the first two commits are unrelated to the rest of the series. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents f5b2650 + 6012052 commit 0ff9275

File tree

13 files changed

+827
-888
lines changed

13 files changed

+827
-888
lines changed

net/tipc/link.c

Lines changed: 158 additions & 259 deletions
Large diffs are not rendered by default.

net/tipc/link.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,10 @@ void tipc_link_reset_all(struct tipc_node *node);
227227
void tipc_link_reset(struct tipc_link *l_ptr);
228228
void tipc_link_reset_list(unsigned int bearer_id);
229229
int tipc_link_xmit(struct sk_buff *buf, u32 dest, u32 selector);
230+
int tipc_link_xmit2(struct sk_buff *buf, u32 dest, u32 selector);
230231
void tipc_link_names_xmit(struct list_head *message_list, u32 dest);
231232
int __tipc_link_xmit(struct tipc_link *l_ptr, struct sk_buff *buf);
233+
int __tipc_link_xmit2(struct tipc_link *link, struct sk_buff *buf);
232234
int tipc_link_send_buf(struct tipc_link *l_ptr, struct sk_buff *buf);
233235
u32 tipc_link_get_max_pkt(u32 dest, u32 selector);
234236
int tipc_link_iovec_xmit_fast(struct tipc_port *sender,

net/tipc/msg.c

Lines changed: 271 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,21 +36,16 @@
3636

3737
#include "core.h"
3838
#include "msg.h"
39+
#include "addr.h"
40+
#include "name_table.h"
3941

40-
u32 tipc_msg_tot_importance(struct tipc_msg *m)
42+
#define MAX_FORWARD_SIZE 1024
43+
44+
static unsigned int align(unsigned int i)
4145
{
42-
if (likely(msg_isdata(m))) {
43-
if (likely(msg_orignode(m) == tipc_own_addr))
44-
return msg_importance(m);
45-
return msg_importance(m) + 4;
46-
}
47-
if ((msg_user(m) == MSG_FRAGMENTER) &&
48-
(msg_type(m) == FIRST_FRAGMENT))
49-
return msg_importance(msg_get_wrapped(m));
50-
return msg_importance(m);
46+
return (i + 3) & ~3u;
5147
}
5248

53-
5449
void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, u32 hsize,
5550
u32 destnode)
5651
{
@@ -152,3 +147,268 @@ int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf)
152147
kfree_skb(*buf);
153148
return 0;
154149
}
150+
151+
152+
/**
153+
* tipc_msg_build2 - create buffer chain containing specified header and data
154+
* @mhdr: Message header, to be prepended to data
155+
* @iov: User data
156+
* @offset: Posision in iov to start copying from
157+
* @dsz: Total length of user data
158+
* @pktmax: Max packet size that can be used
159+
* @chain: Buffer or chain of buffers to be returned to caller
160+
* Returns message data size or errno: -ENOMEM, -EFAULT
161+
*/
162+
int tipc_msg_build2(struct tipc_msg *mhdr, struct iovec const *iov,
163+
int offset, int dsz, int pktmax , struct sk_buff **chain)
164+
{
165+
int mhsz = msg_hdr_sz(mhdr);
166+
int msz = mhsz + dsz;
167+
int pktno = 1;
168+
int pktsz;
169+
int pktrem = pktmax;
170+
int drem = dsz;
171+
struct tipc_msg pkthdr;
172+
struct sk_buff *buf, *prev;
173+
char *pktpos;
174+
int rc;
175+
176+
msg_set_size(mhdr, msz);
177+
178+
/* No fragmentation needed? */
179+
if (likely(msz <= pktmax)) {
180+
buf = tipc_buf_acquire(msz);
181+
*chain = buf;
182+
if (unlikely(!buf))
183+
return -ENOMEM;
184+
skb_copy_to_linear_data(buf, mhdr, mhsz);
185+
pktpos = buf->data + mhsz;
186+
if (!dsz || !memcpy_fromiovecend(pktpos, iov, offset, dsz))
187+
return dsz;
188+
rc = -EFAULT;
189+
goto error;
190+
}
191+
192+
/* Prepare reusable fragment header */
193+
tipc_msg_init(&pkthdr, MSG_FRAGMENTER, FIRST_FRAGMENT,
194+
INT_H_SIZE, msg_destnode(mhdr));
195+
msg_set_size(&pkthdr, pktmax);
196+
msg_set_fragm_no(&pkthdr, pktno);
197+
198+
/* Prepare first fragment */
199+
*chain = buf = tipc_buf_acquire(pktmax);
200+
if (!buf)
201+
return -ENOMEM;
202+
pktpos = buf->data;
203+
skb_copy_to_linear_data(buf, &pkthdr, INT_H_SIZE);
204+
pktpos += INT_H_SIZE;
205+
pktrem -= INT_H_SIZE;
206+
skb_copy_to_linear_data_offset(buf, INT_H_SIZE, mhdr, mhsz);
207+
pktpos += mhsz;
208+
pktrem -= mhsz;
209+
210+
do {
211+
if (drem < pktrem)
212+
pktrem = drem;
213+
214+
if (memcpy_fromiovecend(pktpos, iov, offset, pktrem)) {
215+
rc = -EFAULT;
216+
goto error;
217+
}
218+
drem -= pktrem;
219+
offset += pktrem;
220+
221+
if (!drem)
222+
break;
223+
224+
/* Prepare new fragment: */
225+
if (drem < (pktmax - INT_H_SIZE))
226+
pktsz = drem + INT_H_SIZE;
227+
else
228+
pktsz = pktmax;
229+
prev = buf;
230+
buf = tipc_buf_acquire(pktsz);
231+
if (!buf) {
232+
rc = -ENOMEM;
233+
goto error;
234+
}
235+
prev->next = buf;
236+
msg_set_type(&pkthdr, FRAGMENT);
237+
msg_set_size(&pkthdr, pktsz);
238+
msg_set_fragm_no(&pkthdr, ++pktno);
239+
skb_copy_to_linear_data(buf, &pkthdr, INT_H_SIZE);
240+
pktpos = buf->data + INT_H_SIZE;
241+
pktrem = pktsz - INT_H_SIZE;
242+
243+
} while (1);
244+
245+
msg_set_type(buf_msg(buf), LAST_FRAGMENT);
246+
return dsz;
247+
error:
248+
kfree_skb_list(*chain);
249+
*chain = NULL;
250+
return rc;
251+
}
252+
253+
/**
254+
* tipc_msg_bundle(): Append contents of a buffer to tail of an existing one
255+
* @bbuf: the existing buffer ("bundle")
256+
* @buf: buffer to be appended
257+
* @mtu: max allowable size for the bundle buffer
258+
* Consumes buffer if successful
259+
* Returns true if bundling could be performed, otherwise false
260+
*/
261+
bool tipc_msg_bundle(struct sk_buff *bbuf, struct sk_buff *buf, u32 mtu)
262+
{
263+
struct tipc_msg *bmsg = buf_msg(bbuf);
264+
struct tipc_msg *msg = buf_msg(buf);
265+
unsigned int bsz = msg_size(bmsg);
266+
unsigned int msz = msg_size(msg);
267+
u32 start = align(bsz);
268+
u32 max = mtu - INT_H_SIZE;
269+
u32 pad = start - bsz;
270+
271+
if (likely(msg_user(msg) == MSG_FRAGMENTER))
272+
return false;
273+
if (unlikely(msg_user(msg) == CHANGEOVER_PROTOCOL))
274+
return false;
275+
if (unlikely(msg_user(msg) == BCAST_PROTOCOL))
276+
return false;
277+
if (likely(msg_user(bmsg) != MSG_BUNDLER))
278+
return false;
279+
if (likely(msg_type(bmsg) != BUNDLE_OPEN))
280+
return false;
281+
if (unlikely(skb_tailroom(bbuf) < (pad + msz)))
282+
return false;
283+
if (unlikely(max < (start + msz)))
284+
return false;
285+
286+
skb_put(bbuf, pad + msz);
287+
skb_copy_to_linear_data_offset(bbuf, start, buf->data, msz);
288+
msg_set_size(bmsg, start + msz);
289+
msg_set_msgcnt(bmsg, msg_msgcnt(bmsg) + 1);
290+
bbuf->next = buf->next;
291+
kfree_skb(buf);
292+
return true;
293+
}
294+
295+
/**
296+
* tipc_msg_make_bundle(): Create bundle buf and append message to its tail
297+
* @buf: buffer to be appended and replaced
298+
* @mtu: max allowable size for the bundle buffer, inclusive header
299+
* @dnode: destination node for message. (Not always present in header)
300+
* Replaces buffer if successful
301+
* Returns true if sucess, otherwise false
302+
*/
303+
bool tipc_msg_make_bundle(struct sk_buff **buf, u32 mtu, u32 dnode)
304+
{
305+
struct sk_buff *bbuf;
306+
struct tipc_msg *bmsg;
307+
struct tipc_msg *msg = buf_msg(*buf);
308+
u32 msz = msg_size(msg);
309+
u32 max = mtu - INT_H_SIZE;
310+
311+
if (msg_user(msg) == MSG_FRAGMENTER)
312+
return false;
313+
if (msg_user(msg) == CHANGEOVER_PROTOCOL)
314+
return false;
315+
if (msg_user(msg) == BCAST_PROTOCOL)
316+
return false;
317+
if (msz > (max / 2))
318+
return false;
319+
320+
bbuf = tipc_buf_acquire(max);
321+
if (!bbuf)
322+
return false;
323+
324+
skb_trim(bbuf, INT_H_SIZE);
325+
bmsg = buf_msg(bbuf);
326+
tipc_msg_init(bmsg, MSG_BUNDLER, BUNDLE_OPEN, INT_H_SIZE, dnode);
327+
msg_set_seqno(bmsg, msg_seqno(msg));
328+
msg_set_ack(bmsg, msg_ack(msg));
329+
msg_set_bcast_ack(bmsg, msg_bcast_ack(msg));
330+
bbuf->next = (*buf)->next;
331+
tipc_msg_bundle(bbuf, *buf, mtu);
332+
*buf = bbuf;
333+
return true;
334+
}
335+
336+
/**
337+
* tipc_msg_reverse(): swap source and destination addresses and add error code
338+
* @buf: buffer containing message to be reversed
339+
* @dnode: return value: node where to send message after reversal
340+
* @err: error code to be set in message
341+
* Consumes buffer if failure
342+
* Returns true if success, otherwise false
343+
*/
344+
bool tipc_msg_reverse(struct sk_buff *buf, u32 *dnode, int err)
345+
{
346+
struct tipc_msg *msg = buf_msg(buf);
347+
uint imp = msg_importance(msg);
348+
struct tipc_msg ohdr;
349+
uint rdsz = min_t(uint, msg_data_sz(msg), MAX_FORWARD_SIZE);
350+
351+
if (skb_linearize(buf))
352+
goto exit;
353+
if (msg_dest_droppable(msg))
354+
goto exit;
355+
if (msg_errcode(msg))
356+
goto exit;
357+
358+
memcpy(&ohdr, msg, msg_hdr_sz(msg));
359+
imp = min_t(uint, imp + 1, TIPC_CRITICAL_IMPORTANCE);
360+
if (msg_isdata(msg))
361+
msg_set_importance(msg, imp);
362+
msg_set_errcode(msg, err);
363+
msg_set_origport(msg, msg_destport(&ohdr));
364+
msg_set_destport(msg, msg_origport(&ohdr));
365+
msg_set_prevnode(msg, tipc_own_addr);
366+
if (!msg_short(msg)) {
367+
msg_set_orignode(msg, msg_destnode(&ohdr));
368+
msg_set_destnode(msg, msg_orignode(&ohdr));
369+
}
370+
msg_set_size(msg, msg_hdr_sz(msg) + rdsz);
371+
skb_trim(buf, msg_size(msg));
372+
skb_orphan(buf);
373+
*dnode = msg_orignode(&ohdr);
374+
return true;
375+
exit:
376+
kfree_skb(buf);
377+
return false;
378+
}
379+
380+
/**
381+
* tipc_msg_eval: determine fate of message that found no destination
382+
* @buf: the buffer containing the message.
383+
* @dnode: return value: next-hop node, if message to be forwarded
384+
* @err: error code to use, if message to be rejected
385+
*
386+
* Does not consume buffer
387+
* Returns 0 (TIPC_OK) if message ok and we can try again, -TIPC error
388+
* code if message to be rejected
389+
*/
390+
int tipc_msg_eval(struct sk_buff *buf, u32 *dnode)
391+
{
392+
struct tipc_msg *msg = buf_msg(buf);
393+
u32 dport;
394+
395+
if (msg_type(msg) != TIPC_NAMED_MSG)
396+
return -TIPC_ERR_NO_PORT;
397+
if (skb_linearize(buf))
398+
return -TIPC_ERR_NO_NAME;
399+
if (msg_data_sz(msg) > MAX_FORWARD_SIZE)
400+
return -TIPC_ERR_NO_NAME;
401+
if (msg_reroute_cnt(msg) > 0)
402+
return -TIPC_ERR_NO_NAME;
403+
404+
*dnode = addr_domain(msg_lookup_scope(msg));
405+
dport = tipc_nametbl_translate(msg_nametype(msg),
406+
msg_nameinst(msg),
407+
dnode);
408+
if (!dport)
409+
return -TIPC_ERR_NO_NAME;
410+
msg_incr_reroute_cnt(msg);
411+
msg_set_destnode(msg, *dnode);
412+
msg_set_destport(msg, dport);
413+
return TIPC_OK;
414+
}

net/tipc/msg.h

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,11 @@ static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m)
463463
#define FRAGMENT 1
464464
#define LAST_FRAGMENT 2
465465

466+
/* Bundling protocol message types
467+
*/
468+
#define BUNDLE_OPEN 0
469+
#define BUNDLE_CLOSED 1
470+
466471
/*
467472
* Link management protocol message types
468473
*/
@@ -706,12 +711,37 @@ static inline void msg_set_link_tolerance(struct tipc_msg *m, u32 n)
706711
msg_set_bits(m, 9, 0, 0xffff, n);
707712
}
708713

709-
u32 tipc_msg_tot_importance(struct tipc_msg *m);
714+
static inline u32 tipc_msg_tot_importance(struct tipc_msg *m)
715+
{
716+
if ((msg_user(m) == MSG_FRAGMENTER) && (msg_type(m) == FIRST_FRAGMENT))
717+
return msg_importance(msg_get_wrapped(m));
718+
return msg_importance(m);
719+
}
720+
721+
static inline u32 msg_tot_origport(struct tipc_msg *m)
722+
{
723+
if ((msg_user(m) == MSG_FRAGMENTER) && (msg_type(m) == FIRST_FRAGMENT))
724+
return msg_origport(msg_get_wrapped(m));
725+
return msg_origport(m);
726+
}
727+
728+
bool tipc_msg_reverse(struct sk_buff *buf, u32 *dnode, int err);
729+
730+
int tipc_msg_eval(struct sk_buff *buf, u32 *dnode);
731+
710732
void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, u32 hsize,
711733
u32 destnode);
734+
712735
int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect,
713736
unsigned int len, int max_size, struct sk_buff **buf);
714737

715738
int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf);
716739

740+
bool tipc_msg_bundle(struct sk_buff *bbuf, struct sk_buff *buf, u32 mtu);
741+
742+
bool tipc_msg_make_bundle(struct sk_buff **buf, u32 mtu, u32 dnode);
743+
744+
int tipc_msg_build2(struct tipc_msg *mhdr, struct iovec const *iov,
745+
int offset, int dsz, int mtu , struct sk_buff **chain);
746+
717747
#endif

0 commit comments

Comments
 (0)