net: if: Add NET_IF_UP flag
This adds NET_IF_UP flag support indicating the interface is up, currently this shall only be used internally by the driver, later on it shall be possible to make it public by using dedicated functions. Change-Id: I38090da4030395b2341733b846004789416d61c1 Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
parent
369d5c95df
commit
bf4fb51f44
3 changed files with 96 additions and 14 deletions
|
@ -150,6 +150,14 @@ struct net_if_router {
|
|||
*/
|
||||
#define __net_if_align __aligned(32)
|
||||
|
||||
enum {
|
||||
/* interface is up/ready to receive and transmit */
|
||||
NET_IF_UP,
|
||||
|
||||
/* Total number of flags - must be at the end of the enum */
|
||||
NET_IF_NUM_FLAGS
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Network Interface structure
|
||||
*
|
||||
|
@ -167,6 +175,9 @@ struct net_if {
|
|||
/** The actually device driver instance the net_if is related to */
|
||||
struct device *dev;
|
||||
|
||||
/* For internal use */
|
||||
ATOMIC_DEFINE(flags, NET_IF_NUM_FLAGS);
|
||||
|
||||
/** Interface's L2 layer */
|
||||
const struct net_l2 const *l2;
|
||||
|
||||
|
@ -409,22 +420,20 @@ void net_if_start_rs(struct net_if *iface);
|
|||
* @param iface Pointer to a network interface structure
|
||||
* @param addr a pointer on a uint8_t buffer representing the address
|
||||
* @param len length of the address buffer
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
static inline void net_if_set_link_addr(struct net_if *iface,
|
||||
static inline int net_if_set_link_addr(struct net_if *iface,
|
||||
uint8_t *addr, uint8_t len)
|
||||
{
|
||||
if (atomic_test_bit(iface->flags, NET_IF_UP)) {
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
iface->link_addr.addr = addr;
|
||||
iface->link_addr.len = len;
|
||||
|
||||
#if defined(CONFIG_NET_IPV6_DAD)
|
||||
NET_DBG("Starting DAD for iface %p", iface);
|
||||
net_if_start_dad(iface);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_NET_IPV6_ND)
|
||||
NET_DBG("Starting ND/RS for iface %p", iface);
|
||||
net_if_start_rs(iface);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1088,6 +1097,24 @@ typedef void (*net_if_cb_t)(struct net_if *iface, void *user_data);
|
|||
*/
|
||||
void net_if_foreach(net_if_cb_t cb, void *user_data);
|
||||
|
||||
/**
|
||||
* @brief Bring interface up
|
||||
*
|
||||
* @param iface Pointer to network interface
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
int net_if_up(struct net_if *iface);
|
||||
|
||||
/*
|
||||
* @brief Bring interface down
|
||||
*
|
||||
* @param iface Pointer to network interface
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
int net_if_down(struct net_if *iface);
|
||||
|
||||
struct net_if_api {
|
||||
void (*init)(struct net_if *iface);
|
||||
int (*send)(struct net_if *iface, struct net_buf *buf);
|
||||
|
|
|
@ -135,11 +135,17 @@ static void ipsp_connected(struct bt_l2cap_chan *chan)
|
|||
sys_memcpy_swap(ctxt->dst.val, info.le.dst->a.val, sizeof(ctxt->dst));
|
||||
|
||||
net_if_set_link_addr(ctxt->iface, ctxt->src.val, sizeof(ctxt->src.val));
|
||||
|
||||
/* Set iface up */
|
||||
net_if_up(ctxt->iface);
|
||||
}
|
||||
|
||||
static void ipsp_disconnected(struct bt_l2cap_chan *chan)
|
||||
{
|
||||
NET_DBG("Channel %p disconnected", chan);
|
||||
|
||||
/* Set iface down */
|
||||
net_if_down(ctxt->iface);
|
||||
}
|
||||
|
||||
static void ipsp_recv(struct bt_l2cap_chan *chan, struct net_buf *buf)
|
||||
|
|
|
@ -87,6 +87,8 @@ static void net_if_tx_thread(struct net_if *iface)
|
|||
sizeof(iface->tx_stack), api, &iface->tx_queue);
|
||||
|
||||
api->init(iface);
|
||||
/* Attempt to bring the interface up */
|
||||
net_if_up(iface);
|
||||
|
||||
while (1) {
|
||||
struct net_linkaddr *dst;
|
||||
|
@ -104,7 +106,14 @@ static void net_if_tx_thread(struct net_if *iface)
|
|||
context = net_nbuf_context(buf);
|
||||
context_token = net_nbuf_token(buf);
|
||||
|
||||
status = api->send(iface, buf);
|
||||
if (atomic_test_bit(iface->flags, NET_IF_UP)) {
|
||||
status = api->send(iface, buf);
|
||||
} else {
|
||||
/* Drop packet if interface is not up */
|
||||
NET_WARN("iface %p is down", iface);
|
||||
status = -ENETDOWN;
|
||||
}
|
||||
|
||||
if (status < 0) {
|
||||
net_nbuf_unref(buf);
|
||||
}
|
||||
|
@ -143,8 +152,16 @@ enum net_verdict net_if_send_data(struct net_if *iface, struct net_buf *buf)
|
|||
struct net_linkaddr *dst = net_nbuf_ll_dst(buf);
|
||||
void *token = net_nbuf_token(buf);
|
||||
enum net_verdict verdict;
|
||||
int status = -EIO;
|
||||
|
||||
verdict = iface->l2->send(iface, buf);
|
||||
if (atomic_test_bit(iface->flags, NET_IF_UP)) {
|
||||
verdict = iface->l2->send(iface, buf);
|
||||
} else {
|
||||
/* Drop packet if interface is not up */
|
||||
NET_WARN("iface %p is down", iface);
|
||||
verdict = NET_DROP;
|
||||
status = -ENETDOWN;
|
||||
}
|
||||
|
||||
/* The L2 send() function can return
|
||||
* NET_OK in which case packet was sent successfully.
|
||||
|
@ -159,11 +176,11 @@ enum net_verdict net_if_send_data(struct net_if *iface, struct net_buf *buf)
|
|||
NET_DBG("Calling context send cb %p token %p verdict %d",
|
||||
context, token, verdict);
|
||||
|
||||
net_context_send_cb(context, token, -EIO);
|
||||
net_context_send_cb(context, token, status);
|
||||
}
|
||||
|
||||
if (verdict == NET_DROP) {
|
||||
net_if_call_link_cb(iface, dst, -EIO);
|
||||
net_if_call_link_cb(iface, dst, status);
|
||||
}
|
||||
|
||||
return verdict;
|
||||
|
@ -1324,6 +1341,38 @@ void net_if_foreach(net_if_cb_t cb, void *user_data)
|
|||
}
|
||||
}
|
||||
|
||||
int net_if_up(struct net_if *iface)
|
||||
{
|
||||
NET_DBG("iface %p", iface);
|
||||
|
||||
if (atomic_test_bit(iface->flags, NET_IF_UP)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
atomic_set_bit(iface->flags, NET_IF_UP);
|
||||
|
||||
#if defined(CONFIG_NET_IPV6_DAD)
|
||||
NET_DBG("Starting DAD for iface %p", iface);
|
||||
net_if_start_dad(iface);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_NET_IPV6_ND)
|
||||
NET_DBG("Starting ND/RS for iface %p", iface);
|
||||
net_if_start_rs(iface);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int net_if_down(struct net_if *iface)
|
||||
{
|
||||
NET_DBG("iface %p", iface);
|
||||
|
||||
atomic_clear_bit(iface->flags, NET_IF_UP);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void net_if_init(void)
|
||||
{
|
||||
struct net_if *iface;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue