private void Flood(Packet packet, IConnection connection, uint bufferId = uint.MaxValue) { _controller.LogDebug($"[{connection.Mac}]Flood packet"); OfpPacketOut packetOut = new OfpPacketOut() { Data = packet.Bytes }; packetOut.Actions.Add(OfpActionType.OFPAT_OUTPUT, new OfpActionOutput() { Port = (ushort)OfpPort.OFPP_FLOOD }); connection.Write(packetOut.ToByteArray()); }
//private void Test() //{ // var b = GenerateLldpPacket(EthernetAddress.ETHER_ANY, 3389, 12345); //} public bool SendLldpPacket(IConnection connection, OfpPhyPort port) { if (OfpPhyPort.IsReservedPort(port.PortNo)) { return(false); } _controller.LogDebug($"[{connection.Mac}] Sending LLDP to Port:{port.PortNo} (PortMAC:{port.HwAddr.ToPhysicalAddress()})"); OfpPacketOut packetOut = new OfpPacketOut { Data = GenerateLldpPacket(port.HwAddr.ToPhysicalAddress(), port.PortNo, connection.SwitchFeatures.DatapathId) }; packetOut.Actions.Add(OfpActionType.OFPAT_OUTPUT, new OfpActionOutput() { Port = port.PortNo }); connection.Write(packetOut.ToByteArray()); return(true); }
public override bool PacketIn(OfpPacketIn packetIn, object packet, IConnection handler) { Packet p = packet as Packet; if (p == null) { return(false); } bool first = false; ARPPacket arp = p.Extract(typeof(ARPPacket)) as ARPPacket; if (arp != null) { if (!Equals(arp.SenderHardwareAddress, EthernetAddress.ETHER_ANY)) { var host = arp.SenderHardwareAddress.ToHostString(); if (!Equals(arp.SenderProtocolAddress, IPAddress.Any) && !Equals(arp.SenderProtocolAddress, IPAddress.Broadcast)) { if (_controller.Topo.Hosts.ContainsKey(host)) //更新host { _controller.Topo.Hosts[host].SetIpAddress(arp.SenderProtocolAddress); } else //添加host及link { var h = new Host(arp.SenderHardwareAddress); h.SetIpAddress(arp.SenderProtocolAddress); _controller.Topo.AddHost(h); _controller.Topo.AddHostLink(handler.SwitchFeatures.DatapathId, packetIn.InPort, h.MacAddress); first = true; } } } if (arp.Operation == ARPOperation.Request) { if (!arp.TargetProtocolAddress.IsAvailable()) { Flood(p, handler); return(false); } foreach (var host in _controller.Topo.Hosts.Values) { if (Equals(host.IpAddress, arp.TargetProtocolAddress) && host.HasIpAddress) //已知该主机信息,直接回复 TODO: ARP信息过期 { ARPPacket reply = new ARPPacket(ARPOperation.Response, arp.SenderHardwareAddress, arp.SenderProtocolAddress, host.MacAddress, host.IpAddress); EthernetPacket ep = new EthernetPacket(host.MacAddress, arp.SenderHardwareAddress, EthernetPacketType.Arp); ep.PayloadPacket = reply; OfpPacketOut packetOut = new OfpPacketOut() { Data = ep.Bytes }; packetOut.Actions.Add(OfpActionType.OFPAT_OUTPUT, new OfpActionOutput() { Port = packetIn.InPort }); handler.Write(packetOut.ToByteArray()); return(false); } } Flood(p, handler); return(false); } else if (arp.Operation == ARPOperation.Response) { HandleArpResponse(arp); //Send ARP back var dst = arp.TargetHardwareAddress.ToHostString(); if (!_controller.Topo.Hosts.ContainsKey(dst)) { return(false); } foreach (var key in _controller.Topo.Adjacency[dst].Keys) { if (_controller.Topo.Switches.ContainsKey(key)) { var link = _controller.Topo.Adjacency[key][dst]; _controller.LogDebug($"[{_controller.Topo.Switches[key].Connection.Mac}]send ARP back"); OfpPacketOut packetOut = new OfpPacketOut() { Data = p.Bytes }; packetOut.Actions.Add(OfpActionType.OFPAT_OUTPUT, new OfpActionOutput() { Port = link.SrcPort }); _controller.Topo.Switches[key].Connection.Write(packetOut.ToByteArray()); return(false); } } } } else { IPv4Packet ipPacket = p.Extract(typeof(IPv4Packet)) as IPv4Packet; if (ipPacket == null) { return(false); } PhysicalAddress srcMac = PhysicalAddress.None; foreach (var host in _controller.Topo.Hosts.Values) { if (Equals(host.IpAddress, ipPacket.SourceAddress)) { srcMac = host.MacAddress; break; } } if (Equals(srcMac, PhysicalAddress.None)) { return(false); } foreach (var host in _controller.Topo.Hosts.Values) { if (Equals(host.IpAddress, ipPacket.DestinationAddress)) { var dstMac = host.MacAddress; var dstIp = ipPacket.DestinationAddress; var srcIp = ipPacket.SourceAddress; var src = srcMac.ToHostString(); var dst = dstMac.ToHostString(); if (_controller.Topo.Hosts.ContainsKey(src) && _controller.Topo.Hosts.ContainsKey(dst)) { var path = _controller.Topo.FindShortestPath(src, dst); if (path.Count > 0) { path.Reverse(); for (int i = 0; i < path.Count - 1; i++) { string s = path[i]; if (s.StartsWith("s")) { //Apply FlowMod var sw = _controller.Topo.Switches[s]; if (sw != null) { var link = _controller.Topo.Adjacency[s][path[i + 1]]; if (link != null) { //Console.WriteLine("send IPv4 flowmod"); SendFlowMod(sw, link, srcMac, dstMac); //SendFlowMod(sw, link, srcIp, dstIp); } } } } } path = _controller.Topo.FindShortestPath(dst, src); if (path.Count > 0) { path.Reverse(); for (int i = 0; i < path.Count - 1; i++) { string s = path[i]; if (s.StartsWith("s")) { //Apply FlowMod var sw = _controller.Topo.Switches[s]; if (sw != null) { var link = _controller.Topo.Adjacency[s][path[i + 1]]; if (link != null) { //Console.WriteLine("send IPv4 flowmod"); SendFlowMod(sw, link, dstMac, srcMac); //SendFlowMod(sw, link, dstIp, srcIp); } } } } } } } } } return(false); }