Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 46410c2e authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'pktgen-Behavior-flags-fixes'



Dmitry Safonov says:

====================
pktgen: Behavior flags fixes

v2:
  o fixed a nitpick from David Miller

There are a bunch of fixes/cleanups/Documentations.
Diffstat says for itself, regardless added docs and missed flag
parameters.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 969ade40 52e12d5d
Loading
Loading
Loading
Loading
+14 −5
Original line number Original line Diff line number Diff line
@@ -12,8 +12,8 @@ suitable sample script and configure that.
On a dual CPU:
On a dual CPU:


ps aux | grep pkt
ps aux | grep pkt
root       129  0.3  0.0     0    0 ?        SW    2003 523:20 [pktgen/0]
root       129  0.3  0.0     0    0 ?        SW    2003 523:20 [kpktgend_0]
root       130  0.3  0.0     0    0 ?        SW    2003 509:50 [pktgen/1]
root       130  0.3  0.0     0    0 ?        SW    2003 509:50 [kpktgend_1]




For monitoring and control pktgen creates:
For monitoring and control pktgen creates:
@@ -113,9 +113,16 @@ Configuring devices
===================
===================
This is done via the /proc interface, and most easily done via pgset
This is done via the /proc interface, and most easily done via pgset
as defined in the sample scripts.
as defined in the sample scripts.
You need to specify PGDEV environment variable to use functions from sample
scripts, i.e.:
export PGDEV=/proc/net/pktgen/eth4@0
source samples/pktgen/functions.sh


Examples:
Examples:


 pg_ctrl start           starts injection.
 pg_ctrl stop            aborts injection. Also, ^C aborts generator.

 pgset "clone_skb 1"     sets the number of copies of the same packet
 pgset "clone_skb 1"     sets the number of copies of the same packet
 pgset "clone_skb 0"     use single SKB for all transmits
 pgset "clone_skb 0"     use single SKB for all transmits
 pgset "burst 8"         uses xmit_more API to queue 8 copies of the same
 pgset "burst 8"         uses xmit_more API to queue 8 copies of the same
@@ -165,8 +172,12 @@ Examples:
                              IPSEC # IPsec encapsulation (needs CONFIG_XFRM)
                              IPSEC # IPsec encapsulation (needs CONFIG_XFRM)
                              NODE_ALLOC # node specific memory allocation
                              NODE_ALLOC # node specific memory allocation
                              NO_TIMESTAMP # disable timestamping
                              NO_TIMESTAMP # disable timestamping
 pgset 'flag ![name]'    Clear a flag to determine behaviour.
                         Note that you might need to use single quote in
                         interactive mode, so that your shell wouldn't expand
                         the specified flag as a history command.


 pgset spi SPI_VALUE     Set specific SA used to transform packet.
 pgset "spi [SPI_VALUE]" Set specific SA used to transform packet.


 pgset "udp_src_min 9"   set UDP source port min, If < udp_src_max, then
 pgset "udp_src_min 9"   set UDP source port min, If < udp_src_max, then
                         cycle through the port range.
                         cycle through the port range.
@@ -207,8 +218,6 @@ Examples:
 pgset "tos XX"           set former IPv4 TOS field (e.g. "tos 28" for AF11 no ECN, default 00)
 pgset "tos XX"           set former IPv4 TOS field (e.g. "tos 28" for AF11 no ECN, default 00)
 pgset "traffic_class XX" set former IPv6 TRAFFIC CLASS (e.g. "traffic_class B8" for EF no ECN, default 00)
 pgset "traffic_class XX" set former IPv6 TRAFFIC CLASS (e.g. "traffic_class B8" for EF no ECN, default 00)


 pgset stop    	          aborts injection. Also, ^C aborts generator.

 pgset "rate 300M"        set rate to 300 Mb/s
 pgset "rate 300M"        set rate to 300 Mb/s
 pgset "ratep 1000000"    set rate to 1Mpps
 pgset "ratep 1000000"    set rate to 1Mpps


+89 −177
Original line number Original line Diff line number Diff line
@@ -184,25 +184,44 @@


#define func_enter() pr_debug("entering %s\n", __func__);
#define func_enter() pr_debug("entering %s\n", __func__);


#define PKT_FLAGS							\
	pf(IPV6)		/* Interface in IPV6 Mode */		\
	pf(IPSRC_RND)		/* IP-Src Random  */			\
	pf(IPDST_RND)		/* IP-Dst Random  */			\
	pf(TXSIZE_RND)		/* Transmit size is random */		\
	pf(UDPSRC_RND)		/* UDP-Src Random */			\
	pf(UDPDST_RND)		/* UDP-Dst Random */			\
	pf(UDPCSUM)		/* Include UDP checksum */		\
	pf(NO_TIMESTAMP)	/* Don't timestamp packets (default TS) */ \
	pf(MPLS_RND)		/* Random MPLS labels */		\
	pf(QUEUE_MAP_RND)	/* queue map Random */			\
	pf(QUEUE_MAP_CPU)	/* queue map mirrors smp_processor_id() */ \
	pf(FLOW_SEQ)		/* Sequential flows */			\
	pf(IPSEC)		/* ipsec on for flows */		\
	pf(MACSRC_RND)		/* MAC-Src Random */			\
	pf(MACDST_RND)		/* MAC-Dst Random */			\
	pf(VID_RND)		/* Random VLAN ID */			\
	pf(SVID_RND)		/* Random SVLAN ID */			\
	pf(NODE)		/* Node memory alloc*/			\

#define pf(flag)		flag##_SHIFT,
enum pkt_flags {
	PKT_FLAGS
};
#undef pf

/* Device flag bits */
/* Device flag bits */
#define F_IPSRC_RND   (1<<0)	/* IP-Src Random  */
#define pf(flag)		static const __u32 F_##flag = (1<<flag##_SHIFT);
#define F_IPDST_RND   (1<<1)	/* IP-Dst Random  */
PKT_FLAGS
#define F_UDPSRC_RND  (1<<2)	/* UDP-Src Random */
#undef pf
#define F_UDPDST_RND  (1<<3)	/* UDP-Dst Random */

#define F_MACSRC_RND  (1<<4)	/* MAC-Src Random */
#define pf(flag)		__stringify(flag),
#define F_MACDST_RND  (1<<5)	/* MAC-Dst Random */
static char *pkt_flag_names[] = {
#define F_TXSIZE_RND  (1<<6)	/* Transmit size is random */
	PKT_FLAGS
#define F_IPV6        (1<<7)	/* Interface in IPV6 Mode */
};
#define F_MPLS_RND    (1<<8)	/* Random MPLS labels */
#undef pf
#define F_VID_RND     (1<<9)	/* Random VLAN ID */

#define F_SVID_RND    (1<<10)	/* Random SVLAN ID */
#define NR_PKT_FLAGS		ARRAY_SIZE(pkt_flag_names)
#define F_FLOW_SEQ    (1<<11)	/* Sequential flows */
#define F_IPSEC_ON    (1<<12)	/* ipsec on for flows */
#define F_QUEUE_MAP_RND (1<<13)	/* queue map Random */
#define F_QUEUE_MAP_CPU (1<<14)	/* queue map mirrors smp_processor_id() */
#define F_NODE          (1<<15)	/* Node memory alloc*/
#define F_UDPCSUM       (1<<16)	/* Include UDP checksum */
#define F_NO_TIMESTAMP  (1<<17)	/* Don't timestamp packets (default TS) */


/* Thread control flag bits */
/* Thread control flag bits */
#define T_STOP        (1<<0)	/* Stop run */
#define T_STOP        (1<<0)	/* Stop run */
@@ -534,6 +553,7 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
{
{
	const struct pktgen_dev *pkt_dev = seq->private;
	const struct pktgen_dev *pkt_dev = seq->private;
	ktime_t stopped;
	ktime_t stopped;
	unsigned int i;
	u64 idle;
	u64 idle;


	seq_printf(seq,
	seq_printf(seq,
@@ -595,7 +615,6 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
		   pkt_dev->src_mac_count, pkt_dev->dst_mac_count);
		   pkt_dev->src_mac_count, pkt_dev->dst_mac_count);


	if (pkt_dev->nr_labels) {
	if (pkt_dev->nr_labels) {
		unsigned int i;
		seq_puts(seq, "     mpls: ");
		seq_puts(seq, "     mpls: ");
		for (i = 0; i < pkt_dev->nr_labels; i++)
		for (i = 0; i < pkt_dev->nr_labels; i++)
			seq_printf(seq, "%08x%s", ntohl(pkt_dev->labels[i]),
			seq_printf(seq, "%08x%s", ntohl(pkt_dev->labels[i]),
@@ -631,68 +650,21 @@ static int pktgen_if_show(struct seq_file *seq, void *v)


	seq_puts(seq, "     Flags: ");
	seq_puts(seq, "     Flags: ");


	if (pkt_dev->flags & F_IPV6)
	for (i = 0; i < NR_PKT_FLAGS; i++) {
		seq_puts(seq, "IPV6  ");
		if (i == F_FLOW_SEQ)

			if (!pkt_dev->cflows)
	if (pkt_dev->flags & F_IPSRC_RND)
				continue;
		seq_puts(seq, "IPSRC_RND  ");

	if (pkt_dev->flags & F_IPDST_RND)
		seq_puts(seq, "IPDST_RND  ");

	if (pkt_dev->flags & F_TXSIZE_RND)
		seq_puts(seq, "TXSIZE_RND  ");

	if (pkt_dev->flags & F_UDPSRC_RND)
		seq_puts(seq, "UDPSRC_RND  ");

	if (pkt_dev->flags & F_UDPDST_RND)
		seq_puts(seq, "UDPDST_RND  ");

	if (pkt_dev->flags & F_UDPCSUM)
		seq_puts(seq, "UDPCSUM  ");

	if (pkt_dev->flags & F_NO_TIMESTAMP)
		seq_puts(seq, "NO_TIMESTAMP  ");

	if (pkt_dev->flags & F_MPLS_RND)
		seq_puts(seq,  "MPLS_RND  ");

	if (pkt_dev->flags & F_QUEUE_MAP_RND)
		seq_puts(seq,  "QUEUE_MAP_RND  ");

	if (pkt_dev->flags & F_QUEUE_MAP_CPU)
		seq_puts(seq,  "QUEUE_MAP_CPU  ");


	if (pkt_dev->cflows) {
		if (pkt_dev->flags & (1 << i))
		if (pkt_dev->flags & F_FLOW_SEQ)
			seq_printf(seq, "%s  ", pkt_flag_names[i]);
			seq_puts(seq,  "FLOW_SEQ  "); /*in sequence flows*/
		else if (i == F_FLOW_SEQ)
		else
			seq_puts(seq, "FLOW_RND  ");
			seq_puts(seq, "FLOW_RND  ");
	}


#ifdef CONFIG_XFRM
#ifdef CONFIG_XFRM
	if (pkt_dev->flags & F_IPSEC_ON) {
		if (i == F_IPSEC && pkt_dev->spi)
		seq_puts(seq,  "IPSEC  ");
		if (pkt_dev->spi)
			seq_printf(seq, "spi:%u", pkt_dev->spi);
			seq_printf(seq, "spi:%u", pkt_dev->spi);
	}
#endif
#endif

	}
	if (pkt_dev->flags & F_MACSRC_RND)
		seq_puts(seq, "MACSRC_RND  ");

	if (pkt_dev->flags & F_MACDST_RND)
		seq_puts(seq, "MACDST_RND  ");

	if (pkt_dev->flags & F_VID_RND)
		seq_puts(seq, "VID_RND  ");

	if (pkt_dev->flags & F_SVID_RND)
		seq_puts(seq, "SVID_RND  ");

	if (pkt_dev->flags & F_NODE)
		seq_puts(seq, "NODE_ALLOC  ");


	seq_puts(seq, "\n");
	seq_puts(seq, "\n");


@@ -858,6 +830,35 @@ static ssize_t get_labels(const char __user *buffer, struct pktgen_dev *pkt_dev)
	return i;
	return i;
}
}


static __u32 pktgen_read_flag(const char *f, bool *disable)
{
	__u32 i;

	if (f[0] == '!') {
		*disable = true;
		f++;
	}

	for (i = 0; i < NR_PKT_FLAGS; i++) {
		if (!IS_ENABLED(CONFIG_XFRM) && i == IPSEC_SHIFT)
			continue;

		/* allow only disabling ipv6 flag */
		if (!*disable && i == IPV6_SHIFT)
			continue;

		if (strcmp(f, pkt_flag_names[i]) == 0)
			return 1 << i;
	}

	if (strcmp(f, "FLOW_RND") == 0) {
		*disable = !*disable;
		return F_FLOW_SEQ;
	}

	return 0;
}

static ssize_t pktgen_if_write(struct file *file,
static ssize_t pktgen_if_write(struct file *file,
			       const char __user * user_buffer, size_t count,
			       const char __user * user_buffer, size_t count,
			       loff_t * offset)
			       loff_t * offset)
@@ -1215,7 +1216,10 @@ static ssize_t pktgen_if_write(struct file *file,
		return count;
		return count;
	}
	}
	if (!strcmp(name, "flag")) {
	if (!strcmp(name, "flag")) {
		__u32 flag;
		char f[32];
		char f[32];
		bool disable = false;

		memset(f, 0, 32);
		memset(f, 0, 32);
		len = strn_len(&user_buffer[i], sizeof(f) - 1);
		len = strn_len(&user_buffer[i], sizeof(f) - 1);
		if (len < 0)
		if (len < 0)
@@ -1224,107 +1228,15 @@ static ssize_t pktgen_if_write(struct file *file,
		if (copy_from_user(f, &user_buffer[i], len))
		if (copy_from_user(f, &user_buffer[i], len))
			return -EFAULT;
			return -EFAULT;
		i += len;
		i += len;
		if (strcmp(f, "IPSRC_RND") == 0)
			pkt_dev->flags |= F_IPSRC_RND;

		else if (strcmp(f, "!IPSRC_RND") == 0)
			pkt_dev->flags &= ~F_IPSRC_RND;

		else if (strcmp(f, "TXSIZE_RND") == 0)
			pkt_dev->flags |= F_TXSIZE_RND;

		else if (strcmp(f, "!TXSIZE_RND") == 0)
			pkt_dev->flags &= ~F_TXSIZE_RND;

		else if (strcmp(f, "IPDST_RND") == 0)
			pkt_dev->flags |= F_IPDST_RND;

		else if (strcmp(f, "!IPDST_RND") == 0)
			pkt_dev->flags &= ~F_IPDST_RND;

		else if (strcmp(f, "UDPSRC_RND") == 0)
			pkt_dev->flags |= F_UDPSRC_RND;

		else if (strcmp(f, "!UDPSRC_RND") == 0)
			pkt_dev->flags &= ~F_UDPSRC_RND;

		else if (strcmp(f, "UDPDST_RND") == 0)
			pkt_dev->flags |= F_UDPDST_RND;

		else if (strcmp(f, "!UDPDST_RND") == 0)
			pkt_dev->flags &= ~F_UDPDST_RND;

		else if (strcmp(f, "MACSRC_RND") == 0)
			pkt_dev->flags |= F_MACSRC_RND;

		else if (strcmp(f, "!MACSRC_RND") == 0)
			pkt_dev->flags &= ~F_MACSRC_RND;

		else if (strcmp(f, "MACDST_RND") == 0)
			pkt_dev->flags |= F_MACDST_RND;

		else if (strcmp(f, "!MACDST_RND") == 0)
			pkt_dev->flags &= ~F_MACDST_RND;

		else if (strcmp(f, "MPLS_RND") == 0)
			pkt_dev->flags |= F_MPLS_RND;


		else if (strcmp(f, "!MPLS_RND") == 0)
		flag = pktgen_read_flag(f, &disable);
			pkt_dev->flags &= ~F_MPLS_RND;


		else if (strcmp(f, "VID_RND") == 0)
		if (flag) {
			pkt_dev->flags |= F_VID_RND;
			if (disable)

				pkt_dev->flags &= ~flag;
		else if (strcmp(f, "!VID_RND") == 0)
			else
			pkt_dev->flags &= ~F_VID_RND;
				pkt_dev->flags |= flag;

		} else {
		else if (strcmp(f, "SVID_RND") == 0)
			pkt_dev->flags |= F_SVID_RND;

		else if (strcmp(f, "!SVID_RND") == 0)
			pkt_dev->flags &= ~F_SVID_RND;

		else if (strcmp(f, "FLOW_SEQ") == 0)
			pkt_dev->flags |= F_FLOW_SEQ;

		else if (strcmp(f, "QUEUE_MAP_RND") == 0)
			pkt_dev->flags |= F_QUEUE_MAP_RND;

		else if (strcmp(f, "!QUEUE_MAP_RND") == 0)
			pkt_dev->flags &= ~F_QUEUE_MAP_RND;

		else if (strcmp(f, "QUEUE_MAP_CPU") == 0)
			pkt_dev->flags |= F_QUEUE_MAP_CPU;

		else if (strcmp(f, "!QUEUE_MAP_CPU") == 0)
			pkt_dev->flags &= ~F_QUEUE_MAP_CPU;
#ifdef CONFIG_XFRM
		else if (strcmp(f, "IPSEC") == 0)
			pkt_dev->flags |= F_IPSEC_ON;
#endif

		else if (strcmp(f, "!IPV6") == 0)
			pkt_dev->flags &= ~F_IPV6;

		else if (strcmp(f, "NODE_ALLOC") == 0)
			pkt_dev->flags |= F_NODE;

		else if (strcmp(f, "!NODE_ALLOC") == 0)
			pkt_dev->flags &= ~F_NODE;

		else if (strcmp(f, "UDPCSUM") == 0)
			pkt_dev->flags |= F_UDPCSUM;

		else if (strcmp(f, "!UDPCSUM") == 0)
			pkt_dev->flags &= ~F_UDPCSUM;

		else if (strcmp(f, "NO_TIMESTAMP") == 0)
			pkt_dev->flags |= F_NO_TIMESTAMP;

		else if (strcmp(f, "!NO_TIMESTAMP") == 0)
			pkt_dev->flags &= ~F_NO_TIMESTAMP;

		else {
			sprintf(pg_result,
			sprintf(pg_result,
				"Flag -:%s:- unknown\nAvailable flags, (prepend ! to un-set flag):\n%s",
				"Flag -:%s:- unknown\nAvailable flags, (prepend ! to un-set flag):\n%s",
				f,
				f,
@@ -2541,7 +2453,7 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)
				pkt_dev->flows[flow].cur_daddr =
				pkt_dev->flows[flow].cur_daddr =
				    pkt_dev->cur_daddr;
				    pkt_dev->cur_daddr;
#ifdef CONFIG_XFRM
#ifdef CONFIG_XFRM
				if (pkt_dev->flags & F_IPSEC_ON)
				if (pkt_dev->flags & F_IPSEC)
					get_ipsec_sa(pkt_dev, flow);
					get_ipsec_sa(pkt_dev, flow);
#endif
#endif
				pkt_dev->nflows++;
				pkt_dev->nflows++;
@@ -2646,7 +2558,7 @@ static void free_SAs(struct pktgen_dev *pkt_dev)
static int process_ipsec(struct pktgen_dev *pkt_dev,
static int process_ipsec(struct pktgen_dev *pkt_dev,
			      struct sk_buff *skb, __be16 protocol)
			      struct sk_buff *skb, __be16 protocol)
{
{
	if (pkt_dev->flags & F_IPSEC_ON) {
	if (pkt_dev->flags & F_IPSEC) {
		struct xfrm_state *x = pkt_dev->flows[pkt_dev->curfl].x;
		struct xfrm_state *x = pkt_dev->flows[pkt_dev->curfl].x;
		int nhead = 0;
		int nhead = 0;
		if (x) {
		if (x) {