go.ligato.io/vpp-agent/v3@v3.5.0/plugins/vpp/ifplugin/descriptor/unnumbered.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 descriptor 16 17 import ( 18 "context" 19 20 "github.com/pkg/errors" 21 "go.ligato.io/cn-infra/v2/logging" 22 "google.golang.org/protobuf/proto" 23 24 kvs "go.ligato.io/vpp-agent/v3/plugins/kvscheduler/api" 25 "go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin/descriptor/adapter" 26 "go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin/ifaceidx" 27 "go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin/vppcalls" 28 interfaces "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/interfaces" 29 ) 30 31 const ( 32 // UnnumberedIfDescriptorName is the name of the descriptor for the unnumbered 33 // config-subsection of VPP interfaces. 34 UnnumberedIfDescriptorName = "vpp-unnumbered-interface" 35 36 // dependency labels 37 unnumberedInterfaceHasIPDep = "unnumbered-interface-has-IP" 38 ) 39 40 // UnnumberedIfDescriptor sets/unsets VPP interfaces as unnumbered. 41 // Values = Interface_Unnumbered{} derived from interfaces where IsUnnumbered==true 42 type UnnumberedIfDescriptor struct { 43 log logging.Logger 44 ifHandler vppcalls.InterfaceVppAPI 45 ifIndex ifaceidx.IfaceMetadataIndex 46 } 47 48 // NewUnnumberedIfDescriptor creates a new instance of UnnumberedIfDescriptor. 49 func NewUnnumberedIfDescriptor(ifHandler vppcalls.InterfaceVppAPI, ifIndex ifaceidx.IfaceMetadataIndex, 50 log logging.PluginLogger) *kvs.KVDescriptor { 51 52 ctx := &UnnumberedIfDescriptor{ 53 ifHandler: ifHandler, 54 ifIndex: ifIndex, 55 log: log.NewLogger("unif-descriptor"), 56 } 57 58 typedDescr := &adapter.UnnumberedDescriptor{ 59 Name: UnnumberedIfDescriptorName, 60 KeySelector: ctx.IsUnnumberedInterfaceKey, 61 ValueTypeName: string(proto.MessageName(&interfaces.Interface_Unnumbered{})), 62 Create: ctx.Create, 63 Delete: ctx.Delete, 64 Dependencies: ctx.Dependencies, 65 } 66 67 return adapter.NewUnnumberedDescriptor(typedDescr) 68 } 69 70 // IsUnnumberedInterfaceKey returns true if the key is identifying unnumbered 71 // VPP interface. 72 func (d *UnnumberedIfDescriptor) IsUnnumberedInterfaceKey(key string) bool { 73 _, isValid := interfaces.ParseNameFromUnnumberedKey(key) 74 return isValid 75 } 76 77 // Create sets interface as unnumbered. 78 func (d *UnnumberedIfDescriptor) Create(key string, unIntf *interfaces.Interface_Unnumbered) (metadata interface{}, err error) { 79 ifName, _ := interfaces.ParseNameFromUnnumberedKey(key) 80 81 ifMeta, found := d.ifIndex.LookupByName(ifName) 82 if !found { 83 err = errors.Errorf("failed to find unnumbered interface %s", ifName) 84 d.log.Error(err) 85 return nil, err 86 } 87 88 ifWithIPMeta, found := d.ifIndex.LookupByName(unIntf.InterfaceWithIp) 89 if !found { 90 err = errors.Errorf("failed to find interface %s referenced by unnumbered interface %s", 91 unIntf.InterfaceWithIp, ifName) 92 d.log.Error(err) 93 return nil, err 94 } 95 96 err = d.ifHandler.SetUnnumberedIP(context.TODO(), ifMeta.SwIfIndex, ifWithIPMeta.SwIfIndex) 97 if err != nil { 98 d.log.Error(err) 99 } 100 return nil, err 101 } 102 103 // Delete un-sets interface as unnumbered. 104 func (d *UnnumberedIfDescriptor) Delete(key string, unIntf *interfaces.Interface_Unnumbered, metadata interface{}) error { 105 ifName, _ := interfaces.ParseNameFromUnnumberedKey(key) 106 107 ifMeta, found := d.ifIndex.LookupByName(ifName) 108 if !found { 109 err := errors.Errorf("failed to find unnumbered interface %s", ifName) 110 d.log.Error(err) 111 return err 112 } 113 114 err := d.ifHandler.UnsetUnnumberedIP(context.TODO(), ifMeta.SwIfIndex) 115 if err != nil { 116 d.log.Error(err) 117 } 118 119 return err 120 } 121 122 // Dependencies lists dependencies for an unnumbered VPP interface. 123 func (d *UnnumberedIfDescriptor) Dependencies(key string, unIntf *interfaces.Interface_Unnumbered) (deps []kvs.Dependency) { 124 // link between unnumbered interface and the referenced interface with IP address 125 // - satisfied as along as the referenced interface is configured and has at least 126 // one IP address assigned 127 deps = []kvs.Dependency{ 128 { 129 Label: unnumberedInterfaceHasIPDep, 130 Key: interfaces.InterfaceWithIPKey(unIntf.InterfaceWithIp), 131 }, 132 } 133 134 // interface has to be assigned to VRF before setting as unnumbered 135 iface, _ := interfaces.ParseNameFromUnnumberedKey(key) 136 deps = append(deps, kvs.Dependency{ 137 Label: interfaceInVrfDep, 138 AnyOf: kvs.AnyOfDependency{ 139 KeyPrefixes: []string{interfaces.InterfaceVrfKeyPrefix(iface)}, 140 }, 141 }) 142 return 143 }