diff --git a/pkg/kernel/networkservice/common/mechanisms/vlan/server.go b/pkg/kernel/networkservice/common/mechanisms/vlan/server.go index 61e5d0c2..5c1cdd8b 100644 --- a/pkg/kernel/networkservice/common/mechanisms/vlan/server.go +++ b/pkg/kernel/networkservice/common/mechanisms/vlan/server.go @@ -3,6 +3,7 @@ package vlan import ( "context" "net/url" + "strconv" "github.com/golang/protobuf/ptypes/empty" "github.com/networkservicemesh/api/pkg/api/networkservice/mechanisms/vlan" @@ -10,22 +11,54 @@ import ( "github.com/networkservicemesh/api/pkg/api/networkservice" "github.com/networkservicemesh/sdk/pkg/networkservice/core/next" + "github.com/networkservicemesh/sdk/pkg/tools/log" ) -type vlanMechanismServer struct{} +type vlanMechanismServer struct { + baseInterface string + vlanTag int32 + isOneLeg bool +} // NewServer - creates a NetworkServiceServer that requests a vlan interface and populates the netns inode -func NewServer() networkservice.NetworkServiceServer { - return &vlanMechanismServer{} +func NewServer(baseInterface string, vlanID int32, oneLeg bool) networkservice.NetworkServiceServer { + v := &vlanMechanismServer{ + baseInterface: baseInterface, + vlanTag: vlanID, + isOneLeg: oneLeg, + } + return v } -func (m *vlanMechanismServer) Request(ctx context.Context, request *networkservice.NetworkServiceRequest) (*networkservice.Connection, error) { - if mechanism := vlan.ToMechanism(request.GetConnection().GetMechanism()); mechanism != nil { - mechanism.SetNetNSURL((&url.URL{Scheme: "file", Path: netNSFilename}).String()) +func (v *vlanMechanismServer) Request(ctx context.Context, request *networkservice.NetworkServiceRequest) (*networkservice.Connection, error) { + log.FromContext(ctx).WithField("vlanMechanismServer", "Request"). + WithField("VlanID", v.vlanTag). + WithField("BaseInterfaceName", v.baseInterface). + Debugf("request=", request) + + if conn := request.GetConnection(); conn != nil { + if mechanism := vlan.ToMechanism(conn.GetMechanism()); mechanism != nil { + mechanism.SetNetNSURL((&url.URL{Scheme: "file", Path: netNSFilename}).String()) + if conn.GetContext() == nil { + conn.Context = new(networkservice.ConnectionContext) + } + if conn.GetContext().GetEthernetContext() == nil { + conn.GetContext().EthernetContext = new(networkservice.EthernetContext) + } + ethernetContext := conn.GetContext().GetEthernetContext() + ethernetContext.VlanTag = v.vlanTag + + if conn.GetContext().GetExtraContext() == nil { + request.Connection.Context.ExtraContext = map[string]string{} + } + extracontext := conn.GetContext().GetExtraContext() + extracontext["baseInterface"] = v.baseInterface + extracontext["isOneLeg"] = strconv.FormatBool(v.isOneLeg) + } } return next.Server(ctx).Request(ctx, request) } -func (m *vlanMechanismServer) Close(ctx context.Context, conn *networkservice.Connection) (*empty.Empty, error) { +func (v *vlanMechanismServer) Close(ctx context.Context, conn *networkservice.Connection) (*empty.Empty, error) { return next.Server(ctx).Close(ctx, conn) } diff --git a/pkg/kernel/networkservice/mechanisms/vlan/common.go b/pkg/kernel/networkservice/mechanisms/vlan/common.go index c28639cb..3c49c2ca 100644 --- a/pkg/kernel/networkservice/mechanisms/vlan/common.go +++ b/pkg/kernel/networkservice/mechanisms/vlan/common.go @@ -5,6 +5,7 @@ import ( "crypto/rand" "encoding/hex" "io" + "strconv" "github.com/networkservicemesh/api/pkg/api/networkservice" vlanmech "github.com/networkservicemesh/api/pkg/api/networkservice/mechanisms/vlan" @@ -18,9 +19,20 @@ import ( func create(ctx context.Context, conn *networkservice.Connection, isClient bool) error { if mechanism := vlanmech.ToMechanism(conn.GetMechanism()); mechanism != nil { nsFilename := mechanism.GetNetNSURL() + if nsFilename == "" { + return nil + } hostIfName := mechanism.GetInterfaceName(conn) - vlanID := mechanism.VlanID() - baseInterface := mechanism.GetBaseInterfaceName(conn) + vlanID, err := getVlanID(conn) + if err != nil { + return nil + } + baseInterface, ok := getBaseInterface(conn) + if !ok { + return nil + } + isOneLeg := getOneLegFlag(conn) + logger := log.FromContext(ctx).WithField("vlan", "create"). WithField("HostIfName", hostIfName). WithField("HostNamespace", nsFilename). @@ -29,10 +41,9 @@ func create(ctx context.Context, conn *networkservice.Connection, isClient bool) WithField("isClient", isClient) logger.Debug("request") - if nsFilename == "" || vlanID == 0 || baseInterface == "" { + if isOneLeg && isClient { return nil } - // TODO generate this based on conn id tmpName, _ := generateRandomName(7) @@ -71,6 +82,33 @@ func create(ctx context.Context, conn *networkservice.Connection, isClient bool) return nil } +func getVlanID(conn *networkservice.Connection) (int, error) { + if ethernetContext := conn.GetContext().GetEthernetContext(); ethernetContext != nil { + if ethernetContext.VlanTag != 0 { + return int(ethernetContext.VlanTag), nil + } + } + return 0, errors.New("no vlanID provided") +} +func getBaseInterface(conn *networkservice.Connection) (string, bool) { + if extraContext := conn.GetContext().GetExtraContext(); extraContext != nil { + if baseInterface, ok := extraContext["baseInterface"]; ok { + return baseInterface, true + } + } + return "", false +} +func getOneLegFlag(conn *networkservice.Connection) bool { + if extraContext := conn.GetContext().GetExtraContext(); extraContext != nil { + if strValue, ok := extraContext["isOneLeg"]; ok { + if flag, err := strconv.ParseBool(strValue); err == nil { + return flag + } + } + } + return false +} + func generateRandomName(size int) (string, error) { id := make([]byte, 32) if _, err := io.ReadFull(rand.Reader, id); err != nil { diff --git a/pkg/kernel/networkservice/netnsconnectioncontext/common.go b/pkg/kernel/networkservice/netnsconnectioncontext/common.go index 656f230d..26fb2d0e 100644 --- a/pkg/kernel/networkservice/netnsconnectioncontext/common.go +++ b/pkg/kernel/networkservice/netnsconnectioncontext/common.go @@ -55,7 +55,7 @@ func AddIPs(ctx context.Context, conn *networkservice.Connection, isClient bool) return errors.Wrapf(err, "invalid IP address: %v", ipContext.GetSrcIpAddr()) } - logger.Debugf("Is to set IP: %v and route", ipAddr) + logger.Debugf("Is to set IP: %v and routes: %+v", ipAddr, routes) return setIPandRoutes(hostIfName, routes, ipAddr, currNetNS, clientNetNS) } @@ -96,7 +96,6 @@ func setIPandRoutes(ifName string, routes []*networkservice.Route, ipAddr *netli IP: routeNet.IP, Mask: routeNet.Mask, }, - Src: ipAddr.IP, }); err != nil && !os.IsExist(err) { return errors.Wrapf(err, "failed to add route: %v", route.GetPrefix()) }