[dpdk-dev] [PATCH 12/12] examples/l3fwd: add option to parse ptype

Tan, Jianfeng jianfeng.tan at intel.com
Tue Jan 5 03:44:10 CET 2016



> -----Original Message-----
> From: Ananyev, Konstantin
> Sent: Tuesday, January 5, 2016 2:32 AM
> To: Tan, Jianfeng; dev at dpdk.org
> Cc: Zhang, Helin
> Subject: RE: [PATCH 12/12] examples/l3fwd: add option to parse ptype
> 
> 
> Hi Jianfeng,
> > -----Original Message-----
> > From: Tan, Jianfeng
> > Sent: Thursday, December 31, 2015 6:53 AM
> > To: dev at dpdk.org
> > Cc: Zhang, Helin; Ananyev, Konstantin; Tan, Jianfeng
> > Subject: [PATCH 12/12] examples/l3fwd: add option to parse ptype
> >
> > Firstly, use rte_eth_dev_get_ptype_info() API to check if device will
> > parse needed packet type. If not, specifying the newly added option,
> > --parse-ptype to do it in the callback softly.
> >
> > Signed-off-by: Jianfeng Tan <jianfeng.tan at intel.com>
> > ---
> >  examples/l3fwd/main.c | 86
> +++++++++++++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 86 insertions(+)
> >
> > diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c
> > index 5b0c2dd..ccbdce3 100644
> > --- a/examples/l3fwd/main.c
> > +++ b/examples/l3fwd/main.c
> > @@ -174,6 +174,7 @@ static __m128i val_eth[RTE_MAX_ETHPORTS];
> >  static uint32_t enabled_port_mask = 0;
> >  static int promiscuous_on = 0; /**< Ports set in promiscuous mode off by
> default. */
> >  static int numa_on = 1; /**< NUMA is enabled by default. */
> > +static int parse_ptype = 0; /**< parse packet type using rx callback */
> >
> >  #if (APP_LOOKUP_METHOD == APP_LOOKUP_EXACT_MATCH)
> >  static int ipv6 = 0; /**< ipv6 is false by default. */
> > @@ -2022,6 +2023,7 @@ parse_eth_dest(const char *optarg)
> >  #define CMD_LINE_OPT_IPV6 "ipv6"
> >  #define CMD_LINE_OPT_ENABLE_JUMBO "enable-jumbo"
> >  #define CMD_LINE_OPT_HASH_ENTRY_NUM "hash-entry-num"
> > +#define CMD_LINE_OPT_PARSE_PTYPE "parse-ptype"
> >
> >  /* Parse the argument given in the command line of the application */
> >  static int
> > @@ -2038,6 +2040,7 @@ parse_args(int argc, char **argv)
> >  		{CMD_LINE_OPT_IPV6, 0, 0, 0},
> >  		{CMD_LINE_OPT_ENABLE_JUMBO, 0, 0, 0},
> >  		{CMD_LINE_OPT_HASH_ENTRY_NUM, 1, 0, 0},
> > +		{CMD_LINE_OPT_PARSE_PTYPE, 0, 0, 0},
> >  		{NULL, 0, 0, 0}
> >  	};
> >
> > @@ -2125,6 +2128,12 @@ parse_args(int argc, char **argv)
> >  				}
> >  			}
> >  #endif
> > +			if (!strncmp(lgopts[option_index].name,
> CMD_LINE_OPT_PARSE_PTYPE,
> > +				sizeof(CMD_LINE_OPT_PARSE_PTYPE))) {
> > +				printf("soft parse-ptype is enabled \n");
> > +				parse_ptype = 1;
> > +			}
> > +
> >  			break;
> >
> >  		default:
> > @@ -2559,6 +2568,75 @@ check_all_ports_link_status(uint8_t port_num,
> uint32_t port_mask)
> >  	}
> >  }
> >
> > +static int
> > +check_packet_type_ok(int portid)
> > +{
> > +	int i;
> > +	int ret;
> > +	uint32_t ptypes[RTE_PTYPE_L3_MAX_NUM];
> > +	int ptype_l3_ipv4 = 0, ptype_l3_ipv6 = 0;
> > +
> > +	ret = rte_eth_dev_get_ptype_info(portid, RTE_PTYPE_L3_MASK,
> ptypes);
> > +	for (i = 0; i < ret; ++i) {
> > +		if (ptypes[i] & RTE_PTYPE_L3_IPV4)
> > +			ptype_l3_ipv4 = 1;
> > +		if (ptypes[i] & RTE_PTYPE_L3_IPV6)
> > +			ptype_l3_ipv6 = 1;
> > +	}
> > +
> > +	if (ptype_l3_ipv4 == 0)
> > +		printf("port %d cannot parse RTE_PTYPE_L3_IPV4\n", portid);
> > +
> > +	if (ptype_l3_ipv6 == 0)
> > +		printf("port %d cannot parse RTE_PTYPE_L3_IPV6\n", portid);
> > +
> > +	if (ptype_l3_ipv4 || ptype_l3_ipv6)
> > +		return 1;
> > +
> > +	return 0;
> > +}
> > +static inline void
> > +parse_packet_type(struct rte_mbuf *m)
> > +{
> > +	struct ether_hdr *eth_hdr;
> > +	struct vlan_hdr *vlan_hdr;
> > +	uint32_t packet_type = 0;
> > +	uint16_t ethertype;
> > +
> > +	eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
> > +	ethertype = rte_be_to_cpu_16(eth_hdr->ether_type);
> > +	if (ethertype == ETHER_TYPE_VLAN) {
> 
> I don't think either LPM or EM support packets with VLAN right now.
> So, probably there is no need to support it here.

Good to know. Will remove it.

> 
> > +		vlan_hdr = (struct vlan_hdr *)(eth_hdr + 1);
> > +		ethertype = rte_be_to_cpu_16(vlan_hdr->eth_proto);
> > +	}
> > +	switch (ethertype) {
> > +	case ETHER_TYPE_IPv4:
> > +		packet_type |= RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
> > +		break;
> > +	case ETHER_TYPE_IPv6:
> > +		packet_type |= RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
> > +		break;
> > +	default:
> > +		break;
> > +	}
> > +
> > +	m->packet_type = packet_type;
> 
> Probably:
> m->packet_type |= packet_type;
> in case HW supports some other packet types.

I agree. Will fix it.

> 
> > +}
> > +
> > +static uint16_t
> > +cb_parse_packet_type(uint8_t port __rte_unused,
> > +		uint16_t queue __rte_unused,
> > +		struct rte_mbuf *pkts[],
> > +		uint16_t nb_pkts,
> > +		uint16_t max_pkts __rte_unused,
> > +		void *user_param __rte_unused)
> > +{
> > +	unsigned i;
> > +
> > +	for (i = 0; i < nb_pkts; ++i)
> > +		parse_packet_type(pkts[i]);
> > +}
> > +
> >  int
> >  main(int argc, char **argv)
> >  {
> > @@ -2672,6 +2750,11 @@ main(int argc, char **argv)
> >  				rte_exit(EXIT_FAILURE,
> "rte_eth_tx_queue_setup: err=%d, "
> >  					"port=%d\n", ret, portid);
> >
> > +			if (!check_packet_type_ok(portid) && !parse_ptype)
> > +				rte_exit(EXIT_FAILURE,
> > +						"port %d cannot parse packet
> type, please add --%s\n",
> > +						portid,
> CMD_LINE_OPT_PARSE_PTYPE);
> > +
> >  			qconf = &lcore_conf[lcore_id];
> >  			qconf->tx_queue_id[portid] = queueid;
> >  			queueid++;
> > @@ -2705,6 +2788,9 @@ main(int argc, char **argv)
> >  			if (ret < 0)
> >  				rte_exit(EXIT_FAILURE,
> "rte_eth_rx_queue_setup: err=%d,"
> >  						"port=%d\n", ret, portid);
> > +			if (parse_ptype)
> > +				rte_eth_add_rx_callback(portid, queueid,
> > +						cb_parse_packet_type,
> NULL);
> 
> Need to check return value.
> Konstantin

Oops, good catch!

> 
> >  		}
> >  	}
> >
> > --
> > 2.1.4



More information about the dev mailing list