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); }
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); }
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); }
/// <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); }
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); }
/// <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); }