Ported PeerConnectivity onto ONOS next, and implemented a service that can
construct Interface objects based on PortAddresses from HostService.
Showing
12 changed files
with
628 additions
and
126 deletions
| ... | @@ -2,35 +2,40 @@ | ... | @@ -2,35 +2,40 @@ |
| 2 | <project xmlns="http://maven.apache.org/POM/4.0.0" | 2 | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| 3 | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | 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"> | 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> | 5 | + <modelVersion>4.0.0</modelVersion> |
| 6 | 6 | ||
| 7 | - <parent> | 7 | + <parent> |
| 8 | - <groupId>org.onlab.onos</groupId> | 8 | + <groupId>org.onlab.onos</groupId> |
| 9 | - <artifactId>onos-apps</artifactId> | 9 | + <artifactId>onos-apps</artifactId> |
| 10 | - <version>1.0.0-SNAPSHOT</version> | 10 | + <version>1.0.0-SNAPSHOT</version> |
| 11 | - <relativePath>../pom.xml</relativePath> | 11 | + <relativePath>../pom.xml</relativePath> |
| 12 | - </parent> | 12 | + </parent> |
| 13 | 13 | ||
| 14 | - <artifactId>onos-app-sdnip</artifactId> | 14 | + <artifactId>onos-app-sdnip</artifactId> |
| 15 | - <packaging>bundle</packaging> | 15 | + <packaging>bundle</packaging> |
| 16 | 16 | ||
| 17 | - <description>SDN-IP peering application</description> | 17 | + <description>SDN-IP peering application</description> |
| 18 | 18 | ||
| 19 | - <dependencies> | 19 | + <dependencies> |
| 20 | - <dependency> | 20 | + <dependency> |
| 21 | - <groupId>org.codehaus.jackson</groupId> | 21 | + <groupId>org.codehaus.jackson</groupId> |
| 22 | - <artifactId>jackson-core-asl</artifactId> | 22 | + <artifactId>jackson-core-asl</artifactId> |
| 23 | - </dependency> | 23 | + </dependency> |
| 24 | - <dependency> | 24 | + <dependency> |
| 25 | - <groupId>org.codehaus.jackson</groupId> | 25 | + <groupId>org.codehaus.jackson</groupId> |
| 26 | - <artifactId>jackson-mapper-asl</artifactId> | 26 | + <artifactId>jackson-mapper-asl</artifactId> |
| 27 | - </dependency> | 27 | + </dependency> |
| 28 | - <dependency> | 28 | + <dependency> |
| 29 | - <groupId>com.fasterxml.jackson.core</groupId> | 29 | + <groupId>com.fasterxml.jackson.core</groupId> |
| 30 | - <artifactId>jackson-annotations</artifactId> | 30 | + <artifactId>jackson-annotations</artifactId> |
| 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 | - </dependencies> | 34 | + |
| 35 | + <dependency> | ||
| 36 | + <groupId>com.google.guava</groupId> | ||
| 37 | + <artifactId>guava</artifactId> | ||
| 38 | + </dependency> | ||
| 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; |
| 82 | } | 65 | } |
| 83 | 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; | ||
| 74 | + } | ||
| 75 | + | ||
| 84 | @Override | 76 | @Override |
| 85 | public boolean equals(Object other) { | 77 | public boolean equals(Object other) { |
| 86 | if (!(other instanceof Interface)) { | 78 | if (!(other instanceof Interface)) { |
| ... | @@ -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 | * | ... | ... |
-
Please register or login to post a comment