diff --git a/go/lib/ctrl/colibri_mgmt/BUILD.bazel b/go/lib/ctrl/colibri_mgmt/BUILD.bazel index b6007534ee..1ef49cb93d 100644 --- a/go/lib/ctrl/colibri_mgmt/BUILD.bazel +++ b/go/lib/ctrl/colibri_mgmt/BUILD.bazel @@ -8,6 +8,7 @@ go_library( "e2e_setup.go", "request.go", "reservation_ids.go", + "response.go", "segment_cleanup.go", "segment_index_confirmation.go", "segment_setup.go", diff --git a/go/lib/ctrl/colibri_mgmt/colibri_mgmt.go b/go/lib/ctrl/colibri_mgmt/colibri_mgmt.go index 2253f62128..5c379af01b 100644 --- a/go/lib/ctrl/colibri_mgmt/colibri_mgmt.go +++ b/go/lib/ctrl/colibri_mgmt/colibri_mgmt.go @@ -20,10 +20,6 @@ import ( "github.com/scionproto/scion/go/proto" ) -type Response struct { - // TODO(juagargi) -} - type ColibriRequestPayload struct { Which proto.ColibriRequestPayload_Which Request *Request diff --git a/go/lib/ctrl/colibri_mgmt/colibri_mgmt_test.go b/go/lib/ctrl/colibri_mgmt/colibri_mgmt_test.go index 9759a8edc8..6986e38bcb 100644 --- a/go/lib/ctrl/colibri_mgmt/colibri_mgmt_test.go +++ b/go/lib/ctrl/colibri_mgmt/colibri_mgmt_test.go @@ -197,6 +197,160 @@ func TestSerializeRequest(t *testing.T) { require.NoError(t, err) otherBuffer, err := otherRoot.PackRoot() require.NoError(t, err) + require.Equal(t, buffer, otherBuffer) + }) + } +} + +func TestSerializeResponse(t *testing.T) { + newSegmentSetupResp := func() *colibri_mgmt.SegmentSetupRes { + return &colibri_mgmt.SegmentSetupRes{ + Which: proto.SegmentSetupResData_Which_token, + Token: xtest.MustParseHexString("0000"), + } + } + newE2ESetupResp := func() *colibri_mgmt.E2ESetup { + return &colibri_mgmt.E2ESetup{ + Which: proto.E2ESetupData_Which_success, + Success: &colibri_mgmt.E2ESetupSuccess{ + ReservationID: &colibri_mgmt.E2EReservationID{ + ASID: xtest.MustParseHexString("ff00cafe0001"), + Suffix: xtest.MustParseHexString("0123456789abcdef0123456789abcdef"), + }, + Token: xtest.MustParseHexString("0000"), + }, + } + } + testCases := map[string]struct { + Response *colibri_mgmt.Response + }{ + "setup failed": { + Response: &colibri_mgmt.Response{ + Which: proto.Response_Which_segmentSetup, + SegmentSetup: &colibri_mgmt.SegmentSetupRes{ + Which: proto.SegmentSetupResData_Which_failure, + Failure: &colibri_mgmt.SegmentSetup{ + MinBW: 1, + MaxBW: 2, + SplitCls: 3, + StartProps: colibri_mgmt.PathEndProps{ + Local: true, + Transfer: false, + }, + EndProps: colibri_mgmt.PathEndProps{ + Local: false, + Transfer: true, + }, + AllocationTrail: []*colibri_mgmt.AllocationBeads{ + { + AllocBW: 5, + MaxBW: 6, + }, + }, + }, + }, + Accepted: false, + FailedHop: 3, + }, + }, + "setup success": { + Response: &colibri_mgmt.Response{ + Which: proto.Response_Which_segmentSetup, + SegmentSetup: newSegmentSetupResp(), + Accepted: true, + }, + }, + "renewal": { + Response: &colibri_mgmt.Response{ + Which: proto.Response_Which_segmentRenewal, + SegmentRenewal: newSegmentSetupResp(), + Accepted: true, + }, + }, + "teles setup": { + Response: &colibri_mgmt.Response{ + Which: proto.Response_Which_segmentTelesSetup, + SegmentTelesSetup: newSegmentSetupResp(), + Accepted: true, + }, + }, + "teles renewal": { + Response: &colibri_mgmt.Response{ + Which: proto.Response_Which_segmentTelesRenewal, + SegmentTelesRenewal: newSegmentSetupResp(), + Accepted: true, + }, + }, + "teardown": { + Response: &colibri_mgmt.Response{ + Which: proto.Response_Which_segmentTeardown, + SegmentTeardown: &colibri_mgmt.SegmentTeardownRes{ErrorCode: 123}, + Accepted: false, + FailedHop: 2, + }, + }, + "index confirmation": { + Response: &colibri_mgmt.Response{ + Which: proto.Response_Which_segmentIndexConfirmation, + SegmentIndexConfirmation: &colibri_mgmt.SegmentIndexConfirmation{ + Index: 111, + State: proto.ReservationIndexState_active, + }, + Accepted: true, + }, + }, + "segment cleanup": { + Response: &colibri_mgmt.Response{ + Which: proto.Response_Which_segmentCleanup, + SegmentCleanup: &colibri_mgmt.SegmentCleanup{ + ID: &colibri_mgmt.SegmentReservationID{ + ASID: xtest.MustParseHexString("ff00cafe0001"), + Suffix: xtest.MustParseHexString("deadbeef"), + }, + Index: 17, + }, + Accepted: true, + }, + }, + "e2e setup": { + Response: &colibri_mgmt.Response{ + Which: proto.Response_Which_e2eSetup, + E2ESetup: newE2ESetupResp(), + Accepted: true, + }, + }, + "e2e renewal": { + Response: &colibri_mgmt.Response{ + Which: proto.Response_Which_e2eRenewal, + E2ERenewal: newE2ESetupResp(), + Accepted: true, + }, + }, + "e2e cleanup": { + Response: &colibri_mgmt.Response{ + Which: proto.Response_Which_e2eCleanup, + E2ECleanup: &colibri_mgmt.E2ECleanup{ + ReservationID: &colibri_mgmt.E2EReservationID{ + ASID: xtest.MustParseHexString("ff00cafe0001"), + Suffix: xtest.MustParseHexString("0123456789abcdef0123456789abcdef"), + }, + }, + Accepted: true, + }, + }, + } + for name, tc := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + root := &colibri_mgmt.ColibriRequestPayload{ + Which: proto.ColibriRequestPayload_Which_response, + Response: tc.Response, + } + buffer, err := root.PackRoot() + require.NoError(t, err) + otherRoot, err := colibri_mgmt.NewFromRaw(buffer) + require.NoError(t, err) + otherBuffer, err := otherRoot.PackRoot() require.NoError(t, err) require.Equal(t, buffer, otherBuffer) }) diff --git a/go/lib/ctrl/colibri_mgmt/response.go b/go/lib/ctrl/colibri_mgmt/response.go new file mode 100644 index 0000000000..5d1015841a --- /dev/null +++ b/go/lib/ctrl/colibri_mgmt/response.go @@ -0,0 +1,39 @@ +// Copyright 2020 ETH Zurich, Anapaya Systems +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package colibri_mgmt + +import ( + "github.com/scionproto/scion/go/proto" +) + +type Response struct { + Which proto.Response_Which + SegmentSetup *SegmentSetupRes + SegmentRenewal *SegmentSetupRes + SegmentTelesSetup *SegmentSetupRes + SegmentTelesRenewal *SegmentSetupRes + SegmentTeardown *SegmentTeardownRes + SegmentIndexConfirmation *SegmentIndexConfirmation + SegmentCleanup *SegmentCleanup + E2ESetup *E2ESetup `capnp:"e2eSetup"` + E2ERenewal *E2ESetup `capnp:"e2eRenewal"` + E2ECleanup *E2ECleanup `capnp:"e2eCleanup"` + Accepted bool + FailedHop uint8 // only relevant if Accepted == false +} + +func (r *Response) ProtoId() proto.ProtoIdType { + return proto.Response_TypeID +} diff --git a/go/lib/ctrl/colibri_mgmt/segment_setup.go b/go/lib/ctrl/colibri_mgmt/segment_setup.go index 4fb18fe5ec..7121d30a70 100644 --- a/go/lib/ctrl/colibri_mgmt/segment_setup.go +++ b/go/lib/ctrl/colibri_mgmt/segment_setup.go @@ -31,6 +31,16 @@ func (s *SegmentSetup) ProtoId() proto.ProtoIdType { return proto.SegmentSetupReqData_TypeID } +type SegmentSetupRes struct { + Which proto.SegmentSetupResData_Which + Failure *SegmentSetup + Token []byte +} + +func (s *SegmentSetupRes) ProtoId() proto.ProtoIdType { + return proto.SegmentSetupResData_TypeID +} + type PathEndProps struct { Local bool Transfer bool diff --git a/go/lib/ctrl/colibri_mgmt/segment_teardown.go b/go/lib/ctrl/colibri_mgmt/segment_teardown.go index 3ed714bf8a..e2877e8b01 100644 --- a/go/lib/ctrl/colibri_mgmt/segment_teardown.go +++ b/go/lib/ctrl/colibri_mgmt/segment_teardown.go @@ -23,3 +23,11 @@ type SegmentTeardownReq struct{} func (s *SegmentTeardownReq) ProtoId() proto.ProtoIdType { return proto.SegmentTeardownReqData_TypeID } + +type SegmentTeardownRes struct { + ErrorCode uint8 // relevant only if Response.Accepted == false +} + +func (r *SegmentTeardownRes) ProtoId() proto.ProtoIdType { + return proto.SegmentTeardownResData_TypeID +}