博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
f-stack dpdk bond 功能
阅读量:4056 次
发布时间:2019-05-25

本文共 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/

你可能感兴趣的文章
iphone开发之SDK研究(待续)
查看>>
计算机网络复习要点
查看>>
Variable property attributes or Modifiers in iOS
查看>>
NSNotificationCenter 用法总结
查看>>
C primer plus 基础总结(一)
查看>>
剑指offer算法题分析与整理(三)
查看>>
mint/ubuntu安装搜狗输入法
查看>>
C++动态申请数组和参数传递问题
查看>>
opencv学习——在MFC中读取和显示图像
查看>>
JVM并发机制探讨—内存模型、内存可见性和指令重排序
查看>>
nginx+tomcat+memcached (msm)实现 session同步复制
查看>>
c++模板与泛型编程
查看>>
WAV文件解析
查看>>
WPF中PATH使用AI导出SVG的方法
查看>>
WPF UI&控件免费开源库
查看>>
QT打开项目提示no valid settings file could be found
查看>>
Win10+VS+ESP32环境搭建
查看>>
android 代码实现圆角
查看>>
flutter-解析json
查看>>
android中shader的使用
查看>>