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 }