summaryrefslogtreecommitdiff
path: root/Documentation/intro/install/windows.rst
blob: 0a392d781a522a856abdc835cf667fbc737c394e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
..
      Licensed under the Apache License, Version 2.0 (the "License"); you may
      not use this file except in compliance with the License. You may obtain
      a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
      WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
      License for the specific language governing permissions and limitations
      under the License.

      Convention for heading levels in Open vSwitch documentation:

      =======  Heading 0 (reserved for the title in a document)
      -------  Heading 1
      ~~~~~~~  Heading 2
      +++++++  Heading 3
      '''''''  Heading 4

      Avoid deeper levels because they do not render well.

=======================
Open vSwitch on Windows
=======================

.. _windows-build-reqs:

Build Requirements
------------------

Open vSwitch on Linux uses autoconf and automake for generating Makefiles.  It
will be useful to maintain the same build system while compiling on Windows
too.  One approach is to compile Open vSwitch in a MinGW environment that
contains autoconf and automake utilities and then use Visual C++ as a compiler
and linker.

The following explains the steps in some detail.

- Mingw

  Install Mingw on a Windows machine by following the instructions on
  `mingw.org <http://www.mingw.org/wiki/Getting_Started>`__.

  This should install mingw at ``C:\Mingw`` and msys at ``C:\Mingw\msys``.  Add
  ``C:\MinGW\bin`` and ``C:\Mingw\msys\1.0\bin`` to PATH environment variable
  of Windows.

  You can either use the MinGW installer or the command line utility
  ``mingw-get`` to install both the base packages and additional packages like
  automake and autoconf(version 2.68).

  Also make sure that ``/mingw`` mount point exists. If its not, please
  add/create the following entry in ``/etc/fstab``::

      'C:/MinGW /mingw'.

- Python 3.4 or later.

  Install the latest Python 3.x from python.org and verify that its path is
  part of Windows' PATH environment variable.
  We require that you have pypiwin32 library installed.
  The library can be installed via pip command:

   ::

      $ pip install pypiwin32

- Visual Studio

  You will need at least Visual Studio 2013 (update 4) to compile userspace
  binaries.  In addition to that, if you want to compile the kernel module you
  will also need to install Windows Driver Kit (WDK) 8.1 Update or later.
  To generate the Windows installer you need
  `WiX Toolset <https://wixtoolset.org/>`__ and also be able to build the
  kernel module.

  We recommend using the latest Visual Studio version together with the latest
  WDK installed.

  It is important to get the Visual Studio related environment variables and to
  have the $PATH inside the bash to point to the proper compiler and linker.
  One easy way to achieve this for VS2013 is to get into the "VS2013 x86 Native
  Tools Command Prompt" (in a default installation of Visual Studio 2013 this
  can be found under the following location: ``C:\Program Files (x86)\Microsoft
  Visual Studio 12.0\Common7\Tools\Shortcuts``) and through it enter into the
  bash shell available from msys by typing ``bash --login``.

  There is support for generating 64 bit binaries too.  To compile under x64,
  open the "VS2013 x64 Native Tools Command Prompt" (if your current running OS
  is 64 bit) or "VS2013 x64 Cross Tools Command Prompt" (if your current
  running OS is not 64 bit) instead of opening its x86 variant.  This will
  point the compiler and the linker to their 64 bit equivalent.

  If after the above step, a ``which link`` inside MSYS's bash says,
  ``/bin/link.exe``, rename ``/bin/link.exe`` to something else so that the
  Visual studio's linker is used. You should also see a 'which sort' report
  ``/bin/sort.exe``.

- PThreads4W

  For pthread support, install the library, dll and includes of PThreads4W
  project from `sourceware
  <https://sourceforge.net/projects/pthreads4w/>`__ to a directory
  (e.g.: ``C:/pthread``). You should add the PThreads4W's dll path
  (e.g.: ``C:\pthread\bin``) to the Windows' PATH environment variable.

- OpenSSL

  To get SSL support for Open vSwitch on Windows, you will need to install
  `OpenSSL for Windows <https://wiki.openssl.org/index.php/Binaries>`__

  Note down the directory where OpenSSL is installed (e.g.:
  ``C:/OpenSSL-Win32``) for later use.

.. note::

   Commands prefixed by ``$`` must be run in the Bash shell provided by MinGW.
   Open vSwitch commands, such as ``ovs-dpctl`` are shown running under the DOS
   shell (``cmd.exe``), as indicated by the ``>`` prefix, but will also run
   under Bash. The remainder, prefixed by ``>``, are PowerShell commands and
   must be run in PowerShell.

Install Requirements
--------------------

* Share network adaptors

  We require that you don't disable the "Allow management operating system to
  share this network adapter" under 'Virtual Switch Properties' > 'Connection
  type: External network', in the Hyper-V virtual network switch configuration.

* Checksum Offloads

  While there is some support for checksum/segmentation offloads in software,
  this is still a work in progress. Till the support is complete we recommend
  disabling TX/RX offloads for both the VM's as well as the Hyper-V.

Bootstrapping
-------------

This step is not needed if you have downloaded a released tarball. If
you pulled the sources directly from an Open vSwitch Git tree or got a
Git tree snapshot, then run boot.sh in the top source directory to build
the "configure" script:

::

   $ ./boot.sh

.. _windows-configuring:

Configuring
-----------

Configure the package by running the configure script.  You should provide some
configure options to choose the right compiler, linker, libraries, Open vSwitch
component installation directories, etc. For example:

::

   $ ./configure CC=./build-aux/cccl LD="$(which link)" \
       LIBS="-lws2_32 -lShlwapi -liphlpapi -lwbemuuid -lole32 -loleaut32" \
       --prefix="C:/openvswitch/usr" \
       --localstatedir="C:/openvswitch/var" \
       --sysconfdir="C:/openvswitch/etc" \
       --with-pthread="C:/pthread"

.. note::

   By default, the above enables compiler optimization for fast code.  For
   default compiler optimization, pass the ``--with-debug`` configure option.

To configure with SSL support, add the requisite additional options:

::

   $ ./configure CC=./build-aux/cccl LD="`which link`"  \
       LIBS="-lws2_32 -lShlwapi -liphlpapi -lwbemuuid -lole32 -loleaut32" \
       --prefix="C:/openvswitch/usr" \
       --localstatedir="C:/openvswitch/var"
       --sysconfdir="C:/openvswitch/etc" \
       --with-pthread="C:/pthread" \
       --enable-ssl --with-openssl="C:/OpenSSL-Win32"

Finally, to the kernel module also:

::

   $ ./configure CC=./build-aux/cccl LD="`which link`" \
       LIBS="-lws2_32 -lShlwapi -liphlpapi -lwbemuuid -lole32 -loleaut32" \
       --prefix="C:/openvswitch/usr" \
       --localstatedir="C:/openvswitch/var" \
       --sysconfdir="C:/openvswitch/etc" \
       --with-pthread="C:/pthread" \
       --enable-ssl --with-openssl="C:/OpenSSL-Win32" \
       --with-vstudiotarget="<target type>" \
       --with-vstudiotargetver="<target versions>"

Possible values for ``<target type>`` are: ``Debug`` and ``Release``
Possible values for ``<target versions>`` is a comma separated list
of target versions to compile among: ``Win8,Win8.1,Win10``

.. note::

   You can directly use the Visual Studio 2013 IDE to compile the kernel
   datapath. Open the ovsext.sln file in the IDE and build the solution.

Refer to :doc:`general` for information on additional configuration options.

.. _windows-building:

Building
--------

Once correctly configured, building Open vSwitch on Windows is similar to
building on Linux, FreeBSD, or NetBSD.

#. Run make for the ported executables in the top source directory, e.g.:

   ::

      $ make

   For faster compilation, you can pass the ``-j`` argument to make.  For
   example, to run 4 jobs simultaneously, run ``make -j4``.

   .. note::

      MSYS 1.0.18 has a bug that causes parallel make to hang. You can overcome
      this by downgrading to MSYS 1.0.17.  A simple way to downgrade is to exit
      all MinGW sessions and then run the below command from MSVC developers
      command prompt.:

      ::

         > mingw-get upgrade msys-core-bin=1.0.17-1

#. To run all the unit tests in Open vSwitch, one at a time:

   ::

      $ make check

   To run all the unit tests in Open vSwitch, up to 8 in parallel:

   ::

      $ make check TESTSUITEFLAGS="-j8"

#. To install all the compiled executables on the local machine, run:

   ::

      $ make install

  .. note::

     This will install the Open vSwitch executables in ``C:/openvswitch``.  You
     can add ``C:\openvswitch\usr\bin`` and ``C:\openvswitch\usr\sbin`` to
     Windows' PATH environment variable for easy access.

The Kernel Module
~~~~~~~~~~~~~~~~~

If you are building the kernel module, you will need to copy the below files to
the target Hyper-V machine.

- ``./datapath-windows/x64/Win8.1Debug/package/ovsext.inf``
- ``./datapath-windows/x64/Win8.1Debug/package/OVSExt.sys``
- ``./datapath-windows/x64/Win8.1Debug/package/ovsext.cat``
- ``./datapath-windows/misc/install.cmd``
- ``./datapath-windows/misc/uninstall.cmd``

.. note::

   The above path assumes that the kernel module has been built using Windows
   DDK 8.1 in Debug mode. Change the path appropriately, if a different WDK has
   been used.

Now run ``./uninstall.cmd`` to remove the old extension. Once complete, run
``./install.cmd`` to insert the new one.  For this to work you will have to
turn on ``TESTSIGNING`` boot option or 'Disable Driver Signature
Enforcement' during boot.  The following commands can be used:

::

   > bcdedit /set LOADOPTIONS DISABLE_INTEGRITY_CHECKS
   > bcdedit /set TESTSIGNING ON
   > bcdedit /set nointegritychecks ON

.. note::

  You may have to restart the machine for the settings to take effect.

In the Virtual Switch Manager configuration you can enable the Open vSwitch
Extension on an existing switch or create a new switch.  If you are using an
existing switch, make sure to enable the "Allow Management OS" option for VXLAN
to work (covered later).

The command to create a new switch named 'OVS-Extended-Switch' using a physical
NIC named 'Ethernet 1' is:

::

   PS > New-VMSwitch "OVS-Extended-Switch" -NetAdapterName "Ethernet 1"

.. note::

   You can obtain the list of physical NICs on the host using 'Get-NetAdapter'
   command.

In the properties of any switch, you should now see "Open vSwitch Extension"
under 'Extensions'.  Click the check box to enable the extension.
An alternative way to do the same is to run the following command:

::

   PS > Enable-VMSwitchExtension "Open vSwitch Extension" OVS-Extended-Switch

.. note::

   If you enabled the extension using the command line, a delay of a few
   seconds has been observed for the change to be reflected in the UI.  This is
   not a bug in Open vSwitch.

Generate the Windows installer
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

To generate the Windows installler run the following command from the top
source directory:

::

   $ make windows_installer

.. note::

   This will generate the Windows installer in the following location (relative
   to the top source directory):
   windows/ovs-windows-installer/bin/Release/OpenvSwitch.msi

Starting
--------

.. important::

   The following steps assume that you have installed the Open vSwitch
   utilities in the local machine via 'make install'.

Before starting ovs-vswitchd itself, you need to start its configuration
database, ovsdb-server. Each machine on which Open vSwitch is installed should
run its own copy of ovsdb-server. Before ovsdb-server itself can be started,
configure a database that it can use:

::

   > ovsdb-tool create C:\openvswitch\etc\openvswitch\conf.db \
       C:\openvswitch\usr\share\openvswitch\vswitch.ovsschema

Configure ovsdb-server to use database created above and to listen on a Unix
domain socket:

::

   > ovsdb-server -vfile:info --remote=punix:db.sock --log-file \
       --pidfile --detach

.. note::

   The logfile is created at ``C:/openvswitch/var/log/openvswitch/``

Initialize the database using ovs-vsctl. This is only necessary the first time
after you create the database with ovsdb-tool, though running it at any time is
harmless:

::

   > ovs-vsctl --no-wait init

.. tip::

   If you would later like to terminate the started ovsdb-server, run:

   ::

      > ovs-appctl -t ovsdb-server exit

Start the main Open vSwitch daemon, telling it to connect to the same Unix
domain socket:

::

   > ovs-vswitchd -vfile:info --log-file --pidfile --detach

.. tip::

   If you would like to terminate the started ovs-vswitchd, run:

   ::

      > ovs-appctl exit

.. note::

   The logfile is created at ``C:/openvswitch/var/log/openvswitch/``

Validating
----------

At this point you can use ovs-vsctl to set up bridges and other Open vSwitch
features.

Add bridges
~~~~~~~~~~~

Let's start by creating an integration bridge, ``br-int`` and a PIF bridge,
``br-pif``:

::

   > ovs-vsctl add-br br-int
   > ovs-vsctl add-br br-pif

.. note::

   There's a known bug that running the ovs-vsctl command does not terminate.
   This is generally solved by having ovs-vswitchd running.  If you face the
   issue despite that, hit Ctrl-C to terminate ovs-vsctl and check the output
   to see if your command succeeded.

Validate that ports are added by dumping from both ovs-dpctl and ovs-vsctl:

::

   > ovs-dpctl show
   system@ovs-system:
           lookups: hit:0 missed:0 lost:0
           flows: 0
           port 2: br-pif (internal)     <<< internal port on 'br-pif' bridge
           port 1: br-int (internal)     <<< internal port on 'br-int' bridge

   > ovs-vsctl show
   a56ec7b5-5b1f-49ec-a795-79f6eb63228b
       Bridge br-pif
           Port br-pif
               Interface br-pif
                   type: internal
       Bridge br-int
           Port br-int
               Interface br-int
                   type: internal

.. note::

   There's a known bug that the ports added to OVSDB via ovs-vsctl don't get to
   the kernel datapath immediately, ie. they don't show up in the output of
   ``ovs-dpctl show`` even though they show up in output of ``ovs-vsctl show``.
   In order to workaround this issue, restart ovs-vswitchd. (You can terminate
   ovs-vswitchd by running ``ovs-appctl exit``.)

Add physicals NICs (PIF)
~~~~~~~~~~~~~~~~~~~~~~~~

Now, let's add the physical NIC and the internal port to ``br-pif``. In OVS for
Hyper-V, we use the name of the adapter on top of which the Hyper-V virtual
switch was created, as a special name to refer to the physical NICs connected
to the Hyper-V switch, e.g. if we created the Hyper-V virtual switch on top of
the adapter named ``Ethernet0``, then in OVS we use that name (``Ethernet0``)
as a special name to refer to that adapter.

.. note::

   We assume that the OVS extension is enabled Hyper-V switch.

Internal ports are the virtual adapters created on the Hyper-V switch using the
``ovs-vsctl add-br <bridge>`` command. By default they are created under the
following rule "<name of bridge>" and the adapters are disabled. One needs to
enable them and set the corresponding values to it to make them IP-able.

As a whole example, if we issue the following in a powershell console:

::

    PS > Get-NetAdapter | select Name,InterfaceDescription
    Name                   InterfaceDescription
    ----                   --------------------
    Ethernet1              Intel(R) PRO/1000 MT Network Connection
    br-pif                 Hyper-V Virtual Ethernet Adapter #2
    Ethernet0              Intel(R) PRO/1000 MT Network Connection #2
    br-int                 Hyper-V Virtual Ethernet Adapter #3

    PS > Get-VMSwitch
    Name     SwitchType NetAdapterInterfaceDescription
    ----     ---------- ------------------------------
    external External   Intel(R) PRO/1000 MT Network Connection #2

We can see that we have a switch(external) created upon adapter name
'Ethernet0' with the internal ports under name 'br-pif' and 'br-int'. Thus
resulting into the following ovs-vsctl commands:

::

   > ovs-vsctl add-port br-pif Ethernet0

Dumping the ports should show the additional ports that were just added:

::

   > ovs-dpctl show
   system@ovs-system:
           lookups: hit:0 missed:0 lost:0
           flows: 0
           port 2: br-pif (internal)               <<< internal port
                                                       adapter on
                                                       Hyper-V switch
           port 1: br-int (internal)               <<< internal port
                                                       adapter on
                                                       Hyper-V switch
           port 3: Ethernet0                       <<< Physical NIC

   > ovs-vsctl show
   a56ec7b5-5b1f-49ec-a795-79f6eb63228b
       Bridge br-pif
           Port br-pif
               Interface br-pif
                   type: internal
           Port "Ethernet0"
               Interface "Ethernet0"
       Bridge br-int
           Port br-int
               Interface br-int
                   type: internal

Add virtual interfaces (VIFs)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Adding VIFs to Open vSwitch is a two step procedure.  The first step is to
assign a 'OVS port name' which is a unique name across all VIFs on this
Hyper-V.  The next step is to add the VIF to the ovsdb using its 'OVS port
name' as key.

First, assign a unique 'OVS port name' to the VIF. The VIF needs to have been
disconnected from the Hyper-V switch before assigning a 'OVS port name' to it.
In the example below, we assign a 'OVS port name' called ``ovs-port-a`` to a
VIF on a VM ``VM1``.  By using index 0 for ``$vnic``, the first VIF of the VM
is being addressed.  After assigning the name ``ovs-port-a``, the VIF is
connected back to the Hyper-V switch with name ``OVS-HV-Switch``, which is
assumed to be the Hyper-V switch with OVS extension enabled.:

::

   PS > import-module .\datapath-windows\misc\OVS.psm1
   PS > $vnic = Get-VMNetworkAdapter <Name of the VM>
   PS > Disconnect-VMNetworkAdapter -VMNetworkAdapter $vnic[0]
   PS > $vnic[0] | Set-VMNetworkAdapterOVSPort -OVSPortName ovs-port-a
   PS > Connect-VMNetworkAdapter -VMNetworkAdapter $vnic[0] \
         -SwitchName OVS-Extended-Switch

Next, add the VIFs to ``br-int``:

::

   > ovs-vsctl add-port br-int ovs-port-a

Dumping the ports should show the additional ports that were just added:

::

   > ovs-dpctl show
   system@ovs-system:
           lookups: hit:0 missed:0 lost:0
           flows: 0
           port 4: ovs-port-a
           port 2: br-pif (internal)
           port 1: br-int (internal
           port 3: Ethernet0

   > ovs-vsctl show
   4cd86499-74df-48bd-a64d-8d115b12a9f2
       Bridge br-pif
           Port "vEthernet (external)"
               Interface "vEthernet (external)"
           Port "Ethernet0"
               Interface "Ethernet0"
           Port br-pif
               Interface br-pif
                   type: internal
       Bridge br-int
           Port br-int
               Interface br-int
                   type: internal
           Port "ovs-port-a"
               Interface "ovs-port-a"

Add multiple NICs to be managed by OVS
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

To leverage support of multiple NICs into OVS, we will be using the MSFT
cmdlets for forwarding team extension. More documentation about them can be
found at technet_.

.. _technet: https://technet.microsoft.com/en-us/library/jj553812%28v=wps.630%29.aspx

For example, to set up a switch team combined from ``Ethernet0 2`` and
``Ethernet1 2`` named ``external``:

::

   PS > Get-NetAdapter
   Name                      InterfaceDescription
   ----                      --------------------
   br-int                    Hyper-V Virtual Ethernet Adapter #3
   br-pif                    Hyper-V Virtual Ethernet Adapter #2
   Ethernet3 2               Intel(R) 82574L Gigabit Network Co...#3
   Ethernet2 2               Intel(R) 82574L Gigabit Network Co...#4
   Ethernet1 2               Intel(R) 82574L Gigabit Network Co...#2
   Ethernet0 2               Intel(R) 82574L Gigabit Network Conn...

   PS > New-NetSwitchTeam -Name external -TeamMembers "Ethernet0 2","Ethernet1 2"

   PS > Get-NetSwitchTeam
   Name    : external
   Members : {Ethernet1 2, Ethernet0 2}

This will result in a new adapter bound to the host called ``external``:

::

   PS > Get-NetAdapter
   Name                      InterfaceDescription
   ----                      --------------------
   br-test                   Hyper-V Virtual Ethernet Adapter #4
   br-pif                    Hyper-V Virtual Ethernet Adapter #2
   external                  Microsoft Network Adapter Multiplexo...
   Ethernet3 2               Intel(R) 82574L Gigabit Network Co...#3
   Ethernet2 2               Intel(R) 82574L Gigabit Network Co...#4
   Ethernet1 2               Intel(R) 82574L Gigabit Network Co...#2
   Ethernet0 2               Intel(R) 82574L Gigabit Network Conn...

Next we will set up the Hyper-V VMSwitch on the new adapter ``external``:

::

   PS > New-VMSwitch -Name external -NetAdapterName external \
        -AllowManagementOS $false

Under OVS the adapters under the team ``external``, ``Ethernet0 2`` and
``Ethernet1 2``, can be added either under a bond device or separately.

The following example shows how the bridges look with the NICs being
separated:

::

   > ovs-vsctl show
   6cd9481b-c249-4ee3-8692-97b399dd29d8
       Bridge br-test
           Port br-test
               Interface br-test
                   type: internal
           Port "Ethernet1 2"
               Interface "Ethernet1 2"
       Bridge br-pif
           Port "Ethernet0 2"
               Interface "Ethernet0 2"
           Port br-pif
               Interface br-pif
                   type: internal

Add patch ports and configure VLAN tagging
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The Windows Open vSwitch implementation support VLAN tagging in the switch.
Switch VLAN tagging along with patch ports between ``br-int`` and ``br-pif`` is
used to configure VLAN tagging functionality between two VMs on different
Hyper-Vs.  To start, add a patch port from ``br-int`` to ``br-pif``:

::

   > ovs-vsctl add-port br-int patch-to-pif
   > ovs-vsctl set interface patch-to-pif type=patch \
       options:peer=patch-to-int

Add a patch port from ``br-pif`` to ``br-int``:

::

   > ovs-vsctl add-port br-pif patch-to-int
   > ovs-vsctl set interface patch-to-int type=patch \
       options:peer=patch-to-pif

Re-Add the VIF ports with the VLAN tag:

::

   > ovs-vsctl add-port br-int ovs-port-a tag=900
   > ovs-vsctl add-port br-int ovs-port-b tag=900

Add tunnels
~~~~~~~~~~~

#. IPv4 tunnel, e.g.:

   The Windows Open vSwitch implementation support VXLAN and STT tunnels.
   To add tunnels. For example, first add the tunnel port between
   172.168.201.101 <->172.168.201.102:

   ::

      > ovs-vsctl add-port br-int tun-1
      > ovs-vsctl set Interface tun-1 type=<port-type>
      > ovs-vsctl set Interface tun-1 options:local_ip=172.168.201.101
      > ovs-vsctl set Interface tun-1 options:remote_ip=172.168.201.102
      > ovs-vsctl set Interface tun-1 options:in_key=flow
      > ovs-vsctl set Interface tun-1 options:out_key=flow

    ...and the tunnel port between 172.168.201.101 <-> 172.168.201.105:

   ::

      > ovs-vsctl add-port br-int tun-2
      > ovs-vsctl set Interface tun-2 type=<port-type>
      > ovs-vsctl set Interface tun-2 options:local_ip=172.168.201.102
      > ovs-vsctl set Interface tun-2 options:remote_ip=172.168.201.105
      > ovs-vsctl set Interface tun-2 options:in_key=flow
      > ovs-vsctl set Interface tun-2 options:out_key=flow

      Where ``<port-type>`` is one of: ``stt`` or ``vxlan``

   .. note::

       Any patch ports created between br-int and br-pif MUST be deleted prior
       to adding tunnels.

#. IPv6 tunnel, e.g.:

   To add IPV6 Geneve tunnels. For example, add the tunnel port between
   5000::2 <-> 5000::9.

   ::

      > ovs-vsctl add-port br-int tun-3 -- set interface tun-3 type=Geneve \
        options:csum=true options:key=flow options:local_ip="5000::2"\
        options:remote_ip=flow

     add the tunnel port between 5000::2 <-> 5000::9

      > ovs-ofctl add-flow br-int "table=0,priority=100,ipv6,ipv6_src=6000::2 \
        actions=load:0x9->NXM_NX_TUN_IPV6_DST[0..63], \
        load:0x5000000000000000->NXM_NX_TUN_IPV6_DST[64..127], output:tun-3"

     add the specified flow from 6000::2 go via IPV6 Geneve tunnel

   .. note::

      Till the checksum offload support is complete we recommend
      disabling TX/RX offloads for IPV6 on Windows VM.

Add conntrack for ipv6
~~~~~~~~~~~~~~~~~~~~~~

The Windows Open vSwitch implementation support conntrack ipv6. To use the
conntrack ipv6. Using the following commands. Take tcp6(replace Protocol to
icmp6, udp6 to other protocol) for example.

::

   normal scenario
   Vif38(20::1, ofport:2)->Vif40(20:2, ofport:3)
   Vif38Name="podvif38"
   Vif40Name="podvif40"
   Vif38Port=2
   Vif38Address="20::1"
   Vif40Port=3
   Vif40Address="20::2"
   Vif40MacAddressCli="00-15-5D-F0-01-0C"
   Vif38MacAddressCli="00-15-5D-F0-01-0b"
   Protocol="tcp6"
   > netsh int ipv6 set neighbors $Vif38Name $Vif40Address \
     Vif40MacAddressCli
   > netsh int ipv6 set neighbors $Vif40Name $Vif38Address \
     $Vif38MacAddressCli
   > ovs-ofctl del-flows --strict br-int "table=0,priority=0"
   > ovs-ofctl add-flow br-int "table=0,priority=1,ip6, \
     ipv6_dst=$Vif40Address,$Protocol,actions=ct(table=1)"
   > ovs-ofctl add-flow br-int "table=0,priority=1,ip6, \
     ipv6_dst=$Vif38Address,$Protocol,actions=ct(table=1)"
   > ovs-ofctl add-flow br-int "table=1,priority=1,ip6,ct_state=+new+trk, \
     $Protocol,actions=ct(commit,table=2)"
   > ovs-ofctl add-flow br-int "table=1,priority=2,ip6, \
     ct_state=-new+rpl+trk,$Protocol,actions=ct(commit,table=2)"
   > ovs-ofctl add-flow br-int "table=1,priority=1,ip6, \
     ct_state=+trk+est-new,$Protocol,actions=ct(commit,table=2)"
   > ovs-ofctl add-flow br-int "table=2,priority=1,ip6, \
     ipv6_dst=$Vif38Address,$Protocol,actions=output:$Vif38Port"
   > ovs-ofctl add-flow br-int "table=2,priority=1,ip6, \
     ipv6_dst=$Vif40Address,$Protocol,actions=output:$Vif40Port"


::

   nat scenario
   Vif38(20::1, ofport:2) -> nat address(20::9) -> Vif42(21::3, ofport:4)
   Due to not construct flow to return neighbor mac address,
   we set the neighbor mac address manually.
   Vif38Name="podvif38"
   Vif42Name="podvif42"
   Vif38Ip="20::1"
   Vif38Port=2
   Vif42Port=4
   NatAddress="20::9"
   NatMacAddress="aa:bb:cc:dd:ee:ff"
   NatMacAddressForCli="aa-bb-cc-dd-ee-ff"
   Vif42Ip="21::3"
   Vif38MacAddress="00:15:5D:F0:01:0B"
   Vif38MacAddressCli="00-15-5D-F0-01-0B"
   Vif42MacAddress="00:15:5D:F0:01:0D"
   Protocol="tcp6"
   > netsh int ipv6 set neighbors $Vif38Name $NatAddress \
     $NatMacAddressForCli
   > netsh int ipv6 set neighbors $Vif42Name $Vif38Ip \
     $Vif38MacAddressCli
   > ovs-ofctl del-flows --strict br-int "table=0,priority=0"
   > ovs-ofctl add-flow br-int "table=0, priority=2,ipv6, \
     dl_dst=$NatMacAddress,ct_state=-trk,$Protocol \
     actions=ct(table=1,zone=456,nat)"
   > ovs-ofctl add-flow br-int "table=0, priority=1,ipv6,ct_state=-trk, \
     ip6,$Protocol actions=ct(nat, zone=456,table=1)"
   > ovs-ofctl add-flow br-int "table=1, ipv6,in_port=$Vif38Port, \
     ipv6_dst=$NatAddress,$Protocol,ct_state=+trk+new, \
     actions=ct(commit,nat(dst=$Vif42Ip),zone=456, \
     exec(set_field:1->ct_mark)),mod_dl_src=$NatMacAddress, \
     mod_dl_dst=$Vif42MacAddress,output:$Vif42Port"
   > ovs-ofctl add-flow br-int "table=1, ipv6,ct_state=+dnat,$Protocol, \
     action=resubmit(,2)"
   > ovs-ofctl add-flow br-int "table=1, ipv6,ct_state=+trk+snat, \
     $Protocol, action=resubmit(,2)"
   > ovs-ofctl add-flow br-int "table=2, ipv6,in_port=$Vif38Port, \
     ipv6_dst=$Vif42Ip,$Protocol, actions=mod_dl_src=$NatMacAddress, \
     mod_dl_dst=$Vif42MacAddress,output:$Vif42Port"
   > ovs-ofctl add-flow br-int "table=2, ipv6,in_port=$Vif42Port, \
     ct_state=-new+est,ct_mark=1,ct_zone=456,$Protocol, \
     actions=mod_dl_src=$NatMacAddress,mod_dl_dst=$Vif38MacAddress, \
     output:$Vif38Port"

Ftp is a specific protocol, it contains an related flow, we need to match is
related state.

::

   normal scenario
   Vif38(20::1, ofport:2)->Vif40(20:2, ofport:3)
   Vif38Name="podvif38"
   Vif40Name="podvif40"
   Vif38Port=2
   Vif38Address="20::1"
   Vif38MacAddressCli="00-15-5D-F0-01-0b"
   Vif40Port=3
   Vif40Address="20::2"
   Vif40MacAddressCli="00-15-5D-F0-01-0C"
   Protocol="tcp6"
   > netsh int ipv6 set neighbors $Vif38Name $Vif40Address \
     $Vif40MacAddressCli
   > netsh int ipv6 set neighbors $Vif40Name $Vif38Address \
     $Vif38MacAddressCli
   > ovs-ofctl del-flows br-int --strict "table=0,priority=0"
   > ovs-ofctl add-flow br-int "table=0,priority=1,$Protocol \
     actions=ct(table=1)"
   > ovs-ofctl add-flow br-int "table=1,priority=1,ct_state=+new+trk-est, \
     $Protocol,actions=ct(commit,table=2)"
   > ovs-ofctl add-flow br-int "table=1,priority=1, \
     ct_state=-new+trk+est-rel, $Protocol,actions=ct(commit,table=2)"
   > ovs-ofctl add-flow br-int "table=1,priority=1, \
     ct_state=-new+trk+est+rel, $Protocol,actions=ct(commit,table=2)"
   > ovs-ofctl add-flow br-int "table=2,priority=1,ip6, \
     ipv6_dst=$Vif38Address,$Protocol,actions=output:$Vif38Port"
   > ovs-ofctl add-flow br-int "table=2,priority=1,ip6, \
     ipv6_dst=$Vif40Address,$Protocol,actions=output:$Vif40Port"

::

   nat scenario
   Vif38(20::1, ofport:2) -> nat address(20::9) -> Vif42(21::3, ofport:4)
   Due to not construct flow to return neighbor mac address, we set the
   neighbor mac address manually
   Vif38Port=2
   Vif42Port=4
   Vif38Name="podvif38"
   Vif42Name="podvif42"
   NatAddress="20::9"
   NatMacAddress="aa:bb:cc:dd:ee:ff"
   NatMacAddressForCli="aa-bb-cc-dd-ee-ff"
   Vif42Ip="21::3"
   Vif38MacAddress="00:15:5D:F0:01:0B"
   Vif42MacAddress="00:15:5D:F0:01:0D"
   Protocol="tcp6"
   > netsh int ipv6 set neighbors $Vif38Name $NatAddress \
     $NatMacAddressForCli
   > netsh int ipv6 set neighbors $Vif42Name $NatAddress \
     $NatMacAddressForCli
   > ovs-ofctl del-flows br-int --strict "table=0,priority=0"
   > ovs-ofctl add-flow br-int "table=0,priority=2,ipv6, \
     dl_dst=$NatMacAddress,ct_state=-trk,$Protocol \
     actions=ct(table=1,zone=456,nat)"
   > ovs-ofctl add-flow br-int "table=0,priority=1,ipv6, \
     ct_state=-trk,ip6,$Protocol actions=ct(nat, zone=456,table=1)"
   > ovs-ofctl add-flow br-int "table=1,ipv6,in_port=$Vif38Port, \
     ipv6_dst=$NatAddress,ct_state=+trk+new,$Protocol \
     actions=ct(commit,nat(dst=$Vif42Ip),zone=456, \
     exec(set_field:1->ct_mark)),mod_dl_src=$NatMacAddress, \
     mod_dl_dst=$Vif42MacAddress,output:$Vif42Port"
   > ovs-ofctl add-flow br-int "table=1,ipv6,ct_state=+dnat,$Protocol, \
     action=resubmit(,2)"
   > ovs-ofctl add-flow br-int "table=1,ipv6,ct_state=+trk+snat, \
     $Protocol,action=resubmit(,2)"
   > ovs-ofctl add-flow br-int "table=1,ipv6,ct_state=+trk+rel,$Protocol, \
     action=resubmit(,2)"
   > ovs-ofctl add-flow br-int "table=2,ipv6,in_port=$Vif38Port, \
     ipv6_dst=$Vif42Ip,$Protocol, actions=mod_dl_src=$NatMacAddress, \
     mod_dl_dst=$Vif42MacAddress,output:$Vif42Port"
   > ovs-ofctl add-flow br-int "table=2,ipv6,in_port=$Vif42Port, \
     ct_state=-new+est,ct_mark=1,ct_zone=456,$Protocol, \
     actions=mod_dl_src=$NatMacAddress,mod_dl_dst=$Vif38MacAddress, \
     output:$Vif38Port"

.. note::

    Till the checksum offload support is complete we recommend
    disabling TX/RX offloads for IPV6 on Windows VM.

Windows Services
----------------

Open vSwitch daemons come with support to run as a Windows service. The
instructions here assume that you have installed the Open vSwitch utilities and
daemons via ``make install``.

To start, create the database:

::

   > ovsdb-tool create C:/openvswitch/etc/openvswitch/conf.db \
       "C:/openvswitch/usr/share/openvswitch/vswitch.ovsschema"

Create the ovsdb-server service and start it:

::

   > sc create ovsdb-server \
       binpath="C:/openvswitch/usr/sbin/ovsdb-server.exe \
       C:/openvswitch/etc/openvswitch/conf.db \
       -vfile:info --log-file --pidfile \
       --remote=punix:db.sock --service --service-monitor"
   > sc start ovsdb-server

.. tip::

   One of the common issues with creating a Windows service is with mungled
   paths.  You can make sure that the correct path has been registered with the
   Windows services manager by running:

   ::

      > sc qc ovsdb-server

Check that the service is healthy by running:

::

   > sc query ovsdb-server

Initialize the database:

::

   > ovs-vsctl --no-wait init

Create the ovs-vswitchd service and start it:

::

   > sc create ovs-vswitchd \
       binpath="C:/openvswitch/usr/sbin/ovs-vswitchd.exe \
       --pidfile -vfile:info --log-file  --service --service-monitor"
   > sc start ovs-vswitchd

Check that the service is healthy by running:

::

   > sc query ovs-vswitchd

To stop and delete the services, run:

::

   > sc stop ovs-vswitchd
   > sc stop ovsdb-server
   > sc delete ovs-vswitchd
   > sc delete ovsdb-server

Windows CI Service
------------------

`AppVeyor <www.appveyor.com>`__ provides a free Windows autobuild service for
open source projects.  Open vSwitch has integration with AppVeyor for
continuous build.  A developer can build test his changes for Windows by
logging into appveyor.com using a github account, creating a new project by
linking it to his development repository in github and triggering a new build.

TODO
----

* Investigate the working of sFlow on Windows and re-enable the unit tests.

* Investigate and add the feature to provide QoS.

* Sign the driver.