private OFAction buildL3Modification(Instruction i) {
    L3ModificationInstruction l3m = (L3ModificationInstruction) i;
    ModIPInstruction ip;
    Ip4Address ip4;
    Ip6Address ip6;
    OFOxm<?> oxm = null;
    switch (l3m.subtype()) {
      case IPV4_SRC:
        ip = (ModIPInstruction) i;
        ip4 = ip.ip().getIp4Address();
        oxm = factory().oxms().ipv4Src(IPv4Address.of(ip4.toInt()));
        break;
      case IPV4_DST:
        ip = (ModIPInstruction) i;
        ip4 = ip.ip().getIp4Address();
        oxm = factory().oxms().ipv4Dst(IPv4Address.of(ip4.toInt()));
        break;
      case IPV6_SRC:
        ip = (ModIPInstruction) i;
        ip6 = ip.ip().getIp6Address();
        oxm = factory().oxms().ipv6Src(IPv6Address.of(ip6.toOctets()));
        break;
      case IPV6_DST:
        ip = (ModIPInstruction) i;
        ip6 = ip.ip().getIp6Address();
        oxm = factory().oxms().ipv6Dst(IPv6Address.of(ip6.toOctets()));
        break;
      case IPV6_FLABEL:
        ModIPv6FlowLabelInstruction flowLabelInstruction = (ModIPv6FlowLabelInstruction) i;
        int flowLabel = flowLabelInstruction.flowLabel();
        oxm = factory().oxms().ipv6Flabel(IPv6FlowLabel.of(flowLabel));
        break;
      case DEC_TTL:
        return factory().actions().decNwTtl();
      case TTL_IN:
        return factory().actions().copyTtlIn();
      case TTL_OUT:
        return factory().actions().copyTtlOut();
      default:
        log.warn("Unimplemented action type {}.", l3m.subtype());
        break;
    }

    if (oxm != null) {
      return factory().actions().buildSetField().setField(oxm).build();
    }
    return null;
  }
  /**
   * Matches the contents of a mod IPv6 Flow Label instruction.
   *
   * @param instructionJson JSON instruction to match
   * @param description Description object used for recording errors
   * @return true if contents match, false otherwise
   */
  private boolean matchModIPv6FlowLabelInstruction(
      JsonNode instructionJson, Description description) {
    ModIPv6FlowLabelInstruction instructionToMatch = (ModIPv6FlowLabelInstruction) instruction;
    final String jsonSubtype = instructionJson.get("subtype").textValue();
    if (!instructionToMatch.subtype().name().equals(jsonSubtype)) {
      description.appendText("subtype was " + jsonSubtype);
      return false;
    }

    final String jsonType = instructionJson.get("type").textValue();
    if (!instructionToMatch.type().name().equals(jsonType)) {
      description.appendText("type was " + jsonType);
      return false;
    }

    final int jsonFlowLabel = instructionJson.get("flowLabel").intValue();
    final int flowLabel = instructionToMatch.flowLabel();
    if (flowLabel != jsonFlowLabel) {
      description.appendText("IPv6 flow label was " + jsonFlowLabel);
      return false;
    }

    return true;
  }