1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Vendoring libnetwork for 1.12.1-rc1

* Fixes https://github.com/docker/docker/issues/25236
* Fixes https://github.com/docker/docker/issues/24789
* Fixes https://github.com/docker/docker/issues/25340
* Fixes https://github.com/docker/docker/issues/25130
* Fixes https://github.com/docker/libnetwork/issues/1387
* Fix external DNS responses > 512 bytes getting dropped
* Fix crash when remote plugin returns empty address string
* Make service LB work from self
* Fixed a few race-conditions

Signed-off-by: Madhu Venugopal <madhu@docker.com>
This commit is contained in:
Madhu Venugopal 2016-08-10 23:31:01 -07:00
parent 2a540c18b6
commit 6645ff8ac1
33 changed files with 321 additions and 177 deletions

View file

@ -66,7 +66,7 @@ clone git github.com/RackSec/srslog 259aed10dfa74ea2961eddd1d9847619f6e98837
clone git github.com/imdario/mergo 0.2.1 clone git github.com/imdario/mergo 0.2.1
#get libnetwork packages #get libnetwork packages
clone git github.com/docker/libnetwork 5e7bf83ab07c197d1bef6ec073d9f19ce59e3eb2 clone git github.com/docker/libnetwork f77a0c9f540536c37019cf64d09a9a932dd7b54b
clone git github.com/docker/go-events afb2b9f2c23f33ada1a22b03651775fdc65a5089 clone git github.com/docker/go-events afb2b9f2c23f33ada1a22b03651775fdc65a5089
clone git github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80 clone git github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80
clone git github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec clone git github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec

View file

@ -136,10 +136,16 @@ func (c *controller) handleKeyChange(keys []*types.EncryptionKey) error {
} }
} }
key, tag := c.getPrimaryKeyTag(subsysGossip) key, tag, err := c.getPrimaryKeyTag(subsysGossip)
if err != nil {
return err
}
a.networkDB.SetPrimaryKey(key) a.networkDB.SetPrimaryKey(key)
key, tag = c.getPrimaryKeyTag(subsysIPSec) key, tag, err = c.getPrimaryKeyTag(subsysIPSec)
if err != nil {
return err
}
drvEnc.Primary = key drvEnc.Primary = key
drvEnc.PrimaryTag = tag drvEnc.PrimaryTag = tag
@ -158,82 +164,6 @@ func (c *controller) handleKeyChange(keys []*types.EncryptionKey) error {
return nil return nil
} }
func (c *controller) handleKeyChangeV1(keys []*types.EncryptionKey) error {
drvEnc := discoverapi.DriverEncryptionUpdate{}
// Find the new key and add it to the key ring
a := c.agent
for _, key := range keys {
same := false
for _, cKey := range c.keys {
if same = cKey.LamportTime == key.LamportTime; same {
break
}
}
if !same {
c.keys = append(c.keys, key)
if key.Subsystem == subsysGossip {
a.networkDB.SetKey(key.Key)
}
if key.Subsystem == subsysGossip /*subsysIPSec*/ {
drvEnc.Key = key.Key
drvEnc.Tag = key.LamportTime
}
break
}
}
// Find the deleted key. If the deleted key was the primary key,
// a new primary key should be set before removing if from keyring.
deleted := []byte{}
for i, cKey := range c.keys {
same := false
for _, key := range keys {
if same = key.LamportTime == cKey.LamportTime; same {
break
}
}
if !same {
if cKey.Subsystem == subsysGossip {
deleted = cKey.Key
}
if cKey.Subsystem == subsysGossip /*subsysIPSec*/ {
drvEnc.Prune = cKey.Key
drvEnc.PruneTag = cKey.LamportTime
}
c.keys = append(c.keys[:i], c.keys[i+1:]...)
break
}
}
sort.Sort(ByTime(c.keys))
for _, key := range c.keys {
if key.Subsystem == subsysGossip {
a.networkDB.SetPrimaryKey(key.Key)
break
}
}
for _, key := range c.keys {
if key.Subsystem == subsysGossip /*subsysIPSec*/ {
drvEnc.Primary = key.Key
drvEnc.PrimaryTag = key.LamportTime
break
}
}
if len(deleted) > 0 {
a.networkDB.RemoveKey(deleted)
}
c.drvRegistry.WalkDrivers(func(name string, driver driverapi.Driver, capability driverapi.Capability) bool {
err := driver.DiscoverNew(discoverapi.EncryptionKeysUpdate, drvEnc)
if err != nil {
logrus.Warnf("Failed to update datapath keys in driver %s: %v", name, err)
}
return false
})
return nil
}
func (c *controller) agentSetup() error { func (c *controller) agentSetup() error {
clusterProvider := c.cfg.Daemon.ClusterProvider clusterProvider := c.cfg.Daemon.ClusterProvider
@ -281,17 +211,14 @@ func (c *controller) getKeys(subsys string) ([][]byte, []uint64) {
} }
} }
if len(keys) < keyringSize {
return keys, tags
}
keys[0], keys[1] = keys[1], keys[0] keys[0], keys[1] = keys[1], keys[0]
tags[0], tags[1] = tags[1], tags[0] tags[0], tags[1] = tags[1], tags[0]
return keys, tags return keys, tags
} }
// getPrimaryKeyTag returns the primary key for a given subsytem from the // getPrimaryKeyTag returns the primary key for a given subsystem from the
// list of sorted key and the associated tag // list of sorted key and the associated tag
func (c *controller) getPrimaryKeyTag(subsys string) ([]byte, uint64) { func (c *controller) getPrimaryKeyTag(subsys string) ([]byte, uint64, error) {
sort.Sort(ByTime(c.keys)) sort.Sort(ByTime(c.keys))
keys := []*types.EncryptionKey{} keys := []*types.EncryptionKey{}
for _, key := range c.keys { for _, key := range c.keys {
@ -299,7 +226,7 @@ func (c *controller) getPrimaryKeyTag(subsys string) ([]byte, uint64) {
keys = append(keys, key) keys = append(keys, key)
} }
} }
return keys[1].Key, keys[1].LamportTime return keys[1].Key, keys[1].LamportTime, nil
} }
func (c *controller) agentInit(bindAddrOrInterface, advertiseAddr string) error { func (c *controller) agentInit(bindAddrOrInterface, advertiseAddr string) error {
@ -462,6 +389,7 @@ func (ep *endpoint) addToCluster() error {
VirtualIP: ep.virtualIP.String(), VirtualIP: ep.virtualIP.String(),
IngressPorts: ingressPorts, IngressPorts: ingressPorts,
Aliases: ep.svcAliases, Aliases: ep.svcAliases,
TaskAliases: ep.myAliases,
EndpointIP: ep.Iface().Address().IP.String(), EndpointIP: ep.Iface().Address().IP.String(),
}) })
@ -540,7 +468,10 @@ func (n *network) addDriverWatches() {
} }
c.agent.networkDB.WalkTable(tableName, func(nid, key string, value []byte) bool { c.agent.networkDB.WalkTable(tableName, func(nid, key string, value []byte) bool {
d.EventNotify(driverapi.Create, n.ID(), tableName, key, value) if nid == n.ID() {
d.EventNotify(driverapi.Create, nid, tableName, key, value)
}
return false return false
}) })
} }
@ -653,6 +584,7 @@ func (c *controller) handleEpTableEvent(ev events.Event) {
ip := net.ParseIP(epRec.EndpointIP) ip := net.ParseIP(epRec.EndpointIP)
ingressPorts := epRec.IngressPorts ingressPorts := epRec.IngressPorts
aliases := epRec.Aliases aliases := epRec.Aliases
taskaliases := epRec.TaskAliases
if name == "" || ip == nil { if name == "" || ip == nil {
logrus.Errorf("Invalid endpoint name/ip received while handling service table event %s", value) logrus.Errorf("Invalid endpoint name/ip received while handling service table event %s", value)
@ -668,6 +600,9 @@ func (c *controller) handleEpTableEvent(ev events.Event) {
} }
n.addSvcRecords(name, ip, nil, true) n.addSvcRecords(name, ip, nil, true)
for _, alias := range taskaliases {
n.addSvcRecords(alias, ip, nil, true)
}
} else { } else {
if svcID != "" { if svcID != "" {
if err := c.rmServiceBinding(svcName, svcID, nid, eid, vip, ingressPorts, aliases, ip); err != nil { if err := c.rmServiceBinding(svcName, svcID, nid, eid, vip, ingressPorts, aliases, ip); err != nil {
@ -677,5 +612,8 @@ func (c *controller) handleEpTableEvent(ev events.Event) {
} }
n.deleteSvcRecords(name, ip, nil, true) n.deleteSvcRecords(name, ip, nil, true)
for _, alias := range taskaliases {
n.deleteSvcRecords(alias, ip, nil, true)
}
} }
} }

View file

@ -74,6 +74,8 @@ type EndpointRecord struct {
IngressPorts []*PortConfig `protobuf:"bytes,6,rep,name=ingress_ports,json=ingressPorts" json:"ingress_ports,omitempty"` IngressPorts []*PortConfig `protobuf:"bytes,6,rep,name=ingress_ports,json=ingressPorts" json:"ingress_ports,omitempty"`
// A list of aliases which are alternate names for the service // A list of aliases which are alternate names for the service
Aliases []string `protobuf:"bytes,7,rep,name=aliases" json:"aliases,omitempty"` Aliases []string `protobuf:"bytes,7,rep,name=aliases" json:"aliases,omitempty"`
// List of aliases task specific aliases
TaskAliases []string `protobuf:"bytes,8,rep,name=task_aliases,json=taskAliases" json:"task_aliases,omitempty"`
} }
func (m *EndpointRecord) Reset() { *m = EndpointRecord{} } func (m *EndpointRecord) Reset() { *m = EndpointRecord{} }
@ -122,7 +124,7 @@ func (this *EndpointRecord) GoString() string {
if this == nil { if this == nil {
return "nil" return "nil"
} }
s := make([]string, 0, 11) s := make([]string, 0, 12)
s = append(s, "&libnetwork.EndpointRecord{") s = append(s, "&libnetwork.EndpointRecord{")
s = append(s, "Name: "+fmt.Sprintf("%#v", this.Name)+",\n") s = append(s, "Name: "+fmt.Sprintf("%#v", this.Name)+",\n")
s = append(s, "ServiceName: "+fmt.Sprintf("%#v", this.ServiceName)+",\n") s = append(s, "ServiceName: "+fmt.Sprintf("%#v", this.ServiceName)+",\n")
@ -133,6 +135,7 @@ func (this *EndpointRecord) GoString() string {
s = append(s, "IngressPorts: "+fmt.Sprintf("%#v", this.IngressPorts)+",\n") s = append(s, "IngressPorts: "+fmt.Sprintf("%#v", this.IngressPorts)+",\n")
} }
s = append(s, "Aliases: "+fmt.Sprintf("%#v", this.Aliases)+",\n") s = append(s, "Aliases: "+fmt.Sprintf("%#v", this.Aliases)+",\n")
s = append(s, "TaskAliases: "+fmt.Sprintf("%#v", this.TaskAliases)+",\n")
s = append(s, "}") s = append(s, "}")
return strings.Join(s, "") return strings.Join(s, "")
} }
@ -246,6 +249,21 @@ func (m *EndpointRecord) MarshalTo(data []byte) (int, error) {
i += copy(data[i:], s) i += copy(data[i:], s)
} }
} }
if len(m.TaskAliases) > 0 {
for _, s := range m.TaskAliases {
data[i] = 0x42
i++
l = len(s)
for l >= 1<<7 {
data[i] = uint8(uint64(l)&0x7f | 0x80)
l >>= 7
i++
}
data[i] = uint8(l)
i++
i += copy(data[i:], s)
}
}
return i, nil return i, nil
} }
@ -350,6 +368,12 @@ func (m *EndpointRecord) Size() (n int) {
n += 1 + l + sovAgent(uint64(l)) n += 1 + l + sovAgent(uint64(l))
} }
} }
if len(m.TaskAliases) > 0 {
for _, s := range m.TaskAliases {
l = len(s)
n += 1 + l + sovAgent(uint64(l))
}
}
return n return n
} }
@ -397,6 +421,7 @@ func (this *EndpointRecord) String() string {
`EndpointIP:` + fmt.Sprintf("%v", this.EndpointIP) + `,`, `EndpointIP:` + fmt.Sprintf("%v", this.EndpointIP) + `,`,
`IngressPorts:` + strings.Replace(fmt.Sprintf("%v", this.IngressPorts), "PortConfig", "PortConfig", 1) + `,`, `IngressPorts:` + strings.Replace(fmt.Sprintf("%v", this.IngressPorts), "PortConfig", "PortConfig", 1) + `,`,
`Aliases:` + fmt.Sprintf("%v", this.Aliases) + `,`, `Aliases:` + fmt.Sprintf("%v", this.Aliases) + `,`,
`TaskAliases:` + fmt.Sprintf("%v", this.TaskAliases) + `,`,
`}`, `}`,
}, "") }, "")
return s return s
@ -656,6 +681,35 @@ func (m *EndpointRecord) Unmarshal(data []byte) error {
} }
m.Aliases = append(m.Aliases, string(data[iNdEx:postIndex])) m.Aliases = append(m.Aliases, string(data[iNdEx:postIndex]))
iNdEx = postIndex iNdEx = postIndex
case 8:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field TaskAliases", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowAgent
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := data[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthAgent
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.TaskAliases = append(m.TaskAliases, string(data[iNdEx:postIndex]))
iNdEx = postIndex
default: default:
iNdEx = preIndex iNdEx = preIndex
skippy, err := skipAgent(data[iNdEx:]) skippy, err := skipAgent(data[iNdEx:])
@ -919,30 +973,31 @@ var (
) )
var fileDescriptorAgent = []byte{ var fileDescriptorAgent = []byte{
// 397 bytes of a gzipped FileDescriptorProto // 413 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x6c, 0x90, 0xbf, 0xae, 0xd3, 0x30, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x6c, 0x90, 0xbf, 0xae, 0xd3, 0x30,
0x14, 0xc6, 0x9b, 0xdb, 0x70, 0x6f, 0x73, 0xd2, 0x84, 0xca, 0x42, 0x28, 0xea, 0x90, 0x96, 0x4a, 0x14, 0x87, 0x9b, 0xdb, 0x70, 0x6f, 0x73, 0x72, 0x13, 0xae, 0x2c, 0x84, 0xa2, 0x0e, 0x69, 0xa9,
0x48, 0x1d, 0x50, 0x2a, 0x95, 0xb1, 0x5b, 0x5b, 0x86, 0x2c, 0x28, 0x32, 0x7f, 0xd6, 0x2a, 0x6d, 0x84, 0x74, 0x07, 0x94, 0x2b, 0x95, 0xb1, 0x13, 0x6d, 0x19, 0xb2, 0xa0, 0xc8, 0xfc, 0x59, 0xa3,
0x4c, 0xb0, 0x08, 0x71, 0x64, 0xbb, 0x65, 0x65, 0x44, 0xbc, 0x03, 0x13, 0x23, 0x2f, 0xc2, 0xc8, 0xb4, 0x31, 0xc1, 0x6a, 0x88, 0x23, 0xdb, 0x2d, 0x2b, 0x23, 0xe2, 0x1d, 0x98, 0x78, 0x19, 0x26,
0xc8, 0x84, 0x68, 0x57, 0x16, 0x1e, 0x01, 0xdb, 0x49, 0x5a, 0x21, 0x75, 0xb0, 0xe4, 0xfc, 0xce, 0xc4, 0xc8, 0x84, 0x68, 0x57, 0x16, 0x1e, 0x01, 0xdb, 0x49, 0x5a, 0x21, 0x75, 0x38, 0x92, 0xf3,
0xef, 0x4b, 0x4e, 0x3e, 0x70, 0xd3, 0x9c, 0x94, 0x32, 0xaa, 0x38, 0x93, 0x0c, 0x41, 0x41, 0xb7, 0xfd, 0xbe, 0xe3, 0x1c, 0x1f, 0x70, 0xb3, 0x82, 0x54, 0x32, 0xaa, 0x39, 0x93, 0x0c, 0x41, 0x49,
0x25, 0x91, 0x1f, 0x18, 0x7f, 0x37, 0x7c, 0x90, 0xb3, 0x9c, 0x19, 0x3c, 0xd3, 0xb7, 0xda, 0x98, 0x57, 0x15, 0x91, 0x1f, 0x18, 0xdf, 0x0c, 0x1f, 0x14, 0xac, 0x60, 0x06, 0xdf, 0xe9, 0x53, 0x63,
0x7c, 0xbb, 0x01, 0xff, 0x59, 0x99, 0x55, 0x8c, 0x96, 0x12, 0x93, 0x1d, 0xe3, 0x19, 0x42, 0x60, 0x4c, 0xbe, 0x5f, 0x80, 0xff, 0xbc, 0xca, 0x6b, 0x46, 0x2b, 0x89, 0xc9, 0x9a, 0xf1, 0x1c, 0x21,
0x97, 0xe9, 0x7b, 0x12, 0x58, 0x63, 0x6b, 0xea, 0x60, 0x73, 0x47, 0x8f, 0xa0, 0x2f, 0x08, 0x3f, 0xb0, 0xab, 0xec, 0x3d, 0x09, 0xac, 0xb1, 0x75, 0xeb, 0x60, 0x73, 0x46, 0x8f, 0xe0, 0x5a, 0x10,
0xd0, 0x1d, 0xd9, 0x98, 0xd9, 0x8d, 0x99, 0xb9, 0x0d, 0x7b, 0xae, 0x95, 0x27, 0x00, 0xad, 0x42, 0xbe, 0xa3, 0x6b, 0x92, 0x9a, 0xec, 0xc2, 0x64, 0x6e, 0xcb, 0x5e, 0x68, 0xe5, 0x09, 0x40, 0xa7,
0xb3, 0xa0, 0xab, 0x85, 0xa5, 0x77, 0xfa, 0x35, 0x72, 0x5e, 0xd4, 0x34, 0x5e, 0x63, 0xa7, 0x11, 0xd0, 0x3c, 0xe8, 0x6b, 0x61, 0xee, 0x1d, 0x7e, 0x8d, 0x9c, 0x97, 0x0d, 0x8d, 0x97, 0xd8, 0x69,
0xe2, 0x4c, 0xdb, 0x07, 0xca, 0xe5, 0x3e, 0x2d, 0x36, 0xb4, 0x0a, 0xec, 0x8b, 0xfd, 0xba, 0xa6, 0x85, 0x38, 0xd7, 0xf6, 0x8e, 0x72, 0xb9, 0xcd, 0xca, 0x94, 0xd6, 0x81, 0x7d, 0xb2, 0xdf, 0x34,
0x71, 0x82, 0x9d, 0x46, 0x88, 0x2b, 0x34, 0x03, 0x97, 0x34, 0x4b, 0x6a, 0xfd, 0x9e, 0xd1, 0x7d, 0x34, 0x4e, 0xb0, 0xd3, 0x0a, 0x71, 0x8d, 0xee, 0xc0, 0x25, 0xed, 0x90, 0x5a, 0xbf, 0x67, 0x74,
0xa5, 0x43, 0xbb, 0xbb, 0xf2, 0xa1, 0x55, 0x54, 0x60, 0x01, 0x1e, 0x2d, 0x73, 0x4e, 0x84, 0xd8, 0x5f, 0xe9, 0xd0, 0xcd, 0xae, 0x7c, 0xe8, 0x14, 0xd5, 0x30, 0x03, 0x8f, 0x56, 0x05, 0x27, 0x42,
0x54, 0x8c, 0x4b, 0x11, 0xdc, 0x8e, 0xbb, 0x53, 0x77, 0xfe, 0x30, 0xba, 0x14, 0x12, 0x25, 0x6a, 0xa4, 0x35, 0xe3, 0x52, 0x04, 0x97, 0xe3, 0xfe, 0xad, 0x3b, 0x7d, 0x18, 0x9d, 0x16, 0x12, 0x25,
0xb0, 0x62, 0xe5, 0x1b, 0x9a, 0xe3, 0x7e, 0x23, 0x6b, 0x24, 0x50, 0x00, 0x77, 0x69, 0x41, 0x53, 0x2a, 0x58, 0xb0, 0xea, 0x2d, 0x2d, 0xf0, 0x75, 0x2b, 0x6b, 0x24, 0x50, 0x00, 0x57, 0x59, 0x49,
0x41, 0x44, 0x70, 0xa7, 0x62, 0x0e, 0x6e, 0x1f, 0x27, 0x7f, 0x2c, 0x80, 0x4b, 0xec, 0x6a, 0x53, 0x33, 0x41, 0x44, 0x70, 0xa5, 0xda, 0x1c, 0xdc, 0x7d, 0xea, 0x35, 0xc8, 0x4c, 0x6c, 0xd2, 0x2e,
0x0b, 0xe8, 0x99, 0x66, 0x77, 0xac, 0x30, 0x2d, 0xf9, 0xf3, 0xd1, 0xf5, 0x8f, 0x46, 0x49, 0xa3, 0x1e, 0x98, 0xd8, 0xd5, 0xec, 0x59, 0x83, 0x26, 0x7f, 0x2c, 0x80, 0xd3, 0xcd, 0x67, 0x97, 0x39,
0xe1, 0x73, 0x00, 0x8d, 0xc0, 0x95, 0x29, 0xcf, 0x89, 0x34, 0x5b, 0x9b, 0x12, 0x3d, 0x0c, 0x35, 0x83, 0x81, 0x59, 0xfe, 0x9a, 0x95, 0x66, 0x91, 0xfe, 0x74, 0x74, 0x7e, 0xae, 0x28, 0x69, 0x35,
0xd2, 0x49, 0xf4, 0x18, 0xfc, 0x6a, 0xbf, 0x2d, 0xa8, 0x78, 0x4b, 0xb2, 0xda, 0xb1, 0x8d, 0xe3, 0x7c, 0x6c, 0x40, 0x23, 0x50, 0xbf, 0xe3, 0x05, 0x91, 0xe6, 0x61, 0x66, 0xcf, 0x1e, 0x86, 0x06,
0x9d, 0xa9, 0xd6, 0x26, 0x6b, 0xe8, 0xb5, 0x6f, 0x57, 0x7f, 0xd3, 0x7d, 0xb9, 0x4a, 0x06, 0x9d, 0xe9, 0x4e, 0xf4, 0x18, 0xfc, 0x7a, 0xbb, 0x2a, 0xa9, 0x78, 0x47, 0xf2, 0xc6, 0xb1, 0x8d, 0xe3,
0xe1, 0xfd, 0xcf, 0x5f, 0xc6, 0x6e, 0x8b, 0x15, 0xd2, 0x93, 0x57, 0xeb, 0x64, 0x60, 0xfd, 0x3f, 0x1d, 0xa9, 0xd6, 0x26, 0x4b, 0x18, 0x74, 0xb7, 0xab, 0x07, 0xf7, 0x5f, 0x2d, 0x92, 0x9b, 0xde,
0x51, 0x68, 0x68, 0x7f, 0xfa, 0x1a, 0x76, 0x96, 0xc1, 0xcf, 0x63, 0xd8, 0xf9, 0x7b, 0x0c, 0xad, 0xf0, 0xfe, 0xe7, 0x2f, 0x63, 0xb7, 0xc3, 0x0a, 0xe9, 0xe4, 0xf5, 0x32, 0xb9, 0xb1, 0xfe, 0x4f,
0x8f, 0xa7, 0xd0, 0xfa, 0xae, 0xce, 0x0f, 0x75, 0x7e, 0xab, 0xb3, 0xbd, 0x35, 0x1b, 0x3f, 0xfd, 0x14, 0x1a, 0xda, 0x9f, 0xbe, 0x86, 0xbd, 0x79, 0xf0, 0x73, 0x1f, 0xf6, 0xfe, 0xee, 0x43, 0xeb,
0x17, 0x00, 0x00, 0xff, 0xff, 0xc5, 0x58, 0xc7, 0xbd, 0x6d, 0x02, 0x00, 0x00, 0xe3, 0x21, 0xb4, 0xbe, 0xa9, 0xfa, 0xa1, 0xea, 0xb7, 0xaa, 0xd5, 0xa5, 0x99, 0xf8, 0xe9, 0xbf,
0x00, 0x00, 0x00, 0xff, 0xff, 0xc9, 0x63, 0x1a, 0x0f, 0x90, 0x02, 0x00, 0x00,
} }

View file

@ -34,6 +34,9 @@ message EndpointRecord {
// A list of aliases which are alternate names for the service // A list of aliases which are alternate names for the service
repeated string aliases = 7; repeated string aliases = 7;
// List of aliases task specific aliases
repeated string task_aliases = 8;
} }
// PortConfig specifies an exposed port which can be // PortConfig specifies an exposed port which can be

View file

@ -97,7 +97,7 @@ type NetworkController interface {
// Sandboxes returns the list of Sandbox(s) managed by this controller. // Sandboxes returns the list of Sandbox(s) managed by this controller.
Sandboxes() []Sandbox Sandboxes() []Sandbox
// WlakSandboxes uses the provided function to walk the Sandbox(s) managed by this controller. // WalkSandboxes uses the provided function to walk the Sandbox(s) managed by this controller.
WalkSandboxes(walker SandboxWalker) WalkSandboxes(walker SandboxWalker)
// SandboxByID returns the Sandbox which has the passed id. If not found, a types.NotFoundError is returned. // SandboxByID returns the Sandbox which has the passed id. If not found, a types.NotFoundError is returned.
@ -250,6 +250,21 @@ func (c *controller) SetKeys(keys []*types.EncryptionKey) error {
clusterConfigAvailable := c.clusterConfigAvailable clusterConfigAvailable := c.clusterConfigAvailable
agent := c.agent agent := c.agent
c.Unlock() c.Unlock()
subsysKeys := make(map[string]int)
for _, key := range keys {
if key.Subsystem != subsysGossip &&
key.Subsystem != subsysIPSec {
return fmt.Errorf("key received for unrecognized subsystem")
}
subsysKeys[key.Subsystem]++
}
for s, count := range subsysKeys {
if count != keyringSize {
return fmt.Errorf("incorrect number of keys for susbsystem %v", s)
}
}
if len(existingKeys) == 0 { if len(existingKeys) == 0 {
c.Lock() c.Lock()
c.keys = keys c.keys = keys
@ -269,9 +284,6 @@ func (c *controller) SetKeys(keys []*types.EncryptionKey) error {
c.Unlock() c.Unlock()
return nil return nil
} }
if len(keys) < keyringSize {
return c.handleKeyChangeV1(keys)
}
return c.handleKeyChange(keys) return c.handleKeyChange(keys)
} }

View file

@ -63,13 +63,13 @@ type datastore struct {
sync.Mutex sync.Mutex
} }
// KVObject is Key/Value interface used by objects to be part of the DataStore // KVObject is Key/Value interface used by objects to be part of the DataStore
type KVObject interface { type KVObject interface {
// Key method lets an object to provide the Key to be used in KV Store // Key method lets an object provide the Key to be used in KV Store
Key() []string Key() []string
// KeyPrefix method lets an object to return immediate parent key that can be used for tree walk // KeyPrefix method lets an object return immediate parent key that can be used for tree walk
KeyPrefix() []string KeyPrefix() []string
// Value method lets an object to marshal its content to be stored in the KV store // Value method lets an object marshal its content to be stored in the KV store
Value() []byte Value() []byte
// SetValue is used by the datastore to set the object's value when loaded from the data store. // SetValue is used by the datastore to set the object's value when loaded from the data store.
SetValue([]byte) error SetValue([]byte) error

View file

@ -14,7 +14,7 @@ const (
var procGwNetwork = make(chan (bool), 1) var procGwNetwork = make(chan (bool), 1)
/* /*
libnetwork creates a bridge network "docker_gw_bridge" for provding libnetwork creates a bridge network "docker_gw_bridge" for providing
default gateway for the containers if none of the container's endpoints default gateway for the containers if none of the container's endpoints
have GW set by the driver. ICC is set to false for the GW_bridge network. have GW set by the driver. ICC is set to false for the GW_bridge network.
@ -29,7 +29,7 @@ var procGwNetwork = make(chan (bool), 1)
func (sb *sandbox) setupDefaultGW() error { func (sb *sandbox) setupDefaultGW() error {
// check if the conitainer already has a GW endpoint // check if the container already has a GW endpoint
if ep := sb.getEndpointInGWNetwork(); ep != nil { if ep := sb.getEndpointInGWNetwork(); ep != nil {
return nil return nil
} }

View file

@ -115,7 +115,7 @@ type InterfaceNameInfo interface {
// JoinInfo represents a set of resources that the driver has the ability to provide during // JoinInfo represents a set of resources that the driver has the ability to provide during
// join time. // join time.
type JoinInfo interface { type JoinInfo interface {
// InterfaceName returns a InterfaceNameInfo go interface to facilitate // InterfaceName returns an InterfaceNameInfo go interface to facilitate
// setting the names for the interface. // setting the names for the interface.
InterfaceName() InterfaceNameInfo InterfaceName() InterfaceNameInfo

View file

@ -564,7 +564,7 @@ func (d *driver) CreateNetwork(id string, option map[string]interface{}, nInfo d
} }
d.Unlock() d.Unlock()
// Parse and validate the config. It should not conflict with existing networks' config // Parse and validate the config. It should not be conflict with existing networks' config
config, err := parseNetworkOptions(id, option) config, err := parseNetworkOptions(id, option)
if err != nil { if err != nil {
return err return err

View file

@ -32,7 +32,7 @@ func createIPVlan(containerIfName, parent, ipvlanMode string) (string, error) {
if err != nil { if err != nil {
return "", fmt.Errorf("error occoured looking up the %s parent iface %s error: %s", ipvlanType, parent, err) return "", fmt.Errorf("error occoured looking up the %s parent iface %s error: %s", ipvlanType, parent, err)
} }
// Create a ipvlan link // Create an ipvlan link
ipvlan := &netlink.IPVlan{ ipvlan := &netlink.IPVlan{
LinkAttrs: netlink.LinkAttrs{ LinkAttrs: netlink.LinkAttrs{
Name: containerIfName, Name: containerIfName,

View file

@ -31,7 +31,7 @@ func (d *driver) deleteNetwork(nid string) {
d.Unlock() d.Unlock()
} }
// getNetworks Safely returns a slice of existng networks // getNetworks Safely returns a slice of existing networks
func (d *driver) getNetworks() []*network { func (d *driver) getNetworks() []*network {
d.Lock() d.Lock()
defer d.Unlock() defer d.Unlock()

View file

@ -637,6 +637,10 @@ func (n *network) watchMiss(nlSock *nl.NetlinkSocket) {
continue continue
} }
if !n.driver.isSerfAlive() {
continue
}
mac, IPmask, vtep, err := n.driver.resolvePeer(n.id, neigh.IP) mac, IPmask, vtep, err := n.driver.resolvePeer(n.id, neigh.IP)
if err != nil { if err != nil {
logrus.Errorf("could not resolve peer %q: %v", neigh.IP, err) logrus.Errorf("could not resolve peer %q: %v", neigh.IP, err)
@ -664,17 +668,17 @@ func (d *driver) deleteNetwork(nid string) {
func (d *driver) network(nid string) *network { func (d *driver) network(nid string) *network {
d.Lock() d.Lock()
networks := d.networks n, ok := d.networks[nid]
d.Unlock() d.Unlock()
n, ok := networks[nid]
if !ok { if !ok {
n = d.getNetworkFromStore(nid) n = d.getNetworkFromStore(nid)
if n != nil { if n != nil {
n.driver = d n.driver = d
n.endpoints = endpointTable{} n.endpoints = endpointTable{}
n.once = &sync.Once{} n.once = &sync.Once{}
networks[nid] = n d.Lock()
d.networks[nid] = n
d.Unlock()
} }
} }

View file

@ -168,14 +168,14 @@ func (d *driver) peerDbAdd(nid, eid string, peerIP net.IP, peerIPMask net.IPMask
} }
func (d *driver) peerDbDelete(nid, eid string, peerIP net.IP, peerIPMask net.IPMask, func (d *driver) peerDbDelete(nid, eid string, peerIP net.IP, peerIPMask net.IPMask,
peerMac net.HardwareAddr, vtep net.IP) { peerMac net.HardwareAddr, vtep net.IP) bool {
peerDbWg.Wait() peerDbWg.Wait()
d.peerDb.Lock() d.peerDb.Lock()
pMap, ok := d.peerDb.mp[nid] pMap, ok := d.peerDb.mp[nid]
if !ok { if !ok {
d.peerDb.Unlock() d.peerDb.Unlock()
return return false
} }
d.peerDb.Unlock() d.peerDb.Unlock()
@ -185,8 +185,20 @@ func (d *driver) peerDbDelete(nid, eid string, peerIP net.IP, peerIPMask net.IPM
} }
pMap.Lock() pMap.Lock()
if pEntry, ok := pMap.mp[pKey.String()]; ok {
// Mismatched endpoint ID(possibly outdated). Do not
// delete peerdb
if pEntry.eid != eid {
pMap.Unlock()
return false
}
}
delete(pMap.mp, pKey.String()) delete(pMap.mp, pKey.String())
pMap.Unlock() pMap.Unlock()
return true
} }
func (d *driver) peerDbUpdateSandbox(nid string) { func (d *driver) peerDbUpdateSandbox(nid string) {
@ -281,7 +293,7 @@ func (d *driver) peerAdd(nid, eid string, peerIP net.IP, peerIPMask net.IPMask,
// Add neighbor entry for the peer IP // Add neighbor entry for the peer IP
if err := sbox.AddNeighbor(peerIP, peerMac, sbox.NeighborOptions().LinkName(s.vxlanName)); err != nil { if err := sbox.AddNeighbor(peerIP, peerMac, sbox.NeighborOptions().LinkName(s.vxlanName)); err != nil {
return fmt.Errorf("could not add neigbor entry into the sandbox: %v", err) return fmt.Errorf("could not add neighbor entry into the sandbox: %v", err)
} }
// Add fdb entry to the bridge for the peer mac // Add fdb entry to the bridge for the peer mac
@ -301,7 +313,9 @@ func (d *driver) peerDelete(nid, eid string, peerIP net.IP, peerIPMask net.IPMas
} }
if updateDb { if updateDb {
d.peerDbDelete(nid, eid, peerIP, peerIPMask, peerMac, vtep) if !d.peerDbDelete(nid, eid, peerIP, peerIPMask, peerMac, vtep) {
return nil
}
} }
n := d.network(nid) n := d.network(nid)
@ -321,7 +335,7 @@ func (d *driver) peerDelete(nid, eid string, peerIP net.IP, peerIPMask net.IPMas
// Delete neighbor entry for the peer IP // Delete neighbor entry for the peer IP
if err := sbox.DeleteNeighbor(peerIP, peerMac); err != nil { if err := sbox.DeleteNeighbor(peerIP, peerMac); err != nil {
return fmt.Errorf("could not delete neigbor entry into the sandbox: %v", err) return fmt.Errorf("could not delete neighbor entry into the sandbox: %v", err)
} }
if err := d.checkEncryption(nid, vtep, 0, false, false); err != nil { if err := d.checkEncryption(nid, vtep, 0, false, false); err != nil {

View file

@ -463,6 +463,8 @@ func (epj *endpointJoinInfo) CopyTo(dstEpj *endpointJoinInfo) error {
dstEpj.disableGatewayService = epj.disableGatewayService dstEpj.disableGatewayService = epj.disableGatewayService
dstEpj.StaticRoutes = make([]*types.StaticRoute, len(epj.StaticRoutes)) dstEpj.StaticRoutes = make([]*types.StaticRoute, len(epj.StaticRoutes))
copy(dstEpj.StaticRoutes, epj.StaticRoutes) copy(dstEpj.StaticRoutes, epj.StaticRoutes)
dstEpj.driverTableEntries = make([]*tableEntry, len(epj.driverTableEntries))
copy(dstEpj.driverTableEntries, epj.driverTableEntries)
dstEpj.gw = types.GetIPCopy(epj.gw) dstEpj.gw = types.GetIPCopy(epj.gw)
dstEpj.gw = types.GetIPCopy(epj.gw6) dstEpj.gw = types.GetIPCopy(epj.gw6)
return nil return nil

View file

@ -15,7 +15,7 @@ type LeaveCallback func(entries []net.IP)
type HostDiscovery interface { type HostDiscovery interface {
//Watch Node join and leave cluster events //Watch Node join and leave cluster events
Watch(activeCallback ActiveCallback, joinCallback JoinCallback, leaveCallback LeaveCallback) error Watch(activeCallback ActiveCallback, joinCallback JoinCallback, leaveCallback LeaveCallback) error
// StopDiscovery stops the discovery perocess // StopDiscovery stops the discovery process
StopDiscovery() error StopDiscovery() error
// Fetch returns a list of host IPs that are currently discovered // Fetch returns a list of host IPs that are currently discovered
Fetch() []net.IP Fetch() []net.IP

View file

@ -27,7 +27,7 @@ const (
type Callback interface { type Callback interface {
// RegisterIpamDriver provides a way for Remote drivers to dynamically register with libnetwork // RegisterIpamDriver provides a way for Remote drivers to dynamically register with libnetwork
RegisterIpamDriver(name string, driver Ipam) error RegisterIpamDriver(name string, driver Ipam) error
// RegisterIpamDriverWithCapabilities provides a way for Remote drivers to dynamically register with libnetwork and specify cpaabilities // RegisterIpamDriverWithCapabilities provides a way for Remote drivers to dynamically register with libnetwork and specify capabilities
RegisterIpamDriverWithCapabilities(name string, driver Ipam, capability *Capability) error RegisterIpamDriverWithCapabilities(name string, driver Ipam, capability *Capability) error
} }
@ -46,6 +46,7 @@ var (
ErrOverlapPool = types.ForbiddenErrorf("Address pool overlaps with existing pool on this address space") ErrOverlapPool = types.ForbiddenErrorf("Address pool overlaps with existing pool on this address space")
ErrNoAvailablePool = types.NoServiceErrorf("No available pool") ErrNoAvailablePool = types.NoServiceErrorf("No available pool")
ErrNoAvailableIPs = types.NoServiceErrorf("No available addresses on this pool") ErrNoAvailableIPs = types.NoServiceErrorf("No available addresses on this pool")
ErrNoIPReturned = types.NoServiceErrorf("No address returned")
ErrIPAlreadyAllocated = types.ForbiddenErrorf("Address already in use") ErrIPAlreadyAllocated = types.ForbiddenErrorf("Address already in use")
ErrIPOutOfRange = types.BadRequestErrorf("Requested address is out of range") ErrIPOutOfRange = types.BadRequestErrorf("Requested address is out of range")
ErrPoolOverlap = types.ForbiddenErrorf("Pool overlaps with other one on this address space") ErrPoolOverlap = types.ForbiddenErrorf("Pool overlaps with other one on this address space")

View file

@ -26,7 +26,7 @@ type GetCapabilityResponse struct {
RequiresRequestReplay bool RequiresRequestReplay bool
} }
// ToCapability converts the capability response into the internal ipam driver capaility structure // ToCapability converts the capability response into the internal ipam driver capability structure
func (capRes GetCapabilityResponse) ToCapability() *ipamapi.Capability { func (capRes GetCapabilityResponse) ToCapability() *ipamapi.Capability {
return &ipamapi.Capability{ return &ipamapi.Capability{
RequiresMACAddress: capRes.RequiresMACAddress, RequiresMACAddress: capRes.RequiresMACAddress,

View file

@ -111,6 +111,8 @@ func (a *allocator) RequestAddress(poolID string, address net.IP, options map[st
} }
if res.Address != "" { if res.Address != "" {
retAddress, err = types.ParseCIDR(res.Address) retAddress, err = types.ParseCIDR(res.Address)
} else {
return nil, nil, ipamapi.ErrNoIPReturned
} }
return retAddress, res.Data, err return retAddress, res.Data, err
} }

View file

@ -1,4 +1,4 @@
// Package ipamutils provides utililty functions for ipam management // Package ipamutils provides utility functions for ipam management
package ipamutils package ipamutils
import ( import (
@ -17,7 +17,7 @@ var (
initNetworksOnce sync.Once initNetworksOnce sync.Once
) )
// InitNetworks initializes the pre-defined networks used by the built-in IP allocator // InitNetworks initializes the pre-defined networks used by the built-in IP allocator
func InitNetworks() { func InitNetworks() {
initNetworksOnce.Do(func() { initNetworksOnce.Do(func() {
PredefinedBroadNetworks = initBroadPredefinedNetworks() PredefinedBroadNetworks = initBroadPredefinedNetworks()

View file

@ -94,7 +94,7 @@ func (i *Handle) DelService(s *Service) error {
return i.doCmd(s, nil, ipvsCmdDelService) return i.doCmd(s, nil, ipvsCmdDelService)
} }
// NewDestination creates an new real server in the passed ipvs // NewDestination creates a new real server in the passed ipvs
// service which should already be existing in the passed handle. // service which should already be existing in the passed handle.
func (i *Handle) NewDestination(s *Service, d *Destination) error { func (i *Handle) NewDestination(s *Service, d *Destination) error {
return i.doCmd(s, d, ipvsCmdNewDest) return i.doCmd(s, d, ipvsCmdNewDest)

View file

@ -170,7 +170,7 @@ func ReverseIP(IP string) string {
return strings.Join(reverseIP, ".") return strings.Join(reverseIP, ".")
} }
// ParseAlias parses and validates the specified string as a alias format (name:alias) // ParseAlias parses and validates the specified string as an alias format (name:alias)
func ParseAlias(val string) (string, string, error) { func ParseAlias(val string) (string, string, error) {
if val == "" { if val == "" {
return "", "", fmt.Errorf("empty string specified for alias") return "", "", fmt.Errorf("empty string specified for alias")

View file

@ -63,7 +63,7 @@ func GenerateIfaceName(nlh *netlink.Handle, prefix string, len int) (string, err
// ElectInterfaceAddresses looks for an interface on the OS with the // ElectInterfaceAddresses looks for an interface on the OS with the
// specified name and returns its IPv4 and IPv6 addresses in CIDR // specified name and returns its IPv4 and IPv6 addresses in CIDR
// form. If the interface does not exist, it chooses from a predifined // form. If the interface does not exist, it chooses from a predefined
// list the first IPv4 address which does not conflict with other // list the first IPv4 address which does not conflict with other
// interfaces on the system. // interfaces on the system.
func ElectInterfaceAddresses(name string) (*net.IPNet, []*net.IPNet, error) { func ElectInterfaceAddresses(name string) (*net.IPNet, []*net.IPNet, error) {
@ -94,7 +94,7 @@ func ElectInterfaceAddresses(name string) (*net.IPNet, []*net.IPNet, error) {
} }
if link == nil || v4Net == nil { if link == nil || v4Net == nil {
// Choose from predifined broad networks // Choose from predefined broad networks
v4Net, err = FindAvailableNetwork(ipamutils.PredefinedBroadNetworks) v4Net, err = FindAvailableNetwork(ipamutils.PredefinedBroadNetworks)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err

View file

@ -1183,7 +1183,7 @@ func (n *network) requestPoolHelper(ipam ipamapi.Ipam, addressSpace, preferredPo
} }
// If the network belongs to global scope or the pool was // If the network belongs to global scope or the pool was
// explicitely chosen or it is invalid, do not perform the overlap check. // explicitly chosen or it is invalid, do not perform the overlap check.
if n.Scope() == datastore.GlobalScope || preferredPool != "" || !types.IsIPNetValid(pool) { if n.Scope() == datastore.GlobalScope || preferredPool != "" || !types.IsIPNetValid(pool) {
return poolID, pool, meta, nil return poolID, pool, meta, nil
} }
@ -1207,7 +1207,7 @@ func (n *network) requestPoolHelper(ipam ipamapi.Ipam, addressSpace, preferredPo
}() }()
// If this is a preferred pool request and the network // If this is a preferred pool request and the network
// is local scope and there is a overlap, we fail the // is local scope and there is an overlap, we fail the
// network creation right here. The pool will be // network creation right here. The pool will be
// released in the defer. // released in the defer.
if preferredPool != "" { if preferredPool != "" {

View file

@ -305,7 +305,10 @@ func (nDB *NetworkDB) gossip() {
func (nDB *NetworkDB) bulkSyncTables() { func (nDB *NetworkDB) bulkSyncTables() {
var networks []string var networks []string
nDB.RLock() nDB.RLock()
for nid := range nDB.networks[nDB.config.NodeName] { for nid, network := range nDB.networks[nDB.config.NodeName] {
if network.leaving {
continue
}
networks = append(networks, nid) networks = append(networks, nid)
} }
nDB.RUnlock() nDB.RUnlock()

View file

@ -25,6 +25,10 @@ func (nDB *NetworkDB) handleNetworkEvent(nEvent *NetworkEvent) bool {
nDB.Lock() nDB.Lock()
defer nDB.Unlock() defer nDB.Unlock()
if nEvent.NodeName == nDB.config.NodeName {
return false
}
nodeNetworks, ok := nDB.networks[nEvent.NodeName] nodeNetworks, ok := nDB.networks[nEvent.NodeName]
if !ok { if !ok {
// We haven't heard about this node at all. Ignore the leave // We haven't heard about this node at all. Ignore the leave
@ -71,6 +75,15 @@ func (nDB *NetworkDB) handleTableEvent(tEvent *TableEvent) bool {
// time. // time.
nDB.tableClock.Witness(tEvent.LTime) nDB.tableClock.Witness(tEvent.LTime)
// Ignore the table events for networks that are in the process of going away
nDB.RLock()
networks := nDB.networks[nDB.config.NodeName]
network, ok := networks[tEvent.NetworkID]
nDB.RUnlock()
if !ok || network.leaving {
return true
}
if entry, err := nDB.getEntry(tEvent.TableName, tEvent.NetworkID, tEvent.Key); err == nil { if entry, err := nDB.getEntry(tEvent.TableName, tEvent.NetworkID, tEvent.Key); err == nil {
// We have the latest state. Ignore the event // We have the latest state. Ignore the event
// since it is stale. // since it is stale.
@ -217,9 +230,11 @@ func (nDB *NetworkDB) handleBulkSync(buf []byte) {
} }
var nodeAddr net.IP var nodeAddr net.IP
nDB.RLock()
if node, ok := nDB.nodes[bsm.NodeName]; ok { if node, ok := nDB.nodes[bsm.NodeName]; ok {
nodeAddr = node.Addr nodeAddr = node.Addr
} }
nDB.RUnlock()
if err := nDB.bulkSyncNode(bsm.Networks, bsm.NodeName, false); err != nil { if err := nDB.bulkSyncNode(bsm.Networks, bsm.NodeName, false); err != nil {
logrus.Errorf("Error in responding to bulk sync from node %s: %v", nodeAddr, err) logrus.Errorf("Error in responding to bulk sync from node %s: %v", nodeAddr, err)

View file

@ -371,7 +371,10 @@ func (nDB *NetworkDB) JoinNetwork(nid string) error {
nodeNetworks[nid] = &network{id: nid, ltime: ltime} nodeNetworks[nid] = &network{id: nid, ltime: ltime}
nodeNetworks[nid].tableBroadcasts = &memberlist.TransmitLimitedQueue{ nodeNetworks[nid].tableBroadcasts = &memberlist.TransmitLimitedQueue{
NumNodes: func() int { NumNodes: func() int {
return len(nDB.networkNodes[nid]) nDB.RLock()
num := len(nDB.networkNodes[nid])
nDB.RUnlock()
return num
}, },
RetransmitMult: 4, RetransmitMult: 4,
} }
@ -395,7 +398,8 @@ func (nDB *NetworkDB) JoinNetwork(nid string) error {
// this event across the cluster. This triggers this node leaving the // this event across the cluster. This triggers this node leaving the
// sub-cluster of this network and as a result will no longer // sub-cluster of this network and as a result will no longer
// participate in the network-scoped gossip and bulk sync for this // participate in the network-scoped gossip and bulk sync for this
// network. // network. Also remove all the table entries for this network from
// networkdb
func (nDB *NetworkDB) LeaveNetwork(nid string) error { func (nDB *NetworkDB) LeaveNetwork(nid string) error {
ltime := nDB.networkClock.Increment() ltime := nDB.networkClock.Increment()
if err := nDB.sendNetworkEvent(nid, NetworkEventTypeLeave, ltime); err != nil { if err := nDB.sendNetworkEvent(nid, NetworkEventTypeLeave, ltime); err != nil {
@ -404,6 +408,36 @@ func (nDB *NetworkDB) LeaveNetwork(nid string) error {
nDB.Lock() nDB.Lock()
defer nDB.Unlock() defer nDB.Unlock()
var (
paths []string
entries []*entry
)
nwWalker := func(path string, v interface{}) bool {
entry, ok := v.(*entry)
if !ok {
return false
}
paths = append(paths, path)
entries = append(entries, entry)
return false
}
nDB.indexes[byNetwork].WalkPrefix(fmt.Sprintf("/%s", nid), nwWalker)
for _, path := range paths {
params := strings.Split(path[1:], "/")
tname := params[1]
key := params[2]
if _, ok := nDB.indexes[byTable].Delete(fmt.Sprintf("/%s/%s/%s", tname, nid, key)); !ok {
logrus.Errorf("Could not delete entry in table %s with network id %s and key %s as it does not exist", tname, nid, key)
}
if _, ok := nDB.indexes[byNetwork].Delete(fmt.Sprintf("/%s/%s/%s", nid, tname, key)); !ok {
logrus.Errorf("Could not delete entry in network %s with table name %s and key %s as it does not exist", nid, tname, key)
}
}
nodeNetworks, ok := nDB.networks[nDB.config.NodeName] nodeNetworks, ok := nDB.networks[nDB.config.NodeName]
if !ok { if !ok {
return fmt.Errorf("could not find self node for network %s while trying to leave", nid) return fmt.Errorf("could not find self node for network %s while trying to leave", nid)

View file

@ -41,7 +41,7 @@ func (e TypeMismatchError) Error() string {
return fmt.Sprintf("type mismatch, field %s require type %v, actual type %v", e.Field, e.ExpectType, e.ActualType) return fmt.Sprintf("type mismatch, field %s require type %v, actual type %v", e.Field, e.ExpectType, e.ActualType)
} }
// Generic is an basic type to store arbitrary settings. // Generic is a basic type to store arbitrary settings.
type Generic map[string]interface{} type Generic map[string]interface{}
// NewGeneric returns a new Generic instance. // NewGeneric returns a new Generic instance.

View file

@ -140,7 +140,7 @@ func (i *nwIface) Remove() error {
nlh := n.nlHandle nlh := n.nlHandle
n.Unlock() n.Unlock()
// Find the network inteerface identified by the DstName attribute. // Find the network interface identified by the DstName attribute.
iface, err := nlh.LinkByName(i.DstName()) iface, err := nlh.LinkByName(i.DstName())
if err != nil { if err != nil {
return err return err

View file

@ -361,7 +361,10 @@ func (r *resolver) ServeDNS(w dns.ResponseWriter, query *dns.Msg) {
// Timeout has to be set for every IO operation. // Timeout has to be set for every IO operation.
extConn.SetDeadline(time.Now().Add(extIOTimeout)) extConn.SetDeadline(time.Now().Add(extIOTimeout))
co := &dns.Conn{Conn: extConn} co := &dns.Conn{
Conn: extConn,
UDPSize: uint16(maxSize),
}
defer co.Close() defer co.Close()
// limits the number of outstanding concurrent queries. // limits the number of outstanding concurrent queries.

View file

@ -498,6 +498,38 @@ func (sb *sandbox) ResolveService(name string) ([]*net.SRV, []net.IP, error) {
return srv, ip, nil return srv, ip, nil
} }
func getDynamicNwEndpoints(epList []*endpoint) []*endpoint {
eps := []*endpoint{}
for _, ep := range epList {
n := ep.getNetwork()
if n.dynamic && !n.ingress {
eps = append(eps, ep)
}
}
return eps
}
func getIngressNwEndpoint(epList []*endpoint) *endpoint {
for _, ep := range epList {
n := ep.getNetwork()
if n.ingress {
return ep
}
}
return nil
}
func getLocalNwEndpoints(epList []*endpoint) []*endpoint {
eps := []*endpoint{}
for _, ep := range epList {
n := ep.getNetwork()
if !n.dynamic && !n.ingress {
eps = append(eps, ep)
}
}
return eps
}
func (sb *sandbox) ResolveName(name string, ipType int) ([]net.IP, bool) { func (sb *sandbox) ResolveName(name string, ipType int) ([]net.IP, bool) {
// Embedded server owns the docker network domain. Resolution should work // Embedded server owns the docker network domain. Resolution should work
// for both container_name and container_name.network_name // for both container_name and container_name.network_name
@ -528,6 +560,18 @@ func (sb *sandbox) ResolveName(name string, ipType int) ([]net.IP, bool) {
} }
epList := sb.getConnectedEndpoints() epList := sb.getConnectedEndpoints()
// In swarm mode services with exposed ports are connected to user overlay
// network, ingress network and docker_gwbridge network. Name resolution
// should prioritize returning the VIP/IPs on user overlay network.
newList := []*endpoint{}
if !sb.controller.isDistributedControl() {
newList = append(newList, getDynamicNwEndpoints(epList)...)
newList = append(newList, getIngressNwEndpoint(epList))
newList = append(newList, getLocalNwEndpoints(epList)...)
epList = newList
}
for i := 0; i < len(reqName); i++ { for i := 0; i < len(reqName); i++ {
// First check for local container alias // First check for local container alias

View file

@ -290,7 +290,7 @@ func (sb *sandbox) updateDNS(ipv6Enabled bool) error {
} }
// Embedded DNS server has to be enabled for this sandbox. Rebuild the container's // Embedded DNS server has to be enabled for this sandbox. Rebuild the container's
// resolv.conf by doing the follwing // resolv.conf by doing the following
// - Save the external name servers in resolv.conf in the sandbox // - Save the external name servers in resolv.conf in the sandbox
// - Add only the embedded server's IP to container's resolv.conf // - Add only the embedded server's IP to container's resolv.conf
// - If the embedded server needs any resolv.conf options add it to the current list // - If the embedded server needs any resolv.conf options add it to the current list

View file

@ -139,21 +139,6 @@ func (c *controller) rmServiceBinding(name, sid, nid, eid string, vip net.IP, in
} }
c.Unlock() c.Unlock()
// Delete the special "tasks.svc_name" backend record.
n.(*network).deleteSvcRecords("tasks."+name, ip, nil, false)
for _, alias := range aliases {
n.(*network).deleteSvcRecords("tasks."+alias, ip, nil, false)
}
// If we are doing DNS RR add the endpoint IP to DNS record
// right away.
if len(vip) == 0 {
n.(*network).deleteSvcRecords(name, ip, nil, false)
for _, alias := range aliases {
n.(*network).deleteSvcRecords(alias, ip, nil, false)
}
}
s.Lock() s.Lock()
lb, ok := s.loadBalancers[nid] lb, ok := s.loadBalancers[nid]
if !ok { if !ok {
@ -161,6 +146,12 @@ func (c *controller) rmServiceBinding(name, sid, nid, eid string, vip net.IP, in
return nil return nil
} }
_, ok = lb.backEnds[eid]
if !ok {
s.Unlock()
return nil
}
delete(lb.backEnds, eid) delete(lb.backEnds, eid)
if len(lb.backEnds) == 0 { if len(lb.backEnds) == 0 {
// All the backends for this service have been // All the backends for this service have been
@ -184,6 +175,21 @@ func (c *controller) rmServiceBinding(name, sid, nid, eid string, vip net.IP, in
} }
s.Unlock() s.Unlock()
// Delete the special "tasks.svc_name" backend record.
n.(*network).deleteSvcRecords("tasks."+name, ip, nil, false)
for _, alias := range aliases {
n.(*network).deleteSvcRecords("tasks."+alias, ip, nil, false)
}
// If we are doing DNS RR add the endpoint IP to DNS record
// right away.
if len(vip) == 0 {
n.(*network).deleteSvcRecords(name, ip, nil, false)
for _, alias := range aliases {
n.(*network).deleteSvcRecords(alias, ip, nil, false)
}
}
// Remove the DNS record for VIP only if we are removing the service // Remove the DNS record for VIP only if we are removing the service
if rmService && len(vip) != 0 { if rmService && len(vip) != 0 {
n.(*network).deleteSvcRecords(name, vip, nil, false) n.(*network).deleteSvcRecords(name, vip, nil, false)
@ -255,7 +261,7 @@ func (sb *sandbox) populateLoadbalancers(ep *endpoint) {
addService := true addService := true
for _, ip := range lb.backEnds { for _, ip := range lb.backEnds {
sb.addLBBackend(ip, lb.vip, lb.fwMark, lb.service.ingressPorts, sb.addLBBackend(ip, lb.vip, lb.fwMark, lb.service.ingressPorts,
eIP, gwIP, addService) eIP, gwIP, addService, n.ingress)
addService = false addService = false
} }
lb.service.Unlock() lb.service.Unlock()
@ -278,7 +284,7 @@ func (n *network) addLBBackend(ip, vip net.IP, fwMark uint32, ingressPorts []*Po
gwIP = ep.Iface().Address().IP gwIP = ep.Iface().Address().IP
} }
sb.addLBBackend(ip, vip, fwMark, ingressPorts, ep.Iface().Address(), gwIP, addService) sb.addLBBackend(ip, vip, fwMark, ingressPorts, ep.Iface().Address(), gwIP, addService, n.ingress)
} }
return false return false
@ -301,7 +307,7 @@ func (n *network) rmLBBackend(ip, vip net.IP, fwMark uint32, ingressPorts []*Por
gwIP = ep.Iface().Address().IP gwIP = ep.Iface().Address().IP
} }
sb.rmLBBackend(ip, vip, fwMark, ingressPorts, ep.Iface().Address(), gwIP, rmService) sb.rmLBBackend(ip, vip, fwMark, ingressPorts, ep.Iface().Address(), gwIP, rmService, n.ingress)
} }
return false return false
@ -309,14 +315,18 @@ func (n *network) rmLBBackend(ip, vip net.IP, fwMark uint32, ingressPorts []*Por
} }
// Add loadbalancer backend into one connected sandbox. // Add loadbalancer backend into one connected sandbox.
func (sb *sandbox) addLBBackend(ip, vip net.IP, fwMark uint32, ingressPorts []*PortConfig, eIP *net.IPNet, gwIP net.IP, addService bool) { func (sb *sandbox) addLBBackend(ip, vip net.IP, fwMark uint32, ingressPorts []*PortConfig, eIP *net.IPNet, gwIP net.IP, addService bool, isIngressNetwork bool) {
if sb.osSbox == nil { if sb.osSbox == nil {
return return
} }
if isIngressNetwork && !sb.ingress {
return
}
i, err := ipvs.New(sb.Key()) i, err := ipvs.New(sb.Key())
if err != nil { if err != nil {
logrus.Errorf("Failed to create a ipvs handle for sbox %s: %v", sb.Key(), err) logrus.Errorf("Failed to create an ipvs handle for sbox %s: %v", sb.Key(), err)
return return
} }
defer i.Close() defer i.Close()
@ -364,14 +374,18 @@ func (sb *sandbox) addLBBackend(ip, vip net.IP, fwMark uint32, ingressPorts []*P
} }
// Remove loadbalancer backend from one connected sandbox. // Remove loadbalancer backend from one connected sandbox.
func (sb *sandbox) rmLBBackend(ip, vip net.IP, fwMark uint32, ingressPorts []*PortConfig, eIP *net.IPNet, gwIP net.IP, rmService bool) { func (sb *sandbox) rmLBBackend(ip, vip net.IP, fwMark uint32, ingressPorts []*PortConfig, eIP *net.IPNet, gwIP net.IP, rmService bool, isIngressNetwork bool) {
if sb.osSbox == nil { if sb.osSbox == nil {
return return
} }
if isIngressNetwork && !sb.ingress {
return
}
i, err := ipvs.New(sb.Key()) i, err := ipvs.New(sb.Key())
if err != nil { if err != nil {
logrus.Errorf("Failed to create a ipvs handle for sbox %s: %v", sb.Key(), err) logrus.Errorf("Failed to create an ipvs handle for sbox %s: %v", sb.Key(), err)
return return
} }
defer i.Close() defer i.Close()
@ -704,7 +718,7 @@ func fwMarker() {
os.Exit(4) os.Exit(4)
} }
if len(ingressPorts) != 0 && addDelOpt == "-A" { if addDelOpt == "-A" {
ruleParams := strings.Fields(fmt.Sprintf("-m ipvs --ipvs -j SNAT --to-source %s", os.Args[6])) ruleParams := strings.Fields(fmt.Sprintf("-m ipvs --ipvs -j SNAT --to-source %s", os.Args[6]))
if !iptables.Exists("nat", "POSTROUTING", ruleParams...) { if !iptables.Exists("nat", "POSTROUTING", ruleParams...) {
rule := append(strings.Fields("-t nat -A POSTROUTING"), ruleParams...) rule := append(strings.Fields("-t nat -A POSTROUTING"), ruleParams...)

View file

@ -235,7 +235,7 @@ const (
UDP = 17 UDP = 17
) )
// Protocol represents a IP protocol number // Protocol represents an IP protocol number
type Protocol uint8 type Protocol uint8
func (p Protocol) String() string { func (p Protocol) String() string {