alshabib

Merge branch 'master' of ssh://gerrit.onlab.us:29418/onos-next

Showing 28 changed files with 1757 additions and 25 deletions
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<project xmlns="http://maven.apache.org/POM/4.0.0"
3 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
5 + <modelVersion>4.0.0</modelVersion>
6 +
7 + <parent>
8 + <groupId>org.onlab.onos</groupId>
9 + <artifactId>onos-apps</artifactId>
10 + <version>1.0.0-SNAPSHOT</version>
11 + <relativePath>../pom.xml</relativePath>
12 + </parent>
13 +
14 + <artifactId>onos-app-optical</artifactId>
15 + <packaging>bundle</packaging>
16 +
17 + <description>ONOS application for packet/optical deployments</description>
18 +
19 + <dependencies>
20 +
21 + <dependency>
22 + <groupId>org.onlab.onos</groupId>
23 + <artifactId>onos-cli</artifactId>
24 + <version>${project.version}</version>
25 + </dependency>
26 + <dependency>
27 + <groupId>org.apache.karaf.shell</groupId>
28 + <artifactId>org.apache.karaf.shell.console</artifactId>
29 + </dependency>
30 +
31 + <dependency>
32 + <groupId>org.codehaus.jackson</groupId>
33 + <artifactId>jackson-core-asl</artifactId>
34 + </dependency>
35 + <dependency>
36 + <groupId>org.codehaus.jackson</groupId>
37 + <artifactId>jackson-mapper-asl</artifactId>
38 + </dependency>
39 + <dependency>
40 + <groupId>com.fasterxml.jackson.core</groupId>
41 + <artifactId>jackson-annotations</artifactId>
42 + <scope>provided</scope>
43 + </dependency>
44 +
45 + </dependencies>
46 +
47 +</project>
1 +package org.onlab.onos.optical.cfg;
2 +
3 +import java.util.Map;
4 +import org.codehaus.jackson.JsonNode;
5 +import org.onlab.util.HexString;
6 +
7 +/**
8 + * Public class corresponding to JSON described data model.
9 + */
10 +public class OpticalLinkDescription {
11 + protected String type;
12 + protected Boolean allowed;
13 + protected long dpid1;
14 + protected long dpid2;
15 + protected String nodeDpid1;
16 + protected String nodeDpid2;
17 + protected Map<String, JsonNode> params;
18 + protected Map<String, String> publishAttributes;
19 +
20 + public String getType() {
21 + return type;
22 + }
23 +
24 + public void setType(String type) {
25 + this.type = type;
26 + }
27 +
28 + public Boolean isAllowed() {
29 + return allowed;
30 + }
31 +
32 + public void setAllowed(Boolean allowed) {
33 + this.allowed = allowed;
34 + }
35 +
36 + public String getNodeDpid1() {
37 + return nodeDpid1;
38 + }
39 +
40 + public void setNodeDpid1(String nodeDpid1) {
41 + this.nodeDpid1 = nodeDpid1;
42 + this.dpid1 = HexString.toLong(nodeDpid1);
43 + }
44 +
45 + public String getNodeDpid2() {
46 + return nodeDpid2;
47 + }
48 +
49 + public void setNodeDpid2(String nodeDpid2) {
50 + this.nodeDpid2 = nodeDpid2;
51 + this.dpid2 = HexString.toLong(nodeDpid2);
52 + }
53 +
54 + public long getDpid1() {
55 + return dpid1;
56 + }
57 +
58 + public void setDpid1(long dpid1) {
59 + this.dpid1 = dpid1;
60 + this.nodeDpid1 = HexString.toHexString(dpid1);
61 + }
62 +
63 + public long getDpid2() {
64 + return dpid2;
65 + }
66 +
67 + public void setDpid2(long dpid2) {
68 + this.dpid2 = dpid2;
69 + this.nodeDpid2 = HexString.toHexString(dpid2);
70 + }
71 +
72 + public Map<String, JsonNode> getParams() {
73 + return params;
74 + }
75 +
76 + public void setParams(Map<String, JsonNode> params) {
77 + this.params = params;
78 + }
79 +
80 + public Map<String, String> getPublishAttributes() {
81 + return publishAttributes;
82 + }
83 +
84 + public void setPublishAttributes(Map<String, String> publishAttributes) {
85 + this.publishAttributes = publishAttributes;
86 + }
87 +
88 +}
89 +
1 +package org.onlab.onos.optical.cfg;
2 +
3 +import java.util.ArrayList;
4 +import java.util.List;
5 +
6 +import org.slf4j.Logger;
7 +import org.slf4j.LoggerFactory;
8 +
9 +/**
10 + * Public class corresponding to JSON described data model.
11 + */
12 +public class OpticalNetworkConfig {
13 + protected static final Logger log = LoggerFactory.getLogger(OpticalNetworkConfig.class);
14 +
15 + private List<OpticalSwitchDescription> opticalSwitches;
16 + private List<OpticalLinkDescription> opticalLinks;
17 +
18 + public OpticalNetworkConfig() {
19 + opticalSwitches = new ArrayList<OpticalSwitchDescription>();
20 + opticalLinks = new ArrayList<OpticalLinkDescription>();
21 + }
22 +
23 + public List<OpticalSwitchDescription> getOpticalSwitches() {
24 + return opticalSwitches;
25 + }
26 +
27 + public void setOpticalSwitches(List<OpticalSwitchDescription> switches) {
28 + this.opticalSwitches = switches;
29 + }
30 +
31 + public List<OpticalLinkDescription> getOpticalLinks() {
32 + return opticalLinks;
33 + }
34 +
35 + public void setOpticalLinks(List<OpticalLinkDescription> links) {
36 + this.opticalLinks = links;
37 + }
38 +
39 +}
40 +
1 +package org.onlab.onos.optical.cfg;
2 +
3 +import java.util.Map;
4 +import org.codehaus.jackson.JsonNode;
5 +import org.codehaus.jackson.annotate.JsonProperty;
6 +import org.onlab.util.HexString;
7 +
8 +/**
9 + * Public class corresponding to JSON described data model.
10 + */
11 +public class OpticalSwitchDescription {
12 + protected String name;
13 + protected long dpid;
14 + protected String nodeDpid;
15 + protected String type;
16 + protected double latitude;
17 + protected double longitude;
18 + protected boolean allowed;
19 + protected Map<String, JsonNode> params;
20 + protected Map<String, String> publishAttributes;
21 +
22 + public String getName() {
23 + return name;
24 + }
25 + @JsonProperty("name")
26 + public void setName(String name) {
27 + this.name = name;
28 + }
29 +
30 + public long getDpid() {
31 + return dpid;
32 + }
33 + @JsonProperty("dpid")
34 + public void setDpid(long dpid) {
35 + this.dpid = dpid;
36 + this.nodeDpid = HexString.toHexString(dpid);
37 + }
38 +
39 + public String getNodeDpid() {
40 + return nodeDpid;
41 + }
42 +
43 + public String getHexDpid() {
44 + return nodeDpid;
45 + }
46 +
47 + public void setNodeDpid(String nodeDpid) {
48 + this.nodeDpid = nodeDpid;
49 + this.dpid = HexString.toLong(nodeDpid);
50 + }
51 +
52 + public String getType() {
53 + return type;
54 + }
55 +
56 + public void setType(String type) {
57 + this.type = type;
58 + }
59 +
60 + public double getLatitude() {
61 + return latitude;
62 + }
63 +
64 + public void setLatitude(double latitude) {
65 + this.latitude = latitude;
66 + }
67 +
68 + public double getLongitude() {
69 + return longitude;
70 + }
71 +
72 + public void setLongitude(double longitude) {
73 + this.longitude = longitude;
74 + }
75 +
76 + public boolean isAllowed() {
77 + return allowed;
78 + }
79 +
80 + public void setAllowed(boolean allowed) {
81 + this.allowed = allowed;
82 + }
83 +
84 + public Map<String, JsonNode> getParams() {
85 + return params;
86 + }
87 +
88 + public void setParams(Map<String, JsonNode> params) {
89 + this.params = params;
90 + }
91 +
92 + public Map<String, String> getPublishAttributes() {
93 + return publishAttributes;
94 + }
95 +
96 + public void setPublishAttributes(Map<String, String> publishAttributes) {
97 + this.publishAttributes = publishAttributes;
98 + }
99 +
100 +}
1 +package org.onlab.onos.optical.cfg;
2 +
3 +/**
4 + * Packet-optical link Java data object.
5 + */
6 +class PktOptLink {
7 + private String srcNodeName;
8 + private String snkNodeName;
9 + private String srcNodeId;
10 + private String snkNodeId;
11 + private int srcPort;
12 + private int snkPort;
13 + private double bandwidth;
14 + private double cost;
15 + private long adminWeight;
16 +
17 + public PktOptLink(String srcName, String snkName) {
18 + this.srcNodeName = srcName;
19 + this.snkNodeName = snkName;
20 + }
21 +
22 + public PktOptLink() {
23 + // TODO Auto-generated constructor stub
24 + }
25 +
26 + public void setSrcNodeName(String name) {
27 + this.srcNodeName = name;
28 + }
29 +
30 + public String getSrcNodeName() {
31 + return this.srcNodeName;
32 + }
33 +
34 + public void setSnkNodeName(String name) {
35 + this.snkNodeName = name;
36 + }
37 +
38 + public String getSnkNodeName() {
39 + return this.snkNodeName;
40 + }
41 +
42 + public void setSrcNodeId(String nodeId) {
43 + this.srcNodeId = nodeId;
44 + }
45 +
46 + public String getSrcNodeId() {
47 + return this.srcNodeId;
48 + }
49 +
50 + public void setSnkNodeId(String nodeId) {
51 + this.snkNodeId = nodeId;
52 + }
53 +
54 + public String getSnkNodeId() {
55 + return this.snkNodeId;
56 + }
57 +
58 + public void setSrcPort(int port) {
59 + this.srcPort = port;
60 + }
61 +
62 + public int getSrcPort() {
63 + return this.srcPort;
64 + }
65 +
66 + public void setSnkPort(int port) {
67 + this.snkPort = port;
68 + }
69 +
70 + public int getSnkPort() {
71 + return this.snkPort;
72 + }
73 +
74 + public void setBandwdith(double x) {
75 + this.bandwidth = x;
76 + }
77 +
78 + public double getBandwidth() {
79 + return this.bandwidth;
80 + }
81 +
82 + public void setCost(double x) {
83 + this.cost = x;
84 + }
85 +
86 + public double getCost() {
87 + return this.cost;
88 + }
89 +
90 + public void setAdminWeight(long x) {
91 + this.adminWeight = x;
92 + }
93 +
94 + public long getAdminWeight() {
95 + return this.adminWeight;
96 + }
97 +
98 + @Override
99 + public String toString() {
100 + return new StringBuilder(" srcNodeName: ").append(this.srcNodeName)
101 + .append(" snkNodeName: ").append(this.snkNodeName)
102 + .append(" srcNodeId: ").append(this.srcNodeId)
103 + .append(" snkNodeId: ").append(this.snkNodeId)
104 + .append(" srcPort: ").append(this.srcPort)
105 + .append(" snkPort: ").append(this.snkPort)
106 + .append(" bandwidth: ").append(this.bandwidth)
107 + .append(" cost: ").append(this.cost)
108 + .append(" adminWeight: ").append(this.adminWeight).toString();
109 + }
110 +}
1 +package org.onlab.onos.optical.cfg;
2 +
3 +/**
4 + * ROADM java data object converted from a JSON file.
5 + */
6 +class Roadm {
7 + private String name;
8 + private String nodeID;
9 + private double longtitude;
10 + private double latitude;
11 + private int regenNum;
12 +
13 + //TODO use the following attributes when needed for configurations
14 + private int tPort10G;
15 + private int tPort40G;
16 + private int tPort100G;
17 + private int wPort;
18 +
19 + public Roadm() {
20 + }
21 +
22 + public Roadm(String name) {
23 + this.name = name;
24 + }
25 +
26 + public void setName(String name) {
27 + this.name = name;
28 + }
29 +
30 + public String getName() {
31 + return this.name;
32 + }
33 +
34 + public void setNodeId(String nameId) {
35 + this.nodeID = nameId;
36 + }
37 +
38 + public String getNodeId() {
39 + return this.nodeID;
40 + }
41 +
42 + public void setLongtitude(double x) {
43 + this.longtitude = x;
44 + }
45 +
46 + public double getLongtitude() {
47 + return this.longtitude;
48 + }
49 +
50 + public void setLatitude(double y) {
51 + this.latitude = y;
52 + }
53 +
54 + public double getLatitude() {
55 + return this.latitude;
56 + }
57 +
58 + public void setRegenNum(int num) {
59 + this.regenNum = num;
60 + }
61 + public int getRegenNum() {
62 + return this.regenNum;
63 + }
64 +
65 + public void setTport10GNum(int num) {
66 + this.tPort10G = num;
67 + }
68 + public int getTport10GNum() {
69 + return this.tPort10G;
70 + }
71 +
72 + public void setTport40GNum(int num) {
73 + this.tPort40G = num;
74 + }
75 + public int getTport40GNum() {
76 + return this.tPort40G;
77 + }
78 +
79 + public void setTport100GNum(int num) {
80 + this.tPort100G = num;
81 + }
82 + public int getTport100GNum() {
83 + return this.tPort100G;
84 + }
85 +
86 + public void setWportNum(int num) {
87 + this.wPort = num;
88 + }
89 + public int getWportNum() {
90 + return this.wPort;
91 + }
92 +
93 + @Override
94 + public String toString() {
95 + return new StringBuilder(" ROADM Name: ").append(this.name)
96 + .append(" nodeID: ").append(this.nodeID)
97 + .append(" longtitude: ").append(this.longtitude)
98 + .append(" latitude: ").append(this.latitude)
99 + .append(" regenNum: ").append(this.regenNum)
100 + .append(" 10GTportNum: ").append(this.tPort10G)
101 + .append(" 40GTportNum: ").append(this.tPort40G)
102 + .append(" 100GTportNum: ").append(this.tPort100G)
103 + .append(" WportNum: ").append(this.wPort).toString();
104 + }
105 +}
106 +
1 +package org.onlab.onos.optical.cfg;
2 +
3 +/**
4 + * WDM Link Java data object converted from a JSON file.
5 + */
6 +class WdmLink {
7 + private String srcNodeName;
8 + private String snkNodeName;
9 + private String srcNodeId;
10 + private String snkNodeId;
11 + private int srcPort;
12 + private int snkPort;
13 + private double distance;
14 + private double cost;
15 + private int wavelengthNumber;
16 + private long adminWeight;
17 +
18 + public WdmLink(String name1, String name2) {
19 + this.srcNodeName = name1;
20 + this.snkNodeName = name2;
21 + }
22 +
23 + public WdmLink() {
24 + // TODO Auto-generated constructor stub
25 + }
26 +
27 + public void setSrcNodeName(String name) {
28 + this.srcNodeName = name;
29 + }
30 +
31 + public String getSrcNodeName() {
32 + return this.srcNodeName;
33 + }
34 +
35 + public void setSnkNodeName(String name) {
36 + this.snkNodeName = name;
37 + }
38 +
39 + public String getSnkNodeName() {
40 + return this.snkNodeName;
41 + }
42 +
43 + public void setSrcNodeId(String nodeId) {
44 + this.srcNodeId = nodeId;
45 + }
46 +
47 + public String getSrcNodeId() {
48 + return this.srcNodeId;
49 + }
50 +
51 + public void setSnkNodeId(String nodeId) {
52 + this.snkNodeId = nodeId;
53 + }
54 +
55 + public String getSnkNodeId() {
56 + return this.snkNodeId;
57 + }
58 +
59 + public void setSrcPort(int port) {
60 + this.srcPort = port;
61 + }
62 +
63 + public int getSrcPort() {
64 + return this.srcPort;
65 + }
66 +
67 + public void setSnkPort(int port) {
68 + this.snkPort = port;
69 + }
70 +
71 + public int getSnkPort() {
72 + return this.snkPort;
73 + }
74 +
75 + public void setDistance(double x) {
76 + this.distance = x;
77 + }
78 +
79 + public double getDistance() {
80 + return this.distance;
81 + }
82 +
83 + public void setCost(double x) {
84 + this.cost = x;
85 + }
86 +
87 + public double getCost() {
88 + return this.cost;
89 + }
90 +
91 + public void setWavelengthNumber(int x) {
92 + this.wavelengthNumber = x;
93 + }
94 +
95 + public int getWavelengthNumber() {
96 + return this.wavelengthNumber;
97 + }
98 +
99 + public void setAdminWeight(long x) {
100 + this.adminWeight = x;
101 + }
102 +
103 + public long getAdminWeight() {
104 + return this.adminWeight;
105 + }
106 +
107 + @Override
108 + public String toString() {
109 + return new StringBuilder(" srcNodeName: ").append(this.srcNodeName)
110 + .append(" snkNodeName: ").append(this.snkNodeName)
111 + .append(" srcNodeId: ").append(this.srcNodeId)
112 + .append(" snkNodeId: ").append(this.snkNodeId)
113 + .append(" srcPort: ").append(this.srcPort)
114 + .append(" snkPort: ").append(this.snkPort)
115 + .append(" distance: ").append(this.distance)
116 + .append(" cost: ").append(this.cost)
117 + .append(" wavelengthNumber: ").append(this.wavelengthNumber)
118 + .append(" adminWeight: ").append(this.adminWeight).toString();
119 + }
120 +}
121 +
1 +{
2 + "opticalSwitches": [
3 + {
4 + "allowed": true,
5 + "latitude": 37.6,
6 + "longitude": 122.3,
7 + "name": "SFO-W10",
8 + "nodeDpid": "00:00:ff:ff:ff:ff:ff:01",
9 + "params": {
10 + "numRegen": 0
11 + },
12 + "type": "Roadm"
13 + },
14 +
15 + {
16 + "allowed": true,
17 + "latitude": 37.3,
18 + "longitude": 121.9,
19 + "name": "SJC-W10",
20 + "nodeDpid": "00:00:ff:ff:ff:ff:ff:02",
21 + "params": {
22 + "numRegen": 0
23 + },
24 + "type": "Roadm"
25 + },
26 +
27 + {
28 + "allowed": true,
29 + "latitude": 33.9,
30 + "longitude": 118.4
31 + "name": "LAX-W10",
32 + "nodeDpid": "00:00:ff:ff:ff:ff:ff:03",
33 + "params": {
34 + "numRegen": 0
35 + },
36 + "type": "Roadm"
37 + },
38 +
39 + {
40 + "allowed": true,
41 + "latitude": 32.8,
42 + "longitude": 117.1,
43 + "name": "SDG-W10",
44 + "nodeDpid": "00:00:ff:ff:ff:ff:ff:04",
45 + "params": {
46 + "numRegen": 3
47 + },
48 + "type": "Roadm"
49 + },
50 +
51 + {
52 + "allowed": true,
53 + "latitude": 44.8,
54 + "longitude": 93.1,
55 + "name": "MSP-M10",
56 + "nodeDpid": "00:00:ff:ff:ff:ff:ff:05",
57 + "params": {
58 + "numRegen": 3
59 + },
60 + "type": "Roadm"
61 + },
62 +
63 + {
64 + "allowed": true,
65 + "latitude": 32.8,
66 + "longitude": 97.1,
67 + "name": "DFW-M10",
68 + "nodeDpid": "00:00:ff:ff:ff:ff:ff:06",
69 + "params": {
70 + "numRegen": 3
71 + },
72 + "type": "Roadm"
73 + },
74 +
75 + {
76 + "allowed": true,
77 + "latitude": 41.8,
78 + "longitude": 120.1,
79 + "name": "CHG-N10",
80 + "nodeDpid": "00:00:ff:ff:ff:ff:ff:07",
81 + "params": {
82 + "numRegen": 3
83 + },
84 + "type": "Roadm"
85 + },
86 +
87 + {
88 + "allowed": true,
89 + "latitude": 38.8,
90 + "longitude": 77.1,
91 + "name": "IAD-M10",
92 + "nodeDpid": "00:00:ff:ff:ff:ff:ff:08",
93 + "params": {
94 + "numRegen": 3
95 + },
96 + "type": "Roadm"
97 + },
98 +
99 + {
100 + "allowed": true,
101 + "latitude": 40.8,
102 + "longitude": 73.1,
103 + "name": "JFK-E10",
104 + "nodeDpid": "00:00:ff:ff:ff:ff:ff:09",
105 + "params": {
106 + "numRegen": 0
107 + },
108 + "type": "Roadm"
109 +
110 + },
111 +
112 + {
113 + "allowed": true,
114 + "latitude": 33.8,
115 + "longitude": 84.1,
116 + "name": "ATL-S10",
117 + "nodeDpid": "00:00:ff:ff:ff:ff:ff:0A",
118 + "params": {
119 + "numRegen": 0
120 + },
121 + "type": "Roadm"
122 + }
123 +
124 + ],
125 +
126 + "opticalLinks": [
127 + {
128 + "allowed": true,
129 + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:01",
130 + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:02",
131 + "params": {
132 + "distKms": 1000,
133 + "nodeName1": "SFO-W10",
134 + "nodeName2": "SJC-W10",
135 + "numWaves": 80,
136 + "port1": 10,
137 + "port2": 10
138 + },
139 + "type": "wdmLink"
140 + },
141 +
142 + {
143 + "allowed": true,
144 + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:02",
145 + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:03",
146 + "params": {
147 + "distKms": 1000,
148 + "nodeName1": "SJC-W10",
149 + "nodeName2": "LAX-W10",
150 + "numWaves": 80,
151 + "port1": 20,
152 + "port2": 10
153 + },
154 + "type": "wdmLink"
155 + },
156 +
157 + {
158 + "allowed": true,
159 + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:03",
160 + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:04",
161 + "params": {
162 + "distKms": 1000,
163 + "nodeName1": "LAX-W10",
164 + "nodeName2": "SDG-W10",
165 + "numWaves": 80,
166 + "port1": 30,
167 + "port2": 10
168 + },
169 + "type": "wdmLink"
170 + },
171 +
172 + {
173 + "allowed": true,
174 + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:02",
175 + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:05",
176 + "params": {
177 + "distKms": 4000,
178 + "nodeName1": "SJC-W10",
179 + "nodeName2": "MSP-M10",
180 + "numWaves": 80,
181 + "port1": 20,
182 + "port2": 10
183 + },
184 + "type": "wdmLink"
185 + },
186 +
187 + {
188 +
189 + "allowed": true,
190 + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:03",
191 + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:06",
192 + "params": {
193 + "distKms": 5000,
194 + "nodeName1": "LAX-W10",
195 + "nodeName2": "DFW-M10",
196 + "numWaves": 80,
197 + "port1": 20,
198 + "port2": 10
199 + },
200 + "type": "wdmLink"
201 + },
202 +
203 + {
204 + "allowed": true,
205 + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:05",
206 + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:06",
207 + "params": {
208 + "distKms": 3000,
209 + "nodeName1": "MSP-M10",
210 + "nodeName2": "DFW-M10",
211 + "numWaves": 80,
212 + "port1": 30,
213 + "port2": 20
214 + },
215 + "type": "wdmLink"
216 + },
217 +
218 + {
219 + "allowed": true,
220 + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:05",
221 + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:07",
222 + "params": {
223 + "distKms": 3000,
224 + "nodeName1": "MSP-M10",
225 + "nodeName2": "CHG-N10",
226 + "numWaves": 80,
227 + "port1": 20,
228 + "port2": 21
229 + },
230 + "type": "wdmLink"
231 + },
232 +
233 + {
234 +
235 + "allowed": true,
236 + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:06",
237 + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:08",
238 + "params": {
239 + "distKms": 4000,
240 + "nodeName1": "DFW-M10",
241 + "nodeName2": "IAD-M10",
242 + "numWaves": 80,
243 + "port1": 30,
244 + "port2": 10
245 + },
246 + "type": "wdmLink"
247 + },
248 +
249 + {
250 +
251 + "allowed": true,
252 + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:07",
253 + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:08",
254 + "params": {
255 + "distKms": 4000,
256 + "nodeName1": "CHG-M10",
257 + "nodeName2": "IAD-M10",
258 + "numWaves": 80,
259 + "port1": 30,
260 + "port2": 20
261 + },
262 + "type": "wdmLink"
263 + },
264 +
265 + {
266 + "allowed": true,
267 + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:07",
268 + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:09",
269 + "params": {
270 + "distKms": 5000,
271 + "nodeName1": "CHG-M10",
272 + "nodeName2": "JFK-E10",
273 + "numWaves": 80,
274 + "port1": 20,
275 + "port2": 10
276 + },
277 + "type": "wdmLink"
278 + },
279 +
280 + {
281 + "allowed": true,
282 + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:08",
283 + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:0A",
284 + "params": {
285 + "distKms": 3000,
286 + "nodeName1": "IAD-M10",
287 + "nodeName2": "ATL-S10",
288 + "numWaves": 80,
289 + "port1": 30,
290 + "port2": 10
291 + },
292 + "type": "wdmLink"
293 + },
294 +
295 + {
296 +
297 + "allowed": true,
298 + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:09",
299 + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:0A",
300 + "params": {
301 + "distKms": 4000,
302 + "nodeName1": "JFK-E10",
303 + "nodeName2": "ATL-S10",
304 + "numWaves": 80,
305 + "port1": 20,
306 + "port2": 20
307 + },
308 + "type": "wdmLink"
309 + },
310 +
311 +
312 + {
313 + "allowed": true,
314 + "nodeDpid1": "00:00:ff:ff:ff:ff:00:01",
315 + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:01",
316 + "params": {
317 + "nodeName1": "SFO-R10",
318 + "nodeName2": "SFO-W10",
319 + "port1": 10,
320 + "port2": 1
321 + },
322 + "type": "pktOptLink"
323 + },
324 +
325 + {
326 + "allowed": true,
327 + "nodeDpid1": "00:00:ff:ff:ff:ff:00:03",
328 + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:03",
329 + "params": {
330 + "nodeName1": "LAX-R10",
331 + "nodeName2": "LAX-W10",
332 + "port1": 10,
333 + "port2": 1
334 + },
335 + "type": "pktOptLink"
336 + },
337 +
338 + {
339 + "allowed": true,
340 + "nodeDpid1": "00:00:ff:ff:ff:ff:00:04",
341 + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:04",
342 + "params": {
343 + "nodeName1": "SDG-R10",
344 + "nodeName2": "SDG-W10",
345 + "port1": 10,
346 + "port2": 1
347 + },
348 + "type": "pktOptLink"
349 + },
350 +
351 + {
352 + "allowed": true,
353 + "nodeDpid1": "00:00:ff:ff:ff:ff:00:07",
354 + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:07",
355 + "params": {
356 + "nodeName1": "CHG-R10",
357 + "nodeName2": "CHG-W10",
358 + "port1": 10,
359 + "port2": 1
360 + },
361 + "type": "pktOptLink"
362 + },
363 +
364 + {
365 + "allowed": true,
366 + "nodeDpid1": "00:00:ff:ff:ff:ff:00:09",
367 + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:09",
368 + "params": {
369 + "nodeName1": "JFK-R10",
370 + "nodeName2": "JFK-W10",
371 + "port1": 10,
372 + "port2": 1
373 + },
374 + "type": "pktOptLink"
375 + },
376 +
377 + {
378 + "allowed": true,
379 + "nodeDpid1": "00:00:ff:ff:ff:ff:00:0A",
380 + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:0A",
381 + "params": {
382 + "nodeName1": "ATL-R10",
383 + "nodeName2": "ATL-W10",
384 + "port1": 10,
385 + "port2": 1
386 + },
387 + "type": "pktOptLink"
388 + },
389 +
390 + ]
391 +}
1 +{
2 + "opticalSwitches": [
3 + {
4 + "allowed": true,
5 + "latitude": 37.6,
6 + "longitude": 122.3,
7 + "name": "ROADM1",
8 + "nodeDpid": "00:00:ff:ff:ff:ff:ff:01",
9 + "params": {
10 + "numRegen": 0
11 + },
12 + "type": "Roadm"
13 + },
14 +
15 + {
16 + "allowed": true,
17 + "latitude": 37.3,
18 + "longitude": 121.9,
19 + "name": "ROADM2",
20 + "nodeDpid": "00:00:ff:ff:ff:ff:ff:02",
21 + "params": {
22 + "numRegen": 0
23 + },
24 + "type": "Roadm"
25 + },
26 +
27 + {
28 + "allowed": true,
29 + "latitude": 33.9,
30 + "longitude": 118.4,
31 + "name": "ROADM3",
32 + "nodeDpid": "00:00:ff:ff:ff:ff:ff:03",
33 + "params": {
34 + "numRegen": 2
35 + },
36 + "type": "Roadm"
37 + }
38 + ],
39 +
40 + "opticalLinks": [
41 + {
42 + "allowed": true,
43 + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:01",
44 + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:03",
45 + "params": {
46 + "distKms": 1000,
47 + "nodeName1": "ROADM1",
48 + "nodeName2": "ROADM3",
49 + "numWaves": 80,
50 + "port1": 10,
51 + "port2": 30
52 + },
53 + "type": "wdmLink"
54 + },
55 +
56 + {
57 + "allowed": true,
58 + "nodeDpid1": "00:00:ff:ff:ff:ff:ff:03",
59 + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:02",
60 + "params": {
61 + "distKms": 2000,
62 + "nodeName1": "ROADM3",
63 + "nodeName2": "ROADM2",
64 + "numWaves": 80,
65 + "port1": 31,
66 + "port2": 20
67 + },
68 + "type": "wdmLink"
69 + },
70 +
71 +
72 + {
73 + "allowed": true,
74 + "nodeDpid1": "00:00:ff:ff:ff:ff:00:01",
75 + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:01",
76 + "params": {
77 + "nodeName1": "ROUTER1",
78 + "nodeName2": "ROADM1",
79 + "bandWidth": 100000,
80 + "port1": 10,
81 + "port2": 11
82 + },
83 + "type": "pktOptLink"
84 + },
85 +
86 + {
87 + "allowed": true,
88 + "nodeDpid1": "00:00:ff:ff:ff:ff:00:02",
89 + "nodeDpid2": "00:00:ff:ff:ff:ff:ff:02",
90 + "params": {
91 + "nodeName1": "ROUTER2",
92 + "nodeName2": "ROADM2",
93 + "bandWidth": 100000,
94 + "port1": 10,
95 + "port2": 21
96 + },
97 + "type": "pktOptLink"
98 + }
99 +
100 + ]
101 +}
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
26 <module>config</module> 26 <module>config</module>
27 <module>sdnip</module> 27 <module>sdnip</module>
28 <module>calendar</module> 28 <module>calendar</module>
29 + <module>optical</module>
29 </modules> 30 </modules>
30 31
31 <properties> 32 <properties>
......
...@@ -37,6 +37,15 @@ public interface ClusterCommunicationService { ...@@ -37,6 +37,15 @@ public interface ClusterCommunicationService {
37 boolean multicast(ClusterMessage message, Set<NodeId> nodeIds) throws IOException; 37 boolean multicast(ClusterMessage message, Set<NodeId> nodeIds) throws IOException;
38 38
39 /** 39 /**
40 + * Sends a message synchronously.
41 + * @param message message to send
42 + * @param toNodeId recipient node identifier
43 + * @return ClusterMessageResponse which is reply future.
44 + * @throws IOException
45 + */
46 + ClusterMessageResponse sendAndReceive(ClusterMessage message, NodeId toNodeId) throws IOException;
47 +
48 + /**
40 * Adds a new subscriber for the specified message subject. 49 * Adds a new subscriber for the specified message subject.
41 * 50 *
42 * @param subject message subject 51 * @param subject message subject
......
1 +package org.onlab.onos.store.cluster.messaging;
2 +
3 +import java.util.concurrent.TimeUnit;
4 +import java.util.concurrent.TimeoutException;
5 +
6 +import org.onlab.onos.cluster.NodeId;
7 +
8 +public interface ClusterMessageResponse {
9 + public NodeId sender();
10 + public byte[] get(long timeout, TimeUnit timeunit) throws TimeoutException;
11 + public byte[] get(long timeout) throws InterruptedException;
12 +}
...@@ -43,7 +43,7 @@ public class PointToPointIntentCompiler ...@@ -43,7 +43,7 @@ public class PointToPointIntentCompiler
43 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 43 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
44 protected HostService hostService; 44 protected HostService hostService;
45 45
46 - private IdGenerator<IntentId> intentIdGenerator; 46 + protected IdGenerator<IntentId> intentIdGenerator;
47 47
48 @Activate 48 @Activate
49 public void activate() { 49 public void activate() {
......
...@@ -167,6 +167,7 @@ public class ProxyArpManager implements ProxyArpService { ...@@ -167,6 +167,7 @@ public class ProxyArpManager implements ProxyArpService {
167 return; 167 return;
168 } 168 }
169 169
170 + // TODO find the correct IP address
170 Ethernet arpReply = buildArpReply(dst.ipAddresses().iterator().next(), 171 Ethernet arpReply = buildArpReply(dst.ipAddresses().iterator().next(),
171 dst.mac(), eth); 172 dst.mac(), eth);
172 // TODO: check send status with host service. 173 // TODO: check send status with host service.
......
1 +package org.onlab.onos.net.intent;
2 +
3 +import org.junit.Test;
4 +import org.onlab.onos.net.ConnectPoint;
5 +import org.onlab.onos.net.flow.TrafficSelector;
6 +import org.onlab.onos.net.flow.TrafficTreatment;
7 +
8 +import static org.hamcrest.MatcherAssert.assertThat;
9 +import static org.hamcrest.Matchers.equalTo;
10 +import static org.hamcrest.Matchers.is;
11 +import static org.hamcrest.Matchers.not;
12 +import static org.onlab.onos.net.NetTestTools.connectPoint;
13 +
14 +/**
15 + * Unit tests for the HostToHostIntent class.
16 + */
17 +public class TestPointToPointIntent {
18 +
19 + private TrafficSelector selector = new IntentTestsMocks.MockSelector();
20 + private TrafficTreatment treatment = new IntentTestsMocks.MockTreatment();
21 +
22 + private ConnectPoint point1 = connectPoint("dev1", 1);
23 + private ConnectPoint point2 = connectPoint("dev2", 1);
24 +
25 + private PointToPointIntent makePointToPoint(long id,
26 + ConnectPoint ingress,
27 + ConnectPoint egress) {
28 + return new PointToPointIntent(new IntentId(id),
29 + selector,
30 + treatment,
31 + ingress,
32 + egress);
33 + }
34 +
35 + /**
36 + * Tests the equals() method where two PointToPointIntents have references
37 + * to the same ingress and egress points. These should compare equal.
38 + */
39 + @Test
40 + public void testSameEquals() {
41 + PointToPointIntent i1 = makePointToPoint(12, point1, point2);
42 + PointToPointIntent i2 = makePointToPoint(12, point1, point2);
43 +
44 + assertThat(i1, is(equalTo(i2)));
45 + }
46 +
47 + /**
48 + * Tests the equals() method where two HostToHostIntents have references
49 + * to different Hosts. These should compare not equal.
50 + */
51 + @Test
52 + public void testLinksDifferentEquals() {
53 +
54 + PointToPointIntent i1 = makePointToPoint(12, point1, point2);
55 + PointToPointIntent i2 = makePointToPoint(12, point2, point1);
56 +
57 + assertThat(i1, is(not(equalTo(i2))));
58 + }
59 +
60 + /**
61 + * Tests the equals() method where two HostToHostIntents have different
62 + * ids. These should compare not equal.
63 + */
64 + @Test
65 + public void testBaseDifferentEquals() {
66 + PointToPointIntent i1 = makePointToPoint(12, point1, point2);
67 + PointToPointIntent i2 = makePointToPoint(11, point1, point2);
68 +
69 +
70 + assertThat(i1, is(not(equalTo(i2))));
71 + }
72 +
73 + /**
74 + * Tests that the hashCode() values for two equivalent HostToHostIntent
75 + * objects are the same.
76 + */
77 + @Test
78 + public void testHashCodeEquals() {
79 + PointToPointIntent i1 = makePointToPoint(12, point1, point2);
80 + PointToPointIntent i2 = makePointToPoint(12, point1, point2);
81 +
82 + assertThat(i1.hashCode(), is(equalTo(i2.hashCode())));
83 + }
84 +
85 + /**
86 + * Tests that the hashCode() values for two distinct LinkCollectionIntent
87 + * objects are different.
88 + */
89 + @Test
90 + public void testHashCodeDifferent() {
91 + PointToPointIntent i1 = makePointToPoint(12, point1, point2);
92 + PointToPointIntent i2 = makePointToPoint(22, point1, point2);
93 +
94 + assertThat(i1.hashCode(), is(not(equalTo(i2.hashCode()))));
95 + }
96 +}
1 +package org.onlab.onos.net.intent.impl;
2 +
3 +import java.util.List;
4 +
5 +import org.hamcrest.Matchers;
6 +import org.junit.Test;
7 +import org.onlab.onos.net.flow.TrafficSelector;
8 +import org.onlab.onos.net.flow.TrafficTreatment;
9 +import org.onlab.onos.net.intent.Intent;
10 +import org.onlab.onos.net.intent.IntentId;
11 +import org.onlab.onos.net.intent.IntentTestsMocks;
12 +import org.onlab.onos.net.intent.PathIntent;
13 +import org.onlab.onos.net.intent.PointToPointIntent;
14 +
15 +import static org.hamcrest.CoreMatchers.notNullValue;
16 +import static org.hamcrest.MatcherAssert.assertThat;
17 +import static org.hamcrest.Matchers.hasSize;
18 +import static org.hamcrest.Matchers.is;
19 +import static org.onlab.onos.net.NetTestTools.connectPoint;
20 +import static org.onlab.onos.net.intent.LinksHaveEntryWithSourceDestinationPairMatcher.linksHasPath;
21 +
22 +/**
23 + * Unit tests for the HostToHost intent compiler.
24 + */
25 +public class TestPointToPointIntentCompiler {
26 +
27 + private TrafficSelector selector = new IntentTestsMocks.MockSelector();
28 + private TrafficTreatment treatment = new IntentTestsMocks.MockTreatment();
29 +
30 + /**
31 + * Creates a PointToPoint intent based on ingress and egress device Ids.
32 + *
33 + * @param ingressIdString string for id of ingress device
34 + * @param egressIdString string for id of egress device
35 + * @return PointToPointIntent for the two devices
36 + */
37 + private PointToPointIntent makeIntent(String ingressIdString,
38 + String egressIdString) {
39 + return new PointToPointIntent(new IntentId(12),
40 + selector,
41 + treatment,
42 + connectPoint(ingressIdString, 1),
43 + connectPoint(egressIdString, 1));
44 + }
45 +
46 + /**
47 + * Creates a compiler for HostToHost intents.
48 + *
49 + * @param hops string array describing the path hops to use when compiling
50 + * @return HostToHost intent compiler
51 + */
52 + private PointToPointIntentCompiler makeCompiler(String[] hops) {
53 + PointToPointIntentCompiler compiler =
54 + new PointToPointIntentCompiler();
55 + compiler.pathService = new IntentTestsMocks.MockPathService(hops);
56 + IdBlockAllocator idBlockAllocator = new DummyIdBlockAllocator();
57 + compiler.intentIdGenerator =
58 + new IdBlockAllocatorBasedIntentIdGenerator(idBlockAllocator);
59 + return compiler;
60 + }
61 +
62 +
63 + /**
64 + * Tests a pair of devices in an 8 hop path, forward direction.
65 + */
66 + @Test
67 + public void testForwardPathCompilation() {
68 +
69 + PointToPointIntent intent = makeIntent("d1", "d8");
70 + assertThat(intent, is(notNullValue()));
71 +
72 + String[] hops = {"d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8"};
73 + PointToPointIntentCompiler compiler = makeCompiler(hops);
74 + assertThat(compiler, is(notNullValue()));
75 +
76 + List<Intent> result = compiler.compile(intent);
77 + assertThat(result, is(Matchers.notNullValue()));
78 + assertThat(result, hasSize(1));
79 + Intent forwardResultIntent = result.get(0);
80 + assertThat(forwardResultIntent instanceof PathIntent, is(true));
81 +
82 + if (forwardResultIntent instanceof PathIntent) {
83 + PathIntent forwardPathIntent = (PathIntent) forwardResultIntent;
84 + // 7 links for the hops, plus one default lnk on ingress and egress
85 + assertThat(forwardPathIntent.path().links(), hasSize(hops.length + 1));
86 + assertThat(forwardPathIntent.path().links(), linksHasPath("d1", "d2"));
87 + assertThat(forwardPathIntent.path().links(), linksHasPath("d2", "d3"));
88 + assertThat(forwardPathIntent.path().links(), linksHasPath("d3", "d4"));
89 + assertThat(forwardPathIntent.path().links(), linksHasPath("d4", "d5"));
90 + assertThat(forwardPathIntent.path().links(), linksHasPath("d5", "d6"));
91 + assertThat(forwardPathIntent.path().links(), linksHasPath("d6", "d7"));
92 + assertThat(forwardPathIntent.path().links(), linksHasPath("d7", "d8"));
93 + }
94 + }
95 +
96 + /**
97 + * Tests a pair of devices in an 8 hop path, forward direction.
98 + */
99 + @Test
100 + public void testReversePathCompilation() {
101 +
102 + PointToPointIntent intent = makeIntent("d8", "d1");
103 + assertThat(intent, is(notNullValue()));
104 +
105 + String[] hops = {"d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8"};
106 + PointToPointIntentCompiler compiler = makeCompiler(hops);
107 + assertThat(compiler, is(notNullValue()));
108 +
109 + List<Intent> result = compiler.compile(intent);
110 + assertThat(result, is(Matchers.notNullValue()));
111 + assertThat(result, hasSize(1));
112 + Intent reverseResultIntent = result.get(0);
113 + assertThat(reverseResultIntent instanceof PathIntent, is(true));
114 +
115 + if (reverseResultIntent instanceof PathIntent) {
116 + PathIntent reversePathIntent = (PathIntent) reverseResultIntent;
117 + assertThat(reversePathIntent.path().links(), hasSize(hops.length + 1));
118 + assertThat(reversePathIntent.path().links(), linksHasPath("d2", "d1"));
119 + assertThat(reversePathIntent.path().links(), linksHasPath("d3", "d2"));
120 + assertThat(reversePathIntent.path().links(), linksHasPath("d4", "d3"));
121 + assertThat(reversePathIntent.path().links(), linksHasPath("d5", "d4"));
122 + assertThat(reversePathIntent.path().links(), linksHasPath("d6", "d5"));
123 + assertThat(reversePathIntent.path().links(), linksHasPath("d7", "d6"));
124 + assertThat(reversePathIntent.path().links(), linksHasPath("d8", "d7"));
125 + }
126 + }
127 +}
...@@ -4,6 +4,9 @@ import static com.google.common.base.Preconditions.checkArgument; ...@@ -4,6 +4,9 @@ import static com.google.common.base.Preconditions.checkArgument;
4 4
5 import java.io.IOException; 5 import java.io.IOException;
6 import java.util.Set; 6 import java.util.Set;
7 +import java.util.concurrent.TimeUnit;
8 +import java.util.concurrent.TimeoutException;
9 +
7 import org.apache.felix.scr.annotations.Activate; 10 import org.apache.felix.scr.annotations.Activate;
8 import org.apache.felix.scr.annotations.Component; 11 import org.apache.felix.scr.annotations.Component;
9 import org.apache.felix.scr.annotations.Deactivate; 12 import org.apache.felix.scr.annotations.Deactivate;
...@@ -17,6 +20,7 @@ import org.onlab.onos.store.cluster.impl.ClusterMembershipEvent; ...@@ -17,6 +20,7 @@ import org.onlab.onos.store.cluster.impl.ClusterMembershipEvent;
17 import org.onlab.onos.store.cluster.messaging.ClusterCommunicationService; 20 import org.onlab.onos.store.cluster.messaging.ClusterCommunicationService;
18 import org.onlab.onos.store.cluster.messaging.ClusterMessage; 21 import org.onlab.onos.store.cluster.messaging.ClusterMessage;
19 import org.onlab.onos.store.cluster.messaging.ClusterMessageHandler; 22 import org.onlab.onos.store.cluster.messaging.ClusterMessageHandler;
23 +import org.onlab.onos.store.cluster.messaging.ClusterMessageResponse;
20 import org.onlab.onos.store.cluster.messaging.MessageSubject; 24 import org.onlab.onos.store.cluster.messaging.MessageSubject;
21 import org.onlab.onos.store.serializers.ClusterMessageSerializer; 25 import org.onlab.onos.store.serializers.ClusterMessageSerializer;
22 import org.onlab.onos.store.serializers.KryoPoolUtil; 26 import org.onlab.onos.store.serializers.KryoPoolUtil;
...@@ -28,6 +32,7 @@ import org.onlab.netty.Message; ...@@ -28,6 +32,7 @@ import org.onlab.netty.Message;
28 import org.onlab.netty.MessageHandler; 32 import org.onlab.netty.MessageHandler;
29 import org.onlab.netty.MessagingService; 33 import org.onlab.netty.MessagingService;
30 import org.onlab.netty.NettyMessagingService; 34 import org.onlab.netty.NettyMessagingService;
35 +import org.onlab.netty.Response;
31 import org.slf4j.Logger; 36 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory; 37 import org.slf4j.LoggerFactory;
33 38
...@@ -120,6 +125,22 @@ public class ClusterCommunicationManager ...@@ -120,6 +125,22 @@ public class ClusterCommunicationManager
120 } 125 }
121 126
122 @Override 127 @Override
128 + public ClusterMessageResponse sendAndReceive(ClusterMessage message, NodeId toNodeId) throws IOException {
129 + ControllerNode node = clusterService.getNode(toNodeId);
130 + checkArgument(node != null, "Unknown nodeId: %s", toNodeId);
131 + Endpoint nodeEp = new Endpoint(node.ip().toString(), node.tcpPort());
132 + try {
133 + Response responseFuture =
134 + messagingService.sendAndReceive(nodeEp, message.subject().value(), SERIALIZER.encode(message));
135 + return new InternalClusterMessageResponse(toNodeId, responseFuture);
136 +
137 + } catch (IOException e) {
138 + log.error("Failed interaction with remote nodeId: " + toNodeId, e);
139 + throw e;
140 + }
141 + }
142 +
143 + @Override
123 public void addSubscriber(MessageSubject subject, 144 public void addSubscriber(MessageSubject subject,
124 ClusterMessageHandler subscriber) { 145 ClusterMessageHandler subscriber) {
125 messagingService.registerHandler(subject.value(), new InternalClusterMessageHandler(subscriber)); 146 messagingService.registerHandler(subject.value(), new InternalClusterMessageHandler(subscriber));
...@@ -144,4 +165,30 @@ public class ClusterCommunicationManager ...@@ -144,4 +165,30 @@ public class ClusterCommunicationManager
144 } 165 }
145 } 166 }
146 } 167 }
168 +
169 + private static final class InternalClusterMessageResponse implements ClusterMessageResponse {
170 +
171 + private final NodeId sender;
172 + private final Response responseFuture;
173 +
174 + public InternalClusterMessageResponse(NodeId sender, Response responseFuture) {
175 + this.sender = sender;
176 + this.responseFuture = responseFuture;
177 + }
178 + @Override
179 + public NodeId sender() {
180 + return sender;
181 + }
182 +
183 + @Override
184 + public byte[] get(long timeout, TimeUnit timeunit)
185 + throws TimeoutException {
186 + return responseFuture.get(timeout, timeunit);
187 + }
188 +
189 + @Override
190 + public byte[] get(long timeout) throws InterruptedException {
191 + return responseFuture.get();
192 + }
193 + }
147 } 194 }
......
...@@ -3,14 +3,20 @@ package org.onlab.onos.store.flow.impl; ...@@ -3,14 +3,20 @@ package org.onlab.onos.store.flow.impl;
3 import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_REMOVED; 3 import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_REMOVED;
4 import static org.slf4j.LoggerFactory.getLogger; 4 import static org.slf4j.LoggerFactory.getLogger;
5 5
6 +import java.io.IOException;
6 import java.util.Collection; 7 import java.util.Collection;
7 import java.util.Collections; 8 import java.util.Collections;
9 +import java.util.concurrent.TimeUnit;
10 +import java.util.concurrent.TimeoutException;
8 11
9 import org.apache.felix.scr.annotations.Activate; 12 import org.apache.felix.scr.annotations.Activate;
10 import org.apache.felix.scr.annotations.Component; 13 import org.apache.felix.scr.annotations.Component;
11 import org.apache.felix.scr.annotations.Deactivate; 14 import org.apache.felix.scr.annotations.Deactivate;
15 +import org.apache.felix.scr.annotations.Reference;
16 +import org.apache.felix.scr.annotations.ReferenceCardinality;
12 import org.apache.felix.scr.annotations.Service; 17 import org.apache.felix.scr.annotations.Service;
13 import org.onlab.onos.ApplicationId; 18 import org.onlab.onos.ApplicationId;
19 +import org.onlab.onos.cluster.ClusterService;
14 import org.onlab.onos.net.DeviceId; 20 import org.onlab.onos.net.DeviceId;
15 import org.onlab.onos.net.flow.DefaultFlowEntry; 21 import org.onlab.onos.net.flow.DefaultFlowEntry;
16 import org.onlab.onos.net.flow.FlowEntry; 22 import org.onlab.onos.net.flow.FlowEntry;
...@@ -21,6 +27,13 @@ import org.onlab.onos.net.flow.FlowRuleEvent.Type; ...@@ -21,6 +27,13 @@ import org.onlab.onos.net.flow.FlowRuleEvent.Type;
21 import org.onlab.onos.net.flow.FlowRuleStore; 27 import org.onlab.onos.net.flow.FlowRuleStore;
22 import org.onlab.onos.net.flow.FlowRuleStoreDelegate; 28 import org.onlab.onos.net.flow.FlowRuleStoreDelegate;
23 import org.onlab.onos.store.AbstractStore; 29 import org.onlab.onos.store.AbstractStore;
30 +import org.onlab.onos.store.cluster.messaging.ClusterCommunicationService;
31 +import org.onlab.onos.store.cluster.messaging.ClusterMessage;
32 +import org.onlab.onos.store.cluster.messaging.ClusterMessageResponse;
33 +import org.onlab.onos.store.flow.ReplicaInfo;
34 +import org.onlab.onos.store.serializers.DistributedStoreSerializers;
35 +import org.onlab.onos.store.serializers.KryoSerializer;
36 +import org.onlab.util.KryoPool;
24 import org.slf4j.Logger; 37 import org.slf4j.Logger;
25 38
26 import com.google.common.collect.ArrayListMultimap; 39 import com.google.common.collect.ArrayListMultimap;
...@@ -28,9 +41,8 @@ import com.google.common.collect.ImmutableSet; ...@@ -28,9 +41,8 @@ import com.google.common.collect.ImmutableSet;
28 import com.google.common.collect.Multimap; 41 import com.google.common.collect.Multimap;
29 42
30 /** 43 /**
31 - * Manages inventory of flow rules using trivial in-memory implementation. 44 + * Manages inventory of flow rules using a distributed state management protocol.
32 */ 45 */
33 -//FIXME I LIE. I AIN'T DISTRIBUTED
34 @Component(immediate = true) 46 @Component(immediate = true)
35 @Service 47 @Service
36 public class DistributedFlowRuleStore 48 public class DistributedFlowRuleStore
...@@ -46,6 +58,28 @@ public class DistributedFlowRuleStore ...@@ -46,6 +58,28 @@ public class DistributedFlowRuleStore
46 private final Multimap<Short, FlowRule> flowEntriesById = 58 private final Multimap<Short, FlowRule> flowEntriesById =
47 ArrayListMultimap.<Short, FlowRule>create(); 59 ArrayListMultimap.<Short, FlowRule>create();
48 60
61 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
62 + private ReplicaInfoManager replicaInfoManager;
63 +
64 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
65 + private ClusterCommunicationService clusterCommunicator;
66 +
67 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
68 + private ClusterService clusterService;
69 +
70 + protected static final KryoSerializer SERIALIZER = new KryoSerializer() {
71 + @Override
72 + protected void setupKryoPool() {
73 + serializerPool = KryoPool.newBuilder()
74 + .register(DistributedStoreSerializers.COMMON)
75 + .build()
76 + .populate(1);
77 + }
78 + };
79 +
80 + // TODO: make this configurable
81 + private static final long FLOW_RULE_STORE_TIMEOUT_MILLIS = 1000;
82 +
49 @Activate 83 @Activate
50 public void activate() { 84 public void activate() {
51 log.info("Started"); 85 log.info("Started");
...@@ -91,26 +125,92 @@ public class DistributedFlowRuleStore ...@@ -91,26 +125,92 @@ public class DistributedFlowRuleStore
91 } 125 }
92 126
93 @Override 127 @Override
94 - public synchronized void storeFlowRule(FlowRule rule) { 128 + public void storeFlowRule(FlowRule rule) {
95 - FlowEntry f = new DefaultFlowEntry(rule); 129 + ReplicaInfo replicaInfo = replicaInfoManager.getReplicaInfoFor(rule.deviceId());
96 - DeviceId did = f.deviceId(); 130 + if (replicaInfo.master().get().equals(clusterService.getLocalNode().id())) {
97 - if (!flowEntries.containsEntry(did, f)) { 131 + storeFlowEntryInternal(rule);
98 - flowEntries.put(did, f); 132 + return;
99 - flowEntriesById.put(rule.appId(), f);
100 } 133 }
134 +
135 + ClusterMessage message = new ClusterMessage(
136 + clusterService.getLocalNode().id(),
137 + FlowStoreMessageSubjects.STORE_FLOW_RULE,
138 + SERIALIZER.encode(rule));
139 +
140 + try {
141 + ClusterMessageResponse response = clusterCommunicator.sendAndReceive(message, replicaInfo.master().get());
142 + response.get(FLOW_RULE_STORE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
143 + } catch (IOException | TimeoutException e) {
144 + // FIXME: throw a FlowStoreException
145 + throw new RuntimeException(e);
146 + }
147 + }
148 +
149 + private synchronized void storeFlowEntryInternal(FlowRule flowRule) {
150 + FlowEntry flowEntry = new DefaultFlowEntry(flowRule);
151 + DeviceId deviceId = flowRule.deviceId();
152 + // write to local copy.
153 + if (!flowEntries.containsEntry(deviceId, flowEntry)) {
154 + flowEntries.put(deviceId, flowEntry);
155 + flowEntriesById.put(flowRule.appId(), flowEntry);
156 + }
157 + // write to backup.
158 + // TODO: write to a hazelcast map.
101 } 159 }
102 160
103 @Override 161 @Override
104 public synchronized void deleteFlowRule(FlowRule rule) { 162 public synchronized void deleteFlowRule(FlowRule rule) {
105 - FlowEntry entry = getFlowEntry(rule); 163 + ReplicaInfo replicaInfo = replicaInfoManager.getReplicaInfoFor(rule.deviceId());
164 + if (replicaInfo.master().get().equals(clusterService.getLocalNode().id())) {
165 + deleteFlowRuleInternal(rule);
166 + return;
167 + }
168 +
169 + ClusterMessage message = new ClusterMessage(
170 + clusterService.getLocalNode().id(),
171 + FlowStoreMessageSubjects.DELETE_FLOW_RULE,
172 + SERIALIZER.encode(rule));
173 +
174 + try {
175 + ClusterMessageResponse response = clusterCommunicator.sendAndReceive(message, replicaInfo.master().get());
176 + response.get(FLOW_RULE_STORE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
177 + } catch (IOException | TimeoutException e) {
178 + // FIXME: throw a FlowStoreException
179 + throw new RuntimeException(e);
180 + }
181 + }
182 +
183 + private synchronized void deleteFlowRuleInternal(FlowRule flowRule) {
184 + FlowEntry entry = getFlowEntry(flowRule);
106 if (entry == null) { 185 if (entry == null) {
107 return; 186 return;
108 } 187 }
109 entry.setState(FlowEntryState.PENDING_REMOVE); 188 entry.setState(FlowEntryState.PENDING_REMOVE);
189 + // TODO: also update backup.
110 } 190 }
111 191
112 @Override 192 @Override
113 - public synchronized FlowRuleEvent addOrUpdateFlowRule(FlowEntry rule) { 193 + public FlowRuleEvent addOrUpdateFlowRule(FlowEntry rule) {
194 + ReplicaInfo replicaInfo = replicaInfoManager.getReplicaInfoFor(rule.deviceId());
195 + if (replicaInfo.master().get().equals(clusterService.getLocalNode().id())) {
196 + return addOrUpdateFlowRuleInternal(rule);
197 + }
198 +
199 + ClusterMessage message = new ClusterMessage(
200 + clusterService.getLocalNode().id(),
201 + FlowStoreMessageSubjects.ADD_OR_UPDATE_FLOW_RULE,
202 + SERIALIZER.encode(rule));
203 +
204 + try {
205 + ClusterMessageResponse response = clusterCommunicator.sendAndReceive(message, replicaInfo.master().get());
206 + return SERIALIZER.decode(response.get(FLOW_RULE_STORE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS));
207 + } catch (IOException | TimeoutException e) {
208 + // FIXME: throw a FlowStoreException
209 + throw new RuntimeException(e);
210 + }
211 + }
212 +
213 + private synchronized FlowRuleEvent addOrUpdateFlowRuleInternal(FlowEntry rule) {
114 DeviceId did = rule.deviceId(); 214 DeviceId did = rule.deviceId();
115 215
116 // check if this new rule is an update to an existing entry 216 // check if this new rule is an update to an existing entry
...@@ -128,15 +228,39 @@ public class DistributedFlowRuleStore ...@@ -128,15 +228,39 @@ public class DistributedFlowRuleStore
128 228
129 flowEntries.put(did, rule); 229 flowEntries.put(did, rule);
130 return null; 230 return null;
231 +
232 + // TODO: also update backup.
131 } 233 }
132 234
133 @Override 235 @Override
134 - public synchronized FlowRuleEvent removeFlowRule(FlowEntry rule) { 236 + public FlowRuleEvent removeFlowRule(FlowEntry rule) {
237 + ReplicaInfo replicaInfo = replicaInfoManager.getReplicaInfoFor(rule.deviceId());
238 + if (replicaInfo.master().get().equals(clusterService.getLocalNode().id())) {
239 + // bypass and handle it locally
240 + return removeFlowRuleInternal(rule);
241 + }
242 +
243 + ClusterMessage message = new ClusterMessage(
244 + clusterService.getLocalNode().id(),
245 + FlowStoreMessageSubjects.REMOVE_FLOW_RULE,
246 + SERIALIZER.encode(rule));
247 +
248 + try {
249 + ClusterMessageResponse response = clusterCommunicator.sendAndReceive(message, replicaInfo.master().get());
250 + return SERIALIZER.decode(response.get(FLOW_RULE_STORE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS));
251 + } catch (IOException | TimeoutException e) {
252 + // FIXME: throw a FlowStoreException
253 + throw new RuntimeException(e);
254 + }
255 + }
256 +
257 + private synchronized FlowRuleEvent removeFlowRuleInternal(FlowEntry rule) {
135 // This is where one could mark a rule as removed and still keep it in the store. 258 // This is where one could mark a rule as removed and still keep it in the store.
136 if (flowEntries.remove(rule.deviceId(), rule)) { 259 if (flowEntries.remove(rule.deviceId(), rule)) {
137 return new FlowRuleEvent(RULE_REMOVED, rule); 260 return new FlowRuleEvent(RULE_REMOVED, rule);
138 } else { 261 } else {
139 return null; 262 return null;
140 } 263 }
264 + // TODO: also update backup.
141 } 265 }
142 } 266 }
......
1 +package org.onlab.onos.store.flow.impl;
2 +
3 +import org.onlab.onos.store.cluster.messaging.MessageSubject;
4 +
5 +/**
6 + * MessageSubjects used by DistributedFlowRuleStore peer-peer communication.
7 + */
8 +public final class FlowStoreMessageSubjects {
9 + private FlowStoreMessageSubjects() {}
10 + public static final MessageSubject STORE_FLOW_RULE = new MessageSubject("peer-forward-store-flow-rule");
11 + public static final MessageSubject DELETE_FLOW_RULE = new MessageSubject("peer-forward-delete-flow-rule");
12 + public static final MessageSubject ADD_OR_UPDATE_FLOW_RULE =
13 + new MessageSubject("peer-forward-add-or-update-flow-rule");
14 + public static final MessageSubject REMOVE_FLOW_RULE = new MessageSubject("peer-forward-remove-flow-rule");
15 +}
...@@ -26,6 +26,7 @@ import org.onlab.onos.net.Port; ...@@ -26,6 +26,7 @@ import org.onlab.onos.net.Port;
26 import org.onlab.onos.net.PortNumber; 26 import org.onlab.onos.net.PortNumber;
27 import org.onlab.onos.net.device.DefaultDeviceDescription; 27 import org.onlab.onos.net.device.DefaultDeviceDescription;
28 import org.onlab.onos.net.device.DefaultPortDescription; 28 import org.onlab.onos.net.device.DefaultPortDescription;
29 +import org.onlab.onos.net.flow.DefaultFlowRule;
29 import org.onlab.onos.net.host.DefaultHostDescription; 30 import org.onlab.onos.net.host.DefaultHostDescription;
30 import org.onlab.onos.net.host.HostDescription; 31 import org.onlab.onos.net.host.HostDescription;
31 import org.onlab.onos.net.link.DefaultLinkDescription; 32 import org.onlab.onos.net.link.DefaultLinkDescription;
...@@ -86,7 +87,8 @@ public final class KryoPoolUtil { ...@@ -86,7 +87,8 @@ public final class KryoPoolUtil {
86 Timestamp.class, 87 Timestamp.class,
87 HostId.class, 88 HostId.class,
88 HostDescription.class, 89 HostDescription.class,
89 - DefaultHostDescription.class 90 + DefaultHostDescription.class,
91 + DefaultFlowRule.class
90 ) 92 )
91 .register(URI.class, new URISerializer()) 93 .register(URI.class, new URISerializer())
92 .register(NodeId.class, new NodeIdSerializer()) 94 .register(NodeId.class, new NodeIdSerializer())
......
...@@ -155,6 +155,13 @@ ...@@ -155,6 +155,13 @@
155 <feature>onos-api</feature> 155 <feature>onos-api</feature>
156 <bundle>mvn:org.onlab.onos/onos-app-config/1.0.0-SNAPSHOT</bundle> 156 <bundle>mvn:org.onlab.onos/onos-app-config/1.0.0-SNAPSHOT</bundle>
157 </feature> 157 </feature>
158 +
159 + <feature name="onos-app-optical" version="1.0.0"
160 + description="ONOS optical network config">
161 + <feature>onos-api</feature>
162 + <bundle>mvn:org.onlab.onos/onos-app-optical/1.0.0-SNAPSHOT</bundle>
163 + </feature>
164 +
158 165
159 <feature name="onos-app-sdnip" version="1.0.0" 166 <feature name="onos-app-sdnip" version="1.0.0"
160 description="SDN-IP peering application"> 167 description="SDN-IP peering application">
......
...@@ -223,7 +223,7 @@ public class FlowEntryBuilder { ...@@ -223,7 +223,7 @@ public class FlowEntryBuilder {
223 if (di.isCidrMask()) { 223 if (di.isCidrMask()) {
224 dip = IpPrefix.valueOf(di.getInt(), di.asCidrMaskLength()); 224 dip = IpPrefix.valueOf(di.getInt(), di.asCidrMaskLength());
225 } else { 225 } else {
226 - dip = IpPrefix.valueOf(di.getInt()); 226 + dip = IpPrefix.valueOf(di.getInt(), IpPrefix.MAX_INET_MASK);
227 } 227 }
228 builder.matchIPDst(dip); 228 builder.matchIPDst(dip);
229 break; 229 break;
...@@ -233,7 +233,7 @@ public class FlowEntryBuilder { ...@@ -233,7 +233,7 @@ public class FlowEntryBuilder {
233 if (si.isCidrMask()) { 233 if (si.isCidrMask()) {
234 sip = IpPrefix.valueOf(si.getInt(), si.asCidrMaskLength()); 234 sip = IpPrefix.valueOf(si.getInt(), si.asCidrMaskLength());
235 } else { 235 } else {
236 - sip = IpPrefix.valueOf(si.getInt()); 236 + sip = IpPrefix.valueOf(si.getInt(), IpPrefix.MAX_INET_MASK);
237 } 237 }
238 builder.matchIPSrc(sip); 238 builder.matchIPSrc(sip);
239 break; 239 break;
...@@ -249,6 +249,12 @@ public class FlowEntryBuilder { ...@@ -249,6 +249,12 @@ public class FlowEntryBuilder {
249 VlanId vlanId = VlanId.vlanId(match.get(MatchField.VLAN_VID).getVlan()); 249 VlanId vlanId = VlanId.vlanId(match.get(MatchField.VLAN_VID).getVlan());
250 builder.matchVlanId(vlanId); 250 builder.matchVlanId(vlanId);
251 break; 251 break;
252 + case TCP_DST:
253 + builder.matchTcpDst((short) match.get(MatchField.TCP_DST).getPort());
254 + break;
255 + case TCP_SRC:
256 + builder.matchTcpSrc((short) match.get(MatchField.TCP_SRC).getPort());
257 + break;
252 case ARP_OP: 258 case ARP_OP:
253 case ARP_SHA: 259 case ARP_SHA:
254 case ARP_SPA: 260 case ARP_SPA:
...@@ -272,8 +278,6 @@ public class FlowEntryBuilder { ...@@ -272,8 +278,6 @@ public class FlowEntryBuilder {
272 case MPLS_TC: 278 case MPLS_TC:
273 case SCTP_DST: 279 case SCTP_DST:
274 case SCTP_SRC: 280 case SCTP_SRC:
275 - case TCP_DST:
276 - case TCP_SRC:
277 case TUNNEL_ID: 281 case TUNNEL_ID:
278 case UDP_DST: 282 case UDP_DST:
279 case UDP_SRC: 283 case UDP_SRC:
......
...@@ -15,6 +15,7 @@ import org.onlab.onos.net.flow.criteria.Criteria.EthTypeCriterion; ...@@ -15,6 +15,7 @@ import org.onlab.onos.net.flow.criteria.Criteria.EthTypeCriterion;
15 import org.onlab.onos.net.flow.criteria.Criteria.IPCriterion; 15 import org.onlab.onos.net.flow.criteria.Criteria.IPCriterion;
16 import org.onlab.onos.net.flow.criteria.Criteria.IPProtocolCriterion; 16 import org.onlab.onos.net.flow.criteria.Criteria.IPProtocolCriterion;
17 import org.onlab.onos.net.flow.criteria.Criteria.PortCriterion; 17 import org.onlab.onos.net.flow.criteria.Criteria.PortCriterion;
18 +import org.onlab.onos.net.flow.criteria.Criteria.TcpPortCriterion;
18 import org.onlab.onos.net.flow.criteria.Criteria.VlanIdCriterion; 19 import org.onlab.onos.net.flow.criteria.Criteria.VlanIdCriterion;
19 import org.onlab.onos.net.flow.criteria.Criteria.VlanPcpCriterion; 20 import org.onlab.onos.net.flow.criteria.Criteria.VlanPcpCriterion;
20 import org.onlab.onos.net.flow.criteria.Criterion; 21 import org.onlab.onos.net.flow.criteria.Criterion;
...@@ -42,6 +43,7 @@ import org.projectfloodlight.openflow.types.Masked; ...@@ -42,6 +43,7 @@ import org.projectfloodlight.openflow.types.Masked;
42 import org.projectfloodlight.openflow.types.OFBufferId; 43 import org.projectfloodlight.openflow.types.OFBufferId;
43 import org.projectfloodlight.openflow.types.OFPort; 44 import org.projectfloodlight.openflow.types.OFPort;
44 import org.projectfloodlight.openflow.types.OFVlanVidMatch; 45 import org.projectfloodlight.openflow.types.OFVlanVidMatch;
46 +import org.projectfloodlight.openflow.types.TransportPort;
45 import org.projectfloodlight.openflow.types.U64; 47 import org.projectfloodlight.openflow.types.U64;
46 import org.projectfloodlight.openflow.types.VlanPcp; 48 import org.projectfloodlight.openflow.types.VlanPcp;
47 import org.projectfloodlight.openflow.types.VlanVid; 49 import org.projectfloodlight.openflow.types.VlanVid;
...@@ -199,6 +201,7 @@ public class FlowModBuilder { ...@@ -199,6 +201,7 @@ public class FlowModBuilder {
199 Match.Builder mBuilder = factory.buildMatch(); 201 Match.Builder mBuilder = factory.buildMatch();
200 EthCriterion eth; 202 EthCriterion eth;
201 IPCriterion ip; 203 IPCriterion ip;
204 + TcpPortCriterion tp;
202 for (Criterion c : selector.criteria()) { 205 for (Criterion c : selector.criteria()) {
203 switch (c.type()) { 206 switch (c.type()) {
204 case IN_PORT: 207 case IN_PORT:
...@@ -250,6 +253,14 @@ public class FlowModBuilder { ...@@ -250,6 +253,14 @@ public class FlowModBuilder {
250 mBuilder.setExact(MatchField.VLAN_VID, 253 mBuilder.setExact(MatchField.VLAN_VID,
251 OFVlanVidMatch.ofVlanVid(VlanVid.ofVlan(vid.vlanId().toShort()))); 254 OFVlanVidMatch.ofVlanVid(VlanVid.ofVlan(vid.vlanId().toShort())));
252 break; 255 break;
256 + case TCP_DST:
257 + tp = (TcpPortCriterion) c;
258 + mBuilder.setExact(MatchField.TCP_DST, TransportPort.of(tp.tcpPort()));
259 + break;
260 + case TCP_SRC:
261 + tp = (TcpPortCriterion) c;
262 + mBuilder.setExact(MatchField.TCP_SRC, TransportPort.of(tp.tcpPort()));
263 + break;
253 case ARP_OP: 264 case ARP_OP:
254 case ARP_SHA: 265 case ARP_SHA:
255 case ARP_SPA: 266 case ARP_SPA:
...@@ -276,8 +287,6 @@ public class FlowModBuilder { ...@@ -276,8 +287,6 @@ public class FlowModBuilder {
276 case PBB_ISID: 287 case PBB_ISID:
277 case SCTP_DST: 288 case SCTP_DST:
278 case SCTP_SRC: 289 case SCTP_SRC:
279 - case TCP_DST:
280 - case TCP_SRC:
281 case TUNNEL_ID: 290 case TUNNEL_ID:
282 case UDP_DST: 291 case UDP_DST:
283 case UDP_SRC: 292 case UDP_SRC:
......
1 package org.onlab.onos.provider.of.host.impl; 1 package org.onlab.onos.provider.of.host.impl;
2 2
3 +import static org.onlab.onos.net.DeviceId.deviceId;
4 +import static org.onlab.onos.net.PortNumber.portNumber;
5 +import static org.slf4j.LoggerFactory.getLogger;
6 +
3 import org.apache.felix.scr.annotations.Activate; 7 import org.apache.felix.scr.annotations.Activate;
4 import org.apache.felix.scr.annotations.Component; 8 import org.apache.felix.scr.annotations.Component;
5 import org.apache.felix.scr.annotations.Deactivate; 9 import org.apache.felix.scr.annotations.Deactivate;
...@@ -29,10 +33,6 @@ import org.onlab.packet.IpPrefix; ...@@ -29,10 +33,6 @@ import org.onlab.packet.IpPrefix;
29 import org.onlab.packet.VlanId; 33 import org.onlab.packet.VlanId;
30 import org.slf4j.Logger; 34 import org.slf4j.Logger;
31 35
32 -import static org.onlab.onos.net.DeviceId.deviceId;
33 -import static org.onlab.onos.net.PortNumber.portNumber;
34 -import static org.slf4j.LoggerFactory.getLogger;
35 -
36 /** 36 /**
37 * Provider which uses an OpenFlow controller to detect network 37 * Provider which uses an OpenFlow controller to detect network
38 * end-station hosts. 38 * end-station hosts.
...@@ -110,14 +110,16 @@ public class OpenFlowHostProvider extends AbstractProvider implements HostProvid ...@@ -110,14 +110,16 @@ public class OpenFlowHostProvider extends AbstractProvider implements HostProvid
110 // Potentially a new or moved host 110 // Potentially a new or moved host
111 if (eth.getEtherType() == Ethernet.TYPE_ARP) { 111 if (eth.getEtherType() == Ethernet.TYPE_ARP) {
112 ARP arp = (ARP) eth.getPayload(); 112 ARP arp = (ARP) eth.getPayload();
113 - IpPrefix ip = IpPrefix.valueOf(arp.getSenderProtocolAddress()); 113 + IpPrefix ip = IpPrefix.valueOf(arp.getSenderProtocolAddress(),
114 + IpPrefix.MAX_INET_MASK);
114 HostDescription hdescr = 115 HostDescription hdescr =
115 new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc, ip); 116 new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc, ip);
116 providerService.hostDetected(hid, hdescr); 117 providerService.hostDetected(hid, hdescr);
117 118
118 } else if (ipLearn && eth.getEtherType() == Ethernet.TYPE_IPV4) { 119 } else if (ipLearn && eth.getEtherType() == Ethernet.TYPE_IPV4) {
119 IPv4 pip = (IPv4) eth.getPayload(); 120 IPv4 pip = (IPv4) eth.getPayload();
120 - IpPrefix ip = IpPrefix.valueOf(pip.getSourceAddress()); 121 + IpPrefix ip = IpPrefix.valueOf(pip.getSourceAddress(),
122 + IpPrefix.MAX_INET_MASK);
121 HostDescription hdescr = 123 HostDescription hdescr =
122 new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc, ip); 124 new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc, ip);
123 providerService.hostDetected(hid, hdescr); 125 providerService.hostDetected(hid, hdescr);
......
1 +# Local VirtualBox-based single ONOS instance & ONOS mininet box
2 +
3 +export ONOS_NIC=192.168.56.*
4 +export OC1="192.168.56.101"
5 +export OCN="192.168.56.103"
6 +
7 +export ONOS_FEATURES=webconsole,onos-api,onos-core-trivial,onos-cli,onos-openflow,onos-app-fwd,onos-app-mobility,onos-app-tvue,onos-app-optical
1 +package org.onlab.util;
2 +
3 +public final class HexString {
4 +
5 + private HexString() {
6 +
7 + }
8 +
9 + /**
10 + * Convert a string of bytes to a ':' separated hex string.
11 + *
12 + * @param bytes
13 + * @return "0f:ca:fe:de:ad:be:ef"
14 + */
15 + public static String toHexString(final byte[] bytes) {
16 + int i;
17 + StringBuilder ret = new StringBuilder();
18 + String tmp;
19 + for (i = 0; i < bytes.length; i++) {
20 + if (i > 0) {
21 + ret.append(':');
22 + }
23 + tmp = Integer.toHexString((bytes[i] & 0xff));
24 + if (tmp.length() == 1) {
25 + ret.append('0');
26 + }
27 + ret.append(tmp);
28 + }
29 + return ret.toString();
30 + }
31 +
32 + public static String toHexString(final long val, final int padTo) {
33 + char[] arr = Long.toHexString(val).toCharArray();
34 + String ret = "";
35 + // prepend the right number of leading zeros
36 + int i = 0;
37 + for (; i < (padTo * 2 - arr.length); i++) {
38 + ret += "0";
39 + if ((i % 2) != 0) {
40 + ret += ":";
41 + }
42 + }
43 + for (int j = 0; j < arr.length; j++) {
44 + ret += arr[j];
45 + if ((((i + j) % 2) != 0) && (j < (arr.length - 1))) {
46 + ret += ":";
47 + }
48 + }
49 + return ret;
50 + }
51 +
52 + public static String toHexString(final long val) {
53 + return toHexString(val, 8);
54 + }
55 +
56 + /**
57 + * Convert a string of hex values into a string of bytes.
58 + *
59 + * @param values
60 + * "0f:ca:fe:de:ad:be:ef"
61 + * @return [15, 5 ,2, 5, 17]
62 + * @throws NumberFormatException
63 + * If the string can not be parsed
64 + */
65 + public static byte[] fromHexString(final String values) {
66 + String[] octets = values.split(":");
67 + byte[] ret = new byte[octets.length];
68 +
69 + for (int i = 0; i < octets.length; i++) {
70 + if (octets[i].length() > 2) {
71 + throw new NumberFormatException("Invalid octet length");
72 + }
73 + ret[i] = Integer.valueOf(octets[i], 16).byteValue();
74 + }
75 + return ret;
76 + }
77 +
78 + public static long toLong(String value) {
79 + String[] octets = value.split(":");
80 + if (octets.length > 8) {
81 + throw new NumberFormatException("Input string is too big to fit in long: " + value);
82 + }
83 + long l = 0;
84 + for (String octet: octets) {
85 + if (octet.length() > 2) {
86 + throw new NumberFormatException(
87 + "Each colon-separated byte component must consist of 1 or 2 hex digits: " + value);
88 + }
89 + short s = Short.parseShort(octet, 16);
90 + l = (l << 8) + s;
91 + }
92 + return l;
93 + }
94 +}
1 +package org.onlab.util;
2 +
3 +import org.junit.Test;
4 +
5 +import com.esotericsoftware.minlog.Log;
6 +
7 +import junit.framework.TestCase;
8 +
9 +/**
10 + * Test of the Hexstring.
11 + *
12 + */
13 +
14 +public class HexStringTest extends TestCase {
15 +
16 + @Test
17 + public void testMarshalling() throws Exception {
18 + String dpidStr = "00:00:00:23:20:2d:16:71";
19 + long dpid = HexString.toLong(dpidStr);
20 + String testStr = HexString.toHexString(dpid);
21 + TestCase.assertEquals(dpidStr, testStr);
22 + }
23 +
24 + @Test
25 + public void testToLong() {
26 + String dpidStr = "3e:1f:01:fc:72:8c:63:31";
27 + long valid = 0x3e1f01fc728c6331L;
28 + long testLong = HexString.toLong(dpidStr);
29 + TestCase.assertEquals(valid, testLong);
30 + }
31 +
32 + @Test
33 + public void testToLongMSB() {
34 + String dpidStr = "ca:7c:5e:d1:64:7a:95:9b";
35 + long valid = -3856102927509056101L;
36 + long testLong = HexString.toLong(dpidStr);
37 + TestCase.assertEquals(valid, testLong);
38 + }
39 +
40 + @Test
41 + public void testToLongError() {
42 + String dpidStr = "09:08:07:06:05:04:03:02:01";
43 + try {
44 + HexString.toLong(dpidStr);
45 + fail("HexString.toLong() should have thrown a NumberFormatException");
46 + } catch (NumberFormatException expected) {
47 + Log.info("HexString.toLong() have thrown a NumberFormatException");
48 + }
49 + }
50 +
51 + @Test
52 + public void testToStringBytes() {
53 + byte[] dpid = {0, 0, 0, 0, 0, 0, 0, -1 };
54 + String valid = "00:00:00:00:00:00:00:ff";
55 + String testString = HexString.toHexString(dpid);
56 + TestCase.assertEquals(valid, testString);
57 + }
58 +
59 + @Test
60 + public void testFromHexStringError() {
61 + String invalidStr = "00:00:00:00:00:00:ffff";
62 + try {
63 + HexString.fromHexString(invalidStr);
64 + fail("HexString.fromHexString() should have thrown a NumberFormatException");
65 + } catch (NumberFormatException expected) {
66 + Log.info("HexString.toLong() have thrown a NumberFormatException");
67 + }
68 + }
69 +}
70 +