private void setExternalConnection(OpenstackRouter osRouter, String osSubNetId) {
    if (!osRouter.gatewayExternalInfo().isEnablePnat()) {
      log.debug("Source NAT is disabled");
      return;
    }

    OpenstackSubnet osSubNet = openstackService.subnet(osSubNetId);
    OpenstackNetwork osNet = openstackService.network(osSubNet.networkId());
    populateExternalRules(osNet, osSubNet);
  }
  private void unsetRoutes(OpenstackRouter osRouter, OpenstackSubnet osSubNet) {
    Set<OpenstackSubnet> routableSubNets = routableSubNets(osRouter.id());
    Tools.stream(hostService.getHosts())
        .filter(h -> Objects.equals(h.annotations().value(NETWORK_ID), osSubNet.id()))
        .forEach(h -> removeRoutingRules(h, routableSubNets));

    routableSubNets.forEach(
        n -> {
          Tools.stream(hostService.getHosts())
              .filter(h -> Objects.equals(h.annotations().value(SUBNET_ID), n.id()))
              .forEach(h -> removeRoutingRules(h, ImmutableSet.of(osSubNet)));
          log.debug("Removed between {} to {}", n.name(), osSubNet.name());
        });
  }
  @Override
  public void removeRouterInterface(OpenstackRouterInterface routerIface) {
    OpenstackRouter osRouter = openstackService.router(routerIface.id());
    if (osRouter == null) {
      log.warn("Failed to remove router interface {}", routerIface);
      return;
    }

    OpenstackSubnet osSubnet = openstackService.subnet(routerIface.subnetId());
    OpenstackNetwork osNet = openstackService.network(osSubnet.networkId());

    unsetGatewayIcmp(
        Ip4Address.valueOf(openstackService.subnet(routerIface.subnetId()).gatewayIp()));

    unsetRoutes(osRouter, osSubnet);

    if (osRouter.gatewayExternalInfo().externalFixedIps().size() > 0) {
      unsetExternalConnection(osRouter, osNet.id(), osSubnet.cidr());
    }
    log.info("Disconnected {} from router {}", osSubnet.cidr(), osRouter.name());
  }
  @Override
  public void updateRouter(OpenstackRouter osRouter) {
    if (osRouter.gatewayExternalInfo().externalFixedIps().size() > 0) {
      openstackService
          .ports()
          .stream()
          .filter(
              osPort ->
                  osPort.deviceOwner().equals(DEVICE_OWNER_ROUTER_INTERFACE)
                      && osPort.deviceId().equals(osRouter.id()))
          .forEach(
              osPort -> {
                String subnetId = osPort.fixedIps().keySet().stream().findFirst().get();
                setExternalConnection(osRouter, subnetId);
              });

      log.info(
          "Connected external gateway {} to router {}",
          osRouter.gatewayExternalInfo().externalFixedIps(),
          osRouter.name());
    } else {
      openstackService
          .ports()
          .stream()
          .filter(
              osPort ->
                  osPort.deviceOwner().equals(DEVICE_OWNER_ROUTER_INTERFACE)
                      && osPort.deviceId().equals(osRouter.id()))
          .forEach(
              osPort -> {
                String subnetId = osPort.fixedIps().keySet().stream().findFirst().get();
                OpenstackSubnet osSubNet = openstackService.subnet(subnetId);
                unsetExternalConnection(osRouter, osPort.networkId(), osSubNet.cidr());
              });

      log.info("Disconnected external gateway from router {}", osRouter.name());
    }
  }
 private void populateExternalRules(OpenstackNetwork osNet, OpenstackSubnet osSubNet) {
   populateCnodeToGateway(Long.valueOf(osNet.segmentId()), osSubNet.cidr());
   populateGatewayToController(Long.valueOf(osNet.segmentId()), osSubNet.cidr());
 }