Commit 38504c28 authored by Jon Paul Maloy's avatar Jon Paul Maloy Committed by David S. Miller

tipc: improve and extend media address conversion functions

TIPC currently handles two media specific addresses: Ethernet MAC
addresses and InfiniBand addresses. Those are kept in three different
formats:

1) A "raw" format as obtained from the device. This format is known
   only by the media specific adapter code in eth_media.c and
   ib_media.c.
2) A "generic" internal format, in the form of struct tipc_media_addr,
   which can be referenced and passed around by the generic media-
   unaware code.
3) A serialized version of the latter, to be conveyed in neighbor
   discovery messages.

Conversion between the three formats can only be done by the media
specific code, so we have function pointers for this purpose in
struct tipc_media. Here, the media adapters can install their own
conversion functions at startup.

We now introduce a new such function, 'raw2addr()', whose purpose
is to convert from format 1 to format 2 above. We also try to as far
as possible uniform commenting, variable names and usage of these
functions, with the purpose of making them more comprehensible.

We can now also remove the function tipc_l2_media_addr_set(), whose
job is done better by the new function.

Finally, we expand the field for serialized addresses (format 3)
in discovery messages from 20 to 32 bytes. This is permitted
according to the spec, and reduces the risk of problems when we
add new media in the future.
Signed-off-by: default avatarJon Maloy <jon.maloy@ericsson.com>
Reviewed-by: default avatarYing Xue <ying.xue@windriver.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 37e22164
...@@ -411,28 +411,6 @@ int tipc_disable_bearer(const char *name) ...@@ -411,28 +411,6 @@ int tipc_disable_bearer(const char *name)
return res; return res;
} }
/* tipc_l2_media_addr_set - initialize Ethernet media address structure
*
* Media-dependent "value" field stores MAC address in first 6 bytes
* and zeroes out the remaining bytes.
*/
void tipc_l2_media_addr_set(const struct tipc_bearer *b,
struct tipc_media_addr *a, char *mac)
{
int len = b->media->hwaddr_len;
if (unlikely(sizeof(a->value) < len)) {
WARN_ONCE(1, "Media length invalid\n");
return;
}
memcpy(a->value, mac, len);
memset(a->value + len, 0, sizeof(a->value) - len);
a->media_id = b->media->type_id;
a->broadcast = !memcmp(mac, b->bcast_addr.value, len);
}
int tipc_enable_l2_media(struct tipc_bearer *b) int tipc_enable_l2_media(struct tipc_bearer *b)
{ {
struct net_device *dev; struct net_device *dev;
...@@ -443,21 +421,21 @@ int tipc_enable_l2_media(struct tipc_bearer *b) ...@@ -443,21 +421,21 @@ int tipc_enable_l2_media(struct tipc_bearer *b)
if (!dev) if (!dev)
return -ENODEV; return -ENODEV;
/* Associate TIPC bearer with Ethernet bearer */ /* Associate TIPC bearer with L2 bearer */
rcu_assign_pointer(b->media_ptr, dev); rcu_assign_pointer(b->media_ptr, dev);
memset(b->bcast_addr.value, 0, sizeof(b->bcast_addr.value)); memset(&b->bcast_addr, 0, sizeof(b->bcast_addr));
memcpy(b->bcast_addr.value, dev->broadcast, b->media->hwaddr_len); memcpy(b->bcast_addr.value, dev->broadcast, b->media->hwaddr_len);
b->bcast_addr.media_id = b->media->type_id; b->bcast_addr.media_id = b->media->type_id;
b->bcast_addr.broadcast = 1; b->bcast_addr.broadcast = 1;
b->mtu = dev->mtu; b->mtu = dev->mtu;
tipc_l2_media_addr_set(b, &b->addr, (char *)dev->dev_addr); b->media->raw2addr(b, &b->addr, (char *)dev->dev_addr);
rcu_assign_pointer(dev->tipc_ptr, b); rcu_assign_pointer(dev->tipc_ptr, b);
return 0; return 0;
} }
/* tipc_disable_l2_media - detach TIPC bearer from an Ethernet interface /* tipc_disable_l2_media - detach TIPC bearer from an L2 interface
* *
* Mark Ethernet bearer as inactive so that incoming buffers are thrown away, * Mark L2 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.)
*/ */
...@@ -473,7 +451,7 @@ void tipc_disable_l2_media(struct tipc_bearer *b) ...@@ -473,7 +451,7 @@ void tipc_disable_l2_media(struct tipc_bearer *b)
} }
/** /**
* tipc_l2_send_msg - send a TIPC packet out over an Ethernet interface * tipc_l2_send_msg - send a TIPC packet out over an L2 interface
* @buf: the packet to be sent * @buf: the packet to be sent
* @b_ptr: the bearer through which the packet is to be sent * @b_ptr: the bearer through which the packet is to be sent
* @dest: peer destination address * @dest: peer destination address
...@@ -597,7 +575,7 @@ static int tipc_l2_device_event(struct notifier_block *nb, unsigned long evt, ...@@ -597,7 +575,7 @@ static int tipc_l2_device_event(struct notifier_block *nb, unsigned long evt,
tipc_reset_bearer(b_ptr); tipc_reset_bearer(b_ptr);
break; break;
case NETDEV_CHANGEADDR: case NETDEV_CHANGEADDR:
tipc_l2_media_addr_set(b_ptr, &b_ptr->addr, b_ptr->media->raw2addr(b_ptr, &b_ptr->addr,
(char *)dev->dev_addr); (char *)dev->dev_addr);
tipc_reset_bearer(b_ptr); tipc_reset_bearer(b_ptr);
break; break;
......
...@@ -42,14 +42,12 @@ ...@@ -42,14 +42,12 @@
#define MAX_BEARERS 2 #define MAX_BEARERS 2
#define MAX_MEDIA 2 #define MAX_MEDIA 2
/* /* Identifiers associated with TIPC message header media address info
* Identifiers associated with TIPC message header media address info * - address info field is 32 bytes long
* * - the field's actual content and length is defined per media
* - address info field is 20 bytes long * - remaining unused bytes in the field are set to zero
* - media type identifier located at offset 3
* - remaining bytes vary according to media type
*/ */
#define TIPC_MEDIA_ADDR_SIZE 20 #define TIPC_MEDIA_ADDR_SIZE 32
#define TIPC_MEDIA_TYPE_OFFSET 3 #define TIPC_MEDIA_TYPE_OFFSET 3
/* /*
...@@ -77,9 +75,10 @@ struct tipc_bearer; ...@@ -77,9 +75,10 @@ struct tipc_bearer;
* @send_msg: routine which handles buffer transmission * @send_msg: routine which handles buffer transmission
* @enable_media: routine which enables a media * @enable_media: routine which enables a media
* @disable_media: routine which disables a media * @disable_media: routine which disables a media
* @addr2str: routine which converts media address to string * @addr2str: convert media address format to string
* @addr2msg: routine which converts media address to protocol message area * @addr2msg: convert from media addr format to discovery msg addr format
* @msg2addr: routine which converts media address from protocol message area * @msg2addr: convert from discovery msg addr format to media addr format
* @raw2addr: convert from raw addr format to media addr format
* @priority: default link (and bearer) priority * @priority: default link (and bearer) priority
* @tolerance: default time (in ms) before declaring link failure * @tolerance: default time (in ms) before declaring link failure
* @window: default window (in packets) before declaring link congestion * @window: default window (in packets) before declaring link congestion
...@@ -93,10 +92,16 @@ struct tipc_media { ...@@ -93,10 +92,16 @@ struct tipc_media {
struct tipc_media_addr *dest); struct tipc_media_addr *dest);
int (*enable_media)(struct tipc_bearer *b_ptr); int (*enable_media)(struct tipc_bearer *b_ptr);
void (*disable_media)(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 *addr,
int (*addr2msg)(struct tipc_media_addr *a, char *msg_area); char *strbuf,
int (*msg2addr)(const struct tipc_bearer *b_ptr, int bufsz);
struct tipc_media_addr *a, char *msg_area); int (*addr2msg)(char *msg, struct tipc_media_addr *addr);
int (*msg2addr)(struct tipc_bearer *b,
struct tipc_media_addr *addr,
char *msg);
int (*raw2addr)(struct tipc_bearer *b,
struct tipc_media_addr *addr,
char *raw);
u32 priority; u32 priority;
u32 tolerance; u32 tolerance;
u32 window; u32 window;
...@@ -175,8 +180,6 @@ int tipc_media_set_priority(const char *name, u32 new_value); ...@@ -175,8 +180,6 @@ int tipc_media_set_priority(const char *name, u32 new_value);
int tipc_media_set_window(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); void tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a);
struct sk_buff *tipc_media_get_names(void); struct sk_buff *tipc_media_get_names(void);
void tipc_l2_media_addr_set(const struct tipc_bearer *b,
struct tipc_media_addr *a, char *mac);
int tipc_enable_l2_media(struct tipc_bearer *b); int tipc_enable_l2_media(struct tipc_bearer *b);
void tipc_disable_l2_media(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, int tipc_l2_send_msg(struct sk_buff *buf, struct tipc_bearer *b,
......
...@@ -57,6 +57,7 @@ ...@@ -57,6 +57,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/rtnetlink.h> #include <linux/rtnetlink.h>
#include <linux/etherdevice.h>
#define TIPC_MOD_VER "2.0.0" #define TIPC_MOD_VER "2.0.0"
......
...@@ -83,7 +83,7 @@ static void tipc_disc_init_msg(struct sk_buff *buf, u32 type, ...@@ -83,7 +83,7 @@ static void tipc_disc_init_msg(struct sk_buff *buf, u32 type,
msg_set_node_sig(msg, tipc_random); msg_set_node_sig(msg, tipc_random);
msg_set_dest_domain(msg, dest_domain); msg_set_dest_domain(msg, dest_domain);
msg_set_bc_netid(msg, tipc_net_id); msg_set_bc_netid(msg, tipc_net_id);
b_ptr->media->addr2msg(&b_ptr->addr, msg_media_addr(msg)); b_ptr->media->addr2msg(msg_media_addr(msg), &b_ptr->addr);
} }
/** /**
......
/* /*
* net/tipc/eth_media.c: Ethernet bearer support for TIPC * net/tipc/eth_media.c: Ethernet bearer support for TIPC
* *
* Copyright (c) 2001-2007, 2013, Ericsson AB * Copyright (c) 2001-2007, 2013-2014, Ericsson AB
* Copyright (c) 2005-2008, 2011-2013, Wind River Systems * Copyright (c) 2005-2008, 2011-2013, Wind River Systems
* All rights reserved. * All rights reserved.
* *
...@@ -37,39 +37,52 @@ ...@@ -37,39 +37,52 @@
#include "core.h" #include "core.h"
#include "bearer.h" #include "bearer.h"
#define ETH_ADDR_OFFSET 4 /* message header offset of MAC address */ #define ETH_ADDR_OFFSET 4 /* MAC addr position inside address field */
/* convert Ethernet address to string */ /* Convert Ethernet address (media address format) to string */
static int tipc_eth_addr2str(struct tipc_media_addr *a, char *str_buf, static int tipc_eth_addr2str(struct tipc_media_addr *addr,
int str_size) char *strbuf, int bufsz)
{ {
if (str_size < 18) /* 18 = strlen("aa:bb:cc:dd:ee:ff\0") */ if (bufsz < 18) /* 18 = strlen("aa:bb:cc:dd:ee:ff\0") */
return 1; return 1;
sprintf(str_buf, "%pM", a->value); sprintf(strbuf, "%pM", addr->value);
return 0; return 0;
} }
/* convert Ethernet address format to message header format */ /* Convert from media address format to discovery message addr format */
static int tipc_eth_addr2msg(struct tipc_media_addr *a, char *msg_area) static int tipc_eth_addr2msg(char *msg, struct tipc_media_addr *addr)
{ {
memset(msg_area, 0, TIPC_MEDIA_ADDR_SIZE); memset(msg, 0, TIPC_MEDIA_ADDR_SIZE);
msg_area[TIPC_MEDIA_TYPE_OFFSET] = TIPC_MEDIA_TYPE_ETH; msg[TIPC_MEDIA_TYPE_OFFSET] = TIPC_MEDIA_TYPE_ETH;
memcpy(msg_area + ETH_ADDR_OFFSET, a->value, ETH_ALEN); memcpy(msg + ETH_ADDR_OFFSET, addr->value, ETH_ALEN);
return 0; return 0;
} }
/* convert message header address format to Ethernet format */ /* Convert raw mac address format to media addr format */
static int tipc_eth_msg2addr(const struct tipc_bearer *tb_ptr, static int tipc_eth_raw2addr(struct tipc_bearer *b,
struct tipc_media_addr *a, char *msg_area) struct tipc_media_addr *addr,
char *msg)
{ {
if (msg_area[TIPC_MEDIA_TYPE_OFFSET] != TIPC_MEDIA_TYPE_ETH) char bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
return 1;
tipc_l2_media_addr_set(tb_ptr, a, msg_area + ETH_ADDR_OFFSET); memset(addr, 0, sizeof(*addr));
ether_addr_copy(addr->value, msg);
addr->media_id = TIPC_MEDIA_TYPE_ETH;
addr->broadcast = !memcmp(addr->value, bcast_mac, ETH_ALEN);
return 0; return 0;
} }
/* Convert discovery msg addr format to Ethernet media addr format */
static int tipc_eth_msg2addr(struct tipc_bearer *b,
struct tipc_media_addr *addr,
char *msg)
{
/* Skip past preamble: */
msg += ETH_ADDR_OFFSET;
return tipc_eth_raw2addr(b, addr, msg);
}
/* Ethernet media registration info */ /* Ethernet media registration info */
struct tipc_media eth_media_info = { struct tipc_media eth_media_info = {
.send_msg = tipc_l2_send_msg, .send_msg = tipc_l2_send_msg,
...@@ -78,6 +91,7 @@ struct tipc_media eth_media_info = { ...@@ -78,6 +91,7 @@ struct tipc_media eth_media_info = {
.addr2str = tipc_eth_addr2str, .addr2str = tipc_eth_addr2str,
.addr2msg = tipc_eth_addr2msg, .addr2msg = tipc_eth_addr2msg,
.msg2addr = tipc_eth_msg2addr, .msg2addr = tipc_eth_msg2addr,
.raw2addr = tipc_eth_raw2addr,
.priority = TIPC_DEF_LINK_PRI, .priority = TIPC_DEF_LINK_PRI,
.tolerance = TIPC_DEF_LINK_TOL, .tolerance = TIPC_DEF_LINK_TOL,
.window = TIPC_DEF_LINK_WIN, .window = TIPC_DEF_LINK_WIN,
...@@ -85,4 +99,3 @@ struct tipc_media eth_media_info = { ...@@ -85,4 +99,3 @@ struct tipc_media eth_media_info = {
.hwaddr_len = ETH_ALEN, .hwaddr_len = ETH_ALEN,
.name = "eth" .name = "eth"
}; };
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
#include "core.h" #include "core.h"
#include "bearer.h" #include "bearer.h"
/* convert InfiniBand address to string */ /* convert InfiniBand address (media address format) media address to string */
static int tipc_ib_addr2str(struct tipc_media_addr *a, char *str_buf, static int tipc_ib_addr2str(struct tipc_media_addr *a, char *str_buf,
int str_size) int str_size)
{ {
...@@ -54,23 +54,35 @@ static int tipc_ib_addr2str(struct tipc_media_addr *a, char *str_buf, ...@@ -54,23 +54,35 @@ static int tipc_ib_addr2str(struct tipc_media_addr *a, char *str_buf,
return 0; return 0;
} }
/* convert InfiniBand address format to message header format */ /* Convert from media address format to discovery message addr format */
static int tipc_ib_addr2msg(struct tipc_media_addr *a, char *msg_area) static int tipc_ib_addr2msg(char *msg, struct tipc_media_addr *addr)
{ {
memset(msg_area, 0, TIPC_MEDIA_ADDR_SIZE); memset(msg, 0, TIPC_MEDIA_ADDR_SIZE);
msg_area[TIPC_MEDIA_TYPE_OFFSET] = TIPC_MEDIA_TYPE_IB; memcpy(msg, addr->value, INFINIBAND_ALEN);
memcpy(msg_area, a->value, INFINIBAND_ALEN);
return 0; return 0;
} }
/* convert message header address format to InfiniBand format */ /* Convert raw InfiniBand address format to media addr format */
static int tipc_ib_msg2addr(const struct tipc_bearer *tb_ptr, static int tipc_ib_raw2addr(struct tipc_bearer *b,
struct tipc_media_addr *a, char *msg_area) struct tipc_media_addr *addr,
char *msg)
{ {
tipc_l2_media_addr_set(tb_ptr, a, msg_area); memset(addr, 0, sizeof(*addr));
memcpy(addr->value, msg, INFINIBAND_ALEN);
addr->media_id = TIPC_MEDIA_TYPE_IB;
addr->broadcast = !memcmp(msg, b->bcast_addr.value,
INFINIBAND_ALEN);
return 0; return 0;
} }
/* Convert discovery msg addr format to InfiniBand media addr format */
static int tipc_ib_msg2addr(struct tipc_bearer *b,
struct tipc_media_addr *addr,
char *msg)
{
return tipc_ib_raw2addr(b, addr, msg);
}
/* InfiniBand media registration info */ /* InfiniBand media registration info */
struct tipc_media ib_media_info = { struct tipc_media ib_media_info = {
.send_msg = tipc_l2_send_msg, .send_msg = tipc_l2_send_msg,
...@@ -79,6 +91,7 @@ struct tipc_media ib_media_info = { ...@@ -79,6 +91,7 @@ struct tipc_media ib_media_info = {
.addr2str = tipc_ib_addr2str, .addr2str = tipc_ib_addr2str,
.addr2msg = tipc_ib_addr2msg, .addr2msg = tipc_ib_addr2msg,
.msg2addr = tipc_ib_msg2addr, .msg2addr = tipc_ib_msg2addr,
.raw2addr = tipc_ib_raw2addr,
.priority = TIPC_DEF_LINK_PRI, .priority = TIPC_DEF_LINK_PRI,
.tolerance = TIPC_DEF_LINK_TOL, .tolerance = TIPC_DEF_LINK_TOL,
.window = TIPC_DEF_LINK_WIN, .window = TIPC_DEF_LINK_WIN,
...@@ -86,4 +99,3 @@ struct tipc_media ib_media_info = { ...@@ -86,4 +99,3 @@ struct tipc_media ib_media_info = {
.hwaddr_len = INFINIBAND_ALEN, .hwaddr_len = INFINIBAND_ALEN,
.name = "ib" .name = "ib"
}; };
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