go.ligato.io/vpp-agent/v3@v3.5.0/examples/kvscheduler/interconnect/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  	linuxifaceidx "go.ligato.io/vpp-agent/v3/plugins/linux/ifplugin/ifaceidx"
    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  	vppifaceidx "go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin/ifaceidx"
    32  	"go.ligato.io/vpp-agent/v3/proto/ligato/linux/interfaces"
    33  	linux_l3 "go.ligato.io/vpp-agent/v3/proto/ligato/linux/l3"
    34  	linux_ns "go.ligato.io/vpp-agent/v3/proto/ligato/linux/namespace"
    35  	vpp_interfaces "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/interfaces"
    36  )
    37  
    38  /*
    39  	This example demonstrates KVScheduler-based VPP ifplugin, Linux ifplugin and Linux l3plugin.
    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 "vpp-linux-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 testLocalClientWithScheduler(
    85  		p.VPPIfPlugin.GetInterfaceIndex(),
    86  		p.LinuxIfPlugin.GetInterfaceIndex(),
    87  	)
    88  	return nil
    89  }
    90  
    91  // Close cleans up the resources.
    92  func (p *ExamplePlugin) Close() error {
    93  	return nil
    94  }
    95  
    96  func testLocalClientWithScheduler(
    97  	vppIfIndex vppifaceidx.IfaceMetadataIndex,
    98  	linuxIfIndex linuxifaceidx.LinuxIfMetadataIndex,
    99  ) {
   100  	// initial resync
   101  	time.Sleep(time.Second * 2)
   102  	fmt.Println("=== RESYNC ===")
   103  
   104  	txn := localclient.DataResyncRequest("example")
   105  	err := txn.
   106  		LinuxInterface(veth2).
   107  		LinuxInterface(veth1).
   108  		LinuxInterface(linuxTap).
   109  		LinuxArpEntry(arpForVeth1).
   110  		LinuxArpEntry(arpForLinuxTap).
   111  		LinuxRoute(linkRouteToMs1).
   112  		LinuxRoute(routeToMs1).
   113  		LinuxRoute(linkRouteToMs2).
   114  		LinuxRoute(routeToMs2).
   115  		VppInterface(afpacket).
   116  		VppInterface(vppTap).
   117  		Send().ReceiveReply()
   118  	if err != nil {
   119  		fmt.Println(err)
   120  		return
   121  	}
   122  
   123  	// data change
   124  	time.Sleep(time.Second * 10)
   125  	fmt.Println("=== CHANGE ===")
   126  
   127  	veth1.Enabled = false
   128  
   129  	txn2 := localclient.DataChangeRequest("example")
   130  	err = txn2.
   131  		Put().
   132  		LinuxInterface(veth1).
   133  		/*Delete().
   134  		VppInterface(vppTap.Name).*/
   135  		Send().ReceiveReply()
   136  	if err != nil {
   137  		fmt.Println(err)
   138  		return
   139  	}
   140  
   141  	// test Linux interface metadata map
   142  	linuxIfMeta, exists := linuxIfIndex.LookupByName(veth1LogicalName)
   143  	fmt.Printf("Linux interface %s: found=%t, meta=%v\n", veth1LogicalName, exists, linuxIfMeta)
   144  	linuxIfMeta, exists = linuxIfIndex.LookupByName(linuxTapLogicalName)
   145  	fmt.Printf("Linux interface %s: found=%t, meta=%v\n", linuxTapLogicalName, exists, linuxIfMeta)
   146  
   147  	// test VPP interface metadata map
   148  	vppIfMeta, exists := vppIfIndex.LookupByName(afPacketLogicalName)
   149  	fmt.Printf("VPP interface %s: found=%t, meta=%v\n", afPacketLogicalName, exists, vppIfMeta)
   150  	vppIfMeta, exists = vppIfIndex.LookupByName(vppTapLogicalName)
   151  	fmt.Printf("VPP interface %s: found=%t, meta=%v\n", vppTapLogicalName, exists, vppIfMeta)
   152  }
   153  
   154  const (
   155  	veth1LogicalName = "myVETH1"
   156  
   157  	veth2LogicalName = "myVETH2"
   158  	veth2HostName    = "veth2"
   159  
   160  	afPacketLogicalName = "myAFPacket"
   161  
   162  	afPacketIPAddr = "10.11.1.2"
   163  
   164  	vppTapLogicalName = "myVPPTap"
   165  	vppTapIPAddr      = "10.11.2.2"
   166  	vppTapHwAddr      = "b3:12:12:45:A7:B7"
   167  
   168  	linuxTapLogicalName = "myLinuxTAP"
   169  
   170  	linuxTapIPAddr = "10.11.2.1"
   171  	linuxTapHwAddr = "88:88:88:88:88:88"
   172  
   173  	microserviceNetMask = "/30"
   174  	mycroservice1       = "microservice1"
   175  	mycroservice2       = "microservice2"
   176  	microservice1Net    = "10.11.1.0" + microserviceNetMask
   177  	microservice2Net    = "10.11.2.0" + microserviceNetMask
   178  
   179  	mycroservice2Mtu = 1700
   180  
   181  	routeMetric = 50
   182  )
   183  
   184  var (
   185  	/* microservice1 <-> VPP */
   186  	veth1 = &linux_interfaces.Interface{
   187  		Name:        veth1LogicalName,
   188  		Type:        linux_interfaces.Interface_VETH,
   189  		Enabled:     true,
   190  		PhysAddress: "66:66:66:66:66:66",
   191  		IpAddresses: []string{
   192  			("10.11.1.1") + microserviceNetMask,
   193  		},
   194  		Mtu:        1800,
   195  		HostIfName: "veth1",
   196  		Link: &linux_interfaces.Interface_Veth{
   197  			Veth: &linux_interfaces.VethLink{PeerIfName: veth2LogicalName},
   198  		},
   199  		Namespace: &linux_ns.NetNamespace{
   200  			Type:      linux_ns.NetNamespace_MICROSERVICE,
   201  			Reference: mycroservice1,
   202  		},
   203  	}
   204  
   205  	arpForVeth1 = &linux_l3.ARPEntry{
   206  		Interface: veth1LogicalName,
   207  		IpAddress: vppTapIPAddr,
   208  		HwAddress: vppTapHwAddr,
   209  	}
   210  
   211  	linkRouteToMs2 = &linux_l3.Route{
   212  		OutgoingInterface: veth1LogicalName,
   213  		Scope:             linux_l3.Route_LINK,
   214  		DstNetwork:        vppTapIPAddr + "/32",
   215  	}
   216  
   217  	routeToMs2 = &linux_l3.Route{
   218  		OutgoingInterface: veth1LogicalName,
   219  		Scope:             linux_l3.Route_GLOBAL,
   220  		DstNetwork:        microservice2Net,
   221  		GwAddr:            vppTapIPAddr,
   222  		Metric:            routeMetric,
   223  	}
   224  
   225  	veth2 = &linux_interfaces.Interface{
   226  		Name:       veth2LogicalName,
   227  		Type:       linux_interfaces.Interface_VETH,
   228  		Enabled:    true,
   229  		Mtu:        1800,
   230  		HostIfName: veth2HostName,
   231  		Link: &linux_interfaces.Interface_Veth{
   232  			Veth: &linux_interfaces.VethLink{PeerIfName: veth1LogicalName},
   233  		},
   234  	}
   235  
   236  	afpacket = &vpp_interfaces.Interface{
   237  		Name:        afPacketLogicalName,
   238  		Type:        vpp_interfaces.Interface_AF_PACKET,
   239  		Enabled:     true,
   240  		PhysAddress: "a7:35:45:55:65:75",
   241  		IpAddresses: []string{
   242  			afPacketIPAddr + microserviceNetMask,
   243  		},
   244  		Mtu: 1800,
   245  		Link: &vpp_interfaces.Interface_Afpacket{
   246  			Afpacket: &vpp_interfaces.AfpacketLink{
   247  				HostIfName: veth2HostName,
   248  			},
   249  		},
   250  	}
   251  
   252  	/* microservice2 <-> VPP */
   253  
   254  	linuxTap = &linux_interfaces.Interface{
   255  		Name:        linuxTapLogicalName,
   256  		Type:        linux_interfaces.Interface_TAP_TO_VPP,
   257  		Enabled:     true,
   258  		PhysAddress: linuxTapHwAddr,
   259  		IpAddresses: []string{
   260  			linuxTapIPAddr + microserviceNetMask,
   261  		},
   262  		Mtu:        mycroservice2Mtu,
   263  		HostIfName: "tap_to_vpp",
   264  		Link: &linux_interfaces.Interface_Tap{
   265  			Tap: &linux_interfaces.TapLink{
   266  				VppTapIfName: vppTapLogicalName,
   267  			},
   268  		},
   269  		/*Namespace: &linux_ns.NetNamespace{
   270  			Type:      linux_ns.NetNamespace_MICROSERVICE,
   271  			Reference: mycroservice2,
   272  		},*/
   273  	}
   274  
   275  	vppTap = &vpp_interfaces.Interface{
   276  		Name:        vppTapLogicalName,
   277  		Type:        vpp_interfaces.Interface_TAP,
   278  		Enabled:     true,
   279  		PhysAddress: vppTapHwAddr,
   280  		IpAddresses: []string{
   281  			vppTapIPAddr + microserviceNetMask,
   282  		},
   283  		Mtu: mycroservice2Mtu,
   284  		Link: &vpp_interfaces.Interface_Tap{
   285  			Tap: &vpp_interfaces.TapLink{
   286  				Version: 2,
   287  				//ToMicroservice: mycroservice2,
   288  			},
   289  		},
   290  	}
   291  
   292  	arpForLinuxTap = &linux_l3.ARPEntry{
   293  		Interface: linuxTapLogicalName,
   294  		IpAddress: afPacketIPAddr,
   295  		HwAddress: "a7:35:45:55:65:75",
   296  	}
   297  
   298  	linkRouteToMs1 = &linux_l3.Route{
   299  		OutgoingInterface: linuxTapLogicalName,
   300  		Scope:             linux_l3.Route_LINK,
   301  		DstNetwork:        afPacketIPAddr + "/32",
   302  	}
   303  
   304  	routeToMs1 = &linux_l3.Route{
   305  		OutgoingInterface: linuxTapLogicalName,
   306  		Scope:             linux_l3.Route_GLOBAL,
   307  		DstNetwork:        microservice1Net,
   308  		GwAddr:            afPacketIPAddr,
   309  		Metric:            routeMetric,
   310  	}
   311  )