app/testpmd: add MACsec commands
authorTiwei Bie <tiwei.bie@intel.com>
Fri, 13 Jan 2017 11:21:40 +0000 (19:21 +0800)
committerThomas Monjalon <thomas.monjalon@6wind.com>
Sun, 15 Jan 2017 18:16:48 +0000 (19:16 +0100)
Below MACsec offload commands are added:

- set macsec offload <port_id> on encrypt on|off replay-protect on|off
- set macsec offload <port_id> off
- set macsec sc tx|rx <port_id> <mac> <pi>
- set macsec sa tx|rx <port_id> <idx> <an> <pn> <key>

Also update the testpmd user guide.

Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
Acked-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
app/test-pmd/cmdline.c
app/test-pmd/macfwd.c
app/test-pmd/macswap.c
app/test-pmd/testpmd.h
app/test-pmd/txonly.c
doc/guides/testpmd_app_ug/testpmd_funcs.rst

index f768b6b..1bf42ba 100644 (file)
@@ -275,6 +275,18 @@ static void cmd_help_long_parsed(void *parsed_result,
 
                        "set vf mac antispoof (port_id) (vf_id) (on|off).\n"
                        "    Set MAC antispoof for a VF from the PF.\n\n"
+
+                       "set macsec offload (port_id) on encrypt (on|off) replay-protect (on|off)\n"
+                       "    Enable MACsec offload.\n\n"
+
+                       "set macsec offload (port_id) off\n"
+                       "    Disable MACsec offload.\n\n"
+
+                       "set macsec sc (tx|rx) (port_id) (mac) (pi)\n"
+                       "    Configure MACsec secure connection (SC).\n\n"
+
+                       "set macsec sa (tx|rx) (port_id) (idx) (an) (pn) (key)\n"
+                       "    Configure MACsec secure association (SA).\n\n"
 #endif
 
                        "vlan set strip (on|off) (port_id)\n"
@@ -11488,6 +11500,379 @@ cmdline_parse_inst_t cmd_set_vf_mac_addr = {
                NULL,
        },
 };
+
+/* MACsec configuration */
+
+/* Common result structure for MACsec offload enable */
+struct cmd_macsec_offload_on_result {
+       cmdline_fixed_string_t set;
+       cmdline_fixed_string_t macsec;
+       cmdline_fixed_string_t offload;
+       uint8_t port_id;
+       cmdline_fixed_string_t on;
+       cmdline_fixed_string_t encrypt;
+       cmdline_fixed_string_t en_on_off;
+       cmdline_fixed_string_t replay_protect;
+       cmdline_fixed_string_t rp_on_off;
+};
+
+/* Common CLI fields for MACsec offload disable */
+cmdline_parse_token_string_t cmd_macsec_offload_on_set =
+       TOKEN_STRING_INITIALIZER
+               (struct cmd_macsec_offload_on_result,
+                set, "set");
+cmdline_parse_token_string_t cmd_macsec_offload_on_macsec =
+       TOKEN_STRING_INITIALIZER
+               (struct cmd_macsec_offload_on_result,
+                macsec, "macsec");
+cmdline_parse_token_string_t cmd_macsec_offload_on_offload =
+       TOKEN_STRING_INITIALIZER
+               (struct cmd_macsec_offload_on_result,
+                offload, "offload");
+cmdline_parse_token_num_t cmd_macsec_offload_on_port_id =
+       TOKEN_NUM_INITIALIZER
+               (struct cmd_macsec_offload_on_result,
+                port_id, UINT8);
+cmdline_parse_token_string_t cmd_macsec_offload_on_on =
+       TOKEN_STRING_INITIALIZER
+               (struct cmd_macsec_offload_on_result,
+                on, "on");
+cmdline_parse_token_string_t cmd_macsec_offload_on_encrypt =
+       TOKEN_STRING_INITIALIZER
+               (struct cmd_macsec_offload_on_result,
+                encrypt, "encrypt");
+cmdline_parse_token_string_t cmd_macsec_offload_on_en_on_off =
+       TOKEN_STRING_INITIALIZER
+               (struct cmd_macsec_offload_on_result,
+                en_on_off, "on#off");
+cmdline_parse_token_string_t cmd_macsec_offload_on_replay_protect =
+       TOKEN_STRING_INITIALIZER
+               (struct cmd_macsec_offload_on_result,
+                replay_protect, "replay-protect");
+cmdline_parse_token_string_t cmd_macsec_offload_on_rp_on_off =
+       TOKEN_STRING_INITIALIZER
+               (struct cmd_macsec_offload_on_result,
+                rp_on_off, "on#off");
+
+static void
+cmd_set_macsec_offload_on_parsed(
+       void *parsed_result,
+       __attribute__((unused)) struct cmdline *cl,
+       __attribute__((unused)) void *data)
+{
+       struct cmd_macsec_offload_on_result *res = parsed_result;
+       int ret;
+       portid_t port_id = res->port_id;
+       int en = (strcmp(res->en_on_off, "on") == 0) ? 1 : 0;
+       int rp = (strcmp(res->rp_on_off, "on") == 0) ? 1 : 0;
+
+       if (port_id_is_invalid(port_id, ENABLED_WARN))
+               return;
+
+       ports[port_id].tx_ol_flags |= TESTPMD_TX_OFFLOAD_MACSEC;
+       ret = rte_pmd_ixgbe_macsec_enable(port_id, en, rp);
+
+       switch (ret) {
+       case 0:
+               break;
+       case -ENODEV:
+               printf("invalid port_id %d\n", port_id);
+               break;
+       default:
+               printf("programming error: (%s)\n", strerror(-ret));
+       }
+}
+
+cmdline_parse_inst_t cmd_set_macsec_offload_on = {
+       .f = cmd_set_macsec_offload_on_parsed,
+       .data = NULL,
+       .help_str = "set macsec offload <port_id> on "
+               "encrypt on|off replay-protect on|off",
+       .tokens = {
+               (void *)&cmd_macsec_offload_on_set,
+               (void *)&cmd_macsec_offload_on_macsec,
+               (void *)&cmd_macsec_offload_on_offload,
+               (void *)&cmd_macsec_offload_on_port_id,
+               (void *)&cmd_macsec_offload_on_on,
+               (void *)&cmd_macsec_offload_on_encrypt,
+               (void *)&cmd_macsec_offload_on_en_on_off,
+               (void *)&cmd_macsec_offload_on_replay_protect,
+               (void *)&cmd_macsec_offload_on_rp_on_off,
+               NULL,
+       },
+};
+
+/* Common result structure for MACsec offload disable */
+struct cmd_macsec_offload_off_result {
+       cmdline_fixed_string_t set;
+       cmdline_fixed_string_t macsec;
+       cmdline_fixed_string_t offload;
+       uint8_t port_id;
+       cmdline_fixed_string_t off;
+};
+
+/* Common CLI fields for MACsec offload disable */
+cmdline_parse_token_string_t cmd_macsec_offload_off_set =
+       TOKEN_STRING_INITIALIZER
+               (struct cmd_macsec_offload_off_result,
+                set, "set");
+cmdline_parse_token_string_t cmd_macsec_offload_off_macsec =
+       TOKEN_STRING_INITIALIZER
+               (struct cmd_macsec_offload_off_result,
+                macsec, "macsec");
+cmdline_parse_token_string_t cmd_macsec_offload_off_offload =
+       TOKEN_STRING_INITIALIZER
+               (struct cmd_macsec_offload_off_result,
+                offload, "offload");
+cmdline_parse_token_num_t cmd_macsec_offload_off_port_id =
+       TOKEN_NUM_INITIALIZER
+               (struct cmd_macsec_offload_off_result,
+                port_id, UINT8);
+cmdline_parse_token_string_t cmd_macsec_offload_off_off =
+       TOKEN_STRING_INITIALIZER
+               (struct cmd_macsec_offload_off_result,
+                off, "off");
+
+static void
+cmd_set_macsec_offload_off_parsed(
+       void *parsed_result,
+       __attribute__((unused)) struct cmdline *cl,
+       __attribute__((unused)) void *data)
+{
+       struct cmd_macsec_offload_off_result *res = parsed_result;
+       int ret;
+       portid_t port_id = res->port_id;
+
+       if (port_id_is_invalid(port_id, ENABLED_WARN))
+               return;
+
+       ports[port_id].tx_ol_flags &= ~TESTPMD_TX_OFFLOAD_MACSEC;
+       ret = rte_pmd_ixgbe_macsec_disable(port_id);
+
+       switch (ret) {
+       case 0:
+               break;
+       case -ENODEV:
+               printf("invalid port_id %d\n", port_id);
+               break;
+       default:
+               printf("programming error: (%s)\n", strerror(-ret));
+       }
+}
+
+cmdline_parse_inst_t cmd_set_macsec_offload_off = {
+       .f = cmd_set_macsec_offload_off_parsed,
+       .data = NULL,
+       .help_str = "set macsec offload <port_id> off",
+       .tokens = {
+               (void *)&cmd_macsec_offload_off_set,
+               (void *)&cmd_macsec_offload_off_macsec,
+               (void *)&cmd_macsec_offload_off_offload,
+               (void *)&cmd_macsec_offload_off_port_id,
+               (void *)&cmd_macsec_offload_off_off,
+               NULL,
+       },
+};
+
+/* Common result structure for MACsec secure connection configure */
+struct cmd_macsec_sc_result {
+       cmdline_fixed_string_t set;
+       cmdline_fixed_string_t macsec;
+       cmdline_fixed_string_t sc;
+       cmdline_fixed_string_t tx_rx;
+       uint8_t port_id;
+       struct ether_addr mac;
+       uint16_t pi;
+};
+
+/* Common CLI fields for MACsec secure connection configure */
+cmdline_parse_token_string_t cmd_macsec_sc_set =
+       TOKEN_STRING_INITIALIZER
+               (struct cmd_macsec_sc_result,
+                set, "set");
+cmdline_parse_token_string_t cmd_macsec_sc_macsec =
+       TOKEN_STRING_INITIALIZER
+               (struct cmd_macsec_sc_result,
+                macsec, "macsec");
+cmdline_parse_token_string_t cmd_macsec_sc_sc =
+       TOKEN_STRING_INITIALIZER
+               (struct cmd_macsec_sc_result,
+                sc, "sc");
+cmdline_parse_token_string_t cmd_macsec_sc_tx_rx =
+       TOKEN_STRING_INITIALIZER
+               (struct cmd_macsec_sc_result,
+                tx_rx, "tx#rx");
+cmdline_parse_token_num_t cmd_macsec_sc_port_id =
+       TOKEN_NUM_INITIALIZER
+               (struct cmd_macsec_sc_result,
+                port_id, UINT8);
+cmdline_parse_token_etheraddr_t cmd_macsec_sc_mac =
+       TOKEN_ETHERADDR_INITIALIZER
+               (struct cmd_macsec_sc_result,
+                mac);
+cmdline_parse_token_num_t cmd_macsec_sc_pi =
+       TOKEN_NUM_INITIALIZER
+               (struct cmd_macsec_sc_result,
+                pi, UINT16);
+
+static void
+cmd_set_macsec_sc_parsed(
+       void *parsed_result,
+       __attribute__((unused)) struct cmdline *cl,
+       __attribute__((unused)) void *data)
+{
+       struct cmd_macsec_sc_result *res = parsed_result;
+       int ret;
+       int is_tx = (strcmp(res->tx_rx, "tx") == 0) ? 1 : 0;
+
+       ret = is_tx ?
+               rte_pmd_ixgbe_macsec_config_txsc(res->port_id,
+                               res->mac.addr_bytes) :
+               rte_pmd_ixgbe_macsec_config_rxsc(res->port_id,
+                               res->mac.addr_bytes, res->pi);
+       switch (ret) {
+       case 0:
+               break;
+       case -ENODEV:
+               printf("invalid port_id %d\n", res->port_id);
+               break;
+       default:
+               printf("programming error: (%s)\n", strerror(-ret));
+       }
+}
+
+cmdline_parse_inst_t cmd_set_macsec_sc = {
+       .f = cmd_set_macsec_sc_parsed,
+       .data = NULL,
+       .help_str = "set macsec sc tx|rx <port_id> <mac> <pi>",
+       .tokens = {
+               (void *)&cmd_macsec_sc_set,
+               (void *)&cmd_macsec_sc_macsec,
+               (void *)&cmd_macsec_sc_sc,
+               (void *)&cmd_macsec_sc_tx_rx,
+               (void *)&cmd_macsec_sc_port_id,
+               (void *)&cmd_macsec_sc_mac,
+               (void *)&cmd_macsec_sc_pi,
+               NULL,
+       },
+};
+
+/* Common result structure for MACsec secure connection configure */
+struct cmd_macsec_sa_result {
+       cmdline_fixed_string_t set;
+       cmdline_fixed_string_t macsec;
+       cmdline_fixed_string_t sa;
+       cmdline_fixed_string_t tx_rx;
+       uint8_t port_id;
+       uint8_t idx;
+       uint8_t an;
+       uint32_t pn;
+       cmdline_fixed_string_t key;
+};
+
+/* Common CLI fields for MACsec secure connection configure */
+cmdline_parse_token_string_t cmd_macsec_sa_set =
+       TOKEN_STRING_INITIALIZER
+               (struct cmd_macsec_sa_result,
+                set, "set");
+cmdline_parse_token_string_t cmd_macsec_sa_macsec =
+       TOKEN_STRING_INITIALIZER
+               (struct cmd_macsec_sa_result,
+                macsec, "macsec");
+cmdline_parse_token_string_t cmd_macsec_sa_sa =
+       TOKEN_STRING_INITIALIZER
+               (struct cmd_macsec_sa_result,
+                sa, "sa");
+cmdline_parse_token_string_t cmd_macsec_sa_tx_rx =
+       TOKEN_STRING_INITIALIZER
+               (struct cmd_macsec_sa_result,
+                tx_rx, "tx#rx");
+cmdline_parse_token_num_t cmd_macsec_sa_port_id =
+       TOKEN_NUM_INITIALIZER
+               (struct cmd_macsec_sa_result,
+                port_id, UINT8);
+cmdline_parse_token_num_t cmd_macsec_sa_idx =
+       TOKEN_NUM_INITIALIZER
+               (struct cmd_macsec_sa_result,
+                idx, UINT8);
+cmdline_parse_token_num_t cmd_macsec_sa_an =
+       TOKEN_NUM_INITIALIZER
+               (struct cmd_macsec_sa_result,
+                an, UINT8);
+cmdline_parse_token_num_t cmd_macsec_sa_pn =
+       TOKEN_NUM_INITIALIZER
+               (struct cmd_macsec_sa_result,
+                pn, UINT32);
+cmdline_parse_token_string_t cmd_macsec_sa_key =
+       TOKEN_STRING_INITIALIZER
+               (struct cmd_macsec_sa_result,
+                key, NULL);
+
+static void
+cmd_set_macsec_sa_parsed(
+       void *parsed_result,
+       __attribute__((unused)) struct cmdline *cl,
+       __attribute__((unused)) void *data)
+{
+       struct cmd_macsec_sa_result *res = parsed_result;
+       int ret;
+       int is_tx = (strcmp(res->tx_rx, "tx") == 0) ? 1 : 0;
+       uint8_t key[16] = { 0 };
+       uint8_t xdgt0;
+       uint8_t xdgt1;
+       int key_len;
+       int i;
+
+       key_len = strlen(res->key) / 2;
+       if (key_len > 16)
+               key_len = 16;
+
+       for (i = 0; i < key_len; i++) {
+               xdgt0 = parse_and_check_key_hexa_digit(res->key, (i * 2));
+               if (xdgt0 == 0xFF)
+                       return;
+               xdgt1 = parse_and_check_key_hexa_digit(res->key, (i * 2) + 1);
+               if (xdgt1 == 0xFF)
+                       return;
+               key[i] = (uint8_t) ((xdgt0 * 16) + xdgt1);
+       }
+
+       ret = is_tx ?
+               rte_pmd_ixgbe_macsec_select_txsa(res->port_id,
+                       res->idx, res->an, res->pn, key) :
+               rte_pmd_ixgbe_macsec_select_rxsa(res->port_id,
+                       res->idx, res->an, res->pn, key);
+       switch (ret) {
+       case 0:
+               break;
+       case -EINVAL:
+               printf("invalid idx %d or an %d\n", res->idx, res->an);
+               break;
+       case -ENODEV:
+               printf("invalid port_id %d\n", res->port_id);
+               break;
+       default:
+               printf("programming error: (%s)\n", strerror(-ret));
+       }
+}
+
+cmdline_parse_inst_t cmd_set_macsec_sa = {
+       .f = cmd_set_macsec_sa_parsed,
+       .data = NULL,
+       .help_str = "set macsec sa tx|rx <port_id> <idx> <an> <pn> <key>",
+       .tokens = {
+               (void *)&cmd_macsec_sa_set,
+               (void *)&cmd_macsec_sa_macsec,
+               (void *)&cmd_macsec_sa_sa,
+               (void *)&cmd_macsec_sa_tx_rx,
+               (void *)&cmd_macsec_sa_port_id,
+               (void *)&cmd_macsec_sa_idx,
+               (void *)&cmd_macsec_sa_an,
+               (void *)&cmd_macsec_sa_pn,
+               (void *)&cmd_macsec_sa_key,
+               NULL,
+       },
+};
 #endif
 
 /* ******************************************************************************** */
@@ -11656,6 +12041,10 @@ cmdline_parse_ctx_t main_ctx[] = {
        (cmdline_parse_inst_t *)&cmd_set_all_queues_drop_en,
        (cmdline_parse_inst_t *)&cmd_set_vf_split_drop_en,
        (cmdline_parse_inst_t *)&cmd_set_vf_mac_addr,
+       (cmdline_parse_inst_t *)&cmd_set_macsec_offload_on,
+       (cmdline_parse_inst_t *)&cmd_set_macsec_offload_off,
+       (cmdline_parse_inst_t *)&cmd_set_macsec_sc,
+       (cmdline_parse_inst_t *)&cmd_set_macsec_sa,
 #endif
        NULL,
 };
index d361db1..cf7eab1 100644 (file)
@@ -113,6 +113,8 @@ pkt_burst_mac_forward(struct fwd_stream *fs)
                ol_flags = PKT_TX_VLAN_PKT;
        if (txp->tx_ol_flags & TESTPMD_TX_OFFLOAD_INSERT_QINQ)
                ol_flags |= PKT_TX_QINQ_PKT;
+       if (txp->tx_ol_flags & TESTPMD_TX_OFFLOAD_MACSEC)
+               ol_flags |= PKT_TX_MACSEC;
        for (i = 0; i < nb_rx; i++) {
                if (likely(i < nb_rx - 1))
                        rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[i + 1],
index f996039..3a09351 100644 (file)
@@ -113,6 +113,8 @@ pkt_burst_mac_swap(struct fwd_stream *fs)
                ol_flags = PKT_TX_VLAN_PKT;
        if (txp->tx_ol_flags & TESTPMD_TX_OFFLOAD_INSERT_QINQ)
                ol_flags |= PKT_TX_QINQ_PKT;
+       if (txp->tx_ol_flags & TESTPMD_TX_OFFLOAD_MACSEC)
+               ol_flags |= PKT_TX_MACSEC;
        for (i = 0; i < nb_rx; i++) {
                if (likely(i < nb_rx - 1))
                        rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[i + 1],
index 22ce2d6..0a9a1af 100644 (file)
@@ -143,6 +143,8 @@ struct fwd_stream {
 #define TESTPMD_TX_OFFLOAD_INSERT_VLAN       0x0040
 /** Insert double VLAN header in forward engine */
 #define TESTPMD_TX_OFFLOAD_INSERT_QINQ       0x0080
+/** Offload MACsec in forward engine */
+#define TESTPMD_TX_OFFLOAD_MACSEC            0x0100
 
 /** Descriptor for a single flow. */
 struct port_flow {
index e996f35..8b1a2af 100644 (file)
@@ -215,6 +215,8 @@ pkt_burst_transmit(struct fwd_stream *fs)
                ol_flags = PKT_TX_VLAN_PKT;
        if (txp->tx_ol_flags & TESTPMD_TX_OFFLOAD_INSERT_QINQ)
                ol_flags |= PKT_TX_QINQ_PKT;
+       if (txp->tx_ol_flags & TESTPMD_TX_OFFLOAD_MACSEC)
+               ol_flags |= PKT_TX_MACSEC;
        for (nb_pkt = 0; nb_pkt < nb_pkt_per_burst; nb_pkt++) {
                pkt = rte_mbuf_raw_alloc(mbp);
                if (pkt == NULL) {
index c611dc5..e3222c0 100644 (file)
@@ -507,6 +507,38 @@ Set mac antispoof for a VF from the PF::
 
    testpmd> set vf mac antispoof  (port_id) (vf_id) (on|off)
 
+set macsec offload
+~~~~~~~~~~~~~~~~~~
+
+Enable/disable MACsec offload::
+
+   testpmd> set macsec offload (port_id) on encrypt (on|off) replay-protect (on|off)
+   testpmd> set macsec offload (port_id) off
+
+set macsec sc
+~~~~~~~~~~~~~
+
+Configure MACsec secure connection (SC)::
+
+   testpmd> set macsec sc (tx|rx) (port_id) (mac) (pi)
+
+.. note::
+
+   The pi argument is ignored for tx.
+   Check the NIC Datasheet for hardware limits.
+
+set macsec sa
+~~~~~~~~~~~~~
+
+Configure MACsec secure association (SA)::
+
+   testpmd> set macsec sa (tx|rx) (port_id) (idx) (an) (pn) (key)
+
+.. note::
+
+   The IDX value must be 0 or 1.
+   Check the NIC Datasheet for hardware limits.
+
 vlan set strip
 ~~~~~~~~~~~~~~