net: Add support for IP_MTU IPv4 socket option
Add IP_MTU IPv4 socket option and implement getsockopt() call for the option. The IP_MTU option does not support setsockopt() call. Signed-off-by: Jukka Rissanen <jukka.rissanen@nordicsemi.no>
This commit is contained in:
parent
fad10f7370
commit
a818839186
4 changed files with 72 additions and 0 deletions
|
@ -1292,6 +1292,7 @@ enum net_context_option {
|
|||
NET_OPT_TTL = 16, /**< IPv4 unicast TTL */
|
||||
NET_OPT_ADDR_PREFERENCES = 17, /**< IPv6 address preference */
|
||||
NET_OPT_TIMESTAMPING = 18, /**< Packet timestamping */
|
||||
NET_OPT_MTU = 20, /**< IPv4 socket path MTU */
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -1190,6 +1190,12 @@ struct in_pktinfo {
|
|||
struct in_addr ipi_addr; /**< Header Destination address */
|
||||
};
|
||||
|
||||
/** Retrieve the current known path MTU of the current socket. Returns an
|
||||
* integer. IP_MTU is valid only for getsockopt and can be employed only when
|
||||
* the socket has been connected.
|
||||
*/
|
||||
#define IP_MTU 14
|
||||
|
||||
/** Set IPv4 multicast TTL value. */
|
||||
#define IP_MULTICAST_TTL 33
|
||||
/** Join IPv4 multicast group. */
|
||||
|
|
|
@ -1788,6 +1788,48 @@ static int get_context_timestamping(struct net_context *context,
|
|||
#endif
|
||||
}
|
||||
|
||||
static int get_context_mtu(struct net_context *context,
|
||||
void *value, size_t *len)
|
||||
{
|
||||
sa_family_t family = net_context_get_family(context);
|
||||
struct net_if *iface = NULL;
|
||||
int mtu;
|
||||
|
||||
if (IS_ENABLED(CONFIG_NET_PMTU)) {
|
||||
mtu = net_pmtu_get_mtu(&context->remote);
|
||||
if (mtu > 0) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (net_context_is_bound_to_iface(context)) {
|
||||
iface = net_context_get_iface(context);
|
||||
|
||||
mtu = net_if_get_mtu(iface);
|
||||
} else {
|
||||
if (IS_ENABLED(CONFIG_NET_IPV6) && family == AF_INET6) {
|
||||
iface = net_if_ipv6_select_src_iface(
|
||||
&net_sin6(&context->remote)->sin6_addr);
|
||||
} else if (IS_ENABLED(CONFIG_NET_IPV4) && family == AF_INET) {
|
||||
iface = net_if_ipv4_select_src_iface(
|
||||
&net_sin(&context->remote)->sin_addr);
|
||||
} else {
|
||||
return -EAFNOSUPPORT;
|
||||
}
|
||||
|
||||
mtu = net_if_get_mtu(iface);
|
||||
}
|
||||
|
||||
out:
|
||||
*((int *)value) = mtu;
|
||||
|
||||
if (len) {
|
||||
*len = sizeof(int);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If buf is not NULL, then use it. Otherwise read the data to be written
|
||||
* to net_pkt from msghdr.
|
||||
*/
|
||||
|
@ -3188,6 +3230,14 @@ int net_context_set_option(struct net_context *context,
|
|||
break;
|
||||
case NET_OPT_TIMESTAMPING:
|
||||
ret = set_context_timestamping(context, value, len);
|
||||
break;
|
||||
case NET_OPT_MTU:
|
||||
/* IPv4 only supports getting the MTU */
|
||||
if (IS_ENABLED(CONFIG_NET_IPV4) &&
|
||||
net_context_get_family(context) == AF_INET) {
|
||||
ret = -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -3265,6 +3315,9 @@ int net_context_get_option(struct net_context *context,
|
|||
case NET_OPT_TIMESTAMPING:
|
||||
ret = get_context_timestamping(context, value, len);
|
||||
break;
|
||||
case NET_OPT_MTU:
|
||||
ret = get_context_mtu(context, value, len);
|
||||
break;
|
||||
}
|
||||
|
||||
k_mutex_unlock(&context->lock);
|
||||
|
|
|
@ -1840,6 +1840,18 @@ int zsock_getsockopt_ctx(struct net_context *ctx, int level, int optname,
|
|||
}
|
||||
|
||||
return 0;
|
||||
|
||||
case IP_MTU:
|
||||
if (IS_ENABLED(CONFIG_NET_IPV4)) {
|
||||
ret = net_context_get_option(ctx, NET_OPT_MTU,
|
||||
optval, optlen);
|
||||
if (ret < 0) {
|
||||
errno = -ret;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue