podman

Форк
0
/
networking_slirp4netns.go 
106 строк · 3.3 Кб
1
//go:build !remote && linux
2

3
package libpod
4

5
import (
6
	"fmt"
7
	"io"
8
	"net"
9
	"os"
10
	"path/filepath"
11

12
	"github.com/containers/common/libnetwork/slirp4netns"
13
	"github.com/containers/common/libnetwork/types"
14
	"github.com/containers/podman/v5/pkg/errorhandling"
15
	"github.com/sirupsen/logrus"
16
)
17

18
// setupSlirp4netns can be called in rootful as well as in rootless
19
func (r *Runtime) setupSlirp4netns(ctr *Container, netns string) error {
20
	ports := ctr.convertPortMappings()
21

22
	if !ctr.config.PostConfigureNetNS {
23
		var err error
24
		ctr.rootlessSlirpSyncR, ctr.rootlessSlirpSyncW, err = os.Pipe()
25
		if err != nil {
26
			return fmt.Errorf("failed to create rootless network sync pipe: %w", err)
27
		}
28
		if len(ports) > 0 {
29
			ctr.rootlessPortSyncR, ctr.rootlessPortSyncW, err = os.Pipe()
30
			if err != nil {
31
				return fmt.Errorf("failed to create rootless port sync pipe: %w", err)
32
			}
33
		}
34
	}
35
	defer errorhandling.CloseQuiet(ctr.rootlessSlirpSyncR)
36
	if ctr.rootlessPortSyncR != nil {
37
		defer errorhandling.CloseQuiet(ctr.rootlessPortSyncR)
38
	}
39

40
	res, err := slirp4netns.Setup(&slirp4netns.SetupOptions{
41
		Config:                r.config,
42
		ContainerID:           ctr.ID(),
43
		Netns:                 netns,
44
		Ports:                 ports,
45
		ExtraOptions:          ctr.config.NetworkOptions[slirp4netns.BinaryName],
46
		Slirp4netnsExitPipeR:  ctr.rootlessSlirpSyncR,
47
		RootlessPortExitPipeR: ctr.rootlessPortSyncR,
48
	})
49
	if err != nil {
50
		return err
51
	}
52
	ctr.slirp4netnsSubnet = res.Subnet
53
	return nil
54
}
55

56
func (r *Runtime) setupRootlessPortMappingViaRLK(ctr *Container, netnsPath string, netStatus map[string]types.StatusBlock) error {
57
	var err error
58
	if !ctr.config.PostConfigureNetNS {
59
		ctr.rootlessPortSyncR, ctr.rootlessPortSyncW, err = os.Pipe()
60
		if err != nil {
61
			return fmt.Errorf("failed to create rootless port sync pipe: %w", err)
62
		}
63
	}
64
	defer errorhandling.CloseQuiet(ctr.rootlessPortSyncR)
65
	return slirp4netns.SetupRootlessPortMappingViaRLK(&slirp4netns.SetupOptions{
66
		Config:                r.config,
67
		ContainerID:           ctr.ID(),
68
		Netns:                 netnsPath,
69
		Ports:                 ctr.convertPortMappings(),
70
		RootlessPortExitPipeR: ctr.rootlessPortSyncR,
71
	}, nil, netStatus)
72
}
73

74
// reloadRootlessRLKPortMapping will trigger a reload for the port mappings in the rootlessport process.
75
// This should only be called by network connect/disconnect and only as rootless.
76
func (c *Container) reloadRootlessRLKPortMapping() error {
77
	if len(c.config.PortMappings) == 0 {
78
		return nil
79
	}
80
	childIP := slirp4netns.GetRootlessPortChildIP(nil, c.state.NetworkStatus)
81
	logrus.Debugf("reloading rootless ports for container %s, childIP is %s", c.config.ID, childIP)
82

83
	conn, err := openUnixSocket(filepath.Join(c.runtime.config.Engine.TmpDir, "rp", c.config.ID))
84
	if err != nil {
85
		return fmt.Errorf("could not reload rootless port mappings, port forwarding may no longer work correctly: %w", err)
86
	}
87
	defer conn.Close()
88
	enc := json.NewEncoder(conn)
89
	err = enc.Encode(childIP)
90
	if err != nil {
91
		return fmt.Errorf("port reloading failed: %w", err)
92
	}
93
	b, err := io.ReadAll(conn)
94
	if err != nil {
95
		return fmt.Errorf("port reloading failed: %w", err)
96
	}
97
	data := string(b)
98
	if data != "OK" {
99
		return fmt.Errorf("port reloading failed: %s", data)
100
	}
101
	return nil
102
}
103

104
func getSlirp4netnsIP(subnet *net.IPNet) (*net.IP, error) {
105
	return slirp4netns.GetIP(subnet)
106
}
107

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.