github.com/cilium/cilium@v1.16.2/pkg/hubble/filters/ip_test.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Hubble 3 4 package filters 5 6 import ( 7 "context" 8 "testing" 9 10 flowpb "github.com/cilium/cilium/api/v1/flow" 11 v1 "github.com/cilium/cilium/pkg/hubble/api/v1" 12 ) 13 14 func TestIPFilter(t *testing.T) { 15 type args struct { 16 f []*flowpb.FlowFilter 17 ev []*v1.Event 18 } 19 tests := []struct { 20 name string 21 args args 22 wantErr bool 23 want []bool 24 }{ 25 { 26 name: "source ip", 27 args: args{ 28 f: []*flowpb.FlowFilter{ 29 {SourceIp: []string{"1.1.1.1", "f00d::a10:0:0:9195"}}, 30 }, 31 ev: []*v1.Event{ 32 {Event: &flowpb.Flow{IP: &flowpb.IP{Source: "1.1.1.1", Destination: "10.0.0.2"}}}, 33 {Event: &flowpb.Flow{IP: &flowpb.IP{Source: "10.0.0.2", Destination: "1.1.1.1"}}}, 34 {Event: &flowpb.Flow{IP: &flowpb.IP{Source: "f00d::a10:0:0:9195", Destination: "ff02::1:ff00:b3e5"}}}, 35 {Event: &flowpb.Flow{IP: &flowpb.IP{Source: "ff02::1:ff00:b3e5", Destination: "f00d::a10:0:0:9195"}}}, 36 }, 37 }, 38 want: []bool{ 39 true, 40 false, 41 true, 42 false, 43 }, 44 }, 45 { 46 name: "destination ip", 47 args: args{ 48 f: []*flowpb.FlowFilter{ 49 {DestinationIp: []string{"1.1.1.1", "f00d::a10:0:0:9195"}}, 50 }, 51 ev: []*v1.Event{ 52 {Event: &flowpb.Flow{IP: &flowpb.IP{Source: "1.1.1.1", Destination: "10.0.0.2"}}}, 53 {Event: &flowpb.Flow{IP: &flowpb.IP{Source: "10.0.0.2", Destination: "1.1.1.1"}}}, 54 {Event: &flowpb.Flow{IP: &flowpb.IP{Source: "f00d::a10:0:0:9195", Destination: "ff02::1:ff00:b3e5"}}}, 55 {Event: &flowpb.Flow{IP: &flowpb.IP{Source: "ff02::1:ff00:b3e5", Destination: "f00d::a10:0:0:9195"}}}, 56 }, 57 }, 58 want: []bool{ 59 false, 60 true, 61 false, 62 true, 63 }, 64 }, 65 { 66 name: "snat ip", 67 args: args{ 68 f: []*flowpb.FlowFilter{ 69 {SourceIpXlated: []string{"2.2.2.2", "9bf2:8d06:6d34:da3b::33c5"}}, 70 }, 71 ev: []*v1.Event{ 72 {Event: &flowpb.Flow{IP: &flowpb.IP{Source: "1.1.1.1", Destination: "10.0.0.2"}}}, 73 {Event: &flowpb.Flow{IP: &flowpb.IP{Source: "2.2.2.2", Destination: "10.0.0.2"}}}, 74 {Event: &flowpb.Flow{IP: &flowpb.IP{Source: "1.1.1.1", SourceXlated: "2.2.2.3", Destination: "10.0.0.2"}}}, 75 {Event: &flowpb.Flow{IP: &flowpb.IP{Source: "1.1.1.1", SourceXlated: "2.2.2.2", Destination: "10.0.0.2"}}}, 76 {Event: &flowpb.Flow{IP: &flowpb.IP{Source: "f00d::a10:0:0:9195", Destination: "ff02::1:ff00:b3e5"}}}, 77 {Event: &flowpb.Flow{IP: &flowpb.IP{Source: "f00d::a10:0:0:9195", Destination: "9bf2:8d06:6d34:da3b::33c5"}}}, 78 {Event: &flowpb.Flow{IP: &flowpb.IP{Source: "f00d::a10:0:0:9195", SourceXlated: "9bf2:8d06:6d34:da3b::33c5", Destination: "ff02::1:ff00:b3e5"}}}, 79 }, 80 }, 81 want: []bool{ 82 false, 83 false, 84 false, 85 true, 86 false, 87 false, 88 true, 89 }, 90 }, 91 { 92 name: "source and destination ip", 93 args: args{ 94 f: []*flowpb.FlowFilter{ 95 { 96 SourceIp: []string{"1.1.1.1", "f00d::a10:0:0:9195"}, 97 DestinationIp: []string{"10.0.0.2", "ff02::1:ff00:b3e5"}, 98 }, 99 }, 100 ev: []*v1.Event{ 101 {Event: &flowpb.Flow{IP: &flowpb.IP{Source: "1.1.1.1", Destination: "10.0.0.2"}}}, 102 {Event: &flowpb.Flow{IP: &flowpb.IP{Source: "10.0.0.2", Destination: "1.1.1.1"}}}, 103 {Event: &flowpb.Flow{IP: &flowpb.IP{Source: "f00d::a10:0:0:9195", Destination: "ff02::1:ff00:b3e5"}}}, 104 {Event: &flowpb.Flow{IP: &flowpb.IP{Source: "ff02::1:ff00:b3e5", Destination: "f00d::a10:0:0:9195"}}}, 105 }, 106 }, 107 want: []bool{ 108 true, 109 false, 110 true, 111 false, 112 }, 113 }, 114 { 115 name: "source and snat and destination ip", 116 args: args{ 117 f: []*flowpb.FlowFilter{ 118 { 119 SourceIp: []string{"1.1.1.1", "f00d::a10:0:0:9195"}, 120 SourceIpXlated: []string{"2.2.2.2", "9bf2:8d06:6d34:da3b::33c5"}, 121 DestinationIp: []string{"10.0.0.2", "ff02::1:ff00:b3e5"}, 122 }, 123 }, 124 ev: []*v1.Event{ 125 {Event: &flowpb.Flow{IP: &flowpb.IP{Source: "1.1.1.1", SourceXlated: "2.2.2.2", Destination: "10.0.0.2"}}}, 126 {Event: &flowpb.Flow{IP: &flowpb.IP{Source: "1.1.1.1", Destination: "10.0.0.2"}}}, 127 {Event: &flowpb.Flow{IP: &flowpb.IP{Source: "f00d::a10:0:0:9195", SourceXlated: "9bf2:8d06:6d34:da3b::33c5", Destination: "ff02::1:ff00:b3e5"}}}, 128 {Event: &flowpb.Flow{IP: &flowpb.IP{Source: "f00d::a10:0:0:9195", SourceXlated: "ff02::1:ff00:b3e5", Destination: "9bf2:8d06:6d34:da3b::33c5"}}}, 129 }, 130 }, 131 want: []bool{ 132 true, 133 false, 134 true, 135 false, 136 }, 137 }, 138 { 139 name: "source or destination ip", 140 args: args{ 141 f: []*flowpb.FlowFilter{ 142 {SourceIp: []string{"1.1.1.1"}}, 143 {DestinationIp: []string{"10.0.0.2"}}, 144 }, 145 ev: []*v1.Event{ 146 {Event: &flowpb.Flow{IP: &flowpb.IP{Source: "1.1.1.1", Destination: "10.0.0.2"}}}, 147 {Event: &flowpb.Flow{IP: &flowpb.IP{Source: "10.0.0.2", Destination: "1.1.1.1"}}}, 148 {Event: &flowpb.Flow{IP: &flowpb.IP{Source: "1.1.1.1", Destination: "1.1.1.1"}}}, 149 {Event: &flowpb.Flow{IP: &flowpb.IP{Source: "10.0.0.2", Destination: "10.0.0.2"}}}, 150 }, 151 }, 152 want: []bool{ 153 true, 154 false, 155 true, 156 true, 157 }, 158 }, 159 { 160 name: "invalid data", 161 args: args{ 162 f: []*flowpb.FlowFilter{ 163 {SourceIp: []string{"1.1.1.1"}}, 164 }, 165 ev: []*v1.Event{ 166 nil, 167 {}, 168 {Event: &flowpb.Flow{}}, 169 {Event: &flowpb.Flow{IP: &flowpb.IP{Source: ""}}}, 170 }, 171 }, 172 want: []bool{ 173 false, 174 false, 175 false, 176 false, 177 }, 178 }, 179 { 180 name: "invalid source ip filter", 181 args: args{ 182 f: []*flowpb.FlowFilter{ 183 {SourceIp: []string{"320.320.320.320"}}, 184 }, 185 }, 186 wantErr: true, 187 }, 188 { 189 name: "invalid destination ip filter", 190 args: args{ 191 f: []*flowpb.FlowFilter{ 192 {DestinationIp: []string{""}}, 193 }, 194 }, 195 wantErr: true, 196 }, 197 { 198 name: "invalid snat ip filter", 199 args: args{ 200 f: []*flowpb.FlowFilter{ 201 {SourceIpXlated: []string{""}}, 202 }, 203 }, 204 wantErr: true, 205 }, 206 { 207 name: "source cidr", 208 args: args{ 209 f: []*flowpb.FlowFilter{{SourceIp: []string{"1.1.1.0/24", "f00d::/16"}}}, 210 ev: []*v1.Event{ 211 {Event: &flowpb.Flow{IP: &flowpb.IP{Source: "1.1.1.1", Destination: "10.0.0.2"}}}, 212 {Event: &flowpb.Flow{IP: &flowpb.IP{Source: "10.0.0.2", Destination: "1.1.1.1"}}}, 213 {Event: &flowpb.Flow{IP: &flowpb.IP{Source: "f00d::a10:0:0:9195", Destination: "ff02::1:ff00:b3e5"}}}, 214 {Event: &flowpb.Flow{IP: &flowpb.IP{Source: "ff02::1:ff00:b3e5", Destination: "f00d::a10:0:0:9195"}}}, 215 }, 216 }, 217 want: []bool{ 218 true, 219 false, 220 true, 221 false, 222 }, 223 }, 224 { 225 name: "destination cidr", 226 args: args{ 227 f: []*flowpb.FlowFilter{{DestinationIp: []string{"1.1.1.0/24", "f00d::/16"}}}, 228 ev: []*v1.Event{ 229 {Event: &flowpb.Flow{IP: &flowpb.IP{Destination: "1.1.1.1", Source: "10.0.0.2"}}}, 230 {Event: &flowpb.Flow{IP: &flowpb.IP{Destination: "10.0.0.2", Source: "1.1.1.1"}}}, 231 {Event: &flowpb.Flow{IP: &flowpb.IP{Destination: "f00d::a10:0:0:9195", Source: "ff02::1:ff00:b3e5"}}}, 232 {Event: &flowpb.Flow{IP: &flowpb.IP{Destination: "ff02::1:ff00:b3e5", Source: "f00d::a10:0:0:9195"}}}, 233 }, 234 }, 235 want: []bool{ 236 true, 237 false, 238 true, 239 false, 240 }, 241 }, 242 { 243 name: "snat cidr", 244 args: args{ 245 f: []*flowpb.FlowFilter{{SourceIpXlated: []string{"1.1.1.0/24", "9bf2::/16"}}}, 246 ev: []*v1.Event{ 247 {Event: &flowpb.Flow{IP: &flowpb.IP{Source: "1.1.1.1", Destination: "1.1.1.2"}}}, 248 {Event: &flowpb.Flow{IP: &flowpb.IP{Source: "1.1.1.1", SourceXlated: "1.1.2.1", Destination: "10.0.0.2"}}}, 249 {Event: &flowpb.Flow{IP: &flowpb.IP{Source: "1.1.1.1", SourceXlated: "1.1.1.2", Destination: "10.0.0.2"}}}, 250 {Event: &flowpb.Flow{IP: &flowpb.IP{Source: "f00d::a10:0:0:9195", Destination: "ff02::1:ff00:b3e5"}}}, 251 {Event: &flowpb.Flow{IP: &flowpb.IP{Source: "ff02::1:ff00:b3e5", SourceXlated: "9bf2:8d06:6d34:da3b::33c5", Destination: "f00d::a10:0:0:9195"}}}, 252 }, 253 }, 254 want: []bool{ 255 false, 256 false, 257 true, 258 false, 259 true, 260 }, 261 }, 262 { 263 name: "invalid source cidr filter", 264 args: args{ 265 f: []*flowpb.FlowFilter{ 266 {SourceIp: []string{"1.1.1.1/1234"}}, 267 {SourceIp: []string{"2001::/1234"}}, 268 }, 269 }, 270 wantErr: true, 271 }, 272 { 273 name: "invalid destination cidr filter", 274 args: args{ 275 f: []*flowpb.FlowFilter{ 276 {DestinationIp: []string{"1.1.1.1/1234"}}, 277 {DestinationIp: []string{"2001::/1234"}}, 278 }, 279 }, 280 wantErr: true, 281 }, 282 { 283 name: "invalid snat cidr filter", 284 args: args{ 285 f: []*flowpb.FlowFilter{ 286 {SourceIpXlated: []string{"1.1.1.1/1234"}}, 287 {SourceIpXlated: []string{"2001::/1234"}}, 288 }, 289 }, 290 wantErr: true, 291 }, 292 } 293 for _, tt := range tests { 294 t.Run(tt.name, func(t *testing.T) { 295 fl, err := BuildFilterList(context.Background(), tt.args.f, []OnBuildFilter{&IPFilter{}}) 296 if (err != nil) != tt.wantErr { 297 t.Errorf("BuildFilterList(context.Background(), ) error = %v, wantErr %v", err, tt.wantErr) 298 return 299 } 300 for i, ev := range tt.args.ev { 301 if filterResult := fl.MatchOne(ev); filterResult != tt.want[i] { 302 t.Errorf("\"%s\" filterResult %d = %v, want %v", tt.name, i, filterResult, tt.want[i]) 303 } 304 } 305 }) 306 } 307 } 308 309 func TestIPVersionFilter(t *testing.T) { 310 allvers := []*v1.Event{ 311 {Event: &flowpb.Flow{IP: &flowpb.IP{IpVersion: flowpb.IPVersion_IPv4}}}, 312 {Event: &flowpb.Flow{IP: &flowpb.IP{IpVersion: flowpb.IPVersion_IPv6}}}, 313 {Event: &flowpb.Flow{IP: &flowpb.IP{IpVersion: flowpb.IPVersion_IP_NOT_USED}}}, 314 } 315 type args struct { 316 f []*flowpb.FlowFilter 317 ev []*v1.Event 318 } 319 tests := []struct { 320 name string 321 args args 322 wantErr bool 323 want []bool 324 }{ 325 { 326 name: "ipv4 test", 327 args: args{ 328 f: []*flowpb.FlowFilter{ 329 {IpVersion: []flowpb.IPVersion{flowpb.IPVersion_IPv4}}, 330 }, 331 ev: allvers, 332 }, 333 want: []bool{ 334 true, 335 false, 336 false, 337 }, 338 }, 339 { 340 name: "ipv6 test", 341 args: args{ 342 f: []*flowpb.FlowFilter{ 343 {IpVersion: []flowpb.IPVersion{flowpb.IPVersion_IPv6}}, 344 }, 345 ev: allvers, 346 }, 347 want: []bool{ 348 false, 349 true, 350 false, 351 }, 352 }, 353 { 354 name: "unknown network protocol test", 355 args: args{ 356 f: []*flowpb.FlowFilter{ 357 {IpVersion: []flowpb.IPVersion{flowpb.IPVersion_IP_NOT_USED}}, 358 }, 359 ev: allvers, 360 }, 361 want: []bool{ 362 false, 363 false, 364 true, 365 }, 366 }, 367 { 368 name: "both ipv4 and ipv6 allow test", 369 args: args{ 370 f: []*flowpb.FlowFilter{ 371 {IpVersion: []flowpb.IPVersion{flowpb.IPVersion_IPv4}}, 372 {IpVersion: []flowpb.IPVersion{flowpb.IPVersion_IPv6}}, 373 }, 374 ev: allvers, 375 }, 376 want: []bool{ 377 true, 378 true, 379 false, 380 }, 381 }, 382 { 383 name: "all ipv4,ipv6,unknown allow test", 384 args: args{ 385 f: []*flowpb.FlowFilter{ 386 {IpVersion: []flowpb.IPVersion{flowpb.IPVersion_IPv4}}, 387 {IpVersion: []flowpb.IPVersion{flowpb.IPVersion_IPv6}}, 388 {IpVersion: []flowpb.IPVersion{flowpb.IPVersion_IP_NOT_USED}}, 389 }, 390 ev: allvers, 391 }, 392 want: []bool{ 393 true, 394 true, 395 true, 396 }, 397 }, 398 { 399 name: "test with non-flow event", 400 args: args{ 401 f: []*flowpb.FlowFilter{ 402 {IpVersion: []flowpb.IPVersion{flowpb.IPVersion_IPv4}}, 403 {IpVersion: []flowpb.IPVersion{flowpb.IPVersion_IPv6}}, 404 }, 405 ev: []*v1.Event{ 406 {Event: &flowpb.AgentEvent{}}, 407 }, 408 }, 409 want: []bool{ 410 false, 411 }, 412 }, 413 { 414 name: "test with non-flow event and IP_NOT_USED", 415 args: args{ 416 f: []*flowpb.FlowFilter{ 417 {IpVersion: []flowpb.IPVersion{flowpb.IPVersion_IP_NOT_USED}}, 418 }, 419 ev: []*v1.Event{ 420 {Event: &flowpb.AgentEvent{}}, 421 }, 422 }, 423 want: []bool{ 424 false, 425 }, 426 }, 427 } 428 for _, tt := range tests { 429 t.Run(tt.name, func(t *testing.T) { 430 fl, err := BuildFilterList(context.Background(), tt.args.f, []OnBuildFilter{&IPVersionFilter{}}) 431 if (err != nil) != tt.wantErr { 432 t.Errorf("BuildFilterList(context.Background(), ) error = %v, wantErr %v", err, tt.wantErr) 433 return 434 } 435 for i, ev := range tt.args.ev { 436 if filterResult := fl.MatchOne(ev); filterResult != tt.want[i] { 437 t.Errorf("\"%s\" filterResult %d = %v, want %v", tt.name, i, filterResult, tt.want[i]) 438 } 439 } 440 }) 441 } 442 }