Skip to content

Commit

Permalink
net: l2: Add flags to tell if L2 supports multicast
Browse files Browse the repository at this point in the history
If multicast is not supported, then we do not need to join
multicast group.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
  • Loading branch information
jukkar committed Aug 8, 2018
1 parent 17d0452 commit ccfcdab
Show file tree
Hide file tree
Showing 9 changed files with 77 additions and 13 deletions.
5 changes: 5 additions & 0 deletions include/net/ethernet.h
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,11 @@ struct ethernet_context {
struct ethernet_lldp lldp[NET_VLAN_MAX_COUNT];
#endif

/**
* This tells what L2 features does ethernet support.
*/
enum net_l2_flags ethernet_l2_flags;

#if defined(CONFIG_NET_GPTP)
/** The gPTP port number for this network device. We need to store the
* port number here so that we do not need to fetch it for every
Expand Down
1 change: 1 addition & 0 deletions include/net/ieee802154.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ struct ieee802154_security_ctx {

/* This not meant to be used by any code but 802.15.4 L2 stack */
struct ieee802154_context {
enum net_l2_flags flags;
u16_t pan_id;
u16_t channel;
struct k_sem ack_lock;
Expand Down
16 changes: 14 additions & 2 deletions include/net/net_l2.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ extern "C" {

struct net_if;

enum net_l2_flags {
/** IP multicast supported */
NET_L2_MULTICAST = BIT(0),
};

struct net_l2 {
/**
* This function is used by net core to get iface's L2 layer parsing
Expand All @@ -50,9 +55,14 @@ struct net_l2 {

/**
* This function is used to enable/disable traffic over a network
* interface.
* interface. The function returns <0 if error and >=0 if no error.
*/
int (*enable)(struct net_if *iface, bool state);

/**
* Return L2 flags for the network interface.
*/
enum net_l2_flags (*get_flags)(struct net_if *iface);
};

#define NET_L2_GET_NAME(_name) (__net_l2_##_name)
Expand Down Expand Up @@ -87,13 +97,15 @@ NET_L2_DECLARE_PUBLIC(BLUETOOTH_L2);
NET_L2_DECLARE_PUBLIC(OPENTHREAD_L2);
#endif /* CONFIG_NET_L2_OPENTHREAD */

#define NET_L2_INIT(_name, _recv_fn, _send_fn, _reserve_fn, _enable_fn) \
#define NET_L2_INIT(_name, _recv_fn, _send_fn, _reserve_fn, _enable_fn, \
_get_flags_fn) \
const struct net_l2 (NET_L2_GET_NAME(_name)) __used \
__attribute__((__section__(".net_l2.init"))) = { \
.recv = (_recv_fn), \
.send = (_send_fn), \
.reserve = (_reserve_fn), \
.enable = (_enable_fn), \
.get_flags = (_get_flags_fn), \
}

#define NET_L2_GET_DATA(name, sfx) (__net_l2_data_##name##sfx)
Expand Down
25 changes: 19 additions & 6 deletions subsys/net/ip/net_if.c
Original file line number Diff line number Diff line change
Expand Up @@ -819,6 +819,21 @@ static inline struct in6_addr *check_global_addr(struct net_if *iface)
return NULL;
}

static void join_mcast_nodes(struct net_if *iface, struct in6_addr *addr)
{
enum net_l2_flags flags = 0;

if (net_if_l2(iface)->get_flags) {
flags = net_if_l2(iface)->get_flags(iface);
}

if (flags & NET_L2_MULTICAST) {
join_mcast_allnodes(iface);

join_mcast_solicit_node(iface, addr);
}
}

struct net_if_addr *net_if_ipv6_addr_add(struct net_if *iface,
struct in6_addr *addr,
enum net_addr_type addr_type,
Expand Down Expand Up @@ -860,9 +875,7 @@ struct net_if_addr *net_if_ipv6_addr_add(struct net_if *iface,
/* The allnodes multicast group is only joined once as
* net_ipv6_mcast_join() checks if we have already joined.
*/
join_mcast_allnodes(iface);
join_mcast_solicit_node(iface,
&ipv6->unicast[i].address.in6_addr);
join_mcast_nodes(iface, &ipv6->unicast[i].address.in6_addr);

#if defined(CONFIG_NET_RPL)
/* Do not send DAD for global addresses */
Expand Down Expand Up @@ -1618,6 +1631,7 @@ u32_t net_if_ipv6_calc_reachable_time(struct net_if_ipv6 *ipv6)
#define join_mcast_allnodes(...)
#define join_mcast_solicit_node(...)
#define leave_mcast_all(...)
#define join_mcast_nodes(...)
#endif /* CONFIG_NET_IPV6 */

#if defined(CONFIG_NET_IPV4)
Expand Down Expand Up @@ -2300,9 +2314,8 @@ int net_if_up(struct net_if *iface)
NET_DBG("Starting DAD for iface %p", iface);
net_if_start_dad(iface);
#else
join_mcast_allnodes(iface);
join_mcast_solicit_node(iface,
&iface->config.ip.ipv6->mcast[0].address.in6_addr);
join_mcast_nodes(iface,
&iface->config.ip.ipv6->mcast[0].address.in6_addr);
#endif /* CONFIG_NET_IPV6_DAD */

#if defined(CONFIG_NET_IPV6_ND)
Expand Down
7 changes: 6 additions & 1 deletion subsys/net/l2/bluetooth/bluetooth.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,13 @@ static int net_bt_enable(struct net_if *iface, bool state)
return 0;
}

static enum net_l2_flags net_bt_flags(struct net_if *iface)
{
return NET_L2_MULTICAST;
}

NET_L2_INIT(BLUETOOTH_L2, net_bt_recv, net_bt_send, net_bt_reserve,
net_bt_enable);
net_bt_enable, net_bt_flags);

static void ipsp_connected(struct bt_l2cap_chan *chan)
{
Expand Down
8 changes: 7 additions & 1 deletion subsys/net/l2/dummy/dummy.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,10 @@ static inline u16_t dummy_reserve(struct net_if *iface, void *unused)
return 0;
}

NET_L2_INIT(DUMMY_L2, dummy_recv, dummy_send, dummy_reserve, NULL);
static enum net_l2_flags dummy_flags(struct net_if *iface)
{
return NET_L2_MULTICAST;
}

NET_L2_INIT(DUMMY_L2, dummy_recv, dummy_send, dummy_reserve, NULL, \
dummy_flags);
11 changes: 10 additions & 1 deletion subsys/net/l2/ethernet/ethernet.c
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,13 @@ static inline int ethernet_enable(struct net_if *iface, bool state)
return 0;
}

enum net_l2_flags ethernet_flags(struct net_if *iface)
{
struct ethernet_context *ctx = net_if_l2_data(iface);

return ctx->ethernet_l2_flags;
}

#if defined(CONFIG_NET_VLAN)
struct net_if *net_eth_get_vlan_iface(struct net_if *iface, u16_t tag)
{
Expand Down Expand Up @@ -805,7 +812,7 @@ int net_eth_vlan_disable(struct net_if *iface, u16_t tag)
#endif

NET_L2_INIT(ETHERNET_L2, ethernet_recv, ethernet_send, ethernet_reserve,
ethernet_enable);
ethernet_enable, ethernet_flags);

static void carrier_on(struct k_work *work)
{
Expand Down Expand Up @@ -930,6 +937,8 @@ void ethernet_init(struct net_if *iface)

NET_DBG("Initializing Ethernet L2 %p for iface %p", ctx, iface);

ctx->ethernet_l2_flags = NET_L2_MULTICAST;

#if defined(CONFIG_NET_VLAN)
if (!(net_eth_get_hw_capabilities(iface) & ETHERNET_HW_VLAN)) {
return;
Expand Down
10 changes: 9 additions & 1 deletion subsys/net/l2/ieee802154/ieee802154.c
Original file line number Diff line number Diff line change
Expand Up @@ -305,9 +305,16 @@ static int ieee802154_enable(struct net_if *iface, bool state)
return ieee802154_stop(iface);
}

enum net_l2_flags ieee802154_flags(struct net_if *iface)
{
struct ieee802154_context *ctx = net_if_l2_data(iface);

return ctx->flags;
}

NET_L2_INIT(IEEE802154_L2,
ieee802154_recv, ieee802154_send,
ieee802154_reserve, ieee802154_enable);
ieee802154_reserve, ieee802154_enable, ieee802154_flags);

void ieee802154_init(struct net_if *iface)
{
Expand All @@ -319,6 +326,7 @@ void ieee802154_init(struct net_if *iface)
NET_DBG("Initializing IEEE 802.15.4 stack on iface %p", iface);

ctx->channel = IEEE802154_NO_CHANNEL;
ctx->flags = NET_L2_MULTICAST;

ieee802154_mgmt_init(iface);

Expand Down
7 changes: 6 additions & 1 deletion subsys/net/l2/openthread/openthread.c
Original file line number Diff line number Diff line change
Expand Up @@ -360,5 +360,10 @@ int ieee802154_radio_send(struct net_if *iface, struct net_pkt *pkt)
return -EIO;
}

static enum net_l2_flags openthread_flags(struct net_if *iface)
{
return NET_L2_MULTICAST;
}

NET_L2_INIT(OPENTHREAD_L2, openthread_recv, openthread_send,
openthread_reserve, NULL);
openthread_reserve, NULL, openthread_flags);

0 comments on commit ccfcdab

Please sign in to comment.