go.ligato.io/vpp-agent/v3@v3.5.0/examples/kvscheduler/nat/main.go (about)

     1  //  Copyright (c) 2018 Cisco and/or its affiliates.
     2  //
     3  //  Licensed under the Apache License, Version 2.0 (the "License");
     4  //  you may not use this file except in compliance with the License.
     5  //  You may obtain a copy of the License at:
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  //  Unless required by applicable law or agreed to in writing, software
    10  //  distributed under the License is distributed on an "AS IS" BASIS,
    11  //  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  //  See the License for the specific language governing permissions and
    13  //  limitations under the License.
    14  
    15  package main
    16  
    17  import (
    18  	"fmt"
    19  	"log"
    20  	"time"
    21  
    22  	"go.ligato.io/cn-infra/v2/agent"
    23  
    24  	"go.ligato.io/vpp-agent/v3/clientv2/linux/localclient"
    25  	linux_ifplugin "go.ligato.io/vpp-agent/v3/plugins/linux/ifplugin"
    26  	linux_l3plugin "go.ligato.io/vpp-agent/v3/plugins/linux/l3plugin"
    27  	linux_nsplugin "go.ligato.io/vpp-agent/v3/plugins/linux/nsplugin"
    28  	"go.ligato.io/vpp-agent/v3/plugins/orchestrator"
    29  	vpp_ifplugin "go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin"
    30  	vpp_natplugin "go.ligato.io/vpp-agent/v3/plugins/vpp/natplugin"
    31  	"go.ligato.io/vpp-agent/v3/proto/ligato/linux/interfaces"
    32  	linux_l3 "go.ligato.io/vpp-agent/v3/proto/ligato/linux/l3"
    33  	linux_ns "go.ligato.io/vpp-agent/v3/proto/ligato/linux/namespace"
    34  	vpp_interfaces "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/interfaces"
    35  	vpp_nat "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/nat"
    36  )
    37  
    38  /*
    39  	This example demonstrates natplugin v.2
    40  
    41  	Add this config stanza to the VPP startup configuration:
    42  
    43  	nat {
    44  		endpoint-dependent
    45  	}
    46  
    47  	Deploy microservices with servers:
    48  
    49  	host-term1$ docker run -it --rm  -e MICROSERVICE_LABEL=microservice-server1 lencomilan/ubuntu /bin/bash
    50  	host-term1$ nc -l -p 8080 &
    51  	host-term1$ nc -u -l -p 9090 &
    52  
    53  	host-term2$ docker run -it --rm  -e MICROSERVICE_LABEL=microservice-server2 lencomilan/ubuntu /bin/bash
    54  	host-term2$ nc -l -p 8081 &
    55  	host-term2$ nc -u -l -p 9091 &
    56  
    57  	Test DNATs from microservice-client:
    58  
    59  	host-term3$ docker run -it --rm  -e MICROSERVICE_LABEL=microservice-client lencomilan/ubuntu /bin/bash
    60  	# TCP Service:
    61  	host-term3$ nc 10.36.10.1 80
    62  	host-term3$ nc 10.36.10.2 80
    63  	host-term3$ nc 10.36.10.3 80
    64  	# UDP Service:
    65  	host-term3$ nc -u 10.36.10.10 90
    66  	host-term3$ nc -u 10.36.10.11 90
    67  	host-term3$ nc -u 10.36.10.12 90
    68  
    69  	Run server in the host:
    70  
    71  	host-term4$ nc -l -p 8080 &
    72  
    73  	# Accessing server 192.168.13.10:8080 running in the host should trigger
    74  	# source-NAT in the post-routing, i.e. no need to route microservices from the host:
    75  	host-term3$ nc 192.168.13.20 8080  # host-term3 = microservice-client
    76  */
    77  
    78  func main() {
    79  	// Set inter-dependency between VPP & Linux plugins
    80  	vpp_ifplugin.DefaultPlugin.LinuxIfPlugin = &linux_ifplugin.DefaultPlugin
    81  	vpp_ifplugin.DefaultPlugin.NsPlugin = &linux_nsplugin.DefaultPlugin
    82  	linux_ifplugin.DefaultPlugin.VppIfPlugin = &vpp_ifplugin.DefaultPlugin
    83  
    84  	ep := &ExamplePlugin{
    85  		Orchestrator:  &orchestrator.DefaultPlugin,
    86  		LinuxIfPlugin: &linux_ifplugin.DefaultPlugin,
    87  		LinuxL3Plugin: &linux_l3plugin.DefaultPlugin,
    88  		VPPIfPlugin:   &vpp_ifplugin.DefaultPlugin,
    89  		VPPNATPlugin:  &vpp_natplugin.DefaultPlugin,
    90  	}
    91  
    92  	a := agent.NewAgent(
    93  		agent.AllPlugins(ep),
    94  	)
    95  	if err := a.Run(); err != nil {
    96  		log.Fatal(err)
    97  	}
    98  }
    99  
   100  // ExamplePlugin is the main plugin which
   101  // handles resync and changes in this example.
   102  type ExamplePlugin struct {
   103  	LinuxIfPlugin *linux_ifplugin.IfPlugin
   104  	LinuxL3Plugin *linux_l3plugin.L3Plugin
   105  	VPPIfPlugin   *vpp_ifplugin.IfPlugin
   106  	VPPNATPlugin  *vpp_natplugin.NATPlugin
   107  	Orchestrator  *orchestrator.Plugin
   108  }
   109  
   110  // String returns plugin name
   111  func (p *ExamplePlugin) String() string {
   112  	return "vpp-nat-example"
   113  }
   114  
   115  // Init handles initialization phase.
   116  func (p *ExamplePlugin) Init() error {
   117  	return nil
   118  }
   119  
   120  // AfterInit handles phase after initialization.
   121  func (p *ExamplePlugin) AfterInit() error {
   122  	go testLocalClientWithScheduler()
   123  	return nil
   124  }
   125  
   126  // Close cleans up the resources.
   127  func (p *ExamplePlugin) Close() error {
   128  	return nil
   129  }
   130  
   131  func testLocalClientWithScheduler() {
   132  	// initial resync
   133  	time.Sleep(time.Second * 2)
   134  	fmt.Println("=== RESYNC ===")
   135  
   136  	txn := localclient.DataResyncRequest("example")
   137  	err := txn.
   138  		LinuxInterface(hostLinuxTap).
   139  		LinuxInterface(clientLinuxTap).
   140  		LinuxInterface(server1LinuxTap).
   141  		LinuxInterface(server2LinuxTap).
   142  		LinuxRoute(hostRouteToServices).
   143  		LinuxRoute(clientRouteToServices).
   144  		LinuxRoute(clientRouteToHost).
   145  		LinuxRoute(server1RouteToServices).
   146  		LinuxRoute(server1RouteToHost).
   147  		LinuxRoute(server1RouteToClient).
   148  		LinuxRoute(server2RouteToServices).
   149  		LinuxRoute(server2RouteToHost).
   150  		LinuxRoute(server2RouteToClient).
   151  		VppInterface(hostVPPTap).
   152  		VppInterface(clientVPPTap).
   153  		VppInterface(server1VPPTap).
   154  		VppInterface(server2VPPTap).
   155  		NAT44Global(natGlobal).
   156  		NAT44Interface(natInterfaceTapHost).
   157  		NAT44Interface(natInterfaceTapClient).
   158  		NAT44Interface(natInterfaceTapServer1).
   159  		NAT44Interface(natInterfaceTapServer2).
   160  		NAT44AddressPool(natPool1).
   161  		NAT44AddressPool(natPool2).
   162  		DNAT44(tcpServiceDNAT).
   163  		DNAT44(udpServiceDNAT).
   164  		DNAT44(idDNAT).
   165  		DNAT44(externalIfaceDNAT).
   166  		DNAT44(emptyDNAT).
   167  		DNAT44(addrFromPoolDNAT).
   168  		Send().ReceiveReply()
   169  	if err != nil {
   170  		fmt.Println(err)
   171  		return
   172  	}
   173  
   174  	// data change
   175  	/* UNCOMMENT TO TEST THE CONFIG CHANGE
   176  	time.Sleep(time.Second * 10)
   177  	fmt.Println("=== CHANGE ===")
   178  
   179  	txn2 := localclient.DataChangeRequest("example")
   180  	err = txn2.Put().
   181  		Delete().
   182  		NAT44Global().
   183  		DNAT44(udpServiceDNAT.Label).
   184  		Send().ReceiveReply()
   185  	if err != nil {
   186  		fmt.Println(err)
   187  		return
   188  	}
   189  	*/
   190  }
   191  
   192  const (
   193  	mycroserviceClient           = "microservice-client"
   194  	microserviceClientNetPrefix  = "10.11.1."
   195  	mycroserviceServer1          = "microservice-server1"
   196  	microserviceServer1NetPrefix = "10.11.2."
   197  	mycroserviceServer2          = "microservice-server2"
   198  	microserviceServer2NetPrefix = "10.11.3."
   199  	microserviceNetMask          = "/30"
   200  
   201  	hostNetPrefix = "192.168.13."
   202  	hostNetMask   = "/24"
   203  
   204  	vppTapHostLogicalName = "vpp-tap-host"
   205  	vppTapHostIPAddr      = hostNetPrefix + "10"
   206  	vppTapHostVersion     = 2
   207  
   208  	vppTapClientLogicalName = "vpp-tap-client"
   209  	vppTapClientIPAddr      = microserviceClientNetPrefix + "1"
   210  	vppTapClientVersion     = 2
   211  
   212  	vppTapServer1LogicalName = "vpp-tap-server1"
   213  	vppTapServer1IPAddr      = microserviceServer1NetPrefix + "1"
   214  	vppTapServer1Version     = 2
   215  
   216  	vppTapServer2LogicalName = "vpp-tap-server2"
   217  	vppTapServer2IPAddr      = microserviceServer2NetPrefix + "1"
   218  	vppTapServer2Version     = 2
   219  
   220  	linuxTapHostLogicalName = "linux-tap-host"
   221  	linuxTapHostIPAddr      = hostNetPrefix + "20"
   222  
   223  	linuxTapClientLogicalName = "linux-tap-client"
   224  	linuxTapClientIPAddr      = microserviceClientNetPrefix + "2"
   225  
   226  	linuxTapServer1LogicalName = "linux-tap-server1"
   227  	linuxTapServer1IPAddr      = microserviceServer1NetPrefix + "2"
   228  
   229  	linuxTapServer2LogicalName = "linux-tap-server2"
   230  	linuxTapServer2IPAddr      = microserviceServer2NetPrefix + "2"
   231  
   232  	linuxTapHostName = "tap_to_vpp"
   233  
   234  	serviceNetPrefix = "10.36.10."
   235  	serviceNetMask   = "/24"
   236  
   237  	tcpServiceLabel            = "tcp-service"
   238  	tcpServiceExternalIP1      = serviceNetPrefix + "1"
   239  	tcpServiceExternalIP2      = serviceNetPrefix + "2"
   240  	tcpServiceExternalIP3      = serviceNetPrefix + "3"
   241  	tcpServiceExternalPort     = 80
   242  	tcpServiceLocalPortServer1 = 8080
   243  	tcpServiceLocalPortServer2 = 8081
   244  
   245  	udpServiceLabel            = "udp-service"
   246  	udpServiceExternalIP1      = serviceNetPrefix + "10"
   247  	udpServiceExternalIP2      = serviceNetPrefix + "11"
   248  	udpServiceExternalIP3      = serviceNetPrefix + "12"
   249  	udpServiceExternalPort     = 90
   250  	udpServiceLocalPortServer1 = 9090
   251  	udpServiceLocalPortServer2 = 9091
   252  
   253  	idDNATLabel = "id-dnat"
   254  	idDNATPort  = 7777
   255  
   256  	extIfaceDNATLabel        = "external-interfaces"
   257  	extIfaceDNATExternalPort = 3333
   258  	extIfaceDNATLocalPort    = 4444
   259  
   260  	addrFromPoolDNATLabel = "external-address-from-pool"
   261  	addrFromPoolDNATPort  = 6000
   262  
   263  	emptyDNATLabel = "empty-dnat"
   264  
   265  	natPoolAddr1 = hostNetPrefix + "100"
   266  	natPoolAddr2 = hostNetPrefix + "101"
   267  	natPoolAddr3 = hostNetPrefix + "250"
   268  )
   269  
   270  var (
   271  	/* host <-> VPP */
   272  
   273  	hostLinuxTap = &linux_interfaces.Interface{
   274  		Name:    linuxTapHostLogicalName,
   275  		Type:    linux_interfaces.Interface_TAP_TO_VPP,
   276  		Enabled: true,
   277  		IpAddresses: []string{
   278  			linuxTapHostIPAddr + hostNetMask,
   279  		},
   280  		HostIfName: linuxTapHostName,
   281  		Link: &linux_interfaces.Interface_Tap{
   282  			Tap: &linux_interfaces.TapLink{
   283  				VppTapIfName: vppTapHostLogicalName,
   284  			},
   285  		},
   286  	}
   287  	hostVPPTap = &vpp_interfaces.Interface{
   288  		Name:    vppTapHostLogicalName,
   289  		Type:    vpp_interfaces.Interface_TAP,
   290  		Enabled: true,
   291  		IpAddresses: []string{
   292  			vppTapHostIPAddr + hostNetMask,
   293  		},
   294  		Link: &vpp_interfaces.Interface_Tap{
   295  			Tap: &vpp_interfaces.TapLink{
   296  				Version: vppTapHostVersion,
   297  			},
   298  		},
   299  	}
   300  	hostRouteToServices = &linux_l3.Route{
   301  		OutgoingInterface: linuxTapHostLogicalName,
   302  		Scope:             linux_l3.Route_GLOBAL,
   303  		DstNetwork:        serviceNetPrefix + "0" + serviceNetMask,
   304  		GwAddr:            vppTapHostIPAddr,
   305  	}
   306  
   307  	/* microservice-client <-> VPP */
   308  
   309  	clientLinuxTap = &linux_interfaces.Interface{
   310  		Name:    linuxTapClientLogicalName,
   311  		Type:    linux_interfaces.Interface_TAP_TO_VPP,
   312  		Enabled: true,
   313  		IpAddresses: []string{
   314  			linuxTapClientIPAddr + microserviceNetMask,
   315  		},
   316  		HostIfName: linuxTapHostName,
   317  		Link: &linux_interfaces.Interface_Tap{
   318  			Tap: &linux_interfaces.TapLink{
   319  				VppTapIfName: vppTapClientLogicalName,
   320  			},
   321  		},
   322  		Namespace: &linux_ns.NetNamespace{
   323  			Type:      linux_ns.NetNamespace_MICROSERVICE,
   324  			Reference: mycroserviceClient,
   325  		},
   326  	}
   327  	clientVPPTap = &vpp_interfaces.Interface{
   328  		Name:    vppTapClientLogicalName,
   329  		Type:    vpp_interfaces.Interface_TAP,
   330  		Enabled: true,
   331  		IpAddresses: []string{
   332  			vppTapClientIPAddr + microserviceNetMask,
   333  		},
   334  		Link: &vpp_interfaces.Interface_Tap{
   335  			Tap: &vpp_interfaces.TapLink{
   336  				Version:        vppTapClientVersion,
   337  				ToMicroservice: mycroserviceClient,
   338  			},
   339  		},
   340  	}
   341  	clientRouteToServices = &linux_l3.Route{
   342  		OutgoingInterface: linuxTapClientLogicalName,
   343  		Scope:             linux_l3.Route_GLOBAL,
   344  		DstNetwork:        serviceNetPrefix + "0" + serviceNetMask,
   345  		GwAddr:            vppTapClientIPAddr,
   346  	}
   347  	clientRouteToHost = &linux_l3.Route{
   348  		OutgoingInterface: linuxTapClientLogicalName,
   349  		Scope:             linux_l3.Route_GLOBAL,
   350  		DstNetwork:        hostNetPrefix + "0" + hostNetMask,
   351  		GwAddr:            vppTapClientIPAddr,
   352  	}
   353  
   354  	/* microservice-server1 <-> VPP */
   355  
   356  	server1LinuxTap = &linux_interfaces.Interface{
   357  		Name:    linuxTapServer1LogicalName,
   358  		Type:    linux_interfaces.Interface_TAP_TO_VPP,
   359  		Enabled: true,
   360  		IpAddresses: []string{
   361  			linuxTapServer1IPAddr + microserviceNetMask,
   362  		},
   363  		HostIfName: linuxTapHostName,
   364  		Link: &linux_interfaces.Interface_Tap{
   365  			Tap: &linux_interfaces.TapLink{
   366  				VppTapIfName: vppTapServer1LogicalName,
   367  			},
   368  		},
   369  		Namespace: &linux_ns.NetNamespace{
   370  			Type:      linux_ns.NetNamespace_MICROSERVICE,
   371  			Reference: mycroserviceServer1,
   372  		},
   373  	}
   374  	server1VPPTap = &vpp_interfaces.Interface{
   375  		Name:    vppTapServer1LogicalName,
   376  		Type:    vpp_interfaces.Interface_TAP,
   377  		Enabled: true,
   378  		IpAddresses: []string{
   379  			vppTapServer1IPAddr + microserviceNetMask,
   380  		},
   381  		Link: &vpp_interfaces.Interface_Tap{
   382  			Tap: &vpp_interfaces.TapLink{
   383  				Version:        vppTapServer1Version,
   384  				ToMicroservice: mycroserviceServer1,
   385  			},
   386  		},
   387  	}
   388  	server1RouteToServices = &linux_l3.Route{
   389  		OutgoingInterface: linuxTapServer1LogicalName,
   390  		Scope:             linux_l3.Route_GLOBAL,
   391  		DstNetwork:        serviceNetPrefix + "0" + serviceNetMask,
   392  		GwAddr:            vppTapServer1IPAddr,
   393  	}
   394  	server1RouteToHost = &linux_l3.Route{
   395  		OutgoingInterface: linuxTapServer1LogicalName,
   396  		Scope:             linux_l3.Route_GLOBAL,
   397  		DstNetwork:        hostNetPrefix + "0" + hostNetMask,
   398  		GwAddr:            vppTapServer1IPAddr,
   399  	}
   400  	server1RouteToClient = &linux_l3.Route{
   401  		OutgoingInterface: linuxTapServer1LogicalName,
   402  		Scope:             linux_l3.Route_GLOBAL,
   403  		DstNetwork:        linuxTapClientIPAddr + "/32",
   404  		GwAddr:            vppTapServer1IPAddr,
   405  	}
   406  
   407  	/* microservice-server2 <-> VPP */
   408  	server2LinuxTap = &linux_interfaces.Interface{
   409  		Name:    linuxTapServer2LogicalName,
   410  		Type:    linux_interfaces.Interface_TAP_TO_VPP,
   411  		Enabled: true,
   412  		IpAddresses: []string{
   413  			linuxTapServer2IPAddr + microserviceNetMask,
   414  		},
   415  		HostIfName: linuxTapHostName,
   416  		Link: &linux_interfaces.Interface_Tap{
   417  			Tap: &linux_interfaces.TapLink{
   418  				VppTapIfName: vppTapServer2LogicalName,
   419  			},
   420  		},
   421  		Namespace: &linux_ns.NetNamespace{
   422  			Type:      linux_ns.NetNamespace_MICROSERVICE,
   423  			Reference: mycroserviceServer2,
   424  		},
   425  	}
   426  	server2VPPTap = &vpp_interfaces.Interface{
   427  		Name:    vppTapServer2LogicalName,
   428  		Type:    vpp_interfaces.Interface_TAP,
   429  		Enabled: true,
   430  		IpAddresses: []string{
   431  			vppTapServer2IPAddr + microserviceNetMask,
   432  		},
   433  		Link: &vpp_interfaces.Interface_Tap{
   434  			Tap: &vpp_interfaces.TapLink{
   435  				Version:        vppTapServer2Version,
   436  				ToMicroservice: mycroserviceServer2,
   437  			},
   438  		},
   439  	}
   440  	server2RouteToServices = &linux_l3.Route{
   441  		OutgoingInterface: linuxTapServer2LogicalName,
   442  		Scope:             linux_l3.Route_GLOBAL,
   443  		DstNetwork:        serviceNetPrefix + "0" + serviceNetMask,
   444  		GwAddr:            vppTapServer2IPAddr,
   445  	}
   446  	server2RouteToHost = &linux_l3.Route{
   447  		OutgoingInterface: linuxTapServer2LogicalName,
   448  		Scope:             linux_l3.Route_GLOBAL,
   449  		DstNetwork:        hostNetPrefix + "0" + hostNetMask,
   450  		GwAddr:            vppTapServer2IPAddr,
   451  	}
   452  	server2RouteToClient = &linux_l3.Route{
   453  		OutgoingInterface: linuxTapServer2LogicalName,
   454  		Scope:             linux_l3.Route_GLOBAL,
   455  		DstNetwork:        linuxTapClientIPAddr + "/32",
   456  		GwAddr:            vppTapServer2IPAddr,
   457  	}
   458  
   459  	/* NAT44 global config */
   460  
   461  	natGlobal = &vpp_nat.Nat44Global{
   462  		Forwarding: true,
   463  		VirtualReassembly: &vpp_nat.VirtualReassembly{
   464  			Timeout:         4,
   465  			MaxReassemblies: 2048,
   466  			MaxFragments:    10,
   467  			DropFragments:   true,
   468  		},
   469  	}
   470  
   471  	/* NAT interfaces */
   472  
   473  	natInterfaceTapHost = &vpp_nat.Nat44Interface{
   474  		Name:          vppTapHostLogicalName,
   475  		NatOutside:    true,
   476  		OutputFeature: true,
   477  	}
   478  	natInterfaceTapClient = &vpp_nat.Nat44Interface{
   479  		Name:       vppTapClientLogicalName,
   480  		NatInside:  true, // just to test in & out together
   481  		NatOutside: true,
   482  	}
   483  	natInterfaceTapServer1 = &vpp_nat.Nat44Interface{
   484  		Name:      vppTapServer1LogicalName,
   485  		NatInside: true,
   486  	}
   487  	natInterfaceTapServer2 = &vpp_nat.Nat44Interface{
   488  		Name:      vppTapServer2LogicalName,
   489  		NatInside: true,
   490  	}
   491  
   492  	/* NAT pools */
   493  
   494  	natPool1 = &vpp_nat.Nat44AddressPool{
   495  		FirstIp: natPoolAddr1,
   496  		LastIp:  natPoolAddr2,
   497  	}
   498  	natPool2 = &vpp_nat.Nat44AddressPool{
   499  		FirstIp:  natPoolAddr3,
   500  		TwiceNat: true,
   501  	}
   502  
   503  	/* TCP service */
   504  
   505  	tcpServiceDNAT = &vpp_nat.DNat44{
   506  		Label: tcpServiceLabel,
   507  		StMappings: []*vpp_nat.DNat44_StaticMapping{
   508  			{
   509  				ExternalIp:   tcpServiceExternalIP1, // with LB
   510  				ExternalPort: tcpServiceExternalPort,
   511  				Protocol:     vpp_nat.DNat44_TCP,
   512  				LocalIps: []*vpp_nat.DNat44_StaticMapping_LocalIP{
   513  					{
   514  						LocalIp:     linuxTapServer1IPAddr,
   515  						LocalPort:   tcpServiceLocalPortServer1,
   516  						Probability: 1,
   517  					},
   518  					{
   519  						LocalIp:     linuxTapServer2IPAddr,
   520  						LocalPort:   tcpServiceLocalPortServer2,
   521  						Probability: 2, /* twice more likely */
   522  					},
   523  				},
   524  			},
   525  			{
   526  				ExternalIp:   tcpServiceExternalIP2, // server 1 only
   527  				ExternalPort: tcpServiceExternalPort,
   528  				Protocol:     vpp_nat.DNat44_TCP,
   529  				LocalIps: []*vpp_nat.DNat44_StaticMapping_LocalIP{
   530  					{
   531  						LocalIp:   linuxTapServer1IPAddr,
   532  						LocalPort: tcpServiceLocalPortServer1,
   533  					},
   534  				},
   535  			},
   536  			{
   537  				ExternalIp:   tcpServiceExternalIP3, // server 2 only
   538  				ExternalPort: tcpServiceExternalPort,
   539  				Protocol:     vpp_nat.DNat44_TCP,
   540  				LocalIps: []*vpp_nat.DNat44_StaticMapping_LocalIP{
   541  					{
   542  						LocalIp:   linuxTapServer2IPAddr,
   543  						LocalPort: tcpServiceLocalPortServer2,
   544  					},
   545  				},
   546  			},
   547  		},
   548  	}
   549  
   550  	/* UDP service */
   551  
   552  	udpServiceDNAT = &vpp_nat.DNat44{
   553  		Label: udpServiceLabel,
   554  		StMappings: []*vpp_nat.DNat44_StaticMapping{
   555  			{
   556  				ExternalIp:   udpServiceExternalIP1, // with LB
   557  				ExternalPort: udpServiceExternalPort,
   558  				Protocol:     vpp_nat.DNat44_UDP,
   559  				LocalIps: []*vpp_nat.DNat44_StaticMapping_LocalIP{
   560  					{
   561  						LocalIp:     linuxTapServer1IPAddr,
   562  						LocalPort:   udpServiceLocalPortServer1,
   563  						Probability: 1,
   564  					},
   565  					{
   566  						LocalIp:     linuxTapServer2IPAddr,
   567  						LocalPort:   udpServiceLocalPortServer2,
   568  						Probability: 2, /* twice more likely */
   569  					},
   570  				},
   571  			},
   572  			{
   573  				ExternalIp:   udpServiceExternalIP2, // server 1 only
   574  				ExternalPort: udpServiceExternalPort,
   575  				Protocol:     vpp_nat.DNat44_UDP,
   576  				LocalIps: []*vpp_nat.DNat44_StaticMapping_LocalIP{
   577  					{
   578  						LocalIp:   linuxTapServer1IPAddr,
   579  						LocalPort: udpServiceLocalPortServer1,
   580  					},
   581  				},
   582  			},
   583  			{
   584  				ExternalIp:   udpServiceExternalIP3, // server 2 only
   585  				ExternalPort: udpServiceExternalPort,
   586  				Protocol:     vpp_nat.DNat44_UDP,
   587  				LocalIps: []*vpp_nat.DNat44_StaticMapping_LocalIP{
   588  					{
   589  						LocalIp:   linuxTapServer2IPAddr,
   590  						LocalPort: udpServiceLocalPortServer2,
   591  					},
   592  				},
   593  			},
   594  		},
   595  	}
   596  
   597  	/* identity mapping */
   598  
   599  	idDNAT = &vpp_nat.DNat44{
   600  		Label: idDNATLabel,
   601  		IdMappings: []*vpp_nat.DNat44_IdentityMapping{
   602  			{
   603  				Interface: vppTapClientLogicalName,
   604  				Port:      idDNATPort,
   605  				Protocol:  vpp_nat.DNat44_TCP,
   606  			},
   607  			{
   608  				IpAddress: natPoolAddr2,
   609  				Port:      idDNATPort,
   610  				Protocol:  vpp_nat.DNat44_TCP,
   611  			},
   612  		},
   613  	}
   614  
   615  	/* DNAT with external interfaces */
   616  
   617  	externalIfaceDNAT = &vpp_nat.DNat44{
   618  		Label: extIfaceDNATLabel,
   619  		StMappings: []*vpp_nat.DNat44_StaticMapping{
   620  			{
   621  				ExternalInterface: vppTapServer1LogicalName,
   622  				ExternalPort:      extIfaceDNATExternalPort,
   623  				Protocol:          vpp_nat.DNat44_TCP,
   624  				LocalIps: []*vpp_nat.DNat44_StaticMapping_LocalIP{
   625  					{
   626  						LocalIp:   linuxTapServer1IPAddr,
   627  						LocalPort: extIfaceDNATLocalPort,
   628  					},
   629  				},
   630  			},
   631  			{
   632  				ExternalInterface: vppTapServer2LogicalName,
   633  				ExternalPort:      extIfaceDNATExternalPort,
   634  				Protocol:          vpp_nat.DNat44_TCP,
   635  				LocalIps: []*vpp_nat.DNat44_StaticMapping_LocalIP{
   636  					{
   637  						LocalIp:   linuxTapServer2IPAddr,
   638  						LocalPort: extIfaceDNATLocalPort,
   639  					},
   640  				},
   641  			},
   642  		},
   643  	}
   644  
   645  	/* empty DNAT */
   646  	emptyDNAT = &vpp_nat.DNat44{
   647  		Label: emptyDNATLabel,
   648  	}
   649  
   650  	/* DNAT with address from the pool */
   651  
   652  	addrFromPoolDNAT = &vpp_nat.DNat44{
   653  		Label: addrFromPoolDNATLabel,
   654  		StMappings: []*vpp_nat.DNat44_StaticMapping{
   655  			// Without LB
   656  			{
   657  				ExternalIp:   natPoolAddr1,
   658  				ExternalPort: addrFromPoolDNATPort,
   659  				Protocol:     vpp_nat.DNat44_TCP,
   660  				LocalIps: []*vpp_nat.DNat44_StaticMapping_LocalIP{
   661  					{
   662  						LocalIp:   linuxTapServer1IPAddr,
   663  						LocalPort: addrFromPoolDNATPort,
   664  					},
   665  				},
   666  			},
   667  			// With LB
   668  			{
   669  				ExternalIp:   natPoolAddr2,
   670  				ExternalPort: addrFromPoolDNATPort,
   671  				Protocol:     vpp_nat.DNat44_TCP,
   672  				LocalIps: []*vpp_nat.DNat44_StaticMapping_LocalIP{
   673  					{
   674  						LocalIp:   linuxTapServer1IPAddr,
   675  						LocalPort: addrFromPoolDNATPort,
   676  					},
   677  					{
   678  						LocalIp:   linuxTapServer2IPAddr,
   679  						LocalPort: addrFromPoolDNATPort,
   680  					},
   681  				},
   682  			},
   683  		},
   684  	}
   685  )