func stringHardwareAddress(hardwareAddr net.HardwareAddr) string { s := hardwareAddr.String() if len(s) == 0 { return "-" } return s }
// Disconnects Switch dpid. func disconnect(dpid net.HardwareAddr) { network.Lock() defer network.Unlock() log.Printf("Closing connection with: %s", dpid) network.Switches[dpid.String()].stream.Shutdown <- true delete(network.Switches, dpid.String()) }
// Builds and populates a Switch struct then starts listening // for OpenFlow messages on conn. func NewSwitch(stream *util.MessageStream, dpid net.HardwareAddr, app AppInterface) *OFSwitch { var s *OFSwitch if getSwitch(dpid) == nil { log.Infoln("Openflow Connection for new switch:", dpid) s = new(OFSwitch) s.app = app s.stream = stream s.dpid = dpid // Initialize the fgraph elements s.initFgraph() // Save it switchDb.Set(dpid.String(), s) // Main receive loop for the switch go s.receive() } else { log.Infoln("Openflow Connection for switch:", dpid) s = getSwitch(dpid) s.stream = stream s.dpid = dpid } // send Switch connected callback s.switchConnected() // Return the new switch return s }
// Returns a pointer to the Switch mapped to dpid. func getSwitch(dpid net.HardwareAddr) *OFSwitch { sw, _ := switchDb.Get(dpid.String()) if sw == nil { return nil } return sw.(*OFSwitch) }
// GetLease : get an existing lease or mark a new one. // Find a free address // 1. unused // 2. inactive // 3. expired // 4. fail func (s Store) GetLease(mac net.HardwareAddr) (l *Lease, err error) { newl := &Lease{} // do I have a lease for this mac address logger.Debug("Find Lease for %v", mac) newl, err = s.leases.Mac(mac) if err == nil { return newl, err } logger.Debug("No existing lease %s ", err) // find a lease that is inactive and not reserved l, err = s.leases.Free(mac) if err != nil { logger.Debug("Lease search error %s ", err) } else { // get one lease and update it's mac address logger.Debug("found lease, updating") l.MAC = mac.String() l.Created = time.Now() if l.Name == "" { l.Name = fmt.Sprintf("node%d", l.ID) } logger.Debug("updated lease") s.leases.Save(s.DBname) return l, nil } return l, err }
/** * Get device by MAC Address. */ func (this *devicehelper) GetDevice(macAddress net.HardwareAddr) (device Device, err error) { err = this.collection.GetObject(macAddress.String(), &device) if !bytes.Equal(device.MACAddress, macAddress) { device.MACAddress = macAddress } return }
func getHardwareAddrUint64() uint64 { ifs, err := net.Interfaces() if err != nil { log.Fatalf("Could not get any network interfaces: %v, %+v", err, ifs) } var hwAddr net.HardwareAddr for _, i := range ifs { if len(i.HardwareAddr) > 0 { hwAddr = i.HardwareAddr break } } if hwAddr == nil { log.Fatalf("No interface found with a MAC address: %+v", ifs) } mac := hwAddr.String() hex := macStripRegexp.ReplaceAllLiteralString(mac, "") u, err := strconv.ParseUint(hex, 16, 64) if err != nil { log.Fatalf("Unable to parse %v (from mac %v) as an integer: %v", hex, mac, err) } return u }
// Returns a pointer to the Switch mapped to dpid. func Switch(dpid net.HardwareAddr) (*OFSwitch, bool) { network.RLock() defer network.RUnlock() if sw, ok := network.Switches[dpid.String()]; ok { return sw, ok } return nil, false }
//Mac return a lease for the given Hardwareaddr func (ll LeaseList) Mac(mac net.HardwareAddr) (l *Lease, err error) { for _, i := range ll.Leases { if i.MAC == mac.String() { return i, nil } } return l, errors.New("no lease for mac") }
/** * Deletes a device with the given MAC address. */ func (this *devicehelper) DeleteDevice(macAddress net.HardwareAddr) error { err := this.collection.DeleteObject(macAddress.String()) if err != nil { log.Println("Error Deleting Device from Datastore") } return err }
// Returns the link between Switch s and the Switch dpid. func (s *OFSwitch) Link(dpid net.HardwareAddr) (l Link, ok bool) { s.linksMu.RLock() if n, k := s.links[dpid.String()]; k { l = *n ok = true } s.linksMu.RUnlock() return }
func (dt *DataTracker) FindBoundIP(mac net.HardwareAddr) *Subnet { for _, s := range dt.Subnets { for _, b := range s.Bindings { if b.Mac == mac.String() { return s } } } return nil }
func (test *testEndpoint) SetMacAddress(mac net.HardwareAddr) error { if test.macAddress != "" { return types.ForbiddenErrorf("endpoint interface MAC address present (%s). Cannot be modified with %s.", test.macAddress, mac) } if mac == nil { return types.BadRequestErrorf("tried to set nil MAC address to endpoint interface") } test.macAddress = mac.String() return nil }
func (t *leasehelper) GetLeaseByMacaddress(hardwareAddress net.HardwareAddr) (databaseLease leasepool.Lease, err error) { var leaseip string err = t.macaddressKey.GetObject(hardwareAddress.String(), &leaseip) if err != nil { return } if leaseip != "" { return t.GetLeaseByIP(net.ParseIP(leaseip)) } return }
// GetMachine returns a Machine interface which is the accessor/getter/setter // for a node in the etcd datasource. If an entry associated with the passed // mac address does not exist the second return value will be set to false // part of GeneralDataSource interface implementation func (ds *EtcdDataSource) GetMachine(mac net.HardwareAddr) (Machine, bool) { ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) defer cancel() machineName := nameFromMac(mac.String()) response, err := ds.keysAPI.Get(ctx, ds.prefixify(path.Join("machines/"+machineName)), nil) if err != nil { return nil, false } if response.Node.Key[strings.LastIndex(response.Node.Key, "/")+1:] == machineName { return &EtcdMachine{mac, ds, ds.keysAPI}, true } return nil, false }
// SetMac sets the provided interface's mac address. func SetMac(inter *net.Interface, addr net.HardwareAddr) error { log.Printf("Setting address %s", addr.String()) var errs []error if err := runCommand("ip", "link", "set", "dev", inter.Name, "down"); err != nil { errs = append(errs, err) } if err := runCommand("ip", "link", "set", "dev", inter.Name, "address", addr.String()); err != nil { errs = append(errs, err) } if err := runCommand("ip", "link", "set", "dev", inter.Name, "up"); err != nil { errs = append(errs, err) } if len(errs) > 0 { return errs[0] } return nil }
// CreateMachine Creates a machine, returns the handle, and writes directories and flags to etcd // Second return value determines whether or not Machine creation has been // successful // part of GeneralDataSource interface implementation func (ds *EtcdDataSource) CreateMachine(mac net.HardwareAddr, ip net.IP) (Machine, bool) { machines, err := ds.Machines() if err != nil { return nil, false } for _, node := range machines { if node.Mac().String() == mac.String() { return nil, false } nodeip, err := node.IP() if err != nil { return nil, false } if nodeip.String() == ip.String() { return nil, false } } machine := &EtcdMachine{mac, ds, ds.keysAPI} ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) defer cancel() ds.keysAPI.Set(ctx, ds.prefixify("machines/"+machine.Name()), "", &etcd.SetOptions{Dir: true}) ctx1, cancel1 := context.WithTimeout(context.Background(), 3*time.Second) defer cancel1() ds.keysAPI.Set(ctx1, ds.prefixify("machines/"+machine.Name()+"/_IP"), ip.String(), &etcd.SetOptions{}) ctx2, cancel2 := context.WithTimeout(context.Background(), 3*time.Second) defer cancel2() ds.keysAPI.Set(ctx2, ds.prefixify("machines/"+machine.Name()+"/_mac"), machine.Mac().String(), &etcd.SetOptions{}) ctx3, cancel3 := context.WithTimeout(context.Background(), 3*time.Second) defer cancel3() ds.keysAPI.Set(ctx3, ds.prefixify("machines/"+machine.Name()+"/_first_seen"), strconv.FormatInt(time.Now().UnixNano(), 10), &etcd.SetOptions{}) ctx4, cancel4 := context.WithTimeout(context.Background(), 3*time.Second) defer cancel4() ds.keysAPI.Set(ctx4, "skydns/"+ds.clusterName+"/"+machine.Name(), fmt.Sprintf(`{"host":"%s"}`, ip.String()), nil) machine.CheckIn() machine.SetFlag("state", "unknown") return machine, true }
func GetLocalIdentity(namespace string) (string, error) { interfaces, err := net.Interfaces() if err != nil { return "", err } var ha net.HardwareAddr for _, inter := range interfaces { //fmt.Println(inter.Name, inter.HardwareAddr) if len(inter.HardwareAddr) > 0 { //fmt.Println(inter.HardwareAddr) ha = inter.HardwareAddr //获取第一个 break } } identity := utils.NewShortUUID5(namespace, ha.String()) return identity, nil }
// Allocate a network interface func Allocate(job *engine.Job) engine.Status { var ( ip net.IP mac net.HardwareAddr err error id = job.Args[0] requestedIP = net.ParseIP(job.Getenv("RequestedIP")) ) if requestedIP != nil { ip, err = ipallocator.RequestIP(bridgeNetwork, requestedIP) } else { ip, err = ipallocator.RequestIP(bridgeNetwork, nil) } if err != nil { return job.Error(err) } // If no explicit mac address was given, generate a random one. if mac, err = net.ParseMAC(job.Getenv("RequestedMac")); err != nil { mac = generateMacAddr(ip) } out := engine.Env{} out.Set("IP", ip.String()) out.Set("Mask", bridgeNetwork.Mask.String()) out.Set("Gateway", bridgeNetwork.IP.String()) out.Set("MacAddress", mac.String()) out.Set("Bridge", bridgeIface) size, _ := bridgeNetwork.Mask.Size() out.SetInt("IPPrefixLen", size) currentInterfaces.Set(id, &networkInterface{ IP: ip, }) out.WriteTo(job.Stdout) return engine.StatusOK }
//TODO: make this into a goroutine and rectify the dedup rules periodically func (plugin *kubenetNetworkPlugin) syncEbtablesDedupRules(macAddr net.HardwareAddr) { if plugin.ebtables == nil { plugin.ebtables = utilebtables.New(plugin.execer) glog.V(3).Infof("Flushing dedup chain") if err := plugin.ebtables.FlushChain(utilebtables.TableFilter, dedupChain); err != nil { glog.Errorf("Failed to flush dedup chain: %v", err) } } _, err := plugin.ebtables.GetVersion() if err != nil { glog.Warningf("Failed to get ebtables version. Skip syncing ebtables dedup rules: %v", err) return } glog.V(3).Infof("Filtering packets with ebtables on mac address: %v, gateway: %v, pod CIDR: %v", macAddr.String(), plugin.gateway.String(), plugin.podCidr) _, err = plugin.ebtables.EnsureChain(utilebtables.TableFilter, dedupChain) if err != nil { glog.Errorf("Failed to ensure %v chain %v", utilebtables.TableFilter, dedupChain) return } _, err = plugin.ebtables.EnsureRule(utilebtables.Append, utilebtables.TableFilter, utilebtables.ChainOutput, "-j", string(dedupChain)) if err != nil { glog.Errorf("Failed to ensure %v chain %v jump to %v chain: %v", utilebtables.TableFilter, utilebtables.ChainOutput, dedupChain, err) return } commonArgs := []string{"-p", "IPv4", "-s", macAddr.String(), "-o", "veth+"} _, err = plugin.ebtables.EnsureRule(utilebtables.Prepend, utilebtables.TableFilter, dedupChain, append(commonArgs, "--ip-src", plugin.gateway.String(), "-j", "ACCEPT")...) if err != nil { glog.Errorf("Failed to ensure packets from cbr0 gateway to be accepted") return } _, err = plugin.ebtables.EnsureRule(utilebtables.Append, utilebtables.TableFilter, dedupChain, append(commonArgs, "--ip-src", plugin.podCidr, "-j", "DROP")...) if err != nil { glog.Errorf("Failed to ensure packets from podCidr but has mac address of cbr0 to get dropped.") return } }
func (*TestSuite) Test_Uint64ToHardwareAddr(c *C) { var hw, hwaddr net.HardwareAddr hw, err := net.ParseMAC("01:23:45:67:89:ab") c.Assert(err, IsNil) u64 := uint64(hw[0])<<55 | uint64(hw[1])<<47 | uint64(hw[2])<<39 | uint64(hw[3])<<31 | uint64(hw[4])<<23 | uint64(hw[5])<<15 hwaddr = lifxutil.Uint64ToHardwareAddr(u64) c.Check(hwaddr.String(), Equals, hw.String()) }
// SendTo sends a p2p packet by MAC address func (p *PeerToPeer) SendTo(dst net.HardwareAddr, msg *P2PMessage) (int, error) { // TODO: Speed up this by switching to map Log(Trace, "Requested Send to %s", dst.String()) id, exists := p.MACIDTable[dst.String()] if exists { p.PeersLock.Lock() peer, exists := p.NetworkPeers[id] p.PeersLock.Unlock() runtime.Gosched() if exists { msg.Header.ProxyID = uint16(peer.ProxyID) Log(Debug, "Sending to %s via proxy id %d", dst.String(), msg.Header.ProxyID) size, err := p.UDPSocket.SendMessage(msg, peer.Endpoint) return size, err } } return 0, nil }
func sendLostBuffers(dpid net.HardwareAddr, ipaddr net.IP, macaddr net.HardwareAddr, port uint16) { if _, found := lostBuffers[pair{dpid.String(), ipaddr.String()}]; !found { return } buffers := lostBuffers[pair{dpid.String(), ipaddr.String()}] for _, buffer := range buffers { msg := ofp10.NewPacketOut() msg.InPort = buffer.inport msg.BufferId = buffer.bufferId msg.Data = nil msg.AddAction(ofp10.NewActionDLDst(macaddr)) msg.AddAction(ofp10.NewActionOutput(port)) if sw, ok := ogo.Switch(dpid); ok { sw.Send(msg) } } delete(lostBuffers, pair{dpid.String(), ipaddr.String()}) }
// Allocate a network interface func Allocate(id, requestedMac, requestedIP, requestedIPv6 string) (*network.Settings, error) { var ( ip net.IP mac net.HardwareAddr err error globalIPv6 net.IP ) ip, err = ipAllocator.RequestIP(bridgeIPv4Network, net.ParseIP(requestedIP)) if err != nil { return nil, err } // If no explicit mac address was given, generate a random one. if mac, err = net.ParseMAC(requestedMac); err != nil { mac = generateMacAddr(ip) } if globalIPv6Network != nil { // If globalIPv6Network Size is at least a /80 subnet generate IPv6 address from MAC address netmaskOnes, _ := globalIPv6Network.Mask.Size() ipv6 := net.ParseIP(requestedIPv6) if ipv6 == nil && netmaskOnes <= 80 { ipv6 = make(net.IP, len(globalIPv6Network.IP)) copy(ipv6, globalIPv6Network.IP) for i, h := range mac { ipv6[i+10] = h } } globalIPv6, err = ipAllocator.RequestIP(globalIPv6Network, ipv6) if err != nil { logrus.Errorf("Allocator: RequestIP v6: %v", err) return nil, err } logrus.Infof("Allocated IPv6 %s", globalIPv6) } maskSize, _ := bridgeIPv4Network.Mask.Size() // If linklocal IPv6 localIPv6Net, err := linkLocalIPv6FromMac(mac.String()) if err != nil { return nil, err } localIPv6, _, _ := net.ParseCIDR(localIPv6Net) networkSettings := &network.Settings{ IPAddress: ip.String(), Gateway: bridgeIPv4Network.IP.String(), MacAddress: mac.String(), Bridge: bridgeIface, IPPrefixLen: maskSize, LinkLocalIPv6Address: localIPv6.String(), } if globalIPv6Network != nil { networkSettings.GlobalIPv6Address = globalIPv6.String() maskV6Size, _ := globalIPv6Network.Mask.Size() networkSettings.GlobalIPv6PrefixLen = maskV6Size networkSettings.IPv6Gateway = bridgeIPv6Addr.String() } currentInterfaces.Set(id, &networkInterface{ IP: ip, IPv6: globalIPv6, }) return networkSettings, nil }
// Returns a pointer to the Switch mapped to dpid. func Switch(dpid net.HardwareAddr) *OFSwitch { return switchDb[dpid.String()] }
// Handle openflow messages from the switch func (self *OFSwitch) handleMessages(dpid net.HardwareAddr, msg util.Message) { log.Debugf("Received message: %+v, on switch: %s", msg, dpid.String()) switch t := msg.(type) { case *common.Header: switch t.Header().Type { case openflow13.Type_Hello: // Send Hello response h, err := common.NewHello(4) if err != nil { log.Errorf("Error creating hello message") } self.Send(h) case openflow13.Type_EchoRequest: // Send echo reply res := openflow13.NewEchoReply() self.Send(res) case openflow13.Type_EchoReply: // FIXME: This is too fragile. Create a periodic timer // Wait three seconds then send an echo_request message. go func() { <-time.After(time.Second * 3) // Send echo request res := openflow13.NewEchoRequest() self.Send(res) }() case openflow13.Type_FeaturesRequest: case openflow13.Type_GetConfigRequest: case openflow13.Type_BarrierRequest: case openflow13.Type_BarrierReply: } case *openflow13.ErrorMsg: log.Errorf("Received ofp1.3 error msg: %+v", *t) self.stream.Shutdown <- true case *openflow13.VendorHeader: case *openflow13.SwitchFeatures: case *openflow13.SwitchConfig: switch t.Header.Type { case openflow13.Type_GetConfigReply: case openflow13.Type_SetConfig: } case *openflow13.PacketIn: log.Infof("Received packet(ofctrl): %+v", t) // send packet rcvd callback self.app.PacketRcvd(self, (*PacketIn)(t)) case *openflow13.FlowRemoved: case *openflow13.PortStatus: // FIXME: This needs to propagated to the app. case *openflow13.PacketOut: case *openflow13.FlowMod: case *openflow13.PortMod: case *openflow13.MultipartRequest: case *openflow13.MultipartReply: // FIXME: find a way to get multipart resp to app } }
func (p *PeerToPeer) handlePacketARP(contents []byte, proto int) { // Prepare new ethernet frame and fill it with // contents of the packet f := new(ethernet.Frame) if err := f.UnmarshalBinary(contents); err != nil { Log(Error, "Failed to Unmarshal ARP Binary") return } if f.EtherType != ethernet.EtherTypeARP { Log(Error, "Not ARP") return } packet := new(ARPPacket) if err := packet.UnmarshalARP(f.Payload); err != nil { Log(Error, "Failed to unmarshal arp") return } Log(Trace, "Peers: %v, Target IP: %s", p.NetworkPeers, packet.TargetIP.String()) var hwAddr net.HardwareAddr id, exists := p.IPIDTable[packet.TargetIP.String()] if !exists { Log(Debug, "Unknown IP requested") return } peer, exists := p.NetworkPeers[id] if !exists { Log(Debug, "Specified ID was not found in peer list") return } hwAddr = peer.PeerHW // TODO: Put there normal IP from list of ips // Send a reply if hwAddr == nil { Log(Error, "Cannot find hardware address for requested IP") _, hwAddr = GenerateMAC() peer.PeerHW = hwAddr p.NetworkPeers[id] = peer } if hwAddr.String() == "00:00:00:00:00:00" { _, hwAddr = GenerateMAC() peer.PeerHW = hwAddr p.NetworkPeers[id] = peer } var reply ARPPacket ip := net.ParseIP(packet.TargetIP.String()) response, err := reply.NewPacket(OperationReply, hwAddr, ip, packet.SenderHardwareAddr, packet.SenderIP) if err != nil { Log(Error, "Failed to create ARP reply") return } rp, err := response.MarshalBinary() if err != nil { Log(Error, "Failed to marshal ARP response packet") return } fr := ðernet.Frame{ Destination: response.TargetHardwareAddr, Source: response.SenderHardwareAddr, EtherType: ethernet.EtherTypeARP, Payload: rp, } fb, err := fr.MarshalBinary() if err != nil { Log(Error, "Failed to marshal ARP Ethernet Frame") } Log(Debug, "%v", packet.String()) p.WriteToDevice(fb, uint16(proto), false) }
// Allocate a network interface func Allocate(job *engine.Job) error { var ( ip net.IP mac net.HardwareAddr err error id = job.Args[0] requestedIP = net.ParseIP(job.Getenv("RequestedIP")) requestedIPv6 = net.ParseIP(job.Getenv("RequestedIPv6")) globalIPv6 net.IP ) ip, err = ipAllocator.RequestIP(bridgeIPv4Network, requestedIP) if err != nil { return err } // If no explicit mac address was given, generate a random one. if mac, err = net.ParseMAC(job.Getenv("RequestedMac")); err != nil { mac = generateMacAddr(ip) } if globalIPv6Network != nil { // If globalIPv6Network Size is at least a /80 subnet generate IPv6 address from MAC address netmask_ones, _ := globalIPv6Network.Mask.Size() if requestedIPv6 == nil && netmask_ones <= 80 { requestedIPv6 = make(net.IP, len(globalIPv6Network.IP)) copy(requestedIPv6, globalIPv6Network.IP) for i, h := range mac { requestedIPv6[i+10] = h } } globalIPv6, err = ipAllocator.RequestIP(globalIPv6Network, requestedIPv6) if err != nil { logrus.Errorf("Allocator: RequestIP v6: %v", err) return err } logrus.Infof("Allocated IPv6 %s", globalIPv6) } out := engine.Env{} out.Set("IP", ip.String()) out.Set("Mask", bridgeIPv4Network.Mask.String()) out.Set("Gateway", bridgeIPv4Network.IP.String()) out.Set("MacAddress", mac.String()) out.Set("Bridge", bridgeIface) size, _ := bridgeIPv4Network.Mask.Size() out.SetInt("IPPrefixLen", size) // If linklocal IPv6 localIPv6Net, err := linkLocalIPv6FromMac(mac.String()) if err != nil { return err } localIPv6, _, _ := net.ParseCIDR(localIPv6Net) out.Set("LinkLocalIPv6", localIPv6.String()) out.Set("MacAddress", mac.String()) if globalIPv6Network != nil { out.Set("GlobalIPv6", globalIPv6.String()) sizev6, _ := globalIPv6Network.Mask.Size() out.SetInt("GlobalIPv6PrefixLen", sizev6) out.Set("IPv6Gateway", bridgeIPv6Addr.String()) } currentInterfaces.Set(id, &networkInterface{ IP: ip, IPv6: globalIPv6, }) out.WriteTo(job.Stdout) return nil }
func (m *HostMap) Host(mac net.HardwareAddr) (h Host, ok bool) { m.RLock() defer m.RUnlock() h, ok = m.hosts[mac.String()] return }
func (m *HostMap) SetHost(mac net.HardwareAddr, port uint16) { m.Lock() defer m.Unlock() m.hosts[mac.String()] = Host{mac, port} }