Skip to content

Commit 041cd5f

Browse files
committed
net: if: Add syscall interface to IP address add and rm
Make IPv4 and IPv6 address addition and removal possible from userspace app. But allow this only if CONFIG_NET_IF_USERSPACE_ACCESS By default these operations are not allowed from userspace app. Signed-off-by: Jukka Rissanen <[email protected]>
1 parent 0ca1aaa commit 041cd5f

File tree

3 files changed

+257
-0
lines changed

3 files changed

+257
-0
lines changed

include/net/net_if.h

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -840,6 +840,16 @@ struct net_if_addr *net_if_ipv6_addr_lookup(const struct in6_addr *addr,
840840
struct net_if_addr *net_if_ipv6_addr_lookup_by_iface(struct net_if *iface,
841841
struct in6_addr *addr);
842842

843+
/**
844+
* @brief Check if this IPv6 address belongs to one of the interface indices.
845+
*
846+
* @param addr IPv6 address
847+
*
848+
* @return >0 if address was found in given network interface index,
849+
* all other values mean address was not found
850+
*/
851+
__syscall int net_if_ipv6_addr_lookup_by_index(const struct in6_addr *addr);
852+
843853
/**
844854
* @brief Add a IPv6 address to an interface
845855
*
@@ -855,6 +865,21 @@ struct net_if_addr *net_if_ipv6_addr_add(struct net_if *iface,
855865
enum net_addr_type addr_type,
856866
u32_t vlifetime);
857867

868+
/**
869+
* @brief Add a IPv6 address to an interface by index
870+
*
871+
* @param index Network interface index
872+
* @param addr IPv6 address
873+
* @param addr_type IPv6 address type
874+
* @param vlifetime Validity time for this address
875+
*
876+
* @return True if ok, false if address could not be added
877+
*/
878+
__syscall bool net_if_ipv6_addr_add_by_index(int index,
879+
struct in6_addr *addr,
880+
enum net_addr_type addr_type,
881+
u32_t vlifetime);
882+
858883
/**
859884
* @brief Update validity lifetime time of an IPv6 address.
860885
*
@@ -874,6 +899,16 @@ void net_if_ipv6_addr_update_lifetime(struct net_if_addr *ifaddr,
874899
*/
875900
bool net_if_ipv6_addr_rm(struct net_if *iface, const struct in6_addr *addr);
876901

902+
/**
903+
* @brief Remove an IPv6 address from an interface by index
904+
*
905+
* @param index Network interface index
906+
* @param addr IPv6 address
907+
*
908+
* @return True if successfully removed, false otherwise
909+
*/
910+
__syscall bool net_if_ipv6_addr_rm_by_index(int index,
911+
const struct in6_addr *addr);
877912

878913
/**
879914
* @brief Add a IPv6 multicast address to an interface
@@ -1443,6 +1478,42 @@ struct net_if_addr *net_if_ipv4_addr_add(struct net_if *iface,
14431478
*/
14441479
bool net_if_ipv4_addr_rm(struct net_if *iface, struct in_addr *addr);
14451480

1481+
/**
1482+
* @brief Check if this IPv4 address belongs to one of the interface indices.
1483+
*
1484+
* @param addr IPv4 address
1485+
*
1486+
* @return >0 if address was found in given network interface index,
1487+
* all other values mean address was not found
1488+
*/
1489+
__syscall int net_if_ipv4_addr_lookup_by_index(const struct in_addr *addr);
1490+
1491+
/**
1492+
* @brief Add a IPv4 address to an interface by network interface index
1493+
*
1494+
* @param index Network interface index
1495+
* @param addr IPv4 address
1496+
* @param addr_type IPv4 address type
1497+
* @param vlifetime Validity time for this address
1498+
*
1499+
* @return True if ok, false if the address could not be added
1500+
*/
1501+
__syscall bool net_if_ipv4_addr_add_by_index(int index,
1502+
struct in_addr *addr,
1503+
enum net_addr_type addr_type,
1504+
u32_t vlifetime);
1505+
1506+
/**
1507+
* @brief Remove a IPv4 address from an interface by interface index
1508+
*
1509+
* @param index Network interface index
1510+
* @param addr IPv4 address
1511+
*
1512+
* @return True if successfully removed, false otherwise
1513+
*/
1514+
__syscall bool net_if_ipv4_addr_rm_by_index(int index,
1515+
const struct in_addr *addr);
1516+
14461517
/**
14471518
* @brief Add a IPv4 multicast address to an interface
14481519
*
@@ -2026,6 +2097,8 @@ struct net_if_api {
20262097
}
20272098
#endif
20282099

2100+
#include <syscalls/net_if.h>
2101+
20292102
/**
20302103
* @}
20312104
*/

subsys/net/ip/Kconfig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,14 @@ config NET_HEADERS_ALWAYS_CONTIGUOUS
492492
NET_BUF_FIXED_DATA_SIZE enabled and NET_BUF_DATA_SIZE of 128 for
493493
instance.
494494

495+
config NET_IF_USERSPACE_ACCESS
496+
bool "Allow userspace app to manipulate network interface"
497+
depends on USERSPACE
498+
help
499+
Only enable this if you want a userspace application to manipulate
500+
network interface. Currently this is limited to add or remove
501+
IP addresses. By default this is not allowed.
502+
495503
choice
496504
prompt "Default Network Interface"
497505
default NET_DEFAULT_IF_FIRST

subsys/net/ip/net_if.c

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ LOG_MODULE_REGISTER(net_if, CONFIG_NET_IF_LOG_LEVEL);
1010
#include <init.h>
1111
#include <kernel.h>
1212
#include <linker/sections.h>
13+
#include <syscall_handler.h>
1314
#include <stdlib.h>
1415
#include <string.h>
1516
#include <net/net_core.h>
@@ -751,6 +752,30 @@ struct net_if_addr *net_if_ipv6_addr_lookup_by_iface(struct net_if *iface,
751752
return NULL;
752753
}
753754

755+
int z_impl_net_if_ipv6_addr_lookup_by_index(const struct in6_addr *addr)
756+
{
757+
struct net_if *iface = NULL;
758+
struct net_if_addr *if_addr;
759+
760+
if_addr = net_if_ipv6_addr_lookup(addr, &iface);
761+
if (!if_addr) {
762+
return 0;
763+
}
764+
765+
return net_if_get_by_iface(iface);
766+
}
767+
768+
#ifdef CONFIG_USERSPACE
769+
Z_SYSCALL_HANDLER(net_if_ipv6_addr_lookup_by_index, addr)
770+
{
771+
struct in6_addr addr_v6;
772+
773+
Z_OOPS(z_user_from_copy(&addr_v6, (void *)addr, sizeof(addr_v6)));
774+
775+
return z_impl_net_if_ipv6_addr_lookup_by_index(&addr_v6);
776+
}
777+
#endif
778+
754779
#if defined(CONFIG_NET_IPV6)
755780
static bool check_timeout(u32_t start, s32_t timeout, u32_t counter,
756781
u32_t current_time)
@@ -1087,6 +1112,69 @@ bool net_if_ipv6_addr_rm(struct net_if *iface, const struct in6_addr *addr)
10871112
return false;
10881113
}
10891114

1115+
bool z_impl_net_if_ipv6_addr_add_by_index(int index,
1116+
struct in6_addr *addr,
1117+
enum net_addr_type addr_type,
1118+
u32_t vlifetime)
1119+
{
1120+
struct net_if *iface;
1121+
1122+
iface = net_if_get_by_index(index);
1123+
if (!iface) {
1124+
return false;
1125+
}
1126+
1127+
return net_if_ipv6_addr_add(iface, addr, addr_type, vlifetime) ?
1128+
true : false;
1129+
}
1130+
1131+
#ifdef CONFIG_USERSPACE
1132+
Z_SYSCALL_HANDLER(net_if_ipv6_addr_add_by_index, index, addr, addr_type,
1133+
vlifetime)
1134+
{
1135+
#if defined(CONFIG_NET_IF_USERSPACE_ACCESS)
1136+
struct in6_addr addr_v6;
1137+
1138+
Z_OOPS(z_user_from_copy(&addr_v6, (void *)addr, sizeof(addr_v6)));
1139+
1140+
return z_impl_net_if_ipv6_addr_add_by_index(index,
1141+
&addr_v6,
1142+
addr_type,
1143+
vlifetime);
1144+
#else
1145+
return false;
1146+
#endif /* CONFIG_NET_IF_USERSPACE_ACCESS */
1147+
}
1148+
#endif /* CONFIG_USERSPACE */
1149+
1150+
bool z_impl_net_if_ipv6_addr_rm_by_index(int index,
1151+
const struct in6_addr *addr)
1152+
{
1153+
struct net_if *iface;
1154+
1155+
iface = net_if_get_by_index(index);
1156+
if (!iface) {
1157+
return false;
1158+
}
1159+
1160+
return net_if_ipv6_addr_rm(iface, addr);
1161+
}
1162+
1163+
#ifdef CONFIG_USERSPACE
1164+
Z_SYSCALL_HANDLER(net_if_ipv6_addr_rm_by_index, index, addr)
1165+
{
1166+
#if defined(CONFIG_NET_IF_USERSPACE_ACCESS)
1167+
struct in6_addr addr_v6;
1168+
1169+
Z_OOPS(z_user_from_copy(&addr_v6, (void *)addr, sizeof(addr_v6)));
1170+
1171+
return z_impl_net_if_ipv6_addr_rm_by_index(index, &addr_v6);
1172+
#else
1173+
return false;
1174+
#endif /* CONFIG_NET_IF_USERSPACE_ACCESS */
1175+
}
1176+
#endif /* CONFIG_USERSPACE */
1177+
10901178
struct net_if_mcast_addr *net_if_ipv6_maddr_add(struct net_if *iface,
10911179
const struct in6_addr *addr)
10921180
{
@@ -2485,6 +2573,30 @@ struct net_if_addr *net_if_ipv4_addr_lookup(const struct in_addr *addr,
24852573
return NULL;
24862574
}
24872575

2576+
int z_impl_net_if_ipv4_addr_lookup_by_index(const struct in_addr *addr)
2577+
{
2578+
struct net_if_addr *if_addr;
2579+
struct net_if *iface = NULL;
2580+
2581+
if_addr = net_if_ipv4_addr_lookup(addr, &iface);
2582+
if (!if_addr) {
2583+
return 0;
2584+
}
2585+
2586+
return net_if_get_by_iface(iface);
2587+
}
2588+
2589+
#ifdef CONFIG_USERSPACE
2590+
Z_SYSCALL_HANDLER(net_if_ipv4_addr_lookup_by_index, addr)
2591+
{
2592+
struct in_addr addr_v4;
2593+
2594+
Z_OOPS(z_user_from_copy(&addr_v4, (void *)addr, sizeof(addr_v4)));
2595+
2596+
return z_impl_net_if_ipv4_addr_lookup_by_index(&addr_v4);
2597+
}
2598+
#endif
2599+
24882600
#if defined(CONFIG_NET_IPV4)
24892601
static struct net_if_addr *ipv4_addr_find(struct net_if *iface,
24902602
struct in_addr *addr)
@@ -2609,6 +2721,70 @@ bool net_if_ipv4_addr_rm(struct net_if *iface, struct in_addr *addr)
26092721
return false;
26102722
}
26112723

2724+
bool z_impl_net_if_ipv4_addr_add_by_index(int index,
2725+
struct in_addr *addr,
2726+
enum net_addr_type addr_type,
2727+
u32_t vlifetime)
2728+
{
2729+
struct net_if *iface;
2730+
struct net_if_addr *if_addr;
2731+
2732+
iface = net_if_get_by_index(index);
2733+
if (!iface) {
2734+
return false;
2735+
}
2736+
2737+
if_addr = net_if_ipv4_addr_add(iface, addr, addr_type, vlifetime);
2738+
return if_addr ? true : false;
2739+
}
2740+
2741+
#ifdef CONFIG_USERSPACE
2742+
Z_SYSCALL_HANDLER(net_if_ipv4_addr_add_by_index, index, addr, addr_type,
2743+
vlifetime)
2744+
{
2745+
#if defined(CONFIG_NET_IF_USERSPACE_ACCESS)
2746+
struct in_addr addr_v4;
2747+
2748+
Z_OOPS(z_user_from_copy(&addr_v4, (void *)addr, sizeof(addr_v4)));
2749+
2750+
return z_impl_net_if_ipv4_addr_add_by_index(index,
2751+
&addr_v4,
2752+
addr_type,
2753+
vlifetime);
2754+
#else
2755+
return false;
2756+
#endif /* CONFIG_NET_IF_USERSPACE_ACCESS */
2757+
}
2758+
#endif /* CONFIG_USERSPACE */
2759+
2760+
bool z_impl_net_if_ipv4_addr_rm_by_index(int index,
2761+
const struct in_addr *addr)
2762+
{
2763+
struct net_if *iface;
2764+
2765+
iface = net_if_get_by_index(index);
2766+
if (!iface) {
2767+
return false;
2768+
}
2769+
2770+
return net_if_ipv4_addr_rm(iface, addr);
2771+
}
2772+
2773+
#ifdef CONFIG_USERSPACE
2774+
Z_SYSCALL_HANDLER(net_if_ipv4_addr_rm_by_index, index, addr)
2775+
{
2776+
#if defined(CONFIG_NET_IF_USERSPACE_ACCESS)
2777+
struct in_addr addr_v4;
2778+
2779+
Z_OOPS(z_user_from_copy(&addr_v4, (void *)addr, sizeof(addr_v4)));
2780+
2781+
return (uint32_t)z_impl_net_if_ipv4_addr_rm_by_index(index, &addr_v4);
2782+
#else
2783+
return false;
2784+
#endif /* CONFIG_NET_IF_USERSPACE_ACCESS */
2785+
}
2786+
#endif /* CONFIG_USERSPACE */
2787+
26122788
#if defined(CONFIG_NET_IPV4)
26132789
static struct net_if_mcast_addr *ipv4_maddr_find(struct net_if *iface,
26142790
bool is_used,

0 commit comments

Comments
 (0)