blob: 31cd97120ac94fd19178e3215eedb2a7251ee42c [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.
Jonathan Hart5e0aac02014-10-15 11:43:45 -0700126 TrafficSelector selector = DefaultTrafficSelector.builder()
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700127 .matchEthType(Ethernet.TYPE_IPV4)
128 .matchIPProtocol(IPv4.PROTOCOL_TCP)
Jonathan Hartbcae7bd2014-10-16 10:24:41 -0700129 .matchIPSrc(IpPrefix.valueOf(bgpdAddress.toInt(), IPV4_BIT_LENGTH))
130 .matchIPDst(IpPrefix.valueOf(bgpdPeerAddress.toInt(), IPV4_BIT_LENGTH))
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700131 .matchTcpDst(BGP_PORT)
132 .build();
133
134 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
135 .build();
136
137 PointToPointIntent intentMatchDstTcpPort = new PointToPointIntent(
138 nextIntentId(), selector, treatment,
139 bgpdConnectPoint, bgpdPeerConnectPoint);
140 intentService.submit(intentMatchDstTcpPort);
141 log.debug("Submitted BGP path intent matching dst TCP port 179 "
142 + "from BGPd {} to peer {}: {}",
143 bgpdAddress, bgpdPeerAddress, intentMatchDstTcpPort);
144
145 // install intent for BGP path from BGPd to BGP peer matching
146 // source TCP port 179
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700147 selector = DefaultTrafficSelector.builder()
148 .matchEthType(Ethernet.TYPE_IPV4)
149 .matchIPProtocol(IPv4.PROTOCOL_TCP)
Jonathan Hartbcae7bd2014-10-16 10:24:41 -0700150 .matchIPSrc(IpPrefix.valueOf(bgpdAddress.toInt(), IPV4_BIT_LENGTH))
151 .matchIPDst(IpPrefix.valueOf(bgpdPeerAddress.toInt(), IPV4_BIT_LENGTH))
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700152 .matchTcpSrc(BGP_PORT)
153 .build();
154
155 PointToPointIntent intentMatchSrcTcpPort = new PointToPointIntent(
156 nextIntentId(), selector, treatment,
157 bgpdConnectPoint, bgpdPeerConnectPoint);
158 intentService.submit(intentMatchSrcTcpPort);
159 log.debug("Submitted BGP path intent matching src TCP port 179"
160 + "from BGPd {} to peer {}: {}",
161 bgpdAddress, bgpdPeerAddress, intentMatchSrcTcpPort);
162
163 // install intent for reversed BGP path from BGP peer to BGPd
164 // matching destination TCP port 179
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700165 selector = DefaultTrafficSelector.builder()
166 .matchEthType(Ethernet.TYPE_IPV4)
167 .matchIPProtocol(IPv4.PROTOCOL_TCP)
Jonathan Hartbcae7bd2014-10-16 10:24:41 -0700168 .matchIPSrc(IpPrefix.valueOf(bgpdPeerAddress.toInt(), IPV4_BIT_LENGTH))
169 .matchIPDst(IpPrefix.valueOf(bgpdAddress.toInt(), IPV4_BIT_LENGTH))
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700170 .matchTcpDst(BGP_PORT)
171 .build();
172
173 PointToPointIntent reversedIntentMatchDstTcpPort = new PointToPointIntent(
174 nextIntentId(), selector, treatment,
175 bgpdPeerConnectPoint, bgpdConnectPoint);
176 intentService.submit(reversedIntentMatchDstTcpPort);
177 log.debug("Submitted BGP path intent matching dst TCP port 179"
178 + "from BGP peer {} to BGPd {} : {}",
179 bgpdPeerAddress, bgpdAddress, reversedIntentMatchDstTcpPort);
180
181 // install intent for reversed BGP path from BGP peer to BGPd
182 // matching source TCP port 179
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700183 selector = DefaultTrafficSelector.builder()
184 .matchEthType(Ethernet.TYPE_IPV4)
185 .matchIPProtocol(IPv4.PROTOCOL_TCP)
Jonathan Hartbcae7bd2014-10-16 10:24:41 -0700186 .matchIPSrc(IpPrefix.valueOf(bgpdPeerAddress.toInt(), IPV4_BIT_LENGTH))
187 .matchIPDst(IpPrefix.valueOf(bgpdAddress.toInt(), IPV4_BIT_LENGTH))
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700188 .matchTcpSrc(BGP_PORT)
189 .build();
190
191 PointToPointIntent reversedIntentMatchSrcTcpPort = new PointToPointIntent(
192 nextIntentId(), selector, treatment,
193 bgpdPeerConnectPoint, bgpdConnectPoint);
194 intentService.submit(reversedIntentMatchSrcTcpPort);
195 log.debug("Submitted BGP path intent matching src TCP port 179"
196 + "from BGP peer {} to BGPd {} : {}",
197 bgpdPeerAddress, bgpdAddress, reversedIntentMatchSrcTcpPort);
198
199 }
200 }
201 }
202
203 /**
204 * Sets up ICMP paths between each {@link BgpSpeaker} and all BGP peers
205 * located in other external networks.
206 * <p/>
207 * Run a loop for all BGP speakers and a loop for all BGP Peers. Push
208 * intents for paths from each BGP speaker to all peers. Push intents
209 * for paths from all peers to each BGP speaker.
210 */
211 private void setupIcmpPaths() {
212 for (BgpSpeaker bgpSpeaker : configInfoService.getBgpSpeakers()
213 .values()) {
214 log.debug("Start to set up ICMP paths for BGP speaker: {}",
215 bgpSpeaker);
216 ConnectPoint bgpdConnectPoint = bgpSpeaker.connectPoint();
217 List<InterfaceAddress> interfaceAddresses = bgpSpeaker
218 .interfaceAddresses();
219
220 for (BgpPeer bgpPeer : configInfoService.getBgpPeers().values()) {
221
222 Interface peerInterface = interfaceService.getInterface(
223 bgpPeer.connectPoint());
224
225 if (peerInterface == null) {
226 log.error("Can not find the corresponding Interface from "
227 + "configuration for BGP peer {}",
228 bgpPeer.ipAddress());
229 continue;
230 }
231 IpAddress bgpdAddress = null;
232 for (InterfaceAddress interfaceAddress : interfaceAddresses) {
233 if (interfaceAddress.connectPoint().equals(
234 peerInterface.connectPoint())) {
235 bgpdAddress = interfaceAddress.ipAddress();
236 break;
237 }
238
239 }
240 if (bgpdAddress == null) {
241 log.debug("There is no IP address for bgpPeer: {} on "
242 + "interface port: {}", bgpPeer,
243 bgpPeer.connectPoint());
244 return;
245 }
246
247 IpAddress bgpdPeerAddress = bgpPeer.ipAddress();
248 ConnectPoint bgpdPeerConnectPoint = peerInterface.connectPoint();
249
250 // install intent for ICMP path from BGPd to BGP peer
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700251 TrafficSelector selector = DefaultTrafficSelector.builder()
252 .matchEthType(Ethernet.TYPE_IPV4)
253 .matchIPProtocol(IPv4.PROTOCOL_ICMP)
Jonathan Hartbcae7bd2014-10-16 10:24:41 -0700254 .matchIPSrc(IpPrefix.valueOf(bgpdAddress.toInt(), IPV4_BIT_LENGTH))
255 .matchIPDst(IpPrefix.valueOf(bgpdPeerAddress.toInt(), IPV4_BIT_LENGTH))
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700256 .build();
257
258 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
259 .build();
260
261 PointToPointIntent intent = new PointToPointIntent(
262 nextIntentId(), selector, treatment,
263 bgpdConnectPoint, bgpdPeerConnectPoint);
264 intentService.submit(intent);
265 log.debug("Submitted ICMP path intent from BGPd {} to peer {} :"
266 + " {}", bgpdAddress, bgpdPeerAddress, intent);
267
268 // install intent for reversed ICMP path from BGP peer to BGPd
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700269 selector = DefaultTrafficSelector.builder()
270 .matchEthType(Ethernet.TYPE_IPV4)
271 .matchIPProtocol(IPv4.PROTOCOL_ICMP)
Jonathan Hartbcae7bd2014-10-16 10:24:41 -0700272 .matchIPSrc(IpPrefix.valueOf(bgpdPeerAddress.toInt(), IPV4_BIT_LENGTH))
273 .matchIPDst(IpPrefix.valueOf(bgpdAddress.toInt(), IPV4_BIT_LENGTH))
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700274 .build();
275
276 PointToPointIntent reversedIntent = new PointToPointIntent(
277 nextIntentId(), selector, treatment,
278 bgpdPeerConnectPoint, bgpdConnectPoint);
279 intentService.submit(reversedIntent);
280 log.debug("Submitted ICMP path intent from BGP peer {} to BGPd"
281 + " {} : {}",
282 bgpdPeerAddress, bgpdAddress, reversedIntent);
283 }
284 }
285 }
286
287 private IntentId nextIntentId() {
288 return new IntentId(intentId++);
289 }
290}