#define NFP_NET_IPSEC_MAX_SA_CNT (16 * 1024) /* Firmware support a maximum of 16K SA offload */
/* IPsec config message cmd codes */ enum nfp_ipsec_cfg_mssg_cmd_codes {
NFP_IPSEC_CFG_MSSG_ADD_SA, /* Add a new SA */
NFP_IPSEC_CFG_MSSG_INV_SA /* Invalidate an existing SA */
};
ret = nfp_net_mbox_lock(nn, sizeof(*msg)); if (ret) return ret;
msg_size = ARRAY_SIZE(msg->raw); for (i = 0; i < msg_size; i++)
nn_writel(nn, offset + 4 * i, msg->raw[i]);
ret = nfp_net_mbox_reconfig(nn, entry->cmd); if (ret < 0) {
nn_ctrl_bar_unlock(nn); return ret;
}
/* For now we always read the whole message response back */ for (i = 0; i < msg_size; i++)
msg->raw[i] = nn_readl(nn, offset + 4 * i);
nn_ctrl_bar_unlock(nn);
switch (msg->rsp) { case NFP_IPSEC_CFG_MSSG_OK: return 0; case NFP_IPSEC_CFG_MSSG_SA_INVALID_CMD: return -EINVAL; case NFP_IPSEC_CFG_MSSG_SA_VALID: return -EEXIST; case NFP_IPSEC_CFG_MSSG_FAILED: case NFP_IPSEC_CFG_MSSG_SA_HASH_ADD_FAILED: case NFP_IPSEC_CFG_MSSG_SA_HASH_DEL_FAILED: return -EIO; default: return -EINVAL;
}
}
staticint set_aes_keylen(struct nfp_ipsec_cfg_add_sa *cfg, int alg, int keylen)
{ bool aes_gmac = (alg == SADB_X_EALG_NULL_AES_GMAC);
if (x->aalg) {
key_len = DIV_ROUND_UP(x->aalg->alg_key_len, BITS_PER_BYTE); if (key_len > sizeof(cfg->auth_key)) {
NL_SET_ERR_MSG_MOD(extack, "Insufficient space for offloaded auth key"); return -EINVAL;
} for (i = 0; i < key_len / sizeof(cfg->auth_key[0]) ; i++)
cfg->auth_key[i] = get_unaligned_be32(x->aalg->alg_key + sizeof(cfg->auth_key[0]) * i);
}
/* Encryption */ switch (x->props.ealgo) { case SADB_EALG_NONE: /* The xfrm descriptor for CHACAH20_POLY1305 does not set the algorithm id, which * is the default value SADB_EALG_NONE. In the branch of SADB_EALG_NONE, driver * uses algorithm name to identify CHACAH20_POLY1305's algorithm.
*/ if (x->aead && !strcmp(x->aead->alg_name, "rfc7539esp(chacha20,poly1305)")) { if (nn->pdev->device != PCI_DEVICE_ID_NFP3800) {
NL_SET_ERR_MSG_MOD(extack, "Unsupported encryption algorithm for offload"); return -EINVAL;
} if (x->aead->alg_icv_len != 128) {
NL_SET_ERR_MSG_MOD(extack, "ICV must be 128bit with CHACHA20_POLY1305"); return -EINVAL;
}
/* Aead->alg_key_len includes 32-bit salt */ if (x->aead->alg_key_len - 32 != 256) {
NL_SET_ERR_MSG_MOD(extack, "Unsupported CHACHA20 key length"); return -EINVAL;
}
/* The CHACHA20's mode is not configured */
cfg->ctrl_word.hash = NFP_IPSEC_HASH_POLY1305_128;
cfg->ctrl_word.cipher = NFP_IPSEC_CIPHER_CHACHA20; break;
}
fallthrough; case SADB_EALG_NULL:
cfg->ctrl_word.cimode = NFP_IPSEC_CIMODE_CBC;
cfg->ctrl_word.cipher = NFP_IPSEC_CIPHER_NULL; break; case SADB_EALG_3DESCBC: if (nn->pdev->device == PCI_DEVICE_ID_NFP3800) {
NL_SET_ERR_MSG_MOD(extack, "Unsupported encryption algorithm for offload"); return -EINVAL;
}
cfg->ctrl_word.cimode = NFP_IPSEC_CIMODE_CBC;
cfg->ctrl_word.cipher = NFP_IPSEC_CIPHER_3DES; break; case SADB_X_EALG_AES_GCM_ICV16: case SADB_X_EALG_NULL_AES_GMAC: if (!x->aead) {
NL_SET_ERR_MSG_MOD(extack, "Invalid AES key data"); return -EINVAL;
}
if (x->aead->alg_icv_len != 128) {
NL_SET_ERR_MSG_MOD(extack, "ICV must be 128bit with SADB_X_EALG_AES_GCM_ICV16"); return -EINVAL;
}
cfg->ctrl_word.cimode = NFP_IPSEC_CIMODE_CTR;
cfg->ctrl_word.hash = NFP_IPSEC_HASH_GF128_128;
/* Aead->alg_key_len includes 32-bit salt */ if (set_aes_keylen(cfg, x->props.ealgo, x->aead->alg_key_len - 32)) {
NL_SET_ERR_MSG_MOD(extack, "Unsupported AES key length"); return -EINVAL;
} break; case SADB_X_EALG_AESCBC:
cfg->ctrl_word.cimode = NFP_IPSEC_CIMODE_CBC; if (!x->ealg) {
NL_SET_ERR_MSG_MOD(extack, "Invalid AES key data"); return -EINVAL;
} if (set_aes_keylen(cfg, x->props.ealgo, x->ealg->alg_key_len) < 0) {
NL_SET_ERR_MSG_MOD(extack, "Unsupported AES key length"); return -EINVAL;
} break; default:
NL_SET_ERR_MSG_MOD(extack, "Unsupported encryption algorithm for offload"); return -EINVAL;
}
if (x->aead) { int key_offset = 0; int salt_len = 4;
nn = netdev_priv(dev);
err = nfp_net_sched_mbox_amsg_work(nn, NFP_NET_CFG_MBOX_CMD_IPSEC, &msg, sizeof(msg), nfp_net_ipsec_cfg); if (err)
nn_warn(nn, "Failed to invalidate SA in hardware\n");
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.