net: l2: Add enable callback
This adds enable callback which can be used to notify the L2 driver about changes of interface state, the L2 driver can then check if the new state is allowed and reject otherwise. Change-Id: I4bb6b1e32be2633f24694c0246585f803f8c645d Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
parent
bf4fb51f44
commit
8a16c6681a
6 changed files with 54 additions and 5 deletions
|
@ -55,6 +55,12 @@ struct net_l2 {
|
|||
*/
|
||||
uint16_t (*reserve)(struct net_if *iface, void *data);
|
||||
|
||||
/**
|
||||
* This function is used to enable/disable traffic over a network
|
||||
* interface.
|
||||
*/
|
||||
int (*enable)(struct net_if *iface, bool state);
|
||||
|
||||
#if defined(CONFIG_NET_L2_OFFLOAD_IP)
|
||||
struct net_l2_offload_ip *offload_ip;
|
||||
#endif /* CONFIG_NET_L2_OFFLOAD_IP */
|
||||
|
@ -98,12 +104,13 @@ NET_L2_DECLARE_PUBLIC(IEEE802154_L2);
|
|||
|
||||
extern struct net_l2 __net_l2_end[];
|
||||
|
||||
#define NET_L2_INIT(_name, _recv_fn, _send_fn, _reserve_fn) \
|
||||
#define NET_L2_INIT(_name, _recv_fn, _send_fn, _reserve_fn, _enable_fn) \
|
||||
const struct net_l2 const (NET_L2_GET_NAME(_name)) __used \
|
||||
__attribute__((__section__(".net_l2.init"))) = { \
|
||||
.recv = (_recv_fn), \
|
||||
.send = (_send_fn), \
|
||||
.reserve = (_reserve_fn), \
|
||||
.enable = (_enable_fn), \
|
||||
}
|
||||
|
||||
#define NET_L2_GET_DATA(name, sfx) (__net_l2_data_##name##sfx)
|
||||
|
|
|
@ -109,7 +109,21 @@ static inline uint16_t net_bt_reserve(struct net_if *iface, void *unused)
|
|||
return 0;
|
||||
}
|
||||
|
||||
NET_L2_INIT(BLUETOOTH_L2, net_bt_recv, net_bt_send, net_bt_reserve);
|
||||
static int net_bt_enable(struct net_if *iface, bool state)
|
||||
{
|
||||
struct bt_context *ctxt = net_if_get_device(iface)->driver_data;
|
||||
|
||||
NET_DBG("iface %p %s", iface, state ? "up" : "down");
|
||||
|
||||
if (state && !ctxt->ipsp_chan.chan.conn) {
|
||||
return -ENETDOWN;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
NET_L2_INIT(BLUETOOTH_L2, net_bt_recv, net_bt_send, net_bt_reserve,
|
||||
net_bt_enable);
|
||||
|
||||
static void ipsp_connected(struct bt_l2cap_chan *chan)
|
||||
{
|
||||
|
|
|
@ -46,4 +46,4 @@ static inline uint16_t dummy_reserve(struct net_if *iface, void *unused)
|
|||
return 0;
|
||||
}
|
||||
|
||||
NET_L2_INIT(DUMMY_L2, dummy_recv, dummy_send, dummy_reserve);
|
||||
NET_L2_INIT(DUMMY_L2, dummy_recv, dummy_send, dummy_reserve, NULL);
|
||||
|
|
|
@ -343,4 +343,4 @@ static inline uint16_t ethernet_reserve(struct net_if *iface, void *unused)
|
|||
return sizeof(struct net_eth_hdr);
|
||||
}
|
||||
|
||||
NET_L2_INIT(ETHERNET_L2, ethernet_recv, ethernet_send, ethernet_reserve);
|
||||
NET_L2_INIT(ETHERNET_L2, ethernet_recv, ethernet_send, ethernet_reserve, NULL);
|
||||
|
|
|
@ -321,7 +321,7 @@ static uint16_t ieeee802154_reserve(struct net_if *iface, void *data)
|
|||
}
|
||||
|
||||
NET_L2_INIT(IEEE802154_L2,
|
||||
ieee802154_recv, ieee802154_send, ieeee802154_reserve);
|
||||
ieee802154_recv, ieee802154_send, ieeee802154_reserve, NULL);
|
||||
|
||||
void ieee802154_init(struct net_if *iface)
|
||||
{
|
||||
|
|
|
@ -1343,12 +1343,26 @@ void net_if_foreach(net_if_cb_t cb, void *user_data)
|
|||
|
||||
int net_if_up(struct net_if *iface)
|
||||
{
|
||||
int status;
|
||||
|
||||
NET_DBG("iface %p", iface);
|
||||
|
||||
if (atomic_test_bit(iface->flags, NET_IF_UP)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If the L2 does not support enable just set the flag */
|
||||
if (!iface->l2->enable) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Notify L2 to enable the interface */
|
||||
status = iface->l2->enable(iface, true);
|
||||
if (status < 0) {
|
||||
return status;
|
||||
}
|
||||
|
||||
done:
|
||||
atomic_set_bit(iface->flags, NET_IF_UP);
|
||||
|
||||
#if defined(CONFIG_NET_IPV6_DAD)
|
||||
|
@ -1366,8 +1380,22 @@ int net_if_up(struct net_if *iface)
|
|||
|
||||
int net_if_down(struct net_if *iface)
|
||||
{
|
||||
int status;
|
||||
|
||||
NET_DBG("iface %p", iface);
|
||||
|
||||
/* If the L2 does not support enable just set the flag */
|
||||
if (!iface->l2->enable) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Notify L2 to disable the interface */
|
||||
status = iface->l2->enable(iface, false);
|
||||
if (status < 0) {
|
||||
return status;
|
||||
}
|
||||
|
||||
done:
|
||||
atomic_clear_bit(iface->flags, NET_IF_UP);
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue