From d0063e3cca6597544f17fc3d930bc881d1263000 Mon Sep 17 00:00:00 2001 From: changluyi <47097611+changluyi@users.noreply.github.com> Date: Mon, 14 Aug 2023 13:42:01 +0800 Subject: [PATCH] add mulicast snoop switch (#3129) * add mulicast snoop switch * add mock --- charts/templates/kube-ovn-crd.yaml | 2 ++ dist/images/install.sh | 2 ++ mocks/pkg/ovs/interface.go | 28 ++++++++++++++++++++++ pkg/apis/kubeovn/v1/types.go | 1 + pkg/controller/subnet.go | 14 +++++++++++ pkg/ovs/interface.go | 1 + pkg/ovs/ovn-nb-logical_switch.go | 38 ++++++++++++++++++++++++++++++ yamls/crd.yaml | 2 ++ 8 files changed, 88 insertions(+) diff --git a/charts/templates/kube-ovn-crd.yaml b/charts/templates/kube-ovn-crd.yaml index fae15ed101d..399b4a88d76 100644 --- a/charts/templates/kube-ovn-crd.yaml +++ b/charts/templates/kube-ovn-crd.yaml @@ -1760,6 +1760,8 @@ spec: type: boolean enableEcmp: type: boolean + enableMulticastSnoop: + type: boolean routeTable: type: string scope: Cluster diff --git a/dist/images/install.sh b/dist/images/install.sh index ca582e94a94..1fd552199a8 100755 --- a/dist/images/install.sh +++ b/dist/images/install.sh @@ -2299,6 +2299,8 @@ spec: type: boolean enableEcmp: type: boolean + enableMulticastSnoop: + type: boolean routeTable: type: string scope: Cluster diff --git a/mocks/pkg/ovs/interface.go b/mocks/pkg/ovs/interface.go index f2f42d78a67..cd5d7081564 100644 --- a/mocks/pkg/ovs/interface.go +++ b/mocks/pkg/ovs/interface.go @@ -577,6 +577,20 @@ func (mr *MockLogicalSwitchMockRecorder) LogicalSwitchUpdateLoadBalancers(lsName return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LogicalSwitchUpdateLoadBalancers", reflect.TypeOf((*MockLogicalSwitch)(nil).LogicalSwitchUpdateLoadBalancers), varargs...) } +// LogicalSwitchUpdateOtherConfig mocks base method. +func (m *MockLogicalSwitch) LogicalSwitchUpdateOtherConfig(lsName string, op ovsdb.Mutator, otherConfig map[string]string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "LogicalSwitchUpdateOtherConfig", lsName, op, otherConfig) + ret0, _ := ret[0].(error) + return ret0 +} + +// LogicalSwitchUpdateOtherConfig indicates an expected call of LogicalSwitchUpdateOtherConfig. +func (mr *MockLogicalSwitchMockRecorder) LogicalSwitchUpdateOtherConfig(lsName, op, otherConfig interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LogicalSwitchUpdateOtherConfig", reflect.TypeOf((*MockLogicalSwitch)(nil).LogicalSwitchUpdateOtherConfig), lsName, op, otherConfig) +} + // MockLogicalSwitchPort is a mock of LogicalSwitchPort interface. type MockLogicalSwitchPort struct { ctrl *gomock.Controller @@ -3172,6 +3186,20 @@ func (mr *MockOvnClientMockRecorder) LogicalSwitchUpdateLoadBalancers(lsName, op return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LogicalSwitchUpdateLoadBalancers", reflect.TypeOf((*MockOvnClient)(nil).LogicalSwitchUpdateLoadBalancers), varargs...) } +// LogicalSwitchUpdateOtherConfig mocks base method. +func (m *MockOvnClient) LogicalSwitchUpdateOtherConfig(lsName string, op ovsdb.Mutator, otherConfig map[string]string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "LogicalSwitchUpdateOtherConfig", lsName, op, otherConfig) + ret0, _ := ret[0].(error) + return ret0 +} + +// LogicalSwitchUpdateOtherConfig indicates an expected call of LogicalSwitchUpdateOtherConfig. +func (mr *MockOvnClientMockRecorder) LogicalSwitchUpdateOtherConfig(lsName, op, otherConfig interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LogicalSwitchUpdateOtherConfig", reflect.TypeOf((*MockOvnClient)(nil).LogicalSwitchUpdateOtherConfig), lsName, op, otherConfig) +} + // NatExists mocks base method. func (m *MockOvnClient) NatExists(lrName, natType, externalIP, logicalIP string) (bool, error) { m.ctrl.T.Helper() diff --git a/pkg/apis/kubeovn/v1/types.go b/pkg/apis/kubeovn/v1/types.go index bd4fb4150e5..f1dcea75b88 100644 --- a/pkg/apis/kubeovn/v1/types.go +++ b/pkg/apis/kubeovn/v1/types.go @@ -166,6 +166,7 @@ type SubnetSpec struct { U2OInterconnection bool `json:"u2oInterconnection,omitempty"` EnableLb *bool `json:"enableLb,omitempty"` EnableEcmp bool `json:"enableEcmp,omitempty"` + EnableMulicastSnoop bool `json:"enableMulticastSnoop,omitempty"` RouteTable string `json:"routeTable,omitempty"` } diff --git a/pkg/controller/subnet.go b/pkg/controller/subnet.go index 1acaa5bc040..f3893dd5f02 100644 --- a/pkg/controller/subnet.go +++ b/pkg/controller/subnet.go @@ -104,6 +104,7 @@ func (c *Controller) enqueueUpdateSubnet(old, new interface{}) { oldSubnet.Spec.RouteTable != newSubnet.Spec.RouteTable || oldSubnet.Spec.Vpc != newSubnet.Spec.Vpc || oldSubnet.Spec.NatOutgoing != newSubnet.Spec.NatOutgoing || + oldSubnet.Spec.EnableMulicastSnoop != newSubnet.Spec.EnableMulicastSnoop || !reflect.DeepEqual(oldSubnet.Spec.NatOutgoingPolicyRules, newSubnet.Spec.NatOutgoingPolicyRules) || (newSubnet.Spec.U2OInterconnection && newSubnet.Spec.U2OInterconnectionIP != "" && oldSubnet.Spec.U2OInterconnectionIP != newSubnet.Spec.U2OInterconnectionIP) { @@ -758,6 +759,19 @@ func (c *Controller) handleAddOrUpdateSubnet(key string) error { return err } + multicastSnoopFlag := map[string]string{"mcast_snoop": "true", "mcast_querier": "false"} + if subnet.Spec.EnableMulicastSnoop { + if err := c.ovnClient.LogicalSwitchUpdateOtherConfig(subnet.Name, ovsdb.MutateOperationInsert, multicastSnoopFlag); err != nil { + klog.Errorf("enable logical switch multicast snoop %s: %v", subnet.Name, err) + return err + } + } else { + if err := c.ovnClient.LogicalSwitchUpdateOtherConfig(subnet.Name, ovsdb.MutateOperationDelete, multicastSnoopFlag); err != nil { + klog.Errorf("disable logical switch multicast snoop %s: %v", subnet.Name, err) + return err + } + } + subnet.Status.EnsureStandardConditions() if err := c.updateSubnetDHCPOption(subnet, needRouter); err != nil { diff --git a/pkg/ovs/interface.go b/pkg/ovs/interface.go index 4d3acc9ac67..c8eded24184 100644 --- a/pkg/ovs/interface.go +++ b/pkg/ovs/interface.go @@ -50,6 +50,7 @@ type LogicalSwitch interface { CreateLogicalSwitch(lsName, lrName, cidrBlock, gateway string, needRouter, randomAllocateGW bool) error CreateBareLogicalSwitch(lsName string) error LogicalSwitchUpdateLoadBalancers(lsName string, op ovsdb.Mutator, lbNames ...string) error + LogicalSwitchUpdateOtherConfig(lsName string, op ovsdb.Mutator, otherConfig map[string]string) error DeleteLogicalSwitch(lsName string) error ListLogicalSwitch(needVendorFilter bool, filter func(ls *ovnnb.LogicalSwitch) bool) ([]ovnnb.LogicalSwitch, error) LogicalSwitchExists(lsName string) (bool, error) diff --git a/pkg/ovs/ovn-nb-logical_switch.go b/pkg/ovs/ovn-nb-logical_switch.go index 0a69c56a158..7024de8720d 100644 --- a/pkg/ovs/ovn-nb-logical_switch.go +++ b/pkg/ovs/ovn-nb-logical_switch.go @@ -170,6 +170,25 @@ func (c *ovnClient) LogicalSwitchUpdateLoadBalancers(lsName string, op ovsdb.Mut return nil } +// LogicalSwitchUpdateOtherConfig add other config to or from logical switch once +func (c *ovnClient) LogicalSwitchUpdateOtherConfig(lsName string, op ovsdb.Mutator, otherConfig map[string]string) error { + if len(otherConfig) == 0 { + return nil + } + + ops, err := c.LogicalSwitchUpdateOtherConfigOp(lsName, otherConfig, op) + if err != nil { + klog.Error(err) + return fmt.Errorf("generate operations for logical switch %s update other config %v: %v", lsName, otherConfig, err) + } + + if err := c.Transact("ls-other-config-update", ops); err != nil { + return fmt.Errorf("logical switch %s update other config %v: %v", lsName, otherConfig, err) + } + + return nil +} + // DeleteLogicalSwitch delete logical switch func (c *ovnClient) DeleteLogicalSwitch(lsName string) error { op, err := c.DeleteLogicalSwitchOp(lsName) @@ -286,6 +305,25 @@ func (c *ovnClient) LogicalSwitchUpdatePortOp(lsName string, lspUUID string, op return c.LogicalSwitchOp(lsName, mutation) } +// LogicalSwitchUpdateOtherConfigOp create operations add otherConfig to or delete otherConfig from logical switch +func (c *ovnClient) LogicalSwitchUpdateOtherConfigOp(lsName string, otherConfig map[string]string, op ovsdb.Mutator) ([]ovsdb.Operation, error) { + if len(otherConfig) == 0 { + return nil, nil + } + + mutation := func(ls *ovnnb.LogicalSwitch) *model.Mutation { + mutation := &model.Mutation{ + Field: &ls.OtherConfig, + Value: otherConfig, + Mutator: op, + } + + return mutation + } + + return c.LogicalSwitchOp(lsName, mutation) +} + // LogicalSwitchUpdateLoadBalancerOp create operations add lb to or delete lb from logical switch func (c *ovnClient) LogicalSwitchUpdateLoadBalancerOp(lsName string, lbUUIDs []string, op ovsdb.Mutator) ([]ovsdb.Operation, error) { if len(lbUUIDs) == 0 { diff --git a/yamls/crd.yaml b/yamls/crd.yaml index 3b7b14e16e7..c7be4c63754 100644 --- a/yamls/crd.yaml +++ b/yamls/crd.yaml @@ -2071,6 +2071,8 @@ spec: type: boolean enableEcmp: type: boolean + enableMulticastSnoop: + type: boolean scope: Cluster names: plural: subnets