github.com/contiv/libOpenflow@v0.0.0-20210609050114-d967b14cc688/openflow13/action.go (about) 1 package openflow13 2 3 import ( 4 "encoding/binary" 5 "errors" 6 7 "github.com/contiv/libOpenflow/util" 8 ) 9 10 // ofp_action_type 1.3 11 const ( 12 ActionType_Output = 0 13 ActionType_CopyTtlOut = 11 14 ActionType_CopyTtlIn = 12 15 ActionType_SetMplsTtl = 15 16 ActionType_DecMplsTtl = 16 17 ActionType_PushVlan = 17 18 ActionType_PopVlan = 18 19 ActionType_PushMpls = 19 20 ActionType_PopMpls = 20 21 ActionType_SetQueue = 21 22 ActionType_Group = 22 23 ActionType_SetNwTtl = 23 24 ActionType_DecNwTtl = 24 25 ActionType_SetField = 25 26 ActionType_PushPbb = 26 27 ActionType_PopPbb = 27 28 29 ActionType_Experimenter = 0xffff 30 ) 31 32 type Action interface { 33 Header() *ActionHeader 34 util.Message 35 } 36 37 type ActionHeader struct { 38 Type uint16 39 Length uint16 40 } 41 42 func (a *ActionHeader) Header() *ActionHeader { 43 return a 44 } 45 46 func (a *ActionHeader) Len() (n uint16) { 47 return 4 48 } 49 50 func (a *ActionHeader) MarshalBinary() (data []byte, err error) { 51 data = make([]byte, a.Len()) 52 binary.BigEndian.PutUint16(data[:2], a.Type) 53 binary.BigEndian.PutUint16(data[2:4], a.Length) 54 return 55 } 56 57 func (a *ActionHeader) UnmarshalBinary(data []byte) error { 58 if len(data) < int(a.Len()) { 59 return errors.New("The []byte the wrong size to unmarshal an " + 60 "ActionHeader message.") 61 } 62 a.Type = binary.BigEndian.Uint16(data[:2]) 63 a.Length = binary.BigEndian.Uint16(data[2:4]) 64 return nil 65 } 66 67 // Decode Action types. 68 func DecodeAction(data []byte) (Action, error) { 69 t := binary.BigEndian.Uint16(data[:2]) 70 var a Action 71 switch t { 72 case ActionType_Output: 73 a = new(ActionOutput) 74 case ActionType_CopyTtlOut: 75 a = new(ActionHeader) 76 case ActionType_CopyTtlIn: 77 a = new(ActionHeader) 78 case ActionType_SetMplsTtl: 79 a = new(ActionMplsTtl) 80 case ActionType_DecMplsTtl: 81 a = new(ActionHeader) 82 case ActionType_PushVlan: 83 a = new(ActionPush) 84 case ActionType_PopVlan: 85 a = new(ActionHeader) 86 case ActionType_PushMpls: 87 a = new(ActionPush) 88 case ActionType_PopMpls: 89 a = new(ActionPopMpls) 90 case ActionType_SetQueue: 91 a = new(ActionSetqueue) 92 case ActionType_Group: 93 a = new(ActionGroup) 94 case ActionType_SetNwTtl: 95 a = new(ActionNwTtl) 96 case ActionType_DecNwTtl: 97 a = new(ActionDecNwTtl) 98 case ActionType_SetField: 99 a = new(ActionSetField) 100 case ActionType_PushPbb: 101 a = new(ActionPush) 102 case ActionType_PopPbb: 103 a = new(ActionHeader) 104 case ActionType_Experimenter: 105 // For Experimenter message, the length of action should be at least 10 bytes, 106 // including type(2 byte), length(2 byte), vendor(4 byte), and subtype(2 byte) 107 if len(data) < NxActionHeaderLength { 108 return nil, errors.New("the []byte is too short to decode OpenFlow experimenter message") 109 } 110 v := binary.BigEndian.Uint32(data[4:8]) 111 if v == NxExperimenterID { 112 a = DecodeNxAction(data) 113 } 114 } 115 err := a.UnmarshalBinary(data) 116 if err != nil { 117 return a, err 118 } 119 return a, nil 120 } 121 122 // Action structure for OFPAT_OUTPUT, which sends packets out ’port’. 123 // When the ’port’ is the OFPP_CONTROLLER, ’max_len’ indicates the max 124 // number of bytes to send. A ’max_len’ of zero means no bytes of the 125 // packet should be sent. 126 type ActionOutput struct { 127 ActionHeader 128 Port uint32 129 MaxLen uint16 130 pad []byte // 6 bytes to make it 64bit aligned 131 } 132 133 // ofp_controller_max_len 1.3 134 const ( 135 OFPCML_MAX = 0xffe5 /* maximum max_len value which can be used to request a specific byte length. */ 136 OFPCML_NO_BUFFER = 0xffff /* indicates that no buffering should be applied and the whole packet is to be sent to the controller. */ 137 ) 138 139 // Returns a new Action Output message which sends packets out 140 // port number. 141 func NewActionOutput(portNum uint32) *ActionOutput { 142 act := new(ActionOutput) 143 act.Type = ActionType_Output 144 act.Length = act.Len() 145 act.Port = portNum 146 act.MaxLen = 256 147 act.pad = make([]byte, 6) 148 return act 149 } 150 151 func (a *ActionOutput) Len() (n uint16) { 152 return a.ActionHeader.Len() + 12 153 } 154 155 func (a *ActionOutput) MarshalBinary() (data []byte, err error) { 156 data = make([]byte, int(a.Len())) 157 b := make([]byte, 0) 158 n := 0 159 160 b, err = a.ActionHeader.MarshalBinary() 161 copy(data[n:], b) 162 n += len(b) 163 binary.BigEndian.PutUint32(data[n:], a.Port) 164 n += 4 165 binary.BigEndian.PutUint16(data[n:], a.MaxLen) 166 n += 2 167 copy(data[n:], a.pad) 168 n += len(a.pad) 169 170 return 171 } 172 173 func (a *ActionOutput) UnmarshalBinary(data []byte) error { 174 if len(data) < int(a.Len()) { 175 return errors.New("The []byte the wrong size to unmarshal an " + 176 "ActionOutput message.") 177 } 178 n := 0 179 err := a.ActionHeader.UnmarshalBinary(data[n:]) 180 n += int(a.ActionHeader.Len()) 181 a.Port = binary.BigEndian.Uint32(data[n:]) 182 n += 4 183 a.MaxLen = binary.BigEndian.Uint16(data[n:]) 184 n += 2 185 copy(a.pad, data[n:n+6]) 186 n += 6 187 return err 188 } 189 190 type ActionSetqueue struct { 191 ActionHeader 192 QueueId uint32 193 } 194 195 func NewActionSetQueue(queue uint32) *ActionSetqueue { 196 a := new(ActionSetqueue) 197 a.Type = ActionType_SetQueue 198 a.Length = a.Len() 199 a.QueueId = queue 200 return a 201 } 202 203 func (a *ActionSetqueue) Len() (n uint16) { 204 return a.ActionHeader.Len() + 4 205 } 206 207 func (a *ActionSetqueue) MarshalBinary() (data []byte, err error) { 208 data, err = a.ActionHeader.MarshalBinary() 209 210 bytes := make([]byte, 4) 211 binary.BigEndian.PutUint32(bytes[0:], a.QueueId) 212 213 data = append(data, bytes...) 214 return 215 } 216 217 func (a *ActionSetqueue) UnmarshalBinary(data []byte) error { 218 if len(data) != int(a.Len()) { 219 return errors.New("The []byte the wrong size to unmarshal an " + 220 "ActionEnqueue message.") 221 } 222 a.ActionHeader.UnmarshalBinary(data[:4]) 223 a.QueueId = binary.BigEndian.Uint32(data[4:8]) 224 return nil 225 } 226 227 type ActionGroup struct { 228 ActionHeader 229 GroupId uint32 230 } 231 232 func NewActionGroup(group uint32) *ActionGroup { 233 a := new(ActionGroup) 234 a.Type = ActionType_Group 235 a.Length = a.Len() 236 a.GroupId = group 237 return a 238 } 239 240 func (a *ActionGroup) Len() (n uint16) { 241 return a.ActionHeader.Len() + 4 242 } 243 244 func (a *ActionGroup) MarshalBinary() (data []byte, err error) { 245 data = make([]byte, int(a.Len())) 246 b := make([]byte, 0) 247 n := 0 248 249 b, err = a.ActionHeader.MarshalBinary() 250 copy(data[n:], b) 251 n += len(b) 252 binary.BigEndian.PutUint32(data[n:], a.GroupId) 253 n += 4 254 255 return 256 } 257 258 func (a *ActionGroup) UnmarshalBinary(data []byte) error { 259 if len(data) < int(a.Len()) { 260 return errors.New("The []byte the wrong size to unmarshal an " + 261 "ActionOutput message.") 262 } 263 n := 0 264 err := a.ActionHeader.UnmarshalBinary(data[n:]) 265 n += int(a.ActionHeader.Len()) 266 a.GroupId = binary.BigEndian.Uint32(data[n:]) 267 n += 4 268 269 return err 270 } 271 272 type ActionMplsTtl struct { 273 ActionHeader 274 MplsTtl uint8 275 pad []byte // 3bytes 276 } 277 278 type ActionDecNwTtl struct { 279 ActionHeader 280 pad []byte // 4bytes 281 } 282 283 func NewActionDecNwTtl() *ActionDecNwTtl { 284 act := new(ActionDecNwTtl) 285 act.Type = ActionType_DecNwTtl 286 act.Length = act.Len() 287 act.pad = make([]byte, 4) 288 return act 289 } 290 291 func (a *ActionDecNwTtl) Len() (n uint16) { 292 return a.ActionHeader.Len() + 4 293 } 294 295 func (a *ActionDecNwTtl) MarshalBinary() (data []byte, err error) { 296 data, err = a.ActionHeader.MarshalBinary() 297 if err != nil { 298 return 299 } 300 301 // Padding 302 bytes := make([]byte, 4) 303 data = append(data, bytes...) 304 return 305 } 306 307 func (a *ActionDecNwTtl) UnmarshalBinary(data []byte) error { 308 return a.ActionHeader.UnmarshalBinary(data[:4]) 309 } 310 311 type ActionNwTtl struct { 312 ActionHeader 313 NwTtl uint8 314 pad []byte // 3bytes 315 } 316 317 type ActionPush struct { 318 ActionHeader 319 EtherType uint16 320 pad []byte // 2bytes 321 } 322 323 func NewActionPushVlan(etherType uint16) *ActionPush { 324 a := new(ActionPush) 325 a.Type = ActionType_PushVlan 326 a.Length = a.Len() 327 a.EtherType = etherType 328 return a 329 } 330 331 func NewActionPushMpls(etherType uint16) *ActionPush { 332 a := new(ActionPush) 333 a.Type = ActionType_PushMpls 334 a.Length = a.Len() 335 a.EtherType = etherType 336 return a 337 } 338 339 func (a *ActionPush) Len() (n uint16) { 340 return a.ActionHeader.Len() + 4 341 } 342 343 func (a *ActionPush) MarshalBinary() (data []byte, err error) { 344 data, err = a.ActionHeader.MarshalBinary() 345 346 bytes := make([]byte, 4) 347 binary.BigEndian.PutUint16(bytes[0:], a.EtherType) 348 349 data = append(data, bytes...) 350 return 351 } 352 353 func (a *ActionPush) UnmarshalBinary(data []byte) error { 354 a.ActionHeader.UnmarshalBinary(data[:4]) 355 a.EtherType = binary.BigEndian.Uint16(data[4:]) 356 return nil 357 } 358 359 type ActionPopVlan struct { 360 ActionHeader 361 pad []byte // 4bytes 362 } 363 364 func NewActionPopVlan() *ActionPopVlan { 365 act := new(ActionPopVlan) 366 act.Type = ActionType_PopVlan 367 act.Length = act.Len() 368 369 return act 370 } 371 372 func (a *ActionPopVlan) Len() (n uint16) { 373 return a.ActionHeader.Len() + 4 374 } 375 376 func (a *ActionPopVlan) MarshalBinary() (data []byte, err error) { 377 data, err = a.ActionHeader.MarshalBinary() 378 379 // Padding 380 bytes := make([]byte, 4) 381 382 data = append(data, bytes...) 383 return 384 } 385 386 func (a *ActionPopVlan) UnmarshalBinary(data []byte) error { 387 a.ActionHeader.UnmarshalBinary(data[:4]) 388 return nil 389 } 390 391 type ActionPopMpls struct { 392 ActionHeader 393 EtherType uint16 394 pad []byte // 2bytes 395 } 396 397 func NewActionPopMpls(etherType uint16) *ActionPopMpls { 398 act := new(ActionPopMpls) 399 act.Type = ActionType_PopMpls 400 act.EtherType = etherType 401 act.Length = act.Len() 402 403 return act 404 } 405 406 func (a *ActionPopMpls) Len() (n uint16) { 407 return a.ActionHeader.Len() + 4 408 } 409 410 func (a *ActionPopMpls) MarshalBinary() (data []byte, err error) { 411 data, err = a.ActionHeader.MarshalBinary() 412 413 // Padding 414 bytes := make([]byte, 4) 415 binary.BigEndian.PutUint16(bytes[0:], a.EtherType) 416 417 data = append(data, bytes...) 418 return 419 } 420 421 func (a *ActionPopMpls) UnmarshalBinary(data []byte) error { 422 a.ActionHeader.UnmarshalBinary(data[:4]) 423 a.EtherType = binary.BigEndian.Uint16(data[4:]) 424 return nil 425 } 426 427 type ActionSetField struct { 428 ActionHeader 429 Field MatchField 430 } 431 432 func NewActionSetField(field MatchField) *ActionSetField { 433 a := new(ActionSetField) 434 a.Type = ActionType_SetField 435 a.Field = field 436 a.Length = a.Len() 437 return a 438 } 439 440 func (a *ActionSetField) Len() (n uint16) { 441 n = a.ActionHeader.Len() + a.Field.Len() 442 // Round it to closest multiple of 8 443 n = ((n + 7) / 8) * 8 444 445 return 446 } 447 448 func (a *ActionSetField) MarshalBinary() (data []byte, err error) { 449 data = make([]byte, int(a.Len())) 450 n := 0 451 b, err := a.ActionHeader.MarshalBinary() 452 copy(data, b) 453 n += int(a.ActionHeader.Len()) 454 455 b, err = a.Field.MarshalBinary() 456 copy(data[n:], b) 457 458 return 459 } 460 func (a *ActionSetField) UnmarshalBinary(data []byte) error { 461 n := 0 462 err := a.ActionHeader.UnmarshalBinary(data[n:]) 463 n += int(a.ActionHeader.Len()) 464 err = a.Field.UnmarshalBinary(data[n:]) 465 n += int(a.Field.Len()) 466 467 return err 468 }