0)
static inline bool
-xsk_buff_valid_tx_metadata(const struct xsk_tx_metadata *meta)
+xsk_buff_valid_tx_metadata(const struct xsk_buff_pool *pool,
+ const struct xsk_tx_metadata *meta, u64 *flags)
{
- return !(meta->flags & ~XDP_TXMD_FLAGS_VALID);
+ *flags = READ_ONCE(meta->flags);
+ if (*flags & XDP_TXMD_FLAGS_LAUNCH_TIME)
+ if (pool->tx_metadata_len <
+ offsetofend(struct xsk_tx_metadata, request.launch_time))
+ return false;
+ return !(*flags & ~XDP_TXMD_FLAGS_VALID);
}
static inline struct xsk_tx_metadata *
__xsk_buff_get_metadata(const struct xsk_buff_pool *pool, void *data)
{
struct xsk_tx_metadata *meta;
+ u64 flags;
if (!pool->tx_metadata_len)
return NULL;
meta = data - pool->tx_metadata_len;
- if (unlikely(!xsk_buff_valid_tx_metadata(meta)))
+ if (unlikely(!xsk_buff_valid_tx_metadata(pool, meta, &flags)))
return NULL; /* no way to signal the error to the user */
return meta;
return (struct xdp_desc_ctx){ };
}
-static inline bool xsk_buff_valid_tx_metadata(struct xsk_tx_metadata *meta)
+static inline bool
+xsk_buff_valid_tx_metadata(const struct xsk_buff_pool *pool,
+ const struct xsk_tx_metadata *meta, u64 *flags)
{
return false;
}
{
struct xsk_tx_metadata *meta = NULL;
u16 csum_start, csum_offset;
+ u64 flags;
if (unlikely(pool->tx_metadata_len == 0))
return -EINVAL;
meta = buffer - pool->tx_metadata_len;
- if (unlikely(!xsk_buff_valid_tx_metadata(meta)))
+ if (unlikely(!xsk_buff_valid_tx_metadata(pool, meta, &flags)))
return -EINVAL;
- if (meta->flags & XDP_TXMD_FLAGS_CHECKSUM) {
+ if (flags & XDP_TXMD_FLAGS_CHECKSUM) {
csum_start = READ_ONCE(meta->request.csum_start);
csum_offset = READ_ONCE(meta->request.csum_offset);
}
}
- if (meta->flags & XDP_TXMD_FLAGS_LAUNCH_TIME)
- skb->skb_mstamp_ns = meta->request.launch_time;
- if (!(meta->flags & XDP_TXMD_FLAGS_TIMESTAMP))
+ if (flags & XDP_TXMD_FLAGS_LAUNCH_TIME)
+ skb->skb_mstamp_ns = READ_ONCE(meta->request.launch_time);
+ if (!(flags & XDP_TXMD_FLAGS_TIMESTAMP))
meta = NULL;
xsk_tx_metadata_to_compl(meta, &skb_shinfo(skb)->xsk_meta);