diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/core/pktgen.c | 60 |
1 files changed, 52 insertions, 8 deletions
diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 9f0a780aa916..683da7065886 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c | |||
@@ -181,6 +181,7 @@ | |||
181 | #define F_MPLS_RND (1<<8) /* Random MPLS labels */ | 181 | #define F_MPLS_RND (1<<8) /* Random MPLS labels */ |
182 | #define F_VID_RND (1<<9) /* Random VLAN ID */ | 182 | #define F_VID_RND (1<<9) /* Random VLAN ID */ |
183 | #define F_SVID_RND (1<<10) /* Random SVLAN ID */ | 183 | #define F_SVID_RND (1<<10) /* Random SVLAN ID */ |
184 | #define F_FLOW_SEQ (1<<11) /* Sequential flows */ | ||
184 | 185 | ||
185 | /* Thread control flag bits */ | 186 | /* Thread control flag bits */ |
186 | #define T_TERMINATE (1<<0) | 187 | #define T_TERMINATE (1<<0) |
@@ -207,8 +208,12 @@ static struct proc_dir_entry *pg_proc_dir = NULL; | |||
207 | struct flow_state { | 208 | struct flow_state { |
208 | __be32 cur_daddr; | 209 | __be32 cur_daddr; |
209 | int count; | 210 | int count; |
211 | __u32 flags; | ||
210 | }; | 212 | }; |
211 | 213 | ||
214 | /* flow flag bits */ | ||
215 | #define F_INIT (1<<0) /* flow has been initialized */ | ||
216 | |||
212 | struct pktgen_dev { | 217 | struct pktgen_dev { |
213 | /* | 218 | /* |
214 | * Try to keep frequent/infrequent used vars. separated. | 219 | * Try to keep frequent/infrequent used vars. separated. |
@@ -342,6 +347,7 @@ struct pktgen_dev { | |||
342 | unsigned cflows; /* Concurrent flows (config) */ | 347 | unsigned cflows; /* Concurrent flows (config) */ |
343 | unsigned lflow; /* Flow length (config) */ | 348 | unsigned lflow; /* Flow length (config) */ |
344 | unsigned nflows; /* accumulated flows (stats) */ | 349 | unsigned nflows; /* accumulated flows (stats) */ |
350 | unsigned curfl; /* current sequenced flow (state)*/ | ||
345 | 351 | ||
346 | char result[512]; | 352 | char result[512]; |
347 | }; | 353 | }; |
@@ -691,6 +697,13 @@ static int pktgen_if_show(struct seq_file *seq, void *v) | |||
691 | if (pkt_dev->flags & F_MPLS_RND) | 697 | if (pkt_dev->flags & F_MPLS_RND) |
692 | seq_printf(seq, "MPLS_RND "); | 698 | seq_printf(seq, "MPLS_RND "); |
693 | 699 | ||
700 | if (pkt_dev->cflows) { | ||
701 | if (pkt_dev->flags & F_FLOW_SEQ) | ||
702 | seq_printf(seq, "FLOW_SEQ "); /*in sequence flows*/ | ||
703 | else | ||
704 | seq_printf(seq, "FLOW_RND "); | ||
705 | } | ||
706 | |||
694 | if (pkt_dev->flags & F_MACSRC_RND) | 707 | if (pkt_dev->flags & F_MACSRC_RND) |
695 | seq_printf(seq, "MACSRC_RND "); | 708 | seq_printf(seq, "MACSRC_RND "); |
696 | 709 | ||
@@ -1182,6 +1195,9 @@ static ssize_t pktgen_if_write(struct file *file, | |||
1182 | else if (strcmp(f, "!SVID_RND") == 0) | 1195 | else if (strcmp(f, "!SVID_RND") == 0) |
1183 | pkt_dev->flags &= ~F_SVID_RND; | 1196 | pkt_dev->flags &= ~F_SVID_RND; |
1184 | 1197 | ||
1198 | else if (strcmp(f, "FLOW_SEQ") == 0) | ||
1199 | pkt_dev->flags |= F_FLOW_SEQ; | ||
1200 | |||
1185 | else if (strcmp(f, "!IPV6") == 0) | 1201 | else if (strcmp(f, "!IPV6") == 0) |
1186 | pkt_dev->flags &= ~F_IPV6; | 1202 | pkt_dev->flags &= ~F_IPV6; |
1187 | 1203 | ||
@@ -1190,7 +1206,7 @@ static ssize_t pktgen_if_write(struct file *file, | |||
1190 | "Flag -:%s:- unknown\nAvailable flags, (prepend ! to un-set flag):\n%s", | 1206 | "Flag -:%s:- unknown\nAvailable flags, (prepend ! to un-set flag):\n%s", |
1191 | f, | 1207 | f, |
1192 | "IPSRC_RND, IPDST_RND, UDPSRC_RND, UDPDST_RND, " | 1208 | "IPSRC_RND, IPDST_RND, UDPSRC_RND, UDPDST_RND, " |
1193 | "MACSRC_RND, MACDST_RND, TXSIZE_RND, IPV6, MPLS_RND, VID_RND, SVID_RND\n"); | 1209 | "MACSRC_RND, MACDST_RND, TXSIZE_RND, IPV6, MPLS_RND, VID_RND, SVID_RND, FLOW_SEQ\n"); |
1194 | return count; | 1210 | return count; |
1195 | } | 1211 | } |
1196 | sprintf(pg_result, "OK: flags=0x%x", pkt_dev->flags); | 1212 | sprintf(pg_result, "OK: flags=0x%x", pkt_dev->flags); |
@@ -2083,6 +2099,37 @@ static inline void set_pkt_overhead(struct pktgen_dev *pkt_dev) | |||
2083 | pkt_dev->pkt_overhead += SVLAN_TAG_SIZE(pkt_dev); | 2099 | pkt_dev->pkt_overhead += SVLAN_TAG_SIZE(pkt_dev); |
2084 | } | 2100 | } |
2085 | 2101 | ||
2102 | static inline int f_seen(struct pktgen_dev *pkt_dev, int flow) | ||
2103 | { | ||
2104 | |||
2105 | if (pkt_dev->flows[flow].flags & F_INIT) | ||
2106 | return 1; | ||
2107 | else | ||
2108 | return 0; | ||
2109 | } | ||
2110 | |||
2111 | static inline int f_pick(struct pktgen_dev *pkt_dev) | ||
2112 | { | ||
2113 | int flow = pkt_dev->curfl; | ||
2114 | |||
2115 | if (pkt_dev->flags & F_FLOW_SEQ) { | ||
2116 | if (pkt_dev->flows[flow].count >= pkt_dev->lflow) { | ||
2117 | /* reset time */ | ||
2118 | pkt_dev->flows[flow].count = 0; | ||
2119 | pkt_dev->curfl += 1; | ||
2120 | if (pkt_dev->curfl >= pkt_dev->cflows) | ||
2121 | pkt_dev->curfl = 0; /*reset */ | ||
2122 | } | ||
2123 | } else { | ||
2124 | flow = random32() % pkt_dev->cflows; | ||
2125 | |||
2126 | if (pkt_dev->flows[flow].count > pkt_dev->lflow) | ||
2127 | pkt_dev->flows[flow].count = 0; | ||
2128 | } | ||
2129 | |||
2130 | return pkt_dev->curfl; | ||
2131 | } | ||
2132 | |||
2086 | /* Increment/randomize headers according to flags and current values | 2133 | /* Increment/randomize headers according to flags and current values |
2087 | * for IP src/dest, UDP src/dst port, MAC-Addr src/dst | 2134 | * for IP src/dest, UDP src/dst port, MAC-Addr src/dst |
2088 | */ | 2135 | */ |
@@ -2092,12 +2139,8 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev) | |||
2092 | __u32 imx; | 2139 | __u32 imx; |
2093 | int flow = 0; | 2140 | int flow = 0; |
2094 | 2141 | ||
2095 | if (pkt_dev->cflows) { | 2142 | if (pkt_dev->cflows) |
2096 | flow = random32() % pkt_dev->cflows; | 2143 | flow = f_pick(pkt_dev); |
2097 | |||
2098 | if (pkt_dev->flows[flow].count > pkt_dev->lflow) | ||
2099 | pkt_dev->flows[flow].count = 0; | ||
2100 | } | ||
2101 | 2144 | ||
2102 | /* Deal with source MAC */ | 2145 | /* Deal with source MAC */ |
2103 | if (pkt_dev->src_mac_count > 1) { | 2146 | if (pkt_dev->src_mac_count > 1) { |
@@ -2213,7 +2256,7 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev) | |||
2213 | pkt_dev->cur_saddr = htonl(t); | 2256 | pkt_dev->cur_saddr = htonl(t); |
2214 | } | 2257 | } |
2215 | 2258 | ||
2216 | if (pkt_dev->cflows && pkt_dev->flows[flow].count != 0) { | 2259 | if (pkt_dev->cflows && f_seen(pkt_dev, flow)) { |
2217 | pkt_dev->cur_daddr = pkt_dev->flows[flow].cur_daddr; | 2260 | pkt_dev->cur_daddr = pkt_dev->flows[flow].cur_daddr; |
2218 | } else { | 2261 | } else { |
2219 | imn = ntohl(pkt_dev->daddr_min); | 2262 | imn = ntohl(pkt_dev->daddr_min); |
@@ -2243,6 +2286,7 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev) | |||
2243 | } | 2286 | } |
2244 | } | 2287 | } |
2245 | if (pkt_dev->cflows) { | 2288 | if (pkt_dev->cflows) { |
2289 | pkt_dev->flows[flow].flags |= F_INIT; | ||
2246 | pkt_dev->flows[flow].cur_daddr = | 2290 | pkt_dev->flows[flow].cur_daddr = |
2247 | pkt_dev->cur_daddr; | 2291 | pkt_dev->cur_daddr; |
2248 | pkt_dev->nflows++; | 2292 | pkt_dev->nflows++; |