Skip to content

Commit c8c47b8

Browse files
fix: [NPM-WIN] validate sctp (#1442)
* validate sctp for windows * fix lint
1 parent 7db16e8 commit c8c47b8

File tree

8 files changed

+57
-25
lines changed

8 files changed

+57
-25
lines changed

npm/pkg/controlplane/controllers/v2/namespaceController.go

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,6 @@ import (
2626
"k8s.io/klog"
2727
)
2828

29-
type LabelAppendOperation bool
30-
31-
const (
32-
clearExistingLabels LabelAppendOperation = true
33-
appendToExistingLabels LabelAppendOperation = false
34-
)
35-
3629
var errWorkqueueFormatting = errors.New("error in formatting")
3730

3831
// NpmNamespaceCache to store namespace struct in nameSpaceController.go.
@@ -238,6 +231,10 @@ func (nsc *NamespaceController) syncNamespace(nsKey string) error {
238231
// apply dataplane and record exec time after syncing
239232
operationKind := metrics.NoOp
240233
defer func() {
234+
if err != nil {
235+
klog.Infof("[syncNamespace] failed to sync namespace, but will apply any changes to the dataplane. err: %s", err.Error())
236+
}
237+
241238
dperr := nsc.dp.ApplyDataPlane()
242239

243240
// NOTE: it may seem like Prometheus is considering some ns create events as updates.
@@ -248,7 +245,11 @@ func (nsc *NamespaceController) syncNamespace(nsKey string) error {
248245
metrics.RecordControllerNamespaceExecTime(timer, operationKind, err != nil && dperr != nil)
249246

250247
if dperr != nil {
251-
err = fmt.Errorf("failed with error %w, apply failed with %v", err, dperr)
248+
if err == nil {
249+
err = fmt.Errorf("failed to apply dataplane changes while syncing namespace. err: %w", dperr)
250+
} else {
251+
err = fmt.Errorf("failed to sync namespace and apply dataplane changes. sync err: [%w], apply err: [%v]", err, dperr)
252+
}
252253
}
253254
}()
254255

@@ -270,7 +271,7 @@ func (nsc *NamespaceController) syncNamespace(nsKey string) error {
270271
if err != nil {
271272
// need to retry this cleaning-up process
272273
metrics.SendErrorLogAndMetric(util.NSID, "Error: %v when namespace is not found", err)
273-
return fmt.Errorf("Error: %w when namespace is not found", err)
274+
return fmt.Errorf("error: %w when namespace is not found", err)
274275
}
275276
}
276277
return err

npm/pkg/controlplane/controllers/v2/networkPolicyController.go

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -285,14 +285,17 @@ func (c *NetworkPolicyController) syncAddAndUpdateNetPol(netPolObj *networkingv1
285285
// install translated rules into kernel
286286
npmNetPolObj, err := translation.TranslatePolicy(netPolObj)
287287
if err != nil {
288-
if errors.Is(err, translation.ErrUnsupportedNamedPort) || errors.Is(err, translation.ErrUnsupportedNegativeMatch) {
289-
// We can safely suppress unsupported network policy because re-Queuing will result in same error
290-
klog.Warningf("NetworkPolicy %s in namespace %s is not translated because it has unsupported translated features of Windows.", netPolObj.ObjectMeta.Name, netPolObj.ObjectMeta.Namespace)
291-
// consider a no-op since we the policy is unsupported. The exec time here isn't important either.
288+
if isUnsupportedWindowsTranslationErr(err) {
289+
klog.Warningf("NetworkPolicy %s in namespace %s is not translated because it has unsupported translated features of Windows: %s",
290+
netPolObj.ObjectMeta.Name, netPolObj.ObjectMeta.Namespace, err.Error())
291+
292+
// We can safely suppress unsupported network policy because re-Queuing will result in same error.
293+
// The exec time isn't relevant here, so consider a no-op.
292294
return metrics.NoOp, nil
293295
}
296+
294297
klog.Errorf("Failed to translate podSelector in NetworkPolicy %s in namespace %s: %s", netPolObj.ObjectMeta.Name, netPolObj.ObjectMeta.Namespace, err.Error())
295-
// consider a no-op since we can't translate. The exec time here isn't important either.
298+
// The exec time isn't relevant here, so consider a no-op.
296299
return metrics.NoOp, errNetPolTranslationFailure
297300
}
298301

@@ -342,3 +345,9 @@ func (c *NetworkPolicyController) cleanUpNetworkPolicy(netPolKey string) error {
342345
metrics.DecNumPolicies()
343346
return nil
344347
}
348+
349+
func isUnsupportedWindowsTranslationErr(err error) bool {
350+
return errors.Is(err, translation.ErrUnsupportedNamedPort) ||
351+
errors.Is(err, translation.ErrUnsupportedNegativeMatch) ||
352+
errors.Is(err, translation.ErrUnsupportedSCTP)
353+
}

npm/pkg/controlplane/controllers/v2/podController.go

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -260,11 +260,21 @@ func (c *PodController) syncPod(key string) error {
260260
// apply dataplane and record exec time after syncing
261261
operationKind := metrics.NoOp
262262
defer func() {
263+
if err != nil {
264+
klog.Infof("[syncPod] failed to sync pod, but will apply any changes to the dataplane. err: %s", err.Error())
265+
}
266+
263267
dperr := c.dp.ApplyDataPlane()
268+
264269
// can't record this in another deferred func since deferred funcs are processed in LIFO order
265270
metrics.RecordControllerPodExecTime(timer, operationKind, err != nil && dperr != nil)
271+
266272
if dperr != nil {
267-
err = fmt.Errorf("failed with error %w, apply failed with %v", err, dperr)
273+
if err == nil {
274+
err = fmt.Errorf("failed to apply dataplane changes while syncing pod. err: %w", dperr)
275+
} else {
276+
err = fmt.Errorf("failed to sync pod and apply dataplane changes. sync err: [%w], apply err: [%v]", err, dperr)
277+
}
268278
}
269279
}()
270280

@@ -285,7 +295,7 @@ func (c *PodController) syncPod(key string) error {
285295
err = c.cleanUpDeletedPod(key)
286296
if err != nil {
287297
// need to retry this cleaning-up process
288-
return fmt.Errorf("Error: %w when pod is not found", err)
298+
return fmt.Errorf("error: %w when pod is not found", err)
289299
}
290300
return err
291301
}
@@ -302,7 +312,7 @@ func (c *PodController) syncPod(key string) error {
302312
operationKind = metrics.DeleteOp
303313
}
304314
if err = c.cleanUpDeletedPod(key); err != nil {
305-
return fmt.Errorf("Error: %w when when pod is in completed state", err)
315+
return fmt.Errorf("error: %w when when pod is in completed state", err)
306316
}
307317
return nil
308318
}
@@ -319,7 +329,7 @@ func (c *PodController) syncPod(key string) error {
319329

320330
operationKind, err = c.syncAddAndUpdatePod(pod)
321331
if err != nil {
322-
return fmt.Errorf("Failed to sync pod due to %w", err)
332+
return fmt.Errorf("failed to sync pod due to %w", err)
323333
}
324334

325335
return nil

npm/pkg/controlplane/translation/translatePolicy.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99
"github.com/Azure/azure-container-networking/npm/util"
1010
networkingv1 "k8s.io/api/networking/v1"
1111
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
12-
"k8s.io/klog/v2"
1312
)
1413

1514
/*
@@ -25,6 +24,8 @@ var (
2524
ErrUnsupportedNamedPort = errors.New("unsupported namedport translation features used on windows")
2625
// ErrUnsupportedNegativeMatch is returned when negative match translation feature is used in windows.
2726
ErrUnsupportedNegativeMatch = errors.New("unsupported NotExist operator translation features used on windows")
27+
// ErrUnsupportedSCTP is returned when SCTP protocol is used in windows.
28+
ErrUnsupportedSCTP = errors.New("unsupported SCTP protocol used on windows")
2829
)
2930

3031
type podSelectorResult struct {
@@ -48,7 +49,6 @@ func portType(portRule networkingv1.NetworkPolicyPort) (netpolPortType, error) {
4849
return numericPortType, nil
4950
} else if portRule.Port.IntValue() == 0 && portRule.Port.String() != "" {
5051
if util.IsWindowsDP() {
51-
klog.Warningf("Windows does not support named port. Use numeric port instead.")
5252
return "", ErrUnsupportedNamedPort
5353
}
5454
return namedPortType, nil
@@ -578,5 +578,14 @@ func TranslatePolicy(npObj *networkingv1.NetworkPolicy) (*policies.NPMNetworkPol
578578
}
579579
}
580580
}
581+
582+
// ad-hoc validation to reduce code changes (modifying function signatures and returning errors in all the correct places)
583+
if util.IsWindowsDP() {
584+
for _, acl := range npmNetPol.ACLs {
585+
if acl.Protocol == policies.SCTP {
586+
return nil, ErrUnsupportedSCTP
587+
}
588+
}
589+
}
581590
return npmNetPol, nil
582591
}

npm/pkg/controlplane/translation/translatePolicy_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1629,7 +1629,7 @@ func TestIngressPolicy(t *testing.T) {
16291629
},
16301630
},
16311631
{
1632-
name: "error",
1632+
name: "unknown port type error",
16331633
isNewNwPolicyVer: true,
16341634
targetSelector: &metav1.LabelSelector{
16351635
MatchLabels: map[string]string{
@@ -2284,7 +2284,7 @@ func TestEgressPolicy(t *testing.T) {
22842284
},
22852285
},
22862286
{
2287-
name: "error",
2287+
name: "unknown port type error",
22882288
isNewNwPolicyVer: true,
22892289
targetSelector: &metav1.LabelSelector{
22902290
MatchLabels: map[string]string{

npm/pkg/dataplane/dataplane_windows.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,6 @@ func (dp *DataPlane) refreshAllPodEndpoints() error {
273273
currentTime := time.Now().Unix()
274274
existingIPs := make(map[string]struct{})
275275
for _, endpoint := range endpoints {
276-
klog.Infof("Endpoints info %+v", endpoint.Id)
277276
if len(endpoint.IpConfigurations) == 0 {
278277
klog.Infof("Endpoint ID %s has no IPAddreses", endpoint.Id)
279278
continue
@@ -335,6 +334,8 @@ func (dp *DataPlane) refreshAllPodEndpoints() error {
335334
}
336335
}
337336

337+
klog.Infof("Endpoint cache after refresh: %+v", dp.endpointCache) // TODO: remove for public preview
338+
338339
return nil
339340
}
340341

npm/pkg/dataplane/policies/policy.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,6 @@ func NormalizePolicy(networkPolicy *NPMNetworkPolicy) {
131131
}
132132
}
133133

134-
// TODO do verification in controller?
135134
func ValidatePolicy(networkPolicy *NPMNetworkPolicy) error {
136135
for _, aclPolicy := range networkPolicy.ACLs {
137136
if !aclPolicy.hasKnownTarget() {
@@ -143,6 +142,10 @@ func ValidatePolicy(networkPolicy *NPMNetworkPolicy) error {
143142
if !aclPolicy.hasKnownProtocol() {
144143
return npmerrors.SimpleError(fmt.Sprintf("ACL policy for NetPol %s has unknown protocol [%s]", networkPolicy.PolicyKey, aclPolicy.Protocol))
145144
}
145+
if util.IsWindowsDP() && aclPolicy.Protocol == SCTP {
146+
return npmerrors.SimpleError(fmt.Sprintf("ACL policy for NetPol %s has unsupported SCTP protocol on Windows", networkPolicy.PolicyKey))
147+
}
148+
146149
if !aclPolicy.satisifiesPortAndProtocolConstraints() {
147150
return npmerrors.SimpleError(fmt.Sprintf(
148151
"ACL policy for NetPol %s has dst port(s) (Port or Port and EndPort), so must have protocol tcp, udp, udplite, sctp, or dccp but has protocol %s",

npm/pkg/dataplane/policies/policymanager.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,6 @@ func (pMgr *PolicyManager) AddPolicy(policy *NPMNetworkPolicy, endpointList map[
111111
return nil
112112
}
113113

114-
// TODO move this validation and normalization to controller
115114
NormalizePolicy(policy)
116115
if err := ValidatePolicy(policy); err != nil {
117116
msg := fmt.Sprintf("failed to validate policy: %s", err.Error())

0 commit comments

Comments
 (0)