diff options
| author | David S. Miller <davem@davemloft.net> | 2017-10-13 08:46:01 -0700 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2017-10-13 08:46:01 -0700 |
| commit | a00344bd1bbea2ba40719ae0eb3b6da7fae08cf2 (patch) | |
| tree | 3224d16251675b877b9a7d7b94420de7bbd36a9e /net/tipc/bcast.c | |
| parent | 2d0d21c12dfa3851620f1fa9fe2d444538f1fad4 (diff) | |
| parent | 04d7b574b245c66001a33cb9da2c0311063af73f (diff) | |
Merge branch 'tipc-comm-groups'
Jon Maloy says:
====================
tipc: Introduce Communcation Group feature
With this commit series we introduce a 'Group Communication' feature in
order to resolve the datagram and multicast flow control problem. This
new feature makes it possible for a user to instantiate multiple private
virtual brokerless message buses by just creating and joining member
sockets.
The main features are as follows:
---------------------------------
- Sockets can join a group via a new setsockopt() call TIPC_GROUP_JOIN.
If it is the first socket of the group this implies creation of the
group. This call takes four parameters: 'type' serves as group
identifier, 'instance' serves as member identifier, and 'scope'
indicates the visibility of the group (node/cluster/zone). Finally,
'flags' indicates different options for the socket joining the group.
For the time being, there are only two such flags: 1) 'LOOPBACK'
indicates if the creator of the socket wants to receive a copy of
broadcast or multicast messages it sends to the group, 2) EVENTS
indicates if it wants to receive membership (JOINED/LEFT) events for
the other members of the group.
- Groups are closed, i.e., sockets which have not joined a group will
not be able to send messages to or receive messages from members of
the group, and vice versa. A socket can only be member of one group
at a time.
- There are four transmission modes.
1: Unicast. The sender transmits a message using the port identity
(node:port tuple) of the receiving socket.
2: Anycast. The sender transmits a message using a port name (type:
instance:scope) of one of the receiving sockets. If more than
one member socket matches the given address a destination is
selected according to a round-robin algorithm, but also considering
the destination load (advertised window size) as an additional
criteria.
3: Multicast. The sender transmits a message using a port name
(type:instance:scope) of one or more of the receiving sockets.
All sockets in the group matching the given address will receive
a copy of the message.
4: Broadcast. The sender transmits a message using the primtive
send(). All members of the group, irrespective of their member
identity (instance) number receive a copy of the message.
- TIPC broadcast is used for carrying messages in mode 3 or 4 when
this is deemed more efficient, i.e., depending on number of actual
destinations.
- All transmission modes are flow controlled, so that messages never
are dropped or rejected, just like we are used to from connection
oriented communication. A special algorithm guarantees that this is
true even for multipoint-to-point communication, i.e., at occasions
where many source sockets may decide to send simultaneously towards
the same destination socket.
- Sequence order is always guaranteed, even between the different
transmission modes.
- Member join/leave events are received in all other member sockets
in guaranteed order. I.e., a 'JOINED' (an empty message with the OOB
bit set) will always be received before the first data message from
a new member, and a 'LEAVE' (like 'JOINED', but with EOR bit set) will
always arrive after the last data message from a leaving member.
-----
v2: Reordered variable declarations in descending length order, as per
feedback from David Miller. This was done as far as permitted by the
the initialization order.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/bcast.c')
| -rw-r--r-- | net/tipc/bcast.c | 18 |
1 files changed, 9 insertions, 9 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index a140dd4a84af..329325bd553e 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c @@ -258,20 +258,20 @@ static int tipc_bcast_xmit(struct net *net, struct sk_buff_head *pkts, static int tipc_rcast_xmit(struct net *net, struct sk_buff_head *pkts, struct tipc_nlist *dests, u16 *cong_link_cnt) { + struct tipc_dest *dst, *tmp; struct sk_buff_head _pkts; - struct u32_item *n, *tmp; - u32 dst, selector; + u32 dnode, selector; selector = msg_link_selector(buf_msg(skb_peek(pkts))); skb_queue_head_init(&_pkts); - list_for_each_entry_safe(n, tmp, &dests->list, list) { - dst = n->value; - if (!tipc_msg_pskb_copy(dst, pkts, &_pkts)) + list_for_each_entry_safe(dst, tmp, &dests->list, list) { + dnode = dst->node; + if (!tipc_msg_pskb_copy(dnode, pkts, &_pkts)) return -ENOMEM; /* Any other return value than -ELINKCONG is ignored */ - if (tipc_node_xmit(net, &_pkts, dst, selector) == -ELINKCONG) + if (tipc_node_xmit(net, &_pkts, dnode, selector) == -ELINKCONG) (*cong_link_cnt)++; } return 0; @@ -554,7 +554,7 @@ void tipc_nlist_add(struct tipc_nlist *nl, u32 node) { if (node == nl->self) nl->local = true; - else if (u32_push(&nl->list, node)) + else if (tipc_dest_push(&nl->list, node, 0)) nl->remote++; } @@ -562,13 +562,13 @@ void tipc_nlist_del(struct tipc_nlist *nl, u32 node) { if (node == nl->self) nl->local = false; - else if (u32_del(&nl->list, node)) + else if (tipc_dest_del(&nl->list, node, 0)) nl->remote--; } void tipc_nlist_purge(struct tipc_nlist *nl) { - u32_list_purge(&nl->list); + tipc_dest_list_purge(&nl->list); nl->remote = 0; nl->local = 0; } |
