From a877a48111fda3cddb0c01d1aef76ff0a59c0ba6 Mon Sep 17 00:00:00 2001 From: wenyingd Date: Mon, 9 Aug 2021 07:23:01 -0700 Subject: [PATCH] Modify OF table name Signed-off-by: wenyingd --- go.mod | 4 +- go.sum | 9 +- .../apiserver/handlers/ovsflows/handler.go | 14 +- .../handlers/ovsflows/handler_test.go | 7 + .../controller/networkpolicy/packetin.go | 18 +- pkg/agent/controller/traceflow/packetin.go | 32 +- .../controller/traceflow/packetin_test.go | 8 +- pkg/agent/openflow/client_test.go | 2 +- pkg/agent/openflow/network_policy.go | 12 +- pkg/agent/openflow/network_policy_test.go | 76 ++-- pkg/agent/openflow/pipeline.go | 392 +++++++++--------- pkg/agent/openflow/pipeline_windows.go | 12 +- pkg/agent/querier/querier.go | 4 +- pkg/agent/querier/querier_test.go | 1 + pkg/antctl/antctl.go | 7 +- pkg/ovs/openflow/interfaces.go | 12 +- pkg/ovs/openflow/ofctrl_action.go | 8 +- pkg/ovs/openflow/ofctrl_bridge.go | 100 ++++- pkg/ovs/openflow/ofctrl_flow.go | 2 +- pkg/ovs/openflow/ofctrl_flow_test.go | 16 +- pkg/ovs/openflow/ofctrl_group.go | 2 +- pkg/ovs/ovsctl/interface.go | 3 + pkg/ovs/ovsctl/ofctl.go | 18 +- pkg/ovs/ovsctl/testing/mock_ovsctl.go | 19 + plugins/octant/go.sum | 5 +- test/integration/agent/openflow_test.go | 4 +- test/integration/ovs/ofctrl_test.go | 100 +++-- test/integration/ovs/openflow_test_utils.go | 4 +- 28 files changed, 505 insertions(+), 386 deletions(-) diff --git a/go.mod b/go.mod index b09b6cd8ec8..cc6e7e91c25 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,8 @@ module antrea.io/antrea go 1.17 require ( - antrea.io/libOpenflow v0.2.0 - antrea.io/ofnet v0.1.0 + antrea.io/libOpenflow v0.3.1 + antrea.io/ofnet v0.2.0 github.com/Mellanox/sriovnet v1.0.2 github.com/Microsoft/go-winio v0.4.16-0.20201130162521-d1ffc52c7331 github.com/Microsoft/hcsshim v0.8.9 diff --git a/go.sum b/go.sum index 9a5b09a32d0..b5a8f57424b 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,8 @@ -antrea.io/libOpenflow v0.2.0 h1:bBNT3CI8q2FMQRdphP0dynImRK1LBDmA+cQOu7JULj4= -antrea.io/libOpenflow v0.2.0/go.mod h1:CzEJZxDNAupiGxeL5VOw92PsxfyvehEAvE3PiC6gr8o= -antrea.io/ofnet v0.1.0 h1:r5c/TM5pa8xSVd5xEUj1L2vYfc4EjIzCWs6cHbeuVFc= -antrea.io/ofnet v0.1.0/go.mod h1:fLmHHD9XWeVza2pz/HEdLkGyA7pNutxlXCqodlwWQsA= +antrea.io/libOpenflow v0.3.0/go.mod h1:CzEJZxDNAupiGxeL5VOw92PsxfyvehEAvE3PiC6gr8o= +antrea.io/libOpenflow v0.3.1 h1:zDu2TGxZYbrBCHxHq4o4TKgA7iRk+PfSW6y+nJSBsu4= +antrea.io/libOpenflow v0.3.1/go.mod h1:CzEJZxDNAupiGxeL5VOw92PsxfyvehEAvE3PiC6gr8o= +antrea.io/ofnet v0.2.0 h1:NtiV7Ax2hv23NQukem3vEvMQuQNL1+1kPZEFSRRnZ60= +antrea.io/ofnet v0.2.0/go.mod h1:t9GyuMB4FWTdC54ChMWP/146nRJfX1YHPGP49EYEa1s= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= diff --git a/pkg/agent/apiserver/handlers/ovsflows/handler.go b/pkg/agent/apiserver/handlers/ovsflows/handler.go index ac7afcaa41c..35a0a7a37bf 100644 --- a/pkg/agent/apiserver/handlers/ovsflows/handler.go +++ b/pkg/agent/apiserver/handlers/ovsflows/handler.go @@ -50,12 +50,12 @@ func dumpMatchedFlows(aq agentquerier.AgentQuerier, flowKeys []string) ([]Respon return resps, nil } -func dumpFlows(aq agentquerier.AgentQuerier, table binding.TableIDType) ([]Response, error) { +func dumpFlows(aq agentquerier.AgentQuerier, table uint8) ([]Response, error) { resps := []Response{} var flowStrs []string var err error - if table != binding.TableIDAll { - flowStrs, err = aq.GetOVSCtlClient().DumpTableFlows(uint8(table)) + if table != binding.TableIDAll.GetID() { + flowStrs, err = aq.GetOVSCtlClient().DumpTableFlows(table) } else { flowStrs, err = aq.GetOVSCtlClient().DumpFlows() } @@ -89,17 +89,17 @@ func getTableFlows(aq agentquerier.AgentQuerier, tables string) ([]Response, err var resps []Response for _, tableSeg := range strings.Split(tables, ",") { tableSeg = strings.TrimSpace(tableSeg) - var tableNumber binding.TableIDType + var tableNumber uint8 // Table nubmer is a 8-bit unsigned integer. n, err := strconv.ParseUint(tableSeg, 10, 8) if err == nil { - tableNumber = binding.TableIDType(n) + tableNumber = uint8(n) if openflow.GetFlowTableName(tableNumber) == "" { return nil, nil } } else { tableNumber = openflow.GetFlowTableNumber(tableSeg) - if tableNumber == binding.TableIDAll { + if tableNumber == binding.TableIDAll.GetID() { return nil, nil } } @@ -197,7 +197,7 @@ func HandleFunc(aq agentquerier.AgentQuerier) http.HandlerFunc { } if pod == "" && service == "" && networkPolicy == "" && namespace == "" && table == "" && groups == "" { - resps, err = dumpFlows(aq, binding.TableIDAll) + resps, err = dumpFlows(aq, binding.TableIDAll.GetID()) } else if pod != "" { // Pod Namespace must be provided to dump flows of a Pod. resps, err = getPodFlows(aq, pod, namespace) diff --git a/pkg/agent/apiserver/handlers/ovsflows/handler_test.go b/pkg/agent/apiserver/handlers/ovsflows/handler_test.go index d115f490742..12912961694 100644 --- a/pkg/agent/apiserver/handlers/ovsflows/handler_test.go +++ b/pkg/agent/apiserver/handlers/ovsflows/handler_test.go @@ -25,12 +25,14 @@ import ( "antrea.io/antrea/pkg/agent/interfacestore" interfacestoretest "antrea.io/antrea/pkg/agent/interfacestore/testing" + "antrea.io/antrea/pkg/agent/openflow" oftest "antrea.io/antrea/pkg/agent/openflow/testing" proxytest "antrea.io/antrea/pkg/agent/proxy/testing" agentquerier "antrea.io/antrea/pkg/agent/querier" aqtest "antrea.io/antrea/pkg/agent/querier/testing" cpv1beta "antrea.io/antrea/pkg/apis/controlplane/v1beta2" binding "antrea.io/antrea/pkg/ovs/openflow" + "antrea.io/antrea/pkg/ovs/ovsconfig" ovsctltest "antrea.io/antrea/pkg/ovs/ovsctl/testing" "antrea.io/antrea/pkg/querier" queriertest "antrea.io/antrea/pkg/querier/testing" @@ -131,6 +133,11 @@ func TestServiceFlows(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() + // Create openflow.Client to ensure the OVS tables are added into the cache. + bridgeName := "testbr" + bridgeMgmtAddr := binding.GetMgmtAddress(ovsconfig.DefaultOVSRunDir, bridgeName) + openflow.NewClient(bridgeName, bridgeMgmtAddr, ovsconfig.OVSDatapathSystem, true, false, false, false) + testcases := []testCase{ { test: "Existing Service", diff --git a/pkg/agent/controller/networkpolicy/packetin.go b/pkg/agent/controller/networkpolicy/packetin.go index ed4ccdf8c7d..597e1647c9f 100644 --- a/pkg/agent/controller/networkpolicy/packetin.go +++ b/pkg/agent/controller/networkpolicy/packetin.go @@ -94,19 +94,19 @@ func getMatchRegField(matchers *ofctrl.Matchers, field *binding.RegField) *ofctr // getMatch receives ofctrl matchers and table id, match field. // Modifies match field to Ingress/Egress register based on tableID. -func getMatch(matchers *ofctrl.Matchers, tableID binding.TableIDType, disposition uint32) *ofctrl.MatchField { +func getMatch(matchers *ofctrl.Matchers, tableID uint8, disposition uint32) *ofctrl.MatchField { // Get match from CNPDenyConjIDReg if disposition is not allow. if disposition != openflow.DispositionAllow { return getMatchRegField(matchers, openflow.CNPDenyConjIDField) } // Get match from ingress/egress reg if disposition is allow for _, table := range append(openflow.GetAntreaPolicyEgressTables(), openflow.EgressRuleTable) { - if tableID == table { + if tableID == table.GetID() { return getMatchRegField(matchers, openflow.TFEgressConjIDField) } } for _, table := range append(openflow.GetAntreaPolicyIngressTables(), openflow.IngressRuleTable) { - if tableID == table { + if tableID == table.GetID() { return getMatchRegField(matchers, openflow.TFIngressConjIDField) } } @@ -130,7 +130,7 @@ func getNetworkPolicyInfo(pktIn *ofctrl.PacketIn, c *Controller, ob *logInfo) er matchers := pktIn.GetMatches() var match *ofctrl.MatchField // Get table name - tableID := binding.TableIDType(pktIn.TableId) + tableID := pktIn.TableId ob.tableName = openflow.GetFlowTableName(tableID) // Get disposition Allow or Drop @@ -326,7 +326,7 @@ func (c *Controller) storeDenyConnection(pktIn *ofctrl.PacketIn) error { matchers := pktIn.GetMatches() var match *ofctrl.MatchField // Get table ID - tableID := binding.TableIDType(pktIn.TableId) + tableID := pktIn.TableId // Get disposition Allow, Drop or Reject match = getMatchRegField(matchers, openflow.APDispositionField) id, err := getInfoInReg(match, openflow.APDispositionField.GetRange().ToNXRange()) @@ -336,10 +336,10 @@ func (c *Controller) storeDenyConnection(pktIn *ofctrl.PacketIn) error { disposition := openflow.DispositionToString[id] // For K8s NetworkPolicy implicit drop action, we cannot get name/namespace. - if tableID == openflow.IngressDefaultTable { + if tableID == openflow.IngressDefaultTable.GetID() { denyConn.IngressNetworkPolicyType = registry.PolicyTypeK8sNetworkPolicy denyConn.IngressNetworkPolicyRuleAction = flowexporter.RuleActionToUint8(disposition) - } else if tableID == openflow.EgressDefaultTable { + } else if tableID == openflow.EgressDefaultTable.GetID() { denyConn.EgressNetworkPolicyType = registry.PolicyTypeK8sNetworkPolicy denyConn.EgressNetworkPolicyRuleAction = flowexporter.RuleActionToUint8(disposition) } else { // Get name and namespace for Antrea Network Policy or Antrea Cluster Network Policy @@ -356,13 +356,13 @@ func (c *Controller) storeDenyConnection(pktIn *ofctrl.PacketIn) error { // Default drop by K8s NetworkPolicy klog.V(4).Infof("Cannot find NetworkPolicy or rule that has ruleID %v", ruleID) } else { - if tableID == openflow.AntreaPolicyIngressRuleTable { + if tableID == openflow.AntreaPolicyIngressRuleTable.GetID() { denyConn.IngressNetworkPolicyName = policy.Name denyConn.IngressNetworkPolicyNamespace = policy.Namespace denyConn.IngressNetworkPolicyType = flowexporter.PolicyTypeToUint8(policy.Type) denyConn.IngressNetworkPolicyRuleName = rule.Name denyConn.IngressNetworkPolicyRuleAction = flowexporter.RuleActionToUint8(disposition) - } else if tableID == openflow.AntreaPolicyEgressRuleTable { + } else if tableID == openflow.AntreaPolicyEgressRuleTable.GetID() { denyConn.EgressNetworkPolicyName = policy.Name denyConn.EgressNetworkPolicyNamespace = policy.Namespace denyConn.EgressNetworkPolicyType = flowexporter.PolicyTypeToUint8(policy.Type) diff --git a/pkg/agent/controller/traceflow/packetin.go b/pkg/agent/controller/traceflow/packetin.go index dba0bc0f2ba..fafbe0dad29 100644 --- a/pkg/agent/controller/traceflow/packetin.go +++ b/pkg/agent/controller/traceflow/packetin.go @@ -205,8 +205,8 @@ func (c *Controller) parsePacketIn(pktIn *ofctrl.PacketIn) (*crdv1alpha1.Tracefl } // Get drop table. - if tableID == uint8(openflow.EgressMetricTable) || tableID == uint8(openflow.IngressMetricTable) { - ob := getNetworkPolicyObservation(tableID, tableID == uint8(openflow.IngressMetricTable)) + if tableID == openflow.EgressMetricTable.GetID() || tableID == openflow.IngressMetricTable.GetID() { + ob := getNetworkPolicyObservation(tableID, tableID == openflow.IngressMetricTable.GetID()) if match := getMatchRegField(matchers, openflow.CNPDenyConjIDField); match != nil { notAllowConjInfo, err := getRegValue(match, nil) if err != nil { @@ -222,13 +222,13 @@ func (c *Controller) parsePacketIn(pktIn *ofctrl.PacketIn) (*crdv1alpha1.Tracefl } } obs = append(obs, *ob) - } else if tableID == uint8(openflow.EgressDefaultTable) || tableID == uint8(openflow.IngressDefaultTable) { - ob := getNetworkPolicyObservation(tableID, tableID == uint8(openflow.IngressDefaultTable)) + } else if tableID == openflow.EgressDefaultTable.GetID() || tableID == openflow.IngressDefaultTable.GetID() { + ob := getNetworkPolicyObservation(tableID, tableID == openflow.IngressDefaultTable.GetID()) obs = append(obs, *ob) } // Get output table. - if tableID == uint8(openflow.L2ForwardingOutTable) { + if tableID == openflow.L2ForwardingOutTable.GetID() { ob := new(crdv1alpha1.Observation) tunnelDstIP := "" isIPv6 := c.nodeConfig.NodeIPAddr.IP.To4() == nil @@ -262,7 +262,7 @@ func (c *Controller) parsePacketIn(pktIn *ofctrl.PacketIn) (*crdv1alpha1.Tracefl // Output port is Pod port, packet is delivered. ob.Action = crdv1alpha1.ActionDelivered } - ob.ComponentInfo = openflow.GetFlowTableName(binding.TableIDType(tableID)) + ob.ComponentInfo = openflow.L2ForwardingOutTable.GetName() ob.Component = crdv1alpha1.ComponentForwarding obs = append(obs, *ob) } @@ -340,22 +340,30 @@ func getNetworkPolicyObservation(tableID uint8, ingress bool) *crdv1alpha1.Obser ob.Component = crdv1alpha1.ComponentNetworkPolicy if ingress { switch tableID { - case uint8(openflow.IngressMetricTable), uint8(openflow.IngressDefaultTable): + case openflow.IngressMetricTable.GetID(): // Packet dropped by ANP/default drop rule - ob.ComponentInfo = openflow.GetFlowTableName(binding.TableIDType(tableID)) + ob.ComponentInfo = openflow.IngressMetricTable.GetName() + ob.Action = crdv1alpha1.ActionDropped + case openflow.IngressDefaultTable.GetID(): + // Packet dropped by ANP/default drop rule + ob.ComponentInfo = openflow.IngressDefaultTable.GetName() ob.Action = crdv1alpha1.ActionDropped default: - ob.ComponentInfo = openflow.GetFlowTableName(openflow.IngressRuleTable) + ob.ComponentInfo = openflow.IngressRuleTable.GetName() ob.Action = crdv1alpha1.ActionForwarded } } else { switch tableID { - case uint8(openflow.EgressMetricTable), uint8(openflow.EgressDefaultTable): + case openflow.EgressMetricTable.GetID(): + // Packet dropped by ANP/default drop rule + ob.ComponentInfo = openflow.EgressMetricTable.GetName() + ob.Action = crdv1alpha1.ActionDropped + case openflow.EgressDefaultTable.GetID(): // Packet dropped by ANP/default drop rule - ob.ComponentInfo = openflow.GetFlowTableName(binding.TableIDType(tableID)) + ob.ComponentInfo = openflow.EgressDefaultTable.GetName() ob.Action = crdv1alpha1.ActionDropped default: - ob.ComponentInfo = openflow.GetFlowTableName(openflow.EgressRuleTable) + ob.ComponentInfo = openflow.EgressRuleTable.GetName() ob.Action = crdv1alpha1.ActionForwarded } } diff --git a/pkg/agent/controller/traceflow/packetin_test.go b/pkg/agent/controller/traceflow/packetin_test.go index 96c6cceb275..2cc437bb340 100644 --- a/pkg/agent/controller/traceflow/packetin_test.go +++ b/pkg/agent/controller/traceflow/packetin_test.go @@ -41,7 +41,7 @@ func Test_getNetworkPolicyObservation(t *testing.T) { { name: "ingress metric drop", args: args{ - tableID: uint8(openflow.IngressMetricTable), + tableID: openflow.IngressMetricTable.GetID(), ingress: true, }, want: &crdv1alpha1.Observation{ @@ -53,7 +53,7 @@ func Test_getNetworkPolicyObservation(t *testing.T) { { name: "ingress accept", args: args{ - tableID: uint8(openflow.L2ForwardingOutTable), + tableID: openflow.L2ForwardingOutTable.GetID(), ingress: true, }, want: &crdv1alpha1.Observation{ @@ -65,7 +65,7 @@ func Test_getNetworkPolicyObservation(t *testing.T) { { name: "egress default drop", args: args{ - tableID: uint8(openflow.EgressDefaultTable), + tableID: openflow.EgressDefaultTable.GetID(), ingress: false, }, want: &crdv1alpha1.Observation{ @@ -77,7 +77,7 @@ func Test_getNetworkPolicyObservation(t *testing.T) { { name: "egress accept", args: args{ - tableID: uint8(openflow.L2ForwardingOutTable), + tableID: openflow.L2ForwardingOutTable.GetID(), ingress: false, }, want: &crdv1alpha1.Observation{ diff --git a/pkg/agent/openflow/client_test.go b/pkg/agent/openflow/client_test.go index d2e4f3edd57..0c7d33eb572 100644 --- a/pkg/agent/openflow/client_test.go +++ b/pkg/agent/openflow/client_test.go @@ -402,7 +402,7 @@ func prepareTraceflowFlow(ctrl *gomock.Controller) *client { mFlow := ovsoftest.NewMockFlow(ctrl) ctx := &conjMatchFlowContext{dropFlow: mFlow} mFlow.EXPECT().FlowProtocol().Return(binding.Protocol("ip")) - mFlow.EXPECT().CopyToBuilder(priorityNormal+2, false).Return(c.pipeline[EgressDefaultTable].BuildFlow(priorityNormal + 2)).Times(1) + mFlow.EXPECT().CopyToBuilder(priorityNormal+2, false).Return(getTableByTableID(EgressDefaultTable).BuildFlow(priorityNormal + 2)).Times(1) c.globalConjMatchFlowCache["mockContext"] = ctx c.policyCache.Add(&policyRuleConjunction{metricFlows: []binding.Flow{c.denyRuleMetricFlow(123, false)}}) return c diff --git a/pkg/agent/openflow/network_policy.go b/pkg/agent/openflow/network_policy.go index d500e7d6289..103fb077b0f 100644 --- a/pkg/agent/openflow/network_policy.go +++ b/pkg/agent/openflow/network_policy.go @@ -234,7 +234,7 @@ func (m *conjunctiveMatch) generateGlobalMapKey() string { } else { priorityStr = strconv.Itoa(int(*m.priority)) } - return fmt.Sprintf("table:%d,priority:%s,type:%v,value:%s", m.tableID, priorityStr, matchType, valueStr) + return fmt.Sprintf("table:%d,priority:%s,type:%v,value:%s", m.tableID.GetID(), priorityStr, matchType, valueStr) } // changeType is generally used to describe the change type of a conjMatchFlowContext. It is also used in "flowChange" @@ -1138,12 +1138,12 @@ func (c *policyRuleConjunction) calculateClauses(rule *types.PolicyRule, clnt *c var isEgressRule = false switch rule.Direction { case v1beta2.DirectionOut: - dropTable = clnt.pipeline[EgressDefaultTable] + dropTable = getTableByTableID(EgressDefaultTable) isEgressRule = true default: - dropTable = clnt.pipeline[IngressDefaultTable] + dropTable = getTableByTableID(IngressDefaultTable) } - ruleTable := clnt.pipeline[rule.TableID] + ruleTable := getTableByTableID(rule.TableID) var fromID, toID, serviceID, nClause uint8 // Calculate clause IDs and the total number of clauses. @@ -1642,8 +1642,8 @@ func parseMetricFlow(flow string) (uint32, types.RuleMetric) { func (c *client) NetworkPolicyMetrics() map[uint32]*types.RuleMetric { result := map[uint32]*types.RuleMetric{} - egressFlows, _ := c.ovsctlClient.DumpTableFlows(uint8(EgressMetricTable)) - ingressFlows, _ := c.ovsctlClient.DumpTableFlows(uint8(IngressMetricTable)) + egressFlows, _ := c.ovsctlClient.DumpTableFlows(EgressMetricTable.GetID()) + ingressFlows, _ := c.ovsctlClient.DumpTableFlows(IngressMetricTable.GetID()) collectMetricsFromFlows := func(flows []string) { for _, flow := range flows { diff --git a/pkg/agent/openflow/network_policy_test.go b/pkg/agent/openflow/network_policy_test.go index 86bbb6916c8..c7590cbd40a 100644 --- a/pkg/agent/openflow/network_policy_test.go +++ b/pkg/agent/openflow/network_policy_test.go @@ -334,50 +334,50 @@ func TestBatchInstallPolicyRuleFlows(t *testing.T) { cookiePolicy := c.cookieAllocator.Request(cookie.Policy).Raw() cookieDefault := c.cookieAllocator.Request(cookie.Default).Raw() return []binding.Flow{ - c.pipeline[EgressRuleTable].BuildFlow(priorityLow).Cookie(cookiePolicy). + getTableByTableID(EgressRuleTable).BuildFlow(priorityLow).Cookie(cookiePolicy). MatchProtocol(binding.ProtocolIP).MatchConjID(10). Action().LoadToRegField(TFEgressConjIDField, 10). Action().CT(true, EgressMetricTable, CtZone).LoadToLabelField(10, EgressRuleCTLabel).CTDone().Done(), - c.pipeline[EgressRuleTable].BuildFlow(priorityLow).Cookie(cookiePolicy). + getTableByTableID(EgressRuleTable).BuildFlow(priorityLow).Cookie(cookiePolicy). MatchProtocol(binding.ProtocolIP).MatchConjID(11). Action().LoadToRegField(TFEgressConjIDField, 11). Action().CT(true, EgressMetricTable, CtZone).LoadToLabelField(11, EgressRuleCTLabel).CTDone().Done(), - c.pipeline[EgressRuleTable].BuildFlow(priorityNormal).Cookie(cookiePolicy). + getTableByTableID(EgressRuleTable).BuildFlow(priorityNormal).Cookie(cookiePolicy). MatchProtocol(binding.ProtocolIP).MatchSrcIP(net.ParseIP("192.168.1.40")). Action().Conjunction(10, 1, 2). Action().Conjunction(11, 1, 3).Done(), - c.pipeline[EgressRuleTable].BuildFlow(priorityNormal).Cookie(cookiePolicy). + getTableByTableID(EgressRuleTable).BuildFlow(priorityNormal).Cookie(cookiePolicy). MatchProtocol(binding.ProtocolIP).MatchSrcIP(net.ParseIP("192.168.1.50")). Action().Conjunction(10, 1, 2).Done(), - c.pipeline[EgressRuleTable].BuildFlow(priorityNormal).Cookie(cookiePolicy). + getTableByTableID(EgressRuleTable).BuildFlow(priorityNormal).Cookie(cookiePolicy). MatchProtocol(binding.ProtocolIP).MatchSrcIP(net.ParseIP("192.168.1.51")). Action().Conjunction(11, 1, 3).Done(), - c.pipeline[EgressRuleTable].BuildFlow(priorityNormal).Cookie(cookiePolicy). + getTableByTableID(EgressRuleTable).BuildFlow(priorityNormal).Cookie(cookiePolicy). MatchProtocol(binding.ProtocolIP).MatchDstIPNet(*ip.MustParseCIDR("0.0.0.0/0")). Action().Conjunction(10, 2, 2). Action().Conjunction(11, 2, 3).Done(), - c.pipeline[EgressRuleTable].BuildFlow(priorityNormal).Cookie(cookiePolicy). + getTableByTableID(EgressRuleTable).BuildFlow(priorityNormal).Cookie(cookiePolicy). MatchProtocol(binding.ProtocolTCP).MatchDstPort(8080, nil). Action().Conjunction(11, 3, 3).Done(), - c.pipeline[EgressDefaultTable].BuildFlow(priorityNormal).Cookie(cookieDefault). + getTableByTableID(EgressDefaultTable).BuildFlow(priorityNormal).Cookie(cookieDefault). MatchProtocol(binding.ProtocolIP).MatchSrcIP(net.ParseIP("192.168.1.40")). Action().Drop().Done(), - c.pipeline[EgressDefaultTable].BuildFlow(priorityNormal).Cookie(cookieDefault). + getTableByTableID(EgressDefaultTable).BuildFlow(priorityNormal).Cookie(cookieDefault). MatchProtocol(binding.ProtocolIP).MatchSrcIP(net.ParseIP("192.168.1.50")). Action().Drop().Done(), - c.pipeline[EgressDefaultTable].BuildFlow(priorityNormal).Cookie(cookieDefault). + getTableByTableID(EgressDefaultTable).BuildFlow(priorityNormal).Cookie(cookieDefault). MatchProtocol(binding.ProtocolIP).MatchSrcIP(net.ParseIP("192.168.1.51")). Action().Drop().Done(), - c.pipeline[EgressMetricTable].BuildFlow(priorityNormal).Cookie(cookiePolicy). + getTableByTableID(EgressMetricTable).BuildFlow(priorityNormal).Cookie(cookiePolicy). MatchProtocol(binding.ProtocolIP).MatchCTStateNew(true).MatchCTLabelField(0, uint64(10)<<32, EgressRuleCTLabel). Action().GotoTable(l3ForwardingTable).Done(), - c.pipeline[EgressMetricTable].BuildFlow(priorityNormal).Cookie(cookiePolicy). + getTableByTableID(EgressMetricTable).BuildFlow(priorityNormal).Cookie(cookiePolicy). MatchProtocol(binding.ProtocolIP).MatchCTStateNew(false).MatchCTLabelField(0, uint64(10)<<32, EgressRuleCTLabel). Action().GotoTable(l3ForwardingTable).Done(), - c.pipeline[EgressMetricTable].BuildFlow(priorityNormal).Cookie(cookiePolicy). + getTableByTableID(EgressMetricTable).BuildFlow(priorityNormal).Cookie(cookiePolicy). MatchProtocol(binding.ProtocolIP).MatchCTStateNew(true).MatchCTLabelField(0, uint64(11)<<32, EgressRuleCTLabel). Action().GotoTable(l3ForwardingTable).Done(), - c.pipeline[EgressMetricTable].BuildFlow(priorityNormal).Cookie(cookiePolicy). + getTableByTableID(EgressMetricTable).BuildFlow(priorityNormal).Cookie(cookiePolicy). MatchProtocol(binding.ProtocolIP).MatchCTStateNew(false).MatchCTLabelField(0, uint64(11)<<32, EgressRuleCTLabel). Action().GotoTable(l3ForwardingTable).Done(), } @@ -439,62 +439,62 @@ func TestBatchInstallPolicyRuleFlows(t *testing.T) { expectedFlowsFn: func(c *client) []binding.Flow { cookiePolicy := c.cookieAllocator.Request(cookie.Policy).Raw() return []binding.Flow{ - c.pipeline[AntreaPolicyIngressRuleTable].BuildFlow(priority100).Cookie(cookiePolicy). + getTableByTableID(AntreaPolicyIngressRuleTable).BuildFlow(priority100).Cookie(cookiePolicy). MatchProtocol(binding.ProtocolIP).MatchConjID(10). Action().LoadToRegField(TFIngressConjIDField, 10). Action().CT(true, IngressMetricTable, CtZone).LoadToLabelField(10, IngressRuleCTLabel).CTDone().Done(), - c.pipeline[AntreaPolicyIngressRuleTable].BuildFlow(priority100).Cookie(cookiePolicy). + getTableByTableID(AntreaPolicyIngressRuleTable).BuildFlow(priority100).Cookie(cookiePolicy). MatchConjID(11). Action().LoadToRegField(CNPDenyConjIDField, 11). Action().LoadRegMark(CnpDenyRegMark). Action().GotoTable(IngressMetricTable).Done(), - c.pipeline[AntreaPolicyIngressRuleTable].BuildFlow(priority200).Cookie(cookiePolicy). + getTableByTableID(AntreaPolicyIngressRuleTable).BuildFlow(priority200).Cookie(cookiePolicy). MatchConjID(12). Action().LoadToRegField(CNPDenyConjIDField, 12). Action().LoadRegMark(CnpDenyRegMark). Action().GotoTable(IngressMetricTable).Done(), - c.pipeline[AntreaPolicyIngressRuleTable].BuildFlow(priority100).Cookie(cookiePolicy). + getTableByTableID(AntreaPolicyIngressRuleTable).BuildFlow(priority100).Cookie(cookiePolicy). MatchProtocol(binding.ProtocolIP).MatchSrcIP(net.ParseIP("192.168.1.40")). Action().Conjunction(10, 1, 2). Action().Conjunction(11, 1, 3).Done(), - c.pipeline[AntreaPolicyIngressRuleTable].BuildFlow(priority200).Cookie(cookiePolicy). + getTableByTableID(AntreaPolicyIngressRuleTable).BuildFlow(priority200).Cookie(cookiePolicy). MatchProtocol(binding.ProtocolIP).MatchSrcIP(net.ParseIP("192.168.1.40")). Action().Conjunction(12, 1, 3).Done(), - c.pipeline[AntreaPolicyIngressRuleTable].BuildFlow(priority100).Cookie(cookiePolicy). + getTableByTableID(AntreaPolicyIngressRuleTable).BuildFlow(priority100).Cookie(cookiePolicy). MatchProtocol(binding.ProtocolIP).MatchSrcIP(net.ParseIP("192.168.1.50")). Action().Conjunction(10, 1, 2).Done(), - c.pipeline[AntreaPolicyIngressRuleTable].BuildFlow(priority100).Cookie(cookiePolicy). + getTableByTableID(AntreaPolicyIngressRuleTable).BuildFlow(priority100).Cookie(cookiePolicy). MatchProtocol(binding.ProtocolIP).MatchSrcIP(net.ParseIP("192.168.1.51")). Action().Conjunction(11, 1, 3).Done(), - c.pipeline[AntreaPolicyIngressRuleTable].BuildFlow(priority100).Cookie(cookiePolicy). + getTableByTableID(AntreaPolicyIngressRuleTable).BuildFlow(priority100).Cookie(cookiePolicy). MatchRegFieldWithValue(TargetOFPortField, uint32(1)). Action().Conjunction(10, 2, 2). Action().Conjunction(11, 2, 3).Done(), - c.pipeline[AntreaPolicyIngressRuleTable].BuildFlow(priority200).Cookie(cookiePolicy). + getTableByTableID(AntreaPolicyIngressRuleTable).BuildFlow(priority200).Cookie(cookiePolicy). MatchRegFieldWithValue(TargetOFPortField, uint32(1)). Action().Conjunction(12, 2, 3).Done(), - c.pipeline[AntreaPolicyIngressRuleTable].BuildFlow(priority100).Cookie(cookiePolicy). + getTableByTableID(AntreaPolicyIngressRuleTable).BuildFlow(priority100).Cookie(cookiePolicy). MatchRegFieldWithValue(TargetOFPortField, uint32(2)). Action().Conjunction(10, 2, 2).Done(), - c.pipeline[AntreaPolicyIngressRuleTable].BuildFlow(priority100).Cookie(cookiePolicy). + getTableByTableID(AntreaPolicyIngressRuleTable).BuildFlow(priority100).Cookie(cookiePolicy). MatchRegFieldWithValue(TargetOFPortField, uint32(3)). Action().Conjunction(11, 2, 3).Done(), - c.pipeline[AntreaPolicyIngressRuleTable].BuildFlow(priority100).Cookie(cookiePolicy). + getTableByTableID(AntreaPolicyIngressRuleTable).BuildFlow(priority100).Cookie(cookiePolicy). MatchProtocol(binding.ProtocolTCP).MatchDstPort(8080, nil). Action().Conjunction(11, 3, 3).Done(), - c.pipeline[AntreaPolicyIngressRuleTable].BuildFlow(priority200).Cookie(cookiePolicy). + getTableByTableID(AntreaPolicyIngressRuleTable).BuildFlow(priority200).Cookie(cookiePolicy). MatchProtocol(binding.ProtocolTCP).MatchDstPort(8080, nil). Action().Conjunction(12, 3, 3).Done(), - c.pipeline[IngressMetricTable].BuildFlow(priorityNormal).Cookie(cookiePolicy). + getTableByTableID(IngressMetricTable).BuildFlow(priorityNormal).Cookie(cookiePolicy). MatchProtocol(binding.ProtocolIP).MatchCTStateNew(true).MatchCTLabelField(0, 10, IngressRuleCTLabel). Action().GotoTable(conntrackCommitTable).Done(), - c.pipeline[IngressMetricTable].BuildFlow(priorityNormal).Cookie(cookiePolicy). + getTableByTableID(IngressMetricTable).BuildFlow(priorityNormal).Cookie(cookiePolicy). MatchProtocol(binding.ProtocolIP).MatchCTStateNew(false).MatchCTLabelField(0, 10, IngressRuleCTLabel). Action().GotoTable(conntrackCommitTable).Done(), - c.pipeline[IngressMetricTable].BuildFlow(priorityNormal).Cookie(cookiePolicy). + getTableByTableID(IngressMetricTable).BuildFlow(priorityNormal).Cookie(cookiePolicy). MatchRegMark(CnpDenyRegMark).MatchRegFieldWithValue(CNPDenyConjIDField, 11). Action().Drop().Done(), - c.pipeline[IngressMetricTable].BuildFlow(priorityNormal).Cookie(cookiePolicy). + getTableByTableID(IngressMetricTable).BuildFlow(priorityNormal).Cookie(cookiePolicy). MatchRegMark(CnpDenyRegMark).MatchRegFieldWithValue(CNPDenyConjIDField, 12). Action().Drop().Done(), } @@ -618,7 +618,7 @@ func TestConjMatchFlowContextKeyConflict(t *testing.T) { err = c.applyConjunctiveMatchFlows(flowChange2) require.Nil(t, err, "no error expect in applyConjunctiveMatchFlows") - expectedMatchKey := fmt.Sprintf("table:%d,priority:%s,type:%v,value:%s", EgressRuleTable, strconv.Itoa(int(priorityNormal)), MatchDstIPNet, ipNet.String()) + expectedMatchKey := fmt.Sprintf("table:%d,priority:%s,type:%v,value:%s", EgressRuleTable.GetID(), strconv.Itoa(int(priorityNormal)), MatchDstIPNet, ipNet.String()) ctx, found := c.globalConjMatchFlowCache[expectedMatchKey] assert.True(t, found) assert.Equal(t, 2, len(ctx.actions)) @@ -938,6 +938,7 @@ func createMockTable(ctrl *gomock.Controller, tableID binding.TableIDType, nextT table.EXPECT().GetID().Return(tableID).AnyTimes() table.EXPECT().GetNext().Return(nextTable).AnyTimes() table.EXPECT().GetMissAction().Return(missAction).AnyTimes() + flowTableCache.Update(table) return table } @@ -954,13 +955,6 @@ func prepareClient(ctrl *gomock.Controller) *client { metricTable = createMockTable(ctrl, EgressMetricTable, l3ForwardingTable, binding.TableMissActionNext) outAllowTable = createMockTable(ctrl, l3ForwardingTable, l2ForwardingCalcTable, binding.TableMissActionNext) c = &client{ - pipeline: map[binding.TableIDType]binding.Table{ - AntreaPolicyEgressRuleTable: cnpOutTable, - EgressRuleTable: outTable, - EgressDefaultTable: outDropTable, - EgressMetricTable: metricTable, - l3ForwardingTable: outAllowTable, - }, policyCache: policyCache, globalConjMatchFlowCache: map[string]*conjMatchFlowContext{}, bridge: bridge, @@ -1101,8 +1095,8 @@ func TestNetworkPolicyMetrics(t *testing.T) { mockOVSClient := ovsctltest.NewMockOVSCtlClient(ctrl) c.ovsctlClient = mockOVSClient gomock.InOrder( - mockOVSClient.EXPECT().DumpTableFlows(uint8(EgressMetricTable)).Return(tt.egressFlows, nil), - mockOVSClient.EXPECT().DumpTableFlows(uint8(IngressMetricTable)).Return(tt.ingressFlows, nil), + mockOVSClient.EXPECT().DumpTableFlows(EgressMetricTable.GetID()).Return(tt.egressFlows, nil), + mockOVSClient.EXPECT().DumpTableFlows(IngressMetricTable.GetID()).Return(tt.ingressFlows, nil), ) got := c.NetworkPolicyMetrics() assert.Equal(t, tt.want, got) diff --git a/pkg/agent/openflow/pipeline.go b/pkg/agent/openflow/pipeline.go index 187e30f9bf9..bfee39bea82 100644 --- a/pkg/agent/openflow/pipeline.go +++ b/pkg/agent/openflow/pipeline.go @@ -20,7 +20,6 @@ import ( "math" "net" "sort" - "strings" "sync" "time" @@ -40,37 +39,37 @@ import ( "antrea.io/antrea/third_party/proxy" ) -const ( +var ( // Flow table id index - ClassifierTable binding.TableIDType = 0 - uplinkTable binding.TableIDType = 5 - spoofGuardTable binding.TableIDType = 10 - arpResponderTable binding.TableIDType = 20 - ipv6Table binding.TableIDType = 21 - serviceHairpinTable binding.TableIDType = 29 - conntrackTable binding.TableIDType = 30 - conntrackStateTable binding.TableIDType = 31 - sessionAffinityTable binding.TableIDType = 40 - dnatTable binding.TableIDType = 40 - serviceLBTable binding.TableIDType = 41 - endpointDNATTable binding.TableIDType = 42 - AntreaPolicyEgressRuleTable binding.TableIDType = 45 - DefaultTierEgressRuleTable binding.TableIDType = 49 - EgressRuleTable binding.TableIDType = 50 - EgressDefaultTable binding.TableIDType = 60 - EgressMetricTable binding.TableIDType = 61 - l3ForwardingTable binding.TableIDType = 70 - snatTable binding.TableIDType = 71 - l3DecTTLTable binding.TableIDType = 72 - l2ForwardingCalcTable binding.TableIDType = 80 - AntreaPolicyIngressRuleTable binding.TableIDType = 85 - DefaultTierIngressRuleTable binding.TableIDType = 89 - IngressRuleTable binding.TableIDType = 90 - IngressDefaultTable binding.TableIDType = 100 - IngressMetricTable binding.TableIDType = 101 - conntrackCommitTable binding.TableIDType = 105 - hairpinSNATTable binding.TableIDType = 106 - L2ForwardingOutTable binding.TableIDType = 110 + ClassifierTable = binding.NewTableIDType(0, "Classification") + uplinkTable = binding.NewTableIDType(5, "Uplink") + spoofGuardTable = binding.NewTableIDType(10, "SpoofGuard") + arpResponderTable = binding.NewTableIDType(20, "ARPResponder") + ipv6Table = binding.NewTableIDType(21, "IPv6") + serviceHairpinTable = binding.NewTableIDType(29, "ServiceHairpin") + conntrackTable = binding.NewTableIDType(30, "ConntrackZone") + conntrackStateTable = binding.NewTableIDType(31, "ConntrackState") + sessionAffinityTable = binding.NewTableIDType(40, "SessionAffinity") + dnatTable = binding.NewTableIDType(40, "DNAT(SessionAffinity)") + serviceLBTable = binding.NewTableIDType(41, "ServiceLB") + endpointDNATTable = binding.NewTableIDType(42, "EndpointDNAT") + AntreaPolicyEgressRuleTable = binding.NewTableIDType(45, "AntreaPolicyEgressRule") + DefaultTierEgressRuleTable = binding.NewTableIDType(49, "DefaultTierEgressRule") + EgressRuleTable = binding.NewTableIDType(50, "EgressRule") + EgressDefaultTable = binding.NewTableIDType(60, "EgressDefaultRule") + EgressMetricTable = binding.NewTableIDType(61, "EgressMetric") + l3ForwardingTable = binding.NewTableIDType(70, "L3Forwarding") + snatTable = binding.NewTableIDType(71, "SNAT") + l3DecTTLTable = binding.NewTableIDType(72, "IPTTLDec") + l2ForwardingCalcTable = binding.NewTableIDType(80, "L2Forwarding") + AntreaPolicyIngressRuleTable = binding.NewTableIDType(85, "AntreaPolicyIngressRule") + DefaultTierIngressRuleTable = binding.NewTableIDType(89, "DefaultTierIngressRule") + IngressRuleTable = binding.NewTableIDType(90, "IngressRule") + IngressDefaultTable = binding.NewTableIDType(100, "IngressDefaultRule") + IngressMetricTable = binding.NewTableIDType(101, "IngressMetric") + conntrackCommitTable = binding.NewTableIDType(105, "ConntrackCommit") + hairpinSNATTable = binding.NewTableIDType(106, "HairpinSNATTable") + L2ForwardingOutTable = binding.NewTableIDType(110, "Output") // Flow priority level priorityHigh = uint16(210) @@ -88,6 +87,8 @@ const ( ipv6MulticastAddr = "FF00::/8" // IPv6 link-local prefix ipv6LinkLocalAddr = "FE80::/10" + + tableNameIndex = "tableNameIndex" ) type ofAction int32 @@ -120,61 +121,59 @@ var ( EgressDefaultTable: {}, } - FlowTables = []struct { - Number binding.TableIDType - Name string - }{ - {ClassifierTable, "Classification"}, - {uplinkTable, "Uplink"}, - {spoofGuardTable, "SpoofGuard"}, - {arpResponderTable, "ARPResponder"}, - {ipv6Table, "IPv6"}, - {serviceHairpinTable, "ServiceHairpin"}, - {conntrackTable, "ConntrackZone"}, - {conntrackStateTable, "ConntrackState"}, - {dnatTable, "DNAT(SessionAffinity)"}, - {sessionAffinityTable, "SessionAffinity"}, - {serviceLBTable, "ServiceLB"}, - {endpointDNATTable, "EndpointDNAT"}, - {AntreaPolicyEgressRuleTable, "AntreaPolicyEgressRule"}, - {EgressRuleTable, "EgressRule"}, - {EgressDefaultTable, "EgressDefaultRule"}, - {EgressMetricTable, "EgressMetric"}, - {l3ForwardingTable, "L3Forwarding"}, - {snatTable, "SNAT"}, - {l3DecTTLTable, "IPTTLDec"}, - {l2ForwardingCalcTable, "L2Forwarding"}, - {AntreaPolicyIngressRuleTable, "AntreaPolicyIngressRule"}, - {IngressRuleTable, "IngressRule"}, - {IngressDefaultTable, "IngressDefaultRule"}, - {IngressMetricTable, "IngressMetric"}, - {conntrackCommitTable, "ConntrackCommit"}, - {hairpinSNATTable, "HairpinSNATTable"}, - {L2ForwardingOutTable, "Output"}, - } + flowTableCache = cache.NewIndexer(tableIDIndexFunc, cache.Indexers{tableNameIndex: tableNameIndexFunc}) ) +func tableNameIndexFunc(obj interface{}) ([]string, error) { + ofTable := obj.(binding.Table) + return []string{ofTable.GetID().GetName()}, nil +} + +func tableIDIndexFunc(obj interface{}) (string, error) { + ofTable := obj.(binding.Table) + return fmt.Sprintf("%d", ofTable.GetID().GetID()), nil +} + +func getTableByTableID(tableID binding.TableIDType) binding.Table { + return getTableByID(tableID.GetID()) +} + +func getTableByID(id uint8) binding.Table { + obj, exists, _ := flowTableCache.GetByKey(fmt.Sprintf("%d", id)) + if !exists { + return nil + } + return obj.(binding.Table) +} + // GetFlowTableName returns the flow table name given the table number. An empty // string is returned if the table cannot be found. -func GetFlowTableName(tableNumber binding.TableIDType) string { - for _, t := range FlowTables { - if t.Number == tableNumber { - return t.Name - } +func GetFlowTableName(tableNumber uint8) string { + table := getTableByID(tableNumber) + if table == nil { + return "" } - return "" + return table.GetID().GetName() } // GetFlowTableNumber does a case insensitive lookup of the table name, and // returns the flow table number if the table is found. Otherwise TableIDAll is // returned if the table cannot be found. -func GetFlowTableNumber(tableName string) binding.TableIDType { - for _, t := range FlowTables { - if strings.EqualFold(t.Name, tableName) { - return t.Number - } +func GetFlowTableNumber(tableName string) uint8 { + objs, _ := flowTableCache.ByIndex(tableNameIndex, tableName) + if len(objs) == 0 { + return binding.TableIDAll.GetID() } - return binding.TableIDAll + return objs[0].(binding.Table).GetID().GetID() +} + +func PrintTableBaseInfo() string { + msg := "" + for _, obj := range flowTableCache.List() { + t := obj.(binding.Table) + msg += fmt.Sprintf("\n %d\t%s", uint32(t.GetID().GetID()), t.GetID().GetName()) + } + return msg } func GetAntreaPolicyEgressTables() []binding.TableIDType { @@ -205,20 +204,6 @@ func GetAntreaPolicyMultiTierTables() []binding.TableIDType { } } -type regType uint - -func (rt regType) number() string { - return fmt.Sprint(rt) -} - -func (rt regType) nxm() string { - return fmt.Sprintf("NXM_NX_REG%d", rt) -} - -func (rt regType) reg() string { - return fmt.Sprintf("reg%d", rt) -} - const ( CtZone = 0xfff0 CtZoneV6 = 0xffe6 @@ -300,7 +285,6 @@ type client struct { bridge binding.Bridge egressEntryTable binding.TableIDType ingressEntryTable binding.TableIDType - pipeline map[binding.TableIDType]binding.Table // Flow caches for corresponding deletions. nodeFlowCache, podFlowCache, serviceFlowCache, snatFlowCache, tfFlowCache *flowCategoryCache // "fixed" flows installed by the agent after initialization and which do not change during @@ -439,7 +423,8 @@ func (c *client) DeleteOFEntries(ofEntries []binding.OFEntry) error { // defaultFlows generates the default flows of all tables. func (c *client) defaultFlows() (flows []binding.Flow) { - for _, table := range c.pipeline { + for _, obj := range flowTableCache.List() { + table := obj.(binding.Table) flowBuilder := table.BuildFlow(priorityMiss) switch table.GetMissAction() { case binding.TableMissActionNext: @@ -460,7 +445,7 @@ func (c *client) defaultFlows() (flows []binding.Flow) { // tunnelClassifierFlow generates the flow to mark traffic comes from the tunnelOFPort. func (c *client) tunnelClassifierFlow(tunnelOFPort uint32, category cookie.Category) binding.Flow { - return c.pipeline[ClassifierTable].BuildFlow(priorityNormal). + return getTableByTableID(ClassifierTable).BuildFlow(priorityNormal). MatchInPort(tunnelOFPort). Action().LoadRegMark(FromTunnelRegMark). Action().LoadRegMark(RewriteMACRegMark). @@ -471,7 +456,7 @@ func (c *client) tunnelClassifierFlow(tunnelOFPort uint32, category cookie.Categ // gatewayClassifierFlow generates the flow to mark traffic comes from the gatewayOFPort. func (c *client) gatewayClassifierFlow(category cookie.Category) binding.Flow { - classifierTable := c.pipeline[ClassifierTable] + classifierTable := getTableByTableID(ClassifierTable) return classifierTable.BuildFlow(priorityNormal). MatchInPort(config.HostGatewayOFPort). Action().LoadRegMark(FromGatewayRegMark). @@ -482,7 +467,7 @@ func (c *client) gatewayClassifierFlow(category cookie.Category) binding.Flow { // podClassifierFlow generates the flow to mark traffic comes from the podOFPort. func (c *client) podClassifierFlow(podOFPort uint32, category cookie.Category) binding.Flow { - classifierTable := c.pipeline[ClassifierTable] + classifierTable := getTableByTableID(ClassifierTable) return classifierTable.BuildFlow(priorityLow). MatchInPort(podOFPort). Action().LoadRegMark(FromLocalRegMark). @@ -502,9 +487,9 @@ func (c *client) podClassifierFlow(podOFPort uint32, category cookie.Category) b // to a Service. // 6) Add a flow to bypass reject response packet sent by the controller. func (c *client) connectionTrackFlows(category cookie.Category) []binding.Flow { - connectionTrackTable := c.pipeline[conntrackTable] - connectionTrackStateTable := c.pipeline[conntrackStateTable] - connectionTrackCommitTable := c.pipeline[conntrackCommitTable] + connectionTrackTable := getTableByTableID(conntrackTable) + connectionTrackStateTable := getTableByTableID(conntrackStateTable) + connectionTrackCommitTable := getTableByTableID(conntrackCommitTable) flows := c.conntrackBasicFlows(category) if c.enableProxy { flows = append(flows, @@ -567,7 +552,7 @@ func (c *client) connectionTrackFlows(category cookie.Category) []binding.Flow { // conntrackBypassRejectFlow generates a flow which is used to bypass the reject // response packet sent by the controller to avoid unexpected packet drop. func (c *client) conntrackBypassRejectFlow(proto binding.Protocol) binding.Flow { - connectionTrackStateTable := c.pipeline[conntrackStateTable] + connectionTrackStateTable := getTableByTableID(conntrackStateTable) return connectionTrackStateTable.BuildFlow(priorityHigh). MatchProtocol(proto). MatchRegMark(CustomReasonRejectRegMark). @@ -605,8 +590,8 @@ func (c *client) dnsResponseBypassPacketInFlow() binding.Flow { } func (c *client) conntrackBasicFlows(category cookie.Category) []binding.Flow { - connectionTrackStateTable := c.pipeline[conntrackStateTable] - connectionTrackCommitTable := c.pipeline[conntrackCommitTable] + connectionTrackStateTable := getTableByTableID(conntrackStateTable) + connectionTrackCommitTable := getTableByTableID(conntrackCommitTable) var flows []binding.Flow for _, proto := range c.ipProtocols { ctZone := CtZone @@ -630,7 +615,7 @@ func (c *client) conntrackBasicFlows(category cookie.Category) []binding.Flow { } func (c *client) kubeProxyFlows(category cookie.Category) []binding.Flow { - connectionTrackTable := c.pipeline[conntrackTable] + connectionTrackTable := getTableByTableID(conntrackTable) var flows []binding.Flow for _, proto := range c.ipProtocols { ctZone := CtZone @@ -662,7 +647,7 @@ func (c *client) kubeProxyFlows(category cookie.Category) []binding.Flow { // when receiverOnly is true, the flow is added into l2ForwardingCalcTable and // matches the destination MAC (the receiver Pod MAC). func (c *client) traceflowConnectionTrackFlows(dataplaneTag uint8, receiverOnly bool, packet *binding.Packet, ofPort uint32, timeout uint16, category cookie.Category) []binding.Flow { - connectionTrackStateTable := c.pipeline[conntrackStateTable] + connectionTrackStateTable := getTableByTableID(conntrackStateTable) var flows []binding.Flow if packet == nil { for _, ipProtocol := range c.ipProtocols { @@ -708,7 +693,7 @@ func (c *client) traceflowConnectionTrackFlows(dataplaneTag uint8, receiverOnly Action().ResubmitToTable(connectionTrackStateTable.GetNext()) } } else { - l2FwdCalcTable := c.pipeline[l2ForwardingCalcTable] + l2FwdCalcTable := getTableByTableID(l2ForwardingCalcTable) nextTable := c.ingressEntryTable flowBuilder = l2FwdCalcTable.BuildFlow(priorityHigh). MatchDstMAC(packet.DestinationMAC). @@ -828,7 +813,7 @@ func (c *client) traceflowNetworkPolicyFlows(dataplaneTag uint8, timeout uint16, // serviceLBBypassFlows makes packets that belong to a tracked connection bypass // service LB tables and enter egressRuleTable directly. func (c *client) serviceLBBypassFlows(ipProtocol binding.Protocol) []binding.Flow { - connectionTrackStateTable := c.pipeline[conntrackStateTable] + connectionTrackStateTable := getTableByTableID(conntrackStateTable) flows := []binding.Flow{ // Tracked connections with the ServiceCTMark (load-balanced by AntreaProxy) receive // the macRewriteMark and are sent to egressRuleTable. @@ -853,7 +838,7 @@ func (c *client) serviceLBBypassFlows(ipProtocol binding.Protocol) []binding.Flo // l2ForwardCalcFlow generates the flow that matches dst MAC and loads ofPort to reg. func (c *client) l2ForwardCalcFlow(dstMAC net.HardwareAddr, ofPort uint32, skipIngressRules bool, category cookie.Category) binding.Flow { - l2FwdCalcTable := c.pipeline[l2ForwardingCalcTable] + l2FwdCalcTable := getTableByTableID(l2ForwardingCalcTable) nextTable := l2FwdCalcTable.GetNext() if !skipIngressRules { // Go to ingress NetworkPolicy tables for traffic to local Pods. @@ -874,7 +859,7 @@ func (c *client) l2ForwardCalcFlow(dstMAC net.HardwareAddr, ofPort uint32, skipI // to OVS port and Antrea Agent after L2forwarding calculation. func (c *client) traceflowL2ForwardOutputFlows(dataplaneTag uint8, liveTraffic, droppedOnly bool, timeout uint16, category cookie.Category) []binding.Flow { flows := []binding.Flow{} - l2FwdOutTable := c.pipeline[L2ForwardingOutTable] + l2FwdOutTable := getTableByTableID(L2ForwardingOutTable) for _, ipProtocol := range c.ipProtocols { if c.encapMode.SupportsEncap() { // SendToController and Output if output port is tunnel port. @@ -1005,7 +990,7 @@ func (c *client) traceflowL2ForwardOutputFlows(dataplaneTag uint8, liveTraffic, // l2ForwardOutputServiceHairpinFlow uses in_port action for Service // hairpin packets to avoid packets from being dropped by OVS. func (c *client) l2ForwardOutputServiceHairpinFlow() binding.Flow { - return c.pipeline[L2ForwardingOutTable].BuildFlow(priorityHigh). + return getTableByTableID(L2ForwardingOutTable).BuildFlow(priorityHigh). MatchRegMark(HairpinRegMark). Action().OutputInPort(). Cookie(c.cookieAllocator.Request(cookie.Service).Raw()). @@ -1016,12 +1001,12 @@ func (c *client) l2ForwardOutputServiceHairpinFlow() binding.Flow { func (c *client) l2ForwardOutputFlows(category cookie.Category) []binding.Flow { var flows []binding.Flow flows = append(flows, - c.pipeline[L2ForwardingOutTable].BuildFlow(priorityNormal).MatchProtocol(binding.ProtocolIP). + getTableByTableID(L2ForwardingOutTable).BuildFlow(priorityNormal).MatchProtocol(binding.ProtocolIP). MatchRegMark(OFPortFoundRegMark). Action().OutputToRegField(TargetOFPortField). Cookie(c.cookieAllocator.Request(category).Raw()). Done(), - c.pipeline[L2ForwardingOutTable].BuildFlow(priorityNormal).MatchProtocol(binding.ProtocolIPv6). + getTableByTableID(L2ForwardingOutTable).BuildFlow(priorityNormal).MatchProtocol(binding.ProtocolIPv6). MatchRegMark(OFPortFoundRegMark). Action().OutputToRegField(TargetOFPortField). Cookie(c.cookieAllocator.Request(category).Raw()). @@ -1035,7 +1020,7 @@ func (c *client) l2ForwardOutputFlows(category cookie.Category) []binding.Flow { // the Pod interface MAC, and rewrites the source MAC to the gateway interface // MAC. func (c *client) l3FwdFlowToPod(localGatewayMAC net.HardwareAddr, podInterfaceIPs []net.IP, podInterfaceMAC net.HardwareAddr, category cookie.Category) []binding.Flow { - l3FwdTable := c.pipeline[l3ForwardingTable] + l3FwdTable := getTableByTableID(l3ForwardingTable) var flows []binding.Flow for _, ip := range podInterfaceIPs { ipProtocol := getIPProtocol(ip) @@ -1057,7 +1042,7 @@ func (c *client) l3FwdFlowToPod(localGatewayMAC net.HardwareAddr, podInterfaceIP // interface MAC. The flow is used in the networkPolicyOnly mode for the traffic // from the gateway to a local Pod. func (c *client) l3FwdFlowRouteToPod(podInterfaceIPs []net.IP, podInterfaceMAC net.HardwareAddr, category cookie.Category) []binding.Flow { - l3FwdTable := c.pipeline[l3ForwardingTable] + l3FwdTable := getTableByTableID(l3ForwardingTable) var flows []binding.Flow for _, ip := range podInterfaceIPs { ipProtocol := getIPProtocol(ip) @@ -1076,7 +1061,7 @@ func (c *client) l3FwdFlowRouteToPod(podInterfaceIPs []net.IP, podInterfaceMAC n // interface MAC. The flow is used in the networkPolicyOnly mode for the traffic // from a local Pod to remote Pods, Nodes, or external network. func (c *client) l3FwdFlowRouteToGW(gwMAC net.HardwareAddr, category cookie.Category) []binding.Flow { - l3FwdTable := c.pipeline[l3ForwardingTable] + l3FwdTable := getTableByTableID(l3ForwardingTable) var flows []binding.Flow for _, ipProto := range c.ipProtocols { flows = append(flows, l3FwdTable.BuildFlow(priorityLow).MatchProtocol(ipProto). @@ -1092,7 +1077,7 @@ func (c *client) l3FwdFlowRouteToGW(gwMAC net.HardwareAddr, category cookie.Cate // l3FwdFlowToGateway generates the L3 forward flows to rewrite the destination MAC of the packets to the gateway interface // MAC if the destination IP is the gateway IP or the connection was initiated through the gateway interface. func (c *client) l3FwdFlowToGateway(localGatewayIPs []net.IP, localGatewayMAC net.HardwareAddr, category cookie.Category) []binding.Flow { - l3FwdTable := c.pipeline[l3ForwardingTable] + l3FwdTable := getTableByTableID(l3ForwardingTable) var flows []binding.Flow for _, ip := range localGatewayIPs { ipProtocol := getIPProtocol(ip) @@ -1136,7 +1121,7 @@ func (c *client) l3FwdFlowToRemote( tunnelPeer net.IP, category cookie.Category) binding.Flow { ipProto := getIPProtocol(peerSubnet.IP) - return c.pipeline[l3ForwardingTable].BuildFlow(priorityNormal).MatchProtocol(ipProto). + return getTableByTableID(l3ForwardingTable).BuildFlow(priorityNormal).MatchProtocol(ipProto). MatchDstIPNet(peerSubnet). // Rewrite src MAC to local gateway MAC and rewrite dst MAC to virtual MAC. Action().SetSrcMAC(localGatewayMAC). @@ -1156,7 +1141,7 @@ func (c *client) l3FwdFlowToRemoteViaGW( peerSubnet net.IPNet, category cookie.Category) binding.Flow { ipProto := getIPProtocol(peerSubnet.IP) - l3FwdTable := c.pipeline[l3ForwardingTable] + l3FwdTable := getTableByTableID(l3ForwardingTable) return l3FwdTable.BuildFlow(priorityNormal).MatchProtocol(ipProto). MatchDstIPNet(peerSubnet). Action().SetDstMAC(localGatewayMAC). @@ -1168,7 +1153,7 @@ func (c *client) l3FwdFlowToRemoteViaGW( // arpResponderFlow generates the ARP responder flow entry that replies request comes from local gateway for peer // gateway MAC. func (c *client) arpResponderFlow(peerGatewayIP net.IP, category cookie.Category) binding.Flow { - return c.pipeline[arpResponderTable].BuildFlow(priorityNormal).MatchProtocol(binding.ProtocolARP). + return getTableByTableID(arpResponderTable).BuildFlow(priorityNormal).MatchProtocol(binding.ProtocolARP). MatchARPOp(1). MatchARPTpa(peerGatewayIP). Action().Move(binding.NxmFieldSrcMAC, binding.NxmFieldDstMAC). @@ -1186,7 +1171,7 @@ func (c *client) arpResponderFlow(peerGatewayIP net.IP, category cookie.Category // arpResponderStaticFlow generates ARP reply for any ARP request with the same global virtual MAC. // This flow is used in policy-only mode, where traffic are routed via IP not MAC. func (c *client) arpResponderStaticFlow(category cookie.Category) binding.Flow { - return c.pipeline[arpResponderTable].BuildFlow(priorityNormal).MatchProtocol(binding.ProtocolARP). + return getTableByTableID(arpResponderTable).BuildFlow(priorityNormal).MatchProtocol(binding.ProtocolARP). MatchARPOp(1). Action().Move(binding.NxmFieldSrcMAC, binding.NxmFieldDstMAC). Action().SetSrcMAC(globalVirtualMAC). @@ -1205,8 +1190,7 @@ func (c *client) arpResponderStaticFlow(category cookie.Category) binding.Flow { // podIPSpoofGuardFlow generates the flow to check IP traffic sent out from local pod. Traffic from host gateway interface // will not be checked, since it might be pod to service traffic or host namespace traffic. func (c *client) podIPSpoofGuardFlow(ifIPs []net.IP, ifMAC net.HardwareAddr, ifOFPort uint32, category cookie.Category) []binding.Flow { - ipPipeline := c.pipeline - ipSpoofGuardTable := ipPipeline[spoofGuardTable] + ipSpoofGuardTable := getTableByTableID(spoofGuardTable) var flows []binding.Flow for _, ifIP := range ifIPs { ipProtocol := getIPProtocol(ifIP) @@ -1252,7 +1236,7 @@ func (c *client) serviceHairpinResponseDNATFlow(ipProtocol binding.Protocol) bin from = "NXM_NX_IPV6_SRC" to = "NXM_NX_IPV6_DST" } - return c.pipeline[serviceHairpinTable].BuildFlow(priorityNormal).MatchProtocol(ipProtocol). + return getTableByTableID(serviceHairpinTable).BuildFlow(priorityNormal).MatchProtocol(ipProtocol). MatchDstIP(hpIP). Action().Move(from, to). Action().LoadRegMark(HairpinRegMark). @@ -1263,7 +1247,7 @@ func (c *client) serviceHairpinResponseDNATFlow(ipProtocol binding.Protocol) bin // gatewayARPSpoofGuardFlow generates the flow to check ARP traffic sent out from the local gateway interface. func (c *client) gatewayARPSpoofGuardFlow(gatewayIP net.IP, gatewayMAC net.HardwareAddr, category cookie.Category) binding.Flow { - return c.pipeline[spoofGuardTable].BuildFlow(priorityNormal).MatchProtocol(binding.ProtocolARP). + return getTableByTableID(spoofGuardTable).BuildFlow(priorityNormal).MatchProtocol(binding.ProtocolARP). MatchInPort(config.HostGatewayOFPort). MatchARPSha(gatewayMAC). MatchARPSpa(gatewayIP). @@ -1274,7 +1258,7 @@ func (c *client) gatewayARPSpoofGuardFlow(gatewayIP net.IP, gatewayMAC net.Hardw // arpSpoofGuardFlow generates the flow to check ARP traffic sent out from local pods interfaces. func (c *client) arpSpoofGuardFlow(ifIP net.IP, ifMAC net.HardwareAddr, ifOFPort uint32, category cookie.Category) binding.Flow { - return c.pipeline[spoofGuardTable].BuildFlow(priorityNormal).MatchProtocol(binding.ProtocolARP). + return getTableByTableID(spoofGuardTable).BuildFlow(priorityNormal).MatchProtocol(binding.ProtocolARP). MatchInPort(ifOFPort). MatchARPSha(ifMAC). MatchARPSpa(ifIP). @@ -1288,7 +1272,7 @@ func (c *client) arpSpoofGuardFlow(ifIP net.IP, ifMAC net.HardwareAddr, ifOFPort // case will occur if an Endpoint is removed and is the learned Endpoint // selection of the Service. func (c *client) sessionAffinityReselectFlow() binding.Flow { - return c.pipeline[endpointDNATTable].BuildFlow(priorityLow). + return getTableByTableID(endpointDNATTable).BuildFlow(priorityLow). MatchRegMark(EpSelectedRegMark). Action().LoadRegMark(EpToSelectRegMark). Action().ResubmitToTable(serviceLBTable). @@ -1298,8 +1282,7 @@ func (c *client) sessionAffinityReselectFlow() binding.Flow { // gatewayIPSpoofGuardFlow generates the flow to skip spoof guard checking for traffic sent from gateway interface. func (c *client) gatewayIPSpoofGuardFlows(category cookie.Category) []binding.Flow { - ipPipeline := c.pipeline - ipSpoofGuardTable := ipPipeline[spoofGuardTable] + ipSpoofGuardTable := getTableByTableID(spoofGuardTable) var flows []binding.Flow for _, proto := range c.ipProtocols { nextTable := ipSpoofGuardTable.GetNext() @@ -1323,7 +1306,7 @@ func (c *client) serviceCIDRDNATFlows(serviceCIDRs []*net.IPNet) []binding.Flow for _, serviceCIDR := range serviceCIDRs { if serviceCIDR != nil { ipProto := getIPProtocol(serviceCIDR.IP) - flows = append(flows, c.pipeline[dnatTable].BuildFlow(priorityNormal).MatchProtocol(ipProto). + flows = append(flows, getTableByTableID(dnatTable).BuildFlow(priorityNormal).MatchProtocol(ipProto). MatchDstIPNet(*serviceCIDR). Action().LoadToRegField(TargetOFPortField, config.HostGatewayOFPort). Action().LoadRegMark(OFPortFoundRegMark). @@ -1337,7 +1320,7 @@ func (c *client) serviceCIDRDNATFlows(serviceCIDRs []*net.IPNet) []binding.Flow // serviceNeedLBFlow generates flows to mark packets as LB needed. func (c *client) serviceNeedLBFlow() binding.Flow { - return c.pipeline[sessionAffinityTable].BuildFlow(priorityMiss). + return getTableByTableID(sessionAffinityTable).BuildFlow(priorityMiss). Cookie(c.cookieAllocator.Request(cookie.Service).Raw()). Action().LoadRegMark(EpToSelectRegMark). Done() @@ -1345,7 +1328,7 @@ func (c *client) serviceNeedLBFlow() binding.Flow { // arpNormalFlow generates the flow to response arp in normal way if no flow in arpResponderTable is matched. func (c *client) arpNormalFlow(category cookie.Category) binding.Flow { - return c.pipeline[arpResponderTable].BuildFlow(priorityLow).MatchProtocol(binding.ProtocolARP). + return getTableByTableID(arpResponderTable).BuildFlow(priorityLow).MatchProtocol(binding.ProtocolARP). Action().Normal(). Cookie(c.cookieAllocator.Request(category).Raw()). Done() @@ -1363,11 +1346,11 @@ func (c *client) allowRulesMetricFlows(conjunctionID uint32, ingress bool) []bin field = EgressRuleCTLabel } metricFlow := func(isCTNew bool, protocol binding.Protocol) binding.Flow { - return c.pipeline[metricTableID].BuildFlow(priorityNormal). + return getTableByTableID(metricTableID).BuildFlow(priorityNormal). MatchProtocol(protocol). MatchCTStateNew(isCTNew). MatchCTLabelField(0, uint64(conjunctionID)<