Пример #1
0
        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());
        }
Пример #2
0
        //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);
        }
Пример #3
0
        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);
        }