Skip to content

Commit 9dba724

Browse files
committed
Implements the updated protocol -> port -> {number,range,name}
This goes allow with: kubernetes-sigs/network-policy-api#326
1 parent 11378f5 commit 9dba724

File tree

2 files changed

+448
-67
lines changed

2 files changed

+448
-67
lines changed

plugins/npa-v1alpha2/clusternetworkpolicy.go

Lines changed: 92 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -144,24 +144,37 @@ func (c *ClusterNetworkPolicy) evaluateClusterEgress(
144144
) npav1alpha2.ClusterNetworkPolicyRuleAction {
145145
for _, policy := range policies {
146146
for _, rule := range policy.Spec.Egress {
147-
if rule.Ports != nil {
148-
if !evaluateClusterNetworkPolicyPort(*rule.Ports, dstPod, dstPort, protocol) {
147+
// A rule matches if both its ports and peers match.
148+
// 1. Check ports
149+
if rule.Protocols != nil {
150+
if !evaluateClusterNetworkPolicyProtocols(*rule.Protocols, dstPod, dstPort, protocol) {
149151
continue
150152
}
151153
}
154+
// 2. Check peers
155+
// An empty 'To' slice matches all destinations.
156+
if len(rule.To) == 0 {
157+
return rule.Action
158+
}
159+
160+
// If 'To' is not empty, at least one peer must match.
161+
peerMatches := false
152162
for _, to := range rule.To {
153163
if to.Namespaces != nil && dstPod != nil && networkpolicy.MatchesSelector(to.Namespaces, dstPod.Namespace.Labels) {
154-
return rule.Action
164+
peerMatches = true
165+
break
155166
}
156167

157168
if to.Pods != nil && dstPod != nil &&
158169
networkpolicy.MatchesSelector(&to.Pods.NamespaceSelector, dstPod.Namespace.Labels) &&
159170
networkpolicy.MatchesSelector(&to.Pods.PodSelector, dstPod.Labels) {
160-
return rule.Action
171+
peerMatches = true
172+
break
161173
}
162174

163175
if to.Nodes != nil && dstPod != nil && networkpolicy.MatchesSelector(to.Nodes, dstPod.Node.Labels) {
164-
return rule.Action
176+
peerMatches = true
177+
break
165178
}
166179

167180
for _, network := range to.Networks {
@@ -170,14 +183,27 @@ func (c *ClusterNetworkPolicy) evaluateClusterEgress(
170183
continue
171184
}
172185
if cidr.Contains(dstIP) {
173-
return rule.Action
186+
peerMatches = true
187+
break
174188
}
175189
}
190+
if peerMatches {
191+
break
192+
}
193+
176194
for _, domain := range to.DomainNames {
177195
if c.domainResolver != nil && c.domainResolver.ContainsIP(string(domain), dstIP) {
178-
return rule.Action
196+
peerMatches = true
197+
break
179198
}
180199
}
200+
if peerMatches {
201+
break
202+
}
203+
}
204+
205+
if peerMatches {
206+
return rule.Action
181207
}
182208
}
183209
}
@@ -197,63 +223,97 @@ func (c *ClusterNetworkPolicy) evaluateClusterIngress(
197223
}
198224
for _, policy := range policies {
199225
for _, rule := range policy.Spec.Ingress {
200-
if rule.Ports != nil {
201-
if !evaluateClusterNetworkPolicyPort(*rule.Ports, dstPod, dstPort, protocol) {
226+
// A rule matches if both its ports and peers match.
227+
// 1. Check ports and protocols
228+
if rule.Protocols != nil {
229+
if !evaluateClusterNetworkPolicyProtocols(*rule.Protocols, dstPod, dstPort, protocol) {
202230
continue
203231
}
204232
}
233+
234+
// 2. Check peers
235+
// An empty 'From' slice matches all sources.
236+
if len(rule.From) == 0 {
237+
return rule.Action
238+
}
239+
240+
// If 'From' is not empty, at least one peer must match.
241+
peerMatches := false
205242
for _, from := range rule.From {
206243
if from.Namespaces != nil && networkpolicy.MatchesSelector(from.Namespaces, srcPod.Namespace.Labels) {
207-
return rule.Action
244+
peerMatches = true
245+
break
208246
}
209247

210248
if from.Pods != nil &&
211249
networkpolicy.MatchesSelector(&from.Pods.NamespaceSelector, srcPod.Namespace.Labels) &&
212250
networkpolicy.MatchesSelector(&from.Pods.PodSelector, srcPod.Labels) {
213-
return rule.Action
251+
peerMatches = true
252+
break
214253
}
215254
}
255+
256+
if peerMatches {
257+
return rule.Action
258+
}
216259
}
217260
}
218261
return npav1alpha2.ClusterNetworkPolicyRuleActionPass
219262
}
220263

221-
// evaluateClusterNetworkPolicyPort checks if a specific port and protocol match any port selectors.
222-
func evaluateClusterNetworkPolicyPort(
223-
policyPorts []npav1alpha2.ClusterNetworkPolicyPort,
264+
// evaluateClusterNetworkPolicyProtocols checks if a specific port and protocol
265+
// match any port selectors.
266+
func evaluateClusterNetworkPolicyProtocols(
267+
protocols []npav1alpha2.ClusterNetworkPolicyProtocol,
224268
pod *api.PodInfo,
225269
port int,
226270
protocol v1.Protocol,
227271
) bool {
228-
if len(policyPorts) == 0 {
229-
return true
272+
if len(protocols) == 0 {
273+
return false
230274
}
231275

232-
for _, policyPort := range policyPorts {
233-
if policyPort.PortNumber != nil &&
234-
policyPort.PortNumber.Port == int32(port) &&
235-
policyPort.PortNumber.Protocol == protocol {
276+
for _, policy := range protocols {
277+
if evaluateProtocolPort(policy, pod, int32(port), protocol) {
236278
return true
237279
}
280+
}
238281

239-
if policyPort.NamedPort != nil {
240-
if pod == nil {
241-
continue
242-
}
243-
for _, containerPort := range pod.ContainerPorts {
244-
if containerPort.Name == *policyPort.NamedPort && v1.Protocol(containerPort.Protocol) == protocol && containerPort.Port == int32(port) {
245-
return true
246-
}
282+
return false
283+
}
284+
285+
func evaluateProtocolPort(
286+
policy npav1alpha2.ClusterNetworkPolicyProtocol,
287+
pod *api.PodInfo,
288+
port int32,
289+
protocol v1.Protocol,
290+
) bool {
291+
if policy.Protocol != protocol {
292+
return false
293+
}
294+
295+
switch {
296+
case policy.Port.Number != nil:
297+
return *policy.Port.Number == port
298+
299+
case policy.Port.Name != nil:
300+
if pod == nil {
301+
return false
302+
}
303+
for _, containerPort := range pod.ContainerPorts {
304+
nameOk := containerPort.Name == *policy.Port.Name
305+
portOk := containerPort.Port == port
306+
if nameOk && portOk {
307+
return true
247308
}
248309
}
249310

250-
if policyPort.PortRange != nil &&
251-
policyPort.PortRange.Protocol == protocol &&
252-
policyPort.PortRange.Start <= int32(port) &&
253-
policyPort.PortRange.End >= int32(port) {
311+
case policy.Port.Range != nil:
312+
if policy.Port.Range.Start <= port && port <= policy.Port.Range.End {
254313
return true
255314
}
256315
}
316+
257317
return false
258318
}
259319

0 commit comments

Comments
 (0)