net: ipv4: Add IPv4 options length to net pkt
IPv4 header options length will be stored in ipv4_opts_len in net_pkt structure. Now IPv4 header length will be in net_pkt ip_hdr_len + ipv4_opts_len. So modified relevant places of ip header length calculation for IPv4. Signed-off-by: Ravi kumar Veeramally <ravikumar.veeramally@linux.intel.com>
This commit is contained in:
parent
649ec80c9e
commit
cf9ad748ba
7 changed files with 81 additions and 21 deletions
|
@ -188,6 +188,15 @@ struct net_pkt {
|
||||||
u8_t ipv4_ttl;
|
u8_t ipv4_ttl;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
union {
|
||||||
|
#if defined(CONFIG_NET_IPV4)
|
||||||
|
u8_t ipv4_opts_len; /* Length if IPv4 Header Options */
|
||||||
|
#endif
|
||||||
|
#if defined(CONFIG_NET_IPV6)
|
||||||
|
u16_t ipv6_ext_len; /* length of extension headers */
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
#if NET_TC_COUNT > 1
|
#if NET_TC_COUNT > 1
|
||||||
/** Network packet priority, can be left out in which case packet
|
/** Network packet priority, can be left out in which case packet
|
||||||
* is not prioritised.
|
* is not prioritised.
|
||||||
|
@ -205,8 +214,6 @@ struct net_pkt {
|
||||||
#endif /* CONFIG_NET_VLAN */
|
#endif /* CONFIG_NET_VLAN */
|
||||||
|
|
||||||
#if defined(CONFIG_NET_IPV6)
|
#if defined(CONFIG_NET_IPV6)
|
||||||
u16_t ipv6_ext_len; /* length of extension headers */
|
|
||||||
|
|
||||||
/* Where is the start of the last header before payload data
|
/* Where is the start of the last header before payload data
|
||||||
* in IPv6 packet. This is offset value from start of the IPv6
|
* in IPv6 packet. This is offset value from start of the IPv6
|
||||||
* packet. Note that this value should be updated by who ever
|
* packet. Note that this value should be updated by who ever
|
||||||
|
@ -387,6 +394,17 @@ static inline void net_pkt_set_ipv4_ttl(struct net_pkt *pkt,
|
||||||
{
|
{
|
||||||
pkt->ipv4_ttl = ttl;
|
pkt->ipv4_ttl = ttl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline u8_t net_pkt_ipv4_opts_len(struct net_pkt *pkt)
|
||||||
|
{
|
||||||
|
return pkt->ipv4_opts_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void net_pkt_set_ipv4_opts_len(struct net_pkt *pkt,
|
||||||
|
u8_t opts_len)
|
||||||
|
{
|
||||||
|
pkt->ipv4_opts_len = opts_len;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
static inline u8_t net_pkt_ipv4_ttl(struct net_pkt *pkt)
|
static inline u8_t net_pkt_ipv4_ttl(struct net_pkt *pkt)
|
||||||
{
|
{
|
||||||
|
@ -401,6 +419,19 @@ static inline void net_pkt_set_ipv4_ttl(struct net_pkt *pkt,
|
||||||
ARG_UNUSED(pkt);
|
ARG_UNUSED(pkt);
|
||||||
ARG_UNUSED(ttl);
|
ARG_UNUSED(ttl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline u8_t net_pkt_ipv4_opts_len(struct net_pkt *pkt)
|
||||||
|
{
|
||||||
|
ARG_UNUSED(pkt);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void net_pkt_set_ipv4_opts_len(struct net_pkt *pkt,
|
||||||
|
u8_t opts_len)
|
||||||
|
{
|
||||||
|
ARG_UNUSED(pkt);
|
||||||
|
ARG_UNUSED(opts_len);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_NET_IPV6)
|
#if defined(CONFIG_NET_IPV6)
|
||||||
|
@ -526,6 +557,19 @@ static inline void net_pkt_set_ipv6_hop_limit(struct net_pkt *pkt,
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_NET_IPV6 */
|
#endif /* CONFIG_NET_IPV6 */
|
||||||
|
|
||||||
|
static inline u16_t net_pkt_ip_opts_len(struct net_pkt *pkt)
|
||||||
|
{
|
||||||
|
#if defined(CONFIG_NET_IPV6)
|
||||||
|
return pkt->ipv6_ext_len;
|
||||||
|
#elif defined(CONFIG_NET_IPV4)
|
||||||
|
return pkt->ipv4_opts_len;
|
||||||
|
#else
|
||||||
|
ARG_UNUSED(pkt);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_NET_IPV6_FRAGMENT)
|
#if defined(CONFIG_NET_IPV6_FRAGMENT)
|
||||||
static inline u16_t net_pkt_ipv6_fragment_start(struct net_pkt *pkt)
|
static inline u16_t net_pkt_ipv6_fragment_start(struct net_pkt *pkt)
|
||||||
{
|
{
|
||||||
|
|
|
@ -79,6 +79,12 @@ int net_ipv4_finalize(struct net_pkt *pkt, u8_t next_header_proto)
|
||||||
return -ENOBUFS;
|
return -ENOBUFS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (net_pkt_ipv4_opts_len(pkt)) {
|
||||||
|
ipv4_hdr->vhl = 0x40 | (0x0F &
|
||||||
|
((net_pkt_ip_hdr_len(pkt) +
|
||||||
|
net_pkt_ipv4_opts_len(pkt)) / 4U));
|
||||||
|
}
|
||||||
|
|
||||||
ipv4_hdr->len = htons(net_pkt_get_len(pkt));
|
ipv4_hdr->len = htons(net_pkt_get_len(pkt));
|
||||||
ipv4_hdr->proto = next_header_proto;
|
ipv4_hdr->proto = next_header_proto;
|
||||||
|
|
||||||
|
@ -112,6 +118,7 @@ enum net_verdict net_ipv4_input(struct net_pkt *pkt)
|
||||||
struct net_ipv4_hdr *hdr;
|
struct net_ipv4_hdr *hdr;
|
||||||
union net_ip_header ip;
|
union net_ip_header ip;
|
||||||
u8_t hdr_len;
|
u8_t hdr_len;
|
||||||
|
u8_t opts_len;
|
||||||
int pkt_len;
|
int pkt_len;
|
||||||
|
|
||||||
net_stats_update_ipv4_recv(net_pkt_iface(pkt));
|
net_stats_update_ipv4_recv(net_pkt_iface(pkt));
|
||||||
|
@ -140,7 +147,10 @@ enum net_verdict net_ipv4_input(struct net_pkt *pkt)
|
||||||
goto drop;
|
goto drop;
|
||||||
}
|
}
|
||||||
|
|
||||||
net_pkt_set_ip_hdr_len(pkt, hdr_len);
|
net_pkt_set_ip_hdr_len(pkt, sizeof(struct net_ipv4_hdr));
|
||||||
|
|
||||||
|
opts_len = hdr_len - sizeof(struct net_ipv4_hdr);
|
||||||
|
net_pkt_set_ipv4_opts_len(pkt, opts_len);
|
||||||
|
|
||||||
pkt_len = ntohs(hdr->len);
|
pkt_len = ntohs(hdr->len);
|
||||||
if (real_len < pkt_len) {
|
if (real_len < pkt_len) {
|
||||||
|
@ -188,9 +198,9 @@ enum net_verdict net_ipv4_input(struct net_pkt *pkt)
|
||||||
|
|
||||||
net_pkt_acknowledge_data(pkt, &ipv4_access);
|
net_pkt_acknowledge_data(pkt, &ipv4_access);
|
||||||
|
|
||||||
if (hdr_len > sizeof(struct net_ipv4_hdr)) {
|
if (opts_len) {
|
||||||
/* There are probably options, let's skip them */
|
/* Only few options are handled in EchoRequest, rest skipped */
|
||||||
if (net_pkt_skip(pkt, hdr_len - sizeof(struct net_ipv4_hdr))) {
|
if (net_pkt_skip(pkt, opts_len)) {
|
||||||
NET_DBG("Header too big? %u", hdr_len);
|
NET_DBG("Header too big? %u", hdr_len);
|
||||||
goto drop;
|
goto drop;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1704,6 +1704,8 @@ static void clone_pkt_attributes(struct net_pkt *pkt, struct net_pkt *clone_pkt)
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_NET_IPV4) && net_pkt_family(pkt) == AF_INET) {
|
if (IS_ENABLED(CONFIG_NET_IPV4) && net_pkt_family(pkt) == AF_INET) {
|
||||||
net_pkt_set_ipv4_ttl(clone_pkt, net_pkt_ipv4_ttl(pkt));
|
net_pkt_set_ipv4_ttl(clone_pkt, net_pkt_ipv4_ttl(pkt));
|
||||||
|
net_pkt_set_ipv4_opts_len(clone_pkt,
|
||||||
|
net_pkt_ipv4_opts_len(pkt));
|
||||||
} else if (IS_ENABLED(CONFIG_NET_IPV6) &&
|
} else if (IS_ENABLED(CONFIG_NET_IPV6) &&
|
||||||
net_pkt_family(pkt) == AF_INET6) {
|
net_pkt_family(pkt) == AF_INET6) {
|
||||||
net_pkt_set_ipv6_hop_limit(clone_pkt,
|
net_pkt_set_ipv6_hop_limit(clone_pkt,
|
||||||
|
|
|
@ -873,7 +873,7 @@ int net_tcp_send_pkt(struct net_pkt *pkt)
|
||||||
net_pkt_set_overwrite(pkt, true);
|
net_pkt_set_overwrite(pkt, true);
|
||||||
|
|
||||||
if (net_pkt_skip(pkt, net_pkt_ip_hdr_len(pkt) +
|
if (net_pkt_skip(pkt, net_pkt_ip_hdr_len(pkt) +
|
||||||
net_pkt_ipv6_ext_len(pkt))) {
|
net_pkt_ip_opts_len(pkt))) {
|
||||||
return -EMSGSIZE;
|
return -EMSGSIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -908,7 +908,7 @@ int net_tcp_send_pkt(struct net_pkt *pkt)
|
||||||
if (calc_chksum) {
|
if (calc_chksum) {
|
||||||
net_pkt_cursor_init(pkt);
|
net_pkt_cursor_init(pkt);
|
||||||
net_pkt_skip(pkt, net_pkt_ip_hdr_len(pkt) +
|
net_pkt_skip(pkt, net_pkt_ip_hdr_len(pkt) +
|
||||||
net_pkt_ipv6_ext_len(pkt));
|
net_pkt_ip_opts_len(pkt));
|
||||||
|
|
||||||
/* No need to get tcp_hdr again */
|
/* No need to get tcp_hdr again */
|
||||||
tcp_hdr->chksum = net_calc_chksum_tcp(pkt);
|
tcp_hdr->chksum = net_calc_chksum_tcp(pkt);
|
||||||
|
@ -1076,7 +1076,7 @@ bool net_tcp_ack_received(struct net_context *ctx, u32_t ack)
|
||||||
net_pkt_set_overwrite(pkt, true);
|
net_pkt_set_overwrite(pkt, true);
|
||||||
|
|
||||||
if (net_pkt_skip(pkt, net_pkt_ip_hdr_len(pkt) +
|
if (net_pkt_skip(pkt, net_pkt_ip_hdr_len(pkt) +
|
||||||
net_pkt_ipv6_ext_len(pkt))) {
|
net_pkt_ip_opts_len(pkt))) {
|
||||||
sys_slist_remove(list, NULL, head);
|
sys_slist_remove(list, NULL, head);
|
||||||
net_pkt_unref(pkt);
|
net_pkt_unref(pkt);
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -39,16 +39,16 @@ int net_udp_finalize(struct net_pkt *pkt)
|
||||||
{
|
{
|
||||||
NET_PKT_DATA_ACCESS_DEFINE(udp_access, struct net_udp_hdr);
|
NET_PKT_DATA_ACCESS_DEFINE(udp_access, struct net_udp_hdr);
|
||||||
struct net_udp_hdr *udp_hdr;
|
struct net_udp_hdr *udp_hdr;
|
||||||
u16_t length;
|
u16_t length = 0;
|
||||||
|
|
||||||
udp_hdr = (struct net_udp_hdr *)net_pkt_get_data(pkt, &udp_access);
|
udp_hdr = (struct net_udp_hdr *)net_pkt_get_data(pkt, &udp_access);
|
||||||
if (!udp_hdr) {
|
if (!udp_hdr) {
|
||||||
return -ENOBUFS;
|
return -ENOBUFS;
|
||||||
}
|
}
|
||||||
|
|
||||||
length = net_pkt_get_len(pkt) -
|
length = net_pkt_get_len(pkt) - net_pkt_ip_hdr_len(pkt) -
|
||||||
net_pkt_ip_hdr_len(pkt) -
|
net_pkt_ip_opts_len(pkt);
|
||||||
net_pkt_ipv6_ext_len(pkt);
|
|
||||||
udp_hdr->len = htons(length);
|
udp_hdr->len = htons(length);
|
||||||
|
|
||||||
if (net_if_need_calc_tx_checksum(net_pkt_iface(pkt))) {
|
if (net_if_need_calc_tx_checksum(net_pkt_iface(pkt))) {
|
||||||
|
@ -75,7 +75,7 @@ struct net_udp_hdr *net_udp_get_hdr(struct net_pkt *pkt,
|
||||||
net_pkt_cursor_init(pkt);
|
net_pkt_cursor_init(pkt);
|
||||||
|
|
||||||
if (net_pkt_skip(pkt, net_pkt_ip_hdr_len(pkt) +
|
if (net_pkt_skip(pkt, net_pkt_ip_hdr_len(pkt) +
|
||||||
net_pkt_ipv6_ext_len(pkt))) {
|
net_pkt_ip_opts_len(pkt))) {
|
||||||
udp_hdr = NULL;
|
udp_hdr = NULL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -104,7 +104,7 @@ struct net_udp_hdr *net_udp_set_hdr(struct net_pkt *pkt,
|
||||||
net_pkt_cursor_init(pkt);
|
net_pkt_cursor_init(pkt);
|
||||||
|
|
||||||
if (net_pkt_skip(pkt, net_pkt_ip_hdr_len(pkt) +
|
if (net_pkt_skip(pkt, net_pkt_ip_hdr_len(pkt) +
|
||||||
net_pkt_ipv6_ext_len(pkt))) {
|
net_pkt_ip_opts_len(pkt))) {
|
||||||
udp_hdr = NULL;
|
udp_hdr = NULL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -156,7 +156,7 @@ struct net_udp_hdr *net_udp_input(struct net_pkt *pkt,
|
||||||
|
|
||||||
if (ntohs(udp_hdr->len) != (net_pkt_get_len(pkt) -
|
if (ntohs(udp_hdr->len) != (net_pkt_get_len(pkt) -
|
||||||
net_pkt_ip_hdr_len(pkt) -
|
net_pkt_ip_hdr_len(pkt) -
|
||||||
net_pkt_ipv6_ext_len(pkt))) {
|
net_pkt_ip_opts_len(pkt))) {
|
||||||
NET_DBG("DROP: Invalid hdr length");
|
NET_DBG("DROP: Invalid hdr length");
|
||||||
goto drop;
|
goto drop;
|
||||||
}
|
}
|
||||||
|
|
|
@ -566,7 +566,8 @@ u16_t net_calc_chksum(struct net_pkt *pkt, u8_t proto)
|
||||||
if (proto != IPPROTO_ICMP) {
|
if (proto != IPPROTO_ICMP) {
|
||||||
len = 2 * sizeof(struct in_addr);
|
len = 2 * sizeof(struct in_addr);
|
||||||
sum = net_pkt_get_len(pkt) -
|
sum = net_pkt_get_len(pkt) -
|
||||||
net_pkt_ip_hdr_len(pkt) + proto;
|
net_pkt_ip_hdr_len(pkt) -
|
||||||
|
net_pkt_ipv4_opts_len(pkt) + proto;
|
||||||
}
|
}
|
||||||
} else if (IS_ENABLED(CONFIG_NET_IPV6) &&
|
} else if (IS_ENABLED(CONFIG_NET_IPV6) &&
|
||||||
net_pkt_family(pkt) == AF_INET6) {
|
net_pkt_family(pkt) == AF_INET6) {
|
||||||
|
@ -588,8 +589,7 @@ u16_t net_calc_chksum(struct net_pkt *pkt, u8_t proto)
|
||||||
net_pkt_skip(pkt, net_pkt_ip_hdr_len(pkt) - len);
|
net_pkt_skip(pkt, net_pkt_ip_hdr_len(pkt) - len);
|
||||||
|
|
||||||
sum = calc_chksum(sum, pkt->cursor.pos, len);
|
sum = calc_chksum(sum, pkt->cursor.pos, len);
|
||||||
|
net_pkt_skip(pkt, len + net_pkt_ip_opts_len(pkt));
|
||||||
net_pkt_skip(pkt, len + net_pkt_ipv6_ext_len(pkt));
|
|
||||||
|
|
||||||
sum = pkt_calc_chksum(pkt, sum);
|
sum = pkt_calc_chksum(pkt, sum);
|
||||||
|
|
||||||
|
@ -607,7 +607,9 @@ u16_t net_calc_chksum_ipv4(struct net_pkt *pkt)
|
||||||
{
|
{
|
||||||
u16_t sum;
|
u16_t sum;
|
||||||
|
|
||||||
sum = calc_chksum(0, pkt->buffer->data, net_pkt_ip_hdr_len(pkt));
|
sum = calc_chksum(0, pkt->buffer->data,
|
||||||
|
net_pkt_ip_hdr_len(pkt) +
|
||||||
|
net_pkt_ipv4_opts_len(pkt));
|
||||||
|
|
||||||
sum = (sum == 0U) ? 0xffff : htons(sum);
|
sum = (sum == 0U) ? 0xffff : htons(sum);
|
||||||
|
|
||||||
|
|
|
@ -644,7 +644,9 @@ static int sock_get_pkt_src_addr(struct net_pkt *pkt,
|
||||||
|
|
||||||
ipv4_hdr = (struct net_ipv4_hdr *)net_pkt_get_data(
|
ipv4_hdr = (struct net_ipv4_hdr *)net_pkt_get_data(
|
||||||
pkt, &ipv4_access);
|
pkt, &ipv4_access);
|
||||||
if (!ipv4_hdr || net_pkt_acknowledge_data(pkt, &ipv4_access)) {
|
if (!ipv4_hdr ||
|
||||||
|
net_pkt_acknowledge_data(pkt, &ipv4_access) ||
|
||||||
|
net_pkt_skip(pkt, net_pkt_ipv4_opts_len(pkt))) {
|
||||||
ret = -ENOBUFS;
|
ret = -ENOBUFS;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue