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: PPPoE offload support

Marcin Szycik says:

Add support for dissecting PPPoE and PPP-specific fields in flow dissector:
PPPoE session id and PPP protocol type. Add support for those fields in
tc-flower and support offloading PPPoE. Finally, add support for hardware
offload of PPPoE packets in switchdev mode in ice driver.

Example filter:
tc filter add dev $PF1 ingress protocol ppp_ses prio 1 flower pppoe_sid \
1234 ppp_proto ip skip_sw action mirred egress redirect dev $VF1_PR

Changes in iproute2 are required to use the new fields (will be submitted
soon).

ICE COMMS DDP package is required to create a filter in ice.

* '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue:
ice: Add support for PPPoE hardware offload
flow_offload: Introduce flow_match_pppoe
net/sched: flower: Add PPPoE filter
flow_dissector: Add PPPoE dissectors
====================

Link: https://lore.kernel.org/r/20220726203133.2171332-1-anthony.l.nguyen@intel.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

+416 -13
+1
drivers/net/ethernet/intel/ice/ice.h
··· 52 52 #include <net/udp_tunnel.h> 53 53 #include <net/vxlan.h> 54 54 #include <net/gtp.h> 55 + #include <linux/ppp_defs.h> 55 56 #include "ice_devids.h" 56 57 #include "ice_type.h" 57 58 #include "ice_txrx.h"
+4 -1
drivers/net/ethernet/intel/ice/ice_flex_pipe.c
··· 1964 1964 } 1965 1965 } 1966 1966 } while (fv); 1967 - if (list_empty(fv_list)) 1967 + if (list_empty(fv_list)) { 1968 + dev_warn(ice_hw_to_dev(hw), "Required profiles not found in currently loaded DDP package"); 1968 1969 return -EIO; 1970 + } 1971 + 1969 1972 return 0; 1970 1973 1971 1974 err:
+11
drivers/net/ethernet/intel/ice/ice_protocol_type.h
··· 43 43 ICE_NVGRE, 44 44 ICE_GTP, 45 45 ICE_GTP_NO_PAY, 46 + ICE_PPPOE, 46 47 ICE_VLAN_EX, 47 48 ICE_VLAN_IN, 48 49 ICE_VXLAN_GPE, ··· 110 109 #define ICE_TCP_IL_HW 49 111 110 #define ICE_UDP_ILOS_HW 53 112 111 #define ICE_GRE_OF_HW 64 112 + #define ICE_PPPOE_HW 103 113 113 114 114 #define ICE_UDP_OF_HW 52 /* UDP Tunnels */ 115 115 #define ICE_META_DATA_ID_HW 255 /* this is used for tunnel and VLAN type */ ··· 209 207 u8 rsvrd; 210 208 }; 211 209 210 + struct ice_pppoe_hdr { 211 + u8 rsrvd_ver_type; 212 + u8 rsrvd_code; 213 + __be16 session_id; 214 + __be16 length; 215 + __be16 ppp_prot_id; /* control and data only */ 216 + }; 217 + 212 218 struct ice_nvgre_hdr { 213 219 __be16 flags; 214 220 __be16 protocol; ··· 234 224 struct ice_udp_tnl_hdr tnl_hdr; 235 225 struct ice_nvgre_hdr nvgre_hdr; 236 226 struct ice_udp_gtp_hdr gtp_hdr; 227 + struct ice_pppoe_hdr pppoe_hdr; 237 228 }; 238 229 239 230 /* This is mapping table entry that maps every word within a given protocol
+165
drivers/net/ethernet/intel/ice/ice_switch.c
··· 41 41 ICE_PKT_INNER_UDP = BIT(7), 42 42 ICE_PKT_GTP_NOPAY = BIT(8), 43 43 ICE_PKT_KMALLOC = BIT(9), 44 + ICE_PKT_PPPOE = BIT(10), 44 45 }; 45 46 46 47 struct ice_dummy_pkt_offsets { ··· 1110 1109 0x00, 0x00, 1111 1110 }; 1112 1111 1112 + ICE_DECLARE_PKT_OFFSETS(pppoe_ipv4_tcp) = { 1113 + { ICE_MAC_OFOS, 0 }, 1114 + { ICE_ETYPE_OL, 12 }, 1115 + { ICE_PPPOE, 14 }, 1116 + { ICE_IPV4_OFOS, 22 }, 1117 + { ICE_TCP_IL, 42 }, 1118 + { ICE_PROTOCOL_LAST, 0 }, 1119 + }; 1120 + 1121 + ICE_DECLARE_PKT_TEMPLATE(pppoe_ipv4_tcp) = { 1122 + 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 1123 + 0x00, 0x00, 0x00, 0x00, 1124 + 0x00, 0x00, 0x00, 0x00, 1125 + 1126 + 0x88, 0x64, /* ICE_ETYPE_OL 12 */ 1127 + 1128 + 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 14 */ 1129 + 0x00, 0x16, 1130 + 1131 + 0x00, 0x21, /* PPP Link Layer 20 */ 1132 + 1133 + 0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_OFOS 22 */ 1134 + 0x00, 0x01, 0x00, 0x00, 1135 + 0x00, 0x06, 0x00, 0x00, 1136 + 0x00, 0x00, 0x00, 0x00, 1137 + 0x00, 0x00, 0x00, 0x00, 1138 + 1139 + 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 42 */ 1140 + 0x00, 0x00, 0x00, 0x00, 1141 + 0x00, 0x00, 0x00, 0x00, 1142 + 0x50, 0x00, 0x00, 0x00, 1143 + 0x00, 0x00, 0x00, 0x00, 1144 + 1145 + 0x00, 0x00, /* 2 bytes for 4 bytes alignment */ 1146 + }; 1147 + 1148 + ICE_DECLARE_PKT_OFFSETS(pppoe_ipv4_udp) = { 1149 + { ICE_MAC_OFOS, 0 }, 1150 + { ICE_ETYPE_OL, 12 }, 1151 + { ICE_PPPOE, 14 }, 1152 + { ICE_IPV4_OFOS, 22 }, 1153 + { ICE_UDP_ILOS, 42 }, 1154 + { ICE_PROTOCOL_LAST, 0 }, 1155 + }; 1156 + 1157 + ICE_DECLARE_PKT_TEMPLATE(pppoe_ipv4_udp) = { 1158 + 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 1159 + 0x00, 0x00, 0x00, 0x00, 1160 + 0x00, 0x00, 0x00, 0x00, 1161 + 1162 + 0x88, 0x64, /* ICE_ETYPE_OL 12 */ 1163 + 1164 + 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 14 */ 1165 + 0x00, 0x16, 1166 + 1167 + 0x00, 0x21, /* PPP Link Layer 20 */ 1168 + 1169 + 0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_OFOS 22 */ 1170 + 0x00, 0x01, 0x00, 0x00, 1171 + 0x00, 0x11, 0x00, 0x00, 1172 + 0x00, 0x00, 0x00, 0x00, 1173 + 0x00, 0x00, 0x00, 0x00, 1174 + 1175 + 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 42 */ 1176 + 0x00, 0x08, 0x00, 0x00, 1177 + 1178 + 0x00, 0x00, /* 2 bytes for 4 bytes alignment */ 1179 + }; 1180 + 1181 + ICE_DECLARE_PKT_OFFSETS(pppoe_ipv6_tcp) = { 1182 + { ICE_MAC_OFOS, 0 }, 1183 + { ICE_ETYPE_OL, 12 }, 1184 + { ICE_PPPOE, 14 }, 1185 + { ICE_IPV6_OFOS, 22 }, 1186 + { ICE_TCP_IL, 62 }, 1187 + { ICE_PROTOCOL_LAST, 0 }, 1188 + }; 1189 + 1190 + ICE_DECLARE_PKT_TEMPLATE(pppoe_ipv6_tcp) = { 1191 + 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 1192 + 0x00, 0x00, 0x00, 0x00, 1193 + 0x00, 0x00, 0x00, 0x00, 1194 + 1195 + 0x88, 0x64, /* ICE_ETYPE_OL 12 */ 1196 + 1197 + 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 14 */ 1198 + 0x00, 0x2a, 1199 + 1200 + 0x00, 0x57, /* PPP Link Layer 20 */ 1201 + 1202 + 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 22 */ 1203 + 0x00, 0x14, 0x06, 0x00, /* Next header is TCP */ 1204 + 0x00, 0x00, 0x00, 0x00, 1205 + 0x00, 0x00, 0x00, 0x00, 1206 + 0x00, 0x00, 0x00, 0x00, 1207 + 0x00, 0x00, 0x00, 0x00, 1208 + 0x00, 0x00, 0x00, 0x00, 1209 + 0x00, 0x00, 0x00, 0x00, 1210 + 0x00, 0x00, 0x00, 0x00, 1211 + 0x00, 0x00, 0x00, 0x00, 1212 + 1213 + 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 62 */ 1214 + 0x00, 0x00, 0x00, 0x00, 1215 + 0x00, 0x00, 0x00, 0x00, 1216 + 0x50, 0x00, 0x00, 0x00, 1217 + 0x00, 0x00, 0x00, 0x00, 1218 + 1219 + 0x00, 0x00, /* 2 bytes for 4 bytes alignment */ 1220 + }; 1221 + 1222 + ICE_DECLARE_PKT_OFFSETS(pppoe_ipv6_udp) = { 1223 + { ICE_MAC_OFOS, 0 }, 1224 + { ICE_ETYPE_OL, 12 }, 1225 + { ICE_PPPOE, 14 }, 1226 + { ICE_IPV6_OFOS, 22 }, 1227 + { ICE_UDP_ILOS, 62 }, 1228 + { ICE_PROTOCOL_LAST, 0 }, 1229 + }; 1230 + 1231 + ICE_DECLARE_PKT_TEMPLATE(pppoe_ipv6_udp) = { 1232 + 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 1233 + 0x00, 0x00, 0x00, 0x00, 1234 + 0x00, 0x00, 0x00, 0x00, 1235 + 1236 + 0x88, 0x64, /* ICE_ETYPE_OL 12 */ 1237 + 1238 + 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 14 */ 1239 + 0x00, 0x2a, 1240 + 1241 + 0x00, 0x57, /* PPP Link Layer 20 */ 1242 + 1243 + 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 22 */ 1244 + 0x00, 0x08, 0x11, 0x00, /* Next header UDP*/ 1245 + 0x00, 0x00, 0x00, 0x00, 1246 + 0x00, 0x00, 0x00, 0x00, 1247 + 0x00, 0x00, 0x00, 0x00, 1248 + 0x00, 0x00, 0x00, 0x00, 1249 + 0x00, 0x00, 0x00, 0x00, 1250 + 0x00, 0x00, 0x00, 0x00, 1251 + 0x00, 0x00, 0x00, 0x00, 1252 + 0x00, 0x00, 0x00, 0x00, 1253 + 1254 + 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 62 */ 1255 + 0x00, 0x08, 0x00, 0x00, 1256 + 1257 + 0x00, 0x00, /* 2 bytes for 4 bytes alignment */ 1258 + }; 1259 + 1113 1260 static const struct ice_dummy_pkt_profile ice_dummy_pkt_profiles[] = { 1114 1261 ICE_PKT_PROFILE(ipv6_gtp, ICE_PKT_TUN_GTPU | ICE_PKT_OUTER_IPV6 | 1115 1262 ICE_PKT_GTP_NOPAY), ··· 1284 1135 ICE_PKT_PROFILE(ipv4_gtpu_ipv4_tcp, ICE_PKT_TUN_GTPU), 1285 1136 ICE_PKT_PROFILE(ipv6_gtp, ICE_PKT_TUN_GTPC | ICE_PKT_OUTER_IPV6), 1286 1137 ICE_PKT_PROFILE(ipv4_gtpu_ipv4, ICE_PKT_TUN_GTPC), 1138 + ICE_PKT_PROFILE(pppoe_ipv6_udp, ICE_PKT_PPPOE | ICE_PKT_OUTER_IPV6 | 1139 + ICE_PKT_INNER_UDP), 1140 + ICE_PKT_PROFILE(pppoe_ipv6_tcp, ICE_PKT_PPPOE | ICE_PKT_OUTER_IPV6), 1141 + ICE_PKT_PROFILE(pppoe_ipv4_udp, ICE_PKT_PPPOE | ICE_PKT_INNER_UDP), 1142 + ICE_PKT_PROFILE(pppoe_ipv4_tcp, ICE_PKT_PPPOE), 1287 1143 ICE_PKT_PROFILE(gre_ipv6_tcp, ICE_PKT_TUN_NVGRE | ICE_PKT_INNER_IPV6 | 1288 1144 ICE_PKT_INNER_TCP), 1289 1145 ICE_PKT_PROFILE(gre_tcp, ICE_PKT_TUN_NVGRE | ICE_PKT_INNER_TCP), ··· 4634 4480 { ICE_NVGRE, { 0, 2, 4, 6 } }, 4635 4481 { ICE_GTP, { 8, 10, 12, 14, 16, 18, 20, 22 } }, 4636 4482 { ICE_GTP_NO_PAY, { 8, 10, 12, 14 } }, 4483 + { ICE_PPPOE, { 0, 2, 4, 6 } }, 4637 4484 { ICE_VLAN_EX, { 2, 0 } }, 4638 4485 { ICE_VLAN_IN, { 2, 0 } }, 4639 4486 }; ··· 4657 4502 { ICE_NVGRE, ICE_GRE_OF_HW }, 4658 4503 { ICE_GTP, ICE_UDP_OF_HW }, 4659 4504 { ICE_GTP_NO_PAY, ICE_UDP_ILOS_HW }, 4505 + { ICE_PPPOE, ICE_PPPOE_HW }, 4660 4506 { ICE_VLAN_EX, ICE_VLAN_OF_HW }, 4661 4507 { ICE_VLAN_IN, ICE_VLAN_OL_HW }, 4662 4508 }; ··· 5736 5580 match |= ICE_PKT_INNER_IPV6; 5737 5581 else if (lkups[i].type == ICE_GTP_NO_PAY) 5738 5582 match |= ICE_PKT_GTP_NOPAY; 5583 + else if (lkups[i].type == ICE_PPPOE) { 5584 + match |= ICE_PKT_PPPOE; 5585 + if (lkups[i].h_u.pppoe_hdr.ppp_prot_id == 5586 + htons(PPP_IPV6)) 5587 + match |= ICE_PKT_OUTER_IPV6; 5588 + } 5739 5589 } 5740 5590 5741 5591 while (ret->match && (match & ret->match) != ret->match) ··· 5838 5676 case ICE_GTP_NO_PAY: 5839 5677 case ICE_GTP: 5840 5678 len = sizeof(struct ice_udp_gtp_hdr); 5679 + break; 5680 + case ICE_PPPOE: 5681 + len = sizeof(struct ice_pppoe_hdr); 5841 5682 break; 5842 5683 default: 5843 5684 return -EINVAL;
+70 -1
drivers/net/ethernet/intel/ice/ice_tc_lib.c
··· 54 54 if (flags & ICE_TC_FLWR_FIELD_CVLAN) 55 55 lkups_cnt++; 56 56 57 + /* are PPPoE options specified? */ 58 + if (flags & (ICE_TC_FLWR_FIELD_PPPOE_SESSID | 59 + ICE_TC_FLWR_FIELD_PPP_PROTO)) 60 + lkups_cnt++; 61 + 57 62 /* are IPv[4|6] fields specified? */ 58 63 if (flags & (ICE_TC_FLWR_FIELD_DEST_IPV4 | ICE_TC_FLWR_FIELD_SRC_IPV4 | 59 64 ICE_TC_FLWR_FIELD_DEST_IPV6 | ICE_TC_FLWR_FIELD_SRC_IPV6)) ··· 352 347 list[i].type = ICE_VLAN_IN; 353 348 list[i].h_u.vlan_hdr.vlan = headers->cvlan_hdr.vlan_id; 354 349 list[i].m_u.vlan_hdr.vlan = cpu_to_be16(0xFFFF); 350 + i++; 351 + } 352 + 353 + if (flags & (ICE_TC_FLWR_FIELD_PPPOE_SESSID | 354 + ICE_TC_FLWR_FIELD_PPP_PROTO)) { 355 + struct ice_pppoe_hdr *vals, *masks; 356 + 357 + vals = &list[i].h_u.pppoe_hdr; 358 + masks = &list[i].m_u.pppoe_hdr; 359 + 360 + list[i].type = ICE_PPPOE; 361 + 362 + if (flags & ICE_TC_FLWR_FIELD_PPPOE_SESSID) { 363 + vals->session_id = headers->pppoe_hdr.session_id; 364 + masks->session_id = cpu_to_be16(0xFFFF); 365 + } 366 + 367 + if (flags & ICE_TC_FLWR_FIELD_PPP_PROTO) { 368 + vals->ppp_prot_id = headers->pppoe_hdr.ppp_proto; 369 + masks->ppp_prot_id = cpu_to_be16(0xFFFF); 370 + } 371 + 355 372 i++; 356 373 } 357 374 ··· 721 694 } 722 695 723 696 /** 697 + * ice_tc_set_pppoe - Parse PPPoE fields from TC flower filter 698 + * @match: Pointer to flow match structure 699 + * @fltr: Pointer to filter structure 700 + * @headers: Pointer to outer header fields 701 + * @returns PPP protocol used in filter (ppp_ses or ppp_disc) 702 + */ 703 + static u16 704 + ice_tc_set_pppoe(struct flow_match_pppoe *match, 705 + struct ice_tc_flower_fltr *fltr, 706 + struct ice_tc_flower_lyr_2_4_hdrs *headers) 707 + { 708 + if (match->mask->session_id) { 709 + fltr->flags |= ICE_TC_FLWR_FIELD_PPPOE_SESSID; 710 + headers->pppoe_hdr.session_id = match->key->session_id; 711 + } 712 + 713 + if (match->mask->ppp_proto) { 714 + fltr->flags |= ICE_TC_FLWR_FIELD_PPP_PROTO; 715 + headers->pppoe_hdr.ppp_proto = match->key->ppp_proto; 716 + } 717 + 718 + return be16_to_cpu(match->key->type); 719 + } 720 + 721 + /** 724 722 * ice_tc_set_ipv4 - Parse IPv4 addresses from TC flower filter 725 723 * @match: Pointer to flow match structure 726 724 * @fltr: Pointer to filter structure ··· 1040 988 BIT(FLOW_DISSECTOR_KEY_ENC_PORTS) | 1041 989 BIT(FLOW_DISSECTOR_KEY_ENC_OPTS) | 1042 990 BIT(FLOW_DISSECTOR_KEY_ENC_IP) | 1043 - BIT(FLOW_DISSECTOR_KEY_PORTS))) { 991 + BIT(FLOW_DISSECTOR_KEY_PORTS) | 992 + BIT(FLOW_DISSECTOR_KEY_PPPOE))) { 1044 993 NL_SET_ERR_MSG_MOD(fltr->extack, "Unsupported key used"); 1045 994 return -EOPNOTSUPP; 1046 995 } ··· 1175 1122 cpu_to_be16(match.key->vlan_id & VLAN_VID_MASK); 1176 1123 if (match.mask->vlan_priority) 1177 1124 headers->cvlan_hdr.vlan_prio = match.key->vlan_priority; 1125 + } 1126 + 1127 + if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_PPPOE)) { 1128 + struct flow_match_pppoe match; 1129 + 1130 + flow_rule_match_pppoe(rule, &match); 1131 + n_proto_key = ice_tc_set_pppoe(&match, fltr, headers); 1132 + 1133 + /* If ethertype equals ETH_P_PPP_SES, n_proto might be 1134 + * overwritten by encapsulated protocol (ppp_proto field) or set 1135 + * to 0. To correct this, flow_match_pppoe provides the type 1136 + * field, which contains the actual ethertype (ETH_P_PPP_SES). 1137 + */ 1138 + headers->l2_key.n_proto = cpu_to_be16(n_proto_key); 1139 + headers->l2_mask.n_proto = cpu_to_be16(0xFFFF); 1140 + fltr->flags |= ICE_TC_FLWR_FIELD_ETH_TYPE_ID; 1178 1141 } 1179 1142 1180 1143 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CONTROL)) {
+8
drivers/net/ethernet/intel/ice/ice_tc_lib.h
··· 24 24 #define ICE_TC_FLWR_FIELD_ETH_TYPE_ID BIT(17) 25 25 #define ICE_TC_FLWR_FIELD_ENC_OPTS BIT(18) 26 26 #define ICE_TC_FLWR_FIELD_CVLAN BIT(19) 27 + #define ICE_TC_FLWR_FIELD_PPPOE_SESSID BIT(20) 28 + #define ICE_TC_FLWR_FIELD_PPP_PROTO BIT(21) 27 29 28 30 #define ICE_TC_FLOWER_MASK_32 0xFFFFFFFF 29 31 ··· 44 42 __be16 vlan_id; /* Only last 12 bits valid */ 45 43 u16 vlan_prio; /* Only last 3 bits valid (valid values: 0..7) */ 46 44 __be16 vlan_tpid; 45 + }; 46 + 47 + struct ice_tc_pppoe_hdr { 48 + __be16 session_id; 49 + __be16 ppp_proto; 47 50 }; 48 51 49 52 struct ice_tc_l2_hdr { ··· 91 84 struct ice_tc_l2_hdr l2_mask; 92 85 struct ice_tc_vlan_hdr vlan_hdr; 93 86 struct ice_tc_vlan_hdr cvlan_hdr; 87 + struct ice_tc_pppoe_hdr pppoe_hdr; 94 88 /* L3 (IPv4[6]) layer fields with their mask */ 95 89 struct ice_tc_l3_hdr l3_key; 96 90 struct ice_tc_l3_hdr l3_mask;
+14
include/linux/ppp_defs.h
··· 11 11 #include <uapi/linux/ppp_defs.h> 12 12 13 13 #define PPP_FCS(fcs, c) crc_ccitt_byte(fcs, c) 14 + 15 + /** 16 + * ppp_proto_is_valid - checks if PPP protocol is valid 17 + * @proto: PPP protocol 18 + * 19 + * Assumes proto is not compressed. 20 + * Protocol is valid if the value is odd and the least significant bit of the 21 + * most significant octet is 0 (see RFC 1661, section 2). 22 + */ 23 + static inline bool ppp_proto_is_valid(u16 proto) 24 + { 25 + return !!((proto & 0x0101) == 0x0001); 26 + } 27 + 14 28 #endif /* _PPP_DEFS_H_ */
+13
include/net/flow_dissector.h
··· 277 277 u8 num_of_vlans; 278 278 }; 279 279 280 + /** 281 + * struct flow_dissector_key_pppoe: 282 + * @session_id: pppoe session id 283 + * @ppp_proto: ppp protocol 284 + * @type: pppoe eth type 285 + */ 286 + struct flow_dissector_key_pppoe { 287 + __be16 session_id; 288 + __be16 ppp_proto; 289 + __be16 type; 290 + }; 291 + 280 292 enum flow_dissector_key_id { 281 293 FLOW_DISSECTOR_KEY_CONTROL, /* struct flow_dissector_key_control */ 282 294 FLOW_DISSECTOR_KEY_BASIC, /* struct flow_dissector_key_basic */ ··· 319 307 FLOW_DISSECTOR_KEY_CT, /* struct flow_dissector_key_ct */ 320 308 FLOW_DISSECTOR_KEY_HASH, /* struct flow_dissector_key_hash */ 321 309 FLOW_DISSECTOR_KEY_NUM_OF_VLANS, /* struct flow_dissector_key_num_of_vlans */ 310 + FLOW_DISSECTOR_KEY_PPPOE, /* struct flow_dissector_key_pppoe */ 322 311 323 312 FLOW_DISSECTOR_KEY_MAX, 324 313 };
+6
include/net/flow_offload.h
··· 76 76 struct flow_dissector_key_ct *key, *mask; 77 77 }; 78 78 79 + struct flow_match_pppoe { 80 + struct flow_dissector_key_pppoe *key, *mask; 81 + }; 82 + 79 83 struct flow_rule; 80 84 81 85 void flow_rule_match_meta(const struct flow_rule *rule, ··· 126 122 struct flow_match_enc_opts *out); 127 123 void flow_rule_match_ct(const struct flow_rule *rule, 128 124 struct flow_match_ct *out); 125 + void flow_rule_match_pppoe(const struct flow_rule *rule, 126 + struct flow_match_pppoe *out); 129 127 130 128 enum flow_action_id { 131 129 FLOW_ACTION_ACCEPT = 0,
+3
include/uapi/linux/pkt_cls.h
··· 589 589 590 590 TCA_FLOWER_KEY_NUM_OF_VLANS, /* u8 */ 591 591 592 + TCA_FLOWER_KEY_PPPOE_SID, /* be16 */ 593 + TCA_FLOWER_KEY_PPP_PROTO, /* be16 */ 594 + 592 595 __TCA_FLOWER_MAX, 593 596 }; 594 597
+50 -11
net/core/flow_dissector.c
··· 895 895 return result == BPF_OK; 896 896 } 897 897 898 + static bool is_pppoe_ses_hdr_valid(struct pppoe_hdr hdr) 899 + { 900 + return hdr.ver == 1 && hdr.type == 1 && hdr.code == 0; 901 + } 902 + 898 903 /** 899 904 * __skb_flow_dissect - extract the flow_keys struct and return it 900 905 * @net: associated network namespace, derived from @skb if NULL ··· 1219 1214 struct pppoe_hdr hdr; 1220 1215 __be16 proto; 1221 1216 } *hdr, _hdr; 1217 + u16 ppp_proto; 1218 + 1222 1219 hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data, hlen, &_hdr); 1223 1220 if (!hdr) { 1224 1221 fdret = FLOW_DISSECT_RET_OUT_BAD; 1225 1222 break; 1226 1223 } 1227 1224 1228 - nhoff += PPPOE_SES_HLEN; 1229 - switch (hdr->proto) { 1230 - case htons(PPP_IP): 1231 - proto = htons(ETH_P_IP); 1232 - fdret = FLOW_DISSECT_RET_PROTO_AGAIN; 1233 - break; 1234 - case htons(PPP_IPV6): 1235 - proto = htons(ETH_P_IPV6); 1236 - fdret = FLOW_DISSECT_RET_PROTO_AGAIN; 1237 - break; 1238 - default: 1225 + if (!is_pppoe_ses_hdr_valid(hdr->hdr)) { 1239 1226 fdret = FLOW_DISSECT_RET_OUT_BAD; 1240 1227 break; 1228 + } 1229 + 1230 + /* least significant bit of the most significant octet 1231 + * indicates if protocol field was compressed 1232 + */ 1233 + ppp_proto = ntohs(hdr->proto); 1234 + if (ppp_proto & 0x0100) { 1235 + ppp_proto = ppp_proto >> 8; 1236 + nhoff += PPPOE_SES_HLEN - 1; 1237 + } else { 1238 + nhoff += PPPOE_SES_HLEN; 1239 + } 1240 + 1241 + if (ppp_proto == PPP_IP) { 1242 + proto = htons(ETH_P_IP); 1243 + fdret = FLOW_DISSECT_RET_PROTO_AGAIN; 1244 + } else if (ppp_proto == PPP_IPV6) { 1245 + proto = htons(ETH_P_IPV6); 1246 + fdret = FLOW_DISSECT_RET_PROTO_AGAIN; 1247 + } else if (ppp_proto == PPP_MPLS_UC) { 1248 + proto = htons(ETH_P_MPLS_UC); 1249 + fdret = FLOW_DISSECT_RET_PROTO_AGAIN; 1250 + } else if (ppp_proto == PPP_MPLS_MC) { 1251 + proto = htons(ETH_P_MPLS_MC); 1252 + fdret = FLOW_DISSECT_RET_PROTO_AGAIN; 1253 + } else if (ppp_proto_is_valid(ppp_proto)) { 1254 + fdret = FLOW_DISSECT_RET_OUT_GOOD; 1255 + } else { 1256 + fdret = FLOW_DISSECT_RET_OUT_BAD; 1257 + break; 1258 + } 1259 + 1260 + if (dissector_uses_key(flow_dissector, 1261 + FLOW_DISSECTOR_KEY_PPPOE)) { 1262 + struct flow_dissector_key_pppoe *key_pppoe; 1263 + 1264 + key_pppoe = skb_flow_dissector_target(flow_dissector, 1265 + FLOW_DISSECTOR_KEY_PPPOE, 1266 + target_container); 1267 + key_pppoe->session_id = hdr->hdr.sid; 1268 + key_pppoe->ppp_proto = htons(ppp_proto); 1269 + key_pppoe->type = htons(ETH_P_PPP_SES); 1241 1270 } 1242 1271 break; 1243 1272 }
+7
net/core/flow_offload.c
··· 230 230 } 231 231 EXPORT_SYMBOL(flow_rule_match_ct); 232 232 233 + void flow_rule_match_pppoe(const struct flow_rule *rule, 234 + struct flow_match_pppoe *out) 235 + { 236 + FLOW_DISSECTOR_MATCH(rule, FLOW_DISSECTOR_KEY_PPPOE, out); 237 + } 238 + EXPORT_SYMBOL(flow_rule_match_pppoe); 239 + 233 240 struct flow_block_cb *flow_block_cb_alloc(flow_setup_cb_t *cb, 234 241 void *cb_ident, void *cb_priv, 235 242 void (*release)(void *cb_priv))
+64
net/sched/cls_flower.c
··· 16 16 #include <linux/in6.h> 17 17 #include <linux/ip.h> 18 18 #include <linux/mpls.h> 19 + #include <linux/ppp_defs.h> 19 20 20 21 #include <net/sch_generic.h> 21 22 #include <net/pkt_cls.h> ··· 68 67 struct flow_dissector_key_ct ct; 69 68 struct flow_dissector_key_hash hash; 70 69 struct flow_dissector_key_num_of_vlans num_of_vlans; 70 + struct flow_dissector_key_pppoe pppoe; 71 71 } __aligned(BITS_PER_LONG / 8); /* Ensure that we can do comparisons as longs. */ 72 72 73 73 struct fl_flow_mask_range { ··· 710 708 [TCA_FLOWER_KEY_HASH] = { .type = NLA_U32 }, 711 709 [TCA_FLOWER_KEY_HASH_MASK] = { .type = NLA_U32 }, 712 710 [TCA_FLOWER_KEY_NUM_OF_VLANS] = { .type = NLA_U8 }, 711 + [TCA_FLOWER_KEY_PPPOE_SID] = { .type = NLA_U16 }, 712 + [TCA_FLOWER_KEY_PPP_PROTO] = { .type = NLA_U16 }, 713 713 714 714 }; 715 715 ··· 1036 1032 key_val->vlan_eth_type = 1037 1033 nla_get_be16(tb[vlan_next_eth_type_key]); 1038 1034 key_mask->vlan_eth_type = cpu_to_be16(~0); 1035 + } 1036 + } 1037 + 1038 + static void fl_set_key_pppoe(struct nlattr **tb, 1039 + struct flow_dissector_key_pppoe *key_val, 1040 + struct flow_dissector_key_pppoe *key_mask, 1041 + struct fl_flow_key *key, 1042 + struct fl_flow_key *mask) 1043 + { 1044 + /* key_val::type must be set to ETH_P_PPP_SES 1045 + * because ETH_P_PPP_SES was stored in basic.n_proto 1046 + * which might get overwritten by ppp_proto 1047 + * or might be set to 0, the role of key_val::type 1048 + * is simmilar to vlan_key::tpid 1049 + */ 1050 + key_val->type = htons(ETH_P_PPP_SES); 1051 + key_mask->type = cpu_to_be16(~0); 1052 + 1053 + if (tb[TCA_FLOWER_KEY_PPPOE_SID]) { 1054 + key_val->session_id = 1055 + nla_get_be16(tb[TCA_FLOWER_KEY_PPPOE_SID]); 1056 + key_mask->session_id = cpu_to_be16(~0); 1057 + } 1058 + if (tb[TCA_FLOWER_KEY_PPP_PROTO]) { 1059 + key_val->ppp_proto = 1060 + nla_get_be16(tb[TCA_FLOWER_KEY_PPP_PROTO]); 1061 + key_mask->ppp_proto = cpu_to_be16(~0); 1062 + 1063 + if (key_val->ppp_proto == htons(PPP_IP)) { 1064 + key->basic.n_proto = htons(ETH_P_IP); 1065 + mask->basic.n_proto = cpu_to_be16(~0); 1066 + } else if (key_val->ppp_proto == htons(PPP_IPV6)) { 1067 + key->basic.n_proto = htons(ETH_P_IPV6); 1068 + mask->basic.n_proto = cpu_to_be16(~0); 1069 + } else if (key_val->ppp_proto == htons(PPP_MPLS_UC)) { 1070 + key->basic.n_proto = htons(ETH_P_MPLS_UC); 1071 + mask->basic.n_proto = cpu_to_be16(~0); 1072 + } else if (key_val->ppp_proto == htons(PPP_MPLS_MC)) { 1073 + key->basic.n_proto = htons(ETH_P_MPLS_MC); 1074 + mask->basic.n_proto = cpu_to_be16(~0); 1075 + } 1076 + } else { 1077 + key->basic.n_proto = 0; 1078 + mask->basic.n_proto = cpu_to_be16(0); 1039 1079 } 1040 1080 } 1041 1081 ··· 1693 1645 } 1694 1646 } 1695 1647 1648 + if (key->basic.n_proto == htons(ETH_P_PPP_SES)) 1649 + fl_set_key_pppoe(tb, &key->pppoe, &mask->pppoe, key, mask); 1650 + 1696 1651 if (key->basic.n_proto == htons(ETH_P_IP) || 1697 1652 key->basic.n_proto == htons(ETH_P_IPV6)) { 1698 1653 fl_set_key_val(tb, &key->basic.ip_proto, TCA_FLOWER_KEY_IP_PROTO, ··· 1968 1917 FLOW_DISSECTOR_KEY_HASH, hash); 1969 1918 FL_KEY_SET_IF_MASKED(mask, keys, cnt, 1970 1919 FLOW_DISSECTOR_KEY_NUM_OF_VLANS, num_of_vlans); 1920 + FL_KEY_SET_IF_MASKED(mask, keys, cnt, 1921 + FLOW_DISSECTOR_KEY_PPPOE, pppoe); 1971 1922 1972 1923 skb_flow_dissector_init(dissector, keys, cnt); 1973 1924 } ··· 3097 3044 sizeof(key->basic.ip_proto)) || 3098 3045 fl_dump_key_ip(skb, false, &key->ip, &mask->ip))) 3099 3046 goto nla_put_failure; 3047 + 3048 + if (mask->pppoe.session_id) { 3049 + if (nla_put_be16(skb, TCA_FLOWER_KEY_PPPOE_SID, 3050 + key->pppoe.session_id)) 3051 + goto nla_put_failure; 3052 + } 3053 + if (mask->basic.n_proto && mask->pppoe.ppp_proto) { 3054 + if (nla_put_be16(skb, TCA_FLOWER_KEY_PPP_PROTO, 3055 + key->pppoe.ppp_proto)) 3056 + goto nla_put_failure; 3057 + } 3100 3058 3101 3059 if (key->control.addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS && 3102 3060 (fl_dump_key_val(skb, &key->ipv4.src, TCA_FLOWER_KEY_IPV4_SRC,