go.ligato.io/vpp-agent/v3@v3.5.0/plugins/linux/ifplugin/descriptor/interface_vrfdev.go (about)

     1  // Copyright (c) 2020 Pantheon.tech
     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 descriptor
    16  
    17  import (
    18  	"fmt"
    19  	"github.com/pkg/errors"
    20  	"go.ligato.io/vpp-agent/v3/plugins/linux/ifplugin/linuxcalls"
    21  
    22  	"go.ligato.io/vpp-agent/v3/plugins/linux/ifplugin/ifaceidx"
    23  	nslinuxcalls "go.ligato.io/vpp-agent/v3/plugins/linux/nsplugin/linuxcalls"
    24  	interfaces "go.ligato.io/vpp-agent/v3/proto/ligato/linux/interfaces"
    25  )
    26  
    27  const (
    28  	// Enabling this option allows a “global” listen socket to work across L3 master domains (e.g., VRFs).
    29  	sysctlL3MDevVar = "net.ipv4.tcp_l3mdev_accept"
    30  )
    31  
    32  // createVRF creates a new VRF network device.
    33  func (d *InterfaceDescriptor) createVRF(
    34  	nsCtx nslinuxcalls.NamespaceMgmtCtx, linuxIf *interfaces.Interface,
    35  ) (md *ifaceidx.LinuxIfMetadata, err error) {
    36  	hostName := getHostIfName(linuxIf)
    37  	rt := linuxIf.GetVrfDev().GetRoutingTable()
    38  	agentPrefix := d.serviceLabel.GetAgentPrefix()
    39  
    40  	// move to the namespace with the interface
    41  	revert, err := d.nsPlugin.SwitchToNamespace(nsCtx, linuxIf.Namespace)
    42  	if err != nil {
    43  		d.log.Error("switch to namespace failed:", err)
    44  		return nil, err
    45  	}
    46  	defer revert()
    47  
    48  	// Enable child sockets to inherit the L3 master device index.
    49  	// Without this VRF cannot really be used.
    50  	err = d.enableL3MasterDev()
    51  	if err != nil {
    52  		return nil, err
    53  	}
    54  
    55  	// create a new VRF device
    56  	err = d.ifHandler.AddVRFDevice(hostName, rt)
    57  	if err != nil {
    58  		return nil, errors.WithMessagef(err, "failed to add VRF device %s (rt: %d)", hostName, rt)
    59  	}
    60  
    61  	// add alias
    62  	err = d.ifHandler.SetInterfaceAlias(hostName, agentPrefix+linuxcalls.GetVRFAlias(linuxIf))
    63  	if err != nil {
    64  		return nil, errors.WithMessagef(err, "error setting VRF %s alias", hostName)
    65  	}
    66  
    67  	// build metadata
    68  	link, err := d.ifHandler.GetLinkByName(hostName)
    69  	if err != nil {
    70  		return nil, errors.WithMessagef(err, "error getting link %s", hostName)
    71  	}
    72  
    73  	return &ifaceidx.LinuxIfMetadata{
    74  		Namespace:    linuxIf.Namespace,
    75  		LinuxIfIndex: link.Attrs().Index,
    76  		HostIfName:   hostName,
    77  		VrfDevRT:     rt,
    78  	}, nil
    79  }
    80  
    81  // deleteVRF removes VRF network device.
    82  func (d *InterfaceDescriptor) deleteVRF(linuxIf *interfaces.Interface) error {
    83  	hostName := getHostIfName(linuxIf)
    84  	err := d.ifHandler.DeleteInterface(hostName)
    85  	if err != nil {
    86  		d.log.Error(err)
    87  		return err
    88  	}
    89  	return nil
    90  }
    91  
    92  func (d *InterfaceDescriptor) enableL3MasterDev() error {
    93  	value, err := getSysctl(sysctlL3MDevVar)
    94  	if err != nil {
    95  		err = fmt.Errorf("could not read sysctl value for %s: %w",
    96  			sysctlL3MDevVar, err)
    97  		return err
    98  	}
    99  	if value == "0" {
   100  		_, err = setSysctl(sysctlL3MDevVar, "1")
   101  		if err != nil {
   102  			err = fmt.Errorf("failed to enable %s: %w", sysctlL3MDevVar, err)
   103  			return err
   104  		}
   105  	}
   106  	return nil
   107  }