Fix gateway ip address in OpenstackSwitchingDhcpHandler
Change-Id: I87db9b6159844d4e02a01a483e0a083af6ea77c1
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingDhcpHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingDhcpHandler.java
index 3602275..bfbd716 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingDhcpHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingDhcpHandler.java
@@ -35,6 +35,9 @@
import org.onlab.packet.dhcp.DhcpOption;
import org.onlab.util.Tools;
import org.onosproject.cfg.ComponentConfigService;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.LeadershipService;
+import org.onosproject.cluster.NodeId;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.net.ConnectPoint;
@@ -51,6 +54,9 @@
import org.onosproject.openstacknetworking.api.InstancePortService;
import org.onosproject.openstacknetworking.api.OpenstackFlowRuleService;
import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
+import org.onosproject.openstacknode.api.OpenstackNode;
+import org.onosproject.openstacknode.api.OpenstackNodeEvent;
+import org.onosproject.openstacknode.api.OpenstackNodeListener;
import org.onosproject.openstacknode.api.OpenstackNodeService;
import org.openstack4j.model.network.IP;
import org.openstack4j.model.network.Port;
@@ -61,6 +67,7 @@
import java.nio.ByteBuffer;
import java.util.Dictionary;
import java.util.List;
+import java.util.Objects;
import static org.onlab.packet.DHCP.DHCPOptionCode.OptionCode_BroadcastAddress;
import static org.onlab.packet.DHCP.DHCPOptionCode.OptionCode_DHCPServerIp;
@@ -75,7 +82,7 @@
import static org.onosproject.openstacknetworking.api.Constants.DEFAULT_GATEWAY_MAC_STR;
import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_DHCP_RULE;
import static org.onosproject.openstacknetworking.api.Constants.SRC_VNI_TABLE;
-import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.COMPUTE;
+import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.GATEWAY;
import static org.slf4j.LoggerFactory.getLogger;
/**
@@ -117,6 +124,12 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected OpenstackFlowRuleService osFlowRuleService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected ClusterService clusterService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected LeadershipService leadershipService;
+
@Property(name = DHCP_SERVER_MAC, value = DEFAULT_GATEWAY_MAC_STR,
label = "Fake MAC address for virtual network subnet gateway")
private String dhcpServerMac = DEFAULT_GATEWAY_MAC_STR;
@@ -126,24 +139,29 @@
private int dhcpDataMtu = DHCP_DATA_MTU_DEFAULT;
private final PacketProcessor packetProcessor = new InternalPacketProcessor();
+ private final OpenstackNodeListener osNodeListener = new InternalNodeEventListener();
private ApplicationId appId;
+ private NodeId localNodeId;
@Activate
protected void activate() {
appId = coreService.registerApplication(Constants.OPENSTACK_NETWORKING_APP_ID);
+ localNodeId = clusterService.getLocalNode().id();
+ osNodeService.addListener(osNodeListener);
configService.registerProperties(getClass());
packetService.addProcessor(packetProcessor, PacketProcessor.director(0));
- setDhcpRule(true);
+ leadershipService.runForLeadership(appId.name());
log.info("Started");
}
@Deactivate
protected void deactivate() {
- setDhcpRule(false);
packetService.removeProcessor(packetProcessor);
+ osNodeService.removeListener(osNodeListener);
configService.unregisterProperties(getClass(), false);
+ leadershipService.withdraw(appId.name());
log.info("Stopped");
}
@@ -168,30 +186,6 @@
log.info("Modified");
}
- private void setDhcpRule(boolean install) {
- TrafficSelector selector = DefaultTrafficSelector.builder()
- .matchEthType(Ethernet.TYPE_IPV4)
- .matchIPProtocol(IPv4.PROTOCOL_UDP)
- .matchUdpDst(TpPort.tpPort(UDP.DHCP_SERVER_PORT))
- .matchUdpSrc(TpPort.tpPort(UDP.DHCP_CLIENT_PORT))
- .build();
-
- TrafficTreatment treatment = DefaultTrafficTreatment.builder()
- .punt()
- .build();
-
- osNodeService.completeNodes(COMPUTE).forEach(node -> {
- osFlowRuleService.setRule(
- appId,
- node.intgBridge(),
- selector,
- treatment,
- PRIORITY_DHCP_RULE,
- SRC_VNI_TABLE,
- install);
- });
- }
-
private class InternalPacketProcessor implements PacketProcessor {
@Override
@@ -246,7 +240,7 @@
reqInstPort);
sendReply(context, discoverReply);
log.trace("DHCP OFFER({}) is sent for {}",
- reqInstPort.ipAddress(), clientMac);
+ reqInstPort.ipAddress(), clientMac);
break;
case DHCPREQUEST:
log.trace("DHCP REQUEST received from {}", clientMac);
@@ -256,7 +250,7 @@
reqInstPort);
sendReply(context, requestReply);
log.trace("DHCP ACK({}) is sent for {}",
- reqInstPort.ipAddress(), clientMac);
+ reqInstPort.ipAddress(), clientMac);
break;
case DHCPRELEASE:
log.trace("DHCP RELEASE received from {}", clientMac);
@@ -295,7 +289,8 @@
IPv4 ipv4Request = (IPv4) ethRequest.getPayload();
IPv4 ipv4Reply = new IPv4();
- ipv4Reply.setSourceAddress(Ip4Address.valueOf(osSubnet.getGateway()).toInt());
+
+ ipv4Reply.setSourceAddress(clusterService.getLocalNode().ip().getIp4Address().toString());
ipv4Reply.setDestinationAddress(reqInstPort.ipAddress().getIp4Address().toInt());
ipv4Reply.setTtl(PACKET_TTL);
@@ -337,7 +332,7 @@
private DHCP buildDhcpReply(DHCP request, byte msgType, Ip4Address yourIp,
Subnet osSubnet) {
- Ip4Address gatewayIp = Ip4Address.valueOf(osSubnet.getGateway());
+ Ip4Address gatewayIp = clusterService.getLocalNode().ip().getIp4Address();
int subnetPrefixLen = IpPrefix.valueOf(osSubnet.getCidr()).prefixLength();
DHCP dhcpReply = new DHCP();
@@ -419,4 +414,56 @@
return dhcpReply;
}
}
+
+ private class InternalNodeEventListener implements OpenstackNodeListener {
+ @Override
+ public boolean isRelevant(OpenstackNodeEvent event) {
+ // do not allow to proceed without leadership
+ NodeId leader = leadershipService.getLeader(appId.name());
+ return Objects.equals(localNodeId, leader);
+ }
+
+ @Override
+ public void event(OpenstackNodeEvent event) {
+ OpenstackNode osNode = event.subject();
+ switch (event.type()) {
+ case OPENSTACK_NODE_COMPLETE:
+ setDhcpRule(osNode, true);
+ break;
+ case OPENSTACK_NODE_INCOMPLETE:
+ setDhcpRule(osNode, false);
+ break;
+ case OPENSTACK_NODE_CREATED:
+ case OPENSTACK_NODE_UPDATED:
+ case OPENSTACK_NODE_REMOVED:
+ default:
+ break;
+ }
+ }
+
+ private void setDhcpRule(OpenstackNode openstackNode, boolean install) {
+ if (openstackNode.type().equals(GATEWAY)) {
+ return;
+ }
+ TrafficSelector selector = DefaultTrafficSelector.builder()
+ .matchEthType(Ethernet.TYPE_IPV4)
+ .matchIPProtocol(IPv4.PROTOCOL_UDP)
+ .matchUdpDst(TpPort.tpPort(UDP.DHCP_SERVER_PORT))
+ .matchUdpSrc(TpPort.tpPort(UDP.DHCP_CLIENT_PORT))
+ .build();
+
+ TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+ .punt()
+ .build();
+
+ osFlowRuleService.setRule(
+ appId,
+ openstackNode.intgBridge(),
+ selector,
+ treatment,
+ PRIORITY_DHCP_RULE,
+ SRC_VNI_TABLE,
+ install);
+ }
+ }
}