@@ -2241,13 +2241,14 @@ static int set_pedit_val(u8 hdr_type, u32 mask, u32 val, u32 offset,
2241
2241
2242
2242
struct mlx5_fields {
2243
2243
u8 field ;
2244
- u8 size ;
2244
+ u8 field_bsize ;
2245
+ u32 field_mask ;
2245
2246
u32 offset ;
2246
2247
u32 match_offset ;
2247
2248
};
2248
2249
2249
- #define OFFLOAD (fw_field , size , field , off , match_field ) \
2250
- {MLX5_ACTION_IN_FIELD_OUT_ ## fw_field, size , \
2250
+ #define OFFLOAD (fw_field , field_bsize , field_mask , field , off , match_field ) \
2251
+ {MLX5_ACTION_IN_FIELD_OUT_ ## fw_field, field_bsize, field_mask , \
2251
2252
offsetof(struct pedit_headers, field) + (off), \
2252
2253
MLX5_BYTE_OFF(fte_match_set_lyr_2_4, match_field)}
2253
2254
@@ -2265,18 +2266,18 @@ struct mlx5_fields {
2265
2266
})
2266
2267
2267
2268
static bool cmp_val_mask (void * valp , void * maskp , void * matchvalp ,
2268
- void * matchmaskp , int size )
2269
+ void * matchmaskp , u8 bsize )
2269
2270
{
2270
2271
bool same = false;
2271
2272
2272
- switch (size ) {
2273
- case sizeof ( u8 ) :
2273
+ switch (bsize ) {
2274
+ case 8 :
2274
2275
same = SAME_VAL_MASK (u8 , valp , maskp , matchvalp , matchmaskp );
2275
2276
break ;
2276
- case sizeof ( u16 ) :
2277
+ case 16 :
2277
2278
same = SAME_VAL_MASK (u16 , valp , maskp , matchvalp , matchmaskp );
2278
2279
break ;
2279
- case sizeof ( u32 ) :
2280
+ case 32 :
2280
2281
same = SAME_VAL_MASK (u32 , valp , maskp , matchvalp , matchmaskp );
2281
2282
break ;
2282
2283
}
@@ -2285,41 +2286,43 @@ static bool cmp_val_mask(void *valp, void *maskp, void *matchvalp,
2285
2286
}
2286
2287
2287
2288
static struct mlx5_fields fields [] = {
2288
- OFFLOAD (DMAC_47_16 , 4 , eth .h_dest [0 ], 0 , dmac_47_16 ),
2289
- OFFLOAD (DMAC_15_0 , 2 , eth .h_dest [4 ], 0 , dmac_15_0 ),
2290
- OFFLOAD (SMAC_47_16 , 4 , eth .h_source [0 ], 0 , smac_47_16 ),
2291
- OFFLOAD (SMAC_15_0 , 2 , eth .h_source [4 ], 0 , smac_15_0 ),
2292
- OFFLOAD (ETHERTYPE , 2 , eth .h_proto , 0 , ethertype ),
2293
- OFFLOAD (FIRST_VID , 2 , vlan .h_vlan_TCI , 0 , first_vid ),
2294
-
2295
- OFFLOAD (IP_TTL , 1 , ip4 .ttl , 0 , ttl_hoplimit ),
2296
- OFFLOAD (SIPV4 , 4 , ip4 .saddr , 0 , src_ipv4_src_ipv6 .ipv4_layout .ipv4 ),
2297
- OFFLOAD (DIPV4 , 4 , ip4 .daddr , 0 , dst_ipv4_dst_ipv6 .ipv4_layout .ipv4 ),
2298
-
2299
- OFFLOAD (SIPV6_127_96 , 4 , ip6 .saddr .s6_addr32 [0 ], 0 ,
2289
+ OFFLOAD (DMAC_47_16 , 32 , U32_MAX , eth .h_dest [0 ], 0 , dmac_47_16 ),
2290
+ OFFLOAD (DMAC_15_0 , 16 , U16_MAX , eth .h_dest [4 ], 0 , dmac_15_0 ),
2291
+ OFFLOAD (SMAC_47_16 , 32 , U32_MAX , eth .h_source [0 ], 0 , smac_47_16 ),
2292
+ OFFLOAD (SMAC_15_0 , 16 , U16_MAX , eth .h_source [4 ], 0 , smac_15_0 ),
2293
+ OFFLOAD (ETHERTYPE , 16 , U16_MAX , eth .h_proto , 0 , ethertype ),
2294
+ OFFLOAD (FIRST_VID , 16 , U16_MAX , vlan .h_vlan_TCI , 0 , first_vid ),
2295
+
2296
+ OFFLOAD (IP_DSCP , 8 , 0xfc , ip4 .tos , 0 , ip_dscp ),
2297
+ OFFLOAD (IP_TTL , 8 , U8_MAX , ip4 .ttl , 0 , ttl_hoplimit ),
2298
+ OFFLOAD (SIPV4 , 32 , U32_MAX , ip4 .saddr , 0 , src_ipv4_src_ipv6 .ipv4_layout .ipv4 ),
2299
+ OFFLOAD (DIPV4 , 32 , U32_MAX , ip4 .daddr , 0 , dst_ipv4_dst_ipv6 .ipv4_layout .ipv4 ),
2300
+
2301
+ OFFLOAD (SIPV6_127_96 , 32 , U32_MAX , ip6 .saddr .s6_addr32 [0 ], 0 ,
2300
2302
src_ipv4_src_ipv6 .ipv6_layout .ipv6 [0 ]),
2301
- OFFLOAD (SIPV6_95_64 , 4 , ip6 .saddr .s6_addr32 [1 ], 0 ,
2303
+ OFFLOAD (SIPV6_95_64 , 32 , U32_MAX , ip6 .saddr .s6_addr32 [1 ], 0 ,
2302
2304
src_ipv4_src_ipv6 .ipv6_layout .ipv6 [4 ]),
2303
- OFFLOAD (SIPV6_63_32 , 4 , ip6 .saddr .s6_addr32 [2 ], 0 ,
2305
+ OFFLOAD (SIPV6_63_32 , 32 , U32_MAX , ip6 .saddr .s6_addr32 [2 ], 0 ,
2304
2306
src_ipv4_src_ipv6 .ipv6_layout .ipv6 [8 ]),
2305
- OFFLOAD (SIPV6_31_0 , 4 , ip6 .saddr .s6_addr32 [3 ], 0 ,
2307
+ OFFLOAD (SIPV6_31_0 , 32 , U32_MAX , ip6 .saddr .s6_addr32 [3 ], 0 ,
2306
2308
src_ipv4_src_ipv6 .ipv6_layout .ipv6 [12 ]),
2307
- OFFLOAD (DIPV6_127_96 , 4 , ip6 .daddr .s6_addr32 [0 ], 0 ,
2309
+ OFFLOAD (DIPV6_127_96 , 32 , U32_MAX , ip6 .daddr .s6_addr32 [0 ], 0 ,
2308
2310
dst_ipv4_dst_ipv6 .ipv6_layout .ipv6 [0 ]),
2309
- OFFLOAD (DIPV6_95_64 , 4 , ip6 .daddr .s6_addr32 [1 ], 0 ,
2311
+ OFFLOAD (DIPV6_95_64 , 32 , U32_MAX , ip6 .daddr .s6_addr32 [1 ], 0 ,
2310
2312
dst_ipv4_dst_ipv6 .ipv6_layout .ipv6 [4 ]),
2311
- OFFLOAD (DIPV6_63_32 , 4 , ip6 .daddr .s6_addr32 [2 ], 0 ,
2313
+ OFFLOAD (DIPV6_63_32 , 32 , U32_MAX , ip6 .daddr .s6_addr32 [2 ], 0 ,
2312
2314
dst_ipv4_dst_ipv6 .ipv6_layout .ipv6 [8 ]),
2313
- OFFLOAD (DIPV6_31_0 , 4 , ip6 .daddr .s6_addr32 [3 ], 0 ,
2315
+ OFFLOAD (DIPV6_31_0 , 32 , U32_MAX , ip6 .daddr .s6_addr32 [3 ], 0 ,
2314
2316
dst_ipv4_dst_ipv6 .ipv6_layout .ipv6 [12 ]),
2315
- OFFLOAD (IPV6_HOPLIMIT , 1 , ip6 .hop_limit , 0 , ttl_hoplimit ),
2317
+ OFFLOAD (IPV6_HOPLIMIT , 8 , U8_MAX , ip6 .hop_limit , 0 , ttl_hoplimit ),
2316
2318
2317
- OFFLOAD (TCP_SPORT , 2 , tcp .source , 0 , tcp_sport ),
2318
- OFFLOAD (TCP_DPORT , 2 , tcp .dest , 0 , tcp_dport ),
2319
- OFFLOAD (TCP_FLAGS , 1 , tcp .ack_seq , 5 , tcp_flags ),
2319
+ OFFLOAD (TCP_SPORT , 16 , U16_MAX , tcp .source , 0 , tcp_sport ),
2320
+ OFFLOAD (TCP_DPORT , 16 , U16_MAX , tcp .dest , 0 , tcp_dport ),
2321
+ /* in linux iphdr tcp_flags is 8 bits long */
2322
+ OFFLOAD (TCP_FLAGS , 8 , U8_MAX , tcp .ack_seq , 5 , tcp_flags ),
2320
2323
2321
- OFFLOAD (UDP_SPORT , 2 , udp .source , 0 , udp_sport ),
2322
- OFFLOAD (UDP_DPORT , 2 , udp .dest , 0 , udp_dport ),
2324
+ OFFLOAD (UDP_SPORT , 16 , U16_MAX , udp .source , 0 , udp_sport ),
2325
+ OFFLOAD (UDP_DPORT , 16 , U16_MAX , udp .dest , 0 , udp_dport ),
2323
2326
};
2324
2327
2325
2328
/* On input attr->max_mod_hdr_actions tells how many HW actions can be parsed at
@@ -2332,19 +2335,17 @@ static int offload_pedit_fields(struct pedit_headers_action *hdrs,
2332
2335
struct netlink_ext_ack * extack )
2333
2336
{
2334
2337
struct pedit_headers * set_masks , * add_masks , * set_vals , * add_vals ;
2335
- void * headers_c = get_match_headers_criteria (* action_flags ,
2336
- & parse_attr -> spec );
2337
- void * headers_v = get_match_headers_value (* action_flags ,
2338
- & parse_attr -> spec );
2339
2338
int i , action_size , nactions , max_actions , first , last , next_z ;
2340
- void * s_masks_p , * a_masks_p , * vals_p ;
2339
+ void * headers_c , * headers_v , * action , * vals_p ;
2340
+ u32 * s_masks_p , * a_masks_p , s_mask , a_mask ;
2341
2341
struct mlx5_fields * f ;
2342
- u8 cmd , field_bsize ;
2343
- u32 s_mask , a_mask ;
2344
2342
unsigned long mask ;
2345
2343
__be32 mask_be32 ;
2346
2344
__be16 mask_be16 ;
2347
- void * action ;
2345
+ u8 cmd ;
2346
+
2347
+ headers_c = get_match_headers_criteria (* action_flags , & parse_attr -> spec );
2348
+ headers_v = get_match_headers_value (* action_flags , & parse_attr -> spec );
2348
2349
2349
2350
set_masks = & hdrs [0 ].masks ;
2350
2351
add_masks = & hdrs [1 ].masks ;
@@ -2369,8 +2370,8 @@ static int offload_pedit_fields(struct pedit_headers_action *hdrs,
2369
2370
s_masks_p = (void * )set_masks + f -> offset ;
2370
2371
a_masks_p = (void * )add_masks + f -> offset ;
2371
2372
2372
- memcpy ( & s_mask , s_masks_p , f -> size ) ;
2373
- memcpy ( & a_mask , a_masks_p , f -> size ) ;
2373
+ s_mask = * s_masks_p & f -> field_mask ;
2374
+ a_mask = * a_masks_p & f -> field_mask ;
2374
2375
2375
2376
if (!s_mask && !a_mask ) /* nothing to offload here */
2376
2377
continue ;
@@ -2399,38 +2400,34 @@ static int offload_pedit_fields(struct pedit_headers_action *hdrs,
2399
2400
vals_p = (void * )set_vals + f -> offset ;
2400
2401
/* don't rewrite if we have a match on the same value */
2401
2402
if (cmp_val_mask (vals_p , s_masks_p , match_val ,
2402
- match_mask , f -> size ))
2403
+ match_mask , f -> field_bsize ))
2403
2404
skip = true;
2404
2405
/* clear to denote we consumed this field */
2405
- memset ( s_masks_p , 0 , f -> size ) ;
2406
+ * s_masks_p &= ~ f -> field_mask ;
2406
2407
} else {
2407
- u32 zero = 0 ;
2408
-
2409
2408
cmd = MLX5_ACTION_TYPE_ADD ;
2410
2409
mask = a_mask ;
2411
2410
vals_p = (void * )add_vals + f -> offset ;
2412
2411
/* add 0 is no change */
2413
- if (! memcmp ( vals_p , & zero , f -> size ) )
2412
+ if (( * ( u32 * ) vals_p & f -> field_mask ) == 0 )
2414
2413
skip = true;
2415
2414
/* clear to denote we consumed this field */
2416
- memset ( a_masks_p , 0 , f -> size ) ;
2415
+ * a_masks_p &= ~ f -> field_mask ;
2417
2416
}
2418
2417
if (skip )
2419
2418
continue ;
2420
2419
2421
- field_bsize = f -> size * BITS_PER_BYTE ;
2422
-
2423
- if (field_bsize == 32 ) {
2420
+ if (f -> field_bsize == 32 ) {
2424
2421
mask_be32 = * (__be32 * )& mask ;
2425
2422
mask = (__force unsigned long )cpu_to_le32 (be32_to_cpu (mask_be32 ));
2426
- } else if (field_bsize == 16 ) {
2423
+ } else if (f -> field_bsize == 16 ) {
2427
2424
mask_be16 = * (__be16 * )& mask ;
2428
2425
mask = (__force unsigned long )cpu_to_le16 (be16_to_cpu (mask_be16 ));
2429
2426
}
2430
2427
2431
- first = find_first_bit (& mask , field_bsize );
2432
- next_z = find_next_zero_bit (& mask , field_bsize , first );
2433
- last = find_last_bit (& mask , field_bsize );
2428
+ first = find_first_bit (& mask , f -> field_bsize );
2429
+ next_z = find_next_zero_bit (& mask , f -> field_bsize , first );
2430
+ last = find_last_bit (& mask , f -> field_bsize );
2434
2431
if (first < next_z && next_z < last ) {
2435
2432
NL_SET_ERR_MSG_MOD (extack ,
2436
2433
"rewrite of few sub-fields isn't supported" );
@@ -2443,16 +2440,22 @@ static int offload_pedit_fields(struct pedit_headers_action *hdrs,
2443
2440
MLX5_SET (set_action_in , action , field , f -> field );
2444
2441
2445
2442
if (cmd == MLX5_ACTION_TYPE_SET ) {
2446
- MLX5_SET (set_action_in , action , offset , first );
2443
+ int start ;
2444
+
2445
+ /* if field is bit sized it can start not from first bit */
2446
+ start = find_first_bit ((unsigned long * )& f -> field_mask ,
2447
+ f -> field_bsize );
2448
+
2449
+ MLX5_SET (set_action_in , action , offset , first - start );
2447
2450
/* length is num of bits to be written, zero means length of 32 */
2448
2451
MLX5_SET (set_action_in , action , length , (last - first + 1 ));
2449
2452
}
2450
2453
2451
- if (field_bsize == 32 )
2454
+ if (f -> field_bsize == 32 )
2452
2455
MLX5_SET (set_action_in , action , data , ntohl (* (__be32 * )vals_p ) >> first );
2453
- else if (field_bsize == 16 )
2456
+ else if (f -> field_bsize == 16 )
2454
2457
MLX5_SET (set_action_in , action , data , ntohs (* (__be16 * )vals_p ) >> first );
2455
- else if (field_bsize == 8 )
2458
+ else if (f -> field_bsize == 8 )
2456
2459
MLX5_SET (set_action_in , action , data , * (u8 * )vals_p >> first );
2457
2460
2458
2461
action += action_size ;
@@ -3443,6 +3446,12 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv,
3443
3446
attr -> action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST ;
3444
3447
}
3445
3448
3449
+ if (!(attr -> action &
3450
+ (MLX5_FLOW_CONTEXT_ACTION_FWD_DEST | MLX5_FLOW_CONTEXT_ACTION_DROP ))) {
3451
+ NL_SET_ERR_MSG (extack , "Rule must have at least one forward/drop action" );
3452
+ return - EOPNOTSUPP ;
3453
+ }
3454
+
3446
3455
if (attr -> split_count > 0 && !mlx5_esw_has_fwd_fdb (priv -> mdev )) {
3447
3456
NL_SET_ERR_MSG_MOD (extack ,
3448
3457
"current firmware doesn't support split rule for port mirroring" );
0 commit comments