-
Notifications
You must be signed in to change notification settings - Fork 1
Cross Domain ALTO Solution
Table of Contents
This is a design document about how to apply ALTO to the cross-domain resource optimization.
In order to support cross-domain resource optimization, the system require the following functionalities which should be provided by the related component (e.g. SDN Controller, Cross-domain Manager).
Cross-domain ALTO requires the Real-time Bandwidth Monitoring capability from the domain network management platform. The platform should provide a function which accepts a port id as the input and returns its available TX bandwidth (bps).
data Port = Port String
FetchBW :: Port -> Integer
Cross-domain ALTO requires the intra-domain Path Lookup capability from the domain network management platform. The platform should provide a function which accepts a flow specification and returns an array of network element id. The flow specification should include source IP, destination IP and domain ingress port at least. And each network element id can be used to query a properties mapping of a network element.
data FlowSpec = Flow String String String
LookupPath :: FlowSpec -> [String]
ElementProp :: String -> String -> a
Cross-domain ALTO requires the inter-domain AS Next Hop Lookup capability from the domain network management platform. The platform should provide a function which accepts a flow specification and returns the domain next hop and its ingress port.
data ASSpec = ASHop String String
NextHop :: FlowSpec -> ASSpec
Cross-domain ALTO requires the Reverse Service Lookup capability from the cross-domain management. The cross-domain management should maintain the domain information and provide a function which accepts a domain ingress-point IP address as the input and returns the entry URI of the corresponding domain network manager.
import Data.Network.Address
import Network.URI
ServiceLookup :: IPv4 -> URI
definitions:
Ipv4Addr:
type: string
pattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))$
FlowDesc:
required:
- src
- dst
- ingress
properties:
src:
$ref: "#/definitions/Ipv4Addr"
dst:
$ref: "#/definitions/Ipv4Addr"
ingress:
type: string
VectorArray:
type: array
items:
type: array
items:
type: integer
ErrorResponse:
properties:
meta:
properties:
code:
enum:
- E_SYNTAX
- E_MISSING_FIELD
- E_INVALID_FIELD_TYPE
- E_INVALID_FIELD_VALUE
message:
description: Provides the details of the error
type: string
required:
- code
type: object
definitions:
PathProperty:
required:
- domain-id
- ingress-port
properties:
domain-id:
type: string
ingress-port:
type: string
egress-port:
type: string
PathQueryRequest:
required:
- flows
properties:
flows:
type: array
items:
$ref: "#/definitions/FlowDesc"
PathQueryResponse:
required:
- flow-paths
- path-property
properties:
flow-paths:
$ref: "#/definitions/VectorArray"
path-property:
type: array
items:
$ref: "#/definitions/PathProperty"
paths:
/as-path/lookup:
post:
description: "Make a recursive path query"
consumes:
- application/json
produces:
- application/json
parameters:
- in: body
name: flows
required: true
schema:
$ref: "#/definitions/PathQueryRequest"
responses:
200:
description: Success
schema:
$ref: "#/definitions/PathQueryResponse"
default:
description: Error
schema:
$ref: "#/definitions/ErrorResponse"
If the media type in HTTP header is application/json
, the cross-domain
path query protocol uses the simple mode.
Request
POST /xdom-alto/as-path/lookup
Host: as1.alto.example.com
Content-Length: [TBD]
Content-Type: application/json
Accept: application/json
{
"flows": [
{
"src": "10.0.1.100",
"dst": "10.0.2.100",
"ingress": null
},
{
"src": "10.0.1.101",
"dst": "10.0.3.100",
"ingress": null
}
]
}
Response
HTTP/1.1 200 OK
Content-Length: [TBD]
Content-Type: application/json
{
"flow-paths": [
[0, 1],
[0, 2, 3]
],
"path-property": [
{
"domain-id": "as1",
"ingress-port": null,
"egress-port": "openflow1:1"
},
{
"domain-id": "as2",
"ingress-port": "openflow2:1"
},
{
"domain-id": "as2",
"ingress-port": "openflow2:2"
},
{
"domain-id": "as3",
"ingress-port": "openflow3:1"
}
]
}
The cross-domain path query protocol can be backward compatible with ALTO but
extends the media type. The new media type application/alto-aggregation+json
can allow the server combine multiple ALTO resources into a single response.
Request
POST /xdom-alto/as-path/lookup
Host: as1.alto.example.com
Content-Length: [TBD]
Content-Type: application/alto-flowcostparams+json
Accept: application/alto-aggregation+json, application/alto-error+json
{
"cost-type": {
"cost-mode": "array",
"cost-metric": "ane-path"
},
"flows": {
"flow1": {
"ipv4:source": "10.0.1.100",
"ipv4:destination": "10.0.2.100",
"as:ingress": null
},
"flow2": {
"ipv4:source": "10.0.1.101",
"ipv4:destination": "10.0.3.100",
"as:ingress": null
}
}
}
Response
HTTP/1.1 200 OK
Content-Length: [TBD]
Content-Type: application/alto-aggregation+json
{
"meta": {
"dependent-vtags": [
{
"resource-id": "demo-network-map",
"tag": "75ed013b3cb58f896e839582504f622838ce670f"
}
],
"cost-type": {
"cost-mode": "array",
"cost-metric": "ane-path"
},
"vtag": {
"resource-id": "cost-map-as-path",
"tag": "27612897acf278ffu3287c284dd28841da78213",
"query-id": "query1"
}
},
"flow-cost-map": {
"flow1": ["ane:as-path0", "ane:as-path1"],
"flow2": ["ane:as-path0", "ane:as-path2", "ane:as-path3"]
},
"property-map": {
"ane:as-path0": {
"domain-id": "as1",
"ingress-port": null,
"egress-port": "openflow1:1"
},
"ane:as-path1": {
"domain-id": "as2",
"ingress-port": "openflow2:1"
},
"ane:as-path2": {
"domain-id": "as2",
"ingress-port": "openflow2:2"
},
"ane:as-path3": {
"domain-id": "as3",
"ingress-port": "openflow3:1"
}
}
}
The cross-domain path query protocol can support HTTP multipart extension as an optional feature.
Request
POST /xdom-alto/as-path/lookup
Host: as1.alto.example.com
Content-Length: [TBD]
Content-Type: application/alto-flowcostparams+json
Accept: multipart/related, application/alto-flowcost+json, application/alto-propmap+json, application/alto-error+json
<the request body is same as above>
Response
HTTP/1.1 200 OK
Content-Length: [TBD]
Content-Type: multipart/related; boundary=query-1
--query-1
Content-Type: application/alto-flowcost+json
{
"meta": {
"dependent-vtags": [
{
"resource-id": "demo-network-map",
"tag": "75ed013b3cb58f896e839582504f622838ce670f"
}
],
"cost-type": {
"cost-mode": "array",
"cost-metric": "ane-path"
},
"vtag": {
"resource-id": "cost-map-as-path",
"tag": "27612897acf278ffu3287c284dd28841da78213",
"query-id": "query1"
},
"flow-cost-map": {
"flow1": ["ane:as-path0", "ane:as-path1"],
"flow2": ["ane:as-path0", "ane:as-path2", "ane:as-path3"]
}
}
--query-1
Content-Type: application/alto-propmap+json
{
"property-map": {
"ane:as-path0": {
"domain-id": "as1",
"ingress-port": null,
"egress-port": "openflow1:1"
},
"ane:as-path1": {
"domain-id": "as2",
"ingress-port": "openflow2:1"
},
"ane:as-path2": {
"domain-id": "as2",
"ingress-port": "openflow2:2"
},
"ane:as-path3": {
"domain-id": "as3",
"ingress-port": "openflow3:1"
}
}
}
definitions:
ResourceProperty:
required:
- availbw
properties:
availbw:
type: integer
ResourceQueryRequest:
required:
- flows
properties:
flows:
type: array
items:
$ref: "#/definitions/FlowDesc"
ResourceQueryResponse:
required:
- flow-paths
- path-property
properties:
flow-resources:
$ref: "#/definitions/VectorArray"
path-property:
type: array
items:
$ref: "#/definitions/ResourceProperty"
paths:
/rsa/lookup:
post:
description: Returns resource state abstraction in simple mode
consumes:
- application/json
produces:
- application/json
parameters:
- name: flows
in: body
required: true
schema:
$ref: "#/definitions/PathQueryRequest"
responses:
200:
description: Success
schema:
$ref: "#/definitions/PathQueryResponse"
default:
description: Error
schema:
$ref: "#/definitions/ErrorResponse"
Request
POST /xdom-alto/rsa/lookup
Host: as2.alto.example.com
Content-Length: [TBD]
Content-Type: application/json
Accept: application/json
{
"flows": [
{
"src": "10.0.1.100",
"dst": "10.0.2.100",
"ingress": "openflow2:1"
},
{
"src": "10.0.1.101",
"dst": "10.0.3.100",
"ingress": "openflow2:2"
}
]
}
Response
HTTP/1.1 200 OK
Content-Length: [TBD]
Content-Type: application/json
{
"flow-resources": [
[0, 2, 3],
[1, 2, 4],
],
"resource-property": [
{
"availbw": 100000000
},
{
"availbw": 100000000
},
{
"availbw": 10000000
},
{
"availbw": 10000000
},
{
"availbw": 10000000
}
]
}
Request
POST /xdom-alto/rsa/lookup
Host: as2.alto.example.com
Content-Length: [TBD]
Content-Type: application/alto-flowcostparams+json
Accept: application/alto-aggregation+json, application/alto-error+json
{
"cost-type": {
"cost-mode": "array",
"cost-metric": "ane-path"
},
"flows": {
"flow1": {
"ipv4:source": "10.0.1.100",
"ipv4:destination": "10.0.2.100",
"as:ingress": "openflow2:1"
},
"flow2": {
"ipv4:source": "10.0.1.101",
"ipv4:destination": "10.0.3.100",
"as:ingress": "openflow2:2"
}
}
}
Response
HTTP/1.1 200 OK
Content-Length: [TBD]
Content-Type: application/alto-aggregation+json
{
"meta": {
"dependent-vtags": [
{
"resource-id": "demo-network-map",
"tag": "75ed013b3cb58f896e839582504f622838ce670f"
}
],
"cost-type": {
"cost-mode": "array",
"cost-metric": "ane-path"
},
"vtag": {
"resource-id": "cost-map-as-path",
"tag": "27612897acf278ffu3287c284dd28841da78213",
"query-id": "query1"
}
},
"flow-cost-map": {
"flow1": ["ane:elink0", "ane:ilink0", "ane:ilink1"],
"flow2": ["ane:elink1", "ane:ilink0", "ane:ilink2"]
},
"property-map": {
"ane:elink0": {
"availbw": 100000000
},
"ane:elink1": {
"availbw": 100000000
},
"ane:ilink0": {
"availbw": 10000000
},
"ane:ilink1": {
"availbw": 10000000
},
"ane:ilink2": {
"availbw": 10000000
}
}
}
Request
POST /xdom-alto/as-path/lookup
Host: as1.alto.example.com
Content-Length: [TBD]
Content-Type: application/alto-flowcostparams+json
Accept: multipart/related, application/alto-flowcost+json, application/alto-propmap+json, application/alto-error+json
<the request body is same as above>
Response
HTTP/1.1 200 OK
Content-Length: [TBD]
Content-Type: multipart/related; boundary=query-3
--query-3
Content-Type: application/alto-flowcost+json
{
"meta": {
"dependent-vtags": [
{
"resource-id": "demo-network-map",
"tag": "75ed013b3cb58f896e839582504f622838ce670f"
}
],
"cost-type": {
"cost-mode": "array",
"cost-metric": "ane-path"
},
"vtag": {
"resource-id": "cost-map-as-path",
"tag": "27612897acf278ffu3287c284dd28841da78213",
"query-id": "query3"
},
"flow-cost-map": {
"flow1": ["ane:elink0", "ane:ilink0", "ane:ilink1"],
"flow2": ["ane:elink1", "ane:ilink0", "ane:ilink2"]
}
}
--query-1
Content-Type: application/alto-propmap+json
{
"property-map": {
"ane:elink0": {
"availbw": 100000000
},
"ane:elink1": {
"availbw": 100000000
},
"ane:ilink0": {
"availbw": 10000000
},
"ane:ilink1": {
"availbw": 10000000
},
"ane:ilink2": {
"availbw": 10000000
}
}
}
The legacy ALTO protocol (which has been published since 2014) has not met some emerging network traffic optimization requirements. Some protocol extensions for ALTO have been introduced. The following is some extensions we are using for cross-domain ALTO solution.
The cross-domain ALTO solution requires the ALTO protocol extension Path Vector to extend the ALTO response schema for Path Query and Resource Query functions.
The specification of Path Vector is as defined by the IETF Internet-Draft draft-yang-alto-path-vector.
The cross-domain ALTO solution also requires the ALTO protocol extension Flow-based Cost Query to extend the ALTO request schema.
The specification of FLow-based Cost Query is as defined by the IETF Internet-Draft draft-gao-alto-fcs.