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

     1  package openflow13
     2  
     3  import (
     4  	"encoding/binary"
     5  	"errors"
     6  	"fmt"
     7  	"net"
     8  )
     9  
    10  type Uint16Message struct {
    11  	Data uint16
    12  }
    13  
    14  func newUint16Message(data uint16) *Uint16Message {
    15  	return &Uint16Message{Data: data}
    16  }
    17  
    18  func (m *Uint16Message) Len() uint16 {
    19  	return 2
    20  }
    21  
    22  func (m *Uint16Message) MarshalBinary() (data []byte, err error) {
    23  	data = make([]byte, m.Len())
    24  	binary.BigEndian.PutUint16(data, m.Data)
    25  	return
    26  }
    27  
    28  func (m *Uint16Message) UnmarshalBinary(data []byte) error {
    29  	if len(data) < 2 {
    30  		return errors.New("the []byte is too short to unmarshal a full Uint16Message")
    31  	}
    32  	m.Data = binary.BigEndian.Uint16(data[:2])
    33  	return nil
    34  }
    35  
    36  type Uint32Message struct {
    37  	Data uint32
    38  }
    39  
    40  func newUint32Message(data uint32) *Uint32Message {
    41  	return &Uint32Message{Data: data}
    42  }
    43  
    44  func (m *Uint32Message) Len() uint16 {
    45  	return 4
    46  }
    47  
    48  func (m *Uint32Message) MarshalBinary() (data []byte, err error) {
    49  	data = make([]byte, m.Len())
    50  	binary.BigEndian.PutUint32(data, m.Data)
    51  	return
    52  }
    53  
    54  func (m *Uint32Message) UnmarshalBinary(data []byte) error {
    55  	if len(data) < 4 {
    56  		return errors.New("the []byte is too short to unmarshal a full Uint32Message")
    57  	}
    58  	m.Data = binary.BigEndian.Uint32(data[:4])
    59  	return nil
    60  }
    61  
    62  type ByteArrayField struct {
    63  	Data   []byte
    64  	Length uint8
    65  }
    66  
    67  // Len returns the length of ByteArrayField. The length of ByteArrayField should be multiple of 8 byte.
    68  func (m *ByteArrayField) Len() uint16 {
    69  	return uint16(m.Length)
    70  }
    71  
    72  func (m *ByteArrayField) MarshalBinary() (data []byte, err error) {
    73  	data = make([]byte, m.Len())
    74  	copy(data, m.Data)
    75  	return
    76  }
    77  
    78  func (m *ByteArrayField) UnmarshalBinary(data []byte) error {
    79  	expectLength := m.Len()
    80  	if len(data) < int(expectLength) {
    81  		return errors.New("The byte array has wrong size to unmarshal ByteArrayField message")
    82  	}
    83  	m.Data = data[:expectLength]
    84  	return nil
    85  }
    86  
    87  type CTStates struct {
    88  	data uint32
    89  	mask uint32
    90  }
    91  
    92  func NewCTStates() *CTStates {
    93  	return new(CTStates)
    94  }
    95  
    96  // SetNew sets ct_state as "+new".
    97  func (s *CTStates) SetNew() {
    98  	s.data |= 1 << 0
    99  	s.mask |= 1 << 0
   100  }
   101  
   102  // UnsetNew sets ct_state as "-new".
   103  func (s *CTStates) UnsetNew() {
   104  	s.data &^= 1 << NX_CT_STATE_NEW_OFS
   105  	s.mask |= 1 << NX_CT_STATE_NEW_OFS
   106  }
   107  
   108  // SetEst sets ct_state as "+est".
   109  func (s *CTStates) SetEst() {
   110  	s.data |= 1 << NX_CT_STATE_EST_OFS
   111  	s.mask |= 1 << NX_CT_STATE_EST_OFS
   112  }
   113  
   114  // UnsetEst sets ct_state as "-est".
   115  func (s *CTStates) UnsetEst() {
   116  	s.data &^= 1 << NX_CT_STATE_EST_OFS
   117  	s.mask |= 1 << NX_CT_STATE_EST_OFS
   118  }
   119  
   120  // SetRel sets ct_state as "+rel".
   121  func (s *CTStates) SetRel() {
   122  	s.data |= 1 << NX_CT_STATE_REL_OFS
   123  	s.mask |= 1 << NX_CT_STATE_REL_OFS
   124  }
   125  
   126  // UnsetRel sets ct_state as "-rel".
   127  func (s *CTStates) UnsetRel() {
   128  	s.data &^= 1 << NX_CT_STATE_REL_OFS
   129  	s.mask |= 1 << NX_CT_STATE_REL_OFS
   130  }
   131  
   132  // SetRpl sets ct_state as "+rpl".
   133  func (s *CTStates) SetRpl() {
   134  	s.data |= 1 << NX_CT_STATE_RPL_OFS
   135  	s.mask |= 1 << NX_CT_STATE_RPL_OFS
   136  }
   137  
   138  // UnsetRpl sets ct_state as "-rpl".
   139  func (s *CTStates) UnsetRpl() {
   140  	s.data &^= 1 << NX_CT_STATE_RPL_OFS
   141  	s.mask |= 1 << NX_CT_STATE_RPL_OFS
   142  }
   143  
   144  // SetInv sets ct_state as "+inv".
   145  func (s *CTStates) SetInv() {
   146  	s.data |= 1 << NX_CT_STATE_INV_OFS
   147  	s.mask |= 1 << NX_CT_STATE_INV_OFS
   148  }
   149  
   150  // UnsetInv sets ct_state as "-inv".
   151  func (s *CTStates) UnsetInv() {
   152  	s.data &^= 1 << NX_CT_STATE_INV_OFS
   153  	s.mask |= 1 << NX_CT_STATE_INV_OFS
   154  }
   155  
   156  // SetTrk sets ct_state as "+trk".
   157  func (s *CTStates) SetTrk() {
   158  	s.data |= 1 << NX_CT_STATE_TRK_OFS
   159  	s.mask |= 1 << NX_CT_STATE_TRK_OFS
   160  }
   161  
   162  // UnsetTrk sets ct_state as "-trk".
   163  func (s *CTStates) UnsetTrk() {
   164  	s.data &^= 1 << NX_CT_STATE_TRK_OFS
   165  	s.mask |= 1 << NX_CT_STATE_TRK_OFS
   166  }
   167  
   168  // SetSNAT sets ct_state as "+snat".
   169  func (s *CTStates) SetSNAT() {
   170  	s.data |= 1 << NX_CT_STATE_SNAT_OFS
   171  	s.mask |= 1 << NX_CT_STATE_SNAT_OFS
   172  }
   173  
   174  // UnsetSNAT sets ct_state as "-snat".
   175  func (s *CTStates) UnsetSNAT() {
   176  	s.data &^= 1 << NX_CT_STATE_SNAT_OFS
   177  	s.mask |= 1 << NX_CT_STATE_SNAT_OFS
   178  }
   179  
   180  // SetDNAT sets ct_state as "+dnat".
   181  func (s *CTStates) SetDNAT() {
   182  	s.data |= 1 << NX_CT_STATE_DNAT_OFS
   183  	s.mask |= 1 << NX_CT_STATE_DNAT_OFS
   184  }
   185  
   186  // UnsetDNAT sets ct_state as "-dnat".
   187  func (s *CTStates) UnsetDNAT() {
   188  	s.data &^= 1 << NX_CT_STATE_DNAT_OFS
   189  	s.mask |= 1 << NX_CT_STATE_DNAT_OFS
   190  }
   191  
   192  type NXRange struct {
   193  	start int
   194  	end   int
   195  }
   196  
   197  func newNXRegHeader(idx int, hasMask bool) *MatchField {
   198  	idKey := fmt.Sprintf("NXM_NX_REG%d", idx)
   199  	header, _ := FindFieldHeaderByName(idKey, hasMask)
   200  	return header
   201  }
   202  
   203  func NewRegMatchField(idx int, data uint32, dataRng *NXRange) *MatchField {
   204  	var field *MatchField
   205  	field = newNXRegHeader(idx, dataRng != nil)
   206  
   207  	field.Value = newUint32Message(data)
   208  	if dataRng != nil {
   209  		field.Mask = newUint32Message(dataRng.ToUint32Mask())
   210  	}
   211  	return field
   212  }
   213  
   214  func newNXTunMetadataHeader(idx int, hasMask bool) *MatchField {
   215  	idKey := fmt.Sprintf("NXM_NX_TUN_METADATA%d", idx)
   216  	header, _ := FindFieldHeaderByName(idKey, hasMask)
   217  	return header
   218  }
   219  
   220  func NewTunMetadataField(idx int, data []byte, mask []byte) *MatchField {
   221  	var field *MatchField
   222  	field = newNXTunMetadataHeader(idx, len(mask) > 0)
   223  
   224  	field.Value = &ByteArrayField{
   225  		Data:   data,
   226  		Length: uint8(len(data)),
   227  	}
   228  	field.Length = uint8(len(data))
   229  	if len(mask) > 0 {
   230  		field.Mask = &ByteArrayField{
   231  			Data:   mask,
   232  			Length: uint8(len(mask)),
   233  		}
   234  		field.Length += uint8(len(mask))
   235  	}
   236  	return field
   237  }
   238  
   239  func NewCTStateMatchField(states *CTStates) *MatchField {
   240  	field, _ := FindFieldHeaderByName("NXM_NX_CT_STATE", true)
   241  	field.Value = newUint32Message(states.data)
   242  	field.Mask = newUint32Message(states.mask)
   243  	return field
   244  }
   245  
   246  func NewCTZoneMatchField(zone uint16) *MatchField {
   247  	field, _ := FindFieldHeaderByName("NXM_NX_CT_ZONE", false)
   248  	field.Value = newUint16Message(zone)
   249  	return field
   250  }
   251  
   252  func NewCTMarkMatchField(mark uint32, mask *uint32) *MatchField {
   253  	var field *MatchField
   254  	field, _ = FindFieldHeaderByName("NXM_NX_CT_MARK", mask != nil)
   255  
   256  	field.Value = newUint32Message(mark)
   257  	if mask != nil {
   258  		field.Mask = newUint32Message(*mask)
   259  	}
   260  
   261  	return field
   262  }
   263  
   264  type CTLabel struct {
   265  	data [16]byte
   266  }
   267  
   268  func (m *CTLabel) Len() uint16 {
   269  	return uint16(len(m.data))
   270  }
   271  
   272  func (m *CTLabel) MarshalBinary() (data []byte, err error) {
   273  	data = make([]byte, m.Len())
   274  	copy(data, m.data[:])
   275  	err = nil
   276  	return
   277  }
   278  
   279  func (m *CTLabel) UnmarshalBinary(data []byte) error {
   280  	m.data = [16]byte{}
   281  	if len(data) < len(m.data) {
   282  		copy(m.data[:], data)
   283  	} else {
   284  		copy(m.data[:], data[:16])
   285  	}
   286  	return nil
   287  }
   288  
   289  func newCTLabel(data [16]byte) *CTLabel {
   290  	label := new(CTLabel)
   291  	_ = label.UnmarshalBinary(data[:16])
   292  	return label
   293  }
   294  
   295  func NewCTLabelMatchField(label [16]byte, mask *[16]byte) *MatchField {
   296  	var field *MatchField
   297  	field, _ = FindFieldHeaderByName("NXM_NX_CT_LABEL", mask != nil)
   298  
   299  	field.Value = newCTLabel(label)
   300  	if mask != nil {
   301  		field.Mask = newCTLabel(*mask)
   302  	}
   303  
   304  	return field
   305  }
   306  
   307  func NewConjIDMatchField(conjID uint32) *MatchField {
   308  	field, _ := FindFieldHeaderByName("NXM_NX_CONJ_ID", false)
   309  	field.Value = newUint32Message(conjID)
   310  
   311  	return field
   312  }
   313  
   314  func NewNxARPShaMatchField(addr net.HardwareAddr, mask net.HardwareAddr) *MatchField {
   315  	var field *MatchField
   316  	field, _ = FindFieldHeaderByName("NXM_NX_ARP_SHA", mask != nil)
   317  
   318  	field.Value = &ArpXHaField{ArpHa: addr}
   319  	if mask != nil {
   320  		field.Mask = &ArpXHaField{ArpHa: mask}
   321  	}
   322  
   323  	return field
   324  }
   325  
   326  func NewNxARPThaMatchField(addr net.HardwareAddr, mask net.HardwareAddr) *MatchField {
   327  	var field *MatchField
   328  	field, _ = FindFieldHeaderByName("NXM_NX_ARP_THA", mask != nil)
   329  
   330  	field.Value = &ArpXHaField{ArpHa: addr}
   331  	if mask != nil {
   332  		field.Mask = &ArpXHaField{ArpHa: mask}
   333  	}
   334  
   335  	return field
   336  }
   337  
   338  func NewNxARPSpaMatchField(addr net.IP, mask net.IP) *MatchField {
   339  	var field *MatchField
   340  	field, _ = FindFieldHeaderByName("NXM_OF_ARP_SPA", mask != nil)
   341  
   342  	field.Value = &ArpXPaField{ArpPa: addr}
   343  	if mask != nil {
   344  		field.Mask = &ArpXPaField{ArpPa: mask}
   345  	}
   346  
   347  	return field
   348  }
   349  
   350  func NewNxARPTpaMatchField(addr net.IP, mask net.IP) *MatchField {
   351  	var field *MatchField
   352  	field, _ = FindFieldHeaderByName("NXM_OF_ARP_TPA", mask != nil)
   353  
   354  	field.Value = &ArpXPaField{ArpPa: addr}
   355  	if mask != nil {
   356  		field.Mask = &ArpXPaField{ArpPa: mask}
   357  	}
   358  
   359  	return field
   360  }