Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6851cf28 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'tipc-slim-down-name-table'



Jon Maloy says:

====================
tipc: slim down name table

We clean up and improve the name binding table:

 - Replace the memory consuming 'sub_sequence/service range' array with
   an RB tree.
 - Introduce support for overlapping service sequences/ranges

 v2: #1: Fixed a missing initialization reported by David Miller
     #4: Obsoleted and replaced a few more macros to get a consistent
         terminology in the API.
     #5: Added new commit to fix a potential string overflow bug (it
         is still only in net-next) reported by Arnd Bergmann
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 24197ee2 7494cfa6
Loading
Loading
Loading
Loading
+34 −25
Original line number Diff line number Diff line
@@ -45,33 +45,33 @@
 * TIPC addressing primitives
 */

struct tipc_portid {
struct tipc_socket_addr {
	__u32 ref;
	__u32 node;
};

struct tipc_name {
struct tipc_service_addr {
	__u32 type;
	__u32 instance;
};

struct tipc_name_seq {
struct tipc_service_range {
	__u32 type;
	__u32 lower;
	__u32 upper;
};

/*
 * Application-accessible port name types
 * Application-accessible service types
 */

#define TIPC_CFG_SRV		0	/* configuration service name type */
#define TIPC_TOP_SRV		1	/* topology service name type */
#define TIPC_LINK_STATE		2	/* link state name type */
#define TIPC_RESERVED_TYPES	64	/* lowest user-publishable name type */
#define TIPC_NODE_STATE		0	/* node state service type */
#define TIPC_TOP_SRV		1	/* topology server service type */
#define TIPC_LINK_STATE		2	/* link state service type */
#define TIPC_RESERVED_TYPES	64	/* lowest user-allowed service type */

/*
 * Publication scopes when binding port names and port name sequences
 * Publication scopes when binding service / service range
 */
enum tipc_scope {
	TIPC_CLUSTER_SCOPE = 2, /* 0 can also be used */
@@ -108,28 +108,28 @@ enum tipc_scope {
 * TIPC topology subscription service definitions
 */

#define TIPC_SUB_PORTS		0x01	/* filter for port availability */
#define TIPC_SUB_SERVICE	0x02	/* filter for service availability */
#define TIPC_SUB_CANCEL		0x04	/* cancel a subscription */
#define TIPC_SUB_PORTS          0x01    /* filter: evt at each match */
#define TIPC_SUB_SERVICE        0x02    /* filter: evt at first up/last down */
#define TIPC_SUB_CANCEL         0x04    /* filter: cancel a subscription */

#define TIPC_WAIT_FOREVER	(~0)	/* timeout for permanent subscription */

struct tipc_subscr {
	struct tipc_name_seq seq;	/* name sequence of interest */
	struct tipc_service_range seq;	/* range of interest */
	__u32 timeout;			/* subscription duration (in ms) */
	__u32 filter;			/* bitmask of filter options */
	char usr_handle[8];		/* available for subscriber use */
};

#define TIPC_PUBLISHED		1	/* publication event */
#define TIPC_WITHDRAWN		2	/* withdraw event */
#define TIPC_WITHDRAWN		2	/* withdrawal event */
#define TIPC_SUBSCR_TIMEOUT	3	/* subscription timeout event */

struct tipc_event {
	__u32 event;			/* event type */
	__u32 found_lower;		/* matching name seq instances */
	__u32 found_upper;		/*    "      "    "     "      */
	struct tipc_portid port;	/* associated port */
	__u32 found_lower;		/* matching range */
	__u32 found_upper;		/*    "      "    */
	struct tipc_socket_addr port;	/* associated socket */
	struct tipc_subscr s;		/* associated subscription */
};

@@ -149,20 +149,20 @@ struct tipc_event {
#define SOL_TIPC	271
#endif

#define TIPC_ADDR_NAMESEQ	1
#define TIPC_ADDR_MCAST         1
#define TIPC_ADDR_NAME		2
#define TIPC_ADDR_ID		3
#define TIPC_SERVICE_RANGE      1
#define TIPC_SERVICE_ADDR       2
#define TIPC_SOCKET_ADDR        3

struct sockaddr_tipc {
	unsigned short family;
	unsigned char  addrtype;
	signed   char  scope;
	union {
		struct tipc_portid id;
		struct tipc_name_seq nameseq;
		struct tipc_socket_addr id;
		struct tipc_service_range nameseq;
		struct {
			struct tipc_name name;
			struct tipc_service_addr name;
			__u32 domain;
		} name;
	} addr;
@@ -216,7 +216,7 @@ struct tipc_group_req {
#define TIPC_MAX_MEDIA_NAME	16
#define TIPC_MAX_IF_NAME	16
#define TIPC_MAX_BEARER_NAME	32
#define TIPC_MAX_LINK_NAME	60
#define TIPC_MAX_LINK_NAME	68

#define SIOCGETLINKNAME		SIOCPROTOPRIVATE

@@ -230,8 +230,13 @@ struct tipc_sioc_ln_req {
/* The macros and functions below are deprecated:
 */

#define TIPC_CFG_SRV		0
#define TIPC_ZONE_SCOPE         1

#define TIPC_ADDR_NAMESEQ	1
#define TIPC_ADDR_NAME		2
#define TIPC_ADDR_ID		3

#define TIPC_NODE_BITS          12
#define TIPC_CLUSTER_BITS       12
#define TIPC_ZONE_BITS          8
@@ -250,6 +255,10 @@ struct tipc_sioc_ln_req {

#define TIPC_ZONE_CLUSTER_MASK (TIPC_ZONE_MASK | TIPC_CLUSTER_MASK)

#define tipc_portid tipc_socket_addr
#define tipc_name tipc_service_addr
#define tipc_name_seq tipc_service_range

static inline __u32 tipc_addr(unsigned int zone,
			      unsigned int cluster,
			      unsigned int node)
+1 −0
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@
#include <linux/etherdevice.h>
#include <net/netns/generic.h>
#include <linux/rhashtable.h>
#include <net/genetlink.h>

struct tipc_node;
struct tipc_bearer;
+3 −2
Original line number Diff line number Diff line
@@ -462,7 +462,8 @@ bool tipc_link_create(struct net *net, char *if_name, int bearer_id,
			sprintf(peer_str, "%x", peer);
	}
	/* Peer i/f name will be completed by reset/activate message */
	sprintf(l->name, "%s:%s-%s:unknown", self_str, if_name, peer_str);
	snprintf(l->name, sizeof(l->name), "%s:%s-%s:unknown",
		 self_str, if_name, peer_str);

	strcpy(l->if_name, if_name);
	l->addr = peer;
@@ -1810,7 +1811,7 @@ int tipc_link_bc_nack_rcv(struct tipc_link *l, struct sk_buff *skb,

void tipc_link_set_queue_limits(struct tipc_link *l, u32 win)
{
	int max_bulk = TIPC_MAX_PUBLICATIONS / (l->mtu / ITEM_SIZE);
	int max_bulk = TIPC_MAX_PUBL / (l->mtu / ITEM_SIZE);

	l->window = win;
	l->backlog[TIPC_LOW_IMPORTANCE].limit      = max_t(u16, 50, win);
+22 −68
Original line number Diff line number Diff line
@@ -204,12 +204,12 @@ void tipc_named_node_up(struct net *net, u32 dnode)
 */
static void tipc_publ_purge(struct net *net, struct publication *publ, u32 addr)
{
	struct tipc_net *tn = net_generic(net, tipc_net_id);
	struct tipc_net *tn = tipc_net(net);
	struct publication *p;

	spin_lock_bh(&tn->nametbl_lock);
	p = tipc_nametbl_remove_publ(net, publ->type, publ->lower,
				     publ->node, publ->port, publ->key);
	p = tipc_nametbl_remove_publ(net, publ->type, publ->lower, publ->upper,
				     publ->node, publ->key);
	if (p)
		tipc_node_unsubscribe(net, &p->binding_node, addr);
	spin_unlock_bh(&tn->nametbl_lock);
@@ -261,81 +261,37 @@ void tipc_publ_notify(struct net *net, struct list_head *nsub_list, u32 addr)
static bool tipc_update_nametbl(struct net *net, struct distr_item *i,
				u32 node, u32 dtype)
{
	struct publication *publ = NULL;
	struct publication *p = NULL;
	u32 lower = ntohl(i->lower);
	u32 upper = ntohl(i->upper);
	u32 type = ntohl(i->type);
	u32 port = ntohl(i->port);
	u32 key = ntohl(i->key);

	if (dtype == PUBLICATION) {
		publ = tipc_nametbl_insert_publ(net, ntohl(i->type),
						ntohl(i->lower),
						ntohl(i->upper),
		p = tipc_nametbl_insert_publ(net, type, lower, upper,
					     TIPC_CLUSTER_SCOPE, node,
						ntohl(i->port), ntohl(i->key));
		if (publ) {
			tipc_node_subscribe(net, &publ->binding_node, node);
					     port, key);
		if (p) {
			tipc_node_subscribe(net, &p->binding_node, node);
			return true;
		}
	} else if (dtype == WITHDRAWAL) {
		publ = tipc_nametbl_remove_publ(net, ntohl(i->type),
						ntohl(i->lower),
						node, ntohl(i->port),
						ntohl(i->key));
		if (publ) {
			tipc_node_unsubscribe(net, &publ->binding_node, node);
			kfree_rcu(publ, rcu);
		p = tipc_nametbl_remove_publ(net, type, lower,
					     upper, node, key);
		if (p) {
			tipc_node_unsubscribe(net, &p->binding_node, node);
			kfree_rcu(p, rcu);
			return true;
		}
		pr_warn_ratelimited("Failed to remove binding %u,%u from %x\n",
				    type, lower, node);
	} else {
		pr_warn("Unrecognized name table message received\n");
	}
	return false;
}

/**
 * tipc_named_add_backlog - add a failed name table update to the backlog
 *
 */
static void tipc_named_add_backlog(struct net *net, struct distr_item *i,
				   u32 type, u32 node)
{
	struct distr_queue_item *e;
	struct tipc_net *tn = net_generic(net, tipc_net_id);
	unsigned long now = get_jiffies_64();

	e = kzalloc(sizeof(*e), GFP_ATOMIC);
	if (!e)
		return;
	e->dtype = type;
	e->node = node;
	e->expires = now + msecs_to_jiffies(sysctl_tipc_named_timeout);
	memcpy(e, i, sizeof(*i));
	list_add_tail(&e->next, &tn->dist_queue);
}

/**
 * tipc_named_process_backlog - try to process any pending name table updates
 * from the network.
 */
void tipc_named_process_backlog(struct net *net)
{
	struct distr_queue_item *e, *tmp;
	struct tipc_net *tn = net_generic(net, tipc_net_id);
	unsigned long now = get_jiffies_64();

	list_for_each_entry_safe(e, tmp, &tn->dist_queue, next) {
		if (time_after(e->expires, now)) {
			if (!tipc_update_nametbl(net, &e->i, e->node, e->dtype))
				continue;
		} else {
			pr_warn_ratelimited("Dropping name table update (%d) of {%u, %u, %u} from %x key=%u\n",
					    e->dtype, ntohl(e->i.type),
					    ntohl(e->i.lower),
					    ntohl(e->i.upper),
					    e->node, ntohl(e->i.key));
		}
		list_del(&e->next);
		kfree(e);
	}
}

/**
 * tipc_named_rcv - process name table update messages sent by another node
 */
@@ -358,12 +314,10 @@ void tipc_named_rcv(struct net *net, struct sk_buff_head *inputq)
		count = msg_data_sz(msg) / ITEM_SIZE;
		node = msg_orignode(msg);
		while (count--) {
			if (!tipc_update_nametbl(net, item, node, mtype))
				tipc_named_add_backlog(net, item, mtype, node);
			tipc_update_nametbl(net, item, node, mtype);
			item++;
		}
		kfree_skb(skb);
		tipc_named_process_backlog(net);
	}
	spin_unlock_bh(&tn->nametbl_lock);
}
+0 −1
Original line number Diff line number Diff line
@@ -72,7 +72,6 @@ struct sk_buff *tipc_named_withdraw(struct net *net, struct publication *publ);
void tipc_named_node_up(struct net *net, u32 dnode);
void tipc_named_rcv(struct net *net, struct sk_buff_head *msg_queue);
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
Loading