go.ligato.io/vpp-agent/v3@v3.5.0/plugins/vpp/aclplugin/descriptor/acl_to_interface.go (about)

     1  package descriptor
     2  
     3  import (
     4  	"github.com/pkg/errors"
     5  	"go.ligato.io/cn-infra/v2/logging"
     6  	"google.golang.org/protobuf/proto"
     7  
     8  	kvs "go.ligato.io/vpp-agent/v3/plugins/kvscheduler/api"
     9  	"go.ligato.io/vpp-agent/v3/plugins/vpp/aclplugin/aclidx"
    10  	"go.ligato.io/vpp-agent/v3/plugins/vpp/aclplugin/vppcalls"
    11  	acl "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/acl"
    12  	interfaces "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/interfaces"
    13  )
    14  
    15  const (
    16  	// ACLToInterfaceDescriptorName is name for descriptor
    17  	ACLToInterfaceDescriptorName = "vpp-acl-to-interface"
    18  
    19  	// dependency labels
    20  	interfaceDep = "interface-exists"
    21  )
    22  
    23  // ACLToInterfaceDescriptor represents assignment of ACL to interface.
    24  type ACLToInterfaceDescriptor struct {
    25  	log        logging.Logger
    26  	aclHandler vppcalls.ACLVppAPI
    27  	aclIndex   aclidx.ACLMetadataIndex
    28  }
    29  
    30  // NewACLToInterfaceDescriptor returns new ACLInterface descriptor
    31  func NewACLToInterfaceDescriptor(aclIndex aclidx.ACLMetadataIndex, aclHandler vppcalls.ACLVppAPI,
    32  	log logging.PluginLogger) *ACLToInterfaceDescriptor {
    33  	return &ACLToInterfaceDescriptor{
    34  		log:        log,
    35  		aclIndex:   aclIndex,
    36  		aclHandler: aclHandler,
    37  	}
    38  }
    39  
    40  // GetDescriptor returns descriptor suitable for registration with the KVScheduler.
    41  func (d *ACLToInterfaceDescriptor) GetDescriptor() *kvs.KVDescriptor {
    42  	return &kvs.KVDescriptor{
    43  		Name:         ACLToInterfaceDescriptorName,
    44  		KeySelector:  d.IsACLInterfaceKey,
    45  		Create:       d.Create,
    46  		Delete:       d.Delete,
    47  		Dependencies: d.Dependencies,
    48  	}
    49  }
    50  
    51  // IsACLInterfaceKey returns true if the key is identifying ACL interface (derived value)
    52  func (d *ACLToInterfaceDescriptor) IsACLInterfaceKey(key string) bool {
    53  	_, _, _, isACLToInterfaceKey := acl.ParseACLToInterfaceKey(key)
    54  	return isACLToInterfaceKey
    55  }
    56  
    57  // Create binds interface to ACL.
    58  func (d *ACLToInterfaceDescriptor) Create(key string, emptyVal proto.Message) (metadata kvs.Metadata, err error) {
    59  	aclName, ifName, flow, _ := acl.ParseACLToInterfaceKey(key)
    60  
    61  	aclMeta, found := d.aclIndex.LookupByName(aclName)
    62  	if !found {
    63  		err = errors.Errorf("failed to obtain metadata for ACL %s", aclName)
    64  		d.log.Error(err)
    65  		return nil, err
    66  	}
    67  
    68  	if aclMeta.L2 {
    69  		// MACIP ACL (L2)
    70  		if err := d.aclHandler.AddMACIPACLToInterface(aclMeta.Index, ifName); err != nil {
    71  			d.log.Error(err)
    72  			return nil, err
    73  		}
    74  	} else {
    75  		// ACL (L3/L4)
    76  		if flow == acl.IngressFlow {
    77  			if err := d.aclHandler.AddACLToInterfaceAsIngress(aclMeta.Index, ifName); err != nil {
    78  				d.log.Error(err)
    79  				return nil, err
    80  			}
    81  		} else if flow == acl.EgressFlow {
    82  			if err := d.aclHandler.AddACLToInterfaceAsEgress(aclMeta.Index, ifName); err != nil {
    83  				d.log.Error(err)
    84  				return nil, err
    85  			}
    86  		}
    87  	}
    88  
    89  	return nil, nil
    90  }
    91  
    92  // Delete unbinds interface from ACL.
    93  func (d *ACLToInterfaceDescriptor) Delete(key string, emptyVal proto.Message, metadata kvs.Metadata) error {
    94  	aclName, ifName, flow, _ := acl.ParseACLToInterfaceKey(key)
    95  
    96  	aclMeta, found := d.aclIndex.LookupByName(aclName)
    97  	if !found {
    98  		err := errors.Errorf("failed to obtain metadata for ACL %s", aclName)
    99  		d.log.Error(err)
   100  		return err
   101  	}
   102  
   103  	if aclMeta.L2 {
   104  		// MACIP ACL (L2)
   105  		if err := d.aclHandler.DeleteMACIPACLFromInterface(aclMeta.Index, ifName); err != nil {
   106  			d.log.Error(err)
   107  			return err
   108  		}
   109  	} else {
   110  		// ACL (L3/L4)
   111  		if flow == acl.IngressFlow {
   112  			if err := d.aclHandler.DeleteACLFromInterfaceAsIngress(aclMeta.Index, ifName); err != nil {
   113  				d.log.Error(err)
   114  				return err
   115  			}
   116  		} else if flow == acl.EgressFlow {
   117  			if err := d.aclHandler.DeleteACLFromInterfaceAsEgress(aclMeta.Index, ifName); err != nil {
   118  				d.log.Error(err)
   119  				return err
   120  			}
   121  		}
   122  	}
   123  
   124  	return nil
   125  }
   126  
   127  // Dependencies lists the interface as the only dependency for the binding.
   128  func (d *ACLToInterfaceDescriptor) Dependencies(key string, emptyVal proto.Message) []kvs.Dependency {
   129  	_, ifName, _, _ := acl.ParseACLToInterfaceKey(key)
   130  	return []kvs.Dependency{
   131  		{
   132  			Label: interfaceDep,
   133  			Key:   interfaces.InterfaceKey(ifName),
   134  		},
   135  	}
   136  }