Skip to content

Commit 2f7ccf1

Browse files
committed
Merge branch 'net-tja11xx-macsec-support'
Radu Pirea says: ==================== Add MACsec support for TJA11XX C45 PHYs This is the MACsec support for TJA11XX PHYs. The MACsec block encrypts the ethernet frames on the fly and has no buffering. This operation will grow the frames by 32 bytes. If the frames are sent back to back, the MACsec block will not have enough room to insert the SecTAG and the ICV and the frames will be dropped. To mitigate this, the PHY can parse a specific ethertype with some padding bytes and replace them with the SecTAG and ICV. These padding bytes might be dummy or might contain information about TX SC that must be used to encrypt the frame. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents c2b2ee3 + dc1a003 commit 2f7ccf1

File tree

12 files changed

+2043
-101
lines changed

12 files changed

+2043
-101
lines changed

MAINTAINERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15444,7 +15444,7 @@ NXP C45 TJA11XX PHY DRIVER
1544415444
M: Radu Pirea <[email protected]>
1544515445
1544615446
S: Maintained
15447-
F: drivers/net/phy/nxp-c45-tja11xx.c
15447+
F: drivers/net/phy/nxp-c45-tja11xx*
1544815448

1544915449
NXP FSPI DRIVER
1545015450
M: Han Xu <[email protected]>

drivers/net/macsec.c

Lines changed: 114 additions & 37 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
/**
@@ -604,26 +607,11 @@ static struct sk_buff *macsec_encrypt(struct sk_buff *skb,
604607
return ERR_PTR(-EINVAL);
605608
}
606609

607-
if (unlikely(skb_headroom(skb) < MACSEC_NEEDED_HEADROOM ||
608-
skb_tailroom(skb) < MACSEC_NEEDED_TAILROOM)) {
609-
struct sk_buff *nskb = skb_copy_expand(skb,
610-
MACSEC_NEEDED_HEADROOM,
611-
MACSEC_NEEDED_TAILROOM,
612-
GFP_ATOMIC);
613-
if (likely(nskb)) {
614-
consume_skb(skb);
615-
skb = nskb;
616-
} else {
617-
macsec_txsa_put(tx_sa);
618-
kfree_skb(skb);
619-
return ERR_PTR(-ENOMEM);
620-
}
621-
} else {
622-
skb = skb_unshare(skb, GFP_ATOMIC);
623-
if (!skb) {
624-
macsec_txsa_put(tx_sa);
625-
return ERR_PTR(-ENOMEM);
626-
}
610+
ret = skb_ensure_writable_head_tail(skb, dev);
611+
if (unlikely(ret < 0)) {
612+
macsec_txsa_put(tx_sa);
613+
kfree_skb(skb);
614+
return ERR_PTR(ret);
627615
}
628616

629617
unprotected_len = skb->len;
@@ -2583,6 +2571,33 @@ static bool macsec_is_configured(struct macsec_dev *macsec)
25832571
return false;
25842572
}
25852573

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+
25862601
static int macsec_update_offload(struct net_device *dev, enum macsec_offload offload)
25872602
{
25882603
enum macsec_offload prev_offload;
@@ -2620,8 +2635,13 @@ static int macsec_update_offload(struct net_device *dev, enum macsec_offload off
26202635
ctx.secy = &macsec->secy;
26212636
ret = offload == MACSEC_OFFLOAD_OFF ? macsec_offload(ops->mdo_del_secy, &ctx)
26222637
: macsec_offload(ops->mdo_add_secy, &ctx);
2623-
if (ret)
2638+
if (ret) {
26242639
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);
26252645

26262646
return ret;
26272647
}
@@ -3379,6 +3399,40 @@ static struct genl_family macsec_fam __ro_after_init = {
33793399
.resv_start_op = MACSEC_CMD_UPD_OFFLOAD + 1,
33803400
};
33813401

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+
33823436
static netdev_tx_t macsec_start_xmit(struct sk_buff *skb,
33833437
struct net_device *dev)
33843438
{
@@ -3393,6 +3447,15 @@ static netdev_tx_t macsec_start_xmit(struct sk_buff *skb,
33933447
skb_dst_drop(skb);
33943448
dst_hold(&md_dst->dst);
33953449
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+
33963459
skb->dev = macsec->real_dev;
33973460
return dev_queue_xmit(skb);
33983461
}
@@ -3454,10 +3517,7 @@ static int macsec_dev_init(struct net_device *dev)
34543517
dev->features = real_dev->features & MACSEC_FEATURES;
34553518
dev->features |= NETIF_F_LLTX | NETIF_F_GSO_SOFTWARE;
34563519

3457-
dev->needed_headroom = real_dev->needed_headroom +
3458-
MACSEC_NEEDED_HEADROOM;
3459-
dev->needed_tailroom = real_dev->needed_tailroom +
3460-
MACSEC_NEEDED_TAILROOM;
3520+
macsec_set_head_tail_room(dev);
34613521

34623522
if (is_zero_ether_addr(dev->dev_addr))
34633523
eth_hw_addr_inherit(dev, real_dev);
@@ -3604,21 +3664,19 @@ static int macsec_set_mac_address(struct net_device *dev, void *p)
36043664
struct macsec_dev *macsec = macsec_priv(dev);
36053665
struct net_device *real_dev = macsec->real_dev;
36063666
struct sockaddr *addr = p;
3667+
u8 old_addr[ETH_ALEN];
36073668
int err;
36083669

36093670
if (!is_valid_ether_addr(addr->sa_data))
36103671
return -EADDRNOTAVAIL;
36113672

3612-
if (!(dev->flags & IFF_UP))
3613-
goto out;
3614-
3615-
err = dev_uc_add(real_dev, addr->sa_data);
3616-
if (err < 0)
3617-
return err;
3618-
3619-
dev_uc_del(real_dev, dev->dev_addr);
3673+
if (dev->flags & IFF_UP) {
3674+
err = dev_uc_add(real_dev, addr->sa_data);
3675+
if (err < 0)
3676+
return err;
3677+
}
36203678

3621-
out:
3679+
ether_addr_copy(old_addr, dev->dev_addr);
36223680
eth_hw_addr_set(dev, addr->sa_data);
36233681

36243682
/* If h/w offloading is available, propagate to the device */
@@ -3627,13 +3685,29 @@ static int macsec_set_mac_address(struct net_device *dev, void *p)
36273685
struct macsec_context ctx;
36283686

36293687
ops = macsec_get_ops(macsec, &ctx);
3630-
if (ops) {
3631-
ctx.secy = &macsec->secy;
3632-
macsec_offload(ops->mdo_upd_secy, &ctx);
3688+
if (!ops) {
3689+
err = -EOPNOTSUPP;
3690+
goto restore_old_addr;
36333691
}
3692+
3693+
ctx.secy = &macsec->secy;
3694+
err = macsec_offload(ops->mdo_upd_secy, &ctx);
3695+
if (err)
3696+
goto restore_old_addr;
36343697
}
36353698

3699+
if (dev->flags & IFF_UP)
3700+
dev_uc_del(real_dev, old_addr);
3701+
36363702
return 0;
3703+
3704+
restore_old_addr:
3705+
if (dev->flags & IFF_UP)
3706+
dev_uc_del(real_dev, addr->sa_data);
3707+
3708+
eth_hw_addr_set(dev, old_addr);
3709+
3710+
return err;
36373711
}
36383712

36393713
static int macsec_change_mtu(struct net_device *dev, int new_mtu)
@@ -4126,6 +4200,9 @@ static int macsec_newlink(struct net *net, struct net_device *dev,
41264200
err = macsec_offload(ops->mdo_add_secy, &ctx);
41274201
if (err)
41284202
goto del_dev;
4203+
4204+
macsec->insert_tx_tag =
4205+
macsec_needs_tx_tag(macsec, ops);
41294206
}
41304207
}
41314208

drivers/net/netdevsim/macsec.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,6 @@
33
#include <net/macsec.h>
44
#include "netdevsim.h"
55

6-
static inline u64 sci_to_cpu(sci_t sci)
7-
{
8-
return be64_to_cpu((__force __be64)sci);
9-
}
10-
116
static int nsim_macsec_find_secy(struct netdevsim *ns, sci_t sci)
127
{
138
int i;

drivers/net/phy/Kconfig

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,9 +317,10 @@ config NXP_CBTX_PHY
317317
config NXP_C45_TJA11XX_PHY
318318
tristate "NXP C45 TJA11XX PHYs"
319319
depends on PTP_1588_CLOCK_OPTIONAL
320+
depends on MACSEC || !MACSEC
320321
help
321322
Enable support for NXP C45 TJA11XX PHYs.
322-
Currently supports the TJA1103 and TJA1120 PHYs.
323+
Currently supports the TJA1103, TJA1104 and TJA1120 PHYs.
323324

324325
config NXP_TJA11XX_PHY
325326
tristate "NXP TJA11xx PHYs support"

drivers/net/phy/Makefile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,11 @@ obj-$(CONFIG_MICROSEMI_PHY) += mscc/
8484
obj-$(CONFIG_MOTORCOMM_PHY) += motorcomm.o
8585
obj-$(CONFIG_NATIONAL_PHY) += national.o
8686
obj-$(CONFIG_NCN26000_PHY) += ncn26000.o
87-
obj-$(CONFIG_NXP_C45_TJA11XX_PHY) += nxp-c45-tja11xx.o
87+
nxp-c45-tja-objs += nxp-c45-tja11xx.o
88+
ifdef CONFIG_MACSEC
89+
nxp-c45-tja-objs += nxp-c45-tja11xx-macsec.o
90+
endif
91+
obj-$(CONFIG_NXP_C45_TJA11XX_PHY) += nxp-c45-tja.o
8892
obj-$(CONFIG_NXP_CBTX_PHY) += nxp-cbtx.o
8993
obj-$(CONFIG_NXP_TJA11XX_PHY) += nxp-tja11xx.o
9094
obj-$(CONFIG_QSEMI_PHY) += qsemi.o

0 commit comments

Comments
 (0)