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