| @@ -1469,6 +1469,11 @@ static struct net_device *get_dev_from_nl(struct net *net, · 1468 unmodified lines |
| 1469 | 1469 | return dev; |
| 1470 | 1470 | } |
| 1471 | 1471 | |
| 1472 | +static enum macsec_offload nla_get_offload(const struct nlattr *nla) |
| 1473 | +{ |
| 1474 | + return (__force enum macsec_offload)nla_get_u8(nla); |
| 1475 | +} |
| 1476 | + |
| 1472 | 1477 | static sci_t nla_get_sci(const struct nlattr *nla) |
| 1473 | 1478 | { |
| 1474 | 1479 | return (__force sci_t)nla_get_u64(nla); |
| @@ -4012,8 +4017,16 @@ static int macsec_newlink(struct net *net, struct net_device *dev, · 2537 unmodified lines |
| 4012 | 4017 | |
| 4013 | 4018 | macsec->real_dev = real_dev; |
| 4014 | 4019 | |
| 4015 | | − /* MACsec offloading is off by default */ |
| 4016 | | − macsec->offload = MACSEC_OFFLOAD_OFF; |
| 4020 | + if (data && data[IFLA_MACSEC_OFFLOAD]) |
| 4021 | + macsec->offload = nla_get_offload(data[IFLA_MACSEC_OFFLOAD]); |
| 4022 | + else |
| 4023 | + /* MACsec offloading is off by default */ |
| 4024 | + macsec->offload = MACSEC_OFFLOAD_OFF; |
| 4025 | + |
| 4026 | + /* Check if the offloading mode is supported by the underlying layers */ |
| 4027 | + if (macsec->offload != MACSEC_OFFLOAD_OFF && |
| 4028 | + !macsec_check_offload(macsec->offload, macsec)) |
| 4029 | + return -EOPNOTSUPP; |
| 4017 | 4030 | |
| 4018 | 4031 | if (data && data[IFLA_MACSEC_ICV_LEN]) |
| 4019 | 4032 | icv_len = nla_get_u8(data[IFLA_MACSEC_ICV_LEN]); |
| @@ -4056,6 +4069,20 @@ static int macsec_newlink(struct net *net, struct net_device *dev, · 36 unmodified lines |
| 4056 | 4069 | goto del_dev; |
| 4057 | 4070 | } |
| 4058 | 4071 | |
| 4072 | + /* If h/w offloading is available, propagate to the device */ |
| 4073 | + if (macsec_is_offloaded(macsec)) { |
| 4074 | + const struct macsec_ops *ops; |
| 4075 | + struct macsec_context ctx; |
| 4076 | + |
| 4077 | + ops = macsec_get_ops(macsec, &ctx); |
| 4078 | + if (ops) { |
| 4079 | + ctx.secy = &macsec->secy; |
| 4080 | + err = macsec_offload(ops->mdo_add_secy, &ctx); |
| 4081 | + if (err) |
| 4082 | + goto del_dev; |
| 4083 | + } |
| 4084 | + } |
| 4085 | + |
| 4059 | 4086 | err = register_macsec_dev(real_dev, dev); |
| 4060 | 4087 | if (err < 0) |
| 4061 | 4088 | goto del_dev; |