mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Gracefully handle missing xfrm modules
If xfrm modules cannot be loaded: - Create netlink.Handle only for ROUTE socket - Reject local join on overlay secure network Signed-off-by: Alessandro Boch <aboch@docker.com>
This commit is contained in:
parent
b39f13f80e
commit
117131c41b
6 changed files with 36 additions and 10 deletions
|
@ -3,6 +3,7 @@ package overlay
|
|||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"syscall"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/docker/libnetwork/driverapi"
|
||||
|
@ -31,6 +32,12 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo,
|
|||
return fmt.Errorf("cannot join secure network: encryption keys not present")
|
||||
}
|
||||
|
||||
nlh := ns.NlHandle()
|
||||
|
||||
if n.secure && !nlh.SupportsNetlinkFamily(syscall.NETLINK_XFRM) {
|
||||
return fmt.Errorf("cannot join secure network: required modules to install IPSEC rules are missing on host")
|
||||
}
|
||||
|
||||
s := n.getSubnetforIP(ep.addr)
|
||||
if s == nil {
|
||||
return fmt.Errorf("could not find subnet for endpoint %s", eid)
|
||||
|
@ -65,8 +72,6 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo,
|
|||
return fmt.Errorf("failed to update overlay endpoint %s to local data store: %v", ep.id[0:7], err)
|
||||
}
|
||||
|
||||
nlh := ns.NlHandle()
|
||||
|
||||
// Set the container interface and its peer MTU to 1450 to allow
|
||||
// for 50 bytes vxlan encap (inner eth header(14) + outer IP(20) +
|
||||
// outer UDP(8) + vxlan header(8))
|
||||
|
|
|
@ -284,7 +284,7 @@ func populateVNITbl() {
|
|||
}
|
||||
defer ns.Close()
|
||||
|
||||
nlh, err := netlink.NewHandleAt(ns)
|
||||
nlh, err := netlink.NewHandleAt(ns, syscall.NETLINK_ROUTE)
|
||||
if err != nil {
|
||||
logrus.Errorf("Could not open netlink handle during vni population for ns %s: %v", path, err)
|
||||
return nil
|
||||
|
|
|
@ -3,6 +3,7 @@ package overlay
|
|||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/libnetwork/netutils"
|
||||
|
@ -128,7 +129,7 @@ func deleteVxlanByVNI(path string, vni uint32) error {
|
|||
}
|
||||
defer ns.Close()
|
||||
|
||||
nlh, err = netlink.NewHandleAt(ns)
|
||||
nlh, err = netlink.NewHandleAt(ns, syscall.NETLINK_ROUTE)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get netlink handle for ns %s: %v", path, err)
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@ package ns
|
|||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
|
||||
|
@ -24,7 +26,7 @@ func Init() {
|
|||
if err != nil {
|
||||
log.Errorf("could not get initial namespace: %v", err)
|
||||
}
|
||||
initNl, err = netlink.NewHandle()
|
||||
initNl, err = netlink.NewHandle(getSupportedNlFamilies()...)
|
||||
if err != nil {
|
||||
log.Errorf("could not create netlink handle on initial namespace: %v", err)
|
||||
}
|
||||
|
@ -32,6 +34,7 @@ func Init() {
|
|||
|
||||
// SetNamespace sets the initial namespace handler
|
||||
func SetNamespace() error {
|
||||
initOnce.Do(Init)
|
||||
if err := netns.Set(initNs); err != nil {
|
||||
linkInfo, linkErr := getLink()
|
||||
if linkErr != nil {
|
||||
|
@ -62,3 +65,22 @@ func NlHandle() *netlink.Handle {
|
|||
initOnce.Do(Init)
|
||||
return initNl
|
||||
}
|
||||
|
||||
func getSupportedNlFamilies() []int {
|
||||
fams := []int{syscall.NETLINK_ROUTE}
|
||||
if err := loadXfrmModules(); err != nil {
|
||||
log.Warnf("Could not load necessary modules for IPSEC rules: %v", err)
|
||||
return fams
|
||||
}
|
||||
return append(fams, syscall.NETLINK_XFRM)
|
||||
}
|
||||
|
||||
func loadXfrmModules() error {
|
||||
if out, err := exec.Command("modprobe", "-va", "xfrm_user").CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("Running modprobe xfrm_user failed with message: `%s`, error: %v", strings.TrimSpace(string(out)), err)
|
||||
}
|
||||
if out, err := exec.Command("modprobe", "-va", "xfrm_algo").CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("Running modprobe xfrm_algo failed with message: `%s`, error: %v", strings.TrimSpace(string(out)), err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -30,7 +30,6 @@ var (
|
|||
gpmWg sync.WaitGroup
|
||||
gpmCleanupPeriod = 60 * time.Second
|
||||
gpmChan = make(chan chan struct{})
|
||||
nsOnce sync.Once
|
||||
)
|
||||
|
||||
// The networkNamespace type is the linux implementation of the Sandbox
|
||||
|
@ -196,7 +195,7 @@ func NewSandbox(key string, osCreate, isRestore bool) (Sandbox, error) {
|
|||
}
|
||||
defer sboxNs.Close()
|
||||
|
||||
n.nlHandle, err = netlink.NewHandleAt(sboxNs)
|
||||
n.nlHandle, err = netlink.NewHandleAt(sboxNs, syscall.NETLINK_ROUTE)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create a netlink handle: %v", err)
|
||||
}
|
||||
|
@ -238,7 +237,7 @@ func GetSandboxForExternalKey(basePath string, key string) (Sandbox, error) {
|
|||
}
|
||||
defer sboxNs.Close()
|
||||
|
||||
n.nlHandle, err = netlink.NewHandleAt(sboxNs)
|
||||
n.nlHandle, err = netlink.NewHandleAt(sboxNs, syscall.NETLINK_ROUTE)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create a netlink handle: %v", err)
|
||||
}
|
||||
|
@ -326,7 +325,6 @@ func (n *networkNamespace) InvokeFunc(f func()) error {
|
|||
|
||||
// InitOSContext initializes OS context while configuring network resources
|
||||
func InitOSContext() func() {
|
||||
nsOnce.Do(ns.Init)
|
||||
runtime.LockOSThread()
|
||||
if err := ns.SetNamespace(); err != nil {
|
||||
log.Error(err)
|
||||
|
|
|
@ -197,7 +197,7 @@ func TestDisableIPv6DAD(t *testing.T) {
|
|||
LinkAttrs: netlink.LinkAttrs{Name: "sideA"},
|
||||
PeerName: "sideB",
|
||||
}
|
||||
nlh, err := netlink.NewHandle()
|
||||
nlh, err := netlink.NewHandle(syscall.NETLINK_ROUTE)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue