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

Merge branch '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue

Tony Nguyen says:

====================
ice: GTP support in switchdev

Marcin Szycik says:

Add support for adding GTP-C and GTP-U filters in switchdev mode.

To create a filter for GTP, create a GTP-type netdev with ip tool, enable
hardware offload, add qdisc and add a filter in tc:

ip link add $GTP0 type gtp role <sgsn/ggsn> hsize <hsize>
ethtool -K $PF0 hw-tc-offload on
tc qdisc add dev $GTP0 ingress
tc filter add dev $GTP0 ingress prio 1 flower enc_key_id 1337 \
action mirred egress redirect dev $VF1_PR

By default, a filter for GTP-U will be added. To add a filter for GTP-C,
specify enc_dst_port = 2123, e.g.:

tc filter add dev $GTP0 ingress prio 1 flower enc_key_id 1337 \
enc_dst_port 2123 action mirred egress redirect dev $VF1_PR

Note: outer IPv6 offload is not supported yet.
Note: GTP-U with no payload offload is not supported yet.

ICE COMMS package is required to create a filter as it contains GTP
profiles.

Changes in iproute2 [1] are required to be able to add GTP netdev and use
GTP-specific options (QFI and PDU type).

[1] https://lore.kernel.org/netdev/20220211182902.11542-1-wojciech.drewek@intel.com/T
---
v2: Add more CC
v3: Fix mail thread, sorry for spam
v4: Add GTP echo response in gtp module
v5: Change patch order
v6: Add GTP echo request in gtp module
v7: Fix kernel-docs in ice
v8: Remove handling of GTP Echo Response
v9: Add sending of multicast message on GTP Echo Response, fix GTP-C dummy
packet selection
v10: Rebase, fixed most 80 char line limits
v11: Rebase, collect Harald's Reviewed-by on patch 3
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+1478 -119
+1
drivers/net/ethernet/intel/ice/ice.h
··· 51 51 #include <net/gre.h> 52 52 #include <net/udp_tunnel.h> 53 53 #include <net/vxlan.h> 54 + #include <net/gtp.h> 54 55 #if IS_ENABLED(CONFIG_DCB) 55 56 #include <scsi/iscsi_proto.h> 56 57 #endif /* CONFIG_DCB */
+38 -15
drivers/net/ethernet/intel/ice/ice_flex_pipe.c
··· 1804 1804 return bld; 1805 1805 } 1806 1806 1807 + static bool ice_is_gtp_u_profile(u16 prof_idx) 1808 + { 1809 + return (prof_idx >= ICE_PROFID_IPV6_GTPU_TEID && 1810 + prof_idx <= ICE_PROFID_IPV6_GTPU_IPV6_TCP_INNER) || 1811 + prof_idx == ICE_PROFID_IPV4_GTPU_TEID; 1812 + } 1813 + 1814 + static bool ice_is_gtp_c_profile(u16 prof_idx) 1815 + { 1816 + switch (prof_idx) { 1817 + case ICE_PROFID_IPV4_GTPC_TEID: 1818 + case ICE_PROFID_IPV4_GTPC_NO_TEID: 1819 + case ICE_PROFID_IPV6_GTPC_TEID: 1820 + case ICE_PROFID_IPV6_GTPC_NO_TEID: 1821 + return true; 1822 + default: 1823 + return false; 1824 + } 1825 + } 1826 + 1807 1827 /** 1808 1828 * ice_get_sw_prof_type - determine switch profile type 1809 1829 * @hw: pointer to the HW structure 1810 1830 * @fv: pointer to the switch field vector 1831 + * @prof_idx: profile index to check 1811 1832 */ 1812 1833 static enum ice_prof_type 1813 - ice_get_sw_prof_type(struct ice_hw *hw, struct ice_fv *fv) 1834 + ice_get_sw_prof_type(struct ice_hw *hw, struct ice_fv *fv, u32 prof_idx) 1814 1835 { 1815 1836 u16 i; 1837 + 1838 + if (ice_is_gtp_c_profile(prof_idx)) 1839 + return ICE_PROF_TUN_GTPC; 1840 + 1841 + if (ice_is_gtp_u_profile(prof_idx)) 1842 + return ICE_PROF_TUN_GTPU; 1816 1843 1817 1844 for (i = 0; i < hw->blk[ICE_BLK_SW].es.fvw; i++) { 1818 1845 /* UDP tunnel will have UDP_OF protocol ID and VNI offset */ ··· 1887 1860 1888 1861 if (fv) { 1889 1862 /* Determine field vector type */ 1890 - prof_type = ice_get_sw_prof_type(hw, fv); 1863 + prof_type = ice_get_sw_prof_type(hw, fv, offset); 1891 1864 1892 1865 if (req_profs & prof_type) 1893 1866 set_bit((u16)offset, bm); ··· 1898 1871 /** 1899 1872 * ice_get_sw_fv_list 1900 1873 * @hw: pointer to the HW structure 1901 - * @prot_ids: field vector to search for with a given protocol ID 1902 - * @ids_cnt: lookup/protocol count 1874 + * @lkups: list of protocol types 1903 1875 * @bm: bitmap of field vectors to consider 1904 1876 * @fv_list: Head of a list 1905 1877 * 1906 1878 * Finds all the field vector entries from switch block that contain 1907 - * a given protocol ID and returns a list of structures of type 1879 + * a given protocol ID and offset and returns a list of structures of type 1908 1880 * "ice_sw_fv_list_entry". Every structure in the list has a field vector 1909 1881 * definition and profile ID information 1910 1882 * NOTE: The caller of the function is responsible for freeing the memory 1911 1883 * allocated for every list entry. 1912 1884 */ 1913 1885 int 1914 - ice_get_sw_fv_list(struct ice_hw *hw, u8 *prot_ids, u16 ids_cnt, 1886 + ice_get_sw_fv_list(struct ice_hw *hw, struct ice_prot_lkup_ext *lkups, 1915 1887 unsigned long *bm, struct list_head *fv_list) 1916 1888 { 1917 1889 struct ice_sw_fv_list_entry *fvl; ··· 1922 1896 1923 1897 memset(&state, 0, sizeof(state)); 1924 1898 1925 - if (!ids_cnt || !hw->seg) 1899 + if (!lkups->n_val_words || !hw->seg) 1926 1900 return -EINVAL; 1927 1901 1928 1902 ice_seg = hw->seg; ··· 1941 1915 if (!test_bit((u16)offset, bm)) 1942 1916 continue; 1943 1917 1944 - for (i = 0; i < ids_cnt; i++) { 1918 + for (i = 0; i < lkups->n_val_words; i++) { 1945 1919 int j; 1946 1920 1947 - /* This code assumes that if a switch field vector line 1948 - * has a matching protocol, then this line will contain 1949 - * the entries necessary to represent every field in 1950 - * that protocol header. 1951 - */ 1952 1921 for (j = 0; j < hw->blk[ICE_BLK_SW].es.fvw; j++) 1953 - if (fv->ew[j].prot_id == prot_ids[i]) 1922 + if (fv->ew[j].prot_id == 1923 + lkups->fv_words[i].prot_id && 1924 + fv->ew[j].off == lkups->fv_words[i].off) 1954 1925 break; 1955 1926 if (j >= hw->blk[ICE_BLK_SW].es.fvw) 1956 1927 break; 1957 - if (i + 1 == ids_cnt) { 1928 + if (i + 1 == lkups->n_val_words) { 1958 1929 fvl = devm_kzalloc(ice_hw_to_dev(hw), 1959 1930 sizeof(*fvl), GFP_KERNEL); 1960 1931 if (!fvl)
+1 -1
drivers/net/ethernet/intel/ice/ice_flex_pipe.h
··· 87 87 void 88 88 ice_init_prof_result_bm(struct ice_hw *hw); 89 89 int 90 - ice_get_sw_fv_list(struct ice_hw *hw, u8 *prot_ids, u16 ids_cnt, 90 + ice_get_sw_fv_list(struct ice_hw *hw, struct ice_prot_lkup_ext *lkups, 91 91 unsigned long *bm, struct list_head *fv_list); 92 92 int 93 93 ice_pkg_buf_unreserve_section(struct ice_buf_build *bld, u16 count);
+5 -1
drivers/net/ethernet/intel/ice/ice_flex_type.h
··· 417 417 TNL_VXLAN = 0, 418 418 TNL_GENEVE, 419 419 TNL_GRETAP, 420 + TNL_GTPC, 421 + TNL_GTPU, 420 422 __TNL_TYPE_CNT, 421 423 TNL_LAST = 0xFF, 422 424 TNL_ALL = 0xFF, ··· 675 673 ICE_PROF_NON_TUN = 0x1, 676 674 ICE_PROF_TUN_UDP = 0x2, 677 675 ICE_PROF_TUN_GRE = 0x4, 678 - ICE_PROF_TUN_ALL = 0x6, 676 + ICE_PROF_TUN_GTPU = 0x8, 677 + ICE_PROF_TUN_GTPC = 0x10, 678 + ICE_PROF_TUN_ALL = 0x1E, 679 679 ICE_PROF_ALL = 0xFF, 680 680 }; 681 681
+19
drivers/net/ethernet/intel/ice/ice_protocol_type.h
··· 41 41 ICE_VXLAN, 42 42 ICE_GENEVE, 43 43 ICE_NVGRE, 44 + ICE_GTP, 45 + ICE_GTP_NO_PAY, 44 46 ICE_VXLAN_GPE, 45 47 ICE_SCTP_IL, 46 48 ICE_PROTOCOL_LAST ··· 54 52 ICE_SW_TUN_VXLAN, 55 53 ICE_SW_TUN_GENEVE, 56 54 ICE_SW_TUN_NVGRE, 55 + ICE_SW_TUN_GTPU, 56 + ICE_SW_TUN_GTPC, 57 57 ICE_ALL_TUNNELS /* All tunnel types including NVGRE */ 58 58 }; 59 59 ··· 186 182 __be32 vni; /* only use lower 24-bits */ 187 183 }; 188 184 185 + struct ice_udp_gtp_hdr { 186 + u8 flags; 187 + u8 msg_type; 188 + __be16 rsrvd_len; 189 + __be32 teid; 190 + __be16 rsrvd_seq_nbr; 191 + u8 rsrvd_n_pdu_nbr; 192 + u8 rsrvd_next_ext; 193 + u8 rsvrd_ext_len; 194 + u8 pdu_type; 195 + u8 qfi; 196 + u8 rsvrd; 197 + }; 198 + 189 199 struct ice_nvgre_hdr { 190 200 __be16 flags; 191 201 __be16 protocol; ··· 216 198 struct ice_sctp_hdr sctp_hdr; 217 199 struct ice_udp_tnl_hdr tnl_hdr; 218 200 struct ice_nvgre_hdr nvgre_hdr; 201 + struct ice_udp_gtp_hdr gtp_hdr; 219 202 }; 220 203 221 204 /* This is mapping table entry that maps every word within a given protocol
+599 -55
drivers/net/ethernet/intel/ice/ice_switch.c
··· 726 726 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 727 727 }; 728 728 729 + /* Outer IPv4 + Outer UDP + GTP + Inner IPv4 + Inner TCP */ 730 + static const 731 + struct ice_dummy_pkt_offsets dummy_ipv4_gtpu_ipv4_tcp_packet_offsets[] = { 732 + { ICE_MAC_OFOS, 0 }, 733 + { ICE_IPV4_OFOS, 14 }, 734 + { ICE_UDP_OF, 34 }, 735 + { ICE_GTP, 42 }, 736 + { ICE_IPV4_IL, 62 }, 737 + { ICE_TCP_IL, 82 }, 738 + { ICE_PROTOCOL_LAST, 0 }, 739 + }; 740 + 741 + static const u8 dummy_ipv4_gtpu_ipv4_tcp_packet[] = { 742 + 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */ 743 + 0x00, 0x00, 0x00, 0x00, 744 + 0x00, 0x00, 0x00, 0x00, 745 + 0x08, 0x00, 746 + 747 + 0x45, 0x00, 0x00, 0x58, /* IP 14 */ 748 + 0x00, 0x00, 0x00, 0x00, 749 + 0x00, 0x11, 0x00, 0x00, 750 + 0x00, 0x00, 0x00, 0x00, 751 + 0x00, 0x00, 0x00, 0x00, 752 + 753 + 0x00, 0x00, 0x08, 0x68, /* UDP 34 */ 754 + 0x00, 0x44, 0x00, 0x00, 755 + 756 + 0x34, 0xff, 0x00, 0x34, /* ICE_GTP Header 42 */ 757 + 0x00, 0x00, 0x00, 0x00, 758 + 0x00, 0x00, 0x00, 0x85, 759 + 760 + 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */ 761 + 0x00, 0x00, 0x00, 0x00, 762 + 763 + 0x45, 0x00, 0x00, 0x28, /* IP 62 */ 764 + 0x00, 0x00, 0x00, 0x00, 765 + 0x00, 0x06, 0x00, 0x00, 766 + 0x00, 0x00, 0x00, 0x00, 767 + 0x00, 0x00, 0x00, 0x00, 768 + 769 + 0x00, 0x00, 0x00, 0x00, /* TCP 82 */ 770 + 0x00, 0x00, 0x00, 0x00, 771 + 0x00, 0x00, 0x00, 0x00, 772 + 0x50, 0x00, 0x00, 0x00, 773 + 0x00, 0x00, 0x00, 0x00, 774 + 775 + 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 776 + }; 777 + 778 + /* Outer IPv4 + Outer UDP + GTP + Inner IPv4 + Inner UDP */ 779 + static const 780 + struct ice_dummy_pkt_offsets dummy_ipv4_gtpu_ipv4_udp_packet_offsets[] = { 781 + { ICE_MAC_OFOS, 0 }, 782 + { ICE_IPV4_OFOS, 14 }, 783 + { ICE_UDP_OF, 34 }, 784 + { ICE_GTP, 42 }, 785 + { ICE_IPV4_IL, 62 }, 786 + { ICE_UDP_ILOS, 82 }, 787 + { ICE_PROTOCOL_LAST, 0 }, 788 + }; 789 + 790 + static const u8 dummy_ipv4_gtpu_ipv4_udp_packet[] = { 791 + 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */ 792 + 0x00, 0x00, 0x00, 0x00, 793 + 0x00, 0x00, 0x00, 0x00, 794 + 0x08, 0x00, 795 + 796 + 0x45, 0x00, 0x00, 0x4c, /* IP 14 */ 797 + 0x00, 0x00, 0x00, 0x00, 798 + 0x00, 0x11, 0x00, 0x00, 799 + 0x00, 0x00, 0x00, 0x00, 800 + 0x00, 0x00, 0x00, 0x00, 801 + 802 + 0x00, 0x00, 0x08, 0x68, /* UDP 34 */ 803 + 0x00, 0x38, 0x00, 0x00, 804 + 805 + 0x34, 0xff, 0x00, 0x28, /* ICE_GTP Header 42 */ 806 + 0x00, 0x00, 0x00, 0x00, 807 + 0x00, 0x00, 0x00, 0x85, 808 + 809 + 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */ 810 + 0x00, 0x00, 0x00, 0x00, 811 + 812 + 0x45, 0x00, 0x00, 0x1c, /* IP 62 */ 813 + 0x00, 0x00, 0x00, 0x00, 814 + 0x00, 0x11, 0x00, 0x00, 815 + 0x00, 0x00, 0x00, 0x00, 816 + 0x00, 0x00, 0x00, 0x00, 817 + 818 + 0x00, 0x00, 0x00, 0x00, /* UDP 82 */ 819 + 0x00, 0x08, 0x00, 0x00, 820 + 821 + 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 822 + }; 823 + 824 + /* Outer IPv6 + Outer UDP + GTP + Inner IPv4 + Inner TCP */ 825 + static const 826 + struct ice_dummy_pkt_offsets dummy_ipv4_gtpu_ipv6_tcp_packet_offsets[] = { 827 + { ICE_MAC_OFOS, 0 }, 828 + { ICE_IPV4_OFOS, 14 }, 829 + { ICE_UDP_OF, 34 }, 830 + { ICE_GTP, 42 }, 831 + { ICE_IPV6_IL, 62 }, 832 + { ICE_TCP_IL, 102 }, 833 + { ICE_PROTOCOL_LAST, 0 }, 834 + }; 835 + 836 + static const u8 dummy_ipv4_gtpu_ipv6_tcp_packet[] = { 837 + 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */ 838 + 0x00, 0x00, 0x00, 0x00, 839 + 0x00, 0x00, 0x00, 0x00, 840 + 0x08, 0x00, 841 + 842 + 0x45, 0x00, 0x00, 0x6c, /* IP 14 */ 843 + 0x00, 0x00, 0x00, 0x00, 844 + 0x00, 0x11, 0x00, 0x00, 845 + 0x00, 0x00, 0x00, 0x00, 846 + 0x00, 0x00, 0x00, 0x00, 847 + 848 + 0x00, 0x00, 0x08, 0x68, /* UDP 34 */ 849 + 0x00, 0x58, 0x00, 0x00, 850 + 851 + 0x34, 0xff, 0x00, 0x48, /* ICE_GTP Header 42 */ 852 + 0x00, 0x00, 0x00, 0x00, 853 + 0x00, 0x00, 0x00, 0x85, 854 + 855 + 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */ 856 + 0x00, 0x00, 0x00, 0x00, 857 + 858 + 0x60, 0x00, 0x00, 0x00, /* IPv6 62 */ 859 + 0x00, 0x14, 0x06, 0x00, 860 + 0x00, 0x00, 0x00, 0x00, 861 + 0x00, 0x00, 0x00, 0x00, 862 + 0x00, 0x00, 0x00, 0x00, 863 + 0x00, 0x00, 0x00, 0x00, 864 + 0x00, 0x00, 0x00, 0x00, 865 + 0x00, 0x00, 0x00, 0x00, 866 + 0x00, 0x00, 0x00, 0x00, 867 + 0x00, 0x00, 0x00, 0x00, 868 + 869 + 0x00, 0x00, 0x00, 0x00, /* TCP 102 */ 870 + 0x00, 0x00, 0x00, 0x00, 871 + 0x00, 0x00, 0x00, 0x00, 872 + 0x50, 0x00, 0x00, 0x00, 873 + 0x00, 0x00, 0x00, 0x00, 874 + 875 + 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 876 + }; 877 + 878 + static const 879 + struct ice_dummy_pkt_offsets dummy_ipv4_gtpu_ipv6_udp_packet_offsets[] = { 880 + { ICE_MAC_OFOS, 0 }, 881 + { ICE_IPV4_OFOS, 14 }, 882 + { ICE_UDP_OF, 34 }, 883 + { ICE_GTP, 42 }, 884 + { ICE_IPV6_IL, 62 }, 885 + { ICE_UDP_ILOS, 102 }, 886 + { ICE_PROTOCOL_LAST, 0 }, 887 + }; 888 + 889 + static const u8 dummy_ipv4_gtpu_ipv6_udp_packet[] = { 890 + 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */ 891 + 0x00, 0x00, 0x00, 0x00, 892 + 0x00, 0x00, 0x00, 0x00, 893 + 0x08, 0x00, 894 + 895 + 0x45, 0x00, 0x00, 0x60, /* IP 14 */ 896 + 0x00, 0x00, 0x00, 0x00, 897 + 0x00, 0x11, 0x00, 0x00, 898 + 0x00, 0x00, 0x00, 0x00, 899 + 0x00, 0x00, 0x00, 0x00, 900 + 901 + 0x00, 0x00, 0x08, 0x68, /* UDP 34 */ 902 + 0x00, 0x4c, 0x00, 0x00, 903 + 904 + 0x34, 0xff, 0x00, 0x3c, /* ICE_GTP Header 42 */ 905 + 0x00, 0x00, 0x00, 0x00, 906 + 0x00, 0x00, 0x00, 0x85, 907 + 908 + 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */ 909 + 0x00, 0x00, 0x00, 0x00, 910 + 911 + 0x60, 0x00, 0x00, 0x00, /* IPv6 62 */ 912 + 0x00, 0x08, 0x11, 0x00, 913 + 0x00, 0x00, 0x00, 0x00, 914 + 0x00, 0x00, 0x00, 0x00, 915 + 0x00, 0x00, 0x00, 0x00, 916 + 0x00, 0x00, 0x00, 0x00, 917 + 0x00, 0x00, 0x00, 0x00, 918 + 0x00, 0x00, 0x00, 0x00, 919 + 0x00, 0x00, 0x00, 0x00, 920 + 0x00, 0x00, 0x00, 0x00, 921 + 922 + 0x00, 0x00, 0x00, 0x00, /* UDP 102 */ 923 + 0x00, 0x08, 0x00, 0x00, 924 + 925 + 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 926 + }; 927 + 928 + static const 929 + struct ice_dummy_pkt_offsets dummy_ipv6_gtpu_ipv4_tcp_packet_offsets[] = { 930 + { ICE_MAC_OFOS, 0 }, 931 + { ICE_IPV6_OFOS, 14 }, 932 + { ICE_UDP_OF, 54 }, 933 + { ICE_GTP, 62 }, 934 + { ICE_IPV4_IL, 82 }, 935 + { ICE_TCP_IL, 102 }, 936 + { ICE_PROTOCOL_LAST, 0 }, 937 + }; 938 + 939 + static const u8 dummy_ipv6_gtpu_ipv4_tcp_packet[] = { 940 + 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */ 941 + 0x00, 0x00, 0x00, 0x00, 942 + 0x00, 0x00, 0x00, 0x00, 943 + 0x86, 0xdd, 944 + 945 + 0x60, 0x00, 0x00, 0x00, /* IPv6 14 */ 946 + 0x00, 0x44, 0x11, 0x00, 947 + 0x00, 0x00, 0x00, 0x00, 948 + 0x00, 0x00, 0x00, 0x00, 949 + 0x00, 0x00, 0x00, 0x00, 950 + 0x00, 0x00, 0x00, 0x00, 951 + 0x00, 0x00, 0x00, 0x00, 952 + 0x00, 0x00, 0x00, 0x00, 953 + 0x00, 0x00, 0x00, 0x00, 954 + 0x00, 0x00, 0x00, 0x00, 955 + 956 + 0x00, 0x00, 0x08, 0x68, /* UDP 54 */ 957 + 0x00, 0x44, 0x00, 0x00, 958 + 959 + 0x34, 0xff, 0x00, 0x34, /* ICE_GTP Header 62 */ 960 + 0x00, 0x00, 0x00, 0x00, 961 + 0x00, 0x00, 0x00, 0x85, 962 + 963 + 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */ 964 + 0x00, 0x00, 0x00, 0x00, 965 + 966 + 0x45, 0x00, 0x00, 0x28, /* IP 82 */ 967 + 0x00, 0x00, 0x00, 0x00, 968 + 0x00, 0x06, 0x00, 0x00, 969 + 0x00, 0x00, 0x00, 0x00, 970 + 0x00, 0x00, 0x00, 0x00, 971 + 972 + 0x00, 0x00, 0x00, 0x00, /* TCP 102 */ 973 + 0x00, 0x00, 0x00, 0x00, 974 + 0x00, 0x00, 0x00, 0x00, 975 + 0x50, 0x00, 0x00, 0x00, 976 + 0x00, 0x00, 0x00, 0x00, 977 + 978 + 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 979 + }; 980 + 981 + static const 982 + struct ice_dummy_pkt_offsets dummy_ipv6_gtpu_ipv4_udp_packet_offsets[] = { 983 + { ICE_MAC_OFOS, 0 }, 984 + { ICE_IPV6_OFOS, 14 }, 985 + { ICE_UDP_OF, 54 }, 986 + { ICE_GTP, 62 }, 987 + { ICE_IPV4_IL, 82 }, 988 + { ICE_UDP_ILOS, 102 }, 989 + { ICE_PROTOCOL_LAST, 0 }, 990 + }; 991 + 992 + static const u8 dummy_ipv6_gtpu_ipv4_udp_packet[] = { 993 + 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */ 994 + 0x00, 0x00, 0x00, 0x00, 995 + 0x00, 0x00, 0x00, 0x00, 996 + 0x86, 0xdd, 997 + 998 + 0x60, 0x00, 0x00, 0x00, /* IPv6 14 */ 999 + 0x00, 0x38, 0x11, 0x00, 1000 + 0x00, 0x00, 0x00, 0x00, 1001 + 0x00, 0x00, 0x00, 0x00, 1002 + 0x00, 0x00, 0x00, 0x00, 1003 + 0x00, 0x00, 0x00, 0x00, 1004 + 0x00, 0x00, 0x00, 0x00, 1005 + 0x00, 0x00, 0x00, 0x00, 1006 + 0x00, 0x00, 0x00, 0x00, 1007 + 0x00, 0x00, 0x00, 0x00, 1008 + 1009 + 0x00, 0x00, 0x08, 0x68, /* UDP 54 */ 1010 + 0x00, 0x38, 0x00, 0x00, 1011 + 1012 + 0x34, 0xff, 0x00, 0x28, /* ICE_GTP Header 62 */ 1013 + 0x00, 0x00, 0x00, 0x00, 1014 + 0x00, 0x00, 0x00, 0x85, 1015 + 1016 + 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */ 1017 + 0x00, 0x00, 0x00, 0x00, 1018 + 1019 + 0x45, 0x00, 0x00, 0x1c, /* IP 82 */ 1020 + 0x00, 0x00, 0x00, 0x00, 1021 + 0x00, 0x11, 0x00, 0x00, 1022 + 0x00, 0x00, 0x00, 0x00, 1023 + 0x00, 0x00, 0x00, 0x00, 1024 + 1025 + 0x00, 0x00, 0x00, 0x00, /* UDP 102 */ 1026 + 0x00, 0x08, 0x00, 0x00, 1027 + 1028 + 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 1029 + }; 1030 + 1031 + static const 1032 + struct ice_dummy_pkt_offsets dummy_ipv6_gtpu_ipv6_tcp_packet_offsets[] = { 1033 + { ICE_MAC_OFOS, 0 }, 1034 + { ICE_IPV6_OFOS, 14 }, 1035 + { ICE_UDP_OF, 54 }, 1036 + { ICE_GTP, 62 }, 1037 + { ICE_IPV6_IL, 82 }, 1038 + { ICE_TCP_IL, 122 }, 1039 + { ICE_PROTOCOL_LAST, 0 }, 1040 + }; 1041 + 1042 + static const u8 dummy_ipv6_gtpu_ipv6_tcp_packet[] = { 1043 + 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */ 1044 + 0x00, 0x00, 0x00, 0x00, 1045 + 0x00, 0x00, 0x00, 0x00, 1046 + 0x86, 0xdd, 1047 + 1048 + 0x60, 0x00, 0x00, 0x00, /* IPv6 14 */ 1049 + 0x00, 0x58, 0x11, 0x00, 1050 + 0x00, 0x00, 0x00, 0x00, 1051 + 0x00, 0x00, 0x00, 0x00, 1052 + 0x00, 0x00, 0x00, 0x00, 1053 + 0x00, 0x00, 0x00, 0x00, 1054 + 0x00, 0x00, 0x00, 0x00, 1055 + 0x00, 0x00, 0x00, 0x00, 1056 + 0x00, 0x00, 0x00, 0x00, 1057 + 0x00, 0x00, 0x00, 0x00, 1058 + 1059 + 0x00, 0x00, 0x08, 0x68, /* UDP 54 */ 1060 + 0x00, 0x58, 0x00, 0x00, 1061 + 1062 + 0x34, 0xff, 0x00, 0x48, /* ICE_GTP Header 62 */ 1063 + 0x00, 0x00, 0x00, 0x00, 1064 + 0x00, 0x00, 0x00, 0x85, 1065 + 1066 + 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */ 1067 + 0x00, 0x00, 0x00, 0x00, 1068 + 1069 + 0x60, 0x00, 0x00, 0x00, /* IPv6 82 */ 1070 + 0x00, 0x14, 0x06, 0x00, 1071 + 0x00, 0x00, 0x00, 0x00, 1072 + 0x00, 0x00, 0x00, 0x00, 1073 + 0x00, 0x00, 0x00, 0x00, 1074 + 0x00, 0x00, 0x00, 0x00, 1075 + 0x00, 0x00, 0x00, 0x00, 1076 + 0x00, 0x00, 0x00, 0x00, 1077 + 0x00, 0x00, 0x00, 0x00, 1078 + 0x00, 0x00, 0x00, 0x00, 1079 + 1080 + 0x00, 0x00, 0x00, 0x00, /* TCP 122 */ 1081 + 0x00, 0x00, 0x00, 0x00, 1082 + 0x00, 0x00, 0x00, 0x00, 1083 + 0x50, 0x00, 0x00, 0x00, 1084 + 0x00, 0x00, 0x00, 0x00, 1085 + 1086 + 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 1087 + }; 1088 + 1089 + static const 1090 + struct ice_dummy_pkt_offsets dummy_ipv6_gtpu_ipv6_udp_packet_offsets[] = { 1091 + { ICE_MAC_OFOS, 0 }, 1092 + { ICE_IPV6_OFOS, 14 }, 1093 + { ICE_UDP_OF, 54 }, 1094 + { ICE_GTP, 62 }, 1095 + { ICE_IPV6_IL, 82 }, 1096 + { ICE_UDP_ILOS, 122 }, 1097 + { ICE_PROTOCOL_LAST, 0 }, 1098 + }; 1099 + 1100 + static const u8 dummy_ipv6_gtpu_ipv6_udp_packet[] = { 1101 + 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */ 1102 + 0x00, 0x00, 0x00, 0x00, 1103 + 0x00, 0x00, 0x00, 0x00, 1104 + 0x86, 0xdd, 1105 + 1106 + 0x60, 0x00, 0x00, 0x00, /* IPv6 14 */ 1107 + 0x00, 0x4c, 0x11, 0x00, 1108 + 0x00, 0x00, 0x00, 0x00, 1109 + 0x00, 0x00, 0x00, 0x00, 1110 + 0x00, 0x00, 0x00, 0x00, 1111 + 0x00, 0x00, 0x00, 0x00, 1112 + 0x00, 0x00, 0x00, 0x00, 1113 + 0x00, 0x00, 0x00, 0x00, 1114 + 0x00, 0x00, 0x00, 0x00, 1115 + 0x00, 0x00, 0x00, 0x00, 1116 + 1117 + 0x00, 0x00, 0x08, 0x68, /* UDP 54 */ 1118 + 0x00, 0x4c, 0x00, 0x00, 1119 + 1120 + 0x34, 0xff, 0x00, 0x3c, /* ICE_GTP Header 62 */ 1121 + 0x00, 0x00, 0x00, 0x00, 1122 + 0x00, 0x00, 0x00, 0x85, 1123 + 1124 + 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */ 1125 + 0x00, 0x00, 0x00, 0x00, 1126 + 1127 + 0x60, 0x00, 0x00, 0x00, /* IPv6 82 */ 1128 + 0x00, 0x08, 0x11, 0x00, 1129 + 0x00, 0x00, 0x00, 0x00, 1130 + 0x00, 0x00, 0x00, 0x00, 1131 + 0x00, 0x00, 0x00, 0x00, 1132 + 0x00, 0x00, 0x00, 0x00, 1133 + 0x00, 0x00, 0x00, 0x00, 1134 + 0x00, 0x00, 0x00, 0x00, 1135 + 0x00, 0x00, 0x00, 0x00, 1136 + 0x00, 0x00, 0x00, 0x00, 1137 + 1138 + 0x00, 0x00, 0x00, 0x00, /* UDP 122 */ 1139 + 0x00, 0x08, 0x00, 0x00, 1140 + 1141 + 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 1142 + }; 1143 + 1144 + static const u8 dummy_ipv4_gtpu_ipv4_packet[] = { 1145 + 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 1146 + 0x00, 0x00, 0x00, 0x00, 1147 + 0x00, 0x00, 0x00, 0x00, 1148 + 0x08, 0x00, 1149 + 1150 + 0x45, 0x00, 0x00, 0x44, /* ICE_IPV4_OFOS 14 */ 1151 + 0x00, 0x00, 0x40, 0x00, 1152 + 0x40, 0x11, 0x00, 0x00, 1153 + 0x00, 0x00, 0x00, 0x00, 1154 + 0x00, 0x00, 0x00, 0x00, 1155 + 1156 + 0x08, 0x68, 0x08, 0x68, /* ICE_UDP_OF 34 */ 1157 + 0x00, 0x00, 0x00, 0x00, 1158 + 1159 + 0x34, 0xff, 0x00, 0x28, /* ICE_GTP 42 */ 1160 + 0x00, 0x00, 0x00, 0x00, 1161 + 0x00, 0x00, 0x00, 0x85, 1162 + 1163 + 0x02, 0x00, 0x00, 0x00, /* PDU Session extension header */ 1164 + 0x00, 0x00, 0x00, 0x00, 1165 + 1166 + 0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_IL 62 */ 1167 + 0x00, 0x00, 0x40, 0x00, 1168 + 0x40, 0x00, 0x00, 0x00, 1169 + 0x00, 0x00, 0x00, 0x00, 1170 + 0x00, 0x00, 0x00, 0x00, 1171 + 0x00, 0x00, 1172 + }; 1173 + 1174 + static const 1175 + struct ice_dummy_pkt_offsets dummy_ipv4_gtp_no_pay_packet_offsets[] = { 1176 + { ICE_MAC_OFOS, 0 }, 1177 + { ICE_IPV4_OFOS, 14 }, 1178 + { ICE_UDP_OF, 34 }, 1179 + { ICE_GTP_NO_PAY, 42 }, 1180 + { ICE_PROTOCOL_LAST, 0 }, 1181 + }; 1182 + 1183 + static const 1184 + struct ice_dummy_pkt_offsets dummy_ipv6_gtp_no_pay_packet_offsets[] = { 1185 + { ICE_MAC_OFOS, 0 }, 1186 + { ICE_IPV6_OFOS, 14 }, 1187 + { ICE_UDP_OF, 54 }, 1188 + { ICE_GTP_NO_PAY, 62 }, 1189 + { ICE_PROTOCOL_LAST, 0 }, 1190 + }; 1191 + 1192 + static const u8 dummy_ipv6_gtp_packet[] = { 1193 + 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 1194 + 0x00, 0x00, 0x00, 0x00, 1195 + 0x00, 0x00, 0x00, 0x00, 1196 + 0x86, 0xdd, 1197 + 1198 + 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 14 */ 1199 + 0x00, 0x6c, 0x11, 0x00, /* Next header UDP*/ 1200 + 0x00, 0x00, 0x00, 0x00, 1201 + 0x00, 0x00, 0x00, 0x00, 1202 + 0x00, 0x00, 0x00, 0x00, 1203 + 0x00, 0x00, 0x00, 0x00, 1204 + 0x00, 0x00, 0x00, 0x00, 1205 + 0x00, 0x00, 0x00, 0x00, 1206 + 0x00, 0x00, 0x00, 0x00, 1207 + 0x00, 0x00, 0x00, 0x00, 1208 + 1209 + 0x08, 0x68, 0x08, 0x68, /* ICE_UDP_OF 54 */ 1210 + 0x00, 0x00, 0x00, 0x00, 1211 + 1212 + 0x30, 0x00, 0x00, 0x28, /* ICE_GTP 62 */ 1213 + 0x00, 0x00, 0x00, 0x00, 1214 + 1215 + 0x00, 0x00, 1216 + }; 1217 + 729 1218 #define ICE_SW_RULE_RX_TX_ETH_HDR_SIZE \ 730 1219 (offsetof(struct ice_aqc_sw_rules_elem, pdata.lkup_tx_rx.hdr) + \ 731 1220 (DUMMY_ETH_HDR_LEN * \ ··· 4546 4057 { ICE_UDP_ILOS, { 0, 2 } }, 4547 4058 { ICE_VXLAN, { 8, 10, 12, 14 } }, 4548 4059 { ICE_GENEVE, { 8, 10, 12, 14 } }, 4549 - { ICE_NVGRE, { 0, 2, 4, 6 } }, 4060 + { ICE_NVGRE, { 0, 2, 4, 6 } }, 4061 + { ICE_GTP, { 8, 10, 12, 14, 16, 18, 20, 22 } }, 4062 + { ICE_GTP_NO_PAY, { 8, 10, 12, 14 } }, 4550 4063 }; 4551 4064 4552 4065 static struct ice_protocol_entry ice_prot_id_tbl[ICE_PROTOCOL_LAST] = { ··· 4566 4075 { ICE_UDP_ILOS, ICE_UDP_ILOS_HW }, 4567 4076 { ICE_VXLAN, ICE_UDP_OF_HW }, 4568 4077 { ICE_GENEVE, ICE_UDP_OF_HW }, 4569 - { ICE_NVGRE, ICE_GRE_OF_HW }, 4078 + { ICE_NVGRE, ICE_GRE_OF_HW }, 4079 + { ICE_GTP, ICE_UDP_OF_HW }, 4080 + { ICE_GTP_NO_PAY, ICE_UDP_ILOS_HW }, 4570 4081 }; 4571 4082 4572 4083 /** ··· 5228 4735 } 5229 4736 5230 4737 /** 5231 - * ice_get_fv - get field vectors/extraction sequences for spec. lookup types 5232 - * @hw: pointer to hardware structure 5233 - * @lkups: lookup elements or match criteria for the advanced recipe, one 5234 - * structure per protocol header 5235 - * @lkups_cnt: number of protocols 5236 - * @bm: bitmap of field vectors to consider 5237 - * @fv_list: pointer to a list that holds the returned field vectors 5238 - */ 5239 - static int 5240 - ice_get_fv(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, u16 lkups_cnt, 5241 - unsigned long *bm, struct list_head *fv_list) 5242 - { 5243 - u8 *prot_ids; 5244 - int status; 5245 - u16 i; 5246 - 5247 - prot_ids = kcalloc(lkups_cnt, sizeof(*prot_ids), GFP_KERNEL); 5248 - if (!prot_ids) 5249 - return -ENOMEM; 5250 - 5251 - for (i = 0; i < lkups_cnt; i++) 5252 - if (!ice_prot_type_to_id(lkups[i].type, &prot_ids[i])) { 5253 - status = -EIO; 5254 - goto free_mem; 5255 - } 5256 - 5257 - /* Find field vectors that include all specified protocol types */ 5258 - status = ice_get_sw_fv_list(hw, prot_ids, lkups_cnt, bm, fv_list); 5259 - 5260 - free_mem: 5261 - kfree(prot_ids); 5262 - return status; 5263 - } 5264 - 5265 - /** 5266 4738 * ice_tun_type_match_word - determine if tun type needs a match mask 5267 4739 * @tun_type: tunnel type 5268 4740 * @mask: mask to be used for the tunnel ··· 5238 4780 case ICE_SW_TUN_GENEVE: 5239 4781 case ICE_SW_TUN_VXLAN: 5240 4782 case ICE_SW_TUN_NVGRE: 4783 + case ICE_SW_TUN_GTPU: 4784 + case ICE_SW_TUN_GTPC: 5241 4785 *mask = ICE_TUN_FLAG_MASK; 5242 4786 return true; 5243 4787 ··· 5304 4844 break; 5305 4845 case ICE_SW_TUN_NVGRE: 5306 4846 prof_type = ICE_PROF_TUN_GRE; 4847 + break; 4848 + case ICE_SW_TUN_GTPU: 4849 + prof_type = ICE_PROF_TUN_GTPU; 4850 + break; 4851 + case ICE_SW_TUN_GTPC: 4852 + prof_type = ICE_PROF_TUN_GTPC; 5307 4853 break; 5308 4854 case ICE_SW_TUN_AND_NON_TUN: 5309 4855 default: ··· 5383 4917 5384 4918 /* Get bitmap of field vectors (profiles) that are compatible with the 5385 4919 * rule request; only these will be searched in the subsequent call to 5386 - * ice_get_fv. 4920 + * ice_get_sw_fv_list. 5387 4921 */ 5388 4922 ice_get_compat_fv_bitmap(hw, rinfo, fv_bitmap); 5389 4923 5390 - status = ice_get_fv(hw, lkups, lkups_cnt, fv_bitmap, &rm->fv_list); 4924 + status = ice_get_sw_fv_list(hw, lkup_exts, fv_bitmap, &rm->fv_list); 5391 4925 if (status) 5392 4926 goto err_unroll; 5393 4927 ··· 5511 5045 const u8 **pkt, u16 *pkt_len, 5512 5046 const struct ice_dummy_pkt_offsets **offsets) 5513 5047 { 5514 - bool tcp = false, udp = false, ipv6 = false, vlan = false; 5515 - bool ipv6_il = false; 5048 + bool inner_tcp = false, inner_udp = false, outer_ipv6 = false; 5049 + bool vlan = false, inner_ipv6 = false, gtp_no_pay = false; 5516 5050 u16 i; 5517 5051 5518 5052 for (i = 0; i < lkups_cnt; i++) { 5519 5053 if (lkups[i].type == ICE_UDP_ILOS) 5520 - udp = true; 5054 + inner_udp = true; 5521 5055 else if (lkups[i].type == ICE_TCP_IL) 5522 - tcp = true; 5056 + inner_tcp = true; 5523 5057 else if (lkups[i].type == ICE_IPV6_OFOS) 5524 - ipv6 = true; 5058 + outer_ipv6 = true; 5525 5059 else if (lkups[i].type == ICE_VLAN_OFOS) 5526 5060 vlan = true; 5527 5061 else if (lkups[i].type == ICE_ETYPE_OL && ··· 5529 5063 cpu_to_be16(ICE_IPV6_ETHER_ID) && 5530 5064 lkups[i].m_u.ethertype.ethtype_id == 5531 5065 cpu_to_be16(0xFFFF)) 5532 - ipv6 = true; 5066 + outer_ipv6 = true; 5533 5067 else if (lkups[i].type == ICE_ETYPE_IL && 5534 5068 lkups[i].h_u.ethertype.ethtype_id == 5535 5069 cpu_to_be16(ICE_IPV6_ETHER_ID) && 5536 5070 lkups[i].m_u.ethertype.ethtype_id == 5537 5071 cpu_to_be16(0xFFFF)) 5538 - ipv6_il = true; 5072 + inner_ipv6 = true; 5073 + else if (lkups[i].type == ICE_IPV6_IL) 5074 + inner_ipv6 = true; 5075 + else if (lkups[i].type == ICE_GTP_NO_PAY) 5076 + gtp_no_pay = true; 5077 + } 5078 + 5079 + if (tun_type == ICE_SW_TUN_GTPU) { 5080 + if (outer_ipv6) { 5081 + if (gtp_no_pay) { 5082 + *pkt = dummy_ipv6_gtp_packet; 5083 + *pkt_len = sizeof(dummy_ipv6_gtp_packet); 5084 + *offsets = dummy_ipv6_gtp_no_pay_packet_offsets; 5085 + } else if (inner_ipv6) { 5086 + if (inner_udp) { 5087 + *pkt = dummy_ipv6_gtpu_ipv6_udp_packet; 5088 + *pkt_len = sizeof(dummy_ipv6_gtpu_ipv6_udp_packet); 5089 + *offsets = dummy_ipv6_gtpu_ipv6_udp_packet_offsets; 5090 + } else { 5091 + *pkt = dummy_ipv6_gtpu_ipv6_tcp_packet; 5092 + *pkt_len = sizeof(dummy_ipv6_gtpu_ipv6_tcp_packet); 5093 + *offsets = dummy_ipv6_gtpu_ipv6_tcp_packet_offsets; 5094 + } 5095 + } else { 5096 + if (inner_udp) { 5097 + *pkt = dummy_ipv6_gtpu_ipv4_udp_packet; 5098 + *pkt_len = sizeof(dummy_ipv6_gtpu_ipv4_udp_packet); 5099 + *offsets = dummy_ipv6_gtpu_ipv4_udp_packet_offsets; 5100 + } else { 5101 + *pkt = dummy_ipv6_gtpu_ipv4_tcp_packet; 5102 + *pkt_len = sizeof(dummy_ipv6_gtpu_ipv4_tcp_packet); 5103 + *offsets = dummy_ipv6_gtpu_ipv4_tcp_packet_offsets; 5104 + } 5105 + } 5106 + } else { 5107 + if (gtp_no_pay) { 5108 + *pkt = dummy_ipv4_gtpu_ipv4_packet; 5109 + *pkt_len = sizeof(dummy_ipv4_gtpu_ipv4_packet); 5110 + *offsets = dummy_ipv4_gtp_no_pay_packet_offsets; 5111 + } else if (inner_ipv6) { 5112 + if (inner_udp) { 5113 + *pkt = dummy_ipv4_gtpu_ipv6_udp_packet; 5114 + *pkt_len = sizeof(dummy_ipv4_gtpu_ipv6_udp_packet); 5115 + *offsets = dummy_ipv4_gtpu_ipv6_udp_packet_offsets; 5116 + } else { 5117 + *pkt = dummy_ipv4_gtpu_ipv6_tcp_packet; 5118 + *pkt_len = sizeof(dummy_ipv4_gtpu_ipv6_tcp_packet); 5119 + *offsets = dummy_ipv4_gtpu_ipv6_tcp_packet_offsets; 5120 + } 5121 + } else { 5122 + if (inner_udp) { 5123 + *pkt = dummy_ipv4_gtpu_ipv4_udp_packet; 5124 + *pkt_len = sizeof(dummy_ipv4_gtpu_ipv4_udp_packet); 5125 + *offsets = dummy_ipv4_gtpu_ipv4_udp_packet_offsets; 5126 + } else { 5127 + *pkt = dummy_ipv4_gtpu_ipv4_tcp_packet; 5128 + *pkt_len = sizeof(dummy_ipv4_gtpu_ipv4_tcp_packet); 5129 + *offsets = dummy_ipv4_gtpu_ipv4_tcp_packet_offsets; 5130 + } 5131 + } 5132 + } 5133 + return; 5134 + } 5135 + 5136 + if (tun_type == ICE_SW_TUN_GTPC) { 5137 + if (outer_ipv6) { 5138 + *pkt = dummy_ipv6_gtp_packet; 5139 + *pkt_len = sizeof(dummy_ipv6_gtp_packet); 5140 + *offsets = dummy_ipv6_gtp_no_pay_packet_offsets; 5141 + } else { 5142 + *pkt = dummy_ipv4_gtpu_ipv4_packet; 5143 + *pkt_len = sizeof(dummy_ipv4_gtpu_ipv4_packet); 5144 + *offsets = dummy_ipv4_gtp_no_pay_packet_offsets; 5145 + } 5146 + return; 5539 5147 } 5540 5148 5541 5149 if (tun_type == ICE_SW_TUN_NVGRE) { 5542 - if (tcp && ipv6_il) { 5150 + if (inner_tcp && inner_ipv6) { 5543 5151 *pkt = dummy_gre_ipv6_tcp_packet; 5544 5152 *pkt_len = sizeof(dummy_gre_ipv6_tcp_packet); 5545 5153 *offsets = dummy_gre_ipv6_tcp_packet_offsets; 5546 5154 return; 5547 5155 } 5548 - if (tcp) { 5156 + if (inner_tcp) { 5549 5157 *pkt = dummy_gre_tcp_packet; 5550 5158 *pkt_len = sizeof(dummy_gre_tcp_packet); 5551 5159 *offsets = dummy_gre_tcp_packet_offsets; 5552 5160 return; 5553 5161 } 5554 - if (ipv6_il) { 5162 + if (inner_ipv6) { 5555 5163 *pkt = dummy_gre_ipv6_udp_packet; 5556 5164 *pkt_len = sizeof(dummy_gre_ipv6_udp_packet); 5557 5165 *offsets = dummy_gre_ipv6_udp_packet_offsets; ··· 5639 5099 5640 5100 if (tun_type == ICE_SW_TUN_VXLAN || 5641 5101 tun_type == ICE_SW_TUN_GENEVE) { 5642 - if (tcp && ipv6_il) { 5102 + if (inner_tcp && inner_ipv6) { 5643 5103 *pkt = dummy_udp_tun_ipv6_tcp_packet; 5644 5104 *pkt_len = sizeof(dummy_udp_tun_ipv6_tcp_packet); 5645 5105 *offsets = dummy_udp_tun_ipv6_tcp_packet_offsets; 5646 5106 return; 5647 5107 } 5648 - if (tcp) { 5108 + if (inner_tcp) { 5649 5109 *pkt = dummy_udp_tun_tcp_packet; 5650 5110 *pkt_len = sizeof(dummy_udp_tun_tcp_packet); 5651 5111 *offsets = dummy_udp_tun_tcp_packet_offsets; 5652 5112 return; 5653 5113 } 5654 - if (ipv6_il) { 5114 + if (inner_ipv6) { 5655 5115 *pkt = dummy_udp_tun_ipv6_udp_packet; 5656 5116 *pkt_len = sizeof(dummy_udp_tun_ipv6_udp_packet); 5657 5117 *offsets = dummy_udp_tun_ipv6_udp_packet_offsets; ··· 5663 5123 return; 5664 5124 } 5665 5125 5666 - if (udp && !ipv6) { 5126 + if (inner_udp && !outer_ipv6) { 5667 5127 if (vlan) { 5668 5128 *pkt = dummy_vlan_udp_packet; 5669 5129 *pkt_len = sizeof(dummy_vlan_udp_packet); ··· 5674 5134 *pkt_len = sizeof(dummy_udp_packet); 5675 5135 *offsets = dummy_udp_packet_offsets; 5676 5136 return; 5677 - } else if (udp && ipv6) { 5137 + } else if (inner_udp && outer_ipv6) { 5678 5138 if (vlan) { 5679 5139 *pkt = dummy_vlan_udp_ipv6_packet; 5680 5140 *pkt_len = sizeof(dummy_vlan_udp_ipv6_packet); ··· 5685 5145 *pkt_len = sizeof(dummy_udp_ipv6_packet); 5686 5146 *offsets = dummy_udp_ipv6_packet_offsets; 5687 5147 return; 5688 - } else if ((tcp && ipv6) || ipv6) { 5148 + } else if ((inner_tcp && outer_ipv6) || outer_ipv6) { 5689 5149 if (vlan) { 5690 5150 *pkt = dummy_vlan_tcp_ipv6_packet; 5691 5151 *pkt_len = sizeof(dummy_vlan_tcp_ipv6_packet); ··· 5790 5250 case ICE_VXLAN: 5791 5251 case ICE_GENEVE: 5792 5252 len = sizeof(struct ice_udp_tnl_hdr); 5253 + break; 5254 + case ICE_GTP_NO_PAY: 5255 + case ICE_GTP: 5256 + len = sizeof(struct ice_udp_gtp_hdr); 5793 5257 break; 5794 5258 default: 5795 5259 return -EINVAL;
+9
drivers/net/ethernet/intel/ice/ice_switch.h
··· 14 14 #define ICE_VSI_INVAL_ID 0xffff 15 15 #define ICE_INVAL_Q_HANDLE 0xFFFF 16 16 17 + /* Switch Profile IDs for Profile related switch rules */ 18 + #define ICE_PROFID_IPV4_GTPC_TEID 41 19 + #define ICE_PROFID_IPV4_GTPC_NO_TEID 42 20 + #define ICE_PROFID_IPV4_GTPU_TEID 43 21 + #define ICE_PROFID_IPV6_GTPC_TEID 44 22 + #define ICE_PROFID_IPV6_GTPC_NO_TEID 45 23 + #define ICE_PROFID_IPV6_GTPU_TEID 46 24 + #define ICE_PROFID_IPV6_GTPU_IPV6_TCP_INNER 70 25 + 17 26 #define ICE_SW_RULE_RX_TX_NO_HDR_SIZE \ 18 27 (offsetof(struct ice_aqc_sw_rules_elem, pdata.lkup_tx_rx.hdr)) 19 28
+102 -3
drivers/net/ethernet/intel/ice/ice_tc_lib.c
··· 27 27 if (flags & ICE_TC_FLWR_FIELD_ENC_DST_MAC) 28 28 lkups_cnt++; 29 29 30 + if (flags & ICE_TC_FLWR_FIELD_ENC_OPTS) 31 + lkups_cnt++; 32 + 30 33 if (flags & (ICE_TC_FLWR_FIELD_ENC_SRC_IPV4 | 31 34 ICE_TC_FLWR_FIELD_ENC_DEST_IPV4 | 32 35 ICE_TC_FLWR_FIELD_ENC_SRC_IPV6 | ··· 105 102 return ICE_GENEVE; 106 103 case TNL_GRETAP: 107 104 return ICE_NVGRE; 105 + case TNL_GTPU: 106 + /* NO_PAY profiles will not work with GTP-U */ 107 + return ICE_GTP; 108 + case TNL_GTPC: 109 + return ICE_GTP_NO_PAY; 108 110 default: 109 111 return 0; 110 112 } ··· 125 117 return ICE_SW_TUN_GENEVE; 126 118 case TNL_GRETAP: 127 119 return ICE_SW_TUN_NVGRE; 120 + case TNL_GTPU: 121 + return ICE_SW_TUN_GTPU; 122 + case TNL_GTPC: 123 + return ICE_SW_TUN_GTPC; 128 124 default: 129 125 return ICE_NON_TUN; 130 126 } ··· 155 143 break; 156 144 case TNL_GRETAP: 157 145 list[i].h_u.nvgre_hdr.tni_flow = fltr->tenant_id; 158 - memcpy(&list[i].m_u.nvgre_hdr.tni_flow, "\xff\xff\xff\xff", 4); 146 + memcpy(&list[i].m_u.nvgre_hdr.tni_flow, 147 + "\xff\xff\xff\xff", 4); 148 + i++; 149 + break; 150 + case TNL_GTPC: 151 + case TNL_GTPU: 152 + list[i].h_u.gtp_hdr.teid = fltr->tenant_id; 153 + memcpy(&list[i].m_u.gtp_hdr.teid, 154 + "\xff\xff\xff\xff", 4); 159 155 i++; 160 156 break; 161 157 default: ··· 177 157 hdr->l2_key.dst_mac); 178 158 ether_addr_copy(list[i].m_u.eth_hdr.dst_addr, 179 159 hdr->l2_mask.dst_mac); 160 + i++; 161 + } 162 + 163 + if (flags & ICE_TC_FLWR_FIELD_ENC_OPTS && 164 + (fltr->tunnel_type == TNL_GTPU || fltr->tunnel_type == TNL_GTPC)) { 165 + list[i].type = ice_proto_type_from_tunnel(fltr->tunnel_type); 166 + 167 + if (fltr->gtp_pdu_info_masks.pdu_type) { 168 + list[i].h_u.gtp_hdr.pdu_type = 169 + fltr->gtp_pdu_info_keys.pdu_type << 4; 170 + memcpy(&list[i].m_u.gtp_hdr.pdu_type, "\xf0", 1); 171 + } 172 + 173 + if (fltr->gtp_pdu_info_masks.qfi) { 174 + list[i].h_u.gtp_hdr.qfi = fltr->gtp_pdu_info_keys.qfi; 175 + memcpy(&list[i].m_u.gtp_hdr.qfi, "\x3f", 1); 176 + } 177 + 180 178 i++; 181 179 } 182 180 ··· 399 361 if (netif_is_gretap(tunnel_dev) || 400 362 netif_is_ip6gretap(tunnel_dev)) 401 363 return TNL_GRETAP; 364 + 365 + /* Assume GTP-U by default in case of GTP netdev. 366 + * GTP-C may be selected later, based on enc_dst_port. 367 + */ 368 + if (netif_is_gtp(tunnel_dev)) 369 + return TNL_GTPU; 402 370 return TNL_LAST; 403 371 } 404 372 ··· 804 760 return NULL; 805 761 } 806 762 763 + /** 764 + * ice_parse_gtp_type - Sets GTP tunnel type to GTP-U or GTP-C 765 + * @match: Flow match structure 766 + * @fltr: Pointer to filter structure 767 + * 768 + * GTP-C/GTP-U is selected based on destination port number (enc_dst_port). 769 + * Before calling this funtcion, fltr->tunnel_type should be set to TNL_GTPU, 770 + * therefore making GTP-U the default choice (when destination port number is 771 + * not specified). 772 + */ 773 + static int 774 + ice_parse_gtp_type(struct flow_match_ports match, 775 + struct ice_tc_flower_fltr *fltr) 776 + { 777 + u16 dst_port; 778 + 779 + if (match.key->dst) { 780 + dst_port = be16_to_cpu(match.key->dst); 781 + 782 + switch (dst_port) { 783 + case 2152: 784 + break; 785 + case 2123: 786 + fltr->tunnel_type = TNL_GTPC; 787 + break; 788 + default: 789 + NL_SET_ERR_MSG_MOD(fltr->extack, "Unsupported GTP port number"); 790 + return -EINVAL; 791 + } 792 + } 793 + 794 + return 0; 795 + } 796 + 807 797 static int 808 798 ice_parse_tunnel_attr(struct net_device *dev, struct flow_rule *rule, 809 799 struct ice_tc_flower_fltr *fltr) ··· 893 815 struct flow_match_ports match; 894 816 895 817 flow_rule_match_enc_ports(rule, &match); 896 - if (ice_tc_set_port(match, fltr, headers, true)) 897 - return -EINVAL; 818 + 819 + if (fltr->tunnel_type != TNL_GTPU) { 820 + if (ice_tc_set_port(match, fltr, headers, true)) 821 + return -EINVAL; 822 + } else { 823 + if (ice_parse_gtp_type(match, fltr)) 824 + return -EINVAL; 825 + } 826 + } 827 + 828 + if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_OPTS)) { 829 + struct flow_match_enc_opts match; 830 + 831 + flow_rule_match_enc_opts(rule, &match); 832 + 833 + memcpy(&fltr->gtp_pdu_info_keys, &match.key->data[0], 834 + sizeof(struct gtp_pdu_session_info)); 835 + 836 + memcpy(&fltr->gtp_pdu_info_masks, &match.mask->data[0], 837 + sizeof(struct gtp_pdu_session_info)); 838 + 839 + fltr->flags |= ICE_TC_FLWR_FIELD_ENC_OPTS; 898 840 } 899 841 900 842 return 0; ··· 952 854 BIT(FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS) | 953 855 BIT(FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS) | 954 856 BIT(FLOW_DISSECTOR_KEY_ENC_PORTS) | 857 + BIT(FLOW_DISSECTOR_KEY_ENC_OPTS) | 955 858 BIT(FLOW_DISSECTOR_KEY_ENC_IP) | 956 859 BIT(FLOW_DISSECTOR_KEY_PORTS))) { 957 860 NL_SET_ERR_MSG_MOD(fltr->extack, "Unsupported key used");
+3
drivers/net/ethernet/intel/ice/ice_tc_lib.h
··· 22 22 #define ICE_TC_FLWR_FIELD_ENC_SRC_L4_PORT BIT(15) 23 23 #define ICE_TC_FLWR_FIELD_ENC_DST_MAC BIT(16) 24 24 #define ICE_TC_FLWR_FIELD_ETH_TYPE_ID BIT(17) 25 + #define ICE_TC_FLWR_FIELD_ENC_OPTS BIT(18) 25 26 26 27 #define ICE_TC_FLOWER_MASK_32 0xFFFFFFFF 27 28 ··· 120 119 struct ice_tc_flower_lyr_2_4_hdrs inner_headers; 121 120 struct ice_vsi *src_vsi; 122 121 __be32 tenant_id; 122 + struct gtp_pdu_session_info gtp_pdu_info_keys; 123 + struct gtp_pdu_session_info gtp_pdu_info_masks; 123 124 u32 flags; 124 125 u8 tunnel_type; 125 126 struct ice_tc_flower_action action;
+522 -43
drivers/net/gtp.c
··· 66 66 67 67 struct sock *sk0; 68 68 struct sock *sk1u; 69 + u8 sk_created; 69 70 70 71 struct net_device *dev; 72 + struct net *net; 71 73 72 74 unsigned int role; 73 75 unsigned int hash_size; 74 76 struct hlist_head *tid_hash; 75 77 struct hlist_head *addr_hash; 78 + 79 + u8 restart_count; 80 + }; 81 + 82 + struct echo_info { 83 + struct in_addr ms_addr_ip4; 84 + struct in_addr peer_addr_ip4; 85 + u8 gtp_version; 76 86 }; 77 87 78 88 static unsigned int gtp_net_id __read_mostly; ··· 92 82 }; 93 83 94 84 static u32 gtp_h_initval; 85 + 86 + static struct genl_family gtp_genl_family; 87 + 88 + enum gtp_multicast_groups { 89 + GTP_GENL_MCGRP, 90 + }; 91 + 92 + static const struct genl_multicast_group gtp_genl_mcgrps[] = { 93 + [GTP_GENL_MCGRP] = { .name = GTP_GENL_MCGRP_NAME }, 94 + }; 95 95 96 96 static void pdp_context_delete(struct pdp_ctx *pctx); 97 97 ··· 235 215 return -1; 236 216 } 237 217 218 + static struct rtable *ip4_route_output_gtp(struct flowi4 *fl4, 219 + const struct sock *sk, 220 + __be32 daddr, __be32 saddr) 221 + { 222 + memset(fl4, 0, sizeof(*fl4)); 223 + fl4->flowi4_oif = sk->sk_bound_dev_if; 224 + fl4->daddr = daddr; 225 + fl4->saddr = saddr; 226 + fl4->flowi4_tos = RT_CONN_FLAGS(sk); 227 + fl4->flowi4_proto = sk->sk_protocol; 228 + 229 + return ip_route_output_key(sock_net(sk), fl4); 230 + } 231 + 232 + /* GSM TS 09.60. 7.3 233 + * In all Path Management messages: 234 + * - TID: is not used and shall be set to 0. 235 + * - Flow Label is not used and shall be set to 0 236 + * In signalling messages: 237 + * - number: this field is not yet used in signalling messages. 238 + * It shall be set to 255 by the sender and shall be ignored 239 + * by the receiver 240 + * Returns true if the echo req was correct, false otherwise. 241 + */ 242 + static bool gtp0_validate_echo_hdr(struct gtp0_header *gtp0) 243 + { 244 + return !(gtp0->tid || (gtp0->flags ^ 0x1e) || 245 + gtp0->number != 0xff || gtp0->flow); 246 + } 247 + 248 + /* msg_type has to be GTP_ECHO_REQ or GTP_ECHO_RSP */ 249 + static void gtp0_build_echo_msg(struct gtp0_header *hdr, __u8 msg_type) 250 + { 251 + int len_pkt, len_hdr; 252 + 253 + hdr->flags = 0x1e; /* v0, GTP-non-prime. */ 254 + hdr->type = msg_type; 255 + /* GSM TS 09.60. 7.3 In all Path Management Flow Label and TID 256 + * are not used and shall be set to 0. 257 + */ 258 + hdr->flow = 0; 259 + hdr->tid = 0; 260 + hdr->number = 0xff; 261 + hdr->spare[0] = 0xff; 262 + hdr->spare[1] = 0xff; 263 + hdr->spare[2] = 0xff; 264 + 265 + len_pkt = sizeof(struct gtp0_packet); 266 + len_hdr = sizeof(struct gtp0_header); 267 + 268 + if (msg_type == GTP_ECHO_RSP) 269 + hdr->length = htons(len_pkt - len_hdr); 270 + else 271 + hdr->length = 0; 272 + } 273 + 274 + static int gtp0_send_echo_resp(struct gtp_dev *gtp, struct sk_buff *skb) 275 + { 276 + struct gtp0_packet *gtp_pkt; 277 + struct gtp0_header *gtp0; 278 + struct rtable *rt; 279 + struct flowi4 fl4; 280 + struct iphdr *iph; 281 + __be16 seq; 282 + 283 + gtp0 = (struct gtp0_header *)(skb->data + sizeof(struct udphdr)); 284 + 285 + if (!gtp0_validate_echo_hdr(gtp0)) 286 + return -1; 287 + 288 + seq = gtp0->seq; 289 + 290 + /* pull GTP and UDP headers */ 291 + skb_pull_data(skb, sizeof(struct gtp0_header) + sizeof(struct udphdr)); 292 + 293 + gtp_pkt = skb_push(skb, sizeof(struct gtp0_packet)); 294 + memset(gtp_pkt, 0, sizeof(struct gtp0_packet)); 295 + 296 + gtp0_build_echo_msg(&gtp_pkt->gtp0_h, GTP_ECHO_RSP); 297 + 298 + /* GSM TS 09.60. 7.3 The Sequence Number in a signalling response 299 + * message shall be copied from the signalling request message 300 + * that the GSN is replying to. 301 + */ 302 + gtp_pkt->gtp0_h.seq = seq; 303 + 304 + gtp_pkt->ie.tag = GTPIE_RECOVERY; 305 + gtp_pkt->ie.val = gtp->restart_count; 306 + 307 + iph = ip_hdr(skb); 308 + 309 + /* find route to the sender, 310 + * src address becomes dst address and vice versa. 311 + */ 312 + rt = ip4_route_output_gtp(&fl4, gtp->sk0, iph->saddr, iph->daddr); 313 + if (IS_ERR(rt)) { 314 + netdev_dbg(gtp->dev, "no route for echo response from %pI4\n", 315 + &iph->saddr); 316 + return -1; 317 + } 318 + 319 + udp_tunnel_xmit_skb(rt, gtp->sk0, skb, 320 + fl4.saddr, fl4.daddr, 321 + iph->tos, 322 + ip4_dst_hoplimit(&rt->dst), 323 + 0, 324 + htons(GTP0_PORT), htons(GTP0_PORT), 325 + !net_eq(sock_net(gtp->sk1u), 326 + dev_net(gtp->dev)), 327 + false); 328 + return 0; 329 + } 330 + 331 + static int gtp_genl_fill_echo(struct sk_buff *skb, u32 snd_portid, u32 snd_seq, 332 + int flags, u32 type, struct echo_info echo) 333 + { 334 + void *genlh; 335 + 336 + genlh = genlmsg_put(skb, snd_portid, snd_seq, &gtp_genl_family, flags, 337 + type); 338 + if (!genlh) 339 + goto failure; 340 + 341 + if (nla_put_u32(skb, GTPA_VERSION, echo.gtp_version) || 342 + nla_put_be32(skb, GTPA_PEER_ADDRESS, echo.peer_addr_ip4.s_addr) || 343 + nla_put_be32(skb, GTPA_MS_ADDRESS, echo.ms_addr_ip4.s_addr)) 344 + goto failure; 345 + 346 + genlmsg_end(skb, genlh); 347 + return 0; 348 + 349 + failure: 350 + genlmsg_cancel(skb, genlh); 351 + return -EMSGSIZE; 352 + } 353 + 354 + static int gtp0_handle_echo_resp(struct gtp_dev *gtp, struct sk_buff *skb) 355 + { 356 + struct gtp0_header *gtp0; 357 + struct echo_info echo; 358 + struct sk_buff *msg; 359 + struct iphdr *iph; 360 + int ret; 361 + 362 + gtp0 = (struct gtp0_header *)(skb->data + sizeof(struct udphdr)); 363 + 364 + if (!gtp0_validate_echo_hdr(gtp0)) 365 + return -1; 366 + 367 + iph = ip_hdr(skb); 368 + echo.ms_addr_ip4.s_addr = iph->daddr; 369 + echo.peer_addr_ip4.s_addr = iph->saddr; 370 + echo.gtp_version = GTP_V0; 371 + 372 + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); 373 + if (!msg) 374 + return -ENOMEM; 375 + 376 + ret = gtp_genl_fill_echo(msg, 0, 0, 0, GTP_CMD_ECHOREQ, echo); 377 + if (ret < 0) { 378 + nlmsg_free(msg); 379 + return ret; 380 + } 381 + 382 + return genlmsg_multicast_netns(&gtp_genl_family, dev_net(gtp->dev), 383 + msg, 0, GTP_GENL_MCGRP, GFP_ATOMIC); 384 + } 385 + 238 386 /* 1 means pass up to the stack, -1 means drop and 0 means decapsulated. */ 239 387 static int gtp0_udp_encap_recv(struct gtp_dev *gtp, struct sk_buff *skb) 240 388 { ··· 419 231 if ((gtp0->flags >> 5) != GTP_V0) 420 232 return 1; 421 233 234 + /* If the sockets were created in kernel, it means that 235 + * there is no daemon running in userspace which would 236 + * handle echo request. 237 + */ 238 + if (gtp0->type == GTP_ECHO_REQ && gtp->sk_created) 239 + return gtp0_send_echo_resp(gtp, skb); 240 + 241 + if (gtp0->type == GTP_ECHO_RSP && gtp->sk_created) 242 + return gtp0_handle_echo_resp(gtp, skb); 243 + 422 244 if (gtp0->type != GTP_TPDU) 423 245 return 1; 424 246 ··· 439 241 } 440 242 441 243 return gtp_rx(pctx, skb, hdrlen, gtp->role); 244 + } 245 + 246 + /* msg_type has to be GTP_ECHO_REQ or GTP_ECHO_RSP */ 247 + static void gtp1u_build_echo_msg(struct gtp1_header_long *hdr, __u8 msg_type) 248 + { 249 + int len_pkt, len_hdr; 250 + 251 + /* S flag must be set to 1 */ 252 + hdr->flags = 0x32; /* v1, GTP-non-prime. */ 253 + hdr->type = msg_type; 254 + /* 3GPP TS 29.281 5.1 - TEID has to be set to 0 */ 255 + hdr->tid = 0; 256 + 257 + /* seq, npdu and next should be counted to the length of the GTP packet 258 + * that's why szie of gtp1_header should be subtracted, 259 + * not size of gtp1_header_long. 260 + */ 261 + 262 + len_hdr = sizeof(struct gtp1_header); 263 + 264 + if (msg_type == GTP_ECHO_RSP) { 265 + len_pkt = sizeof(struct gtp1u_packet); 266 + hdr->length = htons(len_pkt - len_hdr); 267 + } else { 268 + /* GTP_ECHO_REQ does not carry GTP Information Element, 269 + * the why gtp1_header_long is used here. 270 + */ 271 + len_pkt = sizeof(struct gtp1_header_long); 272 + hdr->length = htons(len_pkt - len_hdr); 273 + } 274 + } 275 + 276 + static int gtp1u_send_echo_resp(struct gtp_dev *gtp, struct sk_buff *skb) 277 + { 278 + struct gtp1_header_long *gtp1u; 279 + struct gtp1u_packet *gtp_pkt; 280 + struct rtable *rt; 281 + struct flowi4 fl4; 282 + struct iphdr *iph; 283 + 284 + gtp1u = (struct gtp1_header_long *)(skb->data + sizeof(struct udphdr)); 285 + 286 + /* 3GPP TS 29.281 5.1 - For the Echo Request, Echo Response, 287 + * Error Indication and Supported Extension Headers Notification 288 + * messages, the S flag shall be set to 1 and TEID shall be set to 0. 289 + */ 290 + if (!(gtp1u->flags & GTP1_F_SEQ) || gtp1u->tid) 291 + return -1; 292 + 293 + /* pull GTP and UDP headers */ 294 + skb_pull_data(skb, 295 + sizeof(struct gtp1_header_long) + sizeof(struct udphdr)); 296 + 297 + gtp_pkt = skb_push(skb, sizeof(struct gtp1u_packet)); 298 + memset(gtp_pkt, 0, sizeof(struct gtp1u_packet)); 299 + 300 + gtp1u_build_echo_msg(&gtp_pkt->gtp1u_h, GTP_ECHO_RSP); 301 + 302 + /* 3GPP TS 29.281 7.7.2 - The Restart Counter value in the 303 + * Recovery information element shall not be used, i.e. it shall 304 + * be set to zero by the sender and shall be ignored by the receiver. 305 + * The Recovery information element is mandatory due to backwards 306 + * compatibility reasons. 307 + */ 308 + gtp_pkt->ie.tag = GTPIE_RECOVERY; 309 + gtp_pkt->ie.val = 0; 310 + 311 + iph = ip_hdr(skb); 312 + 313 + /* find route to the sender, 314 + * src address becomes dst address and vice versa. 315 + */ 316 + rt = ip4_route_output_gtp(&fl4, gtp->sk1u, iph->saddr, iph->daddr); 317 + if (IS_ERR(rt)) { 318 + netdev_dbg(gtp->dev, "no route for echo response from %pI4\n", 319 + &iph->saddr); 320 + return -1; 321 + } 322 + 323 + udp_tunnel_xmit_skb(rt, gtp->sk1u, skb, 324 + fl4.saddr, fl4.daddr, 325 + iph->tos, 326 + ip4_dst_hoplimit(&rt->dst), 327 + 0, 328 + htons(GTP1U_PORT), htons(GTP1U_PORT), 329 + !net_eq(sock_net(gtp->sk1u), 330 + dev_net(gtp->dev)), 331 + false); 332 + return 0; 333 + } 334 + 335 + static int gtp1u_handle_echo_resp(struct gtp_dev *gtp, struct sk_buff *skb) 336 + { 337 + struct gtp1_header_long *gtp1u; 338 + struct echo_info echo; 339 + struct sk_buff *msg; 340 + struct iphdr *iph; 341 + int ret; 342 + 343 + gtp1u = (struct gtp1_header_long *)(skb->data + sizeof(struct udphdr)); 344 + 345 + /* 3GPP TS 29.281 5.1 - For the Echo Request, Echo Response, 346 + * Error Indication and Supported Extension Headers Notification 347 + * messages, the S flag shall be set to 1 and TEID shall be set to 0. 348 + */ 349 + if (!(gtp1u->flags & GTP1_F_SEQ) || gtp1u->tid) 350 + return -1; 351 + 352 + iph = ip_hdr(skb); 353 + echo.ms_addr_ip4.s_addr = iph->daddr; 354 + echo.peer_addr_ip4.s_addr = iph->saddr; 355 + echo.gtp_version = GTP_V1; 356 + 357 + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); 358 + if (!msg) 359 + return -ENOMEM; 360 + 361 + ret = gtp_genl_fill_echo(msg, 0, 0, 0, GTP_CMD_ECHOREQ, echo); 362 + if (ret < 0) { 363 + nlmsg_free(msg); 364 + return ret; 365 + } 366 + 367 + return genlmsg_multicast_netns(&gtp_genl_family, dev_net(gtp->dev), 368 + msg, 0, GTP_GENL_MCGRP, GFP_ATOMIC); 442 369 } 443 370 444 371 static int gtp1u_udp_encap_recv(struct gtp_dev *gtp, struct sk_buff *skb) ··· 580 257 581 258 if ((gtp1->flags >> 5) != GTP_V1) 582 259 return 1; 260 + 261 + /* If the sockets were created in kernel, it means that 262 + * there is no daemon running in userspace which would 263 + * handle echo request. 264 + */ 265 + if (gtp1->type == GTP_ECHO_REQ && gtp->sk_created) 266 + return gtp1u_send_echo_resp(gtp, skb); 267 + 268 + if (gtp1->type == GTP_ECHO_RSP && gtp->sk_created) 269 + return gtp1u_handle_echo_resp(gtp, skb); 583 270 584 271 if (gtp1->type != GTP_TPDU) 585 272 return 1; ··· 653 320 654 321 static void gtp_encap_disable(struct gtp_dev *gtp) 655 322 { 656 - gtp_encap_disable_sock(gtp->sk0); 657 - gtp_encap_disable_sock(gtp->sk1u); 323 + if (gtp->sk_created) { 324 + udp_tunnel_sock_release(gtp->sk0->sk_socket); 325 + udp_tunnel_sock_release(gtp->sk1u->sk_socket); 326 + gtp->sk_created = false; 327 + gtp->sk0 = NULL; 328 + gtp->sk1u = NULL; 329 + } else { 330 + gtp_encap_disable_sock(gtp->sk0); 331 + gtp_encap_disable_sock(gtp->sk1u); 332 + } 658 333 } 659 334 660 335 /* UDP encapsulation receive handler. See net/ipv4/udp.c. ··· 727 386 728 387 gtp_encap_disable(gtp); 729 388 free_percpu(dev->tstats); 730 - } 731 - 732 - static struct rtable *ip4_route_output_gtp(struct flowi4 *fl4, 733 - const struct sock *sk, 734 - __be32 daddr) 735 - { 736 - memset(fl4, 0, sizeof(*fl4)); 737 - fl4->flowi4_oif = sk->sk_bound_dev_if; 738 - fl4->daddr = daddr; 739 - fl4->saddr = inet_sk(sk)->inet_saddr; 740 - fl4->flowi4_tos = RT_CONN_FLAGS(sk); 741 - fl4->flowi4_proto = sk->sk_protocol; 742 - 743 - return ip_route_output_key(sock_net(sk), fl4); 744 389 } 745 390 746 391 static inline void gtp0_push_header(struct sk_buff *skb, struct pdp_ctx *pctx) ··· 834 507 } 835 508 netdev_dbg(dev, "found PDP context %p\n", pctx); 836 509 837 - rt = ip4_route_output_gtp(&fl4, pctx->sk, pctx->peer_addr_ip4.s_addr); 510 + rt = ip4_route_output_gtp(&fl4, pctx->sk, pctx->peer_addr_ip4.s_addr, 511 + inet_sk(pctx->sk)->inet_saddr); 838 512 if (IS_ERR(rt)) { 839 513 netdev_dbg(dev, "no route to SSGN %pI4\n", 840 514 &pctx->peer_addr_ip4.s_addr); ··· 984 656 kfree(gtp->tid_hash); 985 657 } 986 658 659 + static struct sock *gtp_create_sock(int type, struct gtp_dev *gtp) 660 + { 661 + struct udp_tunnel_sock_cfg tuncfg = {}; 662 + struct udp_port_cfg udp_conf = { 663 + .local_ip.s_addr = htonl(INADDR_ANY), 664 + .family = AF_INET, 665 + }; 666 + struct net *net = gtp->net; 667 + struct socket *sock; 668 + int err; 669 + 670 + if (type == UDP_ENCAP_GTP0) 671 + udp_conf.local_udp_port = htons(GTP0_PORT); 672 + else if (type == UDP_ENCAP_GTP1U) 673 + udp_conf.local_udp_port = htons(GTP1U_PORT); 674 + else 675 + return ERR_PTR(-EINVAL); 676 + 677 + err = udp_sock_create(net, &udp_conf, &sock); 678 + if (err) 679 + return ERR_PTR(err); 680 + 681 + tuncfg.sk_user_data = gtp; 682 + tuncfg.encap_type = type; 683 + tuncfg.encap_rcv = gtp_encap_recv; 684 + tuncfg.encap_destroy = NULL; 685 + 686 + setup_udp_tunnel_sock(net, sock, &tuncfg); 687 + 688 + return sock->sk; 689 + } 690 + 691 + static int gtp_create_sockets(struct gtp_dev *gtp, struct nlattr *data[]) 692 + { 693 + struct sock *sk1u = NULL; 694 + struct sock *sk0 = NULL; 695 + 696 + sk0 = gtp_create_sock(UDP_ENCAP_GTP0, gtp); 697 + if (IS_ERR(sk0)) 698 + return PTR_ERR(sk0); 699 + 700 + sk1u = gtp_create_sock(UDP_ENCAP_GTP1U, gtp); 701 + if (IS_ERR(sk1u)) { 702 + udp_tunnel_sock_release(sk0->sk_socket); 703 + return PTR_ERR(sk1u); 704 + } 705 + 706 + gtp->sk_created = true; 707 + gtp->sk0 = sk0; 708 + gtp->sk1u = sk1u; 709 + 710 + return 0; 711 + } 712 + 987 713 static int gtp_newlink(struct net *src_net, struct net_device *dev, 988 714 struct nlattr *tb[], struct nlattr *data[], 989 715 struct netlink_ext_ack *extack) 990 716 { 717 + unsigned int role = GTP_ROLE_GGSN; 991 718 struct gtp_dev *gtp; 992 719 struct gtp_net *gn; 993 720 int hashsize, err; 994 - 995 - if (!data[IFLA_GTP_FD0] && !data[IFLA_GTP_FD1]) 996 - return -EINVAL; 997 721 998 722 gtp = netdev_priv(dev); 999 723 ··· 1057 677 hashsize = 1024; 1058 678 } 1059 679 680 + if (data[IFLA_GTP_ROLE]) { 681 + role = nla_get_u32(data[IFLA_GTP_ROLE]); 682 + if (role > GTP_ROLE_SGSN) 683 + return -EINVAL; 684 + } 685 + gtp->role = role; 686 + 687 + if (!data[IFLA_GTP_RESTART_COUNT]) 688 + gtp->restart_count = 0; 689 + else 690 + gtp->restart_count = nla_get_u8(data[IFLA_GTP_RESTART_COUNT]); 691 + 692 + gtp->net = src_net; 693 + 1060 694 err = gtp_hashtable_new(gtp, hashsize); 1061 695 if (err < 0) 1062 696 return err; 1063 697 1064 - err = gtp_encap_enable(gtp, data); 698 + if (data[IFLA_GTP_CREATE_SOCKETS]) 699 + err = gtp_create_sockets(gtp, data); 700 + else 701 + err = gtp_encap_enable(gtp, data); 1065 702 if (err < 0) 1066 703 goto out_hashtable; 1067 704 ··· 1123 726 [IFLA_GTP_FD1] = { .type = NLA_U32 }, 1124 727 [IFLA_GTP_PDP_HASHSIZE] = { .type = NLA_U32 }, 1125 728 [IFLA_GTP_ROLE] = { .type = NLA_U32 }, 729 + [IFLA_GTP_CREATE_SOCKETS] = { .type = NLA_U8 }, 730 + [IFLA_GTP_RESTART_COUNT] = { .type = NLA_U8 }, 1126 731 }; 1127 732 1128 733 static int gtp_validate(struct nlattr *tb[], struct nlattr *data[], ··· 1139 740 static size_t gtp_get_size(const struct net_device *dev) 1140 741 { 1141 742 return nla_total_size(sizeof(__u32)) + /* IFLA_GTP_PDP_HASHSIZE */ 1142 - nla_total_size(sizeof(__u32)); /* IFLA_GTP_ROLE */ 743 + nla_total_size(sizeof(__u32)) + /* IFLA_GTP_ROLE */ 744 + nla_total_size(sizeof(__u8)); /* IFLA_GTP_RESTART_COUNT */ 1143 745 } 1144 746 1145 747 static int gtp_fill_info(struct sk_buff *skb, const struct net_device *dev) ··· 1150 750 if (nla_put_u32(skb, IFLA_GTP_PDP_HASHSIZE, gtp->hash_size)) 1151 751 goto nla_put_failure; 1152 752 if (nla_put_u32(skb, IFLA_GTP_ROLE, gtp->role)) 753 + goto nla_put_failure; 754 + if (nla_put_u8(skb, IFLA_GTP_RESTART_COUNT, gtp->restart_count)) 1153 755 goto nla_put_failure; 1154 756 1155 757 return 0; ··· 1250 848 { 1251 849 struct sock *sk1u = NULL; 1252 850 struct sock *sk0 = NULL; 1253 - unsigned int role = GTP_ROLE_GGSN; 851 + 852 + if (!data[IFLA_GTP_FD0] && !data[IFLA_GTP_FD1]) 853 + return -EINVAL; 1254 854 1255 855 if (data[IFLA_GTP_FD0]) { 1256 856 u32 fd0 = nla_get_u32(data[IFLA_GTP_FD0]); ··· 1272 868 } 1273 869 } 1274 870 1275 - if (data[IFLA_GTP_ROLE]) { 1276 - role = nla_get_u32(data[IFLA_GTP_ROLE]); 1277 - if (role > GTP_ROLE_SGSN) { 1278 - gtp_encap_disable_sock(sk0); 1279 - gtp_encap_disable_sock(sk1u); 1280 - return -EINVAL; 1281 - } 1282 - } 1283 - 1284 871 gtp->sk0 = sk0; 1285 872 gtp->sk1u = sk1u; 1286 - gtp->role = role; 1287 873 1288 874 return 0; 1289 875 } ··· 1577 1183 return err; 1578 1184 } 1579 1185 1580 - static struct genl_family gtp_genl_family; 1581 - 1582 - enum gtp_multicast_groups { 1583 - GTP_GENL_MCGRP, 1584 - }; 1585 - 1586 - static const struct genl_multicast_group gtp_genl_mcgrps[] = { 1587 - [GTP_GENL_MCGRP] = { .name = GTP_GENL_MCGRP_NAME }, 1588 - }; 1589 - 1590 1186 static int gtp_genl_fill_info(struct sk_buff *skb, u32 snd_portid, u32 snd_seq, 1591 1187 int flags, u32 type, struct pdp_ctx *pctx) 1592 1188 { ··· 1720 1336 return skb->len; 1721 1337 } 1722 1338 1339 + static int gtp_genl_send_echo_req(struct sk_buff *skb, struct genl_info *info) 1340 + { 1341 + struct sk_buff *skb_to_send; 1342 + __be32 src_ip, dst_ip; 1343 + unsigned int version; 1344 + struct gtp_dev *gtp; 1345 + struct flowi4 fl4; 1346 + struct rtable *rt; 1347 + struct sock *sk; 1348 + __be16 port; 1349 + int len; 1350 + 1351 + if (!info->attrs[GTPA_VERSION] || 1352 + !info->attrs[GTPA_LINK] || 1353 + !info->attrs[GTPA_PEER_ADDRESS] || 1354 + !info->attrs[GTPA_MS_ADDRESS]) 1355 + return -EINVAL; 1356 + 1357 + version = nla_get_u32(info->attrs[GTPA_VERSION]); 1358 + dst_ip = nla_get_be32(info->attrs[GTPA_PEER_ADDRESS]); 1359 + src_ip = nla_get_be32(info->attrs[GTPA_MS_ADDRESS]); 1360 + 1361 + gtp = gtp_find_dev(sock_net(skb->sk), info->attrs); 1362 + if (!gtp) 1363 + return -ENODEV; 1364 + 1365 + if (!gtp->sk_created) 1366 + return -EOPNOTSUPP; 1367 + if (!(gtp->dev->flags & IFF_UP)) 1368 + return -ENETDOWN; 1369 + 1370 + if (version == GTP_V0) { 1371 + struct gtp0_header *gtp0_h; 1372 + 1373 + len = LL_RESERVED_SPACE(gtp->dev) + sizeof(struct gtp0_header) + 1374 + sizeof(struct iphdr) + sizeof(struct udphdr); 1375 + 1376 + skb_to_send = netdev_alloc_skb_ip_align(gtp->dev, len); 1377 + if (!skb_to_send) 1378 + return -ENOMEM; 1379 + 1380 + sk = gtp->sk0; 1381 + port = htons(GTP0_PORT); 1382 + 1383 + gtp0_h = skb_push(skb_to_send, sizeof(struct gtp0_header)); 1384 + memset(gtp0_h, 0, sizeof(struct gtp0_header)); 1385 + gtp0_build_echo_msg(gtp0_h, GTP_ECHO_REQ); 1386 + } else if (version == GTP_V1) { 1387 + struct gtp1_header_long *gtp1u_h; 1388 + 1389 + len = LL_RESERVED_SPACE(gtp->dev) + 1390 + sizeof(struct gtp1_header_long) + 1391 + sizeof(struct iphdr) + sizeof(struct udphdr); 1392 + 1393 + skb_to_send = netdev_alloc_skb_ip_align(gtp->dev, len); 1394 + if (!skb_to_send) 1395 + return -ENOMEM; 1396 + 1397 + sk = gtp->sk1u; 1398 + port = htons(GTP1U_PORT); 1399 + 1400 + gtp1u_h = skb_push(skb_to_send, 1401 + sizeof(struct gtp1_header_long)); 1402 + memset(gtp1u_h, 0, sizeof(struct gtp1_header_long)); 1403 + gtp1u_build_echo_msg(gtp1u_h, GTP_ECHO_REQ); 1404 + } else { 1405 + return -ENODEV; 1406 + } 1407 + 1408 + rt = ip4_route_output_gtp(&fl4, sk, dst_ip, src_ip); 1409 + if (IS_ERR(rt)) { 1410 + netdev_dbg(gtp->dev, "no route for echo request to %pI4\n", 1411 + &dst_ip); 1412 + kfree_skb(skb_to_send); 1413 + return -ENODEV; 1414 + } 1415 + 1416 + udp_tunnel_xmit_skb(rt, sk, skb_to_send, 1417 + fl4.saddr, fl4.daddr, 1418 + fl4.flowi4_tos, 1419 + ip4_dst_hoplimit(&rt->dst), 1420 + 0, 1421 + port, port, 1422 + !net_eq(sock_net(sk), 1423 + dev_net(gtp->dev)), 1424 + false); 1425 + return 0; 1426 + } 1427 + 1723 1428 static const struct nla_policy gtp_genl_policy[GTPA_MAX + 1] = { 1724 1429 [GTPA_LINK] = { .type = NLA_U32, }, 1725 1430 [GTPA_VERSION] = { .type = NLA_U32, }, ··· 1839 1366 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1840 1367 .doit = gtp_genl_get_pdp, 1841 1368 .dumpit = gtp_genl_dump_pdp, 1369 + .flags = GENL_ADMIN_PERM, 1370 + }, 1371 + { 1372 + .cmd = GTP_CMD_ECHOREQ, 1373 + .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, 1374 + .doit = gtp_genl_send_echo_req, 1842 1375 .flags = GENL_ADMIN_PERM, 1843 1376 }, 1844 1377 };
+42
include/net/gtp.h
··· 7 7 #define GTP0_PORT 3386 8 8 #define GTP1U_PORT 2152 9 9 10 + /* GTP messages types */ 11 + #define GTP_ECHO_REQ 1 /* Echo Request */ 12 + #define GTP_ECHO_RSP 2 /* Echo Response */ 10 13 #define GTP_TPDU 255 14 + 15 + #define GTPIE_RECOVERY 14 11 16 12 17 struct gtp0_header { /* According to GSM TS 09.60. */ 13 18 __u8 flags; ··· 31 26 __be16 length; 32 27 __be32 tid; 33 28 } __attribute__ ((packed)); 29 + 30 + struct gtp1_header_long { /* According to 3GPP TS 29.060. */ 31 + __u8 flags; 32 + __u8 type; 33 + __be16 length; 34 + __be32 tid; 35 + __be16 seq; 36 + __u8 npdu; 37 + __u8 next; 38 + } __packed; 39 + 40 + /* GTP Information Element */ 41 + struct gtp_ie { 42 + __u8 tag; 43 + __u8 val; 44 + } __packed; 45 + 46 + struct gtp0_packet { 47 + struct gtp0_header gtp0_h; 48 + struct gtp_ie ie; 49 + } __packed; 50 + 51 + struct gtp1u_packet { 52 + struct gtp1_header_long gtp1u_h; 53 + struct gtp_ie ie; 54 + } __packed; 55 + 56 + struct gtp_pdu_session_info { /* According to 3GPP TS 38.415. */ 57 + u8 pdu_type; 58 + u8 qfi; 59 + }; 60 + 61 + static inline bool netif_is_gtp(const struct net_device *dev) 62 + { 63 + return dev->rtnl_link_ops && 64 + !strcmp(dev->rtnl_link_ops->kind, "gtp"); 65 + } 34 66 35 67 #define GTP1_F_NPDU 0x01 36 68 #define GTP1_F_SEQ 0x02
+1
include/uapi/linux/gtp.h
··· 8 8 GTP_CMD_NEWPDP, 9 9 GTP_CMD_DELPDP, 10 10 GTP_CMD_GETPDP, 11 + GTP_CMD_ECHOREQ, 11 12 12 13 GTP_CMD_MAX, 13 14 };
+2
include/uapi/linux/if_link.h
··· 887 887 IFLA_GTP_FD1, 888 888 IFLA_GTP_PDP_HASHSIZE, 889 889 IFLA_GTP_ROLE, 890 + IFLA_GTP_CREATE_SOCKETS, 891 + IFLA_GTP_RESTART_COUNT, 890 892 __IFLA_GTP_MAX, 891 893 }; 892 894 #define IFLA_GTP_MAX (__IFLA_GTP_MAX - 1)
+3 -1
include/uapi/linux/if_tunnel.h
··· 176 176 #define TUNNEL_VXLAN_OPT __cpu_to_be16(0x1000) 177 177 #define TUNNEL_NOCACHE __cpu_to_be16(0x2000) 178 178 #define TUNNEL_ERSPAN_OPT __cpu_to_be16(0x4000) 179 + #define TUNNEL_GTP_OPT __cpu_to_be16(0x8000) 179 180 180 181 #define TUNNEL_OPTIONS_PRESENT \ 181 - (TUNNEL_GENEVE_OPT | TUNNEL_VXLAN_OPT | TUNNEL_ERSPAN_OPT) 182 + (TUNNEL_GENEVE_OPT | TUNNEL_VXLAN_OPT | TUNNEL_ERSPAN_OPT | \ 183 + TUNNEL_GTP_OPT) 182 184 183 185 #endif /* _UAPI_IF_TUNNEL_H_ */
+15
include/uapi/linux/pkt_cls.h
··· 616 616 * TCA_FLOWER_KEY_ENC_OPT_ERSPAN_ 617 617 * attributes 618 618 */ 619 + TCA_FLOWER_KEY_ENC_OPTS_GTP, /* Nested 620 + * TCA_FLOWER_KEY_ENC_OPT_GTP_ 621 + * attributes 622 + */ 619 623 __TCA_FLOWER_KEY_ENC_OPTS_MAX, 620 624 }; 621 625 ··· 657 653 658 654 #define TCA_FLOWER_KEY_ENC_OPT_ERSPAN_MAX \ 659 655 (__TCA_FLOWER_KEY_ENC_OPT_ERSPAN_MAX - 1) 656 + 657 + enum { 658 + TCA_FLOWER_KEY_ENC_OPT_GTP_UNSPEC, 659 + TCA_FLOWER_KEY_ENC_OPT_GTP_PDU_TYPE, /* u8 */ 660 + TCA_FLOWER_KEY_ENC_OPT_GTP_QFI, /* u8 */ 661 + 662 + __TCA_FLOWER_KEY_ENC_OPT_GTP_MAX, 663 + }; 664 + 665 + #define TCA_FLOWER_KEY_ENC_OPT_GTP_MAX \ 666 + (__TCA_FLOWER_KEY_ENC_OPT_GTP_MAX - 1) 660 667 661 668 enum { 662 669 TCA_FLOWER_KEY_MPLS_OPTS_UNSPEC,
+116
net/sched/cls_flower.c
··· 25 25 #include <net/geneve.h> 26 26 #include <net/vxlan.h> 27 27 #include <net/erspan.h> 28 + #include <net/gtp.h> 28 29 29 30 #include <net/dst.h> 30 31 #include <net/dst_metadata.h> ··· 724 723 [TCA_FLOWER_KEY_ENC_OPTS_GENEVE] = { .type = NLA_NESTED }, 725 724 [TCA_FLOWER_KEY_ENC_OPTS_VXLAN] = { .type = NLA_NESTED }, 726 725 [TCA_FLOWER_KEY_ENC_OPTS_ERSPAN] = { .type = NLA_NESTED }, 726 + [TCA_FLOWER_KEY_ENC_OPTS_GTP] = { .type = NLA_NESTED }, 727 727 }; 728 728 729 729 static const struct nla_policy ··· 746 744 [TCA_FLOWER_KEY_ENC_OPT_ERSPAN_INDEX] = { .type = NLA_U32 }, 747 745 [TCA_FLOWER_KEY_ENC_OPT_ERSPAN_DIR] = { .type = NLA_U8 }, 748 746 [TCA_FLOWER_KEY_ENC_OPT_ERSPAN_HWID] = { .type = NLA_U8 }, 747 + }; 748 + 749 + static const struct nla_policy 750 + gtp_opt_policy[TCA_FLOWER_KEY_ENC_OPT_GTP_MAX + 1] = { 751 + [TCA_FLOWER_KEY_ENC_OPT_GTP_PDU_TYPE] = { .type = NLA_U8 }, 752 + [TCA_FLOWER_KEY_ENC_OPT_GTP_QFI] = { .type = NLA_U8 }, 749 753 }; 750 754 751 755 static const struct nla_policy ··· 1270 1262 return sizeof(*md); 1271 1263 } 1272 1264 1265 + static int fl_set_gtp_opt(const struct nlattr *nla, struct fl_flow_key *key, 1266 + int depth, int option_len, 1267 + struct netlink_ext_ack *extack) 1268 + { 1269 + struct nlattr *tb[TCA_FLOWER_KEY_ENC_OPT_GTP_MAX + 1]; 1270 + struct gtp_pdu_session_info *sinfo; 1271 + u8 len = key->enc_opts.len; 1272 + int err; 1273 + 1274 + sinfo = (struct gtp_pdu_session_info *)&key->enc_opts.data[len]; 1275 + memset(sinfo, 0xff, option_len); 1276 + 1277 + if (!depth) 1278 + return sizeof(*sinfo); 1279 + 1280 + if (nla_type(nla) != TCA_FLOWER_KEY_ENC_OPTS_GTP) { 1281 + NL_SET_ERR_MSG_MOD(extack, "Non-gtp option type for mask"); 1282 + return -EINVAL; 1283 + } 1284 + 1285 + err = nla_parse_nested(tb, TCA_FLOWER_KEY_ENC_OPT_GTP_MAX, nla, 1286 + gtp_opt_policy, extack); 1287 + if (err < 0) 1288 + return err; 1289 + 1290 + if (!option_len && 1291 + (!tb[TCA_FLOWER_KEY_ENC_OPT_GTP_PDU_TYPE] || 1292 + !tb[TCA_FLOWER_KEY_ENC_OPT_GTP_QFI])) { 1293 + NL_SET_ERR_MSG_MOD(extack, 1294 + "Missing tunnel key gtp option pdu type or qfi"); 1295 + return -EINVAL; 1296 + } 1297 + 1298 + if (tb[TCA_FLOWER_KEY_ENC_OPT_GTP_PDU_TYPE]) 1299 + sinfo->pdu_type = 1300 + nla_get_u8(tb[TCA_FLOWER_KEY_ENC_OPT_GTP_PDU_TYPE]); 1301 + 1302 + if (tb[TCA_FLOWER_KEY_ENC_OPT_GTP_QFI]) 1303 + sinfo->qfi = nla_get_u8(tb[TCA_FLOWER_KEY_ENC_OPT_GTP_QFI]); 1304 + 1305 + return sizeof(*sinfo); 1306 + } 1307 + 1273 1308 static int fl_set_enc_opt(struct nlattr **tb, struct fl_flow_key *key, 1274 1309 struct fl_flow_key *mask, 1275 1310 struct netlink_ext_ack *extack) ··· 1434 1383 mask->enc_opts.len += option_len; 1435 1384 if (key->enc_opts.len != mask->enc_opts.len) { 1436 1385 NL_SET_ERR_MSG(extack, "Key and mask miss aligned"); 1386 + return -EINVAL; 1387 + } 1388 + break; 1389 + case TCA_FLOWER_KEY_ENC_OPTS_GTP: 1390 + if (key->enc_opts.dst_opt_type) { 1391 + NL_SET_ERR_MSG_MOD(extack, 1392 + "Duplicate type for gtp options"); 1393 + return -EINVAL; 1394 + } 1395 + option_len = 0; 1396 + key->enc_opts.dst_opt_type = TUNNEL_GTP_OPT; 1397 + option_len = fl_set_gtp_opt(nla_opt_key, key, 1398 + key_depth, option_len, 1399 + extack); 1400 + if (option_len < 0) 1401 + return option_len; 1402 + 1403 + key->enc_opts.len += option_len; 1404 + /* At the same time we need to parse through the mask 1405 + * in order to verify exact and mask attribute lengths. 1406 + */ 1407 + mask->enc_opts.dst_opt_type = TUNNEL_GTP_OPT; 1408 + option_len = fl_set_gtp_opt(nla_opt_msk, mask, 1409 + msk_depth, option_len, 1410 + extack); 1411 + if (option_len < 0) 1412 + return option_len; 1413 + 1414 + mask->enc_opts.len += option_len; 1415 + if (key->enc_opts.len != mask->enc_opts.len) { 1416 + NL_SET_ERR_MSG_MOD(extack, 1417 + "Key and mask miss aligned"); 1437 1418 return -EINVAL; 1438 1419 } 1439 1420 break; ··· 2844 2761 return -EMSGSIZE; 2845 2762 } 2846 2763 2764 + static int fl_dump_key_gtp_opt(struct sk_buff *skb, 2765 + struct flow_dissector_key_enc_opts *enc_opts) 2766 + 2767 + { 2768 + struct gtp_pdu_session_info *session_info; 2769 + struct nlattr *nest; 2770 + 2771 + nest = nla_nest_start_noflag(skb, TCA_FLOWER_KEY_ENC_OPTS_GTP); 2772 + if (!nest) 2773 + goto nla_put_failure; 2774 + 2775 + session_info = (struct gtp_pdu_session_info *)&enc_opts->data[0]; 2776 + 2777 + if (nla_put_u8(skb, TCA_FLOWER_KEY_ENC_OPT_GTP_PDU_TYPE, 2778 + session_info->pdu_type)) 2779 + goto nla_put_failure; 2780 + 2781 + if (nla_put_u8(skb, TCA_FLOWER_KEY_ENC_OPT_GTP_QFI, session_info->qfi)) 2782 + goto nla_put_failure; 2783 + 2784 + nla_nest_end(skb, nest); 2785 + return 0; 2786 + 2787 + nla_put_failure: 2788 + nla_nest_cancel(skb, nest); 2789 + return -EMSGSIZE; 2790 + } 2791 + 2847 2792 static int fl_dump_key_ct(struct sk_buff *skb, 2848 2793 struct flow_dissector_key_ct *key, 2849 2794 struct flow_dissector_key_ct *mask) ··· 2932 2821 break; 2933 2822 case TUNNEL_ERSPAN_OPT: 2934 2823 err = fl_dump_key_erspan_opt(skb, enc_opts); 2824 + if (err) 2825 + goto nla_put_failure; 2826 + break; 2827 + case TUNNEL_GTP_OPT: 2828 + err = fl_dump_key_gtp_opt(skb, enc_opts); 2935 2829 if (err) 2936 2830 goto nla_put_failure; 2937 2831 break;