7 "github.com/Sirupsen/logrus"
8 "github.com/docker/libnetwork/netlabel"
9 "github.com/docker/libnetwork/types"
16 var procGwNetwork = make(chan (bool), 1)
19 libnetwork creates a bridge network "docker_gw_bridge" for providing
20 default gateway for the containers if none of the container's endpoints
21 have GW set by the driver. ICC is set to false for the GW_bridge network.
23 If a driver can't provide external connectivity it can choose to not set
24 the GW IP for the endpoint.
26 endpoint on the GW_bridge network is managed dynamically by libnetwork.
28 - its created when an endpoint without GW joins the container
29 - its deleted when an endpoint with GW joins the container
32 func (sb *sandbox) setupDefaultGW() error {
34 // check if the container already has a GW endpoint
35 if ep := sb.getEndpointInGWNetwork(); ep != nil {
41 // Look for default gw network. In case of error (includes not found),
42 // retry and create it if needed in a serialized execution.
43 n, err := c.NetworkByName(libnGWNetwork)
45 if n, err = c.defaultGwNetwork(); err != nil {
50 createOptions := []EndpointOption{CreateOptionAnonymous()}
53 if len(sb.containerID) < gwEPlen {
54 eplen = len(sb.containerID)
57 sbLabels := sb.Labels()
59 if sbLabels[netlabel.PortMap] != nil {
60 createOptions = append(createOptions, CreateOptionPortMapping(sbLabels[netlabel.PortMap].([]types.PortBinding)))
63 if sbLabels[netlabel.ExposedPorts] != nil {
64 createOptions = append(createOptions, CreateOptionExposedPorts(sbLabels[netlabel.ExposedPorts].([]types.TransportPort)))
67 epOption := getPlatformOption()
69 createOptions = append(createOptions, epOption)
72 newEp, err := n.CreateEndpoint("gateway_"+sb.containerID[0:eplen], createOptions...)
74 return fmt.Errorf("container %s: endpoint create on GW Network failed: %v", sb.containerID, err)
79 if err2 := newEp.Delete(true); err2 != nil {
80 logrus.Warnf("Failed to remove gw endpoint for container %s after failing to join the gateway network: %v",
86 epLocal := newEp.(*endpoint)
88 if err = epLocal.sbJoin(sb); err != nil {
89 return fmt.Errorf("container %s: endpoint join on GW Network failed: %v", sb.containerID, err)
95 // If present, detach and remove the endpoint connecting the sandbox to the default gw network.
96 func (sb *sandbox) clearDefaultGW() error {
99 if ep = sb.getEndpointInGWNetwork(); ep == nil {
102 if err := ep.sbLeave(sb, false); err != nil {
103 return fmt.Errorf("container %s: endpoint leaving GW Network failed: %v", sb.containerID, err)
105 if err := ep.Delete(false); err != nil {
106 return fmt.Errorf("container %s: deleting endpoint on GW Network failed: %v", sb.containerID, err)
111 // Evaluate whether the sandbox requires a default gateway based
112 // on the endpoints to which it is connected. It does not account
113 // for the default gateway network endpoint.
115 func (sb *sandbox) needDefaultGW() bool {
118 for _, ep := range sb.getConnectedEndpoints() {
119 if ep.endpointInGWNetwork() {
122 if ep.getNetwork().Type() == "null" || ep.getNetwork().Type() == "host" {
125 if ep.getNetwork().Internal() {
128 // During stale sandbox cleanup, joinInfo may be nil
129 if ep.joinInfo != nil && ep.joinInfo.disableGatewayService {
132 // TODO v6 needs to be handled.
133 if len(ep.Gateway()) > 0 {
136 for _, r := range ep.StaticRoutes() {
137 if r.Destination != nil && r.Destination.String() == "0.0.0.0/0" {
147 func (sb *sandbox) getEndpointInGWNetwork() *endpoint {
148 for _, ep := range sb.getConnectedEndpoints() {
149 if ep.getNetwork().name == libnGWNetwork && strings.HasPrefix(ep.Name(), "gateway_") {
156 func (ep *endpoint) endpointInGWNetwork() bool {
157 if ep.getNetwork().name == libnGWNetwork && strings.HasPrefix(ep.Name(), "gateway_") {
163 func (sb *sandbox) getEPwithoutGateway() *endpoint {
164 for _, ep := range sb.getConnectedEndpoints() {
165 if ep.getNetwork().Type() == "null" || ep.getNetwork().Type() == "host" {
168 if len(ep.Gateway()) == 0 {
175 // Looks for the default gw network and creates it if not there.
176 // Parallel executions are serialized.
177 func (c *controller) defaultGwNetwork() (Network, error) {
178 procGwNetwork <- true
179 defer func() { <-procGwNetwork }()
181 n, err := c.NetworkByName(libnGWNetwork)
183 if _, ok := err.(types.NotFoundError); ok {
184 n, err = c.createGWNetwork()
190 // Returns the endpoint which is providing external connectivity to the sandbox
191 func (sb *sandbox) getGatewayEndpoint() *endpoint {
192 for _, ep := range sb.getConnectedEndpoints() {
193 if ep.getNetwork().Type() == "null" || ep.getNetwork().Type() == "host" {
196 if len(ep.Gateway()) != 0 {