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 Set<OpenstackSubnet> routableSubNets(String osRouterId) {
   return openstackService
       .ports()
       .stream()
       .filter(
           p ->
               p.deviceOwner().equals(DEVICE_OWNER_ROUTER_INTERFACE)
                   && p.deviceId().equals(osRouterId))
       .map(p -> openstackService.subnet(p.fixedIps().keySet().stream().findFirst().get()))
       .collect(Collectors.toSet());
 }
  @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 addRouterInterface(OpenstackRouterInterface routerIface) {
    OpenstackRouter osRouter = openstackRouter(routerIface.id());
    OpenstackPort osPort = openstackService.port(routerIface.portId());
    if (osRouter == null || osPort == null) {
      log.warn("Failed to add router interface {}", routerIface);
      return;
    }

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

    setRoutes(osRouter, Optional.empty());
    if (osRouter.gatewayExternalInfo().externalFixedIps().size() > 0) {
      String subnetId = osPort.fixedIps().keySet().stream().findFirst().get();
      setExternalConnection(osRouter, subnetId);
    }
    log.info("Connected {} to router {}", osPort.fixedIps(), 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 reloadRoutingRules() {
    eventExecutor.execute(
        () ->
            openstackService
                .ports()
                .stream()
                .filter(osPort -> osPort.deviceOwner().equals(DEVICE_OWNER_ROUTER_INTERFACE))
                .forEach(
                    osPort -> {
                      OpenstackRouter osRouter = openstackRouter(osPort.deviceId());

                      setGatewayIcmp(
                          Ip4Address.valueOf(
                              openstackService
                                  .subnet(osPort.fixedIps().keySet().stream().findAny().get())
                                  .gatewayIp()));

                      setRoutes(osRouter, Optional.empty());
                      if (osRouter.gatewayExternalInfo().externalFixedIps().size() > 0) {
                        String subnetId = osPort.fixedIps().keySet().stream().findFirst().get();
                        setExternalConnection(osRouter, subnetId);
                      }
                    }));
  }