@@ -93,6 +93,8 @@ struct pcpu_secy_stats {
93
93
* @secys: linked list of SecY's on the underlying device
94
94
* @gro_cells: pointer to the Generic Receive Offload cell
95
95
* @offload: status of offloading on the MACsec device
96
+ * @insert_tx_tag: when offloading, device requires to insert an
97
+ * additional tag
96
98
*/
97
99
struct macsec_dev {
98
100
struct macsec_secy secy ;
@@ -102,6 +104,7 @@ struct macsec_dev {
102
104
struct list_head secys ;
103
105
struct gro_cells gro_cells ;
104
106
enum macsec_offload offload ;
107
+ bool insert_tx_tag ;
105
108
};
106
109
107
110
/**
@@ -2568,6 +2571,33 @@ static bool macsec_is_configured(struct macsec_dev *macsec)
2568
2571
return false;
2569
2572
}
2570
2573
2574
+ static bool macsec_needs_tx_tag (struct macsec_dev * macsec ,
2575
+ const struct macsec_ops * ops )
2576
+ {
2577
+ return macsec -> offload == MACSEC_OFFLOAD_PHY &&
2578
+ ops -> mdo_insert_tx_tag ;
2579
+ }
2580
+
2581
+ static void macsec_set_head_tail_room (struct net_device * dev )
2582
+ {
2583
+ struct macsec_dev * macsec = macsec_priv (dev );
2584
+ struct net_device * real_dev = macsec -> real_dev ;
2585
+ int needed_headroom , needed_tailroom ;
2586
+ const struct macsec_ops * ops ;
2587
+
2588
+ ops = macsec_get_ops (macsec , NULL );
2589
+ if (ops ) {
2590
+ needed_headroom = ops -> needed_headroom ;
2591
+ needed_tailroom = ops -> needed_tailroom ;
2592
+ } else {
2593
+ needed_headroom = MACSEC_NEEDED_HEADROOM ;
2594
+ needed_tailroom = MACSEC_NEEDED_TAILROOM ;
2595
+ }
2596
+
2597
+ dev -> needed_headroom = real_dev -> needed_headroom + needed_headroom ;
2598
+ dev -> needed_tailroom = real_dev -> needed_tailroom + needed_tailroom ;
2599
+ }
2600
+
2571
2601
static int macsec_update_offload (struct net_device * dev , enum macsec_offload offload )
2572
2602
{
2573
2603
enum macsec_offload prev_offload ;
@@ -2605,8 +2635,13 @@ static int macsec_update_offload(struct net_device *dev, enum macsec_offload off
2605
2635
ctx .secy = & macsec -> secy ;
2606
2636
ret = offload == MACSEC_OFFLOAD_OFF ? macsec_offload (ops -> mdo_del_secy , & ctx )
2607
2637
: macsec_offload (ops -> mdo_add_secy , & ctx );
2608
- if (ret )
2638
+ if (ret ) {
2609
2639
macsec -> offload = prev_offload ;
2640
+ return ret ;
2641
+ }
2642
+
2643
+ macsec_set_head_tail_room (dev );
2644
+ macsec -> insert_tx_tag = macsec_needs_tx_tag (macsec , ops );
2610
2645
2611
2646
return ret ;
2612
2647
}
@@ -3364,6 +3399,40 @@ static struct genl_family macsec_fam __ro_after_init = {
3364
3399
.resv_start_op = MACSEC_CMD_UPD_OFFLOAD + 1 ,
3365
3400
};
3366
3401
3402
+ static struct sk_buff * macsec_insert_tx_tag (struct sk_buff * skb ,
3403
+ struct net_device * dev )
3404
+ {
3405
+ struct macsec_dev * macsec = macsec_priv (dev );
3406
+ const struct macsec_ops * ops ;
3407
+ struct phy_device * phydev ;
3408
+ struct macsec_context ctx ;
3409
+ int skb_final_len ;
3410
+ int err ;
3411
+
3412
+ ops = macsec_get_ops (macsec , & ctx );
3413
+ skb_final_len = skb -> len - ETH_HLEN + ops -> needed_headroom +
3414
+ ops -> needed_tailroom ;
3415
+ if (unlikely (skb_final_len > macsec -> real_dev -> mtu )) {
3416
+ err = - EINVAL ;
3417
+ goto cleanup ;
3418
+ }
3419
+
3420
+ phydev = macsec -> real_dev -> phydev ;
3421
+
3422
+ err = skb_ensure_writable_head_tail (skb , dev );
3423
+ if (unlikely (err < 0 ))
3424
+ goto cleanup ;
3425
+
3426
+ err = ops -> mdo_insert_tx_tag (phydev , skb );
3427
+ if (unlikely (err ))
3428
+ goto cleanup ;
3429
+
3430
+ return skb ;
3431
+ cleanup :
3432
+ kfree_skb (skb );
3433
+ return ERR_PTR (err );
3434
+ }
3435
+
3367
3436
static netdev_tx_t macsec_start_xmit (struct sk_buff * skb ,
3368
3437
struct net_device * dev )
3369
3438
{
@@ -3378,6 +3447,15 @@ static netdev_tx_t macsec_start_xmit(struct sk_buff *skb,
3378
3447
skb_dst_drop (skb );
3379
3448
dst_hold (& md_dst -> dst );
3380
3449
skb_dst_set (skb , & md_dst -> dst );
3450
+
3451
+ if (macsec -> insert_tx_tag ) {
3452
+ skb = macsec_insert_tx_tag (skb , dev );
3453
+ if (IS_ERR (skb )) {
3454
+ DEV_STATS_INC (dev , tx_dropped );
3455
+ return NETDEV_TX_OK ;
3456
+ }
3457
+ }
3458
+
3381
3459
skb -> dev = macsec -> real_dev ;
3382
3460
return dev_queue_xmit (skb );
3383
3461
}
@@ -3439,10 +3517,7 @@ static int macsec_dev_init(struct net_device *dev)
3439
3517
dev -> features = real_dev -> features & MACSEC_FEATURES ;
3440
3518
dev -> features |= NETIF_F_LLTX | NETIF_F_GSO_SOFTWARE ;
3441
3519
3442
- dev -> needed_headroom = real_dev -> needed_headroom +
3443
- MACSEC_NEEDED_HEADROOM ;
3444
- dev -> needed_tailroom = real_dev -> needed_tailroom +
3445
- MACSEC_NEEDED_TAILROOM ;
3520
+ macsec_set_head_tail_room (dev );
3446
3521
3447
3522
if (is_zero_ether_addr (dev -> dev_addr ))
3448
3523
eth_hw_addr_inherit (dev , real_dev );
@@ -4125,6 +4200,9 @@ static int macsec_newlink(struct net *net, struct net_device *dev,
4125
4200
err = macsec_offload (ops -> mdo_add_secy , & ctx );
4126
4201
if (err )
4127
4202
goto del_dev ;
4203
+
4204
+ macsec -> insert_tx_tag =
4205
+ macsec_needs_tx_tag (macsec , ops );
4128
4206
}
4129
4207
}
4130
4208
0 commit comments