23 SDN OpenFlow Challenges
23.1 Start With the Pressure Point
Keep a Network Safe When Its Rules Move
Picture a factory network whose central rule service becomes slow during an alarm. A new flow reaches a switch, but the switch has no matching rule. Waiting too long may delay a safety message; accepting anything may open the wrong path.
Software-defined networking separates the system that chooses network paths from the devices that forward messages. OpenFlow is one way those choices become switch rules. The network owner should name what each switch does when the rule service is late, unreachable, or wrong.
Test the first message, a full rule table, a broken control link, and a bad update. Keep a safe local rule for urgent traffic. Record which version was active and how the old set returns after failure.
Separate urgent paths from ordinary ones before the test. A safety message may need a small rule that already exists at the switch. A new office connection can wait or fail closed. Write these choices so a late control reply cannot make them by accident.
Use two reviewers for a change. One checks the intended path. The other looks for traffic that gained access or lost protection. Watch the update in steps and stop if a mixed old-and-new state breaks the stated rule.
This simple story does not settle every speed or trust trade-off. Practitioner designs the control limits. Under the Hood examines rule matching, table space, update order, and attack paths.
OpenFlow challenges appear when programmable rules meet finite tables, controller latency, device capability, and failure domains. The first symptom may look like a packet problem, but the cause is often a control-loop pressure point.
Start simple: name the pressure, such as table misses, rule churn, capability drift, or controller placement. Then prove how the switch, controller, and service behave before the pressure reaches production.
23.2 Learning Objectives
By the end of this chapter, you will be able to:
- Explain why rule-state pressure, broad matches, and table-miss behavior create operational risk.
- Check controller placement as a state-ownership and failure-domain decision.
- Identify southbound capability drift without assuming every switch supports the same actions.
- Evaluate controller loss, control-channel security, and constrained IoT boundaries.
- Build a proof record for an OpenFlow-style challenge check.
23.3 Quick Check: Table-Miss Storm Proof
23.4 Minimum Viable Understanding
An OpenFlow challenge is a gap between the controller’s intended rule plan and the proof that switches can execute it safely.
The next minimum viable understanding step needs OpenFlow Challenge Check Route as a visual checkpoint. At Figure 23.1, Decision supplies the relationship to challenge: Check route from challenge signal through affected state, control decision, switch proof, receiver result, and cleanup record.
Read Figure 23.1 as an ordered argument. Read the axes and reference marks first, trace how the signal changes, and then compare the observed change with the threshold or operating limit. Notice which boundary, comparison, or transition explains check route from challenge signal through affected state, control decision, switch proof, receiver result, and cleanup record. That observation connects this visual to the chapter’s running narrative: use it to justify the next design decision and to record what evidence would confirm it in operation.
Use this route:
- Name the challenge signal: table pressure, repeated table misses, controller distance, switch capability drift, controller loss, or control-channel risk.
- Identify affected state: match fields, priorities, table entries, groups, meters, counters, host location, or protected exceptions.
- Choose the control response: aggregate, split, pre-install, move ownership, reject the rule, or require manual approval.
- Verify switch proof: acknowledgement, error, table usage, counter movement, and cleanup status.
- Confirm service behavior: receiver result, protected-path behavior, fallback behavior, and rollback proof.
The check is complete only when the challenge, rule response, and observed behavior are tied together.
23.5 Prerequisites
Revisit these chapters as needed:
- SDN OpenFlow Protocol: protocol role and message vocabulary.
- OpenFlow Protocol and Flow Tables: flow entries, table-miss behavior, counters, and pipeline checks.
- SDN Core Concepts: control/data-plane separation and match-action rules.
- SDN Three-Layer Architecture: controller and infrastructure responsibilities.
23.6 Challenge Map
OpenFlow challenges usually appear in one of six check lanes.
The next challenge map step needs SDN Controller as a visual checkpoint. At Figure 23.2, Unknown Flow supplies the relationship to challenge: OpenFlow rule placement is constrained by latency, control-plane load, limited TCAM space, consistency, and scalability.
The route through Figure 23.2 is figure-specific: SDN Controller states one concern, Unknown Flow names another, and SDN Rule Placement Challenges closes the scope. That structure supports challenge map: OpenFlow rule placement is constrained by latency, control-plane load, limited TCAM space, consistency, and scalability.
Rule pressure
The rule plan asks for more detail than the switch table can safely hold or audit.
Table-miss pressure
Too many unknown packets require controller decisions instead of local forwarding.
Placement pressure
The controller is too far from the state it owns or from the failure domain it protects.
Failure pressure
Controller loss, partition, or stale state changes what can be safely modified.
Capability drift
Switches support different matches, actions, tables, groups, meters, or error behavior.
Security pressure
The control channel, controller identity, and rule authority need separate proof.
23.7 Variant Fit Addendum
SDN variants should be checked through the same challenge lanes, but the dominant risk changes by environment.
- Constrained-edge variants: protect local safety behavior, bound control traffic, and treat delayed acknowledgements differently from wired switch proof.
- Mobility variants: check attachment churn, stale paths, controller placement, and whether handoff decisions preserve protected traffic.
- Data-center and cloud variants: focus on rule scale, tenant scope, overlay boundaries, telemetry volume, and failure-domain containment.
- Gateway-mediated IoT variants: keep sensors local where needed and place programmable policy at gateways, aggregation switches, or service edges.
- Hybrid variants: name which controller owns which match space so overlapping controllers cannot install conflicting rules.
The variant decision is not “which SDN flavor is most advanced.” It is whether rule state, placement, failure behavior, and proof can be checked for the specific traffic class.
23.8 Rule-State Pressure
Rule-state pressure appears when the controller wants one rule per condition but the switch needs bounded, auditable behavior.
The chapter needs visual evidence for rule-state pressure. Figure 23.3 provides it: SDN OpenFlow rule-state pressure. Examine Rule Pressure Needs Layered Rules together with Cleanup Fields.
Read Figure 23.3 as an ordered argument. Start at the input or initiating condition, follow each arrow through the intermediate responsibilities, and finish at the output or evidence record. Notice which boundary, comparison, or transition explains SDN OpenFlow rule-state pressure. That observation connects this visual to the chapter’s running narrative: use it to justify the next design decision and to record what evidence would confirm it in operation.
Check the rule plan in layers:
- Aggregate defaults: broad rules for traffic groups with the same approved behavior.
- Narrow exceptions: temporary or protected rules that must override the default safely.
- Priority order: the winning rule should be obvious when defaults and exceptions overlap.
- Owner and cleanup: every temporary rule should have an owner, expiry condition, and rollback path.
- Counter proof: matched traffic, protected traffic, and unexpected misses should be visible.
The goal is not merely to reduce rule count. The goal is to keep the forwarding policy precise enough to audit.
23.9 Table-Miss Pressure
Reactive control is useful for unusual events, but a design that depends on constant table misses is fragile.
The next table-miss pressure step needs Table-Miss Pressure Review as a visual checkpoint. At Figure 23.4, Controller supplies the relationship to challenge: SDN OpenFlow table-miss pressure.
The route through Figure 23.4 is figure-specific: Table-Miss Pressure Review states one concern, Controller names another, and miss, counter, result closes the scope. That structure supports table-miss pressure: SDN OpenFlow table-miss pressure.
Use table-miss checks to decide what should be local:
- Known service paths: predictable telemetry, management, and update paths should not require a new controller decision for every packet.
- Exceptions: unknown hosts, policy violations, and protected transitions can be sent to the controller when the reason is explicit.
- Fallback: table-miss behavior should be an intentional action, not an implicit default hidden in the switch.
- Backoff: repeated misses from the same source should not overwhelm the control plane or hide an attack pattern.
- Proof: miss counters, controller events, installed rules, receiver outcomes, and cleanup records should agree.
23.9.1 Reactive Placement and Table-Miss Pressure
A table miss turns one data-plane event into a control-plane transaction. The switch first applies the table-miss entry. If policy sends the packet to the controller, it emits PACKET_IN, carrying the match context and either the packet itself or a buffer identifier. The controller authorizes and computes the action, sends FLOW_MOD, and may use the buffer identifier or a separate PACKET_OUT so the triggering packet continues. Later packets can match locally until idle timeout, hard timeout, or explicit deletion removes the entry.
| Stage | Critical fields or state | Failure to expose |
|---|---|---|
PACKET_IN | reason, table ID, match/in-port, buffer ID, total length, captured bytes | controller cannot distinguish a real new flow from truncation, policy miss, or invalid TTL |
| Decision | identity/policy result, topology version, selected path, priority, owner | a fast rule can still be unauthorized or based on stale topology |
FLOW_MOD | command, table, match, priority, cookie, instructions, idle/hard timeout, buffer ID | ambiguous overlap, permanent state, and cleanup failure |
| Switch response | error or acknowledgement strategy, barrier when ordering matters | controller can record intent before the switch can enforce it |
| Service proof | first-packet delay, counter movement, receiver result, expiry | rule installation is mistaken for application success |
The latency should be decomposed rather than hidden under “controller delay”:
where and cover the physical control path, is controller queueing, is decision service time, is switch update time, and is the triggering packet’s continuation. An early experimental example reported roughly 3–5 ms from miss handling through new-rule placement. Treat that as a historical, workload-specific observation to benchmark—not a guarantee for a current controller, encrypted multi-hop channel, clustered state store, or busy switch.
Now connect delay to a miss-rate budget. Let packet arrival rate be , new-flow or miss fraction be , and controller-request rate be
If a measured single worker behaves approximately like an M/M/1 queue with service rate , mean controller time is
Suppose the lab measures ms, so decisions/s, and the control portion of the first-packet budget is 20 ms. Then , giving misses/s. At 10,000 packets/s, that is a miss fraction of at most 2%. This is an illustrative queueing bound, not a sizing certificate: burstiness, locks, clustered replication, garbage collection, and mixed request classes require a measured percentile and headroom.
Reactive rules also consume TCAM over their lifetime. Little’s law gives a first estimate
where is mean rule residence time. At 200 new rules/s and 30 s residence, about 6,000 entries are live before adding proactive policy and safety reserve. Shortening the timeout lowers table pressure but raises misses; lengthening it does the reverse. The release test must sweep miss rate and timeout together, record p50/p95/p99 first-packet delay, controller queue depth, PACKET_IN rate, table occupancy, install errors, receiver results, and cleanup.
Use proactive aggregate rules for stable service paths, reactive exceptions for genuinely uncertain events, and a bounded fallback for overload. Rate-limit or coalesce repeated misses only when doing so cannot hide alarms or authorization failures. During controller loss, the switch needs an explicit fail-secure or fail-operational contract; “send every unknown packet upward” is not a fallback when upward is unavailable.
23.10 Controller Placement
Controller placement decides which state is local, which state is shared, and what happens during a partition.
Before approving controller placement, test the depicted proposition in Figure 23.5: SDN OpenFlow controller placement check. Read from Placement Is State Ownership toward Peer Controller.
For controller placement, the diagram Figure 23.5 uses Placement Is State Ownership as the entry and Peer Controller as a later checkpoint. Finish at gateway. The full reading conveys: SDN OpenFlow controller placement check.
Check placement through ownership questions:
- Local state: link health, gateway reachability, emergency exception, and attachment state may need local authority.
- Shared state: tenant policy, protected paths, identity groups, and cross-site routing may need coordination.
- Conflict handling: overlapping controllers should not be able to install conflicting rules for the same match space.
- Partition behavior: define which changes stop, which rules continue, and which services need manual approval.
- Proof: placement proof should include state convergence, switch acknowledgements, counters, and rollback records.
Placement is not only about delay. It is about where decisions can be made with enough context.
23.11 Failure Domain Boundaries
Switches can continue to forward already installed local rules during controller loss, but the design still needs a failure contract.
The chapter needs visual evidence for failure domain boundaries. Figure 23.6 provides it: SDN OpenFlow failure domain check. Examine Controller Loss Needs a Failure Contract together with Local Rules.
Read Figure 23.6 as an ordered argument. Start at the input or initiating condition, follow each arrow through the intermediate responsibilities, and finish at the output or evidence record. Notice which boundary, comparison, or transition explains SDN OpenFlow failure domain check. That observation connects this visual to the chapter’s running narrative: use it to justify the next design decision and to record what evidence would confirm it in operation.
Capture the failure contract:
Continues locally
Existing approved rules, default forwarding, and protected local fallback may continue when the controller is unavailable.
Stops changing
New unknown-flow decisions, policy changes, and broad exception rules should stop until authority is restored.
Expires carefully
Temporary rules should expire according to their check purpose, not disappear in a way that creates a hidden outage.
Recovers with proof
After reconnection, controller state, switch tables, counters, and receiver behavior should be reconciled.
23.12 Capability Drift
Not every switch exposes the same match fields, table pipeline, group behavior, meter behavior, or error reporting. Treat that difference as a design input.
For capability drift, inspect Figure 23.7 at Capability Drift Must Be Explicit. Its visible premise is: SDN OpenFlow capability drift check. Then compare Rejected.
Figure 23.7 becomes useful when Capability Drift Must Be Explicit is read alongside Rejected. proof log adds the remaining acceptance cue. This supports capability drift. The visual summarizes: SDN OpenFlow capability drift check.
Check capability drift before installing rules:
- Match support: verify the fields used by the rule are supported by the target table.
- Action support: verify output, drop, rewrite, group, meter, and queue behavior before depending on them.
- Pipeline support: verify the expected table order and handoff behavior.
- Error support: rejected or partially applied rules should create explicit proof.
- Fallback rule: document a narrower supported behavior when the preferred action is unavailable.
Capability drift is dangerous when it is discovered after a rule is already part of a release plan.
23.13 Control-Channel Security
The control channel can change forwarding behavior across the network, so its security proof must be separate from data-plane proof.
Treat control-channel security as a system decision around Control-Channel Security Is Rule Authority. The visual in Figure 23.8 places protected control channel within this relationship: SDN OpenFlow control-channel security check.
In the diagram Figure 23.8, Control-Channel Security Is Rule Authority frames the question. protected control channel changes the responsibility; reject untrusted change closes the control-channel security check. Together they explain the reject untrusted change figure claim: SDN OpenFlow control-channel security check.
Check these controls:
- Controller identity: switches should accept control messages only from approved controller endpoints.
- Switch identity: the controller should know which switch received each rule and whether the target is trusted for that role.
- Role scope: applications should not be able to install broad rules outside their approved scope.
- Change audit: every flow change should connect request, approver or owner, target, acknowledgement, and cleanup.
- Protected fallback: control-channel loss should not open a broader path than the approved local fallback.
23.14 Constrained IoT Boundaries
Constrained IoT environments often need gateway-mediated control rather than full switch-like behavior at every device.
Make the constrained iot boundaries premise visible in the diagram Figure 23.9: SDN OpenFlow constrained IoT boundary check. Begin by distinguishing Constrained IoT Needs a Gateway Boundary from Controller.
Three concrete diagram labels organize Figure 23.9: Constrained IoT Needs a Gateway Boundary, Controller, and ack, counter, result. Between them, the constrained iot boundaries relationship becomes visible: SDN OpenFlow constrained IoT boundary check.
Use the boundary to avoid overreach:
- Sensors keep local behavior required for safety, sampling, and recovery.
- Gateways translate controller intent into routing, filtering, queueing, or admission policy.
- Control traffic is bounded so management does not consume the constrained network.
- Delayed or missing acknowledgements are checked differently from wired switch acknowledgements.
- Fallback behavior is tested as part of the release, not left as an assumption.
23.15 Walkthrough: Gateway Update Window
A building gateway needs to steer update traffic for one device group while keeping management traffic and alarms on their protected paths.
Request
- Allow an approved update path for a defined device group.
- Keep alarm, management, and safety traffic on existing protected paths.
- Remove the temporary exception after the update proof is complete.
Check path
- Inventory state: identify the default aggregate rule, protected exceptions, and target device group.
- Check capability: confirm target switches support the match fields, priority, action, and cleanup behavior needed.
- Install narrowly: add a temporary exception with explicit owner, priority, scope, and rollback record.
- Observe proof: compare rule acknowledgements, counters, receiver results, and protected-path counters.
- Clean up: remove or expire the exception, record final counters, and confirm the default path is restored.
Proof record
Service intent: steer update traffic during approved maintenance window
Scope: defined device group and update receiver only
Default rule: aggregate building telemetry path remains active
Exception rule: temporary update path with explicit owner and cleanup
Protected paths: management, alarms, and safety traffic unchanged
Switch proof: acknowledgement or error for each target switch
Traffic proof: update counters move, protected counters stay clean
Receiver proof: update receiver observes expected traffic
Cleanup proof: temporary rule removed or expired and final counters recorded
23.16 Proof Loop
Every OpenFlow challenge check should end in a proof loop that can be reviewed later.
The reason to inspect proof loop is concrete. Figure 23.10 depicts: Proof loop showing challenge signal, rule decision, switch result, service result, protected path check, cleanup, and next check trigger. Distinguish Proof Loop for OpenFlow Challenges from Switch Result.
The Proof Loop for OpenFlow Challenges label opens the diagram Figure 23.10. Switch Result marks a different decision point, while rollback, trigger prevents an early stop in proof loop. Together Proof Loop for OpenFlow Challenges and rollback, trigger connect to the claim: Proof loop showing challenge signal, rule decision, switch result, service result, protected path check, cleanup, and next check trigger.
Capture:
- Challenge signal and check reason.
- Rule owner, scope, match, priority, action, and cleanup.
- Switch acknowledgement, rejection, error, table usage, and counters.
- Receiver result and protected-path behavior.
- Recovery, rollback, cleanup, and next check trigger.
23.17 Knowledge Check
23.18 Check the Challenge Proof
23.19 Match Challenges to Control
23.20 Order an OpenFlow Challenge Check
23.21 Common Pitfalls
- Treating rule count as the only table risk: broad rules can be dangerous if they hide required exceptions or cleanup.
- Leaving table-miss behavior implicit: every miss path should say whether it reports, drops, or follows a checked fallback.
- Assuming placement is only a delay problem: placement also decides state ownership, conflict handling, and partition behavior.
- Ignoring capability drift: a controller rule is not safe until the target switch capability and rejection behavior are known.
- Skipping cleanup proof: temporary exceptions become permanent risk when removal and final counters are not recorded.
23.22 OpenFlow Challenges as Proof Gaps
An OpenFlow challenge is not just a technical limitation. It is a gap between the rule behavior the controller intends and the proof that the switch, controller, receiver, and operator can keep that behavior safe over time.
The practical habit is to treat each challenge as a record: what signal exposed the risk, which state is affected, what response is allowed, what switch proof exists, what receiver outcome changed, and who owns cleanup.
For example, a gateway aggregation switch may start sending many table-miss events after a team adds separate exceptions for alarms, diagnostics, firmware downloads, and management traffic. The challenge is not simply "too many rules." The challenge is whether the design can name the affected match space, table budget, miss rate, controller load, protected paths, and supported switch actions before more exceptions are released.
A good first response is conservative. Aggregate traffic that can share a default, keep only the exceptions that protect service behavior, set priority deliberately, and record the timeout or cleanup owner. Then verify the result with table usage, error messages, counters, receiver observations, and protected-path checks instead of trusting the controller plan alone.
That record should also make the "do nothing" option visible. If the table-miss storm is caused by a firmware bug, a gateway retry loop, or a misclassified diagnostic flow, adding more OpenFlow exceptions may hide the actual cause. The safer decision may be to reject the rule plan, fix the source behavior, or pre-install one known service path while leaving uncertain traffic on a reviewed miss path.
The overview lesson is that OpenFlow gives strong tools for local forwarding, but those tools increase the need for ownership. Every challenge has to say who may create rules, who may approve exceptions, who watches counters, and who removes temporary state when the service condition ends.
23.23 Write The Challenge Record
Use a challenge record whenever the controller plan touches table capacity, table-miss behavior, placement, failure recovery, capability drift, or control-channel authority. The record keeps temporary fixes from becoming invisible production rules.
In a warehouse update window, the record might say that `agg-sw-2` is receiving 1,200 table misses per minute for gateway update and diagnostic traffic, while alarms must stay on the existing low-latency path. The bounded response could aggregate firmware downloads by gateway VLAN, keep alarm and management exceptions explicit, reject unsupported meter actions on the older switch model, and require a cleanup owner before the rule ships.
| Challenge Signal | Bounded Response | Proof Before Closure |
|---|---|---|
| Rule pressure | Aggregate defaults, narrow exceptions, explicit priority, timeout, and owner. | Table usage, matched counters, protected-path counters, and cleanup record. |
| Table-miss pressure | Pre-install known service paths and reserve controller misses for explicit exceptions. | Miss counters, controller event rate, installed-rule record, and receiver outcome. |
| Capability drift | Use a supported fallback rule or reject the change with a visible exception record. | Switch capability check, acknowledgement or error, and approved fallback behavior. |
| Controller loss | Continue approved local rules, stop broad new changes, and reconcile after recovery. | Partition behavior, stale-state check, recovered counters, and owner sign-off. |
The closure fields should be just as concrete: switch acknowledgement or error, table usage before and after, miss-rate change, rule and port counters, alarm receiver latency, update receiver result, final table state, and the owner who removed or expired the temporary rule. If any of those fields are missing, the challenge is still open.
For a mixed switch estate, add one row per switch family instead of assuming the reference design behaves uniformly. A newer Open vSwitch instance may accept the meter or group action, while an older appliance may reject it or need a simpler queue rule. The practitioner record should show which devices accepted the rule, which devices used a fallback, and which devices were excluded from the rollout.
23.24 Rule State Outlives Intent
Controller intent is temporary; installed switch state can persist, expire, overlap, or fail differently than the controller expected. That is why OpenFlow operations need proof from the switch and the service, not only from the controller log.
Rule priority, wildcard breadth, timeout behavior, table pipeline, group behavior, and meter support can all change the actual forwarding result. A temporary exception for a maintenance window can keep matching traffic after the maintenance purpose has ended unless cleanup is verified.
A checklist alone cannot settle rule state outlives intent. Inspect Figure 23.3 for this relationship: Rule-state pressure is closed only when scope, priority, counters, timeout, and cleanup all line up. Compare **Rule Pressure Needs Layered Rules** with **Cleanup Fields**.The Rule Pressure Needs Layered Rules label opens the diagram Figure 23.3. Cleanup Fields marks a different decision point, while receiver result prevents an early stop in rule state outlives intent. Together Rule Pressure Needs Layered Rules and receiver result connect to the claim: Rule-state pressure is closed only when scope, priority, counters, timeout, and cleanup all line up.
The safe pattern is to pair every installed rule with scope, priority, owner, timeout, counters, protected-path checks, receiver proof, and cleanup. Without those records, the network may keep obeying a rule whose original reason has disappeared.
Under the hood, capability drift is especially dangerous because it can look like a policy decision succeeded while one switch executes a fallback path or rejects an action. One switch might support the requested meter or group behavior; another may return an unsupported-action error or silently use a simpler path through an older pipeline. The proof record should keep those switch-specific results visible.
Controller placement adds another state boundary. During a partition, the switch may keep approved local rules but stop receiving new controller decisions. After recovery, the controller must compare intended state against the real table, counters, meters, groups, and expired entries before it assumes the network is synchronized again.
Priority and wildcard breadth are the other hidden boundary. A broad high-priority exception can shadow a safer aggregate rule, and a low-priority cleanup rule may never match if an older table entry still wins first. The final table dump should therefore be read as an ordered pipeline, not as an unordered list of installed rules.
23.25 Summary
OpenFlow challenges are check problems, not just performance problems. Rule-state pressure, table misses, controller placement, failure domains, switch capability drift, control-channel security, and constrained IoT boundaries all need explicit proof. A strong design uses aggregate defaults, narrow exceptions, bounded table-miss behavior, local fallback, identity checks, and cleanup records so forwarding behavior remains understandable after the controller intent has been translated into switch rules.
23.26 Key Takeaway
OpenFlow challenges are operational constraints: scalability, controller availability, rule conflicts, stale state, security, and troubleshooting need explicit mitigations.
23.27 See Also
- SDN OpenFlow Protocol: protocol and architecture context.
- OpenFlow Protocol and Flow Tables: flow-table anatomy and message proof.
- SDN Production Best Practices: production operating practices.
- SDN Production Framework: operating-model and governance checks.
- SDN Analytics and Implementations: telemetry and proof sources.
23.28 What’s Next
Continue to SDN Core Concepts to reinforce the control/data-plane model and match-action thinking that supports OpenFlow challenge checks.
23.29 TCAM Miss Walkthrough
Inspect Figure 23.11 to follow an unmatched packet without hiding finite table capacity or controller delay.
Read Figure 23.11 as PACKET-IN + metadata crosses from SWITCH / TCAM to CONTROLLER, then FLOW-MOD match/action installs the decision before forwarding resumes. The TCAM 63 / 64 meter and BENCHMARK, NOT GUARANTEE card keep capacity and the historical 3–5 ms example scoped to measured workload conditions.
