net: l2: Add flags to tell if L2 supports multicast

If multicast is not supported, then we do not need to join
multicast group.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit is contained in:
Jukka Rissanen 2018-08-06 16:59:33 +03:00
parent 17d045244a
commit ccfcdabaf6
9 changed files with 77 additions and 13 deletions

View file

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

View file

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

View file

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

View file

@ -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,
@ -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 */
@ -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)
@ -2300,9 +2314,8 @@ done:
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)

View file

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

View file

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

View file

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

View file

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

View file

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