From 350e03f04187525f43b53c032465d375516f33bf Mon Sep 17 00:00:00 2001 From: Jinjun Gao Date: Sun, 2 Jan 2022 23:43:12 +0800 Subject: [PATCH] Enable set_field with Metadata register WriteMetadata is write-action instruction which will be applied later than apply-action. In some case, we need use resubmit to do pipeline in the same table and set Metadata before resubmit at the same time. WriteMetadata cannot do the job. We need enable set_field for Metadata register. Actually, WriteMetadata do the same thing with set_field Metadata register in the OvS. From OpenFlow 1.5, Metadata register also can be used with set_field to set, not stricted only using WriteMetadata instruction. After this patch, ofnet can support WriteMetadata and set_field for Metadata meanwhile. Caller can use SetMetadata() or WriteMetadata() API to implement WriteMetadata action, and use SetMetadataAction() and ApplyAction() to implement set_field for Metadata. Signed-off-by: Jinjun Gao --- VERSION | 2 +- ofctrl/fgraphFlow.go | 17 +++++++++++------ ofctrl/ofAction.go | 17 ++++++++++++++++- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/VERSION b/VERSION index 62291ae2..1b0ae03b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v0.5.7 +v0.5.8 diff --git a/ofctrl/fgraphFlow.go b/ofctrl/fgraphFlow.go index 0a3c9b4b..3bdedc89 100644 --- a/ofctrl/fgraphFlow.go +++ b/ofctrl/fgraphFlow.go @@ -98,7 +98,7 @@ type FlowMatch struct { // additional Actions in flow's instruction set type FlowAction struct { - ActionType string // Type of action "setVlan", "setMetadata" + ActionType string // Type of action "setVlan", "writeMetadata" vlanId uint16 // Vlan Id in case of "setVlan" macAddr net.HardwareAddr // Mac address to set mplsEtherType uint16 // mpls ether type to push or pop @@ -106,7 +106,7 @@ type FlowAction struct { l4Port uint16 // Transport port to be set arpOper uint16 // Arp operation type to be set tunnelId uint64 // Tunnel Id (used for setting VNI) - metadata uint64 // Metadata in case of "setMetadata" + metadata uint64 // Metadata in case of "writeMetadata" metadataMask uint64 // Metadata mask dscp uint8 // DSCP field loadAct *NXLoadAction // Load data into OXM/NXM fields, one or more Actions @@ -843,12 +843,13 @@ func (self *Flow) installFlowActions(flowMod *openflow13.FlowMod, log.Debugf("flow install. Added setTunnelId Action: %+v", setTunnelAction) - case "setMetadata": - // Set Metadata instruction + case ActTypeWriteMetadata: + // Write Metadata instruction metadataInstr := openflow13.NewInstrWriteMetadata(flowAction.metadata, flowAction.metadataMask) // Add the instruction to flowmod flowMod.AddInstruction(metadataInstr) + log.Debugf("flow install. Added writeMetadata Action: %+v", metadataInstr) case ActTypeSetSrcIP: // Set IP src @@ -1584,10 +1585,14 @@ func (self *Flow) SetL4Field(port uint16, field string) error { return nil } -// Special actions on the flow to set metadata +// Special actions on the flow to write metadata. +// By using this API, it will call `writeMetadata' instruction +// to write metadata register in installFlowActions(). +// Instead, you can also use SetMetadataAction which uses +// `set_field' to write metadata register. func (self *Flow) SetMetadata(metadata, metadataMask uint64) error { action := new(FlowAction) - action.ActionType = "setMetadata" + action.ActionType = ActTypeWriteMetadata action.metadata = metadata action.metadataMask = metadataMask diff --git a/ofctrl/ofAction.go b/ofctrl/ofAction.go index 14dcabbb..999c9d34 100644 --- a/ofctrl/ofAction.go +++ b/ofctrl/ofAction.go @@ -17,7 +17,8 @@ const ( ActTypeSetDstMac = "setMacDa" ActTypeSetSrcMac = "setMacSa" ActTypeSetTunnelID = "setTunnelId" - ActTypeMetatdata = "setMetadata" + ActTypeSetMetadata = "setMetadata" // use set_field + ActTypeWriteMetadata = "writeMetadata" // use writeMetadata instruction ActTypeSetSrcIP = "setIPSa" ActTypeSetDstIP = "setIPDa" ActTypeSetTunnelSrcIP = "setTunSa" @@ -160,6 +161,20 @@ func (a *SetTunnelIDAction) GetActionType() string { return ActTypeSetTunnelID } +type SetMetadataAction struct { + Metadata uint64 + MetadataMask *uint64 +} + +func (a *SetMetadataAction) GetActionMessage() openflow13.Action { + field := openflow13.NewMetadataField(a.Metadata, a.MetadataMask) + return openflow13.NewActionSetField(*field) +} + +func (a *SetMetadataAction) GetActionType() string { + return ActTypeSetMetadata +} + type SetTunnelDstAction struct { IP net.IP }