This file is indexed.

/usr/share/gocode/src/github.com/docker/libnetwork/drivers/bridge/setup_bridgenetfiltering.go is in golang-github-docker-libnetwork-dev 0.8.0-dev.2+git20170202.599.45b4086-3.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
package bridge

import (
	"fmt"
	"io/ioutil"
	"os"
	"syscall"

	"github.com/Sirupsen/logrus"
)

// Enumeration type saying which versions of IP protocol to process.
type ipVersion int

const (
	ipvnone ipVersion = iota
	ipv4
	ipv6
	ipvboth
)

//Gets the IP version in use ( [ipv4], [ipv6] or [ipv4 and ipv6] )
func getIPVersion(config *networkConfiguration) ipVersion {
	ipVersion := ipv4
	if config.AddressIPv6 != nil || config.EnableIPv6 {
		ipVersion |= ipv6
	}
	return ipVersion
}

func setupBridgeNetFiltering(config *networkConfiguration, i *bridgeInterface) error {
	err := checkBridgeNetFiltering(config, i)
	if err != nil {
		if ptherr, ok := err.(*os.PathError); ok {
			if errno, ok := ptherr.Err.(syscall.Errno); ok && errno == syscall.ENOENT {
				if isRunningInContainer() {
					logrus.Warnf("running inside docker container, ignoring missing kernel params: %v", err)
					err = nil
				} else {
					err = fmt.Errorf("please ensure that br_netfilter kernel module is loaded")
				}
			}
		}
		if err != nil {
			return fmt.Errorf("cannot restrict inter-container communication: %v", err)
		}
	}
	return nil
}

//Enable bridge net filtering if ip forwarding is enabled. See github issue #11404
func checkBridgeNetFiltering(config *networkConfiguration, i *bridgeInterface) error {
	ipVer := getIPVersion(config)
	iface := config.BridgeName
	doEnable := func(ipVer ipVersion) error {
		var ipVerName string
		if ipVer == ipv4 {
			ipVerName = "IPv4"
		} else {
			ipVerName = "IPv6"
		}
		enabled, err := isPacketForwardingEnabled(ipVer, iface)
		if err != nil {
			logrus.Warnf("failed to check %s forwarding: %v", ipVerName, err)
		} else if enabled {
			enabled, err := getKernelBoolParam(getBridgeNFKernelParam(ipVer))
			if err != nil || enabled {
				return err
			}
			return setKernelBoolParam(getBridgeNFKernelParam(ipVer), true)
		}
		return nil
	}

	switch ipVer {
	case ipv4, ipv6:
		return doEnable(ipVer)
	case ipvboth:
		v4err := doEnable(ipv4)
		v6err := doEnable(ipv6)
		if v4err == nil {
			return v6err
		}
		return v4err
	default:
		return nil
	}
}

// Get kernel param path saying whether IPv${ipVer} traffic is being forwarded
// on particular interface. Interface may be specified for IPv6 only. If
// `iface` is empty, `default` will be assumed, which represents default value
// for new interfaces.
func getForwardingKernelParam(ipVer ipVersion, iface string) string {
	switch ipVer {
	case ipv4:
		return "/proc/sys/net/ipv4/ip_forward"
	case ipv6:
		if iface == "" {
			iface = "default"
		}
		return fmt.Sprintf("/proc/sys/net/ipv6/conf/%s/forwarding", iface)
	default:
		return ""
	}
}

// Get kernel param path saying whether bridged IPv${ipVer} traffic shall be
// passed to ip${ipVer}tables' chains.
func getBridgeNFKernelParam(ipVer ipVersion) string {
	switch ipVer {
	case ipv4:
		return "/proc/sys/net/bridge/bridge-nf-call-iptables"
	case ipv6:
		return "/proc/sys/net/bridge/bridge-nf-call-ip6tables"
	default:
		return ""
	}
}

//Gets the value of the kernel parameters located at the given path
func getKernelBoolParam(path string) (bool, error) {
	enabled := false
	line, err := ioutil.ReadFile(path)
	if err != nil {
		return false, err
	}
	if len(line) > 0 {
		enabled = line[0] == '1'
	}
	return enabled, err
}

//Sets the value of the kernel parameter located at the given path
func setKernelBoolParam(path string, on bool) error {
	value := byte('0')
	if on {
		value = byte('1')
	}
	return ioutil.WriteFile(path, []byte{value, '\n'}, 0644)
}

//Checks to see if packet forwarding is enabled
func isPacketForwardingEnabled(ipVer ipVersion, iface string) (bool, error) {
	switch ipVer {
	case ipv4, ipv6:
		return getKernelBoolParam(getForwardingKernelParam(ipVer, iface))
	case ipvboth:
		enabled, err := getKernelBoolParam(getForwardingKernelParam(ipv4, ""))
		if err != nil || !enabled {
			return enabled, err
		}
		return getKernelBoolParam(getForwardingKernelParam(ipv6, iface))
	default:
		return true, nil
	}
}

func isRunningInContainer() bool {
	_, err := os.Stat("/.dockerenv")
	return !os.IsNotExist(err)
}