Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
| ... | ... |
@@ -3,7 +3,7 @@ |
| 3 | 3 |
# LIBNETWORK_COMMIT is used to build the docker-userland-proxy binary. When |
| 4 | 4 |
# updating the binary version, consider updating github.com/docker/libnetwork |
| 5 | 5 |
# in vendor.conf accordingly |
| 6 |
-LIBNETWORK_COMMIT=c15b372ef22125880d378167dde44f4b134e1a77 |
|
| 6 |
+LIBNETWORK_COMMIT=3931ba4d815e385ab97093c64477b82f14dadefb |
|
| 7 | 7 |
|
| 8 | 8 |
install_proxy() {
|
| 9 | 9 |
case "$1" in |
| ... | ... |
@@ -35,7 +35,7 @@ github.com/opentracing/opentracing-go 1361b9cd60be79c4c3a7fa9841b3c132e40066a7 |
| 35 | 35 |
#get libnetwork packages |
| 36 | 36 |
|
| 37 | 37 |
# When updating, also update LIBNETWORK_COMMIT in hack/dockerfile/install/proxy accordingly |
| 38 |
-github.com/docker/libnetwork eb6b2a57955e5c149d47c3973573216e8f8baa09 |
|
| 38 |
+github.com/docker/libnetwork 3931ba4d815e385ab97093c64477b82f14dadefb |
|
| 39 | 39 |
github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9 |
| 40 | 40 |
github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80 |
| 41 | 41 |
github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec |
| ... | ... |
@@ -44,7 +44,6 @@ create network namespaces and allocate interfaces for containers to use. |
| 44 | 44 |
package libnetwork |
| 45 | 45 |
|
| 46 | 46 |
import ( |
| 47 |
- "container/heap" |
|
| 48 | 47 |
"fmt" |
| 49 | 48 |
"net" |
| 50 | 49 |
"path/filepath" |
| ... | ... |
@@ -1085,7 +1084,7 @@ func (c *controller) NewSandbox(containerID string, options ...SandboxOption) (S |
| 1085 | 1085 |
sb = &sandbox{
|
| 1086 | 1086 |
id: sandboxID, |
| 1087 | 1087 |
containerID: containerID, |
| 1088 |
- endpoints: epHeap{},
|
|
| 1088 |
+ endpoints: []*endpoint{},
|
|
| 1089 | 1089 |
epPriority: map[string]int{},
|
| 1090 | 1090 |
populatedEndpoints: map[string]struct{}{},
|
| 1091 | 1091 |
config: containerConfig{},
|
| ... | ... |
@@ -1094,8 +1093,6 @@ func (c *controller) NewSandbox(containerID string, options ...SandboxOption) (S |
| 1094 | 1094 |
} |
| 1095 | 1095 |
} |
| 1096 | 1096 |
|
| 1097 |
- heap.Init(&sb.endpoints) |
|
| 1098 |
- |
|
| 1099 | 1097 |
sb.processOptions(options...) |
| 1100 | 1098 |
|
| 1101 | 1099 |
c.Lock() |
| ... | ... |
@@ -706,8 +706,8 @@ func (d *driver) createNetwork(config *networkConfiguration) error {
|
| 706 | 706 |
// Enable IPv6 Forwarding |
| 707 | 707 |
{enableIPv6Forwarding, setupIPv6Forwarding},
|
| 708 | 708 |
|
| 709 |
- // Setup Loopback Adresses Routing |
|
| 710 |
- {!d.config.EnableUserlandProxy, setupLoopbackAdressesRouting},
|
|
| 709 |
+ // Setup Loopback Addresses Routing |
|
| 710 |
+ {!d.config.EnableUserlandProxy, setupLoopbackAddressesRouting},
|
|
| 711 | 711 |
|
| 712 | 712 |
// Setup IPTables. |
| 713 | 713 |
{d.config.EnableIPTables, network.setupIPTables},
|
| ... | ... |
@@ -64,13 +64,13 @@ func setupGatewayIPv4(config *networkConfiguration, i *bridgeInterface) error {
|
| 64 | 64 |
return nil |
| 65 | 65 |
} |
| 66 | 66 |
|
| 67 |
-func setupLoopbackAdressesRouting(config *networkConfiguration, i *bridgeInterface) error {
|
|
| 67 |
+func setupLoopbackAddressesRouting(config *networkConfiguration, i *bridgeInterface) error {
|
|
| 68 | 68 |
sysPath := filepath.Join("/proc/sys/net/ipv4/conf", config.BridgeName, "route_localnet")
|
| 69 | 69 |
ipv4LoRoutingData, err := ioutil.ReadFile(sysPath) |
| 70 | 70 |
if err != nil {
|
| 71 | 71 |
return fmt.Errorf("Cannot read IPv4 local routing setup: %v", err)
|
| 72 | 72 |
} |
| 73 |
- // Enable loopback adresses routing only if it isn't already enabled |
|
| 73 |
+ // Enable loopback addresses routing only if it isn't already enabled |
|
| 74 | 74 |
if ipv4LoRoutingData[0] != '1' {
|
| 75 | 75 |
if err := ioutil.WriteFile(sysPath, []byte{'1', '\n'}, 0644); err != nil {
|
| 76 | 76 |
return fmt.Errorf("Unable to enable local routing for hairpin mode: %v", err)
|
| ... | ... |
@@ -150,7 +150,7 @@ func parseVlan(linkName string) (string, int, error) {
|
| 150 | 150 |
} |
| 151 | 151 |
// Check if the interface exists |
| 152 | 152 |
if !parentExists(parent) {
|
| 153 |
- return "", 0, fmt.Errorf("-o parent interface does was not found on the host: %s", parent)
|
|
| 153 |
+ return "", 0, fmt.Errorf("-o parent interface was not found on the host: %s", parent)
|
|
| 154 | 154 |
} |
| 155 | 155 |
|
| 156 | 156 |
return parent, vidInt, nil |
| ... | ... |
@@ -1,7 +1,6 @@ |
| 1 | 1 |
package libnetwork |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
- "container/heap" |
|
| 5 | 4 |
"encoding/json" |
| 6 | 5 |
"fmt" |
| 7 | 6 |
"net" |
| ... | ... |
@@ -514,9 +513,7 @@ func (ep *endpoint) sbJoin(sb *sandbox, options ...EndpointOption) (err error) {
|
| 514 | 514 |
// Current endpoint providing external connectivity for the sandbox |
| 515 | 515 |
extEp := sb.getGatewayEndpoint() |
| 516 | 516 |
|
| 517 |
- sb.Lock() |
|
| 518 |
- heap.Push(&sb.endpoints, ep) |
|
| 519 |
- sb.Unlock() |
|
| 517 |
+ sb.addEndpoint(ep) |
|
| 520 | 518 |
defer func() {
|
| 521 | 519 |
if err != nil {
|
| 522 | 520 |
sb.removeEndpoint(ep) |
| ... | ... |
@@ -755,10 +752,8 @@ func (ep *endpoint) sbLeave(sb *sandbox, force bool, options ...EndpointOption) |
| 755 | 755 |
} |
| 756 | 756 |
} |
| 757 | 757 |
|
| 758 |
- if ep.svcID != "" {
|
|
| 759 |
- if err := ep.deleteServiceInfoFromCluster(sb, true, "sbLeave"); err != nil {
|
|
| 760 |
- logrus.Warnf("Failed to clean up service info on container %s disconnect: %v", ep.name, err)
|
|
| 761 |
- } |
|
| 758 |
+ if err := ep.deleteServiceInfoFromCluster(sb, true, "sbLeave"); err != nil {
|
|
| 759 |
+ logrus.Warnf("Failed to clean up service info on container %s disconnect: %v", ep.name, err)
|
|
| 762 | 760 |
} |
| 763 | 761 |
|
| 764 | 762 |
if err := sb.clearNetworkResources(ep); err != nil {
|
| ... | ... |
@@ -389,7 +389,7 @@ func (a *Allocator) getPredefinedPool(as string, ipV6 bool) (*net.IPNet, error) |
| 389 | 389 |
} |
| 390 | 390 |
|
| 391 | 391 |
if as != localAddressSpace && as != globalAddressSpace {
|
| 392 |
- return nil, types.NotImplementedErrorf("no default pool availbale for non-default addresss spaces")
|
|
| 392 |
+ return nil, types.NotImplementedErrorf("no default pool available for non-default address spaces")
|
|
| 393 | 393 |
} |
| 394 | 394 |
|
| 395 | 395 |
aSpace, err := a.getAddrSpace(as) |
| ... | ... |
@@ -280,7 +280,7 @@ func (r *resolver) handleIPQuery(name string, query *dns.Msg, ipType int) (*dns. |
| 280 | 280 |
} |
| 281 | 281 |
|
| 282 | 282 |
func (r *resolver) handlePTRQuery(ptr string, query *dns.Msg) (*dns.Msg, error) {
|
| 283 |
- parts := []string{}
|
|
| 283 |
+ var parts []string |
|
| 284 | 284 |
|
| 285 | 285 |
if strings.HasSuffix(ptr, ptrIPv4domain) {
|
| 286 | 286 |
parts = strings.Split(ptr, ptrIPv4domain) |
| ... | ... |
@@ -1,10 +1,10 @@ |
| 1 | 1 |
package libnetwork |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
- "container/heap" |
|
| 5 | 4 |
"encoding/json" |
| 6 | 5 |
"fmt" |
| 7 | 6 |
"net" |
| 7 |
+ "sort" |
|
| 8 | 8 |
"strings" |
| 9 | 9 |
"sync" |
| 10 | 10 |
"time" |
| ... | ... |
@@ -63,8 +63,6 @@ func (sb *sandbox) processOptions(options ...SandboxOption) {
|
| 63 | 63 |
} |
| 64 | 64 |
} |
| 65 | 65 |
|
| 66 |
-type epHeap []*endpoint |
|
| 67 |
- |
|
| 68 | 66 |
type sandbox struct {
|
| 69 | 67 |
id string |
| 70 | 68 |
containerID string |
| ... | ... |
@@ -75,7 +73,7 @@ type sandbox struct {
|
| 75 | 75 |
resolver Resolver |
| 76 | 76 |
resolverOnce sync.Once |
| 77 | 77 |
refCnt int |
| 78 |
- endpoints epHeap |
|
| 78 |
+ endpoints []*endpoint |
|
| 79 | 79 |
epPriority map[string]int |
| 80 | 80 |
populatedEndpoints map[string]struct{}
|
| 81 | 81 |
joinLeaveDone chan struct{}
|
| ... | ... |
@@ -353,20 +351,36 @@ func (sb *sandbox) getConnectedEndpoints() []*endpoint {
|
| 353 | 353 |
defer sb.Unlock() |
| 354 | 354 |
|
| 355 | 355 |
eps := make([]*endpoint, len(sb.endpoints)) |
| 356 |
- for i, ep := range sb.endpoints {
|
|
| 357 |
- eps[i] = ep |
|
| 358 |
- } |
|
| 356 |
+ copy(eps, sb.endpoints) |
|
| 359 | 357 |
|
| 360 | 358 |
return eps |
| 361 | 359 |
} |
| 362 | 360 |
|
| 361 |
+func (sb *sandbox) addEndpoint(ep *endpoint) {
|
|
| 362 |
+ sb.Lock() |
|
| 363 |
+ defer sb.Unlock() |
|
| 364 |
+ |
|
| 365 |
+ l := len(sb.endpoints) |
|
| 366 |
+ i := sort.Search(l, func(j int) bool {
|
|
| 367 |
+ return ep.Less(sb.endpoints[j]) |
|
| 368 |
+ }) |
|
| 369 |
+ |
|
| 370 |
+ sb.endpoints = append(sb.endpoints, nil) |
|
| 371 |
+ copy(sb.endpoints[i+1:], sb.endpoints[i:]) |
|
| 372 |
+ sb.endpoints[i] = ep |
|
| 373 |
+} |
|
| 374 |
+ |
|
| 363 | 375 |
func (sb *sandbox) removeEndpoint(ep *endpoint) {
|
| 364 | 376 |
sb.Lock() |
| 365 | 377 |
defer sb.Unlock() |
| 366 | 378 |
|
| 379 |
+ sb.removeEndpointRaw(ep) |
|
| 380 |
+} |
|
| 381 |
+ |
|
| 382 |
+func (sb *sandbox) removeEndpointRaw(ep *endpoint) {
|
|
| 367 | 383 |
for i, e := range sb.endpoints {
|
| 368 | 384 |
if e == ep {
|
| 369 |
- heap.Remove(&sb.endpoints, i) |
|
| 385 |
+ sb.endpoints = append(sb.endpoints[:i], sb.endpoints[i+1:]...) |
|
| 370 | 386 |
return |
| 371 | 387 |
} |
| 372 | 388 |
} |
| ... | ... |
@@ -940,7 +954,7 @@ func (sb *sandbox) clearNetworkResources(origEp *endpoint) error {
|
| 940 | 940 |
return nil |
| 941 | 941 |
} |
| 942 | 942 |
|
| 943 |
- heap.Remove(&sb.endpoints, index) |
|
| 943 |
+ sb.removeEndpointRaw(ep) |
|
| 944 | 944 |
for _, e := range sb.endpoints {
|
| 945 | 945 |
if len(e.Gateway()) > 0 {
|
| 946 | 946 |
gwepAfter = e |
| ... | ... |
@@ -1165,80 +1179,69 @@ func OptionIngress() SandboxOption {
|
| 1165 | 1165 |
} |
| 1166 | 1166 |
} |
| 1167 | 1167 |
|
| 1168 |
-func (eh epHeap) Len() int { return len(eh) }
|
|
| 1169 |
- |
|
| 1170 |
-func (eh epHeap) Less(i, j int) bool {
|
|
| 1168 |
+// <=> Returns true if a < b, false if a > b and advances to next level if a == b |
|
| 1169 |
+// epi.prio <=> epj.prio # 2 < 1 |
|
| 1170 |
+// epi.gw <=> epj.gw # non-gw < gw |
|
| 1171 |
+// epi.internal <=> epj.internal # non-internal < internal |
|
| 1172 |
+// epi.joininfo <=> epj.joininfo # ipv6 < ipv4 |
|
| 1173 |
+// epi.name <=> epj.name # bar < foo |
|
| 1174 |
+func (epi *endpoint) Less(epj *endpoint) bool {
|
|
| 1171 | 1175 |
var ( |
| 1172 |
- cip, cjp int |
|
| 1173 |
- ok bool |
|
| 1176 |
+ prioi, prioj int |
|
| 1174 | 1177 |
) |
| 1175 | 1178 |
|
| 1176 |
- ci, _ := eh[i].getSandbox() |
|
| 1177 |
- cj, _ := eh[j].getSandbox() |
|
| 1178 |
- |
|
| 1179 |
- epi := eh[i] |
|
| 1180 |
- epj := eh[j] |
|
| 1179 |
+ sbi, _ := epi.getSandbox() |
|
| 1180 |
+ sbj, _ := epj.getSandbox() |
|
| 1181 | 1181 |
|
| 1182 |
- if epi.endpointInGWNetwork() {
|
|
| 1183 |
- return false |
|
| 1182 |
+ // Prio defaults to 0 |
|
| 1183 |
+ if sbi != nil {
|
|
| 1184 |
+ prioi = sbi.epPriority[epi.ID()] |
|
| 1185 |
+ } |
|
| 1186 |
+ if sbj != nil {
|
|
| 1187 |
+ prioj = sbj.epPriority[epj.ID()] |
|
| 1184 | 1188 |
} |
| 1185 | 1189 |
|
| 1186 |
- if epj.endpointInGWNetwork() {
|
|
| 1187 |
- return true |
|
| 1190 |
+ if prioi != prioj {
|
|
| 1191 |
+ return prioi > prioj |
|
| 1188 | 1192 |
} |
| 1189 | 1193 |
|
| 1190 |
- if epi.getNetwork().Internal() {
|
|
| 1191 |
- return false |
|
| 1194 |
+ gwi := epi.endpointInGWNetwork() |
|
| 1195 |
+ gwj := epj.endpointInGWNetwork() |
|
| 1196 |
+ if gwi != gwj {
|
|
| 1197 |
+ return gwj |
|
| 1192 | 1198 |
} |
| 1193 | 1199 |
|
| 1194 |
- if epj.getNetwork().Internal() {
|
|
| 1195 |
- return true |
|
| 1200 |
+ inti := epi.getNetwork().Internal() |
|
| 1201 |
+ intj := epj.getNetwork().Internal() |
|
| 1202 |
+ if inti != intj {
|
|
| 1203 |
+ return intj |
|
| 1196 | 1204 |
} |
| 1197 | 1205 |
|
| 1198 |
- if epi.joinInfo != nil && epj.joinInfo != nil {
|
|
| 1199 |
- if (epi.joinInfo.gw != nil && epi.joinInfo.gw6 != nil) && |
|
| 1200 |
- (epj.joinInfo.gw == nil || epj.joinInfo.gw6 == nil) {
|
|
| 1201 |
- return true |
|
| 1206 |
+ jii := 0 |
|
| 1207 |
+ if epi.joinInfo != nil {
|
|
| 1208 |
+ if epi.joinInfo.gw != nil {
|
|
| 1209 |
+ jii = jii + 1 |
|
| 1202 | 1210 |
} |
| 1203 |
- if (epj.joinInfo.gw != nil && epj.joinInfo.gw6 != nil) && |
|
| 1204 |
- (epi.joinInfo.gw == nil || epi.joinInfo.gw6 == nil) {
|
|
| 1205 |
- return false |
|
| 1211 |
+ if epi.joinInfo.gw6 != nil {
|
|
| 1212 |
+ jii = jii + 2 |
|
| 1206 | 1213 |
} |
| 1207 | 1214 |
} |
| 1208 | 1215 |
|
| 1209 |
- if ci != nil {
|
|
| 1210 |
- cip, ok = ci.epPriority[eh[i].ID()] |
|
| 1211 |
- if !ok {
|
|
| 1212 |
- cip = 0 |
|
| 1216 |
+ jij := 0 |
|
| 1217 |
+ if epj.joinInfo != nil {
|
|
| 1218 |
+ if epj.joinInfo.gw != nil {
|
|
| 1219 |
+ jij = jij + 1 |
|
| 1213 | 1220 |
} |
| 1214 |
- } |
|
| 1215 |
- |
|
| 1216 |
- if cj != nil {
|
|
| 1217 |
- cjp, ok = cj.epPriority[eh[j].ID()] |
|
| 1218 |
- if !ok {
|
|
| 1219 |
- cjp = 0 |
|
| 1221 |
+ if epj.joinInfo.gw6 != nil {
|
|
| 1222 |
+ jij = jij + 2 |
|
| 1220 | 1223 |
} |
| 1221 | 1224 |
} |
| 1222 | 1225 |
|
| 1223 |
- if cip == cjp {
|
|
| 1224 |
- return eh[i].network.Name() < eh[j].network.Name() |
|
| 1226 |
+ if jii != jij {
|
|
| 1227 |
+ return jii > jij |
|
| 1225 | 1228 |
} |
| 1226 | 1229 |
|
| 1227 |
- return cip > cjp |
|
| 1228 |
-} |
|
| 1229 |
- |
|
| 1230 |
-func (eh epHeap) Swap(i, j int) { eh[i], eh[j] = eh[j], eh[i] }
|
|
| 1231 |
- |
|
| 1232 |
-func (eh *epHeap) Push(x interface{}) {
|
|
| 1233 |
- *eh = append(*eh, x.(*endpoint)) |
|
| 1234 |
-} |
|
| 1235 |
- |
|
| 1236 |
-func (eh *epHeap) Pop() interface{} {
|
|
| 1237 |
- old := *eh |
|
| 1238 |
- n := len(old) |
|
| 1239 |
- x := old[n-1] |
|
| 1240 |
- *eh = old[0 : n-1] |
|
| 1241 |
- return x |
|
| 1230 |
+ return epi.network.Name() < epj.network.Name() |
|
| 1242 | 1231 |
} |
| 1243 | 1232 |
|
| 1244 | 1233 |
func (sb *sandbox) NdotsSet() bool {
|
| ... | ... |
@@ -1,7 +1,6 @@ |
| 1 | 1 |
package libnetwork |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
- "container/heap" |
|
| 5 | 4 |
"encoding/json" |
| 6 | 5 |
"sync" |
| 7 | 6 |
|
| ... | ... |
@@ -215,7 +214,7 @@ func (c *controller) sandboxCleanup(activeSandboxes map[string]interface{}) {
|
| 215 | 215 |
id: sbs.ID, |
| 216 | 216 |
controller: sbs.c, |
| 217 | 217 |
containerID: sbs.Cid, |
| 218 |
- endpoints: epHeap{},
|
|
| 218 |
+ endpoints: []*endpoint{},
|
|
| 219 | 219 |
populatedEndpoints: map[string]struct{}{},
|
| 220 | 220 |
dbIndex: sbs.dbIndex, |
| 221 | 221 |
isStub: true, |
| ... | ... |
@@ -242,7 +241,6 @@ func (c *controller) sandboxCleanup(activeSandboxes map[string]interface{}) {
|
| 242 | 242 |
sb.processOptions(opts...) |
| 243 | 243 |
sb.restorePath() |
| 244 | 244 |
create = !sb.config.useDefaultSandBox |
| 245 |
- heap.Init(&sb.endpoints) |
|
| 246 | 245 |
} |
| 247 | 246 |
sb.osSbox, err = osl.NewSandbox(sb.Key(), create, isRestore) |
| 248 | 247 |
if err != nil {
|
| ... | ... |
@@ -272,7 +270,7 @@ func (c *controller) sandboxCleanup(activeSandboxes map[string]interface{}) {
|
| 272 | 272 |
logrus.Errorf("failed to restore endpoint %s in %s for container %s due to %v", eps.Eid, eps.Nid, sb.ContainerID(), err)
|
| 273 | 273 |
continue |
| 274 | 274 |
} |
| 275 |
- heap.Push(&sb.endpoints, ep) |
|
| 275 |
+ sb.addEndpoint(ep) |
|
| 276 | 276 |
} |
| 277 | 277 |
|
| 278 | 278 |
if _, ok := activeSandboxes[sb.ID()]; !ok {
|
| ... | ... |
@@ -145,7 +145,7 @@ func (p *PortBinding) String() string {
|
| 145 | 145 |
return ret |
| 146 | 146 |
} |
| 147 | 147 |
|
| 148 |
-// FromString reads the TransportPort structure from string |
|
| 148 |
+// FromString reads the PortBinding structure from string |
|
| 149 | 149 |
func (p *PortBinding) FromString(s string) error {
|
| 150 | 150 |
ps := strings.Split(s, "/") |
| 151 | 151 |
if len(ps) != 3 {
|