github.com/contiv/libOpenflow@v0.0.0-20210609050114-d967b14cc688/openflow13/nx_util.go (about)

     1  package openflow13
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  )
     7  
     8  const (
     9  	// OFPP_IN_PORT is the default number of in_port field in resubmit actions.
    10  	OFPP_IN_PORT = 0xfff8
    11  )
    12  
    13  // NX_CT_STATES
    14  const (
    15  	NX_CT_STATE_NEW_OFS  = 0
    16  	NX_CT_STATE_EST_OFS  = 1
    17  	NX_CT_STATE_REL_OFS  = 2
    18  	NX_CT_STATE_RPL_OFS  = 3
    19  	NX_CT_STATE_INV_OFS  = 4
    20  	NX_CT_STATE_TRK_OFS  = 5
    21  	NX_CT_STATE_SNAT_OFS = 6
    22  	NX_CT_STATE_DNAT_OFS = 7
    23  )
    24  
    25  // NX_CT Flags
    26  const (
    27  	NX_CT_F_COMMIT    = 1 << 0
    28  	NX_CT_F_FORCE     = 1 << 1
    29  	NX_CT_RECIRC_NONE = 0xff
    30  )
    31  
    32  // NX_NAT_RANGE flags
    33  const (
    34  	NX_NAT_RANGE_IPV4_MIN  = 1 << 0
    35  	NX_NAT_RANGE_IPV4_MAX  = 1 << 1
    36  	NX_NAT_RANGE_IPV6_MIN  = 1 << 2
    37  	NX_NAT_RANGE_IPV6_MAX  = 1 << 3
    38  	NX_NAT_RANGE_PROTO_MIN = 1 << 4
    39  	NX_NAT_RANGE_PROTO_MAX = 1 << 5
    40  )
    41  
    42  // NX_NAT flags
    43  const (
    44  	NX_NAT_F_SRC          = 1 << 0
    45  	NX_NAT_F_DST          = 1 << 1
    46  	NX_NAT_F_PERSISTENT   = 1 << 2
    47  	NX_NAT_F_PROTO_HASH   = 1 << 3
    48  	NX_NAT_F_PROTO_RANDOM = 1 << 4
    49  	NX_NAT_F_MASK         = (NX_NAT_F_SRC | NX_NAT_F_DST | NX_NAT_F_PERSISTENT | NX_NAT_F_PROTO_HASH | NX_NAT_F_PROTO_RANDOM)
    50  )
    51  
    52  // NX_LEARN flags
    53  const (
    54  	NX_LEARN_F_SEND_FLOW_REM  = 1 << 0
    55  	NX_LEARN_F_DELETE_LEARNED = 1 << 1
    56  	NX_LEARN_F_WRITE_RESULT   = 1 << 2
    57  )
    58  
    59  // NX_LEARN field offset
    60  const (
    61  	LEARN_SPEC_HEADER_LOAD  = 11
    62  	LEARN_SPEC_HEADER_MATCH = 13
    63  )
    64  
    65  // NXM_OF fields. The class number of these fields are 0x0000.
    66  const (
    67  	NXM_OF_IN_PORT uint8 = iota
    68  	NXM_OF_ETH_DST
    69  	NXM_OF_ETH_SRC
    70  	NXM_OF_ETH_TYPE
    71  	NXM_OF_VLAN_TCI
    72  	NXM_OF_IP_TOS
    73  	NXM_OF_IP_PROTO
    74  	NXM_OF_IP_SRC
    75  	NXM_OF_IP_DST
    76  	NXM_OF_TCP_SRC
    77  	NXM_OF_TCP_DST
    78  	NXM_OF_UDP_SRC
    79  	NXM_OF_UDP_DST
    80  	NXM_OF_ICMP_TYPE
    81  	NXM_OF_ICMP_CODE
    82  	NXM_OF_ARP_OP
    83  	NXM_OF_ARP_SPA
    84  	NXM_OF_ARP_TPA
    85  )
    86  
    87  // TLV_Table_Mod commands.
    88  const (
    89  	NXTTMC_ADD = iota
    90  	NXTTMC_DELETE
    91  	NXTTMC_CLEAR
    92  )
    93  
    94  func newMatchFieldHeader(class uint16, field uint8, length uint8) *MatchField {
    95  	var fieldLength = length
    96  	return &MatchField{Class: class, Field: field, Length: fieldLength, HasMask: false}
    97  }
    98  
    99  // oxxFieldHeaderMap is map to find target field header without mask using an OVS known OXX field name
   100  var oxxFieldHeaderMap = map[string]*MatchField{
   101  	"NXM_OF_IN_PORT":   newMatchFieldHeader(OXM_CLASS_NXM_0, NXM_OF_IN_PORT, 2),
   102  	"NXM_OF_ETH_DST":   newMatchFieldHeader(OXM_CLASS_NXM_0, NXM_OF_ETH_DST, 6),
   103  	"NXM_OF_ETH_SRC":   newMatchFieldHeader(OXM_CLASS_NXM_0, NXM_OF_ETH_SRC, 6),
   104  	"NXM_OF_ETH_TYPE":  newMatchFieldHeader(OXM_CLASS_NXM_0, NXM_OF_ETH_TYPE, 2),
   105  	"NXM_OF_VLAN_TCI":  newMatchFieldHeader(OXM_CLASS_NXM_0, NXM_OF_VLAN_TCI, 2),
   106  	"NXM_OF_IP_TOS":    newMatchFieldHeader(OXM_CLASS_NXM_0, NXM_OF_IP_TOS, 1),
   107  	"NXM_OF_IP_PROTO":  newMatchFieldHeader(OXM_CLASS_NXM_0, NXM_OF_IP_PROTO, 1),
   108  	"NXM_OF_IP_SRC":    newMatchFieldHeader(OXM_CLASS_NXM_0, NXM_OF_IP_SRC, 4),
   109  	"NXM_OF_IP_DST":    newMatchFieldHeader(OXM_CLASS_NXM_0, NXM_OF_IP_DST, 4),
   110  	"NXM_OF_TCP_SRC":   newMatchFieldHeader(OXM_CLASS_NXM_0, NXM_OF_TCP_SRC, 2),
   111  	"NXM_OF_TCP_DST":   newMatchFieldHeader(OXM_CLASS_NXM_0, NXM_OF_TCP_DST, 2),
   112  	"NXM_OF_UDP_SRC":   newMatchFieldHeader(OXM_CLASS_NXM_0, NXM_OF_UDP_SRC, 2),
   113  	"NXM_OF_UDP_DST":   newMatchFieldHeader(OXM_CLASS_NXM_0, NXM_OF_UDP_DST, 2),
   114  	"NXM_OF_ICMP_TYPE": newMatchFieldHeader(OXM_CLASS_NXM_0, NXM_OF_ICMP_TYPE, 1),
   115  	"NXM_OF_ICMP_CODE": newMatchFieldHeader(OXM_CLASS_NXM_0, NXM_OF_ICMP_CODE, 1),
   116  	"NXM_OF_ARP_OP":    newMatchFieldHeader(OXM_CLASS_NXM_0, NXM_OF_ARP_OP, 2),
   117  	"NXM_OF_ARP_SPA":   newMatchFieldHeader(OXM_CLASS_NXM_0, NXM_OF_ARP_SPA, 4),
   118  	"NXM_OF_ARP_TPA":   newMatchFieldHeader(OXM_CLASS_NXM_0, NXM_OF_ARP_TPA, 4),
   119  
   120  	"NXM_NX_REG0":          newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_REG0, 4),
   121  	"NXM_NX_REG1":          newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_REG1, 4),
   122  	"NXM_NX_REG2":          newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_REG2, 4),
   123  	"NXM_NX_REG3":          newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_REG3, 4),
   124  	"NXM_NX_REG4":          newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_REG4, 4),
   125  	"NXM_NX_REG5":          newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_REG5, 4),
   126  	"NXM_NX_REG6":          newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_REG6, 4),
   127  	"NXM_NX_REG7":          newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_REG7, 4),
   128  	"NXM_NX_REG8":          newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_REG8, 4),
   129  	"NXM_NX_REG9":          newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_REG9, 4),
   130  	"NXM_NX_REG10":         newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_REG10, 4),
   131  	"NXM_NX_REG11":         newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_REG11, 4),
   132  	"NXM_NX_REG12":         newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_REG12, 4),
   133  	"NXM_NX_REG13":         newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_REG13, 4),
   134  	"NXM_NX_REG14":         newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_REG14, 4),
   135  	"NXM_NX_REG15":         newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_REG15, 4),
   136  	"NXM_NX_TUN_ID":        newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_TUN_ID, 8),
   137  	"NXM_NX_ARP_SHA":       newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_ARP_SHA, 6),
   138  	"NXM_NX_ARP_THA":       newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_ARP_THA, 6),
   139  	"NXM_NX_IPV6_SRC":      newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_IPV6_SRC, 16),
   140  	"NXM_NX_IPV6_DST":      newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_IPV6_DST, 16),
   141  	"NXM_NX_ICMPV6_TYPE":   newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_ICMPV6_TYPE, 1),
   142  	"NXM_NX_ICMPV6_CODE":   newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_ICMPV6_CODE, 1),
   143  	"NXM_NX_ND_TARGET":     newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_ND_TARGET, 16),
   144  	"NXM_NX_ND_SLL":        newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_ND_SLL, 6),
   145  	"NXM_NX_ND_TLL":        newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_ND_TLL, 6),
   146  	"NXM_NX_IP_FRAG":       newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_IP_FRAG, 1),
   147  	"NXM_NX_IPV6_LABEL":    newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_IPV6_LABEL, 1),
   148  	"NXM_NX_IP_ECN":        newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_IP_ECN, 1),
   149  	"NXM_NX_IP_TTL":        newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_IP_TTL, 1),
   150  	"NXM_NX_MPLS_TTL":      newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_MPLS_TTL, 1),
   151  	"NXM_NX_TUN_IPV4_SRC":  newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_TUN_IPV4_SRC, 4),
   152  	"NXM_NX_TUN_IPV4_DST":  newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_TUN_IPV4_DST, 4),
   153  	"NXM_NX_PKT_MARK":      newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_PKT_MARK, 4),
   154  	"NXM_NX_TCP_FLAGS":     newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_TCP_FLAGS, 2),
   155  	"NXM_NX_CONJ_ID":       newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_CONJ_ID, 4),
   156  	"NXM_NX_TUN_GBP_ID":    newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_TUN_GBP_ID, 2),
   157  	"NXM_NX_TUN_GBP_FLAGS": newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_TUN_GBP_FLAGS, 1),
   158  	"NXM_NX_TUN_FLAGS":     newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_TUN_FLAGS, 2),
   159  	"NXM_NX_CT_STATE":      newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_CT_STATE, 4),
   160  	"NXM_NX_CT_ZONE":       newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_CT_ZONE, 2),
   161  	"NXM_NX_CT_MARK":       newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_CT_MARK, 4),
   162  	"NXM_NX_CT_LABEL":      newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_CT_LABEL, 16),
   163  	"NXM_NX_TUN_IPV6_SRC":  newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_TUN_IPV6_SRC, 16),
   164  	"NXM_NX_TUN_IPV6_DST":  newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_TUN_IPV6_DST, 16),
   165  	"NXM_NX_CT_NW_PROTO":   newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_CT_NW_PROTO, 1),
   166  	"NXM_NX_CT_NW_SRC":     newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_CT_NW_SRC, 4),
   167  	"NXM_NX_CT_NW_DST":     newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_CT_NW_DST, 4),
   168  	"NXM_NX_CT_IPV6_SRC":   newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_CT_IPV6_SRC, 16),
   169  	"NXM_NX_CT_IPV6_DST":   newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_CT_IPV6_DST, 16),
   170  	"NXM_NX_CT_TP_SRC":     newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_CT_TP_SRC, 2),
   171  	"NXM_NX_CT_TP_DST":     newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_CT_TP_DST, 2),
   172  	"NXM_NX_TUN_METADATA0": newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_TUN_METADATA0, 128),
   173  	"NXM_NX_TUN_METADATA1": newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_TUN_METADATA1, 128),
   174  	"NXM_NX_TUN_METADATA2": newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_TUN_METADATA2, 128),
   175  	"NXM_NX_TUN_METADATA3": newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_TUN_METADATA3, 128),
   176  	"NXM_NX_TUN_METADATA4": newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_TUN_METADATA4, 128),
   177  	"NXM_NX_TUN_METADATA5": newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_TUN_METADATA5, 128),
   178  	"NXM_NX_TUN_METADATA6": newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_TUN_METADATA6, 128),
   179  	"NXM_NX_TUN_METADATA7": newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_TUN_METADATA7, 128),
   180  	"NXM_NX_XXREG0":        newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_XXREG0, 16),
   181  	"NXM_NX_XXREG1":        newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_XXREG1, 16),
   182  	"NXM_NX_XXREG2":        newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_XXREG2, 16),
   183  	"NXM_NX_XXREG3":        newMatchFieldHeader(OXM_CLASS_NXM_1, NXM_NX_XXREG3, 16),
   184  
   185  	"OXM_OF_IN_PORT":        newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_IN_PORT, 4),
   186  	"OXM_OF_IN_PHY_PORT":    newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_IN_PHY_PORT, 4),
   187  	"OXM_OF_METADATA":       newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_METADATA, 8),
   188  	"OXM_OF_ETH_DST":        newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_ETH_DST, 6),
   189  	"OXM_OF_ETH_SRC":        newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_ETH_SRC, 6),
   190  	"OXM_OF_ETH_TYPE":       newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_ETH_TYPE, 2),
   191  	"OXM_OF_VLAN_VID":       newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_VLAN_VID, 2),
   192  	"OXM_OF_VLAN_PCP":       newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_VLAN_PCP, 1),
   193  	"OXM_OF_IP_DSCP":        newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_IP_DSCP, 1),
   194  	"OXM_OF_IP_ECN":         newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_IP_ECN, 1),
   195  	"OXM_OF_IP_PROTO":       newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_IP_PROTO, 1),
   196  	"OXM_OF_IPV4_SRC":       newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_IPV4_SRC, 4),
   197  	"OXM_OF_IPV4_DST":       newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_IPV4_DST, 4),
   198  	"OXM_OF_TCP_SRC":        newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_TCP_SRC, 2),
   199  	"OXM_OF_TCP_DST":        newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_TCP_DST, 2),
   200  	"OXM_OF_UDP_SRC":        newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_UDP_SRC, 2),
   201  	"OXM_OF_UDP_DST":        newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_UDP_DST, 2),
   202  	"OXM_OF_SCTP_SRC":       newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_SCTP_SRC, 2),
   203  	"OXM_OF_SCTP_DST":       newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_SCTP_DST, 2),
   204  	"OXM_OF_ICMPV4_TYPE":    newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_ICMPV4_TYPE, 1),
   205  	"OXM_OF_ICMPV4_CODE":    newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_ICMPV4_CODE, 1),
   206  	"OXM_OF_ARP_OP":         newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_ARP_OP, 2),
   207  	"OXM_OF_ARP_SPA":        newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_ARP_SPA, 4),
   208  	"OXM_OF_ARP_TPA":        newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_ARP_TPA, 4),
   209  	"OXM_OF_ARP_SHA":        newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_ARP_SHA, 6),
   210  	"OXM_OF_ARP_THA":        newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_ARP_THA, 6),
   211  	"OXM_OF_IPV6_SRC":       newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_IPV6_SRC, 16),
   212  	"OXM_OF_IPV6_DST":       newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_IPV6_DST, 16),
   213  	"OXM_OF_IPV6_FLABEL":    newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_IPV6_FLABEL, 4),
   214  	"OXM_OF_ICMPV6_TYPE":    newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_ICMPV6_TYPE, 1),
   215  	"OXM_OF_ICMPV6_CODE":    newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_ICMPV6_CODE, 1),
   216  	"OXM_OF_IPV6_ND_TARGET": newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_IPV6_ND_TARGET, 16),
   217  	"OXM_OF_IPV6_ND_SLL":    newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_IPV6_ND_SLL, 6),
   218  	"OXM_OF_IPV6_ND_TLL":    newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_IPV6_ND_TLL, 6),
   219  	"OXM_OF_MPLS_LABEL":     newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_MPLS_LABEL, 4),
   220  	"OXM_OF_MPLS_TC":        newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_MPLS_TC, 1),
   221  	"OXM_OF_MPLS_BOS":       newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_MPLS_BOS, 1),
   222  	"OXM_OF_PBB_ISID":       newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_PBB_ISID, 3),
   223  	"OXM_OF_TUNNEL_ID":      newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_TUNNEL_ID, 8),
   224  	"OXM_OF_IPV6_EXTHDR":    newMatchFieldHeader(OXM_CLASS_OPENFLOW_BASIC, OXM_FIELD_IPV6_EXTHDR, 2),
   225  }
   226  
   227  // FindFieldHeaderByName finds OXM/NXM field by name and mask.
   228  func FindFieldHeaderByName(fieldName string, hasMask bool) (*MatchField, error) {
   229  	fieldKey := strings.ToUpper(fieldName)
   230  	field, found := oxxFieldHeaderMap[fieldKey]
   231  	if !found {
   232  		return nil, fmt.Errorf("failed to find header by name %s", fieldName)
   233  	}
   234  	length := field.Length
   235  	if hasMask {
   236  		length = field.Length * 2
   237  	}
   238  	// Create a new MatchField and return it to the caller, then it could avoid race condition.
   239  	return &MatchField{
   240  		Class:   field.Class,
   241  		Field:   field.Field,
   242  		HasMask: hasMask,
   243  		Length:  length,
   244  	}, nil
   245  }
   246  
   247  // encodeOfsNbitsStartEnd encodes the range to a uint16 number.
   248  func encodeOfsNbitsStartEnd(start uint16, end uint16) uint16 {
   249  	return (start << 6) + (end - start)
   250  }
   251  
   252  // Encode the range to a uint16 number.
   253  // ofs is the start pos, nBits is the count of the range.
   254  func encodeOfsNbits(ofs uint16, nBits uint16) uint16 {
   255  	return ofs<<6 | (nBits - 1)
   256  }
   257  
   258  func decodeOfs(ofsNbits uint16) uint16 {
   259  	return ofsNbits >> 6
   260  }
   261  
   262  func decodeNbits(ofsNbits uint16) uint16 {
   263  	return (ofsNbits & 0x3f) + 1
   264  }
   265  
   266  // NewNXRange creates a NXRange using start and end number.
   267  func NewNXRange(start int, end int) *NXRange {
   268  	return &NXRange{start: start, end: end}
   269  }
   270  
   271  // NewNXRangeByOfsNBits creates a NXRange using offshift and bit count.
   272  func NewNXRangeByOfsNBits(ofs int, nBits int) *NXRange {
   273  	return &NXRange{start: ofs, end: ofs + nBits - 1}
   274  }
   275  
   276  // ToUint32Mask generates a uint32 number mask from NXRange.
   277  func (n *NXRange) ToUint32Mask() uint32 {
   278  	start := n.start
   279  	maxLength := 32
   280  	var end int
   281  	if n.end != 0 {
   282  		end = n.end
   283  	} else {
   284  		end = maxLength
   285  	}
   286  	mask1 := ^uint32(0)
   287  	mask1 = mask1 >> uint32(maxLength-(end-n.start+1))
   288  	mask1 = mask1 << uint32(start)
   289  	return mask1
   290  }
   291  
   292  // ToOfsBits encodes the NXRange to a uint16 number to identify offshift and bits count.
   293  func (n *NXRange) ToOfsBits() uint16 {
   294  	return encodeOfsNbitsStartEnd(uint16(n.start), uint16(n.end))
   295  }
   296  
   297  // GetOfs returns the offshift number from NXRange.
   298  func (n *NXRange) GetOfs() uint16 {
   299  	return uint16(n.start)
   300  }
   301  
   302  // GetNbits returns the bits count from NXRange.
   303  func (n *NXRange) GetNbits() uint16 {
   304  	return uint16(n.end - n.start + 1)
   305  }