diff options
Diffstat (limited to 'net/tipc/port.c')
| -rw-r--r-- | net/tipc/port.c | 72 |
1 files changed, 54 insertions, 18 deletions
diff --git a/net/tipc/port.c b/net/tipc/port.c index d91efc69e6f9..94d2904cce66 100644 --- a/net/tipc/port.c +++ b/net/tipc/port.c | |||
| @@ -116,13 +116,13 @@ int tipc_multicast(u32 ref, struct tipc_name_seq const *seq, | |||
| 116 | ibuf = skb_copy(buf, GFP_ATOMIC); | 116 | ibuf = skb_copy(buf, GFP_ATOMIC); |
| 117 | if (ibuf == NULL) { | 117 | if (ibuf == NULL) { |
| 118 | tipc_port_list_free(&dports); | 118 | tipc_port_list_free(&dports); |
| 119 | buf_discard(buf); | 119 | kfree_skb(buf); |
| 120 | return -ENOMEM; | 120 | return -ENOMEM; |
| 121 | } | 121 | } |
| 122 | } | 122 | } |
| 123 | res = tipc_bclink_send_msg(buf); | 123 | res = tipc_bclink_send_msg(buf); |
| 124 | if ((res < 0) && (dports.count != 0)) | 124 | if ((res < 0) && (dports.count != 0)) |
| 125 | buf_discard(ibuf); | 125 | kfree_skb(ibuf); |
| 126 | } else { | 126 | } else { |
| 127 | ibuf = buf; | 127 | ibuf = buf; |
| 128 | } | 128 | } |
| @@ -187,7 +187,7 @@ void tipc_port_recv_mcast(struct sk_buff *buf, struct tipc_port_list *dp) | |||
| 187 | } | 187 | } |
| 188 | } | 188 | } |
| 189 | exit: | 189 | exit: |
| 190 | buf_discard(buf); | 190 | kfree_skb(buf); |
| 191 | tipc_port_list_free(dp); | 191 | tipc_port_list_free(dp); |
| 192 | } | 192 | } |
| 193 | 193 | ||
| @@ -400,15 +400,16 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err) | |||
| 400 | 400 | ||
| 401 | /* send self-abort message when rejecting on a connected port */ | 401 | /* send self-abort message when rejecting on a connected port */ |
| 402 | if (msg_connected(msg)) { | 402 | if (msg_connected(msg)) { |
| 403 | struct sk_buff *abuf = NULL; | ||
| 404 | struct tipc_port *p_ptr = tipc_port_lock(msg_destport(msg)); | 403 | struct tipc_port *p_ptr = tipc_port_lock(msg_destport(msg)); |
| 405 | 404 | ||
| 406 | if (p_ptr) { | 405 | if (p_ptr) { |
| 406 | struct sk_buff *abuf = NULL; | ||
| 407 | |||
| 407 | if (p_ptr->connected) | 408 | if (p_ptr->connected) |
| 408 | abuf = port_build_self_abort_msg(p_ptr, err); | 409 | abuf = port_build_self_abort_msg(p_ptr, err); |
| 409 | tipc_port_unlock(p_ptr); | 410 | tipc_port_unlock(p_ptr); |
| 411 | tipc_net_route_msg(abuf); | ||
| 410 | } | 412 | } |
| 411 | tipc_net_route_msg(abuf); | ||
| 412 | } | 413 | } |
| 413 | 414 | ||
| 414 | /* send returned message & dispose of rejected message */ | 415 | /* send returned message & dispose of rejected message */ |
| @@ -419,7 +420,7 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err) | |||
| 419 | else | 420 | else |
| 420 | tipc_link_send(rbuf, src_node, msg_link_selector(rmsg)); | 421 | tipc_link_send(rbuf, src_node, msg_link_selector(rmsg)); |
| 421 | exit: | 422 | exit: |
| 422 | buf_discard(buf); | 423 | kfree_skb(buf); |
| 423 | return data_sz; | 424 | return data_sz; |
| 424 | } | 425 | } |
| 425 | 426 | ||
| @@ -567,7 +568,7 @@ void tipc_port_recv_proto_msg(struct sk_buff *buf) | |||
| 567 | tipc_port_unlock(p_ptr); | 568 | tipc_port_unlock(p_ptr); |
| 568 | exit: | 569 | exit: |
| 569 | tipc_net_route_msg(r_buf); | 570 | tipc_net_route_msg(r_buf); |
| 570 | buf_discard(buf); | 571 | kfree_skb(buf); |
| 571 | } | 572 | } |
| 572 | 573 | ||
| 573 | static void port_print(struct tipc_port *p_ptr, struct print_buf *buf, int full_id) | 574 | static void port_print(struct tipc_port *p_ptr, struct print_buf *buf, int full_id) |
| @@ -758,7 +759,7 @@ static void port_dispatcher_sigh(void *dummy) | |||
| 758 | } | 759 | } |
| 759 | } | 760 | } |
| 760 | if (buf) | 761 | if (buf) |
| 761 | buf_discard(buf); | 762 | kfree_skb(buf); |
| 762 | buf = next; | 763 | buf = next; |
| 763 | continue; | 764 | continue; |
| 764 | err: | 765 | err: |
| @@ -812,7 +813,7 @@ err: | |||
| 812 | } | 813 | } |
| 813 | } | 814 | } |
| 814 | if (buf) | 815 | if (buf) |
| 815 | buf_discard(buf); | 816 | kfree_skb(buf); |
| 816 | buf = next; | 817 | buf = next; |
| 817 | continue; | 818 | continue; |
| 818 | reject: | 819 | reject: |
| @@ -1053,8 +1054,6 @@ int tipc_connect2port(u32 ref, struct tipc_portid const *peer) | |||
| 1053 | msg = &p_ptr->phdr; | 1054 | msg = &p_ptr->phdr; |
| 1054 | msg_set_destnode(msg, peer->node); | 1055 | msg_set_destnode(msg, peer->node); |
| 1055 | msg_set_destport(msg, peer->ref); | 1056 | msg_set_destport(msg, peer->ref); |
| 1056 | msg_set_orignode(msg, tipc_own_addr); | ||
| 1057 | msg_set_origport(msg, p_ptr->ref); | ||
| 1058 | msg_set_type(msg, TIPC_CONN_MSG); | 1057 | msg_set_type(msg, TIPC_CONN_MSG); |
| 1059 | msg_set_lookup_scope(msg, 0); | 1058 | msg_set_lookup_scope(msg, 0); |
| 1060 | msg_set_hdr_sz(msg, SHORT_H_SIZE); | 1059 | msg_set_hdr_sz(msg, SHORT_H_SIZE); |
| @@ -1132,6 +1131,49 @@ int tipc_shutdown(u32 ref) | |||
| 1132 | return tipc_disconnect(ref); | 1131 | return tipc_disconnect(ref); |
| 1133 | } | 1132 | } |
| 1134 | 1133 | ||
| 1134 | /** | ||
| 1135 | * tipc_port_recv_msg - receive message from lower layer and deliver to port user | ||
| 1136 | */ | ||
| 1137 | |||
| 1138 | int tipc_port_recv_msg(struct sk_buff *buf) | ||
| 1139 | { | ||
| 1140 | struct tipc_port *p_ptr; | ||
| 1141 | struct tipc_msg *msg = buf_msg(buf); | ||
| 1142 | u32 destport = msg_destport(msg); | ||
| 1143 | u32 dsz = msg_data_sz(msg); | ||
| 1144 | u32 err; | ||
| 1145 | |||
| 1146 | /* forward unresolved named message */ | ||
| 1147 | if (unlikely(!destport)) { | ||
| 1148 | tipc_net_route_msg(buf); | ||
| 1149 | return dsz; | ||
| 1150 | } | ||
| 1151 | |||
| 1152 | /* validate destination & pass to port, otherwise reject message */ | ||
| 1153 | p_ptr = tipc_port_lock(destport); | ||
| 1154 | if (likely(p_ptr)) { | ||
| 1155 | if (likely(p_ptr->connected)) { | ||
| 1156 | if ((unlikely(msg_origport(msg) != | ||
| 1157 | tipc_peer_port(p_ptr))) || | ||
| 1158 | (unlikely(msg_orignode(msg) != | ||
| 1159 | tipc_peer_node(p_ptr))) || | ||
| 1160 | (unlikely(!msg_connected(msg)))) { | ||
| 1161 | err = TIPC_ERR_NO_PORT; | ||
| 1162 | tipc_port_unlock(p_ptr); | ||
| 1163 | goto reject; | ||
| 1164 | } | ||
| 1165 | } | ||
| 1166 | err = p_ptr->dispatcher(p_ptr, buf); | ||
| 1167 | tipc_port_unlock(p_ptr); | ||
| 1168 | if (likely(!err)) | ||
| 1169 | return dsz; | ||
| 1170 | } else { | ||
| 1171 | err = TIPC_ERR_NO_PORT; | ||
| 1172 | } | ||
| 1173 | reject: | ||
| 1174 | return tipc_reject_msg(buf, err); | ||
| 1175 | } | ||
| 1176 | |||
| 1135 | /* | 1177 | /* |
| 1136 | * tipc_port_recv_sections(): Concatenate and deliver sectioned | 1178 | * tipc_port_recv_sections(): Concatenate and deliver sectioned |
| 1137 | * message for this node. | 1179 | * message for this node. |
| @@ -1210,8 +1252,6 @@ int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain, | |||
| 1210 | 1252 | ||
| 1211 | msg = &p_ptr->phdr; | 1253 | msg = &p_ptr->phdr; |
| 1212 | msg_set_type(msg, TIPC_NAMED_MSG); | 1254 | msg_set_type(msg, TIPC_NAMED_MSG); |
| 1213 | msg_set_orignode(msg, tipc_own_addr); | ||
| 1214 | msg_set_origport(msg, ref); | ||
| 1215 | msg_set_hdr_sz(msg, NAMED_H_SIZE); | 1255 | msg_set_hdr_sz(msg, NAMED_H_SIZE); |
| 1216 | msg_set_nametype(msg, name->type); | 1256 | msg_set_nametype(msg, name->type); |
| 1217 | msg_set_nameinst(msg, name->instance); | 1257 | msg_set_nameinst(msg, name->instance); |
| @@ -1220,7 +1260,7 @@ int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain, | |||
| 1220 | msg_set_destnode(msg, destnode); | 1260 | msg_set_destnode(msg, destnode); |
| 1221 | msg_set_destport(msg, destport); | 1261 | msg_set_destport(msg, destport); |
| 1222 | 1262 | ||
| 1223 | if (likely(destport)) { | 1263 | if (likely(destport || destnode)) { |
| 1224 | if (likely(destnode == tipc_own_addr)) | 1264 | if (likely(destnode == tipc_own_addr)) |
| 1225 | res = tipc_port_recv_sections(p_ptr, num_sect, | 1265 | res = tipc_port_recv_sections(p_ptr, num_sect, |
| 1226 | msg_sect, total_len); | 1266 | msg_sect, total_len); |
| @@ -1261,8 +1301,6 @@ int tipc_send2port(u32 ref, struct tipc_portid const *dest, | |||
| 1261 | msg = &p_ptr->phdr; | 1301 | msg = &p_ptr->phdr; |
| 1262 | msg_set_type(msg, TIPC_DIRECT_MSG); | 1302 | msg_set_type(msg, TIPC_DIRECT_MSG); |
| 1263 | msg_set_lookup_scope(msg, 0); | 1303 | msg_set_lookup_scope(msg, 0); |
| 1264 | msg_set_orignode(msg, tipc_own_addr); | ||
| 1265 | msg_set_origport(msg, ref); | ||
| 1266 | msg_set_destnode(msg, dest->node); | 1304 | msg_set_destnode(msg, dest->node); |
| 1267 | msg_set_destport(msg, dest->ref); | 1305 | msg_set_destport(msg, dest->ref); |
| 1268 | msg_set_hdr_sz(msg, BASIC_H_SIZE); | 1306 | msg_set_hdr_sz(msg, BASIC_H_SIZE); |
| @@ -1301,8 +1339,6 @@ int tipc_send_buf2port(u32 ref, struct tipc_portid const *dest, | |||
| 1301 | 1339 | ||
| 1302 | msg = &p_ptr->phdr; | 1340 | msg = &p_ptr->phdr; |
| 1303 | msg_set_type(msg, TIPC_DIRECT_MSG); | 1341 | msg_set_type(msg, TIPC_DIRECT_MSG); |
| 1304 | msg_set_orignode(msg, tipc_own_addr); | ||
| 1305 | msg_set_origport(msg, ref); | ||
| 1306 | msg_set_destnode(msg, dest->node); | 1342 | msg_set_destnode(msg, dest->node); |
| 1307 | msg_set_destport(msg, dest->ref); | 1343 | msg_set_destport(msg, dest->ref); |
| 1308 | msg_set_hdr_sz(msg, BASIC_H_SIZE); | 1344 | msg_set_hdr_sz(msg, BASIC_H_SIZE); |
