go.ligato.io/vpp-agent/v3@v3.5.0/plugins/vpp/ipfixplugin/vppcalls/vpp2106/ipfix_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  	"bytes"
    19  	"errors"
    20  	"fmt"
    21  	"net"
    22  
    23  	"go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2106/ip_types"
    24  	vpp_ipfix "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2106/ipfix_export"
    25  	"go.ligato.io/vpp-agent/v3/plugins/vpp/ipfixplugin/vppcalls"
    26  	ipfix "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipfix"
    27  )
    28  
    29  // SetExporter configures IP Flow Information eXport (IPFIX).
    30  func (h *IpfixVppHandler) SetExporter(conf *ipfix.IPFIX) error {
    31  	collectorAddr, err := prepareAddress(conf.GetCollector().GetAddress())
    32  	if err != nil {
    33  		return fmt.Errorf("bad collector address: %v", err)
    34  	}
    35  
    36  	sourceAddr, err := prepareAddress(conf.GetSourceAddress())
    37  	if err != nil {
    38  		return fmt.Errorf("bad source address: %v", err)
    39  	}
    40  
    41  	collectorPort := uint16(conf.GetCollector().GetPort())
    42  	if collectorPort == 0 {
    43  		// Will be set by VPP to the default value: 4739.
    44  		collectorPort = ^uint16(0)
    45  	}
    46  
    47  	mtu := conf.GetPathMtu()
    48  	if mtu == 0 {
    49  		// Will be set by VPP to the default value: 512 bytes.
    50  		mtu = ^uint32(0)
    51  	} else if mtu < vppcalls.MinPathMTU || mtu > vppcalls.MaxPathMTU {
    52  		err := errors.New("path MTU is not in allowed range")
    53  		return err
    54  	}
    55  
    56  	tmplInterval := conf.GetTemplateInterval()
    57  	if tmplInterval == 0 {
    58  		// Will be set by VPP to the default value: 20 sec.
    59  		tmplInterval = ^uint32(0)
    60  	}
    61  
    62  	req := &vpp_ipfix.SetIpfixExporter{
    63  		CollectorAddress: collectorAddr,
    64  		CollectorPort:    collectorPort,
    65  		SrcAddress:       sourceAddr,
    66  		VrfID:            conf.GetVrfId(),
    67  		PathMtu:          mtu,
    68  		TemplateInterval: tmplInterval,
    69  	}
    70  	reply := &vpp_ipfix.SetIpfixExporterReply{}
    71  
    72  	if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil {
    73  		return err
    74  	}
    75  
    76  	return nil
    77  }
    78  
    79  // prepareAddress validates and converts IP address, defined as a string,
    80  // to the type which represents address in VPP binary API.
    81  func prepareAddress(addrStr string) (ip_types.Address, error) {
    82  	var a ip_types.Address
    83  
    84  	addr := net.ParseIP(addrStr)
    85  	if addr == nil {
    86  		err := errors.New("can not parse address")
    87  		return a, err
    88  	}
    89  	if addr.To4() == nil {
    90  		err := errors.New("IPv6 is not supported")
    91  		return a, err
    92  	}
    93  
    94  	var addrBytes [4]byte
    95  	copy(addrBytes[:], addr.To4())
    96  	if bytes.Equal(addrBytes[:], []byte{0, 0, 0, 0}) {
    97  		err := errors.New("address must not be all zeros")
    98  		return a, err
    99  	}
   100  
   101  	a = ip_types.Address{
   102  		Af: ip_types.ADDRESS_IP4,
   103  		Un: ip_types.AddressUnionIP4(addrBytes),
   104  	}
   105  
   106  	return a, nil
   107  }