Jonathan Hart

Ported PeerConnectivity onto ONOS next, and implemented a service that can

construct Interface objects based on PortAddresses from HostService.
...@@ -31,6 +31,11 @@ ...@@ -31,6 +31,11 @@
31 <version>2.4.2</version> 31 <version>2.4.2</version>
32 <scope>provided</scope> 32 <scope>provided</scope>
33 </dependency> 33 </dependency>
34 +
35 + <dependency>
36 + <groupId>com.google.guava</groupId>
37 + <artifactId>guava</artifactId>
38 + </dependency>
34 </dependencies> 39 </dependencies>
35 40
36 </project> 41 </project>
......
1 +package org.onlab.onos.sdnip;
2 +
3 +import static com.google.common.base.Preconditions.checkNotNull;
4 +
5 +import java.util.Set;
6 +
7 +import org.apache.commons.lang.NotImplementedException;
8 +import org.onlab.onos.net.ConnectPoint;
9 +import org.onlab.onos.net.host.HostService;
10 +import org.onlab.onos.net.host.PortAddresses;
11 +import org.onlab.onos.sdnip.config.Interface;
12 +import org.onlab.packet.IpAddress;
13 +
14 +import com.google.common.collect.Sets;
15 +
16 +
17 +
18 +/**
19 + * Provides IntefaceService using PortAddresses data from the HostService.
20 + */
21 +public class HostServiceBasedInterfaceService implements InterfaceService {
22 +
23 + private final HostService hostService;
24 +
25 + public HostServiceBasedInterfaceService(HostService hostService) {
26 + this.hostService = checkNotNull(hostService);
27 + }
28 +
29 + @Override
30 + public Set<Interface> getInterfaces() {
31 + Set<PortAddresses> addresses = hostService.getAddressBindings();
32 + Set<Interface> interfaces = Sets.newHashSetWithExpectedSize(addresses.size());
33 + for (PortAddresses a : addresses) {
34 + interfaces.add(new Interface(a));
35 + }
36 + return interfaces;
37 + }
38 +
39 + @Override
40 + public Interface getInterface(ConnectPoint connectPoint) {
41 + checkNotNull(connectPoint);
42 +
43 + PortAddresses portAddresses =
44 + hostService.getAddressBindingsForPort(connectPoint);
45 +
46 + if (!portAddresses.ips().isEmpty()) {
47 + return new Interface(portAddresses);
48 + }
49 +
50 + return null;
51 + }
52 +
53 + @Override
54 + public Interface getMatchingInterface(IpAddress ipAddress) {
55 + // TODO implement
56 + throw new NotImplementedException("getMatchingInteface is not yet implemented");
57 + }
58 +
59 +}
1 +package org.onlab.onos.sdnip;
2 +
3 +import java.util.Set;
4 +
5 +import org.onlab.onos.net.ConnectPoint;
6 +import org.onlab.onos.sdnip.config.Interface;
7 +import org.onlab.packet.IpAddress;
8 +
9 +/**
10 + * Provides information about the interfaces in the network.
11 + */
12 +public interface InterfaceService {
13 + /**
14 + * Retrieves the entire set of interfaces in the network.
15 + *
16 + * @return the set of interfaces
17 + */
18 + Set<Interface> getInterfaces();
19 +
20 + /**
21 + * Retrieves the interface associated with the given connect point.
22 + *
23 + * @param connectPoint the connect point to retrieve interface information
24 + * for
25 + * @return the interface
26 + */
27 + Interface getInterface(ConnectPoint connectPoint);
28 +
29 + /**
30 + * Retrieves the interface that matches the given IP address. Matching
31 + * means that the IP address is in one of the interface's assigned subnets.
32 + *
33 + * @param ipAddress IP address to match
34 + * @return the matching interface
35 + */
36 + Interface getMatchingInterface(IpAddress ipAddress);
37 +}
1 +package org.onlab.onos.sdnip;
2 +
3 +import java.util.List;
4 +
5 +import org.onlab.onos.net.ConnectPoint;
6 +import org.onlab.onos.net.flow.DefaultTrafficSelector;
7 +import org.onlab.onos.net.flow.DefaultTrafficTreatment;
8 +import org.onlab.onos.net.flow.TrafficSelector;
9 +import org.onlab.onos.net.flow.TrafficTreatment;
10 +import org.onlab.onos.net.intent.IntentId;
11 +import org.onlab.onos.net.intent.IntentService;
12 +import org.onlab.onos.net.intent.PointToPointIntent;
13 +import org.onlab.onos.sdnip.config.BgpPeer;
14 +import org.onlab.onos.sdnip.config.BgpSpeaker;
15 +import org.onlab.onos.sdnip.config.Interface;
16 +import org.onlab.onos.sdnip.config.InterfaceAddress;
17 +import org.onlab.onos.sdnip.config.SdnIpConfigService;
18 +import org.onlab.packet.Ethernet;
19 +import org.onlab.packet.IPv4;
20 +import org.onlab.packet.IpAddress;
21 +import org.onlab.packet.IpPrefix;
22 +import org.slf4j.Logger;
23 +import org.slf4j.LoggerFactory;
24 +
25 +/**
26 + * Manages the connectivity requirements between peers.
27 + */
28 +public class PeerConnectivity {
29 +
30 + private static final Logger log = LoggerFactory.getLogger(
31 + PeerConnectivity.class);
32 +
33 + // TODO these shouldn't be defined here
34 + private static final short BGP_PORT = 179;
35 + private static final int IPV4_BIT_LENGTH = 32;
36 +
37 + private final SdnIpConfigService configInfoService;
38 + private final InterfaceService interfaceService;
39 + private final IntentService intentService;
40 +
41 + // TODO this sucks.
42 + private int intentId = 0;
43 +
44 + public PeerConnectivity(SdnIpConfigService configInfoService,
45 + InterfaceService interfaceService, IntentService intentService) {
46 + this.configInfoService = configInfoService;
47 + this.interfaceService = interfaceService;
48 + this.intentService = intentService;
49 + }
50 +
51 + public void start() {
52 + // TODO are any of these errors?
53 + if (interfaceService.getInterfaces().isEmpty()) {
54 +
55 + log.warn("The interface in configuration file is empty. "
56 + + "Thus, the SDN-IP application can not be started.");
57 + } else if (configInfoService.getBgpPeers().isEmpty()) {
58 +
59 + log.warn("The BGP peer in configuration file is empty."
60 + + "Thus, the SDN-IP application can not be started.");
61 + } else if (configInfoService.getBgpSpeakers() == null) {
62 +
63 + log.error("The BGP speaker in configuration file is empty. "
64 + + "Thus, the SDN-IP application can not be started.");
65 + return;
66 + }
67 +
68 + setupBgpPaths();
69 + setupIcmpPaths();
70 + }
71 +
72 + /**
73 + * Sets up paths for all {@link BgpSpeaker}s and all external peers.
74 + * <p/>
75 + * Run a loop for all BGP speakers and a loop for all BGP peers outside.
76 + * Push intents for paths from each BGP speaker to all peers. Push intents
77 + * for paths from all peers to each BGP speaker.
78 + */
79 + private void setupBgpPaths() {
80 + for (BgpSpeaker bgpSpeaker : configInfoService.getBgpSpeakers()
81 + .values()) {
82 + log.debug("Start to set up BGP paths for BGP speaker: {}",
83 + bgpSpeaker);
84 + ConnectPoint bgpdConnectPoint = bgpSpeaker.connectPoint();
85 +
86 + List<InterfaceAddress> interfaceAddresses =
87 + bgpSpeaker.interfaceAddresses();
88 +
89 + for (BgpPeer bgpPeer : configInfoService.getBgpPeers().values()) {
90 +
91 + log.debug("Start to set up BGP paths between BGP speaker: {} "
92 + + "to BGP peer: {}", bgpSpeaker, bgpPeer);
93 +
94 + Interface peerInterface = interfaceService.getInterface(
95 + bgpPeer.connectPoint());
96 + if (peerInterface == null) {
97 + log.error("Can not find the corresponding Interface from "
98 + + "configuration for BGP peer {}",
99 + bgpPeer.ipAddress());
100 + continue;
101 + }
102 +
103 + IpAddress bgpdAddress = null;
104 + for (InterfaceAddress interfaceAddress : interfaceAddresses) {
105 + if (interfaceAddress.connectPoint().equals(
106 + peerInterface.connectPoint())) {
107 + bgpdAddress = interfaceAddress.ipAddress();
108 + break;
109 + }
110 + }
111 + if (bgpdAddress == null) {
112 + log.debug("There is no interface IP address for bgpPeer: {}"
113 + + " on interface {}", bgpPeer, bgpPeer.connectPoint());
114 + return;
115 + }
116 +
117 + IpAddress bgpdPeerAddress = bgpPeer.ipAddress();
118 + ConnectPoint bgpdPeerConnectPoint = peerInterface.connectPoint();
119 +
120 + // install intent for BGP path from BGPd to BGP peer matching
121 + // destination TCP port 179
122 +
123 + // TODO: The usage of PacketMatchBuilder will be improved, then we
124 + // only need to new the PacketMatchBuilder once.
125 + // By then, the code here will be improved accordingly.
126 + /*PacketMatch packetMatch = new PacketMatchBuilder().setEtherType(
127 + Ethernet.TYPE_IPV4)
128 + .setIpProto(PROTOCOL_TCP)
129 + .setSrcIpNet(new Ip4Prefix(bgpdAddress,
130 + (short) Ip4Address.BIT_LENGTH))
131 + .setDstIpNet(new Ip4Prefix(bgpdPeerAddress,
132 + (short) Ip4Address.BIT_LENGTH))
133 + .setDstTcpPort(BGP_PORT)
134 + .build();
135 + */
136 +
137 + TrafficSelector selector = DefaultTrafficSelector.builder()
138 + .matchEthType(Ethernet.TYPE_IPV4)
139 + .matchIPProtocol(IPv4.PROTOCOL_TCP)
140 + .matchIPSrc(IpPrefix.valueOf(bgpdAddress.toRealInt(), IPV4_BIT_LENGTH))
141 + .matchIPDst(IpPrefix.valueOf(bgpdPeerAddress.toRealInt(), IPV4_BIT_LENGTH))
142 + .matchTcpDst(BGP_PORT)
143 + .build();
144 +
145 + TrafficTreatment treatment = DefaultTrafficTreatment.builder()
146 + .build();
147 +
148 + PointToPointIntent intentMatchDstTcpPort = new PointToPointIntent(
149 + nextIntentId(), selector, treatment,
150 + bgpdConnectPoint, bgpdPeerConnectPoint);
151 + intentService.submit(intentMatchDstTcpPort);
152 + log.debug("Submitted BGP path intent matching dst TCP port 179 "
153 + + "from BGPd {} to peer {}: {}",
154 + bgpdAddress, bgpdPeerAddress, intentMatchDstTcpPort);
155 +
156 + // install intent for BGP path from BGPd to BGP peer matching
157 + // source TCP port 179
158 + /*packetMatch = new PacketMatchBuilder().setEtherType(Ethernet.TYPE_IPV4)
159 + .setIpProto(PROTOCOL_TCP)
160 + .setSrcIpNet(new Ip4Prefix(bgpdAddress,
161 + (short) Ip4Address.BIT_LENGTH))
162 + .setDstIpNet(new Ip4Prefix(bgpdPeerAddress,
163 + (short) Ip4Address.BIT_LENGTH))
164 + .setSrcTcpPort(BGP_PORT)
165 + .build();*/
166 + selector = DefaultTrafficSelector.builder()
167 + .matchEthType(Ethernet.TYPE_IPV4)
168 + .matchIPProtocol(IPv4.PROTOCOL_TCP)
169 + .matchIPSrc(IpPrefix.valueOf(bgpdAddress.toRealInt(), IPV4_BIT_LENGTH))
170 + .matchIPDst(IpPrefix.valueOf(bgpdPeerAddress.toRealInt(), IPV4_BIT_LENGTH))
171 + .matchTcpSrc(BGP_PORT)
172 + .build();
173 +
174 + PointToPointIntent intentMatchSrcTcpPort = new PointToPointIntent(
175 + nextIntentId(), selector, treatment,
176 + bgpdConnectPoint, bgpdPeerConnectPoint);
177 + intentService.submit(intentMatchSrcTcpPort);
178 + log.debug("Submitted BGP path intent matching src TCP port 179"
179 + + "from BGPd {} to peer {}: {}",
180 + bgpdAddress, bgpdPeerAddress, intentMatchSrcTcpPort);
181 +
182 + // install intent for reversed BGP path from BGP peer to BGPd
183 + // matching destination TCP port 179
184 + /*packetMatch = new PacketMatchBuilder().setEtherType(Ethernet.TYPE_IPV4)
185 + .setIpProto(PROTOCOL_TCP)
186 + .setSrcIpNet(new Ip4Prefix(bgpdPeerAddress,
187 + (short) Ip4Address.BIT_LENGTH))
188 + .setDstIpNet(new Ip4Prefix(bgpdAddress,
189 + (short) Ip4Address.BIT_LENGTH))
190 + .setDstTcpPort(BGP_PORT)
191 + .build();*/
192 + selector = DefaultTrafficSelector.builder()
193 + .matchEthType(Ethernet.TYPE_IPV4)
194 + .matchIPProtocol(IPv4.PROTOCOL_TCP)
195 + .matchIPSrc(IpPrefix.valueOf(bgpdPeerAddress.toRealInt(), IPV4_BIT_LENGTH))
196 + .matchIPDst(IpPrefix.valueOf(bgpdAddress.toRealInt(), IPV4_BIT_LENGTH))
197 + .matchTcpDst(BGP_PORT)
198 + .build();
199 +
200 + PointToPointIntent reversedIntentMatchDstTcpPort = new PointToPointIntent(
201 + nextIntentId(), selector, treatment,
202 + bgpdPeerConnectPoint, bgpdConnectPoint);
203 + intentService.submit(reversedIntentMatchDstTcpPort);
204 + log.debug("Submitted BGP path intent matching dst TCP port 179"
205 + + "from BGP peer {} to BGPd {} : {}",
206 + bgpdPeerAddress, bgpdAddress, reversedIntentMatchDstTcpPort);
207 +
208 + // install intent for reversed BGP path from BGP peer to BGPd
209 + // matching source TCP port 179
210 + /*packetMatch = new PacketMatchBuilder().setEtherType(Ethernet.TYPE_IPV4)
211 + .setIpProto(PROTOCOL_TCP)
212 + .setSrcIpNet(new Ip4Prefix(bgpdPeerAddress,
213 + (short) Ip4Address.BIT_LENGTH))
214 + .setDstIpNet(new Ip4Prefix(bgpdAddress,
215 + (short) Ip4Address.BIT_LENGTH))
216 + .setSrcTcpPort(BGP_PORT)
217 + .build();*/
218 + selector = DefaultTrafficSelector.builder()
219 + .matchEthType(Ethernet.TYPE_IPV4)
220 + .matchIPProtocol(IPv4.PROTOCOL_TCP)
221 + .matchIPSrc(IpPrefix.valueOf(bgpdPeerAddress.toRealInt(), IPV4_BIT_LENGTH))
222 + .matchIPDst(IpPrefix.valueOf(bgpdAddress.toRealInt(), IPV4_BIT_LENGTH))
223 + .matchTcpSrc(BGP_PORT)
224 + .build();
225 +
226 + PointToPointIntent reversedIntentMatchSrcTcpPort = new PointToPointIntent(
227 + nextIntentId(), selector, treatment,
228 + bgpdPeerConnectPoint, bgpdConnectPoint);
229 + intentService.submit(reversedIntentMatchSrcTcpPort);
230 + log.debug("Submitted BGP path intent matching src TCP port 179"
231 + + "from BGP peer {} to BGPd {} : {}",
232 + bgpdPeerAddress, bgpdAddress, reversedIntentMatchSrcTcpPort);
233 +
234 + }
235 + }
236 + }
237 +
238 + /**
239 + * Sets up ICMP paths between each {@link BgpSpeaker} and all BGP peers
240 + * located in other external networks.
241 + * <p/>
242 + * Run a loop for all BGP speakers and a loop for all BGP Peers. Push
243 + * intents for paths from each BGP speaker to all peers. Push intents
244 + * for paths from all peers to each BGP speaker.
245 + */
246 + private void setupIcmpPaths() {
247 + for (BgpSpeaker bgpSpeaker : configInfoService.getBgpSpeakers()
248 + .values()) {
249 + log.debug("Start to set up ICMP paths for BGP speaker: {}",
250 + bgpSpeaker);
251 + ConnectPoint bgpdConnectPoint = bgpSpeaker.connectPoint();
252 + List<InterfaceAddress> interfaceAddresses = bgpSpeaker
253 + .interfaceAddresses();
254 +
255 + for (BgpPeer bgpPeer : configInfoService.getBgpPeers().values()) {
256 +
257 + Interface peerInterface = interfaceService.getInterface(
258 + bgpPeer.connectPoint());
259 +
260 + if (peerInterface == null) {
261 + log.error("Can not find the corresponding Interface from "
262 + + "configuration for BGP peer {}",
263 + bgpPeer.ipAddress());
264 + continue;
265 + }
266 + IpAddress bgpdAddress = null;
267 + for (InterfaceAddress interfaceAddress : interfaceAddresses) {
268 + if (interfaceAddress.connectPoint().equals(
269 + peerInterface.connectPoint())) {
270 + bgpdAddress = interfaceAddress.ipAddress();
271 + break;
272 + }
273 +
274 + }
275 + if (bgpdAddress == null) {
276 + log.debug("There is no IP address for bgpPeer: {} on "
277 + + "interface port: {}", bgpPeer,
278 + bgpPeer.connectPoint());
279 + return;
280 + }
281 +
282 + IpAddress bgpdPeerAddress = bgpPeer.ipAddress();
283 + ConnectPoint bgpdPeerConnectPoint = peerInterface.connectPoint();
284 +
285 + // install intent for ICMP path from BGPd to BGP peer
286 + /*PacketMatch packetMatch =
287 + new PacketMatchBuilder().setEtherType(
288 + Ethernet.TYPE_IPV4)
289 + .setIpProto(PROTOCOL_ICMP)
290 + .setSrcIpNet(new Ip4Prefix(bgpdAddress,
291 + (short) Ip4Address.BIT_LENGTH))
292 + .setDstIpNet(new Ip4Prefix(bgpdPeerAddress,
293 + (short) Ip4Address.BIT_LENGTH))
294 + .build();*/
295 + TrafficSelector selector = DefaultTrafficSelector.builder()
296 + .matchEthType(Ethernet.TYPE_IPV4)
297 + .matchIPProtocol(IPv4.PROTOCOL_ICMP)
298 + .matchIPSrc(IpPrefix.valueOf(bgpdAddress.toRealInt(), IPV4_BIT_LENGTH))
299 + .matchIPDst(IpPrefix.valueOf(bgpdPeerAddress.toRealInt(), IPV4_BIT_LENGTH))
300 + .build();
301 +
302 + TrafficTreatment treatment = DefaultTrafficTreatment.builder()
303 + .build();
304 +
305 + PointToPointIntent intent = new PointToPointIntent(
306 + nextIntentId(), selector, treatment,
307 + bgpdConnectPoint, bgpdPeerConnectPoint);
308 + intentService.submit(intent);
309 + log.debug("Submitted ICMP path intent from BGPd {} to peer {} :"
310 + + " {}", bgpdAddress, bgpdPeerAddress, intent);
311 +
312 + // install intent for reversed ICMP path from BGP peer to BGPd
313 + /*packetMatch = new PacketMatchBuilder().setEtherType(
314 + Ethernet.TYPE_IPV4)
315 + .setIpProto(PROTOCOL_ICMP)
316 + .setSrcIpNet(new Ip4Prefix(bgpdPeerAddress,
317 + (short) Ip4Address.BIT_LENGTH))
318 + .setDstIpNet(new Ip4Prefix(bgpdAddress,
319 + (short) Ip4Address.BIT_LENGTH))
320 + .build();*/
321 +
322 + selector = DefaultTrafficSelector.builder()
323 + .matchEthType(Ethernet.TYPE_IPV4)
324 + .matchIPProtocol(IPv4.PROTOCOL_ICMP)
325 + .matchIPSrc(IpPrefix.valueOf(bgpdPeerAddress.toRealInt(), IPV4_BIT_LENGTH))
326 + .matchIPDst(IpPrefix.valueOf(bgpdAddress.toRealInt(), IPV4_BIT_LENGTH))
327 + .build();
328 +
329 + PointToPointIntent reversedIntent = new PointToPointIntent(
330 + nextIntentId(), selector, treatment,
331 + bgpdPeerConnectPoint, bgpdConnectPoint);
332 + intentService.submit(reversedIntent);
333 + log.debug("Submitted ICMP path intent from BGP peer {} to BGPd"
334 + + " {} : {}",
335 + bgpdPeerAddress, bgpdAddress, reversedIntent);
336 + }
337 + }
338 + }
339 +
340 + private IntentId nextIntentId() {
341 + return new IntentId(intentId++);
342 + }
343 +}
...@@ -5,6 +5,10 @@ import static org.slf4j.LoggerFactory.getLogger; ...@@ -5,6 +5,10 @@ import static org.slf4j.LoggerFactory.getLogger;
5 import org.apache.felix.scr.annotations.Activate; 5 import org.apache.felix.scr.annotations.Activate;
6 import org.apache.felix.scr.annotations.Component; 6 import org.apache.felix.scr.annotations.Component;
7 import org.apache.felix.scr.annotations.Deactivate; 7 import org.apache.felix.scr.annotations.Deactivate;
8 +import org.apache.felix.scr.annotations.Reference;
9 +import org.apache.felix.scr.annotations.ReferenceCardinality;
10 +import org.onlab.onos.net.host.HostService;
11 +import org.onlab.onos.net.intent.IntentService;
8 import org.onlab.onos.sdnip.config.SdnIpConfigReader; 12 import org.onlab.onos.sdnip.config.SdnIpConfigReader;
9 import org.slf4j.Logger; 13 import org.slf4j.Logger;
10 14
...@@ -16,7 +20,14 @@ public class SdnIp { ...@@ -16,7 +20,14 @@ public class SdnIp {
16 20
17 private final Logger log = getLogger(getClass()); 21 private final Logger log = getLogger(getClass());
18 22
23 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
24 + protected IntentService intentService;
25 +
26 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
27 + protected HostService hostService;
28 +
19 private SdnIpConfigReader config; 29 private SdnIpConfigReader config;
30 + private PeerConnectivity peerConnectivity;
20 31
21 @Activate 32 @Activate
22 protected void activate() { 33 protected void activate() {
...@@ -24,6 +35,12 @@ public class SdnIp { ...@@ -24,6 +35,12 @@ public class SdnIp {
24 35
25 config = new SdnIpConfigReader(); 36 config = new SdnIpConfigReader();
26 config.init(); 37 config.init();
38 +
39 + InterfaceService interfaceService = new HostServiceBasedInterfaceService(hostService);
40 +
41 + peerConnectivity = new PeerConnectivity(config, interfaceService, intentService);
42 + peerConnectivity.start();
43 +
27 } 44 }
28 45
29 @Deactivate 46 @Deactivate
......
...@@ -8,19 +8,20 @@ import org.onlab.onos.net.DeviceId; ...@@ -8,19 +8,20 @@ import org.onlab.onos.net.DeviceId;
8 import org.onlab.onos.net.PortNumber; 8 import org.onlab.onos.net.PortNumber;
9 import org.onlab.packet.IpAddress; 9 import org.onlab.packet.IpAddress;
10 10
11 +import com.google.common.base.MoreObjects;
12 +
11 /** 13 /**
12 - * Configuration details for a BGP peer. It contains the peer's IP address and 14 + * Configuration details for a BGP peer.
13 - * an interface name which maps to the interface they are attached at.
14 */ 15 */
15 public class BgpPeer { 16 public class BgpPeer {
16 private final ConnectPoint connectPoint; 17 private final ConnectPoint connectPoint;
17 private final IpAddress ipAddress; 18 private final IpAddress ipAddress;
18 19
19 /** 20 /**
20 - * Class constructor, taking the interface name and IP address of the peer. 21 + * Creates a new BgpPeer.
21 * 22 *
22 - * @param interfaceName the String name of the interface which can be used 23 + * @param dpid the DPID of the switch the peer is attached at, as a String
23 - * to look up the interface this peer is attached at 24 + * @param port the port the peer is attached at
24 * @param ipAddress the IP address of the peer as a String 25 * @param ipAddress the IP address of the peer as a String
25 */ 26 */
26 public BgpPeer(@JsonProperty("attachmentDpid") String dpid, 27 public BgpPeer(@JsonProperty("attachmentDpid") String dpid,
...@@ -37,7 +38,7 @@ public class BgpPeer { ...@@ -37,7 +38,7 @@ public class BgpPeer {
37 * 38 *
38 * @return the connection point 39 * @return the connection point
39 */ 40 */
40 - public ConnectPoint getConnectPoint() { 41 + public ConnectPoint connectPoint() {
41 return connectPoint; 42 return connectPoint;
42 } 43 }
43 44
...@@ -46,7 +47,7 @@ public class BgpPeer { ...@@ -46,7 +47,7 @@ public class BgpPeer {
46 * 47 *
47 * @return the IP address 48 * @return the IP address
48 */ 49 */
49 - public IpAddress getIpAddress() { 50 + public IpAddress ipAddress() {
50 return ipAddress; 51 return ipAddress;
51 } 52 }
52 53
...@@ -69,4 +70,12 @@ public class BgpPeer { ...@@ -69,4 +70,12 @@ public class BgpPeer {
69 return Objects.equals(this.connectPoint, that.connectPoint) 70 return Objects.equals(this.connectPoint, that.connectPoint)
70 && Objects.equals(this.ipAddress, that.ipAddress); 71 && Objects.equals(this.ipAddress, that.ipAddress);
71 } 72 }
73 +
74 + @Override
75 + public String toString() {
76 + return MoreObjects.toStringHelper(getClass())
77 + .add("connectPoint", connectPoint)
78 + .add("ipAddress", ipAddress)
79 + .toString();
80 + }
72 } 81 }
......
...@@ -10,6 +10,8 @@ import org.onlab.onos.net.DeviceId; ...@@ -10,6 +10,8 @@ import org.onlab.onos.net.DeviceId;
10 import org.onlab.onos.net.PortNumber; 10 import org.onlab.onos.net.PortNumber;
11 import org.onlab.packet.MacAddress; 11 import org.onlab.packet.MacAddress;
12 12
13 +import com.google.common.base.MoreObjects;
14 +
13 /** 15 /**
14 * Represents a BGP daemon in SDN network. 16 * Represents a BGP daemon in SDN network.
15 * <p/> 17 * <p/>
...@@ -23,28 +25,28 @@ import org.onlab.packet.MacAddress; ...@@ -23,28 +25,28 @@ import org.onlab.packet.MacAddress;
23 * used to reference this speaker in the configuration. 25 * used to reference this speaker in the configuration.
24 */ 26 */
25 public class BgpSpeaker { 27 public class BgpSpeaker {
26 - private final String speakerName; 28 + private final String name;
27 - private final ConnectPoint attachmentSwitchPort; 29 + private final ConnectPoint connectPoint;
28 private final MacAddress macAddress; 30 private final MacAddress macAddress;
29 private List<InterfaceAddress> interfaceAddresses; 31 private List<InterfaceAddress> interfaceAddresses;
30 32
31 /** 33 /**
32 * Class constructor used by the JSON library to create an object. 34 * Class constructor used by the JSON library to create an object.
33 * 35 *
34 - * @param speakerName the name of the BGP router inside SDN network 36 + * @param name the name of the BGP speaker inside SDN network
35 - * @param attachmentDpid the DPID where the BGP router is attached to 37 + * @param attachmentDpid the DPID where the BGP speaker is attached to
36 - * @param attachmentPort the port where the BGP router is attached to 38 + * @param attachmentPort the port where the BGP speaker is attached to
37 - * @param macAddress the MAC address of the BGP router 39 + * @param macAddress the MAC address of the BGP speaker
38 */ 40 */
39 @JsonCreator 41 @JsonCreator
40 - public BgpSpeaker(@JsonProperty("name") String speakerName, 42 + public BgpSpeaker(@JsonProperty("name") String name,
41 @JsonProperty("attachmentDpid") String attachmentDpid, 43 @JsonProperty("attachmentDpid") String attachmentDpid,
42 @JsonProperty("attachmentPort") int attachmentPort, 44 @JsonProperty("attachmentPort") int attachmentPort,
43 @JsonProperty("macAddress") String macAddress) { 45 @JsonProperty("macAddress") String macAddress) {
44 46
45 - this.speakerName = speakerName; 47 + this.name = name;
46 this.macAddress = MacAddress.valueOf(macAddress); 48 this.macAddress = MacAddress.valueOf(macAddress);
47 - this.attachmentSwitchPort = new ConnectPoint( 49 + this.connectPoint = new ConnectPoint(
48 DeviceId.deviceId(SdnIpConfigReader.dpidToUri(attachmentDpid)), 50 DeviceId.deviceId(SdnIpConfigReader.dpidToUri(attachmentDpid)),
49 PortNumber.portNumber(attachmentPort)); 51 PortNumber.portNumber(attachmentPort));
50 } 52 }
...@@ -67,25 +69,25 @@ public class BgpSpeaker { ...@@ -67,25 +69,25 @@ public class BgpSpeaker {
67 * 69 *
68 * @return the BGP speaker name 70 * @return the BGP speaker name
69 */ 71 */
70 - public String getSpeakerName() { 72 + public String name() {
71 - return speakerName; 73 + return name;
72 } 74 }
73 75
74 /** 76 /**
75 - * Gets the switch port where the BGP speaker is attached. 77 + * Gets the connect point where the BGP speaker is attached.
76 * 78 *
77 - * @return the switch port where the BGP speaker is attached 79 + * @return the connect point
78 */ 80 */
79 - public ConnectPoint getAttachmentSwitchPort() { 81 + public ConnectPoint connectPoint() {
80 - return attachmentSwitchPort; 82 + return connectPoint;
81 } 83 }
82 84
83 /** 85 /**
84 * Gets the MAC address of the BGP speaker. 86 * Gets the MAC address of the BGP speaker.
85 * 87 *
86 - * @return the MAC address of the BGP speaker 88 + * @return the MAC address
87 */ 89 */
88 - public MacAddress getMacAddress() { 90 + public MacAddress macAddress() {
89 return macAddress; 91 return macAddress;
90 } 92 }
91 93
...@@ -96,7 +98,7 @@ public class BgpSpeaker { ...@@ -96,7 +98,7 @@ public class BgpSpeaker {
96 * @return a list of IP addresses of the BGP speaker configured on all 98 * @return a list of IP addresses of the BGP speaker configured on all
97 * virtual interfaces 99 * virtual interfaces
98 */ 100 */
99 - public List<InterfaceAddress> getInterfaceAddresses() { 101 + public List<InterfaceAddress> interfaceAddresses() {
100 return interfaceAddresses; 102 return interfaceAddresses;
101 } 103 }
102 104
...@@ -108,17 +110,27 @@ public class BgpSpeaker { ...@@ -108,17 +110,27 @@ public class BgpSpeaker {
108 110
109 BgpSpeaker otherBgpSpeaker = (BgpSpeaker) other; 111 BgpSpeaker otherBgpSpeaker = (BgpSpeaker) other;
110 112
111 - return speakerName.equals(otherBgpSpeaker.speakerName) && 113 + return name.equals(otherBgpSpeaker.name) &&
112 - attachmentSwitchPort.equals( 114 + connectPoint.equals(
113 - otherBgpSpeaker.attachmentSwitchPort) && 115 + otherBgpSpeaker.connectPoint) &&
114 macAddress.equals(otherBgpSpeaker.macAddress) && 116 macAddress.equals(otherBgpSpeaker.macAddress) &&
115 interfaceAddresses.equals(otherBgpSpeaker.interfaceAddresses); 117 interfaceAddresses.equals(otherBgpSpeaker.interfaceAddresses);
116 } 118 }
117 119
118 @Override 120 @Override
119 public int hashCode() { 121 public int hashCode() {
120 - return Objects.hash(speakerName, attachmentSwitchPort, macAddress, 122 + return Objects.hash(name, connectPoint, macAddress,
121 interfaceAddresses); 123 interfaceAddresses);
122 124
123 } 125 }
126 +
127 + @Override
128 + public String toString() {
129 + return MoreObjects.toStringHelper(getClass())
130 + .add("speakerName", name)
131 + .add("connectPoint", connectPoint)
132 + .add("macAddress", macAddress)
133 + .add("interfaceAddresses", interfaceAddresses)
134 + .toString();
135 + }
124 } 136 }
......
1 package org.onlab.onos.sdnip.config; 1 package org.onlab.onos.sdnip.config;
2 2
3 import java.util.Objects; 3 import java.util.Objects;
4 +import java.util.Set;
4 5
5 -import org.codehaus.jackson.annotate.JsonCreator;
6 -import org.codehaus.jackson.annotate.JsonProperty;
7 import org.onlab.onos.net.ConnectPoint; 6 import org.onlab.onos.net.ConnectPoint;
8 -import org.onlab.onos.net.DeviceId; 7 +import org.onlab.onos.net.host.PortAddresses;
9 -import org.onlab.onos.net.PortNumber;
10 import org.onlab.packet.IpPrefix; 8 import org.onlab.packet.IpPrefix;
9 +import org.onlab.packet.MacAddress;
10 +
11 +import com.google.common.base.MoreObjects;
12 +import com.google.common.collect.Sets;
11 13
12 /** 14 /**
13 - * Represents an interface, which is an external-facing switch port that 15 + * An Interface is a set of addresses that are logically mapped to a switch
14 - * connects to another network. 16 + * port in the network.
15 - * <p/>
16 - * SDN-IP treats external-facing ports similarly to router ports. Logically, it
17 - * assigns an IP subnetwork prefix and several IP addresses to each port which
18 - * are used for communication with the BGP peers located in other networks, for
19 - * example, the BGP peering sessions. The peers in other networks will be
20 - * configured to peer with the IP addresses (logically) assigned to the
21 - * interface. The logical {@code Interface} construct maps on to a physical
22 - * port in the data plane, which of course has no notion of IP addresses.
23 - * <p/>
24 - * Each interface has a name, which is a unique identifying String that is used
25 - * to reference this interface in the configuration (for example, to map
26 - * {@link BgpPeer}s to {@code Interfaces}.
27 */ 17 */
28 public class Interface { 18 public class Interface {
29 - private final String name; 19 + private final ConnectPoint connectPoint;
30 - private final ConnectPoint switchPort; 20 + private final Set<IpPrefix> ipAddresses;
31 - private final IpPrefix ip4Prefix; 21 + private final MacAddress macAddress;
32 22
33 /** 23 /**
34 - * Class constructor used by the JSON library to create an object. 24 + * Creates an Interface based on a connection point, a set of IP addresses
25 + * and a MAC address.
35 * 26 *
36 - * @param name the name of the interface 27 + * @param connectPoint the connect point this interface is mapped to
37 - * @param dpid the dpid of the switch 28 + * @param prefixAddress the IP addresses for the interface
38 - * @param port the port on the switch 29 + * @param macAddress the MAC address of the interface
39 - * @param prefixAddress the network prefix address logically assigned to the
40 - * interface
41 - * @param prefixLength the length of the network prefix of the IP address
42 */ 30 */
43 - @JsonCreator 31 + public Interface(ConnectPoint connectPoint, Set<IpPrefix> prefixAddress,
44 - public Interface(@JsonProperty("name") String name, 32 + MacAddress macAddress) {
45 - @JsonProperty("dpid") String dpid, 33 + this.connectPoint = connectPoint;
46 - @JsonProperty("port") int port, 34 + this.ipAddresses = Sets.newHashSet(prefixAddress);
47 - @JsonProperty("ipAddress") String prefixAddress, 35 + this.macAddress = macAddress;
48 - @JsonProperty("prefixLength") short prefixLength) {
49 - this.name = name;
50 - this.switchPort = new ConnectPoint(
51 - DeviceId.deviceId(SdnIpConfigReader.dpidToUri(dpid)),
52 - PortNumber.portNumber(port));
53 - this.ip4Prefix = IpPrefix.valueOf(prefixAddress + "/" + prefixLength);
54 } 36 }
55 37
56 /** 38 /**
57 - * Gets the name of the interface. 39 + * Creates an Interface based on a PortAddresses object.
58 * 40 *
59 - * @return the name of the interface 41 + * @param portAddresses the PortAddresses object to turn into an Interface
60 */ 42 */
61 - public String getName() { 43 + public Interface(PortAddresses portAddresses) {
62 - return name; 44 + connectPoint = portAddresses.connectPoint();
45 + ipAddresses = Sets.newHashSet(portAddresses.ips());
46 + macAddress = portAddresses.mac();
63 } 47 }
64 48
65 /** 49 /**
66 - * Gets the {@link SwitchPort} that this interface maps to. 50 + * Retrieves the connection point that this interface maps to.
67 * 51 *
68 - * @return the switch port 52 + * @return the connection point
69 */ 53 */
70 - public ConnectPoint getSwitchPort() { 54 + public ConnectPoint connectPoint() {
71 - return switchPort; 55 + return connectPoint;
72 } 56 }
73 57
74 /** 58 /**
75 - * Gets the IP prefix of the subnetwork which is logically assigned 59 + * Retrieves the set of IP addresses that are assigned to the interface.
76 - * to the switch port.
77 * 60 *
78 - * @return the IP prefix 61 + * @return the set of IP addresses
79 */ 62 */
80 - public IpPrefix getIp4Prefix() { 63 + public Set<IpPrefix> ips() {
81 - return ip4Prefix; 64 + return ipAddresses;
65 + }
66 +
67 + /**
68 + * Retrieves the MAC address that is assigned to the interface.
69 + *
70 + * @return the MAC address
71 + */
72 + public MacAddress mac() {
73 + return macAddress;
82 } 74 }
83 75
84 @Override 76 @Override
...@@ -89,13 +81,22 @@ public class Interface { ...@@ -89,13 +81,22 @@ public class Interface {
89 81
90 Interface otherInterface = (Interface) other; 82 Interface otherInterface = (Interface) other;
91 83
92 - return name.equals(otherInterface.name) && 84 + return connectPoint.equals(otherInterface.connectPoint) &&
93 - switchPort.equals(otherInterface.switchPort) && 85 + ipAddresses.equals(otherInterface.ipAddresses) &&
94 - ip4Prefix.equals(otherInterface.ip4Prefix); 86 + macAddress.equals(otherInterface.macAddress);
95 } 87 }
96 88
97 @Override 89 @Override
98 public int hashCode() { 90 public int hashCode() {
99 - return Objects.hash(name, switchPort, ip4Prefix); 91 + return Objects.hash(connectPoint, ipAddresses, macAddress);
92 + }
93 +
94 + @Override
95 + public String toString() {
96 + return MoreObjects.toStringHelper(getClass())
97 + .add("connectPoint", connectPoint)
98 + .add("ipAddresses", ipAddresses)
99 + .add("macAddress", macAddress)
100 + .toString();
100 } 101 }
101 } 102 }
......
...@@ -8,6 +8,8 @@ import org.onlab.onos.net.DeviceId; ...@@ -8,6 +8,8 @@ import org.onlab.onos.net.DeviceId;
8 import org.onlab.onos.net.PortNumber; 8 import org.onlab.onos.net.PortNumber;
9 import org.onlab.packet.IpAddress; 9 import org.onlab.packet.IpAddress;
10 10
11 +import com.google.common.base.MoreObjects;
12 +
11 /** 13 /**
12 * Represents an address of a {@link BgpSpeaker} configured on an 14 * Represents an address of a {@link BgpSpeaker} configured on an
13 * {@link Interface}. 15 * {@link Interface}.
...@@ -19,10 +21,10 @@ public class InterfaceAddress { ...@@ -19,10 +21,10 @@ public class InterfaceAddress {
19 private final IpAddress ipAddress; 21 private final IpAddress ipAddress;
20 22
21 /** 23 /**
22 - * Class constructor used by the JSON library to create an object. 24 + * Creates an InterfaceAddress object.
23 * 25 *
24 - * @param interfaceName the interface name for which an IP address of a BGP 26 + * @param dpid the DPID of the interface as a String
25 - * router is configured 27 + * @param port the port of the interface
26 * @param ipAddress the IP address of a {@link BgpSpeaker} configured on 28 * @param ipAddress the IP address of a {@link BgpSpeaker} configured on
27 * the interface 29 * the interface
28 */ 30 */
...@@ -40,7 +42,7 @@ public class InterfaceAddress { ...@@ -40,7 +42,7 @@ public class InterfaceAddress {
40 * 42 *
41 * @return the connection point 43 * @return the connection point
42 */ 44 */
43 - public ConnectPoint getConnectPoint() { 45 + public ConnectPoint connectPoint() {
44 return connectPoint; 46 return connectPoint;
45 } 47 }
46 48
...@@ -49,7 +51,7 @@ public class InterfaceAddress { ...@@ -49,7 +51,7 @@ public class InterfaceAddress {
49 * 51 *
50 * @return the IP address 52 * @return the IP address
51 */ 53 */
52 - public IpAddress getIpAddress() { 54 + public IpAddress ipAddress() {
53 return ipAddress; 55 return ipAddress;
54 } 56 }
55 57
...@@ -72,4 +74,12 @@ public class InterfaceAddress { ...@@ -72,4 +74,12 @@ public class InterfaceAddress {
72 return Objects.equals(this.connectPoint, that.connectPoint) 74 return Objects.equals(this.connectPoint, that.connectPoint)
73 && Objects.equals(this.ipAddress, that.ipAddress); 75 && Objects.equals(this.ipAddress, that.ipAddress);
74 } 76 }
77 +
78 + @Override
79 + public String toString() {
80 + return MoreObjects.toStringHelper(getClass())
81 + .add("connectPoint", connectPoint)
82 + .add("ipAddress", ipAddress)
83 + .toString();
84 + }
75 } 85 }
......
...@@ -50,11 +50,11 @@ public class SdnIpConfigReader implements SdnIpConfigService { ...@@ -50,11 +50,11 @@ public class SdnIpConfigReader implements SdnIpConfigService {
50 }*/ 50 }*/
51 bgpSpeakers = new ConcurrentHashMap<>(); 51 bgpSpeakers = new ConcurrentHashMap<>();
52 for (BgpSpeaker speaker : config.getBgpSpeakers()) { 52 for (BgpSpeaker speaker : config.getBgpSpeakers()) {
53 - bgpSpeakers.put(speaker.getSpeakerName(), speaker); 53 + bgpSpeakers.put(speaker.name(), speaker);
54 } 54 }
55 bgpPeers = new ConcurrentHashMap<>(); 55 bgpPeers = new ConcurrentHashMap<>();
56 for (BgpPeer peer : config.getPeers()) { 56 for (BgpPeer peer : config.getPeers()) {
57 - bgpPeers.put(peer.getIpAddress(), peer); 57 + bgpPeers.put(peer.ipAddress(), peer);
58 } 58 }
59 } catch (IOException e) { 59 } catch (IOException e) {
60 log.error("Error reading JSON file", e); 60 log.error("Error reading JSON file", e);
......
...@@ -161,10 +161,10 @@ public class FlowModBuilder { ...@@ -161,10 +161,10 @@ public class FlowModBuilder {
161 switch (l3m.subtype()) { 161 switch (l3m.subtype()) {
162 case IP_DST: 162 case IP_DST:
163 ip = (ModIPInstruction) i; 163 ip = (ModIPInstruction) i;
164 - return factory.actions().setNwDst(IPv4Address.of(ip.ip().toInt())); 164 + return factory.actions().setNwDst(IPv4Address.of(ip.ip().toRealInt()));
165 case IP_SRC: 165 case IP_SRC:
166 ip = (ModIPInstruction) i; 166 ip = (ModIPInstruction) i;
167 - return factory.actions().setNwSrc(IPv4Address.of(ip.ip().toInt())); 167 + return factory.actions().setNwSrc(IPv4Address.of(ip.ip().toRealInt()));
168 default: 168 default:
169 log.warn("Unimplemented action type {}.", l3m.subtype()); 169 log.warn("Unimplemented action type {}.", l3m.subtype());
170 break; 170 break;
...@@ -220,21 +220,21 @@ public class FlowModBuilder { ...@@ -220,21 +220,21 @@ public class FlowModBuilder {
220 case IPV4_DST: 220 case IPV4_DST:
221 ip = (IPCriterion) c; 221 ip = (IPCriterion) c;
222 if (ip.ip().isMasked()) { 222 if (ip.ip().isMasked()) {
223 - Masked<IPv4Address> maskedIp = Masked.of(IPv4Address.of(ip.ip().toInt()), 223 + Masked<IPv4Address> maskedIp = Masked.of(IPv4Address.of(ip.ip().toRealInt()),
224 - IPv4Address.of(ip.ip().netmask().toInt())); 224 + IPv4Address.of(ip.ip().netmask().toRealInt()));
225 mBuilder.setMasked(MatchField.IPV4_DST, maskedIp); 225 mBuilder.setMasked(MatchField.IPV4_DST, maskedIp);
226 } else { 226 } else {
227 - mBuilder.setExact(MatchField.IPV4_DST, IPv4Address.of(ip.ip().toInt())); 227 + mBuilder.setExact(MatchField.IPV4_DST, IPv4Address.of(ip.ip().toRealInt()));
228 } 228 }
229 break; 229 break;
230 case IPV4_SRC: 230 case IPV4_SRC:
231 ip = (IPCriterion) c; 231 ip = (IPCriterion) c;
232 if (ip.ip().isMasked()) { 232 if (ip.ip().isMasked()) {
233 - Masked<IPv4Address> maskedIp = Masked.of(IPv4Address.of(ip.ip().toInt()), 233 + Masked<IPv4Address> maskedIp = Masked.of(IPv4Address.of(ip.ip().toRealInt()),
234 - IPv4Address.of(ip.ip().netmask().toInt())); 234 + IPv4Address.of(ip.ip().netmask().toRealInt()));
235 mBuilder.setMasked(MatchField.IPV4_SRC, maskedIp); 235 mBuilder.setMasked(MatchField.IPV4_SRC, maskedIp);
236 } else { 236 } else {
237 - mBuilder.setExact(MatchField.IPV4_SRC, IPv4Address.of(ip.ip().toInt())); 237 + mBuilder.setExact(MatchField.IPV4_SRC, IPv4Address.of(ip.ip().toRealInt()));
238 } 238 }
239 break; 239 break;
240 case IP_PROTO: 240 case IP_PROTO:
......
...@@ -181,6 +181,15 @@ public final class IpAddress { ...@@ -181,6 +181,15 @@ public final class IpAddress {
181 return address; 181 return address;
182 } 182 }
183 183
184 + public int toRealInt() {
185 + int val = 0;
186 + for (int i = 0; i < octets.length; i++) {
187 + val <<= 8;
188 + val |= octets[i] & 0xff;
189 + }
190 + return val;
191 + }
192 +
184 /** 193 /**
185 * Helper for computing the mask value from CIDR. 194 * Helper for computing the mask value from CIDR.
186 * 195 *
......