go.ligato.io/vpp-agent/v3@v3.5.0/examples/kvscheduler/netalloc/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  	"context"
    19  	"fmt"
    20  	"log"
    21  	"time"
    22  
    23  	"go.ligato.io/cn-infra/v2/agent"
    24  
    25  	"go.ligato.io/vpp-agent/v3/client"
    26  	linux_ifplugin "go.ligato.io/vpp-agent/v3/plugins/linux/ifplugin"
    27  	linux_l3plugin "go.ligato.io/vpp-agent/v3/plugins/linux/l3plugin"
    28  	linux_nsplugin "go.ligato.io/vpp-agent/v3/plugins/linux/nsplugin"
    29  	"go.ligato.io/vpp-agent/v3/plugins/orchestrator"
    30  	vpp_ifplugin "go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin"
    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  	"go.ligato.io/vpp-agent/v3/proto/ligato/netalloc"
    35  	vpp_interfaces "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/interfaces"
    36  )
    37  
    38  /*
    39  	This example demonstrates netalloc plugin (topology disassociated from the addressing).
    40  */
    41  
    42  func main() {
    43  	// Set inter-dependency between VPP & Linux plugins
    44  	vpp_ifplugin.DefaultPlugin.LinuxIfPlugin = &linux_ifplugin.DefaultPlugin
    45  	vpp_ifplugin.DefaultPlugin.NsPlugin = &linux_nsplugin.DefaultPlugin
    46  	linux_ifplugin.DefaultPlugin.VppIfPlugin = &vpp_ifplugin.DefaultPlugin
    47  
    48  	ep := &ExamplePlugin{
    49  		Orchestrator:  &orchestrator.DefaultPlugin,
    50  		LinuxIfPlugin: &linux_ifplugin.DefaultPlugin,
    51  		LinuxL3Plugin: &linux_l3plugin.DefaultPlugin,
    52  		VPPIfPlugin:   &vpp_ifplugin.DefaultPlugin,
    53  	}
    54  
    55  	a := agent.NewAgent(
    56  		agent.AllPlugins(ep),
    57  	)
    58  	if err := a.Run(); err != nil {
    59  		log.Fatal(err)
    60  	}
    61  }
    62  
    63  // ExamplePlugin is the main plugin which
    64  // handles resync and changes in this example.
    65  type ExamplePlugin struct {
    66  	LinuxIfPlugin *linux_ifplugin.IfPlugin
    67  	LinuxL3Plugin *linux_l3plugin.L3Plugin
    68  	VPPIfPlugin   *vpp_ifplugin.IfPlugin
    69  	Orchestrator  *orchestrator.Plugin
    70  }
    71  
    72  // String returns plugin name
    73  func (p *ExamplePlugin) String() string {
    74  	return "netalloc-example"
    75  }
    76  
    77  // Init handles initialization phase.
    78  func (p *ExamplePlugin) Init() error {
    79  	return nil
    80  }
    81  
    82  // AfterInit handles phase after initialization.
    83  func (p *ExamplePlugin) AfterInit() error {
    84  	go demonstrateNetalloc()
    85  	return nil
    86  }
    87  
    88  // Close cleans up the resources.
    89  func (p *ExamplePlugin) Close() error {
    90  	return nil
    91  }
    92  
    93  func demonstrateNetalloc() {
    94  	// initial resync
    95  	time.Sleep(time.Second)
    96  	fmt.Println("=== RESYNC ===")
    97  
    98  	err := client.LocalClient.ResyncConfig(
    99  		// addresses
   100  		veth1Addr, afpacketAddr, linuxTapAddr, vppTapAddr,
   101  		// topology
   102  		veth2, veth1, linuxTap, arpForVeth1, arpForLinuxTap,
   103  		linkRouteToMs1, routeToMs1, linkRouteToMs2, routeToMs2,
   104  		afpacket, vppTap)
   105  	if err != nil {
   106  		fmt.Println(err)
   107  		return
   108  	}
   109  
   110  	fmt.Println("=== CHANGE ===")
   111  	time.Sleep(time.Second * 5)
   112  	err = client.LocalClient.ChangeRequest().
   113  		Delete(veth1Addr).
   114  		Send(context.Background())
   115  	if err != nil {
   116  		fmt.Println(err)
   117  		return
   118  	}
   119  
   120  	fmt.Println("=== CHANGE (revert of the previous change) ===")
   121  	time.Sleep(time.Second * 5)
   122  	err = client.LocalClient.ChangeRequest().
   123  		Update(veth1Addr).
   124  		Send(context.Background())
   125  	if err != nil {
   126  		fmt.Println(err)
   127  		return
   128  	}
   129  }
   130  
   131  const (
   132  	networkName = "example-net"
   133  
   134  	veth1LogicalName = "myVETH1"
   135  	veth1IPAddr      = "10.11.1.1"
   136  	veth1IPAddr2     = "10.11.1.10"
   137  
   138  	veth2LogicalName = "myVETH2"
   139  	veth2HostName    = "veth2"
   140  
   141  	afPacketLogicalName = "myAFPacket"
   142  	afPacketIPAddr      = "10.11.1.2"
   143  	afPacketHWAddr      = "a7:35:45:55:65:75"
   144  
   145  	vppTapLogicalName = "myVPPTap"
   146  	vppTapIPAddr      = "10.11.2.2"
   147  	vppTapHwAddr      = "b3:12:12:45:A7:B7"
   148  
   149  	linuxTapLogicalName = "myLinuxTAP"
   150  
   151  	linuxTapIPAddr = "10.11.2.1"
   152  	linuxTapHwAddr = "88:88:88:88:88:88"
   153  
   154  	microserviceNetMask = "/30"
   155  	mycroservice1       = "microservice1"
   156  	mycroservice2       = "microservice2"
   157  
   158  	mycroservice2Mtu = 1700
   159  
   160  	routeMetric = 50
   161  )
   162  
   163  // ADRESSING
   164  
   165  var (
   166  	veth1Addr = &netalloc.IPAllocation{
   167  		NetworkName:   networkName,
   168  		InterfaceName: veth1LogicalName,
   169  		Address:       veth1IPAddr + microserviceNetMask,
   170  		Gw:            vppTapIPAddr,
   171  	}
   172  
   173  	veth1Addr2 = &netalloc.IPAllocation{
   174  		NetworkName:   networkName,
   175  		InterfaceName: veth1LogicalName,
   176  		Address:       veth1IPAddr2 + microserviceNetMask,
   177  		Gw:            vppTapIPAddr,
   178  	}
   179  
   180  	afpacketAddr = &netalloc.IPAllocation{
   181  		NetworkName:   networkName,
   182  		InterfaceName: afPacketLogicalName,
   183  		Address:       afPacketIPAddr + microserviceNetMask,
   184  	}
   185  
   186  	linuxTapAddr = &netalloc.IPAllocation{
   187  		NetworkName:   networkName,
   188  		InterfaceName: linuxTapLogicalName,
   189  		Address:       linuxTapIPAddr + microserviceNetMask,
   190  		Gw:            afPacketIPAddr,
   191  	}
   192  
   193  	vppTapAddr = &netalloc.IPAllocation{
   194  		NetworkName:   networkName,
   195  		InterfaceName: vppTapLogicalName,
   196  		Address:       vppTapIPAddr + microserviceNetMask,
   197  	}
   198  )
   199  
   200  // TOPOLOGY
   201  
   202  var (
   203  	/* microservice1 <-> VPP */
   204  	veth1 = &linux_interfaces.Interface{
   205  		Name:        veth1LogicalName,
   206  		Type:        linux_interfaces.Interface_VETH,
   207  		Enabled:     true,
   208  		PhysAddress: "66:66:66:66:66:66",
   209  		IpAddresses: []string{
   210  			"alloc:" + networkName,
   211  		},
   212  		Mtu:        1800,
   213  		HostIfName: "veth1",
   214  		Link: &linux_interfaces.Interface_Veth{
   215  			Veth: &linux_interfaces.VethLink{PeerIfName: veth2LogicalName},
   216  		},
   217  		Namespace: &linux_ns.NetNamespace{
   218  			Type:      linux_ns.NetNamespace_MICROSERVICE,
   219  			Reference: mycroservice1,
   220  		},
   221  	}
   222  
   223  	arpForVeth1 = &linux_l3.ARPEntry{
   224  		Interface: veth1LogicalName,
   225  		IpAddress: "alloc:" + networkName + "/" + vppTapLogicalName,
   226  		HwAddress: vppTapHwAddr,
   227  	}
   228  
   229  	linkRouteToMs2 = &linux_l3.Route{
   230  		OutgoingInterface: veth1LogicalName,
   231  		Scope:             linux_l3.Route_LINK,
   232  		DstNetwork:        "alloc:" + networkName + "/" + veth1LogicalName + "/GW",
   233  	}
   234  
   235  	routeToMs2 = &linux_l3.Route{
   236  		OutgoingInterface: veth1LogicalName,
   237  		Scope:             linux_l3.Route_GLOBAL,
   238  		DstNetwork:        "alloc:" + networkName + "/" + linuxTapLogicalName,
   239  		GwAddr:            "alloc:" + networkName + "/GW",
   240  		Metric:            routeMetric,
   241  	}
   242  
   243  	veth2 = &linux_interfaces.Interface{
   244  		Name:       veth2LogicalName,
   245  		Type:       linux_interfaces.Interface_VETH,
   246  		Enabled:    true,
   247  		Mtu:        1800,
   248  		HostIfName: veth2HostName,
   249  		Link: &linux_interfaces.Interface_Veth{
   250  			Veth: &linux_interfaces.VethLink{PeerIfName: veth1LogicalName},
   251  		},
   252  	}
   253  
   254  	afpacket = &vpp_interfaces.Interface{
   255  		Name:        afPacketLogicalName,
   256  		Type:        vpp_interfaces.Interface_AF_PACKET,
   257  		Enabled:     true,
   258  		PhysAddress: afPacketHWAddr,
   259  		IpAddresses: []string{
   260  			"alloc:" + networkName,
   261  		},
   262  		Mtu: 1800,
   263  		Link: &vpp_interfaces.Interface_Afpacket{
   264  			Afpacket: &vpp_interfaces.AfpacketLink{
   265  				HostIfName: veth2HostName,
   266  			},
   267  		},
   268  	}
   269  
   270  	/* microservice2 <-> VPP */
   271  
   272  	linuxTap = &linux_interfaces.Interface{
   273  		Name:        linuxTapLogicalName,
   274  		Type:        linux_interfaces.Interface_TAP_TO_VPP,
   275  		Enabled:     true,
   276  		PhysAddress: linuxTapHwAddr,
   277  		IpAddresses: []string{
   278  			"alloc:" + networkName,
   279  		},
   280  		Mtu:        mycroservice2Mtu,
   281  		HostIfName: "tap_to_vpp",
   282  		Link: &linux_interfaces.Interface_Tap{
   283  			Tap: &linux_interfaces.TapLink{
   284  				VppTapIfName: vppTapLogicalName,
   285  			},
   286  		},
   287  		Namespace: &linux_ns.NetNamespace{
   288  			Type:      linux_ns.NetNamespace_MICROSERVICE,
   289  			Reference: mycroservice2,
   290  		},
   291  	}
   292  
   293  	vppTap = &vpp_interfaces.Interface{
   294  		Name:        vppTapLogicalName,
   295  		Type:        vpp_interfaces.Interface_TAP,
   296  		Enabled:     true,
   297  		PhysAddress: vppTapHwAddr,
   298  		IpAddresses: []string{
   299  			"alloc:" + networkName,
   300  		},
   301  		Mtu: mycroservice2Mtu,
   302  		Link: &vpp_interfaces.Interface_Tap{
   303  			Tap: &vpp_interfaces.TapLink{
   304  				Version:        2,
   305  				ToMicroservice: mycroservice2,
   306  			},
   307  		},
   308  	}
   309  
   310  	arpForLinuxTap = &linux_l3.ARPEntry{
   311  		Interface: linuxTapLogicalName,
   312  		IpAddress: "alloc:" + networkName + "/" + afPacketLogicalName,
   313  		HwAddress: afPacketHWAddr,
   314  	}
   315  
   316  	linkRouteToMs1 = &linux_l3.Route{
   317  		OutgoingInterface: linuxTapLogicalName,
   318  		Scope:             linux_l3.Route_LINK,
   319  		DstNetwork:        "alloc:" + networkName + "/" + linuxTapLogicalName + "/GW",
   320  	}
   321  
   322  	routeToMs1 = &linux_l3.Route{
   323  		OutgoingInterface: linuxTapLogicalName,
   324  		Scope:             linux_l3.Route_GLOBAL,
   325  		DstNetwork:        "alloc:" + networkName + "/" + veth1LogicalName,
   326  		GwAddr:            "alloc:" + networkName + "/GW",
   327  		Metric:            routeMetric,
   328  	}
   329  )