go.ligato.io/vpp-agent/v3@v3.5.0/plugins/linux/nsplugin/linuxcalls/namespace_api.go (about) 1 // Copyright (c) 2018 Cisco and/or its affiliates. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at: 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package linuxcalls 16 17 import ( 18 "os" 19 "runtime" 20 21 "github.com/vishvananda/netns" 22 "go.ligato.io/cn-infra/v2/logging" 23 ) 24 25 var enableNsCtxCheck = os.Getenv("NSPLUGIN_CHECK_NS_CTX") != "" 26 27 // NamedNetNsAPI defines methods related to management of named network namespaces. 28 type NamedNetNsAPI interface { 29 // CreateNamedNetNs creates a new named Linux network namespace. 30 // It does exactly the same thing as the command "ip netns add NAMESPACE". 31 CreateNamedNetNs(ctx NamespaceMgmtCtx, nsName string) (netns.NsHandle, error) 32 // DeleteNamedNetNs deletes an existing named Linux network namespace. 33 // It does exactly the same thing as the command "ip netns del NAMESPACE". 34 DeleteNamedNetNs(nsName string) error 35 // NamedNetNsExists checks whether named namespace exists. 36 NamedNetNsExists(nsName string) (bool, error) 37 } 38 39 // NamespaceMgmtCtx represents context of an ongoing management of Linux namespaces. 40 // The same context should not be used concurrently. 41 type NamespaceMgmtCtx interface { 42 // LockOSThread wires the calling goroutine to its current operating system thread. 43 // The method should implement re-entrant lock always called from a single go routine. 44 LockOSThread() 45 // UnlockOSThread unwires the calling goroutine from its fixed operating system thread. 46 // The method should implement re-entrant lock always called from a single go routine. 47 UnlockOSThread() 48 } 49 50 // namespaceMgmtCtx implements NamespaceMgmtCtx. 51 type namespaceMgmtCtx struct { 52 lockOsThreadCnt int 53 } 54 55 // LockOSThread wires the calling goroutine to its current operating system thread. 56 func (ctx *namespaceMgmtCtx) LockOSThread() { 57 if ctx.lockOsThreadCnt == 0 { 58 runtime.LockOSThread() 59 } 60 ctx.lockOsThreadCnt++ 61 } 62 63 // UnlockOSThread unwires the calling goroutine from its fixed operating system thread. 64 func (ctx *namespaceMgmtCtx) UnlockOSThread() { 65 ctx.lockOsThreadCnt-- 66 if ctx.lockOsThreadCnt == 0 { 67 runtime.UnlockOSThread() 68 } 69 } 70 71 // NewNamespaceMgmtCtx creates and returns a new context for management of Linux 72 // namespaces. 73 func NewNamespaceMgmtCtx() NamespaceMgmtCtx { 74 nsCtx := &namespaceMgmtCtx{} 75 if enableNsCtxCheck { 76 bt := make([]byte, 1<<16) 77 runtime.Stack(bt, false) 78 runtime.SetFinalizer(nsCtx, func(ctx *namespaceMgmtCtx) { 79 if ctx.lockOsThreadCnt != 0 { 80 panic("locked ns ctx to be GCed - created at: " + string(bt)) 81 } 82 }) 83 } 84 return nsCtx 85 } 86 87 // namedNetNsHandler implements NamedNetNsAPI using provided system handler. 88 type namedNetNsHandler struct { 89 log logging.Logger 90 sysHandler SystemAPI 91 } 92 93 // NewNamedNetNsHandler creates new instance of namespace handler 94 func NewNamedNetNsHandler(sysHandler SystemAPI, log logging.Logger) NamedNetNsAPI { 95 return &namedNetNsHandler{ 96 log: log, 97 sysHandler: sysHandler, 98 } 99 }