blob: 75ffd98cc6907d7e0fea587034d796ee22ee321a [file] [log] [blame]
Jonathan Hartdc711bd2014-10-15 11:24:23 -07001package org.onlab.onos.sdnip;
2
3import java.util.List;
4
5import org.onlab.onos.net.ConnectPoint;
6import org.onlab.onos.net.flow.DefaultTrafficSelector;
7import org.onlab.onos.net.flow.DefaultTrafficTreatment;
8import org.onlab.onos.net.flow.TrafficSelector;
9import org.onlab.onos.net.flow.TrafficTreatment;
10import org.onlab.onos.net.intent.IntentId;
11import org.onlab.onos.net.intent.IntentService;
12import org.onlab.onos.net.intent.PointToPointIntent;
13import org.onlab.onos.sdnip.config.BgpPeer;
14import org.onlab.onos.sdnip.config.BgpSpeaker;
15import org.onlab.onos.sdnip.config.Interface;
16import org.onlab.onos.sdnip.config.InterfaceAddress;
17import org.onlab.onos.sdnip.config.SdnIpConfigService;
18import org.onlab.packet.Ethernet;
19import org.onlab.packet.IPv4;
20import org.onlab.packet.IpAddress;
21import org.onlab.packet.IpPrefix;
22import org.slf4j.Logger;
23import org.slf4j.LoggerFactory;
24
25/**
26 * Manages the connectivity requirements between peers.
27 */
28public 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}