diff options
Diffstat (limited to 'net/tipc')
-rw-r--r-- | net/tipc/bcast.c | 49 | ||||
-rw-r--r-- | net/tipc/bcast.h | 24 | ||||
-rw-r--r-- | net/tipc/name_table.c | 44 | ||||
-rw-r--r-- | net/tipc/name_table.h | 18 | ||||
-rw-r--r-- | net/tipc/socket.c | 48 | ||||
-rw-r--r-- | net/tipc/socket.h | 2 |
6 files changed, 84 insertions, 101 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index 2dfaf272928a..3eaa931e2e8c 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * net/tipc/bcast.c: TIPC broadcast code | 2 | * net/tipc/bcast.c: TIPC broadcast code |
3 | * | 3 | * |
4 | * Copyright (c) 2004-2006, 2014, Ericsson AB | 4 | * Copyright (c) 2004-2006, 2014-2015, Ericsson AB |
5 | * Copyright (c) 2004, Intel Corporation. | 5 | * Copyright (c) 2004, Intel Corporation. |
6 | * Copyright (c) 2005, 2010-2011, Wind River Systems | 6 | * Copyright (c) 2005, 2010-2011, Wind River Systems |
7 | * All rights reserved. | 7 | * All rights reserved. |
@@ -1037,50 +1037,3 @@ static void tipc_nmap_diff(struct tipc_node_map *nm_a, | |||
1037 | } | 1037 | } |
1038 | } | 1038 | } |
1039 | } | 1039 | } |
1040 | |||
1041 | /** | ||
1042 | * tipc_port_list_add - add a port to a port list, ensuring no duplicates | ||
1043 | */ | ||
1044 | void tipc_port_list_add(struct tipc_port_list *pl_ptr, u32 port) | ||
1045 | { | ||
1046 | struct tipc_port_list *item = pl_ptr; | ||
1047 | int i; | ||
1048 | int item_sz = PLSIZE; | ||
1049 | int cnt = pl_ptr->count; | ||
1050 | |||
1051 | for (; ; cnt -= item_sz, item = item->next) { | ||
1052 | if (cnt < PLSIZE) | ||
1053 | item_sz = cnt; | ||
1054 | for (i = 0; i < item_sz; i++) | ||
1055 | if (item->ports[i] == port) | ||
1056 | return; | ||
1057 | if (i < PLSIZE) { | ||
1058 | item->ports[i] = port; | ||
1059 | pl_ptr->count++; | ||
1060 | return; | ||
1061 | } | ||
1062 | if (!item->next) { | ||
1063 | item->next = kmalloc(sizeof(*item), GFP_ATOMIC); | ||
1064 | if (!item->next) { | ||
1065 | pr_warn("Incomplete multicast delivery, no memory\n"); | ||
1066 | return; | ||
1067 | } | ||
1068 | item->next->next = NULL; | ||
1069 | } | ||
1070 | } | ||
1071 | } | ||
1072 | |||
1073 | /** | ||
1074 | * tipc_port_list_free - free dynamically created entries in port_list chain | ||
1075 | * | ||
1076 | */ | ||
1077 | void tipc_port_list_free(struct tipc_port_list *pl_ptr) | ||
1078 | { | ||
1079 | struct tipc_port_list *item; | ||
1080 | struct tipc_port_list *next; | ||
1081 | |||
1082 | for (item = pl_ptr->next; item; item = next) { | ||
1083 | next = item->next; | ||
1084 | kfree(item); | ||
1085 | } | ||
1086 | } | ||
diff --git a/net/tipc/bcast.h b/net/tipc/bcast.h index 6ea190dccfe1..8f4d4dc38e11 100644 --- a/net/tipc/bcast.h +++ b/net/tipc/bcast.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * net/tipc/bcast.h: Include file for TIPC broadcast code | 2 | * net/tipc/bcast.h: Include file for TIPC broadcast code |
3 | * | 3 | * |
4 | * Copyright (c) 2003-2006, 2014, Ericsson AB | 4 | * Copyright (c) 2003-2006, 2014-2015, Ericsson AB |
5 | * Copyright (c) 2005, 2010-2011, Wind River Systems | 5 | * Copyright (c) 2005, 2010-2011, Wind River Systems |
6 | * All rights reserved. | 6 | * All rights reserved. |
7 | * | 7 | * |
@@ -41,22 +41,6 @@ | |||
41 | #include "link.h" | 41 | #include "link.h" |
42 | #include "node.h" | 42 | #include "node.h" |
43 | 43 | ||
44 | #define TIPC_BCLINK_RESET 1 | ||
45 | #define PLSIZE 32 | ||
46 | #define BCBEARER MAX_BEARERS | ||
47 | |||
48 | /** | ||
49 | * struct tipc_port_list - set of node local destination ports | ||
50 | * @count: # of ports in set (only valid for first entry in list) | ||
51 | * @next: pointer to next entry in list | ||
52 | * @ports: array of port references | ||
53 | */ | ||
54 | struct tipc_port_list { | ||
55 | int count; | ||
56 | struct tipc_port_list *next; | ||
57 | u32 ports[PLSIZE]; | ||
58 | }; | ||
59 | |||
60 | /** | 44 | /** |
61 | * struct tipc_bcbearer_pair - a pair of bearers used by broadcast link | 45 | * struct tipc_bcbearer_pair - a pair of bearers used by broadcast link |
62 | * @primary: pointer to primary bearer | 46 | * @primary: pointer to primary bearer |
@@ -71,6 +55,9 @@ struct tipc_bcbearer_pair { | |||
71 | struct tipc_bearer *secondary; | 55 | struct tipc_bearer *secondary; |
72 | }; | 56 | }; |
73 | 57 | ||
58 | #define TIPC_BCLINK_RESET 1 | ||
59 | #define BCBEARER MAX_BEARERS | ||
60 | |||
74 | /** | 61 | /** |
75 | * struct tipc_bcbearer - bearer used by broadcast link | 62 | * struct tipc_bcbearer - bearer used by broadcast link |
76 | * @bearer: (non-standard) broadcast bearer structure | 63 | * @bearer: (non-standard) broadcast bearer structure |
@@ -126,9 +113,6 @@ static inline int tipc_nmap_equal(struct tipc_node_map *nm_a, | |||
126 | return !memcmp(nm_a, nm_b, sizeof(*nm_a)); | 113 | return !memcmp(nm_a, nm_b, sizeof(*nm_a)); |
127 | } | 114 | } |
128 | 115 | ||
129 | void tipc_port_list_add(struct tipc_port_list *pl_ptr, u32 port); | ||
130 | void tipc_port_list_free(struct tipc_port_list *pl_ptr); | ||
131 | |||
132 | int tipc_bclink_init(struct net *net); | 116 | int tipc_bclink_init(struct net *net); |
133 | void tipc_bclink_stop(struct net *net); | 117 | void tipc_bclink_stop(struct net *net); |
134 | void tipc_bclink_set_flags(struct net *tn, unsigned int flags); | 118 | void tipc_bclink_set_flags(struct net *tn, unsigned int flags); |
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index ce09b863528c..18a3d44238bc 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * net/tipc/name_table.c: TIPC name table code | 2 | * net/tipc/name_table.c: TIPC name table code |
3 | * | 3 | * |
4 | * Copyright (c) 2000-2006, 2014, Ericsson AB | 4 | * Copyright (c) 2000-2006, 2014-2015, Ericsson AB |
5 | * Copyright (c) 2004-2008, 2010-2014, Wind River Systems | 5 | * Copyright (c) 2004-2008, 2010-2014, Wind River Systems |
6 | * All rights reserved. | 6 | * All rights reserved. |
7 | * | 7 | * |
@@ -618,7 +618,7 @@ not_found: | |||
618 | * Returns non-zero if any off-node ports overlap | 618 | * Returns non-zero if any off-node ports overlap |
619 | */ | 619 | */ |
620 | int tipc_nametbl_mc_translate(struct net *net, u32 type, u32 lower, u32 upper, | 620 | int tipc_nametbl_mc_translate(struct net *net, u32 type, u32 lower, u32 upper, |
621 | u32 limit, struct tipc_port_list *dports) | 621 | u32 limit, struct tipc_plist *dports) |
622 | { | 622 | { |
623 | struct name_seq *seq; | 623 | struct name_seq *seq; |
624 | struct sub_seq *sseq; | 624 | struct sub_seq *sseq; |
@@ -643,7 +643,7 @@ int tipc_nametbl_mc_translate(struct net *net, u32 type, u32 lower, u32 upper, | |||
643 | info = sseq->info; | 643 | info = sseq->info; |
644 | list_for_each_entry(publ, &info->node_list, node_list) { | 644 | list_for_each_entry(publ, &info->node_list, node_list) { |
645 | if (publ->scope <= limit) | 645 | if (publ->scope <= limit) |
646 | tipc_port_list_add(dports, publ->ref); | 646 | tipc_plist_push(dports, publ->ref); |
647 | } | 647 | } |
648 | 648 | ||
649 | if (info->cluster_list_size != info->node_list_size) | 649 | if (info->cluster_list_size != info->node_list_size) |
@@ -1212,3 +1212,41 @@ int tipc_nl_name_table_dump(struct sk_buff *skb, struct netlink_callback *cb) | |||
1212 | 1212 | ||
1213 | return skb->len; | 1213 | return skb->len; |
1214 | } | 1214 | } |
1215 | |||
1216 | void tipc_plist_push(struct tipc_plist *pl, u32 port) | ||
1217 | { | ||
1218 | struct tipc_plist *nl; | ||
1219 | |||
1220 | if (likely(!pl->port)) { | ||
1221 | pl->port = port; | ||
1222 | return; | ||
1223 | } | ||
1224 | if (pl->port == port) | ||
1225 | return; | ||
1226 | list_for_each_entry(nl, &pl->list, list) { | ||
1227 | if (nl->port == port) | ||
1228 | return; | ||
1229 | } | ||
1230 | nl = kmalloc(sizeof(*nl), GFP_ATOMIC); | ||
1231 | if (nl) { | ||
1232 | nl->port = port; | ||
1233 | list_add(&nl->list, &pl->list); | ||
1234 | } | ||
1235 | } | ||
1236 | |||
1237 | u32 tipc_plist_pop(struct tipc_plist *pl) | ||
1238 | { | ||
1239 | struct tipc_plist *nl; | ||
1240 | u32 port = 0; | ||
1241 | |||
1242 | if (likely(list_empty(&pl->list))) { | ||
1243 | port = pl->port; | ||
1244 | pl->port = 0; | ||
1245 | return port; | ||
1246 | } | ||
1247 | nl = list_first_entry(&pl->list, typeof(*nl), list); | ||
1248 | port = nl->port; | ||
1249 | list_del(&nl->list); | ||
1250 | kfree(nl); | ||
1251 | return port; | ||
1252 | } | ||
diff --git a/net/tipc/name_table.h b/net/tipc/name_table.h index f67b3d8d4b2f..52501fdaafa5 100644 --- a/net/tipc/name_table.h +++ b/net/tipc/name_table.h | |||
@@ -38,7 +38,7 @@ | |||
38 | #define _TIPC_NAME_TABLE_H | 38 | #define _TIPC_NAME_TABLE_H |
39 | 39 | ||
40 | struct tipc_subscription; | 40 | struct tipc_subscription; |
41 | struct tipc_port_list; | 41 | struct tipc_plist; |
42 | 42 | ||
43 | /* | 43 | /* |
44 | * TIPC name types reserved for internal TIPC use (both current and planned) | 44 | * TIPC name types reserved for internal TIPC use (both current and planned) |
@@ -101,7 +101,7 @@ struct sk_buff *tipc_nametbl_get(struct net *net, const void *req_tlv_area, | |||
101 | int req_tlv_space); | 101 | int req_tlv_space); |
102 | u32 tipc_nametbl_translate(struct net *net, u32 type, u32 instance, u32 *node); | 102 | u32 tipc_nametbl_translate(struct net *net, u32 type, u32 instance, u32 *node); |
103 | int tipc_nametbl_mc_translate(struct net *net, u32 type, u32 lower, u32 upper, | 103 | int tipc_nametbl_mc_translate(struct net *net, u32 type, u32 lower, u32 upper, |
104 | u32 limit, struct tipc_port_list *dports); | 104 | u32 limit, struct tipc_plist *dports); |
105 | struct publication *tipc_nametbl_publish(struct net *net, u32 type, u32 lower, | 105 | struct publication *tipc_nametbl_publish(struct net *net, u32 type, u32 lower, |
106 | u32 upper, u32 scope, u32 port_ref, | 106 | u32 upper, u32 scope, u32 port_ref, |
107 | u32 key); | 107 | u32 key); |
@@ -118,4 +118,18 @@ void tipc_nametbl_unsubscribe(struct tipc_subscription *s); | |||
118 | int tipc_nametbl_init(struct net *net); | 118 | int tipc_nametbl_init(struct net *net); |
119 | void tipc_nametbl_stop(struct net *net); | 119 | void tipc_nametbl_stop(struct net *net); |
120 | 120 | ||
121 | struct tipc_plist { | ||
122 | struct list_head list; | ||
123 | u32 port; | ||
124 | }; | ||
125 | |||
126 | static inline void tipc_plist_init(struct tipc_plist *pl) | ||
127 | { | ||
128 | INIT_LIST_HEAD(&pl->list); | ||
129 | pl->port = 0; | ||
130 | } | ||
131 | |||
132 | void tipc_plist_push(struct tipc_plist *pl, u32 port); | ||
133 | u32 tipc_plist_pop(struct tipc_plist *pl); | ||
134 | |||
121 | #endif | 135 | #endif |
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index c1a4611649ab..26aec8414ac1 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * net/tipc/socket.c: TIPC socket API | 2 | * net/tipc/socket.c: TIPC socket API |
3 | * | 3 | * |
4 | * Copyright (c) 2001-2007, 2012-2014, Ericsson AB | 4 | * Copyright (c) 2001-2007, 2012-2015, Ericsson AB |
5 | * Copyright (c) 2004-2008, 2010-2013, Wind River Systems | 5 | * Copyright (c) 2004-2008, 2010-2013, Wind River Systems |
6 | * All rights reserved. | 6 | * All rights reserved. |
7 | * | 7 | * |
@@ -778,48 +778,42 @@ new_mtu: | |||
778 | 778 | ||
779 | /* tipc_sk_mcast_rcv - Deliver multicast message to all destination sockets | 779 | /* tipc_sk_mcast_rcv - Deliver multicast message to all destination sockets |
780 | */ | 780 | */ |
781 | void tipc_sk_mcast_rcv(struct net *net, struct sk_buff *buf) | 781 | void tipc_sk_mcast_rcv(struct net *net, struct sk_buff *skb) |
782 | { | 782 | { |
783 | struct tipc_msg *msg = buf_msg(buf); | 783 | struct tipc_msg *msg = buf_msg(skb); |
784 | struct tipc_port_list dports = {0, NULL, }; | 784 | struct tipc_plist dports; |
785 | struct tipc_port_list *item; | 785 | struct sk_buff *cskb; |
786 | struct sk_buff *b; | 786 | u32 portid; |
787 | uint i, last, dst = 0; | ||
788 | u32 scope = TIPC_CLUSTER_SCOPE; | 787 | u32 scope = TIPC_CLUSTER_SCOPE; |
789 | struct sk_buff_head msgs; | 788 | struct sk_buff_head msgq; |
789 | uint hsz = skb_headroom(skb) + msg_hdr_sz(msg); | ||
790 | |||
791 | skb_queue_head_init(&msgq); | ||
792 | tipc_plist_init(&dports); | ||
790 | 793 | ||
791 | if (in_own_node(net, msg_orignode(msg))) | 794 | if (in_own_node(net, msg_orignode(msg))) |
792 | scope = TIPC_NODE_SCOPE; | 795 | scope = TIPC_NODE_SCOPE; |
793 | 796 | ||
794 | if (unlikely(!msg_mcast(msg))) { | 797 | if (unlikely(!msg_mcast(msg))) { |
795 | pr_warn("Received non-multicast msg in multicast\n"); | 798 | pr_warn("Received non-multicast msg in multicast\n"); |
796 | kfree_skb(buf); | ||
797 | goto exit; | 799 | goto exit; |
798 | } | 800 | } |
799 | /* Create destination port list: */ | 801 | /* Create destination port list: */ |
800 | tipc_nametbl_mc_translate(net, msg_nametype(msg), msg_namelower(msg), | 802 | tipc_nametbl_mc_translate(net, msg_nametype(msg), msg_namelower(msg), |
801 | msg_nameupper(msg), scope, &dports); | 803 | msg_nameupper(msg), scope, &dports); |
802 | last = dports.count; | 804 | portid = tipc_plist_pop(&dports); |
803 | if (!last) { | 805 | for (; portid; portid = tipc_plist_pop(&dports)) { |
804 | kfree_skb(buf); | 806 | cskb = __pskb_copy(skb, hsz, GFP_ATOMIC); |
805 | return; | 807 | if (!cskb) { |
806 | } | 808 | pr_warn("Failed do clone mcast rcv buffer\n"); |
807 | 809 | continue; | |
808 | for (item = &dports; item; item = item->next) { | ||
809 | for (i = 0; i < PLSIZE && ++dst <= last; i++) { | ||
810 | b = (dst != last) ? skb_clone(buf, GFP_ATOMIC) : buf; | ||
811 | if (!b) { | ||
812 | pr_warn("Failed do clone mcast rcv buffer\n"); | ||
813 | continue; | ||
814 | } | ||
815 | msg_set_destport(msg, item->ports[i]); | ||
816 | skb_queue_head_init(&msgs); | ||
817 | skb_queue_tail(&msgs, b); | ||
818 | tipc_sk_rcv(net, &msgs); | ||
819 | } | 810 | } |
811 | msg_set_destport(buf_msg(cskb), portid); | ||
812 | skb_queue_tail(&msgq, cskb); | ||
820 | } | 813 | } |
814 | tipc_sk_rcv(net, &msgq); | ||
821 | exit: | 815 | exit: |
822 | tipc_port_list_free(&dports); | 816 | kfree_skb(skb); |
823 | } | 817 | } |
824 | 818 | ||
825 | /** | 819 | /** |
diff --git a/net/tipc/socket.h b/net/tipc/socket.h index e3dbdc0e1be7..95b015909ac1 100644 --- a/net/tipc/socket.h +++ b/net/tipc/socket.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* net/tipc/socket.h: Include file for TIPC socket code | 1 | /* net/tipc/socket.h: Include file for TIPC socket code |
2 | * | 2 | * |
3 | * Copyright (c) 2014, Ericsson AB | 3 | * Copyright (c) 2014-2015, Ericsson AB |
4 | * All rights reserved. | 4 | * All rights reserved. |
5 | * | 5 | * |
6 | * Redistribution and use in source and binary forms, with or without | 6 | * Redistribution and use in source and binary forms, with or without |