diff --git a/drivers/optical/src/main/java/org/onosproject/driver/optical/protection/OplinkSwitchProtection.java b/drivers/optical/src/main/java/org/onosproject/driver/optical/protection/OplinkSwitchProtection.java
new file mode 100644
index 0000000..f512b9c
--- /dev/null
+++ b/drivers/optical/src/main/java/org/onosproject/driver/optical/protection/OplinkSwitchProtection.java
@@ -0,0 +1,333 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.driver.optical.protection;
+
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.FilteredConnectPoint;
+import org.onosproject.net.Link;
+import org.onosproject.net.LinkKey;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.behaviour.protection.ProtectedTransportEndpointDescription;
+import org.onosproject.net.behaviour.protection.ProtectedTransportEndpointState;
+import org.onosproject.net.behaviour.protection.ProtectionConfigBehaviour;
+import org.onosproject.net.behaviour.protection.TransportEndpointDescription;
+import org.onosproject.net.behaviour.protection.TransportEndpointId;
+import org.onosproject.net.behaviour.protection.TransportEndpointState;
+import org.onosproject.net.config.NetworkConfigService;
+import org.onosproject.net.config.basics.BasicLinkConfig;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.driver.AbstractHandlerBehaviour;
+import org.onosproject.net.flow.DefaultFlowRule;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.link.LinkService;
+import org.onosproject.net.optical.OpticalAnnotations;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+
+import static org.onosproject.net.LinkKey.linkKey;
+
+/**
+ * Implementations of the protection behaviours for Oplink Optical Protection Switch (OPS).
+ *   - Oplink OPS has 3 logical bi-directional ports (6 uni-directional physical ports):
+ *      - port 1 is primary port for network side
+ *      - port 2 is secondary port for network side.
+ *      - port 3 is connected to the client side port;
+ *   - Traffic protection
+ *      - Traffic(Optical light) from client port is broadcasted (50/50 split) to
+ *        both primary and secondary ports all the time.
+ *      - In fault free condition, traffic from primary port is bridged to client port and
+ *        in the case of primary port fails (LOS), traffic is bridged from secondary port to client port.
+ *      - User initiated switch (to primary or secondary) is also supported.
+ */
+public class OplinkSwitchProtection extends AbstractHandlerBehaviour implements ProtectionConfigBehaviour {
+
+    private static final int VIRTUAL_PORT = 0;
+    private static final int PRIMARY_PORT = 1;
+    private static final int SECONDARY_PORT = 2;
+    private static final int CLIENT_PORT = 3;
+    private static final String PRIMARY_ID = "primary_port";
+    private static final String SECONDARY_ID = "secondary_port";
+    private static final String OPLINK_FINGERPRINT = "OplinkOPS";
+
+    protected final Logger log = LoggerFactory.getLogger(getClass());
+
+    private FlowRuleService flowRuleService = this.handler().get(FlowRuleService.class);
+    private DeviceService deviceService = this.handler().get(DeviceService.class);
+    private NetworkConfigService netCfgService = this.handler().get(NetworkConfigService.class);
+
+    @Override
+    public CompletableFuture<ConnectPoint> createProtectionEndpoint(
+            ProtectedTransportEndpointDescription configuration) {
+        //This OPS device only support one protection group of port 2 and port 3
+
+        CompletableFuture result = new CompletableFuture<ConnectPoint>();
+
+        //add flow from client port to virtual port. This set device in auto switch mode
+        addFlow(PortNumber.portNumber(VIRTUAL_PORT));
+
+        //add a virtual link bewteen two virtual ports of this device and peer
+        addLinkToPeer(configuration.peer());
+
+        result.complete(new ConnectPoint(this.data().deviceId(), PortNumber.portNumber(VIRTUAL_PORT)));
+
+        return result;
+    }
+
+    @Override
+    public CompletableFuture<ConnectPoint> updateProtectionEndpoint(
+            ConnectPoint identifier, ProtectedTransportEndpointDescription configuration) {
+
+        log.warn("Update protection configuration is not supported by this device");
+
+        CompletableFuture result = new CompletableFuture<ConnectPoint>();
+        result.complete(new ConnectPoint(this.data().deviceId(), PortNumber.portNumber(VIRTUAL_PORT)));
+
+        return result;
+    }
+
+    @Override
+    public CompletableFuture<Boolean> deleteProtectionEndpoint(ConnectPoint identifier) {
+        //OPS has only one protection group
+        CompletableFuture result = new CompletableFuture<Boolean>();
+
+        if (identifier.port().toLong() == VIRTUAL_PORT) {
+            //add a link bewteen two virtual ports of this device and peer
+            removeLinkToPeer(getPeerId());
+            deleteFlow();
+            result.complete(true);
+        } else {
+            result.complete(false);
+        }
+
+        return result;
+    }
+
+    @Override
+    public CompletableFuture<Map<ConnectPoint, ProtectedTransportEndpointDescription>> getProtectionEndpointConfigs() {
+        ConnectPoint cp = new ConnectPoint(this.data().deviceId(), PortNumber.portNumber(VIRTUAL_PORT));
+
+        Map<ConnectPoint, ProtectedTransportEndpointDescription> protectedGroups = new HashMap<>();
+        CompletableFuture result = new CompletableFuture<Map<ConnectPoint, ProtectedTransportEndpointDescription>>();
+
+        protectedGroups.put(cp, getProtectedTransportEndpointDescription());
+        result.complete(protectedGroups);
+
+        return result;
+    }
+
+    @Override
+    public CompletableFuture<Map<ConnectPoint, ProtectedTransportEndpointState>> getProtectionEndpointStates() {
+        ConnectPoint cp = new ConnectPoint(this.data().deviceId(), PortNumber.portNumber(VIRTUAL_PORT));
+
+        Map<ConnectPoint, ProtectedTransportEndpointState> protectedGroups = new HashMap<>();
+        CompletableFuture result = new CompletableFuture<Map<ConnectPoint, ProtectedTransportEndpointState>>();
+
+        protectedGroups.put(cp, getProtectedTransportEndpointState());
+        result.complete(protectedGroups);
+
+        return result;
+    }
+
+    /*
+    ** index: PRIMARY_PORT - manual switch to primary port
+    *        SECONDARY_PORT - manual switch to Secondary port
+    *        VIRTUAL_PORT - automatic switch mode
+    */
+    @Override
+    public CompletableFuture<Void> switchWorkingPath(ConnectPoint identifier, int index) {
+        CompletableFuture result = new CompletableFuture<Boolean>();
+
+        //send switch command to switch to device by sending a flow-mod message.
+        if (identifier.port().toLong() == VIRTUAL_PORT) {
+            deleteFlow();
+            addFlow(PortNumber.portNumber(index));
+            result.complete(true);
+        } else {
+            result.complete(false);
+        }
+
+        return result;
+    }
+
+    /*
+     * return the protected endpoint description of this devices
+     */
+    private ProtectedTransportEndpointDescription getProtectedTransportEndpointDescription() {
+        List<TransportEndpointDescription> teds = new ArrayList<>();
+        FilteredConnectPoint fcpPrimary = new FilteredConnectPoint(
+                new ConnectPoint(data().deviceId(), PortNumber.portNumber(PRIMARY_PORT)));
+        FilteredConnectPoint fcpSecondary = new FilteredConnectPoint(
+                new ConnectPoint(data().deviceId(), PortNumber.portNumber(SECONDARY_PORT)));
+        TransportEndpointDescription tedPrimary = TransportEndpointDescription.builder()
+                .withOutput(fcpPrimary).build();
+        TransportEndpointDescription tedSecondary = TransportEndpointDescription.builder()
+                .withOutput(fcpSecondary).build();
+
+        teds.add(tedPrimary);
+        teds.add(tedSecondary);
+        return ProtectedTransportEndpointDescription.of(teds,
+                                                        getPeerId(),
+                                                        OPLINK_FINGERPRINT);
+    }
+
+    /*
+     * get endpoint state attributes
+     */
+    private Map<String, String> getProtectionStateAttributes(PortNumber portNumber) {
+        Map<String, String> attributes = new HashMap<>();
+
+        //get status form port annotations, the status is update by hand shaker driver periodically
+        Port port = deviceService.getPort(this.data().deviceId(), portNumber);
+        if (port != null) {
+            String portStatus = port.annotations().value(OpticalAnnotations.INPUT_PORT_STATUS);
+            attributes.put(OpticalAnnotations.INPUT_PORT_STATUS, portStatus);
+        }
+        return attributes;
+    }
+
+    private int getActiveIndex() {
+        Port port = deviceService.getPort(this.data().deviceId(), PortNumber.portNumber(PRIMARY_PORT));
+        if (port != null) {
+            if (port.annotations().value(OpticalAnnotations.INPUT_PORT_STATUS)
+                    .equals(OpticalAnnotations.STATUS_IN_SERVICE)) {
+                return PRIMARY_PORT;
+            }
+        }
+        return SECONDARY_PORT;
+    }
+
+    /*
+     * get protected endpoint state
+     */
+    private ProtectedTransportEndpointState getProtectedTransportEndpointState() {
+        List<TransportEndpointState> tess = new ArrayList<>();
+        FilteredConnectPoint fcpPrimary = new FilteredConnectPoint(
+                new ConnectPoint(data().deviceId(), PortNumber.portNumber(PRIMARY_PORT)));
+        FilteredConnectPoint fcpSecondary = new FilteredConnectPoint(
+                new ConnectPoint(data().deviceId(), PortNumber.portNumber(SECONDARY_PORT)));
+        TransportEndpointDescription tedPrimary = TransportEndpointDescription.builder()
+                .withOutput(fcpPrimary).build();
+        TransportEndpointDescription tedSecondary = TransportEndpointDescription.builder()
+                .withOutput(fcpSecondary).build();
+
+        TransportEndpointState tesPrimary = TransportEndpointState.builder()
+                .withDescription(tedPrimary)
+                .withId(TransportEndpointId.of(PRIMARY_ID))
+                .addAttributes(getProtectionStateAttributes(PortNumber.portNumber(PRIMARY_PORT)))
+                .build();
+        TransportEndpointState tesSecondary = TransportEndpointState.builder()
+                .withDescription(tedSecondary)
+                .withId(TransportEndpointId.of(SECONDARY_ID))
+                .addAttributes(getProtectionStateAttributes((PortNumber.portNumber(SECONDARY_PORT))))
+                .build();
+
+        tess.add(tesPrimary);
+        tess.add(tesSecondary);
+        return ProtectedTransportEndpointState.builder()
+                .withDescription(getProtectedTransportEndpointDescription())
+                .withPathStates(tess)
+                .withActivePathIndex(getActiveIndex())
+                .build();
+    }
+
+    /*
+     *   - Protection switch is controlled by setting up flow on the device
+     *      - There is only one flow on the device at any point
+     *      - A flow from virtual port to client port indicates the device is in auto switch mode
+     *      - A flow from primary port to client port indicates the device is manually switched to primary
+     *      - A flow from secondary port to client port indicates the device is manually switched to secondary
+     */
+    private void addFlow(PortNumber workingPort) {
+        TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+        FlowRule.Builder flowRule = DefaultFlowRule.builder();
+
+        //set working port as flow's input port
+        selectorBuilder.matchInPort(workingPort);
+
+        //the flow's  output port is always the clinet port
+        treatment.setOutput(PortNumber.portNumber(CLIENT_PORT));
+
+        flowRule.forDevice(this.data().deviceId())
+                .withSelector(selectorBuilder.build())
+                .withTreatment(treatment.build())
+                .makePermanent();
+
+        // install flow rule
+        flowRuleService.applyFlowRules(flowRule.build());
+    }
+    /*
+        Delete all the flows to put device in default mode.
+     */
+    private void deleteFlow() {
+        // remove all the flows.
+        flowRuleService.purgeFlowRules(this.data().deviceId());
+    }
+
+    private void addLinkToPeer(DeviceId peerId) {
+
+        if (peerId == null) {
+            log.warn("PeerID is null for device {}", data().deviceId());
+            return;
+        }
+        ConnectPoint dstCp = new ConnectPoint(data().deviceId(), PortNumber.portNumber(VIRTUAL_PORT));
+        ConnectPoint srcCp = new ConnectPoint(peerId, PortNumber.portNumber(VIRTUAL_PORT));
+        LinkKey link = linkKey(srcCp, dstCp);
+        BasicLinkConfig cfg = netCfgService.addConfig(link, BasicLinkConfig.class);
+        cfg.type(Link.Type.VIRTUAL);
+        cfg.apply();
+    }
+
+    private void removeLinkToPeer(DeviceId peerId) {
+        if (peerId == null) {
+            log.warn("PeerID is null for device {}", data().deviceId());
+            return;
+        }
+        ConnectPoint dstCp = new ConnectPoint(data().deviceId(), PortNumber.portNumber(VIRTUAL_PORT));
+        ConnectPoint srcCp = new ConnectPoint(peerId, PortNumber.portNumber(VIRTUAL_PORT));
+        LinkKey link = linkKey(srcCp, dstCp);
+        netCfgService.removeConfig(link, BasicLinkConfig.class);
+    }
+
+    private DeviceId getPeerId() {
+        ConnectPoint dstCp = new ConnectPoint(data().deviceId(), PortNumber.portNumber(VIRTUAL_PORT));
+        Set<Link> links = this.handler().get(LinkService.class).getIngressLinks(dstCp);
+
+        for (Link l : links) {
+            if (l.type() == Link.Type.VIRTUAL) {
+                // this devide is the destination and peer is the source.
+                return l.src().deviceId();
+            }
+        }
+
+        return null;
+    }
+}
