Пример #1
0
        public void HandleLldpPacket(LLDPPacket packet, OfpPacketIn packetIn, IConnection connection)
        {
            if (packet.TlvCollection.Count < 3)
            {
                _controller.LogError($"[{connection.Mac}] LLDP TLV not enough");
                return;
            }
            ulong dpid = 0;
            var   ch   = packet.TlvCollection[0] as ChassisID;
            var   po   = packet.TlvCollection[1] as PortID;

            if (packet.TlvCollection.Count >= 4)
            {
                var sd = packet.TlvCollection[3] as SystemDescription;
                dpid = ulong.Parse(sd.Description, NumberStyles.AllowHexSpecifier);
            }
            if (dpid == 0)
            {
                dpid = ch.MACAddress.GetDatapathId();
            }
            ushort port = 0;

            if (po != null && po.SubTypeValue != null)
            {
                port = BitConverter.ToUInt16((byte[])po.SubTypeValue, 0);
            }
            _controller.LogDebug($"[{connection.Mac}:{packetIn.InPort}] is connected with [{ch?.MACAddress}:{port}] (Get LLDP)");

            //Update Topo
            _controller.Topo.AddTwoWayLink(dpid, port, connection.SwitchFeatures.DatapathId, packetIn.InPort);
        }
Пример #2
0
        public override bool PacketIn(OfpPacketIn packetIn, object packet, IConnection handler)
        {
            try
            {
                var p  = packet as Packet;
                var lp = TryLldpPacket(p);
                if (lp != null)
                {
                    HandleLldpPacket(lp, packetIn, handler);
                }
            }
            catch (Exception ex)
            {
            }

            return(false);
        }
Пример #3
0
        private void PacketIn(MemoryStream ms, OfpHeader header)
        {
            OfpPacketIn packetIn = new OfpPacketIn(ms, header);
            Packet      packet   = null;

            if (Math.Abs(packetIn.TotalLen - packetIn.Data.Length) <= 8)
            {
                try
                {
                    packet = Packet.ParsePacket(LinkLayers.Ethernet, packetIn.Data);
                }
                catch (Exception)
                {
                    packet = null;
                }
            }
            _controller.PluginSystem.PacketIn(packetIn, packet, this);
        }
Пример #4
0
 /// <summary>
 /// 处理包进入消息
 /// </summary>
 /// <param name="packetIn"></param>
 /// <param name="handler"></param>
 /// <returns></returns>
 public virtual bool PacketIn(OfpPacketIn packetIn, object packet, IConnection handler)
 {
     foreach (var plugin in Plugins.Values.Where(plugin => plugin.Active))
     {
         try
         {
             bool result = plugin.MessageHandler.PacketIn(packetIn, packet, handler);
             if (result)
             {
                 break;
             }
         }
         catch (Exception e)
         {
             Debug.WriteLine(e);
         }
     }
     return(true);
 }
Пример #5
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);
        }
Пример #6
0
 /// <summary>
 /// 处理包进入消息
 /// </summary>
 /// <param name="packetIn"></param>
 /// <param name="packet"></param>
 /// <param name="handler"></param>
 /// <returns></returns>
 public virtual bool PacketIn(OfpPacketIn packetIn, object packet, IConnection handler)
 {
     return(false);
 }