Commit 75da2163 authored by Jon Maloy's avatar Jon Maloy Committed by David S. Miller

tipc: introduce communication groups

As a preparation for introducing flow control for multicast and datagram
messaging we need a more strictly defined framework than we have now. A
socket must be able keep track of exactly how many and which other
sockets it is allowed to communicate with at any moment, and keep the
necessary state for those.

We therefore introduce a new concept we have named Communication Group.
Sockets can join a group via a new setsockopt() call TIPC_GROUP_JOIN.
The call takes four parameters: 'type' serves as group identifier,
'instance' serves as an logical member identifier, and 'scope' indicates
the visibility of the group (node/cluster/zone). Finally, 'flags' makes
it possible to set certain properties for the member. For now, there is
only one flag, indicating if the creator of the socket wants to receive
a copy of broadcast or multicast messages it is sending via the socket,
and if wants to be eligible as destination for its own anycasts.

A group is 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.

Any member of a group can send multicast ('group broadcast') messages
to all group members, optionally including itself, using the primitive
send(). The messages are received via the recvmsg() primitive. A socket
can only be member of one group at a time.
Signed-off-by: default avatarJon Maloy <jon.maloy@ericsson.com>
Acked-by: default avatarYing Xue <ying.xue@windriver.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a80ae530
...@@ -231,6 +231,20 @@ struct sockaddr_tipc { ...@@ -231,6 +231,20 @@ struct sockaddr_tipc {
#define TIPC_SOCK_RECVQ_DEPTH 132 /* Default: none (read only) */ #define TIPC_SOCK_RECVQ_DEPTH 132 /* Default: none (read only) */
#define TIPC_MCAST_BROADCAST 133 /* Default: TIPC selects. No arg */ #define TIPC_MCAST_BROADCAST 133 /* Default: TIPC selects. No arg */
#define TIPC_MCAST_REPLICAST 134 /* 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 */
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) * Maximum sizes of TIPC bearer-related names (including terminating NULL)
......
...@@ -8,7 +8,7 @@ tipc-y += addr.o bcast.o bearer.o \ ...@@ -8,7 +8,7 @@ tipc-y += addr.o bcast.o bearer.o \
core.o link.o discover.o msg.o \ core.o link.o discover.o msg.o \
name_distr.o subscr.o monitor.o name_table.o net.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 \ 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_UDP) += udp_media.o
tipc-$(CONFIG_TIPC_MEDIA_IB) += ib_media.o tipc-$(CONFIG_TIPC_MEDIA_IB) += ib_media.o
......
This diff is collapsed.
/*
* net/tipc/group.h: Include file for TIPC group unicast/multicast functions
*
* Copyright (c) 2017, Ericsson AB
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _TIPC_GROUP_H
#define _TIPC_GROUP_H
#include "core.h"
struct tipc_group;
struct tipc_member;
struct tipc_msg;
struct tipc_group *tipc_group_create(struct net *net, u32 portid,
struct tipc_group_req *mreq);
void tipc_group_delete(struct net *net, struct tipc_group *grp);
void tipc_group_add_member(struct tipc_group *grp, u32 node, u32 port);
struct tipc_nlist *tipc_group_dests(struct tipc_group *grp);
void tipc_group_self(struct tipc_group *grp, struct tipc_name_seq *seq,
int *scope);
void tipc_group_filter_msg(struct tipc_group *grp,
struct sk_buff_head *inputq,
struct sk_buff_head *xmitq);
void tipc_group_member_evt(struct tipc_group *grp,
struct sk_buff *skb,
struct sk_buff_head *xmitq);
void tipc_group_proto_rcv(struct tipc_group *grp,
struct tipc_msg *hdr,
struct sk_buff_head *xmitq);
void tipc_group_update_bc_members(struct tipc_group *grp);
u16 tipc_group_bc_snd_nxt(struct tipc_group *grp);
int tipc_group_size(struct tipc_group *grp);
#endif
...@@ -1046,11 +1046,12 @@ static bool tipc_data_input(struct tipc_link *l, struct sk_buff *skb, ...@@ -1046,11 +1046,12 @@ static bool tipc_data_input(struct tipc_link *l, struct sk_buff *skb,
case TIPC_MEDIUM_IMPORTANCE: case TIPC_MEDIUM_IMPORTANCE:
case TIPC_HIGH_IMPORTANCE: case TIPC_HIGH_IMPORTANCE:
case TIPC_CRITICAL_IMPORTANCE: case TIPC_CRITICAL_IMPORTANCE:
if (unlikely(msg_type(hdr) == TIPC_MCAST_MSG)) { if (unlikely(msg_mcast(hdr))) {
skb_queue_tail(l->bc_rcvlink->inputq, skb); skb_queue_tail(l->bc_rcvlink->inputq, skb);
return true; return true;
} }
case CONN_MANAGER: case CONN_MANAGER:
case GROUP_PROTOCOL:
skb_queue_tail(inputq, skb); skb_queue_tail(inputq, skb);
return true; return true;
case NAME_DISTRIBUTOR: case NAME_DISTRIBUTOR:
......
/* /*
* net/tipc/msg.h: Include file for TIPC message header routines * net/tipc/msg.h: Include file for TIPC message header routines
* *
* Copyright (c) 2000-2007, 2014-2015 Ericsson AB * Copyright (c) 2000-2007, 2014-2017 Ericsson AB
* Copyright (c) 2005-2008, 2010-2011, Wind River Systems * Copyright (c) 2005-2008, 2010-2011, Wind River Systems
* All rights reserved. * All rights reserved.
* *
...@@ -61,10 +61,11 @@ struct plist; ...@@ -61,10 +61,11 @@ struct plist;
/* /*
* Payload message types * Payload message types
*/ */
#define TIPC_CONN_MSG 0 #define TIPC_CONN_MSG 0
#define TIPC_MCAST_MSG 1 #define TIPC_MCAST_MSG 1
#define TIPC_NAMED_MSG 2 #define TIPC_NAMED_MSG 2
#define TIPC_DIRECT_MSG 3 #define TIPC_DIRECT_MSG 3
#define TIPC_GRP_BCAST_MSG 4
/* /*
* Internal message users * Internal message users
...@@ -73,6 +74,7 @@ struct plist; ...@@ -73,6 +74,7 @@ struct plist;
#define MSG_BUNDLER 6 #define MSG_BUNDLER 6
#define LINK_PROTOCOL 7 #define LINK_PROTOCOL 7
#define CONN_MANAGER 8 #define CONN_MANAGER 8
#define GROUP_PROTOCOL 9
#define TUNNEL_PROTOCOL 10 #define TUNNEL_PROTOCOL 10
#define NAME_DISTRIBUTOR 11 #define NAME_DISTRIBUTOR 11
#define MSG_FRAGMENTER 12 #define MSG_FRAGMENTER 12
...@@ -87,6 +89,7 @@ struct plist; ...@@ -87,6 +89,7 @@ struct plist;
#define BASIC_H_SIZE 32 /* Basic payload message */ #define BASIC_H_SIZE 32 /* Basic payload message */
#define NAMED_H_SIZE 40 /* Named payload message */ #define NAMED_H_SIZE 40 /* Named payload message */
#define MCAST_H_SIZE 44 /* Multicast payload message */ #define MCAST_H_SIZE 44 /* Multicast payload message */
#define GROUP_H_SIZE 44 /* Group payload message */
#define INT_H_SIZE 40 /* Internal messages */ #define INT_H_SIZE 40 /* Internal messages */
#define MIN_H_SIZE 24 /* Smallest legal TIPC header size */ #define MIN_H_SIZE 24 /* Smallest legal TIPC header size */
#define MAX_H_SIZE 60 /* Largest possible TIPC header size */ #define MAX_H_SIZE 60 /* Largest possible TIPC header size */
...@@ -252,6 +255,11 @@ static inline void msg_set_type(struct tipc_msg *m, u32 n) ...@@ -252,6 +255,11 @@ static inline void msg_set_type(struct tipc_msg *m, u32 n)
msg_set_bits(m, 1, 29, 0x7, n); msg_set_bits(m, 1, 29, 0x7, n);
} }
static inline int msg_in_group(struct tipc_msg *m)
{
return (msg_type(m) == TIPC_GRP_BCAST_MSG);
}
static inline u32 msg_named(struct tipc_msg *m) static inline u32 msg_named(struct tipc_msg *m)
{ {
return msg_type(m) == TIPC_NAMED_MSG; return msg_type(m) == TIPC_NAMED_MSG;
...@@ -259,7 +267,9 @@ static inline u32 msg_named(struct tipc_msg *m) ...@@ -259,7 +267,9 @@ static inline u32 msg_named(struct tipc_msg *m)
static inline u32 msg_mcast(struct tipc_msg *m) static inline u32 msg_mcast(struct tipc_msg *m)
{ {
return msg_type(m) == TIPC_MCAST_MSG; int mtyp = msg_type(m);
return ((mtyp == TIPC_MCAST_MSG) || (mtyp == TIPC_GRP_BCAST_MSG));
} }
static inline u32 msg_connected(struct tipc_msg *m) static inline u32 msg_connected(struct tipc_msg *m)
...@@ -514,6 +524,12 @@ static inline void msg_set_nameupper(struct tipc_msg *m, u32 n) ...@@ -514,6 +524,12 @@ static inline void msg_set_nameupper(struct tipc_msg *m, u32 n)
#define DSC_REQ_MSG 0 #define DSC_REQ_MSG 0
#define DSC_RESP_MSG 1 #define DSC_RESP_MSG 1
/*
* Group protocol message types
*/
#define GRP_JOIN_MSG 0
#define GRP_LEAVE_MSG 1
/* /*
* Word 1 * Word 1
*/ */
...@@ -795,6 +811,28 @@ static inline void msg_set_link_tolerance(struct tipc_msg *m, u32 n) ...@@ -795,6 +811,28 @@ static inline void msg_set_link_tolerance(struct tipc_msg *m, u32 n)
msg_set_bits(m, 9, 0, 0xffff, n); msg_set_bits(m, 9, 0, 0xffff, n);
} }
static inline u16 msg_grp_bc_syncpt(struct tipc_msg *m)
{
return msg_bits(m, 9, 16, 0xffff);
}
static inline void msg_set_grp_bc_syncpt(struct tipc_msg *m, u16 n)
{
msg_set_bits(m, 9, 16, 0xffff, n);
}
/* Word 10
*/
static inline u16 msg_grp_bc_seqno(struct tipc_msg *m)
{
return msg_bits(m, 10, 16, 0xffff);
}
static inline void msg_set_grp_bc_seqno(struct tipc_msg *m, u32 n)
{
msg_set_bits(m, 10, 16, 0xffff, n);
}
static inline bool msg_peer_link_is_up(struct tipc_msg *m) static inline bool msg_peer_link_is_up(struct tipc_msg *m)
{ {
if (likely(msg_user(m) != LINK_PROTOCOL)) if (likely(msg_user(m) != LINK_PROTOCOL))
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include "bcast.h" #include "bcast.h"
#include "addr.h" #include "addr.h"
#include "node.h" #include "node.h"
#include "group.h"
#include <net/genetlink.h> #include <net/genetlink.h>
#define TIPC_NAMETBL_SIZE 1024 /* must be a power of 2 */ #define TIPC_NAMETBL_SIZE 1024 /* must be a power of 2 */
...@@ -596,18 +597,6 @@ u32 tipc_nametbl_translate(struct net *net, u32 type, u32 instance, ...@@ -596,18 +597,6 @@ u32 tipc_nametbl_translate(struct net *net, u32 type, u32 instance,
return ref; return ref;
} }
/**
* tipc_nametbl_mc_translate - find multicast destinations
*
* Creates list of all local ports that overlap the given multicast address;
* also determines if any off-node ports overlap.
*
* Note: Publications with a scope narrower than 'limit' are ignored.
* (i.e. local node-scope publications mustn't receive messages arriving
* from another node, even if the multcast link brought it here)
*
* Returns non-zero if any off-node ports overlap
*/
int tipc_nametbl_mc_translate(struct net *net, u32 type, u32 lower, u32 upper, int tipc_nametbl_mc_translate(struct net *net, u32 type, u32 lower, u32 upper,
u32 limit, struct list_head *dports) u32 limit, struct list_head *dports)
{ {
...@@ -679,6 +668,37 @@ void tipc_nametbl_lookup_dst_nodes(struct net *net, u32 type, u32 lower, ...@@ -679,6 +668,37 @@ void tipc_nametbl_lookup_dst_nodes(struct net *net, u32 type, u32 lower,
rcu_read_unlock(); rcu_read_unlock();
} }
/* tipc_nametbl_build_group - build list of communication group members
*/
void tipc_nametbl_build_group(struct net *net, struct tipc_group *grp,
u32 type, u32 domain)
{
struct sub_seq *sseq, *stop;
struct name_info *info;
struct publication *p;
struct name_seq *seq;
rcu_read_lock();
seq = nametbl_find_seq(net, type);
if (!seq)
goto exit;
spin_lock_bh(&seq->lock);
sseq = seq->sseqs;
stop = seq->sseqs + seq->first_free;
for (; sseq != stop; sseq++) {
info = sseq->info;
list_for_each_entry(p, &info->zone_list, zone_list) {
if (!tipc_in_scope(domain, p->node))
continue;
tipc_group_add_member(grp, p->node, p->ref);
}
}
spin_unlock_bh(&seq->lock);
exit:
rcu_read_unlock();
}
/* /*
* tipc_nametbl_publish - add name publication to network name tables * tipc_nametbl_publish - add name publication to network name tables
*/ */
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
struct tipc_subscription; struct tipc_subscription;
struct tipc_plist; struct tipc_plist;
struct tipc_nlist; struct tipc_nlist;
struct tipc_group;
/* /*
* TIPC name types reserved for internal TIPC use (both current and planned) * TIPC name types reserved for internal TIPC use (both current and planned)
...@@ -101,6 +102,8 @@ int tipc_nl_name_table_dump(struct sk_buff *skb, struct netlink_callback *cb); ...@@ -101,6 +102,8 @@ int tipc_nl_name_table_dump(struct sk_buff *skb, struct netlink_callback *cb);
u32 tipc_nametbl_translate(struct net *net, u32 type, u32 instance, u32 *node); u32 tipc_nametbl_translate(struct net *net, u32 type, u32 instance, u32 *node);
int tipc_nametbl_mc_translate(struct net *net, u32 type, u32 lower, u32 upper, int tipc_nametbl_mc_translate(struct net *net, u32 type, u32 lower, u32 upper,
u32 limit, struct list_head *dports); u32 limit, struct list_head *dports);
void tipc_nametbl_build_group(struct net *net, struct tipc_group *grp,
u32 type, u32 domain);
void tipc_nametbl_lookup_dst_nodes(struct net *net, u32 type, u32 lower, void tipc_nametbl_lookup_dst_nodes(struct net *net, u32 type, u32 lower,
u32 upper, u32 domain, u32 upper, u32 domain,
struct tipc_nlist *nodes); struct tipc_nlist *nodes);
......
...@@ -48,7 +48,8 @@ enum { ...@@ -48,7 +48,8 @@ enum {
TIPC_BCAST_SYNCH = (1 << 1), TIPC_BCAST_SYNCH = (1 << 1),
TIPC_BCAST_STATE_NACK = (1 << 2), TIPC_BCAST_STATE_NACK = (1 << 2),
TIPC_BLOCK_FLOWCTL = (1 << 3), TIPC_BLOCK_FLOWCTL = (1 << 3),
TIPC_BCAST_RCAST = (1 << 4) TIPC_BCAST_RCAST = (1 << 4),
TIPC_MCAST_GROUPS = (1 << 5)
}; };
#define TIPC_NODE_CAPABILITIES (TIPC_BCAST_SYNCH | \ #define TIPC_NODE_CAPABILITIES (TIPC_BCAST_SYNCH | \
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment