go.ligato.io/vpp-agent/v3@v3.5.0/plugins/vpp/ifplugin/vppcalls/vpp2202/wireguard_vppcalls.go (about) 1 // Copyright (c) 2022 Doc.ai 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 vpp2202 16 17 import ( 18 "encoding/base64" 19 "fmt" 20 21 "github.com/pkg/errors" 22 "go.ligato.io/vpp-agent/v3/plugins/vpp" 23 "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2202/interface_types" 24 "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2202/wireguard" 25 "go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin/vppcalls" 26 interfaces "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/interfaces" 27 ) 28 29 // AddWireguardTunnel adds a new wireguard tunnel interface. 30 func (h *InterfaceVppHandler) AddWireguardTunnel(ifName string, wireguardLink *interfaces.WireguardLink) (uint32, error) { 31 invalidIdx := ^uint32(0) 32 if h.wireguard == nil { 33 return invalidIdx, errors.WithMessage(vpp.ErrPluginDisabled, "wireguard") 34 } 35 36 wgItf := wireguard.WireguardInterface{ 37 UserInstance: ^uint32(0), 38 Port: uint16(wireguardLink.Port), 39 } 40 41 genKey := false 42 if len(wireguardLink.PrivateKey) > 0 { 43 publicKeyBin, err := base64.StdEncoding.DecodeString(wireguardLink.PrivateKey) 44 if err != nil { 45 return invalidIdx, err 46 } 47 wgItf.PrivateKey = publicKeyBin 48 } else { 49 genKey = true 50 } 51 52 srcAddr, err := IPToAddress(wireguardLink.SrcAddr) 53 if err != nil { 54 return invalidIdx, err 55 } 56 wgItf.SrcIP = srcAddr 57 58 req := &wireguard.WireguardInterfaceCreate{ 59 Interface: wgItf, 60 GenerateKey: genKey, 61 } 62 63 // prepare reply 64 reply := &wireguard.WireguardInterfaceCreateReply{} 65 // send request and obtain reply 66 if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { 67 return ^uint32(0), err 68 } 69 retSwIfIndex := uint32(reply.SwIfIndex) 70 return retSwIfIndex, h.SetInterfaceTag(ifName, retSwIfIndex) 71 } 72 73 // DeleteWireguardTunnel removes wireguard tunnel interface. 74 func (h *InterfaceVppHandler) DeleteWireguardTunnel(ifName string, ifIdx uint32) error { 75 if h.wireguard == nil { 76 return errors.WithMessage(vpp.ErrPluginDisabled, "wireguard") 77 } 78 79 req := &wireguard.WireguardInterfaceDelete{ 80 SwIfIndex: interface_types.InterfaceIndex(ifIdx), 81 } 82 // prepare reply 83 reply := &wireguard.WireguardInterfaceDeleteReply{} 84 // send request and obtain reply 85 86 if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { 87 return err 88 } 89 return h.RemoveInterfaceTag(ifName, ifIdx) 90 } 91 92 // dumpWireguardDetails dumps wireguard interface details from VPP. 93 func (h *InterfaceVppHandler) dumpWireguardDetails(ifc map[uint32]*vppcalls.InterfaceDetails) error { 94 if h.wireguard == nil { 95 return nil 96 } 97 98 reqCtx := h.callsChannel.SendMultiRequest(&wireguard.WireguardInterfaceDump{}) 99 100 for { 101 wgDetails := &wireguard.WireguardInterfaceDetails{} 102 stop, err := reqCtx.ReceiveReply(wgDetails) 103 if stop { 104 break // Break from the loop. 105 } 106 if err != nil { 107 return fmt.Errorf("failed to dump wireguard interface details: %v", err) 108 } 109 _, ifIdxExists := ifc[uint32(wgDetails.Interface.SwIfIndex)] 110 if !ifIdxExists { 111 h.log.Warnf("Wireguard interface dump: interface name for index %d not found", wgDetails.Interface.SwIfIndex) 112 continue 113 } 114 115 wgLink := &interfaces.WireguardLink{ 116 Port: uint32(wgDetails.Interface.Port), 117 } 118 wgLink.PrivateKey = base64.StdEncoding.EncodeToString(wgDetails.Interface.PrivateKey) 119 120 srcAddr := wgDetails.Interface.SrcIP.ToIP() 121 if !srcAddr.IsUnspecified() { 122 wgLink.SrcAddr = srcAddr.String() 123 } 124 125 ifc[uint32(wgDetails.Interface.SwIfIndex)].Interface.Link = &interfaces.Interface_Wireguard{Wireguard: wgLink} 126 ifc[uint32(wgDetails.Interface.SwIfIndex)].Interface.Type = interfaces.Interface_WIREGUARD_TUNNEL 127 } 128 return nil 129 }