diff --git a/apps/reactive-routing/pom.xml b/apps/reactive-routing/pom.xml
index d7bde79ce0..a5059cab59 100644
--- a/apps/reactive-routing/pom.xml
+++ b/apps/reactive-routing/pom.xml
@@ -41,6 +41,11 @@
onos-app-routing
${project.version}
+
+
+ org.onosproject
+ onos-api
+
\ No newline at end of file
diff --git a/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/SdnIpReactiveRouting.java b/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/SdnIpReactiveRouting.java
index a74387fa4e..46f7fd9889 100644
--- a/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/SdnIpReactiveRouting.java
+++ b/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/SdnIpReactiveRouting.java
@@ -16,13 +16,17 @@
package org.onosproject.reactive.routing;
import static org.slf4j.LoggerFactory.getLogger;
+import java.nio.ByteBuffer;
+
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.packet.ARP;
import org.onlab.packet.Ethernet;
import org.onlab.packet.IPv4;
+import org.onlab.packet.Ip4Address;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onosproject.core.ApplicationId;
@@ -40,6 +44,7 @@ import org.onosproject.net.packet.PacketPriority;
import org.onosproject.net.packet.PacketProcessor;
import org.onosproject.net.packet.PacketService;
import org.onosproject.routing.RoutingService;
+import org.onosproject.routing.config.RoutingConfigurationService;
import org.slf4j.Logger;
/**
@@ -64,6 +69,9 @@ public class SdnIpReactiveRouting {
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected RoutingService routingService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected RoutingConfigurationService config;
+
private ApplicationId appId;
private ReactiveRoutingProcessor processor =
@@ -78,6 +86,9 @@ public class SdnIpReactiveRouting {
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
// TODO: to support IPv6 later
selector.matchEthType(Ethernet.TYPE_IPV4);
+ packetService.requestPackets(selector.build(),
+ PacketPriority.REACTIVE, appId);
+ selector.matchEthType(Ethernet.TYPE_ARP);
packetService.requestPackets(selector.build(),
PacketPriority.REACTIVE, appId);
@@ -100,31 +111,56 @@ public class SdnIpReactiveRouting {
if (ethPkt == null) {
return;
}
-
- // In theory, we do not need to check whether it is Ethernet
- // TYPE_IPV4. However, due to the current implementation of the
- // packetService, we will receive all packets from all subscribers.
- // Hence, we have to check the Ethernet type again here.
- if (ethPkt.getEtherType() != Ethernet.TYPE_IPV4) {
- return;
- }
-
- // Parse packet
- IPv4 ipv4Packet = (IPv4) ethPkt.getPayload();
- IpAddress dstIp =
- IpAddress.valueOf(ipv4Packet.getDestinationAddress());
- IpAddress srcIp =
- IpAddress.valueOf(ipv4Packet.getSourceAddress());
ConnectPoint srcConnectPoint = pkt.receivedFrom();
- MacAddress srcMac = ethPkt.getSourceMAC();
- routingService.packetReactiveProcessor(dstIp, srcIp,
- srcConnectPoint, srcMac);
- // TODO emit packet first or packetReactiveProcessor first
- ConnectPoint egressConnectPoint = null;
- egressConnectPoint = routingService.getEgressConnectPoint(dstIp);
- if (egressConnectPoint != null) {
- forwardPacketToDst(context, egressConnectPoint);
+ switch (ethPkt.getEtherType()) {
+ case Ethernet.TYPE_ARP:
+ ARP arpPacket = (ARP) ethPkt.getPayload();
+ Ip4Address targetIpAddress = Ip4Address
+ .valueOf(arpPacket.getTargetProtocolAddress());
+ // Only when it is an ARP request packet and the target IP
+ // address is a virtual gateway IP address, then it will be
+ // processed.
+ if (arpPacket.getOpCode() == ARP.OP_REQUEST
+ && config.isVirtualGatewayIpAddress(targetIpAddress)) {
+ MacAddress gatewayMacAddress =
+ config.getVirtualGatewayMacAddress();
+ if (gatewayMacAddress == null) {
+ break;
+ }
+ Ethernet eth = ARP.buildArpReply(targetIpAddress,
+ gatewayMacAddress,
+ ethPkt);
+
+ TrafficTreatment.Builder builder =
+ DefaultTrafficTreatment.builder();
+ builder.setOutput(srcConnectPoint.port());
+ packetService.emit(new DefaultOutboundPacket(
+ srcConnectPoint.deviceId(),
+ builder.build(),
+ ByteBuffer.wrap(eth.serialize())));
+ }
+ break;
+ case Ethernet.TYPE_IPV4:
+ // Parse packet
+ IPv4 ipv4Packet = (IPv4) ethPkt.getPayload();
+ IpAddress dstIp =
+ IpAddress.valueOf(ipv4Packet.getDestinationAddress());
+ IpAddress srcIp =
+ IpAddress.valueOf(ipv4Packet.getSourceAddress());
+ MacAddress srcMac = ethPkt.getSourceMAC();
+ routingService.packetReactiveProcessor(dstIp, srcIp,
+ srcConnectPoint, srcMac);
+
+ // TODO emit packet first or packetReactiveProcessor first
+ ConnectPoint egressConnectPoint = null;
+ egressConnectPoint = routingService.getEgressConnectPoint(dstIp);
+ if (egressConnectPoint != null) {
+ forwardPacketToDst(context, egressConnectPoint);
+ }
+ break;
+ default:
+ break;
}
}
}
diff --git a/apps/routing-api/src/main/java/org/onosproject/routing/config/LocalIpPrefixEntry.java b/apps/routing-api/src/main/java/org/onosproject/routing/config/LocalIpPrefixEntry.java
index a2f3c8c180..3f62db4f59 100644
--- a/apps/routing-api/src/main/java/org/onosproject/routing/config/LocalIpPrefixEntry.java
+++ b/apps/routing-api/src/main/java/org/onosproject/routing/config/LocalIpPrefixEntry.java
@@ -20,6 +20,7 @@ import com.google.common.base.MoreObjects;
import java.util.Objects;
+import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
/**
@@ -28,6 +29,7 @@ import org.onlab.packet.IpPrefix;
public class LocalIpPrefixEntry {
private final IpPrefix ipPrefix;
private final IpPrefixType type;
+ private final IpAddress gatewayIpAddress;
/**
* Specifies the type of local IP prefix.
@@ -55,9 +57,12 @@ public class LocalIpPrefixEntry {
* @param type an IP prefix type as an IpPrefixType
*/
public LocalIpPrefixEntry(@JsonProperty("ipPrefix") String ipPrefix,
- @JsonProperty("type") IpPrefixType type) {
+ @JsonProperty("type") IpPrefixType type,
+ @JsonProperty("gatewayIp") IpAddress
+ gatewayIpAddress) {
this.ipPrefix = IpPrefix.valueOf(ipPrefix);
this.type = type;
+ this.gatewayIpAddress = gatewayIpAddress;
}
/**
@@ -78,6 +83,15 @@ public class LocalIpPrefixEntry {
return type;
}
+ /**
+ * Gets the gateway IP address of the IP prefix entry.
+ *
+ * @return the gateway IP address
+ */
+ public IpAddress getGatewayIpAddress() {
+ return gatewayIpAddress;
+ }
+
/**
* Tests whether the IP version of this entry is IPv4.
*
diff --git a/apps/routing-api/src/main/java/org/onosproject/routing/config/RoutingConfigurationService.java b/apps/routing-api/src/main/java/org/onosproject/routing/config/RoutingConfigurationService.java
index a30632866c..a500ff4c23 100644
--- a/apps/routing-api/src/main/java/org/onosproject/routing/config/RoutingConfigurationService.java
+++ b/apps/routing-api/src/main/java/org/onosproject/routing/config/RoutingConfigurationService.java
@@ -17,6 +17,7 @@ package org.onosproject.routing.config;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
import org.onosproject.net.ConnectPoint;
import java.util.Map;
@@ -41,6 +42,21 @@ public interface RoutingConfigurationService {
*/
public Map getBgpPeers();
+ /**
+ * Gets the MAC address configured for virtual gateway in SDN network.
+ *
+ * @return the MAC address of virtual gateway
+ */
+ public MacAddress getVirtualGatewayMacAddress();
+
+ /**
+ * Evaluates whether an IP address is a virtual gateway IP address.
+ *
+ * @param ipAddress the IP address to evaluate
+ * @return true if the IP address is a virtual gateway address, otherwise false
+ */
+ public boolean isVirtualGatewayIpAddress(IpAddress ipAddress);
+
/**
* Evaluates whether an IP address belongs to local SDN network.
*
diff --git a/apps/routing/src/main/java/org/onosproject/routing/config/impl/Configuration.java b/apps/routing/src/main/java/org/onosproject/routing/config/impl/Configuration.java
index 76f1df0ba7..d5a9e29a39 100644
--- a/apps/routing/src/main/java/org/onosproject/routing/config/impl/Configuration.java
+++ b/apps/routing/src/main/java/org/onosproject/routing/config/impl/Configuration.java
@@ -17,6 +17,7 @@ package org.onosproject.routing.config.impl;
import com.fasterxml.jackson.annotation.JsonProperty;
+import org.onlab.packet.MacAddress;
import org.onosproject.routing.config.BgpPeer;
import org.onosproject.routing.config.BgpSpeaker;
import org.onosproject.routing.config.LocalIpPrefixEntry;
@@ -33,6 +34,7 @@ public class Configuration {
// the BGP routers outside our SDN network the BGP peers.
private List bgpSpeakers;
private List peers;
+ private MacAddress virtualGatewayMacAddress;
// All IP prefixes from the configuration are local
private List localIp4PrefixEntries =
@@ -77,7 +79,7 @@ public class Configuration {
}
/**
- * Sets a list of BGP peers we are configured to peer with.
+ * Sets a list of BGP peers we configured to peer with.
*
* @param peers the list of BGP peers
*/
@@ -86,6 +88,26 @@ public class Configuration {
this.peers = peers;
}
+ /**
+ * Gets the MAC address we configured for virtual gateway
+ * in SDN network.
+ *
+ * @return the MAC address of virtual gateway
+ */
+ public MacAddress getVirtualGatewayMacAddress() {
+ return virtualGatewayMacAddress;
+ }
+
+ /**
+ * Sets the MAC address for virtual gateway in SDN network.
+ *
+ * @param virtualGatewayMacAddress the MAC address of virtual gateway
+ */
+ @JsonProperty("virtualGatewayMacAddress")
+ public void setVirtualGatewayMacAddress(MacAddress virtualGatewayMacAddress) {
+ this.virtualGatewayMacAddress = virtualGatewayMacAddress;
+ }
+
/**
* Gets a list of local IPv4 prefix entries configured for local
* SDN network.
diff --git a/apps/routing/src/main/java/org/onosproject/routing/config/impl/RoutingConfigurationImpl.java b/apps/routing/src/main/java/org/onosproject/routing/config/impl/RoutingConfigurationImpl.java
index abb6a13290..c45d286b73 100644
--- a/apps/routing/src/main/java/org/onosproject/routing/config/impl/RoutingConfigurationImpl.java
+++ b/apps/routing/src/main/java/org/onosproject/routing/config/impl/RoutingConfigurationImpl.java
@@ -29,6 +29,7 @@ import org.onlab.packet.Ip4Address;
import org.onlab.packet.Ip6Address;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.host.HostService;
import org.onosproject.routing.config.BgpPeer;
@@ -43,6 +44,7 @@ import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Collections;
+import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@@ -68,6 +70,7 @@ public class RoutingConfigurationImpl implements RoutingConfigurationService {
private Map bgpSpeakers = new ConcurrentHashMap<>();
private Map bgpPeers = new ConcurrentHashMap<>();
+ private Set gatewayIpAddresses = new HashSet<>();
private InvertedRadixTree
localPrefixTable4 = new ConcurrentInvertedRadixTree<>(
@@ -76,6 +79,7 @@ public class RoutingConfigurationImpl implements RoutingConfigurationService {
localPrefixTable6 = new ConcurrentInvertedRadixTree<>(
new DefaultByteArrayNodeFactory());
+ private MacAddress virtualGatewayMacAddress;
private HostToInterfaceAdaptor hostAdaptor;
@Activate
@@ -109,12 +113,16 @@ public class RoutingConfigurationImpl implements RoutingConfigurationService {
for (LocalIpPrefixEntry entry : config.getLocalIp4PrefixEntries()) {
localPrefixTable4.put(createBinaryString(entry.ipPrefix()),
entry);
+ gatewayIpAddresses.add(entry.getGatewayIpAddress());
}
for (LocalIpPrefixEntry entry : config.getLocalIp6PrefixEntries()) {
localPrefixTable6.put(createBinaryString(entry.ipPrefix()),
entry);
+ gatewayIpAddresses.add(entry.getGatewayIpAddress());
}
+ virtualGatewayMacAddress = config.getVirtualGatewayMacAddress();
+
} catch (FileNotFoundException e) {
log.warn("Configuration file not found: {}", configFileName);
} catch (IOException e) {
@@ -178,4 +186,14 @@ public class RoutingConfigurationImpl implements RoutingConfigurationService {
createBinaryString(ipPrefix)) != null);
}
+ @Override
+ public boolean isVirtualGatewayIpAddress(IpAddress ipAddress) {
+ return gatewayIpAddresses.contains(ipAddress);
+ }
+
+ @Override
+ public MacAddress getVirtualGatewayMacAddress() {
+ return virtualGatewayMacAddress;
+ }
+
}
diff --git a/apps/sdnip/src/main/resources/config-examples/sdnip.json b/apps/sdnip/src/main/resources/config-examples/sdnip.json
index 913687ee81..c51de68ae0 100644
--- a/apps/sdnip/src/main/resources/config-examples/sdnip.json
+++ b/apps/sdnip/src/main/resources/config-examples/sdnip.json
@@ -66,17 +66,21 @@
"ip4LocalPrefixes" : [
{
"ipPrefix" : "100.0.0.0/24",
- "type" : "PUBLIC"
+ "type" : "PUBLIC",
+ "gatewayIp" : "100.0.0.1"
},
{
"ipPrefix" : "200.0.0.0/8",
- "type" : "PUBLIC"
+ "type" : "PUBLIC",
+ "gatewayIp" : "200.0.0.3"
},
{
"ipPrefix" : "192.0.0.0/24",
- "type" : "PRIVATE"
+ "type" : "PRIVATE",
+ "gatewayIp" : "192.0.0.254"
}
],
"ip6LocalPrefixes" : [
- ]
+ ],
+ "virtualGatewayMacAddress" : "00:00:00:00:00:01"
}
diff --git a/core/api/src/main/java/org/onosproject/net/proxyarp/ProxyArpService.java b/core/api/src/main/java/org/onosproject/net/proxyarp/ProxyArpService.java
index 920585eb2e..55c7247edd 100644
--- a/core/api/src/main/java/org/onosproject/net/proxyarp/ProxyArpService.java
+++ b/core/api/src/main/java/org/onosproject/net/proxyarp/ProxyArpService.java
@@ -61,5 +61,4 @@ public interface ProxyArpService {
* @return true if handled, false otherwise.
*/
boolean handlePacket(PacketContext context);
-
}
diff --git a/core/net/src/main/java/org/onosproject/net/proxyarp/impl/ProxyArpManager.java b/core/net/src/main/java/org/onosproject/net/proxyarp/impl/ProxyArpManager.java
index 161518c957..27c97613bb 100644
--- a/core/net/src/main/java/org/onosproject/net/proxyarp/impl/ProxyArpManager.java
+++ b/core/net/src/main/java/org/onosproject/net/proxyarp/impl/ProxyArpManager.java
@@ -156,7 +156,7 @@ public class ProxyArpManager implements ProxyArpService {
for (InterfaceIpAddress ia : addresses.ipAddresses()) {
if (ia.ipAddress().equals(targetAddress)) {
Ethernet arpReply =
- buildArpReply(targetAddress, addresses.mac(), eth);
+ ARP.buildArpReply(targetAddress, addresses.mac(), eth);
sendTo(arpReply, inPort);
}
}
@@ -181,7 +181,7 @@ public class ProxyArpManager implements ProxyArpService {
if (src != null && dst != null) {
// We know the target host so we can respond
- Ethernet arpReply = buildArpReply(targetAddress, dst.mac(), eth);
+ Ethernet arpReply = ARP.buildArpReply(targetAddress, dst.mac(), eth);
sendTo(arpReply, inPort);
return;
}
@@ -296,7 +296,6 @@ public class ProxyArpManager implements ProxyArpService {
sendTo(ndpReply, inPort);
}
-
/**
* Outputs the given packet out the given port.
*
@@ -481,41 +480,6 @@ public class ProxyArpManager implements ProxyArpService {
return portNumbers;
}
- /**
- * Builds an ARP reply based on a request.
- *
- * @param srcIp the IP address to use as the reply source
- * @param srcMac the MAC address to use as the reply source
- * @param request the ARP request we got
- * @return an Ethernet frame containing the ARP reply
- */
- private Ethernet buildArpReply(Ip4Address srcIp, MacAddress srcMac,
- Ethernet request) {
-
- Ethernet eth = new Ethernet();
- eth.setDestinationMACAddress(request.getSourceMAC());
- eth.setSourceMACAddress(srcMac);
- eth.setEtherType(Ethernet.TYPE_ARP);
- eth.setVlanID(request.getVlanID());
-
- ARP arp = new ARP();
- arp.setOpCode(ARP.OP_REPLY);
- arp.setProtocolType(ARP.PROTO_TYPE_IP);
- arp.setHardwareType(ARP.HW_TYPE_ETHERNET);
-
- arp.setProtocolAddressLength((byte) Ip4Address.BYTE_LENGTH);
- arp.setHardwareAddressLength((byte) Ethernet.DATALAYER_ADDRESS_LENGTH);
- arp.setSenderHardwareAddress(srcMac.toBytes());
- arp.setTargetHardwareAddress(request.getSourceMACAddress());
-
- arp.setTargetProtocolAddress(((ARP) request.getPayload())
- .getSenderProtocolAddress());
- arp.setSenderProtocolAddress(srcIp.toInt());
-
- eth.setPayload(arp);
- return eth;
- }
-
/**
* Builds an Neighbor Discovery reply based on a request.
*
diff --git a/utils/misc/src/main/java/org/onlab/packet/ARP.java b/utils/misc/src/main/java/org/onlab/packet/ARP.java
index 86fb289696..88e1d4ff49 100644
--- a/utils/misc/src/main/java/org/onlab/packet/ARP.java
+++ b/utils/misc/src/main/java/org/onlab/packet/ARP.java
@@ -357,4 +357,39 @@ public class ARP extends BasePacket {
+ ", targetProtocolAddress="
+ Arrays.toString(this.targetProtocolAddress) + "]";
}
+
+ /**
+ * Builds an ARP reply based on a request.
+ *
+ * @param srcIp the IP address to use as the reply source
+ * @param srcMac the MAC address to use as the reply source
+ * @param request the ARP request we got
+ * @return an Ethernet frame containing the ARP reply
+ */
+ public static Ethernet buildArpReply(Ip4Address srcIp, MacAddress srcMac,
+ Ethernet request) {
+
+ Ethernet eth = new Ethernet();
+ eth.setDestinationMACAddress(request.getSourceMAC());
+ eth.setSourceMACAddress(srcMac);
+ eth.setEtherType(Ethernet.TYPE_ARP);
+ eth.setVlanID(request.getVlanID());
+
+ ARP arp = new ARP();
+ arp.setOpCode(ARP.OP_REPLY);
+ arp.setProtocolType(ARP.PROTO_TYPE_IP);
+ arp.setHardwareType(ARP.HW_TYPE_ETHERNET);
+
+ arp.setProtocolAddressLength((byte) Ip4Address.BYTE_LENGTH);
+ arp.setHardwareAddressLength((byte) Ethernet.DATALAYER_ADDRESS_LENGTH);
+ arp.setSenderHardwareAddress(srcMac.toBytes());
+ arp.setTargetHardwareAddress(request.getSourceMACAddress());
+
+ arp.setTargetProtocolAddress(((ARP) request.getPayload())
+ .getSenderProtocolAddress());
+ arp.setSenderProtocolAddress(srcIp.toInt());
+
+ eth.setPayload(arp);
+ return eth;
+ }
}