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