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 )