diff options
Diffstat (limited to 'net/tipc/port.c')
| -rw-r--r-- | net/tipc/port.c | 295 |
1 files changed, 27 insertions, 268 deletions
diff --git a/net/tipc/port.c b/net/tipc/port.c index 0737680e9266..82092eaa1536 100644 --- a/net/tipc/port.c +++ b/net/tipc/port.c | |||
| @@ -293,34 +293,6 @@ int tipc_deleteport(u32 ref) | |||
| 293 | return 0; | 293 | return 0; |
| 294 | } | 294 | } |
| 295 | 295 | ||
| 296 | /** | ||
| 297 | * tipc_get_port() - return port associated with 'ref' | ||
| 298 | * | ||
| 299 | * Note: Port is not locked. | ||
| 300 | */ | ||
| 301 | |||
| 302 | struct tipc_port *tipc_get_port(const u32 ref) | ||
| 303 | { | ||
| 304 | return (struct tipc_port *)tipc_ref_deref(ref); | ||
| 305 | } | ||
| 306 | |||
| 307 | /** | ||
| 308 | * tipc_get_handle - return user handle associated to port 'ref' | ||
| 309 | */ | ||
| 310 | |||
| 311 | void *tipc_get_handle(const u32 ref) | ||
| 312 | { | ||
| 313 | struct port *p_ptr; | ||
| 314 | void * handle; | ||
| 315 | |||
| 316 | p_ptr = tipc_port_lock(ref); | ||
| 317 | if (!p_ptr) | ||
| 318 | return NULL; | ||
| 319 | handle = p_ptr->publ.usr_handle; | ||
| 320 | tipc_port_unlock(p_ptr); | ||
| 321 | return handle; | ||
| 322 | } | ||
| 323 | |||
| 324 | static int port_unreliable(struct port *p_ptr) | 296 | static int port_unreliable(struct port *p_ptr) |
| 325 | { | 297 | { |
| 326 | return msg_src_droppable(&p_ptr->publ.phdr); | 298 | return msg_src_droppable(&p_ptr->publ.phdr); |
| @@ -392,7 +364,7 @@ static struct sk_buff *port_build_proto_msg(u32 destport, u32 destnode, | |||
| 392 | struct sk_buff *buf; | 364 | struct sk_buff *buf; |
| 393 | struct tipc_msg *msg; | 365 | struct tipc_msg *msg; |
| 394 | 366 | ||
| 395 | buf = buf_acquire(LONG_H_SIZE); | 367 | buf = tipc_buf_acquire(LONG_H_SIZE); |
| 396 | if (buf) { | 368 | if (buf) { |
| 397 | msg = buf_msg(buf); | 369 | msg = buf_msg(buf); |
| 398 | tipc_msg_init(msg, usr, type, LONG_H_SIZE, destnode); | 370 | tipc_msg_init(msg, usr, type, LONG_H_SIZE, destnode); |
| @@ -433,7 +405,7 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err) | |||
| 433 | hdr_sz = MCAST_H_SIZE; | 405 | hdr_sz = MCAST_H_SIZE; |
| 434 | else | 406 | else |
| 435 | hdr_sz = LONG_H_SIZE; | 407 | hdr_sz = LONG_H_SIZE; |
| 436 | rbuf = buf_acquire(data_sz + hdr_sz); | 408 | rbuf = tipc_buf_acquire(data_sz + hdr_sz); |
| 437 | if (rbuf == NULL) { | 409 | if (rbuf == NULL) { |
| 438 | buf_discard(buf); | 410 | buf_discard(buf); |
| 439 | return data_sz; | 411 | return data_sz; |
| @@ -588,19 +560,10 @@ void tipc_port_recv_proto_msg(struct sk_buff *buf) | |||
| 588 | if (!p_ptr) { | 560 | if (!p_ptr) { |
| 589 | err = TIPC_ERR_NO_PORT; | 561 | err = TIPC_ERR_NO_PORT; |
| 590 | } else if (p_ptr->publ.connected) { | 562 | } else if (p_ptr->publ.connected) { |
| 591 | if (port_peernode(p_ptr) != msg_orignode(msg)) | 563 | if ((port_peernode(p_ptr) != msg_orignode(msg)) || |
| 564 | (port_peerport(p_ptr) != msg_origport(msg))) { | ||
| 592 | err = TIPC_ERR_NO_PORT; | 565 | err = TIPC_ERR_NO_PORT; |
| 593 | if (port_peerport(p_ptr) != msg_origport(msg)) | 566 | } else if (msg_type(msg) == CONN_ACK) { |
| 594 | err = TIPC_ERR_NO_PORT; | ||
| 595 | if (!err && msg_routed(msg)) { | ||
| 596 | u32 seqno = msg_transp_seqno(msg); | ||
| 597 | u32 myno = ++p_ptr->last_in_seqno; | ||
| 598 | if (seqno != myno) { | ||
| 599 | err = TIPC_ERR_NO_PORT; | ||
| 600 | abort_buf = port_build_self_abort_msg(p_ptr, err); | ||
| 601 | } | ||
| 602 | } | ||
| 603 | if (msg_type(msg) == CONN_ACK) { | ||
| 604 | int wakeup = tipc_port_congested(p_ptr) && | 567 | int wakeup = tipc_port_congested(p_ptr) && |
| 605 | p_ptr->publ.congested && | 568 | p_ptr->publ.congested && |
| 606 | p_ptr->wakeup; | 569 | p_ptr->wakeup; |
| @@ -719,50 +682,6 @@ struct sk_buff *tipc_port_get_ports(void) | |||
| 719 | return buf; | 682 | return buf; |
| 720 | } | 683 | } |
| 721 | 684 | ||
| 722 | #if 0 | ||
| 723 | |||
| 724 | #define MAX_PORT_STATS 2000 | ||
| 725 | |||
| 726 | struct sk_buff *port_show_stats(const void *req_tlv_area, int req_tlv_space) | ||
| 727 | { | ||
| 728 | u32 ref; | ||
| 729 | struct port *p_ptr; | ||
| 730 | struct sk_buff *buf; | ||
| 731 | struct tlv_desc *rep_tlv; | ||
| 732 | struct print_buf pb; | ||
| 733 | int str_len; | ||
| 734 | |||
| 735 | if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_PORT_REF)) | ||
| 736 | return cfg_reply_error_string(TIPC_CFG_TLV_ERROR); | ||
| 737 | |||
| 738 | ref = *(u32 *)TLV_DATA(req_tlv_area); | ||
| 739 | ref = ntohl(ref); | ||
| 740 | |||
| 741 | p_ptr = tipc_port_lock(ref); | ||
| 742 | if (!p_ptr) | ||
| 743 | return cfg_reply_error_string("port not found"); | ||
| 744 | |||
| 745 | buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_PORT_STATS)); | ||
| 746 | if (!buf) { | ||
| 747 | tipc_port_unlock(p_ptr); | ||
| 748 | return NULL; | ||
| 749 | } | ||
| 750 | rep_tlv = (struct tlv_desc *)buf->data; | ||
| 751 | |||
| 752 | tipc_printbuf_init(&pb, TLV_DATA(rep_tlv), MAX_PORT_STATS); | ||
| 753 | port_print(p_ptr, &pb, 1); | ||
| 754 | /* NEED TO FILL IN ADDITIONAL PORT STATISTICS HERE */ | ||
| 755 | tipc_port_unlock(p_ptr); | ||
| 756 | str_len = tipc_printbuf_validate(&pb); | ||
| 757 | |||
| 758 | skb_put(buf, TLV_SPACE(str_len)); | ||
| 759 | TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); | ||
| 760 | |||
| 761 | return buf; | ||
| 762 | } | ||
| 763 | |||
| 764 | #endif | ||
| 765 | |||
| 766 | void tipc_port_reinit(void) | 685 | void tipc_port_reinit(void) |
| 767 | { | 686 | { |
| 768 | struct port *p_ptr; | 687 | struct port *p_ptr; |
| @@ -1295,50 +1214,13 @@ int tipc_shutdown(u32 ref) | |||
| 1295 | return tipc_disconnect(ref); | 1214 | return tipc_disconnect(ref); |
| 1296 | } | 1215 | } |
| 1297 | 1216 | ||
| 1298 | int tipc_isconnected(u32 ref, int *isconnected) | ||
| 1299 | { | ||
| 1300 | struct port *p_ptr; | ||
| 1301 | |||
| 1302 | p_ptr = tipc_port_lock(ref); | ||
| 1303 | if (!p_ptr) | ||
| 1304 | return -EINVAL; | ||
| 1305 | *isconnected = p_ptr->publ.connected; | ||
| 1306 | tipc_port_unlock(p_ptr); | ||
| 1307 | return 0; | ||
| 1308 | } | ||
| 1309 | |||
| 1310 | int tipc_peer(u32 ref, struct tipc_portid *peer) | ||
| 1311 | { | ||
| 1312 | struct port *p_ptr; | ||
| 1313 | int res; | ||
| 1314 | |||
| 1315 | p_ptr = tipc_port_lock(ref); | ||
| 1316 | if (!p_ptr) | ||
| 1317 | return -EINVAL; | ||
| 1318 | if (p_ptr->publ.connected) { | ||
| 1319 | peer->ref = port_peerport(p_ptr); | ||
| 1320 | peer->node = port_peernode(p_ptr); | ||
| 1321 | res = 0; | ||
| 1322 | } else | ||
| 1323 | res = -ENOTCONN; | ||
| 1324 | tipc_port_unlock(p_ptr); | ||
| 1325 | return res; | ||
| 1326 | } | ||
| 1327 | |||
| 1328 | int tipc_ref_valid(u32 ref) | ||
| 1329 | { | ||
| 1330 | /* Works irrespective of type */ | ||
| 1331 | return !!tipc_ref_deref(ref); | ||
| 1332 | } | ||
| 1333 | |||
| 1334 | |||
| 1335 | /* | 1217 | /* |
| 1336 | * tipc_port_recv_sections(): Concatenate and deliver sectioned | 1218 | * tipc_port_recv_sections(): Concatenate and deliver sectioned |
| 1337 | * message for this node. | 1219 | * message for this node. |
| 1338 | */ | 1220 | */ |
| 1339 | 1221 | ||
| 1340 | int tipc_port_recv_sections(struct port *sender, unsigned int num_sect, | 1222 | static int tipc_port_recv_sections(struct port *sender, unsigned int num_sect, |
| 1341 | struct iovec const *msg_sect) | 1223 | struct iovec const *msg_sect) |
| 1342 | { | 1224 | { |
| 1343 | struct sk_buff *buf; | 1225 | struct sk_buff *buf; |
| 1344 | int res; | 1226 | int res; |
| @@ -1389,65 +1271,16 @@ int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect) | |||
| 1389 | } | 1271 | } |
| 1390 | 1272 | ||
| 1391 | /** | 1273 | /** |
| 1392 | * tipc_send_buf - send message buffer on connection | ||
| 1393 | */ | ||
| 1394 | |||
| 1395 | int tipc_send_buf(u32 ref, struct sk_buff *buf, unsigned int dsz) | ||
| 1396 | { | ||
| 1397 | struct port *p_ptr; | ||
| 1398 | struct tipc_msg *msg; | ||
| 1399 | u32 destnode; | ||
| 1400 | u32 hsz; | ||
| 1401 | u32 sz; | ||
| 1402 | u32 res; | ||
| 1403 | |||
| 1404 | p_ptr = tipc_port_deref(ref); | ||
| 1405 | if (!p_ptr || !p_ptr->publ.connected) | ||
| 1406 | return -EINVAL; | ||
| 1407 | |||
| 1408 | msg = &p_ptr->publ.phdr; | ||
| 1409 | hsz = msg_hdr_sz(msg); | ||
| 1410 | sz = hsz + dsz; | ||
| 1411 | msg_set_size(msg, sz); | ||
| 1412 | if (skb_cow(buf, hsz)) | ||
| 1413 | return -ENOMEM; | ||
| 1414 | |||
| 1415 | skb_push(buf, hsz); | ||
| 1416 | skb_copy_to_linear_data(buf, msg, hsz); | ||
| 1417 | destnode = msg_destnode(msg); | ||
| 1418 | p_ptr->publ.congested = 1; | ||
| 1419 | if (!tipc_port_congested(p_ptr)) { | ||
| 1420 | if (likely(destnode != tipc_own_addr)) | ||
| 1421 | res = tipc_send_buf_fast(buf, destnode); | ||
| 1422 | else { | ||
| 1423 | tipc_port_recv_msg(buf); | ||
| 1424 | res = sz; | ||
| 1425 | } | ||
| 1426 | if (likely(res != -ELINKCONG)) { | ||
| 1427 | port_incr_out_seqno(p_ptr); | ||
| 1428 | p_ptr->sent++; | ||
| 1429 | p_ptr->publ.congested = 0; | ||
| 1430 | return res; | ||
| 1431 | } | ||
| 1432 | } | ||
| 1433 | if (port_unreliable(p_ptr)) { | ||
| 1434 | p_ptr->publ.congested = 0; | ||
| 1435 | return dsz; | ||
| 1436 | } | ||
| 1437 | return -ELINKCONG; | ||
| 1438 | } | ||
| 1439 | |||
| 1440 | /** | ||
| 1441 | * tipc_forward2name - forward message sections to port name | 1274 | * tipc_forward2name - forward message sections to port name |
| 1442 | */ | 1275 | */ |
| 1443 | 1276 | ||
| 1444 | int tipc_forward2name(u32 ref, | 1277 | static int tipc_forward2name(u32 ref, |
| 1445 | struct tipc_name const *name, | 1278 | struct tipc_name const *name, |
| 1446 | u32 domain, | 1279 | u32 domain, |
| 1447 | u32 num_sect, | 1280 | u32 num_sect, |
| 1448 | struct iovec const *msg_sect, | 1281 | struct iovec const *msg_sect, |
| 1449 | struct tipc_portid const *orig, | 1282 | struct tipc_portid const *orig, |
| 1450 | unsigned int importance) | 1283 | unsigned int importance) |
| 1451 | { | 1284 | { |
| 1452 | struct port *p_ptr; | 1285 | struct port *p_ptr; |
| 1453 | struct tipc_msg *msg; | 1286 | struct tipc_msg *msg; |
| @@ -1473,7 +1306,7 @@ int tipc_forward2name(u32 ref, | |||
| 1473 | msg_set_destnode(msg, destnode); | 1306 | msg_set_destnode(msg, destnode); |
| 1474 | msg_set_destport(msg, destport); | 1307 | msg_set_destport(msg, destport); |
| 1475 | 1308 | ||
| 1476 | if (likely(destport || destnode)) { | 1309 | if (likely(destport)) { |
| 1477 | p_ptr->sent++; | 1310 | p_ptr->sent++; |
| 1478 | if (likely(destnode == tipc_own_addr)) | 1311 | if (likely(destnode == tipc_own_addr)) |
| 1479 | return tipc_port_recv_sections(p_ptr, num_sect, msg_sect); | 1312 | return tipc_port_recv_sections(p_ptr, num_sect, msg_sect); |
| @@ -1510,89 +1343,15 @@ int tipc_send2name(u32 ref, | |||
| 1510 | } | 1343 | } |
| 1511 | 1344 | ||
| 1512 | /** | 1345 | /** |
| 1513 | * tipc_forward_buf2name - forward message buffer to port name | ||
| 1514 | */ | ||
| 1515 | |||
| 1516 | int tipc_forward_buf2name(u32 ref, | ||
| 1517 | struct tipc_name const *name, | ||
| 1518 | u32 domain, | ||
| 1519 | struct sk_buff *buf, | ||
| 1520 | unsigned int dsz, | ||
| 1521 | struct tipc_portid const *orig, | ||
| 1522 | unsigned int importance) | ||
| 1523 | { | ||
| 1524 | struct port *p_ptr; | ||
| 1525 | struct tipc_msg *msg; | ||
| 1526 | u32 destnode = domain; | ||
| 1527 | u32 destport; | ||
| 1528 | int res; | ||
| 1529 | |||
| 1530 | p_ptr = (struct port *)tipc_ref_deref(ref); | ||
| 1531 | if (!p_ptr || p_ptr->publ.connected) | ||
| 1532 | return -EINVAL; | ||
| 1533 | |||
| 1534 | msg = &p_ptr->publ.phdr; | ||
| 1535 | if (importance <= TIPC_CRITICAL_IMPORTANCE) | ||
| 1536 | msg_set_importance(msg, importance); | ||
| 1537 | msg_set_type(msg, TIPC_NAMED_MSG); | ||
| 1538 | msg_set_orignode(msg, orig->node); | ||
| 1539 | msg_set_origport(msg, orig->ref); | ||
| 1540 | msg_set_nametype(msg, name->type); | ||
| 1541 | msg_set_nameinst(msg, name->instance); | ||
| 1542 | msg_set_lookup_scope(msg, tipc_addr_scope(domain)); | ||
| 1543 | msg_set_hdr_sz(msg, LONG_H_SIZE); | ||
| 1544 | msg_set_size(msg, LONG_H_SIZE + dsz); | ||
| 1545 | destport = tipc_nametbl_translate(name->type, name->instance, &destnode); | ||
| 1546 | msg_set_destnode(msg, destnode); | ||
| 1547 | msg_set_destport(msg, destport); | ||
| 1548 | msg_dbg(msg, "forw2name ==> "); | ||
| 1549 | if (skb_cow(buf, LONG_H_SIZE)) | ||
| 1550 | return -ENOMEM; | ||
| 1551 | skb_push(buf, LONG_H_SIZE); | ||
| 1552 | skb_copy_to_linear_data(buf, msg, LONG_H_SIZE); | ||
| 1553 | msg_dbg(buf_msg(buf),"PREP:"); | ||
| 1554 | if (likely(destport || destnode)) { | ||
| 1555 | p_ptr->sent++; | ||
| 1556 | if (destnode == tipc_own_addr) | ||
| 1557 | return tipc_port_recv_msg(buf); | ||
| 1558 | res = tipc_send_buf_fast(buf, destnode); | ||
| 1559 | if (likely(res != -ELINKCONG)) | ||
| 1560 | return res; | ||
| 1561 | if (port_unreliable(p_ptr)) | ||
| 1562 | return dsz; | ||
| 1563 | return -ELINKCONG; | ||
| 1564 | } | ||
| 1565 | return tipc_reject_msg(buf, TIPC_ERR_NO_NAME); | ||
| 1566 | } | ||
| 1567 | |||
| 1568 | /** | ||
| 1569 | * tipc_send_buf2name - send message buffer to port name | ||
| 1570 | */ | ||
| 1571 | |||
| 1572 | int tipc_send_buf2name(u32 ref, | ||
| 1573 | struct tipc_name const *dest, | ||
| 1574 | u32 domain, | ||
| 1575 | struct sk_buff *buf, | ||
| 1576 | unsigned int dsz) | ||
| 1577 | { | ||
| 1578 | struct tipc_portid orig; | ||
| 1579 | |||
| 1580 | orig.ref = ref; | ||
| 1581 | orig.node = tipc_own_addr; | ||
| 1582 | return tipc_forward_buf2name(ref, dest, domain, buf, dsz, &orig, | ||
| 1583 | TIPC_PORT_IMPORTANCE); | ||
| 1584 | } | ||
| 1585 | |||
| 1586 | /** | ||
| 1587 | * tipc_forward2port - forward message sections to port identity | 1346 | * tipc_forward2port - forward message sections to port identity |
| 1588 | */ | 1347 | */ |
| 1589 | 1348 | ||
| 1590 | int tipc_forward2port(u32 ref, | 1349 | static int tipc_forward2port(u32 ref, |
| 1591 | struct tipc_portid const *dest, | 1350 | struct tipc_portid const *dest, |
| 1592 | unsigned int num_sect, | 1351 | unsigned int num_sect, |
| 1593 | struct iovec const *msg_sect, | 1352 | struct iovec const *msg_sect, |
| 1594 | struct tipc_portid const *orig, | 1353 | struct tipc_portid const *orig, |
| 1595 | unsigned int importance) | 1354 | unsigned int importance) |
| 1596 | { | 1355 | { |
| 1597 | struct port *p_ptr; | 1356 | struct port *p_ptr; |
| 1598 | struct tipc_msg *msg; | 1357 | struct tipc_msg *msg; |
| @@ -1644,12 +1403,12 @@ int tipc_send2port(u32 ref, | |||
| 1644 | /** | 1403 | /** |
| 1645 | * tipc_forward_buf2port - forward message buffer to port identity | 1404 | * tipc_forward_buf2port - forward message buffer to port identity |
| 1646 | */ | 1405 | */ |
| 1647 | int tipc_forward_buf2port(u32 ref, | 1406 | static int tipc_forward_buf2port(u32 ref, |
| 1648 | struct tipc_portid const *dest, | 1407 | struct tipc_portid const *dest, |
| 1649 | struct sk_buff *buf, | 1408 | struct sk_buff *buf, |
| 1650 | unsigned int dsz, | 1409 | unsigned int dsz, |
| 1651 | struct tipc_portid const *orig, | 1410 | struct tipc_portid const *orig, |
| 1652 | unsigned int importance) | 1411 | unsigned int importance) |
| 1653 | { | 1412 | { |
| 1654 | struct port *p_ptr; | 1413 | struct port *p_ptr; |
| 1655 | struct tipc_msg *msg; | 1414 | struct tipc_msg *msg; |
