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
+}
