go.ligato.io/vpp-agent/v3@v3.5.0/plugins/netalloc/descriptor/ip_alloc.go (about) 1 // Copyright (c) 2019 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 "net" 19 20 "go.ligato.io/cn-infra/v2/logging" 21 "google.golang.org/protobuf/types/known/emptypb" 22 23 kvs "go.ligato.io/vpp-agent/v3/plugins/kvscheduler/api" 24 "go.ligato.io/vpp-agent/v3/plugins/netalloc/descriptor/adapter" 25 "go.ligato.io/vpp-agent/v3/plugins/netalloc/utils" 26 "go.ligato.io/vpp-agent/v3/proto/ligato/netalloc" 27 ) 28 29 const ( 30 // IPAllocDescriptorName is the name of the descriptor for allocating 31 // IP addresses. 32 IPAllocDescriptorName = "netalloc-ip-address" 33 ) 34 35 // IPAllocDescriptor just validates and parses allocated IP addresses. 36 type IPAllocDescriptor struct { 37 log logging.Logger 38 } 39 40 // NewAddrAllocDescriptor creates a new instance of IPAllocDescriptor. 41 func NewAddrAllocDescriptor(log logging.PluginLogger) (descr *kvs.KVDescriptor) { 42 ctx := &IPAllocDescriptor{ 43 log: log.NewLogger("ip-address-alloc-descriptor"), 44 } 45 typedDescr := &adapter.IPAllocDescriptor{ 46 Name: IPAllocDescriptorName, 47 NBKeyPrefix: netalloc.ModelIPAllocation.KeyPrefix(), 48 ValueTypeName: netalloc.ModelIPAllocation.ProtoName(), 49 KeySelector: netalloc.ModelIPAllocation.IsKeyValid, 50 KeyLabel: netalloc.ModelIPAllocation.StripKeyPrefix, 51 WithMetadata: true, 52 Validate: ctx.Validate, 53 Create: ctx.Create, 54 Delete: ctx.Delete, 55 Retrieve: ctx.Retrieve, 56 DerivedValues: ctx.DerivedValues, 57 } 58 descr = adapter.NewIPAllocDescriptor(typedDescr) 59 return 60 } 61 62 // Validate checks if the address can be parsed. 63 func (d *IPAllocDescriptor) Validate(key string, addrAlloc *netalloc.IPAllocation) (err error) { 64 _, _, err = d.parseAddr(addrAlloc) 65 return err 66 } 67 68 // Create parses the address and stores it into the metadata. 69 func (d *IPAllocDescriptor) Create(key string, addrAlloc *netalloc.IPAllocation) (metadata *netalloc.IPAllocMetadata, err error) { 70 metadata, _, err = d.parseAddr(addrAlloc) 71 return 72 } 73 74 // Delete is NOOP. 75 func (d *IPAllocDescriptor) Delete(key string, addrAlloc *netalloc.IPAllocation, metadata *netalloc.IPAllocMetadata) (err error) { 76 return err 77 } 78 79 // DerivedValues derives "neighbour-gateway" key if GW is a neighbour of the interface 80 // (addresses are from the same IP network). 81 func (d *IPAllocDescriptor) DerivedValues(key string, addrAlloc *netalloc.IPAllocation) (derValues []kvs.KeyValuePair) { 82 _, neighGw, _ := d.parseAddr(addrAlloc) 83 if neighGw { 84 derValues = append(derValues, kvs.KeyValuePair{ 85 Key: netalloc.NeighGwKey(addrAlloc.NetworkName, addrAlloc.InterfaceName), 86 Value: &emptypb.Empty{}, 87 }) 88 } 89 return derValues 90 } 91 92 // Retrieve always returns what is expected to exists since Create doesn't really change 93 // anything in SB. 94 func (d *IPAllocDescriptor) Retrieve(correlate []adapter.IPAllocKVWithMetadata) (valid []adapter.IPAllocKVWithMetadata, err error) { 95 for _, addrAlloc := range correlate { 96 if meta, _, err := d.parseAddr(addrAlloc.Value); err == nil { 97 valid = append(valid, adapter.IPAllocKVWithMetadata{ 98 Key: addrAlloc.Key, 99 Value: addrAlloc.Value, 100 Metadata: meta, 101 Origin: kvs.FromNB, 102 }) 103 } 104 } 105 return valid, nil 106 } 107 108 // parseAddr tries to parse the allocated address. 109 func (d *IPAllocDescriptor) parseAddr(addrAlloc *netalloc.IPAllocation) (parsed *netalloc.IPAllocMetadata, neighGw bool, err error) { 110 ifaceAddr, _, err := utils.ParseIPAddr(addrAlloc.Address, nil) 111 if err != nil { 112 return nil, false, err 113 } 114 var gwAddr *net.IPNet 115 if addrAlloc.Gw != "" { 116 gwAddr, neighGw, err = utils.ParseIPAddr(addrAlloc.Gw, ifaceAddr) 117 if err != nil { 118 return nil, false, err 119 } 120 } 121 return &netalloc.IPAllocMetadata{IfaceAddr: ifaceAddr, GwAddr: gwAddr}, neighGw, nil 122 }