Commit d9fbfb94 authored by David S. Miller's avatar David S. Miller

Merge branch 'tipc-namespaces'

Ying Xue says:

====================
tipc: make tipc support namespace

This patchset aims to add net namespace support for TIPC stack.

Currently TIPC module declares the following global resources:
- TIPC network idenfication number
- TIPC node table
- TIPC bearer list table
- TIPC broadcast link
- TIPC socket reference table
- TIPC name service table
- TIPC node address
- TIPC service subscriber server
- TIPC random value
- TIPC netlink

In order that TIPC is aware of namespace, above each resource must be
allocated, initialized and destroyed inside per namespace. Therefore,
the major works of this patchset are to isolate these global resources
and make them private for each namespace. However, before these changes
come true, some necessary preparation works must be first done: convert
socket reference table with generic rhashtable, cleanup core.c and
core.h files, remove unnecessary wrapper functions for kernel timer
interfaces and so on.

It should be noted that commit ##1 ("tipc: fix bug in broadcast
retransmit code") was already submitted to 'net' tree, so please see
below link:

http://patchwork.ozlabs.org/patch/426717/

Since it is prerequisite for the rest of the series to apply, I
prepend them to the series.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 45e81834 d49e2041
......@@ -34,8 +34,51 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "core.h"
#include <linux/kernel.h>
#include "addr.h"
#include "core.h"
/**
* in_own_cluster - test for cluster inclusion; <0.0.0> always matches
*/
int in_own_cluster(struct net *net, u32 addr)
{
return in_own_cluster_exact(net, addr) || !addr;
}
int in_own_cluster_exact(struct net *net, u32 addr)
{
struct tipc_net *tn = net_generic(net, tipc_net_id);
return !((addr ^ tn->own_addr) >> 12);
}
/**
* in_own_node - test for node inclusion; <0.0.0> always matches
*/
int in_own_node(struct net *net, u32 addr)
{
struct tipc_net *tn = net_generic(net, tipc_net_id);
return (addr == tn->own_addr) || !addr;
}
/**
* addr_domain - convert 2-bit scope value to equivalent message lookup domain
*
* Needed when address of a named message must be looked up a second time
* after a network hop.
*/
u32 addr_domain(struct net *net, u32 sc)
{
struct tipc_net *tn = net_generic(net, tipc_net_id);
if (likely(sc == TIPC_NODE_SCOPE))
return tn->own_addr;
if (sc == TIPC_CLUSTER_SCOPE)
return tipc_cluster_mask(tn->own_addr);
return tipc_zone_mask(tn->own_addr);
}
/**
* tipc_addr_domain_valid - validates a network domain address
......
......@@ -37,7 +37,10 @@
#ifndef _TIPC_ADDR_H
#define _TIPC_ADDR_H
#include "core.h"
#include <linux/types.h>
#include <linux/tipc.h>
#include <net/net_namespace.h>
#include <net/netns/generic.h>
#define TIPC_ZONE_MASK 0xff000000u
#define TIPC_CLUSTER_MASK 0xfffff000u
......@@ -52,42 +55,10 @@ static inline u32 tipc_cluster_mask(u32 addr)
return addr & TIPC_CLUSTER_MASK;
}
static inline int in_own_cluster_exact(u32 addr)
{
return !((addr ^ tipc_own_addr) >> 12);
}
/**
* in_own_node - test for node inclusion; <0.0.0> always matches
*/
static inline int in_own_node(u32 addr)
{
return (addr == tipc_own_addr) || !addr;
}
/**
* in_own_cluster - test for cluster inclusion; <0.0.0> always matches
*/
static inline int in_own_cluster(u32 addr)
{
return in_own_cluster_exact(addr) || !addr;
}
/**
* addr_domain - convert 2-bit scope value to equivalent message lookup domain
*
* Needed when address of a named message must be looked up a second time
* after a network hop.
*/
static inline u32 addr_domain(u32 sc)
{
if (likely(sc == TIPC_NODE_SCOPE))
return tipc_own_addr;
if (sc == TIPC_CLUSTER_SCOPE)
return tipc_cluster_mask(tipc_own_addr);
return tipc_zone_mask(tipc_own_addr);
}
int in_own_cluster(struct net *net, u32 addr);
int in_own_cluster_exact(struct net *net, u32 addr);
int in_own_node(struct net *net, u32 addr);
u32 addr_domain(struct net *net, u32 sc);
int tipc_addr_domain_valid(u32);
int tipc_addr_node_valid(u32 addr);
int tipc_in_scope(u32 domain, u32 addr);
......
This diff is collapsed.
......@@ -37,23 +37,13 @@
#ifndef _TIPC_BCAST_H
#define _TIPC_BCAST_H
#include "netlink.h"
#include <linux/tipc_config.h>
#include "link.h"
#include "node.h"
#define MAX_NODES 4096
#define WSIZE 32
#define TIPC_BCLINK_RESET 1
/**
* struct tipc_node_map - set of node identifiers
* @count: # of nodes in set
* @map: bitmap of node identifiers that are in the set
*/
struct tipc_node_map {
u32 count;
u32 map[MAX_NODES / WSIZE];
};
#define PLSIZE 32
#define TIPC_BCLINK_RESET 1
#define PLSIZE 32
#define BCBEARER MAX_BEARERS
/**
* struct tipc_port_list - set of node local destination ports
......@@ -67,9 +57,64 @@ struct tipc_port_list {
u32 ports[PLSIZE];
};
/**
* struct tipc_bcbearer_pair - a pair of bearers used by broadcast link
* @primary: pointer to primary bearer
* @secondary: pointer to secondary bearer
*
* Bearers must have same priority and same set of reachable destinations
* to be paired.
*/
struct tipc_node;
struct tipc_bcbearer_pair {
struct tipc_bearer *primary;
struct tipc_bearer *secondary;
};
/**
* struct tipc_bcbearer - bearer used by broadcast link
* @bearer: (non-standard) broadcast bearer structure
* @media: (non-standard) broadcast media structure
* @bpairs: array of bearer pairs
* @bpairs_temp: temporary array of bearer pairs used by tipc_bcbearer_sort()
* @remains: temporary node map used by tipc_bcbearer_send()
* @remains_new: temporary node map used tipc_bcbearer_send()
*
* Note: The fields labelled "temporary" are incorporated into the bearer
* to avoid consuming potentially limited stack space through the use of
* large local variables within multicast routines. Concurrent access is
* prevented through use of the spinlock "bclink_lock".
*/
struct tipc_bcbearer {
struct tipc_bearer bearer;
struct tipc_media media;
struct tipc_bcbearer_pair bpairs[MAX_BEARERS];
struct tipc_bcbearer_pair bpairs_temp[TIPC_MAX_LINK_PRI + 1];
struct tipc_node_map remains;
struct tipc_node_map remains_new;
};
/**
* struct tipc_bclink - link used for broadcast messages
* @lock: spinlock governing access to structure
* @link: (non-standard) broadcast link structure
* @node: (non-standard) node structure representing b'cast link's peer node
* @flags: represent bclink states
* @bcast_nodes: map of broadcast-capable nodes
* @retransmit_to: node that most recently requested a retransmit
*
* Handles sequence numbering, fragmentation, bundling, etc.
*/
struct tipc_bclink {
spinlock_t lock;
struct tipc_link link;
struct tipc_node node;
unsigned int flags;
struct tipc_node_map bcast_nodes;
struct tipc_node *retransmit_to;
};
struct tipc_node;
extern const char tipc_bclink_name[];
/**
......@@ -84,24 +129,26 @@ static inline int tipc_nmap_equal(struct tipc_node_map *nm_a,
void tipc_port_list_add(struct tipc_port_list *pl_ptr, u32 port);
void tipc_port_list_free(struct tipc_port_list *pl_ptr);
int tipc_bclink_init(void);
void tipc_bclink_stop(void);
void tipc_bclink_set_flags(unsigned int flags);
void tipc_bclink_add_node(u32 addr);
void tipc_bclink_remove_node(u32 addr);
struct tipc_node *tipc_bclink_retransmit_to(void);
int tipc_bclink_init(struct net *net);
void tipc_bclink_stop(struct net *net);
void tipc_bclink_set_flags(struct net *tn, unsigned int flags);
void tipc_bclink_add_node(struct net *net, u32 addr);
void tipc_bclink_remove_node(struct net *net, u32 addr);
struct tipc_node *tipc_bclink_retransmit_to(struct net *tn);
void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked);
void tipc_bclink_rcv(struct sk_buff *buf);
u32 tipc_bclink_get_last_sent(void);
void tipc_bclink_rcv(struct net *net, struct sk_buff *buf);
u32 tipc_bclink_get_last_sent(struct net *net);
u32 tipc_bclink_acks_missing(struct tipc_node *n_ptr);
void tipc_bclink_update_link_state(struct tipc_node *n_ptr, u32 last_sent);
int tipc_bclink_stats(char *stats_buf, const u32 buf_size);
int tipc_bclink_reset_stats(void);
int tipc_bclink_set_queue_limits(u32 limit);
void tipc_bcbearer_sort(struct tipc_node_map *nm_ptr, u32 node, bool action);
void tipc_bclink_update_link_state(struct net *net, struct tipc_node *n_ptr,
u32 last_sent);
int tipc_bclink_stats(struct net *net, char *stats_buf, const u32 buf_size);
int tipc_bclink_reset_stats(struct net *net);
int tipc_bclink_set_queue_limits(struct net *net, u32 limit);
void tipc_bcbearer_sort(struct net *net, struct tipc_node_map *nm_ptr,
u32 node, bool action);
uint tipc_bclink_get_mtu(void);
int tipc_bclink_xmit(struct sk_buff_head *list);
void tipc_bclink_wakeup_users(void);
int tipc_nl_add_bc_link(struct tipc_nl_msg *msg);
int tipc_bclink_xmit(struct net *net, struct sk_buff_head *list);
void tipc_bclink_wakeup_users(struct net *net);
int tipc_nl_add_bc_link(struct net *net, struct tipc_nl_msg *msg);
#endif
This diff is collapsed.
......@@ -37,12 +37,13 @@
#ifndef _TIPC_BEARER_H
#define _TIPC_BEARER_H
#include "bcast.h"
#include "netlink.h"
#include <net/genetlink.h>
#define MAX_BEARERS 2
#define MAX_MEDIA 2
#define MAX_NODES 4096
#define WSIZE 32
/* Identifiers associated with TIPC message header media address info
* - address info field is 32 bytes long
......@@ -58,6 +59,16 @@
#define TIPC_MEDIA_TYPE_ETH 1
#define TIPC_MEDIA_TYPE_IB 2
/**
* struct tipc_node_map - set of node identifiers
* @count: # of nodes in set
* @map: bitmap of node identifiers that are in the set
*/
struct tipc_node_map {
u32 count;
u32 map[MAX_NODES / WSIZE];
};
/**
* struct tipc_media_addr - destination address used by TIPC bearers
* @value: address info (format defined by media)
......@@ -89,10 +100,10 @@ struct tipc_bearer;
* @name: media name
*/
struct tipc_media {
int (*send_msg)(struct sk_buff *buf,
int (*send_msg)(struct net *net, struct sk_buff *buf,
struct tipc_bearer *b_ptr,
struct tipc_media_addr *dest);
int (*enable_media)(struct tipc_bearer *b_ptr);
int (*enable_media)(struct net *net, struct tipc_bearer *b_ptr);
void (*disable_media)(struct tipc_bearer *b_ptr);
int (*addr2str)(struct tipc_media_addr *addr,
char *strbuf,
......@@ -157,17 +168,14 @@ struct tipc_bearer_names {
char if_name[TIPC_MAX_IF_NAME];
};
struct tipc_link;
extern struct tipc_bearer __rcu *bearer_list[];
/*
* TIPC routines available to supported media types
*/
void tipc_rcv(struct sk_buff *skb, struct tipc_bearer *tb_ptr);
int tipc_enable_bearer(const char *bearer_name, u32 disc_domain, u32 priority);
int tipc_disable_bearer(const char *name);
void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b_ptr);
int tipc_enable_bearer(struct net *net, const char *bearer_name,
u32 disc_domain, u32 priority);
int tipc_disable_bearer(struct net *net, const char *name);
/*
* Routines made available to TIPC by supported media types
......@@ -192,20 +200,20 @@ int tipc_media_set_priority(const char *name, u32 new_value);
int tipc_media_set_window(const char *name, u32 new_value);
void tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a);
struct sk_buff *tipc_media_get_names(void);
int tipc_enable_l2_media(struct tipc_bearer *b);
int tipc_enable_l2_media(struct net *net, struct tipc_bearer *b);
void tipc_disable_l2_media(struct tipc_bearer *b);
int tipc_l2_send_msg(struct sk_buff *buf, struct tipc_bearer *b,
struct tipc_media_addr *dest);
int tipc_l2_send_msg(struct net *net, struct sk_buff *buf,
struct tipc_bearer *b, struct tipc_media_addr *dest);
struct sk_buff *tipc_bearer_get_names(void);
void tipc_bearer_add_dest(u32 bearer_id, u32 dest);
void tipc_bearer_remove_dest(u32 bearer_id, u32 dest);
struct tipc_bearer *tipc_bearer_find(const char *name);
struct sk_buff *tipc_bearer_get_names(struct net *net);
void tipc_bearer_add_dest(struct net *net, u32 bearer_id, u32 dest);
void tipc_bearer_remove_dest(struct net *net, u32 bearer_id, u32 dest);
struct tipc_bearer *tipc_bearer_find(struct net *net, const char *name);
struct tipc_media *tipc_media_find(const char *name);
int tipc_bearer_setup(void);
void tipc_bearer_cleanup(void);
void tipc_bearer_stop(void);
void tipc_bearer_send(u32 bearer_id, struct sk_buff *buf,
void tipc_bearer_stop(struct net *net);
void tipc_bearer_send(struct net *net, u32 bearer_id, struct sk_buff *buf,
struct tipc_media_addr *dest);
#endif /* _TIPC_BEARER_H */
......@@ -134,7 +134,7 @@ static struct sk_buff *tipc_show_stats(void)
return buf;
}
static struct sk_buff *cfg_enable_bearer(void)
static struct sk_buff *cfg_enable_bearer(struct net *net)
{
struct tipc_bearer_config *args;
......@@ -142,7 +142,7 @@ static struct sk_buff *cfg_enable_bearer(void)
return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
args = (struct tipc_bearer_config *)TLV_DATA(req_tlv_area);
if (tipc_enable_bearer(args->name,
if (tipc_enable_bearer(net, args->name,
ntohl(args->disc_domain),
ntohl(args->priority)))
return tipc_cfg_reply_error_string("unable to enable bearer");
......@@ -150,62 +150,66 @@ static struct sk_buff *cfg_enable_bearer(void)
return tipc_cfg_reply_none();
}
static struct sk_buff *cfg_disable_bearer(void)
static struct sk_buff *cfg_disable_bearer(struct net *net)
{
if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_BEARER_NAME))
return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
if (tipc_disable_bearer((char *)TLV_DATA(req_tlv_area)))
if (tipc_disable_bearer(net, (char *)TLV_DATA(req_tlv_area)))
return tipc_cfg_reply_error_string("unable to disable bearer");
return tipc_cfg_reply_none();
}
static struct sk_buff *cfg_set_own_addr(void)
static struct sk_buff *cfg_set_own_addr(struct net *net)
{
struct tipc_net *tn = net_generic(net, tipc_net_id);
u32 addr;
if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR))
return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
addr = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
if (addr == tipc_own_addr)
if (addr == tn->own_addr)
return tipc_cfg_reply_none();
if (!tipc_addr_node_valid(addr))
return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
" (node address)");
if (tipc_own_addr)
if (tn->own_addr)
return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
" (cannot change node address once assigned)");
if (!tipc_net_start(addr))
if (!tipc_net_start(net, addr))
return tipc_cfg_reply_none();
return tipc_cfg_reply_error_string("cannot change to network mode");
}
static struct sk_buff *cfg_set_netid(void)
static struct sk_buff *cfg_set_netid(struct net *net)
{
struct tipc_net *tn = net_generic(net, tipc_net_id);
u32 value;
if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
if (value == tipc_net_id)
if (value == tn->net_id)
return tipc_cfg_reply_none();
if (value < 1 || value > 9999)
return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
" (network id must be 1-9999)");
if (tipc_own_addr)
if (tn->own_addr)
return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
" (cannot change network id once TIPC has joined a network)");
tipc_net_id = value;
tn->net_id = value;
return tipc_cfg_reply_none();
}
struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area,
int request_space, int reply_headroom)
struct sk_buff *tipc_cfg_do_cmd(struct net *net, u32 orig_node, u16 cmd,
const void *request_area, int request_space,
int reply_headroom)
{
struct sk_buff *rep_tlv_buf;
struct tipc_net *tn = net_generic(net, tipc_net_id);
rtnl_lock();
......@@ -215,7 +219,7 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
rep_headroom = reply_headroom;
/* Check command authorization */
if (likely(in_own_node(orig_node))) {
if (likely(in_own_node(net, orig_node))) {
/* command is permitted */
} else {
rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
......@@ -229,28 +233,33 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
rep_tlv_buf = tipc_cfg_reply_none();
break;
case TIPC_CMD_GET_NODES:
rep_tlv_buf = tipc_node_get_nodes(req_tlv_area, req_tlv_space);
rep_tlv_buf = tipc_node_get_nodes(net, req_tlv_area,
req_tlv_space);
break;
case TIPC_CMD_GET_LINKS:
rep_tlv_buf = tipc_node_get_links(req_tlv_area, req_tlv_space);
rep_tlv_buf = tipc_node_get_links(net, req_tlv_area,
req_tlv_space);
break;
case TIPC_CMD_SHOW_LINK_STATS:
rep_tlv_buf = tipc_link_cmd_show_stats(req_tlv_area, req_tlv_space);
rep_tlv_buf = tipc_link_cmd_show_stats(net, req_tlv_area,
req_tlv_space);
break;
case TIPC_CMD_RESET_LINK_STATS:
rep_tlv_buf = tipc_link_cmd_reset_stats(req_tlv_area, req_tlv_space);
rep_tlv_buf = tipc_link_cmd_reset_stats(net, req_tlv_area,
req_tlv_space);
break;
case TIPC_CMD_SHOW_NAME_TABLE:
rep_tlv_buf = tipc_nametbl_get(req_tlv_area, req_tlv_space);
rep_tlv_buf = tipc_nametbl_get(net, req_tlv_area,
req_tlv_space);
break;
case TIPC_CMD_GET_BEARER_NAMES:
rep_tlv_buf = tipc_bearer_get_names();
rep_tlv_buf = tipc_bearer_get_names(net);
break;
case TIPC_CMD_GET_MEDIA_NAMES:
rep_tlv_buf = tipc_media_get_names();
break;
case TIPC_CMD_SHOW_PORTS:
rep_tlv_buf = tipc_sk_socks_show();
rep_tlv_buf = tipc_sk_socks_show(net);
break;
case TIPC_CMD_SHOW_STATS:
rep_tlv_buf = tipc_show_stats();
......@@ -258,22 +267,23 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
case TIPC_CMD_SET_LINK_TOL:
case TIPC_CMD_SET_LINK_PRI:
case TIPC_CMD_SET_LINK_WINDOW:
rep_tlv_buf = tipc_link_cmd_config(req_tlv_area, req_tlv_space, cmd);
rep_tlv_buf = tipc_link_cmd_config(net, req_tlv_area,
req_tlv_space, cmd);
break;
case TIPC_CMD_ENABLE_BEARER:
rep_tlv_buf = cfg_enable_bearer();
rep_tlv_buf = cfg_enable_bearer(net);
break;
case TIPC_CMD_DISABLE_BEARER:
rep_tlv_buf = cfg_disable_bearer();
rep_tlv_buf = cfg_disable_bearer(net);
break;
case TIPC_CMD_SET_NODE_ADDR:
rep_tlv_buf = cfg_set_own_addr();
rep_tlv_buf = cfg_set_own_addr(net);
break;
case TIPC_CMD_SET_NETID:
rep_tlv_buf = cfg_set_netid();
rep_tlv_buf = cfg_set_netid(net);
break;
case TIPC_CMD_GET_NETID:
rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_net_id);
rep_tlv_buf = tipc_cfg_reply_unsigned(tn->net_id);
break;
case TIPC_CMD_NOT_NET_ADMIN:
rep_tlv_buf =
......
......@@ -37,10 +37,10 @@
#ifndef _TIPC_CONFIG_H
#define _TIPC_CONFIG_H
/* ---------------------------------------------------------------------- */
#include "link.h"
#define ULTRA_STRING_MAX_LEN 32768
struct sk_buff *tipc_cfg_reply_alloc(int payload_size);
int tipc_cfg_append_tlv(struct sk_buff *buf, int tlv_type,
void *tlv_data, int tlv_data_size);
......@@ -61,7 +61,7 @@ static inline struct sk_buff *tipc_cfg_reply_ultra_string(char *string)
return tipc_cfg_reply_string_type(TIPC_TLV_ULTRA_STRING, string);
}
struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd,
struct sk_buff *tipc_cfg_do_cmd(struct net *net, u32 orig_node, u16 cmd,
const void *req_tlv_area, int req_tlv_space,
int headroom);
#endif
......@@ -44,68 +44,68 @@
#include <linux/module.h>
/* global variables used by multiple sub-systems within TIPC */
int tipc_random __read_mostly;
/* configurable TIPC parameters */
u32 tipc_own_addr __read_mostly;
int tipc_net_id __read_mostly;
int sysctl_tipc_rmem[3] __read_mostly; /* min/default/max */
/**
* tipc_buf_acquire - creates a TIPC message buffer
* @size: message size (including TIPC header)
*
* Returns a new buffer with data pointers set to the specified size.
*
* NOTE: Headroom is reserved to allow prepending of a data link header.
* There may also be unrequested tailroom present at the buffer's end.
*/
struct sk_buff *tipc_buf_acquire(u32 size)
static int __net_init tipc_init_net(struct net *net)
{
struct sk_buff *skb;
unsigned int buf_size = (BUF_HEADROOM + size + 3) & ~3u;
skb = alloc_skb_fclone(buf_size, GFP_ATOMIC);
if (skb) {
skb_reserve(skb, BUF_HEADROOM);
skb_put(skb, size);
skb->next = NULL;
}
return skb;
struct tipc_net *tn = net_generic(net, tipc_net_id);
int err;
tn->net_id = 4711;
tn->own_addr = 0;
get_random_bytes(&tn->random, sizeof(int));
INIT_LIST_HEAD(&tn->node_list);
spin_lock_init(&tn->node_list_lock);
err = tipc_sk_rht_init(net);
if (err)
goto out_sk_rht;
err = tipc_nametbl_init(net);
if (err)
goto out_nametbl;
err = tipc_subscr_start(net);
if (err)
goto out_subscr;
return 0;
out_subscr:
tipc_nametbl_stop(net);
out_nametbl:
tipc_sk_rht_destroy(net);
out_sk_rht:
return err;
}
/**
* tipc_core_stop - switch TIPC from SINGLE NODE to NOT RUNNING mode
*/
static void tipc_core_stop(void)
static void __net_exit tipc_exit_net(struct net *net)
{
tipc_net_stop();
tipc_bearer_cleanup();
tipc_netlink_stop();
tipc_subscr_stop();
tipc_nametbl_stop();
tipc_socket_stop();
tipc_unregister_sysctl();
tipc_sk_rht_destroy();
tipc_subscr_stop(net);
tipc_net_stop(net);
tipc_nametbl_stop(net);
tipc_sk_rht_destroy(net);
}
/**
* tipc_core_start - switch TIPC from NOT RUNNING to SINGLE NODE mode
*/
static int tipc_core_start(void)
static struct pernet_operations tipc_net_ops = {
.init = tipc_init_net,
.exit = tipc_exit_net,
.id = &tipc_net_id,
.size = sizeof(struct tipc_net),
};
static int __init tipc_init(void)
{
int err;
get_random_bytes(&tipc_random, sizeof(tipc_random));
err = tipc_sk_rht_init();
if (err)
goto out_reftbl;
pr_info("Activated (version " TIPC_MOD_VER ")\n");
err = tipc_nametbl_init();
if (err)
goto out_nametbl;
sysctl_tipc_rmem[0] = TIPC_CONN_OVERLOAD_LIMIT >> 4 <<
TIPC_LOW_IMPORTANCE;
sysctl_tipc_rmem[1] = TIPC_CONN_OVERLOAD_LIMIT >> 4 <<
TIPC_CRITICAL_IMPORTANCE;
sysctl_tipc_rmem[2] = TIPC_CONN_OVERLOAD_LIMIT;
err = tipc_netlink_start();
if (err)
......@@ -119,57 +119,37 @@ static int tipc_core_start(void)
if (err)
goto out_sysctl;
err = tipc_subscr_start();
err = register_pernet_subsys(&tipc_net_ops);
if (err)
goto out_subscr;
goto out_pernet;
err = tipc_bearer_setup();
if (err)
goto out_bearer;
pr_info("Started in single node mode\n");
return 0;
out_bearer:
tipc_subscr_stop();
out_subscr:
unregister_pernet_subsys(&tipc_net_ops);
out_pernet:
tipc_unregister_sysctl();
out_sysctl:
tipc_socket_stop();
out_socket:
tipc_netlink_stop();
out_netlink:
tipc_nametbl_stop();
out_nametbl:
tipc_sk_rht_destroy();
out_reftbl:
pr_err("Unable to start in single node mode\n");
return err;
}
static int __init tipc_init(void)
{
int res;
pr_info("Activated (version " TIPC_MOD_VER ")\n");
tipc_own_addr = 0;
tipc_net_id = 4711;
sysctl_tipc_rmem[0] = TIPC_CONN_OVERLOAD_LIMIT >> 4 <<
TIPC_LOW_IMPORTANCE;
sysctl_tipc_rmem[1] = TIPC_CONN_OVERLOAD_LIMIT >> 4 <<
TIPC_CRITICAL_IMPORTANCE;
sysctl_tipc_rmem[2] = TIPC_CONN_OVERLOAD_LIMIT;
res = tipc_core_start();
if (res)
pr_err("Unable to start in single node mode\n");
else
pr_info("Started in single node mode\n");
return res;
}
static void __exit tipc_exit(void)
{
tipc_core_stop();
tipc_bearer_cleanup();
tipc_netlink_stop();
tipc_socket_stop();
tipc_unregister_sysctl();
unregister_pernet_subsys(&tipc_net_ops);
pr_info("Deactivated\n");
}
......
......@@ -57,46 +57,56 @@
#include <linux/vmalloc.h>
#include <linux/rtnetlink.h>
#include <linux/etherdevice.h>
#include <net/netns/generic.h>
#include <linux/rhashtable.h>
#define TIPC_MOD_VER "2.0.0"
#define ULTRA_STRING_MAX_LEN 32768
#define TIPC_MAX_SUBSCRIPTIONS 65535
#define TIPC_MAX_PUBLICATIONS 65535
#include "node.h"
#include "bearer.h"
#include "bcast.h"
#include "netlink.h"
#include "link.h"
#include "node.h"
#include "msg.h"
struct tipc_msg; /* msg.h */
#define TIPC_MOD_VER "2.0.0"
int tipc_snprintf(char *buf, int len, const char *fmt, ...);
/*
* TIPC-specific error codes
*/
#define ELINKCONG EAGAIN /* link congestion <=> resource unavailable */
/*
* Global configuration variables
*/
extern u32 tipc_own_addr __read_mostly;
extern int tipc_net_id __read_mostly;
extern int sysctl_tipc_rmem[3] __read_mostly;
extern int sysctl_tipc_named_timeout __read_mostly;
/*
* Other global variables
*/
extern int tipc_random __read_mostly;
struct tipc_net {
u32 own_addr;
int net_id;
int random;
/*
* Routines available to privileged subsystems
*/
int tipc_netlink_start(void);
void tipc_netlink_stop(void);
int tipc_socket_init(void);
void tipc_socket_stop(void);
int tipc_sock_create_local(int type, struct socket **res);
void tipc_sock_release_local(struct socket *sock);
int tipc_sock_accept_local(struct socket *sock, struct socket **newsock,
int flags);
/* Node table and node list */
spinlock_t node_list_lock;
struct hlist_head node_htable[NODE_HTABLE_SIZE];
struct list_head node_list;
u32 num_nodes;
u32 num_links;
/* Bearer list */
struct tipc_bearer __rcu *bearer_list[MAX_BEARERS + 1];
/* Broadcast link */
struct tipc_bcbearer *bcbearer;
struct tipc_bclink *bclink;
struct tipc_link *bcl;
/* Socket hash table */
struct rhashtable sk_rht;
/* Name table */
spinlock_t nametbl_lock;
struct name_table *nametbl;
/* Topology subscription server */
struct tipc_server *topsrv;
atomic_t subscription_count;
};
#ifdef CONFIG_SYSCTL
int tipc_register_sysctl(void);
......@@ -106,101 +116,4 @@ void tipc_unregister_sysctl(void);
#define tipc_unregister_sysctl()
#endif
/*
* TIPC timer code
*/
typedef void (*Handler) (unsigned long);
/**
* k_init_timer - initialize a timer
* @timer: pointer to timer structure
* @routine: pointer to routine to invoke when timer expires
* @argument: value to pass to routine when timer expires
*
* Timer must be initialized before use (and terminated when no longer needed).
*/
static inline void k_init_timer(struct timer_list *timer, Handler routine,
unsigned long argument)
{
setup_timer(timer, routine, argument);
}
/**
* k_start_timer - start a timer
* @timer: pointer to timer structure
* @msec: time to delay (in ms)
*
* Schedules a previously initialized timer for later execution.
* If timer is already running, the new timeout overrides the previous request.
*
* To ensure the timer doesn't expire before the specified delay elapses,
* the amount of delay is rounded up when converting to the jiffies
* then an additional jiffy is added to account for the fact that
* the starting time may be in the middle of the current jiffy.
*/
static inline void k_start_timer(struct timer_list *timer, unsigned long msec)
{
mod_timer(timer, jiffies + msecs_to_jiffies(msec) + 1);
}
/**
* k_cancel_timer - cancel a timer
* @timer: pointer to timer structure
*
* Cancels a previously initialized timer.
* Can be called safely even if the timer is already inactive.
*
* WARNING: Must not be called when holding locks required by the timer's
* timeout routine, otherwise deadlock can occur on SMP systems!
*/
static inline void k_cancel_timer(struct timer_list *timer)
{
del_timer_sync(timer);
}
/**
* k_term_timer - terminate a timer
* @timer: pointer to timer structure
*
* Prevents further use of a previously initialized timer.
*
* WARNING: Caller must ensure timer isn't currently running.
*
* (Do not "enhance" this routine to automatically cancel an active timer,
* otherwise deadlock can arise when a timeout routine calls k_term_timer.)
*/
static inline void k_term_timer(struct timer_list *timer)
{
}
/*
* TIPC message buffer code
*
* TIPC message buffer headroom reserves space for the worst-case
* link-level device header (in case the message is sent off-node).
*
* Note: Headroom should be a multiple of 4 to ensure the TIPC header fields
* are word aligned for quicker access
*/
#define BUF_HEADROOM LL_MAX_HEADER
struct tipc_skb_cb {
void *handle;
struct sk_buff *tail;
bool deferred;
bool wakeup_pending;
bool bundling;
u16 chain_sz;
u16 chain_imp;
};
#define TIPC_SKB_CB(__skb) ((struct tipc_skb_cb *)&((__skb)->cb[0]))
static inline struct tipc_msg *buf_msg(struct sk_buff *skb)
{
return (struct tipc_msg *)skb->data;
}
struct sk_buff *tipc_buf_acquire(u32 size);
#endif
......@@ -38,15 +38,20 @@
#include "link.h"
#include "discover.h"
#define TIPC_LINK_REQ_INIT 125 /* min delay during bearer start up */
#define TIPC_LINK_REQ_FAST 1000 /* max delay if bearer has no links */
#define TIPC_LINK_REQ_SLOW 60000 /* max delay if bearer has links */
#define TIPC_LINK_REQ_INACTIVE 0xffffffff /* indicates no timer in use */
/* min delay during bearer start up */
#define TIPC_LINK_REQ_INIT msecs_to_jiffies(125)
/* max delay if bearer has no links */
#define TIPC_LINK_REQ_FAST msecs_to_jiffies(1000)
/* max delay if bearer has links */
#define TIPC_LINK_REQ_SLOW msecs_to_jiffies(60000)
/* indicates no timer in use */
#define TIPC_LINK_REQ_INACTIVE 0xffffffff
/**
* struct tipc_link_req - information about an ongoing link setup request
* @bearer_id: identity of bearer issuing requests
* @net: network namespace instance
* @dest: destination address for request messages
* @domain: network domain to which links can be established
* @num_nodes: number of nodes currently discovered (i.e. with an active link)
......@@ -58,31 +63,34 @@
struct tipc_link_req {
u32 bearer_id;
struct tipc_media_addr dest;
struct net *net;
u32 domain;
int num_nodes;
spinlock_t lock;
struct sk_buff *buf;
struct timer_list timer;
unsigned int timer_intv;
unsigned long timer_intv;
};
/**
* tipc_disc_init_msg - initialize a link setup message
* @net: the applicable net namespace
* @type: message type (request or response)
* @b_ptr: ptr to bearer issuing message
*/
static void tipc_disc_init_msg(struct sk_buff *buf, u32 type,
static void tipc_disc_init_msg(struct net *net, struct sk_buff *buf, u32 type,
struct tipc_bearer *b_ptr)
{
struct tipc_net *tn = net_generic(net, tipc_net_id);
struct tipc_msg *msg;
u32 dest_domain = b_ptr->domain;
msg = buf_msg(buf);
tipc_msg_init(msg, LINK_CONFIG, type, INT_H_SIZE, dest_domain);
tipc_msg_init(net, msg, LINK_CONFIG, type, INT_H_SIZE, dest_domain);
msg_set_non_seq(msg, 1);
msg_set_node_sig(msg, tipc_random);
msg_set_node_sig(msg, tn->random);
msg_set_dest_domain(msg, dest_domain);
msg_set_bc_netid(msg, tipc_net_id);
msg_set_bc_netid(msg, tn->net_id);
b_ptr->media->addr2msg(msg_media_addr(msg), &b_ptr->addr);
}
......@@ -107,11 +115,14 @@ static void disc_dupl_alert(struct tipc_bearer *b_ptr, u32 node_addr,
/**
* tipc_disc_rcv - handle incoming discovery message (request or response)
* @net: the applicable net namespace
* @buf: buffer containing message
* @bearer: bearer that message arrived on
*/
void tipc_disc_rcv(struct sk_buff *buf, struct tipc_bearer *bearer)
void tipc_disc_rcv(struct net *net, struct sk_buff *buf,
struct tipc_bearer *bearer)
{
struct tipc_net *tn = net_generic(net, tipc_net_id);
struct tipc_node *node;
struct tipc_link *link;
struct tipc_media_addr maddr;
......@@ -133,7 +144,7 @@ void tipc_disc_rcv(struct sk_buff *buf, struct tipc_bearer *bearer)
kfree_skb(buf);
/* Ensure message from node is valid and communication is permitted */
if (net_id != tipc_net_id)
if (net_id != tn->net_id)
return;
if (maddr.broadcast)
return;
......@@ -142,20 +153,20 @@ void tipc_disc_rcv(struct sk_buff *buf, struct tipc_bearer *bearer)
if (!tipc_addr_node_valid(onode))
return;
if (in_own_node(onode)) {
if (in_own_node(net, onode)) {
if (memcmp(&maddr, &bearer->addr, sizeof(maddr)))
disc_dupl_alert(bearer, tipc_own_addr, &maddr);
disc_dupl_alert(bearer, tn->own_addr, &maddr);
return;
}
if (!tipc_in_scope(ddom, tipc_own_addr))
if (!tipc_in_scope(ddom, tn->own_addr))
return;
if (!tipc_in_scope(bearer->domain, onode))
return;
/* Locate, or if necessary, create, node: */
node = tipc_node_find(onode);
node = tipc_node_find(net, onode);
if (!node)
node = tipc_node_create(onode);
node = tipc_node_create(net, onode);
if (!node)
return;
......@@ -244,8 +255,8 @@ void tipc_disc_rcv(struct sk_buff *buf, struct tipc_bearer *bearer)
if (respond && (mtyp == DSC_REQ_MSG)) {
rbuf = tipc_buf_acquire(INT_H_SIZE);
if (rbuf) {
tipc_disc_init_msg(rbuf, DSC_RESP_MSG, bearer);
tipc_bearer_send(bearer->identity, rbuf, &maddr);
tipc_disc_init_msg(net, rbuf, DSC_RESP_MSG, bearer);
tipc_bearer_send(net, bearer->identity, rbuf, &maddr);
kfree_skb(rbuf);
}
}
......@@ -265,7 +276,7 @@ static void disc_update(struct tipc_link_req *req)
if ((req->timer_intv == TIPC_LINK_REQ_INACTIVE) ||
(req->timer_intv > TIPC_LINK_REQ_FAST)) {
req->timer_intv = TIPC_LINK_REQ_INIT;
k_start_timer(&req->timer, req->timer_intv);
mod_timer(&req->timer, jiffies + req->timer_intv);
}
}
}
......@@ -295,12 +306,13 @@ void tipc_disc_remove_dest(struct tipc_link_req *req)
/**
* disc_timeout - send a periodic link setup request
* @req: ptr to link request structure
* @data: ptr to link request structure
*
* Called whenever a link setup request timer associated with a bearer expires.
*/
static void disc_timeout(struct tipc_link_req *req)
static void disc_timeout(unsigned long data)
{
struct tipc_link_req *req = (struct tipc_link_req *)data;
int max_delay;
spin_lock_bh(&req->lock);
......@@ -318,7 +330,7 @@ static void disc_timeout(struct tipc_link_req *req)
* hold at fast polling rate if don't have any associated nodes,
* otherwise hold at slow polling rate
*/
tipc_bearer_send(req->bearer_id, req->buf, &req->dest);
tipc_bearer_send(req->net, req->bearer_id, req->buf, &req->dest);
req->timer_intv *= 2;
......@@ -329,20 +341,22 @@ static void disc_timeout(struct tipc_link_req *req)
if (req->timer_intv > max_delay)
req->timer_intv = max_delay;
k_start_timer(&req->timer, req->timer_intv);
mod_timer(&req->timer, jiffies + req->timer_intv);
exit:
spin_unlock_bh(&req->lock);
}
/**
* tipc_disc_create - create object to send periodic link setup requests
* @net: the applicable net namespace
* @b_ptr: ptr to bearer issuing requests
* @dest: destination address for request messages
* @dest_domain: network domain to which links can be established
*
* Returns 0 if successful, otherwise -errno.
*/
int tipc_disc_create(struct tipc_bearer *b_ptr, struct tipc_media_addr *dest)
int tipc_disc_create(struct net *net, struct tipc_bearer *b_ptr,
struct tipc_media_addr *dest)
{
struct tipc_link_req *req;
......@@ -356,17 +370,18 @@ int tipc_disc_create(struct tipc_bearer *b_ptr, struct tipc_media_addr *dest)
return -ENOMEM;
}
tipc_disc_init_msg(req->buf, DSC_REQ_MSG, b_ptr);
tipc_disc_init_msg(net, req->buf, DSC_REQ_MSG, b_ptr);
memcpy(&req->dest, dest, sizeof(*dest));
req->net = net;
req->bearer_id = b_ptr->identity;
req->domain = b_ptr->domain;
req->num_nodes = 0;
req->timer_intv = TIPC_LINK_REQ_INIT;
spin_lock_init(&req->lock);
k_init_timer(&req->timer, (Handler)disc_timeout, (unsigned long)req);
k_start_timer(&req->timer, req->timer_intv);
setup_timer(&req->timer, disc_timeout, (unsigned long)req);
mod_timer(&req->timer, jiffies + req->timer_intv);
b_ptr->link_req = req;
tipc_bearer_send(req->bearer_id, req->buf, &req->dest);
tipc_bearer_send(net, req->bearer_id, req->buf, &req->dest);
return 0;
}
......@@ -376,28 +391,29 @@ int tipc_disc_create(struct tipc_bearer *b_ptr, struct tipc_media_addr *dest)
*/
void tipc_disc_delete(struct tipc_link_req *req)
{
k_cancel_timer(&req->timer);
k_term_timer(&req->timer);
del_timer_sync(&req->timer);
kfree_skb(req->buf);
kfree(req);
}
/**
* tipc_disc_reset - reset object to send periodic link setup requests
* @net: the applicable net namespace
* @b_ptr: ptr to bearer issuing requests
* @dest_domain: network domain to which links can be established
*/
void tipc_disc_reset(struct tipc_bearer *b_ptr)
void tipc_disc_reset(struct net *net, struct tipc_bearer *b_ptr)
{
struct tipc_link_req *req = b_ptr->link_req;
spin_lock_bh(&req->lock);
tipc_disc_init_msg(req->buf, DSC_REQ_MSG, b_ptr);
tipc_disc_init_msg(net, req->buf, DSC_REQ_MSG, b_ptr);
req->net = net;
req->bearer_id = b_ptr->identity;
req->domain = b_ptr->domain;
req->num_nodes = 0;
req->timer_intv = TIPC_LINK_REQ_INIT;
k_start_timer(&req->timer, req->timer_intv);
tipc_bearer_send(req->bearer_id, req->buf, &req->dest);
mod_timer(&req->timer, jiffies + req->timer_intv);
tipc_bearer_send(net, req->bearer_id, req->buf, &req->dest);
spin_unlock_bh(&req->lock);
}
......@@ -39,11 +39,13 @@
struct tipc_link_req;
int tipc_disc_create(struct tipc_bearer *b_ptr, struct tipc_media_addr *dest);
int tipc_disc_create(struct net *net, struct tipc_bearer *b_ptr,
struct tipc_media_addr *dest);
void tipc_disc_delete(struct tipc_link_req *req);
void tipc_disc_reset(struct tipc_bearer *b_ptr);
void tipc_disc_reset(struct net *net, struct tipc_bearer *b_ptr);
void tipc_disc_add_dest(struct tipc_link_req *req);
void tipc_disc_remove_dest(struct tipc_link_req *req);
void tipc_disc_rcv(struct sk_buff *buf, struct tipc_bearer *b_ptr);
void tipc_disc_rcv(struct net *net, struct sk_buff *buf,
struct tipc_bearer *b_ptr);
#endif
This diff is collapsed.
......@@ -41,6 +41,10 @@
#include "msg.h"
#include "node.h"
/* TIPC-specific error codes
*/
#define ELINKCONG EAGAIN /* link congestion <=> resource unavailable */
/* Out-of-range value for link sequence numbers
*/
#define INVALID_LINK_SEQ 0x10000
......@@ -105,7 +109,7 @@ struct tipc_stats {
* @peer_bearer_id: bearer id used by link's peer endpoint
* @bearer_id: local bearer id used by link
* @tolerance: minimum link continuity loss needed to reset link [in ms]
* @continuity_interval: link continuity testing interval [in ms]
* @cont_intv: link continuity testing interval
* @abort_limit: # of unacknowledged continuity probes needed to reset link
* @state: current state of link FSM
* @fsm_msg_cnt: # of protocol messages link FSM has sent in current state
......@@ -146,7 +150,7 @@ struct tipc_link {
u32 peer_bearer_id;
u32 bearer_id;
u32 tolerance;
u32 continuity_interval;
unsigned long cont_intv;
u32 abort_limit;
int state;
u32 fsm_msg_cnt;
......@@ -196,28 +200,32 @@ struct tipc_port;
struct tipc_link *tipc_link_create(struct tipc_node *n_ptr,
struct tipc_bearer *b_ptr,
const struct tipc_media_addr *media_addr);
void tipc_link_delete_list(unsigned int bearer_id, bool shutting_down);
void tipc_link_delete_list(struct net *net, unsigned int bearer_id,
bool shutting_down);
void tipc_link_failover_send_queue(struct tipc_link *l_ptr);
void tipc_link_dup_queue_xmit(struct tipc_link *l_ptr, struct tipc_link *dest);
void tipc_link_reset_fragments(struct tipc_link *l_ptr);
int tipc_link_is_up(struct tipc_link *l_ptr);
int tipc_link_is_active(struct tipc_link *l_ptr);
void tipc_link_purge_queues(struct tipc_link *l_ptr);
struct sk_buff *tipc_link_cmd_config(const void *req_tlv_area,
int req_tlv_space,
u16 cmd);
struct sk_buff *tipc_link_cmd_show_stats(const void *req_tlv_area,
struct sk_buff *tipc_link_cmd_config(struct net *net, const void *req_tlv_area,
int req_tlv_space, u16 cmd);
struct sk_buff *tipc_link_cmd_show_stats(struct net *net,
const void *req_tlv_area,
int req_tlv_space);
struct sk_buff *tipc_link_cmd_reset_stats(const void *req_tlv_area,
struct sk_buff *tipc_link_cmd_reset_stats(struct net *net,
const void *req_tlv_area,
int req_tlv_space);
void tipc_link_reset_all(struct tipc_node *node);
void tipc_link_reset(struct tipc_link *l_ptr);
void tipc_link_reset_list(unsigned int bearer_id);
int tipc_link_xmit_skb(struct sk_buff *skb, u32 dest, u32 selector);
int tipc_link_xmit(struct sk_buff_head *list, u32 dest, u32 selector);
int __tipc_link_xmit(struct tipc_link *link, struct sk_buff_head *list);
u32 tipc_link_get_max_pkt(u32 dest, u32 selector);
void tipc_link_bundle_rcv(struct sk_buff *buf);
void tipc_link_reset_list(struct net *net, unsigned int bearer_id);
int tipc_link_xmit_skb(struct net *net, struct sk_buff *skb, u32 dest,
u32 selector);
int tipc_link_xmit(struct net *net, struct sk_buff_head *list, u32 dest,
u32 selector);
int __tipc_link_xmit(struct net *net, struct tipc_link *link,
struct sk_buff_head *list);
void tipc_link_bundle_rcv(struct net *net, struct sk_buff *buf);
void tipc_link_proto_xmit(struct tipc_link *l_ptr, u32 msg_typ, int prob,
u32 gap, u32 tolerance, u32 priority, u32 acked_mtu);
void tipc_link_push_packets(struct tipc_link *l_ptr);
......
......@@ -34,6 +34,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <net/sock.h>
#include "core.h"
#include "msg.h"
#include "addr.h"
......@@ -46,25 +47,50 @@ static unsigned int align(unsigned int i)
return (i + 3) & ~3u;
}
void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, u32 hsize,
u32 destnode)
/**
* tipc_buf_acquire - creates a TIPC message buffer
* @size: message size (including TIPC header)
*
* Returns a new buffer with data pointers set to the specified size.
*
* NOTE: Headroom is reserved to allow prepending of a data link header.
* There may also be unrequested tailroom present at the buffer's end.
*/
struct sk_buff *tipc_buf_acquire(u32 size)
{
struct sk_buff *skb;
unsigned int buf_size = (BUF_HEADROOM + size + 3) & ~3u;
skb = alloc_skb_fclone(buf_size, GFP_ATOMIC);
if (skb) {
skb_reserve(skb, BUF_HEADROOM);
skb_put(skb, size);
skb->next = NULL;
}
return skb;
}
void tipc_msg_init(struct net *net, struct tipc_msg *m, u32 user, u32 type,
u32 hsize, u32 destnode)
{
struct tipc_net *tn = net_generic(net, tipc_net_id);
memset(m, 0, hsize);
msg_set_version(m);
msg_set_user(m, user);
msg_set_hdr_sz(m, hsize);
msg_set_size(m, hsize);
msg_set_prevnode(m, tipc_own_addr);
msg_set_prevnode(m, tn->own_addr);
msg_set_type(m, type);
if (hsize > SHORT_H_SIZE) {
msg_set_orignode(m, tipc_own_addr);
msg_set_orignode(m, tn->own_addr);
msg_set_destnode(m, destnode);
}
}
struct sk_buff *tipc_msg_create(uint user, uint type, uint hdr_sz,
uint data_sz, u32 dnode, u32 onode,
u32 dport, u32 oport, int errcode)
struct sk_buff *tipc_msg_create(struct net *net, uint user, uint type,
uint hdr_sz, uint data_sz, u32 dnode,
u32 onode, u32 dport, u32 oport, int errcode)
{
struct tipc_msg *msg;
struct sk_buff *buf;
......@@ -74,7 +100,7 @@ struct sk_buff *tipc_msg_create(uint user, uint type, uint hdr_sz,
return NULL;
msg = buf_msg(buf);
tipc_msg_init(msg, user, type, hdr_sz, dnode);
tipc_msg_init(net, msg, user, type, hdr_sz, dnode);
msg_set_size(msg, hdr_sz + data_sz);
msg_set_prevnode(msg, onode);
msg_set_origport(msg, oport);
......@@ -170,8 +196,8 @@ int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf)
*
* Returns message data size or errno: -ENOMEM, -EFAULT
*/
int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, int offset,
int dsz, int pktmax, struct sk_buff_head *list)
int tipc_msg_build(struct net *net, struct tipc_msg *mhdr, struct msghdr *m,
int offset, int dsz, int pktmax, struct sk_buff_head *list)
{
int mhsz = msg_hdr_sz(mhdr);
int msz = mhsz + dsz;
......@@ -191,6 +217,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, int offset,
skb = tipc_buf_acquire(msz);
if (unlikely(!skb))
return -ENOMEM;
skb_orphan(skb);
__skb_queue_tail(list, skb);
skb_copy_to_linear_data(skb, mhdr, mhsz);
pktpos = skb->data + mhsz;
......@@ -202,8 +229,8 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, int offset,
}
/* Prepare reusable fragment header */
tipc_msg_init(&pkthdr, MSG_FRAGMENTER, FIRST_FRAGMENT,
INT_H_SIZE, msg_destnode(mhdr));
tipc_msg_init(net, &pkthdr, MSG_FRAGMENTER, FIRST_FRAGMENT, INT_H_SIZE,
msg_destnode(mhdr));
msg_set_size(&pkthdr, pktmax);
msg_set_fragm_no(&pkthdr, pktno);
......@@ -211,6 +238,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, int offset,
skb = tipc_buf_acquire(pktmax);
if (!skb)
return -ENOMEM;
skb_orphan(skb);
__skb_queue_tail(list, skb);
pktpos = skb->data;
skb_copy_to_linear_data(skb, &pkthdr, INT_H_SIZE);
......@@ -244,6 +272,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, int offset,
rc = -ENOMEM;
goto error;
}
skb_orphan(skb);
__skb_queue_tail(list, skb);
msg_set_type(&pkthdr, FRAGMENT);
msg_set_size(&pkthdr, pktsz);
......@@ -312,8 +341,8 @@ bool tipc_msg_bundle(struct sk_buff_head *list, struct sk_buff *skb, u32 mtu)
* Replaces buffer if successful
* Returns true if success, otherwise false
*/
bool tipc_msg_make_bundle(struct sk_buff_head *list, struct sk_buff *skb,
u32 mtu, u32 dnode)
bool tipc_msg_make_bundle(struct net *net, struct sk_buff_head *list,
struct sk_buff *skb, u32 mtu, u32 dnode)
{
struct sk_buff *bskb;
struct tipc_msg *bmsg;
......@@ -336,7 +365,7 @@ bool tipc_msg_make_bundle(struct sk_buff_head *list, struct sk_buff *skb,
skb_trim(bskb, INT_H_SIZE);
bmsg = buf_msg(bskb);
tipc_msg_init(bmsg, MSG_BUNDLER, 0, INT_H_SIZE, dnode);
tipc_msg_init(net, bmsg, MSG_BUNDLER, 0, INT_H_SIZE, dnode);
msg_set_seqno(bmsg, msg_seqno(msg));
msg_set_ack(bmsg, msg_ack(msg));
msg_set_bcast_ack(bmsg, msg_bcast_ack(msg));
......@@ -353,8 +382,10 @@ bool tipc_msg_make_bundle(struct sk_buff_head *list, struct sk_buff *skb,
* Consumes buffer if failure
* Returns true if success, otherwise false
*/
bool tipc_msg_reverse(struct sk_buff *buf, u32 *dnode, int err)
bool tipc_msg_reverse(struct net *net, struct sk_buff *buf, u32 *dnode,
int err)
{
struct tipc_net *tn = net_generic(net, tipc_net_id);
struct tipc_msg *msg = buf_msg(buf);
uint imp = msg_importance(msg);
struct tipc_msg ohdr;
......@@ -374,7 +405,7 @@ bool tipc_msg_reverse(struct sk_buff *buf, u32 *dnode, int err)
msg_set_errcode(msg, err);
msg_set_origport(msg, msg_destport(&ohdr));
msg_set_destport(msg, msg_origport(&ohdr));
msg_set_prevnode(msg, tipc_own_addr);
msg_set_prevnode(msg, tn->own_addr);
if (!msg_short(msg)) {
msg_set_orignode(msg, msg_destnode(&ohdr));
msg_set_destnode(msg, msg_orignode(&ohdr));
......@@ -399,7 +430,7 @@ bool tipc_msg_reverse(struct sk_buff *buf, u32 *dnode, int err)
* Returns 0 (TIPC_OK) if message ok and we can try again, -TIPC error
* code if message to be rejected
*/
int tipc_msg_eval(struct sk_buff *buf, u32 *dnode)
int tipc_msg_eval(struct net *net, struct sk_buff *buf, u32 *dnode)
{
struct tipc_msg *msg = buf_msg(buf);
u32 dport;
......@@ -413,8 +444,8 @@ int tipc_msg_eval(struct sk_buff *buf, u32 *dnode)
if (msg_reroute_cnt(msg) > 0)
return -TIPC_ERR_NO_NAME;
*dnode = addr_domain(msg_lookup_scope(msg));
dport = tipc_nametbl_translate(msg_nametype(msg),
*dnode = addr_domain(net, msg_lookup_scope(msg));
dport = tipc_nametbl_translate(net, msg_nametype(msg),
msg_nameinst(msg),
dnode);
if (!dport)
......
......@@ -37,7 +37,7 @@
#ifndef _TIPC_MSG_H
#define _TIPC_MSG_H
#include "bearer.h"
#include <linux/tipc.h>
/*
* Constants and routines used to read and write TIPC payload message headers
......@@ -77,11 +77,37 @@
#define TIPC_MEDIA_ADDR_OFFSET 5
/**
* TIPC message buffer code
*
* TIPC message buffer headroom reserves space for the worst-case
* link-level device header (in case the message is sent off-node).
*
* Note: Headroom should be a multiple of 4 to ensure the TIPC header fields
* are word aligned for quicker access
*/
#define BUF_HEADROOM LL_MAX_HEADER
struct tipc_skb_cb {
void *handle;
struct sk_buff *tail;
bool deferred;
bool wakeup_pending;
bool bundling;
u16 chain_sz;
u16 chain_imp;
};
#define TIPC_SKB_CB(__skb) ((struct tipc_skb_cb *)&((__skb)->cb[0]))
struct tipc_msg {
__be32 hdr[15];
};
static inline struct tipc_msg *buf_msg(struct sk_buff *skb)
{
return (struct tipc_msg *)skb->data;
}
static inline u32 msg_word(struct tipc_msg *m, u32 pos)
{
......@@ -721,27 +747,21 @@ static inline u32 msg_tot_origport(struct tipc_msg *m)
return msg_origport(m);
}
bool tipc_msg_reverse(struct sk_buff *buf, u32 *dnode, int err);
int tipc_msg_eval(struct sk_buff *buf, u32 *dnode);
void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, u32 hsize,
u32 destnode);
struct sk_buff *tipc_msg_create(uint user, uint type, uint hdr_sz,
uint data_sz, u32 dnode, u32 onode,
u32 dport, u32 oport, int errcode);
struct sk_buff *tipc_buf_acquire(u32 size);
bool tipc_msg_reverse(struct net *net, struct sk_buff *buf, u32 *dnode,
int err);
int tipc_msg_eval(struct net *net, struct sk_buff *buf, u32 *dnode);
void tipc_msg_init(struct net *net, struct tipc_msg *m, u32 user, u32 type,
u32 hsize, u32 destnode);
struct sk_buff *tipc_msg_create(struct net *net, uint user, uint type,
uint hdr_sz, uint data_sz, u32 dnode,
u32 onode, u32 dport, u32 oport, int errcode);
int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf);
bool tipc_msg_bundle(struct sk_buff_head *list, struct sk_buff *skb, u32 mtu);
bool tipc_msg_make_bundle(struct sk_buff_head *list, struct sk_buff *skb,
u32 mtu, u32 dnode);
int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m, int offset,
int dsz, int mtu, struct sk_buff_head *list);
bool tipc_msg_make_bundle(struct net *net, struct sk_buff_head *list,
struct sk_buff *skb, u32 mtu, u32 dnode);
int tipc_msg_build(struct net *net, struct tipc_msg *mhdr, struct msghdr *m,
int offset, int dsz, int mtu, struct sk_buff_head *list);
struct sk_buff *tipc_msg_reassemble(struct sk_buff_head *list);
#endif
This diff is collapsed.
......@@ -67,13 +67,13 @@ struct distr_item {
__be32 key;
};
struct sk_buff *tipc_named_publish(struct publication *publ);
struct sk_buff *tipc_named_withdraw(struct publication *publ);
void named_cluster_distribute(struct sk_buff *buf);
void tipc_named_node_up(u32 dnode);
void tipc_named_rcv(struct sk_buff *buf);
void tipc_named_reinit(void);
void tipc_named_process_backlog(void);
void tipc_publ_notify(struct list_head *nsub_list, u32 addr);
struct sk_buff *tipc_named_publish(struct net *net, struct publication *publ);
struct sk_buff *tipc_named_withdraw(struct net *net, struct publication *publ);
void named_cluster_distribute(struct net *net, struct sk_buff *buf);
void tipc_named_node_up(struct net *net, u32 dnode);
void tipc_named_rcv(struct net *net, struct sk_buff *buf);
void tipc_named_reinit(struct net *net);
void tipc_named_process_backlog(struct net *net);
void tipc_publ_notify(struct net *net, struct list_head *nsub_list, u32 addr);
#endif
This diff is collapsed.
......@@ -95,26 +95,27 @@ struct name_table {
u32 local_publ_count;
};
extern spinlock_t tipc_nametbl_lock;
extern struct name_table *tipc_nametbl;
int tipc_nl_name_table_dump(struct sk_buff *skb, struct netlink_callback *cb);
struct sk_buff *tipc_nametbl_get(const void *req_tlv_area, int req_tlv_space);
u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *node);
int tipc_nametbl_mc_translate(u32 type, u32 lower, u32 upper, u32 limit,
struct tipc_port_list *dports);
struct publication *tipc_nametbl_publish(u32 type, u32 lower, u32 upper,
u32 scope, u32 port_ref, u32 key);
int tipc_nametbl_withdraw(u32 type, u32 lower, u32 ref, u32 key);
struct publication *tipc_nametbl_insert_publ(u32 type, u32 lower, u32 upper,
u32 scope, u32 node, u32 ref,
struct sk_buff *tipc_nametbl_get(struct net *net, const void *req_tlv_area,
int req_tlv_space);
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,
u32 limit, struct tipc_port_list *dports);
struct publication *tipc_nametbl_publish(struct net *net, u32 type, u32 lower,
u32 upper, u32 scope, u32 port_ref,
u32 key);
int tipc_nametbl_withdraw(struct net *net, u32 type, u32 lower, u32 ref,
u32 key);
struct publication *tipc_nametbl_insert_publ(struct net *net, u32 type,
u32 lower, u32 upper, u32 scope,
u32 node, u32 ref, u32 key);
struct publication *tipc_nametbl_remove_publ(struct net *net, u32 type,
u32 lower, u32 node, u32 ref,
u32 key);
struct publication *tipc_nametbl_remove_publ(u32 type, u32 lower, u32 node,
u32 ref, u32 key);
void tipc_nametbl_subscribe(struct tipc_subscription *s);
void tipc_nametbl_unsubscribe(struct tipc_subscription *s);
int tipc_nametbl_init(void);
void tipc_nametbl_stop(void);
int tipc_nametbl_init(struct net *net);
void tipc_nametbl_stop(struct net *net);
#endif
......@@ -41,6 +41,7 @@
#include "socket.h"
#include "node.h"
#include "config.h"
#include "bcast.h"
static const struct nla_policy tipc_nl_net_policy[TIPC_NLA_NET_MAX + 1] = {
[TIPC_NLA_NET_UNSPEC] = { .type = NLA_UNSPEC },
......@@ -108,44 +109,50 @@ static const struct nla_policy tipc_nl_net_policy[TIPC_NLA_NET_MAX + 1] = {
* - A local spin_lock protecting the queue of subscriber events.
*/
int tipc_net_start(u32 addr)
int tipc_net_start(struct net *net, u32 addr)
{
struct tipc_net *tn = net_generic(net, tipc_net_id);
char addr_string[16];
int res;
tipc_own_addr = addr;
tipc_named_reinit();
tipc_sk_reinit();
res = tipc_bclink_init();
tn->own_addr = addr;
tipc_named_reinit(net);
tipc_sk_reinit(net);
res = tipc_bclink_init(net);
if (res)
return res;
tipc_nametbl_publish(TIPC_CFG_SRV, tipc_own_addr, tipc_own_addr,
TIPC_ZONE_SCOPE, 0, tipc_own_addr);
tipc_nametbl_publish(net, TIPC_CFG_SRV, tn->own_addr, tn->own_addr,
TIPC_ZONE_SCOPE, 0, tn->own_addr);
pr_info("Started in network mode\n");
pr_info("Own node address %s, network identity %u\n",
tipc_addr_string_fill(addr_string, tipc_own_addr), tipc_net_id);
tipc_addr_string_fill(addr_string, tn->own_addr),
tn->net_id);
return 0;
}
void tipc_net_stop(void)
void tipc_net_stop(struct net *net)
{
if (!tipc_own_addr)
struct tipc_net *tn = net_generic(net, tipc_net_id);
if (!tn->own_addr)
return;
tipc_nametbl_withdraw(TIPC_CFG_SRV, tipc_own_addr, 0, tipc_own_addr);
tipc_nametbl_withdraw(net, TIPC_CFG_SRV, tn->own_addr, 0,
tn->own_addr);
rtnl_lock();
tipc_bearer_stop();
tipc_bclink_stop();
tipc_node_stop();
tipc_bearer_stop(net);
tipc_bclink_stop(net);
tipc_node_stop(net);
rtnl_unlock();
pr_info("Left network mode\n");
}
static int __tipc_nl_add_net(struct tipc_nl_msg *msg)
static int __tipc_nl_add_net(struct net *net, struct tipc_nl_msg *msg)
{
struct tipc_net *tn = net_generic(net, tipc_net_id);
void *hdr;
struct nlattr *attrs;
......@@ -158,7 +165,7 @@ static int __tipc_nl_add_net(struct tipc_nl_msg *msg)
if (!attrs)
goto msg_full;
if (nla_put_u32(msg->skb, TIPC_NLA_NET_ID, tipc_net_id))
if (nla_put_u32(msg->skb, TIPC_NLA_NET_ID, tn->net_id))
goto attr_msg_full;
nla_nest_end(msg->skb, attrs);
......@@ -176,6 +183,7 @@ static int __tipc_nl_add_net(struct tipc_nl_msg *msg)
int tipc_nl_net_dump(struct sk_buff *skb, struct netlink_callback *cb)
{
struct net *net = sock_net(skb->sk);
int err;
int done = cb->args[0];
struct tipc_nl_msg msg;
......@@ -187,7 +195,7 @@ int tipc_nl_net_dump(struct sk_buff *skb, struct netlink_callback *cb)
msg.portid = NETLINK_CB(cb->skb).portid;
msg.seq = cb->nlh->nlmsg_seq;
err = __tipc_nl_add_net(&msg);
err = __tipc_nl_add_net(net, &msg);
if (err)
goto out;
......@@ -200,8 +208,10 @@ int tipc_nl_net_dump(struct sk_buff *skb, struct netlink_callback *cb)
int tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info)
{
int err;
struct net *net = genl_info_net(info);
struct tipc_net *tn = net_generic(net, tipc_net_id);
struct nlattr *attrs[TIPC_NLA_NET_MAX + 1];
int err;
if (!info->attrs[TIPC_NLA_NET])
return -EINVAL;
......@@ -216,21 +226,21 @@ int tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info)
u32 val;
/* Can't change net id once TIPC has joined a network */
if (tipc_own_addr)
if (tn->own_addr)
return -EPERM;
val = nla_get_u32(attrs[TIPC_NLA_NET_ID]);
if (val < 1 || val > 9999)
return -EINVAL;
tipc_net_id = val;
tn->net_id = val;
}
if (attrs[TIPC_NLA_NET_ADDR]) {
u32 addr;
/* Can't change net addr once TIPC has joined a network */
if (tipc_own_addr)
if (tn->own_addr)
return -EPERM;
addr = nla_get_u32(attrs[TIPC_NLA_NET_ADDR]);
......@@ -238,7 +248,7 @@ int tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info)
return -EINVAL;
rtnl_lock();
tipc_net_start(addr);
tipc_net_start(net, addr);
rtnl_unlock();
}
......
......@@ -39,9 +39,9 @@
#include <net/genetlink.h>
int tipc_net_start(u32 addr);
int tipc_net_start(struct net *net, u32 addr);
void tipc_net_stop(void);
void tipc_net_stop(struct net *net);
int tipc_nl_net_dump(struct sk_buff *skb, struct netlink_callback *cb);
int tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info);
......
......@@ -46,6 +46,7 @@
static int handle_cmd(struct sk_buff *skb, struct genl_info *info)
{
struct net *net = genl_info_net(info);
struct sk_buff *rep_buf;
struct nlmsghdr *rep_nlh;
struct nlmsghdr *req_nlh = info->nlhdr;
......@@ -53,22 +54,24 @@ static int handle_cmd(struct sk_buff *skb, struct genl_info *info)
int hdr_space = nlmsg_total_size(GENL_HDRLEN + TIPC_GENL_HDRLEN);
u16 cmd;
if ((req_userhdr->cmd & 0xC000) && (!netlink_capable(skb, CAP_NET_ADMIN)))
if ((req_userhdr->cmd & 0xC000) &&
(!netlink_net_capable(skb, CAP_NET_ADMIN)))
cmd = TIPC_CMD_NOT_NET_ADMIN;
else
cmd = req_userhdr->cmd;
rep_buf = tipc_cfg_do_cmd(req_userhdr->dest, cmd,
nlmsg_data(req_nlh) + GENL_HDRLEN + TIPC_GENL_HDRLEN,
nlmsg_attrlen(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN),
hdr_space);
rep_buf = tipc_cfg_do_cmd(net, req_userhdr->dest, cmd,
nlmsg_data(req_nlh) + GENL_HDRLEN +
TIPC_GENL_HDRLEN,
nlmsg_attrlen(req_nlh, GENL_HDRLEN +
TIPC_GENL_HDRLEN), hdr_space);
if (rep_buf) {
skb_push(rep_buf, hdr_space);
rep_nlh = nlmsg_hdr(rep_buf);
memcpy(rep_nlh, req_nlh, hdr_space);
rep_nlh->nlmsg_len = rep_buf->len;
genlmsg_unicast(&init_net, rep_buf, NETLINK_CB(skb).portid);
genlmsg_unicast(net, rep_buf, NETLINK_CB(skb).portid);
}
return 0;
......@@ -93,6 +96,7 @@ static struct genl_family tipc_genl_family = {
.version = TIPC_GENL_VERSION,
.hdrsize = TIPC_GENL_HDRLEN,
.maxattr = 0,
.netnsok = true,
};
/* Legacy ASCII API */
......@@ -112,6 +116,7 @@ struct genl_family tipc_genl_v2_family = {
.version = TIPC_GENL_V2_VERSION,
.hdrsize = 0,
.maxattr = TIPC_NLA_MAX,
.netnsok = true,
};
static const struct genl_ops tipc_genl_v2_ops[] = {
......
......@@ -45,4 +45,7 @@ struct tipc_nl_msg {
u32 seq;
};
int tipc_netlink_start(void);
void tipc_netlink_stop(void);
#endif
This diff is collapsed.
......@@ -42,10 +42,10 @@
#include "bearer.h"
#include "msg.h"
/*
* Out-of-range value for node signature
*/
#define INVALID_NODE_SIG 0x10000
/* Out-of-range value for node signature */
#define INVALID_NODE_SIG 0x10000
#define NODE_HTABLE_SIZE 512
/* Flags used to take different actions according to flag type
* TIPC_WAIT_PEER_LINKS_DOWN: wait to see that peer's links are down
......@@ -90,6 +90,7 @@ struct tipc_node_bclink {
* struct tipc_node - TIPC node structure
* @addr: network address of node
* @lock: spinlock governing access to structure
* @net: the applicable net namespace
* @hash: links to adjacent nodes in unsorted hash chain
* @active_links: pointers to active links to node
* @links: pointers to all links to node
......@@ -106,6 +107,7 @@ struct tipc_node_bclink {
struct tipc_node {
u32 addr;
spinlock_t lock;
struct net *net;
struct hlist_node hash;
struct tipc_link *active_links[2];
u32 act_mtus[2];
......@@ -123,23 +125,24 @@ struct tipc_node {
struct rcu_head rcu;
};
extern struct list_head tipc_node_list;
struct tipc_node *tipc_node_find(u32 addr);
struct tipc_node *tipc_node_create(u32 addr);
void tipc_node_stop(void);
struct tipc_node *tipc_node_find(struct net *net, u32 addr);
struct tipc_node *tipc_node_create(struct net *net, u32 addr);
void tipc_node_stop(struct net *net);
void tipc_node_attach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr);
void tipc_node_detach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr);
void tipc_node_link_down(struct tipc_node *n_ptr, struct tipc_link *l_ptr);
void tipc_node_link_up(struct tipc_node *n_ptr, struct tipc_link *l_ptr);
int tipc_node_active_links(struct tipc_node *n_ptr);
int tipc_node_is_up(struct tipc_node *n_ptr);
struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space);
struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space);
int tipc_node_get_linkname(u32 bearer_id, u32 node, char *linkname, size_t len);
struct sk_buff *tipc_node_get_links(struct net *net, const void *req_tlv_area,
int req_tlv_space);
struct sk_buff *tipc_node_get_nodes(struct net *net, const void *req_tlv_area,
int req_tlv_space);
int tipc_node_get_linkname(struct net *net, u32 bearer_id, u32 node,
char *linkname, size_t len);
void tipc_node_unlock(struct tipc_node *node);
int tipc_node_add_conn(u32 dnode, u32 port, u32 peer_port);
void tipc_node_remove_conn(u32 dnode, u32 port);
int tipc_node_add_conn(struct net *net, u32 dnode, u32 port, u32 peer_port);
void tipc_node_remove_conn(struct net *net, u32 dnode, u32 port);
int tipc_nl_node_dump(struct sk_buff *skb, struct netlink_callback *cb);
......@@ -154,12 +157,12 @@ static inline bool tipc_node_blocked(struct tipc_node *node)
TIPC_NOTIFY_NODE_DOWN | TIPC_WAIT_OWN_LINKS_DOWN));
}
static inline uint tipc_node_get_mtu(u32 addr, u32 selector)
static inline uint tipc_node_get_mtu(struct net *net, u32 addr, u32 selector)
{
struct tipc_node *node;
u32 mtu;
node = tipc_node_find(addr);
node = tipc_node_find(net, addr);
if (likely(node))
mtu = node->act_mtus[selector & 1];
......
......@@ -35,6 +35,7 @@
#include "server.h"
#include "core.h"
#include "socket.h"
#include <net/sock.h>
/* Number of messages to send before rescheduling */
......@@ -255,7 +256,8 @@ static int tipc_receive_from_sock(struct tipc_conn *con)
goto out_close;
}
s->tipc_conn_recvmsg(con->conid, &addr, con->usr_data, buf, ret);
s->tipc_conn_recvmsg(sock_net(con->sock->sk), con->conid, &addr,
con->usr_data, buf, ret);
kmem_cache_free(s->rcvbuf_cache, buf);
......@@ -307,7 +309,7 @@ static struct socket *tipc_create_listen_sock(struct tipc_conn *con)
struct socket *sock = NULL;
int ret;
ret = tipc_sock_create_local(s->type, &sock);
ret = tipc_sock_create_local(s->net, s->type, &sock);
if (ret < 0)
return NULL;
ret = kernel_setsockopt(sock, SOL_TIPC, TIPC_IMPORTANCE,
......
......@@ -36,7 +36,9 @@
#ifndef _TIPC_SERVER_H
#define _TIPC_SERVER_H
#include "core.h"
#include <linux/idr.h>
#include <linux/tipc.h>
#include <net/net_namespace.h>
#define TIPC_SERVER_NAME_LEN 32
......@@ -45,6 +47,7 @@
* @conn_idr: identifier set of connection
* @idr_lock: protect the connection identifier set
* @idr_in_use: amount of allocated identifier entry
* @net: network namspace instance
* @rcvbuf_cache: memory cache of server receive buffer
* @rcv_wq: receive workqueue
* @send_wq: send workqueue
......@@ -61,16 +64,18 @@ struct tipc_server {
struct idr conn_idr;
spinlock_t idr_lock;
int idr_in_use;
struct net *net;
struct kmem_cache *rcvbuf_cache;
struct workqueue_struct *rcv_wq;
struct workqueue_struct *send_wq;
int max_rcvbuf_size;
void *(*tipc_conn_new) (int conid);
void (*tipc_conn_shutdown) (int conid, void *usr_data);
void (*tipc_conn_recvmsg) (int conid, struct sockaddr_tipc *addr,
void *usr_data, void *buf, size_t len);
void *(*tipc_conn_new)(int conid);
void (*tipc_conn_shutdown)(int conid, void *usr_data);
void (*tipc_conn_recvmsg)(struct net *net, int conid,
struct sockaddr_tipc *addr, void *usr_data,
void *buf, size_t len);
struct sockaddr_tipc *saddr;
const char name[TIPC_SERVER_NAME_LEN];
char name[TIPC_SERVER_NAME_LEN];
int imp;
int type;
};
......
This diff is collapsed.
......@@ -42,12 +42,19 @@
#define TIPC_FLOWCTRL_WIN (TIPC_CONNACK_INTV * 2)
#define TIPC_CONN_OVERLOAD_LIMIT ((TIPC_FLOWCTRL_WIN * 2 + 1) * \
SKB_TRUESIZE(TIPC_MAX_USER_MSG_SIZE))
int tipc_sk_rcv(struct sk_buff *buf);
struct sk_buff *tipc_sk_socks_show(void);
void tipc_sk_mcast_rcv(struct sk_buff *buf);
void tipc_sk_reinit(void);
int tipc_sk_rht_init(void);
void tipc_sk_rht_destroy(void);
int tipc_socket_init(void);
void tipc_socket_stop(void);
int tipc_sock_create_local(struct net *net, int type, struct socket **res);
void tipc_sock_release_local(struct socket *sock);
int tipc_sock_accept_local(struct socket *sock, struct socket **newsock,
int flags);
int tipc_sk_rcv(struct net *net, struct sk_buff *buf);
struct sk_buff *tipc_sk_socks_show(struct net *net);
void tipc_sk_mcast_rcv(struct net *net, struct sk_buff *buf);
void tipc_sk_reinit(struct net *net);
int tipc_sk_rht_init(struct net *net);
void tipc_sk_rht_destroy(struct net *net);
int tipc_nl_sk_dump(struct sk_buff *skb, struct netlink_callback *cb);
int tipc_nl_publ_dump(struct sk_buff *skb, struct netlink_callback *cb);
......
This diff is collapsed.
......@@ -39,6 +39,9 @@
#include "server.h"
#define TIPC_MAX_SUBSCRIPTIONS 65535
#define TIPC_MAX_PUBLICATIONS 65535
struct tipc_subscription;
struct tipc_subscriber;
......@@ -46,6 +49,7 @@ struct tipc_subscriber;
* struct tipc_subscription - TIPC network topology subscription object
* @subscriber: pointer to its subscriber
* @seq: name sequence associated with subscription
* @net: point to network namespace
* @timeout: duration of subscription (in ms)
* @filter: event filtering to be done for subscription
* @timer: timer governing subscription duration (optional)
......@@ -58,7 +62,8 @@ struct tipc_subscriber;
struct tipc_subscription {
struct tipc_subscriber *subscriber;
struct tipc_name_seq seq;
u32 timeout;
struct net *net;
unsigned long timeout;
u32 filter;
struct timer_list timer;
struct list_head nameseq_list;
......@@ -69,13 +74,10 @@ struct tipc_subscription {
int tipc_subscr_overlap(struct tipc_subscription *sub, u32 found_lower,
u32 found_upper);
void tipc_subscr_report_overlap(struct tipc_subscription *sub, u32 found_lower,
u32 found_upper, u32 event, u32 port_ref,
u32 node, int must);
int tipc_subscr_start(void);
void tipc_subscr_stop(void);
int tipc_subscr_start(struct net *net);
void tipc_subscr_stop(struct net *net);
#endif
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