go.ligato.io/vpp-agent/v3@v3.5.0/examples/kvscheduler/vrf/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  	"google.golang.org/protobuf/proto"
    25  
    26  	"go.ligato.io/vpp-agent/v3/clientv2/linux/localclient"
    27  	"go.ligato.io/vpp-agent/v3/plugins/orchestrator"
    28  	"go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin"
    29  	"go.ligato.io/vpp-agent/v3/plugins/vpp/l3plugin"
    30  	"go.ligato.io/vpp-agent/v3/plugins/vpp/natplugin"
    31  	interfaces "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/interfaces"
    32  	l3 "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l3"
    33  	nat "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/nat"
    34  )
    35  
    36  /*
    37  	This example demonstrates VPP L3Plugin using KVScheduler, with focus on VRF tables.
    38  */
    39  
    40  func main() {
    41  	ep := &ExamplePlugin{
    42  		Orchestrator: &orchestrator.DefaultPlugin,
    43  		VPPIfPlugin:  &ifplugin.DefaultPlugin,
    44  		VPPL3Plugin:  &l3plugin.DefaultPlugin,
    45  		VPPNATPlugin: &natplugin.DefaultPlugin,
    46  	}
    47  
    48  	a := agent.NewAgent(
    49  		agent.AllPlugins(ep),
    50  	)
    51  	if err := a.Run(); err != nil {
    52  		log.Fatal(err)
    53  	}
    54  }
    55  
    56  // ExamplePlugin is the main plugin which
    57  // handles resync and changes in this example.
    58  type ExamplePlugin struct {
    59  	VPPIfPlugin  *ifplugin.IfPlugin
    60  	VPPL3Plugin  *l3plugin.L3Plugin
    61  	VPPNATPlugin *natplugin.NATPlugin
    62  	Orchestrator *orchestrator.Plugin
    63  }
    64  
    65  // String returns plugin name
    66  func (p *ExamplePlugin) String() string {
    67  	return "vpp-vrf-example"
    68  }
    69  
    70  // Init handles initialization phase.
    71  func (p *ExamplePlugin) Init() error {
    72  	return nil
    73  }
    74  
    75  // AfterInit handles phase after initialization.
    76  func (p *ExamplePlugin) AfterInit() error {
    77  	go testLocalClientWithScheduler()
    78  	return nil
    79  }
    80  
    81  // Close cleans up the resources.
    82  func (p *ExamplePlugin) Close() error {
    83  	return nil
    84  }
    85  
    86  func testLocalClientWithScheduler() {
    87  	// initial resync
    88  	time.Sleep(time.Second * 2)
    89  	fmt.Println("=== RESYNC ===")
    90  
    91  	txn := localclient.DataResyncRequest("example")
    92  	err := txn.
    93  		VppInterface(tap1).
    94  		VppInterface(tapUnnum).
    95  		VppInterface(vxlan1).
    96  		StaticRoute(route1).
    97  		StaticRoute(route2).
    98  		NAT44Global(natGlobal).
    99  		DNAT44(dnat1).
   100  		VrfTable(vrfV4).
   101  		Send().ReceiveReply()
   102  	if err != nil {
   103  		fmt.Println(err)
   104  		return
   105  	}
   106  
   107  	// data change
   108  	time.Sleep(time.Second * 15)
   109  	fmt.Println("=== CHANGE #1 ===")
   110  
   111  	tap1 = proto.Clone(tap1).(*interfaces.Interface)
   112  	tap1.IpAddresses = append(tap1.IpAddresses, "2001:db8:a0b:12f0::1/64")
   113  	dnat1 = proto.Clone(dnat1).(*nat.DNat44)
   114  	dnat1.IdMappings = []*nat.DNat44_IdentityMapping{
   115  		{
   116  			VrfId:     4, // not available
   117  			IpAddress: "10.11.12.13",
   118  			Port:      443,
   119  			Protocol:  nat.DNat44_TCP,
   120  		},
   121  	}
   122  
   123  	txn2 := localclient.DataChangeRequest("example")
   124  	err = txn2.
   125  		Put().
   126  		VrfTable(vrfV6).
   127  		VppInterface(tap1). // add IPv6 address
   128  		//		DNAT44(dnat1).      // will become pending
   129  		Send().ReceiveReply()
   130  	if err != nil {
   131  		fmt.Println(err)
   132  		return
   133  	}
   134  
   135  	/*
   136  		// data change #2
   137  		time.Sleep(time.Second * 60)
   138  		fmt.Println("=== CHANGE #2 ===")
   139  
   140  		txn3 := localclient.DataChangeRequest("example")
   141  		err = txn3.
   142  			Delete().
   143  			VrfTable(vrfV6.Id, vrfV6.Protocol).
   144  			VrfTable(vrfV4.Id, vrfV4.Protocol).
   145  			Send().ReceiveReply()
   146  		if err != nil {
   147  			fmt.Println(err)
   148  			return
   149  		}
   150  	*/
   151  }
   152  
   153  var (
   154  	tap1 = &interfaces.Interface{
   155  		Name:        "tap1",
   156  		Enabled:     true,
   157  		Type:        interfaces.Interface_TAP,
   158  		Vrf:         3,
   159  		IpAddresses: []string{"3.3.0.1/16"},
   160  		Link: &interfaces.Interface_Tap{
   161  			Tap: &interfaces.TapLink{
   162  				Version: 2,
   163  			},
   164  		},
   165  	}
   166  	tapUnnum = &interfaces.Interface{
   167  		Name:    "tap-unnumbered",
   168  		Enabled: true,
   169  		Type:    interfaces.Interface_TAP,
   170  		Vrf:     6, // ignored
   171  		Unnumbered: &interfaces.Interface_Unnumbered{
   172  			InterfaceWithIp: tap1.Name,
   173  		},
   174  		Link: &interfaces.Interface_Tap{
   175  			Tap: &interfaces.TapLink{
   176  				Version: 2,
   177  			},
   178  		},
   179  	}
   180  	vxlan1 = &interfaces.Interface{
   181  		Name:    "vxlan1",
   182  		Enabled: true,
   183  		Type:    interfaces.Interface_VXLAN_TUNNEL,
   184  		Vrf:     3,
   185  		Link: &interfaces.Interface_Vxlan{
   186  			Vxlan: &interfaces.VxlanLink{ // depends on VRF 3 for IPv6
   187  				SrcAddress: "2001:db8:85a3::8a2e:370:7334",
   188  				DstAddress: "2001:db8:85a3::7cbb:942:1234",
   189  			},
   190  		},
   191  	}
   192  	route1 = &l3.Route{
   193  		VrfId:             3,
   194  		DstNetwork:        "10.11.1.0/24",
   195  		OutgoingInterface: tap1.GetName(),
   196  		Weight:            100,
   197  		NextHopAddr:       "0.0.0.0",
   198  	}
   199  	route2 = &l3.Route{
   200  		VrfId:             3,
   201  		DstNetwork:        "2001:db8:a0b:12f0::/64",
   202  		OutgoingInterface: tap1.GetName(),
   203  		Weight:            100,
   204  		NextHopAddr:       "::",
   205  	}
   206  	natGlobal = &nat.Nat44Global{
   207  		AddressPool: []*nat.Nat44Global_Address{
   208  			{
   209  				Address: "10.14.5.5",
   210  			},
   211  			{
   212  				Address: "10.12.1.1",
   213  				VrfId:   3,
   214  			},
   215  		},
   216  	}
   217  	dnat1 = &nat.DNat44{
   218  		Label: "dnat1",
   219  		StMappings: []*nat.DNat44_StaticMapping{
   220  			{
   221  				ExternalIp:   "5.5.10.10",
   222  				ExternalPort: 80,
   223  				LocalIps: []*nat.DNat44_StaticMapping_LocalIP{
   224  					{
   225  						VrfId:       3,
   226  						LocalIp:     "192.168.10.5",
   227  						LocalPort:   8080,
   228  						Probability: 1,
   229  					},
   230  					{
   231  						VrfId:       3,
   232  						LocalIp:     "192.168.10.19",
   233  						LocalPort:   8080,
   234  						Probability: 2,
   235  					},
   236  				},
   237  			},
   238  			{
   239  				ExternalInterface: tap1.Name,
   240  				ExternalPort:      80,
   241  				LocalIps: []*nat.DNat44_StaticMapping_LocalIP{
   242  					{
   243  						VrfId:     3,
   244  						LocalIp:   "192.168.17.4",
   245  						LocalPort: 8080,
   246  					},
   247  				},
   248  			},
   249  		},
   250  	}
   251  	vrfV4 = &l3.VrfTable{
   252  		Id: 3,
   253  		//Label: "vrf3-IPv4",
   254  	}
   255  	vrfV6 = &l3.VrfTable{
   256  		Id:       3,
   257  		Protocol: l3.VrfTable_IPV6,
   258  		Label:    "vrf3-IPv6",
   259  	}
   260  )