go.ligato.io/vpp-agent/v3@v3.5.0/plugins/vpp/stnplugin/vppcalls/vpp2106/stn_vppcalls.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 package vpp2106 16 17 import ( 18 "fmt" 19 "net" 20 "strings" 21 22 "github.com/pkg/errors" 23 24 "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2106/interface_types" 25 "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2106/ip_types" 26 vpp_stn "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2106/stn" 27 stn "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/stn" 28 ) 29 30 // AddSTNRule implements STN handler, adds a new STN rule to the VPP. 31 func (h *StnVppHandler) AddSTNRule(stnRule *stn.Rule) error { 32 return h.addDelStnRule(stnRule, true) 33 } 34 35 // DeleteSTNRule implements STN handler, removes the provided STN rule from the VPP. 36 func (h *StnVppHandler) DeleteSTNRule(stnRule *stn.Rule) error { 37 return h.addDelStnRule(stnRule, false) 38 } 39 40 func (h *StnVppHandler) addDelStnRule(stnRule *stn.Rule, isAdd bool) error { 41 // get interface index 42 ifaceMeta, found := h.ifIndexes.LookupByName(stnRule.Interface) 43 if !found { 44 return errors.New("failed to get interface metadata") 45 } 46 swIfIndex := ifaceMeta.GetIndex() 47 48 // remove mask from IP address if necessary 49 ipAddr := stnRule.IpAddress 50 ipParts := strings.Split(ipAddr, "/") 51 if len(ipParts) > 1 { 52 h.log.Debugf("STN IP address %s is defined with mask, removing it") 53 ipAddr = ipParts[0] 54 } 55 56 // parse IP address 57 ip, err := ipToAddress(ipAddr) 58 if err != nil { 59 return err 60 } 61 62 // add STN rule 63 req := &vpp_stn.StnAddDelRule{ 64 IPAddress: ip, 65 SwIfIndex: interface_types.InterfaceIndex(swIfIndex), 66 IsAdd: isAdd, 67 } 68 reply := &vpp_stn.StnAddDelRuleReply{} 69 70 if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { 71 return err 72 } 73 74 return nil 75 76 } 77 78 func ipToAddress(address string) (dhcpAddr ip_types.Address, err error) { 79 netIP := net.ParseIP(address) 80 if netIP == nil { 81 return ip_types.Address{}, fmt.Errorf("invalid IP: %q", address) 82 } 83 if ip4 := netIP.To4(); ip4 == nil { 84 dhcpAddr.Af = ip_types.ADDRESS_IP6 85 var ip6addr ip_types.IP6Address 86 copy(ip6addr[:], netIP.To16()) 87 dhcpAddr.Un.SetIP6(ip6addr) 88 } else { 89 dhcpAddr.Af = ip_types.ADDRESS_IP4 90 var ip4addr ip_types.IP4Address 91 copy(ip4addr[:], ip4) 92 dhcpAddr.Un.SetIP4(ip4addr) 93 } 94 return 95 }