diff options
Diffstat (limited to 'net/tipc/msg.c')
-rw-r--r-- | net/tipc/msg.c | 167 |
1 files changed, 128 insertions, 39 deletions
diff --git a/net/tipc/msg.c b/net/tipc/msg.c index 73dcd00d674e..bb6180c4fcbb 100644 --- a/net/tipc/msg.c +++ b/net/tipc/msg.c | |||
@@ -35,17 +35,109 @@ | |||
35 | */ | 35 | */ |
36 | 36 | ||
37 | #include "core.h" | 37 | #include "core.h" |
38 | #include "addr.h" | ||
39 | #include "dbg.h" | ||
40 | #include "msg.h" | 38 | #include "msg.h" |
41 | #include "bearer.h" | ||
42 | 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 | if (!msg_short(m)) { | ||
65 | msg_set_orignode(m, tipc_own_addr); | ||
66 | msg_set_destnode(m, destnode); | ||
67 | } | ||
68 | } | ||
69 | |||
70 | /** | ||
71 | * tipc_msg_calc_data_size - determine total data size for message | ||
72 | */ | ||
73 | |||
74 | int tipc_msg_calc_data_size(struct iovec const *msg_sect, u32 num_sect) | ||
75 | { | ||
76 | int dsz = 0; | ||
77 | int i; | ||
78 | |||
79 | for (i = 0; i < num_sect; i++) | ||
80 | dsz += msg_sect[i].iov_len; | ||
81 | return dsz; | ||
82 | } | ||
83 | |||
84 | /** | ||
85 | * tipc_msg_build - create message using specified header and data | ||
86 | * | ||
87 | * Note: Caller must not hold any locks in case copy_from_user() is interrupted! | ||
88 | * | ||
89 | * Returns message data size or errno | ||
90 | */ | ||
91 | |||
92 | int tipc_msg_build(struct tipc_msg *hdr, | ||
93 | struct iovec const *msg_sect, u32 num_sect, | ||
94 | int max_size, int usrmem, struct sk_buff **buf) | ||
95 | { | ||
96 | int dsz, sz, hsz, pos, res, cnt; | ||
97 | |||
98 | dsz = tipc_msg_calc_data_size(msg_sect, num_sect); | ||
99 | if (unlikely(dsz > TIPC_MAX_USER_MSG_SIZE)) { | ||
100 | *buf = NULL; | ||
101 | return -EINVAL; | ||
102 | } | ||
103 | |||
104 | pos = hsz = msg_hdr_sz(hdr); | ||
105 | sz = hsz + dsz; | ||
106 | msg_set_size(hdr, sz); | ||
107 | if (unlikely(sz > max_size)) { | ||
108 | *buf = NULL; | ||
109 | return dsz; | ||
110 | } | ||
111 | |||
112 | *buf = tipc_buf_acquire(sz); | ||
113 | if (!(*buf)) | ||
114 | return -ENOMEM; | ||
115 | skb_copy_to_linear_data(*buf, hdr, hsz); | ||
116 | for (res = 1, cnt = 0; res && (cnt < num_sect); cnt++) { | ||
117 | if (likely(usrmem)) | ||
118 | res = !copy_from_user((*buf)->data + pos, | ||
119 | msg_sect[cnt].iov_base, | ||
120 | msg_sect[cnt].iov_len); | ||
121 | else | ||
122 | skb_copy_to_linear_data_offset(*buf, pos, | ||
123 | msg_sect[cnt].iov_base, | ||
124 | msg_sect[cnt].iov_len); | ||
125 | pos += msg_sect[cnt].iov_len; | ||
126 | } | ||
127 | if (likely(res)) | ||
128 | return dsz; | ||
129 | |||
130 | buf_discard(*buf); | ||
131 | *buf = NULL; | ||
132 | return -EFAULT; | ||
133 | } | ||
43 | 134 | ||
44 | #ifdef CONFIG_TIPC_DEBUG | 135 | #ifdef CONFIG_TIPC_DEBUG |
45 | 136 | ||
46 | void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str) | 137 | void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str) |
47 | { | 138 | { |
48 | u32 usr = msg_user(msg); | 139 | u32 usr = msg_user(msg); |
140 | tipc_printf(buf, KERN_DEBUG); | ||
49 | tipc_printf(buf, str); | 141 | tipc_printf(buf, str); |
50 | 142 | ||
51 | switch (usr) { | 143 | switch (usr) { |
@@ -69,10 +161,10 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str) | |||
69 | tipc_printf(buf, "LAST:"); | 161 | tipc_printf(buf, "LAST:"); |
70 | break; | 162 | break; |
71 | default: | 163 | default: |
72 | tipc_printf(buf, "UNKNOWN:%x",msg_type(msg)); | 164 | tipc_printf(buf, "UNKNOWN:%x", msg_type(msg)); |
73 | 165 | ||
74 | } | 166 | } |
75 | tipc_printf(buf, "NO(%u/%u):",msg_long_msgno(msg), | 167 | tipc_printf(buf, "NO(%u/%u):", msg_long_msgno(msg), |
76 | msg_fragm_no(msg)); | 168 | msg_fragm_no(msg)); |
77 | break; | 169 | break; |
78 | case TIPC_LOW_IMPORTANCE: | 170 | case TIPC_LOW_IMPORTANCE: |
@@ -98,7 +190,7 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str) | |||
98 | tipc_printf(buf, "DIR:"); | 190 | tipc_printf(buf, "DIR:"); |
99 | break; | 191 | break; |
100 | default: | 192 | default: |
101 | tipc_printf(buf, "UNKNOWN TYPE %u",msg_type(msg)); | 193 | tipc_printf(buf, "UNKNOWN TYPE %u", msg_type(msg)); |
102 | } | 194 | } |
103 | if (msg_routed(msg) && !msg_non_seq(msg)) | 195 | if (msg_routed(msg) && !msg_non_seq(msg)) |
104 | tipc_printf(buf, "ROUT:"); | 196 | tipc_printf(buf, "ROUT:"); |
@@ -116,7 +208,7 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str) | |||
116 | tipc_printf(buf, "WDRW:"); | 208 | tipc_printf(buf, "WDRW:"); |
117 | break; | 209 | break; |
118 | default: | 210 | default: |
119 | tipc_printf(buf, "UNKNOWN:%x",msg_type(msg)); | 211 | tipc_printf(buf, "UNKNOWN:%x", msg_type(msg)); |
120 | } | 212 | } |
121 | if (msg_routed(msg)) | 213 | if (msg_routed(msg)) |
122 | tipc_printf(buf, "ROUT:"); | 214 | tipc_printf(buf, "ROUT:"); |
@@ -135,39 +227,39 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str) | |||
135 | break; | 227 | break; |
136 | case CONN_ACK: | 228 | case CONN_ACK: |
137 | tipc_printf(buf, "CONN_ACK:"); | 229 | tipc_printf(buf, "CONN_ACK:"); |
138 | tipc_printf(buf, "ACK(%u):",msg_msgcnt(msg)); | 230 | tipc_printf(buf, "ACK(%u):", msg_msgcnt(msg)); |
139 | break; | 231 | break; |
140 | default: | 232 | default: |
141 | tipc_printf(buf, "UNKNOWN TYPE:%x",msg_type(msg)); | 233 | tipc_printf(buf, "UNKNOWN TYPE:%x", msg_type(msg)); |
142 | } | 234 | } |
143 | if (msg_routed(msg)) | 235 | if (msg_routed(msg)) |
144 | tipc_printf(buf, "ROUT:"); | 236 | tipc_printf(buf, "ROUT:"); |
145 | if (msg_reroute_cnt(msg)) | 237 | if (msg_reroute_cnt(msg)) |
146 | tipc_printf(buf, "REROUTED(%u):",msg_reroute_cnt(msg)); | 238 | tipc_printf(buf, "REROUTED(%u):", msg_reroute_cnt(msg)); |
147 | break; | 239 | break; |
148 | case LINK_PROTOCOL: | 240 | case LINK_PROTOCOL: |
149 | tipc_printf(buf, "PROT:TIM(%u):",msg_timestamp(msg)); | 241 | tipc_printf(buf, "PROT:TIM(%u):", msg_timestamp(msg)); |
150 | switch (msg_type(msg)) { | 242 | switch (msg_type(msg)) { |
151 | case STATE_MSG: | 243 | case STATE_MSG: |
152 | tipc_printf(buf, "STATE:"); | 244 | tipc_printf(buf, "STATE:"); |
153 | tipc_printf(buf, "%s:",msg_probe(msg) ? "PRB" :""); | 245 | tipc_printf(buf, "%s:", msg_probe(msg) ? "PRB" : ""); |
154 | tipc_printf(buf, "NXS(%u):",msg_next_sent(msg)); | 246 | tipc_printf(buf, "NXS(%u):", msg_next_sent(msg)); |
155 | tipc_printf(buf, "GAP(%u):",msg_seq_gap(msg)); | 247 | tipc_printf(buf, "GAP(%u):", msg_seq_gap(msg)); |
156 | tipc_printf(buf, "LSTBC(%u):",msg_last_bcast(msg)); | 248 | tipc_printf(buf, "LSTBC(%u):", msg_last_bcast(msg)); |
157 | break; | 249 | break; |
158 | case RESET_MSG: | 250 | case RESET_MSG: |
159 | tipc_printf(buf, "RESET:"); | 251 | tipc_printf(buf, "RESET:"); |
160 | if (msg_size(msg) != msg_hdr_sz(msg)) | 252 | if (msg_size(msg) != msg_hdr_sz(msg)) |
161 | tipc_printf(buf, "BEAR:%s:",msg_data(msg)); | 253 | tipc_printf(buf, "BEAR:%s:", msg_data(msg)); |
162 | break; | 254 | break; |
163 | case ACTIVATE_MSG: | 255 | case ACTIVATE_MSG: |
164 | tipc_printf(buf, "ACTIVATE:"); | 256 | tipc_printf(buf, "ACTIVATE:"); |
165 | break; | 257 | break; |
166 | default: | 258 | default: |
167 | tipc_printf(buf, "UNKNOWN TYPE:%x",msg_type(msg)); | 259 | tipc_printf(buf, "UNKNOWN TYPE:%x", msg_type(msg)); |
168 | } | 260 | } |
169 | tipc_printf(buf, "PLANE(%c):",msg_net_plane(msg)); | 261 | tipc_printf(buf, "PLANE(%c):", msg_net_plane(msg)); |
170 | tipc_printf(buf, "SESS(%u):",msg_session(msg)); | 262 | tipc_printf(buf, "SESS(%u):", msg_session(msg)); |
171 | break; | 263 | break; |
172 | case CHANGEOVER_PROTOCOL: | 264 | case CHANGEOVER_PROTOCOL: |
173 | tipc_printf(buf, "TUNL:"); | 265 | tipc_printf(buf, "TUNL:"); |
@@ -177,10 +269,10 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str) | |||
177 | break; | 269 | break; |
178 | case ORIGINAL_MSG: | 270 | case ORIGINAL_MSG: |
179 | tipc_printf(buf, "ORIG:"); | 271 | tipc_printf(buf, "ORIG:"); |
180 | tipc_printf(buf, "EXP(%u)",msg_msgcnt(msg)); | 272 | tipc_printf(buf, "EXP(%u)", msg_msgcnt(msg)); |
181 | break; | 273 | break; |
182 | default: | 274 | default: |
183 | tipc_printf(buf, "UNKNOWN TYPE:%x",msg_type(msg)); | 275 | tipc_printf(buf, "UNKNOWN TYPE:%x", msg_type(msg)); |
184 | } | 276 | } |
185 | break; | 277 | break; |
186 | case ROUTE_DISTRIBUTOR: | 278 | case ROUTE_DISTRIBUTOR: |
@@ -188,26 +280,26 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str) | |||
188 | switch (msg_type(msg)) { | 280 | switch (msg_type(msg)) { |
189 | case EXT_ROUTING_TABLE: | 281 | case EXT_ROUTING_TABLE: |
190 | tipc_printf(buf, "EXT_TBL:"); | 282 | tipc_printf(buf, "EXT_TBL:"); |
191 | tipc_printf(buf, "TO:%x:",msg_remote_node(msg)); | 283 | tipc_printf(buf, "TO:%x:", msg_remote_node(msg)); |
192 | break; | 284 | break; |
193 | case LOCAL_ROUTING_TABLE: | 285 | case LOCAL_ROUTING_TABLE: |
194 | tipc_printf(buf, "LOCAL_TBL:"); | 286 | tipc_printf(buf, "LOCAL_TBL:"); |
195 | tipc_printf(buf, "TO:%x:",msg_remote_node(msg)); | 287 | tipc_printf(buf, "TO:%x:", msg_remote_node(msg)); |
196 | break; | 288 | break; |
197 | case SLAVE_ROUTING_TABLE: | 289 | case SLAVE_ROUTING_TABLE: |
198 | tipc_printf(buf, "DP_TBL:"); | 290 | tipc_printf(buf, "DP_TBL:"); |
199 | tipc_printf(buf, "TO:%x:",msg_remote_node(msg)); | 291 | tipc_printf(buf, "TO:%x:", msg_remote_node(msg)); |
200 | break; | 292 | break; |
201 | case ROUTE_ADDITION: | 293 | case ROUTE_ADDITION: |
202 | tipc_printf(buf, "ADD:"); | 294 | tipc_printf(buf, "ADD:"); |
203 | tipc_printf(buf, "TO:%x:",msg_remote_node(msg)); | 295 | tipc_printf(buf, "TO:%x:", msg_remote_node(msg)); |
204 | break; | 296 | break; |
205 | case ROUTE_REMOVAL: | 297 | case ROUTE_REMOVAL: |
206 | tipc_printf(buf, "REMOVE:"); | 298 | tipc_printf(buf, "REMOVE:"); |
207 | tipc_printf(buf, "TO:%x:",msg_remote_node(msg)); | 299 | tipc_printf(buf, "TO:%x:", msg_remote_node(msg)); |
208 | break; | 300 | break; |
209 | default: | 301 | default: |
210 | tipc_printf(buf, "UNKNOWN TYPE:%x",msg_type(msg)); | 302 | tipc_printf(buf, "UNKNOWN TYPE:%x", msg_type(msg)); |
211 | } | 303 | } |
212 | break; | 304 | break; |
213 | case LINK_CONFIG: | 305 | case LINK_CONFIG: |
@@ -220,7 +312,7 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str) | |||
220 | tipc_printf(buf, "DSC_RESP:"); | 312 | tipc_printf(buf, "DSC_RESP:"); |
221 | break; | 313 | break; |
222 | default: | 314 | default: |
223 | tipc_printf(buf, "UNKNOWN TYPE:%x:",msg_type(msg)); | 315 | tipc_printf(buf, "UNKNOWN TYPE:%x:", msg_type(msg)); |
224 | break; | 316 | break; |
225 | } | 317 | } |
226 | break; | 318 | break; |
@@ -256,7 +348,8 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str) | |||
256 | tipc_printf(buf, "UNKNOWN ERROR(%x):", | 348 | tipc_printf(buf, "UNKNOWN ERROR(%x):", |
257 | msg_errcode(msg)); | 349 | msg_errcode(msg)); |
258 | } | 350 | } |
259 | default:{} | 351 | default: |
352 | break; | ||
260 | } | 353 | } |
261 | 354 | ||
262 | tipc_printf(buf, "HZ(%u):", msg_hdr_sz(msg)); | 355 | tipc_printf(buf, "HZ(%u):", msg_hdr_sz(msg)); |
@@ -265,9 +358,8 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str) | |||
265 | 358 | ||
266 | if (msg_non_seq(msg)) | 359 | if (msg_non_seq(msg)) |
267 | tipc_printf(buf, "NOSEQ:"); | 360 | tipc_printf(buf, "NOSEQ:"); |
268 | else { | 361 | else |
269 | tipc_printf(buf, "ACK(%u):", msg_ack(msg)); | 362 | tipc_printf(buf, "ACK(%u):", msg_ack(msg)); |
270 | } | ||
271 | tipc_printf(buf, "BACK(%u):", msg_bcast_ack(msg)); | 363 | tipc_printf(buf, "BACK(%u):", msg_bcast_ack(msg)); |
272 | tipc_printf(buf, "PRND(%x)", msg_prevnode(msg)); | 364 | tipc_printf(buf, "PRND(%x)", msg_prevnode(msg)); |
273 | 365 | ||
@@ -295,14 +387,13 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str) | |||
295 | if (msg_user(msg) == NAME_DISTRIBUTOR) { | 387 | if (msg_user(msg) == NAME_DISTRIBUTOR) { |
296 | tipc_printf(buf, ":ONOD(%x):", msg_orignode(msg)); | 388 | tipc_printf(buf, ":ONOD(%x):", msg_orignode(msg)); |
297 | tipc_printf(buf, ":DNOD(%x):", msg_destnode(msg)); | 389 | tipc_printf(buf, ":DNOD(%x):", msg_destnode(msg)); |
298 | if (msg_routed(msg)) { | 390 | if (msg_routed(msg)) |
299 | tipc_printf(buf, ":CSEQN(%u)", msg_transp_seqno(msg)); | 391 | tipc_printf(buf, ":CSEQN(%u)", msg_transp_seqno(msg)); |
300 | } | ||
301 | } | 392 | } |
302 | 393 | ||
303 | if (msg_user(msg) == LINK_CONFIG) { | 394 | if (msg_user(msg) == LINK_CONFIG) { |
304 | u32* raw = (u32*)msg; | 395 | u32 *raw = (u32 *)msg; |
305 | struct tipc_media_addr* orig = (struct tipc_media_addr*)&raw[5]; | 396 | struct tipc_media_addr *orig = (struct tipc_media_addr *)&raw[5]; |
306 | tipc_printf(buf, ":REQL(%u):", msg_req_links(msg)); | 397 | tipc_printf(buf, ":REQL(%u):", msg_req_links(msg)); |
307 | tipc_printf(buf, ":DDOM(%x):", msg_dest_domain(msg)); | 398 | tipc_printf(buf, ":DDOM(%x):", msg_dest_domain(msg)); |
308 | tipc_printf(buf, ":NETID(%u):", msg_bc_netid(msg)); | 399 | tipc_printf(buf, ":NETID(%u):", msg_bc_netid(msg)); |
@@ -313,12 +404,10 @@ void tipc_msg_dbg(struct print_buf *buf, struct tipc_msg *msg, const char *str) | |||
313 | tipc_printf(buf, "TO(%u):", msg_bcgap_to(msg)); | 404 | tipc_printf(buf, "TO(%u):", msg_bcgap_to(msg)); |
314 | } | 405 | } |
315 | tipc_printf(buf, "\n"); | 406 | tipc_printf(buf, "\n"); |
316 | if ((usr == CHANGEOVER_PROTOCOL) && (msg_msgcnt(msg))) { | 407 | if ((usr == CHANGEOVER_PROTOCOL) && (msg_msgcnt(msg))) |
317 | tipc_msg_dbg(buf, msg_get_wrapped(msg), " /"); | 408 | tipc_msg_dbg(buf, msg_get_wrapped(msg), " /"); |
318 | } | 409 | if ((usr == MSG_FRAGMENTER) && (msg_type(msg) == FIRST_FRAGMENT)) |
319 | if ((usr == MSG_FRAGMENTER) && (msg_type(msg) == FIRST_FRAGMENT)) { | ||
320 | tipc_msg_dbg(buf, msg_get_wrapped(msg), " /"); | 410 | tipc_msg_dbg(buf, msg_get_wrapped(msg), " /"); |
321 | } | ||
322 | } | 411 | } |
323 | 412 | ||
324 | #endif | 413 | #endif |