net: ipv6_fragment: store M-bit in addition to the offset

Currently we only store the fragment offset. But in some cases it might
be necessary to also inspect the M-bit (More Fragment) of all received
fragments.

Modify the semantics of the field to store all the flags, rename the
setter to account for this change, and add a getter for the M-bit.

Signed-off-by: Florian Vaussard <florian.vaussard@gmail.com>
This commit is contained in:
Florian Vaussard 2021-07-09 15:21:44 +02:00 committed by Christopher Friedt
parent 0fcf87540e
commit 4fe978661a
3 changed files with 22 additions and 9 deletions

View file

@ -567,6 +567,8 @@ union net_proto_header {
#define NET_IPV6H_LENGTH_OFFSET 0x04 /* Offset of the Length field in the IPv6 header */
#define NET_IPV6_FRAGH_OFFSET_MASK 0xfff8 /* Mask for the 13-bit Fragment Offset field */
/** @endcond */
/**

View file

@ -232,7 +232,7 @@ struct net_pkt {
uint16_t ipv6_prev_hdr_start;
#if defined(CONFIG_NET_IPV6_FRAGMENT)
uint16_t ipv6_fragment_offset; /* Fragment offset of this packet */
uint16_t ipv6_fragment_flags; /* Fragment offset and M (More Fragment) flag */
uint32_t ipv6_fragment_id; /* Fragment id */
uint16_t ipv6_frag_hdr_start; /* Where starts the fragment header */
#endif /* CONFIG_NET_IPV6_FRAGMENT */
@ -649,13 +649,17 @@ static inline void net_pkt_set_ipv6_fragment_start(struct net_pkt *pkt,
static inline uint16_t net_pkt_ipv6_fragment_offset(struct net_pkt *pkt)
{
return pkt->ipv6_fragment_offset;
return pkt->ipv6_fragment_flags & NET_IPV6_FRAGH_OFFSET_MASK;
}
static inline bool net_pkt_ipv6_fragment_more(struct net_pkt *pkt)
{
return (pkt->ipv6_fragment_flags & 0x01) != 0;
}
static inline void net_pkt_set_ipv6_fragment_offset(struct net_pkt *pkt,
uint16_t offset)
static inline void net_pkt_set_ipv6_fragment_flags(struct net_pkt *pkt,
uint16_t flags)
{
pkt->ipv6_fragment_offset = offset;
pkt->ipv6_fragment_flags = flags;
}
static inline uint32_t net_pkt_ipv6_fragment_id(struct net_pkt *pkt)
@ -690,11 +694,18 @@ static inline uint16_t net_pkt_ipv6_fragment_offset(struct net_pkt *pkt)
return 0;
}
static inline void net_pkt_set_ipv6_fragment_offset(struct net_pkt *pkt,
uint16_t offset)
static inline bool net_pkt_ipv6_fragment_more(struct net_pkt *pkt)
{
ARG_UNUSED(pkt);
ARG_UNUSED(offset);
return 0;
}
static inline void net_pkt_set_ipv6_fragment_flags(struct net_pkt *pkt,
uint16_t flags)
{
ARG_UNUSED(pkt);
ARG_UNUSED(flags);
}
static inline uint32_t net_pkt_ipv6_fragment_id(struct net_pkt *pkt)

View file

@ -470,7 +470,7 @@ enum net_verdict net_ipv6_handle_fragment_hdr(struct net_pkt *pkt,
}
more = flag & 0x01;
net_pkt_set_ipv6_fragment_offset(pkt, flag & 0xfff8);
net_pkt_set_ipv6_fragment_flags(pkt, flag);
if (more && net_pkt_get_len(pkt) % 8) {
/* Fragment length is not multiple of 8, discard