func (ep *endpoint) networkIDFromKey(key []string) (types.UUID, error) { // endpoint Key structure : endpoint/network-id/endpoint-id // its an invalid key if the key doesnt have all the 3 key elements above if key == nil || len(key) < 3 || key[0] != datastore.EndpointKeyPrefix { return types.UUID(""), fmt.Errorf("invalid endpoint key : %v", key) } // network-id is placed at index=1. pls refer to endpoint.Key() method return types.UUID(key[1]), nil }
func networkIDFromEndpointKey(key string, ep *endpoint) (types.UUID, error) { eKey, err := datastore.ParseKey(key) if err != nil { return types.UUID(""), err } return ep.networkIDFromKey(eKey) }
func (ep *endpoint) updateParentHosts() error { ep.Lock() container := ep.container network := ep.network ep.Unlock() if container == nil { return ErrNoContainer{} } for _, update := range container.config.parentUpdates { network.Lock() pep, ok := network.endpoints[types.UUID(update.eid)] if !ok { network.Unlock() continue } network.Unlock() pep.Lock() pContainer := pep.container pep.Unlock() if pContainer != nil { if err := etchosts.Update(pContainer.config.hostsPath, update.ip, update.name); err != nil { return err } } } return nil }
func (n *network) EndpointByID(id string) (Endpoint, error) { if id == "" { return nil, ErrInvalidID } n.Lock() defer n.Unlock() if e, ok := n.endpoints[types.UUID(id)]; ok { return e, nil } return nil, ErrNoSuchEndpoint }
func (c *controller) NetworkByID(id string) (Network, error) { if id == "" { return nil, ErrInvalidID } c.Lock() defer c.Unlock() if n, ok := c.networks[types.UUID(id)]; ok { return n, nil } return nil, ErrNoSuchNetwork }
// NewNetwork creates a new network of the specified network type. The options // are network specific and modeled in a generic way. func (c *controller) NewNetwork(networkType, name string, options ...NetworkOption) (Network, error) { if name == "" { return nil, ErrInvalidName(name) } // Check if a driver for the specified network type is available c.Lock() d, ok := c.drivers[networkType] c.Unlock() if !ok { var err error d, err = c.loadDriver(networkType) if err != nil { return nil, err } } // Check if a network already exists with the specified network name c.Lock() for _, n := range c.networks { if n.name == name { c.Unlock() return nil, NetworkNameError(name) } } c.Unlock() // Construct the network object network := &network{ name: name, id: types.UUID(stringid.GenerateRandomID()), ctrlr: c, driver: d, endpoints: endpointTable{}, } network.processOptions(options...) if err := c.addNetworkToStore(network); err != nil { return nil, err } // Create the network if err := d.CreateNetwork(network.id, network.generic); err != nil { return nil, err } // Store the network handler in controller c.Lock() c.networks[network.id] = network c.Unlock() return network, nil }
func (d *driver) processEvent(u serf.UserEvent) { fmt.Printf("Received user event name:%s, payload:%s\n", u.Name, string(u.Payload)) var dummy, action, vtepStr, nid, eid, ipStr, macStr string if _, err := fmt.Sscan(u.Name, &dummy, &vtepStr, &nid, &eid); err != nil { fmt.Printf("Failed to scan name string: %v\n", err) } if _, err := fmt.Sscan(string(u.Payload), &action, &ipStr, &macStr); err != nil { fmt.Printf("Failed to scan value string: %v\n", err) } fmt.Printf("Parsed data = %s/%s/%s/%s/%s\n", nid, eid, vtepStr, ipStr, macStr) mac, err := net.ParseMAC(macStr) if err != nil { fmt.Printf("Failed to parse mac: %v\n", err) } if d.serfInstance.LocalMember().Addr.String() == vtepStr { return } switch action { case "join": if err := d.peerAdd(types.UUID(nid), types.UUID(eid), net.ParseIP(ipStr), mac, net.ParseIP(vtepStr), true); err != nil { fmt.Printf("Peer add failed in the driver: %v\n", err) } case "leave": if err := d.peerDelete(types.UUID(nid), types.UUID(eid), net.ParseIP(ipStr), mac, net.ParseIP(vtepStr), true); err != nil { fmt.Printf("Peer delete failed in the driver: %v\n", err) } } }
// TODO : Can be made much more generic with the help of reflection (but has some golang limitations) func (n *network) UnmarshalJSON(b []byte) (err error) { var netMap map[string]interface{} if err := json.Unmarshal(b, &netMap); err != nil { return err } n.name = netMap["name"].(string) n.id = types.UUID(netMap["id"].(string)) n.networkType = netMap["networkType"].(string) n.enableIPv6 = netMap["enableIPv6"].(bool) if netMap["generic"] != nil { n.generic = netMap["generic"].(map[string]interface{}) } return nil }
func (n *network) CreateEndpoint(name string, options ...EndpointOption) (Endpoint, error) { var err error if !config.IsValidName(name) { return nil, ErrInvalidName(name) } if _, err = n.EndpointByName(name); err == nil { return nil, types.ForbiddenErrorf("service endpoint with name %s already exists", name) } ep := &endpoint{name: name, iFaces: []*endpointInterface{}, generic: make(map[string]interface{})} ep.id = types.UUID(stringid.GenerateRandomID()) ep.network = n ep.processOptions(options...) n.Lock() ctrlr := n.ctrlr n.Unlock() n.IncEndpointCnt() if err = ctrlr.updateNetworkToStore(n); err != nil { return nil, err } defer func() { if err != nil { n.DecEndpointCnt() if err = ctrlr.updateNetworkToStore(n); err != nil { log.Warnf("endpoint count cleanup failed when updating network for %s : %v", name, err) } } }() if err = n.addEndpoint(ep); err != nil { return nil, err } defer func() { if err != nil { if e := ep.Delete(); ep != nil { log.Warnf("cleaning up endpoint failed %s : %v", name, e) } } }() if err = ctrlr.updateEndpointToStore(ep); err != nil { return nil, err } return ep, nil }
func (d *driver) processQuery(q *serf.Query) { fmt.Printf("Received query name:%s, payload:%s\n", q.Name, string(q.Payload)) var nid, ipStr string if _, err := fmt.Sscan(string(q.Payload), &nid, &ipStr); err != nil { fmt.Printf("Failed to scan query payload string: %v\n", err) } peerMac, vtep, err := d.peerDbSearch(types.UUID(nid), net.ParseIP(ipStr)) if err != nil { return } q.Respond([]byte(fmt.Sprintf("%s %s", peerMac.String(), vtep.String()))) }
func (n *network) CreateEndpoint(name string, options ...EndpointOption) (Endpoint, error) { if name == "" { return nil, ErrInvalidName } ep := &endpoint{name: name, iFaces: []*endpointInterface{}, generic: make(map[string]interface{})} ep.id = types.UUID(stringid.GenerateRandomID()) ep.network = n ep.processOptions(options...) d := n.driver err := d.CreateEndpoint(n.id, ep.id, ep, ep.generic) if err != nil { return nil, err } n.Lock() n.endpoints[ep.id] = ep n.Unlock() return ep, nil }
func (n *network) watchMiss(nlSock *nl.NetlinkSocket) { for { msgs, err := nlSock.Recieve() if err != nil { logrus.Errorf("Failed to receive from netlink: %v ", err) continue } for _, msg := range msgs { if msg.Header.Type != syscall.RTM_GETNEIGH && msg.Header.Type != syscall.RTM_NEWNEIGH { continue } neigh, err := netlink.NeighDeserialize(msg.Data) if err != nil { logrus.Errorf("Failed to deserialize netlink ndmsg: %v", err) continue } if neigh.IP.To16() != nil { continue } if neigh.State&(netlink.NUD_STALE|netlink.NUD_INCOMPLETE) == 0 { continue } mac, vtep, err := n.driver.resolvePeer(n.id, neigh.IP) if err != nil { logrus.Errorf("could not resolve peer %q: %v", neigh.IP, err) continue } if err := n.driver.peerAdd(n.id, types.UUID("dummy"), neigh.IP, mac, vtep, true); err != nil { logrus.Errorf("could not add neighbor entry for missed peer: %v", err) } } } }
// NewNetwork creates a new network of the specified network type. The options // are network specific and modeled in a generic way. func (c *controller) NewNetwork(networkType, name string, options ...NetworkOption) (Network, error) { if !config.IsValidName(name) { return nil, ErrInvalidName(name) } // Check if a network already exists with the specified network name c.Lock() for _, n := range c.networks { if n.name == name { c.Unlock() return nil, NetworkNameError(name) } } c.Unlock() // Construct the network object network := &network{ name: name, networkType: networkType, id: types.UUID(stringid.GenerateRandomID()), ctrlr: c, endpoints: endpointTable{}, } network.processOptions(options...) if err := c.addNetwork(network); err != nil { return nil, err } if err := c.updateNetworkToStore(network); err != nil { log.Warnf("couldnt create network %s: %v", network.name, err) if e := network.Delete(); e != nil { log.Warnf("couldnt cleanup network %s: %v", network.name, err) } return nil, err } return network, nil }
func (ep *endpoint) UnmarshalJSON(b []byte) (err error) { ep.Lock() defer ep.Unlock() var epMap map[string]interface{} if err := json.Unmarshal(b, &epMap); err != nil { return err } ep.name = epMap["name"].(string) ep.id = types.UUID(epMap["id"].(string)) ib, _ := json.Marshal(epMap["ep_iface"]) var ifaces []endpointInterface json.Unmarshal(ib, &ifaces) ep.iFaces = make([]*endpointInterface, 0) for _, iface := range ifaces { ep.iFaces = append(ep.iFaces, &iface) } tb, _ := json.Marshal(epMap["exposed_ports"]) var tPorts []types.TransportPort json.Unmarshal(tb, &tPorts) ep.exposedPorts = tPorts epc, ok := epMap["container"] if ok { cb, _ := json.Marshal(epc) var cInfo containerInfo json.Unmarshal(cb, &cInfo) ep.container = &cInfo } if epMap["generic"] != nil { ep.generic = epMap["generic"].(map[string]interface{}) } return nil }
func (d *driver) link(network *bridgeNetwork, endpoint *bridgeEndpoint, options map[string]interface{}, enable bool) error { var ( cc *containerConfiguration err error ) if enable { cc, err = parseContainerOptions(options) if err != nil { return err } } else { cc = endpoint.containerConfig } if cc == nil { return nil } if endpoint.config != nil && endpoint.config.ExposedPorts != nil { for _, p := range cc.ParentEndpoints { var parentEndpoint *bridgeEndpoint parentEndpoint, err = network.getEndpoint(types.UUID(p)) if err != nil { return err } if parentEndpoint == nil { err = InvalidEndpointIDError(p) return err } l := newLink(parentEndpoint.addr.IP.String(), endpoint.addr.IP.String(), endpoint.config.ExposedPorts, network.config.BridgeName) if enable { err = l.Enable() if err != nil { return err } defer func() { if err != nil { l.Disable() } }() } else { l.Disable() } } } for _, c := range cc.ChildEndpoints { var childEndpoint *bridgeEndpoint childEndpoint, err = network.getEndpoint(types.UUID(c)) if err != nil { return err } if childEndpoint == nil { err = InvalidEndpointIDError(c) return err } if childEndpoint.config == nil || childEndpoint.config.ExposedPorts == nil { continue } l := newLink(endpoint.addr.IP.String(), childEndpoint.addr.IP.String(), childEndpoint.config.ExposedPorts, network.config.BridgeName) if enable { err = l.Enable() if err != nil { return err } defer func() { if err != nil { l.Disable() } }() } else { l.Disable() } } if enable { endpoint.containerConfig = cc } return nil }
func main() { if reexec.Init() { return } r := &router{} if err := overlay.Init(r); err != nil { fmt.Printf("Failed to initialize overlay driver: %v\n", err) os.Exit(1) } opt := make(map[string]interface{}) if len(os.Args) > 1 { opt[netlabel.OverlayBindInterface] = os.Args[1] } if len(os.Args) > 2 { opt[netlabel.OverlayNeighborIP] = os.Args[2] } if len(os.Args) > 3 { opt[netlabel.KVProvider] = os.Args[3] } if len(os.Args) > 4 { opt[netlabel.KVProviderURL] = os.Args[4] } r.d.Config(opt) if err := r.d.CreateNetwork(types.UUID("testnetwork"), map[string]interface{}{}); err != nil { fmt.Printf("Failed to create network in the driver: %v\n", err) os.Exit(1) } ep := &endpoint{} if err := r.d.CreateEndpoint(types.UUID("testnetwork"), types.UUID("testep"), ep, map[string]interface{}{}); err != nil { fmt.Printf("Failed to create endpoint in the driver: %v\n", err) os.Exit(1) } if err := r.d.Join(types.UUID("testnetwork"), types.UUID("testep"), "", ep, map[string]interface{}{}); err != nil { fmt.Printf("Failed to join an endpoint in the driver: %v\n", err) os.Exit(1) } link, err := netlink.LinkByName(ep.name) if err != nil { fmt.Printf("Failed to find the container interface with name %s: %v\n", ep.name, err) os.Exit(1) } ipAddr := &netlink.Addr{IPNet: &ep.addr, Label: ""} if err := netlink.AddrAdd(link, ipAddr); err != nil { fmt.Printf("Failed to add address to the interface: %v\n", err) os.Exit(1) } sigCh := make(chan os.Signal, 1) signal.Notify(sigCh, os.Interrupt, os.Kill) for { select { case <-sigCh: r.d.Leave(types.UUID("testnetwork"), types.UUID("testep")) overlay.Fini(r.d) os.Exit(0) } } }