net: Add IPv4 addresses to network interface

Allow user to assign IPv4 addresses to a network interface.

Change-Id: I77be4ed5eb0231eb12b4ad47cb6076c8f4238124
Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit is contained in:
Jukka Rissanen 2016-05-17 14:13:17 +03:00
commit cf5c1db262
4 changed files with 118 additions and 8 deletions

View file

@ -148,6 +148,18 @@ struct net_if {
uint8_t hop_limit;
#endif /* CONFIG_NET_IPV6 */
#if defined(CONFIG_NET_IPV4)
#define NET_IF_MAX_IPV4_ADDR CONFIG_NET_IFACE_UNICAST_IPV4_ADDR_COUNT
#define NET_IF_MAX_IPV4_MADDR CONFIG_NET_IFACE_MCAST_IPV4_ADDR_COUNT
struct {
/** 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];
} ipv4;
#endif /* CONFIG_NET_IPV4 */
};
/**
@ -236,6 +248,26 @@ struct net_if_mcast_addr *net_if_ipv6_maddr_add(struct net_if *iface,
*/
struct net_if_mcast_addr *net_if_ipv6_maddr_lookup(struct in6_addr *addr);
/**
* @brief Check if this IPv4 address belongs to one of the interfaces.
* @param addr IPv4 address
* @return Pointer to interface address, NULL if not found.
*/
struct net_if_addr *net_if_ipv4_addr_lookup(struct in_addr *addr);
/**
* @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);
struct net_if_api {
void (*init)(struct net_if *iface);
int (*send)(struct net_if *iface, struct net_buf *buf);

View file

@ -229,6 +229,12 @@ static inline bool net_is_ipv6_prefix(uint8_t *addr1, uint8_t *addr2,
(addr2[16 - bytes] & ((8 - remain) << 8)));
}
extern struct net_if_addr *net_if_ipv4_addr_lookup(struct in_addr *addr);
static inline bool net_is_my_ipv4_addr(struct in_addr *addr)
{
return net_if_ipv4_addr_lookup(addr) != NULL;
}
#ifdef __cplusplus
}
#endif

View file

@ -30,6 +30,21 @@ config NET_IPV6
Enable IPv6 support. This should be selected by default as there is
limited set of network bearers provided that support IPv4.
config NET_IFACE_UNICAST_IPV6_ADDR_COUNT
int "Max number of unicast IPv6 addresses assigned to network interface"
depends on NET_IPV6
default 1
config NET_IFACE_MCAST_IPV6_ADDR_COUNT
int "Max number of multicast IPv6 addresses assigned to network interface"
depends on NET_IPV6
default 1
config NET_IFACE_IPV6_PREFIX_COUNT
int "Max number of IPv6 prefixes assigned to network interface"
depends on NET_IPV6
default 2
config NET_IPV4
bool "Enable IPv4"
default n
@ -37,18 +52,16 @@ config NET_IPV4
Enable IPv4 support. If this is enabled then the device is
able to send and receive IPv4 network packets.
config NET_IFACE_UNICAST_IPV6_ADDR_COUNT
int "Max number of unicast IPv6 addresses assigned to network interface"
config NET_IFACE_UNICAST_IPV4_ADDR_COUNT
int "Max number of unicast IPv4 addresses assigned to network interface"
depends on NET_IPV4
default 1
config NET_IFACE_MCAST_IPV6_ADDR_COUNT
int "Max number of multicast IPv6 addresses assigned to network interface"
config NET_IFACE_MCAST_IPV4_ADDR_COUNT
int "Max number of multicast IPv4 addresses assigned to network interface"
depends on NET_IPV4
default 1
config NET_IFACE_IPV6_PREFIX_COUNT
int "Max number of IPv6 prefixes assigned to network interface"
default 2
config NET_TX_STACK_SIZE
int "TX fiber stack size"
default 1024

View file

@ -189,6 +189,65 @@ struct net_if_mcast_addr *net_if_ipv6_maddr_lookup(struct in6_addr *maddr)
return NULL;
}
struct net_if_addr *net_if_ipv4_addr_lookup(struct in_addr *addr)
{
struct net_if *iface;
for (iface = __net_if_start; iface != __net_if_end; iface++) {
int i;
for (i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) {
if (!iface->ipv4.unicast[i].is_used ||
iface->ipv4.unicast[i].address.family != AF_INET) {
continue;
}
if (addr->s4_addr32[0] ==
iface->ipv4.unicast[i].address.in_addr.s_addr[0]) {
return &iface->ipv4.unicast[i];
}
}
}
return NULL;
}
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)
{
int i;
for (i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) {
if (iface->ipv4.unicast[i].is_used) {
continue;
}
iface->ipv4.unicast[i].is_used = true;
iface->ipv4.unicast[i].address.family = AF_INET;
iface->ipv4.unicast[i].address.in_addr.s4_addr32[0] =
addr->s4_addr32[0];
iface->ipv4.unicast[i].addr_type = addr_type;
if (vlifetime) {
iface->ipv4.unicast[i].is_infinite = false;
/* FIXME - set the timer */
} else {
iface->ipv4.unicast[i].is_infinite = true;
}
NET_DBG("[%d] interface %p address %s type %s added", i, iface,
net_sprint_ipv4_addr(addr),
net_addr_type2str(addr_type));
return &iface->ipv4.unicast[i];
}
return NULL;
}
int net_if_init(void)
{
struct net_if_api *api;