Repository: scionproto/scion
Pull request #3855 (2020-08-18 19:44:53)

Decouple ctrl messages from data plane
This should make the transition to the new border router easier.
The control plane may have now redundant information that is also present on the data plane, e.g. reservation IDs are now made explicit in the messages, thus not relying on their presence on the data plane packet that arrived to the border router.
Pending:
- [x] rebase after #3843 is merged (first commit is `b0c5ea72`)

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/scionproto/scion/3855)
<!-- Reviewable:end -->


Oncilla: /rebase

Patch:
diff --git a/go/cs/reservation/segment/BUILD.bazel b/go/cs/reservation/segment/BUILD.bazel
index a9cbcc835..51e6f8660 100644
--- a/go/cs/reservation/segment/BUILD.bazel
+++ b/go/cs/reservation/segment/BUILD.bazel
@@ -16,10 +16,8 @@ go_library(
         "//go/lib/addr:go_default_library",
         "//go/lib/colibri/reservation:go_default_library",
         "//go/lib/common:go_default_library",
-        "//go/lib/ctrl/colibri_mgmt:go_default_library",
         "//go/lib/serrors:go_default_library",
         "//go/lib/spath:go_default_library",
-        "//go/proto:go_default_library",
     ],
 )
 
@@ -28,19 +26,14 @@ go_test(
     srcs = [
         "export_test.go",
         "path_test.go",
-        "request_test.go",
         "reservation_test.go",
     ],
     embed = [":go_default_library"],
     deps = [
         "//go/cs/reservation/segmenttest:go_default_library",
         "//go/lib/colibri/reservation:go_default_library",
-        "//go/lib/common:go_default_library",
-        "//go/lib/ctrl/colibri_mgmt:go_default_library",
-        "//go/lib/spath:go_default_library",
         "//go/lib/util:go_default_library",
         "//go/lib/xtest:go_default_library",
-        "//go/proto:go_default_library",
         "@com_github_stretchr_testify//require:go_default_library",
     ],
 )
diff --git a/go/cs/reservation/segment/index.go b/go/cs/reservation/segment/index.go
index 2a6a1f6b3..0934ce720 100644
--- a/go/cs/reservation/segment/index.go
+++ b/go/cs/reservation/segment/index.go
@@ -19,8 +19,6 @@ import (
 
 	base "github.com/scionproto/scion/go/cs/reservation"
 	"github.com/scionproto/scion/go/lib/colibri/reservation"
-	"github.com/scionproto/scion/go/lib/serrors"
-	"github.com/scionproto/scion/go/proto"
 )
 
 type IndexState uint8
@@ -32,34 +30,6 @@ const (
 	IndexActive
 )
 
-// NewIndexStateFromCtrlMsg converts a proto reservation index state into its application type.
-func NewIndexStateFromCtrlMsg(st proto.ReservationIndexState) (IndexState, error) {
-	var state IndexState
-	switch st {
-	case proto.ReservationIndexState_pending:
-		state = IndexPending
-	case proto.ReservationIndexState_active:
-		state = IndexActive
-	default:
-		return 0, serrors.New("unknown index_state in ctrl variable", "index_state", st)
-	}
-	return state, nil
-}
-
-// ToCtrlMsg converts this IndexState to its control message counterpart.
-func (s IndexState) ToCtrlMsg() (proto.ReservationIndexState, error) {
-	var st proto.ReservationIndexState
-	switch s {
-	case IndexPending:
-		st = proto.ReservationIndexState_pending
-	case IndexActive:
-		st = proto.ReservationIndexState_active
-	default:
-		return 0, serrors.New("cannot convert index state to control message", "state", s)
-	}
-	return st, nil
-}
-
 // Index is a segment reservation index.
 type Index struct {
 	Idx        reservation.IndexNumber
diff --git a/go/cs/reservation/segment/request.go b/go/cs/reservation/segment/request.go
index 3c47a48ba..b9057c735 100644
--- a/go/cs/reservation/segment/request.go
+++ b/go/cs/reservation/segment/request.go
@@ -15,29 +15,29 @@
 package segment
 
 import (
-	"encoding/hex"
 	"time"
 
 	base "github.com/scionproto/scion/go/cs/reservation"
 	"github.com/scionproto/scion/go/lib/colibri/reservation"
 	"github.com/scionproto/scion/go/lib/common"
-	"github.com/scionproto/scion/go/lib/ctrl/colibri_mgmt"
 	"github.com/scionproto/scion/go/lib/serrors"
 	"github.com/scionproto/scion/go/lib/spath"
 )
 
-// Request is the base struct for any type of COLIBRI request.
+// Request is the base struct for any type of COLIBRI segment request.
+// It contains a reference to the reservation it requests, or nil if not yet created.
 type Request struct {
-	base.RequestMetadata                       // information about the request (forwarding path)
-	ID                   reservation.SegmentID // the ID this request refers to
-	Timestamp            time.Time             // the mandatory timestamp
-	Ingress              common.IFIDType       // the interface the traffic uses to enter the AS
-	Egress               common.IFIDType       // the interface the traffic uses to leave the AS
-	Reservation          *Reservation          // nil if no reservation yet
+	base.RequestMetadata                         // information about the request (forwarding path)
+	ID                   reservation.SegmentID   // the ID this request refers to
+	Index                reservation.IndexNumber // the index this request refers to
+	Timestamp            time.Time               // the mandatory timestamp
+	Ingress              common.IFIDType         // the interface the traffic uses to enter the AS
+	Egress               common.IFIDType         // the interface the traffic uses to leave the AS
+	Reservation          *Reservation            // nil if no reservation yet
 }
 
 // NewRequest constructs the segment Request type.
-func NewRequest(ts time.Time, ID *colibri_mgmt.SegmentReservationID,
+func NewRequest(ts time.Time, id *reservation.SegmentID, idx reservation.IndexNumber,
 	path *spath.Path) (*Request, error) {
 
 	metadata, err := base.NewRequestMetadata(path)
@@ -57,24 +57,20 @@ func NewRequest(ts time.Time, ID *colibri_mgmt.SegmentReservationID,
 	if !infField.ConsDir {
 		egressIFID, ingressIFID = ingressIFID, egressIFID
 	}
-	if ID == nil {
+	if id == nil {
 		return nil, serrors.New("new segment request with nil ID")
 	}
-	segID, err := reservation.SegmentIDFromRawBuffers(ID.ASID, ID.Suffix)
-	if err != nil {
-		return nil, serrors.WrapStr("new segment request", err)
-	}
 	return &Request{
 		RequestMetadata: *metadata,
 		Timestamp:       ts,
-		ID:              *segID,
+		ID:              *id,
+		Index:           idx,
 		Ingress:         ingressIFID,
 		Egress:          egressIFID,
 	}, nil
 }
 
-// SetupReq is a segment reservation setup request. It contains a reference to the reservation
-// it requests, or nil if not yet created.
+// SetupReq is a segment reservation setup request.
 // This same type is used for renewal of the segment reservation.
 type SetupReq struct {
 	Request
@@ -86,178 +82,25 @@ type SetupReq struct {
 	AllocTrail reservation.AllocationBeads
 }
 
-// NewSetupReqFromCtrlMsg constructs a SetupReq from its control message counterpart. The timestamp
-// comes from the wrapping ColibriRequestPayload, and the spath from the wrapping SCION packet.
-func NewSetupReqFromCtrlMsg(setup *colibri_mgmt.SegmentSetup, ts time.Time,
-	ID *colibri_mgmt.SegmentReservationID, path *spath.Path) (*SetupReq, error) {
-
-	r, err := NewRequest(ts, ID, path)
-	if err != nil {
-		return nil, serrors.WrapStr("cannot construct segment setup request", err)
-	}
-	inF, err := reservation.InfoFieldFromRaw(setup.InfoField)
-	if err != nil {
-		return nil, serrors.WrapStr("cannot construct info field from raw", err)
-	}
-	if inF == nil {
-		return nil, serrors.New("empty info field", "raw", hex.EncodeToString(setup.InfoField))
-	}
-	s := SetupReq{
-		Request:    *r,
-		InfoField:  *inF,
-		MinBW:      reservation.BWCls(setup.MinBW),
-		MaxBW:      reservation.BWCls(setup.MaxBW),
-		SplitCls:   reservation.SplitCls(setup.SplitCls),
-		AllocTrail: make(reservation.AllocationBeads, len(setup.AllocationTrail)),
-		PathProps: reservation.NewPathEndProps(setup.StartProps.Local, setup.StartProps.Transfer,
-			setup.EndProps.Local, setup.EndProps.Transfer),
-	}
-	for i, ab := range setup.AllocationTrail {
-		s.AllocTrail[i] = reservation.AllocationBead{
-			AllocBW: reservation.BWCls(ab.AllocBW),
-			MaxBW:   reservation.BWCls(ab.MaxBW),
-		}
-	}
-	return &s, nil
-}
-
-// ToCtrlMsg creates a new segment setup control message filled with the information from here.
-func (r *SetupReq) ToCtrlMsg() *colibri_mgmt.SegmentSetup {
-
-	msg := &colibri_mgmt.SegmentSetup{
-		MinBW:    uint8(r.MinBW),
-		MaxBW:    uint8(r.MaxBW),
-		SplitCls: uint8(r.SplitCls),
-		StartProps: colibri_mgmt.PathEndProps{
-			Local:    (r.PathProps & reservation.StartLocal) != 0,
-			Transfer: (r.PathProps & reservation.StartTransfer) != 0,
-		},
-		EndProps: colibri_mgmt.PathEndProps{
-			Local:    (r.PathProps & reservation.EndLocal) != 0,
-			Transfer: (r.PathProps & reservation.EndTransfer) != 0,
-		},
-		InfoField:       r.InfoField.ToRaw(),
-		AllocationTrail: make([]*colibri_mgmt.AllocationBead, len(r.AllocTrail)),
-	}
-	for i, bead := range r.AllocTrail {
-		msg.AllocationTrail[i] = &colibri_mgmt.AllocationBead{
-			AllocBW: uint8(bead.AllocBW),
-			MaxBW:   uint8(bead.MaxBW),
-		}
-	}
-	return msg
-}
-
 // SetupTelesReq represents a telescopic segment setup.
 type SetupTelesReq struct {
 	SetupReq
 	BaseID reservation.SegmentID
 }
 
-// NewTelesRequestFromCtrlMsg constucts the app type from its control message counterpart.
-func NewTelesRequestFromCtrlMsg(setup *colibri_mgmt.SegmentTelesSetup, ts time.Time,
-	ID *colibri_mgmt.SegmentReservationID, path *spath.Path) (*SetupTelesReq, error) {
-
-	if setup.BaseID == nil || setup.Setup == nil {
-		return nil, serrors.New("illegal ctrl telescopic setup received", "base_id", setup.BaseID,
-			"segment_setup", setup.Setup)
-	}
-	baseReq, err := NewSetupReqFromCtrlMsg(setup.Setup, ts, ID, path)
-	if err != nil {
-		return nil, serrors.WrapStr("failed to construct base request", err)
-	}
-	s := SetupTelesReq{
-		SetupReq: *baseReq,
-	}
-	id, err := reservation.SegmentIDFromRawBuffers(setup.BaseID.ASID, setup.BaseID.Suffix)
-	if err != nil {
-		return nil, err
-	}
-	s.BaseID = *id
-	return &s, nil
-}
-
-// ToCtrlMsg creates a new segment telescopic setup control message from this request.
-func (r *SetupTelesReq) ToCtrlMsg() *colibri_mgmt.SegmentTelesSetup {
-	buff := make([]byte, reservation.SegmentIDLen)
-	r.BaseID.Read(buff)
-	return &colibri_mgmt.SegmentTelesSetup{
-		Setup: r.SetupReq.ToCtrlMsg(),
-		BaseID: &colibri_mgmt.SegmentReservationID{
-			ASID:   buff[:6],
-			Suffix: buff[6:],
-		},
-	}
+// TeardownReq requests the AS to remove a given index from the DB. If this is the last index
+// in the reservation, the reservation will be completely removed.
+type TeardownReq struct {
+	Request
 }
 
 // IndexConfirmationReq is used to change the state on an index (e.g. from temporary to pending).
 type IndexConfirmationReq struct {
 	Request
-	IndexNumber reservation.IndexNumber
-	State       IndexState
-}
-
-// NewIndexConfirmationReqFromCtrlMsg constructs the application type from its control counterpart.
-func NewIndexConfirmationReqFromCtrlMsg(ctrl *colibri_mgmt.SegmentIndexConfirmation, ts time.Time,
-	ID *colibri_mgmt.SegmentReservationID, path *spath.Path) (*IndexConfirmationReq, error) {
-
-	r, err := NewRequest(ts, ID, path)
-	if err != nil {
-		return nil, serrors.WrapStr("cannot construct index confirmation request", err)
-	}
-	st, err := NewIndexStateFromCtrlMsg(ctrl.State)
-	if err != nil {
-		return nil, err
-	}
-	return &IndexConfirmationReq{
-		Request:     *r,
-		IndexNumber: reservation.IndexNumber(ctrl.Index),
-		State:       st,
-	}, nil
-}
-
-// ToCtrlMsg converts this application type to its control message counterpart.
-func (r *IndexConfirmationReq) ToCtrlMsg() (*colibri_mgmt.SegmentIndexConfirmation, error) {
-	st, err := r.State.ToCtrlMsg()
-	if err != nil {
-		return nil, err
-	}
-	return &colibri_mgmt.SegmentIndexConfirmation{
-		Index: uint8(r.IndexNumber),
-		State: st,
-	}, nil
+	State IndexState
 }
 
 // CleanupReq is used to clean an index.
 type CleanupReq struct {
 	Request
-	IndexNumber reservation.IndexNumber
-}
-
-// NewCleanupReqFromCtrlMsg contructs a cleanup request from its control message counterpart.
-func NewCleanupReqFromCtrlMsg(ctrl *colibri_mgmt.SegmentCleanup, ts time.Time,
-	path *spath.Path) (*CleanupReq, error) {
-
-	// we use the ID inside the control message, as the request could have come without COLIBRI
-	r, err := NewRequest(ts, ctrl.ID, path)
-	if err != nil {
-		return nil, serrors.WrapStr("cannot construct index cleanup request", err)
-	}
-	return &CleanupReq{
-		Request:     *r,
-		IndexNumber: reservation.IndexNumber(ctrl.Index),
-	}, nil
-}
-
-// ToCtrlMsg converts this application type to its control message counterpart.
-func (r *CleanupReq) ToCtrlMsg() *colibri_mgmt.SegmentCleanup {
-	rawid := make([]byte, reservation.SegmentIDLen)
-	r.ID.Read(rawid)
-	return &colibri_mgmt.SegmentCleanup{
-		ID: &colibri_mgmt.SegmentReservationID{
-			ASID:   rawid[:6],
-			Suffix: rawid[6:],
-		},
-		Index: uint8(r.IndexNumber),
-	}
 }
diff --git a/go/cs/reservation/segment/response.go b/go/cs/reservation/segment/response.go
index b9f81a1e8..315aab15e 100644
--- a/go/cs/reservation/segment/response.go
+++ b/go/cs/reservation/segment/response.go
@@ -15,19 +15,86 @@
 package segment
 
 import (
+	"time"
+
 	base "github.com/scionproto/scion/go/cs/reservation"
 	"github.com/scionproto/scion/go/lib/colibri/reservation"
+	"github.com/scionproto/scion/go/lib/serrors"
+	"github.com/scionproto/scion/go/lib/spath"
 )
 
+// Response is the base struct for any type of COLIBRI segment response.
+type Response struct {
+	base.RequestMetadata                         // information about the request (forwarding path)
+	ID                   reservation.SegmentID   // the ID this request refers to
+	Index                reservation.IndexNumber // the index this request refers to
+	Accepted             bool                    // success or failure type of response
+	FailedHop            uint8                   // if accepted is false, the AS that failed it
+}
+
+// NewResponse contructs the segment Response type.
+func NewResponse(ts time.Time, id *reservation.SegmentID, idx reservation.IndexNumber,
+	path *spath.Path, accepted bool, failedHop uint8) (*Response, error) {
+
+	metadata, err := base.NewRequestMetadata(path)
+	if err != nil {
+		return nil, serrors.WrapStr("new segment request", err)
+	}
+	if id == nil {
+		return nil, serrors.New("new segment response with nil ID")
+	}
+	return &Response{
+		RequestMetadata: *metadata,
+		ID:              *id,
+		Index:           reservation.IndexNumber(idx),
+		Accepted:        accepted,
+		FailedHop:       failedHop,
+	}, nil
+}
+
 // ResponseSetupSuccess is the response to a success setup. It's sent on the reverse direction.
 type ResponseSetupSuccess struct {
-	base.RequestMetadata // information about the request (forwarding path)
-	Token                reservation.Token
+	Response
+	Token reservation.Token
 }
 
 // ResponseSetupFailure is the response to a failed setup. It's sent on the reverse direction.
 type ResponseSetupFailure struct {
-	base.RequestMetadata // information about the request (forwarding path)
-	FailedSetup          *SetupReq
-	FailedHop            uint8
+	Response
+	FailedSetup *SetupReq
+}
+
+// ResponseTeardownSuccess is sent by the last AS in the reverse path.
+type ResponseTeardownSuccess struct {
+	Response
+}
+
+// ResponseTeardownFailure is sent in the reverse path.
+type ResponseTeardownFailure struct {
+	Response
+	ErrorCode uint8
+}
+
+// ResponseIndexConfirmationSuccess is a successful index confirmation. The target state is
+// echoed in the response.
+type ResponseIndexConfirmationSuccess struct {
+	Response
+	State IndexState
+}
+
+// ResponseIndexConfirmationFailure is a failed index confirmation.
+type ResponseIndexConfirmationFailure struct {
+	Response
+	ErrorCode uint8
+}
+
+// ResponseCleanupSuccess is a response to a successful cleanup request.
+type ResponseCleanupSuccess struct {
+	Response
+}
+
+// ResponseCleanupFailure is a failed index cleanup.
+type ResponseCleanupFailure struct {
+	Response
+	ErrorCode uint8
 }
diff --git a/go/cs/reservation/translate/BUILD.bazel b/go/cs/reservation/translate/BUILD.bazel
new file mode 100644
index 000000000..a01b2b5de
--- /dev/null
+++ b/go/cs/reservation/translate/BUILD.bazel
@@ -0,0 +1,43 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
+
+go_library(
+    name = "go_default_library",
+    srcs = [
+        "fromctrl.go",
+        "toctrl.go",
+    ],
+    importpath = "github.com/scionproto/scion/go/cs/reservation/translate",
+    visibility = ["//visibility:public"],
+    deps = [
+        "//go/cs/reservation:go_default_library",
+        "//go/cs/reservation/e2e:go_default_library",
+        "//go/cs/reservation/segment:go_default_library",
+        "//go/lib/colibri/reservation:go_default_library",
+        "//go/lib/ctrl/colibri_mgmt:go_default_library",
+        "//go/lib/serrors:go_default_library",
+        "//go/lib/spath:go_default_library",
+        "//go/proto:go_default_library",
+    ],
+)
+
+go_test(
+    name = "go_default_test",
+    srcs = [
+        "common_test.go",
+        "fromctrl_test.go",
+        "toctrl_test.go",
+    ],
+    embed = [":go_default_library"],
+    deps = [
+        "//go/cs/reservation/e2e:go_default_library",
+        "//go/cs/reservation/segment:go_default_library",
+        "//go/lib/colibri/reservation:go_default_library",
+        "//go/lib/common:go_default_library",
+        "//go/lib/ctrl/colibri_mgmt:go_default_library",
+        "//go/lib/spath:go_default_library",
+        "//go/lib/util:go_default_library",
+        "//go/lib/xtest:go_default_library",
+        "//go/proto:go_default_library",
+        "@com_github_stretchr_testify//require:go_default_library",
+    ],
+)
diff --git a/go/cs/reservation/translate/fromctrl.go b/go/cs/reservation/translate/fromctrl.go
new file mode 100644
index 000000000..07d8cac60
--- /dev/null
+++ b/go/cs/reservation/translate/fromctrl.go
@@ -0,0 +1,508 @@
+// 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 translate
+
+import (
+	"encoding/hex"
+	"time"
+
+	base "github.com/scionproto/scion/go/cs/reservation"
+	"github.com/scionproto/scion/go/cs/reservation/e2e"
+	"github.com/scionproto/scion/go/cs/reservation/segment"
+	"github.com/scionproto/scion/go/lib/colibri/reservation"
+	"github.com/scionproto/scion/go/lib/ctrl/colibri_mgmt"
+	"github.com/scionproto/scion/go/lib/serrors"
+	"github.com/scionproto/scion/go/lib/spath"
+	"github.com/scionproto/scion/go/proto"
+)
+
+// NewMsgFromCtrl takes a colibri ctrl message and returns a new application type.
+// the spath.Path comes from the scion packet that encapsulates the ctrl payload.
+func NewMsgFromCtrl(ctrl *colibri_mgmt.ColibriRequestPayload, path *spath.Path) (
+	base.MessageWithPath, error) {
+
+	if ctrl == nil {
+		return nil, serrors.New("nil ctrl message", "type", "ColibriRequestPayload")
+	}
+	ts := reservation.Tick(ctrl.Timestamp).ToTime()
+	switch ctrl.Which {
+	case proto.ColibriRequestPayload_Which_request:
+		return newRequestFromCtrl(ctrl.Request, ts, path)
+	case proto.ColibriRequestPayload_Which_response:
+		return newResponseFromCtrl(ctrl.Response, ts, path)
+	default:
+		return nil, serrors.New("invalid ctrl message", "ctrl", ctrl.Which.String())
+	}
+}
+
+// NewIndexStateFromCtrl converts a proto reservation index state into its application type.
+func NewIndexStateFromCtrl(st proto.ReservationIndexState) (segment.IndexState, error) {
+	var state segment.IndexState
+	switch st {
+	case proto.ReservationIndexState_pending:
+		state = segment.IndexPending
+	case proto.ReservationIndexState_active:
+		state = segment.IndexActive
+	default:
+		return 0, serrors.New("unknown index_state in ctrl variable", "index_state", st)
+	}
+	return state, nil
+}
+
+// NewSegmentIDFromCtrl converts a segment id from ctrl to its application type.
+func NewSegmentIDFromCtrl(ctrl *colibri_mgmt.SegmentReservationID) (
+	*reservation.SegmentID, error) {
+
+	if ctrl == nil {
+		return nil, nil
+	}
+	id, err := reservation.SegmentIDFromRawBuffers(ctrl.ASID, ctrl.Suffix)
+	if err != nil {
+		return nil, serrors.WrapStr("converting segment id", err)
+	}
+	return id, nil
+}
+
+// NewE2EIDFromCtrl converts a segment id from ctrl to its application type.
+func NewE2EIDFromCtrl(ctrl *colibri_mgmt.E2EReservationID) (
+	*reservation.E2EID, error) {
+
+	if ctrl == nil {
+		return nil, nil
+	}
+	id, err := reservation.E2EIDFromRawBuffers(ctrl.ASID, ctrl.Suffix)
+	if err != nil {
+		return nil, serrors.WrapStr("converting e2e id", err)
+	}
+	return id, nil
+}
+
+func newRequestFromCtrl(ctrl *colibri_mgmt.Request, ts time.Time, path *spath.Path) (
+	base.MessageWithPath, error) {
+
+	if ctrl == nil {
+		return nil, serrors.New("nil ctrl message", "type", "Request")
+	}
+	switch ctrl.Which {
+	case proto.Request_Which_segmentSetup:
+		return newRequestSegmentSetup(ctrl.SegmentSetup, ts, path)
+	case proto.Request_Which_segmentRenewal:
+		return newRequestSegmentSetup(ctrl.SegmentRenewal, ts, path)
+	case proto.Request_Which_segmentTelesSetup:
+		return newRequestSegmentTelesSetup(ctrl.SegmentTelesSetup, ts, path)
+	case proto.Request_Which_segmentTelesRenewal:
+		return newRequestSegmentTelesSetup(ctrl.SegmentTelesRenewal, ts, path)
+	case proto.Request_Which_segmentTeardown:
+		return newRequestSegmentTeardown(ctrl.SegmentTeardown, ts, path)
+	case proto.Request_Which_segmentIndexConfirmation:
+		return newRequestSegmentIndexConfirmation(ctrl.SegmentIndexConfirmation, ts, path)
+	case proto.Request_Which_segmentCleanup:
+		return newRequestSegmentCleanup(ctrl.SegmentCleanup, ts, path)
+	case proto.Request_Which_e2eSetup:
+		return newRequestE2ESetup(ctrl.E2ESetup, ts, path)
+	case proto.Request_Which_e2eRenewal:
+		return newRequestE2ESetup(ctrl.E2ERenewal, ts, path)
+	case proto.Request_Which_e2eCleanup:
+		return newRequestE2ECleanup(ctrl.E2ECleanup, ts, path)
+	default:
+		return nil, serrors.New("invalid ctrl message", "ctrl", ctrl.Which.String())
+	}
+}
+
+func newResponseFromCtrl(ctrl *colibri_mgmt.Response, ts time.Time, path *spath.Path) (
+	base.MessageWithPath, error) {
+
+	if ctrl == nil {
+		return nil, serrors.New("nil ctrl message", "type", "Request")
+	}
+	switch ctrl.Which {
+	case proto.Response_Which_segmentSetup:
+		return newResponseSegmentSetup(ctrl.SegmentSetup, ctrl, ts, path)
+	case proto.Response_Which_segmentRenewal:
+		return newResponseSegmentSetup(ctrl.SegmentRenewal, ctrl, ts, path)
+	case proto.Response_Which_segmentTeardown:
+		return newResponseSegmentTeardown(ctrl.SegmentTeardown, ctrl, ts, path)
+	case proto.Response_Which_segmentIndexConfirmation:
+		return newResponseSegmentIndexConfirmation(ctrl.SegmentIndexConfirmation, ctrl, ts, path)
+	case proto.Response_Which_segmentCleanup:
+		return newResponseSegmentCleanup(ctrl.SegmentCleanup, ctrl, ts, path)
+	case proto.Response_Which_e2eSetup:
+		return newResponseE2ESetup(ctrl.E2ESetup, ctrl, ts, path)
+	case proto.Response_Which_e2eRenewal:
+		return newResponseE2ESetup(ctrl.E2ERenewal, ctrl, ts, path)
+	case proto.Response_Which_e2eCleanup:
+		return newResponseE2EClenaup(ctrl.E2ECleanup, ctrl, ts, path)
+	default:
+		return nil, serrors.New("invalid ctrl message", "ctrl", ctrl.Which.String())
+	}
+}
+
+// newRequestSegmentSetup constructs a SetupReq from its control message counterpart.
+// The timestamp comes from the wrapping ColibriRequestPayload,
+// and the spath from the wrapping SCION packet.
+func newRequestSegmentSetup(ctrl *colibri_mgmt.SegmentSetup, ts time.Time,
+	path *spath.Path) (*segment.SetupReq, error) {
+
+	id, err := NewSegmentIDFromCtrl(ctrl.Base.ID)
+	if err != nil {
+		return nil, serrors.WrapStr("cannot convert id", err)
+	}
+	r, err := segment.NewRequest(ts, id, reservation.IndexNumber(ctrl.Base.Index), path)
+	if err != nil {
+		return nil, serrors.WrapStr("cannot construct segment setup request", err)
+	}
+	inF, err := reservation.InfoFieldFromRaw(ctrl.InfoField)
+	if err != nil {
+		return nil, serrors.WrapStr("cannot construct info field from raw", err)
+	}
+	if inF == nil {
+		return nil, serrors.New("empty info field", "raw", hex.EncodeToString(ctrl.InfoField))
+	}
+	s := &segment.SetupReq{
+		Request:    *r,
+		InfoField:  *inF,
+		MinBW:      reservation.BWCls(ctrl.MinBW),
+		MaxBW:      reservation.BWCls(ctrl.MaxBW),
+		SplitCls:   reservation.SplitCls(ctrl.SplitCls),
+		AllocTrail: make(reservation.AllocationBeads, len(ctrl.AllocationTrail)),
+		PathProps: reservation.NewPathEndProps(ctrl.StartProps.Local, ctrl.StartProps.Transfer,
+			ctrl.EndProps.Local, ctrl.EndProps.Transfer),
+	}
+	for i, ab := range ctrl.AllocationTrail {
+		s.AllocTrail[i] = reservation.AllocationBead{
+			AllocBW: reservation.BWCls(ab.AllocBW),
+			MaxBW:   reservation.BWCls(ab.MaxBW),
+		}
+	}
+	return s, nil
+}
+
+// NewTelesRequestFromCtrlMsg constucts the app type from its control message counterpart.
+func newRequestSegmentTelesSetup(ctrl *colibri_mgmt.SegmentTelesSetup, ts time.Time,
+	path *spath.Path) (*segment.SetupTelesReq, error) {
+
+	if ctrl.BaseID == nil || ctrl.Setup == nil {
+		return nil, serrors.New("illegal ctrl telescopic setup received", "base_id", ctrl.BaseID,
+			"segment_setup", ctrl.Setup)
+	}
+	baseReq, err := newRequestSegmentSetup(ctrl.Setup, ts, path)
+	if err != nil {
+		return nil, serrors.WrapStr("failed to construct base request", err)
+	}
+	s := &segment.SetupTelesReq{
+		SetupReq: *baseReq,
+	}
+	id, err := reservation.SegmentIDFromRawBuffers(ctrl.BaseID.ASID, ctrl.BaseID.Suffix)
+	if err != nil {
+		return nil, err
+	}
+	s.BaseID = *id
+	return s, nil
+}
+
+func newRequestSegmentTeardown(ctrl *colibri_mgmt.SegmentTeardownReq, ts time.Time,
+	path *spath.Path) (*segment.TeardownReq, error) {
+
+	id, err := NewSegmentIDFromCtrl(ctrl.Base.ID)
+	if err != nil {
+		return nil, serrors.WrapStr("cannot convert id", err)
+	}
+	r, err := segment.NewRequest(ts, id, reservation.IndexNumber(ctrl.Base.Index), path)
+	if err != nil {
+		return nil, serrors.WrapStr("cannot construct segment teardown request", err)
+	}
+	return &segment.TeardownReq{
+		Request: *r,
+	}, nil
+}
+
+func newRequestSegmentIndexConfirmation(ctrl *colibri_mgmt.SegmentIndexConfirmation, ts time.Time,
+	path *spath.Path) (*segment.IndexConfirmationReq, error) {
+
+	id, err := NewSegmentIDFromCtrl(ctrl.Base.ID)
+	if err != nil {
+		return nil, serrors.WrapStr("cannot convert id", err)
+	}
+	r, err := segment.NewRequest(ts, id, reservation.IndexNumber(ctrl.Base.Index), path)
+	if err != nil {
+		return nil, serrors.WrapStr("cannot construct segment idx confirmation request", err)
+	}
+	st, err := NewIndexStateFromCtrl(ctrl.State)
+	if err != nil {
+		return nil, err
+	}
+	return &segment.IndexConfirmationReq{
+		Request: *r,
+		State:   st,
+	}, nil
+}
+
+func newRequestSegmentCleanup(ctrl *colibri_mgmt.SegmentCleanup, ts time.Time,
+	path *spath.Path) (*segment.CleanupReq, error) {
+
+	id, err := NewSegmentIDFromCtrl(ctrl.Base.ID)
+	if err != nil {
+		return nil, serrors.WrapStr("cannot convert id", err)
+	}
+	r, err := segment.NewRequest(ts, id, reservation.IndexNumber(ctrl.Base.Index), path)
+	if err != nil {
+		return nil, serrors.WrapStr("cannot construct segment cleanup request", err)
+	}
+	return &segment.CleanupReq{
+		Request: *r,
+	}, nil
+}
+
+func newRequestE2ESetup(ctrl *colibri_mgmt.E2ESetup, ts time.Time,
+	path *spath.Path) (base.MessageWithPath, error) {
+
+	id, err := NewE2EIDFromCtrl(ctrl.Base.ID)
+	if err != nil {
+		return nil, serrors.WrapStr("cannot convert id", err)
+	}
+	r, err := e2e.NewRequest(ts, id, reservation.IndexNumber(ctrl.Base.Index), path)
+	if err != nil {
+		return nil, serrors.WrapStr("cannot construct e2e setup request", err)
+	}
+	segmentIDs := make([]reservation.SegmentID, len(ctrl.SegmentRsvs))
+	for i := range ctrl.SegmentRsvs {
+		id, err := NewSegmentIDFromCtrl(&ctrl.SegmentRsvs[i])
+		if err != nil {
+			return nil, serrors.WrapStr("cannot translate segment id in e2e setup", err,
+				"asid", hex.EncodeToString(ctrl.SegmentRsvs[i].ASID),
+				"suffix", hex.EncodeToString(ctrl.SegmentRsvs[i].Suffix))
+		}
+		segmentIDs[i] = *id
+	}
+	allocTrail := make([]reservation.BWCls, len(ctrl.AllocationTrail))
+	for i := range ctrl.AllocationTrail {
+		allocTrail[i] = reservation.BWCls(ctrl.AllocationTrail[i])
+	}
+	setup := e2e.SetupReq{
+		Request:         *r,
+		SegmentRsvs:     segmentIDs,
+		RequestedBW:     reservation.BWCls(ctrl.RequestedBW),
+		AllocationTrail: allocTrail,
+	}
+	switch ctrl.Which {
+	case proto.E2ESetupReqData_Which_success:
+		tok, err := reservation.TokenFromRaw(ctrl.Success.Token)
+		if err != nil {
+			return nil, serrors.WrapStr("cannot construct e2e setup success request", err)
+		}
+		return &e2e.SetupReqSuccess{
+			SetupReq: setup,
+			Token:    *tok,
+		}, nil
+	case proto.E2ESetupReqData_Which_failure:
+		return &e2e.SetupReqFailure{
+			SetupReq:  setup,
+			ErrorCode: ctrl.Failure.ErrorCode,
+		}, nil
+	default:
+		return nil, serrors.New("invalid ctrl message", "ctrl", ctrl.Which.String())
+	}
+}
+
+func newRequestE2ECleanup(ctrl *colibri_mgmt.E2ECleanup, ts time.Time,
+	path *spath.Path) (*e2e.CleanupReq, error) {
+
+	id, err := NewE2EIDFromCtrl(ctrl.Base.ID)
+	if err != nil {
+		return nil, serrors.WrapStr("cannot convert id", err)
+	}
+	r, err := e2e.NewRequest(ts, id, reservation.IndexNumber(ctrl.Base.Index), path)
+	if err != nil {
+		return nil, serrors.WrapStr("cannot construct e2e cleanup request", err)
+	}
+	return &e2e.CleanupReq{
+		Request: *r,
+	}, nil
+}
+
+// the failedHop parameter won't be used if the response is successful.
+func newResponseSegmentSetup(ctrl *colibri_mgmt.SegmentSetupRes, resp *colibri_mgmt.Response,
+	ts time.Time, path *spath.Path) (base.MessageWithPath, error) {
+
+	id, err := NewSegmentIDFromCtrl(ctrl.Base.ID)
+	if err != nil {
+		return nil, serrors.WrapStr("cannot convert id", err)
+	}
+	r, err := segment.NewResponse(ts, id, reservation.IndexNumber(ctrl.Base.Index), path,
+		resp.Accepted, resp.FailedHop)
+	if err != nil {
+		return nil, serrors.WrapStr("cannot construct segment setup response", err)
+	}
+	switch ctrl.Which {
+	case proto.SegmentSetupResData_Which_token:
+		tok, err := reservation.TokenFromRaw(ctrl.Token)
+		if err != nil {
+			return nil, serrors.WrapStr("cannot parse token", err)
+		}
+		return &segment.ResponseSetupSuccess{
+			Response: *r,
+			Token:    *tok,
+		}, nil
+	case proto.SegmentSetupResData_Which_failure:
+		failedSetup, err := newRequestSegmentSetup(ctrl.Failure, ts, path)
+		if err != nil {
+			return nil, serrors.WrapStr("cannot parse failed setup", err)
+		}
+		return &segment.ResponseSetupFailure{
+			Response:    *r,
+			FailedSetup: failedSetup,
+		}, nil
+	default:
+		return nil, serrors.New("invalid ctrl message", "ctrl", ctrl.Which.String())
+	}
+}
+
+func newResponseSegmentTeardown(ctrl *colibri_mgmt.SegmentTeardownRes, resp *colibri_mgmt.Response,
+	ts time.Time, path *spath.Path) (base.MessageWithPath, error) {
+
+	id, err := NewSegmentIDFromCtrl(ctrl.Base.ID)
+	if err != nil {
+		return nil, serrors.WrapStr("cannot convert id", err)
+	}
+	r, err := segment.NewResponse(ts, id, reservation.IndexNumber(ctrl.Base.Index), path,
+		resp.Accepted, resp.FailedHop)
+	if err != nil {
+		return nil, serrors.WrapStr("cannot construct segment setup response", err)
+	}
+	if resp.Accepted {
+		return &segment.ResponseTeardownSuccess{
+			Response: *r,
+		}, nil
+	} else {
+		return &segment.ResponseTeardownFailure{
+			Response:  *r,
+			ErrorCode: ctrl.ErrorCode,
+		}, nil
+	}
+}
+
+func newResponseSegmentIndexConfirmation(ctrl *colibri_mgmt.SegmentIndexConfirmationRes,
+	resp *colibri_mgmt.Response, ts time.Time, path *spath.Path) (base.MessageWithPath, error) {
+
+	id, err := NewSegmentIDFromCtrl(ctrl.Base.ID)
+	if err != nil {
+		return nil, serrors.WrapStr("cannot convert id", err)
+	}
+	r, err := segment.NewResponse(ts, id, reservation.IndexNumber(ctrl.Base.Index), path,
+		resp.Accepted, resp.FailedHop)
+	if err != nil {
+		return nil, serrors.WrapStr("cannot construct segment setup response", err)
+	}
+	if resp.Accepted {
+		return &segment.ResponseIndexConfirmationSuccess{
+			Response: *r,
+		}, nil
+	} else {
+		return &segment.ResponseIndexConfirmationFailure{
+			Response:  *r,
+			ErrorCode: ctrl.ErrorCode,
+		}, nil
+	}
+}
+
+func newResponseSegmentCleanup(ctrl *colibri_mgmt.SegmentCleanupRes, resp *colibri_mgmt.Response,
+	ts time.Time, path *spath.Path) (base.MessageWithPath, error) {
+
+	id, err := NewSegmentIDFromCtrl(ctrl.Base.ID)
+	if err != nil {
+		return nil, serrors.WrapStr("cannot convert id", err)
+	}
+	r, err := segment.NewResponse(ts, id, reservation.IndexNumber(ctrl.Base.Index), path,
+		resp.Accepted, resp.FailedHop)
+	if err != nil {
+		return nil, serrors.WrapStr("cannot construct segment setup response", err)
+	}
+	if resp.Accepted {
+		return &segment.ResponseCleanupSuccess{
+			Response: *r,
+		}, nil
+	} else {
+		return &segment.ResponseCleanupFailure{
+			Response:  *r,
+			ErrorCode: ctrl.ErrorCode,
+		}, nil
+	}
+}
+
+func newResponseE2ESetup(ctrl *colibri_mgmt.E2ESetupRes, resp *colibri_mgmt.Response,
+	ts time.Time, path *spath.Path) (base.MessageWithPath, error) {
+
+	id, err := NewE2EIDFromCtrl(ctrl.Base.ID)
+	if err != nil {
+		return nil, serrors.WrapStr("cannot convert id", err)
+	}
+	r, err := e2e.NewResponse(ts, id, reservation.IndexNumber(ctrl.Base.Index), path,
+		resp.Accepted, resp.FailedHop)
+	if err != nil {
+		return nil, serrors.WrapStr("cannot construct segment setup response", err)
+	}
+	switch ctrl.Which {
+	case proto.E2ESetupResData_Which_success:
+		tok, err := reservation.TokenFromRaw(ctrl.Success.Token)
+		if err != nil {
+			return nil, serrors.WrapStr("cannot parse token", err)
+		}
+		return &e2e.ResponseSetupSuccess{
+			Response: *r,
+			Token:    *tok,
+		}, nil
+	case proto.E2ESetupResData_Which_failure:
+		inf, err := reservation.InfoFieldFromRaw(ctrl.Failure.InfoField)
+		if err != nil {
+			return nil, serrors.WrapStr("cannot parse info field", err)
+		}
+		maxBWs := make([]reservation.BWCls, len(ctrl.Failure.AllocationTrail))
+		for i := range ctrl.Failure.AllocationTrail {
+			maxBWs[i] = reservation.BWCls(ctrl.Failure.AllocationTrail[i])
+		}
+		return &e2e.ResponseSetupFailure{
+			Response:  *r,
+			ErrorCode: ctrl.Failure.ErrorCode,
+			InfoField: *inf,
+			MaxBWs:    maxBWs,
+		}, nil
+	default:
+		return nil, serrors.New("invalid ctrl message", "ctrl", ctrl.Which.String())
+	}
+}
+
+func newResponseE2EClenaup(ctrl *colibri_mgmt.E2ECleanupRes, resp *colibri_mgmt.Response,
+	ts time.Time, path *spath.Path) (base.MessageWithPath, error) {
+
+	id, err := NewE2EIDFromCtrl(ctrl.Base.ID)
+	if err != nil {
+		return nil, serrors.WrapStr("cannot convert id", err)
+	}
+	r, err := e2e.NewResponse(ts, id, reservation.IndexNumber(ctrl.Base.Index), path,
+		resp.Accepted, resp.FailedHop)
+	if err != nil {
+		return nil, serrors.WrapStr("cannot construct segment setup response", err)
+	}
+	if resp.Accepted {
+		return &e2e.ResponseCleanupSuccess{
+			Response: *r,
+		}, nil
+	} else {
+		return &e2e.ResponseCleanupFailure{
+			Response:  *r,
+			ErrorCode: ctrl.ErrorCode,
+		}, nil
+	}
+}
diff --git a/go/cs/reservation/translate/toctrl.go b/go/cs/reservation/translate/toctrl.go
new file mode 100644
index 000000000..ad8d130f8
--- /dev/null
+++ b/go/cs/reservation/translate/toctrl.go
@@ -0,0 +1,581 @@
+// 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 translate
+
+import (
+	"fmt"
+
+	base "github.com/scionproto/scion/go/cs/reservation"
+	"github.com/scionproto/scion/go/cs/reservation/e2e"
+	"github.com/scionproto/scion/go/cs/reservation/segment"
+	"github.com/scionproto/scion/go/lib/colibri/reservation"
+	"github.com/scionproto/scion/go/lib/ctrl/colibri_mgmt"
+	"github.com/scionproto/scion/go/lib/serrors"
+	"github.com/scionproto/scion/go/proto"
+)
+
+// NewCtrlFromMsg translates the application type "msg" into a capnp one.
+func NewCtrlFromMsg(msg base.MessageWithPath, renewal bool) (
+	*colibri_mgmt.ColibriRequestPayload, error) {
+
+	ctrl := &colibri_mgmt.ColibriRequestPayload{}
+	var err error
+	switch r := msg.(type) {
+	// requests (those that move forward in the reservation path):
+	case *segment.SetupReq:
+		if !renewal {
+			err = setSegmentSetup(r, ctrl)
+		} else {
+			err = setSegmentRenewal(r, ctrl)
+		}
+	case *segment.SetupTelesReq:
+		if !renewal {
+			err = setSegmentTelesSetup(r, ctrl)
+		} else {
+			err = setSegmentTelesRenewal(r, ctrl)
+		}
+	case *segment.TeardownReq:
+		err = setSegmentTeardown(r, ctrl)
+	case *segment.IndexConfirmationReq:
+		err = setSegmentIndexConfirmation(r, ctrl)
+	case *segment.CleanupReq:
+		err = setSegmentCleanup(r, ctrl)
+	case *e2e.SetupReqSuccess:
+		if !renewal {
+			err = setE2ESetupReqSuccess(r, ctrl)
+		} else {
+			err = setE2ERenewalReqSuccess(r, ctrl)
+		}
+	case *e2e.SetupReqFailure:
+		if !renewal {
+			err = setE2ESetupReqFailure(r, ctrl)
+		} else {
+			err = setE2ERenewalReqFailure(r, ctrl)
+		}
+	case *e2e.CleanupReq:
+		err = setE2ECleanup(r, ctrl)
+
+	// responses (that move backwards in the reservation path):
+	case *segment.ResponseSetupSuccess:
+		if !renewal {
+			err = setSegmentSetupSuccessResponse(r, ctrl)
+		} else {
+			err = setSegmentRenewalSuccessResponse(r, ctrl)
+		}
+	case *segment.ResponseSetupFailure:
+		if !renewal {
+			err = setSegmentSetupFailureResponse(r, ctrl)
+		} else {
+			err = setSegmentRenewalFailureResponse(r, ctrl)
+		}
+	case *segment.ResponseTeardownSuccess:
+		err = setSegmentTeardownSuccessResponse(r, ctrl)
+	case *segment.ResponseTeardownFailure:
+		err = setSegmentTeardownFailureResponse(r, ctrl)
+	case *segment.ResponseIndexConfirmationSuccess:
+		err = setSegmentIndexConfirmationSuccessResponse(r, ctrl)
+	case *segment.ResponseIndexConfirmationFailure:
+		err = setSegmentIndexConfirmationFailureResponse(r, ctrl)
+	case *segment.ResponseCleanupSuccess:
+		err = setSegmentCleanupSuccessResponse(r, ctrl)
+	case *segment.ResponseCleanupFailure:
+		err = setSegmentCleanupFailureResponse(r, ctrl)
+	case *e2e.ResponseSetupSuccess:
+		if !renewal {
+			err = setE2ESetupSuccessResponse(r, ctrl)
+		} else {
+			err = setE2ERenewalSuccessResponse(r, ctrl)
+		}
+	case *e2e.ResponseSetupFailure:
+		if !renewal {
+			err = setE2ESetupFailureResponse(r, ctrl)
+		} else {
+			err = setE2ERenewalFailureResponse(r, ctrl)
+		}
+	case *e2e.ResponseCleanupSuccess:
+		err = setE2ECleanupSuccessResponse(r, ctrl)
+	case *e2e.ResponseCleanupFailure:
+		err = setE2ECleanupFailureResponse(r, ctrl)
+	default:
+		err = serrors.New("unknown application type", "type", fmt.Sprintf("%T", msg))
+	}
+	return ctrl, err
+}
+
+func NewCtrlSegmentReservationID(ID *reservation.SegmentID) *colibri_mgmt.SegmentReservationID {
+	buf := ID.ToRaw()
+	return &colibri_mgmt.SegmentReservationID{
+		ASID:   buf[:6],
+		Suffix: buf[6:],
+	}
+}
+
+func NewCtrlE2EReservationID(ID *reservation.E2EID) *colibri_mgmt.E2EReservationID {
+	buf := ID.ToRaw()
+	return &colibri_mgmt.E2EReservationID{
+		ASID:   buf[:6],
+		Suffix: buf[6:],
+	}
+}
+
+func newSegmentIDs(ids []reservation.SegmentID) []colibri_mgmt.SegmentReservationID {
+	ctrlIDs := make([]colibri_mgmt.SegmentReservationID, len(ids))
+	for i := range ids {
+		ctrlIDs[i] = *NewCtrlSegmentReservationID(&ids[i])
+	}
+	return ctrlIDs
+}
+
+func newSegmentBase(msg *segment.Request) *colibri_mgmt.SegmentBase {
+	return &colibri_mgmt.SegmentBase{
+		ID:    NewCtrlSegmentReservationID(&msg.ID),
+		Index: uint8(msg.Index),
+	}
+}
+
+func newSegmentBaseFromResponse(msg *segment.Response) *colibri_mgmt.SegmentBase {
+	return &colibri_mgmt.SegmentBase{
+		ID:    NewCtrlSegmentReservationID(&msg.ID),
+		Index: uint8(msg.Index),
+	}
+}
+
+func newE2EBase(msg *e2e.Request) *colibri_mgmt.E2EBase {
+	return &colibri_mgmt.E2EBase{
+		ID:    NewCtrlE2EReservationID(&msg.ID),
+		Index: uint8(msg.Index),
+	}
+}
+
+func newE2EBaseFromResponse(msg *e2e.Response) *colibri_mgmt.E2EBase {
+	return &colibri_mgmt.E2EBase{
+		ID:    NewCtrlE2EReservationID(&msg.ID),
+		Index: uint8(msg.Index),
+	}
+}
+
+func newIndexState(s segment.IndexState) (proto.ReservationIndexState, error) {
+	switch s {
+	case segment.IndexPending:
+		return proto.ReservationIndexState_pending, nil
+	case segment.IndexActive:
+		return proto.ReservationIndexState_active, nil
+	default:
+		return 0, serrors.New("cannot convert index state to control message", "state", s)
+	}
+}
+
+func newSegmentSetup(msg *segment.SetupReq) *colibri_mgmt.SegmentSetup {
+	c := &colibri_mgmt.SegmentSetup{
+		Base:     newSegmentBase(&msg.Request),
+		MinBW:    uint8(msg.MinBW),
+		MaxBW:    uint8(msg.MaxBW),
+		SplitCls: uint8(msg.SplitCls),
+		StartProps: colibri_mgmt.PathEndProps{
+			Local:    (msg.PathProps & reservation.StartLocal) != 0,
+			Transfer: (msg.PathProps & reservation.StartTransfer) != 0,
+		},
+		EndProps: colibri_mgmt.PathEndProps{
+			Local:    (msg.PathProps & reservation.EndLocal) != 0,
+			Transfer: (msg.PathProps & reservation.EndTransfer) != 0,
+		},
+		InfoField:       msg.InfoField.ToRaw(),
+		AllocationTrail: make([]*colibri_mgmt.AllocationBead, len(msg.AllocTrail)),
+	}
+	for i, bead := range msg.AllocTrail {
+		c.AllocationTrail[i] = &colibri_mgmt.AllocationBead{
+			AllocBW: uint8(bead.AllocBW),
+			MaxBW:   uint8(bead.MaxBW),
+		}
+	}
+	return c
+}
+
+// newE2ESetup returns the e2e setup ctrl message common to both success and failure.
+func newE2ESetup(msg *e2e.SetupReq) *colibri_mgmt.E2ESetup {
+	allocTrail := make([]uint8, len(msg.AllocationTrail))
+	for i := range msg.AllocationTrail {
+		allocTrail[i] = uint8(msg.AllocationTrail[i])
+	}
+	return &colibri_mgmt.E2ESetup{
+		Base:            newE2EBase(&msg.Request),
+		SegmentRsvs:     newSegmentIDs(msg.SegmentRsvs),
+		RequestedBW:     uint8(msg.RequestedBW),
+		AllocationTrail: allocTrail,
+	}
+}
+
+func thisIsARequest(ctrl *colibri_mgmt.ColibriRequestPayload) {
+	ctrl.Request = &colibri_mgmt.Request{}
+	ctrl.Which = proto.ColibriRequestPayload_Which_request
+}
+
+// the response is accepted iff failedHop==0
+func thisIsAResponse(ctrl *colibri_mgmt.ColibriRequestPayload, failedHop uint8) {
+	ctrl.Response = &colibri_mgmt.Response{
+		Accepted:  failedHop == 0,
+		FailedHop: failedHop,
+	}
+	ctrl.Which = proto.ColibriRequestPayload_Which_response
+}
+
+func setSegmentSetup(msg *segment.SetupReq, ctrl *colibri_mgmt.ColibriRequestPayload) error {
+	thisIsARequest(ctrl)
+	ctrl.Request.SegmentSetup = newSegmentSetup(msg)
+	ctrl.Request.Which = proto.Request_Which_segmentSetup
+	return nil
+}
+
+func setSegmentRenewal(msg *segment.SetupReq, ctrl *colibri_mgmt.ColibriRequestPayload) error {
+	thisIsARequest(ctrl)
+	ctrl.Request.SegmentRenewal = newSegmentSetup(msg)
+	ctrl.Request.Which = proto.Request_Which_segmentRenewal
+	return nil
+}
+
+func setSegmentTelesSetup(msg *segment.SetupTelesReq,
+	ctrl *colibri_mgmt.ColibriRequestPayload) error {
+
+	thisIsARequest(ctrl)
+	ctrl.Request.SegmentTelesSetup = &colibri_mgmt.SegmentTelesSetup{
+		Setup:  newSegmentSetup(&msg.SetupReq),
+		BaseID: NewCtrlSegmentReservationID(&msg.BaseID),
+	}
+	ctrl.Request.Which = proto.Request_Which_segmentTelesSetup
+	return nil
+}
+
+func setSegmentTelesRenewal(msg *segment.SetupTelesReq,
+	ctrl *colibri_mgmt.ColibriRequestPayload) error {
+
+	thisIsARequest(ctrl)
+	ctrl.Request.SegmentTelesRenewal = &colibri_mgmt.SegmentTelesSetup{
+		Setup:  newSegmentSetup(&msg.SetupReq),
+		BaseID: NewCtrlSegmentReservationID(&msg.BaseID),
+	}
+	ctrl.Request.Which = proto.Request_Which_segmentTelesRenewal
+	return nil
+}
+
+func setSegmentTeardown(msg *segment.TeardownReq, ctrl *colibri_mgmt.ColibriRequestPayload) error {
+	thisIsARequest(ctrl)
+	ctrl.Request.SegmentTeardown = &colibri_mgmt.SegmentTeardownReq{
+		Base: newSegmentBase(&msg.Request),
+	}
+	ctrl.Request.Which = proto.Request_Which_segmentTeardown
+	return nil
+}
+
+func setSegmentIndexConfirmation(msg *segment.IndexConfirmationReq,
+	ctrl *colibri_mgmt.ColibriRequestPayload) error {
+
+	thisIsARequest(ctrl)
+	st, err := newIndexState(msg.State)
+	if err != nil {
+		return err
+	}
+	ctrl.Request.SegmentIndexConfirmation = &colibri_mgmt.SegmentIndexConfirmation{
+		Base:  newSegmentBase(&msg.Request),
+		State: st,
+	}
+	ctrl.Request.Which = proto.Request_Which_segmentIndexConfirmation
+	return nil
+}
+
+func setSegmentCleanup(msg *segment.CleanupReq, ctrl *colibri_mgmt.ColibriRequestPayload) error {
+	thisIsARequest(ctrl)
+	ctrl.Request.SegmentCleanup = &colibri_mgmt.SegmentCleanup{
+		Base: newSegmentBase(&msg.Request),
+	}
+	ctrl.Request.Which = proto.Request_Which_segmentCleanup
+	return nil
+}
+
+func setE2ESetupReqSuccess(msg *e2e.SetupReqSuccess,
+	ctrl *colibri_mgmt.ColibriRequestPayload) error {
+
+	thisIsARequest(ctrl)
+	ctrl.Request.Which = proto.Request_Which_e2eSetup
+	ctrl.Request.E2ESetup = newE2ESetup(&msg.SetupReq)
+	ctrl.Request.E2ESetup.Which = proto.E2ESetupReqData_Which_success
+	ctrl.Request.E2ESetup.Success = &colibri_mgmt.E2ESetupReqSuccess{
+		Token: msg.Token.ToRaw(),
+	}
+	return nil
+}
+
+func setE2ERenewalReqSuccess(msg *e2e.SetupReqSuccess,
+	ctrl *colibri_mgmt.ColibriRequestPayload) error {
+
+	thisIsARequest(ctrl)
+	ctrl.Request.Which = proto.Request_Which_e2eRenewal
+	ctrl.Request.E2ERenewal = newE2ESetup(&msg.SetupReq)
+	ctrl.Request.E2ERenewal.Which = proto.E2ESetupReqData_Which_success
+	ctrl.Request.E2ERenewal.Success = &colibri_mgmt.E2ESetupReqSuccess{
+		Token: msg.Token.ToRaw(),
+	}
+	return nil
+}
+
+func setE2ESetupReqFailure(msg *e2e.SetupReqFailure,
+	ctrl *colibri_mgmt.ColibriRequestPayload) error {
+
+	thisIsARequest(ctrl)
+	ctrl.Request.Which = proto.Request_Which_e2eSetup
+	ctrl.Request.E2ESetup = newE2ESetup(&msg.SetupReq)
+	ctrl.Request.E2ESetup.Which = proto.E2ESetupReqData_Which_failure
+	ctrl.Request.E2ESetup.Failure = &colibri_mgmt.E2ESetupReqFailure{
+		ErrorCode: msg.ErrorCode,
+	}
+
+	return nil
+}
+
+func setE2ERenewalReqFailure(msg *e2e.SetupReqFailure,
+	ctrl *colibri_mgmt.ColibriRequestPayload) error {
+
+	thisIsARequest(ctrl)
+	ctrl.Request.Which = proto.Request_Which_e2eRenewal
+	ctrl.Request.E2ERenewal = newE2ESetup(&msg.SetupReq)
+	ctrl.Request.E2ERenewal.Which = proto.E2ESetupReqData_Which_failure
+	ctrl.Request.E2ERenewal.Failure = &colibri_mgmt.E2ESetupReqFailure{
+		ErrorCode: msg.ErrorCode,
+	}
+	return nil
+}
+
+func setE2ECleanup(msg *e2e.CleanupReq, ctrl *colibri_mgmt.ColibriRequestPayload) error {
+	thisIsARequest(ctrl)
+	ctrl.Request.E2ECleanup = &colibri_mgmt.E2ECleanup{
+		Base: newE2EBase(&msg.Request),
+	}
+	ctrl.Request.Which = proto.Request_Which_e2eCleanup
+	return nil
+}
+
+func setSegmentSetupSuccessResponse(msg *segment.ResponseSetupSuccess,
+	ctrl *colibri_mgmt.ColibriRequestPayload) error {
+
+	thisIsAResponse(ctrl, 0)
+	ctrl.Response.SegmentSetup = &colibri_mgmt.SegmentSetupRes{
+		Base:  newSegmentBaseFromResponse(&msg.Response),
+		Which: proto.SegmentSetupResData_Which_token,
+		Token: msg.Token.ToRaw(),
+	}
+	ctrl.Response.Which = proto.Response_Which_segmentSetup
+	return nil
+}
+
+func setSegmentSetupFailureResponse(msg *segment.ResponseSetupFailure,
+	ctrl *colibri_mgmt.ColibriRequestPayload) error {
+
+	thisIsAResponse(ctrl, msg.FailedHop)
+	ctrl.Response.SegmentSetup = &colibri_mgmt.SegmentSetupRes{
+		Base:    newSegmentBaseFromResponse(&msg.Response),
+		Which:   proto.SegmentSetupResData_Which_failure,
+		Failure: newSegmentSetup(msg.FailedSetup),
+	}
+	ctrl.Response.Which = proto.Response_Which_segmentSetup
+	return nil
+}
+
+func setSegmentRenewalSuccessResponse(msg *segment.ResponseSetupSuccess,
+	ctrl *colibri_mgmt.ColibriRequestPayload) error {
+
+	thisIsAResponse(ctrl, 0)
+	ctrl.Response.SegmentRenewal = &colibri_mgmt.SegmentSetupRes{
+		Base:  newSegmentBaseFromResponse(&msg.Response),
+		Which: proto.SegmentSetupResData_Which_token,
+		Token: msg.Token.ToRaw(),
+	}
+	ctrl.Response.Which = proto.Response_Which_segmentRenewal
+	return nil
+}
+
+func setSegmentRenewalFailureResponse(msg *segment.ResponseSetupFailure,
+	ctrl *colibri_mgmt.ColibriRequestPayload) error {
+
+	thisIsAResponse(ctrl, msg.FailedHop)
+	ctrl.Response.SegmentRenewal = &colibri_mgmt.SegmentSetupRes{
+		Base:    newSegmentBaseFromResponse(&msg.Response),
+		Which:   proto.SegmentSetupResData_Which_failure,
+		Failure: newSegmentSetup(msg.FailedSetup),
+	}
+	ctrl.Response.Which = proto.Response_Which_segmentRenewal
+	return nil
+}
+func setSegmentTeardownSuccessResponse(msg *segment.ResponseTeardownSuccess,
+	ctrl *colibri_mgmt.ColibriRequestPayload) error {
+
+	thisIsAResponse(ctrl, 0)
+	ctrl.Response.SegmentTeardown = &colibri_mgmt.SegmentTeardownRes{
+		Base: newSegmentBaseFromResponse(&msg.Response),
+	}
+	ctrl.Response.Which = proto.Response_Which_segmentTeardown
+	return nil
+}
+
+func setSegmentTeardownFailureResponse(msg *segment.ResponseTeardownFailure,
+	ctrl *colibri_mgmt.ColibriRequestPayload) error {
+
+	thisIsAResponse(ctrl, msg.FailedHop)
+	ctrl.Response.SegmentTeardown = &colibri_mgmt.SegmentTeardownRes{
+		Base:      newSegmentBaseFromResponse(&msg.Response),
+		ErrorCode: msg.ErrorCode,
+	}
+	ctrl.Response.Which = proto.Response_Which_segmentTeardown
+	return nil
+}
+
+func setSegmentIndexConfirmationSuccessResponse(msg *segment.ResponseIndexConfirmationSuccess,
+	ctrl *colibri_mgmt.ColibriRequestPayload) error {
+
+	thisIsAResponse(ctrl, 0)
+	ctrl.Response.SegmentIndexConfirmation = &colibri_mgmt.SegmentIndexConfirmationRes{
+		Base: newSegmentBaseFromResponse(&msg.Response),
+	}
+	ctrl.Response.Which = proto.Response_Which_segmentIndexConfirmation
+	return nil
+}
+
+func setSegmentIndexConfirmationFailureResponse(msg *segment.ResponseIndexConfirmationFailure,
+	ctrl *colibri_mgmt.ColibriRequestPayload) error {
+
+	thisIsAResponse(ctrl, msg.FailedHop)
+	ctrl.Response.SegmentIndexConfirmation = &colibri_mgmt.SegmentIndexConfirmationRes{
+		Base:      newSegmentBaseFromResponse(&msg.Response),
+		ErrorCode: msg.ErrorCode,
+	}
+	ctrl.Response.Which = proto.Response_Which_segmentIndexConfirmation
+	return nil
+}
+
+func setSegmentCleanupSuccessResponse(msg *segment.ResponseCleanupSuccess,
+	ctrl *colibri_mgmt.ColibriRequestPayload) error {
+
+	thisIsAResponse(ctrl, 0)
+	ctrl.Response.SegmentCleanup = &colibri_mgmt.SegmentCleanupRes{
+		Base: newSegmentBaseFromResponse(&msg.Response),
+	}
+	ctrl.Response.Which = proto.Response_Which_segmentCleanup
+	return nil
+}
+
+func setSegmentCleanupFailureResponse(msg *segment.ResponseCleanupFailure,
+	ctrl *colibri_mgmt.ColibriRequestPayload) error {
+
+	thisIsAResponse(ctrl, msg.FailedHop)
+	ctrl.Response.SegmentCleanup = &colibri_mgmt.SegmentCleanupRes{
+		Base:      newSegmentBaseFromResponse(&msg.Response),
+		ErrorCode: msg.ErrorCode,
+	}
+	ctrl.Response.Which = proto.Response_Which_segmentCleanup
+	return nil
+}
+
+func setE2ESetupSuccessResponse(msg *e2e.ResponseSetupSuccess,
+	ctrl *colibri_mgmt.ColibriRequestPayload) error {
+
+	thisIsAResponse(ctrl, 0)
+	ctrl.Response.E2ESetup = &colibri_mgmt.E2ESetupRes{
+		Base:  newE2EBaseFromResponse(&msg.Response),
+		Which: proto.E2ESetupResData_Which_success,
+		Success: &colibri_mgmt.E2ESetupSuccess{
+			Token: msg.Token.ToRaw(),
+		},
+	}
+	ctrl.Response.Which = proto.Response_Which_e2eSetup
+	return nil
+}
+
+func setE2ERenewalSuccessResponse(msg *e2e.ResponseSetupSuccess,
+	ctrl *colibri_mgmt.ColibriRequestPayload) error {
+
+	thisIsAResponse(ctrl, 0)
+	ctrl.Response.E2ERenewal = &colibri_mgmt.E2ESetupRes{
+		Base:  newE2EBaseFromResponse(&msg.Response),
+		Which: proto.E2ESetupResData_Which_success,
+		Success: &colibri_mgmt.E2ESetupSuccess{
+			Token: msg.Token.ToRaw(),
+		},
+	}
+	ctrl.Response.Which = proto.Response_Which_e2eRenewal
+	return nil
+}
+
+func setE2ESetupFailureResponse(msg *e2e.ResponseSetupFailure,
+	ctrl *colibri_mgmt.ColibriRequestPayload) error {
+
+	maxBWs := make([]uint8, len(msg.MaxBWs))
+	for i := range msg.MaxBWs {
+		maxBWs[i] = uint8(msg.MaxBWs[i])
+	}
+	thisIsAResponse(ctrl, msg.FailedHop)
+	ctrl.Response.E2ESetup = &colibri_mgmt.E2ESetupRes{
+		Base:  newE2EBaseFromResponse(&msg.Response),
+		Which: proto.E2ESetupResData_Which_failure,
+		Failure: &colibri_mgmt.E2ESetupFailure{
+			ErrorCode:       msg.ErrorCode,
+			InfoField:       msg.InfoField.ToRaw(),
+			AllocationTrail: maxBWs,
+		},
+	}
+	ctrl.Response.Which = proto.Response_Which_e2eSetup
+	return nil
+}
+
+func setE2ERenewalFailureResponse(msg *e2e.ResponseSetupFailure,
+	ctrl *colibri_mgmt.ColibriRequestPayload) error {
+
+	maxBWs := make([]uint8, len(msg.MaxBWs))
+	for i := range msg.MaxBWs {
+		maxBWs[i] = uint8(msg.MaxBWs[i])
+	}
+	thisIsAResponse(ctrl, msg.FailedHop)
+	ctrl.Response.E2ERenewal = &colibri_mgmt.E2ESetupRes{
+		Base:  newE2EBaseFromResponse(&msg.Response),
+		Which: proto.E2ESetupResData_Which_failure,
+		Failure: &colibri_mgmt.E2ESetupFailure{
+			ErrorCode:       msg.ErrorCode,
+			InfoField:       msg.InfoField.ToRaw(),
+			AllocationTrail: maxBWs,
+		},
+	}
+	ctrl.Response.Which = proto.Response_Which_e2eRenewal
+	return nil
+}
+
+func setE2ECleanupSuccessResponse(msg *e2e.ResponseCleanupSuccess,
+	ctrl *colibri_mgmt.ColibriRequestPayload) error {
+
+	thisIsAResponse(ctrl, 0)
+	ctrl.Response.E2ECleanup = &colibri_mgmt.E2ECleanupRes{
+		Base: newE2EBaseFromResponse(&msg.Response),
+	}
+	ctrl.Response.Which = proto.Response_Which_e2eCleanup
+	return nil
+}
+
+func setE2ECleanupFailureResponse(msg *e2e.ResponseCleanupFailure,
+	ctrl *colibri_mgmt.ColibriRequestPayload) error {
+
+	thisIsAResponse(ctrl, msg.FailedHop)
+	ctrl.Response.E2ECleanup = &colibri_mgmt.E2ECleanupRes{
+		Base:      newE2EBaseFromResponse(&msg.Response),
+		ErrorCode: msg.ErrorCode,
+	}
+	ctrl.Response.Which = proto.Response_Which_e2eCleanup
+	return nil
+}
diff --git a/go/cs/reservationstore/store.go b/go/cs/reservationstore/store.go
index 8a856b915..9ddb53413 100644
--- a/go/cs/reservationstore/store.go
+++ b/go/cs/reservationstore/store.go
@@ -56,18 +56,18 @@ func (s *Store) AdmitSegmentReservation(ctx context.Context, req *segment.SetupR
 		return nil, serrors.WrapStr("while admitting a reservation, cannot reverse path", err,
 			"id", req.ID)
 	}
-	revMetadata, err := base.NewRequestMetadata(revPath)
-	if err != nil {
-		return nil, serrors.WrapStr("cannot construct metadata for reservation packet", err)
-	}
 	if req.IndexOfCurrentHop() != len(req.AllocTrail) {
 		return nil, serrors.New("inconsistent number of hops",
 			"len_alloctrail", len(req.AllocTrail), "hf_count", req.IndexOfCurrentHop())
 	}
+	response, err := segment.NewResponse(time.Now(), &req.ID, req.Index, revPath,
+		false, uint8(len(req.AllocTrail)))
+	if err != nil {
+		return nil, serrors.WrapStr("cannot construct metadata for reservation packet", err)
+	}
 	failedResponse := &segment.ResponseSetupFailure{
-		RequestMetadata: *revMetadata,
-		FailedHop:       uint8(len(req.AllocTrail)),
-		FailedSetup:     req,
+		Response:    *response,
+		FailedSetup: req,
 	}
 	rsv, err := s.db.GetSegmentRsvFromID(ctx, &req.ID)
 	if err != nil {
@@ -133,9 +133,11 @@ func (s *Store) AdmitSegmentReservation(ctx context.Context, req *segment.SetupR
 	var msg base.MessageWithPath
 	if req.IsLastAS() {
 		// TODO(juagargi) update token here
+		response.Accepted = true
+		response.FailedHop = 0
 		msg = &segment.ResponseSetupSuccess{
-			RequestMetadata: *revMetadata,
-			Token:           *index.Token,
+			Response: *response,
+			Token:    *index.Token,
 		}
 	} else {
 		msg = req
diff --git a/go/lib/colibri/reservation/types.go b/go/lib/colibri/reservation/types.go
index 325c378cb..c9da90e67 100644
--- a/go/lib/colibri/reservation/types.go
+++ b/go/lib/colibri/reservation/types.go
@@ -82,6 +82,13 @@ func (id *SegmentID) Read(raw []byte) (int, error) {
 	return SegmentIDLen, nil
 }
 
+// ToRaw calls Read and returns a new allocated buffer with the ID serialized.
+func (id *SegmentID) ToRaw() []byte {
+	buf := make([]byte, SegmentIDLen)
+	id.Read(buf) // safely ignore errors as they can only come from buffer size
+	return buf
+}
+
 func (id *SegmentID) String() string {
 	return fmt.Sprintf("%s-%x", id.ASID, id.Suffix)
 }
diff --git a/go/lib/ctrl/colibri_mgmt/colibri_mgmt.go b/go/lib/ctrl/colibri_mgmt/colibri_mgmt.go
index a11c92ce1..8ee5f25cd 100644
--- a/go/lib/ctrl/colibri_mgmt/colibri_mgmt.go
+++ b/go/lib/ctrl/colibri_mgmt/colibri_mgmt.go
@@ -59,3 +59,21 @@ func NewFromRaw(b []byte) (*ColibriRequestPayload, error) {
 	}
 	return pld, nil
 }
+
+type SegmentBase struct {
+	ID    *SegmentReservationID `capnp:"id"`
+	Index uint8
+}
+
+func (p *SegmentBase) ProtoId() proto.ProtoIdType {
+	return proto.SegmentBase_TypeID
+}
+
+type E2EBase struct {
+	ID    *E2EReservationID `capnp:"id"`
+	Index uint8
+}
+
+func (p *E2EBase) ProtoId() proto.ProtoIdType {
+	return proto.E2EBase_TypeID
+}
diff --git a/go/lib/ctrl/colibri_mgmt/response.go b/go/lib/ctrl/colibri_mgmt/response.go
index 5d1015841..1d9ea4e95 100644
--- a/go/lib/ctrl/colibri_mgmt/response.go
+++ b/go/lib/ctrl/colibri_mgmt/response.go
@@ -22,14 +22,12 @@ 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"`
+	SegmentIndexConfirmation *SegmentIndexConfirmationRes
+	SegmentCleanup           *SegmentCleanupRes
+	E2ESetup                 *E2ESetupRes   `capnp:"e2eSetup"`
+	E2ERenewal               *E2ESetupRes   `capnp:"e2eRenewal"`
+	E2ECleanup               *E2ECleanupRes `capnp:"e2eCleanup"`
 	Accepted                 bool
 	FailedHop                uint8 // only relevant if Accepted == false
 }
diff --git a/go/lib/ctrl/colibri_mgmt/segment_cleanup.go b/go/lib/ctrl/colibri_mgmt/segment_cleanup.go
index 74707a462..c288fca88 100644
--- a/go/lib/ctrl/colibri_mgmt/segment_cleanup.go
+++ b/go/lib/ctrl/colibri_mgmt/segment_cleanup.go
@@ -19,10 +19,18 @@ import (
 )
 
 type SegmentCleanup struct {
-	ID    *SegmentReservationID `capnp:"id"`
-	Index uint8
+	Base *SegmentBase
 }
 
 func (s *SegmentCleanup) ProtoId() proto.ProtoIdType {
 	return proto.SegmentCleanupData_TypeID
 }
+
+type SegmentCleanupRes struct {
+	Base      *SegmentBase
+	ErrorCode uint8
+}
+
+func (s *SegmentCleanupRes) ProtoId() proto.ProtoIdType {
+	return proto.SegmentCleanupResData_TypeID
+}
diff --git a/go/lib/ctrl/colibri_mgmt/segment_index_confirmation.go b/go/lib/ctrl/colibri_mgmt/segment_index_confirmation.go
index 18e9031dc..18ffd3a08 100644
--- a/go/lib/ctrl/colibri_mgmt/segment_index_confirmation.go
+++ b/go/lib/ctrl/colibri_mgmt/segment_index_confirmation.go
@@ -19,10 +19,19 @@ import (
 )
 
 type SegmentIndexConfirmation struct {
-	Index uint8
+	Base  *SegmentBase
 	State proto.ReservationIndexState
 }
 
 func (s *SegmentIndexConfirmation) ProtoId() proto.ProtoIdType {
 	return proto.SegmentIndexConfirmationData_TypeID
 }
+
+type SegmentIndexConfirmationRes struct {
+	Base      *SegmentBase
+	ErrorCode uint8
+}
+
+func (s *SegmentIndexConfirmationRes) ProtoId() proto.ProtoIdType {
+	return proto.SegmentIndexConfirmationResData_TypeID
+}
diff --git a/go/lib/ctrl/colibri_mgmt/segment_setup.go b/go/lib/ctrl/colibri_mgmt/segment_setup.go
index c91471bce..0e72d4dc3 100644
--- a/go/lib/ctrl/colibri_mgmt/segment_setup.go
+++ b/go/lib/ctrl/colibri_mgmt/segment_setup.go
@@ -19,6 +19,7 @@ import (
 )
 
 type SegmentSetup struct {
+	Base            *SegmentBase
 	MinBW           uint8
 	MaxBW           uint8
 	SplitCls        uint8
@@ -33,6 +34,7 @@ func (s *SegmentSetup) ProtoId() proto.ProtoIdType {
 }
 
 type SegmentSetupRes struct {
+	Base    *SegmentBase
 	Which   proto.SegmentSetupResData_Which
 	Failure *SegmentSetup
 	Token   []byte
diff --git a/go/lib/ctrl/colibri_mgmt/segment_teardown.go b/go/lib/ctrl/colibri_mgmt/segment_teardown.go
index e2877e8b0..67f056aff 100644
--- a/go/lib/ctrl/colibri_mgmt/segment_teardown.go
+++ b/go/lib/ctrl/colibri_mgmt/segment_teardown.go
@@ -18,13 +18,16 @@ import (
 	"github.com/scionproto/scion/go/proto"
 )
 
-type SegmentTeardownReq struct{}
+type SegmentTeardownReq struct {
+	Base *SegmentBase
+}
 
 func (s *SegmentTeardownReq) ProtoId() proto.ProtoIdType {
 	return proto.SegmentTeardownReqData_TypeID
 }
 
 type SegmentTeardownRes struct {
+	Base      *SegmentBase
 	ErrorCode uint8 // relevant only if Response.Accepted == false
 }
 
diff --git a/go/proto/colibri.capnp.go b/go/proto/colibri.capnp.go
index 390c0d934..ca7b70532 100644
--- a/go/proto/colibri.capnp.go
+++ b/go/proto/colibri.capnp.go
@@ -362,18 +362,194 @@ func (p AllocationBead_Promise) Struct() (AllocationBead, error) {
 	return AllocationBead{s}, err
 }
 
+type SegmentBase struct{ capnp.Struct }
+
+// SegmentBase_TypeID is the unique identifier for the type SegmentBase.
+const SegmentBase_TypeID = 0x9668b2a783bf3465
+
+func NewSegmentBase(s *capnp.Segment) (SegmentBase, error) {
+	st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1})
+	return SegmentBase{st}, err
+}
+
+func NewRootSegmentBase(s *capnp.Segment) (SegmentBase, error) {
+	st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1})
+	return SegmentBase{st}, err
+}
+
+func ReadRootSegmentBase(msg *capnp.Message) (SegmentBase, error) {
+	root, err := msg.RootPtr()
+	return SegmentBase{root.Struct()}, err
+}
+
+func (s SegmentBase) String() string {
+	str, _ := text.Marshal(0x9668b2a783bf3465, s.Struct)
+	return str
+}
+
+func (s SegmentBase) Id() (SegmentReservationID, error) {
+	p, err := s.Struct.Ptr(0)
+	return SegmentReservationID{Struct: p.Struct()}, err
+}
+
+func (s SegmentBase) HasId() bool {
+	p, err := s.Struct.Ptr(0)
+	return p.IsValid() || err != nil
+}
+
+func (s SegmentBase) SetId(v SegmentReservationID) error {
+	return s.Struct.SetPtr(0, v.Struct.ToPtr())
+}
+
+// NewId sets the id field to a newly
+// allocated SegmentReservationID struct, preferring placement in s's segment.
+func (s SegmentBase) NewId() (SegmentReservationID, error) {
+	ss, err := NewSegmentReservationID(s.Struct.Segment())
+	if err != nil {
+		return SegmentReservationID{}, err
+	}
+	err = s.Struct.SetPtr(0, ss.Struct.ToPtr())
+	return ss, err
+}
+
+func (s SegmentBase) Index() uint8 {
+	return s.Struct.Uint8(0)
+}
+
+func (s SegmentBase) SetIndex(v uint8) {
+	s.Struct.SetUint8(0, v)
+}
+
+// SegmentBase_List is a list of SegmentBase.
+type SegmentBase_List struct{ capnp.List }
+
+// NewSegmentBase creates a new list of SegmentBase.
+func NewSegmentBase_List(s *capnp.Segment, sz int32) (SegmentBase_List, error) {
+	l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}, sz)
+	return SegmentBase_List{l}, err
+}
+
+func (s SegmentBase_List) At(i int) SegmentBase { return SegmentBase{s.List.Struct(i)} }
+
+func (s SegmentBase_List) Set(i int, v SegmentBase) error { return s.List.SetStruct(i, v.Struct) }
+
+func (s SegmentBase_List) String() string {
+	str, _ := text.MarshalList(0x9668b2a783bf3465, s.List)
+	return str
+}
+
+// SegmentBase_Promise is a wrapper for a SegmentBase promised by a client call.
+type SegmentBase_Promise struct{ *capnp.Pipeline }
+
+func (p SegmentBase_Promise) Struct() (SegmentBase, error) {
+	s, err := p.Pipeline.Struct()
+	return SegmentBase{s}, err
+}
+
+func (p SegmentBase_Promise) Id() SegmentReservationID_Promise {
+	return SegmentReservationID_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
+}
+
+type E2EBase struct{ capnp.Struct }
+
+// E2EBase_TypeID is the unique identifier for the type E2EBase.
+const E2EBase_TypeID = 0x830a81292c60dfee
+
+func NewE2EBase(s *capnp.Segment) (E2EBase, error) {
+	st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1})
+	return E2EBase{st}, err
+}
+
+func NewRootE2EBase(s *capnp.Segment) (E2EBase, error) {
+	st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1})
+	return E2EBase{st}, err
+}
+
+func ReadRootE2EBase(msg *capnp.Message) (E2EBase, error) {
+	root, err := msg.RootPtr()
+	return E2EBase{root.Struct()}, err
+}
+
+func (s E2EBase) String() string {
+	str, _ := text.Marshal(0x830a81292c60dfee, s.Struct)
+	return str
+}
+
+func (s E2EBase) Id() (E2EReservationID, error) {
+	p, err := s.Struct.Ptr(0)
+	return E2EReservationID{Struct: p.Struct()}, err
+}
+
+func (s E2EBase) HasId() bool {
+	p, err := s.Struct.Ptr(0)
+	return p.IsValid() || err != nil
+}
+
+func (s E2EBase) SetId(v E2EReservationID) error {
+	return s.Struct.SetPtr(0, v.Struct.ToPtr())
+}
+
+// NewId sets the id field to a newly
+// allocated E2EReservationID struct, preferring placement in s's segment.
+func (s E2EBase) NewId() (E2EReservationID, error) {
+	ss, err := NewE2EReservationID(s.Struct.Segment())
+	if err != nil {
+		return E2EReservationID{}, err
+	}
+	err = s.Struct.SetPtr(0, ss.Struct.ToPtr())
+	return ss, err
+}
+
+func (s E2EBase) Index() uint8 {
+	return s.Struct.Uint8(0)
+}
+
+func (s E2EBase) SetIndex(v uint8) {
+	s.Struct.SetUint8(0, v)
+}
+
+// E2EBase_List is a list of E2EBase.
+type E2EBase_List struct{ capnp.List }
+
+// NewE2EBase creates a new list of E2EBase.
+func NewE2EBase_List(s *capnp.Segment, sz int32) (E2EBase_List, error) {
+	l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}, sz)
+	return E2EBase_List{l}, err
+}
+
+func (s E2EBase_List) At(i int) E2EBase { return E2EBase{s.List.Struct(i)} }
+
+func (s E2EBase_List) Set(i int, v E2EBase) error { return s.List.SetStruct(i, v.Struct) }
+
+func (s E2EBase_List) String() string {
+	str, _ := text.MarshalList(0x830a81292c60dfee, s.List)
+	return str
+}
+
+// E2EBase_Promise is a wrapper for a E2EBase promised by a client call.
+type E2EBase_Promise struct{ *capnp.Pipeline }
+
+func (p E2EBase_Promise) Struct() (E2EBase, error) {
+	s, err := p.Pipeline.Struct()
+	return E2EBase{s}, err
+}
+
+func (p E2EBase_Promise) Id() E2EReservationID_Promise {
+	return E2EReservationID_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
+}
+
 type SegmentSetupReqData struct{ capnp.Struct }
 
 // SegmentSetupReqData_TypeID is the unique identifier for the type SegmentSetupReqData.
 const SegmentSetupReqData_TypeID = 0xa26d74bea4eb287e
 
 func NewSegmentSetupReqData(s *capnp.Segment) (SegmentSetupReqData, error) {
-	st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 4})
+	st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 5})
 	return SegmentSetupReqData{st}, err
 }
 
 func NewRootSegmentSetupReqData(s *capnp.Segment) (SegmentSetupReqData, error) {
-	st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 4})
+	st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 5})
 	return SegmentSetupReqData{st}, err
 }
 
@@ -387,6 +563,31 @@ func (s SegmentSetupReqData) String() string {
 	return str
 }
 
+func (s SegmentSetupReqData) Base() (SegmentBase, error) {
+	p, err := s.Struct.Ptr(0)
+	return SegmentBase{Struct: p.Struct()}, err
+}
+
+func (s SegmentSetupReqData) HasBase() bool {
+	p, err := s.Struct.Ptr(0)
+	return p.IsValid() || err != nil
+}
+
+func (s SegmentSetupReqData) SetBase(v SegmentBase) error {
+	return s.Struct.SetPtr(0, v.Struct.ToPtr())
+}
+
+// NewBase sets the base field to a newly
+// allocated SegmentBase struct, preferring placement in s's segment.
+func (s SegmentSetupReqData) NewBase() (SegmentBase, error) {
+	ss, err := NewSegmentBase(s.Struct.Segment())
+	if err != nil {
+		return SegmentBase{}, err
+	}
+	err = s.Struct.SetPtr(0, ss.Struct.ToPtr())
+	return ss, err
+}
+
 func (s SegmentSetupReqData) MinBW() uint8 {
 	return s.Struct.Uint8(0)
 }
@@ -412,17 +613,17 @@ func (s SegmentSetupReqData) SetSplitCls(v uint8) {
 }
 
 func (s SegmentSetupReqData) StartProps() (PathEndProps, error) {
-	p, err := s.Struct.Ptr(0)
+	p, err := s.Struct.Ptr(1)
 	return PathEndProps{Struct: p.Struct()}, err
 }
 
 func (s SegmentSetupReqData) HasStartProps() bool {
-	p, err := s.Struct.Ptr(0)
+	p, err := s.Struct.Ptr(1)
 	return p.IsValid() || err != nil
 }
 
 func (s SegmentSetupReqData) SetStartProps(v PathEndProps) error {
-	return s.Struct.SetPtr(0, v.Struct.ToPtr())
+	return s.Struct.SetPtr(1, v.Struct.ToPtr())
 }
 
 // NewStartProps sets the startProps field to a newly
@@ -432,22 +633,22 @@ func (s SegmentSetupReqData) NewStartProps() (PathEndProps, error) {
 	if err != nil {
 		return PathEndProps{}, err
 	}
-	err = s.Struct.SetPtr(0, ss.Struct.ToPtr())
+	err = s.Struct.SetPtr(1, ss.Struct.ToPtr())
 	return ss, err
 }
 
 func (s SegmentSetupReqData) EndProps() (PathEndProps, error) {
-	p, err := s.Struct.Ptr(1)
+	p, err := s.Struct.Ptr(2)
 	return PathEndProps{Struct: p.Struct()}, err
 }
 
 func (s SegmentSetupReqData) HasEndProps() bool {
-	p, err := s.Struct.Ptr(1)
+	p, err := s.Struct.Ptr(2)
 	return p.IsValid() || err != nil
 }
 
 func (s SegmentSetupReqData) SetEndProps(v PathEndProps) error {
-	return s.Struct.SetPtr(1, v.Struct.ToPtr())
+	return s.Struct.SetPtr(2, v.Struct.ToPtr())
 }
 
 // NewEndProps sets the endProps field to a newly
@@ -457,36 +658,36 @@ func (s SegmentSetupReqData) NewEndProps() (PathEndProps, error) {
 	if err != nil {
 		return PathEndProps{}, err
 	}
-	err = s.Struct.SetPtr(1, ss.Struct.ToPtr())
+	err = s.Struct.SetPtr(2, ss.Struct.ToPtr())
 	return ss, err
 }
 
 func (s SegmentSetupReqData) InfoField() ([]byte, error) {
-	p, err := s.Struct.Ptr(2)
+	p, err := s.Struct.Ptr(3)
 	return []byte(p.Data()), err
 }
 
 func (s SegmentSetupReqData) HasInfoField() bool {
-	p, err := s.Struct.Ptr(2)
+	p, err := s.Struct.Ptr(3)
 	return p.IsValid() || err != nil
 }
 
 func (s SegmentSetupReqData) SetInfoField(v []byte) error {
-	return s.Struct.SetData(2, v)
+	return s.Struct.SetData(3, v)
 }
 
 func (s SegmentSetupReqData) AllocationTrail() (AllocationBead_List, error) {
-	p, err := s.Struct.Ptr(3)
+	p, err := s.Struct.Ptr(4)
 	return AllocationBead_List{List: p.List()}, err
 }
 
 func (s SegmentSetupReqData) HasAllocationTrail() bool {
-	p, err := s.Struct.Ptr(3)
+	p, err := s.Struct.Ptr(4)
 	return p.IsValid() || err != nil
 }
 
 func (s SegmentSetupReqData) SetAllocationTrail(v AllocationBead_List) error {
-	return s.Struct.SetPtr(3, v.List.ToPtr())
+	return s.Struct.SetPtr(4, v.List.ToPtr())
 }
 
 // NewAllocationTrail sets the allocationTrail field to a newly
@@ -496,7 +697,7 @@ func (s SegmentSetupReqData) NewAllocationTrail(n int32) (AllocationBead_List, e
 	if err != nil {
 		return AllocationBead_List{}, err
 	}
-	err = s.Struct.SetPtr(3, l.List.ToPtr())
+	err = s.Struct.SetPtr(4, l.List.ToPtr())
 	return l, err
 }
 
@@ -505,7 +706,7 @@ type SegmentSetupReqData_List struct{ capnp.List }
 
 // NewSegmentSetupReqData creates a new list of SegmentSetupReqData.
 func NewSegmentSetupReqData_List(s *capnp.Segment, sz int32) (SegmentSetupReqData_List, error) {
-	l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 4}, sz)
+	l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 5}, sz)
 	return SegmentSetupReqData_List{l}, err
 }
 
@@ -530,12 +731,16 @@ func (p SegmentSetupReqData_Promise) Struct() (SegmentSetupReqData, error) {
 	return SegmentSetupReqData{s}, err
 }
 
+func (p SegmentSetupReqData_Promise) Base() SegmentBase_Promise {
+	return SegmentBase_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
+}
+
 func (p SegmentSetupReqData_Promise) StartProps() PathEndProps_Promise {
-	return PathEndProps_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
+	return PathEndProps_Promise{Pipeline: p.Pipeline.GetPipeline(1)}
 }
 
 func (p SegmentSetupReqData_Promise) EndProps() PathEndProps_Promise {
-	return PathEndProps_Promise{Pipeline: p.Pipeline.GetPipeline(1)}
+	return PathEndProps_Promise{Pipeline: p.Pipeline.GetPipeline(2)}
 }
 
 type SegmentSetupResData struct{ capnp.Struct }
@@ -565,12 +770,12 @@ func (w SegmentSetupResData_Which) String() string {
 const SegmentSetupResData_TypeID = 0xaa345154c72e2fa5
 
 func NewSegmentSetupResData(s *capnp.Segment) (SegmentSetupResData, error) {
-	st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1})
+	st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 2})
 	return SegmentSetupResData{st}, err
 }
 
 func NewRootSegmentSetupResData(s *capnp.Segment) (SegmentSetupResData, error) {
-	st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1})
+	st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 2})
 	return SegmentSetupResData{st}, err
 }
 
@@ -587,6 +792,31 @@ func (s SegmentSetupResData) String() string {
 func (s SegmentSetupResData) Which() SegmentSetupResData_Which {
 	return SegmentSetupResData_Which(s.Struct.Uint16(0))
 }
+func (s SegmentSetupResData) Base() (SegmentBase, error) {
+	p, err := s.Struct.Ptr(0)
+	return SegmentBase{Struct: p.Struct()}, err
+}
+
+func (s SegmentSetupResData) HasBase() bool {
+	p, err := s.Struct.Ptr(0)
+	return p.IsValid() || err != nil
+}
+
+func (s SegmentSetupResData) SetBase(v SegmentBase) error {
+	return s.Struct.SetPtr(0, v.Struct.ToPtr())
+}
+
+// NewBase sets the base field to a newly
+// allocated SegmentBase struct, preferring placement in s's segment.
+func (s SegmentSetupResData) NewBase() (SegmentBase, error) {
+	ss, err := NewSegmentBase(s.Struct.Segment())
+	if err != nil {
+		return SegmentBase{}, err
+	}
+	err = s.Struct.SetPtr(0, ss.Struct.ToPtr())
+	return ss, err
+}
+
 func (s SegmentSetupResData) SetUnset() {
 	s.Struct.SetUint16(0, 0)
 
@@ -596,7 +826,7 @@ func (s SegmentSetupResData) Failure() (SegmentSetupReqData, error) {
 	if s.Struct.Uint16(0) != 1 {
 		panic("Which() != failure")
 	}
-	p, err := s.Struct.Ptr(0)
+	p, err := s.Struct.Ptr(1)
 	return SegmentSetupReqData{Struct: p.Struct()}, err
 }
 
@@ -604,13 +834,13 @@ func (s SegmentSetupResData) HasFailure() bool {
 	if s.Struct.Uint16(0) != 1 {
 		return false
 	}
-	p, err := s.Struct.Ptr(0)
+	p, err := s.Struct.Ptr(1)
 	return p.IsValid() || err != nil
 }
 
 func (s SegmentSetupResData) SetFailure(v SegmentSetupReqData) error {
 	s.Struct.SetUint16(0, 1)
-	return s.Struct.SetPtr(0, v.Struct.ToPtr())
+	return s.Struct.SetPtr(1, v.Struct.ToPtr())
 }
 
 // NewFailure sets the failure field to a newly
@@ -621,7 +851,7 @@ func (s SegmentSetupResData) NewFailure() (SegmentSetupReqData, error) {
 	if err != nil {
 		return SegmentSetupReqData{}, err
 	}
-	err = s.Struct.SetPtr(0, ss.Struct.ToPtr())
+	err = s.Struct.SetPtr(1, ss.Struct.ToPtr())
 	return ss, err
 }
 
@@ -629,7 +859,7 @@ func (s SegmentSetupResData) Token() ([]byte, error) {
 	if s.Struct.Uint16(0) != 2 {
 		panic("Which() != token")
 	}
-	p, err := s.Struct.Ptr(0)
+	p, err := s.Struct.Ptr(1)
 	return []byte(p.Data()), err
 }
 
@@ -637,13 +867,13 @@ func (s SegmentSetupResData) HasToken() bool {
 	if s.Struct.Uint16(0) != 2 {
 		return false
 	}
-	p, err := s.Struct.Ptr(0)
+	p, err := s.Struct.Ptr(1)
 	return p.IsValid() || err != nil
 }
 
 func (s SegmentSetupResData) SetToken(v []byte) error {
 	s.Struct.SetUint16(0, 2)
-	return s.Struct.SetData(0, v)
+	return s.Struct.SetData(1, v)
 }
 
 // SegmentSetupResData_List is a list of SegmentSetupResData.
@@ -651,7 +881,7 @@ type SegmentSetupResData_List struct{ capnp.List }
 
 // NewSegmentSetupResData creates a new list of SegmentSetupResData.
 func NewSegmentSetupResData_List(s *capnp.Segment, sz int32) (SegmentSetupResData_List, error) {
-	l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}, sz)
+	l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 2}, sz)
 	return SegmentSetupResData_List{l}, err
 }
 
@@ -676,8 +906,12 @@ func (p SegmentSetupResData_Promise) Struct() (SegmentSetupResData, error) {
 	return SegmentSetupResData{s}, err
 }
 
+func (p SegmentSetupResData_Promise) Base() SegmentBase_Promise {
+	return SegmentBase_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
+}
+
 func (p SegmentSetupResData_Promise) Failure() SegmentSetupReqData_Promise {
-	return SegmentSetupReqData_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
+	return SegmentSetupReqData_Promise{Pipeline: p.Pipeline.GetPipeline(1)}
 }
 
 type SegmentTelesSetupData struct{ capnp.Struct }
@@ -799,12 +1033,12 @@ type SegmentTeardownReqData struct{ capnp.Struct }
 const SegmentTeardownReqData_TypeID = 0xa53b4bed5b0bc568
 
 func NewSegmentTeardownReqData(s *capnp.Segment) (SegmentTeardownReqData, error) {
-	st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 0})
+	st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1})
 	return SegmentTeardownReqData{st}, err
 }
 
 func NewRootSegmentTeardownReqData(s *capnp.Segment) (SegmentTeardownReqData, error) {
-	st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 0})
+	st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1})
 	return SegmentTeardownReqData{st}, err
 }
 
@@ -818,12 +1052,37 @@ func (s SegmentTeardownReqData) String() string {
 	return str
 }
 
+func (s SegmentTeardownReqData) Base() (SegmentBase, error) {
+	p, err := s.Struct.Ptr(0)
+	return SegmentBase{Struct: p.Struct()}, err
+}
+
+func (s SegmentTeardownReqData) HasBase() bool {
+	p, err := s.Struct.Ptr(0)
+	return p.IsValid() || err != nil
+}
+
+func (s SegmentTeardownReqData) SetBase(v SegmentBase) error {
+	return s.Struct.SetPtr(0, v.Struct.ToPtr())
+}
+
+// NewBase sets the base field to a newly
+// allocated SegmentBase struct, preferring placement in s's segment.
+func (s SegmentTeardownReqData) NewBase() (SegmentBase, error) {
+	ss, err := NewSegmentBase(s.Struct.Segment())
+	if err != nil {
+		return SegmentBase{}, err
+	}
+	err = s.Struct.SetPtr(0, ss.Struct.ToPtr())
+	return ss, err
+}
+
 // SegmentTeardownReqData_List is a list of SegmentTeardownReqData.
 type SegmentTeardownReqData_List struct{ capnp.List }
 
 // NewSegmentTeardownReqData creates a new list of SegmentTeardownReqData.
 func NewSegmentTeardownReqData_List(s *capnp.Segment, sz int32) (SegmentTeardownReqData_List, error) {
-	l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 0}, sz)
+	l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1}, sz)
 	return SegmentTeardownReqData_List{l}, err
 }
 
@@ -848,18 +1107,22 @@ func (p SegmentTeardownReqData_Promise) Struct() (SegmentTeardownReqData, error)
 	return SegmentTeardownReqData{s}, err
 }
 
+func (p SegmentTeardownReqData_Promise) Base() SegmentBase_Promise {
+	return SegmentBase_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
+}
+
 type SegmentTeardownResData struct{ capnp.Struct }
 
 // SegmentTeardownResData_TypeID is the unique identifier for the type SegmentTeardownResData.
 const SegmentTeardownResData_TypeID = 0x8bd6c2ab5c4cf984
 
 func NewSegmentTeardownResData(s *capnp.Segment) (SegmentTeardownResData, error) {
-	st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 0})
+	st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1})
 	return SegmentTeardownResData{st}, err
 }
 
 func NewRootSegmentTeardownResData(s *capnp.Segment) (SegmentTeardownResData, error) {
-	st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 0})
+	st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1})
 	return SegmentTeardownResData{st}, err
 }
 
@@ -873,6 +1136,31 @@ func (s SegmentTeardownResData) String() string {
 	return str
 }
 
+func (s SegmentTeardownResData) Base() (SegmentBase, error) {
+	p, err := s.Struct.Ptr(0)
+	return SegmentBase{Struct: p.Struct()}, err
+}
+
+func (s SegmentTeardownResData) HasBase() bool {
+	p, err := s.Struct.Ptr(0)
+	return p.IsValid() || err != nil
+}
+
+func (s SegmentTeardownResData) SetBase(v SegmentBase) error {
+	return s.Struct.SetPtr(0, v.Struct.ToPtr())
+}
+
+// NewBase sets the base field to a newly
+// allocated SegmentBase struct, preferring placement in s's segment.
+func (s SegmentTeardownResData) NewBase() (SegmentBase, error) {
+	ss, err := NewSegmentBase(s.Struct.Segment())
+	if err != nil {
+		return SegmentBase{}, err
+	}
+	err = s.Struct.SetPtr(0, ss.Struct.ToPtr())
+	return ss, err
+}
+
 func (s SegmentTeardownResData) ErrorCode() uint8 {
 	return s.Struct.Uint8(0)
 }
@@ -886,7 +1174,7 @@ type SegmentTeardownResData_List struct{ capnp.List }
 
 // NewSegmentTeardownResData creates a new list of SegmentTeardownResData.
 func NewSegmentTeardownResData_List(s *capnp.Segment, sz int32) (SegmentTeardownResData_List, error) {
-	l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 0}, sz)
+	l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}, sz)
 	return SegmentTeardownResData_List{l}, err
 }
 
@@ -911,18 +1199,22 @@ func (p SegmentTeardownResData_Promise) Struct() (SegmentTeardownResData, error)
 	return SegmentTeardownResData{s}, err
 }
 
+func (p SegmentTeardownResData_Promise) Base() SegmentBase_Promise {
+	return SegmentBase_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
+}
+
 type SegmentIndexConfirmationData struct{ capnp.Struct }
 
 // SegmentIndexConfirmationData_TypeID is the unique identifier for the type SegmentIndexConfirmationData.
 const SegmentIndexConfirmationData_TypeID = 0xc4264f5cf728f9ac
 
 func NewSegmentIndexConfirmationData(s *capnp.Segment) (SegmentIndexConfirmationData, error) {
-	st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 0})
+	st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1})
 	return SegmentIndexConfirmationData{st}, err
 }
 
 func NewRootSegmentIndexConfirmationData(s *capnp.Segment) (SegmentIndexConfirmationData, error) {
-	st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 0})
+	st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1})
 	return SegmentIndexConfirmationData{st}, err
 }
 
@@ -936,20 +1228,37 @@ func (s SegmentIndexConfirmationData) String() string {
 	return str
 }
 
-func (s SegmentIndexConfirmationData) Index() uint8 {
-	return s.Struct.Uint8(0)
+func (s SegmentIndexConfirmationData) Base() (SegmentBase, error) {
+	p, err := s.Struct.Ptr(0)
+	return SegmentBase{Struct: p.Struct()}, err
 }
 
-func (s SegmentIndexConfirmationData) SetIndex(v uint8) {
-	s.Struct.SetUint8(0, v)
+func (s SegmentIndexConfirmationData) HasBase() bool {
+	p, err := s.Struct.Ptr(0)
+	return p.IsValid() || err != nil
+}
+
+func (s SegmentIndexConfirmationData) SetBase(v SegmentBase) error {
+	return s.Struct.SetPtr(0, v.Struct.ToPtr())
+}
+
+// NewBase sets the base field to a newly
+// allocated SegmentBase struct, preferring placement in s's segment.
+func (s SegmentIndexConfirmationData) NewBase() (SegmentBase, error) {
+	ss, err := NewSegmentBase(s.Struct.Segment())
+	if err != nil {
+		return SegmentBase{}, err
+	}
+	err = s.Struct.SetPtr(0, ss.Struct.ToPtr())
+	return ss, err
 }
 
 func (s SegmentIndexConfirmationData) State() ReservationIndexState {
-	return ReservationIndexState(s.Struct.Uint16(2))
+	return ReservationIndexState(s.Struct.Uint16(0))
 }
 
 func (s SegmentIndexConfirmationData) SetState(v ReservationIndexState) {
-	s.Struct.SetUint16(2, uint16(v))
+	s.Struct.SetUint16(0, uint16(v))
 }
 
 // SegmentIndexConfirmationData_List is a list of SegmentIndexConfirmationData.
@@ -957,7 +1266,7 @@ type SegmentIndexConfirmationData_List struct{ capnp.List }
 
 // NewSegmentIndexConfirmationData creates a new list of SegmentIndexConfirmationData.
 func NewSegmentIndexConfirmationData_List(s *capnp.Segment, sz int32) (SegmentIndexConfirmationData_List, error) {
-	l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 0}, sz)
+	l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}, sz)
 	return SegmentIndexConfirmationData_List{l}, err
 }
 
@@ -982,18 +1291,114 @@ func (p SegmentIndexConfirmationData_Promise) Struct() (SegmentIndexConfirmation
 	return SegmentIndexConfirmationData{s}, err
 }
 
+func (p SegmentIndexConfirmationData_Promise) Base() SegmentBase_Promise {
+	return SegmentBase_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
+}
+
+type SegmentIndexConfirmationResData struct{ capnp.Struct }
+
+// SegmentIndexConfirmationResData_TypeID is the unique identifier for the type SegmentIndexConfirmationResData.
+const SegmentIndexConfirmationResData_TypeID = 0xaaff46584917b361
+
+func NewSegmentIndexConfirmationResData(s *capnp.Segment) (SegmentIndexConfirmationResData, error) {
+	st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1})
+	return SegmentIndexConfirmationResData{st}, err
+}
+
+func NewRootSegmentIndexConfirmationResData(s *capnp.Segment) (SegmentIndexConfirmationResData, error) {
+	st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1})
+	return SegmentIndexConfirmationResData{st}, err
+}
+
+func ReadRootSegmentIndexConfirmationResData(msg *capnp.Message) (SegmentIndexConfirmationResData, error) {
+	root, err := msg.RootPtr()
+	return SegmentIndexConfirmationResData{root.Struct()}, err
+}
+
+func (s SegmentIndexConfirmationResData) String() string {
+	str, _ := text.Marshal(0xaaff46584917b361, s.Struct)
+	return str
+}
+
+func (s SegmentIndexConfirmationResData) Base() (SegmentBase, error) {
+	p, err := s.Struct.Ptr(0)
+	return SegmentBase{Struct: p.Struct()}, err
+}
+
+func (s SegmentIndexConfirmationResData) HasBase() bool {
+	p, err := s.Struct.Ptr(0)
+	return p.IsValid() || err != nil
+}
+
+func (s SegmentIndexConfirmationResData) SetBase(v SegmentBase) error {
+	return s.Struct.SetPtr(0, v.Struct.ToPtr())
+}
+
+// NewBase sets the base field to a newly
+// allocated SegmentBase struct, preferring placement in s's segment.
+func (s SegmentIndexConfirmationResData) NewBase() (SegmentBase, error) {
+	ss, err := NewSegmentBase(s.Struct.Segment())
+	if err != nil {
+		return SegmentBase{}, err
+	}
+	err = s.Struct.SetPtr(0, ss.Struct.ToPtr())
+	return ss, err
+}
+
+func (s SegmentIndexConfirmationResData) ErrorCode() uint8 {
+	return s.Struct.Uint8(0)
+}
+
+func (s SegmentIndexConfirmationResData) SetErrorCode(v uint8) {
+	s.Struct.SetUint8(0, v)
+}
+
+// SegmentIndexConfirmationResData_List is a list of SegmentIndexConfirmationResData.
+type SegmentIndexConfirmationResData_List struct{ capnp.List }
+
+// NewSegmentIndexConfirmationResData creates a new list of SegmentIndexConfirmationResData.
+func NewSegmentIndexConfirmationResData_List(s *capnp.Segment, sz int32) (SegmentIndexConfirmationResData_List, error) {
+	l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}, sz)
+	return SegmentIndexConfirmationResData_List{l}, err
+}
+
+func (s SegmentIndexConfirmationResData_List) At(i int) SegmentIndexConfirmationResData {
+	return SegmentIndexConfirmationResData{s.List.Struct(i)}
+}
+
+func (s SegmentIndexConfirmationResData_List) Set(i int, v SegmentIndexConfirmationResData) error {
+	return s.List.SetStruct(i, v.Struct)
+}
+
+func (s SegmentIndexConfirmationResData_List) String() string {
+	str, _ := text.MarshalList(0xaaff46584917b361, s.List)
+	return str
+}
+
+// SegmentIndexConfirmationResData_Promise is a wrapper for a SegmentIndexConfirmationResData promised by a client call.
+type SegmentIndexConfirmationResData_Promise struct{ *capnp.Pipeline }
+
+func (p SegmentIndexConfirmationResData_Promise) Struct() (SegmentIndexConfirmationResData, error) {
+	s, err := p.Pipeline.Struct()
+	return SegmentIndexConfirmationResData{s}, err
+}
+
+func (p SegmentIndexConfirmationResData_Promise) Base() SegmentBase_Promise {
+	return SegmentBase_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
+}
+
 type SegmentCleanupData struct{ capnp.Struct }
 
 // SegmentCleanupData_TypeID is the unique identifier for the type SegmentCleanupData.
 const SegmentCleanupData_TypeID = 0xd3e56d3f1e39ca3c
 
 func NewSegmentCleanupData(s *capnp.Segment) (SegmentCleanupData, error) {
-	st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1})
+	st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1})
 	return SegmentCleanupData{st}, err
 }
 
 func NewRootSegmentCleanupData(s *capnp.Segment) (SegmentCleanupData, error) {
-	st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1})
+	st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1})
 	return SegmentCleanupData{st}, err
 }
 
@@ -1007,219 +1412,532 @@ func (s SegmentCleanupData) String() string {
 	return str
 }
 
-func (s SegmentCleanupData) Id() (SegmentReservationID, error) {
+func (s SegmentCleanupData) Base() (SegmentBase, error) {
 	p, err := s.Struct.Ptr(0)
-	return SegmentReservationID{Struct: p.Struct()}, err
+	return SegmentBase{Struct: p.Struct()}, err
 }
 
-func (s SegmentCleanupData) HasId() bool {
+func (s SegmentCleanupData) HasBase() bool {
 	p, err := s.Struct.Ptr(0)
 	return p.IsValid() || err != nil
 }
 
-func (s SegmentCleanupData) SetId(v SegmentReservationID) error {
-	return s.Struct.SetPtr(0, v.Struct.ToPtr())
+func (s SegmentCleanupData) SetBase(v SegmentBase) error {
+	return s.Struct.SetPtr(0, v.Struct.ToPtr())
+}
+
+// NewBase sets the base field to a newly
+// allocated SegmentBase struct, preferring placement in s's segment.
+func (s SegmentCleanupData) NewBase() (SegmentBase, error) {
+	ss, err := NewSegmentBase(s.Struct.Segment())
+	if err != nil {
+		return SegmentBase{}, err
+	}
+	err = s.Struct.SetPtr(0, ss.Struct.ToPtr())
+	return ss, err
+}
+
+// SegmentCleanupData_List is a list of SegmentCleanupData.
+type SegmentCleanupData_List struct{ capnp.List }
+
+// NewSegmentCleanupData creates a new list of SegmentCleanupData.
+func NewSegmentCleanupData_List(s *capnp.Segment, sz int32) (SegmentCleanupData_List, error) {
+	l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1}, sz)
+	return SegmentCleanupData_List{l}, err
+}
+
+func (s SegmentCleanupData_List) At(i int) SegmentCleanupData {
+	return SegmentCleanupData{s.List.Struct(i)}
+}
+
+func (s SegmentCleanupData_List) Set(i int, v SegmentCleanupData) error {
+	return s.List.SetStruct(i, v.Struct)
+}
+
+func (s SegmentCleanupData_List) String() string {
+	str, _ := text.MarshalList(0xd3e56d3f1e39ca3c, s.List)
+	return str
+}
+
+// SegmentCleanupData_Promise is a wrapper for a SegmentCleanupData promised by a client call.
+type SegmentCleanupData_Promise struct{ *capnp.Pipeline }
+
+func (p SegmentCleanupData_Promise) Struct() (SegmentCleanupData, error) {
+	s, err := p.Pipeline.Struct()
+	return SegmentCleanupData{s}, err
+}
+
+func (p SegmentCleanupData_Promise) Base() SegmentBase_Promise {
+	return SegmentBase_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
+}
+
+type SegmentCleanupResData struct{ capnp.Struct }
+
+// SegmentCleanupResData_TypeID is the unique identifier for the type SegmentCleanupResData.
+const SegmentCleanupResData_TypeID = 0xa6f94955f188b848
+
+func NewSegmentCleanupResData(s *capnp.Segment) (SegmentCleanupResData, error) {
+	st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1})
+	return SegmentCleanupResData{st}, err
+}
+
+func NewRootSegmentCleanupResData(s *capnp.Segment) (SegmentCleanupResData, error) {
+	st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1})
+	return SegmentCleanupResData{st}, err
+}
+
+func ReadRootSegmentCleanupResData(msg *capnp.Message) (SegmentCleanupResData, error) {
+	root, err := msg.RootPtr()
+	return SegmentCleanupResData{root.Struct()}, err
+}
+
+func (s SegmentCleanupResData) String() string {
+	str, _ := text.Marshal(0xa6f94955f188b848, s.Struct)
+	return str
+}
+
+func (s SegmentCleanupResData) Base() (SegmentBase, error) {
+	p, err := s.Struct.Ptr(0)
+	return SegmentBase{Struct: p.Struct()}, err
+}
+
+func (s SegmentCleanupResData) HasBase() bool {
+	p, err := s.Struct.Ptr(0)
+	return p.IsValid() || err != nil
+}
+
+func (s SegmentCleanupResData) SetBase(v SegmentBase) error {
+	return s.Struct.SetPtr(0, v.Struct.ToPtr())
+}
+
+// NewBase sets the base field to a newly
+// allocated SegmentBase struct, preferring placement in s's segment.
+func (s SegmentCleanupResData) NewBase() (SegmentBase, error) {
+	ss, err := NewSegmentBase(s.Struct.Segment())
+	if err != nil {
+		return SegmentBase{}, err
+	}
+	err = s.Struct.SetPtr(0, ss.Struct.ToPtr())
+	return ss, err
+}
+
+func (s SegmentCleanupResData) ErrorCode() uint8 {
+	return s.Struct.Uint8(0)
+}
+
+func (s SegmentCleanupResData) SetErrorCode(v uint8) {
+	s.Struct.SetUint8(0, v)
+}
+
+// SegmentCleanupResData_List is a list of SegmentCleanupResData.
+type SegmentCleanupResData_List struct{ capnp.List }
+
+// NewSegmentCleanupResData creates a new list of SegmentCleanupResData.
+func NewSegmentCleanupResData_List(s *capnp.Segment, sz int32) (SegmentCleanupResData_List, error) {
+	l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}, sz)
+	return SegmentCleanupResData_List{l}, err
+}
+
+func (s SegmentCleanupResData_List) At(i int) SegmentCleanupResData {
+	return SegmentCleanupResData{s.List.Struct(i)}
+}
+
+func (s SegmentCleanupResData_List) Set(i int, v SegmentCleanupResData) error {
+	return s.List.SetStruct(i, v.Struct)
+}
+
+func (s SegmentCleanupResData_List) String() string {
+	str, _ := text.MarshalList(0xa6f94955f188b848, s.List)
+	return str
+}
+
+// SegmentCleanupResData_Promise is a wrapper for a SegmentCleanupResData promised by a client call.
+type SegmentCleanupResData_Promise struct{ *capnp.Pipeline }
+
+func (p SegmentCleanupResData_Promise) Struct() (SegmentCleanupResData, error) {
+	s, err := p.Pipeline.Struct()
+	return SegmentCleanupResData{s}, err
+}
+
+func (p SegmentCleanupResData_Promise) Base() SegmentBase_Promise {
+	return SegmentBase_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
+}
+
+type E2ESetupReqData struct{ capnp.Struct }
+type E2ESetupReqData_success E2ESetupReqData
+type E2ESetupReqData_failure E2ESetupReqData
+type E2ESetupReqData_Which uint16
+
+const (
+	E2ESetupReqData_Which_unset   E2ESetupReqData_Which = 0
+	E2ESetupReqData_Which_success E2ESetupReqData_Which = 1
+	E2ESetupReqData_Which_failure E2ESetupReqData_Which = 2
+)
+
+func (w E2ESetupReqData_Which) String() string {
+	const s = "unsetsuccessfailure"
+	switch w {
+	case E2ESetupReqData_Which_unset:
+		return s[0:5]
+	case E2ESetupReqData_Which_success:
+		return s[5:12]
+	case E2ESetupReqData_Which_failure:
+		return s[12:19]
+
+	}
+	return "E2ESetupReqData_Which(" + strconv.FormatUint(uint64(w), 10) + ")"
+}
+
+// E2ESetupReqData_TypeID is the unique identifier for the type E2ESetupReqData.
+const E2ESetupReqData_TypeID = 0xfb1a873660b7e310
+
+func NewE2ESetupReqData(s *capnp.Segment) (E2ESetupReqData, error) {
+	st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 4})
+	return E2ESetupReqData{st}, err
+}
+
+func NewRootE2ESetupReqData(s *capnp.Segment) (E2ESetupReqData, error) {
+	st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 4})
+	return E2ESetupReqData{st}, err
+}
+
+func ReadRootE2ESetupReqData(msg *capnp.Message) (E2ESetupReqData, error) {
+	root, err := msg.RootPtr()
+	return E2ESetupReqData{root.Struct()}, err
+}
+
+func (s E2ESetupReqData) String() string {
+	str, _ := text.Marshal(0xfb1a873660b7e310, s.Struct)
+	return str
+}
+
+func (s E2ESetupReqData) Which() E2ESetupReqData_Which {
+	return E2ESetupReqData_Which(s.Struct.Uint16(2))
+}
+func (s E2ESetupReqData) Base() (E2EBase, error) {
+	p, err := s.Struct.Ptr(0)
+	return E2EBase{Struct: p.Struct()}, err
+}
+
+func (s E2ESetupReqData) HasBase() bool {
+	p, err := s.Struct.Ptr(0)
+	return p.IsValid() || err != nil
+}
+
+func (s E2ESetupReqData) SetBase(v E2EBase) error {
+	return s.Struct.SetPtr(0, v.Struct.ToPtr())
+}
+
+// NewBase sets the base field to a newly
+// allocated E2EBase struct, preferring placement in s's segment.
+func (s E2ESetupReqData) NewBase() (E2EBase, error) {
+	ss, err := NewE2EBase(s.Struct.Segment())
+	if err != nil {
+		return E2EBase{}, err
+	}
+	err = s.Struct.SetPtr(0, ss.Struct.ToPtr())
+	return ss, err
+}
+
+func (s E2ESetupReqData) SegmentRsvs() (SegmentReservationID_List, error) {
+	p, err := s.Struct.Ptr(1)
+	return SegmentReservationID_List{List: p.List()}, err
+}
+
+func (s E2ESetupReqData) HasSegmentRsvs() bool {
+	p, err := s.Struct.Ptr(1)
+	return p.IsValid() || err != nil
+}
+
+func (s E2ESetupReqData) SetSegmentRsvs(v SegmentReservationID_List) error {
+	return s.Struct.SetPtr(1, v.List.ToPtr())
+}
+
+// NewSegmentRsvs sets the segmentRsvs field to a newly
+// allocated SegmentReservationID_List, preferring placement in s's segment.
+func (s E2ESetupReqData) NewSegmentRsvs(n int32) (SegmentReservationID_List, error) {
+	l, err := NewSegmentReservationID_List(s.Struct.Segment(), n)
+	if err != nil {
+		return SegmentReservationID_List{}, err
+	}
+	err = s.Struct.SetPtr(1, l.List.ToPtr())
+	return l, err
+}
+
+func (s E2ESetupReqData) RequestedBW() uint8 {
+	return s.Struct.Uint8(0)
+}
+
+func (s E2ESetupReqData) SetRequestedBW(v uint8) {
+	s.Struct.SetUint8(0, v)
+}
+
+func (s E2ESetupReqData) AllocationTrail() (capnp.UInt8List, error) {
+	p, err := s.Struct.Ptr(2)
+	return capnp.UInt8List{List: p.List()}, err
+}
+
+func (s E2ESetupReqData) HasAllocationTrail() bool {
+	p, err := s.Struct.Ptr(2)
+	return p.IsValid() || err != nil
+}
+
+func (s E2ESetupReqData) SetAllocationTrail(v capnp.UInt8List) error {
+	return s.Struct.SetPtr(2, v.List.ToPtr())
+}
+
+// NewAllocationTrail sets the allocationTrail field to a newly
+// allocated capnp.UInt8List, preferring placement in s's segment.
+func (s E2ESetupReqData) NewAllocationTrail(n int32) (capnp.UInt8List, error) {
+	l, err := capnp.NewUInt8List(s.Struct.Segment(), n)
+	if err != nil {
+		return capnp.UInt8List{}, err
+	}
+	err = s.Struct.SetPtr(2, l.List.ToPtr())
+	return l, err
+}
+
+func (s E2ESetupReqData) SetUnset() {
+	s.Struct.SetUint16(2, 0)
+
+}
+
+func (s E2ESetupReqData) Success() E2ESetupReqData_success { return E2ESetupReqData_success(s) }
+
+func (s E2ESetupReqData) SetSuccess() {
+	s.Struct.SetUint16(2, 1)
+}
+
+func (s E2ESetupReqData_success) Token() ([]byte, error) {
+	p, err := s.Struct.Ptr(3)
+	return []byte(p.Data()), err
+}
+
+func (s E2ESetupReqData_success) HasToken() bool {
+	p, err := s.Struct.Ptr(3)
+	return p.IsValid() || err != nil
+}
+
+func (s E2ESetupReqData_success) SetToken(v []byte) error {
+	return s.Struct.SetData(3, v)
 }
 
-// NewId sets the id field to a newly
-// allocated SegmentReservationID struct, preferring placement in s's segment.
-func (s SegmentCleanupData) NewId() (SegmentReservationID, error) {
-	ss, err := NewSegmentReservationID(s.Struct.Segment())
-	if err != nil {
-		return SegmentReservationID{}, err
-	}
-	err = s.Struct.SetPtr(0, ss.Struct.ToPtr())
-	return ss, err
+func (s E2ESetupReqData) Failure() E2ESetupReqData_failure { return E2ESetupReqData_failure(s) }
+
+func (s E2ESetupReqData) SetFailure() {
+	s.Struct.SetUint16(2, 2)
 }
 
-func (s SegmentCleanupData) Index() uint8 {
-	return s.Struct.Uint8(0)
+func (s E2ESetupReqData_failure) ErrorCode() uint8 {
+	return s.Struct.Uint8(1)
 }
 
-func (s SegmentCleanupData) SetIndex(v uint8) {
-	s.Struct.SetUint8(0, v)
+func (s E2ESetupReqData_failure) SetErrorCode(v uint8) {
+	s.Struct.SetUint8(1, v)
 }
 
-// SegmentCleanupData_List is a list of SegmentCleanupData.
-type SegmentCleanupData_List struct{ capnp.List }
+// E2ESetupReqData_List is a list of E2ESetupReqData.
+type E2ESetupReqData_List struct{ capnp.List }
 
-// NewSegmentCleanupData creates a new list of SegmentCleanupData.
-func NewSegmentCleanupData_List(s *capnp.Segment, sz int32) (SegmentCleanupData_List, error) {
-	l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}, sz)
-	return SegmentCleanupData_List{l}, err
+// NewE2ESetupReqData creates a new list of E2ESetupReqData.
+func NewE2ESetupReqData_List(s *capnp.Segment, sz int32) (E2ESetupReqData_List, error) {
+	l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 4}, sz)
+	return E2ESetupReqData_List{l}, err
 }
 
-func (s SegmentCleanupData_List) At(i int) SegmentCleanupData {
-	return SegmentCleanupData{s.List.Struct(i)}
-}
+func (s E2ESetupReqData_List) At(i int) E2ESetupReqData { return E2ESetupReqData{s.List.Struct(i)} }
 
-func (s SegmentCleanupData_List) Set(i int, v SegmentCleanupData) error {
+func (s E2ESetupReqData_List) Set(i int, v E2ESetupReqData) error {
 	return s.List.SetStruct(i, v.Struct)
 }
 
-func (s SegmentCleanupData_List) String() string {
-	str, _ := text.MarshalList(0xd3e56d3f1e39ca3c, s.List)
+func (s E2ESetupReqData_List) String() string {
+	str, _ := text.MarshalList(0xfb1a873660b7e310, s.List)
 	return str
 }
 
-// SegmentCleanupData_Promise is a wrapper for a SegmentCleanupData promised by a client call.
-type SegmentCleanupData_Promise struct{ *capnp.Pipeline }
+// E2ESetupReqData_Promise is a wrapper for a E2ESetupReqData promised by a client call.
+type E2ESetupReqData_Promise struct{ *capnp.Pipeline }
 
-func (p SegmentCleanupData_Promise) Struct() (SegmentCleanupData, error) {
+func (p E2ESetupReqData_Promise) Struct() (E2ESetupReqData, error) {
 	s, err := p.Pipeline.Struct()
-	return SegmentCleanupData{s}, err
+	return E2ESetupReqData{s}, err
 }
 
-func (p SegmentCleanupData_Promise) Id() SegmentReservationID_Promise {
-	return SegmentReservationID_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
+func (p E2ESetupReqData_Promise) Base() E2EBase_Promise {
+	return E2EBase_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
 }
 
-type E2ESetupData struct{ capnp.Struct }
-type E2ESetupData_success E2ESetupData
-type E2ESetupData_failure E2ESetupData
-type E2ESetupData_Which uint16
+func (p E2ESetupReqData_Promise) Success() E2ESetupReqData_success_Promise {
+	return E2ESetupReqData_success_Promise{p.Pipeline}
+}
+
+// E2ESetupReqData_success_Promise is a wrapper for a E2ESetupReqData_success promised by a client call.
+type E2ESetupReqData_success_Promise struct{ *capnp.Pipeline }
+
+func (p E2ESetupReqData_success_Promise) Struct() (E2ESetupReqData_success, error) {
+	s, err := p.Pipeline.Struct()
+	return E2ESetupReqData_success{s}, err
+}
+
+func (p E2ESetupReqData_Promise) Failure() E2ESetupReqData_failure_Promise {
+	return E2ESetupReqData_failure_Promise{p.Pipeline}
+}
+
+// E2ESetupReqData_failure_Promise is a wrapper for a E2ESetupReqData_failure promised by a client call.
+type E2ESetupReqData_failure_Promise struct{ *capnp.Pipeline }
+
+func (p E2ESetupReqData_failure_Promise) Struct() (E2ESetupReqData_failure, error) {
+	s, err := p.Pipeline.Struct()
+	return E2ESetupReqData_failure{s}, err
+}
+
+type E2ESetupResData struct{ capnp.Struct }
+type E2ESetupResData_success E2ESetupResData
+type E2ESetupResData_failure E2ESetupResData
+type E2ESetupResData_Which uint16
 
 const (
-	E2ESetupData_Which_unset   E2ESetupData_Which = 0
-	E2ESetupData_Which_success E2ESetupData_Which = 1
-	E2ESetupData_Which_failure E2ESetupData_Which = 2
+	E2ESetupResData_Which_unset   E2ESetupResData_Which = 0
+	E2ESetupResData_Which_success E2ESetupResData_Which = 1
+	E2ESetupResData_Which_failure E2ESetupResData_Which = 2
 )
 
-func (w E2ESetupData_Which) String() string {
+func (w E2ESetupResData_Which) String() string {
 	const s = "unsetsuccessfailure"
 	switch w {
-	case E2ESetupData_Which_unset:
+	case E2ESetupResData_Which_unset:
 		return s[0:5]
-	case E2ESetupData_Which_success:
+	case E2ESetupResData_Which_success:
 		return s[5:12]
-	case E2ESetupData_Which_failure:
+	case E2ESetupResData_Which_failure:
 		return s[12:19]
 
 	}
-	return "E2ESetupData_Which(" + strconv.FormatUint(uint64(w), 10) + ")"
+	return "E2ESetupResData_Which(" + strconv.FormatUint(uint64(w), 10) + ")"
 }
 
-// E2ESetupData_TypeID is the unique identifier for the type E2ESetupData.
-const E2ESetupData_TypeID = 0xeb535c83335d74cf
+// E2ESetupResData_TypeID is the unique identifier for the type E2ESetupResData.
+const E2ESetupResData_TypeID = 0xb65a7701e86386b2
 
-func NewE2ESetupData(s *capnp.Segment) (E2ESetupData, error) {
+func NewE2ESetupResData(s *capnp.Segment) (E2ESetupResData, error) {
 	st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 3})
-	return E2ESetupData{st}, err
+	return E2ESetupResData{st}, err
 }
 
-func NewRootE2ESetupData(s *capnp.Segment) (E2ESetupData, error) {
+func NewRootE2ESetupResData(s *capnp.Segment) (E2ESetupResData, error) {
 	st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 3})
-	return E2ESetupData{st}, err
+	return E2ESetupResData{st}, err
 }
 
-func ReadRootE2ESetupData(msg *capnp.Message) (E2ESetupData, error) {
+func ReadRootE2ESetupResData(msg *capnp.Message) (E2ESetupResData, error) {
 	root, err := msg.RootPtr()
-	return E2ESetupData{root.Struct()}, err
+	return E2ESetupResData{root.Struct()}, err
 }
 
-func (s E2ESetupData) String() string {
-	str, _ := text.Marshal(0xeb535c83335d74cf, s.Struct)
+func (s E2ESetupResData) String() string {
+	str, _ := text.Marshal(0xb65a7701e86386b2, s.Struct)
 	return str
 }
 
-func (s E2ESetupData) Which() E2ESetupData_Which {
-	return E2ESetupData_Which(s.Struct.Uint16(0))
+func (s E2ESetupResData) Which() E2ESetupResData_Which {
+	return E2ESetupResData_Which(s.Struct.Uint16(0))
 }
-func (s E2ESetupData) ReservationID() (E2EReservationID, error) {
+func (s E2ESetupResData) Base() (E2EBase, error) {
 	p, err := s.Struct.Ptr(0)
-	return E2EReservationID{Struct: p.Struct()}, err
+	return E2EBase{Struct: p.Struct()}, err
 }
 
-func (s E2ESetupData) HasReservationID() bool {
+func (s E2ESetupResData) HasBase() bool {
 	p, err := s.Struct.Ptr(0)
 	return p.IsValid() || err != nil
 }
 
-func (s E2ESetupData) SetReservationID(v E2EReservationID) error {
+func (s E2ESetupResData) SetBase(v E2EBase) error {
 	return s.Struct.SetPtr(0, v.Struct.ToPtr())
 }
 
-// NewReservationID sets the reservationID field to a newly
-// allocated E2EReservationID struct, preferring placement in s's segment.
-func (s E2ESetupData) NewReservationID() (E2EReservationID, error) {
-	ss, err := NewE2EReservationID(s.Struct.Segment())
+// NewBase sets the base field to a newly
+// allocated E2EBase struct, preferring placement in s's segment.
+func (s E2ESetupResData) NewBase() (E2EBase, error) {
+	ss, err := NewE2EBase(s.Struct.Segment())
 	if err != nil {
-		return E2EReservationID{}, err
+		return E2EBase{}, err
 	}
 	err = s.Struct.SetPtr(0, ss.Struct.ToPtr())
 	return ss, err
 }
 
-func (s E2ESetupData) SetUnset() {
+func (s E2ESetupResData) SetUnset() {
 	s.Struct.SetUint16(0, 0)
 
 }
 
-func (s E2ESetupData) Success() E2ESetupData_success { return E2ESetupData_success(s) }
+func (s E2ESetupResData) Success() E2ESetupResData_success { return E2ESetupResData_success(s) }
 
-func (s E2ESetupData) SetSuccess() {
+func (s E2ESetupResData) SetSuccess() {
 	s.Struct.SetUint16(0, 1)
 }
 
-func (s E2ESetupData_success) Token() ([]byte, error) {
+func (s E2ESetupResData_success) Token() ([]byte, error) {
 	p, err := s.Struct.Ptr(1)
 	return []byte(p.Data()), err
 }
 
-func (s E2ESetupData_success) HasToken() bool {
+func (s E2ESetupResData_success) HasToken() bool {
 	p, err := s.Struct.Ptr(1)
 	return p.IsValid() || err != nil
 }
 
-func (s E2ESetupData_success) SetToken(v []byte) error {
+func (s E2ESetupResData_success) SetToken(v []byte) error {
 	return s.Struct.SetData(1, v)
 }
 
-func (s E2ESetupData) Failure() E2ESetupData_failure { return E2ESetupData_failure(s) }
+func (s E2ESetupResData) Failure() E2ESetupResData_failure { return E2ESetupResData_failure(s) }
 
-func (s E2ESetupData) SetFailure() {
+func (s E2ESetupResData) SetFailure() {
 	s.Struct.SetUint16(0, 2)
 }
 
-func (s E2ESetupData_failure) ErrorCode() uint8 {
+func (s E2ESetupResData_failure) ErrorCode() uint8 {
 	return s.Struct.Uint8(2)
 }
 
-func (s E2ESetupData_failure) SetErrorCode(v uint8) {
+func (s E2ESetupResData_failure) SetErrorCode(v uint8) {
 	s.Struct.SetUint8(2, v)
 }
 
-func (s E2ESetupData_failure) InfoField() ([]byte, error) {
+func (s E2ESetupResData_failure) InfoField() ([]byte, error) {
 	p, err := s.Struct.Ptr(1)
 	return []byte(p.Data()), err
 }
 
-func (s E2ESetupData_failure) HasInfoField() bool {
+func (s E2ESetupResData_failure) HasInfoField() bool {
 	p, err := s.Struct.Ptr(1)
 	return p.IsValid() || err != nil
 }
 
-func (s E2ESetupData_failure) SetInfoField(v []byte) error {
+func (s E2ESetupResData_failure) SetInfoField(v []byte) error {
 	return s.Struct.SetData(1, v)
 }
 
-func (s E2ESetupData_failure) MaxBWs() (capnp.UInt8List, error) {
+func (s E2ESetupResData_failure) AllocationTrail() (capnp.UInt8List, error) {
 	p, err := s.Struct.Ptr(2)
 	return capnp.UInt8List{List: p.List()}, err
 }
 
-func (s E2ESetupData_failure) HasMaxBWs() bool {
+func (s E2ESetupResData_failure) HasAllocationTrail() bool {
 	p, err := s.Struct.Ptr(2)
 	return p.IsValid() || err != nil
 }
 
-func (s E2ESetupData_failure) SetMaxBWs(v capnp.UInt8List) error {
+func (s E2ESetupResData_failure) SetAllocationTrail(v capnp.UInt8List) error {
 	return s.Struct.SetPtr(2, v.List.ToPtr())
 }
 
-// NewMaxBWs sets the maxBWs field to a newly
+// NewAllocationTrail sets the allocationTrail field to a newly
 // allocated capnp.UInt8List, preferring placement in s's segment.
-func (s E2ESetupData_failure) NewMaxBWs(n int32) (capnp.UInt8List, error) {
+func (s E2ESetupResData_failure) NewAllocationTrail(n int32) (capnp.UInt8List, error) {
 	l, err := capnp.NewUInt8List(s.Struct.Segment(), n)
 	if err != nil {
 		return capnp.UInt8List{}, err
@@ -1228,58 +1946,60 @@ func (s E2ESetupData_failure) NewMaxBWs(n int32) (capnp.UInt8List, error) {
 	return l, err
 }
 
-// E2ESetupData_List is a list of E2ESetupData.
-type E2ESetupData_List struct{ capnp.List }
+// E2ESetupResData_List is a list of E2ESetupResData.
+type E2ESetupResData_List struct{ capnp.List }
 
-// NewE2ESetupData creates a new list of E2ESetupData.
-func NewE2ESetupData_List(s *capnp.Segment, sz int32) (E2ESetupData_List, error) {
+// NewE2ESetupResData creates a new list of E2ESetupResData.
+func NewE2ESetupResData_List(s *capnp.Segment, sz int32) (E2ESetupResData_List, error) {
 	l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 3}, sz)
-	return E2ESetupData_List{l}, err
+	return E2ESetupResData_List{l}, err
 }
 
-func (s E2ESetupData_List) At(i int) E2ESetupData { return E2ESetupData{s.List.Struct(i)} }
+func (s E2ESetupResData_List) At(i int) E2ESetupResData { return E2ESetupResData{s.List.Struct(i)} }
 
-func (s E2ESetupData_List) Set(i int, v E2ESetupData) error { return s.List.SetStruct(i, v.Struct) }
+func (s E2ESetupResData_List) Set(i int, v E2ESetupResData) error {
+	return s.List.SetStruct(i, v.Struct)
+}
 
-func (s E2ESetupData_List) String() string {
-	str, _ := text.MarshalList(0xeb535c83335d74cf, s.List)
+func (s E2ESetupResData_List) String() string {
+	str, _ := text.MarshalList(0xb65a7701e86386b2, s.List)
 	return str
 }
 
-// E2ESetupData_Promise is a wrapper for a E2ESetupData promised by a client call.
-type E2ESetupData_Promise struct{ *capnp.Pipeline }
+// E2ESetupResData_Promise is a wrapper for a E2ESetupResData promised by a client call.
+type E2ESetupResData_Promise struct{ *capnp.Pipeline }
 
-func (p E2ESetupData_Promise) Struct() (E2ESetupData, error) {
+func (p E2ESetupResData_Promise) Struct() (E2ESetupResData, error) {
 	s, err := p.Pipeline.Struct()
-	return E2ESetupData{s}, err
+	return E2ESetupResData{s}, err
 }
 
-func (p E2ESetupData_Promise) ReservationID() E2EReservationID_Promise {
-	return E2EReservationID_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
+func (p E2ESetupResData_Promise) Base() E2EBase_Promise {
+	return E2EBase_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
 }
 
-func (p E2ESetupData_Promise) Success() E2ESetupData_success_Promise {
-	return E2ESetupData_success_Promise{p.Pipeline}
+func (p E2ESetupResData_Promise) Success() E2ESetupResData_success_Promise {
+	return E2ESetupResData_success_Promise{p.Pipeline}
 }
 
-// E2ESetupData_success_Promise is a wrapper for a E2ESetupData_success promised by a client call.
-type E2ESetupData_success_Promise struct{ *capnp.Pipeline }
+// E2ESetupResData_success_Promise is a wrapper for a E2ESetupResData_success promised by a client call.
+type E2ESetupResData_success_Promise struct{ *capnp.Pipeline }
 
-func (p E2ESetupData_success_Promise) Struct() (E2ESetupData_success, error) {
+func (p E2ESetupResData_success_Promise) Struct() (E2ESetupResData_success, error) {
 	s, err := p.Pipeline.Struct()
-	return E2ESetupData_success{s}, err
+	return E2ESetupResData_success{s}, err
 }
 
-func (p E2ESetupData_Promise) Failure() E2ESetupData_failure_Promise {
-	return E2ESetupData_failure_Promise{p.Pipeline}
+func (p E2ESetupResData_Promise) Failure() E2ESetupResData_failure_Promise {
+	return E2ESetupResData_failure_Promise{p.Pipeline}
 }
 
-// E2ESetupData_failure_Promise is a wrapper for a E2ESetupData_failure promised by a client call.
-type E2ESetupData_failure_Promise struct{ *capnp.Pipeline }
+// E2ESetupResData_failure_Promise is a wrapper for a E2ESetupResData_failure promised by a client call.
+type E2ESetupResData_failure_Promise struct{ *capnp.Pipeline }
 
-func (p E2ESetupData_failure_Promise) Struct() (E2ESetupData_failure, error) {
+func (p E2ESetupResData_failure_Promise) Struct() (E2ESetupResData_failure, error) {
 	s, err := p.Pipeline.Struct()
-	return E2ESetupData_failure{s}, err
+	return E2ESetupResData_failure{s}, err
 }
 
 type E2ECleanupData struct{ capnp.Struct }
@@ -1288,12 +2008,12 @@ type E2ECleanupData struct{ capnp.Struct }
 const E2ECleanupData_TypeID = 0x96ec60724ebd66d7
 
 func NewE2ECleanupData(s *capnp.Segment) (E2ECleanupData, error) {
-	st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1})
+	st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1})
 	return E2ECleanupData{st}, err
 }
 
 func NewRootE2ECleanupData(s *capnp.Segment) (E2ECleanupData, error) {
-	st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1})
+	st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1})
 	return E2ECleanupData{st}, err
 }
 
@@ -1307,45 +2027,37 @@ func (s E2ECleanupData) String() string {
 	return str
 }
 
-func (s E2ECleanupData) ReservationID() (E2EReservationID, error) {
+func (s E2ECleanupData) Base() (E2EBase, error) {
 	p, err := s.Struct.Ptr(0)
-	return E2EReservationID{Struct: p.Struct()}, err
+	return E2EBase{Struct: p.Struct()}, err
 }
 
-func (s E2ECleanupData) HasReservationID() bool {
+func (s E2ECleanupData) HasBase() bool {
 	p, err := s.Struct.Ptr(0)
 	return p.IsValid() || err != nil
 }
 
-func (s E2ECleanupData) SetReservationID(v E2EReservationID) error {
+func (s E2ECleanupData) SetBase(v E2EBase) error {
 	return s.Struct.SetPtr(0, v.Struct.ToPtr())
 }
 
-// NewReservationID sets the reservationID field to a newly
-// allocated E2EReservationID struct, preferring placement in s's segment.
-func (s E2ECleanupData) NewReservationID() (E2EReservationID, error) {
-	ss, err := NewE2EReservationID(s.Struct.Segment())
+// NewBase sets the base field to a newly
+// allocated E2EBase struct, preferring placement in s's segment.
+func (s E2ECleanupData) NewBase() (E2EBase, error) {
+	ss, err := NewE2EBase(s.Struct.Segment())
 	if err != nil {
-		return E2EReservationID{}, err
+		return E2EBase{}, err
 	}
 	err = s.Struct.SetPtr(0, ss.Struct.ToPtr())
 	return ss, err
 }
 
-func (s E2ECleanupData) Index() uint8 {
-	return s.Struct.Uint8(0)
-}
-
-func (s E2ECleanupData) SetIndex(v uint8) {
-	s.Struct.SetUint8(0, v)
-}
-
 // E2ECleanupData_List is a list of E2ECleanupData.
 type E2ECleanupData_List struct{ capnp.List }
 
 // NewE2ECleanupData creates a new list of E2ECleanupData.
 func NewE2ECleanupData_List(s *capnp.Segment, sz int32) (E2ECleanupData_List, error) {
-	l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}, sz)
+	l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 1}, sz)
 	return E2ECleanupData_List{l}, err
 }
 
@@ -1366,8 +2078,100 @@ func (p E2ECleanupData_Promise) Struct() (E2ECleanupData, error) {
 	return E2ECleanupData{s}, err
 }
 
-func (p E2ECleanupData_Promise) ReservationID() E2EReservationID_Promise {
-	return E2EReservationID_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
+func (p E2ECleanupData_Promise) Base() E2EBase_Promise {
+	return E2EBase_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
+}
+
+type E2ECleanupResData struct{ capnp.Struct }
+
+// E2ECleanupResData_TypeID is the unique identifier for the type E2ECleanupResData.
+const E2ECleanupResData_TypeID = 0xe04f6146370056c9
+
+func NewE2ECleanupResData(s *capnp.Segment) (E2ECleanupResData, error) {
+	st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1})
+	return E2ECleanupResData{st}, err
+}
+
+func NewRootE2ECleanupResData(s *capnp.Segment) (E2ECleanupResData, error) {
+	st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1})
+	return E2ECleanupResData{st}, err
+}
+
+func ReadRootE2ECleanupResData(msg *capnp.Message) (E2ECleanupResData, error) {
+	root, err := msg.RootPtr()
+	return E2ECleanupResData{root.Struct()}, err
+}
+
+func (s E2ECleanupResData) String() string {
+	str, _ := text.Marshal(0xe04f6146370056c9, s.Struct)
+	return str
+}
+
+func (s E2ECleanupResData) Base() (E2EBase, error) {
+	p, err := s.Struct.Ptr(0)
+	return E2EBase{Struct: p.Struct()}, err
+}
+
+func (s E2ECleanupResData) HasBase() bool {
+	p, err := s.Struct.Ptr(0)
+	return p.IsValid() || err != nil
+}
+
+func (s E2ECleanupResData) SetBase(v E2EBase) error {
+	return s.Struct.SetPtr(0, v.Struct.ToPtr())
+}
+
+// NewBase sets the base field to a newly
+// allocated E2EBase struct, preferring placement in s's segment.
+func (s E2ECleanupResData) NewBase() (E2EBase, error) {
+	ss, err := NewE2EBase(s.Struct.Segment())
+	if err != nil {
+		return E2EBase{}, err
+	}
+	err = s.Struct.SetPtr(0, ss.Struct.ToPtr())
+	return ss, err
+}
+
+func (s E2ECleanupResData) ErrorCode() uint8 {
+	return s.Struct.Uint8(0)
+}
+
+func (s E2ECleanupResData) SetErrorCode(v uint8) {
+	s.Struct.SetUint8(0, v)
+}
+
+// E2ECleanupResData_List is a list of E2ECleanupResData.
+type E2ECleanupResData_List struct{ capnp.List }
+
+// NewE2ECleanupResData creates a new list of E2ECleanupResData.
+func NewE2ECleanupResData_List(s *capnp.Segment, sz int32) (E2ECleanupResData_List, error) {
+	l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 1}, sz)
+	return E2ECleanupResData_List{l}, err
+}
+
+func (s E2ECleanupResData_List) At(i int) E2ECleanupResData {
+	return E2ECleanupResData{s.List.Struct(i)}
+}
+
+func (s E2ECleanupResData_List) Set(i int, v E2ECleanupResData) error {
+	return s.List.SetStruct(i, v.Struct)
+}
+
+func (s E2ECleanupResData_List) String() string {
+	str, _ := text.MarshalList(0xe04f6146370056c9, s.List)
+	return str
+}
+
+// E2ECleanupResData_Promise is a wrapper for a E2ECleanupResData promised by a client call.
+type E2ECleanupResData_Promise struct{ *capnp.Pipeline }
+
+func (p E2ECleanupResData_Promise) Struct() (E2ECleanupResData, error) {
+	s, err := p.Pipeline.Struct()
+	return E2ECleanupResData{s}, err
+}
+
+func (p E2ECleanupResData_Promise) Base() E2EBase_Promise {
+	return E2EBase_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
 }
 
 type Request struct{ capnp.Struct }
@@ -1679,12 +2483,12 @@ func (s Request) NewSegmentCleanup() (SegmentCleanupData, error) {
 	return ss, err
 }
 
-func (s Request) E2eSetup() (E2ESetupData, error) {
+func (s Request) E2eSetup() (E2ESetupReqData, error) {
 	if s.Struct.Uint16(0) != 8 {
 		panic("Which() != e2eSetup")
 	}
 	p, err := s.Struct.Ptr(0)
-	return E2ESetupData{Struct: p.Struct()}, err
+	return E2ESetupReqData{Struct: p.Struct()}, err
 }
 
 func (s Request) HasE2eSetup() bool {
@@ -1695,29 +2499,29 @@ func (s Request) HasE2eSetup() bool {
 	return p.IsValid() || err != nil
 }
 
-func (s Request) SetE2eSetup(v E2ESetupData) error {
+func (s Request) SetE2eSetup(v E2ESetupReqData) error {
 	s.Struct.SetUint16(0, 8)
 	return s.Struct.SetPtr(0, v.Struct.ToPtr())
 }
 
 // NewE2eSetup sets the e2eSetup field to a newly
-// allocated E2ESetupData struct, preferring placement in s's segment.
-func (s Request) NewE2eSetup() (E2ESetupData, error) {
+// allocated E2ESetupReqData struct, preferring placement in s's segment.
+func (s Request) NewE2eSetup() (E2ESetupReqData, error) {
 	s.Struct.SetUint16(0, 8)
-	ss, err := NewE2ESetupData(s.Struct.Segment())
+	ss, err := NewE2ESetupReqData(s.Struct.Segment())
 	if err != nil {
-		return E2ESetupData{}, err
+		return E2ESetupReqData{}, err
 	}
 	err = s.Struct.SetPtr(0, ss.Struct.ToPtr())
 	return ss, err
 }
 
-func (s Request) E2eRenewal() (E2ESetupData, error) {
+func (s Request) E2eRenewal() (E2ESetupReqData, error) {
 	if s.Struct.Uint16(0) != 9 {
 		panic("Which() != e2eRenewal")
 	}
 	p, err := s.Struct.Ptr(0)
-	return E2ESetupData{Struct: p.Struct()}, err
+	return E2ESetupReqData{Struct: p.Struct()}, err
 }
 
 func (s Request) HasE2eRenewal() bool {
@@ -1728,18 +2532,18 @@ func (s Request) HasE2eRenewal() bool {
 	return p.IsValid() || err != nil
 }
 
-func (s Request) SetE2eRenewal(v E2ESetupData) error {
+func (s Request) SetE2eRenewal(v E2ESetupReqData) error {
 	s.Struct.SetUint16(0, 9)
 	return s.Struct.SetPtr(0, v.Struct.ToPtr())
 }
 
 // NewE2eRenewal sets the e2eRenewal field to a newly
-// allocated E2ESetupData struct, preferring placement in s's segment.
-func (s Request) NewE2eRenewal() (E2ESetupData, error) {
+// allocated E2ESetupReqData struct, preferring placement in s's segment.
+func (s Request) NewE2eRenewal() (E2ESetupReqData, error) {
 	s.Struct.SetUint16(0, 9)
-	ss, err := NewE2ESetupData(s.Struct.Segment())
+	ss, err := NewE2ESetupReqData(s.Struct.Segment())
 	if err != nil {
-		return E2ESetupData{}, err
+		return E2ESetupReqData{}, err
 	}
 	err = s.Struct.SetPtr(0, ss.Struct.ToPtr())
 	return ss, err
@@ -1832,12 +2636,12 @@ func (p Request_Promise) SegmentCleanup() SegmentCleanupData_Promise {
 	return SegmentCleanupData_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
 }
 
-func (p Request_Promise) E2eSetup() E2ESetupData_Promise {
-	return E2ESetupData_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
+func (p Request_Promise) E2eSetup() E2ESetupReqData_Promise {
+	return E2ESetupReqData_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
 }
 
-func (p Request_Promise) E2eRenewal() E2ESetupData_Promise {
-	return E2ESetupData_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
+func (p Request_Promise) E2eRenewal() E2ESetupReqData_Promise {
+	return E2ESetupReqData_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
 }
 
 func (p Request_Promise) E2eCleanup() E2ECleanupData_Promise {
@@ -1851,18 +2655,16 @@ const (
 	Response_Which_unset                    Response_Which = 0
 	Response_Which_segmentSetup             Response_Which = 1
 	Response_Which_segmentRenewal           Response_Which = 2
-	Response_Which_segmentTelesSetup        Response_Which = 3
-	Response_Which_segmentTelesRenewal      Response_Which = 4
-	Response_Which_segmentTeardown          Response_Which = 5
-	Response_Which_segmentIndexConfirmation Response_Which = 6
-	Response_Which_segmentCleanup           Response_Which = 7
-	Response_Which_e2eSetup                 Response_Which = 8
-	Response_Which_e2eRenewal               Response_Which = 9
-	Response_Which_e2eCleanup               Response_Which = 10
+	Response_Which_segmentTeardown          Response_Which = 3
+	Response_Which_segmentIndexConfirmation Response_Which = 4
+	Response_Which_segmentCleanup           Response_Which = 5
+	Response_Which_e2eSetup                 Response_Which = 6
+	Response_Which_e2eRenewal               Response_Which = 7
+	Response_Which_e2eCleanup               Response_Which = 8
 )
 
 func (w Response_Which) String() string {
-	const s = "unsetsegmentSetupsegmentRenewalsegmentTelesSetupsegmentTelesRenewalsegmentTeardownsegmentIndexConfirmationsegmentCleanupe2eSetupe2eRenewale2eCleanup"
+	const s = "unsetsegmentSetupsegmentRenewalsegmentTeardownsegmentIndexConfirmationsegmentCleanupe2eSetupe2eRenewale2eCleanup"
 	switch w {
 	case Response_Which_unset:
 		return s[0:5]
@@ -1870,22 +2672,18 @@ func (w Response_Which) String() string {
 		return s[5:17]
 	case Response_Which_segmentRenewal:
 		return s[17:31]
-	case Response_Which_segmentTelesSetup:
-		return s[31:48]
-	case Response_Which_segmentTelesRenewal:
-		return s[48:67]
 	case Response_Which_segmentTeardown:
-		return s[67:82]
+		return s[31:46]
 	case Response_Which_segmentIndexConfirmation:
-		return s[82:106]
+		return s[46:70]
 	case Response_Which_segmentCleanup:
-		return s[106:120]
+		return s[70:84]
 	case Response_Which_e2eSetup:
-		return s[120:128]
+		return s[84:92]
 	case Response_Which_e2eRenewal:
-		return s[128:138]
+		return s[92:102]
 	case Response_Which_e2eCleanup:
-		return s[138:148]
+		return s[102:112]
 
 	}
 	return "Response_Which(" + strconv.FormatUint(uint64(w), 10) + ")"
@@ -1988,74 +2786,8 @@ func (s Response) NewSegmentRenewal() (SegmentSetupResData, error) {
 	return ss, err
 }
 
-func (s Response) SegmentTelesSetup() (SegmentSetupResData, error) {
-	if s.Struct.Uint16(0) != 3 {
-		panic("Which() != segmentTelesSetup")
-	}
-	p, err := s.Struct.Ptr(0)
-	return SegmentSetupResData{Struct: p.Struct()}, err
-}
-
-func (s Response) HasSegmentTelesSetup() bool {
-	if s.Struct.Uint16(0) != 3 {
-		return false
-	}
-	p, err := s.Struct.Ptr(0)
-	return p.IsValid() || err != nil
-}
-
-func (s Response) SetSegmentTelesSetup(v SegmentSetupResData) error {
-	s.Struct.SetUint16(0, 3)
-	return s.Struct.SetPtr(0, v.Struct.ToPtr())
-}
-
-// NewSegmentTelesSetup sets the segmentTelesSetup field to a newly
-// allocated SegmentSetupResData struct, preferring placement in s's segment.
-func (s Response) NewSegmentTelesSetup() (SegmentSetupResData, error) {
-	s.Struct.SetUint16(0, 3)
-	ss, err := NewSegmentSetupResData(s.Struct.Segment())
-	if err != nil {
-		return SegmentSetupResData{}, err
-	}
-	err = s.Struct.SetPtr(0, ss.Struct.ToPtr())
-	return ss, err
-}
-
-func (s Response) SegmentTelesRenewal() (SegmentSetupResData, error) {
-	if s.Struct.Uint16(0) != 4 {
-		panic("Which() != segmentTelesRenewal")
-	}
-	p, err := s.Struct.Ptr(0)
-	return SegmentSetupResData{Struct: p.Struct()}, err
-}
-
-func (s Response) HasSegmentTelesRenewal() bool {
-	if s.Struct.Uint16(0) != 4 {
-		return false
-	}
-	p, err := s.Struct.Ptr(0)
-	return p.IsValid() || err != nil
-}
-
-func (s Response) SetSegmentTelesRenewal(v SegmentSetupResData) error {
-	s.Struct.SetUint16(0, 4)
-	return s.Struct.SetPtr(0, v.Struct.ToPtr())
-}
-
-// NewSegmentTelesRenewal sets the segmentTelesRenewal field to a newly
-// allocated SegmentSetupResData struct, preferring placement in s's segment.
-func (s Response) NewSegmentTelesRenewal() (SegmentSetupResData, error) {
-	s.Struct.SetUint16(0, 4)
-	ss, err := NewSegmentSetupResData(s.Struct.Segment())
-	if err != nil {
-		return SegmentSetupResData{}, err
-	}
-	err = s.Struct.SetPtr(0, ss.Struct.ToPtr())
-	return ss, err
-}
-
 func (s Response) SegmentTeardown() (SegmentTeardownResData, error) {
-	if s.Struct.Uint16(0) != 5 {
+	if s.Struct.Uint16(0) != 3 {
 		panic("Which() != segmentTeardown")
 	}
 	p, err := s.Struct.Ptr(0)
@@ -2063,7 +2795,7 @@ func (s Response) SegmentTeardown() (SegmentTeardownResData, error) {
 }
 
 func (s Response) HasSegmentTeardown() bool {
-	if s.Struct.Uint16(0) != 5 {
+	if s.Struct.Uint16(0) != 3 {
 		return false
 	}
 	p, err := s.Struct.Ptr(0)
@@ -2071,14 +2803,14 @@ func (s Response) HasSegmentTeardown() bool {
 }
 
 func (s Response) SetSegmentTeardown(v SegmentTeardownResData) error {
-	s.Struct.SetUint16(0, 5)
+	s.Struct.SetUint16(0, 3)
 	return s.Struct.SetPtr(0, v.Struct.ToPtr())
 }
 
 // NewSegmentTeardown sets the segmentTeardown field to a newly
 // allocated SegmentTeardownResData struct, preferring placement in s's segment.
 func (s Response) NewSegmentTeardown() (SegmentTeardownResData, error) {
-	s.Struct.SetUint16(0, 5)
+	s.Struct.SetUint16(0, 3)
 	ss, err := NewSegmentTeardownResData(s.Struct.Segment())
 	if err != nil {
 		return SegmentTeardownResData{}, err
@@ -2087,166 +2819,166 @@ func (s Response) NewSegmentTeardown() (SegmentTeardownResData, error) {
 	return ss, err
 }
 
-func (s Response) SegmentIndexConfirmation() (SegmentIndexConfirmationData, error) {
-	if s.Struct.Uint16(0) != 6 {
+func (s Response) SegmentIndexConfirmation() (SegmentIndexConfirmationResData, error) {
+	if s.Struct.Uint16(0) != 4 {
 		panic("Which() != segmentIndexConfirmation")
 	}
 	p, err := s.Struct.Ptr(0)
-	return SegmentIndexConfirmationData{Struct: p.Struct()}, err
+	return SegmentIndexConfirmationResData{Struct: p.Struct()}, err
 }
 
 func (s Response) HasSegmentIndexConfirmation() bool {
-	if s.Struct.Uint16(0) != 6 {
+	if s.Struct.Uint16(0) != 4 {
 		return false
 	}
 	p, err := s.Struct.Ptr(0)
 	return p.IsValid() || err != nil
 }
 
-func (s Response) SetSegmentIndexConfirmation(v SegmentIndexConfirmationData) error {
-	s.Struct.SetUint16(0, 6)
+func (s Response) SetSegmentIndexConfirmation(v SegmentIndexConfirmationResData) error {
+	s.Struct.SetUint16(0, 4)
 	return s.Struct.SetPtr(0, v.Struct.ToPtr())
 }
 
 // NewSegmentIndexConfirmation sets the segmentIndexConfirmation field to a newly
-// allocated SegmentIndexConfirmationData struct, preferring placement in s's segment.
-func (s Response) NewSegmentIndexConfirmation() (SegmentIndexConfirmationData, error) {
-	s.Struct.SetUint16(0, 6)
-	ss, err := NewSegmentIndexConfirmationData(s.Struct.Segment())
+// allocated SegmentIndexConfirmationResData struct, preferring placement in s's segment.
+func (s Response) NewSegmentIndexConfirmation() (SegmentIndexConfirmationResData, error) {
+	s.Struct.SetUint16(0, 4)
+	ss, err := NewSegmentIndexConfirmationResData(s.Struct.Segment())
 	if err != nil {
-		return SegmentIndexConfirmationData{}, err
+		return SegmentIndexConfirmationResData{}, err
 	}
 	err = s.Struct.SetPtr(0, ss.Struct.ToPtr())
 	return ss, err
 }
 
-func (s Response) SegmentCleanup() (SegmentCleanupData, error) {
-	if s.Struct.Uint16(0) != 7 {
+func (s Response) SegmentCleanup() (SegmentCleanupResData, error) {
+	if s.Struct.Uint16(0) != 5 {
 		panic("Which() != segmentCleanup")
 	}
 	p, err := s.Struct.Ptr(0)
-	return SegmentCleanupData{Struct: p.Struct()}, err
+	return SegmentCleanupResData{Struct: p.Struct()}, err
 }
 
 func (s Response) HasSegmentCleanup() bool {
-	if s.Struct.Uint16(0) != 7 {
+	if s.Struct.Uint16(0) != 5 {
 		return false
 	}
 	p, err := s.Struct.Ptr(0)
 	return p.IsValid() || err != nil
 }
 
-func (s Response) SetSegmentCleanup(v SegmentCleanupData) error {
-	s.Struct.SetUint16(0, 7)
+func (s Response) SetSegmentCleanup(v SegmentCleanupResData) error {
+	s.Struct.SetUint16(0, 5)
 	return s.Struct.SetPtr(0, v.Struct.ToPtr())
 }
 
 // NewSegmentCleanup sets the segmentCleanup field to a newly
-// allocated SegmentCleanupData struct, preferring placement in s's segment.
-func (s Response) NewSegmentCleanup() (SegmentCleanupData, error) {
-	s.Struct.SetUint16(0, 7)
-	ss, err := NewSegmentCleanupData(s.Struct.Segment())
+// allocated SegmentCleanupResData struct, preferring placement in s's segment.
+func (s Response) NewSegmentCleanup() (SegmentCleanupResData, error) {
+	s.Struct.SetUint16(0, 5)
+	ss, err := NewSegmentCleanupResData(s.Struct.Segment())
 	if err != nil {
-		return SegmentCleanupData{}, err
+		return SegmentCleanupResData{}, err
 	}
 	err = s.Struct.SetPtr(0, ss.Struct.ToPtr())
 	return ss, err
 }
 
-func (s Response) E2eSetup() (E2ESetupData, error) {
-	if s.Struct.Uint16(0) != 8 {
+func (s Response) E2eSetup() (E2ESetupResData, error) {
+	if s.Struct.Uint16(0) != 6 {
 		panic("Which() != e2eSetup")
 	}
 	p, err := s.Struct.Ptr(0)
-	return E2ESetupData{Struct: p.Struct()}, err
+	return E2ESetupResData{Struct: p.Struct()}, err
 }
 
 func (s Response) HasE2eSetup() bool {
-	if s.Struct.Uint16(0) != 8 {
+	if s.Struct.Uint16(0) != 6 {
 		return false
 	}
 	p, err := s.Struct.Ptr(0)
 	return p.IsValid() || err != nil
 }
 
-func (s Response) SetE2eSetup(v E2ESetupData) error {
-	s.Struct.SetUint16(0, 8)
+func (s Response) SetE2eSetup(v E2ESetupResData) error {
+	s.Struct.SetUint16(0, 6)
 	return s.Struct.SetPtr(0, v.Struct.ToPtr())
 }
 
 // NewE2eSetup sets the e2eSetup field to a newly
-// allocated E2ESetupData struct, preferring placement in s's segment.
-func (s Response) NewE2eSetup() (E2ESetupData, error) {
-	s.Struct.SetUint16(0, 8)
-	ss, err := NewE2ESetupData(s.Struct.Segment())
+// allocated E2ESetupResData struct, preferring placement in s's segment.
+func (s Response) NewE2eSetup() (E2ESetupResData, error) {
+	s.Struct.SetUint16(0, 6)
+	ss, err := NewE2ESetupResData(s.Struct.Segment())
 	if err != nil {
-		return E2ESetupData{}, err
+		return E2ESetupResData{}, err
 	}
 	err = s.Struct.SetPtr(0, ss.Struct.ToPtr())
 	return ss, err
 }
 
-func (s Response) E2eRenewal() (E2ESetupData, error) {
-	if s.Struct.Uint16(0) != 9 {
+func (s Response) E2eRenewal() (E2ESetupResData, error) {
+	if s.Struct.Uint16(0) != 7 {
 		panic("Which() != e2eRenewal")
 	}
 	p, err := s.Struct.Ptr(0)
-	return E2ESetupData{Struct: p.Struct()}, err
+	return E2ESetupResData{Struct: p.Struct()}, err
 }
 
 func (s Response) HasE2eRenewal() bool {
-	if s.Struct.Uint16(0) != 9 {
+	if s.Struct.Uint16(0) != 7 {
 		return false
 	}
 	p, err := s.Struct.Ptr(0)
 	return p.IsValid() || err != nil
 }
 
-func (s Response) SetE2eRenewal(v E2ESetupData) error {
-	s.Struct.SetUint16(0, 9)
+func (s Response) SetE2eRenewal(v E2ESetupResData) error {
+	s.Struct.SetUint16(0, 7)
 	return s.Struct.SetPtr(0, v.Struct.ToPtr())
 }
 
 // NewE2eRenewal sets the e2eRenewal field to a newly
-// allocated E2ESetupData struct, preferring placement in s's segment.
-func (s Response) NewE2eRenewal() (E2ESetupData, error) {
-	s.Struct.SetUint16(0, 9)
-	ss, err := NewE2ESetupData(s.Struct.Segment())
+// allocated E2ESetupResData struct, preferring placement in s's segment.
+func (s Response) NewE2eRenewal() (E2ESetupResData, error) {
+	s.Struct.SetUint16(0, 7)
+	ss, err := NewE2ESetupResData(s.Struct.Segment())
 	if err != nil {
-		return E2ESetupData{}, err
+		return E2ESetupResData{}, err
 	}
 	err = s.Struct.SetPtr(0, ss.Struct.ToPtr())
 	return ss, err
 }
 
-func (s Response) E2eCleanup() (E2ECleanupData, error) {
-	if s.Struct.Uint16(0) != 10 {
+func (s Response) E2eCleanup() (E2ECleanupResData, error) {
+	if s.Struct.Uint16(0) != 8 {
 		panic("Which() != e2eCleanup")
 	}
 	p, err := s.Struct.Ptr(0)
-	return E2ECleanupData{Struct: p.Struct()}, err
+	return E2ECleanupResData{Struct: p.Struct()}, err
 }
 
 func (s Response) HasE2eCleanup() bool {
-	if s.Struct.Uint16(0) != 10 {
+	if s.Struct.Uint16(0) != 8 {
 		return false
 	}
 	p, err := s.Struct.Ptr(0)
 	return p.IsValid() || err != nil
 }
 
-func (s Response) SetE2eCleanup(v E2ECleanupData) error {
-	s.Struct.SetUint16(0, 10)
+func (s Response) SetE2eCleanup(v E2ECleanupResData) error {
+	s.Struct.SetUint16(0, 8)
 	return s.Struct.SetPtr(0, v.Struct.ToPtr())
 }
 
 // NewE2eCleanup sets the e2eCleanup field to a newly
-// allocated E2ECleanupData struct, preferring placement in s's segment.
-func (s Response) NewE2eCleanup() (E2ECleanupData, error) {
-	s.Struct.SetUint16(0, 10)
-	ss, err := NewE2ECleanupData(s.Struct.Segment())
+// allocated E2ECleanupResData struct, preferring placement in s's segment.
+func (s Response) NewE2eCleanup() (E2ECleanupResData, error) {
+	s.Struct.SetUint16(0, 8)
+	ss, err := NewE2ECleanupResData(s.Struct.Segment())
 	if err != nil {
-		return E2ECleanupData{}, err
+		return E2ECleanupResData{}, err
 	}
 	err = s.Struct.SetPtr(0, ss.Struct.ToPtr())
 	return ss, err
@@ -2302,36 +3034,28 @@ func (p Response_Promise) SegmentRenewal() SegmentSetupResData_Promise {
 	return SegmentSetupResData_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
 }
 
-func (p Response_Promise) SegmentTelesSetup() SegmentSetupResData_Promise {
-	return SegmentSetupResData_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
-}
-
-func (p Response_Promise) SegmentTelesRenewal() SegmentSetupResData_Promise {
-	return SegmentSetupResData_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
-}
-
 func (p Response_Promise) SegmentTeardown() SegmentTeardownResData_Promise {
 	return SegmentTeardownResData_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
 }
 
-func (p Response_Promise) SegmentIndexConfirmation() SegmentIndexConfirmationData_Promise {
-	return SegmentIndexConfirmationData_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
+func (p Response_Promise) SegmentIndexConfirmation() SegmentIndexConfirmationResData_Promise {
+	return SegmentIndexConfirmationResData_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
 }
 
-func (p Response_Promise) SegmentCleanup() SegmentCleanupData_Promise {
-	return SegmentCleanupData_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
+func (p Response_Promise) SegmentCleanup() SegmentCleanupResData_Promise {
+	return SegmentCleanupResData_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
 }
 
-func (p Response_Promise) E2eSetup() E2ESetupData_Promise {
-	return E2ESetupData_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
+func (p Response_Promise) E2eSetup() E2ESetupResData_Promise {
+	return E2ESetupResData_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
 }
 
-func (p Response_Promise) E2eRenewal() E2ESetupData_Promise {
-	return E2ESetupData_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
+func (p Response_Promise) E2eRenewal() E2ESetupResData_Promise {
+	return E2ESetupResData_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
 }
 
-func (p Response_Promise) E2eCleanup() E2ECleanupData_Promise {
-	return E2ECleanupData_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
+func (p Response_Promise) E2eCleanup() E2ECleanupResData_Promise {
+	return E2ECleanupResData_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
 }
 
 type ColibriRequestPayload struct{ capnp.Struct }
@@ -2500,148 +3224,177 @@ func (p ColibriRequestPayload_Promise) Response() Response_Promise {
 	return Response_Promise{Pipeline: p.Pipeline.GetPipeline(0)}
 }
 
-const schema_a3bf9fed859570f0 = "x\xda\xd4W}\x8c\\U\x15?\xe7\xde\xf9lww" +
-	"f\xfa\xc6@\xea\xc7h\x03di\xfa\xb9[\xa2\xad\x85" +
-	"\x81\xdd\x1d\xed\xd6\xa2\xf3f\xb6\xb1\xd66\xf4u\xe7." +
-	"\xfbt\xe6\xbd\x99\xf7\xde\xb6\xc5P\x0b\xb5$\x1a\xd4Z" +
-	"\xe2\xd7?\xa2E\x1aE\x9b\x80\x06\x12i\x8a\x82i\xd3" +
-	"\x15J\xb4\x11\x84\x12\xaa\x18m\x88`\x0d\x92XX\x94" +
-	">s\xee\x9byo>\xbb\xfd\xc3\x7f\xfco\xe6\xfe~" +
-	"\xef\xdes\xcf\xf9\x9d\x8f\xbbjy\xf8f\xb6:|0" +
-	"\x02\xa0n\x0aG\xdc\x03s\x9b\xb6\xfd\xf4\xd7\x7f\xb8\x17" +
-	"\xd4\x01D\xf7\x8d\xea\xb7\xee\xb9\xf0\xfd_\xfd\x10BQ" +
-	"\x80\xe1\xe5|)*7\xf2(\x80\xb2\x96g\x01\xdd\xc7" +
-	".\xbd\xfa\xe2\x9b\xb3\xff\xf8:\xa4\x06\x9a\xb8aF\xe4" +
-	"\xed|1*\x15I\xd6\xf9n@\xf7\x85\xa9'>i" +
-	"\xed\xf8\xfb\xb7\xdbv\x0e#QN\xf2\xd7\x943\x92\xfc" +
-	"\xac$\xdf\xb6d\xe7_nz\xe6\xe2w@}/\xa2" +
-	"\xfb[g\xfb\xf0\x97\xb6\x15_\x87\xf7\xf0(\x92!\xa1" +
-	"\xc5\x08\xa8\xdc\x10\"#\xbe8\xf8\xfa\x83\xbft*\x0f" +
-	"\xb4\xef+M\xde\x1cZ\x84\x8a\x90?\xb5\xd0A\x04t" +
-	"\xa7O.\xfc\xec\x85O|\xf4H\xab\xcd\x92\xd1\x1fY" +
-	"\x8a\xca\xfb#Q\xe0\xee\xb1\xc1\xbf\xde{\xe3\xc3\xc5\x87" +
-	"\xba\xddl.\xbc\x04\x95x\x84\x8c\x0dG\xc8\xd8#+" +
-	"W\x9c\x9aP\xd7\xfc\xa4\xcd\x82\x1cF9\x9d\x1bY\x84" +
-	"JM\xd2+\x91\x87\x01\xdd\xeb\xcem?\xb8\xc8=z" +
-	"\xbc\x8b\x8b\x95p\xf4%%\x15\xa5_\xfdQ\xda\xfa\xe8" +
-	"\xdc\xe0[\xdb>u\xdd\x89n\xe1\xa8D\xb7\xa2r\xb7" +
-	"$\xef%\xf2\xbb\x89\xfb~\xf4\xf1\xd3\xb5\x93\x9dV " +
-	"\x1b>\x1b]\x82\xca\xdf$\xf9|\xf4U@\xf7\xf0\xdc" +
-	"\xc4\x1b\x07\xaf\xfa\xc6)H\x0d\xb0\x80\x0d8\xfcTl" +
-	"\x09*gb2\x16\xb1\x0f\x03\xbaK\xa7\xffxh\xc1" +
-	"\xaec\xb3\xdd\xec=\x13{M9'\xb9gcd\xef" +
-	"\xfa\xa7\xd7~ [9\xff\xfbnA\x1e\xbe!\xbe\x00" +
-	"\x95\\\x9c\xd8\xb7\xc4\x89\xbdw\xcb\x85\xb3+W\x9ez" +
-	"\xa5\xd3q\x0b\x01\x94\xef\xc5\x8f)G\x88=|8\xfe" +
-	"'\x06\xe8\x8eY\xb3/\x1f\xbd\xad\xf2\xe7\xee\xf43}" +
-	"?W\xce\xf6\x11\xfd\xf9>\x93\xe8\xbej\xda\xe8\x9c\xc2" +
-	"\xa2\xdc\x93xI9\x94 [\xbe\x96 \x7f\xdc_\xbb" +
-	"\xe9\xdak\xf83o\xf6P\\\xd2S\\\x92\x02x\xe0" +
-	"\xea\xab\xee\xdf\xff\xc2\x87.v\x11\x87r>\xf9\x8e\xf2" +
-	"\xcf$\xfd\xba\x90\xa4+N\x9ae}\xa7\xa5\xaf\xe0\x93" +
-	"Z\xd5\xa8\xae+\x8a\xdb+\xc2p&\x84f\x95\xcc\xdd" +
-	"FA\xd8\x891\xcd\xd1\xf2\x88j\x88\x87\x00B\x08\x90" +
-	"\xea/\x00\xa8}\x1c\xd5\xab\x19\xba\xc2\xb2Lk\xd4," +
-	"\x01\x0a\x8c\x00\xc3H\xcfM\x0b\xc2\x16\xd6.\xcd\xd1M" +
-	"\x83\x8f\x8f\xd1\x961\x7f\xcb\xeb\x97\x02\xa8\xd7pTW" +
-	"1L!\xa6\x91\x16\x97\xaf\x03P\x079\xaak\x18&" +
-	"4[/a?0\xec\x07\xcc\xda3SS\xfa\x9e\xc6" +
-	"_\xff<\xe6\x9d\x97\x1b\xca\x8d\x96\x85f\xccT}\xe3" +
-	"\x9bN\xb2\x82M\x1b\x07\xad\x1e\x02P\x97qT?\xc2" +
-	"\xd0\xb5\xeafBF7\x8d\xf11L\x06\xfe\x04\xc4$" +
-	"`F7JbO\xaf\xcb\xe6\x86rE\xe1\xccT\xe9" +
-	"\xe4\x15\xf6\xcc\xe4\xa4\xe0\xb6M\xceKb\x1a\x19y\x8f" +
-	"\x0e\x8bqT\xd3\x0c3\x8e\xf9yat\xdc\xa3\xd5o" +
-	"r\xbb\x82\xa8\x8di\x0e\xca\xcb\xbc\xcf\xbf\xccc\xb4\xd7" +
-	"#\x1c\xd5\xe3Mn{\x9c\x16\x1f\xe5\xa8>\xc90\xc5" +
-	"\x98w\xea\x13\x1b\x01\xd4\xe3\x1c\xd5Y\x86\xc8\xd3\xc8\x01" +
-	"R'\xb7\x02\xa8'8\xaa\xbfc\x98\x0aa\x1aC\x00" +
-	"\xa9g\x89x\x9a\xa3\xfa\"\xc3T\x98\xa51\x0c\x90z" +
-	"\x9e\"\xfe\x1cG\xf5\x15\x86\xa9\x08Oc\x04 un" +
-	"?\x80\xfa2G\xf5m\x86\x99\x8an\x8c|\xba\xe1\x93" +
-	"LE\xdb\x13\xfcs\xedjYwF\xcb6\x00\x04k" +
-	"\x8ef9y\xcb\x04^\xb51\x19\xd4\x1c\xcf\xc5\xae0" +
-	"Jy\xcb\xac\xcaO:Q\xdd\x982?\xa6\x8b2\xa0" +
-	"/\x09W+\x97\xcdI\xcd\xd1\xd14&,M/\x03" +
-	"\x0e\x00\xe69b2(\x10\x80\xb48\xaf\xe6k\x0d\xd9" +
-	"\xf4d\x96\x85\xed\x059\xda\xa9\xaf\xa1y\x94\x9c\xb1\xe9" +
-	"KL\x06\x8d\xc1\xbbUv\xa7f\x0b\xa97\xbfm\xd5" +
-	"\xaf{YY\xd8\xbe,\xfax\xa8\xcfu\xa5\x1192" +
-	"\xe2f\x8e\xea&\x86\xfdx\xc9\xf5\xac\x18\x1f\x01P\xc7" +
-	"8\xaay\x86\xfd\xec]\xd7S\xc6\xad\xc4\xdd\xc0Q\x9d" +
-	"`\x98\x991l\xe1@d\xdf\x94\xa6\x97g,\xd1i" +
-	"e\x0f\xc5\xd63/\xaf9\xd39\x19:^\xb5\xaf\xc4" +
-	"/\x1b\x83\xc4\xcbP\xfc\xca\x88\xc0\x90\xfa\xa0ci\x86" +
-	"=%,R@c\xadqZ\xa8\xc5\x11\xe3\x94\x8e\xa3" +
-	"\xa61\xa5[\x15Y]\xc64~eQ\x19j\x8aJ" +
-	"KRglGs\x04&\x82.\x04\x88\x89\xceP\x8c" +
-	"z\x7f\x0b\xa26#l'\xaf\xddQ\x8e\x9aZ\x89\x8e" +
-	"N\xfaGk\x94;;8\xaae\x8a\x85[\x8f\x85N" +
-	"g\x978\xaaU\x8a\xc5\xa5z,*\x14\xa1i\x8e\xaa" +
-	"\xc3\xb0\x9fS\x84(Ok\xe4\xa5*G\xf5N\x86\xae" +
-	"\xa3W\x84\xedh\x15\xc0*\xc6\x80a\x0c\x82\xa8Y\x9e" +
-	"\x1d\x98\x0cZQ]B\x96\xb0\xab\xa6a\x0b/\x9f\xfc" +
-	"\xbe\xd6]`M\x85Z\xfa\xb6\xe8D5GH\x87J" +
-	"+S#\xf4a*\xbe\x0e`_U\x18%\xdd\xb8=" +
-	"\xabM:\xfa.\xd1\xae\x87[\xeaIi\x1a\x89\x11\xe1" +
-	"9\xa6)&#\xf3\xc4d\x9f\xcc\xe9\x9ee\xa5{Z" +
-	"\xd4+?e0@\xdb\x81\x8b\x83\x03\xbb\x9d\xc7\xf5R" +
-	"g\xf6\xf5\xa8\xf6\xd8pU\xd6s,\x9d\xb4\xc6O@" +
-	"e;\x0e\x01\x14\xb7 \xc7b\x09\x9brP\xd1\xf0s" +
-	"\x00\xc5\x1d\x04\x94\xb1)\x0d\x15\x1d\xbf\x00P\x9c&\xc0" +
-	"!\x80\xff\xc7\x8b\xbeR\xc3\xfb\x00\x8a\x0e\x01w\x11\x10" +
-	"\xfa\xb7++\xb5\xb2\x17\x1f\x00(\xdeE\xc0W\x09\x08" +
-	"\xbf\xe3\xcaj\xad|\x05\xf7\x03\x14\xbfL\xc07\x09\x88" +
-	"\xcc\xb9\xb2b+\x87\xf0i\x80\xe2w\x09x\x90\x80\xe8" +
-	"\xdbnZ\x8e\xb7\x87\xe5\xe1? \xe0(\x01\xb1\xb7\xdc" +
-	"4\xc6\x00\x94\x87p#@\xf1\xc7\x04<J@\xfc\xa2" +
-	"\x9b\xc68\x80\xf23\xdc\x0aP|\x84\x80\xe3\x04,\xf8" +
-	"\x97\x9b\xc6\x05\x00\xca\xe3\x12\xf8\x05\x01'\x90aja" +
-	"2\x8d4\xfe<%wz\x92\xd6O\xd3z\x1fOc" +
-	"\x1f\x80\xf2\x1b,\x00\x14gi\xfd9\x0c*\x90k\xd7" +
-	"\xab\x1c$\xea\xe5\xd2\x9fb\xeb\xa2\xad\x13\x0a\x90\x15\x86" +
-	"\xd8\xad\x95{S&\xb0Q\xb0\xb1:\x1f\xab \x0c\x11" +
-	"\x9do7\xafQP&\xf9\xcf\x91V\xce8k\xafI" +
-	"2\xef\xfci\xb9\x95=\x0aYO\xb4\x98\x0c\x06\xd4F" +
-	"#\x1c\x12\xb2\xd0{\x89\xeb\x8f}\x01J\x06\xef\x06." +
-	"-\xee\x02\xcbt\x00.\xf7\xf6_8uX\x9b\x9c\x14" +
-	"UG\x94\x9aK,\x15~Q\xda`Ry\xe9\xa9\xf9" +
-	"\x8cW\xee\x10\xd5e\x81\xe4\xaf\x95\x92\xff \x05rY" +
-	"\x8b\xe4\xaf\x97\x92\x1f$`M\x8b\xe4WK\xd5\xad\"" +
-	"`}\x8b\xe4\xd7J\xc9\xaf'`C\x8b\xe4sR\xf2" +
-	"\x1b\x08\x98h\x91\xbc*%\x9f'`[\x8b\xe4?#" +
-	"%\x1f\xe4\x9b/\xf9\xf6|\xf3%_\x93B\xad\x12p" +
-	"g\x8b\xe4\xef\x90\xca\xdeC\xc0\x81\x16\xc9\xdf-\x01?" +
-	"\x11{K\xb8\xad\x97v\x93p\x0fJ\x9b\x84\xfd\xe7\xdf" +
-	"<\x12\xee\xcd\x0b$\xec?8\xff\x1f%\xdc9\xf9\xd7" +
-	"\x87\xef\xfa\x04\xd0\xd4\x86\xad+i\xc3\xd8\xf4\xb4\xa7n" +
-	"\xcc\xa8\x0bc\xd3\xeb+\xb5y\x04\xd8\x15\xbc\x11\x1a-" +
-	"Y\xbe\x00l\xbb1P]\xf6\xb5 9\xdc\x124\xc9" +
-	"%\x99\xd7\xfbs\x85`f\x93M\x92f\xf4[iq" +
-	"\x13GuK}\xc2\xa7\x19}3\xcd\x98y\xef\x82]" +
-	"_e]\xa6\xe6\xac\xec\xa8vcT&\xe6@W\xaf" +
-	"\xd6G\x82\xac\x9c\x09\xfe\x97o\xb7\xff\x06\x00\x00\xff\xff" +
-	"@\x09\xcb\x12"
+const schema_a3bf9fed859570f0 = "x\xda\xc4X}\x8c\x14g\x19\x7f\x9ey\xf7\xeb\xf6n" +
+	"vw\x98%\x10b\xd9J\xda\x06\x08\xe5\xe3\x0emA" +
+	"\xf4\xe4n\x97rX\xca\xcd\xee\xa1\x80\\d\xb8\x9d\xeb" +
+	"\x8d\xee\xd7\xed\xcc\xf1aZ\xb1\x14?\xab\"54\xf1" +
+	"\x0f5\xad\xd6j\xc5\xd0`\xaa-\xa9656|\x84" +
+	"F\xd1V\xc0\x80\x85X\xd2\xa6\xe5\x1a \x85\xf6\x0a\xc7" +
+	"\x98\xe7\x9d\xdd\x99\xbd\xbdY>jj\xff\xdb}\x9fg" +
+	"\x9e\xcf\xdf\xf3\xf1\xbes\x0f\x07>+\xcc\xf3\xafh\x02" +
+	"Pr\xfe\x80\xf5\xf6\xab\xebf\xcdx \xfc (\x11" +
+	"D\xebli\xe77\x86\x7f\xf6\xfc\xcf\xc1\x8fA\x00\xf9" +
+	"\xfb\xbe=\xf2N\x1f\xfd\xda\xe1\xdb\x08hm\x1b\xb9{" +
+	"\xedo\xfe\xfc\xcf\x87\xbc\x98\xdb\x86}3Q\x1e\xe5\xdc" +
+	"#\x9c\xfb\xe9+\xaf\x1f=\xbf\xff\xed\x1f\x80\x14\xa9e" +
+	"\x16\x88y\xb5\x7f\x0a\xca\xba\x9f\x985?1k\xf3\x9f" +
+	"\x7f\xf0\x89=\x03\x8fx\xda\xf1\x82\xff\xef\xf2K\x9c\xf9" +
+	"\x00g>\xd2\xff\xc7{\xca\xeb\xce<R'\x99\xf3\xde" +
+	"\x1axS\x9e\x17\xa0_\xb7\x07\xda\x01\xad\xafM\x7f\xeb" +
+	"\x17\x7f2\xf3\x8f\xd5\x0b&qm\xcb\x03\x13P\xee\x0d" +
+	"p\x8b\x02\xfb\x10\xd0\x1ax\xb1\xf9\x8b\xc3\x9f\xfb\xd4\xe3" +
+	"\x1e\xa2\xdb\x16\x87f\xa2\xac\x84H\xf6\xf2\x10\xc9^\xfa" +
+	"\xcc\xb7\xcf\xad\xec\x1a\xf9\xa5g<\xf2\xa1i(\xdf\xcf" +
+	"\xb97\x87\xc8\xea\xbf\xf6>\xfaV\xf0\xcc\xea_\x812" +
+	"\x15\xd1\xda\xf3\xcd\xbe7p\xe3\x9a\xdf\xc3D\x16D\x80" +
+	"\xb6c\xa1V\x04\x94Oq\xc1{\xa7\xbf\xf6\xd0\xa7w" +
+	"g~\xed\x15:l\x9a\x86\xb2\xd4Dr\xc5&\x92\xfb" +
+	"\xf8\x9c\xd9\xfbz\x94\xf9O\xd6Y\x91\x12\x82\x0c\xa0M" +
+	"o\x9a\x80\xf2f\xce>\xd4\xf4:\xa0\xa5\xfenR\xd7" +
+	"\xaa%\xd6\x93\x9eFw\x85\xcb(\xf7\x86\x89{u\x98" +
+	"\x84\xdf\x93\xbc\xe5\xf2\xab\x13\x8bO\xd9F\xc7\xfe\xf3\x87" +
+	"u\x9f\xfc\xd6\x94K0\xd1\xc7\x8d~6\xcc\x8d~!" +
+	"LF;\x1e\xd5\xd9\xc1\xc8\x0e\xf9t\xf8\xbc|\x8e\x0b" +
+	"\x1e\x0e\x93\x19\xb7\x9d\xe8\xdd>\xc1\xda\xf5\\\x1d7\xc7" +
+	"\xcfw\x9a\xff%\xefl\xe6\xb8k&#v\x8dL\x7f" +
+	"w\xed\x8a\xdb\xfe\xe2i\xf2\xb9\xe65(\xfb[\x88\x1b" +
+	"[6\x02\x8eF\x1f~\xe2\xaeC\x83/\xd6Y\x81A" +
+	"\x86B[o\xcb4\x94\xf3\x9cYo!3\x1e\x1d\xe9" +
+	"9\xbb}\xd2\x0f\xf7\x81\x14\x11\\n\xc0\xb6\x948\x0d" +
+	"\xe5\x95\"q*\xe2\x1d\x80\xd6\xcc\x81\x7f\xef\x08o\xd8" +
+	"\xbb\xdf\xcb\xe0\x95\xe2\x9b\xb2\xcay{E2\xf8\xae\xdf" +
+	"N\xed\xbe\xb8Wy\xa9A\xd4D;j\"Em\xd1" +
+	"\xc1\x05S\xdb\xf3\xa7\xff\xe1\x05\xb8Sb\x18\xe5s\\" +
+	"\xee0g\xfe\xccww\xff(\xd3|\xe8\x887\x84\xc4" +
+	"\x08\x97;1\xb2\x1b\xf0\xd2\x81\xcf\xdf\xb1D]q\xd2" +
+	"+b\x07\"\x02\xca\xafDH\xec\xe1\x08\x99{\xff\xaa" +
+	"\xe1cs\xe6\xec;\x09\xe3b\xd6\x04 \xcf\x8b\xee\x95" +
+	"\x17D\xe9\xc3OD\x8b\x02\xa0\x95,\xef?\xbe\xebK" +
+	"\xf9S\xe3\xd9\x9b\x01\xe4\x13\xd2\x1e\xf9\xb4\xc4\xcd\x978" +
+	"\xfb\xb6\xc9\x93~\xba\xf5\xc8\xc7/z\x80Y\xde\x11\x7f" +
+	"_\xfeI\x9c~\xfd8N\x968\xa1\xaa\x13\xed\x0b2" +
+	"D\xf9B\xfc\xbc\x8c\x13I\xf4h|;Uk_1" +
+	"\xa7\xaf/\xeb\xb3\xb1O-\x15J\x0bS\xad\x89T\x87" +
+	"jh\xdd\x88J\x88\xf9\x00|\x08 \xcd\x98\x02\xa0\xdc" +
+	"\xc2P\x99+ b\x1c\xe9\xec\xf6V\x00e:Ce" +
+	"\xbe\x80L\xcfb\xcc\xb5\x12\x10c\x80\x09\xbd\x90\xd56" +
+	"a\x00\x04\x0c\xd4(b\xb6\xa2\x8cvo^+\x98=" +
+	"\x9aZ\xce\x167\x16\xd2\x9a\x11M\xaa\xa6Z\xa7w\xa6" +
+	"\x87\xde4\x802\x8b\xa1r\xa7\x80\xd1\xf5\xaa\xa1a\xcc" +
+	"m}\xb6fK+\x97\x8b\xe5\xceb\x16P\xbb\x86\xfe" +
+	"\xb4fh\xe5\x0d\xaa\xa9\x17\x0b\xac+\xd9X\xbb\xe4\xa8" +
+	"_\xe8\xba\x1dU\x0d=\x8b\"\x08(\x02\xb6\x1bC\xfd" +
+	"\xfd\xfa\xa6\xea_G\x9f0F_\x87j\xe0\x07\x0a\xae" +
+	"3\x0a\xae\x1a\\\xa1\x9a\xc5TgNS\x0bC%'" +
+	"\xa8>G\x9fHn\x85\x18*q7\x80\xce\x0c\xab\x04" +
+	"\xd0;X\x19\xcd\x1c*\xa5\xb5\xc1\xa4j\"\x17z\xb3" +
+	"#\xf40\x09=\xc4P9\xea:\xf1\x0a9\xf17\x86" +
+	"\xcaq\x01%\x01\xe3(\x00H\xc7\xe8\xf0e\x86\xcaI" +
+	"\x01%&\xc4\x91\x01H'\x96\x01(\xc7\x19*o\x08" +
+	"(\xf90\x8e>\x00\xe9\xf4\x1a\x00\xe55\x86\xcaY\x01" +
+	"%\xbf\x10G?\x804L\x9cg\x18*\xef\x09(\x05" +
+	"X\x1c\x03\x00\xd2\x05\x82\xc4;\x0c\xd3(\xa0\x14\xf4\xc5" +
+	"\xa9D\xa5\xd1\xad\x00\xcae\x86\x99\xc9\xd8\x10(\x89\xbc" +
+	"^\xe8\xf8B5\x8a\x89\xbc\xba\xc9\xfdg\x19\xa5\x9cn" +
+	"v\xe6\x0c\x00p\xcfL\xb5lv\x97\x8b\xc0J\x06\xc6" +
+	"\xdc\x0e\\\xc5]!\xdb].\x96\xf8'\xe3\xa9z\xa1" +
+	"\xbf\xb8D\xd7r\x80\x0eh,5\x97+\xf6\xa9\xa6\x8e" +
+	"\xc5BOY\xd5s\x80\x11\xc0n\x86\x18s\xbb% " +
+	"\x1d^\xb3\x80\x06\xaf3\xd7\xf5\xc5\xe2-\xb7\x82\x9f\xb4" +
+	"f$\x83\xff\xcf\xbaL\xb5\xa6*03\xc8\x9d\xd9\xc6" +
+	"P\xa2\xafO3\x0cr*V\xc1\x90\xd8\xeaz\x950" +
+	"\x8b_\xd1\x0a\xe3\xaa\xae>H9\xcd\xe0b\xbd\x9ci" +
+	"\xbdF\x99'\x0c\xfa\x12c\xee\"d\xbb\xd3N^v" +
+	"%\xc7\x17\xe7\xd5\xcb\xc7p\xca'\xe6\xd8\xa0R@\xd7" +
+	"2T\x06\x04\x14\xd1\xb2l#4\xb2l\x1dC%'" +
+	"\xe0M\xc2\x15\xab\xe2\xbe\xde\x01\xa0d\x19*%\x01o" +
+	"b\xa3tLE\x94'\xee\x01\x86\x8a\xd9\x18\xefC\x05" +
+	"C3!\xb0\xa5_\xd5sCem\xbcO\x0d\xc2\xe9" +
+	"\x1b\xe3H\x17\xf5\x9e\xceb\xa1_/\xe7y\xebLk" +
+	"\x09#\xf9\xd1\xa0d\x90\xa3\xa4_Mp\x87\xaa(\xa1" +
+	"\xae \x92\xaa\x16\x86\xcad\xe1\xea2\x85z\x99\xae3" +
+	"7\x92!\x912T\xb3\xa3R\x9e\x04\x91\xf2S\xb3u" +
+	"HJ\x07\x08\x0d\xba\xae\x93\x1dc\x88C\xbe\x9a\xa5z" +
+	"C\xbbUs \xc5;\x0d+\x19\xd7\x83\xe5en\xcc" +
+	"\x13\xd4nr\x88  M\x7f\xb3\xac\x16\x8c~\xadL" +
+	"\x0d\xabzv\x9d9O\xaa\xec\xba\x12^3\xc9\x1a\xa1" +
+	"\xd20US\xc3\xa8\xbbI\x02bt|\xd2;\xed\xbf" +
+	"impH3\xccnus.XT\xb3uiJ" +
+	"\xd7$\xc4I\x93\xde\xeaV\x0c\xa5\xc9\xae\xa3|\x87[" +
+	"0\x94'\xbb\x8c\x06)Z%\x86\xca}\x02Z\xa6\x9e" +
+	"\xd7\x0cS\xcd\x03\x960\x04\x02\x86j\xb2T\xb6\xed\xc0" +
+	"\x98\xbb\xcdU\x00\\\xd6\x8cR\xb1`h\xf6\x18pV" +
+	"C\xef\xe6P\xb3\x81\xf0\x18g\xcc\xa0j\xda+\x02\xb7" +
+	"R\xea\xa0\x0f\xa5\xa6\x85\x00[JZ!\xab\x17\xeem" +
+	"W\xfbL}\xc38\\,\xae\xcc\x92b!\xda\xa1\xd9" +
+	"\x81\xa9\xc9M\x87\x172j\x92\xb3\x85\x8f\xa2\x86\xd3\xf0" +
+	"\x1a\x058\xa6M3{V\xdfp\x9b\xae\xcc\x1c\x12\x08" +
+	"\xf0?\x0f\xb2\xfaI\xe2\xf4\x88\x16\xe6\x8bU\x16\x8f\x14" +
+	"\xc1%\xc9P\xe9\xaeD\x85\x16\x8f\xe5tx7Ce" +
+	"\x15\xed-\x95\xc5c%\xad\x13=6\x84<\xbb\xc9\x0d" +
+	"Mw\xfa(\xe2ir\xcd\xdc\xa50|\xb0\x8eZ\xbf" +
+	"\xce]\xad\xfba\x15\x86\xed6hI\xe3,\xe6k\xb1" +
+	",R)\xdf\x8a\xad\x00\x99\x9b\x91af\x16RM]" +
+	"\xb1kJ\x9e\x81_\x06\xc8L'\xc2|\"\x08\xa3v" +
+	"Y\xc9\xf3\xf0\xab\x00\x99\xb9DXD\x04v\xd9\xae," +
+	"y\x01n\x05\xc8\xdcI\x84$\x11|\x97,\x1epy" +
+	"1\x1e\x04\xc8,%B\x0f\x11\xfc\xef[<\xe8\xb2\xc2" +
+	"Eu\x13a-\x11\x02#\x16\xef\xed\xf2j\\\x06\x90" +
+	"YE\x84,\x11\x82\xefY|\xeb\x93U\\\x03\x90Y" +
+	"G\x84\x1c\x11B\xefZq\x0c\xd1]\x95\x13\x06\x88`" +
+	"\xd2\x9a\xd8\x14\x8b#]\xcd\x06\xb9\xa4\x12\x9d\xdfG\xe7" +
+	"a\x16\xc70\x80\xbc\x19\xd3\x00\x99Mt\xbe\x0d\x05\xa7" +
+	"\xea-\xa32\xcb!ZY\x0a\x9c\xb7\x83J\xac+\x0c" +
+	"ih\xd7\x0a\xdaF5\xd7\x98\xa5\x07+\xbb\x1bu\x09" +
+	"\xe7ah,O\x97P\xdfwyOq^ \xc6r" +
+	"wB\xbb\x0d\x1f\x8c\xb9/+U\x0c\xb4j\xbc\x1c\xec" +
+	"\xa6\xe4\\|]j\x9a\xec\x05\xc6-\xf6 s`\x02" +
+	"#\xd9\xd5\x9bq\x85\xa8\xf6\xf5i%S\xcb\xd6\x0e\x11" +
+	"\x1a]Zvi\x91\x1agC\xc4%\xecF\xfe!\x02" +
+	"\xeea\x80\xcc\"\",\x1d\x03\xb8\x14>\xd6\x08p[" +
+	"\x1b\x01\xee\xe0\x18\\9\x80\xd3\xb9r\x07W.\xe0\xea" +
+	"\x80%6]\xb4l\xc4m\xe6Ht\x90%\x86/X" +
+	"6\xe4\x1e\xe0\x84\xaf\x13\xe1{W\x85\\\xdd\xce\xe6\x05" +
+	"\xb9\x06,=X\xdd\x84\x91\x049\x8fd^\\\x84\x87" +
+	"\xa0-\xad1\x9f\x0b`\xe7\xd9\xef\xba\x00\xec\xbcG5" +
+	"\x06\xb0\xf3\xac\xe3\x09`\xe7\x99\xc3\x1b\xc0\x1e\xe4\x1a\x00" +
+	"\xbb\xcf\x9fu\xa3\xc3]\x05+c\xb9\x9d\xcf\xe5\x0f\xf3" +
+	"a\xa0f\xed\x1c\xac\xae\x9d\x1fsT=M\xaa\x9eb" +
+	"\xa8<W\xa3\xea\xd9\xf5\x00\xca3\x0c\x95\x97\x05D\xc1" +
+	"^f\x0e\xaf\xaf\xb9lW\xef\xd5\xc7hh\x1de\xa8" +
+	"\xbcC\xe8\xb7l\xf4K\xe7Z\xdd;\xb4\xe8\xe7K\xab" +
+	"\xf3\xda&]\xa0\xa55\xc0\x97V\xe7\xe1R:\xd1x" +
+	"iu\xc1\x1746\x18\xee\xed\xb5\xf6J\x14\xe1;\x11" +
+	"/v\x0d\x82\xd9\x9a\xad\xe2Z\x03\xb2\xd1J\xfc\xdf\x00" +
+	"\x00\x00\xff\xff\x07$@\x84"
 
 func init() {
 	schemas.Register(schema_a3bf9fed859570f0,
+		0x830a81292c60dfee,
 		0x8bd6c2ab5c4cf984,
 		0x8eeec8f2d8e7feb5,
+		0x9668b2a783bf3465,
 		0x96ec60724ebd66d7,
-		0x97f6cb3ee362225f,
 		0xa26d74bea4eb287e,
 		0xa53b4bed5b0bc568,
+		0xa6f94955f188b848,
+		0xa859ec07eba15dcf,
 		0xa953af3d8be428ba,
 		0xaa345154c72e2fa5,
+		0xaaff46584917b361,
+		0xb06f15dffc24444e,
+		0xb65a7701e86386b2,
 		0xbcacff128f5ddd26,
 		0xc4264f5cf728f9ac,
 		0xc571cc47a792000f,
 		0xc790178ff054f9a1,
 		0xc8ba760a91de682a,
+		0xcd51baf6501ead47,
 		0xd3e56d3f1e39ca3c,
+		0xd7cc0b5393af8a3e,
+		0xe04f6146370056c9,
 		0xe0c72f2fd9ed587d,
 		0xe16d5facdcc87244,
-		0xeb535c83335d74cf,
-		0xf2cb0324253e719e,
-		0xf621d7829e171884)
+		0xf621d7829e171884,
+		0xfb1a873660b7e310)
 }
diff --git a/proto/colibri.capnp b/proto/colibri.capnp
index 54c33d711..c77627cda 100644
--- a/proto/colibri.capnp
+++ b/proto/colibri.capnp
@@ -29,60 +29,107 @@ struct AllocationBead {
     maxBW @1 :UInt8;
 }
 
+# All segment requests identify a single index of a segment reservation.
+# Even for setup it is useful to avoid creating a different index down the reservation path, as
+# the requester AS can cleanup an index and without waiting for success start already a new setup.
+struct SegmentBase {
+    id @0 :SegmentReservationID;
+    index @1 :UInt8;
+}
+
+struct E2EBase {
+    id @0 :E2EReservationID;
+    index @1 :UInt8;
+}
+
 # Request to setup a segment reservation.
-# Setups travel inside a hop by hop colibri extension and thus have a SegmentReservationID externally.
 struct SegmentSetupReqData {
-    minBW @0 :UInt8;
-    maxBW @1 :UInt8;
-    splitCls @2 :UInt8;
-    startProps @3 :PathEndProps;
-    endProps @4 :PathEndProps;
-    infoField @5 :Data; # ExpirationTick, Index, BWCls, RLC, and PathType; expected 8 bytes
-    allocationTrail @6 :List(AllocationBead);  # updated on each AS along the path
+    base @0 :SegmentBase;
+    minBW @1 :UInt8;
+    maxBW @2 :UInt8;
+    splitCls @3 :UInt8;
+    startProps @4 :PathEndProps;
+    endProps @5 :PathEndProps;
+    infoField @6 :Data; # ExpirationTick, Index, BWCls, RLC, and PathType; expected 8 bytes
+    allocationTrail @7 :List(AllocationBead);  # updated on each AS along the path
 }
 
 # Response to a segment setup request.
-# They travel inside a hop by hop colibri extension.
 struct SegmentSetupResData {
+    base @0 :SegmentBase;
     union{
-        unset @0 :Void;
-        failure @1 :SegmentSetupReqData; # sent along the path in the opposite direction in case of failure
-        token   @2 :Data;                # if successful
+        unset @1 :Void;
+        failure @2 :SegmentSetupReqData; # sent along the path in the opposite direction in case of failure
+        token   @3 :Data;                # if successful
     }
 }
 
 # Telescoped segment reservations. Their response is identical to a non telescoped setup.
-# They travel in a hop by hop colibri extension.
 struct SegmentTelesSetupData {
     setup @0 :SegmentSetupReqData;
     baseID @1 :SegmentReservationID;
 }
 
 # Request to tear down a segment reservation.
-struct SegmentTeardownReqData {}   # empty (SegmentReservationID and index from hop by hop extension)
+struct SegmentTeardownReqData {
+    base @0 :SegmentBase;
+}
 
 # Response to a tear down request.
 struct SegmentTeardownResData {
-    errorCode @0 :UInt8;    # only relevant if the response indicates failure
+    base @0 :SegmentBase;
+    errorCode @1 :UInt8;    # only relevant if the response indicates failure
 }
 
 # Segment reservation index confirmation request.
-# They travel inside hop by hop colibri extension.
 struct SegmentIndexConfirmationData {
-    index @0 :UInt8;
+    base @0 :SegmentBase;
     state @1 :ReservationIndexState;
 }
 
+# Response to a index confirmation request.
+struct SegmentIndexConfirmationResData {
+    base @0 :SegmentBase;
+    errorCode @1: UInt8;  # only relevant if the response indicates failure
+}
+
 # Removes a pending segment reservation.
-# These messages travel as payload of a hop by hop colibri extension packet.
 struct SegmentCleanupData {
-    id @0 :SegmentReservationID;
-    index @1 :UInt8;
+    base @0 :SegmentBase;
+}
+
+struct SegmentCleanupResData {
+    base @0 :SegmentBase;
+    errorCode @1: UInt8;  # only relevant if the response indicates failure
+}
+
+# TODO(juagargi) the e2e setup request travels forward only if successful, change the type down here:
+
+# Setup an E2E reservation. Sent in a hop by hop colibri extension through
+# a stitched segment reservation. Every AS adds to the allocation trail 
+# the minimum between what it is willing to grant and the value in the request.
+# The request is accepted if all the ASes granted the requested value and no less.
+# The request travels the full path up to the destination endhost, and only then
+# it is returned to the requester endhost.
+struct E2ESetupReqData {
+    base @0 :E2EBase;
+    segmentRsvs @1 :List(SegmentReservationID);
+    requestedBW @2 :UInt8;
+    allocationTrail @3 :List(UInt8);
+    union {
+        unset @4 :Void;
+        success :group {
+            token @5 :Data;
+        }
+        failure :group {
+            errorCode @6 :UInt8;
+        }
+    }
 }
 
-# Setup an E2E reservation. Sent in a hop by hop colibri extension through a stitched segment reservation.
-struct E2ESetupData {
-    reservationID @0 :E2EReservationID;     # 16 byte e2e reservation ID
+# Response to an E2E setup. Sent in a hop by hop colibry extension, in the reverse path.
+struct E2ESetupResData {
+    base @0 :E2EBase;
     union {
         unset @1 :Void;
         success :group {
@@ -91,19 +138,22 @@ struct E2ESetupData {
         failure :group {
             errorCode @3 :UInt8;
             infoField @4 :Data;
-            maxBWs @5 :List(UInt8);     # max bandwidths granted by the ASes along the path, until failure
+            allocationTrail @5 :List(UInt8);     # max bandwidths granted by all the ASes. See E2ESetupReqData
         }
     }
 }
 
-# The reservation ID and index are needed because this request is for a different reservation than
-# the one referenced in the COLIBRI header.
+# Removes a partially setup e2e index.
 struct E2ECleanupData {
-    reservationID @0 :E2EReservationID;
-    index @1 :UInt8;
+    base @0 :E2EBase;
+}
+
+struct E2ECleanupResData {
+    base @0 :E2EBase;
+    errorCode @1 :UInt8;
 }
 
-# All possible requests between ASes.
+# All possible requests between ASes. A requests travels to the next AS.
 struct Request {
     union {
         unset @0 :Void;
@@ -114,28 +164,27 @@ struct Request {
         segmentTeardown @5 :SegmentTeardownReqData;
         segmentIndexConfirmation @6 :SegmentIndexConfirmationData;
         segmentCleanup @7 :SegmentCleanupData;
-        e2eSetup @8 :E2ESetupData;
-        e2eRenewal @9 :E2ESetupData;
+        e2eSetup @8 :E2ESetupReqData;
+        e2eRenewal @9 :E2ESetupReqData;
         e2eCleanup @10 :E2ECleanupData;
     }
 }
 # A Response can be negative (not accepted). In that case, failedHop indicates which hop along the path failed it.
+# Responses travel in the reverse direction as requests, whether successful or not.
 struct Response {
     union {
         unset @0 :Void;
-        segmentSetup @1 :SegmentSetupResData;
-        segmentRenewal @2 :SegmentSetupResData;
-        segmentTelesSetup @3 :SegmentSetupResData;  # same response type as a normal setup
-        segmentTelesRenewal @4 :SegmentSetupResData;
-        segmentTeardown @5 :SegmentTeardownResData;
-        segmentIndexConfirmation @6 :SegmentIndexConfirmationData;
-        segmentCleanup @7 :SegmentCleanupData;
-        e2eSetup @8 :E2ESetupData;
-        e2eRenewal @9 :E2ESetupData; # same response type as a setup
-        e2eCleanup @10 :E2ECleanupData;
+        segmentSetup @1 :SegmentSetupResData;   # also for teles. setup
+        segmentRenewal @2 :SegmentSetupResData; # also for teles. renewal
+        segmentTeardown @3 :SegmentTeardownResData;
+        segmentIndexConfirmation @4 :SegmentIndexConfirmationResData;
+        segmentCleanup @5 :SegmentCleanupResData;
+        e2eSetup @6 :E2ESetupResData;
+        e2eRenewal @7 :E2ESetupResData;
+        e2eCleanup @8 :E2ECleanupResData;
     }
-    accepted @11 :Bool;
-    failedHop @12 :UInt8;    # which hop failed the request
+    accepted @9 :Bool;
+    failedHop @10 :UInt8;    # which hop failed the request
 }
 
 # This travels inside a payload of a hop by hop colibri extension packet.
@@ -147,5 +196,5 @@ struct ColibriRequestPayload {
         request @2 :Request;
         response @3 :Response;
     }
-    # TODO(juagargi) authenticators
+    # TODO(juagargi) DRKey authenticators
 }


Test patch:
diff --git a/go/cs/reservation/e2e/BUILD.bazel b/go/cs/reservation/e2e/BUILD.bazel
index 1b625fea6..696f183ba 100644
--- a/go/cs/reservation/e2e/BUILD.bazel
+++ b/go/cs/reservation/e2e/BUILD.bazel
@@ -6,6 +6,7 @@ go_library(
         "index.go",
         "request.go",
         "reservation.go",
+        "response.go",
     ],
     importpath = "github.com/scionproto/scion/go/cs/reservation/e2e",
     visibility = ["//visibility:public"],
@@ -13,29 +14,21 @@ go_library(
         "//go/cs/reservation:go_default_library",
         "//go/cs/reservation/segment:go_default_library",
         "//go/lib/colibri/reservation:go_default_library",
-        "//go/lib/ctrl/colibri_mgmt:go_default_library",
         "//go/lib/serrors:go_default_library",
         "//go/lib/spath:go_default_library",
-        "//go/proto:go_default_library",
     ],
 )
 
 go_test(
     name = "go_default_test",
-    srcs = [
-        "request_test.go",
-        "reservation_test.go",
-    ],
+    srcs = ["reservation_test.go"],
     embed = [":go_default_library"],
     deps = [
         "//go/cs/reservation/segment:go_default_library",
         "//go/cs/reservation/segmenttest:go_default_library",
         "//go/lib/colibri/reservation:go_default_library",
-        "//go/lib/ctrl/colibri_mgmt:go_default_library",
-        "//go/lib/spath:go_default_library",
         "//go/lib/util:go_default_library",
         "//go/lib/xtest:go_default_library",
-        "//go/proto:go_default_library",
         "@com_github_stretchr_testify//require:go_default_library",
     ],
 )
diff --git a/go/cs/reservation/e2e/request.go b/go/cs/reservation/e2e/request.go
index 87bd68bdb..fa012c5ad 100644
--- a/go/cs/reservation/e2e/request.go
+++ b/go/cs/reservation/e2e/request.go
@@ -19,210 +19,60 @@ import (
 
 	base "github.com/scionproto/scion/go/cs/reservation"
 	"github.com/scionproto/scion/go/lib/colibri/reservation"
-	"github.com/scionproto/scion/go/lib/ctrl/colibri_mgmt"
 	"github.com/scionproto/scion/go/lib/serrors"
 	"github.com/scionproto/scion/go/lib/spath"
-	"github.com/scionproto/scion/go/proto"
 )
 
-// SetupReq is the interface for an e2e setup request.
-// Currently it's implemented by either SuccessSetupReq or FailureSetupReq.
-type SetupReq interface {
-	Reservation() *Reservation
-	Timestamp() time.Time
-	ToCtrlMsg() (*colibri_mgmt.E2ESetup, error)
+// Request is the base struct for any type of COLIBRI e2e request.
+type Request struct {
+	base.RequestMetadata                         // information about the request (forwarding path)
+	ID                   reservation.E2EID       // the ID this request refers to
+	Index                reservation.IndexNumber // the index this request refers to
+	Timestamp            time.Time               // the mandatory timestamp
 }
 
-// BaseSetupReq is the common part of any e2e setup request.
-type BaseSetupReq struct {
-	base.RequestMetadata                   // information about the request (forwarding path)
-	ID                   reservation.E2EID // the ID this request refers to
-	timestamp            time.Time         // the mandatory timestamp
-	reservation          *Reservation      // nil if no reservation yet
-}
-
-func NewBaseSetupReq(path *spath.Path, ts time.Time,
-	ID *colibri_mgmt.E2EReservationID) (*BaseSetupReq, error) {
+// NewRequest constructs the e2e Request type.
+func NewRequest(ts time.Time, id *reservation.E2EID, idx reservation.IndexNumber,
+	path *spath.Path) (*Request, error) {
 
 	metadata, err := base.NewRequestMetadata(path)
 	if err != nil {
-		return nil, serrors.WrapStr("cannot construct e2e setup", err)
+		return nil, serrors.WrapStr("new segment request", err)
 	}
-	if ID == nil {
+
+	if id == nil {
 		return nil, serrors.New("new e2e request with nil ID")
 	}
-	e2eID, err := reservation.E2EIDFromRawBuffers(ID.ASID, ID.Suffix)
-	if err != nil {
-		return nil, serrors.WrapStr("cannot construct e2e request", err)
-	}
-	return &BaseSetupReq{
+
+	return &Request{
 		RequestMetadata: *metadata,
-		ID:              *e2eID,
-		timestamp:       ts,
+		ID:              *id,
+		Index:           idx,
+		Timestamp:       ts,
 	}, nil
 }
 
-func (r *BaseSetupReq) Timestamp() time.Time      { return r.timestamp }
-func (r *BaseSetupReq) Reservation() *Reservation { return r.reservation }
-
-func (r *BaseSetupReq) ToCtrlMsg() (*colibri_mgmt.E2ESetup, error) {
-	id := make([]byte, reservation.E2EIDLen)
-	_, err := r.ID.Read(id)
-	if err != nil {
-		return nil, err
-	}
-	return &colibri_mgmt.E2ESetup{
-		ReservationID: &colibri_mgmt.E2EReservationID{
-			ASID:   id[:6],
-			Suffix: id[6:],
-		},
-	}, nil
+// SetupReq is an e2e setup/renewal request, that has been so far accepted.
+type SetupReq struct {
+	Request
+	SegmentRsvs     []reservation.SegmentID
+	RequestedBW     reservation.BWCls
+	AllocationTrail []reservation.BWCls
 }
 
-// SuccessSetupReq is a successful e2e resevation setup request.
-type SuccessSetupReq struct {
-	BaseSetupReq
+// SetupReqSuccess is a successful e2e setup request traveling along the reservation path.
+type SetupReqSuccess struct {
+	SetupReq
 	Token reservation.Token
 }
 
-var _ SetupReq = (*SuccessSetupReq)(nil)
-
-// NewSuccessSetupReq constructs the app type from its control message.
-func NewSuccessSetupReq(path *spath.Path, ts time.Time, ID *colibri_mgmt.E2EReservationID,
-	ctrl *colibri_mgmt.E2ESetupSuccess) (*SuccessSetupReq, error) {
-
-	baseReq, err := NewBaseSetupReq(path, ts, ID)
-	if err != nil {
-		return nil, serrors.WrapStr("cannot construct success e2e setup", err)
-	}
-	tok, err := reservation.TokenFromRaw(ctrl.Token)
-	if err != nil {
-		return nil, serrors.WrapStr("cannot construct success e2e setup", err)
-	}
-	return &SuccessSetupReq{
-		BaseSetupReq: *baseReq,
-		Token:        *tok,
-	}, nil
-}
-
-func (r *SuccessSetupReq) ToCtrlMsg() (*colibri_mgmt.E2ESetup, error) {
-	ctrl, err := r.BaseSetupReq.ToCtrlMsg()
-	if err != nil {
-		return nil, err
-	}
-	token := make([]byte, r.Token.Len())
-	_, err = r.Token.Read(token)
-	if err != nil {
-		return nil, err
-	}
-	ctrl.Which = proto.E2ESetupData_Which_success
-	ctrl.Success = &colibri_mgmt.E2ESetupSuccess{
-		Token: token,
-	}
-	return ctrl, nil
-}
-
-// FailureSetupReq is a failing e2e resevation setup request.
-type FailureSetupReq struct {
-	BaseSetupReq
-	ErrorCode  int
-	InfoField  reservation.InfoField
-	MaxBWTrail []reservation.BWCls
-}
-
-var _ SetupReq = (*FailureSetupReq)(nil)
-
-func NewFailureSetupReq(path *spath.Path, ts time.Time, ID *colibri_mgmt.E2EReservationID,
-	ctrl *colibri_mgmt.E2ESetupFailure) (*FailureSetupReq, error) {
-
-	baseReq, err := NewBaseSetupReq(path, ts, ID)
-	if err != nil {
-		return nil, serrors.WrapStr("cannot construct failure e2e setup", err)
-	}
-	ifield, err := reservation.InfoFieldFromRaw(ctrl.InfoField)
-	if err != nil {
-		return nil, err
-	}
-	bwTrail := make([]reservation.BWCls, len(ctrl.MaxBWs))
-	for i, bw := range ctrl.MaxBWs {
-		bwTrail[i] = reservation.BWCls(bw)
-	}
-	return &FailureSetupReq{
-		BaseSetupReq: *baseReq,
-		ErrorCode:    int(ctrl.ErrorCode),
-		InfoField:    *ifield,
-		MaxBWTrail:   bwTrail,
-	}, nil
-}
-
-func (r *FailureSetupReq) ToCtrlMsg() (*colibri_mgmt.E2ESetup, error) {
-	ctrl, err := r.BaseSetupReq.ToCtrlMsg()
-	if err != nil {
-		return nil, err
-	}
-	inf := make([]byte, reservation.InfoFieldLen)
-	_, err = r.InfoField.Read(inf)
-	if err != nil {
-		return nil, err
-	}
-	trail := make([]uint8, len(r.MaxBWTrail))
-	for i, bw := range r.MaxBWTrail {
-		trail[i] = uint8(bw)
-	}
-	ctrl.Which = proto.E2ESetupData_Which_failure
-	ctrl.Failure = &colibri_mgmt.E2ESetupFailure{
-		ErrorCode: uint8(r.ErrorCode),
-		InfoField: inf,
-		MaxBWs:    trail,
-	}
-	return ctrl, nil
-}
-
-// NewRequestFromCtrlMsg will return a SuccessSetupReq or FailSetupReq depending on the
-// success flag of the ctrl message.
-func NewRequestFromCtrlMsg(setup *colibri_mgmt.E2ESetup, ts time.Time,
-	path *spath.Path) (SetupReq, error) {
-
-	var s SetupReq
-	var err error
-	switch {
-	case setup.Success != nil:
-		s, err = NewSuccessSetupReq(path, ts, setup.ReservationID, setup.Success)
-	case setup.Failure != nil:
-		s, err = NewFailureSetupReq(path, ts, setup.ReservationID, setup.Failure)
-	default:
-		return nil, serrors.New("invalid E2E setup request received, neither successful or failed",
-			"success_ptr", setup.Success, "failure_ptr", setup.Failure)
-	}
-	return s, err
+// SetupReqFailure is a failed e2e setup request also traveling along the reservation path.
+type SetupReqFailure struct {
+	SetupReq
+	ErrorCode uint8
 }
 
 // CleanupReq is a cleaup request for an e2e index.
 type CleanupReq struct {
-	BaseSetupReq
-}
-
-// NewCleanupReqFromCtrlMsg contructs a cleanup request from its control message counterpart.
-func NewCleanupReqFromCtrlMsg(ctrl *colibri_mgmt.E2ECleanup, ts time.Time,
-	path *spath.Path) (*CleanupReq, error) {
-
-	baseReq, err := NewBaseSetupReq(path, ts, ctrl.ReservationID)
-	if err != nil {
-		return nil, serrors.WrapStr("cannot construct cleanup request", err)
-	}
-	return &CleanupReq{
-		BaseSetupReq: *baseReq,
-	}, nil
-}
-
-// ToCtrlMsg converts this application type to its control message counterpart.
-func (r *CleanupReq) ToCtrlMsg() *colibri_mgmt.E2ECleanup {
-	rawid := make([]byte, reservation.E2EIDLen)
-	r.ID.Read(rawid)
-	return &colibri_mgmt.E2ECleanup{
-		ReservationID: &colibri_mgmt.E2EReservationID{
-			ASID:   rawid[:6],
-			Suffix: rawid[6:],
-		},
-	}
+	Request
 }
diff --git a/go/cs/reservation/e2e/request_test.go b/go/cs/reservation/e2e/request_test.go
deleted file mode 100644
index aa41fafd2..000000000
--- a/go/cs/reservation/e2e/request_test.go
+++ /dev/null
@@ -1,189 +0,0 @@
-// 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 e2e_test
-
-import (
-	"testing"
-	"time"
-
-	"github.com/stretchr/testify/require"
-
-	"github.com/scionproto/scion/go/cs/reservation/e2e"
-	"github.com/scionproto/scion/go/lib/colibri/reservation"
-	"github.com/scionproto/scion/go/lib/ctrl/colibri_mgmt"
-	"github.com/scionproto/scion/go/lib/spath"
-	"github.com/scionproto/scion/go/lib/util"
-	"github.com/scionproto/scion/go/lib/xtest"
-	"github.com/scionproto/scion/go/proto"
-)
-
-func TestNewRequestFromCtrlMsg(t *testing.T) {
-	setup := newE2ESetupSuccess()
-	ts := util.SecsToTime(1)
-	_, err := e2e.NewRequestFromCtrlMsg(setup, ts, nil)
-	require.Error(t, err) // no path
-	p := newPath()
-	r, err := e2e.NewRequestFromCtrlMsg(setup, ts, p)
-	require.NoError(t, err)
-	checkRequest(t, setup, r, ts, p)
-
-	setup = newE2ESetupFailure()
-	_, err = e2e.NewRequestFromCtrlMsg(setup, ts, nil)
-	require.Error(t, err) // no path
-	r, err = e2e.NewRequestFromCtrlMsg(setup, ts, p)
-	require.NoError(t, err)
-	checkRequest(t, setup, r, ts, p)
-}
-
-func TestRequestToCtrlMsg(t *testing.T) {
-	setup := newE2ESetupSuccess()
-	ts := util.SecsToTime(1)
-	r, _ := e2e.NewRequestFromCtrlMsg(setup, ts, newPath())
-	anotherSetup, err := r.ToCtrlMsg()
-	require.NoError(t, err)
-	require.Equal(t, setup, anotherSetup)
-
-	setup = newE2ESetupFailure()
-	r, _ = e2e.NewRequestFromCtrlMsg(setup, ts, newPath())
-	anotherSetup, err = r.ToCtrlMsg()
-	require.NoError(t, err)
-	require.Equal(t, setup, anotherSetup)
-}
-
-func TestNewCleanupReqFromCtrlMsg(t *testing.T) {
-	ctrlMsg := newCleanupReq()
-	ts := util.SecsToTime(1)
-	_, err := e2e.NewCleanupReqFromCtrlMsg(ctrlMsg, ts, nil)
-	require.Error(t, err)
-	p := newPath()
-	r, err := e2e.NewCleanupReqFromCtrlMsg(ctrlMsg, ts, p)
-	require.NoError(t, err)
-	require.Equal(t, p, r.Path())
-	require.Equal(t, ts, r.Timestamp())
-
-	buff := make([]byte, reservation.E2EIDLen)
-	_, err = r.ID.Read(buff)
-	require.NoError(t, err)
-	require.Equal(t, ctrlMsg.ReservationID.ASID, buff[:6])
-	require.Equal(t, ctrlMsg.ReservationID.Suffix, buff[6:])
-}
-
-func TestCleanupToCtrlMsg(t *testing.T) {
-	ctrlMsg := newCleanupReq()
-	ts := util.SecsToTime(1)
-	p := newPath()
-	r, _ := e2e.NewCleanupReqFromCtrlMsg(ctrlMsg, ts, p)
-	anotherCtrlMsg := r.ToCtrlMsg()
-	require.Equal(t, ctrlMsg, anotherCtrlMsg)
-}
-
-func newE2ESetupSuccess() *colibri_mgmt.E2ESetup {
-	return &colibri_mgmt.E2ESetup{
-		ReservationID: newID(),
-		Which:         proto.E2ESetupData_Which_success,
-		Success: &colibri_mgmt.E2ESetupSuccess{
-			Token: xtest.MustParseHexString("16ebdb4f0d042500003f001002bad1ce003f001002facade"),
-		},
-	}
-}
-
-func newE2ESetupFailure() *colibri_mgmt.E2ESetup {
-	return &colibri_mgmt.E2ESetup{
-		ReservationID: newID(),
-		Which:         proto.E2ESetupData_Which_failure,
-		Failure: &colibri_mgmt.E2ESetupFailure{
-			ErrorCode: 42,
-			InfoField: xtest.MustParseHexString("16ebdb4f0d042500"),
-			MaxBWs:    []uint8{1, 2},
-		},
-	}
-}
-
-func newCleanupReq() *colibri_mgmt.E2ECleanup {
-	return &colibri_mgmt.E2ECleanup{ReservationID: newID()}
-}
-
-// new path with one segment consisting on 3 hopfields: (0,2)->(1,2)->(1,0)
-func newPath() *spath.Path {
-	path := &spath.Path{
-		InfOff: 0,
-		HopOff: spath.InfoFieldLength + spath.HopFieldLength, // second hop field
-		Raw:    make([]byte, spath.InfoFieldLength+3*spath.HopFieldLength),
-	}
-	inf := spath.InfoField{ConsDir: true, ISD: 1, Hops: 3}
-	inf.Write(path.Raw)
-
-	hf := &spath.HopField{ConsEgress: 2}
-	hf.Write(path.Raw[spath.InfoFieldLength:])
-	hf = &spath.HopField{ConsIngress: 1, ConsEgress: 2}
-	hf.Write(path.Raw[spath.InfoFieldLength+spath.HopFieldLength:])
-	hf = &spath.HopField{ConsIngress: 1}
-	hf.Write(path.Raw[spath.InfoFieldLength+spath.HopFieldLength*2:])
-
-	return path
-}
-
-func newID() *colibri_mgmt.E2EReservationID {
-	return &colibri_mgmt.E2EReservationID{
-		ASID:   xtest.MustParseHexString("ff00cafe0001"),
-		Suffix: xtest.MustParseHexString("0123456789abcdef0123"),
-	}
-}
-
-func checkRequest(t *testing.T, e2eSetup *colibri_mgmt.E2ESetup, r e2e.SetupReq, ts time.Time,
-	p *spath.Path) {
-	var base *e2e.BaseSetupReq
-	var successSetup *e2e.SuccessSetupReq
-	var failureSetup *e2e.FailureSetupReq
-	switch s := r.(type) {
-	case *e2e.SuccessSetupReq:
-		base = &s.BaseSetupReq
-		successSetup = s
-	case *e2e.FailureSetupReq:
-		base = &s.BaseSetupReq
-		failureSetup = s
-	default:
-		require.FailNow(t, "invalid type for request", "request type: %T", r)
-	}
-
-	require.Equal(t, (*e2e.Reservation)(nil), base.Reservation())
-	require.Equal(t, ts, base.Timestamp())
-	require.Equal(t, p, base.Path())
-	buff := make([]byte, reservation.E2EIDLen)
-	_, err := base.ID.Read(buff)
-	require.NoError(t, err) // tested in the E2EID UT, should not fail
-	require.Equal(t, e2eSetup.ReservationID.ASID, buff[:6])
-	require.Equal(t, e2eSetup.ReservationID.Suffix, buff[6:])
-
-	if successSetup != nil {
-		buff := make([]byte, len(e2eSetup.Success.Token))
-		_, err := successSetup.Token.Read(buff)
-		require.NoError(t, err) // tested in the Token UT, should not fail
-		require.Equal(t, e2eSetup.Success.Token, buff)
-	}
-	if failureSetup != nil {
-		require.Equal(t, int(e2eSetup.Failure.ErrorCode), failureSetup.ErrorCode)
-		buff := make([]byte, reservation.InfoFieldLen)
-		_, err := failureSetup.InfoField.Read(buff)
-		require.NoError(t, err) // tested in the InfoField UT, should not fail
-		require.Equal(t, e2eSetup.Failure.InfoField, buff)
-		trail := make([]uint8, len(failureSetup.MaxBWTrail))
-		for i := range trail {
-			trail[i] = uint8(failureSetup.MaxBWTrail[i])
-		}
-		require.Equal(t, e2eSetup.Failure.MaxBWs, trail)
-
-	}
-}
diff --git a/go/cs/reservation/e2e/response.go b/go/cs/reservation/e2e/response.go
new file mode 100644
index 000000000..f9c8d956c
--- /dev/null
+++ b/go/cs/reservation/e2e/response.go
@@ -0,0 +1,79 @@
+// 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 e2e
+
+import (
+	"time"
+
+	base "github.com/scionproto/scion/go/cs/reservation"
+	"github.com/scionproto/scion/go/lib/colibri/reservation"
+	"github.com/scionproto/scion/go/lib/serrors"
+	"github.com/scionproto/scion/go/lib/spath"
+)
+
+// Response is the base struct for any type of COLIBRI e2e response.
+type Response struct {
+	base.RequestMetadata                         // information about the request (forwarding path)
+	ID                   reservation.E2EID       // the ID this request refers to
+	Index                reservation.IndexNumber // the index this request refers to
+	Accepted             bool                    // success or failure type of response
+	FailedHop            uint8                   // if accepted is false, the AS that failed it
+}
+
+// NewResponse contructs the segment Response type.
+func NewResponse(ts time.Time, id *reservation.E2EID, idx reservation.IndexNumber,
+	path *spath.Path, accepted bool, failedHop uint8) (*Response, error) {
+
+	metadata, err := base.NewRequestMetadata(path)
+	if err != nil {
+		return nil, serrors.WrapStr("new segment request", err)
+	}
+	if id == nil {
+		return nil, serrors.New("new segment response with nil ID")
+	}
+	return &Response{
+		RequestMetadata: *metadata,
+		ID:              *id,
+		Index:           reservation.IndexNumber(idx),
+		Accepted:        accepted,
+		FailedHop:       failedHop,
+	}, nil
+}
+
+// ResponseSetupSuccess is the response to a success setup. It's sent on the reverse direction.
+type ResponseSetupSuccess struct {
+	Response
+	Token reservation.Token
+}
+
+// ResponseSetupFailure is the response to a failed setup. It's sent on the reverse direction.
+// The failed hop is the length of MaxBWs + 1.
+type ResponseSetupFailure struct {
+	Response
+	ErrorCode uint8
+	InfoField reservation.InfoField
+	MaxBWs    []reservation.BWCls // granted by ASes in the path until the failed hop
+}
+
+// ResponseCleanupSuccess is a response to a successful cleanup request.
+type ResponseCleanupSuccess struct {
+	Response
+}
+
+// ResponseCleanupFailure is a failed index cleanup.
+type ResponseCleanupFailure struct {
+	Response
+	ErrorCode uint8
+}
diff --git a/go/cs/reservation/segment/request_test.go b/go/cs/reservation/segment/request_test.go
deleted file mode 100644
index bf11cc561..000000000
--- a/go/cs/reservation/segment/request_test.go
+++ /dev/null
@@ -1,222 +0,0 @@
-// 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 segment_test
-
-import (
-	"testing"
-	"time"
-
-	"github.com/stretchr/testify/require"
-
-	"github.com/scionproto/scion/go/cs/reservation/segment"
-	"github.com/scionproto/scion/go/lib/colibri/reservation"
-	"github.com/scionproto/scion/go/lib/common"
-	"github.com/scionproto/scion/go/lib/ctrl/colibri_mgmt"
-	"github.com/scionproto/scion/go/lib/spath"
-	"github.com/scionproto/scion/go/lib/util"
-	"github.com/scionproto/scion/go/lib/xtest"
-	"github.com/scionproto/scion/go/proto"
-)
-
-func TestNewSetupReqFromCtrlMsg(t *testing.T) {
-	ctrlMsg := newSetup()
-	ts := util.SecsToTime(1)
-	r, err := segment.NewSetupReqFromCtrlMsg(ctrlMsg, ts, nil, nil)
-	require.Error(t, err) // missing both ID and path
-	p := newPath()
-	r, err = segment.NewSetupReqFromCtrlMsg(ctrlMsg, ts, nil, p)
-	require.Error(t, err) // missing ID
-	id := newID()
-	r, err = segment.NewSetupReqFromCtrlMsg(ctrlMsg, ts, id, p)
-	require.NoError(t, err)
-	require.Equal(t, p, r.Path())
-	checkRequest(t, ctrlMsg, r, ts)
-	require.Equal(t, common.IFIDType(1), r.Ingress)
-	require.Equal(t, common.IFIDType(2), r.Egress)
-}
-
-func TestRequestToCtrlMsg(t *testing.T) {
-	ctrlMsg := newSetup()
-	ts := util.SecsToTime(1)
-	r, err := segment.NewSetupReqFromCtrlMsg(ctrlMsg, ts, newID(), newPath())
-	require.NoError(t, err)
-	anotherCtrlMsg := r.ToCtrlMsg()
-	require.Equal(t, ctrlMsg, anotherCtrlMsg)
-}
-
-func TestNewTelesRequestFromCtrlMsg(t *testing.T) {
-	ctrlMsg := newTelesSetup()
-	ts := util.SecsToTime(1)
-	r, err := segment.NewTelesRequestFromCtrlMsg(ctrlMsg, ts, nil, nil)
-	require.Error(t, err) // both path and ID are nil
-	r, err = segment.NewTelesRequestFromCtrlMsg(ctrlMsg, ts, nil, newPath())
-	require.Error(t, err) // ID is nil
-	r, err = segment.NewTelesRequestFromCtrlMsg(ctrlMsg, ts, newID(), newPath())
-	require.NoError(t, err)
-	checkRequest(t, ctrlMsg.Setup, &r.SetupReq, ts)
-	require.Equal(t, xtest.MustParseAS("ff00:cafe:1"), r.BaseID.ASID)
-	require.Equal(t, xtest.MustParseHexString("deadbeef"), r.BaseID.Suffix[:])
-}
-
-func TestTelesRequestToCtrlMsg(t *testing.T) {
-	ctrlMsg := newTelesSetup()
-	ts := util.SecsToTime(1)
-	r, _ := segment.NewTelesRequestFromCtrlMsg(ctrlMsg, ts, newID(), newPath())
-	anotherCtrlMsg := r.ToCtrlMsg()
-	require.Equal(t, ctrlMsg, anotherCtrlMsg)
-}
-
-func TestNewIndexConfirmationReqFromCtrlMsg(t *testing.T) {
-	ctrlMsg := newIndexConfirmation()
-	ts := util.SecsToTime(1)
-	r, err := segment.NewIndexConfirmationReqFromCtrlMsg(ctrlMsg, ts, nil, nil)
-	require.Error(t, err) // nil path and ID
-	r, err = segment.NewIndexConfirmationReqFromCtrlMsg(ctrlMsg, ts, nil, newPath())
-	require.Error(t, err) // nil ID
-	r, err = segment.NewIndexConfirmationReqFromCtrlMsg(ctrlMsg, ts, newID(), newPath())
-	require.NoError(t, err)
-	require.Equal(t, reservation.IndexNumber(2), r.IndexNumber)
-	require.Equal(t, segment.IndexActive, r.State)
-}
-
-func TestIndexConfirmationReqToCtrlMsg(t *testing.T) {
-	ctrlMsg := newIndexConfirmation()
-	ts := util.SecsToTime(1)
-	r, _ := segment.NewIndexConfirmationReqFromCtrlMsg(ctrlMsg, ts, newID(), newPath())
-	r.State = segment.IndexTemporary
-	_, err := r.ToCtrlMsg()
-	require.Error(t, err)
-	r, _ = segment.NewIndexConfirmationReqFromCtrlMsg(ctrlMsg, ts, newID(), newPath())
-	anotherCtrlMsg, err := r.ToCtrlMsg()
-	require.NoError(t, err)
-	require.Equal(t, *ctrlMsg, *anotherCtrlMsg)
-}
-
-func TestNewCleanupReqFromCtrlMsg(t *testing.T) {
-	ctrlMsg := newCleanup()
-	ts := util.SecsToTime(1)
-	r, err := segment.NewCleanupReqFromCtrlMsg(ctrlMsg, ts, nil)
-	require.Error(t, err) // no path
-	ctrlMsg.ID = nil
-	r, err = segment.NewCleanupReqFromCtrlMsg(ctrlMsg, ts, newPath())
-	require.Error(t, err) // the ID inside the ctrl message is nil
-	ctrlMsg = newCleanup()
-	r, err = segment.NewCleanupReqFromCtrlMsg(ctrlMsg, ts, newPath())
-	require.NoError(t, err)
-	require.Equal(t, reservation.IndexNumber(1), r.IndexNumber)
-	require.Equal(t, xtest.MustParseAS("ff00:3:1234"), r.ID.ASID)
-	require.Equal(t, ctrlMsg.ID.Suffix, r.ID.Suffix[:])
-}
-
-func TestCleanupReqToCtrlMsg(t *testing.T) {
-	ctrlMsg := newCleanup()
-	ts := util.SecsToTime(1)
-	r, _ := segment.NewCleanupReqFromCtrlMsg(ctrlMsg, ts, newPath())
-	anotherCtrlMsg := r.ToCtrlMsg()
-	require.Equal(t, ctrlMsg, anotherCtrlMsg)
-}
-
-func newSetup() *colibri_mgmt.SegmentSetup {
-	return &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,
-		},
-		InfoField: xtest.MustParseHexString("16ebdb4f0d042500"),
-		AllocationTrail: []*colibri_mgmt.AllocationBead{
-			{
-				AllocBW: 5,
-				MaxBW:   6,
-			},
-		},
-	}
-}
-
-func newTelesSetup() *colibri_mgmt.SegmentTelesSetup {
-	return &colibri_mgmt.SegmentTelesSetup{
-		Setup:  newSetup(),
-		BaseID: newID(),
-	}
-}
-
-func newIndexConfirmation() *colibri_mgmt.SegmentIndexConfirmation {
-	return &colibri_mgmt.SegmentIndexConfirmation{
-		Index: 2,
-		State: proto.ReservationIndexState_active,
-	}
-}
-
-func newCleanup() *colibri_mgmt.SegmentCleanup {
-	return &colibri_mgmt.SegmentCleanup{
-		Index: 1,
-		ID: &colibri_mgmt.SegmentReservationID{
-			ASID:   xtest.MustParseHexString("ff0000031234"),
-			Suffix: xtest.MustParseHexString("04030201"),
-		},
-	}
-}
-
-// new path with one segment consisting on 3 hopfields: (0,2)->(1,2)->(1,0)
-func newPath() *spath.Path {
-	path := &spath.Path{
-		InfOff: 0,
-		HopOff: spath.InfoFieldLength + spath.HopFieldLength, // second hop field
-		Raw:    make([]byte, spath.InfoFieldLength+3*spath.HopFieldLength),
-	}
-	inf := spath.InfoField{ConsDir: true, ISD: 1, Hops: 3}
-	inf.Write(path.Raw)
-
-	hf := &spath.HopField{ConsEgress: 2}
-	hf.Write(path.Raw[spath.InfoFieldLength:])
-	hf = &spath.HopField{ConsIngress: 1, ConsEgress: 2}
-	hf.Write(path.Raw[spath.InfoFieldLength+spath.HopFieldLength:])
-	hf = &spath.HopField{ConsIngress: 1}
-	hf.Write(path.Raw[spath.InfoFieldLength+spath.HopFieldLength*2:])
-
-	return path
-}
-
-func newID() *colibri_mgmt.SegmentReservationID {
-	return &colibri_mgmt.SegmentReservationID{
-		ASID:   xtest.MustParseHexString("ff00cafe0001"),
-		Suffix: xtest.MustParseHexString("deadbeef"),
-	}
-}
-
-func checkRequest(t *testing.T, segSetup *colibri_mgmt.SegmentSetup, r *segment.SetupReq,
-	ts time.Time) {
-
-	t.Helper()
-	require.Equal(t, (*segment.Reservation)(nil), r.Reservation)
-	require.Equal(t, ts, r.Timestamp)
-	require.Equal(t, segSetup.MinBW, uint8(r.MinBW))
-	require.Equal(t, segSetup.MaxBW, uint8(r.MaxBW))
-	require.Equal(t, segSetup.SplitCls, uint8(r.SplitCls))
-	require.Equal(t, reservation.NewPathEndProps(
-		segSetup.StartProps.Local, segSetup.StartProps.Transfer,
-		segSetup.EndProps.Local, segSetup.EndProps.Transfer), r.PathProps)
-	require.Len(t, r.AllocTrail, len(segSetup.AllocationTrail))
-	for i := range segSetup.AllocationTrail {
-		require.Equal(t, segSetup.AllocationTrail[i].AllocBW, uint8(r.AllocTrail[i].AllocBW))
-		require.Equal(t, segSetup.AllocationTrail[i].MaxBW, uint8(r.AllocTrail[i].MaxBW))
-	}
-}
diff --git a/go/cs/reservation/translate/common_test.go b/go/cs/reservation/translate/common_test.go
new file mode 100644
index 000000000..371e87306
--- /dev/null
+++ b/go/cs/reservation/translate/common_test.go
@@ -0,0 +1,281 @@
+// 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 translate
+
+import (
+	"testing"
+	"time"
+
+	"github.com/stretchr/testify/require"
+
+	"github.com/scionproto/scion/go/cs/reservation/segment"
+	"github.com/scionproto/scion/go/lib/colibri/reservation"
+	"github.com/scionproto/scion/go/lib/ctrl/colibri_mgmt"
+	"github.com/scionproto/scion/go/lib/spath"
+	"github.com/scionproto/scion/go/lib/xtest"
+	"github.com/scionproto/scion/go/proto"
+)
+
+func newTestID() *colibri_mgmt.SegmentReservationID {
+	return &colibri_mgmt.SegmentReservationID{
+		ASID:   xtest.MustParseHexString("ff00cafe0001"),
+		Suffix: xtest.MustParseHexString("deadbeef"),
+	}
+}
+
+func newTestE2EID() *colibri_mgmt.E2EReservationID {
+	return &colibri_mgmt.E2EReservationID{
+		ASID:   xtest.MustParseHexString("ff00cafe0001"),
+		Suffix: xtest.MustParseHexString("0123456789abcdef0123"),
+	}
+}
+
+func newTestBase(idx uint8) *colibri_mgmt.SegmentBase {
+	return &colibri_mgmt.SegmentBase{
+		ID:    newTestID(),
+		Index: idx,
+	}
+}
+
+func newTestE2EBase(idx uint8) *colibri_mgmt.E2EBase {
+	return &colibri_mgmt.E2EBase{
+		ID:    newTestE2EID(),
+		Index: idx,
+	}
+}
+
+func newTestSetup() *colibri_mgmt.SegmentSetup {
+	return &colibri_mgmt.SegmentSetup{
+		Base:     newTestBase(1),
+		MinBW:    1,
+		MaxBW:    2,
+		SplitCls: 3,
+		StartProps: colibri_mgmt.PathEndProps{
+			Local:    true,
+			Transfer: false,
+		},
+		EndProps: colibri_mgmt.PathEndProps{
+			Local:    false,
+			Transfer: true,
+		},
+		InfoField: xtest.MustParseHexString("16ebdb4f0d042500"),
+		AllocationTrail: []*colibri_mgmt.AllocationBead{
+			{
+				AllocBW: 5,
+				MaxBW:   6,
+			},
+		},
+	}
+}
+func newTestSegmentSetupSuccessResponse() *colibri_mgmt.SegmentSetupRes {
+	return &colibri_mgmt.SegmentSetupRes{
+		Base:  newTestBase(1),
+		Which: proto.SegmentSetupResData_Which_token,
+		Token: xtest.MustParseHexString("16ebdb4f0d042500003f001002bad1ce003f001002facade"),
+	}
+}
+
+func newTestSegmentSetupFailureResponse() *colibri_mgmt.SegmentSetupRes {
+	return &colibri_mgmt.SegmentSetupRes{
+		Base:    newTestBase(1),
+		Which:   proto.SegmentSetupResData_Which_failure,
+		Failure: newTestSetup(),
+	}
+}
+
+func newTestTelesSetup() *colibri_mgmt.SegmentTelesSetup {
+	return &colibri_mgmt.SegmentTelesSetup{
+		Setup:  newTestSetup(),
+		BaseID: newTestID(),
+	}
+}
+
+func newTestSegmentTeardown() *colibri_mgmt.SegmentTeardownReq {
+	return &colibri_mgmt.SegmentTeardownReq{
+		Base: newTestBase(1),
+	}
+}
+
+func newTestSegmentTeardownSuccessResponse() *colibri_mgmt.SegmentTeardownRes {
+	return &colibri_mgmt.SegmentTeardownRes{
+		Base: newTestBase(1),
+	}
+}
+
+func newTestSegmentTeardownFailureResponse() *colibri_mgmt.SegmentTeardownRes {
+	return &colibri_mgmt.SegmentTeardownRes{
+		Base:      newTestBase(1),
+		ErrorCode: 42,
+	}
+}
+
+func newTestIndexConfirmation() *colibri_mgmt.SegmentIndexConfirmation {
+	return &colibri_mgmt.SegmentIndexConfirmation{
+		Base:  newTestBase(2),
+		State: proto.ReservationIndexState_active,
+	}
+}
+
+func newTestIndexConfirmationSuccessResponse() *colibri_mgmt.SegmentIndexConfirmationRes {
+	return &colibri_mgmt.SegmentIndexConfirmationRes{
+		Base: newTestBase(1),
+	}
+}
+
+func newTestIndexConfirmationFailureResponse() *colibri_mgmt.SegmentIndexConfirmationRes {
+	return &colibri_mgmt.SegmentIndexConfirmationRes{
+		Base:      newTestBase(1),
+		ErrorCode: 42,
+	}
+}
+
+func newTestCleanup() *colibri_mgmt.SegmentCleanup {
+	return &colibri_mgmt.SegmentCleanup{
+		Base: newTestBase(1),
+	}
+}
+
+func newTestCleanupSuccessResponse() *colibri_mgmt.SegmentCleanupRes {
+	return &colibri_mgmt.SegmentCleanupRes{
+		Base: newTestBase(1),
+	}
+}
+
+func newTestCleanupFailureResponse() *colibri_mgmt.SegmentCleanupRes {
+	return &colibri_mgmt.SegmentCleanupRes{
+		Base:      newTestBase(1),
+		ErrorCode: 42,
+	}
+}
+
+func newTestE2ESetupSuccess() *colibri_mgmt.E2ESetup {
+	return &colibri_mgmt.E2ESetup{
+		Base:            newTestE2EBase(1),
+		SegmentRsvs:     []colibri_mgmt.SegmentReservationID{*newTestID()},
+		RequestedBW:     5,
+		AllocationTrail: []uint8{5, 5},
+		Which:           proto.E2ESetupReqData_Which_success,
+		Success: &colibri_mgmt.E2ESetupReqSuccess{
+			Token: xtest.MustParseHexString("16ebdb4f0d042500003f001002bad1ce003f001002facade"),
+		},
+	}
+}
+
+func newTestE2ESetupFailure() *colibri_mgmt.E2ESetup {
+	return &colibri_mgmt.E2ESetup{
+		Base:            newTestE2EBase(1),
+		SegmentRsvs:     []colibri_mgmt.SegmentReservationID{*newTestID()},
+		RequestedBW:     5,
+		AllocationTrail: []uint8{5, 5},
+		Which:           proto.E2ESetupReqData_Which_failure,
+		Failure: &colibri_mgmt.E2ESetupReqFailure{
+			ErrorCode: 66,
+		},
+	}
+}
+
+func newTestE2ESetupSuccessResponse() *colibri_mgmt.E2ESetupRes {
+	return &colibri_mgmt.E2ESetupRes{
+		Base:  newTestE2EBase(1),
+		Which: proto.E2ESetupResData_Which_success,
+		Success: &colibri_mgmt.E2ESetupSuccess{
+			Token: xtest.MustParseHexString("16ebdb4f0d042500003f001002bad1ce003f001002facade"),
+		},
+	}
+}
+
+func newTestE2ESetupFailureResponse() *colibri_mgmt.E2ESetupRes {
+	return &colibri_mgmt.E2ESetupRes{
+		Base:  newTestE2EBase(1),
+		Which: proto.E2ESetupResData_Which_failure,
+		Failure: &colibri_mgmt.E2ESetupFailure{
+			ErrorCode:       42,
+			InfoField:       xtest.MustParseHexString("16ebdb4f0d042500"),
+			AllocationTrail: []uint8{2, 3, 4},
+		},
+	}
+}
+
+func newTestE2ECleanup() *colibri_mgmt.E2ECleanup {
+	return &colibri_mgmt.E2ECleanup{
+		Base: newTestE2EBase(1),
+	}
+}
+
+func newTestE2ECleanupSuccessResponse() *colibri_mgmt.E2ECleanupRes {
+	return &colibri_mgmt.E2ECleanupRes{
+		Base: newTestE2EBase(1),
+	}
+}
+
+func newTestE2ECleanupFailureResponse() *colibri_mgmt.E2ECleanupRes {
+	return &colibri_mgmt.E2ECleanupRes{
+		Base:      newTestE2EBase(1),
+		ErrorCode: 42,
+	}
+}
+
+// new path with one segment consisting on 3 hopfields: (0,2)->(1,2)->(1,0)
+func newTestPath() *spath.Path {
+	path := &spath.Path{
+		InfOff: 0,
+		HopOff: spath.InfoFieldLength + spath.HopFieldLength, // second hop field
+		Raw:    make([]byte, spath.InfoFieldLength+3*spath.HopFieldLength),
+	}
+	inf := spath.InfoField{ConsDir: true, ISD: 1, Hops: 3}
+	inf.Write(path.Raw)
+
+	hf := &spath.HopField{ConsEgress: 2}
+	hf.Write(path.Raw[spath.InfoFieldLength:])
+	hf = &spath.HopField{ConsIngress: 1, ConsEgress: 2}
+	hf.Write(path.Raw[spath.InfoFieldLength+spath.HopFieldLength:])
+	hf = &spath.HopField{ConsIngress: 1}
+	hf.Write(path.Raw[spath.InfoFieldLength+spath.HopFieldLength*2:])
+
+	return path
+}
+
+func checkRequest(t *testing.T, segSetup *colibri_mgmt.SegmentSetup, r *segment.SetupReq,
+	ts time.Time) {
+
+	t.Helper()
+	require.Equal(t, (*segment.Reservation)(nil), r.Reservation)
+	require.Equal(t, ts, r.Timestamp)
+	checkIDs(t, segSetup.Base.ID, &r.ID)
+	require.Equal(t, segSetup.Base.Index, uint8(r.Index))
+	require.Equal(t, segSetup.MinBW, uint8(r.MinBW))
+	require.Equal(t, segSetup.MaxBW, uint8(r.MaxBW))
+	require.Equal(t, segSetup.SplitCls, uint8(r.SplitCls))
+	require.Equal(t, reservation.NewPathEndProps(
+		segSetup.StartProps.Local, segSetup.StartProps.Transfer,
+		segSetup.EndProps.Local, segSetup.EndProps.Transfer), r.PathProps)
+	require.Len(t, r.AllocTrail, len(segSetup.AllocationTrail))
+	for i := range segSetup.AllocationTrail {
+		require.Equal(t, segSetup.AllocationTrail[i].AllocBW, uint8(r.AllocTrail[i].AllocBW))
+		require.Equal(t, segSetup.AllocationTrail[i].MaxBW, uint8(r.AllocTrail[i].MaxBW))
+	}
+}
+
+func checkIDs(t *testing.T, ctrlID *colibri_mgmt.SegmentReservationID, id *reservation.SegmentID) {
+	t.Helper()
+	expectedID := append(ctrlID.ASID, ctrlID.Suffix...)
+	require.Equal(t, expectedID, id.ToRaw())
+}
+
+func checkE2EIDs(t *testing.T, ctrlID *colibri_mgmt.E2EReservationID, id *reservation.E2EID) {
+	t.Helper()
+	expectedID := append(ctrlID.ASID, ctrlID.Suffix...)
+	require.Equal(t, expectedID, id.ToRaw())
+}
diff --git a/go/cs/reservation/translate/fromctrl_test.go b/go/cs/reservation/translate/fromctrl_test.go
new file mode 100644
index 000000000..9b3a0f831
--- /dev/null
+++ b/go/cs/reservation/translate/fromctrl_test.go
@@ -0,0 +1,457 @@
+// 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 translate
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/require"
+
+	"github.com/scionproto/scion/go/cs/reservation/e2e"
+	"github.com/scionproto/scion/go/cs/reservation/segment"
+	"github.com/scionproto/scion/go/lib/colibri/reservation"
+	"github.com/scionproto/scion/go/lib/common"
+	"github.com/scionproto/scion/go/lib/ctrl/colibri_mgmt"
+	"github.com/scionproto/scion/go/lib/util"
+	"github.com/scionproto/scion/go/lib/xtest"
+	"github.com/scionproto/scion/go/proto"
+)
+
+func TestNewSegmentIDFromCtrl(t *testing.T) {
+	ctrl := newTestID()
+	id, err := NewSegmentIDFromCtrl(ctrl)
+	require.NoError(t, err)
+	rawid := id.ToRaw()
+	require.Equal(t, ctrl.ASID, rawid[:6])
+	require.Equal(t, ctrl.Suffix, rawid[6:])
+}
+
+func TestNewE2EIDFromCtrl(t *testing.T) {
+	ctrl := newTestE2EID()
+	id, err := NewE2EIDFromCtrl(ctrl)
+	require.NoError(t, err)
+	rawid := id.ToRaw()
+	require.Equal(t, ctrl.ASID, rawid[:6])
+	require.Equal(t, ctrl.Suffix, rawid[6:])
+}
+
+func TestNewRequestSegmentSetupFromCtrl(t *testing.T) {
+	ctrlMsg := newTestSetup()
+	ts := util.SecsToTime(1)
+	r, err := newRequestSegmentSetup(ctrlMsg, ts, nil)
+	require.Error(t, err) // missing path
+	p := newTestPath()
+	r, err = newRequestSegmentSetup(ctrlMsg, ts, p)
+	require.NoError(t, err)
+	require.Equal(t, p, r.Path())
+	checkRequest(t, ctrlMsg, r, ts)
+	require.Equal(t, common.IFIDType(1), r.Ingress)
+	require.Equal(t, common.IFIDType(2), r.Egress)
+}
+
+func TestNewRequestSegmentTelesSetup(t *testing.T) {
+	ctrlMsg := newTestTelesSetup()
+	ts := util.SecsToTime(1)
+	r, err := newRequestSegmentTelesSetup(ctrlMsg, ts, nil)
+	require.Error(t, err) // path is nil
+	r, err = newRequestSegmentTelesSetup(ctrlMsg, ts, newTestPath())
+	require.NoError(t, err)
+	checkRequest(t, ctrlMsg.Setup, &r.SetupReq, ts)
+	require.Equal(t, xtest.MustParseAS("ff00:cafe:1"), r.BaseID.ASID)
+	require.Equal(t, xtest.MustParseHexString("deadbeef"), r.BaseID.Suffix[:])
+}
+
+func TestNewRequestSegmentTeardown(t *testing.T) {
+	ctrlMsg := newTestSegmentTeardown()
+	ts := util.SecsToTime(1)
+	r, err := newRequestSegmentTeardown(ctrlMsg, ts, nil)
+	require.Error(t, err) // path is nil
+	r, err = newRequestSegmentTeardown(ctrlMsg, ts, newTestPath())
+	require.NoError(t, err)
+	checkIDs(t, ctrlMsg.Base.ID, &r.ID)
+	require.Equal(t, ctrlMsg.Base.Index, uint8(r.Index))
+}
+
+func TestNewRequestSegmentIndexConfirmation(t *testing.T) {
+	ctrlMsg := newTestIndexConfirmation()
+	ts := util.SecsToTime(1)
+	r, err := newRequestSegmentIndexConfirmation(ctrlMsg, ts, nil)
+	require.Error(t, err) // nil path
+	r, err = newRequestSegmentIndexConfirmation(ctrlMsg, ts, newTestPath())
+	require.NoError(t, err)
+	checkIDs(t, ctrlMsg.Base.ID, &r.ID)
+	require.Equal(t, ctrlMsg.Base.Index, uint8(r.Index))
+	require.Equal(t, segment.IndexActive, r.State)
+}
+
+func TestNewRequestSegmentCleanup(t *testing.T) {
+	ctrlMsg := newTestCleanup()
+	ts := util.SecsToTime(1)
+	r, err := newRequestSegmentCleanup(ctrlMsg, ts, nil)
+	require.Error(t, err) // nil path
+	r, err = newRequestSegmentCleanup(ctrlMsg, ts, newTestPath())
+	require.NoError(t, err)
+	checkIDs(t, ctrlMsg.Base.ID, &r.ID)
+	require.Equal(t, ctrlMsg.Base.Index, uint8(r.Index))
+}
+
+func TestNewRequestE2ESetupSuccess(t *testing.T) {
+	ctrlMsg := newTestE2ESetupSuccess()
+	ts := util.SecsToTime(1)
+	_, err := newRequestE2ESetup(ctrlMsg, ts, nil)
+	require.Error(t, err)
+	s, err := newRequestE2ESetup(ctrlMsg, ts, newTestPath())
+	require.NoError(t, err)
+	require.IsType(t, &e2e.SetupReqSuccess{}, s)
+	r := s.(*e2e.SetupReqSuccess)
+	checkE2EIDs(t, ctrlMsg.Base.ID, &r.ID)
+	require.Equal(t, ctrlMsg.Base.Index, uint8(r.Index))
+	segmentRsvs := make([]reservation.SegmentID, len(ctrlMsg.SegmentRsvs))
+	for i := range ctrlMsg.SegmentRsvs {
+		id, err := reservation.SegmentIDFromRawBuffers(ctrlMsg.SegmentRsvs[i].ASID,
+			ctrlMsg.SegmentRsvs[i].Suffix)
+		require.NoError(t, err)
+		segmentRsvs[i] = *id
+	}
+	require.Equal(t, segmentRsvs, r.SegmentRsvs)
+	require.Equal(t, ctrlMsg.RequestedBW, uint8(r.RequestedBW))
+	allocTrail := make([]reservation.BWCls, len(ctrlMsg.AllocationTrail))
+	for i := range ctrlMsg.AllocationTrail {
+		allocTrail[i] = reservation.BWCls(ctrlMsg.AllocationTrail[i])
+	}
+	require.Equal(t, allocTrail, r.AllocationTrail)
+	require.Equal(t, ctrlMsg.Success.Token, r.Token.ToRaw())
+}
+
+func TestNewRequestE2ESetupFailure(t *testing.T) {
+	ctrlMsg := newTestE2ESetupFailure()
+	ts := util.SecsToTime(1)
+	_, err := newRequestE2ESetup(ctrlMsg, ts, nil)
+	require.Error(t, err)
+	s, err := newRequestE2ESetup(ctrlMsg, ts, newTestPath())
+	require.NoError(t, err)
+	require.IsType(t, &e2e.SetupReqFailure{}, s)
+	r := s.(*e2e.SetupReqFailure)
+	checkE2EIDs(t, ctrlMsg.Base.ID, &r.ID)
+	require.Equal(t, ctrlMsg.Base.Index, uint8(r.Index))
+	segmentRsvs := make([]reservation.SegmentID, len(ctrlMsg.SegmentRsvs))
+	for i := range ctrlMsg.SegmentRsvs {
+		id, err := reservation.SegmentIDFromRawBuffers(ctrlMsg.SegmentRsvs[i].ASID,
+			ctrlMsg.SegmentRsvs[i].Suffix)
+		require.NoError(t, err)
+		segmentRsvs[i] = *id
+	}
+	require.Equal(t, segmentRsvs, r.SegmentRsvs)
+	require.Equal(t, ctrlMsg.RequestedBW, uint8(r.RequestedBW))
+	allocTrail := make([]reservation.BWCls, len(ctrlMsg.AllocationTrail))
+	for i := range ctrlMsg.AllocationTrail {
+		allocTrail[i] = reservation.BWCls(ctrlMsg.AllocationTrail[i])
+	}
+	require.Equal(t, allocTrail, r.AllocationTrail)
+	require.Equal(t, ctrlMsg.Failure.ErrorCode, r.ErrorCode)
+}
+
+func TestNewRequestE2ECleanup(t *testing.T) {
+	ctrlMsg := newTestE2ECleanup()
+	ts := util.SecsToTime(1)
+	r, err := newRequestE2ECleanup(ctrlMsg, ts, nil)
+	require.Error(t, err)
+	r, err = newRequestE2ECleanup(ctrlMsg, ts, newTestPath())
+	require.NoError(t, err)
+	checkE2EIDs(t, ctrlMsg.Base.ID, &r.ID)
+	require.Equal(t, ctrlMsg.Base.Index, uint8(r.Index))
+}
+
+func TestNewResponseSegmentSetup(t *testing.T) {
+	cases := map[string]struct {
+		Ctrl *colibri_mgmt.Response
+	}{
+		"success": {
+			Ctrl: &colibri_mgmt.Response{
+				SegmentSetup: newTestSegmentSetupSuccessResponse(),
+				Which:        proto.Response_Which_segmentSetup,
+				Accepted:     true,
+			},
+		},
+		"failure": {
+			Ctrl: &colibri_mgmt.Response{
+				SegmentSetup: newTestSegmentSetupFailureResponse(),
+				Which:        proto.Response_Which_segmentSetup,
+				Accepted:     false,
+				FailedHop:    9,
+			},
+		},
+	}
+
+	for name, tc := range cases {
+		name, tc := name, tc
+		t.Run(name, func(t *testing.T) {
+			t.Parallel()
+			ts := util.SecsToTime(1)
+			_, err := newResponseSegmentSetup(tc.Ctrl.SegmentSetup, tc.Ctrl, ts, nil)
+			require.Error(t, err)
+			r, err := newResponseSegmentSetup(tc.Ctrl.SegmentSetup, tc.Ctrl, ts, newTestPath())
+			require.NoError(t, err)
+			require.NotNil(t, r)
+			if tc.Ctrl.Accepted {
+				require.IsType(t, &segment.ResponseSetupSuccess{}, r)
+				rs := r.(*segment.ResponseSetupSuccess)
+				checkIDs(t, tc.Ctrl.SegmentSetup.Base.ID, &rs.ID)
+				require.Equal(t, tc.Ctrl.SegmentSetup.Base.Index, uint8(rs.Index))
+				require.Equal(t, tc.Ctrl.SegmentSetup.Token, rs.Token.ToRaw())
+			} else {
+				require.IsType(t, &segment.ResponseSetupFailure{}, r)
+				rs := r.(*segment.ResponseSetupFailure)
+				checkIDs(t, tc.Ctrl.SegmentSetup.Base.ID, &rs.ID)
+				require.Equal(t, tc.Ctrl.SegmentSetup.Base.Index, uint8(rs.Index))
+				checkRequest(t, tc.Ctrl.SegmentSetup.Failure, rs.FailedSetup, ts)
+			}
+		})
+	}
+}
+
+func TestNewResponseSegmentTeardown(t *testing.T) {
+	cases := map[string]struct {
+		Ctrl *colibri_mgmt.Response
+	}{
+		"success": {
+			Ctrl: &colibri_mgmt.Response{
+				SegmentTeardown: newTestSegmentTeardownSuccessResponse(),
+				Which:           proto.Response_Which_segmentTeardown,
+				Accepted:        true,
+			},
+		},
+		"failure": {
+			Ctrl: &colibri_mgmt.Response{
+				SegmentTeardown: newTestSegmentTeardownFailureResponse(),
+				Which:           proto.Response_Which_segmentTeardown,
+				Accepted:        false,
+				FailedHop:       9,
+			},
+		},
+	}
+	for name, tc := range cases {
+		name, tc := name, tc
+		t.Run(name, func(t *testing.T) {
+			t.Parallel()
+			ts := util.SecsToTime(1)
+			_, err := newResponseSegmentTeardown(tc.Ctrl.SegmentTeardown, tc.Ctrl, ts, nil)
+			require.Error(t, err) // no path
+			r, err := newResponseSegmentTeardown(tc.Ctrl.SegmentTeardown, tc.Ctrl, ts,
+				newTestPath())
+			require.NoError(t, err)
+			require.NotNil(t, r)
+			if tc.Ctrl.Accepted {
+				require.IsType(t, &segment.ResponseTeardownSuccess{}, r)
+				rs := r.(*segment.ResponseTeardownSuccess)
+				checkIDs(t, tc.Ctrl.SegmentTeardown.Base.ID, &rs.ID)
+				require.Equal(t, tc.Ctrl.SegmentTeardown.Base.Index, uint8(rs.Index))
+			} else {
+				require.IsType(t, &segment.ResponseTeardownFailure{}, r)
+				rs := r.(*segment.ResponseTeardownFailure)
+				checkIDs(t, tc.Ctrl.SegmentTeardown.Base.ID, &rs.ID)
+				require.Equal(t, tc.Ctrl.SegmentTeardown.Base.Index, uint8(rs.Index))
+				require.Equal(t, tc.Ctrl.SegmentTeardown.ErrorCode, rs.ErrorCode)
+			}
+		})
+	}
+}
+
+func TestNewResponseSegmentIndexConfirmation(t *testing.T) {
+	cases := map[string]struct {
+		Ctrl *colibri_mgmt.Response
+	}{
+		"success": {
+			Ctrl: &colibri_mgmt.Response{
+				SegmentIndexConfirmation: newTestIndexConfirmationSuccessResponse(),
+				Which:                    proto.Response_Which_segmentIndexConfirmation,
+				Accepted:                 true,
+			},
+		},
+		"failure": {
+			Ctrl: &colibri_mgmt.Response{
+				SegmentIndexConfirmation: newTestIndexConfirmationFailureResponse(),
+				Which:                    proto.Response_Which_segmentIndexConfirmation,
+				Accepted:                 false,
+				FailedHop:                9,
+			},
+		},
+	}
+	for name, tc := range cases {
+		name, tc := name, tc
+		t.Run(name, func(t *testing.T) {
+			t.Parallel()
+			ts := util.SecsToTime(1)
+			_, err := newResponseSegmentIndexConfirmation(tc.Ctrl.SegmentIndexConfirmation,
+				tc.Ctrl, ts, nil)
+			require.Error(t, err) // no path
+			r, err := newResponseSegmentIndexConfirmation(tc.Ctrl.SegmentIndexConfirmation,
+				tc.Ctrl, ts, newTestPath())
+			require.NoError(t, err)
+			require.NotNil(t, r)
+			if tc.Ctrl.Accepted {
+				require.IsType(t, &segment.ResponseIndexConfirmationSuccess{}, r)
+				rs := r.(*segment.ResponseIndexConfirmationSuccess)
+				checkIDs(t, tc.Ctrl.SegmentIndexConfirmation.Base.ID, &rs.ID)
+				require.Equal(t, tc.Ctrl.SegmentIndexConfirmation.Base.Index, uint8(rs.Index))
+			} else {
+				require.IsType(t, &segment.ResponseIndexConfirmationFailure{}, r)
+				rs := r.(*segment.ResponseIndexConfirmationFailure)
+				checkIDs(t, tc.Ctrl.SegmentIndexConfirmation.Base.ID, &rs.ID)
+				require.Equal(t, tc.Ctrl.SegmentIndexConfirmation.Base.Index, uint8(rs.Index))
+				require.Equal(t, tc.Ctrl.SegmentIndexConfirmation.ErrorCode, rs.ErrorCode)
+			}
+		})
+	}
+}
+
+func TestNewResponseSegmentCleanup(t *testing.T) {
+	cases := map[string]struct {
+		Ctrl *colibri_mgmt.Response
+	}{
+		"success": {
+			Ctrl: &colibri_mgmt.Response{
+				SegmentCleanup: newTestCleanupSuccessResponse(),
+				Which:          proto.Response_Which_segmentCleanup,
+				Accepted:       true,
+			},
+		},
+		"failure": {
+			Ctrl: &colibri_mgmt.Response{
+				SegmentCleanup: newTestCleanupFailureResponse(),
+				Which:          proto.Response_Which_segmentCleanup,
+				Accepted:       false,
+				FailedHop:      9,
+			},
+		},
+	}
+	for name, tc := range cases {
+		name, tc := name, tc
+		t.Run(name, func(t *testing.T) {
+			t.Parallel()
+			ts := util.SecsToTime(1)
+			_, err := newResponseSegmentCleanup(tc.Ctrl.SegmentCleanup, tc.Ctrl, ts, nil)
+			require.Error(t, err) // no path
+			r, err := newResponseSegmentCleanup(tc.Ctrl.SegmentCleanup, tc.Ctrl, ts, newTestPath())
+			require.NoError(t, err)
+			require.NotNil(t, r)
+			if tc.Ctrl.Accepted {
+				require.IsType(t, &segment.ResponseCleanupSuccess{}, r)
+				rs := r.(*segment.ResponseCleanupSuccess)
+				checkIDs(t, tc.Ctrl.SegmentCleanup.Base.ID, &rs.ID)
+				require.Equal(t, tc.Ctrl.SegmentCleanup.Base.Index, uint8(rs.Index))
+			} else {
+				require.IsType(t, &segment.ResponseCleanupFailure{}, r)
+				rs := r.(*segment.ResponseCleanupFailure)
+				checkIDs(t, tc.Ctrl.SegmentCleanup.Base.ID, &rs.ID)
+				require.Equal(t, tc.Ctrl.SegmentCleanup.Base.Index, uint8(rs.Index))
+				require.Equal(t, tc.Ctrl.SegmentCleanup.ErrorCode, rs.ErrorCode)
+			}
+		})
+	}
+}
+
+func TestNewResponseE2ESetup(t *testing.T) {
+	cases := map[string]struct {
+		Ctrl *colibri_mgmt.Response
+	}{
+		"success": {
+			Ctrl: &colibri_mgmt.Response{
+				E2ESetup: newTestE2ESetupSuccessResponse(),
+				Which:    proto.Response_Which_e2eSetup,
+				Accepted: true,
+			},
+		},
+		"failure": {
+			Ctrl: &colibri_mgmt.Response{
+				E2ESetup: newTestE2ESetupFailureResponse(),
+				Which:    proto.Response_Which_e2eSetup,
+				Accepted: false,
+			},
+		},
+	}
+	for name, tc := range cases {
+		name, tc := name, tc
+		t.Run(name, func(t *testing.T) {
+			t.Parallel()
+			ts := util.SecsToTime(1)
+			_, err := newResponseE2ESetup(tc.Ctrl.E2ESetup, tc.Ctrl, ts, nil)
+			require.Error(t, err) // no path
+			r, err := newResponseE2ESetup(tc.Ctrl.E2ESetup, tc.Ctrl, ts, newTestPath())
+			require.NoError(t, err)
+			require.NotNil(t, r)
+			if tc.Ctrl.Accepted {
+				require.IsType(t, &e2e.ResponseSetupSuccess{}, r)
+				rs := r.(*e2e.ResponseSetupSuccess)
+				checkE2EIDs(t, tc.Ctrl.E2ESetup.Base.ID, &rs.ID)
+				require.Equal(t, tc.Ctrl.E2ESetup.Base.Index, uint8(rs.Index))
+				require.Equal(t, tc.Ctrl.E2ESetup.Success.Token, rs.Token.ToRaw())
+			} else {
+				require.IsType(t, &e2e.ResponseSetupFailure{}, r)
+				rs := r.(*e2e.ResponseSetupFailure)
+				checkE2EIDs(t, tc.Ctrl.E2ESetup.Base.ID, &rs.ID)
+				require.Equal(t, tc.Ctrl.E2ESetup.Base.Index, uint8(rs.Index))
+				require.Equal(t, tc.Ctrl.E2ESetup.Failure.ErrorCode, rs.ErrorCode)
+				require.Equal(t, tc.Ctrl.E2ESetup.Failure.InfoField, rs.InfoField.ToRaw())
+				require.Len(t, rs.MaxBWs, len(tc.Ctrl.E2ESetup.Failure.AllocationTrail))
+			}
+		})
+	}
+}
+
+func TestNewResponseE2EClenaup(t *testing.T) {
+	cases := map[string]struct {
+		Ctrl *colibri_mgmt.Response
+	}{
+		"success": {
+			Ctrl: &colibri_mgmt.Response{
+				E2ECleanup: newTestE2ECleanupSuccessResponse(),
+				Which:      proto.Response_Which_e2eCleanup,
+				Accepted:   true,
+			},
+		},
+		"failure": {
+			Ctrl: &colibri_mgmt.Response{
+				E2ECleanup: newTestE2ECleanupFailureResponse(),
+				Which:      proto.Response_Which_e2eCleanup,
+				Accepted:   false,
+			},
+		},
+	}
+	for name, tc := range cases {
+		name, tc := name, tc
+		t.Run(name, func(t *testing.T) {
+			t.Parallel()
+			ts := util.SecsToTime(1)
+			_, err := newResponseE2EClenaup(tc.Ctrl.E2ECleanup, tc.Ctrl, ts, nil)
+			require.Error(t, err) // no path
+			r, err := newResponseE2EClenaup(tc.Ctrl.E2ECleanup, tc.Ctrl, ts, newTestPath())
+			require.NoError(t, err)
+			require.NotNil(t, r)
+			if tc.Ctrl.Accepted {
+				require.IsType(t, &e2e.ResponseCleanupSuccess{}, r)
+				rs := r.(*e2e.ResponseCleanupSuccess)
+				checkE2EIDs(t, tc.Ctrl.E2ECleanup.Base.ID, &rs.ID)
+				require.Equal(t, tc.Ctrl.E2ECleanup.Base.Index, uint8(rs.Index))
+			} else {
+				require.IsType(t, &e2e.ResponseCleanupFailure{}, r)
+				rs := r.(*e2e.ResponseCleanupFailure)
+				checkE2EIDs(t, tc.Ctrl.E2ECleanup.Base.ID, &rs.ID)
+				require.Equal(t, tc.Ctrl.E2ECleanup.Base.Index, uint8(rs.Index))
+				require.Equal(t, tc.Ctrl.E2ECleanup.ErrorCode, rs.ErrorCode)
+			}
+		})
+	}
+}
diff --git a/go/cs/reservation/translate/toctrl_test.go b/go/cs/reservation/translate/toctrl_test.go
new file mode 100644
index 000000000..482c41d46
--- /dev/null
+++ b/go/cs/reservation/translate/toctrl_test.go
@@ -0,0 +1,366 @@
+// 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 translate
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/require"
+
+	"github.com/scionproto/scion/go/lib/ctrl/colibri_mgmt"
+	"github.com/scionproto/scion/go/lib/util"
+	"github.com/scionproto/scion/go/proto"
+)
+
+func TestSomething(t *testing.T) {
+	_, err := NewMsgFromCtrl(nil, nil)
+	require.Error(t, err)
+}
+
+func TestNewCtrlSegmentReservationID(t *testing.T) {
+	ctrl := newTestID()
+	id, err := NewSegmentIDFromCtrl(ctrl)
+	require.NoError(t, err)
+	newCtrl := NewCtrlSegmentReservationID(id)
+	require.Equal(t, ctrl, newCtrl)
+}
+
+func TestNewCtrlE2EReservationID(t *testing.T) {
+	ctrl := newTestE2EID()
+	id, err := NewE2EIDFromCtrl(ctrl)
+	require.NoError(t, err)
+	newCtrl := NewCtrlE2EReservationID(id)
+	require.Equal(t, ctrl, newCtrl)
+}
+
+func TestNewSegmentSetup(t *testing.T) {
+	ctrl := newTestSetup()
+	ts := util.SecsToTime(1)
+	r, err := newRequestSegmentSetup(ctrl, ts, newTestPath())
+	require.NoError(t, err)
+	newCtrl := newSegmentSetup(r)
+	require.Equal(t, ctrl, newCtrl)
+}
+
+func TestNewCtrlFromMsg(t *testing.T) {
+	cases := map[string]struct {
+		Ctrl    *colibri_mgmt.ColibriRequestPayload
+		Renewal bool
+	}{
+		"segment setup": {
+			Ctrl: &colibri_mgmt.ColibriRequestPayload{
+				Which: proto.ColibriRequestPayload_Which_request,
+				Request: &colibri_mgmt.Request{
+					Which:        proto.Request_Which_segmentSetup,
+					SegmentSetup: newTestSetup(),
+				},
+			},
+			Renewal: false,
+		},
+		"segment renewal": {
+			Ctrl: &colibri_mgmt.ColibriRequestPayload{
+				Which: proto.ColibriRequestPayload_Which_request,
+				Request: &colibri_mgmt.Request{
+					Which:          proto.Request_Which_segmentRenewal,
+					SegmentRenewal: newTestSetup(),
+				},
+			},
+			Renewal: true,
+		},
+		"segment teles setup": {
+			Ctrl: &colibri_mgmt.ColibriRequestPayload{
+				Which: proto.ColibriRequestPayload_Which_request,
+				Request: &colibri_mgmt.Request{
+					Which:             proto.Request_Which_segmentTelesSetup,
+					SegmentTelesSetup: newTestTelesSetup(),
+				},
+			},
+			Renewal: false,
+		},
+		"segment teles renewal": {
+			Ctrl: &colibri_mgmt.ColibriRequestPayload{
+				Which: proto.ColibriRequestPayload_Which_request,
+				Request: &colibri_mgmt.Request{
+					Which:               proto.Request_Which_segmentTelesRenewal,
+					SegmentTelesRenewal: newTestTelesSetup(),
+				},
+			},
+			Renewal: true,
+		},
+		"segment teardown": {
+			Ctrl: &colibri_mgmt.ColibriRequestPayload{
+				Which: proto.ColibriRequestPayload_Which_request,
+				Request: &colibri_mgmt.Request{
+					Which:           proto.Request_Which_segmentTeardown,
+					SegmentTeardown: newTestSegmentTeardown(),
+				},
+			},
+		},
+		"segment index confirmation": {
+			Ctrl: &colibri_mgmt.ColibriRequestPayload{
+				Which: proto.ColibriRequestPayload_Which_request,
+				Request: &colibri_mgmt.Request{
+					Which:                    proto.Request_Which_segmentIndexConfirmation,
+					SegmentIndexConfirmation: newTestIndexConfirmation(),
+				},
+			},
+		},
+		"segment cleanup": {
+			Ctrl: &colibri_mgmt.ColibriRequestPayload{
+				Which: proto.ColibriRequestPayload_Which_request,
+				Request: &colibri_mgmt.Request{
+					Which:          proto.Request_Which_segmentCleanup,
+					SegmentCleanup: newTestCleanup(),
+				},
+			},
+		},
+		"e2e setup success": {
+			Ctrl: &colibri_mgmt.ColibriRequestPayload{
+				Which: proto.ColibriRequestPayload_Which_request,
+				Request: &colibri_mgmt.Request{
+					Which:    proto.Request_Which_e2eSetup,
+					E2ESetup: newTestE2ESetupSuccess(),
+				},
+			},
+			Renewal: false,
+		},
+		"e2e setup failure": {
+			Ctrl: &colibri_mgmt.ColibriRequestPayload{
+				Which: proto.ColibriRequestPayload_Which_request,
+				Request: &colibri_mgmt.Request{
+					Which:    proto.Request_Which_e2eSetup,
+					E2ESetup: newTestE2ESetupFailure(),
+				},
+			},
+			Renewal: false,
+		},
+		"e2e renewal success": {
+			Ctrl: &colibri_mgmt.ColibriRequestPayload{
+				Which: proto.ColibriRequestPayload_Which_request,
+				Request: &colibri_mgmt.Request{
+					Which:      proto.Request_Which_e2eRenewal,
+					E2ERenewal: newTestE2ESetupSuccess(),
+				},
+			},
+			Renewal: true,
+		},
+		"e2e renewal failure": {
+			Ctrl: &colibri_mgmt.ColibriRequestPayload{
+				Which: proto.ColibriRequestPayload_Which_request,
+				Request: &colibri_mgmt.Request{
+					Which:      proto.Request_Which_e2eRenewal,
+					E2ERenewal: newTestE2ESetupFailure(),
+				},
+			},
+			Renewal: true,
+		},
+		"e2e cleanup": {
+			Ctrl: &colibri_mgmt.ColibriRequestPayload{
+				Which: proto.ColibriRequestPayload_Which_request,
+				Request: &colibri_mgmt.Request{
+					Which:      proto.Request_Which_e2eCleanup,
+					E2ECleanup: newTestE2ECleanup(),
+				},
+			},
+		},
+		"response segment setup success": {
+			Ctrl: &colibri_mgmt.ColibriRequestPayload{
+				Which: proto.ColibriRequestPayload_Which_response,
+				Response: &colibri_mgmt.Response{
+					SegmentSetup: newTestSegmentSetupSuccessResponse(),
+					Which:        proto.Response_Which_segmentSetup,
+					Accepted:     true,
+				},
+			},
+			Renewal: false,
+		},
+		"response segment renewal success": {
+			Ctrl: &colibri_mgmt.ColibriRequestPayload{
+				Which: proto.ColibriRequestPayload_Which_response,
+				Response: &colibri_mgmt.Response{
+					SegmentRenewal: newTestSegmentSetupSuccessResponse(),
+					Which:          proto.Response_Which_segmentRenewal,
+					Accepted:       true,
+				},
+			},
+			Renewal: true,
+		},
+		"response segment setup failure": {
+			Ctrl: &colibri_mgmt.ColibriRequestPayload{
+				Which: proto.ColibriRequestPayload_Which_response,
+				Response: &colibri_mgmt.Response{
+					SegmentSetup: newTestSegmentSetupFailureResponse(),
+					Which:        proto.Response_Which_segmentSetup,
+					Accepted:     false,
+					FailedHop:    3,
+				},
+			},
+			Renewal: false,
+		},
+		"response segment renewal failure": {
+			Ctrl: &colibri_mgmt.ColibriRequestPayload{
+				Which: proto.ColibriRequestPayload_Which_response,
+				Response: &colibri_mgmt.Response{
+					SegmentRenewal: newTestSegmentSetupFailureResponse(),
+					Which:          proto.Response_Which_segmentRenewal,
+					Accepted:       false,
+					FailedHop:      3,
+				},
+			},
+			Renewal: true,
+		},
+		"response segment teardown success": {
+			Ctrl: &colibri_mgmt.ColibriRequestPayload{
+				Which: proto.ColibriRequestPayload_Which_response,
+				Response: &colibri_mgmt.Response{
+					SegmentTeardown: newTestSegmentTeardownSuccessResponse(),
+					Which:           proto.Response_Which_segmentTeardown,
+					Accepted:        true,
+				},
+			},
+		},
+		"response segment teardown failure": {
+			Ctrl: &colibri_mgmt.ColibriRequestPayload{
+				Which: proto.ColibriRequestPayload_Which_response,
+				Response: &colibri_mgmt.Response{
+					SegmentTeardown: newTestSegmentTeardownFailureResponse(),
+					Which:           proto.Response_Which_segmentTeardown,
+					Accepted:        false,
+					FailedHop:       3,
+				},
+			},
+		},
+		"response segment index confirmation success": {
+			Ctrl: &colibri_mgmt.ColibriRequestPayload{
+				Which: proto.ColibriRequestPayload_Which_response,
+				Response: &colibri_mgmt.Response{
+					SegmentIndexConfirmation: newTestIndexConfirmationSuccessResponse(),
+					Which:                    proto.Response_Which_segmentIndexConfirmation,
+					Accepted:                 true,
+				},
+			},
+		},
+		"response segment index confirmation failure": {
+			Ctrl: &colibri_mgmt.ColibriRequestPayload{
+				Which: proto.ColibriRequestPayload_Which_response,
+				Response: &colibri_mgmt.Response{
+					SegmentIndexConfirmation: newTestIndexConfirmationFailureResponse(),
+					Which:                    proto.Response_Which_segmentIndexConfirmation,
+					Accepted:                 false,
+					FailedHop:                3,
+				},
+			},
+		},
+		"response segment cleanup success": {
+			Ctrl: &colibri_mgmt.ColibriRequestPayload{
+				Which: proto.ColibriRequestPayload_Which_response,
+				Response: &colibri_mgmt.Response{
+					SegmentCleanup: newTestCleanupSuccessResponse(),
+					Which:          proto.Response_Which_segmentCleanup,
+					Accepted:       true,
+				},
+			},
+		},
+		"response segment cleanup failure": {
+			Ctrl: &colibri_mgmt.ColibriRequestPayload{
+				Which: proto.ColibriRequestPayload_Which_response,
+				Response: &colibri_mgmt.Response{
+					SegmentCleanup: newTestCleanupFailureResponse(),
+					Which:          proto.Response_Which_segmentCleanup,
+					Accepted:       false,
+					FailedHop:      3,
+				},
+			},
+		},
+		"response e2e setup success": {
+			Ctrl: &colibri_mgmt.ColibriRequestPayload{
+				Which: proto.ColibriRequestPayload_Which_response,
+				Response: &colibri_mgmt.Response{
+					E2ESetup: newTestE2ESetupSuccessResponse(),
+					Which:    proto.Response_Which_e2eSetup,
+					Accepted: true,
+				},
+			},
+			Renewal: false,
+		},
+		"response e2e renewal success": {
+			Ctrl: &colibri_mgmt.ColibriRequestPayload{
+				Which: proto.ColibriRequestPayload_Which_response,
+				Response: &colibri_mgmt.Response{
+					E2ERenewal: newTestE2ESetupSuccessResponse(),
+					Which:      proto.Response_Which_e2eRenewal,
+					Accepted:   true,
+				},
+			},
+			Renewal: true,
+		},
+		"response e2e setup failure": {
+			Ctrl: &colibri_mgmt.ColibriRequestPayload{
+				Which: proto.ColibriRequestPayload_Which_response,
+				Response: &colibri_mgmt.Response{
+					E2ESetup:  newTestE2ESetupFailureResponse(),
+					Which:     proto.Response_Which_e2eSetup,
+					Accepted:  false,
+					FailedHop: 3,
+				},
+			},
+			Renewal: false,
+		},
+		"response e2e renewal failure": {
+			Ctrl: &colibri_mgmt.ColibriRequestPayload{
+				Which: proto.ColibriRequestPayload_Which_response,
+				Response: &colibri_mgmt.Response{
+					E2ERenewal: newTestE2ESetupFailureResponse(),
+					Which:      proto.Response_Which_e2eRenewal,
+					Accepted:   false,
+					FailedHop:  3,
+				},
+			},
+			Renewal: true,
+		},
+		"response e2e cleanup success": {
+			Ctrl: &colibri_mgmt.ColibriRequestPayload{
+				Which: proto.ColibriRequestPayload_Which_response,
+				Response: &colibri_mgmt.Response{
+					E2ECleanup: newTestE2ECleanupSuccessResponse(),
+					Which:      proto.Response_Which_e2eCleanup,
+					Accepted:   true,
+				},
+			},
+		},
+		"response e2e cleanup failure": {
+			Ctrl: &colibri_mgmt.ColibriRequestPayload{
+				Which: proto.ColibriRequestPayload_Which_response,
+				Response: &colibri_mgmt.Response{
+					E2ECleanup: newTestE2ECleanupFailureResponse(),
+					Which:      proto.Response_Which_e2eCleanup,
+					Accepted:   false,
+					FailedHop:  3,
+				},
+			},
+		},
+	}
+	for name, tc := range cases {
+		name, tc := name, tc
+		t.Run(name, func(t *testing.T) {
+			t.Parallel()
+			msg, err := NewMsgFromCtrl(tc.Ctrl, newTestPath())
+			require.NoError(t, err)
+			newCtrl, err := NewCtrlFromMsg(msg, tc.Renewal)
+			require.NoError(t, err)
+			require.Equal(t, tc.Ctrl, newCtrl)
+		})
+	}
+}
diff --git a/go/lib/ctrl/colibri_mgmt/colibri_mgmt_test.go b/go/lib/ctrl/colibri_mgmt/colibri_mgmt_test.go
index 9d0e9fd84..43a11f9e9 100644
--- a/go/lib/ctrl/colibri_mgmt/colibri_mgmt_test.go
+++ b/go/lib/ctrl/colibri_mgmt/colibri_mgmt_test.go
@@ -44,6 +44,7 @@ func TestSerializeRoot(t *testing.T) {
 func TestSerializeRequest(t *testing.T) {
 	newSegmentSetup := func() *colibri_mgmt.SegmentSetup {
 		return &colibri_mgmt.SegmentSetup{
+			Base:     newSegmentBase(),
 			MinBW:    1,
 			MaxBW:    2,
 			SplitCls: 3,
@@ -106,15 +107,17 @@ func TestSerializeRequest(t *testing.T) {
 		},
 		"teardown": {
 			Request: &colibri_mgmt.Request{
-				Which:           proto.Request_Which_segmentTeardown,
-				SegmentTeardown: &colibri_mgmt.SegmentTeardownReq{},
+				Which: proto.Request_Which_segmentTeardown,
+				SegmentTeardown: &colibri_mgmt.SegmentTeardownReq{
+					Base: newSegmentBase(),
+				},
 			},
 		},
 		"index_confirmation": {
 			Request: &colibri_mgmt.Request{
 				Which: proto.Request_Which_segmentIndexConfirmation,
 				SegmentIndexConfirmation: &colibri_mgmt.SegmentIndexConfirmation{
-					Index: 111,
+					Base:  newSegmentBase(),
 					State: proto.ReservationIndexState_active,
 				},
 			},
@@ -123,11 +126,7 @@ func TestSerializeRequest(t *testing.T) {
 			Request: &colibri_mgmt.Request{
 				Which: proto.Request_Which_segmentCleanup,
 				SegmentCleanup: &colibri_mgmt.SegmentCleanup{
-					ID: &colibri_mgmt.SegmentReservationID{
-						ASID:   xtest.MustParseHexString("ff00cafe0001"),
-						Suffix: xtest.MustParseHexString("deadbeef"),
-					},
-					Index: 17,
+					Base: newSegmentBase(),
 				},
 			},
 		},
@@ -135,24 +134,18 @@ func TestSerializeRequest(t *testing.T) {
 			Request: &colibri_mgmt.Request{
 				Which: proto.Request_Which_e2eSetup,
 				E2ESetup: &colibri_mgmt.E2ESetup{
-					ReservationID: newE2EReservationID(),
-					Which:         proto.E2ESetupData_Which_success,
-					Success: &colibri_mgmt.E2ESetupSuccess{
-						Token: xtest.MustParseHexString("0000"),
+					Base: newE2EBase(),
+					SegmentRsvs: []colibri_mgmt.SegmentReservationID{
+						{
+							ASID:   xtest.MustParseHexString("ff00cafe0001"),
+							Suffix: xtest.MustParseHexString("deadbeef"),
+						},
 					},
-				},
-			},
-		},
-		"e2esetup_failure": {
-			Request: &colibri_mgmt.Request{
-				Which: proto.Request_Which_e2eSetup,
-				E2ESetup: &colibri_mgmt.E2ESetup{
-					ReservationID: newE2EReservationID(),
-					Which:         proto.E2ESetupData_Which_failure,
-					Failure: &colibri_mgmt.E2ESetupFailure{
-						ErrorCode: 1,
-						InfoField: xtest.MustParseHexString("fedcba9876543210"),
-						MaxBWs:    []uint8{1, 1, 2, 2},
+					RequestedBW:     5,
+					AllocationTrail: []uint8{5},
+					Which:           proto.E2ESetupReqData_Which_success,
+					Success: &colibri_mgmt.E2ESetupReqSuccess{
+						Token: xtest.MustParseHexString("0000"),
 					},
 				},
 			},
@@ -161,12 +154,22 @@ func TestSerializeRequest(t *testing.T) {
 			Request: &colibri_mgmt.Request{
 				Which: proto.Request_Which_e2eRenewal,
 				E2ERenewal: &colibri_mgmt.E2ESetup{
-					ReservationID: newE2EReservationID(),
-					Which:         proto.E2ESetupData_Which_failure,
-					Failure: &colibri_mgmt.E2ESetupFailure{
-						ErrorCode: 1,
-						InfoField: xtest.MustParseHexString("fedcba9876543210"),
-						MaxBWs:    []uint8{1, 1, 2, 2},
+					Base: newE2EBase(),
+					SegmentRsvs: []colibri_mgmt.SegmentReservationID{
+						{
+							ASID:   xtest.MustParseHexString("ff00cafe0001"),
+							Suffix: xtest.MustParseHexString("00000001"),
+						},
+						{
+							ASID:   xtest.MustParseHexString("ff00cafe0002"),
+							Suffix: xtest.MustParseHexString("00000001"),
+						},
+					},
+					RequestedBW:     5,
+					AllocationTrail: []uint8{5, 4},
+					Which:           proto.E2ESetupReqData_Which_failure,
+					Failure: &colibri_mgmt.E2ESetupReqFailure{
+						ErrorCode: 66,
 					},
 				},
 			},
@@ -175,7 +178,7 @@ func TestSerializeRequest(t *testing.T) {
 			Request: &colibri_mgmt.Request{
 				Which: proto.Request_Which_e2eCleanup,
 				E2ECleanup: &colibri_mgmt.E2ECleanup{
-					ReservationID: newE2EReservationID(),
+					Base: newE2EBase(),
 				},
 			},
 		},
@@ -203,16 +206,19 @@ func TestSerializeRequest(t *testing.T) {
 func TestSerializeResponse(t *testing.T) {
 	newSegmentSetupResp := func() *colibri_mgmt.SegmentSetupRes {
 		return &colibri_mgmt.SegmentSetupRes{
+			Base:  newSegmentBase(),
 			Which: proto.SegmentSetupResData_Which_token,
 			Token: xtest.MustParseHexString("0000"),
 		}
 	}
-	newE2ESetup := func() *colibri_mgmt.E2ESetup {
-		return &colibri_mgmt.E2ESetup{
-			ReservationID: newE2EReservationID(),
-			Which:         proto.E2ESetupData_Which_success,
-			Success: &colibri_mgmt.E2ESetupSuccess{
-				Token: xtest.MustParseHexString("0000"),
+	newE2ESetup := func() *colibri_mgmt.E2ESetupRes {
+		return &colibri_mgmt.E2ESetupRes{
+			Base:  newE2EBase(),
+			Which: proto.E2ESetupResData_Which_failure,
+			Failure: &colibri_mgmt.E2ESetupFailure{
+				ErrorCode:       1,
+				InfoField:       xtest.MustParseHexString("fedcba9876543210"),
+				AllocationTrail: []uint8{1, 1, 2, 2},
 			},
 		}
 	}
@@ -225,6 +231,7 @@ func TestSerializeResponse(t *testing.T) {
 				SegmentSetup: &colibri_mgmt.SegmentSetupRes{
 					Which: proto.SegmentSetupResData_Which_failure,
 					Failure: &colibri_mgmt.SegmentSetup{
+						Base:     newSegmentBase(),
 						MinBW:    1,
 						MaxBW:    2,
 						SplitCls: 3,
@@ -262,34 +269,22 @@ func TestSerializeResponse(t *testing.T) {
 				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,
+				Which: proto.Response_Which_segmentTeardown,
+				SegmentTeardown: &colibri_mgmt.SegmentTeardownRes{
+					Base:      newSegmentBase(),
+					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,
+				SegmentIndexConfirmation: &colibri_mgmt.SegmentIndexConfirmationRes{
+					Base: newSegmentBase(),
 				},
 				Accepted: true,
 			},
@@ -297,21 +292,37 @@ func TestSerializeResponse(t *testing.T) {
 		"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"),
+				SegmentCleanup: &colibri_mgmt.SegmentCleanupRes{
+					Base:      newSegmentBase(),
+					ErrorCode: 12,
+				},
+				Accepted: false,
+			},
+		},
+		"e2e setup success": {
+			Response: &colibri_mgmt.Response{
+				Which: proto.Response_Which_e2eSetup,
+				E2ESetup: &colibri_mgmt.E2ESetupRes{
+					Base:  newE2EBase(),
+					Which: proto.E2ESetupResData_Which_success,
+					Success: &colibri_mgmt.E2ESetupSuccess{
+						Token: xtest.MustParseHexString("0000"),
 					},
-					Index: 17,
 				},
-				Accepted: true,
 			},
 		},
-		"e2e setup": {
+		"e2e setup failure": {
 			Response: &colibri_mgmt.Response{
-				Which:    proto.Response_Which_e2eSetup,
-				E2ESetup: newE2ESetup(),
-				Accepted: true,
+				Which: proto.Response_Which_e2eSetup,
+				E2ESetup: &colibri_mgmt.E2ESetupRes{
+					Base:  newE2EBase(),
+					Which: proto.E2ESetupResData_Which_failure,
+					Failure: &colibri_mgmt.E2ESetupFailure{
+						ErrorCode:       1,
+						InfoField:       xtest.MustParseHexString("fedcba9876543210"),
+						AllocationTrail: []uint8{1, 1, 2, 2},
+					},
+				},
 			},
 		},
 		"e2e renewal": {
@@ -324,8 +335,9 @@ func TestSerializeResponse(t *testing.T) {
 		"e2e cleanup": {
 			Response: &colibri_mgmt.Response{
 				Which: proto.Response_Which_e2eCleanup,
-				E2ECleanup: &colibri_mgmt.E2ECleanup{
-					ReservationID: newE2EReservationID(),
+				E2ECleanup: &colibri_mgmt.E2ECleanupRes{
+					Base:      newE2EBase(),
+					ErrorCode: 42,
 				},
 				Accepted: true,
 			},
@@ -349,9 +361,22 @@ func TestSerializeResponse(t *testing.T) {
 	}
 }
 
-func newE2EReservationID() *colibri_mgmt.E2EReservationID {
-	return &colibri_mgmt.E2EReservationID{
-		ASID:   xtest.MustParseHexString("ff00cafe0001"),
-		Suffix: xtest.MustParseHexString("0123456789abcdef0123"),
+func newSegmentBase() *colibri_mgmt.SegmentBase {
+	return &colibri_mgmt.SegmentBase{
+		ID: &colibri_mgmt.SegmentReservationID{
+			ASID:   xtest.MustParseHexString("ff00cafe0001"),
+			Suffix: xtest.MustParseHexString("deadbeef"),
+		},
+		Index: 10,
+	}
+}
+
+func newE2EBase() *colibri_mgmt.E2EBase {
+	return &colibri_mgmt.E2EBase{
+		ID: &colibri_mgmt.E2EReservationID{
+			ASID:   xtest.MustParseHexString("ff00cafe0001"),
+			Suffix: xtest.MustParseHexString("0123456789abcdef0123"),
+		},
+		Index: 11,
 	}
 }
diff --git a/go/lib/ctrl/colibri_mgmt/e2e_cleanup.go b/go/lib/ctrl/colibri_mgmt/e2e_cleanup.go
index ee8a7fa51..738c26c98 100644
--- a/go/lib/ctrl/colibri_mgmt/e2e_cleanup.go
+++ b/go/lib/ctrl/colibri_mgmt/e2e_cleanup.go
@@ -19,9 +19,18 @@ import (
 )
 
 type E2ECleanup struct {
-	ReservationID *E2EReservationID
+	Base *E2EBase
 }
 
 func (r *E2ECleanup) ProtoId() proto.ProtoIdType {
 	return proto.E2ECleanupData_TypeID
 }
+
+type E2ECleanupRes struct {
+	Base      *E2EBase
+	ErrorCode uint8
+}
+
+func (r *E2ECleanupRes) ProtoId() proto.ProtoIdType {
+	return proto.E2ECleanupResData_TypeID
+}
diff --git a/go/lib/ctrl/colibri_mgmt/e2e_setup.go b/go/lib/ctrl/colibri_mgmt/e2e_setup.go
index 3d0a9da81..cbce8ad5c 100644
--- a/go/lib/ctrl/colibri_mgmt/e2e_setup.go
+++ b/go/lib/ctrl/colibri_mgmt/e2e_setup.go
@@ -19,14 +19,36 @@ import (
 )
 
 type E2ESetup struct {
-	ReservationID *E2EReservationID
-	Which         proto.E2ESetupData_Which
-	Success       *E2ESetupSuccess
-	Failure       *E2ESetupFailure
+	Base            *E2EBase
+	SegmentRsvs     []SegmentReservationID
+	RequestedBW     uint8
+	AllocationTrail []uint8
+	Which           proto.E2ESetupReqData_Which
+	Success         *E2ESetupReqSuccess
+	Failure         *E2ESetupReqFailure
 }
 
 func (s *E2ESetup) ProtoId() proto.ProtoIdType {
-	return proto.E2ESetupData_TypeID
+	return proto.E2ESetupReqData_TypeID
+}
+
+type E2ESetupReqSuccess struct {
+	Token []byte
+}
+
+type E2ESetupReqFailure struct {
+	ErrorCode uint8
+}
+
+type E2ESetupRes struct {
+	Base    *E2EBase
+	Which   proto.E2ESetupResData_Which
+	Success *E2ESetupSuccess
+	Failure *E2ESetupFailure
+}
+
+func (s *E2ESetupRes) ProtoId() proto.ProtoIdType {
+	return proto.E2ESetupResData_TypeID
 }
 
 type E2ESetupSuccess struct {
@@ -34,7 +56,7 @@ type E2ESetupSuccess struct {
 }
 
 type E2ESetupFailure struct {
-	ErrorCode uint8
-	InfoField []byte
-	MaxBWs    []uint8
+	ErrorCode       uint8
+	InfoField       []byte
+	AllocationTrail []uint8
 }