Re: [EXTERNAL] Re: What throughput is reasonable?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



OK.... let's do an experiment.

Two c5.9xlarge instances.


$ ./netperf -H 10.0.161.101 -t UDP_STREAM -- -m 8970 
MIGRATED UDP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.0.161.101 () port 0 AF_INET
Socket  Message  Elapsed      Messages                
Size    Size     Time         Okay Errors   Throughput
bytes   bytes    secs            #      #   10^6bits/sec

212992    8970   10.00     1114099      0    7994.75
212992           10.00     1114099           7994.75

OK, it gets less impressive if I limit myself to 1400-byte packets:

$ ./netperf -H 10.0.161.101 -t UDP_STREAM -- -m 1400
MIGRATED UDP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.0.161.101 () port 0 AF_INET
Socket  Message  Elapsed      Messages                
Size    Size     Time         Okay Errors   Throughput
bytes   bytes    secs            #      #   10^6bits/sec

212992    1400   10.00     5077116      0    5686.36
212992           10.00     5074446           5683.37


So... kernel ESP between the two. Here's a script which sets it up:

cat > espsetup.sh <<EOF
#!/bin/sh

KEY=0x1234567890123456789012345678901234567890123456789012345678901234
SPI1=0x12345678
SPI2=0x87654321
SRC=10.0.161.101
DST=10.0.186.131
LOCAL=172.16.0.1
REMOTE=172.16.0.2

if ip addr list dev eth0 | grep -q $DST; then
    xDST=$SRC
    SRC=$DST
    DST=$xDST
    xLOCAL=$REMOTE
    REMOTE=$LOCAL
    LOCAL=$xLOCAL
    xSPI1=$SPI2
    SPI2=$SPI1
    SPI1=$xSPI1
fi

echo $SPI1 $SPI2
ip xfrm state del src $SRC dst $DST proto esp spi $SPI1
ip xfrm state del src $DST dst $SRC proto esp spi $SPI2

ip xfrm state add src $SRC dst $DST proto esp spi $SPI1 reqid $SPI1 mode tunnel auth sha1 $KEY enc aes $KEY encap espinudp 8443 8443 $SRC
ip xfrm state add src $DST dst $SRC proto esp spi $SPI2 reqid $SPI2 mode tunnel auth sha1 $KEY enc aes $KEY encap espinudp 8443 8443 $SRC
ip xfrm policy add src $LOCAL dst $REMOTE dir out tmpl src $SRC dst $DST proto esp reqid $SPI1 mode tunnel
ip xfrm policy add src $REMOTE dst $LOCAL dir in tmpl src $DST dst $SRC proto esp reqid $SPI2 mode tunnel
ip addr add $LOCAL dev lo
ip route add $REMOTE dev eth0 src $LOCAL
EOF


And if you want the kernel to actually receive and process the UDP frames, you have to run something that binds the socket...
(http://techblog.newsnow.co.uk/2011/11/simple-udp-esp-encapsulation-nat-t-for.html)

cat > esplisten.pl <<EOF
#!/usr/bin/perl -w
 
use strict;
 
use Socket qw( IPPROTO_IP IPPROTO_UDP AF_INET SOCK_DGRAM SOL_SOCKET SO_REUSEADDR INADDR_ANY sockaddr_in );
 
my $UDP_ENCAP = 100;
 
# UDP encapsulation types
my $UDP_ENCAP_ESPINUDP_NON_IKE = 1; # /* draft-ietf-ipsec-nat-t-ike-00/01 */
my $UDP_ENCAP_ESPINUDP = 2; # /* draft-ietf-ipsec-udp-encaps-06 */
my $UDP_ENCAP_L2TPINUDP = 3; # /* rfc2661 */
 
my $Sock;
 
socket( $Sock, AF_INET, SOCK_DGRAM, IPPROTO_UDP ) || die "::socket: $!";
setsockopt( $Sock, SOL_SOCKET, SO_REUSEADDR, pack( "l", 1 ) );
 
# struct sadb_x_policy {
# uint16_t sadb_x_policy_len;
# uint16_t sadb_x_policy_exttype;
# uint16_t sadb_x_policy_type;
# uint8_t sadb_x_policy_dir;
# uint8_t sadb_x_policy_reserved;
# uint32_t sadb_x_policy_id;
# uint32_t sadb_x_policy_priority;
# } __attribute__((packed));
# /* sizeof(struct sadb_x_policy) == 16 */
 
my $SADB_X_EXT_POLICY = 18;
my $IP_IPSEC_POLICY = 16;
my $IPSEC_POLICY_BYPASS = 4;
my $IPSEC_DIR_INBOUND = 1;
my $IPSEC_DIR_OUTBOUND = 2;
 
# policy.sadb_x_policy_len = sizeof(policy) / sizeof(u_int64_t);
# policy.sadb_x_policy_exttype = SADB_X_EXT_POLICY;
# policy.sadb_x_policy_type = IPSEC_POLICY_BYPASS;
# policy.sadb_x_policy_dir = IPSEC_DIR_OUTBOUND;
 
my $policy1 = pack("SSSCCLL", 2, $SADB_X_EXT_POLICY, $IPSEC_POLICY_BYPASS, $IPSEC_DIR_OUTBOUND, 0, 0, 0);
my $policy2 = pack("SSSCCLL", 2, $SADB_X_EXT_POLICY, $IPSEC_POLICY_BYPASS, $IPSEC_DIR_INBOUND, 0, 0, 0);
 
# See http://strongswan.sourcearchive.com/documentation/4.1.4/socket_8c-source.html
if( defined setsockopt( $Sock, IPPROTO_IP, $IP_IPSEC_POLICY, $policy1 ) ) {
   print "setsockopt:: policy OK\n"; }
else { print "setsockopt:: policy FAIL\n"; }
 
if( defined setsockopt( $Sock, IPPROTO_IP, $IP_IPSEC_POLICY, $policy2 ) ) {
   print "setsockopt:: policy OK\n"; }
else { print "setsockopt:: policy FAIL\n"; }
 
if( defined setsockopt( $Sock, IPPROTO_UDP, $UDP_ENCAP, $UDP_ENCAP_ESPINUDP) ) {
   print "setsockopt:: UDP_ENCAP OK\n"; }
else { print "setsockopt:: UDP_ENCAP FAIL\n"; }
 
bind( $Sock, sockaddr_in( 8443, INADDR_ANY ) ) || die "::bind: $!";
 
sleep;
 
1;
EOF

Ok, how does that perform?

$ sudo perf record -a ./netperf -H 172.16.0.1 -t UDP_STREAM -- -m 1400 
MIGRATED UDP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 172.16.0.1 () port 0 AF_INET
Socket  Message  Elapsed      Messages                
Size    Size     Time         Okay Errors   Throughput
bytes   bytes    secs            #      #   10^6bits/sec

212992    1400   10.00     1198093      0    1341.86
212992           10.00     1198044           1341.80

At this point netperf is taking 100% of CPU, doing this:

Samples: 49K of event 'cycles', Event count (approx.): 32648308583
Overhead  Command          Shared Object        Symbol
  31.59%  netperf          [kernel.vmlinux]     [k] sha_transform
  17.49%  netperf          [kernel.vmlinux]     [k] _aesni_enc1
   2.88%  netperf          [kernel.vmlinux]     [k] _raw_spin_lock
   2.22%  netperf          [ena]                [k] ena_start_xmit
   1.26%  netperf          [kernel.vmlinux]     [k] aesni_cbc_enc
   1.24%  swapper          [kernel.vmlinux]     [k] intel_idle
   1.23%  netperf          [ena]                [k] ena_com_prepare_tx
   1.13%  netperf          [kernel.vmlinux]     [k] fib_table_lookup
   1.02%  netperf          [kernel.vmlinux]     [k] entry_SYSCALL_64
   0.99%  netperf          [kernel.vmlinux]     [k] csum_partial_copy_generic



Next step... tricking OpenConnect on one end into talking to the kernel ESP on the other.

With openssl s_server and a handful of canned responses, let's see how far I can get...

HTTP/1.1 200 OK
Content-Length: 207

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<response>
  <ip-address>172.16.0.1</ip-address>
  <netmask>255.255.255.0</netmask>
  <mtu>1200</mtu>
  <gw-address>172.16.0.2</gw-address>
</response>

HTTP/1.1 200 OK
Content-Length: 122

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<response>
  <hip-report-needed>no</hip-report-needed>
</response>
START_TUNNEL

I think I just need to add the ESP config into that initial config
response, then hack openconnect to bind to local UDP port 8443...

Attachment: smime.p7s
Description: S/MIME cryptographic signature

_______________________________________________
openconnect-devel mailing list
openconnect-devel@xxxxxxxxxxxxxxxxxxx
http://lists.infradead.org/mailman/listinfo/openconnect-devel

[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux