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

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'xdp-metadata-via-kfuncs-for-ice-vlan-hint'

Larysa Zaremba says:

====================
XDP metadata via kfuncs for ice + VLAN hint

This series introduces XDP hints via kfuncs [0] to the ice driver.

Series brings the following existing hints to the ice driver:
- HW timestamp
- RX hash with type

Series also introduces VLAN tag with protocol XDP hint, it now be accessed by
XDP and userspace (AF_XDP) programs. They can also be checked with xdp_metadata
test and xdp_hw_metadata program.

Impact of these patches on ice performance:
ZC:
* Full hints implementation decreases pps in ZC mode by less than 3%
(64B, rxdrop)

skb (packets with invalid IP, dropped by stack):
* Overall, patchset improves peak performance in skb mode by about 0.5%

[0] https://patchwork.kernel.org/project/netdevbpf/cover/20230119221536.3349901-1-sdf@google.com/

v7:
https://lore.kernel.org/bpf/20231115175301.534113-1-larysa.zaremba@intel.com/
v6:
https://lore.kernel.org/bpf/20231012170524.21085-1-larysa.zaremba@intel.com/
Intermediate RFC v2:
https://lore.kernel.org/bpf/20230927075124.23941-1-larysa.zaremba@intel.com/
Intermediate RFC v1:
https://lore.kernel.org/bpf/20230824192703.712881-1-larysa.zaremba@intel.com/
v5:
https://lore.kernel.org/bpf/20230811161509.19722-1-larysa.zaremba@intel.com/
v4:
https://lore.kernel.org/bpf/20230728173923.1318596-1-larysa.zaremba@intel.com/
v3:
https://lore.kernel.org/bpf/20230719183734.21681-1-larysa.zaremba@intel.com/
v2:
https://lore.kernel.org/bpf/20230703181226.19380-1-larysa.zaremba@intel.com/
v1:
https://lore.kernel.org/all/20230512152607.992209-1-larysa.zaremba@intel.com/

Changes since v7:
* shorten timestamp assignment in ice
* change first argument of ice_fill_rx_descs back to xsk_buff_pool
* fix kernel-doc for ice_run_xdp_zc
* add missing XSK_CHECK_PRIV_TYPE() in ice
* resolved selftests merge conflicts with TX hints
* AF_INET patch adds new packet generation, not replaces AF_XDP one
* fix destination port in xdp_metadata

Changes since v6:
* add ability to fill cb of all xdp_buffs in xsk_buff_pool
* place just pointer to packet context in ice_xdp_buff
* add const qualifiers in veth implementation
* generate uapi for VLAN hint

Changes since v5:
* drop checksum hint from the patchset entirely
* Alex's patch that lifts the data_meta size limitation is no longer
required in this patchset, so will be sent separately
* new patch: hide some ice hints code behind a static key
* fix several bugs in ZC mode (ice)
* change argument order in VLAN hint kfunc (tci, proto -> proto, tci)
* cosmetic changes
* analyze performance impact

Changes since v4:
* Drop the concept of partial checksum from the hint design
* Drop the concept of checksum level from the hint design

Changes since v3:
* use XDP_CHECKSUM_VALID_LVL0 + csum_level instead of csum_level + 1
* fix spelling mistakes
* read XDP timestamp unconditionally
* add TO_STR() macro

Changes since v2:
* redesign checksum hint, so now it gives full status
* rename vlan_tag -> vlan_tci, where applicable
* use open_netns() and close_netns() in xdp_metadata
* improve VLAN hint documentation
* replace CFI with DEI
* use VLAN_VID_MASK in xdp_metadata
* make vlan_get_tag() return -ENODATA
* remove unused rx_ptype in ice_xsk.c
* fix ice timestamp code division between patches

Changes since v1:
* directly return RX hash, RX timestamp and RX checksum status
in skb-common functions
* use intermediate enum value for checksum status in ice
* get rid of ring structure dependency in ice kfunc implementation
* make variables const, when possible, in ice implementation
* use -ENODATA instead of -EOPNOTSUPP for driver implementation
* instead of having 2 separate functions for c-tag and s-tag,
use 1 function that outputs both VLAN tag and protocol ID
* improve documentation for introduced hints
* update xdp_metadata selftest to test new hints
* implement new hints in veth, so they can be tested in xdp_metadata
* parse VLAN tag in xdp_hw_metadata
====================

Link: https://lore.kernel.org/r/20231205210847.28460-1-larysa.zaremba@intel.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

+852 -311
+4
Documentation/netlink/specs/netdev.yaml
··· 54 54 name: hash 55 55 doc: 56 56 Device is capable of exposing receive packet hash via bpf_xdp_metadata_rx_hash(). 57 + - 58 + name: vlan-tag 59 + doc: 60 + Device is capable of exposing receive packet VLAN tag via bpf_xdp_metadata_rx_vlan_tag(). 57 61 - 58 62 type: flags 59 63 name: xsk-flags
+7 -1
Documentation/networking/xdp-rx-metadata.rst
··· 20 20 metadata is supported, this set will grow: 21 21 22 22 .. kernel-doc:: net/core/xdp.c 23 - :identifiers: bpf_xdp_metadata_rx_timestamp bpf_xdp_metadata_rx_hash 23 + :identifiers: bpf_xdp_metadata_rx_timestamp 24 + 25 + .. kernel-doc:: net/core/xdp.c 26 + :identifiers: bpf_xdp_metadata_rx_hash 27 + 28 + .. kernel-doc:: net/core/xdp.c 29 + :identifiers: bpf_xdp_metadata_rx_vlan_tag 24 30 25 31 An XDP program can use these kfuncs to read the metadata into stack 26 32 variables for its own consumption. Or, to pass the metadata on to other
+2
drivers/net/ethernet/intel/ice/ice.h
··· 996 996 set_bit(ICE_FLAG_UNPLUG_AUX_DEV, pf->flags); 997 997 clear_bit(ICE_FLAG_RDMA_ENA, pf->flags); 998 998 } 999 + 1000 + extern const struct xdp_metadata_ops ice_xdp_md_ops; 999 1001 #endif /* _ICE_H_ */
+15
drivers/net/ethernet/intel/ice/ice_base.c
··· 519 519 return 0; 520 520 } 521 521 522 + static void ice_xsk_pool_fill_cb(struct ice_rx_ring *ring) 523 + { 524 + void *ctx_ptr = &ring->pkt_ctx; 525 + struct xsk_cb_desc desc = {}; 526 + 527 + XSK_CHECK_PRIV_TYPE(struct ice_xdp_buff); 528 + desc.src = &ctx_ptr; 529 + desc.off = offsetof(struct ice_xdp_buff, pkt_ctx) - 530 + sizeof(struct xdp_buff); 531 + desc.bytes = sizeof(ctx_ptr); 532 + xsk_pool_fill_cb(ring->xsk_pool, &desc); 533 + } 534 + 522 535 /** 523 536 * ice_vsi_cfg_rxq - Configure an Rx queue 524 537 * @ring: the ring being configured ··· 566 553 if (err) 567 554 return err; 568 555 xsk_pool_set_rxq_info(ring->xsk_pool, &ring->xdp_rxq); 556 + ice_xsk_pool_fill_cb(ring); 569 557 570 558 dev_info(dev, "Registered XDP mem model MEM_TYPE_XSK_BUFF_POOL on Rx ring %d\n", 571 559 ring->q_index); ··· 589 575 590 576 xdp_init_buff(&ring->xdp, ice_rx_pg_size(ring) / 2, &ring->xdp_rxq); 591 577 ring->xdp.data = NULL; 578 + ring->xdp_ext.pkt_ctx = &ring->pkt_ctx; 592 579 err = ice_setup_rx_ctx(ring); 593 580 if (err) { 594 581 dev_err(dev, "ice_setup_rx_ctx failed for RxQ %d, err %d\n",
+208 -204
drivers/net/ethernet/intel/ice/ice_lan_tx_rx.h
··· 673 673 * Use the enum ice_rx_l2_ptype to decode the packet type 674 674 * ENDIF 675 675 */ 676 + #define ICE_PTYPES \ 677 + /* L2 Packet types */ \ 678 + ICE_PTT_UNUSED_ENTRY(0), \ 679 + ICE_PTT(1, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2), \ 680 + ICE_PTT_UNUSED_ENTRY(2), \ 681 + ICE_PTT_UNUSED_ENTRY(3), \ 682 + ICE_PTT_UNUSED_ENTRY(4), \ 683 + ICE_PTT_UNUSED_ENTRY(5), \ 684 + ICE_PTT(6, L2, NONE, NOF, NONE, NONE, NOF, NONE, NONE), \ 685 + ICE_PTT(7, L2, NONE, NOF, NONE, NONE, NOF, NONE, NONE), \ 686 + ICE_PTT_UNUSED_ENTRY(8), \ 687 + ICE_PTT_UNUSED_ENTRY(9), \ 688 + ICE_PTT(10, L2, NONE, NOF, NONE, NONE, NOF, NONE, NONE), \ 689 + ICE_PTT(11, L2, NONE, NOF, NONE, NONE, NOF, NONE, NONE), \ 690 + ICE_PTT_UNUSED_ENTRY(12), \ 691 + ICE_PTT_UNUSED_ENTRY(13), \ 692 + ICE_PTT_UNUSED_ENTRY(14), \ 693 + ICE_PTT_UNUSED_ENTRY(15), \ 694 + ICE_PTT_UNUSED_ENTRY(16), \ 695 + ICE_PTT_UNUSED_ENTRY(17), \ 696 + ICE_PTT_UNUSED_ENTRY(18), \ 697 + ICE_PTT_UNUSED_ENTRY(19), \ 698 + ICE_PTT_UNUSED_ENTRY(20), \ 699 + ICE_PTT_UNUSED_ENTRY(21), \ 700 + \ 701 + /* Non Tunneled IPv4 */ \ 702 + ICE_PTT(22, IP, IPV4, FRG, NONE, NONE, NOF, NONE, PAY3), \ 703 + ICE_PTT(23, IP, IPV4, NOF, NONE, NONE, NOF, NONE, PAY3), \ 704 + ICE_PTT(24, IP, IPV4, NOF, NONE, NONE, NOF, UDP, PAY4), \ 705 + ICE_PTT_UNUSED_ENTRY(25), \ 706 + ICE_PTT(26, IP, IPV4, NOF, NONE, NONE, NOF, TCP, PAY4), \ 707 + ICE_PTT(27, IP, IPV4, NOF, NONE, NONE, NOF, SCTP, PAY4), \ 708 + ICE_PTT(28, IP, IPV4, NOF, NONE, NONE, NOF, ICMP, PAY4), \ 709 + \ 710 + /* IPv4 --> IPv4 */ \ 711 + ICE_PTT(29, IP, IPV4, NOF, IP_IP, IPV4, FRG, NONE, PAY3), \ 712 + ICE_PTT(30, IP, IPV4, NOF, IP_IP, IPV4, NOF, NONE, PAY3), \ 713 + ICE_PTT(31, IP, IPV4, NOF, IP_IP, IPV4, NOF, UDP, PAY4), \ 714 + ICE_PTT_UNUSED_ENTRY(32), \ 715 + ICE_PTT(33, IP, IPV4, NOF, IP_IP, IPV4, NOF, TCP, PAY4), \ 716 + ICE_PTT(34, IP, IPV4, NOF, IP_IP, IPV4, NOF, SCTP, PAY4), \ 717 + ICE_PTT(35, IP, IPV4, NOF, IP_IP, IPV4, NOF, ICMP, PAY4), \ 718 + \ 719 + /* IPv4 --> IPv6 */ \ 720 + ICE_PTT(36, IP, IPV4, NOF, IP_IP, IPV6, FRG, NONE, PAY3), \ 721 + ICE_PTT(37, IP, IPV4, NOF, IP_IP, IPV6, NOF, NONE, PAY3), \ 722 + ICE_PTT(38, IP, IPV4, NOF, IP_IP, IPV6, NOF, UDP, PAY4), \ 723 + ICE_PTT_UNUSED_ENTRY(39), \ 724 + ICE_PTT(40, IP, IPV4, NOF, IP_IP, IPV6, NOF, TCP, PAY4), \ 725 + ICE_PTT(41, IP, IPV4, NOF, IP_IP, IPV6, NOF, SCTP, PAY4), \ 726 + ICE_PTT(42, IP, IPV4, NOF, IP_IP, IPV6, NOF, ICMP, PAY4), \ 727 + \ 728 + /* IPv4 --> GRE/NAT */ \ 729 + ICE_PTT(43, IP, IPV4, NOF, IP_GRENAT, NONE, NOF, NONE, PAY3), \ 730 + \ 731 + /* IPv4 --> GRE/NAT --> IPv4 */ \ 732 + ICE_PTT(44, IP, IPV4, NOF, IP_GRENAT, IPV4, FRG, NONE, PAY3), \ 733 + ICE_PTT(45, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, NONE, PAY3), \ 734 + ICE_PTT(46, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, UDP, PAY4), \ 735 + ICE_PTT_UNUSED_ENTRY(47), \ 736 + ICE_PTT(48, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, TCP, PAY4), \ 737 + ICE_PTT(49, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, SCTP, PAY4), \ 738 + ICE_PTT(50, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, ICMP, PAY4), \ 739 + \ 740 + /* IPv4 --> GRE/NAT --> IPv6 */ \ 741 + ICE_PTT(51, IP, IPV4, NOF, IP_GRENAT, IPV6, FRG, NONE, PAY3), \ 742 + ICE_PTT(52, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, NONE, PAY3), \ 743 + ICE_PTT(53, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, UDP, PAY4), \ 744 + ICE_PTT_UNUSED_ENTRY(54), \ 745 + ICE_PTT(55, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, TCP, PAY4), \ 746 + ICE_PTT(56, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, SCTP, PAY4), \ 747 + ICE_PTT(57, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, ICMP, PAY4), \ 748 + \ 749 + /* IPv4 --> GRE/NAT --> MAC */ \ 750 + ICE_PTT(58, IP, IPV4, NOF, IP_GRENAT_MAC, NONE, NOF, NONE, PAY3), \ 751 + \ 752 + /* IPv4 --> GRE/NAT --> MAC --> IPv4 */ \ 753 + ICE_PTT(59, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, FRG, NONE, PAY3), \ 754 + ICE_PTT(60, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, NONE, PAY3), \ 755 + ICE_PTT(61, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, UDP, PAY4), \ 756 + ICE_PTT_UNUSED_ENTRY(62), \ 757 + ICE_PTT(63, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, TCP, PAY4), \ 758 + ICE_PTT(64, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, SCTP, PAY4), \ 759 + ICE_PTT(65, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, ICMP, PAY4), \ 760 + \ 761 + /* IPv4 --> GRE/NAT -> MAC --> IPv6 */ \ 762 + ICE_PTT(66, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, FRG, NONE, PAY3), \ 763 + ICE_PTT(67, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, NONE, PAY3), \ 764 + ICE_PTT(68, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, UDP, PAY4), \ 765 + ICE_PTT_UNUSED_ENTRY(69), \ 766 + ICE_PTT(70, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, TCP, PAY4), \ 767 + ICE_PTT(71, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, SCTP, PAY4), \ 768 + ICE_PTT(72, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, ICMP, PAY4), \ 769 + \ 770 + /* IPv4 --> GRE/NAT --> MAC/VLAN */ \ 771 + ICE_PTT(73, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, NONE, NOF, NONE, PAY3), \ 772 + \ 773 + /* IPv4 ---> GRE/NAT -> MAC/VLAN --> IPv4 */ \ 774 + ICE_PTT(74, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, FRG, NONE, PAY3), \ 775 + ICE_PTT(75, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, NONE, PAY3), \ 776 + ICE_PTT(76, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, UDP, PAY4), \ 777 + ICE_PTT_UNUSED_ENTRY(77), \ 778 + ICE_PTT(78, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, TCP, PAY4), \ 779 + ICE_PTT(79, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, SCTP, PAY4), \ 780 + ICE_PTT(80, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, ICMP, PAY4), \ 781 + \ 782 + /* IPv4 -> GRE/NAT -> MAC/VLAN --> IPv6 */ \ 783 + ICE_PTT(81, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, FRG, NONE, PAY3), \ 784 + ICE_PTT(82, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, NONE, PAY3), \ 785 + ICE_PTT(83, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, UDP, PAY4), \ 786 + ICE_PTT_UNUSED_ENTRY(84), \ 787 + ICE_PTT(85, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, TCP, PAY4), \ 788 + ICE_PTT(86, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, SCTP, PAY4), \ 789 + ICE_PTT(87, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, ICMP, PAY4), \ 790 + \ 791 + /* Non Tunneled IPv6 */ \ 792 + ICE_PTT(88, IP, IPV6, FRG, NONE, NONE, NOF, NONE, PAY3), \ 793 + ICE_PTT(89, IP, IPV6, NOF, NONE, NONE, NOF, NONE, PAY3), \ 794 + ICE_PTT(90, IP, IPV6, NOF, NONE, NONE, NOF, UDP, PAY4), \ 795 + ICE_PTT_UNUSED_ENTRY(91), \ 796 + ICE_PTT(92, IP, IPV6, NOF, NONE, NONE, NOF, TCP, PAY4), \ 797 + ICE_PTT(93, IP, IPV6, NOF, NONE, NONE, NOF, SCTP, PAY4), \ 798 + ICE_PTT(94, IP, IPV6, NOF, NONE, NONE, NOF, ICMP, PAY4), \ 799 + \ 800 + /* IPv6 --> IPv4 */ \ 801 + ICE_PTT(95, IP, IPV6, NOF, IP_IP, IPV4, FRG, NONE, PAY3), \ 802 + ICE_PTT(96, IP, IPV6, NOF, IP_IP, IPV4, NOF, NONE, PAY3), \ 803 + ICE_PTT(97, IP, IPV6, NOF, IP_IP, IPV4, NOF, UDP, PAY4), \ 804 + ICE_PTT_UNUSED_ENTRY(98), \ 805 + ICE_PTT(99, IP, IPV6, NOF, IP_IP, IPV4, NOF, TCP, PAY4), \ 806 + ICE_PTT(100, IP, IPV6, NOF, IP_IP, IPV4, NOF, SCTP, PAY4), \ 807 + ICE_PTT(101, IP, IPV6, NOF, IP_IP, IPV4, NOF, ICMP, PAY4), \ 808 + \ 809 + /* IPv6 --> IPv6 */ \ 810 + ICE_PTT(102, IP, IPV6, NOF, IP_IP, IPV6, FRG, NONE, PAY3), \ 811 + ICE_PTT(103, IP, IPV6, NOF, IP_IP, IPV6, NOF, NONE, PAY3), \ 812 + ICE_PTT(104, IP, IPV6, NOF, IP_IP, IPV6, NOF, UDP, PAY4), \ 813 + ICE_PTT_UNUSED_ENTRY(105), \ 814 + ICE_PTT(106, IP, IPV6, NOF, IP_IP, IPV6, NOF, TCP, PAY4), \ 815 + ICE_PTT(107, IP, IPV6, NOF, IP_IP, IPV6, NOF, SCTP, PAY4), \ 816 + ICE_PTT(108, IP, IPV6, NOF, IP_IP, IPV6, NOF, ICMP, PAY4), \ 817 + \ 818 + /* IPv6 --> GRE/NAT */ \ 819 + ICE_PTT(109, IP, IPV6, NOF, IP_GRENAT, NONE, NOF, NONE, PAY3), \ 820 + \ 821 + /* IPv6 --> GRE/NAT -> IPv4 */ \ 822 + ICE_PTT(110, IP, IPV6, NOF, IP_GRENAT, IPV4, FRG, NONE, PAY3), \ 823 + ICE_PTT(111, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, NONE, PAY3), \ 824 + ICE_PTT(112, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, UDP, PAY4), \ 825 + ICE_PTT_UNUSED_ENTRY(113), \ 826 + ICE_PTT(114, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, TCP, PAY4), \ 827 + ICE_PTT(115, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, SCTP, PAY4), \ 828 + ICE_PTT(116, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, ICMP, PAY4), \ 829 + \ 830 + /* IPv6 --> GRE/NAT -> IPv6 */ \ 831 + ICE_PTT(117, IP, IPV6, NOF, IP_GRENAT, IPV6, FRG, NONE, PAY3), \ 832 + ICE_PTT(118, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, NONE, PAY3), \ 833 + ICE_PTT(119, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, UDP, PAY4), \ 834 + ICE_PTT_UNUSED_ENTRY(120), \ 835 + ICE_PTT(121, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, TCP, PAY4), \ 836 + ICE_PTT(122, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, SCTP, PAY4), \ 837 + ICE_PTT(123, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, ICMP, PAY4), \ 838 + \ 839 + /* IPv6 --> GRE/NAT -> MAC */ \ 840 + ICE_PTT(124, IP, IPV6, NOF, IP_GRENAT_MAC, NONE, NOF, NONE, PAY3), \ 841 + \ 842 + /* IPv6 --> GRE/NAT -> MAC -> IPv4 */ \ 843 + ICE_PTT(125, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, FRG, NONE, PAY3), \ 844 + ICE_PTT(126, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, NONE, PAY3), \ 845 + ICE_PTT(127, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, UDP, PAY4), \ 846 + ICE_PTT_UNUSED_ENTRY(128), \ 847 + ICE_PTT(129, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, TCP, PAY4), \ 848 + ICE_PTT(130, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, SCTP, PAY4), \ 849 + ICE_PTT(131, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, ICMP, PAY4), \ 850 + \ 851 + /* IPv6 --> GRE/NAT -> MAC -> IPv6 */ \ 852 + ICE_PTT(132, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, FRG, NONE, PAY3), \ 853 + ICE_PTT(133, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, NONE, PAY3), \ 854 + ICE_PTT(134, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, UDP, PAY4), \ 855 + ICE_PTT_UNUSED_ENTRY(135), \ 856 + ICE_PTT(136, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, TCP, PAY4), \ 857 + ICE_PTT(137, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, SCTP, PAY4), \ 858 + ICE_PTT(138, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, ICMP, PAY4), \ 859 + \ 860 + /* IPv6 --> GRE/NAT -> MAC/VLAN */ \ 861 + ICE_PTT(139, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, NONE, NOF, NONE, PAY3), \ 862 + \ 863 + /* IPv6 --> GRE/NAT -> MAC/VLAN --> IPv4 */ \ 864 + ICE_PTT(140, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, FRG, NONE, PAY3), \ 865 + ICE_PTT(141, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, NONE, PAY3), \ 866 + ICE_PTT(142, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, UDP, PAY4), \ 867 + ICE_PTT_UNUSED_ENTRY(143), \ 868 + ICE_PTT(144, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, TCP, PAY4), \ 869 + ICE_PTT(145, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, SCTP, PAY4), \ 870 + ICE_PTT(146, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, ICMP, PAY4), \ 871 + \ 872 + /* IPv6 --> GRE/NAT -> MAC/VLAN --> IPv6 */ \ 873 + ICE_PTT(147, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, FRG, NONE, PAY3), \ 874 + ICE_PTT(148, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, NONE, PAY3), \ 875 + ICE_PTT(149, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, UDP, PAY4), \ 876 + ICE_PTT_UNUSED_ENTRY(150), \ 877 + ICE_PTT(151, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, TCP, PAY4), \ 878 + ICE_PTT(152, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, SCTP, PAY4), \ 879 + ICE_PTT(153, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, ICMP, PAY4), 880 + 881 + #define ICE_NUM_DEFINED_PTYPES 154 676 882 677 883 /* macro to make the table lines short, use explicit indexing with [PTYPE] */ 678 884 #define ICE_PTT(PTYPE, OUTER_IP, OUTER_IP_VER, OUTER_FRAG, T, TE, TEF, I, PL)\ ··· 901 695 902 696 /* Lookup table mapping in the 10-bit HW PTYPE to the bit field for decoding */ 903 697 static const struct ice_rx_ptype_decoded ice_ptype_lkup[BIT(10)] = { 904 - /* L2 Packet types */ 905 - ICE_PTT_UNUSED_ENTRY(0), 906 - ICE_PTT(1, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2), 907 - ICE_PTT_UNUSED_ENTRY(2), 908 - ICE_PTT_UNUSED_ENTRY(3), 909 - ICE_PTT_UNUSED_ENTRY(4), 910 - ICE_PTT_UNUSED_ENTRY(5), 911 - ICE_PTT(6, L2, NONE, NOF, NONE, NONE, NOF, NONE, NONE), 912 - ICE_PTT(7, L2, NONE, NOF, NONE, NONE, NOF, NONE, NONE), 913 - ICE_PTT_UNUSED_ENTRY(8), 914 - ICE_PTT_UNUSED_ENTRY(9), 915 - ICE_PTT(10, L2, NONE, NOF, NONE, NONE, NOF, NONE, NONE), 916 - ICE_PTT(11, L2, NONE, NOF, NONE, NONE, NOF, NONE, NONE), 917 - ICE_PTT_UNUSED_ENTRY(12), 918 - ICE_PTT_UNUSED_ENTRY(13), 919 - ICE_PTT_UNUSED_ENTRY(14), 920 - ICE_PTT_UNUSED_ENTRY(15), 921 - ICE_PTT_UNUSED_ENTRY(16), 922 - ICE_PTT_UNUSED_ENTRY(17), 923 - ICE_PTT_UNUSED_ENTRY(18), 924 - ICE_PTT_UNUSED_ENTRY(19), 925 - ICE_PTT_UNUSED_ENTRY(20), 926 - ICE_PTT_UNUSED_ENTRY(21), 927 - 928 - /* Non Tunneled IPv4 */ 929 - ICE_PTT(22, IP, IPV4, FRG, NONE, NONE, NOF, NONE, PAY3), 930 - ICE_PTT(23, IP, IPV4, NOF, NONE, NONE, NOF, NONE, PAY3), 931 - ICE_PTT(24, IP, IPV4, NOF, NONE, NONE, NOF, UDP, PAY4), 932 - ICE_PTT_UNUSED_ENTRY(25), 933 - ICE_PTT(26, IP, IPV4, NOF, NONE, NONE, NOF, TCP, PAY4), 934 - ICE_PTT(27, IP, IPV4, NOF, NONE, NONE, NOF, SCTP, PAY4), 935 - ICE_PTT(28, IP, IPV4, NOF, NONE, NONE, NOF, ICMP, PAY4), 936 - 937 - /* IPv4 --> IPv4 */ 938 - ICE_PTT(29, IP, IPV4, NOF, IP_IP, IPV4, FRG, NONE, PAY3), 939 - ICE_PTT(30, IP, IPV4, NOF, IP_IP, IPV4, NOF, NONE, PAY3), 940 - ICE_PTT(31, IP, IPV4, NOF, IP_IP, IPV4, NOF, UDP, PAY4), 941 - ICE_PTT_UNUSED_ENTRY(32), 942 - ICE_PTT(33, IP, IPV4, NOF, IP_IP, IPV4, NOF, TCP, PAY4), 943 - ICE_PTT(34, IP, IPV4, NOF, IP_IP, IPV4, NOF, SCTP, PAY4), 944 - ICE_PTT(35, IP, IPV4, NOF, IP_IP, IPV4, NOF, ICMP, PAY4), 945 - 946 - /* IPv4 --> IPv6 */ 947 - ICE_PTT(36, IP, IPV4, NOF, IP_IP, IPV6, FRG, NONE, PAY3), 948 - ICE_PTT(37, IP, IPV4, NOF, IP_IP, IPV6, NOF, NONE, PAY3), 949 - ICE_PTT(38, IP, IPV4, NOF, IP_IP, IPV6, NOF, UDP, PAY4), 950 - ICE_PTT_UNUSED_ENTRY(39), 951 - ICE_PTT(40, IP, IPV4, NOF, IP_IP, IPV6, NOF, TCP, PAY4), 952 - ICE_PTT(41, IP, IPV4, NOF, IP_IP, IPV6, NOF, SCTP, PAY4), 953 - ICE_PTT(42, IP, IPV4, NOF, IP_IP, IPV6, NOF, ICMP, PAY4), 954 - 955 - /* IPv4 --> GRE/NAT */ 956 - ICE_PTT(43, IP, IPV4, NOF, IP_GRENAT, NONE, NOF, NONE, PAY3), 957 - 958 - /* IPv4 --> GRE/NAT --> IPv4 */ 959 - ICE_PTT(44, IP, IPV4, NOF, IP_GRENAT, IPV4, FRG, NONE, PAY3), 960 - ICE_PTT(45, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, NONE, PAY3), 961 - ICE_PTT(46, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, UDP, PAY4), 962 - ICE_PTT_UNUSED_ENTRY(47), 963 - ICE_PTT(48, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, TCP, PAY4), 964 - ICE_PTT(49, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, SCTP, PAY4), 965 - ICE_PTT(50, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, ICMP, PAY4), 966 - 967 - /* IPv4 --> GRE/NAT --> IPv6 */ 968 - ICE_PTT(51, IP, IPV4, NOF, IP_GRENAT, IPV6, FRG, NONE, PAY3), 969 - ICE_PTT(52, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, NONE, PAY3), 970 - ICE_PTT(53, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, UDP, PAY4), 971 - ICE_PTT_UNUSED_ENTRY(54), 972 - ICE_PTT(55, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, TCP, PAY4), 973 - ICE_PTT(56, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, SCTP, PAY4), 974 - ICE_PTT(57, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, ICMP, PAY4), 975 - 976 - /* IPv4 --> GRE/NAT --> MAC */ 977 - ICE_PTT(58, IP, IPV4, NOF, IP_GRENAT_MAC, NONE, NOF, NONE, PAY3), 978 - 979 - /* IPv4 --> GRE/NAT --> MAC --> IPv4 */ 980 - ICE_PTT(59, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, FRG, NONE, PAY3), 981 - ICE_PTT(60, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, NONE, PAY3), 982 - ICE_PTT(61, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, UDP, PAY4), 983 - ICE_PTT_UNUSED_ENTRY(62), 984 - ICE_PTT(63, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, TCP, PAY4), 985 - ICE_PTT(64, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, SCTP, PAY4), 986 - ICE_PTT(65, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, ICMP, PAY4), 987 - 988 - /* IPv4 --> GRE/NAT -> MAC --> IPv6 */ 989 - ICE_PTT(66, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, FRG, NONE, PAY3), 990 - ICE_PTT(67, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, NONE, PAY3), 991 - ICE_PTT(68, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, UDP, PAY4), 992 - ICE_PTT_UNUSED_ENTRY(69), 993 - ICE_PTT(70, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, TCP, PAY4), 994 - ICE_PTT(71, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, SCTP, PAY4), 995 - ICE_PTT(72, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, ICMP, PAY4), 996 - 997 - /* IPv4 --> GRE/NAT --> MAC/VLAN */ 998 - ICE_PTT(73, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, NONE, NOF, NONE, PAY3), 999 - 1000 - /* IPv4 ---> GRE/NAT -> MAC/VLAN --> IPv4 */ 1001 - ICE_PTT(74, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, FRG, NONE, PAY3), 1002 - ICE_PTT(75, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, NONE, PAY3), 1003 - ICE_PTT(76, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, UDP, PAY4), 1004 - ICE_PTT_UNUSED_ENTRY(77), 1005 - ICE_PTT(78, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, TCP, PAY4), 1006 - ICE_PTT(79, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, SCTP, PAY4), 1007 - ICE_PTT(80, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, ICMP, PAY4), 1008 - 1009 - /* IPv4 -> GRE/NAT -> MAC/VLAN --> IPv6 */ 1010 - ICE_PTT(81, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, FRG, NONE, PAY3), 1011 - ICE_PTT(82, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, NONE, PAY3), 1012 - ICE_PTT(83, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, UDP, PAY4), 1013 - ICE_PTT_UNUSED_ENTRY(84), 1014 - ICE_PTT(85, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, TCP, PAY4), 1015 - ICE_PTT(86, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, SCTP, PAY4), 1016 - ICE_PTT(87, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, ICMP, PAY4), 1017 - 1018 - /* Non Tunneled IPv6 */ 1019 - ICE_PTT(88, IP, IPV6, FRG, NONE, NONE, NOF, NONE, PAY3), 1020 - ICE_PTT(89, IP, IPV6, NOF, NONE, NONE, NOF, NONE, PAY3), 1021 - ICE_PTT(90, IP, IPV6, NOF, NONE, NONE, NOF, UDP, PAY4), 1022 - ICE_PTT_UNUSED_ENTRY(91), 1023 - ICE_PTT(92, IP, IPV6, NOF, NONE, NONE, NOF, TCP, PAY4), 1024 - ICE_PTT(93, IP, IPV6, NOF, NONE, NONE, NOF, SCTP, PAY4), 1025 - ICE_PTT(94, IP, IPV6, NOF, NONE, NONE, NOF, ICMP, PAY4), 1026 - 1027 - /* IPv6 --> IPv4 */ 1028 - ICE_PTT(95, IP, IPV6, NOF, IP_IP, IPV4, FRG, NONE, PAY3), 1029 - ICE_PTT(96, IP, IPV6, NOF, IP_IP, IPV4, NOF, NONE, PAY3), 1030 - ICE_PTT(97, IP, IPV6, NOF, IP_IP, IPV4, NOF, UDP, PAY4), 1031 - ICE_PTT_UNUSED_ENTRY(98), 1032 - ICE_PTT(99, IP, IPV6, NOF, IP_IP, IPV4, NOF, TCP, PAY4), 1033 - ICE_PTT(100, IP, IPV6, NOF, IP_IP, IPV4, NOF, SCTP, PAY4), 1034 - ICE_PTT(101, IP, IPV6, NOF, IP_IP, IPV4, NOF, ICMP, PAY4), 1035 - 1036 - /* IPv6 --> IPv6 */ 1037 - ICE_PTT(102, IP, IPV6, NOF, IP_IP, IPV6, FRG, NONE, PAY3), 1038 - ICE_PTT(103, IP, IPV6, NOF, IP_IP, IPV6, NOF, NONE, PAY3), 1039 - ICE_PTT(104, IP, IPV6, NOF, IP_IP, IPV6, NOF, UDP, PAY4), 1040 - ICE_PTT_UNUSED_ENTRY(105), 1041 - ICE_PTT(106, IP, IPV6, NOF, IP_IP, IPV6, NOF, TCP, PAY4), 1042 - ICE_PTT(107, IP, IPV6, NOF, IP_IP, IPV6, NOF, SCTP, PAY4), 1043 - ICE_PTT(108, IP, IPV6, NOF, IP_IP, IPV6, NOF, ICMP, PAY4), 1044 - 1045 - /* IPv6 --> GRE/NAT */ 1046 - ICE_PTT(109, IP, IPV6, NOF, IP_GRENAT, NONE, NOF, NONE, PAY3), 1047 - 1048 - /* IPv6 --> GRE/NAT -> IPv4 */ 1049 - ICE_PTT(110, IP, IPV6, NOF, IP_GRENAT, IPV4, FRG, NONE, PAY3), 1050 - ICE_PTT(111, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, NONE, PAY3), 1051 - ICE_PTT(112, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, UDP, PAY4), 1052 - ICE_PTT_UNUSED_ENTRY(113), 1053 - ICE_PTT(114, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, TCP, PAY4), 1054 - ICE_PTT(115, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, SCTP, PAY4), 1055 - ICE_PTT(116, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, ICMP, PAY4), 1056 - 1057 - /* IPv6 --> GRE/NAT -> IPv6 */ 1058 - ICE_PTT(117, IP, IPV6, NOF, IP_GRENAT, IPV6, FRG, NONE, PAY3), 1059 - ICE_PTT(118, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, NONE, PAY3), 1060 - ICE_PTT(119, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, UDP, PAY4), 1061 - ICE_PTT_UNUSED_ENTRY(120), 1062 - ICE_PTT(121, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, TCP, PAY4), 1063 - ICE_PTT(122, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, SCTP, PAY4), 1064 - ICE_PTT(123, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, ICMP, PAY4), 1065 - 1066 - /* IPv6 --> GRE/NAT -> MAC */ 1067 - ICE_PTT(124, IP, IPV6, NOF, IP_GRENAT_MAC, NONE, NOF, NONE, PAY3), 1068 - 1069 - /* IPv6 --> GRE/NAT -> MAC -> IPv4 */ 1070 - ICE_PTT(125, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, FRG, NONE, PAY3), 1071 - ICE_PTT(126, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, NONE, PAY3), 1072 - ICE_PTT(127, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, UDP, PAY4), 1073 - ICE_PTT_UNUSED_ENTRY(128), 1074 - ICE_PTT(129, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, TCP, PAY4), 1075 - ICE_PTT(130, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, SCTP, PAY4), 1076 - ICE_PTT(131, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, ICMP, PAY4), 1077 - 1078 - /* IPv6 --> GRE/NAT -> MAC -> IPv6 */ 1079 - ICE_PTT(132, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, FRG, NONE, PAY3), 1080 - ICE_PTT(133, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, NONE, PAY3), 1081 - ICE_PTT(134, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, UDP, PAY4), 1082 - ICE_PTT_UNUSED_ENTRY(135), 1083 - ICE_PTT(136, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, TCP, PAY4), 1084 - ICE_PTT(137, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, SCTP, PAY4), 1085 - ICE_PTT(138, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, ICMP, PAY4), 1086 - 1087 - /* IPv6 --> GRE/NAT -> MAC/VLAN */ 1088 - ICE_PTT(139, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, NONE, NOF, NONE, PAY3), 1089 - 1090 - /* IPv6 --> GRE/NAT -> MAC/VLAN --> IPv4 */ 1091 - ICE_PTT(140, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, FRG, NONE, PAY3), 1092 - ICE_PTT(141, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, NONE, PAY3), 1093 - ICE_PTT(142, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, UDP, PAY4), 1094 - ICE_PTT_UNUSED_ENTRY(143), 1095 - ICE_PTT(144, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, TCP, PAY4), 1096 - ICE_PTT(145, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, SCTP, PAY4), 1097 - ICE_PTT(146, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, ICMP, PAY4), 1098 - 1099 - /* IPv6 --> GRE/NAT -> MAC/VLAN --> IPv6 */ 1100 - ICE_PTT(147, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, FRG, NONE, PAY3), 1101 - ICE_PTT(148, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, NONE, PAY3), 1102 - ICE_PTT(149, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, UDP, PAY4), 1103 - ICE_PTT_UNUSED_ENTRY(150), 1104 - ICE_PTT(151, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, TCP, PAY4), 1105 - ICE_PTT(152, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, SCTP, PAY4), 1106 - ICE_PTT(153, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, ICMP, PAY4), 698 + ICE_PTYPES 1107 699 1108 700 /* unused entries */ 1109 - [154 ... 1023] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 } 701 + [ICE_NUM_DEFINED_PTYPES ... 1023] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 } 1110 702 }; 1111 703 1112 704 static inline struct ice_rx_ptype_decoded ice_decode_rx_desc_ptype(u16 ptype)
+21
drivers/net/ethernet/intel/ice/ice_main.c
··· 3397 3397 3398 3398 netdev->netdev_ops = &ice_netdev_ops; 3399 3399 netdev->udp_tunnel_nic_info = &pf->hw.udp_tunnel_nic; 3400 + netdev->xdp_metadata_ops = &ice_xdp_md_ops; 3400 3401 ice_set_ethtool_ops(netdev); 3401 3402 3402 3403 if (vsi->type != ICE_VSI_PF) ··· 6044 6043 } 6045 6044 6046 6045 /** 6046 + * ice_set_rx_rings_vlan_proto - update rings with new stripped VLAN proto 6047 + * @vsi: PF's VSI 6048 + * @vlan_ethertype: VLAN ethertype (802.1Q or 802.1ad) in network byte order 6049 + * 6050 + * Store current stripped VLAN proto in ring packet context, 6051 + * so it can be accessed more efficiently by packet processing code. 6052 + */ 6053 + static void 6054 + ice_set_rx_rings_vlan_proto(struct ice_vsi *vsi, __be16 vlan_ethertype) 6055 + { 6056 + u16 i; 6057 + 6058 + ice_for_each_alloc_rxq(vsi, i) 6059 + vsi->rx_rings[i]->pkt_ctx.vlan_proto = vlan_ethertype; 6060 + } 6061 + 6062 + /** 6047 6063 * ice_set_vlan_offload_features - set VLAN offload features for the PF VSI 6048 6064 * @vsi: PF's VSI 6049 6065 * @features: features used to determine VLAN offload settings ··· 6101 6083 6102 6084 if (strip_err || insert_err) 6103 6085 return -EIO; 6086 + 6087 + ice_set_rx_rings_vlan_proto(vsi, enable_stripping ? 6088 + htons(vlan_ethertype) : 0); 6104 6089 6105 6090 return 0; 6106 6091 }
+8 -14
drivers/net/ethernet/intel/ice/ice_ptp.c
··· 2127 2127 } 2128 2128 2129 2129 /** 2130 - * ice_ptp_rx_hwtstamp - Check for an Rx timestamp 2131 - * @rx_ring: Ring to get the VSI info 2130 + * ice_ptp_get_rx_hwts - Get packet Rx timestamp in ns 2132 2131 * @rx_desc: Receive descriptor 2133 - * @skb: Particular skb to send timestamp with 2132 + * @pkt_ctx: Packet context to get the cached time 2134 2133 * 2135 2134 * The driver receives a notification in the receive descriptor with timestamp. 2136 - * The timestamp is in ns, so we must convert the result first. 2137 2135 */ 2138 - void 2139 - ice_ptp_rx_hwtstamp(struct ice_rx_ring *rx_ring, 2140 - union ice_32b_rx_flex_desc *rx_desc, struct sk_buff *skb) 2136 + u64 ice_ptp_get_rx_hwts(const union ice_32b_rx_flex_desc *rx_desc, 2137 + const struct ice_pkt_ctx *pkt_ctx) 2141 2138 { 2142 - struct skb_shared_hwtstamps *hwtstamps; 2143 2139 u64 ts_ns, cached_time; 2144 2140 u32 ts_high; 2145 2141 2146 2142 if (!(rx_desc->wb.time_stamp_low & ICE_PTP_TS_VALID)) 2147 - return; 2143 + return 0; 2148 2144 2149 - cached_time = READ_ONCE(rx_ring->cached_phctime); 2145 + cached_time = READ_ONCE(pkt_ctx->cached_phctime); 2150 2146 2151 2147 /* Do not report a timestamp if we don't have a cached PHC time */ 2152 2148 if (!cached_time) 2153 - return; 2149 + return 0; 2154 2150 2155 2151 /* Use ice_ptp_extend_32b_ts directly, using the ring-specific cached 2156 2152 * PHC value, rather than accessing the PF. This also allows us to ··· 2157 2161 ts_high = le32_to_cpu(rx_desc->wb.flex_ts.ts_high); 2158 2162 ts_ns = ice_ptp_extend_32b_ts(cached_time, ts_high); 2159 2163 2160 - hwtstamps = skb_hwtstamps(skb); 2161 - memset(hwtstamps, 0, sizeof(*hwtstamps)); 2162 - hwtstamps->hwtstamp = ns_to_ktime(ts_ns); 2164 + return ts_ns; 2163 2165 } 2164 2166 2165 2167 /**
+10 -6
drivers/net/ethernet/intel/ice/ice_ptp.h
··· 298 298 s8 ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb); 299 299 enum ice_tx_tstamp_work ice_ptp_process_ts(struct ice_pf *pf); 300 300 301 - void 302 - ice_ptp_rx_hwtstamp(struct ice_rx_ring *rx_ring, 303 - union ice_32b_rx_flex_desc *rx_desc, struct sk_buff *skb); 301 + u64 ice_ptp_get_rx_hwts(const union ice_32b_rx_flex_desc *rx_desc, 302 + const struct ice_pkt_ctx *pkt_ctx); 304 303 void ice_ptp_reset(struct ice_pf *pf); 305 304 void ice_ptp_prepare_for_reset(struct ice_pf *pf); 306 305 void ice_ptp_init(struct ice_pf *pf); ··· 328 329 { 329 330 return true; 330 331 } 331 - static inline void 332 - ice_ptp_rx_hwtstamp(struct ice_rx_ring *rx_ring, 333 - union ice_32b_rx_flex_desc *rx_desc, struct sk_buff *skb) { } 332 + 333 + static inline u64 334 + ice_ptp_get_rx_hwts(const union ice_32b_rx_flex_desc *rx_desc, 335 + const struct ice_pkt_ctx *pkt_ctx) 336 + { 337 + return 0; 338 + } 339 + 334 340 static inline void ice_ptp_reset(struct ice_pf *pf) { } 335 341 static inline void ice_ptp_prepare_for_reset(struct ice_pf *pf) { } 336 342 static inline void ice_ptp_init(struct ice_pf *pf) { }
+9 -10
drivers/net/ethernet/intel/ice/ice_txrx.c
··· 557 557 * @xdp_prog: XDP program to run 558 558 * @xdp_ring: ring to be used for XDP_TX action 559 559 * @rx_buf: Rx buffer to store the XDP action 560 + * @eop_desc: Last descriptor in packet to read metadata from 560 561 * 561 562 * Returns any of ICE_XDP_{PASS, CONSUMED, TX, REDIR} 562 563 */ 563 564 static void 564 565 ice_run_xdp(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp, 565 566 struct bpf_prog *xdp_prog, struct ice_tx_ring *xdp_ring, 566 - struct ice_rx_buf *rx_buf) 567 + struct ice_rx_buf *rx_buf, union ice_32b_rx_flex_desc *eop_desc) 567 568 { 568 569 unsigned int ret = ICE_XDP_PASS; 569 570 u32 act; 570 571 571 572 if (!xdp_prog) 572 573 goto exit; 574 + 575 + ice_xdp_meta_set_desc(xdp, eop_desc); 573 576 574 577 act = bpf_prog_run_xdp(xdp_prog, xdp); 575 578 switch (act) { ··· 1183 1180 struct sk_buff *skb; 1184 1181 unsigned int size; 1185 1182 u16 stat_err_bits; 1186 - u16 vlan_tag = 0; 1187 - u16 rx_ptype; 1183 + u16 vlan_tci; 1188 1184 1189 1185 /* get the Rx desc from Rx ring based on 'next_to_clean' */ 1190 1186 rx_desc = ICE_RX_DESC(rx_ring, ntc); ··· 1243 1241 if (ice_is_non_eop(rx_ring, rx_desc)) 1244 1242 continue; 1245 1243 1246 - ice_run_xdp(rx_ring, xdp, xdp_prog, xdp_ring, rx_buf); 1244 + ice_run_xdp(rx_ring, xdp, xdp_prog, xdp_ring, rx_buf, rx_desc); 1247 1245 if (rx_buf->act == ICE_XDP_PASS) 1248 1246 goto construct_skb; 1249 1247 total_rx_bytes += xdp_get_buff_len(xdp); ··· 1278 1276 continue; 1279 1277 } 1280 1278 1281 - vlan_tag = ice_get_vlan_tag_from_rx_desc(rx_desc); 1279 + vlan_tci = ice_get_vlan_tci(rx_desc); 1282 1280 1283 1281 /* pad the skb if needed, to make a valid ethernet frame */ 1284 1282 if (eth_skb_pad(skb)) ··· 1288 1286 total_rx_bytes += skb->len; 1289 1287 1290 1288 /* populate checksum, VLAN, and protocol */ 1291 - rx_ptype = le16_to_cpu(rx_desc->wb.ptype_flex_flags0) & 1292 - ICE_RX_FLEX_DESC_PTYPE_M; 1293 - 1294 - ice_process_skb_fields(rx_ring, rx_desc, skb, rx_ptype); 1289 + ice_process_skb_fields(rx_ring, rx_desc, skb); 1295 1290 1296 1291 ice_trace(clean_rx_irq_indicate, rx_ring, rx_desc, skb); 1297 1292 /* send completed skb up the stack */ 1298 - ice_receive_skb(rx_ring, skb, vlan_tag); 1293 + ice_receive_skb(rx_ring, skb, vlan_tci); 1299 1294 1300 1295 /* update budget accounting */ 1301 1296 total_rx_pkts++;
+28 -4
drivers/net/ethernet/intel/ice/ice_txrx.h
··· 257 257 ICE_RX_DTYPE_SPLIT_ALWAYS = 2, 258 258 }; 259 259 260 + struct ice_pkt_ctx { 261 + u64 cached_phctime; 262 + __be16 vlan_proto; 263 + }; 264 + 265 + struct ice_xdp_buff { 266 + struct xdp_buff xdp_buff; 267 + const union ice_32b_rx_flex_desc *eop_desc; 268 + const struct ice_pkt_ctx *pkt_ctx; 269 + }; 270 + 271 + /* Required for compatibility with xdp_buffs from xsk_pool */ 272 + static_assert(offsetof(struct ice_xdp_buff, xdp_buff) == 0); 273 + 260 274 /* indices into GLINT_ITR registers */ 261 275 #define ICE_RX_ITR ICE_IDX_ITR0 262 276 #define ICE_TX_ITR ICE_IDX_ITR1 ··· 312 298 /* descriptor ring, associated with a VSI */ 313 299 struct ice_rx_ring { 314 300 /* CL1 - 1st cacheline starts here */ 315 - struct ice_rx_ring *next; /* pointer to next ring in q_vector */ 316 301 void *desc; /* Descriptor ring memory */ 317 302 struct device *dev; /* Used for DMA mapping */ 318 303 struct net_device *netdev; /* netdev ring maps to */ ··· 323 310 u16 count; /* Number of descriptors */ 324 311 u16 reg_idx; /* HW register index of the ring */ 325 312 u16 next_to_alloc; 326 - /* CL2 - 2nd cacheline starts here */ 313 + 327 314 union { 328 315 struct ice_rx_buf *rx_buf; 329 316 struct xdp_buff **xdp_buf; 330 317 }; 331 - struct xdp_buff xdp; 318 + /* CL2 - 2nd cacheline starts here */ 319 + union { 320 + struct ice_xdp_buff xdp_ext; 321 + struct xdp_buff xdp; 322 + }; 332 323 /* CL3 - 3rd cacheline starts here */ 324 + union { 325 + struct ice_pkt_ctx pkt_ctx; 326 + struct { 327 + u64 cached_phctime; 328 + __be16 vlan_proto; 329 + }; 330 + }; 333 331 struct bpf_prog *xdp_prog; 334 332 u16 rx_offset; 335 333 ··· 356 332 /* CL4 - 4th cacheline starts here */ 357 333 struct ice_channel *ch; 358 334 struct ice_tx_ring *xdp_ring; 335 + struct ice_rx_ring *next; /* pointer to next ring in q_vector */ 359 336 struct xsk_buff_pool *xsk_pool; 360 337 dma_addr_t dma; /* physical address of ring */ 361 - u64 cached_phctime; 362 338 u16 rx_buf_len; 363 339 u8 dcb_tc; /* Traffic class of ring */ 364 340 u8 ptp_rx;
+184 -23
drivers/net/ethernet/intel/ice/ice_txrx_lib.c
··· 63 63 } 64 64 65 65 /** 66 - * ice_rx_hash - set the hash value in the skb 66 + * ice_get_rx_hash - get RX hash value from descriptor 67 + * @rx_desc: specific descriptor 68 + * 69 + * Returns hash, if present, 0 otherwise. 70 + */ 71 + static u32 ice_get_rx_hash(const union ice_32b_rx_flex_desc *rx_desc) 72 + { 73 + const struct ice_32b_rx_flex_desc_nic *nic_mdid; 74 + 75 + if (unlikely(rx_desc->wb.rxdid != ICE_RXDID_FLEX_NIC)) 76 + return 0; 77 + 78 + nic_mdid = (struct ice_32b_rx_flex_desc_nic *)rx_desc; 79 + return le32_to_cpu(nic_mdid->rss_hash); 80 + } 81 + 82 + /** 83 + * ice_rx_hash_to_skb - set the hash value in the skb 67 84 * @rx_ring: descriptor ring 68 85 * @rx_desc: specific descriptor 69 86 * @skb: pointer to current skb 70 87 * @rx_ptype: the ptype value from the descriptor 71 88 */ 72 89 static void 73 - ice_rx_hash(struct ice_rx_ring *rx_ring, union ice_32b_rx_flex_desc *rx_desc, 74 - struct sk_buff *skb, u16 rx_ptype) 90 + ice_rx_hash_to_skb(const struct ice_rx_ring *rx_ring, 91 + const union ice_32b_rx_flex_desc *rx_desc, 92 + struct sk_buff *skb, u16 rx_ptype) 75 93 { 76 - struct ice_32b_rx_flex_desc_nic *nic_mdid; 77 94 u32 hash; 78 95 79 96 if (!(rx_ring->netdev->features & NETIF_F_RXHASH)) 80 97 return; 81 98 82 - if (rx_desc->wb.rxdid != ICE_RXDID_FLEX_NIC) 83 - return; 84 - 85 - nic_mdid = (struct ice_32b_rx_flex_desc_nic *)rx_desc; 86 - hash = le32_to_cpu(nic_mdid->rss_hash); 87 - skb_set_hash(skb, hash, ice_ptype_to_htype(rx_ptype)); 99 + hash = ice_get_rx_hash(rx_desc); 100 + if (likely(hash)) 101 + skb_set_hash(skb, hash, ice_ptype_to_htype(rx_ptype)); 88 102 } 89 103 90 104 /** ··· 185 171 } 186 172 187 173 /** 174 + * ice_ptp_rx_hwts_to_skb - Put RX timestamp into skb 175 + * @rx_ring: Ring to get the VSI info 176 + * @rx_desc: Receive descriptor 177 + * @skb: Particular skb to send timestamp with 178 + * 179 + * The timestamp is in ns, so we must convert the result first. 180 + */ 181 + static void 182 + ice_ptp_rx_hwts_to_skb(struct ice_rx_ring *rx_ring, 183 + const union ice_32b_rx_flex_desc *rx_desc, 184 + struct sk_buff *skb) 185 + { 186 + u64 ts_ns = ice_ptp_get_rx_hwts(rx_desc, &rx_ring->pkt_ctx); 187 + 188 + skb_hwtstamps(skb)->hwtstamp = ns_to_ktime(ts_ns); 189 + } 190 + 191 + /** 192 + * ice_get_ptype - Read HW packet type from the descriptor 193 + * @rx_desc: RX descriptor 194 + */ 195 + static u16 ice_get_ptype(const union ice_32b_rx_flex_desc *rx_desc) 196 + { 197 + return le16_to_cpu(rx_desc->wb.ptype_flex_flags0) & 198 + ICE_RX_FLEX_DESC_PTYPE_M; 199 + } 200 + 201 + /** 188 202 * ice_process_skb_fields - Populate skb header fields from Rx descriptor 189 203 * @rx_ring: Rx descriptor ring packet is being transacted on 190 204 * @rx_desc: pointer to the EOP Rx descriptor 191 205 * @skb: pointer to current skb being populated 192 - * @ptype: the packet type decoded by hardware 193 206 * 194 207 * This function checks the ring, descriptor, and packet information in 195 208 * order to populate the hash, checksum, VLAN, protocol, and ··· 225 184 void 226 185 ice_process_skb_fields(struct ice_rx_ring *rx_ring, 227 186 union ice_32b_rx_flex_desc *rx_desc, 228 - struct sk_buff *skb, u16 ptype) 187 + struct sk_buff *skb) 229 188 { 230 - ice_rx_hash(rx_ring, rx_desc, skb, ptype); 189 + u16 ptype = ice_get_ptype(rx_desc); 190 + 191 + ice_rx_hash_to_skb(rx_ring, rx_desc, skb, ptype); 231 192 232 193 /* modifies the skb - consumes the enet header */ 233 194 skb->protocol = eth_type_trans(skb, rx_ring->netdev); ··· 237 194 ice_rx_csum(rx_ring, skb, rx_desc, ptype); 238 195 239 196 if (rx_ring->ptp_rx) 240 - ice_ptp_rx_hwtstamp(rx_ring, rx_desc, skb); 197 + ice_ptp_rx_hwts_to_skb(rx_ring, rx_desc, skb); 241 198 } 242 199 243 200 /** 244 201 * ice_receive_skb - Send a completed packet up the stack 245 202 * @rx_ring: Rx ring in play 246 203 * @skb: packet to send up 247 - * @vlan_tag: VLAN tag for packet 204 + * @vlan_tci: VLAN TCI for packet 248 205 * 249 206 * This function sends the completed packet (via. skb) up the stack using 250 207 * gro receive functions (with/without VLAN tag) 251 208 */ 252 209 void 253 - ice_receive_skb(struct ice_rx_ring *rx_ring, struct sk_buff *skb, u16 vlan_tag) 210 + ice_receive_skb(struct ice_rx_ring *rx_ring, struct sk_buff *skb, u16 vlan_tci) 254 211 { 255 - netdev_features_t features = rx_ring->netdev->features; 256 - bool non_zero_vlan = !!(vlan_tag & VLAN_VID_MASK); 257 - 258 - if ((features & NETIF_F_HW_VLAN_CTAG_RX) && non_zero_vlan) 259 - __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan_tag); 260 - else if ((features & NETIF_F_HW_VLAN_STAG_RX) && non_zero_vlan) 261 - __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021AD), vlan_tag); 212 + if ((vlan_tci & VLAN_VID_MASK) && rx_ring->vlan_proto) 213 + __vlan_hwaccel_put_tag(skb, rx_ring->vlan_proto, 214 + vlan_tci); 262 215 263 216 napi_gro_receive(&rx_ring->q_vector->napi, skb); 264 217 } ··· 503 464 spin_unlock(&xdp_ring->tx_lock); 504 465 } 505 466 } 467 + 468 + /** 469 + * ice_xdp_rx_hw_ts - HW timestamp XDP hint handler 470 + * @ctx: XDP buff pointer 471 + * @ts_ns: destination address 472 + * 473 + * Copy HW timestamp (if available) to the destination address. 474 + */ 475 + static int ice_xdp_rx_hw_ts(const struct xdp_md *ctx, u64 *ts_ns) 476 + { 477 + const struct ice_xdp_buff *xdp_ext = (void *)ctx; 478 + 479 + *ts_ns = ice_ptp_get_rx_hwts(xdp_ext->eop_desc, 480 + xdp_ext->pkt_ctx); 481 + if (!*ts_ns) 482 + return -ENODATA; 483 + 484 + return 0; 485 + } 486 + 487 + /* Define a ptype index -> XDP hash type lookup table. 488 + * It uses the same ptype definitions as ice_decode_rx_desc_ptype[], 489 + * avoiding possible copy-paste errors. 490 + */ 491 + #undef ICE_PTT 492 + #undef ICE_PTT_UNUSED_ENTRY 493 + 494 + #define ICE_PTT(PTYPE, OUTER_IP, OUTER_IP_VER, OUTER_FRAG, T, TE, TEF, I, PL)\ 495 + [PTYPE] = XDP_RSS_L3_##OUTER_IP_VER | XDP_RSS_L4_##I | XDP_RSS_TYPE_##PL 496 + 497 + #define ICE_PTT_UNUSED_ENTRY(PTYPE) [PTYPE] = 0 498 + 499 + /* A few supplementary definitions for when XDP hash types do not coincide 500 + * with what can be generated from ptype definitions 501 + * by means of preprocessor concatenation. 502 + */ 503 + #define XDP_RSS_L3_NONE XDP_RSS_TYPE_NONE 504 + #define XDP_RSS_L4_NONE XDP_RSS_TYPE_NONE 505 + #define XDP_RSS_TYPE_PAY2 XDP_RSS_TYPE_L2 506 + #define XDP_RSS_TYPE_PAY3 XDP_RSS_TYPE_NONE 507 + #define XDP_RSS_TYPE_PAY4 XDP_RSS_L4 508 + 509 + static const enum xdp_rss_hash_type 510 + ice_ptype_to_xdp_hash[ICE_NUM_DEFINED_PTYPES] = { 511 + ICE_PTYPES 512 + }; 513 + 514 + #undef XDP_RSS_L3_NONE 515 + #undef XDP_RSS_L4_NONE 516 + #undef XDP_RSS_TYPE_PAY2 517 + #undef XDP_RSS_TYPE_PAY3 518 + #undef XDP_RSS_TYPE_PAY4 519 + 520 + #undef ICE_PTT 521 + #undef ICE_PTT_UNUSED_ENTRY 522 + 523 + /** 524 + * ice_xdp_rx_hash_type - Get XDP-specific hash type from the RX descriptor 525 + * @eop_desc: End of Packet descriptor 526 + */ 527 + static enum xdp_rss_hash_type 528 + ice_xdp_rx_hash_type(const union ice_32b_rx_flex_desc *eop_desc) 529 + { 530 + u16 ptype = ice_get_ptype(eop_desc); 531 + 532 + if (unlikely(ptype >= ICE_NUM_DEFINED_PTYPES)) 533 + return 0; 534 + 535 + return ice_ptype_to_xdp_hash[ptype]; 536 + } 537 + 538 + /** 539 + * ice_xdp_rx_hash - RX hash XDP hint handler 540 + * @ctx: XDP buff pointer 541 + * @hash: hash destination address 542 + * @rss_type: XDP hash type destination address 543 + * 544 + * Copy RX hash (if available) and its type to the destination address. 545 + */ 546 + static int ice_xdp_rx_hash(const struct xdp_md *ctx, u32 *hash, 547 + enum xdp_rss_hash_type *rss_type) 548 + { 549 + const struct ice_xdp_buff *xdp_ext = (void *)ctx; 550 + 551 + *hash = ice_get_rx_hash(xdp_ext->eop_desc); 552 + *rss_type = ice_xdp_rx_hash_type(xdp_ext->eop_desc); 553 + if (!likely(*hash)) 554 + return -ENODATA; 555 + 556 + return 0; 557 + } 558 + 559 + /** 560 + * ice_xdp_rx_vlan_tag - VLAN tag XDP hint handler 561 + * @ctx: XDP buff pointer 562 + * @vlan_proto: destination address for VLAN protocol 563 + * @vlan_tci: destination address for VLAN TCI 564 + * 565 + * Copy VLAN tag (if was stripped) and corresponding protocol 566 + * to the destination address. 567 + */ 568 + static int ice_xdp_rx_vlan_tag(const struct xdp_md *ctx, __be16 *vlan_proto, 569 + u16 *vlan_tci) 570 + { 571 + const struct ice_xdp_buff *xdp_ext = (void *)ctx; 572 + 573 + *vlan_proto = xdp_ext->pkt_ctx->vlan_proto; 574 + if (!*vlan_proto) 575 + return -ENODATA; 576 + 577 + *vlan_tci = ice_get_vlan_tci(xdp_ext->eop_desc); 578 + if (!*vlan_tci) 579 + return -ENODATA; 580 + 581 + return 0; 582 + } 583 + 584 + const struct xdp_metadata_ops ice_xdp_md_ops = { 585 + .xmo_rx_timestamp = ice_xdp_rx_hw_ts, 586 + .xmo_rx_hash = ice_xdp_rx_hash, 587 + .xmo_rx_vlan_tag = ice_xdp_rx_vlan_tag, 588 + };
+14 -4
drivers/net/ethernet/intel/ice/ice_txrx_lib.h
··· 84 84 } 85 85 86 86 /** 87 - * ice_get_vlan_tag_from_rx_desc - get VLAN from Rx flex descriptor 87 + * ice_get_vlan_tci - get VLAN TCI from Rx flex descriptor 88 88 * @rx_desc: Rx 32b flex descriptor with RXDID=2 89 89 * 90 90 * The OS and current PF implementation only support stripping a single VLAN tag ··· 92 92 * one is found return the tag, else return 0 to mean no VLAN tag was found. 93 93 */ 94 94 static inline u16 95 - ice_get_vlan_tag_from_rx_desc(union ice_32b_rx_flex_desc *rx_desc) 95 + ice_get_vlan_tci(const union ice_32b_rx_flex_desc *rx_desc) 96 96 { 97 97 u16 stat_err_bits; 98 98 ··· 148 148 void 149 149 ice_process_skb_fields(struct ice_rx_ring *rx_ring, 150 150 union ice_32b_rx_flex_desc *rx_desc, 151 - struct sk_buff *skb, u16 ptype); 151 + struct sk_buff *skb); 152 152 void 153 - ice_receive_skb(struct ice_rx_ring *rx_ring, struct sk_buff *skb, u16 vlan_tag); 153 + ice_receive_skb(struct ice_rx_ring *rx_ring, struct sk_buff *skb, u16 vlan_tci); 154 + 155 + static inline void 156 + ice_xdp_meta_set_desc(struct xdp_buff *xdp, 157 + union ice_32b_rx_flex_desc *eop_desc) 158 + { 159 + struct ice_xdp_buff *xdp_ext = container_of(xdp, struct ice_xdp_buff, 160 + xdp_buff); 161 + 162 + xdp_ext->eop_desc = eop_desc; 163 + } 154 164 #endif /* !_ICE_TXRX_LIB_H_ */
+9 -8
drivers/net/ethernet/intel/ice/ice_xsk.c
··· 458 458 rx_desc->read.pkt_addr = cpu_to_le64(dma); 459 459 rx_desc->wb.status_error0 = 0; 460 460 461 + /* Put private info that changes on a per-packet basis 462 + * into xdp_buff_xsk->cb. 463 + */ 464 + ice_xdp_meta_set_desc(*xdp, rx_desc); 465 + 461 466 rx_desc++; 462 467 xdp++; 463 468 } ··· 868 863 struct xdp_buff *xdp; 869 864 struct sk_buff *skb; 870 865 u16 stat_err_bits; 871 - u16 vlan_tag = 0; 872 - u16 rx_ptype; 866 + u16 vlan_tci; 873 867 874 868 rx_desc = ICE_RX_DESC(rx_ring, ntc); 875 869 ··· 946 942 total_rx_bytes += skb->len; 947 943 total_rx_packets++; 948 944 949 - vlan_tag = ice_get_vlan_tag_from_rx_desc(rx_desc); 945 + vlan_tci = ice_get_vlan_tci(rx_desc); 950 946 951 - rx_ptype = le16_to_cpu(rx_desc->wb.ptype_flex_flags0) & 952 - ICE_RX_FLEX_DESC_PTYPE_M; 953 - 954 - ice_process_skb_fields(rx_ring, rx_desc, skb, rx_ptype); 955 - ice_receive_skb(rx_ring, skb, vlan_tag); 947 + ice_process_skb_fields(rx_ring, rx_desc, skb); 948 + ice_receive_skb(rx_ring, skb, vlan_tci); 956 949 } 957 950 958 951 rx_ring->next_to_clean = ntc;
+15
drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c
··· 256 256 return 0; 257 257 } 258 258 259 + static int mlx5e_xdp_rx_vlan_tag(const struct xdp_md *ctx, __be16 *vlan_proto, 260 + u16 *vlan_tci) 261 + { 262 + const struct mlx5e_xdp_buff *_ctx = (void *)ctx; 263 + const struct mlx5_cqe64 *cqe = _ctx->cqe; 264 + 265 + if (!cqe_has_vlan(cqe)) 266 + return -ENODATA; 267 + 268 + *vlan_proto = htons(ETH_P_8021Q); 269 + *vlan_tci = be16_to_cpu(cqe->vlan_info); 270 + return 0; 271 + } 272 + 259 273 const struct xdp_metadata_ops mlx5e_xdp_metadata_ops = { 260 274 .xmo_rx_timestamp = mlx5e_xdp_rx_timestamp, 261 275 .xmo_rx_hash = mlx5e_xdp_rx_hash, 276 + .xmo_rx_vlan_tag = mlx5e_xdp_rx_vlan_tag, 262 277 }; 263 278 264 279 struct mlx5e_xsk_tx_complete {
+19
drivers/net/veth.c
··· 1722 1722 return 0; 1723 1723 } 1724 1724 1725 + static int veth_xdp_rx_vlan_tag(const struct xdp_md *ctx, __be16 *vlan_proto, 1726 + u16 *vlan_tci) 1727 + { 1728 + const struct veth_xdp_buff *_ctx = (void *)ctx; 1729 + const struct sk_buff *skb = _ctx->skb; 1730 + int err; 1731 + 1732 + if (!skb) 1733 + return -ENODATA; 1734 + 1735 + err = __vlan_hwaccel_get_tag(skb, vlan_tci); 1736 + if (err) 1737 + return err; 1738 + 1739 + *vlan_proto = skb->vlan_proto; 1740 + return err; 1741 + } 1742 + 1725 1743 static const struct net_device_ops veth_netdev_ops = { 1726 1744 .ndo_init = veth_dev_init, 1727 1745 .ndo_open = veth_open, ··· 1764 1746 static const struct xdp_metadata_ops veth_xdp_metadata_ops = { 1765 1747 .xmo_rx_timestamp = veth_xdp_rx_timestamp, 1766 1748 .xmo_rx_hash = veth_xdp_rx_hash, 1749 + .xmo_rx_vlan_tag = veth_xdp_rx_vlan_tag, 1767 1750 }; 1768 1751 1769 1752 #define VETH_FEATURES (NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HW_CSUM | \
+2 -2
include/linux/if_vlan.h
··· 540 540 struct vlan_ethhdr *veth = skb_vlan_eth_hdr(skb); 541 541 542 542 if (!eth_type_vlan(veth->h_vlan_proto)) 543 - return -EINVAL; 543 + return -ENODATA; 544 544 545 545 *vlan_tci = ntohs(veth->h_vlan_TCI); 546 546 return 0; ··· 561 561 return 0; 562 562 } else { 563 563 *vlan_tci = 0; 564 - return -EINVAL; 564 + return -ENODATA; 565 565 } 566 566 } 567 567
+1 -1
include/linux/mlx5/device.h
··· 918 918 return (cqe->tls_outer_l3_tunneled >> 3) & 0x3; 919 919 } 920 920 921 - static inline bool cqe_has_vlan(struct mlx5_cqe64 *cqe) 921 + static inline bool cqe_has_vlan(const struct mlx5_cqe64 *cqe) 922 922 { 923 923 return cqe->l4_l3_hdr_type & 0x1; 924 924 }
+9
include/net/xdp.h
··· 404 404 NETDEV_XDP_RX_METADATA_HASH, \ 405 405 bpf_xdp_metadata_rx_hash, \ 406 406 xmo_rx_hash) \ 407 + XDP_METADATA_KFUNC(XDP_METADATA_KFUNC_RX_VLAN_TAG, \ 408 + NETDEV_XDP_RX_METADATA_VLAN_TAG, \ 409 + bpf_xdp_metadata_rx_vlan_tag, \ 410 + xmo_rx_vlan_tag) \ 407 411 408 412 enum xdp_rx_metadata { 409 413 #define XDP_METADATA_KFUNC(name, _, __, ___) name, ··· 436 432 XDP_RSS_L4_UDP = BIT(5), 437 433 XDP_RSS_L4_SCTP = BIT(6), 438 434 XDP_RSS_L4_IPSEC = BIT(7), /* L4 based hash include IPSEC SPI */ 435 + XDP_RSS_L4_ICMP = BIT(8), 439 436 440 437 /* Second part: RSS hash type combinations used for driver HW mapping */ 441 438 XDP_RSS_TYPE_NONE = 0, ··· 452 447 XDP_RSS_TYPE_L4_IPV4_UDP = XDP_RSS_L3_IPV4 | XDP_RSS_L4 | XDP_RSS_L4_UDP, 453 448 XDP_RSS_TYPE_L4_IPV4_SCTP = XDP_RSS_L3_IPV4 | XDP_RSS_L4 | XDP_RSS_L4_SCTP, 454 449 XDP_RSS_TYPE_L4_IPV4_IPSEC = XDP_RSS_L3_IPV4 | XDP_RSS_L4 | XDP_RSS_L4_IPSEC, 450 + XDP_RSS_TYPE_L4_IPV4_ICMP = XDP_RSS_L3_IPV4 | XDP_RSS_L4 | XDP_RSS_L4_ICMP, 455 451 456 452 XDP_RSS_TYPE_L4_IPV6_TCP = XDP_RSS_L3_IPV6 | XDP_RSS_L4 | XDP_RSS_L4_TCP, 457 453 XDP_RSS_TYPE_L4_IPV6_UDP = XDP_RSS_L3_IPV6 | XDP_RSS_L4 | XDP_RSS_L4_UDP, 458 454 XDP_RSS_TYPE_L4_IPV6_SCTP = XDP_RSS_L3_IPV6 | XDP_RSS_L4 | XDP_RSS_L4_SCTP, 459 455 XDP_RSS_TYPE_L4_IPV6_IPSEC = XDP_RSS_L3_IPV6 | XDP_RSS_L4 | XDP_RSS_L4_IPSEC, 456 + XDP_RSS_TYPE_L4_IPV6_ICMP = XDP_RSS_L3_IPV6 | XDP_RSS_L4 | XDP_RSS_L4_ICMP, 460 457 461 458 XDP_RSS_TYPE_L4_IPV6_TCP_EX = XDP_RSS_TYPE_L4_IPV6_TCP | XDP_RSS_L3_DYNHDR, 462 459 XDP_RSS_TYPE_L4_IPV6_UDP_EX = XDP_RSS_TYPE_L4_IPV6_UDP | XDP_RSS_L3_DYNHDR, ··· 469 462 int (*xmo_rx_timestamp)(const struct xdp_md *ctx, u64 *timestamp); 470 463 int (*xmo_rx_hash)(const struct xdp_md *ctx, u32 *hash, 471 464 enum xdp_rss_hash_type *rss_type); 465 + int (*xmo_rx_vlan_tag)(const struct xdp_md *ctx, __be16 *vlan_proto, 466 + u16 *vlan_tci); 472 467 }; 473 468 474 469 #ifdef CONFIG_NET
+17
include/net/xdp_sock_drv.h
··· 14 14 15 15 #ifdef CONFIG_XDP_SOCKETS 16 16 17 + struct xsk_cb_desc { 18 + void *src; 19 + u8 off; 20 + u8 bytes; 21 + }; 22 + 17 23 void xsk_tx_completed(struct xsk_buff_pool *pool, u32 nb_entries); 18 24 bool xsk_tx_peek_desc(struct xsk_buff_pool *pool, struct xdp_desc *desc); 19 25 u32 xsk_tx_peek_release_desc_batch(struct xsk_buff_pool *pool, u32 max); ··· 51 45 struct xdp_rxq_info *rxq) 52 46 { 53 47 xp_set_rxq_info(pool, rxq); 48 + } 49 + 50 + static inline void xsk_pool_fill_cb(struct xsk_buff_pool *pool, 51 + struct xsk_cb_desc *desc) 52 + { 53 + xp_fill_cb(pool, desc); 54 54 } 55 55 56 56 static inline unsigned int xsk_pool_get_napi_id(struct xsk_buff_pool *pool) ··· 283 271 284 272 static inline void xsk_pool_set_rxq_info(struct xsk_buff_pool *pool, 285 273 struct xdp_rxq_info *rxq) 274 + { 275 + } 276 + 277 + static inline void xsk_pool_fill_cb(struct xsk_buff_pool *pool, 278 + struct xsk_cb_desc *desc) 286 279 { 287 280 } 288 281
+2
include/net/xsk_buff_pool.h
··· 12 12 13 13 struct xsk_buff_pool; 14 14 struct xdp_rxq_info; 15 + struct xsk_cb_desc; 15 16 struct xsk_queue; 16 17 struct xdp_desc; 17 18 struct xdp_umem; ··· 136 135 137 136 /* AF_XDP ZC drivers, via xdp_sock_buff.h */ 138 137 void xp_set_rxq_info(struct xsk_buff_pool *pool, struct xdp_rxq_info *rxq); 138 + void xp_fill_cb(struct xsk_buff_pool *pool, struct xsk_cb_desc *desc); 139 139 int xp_dma_map(struct xsk_buff_pool *pool, struct device *dev, 140 140 unsigned long attrs, struct page **pages, u32 nr_pages); 141 141 void xp_dma_unmap(struct xsk_buff_pool *pool, unsigned long attrs);
+3
include/uapi/linux/netdev.h
··· 44 44 * timestamp via bpf_xdp_metadata_rx_timestamp(). 45 45 * @NETDEV_XDP_RX_METADATA_HASH: Device is capable of exposing receive packet 46 46 * hash via bpf_xdp_metadata_rx_hash(). 47 + * @NETDEV_XDP_RX_METADATA_VLAN_TAG: Device is capable of exposing receive 48 + * packet VLAN tag via bpf_xdp_metadata_rx_vlan_tag(). 47 49 */ 48 50 enum netdev_xdp_rx_metadata { 49 51 NETDEV_XDP_RX_METADATA_TIMESTAMP = 1, 50 52 NETDEV_XDP_RX_METADATA_HASH = 2, 53 + NETDEV_XDP_RX_METADATA_VLAN_TAG = 4, 51 54 }; 52 55 53 56 /**
+33
net/core/xdp.c
··· 736 736 return -EOPNOTSUPP; 737 737 } 738 738 739 + /** 740 + * bpf_xdp_metadata_rx_vlan_tag - Get XDP packet outermost VLAN tag 741 + * @ctx: XDP context pointer. 742 + * @vlan_proto: Destination pointer for VLAN Tag protocol identifier (TPID). 743 + * @vlan_tci: Destination pointer for VLAN TCI (VID + DEI + PCP) 744 + * 745 + * In case of success, ``vlan_proto`` contains *Tag protocol identifier (TPID)*, 746 + * usually ``ETH_P_8021Q`` or ``ETH_P_8021AD``, but some networks can use 747 + * custom TPIDs. ``vlan_proto`` is stored in **network byte order (BE)** 748 + * and should be used as follows: 749 + * ``if (vlan_proto == bpf_htons(ETH_P_8021Q)) do_something();`` 750 + * 751 + * ``vlan_tci`` contains the remaining 16 bits of a VLAN tag. 752 + * Driver is expected to provide those in **host byte order (usually LE)**, 753 + * so the bpf program should not perform byte conversion. 754 + * According to 802.1Q standard, *VLAN TCI (Tag control information)* 755 + * is a bit field that contains: 756 + * *VLAN identifier (VID)* that can be read with ``vlan_tci & 0xfff``, 757 + * *Drop eligible indicator (DEI)* - 1 bit, 758 + * *Priority code point (PCP)* - 3 bits. 759 + * For detailed meaning of DEI and PCP, please refer to other sources. 760 + * 761 + * Return: 762 + * * Returns 0 on success or ``-errno`` on error. 763 + * * ``-EOPNOTSUPP`` : device driver doesn't implement kfunc 764 + * * ``-ENODATA`` : VLAN tag was not stripped or is not available 765 + */ 766 + __bpf_kfunc int bpf_xdp_metadata_rx_vlan_tag(const struct xdp_md *ctx, 767 + __be16 *vlan_proto, u16 *vlan_tci) 768 + { 769 + return -EOPNOTSUPP; 770 + } 771 + 739 772 __bpf_kfunc_end_defs(); 740 773 741 774 BTF_SET8_START(xdp_metadata_kfunc_ids)
+12
net/xdp/xsk_buff_pool.c
··· 125 125 } 126 126 EXPORT_SYMBOL(xp_set_rxq_info); 127 127 128 + void xp_fill_cb(struct xsk_buff_pool *pool, struct xsk_cb_desc *desc) 129 + { 130 + u32 i; 131 + 132 + for (i = 0; i < pool->heads_cnt; i++) { 133 + struct xdp_buff_xsk *xskb = &pool->heads[i]; 134 + 135 + memcpy(xskb->cb + desc->off, desc->src, desc->bytes); 136 + } 137 + } 138 + EXPORT_SYMBOL(xp_fill_cb); 139 + 128 140 static void xp_disable_drv_zc(struct xsk_buff_pool *pool) 129 141 { 130 142 struct netdev_bpf bpf;
+3
tools/include/uapi/linux/netdev.h
··· 44 44 * timestamp via bpf_xdp_metadata_rx_timestamp(). 45 45 * @NETDEV_XDP_RX_METADATA_HASH: Device is capable of exposing receive packet 46 46 * hash via bpf_xdp_metadata_rx_hash(). 47 + * @NETDEV_XDP_RX_METADATA_VLAN_TAG: Device is capable of exposing receive 48 + * packet VLAN tag via bpf_xdp_metadata_rx_vlan_tag(). 47 49 */ 48 50 enum netdev_xdp_rx_metadata { 49 51 NETDEV_XDP_RX_METADATA_TIMESTAMP = 1, 50 52 NETDEV_XDP_RX_METADATA_HASH = 2, 53 + NETDEV_XDP_RX_METADATA_VLAN_TAG = 4, 51 54 }; 52 55 53 56 /**
+1
tools/net/ynl/generated/netdev-user.c
··· 53 53 static const char * const netdev_xdp_rx_metadata_strmap[] = { 54 54 [0] = "timestamp", 55 55 [1] = "hash", 56 + [2] = "vlan-tag", 56 57 }; 57 58 58 59 const char *netdev_xdp_rx_metadata_str(enum netdev_xdp_rx_metadata value)
+113 -19
tools/testing/selftests/bpf/prog_tests/xdp_metadata.c
··· 20 20 21 21 #define UDP_PAYLOAD_BYTES 4 22 22 23 - #define AF_XDP_SOURCE_PORT 1234 23 + #define UDP_SOURCE_PORT 1234 24 24 #define AF_XDP_CONSUMER_PORT 8080 25 25 26 26 #define UMEM_NUM 16 ··· 33 33 #define RX_ADDR "10.0.0.2" 34 34 #define PREFIX_LEN "8" 35 35 #define FAMILY AF_INET 36 + #define TX_NETNS_NAME "xdp_metadata_tx" 37 + #define RX_NETNS_NAME "xdp_metadata_rx" 38 + #define TX_MAC "00:00:00:00:00:01" 39 + #define RX_MAC "00:00:00:00:00:02" 40 + 41 + #define VLAN_ID 59 42 + #define VLAN_PROTO "802.1Q" 43 + #define VLAN_PID htons(ETH_P_8021Q) 44 + #define TX_NAME_VLAN TX_NAME "." TO_STR(VLAN_ID) 45 + 46 + #define XDP_RSS_TYPE_L4 BIT(3) 47 + #define VLAN_VID_MASK 0xfff 36 48 37 49 struct xsk { 38 50 void *umem_area; ··· 193 181 ASSERT_EQ(inet_pton(FAMILY, RX_ADDR, &iph->daddr), 1, "inet_pton(RX_ADDR)"); 194 182 ip_csum(iph); 195 183 196 - udph->source = htons(AF_XDP_SOURCE_PORT); 184 + udph->source = htons(UDP_SOURCE_PORT); 197 185 udph->dest = htons(dst_port); 198 186 udph->len = htons(sizeof(*udph) + UDP_PAYLOAD_BYTES); 199 187 udph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, ··· 214 202 return ret; 215 203 216 204 return 0; 205 + } 206 + 207 + static int generate_packet_inet(void) 208 + { 209 + char udp_payload[UDP_PAYLOAD_BYTES]; 210 + struct sockaddr_in rx_addr; 211 + int sock_fd, err = 0; 212 + 213 + /* Build a packet */ 214 + memset(udp_payload, 0xAA, UDP_PAYLOAD_BYTES); 215 + rx_addr.sin_addr.s_addr = inet_addr(RX_ADDR); 216 + rx_addr.sin_family = AF_INET; 217 + rx_addr.sin_port = htons(AF_XDP_CONSUMER_PORT); 218 + 219 + sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 220 + if (!ASSERT_GE(sock_fd, 0, "socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)")) 221 + return sock_fd; 222 + 223 + err = sendto(sock_fd, udp_payload, UDP_PAYLOAD_BYTES, MSG_DONTWAIT, 224 + (void *)&rx_addr, sizeof(rx_addr)); 225 + ASSERT_GE(err, 0, "sendto"); 226 + 227 + close(sock_fd); 228 + return err; 217 229 } 218 230 219 231 static void complete_tx(struct xsk *xsk) ··· 272 236 } 273 237 } 274 238 275 - static int verify_xsk_metadata(struct xsk *xsk) 239 + static int verify_xsk_metadata(struct xsk *xsk, bool sent_from_af_xdp) 276 240 { 277 241 const struct xdp_desc *rx_desc; 278 242 struct pollfd fds = {}; ··· 326 290 if (!ASSERT_NEQ(meta->rx_hash, 0, "rx_hash")) 327 291 return -1; 328 292 293 + if (!sent_from_af_xdp) { 294 + if (!ASSERT_NEQ(meta->rx_hash_type & XDP_RSS_TYPE_L4, 0, "rx_hash_type")) 295 + return -1; 296 + 297 + if (!ASSERT_EQ(meta->rx_vlan_tci & VLAN_VID_MASK, VLAN_ID, "rx_vlan_tci")) 298 + return -1; 299 + 300 + if (!ASSERT_EQ(meta->rx_vlan_proto, VLAN_PID, "rx_vlan_proto")) 301 + return -1; 302 + goto done; 303 + } 304 + 329 305 ASSERT_EQ(meta->rx_hash_type, 0, "rx_hash_type"); 330 306 331 307 /* checksum offload */ 332 308 ASSERT_EQ(udph->check, htons(0x721c), "csum"); 333 309 310 + done: 334 311 xsk_ring_cons__release(&xsk->rx, 1); 335 312 refill_rx(xsk, comp_addr); 336 313 337 314 return 0; 315 + } 316 + 317 + static void switch_ns_to_rx(struct nstoken **tok) 318 + { 319 + close_netns(*tok); 320 + *tok = open_netns(RX_NETNS_NAME); 321 + } 322 + 323 + static void switch_ns_to_tx(struct nstoken **tok) 324 + { 325 + close_netns(*tok); 326 + *tok = open_netns(TX_NETNS_NAME); 338 327 } 339 328 340 329 void test_xdp_metadata(void) ··· 379 318 int sock_fd; 380 319 int ret; 381 320 382 - /* Setup new networking namespace, with a veth pair. */ 321 + /* Setup new networking namespaces, with a veth pair. */ 322 + SYS(out, "ip netns add " TX_NETNS_NAME); 323 + SYS(out, "ip netns add " RX_NETNS_NAME); 383 324 384 - SYS(out, "ip netns add xdp_metadata"); 385 - tok = open_netns("xdp_metadata"); 325 + tok = open_netns(TX_NETNS_NAME); 386 326 SYS(out, "ip link add numtxqueues 1 numrxqueues 1 " TX_NAME 387 327 " type veth peer " RX_NAME " numtxqueues 1 numrxqueues 1"); 388 - SYS(out, "ip link set dev " TX_NAME " address 00:00:00:00:00:01"); 389 - SYS(out, "ip link set dev " RX_NAME " address 00:00:00:00:00:02"); 328 + SYS(out, "ip link set " RX_NAME " netns " RX_NETNS_NAME); 329 + 330 + SYS(out, "ip link set dev " TX_NAME " address " TX_MAC); 390 331 SYS(out, "ip link set dev " TX_NAME " up"); 332 + 333 + SYS(out, "ip link add link " TX_NAME " " TX_NAME_VLAN 334 + " type vlan proto " VLAN_PROTO " id " TO_STR(VLAN_ID)); 335 + SYS(out, "ip link set dev " TX_NAME_VLAN " up"); 336 + SYS(out, "ip addr add " TX_ADDR "/" PREFIX_LEN " dev " TX_NAME_VLAN); 337 + 338 + /* Avoid ARP calls */ 339 + SYS(out, "ip -4 neigh add " RX_ADDR " lladdr " RX_MAC " dev " TX_NAME_VLAN); 340 + 341 + switch_ns_to_rx(&tok); 342 + 343 + SYS(out, "ip link set dev " RX_NAME " address " RX_MAC); 391 344 SYS(out, "ip link set dev " RX_NAME " up"); 392 - SYS(out, "ip addr add " TX_ADDR "/" PREFIX_LEN " dev " TX_NAME); 393 345 SYS(out, "ip addr add " RX_ADDR "/" PREFIX_LEN " dev " RX_NAME); 394 346 395 347 rx_ifindex = if_nametoindex(RX_NAME); 396 - tx_ifindex = if_nametoindex(TX_NAME); 397 348 398 - /* Setup separate AF_XDP for TX and RX interfaces. */ 399 - 400 - ret = open_xsk(tx_ifindex, &tx_xsk); 401 - if (!ASSERT_OK(ret, "open_xsk(TX_NAME)")) 402 - goto out; 349 + /* Setup separate AF_XDP for RX interface. */ 403 350 404 351 ret = open_xsk(rx_ifindex, &rx_xsk); 405 352 if (!ASSERT_OK(ret, "open_xsk(RX_NAME)")) ··· 448 379 if (!ASSERT_GE(ret, 0, "bpf_map_update_elem")) 449 380 goto out; 450 381 451 - /* Send packet destined to RX AF_XDP socket. */ 382 + switch_ns_to_tx(&tok); 383 + 384 + /* Setup separate AF_XDP for TX interface nad send packet to the RX socket. */ 385 + tx_ifindex = if_nametoindex(TX_NAME); 386 + ret = open_xsk(tx_ifindex, &tx_xsk); 387 + if (!ASSERT_OK(ret, "open_xsk(TX_NAME)")) 388 + goto out; 389 + 452 390 if (!ASSERT_GE(generate_packet(&tx_xsk, AF_XDP_CONSUMER_PORT), 0, 453 391 "generate AF_XDP_CONSUMER_PORT")) 454 392 goto out; 455 393 456 - /* Verify AF_XDP RX packet has proper metadata. */ 457 - if (!ASSERT_GE(verify_xsk_metadata(&rx_xsk), 0, 394 + switch_ns_to_rx(&tok); 395 + 396 + /* Verify packet sent from AF_XDP has proper metadata. */ 397 + if (!ASSERT_GE(verify_xsk_metadata(&rx_xsk, true), 0, 458 398 "verify_xsk_metadata")) 459 399 goto out; 460 400 401 + switch_ns_to_tx(&tok); 461 402 complete_tx(&tx_xsk); 403 + 404 + /* Now check metadata of packet, generated with network stack */ 405 + if (!ASSERT_GE(generate_packet_inet(), 0, "generate UDP packet")) 406 + goto out; 407 + 408 + switch_ns_to_rx(&tok); 409 + 410 + if (!ASSERT_GE(verify_xsk_metadata(&rx_xsk, false), 0, 411 + "verify_xsk_metadata")) 412 + goto out; 462 413 463 414 /* Make sure freplace correctly picks up original bound device 464 415 * and doesn't crash. ··· 497 408 if (!ASSERT_OK(xdp_metadata2__attach(bpf_obj2), "attach freplace")) 498 409 goto out; 499 410 411 + switch_ns_to_tx(&tok); 412 + 500 413 /* Send packet to trigger . */ 501 414 if (!ASSERT_GE(generate_packet(&tx_xsk, AF_XDP_CONSUMER_PORT), 0, 502 415 "generate freplace packet")) 503 416 goto out; 417 + 418 + switch_ns_to_rx(&tok); 504 419 505 420 while (!retries--) { 506 421 if (bpf_obj2->bss->called) ··· 520 427 xdp_metadata__destroy(bpf_obj); 521 428 if (tok) 522 429 close_netns(tok); 523 - SYS_NOFAIL("ip netns del xdp_metadata"); 430 + SYS_NOFAIL("ip netns del " RX_NETNS_NAME); 431 + SYS_NOFAIL("ip netns del " TX_NETNS_NAME); 524 432 }
+33 -9
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) 26 29 { 27 30 void *data, *data_meta, *data_end; 28 31 struct ipv6hdr *ip6h = NULL; 29 - struct ethhdr *eth = NULL; 30 32 struct udphdr *udp = NULL; 31 33 struct iphdr *iph = NULL; 32 34 struct xdp_meta *meta; 35 + struct ethhdr *eth; 33 36 int err; 34 37 35 38 data = (void *)(long)ctx->data; 36 39 data_end = (void *)(long)ctx->data_end; 37 40 eth = data; 41 + 42 + if (eth + 1 < data_end && (eth->h_proto == bpf_htons(ETH_P_8021AD) || 43 + eth->h_proto == bpf_htons(ETH_P_8021Q))) 44 + eth = (void *)eth + sizeof(struct vlan_hdr); 45 + 46 + if (eth + 1 < data_end && eth->h_proto == bpf_htons(ETH_P_8021Q)) 47 + eth = (void *)eth + sizeof(struct vlan_hdr); 48 + 38 49 if (eth + 1 < data_end) { 39 50 if (eth->h_proto == bpf_htons(ETH_P_IP)) { 40 51 iph = (void *)(eth + 1); ··· 87 76 return XDP_PASS; 88 77 } 89 78 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 */ 79 + meta->hint_valid = 0; 95 80 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 */ 81 + meta->xdp_timestamp = bpf_ktime_get_tai_ns(); 82 + err = bpf_xdp_metadata_rx_timestamp(ctx, &meta->rx_timestamp); 83 + if (err) 84 + meta->rx_timestamp_err = err; 85 + else 86 + meta->hint_valid |= XDP_META_FIELD_TS; 87 + 88 + err = bpf_xdp_metadata_rx_hash(ctx, &meta->rx_hash, 89 + &meta->rx_hash_type); 90 + if (err) 91 + meta->rx_hash_err = err; 92 + else 93 + meta->hint_valid |= XDP_META_FIELD_RSS; 94 + 95 + err = bpf_xdp_metadata_rx_vlan_tag(ctx, &meta->rx_vlan_proto, 96 + &meta->rx_vlan_tci); 97 + if (err) 98 + meta->rx_vlan_tag_err = err; 99 + else 100 + meta->hint_valid |= XDP_META_FIELD_VLAN_TAG; 99 101 100 102 __sync_add_and_fetch(&pkts_redir, 1); 101 103 return bpf_redirect_map(&xsk, ctx->rx_queue_index, XDP_PASS);
+5
tools/testing/selftests/bpf/progs/xdp_metadata.c
··· 23 23 __u64 *timestamp) __ksym; 24 24 extern int bpf_xdp_metadata_rx_hash(const struct xdp_md *ctx, __u32 *hash, 25 25 enum xdp_rss_hash_type *rss_type) __ksym; 26 + extern int bpf_xdp_metadata_rx_vlan_tag(const struct xdp_md *ctx, 27 + __be16 *vlan_proto, 28 + __u16 *vlan_tci) __ksym; 26 29 27 30 SEC("xdp") 28 31 int rx(struct xdp_md *ctx) ··· 89 86 meta->rx_timestamp = 1; 90 87 91 88 bpf_xdp_metadata_rx_hash(ctx, &meta->rx_hash, &meta->rx_hash_type); 89 + bpf_xdp_metadata_rx_vlan_tag(ctx, &meta->rx_vlan_proto, 90 + &meta->rx_vlan_tci); 92 91 93 92 return bpf_redirect_map(&xsk, ctx->rx_queue_index, XDP_PASS); 94 93 }
+3
tools/testing/selftests/bpf/testing_helpers.h
··· 9 9 #include <bpf/libbpf.h> 10 10 #include <time.h> 11 11 12 + #define __TO_STR(x) #x 13 + #define TO_STR(x) __TO_STR(x) 14 + 12 15 int parse_num_list(const char *s, bool **set, int *set_len); 13 16 __u32 link_info_prog_id(const struct bpf_link *link, struct bpf_link_info *info); 14 17 int bpf_prog_test_load(const char *file, enum bpf_prog_type type,
+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
+33 -1
tools/testing/selftests/bpf/xdp_metadata.h
··· 9 9 #define ETH_P_IPV6 0x86DD 10 10 #endif 11 11 12 + #ifndef ETH_P_8021Q 13 + #define ETH_P_8021Q 0x8100 14 + #endif 15 + 16 + #ifndef ETH_P_8021AD 17 + #define ETH_P_8021AD 0x88A8 18 + #endif 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 + 12 33 struct xdp_meta { 13 - __u64 rx_timestamp; 34 + union { 35 + __u64 rx_timestamp; 36 + __s32 rx_timestamp_err; 37 + }; 14 38 __u64 xdp_timestamp; 15 39 __u32 rx_hash; 16 40 union { 17 41 __u32 rx_hash_type; 18 42 __s32 rx_hash_err; 19 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; 20 52 };