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

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
...@@ -12,8 +12,8 @@ suitable sample script and configure that. ...@@ -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 ...@@ -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: ...@@ -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: ...@@ -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
......
...@@ -184,25 +184,44 @@ ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) if (pkt_dev->flags & (1 << i))
seq_puts(seq, "QUEUE_MAP_CPU "); seq_printf(seq, "%s ", pkt_flag_names[i]);
else if (i == F_FLOW_SEQ)
if (pkt_dev->cflows) { seq_puts(seq, "FLOW_RND ");
if (pkt_dev->flags & F_FLOW_SEQ)
seq_puts(seq, "FLOW_SEQ "); /*in sequence flows*/
else
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) ...@@ -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, ...@@ -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, ...@@ -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)
pkt_dev->flags &= ~F_MPLS_RND;
else if (strcmp(f, "VID_RND") == 0) flag = pktgen_read_flag(f, &disable);
pkt_dev->flags |= F_VID_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, "SVID_RND") == 0) else
pkt_dev->flags |= F_SVID_RND; pkt_dev->flags |= flag;
} else {
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) ...@@ -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) ...@@ -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) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment