go.ligato.io/vpp-agent/v3@v3.5.0/plugins/vpp/l3plugin/vppcalls/vpp2202/vrrp_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  	"fmt"
    19  
    20  	"go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2202/interface_types"
    21  	"go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2202/ip_types"
    22  	"go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2202/vrrp"
    23  	l3 "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l3"
    24  )
    25  
    26  const (
    27  	centiMilliRatio uint32 = 10
    28  )
    29  
    30  func (h *VrrpVppHandler) vppAddDelVrrp(entry *l3.VRRPEntry, isAdd uint8) error {
    31  	var addrs []ip_types.Address
    32  	var isIpv6 bool
    33  	for idx, addr := range entry.IpAddresses {
    34  		ip, err := ip_types.ParseAddress(addr)
    35  		if err != nil {
    36  			return err
    37  		}
    38  
    39  		if idx == 0 && ip.Af == ip_types.ADDRESS_IP6 {
    40  			isIpv6 = true
    41  		}
    42  
    43  		addrs = append(addrs, ip)
    44  	}
    45  
    46  	md, exist := h.ifIndexes.LookupByName(entry.Interface)
    47  	if !exist {
    48  		return fmt.Errorf("interface does not exist: %v", entry.Interface)
    49  	}
    50  
    51  	var flags uint32
    52  	if entry.Preempt {
    53  		flags |= uint32(vrrp.VRRP_API_VR_PREEMPT)
    54  	}
    55  	if entry.Accept {
    56  		flags |= uint32(vrrp.VRRP_API_VR_ACCEPT)
    57  	}
    58  	if entry.Unicast {
    59  		flags |= uint32(vrrp.VRRP_API_VR_UNICAST)
    60  	}
    61  	if isIpv6 {
    62  		flags |= uint32(vrrp.VRRP_API_VR_IPV6)
    63  	}
    64  
    65  	req := &vrrp.VrrpVrAddDel{
    66  		IsAdd:     isAdd,
    67  		SwIfIndex: interface_types.InterfaceIndex(md.SwIfIndex),
    68  		VrID:      uint8(entry.GetVrId()),
    69  		Priority:  uint8(entry.GetPriority()),
    70  		Interval:  uint16(entry.GetInterval() / centiMilliRatio),
    71  		Flags:     vrrp.VrrpVrFlags(flags),
    72  		NAddrs:    uint8(len(addrs)),
    73  		Addrs:     addrs,
    74  	}
    75  
    76  	reply := &vrrp.VrrpVrAddDelReply{}
    77  	if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil {
    78  		return err
    79  	}
    80  
    81  	return nil
    82  }
    83  
    84  // VppAddVrrp implements VRRP handler.
    85  func (h *VrrpVppHandler) VppAddVrrp(entry *l3.VRRPEntry) error {
    86  	return h.vppAddDelVrrp(entry, 1)
    87  }
    88  
    89  // VppDelVrrp implements VRRP handler.
    90  func (h *VrrpVppHandler) VppDelVrrp(entry *l3.VRRPEntry) error {
    91  	return h.vppAddDelVrrp(entry, 0)
    92  }
    93  
    94  func (h *VrrpVppHandler) vppStartStopVrrp(entry *l3.VRRPEntry, isStart uint8) error {
    95  
    96  	md, exist := h.ifIndexes.LookupByName(entry.Interface)
    97  	if !exist {
    98  		return fmt.Errorf("interface does not exist: %v", entry.Interface)
    99  	}
   100  
   101  	var isIpv6 bool
   102  	for idx, addr := range entry.IpAddresses {
   103  		ip, err := ipToAddress(addr)
   104  		if err != nil {
   105  			return err
   106  		}
   107  
   108  		if idx == 0 && ip.Af == ip_types.ADDRESS_IP6 {
   109  			isIpv6 = true
   110  		}
   111  	}
   112  
   113  	req := &vrrp.VrrpVrStartStop{
   114  		SwIfIndex: interface_types.InterfaceIndex(md.SwIfIndex),
   115  		VrID:      uint8(entry.VrId),
   116  		IsIPv6:    boolToUint(isIpv6),
   117  		IsStart:   isStart,
   118  	}
   119  
   120  	reply := &vrrp.VrrpVrStartStopReply{}
   121  	if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil {
   122  		return err
   123  	}
   124  
   125  	return nil
   126  }
   127  
   128  // VppStartVrrp implements VRRP handler.
   129  func (h *VrrpVppHandler) VppStartVrrp(entry *l3.VRRPEntry) error {
   130  	return h.vppStartStopVrrp(entry, 1)
   131  }
   132  
   133  // VppStopVrrp implements VRRP handler.
   134  func (h *VrrpVppHandler) VppStopVrrp(entry *l3.VRRPEntry) error {
   135  	return h.vppStartStopVrrp(entry, 0)
   136  }