本文共 12946 字,大约阅读时间需要 43 分钟。
要实现f-stack bond 功能,
首先是传递参数到dpdk,一般是在config.ini文件添加dpdk_bond=eth_bond0,mode=2,slave=0000:00:04.0,slave=0000:00:05.0,xmit_policy=l34,怎么解析和传给dpdk自己得研究vpp或是ovs代码,实现dpdk bond有两种方法,一种是传上面参数给dpdk,还有一种是调用dpdk相应接口实现bond。
其次是要让bond口向slave口配置port_conf.rxmode.hw_vlan_strip = 1;,原有的代码只是设置了普通接口,bond口没有下发成功到slave口,我选择在bond 驱动文件里设置
最后是获取slave口的mac,设置到bond 口
修改dpdk bond驱动文件文件:rte_eth_bond.c,实现设置slave网口的hw_vlan_strip
intslave_configure(struct rte_eth_dev *bonded_eth_dev, struct rte_eth_dev *slave_eth_dev){ struct bond_rx_queue *bd_rx_q; struct bond_tx_queue *bd_tx_q; uint16_t old_nb_tx_queues = slave_eth_dev->data->nb_tx_queues; uint16_t old_nb_rx_queues = slave_eth_dev->data->nb_rx_queues; int errval; uint16_t q_id; /* Stop slave */ rte_eth_dev_stop(slave_eth_dev->data->port_id); /* Enable interrupts on slave device if supported */ if (slave_eth_dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC) slave_eth_dev->data->dev_conf.intr_conf.lsc = 1; #if 1 if (bonded_eth_dev->data->dev_conf.rxmode.hw_vlan_strip) { slave_eth_dev->data->dev_conf.rxmode.hw_vlan_strip = 1; } #endif /* If RSS is enabled for bonding, try to enable it for slaves */ if (bonded_eth_dev->data->dev_conf.rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG) { if (bonded_eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key_len != 0) { slave_eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key_len = bonded_eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key_len; slave_eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key = bonded_eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key; } else { slave_eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key = NULL; } slave_eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf = bonded_eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf; slave_eth_dev->data->dev_conf.rxmode.mq_mode = bonded_eth_dev->data->dev_conf.rxmode.mq_mode; } /* Configure device */ errval = rte_eth_dev_configure(slave_eth_dev->data->port_id, bonded_eth_dev->data->nb_rx_queues, bonded_eth_dev->data->nb_tx_queues, &(slave_eth_dev->data->dev_conf)); if (errval != 0) { RTE_BOND_LOG(ERR, "Cannot configure slave device: port %u , err (%d)", slave_eth_dev->data->port_id, errval); return errval; } /* Setup Rx Queues */ /* Use existing queues, if any */ for (q_id = old_nb_rx_queues; q_id < bonded_eth_dev->data->nb_rx_queues; q_id++) { bd_rx_q = (struct bond_rx_queue *)bonded_eth_dev->data->rx_queues[q_id]; errval = rte_eth_rx_queue_setup(slave_eth_dev->data->port_id, q_id, bd_rx_q->nb_rx_desc, rte_eth_dev_socket_id(slave_eth_dev->data->port_id), &(bd_rx_q->rx_conf), bd_rx_q->mb_pool); if (errval != 0) { RTE_BOND_LOG(ERR, "rte_eth_rx_queue_setup: port=%d queue_id %d, err (%d)", slave_eth_dev->data->port_id, q_id, errval); return errval; } } /* Setup Tx Queues */ /* Use existing queues, if any */ for (q_id = old_nb_tx_queues; q_id < bonded_eth_dev->data->nb_tx_queues; q_id++) { bd_tx_q = (struct bond_tx_queue *)bonded_eth_dev->data->tx_queues[q_id]; errval = rte_eth_tx_queue_setup(slave_eth_dev->data->port_id, q_id, bd_tx_q->nb_tx_desc, rte_eth_dev_socket_id(slave_eth_dev->data->port_id), &bd_tx_q->tx_conf); if (errval != 0) { RTE_BOND_LOG(ERR, "rte_eth_tx_queue_setup: port=%d queue_id %d, err (%d)", slave_eth_dev->data->port_id, q_id, errval); return errval; } } /* Start device */ errval = rte_eth_dev_start(slave_eth_dev->data->port_id); if (errval != 0) { RTE_BOND_LOG(ERR, "rte_eth_dev_start: port=%u, err (%d)", slave_eth_dev->data->port_id, errval); return -1; } /* If RSS is enabled for bonding, synchronize RETA */ if (bonded_eth_dev->data->dev_conf.rxmode.mq_mode & ETH_MQ_RX_RSS) { int i; struct bond_dev_private *internals; internals = bonded_eth_dev->data->dev_private; for (i = 0; i < internals->slave_count; i++) { if (internals->slaves[i].port_id == slave_eth_dev->data->port_id) { errval = rte_eth_dev_rss_reta_update( slave_eth_dev->data->port_id, &internals->reta_conf[0], internals->slaves[i].reta_size); if (errval != 0) { RTE_LOG(WARNING, PMD, "rte_eth_dev_rss_reta_update on slave port %d fails (err %d)." " RSS Configuration for bonding may be inconsistent.\n", slave_eth_dev->data->port_id, errval); } break; } } } /* If lsc interrupt is set, check initial slave's link status */ if (slave_eth_dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC) bond_ethdev_lsc_event_callback(slave_eth_dev->data->port_id, RTE_ETH_EVENT_INTR_LSC, &bonded_eth_dev->data->port_id); return 0;}
修改f-stack lib文件:ff_dpdk_if.c,设置bond口的hw_vlan_strip,将第一个slave口的mac设置到bond 口
static intinit_port_start(void){ int nb_ports = ff_global_cfg.dpdk.nb_ports; uint16_t nb_procs = ff_global_cfg.dpdk.nb_procs; unsigned socketid = rte_lcore_to_socket_id(rte_lcore_id()); struct rte_mempool *mbuf_pool = pktmbuf_pool[socketid]; uint16_t i; printf("-------->[%s]:[%d] rte_eth_dev_count()= %d\n", __func__, __LINE__, rte_eth_dev_count()); for (i = 0; i < nb_ports; i++) { uint8_t port_id = ff_global_cfg.dpdk.port_cfgs[i].port_id; struct rte_eth_dev_info dev_info; rte_eth_dev_info_get(port_id, &dev_info);#if 1 if (strncmp (dev_info.driver_name, "rte_bond_pmd", 12) == 0) { dev_info.rx_offload_capa |= DEV_RX_OFFLOAD_VLAN_STRIP; dev_info.tx_offload_capa |= DEV_TX_OFFLOAD_VLAN_INSERT; }#endif if (nb_procs > dev_info.max_rx_queues) { rte_exit(EXIT_FAILURE, "num_procs[%d] bigger than max_rx_queues[%d]\n", nb_procs, dev_info.max_rx_queues); } if (nb_procs > dev_info.max_tx_queues) { rte_exit(EXIT_FAILURE, "num_procs[%d] bigger than max_tx_queues[%d]\n", nb_procs, dev_info.max_tx_queues); } struct ether_addr addr; rte_eth_macaddr_get(port_id, &addr); printf("Port %u MAC: %02" PRIx8 " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 "\n", (unsigned)port_id, addr.addr_bytes[0], addr.addr_bytes[1], addr.addr_bytes[2], addr.addr_bytes[3], addr.addr_bytes[4], addr.addr_bytes[5]); rte_memcpy(ff_global_cfg.dpdk.port_cfgs[i].mac, addr.addr_bytes, ETHER_ADDR_LEN); /* Clear txq_flags - we do not need multi-mempool and refcnt */ dev_info.default_txconf.txq_flags = ETH_TXQ_FLAGS_NOMULTMEMP | ETH_TXQ_FLAGS_NOREFCOUNT; /* Disable features that are not supported by port's HW */ if (!(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_UDP_CKSUM)) { dev_info.default_txconf.txq_flags |= ETH_TXQ_FLAGS_NOXSUMUDP; } if (!(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_CKSUM)) { dev_info.default_txconf.txq_flags |= ETH_TXQ_FLAGS_NOXSUMTCP; } if (!(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_SCTP_CKSUM)) { dev_info.default_txconf.txq_flags |= ETH_TXQ_FLAGS_NOXSUMSCTP; } if (!(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_VLAN_INSERT)) { dev_info.default_txconf.txq_flags |= ETH_TXQ_FLAGS_NOVLANOFFL; } if (!(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_VLAN_INSERT)) { dev_info.default_txconf.txq_flags |= ETH_TXQ_FLAGS_NOVLANOFFL; } if (!(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_TSO) && !(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_UDP_TSO)) { dev_info.default_txconf.txq_flags |= ETH_TXQ_FLAGS_NOMULTSEGS; } struct rte_eth_conf port_conf = {0};#if 1 /* Set RSS mode */ port_conf.rxmode.mq_mode = ETH_MQ_RX_RSS; port_conf.rx_adv_conf.rss_conf.rss_hf = ETH_RSS_PROTO_MASK; port_conf.rx_adv_conf.rss_conf.rss_key = default_rsskey_40bytes; port_conf.rx_adv_conf.rss_conf.rss_key_len = 40;#endif printf("-------->[%s]:[%d]\n", __func__, __LINE__); /* Set Rx VLAN stripping */ if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_VLAN_STRIP) { printf("-------->[%s]:[%d]\n", __func__, __LINE__); port_conf.rxmode.hw_vlan_strip = 1; } /* Enable HW CRC stripping */ port_conf.rxmode.hw_strip_crc = 1; /* FIXME: Enable TCP LRO ?*/ #if 0 if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_TCP_LRO) { printf("LRO is supported\n"); port_conf.rxmode.enable_lro = 1; ff_global_cfg.dpdk.port_cfgs[i].hw_features.rx_lro = 1; } #endif /* Set Rx checksum checking */ if ((dev_info.rx_offload_capa & DEV_RX_OFFLOAD_IPV4_CKSUM) && (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_UDP_CKSUM) && (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_TCP_CKSUM)) { printf("RX checksum offload supported\n"); port_conf.rxmode.hw_ip_checksum = 1; ff_global_cfg.dpdk.port_cfgs[i].hw_features.rx_csum = 1; } if ((dev_info.tx_offload_capa & DEV_TX_OFFLOAD_IPV4_CKSUM)) { printf("TX ip checksum offload supported\n"); ff_global_cfg.dpdk.port_cfgs[i].hw_features.tx_csum_ip = 1; } if ((dev_info.tx_offload_capa & DEV_TX_OFFLOAD_UDP_CKSUM) && (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_CKSUM)) { printf("TX TCP&UDP checksum offload supported\n"); ff_global_cfg.dpdk.port_cfgs[i].hw_features.tx_csum_l4 = 1; } if (ff_global_cfg.dpdk.tso) { if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_TSO) { printf("TSO is supported\n"); ff_global_cfg.dpdk.port_cfgs[i].hw_features.tx_tso = 1; } } else { printf("TSO is disabled\n"); } if (rte_eal_process_type() != RTE_PROC_PRIMARY) { return 0; } /* Currently, proc id 1:1 map to queue id per port. */ int ret = rte_eth_dev_configure(port_id, nb_procs, nb_procs, &port_conf); if (ret != 0) { return ret; } uint16_t q; for (q = 0; q < nb_procs; q++) { ret = rte_eth_tx_queue_setup(port_id, q, TX_QUEUE_SIZE, socketid, &dev_info.default_txconf); if (ret < 0) { return ret; } ret = rte_eth_rx_queue_setup(port_id, q, RX_QUEUE_SIZE, socketid, &dev_info.default_rxconf, mbuf_pool); if (ret < 0) { return ret; } } if (strncmp (dev_info.driver_name, "rte_bond_pmd", 12) == 0) { unsigned char slink[16]; int nlink = rte_eth_bond_slaves_get (port_id, slink, 16); if (nlink > 0) { int rv; unsigned char addr[6]; /* Get MAC of 1st slave link */ rte_eth_macaddr_get (slink[0], (struct ether_addr *) addr); printf("Port %u MAC: %02" PRIx8 " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 "\n", (unsigned)port_id, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); /* Set MAC of bounded interface to that of 1st slave link */ rv = rte_eth_bond_mac_address_set (port_id, (struct ether_addr *) addr); if (rv < 0) rte_exit(EXIT_FAILURE, "Failed to set MAC address"); } printf("-------->[%s]:[%d] nlink = %d\n", __func__, __LINE__, nlink); rte_eth_macaddr_get(port_id, &addr); printf("Port %u MAC: %02" PRIx8 " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 "\n", (unsigned)port_id, addr.addr_bytes[0], addr.addr_bytes[1], addr.addr_bytes[2], addr.addr_bytes[3], addr.addr_bytes[4], addr.addr_bytes[5]); rte_memcpy(ff_global_cfg.dpdk.port_cfgs[i].mac, addr.addr_bytes, ETHER_ADDR_LEN); } ret = rte_eth_dev_start(port_id); if (ret < 0) { return ret; } /* Enable RX in promiscuous mode for the Ethernet device. */ if (ff_global_cfg.dpdk.promiscuous) { rte_eth_promiscuous_enable(port_id); ret = rte_eth_promiscuous_get(port_id); if (ret == 1) { printf("set port %u to promiscuous mode ok\n", port_id); } else { printf("set port %u to promiscuous mode error\n", port_id); } } /* Enable pcap dump */ if (ff_global_cfg.dpdk.port_cfgs[i].pcap) { ff_enable_pcap(ff_global_cfg.dpdk.port_cfgs[i].pcap); } } return 0;}
转载地址:http://tbqci.baihongyu.com/