Skip to content

Commit

Permalink
Merge branch 'tipc-comm-groups'
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
David S. Miller committed Oct 13, 2017
2 parents 2d0d21c + 04d7b57 commit a00344b
Show file tree
Hide file tree
Showing 16 changed files with 1,997 additions and 283 deletions.
15 changes: 15 additions & 0 deletions include/uapi/linux/tipc.h
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,21 @@ struct sockaddr_tipc {
#define TIPC_SOCK_RECVQ_DEPTH 132 /* Default: none (read only) */
#define TIPC_MCAST_BROADCAST 133 /* Default: TIPC selects. No arg */
#define TIPC_MCAST_REPLICAST 134 /* Default: TIPC selects. No arg */
#define TIPC_GROUP_JOIN 135 /* Takes struct tipc_group_req* */
#define TIPC_GROUP_LEAVE 136 /* No argument */

/*
* Flag values
*/
#define TIPC_GROUP_LOOPBACK 0x1 /* Receive copy of sent msg when match */
#define TIPC_GROUP_MEMBER_EVTS 0x2 /* Receive membership events in socket */

struct tipc_group_req {
__u32 type; /* group id */
__u32 instance; /* member id */
__u32 scope; /* zone/cluster/node */
__u32 flags;
};

/*
* Maximum sizes of TIPC bearer-related names (including terminating NULL)
Expand Down
2 changes: 1 addition & 1 deletion net/tipc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ tipc-y += addr.o bcast.o bearer.o \
core.o link.o discover.o msg.o \
name_distr.o subscr.o monitor.o name_table.o net.o \
netlink.o netlink_compat.o node.o socket.o eth_media.o \
server.o socket.o
server.o socket.o group.o

tipc-$(CONFIG_TIPC_MEDIA_UDP) += udp_media.o
tipc-$(CONFIG_TIPC_MEDIA_IB) += ib_media.o
Expand Down
18 changes: 9 additions & 9 deletions net/tipc/bcast.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -554,21 +554,21 @@ 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++;
}

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;
}
5 changes: 5 additions & 0 deletions net/tipc/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,11 @@ static inline struct list_head *tipc_nodes(struct net *net)
return &tipc_net(net)->node_list;
}

static inline struct tipc_server *tipc_topsrv(struct net *net)
{
return tipc_net(net)->topsrv;
}

static inline unsigned int tipc_hashfn(u32 addr)
{
return addr & (NODE_HTABLE_SIZE - 1);
Expand Down
Loading

0 comments on commit a00344b

Please sign in to comment.