pktgen: Behavior flags fixes
Subsystems (3)
v2 cover 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.
Dmitry Safonov (5):
Documentation/pktgen: Clearify how-to use pktgen samples
pktgen: Add missing !flag parameters
pktgen: Add behaviour flags macro to generate flags/names
pktgen: Remove brute-force printing of flags
pktgen: Clean read user supplied flag mess
Documentation/networking/pktgen.txt | 19 ++- net/core/pktgen.c | 266 ++++++++++++------------------------ 2 files changed, 103 insertions(+), 182 deletions(-)
Signature · 1 line
2.13.6
PATCH v2 1/5 Documentation/pktgen: Clearify how-to use pktgen samples
o Change process name in ps output: looks like, these days the process is named kpktgend_<cpu>, rather than pktgen/<cpu>.
o Use pg_ctrl for start/stop as it can work well with pgset without changes to $(PGDEV) variable.
o Clarify a bit needed $(PGDEV) definition for sample scripts and that one needs to source functions.sh.
o Document how-to unset a behaviour flag, note about history expansion.
o Fix pgset spi parameter value.
--- Documentation/networking/pktgen.txt | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-)
Documentation/networking/pktgen.txt +14 -5
@@ -12,8 +12,8 @@ suitable sample script and configure that. On a dual CPU: ps aux | grep pkt -root 129 0.3 0.0 0 0 ? SW 2003 523:20 [pktgen/0] -root 130 0.3 0.0 0 0 ? SW 2003 509:50 [pktgen/1] +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 [kpktgend_1] 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 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: + 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 0" use single SKB for all transmits 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) NODE_ALLOC # node specific memory allocation 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 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 "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 "ratep 1000000" set rate to 1Mpps
Signature · 1 line
2.13.6
PATCH v2 2/5 pktgen: Add missing !flag parameters
In reply to Dmitry Safonovo FLOW_SEQ now can be disabled with pgset "flag !FLOW_SEQ"
o FLOW_SEQ and FLOW_RND are antonyms, as it's shown by pktgen_if_show()
o IPSEC now may be disabled
Note, that IPV6 is enabled with dst6/src6 parameters, not with a flag parameter.
--- net/core/pktgen.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
net/core/pktgen.c +7 -1
@@ -1285,9 +1285,12 @@ static ssize_t pktgen_if_write(struct file *file,else if (strcmp (f,"!SVID_RND" ) ==0 ) pkt_dev->flags &= ~F_SVID_RND ; -else if (strcmp (f,"FLOW_SEQ" ) ==0 ) +else if (strcmp (f,"FLOW_SEQ" ) ==0 ||strcmp (f,"!FLOW_RND" ) ==0 ) pkt_dev->flags |=F_FLOW_SEQ ; +else if (strcmp (f,"FLOW_RND" ) ==0 ||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 ;
@@ -1302,6 +1305,9 @@ static ssize_t pktgen_if_write(struct file *file, #ifdef CONFIG_XFRM else if (strcmp(f, "IPSEC") == 0) pkt_dev->flags |= F_IPSEC_ON; + + else if (strcmp(f, "!IPSEC") == 0) + pkt_dev->flags &= ~F_IPSEC_ON; #endif else if (strcmp(f, "!IPV6") == 0)
Signature · 1 line
2.13.6
PATCH v2 3/5 pktgen: Add behaviour flags macro to generate flags/names
In reply to Dmitry SafonovPKT_FALGS macro will be used to add package behavior names definitions to simplify the code that prints/reads pkg flags.
Sorted the array in order of printing the flags in pktgen_if_show()
Note: Renamed IPSEC_ON => IPSEC for simplicity.
No visible behavior change expected.
--- net/core/pktgen.c | 57 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 23 deletions(-)
net/core/pktgen.c +34 -23
@@ -184,25 +184,36 @@#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 */ -#define F_IPSRC_RND (1<<0)/* IP-Src Random */ -#define F_IPDST_RND (1<<1)/* IP-Dst Random */ -#define F_UDPSRC_RND (1<<2)/* UDP-Src Random */ -#define F_UDPDST_RND (1<<3)/* UDP-Dst Random */ -#define F_MACSRC_RND (1<<4)/* MAC-Src Random */ -#define F_MACDST_RND (1<<5)/* MAC-Dst Random */ -#define F_TXSIZE_RND (1<<6)/* Transmit size is random */ -#define F_IPV6 (1<<7)/* Interface in IPV6 Mode */ -#define F_MPLS_RND (1<<8)/* Random MPLS labels */ -#define F_VID_RND (1<<9)/* Random VLAN ID */ -#define F_SVID_RND (1<<10)/* Random SVLAN ID */ -#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) */ +#define pf (flag) static const __u32 F_##flag = (1<<flag##_SHIFT); +PKT_FLAGS +#undef pf/* Thread control flag bits */ #define T_STOP (1<<0)/* Stop run */
@@ -673,7 +684,7 @@ static int pktgen_if_show(struct seq_file *seq, void *v) }#ifdef CONFIG_XFRM -if (pkt_dev->flags &F_IPSEC_ON ) { +if (pkt_dev->flags &F_IPSEC ) {seq_puts (seq,"IPSEC " );if (pkt_dev->spi)seq_printf (seq,"spi:%u" , pkt_dev->spi);
@@ -1304,10 +1315,10 @@ static ssize_t pktgen_if_write(struct file *file, pkt_dev->flags &= ~F_QUEUE_MAP_CPU ; #ifdef CONFIG_XFRM else if (strcmp(f, "IPSEC") == 0) - pkt_dev->flags |= F_IPSEC_ON; + pkt_dev->flags |= F_IPSEC; else if (strcmp(f, "!IPSEC") == 0) - pkt_dev->flags &= ~F_IPSEC_ON; + pkt_dev->flags &= ~F_IPSEC; #endif else if (strcmp(f, "!IPV6") == 0)
@@ -2550,7 +2561,7 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev) pkt_dev->flows[flow].cur_daddr = pkt_dev->cur_daddr;#ifdef CONFIG_XFRM -if (pkt_dev->flags &F_IPSEC_ON ) +if (pkt_dev->flags &F_IPSEC )get_ipsec_sa (pkt_dev, flow);#endif pkt_dev->nflows++;
@@ -2655,7 +2666,7 @@ static void free_SAs(struct pktgen_dev *pkt_dev)static int process_ipsec (struct pktgen_dev *pkt_dev,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;int nhead =0 ;if (x) {
Signature · 1 line
2.13.6
PATCH v2 4/5 pktgen: Remove brute-force printing of flags
In reply to Dmitry SafonovAdd macro generated pkt_flag_names array, with a little help of which the flags can be printed by using an index.
--- net/core/pktgen.c | 77 ++++++++++++++----------------------------------------- 1 file changed, 19 insertions(+), 58 deletions(-)
net/core/pktgen.c +19 -58
@@ -215,6 +215,14 @@ enum pkt_flags { PKT_FLAGS#undef pf +#define pf (flag) __stringify(flag), +static char *pkt_flag_names[] = { +PKT_FLAGS +}; +#undef pf + +#define NR_PKT_FLAGS ARRAY_SIZE(pkt_flag_names) +/* Thread control flag bits */ #define T_STOP (1<<0)/* Stop run */ #define T_RUN (1<<1)/* Start run */
@@ -546,6 +554,7 @@ static int pktgen_if_show(struct seq_file *seq, void *v) {const struct pktgen_dev *pkt_dev = seq->private;ktime_t stopped; +unsigned int i;u64 idle; seq_printf(seq,
@@ -607,7 +616,6 @@ static int pktgen_if_show(struct seq_file *seq, void *v) pkt_dev->src_mac_count, pkt_dev->dst_mac_count);if (pkt_dev->nr_labels) { -unsigned int i;seq_puts (seq," mpls: " );for (i =0 ; i < pkt_dev->nr_labels; i++) seq_printf(seq, "%08x%s", ntohl(pkt_dev->labels[i]),
@@ -643,68 +651,21 @@ static int pktgen_if_show(struct seq_file *seq, void *v)seq_puts (seq," Flags: " ); -if (pkt_dev->flags &F_IPV6 ) -seq_puts (seq,"IPV6 " ); - -if (pkt_dev->flags &F_IPSRC_RND ) -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 " ); +for (i =0 ; i <NR_PKT_FLAGS ; i++) { +if (i ==F_FLOW_SEQ ) +if (!pkt_dev->cflows) +continue ; -if (pkt_dev->cflows) { -if (pkt_dev->flags &F_FLOW_SEQ ) -seq_puts (seq,"FLOW_SEQ " );/*in sequence flows*/ -else -seq_puts (seq,"FLOW_RND " ); - } +if (pkt_dev->flags & (1 << i)) +seq_printf (seq,"%s " , pkt_flag_names[i]); +else if (i ==F_FLOW_SEQ ) +seq_puts (seq,"FLOW_RND " );#ifdef CONFIG_XFRM -if (pkt_dev->flags &F_IPSEC ) { -seq_puts (seq,"IPSEC " ); -if (pkt_dev->spi) +if (i ==F_IPSEC && pkt_dev->spi)seq_printf (seq,"spi:%u" , pkt_dev->spi); - }#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" );
Signature · 1 line
2.13.6
PATCH v2 5/5 pktgen: Clean read user supplied flag mess
In reply to Dmitry SafonovDon't use error-prone-brute-force way.
--- net/core/pktgen.c | 144 +++++++++++++++--------------------------------------- 1 file changed, 39 insertions(+), 105 deletions(-)
net/core/pktgen.c +39 -105
@@ -831,6 +831,35 @@ static ssize_t get_labels(const char __user *buffer, struct pktgen_dev *pkt_dev)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,const char __user * user_buffer,size_t count,loff_t * offset)
@@ -1188,7 +1217,10 @@ static ssize_t pktgen_if_write(struct file *file,return count; }if (!strcmp (name,"flag" )) { +__u32 flag;char f[32 ]; +bool disable = false; +memset (f,0 ,32 ); len =strn_len (&user_buffer[i],sizeof (f) -1 );if (len <0 )
@@ -1197,113 +1229,15 @@ static ssize_t pktgen_if_write(struct file *file,if (copy_from_user (f, &user_buffer[i], len))return -EFAULT ; 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; + flag =pktgen_read_flag (f, &disable); - 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) - pkt_dev->flags &= ~F_MPLS_RND; - - else if (strcmp(f, "VID_RND") == 0) - pkt_dev->flags |= F_VID_RND; - - else if (strcmp(f, "!VID_RND") == 0) - pkt_dev->flags &= ~F_VID_RND; - - 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 || strcmp(f, "!FLOW_RND") == 0) - pkt_dev->flags |= F_FLOW_SEQ; - - else if (strcmp(f, "FLOW_RND") == 0 || 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; - - else if (strcmp(f, "!IPSEC") == 0) - pkt_dev->flags &= ~F_IPSEC; -#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 { +if (flag) { +if (disable) + pkt_dev->flags &= ~flag; +else + pkt_dev->flags |= flag; + }else { sprintf(pg_result, "Flag -:%s:- unknown\nAvailable flags, (prepend ! to un-set flag):\n%s", f,
Signature · 1 line
2.13.6
David Miller
maintainerFrom: Dmitry Safonov <[email protected]>
Date: Thu, 18 Jan 2018 18:31:32 +0000
Quoted 6 lines
v2:
o fixed a nitpick from David MillerThere are a bunch of fixes/cleanups/Documentations. Diffstat says for itself, regardless added docs and missed flag parameters.
Series applied to net-next, thank you.