diff --git a/internal/pkg/afrouter/affinity-router.go b/internal/pkg/afrouter/affinity-router.go
new file mode 100644
index 0000000..7a94f7b
--- /dev/null
+++ b/internal/pkg/afrouter/affinity-router.go
@@ -0,0 +1,377 @@
+/*
+ * Copyright 2018-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 afrouter
+
+import (
+	"errors"
+	"fmt"
+	"github.com/golang/protobuf/proto"
+	"github.com/opencord/voltha-go/common/log"
+	"google.golang.org/grpc"
+	"regexp"
+	"strconv"
+)
+
+// TODO: Used in multiple routers, should move to common file
+const (
+	PKG_MTHD_PKG  int = 1
+	PKG_MTHD_MTHD int = 2
+)
+
+type AffinityRouter struct {
+	name               string
+	association        associationType
+	routingField       string
+	grpcService        string
+	methodMap          map[string]byte
+	nbBindingMethodMap map[string]byte
+	cluster            *cluster
+	affinity           map[string]*backend
+	currentBackend     **backend
+}
+
+func newAffinityRouter(rconf *RouterConfig, config *RouteConfig) (Router, error) {
+	var err error = nil
+	var rtrn_err = false
+	var pkg_re = regexp.MustCompile(`^(\.[^.]+\.)(.+)$`)
+	// Validate the configuration
+
+	// A name must exist
+	if config.Name == "" {
+		log.Error("A router 'name' must be specified")
+		rtrn_err = true
+	}
+
+	if rconf.ProtoPackage == "" {
+		log.Error("A 'package' must be specified")
+		rtrn_err = true
+	}
+
+	if rconf.ProtoService == "" {
+		log.Error("A 'service' must be specified")
+		rtrn_err = true
+	}
+
+	//if config.RouteField == "" {
+	//	log.Error("A 'routing_field' must be specified")
+	//	rtrn_err = true
+	//}
+
+	// TODO The overrieds section is currently not being used
+	// so the router will route all methods based on the
+	// routing_field. This needs to be added so that methods
+	// can have different routing fields.
+	var bptr *backend
+	bptr = nil
+	dr := AffinityRouter{
+		name:               config.Name,
+		grpcService:        rconf.ProtoService,
+		affinity:           make(map[string]*backend),
+		methodMap:          make(map[string]byte),
+		nbBindingMethodMap: make(map[string]byte),
+		currentBackend:     &bptr,
+	}
+	// An association must exist
+	dr.association = config.Association
+	if dr.association == AssociationUndefined {
+		log.Error("An association must be specified")
+		rtrn_err = true
+	}
+
+	// Build the routing structure based on the loaded protobuf
+	// descriptor file and the config information.
+	type key struct {
+		method string
+		field  string
+	}
+	var fieldNumberLookup = make(map[key]byte)
+	for _, f := range rconf.protoDescriptor.File {
+		// Build a temporary map of message types by name.
+		for _, m := range f.MessageType {
+			for _, fld := range m.Field {
+				log.Debugf("Processing message '%s', field '%s'", *m.Name, *fld.Name)
+				fieldNumberLookup[key{*m.Name, *fld.Name}] = byte(*fld.Number)
+			}
+		}
+	}
+	for _, f := range rconf.protoDescriptor.File {
+		if *f.Package == rconf.ProtoPackage {
+			for _, s := range f.Service {
+				if *s.Name == rconf.ProtoService {
+					log.Debugf("Loading package data '%s' for service '%s' for router '%s'", *f.Package, *s.Name, dr.name)
+					// Now create a map keyed by method name with the value being the
+					// field number of the route selector.
+					var ok bool
+					for _, m := range s.Method {
+						// Find the input type in the messages and extract the
+						// field number and save it for future reference.
+						log.Debugf("Processing method '%s'", *m.Name)
+						// Determine if this is a method we're supposed to be processing.
+						if needMethod(*m.Name, config) {
+							log.Debugf("Enabling method '%s'", *m.Name)
+							pkg_methd := pkg_re.FindStringSubmatch(*m.InputType)
+							if pkg_methd == nil {
+								log.Errorf("Regular expression didn't match input type '%s'", *m.InputType)
+								rtrn_err = true
+							}
+							// The input type has the package name prepended to it. Remove it.
+							//in := (*m.InputType)[len(rconf.ProtoPackage)+2:]
+							in := pkg_methd[PKG_MTHD_MTHD]
+							dr.methodMap[*m.Name], ok = fieldNumberLookup[key{in, config.RouteField}]
+							if !ok {
+								log.Errorf("Method '%s' has no field named '%s' in it's parameter message '%s'",
+									*m.Name, config.RouteField, in)
+								rtrn_err = true
+							}
+						}
+						// The sb method is always included in the methods so we can check it here too.
+						if needNbBindingMethod(*m.Name, config) {
+							log.Debugf("Enabling southbound method '%s'", *m.Name)
+							// The output type has the package name prepended to it. Remove it.
+							out := (*m.OutputType)[len(rconf.ProtoPackage)+2:]
+							dr.nbBindingMethodMap[*m.Name], ok = fieldNumberLookup[key{out, config.RouteField}]
+							if !ok {
+								log.Errorf("Method '%s' has no field named '%s' in it's parameter message '%s'",
+									*m.Name, config.RouteField, out)
+								rtrn_err = true
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+
+	// Create the backend cluster or link to an existing one
+	ok := true
+	if dr.cluster, ok = clusters[config.backendCluster.Name]; !ok {
+		if dr.cluster, err = newBackendCluster(config.backendCluster); err != nil {
+			log.Errorf("Could not create a backend for router %s", config.Name)
+			rtrn_err = true
+		}
+	}
+
+	if rtrn_err {
+		return dr, errors.New(fmt.Sprintf("Failed to create a new router '%s'", dr.name))
+	}
+
+	return dr, nil
+}
+
+func needNbBindingMethod(mthd string, conf *RouteConfig) bool {
+	for _, m := range conf.NbBindingMethods {
+		if mthd == m {
+			return true
+		}
+	}
+	return false
+}
+
+// TODO: Used in multiple routers, should move to common file
+func needMethod(mthd string, conf *RouteConfig) bool {
+	for _, m := range conf.Methods {
+		if mthd == m {
+			return true
+		}
+	}
+	return false
+}
+
+func (ar AffinityRouter) Service() string {
+	return ar.grpcService
+}
+
+func (ar AffinityRouter) Name() string {
+	return ar.name
+}
+
+func (ar AffinityRouter) skipField(data *[]byte, idx *int) error {
+	switch (*data)[*idx] & 3 {
+	case 0: // Varint
+		// skip the field number/type
+		*idx++
+		// if the msb is set, then more bytes to follow
+		for (*data)[*idx] >= 128 {
+			*idx++
+		}
+		// the last byte doesn't have the msb set
+		*idx++
+	case 1: // 64 bit
+		*idx += 9
+	case 2: // Length delimited
+		*idx++
+		b := proto.NewBuffer((*data)[*idx:])
+		t, _ := b.DecodeVarint()
+		*idx += int(t) + 1
+	case 3: // Deprecated
+	case 4: // Deprecated
+	case 5: // 32 bit
+		*idx += 5
+	}
+	return nil
+}
+
+func (ar AffinityRouter) decodeProtoField(payload []byte, fieldId byte) (string, error) {
+	idx := 0
+	b := proto.NewBuffer([]byte{})
+	//b.DebugPrint("The Buffer", payload)
+	for { // Find the route selector field
+		log.Debugf("Decoding afinity value attributeNumber: %d from %v at index %d", fieldId, payload, idx)
+		log.Debugf("Attempting match with payload: %d, methodTable: %d", payload[idx], fieldId)
+		if payload[idx]>>3 == fieldId {
+			log.Debugf("Method match with payload: %d, methodTable: %d", payload[idx], fieldId)
+			// TODO: Consider supporting other selector types.... Way, way in the future
+			// ok, the future is now, support strings as well... ugh.
+			var selector string
+			switch payload[idx] & 3 {
+			case 0: // Integer
+				b.SetBuf(payload[idx+1:])
+				v, e := b.DecodeVarint()
+				if e == nil {
+					log.Debugf("Decoded the ing field: %v", v)
+					selector = strconv.Itoa(int(v))
+				} else {
+					log.Errorf("Failed to decode varint %v", e)
+					return "", e
+				}
+			case 2: // Length delimited AKA string
+				b.SetBuf(payload[idx+1:])
+				v, e := b.DecodeStringBytes()
+				if e == nil {
+					log.Debugf("Decoded the string field: %v", v)
+					selector = v
+				} else {
+					log.Errorf("Failed to decode string %v", e)
+					return "", e
+				}
+			default:
+				err := errors.New(fmt.Sprintf("Only integer and string route selectors are permitted"))
+				log.Error(err)
+				return "", err
+			}
+			return selector, nil
+		} else if err := ar.skipField(&payload, &idx); err != nil {
+			log.Errorf("Parsing message failed %v", err)
+			return "", err
+		}
+	}
+}
+
+func (ar AffinityRouter) Route(sel interface{}) (*backend, *connection) {
+	switch sl := sel.(type) {
+	case *requestFrame:
+		log.Debugf("Route called for requestFrame with method %s", sl.methodInfo.method)
+		// Check if this method should be affinity bound from the
+		// reply rather than the request.
+		if _, ok := ar.nbBindingMethodMap[sl.methodInfo.method]; ok {
+			var err error
+			log.Debugf("Method '%s' affinity binds on reply", sl.methodInfo.method)
+			// Just round robin route the southbound request
+			if *ar.currentBackend, err = ar.cluster.nextBackend(*ar.currentBackend, BackendSequenceRoundRobin); err == nil {
+				return *ar.currentBackend, nil
+			} else {
+				sl.err = err
+				return nil, nil
+			}
+		}
+		// Not a south affinity binding method, proceed with north affinity binding.
+		if selector, err := ar.decodeProtoField(sl.payload, ar.methodMap[sl.methodInfo.method]); err == nil {
+			log.Debugf("Establishing affinity for selector: %s", selector)
+			if rtrn, ok := ar.affinity[selector]; ok {
+				return rtrn, nil
+			} else {
+				// The selector isn't in the map, create a new affinity mapping
+				log.Debugf("MUST CREATE A NEW AFFINITY MAP ENTRY!!")
+				var err error
+				if *ar.currentBackend, err = ar.cluster.nextBackend(*ar.currentBackend, BackendSequenceRoundRobin); err == nil {
+					ar.setAffinity(selector, *ar.currentBackend)
+					//ar.affinity[selector] = *ar.currentBackend
+					//log.Debugf("New affinity set to backend %s",(*ar.currentBackend).name)
+					return *ar.currentBackend, nil
+				} else {
+					sl.err = err
+					return nil, nil
+				}
+			}
+		}
+	default:
+		log.Errorf("Internal: invalid data type in Route call %v", sel)
+		return nil, nil
+	}
+	log.Errorf("Bad lookup in affinity map %v", ar.affinity)
+	return nil, nil
+}
+
+func (ar AffinityRouter) GetMetaKeyVal(serverStream grpc.ServerStream) (string, string, error) {
+	return "", "", nil
+}
+
+func (ar AffinityRouter) IsStreaming(_ string) (bool, bool) {
+	panic("not implemented")
+}
+
+func (ar AffinityRouter) BackendCluster(mthd string, metaKey string) (*cluster, error) {
+	return ar.cluster, nil
+}
+
+func (ar AffinityRouter) FindBackendCluster(beName string) *cluster {
+	if beName == ar.cluster.name {
+		return ar.cluster
+	}
+	return nil
+}
+
+func (ar AffinityRouter) ReplyHandler(sel interface{}) error {
+	switch sl := sel.(type) {
+	case *responseFrame:
+		log.Debugf("Reply handler called for responseFrame with method %s", sl.method)
+		// Determine if reply action is required.
+		if fld, ok := ar.nbBindingMethodMap[sl.method]; ok && len(sl.payload) > 0 {
+			// Extract the field value from the frame and
+			// and set affinity accordingly
+			if selector, err := ar.decodeProtoField(sl.payload, fld); err == nil {
+				log.Debug("Settign affinity on reply")
+				if ar.setAffinity(selector, sl.backend) != nil {
+					log.Error("Setting affinity on reply failed")
+				}
+				return nil
+			} else {
+				err := errors.New(fmt.Sprintf("Failed to decode reply field %d for method %s", fld, sl.method))
+				log.Error(err)
+				return err
+			}
+		}
+		return nil
+	default:
+		err := errors.New(fmt.Sprintf("Internal: invalid data type in ReplyHander call %v", sl))
+		log.Error(err)
+		return err
+	}
+}
+
+func (ar AffinityRouter) setAffinity(key string, be *backend) error {
+	if be2, ok := ar.affinity[key]; !ok {
+		ar.affinity[key] = be
+		log.Debugf("New affinity set to backend %s for key %s", be.name, key)
+	} else if be2 != be {
+		err := errors.New(fmt.Sprintf("Attempting multiple sets of affinity for key %s to backend %s from %s on router %s",
+			key, be.name, ar.affinity[key].name, ar.name))
+		log.Error(err)
+		return err
+	}
+	return nil
+}
diff --git a/internal/pkg/afrouter/affinity-router_test.go b/internal/pkg/afrouter/affinity-router_test.go
new file mode 100644
index 0000000..dfcefc0
--- /dev/null
+++ b/internal/pkg/afrouter/affinity-router_test.go
@@ -0,0 +1,444 @@
+/*
+ * Portions copyright 2019-present Open Networking Foundation
+ * Original copyright 2019-present Ciena Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the"github.com/stretchr/testify/assert" "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 afrouter
+
+import (
+	"fmt"
+	"github.com/golang/protobuf/proto"
+	"github.com/opencord/voltha-go/common/log"
+	common_pb "github.com/opencord/voltha-protos/go/common"
+	voltha_pb "github.com/opencord/voltha-protos/go/voltha"
+	"github.com/stretchr/testify/assert"
+	"google.golang.org/grpc"
+	"testing"
+)
+
+const (
+	AFFINITY_ROUTER_PROTOFILE = "../../../vendor/github.com/opencord/voltha-protos/go/voltha.pb"
+)
+
+// Unit test initialization
+func init() {
+	// Logger must be configured or bad things happen
+	log.SetDefaultLogger(log.JSON, log.DebugLevel, nil)
+	log.AddPackage(log.JSON, log.WarnLevel, nil)
+}
+
+// Build an affinity router configuration
+func MakeAffinityTestConfig(numBackends int, numConnections int) (*RouteConfig, *RouterConfig) {
+
+	var backends []BackendConfig
+	for backendIndex := 0; backendIndex < numBackends; backendIndex++ {
+		var connections []ConnectionConfig
+		for connectionIndex := 0; connectionIndex < numConnections; connectionIndex++ {
+			connectionConfig := ConnectionConfig{
+				Name: fmt.Sprintf("rw_vcore%d%d", backendIndex, connectionIndex+1),
+				Addr: "foo",
+				Port: "123",
+			}
+			connections = append(connections, connectionConfig)
+		}
+
+		backendConfig := BackendConfig{
+			Name:        fmt.Sprintf("rw_vcore%d", backendIndex),
+			Type:        BackendSingleServer,
+			Connections: connections,
+		}
+
+		backends = append(backends, backendConfig)
+	}
+
+	backendClusterConfig := BackendClusterConfig{
+		Name:     "vcore",
+		Backends: backends,
+	}
+
+	routeConfig := RouteConfig{
+		Name:             "dev_manager",
+		Type:             RouteTypeRpcAffinityMessage,
+		Association:      AssociationRoundRobin,
+		BackendCluster:   "vcore",
+		backendCluster:   &backendClusterConfig,
+		RouteField:       "id",
+		Methods:          []string{"CreateDevice", "EnableDevice"},
+		NbBindingMethods: []string{"CreateDevice"},
+	}
+
+	routerConfig := RouterConfig{
+		Name:         "vcore",
+		ProtoService: "VolthaService",
+		ProtoPackage: "voltha",
+		Routes:       []RouteConfig{routeConfig},
+		ProtoFile:    AFFINITY_ROUTER_PROTOFILE,
+	}
+	return &routeConfig, &routerConfig
+}
+
+// Route() requires an open connection, so pretend we have one.
+func PretendAffinityOpenConnection(router Router, clusterName string, backendIndex int, connectionName string) {
+	cluster := router.FindBackendCluster(clusterName)
+
+	// Route Method expects an open connection
+	conn := cluster.backends[backendIndex].connections[connectionName]
+	cluster.backends[backendIndex].openConns[conn] = &grpc.ClientConn{}
+}
+
+// Common setup to run before each unit test
+func AffinityTestSetup() {
+	// reset globals that need to be clean for each unit test
+
+	clusters = make(map[string]*cluster)
+	allRouters = make(map[string]Router)
+}
+
+// Test creation of a new AffinityRouter, and the Service(), Name(), FindBackendCluster(), and
+// methods.
+func TestAffinityRouterInit(t *testing.T) {
+	AffinityTestSetup()
+
+	routeConfig, routerConfig := MakeAffinityTestConfig(1, 1)
+
+	router, err := newAffinityRouter(routerConfig, routeConfig)
+
+	assert.NotNil(t, router)
+	assert.Nil(t, err)
+
+	assert.Equal(t, router.Service(), "VolthaService")
+	assert.Equal(t, router.Name(), "dev_manager")
+
+	cluster, err := router.BackendCluster("foo", "bar")
+	assert.Equal(t, cluster, clusters["vcore"])
+	assert.Nil(t, err)
+
+	assert.Equal(t, router.FindBackendCluster("vcore"), clusters["vcore"])
+}
+
+// Should throw error if no name in configuration
+func TestAffinityRouterInitNoName(t *testing.T) {
+	AffinityTestSetup()
+
+	routeConfig, routerConfig := MakeAffinityTestConfig(1, 1)
+	routeConfig.Name = ""
+
+	_, err := newAffinityRouter(routerConfig, routeConfig)
+
+	assert.EqualError(t, err, "Failed to create a new router ''")
+}
+
+// Should thow error if now ProtoPackage in configuration
+func TestAffinityRouterInitNoProtoPackage(t *testing.T) {
+	AffinityTestSetup()
+
+	routeConfig, routerConfig := MakeAffinityTestConfig(1, 1)
+	routerConfig.ProtoPackage = ""
+
+	_, err := newAffinityRouter(routerConfig, routeConfig)
+
+	assert.EqualError(t, err, "Failed to create a new router 'dev_manager'")
+}
+
+// Should throw error if no ProtoServer in configuration
+func TestAffinityRouterInitNoProtoService(t *testing.T) {
+	AffinityTestSetup()
+
+	routeConfig, routerConfig := MakeAffinityTestConfig(1, 1)
+	routerConfig.ProtoService = ""
+
+	_, err := newAffinityRouter(routerConfig, routeConfig)
+
+	assert.EqualError(t, err, "Failed to create a new router 'dev_manager'")
+}
+
+// Tests a cluster with only one Backend
+func TestAffinityRouteOne(t *testing.T) {
+	AffinityTestSetup()
+
+	_, routerConfig := MakeAffinityTestConfig(1, 1)
+
+	router, err := newRouter(routerConfig)
+	assert.Nil(t, err)
+
+	PretendAffinityOpenConnection(router, "vcore", 0, "rw_vcore01")
+
+	idMessage := &common_pb.ID{Id: "1234"}
+
+	idData, err := proto.Marshal(idMessage)
+	assert.Nil(t, err)
+
+	sel := &requestFrame{payload: idData,
+		err:        nil,
+		metaKey:    NoMeta,
+		methodInfo: newMethodDetails("/voltha.VolthaService/EnableDevice")}
+
+	backend, connection := router.Route(sel)
+
+	assert.Nil(t, sel.err)
+	assert.NotNil(t, backend)
+	assert.Equal(t, "rw_vcore0", backend.name)
+	assert.Nil(t, connection)
+
+	// Since we only have one backend, calling Route a second time should return the same one
+
+	backend, connection = router.Route(sel)
+
+	assert.Nil(t, sel.err)
+	assert.NotNil(t, backend)
+	assert.Equal(t, "rw_vcore0", backend.name)
+	assert.Nil(t, connection)
+}
+
+// Tests a cluster with two Backends
+func TestAffinityRouteTwo(t *testing.T) {
+	AffinityTestSetup()
+
+	_, routerConfig := MakeAffinityTestConfig(2, 1)
+
+	router, err := newRouter(routerConfig)
+	assert.Nil(t, err)
+
+	PretendAffinityOpenConnection(router, "vcore", 0, "rw_vcore01")
+	PretendAffinityOpenConnection(router, "vcore", 1, "rw_vcore11")
+
+	idMessage := &common_pb.ID{Id: "1234"}
+	idData, err := proto.Marshal(idMessage)
+	assert.Nil(t, err)
+
+	sel := &requestFrame{payload: idData,
+		err:        nil,
+		metaKey:    NoMeta,
+		methodInfo: newMethodDetails("/voltha.VolthaService/EnableDevice")}
+
+	// We should Route to the first core and bind affinity to it
+
+	backend, connection := router.Route(sel)
+
+	assert.Nil(t, sel.err)
+	assert.NotNil(t, backend)
+	assert.Equal(t, "rw_vcore0", backend.name)
+	assert.Nil(t, connection)
+
+	// We should have established affinity, and trying Route again should return the same core
+
+	backend, connection = router.Route(sel)
+
+	assert.Nil(t, sel.err)
+	assert.NotNil(t, backend)
+	assert.Equal(t, "rw_vcore0", backend.name)
+	assert.Nil(t, connection)
+
+	// Make up a message with a different id
+	idMessage = &common_pb.ID{Id: "1235"}
+	idData, err = proto.Marshal(idMessage)
+	assert.Nil(t, err)
+
+	sel = &requestFrame{payload: idData,
+		err:        nil,
+		metaKey:    NoMeta,
+		methodInfo: newMethodDetails("/voltha.VolthaService/EnableDevice")}
+
+	// Calling Route with the new ID should cause it to bind affinity to the second core
+
+	backend, connection = router.Route(sel)
+
+	assert.Nil(t, sel.err)
+	assert.NotNil(t, backend)
+	assert.Equal(t, "rw_vcore1", backend.name)
+	assert.Nil(t, connection)
+}
+
+// Tests a cluster with one backend but no open connections
+func TestAffinityRouteOneNoOpenConnection(t *testing.T) {
+	AffinityTestSetup()
+
+	_, routerConfig := MakeAffinityTestConfig(1, 1)
+
+	router, err := newRouter(routerConfig)
+	assert.Nil(t, err)
+
+	idMessage := &common_pb.ID{Id: "1234"}
+
+	idData, err := proto.Marshal(idMessage)
+	assert.Nil(t, err)
+
+	sel := &requestFrame{payload: idData,
+		err:        nil,
+		metaKey:    NoMeta,
+		methodInfo: newMethodDetails("/voltha.VolthaService/EnableDevice")}
+
+	backend, connection := router.Route(sel)
+
+	assert.EqualError(t, sel.err, "No backend with open connections found")
+	assert.Nil(t, backend)
+	assert.Nil(t, connection)
+}
+
+// Tests binding on reply
+func TestAffinityRouteReply(t *testing.T) {
+	AffinityTestSetup()
+
+	_, routerConfig := MakeAffinityTestConfig(2, 1)
+
+	router, err := newRouter(routerConfig)
+	assert.Nil(t, err)
+
+	// Get the created AffinityRouter so we can inspect its state
+	aRouter := allRouters["vcoredev_manager"].(AffinityRouter)
+
+	PretendAffinityOpenConnection(router, "vcore", 0, "rw_vcore01")
+	PretendAffinityOpenConnection(router, "vcore", 1, "rw_vcore11")
+
+	idMessage := &voltha_pb.Device{Id: "1234"}
+	idData, err := proto.Marshal(idMessage)
+	assert.Nil(t, err)
+
+	// Note that sel.backend must be set. As this is a response, it must
+	// have come from a backend and that backend must be known.
+
+	sel := &responseFrame{payload: idData,
+		metaKey: NoMeta,
+		backend: router.FindBackendCluster("vcore").backends[0],
+		method:  "CreateDevice",
+	}
+
+	// affinity should be unset as we have not routed yet
+	assert.Empty(t, aRouter.affinity)
+
+	err = aRouter.ReplyHandler(sel)
+	assert.Nil(t, err)
+
+	// affinity should now be set
+	assert.NotEmpty(t, aRouter.affinity)
+	assert.Equal(t, router.FindBackendCluster("vcore").backends[0], aRouter.affinity["1234"])
+}
+
+// Tests binding on reply, with incorrect frame type
+func TestAffinityRouteReplyIncorrectFrame(t *testing.T) {
+	AffinityTestSetup()
+
+	_, routerConfig := MakeAffinityTestConfig(2, 1)
+
+	router, err := newRouter(routerConfig)
+	assert.Nil(t, err)
+
+	// Get the created AffinityRouter so we can inspect its state
+	aRouter := allRouters["vcoredev_manager"].(AffinityRouter)
+
+	PretendAffinityOpenConnection(router, "vcore", 0, "rw_vcore01")
+	PretendAffinityOpenConnection(router, "vcore", 1, "rw_vcore11")
+
+	idMessage := &voltha_pb.Device{Id: "1234"}
+	idData, err := proto.Marshal(idMessage)
+	assert.Nil(t, err)
+
+	sel := &requestFrame{payload: idData,
+		err:        nil,
+		metaKey:    NoMeta,
+		methodInfo: newMethodDetails("/voltha.VolthaService/EnableDevice"),
+	}
+
+	// ReplyHandler expects a replyFrame and we're giving it a requestFrame instead
+
+	err = aRouter.ReplyHandler(sel)
+	assert.EqualError(t, err, "Internal: invalid data type in ReplyHander call &{[10 4 49 50 51 52] <nil> <nil> <nil> <nil> {/voltha.VolthaService/EnableDevice voltha VolthaService EnableDevice}  nometa }")
+}
+
+func TestAffinityRouterDecodeProtoField(t *testing.T) {
+	AffinityTestSetup()
+
+	_, routerConfig := MakeAffinityTestConfig(2, 1)
+
+	_, err := newRouter(routerConfig)
+	assert.Nil(t, err)
+
+	// Get the created AffinityRouter so we can inspect its state
+	aRouter := allRouters["vcoredev_manager"].(AffinityRouter)
+
+	// Pick something to test with lots of field types. Port is a good candidate.
+	portMessage := &voltha_pb.Port{PortNo: 123,
+		Label:     "testlabel",
+		Type:      3,
+		DeviceId:  "5678",
+		RxPackets: 9876,
+	}
+
+	portData, err := proto.Marshal(portMessage)
+	assert.Nil(t, err)
+
+	/*
+	 * Decode various fields in the protobuf. Decoding each subsequent
+	 * field implies skipfield() is called on its predecessor.
+	 */
+
+	s, err := aRouter.decodeProtoField(portData, 1) // field 1 is PortNo
+	assert.Equal(t, "123", s)
+
+	// Test VOL-1882, skipping of varint field. Note: May cause infinite loop if not fixed!
+	s, err = aRouter.decodeProtoField(portData, 2) // field 2 is Label
+	assert.Equal(t, "testlabel", s)
+
+	s, err = aRouter.decodeProtoField(portData, 3) // field 3 is PortType
+	assert.Equal(t, "3", s)
+
+	s, err = aRouter.decodeProtoField(portData, 7) // field 7 is DeviceId
+	assert.Equal(t, "5678", s)
+
+	// TODO: Seems like an int64 ought to be allowed...
+	s, err = aRouter.decodeProtoField(portData, 9) // field 7 is RxPackets
+	assert.EqualError(t, err, "Only integer and string route selectors are permitted")
+}
+
+// Test setting affinity for a key to a backend
+func TestAffinitySetAffinity(t *testing.T) {
+	AffinityTestSetup()
+
+	_, routerConfig := MakeAffinityTestConfig(2, 1)
+
+	router, err := newRouter(routerConfig)
+	assert.Nil(t, err)
+
+	// Get the created AffinityRouter so we can inspect its state
+	aRouter := allRouters["vcoredev_manager"].(AffinityRouter)
+
+	backend := router.FindBackendCluster("vcore").backends[0]
+	err = aRouter.setAffinity("1234", backend)
+
+	assert.Nil(t, err)
+}
+
+// Trying to set affinity when it has already been set should fail.
+func TestAffinitySetAffinityChange(t *testing.T) {
+	AffinityTestSetup()
+
+	_, routerConfig := MakeAffinityTestConfig(2, 1)
+
+	router, err := newRouter(routerConfig)
+	assert.Nil(t, err)
+
+	// Get the created AffinityRouter so we can inspect its state
+	aRouter := allRouters["vcoredev_manager"].(AffinityRouter)
+
+	backend := router.FindBackendCluster("vcore").backends[0]
+	err = aRouter.setAffinity("1234", backend)
+
+	assert.Nil(t, err)
+
+	// Now pick a different backend
+	backend = router.FindBackendCluster("vcore").backends[1]
+	err = aRouter.setAffinity("1234", backend)
+
+	assert.EqualError(t, err, "Attempting multiple sets of affinity for key 1234 to backend rw_vcore1 from rw_vcore0 on router dev_manager")
+}
diff --git a/internal/pkg/afrouter/api.go b/internal/pkg/afrouter/api.go
new file mode 100644
index 0000000..8b72897
--- /dev/null
+++ b/internal/pkg/afrouter/api.go
@@ -0,0 +1,265 @@
+/*
+ * Copyright 2018-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 afrouter
+
+import (
+	"errors"
+	"fmt"
+	"github.com/opencord/voltha-go/common/log"
+	pb "github.com/opencord/voltha-protos/go/afrouter"
+	common_pb "github.com/opencord/voltha-protos/go/common"
+	"golang.org/x/net/context"
+	"google.golang.org/grpc"
+	"net"
+	"net/url"
+	"runtime"
+	"strconv"
+)
+
+type ArouterApi struct {
+	addr        string
+	port        int
+	apiListener net.Listener
+	apiServer   *grpc.Server
+	running     bool
+	ar          *ArouterProxy
+}
+
+func newApi(config *ApiConfig, ar *ArouterProxy) (*ArouterApi, error) {
+	var rtrn_err bool
+	// Create a seperate server and listener for the API
+	// Validate the ip address if one is provided
+	if _, err := url.Parse(config.Addr); err != nil {
+		log.Errorf("Invalid address '%s' provided for API server", config.Addr)
+		rtrn_err = true
+	}
+	if rtrn_err {
+		return nil, errors.New("Errors in API configuration")
+	} else {
+		var err error = nil
+		aa := &ArouterApi{addr: config.Addr, port: int(config.Port), ar: ar}
+		// Create the listener for the API server
+		if aa.apiListener, err =
+			net.Listen("tcp", config.Addr+":"+
+				strconv.Itoa(int(config.Port))); err != nil {
+			log.Error(err)
+			return nil, err
+		}
+		// Create the API server
+		aa.apiServer = grpc.NewServer()
+		pb.RegisterConfigurationServer(aa.apiServer, *aa)
+		return aa, err
+	}
+}
+
+func (aa *ArouterApi) getServer(srvr string) (*server, error) {
+	if s, ok := aa.ar.servers[srvr]; !ok {
+		err := errors.New(fmt.Sprintf("Server '%s' doesn't exist", srvr))
+		return nil, err
+	} else {
+		return s, nil
+	}
+}
+
+func (aa *ArouterApi) getRouter(s *server, clstr string) (Router, error) {
+	for _, pkg := range s.routers {
+		for _, r := range pkg {
+			if c := r.FindBackendCluster(clstr); c != nil {
+				return r, nil
+			}
+		}
+	}
+	err := errors.New(fmt.Sprintf("Cluster '%s' doesn't exist", clstr))
+	return nil, err
+}
+
+func (aa *ArouterApi) getCluster(s *server, clstr string) (*cluster, error) {
+	for _, pkg := range s.routers {
+		for _, r := range pkg {
+			if c := r.FindBackendCluster(clstr); c != nil {
+				return c, nil
+			}
+		}
+	}
+	err := errors.New(fmt.Sprintf("Cluster '%s' doesn't exist", clstr))
+	return nil, err
+}
+
+func (aa *ArouterApi) getBackend(c *cluster, bknd string) (*backend, error) {
+	for _, b := range c.backends {
+		if b.name == bknd {
+			return b, nil
+		}
+	}
+	err := errors.New(fmt.Sprintf("Backend '%s' doesn't exist in cluster %s",
+		bknd, c.name))
+	return nil, err
+}
+
+func (aa *ArouterApi) getConnection(b *backend, con string) (*connection, error) {
+	if c, ok := b.connections[con]; !ok {
+		err := errors.New(fmt.Sprintf("Connection '%s' doesn't exist", con))
+		return nil, err
+	} else {
+		return c, nil
+	}
+}
+
+func (aa *ArouterApi) updateConnection(in *pb.Conn, cn *connection, b *backend) error {
+	return errors.New("updateConnection not implemented")
+}
+
+func (aa ArouterApi) SetAffinity(ctx context.Context, in *pb.Affinity) (*pb.Result, error) {
+	log.Debugf("SetAffinity called! %v", in)
+	//return &pb.Result{Success:true,Error:""},nil
+	// Navigate down tot he connection and compare IP addresses and ports if they're
+	// not the same then close the existing connection. If they are bothe the same
+	// then return an error describing the situation.
+	var err error
+
+	aap := &aa
+
+	_ = aap
+
+	log.Debugf("Getting router %s and route %s", in.Router, in.Route)
+	if r, ok := allRouters[in.Router+in.Route]; ok {
+		switch rr := r.(type) {
+		case AffinityRouter:
+			log.Debug("Affinity router found")
+			b := rr.FindBackendCluster(in.Cluster).getBackend(in.Backend)
+			if b != nil {
+				rr.setAffinity(in.Id, b)
+			} else {
+				log.Errorf("Requested backend '%s' not found", in.Backend)
+			}
+			_ = rr
+		case MethodRouter:
+			log.Debug("Method router found")
+			_ = rr
+		default:
+			log.Debug("Some other router found")
+			_ = rr
+		}
+	} else {
+		log.Debugf("Couldn't get router type")
+		return &pb.Result{Success: false, Error: err.Error()}, err
+	}
+
+	return &pb.Result{Success: true, Error: ""}, nil
+}
+
+func (aa ArouterApi) SetConnection(ctx context.Context, in *pb.Conn) (*pb.Result, error) {
+	// Navigate down tot he connection and compare IP addresses and ports if they're
+	// not the same then close the existing connection. If they are bothe the same
+	// then return an error describing the situation.
+	var s *server
+	var c *cluster
+	var b *backend
+	var cn *connection
+	var err error
+
+	log.Debugf("SetConnection called! %v", in)
+
+	aap := &aa
+	if s, err = (aap).getServer(in.Server); err != nil {
+		err := errors.New(fmt.Sprintf("Server '%s' doesn't exist", in.Server))
+		log.Error(err)
+		return &pb.Result{Success: false, Error: err.Error()}, err
+	}
+	// The cluster is usually accessed via tha router but since each
+	// cluster is unique it's good enough to find the router that
+	// has the cluster we're looking for rather than fully keying
+	// the path
+	if c, err = aap.getCluster(s, in.Cluster); err != nil {
+		log.Error(err)
+		return &pb.Result{Success: false, Error: err.Error()}, err
+	}
+
+	if b, err = aap.getBackend(c, in.Backend); err != nil {
+		log.Error(err)
+		return &pb.Result{Success: false, Error: err.Error()}, err
+	}
+
+	if cn, err = aap.getConnection(b, in.Connection); err != nil {
+		log.Error(err)
+		return &pb.Result{Success: false, Error: err.Error()}, err
+	}
+
+	if err = aap.updateConnection(in, cn, b); err != nil {
+		log.Error(err)
+		return &pb.Result{Success: false, Error: err.Error()}, err
+	}
+
+	return &pb.Result{Success: true, Error: ""}, nil
+}
+
+func (aa ArouterApi) GetGoroutineCount(ctx context.Context, in *pb.Empty) (*pb.Count, error) {
+	return &pb.Count{Count: uint32(runtime.NumGoroutine())}, nil
+}
+
+func (aa ArouterApi) UpdateLogLevel(ctx context.Context, in *common_pb.Logging) (*pb.Empty, error) {
+	intLevel := int(in.Level)
+
+	if in.PackageName == "" {
+		log.SetAllLogLevel(intLevel)
+		log.SetDefaultLogLevel(intLevel)
+	} else if in.PackageName == "default" {
+		log.SetDefaultLogLevel(intLevel)
+	} else {
+		log.SetPackageLogLevel(in.PackageName, intLevel)
+	}
+
+	return &pb.Empty{}, nil
+}
+
+func (aa ArouterApi) GetLogLevels(ctx context.Context, in *common_pb.LoggingComponent) (*common_pb.Loggings, error) {
+	logLevels := &common_pb.Loggings{}
+
+	// do the per-package log levels
+	for _, packageName := range log.GetPackageNames() {
+		level, err := log.GetPackageLogLevel(packageName)
+		if err != nil {
+			return nil, err
+		}
+		logLevel := &common_pb.Logging{
+			ComponentName: in.ComponentName,
+			PackageName:   packageName,
+			Level:         common_pb.LogLevel_LogLevel(level)}
+		logLevels.Items = append(logLevels.Items, logLevel)
+	}
+
+	// now do the default log level
+	logLevel := &common_pb.Logging{
+		ComponentName: in.ComponentName,
+		PackageName:   "default",
+		Level:         common_pb.LogLevel_LogLevel(log.GetDefaultLogLevel())}
+	logLevels.Items = append(logLevels.Items, logLevel)
+
+	return logLevels, nil
+}
+
+func (aa *ArouterApi) serve() {
+	// Start a serving thread
+	go func() {
+		aa.running = true
+		if err := aa.apiServer.Serve(aa.apiListener); err != nil {
+			aa.running = false
+			log.Error(err)
+			errChan <- err
+		}
+	}()
+}
diff --git a/internal/pkg/afrouter/arproxy.go b/internal/pkg/afrouter/arproxy.go
new file mode 100644
index 0000000..72641de
--- /dev/null
+++ b/internal/pkg/afrouter/arproxy.go
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2018-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 afrouter
+
+// This file implements the ArouterPoxy struct and its
+// functions. The ArouterProxy is the top level object
+// for the affinity router.
+
+import (
+	"github.com/opencord/voltha-go/common/log"
+)
+
+// String names for display in error messages.
+var arProxy *ArouterProxy = nil
+
+type ArouterProxy struct {
+	servers map[string]*server // Defined in handler.go
+	api     *ArouterApi
+}
+
+// Create the routing proxy
+func NewArouterProxy(conf *Configuration) (*ArouterProxy, error) {
+	arProxy = &ArouterProxy{servers: make(map[string]*server)}
+	// Create all the servers listed in the configuration
+	for _, s := range conf.Servers {
+		if ns, err := newServer(&s); err != nil {
+			log.Error("Configuration failed")
+			return nil, err
+		} else {
+			arProxy.servers[ns.Name()] = ns
+		}
+	}
+
+	// TODO: The API is not mandatory, check if it's even in the config before
+	// trying to create it. If it isn't then don't bother but log a warning.
+	if api, err := newApi(&conf.Api, arProxy); err != nil {
+		return nil, err
+	} else {
+		arProxy.api = api
+	}
+
+	return arProxy, nil
+}
+
+// Start serving
+func (ap *ArouterProxy) ListenAndServe() error {
+
+	for _, srvr := range ap.servers {
+		ap.serve(srvr)
+	}
+	ap.api.serve()
+
+	// Just wait until we're done which only happens
+	// on a signal or an error.
+	err := <-doneChan
+
+	return err
+}
+
+func (ap *ArouterProxy) serve(srvr *server) {
+
+	// Start a serving thread
+	go func() {
+		srvr.running = true
+		if err := srvr.proxyServer.Serve(srvr.proxyListener); err != nil {
+			srvr.running = false
+			log.Error(err)
+			errChan <- err
+		}
+	}()
+}
diff --git a/internal/pkg/afrouter/backend.go b/internal/pkg/afrouter/backend.go
new file mode 100644
index 0000000..c597d49
--- /dev/null
+++ b/internal/pkg/afrouter/backend.go
@@ -0,0 +1,295 @@
+/*
+ * Copyright 2018-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 afrouter
+
+// Backend manager handles redundant connections per backend
+
+import (
+	"errors"
+	"fmt"
+	"github.com/opencord/voltha-go/common/log"
+	"golang.org/x/net/context"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/metadata"
+	"net/url"
+	"strconv"
+	"strings"
+	"sync"
+)
+
+// backend represents a collection of backends in a HA configuration
+type backend struct {
+	mutex             sync.Mutex
+	name              string
+	beType            backendType
+	activeAssociation association
+	connFailCallback  func(string, *backend) bool
+	connections       map[string]*connection
+	openConns         map[*connection]*grpc.ClientConn
+	activeRequests    map[*request]struct{}
+}
+
+type association struct {
+	strategy associationStrategy
+	location associationLocation
+	field    string // Used only if location is protobuf
+	key      string
+}
+
+// splitActiveStreamsUnsafe expects the caller to have already locked the backend mutex
+func (be *backend) splitActiveStreamsUnsafe(cn *connection, conn *grpc.ClientConn) {
+	if len(be.activeRequests) != 0 {
+		log.Debugf("Creating new streams for %d existing requests", len(be.activeRequests))
+	}
+	for r := range be.activeRequests {
+		r.mutex.Lock()
+		if _, have := r.streams[cn.name]; !have {
+			log.Debugf("Opening southbound stream for existing request '%s'", r.methodInfo.method)
+			if stream, err := grpc.NewClientStream(r.ctx, clientStreamDescForProxying, conn, r.methodInfo.all); err != nil {
+				log.Debugf("Failed to create a client stream '%s', %v", cn.name, err)
+			} else {
+				go r.catchupRequestStreamThenForwardResponseStream(cn.name, stream)
+				// new thread will unlock the request mutex
+				continue
+			}
+		}
+		r.mutex.Unlock()
+	}
+}
+
+// openSouthboundStreams sets up a connection to each southbound frame
+func (be *backend) openSouthboundStreams(srv interface{}, serverStream grpc.ServerStream, nf *requestFrame, sf *responseFrame) (*request, error) {
+	be.mutex.Lock()
+	defer be.mutex.Unlock()
+
+	isStreamingRequest, isStreamingResponse := nf.router.IsStreaming(nf.methodInfo.method)
+
+	// Get the metadata from the incoming message on the server
+	md, ok := metadata.FromIncomingContext(serverStream.Context())
+	if !ok {
+		return nil, errors.New("could not get a server stream metadata")
+	}
+
+	r := &request{
+		// Create an outgoing context that includes the incoming metadata and that will cancel if the server's context is canceled
+		ctx: metadata.AppendToOutgoingContext(metadata.NewOutgoingContext(serverStream.Context(), md.Copy()), "voltha_serial_number", nf.serialNo),
+
+		streams:         make(map[string]grpc.ClientStream),
+		responseErrChan: make(chan error, 1),
+
+		backend:             be,
+		serverStream:        serverStream,
+		methodInfo:          nf.methodInfo,
+		requestFrame:        nf,
+		responseFrame:       sf,
+		isStreamingRequest:  isStreamingRequest,
+		isStreamingResponse: isStreamingResponse,
+	}
+
+	log.Debugf("Opening southbound request for method '%s'", nf.methodInfo.method)
+
+	// TODO: Need to check if this is an active/active backend cluster
+	// with a serial number in the header.
+	log.Debugf("Serial number for transaction allocated: %s", nf.serialNo)
+	// If even one stream can be created then proceed. If none can be
+	// created then report an error because both the primary and redundant
+	// connections are non-existent.
+	var atLeastOne = false
+	var errStr strings.Builder
+
+	log.Debugf("There are %d/%d streams to open", len(be.openConns), len(be.connections))
+	if nf.connection != nil {
+		// Debug statement triggered by source router. Other routers have no connection preference.
+		log.Debugf("Looking for connection %s", nf.connection.name)
+	}
+	for cn, conn := range be.openConns {
+		// If source-router was used, it will indicate a specific connection to be used
+		if nf.connection != nil && nf.connection != cn {
+			continue
+		}
+
+		log.Debugf("Opening stream for connection '%s'", cn.name)
+		if stream, err := grpc.NewClientStream(r.ctx, clientStreamDescForProxying, conn, r.methodInfo.all); err != nil {
+			log.Debugf("Failed to create a client stream '%s', %v", cn.name, err)
+		} else {
+			r.streams[cn.name] = stream
+			go r.forwardResponseStream(cn.name, stream)
+			atLeastOne = true
+		}
+	}
+	if atLeastOne {
+		be.activeRequests[r] = struct{}{}
+		return r, nil
+	}
+	fmt.Fprintf(&errStr, "{{No open connections for backend '%s' unable to send}} ", be.name)
+	log.Error(errStr.String())
+	return nil, errors.New(errStr.String())
+}
+
+func (be *backend) handler(srv interface{}, serverStream grpc.ServerStream, nf *requestFrame, sf *responseFrame) error {
+	// Set up streams for each open connection
+	request, err := be.openSouthboundStreams(srv, serverStream, nf, sf)
+	if err != nil {
+		log.Errorf("openStreams failed: %v", err)
+		return err
+	}
+
+	log.Debug("Starting request stream forwarding")
+	if s2cErr := request.forwardRequestStream(serverStream); s2cErr != nil {
+		// exit with an error to the stack
+		return grpc.Errorf(codes.Internal, "failed proxying s2c: %v", s2cErr)
+	}
+	// wait for response stream to complete
+	return <-request.responseErrChan
+}
+
+func newBackend(conf *BackendConfig, clusterName string) (*backend, error) {
+	var rtrn_err bool = false
+
+	log.Debugf("Configuring the backend with %v", *conf)
+	// Validate the conifg and configure the backend
+	be := &backend{
+		name:           conf.Name,
+		connections:    make(map[string]*connection),
+		openConns:      make(map[*connection]*grpc.ClientConn),
+		activeRequests: make(map[*request]struct{}),
+	}
+	if conf.Type == BackendUndefined {
+		log.Error("Invalid type specified for backend %s in cluster %s", conf.Name, clusterName)
+		rtrn_err = true
+	}
+	be.beType = conf.Type
+
+	if conf.Association.Strategy == AssociationStrategyUndefined && be.beType == BackendActiveActive {
+		log.Errorf("An association strategy must be provided if the backend "+
+			"type is active/active for backend %s in cluster %s", conf.Name, clusterName)
+		rtrn_err = true
+	}
+	be.activeAssociation.strategy = conf.Association.Strategy
+
+	if conf.Association.Location == AssociationLocationUndefined && be.beType == BackendActiveActive {
+		log.Errorf("An association location must be provided if the backend "+
+			"type is active/active for backend %s in cluster %s", conf.Name, clusterName)
+		rtrn_err = true
+	}
+	be.activeAssociation.location = conf.Association.Location
+
+	if conf.Association.Field == "" && be.activeAssociation.location == AssociationLocationProtobuf {
+		log.Errorf("An association field must be provided if the backend "+
+			"type is active/active and the location is set to protobuf "+
+			"for backend %s in cluster %s", conf.Name, clusterName)
+		rtrn_err = true
+	}
+	be.activeAssociation.field = conf.Association.Field
+
+	if conf.Association.Key == "" && be.activeAssociation.location == AssociationLocationHeader {
+		log.Errorf("An association key must be provided if the backend "+
+			"type is active/active and the location is set to header "+
+			"for backend %s in cluster %s", conf.Name, clusterName)
+		rtrn_err = true
+	}
+	be.activeAssociation.key = conf.Association.Key
+	if rtrn_err {
+		return nil, errors.New("Backend configuration failed")
+	}
+	// Configure the connections
+	// Connections can consist of just a name. This allows for dynamic configuration
+	// at a later time.
+	// TODO: validate that there is one connection for all but active/active backends
+	if len(conf.Connections) > 1 && be.beType != BackendActiveActive {
+		log.Errorf("Only one connection must be specified if the association " +
+			"strategy is not set to 'active_active'")
+		rtrn_err = true
+	}
+	if len(conf.Connections) == 0 {
+		log.Errorf("At least one connection must be specified")
+		rtrn_err = true
+	}
+	for _, cnConf := range conf.Connections {
+		if cnConf.Name == "" {
+			log.Errorf("A connection must have a name for backend %s in cluster %s",
+				conf.Name, clusterName)
+		} else {
+			ctx, cancelFunc := context.WithCancel(context.Background())
+			be.connections[cnConf.Name] = &connection{name: cnConf.Name, addr: cnConf.Addr, port: cnConf.Port, backend: be, ctx: ctx, close: cancelFunc}
+			if _, err := url.Parse(cnConf.Addr); err != nil {
+				log.Errorf("The address for connection %s in backend %s in cluster %s is invalid: %s",
+					cnConf.Name, conf.Name, clusterName, err)
+				rtrn_err = true
+			}
+			// Validate the port number. This just validtes that it's a non 0 integer
+			if n, err := strconv.Atoi(cnConf.Port); err != nil || n <= 0 || n > 65535 {
+				log.Errorf("Port %s for connection %s in backend %s in cluster %s is invalid",
+					cnConf.Port, cnConf.Name, conf.Name, clusterName)
+				rtrn_err = true
+			} else {
+				if n <= 0 && n > 65535 {
+					log.Errorf("Port %s for connection %s in backend %s in cluster %s is invalid",
+						cnConf.Port, cnConf.Name, conf.Name, clusterName)
+					rtrn_err = true
+				}
+			}
+		}
+	}
+
+	if rtrn_err {
+		return nil, errors.New("Connection configuration failed")
+	}
+	// All is well start the backend cluster connections
+	be.connectAll()
+
+	return be, nil
+}
+
+func (be *backend) incConn(cn *connection, conn *grpc.ClientConn) {
+	be.mutex.Lock()
+	defer be.mutex.Unlock()
+
+	be.openConns[cn] = conn
+	be.splitActiveStreamsUnsafe(cn, conn)
+}
+
+func (be *backend) decConn(cn *connection) {
+	be.mutex.Lock()
+	defer be.mutex.Unlock()
+
+	delete(be.openConns, cn)
+}
+
+func (be *backend) NumOpenConnections() int {
+	be.mutex.Lock()
+	defer be.mutex.Unlock()
+
+	return len(be.openConns)
+}
+
+// Attempts to establish all the connections for a backend
+// any failures result in an abort. This should only be called
+// on a first attempt to connect. Individual connections should be
+// handled after that.
+func (be *backend) connectAll() {
+	for _, cn := range be.connections {
+		go cn.connect()
+	}
+}
+
+// Set a callback for connection failure notification
+// This is currently not used.
+func (be *backend) setConnFailCallback(cb func(string, *backend) bool) {
+	be.connFailCallback = cb
+}
diff --git a/internal/pkg/afrouter/binding-router.go b/internal/pkg/afrouter/binding-router.go
new file mode 100644
index 0000000..2602137
--- /dev/null
+++ b/internal/pkg/afrouter/binding-router.go
@@ -0,0 +1,211 @@
+/*
+ * Copyright 2018-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 afrouter
+
+import (
+	"errors"
+	"fmt"
+	"github.com/opencord/voltha-go/common/log"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+)
+
+type BindingRouter struct {
+	name        string
+	association associationType
+	//routingField string
+	grpcService string
+	//protoDescriptor *pb.FileDescriptorSet
+	//methodMap map[string]byte
+	beCluster      *cluster
+	bindings       map[string]*backend
+	bindingType    string
+	bindingField   string
+	bindingMethod  string
+	currentBackend **backend
+}
+
+func (br BindingRouter) IsStreaming(_ string) (bool, bool) {
+	panic("not implemented")
+}
+
+func (br BindingRouter) BackendCluster(s string, metaKey string) (*cluster, error) {
+	return br.beCluster, nil
+	//return nil,errors.New("Not implemented yet")
+}
+func (br BindingRouter) Name() string {
+	return br.name
+}
+func (br BindingRouter) Service() string {
+	return br.grpcService
+}
+func (br BindingRouter) GetMetaKeyVal(serverStream grpc.ServerStream) (string, string, error) {
+	var rtrnK = ""
+	var rtrnV = ""
+
+	// Get the metadata from the server stream
+	md, ok := metadata.FromIncomingContext(serverStream.Context())
+	if !ok {
+		return rtrnK, rtrnV, errors.New("Could not get a server stream metadata")
+	}
+
+	// Determine if one of the method routing keys exists in the metadata
+	if _, ok := md[br.bindingField]; ok == true {
+		rtrnV = md[br.bindingField][0]
+		rtrnK = br.bindingField
+	}
+
+	return rtrnK, rtrnV, nil
+}
+func (br BindingRouter) FindBackendCluster(becName string) *cluster {
+	if becName == br.beCluster.name {
+		return br.beCluster
+	}
+	return nil
+}
+func (br BindingRouter) ReplyHandler(v interface{}) error {
+	return nil
+}
+func (br BindingRouter) Route(sel interface{}) (*backend, *connection) {
+	var err error
+	switch sl := sel.(type) {
+	case *requestFrame:
+		if b, ok := br.bindings[sl.metaVal]; ok == true { // binding exists, just return it
+			return b, nil
+		} else { // establish a new binding or error.
+			if sl.metaVal != "" {
+				err = errors.New(fmt.Sprintf("Attempt to route on non-existent metadata value '%s' in key '%s'",
+					sl.metaVal, sl.metaKey))
+				log.Error(err)
+				sl.err = err
+				return nil, nil
+			}
+			if sl.methodInfo.method != br.bindingMethod {
+				err = errors.New(fmt.Sprintf("Binding must occur with method %s but attempted with method %s",
+					br.bindingMethod, sl.methodInfo.method))
+				log.Error(err)
+				sl.err = err
+				return nil, nil
+			}
+			log.Debugf("MUST CREATE A NEW BINDING MAP ENTRY!!")
+			if *br.currentBackend, err = br.beCluster.nextBackend(*br.currentBackend, BackendSequenceRoundRobin); err == nil {
+				// Use the name of the backend as the metaVal for this new binding
+				br.bindings[(*br.currentBackend).name] = *br.currentBackend
+				return *br.currentBackend, nil
+
+			} else {
+				log.Error(err)
+				sl.err = err
+				return nil, nil
+			}
+		}
+	default:
+		return nil, nil
+	}
+}
+
+func newBindingRouter(rconf *RouterConfig, config *RouteConfig) (Router, error) {
+	var rtrn_err = false
+	var err error = nil
+	log.Debugf("Creating binding router %s", config.Name)
+	// A name must exist
+	if config.Name == "" {
+		log.Error("A router 'name' must be specified")
+		rtrn_err = true
+	}
+
+	if rconf.ProtoPackage == "" {
+		log.Error("A 'package' must be specified")
+		rtrn_err = true
+	}
+
+	if rconf.ProtoService == "" {
+		log.Error("A 'service' must be specified")
+		rtrn_err = true
+	}
+
+	//if config.RouteField == "" {
+	//	log.Error("A 'routing_field' must be specified")
+	//	rtrn_err = true
+	//}
+
+	// TODO: Using the specified service, the imported proto
+	// descriptor file should be scanned for all methods provided
+	// for this router to ensure that this field exists in
+	// the message(s) passed to the method. This will avoid run
+	// time failures that might not be detected for long periods
+	// of time.
+
+	// TODO The routes section is currently not being used
+	// so the router will route all methods based on the
+	// routing_field. This needs to be done.
+	var bptr *backend
+	bptr = nil
+	br := BindingRouter{
+		name:        config.Name,
+		grpcService: rconf.ProtoService,
+		bindings:    make(map[string]*backend),
+		//methodMap:make(map[string]byte),
+		currentBackend: &bptr,
+	}
+
+	// A binding association must exist
+	br.association = config.Binding.Association
+	if br.association == AssociationUndefined {
+		log.Error("An binding association must be specified")
+		rtrn_err = true
+	}
+	// A binding type must exist
+	// TODO: This is parsed but ignored and a header based type is used.
+	if config.Binding.Type != "header" {
+		log.Error("The binding type must be set to header")
+		rtrn_err = true
+	} else {
+		br.bindingType = config.Binding.Type
+	}
+	// A binding method must exist
+	if config.Binding.Method == "" {
+		log.Error("The binding method must be specified")
+		rtrn_err = true
+	} else {
+		br.bindingMethod = config.Binding.Method
+	}
+	// A binding field must exxist
+	if config.Binding.Field == "" {
+		log.Error("The binding field must be specified")
+		rtrn_err = true
+	} else {
+		br.bindingField = config.Binding.Field
+	}
+
+	// Create the backend cluster or link to an existing one
+	ok := true
+	if br.beCluster, ok = clusters[config.backendCluster.Name]; ok == false {
+		if br.beCluster, err = newBackendCluster(config.backendCluster); err != nil {
+			log.Errorf("Could not create a backend for router %s", config.Name)
+			rtrn_err = true
+		}
+	}
+
+	// HERE HERE HERE
+
+	if rtrn_err {
+		return br, errors.New(fmt.Sprintf("Failed to create a new router '%s'", br.name))
+	}
+
+	return br, nil
+}
diff --git a/internal/pkg/afrouter/cluster.go b/internal/pkg/afrouter/cluster.go
new file mode 100644
index 0000000..859d92f
--- /dev/null
+++ b/internal/pkg/afrouter/cluster.go
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2019-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 afrouter
+
+import (
+	"errors"
+	"fmt"
+	"github.com/google/uuid"
+	"github.com/opencord/voltha-go/common/log"
+	"google.golang.org/grpc"
+)
+
+var clusters = make(map[string]*cluster)
+
+// cluster a collection of HA backends
+type cluster struct {
+	name string
+	//backends map[string]*backend
+	backends     []*backend
+	backendIDMap map[*backend]int
+}
+
+//TODO: Move the backend type (active/active etc) to the cluster
+// level. All backends should really be of the same type.
+// Create a new backend cluster
+func newBackendCluster(conf *BackendClusterConfig) (*cluster, error) {
+	var err error = nil
+	var rtrn_err = false
+	var be *backend
+	log.Debugf("Creating a backend cluster with %v", conf)
+	// Validate the configuration
+	if conf.Name == "" {
+		log.Error("A backend cluster must have a name")
+		rtrn_err = true
+	}
+	//bc :=  &cluster{name:conf.Name,backends:make(map[string]*backend)}
+	bc := &cluster{name: conf.Name, backendIDMap: make(map[*backend]int)}
+	clusters[bc.name] = bc
+	idx := 0
+	for _, bec := range conf.Backends {
+		if bec.Name == "" {
+			log.Errorf("A backend must have a name in cluster %s\n", conf.Name)
+			rtrn_err = true
+		}
+		if be, err = newBackend(&bec, conf.Name); err != nil {
+			log.Errorf("Error creating backend %s", bec.Name)
+			rtrn_err = true
+		}
+		bc.backends = append(bc.backends, be)
+		bc.backendIDMap[bc.backends[idx]] = idx
+		idx++
+	}
+	if rtrn_err {
+		return nil, errors.New("Error creating backend(s)")
+	}
+	return bc, nil
+}
+
+func (c *cluster) getBackend(name string) *backend {
+	for _, v := range c.backends {
+		if v.name == name {
+			return v
+		}
+	}
+	return nil
+}
+
+func (c *cluster) allocateSerialNumber() string {
+	return uuid.New().String()
+}
+
+func (c *cluster) nextBackend(be *backend, seq backendSequence) (*backend, error) {
+	switch seq {
+	case BackendSequenceRoundRobin: // Round robin
+		in := be
+		// If no backend is found having a connection
+		// then return nil.
+		if be == nil {
+			log.Debug("Previous backend is nil")
+			be = c.backends[0]
+			in = be
+			if be.NumOpenConnections() != 0 {
+				return be, nil
+			}
+		}
+		for {
+			log.Debugf("Requesting a new backend starting from %s", be.name)
+			cur := c.backendIDMap[be]
+			cur++
+			if cur >= len(c.backends) {
+				cur = 0
+			}
+			log.Debugf("Next backend is %d:%s", cur, c.backends[cur].name)
+			if c.backends[cur].NumOpenConnections() > 0 {
+				return c.backends[cur], nil
+			}
+			if c.backends[cur] == in {
+				err := fmt.Errorf("No backend with open connections found")
+				log.Debug(err)
+				return nil, err
+			}
+			be = c.backends[cur]
+			log.Debugf("Backend '%s' has no open connections, trying next", c.backends[cur].name)
+		}
+	default: // Invalid, default to round robin
+		log.Errorf("Invalid backend sequence %d. Defaulting to round robin", seq)
+		return c.nextBackend(be, BackendSequenceRoundRobin)
+	}
+}
+
+func (c *cluster) handler(srv interface{}, serverStream grpc.ServerStream, r Router, methodInfo methodDetails,
+	mk string, mv string) error {
+	//func (c *cluster) handler(nbR * nbRequest) error {
+
+	// The final backend cluster needs to be determined here. With non-affinity routed backends it could
+	// just be determined here and for affinity routed backends the first message must be received
+	// before the backend is determined. In order to keep things simple, the same approach is taken for
+	// now.
+
+	// Get the backend to use.
+	// Allocate the requestFrame here since it holds the "context" of this communication
+	nf := &requestFrame{router: r, methodInfo: methodInfo, serialNo: c.allocateSerialNumber(), metaKey: mk, metaVal: mv}
+	log.Debugf("Nb frame allocate with method %s", nf.methodInfo.method)
+
+	if be, err := c.assignBackend(serverStream, nf); err != nil {
+		// At this point, no backend streams have been initiated
+		// so just return the error.
+		return err
+	} else {
+		log.Debugf("Backend '%s' selected", be.name)
+		// Allocate a responseFrame here because it might be needed for return value intercept
+		sf := &responseFrame{router: r, backend: be, method: nf.methodInfo.method, metaKey: mk, metaVal: mv}
+		log.Debugf("Sb frame allocated with router %s", r.Name())
+		return be.handler(srv, serverStream, nf, sf)
+	}
+}
+
+func (c *cluster) assignBackend(src grpc.ServerStream, f *requestFrame) (*backend, error) {
+	// Receive the first message from the server. This calls the assigned codec in which
+	// Unmarshal gets executed. That will use the assigned router to select a backend
+	// and add it to the frame
+	if err := src.RecvMsg(f); err != nil {
+		return nil, err
+	}
+	// Check that the backend was routable and actually has connections open.
+	// If it doesn't then return a nil backend to indicate this
+	if f.backend == nil {
+		err := fmt.Errorf("Unable to route method '%s'", f.methodInfo.method)
+		log.Error(err)
+		return nil, err
+	} else if len(f.backend.openConns) == 0 {
+		err := fmt.Errorf("No open connections on backend '%s'", f.backend.name)
+		log.Error(err)
+		return f.backend, err
+	}
+	log.Debugf("Assigned backend %s", f.backend.name)
+	return f.backend, nil
+}
diff --git a/internal/pkg/afrouter/codec.go b/internal/pkg/afrouter/codec.go
new file mode 100644
index 0000000..278fc0a
--- /dev/null
+++ b/internal/pkg/afrouter/codec.go
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2018-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 afrouter
+
+import (
+	"fmt"
+	"github.com/golang/protobuf/proto"
+	"github.com/opencord/voltha-go/common/log"
+	"google.golang.org/grpc"
+)
+
+func Codec() grpc.Codec {
+	return CodecWithParent(&protoCodec{})
+}
+
+func CodecWithParent(parent grpc.Codec) grpc.Codec {
+	return &transparentRoutingCodec{parent}
+}
+
+type transparentRoutingCodec struct {
+	parentCodec grpc.Codec
+}
+
+// responseFrame is a frame being "returned" to whomever established the connection
+type responseFrame struct {
+	payload []byte
+	router  Router
+	method  string
+	backend *backend
+	metaKey string
+	metaVal string
+}
+
+// requestFrame is a frame coming in from whomever established the connection
+type requestFrame struct {
+	payload    []byte
+	router     Router
+	backend    *backend
+	connection *connection // optional, if the router preferred one connection over another
+	err        error
+	methodInfo methodDetails
+	serialNo   string
+	metaKey    string
+	metaVal    string
+}
+
+func (cdc *transparentRoutingCodec) Marshal(v interface{}) ([]byte, error) {
+	switch t := v.(type) {
+	case *responseFrame:
+		return t.payload, nil
+	case *requestFrame:
+		return t.payload, nil
+	default:
+		return cdc.parentCodec.Marshal(v)
+	}
+}
+
+func (cdc *transparentRoutingCodec) Unmarshal(data []byte, v interface{}) error {
+	switch t := v.(type) {
+	case *responseFrame:
+		t.payload = data
+		// This is where the affinity is established on a northbound response
+		t.router.ReplyHandler(v)
+		return nil
+	case *requestFrame:
+		t.payload = data
+		// This is were the afinity value is pulled from the payload
+		// and the backend selected.
+		t.backend, t.connection = t.router.Route(v)
+		name := "<nil>"
+		if t.backend != nil {
+			name = t.backend.name
+		}
+		log.Debugf("Routing returned %s for method %s", name, t.methodInfo.method)
+
+		return nil
+	default:
+		return cdc.parentCodec.Unmarshal(data, v)
+	}
+}
+
+func (cdc *transparentRoutingCodec) String() string {
+	return fmt.Sprintf("%s", cdc.parentCodec.String())
+}
+
+// protoCodec is a Codec implementation with protobuf. It is the default Codec for gRPC.
+type protoCodec struct{}
+
+func (protoCodec) Marshal(v interface{}) ([]byte, error) {
+	return proto.Marshal(v.(proto.Message))
+}
+
+func (protoCodec) Unmarshal(data []byte, v interface{}) error {
+	return proto.Unmarshal(data, v.(proto.Message))
+}
+
+func (protoCodec) String() string {
+	return "protoCodec"
+}
diff --git a/internal/pkg/afrouter/config.go b/internal/pkg/afrouter/config.go
new file mode 100644
index 0000000..6008199
--- /dev/null
+++ b/internal/pkg/afrouter/config.go
@@ -0,0 +1,258 @@
+/*
+ * Copyright 2018-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 afrouter
+
+// Command line parameters and parsing
+import (
+	"encoding/json"
+	"errors"
+	"flag"
+	"fmt"
+	"github.com/golang/protobuf/protoc-gen-go/descriptor"
+	"github.com/opencord/voltha-go/common/log"
+	"io/ioutil"
+	"os"
+	"path"
+)
+
+func ParseCmd() (*Configuration, error) {
+	config := &Configuration{}
+	cmdParse := flag.NewFlagSet(path.Base(os.Args[0]), flag.ContinueOnError)
+	config.ConfigFile = cmdParse.String("config", "arouter.json", "The configuration file for the affinity router")
+	config.LogLevel = cmdParse.Int("logLevel", 0, "The log level for the affinity router")
+	config.GrpcLog = cmdParse.Bool("grpclog", false, "Enable GRPC logging")
+	config.DisplayVersionOnly = cmdParse.Bool("version", false, "Print version information and exit")
+
+	err := cmdParse.Parse(os.Args[1:])
+	if err != nil {
+		//return err
+		return nil, errors.New("Error parsing the command line")
+	}
+	//if(!cmdParse.Parsed()) {
+	//}
+	return config, nil
+}
+
+// Configuration file loading and parsing
+type Configuration struct {
+	ConfigFile         *string
+	LogLevel           *int
+	GrpcLog            *bool
+	DisplayVersionOnly *bool
+	Servers            []ServerConfig         `json:"servers"`
+	Ports              PortConfig             `json:"ports"`
+	ServerCertificates ServerCertConfig       `json:"serverCertificates"`
+	ClientCertificates ClientCertConfig       `json:"clientCertificates"`
+	BackendClusters    []BackendClusterConfig `json:"backend_clusters"`
+	Routers            []RouterConfig         `json:"routers"`
+	Api                ApiConfig
+}
+
+type RouterConfig struct {
+	Name            string        `json:"name"`
+	ProtoService    string        `json:"service"`
+	ProtoPackage    string        `json:"package"`
+	ProtoFile       string        `json:"proto_descriptor"`
+	Routes          []RouteConfig `json:"routes"`
+	protoDescriptor descriptor.FileDescriptorSet
+}
+
+type RouteConfig struct {
+	Name             string           `json:"name"`
+	Type             routeType        `json:"type"`
+	Association      associationType  `json:"association"`
+	RouteField       string           `json:"routing_field"`
+	Methods          []string         `json:"methods"` // The GRPC methods to route using the route field
+	NbBindingMethods []string         `json:"nb_binding_methods"`
+	BackendCluster   string           `json:"backend_cluster"`
+	Binding          BindingConfig    `json:"binding"`
+	Overrides        []OverrideConfig `json:"overrides"`
+	backendCluster   *BackendClusterConfig
+}
+
+type BindingConfig struct {
+	Type        string          `json:"type"`
+	Field       string          `json:"field"`
+	Method      string          `json:"method"`
+	Association associationType `json:"association"`
+}
+
+type OverrideConfig struct {
+	Methods    []string `json:"methods"`
+	Method     string   `json:"method"`
+	RouteField string   `json:"routing_field"`
+}
+
+// Backend configuration
+
+type BackendClusterConfig struct {
+	Name     string          `json:"name"`
+	Backends []BackendConfig `json:"backends"`
+}
+
+type BackendConfig struct {
+	Name        string             `json:"name"`
+	Type        backendType        `json:"type"`
+	Association AssociationConfig  `json:"association"`
+	Connections []ConnectionConfig `json:"connections"`
+}
+
+type AssociationConfig struct {
+	Strategy associationStrategy `json:"strategy"`
+	Location associationLocation `json:"location"`
+	Field    string              `json:"field"`
+	Key      string              `json:"key"`
+}
+
+type ConnectionConfig struct {
+	Name string `json:"name"`
+	Addr string `json:"addr"`
+	Port string `json:"port"`
+}
+
+// Server configuration
+
+type ServerConfig struct {
+	Name    string          `json:"name"`
+	Port    uint            `json:"port"`
+	Addr    string          `json:"address"`
+	Type    string          `json:"type"`
+	Routers []RouterPackage `json:"routers"`
+	routers map[string]*RouterConfig
+}
+
+type RouterPackage struct {
+	Router  string `json:"router"`
+	Package string `json:"package"`
+}
+
+// Port configuration
+type PortConfig struct {
+	GrpcPort             uint `json:"grpcPort"`
+	StreamingGrpcPort    uint `json:"streamingGrpcPort"`
+	TlsGrpcPort          uint `json:"tlsGrpcPort"`
+	TlsStreamingGrpcPort uint `json:"tlsStreamingGrpcPort"`
+	ControlPort          uint `json:"controlPort"`
+}
+
+// Server Certificate configuration
+type ServerCertConfig struct {
+	GrpcCert string `json:"grpcCertificate"` // File path to the certificate file
+	GrpcKey  string `json:"grpcKey"`         // File path to the key file
+	GrpcCsr  string `json:"grpcCsr"`         // File path to the CSR file
+}
+
+// Client Certificate configuration
+type ClientCertConfig struct {
+	GrpcCert string `json:"grpcCertificate"` // File path to the certificate file
+	GrpcKey  string `json:"grpcKey"`         // File path to the key file
+	GrpcCsr  string `json:"grpcCsr"`         // File path to the CSR file
+}
+
+// Api configuration
+type ApiConfig struct {
+	Addr string `json:"address"`
+	Port uint   `json:"port"`
+}
+
+func (conf *Configuration) LoadConfig() error {
+
+	configF, err := os.Open(*conf.ConfigFile)
+	log.Info("Loading configuration from: ", *conf.ConfigFile)
+	if err != nil {
+		log.Error(err)
+		return err
+	}
+
+	defer configF.Close()
+
+	configBytes, err := ioutil.ReadAll(configF)
+	if err != nil {
+		log.Error(err)
+		return err
+	}
+
+	if err := json.Unmarshal(configBytes, conf); err != nil {
+		log.Errorf("Unmarshaling of the configuratino file failed: %v", err)
+		return err
+	}
+
+	// Now resolve references to different config objects in the
+	// config file. Currently there are 2 possible references
+	// to resolve: referecnes to routers in the servers, and
+	// references to backend_cluster in the routers.
+
+	// Resolve router references for the servers
+	log.Debug("Resolving references in the config file")
+	for k := range conf.Servers {
+		//s.routers =make(map[string]*RouterConfig)
+		conf.Servers[k].routers = make(map[string]*RouterConfig)
+		for _, rPkg := range conf.Servers[k].Routers {
+			var found = false
+			// Locate the router "r" in the top lever Routers array
+			log.Debugf("Resolving router reference to router '%s' from server '%s'", rPkg.Router, conf.Servers[k].Name)
+			for rk := range conf.Routers {
+				if conf.Routers[rk].Name == rPkg.Router && !found {
+					log.Debugf("Reference to router '%s' found for package '%s'", rPkg.Router, rPkg.Package)
+					conf.Servers[k].routers[rPkg.Package] = &conf.Routers[rk]
+					found = true
+				} else if conf.Routers[rk].Name == rPkg.Router && found {
+					if _, ok := conf.Servers[k].routers[rPkg.Package]; !ok {
+						log.Debugf("Reference to router '%s' found for package '%s'", rPkg.Router, rPkg.Package)
+						conf.Servers[k].routers[rPkg.Package] = &conf.Routers[rk]
+					} else {
+						err := errors.New(fmt.Sprintf("Duplicate router '%s' defined for package '%s'", rPkg.Router, rPkg.Package))
+						log.Error(err)
+						return err
+					}
+				}
+			}
+			if !found {
+				err := errors.New(fmt.Sprintf("Router %s for server %s not found in config", conf.Servers[k].Name, rPkg.Router))
+				log.Error(err)
+				return err
+			}
+		}
+	}
+
+	// Resolve backend references for the routers
+	for rk, rv := range conf.Routers {
+		for rtk, rtv := range rv.Routes {
+			var found = false
+			log.Debugf("Resolving backend reference to %s from router %s", rtv.BackendCluster, rv.Name)
+			for bek, bev := range conf.BackendClusters {
+				log.Debugf("Checking cluster %s", conf.BackendClusters[bek].Name)
+				if rtv.BackendCluster == bev.Name && !found {
+					conf.Routers[rk].Routes[rtk].backendCluster = &conf.BackendClusters[bek]
+					found = true
+				} else if rtv.BackendCluster == bev.Name && found {
+					err := errors.New(fmt.Sprintf("Duplicate backend defined, %s", conf.BackendClusters[bek].Name))
+					log.Error(err)
+					return err
+				}
+			}
+			if !found {
+				err := errors.New(fmt.Sprintf("Backend %s for router %s not found in config",
+					rtv.BackendCluster, rv.Name))
+				log.Error(err)
+				return err
+			}
+		}
+	}
+
+	return nil
+}
diff --git a/internal/pkg/afrouter/connection.go b/internal/pkg/afrouter/connection.go
new file mode 100644
index 0000000..dcdb8d6
--- /dev/null
+++ b/internal/pkg/afrouter/connection.go
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2019-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 afrouter
+
+import (
+	"context"
+	"github.com/opencord/voltha-go/common/log"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/connectivity"
+	"time"
+)
+
+// connection represents a connection to a single backend
+type connection struct {
+	backend *backend
+	name    string
+	addr    string
+	port    string
+	ctx     context.Context
+	close   context.CancelFunc
+}
+
+func (cn *connection) connect() {
+	for {
+		log.Infof("Connecting to %s with addr: %s and port %s", cn.name, cn.addr, cn.port)
+		// Dial doesn't block, it just returns and continues connecting in the background.
+		// Check back later to confirm and increase the connection count.
+
+		var err error
+		conn, err := grpc.Dial(cn.addr+":"+cn.port, grpc.WithCodec(Codec()), grpc.WithInsecure(), grpc.WithBackoffMaxDelay(time.Second*15))
+		if err != nil {
+			log.Fatalf("Dialing connection %v:%v", cn, err)
+		}
+
+		log.Debugf("Starting the connection monitor for '%s'", cn.name)
+		cn.monitor(conn)
+		conn.Close()
+
+		select {
+		case <-cn.ctx.Done():
+			return
+		default:
+		}
+	}
+}
+
+func (cn *connection) monitor(conn *grpc.ClientConn) {
+	be := cn.backend
+	log.Debugf("Setting up monitoring for backend %s", be.name)
+	state := connectivity.Idle
+monitorLoop:
+	for {
+		if !conn.WaitForStateChange(cn.ctx, state) {
+			log.Debugf("Context canceled for connection '%s' on backend '%s'", cn.name, be.name)
+			break monitorLoop // connection closed
+		}
+
+		if newState := conn.GetState(); newState != state {
+			previousState := state
+			state = newState
+
+			if previousState == connectivity.Ready {
+				be.decConn(cn)
+				log.Infof("Lost connection '%s' on backend '%s'", cn.name, be.name)
+			}
+
+			switch state {
+			case connectivity.Ready:
+				log.Infof("Connection '%s' on backend '%s' becomes ready", cn.name, be.name)
+				be.incConn(cn, conn)
+			case connectivity.TransientFailure, connectivity.Connecting:
+				// we don't log these, to avoid spam
+			case connectivity.Shutdown:
+				// the connection was closed
+				log.Infof("Shutdown for connection '%s' on backend '%s'", cn.name, be.name)
+				break monitorLoop
+			case connectivity.Idle:
+				// This can only happen if the server sends a GoAway. This can
+				// only happen if the server has modified MaxConnectionIdle from
+				// its default of infinity. The only solution here is to close the
+				// connection and keepTrying()?
+				//TODO: Read the grpc source code to see if there's a different approach
+				log.Errorf("Server sent 'GoAway' on connection '%s' on backend '%s'", cn.name, be.name)
+				break monitorLoop
+			}
+		}
+	}
+}
diff --git a/internal/pkg/afrouter/enums.go b/internal/pkg/afrouter/enums.go
new file mode 100644
index 0000000..1847191
--- /dev/null
+++ b/internal/pkg/afrouter/enums.go
@@ -0,0 +1,202 @@
+/*
+ * Copyright 2019-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 afrouter
+
+import (
+	"encoding/json"
+	"fmt"
+)
+
+type backendType int
+
+const (
+	BackendUndefined backendType = iota
+	BackendActiveActive
+	BackendSingleServer
+)
+
+var stringToBeType = map[string]backendType{"active_active": BackendActiveActive, "server": BackendSingleServer}
+var beTypeToString = map[backendType]string{BackendActiveActive: "active_active", BackendSingleServer: "server"}
+
+func (t backendType) MarshalJSON() ([]byte, error) {
+	if t == BackendUndefined {
+		return json.Marshal(nil)
+	}
+	if str, have := beTypeToString[t]; have {
+		return json.Marshal(str)
+	}
+	return nil, fmt.Errorf("unknown %T '%d'", t, t)
+}
+
+func (t *backendType) UnmarshalJSON(b []byte) error {
+	var str string
+	if err := json.Unmarshal(b, &str); err != nil {
+		return err
+	}
+	var have bool
+	if *t, have = stringToBeType[str]; !have {
+		return fmt.Errorf("invalid %T %s", *t, str)
+	}
+	return nil
+}
+
+type associationLocation int
+
+const (
+	AssociationLocationUndefined associationLocation = iota
+	AssociationLocationHeader
+	AssociationLocationProtobuf
+)
+
+var stringToAlType = map[string]associationLocation{"header": AssociationLocationHeader, "protobuf": AssociationLocationProtobuf}
+var alTypeToString = map[associationLocation]string{AssociationLocationHeader: "header", AssociationLocationProtobuf: "protobuf"}
+
+func (t associationLocation) MarshalJSON() ([]byte, error) {
+	if t == AssociationLocationUndefined {
+		return json.Marshal(nil)
+	}
+	if str, have := alTypeToString[t]; have {
+		return json.Marshal(str)
+	}
+	return nil, fmt.Errorf("unknown %T '%d'", t, t)
+}
+
+func (t *associationLocation) UnmarshalJSON(b []byte) error {
+	var str string
+	if err := json.Unmarshal(b, &str); err != nil {
+		return err
+	}
+	var have bool
+	if *t, have = stringToAlType[str]; !have {
+		return fmt.Errorf("invalid %T %s", *t, str)
+	}
+	return nil
+}
+
+type associationStrategy int
+
+const (
+	AssociationStrategyUndefined associationStrategy = iota
+	AssociationStrategySerialNo
+)
+
+var stringToAsType = map[string]associationStrategy{"serial_number": AssociationStrategySerialNo}
+var asTypeToString = map[associationStrategy]string{AssociationStrategySerialNo: "serial_number"}
+
+func (t associationStrategy) MarshalJSON() ([]byte, error) {
+	if t == AssociationStrategyUndefined {
+		return json.Marshal(nil)
+	}
+	if str, have := asTypeToString[t]; have {
+		return json.Marshal(str)
+	}
+	return nil, fmt.Errorf("unknown %T '%d'", t, t)
+}
+
+func (t *associationStrategy) UnmarshalJSON(b []byte) error {
+	var str string
+	if err := json.Unmarshal(b, &str); err != nil {
+		return err
+	}
+	var have bool
+	if *t, have = stringToAsType[str]; !have {
+		return fmt.Errorf("invalid %T %s", *t, str)
+	}
+	return nil
+}
+
+type backendSequence int
+
+const (
+	BackendSequenceRoundRobin backendSequence = iota
+)
+
+type routeType int
+
+const (
+	RouteTypeUndefined routeType = iota
+	RouteTypeRpcAffinityMessage
+	RouteTypeRpcAffinityHeader
+	RouteTypeBinding
+	RouteTypeRoundRobin
+	RouteTypeSource
+)
+
+// String names for display in error messages.
+var stringToRouteType = map[string]routeType{"rpc_affinity_message": RouteTypeRpcAffinityMessage, "rpc_affinity_header": RouteTypeRpcAffinityHeader, "binding": RouteTypeBinding, "round_robin": RouteTypeRoundRobin, "source": RouteTypeSource}
+var routeTypeToString = map[routeType]string{RouteTypeRpcAffinityMessage: "rpc_affinity_message", RouteTypeRpcAffinityHeader: "rpc_affinity_header", RouteTypeBinding: "binding", RouteTypeRoundRobin: "round_robin", RouteTypeSource: "source"}
+
+func (t routeType) String() string {
+	if str, have := routeTypeToString[t]; have {
+		return str
+	}
+	return fmt.Sprintf("%T(%d)", t, t)
+}
+
+func (t routeType) MarshalJSON() ([]byte, error) {
+	if t == RouteTypeUndefined {
+		return json.Marshal(nil)
+	}
+	if str, have := routeTypeToString[t]; have {
+		return json.Marshal(str)
+	}
+	return nil, fmt.Errorf("unknown %T '%d'", t, t)
+}
+
+func (t *routeType) UnmarshalJSON(b []byte) error {
+	var str string
+	if err := json.Unmarshal(b, &str); err != nil {
+		return err
+	}
+	var have bool
+	if *t, have = stringToRouteType[str]; !have {
+		return fmt.Errorf("invalid %T %s", *t, str)
+	}
+	return nil
+}
+
+type associationType int
+
+const (
+	AssociationUndefined associationType = iota
+	AssociationRoundRobin
+)
+
+var stringToAssociationType = map[string]associationType{"round_robin": AssociationRoundRobin}
+var associationTypeToString = map[associationType]string{AssociationRoundRobin: "round_robin"}
+
+func (t associationType) MarshalJSON() ([]byte, error) {
+	if t == AssociationUndefined {
+		return json.Marshal(nil)
+	}
+	if str, have := associationTypeToString[t]; have {
+		return json.Marshal(str)
+	}
+	return nil, fmt.Errorf("unknown %T '%d'", t, t)
+}
+
+func (t *associationType) UnmarshalJSON(b []byte) error {
+	var str string
+	if err := json.Unmarshal(b, &str); err != nil {
+		return err
+	}
+	var have bool
+	if *t, have = stringToAssociationType[str]; !have {
+		return fmt.Errorf("invalid %T %s", *t, str)
+	}
+	return nil
+}
diff --git a/internal/pkg/afrouter/method-details.go b/internal/pkg/afrouter/method-details.go
new file mode 100644
index 0000000..ad05121
--- /dev/null
+++ b/internal/pkg/afrouter/method-details.go
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2019-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 afrouter
+
+import (
+	"github.com/opencord/voltha-go/common/log"
+	"regexp"
+)
+
+type methodDetails struct {
+	all     string
+	pkg     string
+	service string
+	method  string
+}
+
+// The compiled regex to extract the package/service/method
+var mthdSlicer = regexp.MustCompile(`^/([a-zA-Z][a-zA-Z0-9]+)\.([a-zA-Z][a-zA-Z0-9]+)/([a-zA-Z][a-zA-Z0-9]+)`)
+
+func newMethodDetails(fullMethodName string) methodDetails {
+	// The full method name is structured as follows:
+	// <package name>.<service>/<method>
+	mthdSlice := mthdSlicer.FindStringSubmatch(fullMethodName)
+	if mthdSlice == nil {
+		log.Errorf("Faled to slice full method %s, result: %v", fullMethodName, mthdSlice)
+	} else {
+		log.Debugf("Sliced full method %s: %v", fullMethodName, mthdSlice)
+	}
+	return methodDetails{
+		all:     mthdSlice[0],
+		pkg:     mthdSlice[1],
+		service: mthdSlice[2],
+		method:  mthdSlice[3],
+	}
+}
diff --git a/internal/pkg/afrouter/method-router.go b/internal/pkg/afrouter/method-router.go
new file mode 100644
index 0000000..2916edf
--- /dev/null
+++ b/internal/pkg/afrouter/method-router.go
@@ -0,0 +1,215 @@
+/*
+ * Copyright 2018-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 afrouter
+
+import (
+	"errors"
+	"fmt"
+	"github.com/golang/protobuf/proto"
+	"github.com/opencord/voltha-go/common/log"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/metadata"
+	"io/ioutil"
+)
+
+const NoMeta = "nometa"
+
+type MethodRouter struct {
+	name            string
+	service         string
+	methodRouter    map[string]map[string]Router // map of [metadata][method]
+	methodStreaming map[string]streamingDirections
+}
+
+type streamingDirections struct {
+	request  bool
+	response bool
+}
+
+func newMethodRouter(config *RouterConfig) (Router, error) {
+	// Load the protobuf descriptor file
+	fb, err := ioutil.ReadFile(config.ProtoFile)
+	if err != nil {
+		log.Errorf("Could not open proto file '%s'", config.ProtoFile)
+		return nil, err
+	}
+	if err := proto.Unmarshal(fb, &config.protoDescriptor); err != nil {
+		log.Errorf("Could not unmarshal %s, %v", "proto.pb", err)
+		return nil, err
+	}
+
+	mr := MethodRouter{
+		name:    config.Name,
+		service: config.ProtoService,
+		methodRouter: map[string]map[string]Router{
+			NoMeta: make(map[string]Router), // For routes not needing metadata (all except binding at this time)
+		},
+		methodStreaming: make(map[string]streamingDirections),
+	}
+	log.Debugf("Processing MethodRouter config %v", *config)
+
+	for _, file := range config.protoDescriptor.File {
+		if *file.Package == config.ProtoPackage {
+			for _, service := range file.Service {
+				if *service.Name == config.ProtoService {
+					for _, method := range service.Method {
+						if clientStreaming, serverStreaming := method.ClientStreaming != nil && *method.ClientStreaming, method.ServerStreaming != nil && *method.ServerStreaming; clientStreaming || serverStreaming {
+							mr.methodStreaming[*method.Name] = streamingDirections{
+								request:  clientStreaming,
+								response: serverStreaming,
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+
+	if len(config.Routes) == 0 {
+		return nil, errors.New(fmt.Sprintf("Router %s must have at least one route", config.Name))
+	}
+	for _, rtv := range config.Routes {
+		//log.Debugf("Processing route: %v",rtv)
+		var idx1 string
+		r, err := newSubRouter(config, &rtv)
+		if err != nil {
+			return nil, err
+		}
+		if rtv.Type == RouteTypeBinding {
+			idx1 = rtv.Binding.Field
+			if _, ok := mr.methodRouter[idx1]; !ok { // /First attempt on this key
+				mr.methodRouter[idx1] = make(map[string]Router)
+			}
+		} else {
+			idx1 = NoMeta
+		}
+		switch len(rtv.Methods) {
+		case 0:
+			return nil, errors.New(fmt.Sprintf("Route for router %s must have at least one method", config.Name))
+		case 1:
+			if rtv.Methods[0] == "*" {
+				return r, nil
+			} else {
+				log.Debugf("Setting router '%s' for single method '%s'", r.Name(), rtv.Methods[0])
+				if _, ok := mr.methodRouter[idx1][rtv.Methods[0]]; !ok {
+					mr.methodRouter[idx1][rtv.Methods[0]] = r
+				} else {
+					err := errors.New(fmt.Sprintf("Attempt to define method %s for 2 routes: %s & %s", rtv.Methods[0],
+						r.Name(), mr.methodRouter[idx1][rtv.Methods[0]].Name()))
+					log.Error(err)
+					return mr, err
+				}
+			}
+		default:
+			for _, m := range rtv.Methods {
+				log.Debugf("Processing Method %s", m)
+				if _, ok := mr.methodRouter[idx1][m]; !ok {
+					log.Debugf("Setting router '%s' for method '%s'", r.Name(), m)
+					mr.methodRouter[idx1][m] = r
+				} else {
+					err := errors.New(fmt.Sprintf("Attempt to define method %s for 2 routes: %s & %s", m, r.Name(), mr.methodRouter[idx1][m].Name()))
+					log.Error(err)
+					return mr, err
+				}
+			}
+		}
+	}
+
+	return mr, nil
+}
+
+func (mr MethodRouter) Name() string {
+	return mr.name
+}
+
+func (mr MethodRouter) Service() string {
+	return mr.service
+}
+
+func (mr MethodRouter) GetMetaKeyVal(serverStream grpc.ServerStream) (string, string, error) {
+	var rtrnK = NoMeta
+	var rtrnV = ""
+
+	// Get the metadata from the server stream
+	md, ok := metadata.FromIncomingContext(serverStream.Context())
+	if !ok {
+		return rtrnK, rtrnV, errors.New("Could not get a server stream metadata")
+	}
+
+	// Determine if one of the method routing keys exists in the metadata
+	for k := range mr.methodRouter {
+		if _, ok := md[k]; ok {
+			rtrnV = md[k][0]
+			rtrnK = k
+			break
+		}
+	}
+	return rtrnK, rtrnV, nil
+
+}
+
+func (mr MethodRouter) ReplyHandler(sel interface{}) error {
+	switch sl := sel.(type) {
+	case *responseFrame:
+		if r, ok := mr.methodRouter[NoMeta][sl.method]; ok {
+			return r.ReplyHandler(sel)
+		}
+		return errors.New("MethodRouter.ReplyHandler called with unknown meta or method")
+	default:
+		return errors.New("MethodRouter.ReplyHandler called with non-reponseFrame")
+	}
+}
+
+func (mr MethodRouter) Route(sel interface{}) (*backend, *connection) {
+	switch sl := sel.(type) {
+	case *requestFrame:
+		if r, ok := mr.methodRouter[sl.metaKey][sl.methodInfo.method]; ok {
+			return r.Route(sel)
+		}
+		sl.err = fmt.Errorf("MethodRouter.Route unable to resolve meta %s, method %s", sl.metaKey, sl.methodInfo.method)
+		log.Error(sl.err)
+		return nil, nil
+	default:
+		log.Errorf("Internal: invalid data type in Route call %v", sel)
+		return nil, nil
+	}
+}
+
+func (mr MethodRouter) IsStreaming(method string) (bool, bool) {
+	streamingDirections := mr.methodStreaming[method]
+	return streamingDirections.request, streamingDirections.response
+}
+
+func (mr MethodRouter) BackendCluster(mthd string, metaKey string) (*cluster, error) {
+	if r, ok := mr.methodRouter[metaKey][mthd]; ok {
+		return r.BackendCluster(mthd, metaKey)
+	}
+	err := errors.New(fmt.Sprintf("No backend cluster exists for method '%s' using meta key '%s'", mthd, metaKey))
+	log.Error(err)
+	return nil, err
+}
+
+func (mr MethodRouter) FindBackendCluster(beName string) *cluster {
+	for _, meta := range mr.methodRouter {
+		for _, r := range meta {
+			if rtrn := r.FindBackendCluster(beName); rtrn != nil {
+				return rtrn
+			}
+		}
+	}
+	return nil
+}
diff --git a/internal/pkg/afrouter/method-router_test.go b/internal/pkg/afrouter/method-router_test.go
new file mode 100644
index 0000000..2e72f1c
--- /dev/null
+++ b/internal/pkg/afrouter/method-router_test.go
@@ -0,0 +1,396 @@
+/*
+ * Portions copyright 2019-present Open Networking Foundation
+ * Original copyright 2019-present Ciena Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the"github.com/stretchr/testify/assert" "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 afrouter
+
+import (
+	"fmt"
+	"github.com/golang/protobuf/proto"
+	"github.com/opencord/voltha-go/common/log"
+	common_pb "github.com/opencord/voltha-protos/go/common"
+	voltha_pb "github.com/opencord/voltha-protos/go/voltha"
+	"github.com/stretchr/testify/assert"
+	"google.golang.org/grpc"
+	"testing"
+)
+
+const (
+	METHOD_ROUTER_PROTOFILE = "../../../vendor/github.com/opencord/voltha-protos/go/voltha.pb"
+)
+
+// Unit test initialization
+func init() {
+	// Logger must be configured or bad things happen
+	log.SetDefaultLogger(log.JSON, log.DebugLevel, nil)
+	log.AddPackage(log.JSON, log.WarnLevel, nil)
+}
+
+// Build an method router configuration
+func MakeMethodTestConfig(numBackends int, numConnections int) (*RouteConfig, *RouterConfig) {
+
+	var backends []BackendConfig
+	for backendIndex := 0; backendIndex < numBackends; backendIndex++ {
+		var connections []ConnectionConfig
+		for connectionIndex := 0; connectionIndex < numConnections; connectionIndex++ {
+			connectionConfig := ConnectionConfig{
+				Name: fmt.Sprintf("rw_vcore%d%d", backendIndex, connectionIndex+1),
+				Addr: "foo",
+				Port: "123",
+			}
+			connections = append(connections, connectionConfig)
+		}
+
+		backendConfig := BackendConfig{
+			Name:        fmt.Sprintf("rw_vcore%d", backendIndex),
+			Type:        BackendSingleServer,
+			Connections: connections,
+		}
+
+		backends = append(backends, backendConfig)
+	}
+
+	backendClusterConfig := BackendClusterConfig{
+		Name:     "vcore",
+		Backends: backends,
+	}
+
+	routeConfig := RouteConfig{
+		Name:             "dev_manager",
+		Type:             RouteTypeRpcAffinityMessage,
+		Association:      AssociationRoundRobin,
+		BackendCluster:   "vcore",
+		backendCluster:   &backendClusterConfig,
+		RouteField:       "id",
+		Methods:          []string{"CreateDevice", "EnableDevice"},
+		NbBindingMethods: []string{"CreateDevice"},
+	}
+
+	routerConfig := RouterConfig{
+		Name:         "vcore",
+		ProtoService: "VolthaService",
+		ProtoPackage: "voltha",
+		Routes:       []RouteConfig{routeConfig},
+		ProtoFile:    METHOD_ROUTER_PROTOFILE,
+	}
+	return &routeConfig, &routerConfig
+}
+
+// Route() requires an open connection, so pretend we have one.
+func PretendMethodOpenConnection(router Router, clusterName string, backendIndex int, connectionName string) {
+	cluster := router.FindBackendCluster(clusterName)
+
+	// Route Method expects an open connection
+	conn := cluster.backends[backendIndex].connections[connectionName]
+	cluster.backends[backendIndex].openConns[conn] = &grpc.ClientConn{}
+}
+
+// Common setup to run before each unit test
+func MethodTestSetup() {
+	// reset globals that need to be clean for each unit test
+
+	clusters = make(map[string]*cluster)
+	allRouters = make(map[string]Router)
+}
+
+// Test creation of a new AffinityRouter, and the Service(), Name(), FindBackendCluster(), and
+// methods.
+func TestMethodRouterInit(t *testing.T) {
+	MethodTestSetup()
+
+	_, routerConfig := MakeMethodTestConfig(1, 1)
+
+	router, err := newMethodRouter(routerConfig)
+
+	assert.NotNil(t, router)
+	assert.Nil(t, err)
+
+	assert.Equal(t, router.Service(), "VolthaService")
+	assert.Equal(t, router.Name(), "vcore")
+
+	cluster, err := router.BackendCluster("EnableDevice", NoMeta)
+	assert.Equal(t, cluster, clusters["vcore"])
+	assert.Nil(t, err)
+
+	assert.Equal(t, router.FindBackendCluster("vcore"), clusters["vcore"])
+}
+
+// Passing an invalid meta should return an error
+func TestMethodRouterBackendClusterInvalidMeta(t *testing.T) {
+	MethodTestSetup()
+
+	_, routerConfig := MakeMethodTestConfig(1, 1)
+
+	router, err := newMethodRouter(routerConfig)
+
+	assert.NotNil(t, router)
+	assert.Nil(t, err)
+
+	cluster, err := router.BackendCluster("EnableDevice", "wrongmeta")
+	assert.EqualError(t, err, "No backend cluster exists for method 'EnableDevice' using meta key 'wrongmeta'")
+	assert.Nil(t, cluster)
+}
+
+// Passing an invalid method name should return an error
+func TestMethodRouterBackendClusterInvalidMethod(t *testing.T) {
+	MethodTestSetup()
+
+	_, routerConfig := MakeMethodTestConfig(1, 1)
+
+	router, err := newMethodRouter(routerConfig)
+
+	assert.NotNil(t, router)
+	assert.Nil(t, err)
+
+	cluster, err := router.BackendCluster("WrongMethod", NoMeta)
+	assert.EqualError(t, err, "No backend cluster exists for method 'WrongMethod' using meta key 'nometa'")
+	assert.Nil(t, cluster)
+}
+
+// Search for a backend cluster that doesn't exist
+func TestMethodRouterFindBackendClusterNoExist(t *testing.T) {
+	MethodTestSetup()
+
+	_, routerConfig := MakeMethodTestConfig(1, 1)
+
+	router, err := newMethodRouter(routerConfig)
+
+	assert.NotNil(t, router)
+	assert.Nil(t, err)
+
+	assert.Nil(t, router.FindBackendCluster("wrong"))
+}
+
+// MethodRouter's route will cause another router's route, in this case AffinityRouter.
+func TestMethodRoute(t *testing.T) {
+	MethodTestSetup()
+
+	_, routerConfig := MakeMethodTestConfig(1, 1)
+
+	router, err := newMethodRouter(routerConfig)
+	assert.Nil(t, err)
+
+	PretendMethodOpenConnection(router, "vcore", 0, "rw_vcore01")
+
+	idMessage := &common_pb.ID{Id: "1234"}
+
+	idData, err := proto.Marshal(idMessage)
+	assert.Nil(t, err)
+
+	sel := &requestFrame{payload: idData,
+		err:        nil,
+		metaKey:    NoMeta,
+		methodInfo: newMethodDetails("/voltha.VolthaService/EnableDevice")}
+
+	backend, connection := router.Route(sel)
+
+	assert.Nil(t, sel.err)
+	assert.NotNil(t, backend)
+	assert.Equal(t, "rw_vcore0", backend.name)
+	assert.Nil(t, connection)
+
+	// Since we only have one backend, calling Route a second time should return the same one
+
+	backend, connection = router.Route(sel)
+
+	assert.Nil(t, sel.err)
+	assert.NotNil(t, backend)
+	assert.Equal(t, "rw_vcore0", backend.name)
+	assert.Nil(t, connection)
+}
+
+// Try to route to a nonexistent method
+func TestMethodRouteNonexistent(t *testing.T) {
+	MethodTestSetup()
+
+	_, routerConfig := MakeMethodTestConfig(1, 1)
+
+	router, err := newMethodRouter(routerConfig)
+	assert.Nil(t, err)
+
+	idMessage := &common_pb.ID{Id: "1234"}
+
+	idData, err := proto.Marshal(idMessage)
+	assert.Nil(t, err)
+
+	sel := &requestFrame{payload: idData,
+		err:        nil,
+		metaKey:    NoMeta,
+		methodInfo: newMethodDetails("/voltha.VolthaService/NonexistentMethod")}
+
+	backend, connection := router.Route(sel)
+
+	assert.Nil(t, backend)
+	assert.Nil(t, connection)
+
+	assert.EqualError(t, sel.err, "MethodRouter.Route unable to resolve meta nometa, method NonexistentMethod")
+}
+
+// Try to route to a nonexistent meta key
+func TestMethodRouteWrongMeta(t *testing.T) {
+	MethodTestSetup()
+
+	_, routerConfig := MakeMethodTestConfig(1, 1)
+
+	router, err := newMethodRouter(routerConfig)
+	assert.Nil(t, err)
+
+	idMessage := &common_pb.ID{Id: "1234"}
+
+	idData, err := proto.Marshal(idMessage)
+	assert.Nil(t, err)
+
+	sel := &requestFrame{payload: idData,
+		err:        nil,
+		metaKey:    "wrongkey",
+		methodInfo: newMethodDetails("/voltha.VolthaService/EnableDevice")}
+
+	backend, connection := router.Route(sel)
+
+	assert.Nil(t, backend)
+	assert.Nil(t, connection)
+
+	assert.EqualError(t, sel.err, "MethodRouter.Route unable to resolve meta wrongkey, method EnableDevice")
+}
+
+// Try to route to a the wrong type of key
+func TestMethodRouteWrongFrame(t *testing.T) {
+	MethodTestSetup()
+
+	_, routerConfig := MakeMethodTestConfig(1, 1)
+
+	router, err := newMethodRouter(routerConfig)
+	assert.Nil(t, err)
+
+	idMessage := &voltha_pb.Device{Id: "1234"}
+	idData, err := proto.Marshal(idMessage)
+	assert.Nil(t, err)
+
+	// Note that sel.backend must be set. As this is a response, it must
+	// have come from a backend and that backend must be known.
+
+	sel := &responseFrame{payload: idData,
+		metaKey: NoMeta,
+		backend: router.FindBackendCluster("vcore").backends[0],
+		method:  "CreateDevice",
+	}
+
+	// Note: Does not return any error, but does print an error message. Returns nil.
+
+	backend, connection := router.Route(sel)
+
+	assert.Nil(t, backend)
+	assert.Nil(t, connection)
+}
+
+// MethodRouter calls another Router's ReplyHandler, in this case AffinityRouter
+func TestMethodRouteReply(t *testing.T) {
+	MethodTestSetup()
+
+	_, routerConfig := MakeMethodTestConfig(1, 1)
+
+	router, err := newRouter(routerConfig)
+	assert.Nil(t, err)
+
+	aRouter := allRouters["vcoredev_manager"].(AffinityRouter)
+
+	PretendMethodOpenConnection(router, "vcore", 0, "rw_vcore01")
+
+	idMessage := &voltha_pb.Device{Id: "1234"}
+	idData, err := proto.Marshal(idMessage)
+	assert.Nil(t, err)
+
+	// Note that sel.backend must be set. As this is a response, it must
+	// have come from a backend and that backend must be known.
+
+	sel := &responseFrame{payload: idData,
+		metaKey: NoMeta,
+		backend: router.FindBackendCluster("vcore").backends[0],
+		method:  "CreateDevice",
+	}
+
+	// affinity should be unset as we have not routed yet
+	assert.Empty(t, aRouter.affinity)
+
+	err = router.ReplyHandler(sel)
+	assert.Nil(t, err)
+
+	// affinity should now be set
+	assert.NotEmpty(t, aRouter.affinity)
+	assert.Equal(t, router.FindBackendCluster("vcore").backends[0], aRouter.affinity["1234"])
+}
+
+// Call ReplyHandler with the wrong type of frame
+func TestMethodRouteReplyWrongFrame(t *testing.T) {
+	MethodTestSetup()
+
+	_, routerConfig := MakeMethodTestConfig(1, 1)
+
+	router, err := newRouter(routerConfig)
+	assert.Nil(t, err)
+
+	PretendMethodOpenConnection(router, "vcore", 0, "rw_vcore01")
+
+	idMessage := &common_pb.ID{Id: "1234"}
+
+	idData, err := proto.Marshal(idMessage)
+	assert.Nil(t, err)
+
+	sel := &requestFrame{payload: idData,
+		err:        nil,
+		metaKey:    "wrongkey",
+		methodInfo: newMethodDetails("/voltha.VolthaService/EnableDevice")}
+
+	err = router.ReplyHandler(sel)
+	assert.EqualError(t, err, "MethodRouter.ReplyHandler called with non-reponseFrame")
+}
+
+// Call ReplyHandler with an invalid method name
+func TestMethodRouteReplyWrongMethod(t *testing.T) {
+	MethodTestSetup()
+
+	_, routerConfig := MakeMethodTestConfig(1, 1)
+
+	router, err := newRouter(routerConfig)
+	assert.Nil(t, err)
+
+	PretendMethodOpenConnection(router, "vcore", 0, "rw_vcore01")
+
+	idMessage := &common_pb.ID{Id: "1234"}
+
+	idData, err := proto.Marshal(idMessage)
+	assert.Nil(t, err)
+
+	sel := &requestFrame{payload: idData,
+		err:        nil,
+		metaKey:    "wrongkey",
+		methodInfo: newMethodDetails("/voltha.VolthaService/WrongMethod")}
+
+	err = router.ReplyHandler(sel)
+	assert.EqualError(t, err, "MethodRouter.ReplyHandler called with non-reponseFrame")
+}
+
+func TestMethodIsMethodStreaming(t *testing.T) {
+	MethodTestSetup()
+
+	_, routerConfig := MakeMethodTestConfig(1, 1)
+
+	router, err := newRouter(routerConfig)
+	assert.Nil(t, err)
+
+	request, response := router.IsStreaming("EnableDevice")
+	assert.False(t, request)
+	assert.False(t, response)
+}
diff --git a/internal/pkg/afrouter/request.go b/internal/pkg/afrouter/request.go
new file mode 100644
index 0000000..8fc15aa
--- /dev/null
+++ b/internal/pkg/afrouter/request.go
@@ -0,0 +1,279 @@
+/*
+ * Copyright 2019-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 afrouter
+
+import (
+	"context"
+	"encoding/hex"
+	"errors"
+	"github.com/opencord/voltha-go/common/log"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/status"
+	"io"
+	"sync"
+)
+
+type request struct {
+	mutex                    sync.Mutex
+	activeResponseStreamOnce sync.Once
+	setResponseHeaderOnce    sync.Once
+	responseStreamMutex      sync.Mutex
+
+	streams map[string]grpc.ClientStream
+
+	requestFrameBacklog [][]byte
+	responseErrChan     chan error
+	sendClosed          bool
+
+	backend             *backend
+	ctx                 context.Context
+	serverStream        grpc.ServerStream
+	methodInfo          methodDetails
+	requestFrame        *requestFrame
+	responseFrame       *responseFrame
+	isStreamingRequest  bool
+	isStreamingResponse bool
+}
+
+var transactionNotAcquiredErrorString = status.Error(codes.Canceled, "transaction-not-acquired").Error()
+
+// catchupRequestStreamThenForwardResponseStream must be called with request.mutex pre-locked
+func (r *request) catchupRequestStreamThenForwardResponseStream(connName string, stream grpc.ClientStream) {
+	r.streams[connName] = stream
+
+	// prime new streams with any traffic they might have missed (non-streaming requests only)
+	frame := *r.requestFrame // local copy of frame
+	for _, payload := range r.requestFrameBacklog {
+		frame.payload = payload
+		if err := stream.SendMsg(&frame); err != nil {
+			log.Debugf("Error on SendMsg: %s", err.Error())
+			break
+		}
+	}
+	if r.sendClosed {
+		stream.CloseSend()
+	}
+
+	r.mutex.Unlock()
+
+	r.forwardResponseStream(connName, stream)
+}
+
+// forwardResponseStream forwards the response stream
+func (r *request) forwardResponseStream(connName string, stream grpc.ClientStream) {
+	var queuedFrames [][]byte
+	frame := *r.responseFrame
+	var err error
+	activeStream := false
+	for {
+		err = stream.RecvMsg(&frame)
+		// if this is an inactive responder, ignore everything it sends
+		if err != nil && err.Error() == transactionNotAcquiredErrorString {
+			break
+		}
+		// the first thread to reach this point (first to receive a response frame) will become the active stream
+		r.activeResponseStreamOnce.Do(func() { activeStream = true })
+		if err != nil {
+			// this can be io.EOF which is the success case
+			break
+		}
+
+		if r.isStreamingResponse {
+			// streaming response - send immediately
+			if err = r.sendResponseFrame(stream, frame); err != nil {
+				break
+			}
+		} else { // !r.isStreamingResponse
+
+			if r.isStreamingRequest { // && !r.isStreamingResponse
+				// queue the frame (only send response when the last stream closes)
+				queuedFrames = append(queuedFrames, frame.payload)
+			} else { // !r.isStreamingRequest && !r.isStreamingResponse
+
+				// only the active stream will respond
+				if activeStream { // && !r.isStreamingRequest && !r.isStreamingResponse
+					// send the response immediately
+					if err = r.sendResponseFrame(stream, frame); err != nil {
+						break
+					}
+				} else { // !activeStream && !r.isStreamingRequest && !r.isStreamingResponse
+					// just read & discard until the stream dies
+				}
+			}
+		}
+	}
+
+	log.Debugf("Closing stream to %s", connName)
+
+	// io.EOF is the success case
+	if err == io.EOF {
+		err = nil
+	}
+
+	// this double-lock sets off alarm bells in my head
+	r.backend.mutex.Lock()
+	r.mutex.Lock()
+	delete(r.streams, connName)
+	streamsLeft := len(r.streams)
+
+	// handle the case where no cores are the active responder.  Should never happen, but just in case...
+	if streamsLeft == 0 {
+		r.activeResponseStreamOnce.Do(func() { activeStream = true })
+	}
+
+	// if this the active stream (for non-streaming requests), or this is the last stream (for streaming requests)
+	if (activeStream && !r.isStreamingRequest && !r.isStreamingResponse) || (streamsLeft == 0 && (r.isStreamingRequest || r.isStreamingResponse)) {
+		// request is complete, cleanup
+		delete(r.backend.activeRequests, r)
+		r.mutex.Unlock()
+		r.backend.mutex.Unlock()
+
+		// send any queued frames we have (streaming request & !streaming response only, but no harm trying in other cases)
+		for _, payload := range queuedFrames {
+			if err != nil {
+				// if there's been an error, don't try to send anymore
+				break
+			}
+			frame.payload = payload
+			err = r.sendResponseFrame(stream, frame)
+		}
+
+		// We may have received Trailers as part of the call.
+		r.serverStream.SetTrailer(stream.Trailer())
+
+		// response stream complete
+		r.responseErrChan <- err
+	} else {
+		r.mutex.Unlock()
+		r.backend.mutex.Unlock()
+	}
+}
+
+func (r *request) sendResponseFrame(stream grpc.ClientStream, f responseFrame) error {
+	r.responseStreamMutex.Lock()
+	defer r.responseStreamMutex.Unlock()
+
+	// the header should only be set once, even if multiple streams can respond.
+	setHeader := false
+	r.setResponseHeaderOnce.Do(func() { setHeader = true })
+	if setHeader {
+		// This is a bit of a hack, but client to server headers are only readable after first client msg is
+		// received but must be written to server stream before the first msg is flushed.
+		// This is the only place to do it nicely.
+		md, err := stream.Header()
+		if err != nil {
+			return err
+		}
+		// Update the metadata for the response.
+		if f.metaKey != NoMeta {
+			if f.metaVal == "" {
+				// We could also always just do this
+				md.Set(f.metaKey, f.backend.name)
+			} else {
+				md.Set(f.metaKey, f.metaVal)
+			}
+		}
+		if err := r.serverStream.SendHeader(md); err != nil {
+			return err
+		}
+	}
+
+	log.Debugf("Response frame %s", hex.EncodeToString(f.payload))
+
+	return r.serverStream.SendMsg(&f)
+}
+
+func (r *request) sendAll(frame *requestFrame) error {
+	r.mutex.Lock()
+	if !r.isStreamingRequest {
+		// save frames of non-streaming requests, so we can catchup new streams
+		r.requestFrameBacklog = append(r.requestFrameBacklog, frame.payload)
+	}
+
+	// send to all existing streams
+	streams := make(map[string]grpc.ClientStream, len(r.streams))
+	for n, s := range r.streams {
+		streams[n] = s
+	}
+	r.mutex.Unlock()
+
+	var rtrn error
+	atLeastOne := false
+	atLeastOneSuccess := false
+	for _, stream := range streams {
+		if err := stream.SendMsg(frame); err != nil {
+			log.Debugf("Error on SendMsg: %s", err.Error())
+			rtrn = err
+		} else {
+			atLeastOneSuccess = true
+		}
+		atLeastOne = true
+	}
+	// If one of the streams succeeded, declare success
+	// if none did pick an error and return it.
+	if atLeastOne {
+		if atLeastOneSuccess {
+			return nil
+		} else {
+			return rtrn
+		}
+	} else {
+		err := errors.New("unable to send, all streams have closed")
+		log.Error(err)
+		return err
+	}
+}
+
+func (r *request) forwardRequestStream(src grpc.ServerStream) error {
+	// The frame buffer already has the results of a first
+	// RecvMsg in it so the first thing to do is to
+	// send it to the list of client streams and only
+	// then read some more.
+	frame := *r.requestFrame // local copy of frame
+	var rtrn error
+	for {
+		// Send the message to each of the backend streams
+		if err := r.sendAll(&frame); err != nil {
+			log.Debugf("SendAll failed %s", err.Error())
+			rtrn = err
+			break
+		}
+		log.Debugf("Request frame %s", hex.EncodeToString(frame.payload))
+		if err := src.RecvMsg(&frame); err != nil {
+			rtrn = err // this can be io.EOF which is happy case
+			break
+		}
+	}
+
+	r.mutex.Lock()
+	log.Debug("Closing southbound streams")
+	r.sendClosed = true
+	for _, stream := range r.streams {
+		stream.CloseSend()
+	}
+	r.mutex.Unlock()
+
+	if rtrn != io.EOF {
+		log.Debugf("s2cErr reporting %v", rtrn)
+		return rtrn
+	}
+	log.Debug("s2cErr reporting EOF")
+	// this is the successful case where the sender has encountered io.EOF, and won't be sending anymore.
+	// the clientStream>serverStream may continue sending though.
+	return nil
+}
diff --git a/internal/pkg/afrouter/round-robin-router.go b/internal/pkg/afrouter/round-robin-router.go
new file mode 100644
index 0000000..b5f031e
--- /dev/null
+++ b/internal/pkg/afrouter/round-robin-router.go
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2018-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 afrouter
+
+import (
+	"errors"
+	"fmt"
+	"github.com/opencord/voltha-go/common/log"
+	"google.golang.org/grpc"
+)
+
+type RoundRobinRouter struct {
+	name           string
+	grpcService    string
+	cluster        *cluster
+	currentBackend **backend
+}
+
+func newRoundRobinRouter(rconf *RouterConfig, config *RouteConfig) (Router, error) {
+	var err error = nil
+	var rtrn_err = false
+	// Validate the configuration
+
+	log.Debug("Creating a new round robin router")
+	// A name must exist
+	if config.Name == "" {
+		log.Error("A router 'name' must be specified")
+		rtrn_err = true
+	}
+
+	if rconf.ProtoPackage == "" {
+		log.Error("A 'package' must be specified")
+		rtrn_err = true
+	}
+
+	if rconf.ProtoService == "" {
+		log.Error("A 'service' must be specified")
+		rtrn_err = true
+	}
+
+	var bptr *backend
+	bptr = nil
+	rr := RoundRobinRouter{
+		name:           config.Name,
+		grpcService:    rconf.ProtoService,
+		currentBackend: &bptr,
+	}
+
+	// Create the backend cluster or link to an existing one
+	ok := true
+	if rr.cluster, ok = clusters[config.backendCluster.Name]; !ok {
+		if rr.cluster, err = newBackendCluster(config.backendCluster); err != nil {
+			log.Errorf("Could not create a backend for router %s", config.Name)
+			rtrn_err = true
+		}
+	}
+
+	if rtrn_err {
+		return rr, errors.New(fmt.Sprintf("Failed to create a new router '%s'", rr.name))
+	}
+
+	return rr, nil
+}
+
+func (rr RoundRobinRouter) GetMetaKeyVal(serverStream grpc.ServerStream) (string, string, error) {
+	return "", "", nil
+}
+
+func (rr RoundRobinRouter) IsStreaming(_ string) (bool, bool) {
+	panic("not implemented")
+}
+
+func (rr RoundRobinRouter) BackendCluster(s string, mk string) (*cluster, error) {
+	return rr.cluster, nil
+}
+
+func (rr RoundRobinRouter) Name() string {
+	return rr.name
+}
+
+func (rr RoundRobinRouter) Route(sel interface{}) (*backend, *connection) {
+	var err error
+	switch sl := sel.(type) {
+	case *requestFrame:
+		// Since this is a round robin router just get the next backend
+		if *rr.currentBackend, err = rr.cluster.nextBackend(*rr.currentBackend, BackendSequenceRoundRobin); err == nil {
+			return *rr.currentBackend, nil
+		} else {
+			sl.err = err
+			return nil, nil
+		}
+	default:
+		log.Errorf("Internal: invalid data type in Route call %v", sel)
+		return nil, nil
+	}
+}
+
+func (rr RoundRobinRouter) Service() string {
+	return rr.grpcService
+}
+
+func (rr RoundRobinRouter) FindBackendCluster(becName string) *cluster {
+	if becName == rr.cluster.name {
+		return rr.cluster
+	}
+	return nil
+}
+
+func (rr RoundRobinRouter) ReplyHandler(sel interface{}) error { // This is a no-op
+	return nil
+}
diff --git a/internal/pkg/afrouter/round-robin-router_test.go b/internal/pkg/afrouter/round-robin-router_test.go
new file mode 100644
index 0000000..f9bed07
--- /dev/null
+++ b/internal/pkg/afrouter/round-robin-router_test.go
@@ -0,0 +1,289 @@
+/*
+ * Portions copyright 2019-present Open Networking Foundation
+ * Original copyright 2019-present Ciena Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the"github.com/stretchr/testify/assert" "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 afrouter
+
+import (
+	"fmt"
+	"github.com/golang/protobuf/proto"
+	"github.com/opencord/voltha-go/common/log"
+	common_pb "github.com/opencord/voltha-protos/go/common"
+	"github.com/stretchr/testify/assert"
+	"google.golang.org/grpc"
+	"testing"
+)
+
+const (
+	ROUND_ROBIN_ROUTER_PROTOFILE = "../../../vendor/github.com/opencord/voltha-protos/go/voltha.pb"
+)
+
+func init() {
+	log.SetDefaultLogger(log.JSON, log.DebugLevel, nil)
+	log.AddPackage(log.JSON, log.WarnLevel, nil)
+}
+
+func MakeRoundRobinTestConfig(numBackends int, numConnections int) (*RouteConfig, *RouterConfig) {
+
+	var backends []BackendConfig
+	for backendIndex := 0; backendIndex < numBackends; backendIndex++ {
+		var connections []ConnectionConfig
+		for connectionIndex := 0; connectionIndex < numConnections; connectionIndex++ {
+			connectionConfig := ConnectionConfig{
+				Name: fmt.Sprintf("ro_vcore%d%d", backendIndex, connectionIndex+1),
+				Addr: "foo",
+				Port: "123",
+			}
+			connections = append(connections, connectionConfig)
+		}
+
+		backendConfig := BackendConfig{
+			Name:        fmt.Sprintf("ro_vcore%d", backendIndex),
+			Type:        BackendSingleServer,
+			Connections: connections,
+		}
+
+		backends = append(backends, backendConfig)
+	}
+
+	backendClusterConfig := BackendClusterConfig{
+		Name:     "ro_vcore",
+		Backends: backends,
+	}
+
+	routeConfig := RouteConfig{
+		Name:           "read_only",
+		Type:           RouteTypeRoundRobin,
+		Association:    AssociationRoundRobin,
+		BackendCluster: "ro_vcore",
+		backendCluster: &backendClusterConfig,
+		Methods:        []string{"ListDevicePorts"},
+	}
+
+	routerConfig := RouterConfig{
+		Name:         "vcore",
+		ProtoService: "VolthaService",
+		ProtoPackage: "voltha",
+		Routes:       []RouteConfig{routeConfig},
+		ProtoFile:    ROUND_ROBIN_ROUTER_PROTOFILE,
+	}
+	return &routeConfig, &routerConfig
+}
+
+// Route() requires an open connection, so pretend we have one.
+func PretendRoundRobinOpenConnection(router Router, clusterName string, backendIndex int, connectionName string) {
+	cluster := router.FindBackendCluster(clusterName)
+
+	// Route Method expects an open connection
+	conn := cluster.backends[backendIndex].connections[connectionName]
+	cluster.backends[backendIndex].openConns[conn] = &grpc.ClientConn{}
+}
+
+// Common setup to run before each unit test
+func RoundRobinTestSetup() {
+	// reset globals that need to be clean for each unit test
+
+	clusters = make(map[string]*cluster)
+}
+
+// Test creation of a new RoundRobinRouter, and the Service(), Name(), FindBackendCluster(), and
+// ReplyHandler() methods.
+func TestRoundRobinRouterInit(t *testing.T) {
+	RoundRobinTestSetup()
+
+	routeConfig, routerConfig := MakeRoundRobinTestConfig(1, 1)
+
+	router, err := newRoundRobinRouter(routerConfig, routeConfig)
+
+	assert.NotNil(t, router)
+	assert.Nil(t, err)
+
+	assert.Equal(t, router.Service(), "VolthaService")
+	assert.Equal(t, router.Name(), "read_only")
+
+	cluster, err := router.BackendCluster("foo", "bar")
+	assert.Equal(t, cluster, clusters["ro_vcore"])
+	assert.Nil(t, err)
+
+	assert.Equal(t, router.FindBackendCluster("ro_vcore"), clusters["ro_vcore"])
+	assert.Nil(t, router.ReplyHandler("foo"))
+}
+
+func TestRoundRobinRouterInitNoName(t *testing.T) {
+	RoundRobinTestSetup()
+
+	routeConfig, routerConfig := MakeRoundRobinTestConfig(1, 1)
+	routeConfig.Name = ""
+
+	_, err := newRoundRobinRouter(routerConfig, routeConfig)
+
+	assert.EqualError(t, err, "Failed to create a new router ''")
+}
+
+func TestRoundRobinRouterInitNoProtoPackage(t *testing.T) {
+	RoundRobinTestSetup()
+
+	routeConfig, routerConfig := MakeRoundRobinTestConfig(1, 1)
+	routerConfig.ProtoPackage = ""
+
+	_, err := newRoundRobinRouter(routerConfig, routeConfig)
+
+	assert.EqualError(t, err, "Failed to create a new router 'read_only'")
+}
+
+func TestRoundRobinRouterInitNoProtoService(t *testing.T) {
+	RoundRobinTestSetup()
+
+	routeConfig, routerConfig := MakeRoundRobinTestConfig(1, 1)
+	routerConfig.ProtoService = ""
+
+	_, err := newRoundRobinRouter(routerConfig, routeConfig)
+
+	assert.EqualError(t, err, "Failed to create a new router 'read_only'")
+}
+
+// Tests a cluster with no backends
+func TestRoundRobinRouteZero(t *testing.T) {
+	RoundRobinTestSetup()
+
+	routeConfig, routerConfig := MakeRoundRobinTestConfig(1, 1)
+
+	router, err := newRoundRobinRouter(routerConfig, routeConfig)
+	assert.Nil(t, err)
+
+	idMessage := &common_pb.ID{Id: "1234"}
+
+	idData, err := proto.Marshal(idMessage)
+	assert.Nil(t, err)
+
+	sel := &requestFrame{payload: idData,
+		err:        nil,
+		methodInfo: newMethodDetails("/voltha.VolthaService/ListDevicePorts")}
+
+	backend, connection := router.Route(sel)
+
+	assert.EqualError(t, sel.err, "No backend with open connections found")
+	assert.Nil(t, backend)
+	assert.Nil(t, connection)
+}
+
+// Tests a cluster with only one Backend
+func TestRoundRobinRouteOne(t *testing.T) {
+	RoundRobinTestSetup()
+
+	routeConfig, routerConfig := MakeRoundRobinTestConfig(1, 1)
+
+	router, err := newRoundRobinRouter(routerConfig, routeConfig)
+	assert.Nil(t, err)
+
+	PretendRoundRobinOpenConnection(router, "ro_vcore", 0, "ro_vcore01")
+
+	idMessage := &common_pb.ID{Id: "1234"}
+
+	idData, err := proto.Marshal(idMessage)
+	assert.Nil(t, err)
+
+	sel := &requestFrame{payload: idData,
+		err:        nil,
+		methodInfo: newMethodDetails("/voltha.VolthaService/ListDevicePorts")}
+
+	backend, connection := router.Route(sel)
+
+	assert.Nil(t, sel.err)
+	assert.NotNil(t, backend)
+	assert.Equal(t, "ro_vcore0", backend.name)
+	assert.Nil(t, connection)
+
+	// Since we only have one backend, calling Route a second time should return the same one
+
+	backend, connection = router.Route(sel)
+
+	assert.Nil(t, sel.err)
+	assert.NotNil(t, backend)
+	assert.Equal(t, "ro_vcore0", backend.name)
+	assert.Nil(t, connection)
+}
+
+// Tests a cluster with two Backends
+func TestRoundRobinRouteTwo(t *testing.T) {
+	RoundRobinTestSetup()
+
+	routeConfig, routerConfig := MakeRoundRobinTestConfig(2, 1)
+
+	router, err := newRoundRobinRouter(routerConfig, routeConfig)
+	assert.Nil(t, err)
+
+	PretendRoundRobinOpenConnection(router, "ro_vcore", 0, "ro_vcore01")
+	PretendRoundRobinOpenConnection(router, "ro_vcore", 1, "ro_vcore11")
+
+	idMessage := &common_pb.ID{Id: "1234"}
+
+	idData, err := proto.Marshal(idMessage)
+	assert.Nil(t, err)
+
+	sel := &requestFrame{payload: idData,
+		err:        nil,
+		methodInfo: newMethodDetails("/voltha.VolthaService/ListDevicePorts")}
+
+	backend, connection := router.Route(sel)
+
+	assert.Nil(t, sel.err)
+	assert.NotNil(t, backend)
+	assert.Equal(t, "ro_vcore0", backend.name)
+	assert.Nil(t, connection)
+
+	// Since we have two backends, calling Route a second time should return the second
+
+	backend, connection = router.Route(sel)
+
+	assert.Nil(t, sel.err)
+	assert.NotNil(t, backend)
+	assert.Equal(t, "ro_vcore1", backend.name)
+	assert.Nil(t, connection)
+
+	// Calling Route a third time should return the first again
+
+	backend, connection = router.Route(sel)
+
+	assert.Nil(t, sel.err)
+	assert.NotNil(t, backend)
+	assert.Equal(t, "ro_vcore0", backend.name)
+	assert.Nil(t, connection)
+}
+
+// Tests a cluster with one backend but no open connections
+func TestRoundRobinRouteOneNoOpenConnection(t *testing.T) {
+	RoundRobinTestSetup()
+
+	routeConfig, routerConfig := MakeRoundRobinTestConfig(1, 1)
+
+	router, err := newRoundRobinRouter(routerConfig, routeConfig)
+	assert.Nil(t, err)
+
+	idMessage := &common_pb.ID{Id: "1234"}
+
+	idData, err := proto.Marshal(idMessage)
+	assert.Nil(t, err)
+
+	sel := &requestFrame{payload: idData,
+		err:        nil,
+		methodInfo: newMethodDetails("/voltha.VolthaService/ListDevicePorts")}
+
+	backend, connection := router.Route(sel)
+
+	assert.EqualError(t, sel.err, "No backend with open connections found")
+	assert.Nil(t, backend)
+	assert.Nil(t, connection)
+}
diff --git a/internal/pkg/afrouter/router.go b/internal/pkg/afrouter/router.go
new file mode 100644
index 0000000..7abbceb
--- /dev/null
+++ b/internal/pkg/afrouter/router.go
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2018-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 afrouter
+
+import (
+	"errors"
+	"fmt"
+	"google.golang.org/grpc"
+)
+
+var allRouters = make(map[string]Router)
+
+// The router interface
+type Router interface {
+	Name() string
+
+	// Route() returns a backend and a connection. The connection is optional and if unspecified, then any
+	// connection on the backend may be used.
+	Route(interface{}) (*backend, *connection)
+
+	Service() string
+	IsStreaming(string) (bool, bool)
+	BackendCluster(string, string) (*cluster, error)
+	FindBackendCluster(string) *cluster
+	ReplyHandler(interface{}) error
+	GetMetaKeyVal(serverStream grpc.ServerStream) (string, string, error)
+}
+
+func newRouter(config *RouterConfig) (Router, error) {
+	r, err := newMethodRouter(config)
+	if err == nil {
+		allRouters[r.Name()] = r
+	}
+	return r, err
+}
+
+func newSubRouter(rconf *RouterConfig, config *RouteConfig) (Router, error) {
+	switch config.Type {
+	case RouteTypeRpcAffinityMessage:
+		r, err := newAffinityRouter(rconf, config)
+		if err == nil {
+			allRouters[rconf.Name+config.Name] = r
+		}
+		return r, err
+	case RouteTypeBinding:
+		r, err := newBindingRouter(rconf, config)
+		if err == nil {
+			allRouters[rconf.Name+config.Name] = r
+		}
+		return r, err
+	case RouteTypeRoundRobin:
+		r, err := newRoundRobinRouter(rconf, config)
+		if err == nil {
+			allRouters[rconf.Name+config.Name] = r
+		}
+		return r, err
+	case RouteTypeSource:
+		r, err := newSourceRouter(rconf, config)
+		if err == nil {
+			allRouters[rconf.Name+config.Name] = r
+		}
+		return r, err
+	default:
+		return nil, errors.New(fmt.Sprintf("Internal error, undefined router type: %s", config.Type))
+	}
+}
diff --git a/internal/pkg/afrouter/server.go b/internal/pkg/afrouter/server.go
new file mode 100644
index 0000000..82269d2
--- /dev/null
+++ b/internal/pkg/afrouter/server.go
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2018-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 afrouter
+
+import (
+	"errors"
+	"fmt"
+	"github.com/opencord/voltha-go/common/log"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/codes"
+	"net"
+	"net/url"
+	"strconv"
+)
+
+var (
+	clientStreamDescForProxying = &grpc.StreamDesc{
+		ServerStreams: true,
+		ClientStreams: true,
+	}
+)
+
+type server struct {
+	running       bool
+	name          string
+	proxyListener net.Listener
+	routers       map[string]map[string]Router
+	proxyServer   *grpc.Server
+}
+
+func newServer(config *ServerConfig) (*server, error) {
+	var err error = nil
+	var rtrn_err = false
+	var s *server
+	// Change over to the new configuration format
+	// Validate the configuration
+	// There should be a name
+	if config.Name == "" {
+		log.Error("A server has been defined with no name")
+		rtrn_err = true
+	}
+	// Validate that there's a port specified
+	if config.Port == 0 {
+		log.Errorf("Server %s does not have a valid port assigned", config.Name)
+		rtrn_err = true
+	}
+	// Validate the ip address if one is provided
+	if _, err := url.Parse(config.Addr); err != nil {
+		log.Errorf("Invalid address '%s' provided for server '%s'", config.Addr, config.Name)
+		rtrn_err = true
+	}
+	if config.Type != "grpc" && config.Type != "streaming_grpc" {
+		if config.Type == "" {
+			log.Errorf("A server 'type' must be defined for server %s", config.Name)
+		} else {
+			log.Errorf("The server type must be either 'grpc' or 'streaming_grpc' "+
+				"but '%s' was found for server '%s'", config.Type, config.Name)
+		}
+		rtrn_err = true
+	}
+	if len(config.Routers) == 0 {
+		log.Errorf("At least one router must be specified for server '%s'", config.Name)
+		rtrn_err = true
+	}
+
+	if rtrn_err {
+		return nil, errors.New("Server configuration failed")
+	} else {
+		// The configuration is valid, create a server and configure it.
+		s = &server{name: config.Name, routers: make(map[string]map[string]Router)}
+		// The listener
+		if s.proxyListener, err =
+			net.Listen("tcp", config.Addr+":"+
+				strconv.Itoa(int(config.Port))); err != nil {
+			log.Error(err)
+			return nil, err
+		}
+		// Create the routers
+		log.Debugf("Configuring the routers for server %s", s.name)
+		for p, r := range config.routers {
+			log.Debugf("Processing router %s for package %s", r.Name, p)
+			if dr, err := newRouter(r); err != nil {
+				log.Error(err)
+				return nil, err
+			} else {
+				log.Debugf("Adding router %s to the server %s for package %s and service %s",
+					dr.Name(), s.name, p, dr.Service())
+				if _, ok := s.routers[p]; ok {
+					s.routers[p][dr.Service()] = dr
+				} else {
+					s.routers[p] = make(map[string]Router)
+					s.routers[p][dr.Service()] = dr
+				}
+			}
+		}
+		// Configure the grpc handler
+		s.proxyServer = grpc.NewServer(
+			grpc.CustomCodec(Codec()),
+			grpc.UnknownServiceHandler(s.TransparentHandler()),
+		)
+
+	}
+	return s, nil
+}
+
+func (s *server) Name() string {
+	return s.name
+}
+
+func (s *server) TransparentHandler() grpc.StreamHandler {
+	return s.handler
+}
+
+func (s *server) getRouter(pkg string, service string) (Router, bool) {
+	if fn, ok := s.routers[pkg][service]; ok { // Both specified
+		return fn, ok
+	} else if fn, ok = s.routers["*"][service]; ok { // Package wild card
+		return fn, ok
+	} else if fn, ok = s.routers[pkg]["*"]; ok { // Service wild card
+		return fn, ok
+	} else if fn, ok = s.routers["*"]["*"]; ok { // Both Wildcarded
+		return fn, ok
+	} else {
+		return nil, false
+	}
+}
+
+func (s *server) handler(srv interface{}, serverStream grpc.ServerStream) error {
+	// Determine what router is intended to handle this request
+	fullMethodName, ok := grpc.MethodFromServerStream(serverStream)
+	if !ok {
+		return grpc.Errorf(codes.Internal, "lowLevelServerStream doesn't exist in context")
+	}
+	log.Debugf("\n\nProcessing grpc request %s on server %s", fullMethodName, s.name)
+	methodInfo := newMethodDetails(fullMethodName)
+	r, ok := s.getRouter(methodInfo.pkg, methodInfo.service)
+	//fn, ok := s.routers[methodInfo.pkg][methodInfo.service]
+	if !ok {
+		// TODO: Should this be punted to a default transparent router??
+		// Probably not, if one is defined yes otherwise just crap out.
+
+		err := fmt.Errorf("Unable to dispatch! Service '%s' for package '%s' not found.", methodInfo.service, methodInfo.pkg)
+		log.Error(err)
+		return err
+	}
+	log.Debugf("Selected router %s", r.Name())
+
+	mk, mv, err := r.GetMetaKeyVal(serverStream)
+	if err != nil {
+		log.Error(err)
+		return err
+	}
+
+	//nbR := &nbRequest(srv:srv,serverStream:serverStream,r:r,methodInfo:methodInfo,metaKey:mk,metaVal:mv)
+
+	// Extract the cluster from the selected router and use it to manage the transfer
+	if cluster, err := r.BackendCluster(methodInfo.method, mk); err != nil {
+		return err
+	} else {
+		//return beCluster.handler(nbR)
+		return cluster.handler(srv, serverStream, r, methodInfo, mk, mv)
+	}
+}
diff --git a/internal/pkg/afrouter/signals.go b/internal/pkg/afrouter/signals.go
new file mode 100644
index 0000000..37b154b
--- /dev/null
+++ b/internal/pkg/afrouter/signals.go
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2018-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.
+ */
+
+// This file implements an exit handler that tries to shut down all the
+// running servers before finally exiting. There are 2 triggers to this
+// clean exit thread: signals and an exit channel.
+
+package afrouter
+
+import (
+	"github.com/opencord/voltha-go/common/log"
+	"os"
+	"os/signal"
+	"syscall"
+)
+
+var errChan = make(chan error)
+var doneChan = make(chan error)
+
+func InitExitHandler() error {
+
+	// Start the signal handler
+	go signalHandler()
+	// Start the error handler
+	go errHandler()
+
+	return nil
+}
+
+func signalHandler() {
+	// Make signal channel and register notifiers for Interupt and Terminate
+	sigchan := make(chan os.Signal, 1)
+	signal.Notify(sigchan, os.Interrupt)
+	signal.Notify(sigchan, syscall.SIGTERM)
+	signal.Notify(sigchan, syscall.SIGKILL)
+
+	// Block until we receive a signal on the channel
+	<-sigchan
+
+	log.Info("shutting down on signal as requested")
+
+	cleanExit(nil)
+}
+
+func errHandler() {
+
+	err := <-errChan
+
+	cleanExit(err)
+}
+
+func cleanExit(err error) {
+	// Log the shutdown
+	if arProxy != nil {
+		for _, srvr := range arProxy.servers {
+			if srvr.running {
+				log.With(log.Fields{"server": srvr.name}).Debug("Closing server")
+				srvr.proxyServer.GracefulStop()
+				srvr.proxyListener.Close()
+			}
+		}
+	}
+	for _, cl := range clusters {
+		for _, bknd := range cl.backends {
+			log.Debugf("Closing backend %s", bknd.name)
+			for _, conn := range bknd.connections {
+				log.Debugf("Closing connection %s", conn.name)
+				conn.close()
+			}
+		}
+	}
+	doneChan <- err
+	//os.Exit(0)
+}
diff --git a/internal/pkg/afrouter/source-router.go b/internal/pkg/afrouter/source-router.go
new file mode 100644
index 0000000..7841554
--- /dev/null
+++ b/internal/pkg/afrouter/source-router.go
@@ -0,0 +1,303 @@
+/*
+ * Copyright 2018-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 afrouter
+
+/* Source-Router
+
+   This router implements source routing where the caller identifies the
+   component the message should be routed to. The `RouteField` should be
+   configured with the gRPC field name to inspect to determine the
+   destination. This field is assumed to be a string. That string will
+   then be used to identify a particular connection on a particular
+   backend.
+
+   The source-router must be configured with a backend cluster, as all routers
+   must identify a backend cluster. However, that backend cluster
+   is merely a placeholder and is not used by the source-router. The
+   source-router's Route() function will return whatever backend cluster is
+   specified by the `RouteField`.
+*/
+
+import (
+	"errors"
+	"fmt"
+	"github.com/golang/protobuf/proto"
+	"github.com/opencord/voltha-go/common/log"
+	"google.golang.org/grpc"
+	"regexp"
+	"strconv"
+)
+
+type SourceRouter struct {
+	name string
+	//association     associationType
+	routingField string
+	grpcService  string
+	methodMap    map[string]byte
+	cluster      *cluster
+}
+
+func newSourceRouter(rconf *RouterConfig, config *RouteConfig) (Router, error) {
+	var err error = nil
+	var rtrn_err = false
+	var pkg_re = regexp.MustCompile(`^(\.[^.]+\.)(.+)$`)
+	// Validate the configuration
+
+	// A name must exist
+	if config.Name == "" {
+		log.Error("A router 'name' must be specified")
+		rtrn_err = true
+	}
+
+	if rconf.ProtoPackage == "" {
+		log.Error("A 'package' must be specified")
+		rtrn_err = true
+	}
+
+	if rconf.ProtoService == "" {
+		log.Error("A 'service' must be specified")
+		rtrn_err = true
+	}
+
+	if config.RouteField == "" {
+		log.Error("A 'routing_field' must be specified")
+		rtrn_err = true
+	}
+
+	// TODO The overrieds section is currently not being used
+	// so the router will route all methods based on the
+	// routing_field. This needs to be added so that methods
+	// can have different routing fields.
+	dr := SourceRouter{
+		name:        config.Name,
+		grpcService: rconf.ProtoService,
+		methodMap:   make(map[string]byte),
+	}
+
+	// Build the routing structure based on the loaded protobuf
+	// descriptor file and the config information.
+	type key struct {
+		method string
+		field  string
+	}
+	var fieldNumberLookup = make(map[key]byte)
+	for _, f := range rconf.protoDescriptor.File {
+		// Build a temporary map of message types by name.
+		for _, m := range f.MessageType {
+			for _, fld := range m.Field {
+				log.Debugf("Processing message '%s', field '%s'", *m.Name, *fld.Name)
+				fieldNumberLookup[key{*m.Name, *fld.Name}] = byte(*fld.Number)
+			}
+		}
+	}
+	for _, f := range rconf.protoDescriptor.File {
+		if *f.Package == rconf.ProtoPackage {
+			for _, s := range f.Service {
+				if *s.Name == rconf.ProtoService {
+					log.Debugf("Loading package data '%s' for service '%s' for router '%s'", *f.Package, *s.Name, dr.name)
+					// Now create a map keyed by method name with the value being the
+					// field number of the route selector.
+					var ok bool
+					for _, m := range s.Method {
+						// Find the input type in the messages and extract the
+						// field number and save it for future reference.
+						log.Debugf("Processing method '%s'", *m.Name)
+						// Determine if this is a method we're supposed to be processing.
+						if needMethod(*m.Name, config) {
+							log.Debugf("Enabling method '%s'", *m.Name)
+							pkg_methd := pkg_re.FindStringSubmatch(*m.InputType)
+							if pkg_methd == nil {
+								log.Errorf("Regular expression didn't match input type '%s'", *m.InputType)
+								rtrn_err = true
+							}
+							// The input type has the package name prepended to it. Remove it.
+							//in := (*m.InputType)[len(rconf.ProtoPackage)+2:]
+							in := pkg_methd[PKG_MTHD_MTHD]
+							dr.methodMap[*m.Name], ok = fieldNumberLookup[key{in, config.RouteField}]
+							if !ok {
+								log.Errorf("Method '%s' has no field named '%s' in it's parameter message '%s'",
+									*m.Name, config.RouteField, in)
+								rtrn_err = true
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+
+	// We need to pick a cluster, because server will call cluster.handler. The choice we make doesn't
+	// matter, as we can return a different cluster from Route().
+	ok := true
+	if dr.cluster, ok = clusters[config.backendCluster.Name]; !ok {
+		if dr.cluster, err = newBackendCluster(config.backendCluster); err != nil {
+			log.Errorf("Could not create a backend for router %s", config.Name)
+			rtrn_err = true
+		}
+	}
+
+	if rtrn_err {
+		return dr, errors.New(fmt.Sprintf("Failed to create a new router '%s'", dr.name))
+	}
+
+	return dr, nil
+}
+
+func (ar SourceRouter) Service() string {
+	return ar.grpcService
+}
+
+func (ar SourceRouter) Name() string {
+	return ar.name
+}
+
+func (ar SourceRouter) skipField(data *[]byte, idx *int) error {
+	switch (*data)[*idx] & 3 {
+	case 0: // Varint
+		// skip the field number/type
+		*idx++
+		// if the msb is set, then more bytes to follow
+		for (*data)[*idx] >= 128 {
+			*idx++
+		}
+		// the last byte doesn't have the msb set
+		*idx++
+	case 1: // 64 bit
+		*idx += 9
+	case 2: // Length delimited
+		// skip the field number / type
+		*idx++
+		// read a varint that tells length of string
+		b := proto.NewBuffer((*data)[*idx:])
+		t, _ := b.DecodeVarint()
+		// skip the length varint and the string bytes
+		// TODO: This assumes the varint was one byte long -- max string length is 127 bytes
+		*idx += int(t) + 1
+	case 3: // Deprecated
+	case 4: // Deprecated
+	case 5: // 32 bit
+		*idx += 5
+	}
+	return nil
+}
+
+func (ar SourceRouter) decodeProtoField(payload []byte, fieldId byte) (string, error) {
+	idx := 0
+	b := proto.NewBuffer([]byte{})
+	//b.DebugPrint("The Buffer", payload)
+	for { // Find the route selector field
+		log.Debugf("Decoding source value attributeNumber: %d from %v at index %d", fieldId, payload, idx)
+		log.Debugf("Attempting match with payload: %d, methodTable: %d", payload[idx], fieldId)
+		if payload[idx]>>3 == fieldId {
+			log.Debugf("Method match with payload: %d, methodTable: %d", payload[idx], fieldId)
+			// TODO: Consider supporting other selector types.... Way, way in the future
+			// ok, the future is now, support strings as well... ugh.
+			var selector string
+			switch payload[idx] & 3 {
+			case 0: // Integer
+				b.SetBuf(payload[idx+1:])
+				v, e := b.DecodeVarint()
+				if e == nil {
+					log.Debugf("Decoded the ing field: %v", v)
+					selector = strconv.Itoa(int(v))
+				} else {
+					log.Errorf("Failed to decode varint %v", e)
+					return "", e
+				}
+			case 2: // Length delimited AKA string
+				b.SetBuf(payload[idx+1:])
+				v, e := b.DecodeStringBytes()
+				if e == nil {
+					log.Debugf("Decoded the string field: %v", v)
+					selector = v
+				} else {
+					log.Errorf("Failed to decode string %v", e)
+					return "", e
+				}
+			default:
+				err := errors.New(fmt.Sprintf("Only integer and string route selectors are permitted"))
+				log.Error(err)
+				return "", err
+			}
+			return selector, nil
+		} else if err := ar.skipField(&payload, &idx); err != nil {
+			log.Errorf("Parsing message failed %v", err)
+			return "", err
+		}
+	}
+}
+
+func (ar SourceRouter) Route(sel interface{}) (*backend, *connection) {
+	log.Debugf("SourceRouter sel %v", sel)
+	switch sl := sel.(type) {
+	case *requestFrame:
+		log.Debugf("Route called for nbFrame with method %s", sl.methodInfo.method)
+		// Not a south affinity binding method, proceed with north affinity binding.
+		if selector, err := ar.decodeProtoField(sl.payload, ar.methodMap[sl.methodInfo.method]); err == nil {
+			// selector is
+
+			for _, cluster := range clusters {
+				for _, backend := range cluster.backends {
+					log.Debugf("Checking backend %s", backend.name)
+					for _, connection := range backend.connections {
+						log.Debugf("Checking connection %s", connection.name)
+						// caller specified a backend and a connection
+						if backend.name+"."+connection.name == selector {
+							return backend, connection
+						}
+					}
+					// caller specified just a backend
+					if backend.name == selector {
+						return backend, nil
+					}
+				}
+			}
+			sl.err = fmt.Errorf("Backend %s not found", selector)
+			return nil, nil
+		}
+	default:
+		log.Errorf("Internal: invalid data type in Route call %v", sel)
+		return nil, nil
+	}
+	log.Errorf("Bad routing in SourceRouter:Route")
+	return nil, nil
+}
+
+func (ar SourceRouter) GetMetaKeyVal(serverStream grpc.ServerStream) (string, string, error) {
+	return "", "", nil
+}
+
+func (ar SourceRouter) IsStreaming(_ string) (bool, bool) {
+	panic("not implemented")
+}
+
+func (ar SourceRouter) BackendCluster(mthd string, metaKey string) (*cluster, error) {
+	// unsupported?
+	return ar.cluster, nil
+}
+
+func (ar SourceRouter) FindBackendCluster(beName string) *cluster {
+	// unsupported?
+	if beName == ar.cluster.name {
+		return ar.cluster
+	}
+	return nil
+}
+
+func (rr SourceRouter) ReplyHandler(sel interface{}) error { // This is a no-op
+	return nil
+}
diff --git a/internal/pkg/afrouter/source-router_test.go b/internal/pkg/afrouter/source-router_test.go
new file mode 100644
index 0000000..a89c034
--- /dev/null
+++ b/internal/pkg/afrouter/source-router_test.go
@@ -0,0 +1,140 @@
+/*
+ * Portions copyright 2019-present Open Networking Foundation
+ * Original copyright 2019-present Ciena Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the"github.com/stretchr/testify/assert" "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 afrouter
+
+import (
+	"github.com/golang/protobuf/proto"
+	"github.com/opencord/voltha-go/common/log"
+	common_pb "github.com/opencord/voltha-protos/go/common"
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+const (
+	SOURCE_ROUTER_PROTOFILE = "../../../vendor/github.com/opencord/voltha-protos/go/voltha.pb"
+)
+
+func init() {
+	log.SetDefaultLogger(log.JSON, log.DebugLevel, nil)
+	log.AddPackage(log.JSON, log.WarnLevel, nil)
+}
+
+func MakeSourceRouterTestConfig() (*RouteConfig, *RouterConfig) {
+	connectionConfig := ConnectionConfig{
+		Name: "ro_vcore01",
+		Addr: "foo",
+		Port: "123",
+	}
+
+	backendConfig := BackendConfig{
+		Name:        "ro_vcore0",
+		Type:        BackendSingleServer,
+		Connections: []ConnectionConfig{connectionConfig},
+	}
+
+	backendClusterConfig := BackendClusterConfig{
+		Name:     "ro_vcore",
+		Backends: []BackendConfig{backendConfig},
+	}
+
+	routeConfig := RouteConfig{
+		Name:           "logger",
+		Type:           RouteTypeSource,
+		RouteField:     "component_name",
+		BackendCluster: "ro_vcore",
+		backendCluster: &backendClusterConfig,
+		Methods:        []string{"UpdateLogLevel", "GetLogLevel"},
+	}
+
+	routerConfig := RouterConfig{
+		Name:         "vcore",
+		ProtoService: "VolthaService",
+		ProtoPackage: "voltha",
+		Routes:       []RouteConfig{routeConfig},
+		ProtoFile:    SOURCE_ROUTER_PROTOFILE,
+	}
+	return &routeConfig, &routerConfig
+}
+
+func TestSourceRouterInit(t *testing.T) {
+	routeConfig, routerConfig := MakeSourceRouterTestConfig()
+
+	router, err := newSourceRouter(routerConfig, routeConfig)
+
+	assert.NotNil(t, router)
+	assert.Nil(t, err)
+
+	assert.Equal(t, router.Service(), "VolthaService")
+	assert.Equal(t, router.Name(), "logger")
+
+	cluster, err := router.BackendCluster("foo", "bar")
+	assert.Equal(t, cluster, clusters["ro_vcore"])
+	assert.Nil(t, err)
+
+	assert.Equal(t, router.FindBackendCluster("ro_vcore"), clusters["ro_vcore"])
+	assert.Nil(t, router.ReplyHandler("foo"))
+}
+
+func TestSourceRouterDecodeProtoField(t *testing.T) {
+	_, routerConfig := MakeSourceRouterTestConfig()
+	_, err := newRouter(routerConfig)
+	assert.Nil(t, err)
+
+	// Get the created AffinityRouter so we can inspect its state
+	sourceRouter := allRouters["vcorelogger"].(SourceRouter)
+
+	loggingMessage := &common_pb.Logging{Level: 1,
+		PackageName:   "default",
+		ComponentName: "ro_vcore0.ro_vcore01"}
+
+	loggingData, err := proto.Marshal(loggingMessage)
+	assert.Nil(t, err)
+
+	s, err := sourceRouter.decodeProtoField(loggingData, 2) // field 2 is package_name
+	assert.Equal(t, s, "default")
+
+	s, err = sourceRouter.decodeProtoField(loggingData, 3) // field 2 is component_name
+	assert.Equal(t, s, "ro_vcore0.ro_vcore01")
+}
+
+func TestSourceRouterRoute(t *testing.T) {
+	_, routerConfig := MakeSourceRouterTestConfig()
+	_, err := newRouter(routerConfig)
+	assert.Nil(t, err)
+
+	// Get the created AffinityRouter so we can inspect its state
+	sourceRouter := allRouters["vcorelogger"].(SourceRouter)
+
+	loggingMessage := &common_pb.Logging{Level: 1,
+		PackageName:   "default",
+		ComponentName: "ro_vcore0.ro_vcore01"}
+
+	loggingData, err := proto.Marshal(loggingMessage)
+	assert.Nil(t, err)
+
+	sel := &requestFrame{payload: loggingData,
+		err:        nil,
+		methodInfo: newMethodDetails("/voltha.VolthaService/UpdateLogLevel")}
+
+	backend, connection := sourceRouter.Route(sel)
+
+	assert.Nil(t, sel.err)
+	assert.NotNil(t, backend)
+	assert.Equal(t, backend.name, "ro_vcore0")
+	assert.NotNil(t, connection)
+	assert.Equal(t, connection.name, "ro_vcore01")
+}
