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 }