Signed-off-by: Tom Denham <tom@tomdee.co.uk>
| ... | ... |
@@ -23,7 +23,7 @@ github.com/RackSec/srslog 365bf33cd9acc21ae1c355209865f17228ca534e |
| 23 | 23 |
github.com/imdario/mergo 0.2.1 |
| 24 | 24 |
|
| 25 | 25 |
#get libnetwork packages |
| 26 |
-github.com/docker/libnetwork 57be722e077059d1ee0539be31743a3642ccbeb3 |
|
| 26 |
+github.com/docker/libnetwork f36e733a08cd8239a2db296994cb6613fef1cece |
|
| 27 | 27 |
github.com/docker/go-events 18b43f1bc85d9cdd42c05a6cd2d444c7a200a894 |
| 28 | 28 |
github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80 |
| 29 | 29 |
github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec |
| ... | ... |
@@ -381,7 +381,57 @@ func (n *network) leaveCluster() error {
|
| 381 | 381 |
return c.agent.networkDB.LeaveNetwork(n.ID()) |
| 382 | 382 |
} |
| 383 | 383 |
|
| 384 |
-func (ep *endpoint) addToCluster() error {
|
|
| 384 |
+func (ep *endpoint) addDriverInfoToCluster() error {
|
|
| 385 |
+ n := ep.getNetwork() |
|
| 386 |
+ if !n.isClusterEligible() {
|
|
| 387 |
+ return nil |
|
| 388 |
+ } |
|
| 389 |
+ if ep.joinInfo == nil {
|
|
| 390 |
+ return nil |
|
| 391 |
+ } |
|
| 392 |
+ |
|
| 393 |
+ ctrlr := n.ctrlr |
|
| 394 |
+ ctrlr.Lock() |
|
| 395 |
+ agent := ctrlr.agent |
|
| 396 |
+ ctrlr.Unlock() |
|
| 397 |
+ if agent == nil {
|
|
| 398 |
+ return nil |
|
| 399 |
+ } |
|
| 400 |
+ |
|
| 401 |
+ for _, te := range ep.joinInfo.driverTableEntries {
|
|
| 402 |
+ if err := agent.networkDB.CreateEntry(te.tableName, n.ID(), te.key, te.value); err != nil {
|
|
| 403 |
+ return err |
|
| 404 |
+ } |
|
| 405 |
+ } |
|
| 406 |
+ return nil |
|
| 407 |
+} |
|
| 408 |
+ |
|
| 409 |
+func (ep *endpoint) deleteDriverInfoFromCluster() error {
|
|
| 410 |
+ n := ep.getNetwork() |
|
| 411 |
+ if !n.isClusterEligible() {
|
|
| 412 |
+ return nil |
|
| 413 |
+ } |
|
| 414 |
+ if ep.joinInfo == nil {
|
|
| 415 |
+ return nil |
|
| 416 |
+ } |
|
| 417 |
+ |
|
| 418 |
+ ctrlr := n.ctrlr |
|
| 419 |
+ ctrlr.Lock() |
|
| 420 |
+ agent := ctrlr.agent |
|
| 421 |
+ ctrlr.Unlock() |
|
| 422 |
+ if agent == nil {
|
|
| 423 |
+ return nil |
|
| 424 |
+ } |
|
| 425 |
+ |
|
| 426 |
+ for _, te := range ep.joinInfo.driverTableEntries {
|
|
| 427 |
+ if err := agent.networkDB.DeleteEntry(te.tableName, n.ID(), te.key); err != nil {
|
|
| 428 |
+ return err |
|
| 429 |
+ } |
|
| 430 |
+ } |
|
| 431 |
+ return nil |
|
| 432 |
+} |
|
| 433 |
+ |
|
| 434 |
+func (ep *endpoint) addServiceInfoToCluster() error {
|
|
| 385 | 435 |
n := ep.getNetwork() |
| 386 | 436 |
if !n.isClusterEligible() {
|
| 387 | 437 |
return nil |
| ... | ... |
@@ -421,16 +471,10 @@ func (ep *endpoint) addToCluster() error {
|
| 421 | 421 |
} |
| 422 | 422 |
} |
| 423 | 423 |
|
| 424 |
- for _, te := range ep.joinInfo.driverTableEntries {
|
|
| 425 |
- if err := c.agent.networkDB.CreateEntry(te.tableName, n.ID(), te.key, te.value); err != nil {
|
|
| 426 |
- return err |
|
| 427 |
- } |
|
| 428 |
- } |
|
| 429 |
- |
|
| 430 | 424 |
return nil |
| 431 | 425 |
} |
| 432 | 426 |
|
| 433 |
-func (ep *endpoint) deleteFromCluster() error {
|
|
| 427 |
+func (ep *endpoint) deleteServiceInfoFromCluster() error {
|
|
| 434 | 428 |
n := ep.getNetwork() |
| 435 | 429 |
if !n.isClusterEligible() {
|
| 436 | 430 |
return nil |
| ... | ... |
@@ -453,17 +497,6 @@ func (ep *endpoint) deleteFromCluster() error {
|
| 453 | 453 |
return err |
| 454 | 454 |
} |
| 455 | 455 |
} |
| 456 |
- |
|
| 457 |
- if ep.joinInfo == nil {
|
|
| 458 |
- return nil |
|
| 459 |
- } |
|
| 460 |
- |
|
| 461 |
- for _, te := range ep.joinInfo.driverTableEntries {
|
|
| 462 |
- if err := c.agent.networkDB.DeleteEntry(te.tableName, n.ID(), te.key); err != nil {
|
|
| 463 |
- return err |
|
| 464 |
- } |
|
| 465 |
- } |
|
| 466 |
- |
|
| 467 | 456 |
return nil |
| 468 | 457 |
} |
| 469 | 458 |
|
| ... | ... |
@@ -17,11 +17,11 @@ import ( |
| 17 | 17 |
"github.com/docker/libnetwork/osl" |
| 18 | 18 |
) |
| 19 | 19 |
|
| 20 |
-// RestrictedNameChars collects the characters allowed to represent a network or endpoint name. |
|
| 21 |
-const restrictedNameChars = `[a-zA-Z0-9][a-zA-Z0-9_.-]` |
|
| 20 |
+// restrictedNameRegex represents the regular expression which regulates the allowed network or endpoint names. |
|
| 21 |
+const restrictedNameRegex = `^[\w]+[\w-. ]*[\w]+$` |
|
| 22 | 22 |
|
| 23 | 23 |
// RestrictedNamePattern is a regular expression to validate names against the collection of restricted characters. |
| 24 |
-var restrictedNamePattern = regexp.MustCompile(`^/?` + restrictedNameChars + `+$`) |
|
| 24 |
+var restrictedNamePattern = regexp.MustCompile(restrictedNameRegex) |
|
| 25 | 25 |
|
| 26 | 26 |
// Config encapsulates configurations of various Libnetwork components |
| 27 | 27 |
type Config struct {
|
| ... | ... |
@@ -234,7 +234,7 @@ func (c *Config) ProcessOptions(options ...Option) {
|
| 234 | 234 |
// ValidateName validates configuration objects supported by libnetwork |
| 235 | 235 |
func ValidateName(name string) error {
|
| 236 | 236 |
if !restrictedNamePattern.MatchString(name) {
|
| 237 |
- return fmt.Errorf("%s includes invalid characters, only %q are allowed", name, restrictedNameChars)
|
|
| 237 |
+ return fmt.Errorf("%q includes invalid characters, resource name has to conform to %q", name, restrictedNameRegex)
|
|
| 238 | 238 |
} |
| 239 | 239 |
return nil |
| 240 | 240 |
} |
| ... | ... |
@@ -77,7 +77,7 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo, |
| 77 | 77 |
} |
| 78 | 78 |
|
| 79 | 79 |
if s := n.getSubnetforIP(ep.addr); s == nil {
|
| 80 |
- return fmt.Errorf("no matching subnet for IP %q in network %q\n", ep.addr, nid)
|
|
| 80 |
+ return fmt.Errorf("no matching subnet for IP %q in network %q", ep.addr, nid)
|
|
| 81 | 81 |
} |
| 82 | 82 |
|
| 83 | 83 |
if ep.mac == nil {
|
| ... | ... |
@@ -320,6 +320,11 @@ func populateVNITbl() {
|
| 320 | 320 |
} |
| 321 | 321 |
defer nlh.Delete() |
| 322 | 322 |
|
| 323 |
+ err = nlh.SetSocketTimeout(soTimeout) |
|
| 324 |
+ if err != nil {
|
|
| 325 |
+ logrus.Warnf("Failed to set the timeout on the netlink handle sockets for vni table population: %v", err)
|
|
| 326 |
+ } |
|
| 327 |
+ |
|
| 323 | 328 |
links, err := nlh.LinkList() |
| 324 | 329 |
if err != nil {
|
| 325 | 330 |
logrus.Errorf("Failed to list interfaces during vni population for ns %s: %v", path, err)
|
| ... | ... |
@@ -13,6 +13,8 @@ import ( |
| 13 | 13 |
"github.com/vishvananda/netns" |
| 14 | 14 |
) |
| 15 | 15 |
|
| 16 |
+var soTimeout = ns.NetlinkSocketsTimeout |
|
| 17 |
+ |
|
| 16 | 18 |
func validateID(nid, eid string) error {
|
| 17 | 19 |
if nid == "" {
|
| 18 | 20 |
return fmt.Errorf("invalid network id")
|
| ... | ... |
@@ -134,6 +136,10 @@ func deleteVxlanByVNI(path string, vni uint32) error {
|
| 134 | 134 |
return fmt.Errorf("failed to get netlink handle for ns %s: %v", path, err)
|
| 135 | 135 |
} |
| 136 | 136 |
defer nlh.Delete() |
| 137 |
+ err = nlh.SetSocketTimeout(soTimeout) |
|
| 138 |
+ if err != nil {
|
|
| 139 |
+ logrus.Warnf("Failed to set the timeout on the netlink handle sockets for vxlan deletion: %v", err)
|
|
| 140 |
+ } |
|
| 137 | 141 |
} |
| 138 | 142 |
|
| 139 | 143 |
links, err := nlh.LinkList() |
| ... | ... |
@@ -277,7 +277,7 @@ func (d *driver) peerAdd(nid, eid string, peerIP net.IP, peerIPMask net.IPMask, |
| 277 | 277 |
|
| 278 | 278 |
s := n.getSubnetforIP(IP) |
| 279 | 279 |
if s == nil {
|
| 280 |
- return fmt.Errorf("couldn't find the subnet %q in network %q\n", IP.String(), n.id)
|
|
| 280 |
+ return fmt.Errorf("couldn't find the subnet %q in network %q", IP.String(), n.id)
|
|
| 281 | 281 |
} |
| 282 | 282 |
|
| 283 | 283 |
if err := n.obtainVxlanID(s); err != nil {
|
| ... | ... |
@@ -76,7 +76,7 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo, |
| 76 | 76 |
} |
| 77 | 77 |
|
| 78 | 78 |
if s := n.getSubnetforIP(ep.addr); s == nil {
|
| 79 |
- return fmt.Errorf("no matching subnet for IP %q in network %q\n", ep.addr, nid)
|
|
| 79 |
+ return fmt.Errorf("no matching subnet for IP %q in network %q", ep.addr, nid)
|
|
| 80 | 80 |
} |
| 81 | 81 |
|
| 82 | 82 |
if ep.mac == nil {
|
| ... | ... |
@@ -263,7 +263,7 @@ func (d *driver) peerAdd(nid, eid string, peerIP net.IP, peerIPMask net.IPMask, |
| 263 | 263 |
|
| 264 | 264 |
s := n.getSubnetforIP(IP) |
| 265 | 265 |
if s == nil {
|
| 266 |
- return fmt.Errorf("couldn't find the subnet %q in network %q\n", IP.String(), n.id)
|
|
| 266 |
+ return fmt.Errorf("couldn't find the subnet %q in network %q", IP.String(), n.id)
|
|
| 267 | 267 |
} |
| 268 | 268 |
|
| 269 | 269 |
if err := n.obtainVxlanID(s); err != nil {
|
| ... | ... |
@@ -515,6 +515,10 @@ func (ep *endpoint) sbJoin(sb *sandbox, options ...EndpointOption) error {
|
| 515 | 515 |
return err |
| 516 | 516 |
} |
| 517 | 517 |
|
| 518 |
+ if err = ep.addDriverInfoToCluster(); err != nil {
|
|
| 519 |
+ return err |
|
| 520 |
+ } |
|
| 521 |
+ |
|
| 518 | 522 |
if sb.needDefaultGW() && sb.getEndpointInGWNetwork() == nil {
|
| 519 | 523 |
return sb.setupDefaultGW() |
| 520 | 524 |
} |
| ... | ... |
@@ -709,8 +713,12 @@ func (ep *endpoint) sbLeave(sb *sandbox, force bool, options ...EndpointOption) |
| 709 | 709 |
return err |
| 710 | 710 |
} |
| 711 | 711 |
|
| 712 |
- if e := ep.deleteFromCluster(); e != nil {
|
|
| 713 |
- logrus.Errorf("Could not delete state for endpoint %s from cluster: %v", ep.Name(), e)
|
|
| 712 |
+ if e := ep.deleteServiceInfoFromCluster(); e != nil {
|
|
| 713 |
+ logrus.Errorf("Could not delete service state for endpoint %s from cluster: %v", ep.Name(), e)
|
|
| 714 |
+ } |
|
| 715 |
+ |
|
| 716 |
+ if e := ep.deleteDriverInfoFromCluster(); e != nil {
|
|
| 717 |
+ logrus.Errorf("Could not delete endpoint state for endpoint %s from cluster: %v", ep.Name(), e)
|
|
| 714 | 718 |
} |
| 715 | 719 |
|
| 716 | 720 |
sb.deleteHostsEntries(n.getSvcRecords(ep)) |
| ... | ... |
@@ -413,7 +413,7 @@ func (a *Allocator) getPredefinedPool(as string, ipV6 bool) (*net.IPNet, error) |
| 413 | 413 |
} |
| 414 | 414 |
} |
| 415 | 415 |
|
| 416 |
- return nil, types.NotFoundErrorf("could not find an available non-overlapping address pool among the defaults to auto assign to the network")
|
|
| 416 |
+ return nil, types.NotFoundErrorf("could not find an available, non-overlapping IPv%d address pool among the defaults to assign to the network", v)
|
|
| 417 | 417 |
} |
| 418 | 418 |
|
| 419 | 419 |
// RequestAddress returns an address from the specified pool ID |
| ... | ... |
@@ -130,7 +130,7 @@ func NewChain(name string, table Table, hairpinMode bool) (*ChainInfo, error) {
|
| 130 | 130 |
// ProgramChain is used to add rules to a chain |
| 131 | 131 |
func ProgramChain(c *ChainInfo, bridgeName string, hairpinMode, enable bool) error {
|
| 132 | 132 |
if c.Name == "" {
|
| 133 |
- return fmt.Errorf("Could not program chain, missing chain name.")
|
|
| 133 |
+ return fmt.Errorf("Could not program chain, missing chain name")
|
|
| 134 | 134 |
} |
| 135 | 135 |
|
| 136 | 136 |
switch c.Table {
|
| ... | ... |
@@ -166,7 +166,7 @@ func ProgramChain(c *ChainInfo, bridgeName string, hairpinMode, enable bool) err |
| 166 | 166 |
} |
| 167 | 167 |
case Filter: |
| 168 | 168 |
if bridgeName == "" {
|
| 169 |
- return fmt.Errorf("Could not program chain %s/%s, missing bridge name.",
|
|
| 169 |
+ return fmt.Errorf("Could not program chain %s/%s, missing bridge name",
|
|
| 170 | 170 |
c.Table, c.Name) |
| 171 | 171 |
} |
| 172 | 172 |
link := []string{
|
| ... | ... |
@@ -65,6 +65,7 @@ type NetworkInfo interface {
|
| 65 | 65 |
Scope() string |
| 66 | 66 |
IPv6Enabled() bool |
| 67 | 67 |
Internal() bool |
| 68 |
+ Attachable() bool |
|
| 68 | 69 |
Labels() map[string]string |
| 69 | 70 |
Dynamic() bool |
| 70 | 71 |
Created() time.Time |
| ... | ... |
@@ -196,6 +197,7 @@ type network struct {
|
| 196 | 196 |
resolverOnce sync.Once |
| 197 | 197 |
resolver []Resolver |
| 198 | 198 |
internal bool |
| 199 |
+ attachable bool |
|
| 199 | 200 |
inDelete bool |
| 200 | 201 |
ingress bool |
| 201 | 202 |
driverTables []string |
| ... | ... |
@@ -348,6 +350,7 @@ func (n *network) CopyTo(o datastore.KVObject) error {
|
| 348 | 348 |
dstN.dbExists = n.dbExists |
| 349 | 349 |
dstN.drvOnce = n.drvOnce |
| 350 | 350 |
dstN.internal = n.internal |
| 351 |
+ dstN.attachable = n.attachable |
|
| 351 | 352 |
dstN.inDelete = n.inDelete |
| 352 | 353 |
dstN.ingress = n.ingress |
| 353 | 354 |
|
| ... | ... |
@@ -456,6 +459,7 @@ func (n *network) MarshalJSON() ([]byte, error) {
|
| 456 | 456 |
netMap["ipamV6Info"] = string(iis) |
| 457 | 457 |
} |
| 458 | 458 |
netMap["internal"] = n.internal |
| 459 |
+ netMap["attachable"] = n.attachable |
|
| 459 | 460 |
netMap["inDelete"] = n.inDelete |
| 460 | 461 |
netMap["ingress"] = n.ingress |
| 461 | 462 |
return json.Marshal(netMap) |
| ... | ... |
@@ -550,6 +554,9 @@ func (n *network) UnmarshalJSON(b []byte) (err error) {
|
| 550 | 550 |
if v, ok := netMap["internal"]; ok {
|
| 551 | 551 |
n.internal = v.(bool) |
| 552 | 552 |
} |
| 553 |
+ if v, ok := netMap["attachable"]; ok {
|
|
| 554 |
+ n.attachable = v.(bool) |
|
| 555 |
+ } |
|
| 553 | 556 |
if s, ok := netMap["scope"]; ok {
|
| 554 | 557 |
n.scope = s.(string) |
| 555 | 558 |
} |
| ... | ... |
@@ -628,6 +635,13 @@ func NetworkOptionInternalNetwork() NetworkOption {
|
| 628 | 628 |
} |
| 629 | 629 |
} |
| 630 | 630 |
|
| 631 |
+// NetworkOptionAttachable returns an option setter to set attachable for a network |
|
| 632 |
+func NetworkOptionAttachable(attachable bool) NetworkOption {
|
|
| 633 |
+ return func(n *network) {
|
|
| 634 |
+ n.attachable = attachable |
|
| 635 |
+ } |
|
| 636 |
+} |
|
| 637 |
+ |
|
| 631 | 638 |
// NetworkOptionIpam function returns an option setter for the ipam configuration for this network |
| 632 | 639 |
func NetworkOptionIpam(ipamDriver string, addrSpace string, ipV4 []*IpamConf, ipV6 []*IpamConf, opts map[string]string) NetworkOption {
|
| 633 | 640 |
return func(n *network) {
|
| ... | ... |
@@ -1289,9 +1303,6 @@ func (n *network) ipamAllocateVersion(ipVer int, ipam ipamapi.Ipam) error {
|
| 1289 | 1289 |
} |
| 1290 | 1290 |
|
| 1291 | 1291 |
if len(*cfgList) == 0 {
|
| 1292 |
- if ipVer == 6 {
|
|
| 1293 |
- return nil |
|
| 1294 |
- } |
|
| 1295 | 1292 |
*cfgList = []*IpamConf{{}}
|
| 1296 | 1293 |
} |
| 1297 | 1294 |
|
| ... | ... |
@@ -1555,6 +1566,13 @@ func (n *network) Internal() bool {
|
| 1555 | 1555 |
return n.internal |
| 1556 | 1556 |
} |
| 1557 | 1557 |
|
| 1558 |
+func (n *network) Attachable() bool {
|
|
| 1559 |
+ n.Lock() |
|
| 1560 |
+ defer n.Unlock() |
|
| 1561 |
+ |
|
| 1562 |
+ return n.attachable |
|
| 1563 |
+} |
|
| 1564 |
+ |
|
| 1558 | 1565 |
func (n *network) Dynamic() bool {
|
| 1559 | 1566 |
n.Lock() |
| 1560 | 1567 |
defer n.Unlock() |
| ... | ... |
@@ -265,7 +265,7 @@ func (nDB *NetworkDB) CreateEntry(tname, nid, key string, value []byte) error {
|
| 265 | 265 |
} |
| 266 | 266 |
|
| 267 | 267 |
if err := nDB.sendTableEvent(TableEventTypeCreate, nid, tname, key, entry); err != nil {
|
| 268 |
- return fmt.Errorf("cannot send table create event: %v", err)
|
|
| 268 |
+ return fmt.Errorf("cannot send create event for table %s, %v", tname, err)
|
|
| 269 | 269 |
} |
| 270 | 270 |
|
| 271 | 271 |
nDB.Lock() |
| ... | ... |
@@ -7,6 +7,7 @@ import ( |
| 7 | 7 |
"strings" |
| 8 | 8 |
"sync" |
| 9 | 9 |
"syscall" |
| 10 |
+ "time" |
|
| 10 | 11 |
|
| 11 | 12 |
"github.com/Sirupsen/logrus" |
| 12 | 13 |
"github.com/vishvananda/netlink" |
| ... | ... |
@@ -17,6 +18,8 @@ var ( |
| 17 | 17 |
initNs netns.NsHandle |
| 18 | 18 |
initNl *netlink.Handle |
| 19 | 19 |
initOnce sync.Once |
| 20 |
+ // NetlinkSocketsTimeout represents the default timeout duration for the sockets |
|
| 21 |
+ NetlinkSocketsTimeout = 3 * time.Second |
|
| 20 | 22 |
) |
| 21 | 23 |
|
| 22 | 24 |
// Init initializes a new network namespace |
| ... | ... |
@@ -30,6 +33,10 @@ func Init() {
|
| 30 | 30 |
if err != nil {
|
| 31 | 31 |
logrus.Errorf("could not create netlink handle on initial namespace: %v", err)
|
| 32 | 32 |
} |
| 33 |
+ err = initNl.SetSocketTimeout(NetlinkSocketsTimeout) |
|
| 34 |
+ if err != nil {
|
|
| 35 |
+ logrus.Warnf("Failed to set the timeout on the default netlink handle sockets: %v", err)
|
|
| 36 |
+ } |
|
| 33 | 37 |
} |
| 34 | 38 |
|
| 35 | 39 |
// SetNamespace sets the initial namespace handler |
| ... | ... |
@@ -211,6 +211,11 @@ func NewSandbox(key string, osCreate, isRestore bool) (Sandbox, error) {
|
| 211 | 211 |
return nil, fmt.Errorf("failed to create a netlink handle: %v", err)
|
| 212 | 212 |
} |
| 213 | 213 |
|
| 214 |
+ err = n.nlHandle.SetSocketTimeout(ns.NetlinkSocketsTimeout) |
|
| 215 |
+ if err != nil {
|
|
| 216 |
+ logrus.Warnf("Failed to set the timeout on the sandbox netlink handle sockets: %v", err)
|
|
| 217 |
+ } |
|
| 218 |
+ |
|
| 214 | 219 |
if err = n.loopbackUp(); err != nil {
|
| 215 | 220 |
n.nlHandle.Delete() |
| 216 | 221 |
return nil, err |
| ... | ... |
@@ -253,6 +258,11 @@ func GetSandboxForExternalKey(basePath string, key string) (Sandbox, error) {
|
| 253 | 253 |
return nil, fmt.Errorf("failed to create a netlink handle: %v", err)
|
| 254 | 254 |
} |
| 255 | 255 |
|
| 256 |
+ err = n.nlHandle.SetSocketTimeout(ns.NetlinkSocketsTimeout) |
|
| 257 |
+ if err != nil {
|
|
| 258 |
+ logrus.Warnf("Failed to set the timeout on the sandbox netlink handle sockets: %v", err)
|
|
| 259 |
+ } |
|
| 260 |
+ |
|
| 256 | 261 |
if err = n.loopbackUp(); err != nil {
|
| 257 | 262 |
n.nlHandle.Delete() |
| 258 | 263 |
return nil, err |
| ... | ... |
@@ -80,6 +80,7 @@ func (n *networkNamespace) DeleteNeighbor(dstIP net.IP, dstMac net.HardwareAddr, |
| 80 | 80 |
for i, nh := range n.neighbors {
|
| 81 | 81 |
if nh.dstIP.Equal(dstIP) && bytes.Equal(nh.dstMac, dstMac) {
|
| 82 | 82 |
n.neighbors = append(n.neighbors[:i], n.neighbors[i+1:]...) |
| 83 |
+ break |
|
| 83 | 84 |
} |
| 84 | 85 |
} |
| 85 | 86 |
n.Unlock() |
| ... | ... |
@@ -427,7 +427,13 @@ func (sb *sandbox) ResolveIP(ip string) string {
|
| 427 | 427 |
} |
| 428 | 428 |
|
| 429 | 429 |
func (sb *sandbox) ExecFunc(f func()) error {
|
| 430 |
- return sb.osSbox.InvokeFunc(f) |
|
| 430 |
+ sb.Lock() |
|
| 431 |
+ osSbox := sb.osSbox |
|
| 432 |
+ sb.Unlock() |
|
| 433 |
+ if osSbox != nil {
|
|
| 434 |
+ return osSbox.InvokeFunc(f) |
|
| 435 |
+ } |
|
| 436 |
+ return fmt.Errorf("osl sandbox unavailable in ExecFunc for %v", sb.ContainerID())
|
|
| 431 | 437 |
} |
| 432 | 438 |
|
| 433 | 439 |
func (sb *sandbox) ResolveService(name string) ([]*net.SRV, []net.IP) {
|
| ... | ... |
@@ -664,7 +670,7 @@ func (sb *sandbox) SetKey(basePath string) error {
|
| 664 | 664 |
func (sb *sandbox) EnableService() error {
|
| 665 | 665 |
for _, ep := range sb.getConnectedEndpoints() {
|
| 666 | 666 |
if ep.enableService(true) {
|
| 667 |
- if err := ep.addToCluster(); err != nil {
|
|
| 667 |
+ if err := ep.addServiceInfoToCluster(); err != nil {
|
|
| 668 | 668 |
ep.enableService(false) |
| 669 | 669 |
return fmt.Errorf("could not update state for endpoint %s into cluster: %v", ep.Name(), err)
|
| 670 | 670 |
} |
| ... | ... |
@@ -676,7 +682,7 @@ func (sb *sandbox) EnableService() error {
|
| 676 | 676 |
func (sb *sandbox) DisableService() error {
|
| 677 | 677 |
for _, ep := range sb.getConnectedEndpoints() {
|
| 678 | 678 |
if ep.enableService(false) {
|
| 679 |
- if err := ep.deleteFromCluster(); err != nil {
|
|
| 679 |
+ if err := ep.deleteServiceInfoFromCluster(); err != nil {
|
|
| 680 | 680 |
ep.enableService(true) |
| 681 | 681 |
return fmt.Errorf("could not delete state for endpoint %s from cluster: %v", ep.Name(), err)
|
| 682 | 682 |
} |