Pingping Lin
Committed by Jonathan Hart

add a virtual gateway for reactive routing

  There is no physical gateway in SDN network.
  However a host needs a gateway when it tries to communicate with a remote host.
  So we designed a virtual gateway for SDN network.
  The virtual gateway can have multiple IP addresses.
  Each IP address is used as the default gateway address of an IP prefix.
  We only configure one MAC address to the virtual gateway.
  You can choose any MAC address from the BGP speakers as the virtual gateway MAC address.
  We configure this MAC address staticly in the sdnip.json configuration file.

Change-Id: I2a72bef797fc55d25bb5473e8fca624ad659e1d1
...@@ -41,6 +41,11 @@ ...@@ -41,6 +41,11 @@
41 <artifactId>onos-app-routing</artifactId> 41 <artifactId>onos-app-routing</artifactId>
42 <version>${project.version}</version> 42 <version>${project.version}</version>
43 </dependency> 43 </dependency>
44 +
45 + <dependency>
46 + <groupId>org.onosproject</groupId>
47 + <artifactId>onos-api</artifactId>
48 + </dependency>
44 </dependencies> 49 </dependencies>
45 50
46 </project> 51 </project>
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -16,13 +16,17 @@ ...@@ -16,13 +16,17 @@
16 package org.onosproject.reactive.routing; 16 package org.onosproject.reactive.routing;
17 import static org.slf4j.LoggerFactory.getLogger; 17 import static org.slf4j.LoggerFactory.getLogger;
18 18
19 +import java.nio.ByteBuffer;
20 +
19 import org.apache.felix.scr.annotations.Activate; 21 import org.apache.felix.scr.annotations.Activate;
20 import org.apache.felix.scr.annotations.Component; 22 import org.apache.felix.scr.annotations.Component;
21 import org.apache.felix.scr.annotations.Deactivate; 23 import org.apache.felix.scr.annotations.Deactivate;
22 import org.apache.felix.scr.annotations.Reference; 24 import org.apache.felix.scr.annotations.Reference;
23 import org.apache.felix.scr.annotations.ReferenceCardinality; 25 import org.apache.felix.scr.annotations.ReferenceCardinality;
26 +import org.onlab.packet.ARP;
24 import org.onlab.packet.Ethernet; 27 import org.onlab.packet.Ethernet;
25 import org.onlab.packet.IPv4; 28 import org.onlab.packet.IPv4;
29 +import org.onlab.packet.Ip4Address;
26 import org.onlab.packet.IpAddress; 30 import org.onlab.packet.IpAddress;
27 import org.onlab.packet.MacAddress; 31 import org.onlab.packet.MacAddress;
28 import org.onosproject.core.ApplicationId; 32 import org.onosproject.core.ApplicationId;
...@@ -40,6 +44,7 @@ import org.onosproject.net.packet.PacketPriority; ...@@ -40,6 +44,7 @@ import org.onosproject.net.packet.PacketPriority;
40 import org.onosproject.net.packet.PacketProcessor; 44 import org.onosproject.net.packet.PacketProcessor;
41 import org.onosproject.net.packet.PacketService; 45 import org.onosproject.net.packet.PacketService;
42 import org.onosproject.routing.RoutingService; 46 import org.onosproject.routing.RoutingService;
47 +import org.onosproject.routing.config.RoutingConfigurationService;
43 import org.slf4j.Logger; 48 import org.slf4j.Logger;
44 49
45 /** 50 /**
...@@ -64,6 +69,9 @@ public class SdnIpReactiveRouting { ...@@ -64,6 +69,9 @@ public class SdnIpReactiveRouting {
64 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 69 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
65 protected RoutingService routingService; 70 protected RoutingService routingService;
66 71
72 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
73 + protected RoutingConfigurationService config;
74 +
67 private ApplicationId appId; 75 private ApplicationId appId;
68 76
69 private ReactiveRoutingProcessor processor = 77 private ReactiveRoutingProcessor processor =
...@@ -80,6 +88,9 @@ public class SdnIpReactiveRouting { ...@@ -80,6 +88,9 @@ public class SdnIpReactiveRouting {
80 selector.matchEthType(Ethernet.TYPE_IPV4); 88 selector.matchEthType(Ethernet.TYPE_IPV4);
81 packetService.requestPackets(selector.build(), 89 packetService.requestPackets(selector.build(),
82 PacketPriority.REACTIVE, appId); 90 PacketPriority.REACTIVE, appId);
91 + selector.matchEthType(Ethernet.TYPE_ARP);
92 + packetService.requestPackets(selector.build(),
93 + PacketPriority.REACTIVE, appId);
83 94
84 log.info("SDN-IP Reactive Routing Started"); 95 log.info("SDN-IP Reactive Routing Started");
85 } 96 }
...@@ -100,31 +111,56 @@ public class SdnIpReactiveRouting { ...@@ -100,31 +111,56 @@ public class SdnIpReactiveRouting {
100 if (ethPkt == null) { 111 if (ethPkt == null) {
101 return; 112 return;
102 } 113 }
103 -
104 - // In theory, we do not need to check whether it is Ethernet
105 - // TYPE_IPV4. However, due to the current implementation of the
106 - // packetService, we will receive all packets from all subscribers.
107 - // Hence, we have to check the Ethernet type again here.
108 - if (ethPkt.getEtherType() != Ethernet.TYPE_IPV4) {
109 - return;
110 - }
111 -
112 - // Parse packet
113 - IPv4 ipv4Packet = (IPv4) ethPkt.getPayload();
114 - IpAddress dstIp =
115 - IpAddress.valueOf(ipv4Packet.getDestinationAddress());
116 - IpAddress srcIp =
117 - IpAddress.valueOf(ipv4Packet.getSourceAddress());
118 ConnectPoint srcConnectPoint = pkt.receivedFrom(); 114 ConnectPoint srcConnectPoint = pkt.receivedFrom();
119 - MacAddress srcMac = ethPkt.getSourceMAC(); 115 +
120 - routingService.packetReactiveProcessor(dstIp, srcIp, 116 + switch (ethPkt.getEtherType()) {
121 - srcConnectPoint, srcMac); 117 + case Ethernet.TYPE_ARP:
122 - 118 + ARP arpPacket = (ARP) ethPkt.getPayload();
123 - // TODO emit packet first or packetReactiveProcessor first 119 + Ip4Address targetIpAddress = Ip4Address
124 - ConnectPoint egressConnectPoint = null; 120 + .valueOf(arpPacket.getTargetProtocolAddress());
125 - egressConnectPoint = routingService.getEgressConnectPoint(dstIp); 121 + // Only when it is an ARP request packet and the target IP
126 - if (egressConnectPoint != null) { 122 + // address is a virtual gateway IP address, then it will be
127 - forwardPacketToDst(context, egressConnectPoint); 123 + // processed.
124 + if (arpPacket.getOpCode() == ARP.OP_REQUEST
125 + && config.isVirtualGatewayIpAddress(targetIpAddress)) {
126 + MacAddress gatewayMacAddress =
127 + config.getVirtualGatewayMacAddress();
128 + if (gatewayMacAddress == null) {
129 + break;
130 + }
131 + Ethernet eth = ARP.buildArpReply(targetIpAddress,
132 + gatewayMacAddress,
133 + ethPkt);
134 +
135 + TrafficTreatment.Builder builder =
136 + DefaultTrafficTreatment.builder();
137 + builder.setOutput(srcConnectPoint.port());
138 + packetService.emit(new DefaultOutboundPacket(
139 + srcConnectPoint.deviceId(),
140 + builder.build(),
141 + ByteBuffer.wrap(eth.serialize())));
142 + }
143 + break;
144 + case Ethernet.TYPE_IPV4:
145 + // Parse packet
146 + IPv4 ipv4Packet = (IPv4) ethPkt.getPayload();
147 + IpAddress dstIp =
148 + IpAddress.valueOf(ipv4Packet.getDestinationAddress());
149 + IpAddress srcIp =
150 + IpAddress.valueOf(ipv4Packet.getSourceAddress());
151 + MacAddress srcMac = ethPkt.getSourceMAC();
152 + routingService.packetReactiveProcessor(dstIp, srcIp,
153 + srcConnectPoint, srcMac);
154 +
155 + // TODO emit packet first or packetReactiveProcessor first
156 + ConnectPoint egressConnectPoint = null;
157 + egressConnectPoint = routingService.getEgressConnectPoint(dstIp);
158 + if (egressConnectPoint != null) {
159 + forwardPacketToDst(context, egressConnectPoint);
160 + }
161 + break;
162 + default:
163 + break;
128 } 164 }
129 } 165 }
130 } 166 }
......
...@@ -20,6 +20,7 @@ import com.google.common.base.MoreObjects; ...@@ -20,6 +20,7 @@ import com.google.common.base.MoreObjects;
20 20
21 import java.util.Objects; 21 import java.util.Objects;
22 22
23 +import org.onlab.packet.IpAddress;
23 import org.onlab.packet.IpPrefix; 24 import org.onlab.packet.IpPrefix;
24 25
25 /** 26 /**
...@@ -28,6 +29,7 @@ import org.onlab.packet.IpPrefix; ...@@ -28,6 +29,7 @@ import org.onlab.packet.IpPrefix;
28 public class LocalIpPrefixEntry { 29 public class LocalIpPrefixEntry {
29 private final IpPrefix ipPrefix; 30 private final IpPrefix ipPrefix;
30 private final IpPrefixType type; 31 private final IpPrefixType type;
32 + private final IpAddress gatewayIpAddress;
31 33
32 /** 34 /**
33 * Specifies the type of local IP prefix. 35 * Specifies the type of local IP prefix.
...@@ -55,9 +57,12 @@ public class LocalIpPrefixEntry { ...@@ -55,9 +57,12 @@ public class LocalIpPrefixEntry {
55 * @param type an IP prefix type as an IpPrefixType 57 * @param type an IP prefix type as an IpPrefixType
56 */ 58 */
57 public LocalIpPrefixEntry(@JsonProperty("ipPrefix") String ipPrefix, 59 public LocalIpPrefixEntry(@JsonProperty("ipPrefix") String ipPrefix,
58 - @JsonProperty("type") IpPrefixType type) { 60 + @JsonProperty("type") IpPrefixType type,
61 + @JsonProperty("gatewayIp") IpAddress
62 + gatewayIpAddress) {
59 this.ipPrefix = IpPrefix.valueOf(ipPrefix); 63 this.ipPrefix = IpPrefix.valueOf(ipPrefix);
60 this.type = type; 64 this.type = type;
65 + this.gatewayIpAddress = gatewayIpAddress;
61 } 66 }
62 67
63 /** 68 /**
...@@ -79,6 +84,15 @@ public class LocalIpPrefixEntry { ...@@ -79,6 +84,15 @@ public class LocalIpPrefixEntry {
79 } 84 }
80 85
81 /** 86 /**
87 + * Gets the gateway IP address of the IP prefix entry.
88 + *
89 + * @return the gateway IP address
90 + */
91 + public IpAddress getGatewayIpAddress() {
92 + return gatewayIpAddress;
93 + }
94 +
95 + /**
82 * Tests whether the IP version of this entry is IPv4. 96 * Tests whether the IP version of this entry is IPv4.
83 * 97 *
84 * @return true if the IP version of this entry is IPv4, otherwise false. 98 * @return true if the IP version of this entry is IPv4, otherwise false.
......
...@@ -17,6 +17,7 @@ package org.onosproject.routing.config; ...@@ -17,6 +17,7 @@ package org.onosproject.routing.config;
17 17
18 import org.onlab.packet.IpAddress; 18 import org.onlab.packet.IpAddress;
19 import org.onlab.packet.IpPrefix; 19 import org.onlab.packet.IpPrefix;
20 +import org.onlab.packet.MacAddress;
20 import org.onosproject.net.ConnectPoint; 21 import org.onosproject.net.ConnectPoint;
21 22
22 import java.util.Map; 23 import java.util.Map;
...@@ -42,6 +43,21 @@ public interface RoutingConfigurationService { ...@@ -42,6 +43,21 @@ public interface RoutingConfigurationService {
42 public Map<IpAddress, BgpPeer> getBgpPeers(); 43 public Map<IpAddress, BgpPeer> getBgpPeers();
43 44
44 /** 45 /**
46 + * Gets the MAC address configured for virtual gateway in SDN network.
47 + *
48 + * @return the MAC address of virtual gateway
49 + */
50 + public MacAddress getVirtualGatewayMacAddress();
51 +
52 + /**
53 + * Evaluates whether an IP address is a virtual gateway IP address.
54 + *
55 + * @param ipAddress the IP address to evaluate
56 + * @return true if the IP address is a virtual gateway address, otherwise false
57 + */
58 + public boolean isVirtualGatewayIpAddress(IpAddress ipAddress);
59 +
60 + /**
45 * Evaluates whether an IP address belongs to local SDN network. 61 * Evaluates whether an IP address belongs to local SDN network.
46 * 62 *
47 * @param ipAddress the IP address to evaluate 63 * @param ipAddress the IP address to evaluate
......
...@@ -17,6 +17,7 @@ package org.onosproject.routing.config.impl; ...@@ -17,6 +17,7 @@ package org.onosproject.routing.config.impl;
17 17
18 import com.fasterxml.jackson.annotation.JsonProperty; 18 import com.fasterxml.jackson.annotation.JsonProperty;
19 19
20 +import org.onlab.packet.MacAddress;
20 import org.onosproject.routing.config.BgpPeer; 21 import org.onosproject.routing.config.BgpPeer;
21 import org.onosproject.routing.config.BgpSpeaker; 22 import org.onosproject.routing.config.BgpSpeaker;
22 import org.onosproject.routing.config.LocalIpPrefixEntry; 23 import org.onosproject.routing.config.LocalIpPrefixEntry;
...@@ -33,6 +34,7 @@ public class Configuration { ...@@ -33,6 +34,7 @@ public class Configuration {
33 // the BGP routers outside our SDN network the BGP peers. 34 // the BGP routers outside our SDN network the BGP peers.
34 private List<BgpSpeaker> bgpSpeakers; 35 private List<BgpSpeaker> bgpSpeakers;
35 private List<BgpPeer> peers; 36 private List<BgpPeer> peers;
37 + private MacAddress virtualGatewayMacAddress;
36 38
37 // All IP prefixes from the configuration are local 39 // All IP prefixes from the configuration are local
38 private List<LocalIpPrefixEntry> localIp4PrefixEntries = 40 private List<LocalIpPrefixEntry> localIp4PrefixEntries =
...@@ -77,7 +79,7 @@ public class Configuration { ...@@ -77,7 +79,7 @@ public class Configuration {
77 } 79 }
78 80
79 /** 81 /**
80 - * Sets a list of BGP peers we are configured to peer with. 82 + * Sets a list of BGP peers we configured to peer with.
81 * 83 *
82 * @param peers the list of BGP peers 84 * @param peers the list of BGP peers
83 */ 85 */
...@@ -87,6 +89,26 @@ public class Configuration { ...@@ -87,6 +89,26 @@ public class Configuration {
87 } 89 }
88 90
89 /** 91 /**
92 + * Gets the MAC address we configured for virtual gateway
93 + * in SDN network.
94 + *
95 + * @return the MAC address of virtual gateway
96 + */
97 + public MacAddress getVirtualGatewayMacAddress() {
98 + return virtualGatewayMacAddress;
99 + }
100 +
101 + /**
102 + * Sets the MAC address for virtual gateway in SDN network.
103 + *
104 + * @param virtualGatewayMacAddress the MAC address of virtual gateway
105 + */
106 + @JsonProperty("virtualGatewayMacAddress")
107 + public void setVirtualGatewayMacAddress(MacAddress virtualGatewayMacAddress) {
108 + this.virtualGatewayMacAddress = virtualGatewayMacAddress;
109 + }
110 +
111 + /**
90 * Gets a list of local IPv4 prefix entries configured for local 112 * Gets a list of local IPv4 prefix entries configured for local
91 * SDN network. 113 * SDN network.
92 * <p> 114 * <p>
......
...@@ -29,6 +29,7 @@ import org.onlab.packet.Ip4Address; ...@@ -29,6 +29,7 @@ import org.onlab.packet.Ip4Address;
29 import org.onlab.packet.Ip6Address; 29 import org.onlab.packet.Ip6Address;
30 import org.onlab.packet.IpAddress; 30 import org.onlab.packet.IpAddress;
31 import org.onlab.packet.IpPrefix; 31 import org.onlab.packet.IpPrefix;
32 +import org.onlab.packet.MacAddress;
32 import org.onosproject.net.ConnectPoint; 33 import org.onosproject.net.ConnectPoint;
33 import org.onosproject.net.host.HostService; 34 import org.onosproject.net.host.HostService;
34 import org.onosproject.routing.config.BgpPeer; 35 import org.onosproject.routing.config.BgpPeer;
...@@ -43,6 +44,7 @@ import java.io.File; ...@@ -43,6 +44,7 @@ import java.io.File;
43 import java.io.FileNotFoundException; 44 import java.io.FileNotFoundException;
44 import java.io.IOException; 45 import java.io.IOException;
45 import java.util.Collections; 46 import java.util.Collections;
47 +import java.util.HashSet;
46 import java.util.Map; 48 import java.util.Map;
47 import java.util.Set; 49 import java.util.Set;
48 import java.util.concurrent.ConcurrentHashMap; 50 import java.util.concurrent.ConcurrentHashMap;
...@@ -68,6 +70,7 @@ public class RoutingConfigurationImpl implements RoutingConfigurationService { ...@@ -68,6 +70,7 @@ public class RoutingConfigurationImpl implements RoutingConfigurationService {
68 70
69 private Map<String, BgpSpeaker> bgpSpeakers = new ConcurrentHashMap<>(); 71 private Map<String, BgpSpeaker> bgpSpeakers = new ConcurrentHashMap<>();
70 private Map<IpAddress, BgpPeer> bgpPeers = new ConcurrentHashMap<>(); 72 private Map<IpAddress, BgpPeer> bgpPeers = new ConcurrentHashMap<>();
73 + private Set<IpAddress> gatewayIpAddresses = new HashSet<>();
71 74
72 private InvertedRadixTree<LocalIpPrefixEntry> 75 private InvertedRadixTree<LocalIpPrefixEntry>
73 localPrefixTable4 = new ConcurrentInvertedRadixTree<>( 76 localPrefixTable4 = new ConcurrentInvertedRadixTree<>(
...@@ -76,6 +79,7 @@ public class RoutingConfigurationImpl implements RoutingConfigurationService { ...@@ -76,6 +79,7 @@ public class RoutingConfigurationImpl implements RoutingConfigurationService {
76 localPrefixTable6 = new ConcurrentInvertedRadixTree<>( 79 localPrefixTable6 = new ConcurrentInvertedRadixTree<>(
77 new DefaultByteArrayNodeFactory()); 80 new DefaultByteArrayNodeFactory());
78 81
82 + private MacAddress virtualGatewayMacAddress;
79 private HostToInterfaceAdaptor hostAdaptor; 83 private HostToInterfaceAdaptor hostAdaptor;
80 84
81 @Activate 85 @Activate
...@@ -109,12 +113,16 @@ public class RoutingConfigurationImpl implements RoutingConfigurationService { ...@@ -109,12 +113,16 @@ public class RoutingConfigurationImpl implements RoutingConfigurationService {
109 for (LocalIpPrefixEntry entry : config.getLocalIp4PrefixEntries()) { 113 for (LocalIpPrefixEntry entry : config.getLocalIp4PrefixEntries()) {
110 localPrefixTable4.put(createBinaryString(entry.ipPrefix()), 114 localPrefixTable4.put(createBinaryString(entry.ipPrefix()),
111 entry); 115 entry);
116 + gatewayIpAddresses.add(entry.getGatewayIpAddress());
112 } 117 }
113 for (LocalIpPrefixEntry entry : config.getLocalIp6PrefixEntries()) { 118 for (LocalIpPrefixEntry entry : config.getLocalIp6PrefixEntries()) {
114 localPrefixTable6.put(createBinaryString(entry.ipPrefix()), 119 localPrefixTable6.put(createBinaryString(entry.ipPrefix()),
115 entry); 120 entry);
121 + gatewayIpAddresses.add(entry.getGatewayIpAddress());
116 } 122 }
117 123
124 + virtualGatewayMacAddress = config.getVirtualGatewayMacAddress();
125 +
118 } catch (FileNotFoundException e) { 126 } catch (FileNotFoundException e) {
119 log.warn("Configuration file not found: {}", configFileName); 127 log.warn("Configuration file not found: {}", configFileName);
120 } catch (IOException e) { 128 } catch (IOException e) {
...@@ -178,4 +186,14 @@ public class RoutingConfigurationImpl implements RoutingConfigurationService { ...@@ -178,4 +186,14 @@ public class RoutingConfigurationImpl implements RoutingConfigurationService {
178 createBinaryString(ipPrefix)) != null); 186 createBinaryString(ipPrefix)) != null);
179 } 187 }
180 188
189 + @Override
190 + public boolean isVirtualGatewayIpAddress(IpAddress ipAddress) {
191 + return gatewayIpAddresses.contains(ipAddress);
192 + }
193 +
194 + @Override
195 + public MacAddress getVirtualGatewayMacAddress() {
196 + return virtualGatewayMacAddress;
197 + }
198 +
181 } 199 }
......
...@@ -66,17 +66,21 @@ ...@@ -66,17 +66,21 @@
66 "ip4LocalPrefixes" : [ 66 "ip4LocalPrefixes" : [
67 { 67 {
68 "ipPrefix" : "100.0.0.0/24", 68 "ipPrefix" : "100.0.0.0/24",
69 - "type" : "PUBLIC" 69 + "type" : "PUBLIC",
70 + "gatewayIp" : "100.0.0.1"
70 }, 71 },
71 { 72 {
72 "ipPrefix" : "200.0.0.0/8", 73 "ipPrefix" : "200.0.0.0/8",
73 - "type" : "PUBLIC" 74 + "type" : "PUBLIC",
75 + "gatewayIp" : "200.0.0.3"
74 }, 76 },
75 { 77 {
76 "ipPrefix" : "192.0.0.0/24", 78 "ipPrefix" : "192.0.0.0/24",
77 - "type" : "PRIVATE" 79 + "type" : "PRIVATE",
80 + "gatewayIp" : "192.0.0.254"
78 } 81 }
79 ], 82 ],
80 "ip6LocalPrefixes" : [ 83 "ip6LocalPrefixes" : [
81 - ] 84 + ],
85 + "virtualGatewayMacAddress" : "00:00:00:00:00:01"
82 } 86 }
......
...@@ -61,5 +61,4 @@ public interface ProxyArpService { ...@@ -61,5 +61,4 @@ public interface ProxyArpService {
61 * @return true if handled, false otherwise. 61 * @return true if handled, false otherwise.
62 */ 62 */
63 boolean handlePacket(PacketContext context); 63 boolean handlePacket(PacketContext context);
64 -
65 } 64 }
......
...@@ -156,7 +156,7 @@ public class ProxyArpManager implements ProxyArpService { ...@@ -156,7 +156,7 @@ public class ProxyArpManager implements ProxyArpService {
156 for (InterfaceIpAddress ia : addresses.ipAddresses()) { 156 for (InterfaceIpAddress ia : addresses.ipAddresses()) {
157 if (ia.ipAddress().equals(targetAddress)) { 157 if (ia.ipAddress().equals(targetAddress)) {
158 Ethernet arpReply = 158 Ethernet arpReply =
159 - buildArpReply(targetAddress, addresses.mac(), eth); 159 + ARP.buildArpReply(targetAddress, addresses.mac(), eth);
160 sendTo(arpReply, inPort); 160 sendTo(arpReply, inPort);
161 } 161 }
162 } 162 }
...@@ -181,7 +181,7 @@ public class ProxyArpManager implements ProxyArpService { ...@@ -181,7 +181,7 @@ public class ProxyArpManager implements ProxyArpService {
181 181
182 if (src != null && dst != null) { 182 if (src != null && dst != null) {
183 // We know the target host so we can respond 183 // We know the target host so we can respond
184 - Ethernet arpReply = buildArpReply(targetAddress, dst.mac(), eth); 184 + Ethernet arpReply = ARP.buildArpReply(targetAddress, dst.mac(), eth);
185 sendTo(arpReply, inPort); 185 sendTo(arpReply, inPort);
186 return; 186 return;
187 } 187 }
...@@ -296,7 +296,6 @@ public class ProxyArpManager implements ProxyArpService { ...@@ -296,7 +296,6 @@ public class ProxyArpManager implements ProxyArpService {
296 sendTo(ndpReply, inPort); 296 sendTo(ndpReply, inPort);
297 } 297 }
298 298
299 -
300 /** 299 /**
301 * Outputs the given packet out the given port. 300 * Outputs the given packet out the given port.
302 * 301 *
...@@ -482,41 +481,6 @@ public class ProxyArpManager implements ProxyArpService { ...@@ -482,41 +481,6 @@ public class ProxyArpManager implements ProxyArpService {
482 } 481 }
483 482
484 /** 483 /**
485 - * Builds an ARP reply based on a request.
486 - *
487 - * @param srcIp the IP address to use as the reply source
488 - * @param srcMac the MAC address to use as the reply source
489 - * @param request the ARP request we got
490 - * @return an Ethernet frame containing the ARP reply
491 - */
492 - private Ethernet buildArpReply(Ip4Address srcIp, MacAddress srcMac,
493 - Ethernet request) {
494 -
495 - Ethernet eth = new Ethernet();
496 - eth.setDestinationMACAddress(request.getSourceMAC());
497 - eth.setSourceMACAddress(srcMac);
498 - eth.setEtherType(Ethernet.TYPE_ARP);
499 - eth.setVlanID(request.getVlanID());
500 -
501 - ARP arp = new ARP();
502 - arp.setOpCode(ARP.OP_REPLY);
503 - arp.setProtocolType(ARP.PROTO_TYPE_IP);
504 - arp.setHardwareType(ARP.HW_TYPE_ETHERNET);
505 -
506 - arp.setProtocolAddressLength((byte) Ip4Address.BYTE_LENGTH);
507 - arp.setHardwareAddressLength((byte) Ethernet.DATALAYER_ADDRESS_LENGTH);
508 - arp.setSenderHardwareAddress(srcMac.toBytes());
509 - arp.setTargetHardwareAddress(request.getSourceMACAddress());
510 -
511 - arp.setTargetProtocolAddress(((ARP) request.getPayload())
512 - .getSenderProtocolAddress());
513 - arp.setSenderProtocolAddress(srcIp.toInt());
514 -
515 - eth.setPayload(arp);
516 - return eth;
517 - }
518 -
519 - /**
520 * Builds an Neighbor Discovery reply based on a request. 484 * Builds an Neighbor Discovery reply based on a request.
521 * 485 *
522 * @param srcIp the IP address to use as the reply source 486 * @param srcIp the IP address to use as the reply source
......
...@@ -357,4 +357,39 @@ public class ARP extends BasePacket { ...@@ -357,4 +357,39 @@ public class ARP extends BasePacket {
357 + ", targetProtocolAddress=" 357 + ", targetProtocolAddress="
358 + Arrays.toString(this.targetProtocolAddress) + "]"; 358 + Arrays.toString(this.targetProtocolAddress) + "]";
359 } 359 }
360 +
361 + /**
362 + * Builds an ARP reply based on a request.
363 + *
364 + * @param srcIp the IP address to use as the reply source
365 + * @param srcMac the MAC address to use as the reply source
366 + * @param request the ARP request we got
367 + * @return an Ethernet frame containing the ARP reply
368 + */
369 + public static Ethernet buildArpReply(Ip4Address srcIp, MacAddress srcMac,
370 + Ethernet request) {
371 +
372 + Ethernet eth = new Ethernet();
373 + eth.setDestinationMACAddress(request.getSourceMAC());
374 + eth.setSourceMACAddress(srcMac);
375 + eth.setEtherType(Ethernet.TYPE_ARP);
376 + eth.setVlanID(request.getVlanID());
377 +
378 + ARP arp = new ARP();
379 + arp.setOpCode(ARP.OP_REPLY);
380 + arp.setProtocolType(ARP.PROTO_TYPE_IP);
381 + arp.setHardwareType(ARP.HW_TYPE_ETHERNET);
382 +
383 + arp.setProtocolAddressLength((byte) Ip4Address.BYTE_LENGTH);
384 + arp.setHardwareAddressLength((byte) Ethernet.DATALAYER_ADDRESS_LENGTH);
385 + arp.setSenderHardwareAddress(srcMac.toBytes());
386 + arp.setTargetHardwareAddress(request.getSourceMACAddress());
387 +
388 + arp.setTargetProtocolAddress(((ARP) request.getPayload())
389 + .getSenderProtocolAddress());
390 + arp.setSenderProtocolAddress(srcIp.toInt());
391 +
392 + eth.setPayload(arp);
393 + return eth;
394 + }
360 } 395 }
......