github.com/contiv/libOpenflow@v0.0.0-20210609050114-d967b14cc688/openflow13/multipart.go (about) 1 package openflow13 2 3 import ( 4 "encoding/binary" 5 6 log "github.com/sirupsen/logrus" 7 8 "github.com/contiv/libOpenflow/common" 9 "github.com/contiv/libOpenflow/util" 10 ) 11 12 // ofp_multipart_request 1.3 13 type MultipartRequest struct { 14 common.Header 15 Type uint16 16 Flags uint16 17 pad []byte // 4 bytes 18 Body util.Message 19 } 20 21 func (s *MultipartRequest) Len() (n uint16) { 22 return s.Header.Len() + 8 + s.Body.Len() 23 } 24 25 func (s *MultipartRequest) MarshalBinary() (data []byte, err error) { 26 s.Header.Length = s.Len() 27 data, err = s.Header.MarshalBinary() 28 29 b := make([]byte, 8) 30 n := 0 31 binary.BigEndian.PutUint16(b[n:], s.Type) 32 n += 2 33 binary.BigEndian.PutUint16(b[n:], s.Flags) 34 n += 2 35 n += 4 // for padding 36 data = append(data, b...) 37 38 b, err = s.Body.MarshalBinary() 39 data = append(data, b...) 40 41 log.Debugf("Sending MultipartRequest (%d): %v", len(data), data) 42 43 return 44 } 45 46 func (s *MultipartRequest) UnmarshalBinary(data []byte) error { 47 err := s.Header.UnmarshalBinary(data) 48 n := s.Header.Len() 49 50 s.Type = binary.BigEndian.Uint16(data[n:]) 51 n += 2 52 s.Flags = binary.BigEndian.Uint16(data[n:]) 53 n += 2 54 n += 4 // for padding 55 56 var req util.Message 57 switch s.Type { 58 case MultipartType_Aggregate: 59 req = s.Body.(*AggregateStatsRequest) 60 err = req.UnmarshalBinary(data[n:]) 61 case MultipartType_Desc: 62 break 63 case MultipartType_Flow: 64 req = s.Body.(*FlowStatsRequest) 65 err = req.UnmarshalBinary(data[n:]) 66 case MultipartType_Port: 67 req = s.Body.(*PortStatsRequest) 68 err = req.UnmarshalBinary(data[n:]) 69 case MultipartType_Table: 70 break 71 case MultipartType_Queue: 72 req = s.Body.(*QueueStatsRequest) 73 err = req.UnmarshalBinary(data[n:]) 74 case MultipartType_Experimenter: 75 break 76 } 77 return err 78 } 79 80 // ofp_multipart_reply 1.3 81 type MultipartReply struct { 82 common.Header 83 Type uint16 84 Flags uint16 85 pad []byte // 4 bytes 86 Body []util.Message 87 } 88 89 func (s *MultipartReply) Len() (n uint16) { 90 n = s.Header.Len() 91 n += 8 92 for _, r := range s.Body { 93 n += uint16(r.Len()) 94 } 95 return 96 } 97 98 func (s *MultipartReply) MarshalBinary() (data []byte, err error) { 99 s.Header.Length = s.Len() 100 data, err = s.Header.MarshalBinary() 101 102 b := make([]byte, 8) 103 n := 0 104 binary.BigEndian.PutUint16(b[n:], s.Type) 105 n += 2 106 binary.BigEndian.PutUint16(b[n:], s.Flags) 107 n += 2 108 n += 4 // for padding 109 data = append(data, b...) 110 111 for _, r := range s.Body { 112 b, err = r.MarshalBinary() 113 data = append(data, b...) 114 } 115 116 return 117 } 118 119 func (s *MultipartReply) UnmarshalBinary(data []byte) error { 120 err := s.Header.UnmarshalBinary(data) 121 n := s.Header.Len() 122 123 s.Type = binary.BigEndian.Uint16(data[n:]) 124 n += 2 125 s.Flags = binary.BigEndian.Uint16(data[n:]) 126 n += 2 127 n += 4 // for padding 128 var req []util.Message 129 for n < s.Header.Length { 130 var repl util.Message 131 switch s.Type { 132 case MultipartType_Aggregate: 133 repl = new(AggregateStats) 134 case MultipartType_Desc: 135 repl = new(DescStats) 136 case MultipartType_Flow: 137 repl = new(FlowStats) 138 case MultipartType_Port: 139 repl = new(PortStats) 140 case MultipartType_Table: 141 repl = new(TableStats) 142 case MultipartType_Queue: 143 repl = new(QueueStats) 144 // FIXME: Support all types 145 case MultipartType_Experimenter: 146 break 147 } 148 149 err = repl.UnmarshalBinary(data[n:]) 150 if err != nil { 151 log.Printf("Error parsing stats reply") 152 } 153 n += repl.Len() 154 req = append(req, repl) 155 156 } 157 158 s.Body = req 159 160 return err 161 } 162 163 // ofp_multipart_request_flags & ofp_multipart_reply_flags 1.3 164 const ( 165 OFPMPF_REQ_MORE = 1 << 0 /* More requests to follow. */ 166 OFPMPF_REPLY_MORE = 1 << 0 /* More replies to follow. */ 167 ) 168 169 // _stats_types 170 const ( 171 /* Description of this OpenFlow switch. 172 * The request body is empty. 173 * The reply body is struct ofp_desc_stats. */ 174 MultipartType_Desc = iota 175 176 /* Individual flow statistics. 177 * The request body is struct ofp_flow_stats_request. 178 * The reply body is an array of struct ofp_flow_stats. */ 179 MultipartType_Flow 180 181 /* Aggregate flow statistics. 182 * The request body is struct ofp_aggregate_stats_request. 183 * The reply body is struct ofp_aggregate_stats_reply. */ 184 MultipartType_Aggregate 185 186 /* Flow table statistics. 187 * The request body is empty. 188 * The reply body is an array of struct ofp_table_stats. */ 189 MultipartType_Table 190 191 /* Port statistics. 192 * The request body is struct ofp_port_stats_request. 193 * The reply body is an array of struct ofp_port_stats. */ 194 MultipartType_Port 195 196 /* Queue statistics for a port 197 * The request body is struct _queue_stats_request. 198 * The reply body is an array of struct ofp_queue_stats */ 199 MultipartType_Queue 200 201 /* Group counter statistics. 202 * The request body is struct ofp_group_stats_request. 203 * The reply is an array of struct ofp_group_stats. */ 204 MultipartType_Group 205 206 /* Group description. 207 * The request body is empty. 208 * The reply body is an array of struct ofp_group_desc. */ 209 MultipartType_GroupDesc 210 211 /* Group features. 212 * The request body is empty. 213 * The reply body is struct ofp_group_features. */ 214 MultipartType_GroupFeatures 215 216 /* Meter statistics. 217 * The request body is struct ofp_meter_multipart_requests. 218 * The reply body is an array of struct ofp_meter_stats. */ 219 MultipartType_Meter 220 221 /* Meter configuration. 222 * The request body is struct ofp_meter_multipart_requests. 223 * The reply body is an array of struct ofp_meter_config. */ 224 MultipartType_MeterConfig 225 226 /* Meter features. 227 * The request body is empty. 228 * The reply body is struct ofp_meter_features. */ 229 MultipartType_MeterFeatures 230 231 /* Table features. 232 * The request body is either empty or contains an array of 233 * struct ofp_table_features containing the controller’s 234 * desired view of the switch. If the switch is unable to 235 * set the specified view an error is returned. 236 * The reply body is an array of struct ofp_table_features. */ 237 MultipartType_TableFeatures 238 239 /* Port description. 240 * The request body is empty. 241 * The reply body is an array of struct ofp_port. */ 242 MultipartType_PortDesc 243 244 /* Experimenter extension. 245 * The request and reply bodies begin with 246 * struct ofp_experimenter_multipart_header. 247 * The request and reply bodies are otherwise experimenter-defined. */ 248 MultipartType_Experimenter = 0xffff 249 ) 250 251 // ofp_desc_stats 1.3 252 type DescStats struct { 253 MfrDesc []byte // Size DESC_STR_LEN 254 HWDesc []byte // Size DESC_STR_LEN 255 SWDesc []byte // Size DESC_STR_LEN 256 SerialNum []byte // Size SERIAL_NUM_LEN 257 DPDesc []byte // Size DESC_STR_LEN 258 } 259 260 func NewDescStats() *DescStats { 261 s := new(DescStats) 262 s.MfrDesc = make([]byte, DESC_STR_LEN) 263 s.HWDesc = make([]byte, DESC_STR_LEN) 264 s.SWDesc = make([]byte, DESC_STR_LEN) 265 s.SerialNum = make([]byte, SERIAL_NUM_LEN) 266 s.DPDesc = make([]byte, DESC_STR_LEN) 267 return s 268 } 269 270 func (s *DescStats) Len() (n uint16) { 271 return uint16(DESC_STR_LEN*4 + SERIAL_NUM_LEN) 272 } 273 274 func (s *DescStats) MarshalBinary() (data []byte, err error) { 275 data = make([]byte, int(s.Len())) 276 n := 0 277 copy(data[n:], s.MfrDesc) 278 n += len(s.MfrDesc) 279 copy(data[n:], s.HWDesc) 280 n += len(s.HWDesc) 281 copy(data[n:], s.SWDesc) 282 n += len(s.SWDesc) 283 copy(data[n:], s.SerialNum) 284 n += len(s.SerialNum) 285 copy(data[n:], s.DPDesc) 286 n += len(s.DPDesc) 287 return 288 } 289 290 func (s *DescStats) UnmarshalBinary(data []byte) error { 291 n := 0 292 copy(s.MfrDesc, data[n:]) 293 n += len(s.MfrDesc) 294 copy(s.HWDesc, data[n:]) 295 n += len(s.HWDesc) 296 copy(s.SWDesc, data[n:]) 297 n += len(s.SWDesc) 298 copy(s.SerialNum, data[n:]) 299 n += len(s.SerialNum) 300 copy(s.DPDesc, data[n:]) 301 n += len(s.DPDesc) 302 return nil 303 } 304 305 const ( 306 DESC_STR_LEN = 256 307 SERIAL_NUM_LEN = 32 308 ) 309 310 const ( 311 OFPTT_MAX = 0xfe 312 /* Fake tables. */ 313 OFPTT_ALL = 0xff /* Wildcard table used for table config, flow stats and flow deletes. */ 314 ) 315 316 // ofp_flow_stats_request 1.3 317 type FlowStatsRequest struct { 318 TableId uint8 319 pad []byte // 3 bytes 320 OutPort uint32 321 OutGroup uint32 322 pad2 []byte // 4 bytes 323 Cookie uint64 324 CookieMask uint64 325 Match Match 326 } 327 328 func NewFlowStatsRequest() *FlowStatsRequest { 329 s := new(FlowStatsRequest) 330 s.OutPort = P_ANY 331 s.OutGroup = OFPG_ANY 332 s.pad = make([]byte, 3) 333 s.pad2 = make([]byte, 4) 334 s.Match = *NewMatch() 335 return s 336 } 337 338 func (s *FlowStatsRequest) Len() (n uint16) { 339 return s.Match.Len() + 32 340 } 341 342 func (s *FlowStatsRequest) MarshalBinary() (data []byte, err error) { 343 data = make([]byte, 32) 344 n := 0 345 data[n] = s.TableId 346 n += 1 347 copy(data[n:], s.pad) 348 n += 3 349 binary.BigEndian.PutUint32(data[n:], s.OutPort) 350 n += 4 351 binary.BigEndian.PutUint32(data[n:], s.OutGroup) 352 n += 4 353 copy(data[n:], s.pad2) 354 n += 4 355 binary.BigEndian.PutUint64(data[n:], s.Cookie) 356 n += 8 357 binary.BigEndian.PutUint64(data[n:], s.CookieMask) 358 n += 8 359 360 b, err := s.Match.MarshalBinary() 361 data = append(data, b...) 362 return 363 } 364 365 func (s *FlowStatsRequest) UnmarshalBinary(data []byte) error { 366 n := 0 367 s.TableId = data[n] 368 n += 1 369 copy(s.pad, data[n:n+3]) 370 n += 3 371 s.OutPort = binary.BigEndian.Uint32(data[n:]) 372 n += 4 373 s.OutGroup = binary.BigEndian.Uint32(data[n:]) 374 n += 4 375 copy(s.pad2, data[n:n+4]) 376 n += 4 377 s.Cookie = binary.BigEndian.Uint64(data[n:]) 378 n += 8 379 s.CookieMask = binary.BigEndian.Uint64(data[n:]) 380 n += 8 381 382 err := s.Match.UnmarshalBinary(data[n:]) 383 n += int(s.Match.Len()) 384 385 return err 386 } 387 388 // ofp_flow_stats 1.3 389 type FlowStats struct { 390 Length uint16 391 TableId uint8 392 pad uint8 393 DurationSec uint32 394 DurationNSec uint32 395 Priority uint16 396 IdleTimeout uint16 397 HardTimeout uint16 398 Flags uint16 399 pad2 []uint8 // Size 4 400 Cookie uint64 401 PacketCount uint64 402 ByteCount uint64 403 Match Match 404 Instructions []Instruction 405 } 406 407 func NewFlowStats() *FlowStats { 408 f := new(FlowStats) 409 f.Match = *NewMatch() 410 f.pad2 = make([]byte, 4) 411 f.Instructions = make([]Instruction, 0) 412 return f 413 } 414 415 func (s *FlowStats) Len() (n uint16) { 416 n = 48 + s.Match.Len() 417 for _, instr := range s.Instructions { 418 n += instr.Len() 419 } 420 return 421 } 422 423 func (s *FlowStats) MarshalBinary() (data []byte, err error) { 424 data = make([]byte, 48) 425 n := 0 426 427 binary.BigEndian.PutUint16(data[n:], s.Length) 428 n += 2 429 data[n] = s.TableId 430 n += 1 431 data[n] = s.pad 432 n += 1 433 434 binary.BigEndian.PutUint32(data[n:], s.DurationSec) 435 n += 4 436 binary.BigEndian.PutUint32(data[n:], s.DurationNSec) 437 n += 4 438 binary.BigEndian.PutUint16(data[n:], s.Priority) 439 n += 2 440 binary.BigEndian.PutUint16(data[n:], s.IdleTimeout) 441 n += 2 442 binary.BigEndian.PutUint16(data[n:], s.HardTimeout) 443 n += 2 444 binary.BigEndian.PutUint16(data[n:], s.Flags) 445 n += 2 446 copy(data[n:], s.pad2) 447 n += len(s.pad2) 448 binary.BigEndian.PutUint64(data[n:], s.Cookie) 449 n += 8 450 binary.BigEndian.PutUint64(data[n:], s.PacketCount) 451 n += 8 452 binary.BigEndian.PutUint64(data[n:], s.ByteCount) 453 n += 8 454 455 b, err := s.Match.MarshalBinary() 456 data = append(data, b...) 457 n += len(b) 458 459 for _, instr := range s.Instructions { 460 b, err = instr.MarshalBinary() 461 data = append(data, b...) 462 n += len(b) 463 } 464 return 465 } 466 467 func (s *FlowStats) UnmarshalBinary(data []byte) error { 468 n := 0 469 s.Length = binary.BigEndian.Uint16(data[n:]) 470 n += 2 471 s.TableId = data[n] 472 n += 1 473 s.pad = data[n] 474 n += 1 475 s.DurationSec = binary.BigEndian.Uint32(data[n:]) 476 n += 4 477 s.DurationNSec = binary.BigEndian.Uint32(data[n:]) 478 n += 4 479 s.Priority = binary.BigEndian.Uint16(data[n:]) 480 n += 2 481 s.IdleTimeout = binary.BigEndian.Uint16(data[n:]) 482 n += 2 483 s.HardTimeout = binary.BigEndian.Uint16(data[n:]) 484 n += 2 485 s.Flags = binary.BigEndian.Uint16(data[n:]) 486 n += 2 487 copy(s.pad2, data[n:n+4]) 488 n += 4 489 s.Cookie = binary.BigEndian.Uint64(data[n:]) 490 n += 8 491 s.PacketCount = binary.BigEndian.Uint64(data[n:]) 492 n += 8 493 s.ByteCount = binary.BigEndian.Uint64(data[n:]) 494 n += 8 495 err := s.Match.UnmarshalBinary(data[n:]) 496 n += int(s.Match.Len()) 497 498 for n < int(s.Length) { 499 instr := DecodeInstr(data[n:]) 500 s.Instructions = append(s.Instructions, instr) 501 n += int(instr.Len()) 502 } 503 return err 504 } 505 506 // ofp_aggregate_stats_request 1.3 507 type AggregateStatsRequest struct { 508 TableId uint8 509 pad []byte // 3 bytes 510 OutPort uint32 511 OutGroup uint32 512 pad2 []byte // 4 bytes 513 Cookie uint64 514 CookieMask uint64 515 Match 516 } 517 518 func NewAggregateStatsRequest() *AggregateStatsRequest { 519 a := new(AggregateStatsRequest) 520 a.pad = make([]byte, 3) 521 a.pad2 = make([]byte, 4) 522 a.Match = *NewMatch() 523 524 return a 525 } 526 527 func (s *AggregateStatsRequest) Len() (n uint16) { 528 return s.Match.Len() + 32 529 } 530 531 func (s *AggregateStatsRequest) MarshalBinary() (data []byte, err error) { 532 data = make([]byte, 32) 533 n := 0 534 data[n] = s.TableId 535 n += 1 536 copy(data[n:], s.pad) 537 n += 3 538 binary.BigEndian.PutUint32(data[n:], s.OutPort) 539 n += 4 540 binary.BigEndian.PutUint32(data[n:], s.OutGroup) 541 n += 4 542 copy(data[n:], s.pad2) 543 n += 4 544 binary.BigEndian.PutUint64(data[n:], s.Cookie) 545 n += 8 546 binary.BigEndian.PutUint64(data[n:], s.CookieMask) 547 n += 8 548 549 b, err := s.Match.MarshalBinary() 550 data = append(data, b...) 551 return 552 } 553 554 func (s *AggregateStatsRequest) UnmarshalBinary(data []byte) error { 555 n := 0 556 s.TableId = data[n] 557 n += 1 558 copy(s.pad, data[n:n+3]) 559 n += 3 560 s.OutPort = binary.BigEndian.Uint32(data[n:]) 561 n += 4 562 s.OutGroup = binary.BigEndian.Uint32(data[n:]) 563 n += 4 564 copy(s.pad2, data[n:n+4]) 565 n += 4 566 s.Cookie = binary.BigEndian.Uint64(data[n:]) 567 n += 8 568 s.CookieMask = binary.BigEndian.Uint64(data[n:]) 569 n += 8 570 571 s.Match.UnmarshalBinary(data[n:]) 572 n += int(s.Match.Len()) 573 return nil 574 } 575 576 // ofp_aggregate_stats_reply 1.3 577 type AggregateStats struct { 578 PacketCount uint64 579 ByteCount uint64 580 FlowCount uint32 581 pad []uint8 // Size 4 582 } 583 584 func NewAggregateStats() *AggregateStats { 585 s := new(AggregateStats) 586 s.pad = make([]byte, 4) 587 return s 588 } 589 590 func (s *AggregateStats) Len() (n uint16) { 591 return 24 592 } 593 594 func (s *AggregateStats) MarshalBinary() (data []byte, err error) { 595 data = make([]byte, int(s.Len())) 596 n := 0 597 binary.BigEndian.PutUint64(data[n:], s.PacketCount) 598 n += 8 599 binary.BigEndian.PutUint64(data[n:], s.ByteCount) 600 n += 8 601 binary.BigEndian.PutUint32(data[n:], s.FlowCount) 602 n += 4 603 copy(data[n:], s.pad) 604 n += 4 605 return 606 } 607 608 func (s *AggregateStats) UnmarshalBinary(data []byte) error { 609 n := 0 610 s.PacketCount = binary.BigEndian.Uint64(data[n:]) 611 n += 8 612 s.ByteCount = binary.BigEndian.Uint64(data[n:]) 613 n += 8 614 s.FlowCount = binary.BigEndian.Uint32(data[n:]) 615 n += 4 616 copy(s.pad, data[n:]) 617 return nil 618 } 619 620 // FIXME: Everything below this needs to be changed for ofp1.3 621 // ofp_table_stats 1.0 622 type TableStats struct { 623 TableId uint8 624 pad []uint8 // Size 3 625 Name []byte // Size MAX_TABLE_NAME_LEN 626 Wildcards uint32 627 MaxEntries uint32 628 ActiveCount uint32 629 LookupCount uint64 630 MatchedCount uint64 631 } 632 633 func NewTableStats() *TableStats { 634 s := new(TableStats) 635 s.pad = make([]byte, 3) 636 s.Name = make([]byte, MAX_TABLE_NAME_LEN) 637 return s 638 } 639 640 func (s *TableStats) Len() (n uint16) { 641 return 4 + MAX_TABLE_NAME_LEN + 28 642 } 643 644 func (s *TableStats) MarshalBinary() (data []byte, err error) { 645 data = make([]byte, int(s.Len())) 646 n := 0 647 data[n] = s.TableId 648 n += 1 649 copy(data[n:], s.pad) 650 n += len(s.pad) 651 copy(data[n:], s.Name) 652 n += len(s.Name) 653 binary.BigEndian.PutUint32(data[n:], s.Wildcards) 654 n += 4 655 binary.BigEndian.PutUint32(data[n:], s.MaxEntries) 656 n += 4 657 binary.BigEndian.PutUint32(data[n:], s.ActiveCount) 658 n += 4 659 binary.BigEndian.PutUint64(data[n:], s.LookupCount) 660 n += 8 661 binary.BigEndian.PutUint64(data[n:], s.MatchedCount) 662 n += 8 663 return 664 } 665 666 func (s *TableStats) UnmarshalBinary(data []byte) error { 667 n := 0 668 s.TableId = data[0] 669 n += 1 670 copy(s.pad, data[n:]) 671 n += len(s.pad) 672 copy(s.Name, data[n:]) 673 n += len(s.Name) 674 s.Wildcards = binary.BigEndian.Uint32(data[n:]) 675 n += 4 676 s.MaxEntries = binary.BigEndian.Uint32(data[n:]) 677 n += 4 678 s.ActiveCount = binary.BigEndian.Uint32(data[n:]) 679 n += 4 680 s.LookupCount = binary.BigEndian.Uint64(data[n:]) 681 n += 8 682 s.MatchedCount = binary.BigEndian.Uint64(data[n:]) 683 n += 8 684 return nil 685 } 686 687 const ( 688 MAX_TABLE_NAME_LEN = 32 689 ) 690 691 // ofp_port_stats_request 1.0 692 type PortStatsRequest struct { 693 PortNo uint16 694 pad []uint8 // Size 6 695 } 696 697 func NewPortStatsRequest() *PortStatsRequest { 698 p := new(PortStatsRequest) 699 p.pad = make([]byte, 6) 700 return p 701 } 702 703 func (s *PortStatsRequest) Len() (n uint16) { 704 return 8 705 } 706 707 func (s *PortStatsRequest) MarshalBinary() (data []byte, err error) { 708 data = make([]byte, int(s.Len())) 709 n := 0 710 binary.BigEndian.PutUint16(data[n:], s.PortNo) 711 n += 2 712 copy(data[n:], s.pad) 713 n += len(s.pad) 714 return 715 } 716 717 func (s *PortStatsRequest) UnmarshalBinary(data []byte) error { 718 n := 0 719 s.PortNo = binary.BigEndian.Uint16(data[n:]) 720 n += 2 721 copy(s.pad, data[n:]) 722 n += len(s.pad) 723 return nil 724 } 725 726 // ofp_port_stats 1.0 727 type PortStats struct { 728 PortNo uint16 729 pad []uint8 // Size 6 730 RxPackets uint64 731 TxPackets uint64 732 RxBytes uint64 733 TxBytes uint64 734 RxDropped uint64 735 TxDropped uint64 736 RxErrors uint64 737 TxErrors uint64 738 RxFrameErr uint64 739 RxOverErr uint64 740 RxCRCErr uint64 741 Collisions uint64 742 } 743 744 func NewPortStats() *PortStats { 745 p := new(PortStats) 746 p.pad = make([]byte, 6) 747 return p 748 } 749 750 func (s *PortStats) Len() (n uint16) { 751 return 104 752 } 753 754 func (s *PortStats) MarshalBinary() (data []byte, err error) { 755 data = make([]byte, int(s.Len())) 756 n := 0 757 binary.BigEndian.PutUint16(data[n:], s.PortNo) 758 n += 2 759 copy(data[n:], s.pad) 760 n += len(s.pad) 761 binary.BigEndian.PutUint64(data[n:], s.RxPackets) 762 n += 8 763 binary.BigEndian.PutUint64(data[n:], s.TxPackets) 764 n += 8 765 binary.BigEndian.PutUint64(data[n:], s.RxBytes) 766 n += 8 767 binary.BigEndian.PutUint64(data[n:], s.TxBytes) 768 n += 8 769 binary.BigEndian.PutUint64(data[n:], s.RxDropped) 770 n += 8 771 binary.BigEndian.PutUint64(data[n:], s.TxDropped) 772 n += 8 773 binary.BigEndian.PutUint64(data[n:], s.RxErrors) 774 n += 8 775 binary.BigEndian.PutUint64(data[n:], s.TxErrors) 776 n += 8 777 binary.BigEndian.PutUint64(data[n:], s.RxFrameErr) 778 n += 8 779 binary.BigEndian.PutUint64(data[n:], s.RxOverErr) 780 n += 8 781 binary.BigEndian.PutUint64(data[n:], s.RxCRCErr) 782 n += 8 783 binary.BigEndian.PutUint64(data[n:], s.Collisions) 784 n += 8 785 return 786 } 787 788 func (s *PortStats) UnmarshalBinary(data []byte) error { 789 n := 0 790 s.PortNo = binary.BigEndian.Uint16(data[n:]) 791 n += 2 792 copy(s.pad, data[n:]) 793 n += len(s.pad) 794 s.RxPackets = binary.BigEndian.Uint64(data[n:]) 795 n += 8 796 s.TxPackets = binary.BigEndian.Uint64(data[n:]) 797 n += 8 798 s.RxBytes = binary.BigEndian.Uint64(data[n:]) 799 n += 8 800 s.TxBytes = binary.BigEndian.Uint64(data[n:]) 801 n += 8 802 s.RxDropped = binary.BigEndian.Uint64(data[n:]) 803 n += 8 804 s.TxDropped = binary.BigEndian.Uint64(data[n:]) 805 n += 8 806 s.RxErrors = binary.BigEndian.Uint64(data[n:]) 807 n += 8 808 s.TxErrors = binary.BigEndian.Uint64(data[n:]) 809 n += 8 810 s.RxFrameErr = binary.BigEndian.Uint64(data[n:]) 811 n += 8 812 s.RxOverErr = binary.BigEndian.Uint64(data[n:]) 813 n += 8 814 s.RxCRCErr = binary.BigEndian.Uint64(data[n:]) 815 n += 8 816 s.Collisions = binary.BigEndian.Uint64(data[n:]) 817 n += 8 818 return nil 819 } 820 821 // ofp_queue_stats_request 1.0 822 type QueueStatsRequest struct { 823 PortNo uint16 824 pad []uint8 // Size 2 825 QueueId uint32 826 } 827 828 func NewQueueStatsRequest() *QueueStatsRequest { 829 q := new(QueueStatsRequest) 830 q.pad = make([]byte, 2) 831 return q 832 } 833 834 func (s *QueueStatsRequest) Len() (n uint16) { 835 return 8 836 } 837 838 func (s *QueueStatsRequest) MarshalBinary() (data []byte, err error) { 839 data = make([]byte, int(s.Len())) 840 n := 0 841 binary.BigEndian.PutUint16(data[n:], s.PortNo) 842 n += 2 843 copy(data[n:], s.pad) 844 n += 2 845 binary.BigEndian.PutUint32(data[n:], s.QueueId) 846 n += 4 847 return 848 } 849 850 func (s *QueueStatsRequest) UnmarshalBinary(data []byte) error { 851 n := 0 852 s.PortNo = binary.BigEndian.Uint16(data[n:]) 853 n += 2 854 copy(s.pad, data[n:]) 855 n += 2 856 s.QueueId = binary.BigEndian.Uint32(data[n:]) 857 return nil 858 } 859 860 // ofp_queue_stats 1.0 861 type QueueStats struct { 862 PortNo uint16 863 pad []uint8 // Size 2 864 QueueId uint32 865 TxBytes uint64 866 TxPackets uint64 867 TxErrors uint64 868 } 869 870 func (s *QueueStats) Len() (n uint16) { 871 return 32 872 } 873 874 func (s *QueueStats) MarshalBinary() (data []byte, err error) { 875 data = make([]byte, 32) 876 n := 0 877 878 binary.BigEndian.PutUint16(data[n:], s.PortNo) 879 n += 2 880 copy(data[n:], s.pad) 881 n += 2 882 binary.BigEndian.PutUint32(data[n:], s.QueueId) 883 n += 4 884 binary.BigEndian.PutUint64(data[n:], s.TxBytes) 885 n += 8 886 binary.BigEndian.PutUint64(data[n:], s.TxPackets) 887 n += 8 888 binary.BigEndian.PutUint64(data[n:], s.TxErrors) 889 n += 8 890 return 891 } 892 893 func (s *QueueStats) UnmarshalBinary(data []byte) error { 894 n := 0 895 s.PortNo = binary.BigEndian.Uint16(data[n:]) 896 n += 2 897 copy(s.pad, data[n:]) 898 n += len(s.pad) 899 s.QueueId = binary.BigEndian.Uint32(data[n:]) 900 n += 4 901 s.TxBytes = binary.BigEndian.Uint64(data[n:]) 902 n += 8 903 s.TxPackets = binary.BigEndian.Uint64(data[n:]) 904 n += 8 905 s.TxErrors = binary.BigEndian.Uint64(data[n:]) 906 n += 8 907 return nil 908 } 909 910 // ofp_port_status 911 type PortStatus struct { 912 common.Header 913 Reason uint8 914 pad []uint8 // Size 7 915 Desc PhyPort 916 } 917 918 func NewPortStatus() *PortStatus { 919 p := new(PortStatus) 920 p.Header = NewOfp13Header() 921 p.pad = make([]byte, 7) 922 return p 923 } 924 925 func (p *PortStatus) Len() (n uint16) { 926 n = p.Header.Len() 927 n += 8 928 n += p.Desc.Len() 929 return 930 } 931 932 func (s *PortStatus) MarshalBinary() (data []byte, err error) { 933 s.Header.Length = s.Len() 934 data, err = s.Header.MarshalBinary() 935 936 b := make([]byte, 8) 937 n := 0 938 b[0] = s.Reason 939 n += 1 940 copy(b[n:], s.pad) 941 data = append(data, b...) 942 943 b, err = s.Desc.MarshalBinary() 944 data = append(data, b...) 945 return 946 } 947 948 func (s *PortStatus) UnmarshalBinary(data []byte) error { 949 err := s.Header.UnmarshalBinary(data) 950 n := int(s.Header.Len()) 951 952 s.Reason = data[n] 953 n += 1 954 copy(s.pad, data[n:]) 955 n += len(s.pad) 956 957 err = s.Desc.UnmarshalBinary(data[n:]) 958 return err 959 } 960 961 // ofp_port_reason 1.0 962 const ( 963 PR_ADD = iota 964 PR_DELETE 965 PR_MODIFY 966 )