diff --git a/BUCK b/BUCK
index 5942871..39243fe 100644
--- a/BUCK
+++ b/BUCK
@@ -5,6 +5,7 @@
     '//lib:org.apache.karaf.shell.console',
     '//lib:javax.ws.rs-api',
     '//cli:onos-cli',
+    '//core/common:onos-core-common',
     '//core/store/serializers:onos-core-serializers',
     '//incubator/api:onos-incubator-api',
     '//utils/rest:onlab-rest',
diff --git a/src/main/java/org/onosproject/segmentrouting/PortAuthTracker.java b/src/main/java/org/onosproject/segmentrouting/PortAuthTracker.java
new file mode 100644
index 0000000..627ca7d
--- /dev/null
+++ b/src/main/java/org/onosproject/segmentrouting/PortAuthTracker.java
@@ -0,0 +1,337 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.segmentrouting;
+
+
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.segmentrouting.config.BlockedPortsConfig;
+import org.onosproject.utils.Comparators;
+import org.slf4j.Logger;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.onosproject.net.DeviceId.deviceId;
+import static org.onosproject.net.PortNumber.portNumber;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Keeps track of ports that have been configured for blocking,
+ * and their current authentication state.
+ */
+public class PortAuthTracker {
+
+    private static final Logger log = getLogger(PortAuthTracker.class);
+
+    private Map<DeviceId, Map<PortNumber, BlockState>> blockedPorts = new HashMap<>();
+    private Map<DeviceId, Map<PortNumber, BlockState>> oldMap;
+
+    @Override
+    public String toString() {
+        return "PortAuthTracker{entries = " + blockedPorts.size() + "}";
+    }
+
+    /**
+     * Changes the state of the given device id / port number pair to the
+     * specified state.
+     *
+     * @param d        device identifier
+     * @param p        port number
+     * @param newState the updated state
+     * @return true, if the state changed from what was previously mapped
+     */
+    private boolean changeStateTo(DeviceId d, PortNumber p, BlockState newState) {
+        Map<PortNumber, BlockState> portMap =
+                blockedPorts.computeIfAbsent(d, k -> new HashMap<>());
+        BlockState oldState =
+                portMap.computeIfAbsent(p, k -> BlockState.UNCHECKED);
+        portMap.put(p, newState);
+        return (oldState != newState);
+    }
+
+    /**
+     * Radius has authorized the supplicant at this connect point. If
+     * we are tracking this port, clear the blocking flow and mark the
+     * port as authorized.
+     *
+     * @param connectPoint supplicant connect point
+     */
+    void radiusAuthorize(ConnectPoint connectPoint) {
+        DeviceId d = connectPoint.deviceId();
+        PortNumber p = connectPoint.port();
+        if (configured(d, p)) {
+            clearBlockingFlow(d, p);
+            markAsAuthenticated(d, p);
+        }
+    }
+
+    /**
+     * Supplicant at specified connect point has logged off Radius. If
+     * we are tracking this port, install a blocking flow and mark the
+     * port as blocked.
+     *
+     * @param connectPoint supplicant connect point
+     */
+    void radiusLogoff(ConnectPoint connectPoint) {
+        DeviceId d = connectPoint.deviceId();
+        PortNumber p = connectPoint.port();
+        if (configured(d, p)) {
+            installBlockingFlow(d, p);
+            markAsBlocked(d, p);
+        }
+    }
+
+    /**
+     * Marks the specified device/port as blocked.
+     *
+     * @param d device id
+     * @param p port number
+     * @return true if the state changed (was not already blocked)
+     */
+    private boolean markAsBlocked(DeviceId d, PortNumber p) {
+        return changeStateTo(d, p, BlockState.BLOCKED);
+    }
+
+    /**
+     * Marks the specified device/port as authenticated.
+     *
+     * @param d device id
+     * @param p port number
+     * @return true if the state changed (was not already authenticated)
+     */
+    private boolean markAsAuthenticated(DeviceId d, PortNumber p) {
+        return changeStateTo(d, p, BlockState.AUTHENTICATED);
+    }
+
+    /**
+     * Returns true if the given device/port are configured for blocking.
+     *
+     * @param d device id
+     * @param p port number
+     * @return true if this device/port configured for blocking
+     */
+    private boolean configured(DeviceId d, PortNumber p) {
+        Map<PortNumber, BlockState> portMap = blockedPorts.get(d);
+        return portMap != null && portMap.get(p) != null;
+    }
+
+    private BlockState whatState(DeviceId d, PortNumber p,
+                                 Map<DeviceId, Map<PortNumber, BlockState>> m) {
+        Map<PortNumber, BlockState> portMap = m.get(d);
+        if (portMap == null) {
+            return BlockState.UNCHECKED;
+        }
+        BlockState state = portMap.get(p);
+        if (state == null) {
+            return BlockState.UNCHECKED;
+        }
+        return state;
+    }
+
+    /**
+     * Returns the current state of the given device/port.
+     *
+     * @param d device id
+     * @param p port number
+     * @return current block-state
+     */
+    BlockState currentState(DeviceId d, PortNumber p) {
+        return whatState(d, p, blockedPorts);
+    }
+
+    /**
+     * Returns the current state of the given connect point.
+     *
+     * @param cp connect point
+     * @return current block-state
+     */
+
+    BlockState currentState(ConnectPoint cp) {
+        return whatState(cp.deviceId(), cp.port(), blockedPorts);
+    }
+
+    /**
+     * Returns the number of entries being tracked.
+     *
+     * @return the number of tracked entries
+     */
+    int entryCount() {
+        int count = 0;
+        for (Map<PortNumber, BlockState> m : blockedPorts.values()) {
+            count += m.size();
+        }
+        return count;
+    }
+
+    /**
+     * Returns the previously recorded state of the given device/port.
+     *
+     * @param d device id
+     * @param p port number
+     * @return previous block-state
+     */
+    private BlockState oldState(DeviceId d, PortNumber p) {
+        return whatState(d, p, oldMap);
+    }
+
+    private void configurePort(DeviceId d, PortNumber p) {
+        boolean alreadyAuthenticated =
+                oldState(d, p) == BlockState.AUTHENTICATED;
+
+        if (alreadyAuthenticated) {
+            clearBlockingFlow(d, p);
+            markAsAuthenticated(d, p);
+        } else {
+            installBlockingFlow(d, p);
+            markAsBlocked(d, p);
+        }
+        log.info("Configuring port {}/{} as {}", d, p,
+                 alreadyAuthenticated ? "AUTHENTICATED" : "BLOCKED");
+    }
+
+    private boolean notInMap(DeviceId deviceId, PortNumber portNumber) {
+        Map<PortNumber, BlockState> m = blockedPorts.get(deviceId);
+        return m == null || m.get(portNumber) == null;
+    }
+
+    private void logPortsNoLongerBlocked() {
+        for (Map.Entry<DeviceId, Map<PortNumber, BlockState>> entry :
+                oldMap.entrySet()) {
+            DeviceId d = entry.getKey();
+            Map<PortNumber, BlockState> portMap = entry.getValue();
+
+            for (PortNumber p : portMap.keySet()) {
+                if (notInMap(d, p)) {
+                    clearBlockingFlow(d, p);
+                    log.info("De-configuring port {}/{} (UNCHECKED)", d, p);
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Reconfigures the port tracker using the supplied configuration.
+     *
+     * @param cfg the new configuration
+     */
+    void configurePortBlocking(BlockedPortsConfig cfg) {
+        // remember the old map; prepare a new map
+        oldMap = blockedPorts;
+        blockedPorts = new HashMap<>();
+
+        // for each configured device, add configured ports to map
+        for (String devId : cfg.deviceIds()) {
+            cfg.portIterator(devId)
+                    .forEachRemaining(p -> configurePort(deviceId(devId),
+                                                         portNumber(p)));
+        }
+
+        // have we de-configured any ports?
+        logPortsNoLongerBlocked();
+
+        // allow old map to be garbage collected
+        oldMap = null;
+    }
+
+    private List<PortAuthState> reportPortsAuthState() {
+        List<PortAuthState> result = new ArrayList<>();
+
+        for (Map.Entry<DeviceId, Map<PortNumber, BlockState>> entry :
+                blockedPorts.entrySet()) {
+            DeviceId d = entry.getKey();
+            Map<PortNumber, BlockState> portMap = entry.getValue();
+
+            for (PortNumber p : portMap.keySet()) {
+                result.add(new PortAuthState(d, p, portMap.get(p)));
+            }
+        }
+        Collections.sort(result);
+        return result;
+    }
+
+    /**
+     * Installs a "blocking" flow for device/port specified.
+     *
+     * @param d device id
+     * @param p port number
+     */
+    void installBlockingFlow(DeviceId d, PortNumber p) {
+        log.debug("Installing Blocking Flow at {}/{}", d, p);
+        // TODO: invoke SegmentRoutingService.block(...) appropriately
+        log.info("TODO >> Installing Blocking Flow at {}/{}", d, p);
+    }
+
+    /**
+     * Removes the "blocking" flow from device/port specified.
+     *
+     * @param d device id
+     * @param p port number
+     */
+    void clearBlockingFlow(DeviceId d, PortNumber p) {
+        log.debug("Clearing Blocking Flow from {}/{}", d, p);
+        // TODO: invoke SegmentRoutingService.block(...) appropriately
+        log.info("TODO >> Clearing Blocking Flow from {}/{}", d, p);
+    }
+
+
+    /**
+     * Designates the state of a given port. One of:
+     * <ul>
+     * <li> UNCHECKED: not configured for blocking </li>
+     * <li> BLOCKED: configured for blocking, and not yet authenticated </li>
+     * <li> AUTHENTICATED: configured for blocking, but authenticated </li>
+     * </ul>
+     */
+    public enum BlockState {
+        UNCHECKED,
+        BLOCKED,
+        AUTHENTICATED
+    }
+
+    /**
+     * A simple DTO binding of device identifier, port number, and block state.
+     */
+    public static final class PortAuthState implements Comparable<PortAuthState> {
+        private final DeviceId d;
+        private final PortNumber p;
+        private final BlockState s;
+
+        private PortAuthState(DeviceId d, PortNumber p, BlockState s) {
+            this.d = d;
+            this.p = p;
+            this.s = s;
+        }
+
+        @Override
+        public String toString() {
+            return String.valueOf(d) + "/" + p + " -- " + s;
+        }
+
+        @Override
+        public int compareTo(PortAuthState o) {
+            // NOTE: only compare against "deviceid/port"
+            int result = Comparators.ELEMENT_ID_COMPARATOR.compare(d, o.d);
+            return (result != 0) ? result : Long.signum(p.toLong() - o.p.toLong());
+        }
+    }
+}
diff --git a/src/test/java/org/onosproject/segmentrouting/AugmentedPortAuthTracker.java b/src/test/java/org/onosproject/segmentrouting/AugmentedPortAuthTracker.java
new file mode 100644
index 0000000..cc214e3
--- /dev/null
+++ b/src/test/java/org/onosproject/segmentrouting/AugmentedPortAuthTracker.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.segmentrouting;
+
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * An augmented implementation of {@link PortAuthTracker}, so that we can
+ * instrument its behavior for unit test assertions.
+ */
+class AugmentedPortAuthTracker extends PortAuthTracker {
+
+    // instrument blocking flow activity, so we can see when we get hits
+    final List<ConnectPoint> installed = new ArrayList<>();
+    final List<ConnectPoint> cleared = new ArrayList<>();
+
+
+    void resetMetrics() {
+        installed.clear();
+        cleared.clear();
+    }
+
+    @Override
+    void installBlockingFlow(DeviceId d, PortNumber p) {
+        super.installBlockingFlow(d, p);
+        installed.add(new ConnectPoint(d, p));
+    }
+
+    @Override
+    void clearBlockingFlow(DeviceId d, PortNumber p) {
+        super.clearBlockingFlow(d, p);
+        cleared.add(new ConnectPoint(d, p));
+    }
+}
diff --git a/src/test/java/org/onosproject/segmentrouting/PortAuthTrackerTest.java b/src/test/java/org/onosproject/segmentrouting/PortAuthTrackerTest.java
new file mode 100644
index 0000000..6ab4bad
--- /dev/null
+++ b/src/test/java/org/onosproject/segmentrouting/PortAuthTrackerTest.java
@@ -0,0 +1,246 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.segmentrouting;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.DefaultApplicationId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.segmentrouting.PortAuthTracker.BlockState;
+import org.onosproject.segmentrouting.config.BlockedPortsConfig;
+import org.onosproject.segmentrouting.config.BlockedPortsConfigTest;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.onosproject.net.ConnectPoint.deviceConnectPoint;
+import static org.onosproject.net.DeviceId.deviceId;
+import static org.onosproject.net.PortNumber.portNumber;
+import static org.onosproject.segmentrouting.PortAuthTracker.BlockState.AUTHENTICATED;
+import static org.onosproject.segmentrouting.PortAuthTracker.BlockState.BLOCKED;
+import static org.onosproject.segmentrouting.PortAuthTracker.BlockState.UNCHECKED;
+
+/**
+ * Unit Tests for {@link PortAuthTracker}.
+ */
+public class PortAuthTrackerTest {
+    private static final ApplicationId APP_ID = new DefaultApplicationId(1, "foo");
+    private static final String KEY = "blocked";
+    private static final ObjectMapper MAPPER = new ObjectMapper();
+    private static final String PATH_CFG = "/blocked-ports.json";
+    private static final String PATH_CFG_ALT = "/blocked-ports-alt.json";
+
+    private static final String DEV1 = "of:0000000000000001";
+    private static final String DEV3 = "of:0000000000000003";
+    private static final String DEV4 = "of:0000000000000004";
+
+    private BlockedPortsConfig cfg;
+    private AugmentedPortAuthTracker tracker;
+
+    private void print(String s) {
+        System.out.println(s);
+    }
+
+    private void print(Object o) {
+        print(o.toString());
+    }
+
+    private void print(String fmt, Object... params) {
+        print(String.format(fmt, params));
+    }
+
+    private void title(String s) {
+        print("=== %s ===", s);
+    }
+
+    private BlockedPortsConfig makeConfig(String path) throws IOException {
+        InputStream blockedPortsJson = BlockedPortsConfigTest.class
+                .getResourceAsStream(path);
+        JsonNode node = MAPPER.readTree(blockedPortsJson);
+        BlockedPortsConfig cfg = new BlockedPortsConfig();
+        cfg.init(APP_ID, KEY, node, MAPPER, null);
+        return cfg;
+    }
+
+    ConnectPoint cp(String devId, int port) {
+        return ConnectPoint.deviceConnectPoint(devId + "/" + port);
+    }
+
+    @Before
+    public void setUp() throws IOException {
+        cfg = makeConfig(PATH_CFG);
+        tracker = new AugmentedPortAuthTracker();
+    }
+
+    private void verifyPortState(String devId, int first, BlockState... states) {
+        DeviceId dev = deviceId(devId);
+        int last = first + states.length;
+        int pn = first;
+        int i = 0;
+        while (pn < last) {
+            PortNumber pnum = portNumber(pn);
+            BlockState actual = tracker.currentState(dev, pnum);
+            print("%s/%s [%s]  --> %s", devId, pn, states[i], actual);
+            assertEquals("oops: " + devId + "/" + pn + "~" + actual,
+                         states[i], actual);
+            pn++;
+            i++;
+        }
+    }
+
+    @Test
+    public void basic() {
+        title("basic");
+        print(tracker);
+        print(cfg);
+
+        assertEquals("wrong entry count", 0, tracker.entryCount());
+
+        // let's assume that the net config just got loaded..
+        tracker.configurePortBlocking(cfg);
+        assertEquals("wrong entry count", 13, tracker.entryCount());
+
+        verifyPortState(DEV1, 1, BLOCKED, BLOCKED, BLOCKED, BLOCKED, UNCHECKED);
+        verifyPortState(DEV1, 6, UNCHECKED, BLOCKED, BLOCKED, BLOCKED, UNCHECKED);
+
+        verifyPortState(DEV3, 1, UNCHECKED, UNCHECKED, UNCHECKED);
+        verifyPortState(DEV3, 6, UNCHECKED, BLOCKED, BLOCKED, BLOCKED, UNCHECKED);
+
+        verifyPortState(DEV4, 1, BLOCKED, UNCHECKED, UNCHECKED, UNCHECKED, BLOCKED);
+    }
+
+    @Test
+    public void logonLogoff() {
+        title("logonLogoff");
+
+        tracker.configurePortBlocking(cfg);
+        assertEquals("wrong entry count", 13, tracker.entryCount());
+        verifyPortState(DEV1, 1, BLOCKED, BLOCKED, BLOCKED);
+
+        ConnectPoint cp = deviceConnectPoint(DEV1 + "/2");
+        tracker.radiusAuthorize(cp);
+        print("");
+        verifyPortState(DEV1, 1, BLOCKED, AUTHENTICATED, BLOCKED);
+
+        tracker.radiusLogoff(cp);
+        print("");
+        verifyPortState(DEV1, 1, BLOCKED, BLOCKED, BLOCKED);
+    }
+
+    @Test
+    public void installedFlows() {
+        title("installed flows");
+
+        assertEquals(0, tracker.installed.size());
+        tracker.configurePortBlocking(cfg);
+        assertEquals(13, tracker.installed.size());
+
+        assertTrue(tracker.installed.contains(cp(DEV1, 1)));
+        assertTrue(tracker.installed.contains(cp(DEV3, 7)));
+        assertTrue(tracker.installed.contains(cp(DEV4, 5)));
+    }
+
+    @Test
+    public void flowsLogonLogoff() {
+        title("flows logon logoff");
+
+        tracker.configurePortBlocking(cfg);
+
+        // let's pick a connect point from the configuration
+        ConnectPoint cp = cp(DEV4, 5);
+
+        assertTrue(tracker.installed.contains(cp));
+        assertEquals(0, tracker.cleared.size());
+
+        tracker.resetMetrics();
+        tracker.radiusAuthorize(cp);
+        // verify we requested the blocking flow to be cleared
+        assertTrue(tracker.cleared.contains(cp));
+
+        tracker.resetMetrics();
+        assertEquals(0, tracker.installed.size());
+        tracker.radiusLogoff(cp);
+        // verify we requested the blocking flow to be reinstated
+        assertTrue(tracker.installed.contains(cp));
+    }
+
+    @Test
+    public void uncheckedPortIgnored() {
+        title("unchecked port ignored");
+
+        tracker.configurePortBlocking(cfg);
+        tracker.resetMetrics();
+
+        // let's pick a connect point NOT in the configuration
+        ConnectPoint cp = cp(DEV4, 2);
+        assertEquals(BlockState.UNCHECKED, tracker.currentState(cp));
+
+        assertEquals(0, tracker.installed.size());
+        assertEquals(0, tracker.cleared.size());
+        tracker.radiusAuthorize(cp);
+        assertEquals(0, tracker.installed.size());
+        assertEquals(0, tracker.cleared.size());
+        tracker.radiusLogoff(cp);
+        assertEquals(0, tracker.installed.size());
+        assertEquals(0, tracker.cleared.size());
+    }
+
+    @Test
+    public void reconfiguration() throws IOException {
+        title("reconfiguration");
+
+        /* see 'blocked-ports.json' and 'blocked-ports-alt.json'
+
+          cfg:  "1": ["1-4", "7-9"],
+                "3": ["7-9"],
+                "4": ["1", "5", "9"]
+
+          alt:  "1": ["1-9"],
+                "3": ["7"],
+                "4": ["1"]
+         */
+        tracker.configurePortBlocking(cfg);
+        // dev1: ports 5 and 6 are NOT configured in the original CFG
+        assertFalse(tracker.installed.contains(cp(DEV1, 5)));
+        assertFalse(tracker.installed.contains(cp(DEV1, 6)));
+
+        tracker.resetMetrics();
+        assertEquals(0, tracker.installed.size());
+        assertEquals(0, tracker.cleared.size());
+
+        BlockedPortsConfig alt = makeConfig(PATH_CFG_ALT);
+        tracker.configurePortBlocking(alt);
+
+        // dev1: ports 5 and 6 ARE configured in the alternate CFG
+        assertTrue(tracker.installed.contains(cp(DEV1, 5)));
+        assertTrue(tracker.installed.contains(cp(DEV1, 6)));
+
+        // also, check for the ports that were decommissioned
+        assertTrue(tracker.cleared.contains(cp(DEV3, 8)));
+        assertTrue(tracker.cleared.contains(cp(DEV3, 9)));
+        assertTrue(tracker.cleared.contains(cp(DEV4, 5)));
+        assertTrue(tracker.cleared.contains(cp(DEV4, 9)));
+    }
+}
diff --git a/src/test/resources/blocked-ports-alt.json b/src/test/resources/blocked-ports-alt.json
new file mode 100644
index 0000000..3d8749e
--- /dev/null
+++ b/src/test/resources/blocked-ports-alt.json
@@ -0,0 +1,5 @@
+{
+  "of:0000000000000001": ["1-9"],
+  "of:0000000000000003": ["7"],
+  "of:0000000000000004": ["1"]
+}
