{"action":"created","comment":{"url":"https://api.github.com/repos/wenyingd/libOpenflow/pulls/comments/335245334","pull_request_review_id":302244302,"id":335245334,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDMzNTI0NTMzNA==","diff_hunk":"@@ -0,0 +1,956 @@\n+package openflow13\n+\n+import (\n+\t\"encoding/binary\"\n+\t\"errors\"\n+\t\"math\"\n+\t\"net\"\n+)\n+\n+const (\n+\tNxExperimenterID     = 0x00002320 // Experimenter_ID for Nicira extension messages\n+\tNxActionHeaderLength = 10         // Length of Nicira extension message header\n+\n+\tNXAST_RESUBMIT         = 1  // Nicira extended action: resubmit(port)\n+\tNXAST_SET_TUNNEL       = 2  // Nicira extended action: set_tunnel\n+\tNXAST_DROP_SPOOFED_ARP = 3  // Nicira extended action: drop spoofed arp packets\n+\tNXAST_SET_QUEUE        = 4  // Nicira extended action: set_queue\n+\tNXAST_POP_QUEUE        = 5  // Nicira extended action: pop_tunnel\n+\tNXAST_REG_MOVE         = 6  // Nicira extended action: move:srcField[m1..n1]->dstField[m2..n2]\n+\tNXAST_REG_LOAD         = 7  // Nicira extended action: load:data->dstField[m..n]\n+\tNXAST_NOTE             = 8  // Nicira extended action: note\n+\tNXAST_SET_TUNNEL_V6    = 9  // Nicira extended action: set_tunnel64\n+\tNXAST_MULTIPATH        = 10 // Nicira extended action: set_tunnel\n+\tNXAST_AUTOPATH         = 11 // Nicira extended action: multipath\n+\tNXAST_BUNDLE           = 12 // Nicira extended action: bundle\n+\tNXAST_BUNDLE_LOAD      = 13 // Nicira extended action: bundle_load\n+\tNXAST_RESUBMIT_TABLE   = 14 // Nicira extended action: resubmit(port, table)\n+\tNXAST_OUTPUT_REG       = 15 // Nicira extended action: output:field\n+\tNXAST_LEARN            = 16 // Nicira extended action: learn\n+\tNXAST_EXIT             = 17 // Nicira extended action: exit\n+\tNXAST_DEC_TTL          = 18 // Nicira extended action: dec_ttl\n+\tNXAST_FIN_TIMEOUT      = 19 // Nicira extended action: output:field\n+\tNXAST_CONTROLLER       = 20 // Nicira extended action: fin_timeout\n+\tNXAST_DEC_TTL_CNT_IDS  = 21 // Nicira extended action: dec_ttl(id1,[id2]...)\n+\tNXAST_PUSH_MPLS        = 23 // Nicira extended action: push_mpls\n+\tNXAST_POP_MPLS         = 24 // Nicira extended action: pop_mpls\n+\tNXAST_SET_MPLS_TTL     = 25 // Nicira extended action: set_mpls_ttl\n+\tNXAST_DEC_MPLS_TTL     = 26 // Nicira extended action: set_mpls_ttl\n+\tNXAST_STACK_PUSH       = 27 // Nicira extended action: push:src\n+\tNXAST_STACK_POP        = 28 // Nicira extended action: pop:dst\n+\tNXAST_SAMPLE           = 29 // Nicira extended action: sample\n+\tNXAST_SET_MPLS_LABEL   = 30 // Nicira extended action: set_mpls_label\n+\tNXAST_SET_MPLS_TC      = 31 // Nicira extended action: set_mpls_tc\n+\tNXAST_OUTPUT_REG2      = 32 // Nicira extended action: output(port=port,max_len)\n+\tNXAST_REG_LOAD2        = 33 // Nicira extended action: load\n+\tNXAST_CNJUNCTION       = 34 // Nicira extended action: conjunction\n+\tNXAST_CT               = 35 // Nicira extended action: ct\n+\tNXAST_NAT              = 36 // Nicira extended action: nat, need to be along with ct action\n+\tNXAST_CONTROLLER2      = 37 // Nicira extended action: controller(userdata=xxx,pause)\n+\tNXAST_SAMPLE2          = 38 // Nicira extended action: sample, support for exporting egress tunnel\n+\tNXAST_OUTPUT_TRUNC     = 39 // Nicira extended action: truncate output action\n+\tNXAST_CT_CLEAR         = 43 // Nicira extended action: ct_clear\n+\tNXAST_CT_RESUBMIT      = 44 // Nicira extended action: resubmit to table in ct\n+\tNXAST_RAW_ENCAP        = 46 // Nicira extended action: encap\n+\tNXAST_RAW_DECAP        = 47 // Nicira extended action: decap\n+\tNXAST_DEC_NSH_TTL      = 48 // Nicira extended action: dec_nsh_ttl\n+)\n+\n+type NXActionHeader struct {\n+\t*ActionHeader\n+\tVendor  uint32\n+\tSubtype uint16\n+}\n+\n+func (a *NXActionHeader) Header() *ActionHeader {\n+\treturn a.ActionHeader\n+}\n+\n+func (a *NXActionHeader) NXHeader() *NXActionHeader {\n+\treturn a\n+}\n+\n+func (a *NXActionHeader) Len() (n uint16) {\n+\treturn NxActionHeaderLength\n+}\n+\n+func (a *NXActionHeader) MarshalBinary() (data []byte, err error) {\n+\tdata = make([]byte, a.Len())\n+\tb := make([]byte, 0)\n+\tn := 0\n+\n+\tb, err = a.ActionHeader.MarshalBinary()\n+\tcopy(data[n:], b)\n+\tn += len(b)\n+\tbinary.BigEndian.PutUint32(data[n:], a.Vendor)\n+\tn += 4\n+\tbinary.BigEndian.PutUint16(data[n:], a.Subtype)\n+\treturn\n+}\n+\n+func (a *NXActionHeader) UnmarshalBinary(data []byte) error {\n+\tif len(data) < int(NxActionHeaderLength) {\n+\t\treturn errors.New(\"the byte array has wrong size to unmarshal an NXActionHeader message.\")\n+\t}\n+\ta.ActionHeader = new(ActionHeader)\n+\tn := 0\n+\terr := a.ActionHeader.UnmarshalBinary(data[:4])\n+\tn += 4\n+\ta.Vendor = binary.BigEndian.Uint32(data[n:])\n+\tn += 4\n+\ta.Subtype = binary.BigEndian.Uint16(data[n:])\n+\treturn err\n+}\n+\n+func NewNxActionHeader(subtype uint16) *NXActionHeader {\n+\tactionHeader := &ActionHeader{Type: ActionType_Experimenter, Length: NxActionHeaderLength}\n+\treturn &NXActionHeader{ActionHeader: actionHeader, Vendor: NxExperimenterID, Subtype: subtype}\n+}\n+\n+// nxast_conjunction\n+type NXActionConjunction struct {\n+\t*NXActionHeader\n+\tClause  uint8\n+\tNClause uint8\n+\tID      uint32\n+}\n+\n+// conjunction(ID, Clause/nclause)\n+func NewNXActionConjunction(clause uint8, nclause uint8, id uint32) *NXActionConjunction {\n+\ta := new(NXActionConjunction)\n+\ta.NXActionHeader = NewNxActionHeader(NXAST_CNJUNCTION)\n+\ta.Length = a.NXActionHeader.Len() + 6\n+\ta.Clause = clause\n+\ta.NClause = nclause\n+\ta.ID = id\n+\treturn a\n+}\n+\n+func (a *NXActionConjunction) Len() (n uint16) {\n+\treturn a.Length\n+}\n+\n+func (a *NXActionConjunction) MarshalBinary() (data []byte, err error) {\n+\tdata = make([]byte, int(a.Len()))\n+\tb := make([]byte, 0)\n+\tn := 0\n+\n+\tb, err = a.NXActionHeader.MarshalBinary()\n+\tcopy(data[n:], b)\n+\tn += len(b)\n+\tdata[n] = a.Clause\n+\tn += 1\n+\tdata[n] = a.NClause\n+\tn += 1\n+\tbinary.BigEndian.PutUint32(data[n:], a.ID)\n+\tn += 4\n+\n+\treturn\n+}\n+\n+func (a *NXActionConjunction) UnmarshalBinary(data []byte) error {\n+\tn := 0\n+\ta.NXActionHeader = new(NXActionHeader)\n+\terr := a.NXActionHeader.UnmarshalBinary(data[n:])\n+\tn += int(a.NXActionHeader.Len())\n+\tif len(data) < int(a.Len()) {\n+\t\treturn errors.New(\"the byte array has wrong size to unmarshal an NXActionConjunction message\")\n+\t}\n+\ta.Clause = uint8(data[n])\n+\tn += 1\n+\ta.NClause = uint8(data[n])\n+\tn += 1\n+\ta.ID = binary.BigEndian.Uint32(data[n:])\n+\n+\treturn err\n+}\n+\n+// nx_action_conntrack\n+type NXActionConnTrack struct {\n+\t*NXActionHeader\n+\tFlags        uint16\n+\tZoneSrc      uint32\n+\tZoneOfsNbits uint16\n+\tRecircTable  uint8\n+\tpad          []byte // 3bytes\n+\tAlg          uint16\n+\tactions      []Action\n+}\n+\n+func (a *NXActionConnTrack) Len() (n uint16) {\n+\treturn a.Length\n+}\n+\n+func (a *NXActionConnTrack) MarshalBinary() (data []byte, err error) {\n+\tdata = make([]byte, int(a.Length))\n+\tb := make([]byte, 0)\n+\tn := 0\n+\n+\tb, err = a.NXActionHeader.MarshalBinary()\n+\tcopy(data[n:], b)\n+\tn += len(b)\n+\tbinary.BigEndian.PutUint16(data[n:], a.Flags)\n+\tn += 2\n+\tbinary.BigEndian.PutUint32(data[n:], a.ZoneSrc)\n+\tn += 4\n+\tbinary.BigEndian.PutUint16(data[n:], a.ZoneOfsNbits)\n+\tn += 2\n+\tdata[n] = a.RecircTable\n+\tn += 1\n+\tcopy(data[n:], a.pad)\n+\tn += 3\n+\tbinary.BigEndian.PutUint16(data[n:], a.Alg)\n+\tn += 2\n+\t// Marshal ct actions\n+\tfor _, action := range a.actions {\n+\t\tactionBytes, err := action.MarshalBinary()\n+\t\tif err != nil {\n+\t\t\treturn data, errors.New(\"failed to Marshal ct subActions\")\n+\t\t}\n+\t\tcopy(data[n:], actionBytes)\n+\t\tn += len(actionBytes)\n+\t}\n+\treturn\n+}\n+\n+func (a *NXActionConnTrack) UnmarshalBinary(data []byte) error {\n+\tn := 0\n+\ta.NXActionHeader = new(NXActionHeader)\n+\terr := a.NXActionHeader.UnmarshalBinary(data[n:])\n+\tn += int(a.NXActionHeader.Len())\n+\tif len(data) < int(a.Len()) {\n+\t\treturn errors.New(\"the byte array has wrong size to unmarshal an NXActionConnTrack message\")\n+\t}\n+\ta.Flags = binary.BigEndian.Uint16(data[n:])\n+\tn += 2\n+\ta.ZoneSrc = binary.BigEndian.Uint32(data[n:])\n+\tn += 4\n+\ta.ZoneOfsNbits = binary.BigEndian.Uint16(data[n:])\n+\tn += 2\n+\ta.RecircTable = data[n]\n+\tn += 1\n+\tcopy(a.pad, data[n:n+3])\n+\tn += 3\n+\ta.Alg = binary.BigEndian.Uint16(data[n:])\n+\tn += 2\n+\n+\tfor n < int(a.Len()) {\n+\t\tact, err := DecodeAction(data[n:])\n+\t\tif err != nil {\n+\t\t\treturn errors.New(\"failed to decode actions\")\n+\t\t}\n+\t\ta.actions = append(a.actions, act)\n+\t\tn += int(act.Len())\n+\t}\n+\ta.Length = uint16(n)\n+\treturn err\n+}\n+\n+func (a *NXActionConnTrack) Commit() *NXActionConnTrack {\n+\ta.Flags |= NX_CT_F_COMMIT\n+\treturn a\n+}\n+\n+func (a *NXActionConnTrack) Force() *NXActionConnTrack {\n+\ta.Flags |= NX_CT_F_FORCE\n+\treturn a\n+}\n+\n+func (a *NXActionConnTrack) Table(tableID uint8) *NXActionConnTrack {\n+\ta.RecircTable = tableID\n+\treturn a\n+}\n+\n+func (a *NXActionConnTrack) ZoneImm(zoneID uint16) *NXActionConnTrack {\n+\ta.ZoneSrc = 0\n+\ta.ZoneOfsNbits = zoneID\n+\treturn a\n+}\n+\n+func (a *NXActionConnTrack) ZoneRange(field *MatchField, rng *NXRange) *NXActionConnTrack {\n+\ta.ZoneSrc = field.MarshalHeader()\n+\ta.ZoneOfsNbits = rng.ToOfsBits()\n+\treturn a\n+}\n+\n+func (a *NXActionConnTrack) AddAction(actions ...Action) *NXActionConnTrack {\n+\tfor _, act := range actions {\n+\t\ta.actions = append(a.actions, act)\n+\t\ta.Length += act.Len()\n+\t}\n+\treturn a\n+}\n+\n+func NewNXActionConnTrack() *NXActionConnTrack {\n+\ta := new(NXActionConnTrack)\n+\ta.NXActionHeader = NewNxActionHeader(NXAST_CT)\n+\ta.Length = a.NXActionHeader.Len() + 14\n+\ta.RecircTable = NX_CT_RECIRC_NONE\n+\treturn a\n+}\n+\n+// nx_action_reg_load\n+type NXActionRegLoad struct {\n+\t*NXActionHeader\n+\tOfsNbits uint16\n+\tDstReg   *MatchField\n+\tValue    uint64\n+}\n+\n+func NewNXActionRegLoad(ofsNbits uint16, dstField *MatchField, value uint64) *NXActionRegLoad {\n+\ta := new(NXActionRegLoad)\n+\ta.NXActionHeader = NewNxActionHeader(NXAST_REG_LOAD)\n+\ta.Length = a.NXActionHeader.Len() + 14\n+\ta.OfsNbits = ofsNbits\n+\ta.DstReg = dstField\n+\ta.Value = value\n+\treturn a\n+}\n+\n+func (a *NXActionRegLoad) Len() (n uint16) {\n+\treturn a.Length\n+}\n+\n+func (a *NXActionRegLoad) MarshalBinary() (data []byte, err error) {\n+\tdata = make([]byte, int(a.Len()))\n+\tb := make([]byte, 0)\n+\tn := 0\n+\n+\tb, err = a.NXActionHeader.MarshalBinary()\n+\tcopy(data[n:], b)\n+\tn += len(b)\n+\tbinary.BigEndian.PutUint16(data[n:], a.OfsNbits)\n+\tn += 2\n+\tfieldHeaderData := a.DstReg.MarshalHeader()\n+\tbinary.BigEndian.PutUint32(data[n:], fieldHeaderData)\n+\tn += 4\n+\tbinary.BigEndian.PutUint64(data[n:], a.Value)\n+\tn += 8\n+\n+\treturn\n+}\n+\n+func (a *NXActionRegLoad) UnmarshalBinary(data []byte) error {\n+\tn := 0\n+\ta.NXActionHeader = new(NXActionHeader)\n+\terr := a.NXActionHeader.UnmarshalBinary(data[n:])\n+\tn += int(a.NXActionHeader.Len())\n+\tif len(data) < int(a.Len()) {\n+\t\treturn errors.New(\"the byte array has wrong size to unmarshal an NXActionRegLoad message\")\n+\t}\n+\ta.OfsNbits = binary.BigEndian.Uint16(data[n:])\n+\tn += 2\n+\ta.DstReg = new(MatchField)\n+\terr = a.DstReg.UnmarshalHeader(data[n : n+4])\n+\tn += 4\n+\ta.Value = binary.BigEndian.Uint64(data[n:])\n+\treturn err\n+}\n+\n+// nx_action_reg_move\n+type NXActionRegMove struct {\n+\t*NXActionHeader\n+\tNbits    uint16\n+\tSrcOfs   uint16\n+\tDstOfs   uint16\n+\tSrcField *MatchField\n+\tDstField *MatchField\n+}\n+\n+func NewNXActionRegMove(nBits uint16, srcOfs uint16, dstOfs uint16, srcField *MatchField, dstField *MatchField) *NXActionRegMove {\n+\ta := new(NXActionRegMove)\n+\ta.NXActionHeader = NewNxActionHeader(NXAST_REG_MOVE)\n+\ta.Length = a.NXActionHeader.Len() + 14\n+\ta.Nbits = nBits\n+\ta.SrcOfs = srcOfs\n+\ta.DstOfs = dstOfs\n+\ta.SrcField = srcField\n+\ta.DstField = dstField\n+\treturn a\n+}\n+\n+func (a *NXActionRegMove) Len() (n uint16) {\n+\treturn a.Length\n+}\n+\n+func (a *NXActionRegMove) MarshalBinary() (data []byte, err error) {\n+\tdata = make([]byte, 24)\n+\tb := make([]byte, 0)\n+\tn := 0\n+\n+\tb, err = a.NXActionHeader.MarshalBinary()\n+\tcopy(data[n:], b)\n+\tn += len(b)\n+\tbinary.BigEndian.PutUint16(data[n:], a.Nbits)\n+\tn += 2\n+\tbinary.BigEndian.PutUint16(data[n:], a.SrcOfs)\n+\tn += 2\n+\tbinary.BigEndian.PutUint16(data[n:], a.DstOfs)\n+\tn += 2\n+\n+\tsrcFieldHeaderData := a.SrcField.MarshalHeader()\n+\tbinary.BigEndian.PutUint32(data[n:], srcFieldHeaderData)\n+\tn += 4\n+\n+\tdstFieldHeaderData := a.DstField.MarshalHeader()\n+\tbinary.BigEndian.PutUint32(data[n:], dstFieldHeaderData)\n+\tn += 4\n+\treturn\n+}\n+\n+func (a *NXActionRegMove) UnmarshalBinary(data []byte) error {\n+\tn := 0\n+\ta.NXActionHeader = new(NXActionHeader)\n+\terr := a.NXActionHeader.UnmarshalBinary(data[n:])\n+\tn += int(a.NXActionHeader.Len())\n+\tif len(data) < int(a.Len()) {\n+\t\treturn errors.New(\"the byte array has wrong size to unmarshal an NXActionRegLoad message\")\n+\t}\n+\ta.Nbits = binary.BigEndian.Uint16(data[n:])\n+\tn += 2\n+\ta.SrcOfs = binary.BigEndian.Uint16(data[n:])\n+\tn += 2\n+\ta.DstOfs = binary.BigEndian.Uint16(data[n:])\n+\tn += 2\n+\ta.SrcField = new(MatchField)\n+\terr = a.SrcField.UnmarshalHeader(data[n:])\n+\tn += 4\n+\ta.DstField = new(MatchField)\n+\terr = a.DstField.UnmarshalHeader(data[n:])\n+\treturn err\n+}\n+\n+type NXActionResubmit struct {\n+\t*NXActionHeader\n+\tInPort  uint16\n+\tTableID uint8\n+\tpad     []byte // 3 bytes\n+}\n+\n+func NewNXActionResubmit(inPort uint16) *NXActionResubmit {\n+\ta := new(NXActionResubmit)\n+\ta.NXActionHeader = NewNxActionHeader(NXAST_RESUBMIT)\n+\ta.Type = Type_Experimenter\n+\ta.Length = a.NXActionHeader.Len() + 6\n+\ta.InPort = inPort\n+\ta.pad = make([]byte, 3, 3)\n+\treturn a\n+}\n+\n+func (a *NXActionResubmit) Len() (n uint16) {\n+\treturn a.Length\n+}\n+\n+func (a *NXActionResubmit) MarshalBinary() (data []byte, err error) {\n+\tdata = make([]byte, int(a.Len()))\n+\tb := make([]byte, 0)\n+\tn := 0\n+\n+\tb, err = a.NXActionHeader.MarshalBinary()\n+\tcopy(data[n:], b)\n+\tn += len(b)\n+\tbinary.BigEndian.PutUint16(data[n:], a.InPort)\n+\tn += 2\n+\ta.TableID = OFPTT_ALL\n+\tn += 1\n+\tcopy(data[n:], a.pad)\n+\tn += 3\n+\n+\treturn\n+}\n+\n+func (a *NXActionResubmit) UnmarshalBinary(data []byte) error {\n+\tn := 0\n+\ta.NXActionHeader = new(NXActionHeader)\n+\terr := a.NXActionHeader.UnmarshalBinary(data[n:])\n+\tn += int(a.NXActionHeader.Len())\n+\tif len(data) < int(a.Len()) {\n+\t\treturn errors.New(\"the byte array has wrong size to unmarshal an NXActionConjunction message\")\n+\t}\n+\ta.InPort = binary.BigEndian.Uint16(data[n:])\n+\n+\treturn err\n+}\n+\n+// nxast_resubmit_table\n+type NXActionResubmitTable struct {\n+\t*NXActionHeader\n+\tInPort  uint16\n+\tTableID uint8\n+\tpad     []byte // 3 bytes\n+\twithCT  bool\n+}\n+\n+func newNXActionResubmitTable() *NXActionResubmitTable {\n+\ta := &NXActionResubmitTable{\n+\t\tNXActionHeader: NewNxActionHeader(NXAST_RESUBMIT_TABLE),\n+\t\twithCT:         false,\n+\t\tpad:            make([]byte, 3, 3),\n+\t}\n+\ta.Length = 16\n+\treturn a\n+}\n+\n+func newNXActionResubmitTableCT() *NXActionResubmitTable {\n+\ta := &NXActionResubmitTable{\n+\t\tNXActionHeader: NewNxActionHeader(NXAST_RESUBMIT_TABLE),\n+\t\twithCT:         true,\n+\t\tpad:            make([]byte, 3, 3),\n+\t}\n+\ta.Length = 16\n+\treturn a\n+}\n+\n+func NewNXActionResubmitTableAction(inPort uint16, tableId uint8) *NXActionResubmitTable {\n+\ta := newNXActionResubmitTable()\n+\ta.InPort = inPort\n+\ta.TableID = tableId\n+\treturn a\n+}\n+\n+func (a *NXActionResubmitTable) IsCT() bool {\n+\treturn a.withCT\n+}\n+\n+func (a *NXActionResubmitTable) Len() (n uint16) {\n+\treturn a.Length\n+}\n+\n+func (a *NXActionResubmitTable) MarshalBinary() (data []byte, err error) {\n+\tdata = make([]byte, int(a.Len()))\n+\tb := make([]byte, 0)\n+\tn := 0\n+\n+\tb, err = a.NXActionHeader.MarshalBinary()\n+\tcopy(data[n:], b)\n+\tn += len(b)\n+\tbinary.BigEndian.PutUint16(data[n:], a.InPort)\n+\tn += 2\n+\tdata[n] = a.TableID\n+\tn += 1\n+\tcopy(data[n:], a.pad)\n+\tn += 3\n+\n+\treturn\n+}\n+\n+func (a *NXActionResubmitTable) UnmarshalBinary(data []byte) error {\n+\tn := 0\n+\ta.NXActionHeader = new(NXActionHeader)\n+\terr := a.NXActionHeader.UnmarshalBinary(data[n:])\n+\tn += int(a.NXActionHeader.Len())\n+\tif len(data) < int(a.Len()) {\n+\t\treturn errors.New(\"the byte array has wrong size to unmarshal an NXActionResubmitTable message\")\n+\t}\n+\ta.InPort = binary.BigEndian.Uint16(data[n:])\n+\tn += 2\n+\ta.TableID = data[n]\n+\tn += 1\n+\tcopy(a.pad, data[n:n+3])\n+\n+\treturn err\n+}\n+\n+func NewNXActionResubmitTableCT(inPort uint16, tableId uint8) *NXActionResubmitTable {\n+\ta := newNXActionResubmitTableCT()\n+\ta.InPort = inPort\n+\ta.TableID = tableId\n+\treturn a\n+}\n+\n+func NewNXActionResubmitTableCTNoInPort(tableId uint8) *NXActionResubmitTable {\n+\ta := newNXActionResubmitTableCT()\n+\ta.InPort = OFPP_IN_PORT\n+\ta.TableID = tableId\n+\treturn a\n+}\n+\n+// nxast_resubmit_table\n+type NXActionCTNAT struct {\n+\t*NXActionHeader\n+\tpad          []byte // 2 bytes\n+\tFlags        uint16 // nat Flags to identify snat/dnat, and nat algorithms: random/protocolHash, connection persistent\n+\trangePresent uint16 // mark if has set nat range, including ipv4/ipv6 range, port range\n+\n+\trangeIPv4Min  net.IP\n+\trangeIPv4Max  net.IP\n+\trangeIPv6Min  net.IP\n+\trangeIPv6Max  net.IP\n+\trangeProtoMin *uint16\n+\trangeProtoMax *uint16\n+}\n+\n+func NewNXActionCTNAT() *NXActionCTNAT {\n+\ta := new(NXActionCTNAT)\n+\ta.NXActionHeader = NewNxActionHeader(NXAST_NAT)\n+\ta.Length = 16\n+\ta.pad = make([]byte, 2, 2)\n+\treturn a\n+}\n+\n+func (a *NXActionCTNAT) Len() (n uint16) {\n+\ta.Length = uint16(math.Ceil(float64(a.Length)/float64(8))) * 8","path":"openflow13/nx_action.go","position":592,"original_position":592,"commit_id":"3b569beac0981d05f27a81b2a450bd7820d5c393","original_commit_id":"3b569beac0981d05f27a81b2a450bd7820d5c393","user":{"login":"antoninbas","id":2495809,"node_id":"MDQ6VXNlcjI0OTU4MDk=","avatar_url":"https://avatars1.githubusercontent.com/u/2495809?v=4","gravatar_id":"","url":"https://api.github.com/users/antoninbas","html_url":"https://github.com/antoninbas","followers_url":"https://api.github.com/users/antoninbas/followers","following_url":"https://api.github.com/users/antoninbas/following{/other_user}","gists_url":"https://api.github.com/users/antoninbas/gists{/gist_id}","starred_url":"https://api.github.com/users/antoninbas/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/antoninbas/subscriptions","organizations_url":"https://api.github.com/users/antoninbas/orgs","repos_url":"https://api.github.com/users/antoninbas/repos","events_url":"https://api.github.com/users/antoninbas/events{/privacy}","received_events_url":"https://api.github.com/users/antoninbas/received_events","type":"User","site_admin":false},"body":"I think the following is more concise / elegant:\r\n```\r\na.Length = ((a.Length + 7) / 8) * 8\r\n```","created_at":"2019-10-16T01:36:41Z","updated_at":"2019-10-16T01:58:09Z","html_url":"https://github.com/wenyingd/libOpenflow/pull/1#discussion_r335245334","pull_request_url":"https://api.github.com/repos/wenyingd/libOpenflow/pulls/1","author_association":"NONE","_links":{"self":{"href":"https://api.github.com/repos/wenyingd/libOpenflow/pulls/comments/335245334"},"html":{"href":"https://github.com/wenyingd/libOpenflow/pull/1#discussion_r335245334"},"pull_request":{"href":"https://api.github.com/repos/wenyingd/libOpenflow/pulls/1"}}},"pull_request":{"url":"https://api.github.com/repos/wenyingd/libOpenflow/pulls/1","id":316262757,"node_id":"MDExOlB1bGxSZXF1ZXN0MzE2MjYyNzU3","html_url":"https://github.com/wenyingd/libOpenflow/pull/1","diff_url":"https://github.com/wenyingd/libOpenflow/pull/1.diff","patch_url":"https://github.com/wenyingd/libOpenflow/pull/1.patch","issue_url":"https://api.github.com/repos/wenyingd/libOpenflow/issues/1","number":1,"state":"open","locked":false,"title":"Nx extension2","user":{"login":"wenyingd","id":5153872,"node_id":"MDQ6VXNlcjUxNTM4NzI=","avatar_url":"https://avatars0.githubusercontent.com/u/5153872?v=4","gravatar_id":"","url":"https://api.github.com/users/wenyingd","html_url":"https://github.com/wenyingd","followers_url":"https://api.github.com/users/wenyingd/followers","following_url":"https://api.github.com/users/wenyingd/following{/other_user}","gists_url":"https://api.github.com/users/wenyingd/gists{/gist_id}","starred_url":"https://api.github.com/users/wenyingd/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wenyingd/subscriptions","organizations_url":"https://api.github.com/users/wenyingd/orgs","repos_url":"https://api.github.com/users/wenyingd/repos","events_url":"https://api.github.com/users/wenyingd/events{/privacy}","received_events_url":"https://api.github.com/users/wenyingd/received_events","type":"User","site_admin":false},"body":"Add support for Nicira extension, and also add support for several standard OF match and actions.\r\nThis pull request could be leveraged to help generate openflow entries for OKN implementation.","created_at":"2019-09-11T04:07:24Z","updated_at":"2019-10-16T01:58:08Z","closed_at":null,"merged_at":null,"merge_commit_sha":"d5fe30ed7ce8204a737ea3fe36a3800ef608883d","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/wenyingd/libOpenflow/pulls/1/commits","review_comments_url":"https://api.github.com/repos/wenyingd/libOpenflow/pulls/1/comments","review_comment_url":"https://api.github.com/repos/wenyingd/libOpenflow/pulls/comments{/number}","comments_url":"https://api.github.com/repos/wenyingd/libOpenflow/issues/1/comments","statuses_url":"https://api.github.com/repos/wenyingd/libOpenflow/statuses/3b569beac0981d05f27a81b2a450bd7820d5c393","head":{"label":"wenyingd:nx_extension2","ref":"nx_extension2","sha":"3b569beac0981d05f27a81b2a450bd7820d5c393","user":{"login":"wenyingd","id":5153872,"node_id":"MDQ6VXNlcjUxNTM4NzI=","avatar_url":"https://avatars0.githubusercontent.com/u/5153872?v=4","gravatar_id":"","url":"https://api.github.com/users/wenyingd","html_url":"https://github.com/wenyingd","followers_url":"https://api.github.com/users/wenyingd/followers","following_url":"https://api.github.com/users/wenyingd/following{/other_user}","gists_url":"https://api.github.com/users/wenyingd/gists{/gist_id}","starred_url":"https://api.github.com/users/wenyingd/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wenyingd/subscriptions","organizations_url":"https://api.github.com/users/wenyingd/orgs","repos_url":"https://api.github.com/users/wenyingd/repos","events_url":"https://api.github.com/users/wenyingd/events{/privacy}","received_events_url":"https://api.github.com/users/wenyingd/received_events","type":"User","site_admin":false},"repo":{"id":197708271,"node_id":"MDEwOlJlcG9zaXRvcnkxOTc3MDgyNzE=","name":"libOpenflow","full_name":"wenyingd/libOpenflow","private":false,"owner":{"login":"wenyingd","id":5153872,"node_id":"MDQ6VXNlcjUxNTM4NzI=","avatar_url":"https://avatars0.githubusercontent.com/u/5153872?v=4","gravatar_id":"","url":"https://api.github.com/users/wenyingd","html_url":"https://github.com/wenyingd","followers_url":"https://api.github.com/users/wenyingd/followers","following_url":"https://api.github.com/users/wenyingd/following{/other_user}","gists_url":"https://api.github.com/users/wenyingd/gists{/gist_id}","starred_url":"https://api.github.com/users/wenyingd/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wenyingd/subscriptions","organizations_url":"https://api.github.com/users/wenyingd/orgs","repos_url":"https://api.github.com/users/wenyingd/repos","events_url":"https://api.github.com/users/wenyingd/events{/privacy}","received_events_url":"https://api.github.com/users/wenyingd/received_events","type":"User","site_admin":false},"html_url":"https://github.com/wenyingd/libOpenflow","description":null,"fork":true,"url":"https://api.github.com/repos/wenyingd/libOpenflow","forks_url":"https://api.github.com/repos/wenyingd/libOpenflow/forks","keys_url":"https://api.github.com/repos/wenyingd/libOpenflow/keys{/key_id}","collaborators_url":"https://api.github.com/repos/wenyingd/libOpenflow/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/wenyingd/libOpenflow/teams","hooks_url":"https://api.github.com/repos/wenyingd/libOpenflow/hooks","issue_events_url":"https://api.github.com/repos/wenyingd/libOpenflow/issues/events{/number}","events_url":"https://api.github.com/repos/wenyingd/libOpenflow/events","assignees_url":"https://api.github.com/repos/wenyingd/libOpenflow/assignees{/user}","branches_url":"https://api.github.com/repos/wenyingd/libOpenflow/branches{/branch}","tags_url":"https://api.github.com/repos/wenyingd/libOpenflow/tags","blobs_url":"https://api.github.com/repos/wenyingd/libOpenflow/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/wenyingd/libOpenflow/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/wenyingd/libOpenflow/git/refs{/sha}","trees_url":"https://api.github.com/repos/wenyingd/libOpenflow/git/trees{/sha}","statuses_url":"https://api.github.com/repos/wenyingd/libOpenflow/statuses/{sha}","languages_url":"https://api.github.com/repos/wenyingd/libOpenflow/languages","stargazers_url":"https://api.github.com/repos/wenyingd/libOpenflow/stargazers","contributors_url":"https://api.github.com/repos/wenyingd/libOpenflow/contributors","subscribers_url":"https://api.github.com/repos/wenyingd/libOpenflow/subscribers","subscription_url":"https://api.github.com/repos/wenyingd/libOpenflow/subscription","commits_url":"https://api.github.com/repos/wenyingd/libOpenflow/commits{/sha}","git_commits_url":"https://api.github.com/repos/wenyingd/libOpenflow/git/commits{/sha}","comments_url":"https://api.github.com/repos/wenyingd/libOpenflow/comments{/number}","issue_comment_url":"https://api.github.com/repos/wenyingd/libOpenflow/issues/comments{/number}","contents_url":"https://api.github.com/repos/wenyingd/libOpenflow/contents/{+path}","compare_url":"https://api.github.com/repos/wenyingd/libOpenflow/compare/{base}...{head}","merges_url":"https://api.github.com/repos/wenyingd/libOpenflow/merges","archive_url":"https://api.github.com/repos/wenyingd/libOpenflow/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/wenyingd/libOpenflow/downloads","issues_url":"https://api.github.com/repos/wenyingd/libOpenflow/issues{/number}","pulls_url":"https://api.github.com/repos/wenyingd/libOpenflow/pulls{/number}","milestones_url":"https://api.github.com/repos/wenyingd/libOpenflow/milestones{/number}","notifications_url":"https://api.github.com/repos/wenyingd/libOpenflow/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/wenyingd/libOpenflow/labels{/name}","releases_url":"https://api.github.com/repos/wenyingd/libOpenflow/releases{/id}","deployments_url":"https://api.github.com/repos/wenyingd/libOpenflow/deployments","created_at":"2019-07-19T05:35:07Z","updated_at":"2019-08-29T12:06:18Z","pushed_at":"2019-10-08T10:30:09Z","git_url":"git://github.com/wenyingd/libOpenflow.git","ssh_url":"git@github.com:wenyingd/libOpenflow.git","clone_url":"https://github.com/wenyingd/libOpenflow.git","svn_url":"https://github.com/wenyingd/libOpenflow","homepage":null,"size":109,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":1,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"base":{"label":"wenyingd:master","ref":"master","sha":"cb1835d1c11f5810c2fcf404a6d1eb907168f951","user":{"login":"wenyingd","id":5153872,"node_id":"MDQ6VXNlcjUxNTM4NzI=","avatar_url":"https://avatars0.githubusercontent.com/u/5153872?v=4","gravatar_id":"","url":"https://api.github.com/users/wenyingd","html_url":"https://github.com/wenyingd","followers_url":"https://api.github.com/users/wenyingd/followers","following_url":"https://api.github.com/users/wenyingd/following{/other_user}","gists_url":"https://api.github.com/users/wenyingd/gists{/gist_id}","starred_url":"https://api.github.com/users/wenyingd/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wenyingd/subscriptions","organizations_url":"https://api.github.com/users/wenyingd/orgs","repos_url":"https://api.github.com/users/wenyingd/repos","events_url":"https://api.github.com/users/wenyingd/events{/privacy}","received_events_url":"https://api.github.com/users/wenyingd/received_events","type":"User","site_admin":false},"repo":{"id":197708271,"node_id":"MDEwOlJlcG9zaXRvcnkxOTc3MDgyNzE=","name":"libOpenflow","full_name":"wenyingd/libOpenflow","private":false,"owner":{"login":"wenyingd","id":5153872,"node_id":"MDQ6VXNlcjUxNTM4NzI=","avatar_url":"https://avatars0.githubusercontent.com/u/5153872?v=4","gravatar_id":"","url":"https://api.github.com/users/wenyingd","html_url":"https://github.com/wenyingd","followers_url":"https://api.github.com/users/wenyingd/followers","following_url":"https://api.github.com/users/wenyingd/following{/other_user}","gists_url":"https://api.github.com/users/wenyingd/gists{/gist_id}","starred_url":"https://api.github.com/users/wenyingd/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wenyingd/subscriptions","organizations_url":"https://api.github.com/users/wenyingd/orgs","repos_url":"https://api.github.com/users/wenyingd/repos","events_url":"https://api.github.com/users/wenyingd/events{/privacy}","received_events_url":"https://api.github.com/users/wenyingd/received_events","type":"User","site_admin":false},"html_url":"https://github.com/wenyingd/libOpenflow","description":null,"fork":true,"url":"https://api.github.com/repos/wenyingd/libOpenflow","forks_url":"https://api.github.com/repos/wenyingd/libOpenflow/forks","keys_url":"https://api.github.com/repos/wenyingd/libOpenflow/keys{/key_id}","collaborators_url":"https://api.github.com/repos/wenyingd/libOpenflow/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/wenyingd/libOpenflow/teams","hooks_url":"https://api.github.com/repos/wenyingd/libOpenflow/hooks","issue_events_url":"https://api.github.com/repos/wenyingd/libOpenflow/issues/events{/number}","events_url":"https://api.github.com/repos/wenyingd/libOpenflow/events","assignees_url":"https://api.github.com/repos/wenyingd/libOpenflow/assignees{/user}","branches_url":"https://api.github.com/repos/wenyingd/libOpenflow/branches{/branch}","tags_url":"https://api.github.com/repos/wenyingd/libOpenflow/tags","blobs_url":"https://api.github.com/repos/wenyingd/libOpenflow/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/wenyingd/libOpenflow/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/wenyingd/libOpenflow/git/refs{/sha}","trees_url":"https://api.github.com/repos/wenyingd/libOpenflow/git/trees{/sha}","statuses_url":"https://api.github.com/repos/wenyingd/libOpenflow/statuses/{sha}","languages_url":"https://api.github.com/repos/wenyingd/libOpenflow/languages","stargazers_url":"https://api.github.com/repos/wenyingd/libOpenflow/stargazers","contributors_url":"https://api.github.com/repos/wenyingd/libOpenflow/contributors","subscribers_url":"https://api.github.com/repos/wenyingd/libOpenflow/subscribers","subscription_url":"https://api.github.com/repos/wenyingd/libOpenflow/subscription","commits_url":"https://api.github.com/repos/wenyingd/libOpenflow/commits{/sha}","git_commits_url":"https://api.github.com/repos/wenyingd/libOpenflow/git/commits{/sha}","comments_url":"https://api.github.com/repos/wenyingd/libOpenflow/comments{/number}","issue_comment_url":"https://api.github.com/repos/wenyingd/libOpenflow/issues/comments{/number}","contents_url":"https://api.github.com/repos/wenyingd/libOpenflow/contents/{+path}","compare_url":"https://api.github.com/repos/wenyingd/libOpenflow/compare/{base}...{head}","merges_url":"https://api.github.com/repos/wenyingd/libOpenflow/merges","archive_url":"https://api.github.com/repos/wenyingd/libOpenflow/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/wenyingd/libOpenflow/downloads","issues_url":"https://api.github.com/repos/wenyingd/libOpenflow/issues{/number}","pulls_url":"https://api.github.com/repos/wenyingd/libOpenflow/pulls{/number}","milestones_url":"https://api.github.com/repos/wenyingd/libOpenflow/milestones{/number}","notifications_url":"https://api.github.com/repos/wenyingd/libOpenflow/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/wenyingd/libOpenflow/labels{/name}","releases_url":"https://api.github.com/repos/wenyingd/libOpenflow/releases{/id}","deployments_url":"https://api.github.com/repos/wenyingd/libOpenflow/deployments","created_at":"2019-07-19T05:35:07Z","updated_at":"2019-08-29T12:06:18Z","pushed_at":"2019-10-08T10:30:09Z","git_url":"git://github.com/wenyingd/libOpenflow.git","ssh_url":"git@github.com:wenyingd/libOpenflow.git","clone_url":"https://github.com/wenyingd/libOpenflow.git","svn_url":"https://github.com/wenyingd/libOpenflow","homepage":null,"size":109,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":1,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/wenyingd/libOpenflow/pulls/1"},"html":{"href":"https://github.com/wenyingd/libOpenflow/pull/1"},"issue":{"href":"https://api.github.com/repos/wenyingd/libOpenflow/issues/1"},"comments":{"href":"https://api.github.com/repos/wenyingd/libOpenflow/issues/1/comments"},"review_comments":{"href":"https://api.github.com/repos/wenyingd/libOpenflow/pulls/1/comments"},"review_comment":{"href":"https://api.github.com/repos/wenyingd/libOpenflow/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/wenyingd/libOpenflow/pulls/1/commits"},"statuses":{"href":"https://api.github.com/repos/wenyingd/libOpenflow/statuses/3b569beac0981d05f27a81b2a450bd7820d5c393"}},"author_association":"OWNER"}}
{"actor":{"display_login":"antoninbas"}}