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

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Hubble
     3  
     4  package filters
     5  
     6  import (
     7  	"context"
     8  	"fmt"
     9  	"strings"
    10  
    11  	flowpb "github.com/cilium/cilium/api/v1/flow"
    12  	v1 "github.com/cilium/cilium/pkg/hubble/api/v1"
    13  )
    14  
    15  func filterByProtocol(protocols []string) (FilterFunc, error) {
    16  	var l4Protocols, l7Protocols []string
    17  	for _, p := range protocols {
    18  		proto := strings.ToLower(p)
    19  		switch proto {
    20  		case "icmp", "icmpv4", "icmpv6", "tcp", "udp", "sctp":
    21  			l4Protocols = append(l4Protocols, proto)
    22  		case "dns", "http", "kafka":
    23  			l7Protocols = append(l7Protocols, proto)
    24  		default:
    25  			return nil, fmt.Errorf("unknown protocol: %q", p)
    26  		}
    27  	}
    28  
    29  	return func(ev *v1.Event) bool {
    30  		l4 := ev.GetFlow().GetL4()
    31  		for _, proto := range l4Protocols {
    32  			switch proto {
    33  			case "icmp":
    34  				if l4.GetICMPv4() != nil || l4.GetICMPv6() != nil {
    35  					return true
    36  				}
    37  			case "icmpv4":
    38  				if l4.GetICMPv4() != nil {
    39  					return true
    40  				}
    41  			case "icmpv6":
    42  				if l4.GetICMPv6() != nil {
    43  					return true
    44  				}
    45  			case "tcp":
    46  				if l4.GetTCP() != nil {
    47  					return true
    48  				}
    49  			case "udp":
    50  				if l4.GetUDP() != nil {
    51  					return true
    52  				}
    53  			case "sctp":
    54  				if l4.GetSCTP() != nil {
    55  					return true
    56  				}
    57  			}
    58  		}
    59  
    60  		l7 := ev.GetFlow().GetL7()
    61  		for _, proto := range l7Protocols {
    62  			switch proto {
    63  			case "dns":
    64  				if l7.GetDns() != nil {
    65  					return true
    66  				}
    67  			case "http":
    68  				if l7.GetHttp() != nil {
    69  					return true
    70  				}
    71  			case "kafka":
    72  				if l7.GetKafka() != nil {
    73  					return true
    74  				}
    75  			}
    76  		}
    77  
    78  		return false
    79  	}, nil
    80  }
    81  
    82  // ProtocolFilter implements filtering based on L4 protocol
    83  type ProtocolFilter struct{}
    84  
    85  // OnBuildFilter builds a L4 protocol filter
    86  func (p *ProtocolFilter) OnBuildFilter(ctx context.Context, ff *flowpb.FlowFilter) ([]FilterFunc, error) {
    87  	var fs []FilterFunc
    88  
    89  	if ff.GetProtocol() != nil {
    90  		pf, err := filterByProtocol(ff.GetProtocol())
    91  		if err != nil {
    92  			return nil, fmt.Errorf("invalid protocol filter: %w", err)
    93  		}
    94  		fs = append(fs, pf)
    95  	}
    96  
    97  	return fs, nil
    98  }