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

     1  // Copyright (c) 2019 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 descriptor
    16  
    17  import (
    18  	"go.ligato.io/vpp-agent/v3/plugins/linux/ifplugin/ifaceidx"
    19  	interfaces "go.ligato.io/vpp-agent/v3/proto/ligato/linux/interfaces"
    20  
    21  	"strings"
    22  
    23  	nslinuxcalls "go.ligato.io/vpp-agent/v3/plugins/linux/nsplugin/linuxcalls"
    24  )
    25  
    26  const unconfiguredAlias = "unconfigured"
    27  
    28  // createLoopback adds logical name as alias to linux loopback interface
    29  func (d *InterfaceDescriptor) createLoopback(nsCtx nslinuxcalls.NamespaceMgmtCtx,
    30  	linuxIf *interfaces.Interface) (metadata *ifaceidx.LinuxIfMetadata, err error) {
    31  
    32  	hostName := getHostIfName(linuxIf)
    33  	agentPrefix := d.serviceLabel.GetAgentPrefix()
    34  
    35  	if linuxIf.Namespace != nil {
    36  		revert, err := d.nsPlugin.SwitchToNamespace(nsCtx, linuxIf.Namespace)
    37  		if err != nil {
    38  			d.log.Error(err)
    39  			return nil, err
    40  		}
    41  		defer revert()
    42  	}
    43  
    44  	// in each network namespace there is exactly one loopback interface,
    45  	// multiple configurations for a single namespaces is not valid
    46  	alias, err := d.getLoopbackAlias(nsCtx, linuxIf)
    47  	if err != nil {
    48  		d.log.Error(err)
    49  		return nil, ErrLoopbackNotFound
    50  	}
    51  	if alias != "" && alias != linuxIf.Name && alias != unconfiguredAlias {
    52  		d.log.Errorf("loopback already configured using logical name '%v'", alias)
    53  		return nil, ErrLoopbackAlreadyConfigured
    54  	}
    55  
    56  	// add alias in order to include loopback in retrieve output
    57  	err = d.ifHandler.SetInterfaceAlias(hostName, agentPrefix+linuxIf.Name)
    58  	if err != nil {
    59  		d.log.Error(err)
    60  		return nil, err
    61  	}
    62  
    63  	link, err := d.ifHandler.GetLinkByName(hostName)
    64  	if err != nil {
    65  		d.log.Error(err)
    66  		return nil, err
    67  	}
    68  
    69  	metadata = &ifaceidx.LinuxIfMetadata{
    70  		Namespace:    linuxIf.Namespace,
    71  		LinuxIfIndex: link.Attrs().Index,
    72  	}
    73  
    74  	return metadata, nil
    75  }
    76  
    77  // deleteLoopback clear associated interface alias
    78  func (d *InterfaceDescriptor) deleteLoopback(nsCtx nslinuxcalls.NamespaceMgmtCtx, linuxIf *interfaces.Interface) error {
    79  	hostName := getHostIfName(linuxIf)
    80  
    81  	if linuxIf.Namespace != nil {
    82  		revert, err := d.nsPlugin.SwitchToNamespace(nsCtx, linuxIf.Namespace)
    83  		if err != nil {
    84  			d.log.Error(err)
    85  			return err
    86  		}
    87  		defer revert()
    88  	}
    89  
    90  	// remove interface alias
    91  	// - actually vishvananda/netlink does not support alias removal, so we just change
    92  	//   it to a string which is not prefixed with agent label
    93  	err := d.ifHandler.SetInterfaceAlias(hostName, unconfiguredAlias)
    94  	if err != nil {
    95  		d.log.Error(err)
    96  		return err
    97  	}
    98  
    99  	return nil
   100  }
   101  
   102  // getLoopbackAlias returns alias associated with the loopback
   103  func (d *InterfaceDescriptor) getLoopbackAlias(nsCtx nslinuxcalls.NamespaceMgmtCtx, linuxIf *interfaces.Interface) (string, error) {
   104  	if linuxIf.Namespace != nil {
   105  		revert, err := d.nsPlugin.SwitchToNamespace(nsCtx, linuxIf.Namespace)
   106  		if err != nil {
   107  			d.log.Error(err)
   108  			return "", err
   109  		}
   110  		defer revert()
   111  	}
   112  
   113  	link, err := d.ifHandler.GetLinkByName(getHostIfName(linuxIf))
   114  	if err != nil {
   115  		d.log.Error(err)
   116  		return "", err
   117  	}
   118  	return strings.TrimPrefix(link.Attrs().Alias, d.serviceLabel.GetAgentPrefix()), nil
   119  }