go.ligato.io/vpp-agent/v3@v3.5.0/examples/kvscheduler/l2/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  	"go.ligato.io/vpp-agent/v3/plugins/orchestrator"
    28  	vpp_ifplugin "go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin"
    29  	vpp_l2plugin "go.ligato.io/vpp-agent/v3/plugins/vpp/l2plugin"
    30  	linux_interfaces "go.ligato.io/vpp-agent/v3/proto/ligato/linux/interfaces"
    31  	linux_ns "go.ligato.io/vpp-agent/v3/proto/ligato/linux/namespace"
    32  	vpp_interfaces "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/interfaces"
    33  	vpp_l2 "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l2"
    34  )
    35  
    36  /*
    37  	This example demonstrates L2 Plugin v.2.
    38  */
    39  
    40  func main() {
    41  	// Set inter-dependency between VPP & Linux plugins
    42  	vpp_ifplugin.DefaultPlugin.LinuxIfPlugin = &linux_ifplugin.DefaultPlugin
    43  	linux_ifplugin.DefaultPlugin.VppIfPlugin = &vpp_ifplugin.DefaultPlugin
    44  
    45  	ep := &ExamplePlugin{
    46  		Orchestrator:  &orchestrator.DefaultPlugin,
    47  		LinuxIfPlugin: &linux_ifplugin.DefaultPlugin,
    48  		LinuxL3Plugin: &linux_l3plugin.DefaultPlugin,
    49  		VPPIfPlugin:   &vpp_ifplugin.DefaultPlugin,
    50  		VPPL2Plugin:   &vpp_l2plugin.DefaultPlugin,
    51  	}
    52  
    53  	a := agent.NewAgent(
    54  		agent.AllPlugins(ep),
    55  	)
    56  	if err := a.Run(); err != nil {
    57  		log.Fatal(err)
    58  	}
    59  }
    60  
    61  // ExamplePlugin is the main plugin which
    62  // handles resync and changes in this example.
    63  type ExamplePlugin struct {
    64  	LinuxIfPlugin *linux_ifplugin.IfPlugin
    65  	LinuxL3Plugin *linux_l3plugin.L3Plugin
    66  	VPPIfPlugin   *vpp_ifplugin.IfPlugin
    67  	VPPL2Plugin   *vpp_l2plugin.L2Plugin
    68  	Orchestrator  *orchestrator.Plugin
    69  }
    70  
    71  // String returns plugin name
    72  func (p *ExamplePlugin) String() string {
    73  	return "l2-example"
    74  }
    75  
    76  // Init handles initialization phase.
    77  func (p *ExamplePlugin) Init() error {
    78  	return nil
    79  }
    80  
    81  // AfterInit handles phase after initialization.
    82  func (p *ExamplePlugin) AfterInit() error {
    83  	go testLocalClientWithScheduler()
    84  	return nil
    85  }
    86  
    87  // Close cleans up the resources.
    88  func (p *ExamplePlugin) Close() error {
    89  	return nil
    90  }
    91  
    92  func testLocalClientWithScheduler() {
    93  	// initial resync
    94  	time.Sleep(time.Second * 2)
    95  	fmt.Println("=== RESYNC (using bridge domain) ===")
    96  
    97  	txn := localclient.DataResyncRequest("example")
    98  	err := txn.
    99  		LinuxInterface(veth2).
   100  		LinuxInterface(veth1).
   101  		LinuxInterface(linuxTap).
   102  		VppInterface(afpacket).
   103  		VppInterface(vppTap).
   104  		VppInterface(bviLoop).
   105  		VppInterface(loop2).
   106  		BD(bd).
   107  		BDFIB(fibForLoop).
   108  		BDFIB(fibForTAP).
   109  		BDFIB(fibForVETH).
   110  		BDFIB(dropFIB).
   111  		Send().ReceiveReply()
   112  	if err != nil {
   113  		fmt.Println(err)
   114  		return
   115  	}
   116  
   117  	// data changes
   118  
   119  	time.Sleep(time.Second * 10)
   120  	fmt.Printf("=== CHANGE (switching to XConnect) ===\n")
   121  
   122  	txn3 := localclient.DataChangeRequest("example")
   123  	err = txn3.Delete().
   124  		BD(bd.Name). // FIBs will be pending
   125  		Put().
   126  		XConnect(xConnectMs1ToMs2).
   127  		XConnect(xConnectMs2ToMs1).
   128  		Send().ReceiveReply()
   129  	if err != nil {
   130  		fmt.Println(err)
   131  		return
   132  	}
   133  }
   134  
   135  const (
   136  	bdNetPrefix = "10.11.1."
   137  	bdNetMask   = "/24"
   138  
   139  	veth1LogicalName = "myVETH1"
   140  	veth1HostName    = "veth1"
   141  	veth1IPAddr      = bdNetPrefix + "1"
   142  	veth1HwAddr      = "66:66:66:66:66:66"
   143  
   144  	veth2LogicalName = "myVETH2"
   145  	veth2HostName    = "veth2"
   146  
   147  	afPacketLogicalName = "myAFPacket"
   148  	afPacketHwAddr      = "a7:35:45:55:65:75"
   149  
   150  	vppTapLogicalName = "myVPPTap"
   151  	vppTapHwAddr      = "b3:12:12:45:A7:B7"
   152  	vppTapVersion     = 2
   153  
   154  	linuxTapLogicalName = "myLinuxTAP"
   155  	linuxTapHostName    = "tap_to_vpp"
   156  	linuxTapIPAddr      = bdNetPrefix + "2"
   157  	linuxTapHwAddr      = "88:88:88:88:88:88"
   158  
   159  	mycroservice1 = "microservice1"
   160  	mycroservice2 = "microservice2"
   161  
   162  	bviLoopName   = "myLoopback1"
   163  	bviLoopIP     = bdNetPrefix + "3"
   164  	bviLoopHwAddr = "cd:cd:cd:cd:cd:cd"
   165  
   166  	loop2Name   = "myLoopback2"
   167  	loop2HwAddr = "ef:ef:ef:ef:ef:ef"
   168  
   169  	bdName                = "myBridgeDomain"
   170  	bdFlood               = true
   171  	bdUnknownUnicastFlood = true
   172  	bdForward             = true
   173  	bdLearn               = false /* Learning turned off, FIBs are needed for connectivity */
   174  	bdArpTermination      = true
   175  	bdMacAge              = 0
   176  )
   177  
   178  var (
   179  	/* microservice1 <-> VPP */
   180  
   181  	veth1 = &linux_interfaces.Interface{
   182  		Name:        veth1LogicalName,
   183  		Type:        linux_interfaces.Interface_VETH,
   184  		Enabled:     true,
   185  		PhysAddress: veth1HwAddr,
   186  		IpAddresses: []string{
   187  			veth1IPAddr + bdNetMask,
   188  		},
   189  		HostIfName: veth1HostName,
   190  		Link: &linux_interfaces.Interface_Veth{
   191  			Veth: &linux_interfaces.VethLink{PeerIfName: veth2LogicalName},
   192  		},
   193  		Namespace: &linux_ns.NetNamespace{
   194  			Type:      linux_ns.NetNamespace_MICROSERVICE,
   195  			Reference: mycroservice1,
   196  		},
   197  	}
   198  	veth2 = &linux_interfaces.Interface{
   199  		Name:       veth2LogicalName,
   200  		Type:       linux_interfaces.Interface_VETH,
   201  		Enabled:    true,
   202  		HostIfName: veth2HostName,
   203  		Link: &linux_interfaces.Interface_Veth{
   204  			Veth: &linux_interfaces.VethLink{PeerIfName: veth1LogicalName},
   205  		},
   206  	}
   207  	afpacket = &vpp_interfaces.Interface{
   208  		Name:        afPacketLogicalName,
   209  		Type:        vpp_interfaces.Interface_AF_PACKET,
   210  		Enabled:     true,
   211  		PhysAddress: afPacketHwAddr,
   212  		Link: &vpp_interfaces.Interface_Afpacket{
   213  			Afpacket: &vpp_interfaces.AfpacketLink{
   214  				HostIfName: veth2HostName,
   215  			},
   216  		},
   217  	}
   218  
   219  	/* microservice2 <-> VPP */
   220  
   221  	linuxTap = &linux_interfaces.Interface{
   222  		Name:        linuxTapLogicalName,
   223  		Type:        linux_interfaces.Interface_TAP_TO_VPP,
   224  		Enabled:     true,
   225  		PhysAddress: linuxTapHwAddr,
   226  		IpAddresses: []string{
   227  			linuxTapIPAddr + bdNetMask,
   228  		},
   229  		HostIfName: linuxTapHostName,
   230  		Link: &linux_interfaces.Interface_Tap{
   231  			Tap: &linux_interfaces.TapLink{
   232  				VppTapIfName: vppTapLogicalName,
   233  			},
   234  		},
   235  		Namespace: &linux_ns.NetNamespace{
   236  			Type:      linux_ns.NetNamespace_MICROSERVICE,
   237  			Reference: mycroservice2,
   238  		},
   239  	}
   240  	vppTap = &vpp_interfaces.Interface{
   241  		Name:        vppTapLogicalName,
   242  		Type:        vpp_interfaces.Interface_TAP,
   243  		Enabled:     true,
   244  		PhysAddress: vppTapHwAddr,
   245  		Link: &vpp_interfaces.Interface_Tap{
   246  			Tap: &vpp_interfaces.TapLink{
   247  				Version:        vppTapVersion,
   248  				ToMicroservice: mycroservice2,
   249  			},
   250  		},
   251  	}
   252  
   253  	/* Bridge domain */
   254  
   255  	bd = &vpp_l2.BridgeDomain{
   256  		Name:                bdName,
   257  		Flood:               bdFlood,
   258  		UnknownUnicastFlood: bdUnknownUnicastFlood,
   259  		Forward:             bdForward,
   260  		Learn:               bdLearn,
   261  		ArpTermination:      bdArpTermination,
   262  		MacAge:              bdMacAge,
   263  		Interfaces: []*vpp_l2.BridgeDomain_Interface{
   264  			{
   265  				Name: vppTapLogicalName,
   266  			},
   267  			{
   268  				Name: afPacketLogicalName,
   269  			},
   270  			{
   271  				Name:                    bviLoopName,
   272  				BridgedVirtualInterface: true,
   273  			},
   274  		},
   275  	}
   276  	bviLoop = &vpp_interfaces.Interface{
   277  		Name:        bviLoopName,
   278  		Type:        vpp_interfaces.Interface_SOFTWARE_LOOPBACK,
   279  		Enabled:     true,
   280  		PhysAddress: bviLoopHwAddr,
   281  		IpAddresses: []string{
   282  			bviLoopIP + bdNetMask,
   283  		},
   284  	}
   285  	loop2 = &vpp_interfaces.Interface{
   286  		Name:        loop2Name,
   287  		Type:        vpp_interfaces.Interface_SOFTWARE_LOOPBACK,
   288  		Enabled:     true,
   289  		PhysAddress: loop2HwAddr,
   290  	}
   291  
   292  	/* FIB entries */
   293  
   294  	fibForLoop = &vpp_l2.FIBEntry{
   295  		PhysAddress:             bviLoopHwAddr,
   296  		BridgeDomain:            bdName,
   297  		Action:                  vpp_l2.FIBEntry_FORWARD,
   298  		OutgoingInterface:       bviLoopName,
   299  		BridgedVirtualInterface: true,
   300  		StaticConfig:            true,
   301  	}
   302  	fibForVETH = &vpp_l2.FIBEntry{
   303  		PhysAddress:       veth1HwAddr,
   304  		BridgeDomain:      bdName,
   305  		Action:            vpp_l2.FIBEntry_FORWARD,
   306  		OutgoingInterface: afPacketLogicalName,
   307  	}
   308  	fibForTAP = &vpp_l2.FIBEntry{
   309  		PhysAddress:       linuxTapHwAddr,
   310  		BridgeDomain:      bdName,
   311  		Action:            vpp_l2.FIBEntry_FORWARD,
   312  		OutgoingInterface: vppTapLogicalName,
   313  	}
   314  	dropFIB = &vpp_l2.FIBEntry{
   315  		PhysAddress:  loop2HwAddr,
   316  		BridgeDomain: bdName,
   317  		Action:       vpp_l2.FIBEntry_DROP,
   318  	}
   319  
   320  	/* XConnect */
   321  
   322  	xConnectMs1ToMs2 = &vpp_l2.XConnectPair{
   323  		ReceiveInterface:  afPacketLogicalName,
   324  		TransmitInterface: vppTapLogicalName,
   325  	}
   326  	xConnectMs2ToMs1 = &vpp_l2.XConnectPair{
   327  		ReceiveInterface:  vppTapLogicalName,
   328  		TransmitInterface: afPacketLogicalName,
   329  	}
   330  )