• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

kubeovn / kube-ovn / 18489953059

14 Oct 2025 08:12AM UTC coverage: 21.028% (-0.03%) from 21.058%
18489953059

push

github

web-flow
fix(netpol): don't add default block twice for dualstacks (#5741)

* fix(netpol): don't add default block twice for dualstacks

Signed-off-by: SkalaNetworks <contact@skala.network>

* fix(e2e): conformance + remove ipv6

Signed-off-by: SkalaNetworks <contact@skala.network>

---------

Signed-off-by: SkalaNetworks <contact@skala.network>

32 of 55 new or added lines in 2 files covered. (58.18%)

3 existing lines in 2 files now uncovered.

10687 of 50822 relevant lines covered (21.03%)

0.24 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/pkg/controller/network_policy.go
1
package controller
2

3
import (
4
        "fmt"
5
        "maps"
6
        "reflect"
7
        "slices"
8
        "strconv"
9
        "strings"
10
        "unicode"
11

12
        "github.com/scylladb/go-set/strset"
13
        corev1 "k8s.io/api/core/v1"
14
        netv1 "k8s.io/api/networking/v1"
15
        k8serrors "k8s.io/apimachinery/pkg/api/errors"
16
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
17
        "k8s.io/apimachinery/pkg/labels"
18
        utilruntime "k8s.io/apimachinery/pkg/util/runtime"
19
        "k8s.io/client-go/tools/cache"
20
        "k8s.io/klog/v2"
21
        "k8s.io/utils/set"
22

23
        kubeovnv1 "github.com/kubeovn/kube-ovn/pkg/apis/kubeovn/v1"
24
        "github.com/kubeovn/kube-ovn/pkg/ovs"
25
        "github.com/kubeovn/kube-ovn/pkg/ovsdb/ovnnb"
26
        "github.com/kubeovn/kube-ovn/pkg/util"
27
)
28

29
func (c *Controller) enqueueAddNp(obj any) {
×
30
        key := cache.MetaObjectToName(obj.(*netv1.NetworkPolicy)).String()
×
31
        klog.V(3).Infof("enqueue add network policy %s", key)
×
32
        c.updateNpQueue.Add(key)
×
33
}
×
34

35
func (c *Controller) enqueueDeleteNp(obj any) {
×
36
        var np *netv1.NetworkPolicy
×
37
        switch t := obj.(type) {
×
38
        case *netv1.NetworkPolicy:
×
39
                np = t
×
40
        case cache.DeletedFinalStateUnknown:
×
41
                n, ok := t.Obj.(*netv1.NetworkPolicy)
×
42
                if !ok {
×
43
                        klog.Warningf("unexpected object type: %T", t.Obj)
×
44
                        return
×
45
                }
×
46
                np = n
×
47
        default:
×
48
                klog.Warningf("unexpected type: %T", obj)
×
49
                return
×
50
        }
51

52
        key := cache.MetaObjectToName(np).String()
×
53
        klog.V(3).Infof("enqueue delete network policy %s", key)
×
54
        c.deleteNpQueue.Add(key)
×
55
}
56

57
func (c *Controller) enqueueUpdateNp(oldObj, newObj any) {
×
58
        oldNp := oldObj.(*netv1.NetworkPolicy)
×
59
        newNp := newObj.(*netv1.NetworkPolicy)
×
60
        if !reflect.DeepEqual(oldNp.Spec, newNp.Spec) ||
×
61
                !maps.Equal(oldNp.Annotations, newNp.Annotations) {
×
62
                key := cache.MetaObjectToName(newNp).String()
×
63
                klog.V(3).Infof("enqueue update np %s", key)
×
64
                c.updateNpQueue.Add(key)
×
65
        }
×
66
}
67

68
func (c *Controller) createAsForNetpol(ns, name, direction, asName string, addresses []string) error {
×
69
        if err := c.OVNNbClient.CreateAddressSet(asName, map[string]string{
×
70
                networkPolicyKey: fmt.Sprintf("%s/%s/%s", ns, name, direction),
×
71
        }); err != nil {
×
72
                klog.Errorf("failed to create ovn address set %s for np %s/%s: %v", asName, ns, name, err)
×
73
                return err
×
74
        }
×
75

76
        if err := c.OVNNbClient.AddressSetUpdateAddress(asName, addresses...); err != nil {
×
77
                klog.Errorf("failed to set addresses %q to address set %s: %v", strings.Join(addresses, ","), asName, err)
×
78
                return err
×
79
        }
×
80

81
        return nil
×
82
}
83

84
func (c *Controller) handleUpdateNp(key string) error {
×
85
        namespace, name, err := cache.SplitMetaNamespaceKey(key)
×
86
        if err != nil {
×
87
                utilruntime.HandleError(fmt.Errorf("invalid resource key: %s", key))
×
88
                return nil
×
89
        }
×
90

91
        c.npKeyMutex.LockKey(key)
×
92
        defer func() { _ = c.npKeyMutex.UnlockKey(key) }()
×
93
        klog.Infof("handle add/update network policy %s", key)
×
94

×
95
        np, err := c.npsLister.NetworkPolicies(namespace).Get(name)
×
96
        if err != nil {
×
97
                if k8serrors.IsNotFound(err) {
×
98
                        return nil
×
99
                }
×
100
                klog.Error(err)
×
101
                return err
×
102
        }
103

104
        defer func() {
×
105
                if err != nil {
×
106
                        c.recorder.Eventf(np, corev1.EventTypeWarning, "CreateACLFailed", err.Error())
×
107
                }
×
108
        }()
109

110
        logEnable := np.Annotations[util.NetworkPolicyLogAnnotation] == "true"
×
111

×
112
        var logActions []string
×
113
        if np.Annotations[util.ACLActionsLogAnnotation] != "" {
×
114
                logActions = strings.Split(np.Annotations[util.ACLActionsLogAnnotation], ",")
×
115
        } else {
×
116
                logActions = []string{ovnnb.ACLActionDrop}
×
117
        }
×
118

119
        npName := np.Name
×
120
        nameArray := []rune(np.Name)
×
121
        if !unicode.IsLetter(nameArray[0]) {
×
122
                npName = "np" + np.Name
×
123
        }
×
124

125
        // TODO: ovn acl doesn't support address_set name with '-', now we replace '-' by '.'.
126
        // This may cause conflict if two np with name test-np and test.np. Maybe hash is a better solution,
127
        // but we do not want to lost the readability now.
128
        pgName := strings.ReplaceAll(fmt.Sprintf("%s.%s", npName, np.Namespace), "-", ".")
×
129
        ingressAllowAsNamePrefix := strings.ReplaceAll(fmt.Sprintf("%s.%s.ingress.allow", npName, np.Namespace), "-", ".")
×
130
        ingressExceptAsNamePrefix := strings.ReplaceAll(fmt.Sprintf("%s.%s.ingress.except", npName, np.Namespace), "-", ".")
×
131
        egressAllowAsNamePrefix := strings.ReplaceAll(fmt.Sprintf("%s.%s.egress.allow", npName, np.Namespace), "-", ".")
×
132
        egressExceptAsNamePrefix := strings.ReplaceAll(fmt.Sprintf("%s.%s.egress.except", npName, np.Namespace), "-", ".")
×
133

×
134
        if err = c.OVNNbClient.CreatePortGroup(pgName, map[string]string{networkPolicyKey: np.Namespace + "/" + npName}); err != nil {
×
135
                klog.Errorf("create port group for np %s: %v", key, err)
×
136
                return err
×
137
        }
×
138

139
        namedPortMap := c.namedPort.GetNamedPortByNs(np.Namespace)
×
140
        ports, subnetNames, err := c.fetchSelectedPorts(np.Namespace, &np.Spec.PodSelector)
×
141
        if err != nil {
×
142
                klog.Errorf("fetch ports belongs to np %s: %v", key, err)
×
143
                return err
×
144
        }
×
145

146
        var subnets []*kubeovnv1.Subnet
×
147
        protocolSet := strset.NewWithSize(2)
×
148
        for _, subnetName := range subnetNames {
×
149
                subnet, err := c.subnetsLister.Get(subnetName)
×
150
                if err != nil {
×
151
                        klog.Errorf("failed to get pod's subnet %s, %v", subnetName, err)
×
152
                        return err
×
153
                }
×
154
                subnets = append(subnets, subnet)
×
155

×
156
                if subnet.Spec.Protocol == kubeovnv1.ProtocolDual {
×
157
                        protocolSet.Add(kubeovnv1.ProtocolIPv4, kubeovnv1.ProtocolIPv6)
×
158
                } else {
×
159
                        protocolSet.Add(subnet.Spec.Protocol)
×
160
                }
×
161
        }
162
        klog.Infof("UpdateNp, related subnets protocols %s", protocolSet.String())
×
163

×
164
        if err = c.OVNNbClient.PortGroupSetPorts(pgName, ports); err != nil {
×
165
                klog.Errorf("failed to set ports of port group %s to %v: %v", pgName, ports, err)
×
166
                return err
×
167
        }
×
168

169
        ingressACLOps, err := c.OVNNbClient.DeleteAclsOps(pgName, portGroupKey, "to-lport", nil)
×
170
        if err != nil {
×
171
                klog.Errorf("generate operations that clear np %s ingress acls: %v", key, err)
×
172
                return err
×
173
        }
×
174

175
        if hasIngressRule(np) {
×
NEW
176
                if protocolSet.Size() > 0 {
×
NEW
177
                        blockACLOps, err := c.OVNNbClient.UpdateDefaultBlockACLOps(key, pgName, ovnnb.ACLDirectionToLport, logEnable)
×
NEW
178
                        if err != nil {
×
NEW
179
                                klog.Errorf("failed to set default ingress block acl: %v", err)
×
NEW
180
                                return fmt.Errorf("failed to set default ingress block acl: %w", err)
×
NEW
181
                        }
×
NEW
182
                        ingressACLOps = append(ingressACLOps, blockACLOps...)
×
183
                }
184

185
                for _, protocol := range protocolSet.List() {
×
186
                        for idx, npr := range np.Spec.Ingress {
×
187
                                // A single address set must contain addresses of the same type and the name must be unique within table, so IPv4 and IPv6 address set should be different
×
188
                                ingressAllowAsName := fmt.Sprintf("%s.%s.%d", ingressAllowAsNamePrefix, protocol, idx)
×
189
                                ingressExceptAsName := fmt.Sprintf("%s.%s.%d", ingressExceptAsNamePrefix, protocol, idx)
×
190
                                aclName := fmt.Sprintf("np/%s.%s/ingress/%s/%d", npName, np.Namespace, protocol, idx)
×
191

×
192
                                var allows, excepts []string
×
193
                                if len(npr.From) == 0 {
×
194
                                        if protocol == kubeovnv1.ProtocolIPv4 {
×
195
                                                allows = []string{"0.0.0.0/0"}
×
196
                                        } else {
×
197
                                                allows = []string{"::/0"}
×
198
                                        }
×
199
                                } else {
×
200
                                        var allow, except []string
×
201
                                        for _, npp := range npr.From {
×
202
                                                if allow, except, err = c.fetchPolicySelectedAddresses(np.Namespace, protocol, npp); err != nil {
×
203
                                                        klog.Errorf("failed to fetch policy selected addresses, %v", err)
×
204
                                                        return err
×
205
                                                }
×
206
                                                allows = append(allows, allow...)
×
207
                                                excepts = append(excepts, except...)
×
208
                                        }
209
                                }
210
                                klog.Infof("UpdateNp Ingress, allows is %v, excepts is %v, log %v, protocol %v", allows, excepts, logEnable, protocol)
×
211

×
212
                                if err = c.createAsForNetpol(np.Namespace, npName, "ingress", ingressAllowAsName, allows); err != nil {
×
213
                                        klog.Error(err)
×
214
                                        return err
×
215
                                }
×
216
                                if err = c.createAsForNetpol(np.Namespace, npName, "ingress", ingressExceptAsName, excepts); err != nil {
×
217
                                        klog.Error(err)
×
218
                                        return err
×
219
                                }
×
220

221
                                npp := []netv1.NetworkPolicyPort{}
×
222
                                if len(allows) != 0 || len(excepts) != 0 {
×
223
                                        npp = npr.Ports
×
224
                                }
×
225

NEW
226
                                ops, err := c.OVNNbClient.UpdateIngressACLOps(pgName, ingressAllowAsName, ingressExceptAsName, protocol, aclName, npp, logEnable, logActions, namedPortMap)
×
227
                                if err != nil {
×
228
                                        klog.Errorf("generate operations that add ingress acls to np %s: %v", key, err)
×
229
                                        return err
×
230
                                }
×
231

232
                                ingressACLOps = append(ingressACLOps, ops...)
×
233
                        }
234
                        if len(np.Spec.Ingress) == 0 {
×
235
                                ingressAllowAsName := fmt.Sprintf("%s.%s.all", ingressAllowAsNamePrefix, protocol)
×
236
                                ingressExceptAsName := fmt.Sprintf("%s.%s.all", ingressExceptAsNamePrefix, protocol)
×
237
                                aclName := fmt.Sprintf("np/%s.%s/ingress/%s/all", npName, np.Namespace, protocol)
×
238

×
239
                                if err = c.createAsForNetpol(np.Namespace, npName, "ingress", ingressAllowAsName, nil); err != nil {
×
240
                                        klog.Error(err)
×
241
                                        return err
×
242
                                }
×
243
                                if err = c.createAsForNetpol(np.Namespace, npName, "ingress", ingressExceptAsName, nil); err != nil {
×
244
                                        klog.Error(err)
×
245
                                        return err
×
246
                                }
×
247

NEW
248
                                ops, err := c.OVNNbClient.UpdateIngressACLOps(pgName, ingressAllowAsName, ingressExceptAsName, protocol, aclName, nil, logEnable, logActions, namedPortMap)
×
249
                                if err != nil {
×
250
                                        klog.Errorf("generate operations that add ingress acls to np %s: %v", key, err)
×
251
                                        return err
×
252
                                }
×
253

254
                                ingressACLOps = append(ingressACLOps, ops...)
×
255
                        }
256
                }
257

258
                if err := c.OVNNbClient.Transact("add-ingress-acls", ingressACLOps); err != nil {
×
259
                        return fmt.Errorf("add ingress acls to %s: %w", pgName, err)
×
260
                }
×
261

262
                if err := c.OVNNbClient.SetACLLog(pgName, logEnable, true); err != nil {
×
263
                        // just log and do not return err here
×
264
                        klog.Errorf("failed to set ingress acl log for np %s, %v", key, err)
×
265
                }
×
266

267
                ass, err := c.OVNNbClient.ListAddressSets(map[string]string{
×
268
                        networkPolicyKey: fmt.Sprintf("%s/%s/%s", np.Namespace, npName, "ingress"),
×
269
                })
×
270
                if err != nil {
×
271
                        klog.Errorf("list np %s address sets: %v", key, err)
×
272
                        return err
×
273
                }
×
274

275
                // The format of asName is like "test.network.policy.test.ingress.except.0" or "test.network.policy.test.ingress.allow.0" for ingress
276
                for _, as := range ass {
×
277
                        values := strings.Split(as.Name, ".")
×
278
                        if len(values) <= 1 {
×
279
                                continue
×
280
                        }
281
                        idxStr := values[len(values)-1]
×
282
                        if idxStr == "all" {
×
283
                                continue
×
284
                        }
285
                        idx, _ := strconv.Atoi(idxStr)
×
286
                        if idx >= len(np.Spec.Ingress) {
×
287
                                if err = c.OVNNbClient.DeleteAddressSet(as.Name); err != nil {
×
288
                                        klog.Errorf("failed to delete np %s address set, %v", key, err)
×
289
                                        return err
×
290
                                }
×
291
                        }
292
                }
293
        } else {
×
294
                if err = c.OVNNbClient.DeleteAcls(pgName, portGroupKey, "to-lport", nil); err != nil {
×
295
                        klog.Errorf("delete np %s ingress acls: %v", key, err)
×
296
                        return err
×
297
                }
×
298

299
                if err := c.OVNNbClient.DeleteAddressSets(map[string]string{
×
300
                        networkPolicyKey: fmt.Sprintf("%s/%s/%s", np.Namespace, npName, "ingress"),
×
301
                }); err != nil {
×
302
                        klog.Errorf("delete np %s ingress address set: %v", key, err)
×
303
                        return err
×
304
                }
×
305
        }
306

307
        egressACLOps, err := c.OVNNbClient.DeleteAclsOps(pgName, portGroupKey, "from-lport", nil)
×
308
        if err != nil {
×
309
                klog.Errorf("generate operations that clear np %s egress acls: %v", key, err)
×
310
                return err
×
311
        }
×
312

313
        if hasEgressRule(np) {
×
NEW
314
                if protocolSet.Size() > 0 {
×
NEW
315
                        blockACLOps, err := c.OVNNbClient.UpdateDefaultBlockACLOps(key, pgName, ovnnb.ACLDirectionFromLport, logEnable)
×
NEW
316
                        if err != nil {
×
NEW
317
                                klog.Errorf("failed to set default egress block acl: %v", err)
×
NEW
318
                                return fmt.Errorf("failed to set default egress block acl: %w", err)
×
NEW
319
                        }
×
NEW
320
                        egressACLOps = append(egressACLOps, blockACLOps...)
×
321
                }
322

323
                for _, protocol := range protocolSet.List() {
×
324
                        for idx, npr := range np.Spec.Egress {
×
325
                                // A single address set must contain addresses of the same type and the name must be unique within table, so IPv4 and IPv6 address set should be different
×
326
                                egressAllowAsName := fmt.Sprintf("%s.%s.%d", egressAllowAsNamePrefix, protocol, idx)
×
327
                                egressExceptAsName := fmt.Sprintf("%s.%s.%d", egressExceptAsNamePrefix, protocol, idx)
×
328
                                aclName := fmt.Sprintf("np/%s.%s/egress/%s/%d", npName, np.Namespace, protocol, idx)
×
329

×
330
                                var allows, excepts []string
×
331
                                if len(npr.To) == 0 {
×
332
                                        if protocol == kubeovnv1.ProtocolIPv4 {
×
333
                                                allows = []string{"0.0.0.0/0"}
×
334
                                        } else {
×
335
                                                allows = []string{"::/0"}
×
336
                                        }
×
337
                                } else {
×
338
                                        var allow, except []string
×
339
                                        for _, npp := range npr.To {
×
340
                                                if allow, except, err = c.fetchPolicySelectedAddresses(np.Namespace, protocol, npp); err != nil {
×
341
                                                        klog.Errorf("failed to fetch policy selected addresses, %v", err)
×
342
                                                        return err
×
343
                                                }
×
344
                                                allows = append(allows, allow...)
×
345
                                                excepts = append(excepts, except...)
×
346
                                        }
347
                                }
348
                                klog.Infof("UpdateNp Egress %s, allows is %v, excepts is %v, log %v", aclName, allows, excepts, logEnable)
×
349

×
350
                                if err = c.createAsForNetpol(np.Namespace, npName, "egress", egressAllowAsName, allows); err != nil {
×
351
                                        klog.Error(err)
×
352
                                        return err
×
353
                                }
×
354
                                if err = c.createAsForNetpol(np.Namespace, npName, "egress", egressExceptAsName, excepts); err != nil {
×
355
                                        klog.Error(err)
×
356
                                        return err
×
357
                                }
×
358

359
                                npp := []netv1.NetworkPolicyPort{}
×
360
                                if len(allows) != 0 || len(excepts) != 0 {
×
361
                                        npp = npr.Ports
×
362
                                }
×
363

NEW
364
                                ops, err := c.OVNNbClient.UpdateEgressACLOps(pgName, egressAllowAsName, egressExceptAsName, protocol, aclName, npp, logEnable, logActions, namedPortMap)
×
365
                                if err != nil {
×
366
                                        klog.Errorf("generate operations that add egress acls to np %s: %v", key, err)
×
367
                                        return err
×
368
                                }
×
369

370
                                egressACLOps = append(egressACLOps, ops...)
×
371
                        }
372
                        if len(np.Spec.Egress) == 0 {
×
373
                                egressAllowAsName := fmt.Sprintf("%s.%s.all", egressAllowAsNamePrefix, protocol)
×
374
                                egressExceptAsName := fmt.Sprintf("%s.%s.all", egressExceptAsNamePrefix, protocol)
×
375
                                aclName := fmt.Sprintf("np/%s.%s/egress/%s/all", npName, np.Namespace, protocol)
×
376

×
377
                                if err = c.createAsForNetpol(np.Namespace, npName, "egress", egressAllowAsName, nil); err != nil {
×
378
                                        klog.Error(err)
×
379
                                        return err
×
380
                                }
×
381
                                if err = c.createAsForNetpol(np.Namespace, npName, "egress", egressExceptAsName, nil); err != nil {
×
382
                                        klog.Error(err)
×
383
                                        return err
×
384
                                }
×
385

NEW
386
                                ops, err := c.OVNNbClient.UpdateEgressACLOps(pgName, egressAllowAsName, egressExceptAsName, protocol, aclName, nil, logEnable, logActions, namedPortMap)
×
387
                                if err != nil {
×
388
                                        klog.Errorf("generate operations that add egress acls to np %s: %v", key, err)
×
389
                                        return err
×
390
                                }
×
391

392
                                egressACLOps = append(egressACLOps, ops...)
×
393
                        }
394
                }
395

396
                if err := c.OVNNbClient.Transact("add-egress-acls", egressACLOps); err != nil {
×
397
                        return fmt.Errorf("add egress acls to %s: %w", pgName, err)
×
398
                }
×
399

400
                if err := c.OVNNbClient.SetACLLog(pgName, logEnable, false); err != nil {
×
401
                        // just log and do not return err here
×
402
                        klog.Errorf("failed to set egress acl log for np %s, %v", key, err)
×
403
                }
×
404

405
                ass, err := c.OVNNbClient.ListAddressSets(map[string]string{
×
406
                        networkPolicyKey: fmt.Sprintf("%s/%s/%s", np.Namespace, npName, "egress"),
×
407
                })
×
408
                if err != nil {
×
409
                        klog.Errorf("list np %s address sets: %v", key, err)
×
410
                        return err
×
411
                }
×
412

413
                // The format of asName is like "test.network.policy.test.egress.except.0" or "test.network.policy.test.egress.allow.0" for egress
414
                for _, as := range ass {
×
415
                        values := strings.Split(as.Name, ".")
×
416
                        if len(values) <= 1 {
×
417
                                continue
×
418
                        }
419
                        idxStr := values[len(values)-1]
×
420
                        if idxStr == "all" {
×
421
                                continue
×
422
                        }
423

424
                        idx, _ := strconv.Atoi(idxStr)
×
425
                        if idx >= len(np.Spec.Egress) {
×
426
                                if err = c.OVNNbClient.DeleteAddressSet(as.Name); err != nil {
×
427
                                        klog.Errorf("delete np %s address set: %v", key, err)
×
428
                                        return err
×
429
                                }
×
430
                        }
431
                }
432
        } else {
×
433
                if err = c.OVNNbClient.DeleteAcls(pgName, portGroupKey, "from-lport", nil); err != nil {
×
434
                        klog.Errorf("delete np %s egress acls: %v", key, err)
×
435
                        return err
×
436
                }
×
437

438
                if err := c.OVNNbClient.DeleteAddressSets(map[string]string{
×
439
                        networkPolicyKey: fmt.Sprintf("%s/%s/%s", np.Namespace, npName, "egress"),
×
440
                }); err != nil {
×
441
                        klog.Errorf("delete np %s egress address set: %v", key, err)
×
442
                        return err
×
443
                }
×
444
        }
445

446
        for _, subnet := range subnets {
×
447
                if err = c.OVNNbClient.CreateGatewayACL("", pgName, subnet.Spec.Gateway, subnet.Status.U2OInterconnectionIP); err != nil {
×
448
                        klog.Errorf("create gateway acl: %v", err)
×
449
                        return err
×
450
                }
×
451
        }
452
        return nil
×
453
}
454

455
func (c *Controller) handleDeleteNp(key string) error {
×
456
        namespace, name, err := cache.SplitMetaNamespaceKey(key)
×
457
        if err != nil {
×
458
                utilruntime.HandleError(fmt.Errorf("invalid resource key: %s", key))
×
459
                return nil
×
460
        }
×
461

462
        c.npKeyMutex.LockKey(key)
×
463
        defer func() { _ = c.npKeyMutex.UnlockKey(key) }()
×
464
        klog.Infof("handle delete network policy %s", key)
×
465

×
466
        npName := name
×
467
        nameArray := []rune(name)
×
468
        if !unicode.IsLetter(nameArray[0]) {
×
469
                npName = "np" + name
×
470
        }
×
471

472
        pgName := strings.ReplaceAll(fmt.Sprintf("%s.%s", npName, namespace), "-", ".")
×
473
        if err = c.OVNNbClient.DeletePortGroup(pgName); err != nil {
×
474
                klog.Errorf("delete np %s port group: %v", key, err)
×
475
        }
×
476

477
        if err := c.OVNNbClient.DeleteAddressSets(map[string]string{
×
478
                networkPolicyKey: fmt.Sprintf("%s/%s/%s", namespace, npName, "service"),
×
479
        }); err != nil {
×
480
                klog.Errorf("delete np %s service address set: %v", key, err)
×
481
                return err
×
482
        }
×
483

484
        if err := c.OVNNbClient.DeleteAddressSets(map[string]string{
×
485
                networkPolicyKey: fmt.Sprintf("%s/%s/%s", namespace, npName, "ingress"),
×
486
        }); err != nil {
×
487
                klog.Errorf("delete np %s ingress address set: %v", key, err)
×
488
                return err
×
489
        }
×
490

491
        if err := c.OVNNbClient.DeleteAddressSets(map[string]string{
×
492
                networkPolicyKey: fmt.Sprintf("%s/%s/%s", namespace, npName, "egress"),
×
493
        }); err != nil {
×
494
                klog.Errorf("delete np %s egress address set: %v", key, err)
×
495
                return err
×
496
        }
×
497

498
        return nil
×
499
}
500

501
func (c *Controller) fetchSelectedPorts(namespace string, selector *metav1.LabelSelector) ([]string, []string, error) {
×
502
        var subnets []string
×
503
        sel, err := metav1.LabelSelectorAsSelector(selector)
×
504
        if err != nil {
×
505
                return nil, nil, fmt.Errorf("error creating label selector, %w", err)
×
506
        }
×
507
        pods, err := c.podsLister.Pods(namespace).List(sel)
×
508
        if err != nil {
×
509
                return nil, nil, fmt.Errorf("failed to list pods, %w", err)
×
510
        }
×
511

512
        ports := make([]string, 0, len(pods))
×
513
        for _, pod := range pods {
×
514
                if pod.Spec.HostNetwork {
×
515
                        continue
×
516
                }
517
                podName := c.getNameByPod(pod)
×
518
                podNets, err := c.getPodKubeovnNets(pod)
×
519
                if err != nil {
×
520
                        return nil, nil, fmt.Errorf("failed to get pod networks, %w", err)
×
521
                }
×
522

523
                for _, podNet := range podNets {
×
524
                        if !isOvnSubnet(podNet.Subnet) {
×
525
                                continue
×
526
                        }
527

528
                        if pod.Annotations[fmt.Sprintf(util.AllocatedAnnotationTemplate, podNet.ProviderName)] == "true" {
×
529
                                ports = append(ports, ovs.PodNameToPortName(podName, pod.Namespace, podNet.ProviderName))
×
530
                                // Pod selected by networkpolicy has its own subnet which is not the default subnet
×
531
                                subnets = append(subnets, podNet.Subnet.Name)
×
532
                        }
×
533
                }
534
        }
535
        subnets = slices.Compact(subnets)
×
536
        return ports, subnets, nil
×
537
}
538

539
func hasIngressRule(np *netv1.NetworkPolicy) bool {
×
540
        for _, pt := range np.Spec.PolicyTypes {
×
541
                if strings.Contains(string(pt), string(netv1.PolicyTypeIngress)) {
×
542
                        return true
×
543
                }
×
544
        }
545
        return np.Spec.Ingress != nil
×
546
}
547

548
func hasEgressRule(np *netv1.NetworkPolicy) bool {
×
549
        for _, pt := range np.Spec.PolicyTypes {
×
550
                if strings.Contains(string(pt), string(netv1.PolicyTypeEgress)) {
×
551
                        return true
×
552
                }
×
553
        }
554
        return np.Spec.Egress != nil
×
555
}
556

557
func (c *Controller) fetchPolicySelectedAddresses(namespace, protocol string, npp netv1.NetworkPolicyPeer) ([]string, []string, error) {
×
558
        selectedAddresses := []string{}
×
559
        exceptAddresses := []string{}
×
560

×
561
        // ingress.from.ipblock or egress.to.ipblock
×
562
        if npp.IPBlock != nil && util.CheckProtocol(npp.IPBlock.CIDR) == protocol {
×
563
                selectedAddresses = append(selectedAddresses, npp.IPBlock.CIDR)
×
564
                if npp.IPBlock.Except != nil {
×
565
                        exceptAddresses = append(exceptAddresses, npp.IPBlock.Except...)
×
566
                }
×
567
        }
568
        if npp.NamespaceSelector == nil && npp.PodSelector == nil {
×
569
                return selectedAddresses, exceptAddresses, nil
×
570
        }
×
571

572
        selectedNs := []string{}
×
573
        if npp.NamespaceSelector == nil {
×
574
                selectedNs = append(selectedNs, namespace)
×
575
        } else {
×
576
                sel, err := metav1.LabelSelectorAsSelector(npp.NamespaceSelector)
×
577
                if err != nil {
×
578
                        return nil, nil, fmt.Errorf("error creating label selector, %w", err)
×
579
                }
×
580
                nss, err := c.namespacesLister.List(sel)
×
581
                if err != nil {
×
582
                        return nil, nil, fmt.Errorf("failed to list ns, %w", err)
×
583
                }
×
584
                for _, ns := range nss {
×
585
                        selectedNs = append(selectedNs, ns.Name)
×
586
                }
×
587
        }
588

589
        var sel labels.Selector
×
590
        if npp.PodSelector == nil {
×
591
                sel = labels.Everything()
×
592
        } else {
×
593
                sel, _ = metav1.LabelSelectorAsSelector(npp.PodSelector)
×
594
        }
×
595

596
        for _, ns := range selectedNs {
×
597
                pods, err := c.podsLister.Pods(ns).List(sel)
×
598
                if err != nil {
×
599
                        return nil, nil, fmt.Errorf("failed to list pod, %w", err)
×
600
                }
×
601
                svcs, err := c.servicesLister.Services(ns).List(labels.Everything())
×
602
                if err != nil {
×
603
                        klog.Errorf("failed to list svc, %v", err)
×
604
                        return nil, nil, fmt.Errorf("failed to list svc, %w", err)
×
605
                }
×
606

607
                for _, pod := range pods {
×
608
                        podNets, err := c.getPodKubeovnNets(pod)
×
609
                        if err != nil {
×
610
                                klog.Errorf("failed to get pod nets %v", err)
×
611
                                return nil, nil, err
×
612
                        }
×
613
                        for _, podNet := range podNets {
×
614
                                podIPAnnotation := pod.Annotations[fmt.Sprintf(util.IPAddressAnnotationTemplate, podNet.ProviderName)]
×
615
                                podIPs := strings.SplitSeq(podIPAnnotation, ",")
×
616
                                for podIP := range podIPs {
×
617
                                        if podIP != "" && util.CheckProtocol(podIP) == protocol {
×
618
                                                selectedAddresses = append(selectedAddresses, podIP)
×
619
                                        }
×
620
                                }
621
                                if len(svcs) == 0 {
×
622
                                        continue
×
623
                                }
624

625
                                svcIPs, err := svcMatchPods(svcs, pod, protocol)
×
626
                                if err != nil {
×
627
                                        return nil, nil, err
×
628
                                }
×
629
                                selectedAddresses = append(selectedAddresses, svcIPs...)
×
630
                        }
631
                }
632
        }
633
        return selectedAddresses, exceptAddresses, nil
×
634
}
635

636
func svcMatchPods(svcs []*corev1.Service, pod *corev1.Pod, protocol string) ([]string, error) {
×
637
        matchSvcs := []string{}
×
638
        // find svc ip by pod's info
×
639
        for _, svc := range svcs {
×
640
                if isSvcMatchPod(svc, pod) {
×
641
                        clusterIPs := util.ServiceClusterIPs(*svc)
×
642
                        protocolClusterIPs := getProtocolSvcIP(clusterIPs, protocol)
×
643
                        if len(protocolClusterIPs) != 0 {
×
644
                                matchSvcs = append(matchSvcs, protocolClusterIPs...)
×
645
                        }
×
646
                }
647
        }
648
        return matchSvcs, nil
×
649
}
650

651
func getProtocolSvcIP(clusterIPs []string, protocol string) []string {
×
652
        protocolClusterIPs := []string{}
×
653
        for _, clusterIP := range clusterIPs {
×
654
                if clusterIP != "" && clusterIP != corev1.ClusterIPNone && util.CheckProtocol(clusterIP) == protocol {
×
655
                        protocolClusterIPs = append(protocolClusterIPs, clusterIP)
×
656
                }
×
657
        }
658
        return protocolClusterIPs
×
659
}
660

661
func isSvcMatchPod(svc *corev1.Service, pod *corev1.Pod) bool {
×
662
        return labels.Set(svc.Spec.Selector).AsSelector().Matches(labels.Set(pod.Labels))
×
663
}
×
664

665
func (c *Controller) podMatchNetworkPolicies(pod *corev1.Pod) []string {
×
666
        podNs, err := c.namespacesLister.Get(pod.Namespace)
×
667
        if err != nil {
×
668
                klog.Errorf("failed to get namespace %s: %v", pod.Namespace, err)
×
669
                utilruntime.HandleError(err)
×
670
                return nil
×
671
        }
×
672

673
        nps, err := c.npsLister.NetworkPolicies(corev1.NamespaceAll).List(labels.Everything())
×
674
        if err != nil {
×
675
                klog.Errorf("failed to list network policies: %v", err)
×
676
                utilruntime.HandleError(err)
×
677
                return nil
×
678
        }
×
679

680
        match := []string{}
×
681
        for _, np := range nps {
×
682
                if isPodMatchNetworkPolicy(pod, podNs, np, np.Namespace) {
×
683
                        match = append(match, cache.MetaObjectToName(np).String())
×
684
                }
×
685
        }
686
        return match
×
687
}
688

689
func (c *Controller) svcMatchNetworkPolicies(svc *corev1.Service) ([]string, error) {
×
690
        // find all match pod
×
691
        sel := labels.Set(svc.Spec.Selector).AsSelector()
×
692
        pods, err := c.podsLister.Pods(svc.Namespace).List(sel)
×
693
        if err != nil {
×
694
                return nil, fmt.Errorf("failed to list pods, %w", err)
×
695
        }
×
696

697
        // find all match netpol
698
        nps, err := c.npsLister.NetworkPolicies(corev1.NamespaceAll).List(labels.Everything())
×
699
        if err != nil {
×
700
                return nil, fmt.Errorf("failed to list netpols, %w", err)
×
701
        }
×
702
        match := set.New[string]()
×
703
        ns, _ := c.namespacesLister.Get(svc.Namespace)
×
704
        for _, pod := range pods {
×
705
                for _, np := range nps {
×
706
                        key := cache.MetaObjectToName(np).String()
×
707
                        if match.Has(key) {
×
708
                                continue
×
709
                        }
710
                        if isPodMatchNetworkPolicy(pod, ns, np, np.Namespace) {
×
711
                                match.Insert(key)
×
712
                                klog.V(3).Infof("svc %s/%s match np %s", svc.Namespace, svc.Name, key)
×
713
                        }
×
714
                }
715
        }
716
        return match.UnsortedList(), nil
×
717
}
718

719
func isPodMatchNetworkPolicy(pod *corev1.Pod, podNs *corev1.Namespace, policy *netv1.NetworkPolicy, policyNs string) bool {
×
720
        sel, _ := metav1.LabelSelectorAsSelector(&policy.Spec.PodSelector)
×
721
        if podNs.Name == policyNs && sel.Matches(labels.Set(pod.Labels)) {
×
722
                return true
×
723
        }
×
724
        for _, npr := range policy.Spec.Ingress {
×
725
                for _, npp := range npr.From {
×
726
                        if isPodMatchPolicyPeer(pod, podNs, npp, policyNs) {
×
727
                                return true
×
728
                        }
×
729
                }
730
        }
731
        for _, npr := range policy.Spec.Egress {
×
732
                for _, npp := range npr.To {
×
733
                        if isPodMatchPolicyPeer(pod, podNs, npp, policyNs) {
×
734
                                return true
×
735
                        }
×
736
                }
737
        }
738
        return false
×
739
}
740

741
func isPodMatchPolicyPeer(pod *corev1.Pod, podNs *corev1.Namespace, policyPeer netv1.NetworkPolicyPeer, policyNs string) bool {
×
742
        if policyPeer.IPBlock != nil {
×
743
                return false
×
744
        }
×
745
        if policyPeer.NamespaceSelector == nil {
×
746
                if policyNs != podNs.Name {
×
747
                        return false
×
748
                }
×
749
        } else if !util.ObjectMatchesLabelSelector(podNs, policyPeer.NamespaceSelector) {
×
750
                return false
×
751
        }
×
752

753
        return policyPeer.PodSelector == nil || util.ObjectMatchesLabelSelector(pod, policyPeer.PodSelector)
×
754
}
755

756
func (c *Controller) namespaceMatchNetworkPolicies(ns *corev1.Namespace) []string {
×
757
        nps, _ := c.npsLister.NetworkPolicies(corev1.NamespaceAll).List(labels.Everything())
×
758
        match := make([]string, 0, len(nps))
×
759
        for _, np := range nps {
×
760
                if isNamespaceMatchNetworkPolicy(ns, np) {
×
761
                        match = append(match, cache.MetaObjectToName(np).String())
×
762
                }
×
763
        }
764
        return match
×
765
}
766

767
func isNamespaceMatchNetworkPolicy(ns *corev1.Namespace, policy *netv1.NetworkPolicy) bool {
×
768
        for _, npr := range policy.Spec.Ingress {
×
769
                for _, npp := range npr.From {
×
770
                        if npp.NamespaceSelector != nil {
×
771
                                nsSel, _ := metav1.LabelSelectorAsSelector(npp.NamespaceSelector)
×
772
                                if ns.Labels == nil {
×
773
                                        ns.Labels = map[string]string{}
×
774
                                }
×
775
                                if nsSel.Matches(labels.Set(ns.Labels)) {
×
776
                                        return true
×
777
                                }
×
778
                        }
779
                }
780
        }
781

782
        for _, npr := range policy.Spec.Egress {
×
783
                for _, npp := range npr.To {
×
784
                        if npp.NamespaceSelector != nil {
×
785
                                nsSel, _ := metav1.LabelSelectorAsSelector(npp.NamespaceSelector)
×
786
                                if ns.Labels == nil {
×
787
                                        ns.Labels = map[string]string{}
×
788
                                }
×
789
                                if nsSel.Matches(labels.Set(ns.Labels)) {
×
790
                                        return true
×
791
                                }
×
792
                        }
793
                }
794
        }
795
        return false
×
796
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc