github.com/contiv/libOpenflow@v0.0.0-20210609050114-d967b14cc688/openflow13/nxt_message.go (about) 1 package openflow13 2 3 import ( 4 "encoding/binary" 5 "errors" 6 7 "github.com/contiv/libOpenflow/util" 8 ) 9 10 // Nicira extension messages. 11 const ( 12 Type_SetFlowFormat = 12 13 Type_FlowModTableId = 15 14 Type_SetPacketInFormat = 16 15 Type_SetControllerId = 20 16 Type_TlvTableMod = 24 17 Type_TlvTableRequest = 25 18 Type_TlvTableReply = 26 19 Type_Resume = 28 20 Type_CtFlushZone = 29 21 ) 22 23 // ofpet_tlv_table_mod_failed_code 1.3 24 const ( 25 OFPERR_NXTTMFC_BAD_COMMAND = 16 26 OFPERR_NXTTMFC_BAD_OPT_LEN = 17 27 ERR_NXTTMFC_BAD_FIELD_IDX = 18 28 OFPERR_NXTTMFC_TABLE_FULL = 19 29 OFPERR_NXTTMFC_ALREADY_MAPPED = 20 30 OFPERR_NXTTMFC_DUP_ENTRY = 21 31 OFPERR_NXTTMFC_INVALID_TLV_DEL = 38 32 ) 33 34 func NewNXTVendorHeader(msgType uint32) *VendorHeader { 35 h := NewOfp13Header() 36 h.Type = Type_Experimenter 37 return &VendorHeader{ 38 Header: h, 39 Vendor: NxExperimenterID, 40 ExperimenterType: msgType, 41 } 42 } 43 44 type ControllerID struct { 45 pad [6]byte 46 ID uint16 47 } 48 49 func (c *ControllerID) Len() uint16 { 50 return uint16(len(c.pad) + 2) 51 } 52 53 func (c *ControllerID) MarshalBinary() (data []byte, err error) { 54 data = make([]byte, int(c.Len())) 55 n := 6 56 binary.BigEndian.PutUint16(data[n:], c.ID) 57 return data, nil 58 } 59 60 func (c *ControllerID) UnmarshalBinary(data []byte) error { 61 if len(data) < int(c.Len()) { 62 return errors.New("the []byte is too short to unmarshal a full ControllerID message") 63 } 64 n := 6 65 c.ID = binary.BigEndian.Uint16(data[n:]) 66 return nil 67 } 68 69 func NewSetControllerID(id uint16) *VendorHeader { 70 msg := NewNXTVendorHeader(Type_SetControllerId) 71 msg.VendorData = &ControllerID{ 72 ID: id, 73 } 74 return msg 75 } 76 77 type TLVTableMap struct { 78 OptClass uint16 79 OptType uint8 80 OptLength uint8 81 Index uint16 82 pad [2]byte 83 } 84 85 func (t *TLVTableMap) Len() uint16 { 86 return uint16(len(t.pad) + 6) 87 } 88 89 func (t *TLVTableMap) MarshalBinary() (data []byte, err error) { 90 data = make([]byte, int(t.Len())) 91 n := 0 92 binary.BigEndian.PutUint16(data[n:], t.OptClass) 93 n += 2 94 data[n] = t.OptType 95 n += 1 96 data[n] = t.OptLength 97 n += 1 98 binary.BigEndian.PutUint16(data[n:], t.Index) 99 return data, nil 100 } 101 102 func (t *TLVTableMap) UnmarshalBinary(data []byte) error { 103 if len(data) < int(t.Len()) { 104 return errors.New("the []byte is too short to unmarshal a full TLVTableMap message") 105 } 106 n := 0 107 t.OptClass = binary.BigEndian.Uint16(data[n:]) 108 n += 2 109 t.OptType = data[n] 110 n += 1 111 t.OptLength = data[n] 112 n += 1 113 t.Index = binary.BigEndian.Uint16(data[n:]) 114 return nil 115 } 116 117 type TLVTableMod struct { 118 Command uint16 119 pad [6]byte 120 TlvMaps []*TLVTableMap 121 } 122 123 func (t *TLVTableMod) Len() uint16 { 124 length := uint16(8) 125 for _, tlvMap := range t.TlvMaps { 126 length += tlvMap.Len() 127 } 128 return length 129 } 130 131 func (t *TLVTableMod) MarshalBinary() (data []byte, err error) { 132 data = make([]byte, t.Len()) 133 n := 0 134 binary.BigEndian.PutUint16(data[n:], t.Command) 135 n += 2 136 n += 6 137 for _, tlvMap := range t.TlvMaps { 138 tlvData, err := tlvMap.MarshalBinary() 139 if err != nil { 140 return nil, err 141 } 142 copy(data[n:], tlvData) 143 n += len(tlvData) 144 } 145 return data, nil 146 } 147 148 func (t *TLVTableMod) UnmarshalBinary(data []byte) error { 149 if len(data) < 8 { 150 return errors.New("the []byte is too short to unmarshal a full TLVTableMod message") 151 } 152 n := 0 153 t.Command = binary.BigEndian.Uint16(data[n:]) 154 n += 2 155 n += 6 156 157 for n < len(data) { 158 tlvMap := new(TLVTableMap) 159 err := tlvMap.UnmarshalBinary(data[n:]) 160 if err != nil { 161 return err 162 } 163 n += int(tlvMap.Len()) 164 t.TlvMaps = append(t.TlvMaps, tlvMap) 165 } 166 return nil 167 } 168 169 func NewTLVTableMod(command uint16, tlvMaps []*TLVTableMap) *TLVTableMod { 170 return &TLVTableMod{ 171 Command: command, 172 TlvMaps: tlvMaps, 173 } 174 } 175 176 func NewTLVTableModMessage(tlvMod *TLVTableMod) *VendorHeader { 177 msg := NewNXTVendorHeader(Type_TlvTableMod) 178 msg.VendorData = tlvMod 179 return msg 180 } 181 182 type TLVTableReply struct { 183 MaxSpace uint32 184 MaxFields uint16 185 reserved [10]byte 186 TlvMaps []*TLVTableMap 187 } 188 189 func (t *TLVTableReply) Len() uint16 { 190 length := uint16(16) 191 for _, tlvMap := range t.TlvMaps { 192 length += tlvMap.Len() 193 } 194 return length 195 } 196 197 func (t *TLVTableReply) MarshalBinary() (data []byte, err error) { 198 data = make([]byte, t.Len()) 199 n := 0 200 binary.BigEndian.PutUint32(data[n:], t.MaxSpace) 201 n += 4 202 binary.BigEndian.PutUint16(data[n:], t.MaxFields) 203 n += 2 204 n += 10 205 for _, tlvMap := range t.TlvMaps { 206 tlvData, err := tlvMap.MarshalBinary() 207 if err != nil { 208 return nil, err 209 } 210 copy(data[n:], tlvData) 211 n += len(tlvData) 212 } 213 return data, nil 214 } 215 216 func (t *TLVTableReply) UnmarshalBinary(data []byte) error { 217 n := 0 218 t.MaxSpace = binary.BigEndian.Uint32(data[n:]) 219 n += 4 220 t.MaxFields = binary.BigEndian.Uint16(data[n:]) 221 n += 2 222 t.reserved = [10]byte{} 223 copy(t.reserved[0:], data[n:n+10]) 224 n += 10 225 for n < len(data) { 226 tlvMap := new(TLVTableMap) 227 err := tlvMap.UnmarshalBinary(data[n:]) 228 if err != nil { 229 return err 230 } 231 n += int(tlvMap.Len()) 232 t.TlvMaps = append(t.TlvMaps, tlvMap) 233 } 234 return nil 235 } 236 237 func NewTLVTableRequest() *VendorHeader { 238 return NewNXTVendorHeader(Type_TlvTableRequest) 239 } 240 241 func decodeVendorData(experimenterType uint32, data []byte) (msg util.Message, err error) { 242 switch experimenterType { 243 case Type_SetControllerId: 244 msg = new(ControllerID) 245 case Type_TlvTableMod: 246 msg = new(TLVTableMod) 247 case Type_TlvTableReply: 248 msg = new(TLVTableReply) 249 case Type_BundleCtrl: 250 msg = new(BundleControl) 251 case Type_BundleAdd: 252 msg = new(BundleAdd) 253 } 254 err = msg.UnmarshalBinary(data) 255 if err != nil { 256 return nil, err 257 } 258 return msg, err 259 }