github.com/cilium/cilium@v1.16.2/pkg/hubble/filters/port.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  	"strconv"
    10  
    11  	flowpb "github.com/cilium/cilium/api/v1/flow"
    12  	v1 "github.com/cilium/cilium/pkg/hubble/api/v1"
    13  )
    14  
    15  func sourcePort(ev *v1.Event) (port uint16, ok bool) {
    16  	l4 := ev.GetFlow().GetL4()
    17  	if tcp := l4.GetTCP(); tcp != nil {
    18  		return uint16(tcp.SourcePort), true
    19  	}
    20  	if udp := l4.GetUDP(); udp != nil {
    21  		return uint16(udp.SourcePort), true
    22  	}
    23  	if sctp := l4.GetSCTP(); sctp != nil {
    24  		return uint16(sctp.SourcePort), true
    25  	}
    26  	return 0, false
    27  }
    28  
    29  func destinationPort(ev *v1.Event) (port uint16, ok bool) {
    30  	l4 := ev.GetFlow().GetL4()
    31  	if tcp := l4.GetTCP(); tcp != nil {
    32  		return uint16(tcp.DestinationPort), true
    33  	}
    34  	if udp := l4.GetUDP(); udp != nil {
    35  		return uint16(udp.DestinationPort), true
    36  	}
    37  	if sctp := l4.GetSCTP(); sctp != nil {
    38  		return uint16(sctp.DestinationPort), true
    39  	}
    40  	return 0, false
    41  }
    42  
    43  func filterByPort(portStrs []string, getPort func(*v1.Event) (port uint16, ok bool)) (FilterFunc, error) {
    44  	ports := make([]uint16, 0, len(portStrs))
    45  	for _, p := range portStrs {
    46  		port, err := strconv.ParseUint(p, 10, 16)
    47  		if err != nil {
    48  			return nil, fmt.Errorf("invalid port %q: %w", p, err)
    49  		}
    50  		ports = append(ports, uint16(port))
    51  	}
    52  
    53  	return func(ev *v1.Event) bool {
    54  		if port, ok := getPort(ev); ok {
    55  			for _, p := range ports {
    56  				if p == port {
    57  					return true
    58  				}
    59  			}
    60  		}
    61  		return false
    62  	}, nil
    63  }
    64  
    65  // PortFilter implements filtering based on L4 port numbers
    66  type PortFilter struct{}
    67  
    68  // OnBuildFilter builds a L4 port filter
    69  func (p *PortFilter) OnBuildFilter(ctx context.Context, ff *flowpb.FlowFilter) ([]FilterFunc, error) {
    70  	var fs []FilterFunc
    71  
    72  	if ff.GetSourcePort() != nil {
    73  		spf, err := filterByPort(ff.GetSourcePort(), sourcePort)
    74  		if err != nil {
    75  			return nil, fmt.Errorf("invalid source port filter: %w", err)
    76  		}
    77  		fs = append(fs, spf)
    78  	}
    79  
    80  	if ff.GetDestinationPort() != nil {
    81  		dpf, err := filterByPort(ff.GetDestinationPort(), destinationPort)
    82  		if err != nil {
    83  			return nil, fmt.Errorf("invalid destination port filter: %w", err)
    84  		}
    85  		fs = append(fs, dpf)
    86  	}
    87  
    88  	return fs, nil
    89  }