==Standalone project for netconfd module implementing ietf-traffic-generator.yang==
Dependency: installed netconfd run-time binaries and development shared libraries and headers.

===Build and install===
 autoreconf -i -f
 ./configure CFLAGS="-g -O0"  CXXFLAGS="-g -O0" --prefix=/usr
 make
 sudo make install

 sudo /usr/sbin/netconfd --module=ietf-interfaces --module=ietf-traffic-generator --module=ietf-traffic-analyzer --module=traffic-generator-testframe --no-startup --log-level=debug4 --superuser=root

===Functionality===
 yangcli root@localhost> create /interfaces/interface[name='eth0'] -- type=ethernetCsmacd
 yangcli root@localhost> create /interfaces/interface[name='eth0']/traffic-generator -- frame-size=64 interframe-gap=67000000  testframe-type=dynamic frame-data=\
 6CA96F0000026CA96F00000108004500\
 002ED4A500000A115816C0000201C000\
 0202C0200007001A0000010203040506\
 0708090A0B0C0D0E0F101112

 yangcli root@localhost> create /interfaces/interface[name='eth1'] -- type=ethernetCsmacd
 yangcli root@localhost> create /interfaces/interface[name='eth1']/traffic-analyzer

 yangcli root@localhost> commit

yangcli root@192.168.0.17> xget /interfaces

RPC Data Reply 51 for session 1:

rpc-reply {
  data {
    interfaces {
      interface eth0 {
        name eth0
        type ianaift:ethernetCsmacd
        traffic-generator {
          frame-size 64
          frame-data 6CA96F0000026CA96F00000108004500002ED4A500000A115816C0000201C0000202C0200007001A00000102030405060708090A0B0C0D0E0F101112
          interframe-gap 67000000
          testframe-type dynamic
        }
      }
      interface eth1 {
        name eth1
        type ianaift:ethernetCsmacd
        traffic-analyzer {
          state {
            pkts 15687
            testframe-stats {
              testframe-pkts 15223
              latency {
                min 54190
                max 2084628
                latest 218892
              }
            }
          }
        }
      }
    }
  }
}

=== realtime-epoch ===
Generation can be synchronized in realtime using the realtime-epoch leaf.
The configured epoch should be in future. Restarting traffic generation on two interfaces with 1s phase difference.
Assuming time is 2020-09-29T13:43:59.000000000Z or earlier when you commit.

 yangcli root@localhost> merge /interfaces/interface[name='eth1']/traffic-generator -- realtime-epoch="2020-09-29T13:44:00.000000000Z"
 yangcli root@localhost> merge /interfaces/interface[name='eth0']/traffic-generator -- realtime-epoch="2020-09-29T13:44:01.000000000Z"
 yangcli root@localhost> commit

==Design notes==
The libtraffic_generator library creates traffic generator instance context
from the ietf-traffic-generator data upon initialization. Then
each call fills frame buffer and returns it timestamp and length until after
the last frame is generated. Then zero length is returned.

The traffic-generator tool is started for each interface with configured
/interfaces/interface/traffic-generator container.

There is a --stdout-mode option that can be used for a dry run.

Usage:

  $ ./traffic-generator --stdout-mode --interface=eth0 --frame-size=64 --interframe-gap=20 --interburst-gap=124999852 \
   --frames-per-burst=2 --total-frames=4 --realtime-epoch="1970-01-01T00:00:00.000000000Z" --interface-speed=1000000000
   --frame-data="123456789ABCDEF01234567808004500002E000000000A112CBCC0000201C0000202C0200007001A0000000102030405060708090A0B0C0D0E0F10119CD50E0F"
        0 000000000000000:000000000   64 123456789ABCDEF01234567808004500002E000000000A112CBCC0000201C0000202C0200007001A0000000102030405060708090A0B0C0D0E0F10119CD50E0F
        1 000000000000000:000000672   64 123456789ABCDEF01234567808004500002E000000000A112CBCC0000201C0000202C0200007001A0000000102030405060708090A0B0C0D0E0F10119CD50E0F
        2 000000000000001:000000000   64 123456789ABCDEF01234567808004500002E000000000A112CBCC0000201C0000202C0200007001A0000000102030405060708090A0B0C0D0E0F10119CD50E0F
        3 000000000000001:000000672   64 123456789ABCDEF01234567808004500002E000000000A112CBCC0000201C0000202C0200007001A0000000102030405060708090A0B0C0D0E0F10119CD50E0F

==Dynamic testframe - stamped with sequence number and time==
Adding the --testframe-type=dynamc according to the model testframes are dynamically stamped with sequence number (8 octets) and IEEE 1588 timestamp (10 octets).
These dynamic fields are added at the back of the payload within the specified --frame-size argument:
        ...
        0 000000000000000:000000000   64 123456789ABCDEF01234567808004500002E000000000A112CBCC0000201C0000202C0200007001A00000000000000000000000000000000000000005465E0B4
        1 000000000000000:000000672   64 123456789ABCDEF01234567808004500002E000000000A112CBCC0000201C0000202C0200007001A00000000000000000001000000000000000002A0FE7B8E91
        2 000000000000001:000000000   64 123456789ABCDEF01234567808004500002E000000000A112CBCC0000201C0000202C0200007001A000000000000000000020000000000010000000025F5ECD1
        3 000000000000001:000000672   64 123456789ABCDEF01234567808004500002E000000000A112CBCC0000201C0000202C0200007001A00000000000000000003000000000001000002A08FEB82F4

===Testframe generation===
While you could use any ethernet frame specified with the --frame-data parameter there is a tool that generates RFC2544 sec C.2.6.4 testframe.

Usage:

  $ ./traffic-generator-make-testframe --frame-size=64 --dst-mac-address="12:34:56:78:9A:BC" --src-mac-address="DE:F0:12:34:56:78" --src-ipv4-address="192.0.2.1" --ipv4-ttl=10 --src-ipv4-udp-port=49184 --dst-ipv4-address="192.0.2.2" --dst-ipv4-udp-port=7
 123456789ABCDEF01234567808004500002E000000000A112CBCC0000201C0000202C0200007001A0000000102030405060708090A0B0C0D0E0F10119CD50E0F
