blob: 95276903fd7dc537e2031e15834b7b05d544609e [file] [log] [blame]
/*
* Copyright (c) 2016 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Public API for network interface
*/
#ifndef ZEPHYR_INCLUDE_NET_NET_IF_H_
#define ZEPHYR_INCLUDE_NET_NET_IF_H_
/**
* @brief Network Interface abstraction layer
* @defgroup net_if Network Interface abstraction layer
* @ingroup networking
* @{
*/
#include <device.h>
#include <sys/slist.h>
#include <net/net_core.h>
#include <net/hostname.h>
#include <net/net_linkaddr.h>
#include <net/net_ip.h>
#include <net/net_l2.h>
#include <net/net_stats.h>
#include <net/net_timeout.h>
#if defined(CONFIG_NET_DHCPV4) && defined(CONFIG_NET_NATIVE_IPV4)
#include <net/dhcpv4.h>
#endif
#if defined(CONFIG_NET_IPV4_AUTO) && defined(CONFIG_NET_NATIVE_IPV4)
#include <net/ipv4_autoconf.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Network Interface unicast IP addresses
*
* Stores the unicast IP addresses assigned to this network interface.
*/
struct net_if_addr {
/** IP address */
struct net_addr address;
#if defined(CONFIG_NET_NATIVE_IPV6)
struct net_timeout lifetime;
#endif
#if defined(CONFIG_NET_IPV6_DAD) && defined(CONFIG_NET_NATIVE_IPV6)
/** Duplicate address detection (DAD) timer */
sys_snode_t dad_node;
uint32_t dad_start;
#endif
/** How the IP address was set */
enum net_addr_type addr_type;
/** What is the current state of the address */
enum net_addr_state addr_state;
#if defined(CONFIG_NET_IPV6_DAD) && defined(CONFIG_NET_NATIVE_IPV6)
/** How many times we have done DAD */
uint8_t dad_count;
#endif
/** Is the IP address valid forever */
uint8_t is_infinite : 1;
/** Is this IP address used or not */
uint8_t is_used : 1;
/** Is this IP address usage limited to the subnet (mesh) or not */
uint8_t is_mesh_local : 1;
uint8_t _unused : 5;
};
/**
* @brief Network Interface multicast IP addresses
*
* Stores the multicast IP addresses assigned to this network interface.
*/
struct net_if_mcast_addr {
/** IP address */
struct net_addr address;
/** Is this multicast IP address used or not */
uint8_t is_used : 1;
/** Did we join to this group */
uint8_t is_joined : 1;
uint8_t _unused : 6;
};
/**
* @brief Network Interface IPv6 prefixes
*
* Stores the multicast IP addresses assigned to this network interface.
*/
struct net_if_ipv6_prefix {
/** Prefix lifetime */
struct net_timeout lifetime;
/** IPv6 prefix */
struct in6_addr prefix;
/** Backpointer to network interface where this prefix is used */
struct net_if *iface;
/** Prefix length */
uint8_t len;
/** Is the IP prefix valid forever */
uint8_t is_infinite : 1;
/** Is this prefix used or not */
uint8_t is_used : 1;
uint8_t _unused : 6;
};
/**
* @brief Information about routers in the system.
*
* Stores the router information.
*/
struct net_if_router {
/** Slist lifetime timer node */
sys_snode_t node;
/** IP address */
struct net_addr address;
/** Network interface the router is connected to */
struct net_if *iface;
/** Router life timer start */
uint32_t life_start;
/** Router lifetime */
uint16_t lifetime;
/** Is this router used or not */
uint8_t is_used : 1;
/** Is default router */
uint8_t is_default : 1;
/** Is the router valid forever */
uint8_t is_infinite : 1;
uint8_t _unused : 5;
};
enum net_if_flag {
/** Interface is up/ready to receive and transmit */
NET_IF_UP,
/** Interface is pointopoint */
NET_IF_POINTOPOINT,
/** Interface is in promiscuous mode */
NET_IF_PROMISC,
/** Do not start the interface immediately after initialization.
* This requires that either the device driver or some other entity
* will need to manually take the interface up when needed.
* For example for Ethernet this will happen when the driver calls
* the net_eth_carrier_on() function.
*/
NET_IF_NO_AUTO_START,
/** Power management specific: interface is being suspended */
NET_IF_SUSPENDED,
/** Flag defines if received multicasts of other interface are
* forwarded on this interface. This activates multicast
* routing / forwarding for this interface.
*/
NET_IF_FORWARD_MULTICASTS,
/** @cond INTERNAL_HIDDEN */
/* Total number of flags - must be at the end of the enum */
NET_IF_NUM_FLAGS
/** @endcond */
};
#if defined(CONFIG_NET_OFFLOAD)
struct net_offload;
#endif /* CONFIG_NET_OFFLOAD */
/** @cond INTERNAL_HIDDEN */
#if defined(CONFIG_NET_NATIVE_IPV6)
#define NET_IF_MAX_IPV6_ADDR CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT
#define NET_IF_MAX_IPV6_MADDR CONFIG_NET_IF_MCAST_IPV6_ADDR_COUNT
#define NET_IF_MAX_IPV6_PREFIX CONFIG_NET_IF_IPV6_PREFIX_COUNT
#else
#define NET_IF_MAX_IPV6_ADDR 0
#define NET_IF_MAX_IPV6_MADDR 0
#define NET_IF_MAX_IPV6_PREFIX 0
#endif
/* @endcond */
struct net_if_ipv6 {
/** Unicast IP addresses */
struct net_if_addr unicast[NET_IF_MAX_IPV6_ADDR];
/** Multicast IP addresses */
struct net_if_mcast_addr mcast[NET_IF_MAX_IPV6_MADDR];
/** Prefixes */
struct net_if_ipv6_prefix prefix[NET_IF_MAX_IPV6_PREFIX];
/** Default reachable time (RFC 4861, page 52) */
uint32_t base_reachable_time;
/** Reachable time (RFC 4861, page 20) */
uint32_t reachable_time;
/** Retransmit timer (RFC 4861, page 52) */
uint32_t retrans_timer;
#if defined(CONFIG_NET_IPV6_ND) && defined(CONFIG_NET_NATIVE_IPV6)
/** Router solicitation timer node */
sys_snode_t rs_node;
/* RS start time */
uint32_t rs_start;
/** RS count */
uint8_t rs_count;
#endif
/** IPv6 hop limit */
uint8_t hop_limit;
};
/** @cond INTERNAL_HIDDEN */
#if defined(CONFIG_NET_NATIVE_IPV4)
#define NET_IF_MAX_IPV4_ADDR CONFIG_NET_IF_UNICAST_IPV4_ADDR_COUNT
#define NET_IF_MAX_IPV4_MADDR CONFIG_NET_IF_MCAST_IPV4_ADDR_COUNT
#else
#define NET_IF_MAX_IPV4_ADDR 0
#define NET_IF_MAX_IPV4_MADDR 0
#endif
/** @endcond */
struct net_if_ipv4 {
/** Unicast IP addresses */
struct net_if_addr unicast[NET_IF_MAX_IPV4_ADDR];
/** Multicast IP addresses */
struct net_if_mcast_addr mcast[NET_IF_MAX_IPV4_MADDR];
/** Gateway */
struct in_addr gw;
/** Netmask */
struct in_addr netmask;
/** IPv4 time-to-live */
uint8_t ttl;
};
#if defined(CONFIG_NET_DHCPV4) && defined(CONFIG_NET_NATIVE_IPV4)
struct net_if_dhcpv4 {
/** Used for timer lists */
sys_snode_t node;
/** Timer start */
int64_t timer_start;
/** Time for INIT, DISCOVER, REQUESTING, RENEWAL */
uint32_t request_time;
uint32_t xid;
/** IP address Lease time */
uint32_t lease_time;
/** IP address Renewal time */
uint32_t renewal_time;
/** IP address Rebinding time */
uint32_t rebinding_time;
/** Server ID */
struct in_addr server_id;
/** Requested IP addr */
struct in_addr requested_ip;
/**
* DHCPv4 client state in the process of network
* address allocation.
*/
enum net_dhcpv4_state state;
/** Number of attempts made for REQUEST and RENEWAL messages */
uint8_t attempts;
};
#endif /* CONFIG_NET_DHCPV4 */
#if defined(CONFIG_NET_IPV4_AUTO) && defined(CONFIG_NET_NATIVE_IPV4)
struct net_if_ipv4_autoconf {
/** Used for timer lists */
sys_snode_t node;
/** Backpointer to correct network interface */
struct net_if *iface;
/** Timer start */
int64_t timer_start;
/** Time for INIT, DISCOVER, REQUESTING, RENEWAL */
uint32_t timer_timeout;
/** Current IP addr */
struct in_addr current_ip;
/** Requested IP addr */
struct in_addr requested_ip;
/** IPV4 Autoconf state in the process of network address allocation.
*/
enum net_ipv4_autoconf_state state;
/** Number of sent probe requests */
uint8_t probe_cnt;
/** Number of sent announcements */
uint8_t announce_cnt;
/** Incoming conflict count */
uint8_t conflict_cnt;
};
#endif /* CONFIG_NET_IPV4_AUTO */
/** @cond INTERNAL_HIDDEN */
/* We always need to have at least one IP config */
#define NET_IF_MAX_CONFIGS 1
/** @endcond */
/**
* @brief Network interface IP address configuration.
*/
struct net_if_ip {
#if defined(CONFIG_NET_NATIVE_IPV6)
struct net_if_ipv6 *ipv6;
#endif /* CONFIG_NET_IPV6 */
#if defined(CONFIG_NET_NATIVE_IPV4)
struct net_if_ipv4 *ipv4;
#endif /* CONFIG_NET_IPV4 */
};
/**
* @brief IP and other configuration related data for network interface.
*/
struct net_if_config {
/** IP address configuration setting */
struct net_if_ip ip;
#if defined(CONFIG_NET_DHCPV4) && defined(CONFIG_NET_NATIVE_IPV4)
struct net_if_dhcpv4 dhcpv4;
#endif /* CONFIG_NET_DHCPV4 */
#if defined(CONFIG_NET_IPV4_AUTO) && defined(CONFIG_NET_NATIVE_IPV4)
struct net_if_ipv4_autoconf ipv4auto;
#endif /* CONFIG_NET_IPV4_AUTO */
};
/**
* @brief Network traffic class.
*
* Traffic classes are used when sending or receiving data that is classified
* with different priorities. So some traffic can be marked as high priority
* and it will be sent or received first. There is always at least one work
* queue in the system for Rx and Tx. Each network packet that is transmitted
* or received goes through a work queue thread that will transmit it.
*/
struct net_traffic_class {
/** Work queue for handling this Tx or Rx packet */
struct k_work_q work_q;
/** Stack for this work queue */
k_thread_stack_t *stack;
/** Traffic class value */
int tc;
};
/**
* @brief Network Interface Device structure
*
* Used to handle a network interface on top of a device driver instance.
* There can be many net_if_dev instance against the same device.
*
* Such interface is mainly to be used by the link layer, but is also tight
* to a network context: it then makes the relation with a network context
* and the network device.
*
* Because of the strong relationship between a device driver and such
* network interface, each net_if_dev should be instantiated by
*/
struct net_if_dev {
/** The actually device driver instance the net_if is related to */
const struct device *dev;
/** Interface's L2 layer */
const struct net_l2 * const l2;
/** Interface's private L2 data pointer */
void *l2_data;
/* For internal use */
ATOMIC_DEFINE(flags, NET_IF_NUM_FLAGS);
/** The hardware link address */
struct net_linkaddr link_addr;
#if defined(CONFIG_NET_OFFLOAD)
/** TCP/IP Offload functions.
* If non-NULL, then the TCP/IP stack is located
* in the communication chip that is accessed via this
* network interface.
*/
struct net_offload *offload;
#endif /* CONFIG_NET_OFFLOAD */
/** The hardware MTU */
uint16_t mtu;
#if defined(CONFIG_NET_SOCKETS_OFFLOAD)
/** Indicate whether interface is offloaded at socket level. */
bool offloaded;
#endif /* CONFIG_NET_SOCKETS_OFFLOAD */
};
/**
* @brief Network Interface structure
*
* Used to handle a network interface on top of a net_if_dev instance.
* There can be many net_if instance against the same net_if_dev instance.
*
*/
struct net_if {
/** The net_if_dev instance the net_if is related to */
struct net_if_dev *if_dev;
#if defined(CONFIG_NET_STATISTICS_PER_INTERFACE)
/** Network statistics related to this network interface */
struct net_stats stats;
#endif /* CONFIG_NET_STATISTICS_PER_INTERFACE */
/** Network interface instance configuration */
struct net_if_config config;
#if defined(CONFIG_NET_POWER_MANAGEMENT)
/** Keep track of packets pending in traffic queues. This is
* needed to avoid putting network device driver to sleep if
* there are packets waiting to be sent.
*/
int tx_pending;
#endif
};
/**
* @brief Set a value in network interface flags
*
* @param iface Pointer to network interface
* @param value Flag value
*/
static inline void net_if_flag_set(struct net_if *iface,
enum net_if_flag value)
{
NET_ASSERT(iface);
atomic_set_bit(iface->if_dev->flags, value);
}
/**
* @brief Test and set a value in network interface flags
*
* @param iface Pointer to network interface
* @param value Flag value
*
* @return true if the bit was set, false if it wasn't.
*/
static inline bool net_if_flag_test_and_set(struct net_if *iface,
enum net_if_flag value)
{
NET_ASSERT(iface);
return atomic_test_and_set_bit(iface->if_dev->flags, value);
}
/**
* @brief Clear a value in network interface flags
*
* @param iface Pointer to network interface
* @param value Flag value
*/
static inline void net_if_flag_clear(struct net_if *iface,
enum net_if_flag value)
{
NET_ASSERT(iface);
atomic_clear_bit(iface->if_dev->flags, value);
}
/**
* @brief Check if a value in network interface flags is set
*
* @param iface Pointer to network interface
* @param value Flag value
*
* @return True if the value is set, false otherwise
*/
static inline bool net_if_flag_is_set(struct net_if *iface,
enum net_if_flag value)
{
NET_ASSERT(iface);
return atomic_test_bit(iface->if_dev->flags, value);
}
/**
* @brief Send a packet through a net iface
*
* @param iface Pointer to a network interface structure
* @param pkt Pointer to a net packet to send
*
* return verdict about the packet
*/
enum net_verdict net_if_send_data(struct net_if *iface, struct net_pkt *pkt);
/**
* @brief Get a pointer to the interface L2
*
* @param iface a valid pointer to a network interface structure
*
* @return a pointer to the iface L2
*/
static inline const struct net_l2 * const net_if_l2(struct net_if *iface)
{
if (!iface || !iface->if_dev) {
return NULL;
}
return iface->if_dev->l2;
}
/**
* @brief Input a packet through a net iface
*
* @param iface Pointer to a network interface structure
* @param pkt Pointer to a net packet to input
*
* @return verdict about the packet
*/
enum net_verdict net_if_recv_data(struct net_if *iface, struct net_pkt *pkt);
/**
* @brief Get a pointer to the interface L2 private data
*
* @param iface a valid pointer to a network interface structure
*
* @return a pointer to the iface L2 data
*/
static inline void *net_if_l2_data(struct net_if *iface)
{
return iface->if_dev->l2_data;
}
/**
* @brief Get an network interface's device
*
* @param iface Pointer to a network interface structure
*
* @return a pointer to the device driver instance
*/
static inline const struct device *net_if_get_device(struct net_if *iface)
{
return iface->if_dev->dev;
}
/**
* @brief Queue a packet to the net interface TX queue
*
* @param iface Pointer to a network interface structure
* @param pkt Pointer to a net packet to queue
*/
void net_if_queue_tx(struct net_if *iface, struct net_pkt *pkt);
/**
* @brief Return the IP offload status
*
* @param iface Network interface
*
* @return True if IP offlining is active, false otherwise.
*/
static inline bool net_if_is_ip_offloaded(struct net_if *iface)
{
#if defined(CONFIG_NET_OFFLOAD)
return (iface->if_dev->offload != NULL);
#else
ARG_UNUSED(iface);
return false;
#endif
}
/**
* @brief Return the IP offload plugin
*
* @param iface Network interface
*
* @return NULL if there is no offload plugin defined, valid pointer otherwise
*/
static inline struct net_offload *net_if_offload(struct net_if *iface)
{
#if defined(CONFIG_NET_OFFLOAD)
return iface->if_dev->offload;
#else
return NULL;
#endif
}
/**
* @brief Return the socket offload status
*
* @param iface Network interface
*
* @return True if socket offloading is active, false otherwise.
*/
static inline bool net_if_is_socket_offloaded(struct net_if *iface)
{
#if defined(CONFIG_NET_SOCKETS_OFFLOAD)
return iface->if_dev->offloaded;
#else
ARG_UNUSED(iface);
return false;
#endif
}
/**
* @brief Get an network interface's link address
*
* @param iface Pointer to a network interface structure
*
* @return a pointer to the network link address
*/
static inline struct net_linkaddr *net_if_get_link_addr(struct net_if *iface)
{
return &iface->if_dev->link_addr;
}
/**
* @brief Return network configuration for this network interface
*
* @param iface Pointer to a network interface structure
*
* @return Pointer to configuration
*/
static inline struct net_if_config *net_if_get_config(struct net_if *iface)
{
return &iface->config;
}
/**
* @brief Start duplicate address detection procedure.
*
* @param iface Pointer to a network interface structure
*/
#if defined(CONFIG_NET_IPV6_DAD) && defined(CONFIG_NET_NATIVE_IPV6)
void net_if_start_dad(struct net_if *iface);
#else
static inline void net_if_start_dad(struct net_if *iface)
{
ARG_UNUSED(iface);
}
#endif
/**
* @brief Start neighbor discovery and send router solicitation message.
*
* @param iface Pointer to a network interface structure
*/
void net_if_start_rs(struct net_if *iface);
/**
* @brief Stop neighbor discovery.
*
* @param iface Pointer to a network interface structure
*/
#if defined(CONFIG_NET_IPV6_ND) && defined(CONFIG_NET_NATIVE_IPV6)
void net_if_stop_rs(struct net_if *iface);
#else
static inline void net_if_stop_rs(struct net_if *iface)
{
ARG_UNUSED(iface);
}
#endif /* CONFIG_NET_IPV6_ND */
/**
* @brief Set a network interface's link address
*
* @param iface Pointer to a network interface structure
* @param addr A pointer to a uint8_t buffer representing the address.
* The buffer must remain valid throughout interface lifetime.
* @param len length of the address buffer
* @param type network bearer type of this link address
*
* @return 0 on success
*/
static inline int net_if_set_link_addr(struct net_if *iface,
uint8_t *addr, uint8_t len,
enum net_link_type type)
{
if (net_if_flag_is_set(iface, NET_IF_UP)) {
return -EPERM;
}
net_if_get_link_addr(iface)->addr = addr;
net_if_get_link_addr(iface)->len = len;
net_if_get_link_addr(iface)->type = type;
net_hostname_set_postfix(addr, len);
return 0;
}
/**
* @brief Get an network interface's MTU
*
* @param iface Pointer to a network interface structure
*
* @return the MTU
*/
static inline uint16_t net_if_get_mtu(struct net_if *iface)
{
return iface->if_dev->mtu;
}
/**
* @brief Set an network interface's MTU
*
* @param iface Pointer to a network interface structure
* @param mtu New MTU, note that we store only 16 bit mtu value.
*/
static inline void net_if_set_mtu(struct net_if *iface,
uint16_t mtu)
{
iface->if_dev->mtu = mtu;
}
/**
* @brief Set the infinite status of the network interface address
*
* @param ifaddr IP address for network interface
* @param is_infinite Infinite status
*/
static inline void net_if_addr_set_lf(struct net_if_addr *ifaddr,
bool is_infinite)
{
ifaddr->is_infinite = is_infinite;
}
/**
* @brief Get an interface according to link layer address.
*
* @param ll_addr Link layer address.
*
* @return Network interface or NULL if not found.
*/
struct net_if *net_if_get_by_link_addr(struct net_linkaddr *ll_addr);
/**
* @brief Find an interface from it's related device
*
* @param dev A valid struct device pointer to relate with an interface
*
* @return a valid struct net_if pointer on success, NULL otherwise
*/
struct net_if *net_if_lookup_by_dev(const struct device *dev);
/**
* @brief Get network interface IP config
*
* @param iface Interface to use.
*
* @return NULL if not found or pointer to correct config settings.
*/
static inline struct net_if_config *net_if_config_get(struct net_if *iface)
{
return &iface->config;
}
/**
* @brief Remove a router from the system
*
* @param router Pointer to existing router
*/
static inline void net_if_router_rm(struct net_if_router *router)
{
router->is_used = false;
/* FIXME - remove timer */
}
/**
* @brief Get the default network interface.
*
* @return Default interface or NULL if no interfaces are configured.
*/
struct net_if *net_if_get_default(void);
/**
* @brief Get the first network interface according to its type.
*
* @param l2 Layer 2 type of the network interface.
*
* @return First network interface of a given type or NULL if no such
* interfaces was found.
*/
struct net_if *net_if_get_first_by_type(const struct net_l2 *l2);
#if defined(CONFIG_NET_L2_IEEE802154)
/**
* @brief Get the first IEEE 802.15.4 network interface.
*
* @return First IEEE 802.15.4 network interface or NULL if no such
* interfaces was found.
*/
static inline struct net_if *net_if_get_ieee802154(void)
{
return net_if_get_first_by_type(&NET_L2_GET_NAME(IEEE802154));
}
#endif /* CONFIG_NET_L2_IEEE802154 */
/**
* @brief Allocate network interface IPv6 config.
*
* @details This function will allocate new IPv6 config.
*
* @param iface Interface to use.
* @param ipv6 Pointer to allocated IPv6 struct is returned to caller.
*
* @return 0 if ok, <0 if error
*/
int net_if_config_ipv6_get(struct net_if *iface,
struct net_if_ipv6 **ipv6);
/**
* @brief Release network interface IPv6 config.
*
* @param iface Interface to use.
*
* @return 0 if ok, <0 if error
*/
int net_if_config_ipv6_put(struct net_if *iface);
/**
* @brief Check if this IPv6 address belongs to one of the interfaces.
*
* @param addr IPv6 address
* @param iface Pointer to interface is returned
*
* @return Pointer to interface address, NULL if not found.
*/
struct net_if_addr *net_if_ipv6_addr_lookup(const struct in6_addr *addr,
struct net_if **iface);
/**
* @brief Check if this IPv6 address belongs to this specific interfaces.
*
* @param iface Network interface
* @param addr IPv6 address
*
* @return Pointer to interface address, NULL if not found.
*/
struct net_if_addr *net_if_ipv6_addr_lookup_by_iface(struct net_if *iface,
struct in6_addr *addr);
/**
* @brief Check if this IPv6 address belongs to one of the interface indices.
*
* @param addr IPv6 address
*
* @return >0 if address was found in given network interface index,
* all other values mean address was not found
*/
__syscall int net_if_ipv6_addr_lookup_by_index(const struct in6_addr *addr);
/**
* @brief Add a IPv6 address to an interface
*
* @param iface Network interface
* @param addr IPv6 address
* @param addr_type IPv6 address type
* @param vlifetime Validity time for this address
*
* @return Pointer to interface address, NULL if cannot be added
*/
struct net_if_addr *net_if_ipv6_addr_add(struct net_if *iface,
struct in6_addr *addr,
enum net_addr_type addr_type,
uint32_t vlifetime);
/**
* @brief Add a IPv6 address to an interface by index
*
* @param index Network interface index
* @param addr IPv6 address
* @param addr_type IPv6 address type
* @param vlifetime Validity time for this address
*
* @return True if ok, false if address could not be added
*/
__syscall bool net_if_ipv6_addr_add_by_index(int index,
struct in6_addr *addr,
enum net_addr_type addr_type,
uint32_t vlifetime);
/**
* @brief Update validity lifetime time of an IPv6 address.
*
* @param ifaddr Network IPv6 address
* @param vlifetime Validity time for this address
*/
void net_if_ipv6_addr_update_lifetime(struct net_if_addr *ifaddr,
uint32_t vlifetime);
/**
* @brief Remove an IPv6 address from an interface
*
* @param iface Network interface
* @param addr IPv6 address
*
* @return True if successfully removed, false otherwise
*/
bool net_if_ipv6_addr_rm(struct net_if *iface, const struct in6_addr *addr);
/**
* @brief Remove an IPv6 address from an interface by index
*
* @param index Network interface index
* @param addr IPv6 address
*
* @return True if successfully removed, false otherwise
*/
__syscall bool net_if_ipv6_addr_rm_by_index(int index,
const struct in6_addr *addr);
/**
* @brief Add a IPv6 multicast address to an interface
*
* @param iface Network interface
* @param addr IPv6 multicast address
*
* @return Pointer to interface multicast address, NULL if cannot be added
*/
struct net_if_mcast_addr *net_if_ipv6_maddr_add(struct net_if *iface,
const struct in6_addr *addr);
/**
* @brief Remove an IPv6 multicast address from an interface
*
* @param iface Network interface
* @param addr IPv6 multicast address
*
* @return True if successfully removed, false otherwise
*/
bool net_if_ipv6_maddr_rm(struct net_if *iface, const struct in6_addr *addr);
/**
* @brief Check if this IPv6 multicast address belongs to a specific interface
* or one of the interfaces.
*
* @param addr IPv6 address
* @param iface If *iface is null, then pointer to interface is returned,
* otherwise the *iface value needs to be matched.
*
* @return Pointer to interface multicast address, NULL if not found.
*/
struct net_if_mcast_addr *net_if_ipv6_maddr_lookup(const struct in6_addr *addr,
struct net_if **iface);
/**
* @typedef net_if_mcast_callback_t
* @brief Define callback that is called whenever IPv6 multicast address group
* is joined or left.
* @param "struct net_if *iface" A pointer to a struct net_if to which the
* multicast address is attached.
* @param "const struct in6_addr *addr" IPv6 multicast address.
* @param "bool is_joined" True if the address is joined, false if left.
*/
typedef void (*net_if_mcast_callback_t)(struct net_if *iface,
const struct in6_addr *addr,
bool is_joined);
/**
* @brief Multicast monitor handler struct.
*
* Stores the multicast callback information. Caller must make sure that
* the variable pointed by this is valid during the lifetime of
* registration. Typically this means that the variable cannot be
* allocated from stack.
*/
struct net_if_mcast_monitor {
/** Node information for the slist. */
sys_snode_t node;
/** Network interface */
struct net_if *iface;
/** Multicast callback */
net_if_mcast_callback_t cb;
};
/**
* @brief Register a multicast monitor
*
* @param mon Monitor handle. This is a pointer to a monitor storage structure
* which should be allocated by caller, but does not need to be initialized.
* @param iface Network interface
* @param cb Monitor callback
*/
void net_if_mcast_mon_register(struct net_if_mcast_monitor *mon,
struct net_if *iface,
net_if_mcast_callback_t cb);
/**
* @brief Unregister a multicast monitor
*
* @param mon Monitor handle
*/
void net_if_mcast_mon_unregister(struct net_if_mcast_monitor *mon);
/**
* @brief Call registered multicast monitors
*
* @param iface Network interface
* @param addr Multicast address
* @param is_joined Is this multicast address joined (true) or not (false)
*/
void net_if_mcast_monitor(struct net_if *iface, const struct in6_addr *addr,
bool is_joined);
/**
* @brief Mark a given multicast address to be joined.
*
* @param addr IPv6 multicast address
*/
static inline void net_if_ipv6_maddr_join(struct net_if_mcast_addr *addr)
{
NET_ASSERT(addr);
addr->is_joined = true;
}
/**
* @brief Check if given multicast address is joined or not.
*
* @param addr IPv6 multicast address
*
* @return True if address is joined, False otherwise.
*/
static inline bool net_if_ipv6_maddr_is_joined(struct net_if_mcast_addr *addr)
{
NET_ASSERT(addr);
return addr->is_joined;
}
/**
* @brief Mark a given multicast address to be left.
*
* @param addr IPv6 multicast address
*/
static inline void net_if_ipv6_maddr_leave(struct net_if_mcast_addr *addr)
{
NET_ASSERT(addr);
addr->is_joined = false;
}
/**
* @brief Return prefix that corresponds to this IPv6 address.
*
* @param iface Network interface
* @param addr IPv6 address
*
* @return Pointer to prefix, NULL if not found.
*/
struct net_if_ipv6_prefix *net_if_ipv6_prefix_get(struct net_if *iface,
struct in6_addr *addr);
/**
* @brief Check if this IPv6 prefix belongs to this interface
*
* @param iface Network interface
* @param addr IPv6 address
* @param len Prefix length
*
* @return Pointer to prefix, NULL if not found.
*/
struct net_if_ipv6_prefix *net_if_ipv6_prefix_lookup(struct net_if *iface,
struct in6_addr *addr,
uint8_t len);
/**
* @brief Add a IPv6 prefix to an network interface.
*
* @param iface Network interface
* @param prefix IPv6 address
* @param len Prefix length
* @param lifetime Prefix lifetime in seconds
*
* @return Pointer to prefix, NULL if the prefix was not added.
*/
struct net_if_ipv6_prefix *net_if_ipv6_prefix_add(struct net_if *iface,
struct in6_addr *prefix,
uint8_t len,
uint32_t lifetime);
/**
* @brief Remove an IPv6 prefix from an interface
*
* @param iface Network interface
* @param addr IPv6 prefix address
* @param len Prefix length
*
* @return True if successfully removed, false otherwise
*/
bool net_if_ipv6_prefix_rm(struct net_if *iface, struct in6_addr *addr,
uint8_t len);
/**
* @brief Set the infinite status of the prefix
*
* @param prefix IPv6 address
* @param is_infinite Infinite status
*/
static inline void net_if_ipv6_prefix_set_lf(struct net_if_ipv6_prefix *prefix,
bool is_infinite)
{
prefix->is_infinite = is_infinite;
}
/**
* @brief Set the prefix lifetime timer.
*
* @param prefix IPv6 address
* @param lifetime Prefix lifetime in seconds
*/
void net_if_ipv6_prefix_set_timer(struct net_if_ipv6_prefix *prefix,
uint32_t lifetime);
/**
* @brief Unset the prefix lifetime timer.
*
* @param prefix IPv6 address
*/
void net_if_ipv6_prefix_unset_timer(struct net_if_ipv6_prefix *prefix);
/**
* @brief Check if this IPv6 address is part of the subnet of our
* network interface.
*
* @param iface Network interface. This is returned to the caller.
* The iface can be NULL in which case we check all the interfaces.
* @param addr IPv6 address
*
* @return True if address is part of our subnet, false otherwise
*/
bool net_if_ipv6_addr_onlink(struct net_if **iface, struct in6_addr *addr);
/**
* @brief Get the IPv6 address of the given router
* @param router a network router
*
* @return pointer to the IPv6 address, or NULL if none
*/
#if defined(CONFIG_NET_NATIVE_IPV6)
static inline struct in6_addr *net_if_router_ipv6(struct net_if_router *router)
{
return &router->address.in6_addr;
}
#else
static inline struct in6_addr *net_if_router_ipv6(struct net_if_router *router)
{
static struct in6_addr addr;
ARG_UNUSED(router);
return &addr;
}
#endif
/**
* @brief Check if IPv6 address is one of the routers configured
* in the system.
*
* @param iface Network interface
* @param addr IPv6 address
*
* @return Pointer to router information, NULL if cannot be found
*/
struct net_if_router *net_if_ipv6_router_lookup(struct net_if *iface,
struct in6_addr *addr);
/**
* @brief Find default router for this IPv6 address.
*
* @param iface Network interface. This can be NULL in which case we
* go through all the network interfaces to find a suitable router.
* @param addr IPv6 address
*
* @return Pointer to router information, NULL if cannot be found
*/
struct net_if_router *net_if_ipv6_router_find_default(struct net_if *iface,
struct in6_addr *addr);
/**
* @brief Update validity lifetime time of a router.
*
* @param router Network IPv6 address
* @param lifetime Lifetime of this router.
*/
void net_if_ipv6_router_update_lifetime(struct net_if_router *router,
uint16_t lifetime);
/**
* @brief Add IPv6 router to the system.
*
* @param iface Network interface
* @param addr IPv6 address
* @param router_lifetime Lifetime of the router
*
* @return Pointer to router information, NULL if could not be added
*/
struct net_if_router *net_if_ipv6_router_add(struct net_if *iface,
struct in6_addr *addr,
uint16_t router_lifetime);
/**
* @brief Remove IPv6 router from the system.
*
* @param router Router information.
*
* @return True if successfully removed, false otherwise
*/
bool net_if_ipv6_router_rm(struct net_if_router *router);
/**
* @brief Get IPv6 hop limit specified for a given interface. This is the
* default value but can be overridden by the user.
*
* @param iface Network interface
*
* @return Hop limit
*/
static inline uint8_t net_if_ipv6_get_hop_limit(struct net_if *iface)
{
#if defined(CONFIG_NET_NATIVE_IPV6)
if (!iface->config.ip.ipv6) {
return 0;
}
return iface->config.ip.ipv6->hop_limit;
#else
return 0;
#endif
}
/**
* @brief Set the default IPv6 hop limit of a given interface.
*
* @param iface Network interface
* @param hop_limit New hop limit
*/
static inline void net_ipv6_set_hop_limit(struct net_if *iface,
uint8_t hop_limit)
{
#if defined(CONFIG_NET_NATIVE_IPV6)
if (!iface->config.ip.ipv6) {
return;
}
iface->config.ip.ipv6->hop_limit = hop_limit;
#endif
}
/**
* @brief Set IPv6 reachable time for a given interface
*
* @param iface Network interface
* @param reachable_time New reachable time
*/
static inline void net_if_ipv6_set_base_reachable_time(struct net_if *iface,
uint32_t reachable_time)
{
#if defined(CONFIG_NET_NATIVE_IPV6)
if (!iface->config.ip.ipv6) {
return;
}
iface->config.ip.ipv6->base_reachable_time = reachable_time;
#endif
}
/**
* @brief Get IPv6 reachable timeout specified for a given interface
*
* @param iface Network interface
*
* @return Reachable timeout
*/
static inline uint32_t net_if_ipv6_get_reachable_time(struct net_if *iface)
{
#if defined(CONFIG_NET_NATIVE_IPV6)
if (!iface->config.ip.ipv6) {
return 0;
}
return iface->config.ip.ipv6->reachable_time;
#else
return 0;
#endif
}
/**
* @brief Calculate next reachable time value for IPv6 reachable time
*
* @param ipv6 IPv6 address configuration
*
* @return Reachable time
*/
uint32_t net_if_ipv6_calc_reachable_time(struct net_if_ipv6 *ipv6);
/**
* @brief Set IPv6 reachable time for a given interface. This requires
* that base reachable time is set for the interface.
*
* @param ipv6 IPv6 address configuration
*/
static inline void net_if_ipv6_set_reachable_time(struct net_if_ipv6 *ipv6)
{
#if defined(CONFIG_NET_NATIVE_IPV6)
ipv6->reachable_time = net_if_ipv6_calc_reachable_time(ipv6);
#endif
}
/**
* @brief Set IPv6 retransmit timer for a given interface
*
* @param iface Network interface
* @param retrans_timer New retransmit timer
*/
static inline void net_if_ipv6_set_retrans_timer(struct net_if *iface,
uint32_t retrans_timer)
{
#if defined(CONFIG_NET_NATIVE_IPV6)
if (!iface->config.ip.ipv6) {
return;
}
iface->config.ip.ipv6->retrans_timer = retrans_timer;
#endif
}
/**
* @brief Get IPv6 retransmit timer specified for a given interface
*
* @param iface Network interface
*
* @return Retransmit timer
*/
static inline uint32_t net_if_ipv6_get_retrans_timer(struct net_if *iface)
{
#if defined(CONFIG_NET_NATIVE_IPV6)
if (!iface->config.ip.ipv6) {
return 0;
}
return iface->config.ip.ipv6->retrans_timer;
#else
return 0;
#endif
}
/**
* @brief Get a IPv6 source address that should be used when sending
* network data to destination.
*
* @param iface Interface that was used when packet was received.
* If the interface is not known, then NULL can be given.
* @param dst IPv6 destination address
*
* @return Pointer to IPv6 address to use, NULL if no IPv6 address
* could be found.
*/
#if defined(CONFIG_NET_NATIVE_IPV6)
const struct in6_addr *net_if_ipv6_select_src_addr(struct net_if *iface,
const struct in6_addr *dst);
#else
static inline const struct in6_addr *net_if_ipv6_select_src_addr(
struct net_if *iface, const struct in6_addr *dst)
{
ARG_UNUSED(iface);
ARG_UNUSED(dst);
return NULL;
}
#endif
/**
* @brief Get a network interface that should be used when sending
* IPv6 network data to destination.
*
* @param dst IPv6 destination address
*
* @return Pointer to network interface to use, NULL if no suitable interface
* could be found.
*/
#if defined(CONFIG_NET_NATIVE_IPV6)
struct net_if *net_if_ipv6_select_src_iface(const struct in6_addr *dst);
#else
static inline struct net_if *net_if_ipv6_select_src_iface(
const struct in6_addr *dst)
{
ARG_UNUSED(dst);
return NULL;
}
#endif
/**
* @brief Get a IPv6 link local address in a given state.
*
* @param iface Interface to use. Must be a valid pointer to an interface.
* @param addr_state IPv6 address state (preferred, tentative, deprecated)
*
* @return Pointer to link local IPv6 address, NULL if no proper IPv6 address
* could be found.
*/
struct in6_addr *net_if_ipv6_get_ll(struct net_if *iface,
enum net_addr_state addr_state);
/**
* @brief Return link local IPv6 address from the first interface that has
* a link local address matching give state.
*
* @param state IPv6 address state (ANY, TENTATIVE, PREFERRED, DEPRECATED)
* @param iface Pointer to interface is returned
*
* @return Pointer to IPv6 address, NULL if not found.
*/
struct in6_addr *net_if_ipv6_get_ll_addr(enum net_addr_state state,
struct net_if **iface);
/**
* @brief Stop IPv6 Duplicate Address Detection (DAD) procedure if
* we find out that our IPv6 address is already in use.
*
* @param iface Interface where the DAD was running.
* @param addr IPv6 address that failed DAD
*/
void net_if_ipv6_dad_failed(struct net_if *iface, const struct in6_addr *addr);
/**
* @brief Return global IPv6 address from the first interface that has
* a global IPv6 address matching the given state.
*
* @param state IPv6 address state (ANY, TENTATIVE, PREFERRED, DEPRECATED)
* @param iface Caller can give an interface to check. If iface is set to NULL,
* then all the interfaces are checked. Pointer to interface where the IPv6
* address is defined is returned to the caller.
*
* @return Pointer to IPv6 address, NULL if not found.
*/
struct in6_addr *net_if_ipv6_get_global_addr(enum net_addr_state state,
struct net_if **iface);
/**
* @brief Allocate network interface IPv4 config.
*
* @details This function will allocate new IPv4 config.
*
* @param iface Interface to use.
* @param ipv4 Pointer to allocated IPv4 struct is returned to caller.
*
* @return 0 if ok, <0 if error
*/
int net_if_config_ipv4_get(struct net_if *iface,
struct net_if_ipv4 **ipv4);
/**
* @brief Release network interface IPv4 config.
*
* @param iface Interface to use.
*
* @return 0 if ok, <0 if error
*/
int net_if_config_ipv4_put(struct net_if *iface);
/**
* @brief Get IPv4 time-to-live value specified for a given interface
*
* @param iface Network interface
*
* @return Time-to-live
*/
static inline uint8_t net_if_ipv4_get_ttl(struct net_if *iface)
{
#if defined(CONFIG_NET_NATIVE_IPV4)
if (!iface->config.ip.ipv4) {
return 0;
}
return iface->config.ip.ipv4->ttl;
#else
return 0;
#endif
}
/**
* @brief Check if this IPv4 address belongs to one of the interfaces.
*
* @param addr IPv4 address
* @param iface Interface is returned
*
* @return Pointer to interface address, NULL if not found.
*/
struct net_if_addr *net_if_ipv4_addr_lookup(const struct in_addr *addr,
struct net_if **iface);
/**
* @brief Add a IPv4 address to an interface
*
* @param iface Network interface
* @param addr IPv4 address
* @param addr_type IPv4 address type
* @param vlifetime Validity time for this address
*
* @return Pointer to interface address, NULL if cannot be added
*/
struct net_if_addr *net_if_ipv4_addr_add(struct net_if *iface,
struct in_addr *addr,
enum net_addr_type addr_type,
uint32_t vlifetime);
/**
* @brief Remove a IPv4 address from an interface
*
* @param iface Network interface
* @param addr IPv4 address
*
* @return True if successfully removed, false otherwise
*/
bool net_if_ipv4_addr_rm(struct net_if *iface, const struct in_addr *addr);
/**
* @brief Check if this IPv4 address belongs to one of the interface indices.
*
* @param addr IPv4 address
*
* @return >0 if address was found in given network interface index,
* all other values mean address was not found
*/
__syscall int net_if_ipv4_addr_lookup_by_index(const struct in_addr *addr);
/**
* @brief Add a IPv4 address to an interface by network interface index
*
* @param index Network interface index
* @param addr IPv4 address
* @param addr_type IPv4 address type
* @param vlifetime Validity time for this address
*
* @return True if ok, false if the address could not be added
*/
__syscall bool net_if_ipv4_addr_add_by_index(int index,
struct in_addr *addr,
enum net_addr_type addr_type,
uint32_t vlifetime);
/**
* @brief Remove a IPv4 address from an interface by interface index
*
* @param index Network interface index
* @param addr IPv4 address
*
* @return True if successfully removed, false otherwise
*/
__syscall bool net_if_ipv4_addr_rm_by_index(int index,
const struct in_addr *addr);
/**
* @brief Add a IPv4 multicast address to an interface
*
* @param iface Network interface
* @param addr IPv4 multicast address
*
* @return Pointer to interface multicast address, NULL if cannot be added
*/
struct net_if_mcast_addr *net_if_ipv4_maddr_add(struct net_if *iface,
const struct in_addr *addr);
/**
* @brief Remove an IPv4 multicast address from an interface
*
* @param iface Network interface
* @param addr IPv4 multicast address
*
* @return True if successfully removed, false otherwise
*/
bool net_if_ipv4_maddr_rm(struct net_if *iface, const struct in_addr *addr);
/**
* @brief Check if this IPv4 multicast address belongs to a specific interface
* or one of the interfaces.
*
* @param addr IPv4 address
* @param iface If *iface is null, then pointer to interface is returned,
* otherwise the *iface value needs to be matched.
*
* @return Pointer to interface multicast address, NULL if not found.
*/
struct net_if_mcast_addr *net_if_ipv4_maddr_lookup(const struct in_addr *addr,
struct net_if **iface);
/**
* @brief Get the IPv4 address of the given router
* @param router a network router
*
* @return pointer to the IPv4 address, or NULL if none
*/
#if defined(CONFIG_NET_NATIVE_IPV4)
static inline struct in_addr *net_if_router_ipv4(struct net_if_router *router)
{
return &router->address.in_addr;
}
#else
static inline struct in_addr *net_if_router_ipv4(struct net_if_router *router)
{
static struct in_addr addr;
ARG_UNUSED(router);
return &addr;
}
#endif
/**
* @brief Check if IPv4 address is one of the routers configured
* in the system.
*
* @param iface Network interface
* @param addr IPv4 address
*
* @return Pointer to router information, NULL if cannot be found
*/
struct net_if_router *net_if_ipv4_router_lookup(struct net_if *iface,
struct in_addr *addr);
/**
* @brief Find default router for this IPv4 address.
*
* @param iface Network interface. This can be NULL in which case we
* go through all the network interfaces to find a suitable router.
* @param addr IPv4 address
*
* @return Pointer to router information, NULL if cannot be found
*/
struct net_if_router *net_if_ipv4_router_find_default(struct net_if *iface,
struct in_addr *addr);
/**
* @brief Add IPv4 router to the system.
*
* @param iface Network interface
* @param addr IPv4 address
* @param is_default Is this router the default one
* @param router_lifetime Lifetime of the router
*
* @return Pointer to router information, NULL if could not be added
*/
struct net_if_router *net_if_ipv4_router_add(struct net_if *iface,
struct in_addr *addr,
bool is_default,
uint16_t router_lifetime);
/**
* @brief Remove IPv4 router from the system.
*
* @param router Router information.
*
* @return True if successfully removed, false otherwise
*/
bool net_if_ipv4_router_rm(struct net_if_router *router);
/**
* @brief Check if the given IPv4 address belongs to local subnet.
*
* @param iface Interface to use. Must be a valid pointer to an interface.
* @param addr IPv4 address
*
* @return True if address is part of local subnet, false otherwise.
*/
bool net_if_ipv4_addr_mask_cmp(struct net_if *iface,
const struct in_addr *addr);
/**
* @brief Check if the given IPv4 address is a broadcast address.
*
* @param iface Interface to use. Must be a valid pointer to an interface.
* @param addr IPv4 address, this should be in network byte order
*
* @return True if address is a broadcast address, false otherwise.
*/
bool net_if_ipv4_is_addr_bcast(struct net_if *iface,
const struct in_addr *addr);
/**
* @brief Get a network interface that should be used when sending
* IPv4 network data to destination.
*
* @param dst IPv4 destination address
*
* @return Pointer to network interface to use, NULL if no suitable interface
* could be found.
*/
#if defined(CONFIG_NET_NATIVE_IPV4)
struct net_if *net_if_ipv4_select_src_iface(const struct in_addr *dst);
#else
static inline struct net_if *net_if_ipv4_select_src_iface(
const struct in_addr *dst)
{
ARG_UNUSED(dst);
return NULL;
}
#endif
/**
* @brief Get a IPv4 source address that should be used when sending
* network data to destination.
*
* @param iface Interface to use when sending the packet.
* If the interface is not known, then NULL can be given.
* @param dst IPv4 destination address
*
* @return Pointer to IPv4 address to use, NULL if no IPv4 address
* could be found.
*/
#if defined(CONFIG_NET_NATIVE_IPV4)
const struct in_addr *net_if_ipv4_select_src_addr(struct net_if *iface,
const struct in_addr *dst);
#else
static inline const struct in_addr *net_if_ipv4_select_src_addr(
struct net_if *iface, const struct in_addr *dst)
{
ARG_UNUSED(iface);
ARG_UNUSED(dst);
return NULL;
}
#endif
/**
* @brief Get a IPv4 link local address in a given state.
*
* @param iface Interface to use. Must be a valid pointer to an interface.
* @param addr_state IPv4 address state (preferred, tentative, deprecated)
*
* @return Pointer to link local IPv4 address, NULL if no proper IPv4 address
* could be found.
*/
struct in_addr *net_if_ipv4_get_ll(struct net_if *iface,
enum net_addr_state addr_state);
/**
* @brief Get a IPv4 global address in a given state.
*
* @param iface Interface to use. Must be a valid pointer to an interface.
* @param addr_state IPv4 address state (preferred, tentative, deprecated)
*
* @return Pointer to link local IPv4 address, NULL if no proper IPv4 address
* could be found.
*/
struct in_addr *net_if_ipv4_get_global_addr(struct net_if *iface,
enum net_addr_state addr_state);
/**
* @brief Set IPv4 netmask for an interface.
*
* @param iface Interface to use.
* @param netmask IPv4 netmask
*/
void net_if_ipv4_set_netmask(struct net_if *iface,
const struct in_addr *netmask);
/**
* @brief Set IPv4 netmask for an interface index.
*
* @param index Network interface index
* @param netmask IPv4 netmask
*
* @return True if netmask was added, false otherwise.
*/
__syscall bool net_if_ipv4_set_netmask_by_index(int index,
const struct in_addr *netmask);
/**
* @brief Set IPv4 gateway for an interface.
*
* @param iface Interface to use.
* @param gw IPv4 address of an gateway
*/
void net_if_ipv4_set_gw(struct net_if *iface, const struct in_addr *gw);
/**
* @brief Set IPv4 gateway for an interface index.
*
* @param index Network interface index
* @param gw IPv4 address of an gateway
*
* @return True if gateway was added, false otherwise.
*/
__syscall bool net_if_ipv4_set_gw_by_index(int index, const struct in_addr *gw);
/**
* @brief Get a network interface that should be used when sending
* IPv6 or IPv4 network data to destination.
*
* @param dst IPv6 or IPv4 destination address
*
* @return Pointer to network interface to use. Note that the function
* will return the default network interface if the best network interface
* is not found.
*/
struct net_if *net_if_select_src_iface(const struct sockaddr *dst);
/**
* @typedef net_if_link_callback_t
* @brief Define callback that is called after a network packet
* has been sent.
* @param "struct net_if *iface" A pointer to a struct net_if to which the
* the net_pkt was sent to.
* @param "struct net_linkaddr *dst" Link layer address of the destination
* where the network packet was sent.
* @param "int status" Send status, 0 is ok, < 0 error.
*/
typedef void (*net_if_link_callback_t)(struct net_if *iface,
struct net_linkaddr *dst,
int status);
/**
* @brief Link callback handler struct.
*
* Stores the link callback information. Caller must make sure that
* the variable pointed by this is valid during the lifetime of
* registration. Typically this means that the variable cannot be
* allocated from stack.
*/
struct net_if_link_cb {
/** Node information for the slist. */
sys_snode_t node;
/** Link callback */
net_if_link_callback_t cb;
};
/**
* @brief Register a link callback.
*
* @param link Caller specified handler for the callback.
* @param cb Callback to register.
*/
void net_if_register_link_cb(struct net_if_link_cb *link,
net_if_link_callback_t cb);
/**
* @brief Unregister a link callback.
*
* @param link Caller specified handler for the callback.
*/
void net_if_unregister_link_cb(struct net_if_link_cb *link);
/**
* @brief Call a link callback function.
*
* @param iface Network interface.
* @param lladdr Destination link layer address
* @param status 0 is ok, < 0 error
*/
void net_if_call_link_cb(struct net_if *iface, struct net_linkaddr *lladdr,
int status);
/**
* @brief Check if received network packet checksum calculation can be avoided
* or not. For example many ethernet devices support network packet offloading
* in which case the IP stack does not need to calculate the checksum.
*
* @param iface Network interface
*
* @return True if checksum needs to be calculated, false otherwise.
*/
bool net_if_need_calc_rx_checksum(struct net_if *iface);
/**
* @brief Check if network packet checksum calculation can be avoided or not
* when sending the packet. For example many ethernet devices support network
* packet offloading in which case the IP stack does not need to calculate the
* checksum.
*
* @param iface Network interface
*
* @return True if checksum needs to be calculated, false otherwise.
*/
bool net_if_need_calc_tx_checksum(struct net_if *iface);
/**
* @brief Get interface according to index
*
* @details This is a syscall only to provide access to the object for purposes
* of assigning permissions.
*
* @param index Interface index
*
* @return Pointer to interface or NULL if not found.
*/
__syscall struct net_if *net_if_get_by_index(int index);
/**
* @brief Get interface index according to pointer
*
* @param iface Pointer to network interface
*
* @return Interface index
*/
int net_if_get_by_iface(struct net_if *iface);
/**
* @typedef net_if_cb_t
* @brief Callback used while iterating over network interfaces
*
* @param iface Pointer to current network interface
* @param user_data A valid pointer to user data or NULL
*/
typedef void (*net_if_cb_t)(struct net_if *iface, void *user_data);
/**
* @brief Go through all the network interfaces and call callback
* for each interface.
*
* @param cb User-supplied callback function to call
* @param user_data User specified 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 Check if interface is up.
*
* @param iface Pointer to network interface
*
* @return True if interface is up, False if it is down.
*/
static inline bool net_if_is_up(struct net_if *iface)
{
NET_ASSERT(iface);
return net_if_flag_is_set(iface, NET_IF_UP);
}
/**
* @brief Bring interface down
*
* @param iface Pointer to network interface
*
* @return 0 on success
*/
int net_if_down(struct net_if *iface);
#if defined(CONFIG_NET_PKT_TIMESTAMP) && defined(CONFIG_NET_NATIVE)
/**
* @typedef net_if_timestamp_callback_t
* @brief Define callback that is called after a network packet
* has been timestamped.
* @param "struct net_pkt *pkt" A pointer on a struct net_pkt which has
* been timestamped after being sent.
*/
typedef void (*net_if_timestamp_callback_t)(struct net_pkt *pkt);
/**
* @brief Timestamp callback handler struct.
*
* Stores the timestamp callback information. Caller must make sure that
* the variable pointed by this is valid during the lifetime of
* registration. Typically this means that the variable cannot be
* allocated from stack.
*/
struct net_if_timestamp_cb {
/** Node information for the slist. */
sys_snode_t node;
/** Packet for which the callback is needed.
* A NULL value means all packets.
*/
struct net_pkt *pkt;
/** Net interface for which the callback is needed.
* A NULL value means all interfaces.
*/
struct net_if *iface;
/** Timestamp callback */
net_if_timestamp_callback_t cb;
};
/**
* @brief Register a timestamp callback.
*
* @param handle Caller specified handler for the callback.
* @param pkt Net packet for which the callback is registered. NULL for all
* packets.
* @param iface Net interface for which the callback is. NULL for all
* interfaces.
* @param cb Callback to register.
*/
void net_if_register_timestamp_cb(struct net_if_timestamp_cb *handle,
struct net_pkt *pkt,
struct net_if *iface,
net_if_timestamp_callback_t cb);
/**
* @brief Unregister a timestamp callback.
*
* @param handle Caller specified handler for the callback.
*/
void net_if_unregister_timestamp_cb(struct net_if_timestamp_cb *handle);
/**
* @brief Call a timestamp callback function.
*
* @param pkt Network buffer.
*/
void net_if_call_timestamp_cb(struct net_pkt *pkt);
/*
* @brief Add timestamped TX buffer to be handled
*
* @param pkt Timestamped buffer
*/
void net_if_add_tx_timestamp(struct net_pkt *pkt);
#endif /* CONFIG_NET_PKT_TIMESTAMP */
/**
* @brief Set network interface into promiscuous mode
*
* @details Note that not all network technologies will support this.
*
* @param iface Pointer to network interface
*
* @return 0 on success, <0 if error
*/
int net_if_set_promisc(struct net_if *iface);
/**
* @brief Set network interface into normal mode
*
* @param iface Pointer to network interface
*/
void net_if_unset_promisc(struct net_if *iface);
/**
* @brief Check if promiscuous mode is set or not.
*
* @param iface Pointer to network interface
*
* @return True if interface is in promisc mode,
* False if interface is not in in promiscuous mode.
*/
bool net_if_is_promisc(struct net_if *iface);
/**
* @brief Check if there are any pending TX network data for a given network
* interface.
*
* @param iface Pointer to network interface
*
* @return True if there are pending TX network packets for this network
* interface, False otherwise.
*/
static inline bool net_if_are_pending_tx_packets(struct net_if *iface)
{
#if defined(CONFIG_NET_POWER_MANAGEMENT)
return !!iface->tx_pending;
#else
ARG_UNUSED(iface);
return false;
#endif
}
#ifdef CONFIG_NET_POWER_MANAGEMENT
/**
* @brief Suspend a network interface from a power management perspective
*
* @param iface Pointer to network interface
*
* @return 0 on success, or -EALREADY/-EBUSY as possible errors.
*/
int net_if_suspend(struct net_if *iface);
/**
* @brief Resume a network interface from a power management perspective
*
* @param iface Pointer to network interface
*
* @return 0 on success, or -EALREADY as a possible error.
*/
int net_if_resume(struct net_if *iface);
/**
* @brief Check if the network interface is suspended or not.
*
* @param iface Pointer to network interface
*
* @return True if interface is suspended, False otherwise.
*/
bool net_if_is_suspended(struct net_if *iface);
#endif /* CONFIG_NET_POWER_MANAGEMENT */
/** @cond INTERNAL_HIDDEN */
struct net_if_api {
void (*init)(struct net_if *iface);
};
#if defined(CONFIG_NET_DHCPV4) && defined(CONFIG_NET_NATIVE_IPV4)
#define NET_IF_DHCPV4_INIT .dhcpv4.state = NET_DHCPV4_DISABLED,
#else
#define NET_IF_DHCPV4_INIT
#endif
#define NET_IF_CONFIG_INIT \
.config = { \
.ip = { \
}, \
NET_IF_DHCPV4_INIT \
}
#define NET_IF_GET_NAME(dev_name, sfx) __net_if_##dev_name##_##sfx
#define NET_IF_DEV_GET_NAME(dev_name, sfx) __net_if_dev_##dev_name##_##sfx
#define NET_IF_GET(dev_name, sfx) \
((struct net_if *)&NET_IF_GET_NAME(dev_name, sfx))
#define NET_IF_INIT(dev_name, sfx, _l2, _mtu, _num_configs) \
static Z_STRUCT_SECTION_ITERABLE(net_if_dev, \
NET_IF_DEV_GET_NAME(dev_name, sfx)) = { \
.dev = &(DEVICE_NAME_GET(dev_name)), \
.l2 = &(NET_L2_GET_NAME(_l2)), \
.l2_data = &(NET_L2_GET_DATA(dev_name, sfx)), \
.mtu = _mtu, \
}; \
static Z_DECL_ALIGN(struct net_if) \
NET_IF_GET_NAME(dev_name, sfx)[_num_configs] \
__used __in_section(_net_if, static, net_if) = { \
[0 ... (_num_configs - 1)] = { \
.if_dev = &(NET_IF_DEV_GET_NAME(dev_name, sfx)), \
NET_IF_CONFIG_INIT \
} \
}
#define NET_IF_OFFLOAD_INIT(dev_name, sfx, _mtu) \
static Z_STRUCT_SECTION_ITERABLE(net_if_dev, \
NET_IF_DEV_GET_NAME(dev_name, sfx)) = { \
.dev = &(DEVICE_NAME_GET(dev_name)), \
.mtu = _mtu, \
}; \
static Z_DECL_ALIGN(struct net_if) \
NET_IF_GET_NAME(dev_name, sfx)[NET_IF_MAX_CONFIGS] \
__used __in_section(_net_if, static, net_if) = { \
[0 ... (NET_IF_MAX_CONFIGS - 1)] = { \
.if_dev = &(NET_IF_DEV_GET_NAME(dev_name, sfx)), \
NET_IF_CONFIG_INIT \
} \
}
/** @endcond */
/* Network device initialization macros */
/**
* @def NET_DEVICE_INIT
*
* @brief Create a network interface and bind it to network device.
*
* @param dev_name Network device name.
* @param drv_name The name this instance of the driver exposes to
* the system.
* @param init_fn Address to the init function of the driver.
* @param pm_control_fn Pointer to device_pm_control function.
* Can be empty function (device_pm_control_nop) if not implemented.
* @param data Pointer to the device's private data.
* @param cfg The address to the structure containing the
* configuration information for this instance of the driver.
* @param prio The initialization level at which configuration occurs.
* @param api Provides an initial pointer to the API function struct
* used by the driver. Can be NULL.
* @param l2 Network L2 layer for this network interface.
* @param l2_ctx_type Type of L2 context data.
* @param mtu Maximum transfer unit in bytes for this network interface.
*/
#define NET_DEVICE_INIT(dev_name, drv_name, init_fn, pm_control_fn, \
data, cfg, prio, api, l2, \
l2_ctx_type, mtu) \
DEVICE_DEFINE(dev_name, drv_name, init_fn, pm_control_fn, data, \
cfg, POST_KERNEL, prio, api); \
NET_L2_DATA_INIT(dev_name, 0, l2_ctx_type); \
NET_IF_INIT(dev_name, 0, l2, mtu, NET_IF_MAX_CONFIGS)
/**
* @def NET_DEVICE_INIT_INSTANCE
*
* @brief Create multiple network interfaces and bind them to network device.
* If your network device needs more than one instance of a network interface,
* use this macro below and provide a different instance suffix each time
* (0, 1, 2, ... or a, b, c ... whatever works for you)
*
* @param dev_name Network device name.
* @param drv_name The name this instance of the driver exposes to
* the system.
* @param instance Instance identifier.
* @param init_fn Address to the init function of the driver.
* @param pm_control_fn Pointer to device_pm_control function.
* Can be empty function (device_pm_control_nop) if not implemented.
* @param data Pointer to the device's private data.
* @param cfg The address to the structure containing the
* configuration information for this instance of the driver.
* @param prio The initialization level at which configuration occurs.
* @param api Provides an initial pointer to the API function struct
* used by the driver. Can be NULL.
* @param l2 Network L2 layer for this network interface.
* @param l2_ctx_type Type of L2 context data.
* @param mtu Maximum transfer unit in bytes for this network interface.
*/
#define NET_DEVICE_INIT_INSTANCE(dev_name, drv_name, instance, init_fn, \
pm_control_fn, data, cfg, prio, \
api, l2, l2_ctx_type, mtu) \
DEVICE_DEFINE(dev_name, drv_name, init_fn, pm_control_fn, data, \
cfg, POST_KERNEL, prio, api); \
NET_L2_DATA_INIT(dev_name, instance, l2_ctx_type); \
NET_IF_INIT(dev_name, instance, l2, mtu, NET_IF_MAX_CONFIGS)
/**
* @def NET_DEVICE_OFFLOAD_INIT
*
* @brief Create a offloaded network interface and bind it to network device.
* The offloaded network interface is implemented by a device vendor HAL or
* similar.
*
* @param dev_name Network device name.
* @param drv_name The name this instance of the driver exposes to
* the system.
* @param init_fn Address to the init function of the driver.
* @param pm_control_fn Pointer to device_pm_control function.
* Can be empty function (device_pm_control_nop) if not implemented.
* @param data Pointer to the device's private data.
* @param cfg The address to the structure containing the
* configuration information for this instance of the driver.
* @param prio The initialization level at which configuration occurs.
* @param api Provides an initial pointer to the API function struct
* used by the driver. Can be NULL.
* @param mtu Maximum transfer unit in bytes for this network interface.
*/
#define NET_DEVICE_OFFLOAD_INIT(dev_name, drv_name, init_fn, \
pm_control_fn, data, cfg, prio, \
api, mtu) \
DEVICE_DEFINE(dev_name, drv_name, init_fn, pm_control_fn, data, \
cfg, POST_KERNEL, prio, api); \
NET_IF_OFFLOAD_INIT(dev_name, 0, mtu)
#ifdef __cplusplus
}
#endif
#include <syscalls/net_if.h>
/**
* @}
*/
#endif /* ZEPHYR_INCLUDE_NET_NET_IF_H_ */