go.ligato.io/vpp-agent/v3@v3.5.0/plugins/vpp/puntplugin/puntplugin.go (about) 1 // Copyright (c) 2021 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 //go:generate descriptor-adapter --descriptor-name IPPuntRedirect --value-type *vpp_punt.IPRedirect --import "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/punt" --output-dir "descriptor" 16 //go:generate descriptor-adapter --descriptor-name PuntToHost --value-type *vpp_punt.ToHost --import "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/punt" --output-dir "descriptor" 17 //go:generate descriptor-adapter --descriptor-name PuntException --value-type *vpp_punt.Exception --import "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/punt" --output-dir "descriptor" 18 19 package puntplugin 20 21 import ( 22 "strings" 23 24 "go.ligato.io/cn-infra/v2/datasync" 25 "go.ligato.io/cn-infra/v2/health/statuscheck" 26 "go.ligato.io/cn-infra/v2/infra" 27 "google.golang.org/protobuf/proto" 28 29 "go.ligato.io/vpp-agent/v3/pkg/models" 30 "go.ligato.io/vpp-agent/v3/plugins/govppmux" 31 kvs "go.ligato.io/vpp-agent/v3/plugins/kvscheduler/api" 32 "go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin" 33 "go.ligato.io/vpp-agent/v3/plugins/vpp/puntplugin/descriptor" 34 "go.ligato.io/vpp-agent/v3/plugins/vpp/puntplugin/descriptor/adapter" 35 "go.ligato.io/vpp-agent/v3/plugins/vpp/puntplugin/vppcalls" 36 vpp_punt "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/punt" 37 38 _ "go.ligato.io/vpp-agent/v3/plugins/vpp/puntplugin/vppcalls/vpp2101" 39 _ "go.ligato.io/vpp-agent/v3/plugins/vpp/puntplugin/vppcalls/vpp2106" 40 _ "go.ligato.io/vpp-agent/v3/plugins/vpp/puntplugin/vppcalls/vpp2202" 41 _ "go.ligato.io/vpp-agent/v3/plugins/vpp/puntplugin/vppcalls/vpp2210" 42 ) 43 44 // PuntPlugin configures VPP punt to host or unix domain socket entries and IP redirect entries using GoVPP. 45 type PuntPlugin struct { 46 Deps 47 48 // handler 49 puntHandler vppcalls.PuntVppAPI 50 51 // descriptors 52 ipRedirectDescriptor *descriptor.IPRedirectDescriptor 53 toHostDescriptor *descriptor.PuntToHostDescriptor 54 puntExceptionDescriptor *descriptor.PuntExceptionDescriptor 55 } 56 57 // Deps lists dependencies of the punt plugin. 58 type Deps struct { 59 infra.PluginDeps 60 KVScheduler kvs.KVScheduler 61 VPP govppmux.API 62 IfPlugin ifplugin.API 63 PublishState datasync.KeyProtoValWriter // optional 64 StatusCheck statuscheck.PluginStatusWriter // optional 65 } 66 67 // Init registers STN-related descriptors. 68 func (p *PuntPlugin) Init() (err error) { 69 // init punt handler 70 p.puntHandler = vppcalls.CompatiblePuntVppHandler(p.VPP, p.IfPlugin.GetInterfaceIndex(), p.Log) 71 72 // init and register IP punt redirect 73 p.ipRedirectDescriptor = descriptor.NewIPRedirectDescriptor(p.puntHandler, p.Log) 74 ipRedirectDescriptor := adapter.NewIPPuntRedirectDescriptor(p.ipRedirectDescriptor.GetDescriptor()) 75 err = p.KVScheduler.RegisterKVDescriptor(ipRedirectDescriptor) 76 if err != nil { 77 return err 78 } 79 80 // init and register punt descriptor 81 p.toHostDescriptor = descriptor.NewPuntToHostDescriptor(p.puntHandler, p.Log) 82 toHostDescriptor := adapter.NewPuntToHostDescriptor(p.toHostDescriptor.GetDescriptor()) 83 err = p.KVScheduler.RegisterKVDescriptor(toHostDescriptor) 84 if err != nil { 85 return err 86 } 87 88 // init and register punt exception descriptor 89 p.puntExceptionDescriptor = descriptor.NewPuntExceptionDescriptor(p.puntHandler, p.Log) 90 exceptionDescriptor := adapter.NewPuntExceptionDescriptor(p.puntExceptionDescriptor.GetDescriptor()) 91 err = p.KVScheduler.RegisterKVDescriptor(exceptionDescriptor) 92 if err != nil { 93 return err 94 } 95 96 // FIXME: temporary workaround for publishing registered sockets 97 p.toHostDescriptor.RegisterSocketFn = func(register bool, toHost *vpp_punt.ToHost, socketPath string) { 98 if p.PublishState == nil { 99 return 100 } 101 key := strings.Replace(models.Key(toHost), "config/", "status/", -1) 102 if register { 103 puntToHost := proto.Clone(toHost).(*vpp_punt.Exception) 104 puntToHost.SocketPath = socketPath 105 if err := p.PublishState.Put(key, puntToHost, datasync.WithClientLifetimeTTL()); err != nil { 106 p.Log.Errorf("publishing registered punt socket failed: %v", err) 107 } 108 } else { 109 if err := p.PublishState.Put(key, nil); err != nil { 110 p.Log.Errorf("publishing unregistered punt socket failed: %v", err) 111 } 112 } 113 } 114 p.puntExceptionDescriptor.RegisterSocketFn = func(register bool, puntExc *vpp_punt.Exception, socketPath string) { 115 if p.PublishState == nil { 116 return 117 } 118 key := strings.Replace(models.Key(puntExc), "config/", "status/", -1) 119 if register { 120 punt := proto.Clone(puntExc).(*vpp_punt.Exception) 121 punt.SocketPath = socketPath 122 if err := p.PublishState.Put(key, punt, datasync.WithClientLifetimeTTL()); err != nil { 123 p.Log.Errorf("publishing registered punt exception socket failed: %v", err) 124 } 125 } else { 126 if err := p.PublishState.Put(key, nil); err != nil { 127 p.Log.Errorf("publishing unregistered punt exception socket failed: %v", err) 128 } 129 } 130 } 131 132 return nil 133 } 134 135 // AfterInit registers plugin with StatusCheck. 136 func (p *PuntPlugin) AfterInit() error { 137 if p.StatusCheck != nil { 138 p.StatusCheck.Register(p.PluginName, nil) 139 } 140 return nil 141 }