From patchwork Fri Apr 26 15:48:51 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Hemminger X-Patchwork-Id: 139706 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 2F0AA43F19; Fri, 26 Apr 2024 17:51:44 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 3E32443F02; Fri, 26 Apr 2024 17:51:38 +0200 (CEST) Received: from mail-pj1-f53.google.com (mail-pj1-f53.google.com [209.85.216.53]) by mails.dpdk.org (Postfix) with ESMTP id E177943EF6 for ; Fri, 26 Apr 2024 17:51:36 +0200 (CEST) Received: by mail-pj1-f53.google.com with SMTP id 98e67ed59e1d1-2ad8fb779d2so1977122a91.0 for ; Fri, 26 Apr 2024 08:51:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=networkplumber-org.20230601.gappssmtp.com; s=20230601; t=1714146696; x=1714751496; darn=dpdk.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=7f1jpsjVWf4Sbi1Y40mgWHyNBq/+dUu72ZYzE/peOtU=; b=ks1NprymLMjLy3rRlmnlCSaHphAdd1cDbmIJkNQukZO6Tv4Wdd4JFsXQm36cV8QY29 0IQ1d5n712DiMvtXlp8JZ685cPgzCyttF4FRYhmUZrQ2DQKHJBSUi3MuSGBtTx3LX0wx JMLKsJJ+joJf311Yoka0ppJkKJm8JxbfSS8ZaQidUEKfhsZWYH4ZcyVTYTH+aZkrp5bE nKU6m7VjjnZYqjRLIYBViVTg/zKeKmAGE6IMTowqu0BDgSZezwCIf0iYjE0EBasrO50s nocx/8E7qJZT1syzG6A0xZx05Z0/WDO9ClwaGJN0ziCfL1eMwUBqav3p1N6d88KzODQM dj5g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714146696; x=1714751496; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=7f1jpsjVWf4Sbi1Y40mgWHyNBq/+dUu72ZYzE/peOtU=; b=SbiBryZOcb0lvIxlqSdbI4MmWsqeJTceOkeTAqI3bWHX3Jc7WiLQRrn1NeweTNmd7T RZnrcUrFHgLPPUAmMbGaI5enzvB4x+4ezLqK4IG0Xc2J7EqjbHlZffHVNHObpkYzFG9L +Pp2SYbiAgj+KJmMFa2AKc7NXzVW3CKbK9nPmi2947RcI2cz8GKK8ABIbYr8o5hdYFB9 9mv3gdH4HG1Kzo8cLTLKjIpLNyuSmxkOEy9q2JR0gyZaViGe4xFHmiQQRp7JMPB3UsdJ dWulRnu033TztTap6STySN9LIpdOgtD2j7kVH1b0lboApMGcOwLyj2u7qehvwI5WMdOE 9/nA== X-Gm-Message-State: AOJu0Yxiaj/joI9I50TExaIj3c4cHYIEBatLv1Pgv2ViLiqxAfIxphC2 gj1rQQc1y9qC9b9JWgznpLSvDxra8kZ7asDTPBGQb1nVBdCs4BwYcnorN5A6kfWBsRRV1qL1g43 hDug= X-Google-Smtp-Source: AGHT+IGmqXfCWAipsbCYTJsAv3/UTY7i6WlnlL5tSU3qPrFb0CR7tpCsJ5w9HnEReVYPRB4jRLpYBw== X-Received: by 2002:a17:90b:88:b0:2a7:455d:82db with SMTP id bb8-20020a17090b008800b002a7455d82dbmr3135815pjb.36.1714146695557; Fri, 26 Apr 2024 08:51:35 -0700 (PDT) Received: from hermes.local (204-195-96-226.wavecable.com. [204.195.96.226]) by smtp.gmail.com with ESMTPSA id ns5-20020a17090b250500b002a5f44353d2sm16770978pjb.7.2024.04.26.08.51.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 26 Apr 2024 08:51:35 -0700 (PDT) From: Stephen Hemminger To: dev@dpdk.org Cc: Stephen Hemminger Subject: [PATCH v9 1/9] net/tap: do not duplicate fd's Date: Fri, 26 Apr 2024 08:48:51 -0700 Message-ID: <20240426155125.125910-2-stephen@networkplumber.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240426155125.125910-1-stephen@networkplumber.org> References: <20240130034925.44869-1-stephen@networkplumber.org> <20240426155125.125910-1-stephen@networkplumber.org> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org The TAP device can use same file descriptopr for both rx and tx queues. This allows up to 8 queues (versus 4) to be used with secondary process. Signed-off-by: Stephen Hemminger --- drivers/net/tap/rte_eth_tap.c | 197 +++++++++++++++------------------- drivers/net/tap/rte_eth_tap.h | 3 +- drivers/net/tap/tap_flow.c | 3 +- drivers/net/tap/tap_intr.c | 7 +- 4 files changed, 91 insertions(+), 119 deletions(-) diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c index 69d9da695b..38a1b2d825 100644 --- a/drivers/net/tap/rte_eth_tap.c +++ b/drivers/net/tap/rte_eth_tap.c @@ -124,8 +124,7 @@ enum ioctl_mode { /* Message header to synchronize queues via IPC */ struct ipc_queues { char port_name[RTE_DEV_NAME_MAX_LEN]; - int rxq_count; - int txq_count; + int q_count; /* * The file descriptors are in the dedicated part * of the Unix message to be translated by the kernel. @@ -446,7 +445,7 @@ pmd_rx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) uint16_t data_off = rte_pktmbuf_headroom(mbuf); int len; - len = readv(process_private->rxq_fds[rxq->queue_id], + len = readv(process_private->fds[rxq->queue_id], *rxq->iovecs, 1 + (rxq->rxmode->offloads & RTE_ETH_RX_OFFLOAD_SCATTER ? rxq->nb_rx_desc : 1)); @@ -643,7 +642,7 @@ tap_write_mbufs(struct tx_queue *txq, uint16_t num_mbufs, } /* copy the tx frame data */ - n = writev(process_private->txq_fds[txq->queue_id], iovecs, k); + n = writev(process_private->fds[txq->queue_id], iovecs, k); if (n <= 0) return -1; @@ -851,7 +850,6 @@ tap_mp_req_on_rxtx(struct rte_eth_dev *dev) struct rte_mp_msg msg; struct ipc_queues *request_param = (struct ipc_queues *)msg.param; int err; - int fd_iterator = 0; struct pmd_process_private *process_private = dev->process_private; int i; @@ -859,16 +857,13 @@ tap_mp_req_on_rxtx(struct rte_eth_dev *dev) strlcpy(msg.name, TAP_MP_REQ_START_RXTX, sizeof(msg.name)); strlcpy(request_param->port_name, dev->data->name, sizeof(request_param->port_name)); msg.len_param = sizeof(*request_param); - for (i = 0; i < dev->data->nb_tx_queues; i++) { - msg.fds[fd_iterator++] = process_private->txq_fds[i]; - msg.num_fds++; - request_param->txq_count++; - } - for (i = 0; i < dev->data->nb_rx_queues; i++) { - msg.fds[fd_iterator++] = process_private->rxq_fds[i]; - msg.num_fds++; - request_param->rxq_count++; - } + + /* rx and tx share file descriptors and nb_tx_queues == nb_rx_queues */ + for (i = 0; i < dev->data->nb_rx_queues; i++) + msg.fds[i] = process_private->fds[i]; + + request_param->q_count = dev->data->nb_rx_queues; + msg.num_fds = dev->data->nb_rx_queues; err = rte_mp_sendmsg(&msg); if (err < 0) { @@ -910,8 +905,6 @@ tap_mp_req_start_rxtx(const struct rte_mp_msg *request, __rte_unused const void struct rte_eth_dev *dev; const struct ipc_queues *request_param = (const struct ipc_queues *)request->param; - int fd_iterator; - int queue; struct pmd_process_private *process_private; dev = rte_eth_dev_get_by_name(request_param->port_name); @@ -920,14 +913,13 @@ tap_mp_req_start_rxtx(const struct rte_mp_msg *request, __rte_unused const void request_param->port_name); return -1; } + process_private = dev->process_private; - fd_iterator = 0; - TAP_LOG(DEBUG, "tap_attach rx_q:%d tx_q:%d\n", request_param->rxq_count, - request_param->txq_count); - for (queue = 0; queue < request_param->txq_count; queue++) - process_private->txq_fds[queue] = request->fds[fd_iterator++]; - for (queue = 0; queue < request_param->rxq_count; queue++) - process_private->rxq_fds[queue] = request->fds[fd_iterator++]; + TAP_LOG(DEBUG, "tap_attach q:%d\n", request_param->q_count); + + for (int q = 0; q < request_param->q_count; q++) + process_private->fds[q] = request->fds[q]; + return 0; } @@ -1121,7 +1113,6 @@ tap_dev_close(struct rte_eth_dev *dev) int i; struct pmd_internals *internals = dev->data->dev_private; struct pmd_process_private *process_private = dev->process_private; - struct rx_queue *rxq; if (rte_eal_process_type() != RTE_PROC_PRIMARY) { rte_free(dev->process_private); @@ -1141,19 +1132,18 @@ tap_dev_close(struct rte_eth_dev *dev) } for (i = 0; i < RTE_PMD_TAP_MAX_QUEUES; i++) { - if (process_private->rxq_fds[i] != -1) { - rxq = &internals->rxq[i]; - close(process_private->rxq_fds[i]); - process_private->rxq_fds[i] = -1; - tap_rxq_pool_free(rxq->pool); - rte_free(rxq->iovecs); - rxq->pool = NULL; - rxq->iovecs = NULL; - } - if (process_private->txq_fds[i] != -1) { - close(process_private->txq_fds[i]); - process_private->txq_fds[i] = -1; - } + struct rx_queue *rxq = &internals->rxq[i]; + + if (process_private->fds[i] == -1) + continue; + + close(process_private->fds[i]); + process_private->fds[i] = -1; + + tap_rxq_pool_free(rxq->pool); + rte_free(rxq->iovecs); + rxq->pool = NULL; + rxq->iovecs = NULL; } if (internals->remote_if_index) { @@ -1198,6 +1188,15 @@ tap_dev_close(struct rte_eth_dev *dev) return 0; } +static void +tap_queue_close(struct pmd_process_private *process_private, uint16_t qid) +{ + if (process_private->fds[qid] != -1) { + close(process_private->fds[qid]); + process_private->fds[qid] = -1; + } +} + static void tap_rx_queue_release(struct rte_eth_dev *dev, uint16_t qid) { @@ -1206,15 +1205,16 @@ tap_rx_queue_release(struct rte_eth_dev *dev, uint16_t qid) if (!rxq) return; + process_private = rte_eth_devices[rxq->in_port].process_private; - if (process_private->rxq_fds[rxq->queue_id] != -1) { - close(process_private->rxq_fds[rxq->queue_id]); - process_private->rxq_fds[rxq->queue_id] = -1; - tap_rxq_pool_free(rxq->pool); - rte_free(rxq->iovecs); - rxq->pool = NULL; - rxq->iovecs = NULL; - } + + tap_rxq_pool_free(rxq->pool); + rte_free(rxq->iovecs); + rxq->pool = NULL; + rxq->iovecs = NULL; + + if (dev->data->tx_queues[qid] == NULL) + tap_queue_close(process_private, qid); } static void @@ -1225,12 +1225,10 @@ tap_tx_queue_release(struct rte_eth_dev *dev, uint16_t qid) if (!txq) return; - process_private = rte_eth_devices[txq->out_port].process_private; - if (process_private->txq_fds[txq->queue_id] != -1) { - close(process_private->txq_fds[txq->queue_id]); - process_private->txq_fds[txq->queue_id] = -1; - } + process_private = rte_eth_devices[txq->out_port].process_private; + if (dev->data->rx_queues[qid] == NULL) + tap_queue_close(process_private, qid); } static int @@ -1482,52 +1480,34 @@ tap_setup_queue(struct rte_eth_dev *dev, uint16_t qid, int is_rx) { - int ret; - int *fd; - int *other_fd; - const char *dir; + int fd, ret; struct pmd_internals *pmd = dev->data->dev_private; struct pmd_process_private *process_private = dev->process_private; struct rx_queue *rx = &internals->rxq[qid]; struct tx_queue *tx = &internals->txq[qid]; - struct rte_gso_ctx *gso_ctx; + struct rte_gso_ctx *gso_ctx = NULL; + const char *dir = is_rx ? "rx" : "tx"; - if (is_rx) { - fd = &process_private->rxq_fds[qid]; - other_fd = &process_private->txq_fds[qid]; - dir = "rx"; - gso_ctx = NULL; - } else { - fd = &process_private->txq_fds[qid]; - other_fd = &process_private->rxq_fds[qid]; - dir = "tx"; + if (is_rx) gso_ctx = &tx->gso_ctx; - } - if (*fd != -1) { + + fd = process_private->fds[qid]; + if (fd != -1) { /* fd for this queue already exists */ TAP_LOG(DEBUG, "%s: fd %d for %s queue qid %d exists", - pmd->name, *fd, dir, qid); + pmd->name, fd, dir, qid); gso_ctx = NULL; - } else if (*other_fd != -1) { - /* Only other_fd exists. dup it */ - *fd = dup(*other_fd); - if (*fd < 0) { - *fd = -1; - TAP_LOG(ERR, "%s: dup() failed.", pmd->name); - return -1; - } - TAP_LOG(DEBUG, "%s: dup fd %d for %s queue qid %d (%d)", - pmd->name, *other_fd, dir, qid, *fd); } else { - /* Both RX and TX fds do not exist (equal -1). Create fd */ - *fd = tun_alloc(pmd, 0, 0); - if (*fd < 0) { - *fd = -1; /* restore original value */ + fd = tun_alloc(pmd, 0, 0); + if (fd < 0) { TAP_LOG(ERR, "%s: tun_alloc() failed.", pmd->name); return -1; } + TAP_LOG(DEBUG, "%s: add %s queue for qid %d fd %d", - pmd->name, dir, qid, *fd); + pmd->name, dir, qid, fd); + + process_private->fds[qid] = fd; } tx->mtu = &dev->data->mtu; @@ -1540,7 +1520,7 @@ tap_setup_queue(struct rte_eth_dev *dev, tx->type = pmd->type; - return *fd; + return fd; } static int @@ -1620,7 +1600,7 @@ tap_rx_queue_setup(struct rte_eth_dev *dev, TAP_LOG(DEBUG, " RX TUNTAP device name %s, qid %d on fd %d", internals->name, rx_queue_id, - process_private->rxq_fds[rx_queue_id]); + process_private->fds[rx_queue_id]); return 0; @@ -1664,7 +1644,7 @@ tap_tx_queue_setup(struct rte_eth_dev *dev, TAP_LOG(DEBUG, " TX TUNTAP device name %s, qid %d on fd %d csum %s", internals->name, tx_queue_id, - process_private->txq_fds[tx_queue_id], + process_private->fds[tx_queue_id], txq->csum ? "on" : "off"); return 0; @@ -2001,10 +1981,9 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, const char *tap_name, dev->intr_handle = pmd->intr_handle; /* Presetup the fds to -1 as being not valid */ - for (i = 0; i < RTE_PMD_TAP_MAX_QUEUES; i++) { - process_private->rxq_fds[i] = -1; - process_private->txq_fds[i] = -1; - } + for (i = 0; i < RTE_PMD_TAP_MAX_QUEUES; i++) + process_private->fds[i] = -1; + if (pmd->type == ETH_TUNTAP_TYPE_TAP) { if (rte_is_zero_ether_addr(mac_addr)) @@ -2332,7 +2311,6 @@ tap_mp_attach_queues(const char *port_name, struct rte_eth_dev *dev) struct ipc_queues *request_param = (struct ipc_queues *)request.param; struct ipc_queues *reply_param; struct pmd_process_private *process_private = dev->process_private; - int queue, fd_iterator; /* Prepare the request */ memset(&request, 0, sizeof(request)); @@ -2352,18 +2330,17 @@ tap_mp_attach_queues(const char *port_name, struct rte_eth_dev *dev) TAP_LOG(DEBUG, "Received IPC reply for %s", reply_param->port_name); /* Attach the queues from received file descriptors */ - if (reply_param->rxq_count + reply_param->txq_count != reply->num_fds) { + if (reply_param->q_count != reply->num_fds) { TAP_LOG(ERR, "Unexpected number of fds received"); return -1; } - dev->data->nb_rx_queues = reply_param->rxq_count; - dev->data->nb_tx_queues = reply_param->txq_count; - fd_iterator = 0; - for (queue = 0; queue < reply_param->rxq_count; queue++) - process_private->rxq_fds[queue] = reply->fds[fd_iterator++]; - for (queue = 0; queue < reply_param->txq_count; queue++) - process_private->txq_fds[queue] = reply->fds[fd_iterator++]; + dev->data->nb_rx_queues = reply_param->q_count; + dev->data->nb_tx_queues = reply_param->q_count; + + for (int q = 0; q < reply_param->q_count; q++) + process_private->fds[q] = reply->fds[q]; + free(reply); return 0; } @@ -2393,25 +2370,19 @@ tap_mp_sync_queues(const struct rte_mp_msg *request, const void *peer) /* Fill file descriptors for all queues */ reply.num_fds = 0; - reply_param->rxq_count = 0; - if (dev->data->nb_rx_queues + dev->data->nb_tx_queues > - RTE_MP_MAX_FD_NUM){ - TAP_LOG(ERR, "Number of rx/tx queues exceeds max number of fds"); + reply_param->q_count = 0; + + RTE_ASSERT(dev->data->nb_rx_queues == dev->data->nb_tx_queues); + if (dev->data->nb_rx_queues > RTE_MP_MAX_FD_NUM) { + TAP_LOG(ERR, "Number of rx/tx queues %u exceeds max number of fds %u", + dev->data->nb_rx_queues, RTE_MP_MAX_FD_NUM); return -1; } for (queue = 0; queue < dev->data->nb_rx_queues; queue++) { - reply.fds[reply.num_fds++] = process_private->rxq_fds[queue]; - reply_param->rxq_count++; - } - RTE_ASSERT(reply_param->rxq_count == dev->data->nb_rx_queues); - - reply_param->txq_count = 0; - for (queue = 0; queue < dev->data->nb_tx_queues; queue++) { - reply.fds[reply.num_fds++] = process_private->txq_fds[queue]; - reply_param->txq_count++; + reply.fds[reply.num_fds++] = process_private->fds[queue]; + reply_param->q_count++; } - RTE_ASSERT(reply_param->txq_count == dev->data->nb_tx_queues); /* Send reply */ strlcpy(reply.name, request->name, sizeof(reply.name)); diff --git a/drivers/net/tap/rte_eth_tap.h b/drivers/net/tap/rte_eth_tap.h index 5ac93f93e9..dc8201020b 100644 --- a/drivers/net/tap/rte_eth_tap.h +++ b/drivers/net/tap/rte_eth_tap.h @@ -96,8 +96,7 @@ struct pmd_internals { }; struct pmd_process_private { - int rxq_fds[RTE_PMD_TAP_MAX_QUEUES]; - int txq_fds[RTE_PMD_TAP_MAX_QUEUES]; + int fds[RTE_PMD_TAP_MAX_QUEUES]; }; /* tap_intr.c */ diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c index fa50fe45d7..a78fd50cd4 100644 --- a/drivers/net/tap/tap_flow.c +++ b/drivers/net/tap/tap_flow.c @@ -1595,8 +1595,9 @@ tap_flow_isolate(struct rte_eth_dev *dev, * If netdevice is there, setup appropriate flow rules immediately. * Otherwise it will be set when bringing up the netdevice (tun_alloc). */ - if (!process_private->rxq_fds[0]) + if (process_private->fds[0] == -1) return 0; + if (set) { struct rte_flow *remote_flow; diff --git a/drivers/net/tap/tap_intr.c b/drivers/net/tap/tap_intr.c index a9097def1a..1908f71f97 100644 --- a/drivers/net/tap/tap_intr.c +++ b/drivers/net/tap/tap_intr.c @@ -68,9 +68,11 @@ tap_rx_intr_vec_install(struct rte_eth_dev *dev) } for (i = 0; i < n; i++) { struct rx_queue *rxq = pmd->dev->data->rx_queues[i]; + int fd = process_private->fds[i]; /* Skip queues that cannot request interrupts. */ - if (!rxq || process_private->rxq_fds[i] == -1) { + if (!rxq || fd == -1) { + /* Use invalid intr_vec[] index to disable entry. */ /* Use invalid intr_vec[] index to disable entry. */ if (rte_intr_vec_list_index_set(intr_handle, i, RTE_INTR_VEC_RXTX_OFFSET + RTE_MAX_RXTX_INTR_VEC_ID)) @@ -80,8 +82,7 @@ tap_rx_intr_vec_install(struct rte_eth_dev *dev) if (rte_intr_vec_list_index_set(intr_handle, i, RTE_INTR_VEC_RXTX_OFFSET + count)) return -rte_errno; - if (rte_intr_efds_index_set(intr_handle, count, - process_private->rxq_fds[i])) + if (rte_intr_efds_index_set(intr_handle, count, fd)) return -rte_errno; count++; } From patchwork Fri Apr 26 15:48:52 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Hemminger X-Patchwork-Id: 139707 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 3ED8143F19; Fri, 26 Apr 2024 17:51:51 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 7C5F943EF8; Fri, 26 Apr 2024 17:51:41 +0200 (CEST) Received: from mail-pg1-f172.google.com (mail-pg1-f172.google.com [209.85.215.172]) by mails.dpdk.org (Postfix) with ESMTP id D9A8443F00 for ; Fri, 26 Apr 2024 17:51:37 +0200 (CEST) Received: by mail-pg1-f172.google.com with SMTP id 41be03b00d2f7-53fbf2c42bfso1584904a12.3 for ; Fri, 26 Apr 2024 08:51:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=networkplumber-org.20230601.gappssmtp.com; s=20230601; t=1714146697; x=1714751497; darn=dpdk.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=nQflKhToqXQy5/HFwbUg/VVDegoBYmRvbf0vhBIdcqA=; b=deEXkABRAw1K+Ajx33RM2pbdxmfcuEkeDYQn6CLFbPMVq8Tf2UJRfxyC1JYkadS2A7 LpPYzhqjM2xt4tUivS3tmgDadixzZwkh0j5Nb3X+ol1rqI5DtGLyIHDJbbiTaTmNtjfE 91B7tKDK+tICaGkSWq6cQB43F5i3W7zdAOrzvkL6JbVoTDMRXcrFdk53iGCMf61ZW/hG kpPj/UZlgqhOWKIVcPDM6VxT7h8WQCW2PfTUImZEiyaS8fINVIwPpnzxKAdbXXxH17cg O3+xPBJNBqCpC6SADH/avPrTlr97ohSxN0VEEy1EV7qIUmTUeHrjsPVDMPsjMrnIwp8h 1ifw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714146697; x=1714751497; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=nQflKhToqXQy5/HFwbUg/VVDegoBYmRvbf0vhBIdcqA=; b=ISTUXmrCesZQroEJ0LmbxcwQjTEscOfJf9nwo5Sia3fbZs1GYlm6o8qVtWiINpaiBc safmcQe3Y+I/+UkHxolyTZ3Z/qnIp77F6ERUIxScQtvfj/p5QSrBqpsRNF9XkmseShx/ bbfu+0crigyEepOQXiAIf1bg4BHOzJISsJ8v5PF9hTW3pUdPMzyuVnZffE25yLgFNOyf m7IyaUoA5jvepGGGRFFOt+bZE/lAEgmmOBZZrLrIkadDLxkDrAWvfwQRP7Pae/Q5yEzd Y73BtQkqadlNJej5VPzrcn9RvLVc34gnmAgxFGjJPiw9cu/RVCoMsI/K/SIqIlLez+jJ hK2Q== X-Gm-Message-State: AOJu0YxGT6WEmOwnYWgHSceacMxfChZAo7RWdZE3SJsSavfSoia1Dx0o /ExSpMhaGau+oJu3Bo3Mf/Z87KzpWsYuGo7diT09EUhp+nRvSoNmRziBwhkoiCrEh8SeJ6v98Cq zjQs= X-Google-Smtp-Source: AGHT+IHa8edXuW47WAdtjqKRo3Dv3U9BXOcMrvMct2DGwRYzyLdLkJc7e46qY3jjx/+4kqNgkdDtZw== X-Received: by 2002:a17:90a:bc89:b0:2a2:7a00:f101 with SMTP id x9-20020a17090abc8900b002a27a00f101mr3013338pjr.47.1714146697034; Fri, 26 Apr 2024 08:51:37 -0700 (PDT) Received: from hermes.local (204-195-96-226.wavecable.com. [204.195.96.226]) by smtp.gmail.com with ESMTPSA id ns5-20020a17090b250500b002a5f44353d2sm16770978pjb.7.2024.04.26.08.51.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 26 Apr 2024 08:51:35 -0700 (PDT) From: Stephen Hemminger To: dev@dpdk.org Cc: Stephen Hemminger Subject: [PATCH v9 2/9] net/tap: remove unused fields Date: Fri, 26 Apr 2024 08:48:52 -0700 Message-ID: <20240426155125.125910-3-stephen@networkplumber.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240426155125.125910-1-stephen@networkplumber.org> References: <20240130034925.44869-1-stephen@networkplumber.org> <20240426155125.125910-1-stephen@networkplumber.org> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org The driver doesn't support these other hash types, and there is no reason to implement these in future. The rss_flows list was set but never used. Signed-off-by: Stephen Hemminger --- drivers/net/tap/rte_eth_tap.h | 4 +--- drivers/net/tap/tap_flow.c | 1 - drivers/net/tap/tap_rss.h | 6 ------ 3 files changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/net/tap/rte_eth_tap.h b/drivers/net/tap/rte_eth_tap.h index dc8201020b..1bcf92ce80 100644 --- a/drivers/net/tap/rte_eth_tap.h +++ b/drivers/net/tap/rte_eth_tap.h @@ -77,14 +77,12 @@ struct pmd_internals { int ioctl_sock; /* socket for ioctl calls */ int nlsk_fd; /* Netlink socket fd */ int flow_isolate; /* 1 if flow isolation is enabled */ - int flower_support; /* 1 if kernel supports, else 0 */ - int flower_vlan_support; /* 1 if kernel supports, else 0 */ int rss_enabled; /* 1 if RSS is enabled, else 0 */ int persist; /* 1 if keep link up, else 0 */ /* implicit rules set when RSS is enabled */ int map_fd; /* BPF RSS map fd */ int bpf_fd[RTE_PMD_TAP_MAX_QUEUES];/* List of bpf fds per queue */ - LIST_HEAD(tap_rss_flows, rte_flow) rss_flows; + LIST_HEAD(tap_flows, rte_flow) flows; /* rte_flow rules */ /* implicit rte_flow rules set when a remote device is active */ LIST_HEAD(tap_implicit_flows, rte_flow) implicit_flows; diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c index a78fd50cd4..8fccd599f0 100644 --- a/drivers/net/tap/tap_flow.c +++ b/drivers/net/tap/tap_flow.c @@ -1958,7 +1958,6 @@ static int rss_enable(struct pmd_internals *pmd, errno, strerror(errno)); return err; } - LIST_INSERT_HEAD(&pmd->rss_flows, rss_flow, next); } pmd->rss_enabled = 1; diff --git a/drivers/net/tap/tap_rss.h b/drivers/net/tap/tap_rss.h index dff46a012f..8766ffc244 100644 --- a/drivers/net/tap/tap_rss.h +++ b/drivers/net/tap/tap_rss.h @@ -21,12 +21,6 @@ enum hash_field { HASH_FIELD_IPV4_L3_L4, /* IPv4 src/dst addr + L4 src/dst ports */ HASH_FIELD_IPV6_L3, /* IPv6 src/dst addr */ HASH_FIELD_IPV6_L3_L4, /* IPv6 src/dst addr + L4 src/dst ports */ - HASH_FIELD_L2_SRC, /* Ethernet src addr */ - HASH_FIELD_L2_DST, /* Ethernet dst addr */ - HASH_FIELD_L3_SRC, /* L3 src addr */ - HASH_FIELD_L3_DST, /* L3 dst addr */ - HASH_FIELD_L4_SRC, /* TCP/UDP src ports */ - HASH_FIELD_L4_DST, /* TCP/UDP dst ports */ }; struct rss_key { From patchwork Fri Apr 26 15:48:53 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Hemminger X-Patchwork-Id: 139708 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id EED1243F19; Fri, 26 Apr 2024 17:51:57 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 9DFC843F09; Fri, 26 Apr 2024 17:51:42 +0200 (CEST) Received: from mail-pg1-f179.google.com (mail-pg1-f179.google.com [209.85.215.179]) by mails.dpdk.org (Postfix) with ESMTP id B0D5B43F04 for ; Fri, 26 Apr 2024 17:51:38 +0200 (CEST) Received: by mail-pg1-f179.google.com with SMTP id 41be03b00d2f7-5e4f79007ffso1495968a12.2 for ; Fri, 26 Apr 2024 08:51:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=networkplumber-org.20230601.gappssmtp.com; s=20230601; t=1714146698; x=1714751498; darn=dpdk.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=QMpE4bJ02MY4VpUrTabgs0S4YJan2oEdqn4ZAnWdaHI=; b=oHxn2G2X7CzvK3MF7MNmyK5zfiqbUXdBrM/1Gl5/u0sczL7GXwShrqO7pdEZq0kAh2 24dmcElHXV2LqMYEyUAqeYIrvNwWhB63CBmfZMku6ozzCR2kQTbXqI2Af6KcyvcTXMnl MuO9b05usMqpzEtbLVEib0X41I9MlVFaXbSKhnC7DWoNphLcMv8x1oTJlGx59TlBXfTw 7ZlgzyBoO9qXuV7SgaHFC1NdoH17mLRkZxMeKhqoMLF8B5SSreufOT8NQfS4Fmv8sDyM LPI27XMEaoTZBb7yrA+Jqp+ep0gQTRto6iDXfsDgKNHifjiDqxNC4RYlmLKlJITDuhHc xTCg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714146698; x=1714751498; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=QMpE4bJ02MY4VpUrTabgs0S4YJan2oEdqn4ZAnWdaHI=; b=TfnrOF5pmqfG52/sfXWxYUBLBQJqfpvQvluqpsvG6L5zBU3SEjJErYt3/fwuTKwdOf ev/AKHW9sB5vXoKNCbMkcgz8QIkhyFN8SD2/e1hJyw/uxBkPFC8C3Z4PoU0rj85uNf20 6UCZIp3Q+O4Uo9Bdgj9lbqFofN7TZZa0Lg7yAhwv2qnHhHg2E2WiqSfqKu4zHN40l1BX HJRy4FfI5hlpBkiuDi7DD91GAle0OMvCJ8PFYFeMBB6FG3S/YmhfCivoCRSkZQ6CAk06 BpUx6kKVKgyPzzL39D8bYRbyCwYL+gAiNvehEkjm9m8lxWho3B04wUjqALtVSVCxVMFj 4nJQ== X-Gm-Message-State: AOJu0Yz7W8fHWOUZjRoMwADEes4pssEjjYcakb0nxOyHWBiUk6Lkp+KC HTC1iC05jGbNL1D1gEfJw/BamSd/J8wTVuOc8hQncRhMoyrIuODIoKQg2P2/1AaSWTuSlWx/5Rj 6W7k= X-Google-Smtp-Source: AGHT+IFAu5guFmqvzquEUDs7CISE9vpd5nEx/faH9tR0gp74v3hbluAMYOPaz6BUv3F/UX2TI5wPIA== X-Received: by 2002:a17:90a:4927:b0:2a5:c9b2:fb53 with SMTP id c36-20020a17090a492700b002a5c9b2fb53mr3165894pjh.40.1714146697928; Fri, 26 Apr 2024 08:51:37 -0700 (PDT) Received: from hermes.local (204-195-96-226.wavecable.com. [204.195.96.226]) by smtp.gmail.com with ESMTPSA id ns5-20020a17090b250500b002a5f44353d2sm16770978pjb.7.2024.04.26.08.51.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 26 Apr 2024 08:51:37 -0700 (PDT) From: Stephen Hemminger To: dev@dpdk.org Cc: Stephen Hemminger Subject: [PATCH v9 3/9] net/tap: validate and setup parameters for BPF RSS Date: Fri, 26 Apr 2024 08:48:53 -0700 Message-ID: <20240426155125.125910-4-stephen@networkplumber.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240426155125.125910-1-stephen@networkplumber.org> References: <20240130034925.44869-1-stephen@networkplumber.org> <20240426155125.125910-1-stephen@networkplumber.org> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org The flow RSS support via BPF was not using the key, or hash type parameters. Which is good because they were never properly setup. Fix the setup and validate the flow parameters, the BPF side gets fixed later. Signed-off-by: Stephen Hemminger --- drivers/net/tap/tap_flow.c | 65 +++++++++++++++++++++++++++++++++++--- drivers/net/tap/tap_rss.h | 5 ++- 2 files changed, 62 insertions(+), 8 deletions(-) diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c index 8fccd599f0..8cf64364a7 100644 --- a/drivers/net/tap/tap_flow.c +++ b/drivers/net/tap/tap_flow.c @@ -11,9 +11,11 @@ #include #include +#include #include #include #include + #include #include #include @@ -2061,6 +2063,21 @@ static int bpf_rss_key(enum bpf_rss_key_e cmd, __u32 *key_idx) return err; } + +/* Default RSS hash key also used by mlx devices */ +static const uint8_t rss_hash_default_key[] = { + 0x2c, 0xc6, 0x81, 0xd1, + 0x5b, 0xdb, 0xf4, 0xf7, + 0xfc, 0xa2, 0x83, 0x19, + 0xdb, 0x1a, 0x3e, 0x94, + 0x6b, 0x9e, 0x38, 0xd9, + 0x2c, 0x9c, 0x03, 0xd1, + 0xad, 0x99, 0x44, 0xa7, + 0xd9, 0x56, 0x3d, 0x59, + 0x06, 0x3c, 0x25, 0xf3, + 0xfc, 0x1f, 0xdc, 0x2a, +}; + /** * Add RSS hash calculations and queue selection * @@ -2079,11 +2096,11 @@ static int rss_add_actions(struct rte_flow *flow, struct pmd_internals *pmd, const struct rte_flow_action_rss *rss, struct rte_flow_error *error) { - /* 4096 is the maximum number of instructions for a BPF program */ + struct rss_key rss_entry = { }; + const uint8_t *key_in; + uint32_t hash_type = 0; unsigned int i; int err; - struct rss_key rss_entry = { .hash_fields = 0, - .key_size = 0 }; /* Check supported RSS features */ if (rss->func != RTE_ETH_HASH_FUNCTION_DEFAULT) @@ -2095,6 +2112,41 @@ static int rss_add_actions(struct rte_flow *flow, struct pmd_internals *pmd, (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, "a nonzero RSS encapsulation level is not supported"); + if (rss->queue_num == 0 || rss->queue_num >= TAP_MAX_QUEUES) + return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, + "invalid number of queues"); + + /* allow RSS key_len 0 in case of NULL (default) RSS key. */ + if (rss->key_len == 0) { + if (rss->key != NULL) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ACTION_CONF, + &rss->key_len, "RSS hash key length 0"); + key_in = rss_hash_default_key; + } else { + if (rss->key_len != TAP_RSS_HASH_KEY_SIZE) + return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, "RSS hash invalid key length"); + if (rss->key == NULL) + return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, "RSS hash key is NULL"); + key_in = rss->key; + } + + if (rss->types & TAP_RSS_HF_MASK) + return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, "RSS hash type not supported"); + + if (rss->types & (RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_NONFRAG_IPV4_TCP)) + hash_type |= RTE_BIT32(HASH_FIELD_IPV4_L3_L4); + else if (rss->types & (RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_FRAG_IPV4)) + hash_type |= RTE_BIT32(HASH_FIELD_IPV4_L3); + + if (rss->types & (RTE_ETH_RSS_NONFRAG_IPV6_UDP | RTE_ETH_RSS_NONFRAG_IPV6_TCP)) + hash_type |= RTE_BIT32(HASH_FIELD_IPV6_L3_L4); + else if (rss->types & (RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_FRAG_IPV6 | RTE_ETH_RSS_IPV6_EX)) + hash_type |= RTE_BIT32(HASH_FIELD_IPV6_L3); + /* Get a new map key for a new RSS rule */ err = bpf_rss_key(KEY_CMD_GET, &flow->key_idx); if (err < 0) { @@ -2109,8 +2161,11 @@ static int rss_add_actions(struct rte_flow *flow, struct pmd_internals *pmd, rss_entry.nb_queues = rss->queue_num; for (i = 0; i < rss->queue_num; i++) rss_entry.queues[i] = rss->queue[i]; - rss_entry.hash_fields = - (1 << HASH_FIELD_IPV4_L3_L4) | (1 << HASH_FIELD_IPV6_L3_L4); + + rss_entry.hash_fields = hash_type; + rte_convert_rss_key((const uint32_t *)key_in, (uint32_t *)rss_entry.key, + TAP_RSS_HASH_KEY_SIZE); + /* Add this RSS entry to map */ err = tap_flow_bpf_update_rss_elem(pmd->map_fd, diff --git a/drivers/net/tap/tap_rss.h b/drivers/net/tap/tap_rss.h index 8766ffc244..6009be7031 100644 --- a/drivers/net/tap/tap_rss.h +++ b/drivers/net/tap/tap_rss.h @@ -24,11 +24,10 @@ enum hash_field { }; struct rss_key { - __u8 key[128]; __u32 hash_fields; - __u32 key_size; - __u32 queues[TAP_MAX_QUEUES]; + __u8 key[TAP_RSS_HASH_KEY_SIZE]; __u32 nb_queues; + __u32 queues[TAP_MAX_QUEUES]; } __attribute__((packed)); #endif /* _TAP_RSS_H_ */ From patchwork Fri Apr 26 15:48:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Hemminger X-Patchwork-Id: 139709 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 763FD43F19; Fri, 26 Apr 2024 17:52:04 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id D1F1843F0F; Fri, 26 Apr 2024 17:51:43 +0200 (CEST) Received: from mail-pg1-f180.google.com (mail-pg1-f180.google.com [209.85.215.180]) by mails.dpdk.org (Postfix) with ESMTP id F16ED43EFB for ; Fri, 26 Apr 2024 17:51:39 +0200 (CEST) Received: by mail-pg1-f180.google.com with SMTP id 41be03b00d2f7-5ca29c131ebso1798764a12.0 for ; Fri, 26 Apr 2024 08:51:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=networkplumber-org.20230601.gappssmtp.com; s=20230601; t=1714146699; x=1714751499; darn=dpdk.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=RQOowVHJY5nWjRB4NAsO3F5OLozCuaQSZDzpoe/jvF0=; b=NOFAjBRb3UMXpKfsmiW9liJ9pIsazPcbpm0I68nmKY7yo4pmFkiKwG+0rA7tKhpPvA jr95LeAHv0tjUMDIySkDcKQhuyllAqXW7BCkyw3sUqVd58L3MRMxEsl9AbjKwJR7yRC1 3lYO1N+VIpcR/s/dx9oXarZ2g79TNKLqNBlvDC1rQ2OnetU38WkBwQB6aX6lXl6aN4Aa KunhTjWYBFNFIcDuUeEXsR7J7XNOpP1ke7c4LkpFD1w5JJokxNcdWVpmsBW7o5FYrKE9 sbMuqzpsem9IXW6AIM5MXRtMuJZz1KEB5SDATNh2p2r7tmy5jXT/pjZbjzhQAqqScbAW i8mw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714146699; x=1714751499; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=RQOowVHJY5nWjRB4NAsO3F5OLozCuaQSZDzpoe/jvF0=; b=e1JShZFPSlJWnA38BRWb5TjBw9yG6Mk3oxb43QHYg5NFlNStOA64Uu45FdPP+wxRyN L8d/rCIhg4rjH5iFexuTKF9KihQ5wbykXQsRgfJLsgya3wllBNquEUufhNr5oW11JZox r+DHDHaN4+Rp3IAaCGximfDaMpH1vn8duAeiz3lgdj2wvBH9I/mYmbaxg+QSvov9EE/h 3NCD7xCSeaiVyRZLOGMZk/bz9l/JbAJLBtJGl9xn1OQBbVwPylJAT8qQ/eJSkLyJfifz iq/pJD6Inzt3Fn4bNwqMy3C4gS+Cax0pwtG7ndpI1YZGEj3ZkyjFKsgeQoz/r9wPQhTz 1+IA== X-Gm-Message-State: AOJu0YwCBVn53AmJXkxkULYRtpMwTEogclwCza0dFfncx1nbPhKbHogS /Av87ivWqTay3Z5stU3YelKV+2lcmNn19TmqoQZalpthXNcqChMBLpvPUazVhixnLN1BQVvIgNc 6Bb8= X-Google-Smtp-Source: AGHT+IE2sOTtC+j2n+FQWLmSDKQm4COU4Jld1Aofqa39nOyel36YvfzTwxKIrnicB5/sXUfjIxTHoA== X-Received: by 2002:a17:90a:bb96:b0:2ad:e74a:f500 with SMTP id v22-20020a17090abb9600b002ade74af500mr2906958pjr.27.1714146698976; Fri, 26 Apr 2024 08:51:38 -0700 (PDT) Received: from hermes.local (204-195-96-226.wavecable.com. [204.195.96.226]) by smtp.gmail.com with ESMTPSA id ns5-20020a17090b250500b002a5f44353d2sm16770978pjb.7.2024.04.26.08.51.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 26 Apr 2024 08:51:38 -0700 (PDT) From: Stephen Hemminger To: dev@dpdk.org Cc: Stephen Hemminger Subject: [PATCH v9 4/9] net/tap: do not build flow support if header is out of date Date: Fri, 26 Apr 2024 08:48:54 -0700 Message-ID: <20240426155125.125910-5-stephen@networkplumber.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240426155125.125910-1-stephen@networkplumber.org> References: <20240130034925.44869-1-stephen@networkplumber.org> <20240426155125.125910-1-stephen@networkplumber.org> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org The proper place for finding bpf structures and functions is in linux/bpf.h. The original version was trying to workaround the case where the build environment was running on old pre BPF version of Glibc, but the target environment had BPF. Having own private (and divergent) version headers leads to future problems when BPF definitions evolve. If the build infrastructure is so old that TC flower is not supported, then the TAP device will build without any flow support. Signed-off-by: Stephen Hemminger --- drivers/net/tap/bpf/bpf_extract.py | 1 - drivers/net/tap/meson.build | 17 ++-- drivers/net/tap/rte_eth_tap.c | 38 +++++++-- drivers/net/tap/rte_eth_tap.h | 7 +- drivers/net/tap/tap_bpf.h | 121 ----------------------------- drivers/net/tap/tap_bpf_api.c | 20 +++-- drivers/net/tap/tap_bpf_insns.h | 2 - drivers/net/tap/tap_flow.c | 90 --------------------- 8 files changed, 60 insertions(+), 236 deletions(-) delete mode 100644 drivers/net/tap/tap_bpf.h diff --git a/drivers/net/tap/bpf/bpf_extract.py b/drivers/net/tap/bpf/bpf_extract.py index b630c42b80..73c4dafe4e 100644 --- a/drivers/net/tap/bpf/bpf_extract.py +++ b/drivers/net/tap/bpf/bpf_extract.py @@ -65,7 +65,6 @@ def write_header(out, source): print(f' * Auto-generated from {source}', file=out) print(" * This not the original source file. Do NOT edit it.", file=out) print(" */\n", file=out) - print("#include ", file=out) def main(): diff --git a/drivers/net/tap/meson.build b/drivers/net/tap/meson.build index 5099ccdff1..66647a1c62 100644 --- a/drivers/net/tap/meson.build +++ b/drivers/net/tap/meson.build @@ -7,13 +7,19 @@ if not is_linux endif sources = files( 'rte_eth_tap.c', - 'tap_bpf_api.c', - 'tap_flow.c', 'tap_intr.c', 'tap_netlink.c', - 'tap_tcmsgs.c', ) +if cc.has_header_symbol('linux/pkt_cls.h', 'TCA_FLOWER_ACT') + cflags += '-DHAVE_TCA_FLOWER' + sources += files( + 'tap_bpf_api.c', + 'tap_flow.c', + 'tap_tcmsgs.c', + ) +endif + deps = ['bus_vdev', 'gso', 'hash'] cflags += '-DTAP_MAX_QUEUES=16' @@ -23,12 +29,7 @@ cflags += '-DTAP_MAX_QUEUES=16' # "enum/define", "symbol to search" ] # args = [ - [ 'HAVE_TC_FLOWER', 'linux/pkt_cls.h', 'TCA_FLOWER_UNSPEC' ], - [ 'HAVE_TC_VLAN_ID', 'linux/pkt_cls.h', 'TCA_FLOWER_KEY_VLAN_PRIO' ], - [ 'HAVE_TC_BPF', 'linux/pkt_cls.h', 'TCA_BPF_UNSPEC' ], - [ 'HAVE_TC_BPF_FD', 'linux/pkt_cls.h', 'TCA_BPF_FD' ], [ 'HAVE_TC_ACT_BPF', 'linux/tc_act/tc_bpf.h', 'TCA_ACT_BPF_UNSPEC' ], - [ 'HAVE_TC_ACT_BPF_FD', 'linux/tc_act/tc_bpf.h', 'TCA_ACT_BPF_FD' ], ] config = configuration_data() foreach arg:args diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c index 38a1b2d825..3f4fe95a09 100644 --- a/drivers/net/tap/rte_eth_tap.c +++ b/drivers/net/tap/rte_eth_tap.c @@ -1124,12 +1124,15 @@ tap_dev_close(struct rte_eth_dev *dev) if (!internals->persist) tap_link_set_down(dev); + +#ifdef HAVE_TCA_FLOWER if (internals->nlsk_fd != -1) { tap_flow_flush(dev, NULL); tap_flow_implicit_flush(internals, NULL); tap_nl_final(internals->nlsk_fd); internals->nlsk_fd = -1; } +#endif for (i = 0; i < RTE_PMD_TAP_MAX_QUEUES; i++) { struct rx_queue *rxq = &internals->rxq[i]; @@ -1265,6 +1268,7 @@ tap_promisc_enable(struct rte_eth_dev *dev) if (ret != 0) return ret; +#ifdef HAVE_TCA_FLOWER if (pmd->remote_if_index && !pmd->flow_isolate) { dev->data->promiscuous = 1; ret = tap_flow_implicit_create(pmd, TAP_REMOTE_PROMISC); @@ -1278,7 +1282,7 @@ tap_promisc_enable(struct rte_eth_dev *dev) return ret; } } - +#endif return 0; } @@ -1293,6 +1297,7 @@ tap_promisc_disable(struct rte_eth_dev *dev) if (ret != 0) return ret; +#ifdef HAVE_TCA_FLOWER if (pmd->remote_if_index && !pmd->flow_isolate) { dev->data->promiscuous = 0; ret = tap_flow_implicit_destroy(pmd, TAP_REMOTE_PROMISC); @@ -1306,6 +1311,7 @@ tap_promisc_disable(struct rte_eth_dev *dev) return ret; } } +#endif return 0; } @@ -1321,6 +1327,7 @@ tap_allmulti_enable(struct rte_eth_dev *dev) if (ret != 0) return ret; +#ifdef HAVE_TCA_FLOWER if (pmd->remote_if_index && !pmd->flow_isolate) { dev->data->all_multicast = 1; ret = tap_flow_implicit_create(pmd, TAP_REMOTE_ALLMULTI); @@ -1334,6 +1341,7 @@ tap_allmulti_enable(struct rte_eth_dev *dev) return ret; } } +#endif return 0; } @@ -1349,6 +1357,7 @@ tap_allmulti_disable(struct rte_eth_dev *dev) if (ret != 0) return ret; +#ifdef HAVE_TCA_FLOWER if (pmd->remote_if_index && !pmd->flow_isolate) { dev->data->all_multicast = 0; ret = tap_flow_implicit_destroy(pmd, TAP_REMOTE_ALLMULTI); @@ -1362,6 +1371,7 @@ tap_allmulti_disable(struct rte_eth_dev *dev) return ret; } } +#endif return 0; } @@ -1407,6 +1417,8 @@ tap_mac_set(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr) if (ret < 0) return ret; rte_memcpy(&pmd->eth_addr, mac_addr, RTE_ETHER_ADDR_LEN); + +#ifdef HAVE_TCA_FLOWER if (pmd->remote_if_index && !pmd->flow_isolate) { /* Replace MAC redirection rule after a MAC change */ ret = tap_flow_implicit_destroy(pmd, TAP_REMOTE_LOCAL_MAC); @@ -1424,6 +1436,7 @@ tap_mac_set(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr) return ret; } } +#endif return 0; } @@ -1901,7 +1914,9 @@ static const struct eth_dev_ops ops = { .stats_reset = tap_stats_reset, .dev_supported_ptypes_get = tap_dev_supported_ptypes_get, .rss_hash_update = tap_rss_hash_update, +#ifdef HAVE_TCA_FLOWER .flow_ops_get = tap_dev_flow_ops_get, +#endif }; static int @@ -1941,7 +1956,9 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, const char *tap_name, strlcpy(pmd->name, tap_name, sizeof(pmd->name)); pmd->type = type; pmd->ka_fd = -1; +#ifdef HAVE_TCA_FLOWER pmd->nlsk_fd = -1; +#endif pmd->gso_ctx_mp = NULL; pmd->ioctl_sock = socket(AF_INET, SOCK_DGRAM, 0); @@ -2021,6 +2038,14 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, const char *tap_name, /* Make network device persist after application exit */ pmd->persist = persist; + pmd->if_index = if_nametoindex(pmd->name); + if (!pmd->if_index) { + TAP_LOG(ERR, "%s: failed to get if_index.", pmd->name); + goto disable_rte_flow; + } + + +#ifdef HAVE_TCA_FLOWER /* * Set up everything related to rte_flow: * - netlink socket @@ -2035,11 +2060,6 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, const char *tap_name, pmd->name); goto disable_rte_flow; } - pmd->if_index = if_nametoindex(pmd->name); - if (!pmd->if_index) { - TAP_LOG(ERR, "%s: failed to get if_index.", pmd->name); - goto disable_rte_flow; - } if (qdisc_create_multiq(pmd->nlsk_fd, pmd->if_index) < 0) { TAP_LOG(ERR, "%s: failed to create multiq qdisc.", pmd->name); @@ -2050,6 +2070,7 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, const char *tap_name, pmd->name); goto disable_rte_flow; } + LIST_INIT(&pmd->flows); if (strlen(remote_iface)) { @@ -2102,6 +2123,7 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, const char *tap_name, goto error_remote; } } +#endif rte_eth_dev_probing_finish(dev); return 0; @@ -2116,14 +2138,18 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, const char *tap_name, rte_eth_dev_probing_finish(dev); return 0; +#ifdef HAVE_TCA_FLOWER error_remote: TAP_LOG(ERR, " Can't set up remote feature: %s(%d)", strerror(errno), errno); tap_flow_implicit_flush(pmd, NULL); +#endif error_exit: +#ifdef HAVE_TCA_FLOWER if (pmd->nlsk_fd != -1) close(pmd->nlsk_fd); +#endif if (pmd->ka_fd != -1) close(pmd->ka_fd); if (pmd->ioctl_sock != -1) diff --git a/drivers/net/tap/rte_eth_tap.h b/drivers/net/tap/rte_eth_tap.h index 1bcf92ce80..af18b29090 100644 --- a/drivers/net/tap/rte_eth_tap.h +++ b/drivers/net/tap/rte_eth_tap.h @@ -16,6 +16,7 @@ #include #include #include + #include "tap_log.h" #ifdef IFF_MULTI_QUEUE @@ -70,15 +71,17 @@ struct pmd_internals { char remote_iface[RTE_ETH_NAME_MAX_LEN]; /* Remote netdevice name */ char name[RTE_ETH_NAME_MAX_LEN]; /* Internal Tap device name */ int type; /* Type field - TUN|TAP */ + int persist; /* 1 if keep link up, else 0 */ struct rte_ether_addr eth_addr; /* Mac address of the device port */ struct ifreq remote_initial_flags;/* Remote netdevice flags on init */ int remote_if_index; /* remote netdevice IF_INDEX */ int if_index; /* IF_INDEX for the port */ int ioctl_sock; /* socket for ioctl calls */ + +#ifdef HAVE_TCA_FLOWER int nlsk_fd; /* Netlink socket fd */ int flow_isolate; /* 1 if flow isolation is enabled */ int rss_enabled; /* 1 if RSS is enabled, else 0 */ - int persist; /* 1 if keep link up, else 0 */ /* implicit rules set when RSS is enabled */ int map_fd; /* BPF RSS map fd */ int bpf_fd[RTE_PMD_TAP_MAX_QUEUES];/* List of bpf fds per queue */ @@ -86,6 +89,8 @@ struct pmd_internals { LIST_HEAD(tap_flows, rte_flow) flows; /* rte_flow rules */ /* implicit rte_flow rules set when a remote device is active */ LIST_HEAD(tap_implicit_flows, rte_flow) implicit_flows; +#endif + struct rx_queue rxq[RTE_PMD_TAP_MAX_QUEUES]; /* List of RX queues */ struct tx_queue txq[RTE_PMD_TAP_MAX_QUEUES]; /* List of TX queues */ struct rte_intr_handle *intr_handle; /* LSC interrupt handle. */ diff --git a/drivers/net/tap/tap_bpf.h b/drivers/net/tap/tap_bpf.h deleted file mode 100644 index d8437927ef..0000000000 --- a/drivers/net/tap/tap_bpf.h +++ /dev/null @@ -1,121 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 - * Copyright 2017 Mellanox Technologies, Ltd - */ - -#ifndef __TAP_BPF_H__ -#define __TAP_BPF_H__ - -#include - -/* Do not #include since eBPF must compile on different - * distros which may include partial definitions for eBPF (while the - * kernel itself may support eBPF). Instead define here all that is needed - */ - -/* BPF_MAP_UPDATE_ELEM command flags */ -#define BPF_ANY 0 /* create a new element or update an existing */ - -/* BPF architecture instruction struct */ -struct bpf_insn { - __u8 code; - __u8 dst_reg:4; - __u8 src_reg:4; - __s16 off; - __s32 imm; /* immediate value */ -}; - -/* BPF program types */ -enum bpf_prog_type { - BPF_PROG_TYPE_UNSPEC, - BPF_PROG_TYPE_SOCKET_FILTER, - BPF_PROG_TYPE_KPROBE, - BPF_PROG_TYPE_SCHED_CLS, - BPF_PROG_TYPE_SCHED_ACT, -}; - -/* BPF commands types */ -enum bpf_cmd { - BPF_MAP_CREATE, - BPF_MAP_LOOKUP_ELEM, - BPF_MAP_UPDATE_ELEM, - BPF_MAP_DELETE_ELEM, - BPF_MAP_GET_NEXT_KEY, - BPF_PROG_LOAD, -}; - -/* BPF maps types */ -enum bpf_map_type { - BPF_MAP_TYPE_UNSPEC, - BPF_MAP_TYPE_HASH, -}; - -/* union of anonymous structs used with TAP BPF commands */ -union __rte_aligned(8) bpf_attr { - /* BPF_MAP_CREATE command */ - struct { - __u32 map_type; - __u32 key_size; - __u32 value_size; - __u32 max_entries; - __u32 map_flags; - __u32 inner_map_fd; - }; - - /* BPF_MAP_UPDATE_ELEM, BPF_MAP_DELETE_ELEM commands */ - struct { - __u32 map_fd; - __aligned_u64 key; - union { - __aligned_u64 value; - __aligned_u64 next_key; - }; - __u64 flags; - }; - - /* BPF_PROG_LOAD command */ - struct { - __u32 prog_type; - __u32 insn_cnt; - __aligned_u64 insns; - __aligned_u64 license; - __u32 log_level; - __u32 log_size; - __aligned_u64 log_buf; - __u32 kern_version; - __u32 prog_flags; - }; -}; - -#ifndef __NR_bpf -# if defined(__i386__) -# define __NR_bpf 357 -# elif defined(__x86_64__) -# define __NR_bpf 321 -# elif defined(__arm__) -# define __NR_bpf 386 -# elif defined(__aarch64__) -# define __NR_bpf 280 -# elif defined(__sparc__) -# define __NR_bpf 349 -# elif defined(__s390__) -# define __NR_bpf 351 -# elif defined(__powerpc__) -# define __NR_bpf 361 -# elif defined(__riscv) -# define __NR_bpf 280 -# elif defined(__loongarch__) -# define __NR_bpf 280 -# else -# error __NR_bpf not defined -# endif -#endif - -enum { - BPF_MAP_ID_KEY, - BPF_MAP_ID_SIMPLE, -}; - -static int bpf_load(enum bpf_prog_type type, const struct bpf_insn *insns, - size_t insns_cnt, const char *license); - -#endif /* __TAP_BPF_H__ */ diff --git a/drivers/net/tap/tap_bpf_api.c b/drivers/net/tap/tap_bpf_api.c index 15283f8917..9e05e2ddf1 100644 --- a/drivers/net/tap/tap_bpf_api.c +++ b/drivers/net/tap/tap_bpf_api.c @@ -2,19 +2,19 @@ * Copyright 2017 Mellanox Technologies, Ltd */ -#include -#include #include -#include +#include +#include -#include -#include #include #include -#include -#include + #include + +static int bpf_load(enum bpf_prog_type type, const struct bpf_insn *insns, + size_t insns_cnt, const char *license); + /** * Load BPF program (section cls_q) into the kernel and return a bpf fd * @@ -89,7 +89,13 @@ static inline __u64 ptr_to_u64(const void *ptr) static inline int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr, unsigned int size) { +#ifdef __NR_bpf return syscall(__NR_bpf, cmd, attr, size); +#else + TAP_LOG(ERR, "No bpf syscall, kernel headers too old?\n"); + errno = ENOSYS; + return -1; +#endif } /** diff --git a/drivers/net/tap/tap_bpf_insns.h b/drivers/net/tap/tap_bpf_insns.h index 53fa76c4e6..cdf2febf05 100644 --- a/drivers/net/tap/tap_bpf_insns.h +++ b/drivers/net/tap/tap_bpf_insns.h @@ -3,8 +3,6 @@ * This not the original source file. Do NOT edit it. */ -#include - static struct bpf_insn cls_q_insns[] = { {0x61, 2, 1, 52, 0x00000000}, {0x18, 3, 0, 0, 0xdeadbeef}, diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c index 8cf64364a7..5a5a4ea048 100644 --- a/drivers/net/tap/tap_flow.c +++ b/drivers/net/tap/tap_flow.c @@ -21,96 +21,6 @@ #include #include -#ifndef HAVE_TC_FLOWER -/* - * For kernels < 4.2, this enum is not defined. Runtime checks will be made to - * avoid sending TC messages the kernel cannot understand. - */ -enum { - TCA_FLOWER_UNSPEC, - TCA_FLOWER_CLASSID, - TCA_FLOWER_INDEV, - TCA_FLOWER_ACT, - TCA_FLOWER_KEY_ETH_DST, /* ETH_ALEN */ - TCA_FLOWER_KEY_ETH_DST_MASK, /* ETH_ALEN */ - TCA_FLOWER_KEY_ETH_SRC, /* ETH_ALEN */ - TCA_FLOWER_KEY_ETH_SRC_MASK, /* ETH_ALEN */ - TCA_FLOWER_KEY_ETH_TYPE, /* be16 */ - TCA_FLOWER_KEY_IP_PROTO, /* u8 */ - TCA_FLOWER_KEY_IPV4_SRC, /* be32 */ - TCA_FLOWER_KEY_IPV4_SRC_MASK, /* be32 */ - TCA_FLOWER_KEY_IPV4_DST, /* be32 */ - TCA_FLOWER_KEY_IPV4_DST_MASK, /* be32 */ - TCA_FLOWER_KEY_IPV6_SRC, /* struct in6_addr */ - TCA_FLOWER_KEY_IPV6_SRC_MASK, /* struct in6_addr */ - TCA_FLOWER_KEY_IPV6_DST, /* struct in6_addr */ - TCA_FLOWER_KEY_IPV6_DST_MASK, /* struct in6_addr */ - TCA_FLOWER_KEY_TCP_SRC, /* be16 */ - TCA_FLOWER_KEY_TCP_DST, /* be16 */ - TCA_FLOWER_KEY_UDP_SRC, /* be16 */ - TCA_FLOWER_KEY_UDP_DST, /* be16 */ -}; -#endif -#ifndef HAVE_TC_VLAN_ID -enum { - /* TCA_FLOWER_FLAGS, */ - TCA_FLOWER_KEY_VLAN_ID = TCA_FLOWER_KEY_UDP_DST + 2, /* be16 */ - TCA_FLOWER_KEY_VLAN_PRIO, /* u8 */ - TCA_FLOWER_KEY_VLAN_ETH_TYPE, /* be16 */ -}; -#endif -/* - * For kernels < 4.2 BPF related enums may not be defined. - * Runtime checks will be carried out to gracefully report on TC messages that - * are rejected by the kernel. Rejection reasons may be due to: - * 1. enum is not defined - * 2. enum is defined but kernel is not configured to support BPF system calls, - * BPF classifications or BPF actions. - */ -#ifndef HAVE_TC_BPF -enum { - TCA_BPF_UNSPEC, - TCA_BPF_ACT, - TCA_BPF_POLICE, - TCA_BPF_CLASSID, - TCA_BPF_OPS_LEN, - TCA_BPF_OPS, -}; -#endif -#ifndef HAVE_TC_BPF_FD -enum { - TCA_BPF_FD = TCA_BPF_OPS + 1, - TCA_BPF_NAME, -}; -#endif -#ifndef HAVE_TC_ACT_BPF -#define tc_gen \ - __u32 index; \ - __u32 capab; \ - int action; \ - int refcnt; \ - int bindcnt - -struct tc_act_bpf { - tc_gen; -}; - -enum { - TCA_ACT_BPF_UNSPEC, - TCA_ACT_BPF_TM, - TCA_ACT_BPF_PARMS, - TCA_ACT_BPF_OPS_LEN, - TCA_ACT_BPF_OPS, -}; - -#endif -#ifndef HAVE_TC_ACT_BPF_FD -enum { - TCA_ACT_BPF_FD = TCA_ACT_BPF_OPS + 1, - TCA_ACT_BPF_NAME, -}; -#endif - /* RSS key management */ enum bpf_rss_key_e { KEY_CMD_GET = 1, From patchwork Fri Apr 26 15:48:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Stephen Hemminger X-Patchwork-Id: 139710 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 731BA43F19; Fri, 26 Apr 2024 17:52:13 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 80BA543F1A; Fri, 26 Apr 2024 17:51:45 +0200 (CEST) Received: from mail-pj1-f53.google.com (mail-pj1-f53.google.com [209.85.216.53]) by mails.dpdk.org (Postfix) with ESMTP id 14C5F43EFB for ; Fri, 26 Apr 2024 17:51:41 +0200 (CEST) Received: by mail-pj1-f53.google.com with SMTP id 98e67ed59e1d1-2a2d82537efso1635914a91.2 for ; Fri, 26 Apr 2024 08:51:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=networkplumber-org.20230601.gappssmtp.com; s=20230601; t=1714146700; x=1714751500; darn=dpdk.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=38CZ4DWGHcOFCd2nCP00hPr47SsSpAChpDwZh8MAiuY=; b=0/ke6bhFPo1tv1A/wWwSCI8C7coq098h4VVg+C83uV8pN0MkNKrgmnF0ORz/SSmbXC G+jpFmWhXsnm+ohz/zUchOHUwEheJQRpEcIFnZWvThAp+Vn3+gmyGLleqDUbUGRWHZKo P8tJ8W/Q2AAVYks50RtqNICxjGQGWNw0W6ozaUfrc+JHf3esofj8c1j9Iwqv0SMJW/qD 0lH2MSxCs/ANGcafPytsO+S2r5gfc1dwrdFsJh630DiThSC9HNugbtO9Szy6lwsRosWn KaNo6oAcd662B97qM1LuACMJMf2UzM4l5L5XAaJlDu3Iuz5suQEhJJ6ppaG7CH/RVBks zHSA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714146700; x=1714751500; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=38CZ4DWGHcOFCd2nCP00hPr47SsSpAChpDwZh8MAiuY=; b=BjQOeWYrKU8Agywpu5k8DzsE8U7s6NF5mYca1gk7T1UDy7GrTaRR/Kpp9vP9txn6Z6 0wetSQtFgJnqYtXwJ1nb83/KO01bXg8IjmUNrUYD2jLL3lV6j1lnwbHQ7f9tbotTKt4o EiGZZAtU174lv8Vmuf96Z4PV2yRrHVuvlh+A+XGT7oHuOe1D5VjNmVGH9t4zeDcZnle2 ecOGkSQ2xWFGQF6ordIYkqHjyEnUX4rSV5CUJsZhccAqePi4BaRA4FW6J4CPMGa3CMym KKbbqrKWpyF0Lcm1stQF8s2mFZeoWoClxiuDhYXhAgcM4JljVk6XO5myDZmij/xNNaiP ZrgQ== X-Gm-Message-State: AOJu0YzLlCYIKo/OB5CaGNzITgNnmhuPcnGUMPtpZP3FJCdRDQx0Yk+W EcP0Y/NDRynp4Qu7mmO1sVxXxGO/2qtitcyaN7+yqlDjLsmPm0il5MD2TEgNJKUA7sVx4wIKhWq WR+o= X-Google-Smtp-Source: AGHT+IGuWOmR7UsAVEQV7zRh8NXrHYTDd/0tyJIGe8U8OS9T07DdX0cRIXnaWHHKdYANHJgF4PGREw== X-Received: by 2002:a17:90b:1988:b0:2ad:f257:a678 with SMTP id mv8-20020a17090b198800b002adf257a678mr3324699pjb.33.1714146699847; Fri, 26 Apr 2024 08:51:39 -0700 (PDT) Received: from hermes.local (204-195-96-226.wavecable.com. [204.195.96.226]) by smtp.gmail.com with ESMTPSA id ns5-20020a17090b250500b002a5f44353d2sm16770978pjb.7.2024.04.26.08.51.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 26 Apr 2024 08:51:39 -0700 (PDT) From: Stephen Hemminger To: dev@dpdk.org Cc: Stephen Hemminger Subject: [PATCH v9 5/9] net/tap: rewrite the RSS BPF program Date: Fri, 26 Apr 2024 08:48:55 -0700 Message-ID: <20240426155125.125910-6-stephen@networkplumber.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240426155125.125910-1-stephen@networkplumber.org> References: <20240130034925.44869-1-stephen@networkplumber.org> <20240426155125.125910-1-stephen@networkplumber.org> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Rewrite the BPF program used to do queue based RSS. Important changes: - uses newer BPF map format BTF - accepts key as parameter rather than constant default - can do L3 or L4 hashing - supports IPv4 options - supports IPv6 extension headers - restructured for readability The usage of BPF is different as well: - the incoming configuration is looked up based on class parameters rather than patching the BPF. - the resulting queue is placed in skb rather than requiring a second pass through classifier step. Note: This version only works with later patch to enable it on the DPDK driver side. It is submitted as an incremental patch to allow for easier review. Bisection still works because the old instruction are still present for now. Signed-off-by: Stephen Hemminger --- .gitignore | 3 - drivers/net/tap/bpf/Makefile | 19 -- drivers/net/tap/bpf/README | 38 ++++ drivers/net/tap/bpf/bpf_api.h | 276 -------------------------- drivers/net/tap/bpf/bpf_elf.h | 53 ----- drivers/net/tap/bpf/bpf_extract.py | 85 -------- drivers/net/tap/bpf/meson.build | 81 ++++++++ drivers/net/tap/bpf/tap_bpf_program.c | 255 ------------------------ drivers/net/tap/bpf/tap_rss.c | 264 ++++++++++++++++++++++++ 9 files changed, 383 insertions(+), 691 deletions(-) delete mode 100644 drivers/net/tap/bpf/Makefile create mode 100644 drivers/net/tap/bpf/README delete mode 100644 drivers/net/tap/bpf/bpf_api.h delete mode 100644 drivers/net/tap/bpf/bpf_elf.h delete mode 100644 drivers/net/tap/bpf/bpf_extract.py create mode 100644 drivers/net/tap/bpf/meson.build delete mode 100644 drivers/net/tap/bpf/tap_bpf_program.c create mode 100644 drivers/net/tap/bpf/tap_rss.c diff --git a/.gitignore b/.gitignore index 3f444dcace..01a47a7606 100644 --- a/.gitignore +++ b/.gitignore @@ -36,9 +36,6 @@ TAGS # ignore python bytecode files *.pyc -# ignore BPF programs -drivers/net/tap/bpf/tap_bpf_program.o - # DTS results dts/output diff --git a/drivers/net/tap/bpf/Makefile b/drivers/net/tap/bpf/Makefile deleted file mode 100644 index 9efeeb1bc7..0000000000 --- a/drivers/net/tap/bpf/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -# SPDX-License-Identifier: BSD-3-Clause -# This file is not built as part of normal DPDK build. -# It is used to generate the eBPF code for TAP RSS. - -CLANG=clang -CLANG_OPTS=-O2 -TARGET=../tap_bpf_insns.h - -all: $(TARGET) - -clean: - rm tap_bpf_program.o $(TARGET) - -tap_bpf_program.o: tap_bpf_program.c - $(CLANG) $(CLANG_OPTS) -emit-llvm -c $< -o - | \ - llc -march=bpf -filetype=obj -o $@ - -$(TARGET): tap_bpf_program.o - python3 bpf_extract.py -stap_bpf_program.c -o $@ $< diff --git a/drivers/net/tap/bpf/README b/drivers/net/tap/bpf/README new file mode 100644 index 0000000000..1d421ff42c --- /dev/null +++ b/drivers/net/tap/bpf/README @@ -0,0 +1,38 @@ +This is the BPF program used to implement the RSS across queues flow action. +The program is loaded when first RSS flow rule is created and is never unloaded. + +Each flow rule creates a unique key (handle) and this is used as the key +for finding the RSS information for that flow rule. + +This version is built the BPF Compile Once — Run Everywhere (CO-RE) +framework and uses libbpf and bpftool. + +Limitations +----------- +- requires libbpf to run +- rebuilding the BPF requires Clang and bpftool. + Some older versions of Ubuntu do not have working bpftool package. + Need a version of Clang that can compile to BPF. +- only standard Toeplitz hash with standard 40 byte key is supported +- the number of flow rules using RSS is limited to 32 + +Building +-------- +During the DPDK build process the meson build file checks that +libbpf, bpftool, and clang are not available. If everything is +there then BPF RSS is enabled. + +1. Using clang to compile tap_rss.c the tap_rss.bpf.o file. + +2. Using bpftool generate a skeleton header file tap_rss.skel.h from tap_rss.bpf.o. + This skeleton header is an large byte array which contains the + BPF binary and wrappers to load and use it. + +3. The tap flow code then compiles that BPF byte array into the PMD object. + +4. When needed the BPF array is loaded by libbpf. + +References +---------- +BPF and XDP reference guide +https://docs.cilium.io/en/latest/bpf/progtypes/ diff --git a/drivers/net/tap/bpf/bpf_api.h b/drivers/net/tap/bpf/bpf_api.h deleted file mode 100644 index 4cd25fa593..0000000000 --- a/drivers/net/tap/bpf/bpf_api.h +++ /dev/null @@ -1,276 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */ - -#ifndef __BPF_API__ -#define __BPF_API__ - -/* Note: - * - * This file can be included into eBPF kernel programs. It contains - * a couple of useful helper functions, map/section ABI (bpf_elf.h), - * misc macros and some eBPF specific LLVM built-ins. - */ - -#include - -#include -#include -#include - -#include - -#include "bpf_elf.h" - -/** libbpf pin type. */ -enum libbpf_pin_type { - LIBBPF_PIN_NONE, - /* PIN_BY_NAME: pin maps by name (in /sys/fs/bpf by default) */ - LIBBPF_PIN_BY_NAME, -}; - -/** Type helper macros. */ - -#define __uint(name, val) int (*name)[val] -#define __type(name, val) typeof(val) *name -#define __array(name, val) typeof(val) *name[] - -/** Misc macros. */ - -#ifndef __stringify -# define __stringify(X) #X -#endif - -#ifndef __maybe_unused -# define __maybe_unused __attribute__((__unused__)) -#endif - -#ifndef offsetof -# define offsetof(TYPE, MEMBER) __builtin_offsetof(TYPE, MEMBER) -#endif - -#ifndef likely -# define likely(X) __builtin_expect(!!(X), 1) -#endif - -#ifndef unlikely -# define unlikely(X) __builtin_expect(!!(X), 0) -#endif - -#ifndef htons -# define htons(X) __constant_htons((X)) -#endif - -#ifndef ntohs -# define ntohs(X) __constant_ntohs((X)) -#endif - -#ifndef htonl -# define htonl(X) __constant_htonl((X)) -#endif - -#ifndef ntohl -# define ntohl(X) __constant_ntohl((X)) -#endif - -#ifndef __inline__ -# define __inline__ __attribute__((always_inline)) -#endif - -/** Section helper macros. */ - -#ifndef __section -# define __section(NAME) \ - __attribute__((section(NAME), used)) -#endif - -#ifndef __section_tail -# define __section_tail(ID, KEY) \ - __section(__stringify(ID) "/" __stringify(KEY)) -#endif - -#ifndef __section_xdp_entry -# define __section_xdp_entry \ - __section(ELF_SECTION_PROG) -#endif - -#ifndef __section_cls_entry -# define __section_cls_entry \ - __section(ELF_SECTION_CLASSIFIER) -#endif - -#ifndef __section_act_entry -# define __section_act_entry \ - __section(ELF_SECTION_ACTION) -#endif - -#ifndef __section_lwt_entry -# define __section_lwt_entry \ - __section(ELF_SECTION_PROG) -#endif - -#ifndef __section_license -# define __section_license \ - __section(ELF_SECTION_LICENSE) -#endif - -#ifndef __section_maps -# define __section_maps \ - __section(ELF_SECTION_MAPS) -#endif - -/** Declaration helper macros. */ - -#ifndef BPF_LICENSE -# define BPF_LICENSE(NAME) \ - char ____license[] __section_license = NAME -#endif - -/** Classifier helper */ - -#ifndef BPF_H_DEFAULT -# define BPF_H_DEFAULT -1 -#endif - -/** BPF helper functions for tc. Individual flags are in linux/bpf.h */ - -#ifndef __BPF_FUNC -# define __BPF_FUNC(NAME, ...) \ - (* NAME)(__VA_ARGS__) __maybe_unused -#endif - -#ifndef BPF_FUNC -# define BPF_FUNC(NAME, ...) \ - __BPF_FUNC(NAME, __VA_ARGS__) = (void *) BPF_FUNC_##NAME -#endif - -/* Map access/manipulation */ -static void *BPF_FUNC(map_lookup_elem, void *map, const void *key); -static int BPF_FUNC(map_update_elem, void *map, const void *key, - const void *value, uint32_t flags); -static int BPF_FUNC(map_delete_elem, void *map, const void *key); - -/* Time access */ -static uint64_t BPF_FUNC(ktime_get_ns); - -/* Debugging */ - -/* FIXME: __attribute__ ((format(printf, 1, 3))) not possible unless - * llvm bug https://llvm.org/bugs/show_bug.cgi?id=26243 gets resolved. - * It would require ____fmt to be made const, which generates a reloc - * entry (non-map). - */ -static void BPF_FUNC(trace_printk, const char *fmt, int fmt_size, ...); - -#ifndef printt -# define printt(fmt, ...) \ - __extension__ ({ \ - char ____fmt[] = fmt; \ - trace_printk(____fmt, sizeof(____fmt), ##__VA_ARGS__); \ - }) -#endif - -/* Random numbers */ -static uint32_t BPF_FUNC(get_prandom_u32); - -/* Tail calls */ -static void BPF_FUNC(tail_call, struct __sk_buff *skb, void *map, - uint32_t index); - -/* System helpers */ -static uint32_t BPF_FUNC(get_smp_processor_id); -static uint32_t BPF_FUNC(get_numa_node_id); - -/* Packet misc meta data */ -static uint32_t BPF_FUNC(get_cgroup_classid, struct __sk_buff *skb); -static int BPF_FUNC(skb_under_cgroup, void *map, uint32_t index); - -static uint32_t BPF_FUNC(get_route_realm, struct __sk_buff *skb); -static uint32_t BPF_FUNC(get_hash_recalc, struct __sk_buff *skb); -static uint32_t BPF_FUNC(set_hash_invalid, struct __sk_buff *skb); - -/* Packet redirection */ -static int BPF_FUNC(redirect, int ifindex, uint32_t flags); -static int BPF_FUNC(clone_redirect, struct __sk_buff *skb, int ifindex, - uint32_t flags); - -/* Packet manipulation */ -static int BPF_FUNC(skb_load_bytes, struct __sk_buff *skb, uint32_t off, - void *to, uint32_t len); -static int BPF_FUNC(skb_store_bytes, struct __sk_buff *skb, uint32_t off, - const void *from, uint32_t len, uint32_t flags); - -static int BPF_FUNC(l3_csum_replace, struct __sk_buff *skb, uint32_t off, - uint32_t from, uint32_t to, uint32_t flags); -static int BPF_FUNC(l4_csum_replace, struct __sk_buff *skb, uint32_t off, - uint32_t from, uint32_t to, uint32_t flags); -static int BPF_FUNC(csum_diff, const void *from, uint32_t from_size, - const void *to, uint32_t to_size, uint32_t seed); -static int BPF_FUNC(csum_update, struct __sk_buff *skb, uint32_t wsum); - -static int BPF_FUNC(skb_change_type, struct __sk_buff *skb, uint32_t type); -static int BPF_FUNC(skb_change_proto, struct __sk_buff *skb, uint32_t proto, - uint32_t flags); -static int BPF_FUNC(skb_change_tail, struct __sk_buff *skb, uint32_t nlen, - uint32_t flags); - -static int BPF_FUNC(skb_pull_data, struct __sk_buff *skb, uint32_t len); - -/* Event notification */ -static int __BPF_FUNC(skb_event_output, struct __sk_buff *skb, void *map, - uint64_t index, const void *data, uint32_t size) = - (void *) BPF_FUNC_perf_event_output; - -/* Packet vlan encap/decap */ -static int BPF_FUNC(skb_vlan_push, struct __sk_buff *skb, uint16_t proto, - uint16_t vlan_tci); -static int BPF_FUNC(skb_vlan_pop, struct __sk_buff *skb); - -/* Packet tunnel encap/decap */ -static int BPF_FUNC(skb_get_tunnel_key, struct __sk_buff *skb, - struct bpf_tunnel_key *to, uint32_t size, uint32_t flags); -static int BPF_FUNC(skb_set_tunnel_key, struct __sk_buff *skb, - const struct bpf_tunnel_key *from, uint32_t size, - uint32_t flags); - -static int BPF_FUNC(skb_get_tunnel_opt, struct __sk_buff *skb, - void *to, uint32_t size); -static int BPF_FUNC(skb_set_tunnel_opt, struct __sk_buff *skb, - const void *from, uint32_t size); - -/** LLVM built-ins, mem*() routines work for constant size */ - -#ifndef lock_xadd -# define lock_xadd(ptr, val) ((void) __sync_fetch_and_add(ptr, val)) -#endif - -#ifndef memset -# define memset(s, c, n) __builtin_memset((s), (c), (n)) -#endif - -#ifndef memcpy -# define memcpy(d, s, n) __builtin_memcpy((d), (s), (n)) -#endif - -#ifndef memmove -# define memmove(d, s, n) __builtin_memmove((d), (s), (n)) -#endif - -/* FIXME: __builtin_memcmp() is not yet fully usable unless llvm bug - * https://llvm.org/bugs/show_bug.cgi?id=26218 gets resolved. Also - * this one would generate a reloc entry (non-map), otherwise. - */ -#if 0 -#ifndef memcmp -# define memcmp(a, b, n) __builtin_memcmp((a), (b), (n)) -#endif -#endif - -unsigned long long load_byte(void *skb, unsigned long long off) - asm ("llvm.bpf.load.byte"); - -unsigned long long load_half(void *skb, unsigned long long off) - asm ("llvm.bpf.load.half"); - -unsigned long long load_word(void *skb, unsigned long long off) - asm ("llvm.bpf.load.word"); - -#endif /* __BPF_API__ */ diff --git a/drivers/net/tap/bpf/bpf_elf.h b/drivers/net/tap/bpf/bpf_elf.h deleted file mode 100644 index ea8a11c95c..0000000000 --- a/drivers/net/tap/bpf/bpf_elf.h +++ /dev/null @@ -1,53 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */ -#ifndef __BPF_ELF__ -#define __BPF_ELF__ - -#include - -/* Note: - * - * Below ELF section names and bpf_elf_map structure definition - * are not (!) kernel ABI. It's rather a "contract" between the - * application and the BPF loader in tc. For compatibility, the - * section names should stay as-is. Introduction of aliases, if - * needed, are a possibility, though. - */ - -/* ELF section names, etc */ -#define ELF_SECTION_LICENSE "license" -#define ELF_SECTION_MAPS "maps" -#define ELF_SECTION_PROG "prog" -#define ELF_SECTION_CLASSIFIER "classifier" -#define ELF_SECTION_ACTION "action" - -#define ELF_MAX_MAPS 64 -#define ELF_MAX_LICENSE_LEN 128 - -/* Object pinning settings */ -#define PIN_NONE 0 -#define PIN_OBJECT_NS 1 -#define PIN_GLOBAL_NS 2 - -/* ELF map definition */ -struct bpf_elf_map { - __u32 type; - __u32 size_key; - __u32 size_value; - __u32 max_elem; - __u32 flags; - __u32 id; - __u32 pinning; - __u32 inner_id; - __u32 inner_idx; -}; - -#define BPF_ANNOTATE_KV_PAIR(name, type_key, type_val) \ - struct ____btf_map_##name { \ - type_key key; \ - type_val value; \ - }; \ - struct ____btf_map_##name \ - __attribute__ ((section(".maps." #name), used)) \ - ____btf_map_##name = { } - -#endif /* __BPF_ELF__ */ diff --git a/drivers/net/tap/bpf/bpf_extract.py b/drivers/net/tap/bpf/bpf_extract.py deleted file mode 100644 index 73c4dafe4e..0000000000 --- a/drivers/net/tap/bpf/bpf_extract.py +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env python3 -# SPDX-License-Identifier: BSD-3-Clause -# Copyright (c) 2023 Stephen Hemminger - -import argparse -import sys -import struct -from tempfile import TemporaryFile -from elftools.elf.elffile import ELFFile - - -def load_sections(elffile): - """Get sections of interest from ELF""" - result = [] - parts = [("cls_q", "cls_q_insns"), ("l3_l4", "l3_l4_hash_insns")] - for name, tag in parts: - section = elffile.get_section_by_name(name) - if section: - insns = struct.iter_unpack('> 4 - dst = bpf[1] & 0xf - off = bpf[2] - imm = bpf[3] - print(f'\t{{{code:#04x}, {dst:4d}, {src:4d}, {off:8d}, {imm:#010x}}},', - file=out) - print('};', file=out) - - -def parse_args(): - """Parse command line arguments""" - parser = argparse.ArgumentParser() - parser.add_argument('-s', - '--source', - type=str, - help="original source file") - parser.add_argument('-o', '--out', type=str, help="output C file path") - parser.add_argument("file", - nargs='+', - help="object file path or '-' for stdin") - return parser.parse_args() - - -def open_input(path): - """Open the file or stdin""" - if path == "-": - temp = TemporaryFile() - temp.write(sys.stdin.buffer.read()) - return temp - return open(path, 'rb') - - -def write_header(out, source): - """Write file intro header""" - print("/* SPDX-License-Identifier: BSD-3-Clause", file=out) - if source: - print(f' * Auto-generated from {source}', file=out) - print(" * This not the original source file. Do NOT edit it.", file=out) - print(" */\n", file=out) - - -def main(): - '''program main function''' - args = parse_args() - - with open(args.out, 'w', - encoding="utf-8") if args.out else sys.stdout as out: - write_header(out, args.source) - for path in args.file: - elffile = ELFFile(open_input(path)) - sections = load_sections(elffile) - for name, insns in sections: - dump_section(name, insns, out) - - -if __name__ == "__main__": - main() diff --git a/drivers/net/tap/bpf/meson.build b/drivers/net/tap/bpf/meson.build new file mode 100644 index 0000000000..f2c03a19fd --- /dev/null +++ b/drivers/net/tap/bpf/meson.build @@ -0,0 +1,81 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright 2024 Stephen Hemminger + +enable_tap_rss = false + +libbpf = dependency('libbpf', required: false, method: 'pkg-config') +if not libbpf.found() + message('net/tap: no RSS support missing libbpf') + subdir_done() +endif + +# Debian install this in /usr/sbin which is not in $PATH +bpftool = find_program('bpftool', '/usr/sbin/bpftool', required: false, version: '>= 5.6.0') +if not bpftool.found() + message('net/tap: no RSS support missing bpftool') + subdir_done() +endif + +clang_supports_bpf = false +clang = find_program('clang', required: false) +if clang.found() + clang_supports_bpf = run_command(clang, '-target', 'bpf', '--print-supported-cpus', + check: false).returncode() == 0 +endif + +if not clang_supports_bpf + message('net/tap: no RSS support missing clang BPF') + subdir_done() +endif + +enable_tap_rss = true + +libbpf_include_dir = libbpf.get_variable(pkgconfig : 'includedir') + +# The include files and others include +# but is not defined for multi-lib environment target. +# Workaround by using include directoriy from the host build environment. +machine_name = run_command('uname', '-m').stdout().strip() +march_include_dir = '/usr/include/' + machine_name + '-linux-gnu' + +clang_flags = [ + '-O2', + '-Wall', + '-Wextra', + '-target', + 'bpf', + '-g', + '-c', +] + +bpf_o_cmd = [ + clang, + clang_flags, + '-idirafter', + libbpf_include_dir, + '-idirafter', + march_include_dir, + '@INPUT@', + '-o', + '@OUTPUT@' +] + +skel_h_cmd = [ + bpftool, + 'gen', + 'skeleton', + '@INPUT@' +] + +tap_rss_o = custom_target( + 'tap_rss.bpf.o', + input: 'tap_rss.c', + output: 'tap_rss.o', + command: bpf_o_cmd) + +tap_rss_skel_h = custom_target( + 'tap_rss.skel.h', + input: tap_rss_o, + output: 'tap_rss.skel.h', + command: skel_h_cmd, + capture: true) diff --git a/drivers/net/tap/bpf/tap_bpf_program.c b/drivers/net/tap/bpf/tap_bpf_program.c deleted file mode 100644 index f05aed021c..0000000000 --- a/drivers/net/tap/bpf/tap_bpf_program.c +++ /dev/null @@ -1,255 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 - * Copyright 2017 Mellanox Technologies, Ltd - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "bpf_api.h" -#include "bpf_elf.h" -#include "../tap_rss.h" - -/** Create IPv4 address */ -#define IPv4(a, b, c, d) ((__u32)(((a) & 0xff) << 24) | \ - (((b) & 0xff) << 16) | \ - (((c) & 0xff) << 8) | \ - ((d) & 0xff)) - -#define PORT(a, b) ((__u16)(((a) & 0xff) << 8) | \ - ((b) & 0xff)) - -/* - * The queue number is offset by a unique QUEUE_OFFSET, to distinguish - * packets that have gone through this rule (skb->cb[1] != 0) from others. - */ -#define QUEUE_OFFSET 0x7cafe800 -#define PIN_GLOBAL_NS 2 - -#define KEY_IDX 0 -#define BPF_MAP_ID_KEY 1 - -struct vlan_hdr { - __be16 proto; - __be16 tci; -}; - -struct bpf_elf_map __attribute__((section("maps"), used)) -map_keys = { - .type = BPF_MAP_TYPE_HASH, - .id = BPF_MAP_ID_KEY, - .size_key = sizeof(__u32), - .size_value = sizeof(struct rss_key), - .max_elem = 256, - .pinning = PIN_GLOBAL_NS, -}; - -__section("cls_q") int -match_q(struct __sk_buff *skb) -{ - __u32 queue = skb->cb[1]; - /* queue is set by tap_flow_bpf_cls_q() before load */ - volatile __u32 q = 0xdeadbeef; - __u32 match_queue = QUEUE_OFFSET + q; - - /* printt("match_q$i() queue = %d\n", queue); */ - - if (queue != match_queue) - return TC_ACT_OK; - - /* queue match */ - skb->cb[1] = 0; - return TC_ACT_UNSPEC; -} - - -struct ipv4_l3_l4_tuple { - __u32 src_addr; - __u32 dst_addr; - __u16 dport; - __u16 sport; -} __attribute__((packed)); - -struct ipv6_l3_l4_tuple { - __u8 src_addr[16]; - __u8 dst_addr[16]; - __u16 dport; - __u16 sport; -} __attribute__((packed)); - -static const __u8 def_rss_key[TAP_RSS_HASH_KEY_SIZE] = { - 0xd1, 0x81, 0xc6, 0x2c, - 0xf7, 0xf4, 0xdb, 0x5b, - 0x19, 0x83, 0xa2, 0xfc, - 0x94, 0x3e, 0x1a, 0xdb, - 0xd9, 0x38, 0x9e, 0x6b, - 0xd1, 0x03, 0x9c, 0x2c, - 0xa7, 0x44, 0x99, 0xad, - 0x59, 0x3d, 0x56, 0xd9, - 0xf3, 0x25, 0x3c, 0x06, - 0x2a, 0xdc, 0x1f, 0xfc, -}; - -static __u32 __attribute__((always_inline)) -rte_softrss_be(const __u32 *input_tuple, const uint8_t *rss_key, - __u8 input_len) -{ - __u32 i, j, hash = 0; -#pragma unroll - for (j = 0; j < input_len; j++) { -#pragma unroll - for (i = 0; i < 32; i++) { - if (input_tuple[j] & (1U << (31 - i))) { - hash ^= ((const __u32 *)def_rss_key)[j] << i | - (__u32)((uint64_t) - (((const __u32 *)def_rss_key)[j + 1]) - >> (32 - i)); - } - } - } - return hash; -} - -static int __attribute__((always_inline)) -rss_l3_l4(struct __sk_buff *skb) -{ - void *data_end = (void *)(long)skb->data_end; - void *data = (void *)(long)skb->data; - __u16 proto = (__u16)skb->protocol; - __u32 key_idx = 0xdeadbeef; - __u32 hash; - struct rss_key *rsskey; - __u64 off = ETH_HLEN; - int j; - __u8 *key = 0; - __u32 len; - __u32 queue = 0; - bool mf = 0; - __u16 frag_off = 0; - - rsskey = map_lookup_elem(&map_keys, &key_idx); - if (!rsskey) { - printt("hash(): rss key is not configured\n"); - return TC_ACT_OK; - } - key = (__u8 *)rsskey->key; - - /* Get correct proto for 802.1ad */ - if (skb->vlan_present && skb->vlan_proto == htons(ETH_P_8021AD)) { - if (data + ETH_ALEN * 2 + sizeof(struct vlan_hdr) + - sizeof(proto) > data_end) - return TC_ACT_OK; - proto = *(__u16 *)(data + ETH_ALEN * 2 + - sizeof(struct vlan_hdr)); - off += sizeof(struct vlan_hdr); - } - - if (proto == htons(ETH_P_IP)) { - if (data + off + sizeof(struct iphdr) + sizeof(__u32) - > data_end) - return TC_ACT_OK; - - __u8 *src_dst_addr = data + off + offsetof(struct iphdr, saddr); - __u8 *frag_off_addr = data + off + offsetof(struct iphdr, frag_off); - __u8 *prot_addr = data + off + offsetof(struct iphdr, protocol); - __u8 *src_dst_port = data + off + sizeof(struct iphdr); - struct ipv4_l3_l4_tuple v4_tuple = { - .src_addr = IPv4(*(src_dst_addr + 0), - *(src_dst_addr + 1), - *(src_dst_addr + 2), - *(src_dst_addr + 3)), - .dst_addr = IPv4(*(src_dst_addr + 4), - *(src_dst_addr + 5), - *(src_dst_addr + 6), - *(src_dst_addr + 7)), - .sport = 0, - .dport = 0, - }; - /** Fetch the L4-payer port numbers only in-case of TCP/UDP - ** and also if the packet is not fragmented. Since fragmented - ** chunks do not have L4 TCP/UDP header. - **/ - if (*prot_addr == IPPROTO_UDP || *prot_addr == IPPROTO_TCP) { - frag_off = PORT(*(frag_off_addr + 0), - *(frag_off_addr + 1)); - mf = frag_off & 0x2000; - frag_off = frag_off & 0x1fff; - if (mf == 0 && frag_off == 0) { - v4_tuple.sport = PORT(*(src_dst_port + 0), - *(src_dst_port + 1)); - v4_tuple.dport = PORT(*(src_dst_port + 2), - *(src_dst_port + 3)); - } - } - __u8 input_len = sizeof(v4_tuple) / sizeof(__u32); - if (rsskey->hash_fields & (1 << HASH_FIELD_IPV4_L3)) - input_len--; - hash = rte_softrss_be((__u32 *)&v4_tuple, key, 3); - } else if (proto == htons(ETH_P_IPV6)) { - if (data + off + sizeof(struct ipv6hdr) + - sizeof(__u32) > data_end) - return TC_ACT_OK; - __u8 *src_dst_addr = data + off + - offsetof(struct ipv6hdr, saddr); - __u8 *src_dst_port = data + off + - sizeof(struct ipv6hdr); - __u8 *next_hdr = data + off + - offsetof(struct ipv6hdr, nexthdr); - - struct ipv6_l3_l4_tuple v6_tuple; - for (j = 0; j < 4; j++) - *((uint32_t *)&v6_tuple.src_addr + j) = - __builtin_bswap32(*((uint32_t *) - src_dst_addr + j)); - for (j = 0; j < 4; j++) - *((uint32_t *)&v6_tuple.dst_addr + j) = - __builtin_bswap32(*((uint32_t *) - src_dst_addr + 4 + j)); - - /** Fetch the L4 header port-numbers only if next-header - * is TCP/UDP **/ - if (*next_hdr == IPPROTO_UDP || *next_hdr == IPPROTO_TCP) { - v6_tuple.sport = PORT(*(src_dst_port + 0), - *(src_dst_port + 1)); - v6_tuple.dport = PORT(*(src_dst_port + 2), - *(src_dst_port + 3)); - } else { - v6_tuple.sport = 0; - v6_tuple.dport = 0; - } - - __u8 input_len = sizeof(v6_tuple) / sizeof(__u32); - if (rsskey->hash_fields & (1 << HASH_FIELD_IPV6_L3)) - input_len--; - hash = rte_softrss_be((__u32 *)&v6_tuple, key, 9); - } else { - return TC_ACT_PIPE; - } - - queue = rsskey->queues[(hash % rsskey->nb_queues) & - (TAP_MAX_QUEUES - 1)]; - skb->cb[1] = QUEUE_OFFSET + queue; - /* printt(">>>>> rss_l3_l4 hash=0x%x queue=%u\n", hash, queue); */ - - return TC_ACT_RECLASSIFY; -} - -#define RSS(L) \ - __section(#L) int \ - L ## _hash(struct __sk_buff *skb) \ - { \ - return rss_ ## L (skb); \ - } - -RSS(l3_l4) - -BPF_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/tap/bpf/tap_rss.c b/drivers/net/tap/bpf/tap_rss.c new file mode 100644 index 0000000000..888b3bdc24 --- /dev/null +++ b/drivers/net/tap/bpf/tap_rss.c @@ -0,0 +1,264 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 + * Copyright 2017 Mellanox Technologies, Ltd + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "../tap_rss.h" + +/* + * This map provides configuration information about flows which need BPF RSS. + * + * The hash is indexed by the skb mark. + */ +struct { + __uint(type, BPF_MAP_TYPE_HASH); + __uint(key_size, sizeof(__u32)); + __uint(value_size, sizeof(struct rss_key)); + __uint(max_entries, TAP_RSS_MAX); +} rss_map SEC(".maps"); + +#define IP_MF 0x2000 /** IP header Flags **/ +#define IP_OFFSET 0x1FFF /** IP header fragment offset **/ + +/* + * Compute Toeplitz hash over the input tuple. + * This is same as rte_softrss_be in lib/hash + * but loop needs to be setup to match BPF restrictions. + */ +static __u32 __attribute__((always_inline)) +softrss_be(const __u32 *input_tuple, __u32 input_len, const __u32 *key) +{ + __u32 i, j, hash = 0; + +#pragma unroll + for (j = 0; j < input_len; j++) { +#pragma unroll + for (i = 0; i < 32; i++) { + if (input_tuple[j] & (1U << (31 - i))) + hash ^= key[j] << i | key[j + 1] >> (32 - i); + } + } + return hash; +} + +/* + * Compute RSS hash for IPv4 packet. + * return in 0 if RSS not specified + */ +static __u32 __attribute__((always_inline)) +parse_ipv4(const struct __sk_buff *skb, __u32 hash_type, const __u32 *key) +{ + struct iphdr iph; + __u32 off = 0; + + if (bpf_skb_load_bytes_relative(skb, off, &iph, sizeof(iph), BPF_HDR_START_NET)) + return 0; /* no IP header present */ + + struct { + __u32 src_addr; + __u32 dst_addr; + __u16 dport; + __u16 sport; + } v4_tuple = { + .src_addr = bpf_ntohl(iph.saddr), + .dst_addr = bpf_ntohl(iph.daddr), + }; + + /* If only calculating L3 hash, do it now */ + if (hash_type & (1 << HASH_FIELD_IPV4_L3)) + return softrss_be((__u32 *)&v4_tuple, sizeof(v4_tuple) / sizeof(__u32) - 1, key); + + /* If packet is fragmented then no L4 hash is possible */ + if ((iph.frag_off & bpf_htons(IP_MF | IP_OFFSET)) != 0) + return 0; + + /* Do RSS on UDP or TCP protocols */ + if (iph.protocol == IPPROTO_UDP || iph.protocol == IPPROTO_TCP) { + __u16 src_dst_port[2]; + + off += iph.ihl * 4; + if (bpf_skb_load_bytes_relative(skb, off, &src_dst_port, sizeof(src_dst_port), + BPF_HDR_START_NET)) + return 0; /* TCP or UDP header missing */ + + v4_tuple.sport = bpf_ntohs(src_dst_port[0]); + v4_tuple.dport = bpf_ntohs(src_dst_port[1]); + return softrss_be((__u32 *)&v4_tuple, sizeof(v4_tuple) / sizeof(__u32), key); + } + + /* Other protocol */ + return 0; +} + +/* + * Parse Ipv6 extended headers, update offset and return next proto. + * returns next proto on success, -1 on malformed header + */ +static int __attribute__((always_inline)) +skip_ip6_ext(__u16 proto, const struct __sk_buff *skb, __u32 *off, int *frag) +{ + struct ext_hdr { + __u8 next_hdr; + __u8 len; + } xh; + unsigned int i; + + *frag = 0; + +#define MAX_EXT_HDRS 5 +#pragma unroll + for (i = 0; i < MAX_EXT_HDRS; i++) { + switch (proto) { + case IPPROTO_HOPOPTS: + case IPPROTO_ROUTING: + case IPPROTO_DSTOPTS: + if (bpf_skb_load_bytes_relative(skb, *off, &xh, sizeof(xh), + BPF_HDR_START_NET)) + return -1; + + *off += (xh.len + 1) * 8; + proto = xh.next_hdr; + break; + case IPPROTO_FRAGMENT: + if (bpf_skb_load_bytes_relative(skb, *off, &xh, sizeof(xh), + BPF_HDR_START_NET)) + return -1; + + *off += 8; + proto = xh.next_hdr; + *frag = 1; + return proto; /* this is always the last ext hdr */ + default: + return proto; + } + } + + /* too many extension headers give up */ + return -1; +} + +/* + * Compute RSS hash for IPv6 packet. + * return in 0 if RSS not specified + */ +static __u32 __attribute__((always_inline)) +parse_ipv6(const struct __sk_buff *skb, __u32 hash_type, const __u32 *key) +{ + struct { + __u32 src_addr[4]; + __u32 dst_addr[4]; + __u16 dport; + __u16 sport; + } v6_tuple = { }; + struct ipv6hdr ip6h; + __u32 off = 0, j; + int proto, frag; + + if (bpf_skb_load_bytes_relative(skb, off, &ip6h, sizeof(ip6h), BPF_HDR_START_NET)) + return 0; /* missing IPv6 header */ + +#pragma unroll + for (j = 0; j < 4; j++) { + v6_tuple.src_addr[j] = bpf_ntohl(ip6h.saddr.in6_u.u6_addr32[j]); + v6_tuple.dst_addr[j] = bpf_ntohl(ip6h.daddr.in6_u.u6_addr32[j]); + } + + /* If only doing L3 hash, do it now */ + if (hash_type & (1 << HASH_FIELD_IPV6_L3)) + return softrss_be((__u32 *)&v6_tuple, sizeof(v6_tuple) / sizeof(__u32) - 1, key); + + /* Skip extension headers if present */ + off += sizeof(ip6h); + proto = skip_ip6_ext(ip6h.nexthdr, skb, &off, &frag); + if (proto < 0) + return 0; + + /* If packet is a fragment then no L4 hash is possible */ + if (frag) + return 0; + + /* Do RSS on UDP or TCP */ + if (proto == IPPROTO_UDP || proto == IPPROTO_TCP) { + __u16 src_dst_port[2]; + + if (bpf_skb_load_bytes_relative(skb, off, &src_dst_port, sizeof(src_dst_port), + BPF_HDR_START_NET)) + return 0; + + v6_tuple.sport = bpf_ntohs(src_dst_port[0]); + v6_tuple.dport = bpf_ntohs(src_dst_port[1]); + + return softrss_be((__u32 *)&v6_tuple, sizeof(v6_tuple) / sizeof(__u32), key); + } + + return 0; +} + +/* + * Compute RSS hash for packets. + * Returns 0 if no hash is possible. + */ +static __u32 __attribute__((always_inline)) +calculate_rss_hash(const struct __sk_buff *skb, const struct rss_key *rsskey) +{ + const __u32 *key = (const __u32 *)rsskey->key; + + if (skb->protocol == bpf_htons(ETH_P_IP)) + return parse_ipv4(skb, rsskey->hash_fields, key); + else if (skb->protocol == bpf_htons(ETH_P_IPV6)) + return parse_ipv6(skb, rsskey->hash_fields, key); + else + return 0; +} + +/* + * Scale value to be into range [0, n) + * Assumes val is large (ie hash covers whole u32 range) + */ +static __u32 __attribute__((always_inline)) +reciprocal_scale(__u32 val, __u32 n) +{ + return (__u32)(((__u64)val * n) >> 32); +} + +/* + * When this BPF program is run by tc from the filter classifier, + * it is able to read skb metadata and packet data. + * + * For packets where RSS is not possible, then just return TC_ACT_OK. + * When RSS is desired, change the skb->queue_mapping and set TC_ACT_PIPE + * to continue processing. + * + * This should be BPF_PROG_TYPE_SCHED_ACT so section needs to be "action" + */ +SEC("action") int +rss_flow_action(struct __sk_buff *skb) +{ + const struct rss_key *rsskey; + __u32 mark = skb->mark; + __u32 hash; + + /* Lookup RSS configuration for that BPF class */ + rsskey = bpf_map_lookup_elem(&rss_map, &mark); + if (rsskey == NULL) + return TC_ACT_OK; + + hash = calculate_rss_hash(skb, rsskey); + if (!hash) + return TC_ACT_OK; + + /* Fold hash to the number of queues configured */ + skb->queue_mapping = reciprocal_scale(hash, rsskey->nb_queues); + return TC_ACT_PIPE; +} + +char _license[] SEC("license") = "Dual BSD/GPL"; From patchwork Fri Apr 26 15:48:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Hemminger X-Patchwork-Id: 139711 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 7A92E43F19; Fri, 26 Apr 2024 17:52:20 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id C8A6E43F1E; Fri, 26 Apr 2024 17:51:46 +0200 (CEST) Received: from mail-pg1-f170.google.com (mail-pg1-f170.google.com [209.85.215.170]) by mails.dpdk.org (Postfix) with ESMTP id AB0B143EFB for ; Fri, 26 Apr 2024 17:51:41 +0200 (CEST) Received: by mail-pg1-f170.google.com with SMTP id 41be03b00d2f7-5e42b4bbfa4so1460818a12.1 for ; Fri, 26 Apr 2024 08:51:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=networkplumber-org.20230601.gappssmtp.com; s=20230601; t=1714146701; x=1714751501; darn=dpdk.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=aYJCmNFOVedHApS/WzQzrBs6k52ZDo9m1VFd7MFhABU=; b=OF9K/k0gk38YHwPUrkLgVr9JuyBKtOlUxV7YOf78qiB3pBS0KH3NR0bu4k2+83cALV 3LDxZXXSroaXWcIL37pDolA8g2SCdSpx2flbIBGG+bClfzGKx8/prE+qso63mbmrf37L xDOKsj4PMH54Srx34ZNldtiO6uspXGgDCInQ3MrFn5lWtQizLprejYytjqYGaWeukR3U HnWJm12/ych18+tuu99Ec6IedYgbSB4ZlgB0F/J8u+WGKrwSSmenGjFLc6JyzwJfOtr4 CxZVxm9k//c9GmrmGGzlu+G8tAfi7WVaq+MFFE8XO8Akqhb6UexlgtkNI2nWY55FPMEM dPTw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714146701; x=1714751501; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=aYJCmNFOVedHApS/WzQzrBs6k52ZDo9m1VFd7MFhABU=; b=pIWcryZAJT3r8pj/SIpA17wRcth7STVIHa+a0+qFmPcCBrFGD0xy2y0tIs9XIxURXY q3fE13c3mAa1pI1rRmvqnIbJTSwgrXkqCXgmMkHGN7uMN+ooAyFHNCfTm5o+xsunfAY0 Vy2nzJVGcO9Uy0K5ZbsywMOs0dtKq6Nnyy4L1wHQa9aLmDaib6WKV9WkLBFxvVKF5wnL lWq2wMk15pSY0cBMCKk52iFe7YSYQxauM7tub6E08WZWgsyndwPKjcHm1a+pR/W0freR 2FqzGN5BgD2YOQs3UJpwA/U5N+Xy3TRDW1a27hLIH1U6uz0HrFcpN0hmp5EMwRg+G7ea 5Zvg== X-Gm-Message-State: AOJu0YyTLINQHkjTUzyDs1f37x1zgJEAACzkS/zdCo343WyheQgorRjE 2IN18ksXR3SL2syEQF8YlhIYP6ObL5bSGWwgPGQp2zu20ZnJDUDwKq53sY6TW+Gnhp+Qwpd2SQD k774= X-Google-Smtp-Source: AGHT+IFXzbAXX/yrpmJwQdl5LAf0x5aoMqLRWMUf1RoQIgbrDTUAoACOKhH0r4Ww6YwpCdYxgixV2w== X-Received: by 2002:a17:90a:c292:b0:2ae:814f:43fa with SMTP id f18-20020a17090ac29200b002ae814f43famr2957130pjt.46.1714146700789; Fri, 26 Apr 2024 08:51:40 -0700 (PDT) Received: from hermes.local (204-195-96-226.wavecable.com. [204.195.96.226]) by smtp.gmail.com with ESMTPSA id ns5-20020a17090b250500b002a5f44353d2sm16770978pjb.7.2024.04.26.08.51.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 26 Apr 2024 08:51:40 -0700 (PDT) From: Stephen Hemminger To: dev@dpdk.org Cc: Stephen Hemminger Subject: [PATCH v9 6/9] net/tap: use libbpf to load new BPF program Date: Fri, 26 Apr 2024 08:48:56 -0700 Message-ID: <20240426155125.125910-7-stephen@networkplumber.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240426155125.125910-1-stephen@networkplumber.org> References: <20240130034925.44869-1-stephen@networkplumber.org> <20240426155125.125910-1-stephen@networkplumber.org> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org There were multiple issues in the RSS queue support in the TAP driver. This required extensive rework of the BPF support. Change the BPF loading to use bpftool to create a skeleton header file, and load with libbpf. The BPF is always compiled from source so less chance that source and instructions diverge. Also resolves issue where libbpf and source get out of sync. The program is only loaded once, so if multiple rules are created only one BPF program is loaded in kernel. The new BPF program only needs a single action. No need for action and re-classification step. It also fixes the missing bits from the original. - supports setting RSS key per flow - level of hash can be L3 or L3/L4. Signed-off-by: Stephen Hemminger --- drivers/net/tap/bpf/meson.build | 36 ++- drivers/net/tap/bpf/tap_rss.c | 45 ++-- drivers/net/tap/meson.build | 35 ++- drivers/net/tap/rte_eth_tap.c | 14 +- drivers/net/tap/rte_eth_tap.h | 6 +- drivers/net/tap/tap_flow.c | 418 ++++++++------------------------ drivers/net/tap/tap_flow.h | 17 +- drivers/net/tap/tap_rss.h | 10 +- drivers/net/tap/tap_tcmsgs.h | 4 +- 9 files changed, 189 insertions(+), 396 deletions(-) diff --git a/drivers/net/tap/bpf/meson.build b/drivers/net/tap/bpf/meson.build index f2c03a19fd..45e8c3b498 100644 --- a/drivers/net/tap/bpf/meson.build +++ b/drivers/net/tap/bpf/meson.build @@ -1,17 +1,26 @@ # SPDX-License-Identifier: BSD-3-Clause # Copyright 2024 Stephen Hemminger -enable_tap_rss = false - -libbpf = dependency('libbpf', required: false, method: 'pkg-config') +# Loading BPF requires libbpf +# and the bpf_map__XXX API's were introduced in 0.8.0 +libbpf = dependency('libbpf', version: '>= 1.0', + required: false, method: 'pkg-config') if not libbpf.found() message('net/tap: no RSS support missing libbpf') subdir_done() endif +# Making skeleton needs bpftool # Debian install this in /usr/sbin which is not in $PATH -bpftool = find_program('bpftool', '/usr/sbin/bpftool', required: false, version: '>= 5.6.0') -if not bpftool.found() +bpftool_supports_skel = false +bpftool = find_program('bpftool', '/usr/sbin/bpftool', required: false) +if bpftool.found() + # Some Ubuntu versions have non-functional bpftool + bpftool_supports_skel = run_command(bpftool, 'gen', 'help', + check:false).returncode() == 0 +endif + +if not bpftool_supports_skel message('net/tap: no RSS support missing bpftool') subdir_done() endif @@ -42,6 +51,7 @@ clang_flags = [ '-O2', '-Wall', '-Wextra', + max_queues, '-target', 'bpf', '-g', @@ -67,6 +77,22 @@ skel_h_cmd = [ '@INPUT@' ] +vmlinux_h_cmd = [ + bpftool, + 'btf', + 'dump', + 'file', + '/sys/kernel/btf/vmlinux', + 'format', + 'c' +] + +vmlinux_h = custom_target( + 'vmlinux.h', + output: 'vmlinux.h', + command: vmlinux_h_cmd, + capture: true) + tap_rss_o = custom_target( 'tap_rss.bpf.o', input: 'tap_rss.c', diff --git a/drivers/net/tap/bpf/tap_rss.c b/drivers/net/tap/bpf/tap_rss.c index 888b3bdc24..1d71941c53 100644 --- a/drivers/net/tap/bpf/tap_rss.c +++ b/drivers/net/tap/bpf/tap_rss.c @@ -203,23 +203,6 @@ parse_ipv6(const struct __sk_buff *skb, __u32 hash_type, const __u32 *key) return 0; } -/* - * Compute RSS hash for packets. - * Returns 0 if no hash is possible. - */ -static __u32 __attribute__((always_inline)) -calculate_rss_hash(const struct __sk_buff *skb, const struct rss_key *rsskey) -{ - const __u32 *key = (const __u32 *)rsskey->key; - - if (skb->protocol == bpf_htons(ETH_P_IP)) - return parse_ipv4(skb, rsskey->hash_fields, key); - else if (skb->protocol == bpf_htons(ETH_P_IPV6)) - return parse_ipv6(skb, rsskey->hash_fields, key); - else - return 0; -} - /* * Scale value to be into range [0, n) * Assumes val is large (ie hash covers whole u32 range) @@ -244,20 +227,40 @@ SEC("action") int rss_flow_action(struct __sk_buff *skb) { const struct rss_key *rsskey; - __u32 mark = skb->mark; + const __u32 *key; + __be16 proto; + __u32 mark; __u32 hash; + __u16 queue; + + __builtin_preserve_access_index(({ + mark = skb->mark; + proto = skb->protocol; + })); /* Lookup RSS configuration for that BPF class */ rsskey = bpf_map_lookup_elem(&rss_map, &mark); if (rsskey == NULL) return TC_ACT_OK; - hash = calculate_rss_hash(skb, rsskey); - if (!hash) + key = (const __u32 *)rsskey->key; + + if (proto == bpf_htons(ETH_P_IP)) + hash = parse_ipv4(skb, rsskey->hash_fields, key); + else if (proto == bpf_htons(ETH_P_IPV6)) + hash = parse_ipv6(skb, rsskey->hash_fields, key); + else + hash = 0; + + if (hash == 0) return TC_ACT_OK; /* Fold hash to the number of queues configured */ - skb->queue_mapping = reciprocal_scale(hash, rsskey->nb_queues); + queue = reciprocal_scale(hash, rsskey->nb_queues); + + __builtin_preserve_access_index(({ + skb->queue_mapping = queue; + })); return TC_ACT_PIPE; } diff --git a/drivers/net/tap/meson.build b/drivers/net/tap/meson.build index 66647a1c62..26074059fa 100644 --- a/drivers/net/tap/meson.build +++ b/drivers/net/tap/meson.build @@ -5,36 +5,33 @@ if not is_linux build = false reason = 'only supported on Linux' endif + sources = files( 'rte_eth_tap.c', 'tap_intr.c', 'tap_netlink.c', ) +deps = ['bus_vdev', 'gso', 'hash'] + +max_queues = '-DTAP_MAX_QUEUES=16' +cflags += max_queues + +require_iova_in_mbuf = false + if cc.has_header_symbol('linux/pkt_cls.h', 'TCA_FLOWER_ACT') cflags += '-DHAVE_TCA_FLOWER' sources += files( - 'tap_bpf_api.c', 'tap_flow.c', 'tap_tcmsgs.c', ) -endif - -deps = ['bus_vdev', 'gso', 'hash'] -cflags += '-DTAP_MAX_QUEUES=16' - -# input array for meson symbol search: -# [ "MACRO to define if found", "header for the search", -# "enum/define", "symbol to search" ] -# -args = [ - [ 'HAVE_TC_ACT_BPF', 'linux/tc_act/tc_bpf.h', 'TCA_ACT_BPF_UNSPEC' ], -] -config = configuration_data() -foreach arg:args - config.set(arg[0], cc.has_header_symbol(arg[1], arg[2])) -endforeach -configure_file(output : 'tap_autoconf.h', configuration : config) + enable_tap_rss = false -require_iova_in_mbuf = false + subdir('bpf') + if enable_tap_rss + cflags += '-DHAVE_BPF_RSS' + ext_deps += libbpf + sources += tap_rss_skel_h + endif +endif diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c index 3f4fe95a09..793730de08 100644 --- a/drivers/net/tap/rte_eth_tap.c +++ b/drivers/net/tap/rte_eth_tap.c @@ -1131,6 +1131,7 @@ tap_dev_close(struct rte_eth_dev *dev) tap_flow_implicit_flush(internals, NULL); tap_nl_final(internals->nlsk_fd); internals->nlsk_fd = -1; + tap_flow_bpf_destroy(internals); } #endif @@ -1956,6 +1957,7 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, const char *tap_name, strlcpy(pmd->name, tap_name, sizeof(pmd->name)); pmd->type = type; pmd->ka_fd = -1; + #ifdef HAVE_TCA_FLOWER pmd->nlsk_fd = -1; #endif @@ -2038,13 +2040,6 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, const char *tap_name, /* Make network device persist after application exit */ pmd->persist = persist; - pmd->if_index = if_nametoindex(pmd->name); - if (!pmd->if_index) { - TAP_LOG(ERR, "%s: failed to get if_index.", pmd->name); - goto disable_rte_flow; - } - - #ifdef HAVE_TCA_FLOWER /* * Set up everything related to rte_flow: @@ -2060,6 +2055,11 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, const char *tap_name, pmd->name); goto disable_rte_flow; } + pmd->if_index = if_nametoindex(pmd->name); + if (!pmd->if_index) { + TAP_LOG(ERR, "%s: failed to get if_index.", pmd->name); + goto disable_rte_flow; + } if (qdisc_create_multiq(pmd->nlsk_fd, pmd->if_index) < 0) { TAP_LOG(ERR, "%s: failed to create multiq qdisc.", pmd->name); diff --git a/drivers/net/tap/rte_eth_tap.h b/drivers/net/tap/rte_eth_tap.h index af18b29090..ce4322ad04 100644 --- a/drivers/net/tap/rte_eth_tap.h +++ b/drivers/net/tap/rte_eth_tap.h @@ -81,10 +81,8 @@ struct pmd_internals { #ifdef HAVE_TCA_FLOWER int nlsk_fd; /* Netlink socket fd */ int flow_isolate; /* 1 if flow isolation is enabled */ - int rss_enabled; /* 1 if RSS is enabled, else 0 */ - /* implicit rules set when RSS is enabled */ - int map_fd; /* BPF RSS map fd */ - int bpf_fd[RTE_PMD_TAP_MAX_QUEUES];/* List of bpf fds per queue */ + + struct tap_rss *rss; /* BPF program */ LIST_HEAD(tap_flows, rte_flow) flows; /* rte_flow rules */ /* implicit rte_flow rules set when a remote device is active */ diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c index 5a5a4ea048..322153d806 100644 --- a/drivers/net/tap/tap_flow.c +++ b/drivers/net/tap/tap_flow.c @@ -15,25 +15,19 @@ #include #include #include +#include #include -#include #include #include -/* RSS key management */ -enum bpf_rss_key_e { - KEY_CMD_GET = 1, - KEY_CMD_RELEASE, - KEY_CMD_INIT, - KEY_CMD_DEINIT, -}; - -enum key_status_e { - KEY_STAT_UNSPEC, - KEY_STAT_USED, - KEY_STAT_AVAILABLE, -}; +#ifdef HAVE_BPF_RSS +/* Workaround for warning in bpftool generated skeleton code */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-qual" +#include "tap_rss.skel.h" +#pragma GCC diagnostic pop +#endif #define ISOLATE_HANDLE 1 #define REMOTE_PROMISCUOUS_HANDLE 2 @@ -41,8 +35,6 @@ enum key_status_e { struct rte_flow { LIST_ENTRY(rte_flow) next; /* Pointer to the next rte_flow structure */ struct rte_flow *remote_flow; /* associated remote flow */ - int bpf_fd[SEC_MAX]; /* list of bfs fds per ELF section */ - uint32_t key_idx; /* RSS rule key index into BPF map */ struct nlmsg msg; }; @@ -69,12 +61,16 @@ struct action_data { struct skbedit { struct tc_skbedit skbedit; uint16_t queue; + uint32_t mark; } skbedit; +#ifdef HAVE_BPF_RSS struct bpf { struct tc_act_bpf bpf; + uint32_t map_key; int bpf_fd; const char *annotation; } bpf; +#endif }; }; @@ -112,13 +108,12 @@ tap_flow_isolate(struct rte_eth_dev *dev, int set, struct rte_flow_error *error); -static int bpf_rss_key(enum bpf_rss_key_e cmd, __u32 *key_idx); -static int rss_enable(struct pmd_internals *pmd, - const struct rte_flow_attr *attr, - struct rte_flow_error *error); +#ifdef HAVE_BPF_RSS +static int rss_enable(struct pmd_internals *pmd, struct rte_flow_error *error); static int rss_add_actions(struct rte_flow *flow, struct pmd_internals *pmd, const struct rte_flow_action_rss *rss, struct rte_flow_error *error); +#endif static const struct rte_flow_ops tap_flow_ops = { .validate = tap_flow_validate, @@ -853,11 +848,14 @@ add_action(struct rte_flow *flow, size_t *act_index, struct action_data *adata) &adata->mirred); } else if (strcmp("skbedit", adata->id) == 0) { tap_nlattr_add(&msg->nh, TCA_SKBEDIT_PARMS, - sizeof(adata->skbedit.skbedit), - &adata->skbedit.skbedit); - tap_nlattr_add16(&msg->nh, TCA_SKBEDIT_QUEUE_MAPPING, - adata->skbedit.queue); - } else if (strcmp("bpf", adata->id) == 0) { + sizeof(adata->skbedit.skbedit), &adata->skbedit.skbedit); + if (adata->skbedit.mark) + tap_nlattr_add32(&msg->nh, TCA_SKBEDIT_MARK, adata->skbedit.mark); + else + tap_nlattr_add16(&msg->nh, TCA_SKBEDIT_QUEUE_MAPPING, adata->skbedit.queue); + } +#ifdef HAVE_BPF_RSS + else if (strcmp("bpf", adata->id) == 0) { tap_nlattr_add32(&msg->nh, TCA_ACT_BPF_FD, adata->bpf.bpf_fd); tap_nlattr_add(&msg->nh, TCA_ACT_BPF_NAME, strlen(adata->bpf.annotation) + 1, @@ -865,7 +863,9 @@ add_action(struct rte_flow *flow, size_t *act_index, struct action_data *adata) tap_nlattr_add(&msg->nh, TCA_ACT_BPF_PARMS, sizeof(adata->bpf.bpf), &adata->bpf.bpf); - } else { + } +#endif + else { return -1; } tap_nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */ @@ -1104,8 +1104,7 @@ priv_flow_process(struct pmd_internals *pmd, }, }; - err = add_actions(flow, 1, &adata, - TCA_FLOWER_ACT); + err = add_actions(flow, 1, &adata, TCA_FLOWER_ACT); } } else if (actions->type == RTE_FLOW_ACTION_TYPE_QUEUE) { const struct rte_flow_action_queue *queue = @@ -1135,6 +1134,7 @@ priv_flow_process(struct pmd_internals *pmd, err = add_actions(flow, 1, &adata, TCA_FLOWER_ACT); } +#ifdef HAVE_BPF_RSS } else if (actions->type == RTE_FLOW_ACTION_TYPE_RSS) { const struct rte_flow_action_rss *rss = (const struct rte_flow_action_rss *) @@ -1143,13 +1143,14 @@ priv_flow_process(struct pmd_internals *pmd, if (action++) goto exit_action_not_supported; - if (!pmd->rss_enabled) { - err = rss_enable(pmd, attr, error); + if (pmd->rss == NULL) { + err = rss_enable(pmd, error); if (err) goto exit_return_error; } if (flow) err = rss_add_actions(flow, pmd, rss, error); +#endif } else { goto exit_action_not_supported; } @@ -1246,26 +1247,17 @@ tap_flow_set_handle(struct rte_flow *flow) * */ static void -tap_flow_free(struct pmd_internals *pmd, struct rte_flow *flow) +tap_flow_free(struct pmd_internals *pmd __rte_unused, struct rte_flow *flow) { - int i; - if (!flow) return; - if (pmd->rss_enabled) { - /* Close flow BPF file descriptors */ - for (i = 0; i < SEC_MAX; i++) - if (flow->bpf_fd[i] != 0) { - close(flow->bpf_fd[i]); - flow->bpf_fd[i] = 0; - } - - /* Release the map key for this RSS rule */ - bpf_rss_key(KEY_CMD_RELEASE, &flow->key_idx); - flow->key_idx = 0; - } - +#ifdef HAVE_BPF_RSS + struct tap_rss *rss = pmd->rss; + if (rss) + bpf_map__delete_elem(rss->maps.rss_map, + &flow->msg.t.tcm_handle, sizeof(uint32_t), 0); +#endif /* Free flow allocated memory */ rte_free(flow); } @@ -1733,14 +1725,18 @@ tap_flow_implicit_flush(struct pmd_internals *pmd, struct rte_flow_error *error) return 0; } -#define MAX_RSS_KEYS 256 -#define KEY_IDX_OFFSET (3 * MAX_RSS_KEYS) -#define SEC_NAME_CLS_Q "cls_q" - -static const char *sec_name[SEC_MAX] = { - [SEC_L3_L4] = "l3_l4", -}; +/** + * Cleanup when device is closed + */ +void tap_flow_bpf_destroy(struct pmd_internals *pmd __rte_unused) +{ +#ifdef HAVE_BPF_RSS + tap_rss__destroy(pmd->rss); + pmd->rss = NULL; +#endif +} +#ifdef HAVE_BPF_RSS /** * Enable RSS on tap: create TC rules for queuing. * @@ -1755,225 +1751,32 @@ static const char *sec_name[SEC_MAX] = { * * @return 0 on success, negative value on failure. */ -static int rss_enable(struct pmd_internals *pmd, - const struct rte_flow_attr *attr, - struct rte_flow_error *error) +static int rss_enable(struct pmd_internals *pmd, struct rte_flow_error *error) { - struct rte_flow *rss_flow = NULL; - struct nlmsg *msg = NULL; - /* 4096 is the maximum number of instructions for a BPF program */ - char annotation[64]; - int i; - int err = 0; - - /* unlimit locked memory */ - struct rlimit memlock_limit = { - .rlim_cur = RLIM_INFINITY, - .rlim_max = RLIM_INFINITY, - }; - setrlimit(RLIMIT_MEMLOCK, &memlock_limit); - - /* Get a new map key for a new RSS rule */ - err = bpf_rss_key(KEY_CMD_INIT, NULL); - if (err < 0) { - rte_flow_error_set( - error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL, - "Failed to initialize BPF RSS keys"); - - return -1; - } - - /* - * Create BPF RSS MAP - */ - pmd->map_fd = tap_flow_bpf_rss_map_create(sizeof(__u32), /* key size */ - sizeof(struct rss_key), - MAX_RSS_KEYS); - if (pmd->map_fd < 0) { - TAP_LOG(ERR, - "Failed to create BPF map (%d): %s", - errno, strerror(errno)); - rte_flow_error_set( - error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE, NULL, - "Kernel too old or not configured " - "to support BPF maps"); + int err; - return -ENOTSUP; + /* Load the BPF program (defined in tap_bpf.h from skeleton) */ + pmd->rss = tap_rss__open_and_load(); + if (pmd->rss == NULL) { + TAP_LOG(ERR, "Failed to load BPF object: %s", strerror(errno)); + rte_flow_error_set(error, errno, RTE_FLOW_ERROR_TYPE_HANDLE, NULL, + "BPF object could not be loaded"); + return -errno; } - /* - * Add a rule per queue to match reclassified packets and direct them to - * the correct queue. - */ - for (i = 0; i < pmd->dev->data->nb_rx_queues; i++) { - pmd->bpf_fd[i] = tap_flow_bpf_cls_q(i); - if (pmd->bpf_fd[i] < 0) { - TAP_LOG(ERR, - "Failed to load BPF section %s for queue %d", - SEC_NAME_CLS_Q, i); - rte_flow_error_set( - error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE, - NULL, - "Kernel too old or not configured " - "to support BPF programs loading"); - - return -ENOTSUP; - } - - rss_flow = rte_zmalloc(__func__, sizeof(struct rte_flow), 0); - if (!rss_flow) { - TAP_LOG(ERR, - "Cannot allocate memory for rte_flow"); - return -1; - } - msg = &rss_flow->msg; - tc_init_msg(msg, pmd->if_index, RTM_NEWTFILTER, NLM_F_REQUEST | - NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE); - msg->t.tcm_info = TC_H_MAKE(0, htons(ETH_P_ALL)); - tap_flow_set_handle(rss_flow); - uint16_t group = attr->group << GROUP_SHIFT; - uint16_t prio = group | (i + PRIORITY_OFFSET); - msg->t.tcm_info = TC_H_MAKE(prio << 16, msg->t.tcm_info); - msg->t.tcm_parent = TC_H_MAKE(MULTIQ_MAJOR_HANDLE, 0); - - tap_nlattr_add(&msg->nh, TCA_KIND, sizeof("bpf"), "bpf"); - if (tap_nlattr_nested_start(msg, TCA_OPTIONS) < 0) - return -1; - tap_nlattr_add32(&msg->nh, TCA_BPF_FD, pmd->bpf_fd[i]); - snprintf(annotation, sizeof(annotation), "[%s%d]", - SEC_NAME_CLS_Q, i); - tap_nlattr_add(&msg->nh, TCA_BPF_NAME, strlen(annotation) + 1, - annotation); - /* Actions */ - { - struct action_data adata = { - .id = "skbedit", - .skbedit = { - .skbedit = { - .action = TC_ACT_PIPE, - }, - .queue = i, - }, - }; - if (add_actions(rss_flow, 1, &adata, TCA_BPF_ACT) < 0) - return -1; - } - tap_nlattr_nested_finish(msg); /* nested TCA_OPTIONS */ - - /* Netlink message is now ready to be sent */ - if (tap_nl_send(pmd->nlsk_fd, &msg->nh) < 0) - return -1; - err = tap_nl_recv_ack(pmd->nlsk_fd); - if (err < 0) { - TAP_LOG(ERR, - "Kernel refused TC filter rule creation (%d): %s", - errno, strerror(errno)); - return err; - } - } - - pmd->rss_enabled = 1; - return err; -} - -/** - * Manage bpf RSS keys repository with operations: init, get, release - * - * @param[in] cmd - * Command on RSS keys: init, get, release - * - * @param[in, out] key_idx - * Pointer to RSS Key index (out for get command, in for release command) - * - * @return -1 if couldn't get, release or init the RSS keys, 0 otherwise. - */ -static int bpf_rss_key(enum bpf_rss_key_e cmd, __u32 *key_idx) -{ - __u32 i; - int err = 0; - static __u32 num_used_keys; - static __u32 rss_keys[MAX_RSS_KEYS] = {KEY_STAT_UNSPEC}; - static __u32 rss_keys_initialized; - __u32 key; - - switch (cmd) { - case KEY_CMD_GET: - if (!rss_keys_initialized) { - err = -1; - break; - } - - if (num_used_keys == RTE_DIM(rss_keys)) { - err = -1; - break; - } - - *key_idx = num_used_keys % RTE_DIM(rss_keys); - while (rss_keys[*key_idx] == KEY_STAT_USED) - *key_idx = (*key_idx + 1) % RTE_DIM(rss_keys); - - rss_keys[*key_idx] = KEY_STAT_USED; - - /* - * Add an offset to key_idx in order to handle a case of - * RSS and non RSS flows mixture. - * If a non RSS flow is destroyed it has an eBPF map - * index 0 (initialized on flow creation) and might - * unintentionally remove RSS entry 0 from eBPF map. - * To avoid this issue, add an offset to the real index - * during a KEY_CMD_GET operation and subtract this offset - * during a KEY_CMD_RELEASE operation in order to restore - * the real index. - */ - *key_idx += KEY_IDX_OFFSET; - num_used_keys++; - break; - - case KEY_CMD_RELEASE: - if (!rss_keys_initialized) - break; - - /* - * Subtract offset to restore real key index - * If a non RSS flow is falsely trying to release map - * entry 0 - the offset subtraction will calculate the real - * map index as an out-of-range value and the release operation - * will be silently ignored. - */ - key = *key_idx - KEY_IDX_OFFSET; - if (key >= RTE_DIM(rss_keys)) - break; - - if (rss_keys[key] == KEY_STAT_USED) { - rss_keys[key] = KEY_STAT_AVAILABLE; - num_used_keys--; - } - break; - - case KEY_CMD_INIT: - for (i = 0; i < RTE_DIM(rss_keys); i++) - rss_keys[i] = KEY_STAT_AVAILABLE; - - rss_keys_initialized = 1; - num_used_keys = 0; - break; - - case KEY_CMD_DEINIT: - for (i = 0; i < RTE_DIM(rss_keys); i++) - rss_keys[i] = KEY_STAT_UNSPEC; - - rss_keys_initialized = 0; - num_used_keys = 0; - break; - - default: - break; + /* Attach the maps defined in BPF program */ + err = tap_rss__attach(pmd->rss); + if (err < 0) { + TAP_LOG(ERR, "Failed to attach BPF object: %d", err); + rte_flow_error_set(error, -err, RTE_FLOW_ERROR_TYPE_HANDLE, NULL, + "BPF object could not be attached"); + tap_flow_bpf_destroy(pmd); + return err; } - return err; + return 0; } - /* Default RSS hash key also used by mlx devices */ static const uint8_t rss_hash_default_key[] = { 0x2c, 0xc6, 0x81, 0xd1, @@ -2006,9 +1809,11 @@ static int rss_add_actions(struct rte_flow *flow, struct pmd_internals *pmd, const struct rte_flow_action_rss *rss, struct rte_flow_error *error) { + const struct bpf_program *rss_prog = pmd->rss->progs.rss_flow_action; struct rss_key rss_entry = { }; const uint8_t *key_in; uint32_t hash_type = 0; + uint32_t handle = flow->msg.t.tcm_handle; unsigned int i; int err; @@ -2057,34 +1862,24 @@ static int rss_add_actions(struct rte_flow *flow, struct pmd_internals *pmd, else if (rss->types & (RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_FRAG_IPV6 | RTE_ETH_RSS_IPV6_EX)) hash_type |= RTE_BIT32(HASH_FIELD_IPV6_L3); - /* Get a new map key for a new RSS rule */ - err = bpf_rss_key(KEY_CMD_GET, &flow->key_idx); - if (err < 0) { - rte_flow_error_set( - error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE, NULL, - "Failed to get BPF RSS key"); - - return -1; - } + rss_entry.hash_fields = hash_type; + rte_convert_rss_key((const uint32_t *)key_in, (uint32_t *)rss_entry.key, + TAP_RSS_HASH_KEY_SIZE); /* Update RSS map entry with queues */ rss_entry.nb_queues = rss->queue_num; for (i = 0; i < rss->queue_num; i++) rss_entry.queues[i] = rss->queue[i]; - rss_entry.hash_fields = hash_type; - rte_convert_rss_key((const uint32_t *)key_in, (uint32_t *)rss_entry.key, - TAP_RSS_HASH_KEY_SIZE); - - - /* Add this RSS entry to map */ - err = tap_flow_bpf_update_rss_elem(pmd->map_fd, - &flow->key_idx, &rss_entry); + /* Add this way for BPF to find entry in map */ + err = bpf_map__update_elem(pmd->rss->maps.rss_map, + &handle, sizeof(handle), + &rss_entry, sizeof(rss_entry), 0); if (err) { TAP_LOG(ERR, - "Failed to update BPF map entry #%u (%d): %s", - flow->key_idx, errno, strerror(errno)); + "Failed to update BPF map entry %#x (%d): %s", + handle, errno, strerror(errno)); rte_flow_error_set( error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE, NULL, "Kernel too old or not configured " @@ -2093,47 +1888,28 @@ static int rss_add_actions(struct rte_flow *flow, struct pmd_internals *pmd, return -ENOTSUP; } - - /* - * Load bpf rules to calculate hash for this key_idx - */ - - flow->bpf_fd[SEC_L3_L4] = - tap_flow_bpf_calc_l3_l4_hash(flow->key_idx, pmd->map_fd); - if (flow->bpf_fd[SEC_L3_L4] < 0) { - TAP_LOG(ERR, - "Failed to load BPF section %s (%d): %s", - sec_name[SEC_L3_L4], errno, strerror(errno)); - rte_flow_error_set( - error, ENOTSUP, RTE_FLOW_ERROR_TYPE_HANDLE, NULL, - "Kernel too old or not configured " - "to support BPF program loading"); - - return -ENOTSUP; - } - - /* Actions */ - { - struct action_data adata[] = { - { - .id = "bpf", - .bpf = { - .bpf_fd = flow->bpf_fd[SEC_L3_L4], - .annotation = sec_name[SEC_L3_L4], - .bpf = { - .action = TC_ACT_PIPE, - }, - }, + /* Add actions to mark packet then run the RSS BPF program */ + struct action_data adata[] = { + { + .id = "skbedit", + .skbedit = { + .skbedit.action = TC_ACT_PIPE, + .mark = handle, }, - }; - - if (add_actions(flow, RTE_DIM(adata), adata, - TCA_FLOWER_ACT) < 0) - return -1; - } + }, + { + .id = "bpf", + .bpf = { + .bpf.action = TC_ACT_PIPE, + .annotation = "tap_rss", + .bpf_fd = bpf_program__fd(rss_prog), + }, + }, + }; - return 0; + return add_actions(flow, RTE_DIM(adata), adata, TCA_FLOWER_ACT); } +#endif /** * Get rte_flow operations. diff --git a/drivers/net/tap/tap_flow.h b/drivers/net/tap/tap_flow.h index 240fbc3dfa..8b19347a93 100644 --- a/drivers/net/tap/tap_flow.h +++ b/drivers/net/tap/tap_flow.h @@ -9,7 +9,11 @@ #include #include #include -#include + +/** + * Mask of unsupported RSS types + */ +#define TAP_RSS_HF_MASK (~(RTE_ETH_RSS_IP | RTE_ETH_RSS_UDP | RTE_ETH_RSS_TCP)) /** * In TC, priority 0 means we require the kernel to allocate one for us. @@ -41,11 +45,6 @@ enum implicit_rule_index { TAP_REMOTE_MAX_IDX, }; -enum bpf_fd_idx { - SEC_L3_L4, - SEC_MAX, -}; - int tap_dev_flow_ops_get(struct rte_eth_dev *dev, const struct rte_flow_ops **ops); int tap_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *error); @@ -57,10 +56,6 @@ int tap_flow_implicit_destroy(struct pmd_internals *pmd, int tap_flow_implicit_flush(struct pmd_internals *pmd, struct rte_flow_error *error); -int tap_flow_bpf_cls_q(__u32 queue_idx); -int tap_flow_bpf_calc_l3_l4_hash(__u32 key_idx, int map_fd); -int tap_flow_bpf_rss_map_create(unsigned int key_size, unsigned int value_size, - unsigned int max_entries); -int tap_flow_bpf_update_rss_elem(int fd, void *key, void *value); +void tap_flow_bpf_destroy(struct pmd_internals *pmd); #endif /* _TAP_FLOW_H_ */ diff --git a/drivers/net/tap/tap_rss.h b/drivers/net/tap/tap_rss.h index 6009be7031..65bd8991b1 100644 --- a/drivers/net/tap/tap_rss.h +++ b/drivers/net/tap/tap_rss.h @@ -5,16 +5,14 @@ #ifndef _TAP_RSS_H_ #define _TAP_RSS_H_ -#ifndef TAP_MAX_QUEUES -#define TAP_MAX_QUEUES 16 +/* Size of the map from BPF classid to queue table */ +#ifndef TAP_RSS_MAX +#define TAP_RSS_MAX 32 #endif -/* Fixed RSS hash key size in bytes. */ +/* Standard Toeplitz hash key size */ #define TAP_RSS_HASH_KEY_SIZE 40 -/* Supported RSS */ -#define TAP_RSS_HF_MASK (~(RTE_ETH_RSS_IP | RTE_ETH_RSS_UDP | RTE_ETH_RSS_TCP)) - /* hashed fields for RSS */ enum hash_field { HASH_FIELD_IPV4_L3, /* IPv4 src/dst addr */ diff --git a/drivers/net/tap/tap_tcmsgs.h b/drivers/net/tap/tap_tcmsgs.h index a64cb29d6f..9411626661 100644 --- a/drivers/net/tap/tap_tcmsgs.h +++ b/drivers/net/tap/tap_tcmsgs.h @@ -6,7 +6,6 @@ #ifndef _TAP_TCMSGS_H_ #define _TAP_TCMSGS_H_ -#include #include #include #include @@ -14,9 +13,10 @@ #include #include #include -#ifdef HAVE_TC_ACT_BPF +#ifdef HAVE_BPF_RSS #include #endif + #include #include From patchwork Fri Apr 26 15:48:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Hemminger X-Patchwork-Id: 139712 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 038D943F19; Fri, 26 Apr 2024 17:52:28 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 5AF5D43F24; Fri, 26 Apr 2024 17:51:48 +0200 (CEST) Received: from mail-pg1-f176.google.com (mail-pg1-f176.google.com [209.85.215.176]) by mails.dpdk.org (Postfix) with ESMTP id 0136143F0B for ; Fri, 26 Apr 2024 17:51:43 +0200 (CEST) Received: by mail-pg1-f176.google.com with SMTP id 41be03b00d2f7-5c229dabbb6so1577824a12.0 for ; Fri, 26 Apr 2024 08:51:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=networkplumber-org.20230601.gappssmtp.com; s=20230601; t=1714146702; x=1714751502; darn=dpdk.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=k65SDCHwmSyyBJZ8DiohRCGj/brh5bz3P4txRIRxCW8=; b=rNBb4CvxBx8D750CGUo8Gvax4UW0+Lo39KdS7bb+O6xqbtGqTQQUXBPMMWQGcgUQmT f0Ffdea/1piJLp9TederXbcLYLNjEy/rHVT7+ry4TCXRorVnzG56RzgrGvOTY3KezNtb YCBBtpzcv1SeC+lyVodqXW9kwDv0L0CHsN0gLqg4f66wO2JBHQBcDoLBp6pT/ciF4QCV 1hdqji1CKWygNWqKfbHtx9PYXoZzUFOkKl3I0Vktmy6pI55Ge5xM78bvVT167X/UxImb WU8xJSz1ZHGnNdx84mx6g/CoyUvsBFGR4MZu5BqlSEo6q7z+fzOMCE/VBxTnmqfXu0+5 aPcg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714146702; x=1714751502; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=k65SDCHwmSyyBJZ8DiohRCGj/brh5bz3P4txRIRxCW8=; b=LtMr7aAUw/r8iB9mJyEsSYry0ZkAMXM4+vZbCfn+vdBLjWlWdT5f+EqhHF+NxWSYzN bQGTnYjyiyBPUMH6OpIgRVI8tactCQ8mKMIr9UJohtCKhA6rdesdlyObwWwSFN/Ta8UU L5j4VNE0jAuQwbDnmh+pqNEtI6CiE8Evtmn1yA70FoVEQSMjHJAXOv17FhYkdtnuN4cV DBC5U/85S5sVjVzig6MVJyvfPUrBfvKUMjJEsrBmNChLsqXw0oCYSGPO//g2tu4XJAtF +fMRbsFILgvJbV3cDi5JfdoZWS6L3kore3KV4U689xn8S3hOB1ak38GpCBTkOU6nNmIT 7Szw== X-Gm-Message-State: AOJu0YwHv/theTBIahaRG9Ru4wr4rgMXDp/FaQ5P6oEGCdZBcloO9JSi EYAdiAo8zhpseYNEpDnc3Gq6KkNl84/zJK/bSHsxCwR8oRao9Zy4CPeuzMOdhJr6FVV/uLha93Z qQfc= X-Google-Smtp-Source: AGHT+IEf/8nAWVUYBIuLd1rhG7bKLa/UsKcQd+bVxDwLXt28R3/0E4/T7bF2hsf8JyJKCeevagqXJg== X-Received: by 2002:a17:90a:aa0b:b0:2af:8fa4:40e with SMTP id k11-20020a17090aaa0b00b002af8fa4040emr3067455pjq.1.1714146701796; Fri, 26 Apr 2024 08:51:41 -0700 (PDT) Received: from hermes.local (204-195-96-226.wavecable.com. [204.195.96.226]) by smtp.gmail.com with ESMTPSA id ns5-20020a17090b250500b002a5f44353d2sm16770978pjb.7.2024.04.26.08.51.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 26 Apr 2024 08:51:41 -0700 (PDT) From: Stephen Hemminger To: dev@dpdk.org Cc: Stephen Hemminger Subject: [PATCH v9 7/9] net/tap: remove no longer used files Date: Fri, 26 Apr 2024 08:48:57 -0700 Message-ID: <20240426155125.125910-8-stephen@networkplumber.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240426155125.125910-1-stephen@networkplumber.org> References: <20240130034925.44869-1-stephen@networkplumber.org> <20240426155125.125910-1-stephen@networkplumber.org> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org The BPF api was replaced by use of libbpf. And the BPF instruction header was replaced by the skeleton. Signed-off-by: Stephen Hemminger --- drivers/net/tap/tap_bpf_api.c | 196 ---- drivers/net/tap/tap_bpf_insns.h | 1741 ------------------------------- 2 files changed, 1937 deletions(-) delete mode 100644 drivers/net/tap/tap_bpf_api.c delete mode 100644 drivers/net/tap/tap_bpf_insns.h diff --git a/drivers/net/tap/tap_bpf_api.c b/drivers/net/tap/tap_bpf_api.c deleted file mode 100644 index 9e05e2ddf1..0000000000 --- a/drivers/net/tap/tap_bpf_api.c +++ /dev/null @@ -1,196 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright 2017 Mellanox Technologies, Ltd - */ - -#include -#include -#include - -#include -#include - -#include - - -static int bpf_load(enum bpf_prog_type type, const struct bpf_insn *insns, - size_t insns_cnt, const char *license); - -/** - * Load BPF program (section cls_q) into the kernel and return a bpf fd - * - * @param queue_idx - * Queue index matching packet cb - * - * @return - * -1 if the BPF program couldn't be loaded. An fd (int) otherwise. - */ -int tap_flow_bpf_cls_q(__u32 queue_idx) -{ - cls_q_insns[1].imm = queue_idx; - - return bpf_load(BPF_PROG_TYPE_SCHED_CLS, - (struct bpf_insn *)cls_q_insns, - RTE_DIM(cls_q_insns), - "Dual BSD/GPL"); -} - -/** - * Load BPF program (section l3_l4) into the kernel and return a bpf fd. - * - * @param[in] key_idx - * RSS MAP key index - * - * @param[in] map_fd - * BPF RSS map file descriptor - * - * @return - * -1 if the BPF program couldn't be loaded. An fd (int) otherwise. - */ -int tap_flow_bpf_calc_l3_l4_hash(__u32 key_idx, int map_fd) -{ - l3_l4_hash_insns[4].imm = key_idx; - l3_l4_hash_insns[9].imm = map_fd; - - return bpf_load(BPF_PROG_TYPE_SCHED_ACT, - (struct bpf_insn *)l3_l4_hash_insns, - RTE_DIM(l3_l4_hash_insns), - "Dual BSD/GPL"); -} - -/** - * Helper function to convert a pointer to unsigned 64 bits - * - * @param[in] ptr - * pointer to address - * - * @return - * 64 bit unsigned long type of pointer address - */ -static inline __u64 ptr_to_u64(const void *ptr) -{ - return (__u64)(unsigned long)ptr; -} - -/** - * Call BPF system call - * - * @param[in] cmd - * BPF command for program loading, map creation, map entry update, etc - * - * @param[in] attr - * System call attributes relevant to system call command - * - * @param[in] size - * size of attr parameter - * - * @return - * -1 if BPF system call failed, 0 otherwise - */ -static inline int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr, - unsigned int size) -{ -#ifdef __NR_bpf - return syscall(__NR_bpf, cmd, attr, size); -#else - TAP_LOG(ERR, "No bpf syscall, kernel headers too old?\n"); - errno = ENOSYS; - return -1; -#endif -} - -/** - * Load BPF instructions to kernel - * - * @param[in] type - * BPF program type: classifier or action - * - * @param[in] insns - * Array of BPF instructions (equivalent to BPF instructions) - * - * @param[in] insns_cnt - * Number of BPF instructions (size of array) - * - * @param[in] license - * License string that must be acknowledged by the kernel - * - * @return - * -1 if the BPF program couldn't be loaded, fd (file descriptor) otherwise - */ -static int bpf_load(enum bpf_prog_type type, - const struct bpf_insn *insns, - size_t insns_cnt, - const char *license) -{ - union bpf_attr attr = {}; - - bzero(&attr, sizeof(attr)); - attr.prog_type = type; - attr.insn_cnt = (__u32)insns_cnt; - attr.insns = ptr_to_u64(insns); - attr.license = ptr_to_u64(license); - attr.log_buf = ptr_to_u64(NULL); - attr.log_level = 0; - attr.kern_version = 0; - - return sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr)); -} - -/** - * Create BPF map for RSS rules - * - * @param[in] key_size - * map RSS key size - * - * @param[in] value_size - * Map RSS value size - * - * @param[in] max_entries - * Map max number of RSS entries (limit on max RSS rules) - * - * @return - * -1 if BPF map couldn't be created, map fd otherwise - */ -int tap_flow_bpf_rss_map_create(unsigned int key_size, - unsigned int value_size, - unsigned int max_entries) -{ - union bpf_attr attr = {}; - - bzero(&attr, sizeof(attr)); - attr.map_type = BPF_MAP_TYPE_HASH; - attr.key_size = key_size; - attr.value_size = value_size; - attr.max_entries = max_entries; - - return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr)); -} - -/** - * Update RSS entry in BPF map - * - * @param[in] fd - * RSS map fd - * - * @param[in] key - * Pointer to RSS key whose entry is updated - * - * @param[in] value - * Pointer to RSS new updated value - * - * @return - * -1 if RSS entry failed to be updated, 0 otherwise - */ -int tap_flow_bpf_update_rss_elem(int fd, void *key, void *value) -{ - union bpf_attr attr = {}; - - bzero(&attr, sizeof(attr)); - - attr.map_type = BPF_MAP_TYPE_HASH; - attr.map_fd = fd; - attr.key = ptr_to_u64(key); - attr.value = ptr_to_u64(value); - attr.flags = BPF_ANY; - - return sys_bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr)); -} diff --git a/drivers/net/tap/tap_bpf_insns.h b/drivers/net/tap/tap_bpf_insns.h deleted file mode 100644 index cdf2febf05..0000000000 --- a/drivers/net/tap/tap_bpf_insns.h +++ /dev/null @@ -1,1741 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Auto-generated from tap_bpf_program.c - * This not the original source file. Do NOT edit it. - */ - -static struct bpf_insn cls_q_insns[] = { - {0x61, 2, 1, 52, 0x00000000}, - {0x18, 3, 0, 0, 0xdeadbeef}, - {0x00, 0, 0, 0, 0x00000000}, - {0x63, 10, 3, -4, 0x00000000}, - {0xb7, 0, 0, 0, 0x00000000}, - {0x61, 3, 10, -4, 0x00000000}, - {0x07, 3, 0, 0, 0x7cafe800}, - {0x67, 3, 0, 0, 0x00000020}, - {0x77, 3, 0, 0, 0x00000020}, - {0x5d, 2, 3, 4, 0x00000000}, - {0xb7, 2, 0, 0, 0x00000000}, - {0x63, 1, 2, 52, 0x00000000}, - {0x18, 0, 0, 0, 0xffffffff}, - {0x00, 0, 0, 0, 0x00000000}, - {0x95, 0, 0, 0, 0x00000000}, -}; - -static struct bpf_insn l3_l4_hash_insns[] = { - {0xbf, 7, 1, 0, 0x00000000}, - {0x61, 6, 7, 16, 0x00000000}, - {0x61, 8, 7, 76, 0x00000000}, - {0x61, 9, 7, 80, 0x00000000}, - {0x18, 1, 0, 0, 0xdeadbeef}, - {0x00, 0, 0, 0, 0x00000000}, - {0x63, 10, 1, -4, 0x00000000}, - {0xbf, 2, 10, 0, 0x00000000}, - {0x07, 2, 0, 0, 0xfffffffc}, - {0x18, 1, 0, 0, 0x00000000}, - {0x00, 0, 0, 0, 0x00000000}, - {0x85, 0, 0, 0, 0x00000001}, - {0x55, 0, 0, 21, 0x00000000}, - {0xb7, 1, 0, 0, 0x00000a64}, - {0x6b, 10, 1, -16, 0x00000000}, - {0x18, 1, 0, 0, 0x69666e6f}, - {0x00, 0, 0, 0, 0x65727567}, - {0x7b, 10, 1, -24, 0x00000000}, - {0x18, 1, 0, 0, 0x6e207369}, - {0x00, 0, 0, 0, 0x6320746f}, - {0x7b, 10, 1, -32, 0x00000000}, - {0x18, 1, 0, 0, 0x20737372}, - {0x00, 0, 0, 0, 0x2079656b}, - {0x7b, 10, 1, -40, 0x00000000}, - {0x18, 1, 0, 0, 0x68736168}, - {0x00, 0, 0, 0, 0x203a2928}, - {0x7b, 10, 1, -48, 0x00000000}, - {0xb7, 7, 0, 0, 0x00000000}, - {0x73, 10, 7, -14, 0x00000000}, - {0xbf, 1, 10, 0, 0x00000000}, - {0x07, 1, 0, 0, 0xffffffd0}, - {0xb7, 2, 0, 0, 0x00000023}, - {0x85, 0, 0, 0, 0x00000006}, - {0x05, 0, 0, 1680, 0x00000000}, - {0xb7, 1, 0, 0, 0x0000000e}, - {0x61, 2, 7, 20, 0x00000000}, - {0x15, 2, 0, 10, 0x00000000}, - {0x61, 2, 7, 28, 0x00000000}, - {0x55, 2, 0, 8, 0x0000a888}, - {0xbf, 2, 7, 0, 0x00000000}, - {0xb7, 7, 0, 0, 0x00000000}, - {0xbf, 1, 8, 0, 0x00000000}, - {0x07, 1, 0, 0, 0x00000012}, - {0x2d, 1, 9, 1670, 0x00000000}, - {0xb7, 1, 0, 0, 0x00000012}, - {0x69, 6, 8, 16, 0x00000000}, - {0xbf, 7, 2, 0, 0x00000000}, - {0x57, 6, 0, 0, 0x0000ffff}, - {0x7b, 10, 7, -56, 0x00000000}, - {0x15, 6, 0, 443, 0x0000dd86}, - {0xb7, 7, 0, 0, 0x00000003}, - {0x55, 6, 0, 1662, 0x00000008}, - {0x0f, 8, 1, 0, 0x00000000}, - {0xb7, 7, 0, 0, 0x00000000}, - {0xbf, 1, 8, 0, 0x00000000}, - {0x07, 1, 0, 0, 0x00000018}, - {0x2d, 1, 9, 1657, 0x00000000}, - {0xb7, 1, 0, 0, 0x00000000}, - {0x71, 3, 8, 12, 0x00000000}, - {0x71, 2, 8, 9, 0x00000000}, - {0x15, 2, 0, 1, 0x00000011}, - {0x55, 2, 0, 21, 0x00000006}, - {0x71, 2, 8, 7, 0x00000000}, - {0x71, 4, 8, 6, 0x00000000}, - {0xbf, 5, 4, 0, 0x00000000}, - {0x67, 5, 0, 0, 0x00000008}, - {0x57, 5, 0, 0, 0x00001f00}, - {0x4f, 5, 2, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000020}, - {0x4f, 4, 5, 0, 0x00000000}, - {0x55, 4, 0, 12, 0x00000000}, - {0xbf, 2, 8, 0, 0x00000000}, - {0x07, 2, 0, 0, 0x00000014}, - {0x71, 4, 2, 0, 0x00000000}, - {0x67, 4, 0, 0, 0x00000018}, - {0x71, 1, 2, 1, 0x00000000}, - {0x67, 1, 0, 0, 0x00000010}, - {0x4f, 1, 4, 0, 0x00000000}, - {0x71, 4, 2, 3, 0x00000000}, - {0x4f, 1, 4, 0, 0x00000000}, - {0x71, 2, 2, 2, 0x00000000}, - {0x67, 2, 0, 0, 0x00000008}, - {0x4f, 1, 2, 0, 0x00000000}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x67, 4, 0, 0, 0x00000038}, - {0xc7, 4, 0, 0, 0x00000038}, - {0xb7, 2, 0, 0, 0x00000000}, - {0x65, 4, 0, 1, 0xffffffff}, - {0xb7, 7, 0, 0, 0x2cc681d1}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000040}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x598d03a2}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000020}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xb31a0745}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000010}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x66340e8a}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000008}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xcc681d15}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000004}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x98d03a2b}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000002}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x31a07456}, - {0x71, 4, 8, 13, 0x00000000}, - {0x57, 3, 0, 0, 0x00000001}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x6340e8ad}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x67, 3, 0, 0, 0x00000038}, - {0xc7, 3, 0, 0, 0x00000038}, - {0xbf, 5, 7, 0, 0x00000000}, - {0xa7, 5, 0, 0, 0xc681d15b}, - {0x6d, 2, 3, 1, 0x00000000}, - {0xbf, 5, 7, 0, 0x00000000}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000040}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x8d03a2b7}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000020}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x1a07456f}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000010}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x340e8ade}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000008}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x681d15bd}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000004}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xd03a2b7b}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000002}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xa07456f6}, - {0x71, 3, 8, 14, 0x00000000}, - {0x57, 4, 0, 0, 0x00000001}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x40e8aded}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x67, 4, 0, 0, 0x00000038}, - {0xc7, 4, 0, 0, 0x00000038}, - {0xbf, 7, 5, 0, 0x00000000}, - {0xa7, 7, 0, 0, 0x81d15bdb}, - {0x6d, 2, 4, 1, 0x00000000}, - {0xbf, 7, 5, 0, 0x00000000}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000040}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x03a2b7b7}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000020}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x07456f6f}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000010}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x0e8adedf}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000008}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x1d15bdbf}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000004}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x3a2b7b7e}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000002}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x7456f6fd}, - {0x71, 4, 8, 15, 0x00000000}, - {0x57, 3, 0, 0, 0x00000001}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xe8adedfa}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x67, 3, 0, 0, 0x00000038}, - {0xc7, 3, 0, 0, 0x00000038}, - {0xbf, 5, 7, 0, 0x00000000}, - {0xa7, 5, 0, 0, 0xd15bdbf4}, - {0x6d, 2, 3, 1, 0x00000000}, - {0xbf, 5, 7, 0, 0x00000000}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000040}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xa2b7b7e9}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000020}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x456f6fd3}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000010}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x8adedfa7}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000008}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x15bdbf4f}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000004}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x2b7b7e9e}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000002}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x56f6fd3d}, - {0x71, 3, 8, 16, 0x00000000}, - {0x57, 4, 0, 0, 0x00000001}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xadedfa7b}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x67, 4, 0, 0, 0x00000038}, - {0xc7, 4, 0, 0, 0x00000038}, - {0xbf, 7, 5, 0, 0x00000000}, - {0xa7, 7, 0, 0, 0x5bdbf4f7}, - {0x6d, 2, 4, 1, 0x00000000}, - {0xbf, 7, 5, 0, 0x00000000}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000040}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xb7b7e9ef}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000020}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x6f6fd3df}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000010}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xdedfa7bf}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000008}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xbdbf4f7f}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000004}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x7b7e9eff}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000002}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xf6fd3dff}, - {0x71, 4, 8, 17, 0x00000000}, - {0x57, 3, 0, 0, 0x00000001}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xedfa7bfe}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x67, 3, 0, 0, 0x00000038}, - {0xc7, 3, 0, 0, 0x00000038}, - {0xbf, 5, 7, 0, 0x00000000}, - {0xa7, 5, 0, 0, 0xdbf4f7fc}, - {0x6d, 2, 3, 1, 0x00000000}, - {0xbf, 5, 7, 0, 0x00000000}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000040}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xb7e9eff9}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000020}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x6fd3dff2}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000010}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xdfa7bfe5}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000008}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xbf4f7fca}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000004}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x7e9eff94}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000002}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xfd3dff28}, - {0x71, 3, 8, 18, 0x00000000}, - {0x57, 4, 0, 0, 0x00000001}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xfa7bfe51}, - {0xbf, 6, 3, 0, 0x00000000}, - {0x67, 6, 0, 0, 0x00000038}, - {0xc7, 6, 0, 0, 0x00000038}, - {0xbf, 4, 5, 0, 0x00000000}, - {0xa7, 4, 0, 0, 0xf4f7fca2}, - {0x6d, 2, 6, 1, 0x00000000}, - {0xbf, 4, 5, 0, 0x00000000}, - {0xbf, 5, 3, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x00000040}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0xe9eff945}, - {0xbf, 5, 3, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x00000020}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0xd3dff28a}, - {0xbf, 5, 3, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x00000010}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0xa7bfe514}, - {0xbf, 5, 3, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x00000008}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x4f7fca28}, - {0xbf, 5, 3, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x00000004}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x9eff9450}, - {0xbf, 5, 3, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x00000002}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x3dff28a0}, - {0x71, 5, 8, 19, 0x00000000}, - {0x57, 3, 0, 0, 0x00000001}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x7bfe5141}, - {0xbf, 3, 5, 0, 0x00000000}, - {0x67, 3, 0, 0, 0x00000038}, - {0xc7, 3, 0, 0, 0x00000038}, - {0xbf, 7, 4, 0, 0x00000000}, - {0xa7, 7, 0, 0, 0xf7fca283}, - {0x6d, 2, 3, 1, 0x00000000}, - {0xbf, 7, 4, 0, 0x00000000}, - {0xbf, 3, 5, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000040}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xeff94506}, - {0xbf, 3, 5, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000020}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xdff28a0c}, - {0xbf, 3, 5, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000010}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xbfe51418}, - {0xbf, 3, 5, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000008}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x7fca2831}, - {0xbf, 3, 5, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000004}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xff945063}, - {0xbf, 3, 5, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000002}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xff28a0c6}, - {0x57, 5, 0, 0, 0x00000001}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xfe51418c}, - {0xbf, 4, 1, 0, 0x00000000}, - {0x67, 4, 0, 0, 0x00000020}, - {0xc7, 4, 0, 0, 0x00000020}, - {0xbf, 3, 7, 0, 0x00000000}, - {0xa7, 3, 0, 0, 0xfca28319}, - {0x6d, 2, 4, 1, 0x00000000}, - {0xbf, 3, 7, 0, 0x00000000}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x40000000}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0xf9450633}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x20000000}, - {0x79, 6, 10, -56, 0x00000000}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0xf28a0c67}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x10000000}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0xe51418ce}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x08000000}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0xca28319d}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x04000000}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x9450633b}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x02000000}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x28a0c676}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x01000000}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x51418ced}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00800000}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0xa28319db}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00400000}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x450633b6}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00200000}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x8a0c676c}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00100000}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x1418ced8}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00080000}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x28319db1}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00040000}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x50633b63}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00020000}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0xa0c676c6}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00010000}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x418ced8d}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00008000}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x8319db1a}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00004000}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x0633b634}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00002000}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x0c676c68}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00001000}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x18ced8d1}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00000800}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x319db1a3}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00000400}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x633b6347}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00000200}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0xc676c68f}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00000100}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x8ced8d1f}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00000080}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x19db1a3e}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00000040}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x33b6347d}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00000020}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x676c68fa}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00000010}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0xced8d1f4}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00000008}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x9db1a3e9}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00000004}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x3b6347d2}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00000002}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x76c68fa5}, - {0x57, 1, 0, 0, 0x00000001}, - {0x15, 1, 0, 1194, 0x00000000}, - {0xa7, 3, 0, 0, 0xed8d1f4a}, - {0x05, 0, 0, 1192, 0x00000000}, - {0x0f, 8, 1, 0, 0x00000000}, - {0xb7, 7, 0, 0, 0x00000000}, - {0xbf, 1, 8, 0, 0x00000000}, - {0x07, 1, 0, 0, 0x0000002c}, - {0x2d, 1, 9, 1216, 0x00000000}, - {0x61, 2, 8, 8, 0x00000000}, - {0xdc, 2, 0, 0, 0x00000040}, - {0xc7, 2, 0, 0, 0x00000020}, - {0x71, 3, 8, 6, 0x00000000}, - {0x15, 3, 0, 2, 0x00000011}, - {0xb7, 1, 0, 0, 0x00000000}, - {0x55, 3, 0, 12, 0x00000006}, - {0xbf, 3, 8, 0, 0x00000000}, - {0x07, 3, 0, 0, 0x00000028}, - {0x71, 4, 3, 0, 0x00000000}, - {0x67, 4, 0, 0, 0x00000018}, - {0x71, 1, 3, 1, 0x00000000}, - {0x67, 1, 0, 0, 0x00000010}, - {0x4f, 1, 4, 0, 0x00000000}, - {0x71, 4, 3, 3, 0x00000000}, - {0x4f, 1, 4, 0, 0x00000000}, - {0x71, 3, 3, 2, 0x00000000}, - {0x67, 3, 0, 0, 0x00000008}, - {0x4f, 1, 3, 0, 0x00000000}, - {0xbf, 4, 2, 0, 0x00000000}, - {0x77, 4, 0, 0, 0x0000001f}, - {0x57, 4, 0, 0, 0x2cc681d1}, - {0xbf, 3, 2, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x40000000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x598d03a2}, - {0xbf, 3, 2, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x20000000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0xb31a0745}, - {0xbf, 3, 2, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x10000000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x66340e8a}, - {0xbf, 3, 2, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x08000000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0xcc681d15}, - {0xbf, 3, 2, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x04000000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x98d03a2b}, - {0xbf, 3, 2, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x02000000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x31a07456}, - {0xbf, 3, 2, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x01000000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x6340e8ad}, - {0xbf, 3, 2, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00800000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0xc681d15b}, - {0xbf, 3, 2, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00400000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x8d03a2b7}, - {0xbf, 3, 2, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00200000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x1a07456f}, - {0xbf, 3, 2, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00100000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x340e8ade}, - {0xbf, 3, 2, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00080000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x681d15bd}, - {0xbf, 3, 2, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00040000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0xd03a2b7b}, - {0xbf, 3, 2, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00020000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0xa07456f6}, - {0xbf, 3, 2, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00010000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x40e8aded}, - {0xbf, 3, 2, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00008000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x81d15bdb}, - {0xbf, 3, 2, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00004000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x03a2b7b7}, - {0xbf, 3, 2, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00002000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x07456f6f}, - {0xbf, 3, 2, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00001000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x0e8adedf}, - {0xbf, 3, 2, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000800}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x1d15bdbf}, - {0xbf, 3, 2, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000400}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x3a2b7b7e}, - {0xbf, 3, 2, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000200}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x7456f6fd}, - {0xbf, 3, 2, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000100}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0xe8adedfa}, - {0xbf, 3, 2, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000080}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0xd15bdbf4}, - {0xbf, 3, 2, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000040}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0xa2b7b7e9}, - {0xbf, 3, 2, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000020}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x456f6fd3}, - {0xbf, 3, 2, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000010}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x8adedfa7}, - {0xbf, 3, 2, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000008}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x15bdbf4f}, - {0x61, 3, 8, 12, 0x00000000}, - {0xbf, 5, 2, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x00000004}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x2b7b7e9e}, - {0xdc, 3, 0, 0, 0x00000040}, - {0xbf, 5, 2, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x00000002}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x56f6fd3d}, - {0xc7, 3, 0, 0, 0x00000020}, - {0x57, 2, 0, 0, 0x00000001}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0xadedfa7b}, - {0xb7, 2, 0, 0, 0x00000000}, - {0xbf, 5, 4, 0, 0x00000000}, - {0xa7, 5, 0, 0, 0x5bdbf4f7}, - {0x6d, 2, 3, 1, 0x00000000}, - {0xbf, 5, 4, 0, 0x00000000}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x40000000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xb7b7e9ef}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x20000000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x6f6fd3df}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x10000000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xdedfa7bf}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x08000000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xbdbf4f7f}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x04000000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x7b7e9eff}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x02000000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xf6fd3dff}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x01000000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xedfa7bfe}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00800000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xdbf4f7fc}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00400000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xb7e9eff9}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00200000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x6fd3dff2}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00100000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xdfa7bfe5}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00080000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xbf4f7fca}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00040000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x7e9eff94}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00020000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xfd3dff28}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00010000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xfa7bfe51}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00008000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xf4f7fca2}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00004000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xe9eff945}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00002000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xd3dff28a}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00001000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xa7bfe514}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000800}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x4f7fca28}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000400}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x9eff9450}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000200}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x3dff28a0}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000100}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x7bfe5141}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000080}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xf7fca283}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000040}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xeff94506}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000020}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xdff28a0c}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000010}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xbfe51418}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000008}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x7fca2831}, - {0x61, 4, 8, 16, 0x00000000}, - {0xbf, 6, 3, 0, 0x00000000}, - {0x57, 6, 0, 0, 0x00000004}, - {0x15, 6, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xff945063}, - {0xdc, 4, 0, 0, 0x00000040}, - {0xbf, 6, 3, 0, 0x00000000}, - {0x57, 6, 0, 0, 0x00000002}, - {0x15, 6, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xff28a0c6}, - {0xc7, 4, 0, 0, 0x00000020}, - {0x57, 3, 0, 0, 0x00000001}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xfe51418c}, - {0xbf, 7, 5, 0, 0x00000000}, - {0xa7, 7, 0, 0, 0xfca28319}, - {0x6d, 2, 4, 1, 0x00000000}, - {0xbf, 7, 5, 0, 0x00000000}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x40000000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xf9450633}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x20000000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xf28a0c67}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x10000000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xe51418ce}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x08000000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xca28319d}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x04000000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x9450633b}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x02000000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x28a0c676}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x01000000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x51418ced}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00800000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xa28319db}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00400000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x450633b6}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00200000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x8a0c676c}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00100000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x1418ced8}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00080000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x28319db1}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00040000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x50633b63}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00020000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xa0c676c6}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00010000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x418ced8d}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00008000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x8319db1a}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00004000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x0633b634}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00002000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x0c676c68}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00001000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x18ced8d1}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000800}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x319db1a3}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000400}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x633b6347}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000200}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xc676c68f}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000100}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x8ced8d1f}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000080}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x19db1a3e}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000040}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x33b6347d}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000020}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x676c68fa}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000010}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xced8d1f4}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000008}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x9db1a3e9}, - {0x61, 3, 8, 20, 0x00000000}, - {0xbf, 5, 4, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x00000004}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x3b6347d2}, - {0xdc, 3, 0, 0, 0x00000040}, - {0xbf, 5, 4, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x00000002}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x76c68fa5}, - {0xc7, 3, 0, 0, 0x00000020}, - {0x57, 4, 0, 0, 0x00000001}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xed8d1f4a}, - {0xbf, 5, 7, 0, 0x00000000}, - {0xa7, 5, 0, 0, 0xdb1a3e94}, - {0x6d, 2, 3, 1, 0x00000000}, - {0xbf, 5, 7, 0, 0x00000000}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x40000000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xb6347d28}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x20000000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x6c68fa51}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x10000000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xd8d1f4a3}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x08000000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xb1a3e946}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x04000000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x6347d28d}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x02000000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xc68fa51a}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x01000000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x8d1f4a35}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00800000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x1a3e946b}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00400000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x347d28d7}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00200000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x68fa51ae}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00100000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xd1f4a35c}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00080000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xa3e946b9}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00040000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x47d28d73}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00020000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x8fa51ae7}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00010000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x1f4a35cf}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00008000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x3e946b9e}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00004000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x7d28d73c}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00002000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xfa51ae78}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00001000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xf4a35cf1}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000800}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xe946b9e3}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000400}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xd28d73c7}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000200}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xa51ae78e}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000100}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x4a35cf1c}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000080}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x946b9e38}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000040}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x28d73c71}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000020}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x51ae78e3}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000010}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xa35cf1c6}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000008}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x46b9e38d}, - {0x61, 4, 8, 24, 0x00000000}, - {0xbf, 6, 3, 0, 0x00000000}, - {0x57, 6, 0, 0, 0x00000004}, - {0x15, 6, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x8d73c71b}, - {0xdc, 4, 0, 0, 0x00000040}, - {0xbf, 6, 3, 0, 0x00000000}, - {0x57, 6, 0, 0, 0x00000002}, - {0x15, 6, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x1ae78e36}, - {0xc7, 4, 0, 0, 0x00000020}, - {0x57, 3, 0, 0, 0x00000001}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x35cf1c6c}, - {0xbf, 7, 5, 0, 0x00000000}, - {0xa7, 7, 0, 0, 0x6b9e38d9}, - {0x6d, 2, 4, 1, 0x00000000}, - {0xbf, 7, 5, 0, 0x00000000}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x40000000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xd73c71b2}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x20000000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xae78e364}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x10000000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x5cf1c6c9}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x08000000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xb9e38d92}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x04000000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x73c71b25}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x02000000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xe78e364b}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x01000000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xcf1c6c96}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00800000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x9e38d92c}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00400000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x3c71b259}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00200000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x78e364b2}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00100000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xf1c6c964}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00080000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xe38d92c9}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00040000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xc71b2593}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00020000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x8e364b27}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00010000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x1c6c964e}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00008000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x38d92c9c}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00004000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x71b25938}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00002000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xe364b270}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00001000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xc6c964e0}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000800}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x8d92c9c0}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000400}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x1b259380}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000200}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x364b2700}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000100}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x6c964e01}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000080}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xd92c9c03}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000040}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xb2593807}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000020}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x64b2700f}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000010}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xc964e01e}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000008}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x92c9c03d}, - {0x61, 3, 8, 28, 0x00000000}, - {0xbf, 5, 4, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x00000004}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x2593807a}, - {0xdc, 3, 0, 0, 0x00000040}, - {0xbf, 5, 4, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x00000002}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x4b2700f4}, - {0xc7, 3, 0, 0, 0x00000020}, - {0x57, 4, 0, 0, 0x00000001}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x964e01e8}, - {0xbf, 5, 7, 0, 0x00000000}, - {0xa7, 5, 0, 0, 0x2c9c03d1}, - {0x6d, 2, 3, 1, 0x00000000}, - {0xbf, 5, 7, 0, 0x00000000}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x40000000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x593807a3}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x20000000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xb2700f46}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x10000000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x64e01e8d}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x08000000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xc9c03d1a}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x04000000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x93807a35}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x02000000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x2700f46b}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x01000000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x4e01e8d6}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00800000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x9c03d1ad}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00400000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x3807a35b}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00200000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x700f46b6}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00100000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xe01e8d6c}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00080000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xc03d1ad9}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00040000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x807a35b3}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00020000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x00f46b66}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00010000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x01e8d6cc}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00008000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x03d1ad99}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00004000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x07a35b32}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00002000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x0f46b665}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00001000}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x1e8d6cca}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000800}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x3d1ad994}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000400}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x7a35b328}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000200}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xf46b6651}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000100}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xe8d6cca2}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000080}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xd1ad9944}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000040}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xa35b3289}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000020}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x46b66512}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000010}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x8d6cca25}, - {0xbf, 4, 3, 0, 0x00000000}, - {0x57, 4, 0, 0, 0x00000008}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x1ad9944a}, - {0x61, 4, 8, 32, 0x00000000}, - {0xbf, 6, 3, 0, 0x00000000}, - {0x57, 6, 0, 0, 0x00000004}, - {0x15, 6, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x35b32894}, - {0xdc, 4, 0, 0, 0x00000040}, - {0xbf, 6, 3, 0, 0x00000000}, - {0x57, 6, 0, 0, 0x00000002}, - {0x15, 6, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0x6b665129}, - {0xc7, 4, 0, 0, 0x00000020}, - {0x57, 3, 0, 0, 0x00000001}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 5, 0, 0, 0xd6cca253}, - {0xbf, 7, 5, 0, 0x00000000}, - {0xa7, 7, 0, 0, 0xad9944a7}, - {0x6d, 2, 4, 1, 0x00000000}, - {0xbf, 7, 5, 0, 0x00000000}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x40000000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x5b32894f}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x20000000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xb665129f}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x10000000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x6cca253e}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x08000000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xd9944a7d}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x04000000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xb32894fb}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x02000000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x665129f6}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x01000000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xcca253ec}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00800000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x9944a7d9}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00400000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x32894fb2}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00200000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x65129f65}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00100000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xca253eca}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00080000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x944a7d95}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00040000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x2894fb2a}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00020000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x5129f655}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00010000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xa253ecab}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00008000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x44a7d956}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00004000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x894fb2ac}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00002000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x129f6558}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00001000}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x253ecab1}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000800}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x4a7d9563}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000400}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x94fb2ac7}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000200}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x29f6558f}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000100}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x53ecab1e}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000080}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xa7d9563d}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000040}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x4fb2ac7a}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000020}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x9f6558f5}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000010}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x3ecab1ea}, - {0xbf, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x00000008}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0x7d9563d5}, - {0x61, 3, 8, 36, 0x00000000}, - {0xbf, 5, 4, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x00000004}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xfb2ac7ab}, - {0xdc, 3, 0, 0, 0x00000040}, - {0xbf, 5, 4, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x00000002}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xf6558f56}, - {0xc7, 3, 0, 0, 0x00000020}, - {0x57, 4, 0, 0, 0x00000001}, - {0x15, 4, 0, 1, 0x00000000}, - {0xa7, 7, 0, 0, 0xecab1eac}, - {0xbf, 4, 7, 0, 0x00000000}, - {0xa7, 4, 0, 0, 0xd9563d59}, - {0x6d, 2, 3, 1, 0x00000000}, - {0xbf, 4, 7, 0, 0x00000000}, - {0xbf, 5, 3, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x40000000}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0xb2ac7ab2}, - {0xbf, 5, 3, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x20000000}, - {0x79, 6, 10, -56, 0x00000000}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x6558f564}, - {0xbf, 5, 3, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x10000000}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0xcab1eac8}, - {0xbf, 5, 3, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x08000000}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x9563d590}, - {0xbf, 5, 3, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x04000000}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x2ac7ab20}, - {0xbf, 5, 3, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x02000000}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x558f5641}, - {0xbf, 5, 3, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x01000000}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0xab1eac83}, - {0xbf, 5, 3, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x00800000}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x563d5906}, - {0xbf, 5, 3, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x00400000}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0xac7ab20c}, - {0xbf, 5, 3, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x00200000}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x58f56418}, - {0xbf, 5, 3, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x00100000}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0xb1eac831}, - {0xbf, 5, 3, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x00080000}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x63d59063}, - {0xbf, 5, 3, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x00040000}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0xc7ab20c7}, - {0xbf, 5, 3, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x00020000}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x8f56418f}, - {0xbf, 5, 3, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x00010000}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x1eac831e}, - {0xbf, 5, 3, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x00008000}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x3d59063c}, - {0xbf, 5, 3, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x00004000}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x7ab20c78}, - {0xbf, 5, 3, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x00002000}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0xf56418f0}, - {0xbf, 5, 3, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x00001000}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0xeac831e1}, - {0xbf, 5, 3, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x00000800}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0xd59063c2}, - {0xbf, 5, 3, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x00000400}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0xab20c784}, - {0xbf, 5, 3, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x00000200}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x56418f09}, - {0xbf, 5, 3, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x00000100}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0xac831e12}, - {0xbf, 5, 3, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x00000080}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x59063c25}, - {0xbf, 5, 3, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x00000040}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0xb20c784b}, - {0xbf, 5, 3, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x00000020}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x6418f097}, - {0xbf, 5, 3, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x00000010}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0xc831e12f}, - {0xbf, 5, 3, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x00000008}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x9063c25f}, - {0xbf, 5, 3, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x00000004}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x20c784be}, - {0xbf, 5, 3, 0, 0x00000000}, - {0x57, 5, 0, 0, 0x00000002}, - {0x15, 5, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x418f097c}, - {0x57, 3, 0, 0, 0x00000001}, - {0x15, 3, 0, 1, 0x00000000}, - {0xa7, 4, 0, 0, 0x831e12f9}, - {0xbf, 5, 1, 0, 0x00000000}, - {0x67, 5, 0, 0, 0x00000020}, - {0xc7, 5, 0, 0, 0x00000020}, - {0xbf, 3, 4, 0, 0x00000000}, - {0xa7, 3, 0, 0, 0x063c25f3}, - {0x6d, 2, 5, 1, 0x00000000}, - {0xbf, 3, 4, 0, 0x00000000}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x40000000}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x0c784be7}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x20000000}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x18f097cf}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x10000000}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x31e12f9f}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x08000000}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x63c25f3f}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x04000000}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0xc784be7f}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x02000000}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x8f097cff}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x01000000}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x1e12f9fe}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00800000}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x3c25f3fc}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00400000}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x784be7f8}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00200000}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0xf097cff0}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00100000}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0xe12f9fe0}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00080000}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0xc25f3fc1}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00040000}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x84be7f83}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00020000}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x097cff07}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00010000}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x12f9fe0f}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00008000}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x25f3fc1f}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00004000}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x4be7f83f}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00002000}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x97cff07f}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00001000}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x2f9fe0fe}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00000800}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x5f3fc1fd}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00000400}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0xbe7f83fb}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00000200}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x7cff07f7}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00000100}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0xf9fe0fee}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00000080}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0xf3fc1fdc}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00000040}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0xe7f83fb8}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00000020}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0xcff07f70}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00000010}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x9fe0fee1}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00000008}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x3fc1fdc2}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00000004}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0x7f83fb85}, - {0xbf, 2, 1, 0, 0x00000000}, - {0x57, 2, 0, 0, 0x00000002}, - {0x15, 2, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0xff07f70a}, - {0x57, 1, 0, 0, 0x00000001}, - {0x15, 1, 0, 1, 0x00000000}, - {0xa7, 3, 0, 0, 0xfe0fee15}, - {0x71, 1, 0, 201, 0x00000000}, - {0x67, 1, 0, 0, 0x00000008}, - {0x71, 2, 0, 200, 0x00000000}, - {0x4f, 1, 2, 0, 0x00000000}, - {0x71, 2, 0, 202, 0x00000000}, - {0x67, 2, 0, 0, 0x00000010}, - {0x71, 4, 0, 203, 0x00000000}, - {0x67, 4, 0, 0, 0x00000018}, - {0x4f, 4, 2, 0, 0x00000000}, - {0x4f, 4, 1, 0, 0x00000000}, - {0x67, 3, 0, 0, 0x00000020}, - {0x77, 3, 0, 0, 0x00000020}, - {0x9f, 3, 4, 0, 0x00000000}, - {0x57, 3, 0, 0, 0x0000000f}, - {0x67, 3, 0, 0, 0x00000002}, - {0x0f, 0, 3, 0, 0x00000000}, - {0x71, 1, 0, 137, 0x00000000}, - {0x67, 1, 0, 0, 0x00000008}, - {0x71, 2, 0, 136, 0x00000000}, - {0x4f, 1, 2, 0, 0x00000000}, - {0x71, 2, 0, 138, 0x00000000}, - {0x67, 2, 0, 0, 0x00000010}, - {0x71, 3, 0, 139, 0x00000000}, - {0x67, 3, 0, 0, 0x00000018}, - {0x4f, 3, 2, 0, 0x00000000}, - {0x4f, 3, 1, 0, 0x00000000}, - {0x07, 3, 0, 0, 0x7cafe800}, - {0x63, 6, 3, 52, 0x00000000}, - {0xb7, 7, 0, 0, 0x00000001}, - {0xbf, 0, 7, 0, 0x00000000}, - {0x95, 0, 0, 0, 0x00000000}, -}; From patchwork Fri Apr 26 15:48:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Hemminger X-Patchwork-Id: 139713 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 675D143F19; Fri, 26 Apr 2024 17:52:36 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 8B98A43F22; Fri, 26 Apr 2024 17:51:49 +0200 (CEST) Received: from mail-pj1-f50.google.com (mail-pj1-f50.google.com [209.85.216.50]) by mails.dpdk.org (Postfix) with ESMTP id AC77F43F0E for ; Fri, 26 Apr 2024 17:51:43 +0200 (CEST) Received: by mail-pj1-f50.google.com with SMTP id 98e67ed59e1d1-2a58209b159so1955212a91.3 for ; Fri, 26 Apr 2024 08:51:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=networkplumber-org.20230601.gappssmtp.com; s=20230601; t=1714146703; x=1714751503; darn=dpdk.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ripfI62aWcyyKcy7T/8SscUCQ7wbKHxjMNdzwCNhxNk=; b=Gak8xZKJkXYDDTNpDmpaAuDCMNrSh90tor/p5k4QwfilXEzQQZW3u2egBtqKQOQCFy 4s3sKSFcrkw3APu8V4xbIWytVvCvwnFqD9mp/VTxRD0fnLR5EEoX9p5cQWEGmYep7rHK 12QKHpkLnzQlygn6TZKnFVFLs5eSKgQMCDY7yyAshFdwGmGU3aU87NRr5RxhG069JiR8 cSk75L4SroLemimPDNZUtIW8/QKn0TOTczM9Q+LuzXoBKLbH7OdqLs7pBmMtDZOgCBf8 jnrnbev5Q0YbkDxnu0qYvVpqiEU1Tlx9DpEFA4WydC61Gauoru5SN1j8/svilGwRzFi1 gK1w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714146703; x=1714751503; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ripfI62aWcyyKcy7T/8SscUCQ7wbKHxjMNdzwCNhxNk=; b=HCsRQtXMNN6uq0pKs4jvnLWTJpP8LiULcaBr4WvvsRXxaynNrPFZU4sSCbPk1LuwPS FtNk4WfbdWFOiDi6j1wktQ1yTRKPvzcmdGQB4ZTyC4WIFXDBkQxprZxnAJTCUkDLGSVQ NqL6vSLfwbzVZfXKmiH6n9a6qzStGNdO2ck0enV4nmv7Rr1Yk5y0xwbkNfE4H31mxk5s IhC9EQEv6myiHwELbv/+wVz30YPSwrISNmBIffIn20oW4kSf0q0Uj0/r90wmuDgmLjx/ LuXsulwxM13nA7w7tqg8LmqtEVmAWGUuQ+4hALQFa5ZdQuurm+QVgh/xIdLkS5isNiU/ 9GLA== X-Gm-Message-State: AOJu0YwFs/FAxLsF0Vz1nOwvjv1CSEyyjcs5lEPH/L4xk2xFkn3s0fVt wtXOi2t2Tf0tpdfVNR+ornHANYqbNR6OsgWFyUAAw8WSMb8FrJG6JsCBfTACRICBH9FpJOVlkA6 WlfA= X-Google-Smtp-Source: AGHT+IG0dH366WS6c161eNIB5ga8epQCUQigfsGRogpCx8vBZJcKfufX2Z76l1lk8J6FftZ+cf2nPw== X-Received: by 2002:a17:90a:4e08:b0:2ad:5195:1eb5 with SMTP id n8-20020a17090a4e0800b002ad51951eb5mr3116474pjh.40.1714146702636; Fri, 26 Apr 2024 08:51:42 -0700 (PDT) Received: from hermes.local (204-195-96-226.wavecable.com. [204.195.96.226]) by smtp.gmail.com with ESMTPSA id ns5-20020a17090b250500b002a5f44353d2sm16770978pjb.7.2024.04.26.08.51.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 26 Apr 2024 08:51:42 -0700 (PDT) From: Stephen Hemminger To: dev@dpdk.org Cc: Stephen Hemminger Subject: [PATCH v9 8/9] doc: update documentation of TAP PMD Date: Fri, 26 Apr 2024 08:48:58 -0700 Message-ID: <20240426155125.125910-9-stephen@networkplumber.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240426155125.125910-1-stephen@networkplumber.org> References: <20240130034925.44869-1-stephen@networkplumber.org> <20240426155125.125910-1-stephen@networkplumber.org> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org The driver support of flows has changed and the wording in the guide was awkward. Drop references to DPDK pktgen in this documentation since it is not required and confusing. Signed-off-by: Stephen Hemminger --- doc/guides/linux_gsg/sys_reqs.rst | 3 + doc/guides/nics/tap.rst | 274 +++++++++--------------------- 2 files changed, 80 insertions(+), 197 deletions(-) diff --git a/doc/guides/linux_gsg/sys_reqs.rst b/doc/guides/linux_gsg/sys_reqs.rst index 13be715933..0254568517 100644 --- a/doc/guides/linux_gsg/sys_reqs.rst +++ b/doc/guides/linux_gsg/sys_reqs.rst @@ -101,6 +101,9 @@ Running DPDK Applications To run a DPDK application, some customization may be required on the target machine. +.. _linux_gsg_kernel_version: + + System Software ~~~~~~~~~~~~~~~ diff --git a/doc/guides/nics/tap.rst b/doc/guides/nics/tap.rst index d4f45c02a1..55e38fb25b 100644 --- a/doc/guides/nics/tap.rst +++ b/doc/guides/nics/tap.rst @@ -1,47 +1,51 @@ .. SPDX-License-Identifier: BSD-3-Clause Copyright(c) 2016 Intel Corporation. -Tun|Tap Poll Mode Driver -======================== +TAP Poll Mode Driver +==================== -The ``rte_eth_tap.c`` PMD creates a device using TAP interfaces on the -local host. The PMD allows for DPDK and the host to communicate using a raw -device interface on the host and in the DPDK application. +The TAP Poll Mode Driver (PMD) is a virtual device for injecting packets to be processed +by the Linux kernel. This PMD is useful when writing DPDK application +for offloading network functionality (such as tunneling) from the kernel. -The device created is a TAP device, which sends/receives packet in a raw -format with a L2 header. The usage for a TAP PMD is for connectivity to the -local host using a TAP interface. When the TAP PMD is initialized it will -create a number of tap devices in the host accessed via ``ifconfig -a`` or -``ip`` command. The commands can be used to assign and query the virtual like -device. +From the kernel point of view, the TAP device looks like a regular network interface. +The network device can be managed by standard tools such as ``ip`` and ``ethtool`` commands. +It is also possible to use existing packet tools such as ``wireshark`` or ``tcpdump``. -These TAP interfaces can be used with Wireshark or tcpdump or Pktgen-DPDK -along with being able to be used as a network connection to the DPDK -application. The method enable one or more interfaces is to use the -``--vdev=net_tap0`` option on the DPDK application command line. Each -``--vdev=net_tap1`` option given will create an interface named dtap0, dtap1, -and so on. +From the DPDK application, the TAP device looks like a DPDK ethdev. +Packets are sent and received in L2 (Ethernet) format. The standare DPDK +API's to query for information, statistics and send and receive packets +work as expected. -The interface name can be changed by adding the ``iface=foo0``, for example:: +Requirements +~~~~~~~~~~~~ + +The TAP PMD requires kernel support for multiple queues in TAP device as +well as the multi-queue ``multiq`` and incoming ``ingress`` queue disciplines. +These are standard kernel features in most Linux distributions. + +Arguments +--------- + +TAP devices are created with the command line +``--vdev=net_tap0`` option. This option maybe specified more the once by repeating +with a different ``net_tapX`` device. + +By default, the Linux interfaces are named ``dtap0``, ``dtap1``, etc. +The interface name can be specified by adding the ``iface=foo0``, for example:: --vdev=net_tap0,iface=foo0 --vdev=net_tap1,iface=foo1, ... -Normally the PMD will generate a random MAC address, but when testing or with -a static configuration the developer may need a fixed MAC address style. -Using the option ``mac=fixed`` you can create a fixed known MAC address:: +Normally the PMD will generate a random MAC address. +If a static address is desired instead, the ``mac=fixed`` can be used. --vdev=net_tap0,mac=fixed -The MAC address will have a fixed value with the last octet incrementing by one -for each interface string containing ``mac=fixed``. The MAC address is formatted -as 02:'d':'t':'a':'p':[00-FF]. Convert the characters to hex and you get the -actual MAC address: ``02:64:74:61:70:[00-FF]``. - - --vdev=net_tap0,mac="02:64:74:61:70:11" +With the fixed option, the MAC address will have the first octets: +as 02:'d':'t':'a':'p':[00-FF] and the last octets are the interface number. -The MAC address will have a user value passed as string. The MAC address is in -format with delimiter ``:``. The string is byte converted to hex and you get -the actual MAC address: ``02:64:74:61:70:11``. +To specify a specific MAC address use the conventional representation. +The string is byte converted to hex, the result is MAC address: ``02:64:74:61:70:11``. It is possible to specify a remote netdevice to capture packets from by adding ``remote=foo1``, for example:: @@ -59,40 +63,20 @@ netdevice that has no support in the DPDK. It is possible to add explicit rte_flow rules on the tap PMD to capture specific traffic (see next section for examples). -After the DPDK application is started you can send and receive packets on the -interface using the standard rx_burst/tx_burst APIs in DPDK. From the host -point of view you can use any host tool like tcpdump, Wireshark, ping, Pktgen -and others to communicate with the DPDK application. The DPDK application may -not understand network protocols like IPv4/6, UDP or TCP unless the -application has been written to understand these protocols. - -If you need the interface as a real network interface meaning running and has -a valid IP address then you can do this with the following commands:: - - sudo ip link set dtap0 up; sudo ip addr add 192.168.0.250/24 dev dtap0 - sudo ip link set dtap1 up; sudo ip addr add 192.168.1.250/24 dev dtap1 - -Please change the IP addresses as you see fit. - -If routing is enabled on the host you can also communicate with the DPDK App -over the internet via a standard socket layer application as long as you -account for the protocol handling in the application. - -If you have a Network Stack in your DPDK application or something like it you -can utilize that stack to handle the network protocols. Plus you would be able -to address the interface using an IP address assigned to the internal -interface. - Normally, when the DPDK application exits, the TAP device is marked down and is removed. -But this behaviour can be overridden by the use of the persist flag, example:: +But this behavior can be overridden by the use of the persist flag, example:: --vdev=net_tap0,iface=tap0,persist ... -The TUN PMD allows user to create a TUN device on host. The PMD allows user -to transmit and receive packets via DPDK API calls with L3 header and payload. -The devices in host can be accessed via ``ifconfig`` or ``ip`` command. TUN -interfaces are passed to DPDK ``rte_eal_init`` arguments as ``--vdev=net_tunX``, +TUN devices +----------- + +The TAP device can be used an L3 tunnel only device (TUN). +This type of device does not include the Ethernet (L2) header; all packets +are sent and received as IP packets. + +TUN devices are created with the command line arguments ``--vdev=net_tunX``, where X stands for unique id, example:: --vdev=net_tun0 --vdev=net_tun1,iface=foo1, ... @@ -103,27 +87,33 @@ options. Default interface name is ``dtunX``, where X stands for unique id. Flow API support ---------------- -The tap PMD supports major flow API pattern items and actions, when running on -linux kernels above 4.2 ("Flower" classifier required). -The kernel support can be checked with this command:: +The TAP PMD supports major flow API pattern items and actions. + +Requirements +~~~~~~~~~~~~ - zcat /proc/config.gz | ( grep 'CLS_FLOWER=' || echo 'not supported' ) | - tee -a /dev/stderr | grep -q '=m' && - lsmod | ( grep cls_flower || echo 'try modprobe cls_flower' ) +Flow support in TAP driver requires the Linux kernel support of flow based +traffic control filter ``flower``. This was added in Linux 4.3 kernel. -Supported items: +The implementation of RSS action uses an eBPF module that requires additional +libraries and tools. Building the RSS support requires the ``clang`` +compiler to compile the C code to BPF target; ``bpftool`` to convert the +compiled BPF object to a header file; and ``libbpf`` to load the eBPF +action into the kernel. -- eth: src and dst (with variable masks), and eth_type (0xffff mask). -- vlan: vid, pcp, but not eid. (requires kernel 4.9) -- ipv4/6: src and dst (with variable masks), and ip_proto (0xffff mask). -- udp/tcp: src and dst port (0xffff) mask. +Supported match items: + + - eth: src and dst (with variable masks), and eth_type (0xffff mask). + - vlan: vid, pcp, but not eid. (requires kernel 4.9) + - ipv4/6: src and dst (with variable masks), and ip_proto (0xffff mask). + - udp/tcp: src and dst port (0xffff) mask. Supported actions: - DROP - QUEUE - PASSTHRU -- RSS (requires kernel 4.9) +- RSS It is generally not possible to provide a "last" item. However, if the "last" item, once masked, is identical to the masked spec, then it is supported. @@ -133,7 +123,7 @@ full mask (exact match). As rules are translated to TC, it is possible to show them with something like:: - tc -s filter show dev tap1 parent 1: + tc -s filter show dev dtap1 parent 1: Examples of testpmd flow rules ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -174,135 +164,25 @@ The IPC synchronization of Rx/Tx queues is currently limited: - Maximum 8 queues shared - Synchronized on probing, but not on later port update -Example -------- - -The following is a simple example of using the TAP PMD with the Pktgen -packet generator. It requires that the ``socat`` utility is installed on the -test system. - -Build DPDK, then pull down Pktgen and build pktgen using the DPDK SDK/Target -used to build the dpdk you pulled down. - -Run pktgen from the pktgen directory in a terminal with a commandline like the -following:: - - sudo ./app/app/x86_64-native-linux-gcc/app/pktgen -l 1-5 -n 4 \ - --proc-type auto --log-level debug --socket-mem 512,512 --file-prefix pg \ - --vdev=net_tap0 --vdev=net_tap1 -b 05:00.0 -b 05:00.1 \ - -b 04:00.0 -b 04:00.1 -b 04:00.2 -b 04:00.3 \ - -b 81:00.0 -b 81:00.1 -b 81:00.2 -b 81:00.3 \ - -b 82:00.0 -b 83:00.0 -- -T -P -m [2:3].0 -m [4:5].1 \ - -f themes/black-yellow.theme - -.. Note: - - Change the ``-b`` options to exclude all of your physical ports. The - following command line is all one line. - - Also, ``-f themes/black-yellow.theme`` is optional if the default colors - work on your system configuration. See the Pktgen docs for more - information. - -Verify with ``ifconfig -a`` command in a different xterm window, should have a -``dtap0`` and ``dtap1`` interfaces created. - -Next set the links for the two interfaces to up via the commands below:: - - sudo ip link set dtap0 up; sudo ip addr add 192.168.0.250/24 dev dtap0 - sudo ip link set dtap1 up; sudo ip addr add 192.168.1.250/24 dev dtap1 - -Then use socat to create a loopback for the two interfaces:: - - sudo socat interface:dtap0 interface:dtap1 - -Then on the Pktgen command line interface you can start sending packets using -the commands ``start 0`` and ``start 1`` or you can start both at the same -time with ``start all``. The command ``str`` is an alias for ``start all`` and -``stp`` is an alias for ``stop all``. - -While running you should see the 64 byte counters increasing to verify the -traffic is being looped back. You can use ``set all size XXX`` to change the -size of the packets after you stop the traffic. Use pktgen ``help`` -command to see a list of all commands. You can also use the ``-f`` option to -load commands at startup in command line or Lua script in pktgen. RSS specifics ------------- -Packet distribution in TAP is done by the kernel which has a default -distribution. This feature is adding RSS distribution based on eBPF code. -The default eBPF code calculates RSS hash based on Toeplitz algorithm for -a fixed RSS key. It is calculated on fixed packet offsets. For IPv4 and IPv6 it -is calculated over src/dst addresses (8 or 32 bytes for IPv4 or IPv6 -respectively) and src/dst TCP/UDP ports (4 bytes). - -The RSS algorithm is written in file ``tap_bpf_program.c`` which -does not take part in TAP PMD compilation. Instead this file is compiled -in advance to eBPF object file. The eBPF object file is then parsed and -translated into eBPF byte code in the format of C arrays of eBPF -instructions. The C array of eBPF instructions is part of TAP PMD tree and -is taking part in TAP PMD compilation. At run time the C arrays are uploaded to -the kernel via BPF system calls and the RSS hash is calculated by the -kernel. - -It is possible to support different RSS hash algorithms by updating file -``tap_bpf_program.c`` In order to add a new RSS hash algorithm follow these -steps: - -#. Write the new RSS implementation in file ``tap_bpf_program.c`` - - BPF programs which are uploaded to the kernel correspond to - C functions under different ELF sections. - -#. Install ``LLVM`` library and ``clang`` compiler versions 3.7 and above - -#. Use make to compile `tap_bpf_program.c`` via ``LLVM`` into an object file - and extract the resulting instructions into ``tap_bpf_insn.h``:: - - cd bpf; make - -#. Recompile the TAP PMD. - -The C arrays are uploaded to the kernel using BPF system calls. - -``tc`` (traffic control) is a well known user space utility program used to -configure the Linux kernel packet scheduler. It is usually packaged as -part of the ``iproute2`` package. -Since commit 11c39b5e9 ("tc: add eBPF support to f_bpf") ``tc`` can be used -to uploads eBPF code to the kernel and can be patched in order to print the -C arrays of eBPF instructions just before calling the BPF system call. -Please refer to ``iproute2`` package file ``lib/bpf.c`` function -``bpf_prog_load()``. - -An example utility for eBPF instruction generation in the format of C arrays will -be added in next releases - -TAP reports on supported RSS functions as part of dev_infos_get callback: -``RTE_ETH_RSS_IP``, ``RTE_ETH_RSS_UDP`` and ``RTE_ETH_RSS_TCP``. -**Known limitation:** TAP supports all of the above hash functions together -and not in partial combinations. - -Systems supporting flow API ---------------------------- - -- "tc flower" classifier requires linux kernel above 4.2 -- eBPF/RSS requires linux kernel above 4.9 - -+--------------------+-----------------------+ -| RH7.3 | No flow rule support | -+--------------------+-----------------------+ -| RH7.4 | No RSS action support | -+--------------------+-----------------------+ -| RH7.5 | No RSS action support | -+--------------------+-----------------------+ -| SLES 15, | No limitation | -| kernel 4.12 | | -+--------------------+-----------------------+ -| Azure Ubuntu 16.04,| No limitation | -| kernel 4.13 | | -+--------------------+-----------------------+ +The default packet distribution in TAP without flow rules is done by the +kernel which has a default flow based distribution. +When flow rules are used to distribute packets across a set of queues +an eBPF program is used to calculate the RSS based on Toeplitz algorithm for +with the given key. + +The hash is calculated for IPv4 and IPv6, over src/dst addresses +(8 or 32 bytes for IPv4 or IPv6 respectively) and +optionally the src/dst TCP/UDP ports (4 bytes). + Limitations ----------- -* Rx/Tx must have the same number of queues. +- Since TAP device uses a file descriptors to talk to the kernel. + The same number of queues must be specified for receive and transmit. + +- The RSS algorithm only support L3 or L4 functions. It does not support + finer grain selections (for example: only IPV6 packets with extension headers). From patchwork Fri Apr 26 15:48:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Hemminger X-Patchwork-Id: 139714 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 6DC7E43F19; Fri, 26 Apr 2024 17:52:50 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 50C1143F3F; Fri, 26 Apr 2024 17:51:52 +0200 (CEST) Received: from mail-pj1-f49.google.com (mail-pj1-f49.google.com [209.85.216.49]) by mails.dpdk.org (Postfix) with ESMTP id AA92743F11 for ; Fri, 26 Apr 2024 17:51:44 +0200 (CEST) Received: by mail-pj1-f49.google.com with SMTP id 98e67ed59e1d1-2a484f772e2so1620495a91.3 for ; Fri, 26 Apr 2024 08:51:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=networkplumber-org.20230601.gappssmtp.com; s=20230601; t=1714146704; x=1714751504; darn=dpdk.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=CASiGeiYMOqJ2aivudSsgIq3JXXBscw18MAvjgHM6LA=; b=IF486AijkvAGOTKw3CSBpdUu/bvjhHJoV8Z1QLb8aMIuWM3rXzc4b5oXqw4ojpcDhn rew3rgeu27H22DUBQ4VszF0NZAI1SQi24XbKLcZ5+FNLVl25vjN6VmAdgEs8iFh2dbcA aGaPbJgD05bUn9bF344nxPPwA//ipswjJpHgV7l+NAxouLmiLFAEel6Ova4wmNPPAfFq +te+U+80rt1T4GcYb93fNpj02KbZSeGFc7iIhDnCynxnr8XfiI6vxFzMfyyKlXqCt/XV 4p5PLKC/1ms8ZDUUQuOkoaedfupPu3s4naV0430SJ49lUGu6he7OFbdE2qz7HzuECawO b4Gw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714146704; x=1714751504; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=CASiGeiYMOqJ2aivudSsgIq3JXXBscw18MAvjgHM6LA=; b=VDUwZu2JMheKVMzhi4oAcFM/UtEC9c7vYw0fGJPJpgFdZHB5R+sKTin1nvCwk3qPby IfeELs23hqsTCtyRRZHnRp8J4P3AmgpPf0+m2vN9Ko1IGJwC3IKsRFE4MRSSr4vM3uqP A4F6glXySzWFwpewZfhRIGVIAjlejnqlSDGuAv4wRvjJOyPpfRcledwzDMMXTxibgTrA gOTi4n5TzaGeAyLFaPA9exVZoIBIS9DXD8h5xwjyMx0tcg3AxOjtWmh7xozD9Oeucc/i suzd2Z0aOok3zUWij1r5Bq/md0T9YHUbFPcA1NdcBC9M4ZtlLD8IV7Uo+i9Gsx/G1Dyv Irfw== X-Gm-Message-State: AOJu0Yy//gZTpijMBFU+KqvTkubjgnXSw1j1wSqc8uL6D6oY4hQ0I6Sq kGlp9+dmyre0R2aEywzf4YAg30iLNjZ+KINw6da26Z0pdjlvYdfjyZO5txBxeULOAOXA1VyBQie auaI= X-Google-Smtp-Source: AGHT+IHEPspmWeDM7tQ9QynDnSDfQPwpBYXOPrM0RCgis1K0wqQQnDTFyMw+Z2LiGiK3g/IXl2EEiA== X-Received: by 2002:a17:90a:d397:b0:2af:6ce2:bd2f with SMTP id q23-20020a17090ad39700b002af6ce2bd2fmr3232163pju.1.1714146703888; Fri, 26 Apr 2024 08:51:43 -0700 (PDT) Received: from hermes.local (204-195-96-226.wavecable.com. [204.195.96.226]) by smtp.gmail.com with ESMTPSA id ns5-20020a17090b250500b002a5f44353d2sm16770978pjb.7.2024.04.26.08.51.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 26 Apr 2024 08:51:43 -0700 (PDT) From: Stephen Hemminger To: dev@dpdk.org Cc: Stephen Hemminger Subject: [PATCH v9 9/9] net/tap: simplify the internal structure Date: Fri, 26 Apr 2024 08:48:59 -0700 Message-ID: <20240426155125.125910-10-stephen@networkplumber.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240426155125.125910-1-stephen@networkplumber.org> References: <20240130034925.44869-1-stephen@networkplumber.org> <20240426155125.125910-1-stephen@networkplumber.org> MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org The names of Linux network devices are IFNAMSIZ(16) not the same as DPDK which has up to 64 characters. Don't need to hold onto the whole ifreq to save the remote interface flags. Rearrange internal structure for locality. Signed-off-by: Stephen Hemminger --- drivers/net/tap/rte_eth_tap.c | 42 ++++++++++++++++++++++------------- drivers/net/tap/rte_eth_tap.h | 12 +++++----- 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c index 793730de08..b066a8acd1 100644 --- a/drivers/net/tap/rte_eth_tap.c +++ b/drivers/net/tap/rte_eth_tap.c @@ -212,7 +212,7 @@ tun_alloc(struct pmd_internals *pmd, int is_keepalive, int persistent) * and need to find the resulting device. */ TAP_LOG(DEBUG, "Device name is '%s'", ifr.ifr_name); - strlcpy(pmd->name, ifr.ifr_name, RTE_ETH_NAME_MAX_LEN); + strlcpy(pmd->name, ifr.ifr_name, IFNAMSIZ); if (is_keepalive) { /* @@ -1151,9 +1151,13 @@ tap_dev_close(struct rte_eth_dev *dev) } if (internals->remote_if_index) { + struct ifreq remote_ifr; + + strlcpy(remote_ifr.ifr_name, internals->remote_iface, IFNAMSIZ); + remote_ifr.ifr_flags = internals->remote_flags; + /* Restore initial remote state */ - int ret = ioctl(internals->ioctl_sock, SIOCSIFFLAGS, - &internals->remote_initial_flags); + int ret = ioctl(internals->ioctl_sock, SIOCSIFFLAGS, &remote_ifr); if (ret) TAP_LOG(ERR, "restore remote state failed: %d", ret); @@ -2074,16 +2078,22 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, const char *tap_name, LIST_INIT(&pmd->flows); if (strlen(remote_iface)) { + struct ifreq remote_ifr; + pmd->remote_if_index = if_nametoindex(remote_iface); if (!pmd->remote_if_index) { TAP_LOG(ERR, "%s: failed to get %s if_index.", pmd->name, remote_iface); goto error_remote; } - strlcpy(pmd->remote_iface, remote_iface, RTE_ETH_NAME_MAX_LEN); + strlcpy(pmd->remote_iface, remote_iface, IFNAMSIZ); + + memset(&remote_ifr, 0, sizeof(ifr)); + strlcpy(remote_ifr.ifr_name, remote_iface, IFNAMSIZ); /* Save state of remote device */ - tap_ioctl(pmd, SIOCGIFFLAGS, &pmd->remote_initial_flags, 0, REMOTE_ONLY); + tap_ioctl(pmd, SIOCGIFFLAGS, &remote_ifr, 0, REMOTE_ONLY); + pmd->remote_flags = remote_ifr.ifr_flags; /* Replicate remote MAC address */ if (tap_ioctl(pmd, SIOCGIFHWADDR, &ifr, 0, REMOTE_ONLY) < 0) { @@ -2197,10 +2207,10 @@ set_interface_name(const char *key __rte_unused, value); return -1; } - strlcpy(name, value, RTE_ETH_NAME_MAX_LEN); + strlcpy(name, value, IFNAMSIZ); } else { /* use tap%d which causes kernel to choose next available */ - strlcpy(name, DEFAULT_TAP_NAME "%d", RTE_ETH_NAME_MAX_LEN); + strlcpy(name, DEFAULT_TAP_NAME "%d", IFNAMSIZ); } return 0; } @@ -2218,7 +2228,7 @@ set_remote_iface(const char *key __rte_unused, value); return -1; } - strlcpy(name, value, RTE_ETH_NAME_MAX_LEN); + strlcpy(name, value, IFNAMSIZ); } return 0; @@ -2269,13 +2279,13 @@ rte_pmd_tun_probe(struct rte_vdev_device *dev) const char *name, *params; int ret; struct rte_kvargs *kvlist = NULL; - char tun_name[RTE_ETH_NAME_MAX_LEN]; - char remote_iface[RTE_ETH_NAME_MAX_LEN]; + char tun_name[IFNAMSIZ]; + char remote_iface[IFNAMSIZ]; struct rte_eth_dev *eth_dev; name = rte_vdev_device_name(dev); params = rte_vdev_device_args(dev); - memset(remote_iface, 0, RTE_ETH_NAME_MAX_LEN); + memset(remote_iface, 0, IFNAMSIZ); if (rte_eal_process_type() == RTE_PROC_SECONDARY && strlen(params) == 0) { @@ -2291,7 +2301,7 @@ rte_pmd_tun_probe(struct rte_vdev_device *dev) } /* use tun%d which causes kernel to choose next available */ - strlcpy(tun_name, DEFAULT_TUN_NAME "%d", RTE_ETH_NAME_MAX_LEN); + strlcpy(tun_name, DEFAULT_TUN_NAME "%d", IFNAMSIZ); if (params && (params[0] != '\0')) { TAP_LOG(DEBUG, "parameters (%s)", params); @@ -2431,8 +2441,8 @@ rte_pmd_tap_probe(struct rte_vdev_device *dev) int ret; struct rte_kvargs *kvlist = NULL; int speed; - char tap_name[RTE_ETH_NAME_MAX_LEN]; - char remote_iface[RTE_ETH_NAME_MAX_LEN]; + char tap_name[IFNAMSIZ]; + char remote_iface[IFNAMSIZ]; struct rte_ether_addr user_mac = { .addr_bytes = {0} }; struct rte_eth_dev *eth_dev; int tap_devices_count_increased = 0; @@ -2486,8 +2496,8 @@ rte_pmd_tap_probe(struct rte_vdev_device *dev) speed = RTE_ETH_SPEED_NUM_10G; /* use tap%d which causes kernel to choose next available */ - strlcpy(tap_name, DEFAULT_TAP_NAME "%d", RTE_ETH_NAME_MAX_LEN); - memset(remote_iface, 0, RTE_ETH_NAME_MAX_LEN); + strlcpy(tap_name, DEFAULT_TAP_NAME "%d", IFNAMSIZ); + memset(remote_iface, 0, IFNAMSIZ); if (params && (params[0] != '\0')) { TAP_LOG(DEBUG, "parameters (%s)", params); diff --git a/drivers/net/tap/rte_eth_tap.h b/drivers/net/tap/rte_eth_tap.h index ce4322ad04..ca510e2c6b 100644 --- a/drivers/net/tap/rte_eth_tap.h +++ b/drivers/net/tap/rte_eth_tap.h @@ -68,15 +68,16 @@ struct tx_queue { struct pmd_internals { struct rte_eth_dev *dev; /* Ethernet device. */ - char remote_iface[RTE_ETH_NAME_MAX_LEN]; /* Remote netdevice name */ - char name[RTE_ETH_NAME_MAX_LEN]; /* Internal Tap device name */ + char remote_iface[IFNAMSIZ]; /* Remote netdevice name */ + char name[IFNAMSIZ]; /* Internal Tap device name */ int type; /* Type field - TUN|TAP */ int persist; /* 1 if keep link up, else 0 */ struct rte_ether_addr eth_addr; /* Mac address of the device port */ - struct ifreq remote_initial_flags;/* Remote netdevice flags on init */ + uint16_t remote_flags; /* Remote netdevice flags on init */ int remote_if_index; /* remote netdevice IF_INDEX */ int if_index; /* IF_INDEX for the port */ int ioctl_sock; /* socket for ioctl calls */ + int ka_fd; /* keep-alive file descriptor */ #ifdef HAVE_TCA_FLOWER int nlsk_fd; /* Netlink socket fd */ @@ -88,12 +89,11 @@ struct pmd_internals { /* implicit rte_flow rules set when a remote device is active */ LIST_HEAD(tap_implicit_flows, rte_flow) implicit_flows; #endif + struct rte_intr_handle *intr_handle; /* LSC interrupt handle. */ + struct rte_mempool *gso_ctx_mp; /* Mempool for GSO packets */ struct rx_queue rxq[RTE_PMD_TAP_MAX_QUEUES]; /* List of RX queues */ struct tx_queue txq[RTE_PMD_TAP_MAX_QUEUES]; /* List of TX queues */ - struct rte_intr_handle *intr_handle; /* LSC interrupt handle. */ - int ka_fd; /* keep-alive file descriptor */ - struct rte_mempool *gso_ctx_mp; /* Mempool for GSO packets */ }; struct pmd_process_private {