@@ -1130,28 +1130,50 @@ static int bnxt_grxclsrule(struct bnxt *bp, struct ethtool_rxnfc *cmd)
11301130 fkeys = & fltr -> fkeys ;
11311131 fmasks = & fltr -> fmasks ;
11321132 if (fkeys -> basic .n_proto == htons (ETH_P_IP )) {
1133- if (fkeys -> basic .ip_proto == IPPROTO_TCP )
1133+ if (fkeys -> basic .ip_proto == IPPROTO_ICMP ||
1134+ fkeys -> basic .ip_proto == IPPROTO_RAW ) {
1135+ fs -> flow_type = IP_USER_FLOW ;
1136+ fs -> h_u .usr_ip4_spec .ip_ver = ETH_RX_NFC_IP4 ;
1137+ if (fkeys -> basic .ip_proto == IPPROTO_ICMP )
1138+ fs -> h_u .usr_ip4_spec .proto = IPPROTO_ICMP ;
1139+ else
1140+ fs -> h_u .usr_ip4_spec .proto = IPPROTO_RAW ;
1141+ fs -> m_u .usr_ip4_spec .proto = BNXT_IP_PROTO_FULL_MASK ;
1142+ } else if (fkeys -> basic .ip_proto == IPPROTO_TCP ) {
11341143 fs -> flow_type = TCP_V4_FLOW ;
1135- else if (fkeys -> basic .ip_proto == IPPROTO_UDP )
1144+ } else if (fkeys -> basic .ip_proto == IPPROTO_UDP ) {
11361145 fs -> flow_type = UDP_V4_FLOW ;
1137- else
1146+ } else {
11381147 goto fltr_err ;
1148+ }
11391149
11401150 fs -> h_u .tcp_ip4_spec .ip4src = fkeys -> addrs .v4addrs .src ;
11411151 fs -> m_u .tcp_ip4_spec .ip4src = fmasks -> addrs .v4addrs .src ;
11421152 fs -> h_u .tcp_ip4_spec .ip4dst = fkeys -> addrs .v4addrs .dst ;
11431153 fs -> m_u .tcp_ip4_spec .ip4dst = fmasks -> addrs .v4addrs .dst ;
1144- fs -> h_u .tcp_ip4_spec .psrc = fkeys -> ports .src ;
1145- fs -> m_u .tcp_ip4_spec .psrc = fmasks -> ports .src ;
1146- fs -> h_u .tcp_ip4_spec .pdst = fkeys -> ports .dst ;
1147- fs -> m_u .tcp_ip4_spec .pdst = fmasks -> ports .dst ;
1154+ if (fs -> flow_type == TCP_V4_FLOW ||
1155+ fs -> flow_type == UDP_V4_FLOW ) {
1156+ fs -> h_u .tcp_ip4_spec .psrc = fkeys -> ports .src ;
1157+ fs -> m_u .tcp_ip4_spec .psrc = fmasks -> ports .src ;
1158+ fs -> h_u .tcp_ip4_spec .pdst = fkeys -> ports .dst ;
1159+ fs -> m_u .tcp_ip4_spec .pdst = fmasks -> ports .dst ;
1160+ }
11481161 } else {
1149- if (fkeys -> basic .ip_proto == IPPROTO_TCP )
1162+ if (fkeys -> basic .ip_proto == IPPROTO_ICMPV6 ||
1163+ fkeys -> basic .ip_proto == IPPROTO_RAW ) {
1164+ fs -> flow_type = IPV6_USER_FLOW ;
1165+ if (fkeys -> basic .ip_proto == IPPROTO_ICMPV6 )
1166+ fs -> h_u .usr_ip6_spec .l4_proto = IPPROTO_ICMPV6 ;
1167+ else
1168+ fs -> h_u .usr_ip6_spec .l4_proto = IPPROTO_RAW ;
1169+ fs -> m_u .usr_ip6_spec .l4_proto = BNXT_IP_PROTO_FULL_MASK ;
1170+ } else if (fkeys -> basic .ip_proto == IPPROTO_TCP ) {
11501171 fs -> flow_type = TCP_V6_FLOW ;
1151- else if (fkeys -> basic .ip_proto == IPPROTO_UDP )
1172+ } else if (fkeys -> basic .ip_proto == IPPROTO_UDP ) {
11521173 fs -> flow_type = UDP_V6_FLOW ;
1153- else
1174+ } else {
11541175 goto fltr_err ;
1176+ }
11551177
11561178 * (struct in6_addr * )& fs -> h_u .tcp_ip6_spec .ip6src [0 ] =
11571179 fkeys -> addrs .v6addrs .src ;
@@ -1161,10 +1183,13 @@ static int bnxt_grxclsrule(struct bnxt *bp, struct ethtool_rxnfc *cmd)
11611183 fkeys -> addrs .v6addrs .dst ;
11621184 * (struct in6_addr * )& fs -> m_u .tcp_ip6_spec .ip6dst [0 ] =
11631185 fmasks -> addrs .v6addrs .dst ;
1164- fs -> h_u .tcp_ip6_spec .psrc = fkeys -> ports .src ;
1165- fs -> m_u .tcp_ip6_spec .psrc = fmasks -> ports .src ;
1166- fs -> h_u .tcp_ip6_spec .pdst = fkeys -> ports .dst ;
1167- fs -> m_u .tcp_ip6_spec .pdst = fmasks -> ports .dst ;
1186+ if (fs -> flow_type == TCP_V6_FLOW ||
1187+ fs -> flow_type == UDP_V6_FLOW ) {
1188+ fs -> h_u .tcp_ip6_spec .psrc = fkeys -> ports .src ;
1189+ fs -> m_u .tcp_ip6_spec .psrc = fmasks -> ports .src ;
1190+ fs -> h_u .tcp_ip6_spec .pdst = fkeys -> ports .dst ;
1191+ fs -> m_u .tcp_ip6_spec .pdst = fmasks -> ports .dst ;
1192+ }
11681193 }
11691194
11701195 fs -> ring_cookie = fltr -> base .rxq ;
@@ -1228,6 +1253,28 @@ static int bnxt_add_l2_cls_rule(struct bnxt *bp,
12281253 return rc ;
12291254}
12301255
1256+ static bool bnxt_verify_ntuple_ip4_flow (struct ethtool_usrip4_spec * ip_spec ,
1257+ struct ethtool_usrip4_spec * ip_mask )
1258+ {
1259+ if (ip_mask -> l4_4_bytes || ip_mask -> tos ||
1260+ ip_spec -> ip_ver != ETH_RX_NFC_IP4 ||
1261+ ip_mask -> proto != BNXT_IP_PROTO_FULL_MASK ||
1262+ (ip_spec -> proto != IPPROTO_RAW && ip_spec -> proto != IPPROTO_ICMP ))
1263+ return false;
1264+ return true;
1265+ }
1266+
1267+ static bool bnxt_verify_ntuple_ip6_flow (struct ethtool_usrip6_spec * ip_spec ,
1268+ struct ethtool_usrip6_spec * ip_mask )
1269+ {
1270+ if (ip_mask -> l4_4_bytes || ip_mask -> tclass ||
1271+ ip_mask -> l4_proto != BNXT_IP_PROTO_FULL_MASK ||
1272+ (ip_spec -> l4_proto != IPPROTO_RAW &&
1273+ ip_spec -> l4_proto != IPPROTO_ICMPV6 ))
1274+ return false;
1275+ return true;
1276+ }
1277+
12311278static int bnxt_add_ntuple_cls_rule (struct bnxt * bp ,
12321279 struct ethtool_rx_flow_spec * fs )
12331280{
@@ -1247,6 +1294,18 @@ static int bnxt_add_ntuple_cls_rule(struct bnxt *bp,
12471294 if ((flow_type & (FLOW_MAC_EXT | FLOW_EXT )) || vf )
12481295 return - EOPNOTSUPP ;
12491296
1297+ if (flow_type == IP_USER_FLOW ) {
1298+ if (!bnxt_verify_ntuple_ip4_flow (& fs -> h_u .usr_ip4_spec ,
1299+ & fs -> m_u .usr_ip4_spec ))
1300+ return - EOPNOTSUPP ;
1301+ }
1302+
1303+ if (flow_type == IPV6_USER_FLOW ) {
1304+ if (!bnxt_verify_ntuple_ip6_flow (& fs -> h_u .usr_ip6_spec ,
1305+ & fs -> m_u .usr_ip6_spec ))
1306+ return - EOPNOTSUPP ;
1307+ }
1308+
12501309 new_fltr = kzalloc (sizeof (* new_fltr ), GFP_KERNEL );
12511310 if (!new_fltr )
12521311 return - ENOMEM ;
@@ -1259,6 +1318,18 @@ static int bnxt_add_ntuple_cls_rule(struct bnxt *bp,
12591318
12601319 rc = - EOPNOTSUPP ;
12611320 switch (flow_type ) {
1321+ case IP_USER_FLOW : {
1322+ struct ethtool_usrip4_spec * ip_spec = & fs -> h_u .usr_ip4_spec ;
1323+ struct ethtool_usrip4_spec * ip_mask = & fs -> m_u .usr_ip4_spec ;
1324+
1325+ fkeys -> basic .ip_proto = ip_spec -> proto ;
1326+ fkeys -> basic .n_proto = htons (ETH_P_IP );
1327+ fkeys -> addrs .v4addrs .src = ip_spec -> ip4src ;
1328+ fmasks -> addrs .v4addrs .src = ip_mask -> ip4src ;
1329+ fkeys -> addrs .v4addrs .dst = ip_spec -> ip4dst ;
1330+ fmasks -> addrs .v4addrs .dst = ip_mask -> ip4dst ;
1331+ break ;
1332+ }
12621333 case TCP_V4_FLOW :
12631334 case UDP_V4_FLOW : {
12641335 struct ethtool_tcpip4_spec * ip_spec = & fs -> h_u .tcp_ip4_spec ;
@@ -1278,6 +1349,18 @@ static int bnxt_add_ntuple_cls_rule(struct bnxt *bp,
12781349 fmasks -> ports .dst = ip_mask -> pdst ;
12791350 break ;
12801351 }
1352+ case IPV6_USER_FLOW : {
1353+ struct ethtool_usrip6_spec * ip_spec = & fs -> h_u .usr_ip6_spec ;
1354+ struct ethtool_usrip6_spec * ip_mask = & fs -> m_u .usr_ip6_spec ;
1355+
1356+ fkeys -> basic .ip_proto = ip_spec -> l4_proto ;
1357+ fkeys -> basic .n_proto = htons (ETH_P_IPV6 );
1358+ fkeys -> addrs .v6addrs .src = * (struct in6_addr * )& ip_spec -> ip6src ;
1359+ fmasks -> addrs .v6addrs .src = * (struct in6_addr * )& ip_mask -> ip6src ;
1360+ fkeys -> addrs .v6addrs .dst = * (struct in6_addr * )& ip_spec -> ip6dst ;
1361+ fmasks -> addrs .v6addrs .dst = * (struct in6_addr * )& ip_mask -> ip6dst ;
1362+ break ;
1363+ }
12811364 case TCP_V6_FLOW :
12821365 case UDP_V6_FLOW : {
12831366 struct ethtool_tcpip6_spec * ip_spec = & fs -> h_u .tcp_ip6_spec ;
@@ -1349,6 +1432,15 @@ static int bnxt_srxclsrlins(struct bnxt *bp, struct ethtool_rxnfc *cmd)
13491432 if (fs -> location != RX_CLS_LOC_ANY )
13501433 return - EINVAL ;
13511434
1435+ flow_type = fs -> flow_type ;
1436+ if ((flow_type == IP_USER_FLOW ||
1437+ flow_type == IPV6_USER_FLOW ) &&
1438+ !(bp -> fw_cap & BNXT_FW_CAP_CFA_NTUPLE_RX_EXT_IP_PROTO ))
1439+ return - EOPNOTSUPP ;
1440+ if (flow_type & (FLOW_MAC_EXT | FLOW_RSS ))
1441+ return - EINVAL ;
1442+ flow_type &= ~FLOW_EXT ;
1443+
13521444 ring = ethtool_get_flow_spec_ring (fs -> ring_cookie );
13531445 vf = ethtool_get_flow_spec_ring_vf (fs -> ring_cookie );
13541446 if (BNXT_VF (bp ) && vf )
@@ -1358,10 +1450,6 @@ static int bnxt_srxclsrlins(struct bnxt *bp, struct ethtool_rxnfc *cmd)
13581450 if (!vf && ring >= bp -> rx_nr_rings )
13591451 return - EINVAL ;
13601452
1361- flow_type = fs -> flow_type ;
1362- if (flow_type & (FLOW_MAC_EXT | FLOW_RSS ))
1363- return - EINVAL ;
1364- flow_type &= ~FLOW_EXT ;
13651453 if (flow_type == ETHER_FLOW )
13661454 rc = bnxt_add_l2_cls_rule (bp , fs );
13671455 else
0 commit comments