override public ForwardingDecision process_packet(int in_port, ref Packet packet) { #if DEBUG Console.Write("!"); Console.Write("{0}({1}/{2}) ", in_port, Interlocked.Increment(ref count), PaxConfig_Lite.no_interfaces); #endif int[] target_ports = ForwardingDecision.broadcast_raw(in_port); return(new ForwardingDecision.MultiPortForward(target_ports)); }
override public ForwardingDecision process_packet(int in_port, ref Packet packet) { int[] out_ports; if (packet is PacketDotNet.EthernetPacket) { EthernetPacket eth = ((PacketDotNet.EthernetPacket)packet); int lookup_out_port; // Forwarding decision. if (forwarding_table.TryGetValue(eth.DestinationHwAddress, out lookup_out_port)) { if (lookup_out_port == in_port) { var tmp = Console.ForegroundColor; Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Interface {0} was about to emit a frame it has just received.", PaxConfig.deviceMap[in_port].Name); Console.ForegroundColor = tmp; out_ports = new int[0]; } else { out_ports = new int[1] { lookup_out_port }; } } else { out_ports = ForwardingDecision.broadcast_raw(in_port); } // This might hold the value that's mapped to by eth.SourceHwAddress, // if one exists in our forwarding_table. int supposed_in_port; // Switch learns which port knows about the SourceHwAddress. if (forwarding_table.TryGetValue(eth.SourceHwAddress, out supposed_in_port)) { if (supposed_in_port != in_port) { if (!forwarding_table.TryUpdate(eth.SourceHwAddress, in_port, supposed_in_port)) { Console.WriteLine("Concurrent update of output port for " + eth.SourceHwAddress.ToString()); } #if DEBUG Debug.WriteLine("Relearned " + eth.SourceHwAddress.ToString() + " <- " + PaxConfig.deviceMap[in_port].Name); #endif } } else { if (!forwarding_table.TryUpdate(eth.SourceHwAddress, in_port, supposed_in_port)) { Console.WriteLine("Concurrent update of output port for " + eth.SourceHwAddress.ToString()); } #if DEBUG Debug.WriteLine("Learned " + eth.SourceHwAddress.ToString() + " <- " + PaxConfig.deviceMap[in_port].Name); #endif } // FIXME We don't have a "forgetting policy". We could periodically empty our forwarding_table. } else { // Drop if the packet's not an Ethernet frame. out_ports = new int[0]; } return(new ForwardingDecision.MultiPortForward(out_ports)); }