go.ligato.io/vpp-agent/v3@v3.5.0/plugins/vpp/l3plugin/vppcalls/vpp2101/l3xc_vppcalls.go (about)

     1  //  Copyright (c) 2020 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 vpp2101
    16  
    17  import (
    18  	"context"
    19  	"io"
    20  	"net"
    21  
    22  	"github.com/pkg/errors"
    23  
    24  	"go.ligato.io/vpp-agent/v3/plugins/vpp"
    25  	"go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2101/fib_types"
    26  	"go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2101/interface_types"
    27  	"go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2101/ip_types"
    28  	"go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2101/l3xc"
    29  	"go.ligato.io/vpp-agent/v3/plugins/vpp/l3plugin/vppcalls"
    30  )
    31  
    32  func (h *L3XCHandler) DumpAllL3XC(ctx context.Context) ([]vppcalls.L3XC, error) {
    33  	return h.DumpL3XC(ctx, ^uint32(0))
    34  }
    35  
    36  func (h *L3XCHandler) DumpL3XC(ctx context.Context, index uint32) ([]vppcalls.L3XC, error) {
    37  	if h.l3xc == nil {
    38  		// no-op when disabled
    39  		return nil, nil
    40  	}
    41  
    42  	dump, err := h.l3xc.L3xcDump(ctx, &l3xc.L3xcDump{
    43  		SwIfIndex: interface_types.InterfaceIndex(index),
    44  	})
    45  	if err != nil {
    46  		return nil, err
    47  	}
    48  	l3xcs := make([]vppcalls.L3XC, 0)
    49  	for {
    50  		recv, err := dump.Recv()
    51  		if err == io.EOF {
    52  			break
    53  		} else if err != nil {
    54  			return nil, err
    55  		}
    56  		paths := make([]vppcalls.Path, len(recv.L3xc.Paths))
    57  		for i, p := range recv.L3xc.Paths {
    58  			var nextHop net.IP
    59  			if p.Proto == fib_types.FIB_API_PATH_NH_PROTO_IP6 {
    60  				ip6Addr := p.Nh.Address.GetIP6()
    61  				nextHop = net.IP(ip6Addr[:]).To16()
    62  			} else {
    63  				ip4Addr := p.Nh.Address.GetIP4()
    64  				nextHop = net.IP(ip4Addr[:4]).To4()
    65  			}
    66  			paths[i] = vppcalls.Path{
    67  				SwIfIndex:  p.SwIfIndex,
    68  				Weight:     p.Weight,
    69  				Preference: p.Preference,
    70  				NextHop:    nextHop,
    71  			}
    72  		}
    73  		l3xcs = append(l3xcs, vppcalls.L3XC{
    74  			SwIfIndex: uint32(recv.L3xc.SwIfIndex),
    75  			IsIPv6:    recv.L3xc.IsIP6,
    76  			Paths:     paths,
    77  		})
    78  	}
    79  	return l3xcs, nil
    80  }
    81  
    82  func (h *L3XCHandler) UpdateL3XC(ctx context.Context, xc *vppcalls.L3XC) error {
    83  	if h.l3xc == nil {
    84  		return errors.Wrap(vpp.ErrPluginDisabled, "l3xc")
    85  	}
    86  
    87  	paths := make([]fib_types.FibPath, len(xc.Paths))
    88  	for i, p := range xc.Paths {
    89  		fibPath := fib_types.FibPath{
    90  			SwIfIndex:  p.SwIfIndex,
    91  			Weight:     p.Weight,
    92  			Preference: p.Preference,
    93  			Type:       fib_types.FIB_API_PATH_TYPE_NORMAL,
    94  		}
    95  		fibPath.Nh, fibPath.Proto = getL3XCFibPathNhAndProto(p.NextHop)
    96  		paths[i] = fibPath
    97  	}
    98  	_, err := h.l3xc.L3xcUpdate(ctx, &l3xc.L3xcUpdate{
    99  		L3xc: l3xc.L3xc{
   100  			SwIfIndex: interface_types.InterfaceIndex(xc.SwIfIndex),
   101  			IsIP6:     xc.IsIPv6,
   102  			Paths:     paths,
   103  		},
   104  	})
   105  	if err != nil {
   106  		return err
   107  	}
   108  	return nil
   109  }
   110  
   111  func (h *L3XCHandler) DeleteL3XC(ctx context.Context, index uint32, ipv6 bool) error {
   112  	if h.l3xc == nil {
   113  		return errors.Wrap(vpp.ErrPluginDisabled, "l3xc")
   114  	}
   115  
   116  	_, err := h.l3xc.L3xcDel(ctx, &l3xc.L3xcDel{
   117  		SwIfIndex: interface_types.InterfaceIndex(index),
   118  		IsIP6:     ipv6,
   119  	})
   120  	if err != nil {
   121  		return err
   122  	}
   123  	return nil
   124  }
   125  
   126  func getL3XCFibPathNhAndProto(netIP net.IP) (nh fib_types.FibPathNh, proto fib_types.FibPathNhProto) {
   127  	var addrUnion ip_types.AddressUnion
   128  	if netIP.To4() == nil {
   129  		proto = fib_types.FIB_API_PATH_NH_PROTO_IP6
   130  		var ip6addr ip_types.IP6Address
   131  		copy(ip6addr[:], netIP.To16())
   132  		addrUnion.SetIP6(ip6addr)
   133  	} else {
   134  		proto = fib_types.FIB_API_PATH_NH_PROTO_IP4
   135  		var ip4addr ip_types.IP4Address
   136  		copy(ip4addr[:], netIP.To4())
   137  		addrUnion.SetIP4(ip4addr)
   138  	}
   139  	return fib_types.FibPathNh{
   140  		Address:            addrUnion,
   141  		ViaLabel:           NextHopViaLabelUnset,
   142  		ClassifyTableIndex: ClassifyTableIndexUnset,
   143  	}, proto
   144  }