go.ligato.io/vpp-agent/v3@v3.5.0/plugins/vpp/ifplugin/vppcalls/vpp2202/gre_vppcalls.go (about) 1 // Copyright (c) 2022 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 vpp2202 16 17 import ( 18 "errors" 19 "net" 20 21 vpp_gre "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2202/gre" 22 "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2202/ip_types" 23 "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2202/tunnel_types" 24 ifs "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/interfaces" 25 ) 26 27 func (h *InterfaceVppHandler) greAddDelTunnel(isAdd bool, greLink *ifs.GreLink) (uint32, error) { 28 if greLink.TunnelType == ifs.GreLink_UNKNOWN { 29 err := errors.New("bad GRE tunnel type") 30 return 0, err 31 } 32 33 greSource := net.ParseIP(greLink.SrcAddr) 34 if greSource == nil { 35 err := errors.New("bad source address for GRE tunnel") 36 return 0, err 37 } 38 greDestination := net.ParseIP(greLink.DstAddr) 39 if greDestination == nil { 40 err := errors.New("bad destination address for GRE tunnel") 41 return 0, err 42 } 43 44 if greLink.SrcAddr == greLink.DstAddr { 45 err := errors.New("source and destination are the same") 46 return 0, err 47 } 48 49 if greLink.TunnelType == ifs.GreLink_ERSPAN && greLink.SessionId > 1023 { 50 err := errors.New("set session id for ERSPAN tunnel type") 51 return 0, err 52 } 53 54 var tt vpp_gre.GreTunnelType 55 switch greLink.TunnelType { 56 case ifs.GreLink_L3: 57 tt = vpp_gre.GRE_API_TUNNEL_TYPE_L3 58 case ifs.GreLink_TEB: 59 tt = vpp_gre.GRE_API_TUNNEL_TYPE_TEB 60 case ifs.GreLink_ERSPAN: 61 tt = vpp_gre.GRE_API_TUNNEL_TYPE_ERSPAN 62 default: 63 return 0, errors.New("bad GRE tunnel type") 64 } 65 66 tunnel := vpp_gre.GreTunnel{ 67 Type: tt, 68 Mode: tunnel_types.TUNNEL_API_MODE_P2P, // TODO: add mode to proto model 69 Instance: ^uint32(0), 70 OuterTableID: greLink.OuterFibId, 71 SessionID: uint16(greLink.SessionId), 72 } 73 74 var isSrcIPv6, isDstIPv6 bool 75 76 if greSource.To4() == nil { 77 isSrcIPv6 = true 78 } 79 if greDestination.To4() == nil { 80 isDstIPv6 = true 81 } 82 if isSrcIPv6 != isDstIPv6 { 83 return 0, errors.New("source and destination addresses must be both either in IPv4 or IPv6") 84 } 85 86 if isSrcIPv6 { 87 var src, dst [16]uint8 88 copy(src[:], greSource.To16()) 89 copy(dst[:], greDestination.To16()) 90 tunnel.Src = ip_types.Address{ 91 Af: ip_types.ADDRESS_IP6, 92 Un: ip_types.AddressUnionIP6(src), 93 } 94 tunnel.Dst = ip_types.Address{ 95 Af: ip_types.ADDRESS_IP6, 96 Un: ip_types.AddressUnionIP6(dst), 97 } 98 } else { 99 var src, dst [4]uint8 100 copy(src[:], greSource.To4()) 101 copy(dst[:], greDestination.To4()) 102 tunnel.Src = ip_types.Address{ 103 Af: ip_types.ADDRESS_IP4, 104 Un: ip_types.AddressUnionIP4(src), 105 } 106 tunnel.Dst = ip_types.Address{ 107 Af: ip_types.ADDRESS_IP4, 108 Un: ip_types.AddressUnionIP4(dst), 109 } 110 } 111 112 req := &vpp_gre.GreTunnelAddDel{ 113 IsAdd: isAdd, 114 Tunnel: tunnel, 115 } 116 reply := &vpp_gre.GreTunnelAddDelReply{} 117 118 if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { 119 return 0, err 120 } 121 return uint32(reply.SwIfIndex), nil 122 } 123 124 // AddGreTunnel adds new GRE interface. 125 func (h *InterfaceVppHandler) AddGreTunnel(ifName string, greLink *ifs.GreLink) (uint32, error) { 126 swIfIndex, err := h.greAddDelTunnel(true, greLink) 127 if err != nil { 128 return 0, err 129 } 130 return swIfIndex, h.SetInterfaceTag(ifName, swIfIndex) 131 } 132 133 // DelGreTunnel removes GRE interface. 134 func (h *InterfaceVppHandler) DelGreTunnel(ifName string, greLink *ifs.GreLink) (uint32, error) { 135 swIfIndex, err := h.greAddDelTunnel(false, greLink) 136 if err != nil { 137 return 0, err 138 } 139 return swIfIndex, h.RemoveInterfaceTag(ifName, swIfIndex) 140 }