Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wireguard VPN support #86020

Open
wants to merge 36 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
74c11c9
net: virtual: Add capability flag for VPN type interface
jukkar Jul 25, 2024
26e768d
net: Add helper to get sockaddr from sockaddr_storage struct
jukkar Feb 19, 2025
c648eaf
net: wireguard: Add initial implementation
jukkar Jul 23, 2024
004cae2
net: wireguard: Add crypto support
jukkar Jul 26, 2024
7972236
net: wireguard: crypto: Add SPDX license identifiers
jukkar Jul 29, 2024
9cf63e7
net: wireguard: crypto: Fix CI compliance issues
jukkar Feb 19, 2025
742d856
net: wireguard: crypto: Fix warning in x25519.c mul()
jukkar Feb 20, 2025
4337ceb
net: shell: Add Wireguard VPN support
jukkar Jul 25, 2024
b64147d
net: shell: iface: Print Wireguard public key
jukkar Feb 13, 2025
9febbbb
net: shell: iface: Print low level information if iface dbg is enabled
jukkar Feb 17, 2025
5ffac42
net: shell: iface: Allow user to set the default interface
jukkar Feb 27, 2025
b73eace
net: shell: conn: Print all connection information
jukkar Feb 20, 2025
4f101b6
net: wireguard: stats: Add statistics support
jukkar Feb 20, 2025
ccf91dc
net: shell: wg: Add VPN statistics support
jukkar Feb 20, 2025
715ef34
net: shell: wg: Print detailed peer information
jukkar Feb 27, 2025
e12cc5e
net: wireguard: Send network events for VPN activity
jukkar Feb 25, 2025
2d2899c
net: shell: events: Print wireguard event information
jukkar Feb 25, 2025
9959efc
net: utils: Add helper to parse ip address string with a mask len
jukkar Feb 14, 2025
ab418dc
tests: net: utils: Add tests for IP address string with mask
jukkar Feb 14, 2025
3159a3b
net: l2: virtual: Add support for VPN public/private key set/get
jukkar Feb 13, 2025
b1d86ef
net: l2: virtual: Handle the packet if no attached interfaces
jukkar Feb 15, 2025
1ae3c85
net: l2: dummy: Update sent statistics
jukkar Feb 17, 2025
f7af5ea
net: if: Add helper to get src interface and address from dst address
jukkar Feb 17, 2025
7e4d9a4
samples: net: echo-server: Add Wireguard VPN support
jukkar Feb 17, 2025
ef10988
samples: net: echo-client: Add Wireguard VPN support
jukkar Feb 20, 2025
3bf71e3
samples: net: echo-client: Enable event mgmt info support
jukkar Feb 20, 2025
8bcb4d8
samples: net: http-server: Add Wireguard VPN support
jukkar Feb 20, 2025
a256707
samples: net: Enable Wireguard VPN compilation in tests
jukkar Feb 20, 2025
c7c51ff
samples: net: echo-server: Refactor VLAN support
jukkar Feb 24, 2025
bef52e8
samples: net: echo-client: Refactor VLAN support
jukkar Feb 24, 2025
915e1bf
samples: net: mdns_responder: Refactor VLAN support
jukkar Feb 25, 2025
3bf23c1
samples: net: txtime: Refactor VLAN support
jukkar Feb 25, 2025
80f0e3e
samples: net: vlan: Refactor VLAN support
jukkar Feb 25, 2025
76ceb7c
samples: net: common: Add information about VPN and VLAN
jukkar Feb 25, 2025
424f037
net: if: Add special handling for IPv4/6 address check for VPN
jukkar Feb 27, 2025
49eba58
manifest: Update net-tools to have Wireguard support
jukkar Feb 20, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions include/zephyr/net/net_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ enum net_event_l4_cmd {
NET_EVENT_L4_CMD_HOSTNAME_CHANGED,
NET_EVENT_L4_CMD_CAPTURE_STARTED,
NET_EVENT_L4_CMD_CAPTURE_STOPPED,
NET_EVENT_L4_CMD_VPN_CONNECTED,
NET_EVENT_L4_CMD_VPN_DISCONNECTED,
NET_EVENT_L4_CMD_VPN_PEER_ADD,
NET_EVENT_L4_CMD_VPN_PEER_DEL,
};

/** @endcond */
Expand Down Expand Up @@ -358,6 +362,22 @@ enum net_event_l4_cmd {
#define NET_EVENT_CAPTURE_STOPPED \
(_NET_EVENT_L4_BASE | NET_EVENT_L4_CMD_CAPTURE_STOPPED)

/** Event emitted when VPN network connectivity is available. */
#define NET_EVENT_VPN_CONNECTED \
(_NET_EVENT_L4_BASE | NET_EVENT_L4_CMD_VPN_CONNECTED)

/** Event emitted when VPN network connectivity is lost. */
#define NET_EVENT_VPN_DISCONNECTED \
(_NET_EVENT_L4_BASE | NET_EVENT_L4_CMD_VPN_DISCONNECTED)

/** Event emitted when a VPN peer is added to the system. */
#define NET_EVENT_VPN_PEER_ADD \
(_NET_EVENT_L4_BASE | NET_EVENT_L4_CMD_VPN_PEER_ADD)

/** Event emitted when a VPN peer is removed from the system. */
#define NET_EVENT_VPN_PEER_DEL \
(_NET_EVENT_L4_BASE | NET_EVENT_L4_CMD_VPN_PEER_DEL)

/**
* @brief Network Management event information structure
* Used to pass information on network events like
Expand Down
52 changes: 52 additions & 0 deletions include/zephyr/net/net_if.h
Original file line number Diff line number Diff line change
Expand Up @@ -2153,6 +2153,32 @@ static inline struct net_if *net_if_ipv6_select_src_iface(
}
#endif

/**
* @brief Get a network interface that should be used when sending
* IPv6 network data to destination. Also return the source IPv6 address from
* that network interface.
*
* @param dst IPv6 destination address
* @param src_addr IPv6 source address. This can be set to NULL if the source
* address is not needed.
*
* @return Pointer to network interface to use, NULL if no suitable interface
* could be found.
*/
#if defined(CONFIG_NET_IPV6)
struct net_if *net_if_ipv6_select_src_iface_addr(const struct in6_addr *dst,
const struct in6_addr **src_addr);
#else
static inline struct net_if *net_if_ipv6_select_src_iface_addr(
const struct in6_addr *dst, const struct in6_addr **src_addr)
{
ARG_UNUSED(dst);
ARG_UNUSED(src_addr);

return NULL;
}
#endif /* CONFIG_NET_IPV6 */

/**
* @brief Get a IPv6 link local address in a given state.
*
Expand Down Expand Up @@ -2534,6 +2560,32 @@ static inline struct net_if *net_if_ipv4_select_src_iface(
}
#endif

/**
* @brief Get a network interface that should be used when sending
* IPv4 network data to destination. Also return the source IPv4 address from
* that network interface.
*
* @param dst IPv4 destination address
* @param src_addr IPv4 source address. This can be set to NULL if the source
* address is not needed.
*
* @return Pointer to network interface to use, NULL if no suitable interface
* could be found.
*/
#if defined(CONFIG_NET_IPV4)
struct net_if *net_if_ipv4_select_src_iface_addr(const struct in_addr *dst,
const struct in_addr **src_addr);
#else
static inline struct net_if *net_if_ipv4_select_src_iface_addr(
const struct in_addr *dst, const struct in_addr **src_addr)
{
ARG_UNUSED(dst);
ARG_UNUSED(src_addr);

return NULL;
}
#endif /* CONFIG_NET_IPV4 */

/**
* @brief Get a IPv4 source address that should be used when sending
* network data to destination.
Expand Down
69 changes: 69 additions & 0 deletions include/zephyr/net/net_ip.h
Original file line number Diff line number Diff line change
Expand Up @@ -1544,6 +1544,19 @@ static inline bool net_ipv6_addr_based_on_ll(const struct in6_addr *addr,
return false;
}

/**
* @brief Get sockaddr from sockaddr_storage. This is a helper so that
* the code calling this function can be made shorter.
*
* @param addr Socket storage address
*
* @return Pointer to socket address (struct sockaddr)
*/
static inline struct sockaddr *net_sad(const struct sockaddr_storage *addr)
{
return (struct sockaddr *)addr;
}

/**
* @brief Get sockaddr_in6 from sockaddr. This is a helper so that
* the code calling this function can be made shorter.
Expand Down Expand Up @@ -1655,6 +1668,32 @@ __syscall int net_addr_pton(sa_family_t family, const char *src, void *dst);
__syscall char *net_addr_ntop(sa_family_t family, const void *src,
char *dst, size_t size);

/**
* @brief Create netmask from mask length.
*
* @param family IP address family (AF_INET or AF_INET6)
* @param mask_len Netmask length (in IPv4) or prefix length (in IPv6)
* @param mask Pointer to struct sockaddr_in if family is AF_INET or
* pointer to struct sockaddr_in6 if family is AF_INET6
*
* @return 0 if ok, < 0 if error
*/
int net_mask_len_to_netmask(sa_family_t family, uint8_t mask_len,
struct sockaddr *mask);

/**
* @brief Create mask length from netmask.
*
* @param family IP address family (AF_INET or AF_INET6)
* @param mask Pointer to struct sockaddr_in if family is AF_INET or
* pointer to struct sockaddr_in6 if family is AF_INET6
* @param mask_len Netmask length (in IPv4) or prefix length (in IPv6)
*
* @return 0 if ok, < 0 if error
*/
int net_netmask_to_mask_len(sa_family_t family, struct sockaddr *mask,
uint8_t *mask_len);

/**
* @brief Parse a string that contains either IPv4 or IPv6 address
* and optional port, and store the information in user supplied
Expand All @@ -1679,6 +1718,36 @@ __syscall char *net_addr_ntop(sa_family_t family, const void *src,
bool net_ipaddr_parse(const char *str, size_t str_len,
struct sockaddr *addr);

/**
* @brief Parse a string that contains either IPv4 or IPv6 address
* and optional mask len, and store the information in user supplied
* sockaddr struct. There can be multiple IP addresses separated by
* comma or space. The function returns the pointer to the next IP address
* in the string.
*
* @details Syntax of the IP address string:
* 192.0.2.1/24
* 192.0.2.42
* 2001:db8::1/64
* 2001:db8::2
* 2001:db::42/128
* 2001:db8::1/64,192.0.2.1,2001:db8::2,192.0.2.2/24
* 2001:db8::1/64 192.0.2.1 2001:db8::2 192.0.2.2/24
* Note that the str_len parameter is used to restrict the amount of
* characters that are checked.
*
* @param str String that contains the IP address.
* @param str_len Length of the string to be parsed.
* @param addr Pointer to user supplied struct sockaddr.
* @param mask_len Pointer to mask_len which is returned to the caller.
*
* @return NULL if there was an error while parsing.
* "" if we could parse the IP address and there is nothing more to parse.
* All other values point to next character after the "," or " " in the string.
*/
const char *net_ipaddr_parse_mask(const char *str, size_t str_len,
struct sockaddr *addr, uint8_t *mask_len);

/**
* @brief Set the default port in the sockaddr structure.
* If the port is already set, then do nothing.
Expand Down
60 changes: 60 additions & 0 deletions include/zephyr/net/net_pkt.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,19 @@ struct net_pkt {
struct net_if *orig_iface; /* Original network interface */
#endif

#if defined(CONFIG_WIREGUARD)
struct {
/** Original network interface */
struct net_if *iface;
/** Pointer to IP header of the encrypted pkt */
union net_ip_header ip_hdr;
/** Pointer to UDP header of the encrypted pkt */
union net_proto_header proto_hdr;
/** Peer id */
int peer_id;
} wg;
#endif

#if defined(CONFIG_NET_PKT_TIMESTAMP) || defined(CONFIG_NET_PKT_TXTIME)
/**
* TX or RX timestamp if available
Expand Down Expand Up @@ -410,6 +423,53 @@ static inline void net_pkt_set_orig_iface(struct net_pkt *pkt,
#endif
}

#if defined(CONFIG_WIREGUARD)
static inline struct net_if *net_pkt_wg_iface(struct net_pkt *pkt)
{
return pkt->wg.iface;
}

static inline void net_pkt_set_wg_iface(struct net_pkt *pkt,
struct net_if *iface)
{
pkt->wg.iface = iface;
}

static inline union net_ip_header *net_pkt_wg_ip_hdr(struct net_pkt *pkt)
{
return &pkt->wg.ip_hdr;
}

static inline void net_pkt_set_wg_ip_hdr(struct net_pkt *pkt,
union net_ip_header *ip_hdr)
{
pkt->wg.ip_hdr = *ip_hdr;
}

static inline union net_proto_header *net_pkt_wg_udp_hdr(struct net_pkt *pkt)
{
return &pkt->wg.proto_hdr;
}

static inline void net_pkt_set_wg_udp_hdr(struct net_pkt *pkt,
union net_proto_header *proto_hdr)
{
pkt->wg.proto_hdr = *proto_hdr;
}

static inline int net_pkt_wg_peer_id(struct net_pkt *pkt)
{
return pkt->wg.peer_id;
}

static inline void net_pkt_set_wg_peer_id(struct net_pkt *pkt,
int peer_id)
{
pkt->wg.peer_id = peer_id;
}

#endif

static inline uint8_t net_pkt_family(struct net_pkt *pkt)
{
return pkt->family;
Expand Down
11 changes: 11 additions & 0 deletions include/zephyr/net/net_stats.h
Original file line number Diff line number Diff line change
Expand Up @@ -724,6 +724,7 @@ enum net_request_stats_cmd {
NET_REQUEST_STATS_CMD_GET_PM,
NET_REQUEST_STATS_CMD_GET_WIFI,
NET_REQUEST_STATS_CMD_RESET_WIFI,
NET_REQUEST_STATS_CMD_GET_VPN,
};

/** @endcond */
Expand Down Expand Up @@ -853,6 +854,16 @@ NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_STATS_GET_PPP);
/** @endcond */
#endif /* CONFIG_NET_STATISTICS_PPP */

#if defined(CONFIG_NET_STATISTICS_VPN)
/** Request VPN statistics */
#define NET_REQUEST_STATS_GET_VPN \
(_NET_STATS_BASE | NET_REQUEST_STATS_CMD_GET_VPN)

/** @cond INTERNAL_HIDDEN */
NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_STATS_GET_VPN);
/** @endcond */
#endif /* CONFIG_NET_STATISTICS_VPN */

#endif /* CONFIG_NET_STATISTICS_USER_API */

#if defined(CONFIG_NET_STATISTICS_POWER_MANAGEMENT)
Expand Down
17 changes: 17 additions & 0 deletions include/zephyr/net/virtual.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ enum virtual_interface_caps {
/** Virtual Ethernet bridge interface. */
VIRTUAL_INTERFACE_BRIDGE = BIT(3),

/** VPN interface */
VIRTUAL_INTERFACE_VPN = BIT(4),

/** @cond INTERNAL_HIDDEN */
/* Marker for capabilities - must be at the end of the enum.
* It is here because the capability list cannot be empty.
Expand All @@ -60,6 +63,8 @@ enum virtual_interface_config_type {
VIRTUAL_INTERFACE_CONFIG_TYPE_PEER_ADDRESS,
VIRTUAL_INTERFACE_CONFIG_TYPE_MTU,
VIRTUAL_INTERFACE_CONFIG_TYPE_LINK_TYPE,
VIRTUAL_INTERFACE_CONFIG_TYPE_PRIVATE_KEY,
VIRTUAL_INTERFACE_CONFIG_TYPE_PUBLIC_KEY,
};

struct virtual_interface_link_types {
Expand All @@ -69,13 +74,25 @@ struct virtual_interface_link_types {
(1))];
};

#if !defined(NET_VIRTUAL_MAX_PUBLIC_KEY_LEN)
#define NET_VIRTUAL_MAX_PUBLIC_KEY_LEN 32U
#endif

struct virtual_interface_config {
sa_family_t family;
union {
struct in_addr peer4addr;
struct in6_addr peer6addr;
int mtu;
struct virtual_interface_link_types link_types;
struct {
size_t len;
uint8_t *data;
} private_key;
struct {
size_t len;
uint8_t data[NET_VIRTUAL_MAX_PUBLIC_KEY_LEN];
} public_key;
};
};

Expand Down
22 changes: 22 additions & 0 deletions include/zephyr/net/virtual_mgmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,14 @@ struct virtual_interface_req_params {
struct in6_addr peer6addr;
int mtu;
struct virtual_interface_link_types link_types;
struct {
size_t len;
uint8_t *data;
} private_key;
struct {
size_t len;
uint8_t data[NET_VIRTUAL_MAX_PUBLIC_KEY_LEN];
} public_key;
};
};

Expand All @@ -56,6 +64,8 @@ enum net_request_virtual_interface_cmd {
NET_REQUEST_VIRTUAL_INTERFACE_CMD_GET_MTU,
NET_REQUEST_VIRTUAL_INTERFACE_CMD_SET_LINK_TYPE,
NET_REQUEST_VIRTUAL_INTERFACE_CMD_GET_LINK_TYPE,
NET_REQUEST_VIRTUAL_INTERFACE_CMD_SET_PRIVATE_KEY,
NET_REQUEST_VIRTUAL_INTERFACE_CMD_GET_PUBLIC_KEY,
};

#define NET_REQUEST_VIRTUAL_INTERFACE_SET_PEER_ADDRESS \
Expand Down Expand Up @@ -94,6 +104,18 @@ NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_VIRTUAL_INTERFACE_GET_MTU);

NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_VIRTUAL_INTERFACE_GET_LINK_TYPE);

#define NET_REQUEST_VIRTUAL_INTERFACE_SET_PRIVATE_KEY \
(_NET_VIRTUAL_INTERFACE_BASE | \
NET_REQUEST_VIRTUAL_INTERFACE_CMD_SET_PRIVATE_KEY)

NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_VIRTUAL_INTERFACE_SET_PRIVATE_KEY);

#define NET_REQUEST_VIRTUAL_INTERFACE_GET_PUBLIC_KEY \
(_NET_VIRTUAL_INTERFACE_BASE | \
NET_REQUEST_VIRTUAL_INTERFACE_CMD_GET_PUBLIC_KEY)

NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_VIRTUAL_INTERFACE_GET_PUBLIC_KEY);

struct net_if;

/** @endcond */
Expand Down
Loading
Loading