Ejemplo n.º 1
0
  private void installDownstreamRules(ForwardingObjective fwd) {
    List<Pair<Instruction, Instruction>> vlanOps =
        vlanOps(fwd, L2ModificationInstruction.L2SubType.VLAN_POP);

    if (vlanOps == null) {
      return;
    }

    Instruction output = fetchOutput(fwd, "downstream");

    if (output == null) {
      return;
    }

    Pair<Instruction, Instruction> popAndRewrite = vlanOps.remove(0);

    TrafficSelector selector = fwd.selector();

    Criterion outerVlan = selector.getCriterion(Criterion.Type.VLAN_VID);
    Criterion innerVlan = selector.getCriterion(Criterion.Type.INNER_VLAN_VID);
    Criterion inport = selector.getCriterion(Criterion.Type.IN_PORT);

    if (outerVlan == null || innerVlan == null || inport == null) {
      log.error("Forwarding objective is underspecified: {}", fwd);
      fail(fwd, ObjectiveError.BADPARAMS);
      return;
    }

    Criterion innerVid = Criteria.matchVlanId(((VlanIdCriterion) innerVlan).vlanId());

    FlowRule.Builder outer =
        DefaultFlowRule.builder()
            .forDevice(deviceId)
            .fromApp(appId)
            .makePermanent()
            .withPriority(fwd.priority())
            .withSelector(buildSelector(inport, outerVlan))
            .withTreatment(
                buildTreatment(popAndRewrite.getLeft(), Instructions.transition(QQ_TABLE)));

    FlowRule.Builder inner =
        DefaultFlowRule.builder()
            .forDevice(deviceId)
            .fromApp(appId)
            .forTable(QQ_TABLE)
            .makePermanent()
            .withPriority(fwd.priority())
            .withSelector(buildSelector(inport, innerVid))
            .withTreatment(buildTreatment(popAndRewrite.getLeft(), output));

    applyRules(fwd, inner, outer);
  }
Ejemplo n.º 2
0
  private void buildAndApplyRule(
      FilteringObjective filter, TrafficSelector selector, TrafficTreatment treatment) {
    FlowRule rule =
        DefaultFlowRule.builder()
            .forDevice(deviceId)
            .forTable(0)
            .fromApp(filter.appId())
            .makePermanent()
            .withSelector(selector)
            .withTreatment(treatment)
            .withPriority(filter.priority())
            .build();

    FlowRuleOperations.Builder opsBuilder = FlowRuleOperations.builder();

    switch (filter.type()) {
      case PERMIT:
        opsBuilder.add(rule);
        break;
      case DENY:
        opsBuilder.remove(rule);
        break;
      default:
        log.warn("Unknown filter type : {}", filter.type());
        fail(filter, ObjectiveError.UNSUPPORTED);
    }

    applyFlowRules(opsBuilder, filter);
  }
Ejemplo n.º 3
0
  private void installUpstreamRules(ForwardingObjective fwd) {
    List<Pair<Instruction, Instruction>> vlanOps =
        vlanOps(fwd, L2ModificationInstruction.L2SubType.VLAN_PUSH);

    if (vlanOps == null) {
      return;
    }

    Instruction output = fetchOutput(fwd, "upstream");

    if (output == null) {
      return;
    }

    Pair<Instruction, Instruction> innerPair = vlanOps.remove(0);

    Pair<Instruction, Instruction> outerPair = vlanOps.remove(0);

    FlowRule.Builder inner =
        DefaultFlowRule.builder()
            .forDevice(deviceId)
            .fromApp(appId)
            .makePermanent()
            .withPriority(fwd.priority())
            .withSelector(fwd.selector())
            .withTreatment(buildTreatment(innerPair.getRight(), Instructions.transition(QQ_TABLE)));

    PortCriterion inPort = (PortCriterion) fwd.selector().getCriterion(Criterion.Type.IN_PORT);

    VlanId cVlanId =
        ((L2ModificationInstruction.ModVlanIdInstruction) innerPair.getRight()).vlanId();

    FlowRule.Builder outer =
        DefaultFlowRule.builder()
            .forDevice(deviceId)
            .fromApp(appId)
            .forTable(QQ_TABLE)
            .makePermanent()
            .withPriority(fwd.priority())
            .withSelector(buildSelector(inPort, Criteria.matchVlanId(cVlanId)))
            .withTreatment(buildTreatment(outerPair.getLeft(), outerPair.getRight(), output));

    applyRules(fwd, inner, outer);
  }
Ejemplo n.º 4
0
    private void prepareInstallation() {
      Set<ControllerNode> instances = Sets.newHashSet(clusterService.getNodes());
      instances.remove(clusterService.getLocalNode());
      Set<NodeId> acceptableNodes = Sets.newHashSet();
      if (neighbours >= instances.size()) {
        instances.forEach(instance -> acceptableNodes.add(instance.id()));
      } else {
        Iterator<ControllerNode> nodes = instances.iterator();
        for (int i = neighbours; i > 0; i--) {
          acceptableNodes.add(nodes.next().id());
        }
      }
      acceptableNodes.add(clusterService.getLocalNode().id());

      Set<Device> devices = Sets.newHashSet();
      for (Device dev : deviceService.getDevices()) {
        if (acceptableNodes.contains(mastershipService.getMasterFor(dev.id()))) {
          devices.add(dev);
        }
      }

      TrafficTreatment treatment =
          DefaultTrafficTreatment.builder()
              .setOutput(PortNumber.portNumber(RandomUtils.nextInt()))
              .build();
      TrafficSelector.Builder sbuilder;
      FlowRuleOperations.Builder rules = FlowRuleOperations.builder();
      FlowRuleOperations.Builder remove = FlowRuleOperations.builder();

      for (Device d : devices) {
        for (int i = 0; i < this.flowPerDevice; i++) {
          sbuilder = DefaultTrafficSelector.builder();

          sbuilder
              .matchEthSrc(MacAddress.valueOf(RandomUtils.nextInt() * i))
              .matchEthDst(MacAddress.valueOf((Integer.MAX_VALUE - i) * RandomUtils.nextInt()));

          int randomPriority = RandomUtils.nextInt();
          FlowRule f =
              DefaultFlowRule.builder()
                  .forDevice(d.id())
                  .withSelector(sbuilder.build())
                  .withTreatment(treatment)
                  .withPriority(randomPriority)
                  .fromApp(appId)
                  .makeTemporary(10)
                  .build();
          rules.add(f);
          remove.remove(f);
        }
      }

      this.adds = rules;
      this.removes = remove;
    }
Ejemplo n.º 5
0
    /**
     * Ensures packet is of required type. Obtain the PortNumber associated with the inPackets
     * DeviceId. If this port has previously been learned (in initMacTable method) build a flow
     * using the packet's out port, treatment, destination, and other properties. Send the flow to
     * the learned out port. Otherwise, flood packet to all ports if out port is not learned.
     *
     * @param pc the PacketContext object passed through from activate() method
     */
    public void actLikeSwitch(PacketContext pc) {

      /*
       * Ensures the type of packet being processed is only of type IPV4 (not LLDP or BDDP).  If it is not, return
       * and do nothing with the packet. actLikeSwitch can only process IPV4 packets.
       */
      Short type = pc.inPacket().parsed().getEtherType();
      if (type != Ethernet.TYPE_IPV4) {
        return;
      }

      /*
       * Learn the destination, source, and output port of the packet using a ConnectPoint and the
       * associated macTable.  If there is a known port associated with the packet's destination MAC Address,
       * the output port will not be null.
       */
      ConnectPoint cp = pc.inPacket().receivedFrom();
      Map<MacAddress, PortNumber> macTable = macTables.get(cp.deviceId());
      MacAddress srcMac = pc.inPacket().parsed().getSourceMAC();
      MacAddress dstMac = pc.inPacket().parsed().getDestinationMAC();
      macTable.put(srcMac, cp.port());
      PortNumber outPort = macTable.get(dstMac);

      /*
       * If port is known, set pc's out port to the packet's learned output port and construct a
       * FlowRule using a source, destination, treatment and other properties. Send the FlowRule
       * to the designated output port.
       */
      if (outPort != null) {
        pc.treatmentBuilder().setOutput(outPort);
        FlowRule fr =
            DefaultFlowRule.builder()
                .withSelector(DefaultTrafficSelector.builder().matchEthDst(dstMac).build())
                .withTreatment(DefaultTrafficTreatment.builder().setOutput(outPort).build())
                .forDevice(cp.deviceId())
                .withPriority(PacketPriority.REACTIVE.priorityValue())
                .makeTemporary(60)
                .fromApp(appId)
                .build();

        flowRuleService.applyFlowRules(fr);
        pc.send();
      } else {
        /*
         * else, the output port has not been learned yet.  Flood the packet to all ports using
         * the actLikeHub method
         */
        actLikeHub(pc);
      }
    }
Ejemplo n.º 6
0
  private void processMulticastRule(ForwardingObjective fwd) {
    if (fwd.nextId() == null) {
      log.error("Multicast objective does not have a next id");
      fail(fwd, ObjectiveError.BADPARAMS);
    }

    OLTPipelineGroup next = getGroupForNextObjective(fwd.nextId());

    if (next == null) {
      log.error("Group for forwarding objective missing: {}", fwd);
      fail(fwd, ObjectiveError.GROUPMISSING);
    }

    Group group = groupService.getGroup(deviceId, next.key());
    TrafficTreatment treatment = buildTreatment(Instructions.createGroup(group.id()));

    FlowRule rule =
        DefaultFlowRule.builder()
            .forDevice(deviceId)
            .forTable(0)
            .fromApp(fwd.appId())
            .makePermanent()
            .withPriority(fwd.priority())
            .withSelector(fwd.selector())
            .withTreatment(treatment)
            .build();

    FlowRuleOperations.Builder builder = FlowRuleOperations.builder();
    switch (fwd.op()) {
      case ADD:
        builder.add(rule);
        break;
      case REMOVE:
        builder.remove(rule);
        break;
      case ADD_TO_EXISTING:
      case REMOVE_FROM_EXISTING:
        break;
      default:
        log.warn("Unknown forwarding operation: {}", fwd.op());
    }

    applyFlowRules(builder, fwd);
  }
Ejemplo n.º 7
0
  @Override
  // Dell switches need ETH_DST based match condition in all IP table entries.
  // So this method overrides the default spring-open behavior and adds
  // ETH_DST match condition while pushing IP table flow rules
  protected Collection<FlowRule> processSpecific(ForwardingObjective fwd) {
    log.debug("Processing specific");
    TrafficSelector selector = fwd.selector();
    EthTypeCriterion ethType = (EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE);
    if ((ethType == null)
        || ((((short) ethType.ethType()) != Ethernet.TYPE_IPV4)
            && (((short) ethType.ethType()) != Ethernet.MPLS_UNICAST))) {
      log.debug("processSpecific: Unsupported " + "forwarding objective criteraia");
      fail(fwd, ObjectiveError.UNSUPPORTED);
      return Collections.emptySet();
    }

    TrafficSelector.Builder filteredSelectorBuilder = DefaultTrafficSelector.builder();
    int forTableId = -1;
    if (((short) ethType.ethType()) == Ethernet.TYPE_IPV4) {
      if (deviceTMac == null) {
        log.debug(
            "processSpecific: ETH_DST filtering "
                + "objective is not set which is required "
                + "before sending a IPv4 forwarding objective");
        // TODO: Map the error to more appropriate error code.
        fail(fwd, ObjectiveError.DEVICEMISSING);
        return Collections.emptySet();
      }
      filteredSelectorBuilder =
          filteredSelectorBuilder
              .matchEthType(Ethernet.TYPE_IPV4)
              .matchEthDst(deviceTMac)
              .matchIPDst(((IPCriterion) selector.getCriterion(Criterion.Type.IPV4_DST)).ip());
      forTableId = ipv4UnicastTableId;
      log.debug("processing IPv4 specific forwarding objective");
    } else {
      filteredSelectorBuilder =
          filteredSelectorBuilder
              .matchEthType(Ethernet.MPLS_UNICAST)
              .matchMplsLabel(
                  ((MplsCriterion) selector.getCriterion(Criterion.Type.MPLS_LABEL)).label());
      // TODO: Add Match for BoS
      // if (selector.getCriterion(Criterion.Type.MPLS_BOS) != null) {
      // }
      forTableId = mplsTableId;
      log.debug("processing MPLS specific forwarding objective");
    }

    TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
    if (fwd.treatment() != null) {
      for (Instruction i : fwd.treatment().allInstructions()) {
        treatmentBuilder.add(i);
      }
    }

    if (fwd.nextId() != null) {
      NextGroup next = flowObjectiveStore.getNextGroup(fwd.nextId());

      if (next != null) {
        GroupKey key = appKryo.deserialize(next.data());

        Group group = groupService.getGroup(deviceId, key);

        if (group == null) {
          log.warn("The group left!");
          fail(fwd, ObjectiveError.GROUPMISSING);
          return Collections.emptySet();
        }
        treatmentBuilder.group(group.id());
        log.debug("Adding OUTGROUP action");
      } else {
        log.warn("processSpecific: No associated next objective object");
        fail(fwd, ObjectiveError.GROUPMISSING);
        return Collections.emptySet();
      }
    }

    TrafficSelector filteredSelector = filteredSelectorBuilder.build();
    TrafficTreatment treatment = treatmentBuilder.transition(aclTableId).build();

    FlowRule.Builder ruleBuilder =
        DefaultFlowRule.builder()
            .fromApp(fwd.appId())
            .withPriority(fwd.priority())
            .forDevice(deviceId)
            .withSelector(filteredSelector)
            .withTreatment(treatment);

    if (fwd.permanent()) {
      ruleBuilder.makePermanent();
    } else {
      ruleBuilder.makeTemporary(fwd.timeout());
    }

    ruleBuilder.forTable(forTableId);
    return Collections.singletonList(ruleBuilder.build());
  }