/**
   * Constructs a BGP intent and put it into the intentList.
   *
   * <p>The purpose of this method is too simplify the setUpBgpIntents() method, and to make the
   * setUpBgpIntents() easy to read.
   *
   * @param srcVlanId ingress VlanId
   * @param dstVlanId egress VlanId
   * @param srcPrefix source IP prefix to match
   * @param dstPrefix destination IP prefix to match
   * @param srcTcpPort source TCP port to match
   * @param dstTcpPort destination TCP port to match
   * @param srcConnectPoint source connect point for PointToPointIntent
   * @param dstConnectPoint destination connect point for PointToPointIntent
   */
  private void bgpPathintentConstructor(
      VlanId srcVlanId,
      VlanId dstVlanId,
      String srcPrefix,
      String dstPrefix,
      Short srcTcpPort,
      Short dstTcpPort,
      ConnectPoint srcConnectPoint,
      ConnectPoint dstConnectPoint) {

    TrafficSelector.Builder builder =
        DefaultTrafficSelector.builder()
            .matchEthType(Ethernet.TYPE_IPV4)
            .matchIPProtocol(IPv4.PROTOCOL_TCP)
            .matchIPSrc(IpPrefix.valueOf(srcPrefix))
            .matchIPDst(IpPrefix.valueOf(dstPrefix));

    if (!srcVlanId.equals(VlanId.NONE)) {
      builder.matchVlanId(srcVlanId);
    }

    TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();

    if (!dstVlanId.equals(VlanId.NONE)) {
      treatment.setVlanId(dstVlanId);
    }

    if (srcTcpPort != null) {
      builder.matchTcpSrc(TpPort.tpPort(srcTcpPort));
    }
    if (dstTcpPort != null) {
      builder.matchTcpDst(TpPort.tpPort(dstTcpPort));
    }

    Key key =
        Key.of(
            srcPrefix.split("/")[0]
                + "-"
                + dstPrefix.split("/")[0]
                + "-"
                + ((srcTcpPort == null) ? "dst" : "src"),
            APPID);

    PointToPointIntent intent =
        PointToPointIntent.builder()
            .appId(APPID)
            .key(key)
            .selector(builder.build())
            .treatment(treatment.build())
            .ingressPoint(srcConnectPoint)
            .egressPoint(dstConnectPoint)
            .build();

    intentList.add(intent);
  }
예제 #2
0
 @Override
 protected void execute() {
   SubnetService service = get(SubnetService.class);
   if (id == null || networkId == null || tenantId == null) {
     print(null, "id,networkId,tenantId can not be null");
     return;
   }
   Subnet subnet =
       new DefaultSubnet(
           SubnetId.subnetId(id),
           subnetName,
           TenantNetworkId.networkId(networkId),
           TenantId.tenantId(tenantId),
           ipVersion,
           cidr == null ? null : IpPrefix.valueOf(cidr),
           gatewayIp == null ? null : IpAddress.valueOf(gatewayIp),
           dhcpEnabled,
           shared,
           hostRoutes,
           ipV6AddressMode == null ? null : Mode.valueOf(ipV6AddressMode),
           ipV6RaMode == null ? null : Mode.valueOf(ipV6RaMode),
           allocationPools);
   Set<Subnet> subnetsSet = Sets.newHashSet();
   subnetsSet.add(subnet);
   service.updateSubnets(subnetsSet);
 }
예제 #3
0
  private void populateRoutingRulestoSameNode(
      Ip4Address vmIp,
      MacAddress vmMac,
      PortNumber port,
      DeviceId deviceId,
      long vni,
      String cidr) {
    TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
    TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();

    // FIXME: we need to check the VNI of the dest IP also just in case...
    sBuilder
        .matchEthType(Ethernet.TYPE_IPV4)
        .matchIPDst(vmIp.toIpPrefix())
        .matchIPSrc(IpPrefix.valueOf(cidr))
        .matchTunnelId(vni);

    tBuilder.setEthDst(vmMac).setOutput(port);

    ForwardingObjective fo =
        DefaultForwardingObjective.builder()
            .withSelector(sBuilder.build())
            .withTreatment(tBuilder.build())
            .withPriority(EW_ROUTING_RULE_PRIORITY)
            .withFlag(ForwardingObjective.Flag.SPECIFIC)
            .fromApp(appId)
            .add();

    flowObjectiveService.forward(deviceId, fo);
  }
예제 #4
0
  private void populateRoutingRulestoDifferentNode(
      Ip4Address vmIp, long vni, DeviceId deviceId, Ip4Address hostIp, String cidr) {
    TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
    TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();

    sBuilder
        .matchEthType(Ethernet.TYPE_IPV4)
        .matchTunnelId(vni)
        .matchIPSrc(IpPrefix.valueOf(cidr))
        .matchIPDst(vmIp.toIpPrefix());
    tBuilder
        .extension(buildExtension(deviceService, deviceId, hostIp), deviceId)
        .setOutput(nodeService.tunnelPort(deviceId).get());

    ForwardingObjective fo =
        DefaultForwardingObjective.builder()
            .withSelector(sBuilder.build())
            .withTreatment(tBuilder.build())
            .withPriority(EW_ROUTING_RULE_PRIORITY)
            .withFlag(ForwardingObjective.Flag.SPECIFIC)
            .fromApp(appId)
            .add();

    flowObjectiveService.forward(deviceId, fo);
  }
예제 #5
0
  private void removeExternalRules(OpenstackNetwork osNet, String subNetCidr) {
    TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
    sBuilder
        .matchEthType(Ethernet.TYPE_IPV4)
        .matchTunnelId(Long.valueOf(osNet.segmentId()))
        .matchIPSrc(IpPrefix.valueOf(subNetCidr))
        .matchEthDst(Constants.DEFAULT_GATEWAY_MAC);

    nodeService
        .completeNodes()
        .forEach(
            node -> {
              ForwardingObjective.Flag flag =
                  node.type().equals(GATEWAY)
                      ? ForwardingObjective.Flag.VERSATILE
                      : ForwardingObjective.Flag.SPECIFIC;

              RulePopulatorUtil.removeRule(
                  flowObjectiveService,
                  appId,
                  node.intBridge(),
                  sBuilder.build(),
                  flag,
                  ROUTING_RULE_PRIORITY);
            });
  }
 @Override
 public Criterion decodeCriterion(ObjectNode json) {
   String ip =
       nullIsIllegal(json.get(CriterionCodec.IP), CriterionCodec.IP + MISSING_MEMBER_MESSAGE)
           .asText();
   return Criteria.matchIPv6Dst(IpPrefix.valueOf(ip));
 }
예제 #7
0
  /**
   * Process incoming ICMP packet. If it is an ICMP request to router or known host, then sends an
   * ICMP response. If it is an ICMP packet to known host and forward the packet to the host. If it
   * is an ICMP packet to unknown host in a subnet, then sends an ARP request to the subnet.
   *
   * @param pkt inbound packet
   */
  public void processPacketIn(InboundPacket pkt) {

    Ethernet ethernet = pkt.parsed();
    IPv4 ipv4 = (IPv4) ethernet.getPayload();

    ConnectPoint connectPoint = pkt.receivedFrom();
    DeviceId deviceId = connectPoint.deviceId();
    Ip4Address destinationAddress = Ip4Address.valueOf(ipv4.getDestinationAddress());
    Set<Ip4Address> gatewayIpAddresses = config.getPortIPs(deviceId);
    Ip4Address routerIp;
    try {
      routerIp = config.getRouterIp(deviceId);
    } catch (DeviceConfigNotFoundException e) {
      log.warn(e.getMessage() + " Aborting processPacketIn.");
      return;
    }
    IpPrefix routerIpPrefix = IpPrefix.valueOf(routerIp, IpPrefix.MAX_INET_MASK_LENGTH);
    Ip4Address routerIpAddress = routerIpPrefix.getIp4Prefix().address();

    // ICMP to the router IP or gateway IP
    if (((ICMP) ipv4.getPayload()).getIcmpType() == ICMP.TYPE_ECHO_REQUEST
        && (destinationAddress.equals(routerIpAddress)
            || gatewayIpAddresses.contains(destinationAddress))) {
      sendICMPResponse(ethernet, connectPoint);

      // ICMP for any known host
    } else if (!srManager.hostService.getHostsByIp(destinationAddress).isEmpty()) {
      // TODO: known host packet should not be coming to controller - resend flows?
      srManager.ipHandler.forwardPackets(deviceId, destinationAddress);

      // ICMP for an unknown host in the subnet of the router
    } else if (config.inSameSubnet(deviceId, destinationAddress)) {
      srManager.arpHandler.sendArpRequest(deviceId, destinationAddress, connectPoint);

      // ICMP for an unknown host
    } else {
      log.debug("ICMP request for unknown host {} ", destinationAddress);
      // Do nothing
    }
  }
예제 #8
0
  /** Tests the encoding of an intent with treatment, selector and constraints specified. */
  @Test
  public void intentWithTreatmentSelectorAndConstraints() {
    ConnectPoint ingress = NetTestTools.connectPoint("ingress", 1);
    ConnectPoint egress = NetTestTools.connectPoint("egress", 2);
    DeviceId did1 = did("device1");
    DeviceId did2 = did("device2");
    DeviceId did3 = did("device3");
    Lambda ochSignal = Lambda.ochSignal(GridType.DWDM, ChannelSpacing.CHL_100GHZ, 4, 8);
    final TrafficSelector selector =
        DefaultTrafficSelector.builder()
            .matchIPProtocol((byte) 3)
            .matchMplsLabel(MplsLabel.mplsLabel(4))
            .add(Criteria.matchOchSignalType(OchSignalType.FIXED_GRID))
            .add(Criteria.matchLambda(ochSignal))
            .matchEthDst(MacAddress.BROADCAST)
            .matchIPDst(IpPrefix.valueOf("1.2.3.4/24"))
            .build();
    final TrafficTreatment treatment =
        DefaultTrafficTreatment.builder()
            .add(Instructions.modL0Lambda(new IndexedLambda(33)))
            .setMpls(MplsLabel.mplsLabel(44))
            .setOutput(PortNumber.CONTROLLER)
            .setEthDst(MacAddress.BROADCAST)
            .build();

    final List<Constraint> constraints =
        ImmutableList.of(
            new BandwidthConstraint(Bandwidth.bps(1.0)),
            new LambdaConstraint(new IndexedLambda(3)),
            new AnnotationConstraint("key", 33.0),
            new AsymmetricPathConstraint(),
            new LatencyConstraint(Duration.ofSeconds(2)),
            new ObstacleConstraint(did1, did2),
            new WaypointConstraint(did3));

    final PointToPointIntent intent =
        PointToPointIntent.builder()
            .appId(appId)
            .selector(selector)
            .treatment(treatment)
            .ingressPoint(ingress)
            .egressPoint(egress)
            .constraints(constraints)
            .build();

    final JsonCodec<PointToPointIntent> intentCodec = context.codec(PointToPointIntent.class);
    assertThat(intentCodec, notNullValue());

    final ObjectNode intentJson = intentCodec.encode(intent, context);
    assertThat(intentJson, matchesIntent(intent));
  }
예제 #9
0
  @Override
  protected void execute() {
    StaticRoutingService routingService = get(StaticRoutingService.class);

    if (fibEntryString.length < 3) {
      return;
    }

    IpPrefix prefix = IpPrefix.valueOf(fibEntryString[0]);
    IpAddress nextHopIp = IpAddress.valueOf(fibEntryString[1]);
    MacAddress nextHopMac = MacAddress.valueOf(fibEntryString[2]);
    FibEntry fibEntry = new FibEntry(prefix, nextHopIp, nextHopMac);
    FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.DELETE, fibEntry);

    FibListener fibListener = routingService.getFibListener();
    fibListener.update(Collections.emptyList(), Arrays.asList(fibUpdate));
  }
예제 #10
0
  private void populateRuleToGateway(DeviceId deviceId, GroupId groupId, long vni, String cidr) {
    TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
    TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();

    sBuilder
        .matchEthType(Ethernet.TYPE_IPV4)
        .matchTunnelId(vni)
        .matchIPSrc(IpPrefix.valueOf(cidr))
        .matchEthDst(Constants.DEFAULT_GATEWAY_MAC);

    tBuilder.group(groupId);
    ForwardingObjective fo =
        DefaultForwardingObjective.builder()
            .withSelector(sBuilder.build())
            .withTreatment(tBuilder.build())
            .withFlag(ForwardingObjective.Flag.SPECIFIC)
            .withPriority(ROUTING_RULE_PRIORITY)
            .fromApp(appId)
            .add();

    flowObjectiveService.forward(deviceId, fo);
  }
예제 #11
0
  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);
  }
예제 #12
0
  private void populateGatewayToController(long vni, String subNetCidr) {
    TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
    TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();

    sBuilder
        .matchEthType(Ethernet.TYPE_IPV4)
        .matchTunnelId(vni)
        .matchIPSrc(IpPrefix.valueOf(subNetCidr))
        .matchEthDst(Constants.DEFAULT_GATEWAY_MAC);
    tBuilder.setOutput(PortNumber.CONTROLLER);

    ForwardingObjective fo =
        DefaultForwardingObjective.builder()
            .withSelector(sBuilder.build())
            .withTreatment(tBuilder.build())
            .withFlag(ForwardingObjective.Flag.VERSATILE)
            .withPriority(ROUTING_RULE_PRIORITY)
            .fromApp(appId)
            .add();

    gatewayService
        .getGatewayDeviceIds()
        .forEach(deviceId -> flowObjectiveService.forward(deviceId, fo));
  }
예제 #13
0
파일: SdnIpFib.java 프로젝트: Mohdrz/Onos
  /**
   * Generates a route intent for a prefix, the next hop IP address, and the next hop MAC address.
   *
   * <p>This method will find the egress interface for the intent. Intent will match dst IP prefix
   * and rewrite dst MAC address at all other border switches, then forward packets according to dst
   * MAC address.
   *
   * @param prefix IP prefix of the route to add
   * @param nextHopIpAddress IP address of the next hop
   * @param nextHopMacAddress MAC address of the next hop
   * @return the generated intent, or null if no intent should be submitted
   */
  private MultiPointToSinglePointIntent generateRouteIntent(
      IpPrefix prefix, IpAddress nextHopIpAddress, MacAddress nextHopMacAddress) {

    // Find the attachment point (egress interface) of the next hop
    Interface egressInterface = interfaceService.getMatchingInterface(nextHopIpAddress);
    if (egressInterface == null) {
      log.warn("No outgoing interface found for {}", nextHopIpAddress);
      return null;
    }

    // Generate the intent itself
    Set<ConnectPoint> ingressPorts = new HashSet<>();
    ConnectPoint egressPort = egressInterface.connectPoint();
    log.debug("Generating intent for prefix {}, next hop mac {}", prefix, nextHopMacAddress);

    for (Interface intf : interfaceService.getInterfaces()) {
      // TODO this should be only peering interfaces
      if (!intf.connectPoint().equals(egressInterface.connectPoint())) {
        ConnectPoint srcPort = intf.connectPoint();
        ingressPorts.add(srcPort);
      }
    }

    // Match the destination IP prefix at the first hop
    TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
    if (prefix.isIp4()) {
      selector.matchEthType(Ethernet.TYPE_IPV4);
      // if it is default route, then we do not need match destination
      // IP address
      if (prefix.prefixLength() != 0) {
        selector.matchIPDst(prefix);
      }
    } else {
      selector.matchEthType(Ethernet.TYPE_IPV6);
      // if it is default route, then we do not need match destination
      // IP address
      if (prefix.prefixLength() != 0) {
        selector.matchIPv6Dst(prefix);
      }
    }

    // Rewrite the destination MAC address
    TrafficTreatment.Builder treatment =
        DefaultTrafficTreatment.builder().setEthDst(nextHopMacAddress);
    if (!egressInterface.vlan().equals(VlanId.NONE)) {
      treatment.setVlanId(egressInterface.vlan());
      // If we set VLAN ID, we have to make sure a VLAN tag exists.
      // TODO support no VLAN -> VLAN routing
      selector.matchVlanId(VlanId.ANY);
    }

    int priority = prefix.prefixLength() * PRIORITY_MULTIPLIER + PRIORITY_OFFSET;
    Key key = Key.of(prefix.toString(), appId);
    return MultiPointToSinglePointIntent.builder()
        .appId(appId)
        .key(key)
        .selector(selector.build())
        .treatment(treatment.build())
        .ingressPoints(ingressPorts)
        .egressPoint(egressPort)
        .priority(priority)
        .constraints(CONSTRAINTS)
        .build();
  }
예제 #14
0
/** Unit tests for flow classifier REST APIs. */
public class FlowClassifierResourceTest extends VtnResourceTest {

  final FlowClassifierService flowClassifierService = createMock(FlowClassifierService.class);

  FlowClassifierId flowClassifierId1 = FlowClassifierId.of("4a334cd4-fe9c-4fae-af4b-321c5e2eb051");
  TenantId tenantId1 = TenantId.tenantId("1814726e2d22407b8ca76db5e567dcf1");
  VirtualPortId srcPortId1 = VirtualPortId.portId("dace4513-24fc-4fae-af4b-321c5e2eb3d1");
  VirtualPortId dstPortId1 = VirtualPortId.portId("aef3478a-4a56-2a6e-cd3a-9dee4e2ec345");

  final MockFlowClassifier flowClassifier1 =
      new MockFlowClassifier(
          flowClassifierId1,
          tenantId1,
          "flowClassifier1",
          "Mock flow classifier",
          "IPv4",
          "IP",
          1001,
          1500,
          5001,
          6000,
          IpPrefix.valueOf("1.1.1.1/16"),
          IpPrefix.valueOf("22.12.34.45/16"),
          srcPortId1,
          dstPortId1);

  /** Mock class for a flow classifier. */
  private static class MockFlowClassifier implements FlowClassifier {

    private final FlowClassifierId flowClassifierId;
    private final TenantId tenantId;
    private final String name;
    private final String description;
    private final String etherType;
    private final String protocol;
    private final int minSrcPortRange;
    private final int maxSrcPortRange;
    private final int minDstPortRange;
    private final int maxDstPortRange;
    private final IpPrefix srcIpPrefix;
    private final IpPrefix dstIpPrefix;
    private final VirtualPortId srcPort;
    private final VirtualPortId dstPort;

    public MockFlowClassifier(
        FlowClassifierId flowClassifierId,
        TenantId tenantId,
        String name,
        String description,
        String etherType,
        String protocol,
        int minSrcPortRange,
        int maxSrcPortRange,
        int minDstPortRange,
        int maxDstPortRange,
        IpPrefix srcIpPrefix,
        IpPrefix dstIpPrefix,
        VirtualPortId srcPort,
        VirtualPortId dstPort) {
      this.flowClassifierId = flowClassifierId;
      this.tenantId = tenantId;
      this.name = name;
      this.description = description;
      this.etherType = etherType;
      this.protocol = protocol;
      this.minSrcPortRange = minSrcPortRange;
      this.maxSrcPortRange = maxSrcPortRange;
      this.minDstPortRange = minDstPortRange;
      this.maxDstPortRange = maxDstPortRange;
      this.srcIpPrefix = srcIpPrefix;
      this.dstIpPrefix = dstIpPrefix;
      this.srcPort = srcPort;
      this.dstPort = dstPort;
    }

    @Override
    public FlowClassifierId flowClassifierId() {
      return flowClassifierId;
    }

    @Override
    public TenantId tenantId() {
      return tenantId;
    }

    @Override
    public String name() {
      return name;
    }

    @Override
    public String description() {
      return description;
    }

    @Override
    public String etherType() {
      return etherType;
    }

    @Override
    public String protocol() {
      return protocol;
    }

    @Override
    public int minSrcPortRange() {
      return minSrcPortRange;
    }

    @Override
    public int maxSrcPortRange() {
      return maxSrcPortRange;
    }

    @Override
    public int minDstPortRange() {
      return minDstPortRange;
    }

    @Override
    public int maxDstPortRange() {
      return maxDstPortRange;
    }

    @Override
    public IpPrefix srcIpPrefix() {
      return srcIpPrefix;
    }

    @Override
    public IpPrefix dstIpPrefix() {
      return dstIpPrefix;
    }

    @Override
    public VirtualPortId srcPort() {
      return srcPort;
    }

    @Override
    public VirtualPortId dstPort() {
      return dstPort;
    }

    @Override
    public boolean exactMatch(FlowClassifier flowClassifier) {
      return this.equals(flowClassifier)
          && Objects.equals(this.flowClassifierId, flowClassifier.flowClassifierId())
          && Objects.equals(this.tenantId, flowClassifier.tenantId());
    }
  }

  /** Sets up the global values for all the tests. */
  @Before
  public void setUpTest() {
    SfcCodecContext context = new SfcCodecContext();

    ServiceDirectory testDirectory =
        new TestServiceDirectory()
            .add(FlowClassifierService.class, flowClassifierService)
            .add(CodecService.class, context.codecManager());
    BaseResource.setServiceDirectory(testDirectory);
  }

  /** Cleans up. */
  @After
  public void tearDownTest() {}

  /** Tests the result of the rest api GET when there are no flow classifiers. */
  @Test
  public void testFlowClassifiersEmpty() {

    expect(flowClassifierService.getFlowClassifiers()).andReturn(null).anyTimes();
    replay(flowClassifierService);
    final WebResource rs = resource();
    final String response = rs.path("flow_classifiers").get(String.class);
    assertThat(response, is("{\"flow_classifiers\":[]}"));
  }

  /** Tests the result of a rest api GET for flow classifier id. */
  @Test
  public void testGetFlowClassifierId() {

    final Set<FlowClassifier> flowClassifiers = new HashSet<>();
    flowClassifiers.add(flowClassifier1);

    expect(flowClassifierService.exists(anyObject())).andReturn(true).anyTimes();
    expect(flowClassifierService.getFlowClassifier(anyObject()))
        .andReturn(flowClassifier1)
        .anyTimes();
    replay(flowClassifierService);

    final WebResource rs = resource();
    final String response =
        rs.path("flow_classifiers/4a334cd4-fe9c-4fae-af4b-321c5e2eb051").get(String.class);
    final JsonObject result = JsonObject.readFrom(response);
    assertThat(result, notNullValue());
  }

  /** Tests that a fetch of a non-existent flow classifier object throws an exception. */
  @Test
  public void testBadGet() {
    expect(flowClassifierService.getFlowClassifier(anyObject())).andReturn(null).anyTimes();
    replay(flowClassifierService);
    WebResource rs = resource();
    try {
      rs.path("flow_classifiers/78dcd363-fc23-aeb6-f44b-56dc5aafb3ae").get(String.class);
      fail("Fetch of non-existent flow classifier did not throw an exception");
    } catch (UniformInterfaceException ex) {
      assertThat(ex.getMessage(), containsString("returned a response status of"));
    }
  }

  /** Tests creating a flow classifier with POST. */
  @Test
  public void testPost() {

    expect(flowClassifierService.createFlowClassifier(anyObject())).andReturn(true).anyTimes();
    replay(flowClassifierService);

    WebResource rs = resource();
    InputStream jsonStream =
        FlowClassifierResourceTest.class.getResourceAsStream("post-FlowClassifier.json");

    ClientResponse response =
        rs.path("flow_classifiers")
            .type(MediaType.APPLICATION_JSON_TYPE)
            .post(ClientResponse.class, jsonStream);
    assertThat(response.getStatus(), is(HttpURLConnection.HTTP_OK));
  }

  /** Tests deleting a flow classifier. */
  @Test
  public void testDelete() {
    expect(flowClassifierService.removeFlowClassifier(anyObject())).andReturn(true).anyTimes();
    replay(flowClassifierService);

    WebResource rs = resource();

    String location = "flow_classifiers/4a334cd4-fe9c-4fae-af4b-321c5e2eb051";

    ClientResponse deleteResponse =
        rs.path(location).type(MediaType.APPLICATION_JSON_TYPE).delete(ClientResponse.class);
    assertThat(deleteResponse.getStatus(), is(HttpURLConnection.HTTP_NO_CONTENT));
  }
}
  /**
   * Sets up logical interfaces, which emulate the configured interfaces in SDN-IP application.
   *
   * @return configured interfaces as a map from interface name to Interface
   */
  private Map<String, Interface> setUpInterfaces() {

    Map<String, Interface> configuredInterfaces = new HashMap<>();

    String interfaceSw1Eth1 = "s1-eth1";
    InterfaceIpAddress ia1 =
        new InterfaceIpAddress(
            IpAddress.valueOf("192.168.10.101"), IpPrefix.valueOf("192.168.10.0/24"));
    Interface intfsw1eth1 =
        new Interface(
            interfaceSw1Eth1,
            s1Eth1,
            Collections.singletonList(ia1),
            MacAddress.valueOf("00:00:00:00:00:01"),
            VlanId.NONE);

    configuredInterfaces.put(interfaceSw1Eth1, intfsw1eth1);

    String interfaceSw2Eth1 = "s2-eth1";
    InterfaceIpAddress ia2 =
        new InterfaceIpAddress(
            IpAddress.valueOf("192.168.20.101"), IpPrefix.valueOf("192.168.20.0/24"));
    Interface intfsw2eth1 =
        new Interface(
            interfaceSw2Eth1,
            s2Eth1,
            Collections.singletonList(ia2),
            MacAddress.valueOf("00:00:00:00:00:02"),
            VlanId.NONE);

    configuredInterfaces.put(interfaceSw2Eth1, intfsw2eth1);

    String interfaceSw2Eth1intf2 = "s2-eth1_2";
    InterfaceIpAddress ia3 =
        new InterfaceIpAddress(
            IpAddress.valueOf("192.168.30.101"), IpPrefix.valueOf("192.168.30.0/24"));
    Interface intfsw2eth1intf2 =
        new Interface(
            interfaceSw2Eth1intf2,
            s2Eth1,
            Collections.singletonList(ia3),
            MacAddress.valueOf("00:00:00:00:00:03"),
            VlanId.NONE);

    configuredInterfaces.put(interfaceSw2Eth1intf2, intfsw2eth1intf2);

    String interfaceSw3Eth1 = "s3-eth1";
    InterfaceIpAddress ia4 =
        new InterfaceIpAddress(
            IpAddress.valueOf("192.168.40.101"), IpPrefix.valueOf("192.168.40.0/24"));
    Interface intfsw3eth1 =
        new Interface(
            Interface.NO_INTERFACE_NAME,
            s3Eth1,
            ImmutableList.of(ia4),
            MacAddress.valueOf("00:00:00:00:00:04"),
            VLAN10);

    configuredInterfaces.put(interfaceSw3Eth1, intfsw3eth1);

    String interfaceSw3Eth1intf2 = "s3-eth1_2";
    InterfaceIpAddress ia5 =
        new InterfaceIpAddress(
            IpAddress.valueOf("192.168.50.101"), IpPrefix.valueOf("192.168.50.0/24"));
    Interface intfsw3eth1intf2 =
        new Interface(
            Interface.NO_INTERFACE_NAME,
            s3Eth1,
            ImmutableList.of(ia5),
            MacAddress.valueOf("00:00:00:00:00:05"),
            VLAN20);

    configuredInterfaces.put(interfaceSw3Eth1intf2, intfsw3eth1intf2);

    expect(interfaceService.getInterfacesByPort(s1Eth1))
        .andReturn(Collections.singleton(intfsw1eth1))
        .anyTimes();
    expect(interfaceService.getInterfacesByIp(IpAddress.valueOf("192.168.10.101")))
        .andReturn(Collections.singleton(intfsw1eth1))
        .anyTimes();
    expect(interfaceService.getMatchingInterface(IpAddress.valueOf("192.168.10.1")))
        .andReturn(intfsw1eth1)
        .anyTimes();

    expect(interfaceService.getInterfacesByPort(s2Eth1))
        .andReturn(Collections.singleton(intfsw2eth1))
        .anyTimes();
    expect(interfaceService.getInterfacesByIp(IpAddress.valueOf("192.168.20.101")))
        .andReturn(Collections.singleton(intfsw2eth1))
        .anyTimes();
    expect(interfaceService.getMatchingInterface(IpAddress.valueOf("192.168.20.1")))
        .andReturn(intfsw2eth1)
        .anyTimes();

    expect(interfaceService.getInterfacesByIp(IpAddress.valueOf("192.168.30.101")))
        .andReturn(Collections.singleton(intfsw2eth1intf2))
        .anyTimes();
    expect(interfaceService.getMatchingInterface(IpAddress.valueOf("192.168.30.1")))
        .andReturn(intfsw2eth1intf2)
        .anyTimes();

    expect(interfaceService.getInterfacesByIp(IpAddress.valueOf("192.168.40.101")))
        .andReturn(Collections.singleton(intfsw3eth1))
        .anyTimes();
    expect(interfaceService.getMatchingInterface(IpAddress.valueOf("192.168.40.1")))
        .andReturn(intfsw3eth1)
        .anyTimes();

    expect(interfaceService.getInterfacesByIp(IpAddress.valueOf("192.168.50.101")))
        .andReturn(Collections.singleton(intfsw3eth1intf2))
        .anyTimes();
    expect(interfaceService.getMatchingInterface(IpAddress.valueOf("192.168.50.1")))
        .andReturn(intfsw3eth1intf2)
        .anyTimes();

    // Non-existent interface used during one of the tests
    expect(
            interfaceService.getInterfacesByPort(
                new ConnectPoint(
                    DeviceId.deviceId("of:0000000000000100"), PortNumber.portNumber(1))))
        .andReturn(null)
        .anyTimes();

    expect(interfaceService.getInterfaces())
        .andReturn(Sets.newHashSet(configuredInterfaces.values()))
        .anyTimes();

    return configuredInterfaces;
  }