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

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

Merge branch 'tipc'

Jon Maloy says:

====================
Some small and relatively straightforward patches. With exception of
the two first ones they are all unrelated and address minor issues.

v2: update of v1 (http://patchwork.ozlabs.org/patch/277404/

)

-added commit to use memcpy_fromiovec on user data as per v1 feedback
-updated sparse fix commit to drop chunks covered by above commit
-added new commit that greatly simplifies the link lookup routine
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 7cc7c5e5 bbfbe47c
Loading
Loading
Loading
Loading
+5 −13
Original line number Original line Diff line number Diff line
@@ -387,7 +387,7 @@ restart:


	b_ptr = &tipc_bearers[bearer_id];
	b_ptr = &tipc_bearers[bearer_id];
	strcpy(b_ptr->name, name);
	strcpy(b_ptr->name, name);
	res = m_ptr->enable_bearer(b_ptr);
	res = m_ptr->enable_media(b_ptr);
	if (res) {
	if (res) {
		pr_warn("Bearer <%s> rejected, enable failure (%d)\n",
		pr_warn("Bearer <%s> rejected, enable failure (%d)\n",
			name, -res);
			name, -res);
@@ -420,23 +420,15 @@ exit:
}
}


/**
/**
 * tipc_block_bearer - Block the bearer with the given name, and reset all its links
 * tipc_block_bearer - Block the bearer, and reset all its links
 */
 */
int tipc_block_bearer(const char *name)
int tipc_block_bearer(struct tipc_bearer *b_ptr)
{
{
	struct tipc_bearer *b_ptr = NULL;
	struct tipc_link *l_ptr;
	struct tipc_link *l_ptr;
	struct tipc_link *temp_l_ptr;
	struct tipc_link *temp_l_ptr;


	read_lock_bh(&tipc_net_lock);
	read_lock_bh(&tipc_net_lock);
	b_ptr = tipc_bearer_find(name);
	pr_info("Blocking bearer <%s>\n", b_ptr->name);
	if (!b_ptr) {
		pr_warn("Attempt to block unknown bearer <%s>\n", name);
		read_unlock_bh(&tipc_net_lock);
		return -EINVAL;
	}

	pr_info("Blocking bearer <%s>\n", name);
	spin_lock_bh(&b_ptr->lock);
	spin_lock_bh(&b_ptr->lock);
	b_ptr->blocked = 1;
	b_ptr->blocked = 1;
	list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) {
	list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) {
@@ -465,7 +457,7 @@ static void bearer_disable(struct tipc_bearer *b_ptr)
	pr_info("Disabling bearer <%s>\n", b_ptr->name);
	pr_info("Disabling bearer <%s>\n", b_ptr->name);
	spin_lock_bh(&b_ptr->lock);
	spin_lock_bh(&b_ptr->lock);
	b_ptr->blocked = 1;
	b_ptr->blocked = 1;
	b_ptr->media->disable_bearer(b_ptr);
	b_ptr->media->disable_media(b_ptr);
	list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) {
	list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) {
		tipc_link_delete(l_ptr);
		tipc_link_delete(l_ptr);
	}
	}
+5 −5
Original line number Original line Diff line number Diff line
@@ -75,8 +75,8 @@ struct tipc_bearer;
/**
/**
 * struct tipc_media - TIPC media information available to internal users
 * struct tipc_media - TIPC media information available to internal users
 * @send_msg: routine which handles buffer transmission
 * @send_msg: routine which handles buffer transmission
 * @enable_bearer: routine which enables a bearer
 * @enable_media: routine which enables a media
 * @disable_bearer: routine which disables a bearer
 * @disable_media: routine which disables a media
 * @addr2str: routine which converts media address to string
 * @addr2str: routine which converts media address to string
 * @addr2msg: routine which converts media address to protocol message area
 * @addr2msg: routine which converts media address to protocol message area
 * @msg2addr: routine which converts media address from protocol message area
 * @msg2addr: routine which converts media address from protocol message area
@@ -91,8 +91,8 @@ struct tipc_media {
	int (*send_msg)(struct sk_buff *buf,
	int (*send_msg)(struct sk_buff *buf,
			struct tipc_bearer *b_ptr,
			struct tipc_bearer *b_ptr,
			struct tipc_media_addr *dest);
			struct tipc_media_addr *dest);
	int (*enable_bearer)(struct tipc_bearer *b_ptr);
	int (*enable_media)(struct tipc_bearer *b_ptr);
	void (*disable_bearer)(struct tipc_bearer *b_ptr);
	void (*disable_media)(struct tipc_bearer *b_ptr);
	int (*addr2str)(struct tipc_media_addr *a, char *str_buf, int str_size);
	int (*addr2str)(struct tipc_media_addr *a, char *str_buf, int str_size);
	int (*addr2msg)(struct tipc_media_addr *a, char *msg_area);
	int (*addr2msg)(struct tipc_media_addr *a, char *msg_area);
	int (*msg2addr)(const struct tipc_bearer *b_ptr,
	int (*msg2addr)(const struct tipc_bearer *b_ptr,
@@ -163,7 +163,7 @@ int tipc_register_media(struct tipc_media *m_ptr);


void tipc_recv_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr);
void tipc_recv_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr);


int  tipc_block_bearer(const char *name);
int  tipc_block_bearer(struct tipc_bearer *b_ptr);
void tipc_continue(struct tipc_bearer *tb_ptr);
void tipc_continue(struct tipc_bearer *tb_ptr);


int tipc_enable_bearer(const char *bearer_name, u32 disc_domain, u32 priority);
int tipc_enable_bearer(const char *bearer_name, u32 disc_domain, u32 priority);
+34 −34
Original line number Original line Diff line number Diff line
@@ -2,7 +2,7 @@
 * net/tipc/eth_media.c: Ethernet bearer support for TIPC
 * net/tipc/eth_media.c: Ethernet bearer support for TIPC
 *
 *
 * Copyright (c) 2001-2007, Ericsson AB
 * Copyright (c) 2001-2007, Ericsson AB
 * Copyright (c) 2005-2008, 2011, Wind River Systems
 * Copyright (c) 2005-2008, 2011-2013, Wind River Systems
 * All rights reserved.
 * All rights reserved.
 *
 *
 * Redistribution and use in source and binary forms, with or without
 * Redistribution and use in source and binary forms, with or without
@@ -37,19 +37,19 @@
#include "core.h"
#include "core.h"
#include "bearer.h"
#include "bearer.h"


#define MAX_ETH_BEARERS		MAX_BEARERS
#define MAX_ETH_MEDIA		MAX_BEARERS


#define ETH_ADDR_OFFSET	4	/* message header offset of MAC address */
#define ETH_ADDR_OFFSET	4	/* message header offset of MAC address */


/**
/**
 * struct eth_bearer - Ethernet bearer data structure
 * struct eth_media - Ethernet bearer data structure
 * @bearer: ptr to associated "generic" bearer structure
 * @bearer: ptr to associated "generic" bearer structure
 * @dev: ptr to associated Ethernet network device
 * @dev: ptr to associated Ethernet network device
 * @tipc_packet_type: used in binding TIPC to Ethernet driver
 * @tipc_packet_type: used in binding TIPC to Ethernet driver
 * @setup: work item used when enabling bearer
 * @setup: work item used when enabling bearer
 * @cleanup: work item used when disabling bearer
 * @cleanup: work item used when disabling bearer
 */
 */
struct eth_bearer {
struct eth_media {
	struct tipc_bearer *bearer;
	struct tipc_bearer *bearer;
	struct net_device *dev;
	struct net_device *dev;
	struct packet_type tipc_packet_type;
	struct packet_type tipc_packet_type;
@@ -58,7 +58,7 @@ struct eth_bearer {
};
};


static struct tipc_media eth_media_info;
static struct tipc_media eth_media_info;
static struct eth_bearer eth_bearers[MAX_ETH_BEARERS];
static struct eth_media eth_media_array[MAX_ETH_MEDIA];
static int eth_started;
static int eth_started;


static int recv_notification(struct notifier_block *nb, unsigned long evt,
static int recv_notification(struct notifier_block *nb, unsigned long evt,
@@ -100,7 +100,7 @@ static int send_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr,
	if (!clone)
	if (!clone)
		return 0;
		return 0;


	dev = ((struct eth_bearer *)(tb_ptr->usr_handle))->dev;
	dev = ((struct eth_media *)(tb_ptr->usr_handle))->dev;
	delta = dev->hard_header_len - skb_headroom(buf);
	delta = dev->hard_header_len - skb_headroom(buf);


	if ((delta > 0) &&
	if ((delta > 0) &&
@@ -128,43 +128,43 @@ static int send_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr,
static int recv_msg(struct sk_buff *buf, struct net_device *dev,
static int recv_msg(struct sk_buff *buf, struct net_device *dev,
		    struct packet_type *pt, struct net_device *orig_dev)
		    struct packet_type *pt, struct net_device *orig_dev)
{
{
	struct eth_bearer *eb_ptr = (struct eth_bearer *)pt->af_packet_priv;
	struct eth_media *eb_ptr = (struct eth_media *)pt->af_packet_priv;


	if (!net_eq(dev_net(dev), &init_net)) {
	if (!net_eq(dev_net(dev), &init_net)) {
		kfree_skb(buf);
		kfree_skb(buf);
		return 0;
		return NET_RX_DROP;
	}
	}


	if (likely(eb_ptr->bearer)) {
	if (likely(eb_ptr->bearer)) {
		if (likely(buf->pkt_type <= PACKET_BROADCAST)) {
		if (likely(buf->pkt_type <= PACKET_BROADCAST)) {
			buf->next = NULL;
			buf->next = NULL;
			tipc_recv_msg(buf, eb_ptr->bearer);
			tipc_recv_msg(buf, eb_ptr->bearer);
			return 0;
			return NET_RX_SUCCESS;
		}
		}
	}
	}
	kfree_skb(buf);
	kfree_skb(buf);
	return 0;
	return NET_RX_DROP;
}
}


/**
/**
 * setup_bearer - setup association between Ethernet bearer and interface
 * setup_media - setup association between Ethernet bearer and interface
 */
 */
static void setup_bearer(struct work_struct *work)
static void setup_media(struct work_struct *work)
{
{
	struct eth_bearer *eb_ptr =
	struct eth_media *eb_ptr =
		container_of(work, struct eth_bearer, setup);
		container_of(work, struct eth_media, setup);


	dev_add_pack(&eb_ptr->tipc_packet_type);
	dev_add_pack(&eb_ptr->tipc_packet_type);
}
}


/**
/**
 * enable_bearer - attach TIPC bearer to an Ethernet interface
 * enable_media - attach TIPC bearer to an Ethernet interface
 */
 */
static int enable_bearer(struct tipc_bearer *tb_ptr)
static int enable_media(struct tipc_bearer *tb_ptr)
{
{
	struct net_device *dev;
	struct net_device *dev;
	struct eth_bearer *eb_ptr = &eth_bearers[0];
	struct eth_media *eb_ptr = &eth_media_array[0];
	struct eth_bearer *stop = &eth_bearers[MAX_ETH_BEARERS];
	struct eth_media *stop = &eth_media_array[MAX_ETH_MEDIA];
	char *driver_name = strchr((const char *)tb_ptr->name, ':') + 1;
	char *driver_name = strchr((const char *)tb_ptr->name, ':') + 1;
	int pending_dev = 0;
	int pending_dev = 0;


@@ -188,7 +188,7 @@ static int enable_bearer(struct tipc_bearer *tb_ptr)
	eb_ptr->tipc_packet_type.func = recv_msg;
	eb_ptr->tipc_packet_type.func = recv_msg;
	eb_ptr->tipc_packet_type.af_packet_priv = eb_ptr;
	eb_ptr->tipc_packet_type.af_packet_priv = eb_ptr;
	INIT_LIST_HEAD(&(eb_ptr->tipc_packet_type.list));
	INIT_LIST_HEAD(&(eb_ptr->tipc_packet_type.list));
	INIT_WORK(&eb_ptr->setup, setup_bearer);
	INIT_WORK(&eb_ptr->setup, setup_media);
	schedule_work(&eb_ptr->setup);
	schedule_work(&eb_ptr->setup);


	/* Associate TIPC bearer with Ethernet bearer */
	/* Associate TIPC bearer with Ethernet bearer */
@@ -205,14 +205,14 @@ static int enable_bearer(struct tipc_bearer *tb_ptr)
}
}


/**
/**
 * cleanup_bearer - break association between Ethernet bearer and interface
 * cleanup_media - break association between Ethernet bearer and interface
 *
 *
 * This routine must be invoked from a work queue because it can sleep.
 * This routine must be invoked from a work queue because it can sleep.
 */
 */
static void cleanup_bearer(struct work_struct *work)
static void cleanup_media(struct work_struct *work)
{
{
	struct eth_bearer *eb_ptr =
	struct eth_media *eb_ptr =
		container_of(work, struct eth_bearer, cleanup);
		container_of(work, struct eth_media, cleanup);


	dev_remove_pack(&eb_ptr->tipc_packet_type);
	dev_remove_pack(&eb_ptr->tipc_packet_type);
	dev_put(eb_ptr->dev);
	dev_put(eb_ptr->dev);
@@ -220,18 +220,18 @@ static void cleanup_bearer(struct work_struct *work)
}
}


/**
/**
 * disable_bearer - detach TIPC bearer from an Ethernet interface
 * disable_media - detach TIPC bearer from an Ethernet interface
 *
 *
 * Mark Ethernet bearer as inactive so that incoming buffers are thrown away,
 * Mark Ethernet bearer as inactive so that incoming buffers are thrown away,
 * then get worker thread to complete bearer cleanup.  (Can't do cleanup
 * then get worker thread to complete bearer cleanup.  (Can't do cleanup
 * here because cleanup code needs to sleep and caller holds spinlocks.)
 * here because cleanup code needs to sleep and caller holds spinlocks.)
 */
 */
static void disable_bearer(struct tipc_bearer *tb_ptr)
static void disable_media(struct tipc_bearer *tb_ptr)
{
{
	struct eth_bearer *eb_ptr = (struct eth_bearer *)tb_ptr->usr_handle;
	struct eth_media *eb_ptr = (struct eth_media *)tb_ptr->usr_handle;


	eb_ptr->bearer = NULL;
	eb_ptr->bearer = NULL;
	INIT_WORK(&eb_ptr->cleanup, cleanup_bearer);
	INIT_WORK(&eb_ptr->cleanup, cleanup_media);
	schedule_work(&eb_ptr->cleanup);
	schedule_work(&eb_ptr->cleanup);
}
}


@@ -245,8 +245,8 @@ static int recv_notification(struct notifier_block *nb, unsigned long evt,
			     void *ptr)
			     void *ptr)
{
{
	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
	struct eth_bearer *eb_ptr = &eth_bearers[0];
	struct eth_media *eb_ptr = &eth_media_array[0];
	struct eth_bearer *stop = &eth_bearers[MAX_ETH_BEARERS];
	struct eth_media *stop = &eth_media_array[MAX_ETH_MEDIA];


	if (!net_eq(dev_net(dev), &init_net))
	if (!net_eq(dev_net(dev), &init_net))
		return NOTIFY_DONE;
		return NOTIFY_DONE;
@@ -265,17 +265,17 @@ static int recv_notification(struct notifier_block *nb, unsigned long evt,
		if (netif_carrier_ok(dev))
		if (netif_carrier_ok(dev))
			tipc_continue(eb_ptr->bearer);
			tipc_continue(eb_ptr->bearer);
		else
		else
			tipc_block_bearer(eb_ptr->bearer->name);
			tipc_block_bearer(eb_ptr->bearer);
		break;
		break;
	case NETDEV_UP:
	case NETDEV_UP:
		tipc_continue(eb_ptr->bearer);
		tipc_continue(eb_ptr->bearer);
		break;
		break;
	case NETDEV_DOWN:
	case NETDEV_DOWN:
		tipc_block_bearer(eb_ptr->bearer->name);
		tipc_block_bearer(eb_ptr->bearer);
		break;
		break;
	case NETDEV_CHANGEMTU:
	case NETDEV_CHANGEMTU:
	case NETDEV_CHANGEADDR:
	case NETDEV_CHANGEADDR:
		tipc_block_bearer(eb_ptr->bearer->name);
		tipc_block_bearer(eb_ptr->bearer);
		tipc_continue(eb_ptr->bearer);
		tipc_continue(eb_ptr->bearer);
		break;
		break;
	case NETDEV_UNREGISTER:
	case NETDEV_UNREGISTER:
@@ -327,8 +327,8 @@ static int eth_msg2addr(const struct tipc_bearer *tb_ptr,
 */
 */
static struct tipc_media eth_media_info = {
static struct tipc_media eth_media_info = {
	.send_msg	= send_msg,
	.send_msg	= send_msg,
	.enable_bearer	= enable_bearer,
	.enable_media	= enable_media,
	.disable_bearer	= disable_bearer,
	.disable_media	= disable_media,
	.addr2str	= eth_addr2str,
	.addr2str	= eth_addr2str,
	.addr2msg	= eth_addr2msg,
	.addr2msg	= eth_addr2msg,
	.msg2addr	= eth_msg2addr,
	.msg2addr	= eth_msg2addr,
+29 −29
Original line number Original line Diff line number Diff line
@@ -42,17 +42,17 @@
#include "core.h"
#include "core.h"
#include "bearer.h"
#include "bearer.h"


#define MAX_IB_BEARERS		MAX_BEARERS
#define MAX_IB_MEDIA		MAX_BEARERS


/**
/**
 * struct ib_bearer - Infiniband bearer data structure
 * struct ib_media - Infiniband media data structure
 * @bearer: ptr to associated "generic" bearer structure
 * @bearer: ptr to associated "generic" bearer structure
 * @dev: ptr to associated Infiniband network device
 * @dev: ptr to associated Infiniband network device
 * @tipc_packet_type: used in binding TIPC to Infiniband driver
 * @tipc_packet_type: used in binding TIPC to Infiniband driver
 * @cleanup: work item used when disabling bearer
 * @cleanup: work item used when disabling bearer
 */
 */


struct ib_bearer {
struct ib_media {
	struct tipc_bearer *bearer;
	struct tipc_bearer *bearer;
	struct net_device *dev;
	struct net_device *dev;
	struct packet_type tipc_packet_type;
	struct packet_type tipc_packet_type;
@@ -61,7 +61,7 @@ struct ib_bearer {
};
};


static struct tipc_media ib_media_info;
static struct tipc_media ib_media_info;
static struct ib_bearer ib_bearers[MAX_IB_BEARERS];
static struct ib_media ib_media_array[MAX_IB_MEDIA];
static int ib_started;
static int ib_started;


/**
/**
@@ -93,7 +93,7 @@ static int send_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr,
	if (!clone)
	if (!clone)
		return 0;
		return 0;


	dev = ((struct ib_bearer *)(tb_ptr->usr_handle))->dev;
	dev = ((struct ib_media *)(tb_ptr->usr_handle))->dev;
	delta = dev->hard_header_len - skb_headroom(buf);
	delta = dev->hard_header_len - skb_headroom(buf);


	if ((delta > 0) &&
	if ((delta > 0) &&
@@ -121,43 +121,43 @@ static int send_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr,
static int recv_msg(struct sk_buff *buf, struct net_device *dev,
static int recv_msg(struct sk_buff *buf, struct net_device *dev,
		    struct packet_type *pt, struct net_device *orig_dev)
		    struct packet_type *pt, struct net_device *orig_dev)
{
{
	struct ib_bearer *ib_ptr = (struct ib_bearer *)pt->af_packet_priv;
	struct ib_media *ib_ptr = (struct ib_media *)pt->af_packet_priv;


	if (!net_eq(dev_net(dev), &init_net)) {
	if (!net_eq(dev_net(dev), &init_net)) {
		kfree_skb(buf);
		kfree_skb(buf);
		return 0;
		return NET_RX_DROP;
	}
	}


	if (likely(ib_ptr->bearer)) {
	if (likely(ib_ptr->bearer)) {
		if (likely(buf->pkt_type <= PACKET_BROADCAST)) {
		if (likely(buf->pkt_type <= PACKET_BROADCAST)) {
			buf->next = NULL;
			buf->next = NULL;
			tipc_recv_msg(buf, ib_ptr->bearer);
			tipc_recv_msg(buf, ib_ptr->bearer);
			return 0;
			return NET_RX_SUCCESS;
		}
		}
	}
	}
	kfree_skb(buf);
	kfree_skb(buf);
	return 0;
	return NET_RX_DROP;
}
}


/**
/**
 * setup_bearer - setup association between InfiniBand bearer and interface
 * setup_bearer - setup association between InfiniBand bearer and interface
 */
 */
static void setup_bearer(struct work_struct *work)
static void setup_media(struct work_struct *work)
{
{
	struct ib_bearer *ib_ptr =
	struct ib_media *ib_ptr =
		container_of(work, struct ib_bearer, setup);
		container_of(work, struct ib_media, setup);


	dev_add_pack(&ib_ptr->tipc_packet_type);
	dev_add_pack(&ib_ptr->tipc_packet_type);
}
}


/**
/**
 * enable_bearer - attach TIPC bearer to an InfiniBand interface
 * enable_media - attach TIPC bearer to an InfiniBand interface
 */
 */
static int enable_bearer(struct tipc_bearer *tb_ptr)
static int enable_media(struct tipc_bearer *tb_ptr)
{
{
	struct net_device *dev;
	struct net_device *dev;
	struct ib_bearer *ib_ptr = &ib_bearers[0];
	struct ib_media *ib_ptr = &ib_media_array[0];
	struct ib_bearer *stop = &ib_bearers[MAX_IB_BEARERS];
	struct ib_media *stop = &ib_media_array[MAX_IB_MEDIA];
	char *driver_name = strchr((const char *)tb_ptr->name, ':') + 1;
	char *driver_name = strchr((const char *)tb_ptr->name, ':') + 1;
	int pending_dev = 0;
	int pending_dev = 0;


@@ -181,7 +181,7 @@ static int enable_bearer(struct tipc_bearer *tb_ptr)
	ib_ptr->tipc_packet_type.func = recv_msg;
	ib_ptr->tipc_packet_type.func = recv_msg;
	ib_ptr->tipc_packet_type.af_packet_priv = ib_ptr;
	ib_ptr->tipc_packet_type.af_packet_priv = ib_ptr;
	INIT_LIST_HEAD(&(ib_ptr->tipc_packet_type.list));
	INIT_LIST_HEAD(&(ib_ptr->tipc_packet_type.list));
	INIT_WORK(&ib_ptr->setup, setup_bearer);
	INIT_WORK(&ib_ptr->setup, setup_media);
	schedule_work(&ib_ptr->setup);
	schedule_work(&ib_ptr->setup);


	/* Associate TIPC bearer with InfiniBand bearer */
	/* Associate TIPC bearer with InfiniBand bearer */
@@ -204,8 +204,8 @@ static int enable_bearer(struct tipc_bearer *tb_ptr)
 */
 */
static void cleanup_bearer(struct work_struct *work)
static void cleanup_bearer(struct work_struct *work)
{
{
	struct ib_bearer *ib_ptr =
	struct ib_media *ib_ptr =
		container_of(work, struct ib_bearer, cleanup);
		container_of(work, struct ib_media, cleanup);


	dev_remove_pack(&ib_ptr->tipc_packet_type);
	dev_remove_pack(&ib_ptr->tipc_packet_type);
	dev_put(ib_ptr->dev);
	dev_put(ib_ptr->dev);
@@ -213,15 +213,15 @@ static void cleanup_bearer(struct work_struct *work)
}
}


/**
/**
 * disable_bearer - detach TIPC bearer from an InfiniBand interface
 * disable_media - detach TIPC bearer from an InfiniBand interface
 *
 *
 * Mark InfiniBand bearer as inactive so that incoming buffers are thrown away,
 * Mark InfiniBand bearer as inactive so that incoming buffers are thrown away,
 * then get worker thread to complete bearer cleanup.  (Can't do cleanup
 * then get worker thread to complete bearer cleanup.  (Can't do cleanup
 * here because cleanup code needs to sleep and caller holds spinlocks.)
 * here because cleanup code needs to sleep and caller holds spinlocks.)
 */
 */
static void disable_bearer(struct tipc_bearer *tb_ptr)
static void disable_media(struct tipc_bearer *tb_ptr)
{
{
	struct ib_bearer *ib_ptr = (struct ib_bearer *)tb_ptr->usr_handle;
	struct ib_media *ib_ptr = (struct ib_media *)tb_ptr->usr_handle;


	ib_ptr->bearer = NULL;
	ib_ptr->bearer = NULL;
	INIT_WORK(&ib_ptr->cleanup, cleanup_bearer);
	INIT_WORK(&ib_ptr->cleanup, cleanup_bearer);
@@ -238,8 +238,8 @@ static int recv_notification(struct notifier_block *nb, unsigned long evt,
			     void *ptr)
			     void *ptr)
{
{
	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
	struct ib_bearer *ib_ptr = &ib_bearers[0];
	struct ib_media *ib_ptr = &ib_media_array[0];
	struct ib_bearer *stop = &ib_bearers[MAX_IB_BEARERS];
	struct ib_media *stop = &ib_media_array[MAX_IB_MEDIA];


	if (!net_eq(dev_net(dev), &init_net))
	if (!net_eq(dev_net(dev), &init_net))
		return NOTIFY_DONE;
		return NOTIFY_DONE;
@@ -258,17 +258,17 @@ static int recv_notification(struct notifier_block *nb, unsigned long evt,
		if (netif_carrier_ok(dev))
		if (netif_carrier_ok(dev))
			tipc_continue(ib_ptr->bearer);
			tipc_continue(ib_ptr->bearer);
		else
		else
			tipc_block_bearer(ib_ptr->bearer->name);
			tipc_block_bearer(ib_ptr->bearer);
		break;
		break;
	case NETDEV_UP:
	case NETDEV_UP:
		tipc_continue(ib_ptr->bearer);
		tipc_continue(ib_ptr->bearer);
		break;
		break;
	case NETDEV_DOWN:
	case NETDEV_DOWN:
		tipc_block_bearer(ib_ptr->bearer->name);
		tipc_block_bearer(ib_ptr->bearer);
		break;
		break;
	case NETDEV_CHANGEMTU:
	case NETDEV_CHANGEMTU:
	case NETDEV_CHANGEADDR:
	case NETDEV_CHANGEADDR:
		tipc_block_bearer(ib_ptr->bearer->name);
		tipc_block_bearer(ib_ptr->bearer);
		tipc_continue(ib_ptr->bearer);
		tipc_continue(ib_ptr->bearer);
		break;
		break;
	case NETDEV_UNREGISTER:
	case NETDEV_UNREGISTER:
@@ -323,8 +323,8 @@ static int ib_msg2addr(const struct tipc_bearer *tb_ptr,
 */
 */
static struct tipc_media ib_media_info = {
static struct tipc_media ib_media_info = {
	.send_msg	= send_msg,
	.send_msg	= send_msg,
	.enable_bearer	= enable_bearer,
	.enable_media	= enable_media,
	.disable_bearer	= disable_bearer,
	.disable_media	= disable_media,
	.addr2str	= ib_addr2str,
	.addr2str	= ib_addr2str,
	.addr2msg	= ib_addr2msg,
	.addr2msg	= ib_addr2msg,
	.msg2addr	= ib_msg2addr,
	.msg2addr	= ib_msg2addr,
+44 −123
Original line number Original line Diff line number Diff line
@@ -75,20 +75,6 @@ static const char *link_unk_evt = "Unknown link event ";
 */
 */
#define START_CHANGEOVER 100000u
#define START_CHANGEOVER 100000u


/**
 * struct tipc_link_name - deconstructed link name
 * @addr_local: network address of node at this end
 * @if_local: name of interface at this end
 * @addr_peer: network address of node at far end
 * @if_peer: name of interface at far end
 */
struct tipc_link_name {
	u32 addr_local;
	char if_local[TIPC_MAX_IF_NAME];
	u32 addr_peer;
	char if_peer[TIPC_MAX_IF_NAME];
};

static void link_handle_out_of_seq_msg(struct tipc_link *l_ptr,
static void link_handle_out_of_seq_msg(struct tipc_link *l_ptr,
				       struct sk_buff *buf);
				       struct sk_buff *buf);
static void link_recv_proto_msg(struct tipc_link *l_ptr, struct sk_buff *buf);
static void link_recv_proto_msg(struct tipc_link *l_ptr, struct sk_buff *buf);
@@ -97,8 +83,7 @@ static int link_recv_changeover_msg(struct tipc_link **l_ptr,
static void link_set_supervision_props(struct tipc_link *l_ptr, u32 tolerance);
static void link_set_supervision_props(struct tipc_link *l_ptr, u32 tolerance);
static int  link_send_sections_long(struct tipc_port *sender,
static int  link_send_sections_long(struct tipc_port *sender,
				    struct iovec const *msg_sect,
				    struct iovec const *msg_sect,
				    u32 num_sect, unsigned int total_len,
				    unsigned int len, u32 destnode);
				    u32 destnode);
static void link_state_event(struct tipc_link *l_ptr, u32 event);
static void link_state_event(struct tipc_link *l_ptr, u32 event);
static void link_reset_statistics(struct tipc_link *l_ptr);
static void link_reset_statistics(struct tipc_link *l_ptr);
static void link_print(struct tipc_link *l_ptr, const char *str);
static void link_print(struct tipc_link *l_ptr, const char *str);
@@ -160,72 +145,6 @@ int tipc_link_is_active(struct tipc_link *l_ptr)
		(l_ptr->owner->active_links[1] == l_ptr);
		(l_ptr->owner->active_links[1] == l_ptr);
}
}


/**
 * link_name_validate - validate & (optionally) deconstruct tipc_link name
 * @name: ptr to link name string
 * @name_parts: ptr to area for link name components (or NULL if not needed)
 *
 * Returns 1 if link name is valid, otherwise 0.
 */
static int link_name_validate(const char *name,
				struct tipc_link_name *name_parts)
{
	char name_copy[TIPC_MAX_LINK_NAME];
	char *addr_local;
	char *if_local;
	char *addr_peer;
	char *if_peer;
	char dummy;
	u32 z_local, c_local, n_local;
	u32 z_peer, c_peer, n_peer;
	u32 if_local_len;
	u32 if_peer_len;

	/* copy link name & ensure length is OK */
	name_copy[TIPC_MAX_LINK_NAME - 1] = 0;
	/* need above in case non-Posix strncpy() doesn't pad with nulls */
	strncpy(name_copy, name, TIPC_MAX_LINK_NAME);
	if (name_copy[TIPC_MAX_LINK_NAME - 1] != 0)
		return 0;

	/* ensure all component parts of link name are present */
	addr_local = name_copy;
	if_local = strchr(addr_local, ':');
	if (if_local == NULL)
		return 0;
	*(if_local++) = 0;
	addr_peer = strchr(if_local, '-');
	if (addr_peer == NULL)
		return 0;
	*(addr_peer++) = 0;
	if_local_len = addr_peer - if_local;
	if_peer = strchr(addr_peer, ':');
	if (if_peer == NULL)
		return 0;
	*(if_peer++) = 0;
	if_peer_len = strlen(if_peer) + 1;

	/* validate component parts of link name */
	if ((sscanf(addr_local, "%u.%u.%u%c",
		    &z_local, &c_local, &n_local, &dummy) != 3) ||
	    (sscanf(addr_peer, "%u.%u.%u%c",
		    &z_peer, &c_peer, &n_peer, &dummy) != 3) ||
	    (z_local > 255) || (c_local > 4095) || (n_local > 4095) ||
	    (z_peer  > 255) || (c_peer  > 4095) || (n_peer  > 4095) ||
	    (if_local_len <= 1) || (if_local_len > TIPC_MAX_IF_NAME) ||
	    (if_peer_len  <= 1) || (if_peer_len  > TIPC_MAX_IF_NAME))
		return 0;

	/* return link name components, if necessary */
	if (name_parts) {
		name_parts->addr_local = tipc_addr(z_local, c_local, n_local);
		strcpy(name_parts->if_local, if_local);
		name_parts->addr_peer = tipc_addr(z_peer, c_peer, n_peer);
		strcpy(name_parts->if_peer, if_peer);
	}
	return 1;
}

/**
/**
 * link_timeout - handle expiration of link timer
 * link_timeout - handle expiration of link timer
 * @l_ptr: pointer to link
 * @l_ptr: pointer to link
@@ -1065,8 +984,7 @@ static int link_send_buf_fast(struct tipc_link *l_ptr, struct sk_buff *buf,
 */
 */
int tipc_link_send_sections_fast(struct tipc_port *sender,
int tipc_link_send_sections_fast(struct tipc_port *sender,
				 struct iovec const *msg_sect,
				 struct iovec const *msg_sect,
				 const u32 num_sect, unsigned int total_len,
				 unsigned int len, u32 destaddr)
				 u32 destaddr)
{
{
	struct tipc_msg *hdr = &sender->phdr;
	struct tipc_msg *hdr = &sender->phdr;
	struct tipc_link *l_ptr;
	struct tipc_link *l_ptr;
@@ -1080,8 +998,7 @@ again:
	 * Try building message using port's max_pkt hint.
	 * Try building message using port's max_pkt hint.
	 * (Must not hold any locks while building message.)
	 * (Must not hold any locks while building message.)
	 */
	 */
	res = tipc_msg_build(hdr, msg_sect, num_sect, total_len,
	res = tipc_msg_build(hdr, msg_sect, len, sender->max_pkt, &buf);
			     sender->max_pkt, &buf);
	/* Exit if build request was invalid */
	/* Exit if build request was invalid */
	if (unlikely(res < 0))
	if (unlikely(res < 0))
		return res;
		return res;
@@ -1121,8 +1038,7 @@ exit:
			if ((msg_hdr_sz(hdr) + res) <= sender->max_pkt)
			if ((msg_hdr_sz(hdr) + res) <= sender->max_pkt)
				goto again;
				goto again;


			return link_send_sections_long(sender, msg_sect,
			return link_send_sections_long(sender, msg_sect, len,
						       num_sect, total_len,
						       destaddr);
						       destaddr);
		}
		}
		tipc_node_unlock(node);
		tipc_node_unlock(node);
@@ -1133,8 +1049,8 @@ exit:
	if (buf)
	if (buf)
		return tipc_reject_msg(buf, TIPC_ERR_NO_NODE);
		return tipc_reject_msg(buf, TIPC_ERR_NO_NODE);
	if (res >= 0)
	if (res >= 0)
		return tipc_port_reject_sections(sender, hdr, msg_sect, num_sect,
		return tipc_port_reject_sections(sender, hdr, msg_sect,
						 total_len, TIPC_ERR_NO_NODE);
						 len, TIPC_ERR_NO_NODE);
	return res;
	return res;
}
}


@@ -1154,18 +1070,17 @@ exit:
 */
 */
static int link_send_sections_long(struct tipc_port *sender,
static int link_send_sections_long(struct tipc_port *sender,
				   struct iovec const *msg_sect,
				   struct iovec const *msg_sect,
				   u32 num_sect, unsigned int total_len,
				   unsigned int len, u32 destaddr)
				   u32 destaddr)
{
{
	struct tipc_link *l_ptr;
	struct tipc_link *l_ptr;
	struct tipc_node *node;
	struct tipc_node *node;
	struct tipc_msg *hdr = &sender->phdr;
	struct tipc_msg *hdr = &sender->phdr;
	u32 dsz = total_len;
	u32 dsz = len;
	u32 max_pkt, fragm_sz, rest;
	u32 max_pkt, fragm_sz, rest;
	struct tipc_msg fragm_hdr;
	struct tipc_msg fragm_hdr;
	struct sk_buff *buf, *buf_chain, *prev;
	struct sk_buff *buf, *buf_chain, *prev;
	u32 fragm_crs, fragm_rest, hsz, sect_rest;
	u32 fragm_crs, fragm_rest, hsz, sect_rest;
	const unchar *sect_crs;
	const unchar __user *sect_crs;
	int curr_sect;
	int curr_sect;
	u32 fragm_no;
	u32 fragm_no;
	int res = 0;
	int res = 0;
@@ -1207,7 +1122,7 @@ again:


		if (!sect_rest) {
		if (!sect_rest) {
			sect_rest = msg_sect[++curr_sect].iov_len;
			sect_rest = msg_sect[++curr_sect].iov_len;
			sect_crs = (const unchar *)msg_sect[curr_sect].iov_base;
			sect_crs = msg_sect[curr_sect].iov_base;
		}
		}


		if (sect_rest < fragm_rest)
		if (sect_rest < fragm_rest)
@@ -1283,8 +1198,8 @@ reject:
			buf = buf_chain->next;
			buf = buf_chain->next;
			kfree_skb(buf_chain);
			kfree_skb(buf_chain);
		}
		}
		return tipc_port_reject_sections(sender, hdr, msg_sect, num_sect,
		return tipc_port_reject_sections(sender, hdr, msg_sect,
						 total_len, TIPC_ERR_NO_NODE);
						 len, TIPC_ERR_NO_NODE);
	}
	}


	/* Append chain of fragments to send queue & send them */
	/* Append chain of fragments to send queue & send them */
@@ -2585,25 +2500,21 @@ void tipc_link_set_queue_limits(struct tipc_link *l_ptr, u32 window)
static struct tipc_link *link_find_link(const char *name,
static struct tipc_link *link_find_link(const char *name,
					struct tipc_node **node)
					struct tipc_node **node)
{
{
	struct tipc_link_name link_name_parts;
	struct tipc_bearer *b_ptr;
	struct tipc_link *l_ptr;
	struct tipc_link *l_ptr;
	struct tipc_node *n_ptr;
	int i;


	if (!link_name_validate(name, &link_name_parts))
	list_for_each_entry(n_ptr, &tipc_node_list, list) {
		return NULL;
		for (i = 0; i < MAX_BEARERS; i++) {

			l_ptr = n_ptr->links[i];
	b_ptr = tipc_bearer_find_interface(link_name_parts.if_local);
			if (l_ptr && !strcmp(l_ptr->name, name))
	if (!b_ptr)
				goto found;
		return NULL;
		}

	}
	*node = tipc_node_find(link_name_parts.addr_peer);
	l_ptr = NULL;
	if (!*node)
	n_ptr = NULL;
		return NULL;
found:

	*node = n_ptr;
	l_ptr = (*node)->links[b_ptr->identity];
	if (!l_ptr || strcmp(l_ptr->name, name))
		return NULL;

	return l_ptr;
	return l_ptr;
}
}


@@ -2646,6 +2557,7 @@ static int link_cmd_set_value(const char *name, u32 new_value, u16 cmd)
	struct tipc_link *l_ptr;
	struct tipc_link *l_ptr;
	struct tipc_bearer *b_ptr;
	struct tipc_bearer *b_ptr;
	struct tipc_media *m_ptr;
	struct tipc_media *m_ptr;
	int res = 0;


	l_ptr = link_find_link(name, &node);
	l_ptr = link_find_link(name, &node);
	if (l_ptr) {
	if (l_ptr) {
@@ -2668,9 +2580,12 @@ static int link_cmd_set_value(const char *name, u32 new_value, u16 cmd)
		case TIPC_CMD_SET_LINK_WINDOW:
		case TIPC_CMD_SET_LINK_WINDOW:
			tipc_link_set_queue_limits(l_ptr, new_value);
			tipc_link_set_queue_limits(l_ptr, new_value);
			break;
			break;
		default:
			res = -EINVAL;
			break;
		}
		}
		tipc_node_unlock(node);
		tipc_node_unlock(node);
		return 0;
		return res;
	}
	}


	b_ptr = tipc_bearer_find(name);
	b_ptr = tipc_bearer_find(name);
@@ -2678,15 +2593,18 @@ static int link_cmd_set_value(const char *name, u32 new_value, u16 cmd)
		switch (cmd) {
		switch (cmd) {
		case TIPC_CMD_SET_LINK_TOL:
		case TIPC_CMD_SET_LINK_TOL:
			b_ptr->tolerance = new_value;
			b_ptr->tolerance = new_value;
			return 0;
			break;
		case TIPC_CMD_SET_LINK_PRI:
		case TIPC_CMD_SET_LINK_PRI:
			b_ptr->priority = new_value;
			b_ptr->priority = new_value;
			return 0;
			break;
		case TIPC_CMD_SET_LINK_WINDOW:
		case TIPC_CMD_SET_LINK_WINDOW:
			b_ptr->window = new_value;
			b_ptr->window = new_value;
			return 0;
			break;
		default:
			res = -EINVAL;
			break;
		}
		}
		return -EINVAL;
		return res;
	}
	}


	m_ptr = tipc_media_find(name);
	m_ptr = tipc_media_find(name);
@@ -2695,15 +2613,18 @@ static int link_cmd_set_value(const char *name, u32 new_value, u16 cmd)
	switch (cmd) {
	switch (cmd) {
	case TIPC_CMD_SET_LINK_TOL:
	case TIPC_CMD_SET_LINK_TOL:
		m_ptr->tolerance = new_value;
		m_ptr->tolerance = new_value;
		return 0;
		break;
	case TIPC_CMD_SET_LINK_PRI:
	case TIPC_CMD_SET_LINK_PRI:
		m_ptr->priority = new_value;
		m_ptr->priority = new_value;
		return 0;
		break;
	case TIPC_CMD_SET_LINK_WINDOW:
	case TIPC_CMD_SET_LINK_WINDOW:
		m_ptr->window = new_value;
		m_ptr->window = new_value;
		return 0;
		break;
	default:
		res = -EINVAL;
		break;
	}
	}
	return -EINVAL;
	return res;
}
}


struct sk_buff *tipc_link_cmd_config(const void *req_tlv_area, int req_tlv_space,
struct sk_buff *tipc_link_cmd_config(const void *req_tlv_area, int req_tlv_space,
Loading