blob: 74784561fa2114d8fd2446f728b6c9f647c99a58 [file] [log] [blame]
Tomasz Bursztyka5f165e72016-05-02 09:02:04 +02001/*
2 * Copyright (c) 2016 Intel Corporation.
3 *
David B. Kinderac74d8b2017-01-18 17:01:01 -08004 * SPDX-License-Identifier: Apache-2.0
Tomasz Bursztyka5f165e72016-05-02 09:02:04 +02005 */
6
Jukka Rissanen68ea9372016-11-12 00:13:24 +02007/**
8 * @file
9 * @brief Public API for network interface
10 */
11
Flavio Ceolin67ca1762018-09-14 10:43:44 -070012#ifndef ZEPHYR_INCLUDE_NET_NET_IF_H_
13#define ZEPHYR_INCLUDE_NET_NET_IF_H_
Jukka Rissanen68ea9372016-11-12 00:13:24 +020014
Tomasz Bursztykad8323e12017-01-06 14:10:06 +010015/**
16 * @brief Network Interface abstraction layer
17 * @defgroup net_if Network Interface abstraction layer
Anas Nashifca9285d2017-11-17 11:43:53 -050018 * @ingroup networking
Tomasz Bursztykad8323e12017-01-06 14:10:06 +010019 * @{
20 */
21
Jukka Rissanen68ea9372016-11-12 00:13:24 +020022#include <device.h>
Anas Nashif536dd5a2019-06-26 10:33:52 -040023#include <sys/slist.h>
Jukka Rissanen68ea9372016-11-12 00:13:24 +020024
25#include <net/net_core.h>
Jukka Rissanene3adbf82017-09-21 23:30:32 +030026#include <net/hostname.h>
Jukka Rissanen68ea9372016-11-12 00:13:24 +020027#include <net/net_linkaddr.h>
28#include <net/net_ip.h>
29#include <net/net_l2.h>
Jukka Rissanen1443ff02018-03-27 11:31:31 +030030#include <net/net_stats.h>
Jukka Rissanenc4cc8a52018-08-17 17:04:10 +030031#include <net/net_timeout.h>
Jukka Rissanen68ea9372016-11-12 00:13:24 +020032
Jukka Rissanen6cf1da42019-08-09 14:49:35 +030033#if defined(CONFIG_NET_DHCPV4) && defined(CONFIG_NET_NATIVE_IPV4)
Jukka Rissanen68ea9372016-11-12 00:13:24 +020034#include <net/dhcpv4.h>
Tomasz Bursztyka2fa38c12016-05-02 09:02:04 +020035#endif
Jukka Rissanen6cf1da42019-08-09 14:49:35 +030036#if defined(CONFIG_NET_IPV4_AUTO) && defined(CONFIG_NET_NATIVE_IPV4)
Jukka Rissanen00e37cb2018-07-30 18:28:35 +030037#include <net/ipv4_autoconf.h>
38#endif
Jukka Rissanen68ea9372016-11-12 00:13:24 +020039
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44/**
45 * @brief Network Interface unicast IP addresses
46 *
47 * Stores the unicast IP addresses assigned to this network interface.
48 */
49struct net_if_addr {
Jukka Rissanen68ea9372016-11-12 00:13:24 +020050 /** IP address */
51 struct net_addr address;
52
Jukka Rissanen6cf1da42019-08-09 14:49:35 +030053#if defined(CONFIG_NET_NATIVE_IPV6)
Jukka Rissanenc4cc8a52018-08-17 17:04:10 +030054 struct net_timeout lifetime;
Jukka Rissaneneeabc2b2018-08-17 10:20:05 +030055#endif
Jukka Rissanen68ea9372016-11-12 00:13:24 +020056
Jukka Rissanen6cf1da42019-08-09 14:49:35 +030057#if defined(CONFIG_NET_IPV6_DAD) && defined(CONFIG_NET_NATIVE_IPV6)
Jukka Rissanen68ea9372016-11-12 00:13:24 +020058 /** Duplicate address detection (DAD) timer */
Tomasz Bursztyka09e72622019-05-21 11:12:45 +020059 sys_snode_t dad_node;
Kumar Galaa1b77fd2020-05-27 11:26:57 -050060 uint32_t dad_start;
Jukka Rissanen8b8371f2017-04-12 23:00:21 +030061#endif
62 /** How the IP address was set */
63 enum net_addr_type addr_type;
Jukka Rissanen68ea9372016-11-12 00:13:24 +020064
Jukka Rissanen8b8371f2017-04-12 23:00:21 +030065 /** What is the current state of the address */
66 enum net_addr_state addr_state;
67
Jukka Rissanen6cf1da42019-08-09 14:49:35 +030068#if defined(CONFIG_NET_IPV6_DAD) && defined(CONFIG_NET_NATIVE_IPV6)
Jukka Rissanen68ea9372016-11-12 00:13:24 +020069 /** How many times we have done DAD */
Kumar Galaa1b77fd2020-05-27 11:26:57 -050070 uint8_t dad_count;
Jukka Rissanen8b8371f2017-04-12 23:00:21 +030071#endif
72
73 /** Is the IP address valid forever */
Kumar Galaa1b77fd2020-05-27 11:26:57 -050074 uint8_t is_infinite : 1;
Jukka Rissanen8b8371f2017-04-12 23:00:21 +030075
76 /** Is this IP address used or not */
Kumar Galaa1b77fd2020-05-27 11:26:57 -050077 uint8_t is_used : 1;
Jukka Rissanen4b9d9802018-08-10 17:21:08 +030078
Robert Lubos83b8aba2019-01-24 15:56:10 +010079 /** Is this IP address usage limited to the subnet (mesh) or not */
Kumar Galaa1b77fd2020-05-27 11:26:57 -050080 uint8_t is_mesh_local : 1;
Robert Lubos83b8aba2019-01-24 15:56:10 +010081
Kumar Galaa1b77fd2020-05-27 11:26:57 -050082 uint8_t _unused : 5;
Jukka Rissanen68ea9372016-11-12 00:13:24 +020083};
84
85/**
86 * @brief Network Interface multicast IP addresses
87 *
88 * Stores the multicast IP addresses assigned to this network interface.
89 */
90struct net_if_mcast_addr {
Jukka Rissanen9b8c83f2018-07-25 13:22:49 +030091 /** IP address */
92 struct net_addr address;
93
Jukka Rissanen68ea9372016-11-12 00:13:24 +020094 /** Is this multicast IP address used or not */
Kumar Galaa1b77fd2020-05-27 11:26:57 -050095 uint8_t is_used : 1;
Jukka Rissanenf8467432017-02-10 09:36:09 +020096
97 /** Did we join to this group */
Kumar Galaa1b77fd2020-05-27 11:26:57 -050098 uint8_t is_joined : 1;
Jukka Rissanenf8467432017-02-10 09:36:09 +020099
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500100 uint8_t _unused : 6;
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200101};
102
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200103/**
104 * @brief Network Interface IPv6 prefixes
105 *
106 * Stores the multicast IP addresses assigned to this network interface.
107 */
108struct net_if_ipv6_prefix {
Jukka Rissanenf8c94392017-04-12 22:54:08 +0300109 /** Prefix lifetime */
Jukka Rissanen09390e52018-08-27 14:02:09 +0300110 struct net_timeout lifetime;
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200111
112 /** IPv6 prefix */
113 struct in6_addr prefix;
114
Jukka Rissanen57a41a22018-08-17 13:33:20 +0300115 /** Backpointer to network interface where this prefix is used */
116 struct net_if *iface;
117
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200118 /** Prefix length */
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500119 uint8_t len;
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200120
121 /** Is the IP prefix valid forever */
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500122 uint8_t is_infinite : 1;
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200123
Jukka Rissanenf8c94392017-04-12 22:54:08 +0300124 /** Is this prefix used or not */
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500125 uint8_t is_used : 1;
Jukka Rissanen4b9d9802018-08-10 17:21:08 +0300126
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500127 uint8_t _unused : 6;
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200128};
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200129
130/**
131 * @brief Information about routers in the system.
132 *
133 * Stores the router information.
134 */
135struct net_if_router {
Tomasz Bursztykaeccc2682019-05-22 12:04:04 +0200136 /** Slist lifetime timer node */
137 sys_snode_t node;
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200138
139 /** IP address */
140 struct net_addr address;
141
Jukka Rissanenf8c94392017-04-12 22:54:08 +0300142 /** Network interface the router is connected to */
143 struct net_if *iface;
144
Tomasz Bursztykaeccc2682019-05-22 12:04:04 +0200145 /** Router life timer start */
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500146 uint32_t life_start;
Tomasz Bursztykaeccc2682019-05-22 12:04:04 +0200147
148 /** Router lifetime */
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500149 uint16_t lifetime;
Tomasz Bursztykaeccc2682019-05-22 12:04:04 +0200150
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200151 /** Is this router used or not */
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500152 uint8_t is_used : 1;
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200153
154 /** Is default router */
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500155 uint8_t is_default : 1;
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200156
157 /** Is the router valid forever */
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500158 uint8_t is_infinite : 1;
Jukka Rissanen4b9d9802018-08-10 17:21:08 +0300159
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500160 uint8_t _unused : 5;
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200161};
162
Jukka Rissanen712103d2019-04-16 10:55:34 +0300163enum net_if_flag {
Jukka Rissanenb1bfb632019-02-19 16:37:27 +0200164 /** Interface is up/ready to receive and transmit */
Luiz Augusto von Dentzbf4fb512016-12-19 14:18:10 +0200165 NET_IF_UP,
166
Jukka Rissanenb1bfb632019-02-19 16:37:27 +0200167 /** Interface is pointopoint */
Luiz Augusto von Dentz2c1bef42017-02-02 11:58:15 +0200168 NET_IF_POINTOPOINT,
169
Jukka Rissanenb1bfb632019-02-19 16:37:27 +0200170 /** Interface is in promiscuous mode */
Jukka Rissanenb19cb202018-07-20 16:42:54 +0300171 NET_IF_PROMISC,
172
Jukka Rissanen36339512019-04-16 10:55:57 +0300173 /** Do not start the interface immediately after initialization.
174 * This requires that either the device driver or some other entity
175 * will need to manually take the interface up when needed.
176 * For example for Ethernet this will happen when the driver calls
177 * the net_eth_carrier_on() function.
178 */
179 NET_IF_NO_AUTO_START,
180
Tomasz Bursztyka80917ec2020-02-25 09:42:35 +0100181 /** Power management specific: interface is being suspended */
182 NET_IF_SUSPENDED,
183
Jan Georgi5931a292020-08-17 15:24:46 +0200184 /** Flag defines if received multicasts of other interface are
185 * forwarded on this interface. This activates multicast
186 * routing / forwarding for this interface.
187 */
188 NET_IF_FORWARD_MULTICASTS,
189
Jukka Rissanenb1bfb632019-02-19 16:37:27 +0200190/** @cond INTERNAL_HIDDEN */
Luiz Augusto von Dentzbf4fb512016-12-19 14:18:10 +0200191 /* Total number of flags - must be at the end of the enum */
192 NET_IF_NUM_FLAGS
Jukka Rissanenb1bfb632019-02-19 16:37:27 +0200193/** @endcond */
Luiz Augusto von Dentzbf4fb512016-12-19 14:18:10 +0200194};
195
Gil Pitney3209c222017-03-09 05:43:01 -0800196#if defined(CONFIG_NET_OFFLOAD)
Gil Pitney657ad142017-03-09 06:08:19 -0800197struct net_offload;
Gil Pitney3209c222017-03-09 05:43:01 -0800198#endif /* CONFIG_NET_OFFLOAD */
199
Jukka Rissanenb288a9d2019-02-14 16:12:24 +0200200/** @cond INTERNAL_HIDDEN */
Jukka Rissanen6cf1da42019-08-09 14:49:35 +0300201#if defined(CONFIG_NET_NATIVE_IPV6)
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200202#define NET_IF_MAX_IPV6_ADDR CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT
203#define NET_IF_MAX_IPV6_MADDR CONFIG_NET_IF_MCAST_IPV6_ADDR_COUNT
204#define NET_IF_MAX_IPV6_PREFIX CONFIG_NET_IF_IPV6_PREFIX_COUNT
Jukka Rissanen2808b232018-11-05 13:22:14 +0200205#else
206#define NET_IF_MAX_IPV6_ADDR 0
207#define NET_IF_MAX_IPV6_MADDR 0
208#define NET_IF_MAX_IPV6_PREFIX 0
209#endif
Jukka Rissanenb288a9d2019-02-14 16:12:24 +0200210/* @endcond */
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200211
212struct net_if_ipv6 {
213 /** Unicast IP addresses */
214 struct net_if_addr unicast[NET_IF_MAX_IPV6_ADDR];
215
216 /** Multicast IP addresses */
217 struct net_if_mcast_addr mcast[NET_IF_MAX_IPV6_MADDR];
218
219 /** Prefixes */
220 struct net_if_ipv6_prefix prefix[NET_IF_MAX_IPV6_PREFIX];
221
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200222 /** Default reachable time (RFC 4861, page 52) */
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500223 uint32_t base_reachable_time;
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200224
225 /** Reachable time (RFC 4861, page 20) */
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500226 uint32_t reachable_time;
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200227
228 /** Retransmit timer (RFC 4861, page 52) */
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500229 uint32_t retrans_timer;
Jukka Rissanen6cf1da42019-08-09 14:49:35 +0300230#if defined(CONFIG_NET_IPV6_ND) && defined(CONFIG_NET_NATIVE_IPV6)
Tomasz Bursztykab5bcd252019-05-21 12:07:08 +0200231 /** Router solicitation timer node */
232 sys_snode_t rs_node;
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200233
Tomasz Bursztykab5bcd252019-05-21 12:07:08 +0200234 /* RS start time */
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500235 uint32_t rs_start;
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200236
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200237 /** RS count */
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500238 uint8_t rs_count;
Tomasz Bursztykab5bcd252019-05-21 12:07:08 +0200239#endif
240
241 /** IPv6 hop limit */
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500242 uint8_t hop_limit;
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200243};
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200244
Jukka Rissanenb288a9d2019-02-14 16:12:24 +0200245/** @cond INTERNAL_HIDDEN */
Jukka Rissanen6cf1da42019-08-09 14:49:35 +0300246#if defined(CONFIG_NET_NATIVE_IPV4)
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200247#define NET_IF_MAX_IPV4_ADDR CONFIG_NET_IF_UNICAST_IPV4_ADDR_COUNT
248#define NET_IF_MAX_IPV4_MADDR CONFIG_NET_IF_MCAST_IPV4_ADDR_COUNT
Jukka Rissanenaa5f2192018-11-05 16:07:48 +0200249#else
250#define NET_IF_MAX_IPV4_ADDR 0
251#define NET_IF_MAX_IPV4_MADDR 0
252#endif
Jukka Rissanenb288a9d2019-02-14 16:12:24 +0200253/** @endcond */
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200254
255struct net_if_ipv4 {
256 /** Unicast IP addresses */
257 struct net_if_addr unicast[NET_IF_MAX_IPV4_ADDR];
258
259 /** Multicast IP addresses */
260 struct net_if_mcast_addr mcast[NET_IF_MAX_IPV4_MADDR];
261
262 /** Gateway */
263 struct in_addr gw;
264
265 /** Netmask */
266 struct in_addr netmask;
267
268 /** IPv4 time-to-live */
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500269 uint8_t ttl;
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200270};
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200271
Jukka Rissanen6cf1da42019-08-09 14:49:35 +0300272#if defined(CONFIG_NET_DHCPV4) && defined(CONFIG_NET_NATIVE_IPV4)
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200273struct net_if_dhcpv4 {
Tomasz Bursztyka2ba28dd2018-07-25 13:55:01 +0200274 /** Used for timer lists */
275 sys_snode_t node;
276
277 /** Timer start */
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500278 int64_t timer_start;
Tomasz Bursztyka2ba28dd2018-07-25 13:55:01 +0200279
280 /** Time for INIT, DISCOVER, REQUESTING, RENEWAL */
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500281 uint32_t request_time;
Tomasz Bursztyka2ba28dd2018-07-25 13:55:01 +0200282
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500283 uint32_t xid;
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200284
285 /** IP address Lease time */
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500286 uint32_t lease_time;
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200287
288 /** IP address Renewal time */
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500289 uint32_t renewal_time;
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200290
291 /** IP address Rebinding time */
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500292 uint32_t rebinding_time;
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200293
294 /** Server ID */
295 struct in_addr server_id;
296
297 /** Requested IP addr */
298 struct in_addr requested_ip;
299
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200300 /**
301 * DHCPv4 client state in the process of network
302 * address allocation.
303 */
304 enum net_dhcpv4_state state;
305
306 /** Number of attempts made for REQUEST and RENEWAL messages */
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500307 uint8_t attempts;
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200308};
309#endif /* CONFIG_NET_DHCPV4 */
310
Jukka Rissanen6cf1da42019-08-09 14:49:35 +0300311#if defined(CONFIG_NET_IPV4_AUTO) && defined(CONFIG_NET_NATIVE_IPV4)
Jukka Rissanen00e37cb2018-07-30 18:28:35 +0300312struct net_if_ipv4_autoconf {
313 /** Used for timer lists */
314 sys_snode_t node;
315
316 /** Backpointer to correct network interface */
317 struct net_if *iface;
318
319 /** Timer start */
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500320 int64_t timer_start;
Jukka Rissanen00e37cb2018-07-30 18:28:35 +0300321
322 /** Time for INIT, DISCOVER, REQUESTING, RENEWAL */
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500323 uint32_t timer_timeout;
Jukka Rissanen00e37cb2018-07-30 18:28:35 +0300324
325 /** Current IP addr */
326 struct in_addr current_ip;
327
328 /** Requested IP addr */
329 struct in_addr requested_ip;
330
331 /** IPV4 Autoconf state in the process of network address allocation.
332 */
333 enum net_ipv4_autoconf_state state;
334
335 /** Number of sent probe requests */
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500336 uint8_t probe_cnt;
Jukka Rissanen00e37cb2018-07-30 18:28:35 +0300337
338 /** Number of sent announcements */
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500339 uint8_t announce_cnt;
Jukka Rissanen00e37cb2018-07-30 18:28:35 +0300340
341 /** Incoming conflict count */
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500342 uint8_t conflict_cnt;
Jukka Rissanen00e37cb2018-07-30 18:28:35 +0300343};
344#endif /* CONFIG_NET_IPV4_AUTO */
345
Jukka Rissanenb1bfb632019-02-19 16:37:27 +0200346/** @cond INTERNAL_HIDDEN */
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200347/* We always need to have at least one IP config */
348#define NET_IF_MAX_CONFIGS 1
Jukka Rissanenb1bfb632019-02-19 16:37:27 +0200349/** @endcond */
Gil Pitney3209c222017-03-09 05:43:01 -0800350
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200351/**
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200352 * @brief Network interface IP address configuration.
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200353 */
354struct net_if_ip {
Jukka Rissanen6cf1da42019-08-09 14:49:35 +0300355#if defined(CONFIG_NET_NATIVE_IPV6)
Jukka Rissanenca8b00a2018-01-19 19:01:23 +0200356 struct net_if_ipv6 *ipv6;
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200357#endif /* CONFIG_NET_IPV6 */
358
Jukka Rissanen6cf1da42019-08-09 14:49:35 +0300359#if defined(CONFIG_NET_NATIVE_IPV4)
Jukka Rissanenca8b00a2018-01-19 19:01:23 +0200360 struct net_if_ipv4 *ipv4;
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200361#endif /* CONFIG_NET_IPV4 */
362};
363
364/**
365 * @brief IP and other configuration related data for network interface.
366 */
367struct net_if_config {
368 /** IP address configuration setting */
369 struct net_if_ip ip;
370
Jukka Rissanen6cf1da42019-08-09 14:49:35 +0300371#if defined(CONFIG_NET_DHCPV4) && defined(CONFIG_NET_NATIVE_IPV4)
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200372 struct net_if_dhcpv4 dhcpv4;
373#endif /* CONFIG_NET_DHCPV4 */
Jukka Rissanen00e37cb2018-07-30 18:28:35 +0300374
Jukka Rissanen6cf1da42019-08-09 14:49:35 +0300375#if defined(CONFIG_NET_IPV4_AUTO) && defined(CONFIG_NET_NATIVE_IPV4)
Jukka Rissanen00e37cb2018-07-30 18:28:35 +0300376 struct net_if_ipv4_autoconf ipv4auto;
377#endif /* CONFIG_NET_IPV4_AUTO */
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200378};
379
380/**
Jukka Rissanen60492072018-02-07 15:00:08 +0200381 * @brief Network traffic class.
382 *
383 * Traffic classes are used when sending or receiving data that is classified
384 * with different priorities. So some traffic can be marked as high priority
385 * and it will be sent or received first. There is always at least one work
386 * queue in the system for Rx and Tx. Each network packet that is transmitted
387 * or received goes through a work queue thread that will transmit it.
388 */
389struct net_traffic_class {
390 /** Work queue for handling this Tx or Rx packet */
391 struct k_work_q work_q;
392
393 /** Stack for this work queue */
394 k_thread_stack_t *stack;
Jukka Rissanen60492072018-02-07 15:00:08 +0200395};
396
397/**
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200398 * @brief Network Interface Device structure
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200399 *
400 * Used to handle a network interface on top of a device driver instance.
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200401 * There can be many net_if_dev instance against the same device.
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200402 *
403 * Such interface is mainly to be used by the link layer, but is also tight
404 * to a network context: it then makes the relation with a network context
405 * and the network device.
406 *
407 * Because of the strong relationship between a device driver and such
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200408 * network interface, each net_if_dev should be instantiated by
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200409 */
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200410struct net_if_dev {
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200411 /** The actually device driver instance the net_if is related to */
Tomasz Bursztykae18fcbb2020-04-30 20:33:38 +0200412 const struct device *dev;
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200413
414 /** Interface's L2 layer */
Tomasz Bursztykaf0f9be82017-02-14 12:47:42 +0100415 const struct net_l2 * const l2;
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200416
417 /** Interface's private L2 data pointer */
418 void *l2_data;
419
Jukka Rissanenf8c94392017-04-12 22:54:08 +0300420 /* For internal use */
421 ATOMIC_DEFINE(flags, NET_IF_NUM_FLAGS);
422
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200423 /** The hardware link address */
424 struct net_linkaddr link_addr;
425
Gil Pitney3209c222017-03-09 05:43:01 -0800426#if defined(CONFIG_NET_OFFLOAD)
427 /** TCP/IP Offload functions.
428 * If non-NULL, then the TCP/IP stack is located
429 * in the communication chip that is accessed via this
430 * network interface.
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200431 */
Gil Pitney657ad142017-03-09 06:08:19 -0800432 struct net_offload *offload;
Gil Pitney3209c222017-03-09 05:43:01 -0800433#endif /* CONFIG_NET_OFFLOAD */
Jukka Rissanen9b8c83f2018-07-25 13:22:49 +0300434
435 /** The hardware MTU */
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500436 uint16_t mtu;
Robert Lubos047969c2019-10-14 16:08:18 +0200437
438#if defined(CONFIG_NET_SOCKETS_OFFLOAD)
439 /** Indicate whether interface is offloaded at socket level. */
440 bool offloaded;
441#endif /* CONFIG_NET_SOCKETS_OFFLOAD */
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200442};
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200443
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200444/**
445 * @brief Network Interface structure
446 *
447 * Used to handle a network interface on top of a net_if_dev instance.
448 * There can be many net_if instance against the same net_if_dev instance.
449 *
450 */
451struct net_if {
452 /** The net_if_dev instance the net_if is related to */
453 struct net_if_dev *if_dev;
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200454
Jukka Rissanen1443ff02018-03-27 11:31:31 +0300455#if defined(CONFIG_NET_STATISTICS_PER_INTERFACE)
456 /** Network statistics related to this network interface */
457 struct net_stats stats;
458#endif /* CONFIG_NET_STATISTICS_PER_INTERFACE */
459
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200460 /** Network interface instance configuration */
461 struct net_if_config config;
Jukka Rissanendee07c92020-03-19 18:48:50 +0200462
463#if defined(CONFIG_NET_POWER_MANAGEMENT)
464 /** Keep track of packets pending in traffic queues. This is
465 * needed to avoid putting network device driver to sleep if
466 * there are packets waiting to be sent.
467 */
468 int tx_pending;
469#endif
Jukka Rissanen4746a132020-06-23 00:37:45 +0300470};
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200471
472/**
Jukka Rissanen712103d2019-04-16 10:55:34 +0300473 * @brief Set a value in network interface flags
474 *
475 * @param iface Pointer to network interface
476 * @param value Flag value
477 */
478static inline void net_if_flag_set(struct net_if *iface,
479 enum net_if_flag value)
480{
481 NET_ASSERT(iface);
482
483 atomic_set_bit(iface->if_dev->flags, value);
484}
485
486/**
487 * @brief Test and set a value in network interface flags
488 *
489 * @param iface Pointer to network interface
490 * @param value Flag value
491 *
492 * @return true if the bit was set, false if it wasn't.
493 */
494static inline bool net_if_flag_test_and_set(struct net_if *iface,
495 enum net_if_flag value)
496{
497 NET_ASSERT(iface);
498
499 return atomic_test_and_set_bit(iface->if_dev->flags, value);
500}
501
502/**
503 * @brief Clear a value in network interface flags
504 *
505 * @param iface Pointer to network interface
506 * @param value Flag value
507 */
508static inline void net_if_flag_clear(struct net_if *iface,
509 enum net_if_flag value)
510{
511 NET_ASSERT(iface);
512
513 atomic_clear_bit(iface->if_dev->flags, value);
514}
515
516/**
517 * @brief Check if a value in network interface flags is set
518 *
519 * @param iface Pointer to network interface
520 * @param value Flag value
521 *
522 * @return True if the value is set, false otherwise
523 */
524static inline bool net_if_flag_is_set(struct net_if *iface,
525 enum net_if_flag value)
526{
527 NET_ASSERT(iface);
528
529 return atomic_test_bit(iface->if_dev->flags, value);
530}
531
532/**
Tomasz Bursztykadb11fcd2017-04-05 08:37:44 +0200533 * @brief Send a packet through a net iface
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200534 *
535 * @param iface Pointer to a network interface structure
Paul Sokolovsky29d9f952017-05-11 15:19:24 +0300536 * @param pkt Pointer to a net packet to send
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200537 *
538 * return verdict about the packet
539 */
Tomasz Bursztykadb11fcd2017-04-05 08:37:44 +0200540enum net_verdict net_if_send_data(struct net_if *iface, struct net_pkt *pkt);
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200541
542/**
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200543 * @brief Get a pointer to the interface L2
544 *
545 * @param iface a valid pointer to a network interface structure
546 *
547 * @return a pointer to the iface L2
548 */
549static inline const struct net_l2 * const net_if_l2(struct net_if *iface)
550{
Michael Scott407ceee2020-01-24 11:41:54 -0800551 if (!iface || !iface->if_dev) {
Jukka Rissanen971ae592019-10-29 12:25:30 +0200552 return NULL;
553 }
554
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200555 return iface->if_dev->l2;
556}
557
558/**
Tomasz Bursztykadb11fcd2017-04-05 08:37:44 +0200559 * @brief Input a packet through a net iface
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200560 *
561 * @param iface Pointer to a network interface structure
Paul Sokolovsky29d9f952017-05-11 15:19:24 +0300562 * @param pkt Pointer to a net packet to input
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200563 *
564 * @return verdict about the packet
565 */
Jukka Rissanen3f9c7bd2018-07-23 14:03:11 +0300566enum net_verdict net_if_recv_data(struct net_if *iface, struct net_pkt *pkt);
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200567
568/**
Paul Sokolovsky29d9f952017-05-11 15:19:24 +0300569 * @brief Get a pointer to the interface L2 private data
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200570 *
571 * @param iface a valid pointer to a network interface structure
572 *
Paul Sokolovsky29d9f952017-05-11 15:19:24 +0300573 * @return a pointer to the iface L2 data
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200574 */
575static inline void *net_if_l2_data(struct net_if *iface)
576{
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200577 return iface->if_dev->l2_data;
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200578}
579
580/**
581 * @brief Get an network interface's device
582 *
583 * @param iface Pointer to a network interface structure
584 *
Paul Sokolovsky29d9f952017-05-11 15:19:24 +0300585 * @return a pointer to the device driver instance
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200586 */
Tomasz Bursztykae18fcbb2020-04-30 20:33:38 +0200587static inline const struct device *net_if_get_device(struct net_if *iface)
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200588{
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200589 return iface->if_dev->dev;
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200590}
591
592/**
Paul Sokolovsky29d9f952017-05-11 15:19:24 +0300593 * @brief Queue a packet to the net interface TX queue
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200594 *
595 * @param iface Pointer to a network interface structure
Paul Sokolovsky29d9f952017-05-11 15:19:24 +0300596 * @param pkt Pointer to a net packet to queue
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200597 */
Jukka Rissanen60492072018-02-07 15:00:08 +0200598void net_if_queue_tx(struct net_if *iface, struct net_pkt *pkt);
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200599
600/**
Paul Sokolovsky29d9f952017-05-11 15:19:24 +0300601 * @brief Return the IP offload status
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200602 *
603 * @param iface Network interface
604 *
605 * @return True if IP offlining is active, false otherwise.
606 */
Jukka Rissanen82616a62019-02-22 11:11:22 +0200607static inline bool net_if_is_ip_offloaded(struct net_if *iface)
608{
Jukka Rissanenef7081e2019-02-14 15:33:22 +0200609#if defined(CONFIG_NET_OFFLOAD)
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200610 return (iface->if_dev->offload != NULL);
Jukka Rissanenef7081e2019-02-14 15:33:22 +0200611#else
Jukka Rissanenef7081e2019-02-14 15:33:22 +0200612 ARG_UNUSED(iface);
613
614 return false;
Jukka Rissanenef7081e2019-02-14 15:33:22 +0200615#endif
Jukka Rissanen82616a62019-02-22 11:11:22 +0200616}
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200617
618/**
619 * @brief Return the IP offload plugin
620 *
621 * @param iface Network interface
622 *
623 * @return NULL if there is no offload plugin defined, valid pointer otherwise
624 */
625static inline struct net_offload *net_if_offload(struct net_if *iface)
626{
Jukka Rissanen82616a62019-02-22 11:11:22 +0200627#if defined(CONFIG_NET_OFFLOAD)
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200628 return iface->if_dev->offload;
Jukka Rissanen82616a62019-02-22 11:11:22 +0200629#else
630 return NULL;
Gil Pitney3209c222017-03-09 05:43:01 -0800631#endif
Jukka Rissanen82616a62019-02-22 11:11:22 +0200632}
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200633
634/**
Robert Lubos047969c2019-10-14 16:08:18 +0200635 * @brief Return the socket offload status
636 *
637 * @param iface Network interface
638 *
639 * @return True if socket offloading is active, false otherwise.
640 */
641static inline bool net_if_is_socket_offloaded(struct net_if *iface)
642{
643#if defined(CONFIG_NET_SOCKETS_OFFLOAD)
644 return iface->if_dev->offloaded;
645#else
646 ARG_UNUSED(iface);
647
648 return false;
649#endif
650}
651
652/**
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200653 * @brief Get an network interface's link address
654 *
655 * @param iface Pointer to a network interface structure
656 *
Paul Sokolovsky29d9f952017-05-11 15:19:24 +0300657 * @return a pointer to the network link address
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200658 */
659static inline struct net_linkaddr *net_if_get_link_addr(struct net_if *iface)
660{
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200661 return &iface->if_dev->link_addr;
662}
663
664/**
665 * @brief Return network configuration for this network interface
666 *
667 * @param iface Pointer to a network interface structure
668 *
669 * @return Pointer to configuration
670 */
671static inline struct net_if_config *net_if_get_config(struct net_if *iface)
672{
673 return &iface->config;
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200674}
675
676/**
677 * @brief Start duplicate address detection procedure.
678 *
679 * @param iface Pointer to a network interface structure
680 */
Jukka Rissanen6cf1da42019-08-09 14:49:35 +0300681#if defined(CONFIG_NET_IPV6_DAD) && defined(CONFIG_NET_NATIVE_IPV6)
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200682void net_if_start_dad(struct net_if *iface);
683#else
Tomasz Bursztyka6a513e42019-05-20 15:46:14 +0200684static inline void net_if_start_dad(struct net_if *iface)
685{
686 ARG_UNUSED(iface);
687}
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200688#endif
689
690/**
691 * @brief Start neighbor discovery and send router solicitation message.
692 *
693 * @param iface Pointer to a network interface structure
694 */
695void net_if_start_rs(struct net_if *iface);
696
Tomasz Bursztykab5bcd252019-05-21 12:07:08 +0200697
698/**
699 * @brief Stop neighbor discovery.
700 *
701 * @param iface Pointer to a network interface structure
702 */
Jukka Rissanen6cf1da42019-08-09 14:49:35 +0300703#if defined(CONFIG_NET_IPV6_ND) && defined(CONFIG_NET_NATIVE_IPV6)
Tomasz Bursztykab5bcd252019-05-21 12:07:08 +0200704void net_if_stop_rs(struct net_if *iface);
705#else
706static inline void net_if_stop_rs(struct net_if *iface)
707{
708 ARG_UNUSED(iface);
709}
710#endif /* CONFIG_NET_IPV6_ND */
711
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200712/**
713 * @brief Set a network interface's link address
714 *
715 * @param iface Pointer to a network interface structure
Jukka Rissanen34ddb8c2020-08-21 13:27:39 +0300716 * @param addr A pointer to a uint8_t buffer representing the address.
717 * The buffer must remain valid throughout interface lifetime.
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200718 * @param len length of the address buffer
Jukka Rissanen4eb20202017-02-15 13:20:31 +0200719 * @param type network bearer type of this link address
Luiz Augusto von Dentzbf4fb512016-12-19 14:18:10 +0200720 *
721 * @return 0 on success
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200722 */
Luiz Augusto von Dentzbf4fb512016-12-19 14:18:10 +0200723static inline int net_if_set_link_addr(struct net_if *iface,
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500724 uint8_t *addr, uint8_t len,
Jukka Rissanen4eb20202017-02-15 13:20:31 +0200725 enum net_link_type type)
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200726{
Jukka Rissanen712103d2019-04-16 10:55:34 +0300727 if (net_if_flag_is_set(iface, NET_IF_UP)) {
Luiz Augusto von Dentzbf4fb512016-12-19 14:18:10 +0200728 return -EPERM;
729 }
730
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200731 net_if_get_link_addr(iface)->addr = addr;
732 net_if_get_link_addr(iface)->len = len;
733 net_if_get_link_addr(iface)->type = type;
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200734
Jukka Rissanene3adbf82017-09-21 23:30:32 +0300735 net_hostname_set_postfix(addr, len);
736
Luiz Augusto von Dentzbf4fb512016-12-19 14:18:10 +0200737 return 0;
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200738}
739
740/**
741 * @brief Get an network interface's MTU
742 *
743 * @param iface Pointer to a network interface structure
744 *
745 * @return the MTU
746 */
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500747static inline uint16_t net_if_get_mtu(struct net_if *iface)
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200748{
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200749 return iface->if_dev->mtu;
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200750}
751
752/**
753 * @brief Set an network interface's MTU
754 *
755 * @param iface Pointer to a network interface structure
756 * @param mtu New MTU, note that we store only 16 bit mtu value.
757 */
758static inline void net_if_set_mtu(struct net_if *iface,
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500759 uint16_t mtu)
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200760{
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200761 iface->if_dev->mtu = mtu;
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200762}
763
764/**
765 * @brief Set the infinite status of the network interface address
766 *
767 * @param ifaddr IP address for network interface
768 * @param is_infinite Infinite status
769 */
770static inline void net_if_addr_set_lf(struct net_if_addr *ifaddr,
771 bool is_infinite)
772{
773 ifaddr->is_infinite = is_infinite;
774}
775
776/**
777 * @brief Get an interface according to link layer address.
778 *
779 * @param ll_addr Link layer address.
780 *
781 * @return Network interface or NULL if not found.
782 */
783struct net_if *net_if_get_by_link_addr(struct net_linkaddr *ll_addr);
784
785/**
786 * @brief Find an interface from it's related device
787 *
788 * @param dev A valid struct device pointer to relate with an interface
789 *
790 * @return a valid struct net_if pointer on success, NULL otherwise
791 */
Tomasz Bursztykae18fcbb2020-04-30 20:33:38 +0200792struct net_if *net_if_lookup_by_dev(const struct device *dev);
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200793
794/**
Jukka Rissanen47dafff2018-01-11 16:06:53 +0200795 * @brief Get network interface IP config
796 *
797 * @param iface Interface to use.
798 *
799 * @return NULL if not found or pointer to correct config settings.
800 */
801static inline struct net_if_config *net_if_config_get(struct net_if *iface)
802{
803 return &iface->config;
804}
805
806/**
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200807 * @brief Remove a router from the system
808 *
809 * @param router Pointer to existing router
810 */
811static inline void net_if_router_rm(struct net_if_router *router)
812{
813 router->is_used = false;
814
815 /* FIXME - remove timer */
816}
817
818/**
819 * @brief Get the default network interface.
820 *
821 * @return Default interface or NULL if no interfaces are configured.
822 */
823struct net_if *net_if_get_default(void);
824
Jukka Rissanenf6661512017-08-08 08:38:47 +0300825/**
826 * @brief Get the first network interface according to its type.
827 *
828 * @param l2 Layer 2 type of the network interface.
829 *
830 * @return First network interface of a given type or NULL if no such
831 * interfaces was found.
832 */
833struct net_if *net_if_get_first_by_type(const struct net_l2 *l2);
834
Jukka Rissanen53928aa2017-08-08 12:05:49 +0300835#if defined(CONFIG_NET_L2_IEEE802154)
836/**
837 * @brief Get the first IEEE 802.15.4 network interface.
838 *
839 * @return First IEEE 802.15.4 network interface or NULL if no such
840 * interfaces was found.
841 */
842static inline struct net_if *net_if_get_ieee802154(void)
843{
844 return net_if_get_first_by_type(&NET_L2_GET_NAME(IEEE802154));
845}
846#endif /* CONFIG_NET_L2_IEEE802154 */
847
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200848/**
Jukka Rissanenca8b00a2018-01-19 19:01:23 +0200849 * @brief Allocate network interface IPv6 config.
850 *
851 * @details This function will allocate new IPv6 config.
852 *
853 * @param iface Interface to use.
854 * @param ipv6 Pointer to allocated IPv6 struct is returned to caller.
855 *
856 * @return 0 if ok, <0 if error
857 */
858int net_if_config_ipv6_get(struct net_if *iface,
859 struct net_if_ipv6 **ipv6);
860
861/**
862 * @brief Release network interface IPv6 config.
863 *
864 * @param iface Interface to use.
865 *
866 * @return 0 if ok, <0 if error
867 */
868int net_if_config_ipv6_put(struct net_if *iface);
869
870/**
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200871 * @brief Check if this IPv6 address belongs to one of the interfaces.
872 *
873 * @param addr IPv6 address
874 * @param iface Pointer to interface is returned
875 *
876 * @return Pointer to interface address, NULL if not found.
877 */
878struct net_if_addr *net_if_ipv6_addr_lookup(const struct in6_addr *addr,
879 struct net_if **iface);
880
881/**
882 * @brief Check if this IPv6 address belongs to this specific interfaces.
883 *
884 * @param iface Network interface
885 * @param addr IPv6 address
886 *
887 * @return Pointer to interface address, NULL if not found.
888 */
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200889struct net_if_addr *net_if_ipv6_addr_lookup_by_iface(struct net_if *iface,
Jukka Rissanenf39ff762018-08-07 12:57:21 +0300890 struct in6_addr *addr);
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200891
892/**
Jukka Rissanen041cd5f2019-05-29 11:43:13 +0800893 * @brief Check if this IPv6 address belongs to one of the interface indices.
894 *
895 * @param addr IPv6 address
896 *
897 * @return >0 if address was found in given network interface index,
898 * all other values mean address was not found
899 */
900__syscall int net_if_ipv6_addr_lookup_by_index(const struct in6_addr *addr);
901
902/**
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200903 * @brief Add a IPv6 address to an interface
904 *
905 * @param iface Network interface
906 * @param addr IPv6 address
907 * @param addr_type IPv6 address type
908 * @param vlifetime Validity time for this address
909 *
910 * @return Pointer to interface address, NULL if cannot be added
911 */
912struct net_if_addr *net_if_ipv6_addr_add(struct net_if *iface,
913 struct in6_addr *addr,
914 enum net_addr_type addr_type,
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500915 uint32_t vlifetime);
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200916
917/**
Jukka Rissanen041cd5f2019-05-29 11:43:13 +0800918 * @brief Add a IPv6 address to an interface by index
919 *
920 * @param index Network interface index
921 * @param addr IPv6 address
922 * @param addr_type IPv6 address type
923 * @param vlifetime Validity time for this address
924 *
925 * @return True if ok, false if address could not be added
926 */
927__syscall bool net_if_ipv6_addr_add_by_index(int index,
928 struct in6_addr *addr,
929 enum net_addr_type addr_type,
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500930 uint32_t vlifetime);
Jukka Rissanen041cd5f2019-05-29 11:43:13 +0800931
932/**
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200933 * @brief Update validity lifetime time of an IPv6 address.
934 *
935 * @param ifaddr Network IPv6 address
936 * @param vlifetime Validity time for this address
937 */
938void net_if_ipv6_addr_update_lifetime(struct net_if_addr *ifaddr,
Kumar Galaa1b77fd2020-05-27 11:26:57 -0500939 uint32_t vlifetime);
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200940
941/**
942 * @brief Remove an IPv6 address from an interface
943 *
944 * @param iface Network interface
945 * @param addr IPv6 address
946 *
947 * @return True if successfully removed, false otherwise
948 */
Jukka Rissanen528a3932017-04-12 10:34:59 +0300949bool net_if_ipv6_addr_rm(struct net_if *iface, const struct in6_addr *addr);
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200950
Jukka Rissanen041cd5f2019-05-29 11:43:13 +0800951/**
952 * @brief Remove an IPv6 address from an interface by index
953 *
954 * @param index Network interface index
955 * @param addr IPv6 address
956 *
957 * @return True if successfully removed, false otherwise
958 */
959__syscall bool net_if_ipv6_addr_rm_by_index(int index,
960 const struct in6_addr *addr);
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200961
962/**
963 * @brief Add a IPv6 multicast address to an interface
964 *
965 * @param iface Network interface
966 * @param addr IPv6 multicast address
967 *
968 * @return Pointer to interface multicast address, NULL if cannot be added
969 */
970struct net_if_mcast_addr *net_if_ipv6_maddr_add(struct net_if *iface,
Jukka Rissanenc3573492017-02-09 09:48:31 +0200971 const struct in6_addr *addr);
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200972
973/**
974 * @brief Remove an IPv6 multicast address from an interface
975 *
976 * @param iface Network interface
977 * @param addr IPv6 multicast address
978 *
979 * @return True if successfully removed, false otherwise
980 */
Jukka Rissanenc3573492017-02-09 09:48:31 +0200981bool net_if_ipv6_maddr_rm(struct net_if *iface, const struct in6_addr *addr);
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200982
983/**
Jukka Rissanenc3b0f352017-02-09 09:50:50 +0200984 * @brief Check if this IPv6 multicast address belongs to a specific interface
985 * or one of the interfaces.
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200986 *
987 * @param addr IPv6 address
Jukka Rissanenc3b0f352017-02-09 09:50:50 +0200988 * @param iface If *iface is null, then pointer to interface is returned,
989 * otherwise the *iface value needs to be matched.
Jukka Rissanen68ea9372016-11-12 00:13:24 +0200990 *
991 * @return Pointer to interface multicast address, NULL if not found.
992 */
993struct net_if_mcast_addr *net_if_ipv6_maddr_lookup(const struct in6_addr *addr,
994 struct net_if **iface);
995
996/**
Jukka Rissanen93d2df62017-08-29 09:57:27 +0300997 * @typedef net_if_mcast_callback_t
998
999 * @brief Define callback that is called whenever IPv6 multicast address group
1000 * is joined or left.
1001
1002 * @param "struct net_if *iface" A pointer to a struct net_if to which the
1003 * multicast address is attached.
1004 * @param "const struct in6_addr *addr" IPv6 multicast address.
1005 * @param "bool is_joined" True if the address is joined, false if left.
1006 */
1007typedef void (*net_if_mcast_callback_t)(struct net_if *iface,
1008 const struct in6_addr *addr,
1009 bool is_joined);
1010
1011/**
1012 * @brief Multicast monitor handler struct.
1013 *
1014 * Stores the multicast callback information. Caller must make sure that
1015 * the variable pointed by this is valid during the lifetime of
1016 * registration. Typically this means that the variable cannot be
1017 * allocated from stack.
1018 */
1019struct net_if_mcast_monitor {
1020 /** Node information for the slist. */
1021 sys_snode_t node;
1022
1023 /** Network interface */
1024 struct net_if *iface;
1025
1026 /** Multicast callback */
1027 net_if_mcast_callback_t cb;
1028};
1029
1030/**
1031 * @brief Register a multicast monitor
1032 *
1033 * @param mon Monitor handle. This is a pointer to a monitor storage structure
1034 * which should be allocated by caller, but does not need to be initialized.
1035 * @param iface Network interface
1036 * @param cb Monitor callback
1037 */
1038void net_if_mcast_mon_register(struct net_if_mcast_monitor *mon,
1039 struct net_if *iface,
1040 net_if_mcast_callback_t cb);
1041
1042/**
1043 * @brief Unregister a multicast monitor
1044 *
1045 * @param mon Monitor handle
1046 */
1047void net_if_mcast_mon_unregister(struct net_if_mcast_monitor *mon);
1048
1049/**
1050 * @brief Call registered multicast monitors
1051 *
1052 * @param iface Network interface
1053 * @param addr Multicast address
1054 * @param is_joined Is this multicast address joined (true) or not (false)
1055 */
1056void net_if_mcast_monitor(struct net_if *iface, const struct in6_addr *addr,
1057 bool is_joined);
1058
1059/**
Jukka Rissanenf8467432017-02-10 09:36:09 +02001060 * @brief Mark a given multicast address to be joined.
1061 *
1062 * @param addr IPv6 multicast address
1063 */
1064static inline void net_if_ipv6_maddr_join(struct net_if_mcast_addr *addr)
1065{
1066 NET_ASSERT(addr);
1067
1068 addr->is_joined = true;
1069}
1070
1071/**
Jukka Rissanen82267e72017-02-10 09:45:32 +02001072 * @brief Check if given multicast address is joined or not.
1073 *
1074 * @param addr IPv6 multicast address
1075 *
1076 * @return True if address is joined, False otherwise.
1077 */
1078static inline bool net_if_ipv6_maddr_is_joined(struct net_if_mcast_addr *addr)
1079{
1080 NET_ASSERT(addr);
1081
1082 return addr->is_joined;
1083}
1084
1085/**
Jukka Rissanenf8467432017-02-10 09:36:09 +02001086 * @brief Mark a given multicast address to be left.
1087 *
1088 * @param addr IPv6 multicast address
1089 */
1090static inline void net_if_ipv6_maddr_leave(struct net_if_mcast_addr *addr)
1091{
1092 NET_ASSERT(addr);
1093
1094 addr->is_joined = false;
1095}
1096
1097/**
Jukka Rissanen3f4d4682018-08-22 12:41:30 +03001098 * @brief Return prefix that corresponds to this IPv6 address.
1099 *
1100 * @param iface Network interface
1101 * @param addr IPv6 address
1102 *
1103 * @return Pointer to prefix, NULL if not found.
1104 */
1105struct net_if_ipv6_prefix *net_if_ipv6_prefix_get(struct net_if *iface,
1106 struct in6_addr *addr);
1107
1108/**
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001109 * @brief Check if this IPv6 prefix belongs to this interface
1110 *
1111 * @param iface Network interface
1112 * @param addr IPv6 address
1113 * @param len Prefix length
1114 *
1115 * @return Pointer to prefix, NULL if not found.
1116 */
1117struct net_if_ipv6_prefix *net_if_ipv6_prefix_lookup(struct net_if *iface,
1118 struct in6_addr *addr,
Kumar Galaa1b77fd2020-05-27 11:26:57 -05001119 uint8_t len);
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001120
1121/**
1122 * @brief Add a IPv6 prefix to an network interface.
1123 *
1124 * @param iface Network interface
1125 * @param prefix IPv6 address
1126 * @param len Prefix length
1127 * @param lifetime Prefix lifetime in seconds
1128 *
1129 * @return Pointer to prefix, NULL if the prefix was not added.
1130 */
1131struct net_if_ipv6_prefix *net_if_ipv6_prefix_add(struct net_if *iface,
1132 struct in6_addr *prefix,
Kumar Galaa1b77fd2020-05-27 11:26:57 -05001133 uint8_t len,
1134 uint32_t lifetime);
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001135
1136/**
1137 * @brief Remove an IPv6 prefix from an interface
1138 *
1139 * @param iface Network interface
1140 * @param addr IPv6 prefix address
1141 * @param len Prefix length
1142 *
1143 * @return True if successfully removed, false otherwise
1144 */
1145bool net_if_ipv6_prefix_rm(struct net_if *iface, struct in6_addr *addr,
Kumar Galaa1b77fd2020-05-27 11:26:57 -05001146 uint8_t len);
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001147
1148/**
1149 * @brief Set the infinite status of the prefix
1150 *
1151 * @param prefix IPv6 address
1152 * @param is_infinite Infinite status
1153 */
1154static inline void net_if_ipv6_prefix_set_lf(struct net_if_ipv6_prefix *prefix,
1155 bool is_infinite)
1156{
1157 prefix->is_infinite = is_infinite;
1158}
1159
1160/**
1161 * @brief Set the prefix lifetime timer.
1162 *
1163 * @param prefix IPv6 address
1164 * @param lifetime Prefix lifetime in seconds
1165 */
1166void net_if_ipv6_prefix_set_timer(struct net_if_ipv6_prefix *prefix,
Kumar Galaa1b77fd2020-05-27 11:26:57 -05001167 uint32_t lifetime);
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001168
1169/**
1170 * @brief Unset the prefix lifetime timer.
1171 *
1172 * @param prefix IPv6 address
1173 */
1174void net_if_ipv6_prefix_unset_timer(struct net_if_ipv6_prefix *prefix);
1175
1176/**
1177 * @brief Check if this IPv6 address is part of the subnet of our
1178 * network interface.
1179 *
1180 * @param iface Network interface. This is returned to the caller.
1181 * The iface can be NULL in which case we check all the interfaces.
1182 * @param addr IPv6 address
1183 *
1184 * @return True if address is part of our subnet, false otherwise
1185 */
1186bool net_if_ipv6_addr_onlink(struct net_if **iface, struct in6_addr *addr);
1187
1188/**
Tomasz Bursztykaeccc2682019-05-22 12:04:04 +02001189 * @brief Get the IPv6 address of the given router
1190 * @param router a network router
1191 *
1192 * @return pointer to the IPv6 address, or NULL if none
1193 */
Jukka Rissanen6cf1da42019-08-09 14:49:35 +03001194#if defined(CONFIG_NET_NATIVE_IPV6)
Tomasz Bursztykaeccc2682019-05-22 12:04:04 +02001195static inline struct in6_addr *net_if_router_ipv6(struct net_if_router *router)
1196{
1197 return &router->address.in6_addr;
1198}
1199#else
1200static inline struct in6_addr *net_if_router_ipv6(struct net_if_router *router)
1201{
1202 static struct in6_addr addr;
1203
1204 ARG_UNUSED(router);
1205
1206 return &addr;
1207}
1208#endif
1209
1210/**
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001211 * @brief Check if IPv6 address is one of the routers configured
1212 * in the system.
1213 *
1214 * @param iface Network interface
1215 * @param addr IPv6 address
1216 *
1217 * @return Pointer to router information, NULL if cannot be found
1218 */
1219struct net_if_router *net_if_ipv6_router_lookup(struct net_if *iface,
1220 struct in6_addr *addr);
1221
1222/**
1223 * @brief Find default router for this IPv6 address.
1224 *
1225 * @param iface Network interface. This can be NULL in which case we
1226 * go through all the network interfaces to find a suitable router.
1227 * @param addr IPv6 address
1228 *
1229 * @return Pointer to router information, NULL if cannot be found
1230 */
1231struct net_if_router *net_if_ipv6_router_find_default(struct net_if *iface,
1232 struct in6_addr *addr);
1233
1234/**
1235 * @brief Update validity lifetime time of a router.
1236 *
1237 * @param router Network IPv6 address
1238 * @param lifetime Lifetime of this router.
1239 */
1240void net_if_ipv6_router_update_lifetime(struct net_if_router *router,
Kumar Galaa1b77fd2020-05-27 11:26:57 -05001241 uint16_t lifetime);
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001242
1243/**
1244 * @brief Add IPv6 router to the system.
1245 *
1246 * @param iface Network interface
1247 * @param addr IPv6 address
1248 * @param router_lifetime Lifetime of the router
1249 *
1250 * @return Pointer to router information, NULL if could not be added
1251 */
1252struct net_if_router *net_if_ipv6_router_add(struct net_if *iface,
1253 struct in6_addr *addr,
Kumar Galaa1b77fd2020-05-27 11:26:57 -05001254 uint16_t router_lifetime);
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001255
1256/**
1257 * @brief Remove IPv6 router from the system.
1258 *
1259 * @param router Router information.
1260 *
1261 * @return True if successfully removed, false otherwise
1262 */
1263bool net_if_ipv6_router_rm(struct net_if_router *router);
1264
1265/**
Jukka Rissanen42bd36e2017-04-11 10:21:48 +03001266 * @brief Get IPv6 hop limit specified for a given interface. This is the
1267 * default value but can be overridden by the user.
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001268 *
1269 * @param iface Network interface
1270 *
1271 * @return Hop limit
1272 */
Kumar Galaa1b77fd2020-05-27 11:26:57 -05001273static inline uint8_t net_if_ipv6_get_hop_limit(struct net_if *iface)
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001274{
Jukka Rissanen6cf1da42019-08-09 14:49:35 +03001275#if defined(CONFIG_NET_NATIVE_IPV6)
Jukka Rissanenca8b00a2018-01-19 19:01:23 +02001276 if (!iface->config.ip.ipv6) {
1277 return 0;
1278 }
Jukka Rissanen47dafff2018-01-11 16:06:53 +02001279
Jukka Rissanenca8b00a2018-01-19 19:01:23 +02001280 return iface->config.ip.ipv6->hop_limit;
Jukka Rissanen2808b232018-11-05 13:22:14 +02001281#else
1282 return 0;
1283#endif
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001284}
1285
1286/**
Jukka Rissanen42bd36e2017-04-11 10:21:48 +03001287 * @brief Set the default IPv6 hop limit of a given interface.
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001288 *
1289 * @param iface Network interface
1290 * @param hop_limit New hop limit
1291 */
1292static inline void net_ipv6_set_hop_limit(struct net_if *iface,
Kumar Galaa1b77fd2020-05-27 11:26:57 -05001293 uint8_t hop_limit)
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001294{
Jukka Rissanen6cf1da42019-08-09 14:49:35 +03001295#if defined(CONFIG_NET_NATIVE_IPV6)
Jukka Rissanenca8b00a2018-01-19 19:01:23 +02001296 if (!iface->config.ip.ipv6) {
1297 return;
1298 }
Jukka Rissanen47dafff2018-01-11 16:06:53 +02001299
Jukka Rissanenca8b00a2018-01-19 19:01:23 +02001300 iface->config.ip.ipv6->hop_limit = hop_limit;
Jukka Rissanen2808b232018-11-05 13:22:14 +02001301#endif
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001302}
1303
1304/**
1305 * @brief Set IPv6 reachable time for a given interface
1306 *
1307 * @param iface Network interface
1308 * @param reachable_time New reachable time
1309 */
1310static inline void net_if_ipv6_set_base_reachable_time(struct net_if *iface,
Kumar Galaa1b77fd2020-05-27 11:26:57 -05001311 uint32_t reachable_time)
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001312{
Jukka Rissanen6cf1da42019-08-09 14:49:35 +03001313#if defined(CONFIG_NET_NATIVE_IPV6)
Jukka Rissanenca8b00a2018-01-19 19:01:23 +02001314 if (!iface->config.ip.ipv6) {
1315 return;
1316 }
Jukka Rissanen47dafff2018-01-11 16:06:53 +02001317
Jukka Rissanenca8b00a2018-01-19 19:01:23 +02001318 iface->config.ip.ipv6->base_reachable_time = reachable_time;
Jukka Rissanen2808b232018-11-05 13:22:14 +02001319#endif
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001320}
1321
1322/**
1323 * @brief Get IPv6 reachable timeout specified for a given interface
1324 *
1325 * @param iface Network interface
1326 *
1327 * @return Reachable timeout
1328 */
Kumar Galaa1b77fd2020-05-27 11:26:57 -05001329static inline uint32_t net_if_ipv6_get_reachable_time(struct net_if *iface)
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001330{
Jukka Rissanen6cf1da42019-08-09 14:49:35 +03001331#if defined(CONFIG_NET_NATIVE_IPV6)
Jukka Rissanenca8b00a2018-01-19 19:01:23 +02001332 if (!iface->config.ip.ipv6) {
1333 return 0;
1334 }
Jukka Rissanen47dafff2018-01-11 16:06:53 +02001335
Jukka Rissanenca8b00a2018-01-19 19:01:23 +02001336 return iface->config.ip.ipv6->reachable_time;
Jukka Rissanen2808b232018-11-05 13:22:14 +02001337#else
1338 return 0;
1339#endif
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001340}
1341
1342/**
1343 * @brief Calculate next reachable time value for IPv6 reachable time
1344 *
Jukka Rissanenca8b00a2018-01-19 19:01:23 +02001345 * @param ipv6 IPv6 address configuration
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001346 *
1347 * @return Reachable time
1348 */
Kumar Galaa1b77fd2020-05-27 11:26:57 -05001349uint32_t net_if_ipv6_calc_reachable_time(struct net_if_ipv6 *ipv6);
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001350
1351/**
1352 * @brief Set IPv6 reachable time for a given interface. This requires
1353 * that base reachable time is set for the interface.
1354 *
Jukka Rissanenca8b00a2018-01-19 19:01:23 +02001355 * @param ipv6 IPv6 address configuration
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001356 */
Jukka Rissanenca8b00a2018-01-19 19:01:23 +02001357static inline void net_if_ipv6_set_reachable_time(struct net_if_ipv6 *ipv6)
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001358{
Jukka Rissanen6cf1da42019-08-09 14:49:35 +03001359#if defined(CONFIG_NET_NATIVE_IPV6)
Jukka Rissanenca8b00a2018-01-19 19:01:23 +02001360 ipv6->reachable_time = net_if_ipv6_calc_reachable_time(ipv6);
Jukka Rissanen2808b232018-11-05 13:22:14 +02001361#endif
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001362}
1363
1364/**
1365 * @brief Set IPv6 retransmit timer for a given interface
1366 *
1367 * @param iface Network interface
1368 * @param retrans_timer New retransmit timer
1369 */
1370static inline void net_if_ipv6_set_retrans_timer(struct net_if *iface,
Kumar Galaa1b77fd2020-05-27 11:26:57 -05001371 uint32_t retrans_timer)
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001372{
Jukka Rissanen6cf1da42019-08-09 14:49:35 +03001373#if defined(CONFIG_NET_NATIVE_IPV6)
Jukka Rissanenca8b00a2018-01-19 19:01:23 +02001374 if (!iface->config.ip.ipv6) {
1375 return;
1376 }
Jukka Rissanen47dafff2018-01-11 16:06:53 +02001377
Jukka Rissanenca8b00a2018-01-19 19:01:23 +02001378 iface->config.ip.ipv6->retrans_timer = retrans_timer;
Jukka Rissanen2808b232018-11-05 13:22:14 +02001379#endif
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001380}
1381
1382/**
1383 * @brief Get IPv6 retransmit timer specified for a given interface
1384 *
1385 * @param iface Network interface
1386 *
1387 * @return Retransmit timer
1388 */
Kumar Galaa1b77fd2020-05-27 11:26:57 -05001389static inline uint32_t net_if_ipv6_get_retrans_timer(struct net_if *iface)
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001390{
Jukka Rissanen6cf1da42019-08-09 14:49:35 +03001391#if defined(CONFIG_NET_NATIVE_IPV6)
Jukka Rissanenca8b00a2018-01-19 19:01:23 +02001392 if (!iface->config.ip.ipv6) {
1393 return 0;
1394 }
Jukka Rissanen47dafff2018-01-11 16:06:53 +02001395
Jukka Rissanenca8b00a2018-01-19 19:01:23 +02001396 return iface->config.ip.ipv6->retrans_timer;
Jukka Rissanen2808b232018-11-05 13:22:14 +02001397#else
1398 return 0;
1399#endif
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001400}
1401
1402/**
1403 * @brief Get a IPv6 source address that should be used when sending
1404 * network data to destination.
1405 *
1406 * @param iface Interface that was used when packet was received.
1407 * If the interface is not known, then NULL can be given.
1408 * @param dst IPv6 destination address
1409 *
1410 * @return Pointer to IPv6 address to use, NULL if no IPv6 address
1411 * could be found.
1412 */
Jukka Rissanen6cf1da42019-08-09 14:49:35 +03001413#if defined(CONFIG_NET_NATIVE_IPV6)
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001414const struct in6_addr *net_if_ipv6_select_src_addr(struct net_if *iface,
Jukka Rissanene812b682018-12-07 15:15:31 +02001415 const struct in6_addr *dst);
Jukka Rissanen6cf1da42019-08-09 14:49:35 +03001416#else
1417static inline const struct in6_addr *net_if_ipv6_select_src_addr(
1418 struct net_if *iface, const struct in6_addr *dst)
1419{
1420 ARG_UNUSED(iface);
1421 ARG_UNUSED(dst);
1422
1423 return NULL;
1424}
1425#endif
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001426
1427/**
Jukka Rissanenb8fdf3c2018-08-07 11:28:49 +03001428 * @brief Get a network interface that should be used when sending
1429 * IPv6 network data to destination.
1430 *
1431 * @param dst IPv6 destination address
1432 *
1433 * @return Pointer to network interface to use, NULL if no suitable interface
1434 * could be found.
1435 */
Jukka Rissanen6cf1da42019-08-09 14:49:35 +03001436#if defined(CONFIG_NET_NATIVE_IPV6)
Jukka Rissanene812b682018-12-07 15:15:31 +02001437struct net_if *net_if_ipv6_select_src_iface(const struct in6_addr *dst);
Jukka Rissanen6cf1da42019-08-09 14:49:35 +03001438#else
1439static inline struct net_if *net_if_ipv6_select_src_iface(
1440 const struct in6_addr *dst)
1441{
1442 ARG_UNUSED(dst);
1443
1444 return NULL;
1445}
1446#endif
Jukka Rissanenb8fdf3c2018-08-07 11:28:49 +03001447
1448/**
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001449 * @brief Get a IPv6 link local address in a given state.
1450 *
1451 * @param iface Interface to use. Must be a valid pointer to an interface.
1452 * @param addr_state IPv6 address state (preferred, tentative, deprecated)
1453 *
1454 * @return Pointer to link local IPv6 address, NULL if no proper IPv6 address
1455 * could be found.
1456 */
1457struct in6_addr *net_if_ipv6_get_ll(struct net_if *iface,
1458 enum net_addr_state addr_state);
1459
1460/**
1461 * @brief Return link local IPv6 address from the first interface that has
1462 * a link local address matching give state.
1463 *
1464 * @param state IPv6 address state (ANY, TENTATIVE, PREFERRED, DEPRECATED)
1465 * @param iface Pointer to interface is returned
1466 *
1467 * @return Pointer to IPv6 address, NULL if not found.
1468 */
1469struct in6_addr *net_if_ipv6_get_ll_addr(enum net_addr_state state,
1470 struct net_if **iface);
1471
1472/**
Jukka Rissanen57e12862017-04-12 10:25:54 +03001473 * @brief Stop IPv6 Duplicate Address Detection (DAD) procedure if
1474 * we find out that our IPv6 address is already in use.
1475 *
1476 * @param iface Interface where the DAD was running.
1477 * @param addr IPv6 address that failed DAD
1478 */
1479void net_if_ipv6_dad_failed(struct net_if *iface, const struct in6_addr *addr);
1480
1481/**
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001482 * @brief Return global IPv6 address from the first interface that has
Tomasz Bursztyka979aedf2019-05-14 14:41:56 +02001483 * a global IPv6 address matching the given state.
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001484 *
Tomasz Bursztyka979aedf2019-05-14 14:41:56 +02001485 * @param state IPv6 address state (ANY, TENTATIVE, PREFERRED, DEPRECATED)
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001486 * @param iface Caller can give an interface to check. If iface is set to NULL,
1487 * then all the interfaces are checked. Pointer to interface where the IPv6
1488 * address is defined is returned to the caller.
1489 *
1490 * @return Pointer to IPv6 address, NULL if not found.
1491 */
Tomasz Bursztyka979aedf2019-05-14 14:41:56 +02001492struct in6_addr *net_if_ipv6_get_global_addr(enum net_addr_state state,
1493 struct net_if **iface);
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001494
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001495/**
Jukka Rissanenca8b00a2018-01-19 19:01:23 +02001496 * @brief Allocate network interface IPv4 config.
1497 *
1498 * @details This function will allocate new IPv4 config.
1499 *
1500 * @param iface Interface to use.
1501 * @param ipv4 Pointer to allocated IPv4 struct is returned to caller.
1502 *
1503 * @return 0 if ok, <0 if error
1504 */
1505int net_if_config_ipv4_get(struct net_if *iface,
1506 struct net_if_ipv4 **ipv4);
1507
1508/**
1509 * @brief Release network interface IPv4 config.
1510 *
1511 * @param iface Interface to use.
1512 *
1513 * @return 0 if ok, <0 if error
1514 */
1515int net_if_config_ipv4_put(struct net_if *iface);
1516
1517/**
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001518 * @brief Get IPv4 time-to-live value specified for a given interface
1519 *
1520 * @param iface Network interface
1521 *
1522 * @return Time-to-live
1523 */
Kumar Galaa1b77fd2020-05-27 11:26:57 -05001524static inline uint8_t net_if_ipv4_get_ttl(struct net_if *iface)
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001525{
Jukka Rissanen6cf1da42019-08-09 14:49:35 +03001526#if defined(CONFIG_NET_NATIVE_IPV4)
Jukka Rissanenca8b00a2018-01-19 19:01:23 +02001527 if (!iface->config.ip.ipv4) {
1528 return 0;
1529 }
Jukka Rissanen47dafff2018-01-11 16:06:53 +02001530
Jukka Rissanenca8b00a2018-01-19 19:01:23 +02001531 return iface->config.ip.ipv4->ttl;
Jukka Rissanenaa5f2192018-11-05 16:07:48 +02001532#else
1533 return 0;
1534#endif
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001535}
1536
1537/**
1538 * @brief Check if this IPv4 address belongs to one of the interfaces.
1539 *
1540 * @param addr IPv4 address
1541 * @param iface Interface is returned
1542 *
1543 * @return Pointer to interface address, NULL if not found.
1544 */
1545struct net_if_addr *net_if_ipv4_addr_lookup(const struct in_addr *addr,
1546 struct net_if **iface);
1547
1548/**
1549 * @brief Add a IPv4 address to an interface
1550 *
1551 * @param iface Network interface
1552 * @param addr IPv4 address
1553 * @param addr_type IPv4 address type
1554 * @param vlifetime Validity time for this address
1555 *
1556 * @return Pointer to interface address, NULL if cannot be added
1557 */
1558struct net_if_addr *net_if_ipv4_addr_add(struct net_if *iface,
1559 struct in_addr *addr,
1560 enum net_addr_type addr_type,
Kumar Galaa1b77fd2020-05-27 11:26:57 -05001561 uint32_t vlifetime);
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001562
1563/**
1564 * @brief Remove a IPv4 address from an interface
1565 *
1566 * @param iface Network interface
1567 * @param addr IPv4 address
1568 *
1569 * @return True if successfully removed, false otherwise
1570 */
Jukka Rissanen10189332019-05-29 13:03:34 +08001571bool net_if_ipv4_addr_rm(struct net_if *iface, const struct in_addr *addr);
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001572
Jukka Rissanend14919c2017-09-21 23:06:59 +03001573/**
Jukka Rissanen041cd5f2019-05-29 11:43:13 +08001574 * @brief Check if this IPv4 address belongs to one of the interface indices.
1575 *
1576 * @param addr IPv4 address
1577 *
1578 * @return >0 if address was found in given network interface index,
1579 * all other values mean address was not found
1580 */
1581__syscall int net_if_ipv4_addr_lookup_by_index(const struct in_addr *addr);
1582
1583/**
1584 * @brief Add a IPv4 address to an interface by network interface index
1585 *
1586 * @param index Network interface index
1587 * @param addr IPv4 address
1588 * @param addr_type IPv4 address type
1589 * @param vlifetime Validity time for this address
1590 *
1591 * @return True if ok, false if the address could not be added
1592 */
1593__syscall bool net_if_ipv4_addr_add_by_index(int index,
1594 struct in_addr *addr,
1595 enum net_addr_type addr_type,
Kumar Galaa1b77fd2020-05-27 11:26:57 -05001596 uint32_t vlifetime);
Jukka Rissanen041cd5f2019-05-29 11:43:13 +08001597
1598/**
1599 * @brief Remove a IPv4 address from an interface by interface index
1600 *
1601 * @param index Network interface index
1602 * @param addr IPv4 address
1603 *
1604 * @return True if successfully removed, false otherwise
1605 */
1606__syscall bool net_if_ipv4_addr_rm_by_index(int index,
1607 const struct in_addr *addr);
1608
1609/**
Jukka Rissanend14919c2017-09-21 23:06:59 +03001610 * @brief Add a IPv4 multicast address to an interface
1611 *
1612 * @param iface Network interface
1613 * @param addr IPv4 multicast address
1614 *
1615 * @return Pointer to interface multicast address, NULL if cannot be added
1616 */
1617struct net_if_mcast_addr *net_if_ipv4_maddr_add(struct net_if *iface,
1618 const struct in_addr *addr);
1619
1620/**
1621 * @brief Remove an IPv4 multicast address from an interface
1622 *
1623 * @param iface Network interface
1624 * @param addr IPv4 multicast address
1625 *
1626 * @return True if successfully removed, false otherwise
1627 */
1628bool net_if_ipv4_maddr_rm(struct net_if *iface, const struct in_addr *addr);
1629
1630/**
1631 * @brief Check if this IPv4 multicast address belongs to a specific interface
1632 * or one of the interfaces.
1633 *
1634 * @param addr IPv4 address
1635 * @param iface If *iface is null, then pointer to interface is returned,
1636 * otherwise the *iface value needs to be matched.
1637 *
1638 * @return Pointer to interface multicast address, NULL if not found.
1639 */
1640struct net_if_mcast_addr *net_if_ipv4_maddr_lookup(const struct in_addr *addr,
1641 struct net_if **iface);
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001642
1643/**
Tomasz Bursztykaeccc2682019-05-22 12:04:04 +02001644 * @brief Get the IPv4 address of the given router
1645 * @param router a network router
1646 *
1647 * @return pointer to the IPv4 address, or NULL if none
1648 */
Jukka Rissanen6cf1da42019-08-09 14:49:35 +03001649#if defined(CONFIG_NET_NATIVE_IPV4)
Tomasz Bursztykaeccc2682019-05-22 12:04:04 +02001650static inline struct in_addr *net_if_router_ipv4(struct net_if_router *router)
1651{
1652 return &router->address.in_addr;
1653}
1654#else
1655static inline struct in_addr *net_if_router_ipv4(struct net_if_router *router)
1656{
1657 static struct in_addr addr;
1658
1659 ARG_UNUSED(router);
1660
1661 return &addr;
1662}
1663#endif
1664
1665/**
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001666 * @brief Check if IPv4 address is one of the routers configured
1667 * in the system.
1668 *
1669 * @param iface Network interface
1670 * @param addr IPv4 address
1671 *
1672 * @return Pointer to router information, NULL if cannot be found
1673 */
1674struct net_if_router *net_if_ipv4_router_lookup(struct net_if *iface,
1675 struct in_addr *addr);
1676
1677/**
Tomasz Bursztykad80d1812019-05-22 19:41:04 +02001678 * @brief Find default router for this IPv4 address.
1679 *
1680 * @param iface Network interface. This can be NULL in which case we
1681 * go through all the network interfaces to find a suitable router.
1682 * @param addr IPv4 address
1683 *
1684 * @return Pointer to router information, NULL if cannot be found
1685 */
1686struct net_if_router *net_if_ipv4_router_find_default(struct net_if *iface,
1687 struct in_addr *addr);
1688/**
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001689 * @brief Add IPv4 router to the system.
1690 *
1691 * @param iface Network interface
1692 * @param addr IPv4 address
1693 * @param is_default Is this router the default one
1694 * @param router_lifetime Lifetime of the router
1695 *
1696 * @return Pointer to router information, NULL if could not be added
1697 */
1698struct net_if_router *net_if_ipv4_router_add(struct net_if *iface,
1699 struct in_addr *addr,
1700 bool is_default,
Kumar Galaa1b77fd2020-05-27 11:26:57 -05001701 uint16_t router_lifetime);
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001702
1703/**
Tomasz Bursztykad80d1812019-05-22 19:41:04 +02001704 * @brief Remove IPv4 router from the system.
1705 *
1706 * @param router Router information.
1707 *
1708 * @return True if successfully removed, false otherwise
1709 */
1710bool net_if_ipv4_router_rm(struct net_if_router *router);
1711
1712/**
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001713 * @brief Check if the given IPv4 address belongs to local subnet.
1714 *
1715 * @param iface Interface to use. Must be a valid pointer to an interface.
1716 * @param addr IPv4 address
1717 *
1718 * @return True if address is part of local subnet, false otherwise.
1719 */
1720bool net_if_ipv4_addr_mask_cmp(struct net_if *iface,
Jukka Rissanen5f668522018-10-23 17:43:22 +03001721 const struct in_addr *addr);
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001722
1723/**
Jukka Rissanenaa2240a2018-10-23 17:49:32 +03001724 * @brief Check if the given IPv4 address is a broadcast address.
1725 *
1726 * @param iface Interface to use. Must be a valid pointer to an interface.
1727 * @param addr IPv4 address, this should be in network byte order
1728 *
1729 * @return True if address is a broadcast address, false otherwise.
1730 */
1731bool net_if_ipv4_is_addr_bcast(struct net_if *iface,
1732 const struct in_addr *addr);
1733
1734/**
Jukka Rissanenda8af392018-01-31 16:09:38 +02001735 * @brief Get a network interface that should be used when sending
1736 * IPv4 network data to destination.
1737 *
1738 * @param dst IPv4 destination address
1739 *
1740 * @return Pointer to network interface to use, NULL if no suitable interface
1741 * could be found.
1742 */
Jukka Rissanen6cf1da42019-08-09 14:49:35 +03001743#if defined(CONFIG_NET_NATIVE_IPV4)
Jukka Rissanene812b682018-12-07 15:15:31 +02001744struct net_if *net_if_ipv4_select_src_iface(const struct in_addr *dst);
Jukka Rissanen6cf1da42019-08-09 14:49:35 +03001745#else
1746static inline struct net_if *net_if_ipv4_select_src_iface(
1747 const struct in_addr *dst)
1748{
1749 ARG_UNUSED(dst);
1750
1751 return NULL;
1752}
1753#endif
Jukka Rissanenda8af392018-01-31 16:09:38 +02001754
1755/**
Jukka Rissanen12855782018-04-27 13:01:33 +03001756 * @brief Get a IPv4 source address that should be used when sending
1757 * network data to destination.
1758 *
1759 * @param iface Interface to use when sending the packet.
1760 * If the interface is not known, then NULL can be given.
1761 * @param dst IPv4 destination address
1762 *
1763 * @return Pointer to IPv4 address to use, NULL if no IPv4 address
1764 * could be found.
1765 */
Jukka Rissanen6cf1da42019-08-09 14:49:35 +03001766#if defined(CONFIG_NET_NATIVE_IPV4)
Jukka Rissanenaa5f2192018-11-05 16:07:48 +02001767const struct in_addr *net_if_ipv4_select_src_addr(struct net_if *iface,
Jukka Rissanene812b682018-12-07 15:15:31 +02001768 const struct in_addr *dst);
Jukka Rissanen6cf1da42019-08-09 14:49:35 +03001769#else
1770static inline const struct in_addr *net_if_ipv4_select_src_addr(
1771 struct net_if *iface, const struct in_addr *dst)
1772{
1773 ARG_UNUSED(iface);
1774 ARG_UNUSED(dst);
1775
1776 return NULL;
1777}
1778#endif
Jukka Rissanen12855782018-04-27 13:01:33 +03001779
1780/**
1781 * @brief Get a IPv4 link local address in a given state.
1782 *
1783 * @param iface Interface to use. Must be a valid pointer to an interface.
1784 * @param addr_state IPv4 address state (preferred, tentative, deprecated)
1785 *
1786 * @return Pointer to link local IPv4 address, NULL if no proper IPv4 address
1787 * could be found.
1788 */
1789struct in_addr *net_if_ipv4_get_ll(struct net_if *iface,
1790 enum net_addr_state addr_state);
1791
1792/**
Tomasz Bursztyka426764e2019-05-14 14:49:25 +02001793 * @brief Get a IPv4 global address in a given state.
1794 *
1795 * @param iface Interface to use. Must be a valid pointer to an interface.
1796 * @param addr_state IPv4 address state (preferred, tentative, deprecated)
1797 *
1798 * @return Pointer to link local IPv4 address, NULL if no proper IPv4 address
1799 * could be found.
1800 */
1801struct in_addr *net_if_ipv4_get_global_addr(struct net_if *iface,
1802 enum net_addr_state addr_state);
1803
1804/**
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001805 * @brief Set IPv4 netmask for an interface.
1806 *
1807 * @param iface Interface to use.
1808 * @param netmask IPv4 netmask
1809 */
Jukka Rissanen813ae632019-06-19 11:23:10 +03001810void net_if_ipv4_set_netmask(struct net_if *iface,
1811 const struct in_addr *netmask);
Jukka Rissanen47dafff2018-01-11 16:06:53 +02001812
Jukka Rissanen813ae632019-06-19 11:23:10 +03001813/**
1814 * @brief Set IPv4 netmask for an interface index.
1815 *
1816 * @param index Network interface index
1817 * @param netmask IPv4 netmask
1818 *
1819 * @return True if netmask was added, false otherwise.
1820 */
1821__syscall bool net_if_ipv4_set_netmask_by_index(int index,
1822 const struct in_addr *netmask);
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001823
1824/**
1825 * @brief Set IPv4 gateway for an interface.
1826 *
1827 * @param iface Interface to use.
1828 * @param gw IPv4 address of an gateway
1829 */
Jukka Rissanen766ad9f2019-06-19 11:36:16 +03001830void net_if_ipv4_set_gw(struct net_if *iface, const struct in_addr *gw);
Jukka Rissanen47dafff2018-01-11 16:06:53 +02001831
Jukka Rissanen70639212019-06-19 11:35:05 +03001832/**
1833 * @brief Set IPv4 gateway for an interface index.
1834 *
1835 * @param index Network interface index
1836 * @param gw IPv4 address of an gateway
1837 *
1838 * @return True if gateway was added, false otherwise.
1839 */
1840__syscall bool net_if_ipv4_set_gw_by_index(int index, const struct in_addr *gw);
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001841
1842/**
Jukka Rissanend0205692018-08-07 13:05:55 +03001843 * @brief Get a network interface that should be used when sending
1844 * IPv6 or IPv4 network data to destination.
1845 *
1846 * @param dst IPv6 or IPv4 destination address
1847 *
1848 * @return Pointer to network interface to use. Note that the function
1849 * will return the default network interface if the best network interface
1850 * is not found.
1851 */
1852struct net_if *net_if_select_src_iface(const struct sockaddr *dst);
1853
1854/**
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001855 * @typedef net_if_link_callback_t
1856 * @brief Define callback that is called after a network packet
1857 * has been sent.
Paul Sokolovsky29d9f952017-05-11 15:19:24 +03001858 * @param "struct net_if *iface" A pointer to a struct net_if to which the
Tomasz Bursztykadb11fcd2017-04-05 08:37:44 +02001859 * the net_pkt was sent to.
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001860 * @param "struct net_linkaddr *dst" Link layer address of the destination
1861 * where the network packet was sent.
1862 * @param "int status" Send status, 0 is ok, < 0 error.
1863 */
1864typedef void (*net_if_link_callback_t)(struct net_if *iface,
1865 struct net_linkaddr *dst,
1866 int status);
1867
1868/**
1869 * @brief Link callback handler struct.
1870 *
1871 * Stores the link callback information. Caller must make sure that
1872 * the variable pointed by this is valid during the lifetime of
1873 * registration. Typically this means that the variable cannot be
1874 * allocated from stack.
1875 */
1876struct net_if_link_cb {
1877 /** Node information for the slist. */
1878 sys_snode_t node;
1879
1880 /** Link callback */
1881 net_if_link_callback_t cb;
1882};
1883
1884/**
1885 * @brief Register a link callback.
1886 *
1887 * @param link Caller specified handler for the callback.
1888 * @param cb Callback to register.
1889 */
1890void net_if_register_link_cb(struct net_if_link_cb *link,
1891 net_if_link_callback_t cb);
1892
1893/**
1894 * @brief Unregister a link callback.
1895 *
1896 * @param link Caller specified handler for the callback.
1897 */
1898void net_if_unregister_link_cb(struct net_if_link_cb *link);
1899
1900/**
1901 * @brief Call a link callback function.
1902 *
1903 * @param iface Network interface.
1904 * @param lladdr Destination link layer address
1905 * @param status 0 is ok, < 0 error
1906 */
1907void net_if_call_link_cb(struct net_if *iface, struct net_linkaddr *lladdr,
1908 int status);
1909
1910/**
Jukka Rissanen85a24592018-03-14 10:55:19 +02001911 * @brief Check if received network packet checksum calculation can be avoided
1912 * or not. For example many ethernet devices support network packet offloading
1913 * in which case the IP stack does not need to calculate the checksum.
1914 *
1915 * @param iface Network interface
1916 *
1917 * @return True if checksum needs to be calculated, false otherwise.
1918 */
1919bool net_if_need_calc_rx_checksum(struct net_if *iface);
1920
1921/**
1922 * @brief Check if network packet checksum calculation can be avoided or not
1923 * when sending the packet. For example many ethernet devices support network
1924 * packet offloading in which case the IP stack does not need to calculate the
1925 * checksum.
1926 *
1927 * @param iface Network interface
1928 *
1929 * @return True if checksum needs to be calculated, false otherwise.
1930 */
1931bool net_if_need_calc_tx_checksum(struct net_if *iface);
1932
1933/**
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001934 * @brief Get interface according to index
1935 *
Jukka Rissanen336bcfa2020-06-18 19:05:12 +03001936 * @details This is a syscall only to provide access to the object for purposes
1937 * of assigning permissions.
1938 *
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001939 * @param index Interface index
1940 *
1941 * @return Pointer to interface or NULL if not found.
1942 */
Jukka Rissanen336bcfa2020-06-18 19:05:12 +03001943__syscall struct net_if *net_if_get_by_index(int index);
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001944
1945/**
1946 * @brief Get interface index according to pointer
1947 *
1948 * @param iface Pointer to network interface
1949 *
1950 * @return Interface index
1951 */
Jukka Rissanen32065682019-02-14 11:37:23 +02001952int net_if_get_by_iface(struct net_if *iface);
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001953
Tomasz Bursztykad8323e12017-01-06 14:10:06 +01001954/**
1955 * @typedef net_if_cb_t
1956 * @brief Callback used while iterating over network interfaces
1957 *
1958 * @param iface Pointer to current network interface
Paul Sokolovsky29d9f952017-05-11 15:19:24 +03001959 * @param user_data A valid pointer to user data or NULL
Tomasz Bursztykad8323e12017-01-06 14:10:06 +01001960 */
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001961typedef void (*net_if_cb_t)(struct net_if *iface, void *user_data);
1962
1963/**
1964 * @brief Go through all the network interfaces and call callback
1965 * for each interface.
1966 *
David B. Kinder2c850d72017-08-10 08:21:28 -07001967 * @param cb User-supplied callback function to call
Paul Sokolovsky29d9f952017-05-11 15:19:24 +03001968 * @param user_data User specified data
Jukka Rissanen68ea9372016-11-12 00:13:24 +02001969 */
1970void net_if_foreach(net_if_cb_t cb, void *user_data);
1971
Luiz Augusto von Dentzbf4fb512016-12-19 14:18:10 +02001972/**
1973 * @brief Bring interface up
1974 *
1975 * @param iface Pointer to network interface
1976 *
1977 * @return 0 on success
1978 */
1979int net_if_up(struct net_if *iface);
1980
Marcus Shawcroftf9980772017-02-23 22:13:18 +00001981/**
Jukka Rissanenf8c5f692017-07-27 14:35:17 +03001982 * @brief Check if interface is up.
1983 *
1984 * @param iface Pointer to network interface
1985 *
1986 * @return True if interface is up, False if it is down.
1987 */
1988static inline bool net_if_is_up(struct net_if *iface)
1989{
1990 NET_ASSERT(iface);
1991
Jukka Rissanen712103d2019-04-16 10:55:34 +03001992 return net_if_flag_is_set(iface, NET_IF_UP);
Jukka Rissanenf8c5f692017-07-27 14:35:17 +03001993}
1994
1995/**
Luiz Augusto von Dentzbf4fb512016-12-19 14:18:10 +02001996 * @brief Bring interface down
1997 *
1998 * @param iface Pointer to network interface
1999 *
2000 * @return 0 on success
2001 */
2002int net_if_down(struct net_if *iface);
2003
Jukka Rissanen6cf1da42019-08-09 14:49:35 +03002004#if defined(CONFIG_NET_PKT_TIMESTAMP) && defined(CONFIG_NET_NATIVE)
Jukka Rissanen580596c2018-01-24 15:20:21 +02002005/**
2006 * @typedef net_if_timestamp_callback_t
2007 * @brief Define callback that is called after a network packet
2008 * has been timestamped.
2009 * @param "struct net_pkt *pkt" A pointer on a struct net_pkt which has
2010 * been timestamped after being sent.
2011 */
2012typedef void (*net_if_timestamp_callback_t)(struct net_pkt *pkt);
2013
2014/**
2015 * @brief Timestamp callback handler struct.
2016 *
2017 * Stores the timestamp callback information. Caller must make sure that
2018 * the variable pointed by this is valid during the lifetime of
2019 * registration. Typically this means that the variable cannot be
2020 * allocated from stack.
2021 */
2022struct net_if_timestamp_cb {
2023 /** Node information for the slist. */
2024 sys_snode_t node;
2025
Tomasz Gorochowik2ca3b1e2018-06-04 14:23:12 +02002026 /** Packet for which the callback is needed.
2027 * A NULL value means all packets.
2028 */
2029 struct net_pkt *pkt;
2030
Jukka Rissanen580596c2018-01-24 15:20:21 +02002031 /** Net interface for which the callback is needed.
2032 * A NULL value means all interfaces.
2033 */
2034 struct net_if *iface;
2035
2036 /** Timestamp callback */
2037 net_if_timestamp_callback_t cb;
2038};
2039
2040/**
2041 * @brief Register a timestamp callback.
2042 *
2043 * @param handle Caller specified handler for the callback.
Tomasz Gorochowik2ca3b1e2018-06-04 14:23:12 +02002044 * @param pkt Net packet for which the callback is registered. NULL for all
2045 * packets.
Jukka Rissanen580596c2018-01-24 15:20:21 +02002046 * @param iface Net interface for which the callback is. NULL for all
2047 * interfaces.
2048 * @param cb Callback to register.
2049 */
2050void net_if_register_timestamp_cb(struct net_if_timestamp_cb *handle,
Tomasz Gorochowik2ca3b1e2018-06-04 14:23:12 +02002051 struct net_pkt *pkt,
Jukka Rissanen580596c2018-01-24 15:20:21 +02002052 struct net_if *iface,
2053 net_if_timestamp_callback_t cb);
2054
2055/**
2056 * @brief Unregister a timestamp callback.
2057 *
2058 * @param handle Caller specified handler for the callback.
2059 */
2060void net_if_unregister_timestamp_cb(struct net_if_timestamp_cb *handle);
2061
2062/**
2063 * @brief Call a timestamp callback function.
2064 *
2065 * @param pkt Network buffer.
2066 */
2067void net_if_call_timestamp_cb(struct net_pkt *pkt);
2068
2069/*
2070 * @brief Add timestamped TX buffer to be handled
2071 *
2072 * @param pkt Timestamped buffer
2073 */
2074void net_if_add_tx_timestamp(struct net_pkt *pkt);
2075#endif /* CONFIG_NET_PKT_TIMESTAMP */
2076
Jukka Rissanenb19cb202018-07-20 16:42:54 +03002077/**
2078 * @brief Set network interface into promiscuous mode
2079 *
2080 * @details Note that not all network technologies will support this.
2081 *
2082 * @param iface Pointer to network interface
2083 *
2084 * @return 0 on success, <0 if error
2085 */
2086int net_if_set_promisc(struct net_if *iface);
2087
2088/**
2089 * @brief Set network interface into normal mode
2090 *
2091 * @param iface Pointer to network interface
2092 */
2093void net_if_unset_promisc(struct net_if *iface);
2094
2095/**
2096 * @brief Check if promiscuous mode is set or not.
2097 *
2098 * @param iface Pointer to network interface
2099 *
2100 * @return True if interface is in promisc mode,
2101 * False if interface is not in in promiscuous mode.
2102 */
2103bool net_if_is_promisc(struct net_if *iface);
2104
Jukka Rissanendee07c92020-03-19 18:48:50 +02002105/**
2106 * @brief Check if there are any pending TX network data for a given network
2107 * interface.
2108 *
2109 * @param iface Pointer to network interface
2110 *
2111 * @return True if there are pending TX network packets for this network
2112 * interface, False otherwise.
2113 */
2114static inline bool net_if_are_pending_tx_packets(struct net_if *iface)
2115{
2116#if defined(CONFIG_NET_POWER_MANAGEMENT)
2117 return !!iface->tx_pending;
2118#else
2119 ARG_UNUSED(iface);
2120
2121 return false;
2122#endif
2123}
2124
Tomasz Bursztyka80917ec2020-02-25 09:42:35 +01002125#ifdef CONFIG_NET_POWER_MANAGEMENT
Tomasz Bursztyka80917ec2020-02-25 09:42:35 +01002126/**
2127 * @brief Suspend a network interface from a power management perspective
2128 *
2129 * @param iface Pointer to network interface
2130 *
2131 * @return 0 on success, or -EALREADY/-EBUSY as possible errors.
2132 */
2133int net_if_suspend(struct net_if *iface);
2134
2135/**
2136 * @brief Resume a network interface from a power management perspective
2137 *
2138 * @param iface Pointer to network interface
2139 *
2140 * @return 0 on success, or -EALREADY as a possible error.
2141 */
2142int net_if_resume(struct net_if *iface);
2143
Tomasz Bursztyka4322c662020-02-28 11:14:46 +01002144/**
2145 * @brief Check if the network interface is suspended or not.
2146 *
2147 * @param iface Pointer to network interface
2148 *
2149 * @return True if interface is suspended, False otherwise.
2150 */
2151bool net_if_is_suspended(struct net_if *iface);
Tomasz Bursztyka80917ec2020-02-25 09:42:35 +01002152#endif /* CONFIG_NET_POWER_MANAGEMENT */
2153
Jukka Rissanenb288a9d2019-02-14 16:12:24 +02002154/** @cond INTERNAL_HIDDEN */
Jukka Rissanen68ea9372016-11-12 00:13:24 +02002155struct net_if_api {
2156 void (*init)(struct net_if *iface);
Jukka Rissanen68ea9372016-11-12 00:13:24 +02002157};
2158
Jukka Rissanen6cf1da42019-08-09 14:49:35 +03002159#if defined(CONFIG_NET_DHCPV4) && defined(CONFIG_NET_NATIVE_IPV4)
Marcus Shawcroft3726bb92017-02-11 17:45:17 +00002160#define NET_IF_DHCPV4_INIT .dhcpv4.state = NET_DHCPV4_DISABLED,
Marcus Shawcroft81c0d5f2017-02-10 19:10:27 +00002161#else
2162#define NET_IF_DHCPV4_INIT
2163#endif
2164
Jukka Rissanen47dafff2018-01-11 16:06:53 +02002165#define NET_IF_CONFIG_INIT \
2166 .config = { \
2167 .ip = { \
2168 }, \
2169 NET_IF_DHCPV4_INIT \
2170 }
2171
Jukka Rissanen62580742020-06-22 23:31:22 +03002172#define NET_IF_GET_NAME(dev_name, sfx) __net_if_##dev_name##_##sfx
2173#define NET_IF_DEV_GET_NAME(dev_name, sfx) __net_if_dev_##dev_name##_##sfx
Tomasz Bursztykae38a9e82017-03-08 09:30:03 +01002174
Jukka Rissanen68ea9372016-11-12 00:13:24 +02002175#define NET_IF_GET(dev_name, sfx) \
2176 ((struct net_if *)&NET_IF_GET_NAME(dev_name, sfx))
2177
Jukka Rissanende13e972018-01-19 12:24:33 +02002178#define NET_IF_INIT(dev_name, sfx, _l2, _mtu, _num_configs) \
Jukka Rissanen62580742020-06-22 23:31:22 +03002179 static Z_STRUCT_SECTION_ITERABLE(net_if_dev, \
2180 NET_IF_DEV_GET_NAME(dev_name, sfx)) = { \
Jukka Rissanen687c3332018-01-30 17:34:39 +02002181 .dev = &(DEVICE_NAME_GET(dev_name)), \
Jukka Rissanen68ea9372016-11-12 00:13:24 +02002182 .l2 = &(NET_L2_GET_NAME(_l2)), \
2183 .l2_data = &(NET_L2_GET_DATA(dev_name, sfx)), \
2184 .mtu = _mtu, \
Jukka Rissanen47dafff2018-01-11 16:06:53 +02002185 }; \
Jukka Rissanen62580742020-06-22 23:31:22 +03002186 static Z_DECL_ALIGN(struct net_if) \
2187 NET_IF_GET_NAME(dev_name, sfx)[_num_configs] \
2188 __used __in_section(_net_if, static, net_if) = { \
Jukka Rissanende13e972018-01-19 12:24:33 +02002189 [0 ... (_num_configs - 1)] = { \
Jukka Rissanen47dafff2018-01-11 16:06:53 +02002190 .if_dev = &(NET_IF_DEV_GET_NAME(dev_name, sfx)), \
2191 NET_IF_CONFIG_INIT \
2192 } \
Jukka Rissanen60492072018-02-07 15:00:08 +02002193 }
Jukka Rissanen68ea9372016-11-12 00:13:24 +02002194
Dario Pennisi6d387ec2017-05-03 10:32:24 +02002195#define NET_IF_OFFLOAD_INIT(dev_name, sfx, _mtu) \
Jukka Rissanen2705a9d2020-07-22 10:33:24 +03002196 static Z_STRUCT_SECTION_ITERABLE(net_if_dev, \
2197 NET_IF_DEV_GET_NAME(dev_name, sfx)) = { \
2198 .dev = &(DEVICE_NAME_GET(dev_name)), \
Dario Pennisi6d387ec2017-05-03 10:32:24 +02002199 .mtu = _mtu, \
2200 }; \
Jukka Rissanen2705a9d2020-07-22 10:33:24 +03002201 static Z_DECL_ALIGN(struct net_if) \
2202 NET_IF_GET_NAME(dev_name, sfx)[NET_IF_MAX_CONFIGS] \
2203 __used __in_section(_net_if, static, net_if) = { \
Dario Pennisi6d387ec2017-05-03 10:32:24 +02002204 [0 ... (NET_IF_MAX_CONFIGS - 1)] = { \
2205 .if_dev = &(NET_IF_DEV_GET_NAME(dev_name, sfx)), \
2206 NET_IF_CONFIG_INIT \
2207 } \
2208 }
2209
Jukka Rissanenb1bfb632019-02-19 16:37:27 +02002210/** @endcond */
2211
Jukka Rissanen68ea9372016-11-12 00:13:24 +02002212/* Network device initialization macros */
2213
Jukka Rissanenb1bfb632019-02-19 16:37:27 +02002214/**
2215 * @def NET_DEVICE_INIT
2216 *
2217 * @brief Create a network interface and bind it to network device.
2218 *
2219 * @param dev_name Network device name.
2220 * @param drv_name The name this instance of the driver exposes to
2221 * the system.
2222 * @param init_fn Address to the init function of the driver.
Tomasz Bursztyka4ae72db2020-02-25 10:45:25 +01002223 * @param pm_control_fn Pointer to device_pm_control function.
2224 * Can be empty function (device_pm_control_nop) if not implemented.
Tomasz Bursztyka549cfff2020-05-29 09:18:31 +02002225 * @param data Pointer to the device's private data.
Tomasz Bursztykaa8cd1622020-05-28 20:36:09 +02002226 * @param cfg The address to the structure containing the
Jukka Rissanenb1bfb632019-02-19 16:37:27 +02002227 * configuration information for this instance of the driver.
2228 * @param prio The initialization level at which configuration occurs.
2229 * @param api Provides an initial pointer to the API function struct
2230 * used by the driver. Can be NULL.
2231 * @param l2 Network L2 layer for this network interface.
2232 * @param l2_ctx_type Type of L2 context data.
2233 * @param mtu Maximum transfer unit in bytes for this network interface.
2234 */
Tomasz Bursztyka4ae72db2020-02-25 10:45:25 +01002235#define NET_DEVICE_INIT(dev_name, drv_name, init_fn, pm_control_fn, \
Tomasz Bursztykaa8cd1622020-05-28 20:36:09 +02002236 data, cfg, prio, api, l2, \
Tomasz Bursztyka4ae72db2020-02-25 10:45:25 +01002237 l2_ctx_type, mtu) \
2238 DEVICE_DEFINE(dev_name, drv_name, init_fn, pm_control_fn, data, \
Tomasz Bursztykaa8cd1622020-05-28 20:36:09 +02002239 cfg, POST_KERNEL, prio, api); \
Tomasz Bursztyka4ae72db2020-02-25 10:45:25 +01002240 NET_L2_DATA_INIT(dev_name, 0, l2_ctx_type); \
Jukka Rissanende13e972018-01-19 12:24:33 +02002241 NET_IF_INIT(dev_name, 0, l2, mtu, NET_IF_MAX_CONFIGS)
Jukka Rissanen68ea9372016-11-12 00:13:24 +02002242
2243/**
Jukka Rissanenb1bfb632019-02-19 16:37:27 +02002244 * @def NET_DEVICE_INIT_INSTANCE
2245 *
2246 * @brief Create multiple network interfaces and bind them to network device.
Jukka Rissanen68ea9372016-11-12 00:13:24 +02002247 * If your network device needs more than one instance of a network interface,
Jukka Rissanenb1bfb632019-02-19 16:37:27 +02002248 * use this macro below and provide a different instance suffix each time
Jukka Rissanen68ea9372016-11-12 00:13:24 +02002249 * (0, 1, 2, ... or a, b, c ... whatever works for you)
Jukka Rissanenb1bfb632019-02-19 16:37:27 +02002250 *
2251 * @param dev_name Network device name.
2252 * @param drv_name The name this instance of the driver exposes to
2253 * the system.
2254 * @param instance Instance identifier.
2255 * @param init_fn Address to the init function of the driver.
Tomasz Bursztyka4ae72db2020-02-25 10:45:25 +01002256 * @param pm_control_fn Pointer to device_pm_control function.
2257 * Can be empty function (device_pm_control_nop) if not implemented.
Tomasz Bursztyka549cfff2020-05-29 09:18:31 +02002258 * @param data Pointer to the device's private data.
Tomasz Bursztykaa8cd1622020-05-28 20:36:09 +02002259 * @param cfg The address to the structure containing the
Jukka Rissanenb1bfb632019-02-19 16:37:27 +02002260 * configuration information for this instance of the driver.
2261 * @param prio The initialization level at which configuration occurs.
2262 * @param api Provides an initial pointer to the API function struct
2263 * used by the driver. Can be NULL.
2264 * @param l2 Network L2 layer for this network interface.
2265 * @param l2_ctx_type Type of L2 context data.
2266 * @param mtu Maximum transfer unit in bytes for this network interface.
Jukka Rissanen68ea9372016-11-12 00:13:24 +02002267 */
2268#define NET_DEVICE_INIT_INSTANCE(dev_name, drv_name, instance, init_fn, \
Tomasz Bursztykaa8cd1622020-05-28 20:36:09 +02002269 pm_control_fn, data, cfg, prio, \
Tomasz Bursztyka4ae72db2020-02-25 10:45:25 +01002270 api, l2, l2_ctx_type, mtu) \
2271 DEVICE_DEFINE(dev_name, drv_name, init_fn, pm_control_fn, data, \
Tomasz Bursztykaa8cd1622020-05-28 20:36:09 +02002272 cfg, POST_KERNEL, prio, api); \
Jukka Rissanen68ea9372016-11-12 00:13:24 +02002273 NET_L2_DATA_INIT(dev_name, instance, l2_ctx_type); \
Jukka Rissanende13e972018-01-19 12:24:33 +02002274 NET_IF_INIT(dev_name, instance, l2, mtu, NET_IF_MAX_CONFIGS)
Jukka Rissanen68ea9372016-11-12 00:13:24 +02002275
Jukka Rissanenb1bfb632019-02-19 16:37:27 +02002276/**
2277 * @def NET_DEVICE_OFFLOAD_INIT
2278 *
2279 * @brief Create a offloaded network interface and bind it to network device.
2280 * The offloaded network interface is implemented by a device vendor HAL or
2281 * similar.
2282 *
2283 * @param dev_name Network device name.
2284 * @param drv_name The name this instance of the driver exposes to
2285 * the system.
2286 * @param init_fn Address to the init function of the driver.
Tomasz Bursztyka4ae72db2020-02-25 10:45:25 +01002287 * @param pm_control_fn Pointer to device_pm_control function.
2288 * Can be empty function (device_pm_control_nop) if not implemented.
Tomasz Bursztyka549cfff2020-05-29 09:18:31 +02002289 * @param data Pointer to the device's private data.
Tomasz Bursztykaa8cd1622020-05-28 20:36:09 +02002290 * @param cfg The address to the structure containing the
Jukka Rissanenb1bfb632019-02-19 16:37:27 +02002291 * configuration information for this instance of the driver.
2292 * @param prio The initialization level at which configuration occurs.
2293 * @param api Provides an initial pointer to the API function struct
2294 * used by the driver. Can be NULL.
2295 * @param mtu Maximum transfer unit in bytes for this network interface.
2296 */
Tomasz Bursztyka4ae72db2020-02-25 10:45:25 +01002297#define NET_DEVICE_OFFLOAD_INIT(dev_name, drv_name, init_fn, \
Tomasz Bursztykaa8cd1622020-05-28 20:36:09 +02002298 pm_control_fn, data, cfg, prio, \
Tomasz Bursztyka4ae72db2020-02-25 10:45:25 +01002299 api, mtu) \
2300 DEVICE_DEFINE(dev_name, drv_name, init_fn, pm_control_fn, data, \
Tomasz Bursztykaa8cd1622020-05-28 20:36:09 +02002301 cfg, POST_KERNEL, prio, api); \
Jukka Rissanenb1bfb632019-02-19 16:37:27 +02002302 NET_IF_OFFLOAD_INIT(dev_name, 0, mtu)
Jukka Rissanenb288a9d2019-02-14 16:12:24 +02002303
Jukka Rissanen68ea9372016-11-12 00:13:24 +02002304#ifdef __cplusplus
2305}
2306#endif
2307
Jukka Rissanen041cd5f2019-05-29 11:43:13 +08002308#include <syscalls/net_if.h>
2309
Tomasz Bursztykad8323e12017-01-06 14:10:06 +01002310/**
2311 * @}
2312 */
2313
Flavio Ceolin67ca1762018-09-14 10:43:44 -07002314#endif /* ZEPHYR_INCLUDE_NET_NET_IF_H_ */