Jonathan Hart

Ported the configuration reader for the SDN-IP specific configuration

...@@ -5,6 +5,7 @@ import static org.slf4j.LoggerFactory.getLogger; ...@@ -5,6 +5,7 @@ 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.onlab.onos.sdnip.config.SdnIpConfigReader;
8 import org.slf4j.Logger; 9 import org.slf4j.Logger;
9 10
10 /** 11 /**
...@@ -15,9 +16,14 @@ public class SdnIp { ...@@ -15,9 +16,14 @@ public class SdnIp {
15 16
16 private final Logger log = getLogger(getClass()); 17 private final Logger log = getLogger(getClass());
17 18
19 + private SdnIpConfigReader config;
20 +
18 @Activate 21 @Activate
19 protected void activate() { 22 protected void activate() {
20 log.debug("SDN-IP started"); 23 log.debug("SDN-IP started");
24 +
25 + config = new SdnIpConfigReader();
26 + config.init();
21 } 27 }
22 28
23 @Deactivate 29 @Deactivate
......
1 +package org.onlab.onos.sdnip.config;
2 +
3 +import java.util.Objects;
4 +
5 +import org.codehaus.jackson.annotate.JsonProperty;
6 +import org.onlab.onos.net.ConnectPoint;
7 +import org.onlab.onos.net.DeviceId;
8 +import org.onlab.onos.net.PortNumber;
9 +import org.onlab.packet.IpAddress;
10 +
11 +/**
12 + * Configuration details for a BGP peer. It contains the peer's IP address and
13 + * an interface name which maps to the interface they are attached at.
14 + */
15 +public class BgpPeer {
16 + private final ConnectPoint connectPoint;
17 + private final IpAddress ipAddress;
18 +
19 + /**
20 + * Class constructor, taking the interface name and IP address of the peer.
21 + *
22 + * @param interfaceName the String name of the interface which can be used
23 + * to look up the interface this peer is attached at
24 + * @param ipAddress the IP address of the peer as a String
25 + */
26 + public BgpPeer(@JsonProperty("attachmentDpid") String dpid,
27 + @JsonProperty("attachmentPort") int port,
28 + @JsonProperty("ipAddress") String ipAddress) {
29 + this.connectPoint = new ConnectPoint(
30 + DeviceId.deviceId(SdnIpConfigReader.dpidToUri(dpid)),
31 + PortNumber.portNumber(port));
32 + this.ipAddress = IpAddress.valueOf(ipAddress);
33 + }
34 +
35 + /**
36 + * Gets the connection point of the peer.
37 + *
38 + * @return the connection point
39 + */
40 + public ConnectPoint getConnectPoint() {
41 + return connectPoint;
42 + }
43 +
44 + /**
45 + * Gets the IP address of the peer.
46 + *
47 + * @return the IP address
48 + */
49 + public IpAddress getIpAddress() {
50 + return ipAddress;
51 + }
52 +
53 + @Override
54 + public int hashCode() {
55 + return Objects.hash(connectPoint, ipAddress);
56 + }
57 +
58 + @Override
59 + public boolean equals(Object obj) {
60 + if (obj == this) {
61 + return true;
62 + }
63 +
64 + if (!(obj instanceof BgpPeer)) {
65 + return false;
66 + }
67 +
68 + BgpPeer that = (BgpPeer) obj;
69 + return Objects.equals(this.connectPoint, that.connectPoint)
70 + && Objects.equals(this.ipAddress, that.ipAddress);
71 + }
72 +}
1 +package org.onlab.onos.sdnip.config;
2 +
3 +import java.util.List;
4 +import java.util.Objects;
5 +
6 +import org.codehaus.jackson.annotate.JsonCreator;
7 +import org.codehaus.jackson.annotate.JsonProperty;
8 +import org.onlab.onos.net.ConnectPoint;
9 +import org.onlab.onos.net.DeviceId;
10 +import org.onlab.onos.net.PortNumber;
11 +import org.onlab.packet.MacAddress;
12 +
13 +/**
14 + * Represents a BGP daemon in SDN network.
15 + * <p/>
16 + * Each BGP speaker has a attachment point, which includes a switch DPID and a
17 + * switch port. Each BGP speaker has one MAC address and several IP addresses,
18 + * which are used to peer with BGP peers outside the SDN network. For each
19 + * peer outside the SDN network, we configure a different IP address to BGP
20 + * speaker inside the SDN network.
21 + * <p/>
22 + * Each BGP speaker has a name, which is a unique identifying String that is
23 + * used to reference this speaker in the configuration.
24 + */
25 +public class BgpSpeaker {
26 + private final String speakerName;
27 + private final ConnectPoint attachmentSwitchPort;
28 + private final MacAddress macAddress;
29 + private List<InterfaceAddress> interfaceAddresses;
30 +
31 + /**
32 + * Class constructor used by the JSON library to create an object.
33 + *
34 + * @param speakerName the name of the BGP router inside SDN network
35 + * @param attachmentDpid the DPID where the BGP router is attached to
36 + * @param attachmentPort the port where the BGP router is attached to
37 + * @param macAddress the MAC address of the BGP router
38 + */
39 + @JsonCreator
40 + public BgpSpeaker(@JsonProperty("name") String speakerName,
41 + @JsonProperty("attachmentDpid") String attachmentDpid,
42 + @JsonProperty("attachmentPort") int attachmentPort,
43 + @JsonProperty("macAddress") String macAddress) {
44 +
45 + this.speakerName = speakerName;
46 + this.macAddress = MacAddress.valueOf(macAddress);
47 + this.attachmentSwitchPort = new ConnectPoint(
48 + DeviceId.deviceId(SdnIpConfigReader.dpidToUri(attachmentDpid)),
49 + PortNumber.portNumber(attachmentPort));
50 + }
51 +
52 + /**
53 + * Sets the addresses we configured for the BGP speaker on all virtual
54 + * {@link Interface}s.
55 + *
56 + * @param interfaceAddresses a list of IP addresses of the BGP speaker
57 + * configured on all virtual interfaces
58 + */
59 + @JsonProperty("interfaceAddresses")
60 + public void setInterfaceAddresses(
61 + List<InterfaceAddress> interfaceAddresses) {
62 + this.interfaceAddresses = interfaceAddresses;
63 + }
64 +
65 + /**
66 + * Gets the BGP speaker name.
67 + *
68 + * @return the BGP speaker name
69 + */
70 + public String getSpeakerName() {
71 + return speakerName;
72 + }
73 +
74 + /**
75 + * Gets the switch port where the BGP speaker is attached.
76 + *
77 + * @return the switch port where the BGP speaker is attached
78 + */
79 + public ConnectPoint getAttachmentSwitchPort() {
80 + return attachmentSwitchPort;
81 + }
82 +
83 + /**
84 + * Gets the MAC address of the BGP speaker.
85 + *
86 + * @return the MAC address of the BGP speaker
87 + */
88 + public MacAddress getMacAddress() {
89 + return macAddress;
90 + }
91 +
92 + /**
93 + * Gets all IP addresses configured on all {@link Interface}s of the
94 + * BGP speaker.
95 + *
96 + * @return a list of IP addresses of the BGP speaker configured on all
97 + * virtual interfaces
98 + */
99 + public List<InterfaceAddress> getInterfaceAddresses() {
100 + return interfaceAddresses;
101 + }
102 +
103 + @Override
104 + public boolean equals(Object other) {
105 + if (!(other instanceof BgpSpeaker)) {
106 + return false;
107 + }
108 +
109 + BgpSpeaker otherBgpSpeaker = (BgpSpeaker) other;
110 +
111 + return speakerName.equals(otherBgpSpeaker.speakerName) &&
112 + attachmentSwitchPort.equals(
113 + otherBgpSpeaker.attachmentSwitchPort) &&
114 + macAddress.equals(otherBgpSpeaker.macAddress) &&
115 + interfaceAddresses.equals(otherBgpSpeaker.interfaceAddresses);
116 + }
117 +
118 + @Override
119 + public int hashCode() {
120 + return Objects.hash(speakerName, attachmentSwitchPort, macAddress,
121 + interfaceAddresses);
122 +
123 + }
124 +}
1 +package org.onlab.onos.sdnip.config;
2 +
3 +import java.util.Collections;
4 +import java.util.List;
5 +
6 +import org.codehaus.jackson.annotate.JsonProperty;
7 +
8 +/**
9 + * Contains the configuration data for SDN-IP that has been read from a
10 + * JSON-formatted configuration file.
11 + */
12 +public class Configuration {
13 + // We call the BGP routers in our SDN network the BGP speakers, and call
14 + // the BGP routers outside our SDN network the BGP peers.
15 + private List<BgpSpeaker> bgpSpeakers;
16 + private List<BgpPeer> peers;
17 +
18 + /**
19 + * Default constructor.
20 + */
21 + public Configuration() {
22 + }
23 +
24 + /**
25 + * Gets a list of bgpSpeakers in the system, represented by
26 + * {@link BgpSpeaker} objects.
27 + *
28 + * @return the list of BGP speakers
29 + */
30 + public List<BgpSpeaker> getBgpSpeakers() {
31 + return Collections.unmodifiableList(bgpSpeakers);
32 + }
33 +
34 + /**
35 + * Sets a list of bgpSpeakers in the system.
36 + *
37 + * @param bgpSpeakers the list of BGP speakers
38 + */
39 + @JsonProperty("bgpSpeakers")
40 + public void setBgpSpeakers(List<BgpSpeaker> bgpSpeakers) {
41 + this.bgpSpeakers = bgpSpeakers;
42 + }
43 +
44 + /**
45 + * Gets a list of BGP peers we are configured to peer with. Peers are
46 + * represented by {@link BgpPeer} objects.
47 + *
48 + * @return the list of BGP peers
49 + */
50 + public List<BgpPeer> getPeers() {
51 + return Collections.unmodifiableList(peers);
52 + }
53 +
54 + /**
55 + * Sets a list of BGP peers we are configured to peer with.
56 + *
57 + * @param peers the list of BGP peers
58 + */
59 + @JsonProperty("bgpPeers")
60 + public void setPeers(List<BgpPeer> peers) {
61 + this.peers = peers;
62 + }
63 +
64 +}
1 +package org.onlab.onos.sdnip.config;
2 +
3 +import java.util.Objects;
4 +
5 +import org.codehaus.jackson.annotate.JsonCreator;
6 +import org.codehaus.jackson.annotate.JsonProperty;
7 +import org.onlab.onos.net.ConnectPoint;
8 +import org.onlab.onos.net.DeviceId;
9 +import org.onlab.onos.net.PortNumber;
10 +import org.onlab.packet.IpPrefix;
11 +
12 +/**
13 + * Represents an interface, which is an external-facing switch port that
14 + * connects to another 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 + */
28 +public class Interface {
29 + private final String name;
30 + private final ConnectPoint switchPort;
31 + private final IpPrefix ip4Prefix;
32 +
33 + /**
34 + * Class constructor used by the JSON library to create an object.
35 + *
36 + * @param name the name of the interface
37 + * @param dpid the dpid of the switch
38 + * @param port the port on the switch
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 + */
43 + @JsonCreator
44 + public Interface(@JsonProperty("name") String name,
45 + @JsonProperty("dpid") String dpid,
46 + @JsonProperty("port") int port,
47 + @JsonProperty("ipAddress") String prefixAddress,
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 + }
55 +
56 + /**
57 + * Gets the name of the interface.
58 + *
59 + * @return the name of the interface
60 + */
61 + public String getName() {
62 + return name;
63 + }
64 +
65 + /**
66 + * Gets the {@link SwitchPort} that this interface maps to.
67 + *
68 + * @return the switch port
69 + */
70 + public ConnectPoint getSwitchPort() {
71 + return switchPort;
72 + }
73 +
74 + /**
75 + * Gets the IP prefix of the subnetwork which is logically assigned
76 + * to the switch port.
77 + *
78 + * @return the IP prefix
79 + */
80 + public IpPrefix getIp4Prefix() {
81 + return ip4Prefix;
82 + }
83 +
84 + @Override
85 + public boolean equals(Object other) {
86 + if (!(other instanceof Interface)) {
87 + return false;
88 + }
89 +
90 + Interface otherInterface = (Interface) other;
91 +
92 + return name.equals(otherInterface.name) &&
93 + switchPort.equals(otherInterface.switchPort) &&
94 + ip4Prefix.equals(otherInterface.ip4Prefix);
95 + }
96 +
97 + @Override
98 + public int hashCode() {
99 + return Objects.hash(name, switchPort, ip4Prefix);
100 + }
101 +}
1 +package org.onlab.onos.sdnip.config;
2 +
3 +import java.util.Objects;
4 +
5 +import org.codehaus.jackson.annotate.JsonProperty;
6 +import org.onlab.onos.net.ConnectPoint;
7 +import org.onlab.onos.net.DeviceId;
8 +import org.onlab.onos.net.PortNumber;
9 +import org.onlab.packet.IpAddress;
10 +
11 +/**
12 + * Represents an address of a {@link BgpSpeaker} configured on an
13 + * {@link Interface}.
14 + * <p/>
15 + * Each InterfaceAddress includes the interface name and an IP address.
16 + */
17 +public class InterfaceAddress {
18 + private final ConnectPoint connectPoint;
19 + private final IpAddress ipAddress;
20 +
21 + /**
22 + * Class constructor used by the JSON library to create an object.
23 + *
24 + * @param interfaceName the interface name for which an IP address of a BGP
25 + * router is configured
26 + * @param ipAddress the IP address of a {@link BgpSpeaker} configured on
27 + * the interface
28 + */
29 + public InterfaceAddress(@JsonProperty("interfaceDpid") String dpid,
30 + @JsonProperty("interfacePort") int port,
31 + @JsonProperty("ipAddress") String ipAddress) {
32 + this.connectPoint = new ConnectPoint(
33 + DeviceId.deviceId(SdnIpConfigReader.dpidToUri(dpid)),
34 + PortNumber.portNumber(port));
35 + this.ipAddress = IpAddress.valueOf(ipAddress);
36 + }
37 +
38 + /**
39 + * Gets the connection point of the peer.
40 + *
41 + * @return the connection point
42 + */
43 + public ConnectPoint getConnectPoint() {
44 + return connectPoint;
45 + }
46 +
47 + /**
48 + * Gets the IP address of a BGP speaker configured on an {@link Interface}.
49 + *
50 + * @return the IP address
51 + */
52 + public IpAddress getIpAddress() {
53 + return ipAddress;
54 + }
55 +
56 + @Override
57 + public int hashCode() {
58 + return Objects.hash(connectPoint, ipAddress);
59 + }
60 +
61 + @Override
62 + public boolean equals(Object obj) {
63 + if (obj == this) {
64 + return true;
65 + }
66 +
67 + if (!(obj instanceof InterfaceAddress)) {
68 + return false;
69 + }
70 +
71 + InterfaceAddress that = (InterfaceAddress) obj;
72 + return Objects.equals(this.connectPoint, that.connectPoint)
73 + && Objects.equals(this.ipAddress, that.ipAddress);
74 + }
75 +}
1 +package org.onlab.onos.sdnip.config;
2 +
3 +import java.io.File;
4 +import java.io.IOException;
5 +import java.util.Collections;
6 +import java.util.Map;
7 +import java.util.concurrent.ConcurrentHashMap;
8 +
9 +import org.codehaus.jackson.map.ObjectMapper;
10 +import org.onlab.packet.IpAddress;
11 +import org.slf4j.Logger;
12 +import org.slf4j.LoggerFactory;
13 +
14 +/**
15 + * SDN-IP Config Reader provides IConfigInfoService
16 + * by reading from an SDN-IP configuration file.
17 + * It must be enabled on the nodes within the cluster
18 + * not running SDN-IP.
19 + * <p/>
20 + * TODO: As a long term solution, a module providing
21 + * general network configuration to ONOS nodes should be used.
22 + */
23 +public class SdnIpConfigReader implements SdnIpConfigService {
24 +
25 + private static final Logger log = LoggerFactory.getLogger(SdnIpConfigReader.class);
26 +
27 + private static final String DEFAULT_CONFIG_FILE = "config/sdnip.json";
28 + private String configFileName = DEFAULT_CONFIG_FILE;
29 + //private Map<String, Interface> interfaces;
30 + // We call the BGP routers in our SDN network the BGP speakers, and call
31 + // the BGP routers outside our SDN network the BGP peers.
32 + private Map<String, BgpSpeaker> bgpSpeakers;
33 + private Map<IpAddress, BgpPeer> bgpPeers;
34 + //private InvertedRadixTree<Interface> interfaceRoutes;
35 +
36 + /**
37 + * Reads the info contained in the configuration file.
38 + *
39 + * @param configFilename The name of configuration file for SDN-IP application.
40 + */
41 + private void readConfiguration(String configFilename) {
42 + File gatewaysFile = new File(configFilename);
43 + ObjectMapper mapper = new ObjectMapper();
44 +
45 + try {
46 + Configuration config = mapper.readValue(gatewaysFile, Configuration.class);
47 + /*interfaces = new ConcurrentHashMap<>();
48 + for (Interface intf : config.getInterfaces()) {
49 + interfaces.put(intf.getName(), intf);
50 + }*/
51 + bgpSpeakers = new ConcurrentHashMap<>();
52 + for (BgpSpeaker speaker : config.getBgpSpeakers()) {
53 + bgpSpeakers.put(speaker.getSpeakerName(), speaker);
54 + }
55 + bgpPeers = new ConcurrentHashMap<>();
56 + for (BgpPeer peer : config.getPeers()) {
57 + bgpPeers.put(peer.getIpAddress(), peer);
58 + }
59 + } catch (IOException e) {
60 + log.error("Error reading JSON file", e);
61 + //throw new ConfigurationRuntimeException("Error in JSON file", e);
62 + }
63 +
64 + // Populate the interface InvertedRadixTree
65 + /*for (Interface intf : interfaces.values()) {
66 + Ip4Prefix prefix = intf.getIp4Prefix();
67 + String binaryString = RouteEntry.createBinaryString(prefix);
68 + interfaceRoutes.put(binaryString, intf);
69 + }*/
70 + }
71 +
72 + /**
73 + * To find the Interface which has longest matchable IP prefix (sub-network
74 + * prefix) to next hop IP address.
75 + *
76 + * @param address the IP address of next hop router
77 + * @return the Interface which has longest matchable IP prefix
78 + */
79 + /*private Interface longestInterfacePrefixMatch(IpAddress address) {
80 + Ip4Prefix prefixToSearchFor =
81 + new Ip4Prefix(address, (short) Ip4Address.BIT_LENGTH);
82 + String binaryString = RouteEntry.createBinaryString(prefixToSearchFor);
83 +
84 + Iterator<Interface> it =
85 + interfaceRoutes.getValuesForKeysPrefixing(binaryString).iterator();
86 + Interface intf = null;
87 + // Find the last prefix, which will be the longest prefix
88 + while (it.hasNext()) {
89 + intf = it.next();
90 + }
91 +
92 + return intf;
93 + }*/
94 +
95 + /*@Override
96 + public Interface getOutgoingInterface(IpAddress dstIpAddress) {
97 + return longestInterfacePrefixMatch(dstIpAddress);
98 + }*/
99 +
100 + public void init() {
101 + //interfaceRoutes = new ConcurrentInvertedRadixTree<>(
102 + //new DefaultByteArrayNodeFactory());
103 +
104 + // Reading config values
105 + /*String configFilenameParameter = context.getConfigParams(this).get("configfile");
106 + if (configFilenameParameter != null) {
107 + currentConfigFilename = configFilenameParameter;
108 + }*/
109 + log.debug("Config file set to {}", configFileName);
110 +
111 + readConfiguration(configFileName);
112 + }
113 +
114 + /*@Override
115 + public Map<String, Interface> getInterfaces() {
116 + return Collections.unmodifiableMap(interfaces);
117 + }*/
118 +
119 + @Override
120 + public Map<String, BgpSpeaker> getBgpSpeakers() {
121 + return Collections.unmodifiableMap(bgpSpeakers);
122 + }
123 +
124 + @Override
125 + public Map<IpAddress, BgpPeer> getBgpPeers() {
126 + return Collections.unmodifiableMap(bgpPeers);
127 + }
128 +
129 + static String dpidToUri(String dpid) {
130 + return "of:" + dpid.replace(":", "");
131 + }
132 +}
1 +package org.onlab.onos.sdnip.config;
2 +
3 +import java.util.Map;
4 +
5 +import org.onlab.packet.IpAddress;
6 +
7 +/**
8 + * Provides information about the layer 3 properties of the network.
9 + * This is based on IP addresses configured on ports in the network.
10 + */
11 +public interface SdnIpConfigService {
12 +
13 + /**
14 + * Gets the list of virtual external-facing interfaces.
15 + *
16 + * @return the map of interface names to interface objects
17 + */
18 + //public Map<String, Interface> getInterfaces();
19 +
20 + /**
21 + * Gets the list of BGP speakers inside the SDN network.
22 + *
23 + * @return the map of BGP speaker names to BGP speaker objects
24 + */
25 + public Map<String, BgpSpeaker> getBgpSpeakers();
26 +
27 + /**
28 + * Gets the list of configured BGP peers.
29 + *
30 + * @return the map from peer IP address to BgpPeer object
31 + */
32 + public Map<IpAddress, BgpPeer> getBgpPeers();
33 +
34 + /**
35 + * Gets the Interface object for the interface that packets
36 + * to dstIpAddress will be sent out of. Returns null if dstIpAddress is not
37 + * in a directly connected network, or if no interfaces are configured.
38 + *
39 + * @param dstIpAddress destination IP address that we want to match to
40 + * an outgoing interface
41 + * @return the Interface object if one is found, otherwise null
42 + */
43 + //public Interface getOutgoingInterface(IpAddress dstIpAddress);
44 +
45 +}
1 +/**
2 + * SDN-IP configuration.
3 + */
4 +package org.onlab.onos.sdnip.config;
...\ No newline at end of file ...\ No newline at end of file
...@@ -163,4 +163,10 @@ ...@@ -163,4 +163,10 @@
163 <bundle>mvn:org.onlab.onos/onos-app-config/1.0.0-SNAPSHOT</bundle> 163 <bundle>mvn:org.onlab.onos/onos-app-config/1.0.0-SNAPSHOT</bundle>
164 </feature> 164 </feature>
165 165
166 + <feature name="onos-app-sdnip" version="1.0.0"
167 + description="SDN-IP peering application">
168 + <feature>onos-api</feature>
169 + <bundle>mvn:org.onlab.onos/onos-app-sdnip/1.0.0-SNAPSHOT</bundle>
170 + </feature>
171 +
166 </features> 172 </features>
......