diff --git a/mocks/pkg/ovs/interface.go b/mocks/pkg/ovs/interface.go index 0bfaeae93be..dcef2aa0e2e 100644 --- a/mocks/pkg/ovs/interface.go +++ b/mocks/pkg/ovs/interface.go @@ -1539,33 +1539,33 @@ func (mr *MockACLMockRecorder) SetLogicalSwitchPrivate(lsName, cidrBlock, nodeSw } // UpdateEgressACLOps mocks base method. -func (m *MockACL) UpdateEgressACLOps(pgName, asEgressName, asExceptName, protocol string, npp []v10.NetworkPolicyPort, logEnable bool, namedPortMap map[string]*util.NamedPortInfo) ([]ovsdb.Operation, error) { +func (m *MockACL) UpdateEgressACLOps(pgName, asEgressName, asExceptName, protocol, aclName string, npp []v10.NetworkPolicyPort, logEnable bool, logACLActions []ovnnb.ACLAction, namedPortMap map[string]*util.NamedPortInfo) ([]ovsdb.Operation, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UpdateEgressACLOps", pgName, asEgressName, asExceptName, protocol, npp, logEnable, namedPortMap) + ret := m.ctrl.Call(m, "UpdateEgressACLOps", pgName, asEgressName, asExceptName, protocol, aclName, npp, logEnable, logACLActions, namedPortMap) ret0, _ := ret[0].([]ovsdb.Operation) ret1, _ := ret[1].(error) return ret0, ret1 } // UpdateEgressACLOps indicates an expected call of UpdateEgressACLOps. -func (mr *MockACLMockRecorder) UpdateEgressACLOps(pgName, asEgressName, asExceptName, protocol, npp, logEnable, namedPortMap any) *gomock.Call { +func (mr *MockACLMockRecorder) UpdateEgressACLOps(pgName, asEgressName, asExceptName, protocol, aclName, npp, logEnable, logACLActions, namedPortMap any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateEgressACLOps", reflect.TypeOf((*MockACL)(nil).UpdateEgressACLOps), pgName, asEgressName, asExceptName, protocol, npp, logEnable, namedPortMap) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateEgressACLOps", reflect.TypeOf((*MockACL)(nil).UpdateEgressACLOps), pgName, asEgressName, asExceptName, protocol, aclName, npp, logEnable, logACLActions, namedPortMap) } // UpdateIngressACLOps mocks base method. -func (m *MockACL) UpdateIngressACLOps(pgName, asIngressName, asExceptName, protocol string, npp []v10.NetworkPolicyPort, logEnable bool, namedPortMap map[string]*util.NamedPortInfo) ([]ovsdb.Operation, error) { +func (m *MockACL) UpdateIngressACLOps(pgName, asIngressName, asExceptName, protocol, aclName string, npp []v10.NetworkPolicyPort, logEnable bool, logACLActions []ovnnb.ACLAction, namedPortMap map[string]*util.NamedPortInfo) ([]ovsdb.Operation, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UpdateIngressACLOps", pgName, asIngressName, asExceptName, protocol, npp, logEnable, namedPortMap) + ret := m.ctrl.Call(m, "UpdateIngressACLOps", pgName, asIngressName, asExceptName, protocol, aclName, npp, logEnable, logACLActions, namedPortMap) ret0, _ := ret[0].([]ovsdb.Operation) ret1, _ := ret[1].(error) return ret0, ret1 } // UpdateIngressACLOps indicates an expected call of UpdateIngressACLOps. -func (mr *MockACLMockRecorder) UpdateIngressACLOps(pgName, asIngressName, asExceptName, protocol, npp, logEnable, namedPortMap any) *gomock.Call { +func (mr *MockACLMockRecorder) UpdateIngressACLOps(pgName, asIngressName, asExceptName, protocol, aclName, npp, logEnable, logACLActions, namedPortMap any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateIngressACLOps", reflect.TypeOf((*MockACL)(nil).UpdateIngressACLOps), pgName, asIngressName, asExceptName, protocol, npp, logEnable, namedPortMap) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateIngressACLOps", reflect.TypeOf((*MockACL)(nil).UpdateIngressACLOps), pgName, asIngressName, asExceptName, protocol, aclName, npp, logEnable, logACLActions, namedPortMap) } // UpdateLogicalSwitchACL mocks base method. @@ -4016,33 +4016,33 @@ func (mr *MockNbClientMockRecorder) UpdateDnatAndSnat(lrName, externalIP, logica } // UpdateEgressACLOps mocks base method. -func (m *MockNbClient) UpdateEgressACLOps(pgName, asEgressName, asExceptName, protocol string, npp []v10.NetworkPolicyPort, logEnable bool, namedPortMap map[string]*util.NamedPortInfo) ([]ovsdb.Operation, error) { +func (m *MockNbClient) UpdateEgressACLOps(pgName, asEgressName, asExceptName, protocol, aclName string, npp []v10.NetworkPolicyPort, logEnable bool, logACLActions []ovnnb.ACLAction, namedPortMap map[string]*util.NamedPortInfo) ([]ovsdb.Operation, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UpdateEgressACLOps", pgName, asEgressName, asExceptName, protocol, npp, logEnable, namedPortMap) + ret := m.ctrl.Call(m, "UpdateEgressACLOps", pgName, asEgressName, asExceptName, protocol, aclName, npp, logEnable, logACLActions, namedPortMap) ret0, _ := ret[0].([]ovsdb.Operation) ret1, _ := ret[1].(error) return ret0, ret1 } // UpdateEgressACLOps indicates an expected call of UpdateEgressACLOps. -func (mr *MockNbClientMockRecorder) UpdateEgressACLOps(pgName, asEgressName, asExceptName, protocol, npp, logEnable, namedPortMap any) *gomock.Call { +func (mr *MockNbClientMockRecorder) UpdateEgressACLOps(pgName, asEgressName, asExceptName, protocol, aclName, npp, logEnable, logACLActions, namedPortMap any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateEgressACLOps", reflect.TypeOf((*MockNbClient)(nil).UpdateEgressACLOps), pgName, asEgressName, asExceptName, protocol, npp, logEnable, namedPortMap) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateEgressACLOps", reflect.TypeOf((*MockNbClient)(nil).UpdateEgressACLOps), pgName, asEgressName, asExceptName, protocol, aclName, npp, logEnable, logACLActions, namedPortMap) } // UpdateIngressACLOps mocks base method. -func (m *MockNbClient) UpdateIngressACLOps(pgName, asIngressName, asExceptName, protocol string, npp []v10.NetworkPolicyPort, logEnable bool, namedPortMap map[string]*util.NamedPortInfo) ([]ovsdb.Operation, error) { +func (m *MockNbClient) UpdateIngressACLOps(pgName, asIngressName, asExceptName, protocol, aclName string, npp []v10.NetworkPolicyPort, logEnable bool, logACLActions []ovnnb.ACLAction, namedPortMap map[string]*util.NamedPortInfo) ([]ovsdb.Operation, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UpdateIngressACLOps", pgName, asIngressName, asExceptName, protocol, npp, logEnable, namedPortMap) + ret := m.ctrl.Call(m, "UpdateIngressACLOps", pgName, asIngressName, asExceptName, protocol, aclName, npp, logEnable, logACLActions, namedPortMap) ret0, _ := ret[0].([]ovsdb.Operation) ret1, _ := ret[1].(error) return ret0, ret1 } // UpdateIngressACLOps indicates an expected call of UpdateIngressACLOps. -func (mr *MockNbClientMockRecorder) UpdateIngressACLOps(pgName, asIngressName, asExceptName, protocol, npp, logEnable, namedPortMap any) *gomock.Call { +func (mr *MockNbClientMockRecorder) UpdateIngressACLOps(pgName, asIngressName, asExceptName, protocol, aclName, npp, logEnable, logACLActions, namedPortMap any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateIngressACLOps", reflect.TypeOf((*MockNbClient)(nil).UpdateIngressACLOps), pgName, asIngressName, asExceptName, protocol, npp, logEnable, namedPortMap) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateIngressACLOps", reflect.TypeOf((*MockNbClient)(nil).UpdateIngressACLOps), pgName, asIngressName, asExceptName, protocol, aclName, npp, logEnable, logACLActions, namedPortMap) } // UpdateLogicalRouterPortOptions mocks base method. diff --git a/pkg/controller/network_policy.go b/pkg/controller/network_policy.go index 3343f80af59..3f39bd6f47a 100644 --- a/pkg/controller/network_policy.go +++ b/pkg/controller/network_policy.go @@ -20,6 +20,7 @@ import ( kubeovnv1 "github.com/kubeovn/kube-ovn/pkg/apis/kubeovn/v1" "github.com/kubeovn/kube-ovn/pkg/ovs" + "github.com/kubeovn/kube-ovn/pkg/ovsdb/ovnnb" "github.com/kubeovn/kube-ovn/pkg/util" ) @@ -160,6 +161,12 @@ func (c *Controller) handleUpdateNp(key string) error { if np.Annotations[util.NetworkPolicyLogAnnotation] == "true" { logEnable = true } + var logActions []string + if np.Annotations[util.ACLActionsLogAnnotation] != "" { + logActions = strings.Split(np.Annotations[util.ACLActionsLogAnnotation], ",") + } else { + logActions = []string{ovnnb.ACLActionDrop} + } npName := np.Name if nameArray := []rune(np.Name); !unicode.IsLetter(nameArray[0]) { @@ -259,6 +266,7 @@ func (c *Controller) handleUpdateNp(key string) error { // 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 ingressAllowAsName := fmt.Sprintf("%s.%s.%d", ingressAllowAsNamePrefix, protocol, idx) ingressExceptAsName := fmt.Sprintf("%s.%s.%d", ingressExceptAsNamePrefix, protocol, idx) + aclName := fmt.Sprintf("np/%s.%s/ingress/%s/%d", npName, np.Namespace, protocol, idx) var allows, excepts []string if len(npr.From) == 0 { @@ -309,7 +317,7 @@ func (c *Controller) handleUpdateNp(key string) error { npp = npr.Ports } - ops, err := c.OVNNbClient.UpdateIngressACLOps(pgName, ingressAllowAsName, ingressExceptAsName, protocol, npp, logEnable, namedPortMap) + ops, err := c.OVNNbClient.UpdateIngressACLOps(pgName, ingressAllowAsName, ingressExceptAsName, protocol, aclName, npp, logEnable, logActions, namedPortMap) if err != nil { klog.Errorf("generate operations that add ingress acls to np %s: %v", key, err) return err @@ -321,6 +329,7 @@ func (c *Controller) handleUpdateNp(key string) error { ingressAllowAsName := fmt.Sprintf("%s.%s.all", ingressAllowAsNamePrefix, protocol) ingressExceptAsName := fmt.Sprintf("%s.%s.all", ingressExceptAsNamePrefix, protocol) + aclName := fmt.Sprintf("np/%s.%s/ingress/%s/all", npName, np.Namespace, protocol) if err = c.OVNNbClient.CreateAddressSet(ingressAllowAsName, map[string]string{ networkPolicyKey: fmt.Sprintf("%s/%s/%s", np.Namespace, npName, "ingress"), }); err != nil { @@ -335,7 +344,7 @@ func (c *Controller) handleUpdateNp(key string) error { return err } - ops, err := c.OVNNbClient.UpdateIngressACLOps(pgName, ingressAllowAsName, ingressExceptAsName, protocol, []netv1.NetworkPolicyPort{}, logEnable, namedPortMap) + ops, err := c.OVNNbClient.UpdateIngressACLOps(pgName, ingressAllowAsName, ingressExceptAsName, protocol, aclName, nil, logEnable, logActions, namedPortMap) if err != nil { klog.Errorf("generate operations that add ingress acls to np %s: %v", key, err) return err @@ -411,6 +420,7 @@ func (c *Controller) handleUpdateNp(key string) error { // 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 egressAllowAsName := fmt.Sprintf("%s.%s.%d", egressAllowAsNamePrefix, protocol, idx) egressExceptAsName := fmt.Sprintf("%s.%s.%d", egressExceptAsNamePrefix, protocol, idx) + aclName := fmt.Sprintf("np/%s.%s/egress/%s/%d", npName, np.Namespace, protocol, idx) var allows, excepts []string if len(npr.To) == 0 { @@ -457,7 +467,7 @@ func (c *Controller) handleUpdateNp(key string) error { } if len(allows) != 0 || len(excepts) != 0 { - ops, err := c.OVNNbClient.UpdateEgressACLOps(pgName, egressAllowAsName, egressExceptAsName, protocol, npr.Ports, logEnable, namedPortMap) + ops, err := c.OVNNbClient.UpdateEgressACLOps(pgName, egressAllowAsName, egressExceptAsName, protocol, aclName, npr.Ports, logEnable, logActions, namedPortMap) if err != nil { klog.Errorf("generate operations that add egress acls to np %s: %v", key, err) return err @@ -470,6 +480,7 @@ func (c *Controller) handleUpdateNp(key string) error { egressAllowAsName := fmt.Sprintf("%s.%s.all", egressAllowAsNamePrefix, protocol) egressExceptAsName := fmt.Sprintf("%s.%s.all", egressExceptAsNamePrefix, protocol) + aclName := fmt.Sprintf("np/%s.%s/egress/%s/all", npName, np.Namespace, protocol) if err = c.OVNNbClient.CreateAddressSet(egressAllowAsName, map[string]string{ networkPolicyKey: fmt.Sprintf("%s/%s/%s", np.Namespace, npName, "egress"), }); err != nil { @@ -484,7 +495,7 @@ func (c *Controller) handleUpdateNp(key string) error { return err } - ops, err := c.OVNNbClient.UpdateEgressACLOps(pgName, egressAllowAsName, egressExceptAsName, protocol, []netv1.NetworkPolicyPort{}, logEnable, namedPortMap) + ops, err := c.OVNNbClient.UpdateEgressACLOps(pgName, egressAllowAsName, egressExceptAsName, protocol, aclName, nil, logEnable, logActions, namedPortMap) if err != nil { klog.Errorf("generate operations that add egress acls to np %s: %v", key, err) return err diff --git a/pkg/ovs/interface.go b/pkg/ovs/interface.go index bc6f9cad120..88da78745a9 100644 --- a/pkg/ovs/interface.go +++ b/pkg/ovs/interface.go @@ -117,8 +117,8 @@ type PortGroup interface { } type ACL interface { - UpdateIngressACLOps(pgName, asIngressName, asExceptName, protocol string, npp []netv1.NetworkPolicyPort, logEnable bool, namedPortMap map[string]*util.NamedPortInfo) ([]ovsdb.Operation, error) - UpdateEgressACLOps(pgName, asEgressName, asExceptName, protocol string, npp []netv1.NetworkPolicyPort, logEnable bool, namedPortMap map[string]*util.NamedPortInfo) ([]ovsdb.Operation, error) + UpdateIngressACLOps(pgName, asIngressName, asExceptName, protocol, aclName string, npp []netv1.NetworkPolicyPort, logEnable bool, logACLActions []ovnnb.ACLAction, namedPortMap map[string]*util.NamedPortInfo) ([]ovsdb.Operation, error) + UpdateEgressACLOps(pgName, asEgressName, asExceptName, protocol, aclName string, npp []netv1.NetworkPolicyPort, logEnable bool, logACLActions []ovnnb.ACLAction, namedPortMap map[string]*util.NamedPortInfo) ([]ovsdb.Operation, error) CreateGatewayACL(lsName, pgName, gateway string) error CreateNodeACL(pgName, nodeIPStr, joinIPStr string) error CreateSgDenyAllACL(sgName string) error diff --git a/pkg/ovs/ovn-nb-acl.go b/pkg/ovs/ovn-nb-acl.go index 0de6bf13950..7b57b67068d 100644 --- a/pkg/ovs/ovn-nb-acl.go +++ b/pkg/ovs/ovn-nb-acl.go @@ -8,6 +8,7 @@ import ( "github.com/ovn-org/libovsdb/model" "github.com/ovn-org/libovsdb/ovsdb" + "golang.org/x/exp/slices" netv1 "k8s.io/api/networking/v1" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/klog/v2" @@ -19,7 +20,7 @@ import ( ) // UpdateIngressACLOps return operation that creates an ingress ACL -func (c *OVNNbClient) UpdateIngressACLOps(pgName, asIngressName, asExceptName, protocol string, npp []netv1.NetworkPolicyPort, logEnable bool, namedPortMap map[string]*util.NamedPortInfo) ([]ovsdb.Operation, error) { +func (c *OVNNbClient) UpdateIngressACLOps(pgName, asIngressName, asExceptName, protocol, aclName string, npp []netv1.NetworkPolicyPort, logEnable bool, logACLActions []ovnnb.ACLAction, namedPortMap map[string]*util.NamedPortInfo) ([]ovsdb.Operation, error) { acls := make([]*ovnnb.ACL, 0) if strings.HasSuffix(asIngressName, ".0") || strings.HasSuffix(asIngressName, ".all") { @@ -47,7 +48,13 @@ func (c *OVNNbClient) UpdateIngressACLOps(pgName, asIngressName, asExceptName, p /* allow acl */ matches := newNetworkPolicyACLMatch(pgName, asIngressName, asExceptName, protocol, ovnnb.ACLDirectionToLport, npp, namedPortMap) for _, m := range matches { - allowACL, err := c.newACLWithoutCheck(pgName, ovnnb.ACLDirectionToLport, util.IngressAllowPriority, m, ovnnb.ACLActionAllowRelated) + options := func(acl *ovnnb.ACL) { + if logEnable && slices.Contains(logACLActions, ovnnb.ACLActionAllow) { + acl.Name = &aclName + acl.Log = true + } + } + allowACL, err := c.newACLWithoutCheck(pgName, ovnnb.ACLDirectionToLport, util.IngressAllowPriority, m, ovnnb.ACLActionAllowRelated, options) if err != nil { return nil, fmt.Errorf("new allow ingress acl for port group %s: %v", pgName, err) } @@ -64,7 +71,7 @@ func (c *OVNNbClient) UpdateIngressACLOps(pgName, asIngressName, asExceptName, p } // UpdateEgressACLOps return operation that creates an egress ACL -func (c *OVNNbClient) UpdateEgressACLOps(pgName, asEgressName, asExceptName, protocol string, npp []netv1.NetworkPolicyPort, logEnable bool, namedPortMap map[string]*util.NamedPortInfo) ([]ovsdb.Operation, error) { +func (c *OVNNbClient) UpdateEgressACLOps(pgName, asEgressName, asExceptName, protocol, aclName string, npp []netv1.NetworkPolicyPort, logEnable bool, logACLActions []ovnnb.ACLAction, namedPortMap map[string]*util.NamedPortInfo) ([]ovsdb.Operation, error) { acls := make([]*ovnnb.ACL, 0) if strings.HasSuffix(asEgressName, ".0") || strings.HasSuffix(asEgressName, ".all") { @@ -103,6 +110,10 @@ func (c *OVNNbClient) UpdateEgressACLOps(pgName, asEgressName, asExceptName, pro acl.Options = make(map[string]string) } acl.Options["apply-after-lb"] = "true" + if logEnable && slices.Contains(logACLActions, ovnnb.ACLActionAllow) { + acl.Name = &aclName + acl.Log = true + } }) if err != nil { klog.Error(err) diff --git a/pkg/ovs/ovn-nb-acl_test.go b/pkg/ovs/ovn-nb-acl_test.go index 5eee9267743..19eca6bf716 100644 --- a/pkg/ovs/ovn-nb-acl_test.go +++ b/pkg/ovs/ovn-nb-acl_test.go @@ -84,13 +84,14 @@ func (suite *OvnClientTestSuite) testUpdateIngressACLOps() { asIngressName := "test.default.ingress.allow.ipv4.all" asExceptName := "test.default.ingress.except.ipv4.all" protocol := kubeovnv1.ProtocolIPv4 + aclName := "test_create_v4_ingress_acl_pg" err := ovnClient.CreatePortGroup(pgName, nil) require.NoError(t, err) npp := mockNetworkPolicyPort() - ops, err := ovnClient.UpdateIngressACLOps(pgName, asIngressName, asExceptName, protocol, npp, true, nil) + ops, err := ovnClient.UpdateIngressACLOps(pgName, asIngressName, asExceptName, protocol, aclName, npp, true, nil, nil) require.NoError(t, err) require.Len(t, ops, 4) @@ -112,11 +113,12 @@ func (suite *OvnClientTestSuite) testUpdateIngressACLOps() { asIngressName := "test.default.ingress.allow.ipv6.all" asExceptName := "test.default.ingress.except.ipv6.all" protocol := kubeovnv1.ProtocolIPv6 + aclName := "test_create_v6_ingress_acl_pg" err := ovnClient.CreatePortGroup(pgName, nil) require.NoError(t, err) - ops, err := ovnClient.UpdateIngressACLOps(pgName, asIngressName, asExceptName, protocol, nil, true, nil) + ops, err := ovnClient.UpdateIngressACLOps(pgName, asIngressName, asExceptName, protocol, aclName, nil, true, nil, nil) require.NoError(t, err) require.Len(t, ops, 3) @@ -154,13 +156,14 @@ func (suite *OvnClientTestSuite) testUpdateEgressACLOps() { asEgressName := "test.default.egress.allow.ipv4.all" asExceptName := "test.default.egress.except.ipv4.all" protocol := kubeovnv1.ProtocolIPv4 + aclName := "test_create_v4_egress_acl_pg" err := ovnClient.CreatePortGroup(pgName, nil) require.NoError(t, err) npp := mockNetworkPolicyPort() - ops, err := ovnClient.UpdateEgressACLOps(pgName, asEgressName, asExceptName, protocol, npp, true, nil) + ops, err := ovnClient.UpdateEgressACLOps(pgName, asEgressName, asExceptName, protocol, aclName, npp, true, nil, nil) require.NoError(t, err) require.Len(t, ops, 4) @@ -182,11 +185,12 @@ func (suite *OvnClientTestSuite) testUpdateEgressACLOps() { asEgressName := "test.default.egress.allow.ipv6.all" asExceptName := "test.default.egress.except.ipv6.all" protocol := kubeovnv1.ProtocolIPv6 + aclName := "test_create_v6_egress_acl_pg" err := ovnClient.CreatePortGroup(pgName, nil) require.NoError(t, err) - ops, err := ovnClient.UpdateEgressACLOps(pgName, asEgressName, asExceptName, protocol, nil, true, nil) + ops, err := ovnClient.UpdateEgressACLOps(pgName, asEgressName, asExceptName, protocol, aclName, nil, true, nil, nil) require.NoError(t, err) require.Len(t, ops, 3) diff --git a/pkg/util/const.go b/pkg/util/const.go index 1db2044f81f..78cf0a88fa9 100644 --- a/pkg/util/const.go +++ b/pkg/util/const.go @@ -109,6 +109,7 @@ const ( QoSLabel = "ovn.kubernetes.io/qos" NodeNameLabel = "ovn.kubernetes.io/node-name" NetworkPolicyLogAnnotation = "ovn.kubernetes.io/enable_log" + ACLActionsLogAnnotation = "ovn.kubernetes.io/log_acl_actions" VpcLastName = "ovn.kubernetes.io/last_vpc_name" VpcLastPolicies = "ovn.kubernetes.io/last_policies"