~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to net/tipc/msg.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * net/tipc/msg.c: TIPC message header routines
 
3
 *
 
4
 * Copyright (c) 2000-2006, Ericsson AB
 
5
 * Copyright (c) 2005, 2010-2011, Wind River Systems
 
6
 * All rights reserved.
 
7
 *
 
8
 * Redistribution and use in source and binary forms, with or without
 
9
 * modification, are permitted provided that the following conditions are met:
 
10
 *
 
11
 * 1. Redistributions of source code must retain the above copyright
 
12
 *    notice, this list of conditions and the following disclaimer.
 
13
 * 2. Redistributions in binary form must reproduce the above copyright
 
14
 *    notice, this list of conditions and the following disclaimer in the
 
15
 *    documentation and/or other materials provided with the distribution.
 
16
 * 3. Neither the names of the copyright holders nor the names of its
 
17
 *    contributors may be used to endorse or promote products derived from
 
18
 *    this software without specific prior written permission.
 
19
 *
 
20
 * Alternatively, this software may be distributed under the terms of the
 
21
 * GNU General Public License ("GPL") version 2 as published by the Free
 
22
 * Software Foundation.
 
23
 *
 
24
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 
25
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
26
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
27
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 
28
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 
29
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 
30
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 
31
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 
32
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
33
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 
34
 * POSSIBILITY OF SUCH DAMAGE.
 
35
 */
 
36
 
 
37
#include "core.h"
 
38
#include "msg.h"
 
39
 
 
40
u32 tipc_msg_tot_importance(struct tipc_msg *m)
 
41
{
 
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);
 
51
}
 
52
 
 
53
 
 
54
void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type,
 
55
                            u32 hsize, u32 destnode)
 
56
{
 
57
        memset(m, 0, hsize);
 
58
        msg_set_version(m);
 
59
        msg_set_user(m, user);
 
60
        msg_set_hdr_sz(m, hsize);
 
61
        msg_set_size(m, hsize);
 
62
        msg_set_prevnode(m, tipc_own_addr);
 
63
        msg_set_type(m, type);
 
64
        msg_set_orignode(m, tipc_own_addr);
 
65
        msg_set_destnode(m, destnode);
 
66
}
 
67
 
 
68
/**
 
69
 * tipc_msg_build - create message using specified header and data
 
70
 *
 
71
 * Note: Caller must not hold any locks in case copy_from_user() is interrupted!
 
72
 *
 
73
 * Returns message data size or errno
 
74
 */
 
75
 
 
76
int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect,
 
77
                   u32 num_sect, unsigned int total_len,
 
78
                            int max_size, int usrmem, struct sk_buff **buf)
 
79
{
 
80
        int dsz, sz, hsz, pos, res, cnt;
 
81
 
 
82
        dsz = total_len;
 
83
        pos = hsz = msg_hdr_sz(hdr);
 
84
        sz = hsz + dsz;
 
85
        msg_set_size(hdr, sz);
 
86
        if (unlikely(sz > max_size)) {
 
87
                *buf = NULL;
 
88
                return dsz;
 
89
        }
 
90
 
 
91
        *buf = tipc_buf_acquire(sz);
 
92
        if (!(*buf))
 
93
                return -ENOMEM;
 
94
        skb_copy_to_linear_data(*buf, hdr, hsz);
 
95
        for (res = 1, cnt = 0; res && (cnt < num_sect); cnt++) {
 
96
                if (likely(usrmem))
 
97
                        res = !copy_from_user((*buf)->data + pos,
 
98
                                              msg_sect[cnt].iov_base,
 
99
                                              msg_sect[cnt].iov_len);
 
100
                else
 
101
                        skb_copy_to_linear_data_offset(*buf, pos,
 
102
                                                       msg_sect[cnt].iov_base,
 
103
                                                       msg_sect[cnt].iov_len);
 
104
                pos += msg_sect[cnt].iov_len;
 
105
        }
 
106
        if (likely(res))
 
107
                return dsz;
 
108
 
 
109
        buf_discard(*buf);
 
110
        *buf = NULL;
 
111
        return -EFAULT;
 
112
}
 
113
 
 
114
#ifdef CONFIG_TIPC_DEBUG
 
115
 
 
116
void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str)
 
117
{
 
118
        u32 usr = msg_user(msg);
 
119
        tipc_printf(buf, KERN_DEBUG);
 
120
        tipc_printf(buf, str);
 
121
 
 
122
        switch (usr) {
 
123
        case MSG_BUNDLER:
 
124
                tipc_printf(buf, "BNDL::");
 
125
                tipc_printf(buf, "MSGS(%u):", msg_msgcnt(msg));
 
126
                break;
 
127
        case BCAST_PROTOCOL:
 
128
                tipc_printf(buf, "BCASTP::");
 
129
                break;
 
130
        case MSG_FRAGMENTER:
 
131
                tipc_printf(buf, "FRAGM::");
 
132
                switch (msg_type(msg)) {
 
133
                case FIRST_FRAGMENT:
 
134
                        tipc_printf(buf, "FIRST:");
 
135
                        break;
 
136
                case FRAGMENT:
 
137
                        tipc_printf(buf, "BODY:");
 
138
                        break;
 
139
                case LAST_FRAGMENT:
 
140
                        tipc_printf(buf, "LAST:");
 
141
                        break;
 
142
                default:
 
143
                        tipc_printf(buf, "UNKNOWN:%x", msg_type(msg));
 
144
 
 
145
                }
 
146
                tipc_printf(buf, "NO(%u/%u):", msg_long_msgno(msg),
 
147
                            msg_fragm_no(msg));
 
148
                break;
 
149
        case TIPC_LOW_IMPORTANCE:
 
150
        case TIPC_MEDIUM_IMPORTANCE:
 
151
        case TIPC_HIGH_IMPORTANCE:
 
152
        case TIPC_CRITICAL_IMPORTANCE:
 
153
                tipc_printf(buf, "DAT%u:", msg_user(msg));
 
154
                if (msg_short(msg)) {
 
155
                        tipc_printf(buf, "CON:");
 
156
                        break;
 
157
                }
 
158
                switch (msg_type(msg)) {
 
159
                case TIPC_CONN_MSG:
 
160
                        tipc_printf(buf, "CON:");
 
161
                        break;
 
162
                case TIPC_MCAST_MSG:
 
163
                        tipc_printf(buf, "MCST:");
 
164
                        break;
 
165
                case TIPC_NAMED_MSG:
 
166
                        tipc_printf(buf, "NAM:");
 
167
                        break;
 
168
                case TIPC_DIRECT_MSG:
 
169
                        tipc_printf(buf, "DIR:");
 
170
                        break;
 
171
                default:
 
172
                        tipc_printf(buf, "UNKNOWN TYPE %u", msg_type(msg));
 
173
                }
 
174
                if (msg_reroute_cnt(msg))
 
175
                        tipc_printf(buf, "REROUTED(%u):",
 
176
                                    msg_reroute_cnt(msg));
 
177
                break;
 
178
        case NAME_DISTRIBUTOR:
 
179
                tipc_printf(buf, "NMD::");
 
180
                switch (msg_type(msg)) {
 
181
                case PUBLICATION:
 
182
                        tipc_printf(buf, "PUBL(%u):", (msg_size(msg) - msg_hdr_sz(msg)) / 20);  /* Items */
 
183
                        break;
 
184
                case WITHDRAWAL:
 
185
                        tipc_printf(buf, "WDRW:");
 
186
                        break;
 
187
                default:
 
188
                        tipc_printf(buf, "UNKNOWN:%x", msg_type(msg));
 
189
                }
 
190
                if (msg_reroute_cnt(msg))
 
191
                        tipc_printf(buf, "REROUTED(%u):",
 
192
                                    msg_reroute_cnt(msg));
 
193
                break;
 
194
        case CONN_MANAGER:
 
195
                tipc_printf(buf, "CONN_MNG:");
 
196
                switch (msg_type(msg)) {
 
197
                case CONN_PROBE:
 
198
                        tipc_printf(buf, "PROBE:");
 
199
                        break;
 
200
                case CONN_PROBE_REPLY:
 
201
                        tipc_printf(buf, "PROBE_REPLY:");
 
202
                        break;
 
203
                case CONN_ACK:
 
204
                        tipc_printf(buf, "CONN_ACK:");
 
205
                        tipc_printf(buf, "ACK(%u):", msg_msgcnt(msg));
 
206
                        break;
 
207
                default:
 
208
                        tipc_printf(buf, "UNKNOWN TYPE:%x", msg_type(msg));
 
209
                }
 
210
                if (msg_reroute_cnt(msg))
 
211
                        tipc_printf(buf, "REROUTED(%u):", msg_reroute_cnt(msg));
 
212
                break;
 
213
        case LINK_PROTOCOL:
 
214
                switch (msg_type(msg)) {
 
215
                case STATE_MSG:
 
216
                        tipc_printf(buf, "STATE:");
 
217
                        tipc_printf(buf, "%s:", msg_probe(msg) ? "PRB" : "");
 
218
                        tipc_printf(buf, "NXS(%u):", msg_next_sent(msg));
 
219
                        tipc_printf(buf, "GAP(%u):", msg_seq_gap(msg));
 
220
                        tipc_printf(buf, "LSTBC(%u):", msg_last_bcast(msg));
 
221
                        break;
 
222
                case RESET_MSG:
 
223
                        tipc_printf(buf, "RESET:");
 
224
                        if (msg_size(msg) != msg_hdr_sz(msg))
 
225
                                tipc_printf(buf, "BEAR:%s:", msg_data(msg));
 
226
                        break;
 
227
                case ACTIVATE_MSG:
 
228
                        tipc_printf(buf, "ACTIVATE:");
 
229
                        break;
 
230
                default:
 
231
                        tipc_printf(buf, "UNKNOWN TYPE:%x", msg_type(msg));
 
232
                }
 
233
                tipc_printf(buf, "PLANE(%c):", msg_net_plane(msg));
 
234
                tipc_printf(buf, "SESS(%u):", msg_session(msg));
 
235
                break;
 
236
        case CHANGEOVER_PROTOCOL:
 
237
                tipc_printf(buf, "TUNL:");
 
238
                switch (msg_type(msg)) {
 
239
                case DUPLICATE_MSG:
 
240
                        tipc_printf(buf, "DUPL:");
 
241
                        break;
 
242
                case ORIGINAL_MSG:
 
243
                        tipc_printf(buf, "ORIG:");
 
244
                        tipc_printf(buf, "EXP(%u)", msg_msgcnt(msg));
 
245
                        break;
 
246
                default:
 
247
                        tipc_printf(buf, "UNKNOWN TYPE:%x", msg_type(msg));
 
248
                }
 
249
                break;
 
250
        case LINK_CONFIG:
 
251
                tipc_printf(buf, "CFG:");
 
252
                switch (msg_type(msg)) {
 
253
                case DSC_REQ_MSG:
 
254
                        tipc_printf(buf, "DSC_REQ:");
 
255
                        break;
 
256
                case DSC_RESP_MSG:
 
257
                        tipc_printf(buf, "DSC_RESP:");
 
258
                        break;
 
259
                default:
 
260
                        tipc_printf(buf, "UNKNOWN TYPE:%x:", msg_type(msg));
 
261
                        break;
 
262
                }
 
263
                break;
 
264
        default:
 
265
                tipc_printf(buf, "UNKNOWN USER:");
 
266
        }
 
267
 
 
268
        switch (usr) {
 
269
        case CONN_MANAGER:
 
270
        case TIPC_LOW_IMPORTANCE:
 
271
        case TIPC_MEDIUM_IMPORTANCE:
 
272
        case TIPC_HIGH_IMPORTANCE:
 
273
        case TIPC_CRITICAL_IMPORTANCE:
 
274
                switch (msg_errcode(msg)) {
 
275
                case TIPC_OK:
 
276
                        break;
 
277
                case TIPC_ERR_NO_NAME:
 
278
                        tipc_printf(buf, "NO_NAME:");
 
279
                        break;
 
280
                case TIPC_ERR_NO_PORT:
 
281
                        tipc_printf(buf, "NO_PORT:");
 
282
                        break;
 
283
                case TIPC_ERR_NO_NODE:
 
284
                        tipc_printf(buf, "NO_PROC:");
 
285
                        break;
 
286
                case TIPC_ERR_OVERLOAD:
 
287
                        tipc_printf(buf, "OVERLOAD:");
 
288
                        break;
 
289
                case TIPC_CONN_SHUTDOWN:
 
290
                        tipc_printf(buf, "SHUTDOWN:");
 
291
                        break;
 
292
                default:
 
293
                        tipc_printf(buf, "UNKNOWN ERROR(%x):",
 
294
                                    msg_errcode(msg));
 
295
                }
 
296
        default:
 
297
                break;
 
298
        }
 
299
 
 
300
        tipc_printf(buf, "HZ(%u):", msg_hdr_sz(msg));
 
301
        tipc_printf(buf, "SZ(%u):", msg_size(msg));
 
302
        tipc_printf(buf, "SQNO(%u):", msg_seqno(msg));
 
303
 
 
304
        if (msg_non_seq(msg))
 
305
                tipc_printf(buf, "NOSEQ:");
 
306
        else
 
307
                tipc_printf(buf, "ACK(%u):", msg_ack(msg));
 
308
        tipc_printf(buf, "BACK(%u):", msg_bcast_ack(msg));
 
309
        tipc_printf(buf, "PRND(%x)", msg_prevnode(msg));
 
310
 
 
311
        if (msg_isdata(msg)) {
 
312
                if (msg_named(msg)) {
 
313
                        tipc_printf(buf, "NTYP(%u):", msg_nametype(msg));
 
314
                        tipc_printf(buf, "NINST(%u)", msg_nameinst(msg));
 
315
                }
 
316
        }
 
317
 
 
318
        if ((usr != LINK_PROTOCOL) && (usr != LINK_CONFIG) &&
 
319
            (usr != MSG_BUNDLER)) {
 
320
                if (!msg_short(msg)) {
 
321
                        tipc_printf(buf, ":ORIG(%x:%u):",
 
322
                                    msg_orignode(msg), msg_origport(msg));
 
323
                        tipc_printf(buf, ":DEST(%x:%u):",
 
324
                                    msg_destnode(msg), msg_destport(msg));
 
325
                } else {
 
326
                        tipc_printf(buf, ":OPRT(%u):", msg_origport(msg));
 
327
                        tipc_printf(buf, ":DPRT(%u):", msg_destport(msg));
 
328
                }
 
329
        }
 
330
        if (msg_user(msg) == NAME_DISTRIBUTOR) {
 
331
                tipc_printf(buf, ":ONOD(%x):", msg_orignode(msg));
 
332
                tipc_printf(buf, ":DNOD(%x):", msg_destnode(msg));
 
333
        }
 
334
 
 
335
        if (msg_user(msg) ==  LINK_CONFIG) {
 
336
                u32 *raw = (u32 *)msg;
 
337
                struct tipc_media_addr *orig = (struct tipc_media_addr *)&raw[5];
 
338
                tipc_printf(buf, ":DDOM(%x):", msg_dest_domain(msg));
 
339
                tipc_printf(buf, ":NETID(%u):", msg_bc_netid(msg));
 
340
                tipc_media_addr_printf(buf, orig);
 
341
        }
 
342
        if (msg_user(msg) == BCAST_PROTOCOL) {
 
343
                tipc_printf(buf, "BCNACK:AFTER(%u):", msg_bcgap_after(msg));
 
344
                tipc_printf(buf, "TO(%u):", msg_bcgap_to(msg));
 
345
        }
 
346
        tipc_printf(buf, "\n");
 
347
        if ((usr == CHANGEOVER_PROTOCOL) && (msg_msgcnt(msg)))
 
348
                tipc_msg_dbg(buf, msg_get_wrapped(msg), "      /");
 
349
        if ((usr == MSG_FRAGMENTER) && (msg_type(msg) == FIRST_FRAGMENT))
 
350
                tipc_msg_dbg(buf, msg_get_wrapped(msg), "      /");
 
351
}
 
352
 
 
353
#endif