Skip to content

Commit a73d877

Browse files
Radu Pirea (NXP OSS)davem330
authored andcommitted
net: macsec: introduce mdo_insert_tx_tag
Offloading MACsec in PHYs requires inserting the SecTAG and the ICV in the ethernet frame. This operation will increase the frame size with up to 32 bytes. If the frames are sent at line rate, the PHY will not have enough room to insert the SecTAG and the ICV. Some PHYs use a hardware buffer to store a number of ethernet frames and, if it fills up, a pause frame is sent to the MAC to control the flow. This HW implementation does not need any modification in the stack. Other PHYs might offer to use a specific ethertype with some padding bytes present in the ethernet frame. This ethertype and its associated bytes will be replaced by the SecTAG and ICV. mdo_insert_tx_tag allows the PHY drivers to add any specific tag in the skb. Signed-off-by: Radu Pirea (NXP OSS) <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 25a00d0 commit a73d877

File tree

2 files changed

+93
-5
lines changed

2 files changed

+93
-5
lines changed

drivers/net/macsec.c

Lines changed: 83 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ struct pcpu_secy_stats {
9393
* @secys: linked list of SecY's on the underlying device
9494
* @gro_cells: pointer to the Generic Receive Offload cell
9595
* @offload: status of offloading on the MACsec device
96+
* @insert_tx_tag: when offloading, device requires to insert an
97+
* additional tag
9698
*/
9799
struct macsec_dev {
98100
struct macsec_secy secy;
@@ -102,6 +104,7 @@ struct macsec_dev {
102104
struct list_head secys;
103105
struct gro_cells gro_cells;
104106
enum macsec_offload offload;
107+
bool insert_tx_tag;
105108
};
106109

107110
/**
@@ -2568,6 +2571,33 @@ static bool macsec_is_configured(struct macsec_dev *macsec)
25682571
return false;
25692572
}
25702573

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+
25712601
static int macsec_update_offload(struct net_device *dev, enum macsec_offload offload)
25722602
{
25732603
enum macsec_offload prev_offload;
@@ -2605,8 +2635,13 @@ static int macsec_update_offload(struct net_device *dev, enum macsec_offload off
26052635
ctx.secy = &macsec->secy;
26062636
ret = offload == MACSEC_OFFLOAD_OFF ? macsec_offload(ops->mdo_del_secy, &ctx)
26072637
: macsec_offload(ops->mdo_add_secy, &ctx);
2608-
if (ret)
2638+
if (ret) {
26092639
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);
26102645

26112646
return ret;
26122647
}
@@ -3364,6 +3399,40 @@ static struct genl_family macsec_fam __ro_after_init = {
33643399
.resv_start_op = MACSEC_CMD_UPD_OFFLOAD + 1,
33653400
};
33663401

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+
33673436
static netdev_tx_t macsec_start_xmit(struct sk_buff *skb,
33683437
struct net_device *dev)
33693438
{
@@ -3378,6 +3447,15 @@ static netdev_tx_t macsec_start_xmit(struct sk_buff *skb,
33783447
skb_dst_drop(skb);
33793448
dst_hold(&md_dst->dst);
33803449
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+
33813459
skb->dev = macsec->real_dev;
33823460
return dev_queue_xmit(skb);
33833461
}
@@ -3439,10 +3517,7 @@ static int macsec_dev_init(struct net_device *dev)
34393517
dev->features = real_dev->features & MACSEC_FEATURES;
34403518
dev->features |= NETIF_F_LLTX | NETIF_F_GSO_SOFTWARE;
34413519

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);
34463521

34473522
if (is_zero_ether_addr(dev->dev_addr))
34483523
eth_hw_addr_inherit(dev, real_dev);
@@ -4125,6 +4200,9 @@ static int macsec_newlink(struct net *net, struct net_device *dev,
41254200
err = macsec_offload(ops->mdo_add_secy, &ctx);
41264201
if (err)
41274202
goto del_dev;
4203+
4204+
macsec->insert_tx_tag =
4205+
macsec_needs_tx_tag(macsec, ops);
41284206
}
41294207
}
41304208

include/net/macsec.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,11 @@ struct macsec_context {
316316
* @mdo_get_tx_sa_stats: called when TX SA stats are read
317317
* @mdo_get_rx_sc_stats: called when RX SC stats are read
318318
* @mdo_get_rx_sa_stats: called when RX SA stats are read
319+
* @mdo_insert_tx_tag: called to insert the TX tag
320+
* @needed_headroom: number of bytes reserved at the beginning of the sk_buff
321+
* for the TX tag
322+
* @needed_tailroom: number of bytes reserved at the end of the sk_buff for the
323+
* TX tag
319324
*/
320325
struct macsec_ops {
321326
/* Device wide */
@@ -342,6 +347,11 @@ struct macsec_ops {
342347
int (*mdo_get_tx_sa_stats)(struct macsec_context *ctx);
343348
int (*mdo_get_rx_sc_stats)(struct macsec_context *ctx);
344349
int (*mdo_get_rx_sa_stats)(struct macsec_context *ctx);
350+
/* Offload tag */
351+
int (*mdo_insert_tx_tag)(struct phy_device *phydev,
352+
struct sk_buff *skb);
353+
unsigned int needed_headroom;
354+
unsigned int needed_tailroom;
345355
};
346356

347357
void macsec_pn_wrapped(struct macsec_secy *secy, struct macsec_tx_sa *tx_sa);

0 commit comments

Comments
 (0)