From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from EUR02-AM5-obe.outbound.protection.outlook.com (mail-eopbgr00069.outbound.protection.outlook.com [40.107.0.69]) by dpdk.org (Postfix) with ESMTP id 600595F2E for ; Tue, 16 Oct 2018 23:41:04 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=iY2x2x3MtG5W52aSonZ7A+nOa3m3nd2+J+XkSoj5zRQ=; b=GKqTrqdizwWu+3nj01I9Wz0IkuLqVbXSzPvXP42TG5EhnZOfr7KABxuhPB+sAkIs7KJzU67cEkQZJLa6KN5iieVgeRVmzyJbKWj6lGwKMtCqlnRtw/2hG9Ru1IRvCkkhQQ7EEhIT0J7ZxN64KbSJ8D2g5THxskh3Ni96+bABjk0= Received: from AM4PR05MB3425.eurprd05.prod.outlook.com (10.171.187.142) by AM4PR05MB3185.eurprd05.prod.outlook.com (10.171.186.26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1228.23; Tue, 16 Oct 2018 21:41:02 +0000 Received: from AM4PR05MB3425.eurprd05.prod.outlook.com ([fe80::fdeb:3890:f0f0:2202]) by AM4PR05MB3425.eurprd05.prod.outlook.com ([fe80::fdeb:3890:f0f0:2202%4]) with mapi id 15.20.1228.027; Tue, 16 Oct 2018 21:41:02 +0000 From: Ori Kam To: "wenzhuo.lu@intel.com" , "jingjing.wu@intel.com" , "bernard.iremonger@intel.com" , "arybchenko@solarflare.com" , "ferruh.yigit@intel.com" , "stephen@networkplumber.org" , Adrien Mazarguil CC: "dev@dpdk.org" , Dekel Peled , Thomas Monjalon , =?iso-8859-1?Q?N=E9lio_Laranjeiro?= , Yongseok Koh , Ori Kam , Shahaf Shuler Thread-Topic: [PATCH v4 2/3] app/testpmd: add MPLSoUDP encapsulation Thread-Index: AQHUZZjvadOLKP+Wlk2vzBu6GFf93Q== Date: Tue, 16 Oct 2018 21:41:02 +0000 Message-ID: <1539726023-14402-3-git-send-email-orika@mellanox.com> References: <1538917054-68283-1-git-send-email-orika@mellanox.com> <1539726023-14402-1-git-send-email-orika@mellanox.com> In-Reply-To: <1539726023-14402-1-git-send-email-orika@mellanox.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: DB6PR05CA0015.eurprd05.prod.outlook.com (2603:10a6:6:14::28) To AM4PR05MB3425.eurprd05.prod.outlook.com (2603:10a6:205:6::14) x-ms-exchange-messagesentrepresentingtype: 1 x-originating-ip: [37.142.13.130] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; AM4PR05MB3185; 6:eMaXOoEyXduq8nQbY7ziQ0jz2KN7VRGUVdHfHZz8mae6h/x+4TMDY0t8Ru/pOZ2XYaOQ7YhhO1c1/gu7ggzLJL6sP+Gy3PB82KY5o9p2O2AB/uJ0UUlAaU/SJJEYxRHPXQUBy4i12Hi6MvVkAl+HtWSz2zvBpE9RK+zjVsKEXu4wr/zegkwf31xA2ScybVFIiYDvZS9YgJx67s6okHYWyyCdkEyiCUfeQ1+OmHANZF1Fx6D+RopxtD9TMydSDaxA3wqtqC6R7ajtaa5km9zt+25l2lbQZafXwmSHZNbbKeowOIRiHA3v7BC1DIDpTPbIFP9z2q0UI/tZBcOPFbXEINwvCkOBpYAXinjOXYfjLh2cqWkkVfu+bnWf6tKD0X5uAi26VaHfnDk09Df69q96gRJqVhcY0tzAAeqimwfH/a5DkrBOiQvs6x1si/uL0/+ZjUIQGmO6AEX/TwnnivUxPQ==; 5:cm796gdz6AbGrqgraQR1SPYbUd5b49dThzfsBJSLbRY+XuOECHG+Dim6irnF/GkNb12xHvnfXt+H1hjn9wy4oHbZ+7ZpVcCN5O/0/b3xgA6H5Bz+rIOqfEkbACfCCZjj3HykbzbKb6ykjnAAKYL9ywyEZVKLzaLPa0ppdMkQDNs=; 7:OFFvq5K5bsEDITu1rJHP/aSte5ba9zVBcumQZWi8TFEU6FHNWdrUVgjBqRPbTmS58wXBQ/xXZ3KHeXNudUk9ZTr2xPJNbK0UGHl0nm86SljNjAV9Zr2uRrcMtwcSFZ5NB8r0MMVQu/QbI42MMKhwPtFKFAgIp6rUpATgydMo74rIChNCriMVQzEZgZGLvUJhQQ6mx+QYEbvGn1GXGxo3Wjh2ccbuKGO4gbGWGCqu1MuKA9++UqoDXrCBxbn4/Fzy x-ms-office365-filtering-correlation-id: 8e9b9edd-bf93-4662-5d33-08d633b01196 x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0; PCL:0; RULEID:(7020095)(4652040)(8989299)(5600074)(711020)(4618075)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(2017052603328)(7153060)(7193020); SRVR:AM4PR05MB3185; x-ms-traffictypediagnostic: AM4PR05MB3185: x-ld-processed: a652971c-7d2e-4d9b-a6a4-d149256f461b,ExtAddr x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:(17755550239193); x-ms-exchange-senderadcheck: 1 x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(8121501046)(5005006)(3002001)(3231355)(944501410)(52105095)(10201501046)(93006095)(93001095)(6055026)(149066)(150057)(6041310)(20161123560045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123564045)(20161123558120)(20161123562045)(201708071742011)(7699051)(76991076); SRVR:AM4PR05MB3185; BCL:0; PCL:0; RULEID:; SRVR:AM4PR05MB3185; x-forefront-prvs: 0827D7ACB9 x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(366004)(136003)(396003)(346002)(39860400002)(376002)(199004)(189003)(2900100001)(5250100002)(107886003)(71200400001)(3846002)(6116002)(476003)(16200700003)(53946003)(478600001)(53936002)(4744004)(2616005)(11346002)(446003)(4326008)(14444005)(102836004)(14454004)(6436002)(2906002)(256004)(6486002)(71190400001)(186003)(6346003)(26005)(6512007)(66066001)(76176011)(36756003)(110136005)(54906003)(305945005)(86362001)(7416002)(52116002)(2501003)(386003)(7736002)(6506007)(5660300001)(2201001)(68736007)(316002)(25786009)(97736004)(486006)(106356001)(81166006)(81156014)(8936002)(99286004)(8676002)(105586002)(569006); DIR:OUT; SFP:1101; SCL:1; SRVR:AM4PR05MB3185; H:AM4PR05MB3425.eurprd05.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; A:1; MX:1; received-spf: None (protection.outlook.com: mellanox.com does not designate permitted sender hosts) authentication-results: spf=none (sender IP is ) smtp.mailfrom=orika@mellanox.com; x-microsoft-antispam-message-info: Badw1jUmqJki/E4w1lyibCxsQVyri18Ea9E7dlMPC0H4mz0PL49IBps7TJTe6y/sSsoV0R4I+xdFvVI9jkJtjfH1FOl0WRIRQe4T3dU+7flAzgMM7qW3c1tjMNUw0fOXUAp2TVDSN52EbN76+Km8NsN8gI2EoltprQXPDG5yRzpcKVJAeZb4bbHVwopZkRDTsxG38589hoEzfFlG1se836Krk6QxfPhTLfbMeU8L4UhaqpYY1Vr34Gx+0Gqe232MwV/wUMmAnazGxKti7cHgd8xn0S/TM4kaCYaAyaNHQuM06j+Z6b1qc1wMc0n0Cpv9w/15QmB5GHh4z5voeHnLT8iF/TU+sda/e2oJUUrFZCI= spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-OriginatorOrg: Mellanox.com X-MS-Exchange-CrossTenant-Network-Message-Id: 8e9b9edd-bf93-4662-5d33-08d633b01196 X-MS-Exchange-CrossTenant-originalarrivaltime: 16 Oct 2018 21:41:02.6094 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: a652971c-7d2e-4d9b-a6a4-d149256f461b X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM4PR05MB3185 Subject: [dpdk-dev] [PATCH v4 2/3] app/testpmd: add MPLSoUDP encapsulation X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 16 Oct 2018 21:41:04 -0000 MPLSoUDP is an example for L3 tunnel encapsulation. L3 tunnel type is a tunnel that is missing the layer 2 header of the inner packet. Example for MPLSoUDP tunnel: ETH / IPV4 / UDP / MPLS / IP / L4..L7 In order to encapsulate such a tunnel there is a need to remove L2 of the inner packet and encap the remaining tunnel, this is done by applying 2 rte flow commands l2_decap followed by mplsoudp_encap. Both commands must appear in the same flow, and from the point of the packet it both actions are applyed at the same time. (There is no part where a packet doesn't have L2 header). Decapsulating such a tunnel works the other way, first we need to decap the outer tunnel header and then apply the new L2. So the commands will be mplsoudp_decap / l2_encap Due to the complex encapsulation of MPLSoUDP and L2 flow actions and based on the fact testpmd does not allocate memory, this patch adds a new command in testpmd to initialise a global structurs containing the necessary information to make the outer layer of the packet. This same global structures will then be used by the flow commands in testpmd when the action mplsoudp_encap, mplsoudp_decap, l2_encap, l2_decap, will be parsed, at this point, the conversion into such action becomes trivial. The l2_encap and l2_decap actions can also be used for other L3 tunnel types. Signed-off-by: Ori Kam --- app/test-pmd/cmdline.c | 410 ++++++++++++++++++++++++= ++++ app/test-pmd/cmdline_flow.c | 379 ++++++++++++++++++++++++= + app/test-pmd/testpmd.h | 40 +++ doc/guides/testpmd_app_ug/testpmd_funcs.rst | 175 ++++++++++++ 4 files changed, 1004 insertions(+) diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index 3b469ac..e807dbb 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -15282,6 +15282,408 @@ static void cmd_set_nvgre_parsed(void *parsed_res= ult, }, }; =20 +/** Set L2 encapsulation details */ +struct cmd_set_l2_encap_result { + cmdline_fixed_string_t set; + cmdline_fixed_string_t l2_encap; + cmdline_fixed_string_t pos_token; + cmdline_fixed_string_t ip_version; + uint32_t vlan_present:1; + uint16_t tci; + struct ether_addr eth_src; + struct ether_addr eth_dst; +}; + +cmdline_parse_token_string_t cmd_set_l2_encap_set =3D + TOKEN_STRING_INITIALIZER(struct cmd_set_l2_encap_result, set, "set"); +cmdline_parse_token_string_t cmd_set_l2_encap_l2_encap =3D + TOKEN_STRING_INITIALIZER(struct cmd_set_l2_encap_result, l2_encap, "l2_en= cap"); +cmdline_parse_token_string_t cmd_set_l2_encap_l2_encap_with_vlan =3D + TOKEN_STRING_INITIALIZER(struct cmd_set_l2_encap_result, l2_encap, + "l2_encap-with-vlan"); +cmdline_parse_token_string_t cmd_set_l2_encap_ip_version =3D + TOKEN_STRING_INITIALIZER(struct cmd_set_l2_encap_result, pos_token, + "ip-version"); +cmdline_parse_token_string_t cmd_set_l2_encap_ip_version_value =3D + TOKEN_STRING_INITIALIZER(struct cmd_set_l2_encap_result, ip_version, + "ipv4#ipv6"); +cmdline_parse_token_string_t cmd_set_l2_encap_vlan =3D + TOKEN_STRING_INITIALIZER(struct cmd_set_l2_encap_result, pos_token, + "vlan-tci"); +cmdline_parse_token_num_t cmd_set_l2_encap_vlan_value =3D + TOKEN_NUM_INITIALIZER(struct cmd_set_l2_encap_result, tci, UINT16); +cmdline_parse_token_string_t cmd_set_l2_encap_eth_src =3D + TOKEN_STRING_INITIALIZER(struct cmd_set_l2_encap_result, pos_token, + "eth-src"); +cmdline_parse_token_etheraddr_t cmd_set_l2_encap_eth_src_value =3D + TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_l2_encap_result, eth_src); +cmdline_parse_token_string_t cmd_set_l2_encap_eth_dst =3D + TOKEN_STRING_INITIALIZER(struct cmd_set_l2_encap_result, pos_token, + "eth-dst"); +cmdline_parse_token_etheraddr_t cmd_set_l2_encap_eth_dst_value =3D + TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_l2_encap_result, eth_dst); + +static void cmd_set_l2_encap_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_set_l2_encap_result *res =3D parsed_result; + + if (strcmp(res->l2_encap, "l2_encap") =3D=3D 0) + l2_encap_conf.select_vlan =3D 0; + else if (strcmp(res->l2_encap, "l2_encap-with-vlan") =3D=3D 0) + l2_encap_conf.select_vlan =3D 1; + if (strcmp(res->ip_version, "ipv4") =3D=3D 0) + l2_encap_conf.select_ipv4 =3D 1; + else if (strcmp(res->ip_version, "ipv6") =3D=3D 0) + l2_encap_conf.select_ipv4 =3D 0; + else + return; + if (l2_encap_conf.select_vlan) + l2_encap_conf.vlan_tci =3D rte_cpu_to_be_16(res->tci); + rte_memcpy(l2_encap_conf.eth_src, res->eth_src.addr_bytes, + ETHER_ADDR_LEN); + rte_memcpy(l2_encap_conf.eth_dst, res->eth_dst.addr_bytes, + ETHER_ADDR_LEN); +} + +cmdline_parse_inst_t cmd_set_l2_encap =3D { + .f =3D cmd_set_l2_encap_parsed, + .data =3D NULL, + .help_str =3D "set l2_encap ip-version ipv4|ipv6" + " eth-src eth-dst ", + .tokens =3D { + (void *)&cmd_set_l2_encap_set, + (void *)&cmd_set_l2_encap_l2_encap, + (void *)&cmd_set_l2_encap_ip_version, + (void *)&cmd_set_l2_encap_ip_version_value, + (void *)&cmd_set_l2_encap_eth_src, + (void *)&cmd_set_l2_encap_eth_src_value, + (void *)&cmd_set_l2_encap_eth_dst, + (void *)&cmd_set_l2_encap_eth_dst_value, + NULL, + }, +}; + +cmdline_parse_inst_t cmd_set_l2_encap_with_vlan =3D { + .f =3D cmd_set_l2_encap_parsed, + .data =3D NULL, + .help_str =3D "set l2_encap-with-vlan ip-version ipv4|ipv6" + " vlan-tci eth-src eth-dst ", + .tokens =3D { + (void *)&cmd_set_l2_encap_set, + (void *)&cmd_set_l2_encap_l2_encap_with_vlan, + (void *)&cmd_set_l2_encap_ip_version, + (void *)&cmd_set_l2_encap_ip_version_value, + (void *)&cmd_set_l2_encap_vlan, + (void *)&cmd_set_l2_encap_vlan_value, + (void *)&cmd_set_l2_encap_eth_src, + (void *)&cmd_set_l2_encap_eth_src_value, + (void *)&cmd_set_l2_encap_eth_dst, + (void *)&cmd_set_l2_encap_eth_dst_value, + NULL, + }, +}; + +/** Set L2 decapsulation details */ +struct cmd_set_l2_decap_result { + cmdline_fixed_string_t set; + cmdline_fixed_string_t l2_decap; + cmdline_fixed_string_t pos_token; + uint32_t vlan_present:1; +}; + +cmdline_parse_token_string_t cmd_set_l2_decap_set =3D + TOKEN_STRING_INITIALIZER(struct cmd_set_l2_decap_result, set, "set"); +cmdline_parse_token_string_t cmd_set_l2_decap_l2_decap =3D + TOKEN_STRING_INITIALIZER(struct cmd_set_l2_decap_result, l2_decap, + "l2_decap"); +cmdline_parse_token_string_t cmd_set_l2_decap_l2_decap_with_vlan =3D + TOKEN_STRING_INITIALIZER(struct cmd_set_l2_decap_result, l2_decap, + "l2_decap-with-vlan"); + +static void cmd_set_l2_decap_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_set_l2_decap_result *res =3D parsed_result; + + if (strcmp(res->l2_decap, "l2_decap") =3D=3D 0) + l2_decap_conf.select_vlan =3D 0; + else if (strcmp(res->l2_decap, "l2_decap-with-vlan") =3D=3D 0) + l2_decap_conf.select_vlan =3D 1; +} + +cmdline_parse_inst_t cmd_set_l2_decap =3D { + .f =3D cmd_set_l2_decap_parsed, + .data =3D NULL, + .help_str =3D "set l2_decap", + .tokens =3D { + (void *)&cmd_set_l2_decap_set, + (void *)&cmd_set_l2_decap_l2_decap, + NULL, + }, +}; + +cmdline_parse_inst_t cmd_set_l2_decap_with_vlan =3D { + .f =3D cmd_set_l2_decap_parsed, + .data =3D NULL, + .help_str =3D "set l2_decap-with-vlan", + .tokens =3D { + (void *)&cmd_set_l2_decap_set, + (void *)&cmd_set_l2_decap_l2_decap_with_vlan, + NULL, + }, +}; + +/** Set MPLSoUDP encapsulation details */ +struct cmd_set_mplsoudp_encap_result { + cmdline_fixed_string_t set; + cmdline_fixed_string_t mplsoudp; + cmdline_fixed_string_t pos_token; + cmdline_fixed_string_t ip_version; + uint32_t vlan_present:1; + uint32_t label; + uint16_t udp_src; + uint16_t udp_dst; + cmdline_ipaddr_t ip_src; + cmdline_ipaddr_t ip_dst; + uint16_t tci; + struct ether_addr eth_src; + struct ether_addr eth_dst; +}; + +cmdline_parse_token_string_t cmd_set_mplsoudp_encap_set =3D + TOKEN_STRING_INITIALIZER(struct cmd_set_mplsoudp_encap_result, set, + "set"); +cmdline_parse_token_string_t cmd_set_mplsoudp_encap_mplsoudp_encap =3D + TOKEN_STRING_INITIALIZER(struct cmd_set_mplsoudp_encap_result, mplsoudp, + "mplsoudp_encap"); +cmdline_parse_token_string_t cmd_set_mplsoudp_encap_mplsoudp_encap_with_vl= an =3D + TOKEN_STRING_INITIALIZER(struct cmd_set_mplsoudp_encap_result, + mplsoudp, "mplsoudp_encap-with-vlan"); +cmdline_parse_token_string_t cmd_set_mplsoudp_encap_ip_version =3D + TOKEN_STRING_INITIALIZER(struct cmd_set_mplsoudp_encap_result, + pos_token, "ip-version"); +cmdline_parse_token_string_t cmd_set_mplsoudp_encap_ip_version_value =3D + TOKEN_STRING_INITIALIZER(struct cmd_set_mplsoudp_encap_result, + ip_version, "ipv4#ipv6"); +cmdline_parse_token_string_t cmd_set_mplsoudp_encap_label =3D + TOKEN_STRING_INITIALIZER(struct cmd_set_mplsoudp_encap_result, + pos_token, "label"); +cmdline_parse_token_num_t cmd_set_mplsoudp_encap_label_value =3D + TOKEN_NUM_INITIALIZER(struct cmd_set_mplsoudp_encap_result, label, + UINT32); +cmdline_parse_token_string_t cmd_set_mplsoudp_encap_udp_src =3D + TOKEN_STRING_INITIALIZER(struct cmd_set_mplsoudp_encap_result, + pos_token, "udp-src"); +cmdline_parse_token_num_t cmd_set_mplsoudp_encap_udp_src_value =3D + TOKEN_NUM_INITIALIZER(struct cmd_set_mplsoudp_encap_result, udp_src, + UINT16); +cmdline_parse_token_string_t cmd_set_mplsoudp_encap_udp_dst =3D + TOKEN_STRING_INITIALIZER(struct cmd_set_mplsoudp_encap_result, + pos_token, "udp-dst"); +cmdline_parse_token_num_t cmd_set_mplsoudp_encap_udp_dst_value =3D + TOKEN_NUM_INITIALIZER(struct cmd_set_mplsoudp_encap_result, udp_dst, + UINT16); +cmdline_parse_token_string_t cmd_set_mplsoudp_encap_ip_src =3D + TOKEN_STRING_INITIALIZER(struct cmd_set_mplsoudp_encap_result, + pos_token, "ip-src"); +cmdline_parse_token_ipaddr_t cmd_set_mplsoudp_encap_ip_src_value =3D + TOKEN_IPADDR_INITIALIZER(struct cmd_set_mplsoudp_encap_result, ip_src); +cmdline_parse_token_string_t cmd_set_mplsoudp_encap_ip_dst =3D + TOKEN_STRING_INITIALIZER(struct cmd_set_mplsoudp_encap_result, + pos_token, "ip-dst"); +cmdline_parse_token_ipaddr_t cmd_set_mplsoudp_encap_ip_dst_value =3D + TOKEN_IPADDR_INITIALIZER(struct cmd_set_mplsoudp_encap_result, ip_dst); +cmdline_parse_token_string_t cmd_set_mplsoudp_encap_vlan =3D + TOKEN_STRING_INITIALIZER(struct cmd_set_mplsoudp_encap_result, + pos_token, "vlan-tci"); +cmdline_parse_token_num_t cmd_set_mplsoudp_encap_vlan_value =3D + TOKEN_NUM_INITIALIZER(struct cmd_set_mplsoudp_encap_result, tci, + UINT16); +cmdline_parse_token_string_t cmd_set_mplsoudp_encap_eth_src =3D + TOKEN_STRING_INITIALIZER(struct cmd_set_mplsoudp_encap_result, + pos_token, "eth-src"); +cmdline_parse_token_etheraddr_t cmd_set_mplsoudp_encap_eth_src_value =3D + TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_mplsoudp_encap_result, + eth_src); +cmdline_parse_token_string_t cmd_set_mplsoudp_encap_eth_dst =3D + TOKEN_STRING_INITIALIZER(struct cmd_set_mplsoudp_encap_result, + pos_token, "eth-dst"); +cmdline_parse_token_etheraddr_t cmd_set_mplsoudp_encap_eth_dst_value =3D + TOKEN_ETHERADDR_INITIALIZER(struct cmd_set_mplsoudp_encap_result, + eth_dst); + +static void cmd_set_mplsoudp_encap_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_set_mplsoudp_encap_result *res =3D parsed_result; + union { + uint32_t mplsoudp_label; + uint8_t label[3]; + } id =3D { + .mplsoudp_label =3D + rte_cpu_to_be_32(res->label) & RTE_BE32(0x00ffffff), + }; + + if (strcmp(res->mplsoudp, "mplsoudp_encap") =3D=3D 0) + mplsoudp_encap_conf.select_vlan =3D 0; + else if (strcmp(res->mplsoudp, "mplsoudp_encap-with-vlan") =3D=3D 0) + mplsoudp_encap_conf.select_vlan =3D 1; + if (strcmp(res->ip_version, "ipv4") =3D=3D 0) + mplsoudp_encap_conf.select_ipv4 =3D 1; + else if (strcmp(res->ip_version, "ipv6") =3D=3D 0) + mplsoudp_encap_conf.select_ipv4 =3D 0; + else + return; + rte_memcpy(mplsoudp_encap_conf.label, &id.label[1], 3); + mplsoudp_encap_conf.udp_src =3D rte_cpu_to_be_16(res->udp_src); + mplsoudp_encap_conf.udp_dst =3D rte_cpu_to_be_16(res->udp_dst); + if (mplsoudp_encap_conf.select_ipv4) { + IPV4_ADDR_TO_UINT(res->ip_src, mplsoudp_encap_conf.ipv4_src); + IPV4_ADDR_TO_UINT(res->ip_dst, mplsoudp_encap_conf.ipv4_dst); + } else { + IPV6_ADDR_TO_ARRAY(res->ip_src, mplsoudp_encap_conf.ipv6_src); + IPV6_ADDR_TO_ARRAY(res->ip_dst, mplsoudp_encap_conf.ipv6_dst); + } + if (mplsoudp_encap_conf.select_vlan) + mplsoudp_encap_conf.vlan_tci =3D rte_cpu_to_be_16(res->tci); + rte_memcpy(mplsoudp_encap_conf.eth_src, res->eth_src.addr_bytes, + ETHER_ADDR_LEN); + rte_memcpy(mplsoudp_encap_conf.eth_dst, res->eth_dst.addr_bytes, + ETHER_ADDR_LEN); +} + +cmdline_parse_inst_t cmd_set_mplsoudp_encap =3D { + .f =3D cmd_set_mplsoudp_encap_parsed, + .data =3D NULL, + .help_str =3D "set mplsoudp_encap ip-version ipv4|ipv6 label