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