Skip to contentSkip to conversation

pktgen: receive packets and process incoming rate

PATCH Applied Daniel Turull 3 participants 6 messages Jun 2, 2010 – Jun 15, 2010

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 2/2 pktgen: receive packets and process incoming rate

This patch adds receiver part to pktgen taking advantages of SMP systems with multiple rx queues:
- Creation of new proc file /proc/net/pktgen/pgrx to control and display the receiver.
- It uses PER-CPU variable to store the results per each CPU.
- Results displayed per CPU and aggregated.
- The packet handler is add in the protocols handlers (dev_Add_pack())
- Available statistics: packets and bytes received, work time and rate
- Only process pktgen packets
- It is possible to select the incoming interface
- Documentation updated with the new commands to control the receiver part.

---

Documentation/networking/pktgen.txt +44 -1
index ac0e4ff..20a8810 100644
@@ -22,7 +22,7 @@ For monitoring and control pktgen creates:
 	/proc/net/pktgen/pgctrl
 	/proc/net/pktgen/kpktgend_X
         /proc/net/pktgen/ethX
-
+	/proc/net/pktgen/pgrx
 
 Viewing threads
 ===============
@@ -155,6 +155,43 @@ Examples:
  pgset stop    	          aborts injection. Also, ^C aborts generator.
 
 
+=======
+Viewing receiver
+================
+
+/proc/net/pktgen/pgrx
+
+		RECEPTION STATISTICS
+	PER-CPU Stats.
+CPU 0: 	Rx packets: 0	 Rx bytes: 0
+CPU 1: 	Rx packets: 2502400	 Rx bytes: 150144000
+	Rate:  22218pps 10 Mb/sec (10665033bps)
+	Worktime 112625248 us
+CPU 2: 	Rx packets: 1251200	 Rx bytes: 75072000
+	Rate:  11109pps 5 Mb/sec (5332412bps)
+	Worktime 112627453 us
+CPU 3: 	Rx packets: 1251100	 Rx bytes: 75066000
+	Rate:  11108pps 5 Mb/sec (5332035bps)
+	Worktime 112626413 us
+CPU 4: 	Rx packets: 1251400	 Rx bytes: 75084000
+	Rate:  11111pps 5 Mb/sec (5333458bps)
+	Worktime 112623364 us
+CPU 5: 	Rx packets: 1251200	 Rx bytes: 75072000
+	Rate:  11110pps 5 Mb/sec (5332844bps)
+	Worktime 112618314 us
+CPU 6: 	Rx packets: 1241500	 Rx bytes: 74490000
+	Rate:  11023pps 5 Mb/sec (5291273bps)
+	Worktime 112623172 us
+CPU 7: 	Rx packets: 1251200	 Rx bytes: 75072000
+	Rate:  11109pps 5 Mb/sec (5332628bps)
+	Worktime 112622877 us
+
+	Global Statistics
+Packets Rx: 10000000	 Bytes Rx: 600000000
+Start: 64952587054 us	 Stop: 65065224574 us	 Worktime  112637519 us
+Received throughput:
+  88780pps 42 Mb/sec (42614574bps)
+
 Example scripts
 ===============
 
@@ -247,6 +284,12 @@ src6
 flows
 flowlen
 
+**Receiver commands:
+
+rx [device]
+rx_reset
+rx_disable
+
 References:
 ftp://robur.slu.se/pub/Linux/net-development/pktgen-testing/
 ftp://robur.slu.se/pub/Linux/net-development/pktgen-testing/examples/
net/core/pktgen.c +307 -0

379 lines not on this page · raw message

#1 lore raw
Quoted 11 lines · Daniel Turull

This patch adds receiver part to pktgen taking advantages of SMP systems with multiple rx queues:
- Creation of new proc file /proc/net/pktgen/pgrx to control and display the receiver.
- It uses PER-CPU variable to store the results per each CPU.
- Results displayed per CPU and aggregated.
- The packet handler is add in the protocols handlers (dev_Add_pack())
- Available statistics: packets and bytes received, work time and rate
- Only process pktgen packets
- It is possible to select the incoming interface
- Documentation updated with the new commands to control the receiver part.

Interesting, but does it belongs to pktgen ?

other comments included :)

net/core/pktgen.c struct pktgen_thread { · line 415

Quoted 8 lines
net/core/pktgen.c +3 -0
+/*Recevier parameters per cpu*/
+struct pktgen_rx {
+	u64 rx_packets;		/*packets arrived*/

unsigned long rx_packets ?

Quoted 4 lines
net/core/pktgen.c +4 -0
+	u64 rx_bytes;		/*bytes arrived*/
+
+	ktime_t start_time;	/*first time stamp of a packet*/
+	ktime_t last_time;	/*last packet arrival */

net/core/pktgen.c static int pktgen_remove_device(struct pktgen_thread *t, · line 4155

Quoted 10 lines
net/core/pktgen.c +8 -0
+};
 
 
+int pktgen_rcv_basic(struct sk_buff *skb, struct net_device *dev,
+			 struct packet_type *pt, struct net_device *orig_dev)
+{
+	/* Check magic*/
+	struct iphdr *iph = ip_hdr(skb);
+	struct pktgen_hdr *pgh;
+	void *vaddr;

Following code is ... well ... interesting... But ...

1) Is it IPV6 compatable ? pktgen can be ipv6 or ipv4
2) Is it resistant to malicious packets ? (very small ones)
3) No checksum ?

I think you should use standard mechanisms... (pskb_may_pull(), ...) Take a look at __netpoll_rx() for an example.

Quoted 6 lines
net/core/pktgen.c +6 -0
+	if (skb_is_nonlinear(skb)) {
+		vaddr = kmap_skb_frag(&skb_shinfo(skb)->frags[0]);
+		pgh = (struct pktgen_hdr *)
+			(vaddr+skb_shinfo(skb)->frags[0].page_offset);
+	} else {
+		pgh = (struct pktgen_hdr *)(((char *)(iph)) + 28);

net/core/pktgen.c static int pktgen_remove_device(struct pktgen_thread *t, · line 4171

Quoted 10 lines
net/core/pktgen.c +10 -0
+	}
+
+	if (unlikely(pgh->pgh_magic != PKTGEN_MAGIC_NET))
+		goto end;
+
+	if (unlikely(!__get_cpu_var(pktgen_rx_data).rx_packets))
+		__get_cpu_var(pktgen_rx_data).start_time = ktime_now();
+
+	__get_cpu_var(pktgen_rx_data).last_time = ktime_now();
+

Its a bit suboptimal to use __get_cpu_var several time. Take a look at disassembly code :)

Use a pointer instead

net/core/pktgen.c static int pktgen_remove_device(struct pktgen_thread *t, · line 4174

Quoted 3 lines
net/core/pktgen.c +3 -0
+	/* Update counter of packets*/
+	__get_cpu_var(pktgen_rx_data).rx_packets++;
+	__get_cpu_var(pktgen_rx_data).rx_bytes += skb->len+14;

This +14 seems suspect (what about vlan tags ?)
Use ETH_HLEN instead at a very minimum?

net/core/pktgen.c static int pktgen_remove_device(struct pktgen_thread *t, · line 4177

Quoted 3 lines
net/core/pktgen.c +3 -0
+end:
+	if (skb_is_nonlinear(skb))
+		kunmap_skb_frag(vaddr);

Should not recognised packets be allowed to flight in other parts of kernel stack ? This way, we could use ssh to remotely control this pktgen session ;)

Quoted 4 lines
net/core/pktgen.c +4 -0
+	kfree_skb(skb);
+	return 0;
+}
+
#2 lore raw
Quoted 13 lines · Eric Dumazet
Quoted 11 lines · Daniel Turull

This patch adds receiver part to pktgen taking advantages of SMP systems with multiple rx queues:
- Creation of new proc file /proc/net/pktgen/pgrx to control and display the receiver.
- It uses PER-CPU variable to store the results per each CPU.
- Results displayed per CPU and aggregated.
- The packet handler is add in the protocols handlers (dev_Add_pack())
- Available statistics: packets and bytes received, work time and rate
- Only process pktgen packets
- It is possible to select the incoming interface
- Documentation updated with the new commands to control the receiver part.

Quoted 1 line

Interesting, but does it belongs to pktgen ?

Yes, it allows to receive a feedback of pktgen of the traffic received which comes from pktgen. It is an addition for pktgen. By default is disabled.

Quoted 7 lines

other comments included :)

Quoted 5 lines
Quoted 5 lines

net/core/pktgen.c struct pktgen_thread { · line 415

Quoted 3 lines
net/core/pktgen.c +3 -0
+/*Recevier parameters per cpu*/
+struct pktgen_rx {
+	u64 rx_packets;		/*packets arrived*/

unsigned long rx_packets ?

Yes, I used the same type as the number of packets send of the transmission size struct pktgen_dev

	__u64 sofar;
Quoted 17 lines
Quoted 4 lines
net/core/pktgen.c +4 -0
+	u64 rx_bytes;		/*bytes arrived*/
+
+	ktime_t start_time;	/*first time stamp of a packet*/
+	ktime_t last_time;	/*last packet arrival */

net/core/pktgen.c static int pktgen_remove_device(struct pktgen_thread *t, · line 4155

Quoted 10 lines
net/core/pktgen.c +8 -0
+};
 
 
+int pktgen_rcv_basic(struct sk_buff *skb, struct net_device *dev,
+			 struct packet_type *pt, struct net_device *orig_dev)
+{
+	/* Check magic*/
+	struct iphdr *iph = ip_hdr(skb);
+	struct pktgen_hdr *pgh;
+	void *vaddr;

Following code is ... well ... interesting... But ...

Quoted 1 line

1) Is it IPV6 compatable ? pktgen can be ipv6 or ipv4

It is not IPV6 compatible yet.

Quoted 1 line

2) Is it resistant to malicious packets ? (very small ones)

I only tried with pktgen traffic

Quoted 1 line

3) No checksum ?

The PKTGEN_MAGIC is checked in order to validate that is a pktgen packet

Quoted 23 lines

I think you should use standard mechanisms... (pskb_may_pull(), ...) Take a look at __netpoll_rx() for an example.

Quoted 6 lines
net/core/pktgen.c +6 -0
+	if (skb_is_nonlinear(skb)) {
+		vaddr = kmap_skb_frag(&skb_shinfo(skb)->frags[0]);
+		pgh = (struct pktgen_hdr *)
+			(vaddr+skb_shinfo(skb)->frags[0].page_offset);
+	} else {
+		pgh = (struct pktgen_hdr *)(((char *)(iph)) + 28);

net/core/pktgen.c static int pktgen_remove_device(struct pktgen_thread *t, · line 4171

Quoted 10 lines
net/core/pktgen.c +10 -0
+	}
+
+	if (unlikely(pgh->pgh_magic != PKTGEN_MAGIC_NET))
+		goto end;
+
+	if (unlikely(!__get_cpu_var(pktgen_rx_data).rx_packets))
+		__get_cpu_var(pktgen_rx_data).start_time = ktime_now();
+
+	__get_cpu_var(pktgen_rx_data).last_time = ktime_now();
+

Its a bit suboptimal to use __get_cpu_var several time. Take a look at disassembly code :)

Quoted 1 line

Use a pointer instead

Ok, thanks for the advice. I will redo this part in order to make it compatabile with IPV6 and make it more optimal.

Quoted 7 lines

net/core/pktgen.c static int pktgen_remove_device(struct pktgen_thread *t, · line 4174

Quoted 4 lines
net/core/pktgen.c +3 -0
+	/* Update counter of packets*/
+	__get_cpu_var(pktgen_rx_data).rx_packets++;
+	__get_cpu_var(pktgen_rx_data).rx_bytes += skb->len+14;

This +14 seems suspect (what about vlan tags ?)
Use ETH_HLEN instead at a very minimum?

This was added, in order to add the ethernet header in the bytes in order to have the same number in tx an rx, but yes I should use ETH_HLEN

Quoted 7 lines

net/core/pktgen.c static int pktgen_remove_device(struct pktgen_thread *t, · line 4177

Quoted 3 lines
net/core/pktgen.c +3 -0
+end:
+	if (skb_is_nonlinear(skb))
+		kunmap_skb_frag(vaddr);

Should not recognised packets be allowed to flight in other parts of kernel stack ? This way, we could use ssh to remotely control this pktgen session ;)

This handler as a new packet type, but the packets are also delivered to the IP stack. It is possible to control the session with ssh.

Quoted 5 lines
Quoted 4 lines
net/core/pktgen.c +4 -0
+	kfree_skb(skb);
+	return 0;
+}
+
#3 lore raw

Hi,

I've made some modification to the patch. I'll send another email with the patch, but I want to comment some things

Quoted 47 lines · Daniel Turull
Quoted 12 lines · Eric Dumazet
Quoted 11 lines · Daniel Turull

This patch adds receiver part to pktgen taking advantages of SMP systems with multiple rx queues:
- Creation of new proc file /proc/net/pktgen/pgrx to control and display the receiver.
- It uses PER-CPU variable to store the results per each CPU.
- Results displayed per CPU and aggregated.
- The packet handler is add in the protocols handlers (dev_Add_pack())
- Available statistics: packets and bytes received, work time and rate
- Only process pktgen packets
- It is possible to select the incoming interface
- Documentation updated with the new commands to control the receiver part.

Quoted 1 line

Interesting, but does it belongs to pktgen ?

Yes, it allows to receive a feedback of pktgen of the traffic received which comes from pktgen. It is an addition for pktgen. By default is disabled.

Quoted 10 lines

other comments included :)

net/core/pktgen.c struct pktgen_thread { · line 415

Quoted 7 lines
net/core/pktgen.c +3 -0
+/*Recevier parameters per cpu*/
+struct pktgen_rx {
+	u64 rx_packets;		/*packets arrived*/

unsigned long rx_packets ?

Yes, I used the same type as the number of packets send of the transmission size struct pktgen_dev

	__u64 sofar;
Quoted 15 lines

net/core/pktgen.c static int pktgen_remove_device(struct pktgen_thread *t, · line 4155

Quoted 13 lines
net/core/pktgen.c +12 -0
+	u64 rx_bytes;		/*bytes arrived*/
+
+	ktime_t start_time;	/*first time stamp of a packet*/
+	ktime_t last_time;	/*last packet arrival */
+};
 
+int pktgen_rcv_basic(struct sk_buff *skb, struct net_device *dev,
+			 struct packet_type *pt, struct net_device *orig_dev)
+{
+	/* Check magic*/
+	struct iphdr *iph = ip_hdr(skb);
+	struct pktgen_hdr *pgh;
+	void *vaddr;

Following code is ... well ... interesting... But ...

Quoted 2 lines
Quoted 1 line

1) Is it IPV6 compatable ? pktgen can be ipv6 or ipv4

It is not IPV6 compatible yet.

In order to make it to ipv6 compatible it will be better to create a new packet handler for the ipv6, because a different struct is need.

Quoted 2 lines
Quoted 1 line

2) Is it resistant to malicious packets ? (very small ones)

I only tried with pktgen traffic

Pktgen is used in experimental environments. In order to start the receiver is necessary to load the module and enable the reception with the proc file system.

Quoted 6 lines
Quoted 1 line

3) No checksum ?

The PKTGEN_MAGIC is checked in order to validate that is a pktgen packet

Quoted 2 lines

I think you should use standard mechanisms... (pskb_may_pull(), ...) Take a look at __netpoll_rx() for an example.

Now I'm using pskb_may_pull() but the performance is reduced.

Quoted 19 lines
Quoted 19 lines
Quoted 6 lines
net/core/pktgen.c +6 -0
+	if (skb_is_nonlinear(skb)) {
+		vaddr = kmap_skb_frag(&skb_shinfo(skb)->frags[0]);
+		pgh = (struct pktgen_hdr *)
+			(vaddr+skb_shinfo(skb)->frags[0].page_offset);
+	} else {
+		pgh = (struct pktgen_hdr *)(((char *)(iph)) + 28);

net/core/pktgen.c static int pktgen_remove_device(struct pktgen_thread *t, · line 4171

Quoted 10 lines
net/core/pktgen.c +10 -0
+	}
+
+	if (unlikely(pgh->pgh_magic != PKTGEN_MAGIC_NET))
+		goto end;
+
+	if (unlikely(!__get_cpu_var(pktgen_rx_data).rx_packets))
+		__get_cpu_var(pktgen_rx_data).start_time = ktime_now();
+
+	__get_cpu_var(pktgen_rx_data).last_time = ktime_now();
+

Its a bit suboptimal to use __get_cpu_var several time. Take a look at disassembly code :)

Quoted 3 lines
Quoted 1 line

Use a pointer instead

Ok, thanks for the advice. I will redo this part in order to make it compatabile with IPV6 and make it more optimal.

Changed.

Quoted 8 lines
Quoted 5 lines

net/core/pktgen.c static int pktgen_remove_device(struct pktgen_thread *t, · line 4174

Quoted 3 lines
net/core/pktgen.c +3 -0
+	/* Update counter of packets*/
+	__get_cpu_var(pktgen_rx_data).rx_packets++;
+	__get_cpu_var(pktgen_rx_data).rx_bytes += skb->len+14;

This +14 seems suspect (what about vlan tags ?)
Use ETH_HLEN instead at a very minimum?

This was added, in order to add the ethernet header in the bytes in order to have the same number in tx an rx, but yes I should use ETH_HLEN

I changed the 14 to ETH_HLEN. The VLAN, mpls overheads are not computed in this statistics because in the transmission, only the packet size introduced is counted.

Quoted 14 lines
Quoted 6 lines

net/core/pktgen.c static int pktgen_remove_device(struct pktgen_thread *t, · line 4177

Quoted 3 lines
net/core/pktgen.c +3 -0
+end:
+	if (skb_is_nonlinear(skb))
+		kunmap_skb_frag(vaddr);

Should not recognised packets be allowed to flight in other parts of kernel stack ? This way, we could use ssh to remotely control this pktgen session ;)

This handler as a new packet type, but the packets are also delivered to the IP stack. It is possible to control the session with ssh.

Quoted 4 lines
Quoted 4 lines
net/core/pktgen.c +4 -0
+	kfree_skb(skb);
+	return 0;
+}
+
#4 lore raw
In reply to Daniel Turull

This patch adds receiver part to pktgen taking advantages of SMP systems with multiple rx queues:
- Creation of new proc file /proc/net/pktgen/pgrx to control and display the receiver.
- It uses PER-CPU variable to store the results per each CPU.
- Results displayed per CPU and aggregated.
- The packet handler is add in the protocols handlers (dev_add_pack())
- Available statistics: packets and bytes received, work time and rate
- Only process pktgen packets
- It is possible to select the incoming interface
- Documentation updated with the new commands to control the receiver part.

---

Documentation/networking/pktgen.txt +43 -1
index ac0e4ff..ed3016a 100644
@@ -22,7 +22,7 @@ For monitoring and control pktgen creates:
 	/proc/net/pktgen/pgctrl
 	/proc/net/pktgen/kpktgend_X
         /proc/net/pktgen/ethX
-
+	/proc/net/pktgen/pgrx
 
 Viewing threads
 ===============
@@ -155,6 +155,42 @@ Examples:
  pgset stop    	          aborts injection. Also, ^C aborts generator.
 
 
+Viewing receiver
+================
+
+/proc/net/pktgen/pgrx
+
+		RECEPTION STATISTICS
+	PER-CPU Stats.
+CPU 0: 	Rx packets: 0	 Rx bytes: 0
+CPU 1: 	Rx packets: 2502400	 Rx bytes: 150144000
+	Rate:  22218pps 10 Mb/sec (10665033bps)
+	Worktime 112625248 us
+CPU 2: 	Rx packets: 1251200	 Rx bytes: 75072000
+	Rate:  11109pps 5 Mb/sec (5332412bps)
+	Worktime 112627453 us
+CPU 3: 	Rx packets: 1251100	 Rx bytes: 75066000
+	Rate:  11108pps 5 Mb/sec (5332035bps)
+	Worktime 112626413 us
+CPU 4: 	Rx packets: 1251400	 Rx bytes: 75084000
+	Rate:  11111pps 5 Mb/sec (5333458bps)
+	Worktime 112623364 us
+CPU 5: 	Rx packets: 1251200	 Rx bytes: 75072000
+	Rate:  11110pps 5 Mb/sec (5332844bps)
+	Worktime 112618314 us
+CPU 6: 	Rx packets: 1241500	 Rx bytes: 74490000
+	Rate:  11023pps 5 Mb/sec (5291273bps)
+	Worktime 112623172 us
+CPU 7: 	Rx packets: 1251200	 Rx bytes: 75072000
+	Rate:  11109pps 5 Mb/sec (5332628bps)
+	Worktime 112622877 us
+
+	Global Statistics
+Packets Rx: 10000000	 Bytes Rx: 600000000
+Start: 64952587054 us	 Stop: 65065224574 us	 Worktime  112637519 us
+Received throughput:
+  88780pps 42 Mb/sec (42614574bps)
+
 Example scripts
 ===============
 
@@ -247,6 +283,12 @@ src6
 flows
 flowlen
 
+**Receiver commands:
+
+rx [device]
+rx_reset
+rx_disable
+
 References:
 ftp://robur.slu.se/pub/Linux/net-development/pktgen-testing/
 ftp://robur.slu.se/pub/Linux/net-development/pktgen-testing/examples/
net/core/pktgen.c +308 -0

374 lines not on this page · raw message

maintainer
#5 lore raw

From: Daniel Turull <[email protected]>
Date: Thu, 10 Jun 2010 16:05:11 +0200

Quoted 11 lines

This patch adds receiver part to pktgen taking advantages of SMP systems with multiple rx queues:
- Creation of new proc file /proc/net/pktgen/pgrx to control and display the receiver.
- It uses PER-CPU variable to store the results per each CPU.
- Results displayed per CPU and aggregated.
- The packet handler is add in the protocols handlers (dev_add_pack())
- Available statistics: packets and bytes received, work time and rate
- Only process pktgen packets
- It is possible to select the incoming interface
- Documentation updated with the new commands to control the receiver part.

Quoted 1 line

I completely disagree with this patch on two levels:

1) pktgen is for "generating" packets, not receiving them. Trying to put lipstick on a pig is never a good idea.

2) The information it gathers and shows is completely useless. What's interesting as "RX work cost" is what happens deep down in the netif_receive_skb() code paths, IP input, routing, netfilter, whatever... but that is not what this thing is measuring at all.

Sorry, I'm not applying this. You can probably do something more clever with tracepoints.