Commit 9999974a authored by Jon Paul Maloy's avatar Jon Paul Maloy Committed by David S. Miller

tipc: add function for checking broadcast support in bearer

As a preparation for the 'replicast' functionality we are going to
introduce in the next commits, we need the broadcast base structure to
store whether bearer broadcast is available at all from the currently
used bearer or bearers.

We do this by adding a new function tipc_bearer_bcast_support() to
the bearer layer, and letting the bearer selection function in
bcast.c use this to give a new boolean field, 'bcast_support' the
appropriate value.
Reviewed-by: default avatarParthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
Acked-by: default avatarYing Xue <ying.xue@windriver.com>
Signed-off-by: default avatarJon Maloy <jon.maloy@ericsson.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a5e8c070
/* /*
* net/tipc/bcast.c: TIPC broadcast code * net/tipc/bcast.c: TIPC broadcast code
* *
* Copyright (c) 2004-2006, 2014-2015, Ericsson AB * Copyright (c) 2004-2006, 2014-2016, Ericsson AB
* Copyright (c) 2004, Intel Corporation. * Copyright (c) 2004, Intel Corporation.
* Copyright (c) 2005, 2010-2011, Wind River Systems * Copyright (c) 2005, 2010-2011, Wind River Systems
* All rights reserved. * All rights reserved.
...@@ -54,12 +54,14 @@ const char tipc_bclink_name[] = "broadcast-link"; ...@@ -54,12 +54,14 @@ const char tipc_bclink_name[] = "broadcast-link";
* @inputq: data input queue; will only carry SOCK_WAKEUP messages * @inputq: data input queue; will only carry SOCK_WAKEUP messages
* @dest: array keeping number of reachable destinations per bearer * @dest: array keeping number of reachable destinations per bearer
* @primary_bearer: a bearer having links to all broadcast destinations, if any * @primary_bearer: a bearer having links to all broadcast destinations, if any
* @bcast_support: indicates if primary bearer, if any, supports broadcast
*/ */
struct tipc_bc_base { struct tipc_bc_base {
struct tipc_link *link; struct tipc_link *link;
struct sk_buff_head inputq; struct sk_buff_head inputq;
int dests[MAX_BEARERS]; int dests[MAX_BEARERS];
int primary_bearer; int primary_bearer;
bool bcast_support;
}; };
static struct tipc_bc_base *tipc_bc_base(struct net *net) static struct tipc_bc_base *tipc_bc_base(struct net *net)
...@@ -79,9 +81,10 @@ static void tipc_bcbase_select_primary(struct net *net) ...@@ -79,9 +81,10 @@ static void tipc_bcbase_select_primary(struct net *net)
{ {
struct tipc_bc_base *bb = tipc_bc_base(net); struct tipc_bc_base *bb = tipc_bc_base(net);
int all_dests = tipc_link_bc_peers(bb->link); int all_dests = tipc_link_bc_peers(bb->link);
int i, mtu; int i, mtu, prim;
bb->primary_bearer = INVALID_BEARER_ID; bb->primary_bearer = INVALID_BEARER_ID;
bb->bcast_support = true;
if (!all_dests) if (!all_dests)
return; return;
...@@ -93,7 +96,7 @@ static void tipc_bcbase_select_primary(struct net *net) ...@@ -93,7 +96,7 @@ static void tipc_bcbase_select_primary(struct net *net)
mtu = tipc_bearer_mtu(net, i); mtu = tipc_bearer_mtu(net, i);
if (mtu < tipc_link_mtu(bb->link)) if (mtu < tipc_link_mtu(bb->link))
tipc_link_set_mtu(bb->link, mtu); tipc_link_set_mtu(bb->link, mtu);
bb->bcast_support &= tipc_bearer_bcast_support(net, i);
if (bb->dests[i] < all_dests) if (bb->dests[i] < all_dests)
continue; continue;
...@@ -103,6 +106,9 @@ static void tipc_bcbase_select_primary(struct net *net) ...@@ -103,6 +106,9 @@ static void tipc_bcbase_select_primary(struct net *net)
if ((i ^ tipc_own_addr(net)) & 1) if ((i ^ tipc_own_addr(net)) & 1)
break; break;
} }
prim = bb->primary_bearer;
if (prim != INVALID_BEARER_ID)
bb->bcast_support = tipc_bearer_bcast_support(net, prim);
} }
void tipc_bcast_inc_bearer_dst_cnt(struct net *net, int bearer_id) void tipc_bcast_inc_bearer_dst_cnt(struct net *net, int bearer_id)
......
...@@ -431,7 +431,7 @@ int tipc_enable_l2_media(struct net *net, struct tipc_bearer *b, ...@@ -431,7 +431,7 @@ int tipc_enable_l2_media(struct net *net, struct tipc_bearer *b,
memset(&b->bcast_addr, 0, sizeof(b->bcast_addr)); 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 = TIPC_BROADCAST_SUPPORT;
b->mtu = dev->mtu; b->mtu = dev->mtu;
b->media->raw2addr(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);
...@@ -482,6 +482,19 @@ int tipc_l2_send_msg(struct net *net, struct sk_buff *skb, ...@@ -482,6 +482,19 @@ int tipc_l2_send_msg(struct net *net, struct sk_buff *skb,
return 0; return 0;
} }
bool tipc_bearer_bcast_support(struct net *net, u32 bearer_id)
{
bool supp = false;
struct tipc_bearer *b;
rcu_read_lock();
b = bearer_get(net, bearer_id);
if (b)
supp = (b->bcast_addr.broadcast == TIPC_BROADCAST_SUPPORT);
rcu_read_unlock();
return supp;
}
int tipc_bearer_mtu(struct net *net, u32 bearer_id) int tipc_bearer_mtu(struct net *net, u32 bearer_id)
{ {
int mtu = 0; int mtu = 0;
......
...@@ -60,9 +60,14 @@ ...@@ -60,9 +60,14 @@
#define TIPC_MEDIA_TYPE_IB 2 #define TIPC_MEDIA_TYPE_IB 2
#define TIPC_MEDIA_TYPE_UDP 3 #define TIPC_MEDIA_TYPE_UDP 3
/* minimum bearer MTU */ /* Minimum bearer MTU */
#define TIPC_MIN_BEARER_MTU (MAX_H_SIZE + INT_H_SIZE) #define TIPC_MIN_BEARER_MTU (MAX_H_SIZE + INT_H_SIZE)
/* Identifiers for distinguishing between broadcast/multicast and replicast
*/
#define TIPC_BROADCAST_SUPPORT 1
#define TIPC_REPLICAST_SUPPORT 2
/** /**
* struct tipc_media_addr - destination address used by TIPC bearers * struct tipc_media_addr - destination address used by TIPC bearers
* @value: address info (format defined by media) * @value: address info (format defined by media)
...@@ -210,6 +215,7 @@ int tipc_bearer_setup(void); ...@@ -210,6 +215,7 @@ int tipc_bearer_setup(void);
void tipc_bearer_cleanup(void); void tipc_bearer_cleanup(void);
void tipc_bearer_stop(struct net *net); void tipc_bearer_stop(struct net *net);
int tipc_bearer_mtu(struct net *net, u32 bearer_id); int tipc_bearer_mtu(struct net *net, u32 bearer_id);
bool tipc_bearer_bcast_support(struct net *net, u32 bearer_id);
void tipc_bearer_xmit_skb(struct net *net, u32 bearer_id, void tipc_bearer_xmit_skb(struct net *net, u32 bearer_id,
struct sk_buff *skb, struct sk_buff *skb,
struct tipc_media_addr *dest); struct tipc_media_addr *dest);
......
...@@ -113,7 +113,7 @@ static void tipc_udp_media_addr_set(struct tipc_media_addr *addr, ...@@ -113,7 +113,7 @@ static void tipc_udp_media_addr_set(struct tipc_media_addr *addr,
memcpy(addr->value, ua, sizeof(struct udp_media_addr)); memcpy(addr->value, ua, sizeof(struct udp_media_addr));
if (tipc_udp_is_mcast_addr(ua)) if (tipc_udp_is_mcast_addr(ua))
addr->broadcast = 1; addr->broadcast = TIPC_BROADCAST_SUPPORT;
} }
/* tipc_udp_addr2str - convert ip/udp address to string */ /* tipc_udp_addr2str - convert ip/udp address to string */
...@@ -229,7 +229,7 @@ static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb, ...@@ -229,7 +229,7 @@ static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb,
goto out; goto out;
} }
if (!addr->broadcast || list_empty(&ub->rcast.list)) if (addr->broadcast != TIPC_REPLICAST_SUPPORT)
return tipc_udp_xmit(net, skb, ub, src, dst); return tipc_udp_xmit(net, skb, ub, src, dst);
/* Replicast, send an skb to each configured IP address */ /* Replicast, send an skb to each configured IP address */
...@@ -296,7 +296,7 @@ static int tipc_udp_rcast_add(struct tipc_bearer *b, ...@@ -296,7 +296,7 @@ static int tipc_udp_rcast_add(struct tipc_bearer *b,
else if (ntohs(addr->proto) == ETH_P_IPV6) else if (ntohs(addr->proto) == ETH_P_IPV6)
pr_info("New replicast peer: %pI6\n", &rcast->addr.ipv6); pr_info("New replicast peer: %pI6\n", &rcast->addr.ipv6);
#endif #endif
b->bcast_addr.broadcast = TIPC_REPLICAST_SUPPORT;
list_add_rcu(&rcast->list, &ub->rcast.list); list_add_rcu(&rcast->list, &ub->rcast.list);
return 0; return 0;
} }
...@@ -681,7 +681,7 @@ static int tipc_udp_enable(struct net *net, struct tipc_bearer *b, ...@@ -681,7 +681,7 @@ static int tipc_udp_enable(struct net *net, struct tipc_bearer *b,
goto err; goto err;
b->bcast_addr.media_id = TIPC_MEDIA_TYPE_UDP; b->bcast_addr.media_id = TIPC_MEDIA_TYPE_UDP;
b->bcast_addr.broadcast = 1; b->bcast_addr.broadcast = TIPC_BROADCAST_SUPPORT;
rcu_assign_pointer(b->media_ptr, ub); rcu_assign_pointer(b->media_ptr, ub);
rcu_assign_pointer(ub->bearer, b); rcu_assign_pointer(ub->bearer, b);
tipc_udp_media_addr_set(&b->addr, &local); tipc_udp_media_addr_set(&b->addr, &local);
......
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