// NOTE currently this is specific to the version of NetFPGA SUME we're using. override public ForwardingDecision process_packet(int in_port, ref Packet packet) { // Set metadata. NetFPGA_Data dataplane = instance.Get_Data(); NetFPGA.Set_Input_Port(ref dataplane, (ulong)in_port); Debug.Assert(in_port == (int)NetFPGA.Read_Input_Port(dataplane)); byte[] bs = packet.Bytes; NetFPGA.Set_Frame(bs, ref dataplane); instance.Set_Data(dataplane); // Run the logic! instance.SwitchLogic(); dataplane = instance.Get_Data(); // Retrieve frame. bs = new byte[NetFPGA_Data.BUF_SIZE * sizeof(ulong)]; NetFPGA.Get_Frame(dataplane, ref bs); // NOTE assuming Ethernet link layer. packet = Packet.ParsePacket(LinkLayers.Ethernet, bs); // Retrieve forwarding decision. int[] outs = new int[NetFPGA_Data.NET_PORTS]; int outputs = NetFPGA.Get_Output_Ports(ref dataplane, ref outs, max_ports: PaxConfig_Lite.no_interfaces); ForwardingDecision fwd = null; // Trim away unused array space. Array.Resize <int>(ref outs, outputs); fwd = new ForwardingDecision.MultiPortForward(outs); return(fwd); }
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)); }
public static ForwardingDecision[] InitialConfig(int size) { ForwardingDecision[] cfg = new ForwardingDecision[size]; for (int i = 0; i < cfg.Length; i++) { // The default configuration is for the mirror to do nothing. // This won't get in the way of chained elements transforming or forwarding the packet. cfg[i] = ForwardingDecision.Drop.Instance; } return(cfg); }
override public ForwardingDecision process_packet(int in_port, ref Packet packet) { /* NOTE disabled this since this processor doesn't look at packets, only at the in_port. * // Extract the bytes and call the instance of IAbstract_ByteProcessor * byte[] bs = packet.Bytes; */ /* FIXME ideally we should be able use a single implementation of the logic. * This is possible, but requires some in-progress development. * Specifically this conists of a phase that switches between * the high-level and lower-level encoding of in_port, packet, and forward. * Then we get two runtime options: * the Pax instance can use the Pax and Pax-Lite level logic (the latter * by using the en/decoding) * the Pax_Lite instance can only use the low-level encoding since the * types for the high-level encoding are not in its universe. * * process_packet (in_port); * TODO var forward = decode_forward(); * return forward; */ return(ForwardingDecision.broadcast(in_port)); }
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)); }