Skip to content

Commit

Permalink
Modify OF table name
Browse files Browse the repository at this point in the history
Signed-off-by: wenyingd <[email protected]>
  • Loading branch information
wenyingd committed Aug 12, 2021
1 parent d785904 commit 860cbde
Show file tree
Hide file tree
Showing 11 changed files with 171 additions and 58 deletions.
4 changes: 4 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,7 @@ require (
// hcshim repo is modifed to add "AdditionalParams" field to HNSEndpoint struct.
// We will use this replace before pushing the change to hcshim upstream repo.
replace github.com/Microsoft/hcsshim v0.8.9 => github.com/ruicao93/hcsshim v0.8.10-0.20210114035434-63fe00c1b9aa

replace antrea.io/libOpenflow v0.2.0 => github.com/wenyingd/libOpenflow v0.0.0-20210812015436-95863d0466d9

replace antrea.io/ofnet v0.1.0 => github.com/wenyingd/ofnet v0.0.0-20210812042331-61537ad36eb2
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
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=
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=
Expand Down Expand Up @@ -628,6 +624,10 @@ github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df h1:OviZH7qLw/7Zo
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
github.com/vmware/go-ipfix v0.5.4 h1:n7TssKO8D4E3qpFmO6eDs7yU9Mr4fSbLFC+GstPU8kw=
github.com/vmware/go-ipfix v0.5.4/go.mod h1:yzbG1rv+yJ8GeMrRm+MDhOV3akygNZUHLhC1pDoD2AY=
github.com/wenyingd/libOpenflow v0.0.0-20210812015436-95863d0466d9 h1:r4+05OcA5JYOhEFUGxc5LJhvKk1xXO7jTSvMYNqZQBs=
github.com/wenyingd/libOpenflow v0.0.0-20210812015436-95863d0466d9/go.mod h1:CzEJZxDNAupiGxeL5VOw92PsxfyvehEAvE3PiC6gr8o=
github.com/wenyingd/ofnet v0.0.0-20210812042331-61537ad36eb2 h1:pBqjz7uMbSaT853xcgwSIXJqlsfQPkMcdwIQsqZAUsg=
github.com/wenyingd/ofnet v0.0.0-20210812042331-61537ad36eb2/go.mod h1:hVCm7jpMByg9CF4k/4hRDPs/bV1RkaAaIfFWtMe3V54=
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
Expand Down
62 changes: 31 additions & 31 deletions pkg/agent/openflow/pipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -2142,48 +2142,48 @@ func (c *client) genPacketInMeter(meterID binding.MeterIDType, rate uint32) bind
func (c *client) generatePipeline() {
bridge := c.bridge
c.pipeline = map[binding.TableIDType]binding.Table{
ClassifierTable: bridge.CreateTable(ClassifierTable, spoofGuardTable, binding.TableMissActionDrop),
arpResponderTable: bridge.CreateTable(arpResponderTable, binding.LastTableID, binding.TableMissActionDrop),
conntrackTable: bridge.CreateTable(conntrackTable, conntrackStateTable, binding.TableMissActionNone),
EgressRuleTable: bridge.CreateTable(EgressRuleTable, EgressDefaultTable, binding.TableMissActionNext),
EgressDefaultTable: bridge.CreateTable(EgressDefaultTable, EgressMetricTable, binding.TableMissActionNext),
EgressMetricTable: bridge.CreateTable(EgressMetricTable, l3ForwardingTable, binding.TableMissActionNext),
l3ForwardingTable: bridge.CreateTable(l3ForwardingTable, l2ForwardingCalcTable, binding.TableMissActionNext),
l3DecTTLTable: bridge.CreateTable(l3DecTTLTable, l2ForwardingCalcTable, binding.TableMissActionNext),
ClassifierTable: bridge.CreateTable(ClassifierTable, spoofGuardTable, binding.TableMissActionDrop, "ClassifierTable"),
arpResponderTable: bridge.CreateTable(arpResponderTable, binding.LastTableID, binding.TableMissActionDrop, "arpResponderTable"),
conntrackTable: bridge.CreateTable(conntrackTable, conntrackStateTable, binding.TableMissActionNone, "conntrackTable"),
EgressRuleTable: bridge.CreateTable(EgressRuleTable, EgressDefaultTable, binding.TableMissActionNext, "EgressRuleTable"),
EgressDefaultTable: bridge.CreateTable(EgressDefaultTable, EgressMetricTable, binding.TableMissActionNext, "EgressDefaultTable"),
EgressMetricTable: bridge.CreateTable(EgressMetricTable, l3ForwardingTable, binding.TableMissActionNext, "EgressMetricTable"),
l3ForwardingTable: bridge.CreateTable(l3ForwardingTable, l2ForwardingCalcTable, binding.TableMissActionNext, "l3ForwardingTable"),
l3DecTTLTable: bridge.CreateTable(l3DecTTLTable, l2ForwardingCalcTable, binding.TableMissActionNext, "l3DecTTLTable"),
// Packets from l2ForwardingCalcTable should be forwarded to IngressMetricTable by default to collect ingress stats.
l2ForwardingCalcTable: bridge.CreateTable(l2ForwardingCalcTable, IngressMetricTable, binding.TableMissActionNext),
IngressRuleTable: bridge.CreateTable(IngressRuleTable, IngressDefaultTable, binding.TableMissActionNext),
IngressDefaultTable: bridge.CreateTable(IngressDefaultTable, IngressMetricTable, binding.TableMissActionNext),
IngressMetricTable: bridge.CreateTable(IngressMetricTable, conntrackCommitTable, binding.TableMissActionNext),
L2ForwardingOutTable: bridge.CreateTable(L2ForwardingOutTable, binding.LastTableID, binding.TableMissActionDrop),
l2ForwardingCalcTable: bridge.CreateTable(l2ForwardingCalcTable, IngressMetricTable, binding.TableMissActionNext, "l2ForwardingCalcTable"),
IngressRuleTable: bridge.CreateTable(IngressRuleTable, IngressDefaultTable, binding.TableMissActionNext, "IngressRuleTable"),
IngressDefaultTable: bridge.CreateTable(IngressDefaultTable, IngressMetricTable, binding.TableMissActionNext, "IngressDefaultTable"),
IngressMetricTable: bridge.CreateTable(IngressMetricTable, conntrackCommitTable, binding.TableMissActionNext, "IngressMetricTable"),
L2ForwardingOutTable: bridge.CreateTable(L2ForwardingOutTable, binding.LastTableID, binding.TableMissActionDrop, "L2ForwardingOutTable"),
}
if c.enableProxy {
c.pipeline[spoofGuardTable] = bridge.CreateTable(spoofGuardTable, serviceHairpinTable, binding.TableMissActionDrop)
c.pipeline[ipv6Table] = bridge.CreateTable(ipv6Table, serviceHairpinTable, binding.TableMissActionNext)
c.pipeline[serviceHairpinTable] = bridge.CreateTable(serviceHairpinTable, conntrackTable, binding.TableMissActionNext)
c.pipeline[conntrackStateTable] = bridge.CreateTable(conntrackStateTable, endpointDNATTable, binding.TableMissActionNext)
c.pipeline[sessionAffinityTable] = bridge.CreateTable(sessionAffinityTable, binding.LastTableID, binding.TableMissActionNone)
c.pipeline[serviceLBTable] = bridge.CreateTable(serviceLBTable, endpointDNATTable, binding.TableMissActionNext)
c.pipeline[endpointDNATTable] = bridge.CreateTable(endpointDNATTable, c.egressEntryTable, binding.TableMissActionNext)
c.pipeline[conntrackCommitTable] = bridge.CreateTable(conntrackCommitTable, hairpinSNATTable, binding.TableMissActionNext)
c.pipeline[hairpinSNATTable] = bridge.CreateTable(hairpinSNATTable, L2ForwardingOutTable, binding.TableMissActionNext)
c.pipeline[spoofGuardTable] = bridge.CreateTable(spoofGuardTable, serviceHairpinTable, binding.TableMissActionDrop, "spoofGuardTable")
c.pipeline[ipv6Table] = bridge.CreateTable(ipv6Table, serviceHairpinTable, binding.TableMissActionNext, "ipv6Table")
c.pipeline[serviceHairpinTable] = bridge.CreateTable(serviceHairpinTable, conntrackTable, binding.TableMissActionNext, "serviceHairpinTable")
c.pipeline[conntrackStateTable] = bridge.CreateTable(conntrackStateTable, endpointDNATTable, binding.TableMissActionNext, "conntrackStateTable")
c.pipeline[sessionAffinityTable] = bridge.CreateTable(sessionAffinityTable, binding.LastTableID, binding.TableMissActionNone, "sessionAffinityTable")
c.pipeline[serviceLBTable] = bridge.CreateTable(serviceLBTable, endpointDNATTable, binding.TableMissActionNext, "serviceLBTable")
c.pipeline[endpointDNATTable] = bridge.CreateTable(endpointDNATTable, c.egressEntryTable, binding.TableMissActionNext, "endpointDNATTable")
c.pipeline[conntrackCommitTable] = bridge.CreateTable(conntrackCommitTable, hairpinSNATTable, binding.TableMissActionNext, "conntrackCommitTable")
c.pipeline[hairpinSNATTable] = bridge.CreateTable(hairpinSNATTable, L2ForwardingOutTable, binding.TableMissActionNext, "hairpinSNATTable")
} else {
c.pipeline[spoofGuardTable] = bridge.CreateTable(spoofGuardTable, conntrackTable, binding.TableMissActionDrop)
c.pipeline[ipv6Table] = bridge.CreateTable(ipv6Table, conntrackTable, binding.TableMissActionNext)
c.pipeline[conntrackStateTable] = bridge.CreateTable(conntrackStateTable, dnatTable, binding.TableMissActionNext)
c.pipeline[dnatTable] = bridge.CreateTable(dnatTable, c.egressEntryTable, binding.TableMissActionNext)
c.pipeline[conntrackCommitTable] = bridge.CreateTable(conntrackCommitTable, L2ForwardingOutTable, binding.TableMissActionNext)
c.pipeline[spoofGuardTable] = bridge.CreateTable(spoofGuardTable, conntrackTable, binding.TableMissActionDrop, "spoofGuardTable")
c.pipeline[ipv6Table] = bridge.CreateTable(ipv6Table, conntrackTable, binding.TableMissActionNext, "ipv6Table")
c.pipeline[conntrackStateTable] = bridge.CreateTable(conntrackStateTable, dnatTable, binding.TableMissActionNext, "conntrackStateTable")
c.pipeline[dnatTable] = bridge.CreateTable(dnatTable, c.egressEntryTable, binding.TableMissActionNext, "dnatTable")
c.pipeline[conntrackCommitTable] = bridge.CreateTable(conntrackCommitTable, L2ForwardingOutTable, binding.TableMissActionNext, "conntrackCommitTable")
}
// The default SNAT is implemented with OVS on Windows.
if c.enableEgress || runtime.IsWindowsPlatform() {
c.pipeline[snatTable] = bridge.CreateTable(snatTable, l2ForwardingCalcTable, binding.TableMissActionNext)
c.pipeline[snatTable] = bridge.CreateTable(snatTable, l2ForwardingCalcTable, binding.TableMissActionNext, "snatTable")
}
if runtime.IsWindowsPlatform() {
c.pipeline[uplinkTable] = bridge.CreateTable(uplinkTable, spoofGuardTable, binding.TableMissActionNone)
c.pipeline[uplinkTable] = bridge.CreateTable(uplinkTable, spoofGuardTable, binding.TableMissActionNone, "uplinkTable")
}
if c.enableAntreaPolicy {
c.pipeline[AntreaPolicyEgressRuleTable] = bridge.CreateTable(AntreaPolicyEgressRuleTable, EgressRuleTable, binding.TableMissActionNext)
c.pipeline[AntreaPolicyIngressRuleTable] = bridge.CreateTable(AntreaPolicyIngressRuleTable, IngressRuleTable, binding.TableMissActionNext)
c.pipeline[AntreaPolicyEgressRuleTable] = bridge.CreateTable(AntreaPolicyEgressRuleTable, EgressRuleTable, binding.TableMissActionNext, "AntreaPolicyEgressRuleTable")
c.pipeline[AntreaPolicyIngressRuleTable] = bridge.CreateTable(AntreaPolicyIngressRuleTable, IngressRuleTable, binding.TableMissActionNext, "AntreaPolicyIngressRuleTable")
}
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/ovs/openflow/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ var IPDSCPToSRange = Range{2, 7}

// Bridge defines operations on an openflow bridge.
type Bridge interface {
CreateTable(id, next TableIDType, missAction MissActionType) Table
CreateTable(id, next TableIDType, missAction MissActionType, name string) Table
DeleteTable(id TableIDType) bool
CreateGroup(id GroupIDType) Group
DeleteGroup(id GroupIDType) bool
Expand Down
77 changes: 74 additions & 3 deletions pkg/ovs/openflow/ofctrl_bridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type ofTable struct {
missAction MissActionType
flowCount uint
updateTime time.Time
name string

*ofctrl.Table
}
Expand Down Expand Up @@ -113,11 +114,12 @@ func (t *ofTable) DumpFlows(cookieID, cookieMask uint64) (map[uint64]*FlowStates
return flowStats, nil
}

func newOFTable(id, next TableIDType, missAction MissActionType) *ofTable {
func newOFTable(id, next TableIDType, missAction MissActionType, name string) *ofTable {
return &ofTable{
id: id,
next: next,
missAction: missAction,
name: name,
}
}

Expand Down Expand Up @@ -146,6 +148,7 @@ type OFBridge struct {
connected chan bool
// pktConsumers is a map from PacketIn reason to the channel that is used to publish the PacketIn message.
pktConsumers sync.Map
mpartRplChs map[uint32]chan *openflow13.MultipartReply
}

func (b *OFBridge) CreateGroup(id GroupIDType) Group {
Expand Down Expand Up @@ -202,8 +205,8 @@ func (b *OFBridge) DeleteMeterAll() error {
return nil
}

func (b *OFBridge) CreateTable(id, next TableIDType, missAction MissActionType) Table {
t := newOFTable(id, next, missAction)
func (b *OFBridge) CreateTable(id, next TableIDType, missAction MissActionType, name string) Table {
t := newOFTable(id, next, missAction, name)

b.Lock()
defer b.Unlock()
Expand Down Expand Up @@ -269,6 +272,9 @@ func (b *OFBridge) SwitchConnected(sw *ofctrl.OFSwitch) {
// MultipartReply is a callback when multipartReply message is received on ofctrl.OFSwitch is connected.
// Client uses this method to handle the reply message if it has customized MultipartRequest message.
func (b *OFBridge) MultipartReply(sw *ofctrl.OFSwitch, rep *openflow13.MultipartReply) {
if ch, ok := b.mpartRplChs[rep.Xid]; ok {
ch <- rep
}
}

func (b *OFBridge) SwitchDisconnected(sw *ofctrl.OFSwitch) {
Expand All @@ -294,6 +300,8 @@ func (b *OFBridge) initialize() {
table.ResetStatus()
}

b.queryTableFeatures()

metrics.OVSTotalFlowCount.Set(0)
}

Expand Down Expand Up @@ -629,13 +637,76 @@ func (b *OFBridge) RetryInterval() time.Duration {
return b.retryInterval
}

func (b *OFBridge) queryTableFeatures() {
mpartRequest := &openflow13.MultipartRequest{
Header: openflow13.NewOfp13Header(),
Type: openflow13.MultipartType_TableFeatures,
Flags: 0,
}
mpartRequest.Header.Type = openflow13.Type_MultiPartRequest
mpartRequest.Header.Length = mpartRequest.Len()
tableFeatureChan := make(chan *openflow13.MultipartReply)
b.mpartRplChs[mpartRequest.Header.Xid] = tableFeatureChan
go b.processTableFeatures(mpartRequest.Header.Xid, tableFeatureChan)
b.ofSwitch.Send(mpartRequest)
}

func (b *OFBridge) processTableFeatures(xid uint32, ch chan *openflow13.MultipartReply) {
header := openflow13.NewOfp13Header()
header.Type = openflow13.Type_MultiPartRequest
requests := make([]*openflow13.MultipartRequest, 0)
tableCount := 0
for {
select {
case rpl := <-ch:
request := &openflow13.MultipartRequest{
Header: header,
Type: openflow13.MultipartType_TableFeatures,
Flags: 1,
}
for _, body := range rpl.Body {
request.Body = append(request.Body, body)
}
tableCount += len(rpl.Body)
request.Length = request.Len()
requests = append(requests, request)
if tableCount == int(LastTableID-1) {
goto sendRequest
}
}
}
sendRequest:
close(ch)
delete(b.mpartRplChs, xid)
for i := range requests {
req := requests[i]
for _, body := range req.Body {
tableFeature := body.(*openflow13.OFPTableFeatures)
// Modify table name if the table is in the pipeline, otherwise use the default table features.
// OVS doesn't allow to skip any table except the hidden table (always the last table) in a table_features
// request. So use the table features which is got from the initial query result for the tables that Antrea
// doesn't define in the pipeline.
if t, ok := b.tableCache[TableIDType(tableFeature.TableID)]; ok {
// Set table name with the configured value.
copy(tableFeature.Name[0:], t.name)
}

}
if i == (len(requests) - 1) {
req.Flags = 0
}
b.ofSwitch.Send(req)
}
}

func NewOFBridge(br string, mgmtAddr string) Bridge {
s := &OFBridge{
bridgeName: br,
mgmtAddr: mgmtAddr,
tableCache: make(map[TableIDType]*ofTable),
retryInterval: 1 * time.Second,
pktConsumers: sync.Map{},
mpartRplChs: make(map[uint32]chan *openflow13.MultipartReply),
}
s.controller = ofctrl.NewController(s)
return s
Expand Down
8 changes: 4 additions & 4 deletions pkg/ovs/openflow/testing/mock_openflow.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions pkg/ovs/ovsctl/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ type TracingRequest struct {
type OVSCtlClient interface {
// DumpFlows returns flows of the bridge.
DumpFlows(args ...string) ([]string, error)
// DumpFlowsWithoutTableNames returns flows of the bridge, and the table is shown as uint8 value in the result.
// This function is only used in test.
DumpFlowsWithoutTableNames(args ...string) ([]string, error)
// DumpMatchedFlows returns the flow which exactly matches the matchStr.
DumpMatchedFlow(matchStr string) (string, error)
// DumpTableFlows returns all flows in the table.
Expand Down
18 changes: 17 additions & 1 deletion pkg/ovs/ovsctl/ofctl.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,28 @@ func (c *ovsCtlClient) DumpFlows(args ...string) ([]string, error) {
if err != nil {
return nil, err
}
return c.parseFlowEntries(flowDump)
}

func (c *ovsCtlClient) DumpFlowsWithoutTableNames(args ...string) ([]string, error) {
flowDump, err := c.RunOfctlCmd("dump-flows", append(args, "--no-names")...)
if err != nil {
return nil, err
}
return c.parseFlowEntries(flowDump)
}

func (c *ovsCtlClient) parseFlowEntries(flowDump []byte) ([]string, error) {
scanner := bufio.NewScanner(strings.NewReader(string(flowDump)))
scanner.Split(bufio.ScanLines)
flowList := []string{}
for scanner.Scan() {
flowList = append(flowList, trimFlowStr(scanner.Text()))
flow := trimFlowStr(scanner.Text())
// Skip the non-flow line, which is printed when using parameter "--no-names" in tests.
if strings.Contains(flow, "NXST_FLOW reply") || strings.Contains(flow, "OFPST_FLOW reply") {
continue
}
flowList = append(flowList, flow)
}
return flowList, nil
}
Expand Down
19 changes: 19 additions & 0 deletions pkg/ovs/ovsctl/testing/mock_ovsctl.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 860cbde

Please sign in to comment.