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  }