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:
parent
17d045244a
commit
ccfcdabaf6
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue