github.com/cilium/cilium@v1.16.2/pkg/hubble/filters/ip.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  	"net"
    10  	"strings"
    11  
    12  	flowpb "github.com/cilium/cilium/api/v1/flow"
    13  	v1 "github.com/cilium/cilium/pkg/hubble/api/v1"
    14  )
    15  
    16  func sourceIP(ev *v1.Event) string {
    17  	return ev.GetFlow().GetIP().GetSource()
    18  }
    19  
    20  func destinationIP(ev *v1.Event) string {
    21  	return ev.GetFlow().GetIP().GetDestination()
    22  }
    23  
    24  func sourceIPXlated(ev *v1.Event) string {
    25  	return ev.GetFlow().GetIP().GetSourceXlated()
    26  }
    27  
    28  func filterByIPs(ips []string, getIP func(*v1.Event) string) (FilterFunc, error) {
    29  	// IP filter can either be an exact match (e.g. "1.1.1.1") or a CIDR range
    30  	// (e.g. "1.1.1.0/24"). Put them into 2 separate lists here.
    31  	var addresses []string
    32  	var cidrs []*net.IPNet
    33  	for _, ip := range ips {
    34  		if strings.Contains(ip, "/") {
    35  			_, ipnet, err := net.ParseCIDR(ip)
    36  			if err != nil {
    37  				return nil, fmt.Errorf("invalid CIDR in filter: %q", ip)
    38  			}
    39  			cidrs = append(cidrs, ipnet)
    40  		} else {
    41  			if net.ParseIP(ip) == nil {
    42  				return nil, fmt.Errorf("invalid IP address in filter: %q", ip)
    43  			}
    44  			addresses = append(addresses, ip)
    45  		}
    46  	}
    47  
    48  	return func(ev *v1.Event) bool {
    49  		eventIP := getIP(ev)
    50  		if eventIP == "" {
    51  			return false
    52  		}
    53  
    54  		for _, ip := range addresses {
    55  			if ip == eventIP {
    56  				return true
    57  			}
    58  		}
    59  
    60  		if len(cidrs) > 0 {
    61  			parsedIP := net.ParseIP(eventIP)
    62  			for _, cidr := range cidrs {
    63  				if cidr.Contains(parsedIP) {
    64  					return true
    65  				}
    66  			}
    67  		}
    68  
    69  		return false
    70  	}, nil
    71  }
    72  
    73  // IPFilter implements IP addressing filtering for the source and destination
    74  // address
    75  type IPFilter struct{}
    76  
    77  // OnBuildFilter builds an IP address filter
    78  func (f *IPFilter) OnBuildFilter(ctx context.Context, ff *flowpb.FlowFilter) ([]FilterFunc, error) {
    79  	var fs []FilterFunc
    80  
    81  	if ff.GetSourceIp() != nil {
    82  		ipf, err := filterByIPs(ff.GetSourceIp(), sourceIP)
    83  		if err != nil {
    84  			return nil, err
    85  		}
    86  		fs = append(fs, ipf)
    87  	}
    88  
    89  	if ff.GetDestinationIp() != nil {
    90  		ipf, err := filterByIPs(ff.GetDestinationIp(), destinationIP)
    91  		if err != nil {
    92  			return nil, err
    93  		}
    94  		fs = append(fs, ipf)
    95  	}
    96  
    97  	if ff.GetSourceIpXlated() != nil {
    98  		ipf, err := filterByIPs(ff.GetSourceIpXlated(), sourceIPXlated)
    99  		if err != nil {
   100  			return nil, err
   101  		}
   102  		fs = append(fs, ipf)
   103  	}
   104  
   105  	return fs, nil
   106  }
   107  
   108  func filterByIPVersion(ipver []flowpb.IPVersion) (FilterFunc, error) {
   109  	return func(ev *v1.Event) bool {
   110  		flow := ev.GetFlow()
   111  		if flow == nil {
   112  			return false
   113  		}
   114  		ver := flow.GetIP().GetIpVersion()
   115  		for _, v := range ipver {
   116  			if v == ver {
   117  				return true
   118  			}
   119  		}
   120  		return false
   121  	}, nil
   122  }
   123  
   124  // IPVersionFilter implements IP version based filtering
   125  type IPVersionFilter struct{}
   126  
   127  // OnBuildFilter builds an IP version filter
   128  func (f *IPVersionFilter) OnBuildFilter(ctx context.Context, ff *flowpb.FlowFilter) ([]FilterFunc, error) {
   129  	var fs []FilterFunc
   130  
   131  	if ff.GetIpVersion() != nil {
   132  		pf, err := filterByIPVersion(ff.GetIpVersion())
   133  		if err != nil {
   134  			return nil, err
   135  		}
   136  		fs = append(fs, pf)
   137  	}
   138  
   139  	return fs, nil
   140  }