Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/bpf: Add flags and VLAN hint to xdp_hw_metadata

Add VLAN hint to the xdp_hw_metadata program.

Also, to make metadata layout more straightforward, add flags field
to pass information about validity of every separate hint separately.

Acked-by: Stanislav Fomichev <sdf@google.com>
Signed-off-by: Larysa Zaremba <larysa.zaremba@intel.com>
Link: https://lore.kernel.org/r/20231205210847.28460-17-larysa.zaremba@intel.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Larysa Zaremba and committed by
Alexei Starovoitov
8e68a4be e71a9fa7

+78 -14
+24 -8
tools/testing/selftests/bpf/progs/xdp_hw_metadata.c
··· 20 20 __u64 *timestamp) __ksym; 21 21 extern int bpf_xdp_metadata_rx_hash(const struct xdp_md *ctx, __u32 *hash, 22 22 enum xdp_rss_hash_type *rss_type) __ksym; 23 + extern int bpf_xdp_metadata_rx_vlan_tag(const struct xdp_md *ctx, 24 + __be16 *vlan_proto, 25 + __u16 *vlan_tci) __ksym; 23 26 24 27 SEC("xdp.frags") 25 28 int rx(struct xdp_md *ctx) ··· 87 84 return XDP_PASS; 88 85 } 89 86 90 - err = bpf_xdp_metadata_rx_timestamp(ctx, &meta->rx_timestamp); 91 - if (!err) 92 - meta->xdp_timestamp = bpf_ktime_get_tai_ns(); 93 - else 94 - meta->rx_timestamp = 0; /* Used by AF_XDP as not avail signal */ 87 + meta->hint_valid = 0; 95 88 96 - err = bpf_xdp_metadata_rx_hash(ctx, &meta->rx_hash, &meta->rx_hash_type); 97 - if (err < 0) 98 - meta->rx_hash_err = err; /* Used by AF_XDP as no hash signal */ 89 + meta->xdp_timestamp = bpf_ktime_get_tai_ns(); 90 + err = bpf_xdp_metadata_rx_timestamp(ctx, &meta->rx_timestamp); 91 + if (err) 92 + meta->rx_timestamp_err = err; 93 + else 94 + meta->hint_valid |= XDP_META_FIELD_TS; 95 + 96 + err = bpf_xdp_metadata_rx_hash(ctx, &meta->rx_hash, 97 + &meta->rx_hash_type); 98 + if (err) 99 + meta->rx_hash_err = err; 100 + else 101 + meta->hint_valid |= XDP_META_FIELD_RSS; 102 + 103 + err = bpf_xdp_metadata_rx_vlan_tag(ctx, &meta->rx_vlan_proto, 104 + &meta->rx_vlan_tci); 105 + if (err) 106 + meta->rx_vlan_tag_err = err; 107 + else 108 + meta->hint_valid |= XDP_META_FIELD_VLAN_TAG; 99 109 100 110 __sync_add_and_fetch(&pkts_redir, 1); 101 111 return bpf_redirect_map(&xsk, ctx->rx_queue_index, XDP_PASS);
+29 -5
tools/testing/selftests/bpf/xdp_hw_metadata.c
··· 21 21 #include "xsk.h" 22 22 23 23 #include <error.h> 24 + #include <linux/kernel.h> 25 + #include <linux/bits.h> 26 + #include <linux/bitfield.h> 24 27 #include <linux/errqueue.h> 25 28 #include <linux/if_link.h> 26 29 #include <linux/net_tstamp.h> ··· 185 182 (double)delta / 1000); 186 183 } 187 184 185 + #define VLAN_PRIO_MASK GENMASK(15, 13) /* Priority Code Point */ 186 + #define VLAN_DEI_MASK GENMASK(12, 12) /* Drop Eligible Indicator */ 187 + #define VLAN_VID_MASK GENMASK(11, 0) /* VLAN Identifier */ 188 + static void print_vlan_tci(__u16 tag) 189 + { 190 + __u16 vlan_id = FIELD_GET(VLAN_VID_MASK, tag); 191 + __u8 pcp = FIELD_GET(VLAN_PRIO_MASK, tag); 192 + bool dei = FIELD_GET(VLAN_DEI_MASK, tag); 193 + 194 + printf("PCP=%u, DEI=%d, VID=0x%X\n", pcp, dei, vlan_id); 195 + } 196 + 188 197 static void verify_xdp_metadata(void *data, clockid_t clock_id) 189 198 { 190 199 struct xdp_meta *meta; 191 200 192 201 meta = data - sizeof(*meta); 193 202 194 - if (meta->rx_hash_err < 0) 195 - printf("No rx_hash err=%d\n", meta->rx_hash_err); 196 - else 203 + if (meta->hint_valid & XDP_META_FIELD_RSS) 197 204 printf("rx_hash: 0x%X with RSS type:0x%X\n", 198 205 meta->rx_hash, meta->rx_hash_type); 206 + else 207 + printf("No rx_hash, err=%d\n", meta->rx_hash_err); 199 208 200 - if (meta->rx_timestamp) { 209 + if (meta->hint_valid & XDP_META_FIELD_TS) { 201 210 __u64 ref_tstamp = gettime(clock_id); 202 211 203 212 /* store received timestamps to calculate a delta at tx */ ··· 221 206 print_tstamp_delta("XDP RX-time", "User RX-time", 222 207 meta->xdp_timestamp, ref_tstamp); 223 208 } else { 224 - printf("No rx_timestamp\n"); 209 + printf("No rx_timestamp, err=%d\n", meta->rx_timestamp_err); 210 + } 211 + 212 + if (meta->hint_valid & XDP_META_FIELD_VLAN_TAG) { 213 + printf("rx_vlan_proto: 0x%X\n", ntohs(meta->rx_vlan_proto)); 214 + printf("rx_vlan_tci: "); 215 + print_vlan_tci(meta->rx_vlan_tci); 216 + } else { 217 + printf("No rx_vlan_tci or rx_vlan_proto, err=%d\n", 218 + meta->rx_vlan_tag_err); 225 219 } 226 220 } 227 221
+25 -1
tools/testing/selftests/bpf/xdp_metadata.h
··· 17 17 #define ETH_P_8021AD 0x88A8 18 18 #endif 19 19 20 + #ifndef BIT 21 + #define BIT(nr) (1 << (nr)) 22 + #endif 23 + 24 + /* Non-existent checksum status */ 25 + #define XDP_CHECKSUM_MAGIC BIT(2) 26 + 27 + enum xdp_meta_field { 28 + XDP_META_FIELD_TS = BIT(0), 29 + XDP_META_FIELD_RSS = BIT(1), 30 + XDP_META_FIELD_VLAN_TAG = BIT(2), 31 + }; 32 + 20 33 struct xdp_meta { 21 - __u64 rx_timestamp; 34 + union { 35 + __u64 rx_timestamp; 36 + __s32 rx_timestamp_err; 37 + }; 22 38 __u64 xdp_timestamp; 23 39 __u32 rx_hash; 24 40 union { 25 41 __u32 rx_hash_type; 26 42 __s32 rx_hash_err; 27 43 }; 44 + union { 45 + struct { 46 + __be16 rx_vlan_proto; 47 + __u16 rx_vlan_tci; 48 + }; 49 + __s32 rx_vlan_tag_err; 50 + }; 51 + enum xdp_meta_field hint_valid; 28 52 };