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: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2013-10-18 13:22:19 -04:00
Родитель 7cc7c5e54b bbfbe47cc9
Коммит ace0d5d8bf
11 изменённых файлов: 167 добавлений и 282 удалений

Просмотреть файл

@ -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);
} }

Просмотреть файл

@ -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);

Просмотреть файл

@ -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,

Просмотреть файл

@ -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,

Просмотреть файл

@ -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,

Просмотреть файл

@ -227,9 +227,7 @@ int tipc_link_send_buf(struct tipc_link *l_ptr, struct sk_buff *buf);
u32 tipc_link_get_max_pkt(u32 dest, u32 selector); u32 tipc_link_get_max_pkt(u32 dest, u32 selector);
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 len, u32 destnode);
unsigned int total_len,
u32 destnode);
void tipc_link_recv_bundle(struct sk_buff *buf); void tipc_link_recv_bundle(struct sk_buff *buf);
int tipc_link_recv_fragment(struct sk_buff **pending, int tipc_link_recv_fragment(struct sk_buff **pending,
struct sk_buff **fb, struct sk_buff **fb,

Просмотреть файл

@ -73,13 +73,13 @@ void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, u32 hsize,
* Returns message data size or errno * Returns message data size or errno
*/ */
int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect, int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect,
u32 num_sect, unsigned int total_len, int max_size, unsigned int len, int max_size, struct sk_buff **buf)
struct sk_buff **buf)
{ {
int dsz, sz, hsz, pos, res, cnt; int dsz, sz, hsz;
unsigned char *to;
dsz = total_len; dsz = len;
pos = hsz = msg_hdr_sz(hdr); hsz = msg_hdr_sz(hdr);
sz = hsz + dsz; sz = hsz + dsz;
msg_set_size(hdr, sz); msg_set_size(hdr, sz);
if (unlikely(sz > max_size)) { if (unlikely(sz > max_size)) {
@ -91,16 +91,11 @@ int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect,
if (!(*buf)) if (!(*buf))
return -ENOMEM; return -ENOMEM;
skb_copy_to_linear_data(*buf, hdr, hsz); skb_copy_to_linear_data(*buf, hdr, hsz);
for (res = 1, cnt = 0; res && (cnt < num_sect); cnt++) { to = (*buf)->data + hsz;
skb_copy_to_linear_data_offset(*buf, pos, if (len && memcpy_fromiovecend(to, msg_sect, 0, dsz)) {
msg_sect[cnt].iov_base, kfree_skb(*buf);
msg_sect[cnt].iov_len); *buf = NULL;
pos += msg_sect[cnt].iov_len; return -EFAULT;
} }
if (likely(res)) return dsz;
return dsz;
kfree_skb(*buf);
*buf = NULL;
return -EFAULT;
} }

Просмотреть файл

@ -722,6 +722,5 @@ u32 tipc_msg_tot_importance(struct tipc_msg *m);
void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, u32 hsize, void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, u32 hsize,
u32 destnode); u32 destnode);
int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect, int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect,
u32 num_sect, unsigned int total_len, int max_size, unsigned int len, int max_size, struct sk_buff **buf);
struct sk_buff **buf);
#endif #endif

Просмотреть файл

@ -90,8 +90,7 @@ int tipc_port_peer_msg(struct tipc_port *p_ptr, struct tipc_msg *msg)
* tipc_multicast - send a multicast message to local and remote destinations * tipc_multicast - send a multicast message to local and remote destinations
*/ */
int tipc_multicast(u32 ref, struct tipc_name_seq const *seq, int tipc_multicast(u32 ref, struct tipc_name_seq const *seq,
u32 num_sect, struct iovec const *msg_sect, struct iovec const *msg_sect, unsigned int len)
unsigned int total_len)
{ {
struct tipc_msg *hdr; struct tipc_msg *hdr;
struct sk_buff *buf; struct sk_buff *buf;
@ -114,8 +113,7 @@ int tipc_multicast(u32 ref, struct tipc_name_seq const *seq,
msg_set_namelower(hdr, seq->lower); msg_set_namelower(hdr, seq->lower);
msg_set_nameupper(hdr, seq->upper); msg_set_nameupper(hdr, seq->upper);
msg_set_hdr_sz(hdr, MCAST_H_SIZE); msg_set_hdr_sz(hdr, MCAST_H_SIZE);
res = tipc_msg_build(hdr, msg_sect, num_sect, total_len, MAX_MSG_SIZE, res = tipc_msg_build(hdr, msg_sect, len, MAX_MSG_SIZE, &buf);
&buf);
if (unlikely(!buf)) if (unlikely(!buf))
return res; return res;
@ -436,14 +434,13 @@ exit:
} }
int tipc_port_reject_sections(struct tipc_port *p_ptr, struct tipc_msg *hdr, int tipc_port_reject_sections(struct tipc_port *p_ptr, struct tipc_msg *hdr,
struct iovec const *msg_sect, u32 num_sect, struct iovec const *msg_sect, unsigned int len,
unsigned int total_len, int err) int err)
{ {
struct sk_buff *buf; struct sk_buff *buf;
int res; int res;
res = tipc_msg_build(hdr, msg_sect, num_sect, total_len, MAX_MSG_SIZE, res = tipc_msg_build(hdr, msg_sect, len, MAX_MSG_SIZE, &buf);
&buf);
if (!buf) if (!buf)
return res; return res;
@ -918,15 +915,14 @@ int tipc_port_recv_msg(struct sk_buff *buf)
* tipc_port_recv_sections(): Concatenate and deliver sectioned * tipc_port_recv_sections(): Concatenate and deliver sectioned
* message for this node. * message for this node.
*/ */
static int tipc_port_recv_sections(struct tipc_port *sender, unsigned int num_sect, static int tipc_port_recv_sections(struct tipc_port *sender,
struct iovec const *msg_sect, struct iovec const *msg_sect,
unsigned int total_len) unsigned int len)
{ {
struct sk_buff *buf; struct sk_buff *buf;
int res; int res;
res = tipc_msg_build(&sender->phdr, msg_sect, num_sect, total_len, res = tipc_msg_build(&sender->phdr, msg_sect, len, MAX_MSG_SIZE, &buf);
MAX_MSG_SIZE, &buf);
if (likely(buf)) if (likely(buf))
tipc_port_recv_msg(buf); tipc_port_recv_msg(buf);
return res; return res;
@ -935,8 +931,7 @@ static int tipc_port_recv_sections(struct tipc_port *sender, unsigned int num_se
/** /**
* tipc_send - send message sections on connection * tipc_send - send message sections on connection
*/ */
int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect, int tipc_send(u32 ref, struct iovec const *msg_sect, unsigned int len)
unsigned int total_len)
{ {
struct tipc_port *p_ptr; struct tipc_port *p_ptr;
u32 destnode; u32 destnode;
@ -950,11 +945,10 @@ int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect,
if (!tipc_port_congested(p_ptr)) { if (!tipc_port_congested(p_ptr)) {
destnode = port_peernode(p_ptr); destnode = port_peernode(p_ptr);
if (likely(!in_own_node(destnode))) if (likely(!in_own_node(destnode)))
res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect, res = tipc_link_send_sections_fast(p_ptr, msg_sect,
total_len, destnode); len, destnode);
else else
res = tipc_port_recv_sections(p_ptr, num_sect, msg_sect, res = tipc_port_recv_sections(p_ptr, msg_sect, len);
total_len);
if (likely(res != -ELINKCONG)) { if (likely(res != -ELINKCONG)) {
p_ptr->congested = 0; p_ptr->congested = 0;
@ -965,7 +959,7 @@ int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect,
} }
if (port_unreliable(p_ptr)) { if (port_unreliable(p_ptr)) {
p_ptr->congested = 0; p_ptr->congested = 0;
return total_len; return len;
} }
return -ELINKCONG; return -ELINKCONG;
} }
@ -974,8 +968,7 @@ int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect,
* tipc_send2name - send message sections to port name * tipc_send2name - send message sections to port name
*/ */
int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain, int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain,
unsigned int num_sect, struct iovec const *msg_sect, struct iovec const *msg_sect, unsigned int len)
unsigned int total_len)
{ {
struct tipc_port *p_ptr; struct tipc_port *p_ptr;
struct tipc_msg *msg; struct tipc_msg *msg;
@ -999,36 +992,32 @@ int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain,
if (likely(destport || destnode)) { if (likely(destport || destnode)) {
if (likely(in_own_node(destnode))) if (likely(in_own_node(destnode)))
res = tipc_port_recv_sections(p_ptr, num_sect, res = tipc_port_recv_sections(p_ptr, msg_sect, len);
msg_sect, total_len);
else if (tipc_own_addr) else if (tipc_own_addr)
res = tipc_link_send_sections_fast(p_ptr, msg_sect, res = tipc_link_send_sections_fast(p_ptr, msg_sect,
num_sect, total_len, len, destnode);
destnode);
else else
res = tipc_port_reject_sections(p_ptr, msg, msg_sect, res = tipc_port_reject_sections(p_ptr, msg, msg_sect,
num_sect, total_len, len, TIPC_ERR_NO_NODE);
TIPC_ERR_NO_NODE);
if (likely(res != -ELINKCONG)) { if (likely(res != -ELINKCONG)) {
if (res > 0) if (res > 0)
p_ptr->sent++; p_ptr->sent++;
return res; return res;
} }
if (port_unreliable(p_ptr)) { if (port_unreliable(p_ptr)) {
return total_len; return len;
} }
return -ELINKCONG; return -ELINKCONG;
} }
return tipc_port_reject_sections(p_ptr, msg, msg_sect, num_sect, return tipc_port_reject_sections(p_ptr, msg, msg_sect, len,
total_len, TIPC_ERR_NO_NAME); TIPC_ERR_NO_NAME);
} }
/** /**
* tipc_send2port - send message sections to port identity * tipc_send2port - send message sections to port identity
*/ */
int tipc_send2port(u32 ref, struct tipc_portid const *dest, int tipc_send2port(u32 ref, struct tipc_portid const *dest,
unsigned int num_sect, struct iovec const *msg_sect, struct iovec const *msg_sect, unsigned int len)
unsigned int total_len)
{ {
struct tipc_port *p_ptr; struct tipc_port *p_ptr;
struct tipc_msg *msg; struct tipc_msg *msg;
@ -1046,21 +1035,20 @@ int tipc_send2port(u32 ref, struct tipc_portid const *dest,
msg_set_hdr_sz(msg, BASIC_H_SIZE); msg_set_hdr_sz(msg, BASIC_H_SIZE);
if (in_own_node(dest->node)) if (in_own_node(dest->node))
res = tipc_port_recv_sections(p_ptr, num_sect, msg_sect, res = tipc_port_recv_sections(p_ptr, msg_sect, len);
total_len);
else if (tipc_own_addr) else if (tipc_own_addr)
res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect, res = tipc_link_send_sections_fast(p_ptr, msg_sect, len,
total_len, dest->node); dest->node);
else else
res = tipc_port_reject_sections(p_ptr, msg, msg_sect, num_sect, res = tipc_port_reject_sections(p_ptr, msg, msg_sect, len,
total_len, TIPC_ERR_NO_NODE); TIPC_ERR_NO_NODE);
if (likely(res != -ELINKCONG)) { if (likely(res != -ELINKCONG)) {
if (res > 0) if (res > 0)
p_ptr->sent++; p_ptr->sent++;
return res; return res;
} }
if (port_unreliable(p_ptr)) { if (port_unreliable(p_ptr)) {
return total_len; return len;
} }
return -ELINKCONG; return -ELINKCONG;
} }

Просмотреть файл

@ -151,24 +151,20 @@ int tipc_port_peer_msg(struct tipc_port *p_ptr, struct tipc_msg *msg);
* TIPC messaging routines * TIPC messaging routines
*/ */
int tipc_port_recv_msg(struct sk_buff *buf); int tipc_port_recv_msg(struct sk_buff *buf);
int tipc_send(u32 portref, unsigned int num_sect, struct iovec const *msg_sect, int tipc_send(u32 portref, struct iovec const *msg_sect, unsigned int len);
unsigned int total_len);
int tipc_send2name(u32 portref, struct tipc_name const *name, u32 domain, int tipc_send2name(u32 portref, struct tipc_name const *name, u32 domain,
unsigned int num_sect, struct iovec const *msg_sect, struct iovec const *msg_sect, unsigned int len);
unsigned int total_len);
int tipc_send2port(u32 portref, struct tipc_portid const *dest, int tipc_send2port(u32 portref, struct tipc_portid const *dest,
unsigned int num_sect, struct iovec const *msg_sect, struct iovec const *msg_sect, unsigned int len);
unsigned int total_len);
int tipc_multicast(u32 portref, struct tipc_name_seq const *seq, int tipc_multicast(u32 portref, struct tipc_name_seq const *seq,
unsigned int section_count, struct iovec const *msg, struct iovec const *msg, unsigned int len);
unsigned int total_len);
int tipc_port_reject_sections(struct tipc_port *p_ptr, struct tipc_msg *hdr, int tipc_port_reject_sections(struct tipc_port *p_ptr, struct tipc_msg *hdr,
struct iovec const *msg_sect, u32 num_sect, struct iovec const *msg_sect, unsigned int len,
unsigned int total_len, int err); int err);
struct sk_buff *tipc_port_get_ports(void); struct sk_buff *tipc_port_get_ports(void);
void tipc_port_recv_proto_msg(struct sk_buff *buf); void tipc_port_recv_proto_msg(struct sk_buff *buf);
void tipc_port_recv_mcast(struct sk_buff *buf, struct tipc_port_list *dp); void tipc_port_recv_mcast(struct sk_buff *buf, struct tipc_port_list *dp);

Просмотреть файл

@ -338,7 +338,7 @@ static int release(struct socket *sock)
buf = __skb_dequeue(&sk->sk_receive_queue); buf = __skb_dequeue(&sk->sk_receive_queue);
if (buf == NULL) if (buf == NULL)
break; break;
if (TIPC_SKB_CB(buf)->handle != 0) if (TIPC_SKB_CB(buf)->handle != NULL)
kfree_skb(buf); kfree_skb(buf);
else { else {
if ((sock->state == SS_CONNECTING) || if ((sock->state == SS_CONNECTING) ||
@ -622,13 +622,11 @@ static int send_msg(struct kiocb *iocb, struct socket *sock,
res = tipc_send2name(tport->ref, res = tipc_send2name(tport->ref,
&dest->addr.name.name, &dest->addr.name.name,
dest->addr.name.domain, dest->addr.name.domain,
m->msg_iovlen,
m->msg_iov, m->msg_iov,
total_len); total_len);
} else if (dest->addrtype == TIPC_ADDR_ID) { } else if (dest->addrtype == TIPC_ADDR_ID) {
res = tipc_send2port(tport->ref, res = tipc_send2port(tport->ref,
&dest->addr.id, &dest->addr.id,
m->msg_iovlen,
m->msg_iov, m->msg_iov,
total_len); total_len);
} else if (dest->addrtype == TIPC_ADDR_MCAST) { } else if (dest->addrtype == TIPC_ADDR_MCAST) {
@ -641,7 +639,6 @@ static int send_msg(struct kiocb *iocb, struct socket *sock,
break; break;
res = tipc_multicast(tport->ref, res = tipc_multicast(tport->ref,
&dest->addr.nameseq, &dest->addr.nameseq,
m->msg_iovlen,
m->msg_iov, m->msg_iov,
total_len); total_len);
} }
@ -707,8 +704,7 @@ static int send_packet(struct kiocb *iocb, struct socket *sock,
break; break;
} }
res = tipc_send(tport->ref, m->msg_iovlen, m->msg_iov, res = tipc_send(tport->ref, m->msg_iov, total_len);
total_len);
if (likely(res != -ELINKCONG)) if (likely(res != -ELINKCONG))
break; break;
if (timeout_val <= 0L) { if (timeout_val <= 0L) {
@ -1368,7 +1364,7 @@ static u32 filter_rcv(struct sock *sk, struct sk_buff *buf)
return TIPC_ERR_OVERLOAD; return TIPC_ERR_OVERLOAD;
/* Enqueue message */ /* Enqueue message */
TIPC_SKB_CB(buf)->handle = 0; TIPC_SKB_CB(buf)->handle = NULL;
__skb_queue_tail(&sk->sk_receive_queue, buf); __skb_queue_tail(&sk->sk_receive_queue, buf);
skb_set_owner_r(buf, sk); skb_set_owner_r(buf, sk);
@ -1691,7 +1687,7 @@ restart:
/* Disconnect and send a 'FIN+' or 'FIN-' message to peer */ /* Disconnect and send a 'FIN+' or 'FIN-' message to peer */
buf = __skb_dequeue(&sk->sk_receive_queue); buf = __skb_dequeue(&sk->sk_receive_queue);
if (buf) { if (buf) {
if (TIPC_SKB_CB(buf)->handle != 0) { if (TIPC_SKB_CB(buf)->handle != NULL) {
kfree_skb(buf); kfree_skb(buf);
goto restart; goto restart;
} }