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()); }
private OpenstackRouter openstackRouter(String routerId) { return openstackService .routers() .stream() .filter(r -> r.id().equals(routerId)) .iterator() .next(); }
@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()); }
private Optional<OpenstackPort> routerIfacePort(String osNetId) { // FIXME router interface is subnet specific, not network return openstackService .ports() .stream() .filter( p -> p.deviceOwner().equals(DEVICE_OWNER_ROUTER_INTERFACE) && p.networkId().equals(osNetId)) .findAny(); }
private void unsetExternalConnection( OpenstackRouter osRouter, String osNetId, String subNetCidr) { if (!osRouter.gatewayExternalInfo().isEnablePnat()) { log.debug("Source NAT is disabled"); return; } // FIXME router interface is subnet specific, not network OpenstackNetwork osNet = openstackService.network(osNetId); removeExternalRules(osNet, subNetCidr); }
@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 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); } })); }
private void populateRoutingRules(Host host, Set<OpenstackSubnet> osSubNets) { String osSubNetId = host.annotations().value(SUBNET_ID); if (osSubNetId == null) { return; } DeviceId localDevice = host.location().deviceId(); PortNumber localPort = host.location().port(); if (!nodeService.dataIp(localDevice).isPresent()) { log.warn("Failed to populate L3 rules"); return; } Map<String, String> vniMap = new HashMap<>(); openstackService.networks().stream().forEach(n -> vniMap.put(n.id(), n.segmentId())); // TODO improve pipeline, do we have to install access rules between networks // for every single VMs? osSubNets .stream() .filter(osSubNet -> !osSubNet.id().equals(osSubNetId)) .forEach( osSubNet -> { populateRoutingRulestoSameNode( host.ipAddresses().stream().findFirst().get().getIp4Address(), host.mac(), localPort, localDevice, Long.valueOf(vniMap.get(osSubNet.networkId())), osSubNet.cidr()); nodeService .completeNodes() .stream() .filter(node -> node.type().equals(COMPUTE)) .filter(node -> !node.intBridge().equals(localDevice)) .forEach( node -> populateRoutingRulestoDifferentNode( host.ipAddresses().stream().findFirst().get().getIp4Address(), Long.valueOf(vniMap.get(osSubNet.networkId())), node.intBridge(), nodeService.dataIp(localDevice).get().getIp4Address(), osSubNet.cidr())); }); }
private void removeRoutingRules(Host host, Set<OpenstackSubnet> osSubNets) { String osSubNetId = host.annotations().value(SUBNET_ID); if (osSubNetId == null) { return; } Map<String, String> vniMap = new HashMap<>(); openstackService.networks().stream().forEach(n -> vniMap.put(n.id(), n.segmentId())); osSubNets .stream() .filter(osSubNet -> !osSubNet.id().equals(osSubNetId)) .forEach( osSubNet -> { TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder(); sBuilder .matchEthType(Ethernet.TYPE_IPV4) .matchIPDst(host.ipAddresses().stream().findFirst().get().toIpPrefix()) .matchIPSrc(IpPrefix.valueOf(osSubNet.cidr())) .matchTunnelId(Long.valueOf(vniMap.get(osSubNet.networkId()))); nodeService .completeNodes() .stream() .filter(node -> node.type().equals(COMPUTE)) .forEach( node -> RulePopulatorUtil.removeRule( flowObjectiveService, appId, node.intBridge(), sBuilder.build(), ForwardingObjective.Flag.SPECIFIC, EW_ROUTING_RULE_PRIORITY)); }); log.debug("Removed routing rule from {} to {}", host, osSubNets); }