github.com/cilium/cilium@v1.16.2/pkg/hubble/filters/filters.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Hubble
     3  
     4  package filters
     5  
     6  import (
     7  	"context"
     8  
     9  	"github.com/sirupsen/logrus"
    10  
    11  	flowpb "github.com/cilium/cilium/api/v1/flow"
    12  	v1 "github.com/cilium/cilium/pkg/hubble/api/v1"
    13  )
    14  
    15  // FilterFunc is the function will be used to filter the given data.
    16  // Should return true if the filter is hit, false otherwise.
    17  type FilterFunc func(ev *v1.Event) bool
    18  
    19  // FilterFuncs is a combination of multiple filters, typically applied together.
    20  type FilterFuncs []FilterFunc
    21  
    22  // Apply filters the flow with the given white- and blacklist. Returns true
    23  // if the flow should be included in the result.
    24  func Apply(whitelist, blacklist FilterFuncs, ev *v1.Event) bool {
    25  	return whitelist.MatchOne(ev) && blacklist.MatchNone(ev)
    26  }
    27  
    28  // MatchAll returns true if all the filters match the provided data, i.e. AND.
    29  func (fs FilterFuncs) MatchAll(ev *v1.Event) bool {
    30  	for _, f := range fs {
    31  		if !f(ev) {
    32  			return false
    33  		}
    34  	}
    35  	return true
    36  }
    37  
    38  // MatchOne returns true if at least one of the filters match the provided data or
    39  // if no filters are specified, i.e. OR.
    40  func (fs FilterFuncs) MatchOne(ev *v1.Event) bool {
    41  	if len(fs) == 0 {
    42  		return true
    43  	}
    44  
    45  	for _, f := range fs {
    46  		if f(ev) {
    47  			return true
    48  		}
    49  	}
    50  	return false
    51  }
    52  
    53  // MatchNone returns true if none of the filters match the provided data or
    54  // if no filters are specified, i.e. NOR
    55  func (fs FilterFuncs) MatchNone(ev *v1.Event) bool {
    56  	if len(fs) == 0 {
    57  		return true
    58  	}
    59  
    60  	for _, f := range fs {
    61  		if f(ev) {
    62  			return false
    63  		}
    64  	}
    65  	return true
    66  }
    67  
    68  // OnBuildFilter is invoked while building a flow filter
    69  type OnBuildFilter interface {
    70  	OnBuildFilter(context.Context, *flowpb.FlowFilter) ([]FilterFunc, error)
    71  }
    72  
    73  // OnBuildFilterFunc implements OnBuildFilter for a single function
    74  type OnBuildFilterFunc func(context.Context, *flowpb.FlowFilter) ([]FilterFunc, error)
    75  
    76  // OnBuildFilter is invoked while building a flow filter
    77  func (f OnBuildFilterFunc) OnBuildFilter(ctx context.Context, flow *flowpb.FlowFilter) ([]FilterFunc, error) {
    78  	return f(ctx, flow)
    79  }
    80  
    81  // BuildFilter builds a filter based on a FlowFilter. It returns:
    82  //   - the FilterFunc to be used to filter packets based on the requested
    83  //     FlowFilter;
    84  //   - an error in case something went wrong.
    85  func BuildFilter(ctx context.Context, ff *flowpb.FlowFilter, auxFilters []OnBuildFilter) (FilterFuncs, error) {
    86  	var fs []FilterFunc
    87  
    88  	for _, f := range auxFilters {
    89  		fl, err := f.OnBuildFilter(ctx, ff)
    90  		if err != nil {
    91  			return nil, err
    92  		}
    93  		if fl != nil {
    94  			fs = append(fs, fl...)
    95  		}
    96  	}
    97  
    98  	return fs, nil
    99  }
   100  
   101  // BuildFilterList constructs a list of filter functions representing the list
   102  // of FlowFilter. It returns:
   103  //   - the FilterFunc to be used to filter packets based on the requested
   104  //     FlowFilter;
   105  //   - an error in case something went wrong.
   106  func BuildFilterList(ctx context.Context, ff []*flowpb.FlowFilter, auxFilters []OnBuildFilter) (FilterFuncs, error) {
   107  	filterList := make([]FilterFunc, 0, len(ff))
   108  
   109  	for _, flowFilter := range ff {
   110  		// Build filter matching on all requirements of the FlowFilter
   111  		tf, err := BuildFilter(ctx, flowFilter, auxFilters)
   112  		if err != nil {
   113  			return nil, err
   114  		}
   115  
   116  		// All filters representing a FlowFilter must match
   117  		filterFunc := func(ev *v1.Event) bool {
   118  			return tf.MatchAll(ev)
   119  		}
   120  
   121  		filterList = append(filterList, filterFunc)
   122  	}
   123  
   124  	return filterList, nil
   125  }
   126  
   127  // DefaultFilters is the list of default filters
   128  func DefaultFilters(log logrus.FieldLogger) []OnBuildFilter {
   129  	return []OnBuildFilter{
   130  		&UUIDFilter{},
   131  		&EventTypeFilter{},
   132  		&VerdictFilter{},
   133  		&DropReasonDescFilter{},
   134  		&ReplyFilter{},
   135  		&IdentityFilter{},
   136  		&ProtocolFilter{},
   137  		&IPFilter{},
   138  		&PodFilter{},
   139  		&WorkloadFilter{},
   140  		&ServiceFilter{},
   141  		&FQDNFilter{},
   142  		&LabelsFilter{},
   143  		&PortFilter{},
   144  		&HTTPFilter{},
   145  		&TCPFilter{},
   146  		&NodeNameFilter{},
   147  		&IPVersionFilter{},
   148  		&TraceIDFilter{},
   149  		&TrafficDirectionFilter{},
   150  		&CELExpressionFilter{log: log},
   151  		&NetworkInterfaceFilter{},
   152  	}
   153  }