Esempio n. 1
0
    // This procedure calculates the checksum of a given byte stream
    // It returns the result in big endianess format
    // It doenst compute the 1's complement
    static public void calc_UDP_checksum(ulong data)
    {
        ulong tmp0 = 0x00, tmp1 = 0x00, tmp2 = 0x00, tmp3 = 0x00, sum0 = 0, sum1 = 0, sum = 0, chk = 0;

        chk = chksum_UDP;
        // The ICMP header & payload start from this packet number
        if (true)
        {
            // extract every 16-bit from the stream for addition and reorder it to big endianess
            tmp0 = ((ulong)(data >> 0) & (ulong)0x00ff) << 8 | ((ulong)(data >> 0) & (ulong)0x00ff00) >> 8;
            tmp1 = ((ulong)(data >> 16) & (ulong)0x00ff) << 8 | ((ulong)(data >> 16) & (ulong)0x00ff00) >> 8;
            tmp2 = ((ulong)(data >> 32) & (ulong)0x00ff) << 8 | ((ulong)(data >> 32) & (ulong)0x00ff00) >> 8;
            tmp3 = ((ulong)(data >> 48) & (ulong)0x00ff) << 8 | ((ulong)(data >> 48) & (ulong)0x00ff00) >> 8;
            // check for carry and add it if its needed
            sum0 = (ulong)((tmp0 + tmp1) & (ulong)0x00ffff) + (ulong)((tmp0 + tmp1) >> 16);
            sum1 = (ulong)((tmp2 + tmp3) & (ulong)0x00ffff) + (ulong)((tmp2 + tmp3) >> 16);
            Kiwi.Pause();
            // check for carry and add it if its needed
            sum = (ulong)((sum0 + sum1) & (ulong)0x00ffff) + (ulong)((sum0 + sum1) >> 16);
            // add the current sum to the previous sums
            chksum_UDP = (ulong)((sum + chk) & (ulong)0x00ffff) + (ulong)((sum + chk) >> 16);
        }
    }
Esempio n. 2
0
    // This method describes the operations required to tx a frame over the AXI4-Stream.
    static void SendFrame(uint pkt_size)
    {
        // #############################
        // # Transmit the frame
        // #############################
        m_axis_tvalid    = true;
        m_axis_tlast     = false;
        m_axis_tdata     = (ulong)tdata[0];
        m_axis_tkeep     = (byte)tkeep[0];
        m_axis_tuser_hi  = (ulong)0x0;
        m_axis_tuser_low = (ulong)tuser_low[0];
        uint i = 1U;

        Kiwi.Pause();

        while (i <= pkt_size)
        {
            if (m_axis_tready)
            {
                m_axis_tdata     = tdata[i];
                m_axis_tkeep     = (i == pkt_size) ? tkeep[pkt_size] : (byte)0xff;
                m_axis_tlast     = i == pkt_size;
                m_axis_tuser_hi  = 0UL;
                m_axis_tuser_low = 0UL;
                i++;
            }
            Kiwi.Pause();
        }

        m_axis_tvalid    = false;
        m_axis_tlast     = false;
        m_axis_tdata     = (ulong)0x0;
        m_axis_tkeep     = (byte)0x0;
        m_axis_tuser_hi  = (ulong)0x0;
        m_axis_tuser_low = (ulong)0x0;
        Kiwi.Pause();
    }
        /*
         * Function: SendOne
         * Description: Send a single segment of the buffered ethernet frame.
         */
        public static uint SendOne(CircularFrameBuffer cfb, bool stop = true, bool movepeek = false,
                                   bool checkready = true)
        {
            if (cfb.CanPop(movepeek) && (!checkready || Emu.m_axis_tready))
            {
                Emu.Status = 11;
                SetData(cfb, movepeek, true);

                var done = cfb.PopData.Tlast;
                Emu.Status = 3;

                Kiwi.Pause();

                if (stop)
                {
                    Reset();
                }

                if (done)
                {
                    Emu.PktOut++;
                    Emu.Status = 12;
                    return(2U);
                }
                Emu.Status = 13;
                return(0U);
            }

            Emu.Status = 14;

            if (stop)
            {
                Reset();
            }

            return(3U);
        }
Esempio n. 4
0
    // This method describes the operations required to route the frames
    static public void switch_logic()
    {
        metadata = 0UL;
        src_mac  = 0UL;
        dst_mac  = 0UL;
        LUT_hit  = false;

        while (true)
        {
            ReceiveFrameSegm();

            // #############################
            // # Switch Logic -- START
            // #############################

            broadcast_ports = ((metadata & (ulong)0x00FF0000) ^ DEFAULT_oqs) << (byte)8;

            CAM_check_n_learn(dst_mac, src_mac << 16);
            Kiwi.Pause();
            tuser_low = LUT_hit ? (ulong)(OQ << 24 | metadata) : (ulong)(broadcast_ports | metadata);

            //#############################
            // # Switch Logic -- END
            // #############################

            // Send out this frame and the rest
            SendFrame();

            // End of frame, ready for next frame
            LUT_hit  = false;
            metadata = 0UL;
            src_mac  = 0UL;
            dst_mac  = 0UL;
            LUT_hit  = false;
            OQ       = 0UL;
        }
    }
Esempio n. 5
0
    // This method describes the operations required to tx a frame over the AXI4-Stream.
    static void SendFrame(uint psize)
    {
        // #############################
        // # Transmit the frame
        // #############################
        m_axis_tvalid    = true;
        m_axis_tlast     = false;
        m_axis_tdata     = (ulong)0x0;
        m_axis_tkeep     = (byte)0x0;
        m_axis_tuser_hi  = (ulong)0x0;
        m_axis_tuser_low = (ulong)0x0;

        uint i = 0U;


        while (i <= psize)
        {
            if (m_axis_tready)
            {
                m_axis_tdata     = tdata[i];
                m_axis_tkeep     = tkeep[i];
                m_axis_tlast     = i == (psize);
                m_axis_tuser_hi  = tuser_hi[i];
                m_axis_tuser_low = tuser_low[i];
                i = i + 1U;
            }
            Kiwi.Pause();
        }

        m_axis_tvalid    = false;
        m_axis_tlast     = false;
        m_axis_tdata     = (ulong)0x0;
        m_axis_tkeep     = (byte)0x0;
        m_axis_tuser_hi  = (ulong)0x0;
        m_axis_tuser_low = (ulong)0x0;
        Kiwi.Pause();
    }
Esempio n. 6
0
        // This method describes the operations required to tx a frame over the AXI4-Stream.
        protected static void SendFrame(uint fm_size)
        {
            m_axis_tvalid    = true;
            m_axis_tlast     = false;
            m_axis_tdata     = (ulong)0x0;
            m_axis_tkeep     = (byte)0x0;
            m_axis_tuser_hi  = (ulong)0x0;
            m_axis_tuser_low = (ulong)0x0;

            uint i = 0;

            while (i <= fm_size)
            {
                if (m_axis_tready)
                {
                    m_axis_tdata = dataplane.tdata[i];
                    m_axis_tkeep = dataplane.tkeep[i];
                    // -- BUG DONT USE
                    //m_axis_tlast    = (i==fm_size) ? true : false;
                    //if (i==fm_size) m_axis_tlast = true;
                    m_axis_tlast     = i == (fm_size);
                    m_axis_tuser_hi  = dataplane.tuser_hi[i];
                    m_axis_tuser_low = dataplane.tuser_low[i];
                    i++;
                }
                Kiwi.Pause();
            }

            m_axis_tvalid    = false;
            m_axis_tlast     = false;
            m_axis_tdata     = (ulong)0x0;
            m_axis_tkeep     = (byte)0x0;
            m_axis_tuser_hi  = (ulong)0x0;
            m_axis_tuser_low = (ulong)0x0;
            Kiwi.Pause();
        }
Esempio n. 7
0
        // This method describes the operations required to rx a frame over the AXI4-Stream.
        // and extract basic information such as dst_MAC, src_MAC, dst_port, src_port
        public void ReceiveFrame()
        {
            s_axis_tready = true;

            // The start condition
            uint cnt         = 0U;
            bool doneReading = true;

            // #############################
            // # Receive the frame
            // #############################
            //Kiwi.Pause();

            while (doneReading)
            {
                if (s_axis_tvalid)
                {
                    packet_size = (uint)(s_axis_tuser_low & (ulong)0x00ffff);

                    new_pkt_arrived = cnt == 0U;
                    // Condition to stop receiving data
                    doneReading = !s_axis_tlast && s_axis_tvalid;
                    cnt         = s_axis_tlast ? 0 : cnt + 1U;
                    // Create backpresure to whatever sends data to us
                    //s_axis_tready = s_axis_tlast ? false : true;
                }
                else
                {
                    new_pkt_arrived = false;
                }

                Kiwi.Pause();
            }
            new_pkt_arrived = false;
            //s_axis_tready	= false;
        }
Esempio n. 8
0
        public bool recvOne(bool check_updated = true)
        {
            if ((!check_updated || !s_updated) && Emu.axi_s_axis_tvalid)
            {
                s_updated             = true;
                Emu.axi_s_axis_tready = true;
                axi_s_axis_tdata_0    = Emu.axi_s_axis_tdata_0;
                axi_s_axis_tdata_1    = Emu.axi_s_axis_tdata_1;
                axi_s_axis_tdata_2    = Emu.axi_s_axis_tdata_2;
                axi_s_axis_tdata_3    = Emu.axi_s_axis_tdata_3;
                axi_s_axis_tstrb      = Emu.axi_s_axis_tstrb;
                axi_s_axis_tkeep      = Emu.axi_s_axis_tkeep;
                axi_s_axis_tlast      = Emu.axi_s_axis_tlast;
                axi_s_axis_tid        = Emu.axi_s_axis_tid;
                axi_s_axis_tdest      = Emu.axi_s_axis_tdest;
                axi_s_axis_tuser_0    = Emu.axi_s_axis_tuser_0;
                axi_s_axis_tuser_1    = Emu.axi_s_axis_tuser_1;
                Kiwi.Pause();
                Emu.axi_s_axis_tready = false;
                return(true);
            }

            return(false);
        }
Esempio n. 9
0
    static void Main()
    {
        HashCAM.Read(10);
        HashCAM.Read(10);
        HashCAM.Write(10, 7);
        HashCAM.Read(10);
        HashCAM.Write(10, 7);
        HashCAM.Read(10);
        HashCAM.Write(10, 7);
        HashCAM.Read(10);

        HashCAM.Write(10, 8);
        HashCAM.Read(10);
        HashCAM.Write(10, 7);

        HashCAM.Read(11);
        HashCAM.Write(12, 9);

        for (int i = 0; i < 300; i++)
        {
            HashCAM.Write((ulong)i, 1);
            Kiwi.Pause();
        }
    }
Esempio n. 10
0
        // This procedure perform swap of multiple fields
        // dst_mac<->src_mac, dst_ip<->src_ip, dst_port<->src_port
        static void swap_multiple_fields(bool tcp_udp, bool icmp)
        {
            ulong tmp;
            bool  tcp_udp_tmp, icmp_tmp;

            tcp_udp_tmp = tcp_udp;
            icmp_tmp    = icmp;
            // Ethernet header swap
            tdata[0] = src_mac | (dst_mac << 48);
            Kiwi.Pause();
            tmp = (tdata[1] & (ulong)0xffffffff00000000) | dst_mac >> 16;
            Kiwi.Pause();
            tdata[1] = tmp;
            Kiwi.Pause();

            // IP header swap + UDP header swap
            tmp = (tdata[3] & (ulong)0x00ffff) | dst_ip << 16 | src_ip << 48;
            // tmp = dst_ip<<16 | src_ip<<48;
            Kiwi.Pause();
            tdata[3] = tmp;
            Kiwi.Pause();
            if (tcp_udp_tmp)
            {
                // Swap the ports, Memcached - TCP ping
                tmp = (tdata[4] & (ulong)0xffff000000000000) | src_ip >> 16 | app_src_port << 32 | app_dst_port << 16;
            }
            else if (icmp_tmp)
            {
                // Set the ICMP echo reply type=0, code=0 and checksum=0x00
                tmp = (tdata[4] & (ulong)0xffff000000000000) | src_ip >> 16;
            }
            Kiwi.Pause();

            tdata[4] = tmp;
            Kiwi.Pause();
        }
Esempio n. 11
0
    public static ulong Write(ulong key_in, ulong value_in)
    {
        ulong result = 0;

        while (write_ready)
        {
            Kiwi.Pause();
        }
        HashCAM.key_in   = key_in;
        HashCAM.value_in = value_in;
        write_enable     = true;
        Kiwi.Pause();
        while (!write_ready)
        {
            Kiwi.Pause();
        }
        Kiwi.Pause();
        matched      = match;
        result       = value_out;
        is_full      = full;
        write_enable = false;
        Kiwi.Pause();
        return(result);
    }
Esempio n. 12
0
    static int EntryPoint()
    {
        // Create and start the thread for receiving and parsing the tuple
        RX     rx   = new RX();
        Thread rxTh = new Thread(new ThreadStart(rx.start_rx));

        rxTh.Start();

        TIMER  timer   = new TIMER();
        Thread timerTh = new Thread(new ThreadStart(timer.start_timer));

        timerTh.Start();

        TABLES tables = new TABLES();

        tables.reset_tables();
        Thread bw_tmpTh = new Thread(new ThreadStart(tables.update_bw_tmp));

        bw_tmpTh.Start();
        Thread tablesTh = new Thread(new ThreadStart(tables.update_tables));

        tablesTh.Start();

        while (true)
        {
            if (rst | clear)
            {
                timer.reset_timer();
                tables.reset_raw_entry();
                tables.reset_bw_tmp();
                tables.reset_total_entries();
            }
            Kiwi.Pause();
        }
        return(0);
    }
Esempio n. 13
0
    // This procedure perform basic control operation for the CAM
    static uint cam_controller(byte mode)
    {
        uint tmp_addr = 0x00;

        // Poll until CAM is ready
        while (cam_busy)
        {
            Kiwi.Pause();
        }

        //addr = mem_controller_cnt;
        //tmp_key = key;

        //if(mem_controller_cnt == (uint)(MEM_SIZE-1U)) mem_controller_cnt = 0;

        switch (mode)
        {               // WRITE operation - returns the address in which the key is stored
        case SET:       // 0x01
            // Check if the key exists in the CAM
            cam_cmp_din = key;
            Kiwi.Pause();
            cam_cmp_din = key;
            Kiwi.Pause();
            // Perform the store operation
            cam_din     = key;
            cam_wr_addr = (cam_match) ? (byte)cam_match_addr : (byte)mem_controller_cnt;
            tmp_addr    = (cam_match) ? (byte)cam_match_addr : (byte)mem_controller_cnt;
            Kiwi.Pause();

            cam_we = true;
            Kiwi.Pause();
            cam_we = false;
            Kiwi.Pause();

            break;

        // READ operation - return the address if we have a match otherwhise MEM_SIZE
        case GET:                 // 0x00
            cam_cmp_din = key;
            Kiwi.Pause();
            cam_cmp_din = key;
            Kiwi.Pause();

            tmp_addr = (cam_match) ? (uint)cam_match_addr : (uint)MEM_SIZE;

            break;

        // DELETE operation - return the address if we have a match otherwhise MEM_SIZE
        case DELETE:                 // 0x04
            cam_cmp_din = key;
            Kiwi.Pause();
            cam_cmp_din = key;
            Kiwi.Pause();
            if (cam_match)
            {
                tmp_addr = (uint)cam_match_addr;
            }
            else
            {
                tmp_addr = (uint)MEM_SIZE;
            }

            Kiwi.Pause();
            if (cam_match)
            {
                Kiwi.Pause();
                cam_din     = (ulong)0x00;
                cam_wr_addr = (byte)tmp_addr;
                Kiwi.Pause();
                cam_we = true;
                Kiwi.Pause();
                cam_we = false;
                Kiwi.Pause();
            }
            break;

        default: break;
        }

        if (mem_controller_cnt == (uint)(MEM_SIZE - 1U))
        {
            mem_controller_cnt = 0;
        }
        else
        {
            mem_controller_cnt += 1U;
        }

        return(tmp_addr);
    }
Esempio n. 14
0
    // This procedure creates the DELETE response packet
    static public uint Memcached_DELETE(bool err)
    {
        ulong tmp = 0x00, tmp2 = 0x00;

        // DELETE - Fixed size of key(6B)
        if (!err)
        {
            tmp = ((ulong)(ulong)((IP_total_length >> 8) | (IP_total_length << 8 & (ulong)0x00ff00)) - (ulong)6) & (ulong)0x00ffff;
        }
        else            // add length of textual error code (8B)
        {
            tmp = ((ulong)(ulong)((IP_total_length >> 8) | (IP_total_length << 8 & (ulong)0x00ff00)) + (ulong)2) & (ulong)0x00ffff;
        }

        tmp2 = tdata[2] & (ulong)0xffffffffffff0000;
        Kiwi.Pause();
        tdata[2] = tmp2 | (tmp >> 8) | (tmp << 8 & (ulong)0x00ff00);
        Kiwi.Pause();

        // Set the checksum to 0x00, calculate later
        tmp = tdata[3] & (ulong)0xffffffffffff0000;
        Kiwi.Pause();
        tdata[3] = tmp;

        // DELETE - Fixed size of key(6B)
        if (!err)
        {
            tmp = ((ulong)(ulong)((UDP_total_length >> 8) | (UDP_total_length << 8 & (ulong)0x00ff00)) - (ulong)6);
        }
        else
        {
            tmp = ((ulong)(ulong)((UDP_total_length >> 8) | (UDP_total_length << 8 & (ulong)0x00ff00)) + (ulong)2);
        }

        tmp2 = tdata[4] & (ulong)0x0000ffffffffffff;
        Kiwi.Pause();
        tdata[4] = tmp2 | ((tmp & (ulong)0xff00) << 40) | (tmp << 56);
        Kiwi.Pause();

        // Reset the UDP checksum
        tmp = tdata[5];
        Kiwi.Pause();
        tdata[5] = tmp & ~(ulong)0x00ffff;
        Kiwi.Pause();

        tmp = tdata[6] & (ulong)0x00ffff;
        Kiwi.Pause();
        //set DELETE magic number + opcode
        tdata[6] = (ulong)DELETE << 24 | (ulong)RESPONSE << 16 | tmp;
        Kiwi.Pause();

        // Set the status code = key not found IPv4
        // and the opaque - DELETE response
        if (err)
        {
            tmp = (tdata[7] & 0xffff000000000000) | (ulong)0x0000080000000100;
        }
        else
        {
            tmp = (tdata[7] & 0xffff000000000000);
        }
        Kiwi.Pause();

        tdata[7] = tmp;
        Kiwi.Pause();

        // Fill up the rest of the response packet
        if (!err)
        {
            tmp = tdata[8] & 0x000000000000ffff;
            Kiwi.Pause();
            tdata[8] = tmp;
            Kiwi.Pause();

            tdata[9] = (ulong)0x00;
            // Set the correct metadata for the datapath
            // Fixed size response packet for  DELETE success
            tuser_low[0] = (src_port << 24) | (src_port << 16) | (ulong)74;
            tkeep[9]     = (byte)0x03;
            //pkt_size = 8;
            return(9U);
        }
        else
        {
            tmp = (tdata[8] & 0x000000000000ffff);
            Kiwi.Pause();
            tdata[8] = tmp;
            Kiwi.Pause();

            tdata[9] = ERROR_MSG << 16;
            Kiwi.Pause();
            tdata[10] = ERROR_MSG >> 48;
            // Set the correct metadata for the datapath
            // Fixed size response packet for DELETE failure
            tuser_low[0] = (src_port << 24) | (src_port << 16) | (ulong)82;
            tkeep[10]    = (byte)0x03;
            //pkt_size = 9;
            return(10U);
        }
    }
Esempio n. 15
0
    // This procedure creates the GET response packet
    static public uint Memcached_GET(bool err)
    {
        ulong tmp = 0x00, tmp2 = 0x00;

        // Set the correct IP packet length (little endianess)
        // GET - Fixed size of extras(4B)[only flag] + key(6B) + value(8B)
        if (!err)
        {
            tmp = ((ulong)(ulong)((IP_total_length >> 8) | (IP_total_length << 8 & (ulong)0x00ff00)) + (ulong)6) & (ulong)0x00ffff;
        }
        else
        {
            // in case of an error we must adjust the length accordinlgy
            // add length of textual error code (8B)
            tmp = ((ulong)(ulong)((IP_total_length >> 8) | (IP_total_length << 8 & (ulong)0x00ff00)) + (ulong)2) & (ulong)0x00ffff;
        }

        tmp2 = tdata[2] & (ulong)0xffffffffffff0000;
        Kiwi.Pause();
        tdata[2] = tmp2 | (tmp >> 8) | (tmp << 8 & (ulong)0x00ff00);
        Kiwi.Pause();

        // Set the checksum to 0x00, calculate later
        tmp = tdata[3] & (ulong)0xffffffffffff0000;
        Kiwi.Pause();
        tdata[3] = tmp;
        // Set the correct UDP packet length (little endianess)
        // GET - Fixed size of extras(4B)[only flag] + key(6B) + value(8B)
        // in case of an error we must adjust the length accordinlgy
        if (!err)
        {
            tmp = ((ulong)(ulong)((UDP_total_length >> 8) | (UDP_total_length << 8 & (ulong)0x00ff00)) + (ulong)6);
        }
        else
        {
            tmp = ((ulong)(ulong)((UDP_total_length >> 8) | (UDP_total_length << 8 & (ulong)0x00ff00)) + (ulong)2);
        }
        tmp2 = tdata[4] & (ulong)0x0000ffffffffffff;
        Kiwi.Pause();
        tdata[4] = tmp2 | ((tmp & (ulong)0xff00) << 40) | (tmp << 56);
        Kiwi.Pause();

        // Reset the UDP checksum
        tmp = tdata[5];
        Kiwi.Pause();
        tdata[5] = tmp & ~(ulong)0x00ffff;
        Kiwi.Pause();

        tmp = tdata[6] & (ulong)0x00ffff;
        Kiwi.Pause();

        // set GET magic number + opcode
        // set also the extras length(4b)
        if (!err)
        {
            tdata[6] = ((ulong)GET << 24 | (ulong)RESPONSE << 16 | ((ulong)0x0004) << 48) | tmp;
        }
        else
        {
            tdata[6] = ((ulong)GET << 24 | (ulong)RESPONSE << 16) | tmp;
        }
        Kiwi.Pause();
        // Set the opaque
        // Set the status code = key not found
        // and the opaque - GET response
        if (err)
        {
            // total length is fixed (error msg(8B) = 0x14)
            tmp = (tdata[7] & 0xffff000000000000) | (ulong)0x0000080000000100;
        }
        else            // total length is fixed (flag(4B)+key_value(8B)= 0x0c)
        {
            tmp = (tdata[7] & 0xffff000000000000) | (ulong)0x00000c0000000000;
        }

        Kiwi.Pause();
        tdata[7] = tmp;
        Kiwi.Pause();

        // Fill up the rest of the response packet
        if (err)
        {
            tmp = (tdata[8] & 0x000000000000ffff);
            Kiwi.Pause();
            tdata[8] = tmp;
            Kiwi.Pause();

            tdata[9] = ERROR_MSG << 16;
            Kiwi.Pause();
            tdata[10] = ERROR_MSG >> 48;

            // Set the correct metadata for the datapath
            // Fixed size response packet for GET/DELETE failure
            tuser_low[0] = (src_port << 24) | (src_port << 16) | (ulong)82;
            tkeep[10]    = (byte)0x03;
            //pkt_size = 9;
        }
        else
        {
            tdata[9] = (((ulong)flag >> 16) & (ulong)0x00ffffffff0000) | (ulong)key_value << 48;
            Kiwi.Pause();
            tdata[10]    = (ulong)key_value >> 16;        //&(ulong)0x00ffffffffffff;
            tuser_low[0] = (src_port << 24) | (src_port << 16) | (ulong)86;
            tkeep[10]    = (byte)0x3f;

            //pkt_size = 9;
        }
        return(10U);
    }
Esempio n. 16
0
        // This method describes the operations required to rx a frame over the AXI4-Stream.
        // and extract basic information such as dst_MAC, src_MAC, dst_port, src_port
        static public uint ReceiveFrame()
        {
            m_axis_tdata     = (ulong)0x0;
            m_axis_tkeep     = (byte)0x0;
            m_axis_tlast     = false;
            m_axis_tvalid    = false;
            m_axis_tuser_hi  = (ulong)0x0;
            m_axis_tuser_low = (ulong)0x0;
            s_axis_tready    = true;

            segm_num    = 0U;
            icmp_header = false;
            //num = (uint)0x01;
            Kiwi.Pause();

            // The start condition
            uint  cnt         = 0;
            uint  psize       = 0;
            bool  start       = s_axis_tvalid && s_axis_tready;
            bool  doneReading = true;
            bool  receive     = s_axis_tvalid;
            ulong data        = 0x00;
            byte  data2       = 0x00;

            // #############################
            // # Receive the frame
            // #############################
            cnt = 0;

            doneReading = true;

            while (doneReading)
            {
                if (s_axis_tvalid)
                {
                    //Extract_data(segm_num++) <-- BUG
                    //Extract_data(cnt+1);
                    //Extract_data();
//				shared_tdata	= s_axis_tdata;
//				shared_tuser	= s_axis_tuser_low;
//
//				if(cnt==4U) calc_UDP_checksum(s_axis_tdata >> 16);
//				if(cnt>4U) calc_UDP_checksum(s_axis_tdata);

                    tdata[cnt]     = s_axis_tdata;
                    tkeep[cnt]     = s_axis_tkeep;
                    tlast[cnt]     = s_axis_tlast;
                    tuser_hi[cnt]  = s_axis_tuser_hi;
                    tuser_low[cnt] = s_axis_tuser_low;

                    segm_num   += 1U;
                    psize       = cnt++;
                    doneReading = !s_axis_tlast && s_axis_tvalid;

                    // Create backpresure to whatever sends data to us
                    s_axis_tready = s_axis_tlast ? false : true;
                }
                //else icmp_header=false;
                Kiwi.Pause();
            }
            icmp_header = false;

            data  = tdata[psize];
            data2 = tkeep[psize];

            Kiwi.Pause();

/*
 *              if(data2==0x01){	tdata[psize] = data & (ulong)0x00ff; Kiwi.Pause();}
 *              else if(data2==0x03){	tdata[psize] = data & (ulong)0x00ffff; Kiwi.Pause();}
 *              else if(data2==0x07){	tdata[psize] = data & (ulong)0x00ffffff; Kiwi.Pause();}
 *              else if(data2==0x0f){	tdata[psize] = data & (ulong)0x00ffffffff; Kiwi.Pause();}
 *              else if(data2==0x1f){	tdata[psize] = data & (ulong)0x00ffffffffff; Kiwi.Pause();}
 *              else if(data2==0x3f){	tdata[psize] = data & (ulong)0x00ffffffffffff; Kiwi.Pause();}
 *              else if(data2==0x7f){	tdata[psize] = data & (ulong)0x00ffffffffffffff; Kiwi.Pause();}
 *              else{;}
 */
            switch (data2)
            {
            case 0x01:
                tdata[psize] = data & (ulong)0x00ff;
                break;

            case 0x03:
                tdata[psize] = data & (ulong)0x00ffff;
                break;

            case 0x07:
                tdata[psize] = data & (ulong)0x00ffffff;
                break;

            case 0x0f:
                tdata[psize] = data & (ulong)0x00ffffffff;
                break;

            case 0x1f:
                tdata[psize] = data & (ulong)0x00ffffffffff;
                break;

            case 0x3f:
                tdata[psize] = data & (ulong)0x00ffffffffffff;
                break;

            case 0x7f:
                tdata[psize] = data & (ulong)0x00ffffffffffffff;
                break;

            default:
                break;
            }

            Kiwi.Pause();

            s_axis_tready = false;
            cnt           = 0;
            segm_num      = 0;
            //last = false;
            //start = false;
            return(psize);
        }
Esempio n. 17
0
    // This method describes the operations required to route the frames
    static public void switch_logic()
    {
        uint i = 0U, ptr = 0U, free = 0U, cnt = 0U;
        uint pkt_size = 0U;
        bool exist = false, doneReading;

        IP       = false;
        metadata = 0UL;
        src_mac  = 0UL;
        dst_mac  = 0UL;
        LUT_hit  = false;

        while (true) // Process packets indefinately
        {
            // Procedure call for receiving the first frame of the packet

            m_axis_tdata_0 = (ulong)0x0;
            m_axis_tdata_1 = (ulong)0x0;
            m_axis_tdata_2 = (ulong)0x0;
            m_axis_tdata_3 = (ulong)0x0;

            m_axis_tkeep     = (uint)0x0;
            m_axis_tlast     = false;
            m_axis_tuser_hi  = (ulong)0x0;
            m_axis_tuser_low = (ulong)0x0;
            s_axis_tready    = true;
            cnt = 0U;
            Kiwi.Pause();

            doneReading = true;

            while (doneReading)
            {
                if (s_axis_tvalid)
                {
                    tdata_0[cnt] = s_axis_tdata_0;
                    tdata_1[cnt] = s_axis_tdata_1;
                    tdata_2[cnt] = s_axis_tdata_2;
                    tdata_3[cnt] = s_axis_tdata_3;

                    tkeep[cnt]     = s_axis_tkeep;
                    tlast[cnt]     = s_axis_tlast;
                    tuser_hi[cnt]  = s_axis_tuser_hi;
                    tuser_low[cnt] = s_axis_tuser_low;

                    if (cnt == 0U)
                    {
                        metadata = s_axis_tuser_low;
                        dst_mac  = s_axis_tdata_0 << (byte)16;
                        src_mac  = ((s_axis_tdata_0 >> (byte)48) & (ulong)0x00ffff) | (s_axis_tdata_1 & (ulong)0x00ffffffff) << (byte)16;

                        s_axis_tready = false;
                        doneReading   = false;
                        break;
                    }

                    cnt++;
                }
                Kiwi.Pause();
            }

            // #############################
            // # Switch Logic -- START
            // #############################
            tmp = 0UL; tmp1 = 0UL; tmp2 = 0UL; tmp0 = 0UL; ptr = 0U;

            broadcast_ports = ((metadata & (ulong)0x00FF0000) ^ DEFAULT_oqs) << (byte)8;

            // Search the LUT for the dst_mac and for the src_mac
            for (i = 0U; (uint)i < (uint)LUT_SIZE; i = i + 1U)
            {
                tmp1 = LUT[i];
                Kiwi.Pause();
                // Get the mac address from LUT
                tmp = tmp1 & (ulong)0xffffffffffff0000;
                // Get the output port from LUT
                tmp2 = tmp1 & (ulong)0x00000000000000ff;

                // Check if we have a hit in the LUT for the dst_mac
                if (dst_mac == tmp)
                {
                    // Get the engress port numnber from the LUT
                    OQ      = tmp2 << 24;
                    LUT_hit = true;
                    //break;
                }
                // Here we check if we need to update an entry based on the src_mac
                // Get rid off the oq, keep only the mac
                if (src_mac == tmp >> (byte)16)
                {
                    // Update if needed
                    // tmp0	= tmp | (metadata & (ulong)0x00ff0000)>>(byte)16;
                    exist = true;
                    ptr   = i;
                    //break;
                }
                // Save some cycles (maybe)
                if (LUT_hit && exist)
                {
                    break;
                }
            }

            // If we have a LUT hit prepare the appropriate output port in the metadata, otherwise flood
            tuser_low[0] = LUT_hit ? (ulong)(OQ | metadata) : (ulong)(broadcast_ports | metadata);
            // Update entry
            if (exist)
            {
                LUT[ptr] = src_mac << (byte)16 | (ulong)((metadata >> (byte)16) & (ulong)0x00ff);
            }
            Kiwi.Pause();
            // Create entry
            if (!LUT_hit)
            {
                LUT[ptr] = src_mac << (byte)16 | (ulong)((metadata >> (byte)16) & (ulong)0x00ff);
                free     = (free > (uint)(LUT_SIZE - 1U)) ? 0U : free = free + 1U;
            }
            // #############################
            // # Switch Logic -- END
            // #############################

            // Send out this frame and the rest
            SendFrame(0);

            // End of frame, ready for next frame
            IP       = false;
            metadata = 0UL;
            src_mac  = 0UL;
            dst_mac  = 0UL;
            LUT_hit  = false;
            OQ       = 0UL;
            exist    = false;
        }
    }
Esempio n. 18
0
    // This procedure creates the GET response packet
    static public uint Memcached_GET(bool err)
    {
        ulong tmp = 0x00, tmp2 = 0x00;

        // Set the correct IP packet length (little endianess)
        // GET - Fixed size
        // Error - size 41B
        // !Error - size 71B
        tmp  = (err) ? (ulong)0x002900 : (ulong)0x004700;
        tmp2 = tdata[2] & (ulong)0xffffffffffff0000;
        Kiwi.Pause();
        tdata[2] = tmp2 | tmp;
        Kiwi.Pause();

        // Set the checksum to 0x00, calculate later
        tmp = tdata[3] & (ulong)0xffffffffffff0000;
        Kiwi.Pause();
        tdata[3] = tmp;
        Kiwi.Pause();
        // Set the correct UDP packet length (little endianess)
        // GET - Fixed size
        // in case of an error we must adjust the length accordinlgy
        // Error - size 21B - 0x15
        // !Error - size 51B - 0x33
        tmp  = (err) ? (ulong)0x1500000000000000 : (ulong)0x3300000000000000;
        tmp2 = tdata[4] & (ulong)0x0000ffffffffffff;
        Kiwi.Pause();
        tdata[4] = tmp2 | tmp;
        Kiwi.Pause();

        // Reset the UDP checksum
        tmp = tdata[5];
        Kiwi.Pause();
        tdata[5] = tmp & ~(ulong)0x00ffff;
        Kiwi.Pause();

        // Set the response
        // VALUE <key> <flags> <bytes>\r\n
        // <data block>\r\n
        // END\r\n
        tmp = tdata[6] & (ulong)0x00ffff;
        Kiwi.Pause();

        // set GET magic number + opcode
        // set also the extras length(4b)
        if (!err)
        {
            tdata[6] = tmp | (ulong)0x2045554c41560000;             // VALUE
            Kiwi.Pause();
            tdata[7] = key;                                         // <key>
            Kiwi.Pause();
            tdata[8] = (ulong)0x00000a0d38203020 | key_value << 48; // <flags> + <bytes> + <data_block>
            Kiwi.Pause();
            tdata[9] = key_value >> 16 | (ulong)0x0a0d000000000000; // <data block>\r\n
            Kiwi.Pause();
            tdata[10] = (ulong)0x000a0d444e45;
        }
        else
        {
            tdata[6] = tmp | (ulong)0x000a0d444e450000;             // END\r\n
        }
        Kiwi.Pause();

        // Fill up the rest of the response packet
        if (!err)
        {
            // Set the correct metadata for the datapath
            // Fixed size response packet for GET/DELETE failure
            tuser_low[0] = (dst_port << 24) | (src_port << 16) | (ulong)85;
            tkeep[10]    = (byte)0x1f;
            return(10);
        }
        else
        {
            tuser_low[0] = (dst_port << 24) | (src_port << 16) | (ulong)55;
            tkeep[6]     = (byte)0x7f;
            return(6);
        }
    }
Esempio n. 19
0
    // This procedure perform basic control operation for the CAM
    static uint cam_controller(byte mode)
    {
        uint tmp_addr = 0x00;

        // Poll until CAM is ready
        while (cam_busy)
        {
            Kiwi.Pause();
        }

        switch (mode)
        {               // WRITE operation - returns the address in which the key is stored
        case SET:       // 0x01
            // Check if the key exists in the CAM
            cam_cmp_din = key;
            Kiwi.Pause();
            cam_cmp_din = key;
            Kiwi.Pause();
            // Perform the store operation
            // If exist, uoate the entry, otherwise store
            if (!cam_match)
            {
                Kiwi.Pause();
                cam_din     = key;
                cam_wr_addr = (byte)mem_controller_cnt;
                Kiwi.Pause();
                cam_we = true;
                Kiwi.Pause();
                cam_we = false;
                Kiwi.Pause();
            }

            tmp_addr = (cam_match) ? (byte)cam_match_addr : (byte)mem_controller_cnt;
            // Increase the counter if we done have any match
            if (!cam_match)
            {
                mem_controller_cnt += 1U;
            }

            break;

        // READ operation - return the address if we have a match otherwhise MEM_SIZE
        case GET:                 // 0x02
            cam_cmp_din = key;
            Kiwi.Pause();
            cam_cmp_din = key;
            Kiwi.Pause();

            tmp_addr = (cam_match) ? (uint)cam_match_addr : (uint)MEM_SIZE;

            break;

        // DELETE operation - return the address if we have a match otherwhise MEM_SIZE
        case DELETE:                 // 0x03
            cam_cmp_din = key;
            Kiwi.Pause();
            cam_cmp_din = key;
            Kiwi.Pause();
            tmp_addr = (cam_match) ? (uint)cam_match_addr : (uint)MEM_SIZE;
            Kiwi.Pause();
            if (cam_match)
            {
                Kiwi.Pause();
                cam_din     = (ulong)0x00;
                cam_wr_addr = (byte)tmp_addr;
                Kiwi.Pause();
                cam_we = true;
                Kiwi.Pause();
                cam_we = false;
                Kiwi.Pause();
            }
            break;

        default: break;
        }

        if (mem_controller_cnt == (uint)(MEM_SIZE - 1U))
        {
            mem_controller_cnt = 0;                                                  // else mem_controller_cnt += 1U;
        }
        return(tmp_addr);
    }
Esempio n. 20
0
    // This method describes the operations required to rx a frame over the AXI4-Stream.
    // and extract basic information such as dst_MAC, src_MAC, dst_port, src_port
    static public uint ReceiveFrame()
    {
        m_axis_tdata     = (ulong)0x0;
        m_axis_tkeep     = (byte)0x0;
        m_axis_tlast     = false;
        m_axis_tvalid    = false;
        m_axis_tuser_hi  = (ulong)0x0;
        m_axis_tuser_low = (ulong)0x0;
        s_axis_tready    = true;

        segm_num    = 0U;
        icmp_header = false;
        Kiwi.Pause();

        // The start condition
        uint  cnt         = 0;
        uint  psize       = 0;
        bool  start       = s_axis_tvalid && s_axis_tready;
        bool  doneReading = true;
        bool  receive     = s_axis_tvalid;
        ulong data        = 0x00;
        byte  data2       = 0x00;

        // #############################
        // # Receive the frame
        // #############################
        cnt         = 0;
        doneReading = true;

        while (doneReading)
        {
            if (s_axis_tvalid)
            {
                tdata[cnt] = s_axis_tdata;
                tkeep[cnt] = s_axis_tkeep;
                tlast[cnt] = s_axis_tlast;
                //tuser_hi[cnt]     = s_axis_tuser_hi;
                tuser_low[cnt] = s_axis_tuser_low;

                segm_num   += 1U;
                psize       = cnt++;
                doneReading = !s_axis_tlast && s_axis_tvalid;

                // Create backpresure to whatever sends data to us
                s_axis_tready = s_axis_tlast ? false : true;
            }
            Kiwi.Pause();
        }
        icmp_header = false;

        data  = tdata[psize];
        data2 = tkeep[psize];

        Kiwi.Pause();

        switch (data2)
        {
        case 0x01:
            tdata[psize] = data & (ulong)0x00ff;
            break;

        case 0x03:
            tdata[psize] = data & (ulong)0x00ffff;
            break;

        case 0x07:
            tdata[psize] = data & (ulong)0x00ffffff;
            break;

        case 0x0f:
            tdata[psize] = data & (ulong)0x00ffffffff;
            break;

        case 0x1f:
            tdata[psize] = data & (ulong)0x00ffffffffff;
            break;

        case 0x3f:
            tdata[psize] = data & (ulong)0x00ffffffffffff;
            break;

        case 0x7f:
            tdata[psize] = data & (ulong)0x00ffffffffffffff;
            break;

        default:
            break;
        }

        Kiwi.Pause();

        s_axis_tready = false;
        cnt           = 0;
        segm_num      = 0;
        return(psize);
    }
Esempio n. 21
0
    public static void Main()
    {
        bool kpp = true;

        elimit = limit;
        Kiwi.KppMark("START", "INITIALISE"); // Waypoint
        Console.WriteLine("Primes Up To " + limit);
        Kiwi.Pause();
        PA[0] = vol > 0; // Process some runtime input data on this thread - prevents Kiwic running the whole program at compile time.
        Kiwi.Pause();
        // Clear array

        count1 = 2; count = 0; // RESET VALUE FAILED AT ONE POINT: HENCE NEED THIS LINE
        for (int woz = 0; woz < limit; woz++)
        {
            Kiwi.Pause();
            PA[woz] = true;
            Console.WriteLine("Setting initial array flag to hold : addr={0} readback={1}", woz, PA[woz]); // Read back and print.
        }

        Kiwi.KppMark("wp2", "CROSSOFF"); // Waypoint
        int i, j;

        for (i = 2; i < limit; i++) // Can our predictor cope with the standard optimisations?
        {
            Kiwi.Pause();
            // Cross off the multiples - optimise by skipping where the base is already crossed off.
            if (evariant_master > 0)
            {
                bool pp = PA[i];
                Console.WriteLine(" tnow={2}: scaning up for live factor {0} = {1} ", i, pp, Kiwi.tnow);
                if (!pp)
                {
                    continue;
                }
                count1 += 1;
            }
            // Can further optimise by commencing the cross-off at the factor squared.
            j = (evariant_master > 1) ? i * i : i + i;
            if (j >= limit)
            {
                Console.WriteLine("Skip out on square");
                break;
            }
            for (; j < limit; j += i)
            {
                Console.WriteLine("Cross off {0} {1}   (count1={2})", i, j, count1);
                Kiwi.Pause(); PA[j] = false;
            }
        }
        Kiwi.KppMark("wp3", "COUNTING"); // Waypoint
        Console.WriteLine("Now counting");
        // Count how many there were and store them consecutively in the output array.
        for (int w = 0; w < limit; w++)
        {
            Kiwi.Pause();
            if (PA[w])
            {
                count += 1;
                if (false)
                {
//	             PY[count] = (uint)w;
//               PZ1[count] = w;
//		     PZ2[count] = w;
                }
            }
            Console.WriteLine("Tally counting {0} {1}", w, count);
            //Console.WriteLine("Tally counting {0} {1} at {2}", w, count, Kiwi.tnow);
        }


        Console.WriteLine("There are {0} primes below the natural number {1}.", count, limit);
        Console.WriteLine("Optimisation variant={1} (count1 is {0}).", count1, evariant_master);
        Kiwi.Pause();
        Kiwi.Pause();
        Kiwi.KppMark("FINISH"); // Waypoint
        Kiwi.Pause();
        finished = true;
        Kiwi.Pause();
    }
Esempio n. 22
0
 void Start()
 {
     m_dynamiteAdapterObj = m_dynamiteAdapterObj.GetComponent<DynamiteAdapter>();
      m_kiwiObj = m_kiwiObj.GetComponent<Kiwi>();
      m_banaobj = m_kiwiObj.GetComponent<Banana>();
      m_pumpkin = m_kiwiObj.GetComponent<Pumpkin>();
 }
Esempio n. 23
0
    // This method describes the operations required to tx a frame over the AXI4-Stream.
    static void SendFrame(uint psize)
    {
        // #############################
        // # Transmit the frame
        // #############################
        m_axis_tvalid = false;
        s_axis_tready = false;

        uint i = 0U, ttkeep; bool done = false, valid = false, ttlast;

        ulong a = 0UL, ttdata_0, ttdata_1, ttdata_2, ttdata_3, ttuser_hi, ttuser_low; byte b = 0; bool c = false;

        // transmit the first frame that we have already read
        do
        {
            m_axis_tdata_0 = tdata_0[0];
            m_axis_tdata_1 = tdata_1[0];
            m_axis_tdata_2 = tdata_2[0];
            m_axis_tdata_3 = tdata_3[0];

            m_axis_tkeep     = tkeep[0];
            m_axis_tlast     = tlast[0];
            m_axis_tuser_hi  = 0U;
            m_axis_tuser_low = tuser_low[0];

            m_axis_tvalid = true;

            Kiwi.Pause();
        }while(!m_axis_tready);

        m_axis_tvalid = false;

        s_axis_tready = true;

        // Continue with the rest of the frames, as a cut through
        do
        {
            if (m_axis_tready && s_axis_tvalid)
            {
                m_axis_tdata_0 = s_axis_tdata_0;
                m_axis_tdata_1 = s_axis_tdata_1;
                m_axis_tdata_2 = s_axis_tdata_2;
                m_axis_tdata_3 = s_axis_tdata_3;

                m_axis_tkeep     = s_axis_tkeep;
                m_axis_tlast     = s_axis_tlast;
                m_axis_tuser_hi  = 0U;
                m_axis_tuser_low = 0U;

                m_axis_tvalid = true;

                s_axis_tready = true;

                done = s_axis_tlast && s_axis_tvalid;
            }
            else
            {
                s_axis_tready = false;
                m_axis_tvalid = false;
            }

            Kiwi.Pause();
            m_axis_tvalid = false;
            s_axis_tready = false;
            Kiwi.Pause();
        }while(!done);


        s_axis_tready = false;

        m_axis_tvalid    = false;
        m_axis_tlast     = false;
        m_axis_tdata_0   = (ulong)0x0;
        m_axis_tdata_1   = (ulong)0x0;
        m_axis_tdata_2   = (ulong)0x0;
        m_axis_tdata_3   = (ulong)0x0;
        m_axis_tkeep     = (uint)0x0;
        m_axis_tuser_hi  = (ulong)0x0;
        m_axis_tuser_low = (ulong)0x0;
        Kiwi.Pause();
    }
Esempio n. 24
0
    // This method describes the main logic functionality of the Server
    static public void memcached_logic()
    {
        ulong d, u;
        uint  i = 0U;
        byte  local_command_type = 0;

        uint pkt_size = 0U;
        bool is_ipv4 = false, is_udp = false, is_icmp = false;
        uint addr = 0U;
        bool good_IP_checksum = false, error = false;

        while (true)         // Process packets indefinately
        {
            // Store the packet into the buffer
            pkt_size = ReceiveFrame();
            Kiwi.Pause();

            // Extract information from the Ethernet, IP, TCP, UDP frames
            // Currently this information is located in the buffer entries 0-9
            for (i = 0; i <= pkt_size; i++)
            {
                d = tdata[i];
                u = tuser_low[i];
                Kiwi.Pause();
                Extract_headers(i, d, u);
                Kiwi.Pause();
            }

            // We need to store the shared-threat variables here
            // otherwise if we use it explicity we get long compilation times
            is_ipv4            = IPv4;
            is_udp             = proto_UDP;
            is_icmp            = false;
            local_command_type = command_type;

            Kiwi.Pause();
            // #############################
            // # Server Logic -- START
            // #############################

            // #######################################################################################
            // #                MEMCACHED SERVER
            if (is_ipv4 && is_udp)      //&& (local_command_type!=0x00) )
            {
                // Calculate the IP checksum
                chksum_IP        = calc_IP_checksum();
                good_IP_checksum = (chksum_IP == (ulong)0x00);
                Kiwi.Pause();

                if (local_command_type != NONE && good_IP_checksum)
                {
                    // Give to the controller the command to perform an action
                    addr  = cam_controller(local_command_type);
                    error = addr == (uint)MEM_SIZE;
                    Kiwi.Pause();

                    if (!error)
                    {
                        // Store/get the value in/from the RAM
                        switch (local_command_type)
                        {
                        case SET:
                            VALUES_MEM[addr] = key_value;
                            break;

                        case GET:
                            key_value = VALUES_MEM[addr];
                            break;

                        case DELETE:
                            VALUES_MEM[addr] = 0UL;
                            break;

                        default:
                            break;
                        }
                    }
                    Kiwi.Pause();

                    chksum_UDP = (ulong)0x00;
                    chksum_IP  = 0x00;
                    // Swap the fields in the Ethernet frame
                    swap_multiple_fields(is_udp, is_icmp);
                    Kiwi.Pause();
                    // Create the response packet + reset appropriate fields(ex. UDP checksum)
                    switch (local_command_type)
                    {
                    case SET:       pkt_size = Memcached_SET();             break;

                    case GET:       pkt_size = Memcached_GET(error);        break;

                    case DELETE:       pkt_size = Memcached_DELETE(error);     break;

                    default:                                               break;
                    }
                    Kiwi.Pause();

                    tmp = tdata[3];
                    Kiwi.Pause();

                    chksum_IP = calc_IP_checksum();
                    Kiwi.Pause();
                    // Set the new IP checksum - as we dont change any info in the IP header,
                    // the checksum should remane the same - but anyway recalc and put it back
                    tdata[3] = (chksum_IP >> 8 | (chksum_IP & (ulong)0x00ff) << 8) | tmp;
                    Kiwi.Pause();

                    // Here is the UDP checksum - clear it and preserve the other data
                    tmp = tdata[5];             //we have already clear the UDP checksum
                    Kiwi.Pause();
                    // The 4th element in the buffer is the start of the UDP frame
                    for (i = 4; i <= pkt_size; i++)
                    {
                        tmp2 = (i != 4) ? tdata[i] : tdata[i] >> 16;
                        Kiwi.Pause();
                        calc_UDP_checksum(tmp2);
                    }
                    // Here is the new UDP length + proto type
                    tmp3 = (tdata[4] & (ulong)0xffff000000000000) | (ulong)0x001100;
                    // (optimization) src, dst IPs - pseudo header
                    tmp2 = src_ip << 32 | dst_ip;
                    Kiwi.Pause();
                    // (optimization) 11U = 0x11 = UDP proto_type , UDP length - pseudo header
                    calc_UDP_checksum(tmp3);
                    Kiwi.Pause();
                    calc_UDP_checksum(tmp2);
                    Kiwi.Pause();
                    // 1's complement of the result
                    tmp2 = (ulong)((chksum_UDP ^ ~(ulong)0x00) & (ulong)0x00ffff);
                    Kiwi.Pause();
                    // make it back to little endian
                    tmp3 = (ulong)((tmp2 >> 8) | (ulong)(tmp2 & (ulong)0x00ff) << 8);
                    // Set the new UDP checksum
                    tdata[5] = tmp | tmp3;
                }
            }
            //#
            //###########################################################################################

            //#############################
            //# Server Logic -- END
            //#############################

            // Procedure to send out the packet
            if (pkt_size != 0U)
            {
                SendFrame(pkt_size);
            }

            // End of frame, ready for next frame
            command_type = NONE;
            IPv4         = false;
            proto_UDP    = false;
            chksum_UDP   = 0x00;
            pkt_size     = 0x00;
            error        = false;
        }
    }
Esempio n. 25
0
        // This method describes the main logic functionality of the Server
        static public void switch_logic()
        {
            ulong local_icmp_code_type, local_chksum_udp, d, u;//, ipv4;
            uint  i = 0, pointer = 0;
            byte  ii = 0, local_magic_num = 0, local_opcode = 0;

            uint  pkt_size = 0, p_size = 0;
            bool  is_ipv4 = false, is_udp = false, is_icmp = false;
            uint  cam_addr = 0, tmp_addr = 0, addr = 0;
            bool  good_IP_checksum = false, error = false;
            ulong local_key_value, local_extras, local_flag;

            while (true) // Process packets indefinately
            {
                pkt_size = ReceiveFrame();

                // Extract information from the Ethernet, IP, TCP, UDP frames
                for (i = 0; i <= pkt_size; i++)
                {
                    d = tdata[i];
                    u = tuser_low[i];
                    Kiwi.Pause();
                    Extract_headers(i, d, u);
                }


                Kiwi.Pause();
                // We need to store the shared-threat variables here
                // otherwise if we use it explicity we get long compilation times
                is_ipv4 = IPv4;
                is_udp  = proto_UDP;
                is_icmp = proto_ICMP;
//		local_magic_num     = magic_num;
//		local_opcode		= opcode;
//		local_icmp_code_type    = ICMP_code_type;
                local_chksum_udp = chksum_UDP;
//		local_key_value		= key_value;
//		local_extras		= extras;
//		local_flag		= flag;


                Kiwi.Pause();
                // #############################
                // # Server Logic -- START
                // #############################

                // #######################################################################################
                // #                DNS SERVER
                if (is_ipv4 && is_udp)
                {
                    chksumIP         = calc_IP_checksum();
                    good_IP_checksum = (chksumIP == (ulong)0x00);
                    //Kiwi.Pause();

                    // We have already validate part of the UDP checksum while we were receiving the packet
                    // now we need also to add the IP pseudo header + UDP length + prototype(UDP=0x0011)
//			tmp = (ulong)(src_ip<<32 | dst_ip);
//			tmp2= (ulong)0x001100 | UDP_total_length<<32;
//			Kiwi.Pause();
//			calc_UDP_checksum(tmp2); // (optimization) 11U = 0x11 = UDP proto_type , UDP length
//			Kiwi.Pause();
//			calc_UDP_checksum(tmp); // (optimization) src, dst IPs
//			local_chksum_udp = ((tdata[5]&(ulong)0x00ffff)==0x00) ? (ulong)0x00ffff : chksum_UDP; // Check if the UDP checksum is disabled
//			Kiwi.Pause();

                    if (good_IP_checksum && one_question && std_query)
                    {
                        chksum_UDP = (ulong)0x00;
                        chksumIP   = 0x00;
                        exist_rest = false;
                        swap_multiple_fields(is_udp, is_icmp);
                        Kiwi.Pause();


                        // Fisrt pattern of the IP name
                        tmp = tdata[7];
                        Kiwi.Pause();

                        pointer = MEM_SIZE;
                        for (i = 0; i < MEM_SIZE; i++)
                        {
                            // lookup the first pattern of the IP name
                            tmp1 = DNS_part_0[i];
                            tmp2 = DNS_part_1[i];
                            tmp3 = DNS_part_2[i];
                            // Second part of the IP name
                            tmp4 = tdata[8];
                            Kiwi.Pause();
                            if (tmp == tmp1)
                            {
                                if (pkt_size == 9U)
                                {
                                    // Third  pattern of the IP name
                                    tmp5 = tdata[9];
                                    Kiwi.Pause();
                                    exist_rest = ((tmp4 == tmp2) && (tmp5 == tmp3));
                                }
                                else
                                {
                                    exist_rest = (tmp4 == tmp2);
                                }
                                pointer = i;
                                break;
                            }
                        }

                        // Extract the size of the packet from the tuser_low
                        p_size = (uint)(tuser_low[0] & (ulong)0x00ffff);

                        // Preserve the transaction ID and the number of questions and flags, reset the UDP checksum
                        tmp = tdata[5] & ~(ulong)0x00ffff;
                        Kiwi.Pause();
                        // Set the response bit in the flag field
                        tdata[5] = tmp | (ulong)0x008000000000;
                        Kiwi.Pause();


                        // Set the response packet with the IP address
                        if (start_parsing && exist_rest)
                        {
                            // Set the number of response answers field
                            tmp = tdata[6] & ~(ulong)0x00ffff;
                            Kiwi.Pause();
                            tdata[6] = tmp | (ulong)0x000100;            // set the number of answers to 1

                            // Build the answer that we need to append to the end of the packet
                            // Currrenlty the answer is:
                            //	1. pointer(2B) + type(2B) + class(2B) + part of TTL(2B)
                            //	2. part of TTL(2B) + length(2B) + IP(4B)
                            tmp1 = (ulong)0x0000010001000cc0;
                            tmp2 = (ulong)IPs[pointer] << 32 | (ulong)0x000400100e;
                            Kiwi.Pause();

                            if (last_tkeep == 0x00)
                            {
                                tdata[pkt_size + 1U] = tmp1; Kiwi.Pause();
                                tdata[pkt_size + 2U] = tmp2; tkeep[pkt_size + 1U] = (byte)0xff; Kiwi.Pause();

                                tkeep[pkt_size + 2U] = (byte)0xff;
                            }
                            else
                            {
                                tmp3 = tdata[pkt_size] | tmp1 << (last_tkeep * 0x08); tkeep[pkt_size] = 0xff;
                                Kiwi.Pause();
                                tdata[pkt_size] = tmp3;
                                Kiwi.Pause();

                                tdata[pkt_size + 1U] = tmp1 >> (((byte)0x08 - last_tkeep) * 0x08) | tmp2 << ((last_tkeep) * 0x08);
                                tkeep[pkt_size + 1U] = 0xff;
                                Kiwi.Pause();

                                tdata[pkt_size + 2U] = tmp2 >> (((byte)0x08 - last_tkeep) * 0x08);
                                tkeep[pkt_size + 2U] = (byte)(0xff >> ((byte)0x08 - last_tkeep));
                                Kiwi.Pause();
                            }

                            // Calculate the new IP length
                            tmp  = IP_total_length >> 8 | (IP_total_length & (ulong)0x00ff) << 8;
                            tmp2 = tdata[2] & ~(ulong)0x00ffff;             // Reset the IP length
                            Kiwi.Pause();
                            IP_total_length = tmp + 16U;
                            tdata[2]        = tmp2 | (IP_total_length >> 8 | (IP_total_length & (ulong)0x00ff) << 8);

                            // Calculate the new UDP length
                            tmp  = UDP_total_length >> 8 | (UDP_total_length & (ulong)0x00ff) << 8;
                            tmp2 = tdata[4] & (ulong)0x0000ffffffffffff;             // Reset the UDP length
                            Kiwi.Pause();
                            UDP_total_length = tmp + 16U;
                            tdata[4]         = tmp2 | (UDP_total_length >> 8 | (UDP_total_length & (ulong)0x00ff) << 8) << 48;


                            // Set the output port with the new packet size
                            tuser_low[0] = (src_port << 24) | (src_port << 16) | p_size + 16U;

                            pkt_size += 2U;
                        }
                        // Set the response packet with an error message
                        else
                        {               // Set the error code = 0x03 "no such name" , and the response flag
                            tdata[5] = tmp | (ulong)0x00038000000000;
                            tmp5     = tuser_low[0];
                            Kiwi.Pause();
                            // Set the output port
                            tuser_low[0] = (src_port << 24) | tmp5;
                        }



                        // Calculate the new IP checksum
                        tmp = tdata[3] & ~(ulong)0x00ffff;
                        Kiwi.Pause();
                        tdata[3] = tmp;
                        Kiwi.Pause();
                        chksumIP = calc_IP_checksum();
                        Kiwi.Pause();
                        tdata[3] = (chksumIP >> 8 | (chksumIP & (ulong)0x00ff) << 8) | tmp;
                        Kiwi.Pause();

                        // Here is the UDP checksum - clear it and preserve the other data
                        tmp = tdata[5];         //we have already clear the UDP checksum
                        Kiwi.Pause();
                        // The 4th element in the buffer is the start of the UDP frame
                        for (i = 4; i <= pkt_size; i++)
                        {
                            tmp2 = (i != 4) ? tdata[i] : tdata[i] >> 16;
                            Kiwi.Pause();
                            calc_UDP_checksum(tmp2);
                        }
                        tmp3 = (tdata[4] & (ulong)0xffff000000000000) | (ulong)0x001100; // Here is the new UDP length + proto type
                        tmp2 = src_ip << 32 | dst_ip;                                    // (optimization) src, dst IPs
                        Kiwi.Pause();
                        calc_UDP_checksum(tmp3);                                         // (optimization) 11U = 0x11 = UDP proto_type , UDP length
                        Kiwi.Pause();
                        calc_UDP_checksum(tmp2);
                        Kiwi.Pause();
                        // 1's complement of the result
                        tmp2 = (ulong)((chksum_UDP ^ ~(ulong)0x00) & (ulong)0x00ffff);
                        Kiwi.Pause();
                        // make it back to little endian
                        tmp3 = (ulong)((tmp2 >> 8) | (ulong)(tmp2 & (ulong)0x00ff) << 8);
                        // Set the new UDP checksum
                        tdata[5] = tmp | tmp3;
                    }
                }
                // #
                // ###########################################################################################


                Kiwi.Pause();
                // #
                // ###########################################################################################


                // #############################
                // # Server Logic -- END
                // #############################

                // Procedure calchksum_ICMPl for transmiting packet
                SendFrame(pkt_size);

                //End of frame, ready for next frame
                one_question  = false;
                std_query     = false;
                start_parsing = false;
                IPv4          = false;
                proto_UDP     = false;
                proto_ICMP    = false;
                chksum_UDP    = 0x00;
                pkt_size      = 0x00;
                exist_rest    = false;
            }
        }
Esempio n. 26
0
    // This procedure creates the DELETE response packet
    static public uint Memcached_DELETE(bool err)
    {
        ulong tmp = 0x00, tmp2 = 0x00;

        // DELETE - Fixed size total IP length
        tmp  = (!err) ? (ulong)0x002d00 : (ulong)0x002f00;
        tmp2 = tdata[2] & (ulong)0xffffffffffff0000;
        Kiwi.Pause();
        tdata[2] = tmp2 | tmp;
        Kiwi.Pause();

        // Set the checksum to 0x00, calculate later
        tmp = tdata[3] & (ulong)0xffffffffffff0000;
        Kiwi.Pause();
        tdata[3] = tmp;

        // DELETE - Fixed size UDP length ( IP_length - 20B)
        tmp  = (!err) ? (ulong)0x1900000000000000 : (ulong)0x1b00000000000000;
        tmp2 = tdata[4] & (ulong)0x0000ffffffffffff;
        Kiwi.Pause();
        tdata[4] = tmp2 | tmp;
        Kiwi.Pause();

        // Reset the UDP checksum
        tmp = tdata[5];
        Kiwi.Pause();
        tdata[5] = tmp & ~(ulong)0x00ffff;
        Kiwi.Pause();


        // Fill up the rest of the response packet
        if (!err)
        {
            tmp = tdata[6] & 0x000000000000ffff;
            Kiwi.Pause();
            tdata[6] = (ulong)0x4554454c45440000;             // DELETE
            Kiwi.Pause();

            tdata[7] = (ulong)0x000a0d44;               // D\r\n
            Kiwi.Pause();
            // Set the correct metadata for the datapath
            // Fixed size response packet for  DELETE success
            tuser_low[0] = (src_port << 24) | (src_port << 16) | (ulong)59;
            tkeep[7]     = (byte)0x07;
            //pkt_size = 8;
            return(7U);
        }
        else
        {
            tmp = tdata[6] & 0x000000000000ffff;
            Kiwi.Pause();
            tdata[6] = (ulong)0x4f465f544f4e0000;             // NOT_FO
            Kiwi.Pause();

            tdata[7] = (ulong)0x000a0d444e55;                   // UND\r\n
            Kiwi.Pause();
            // Set the correct metadata for the datapath
            // Fixed size response packet for  DELETE success
            tuser_low[0] = (dst_port << 24) | (src_port << 16) | (ulong)61;
            tkeep[7]     = (byte)0x1f;
            return(7U);
        }
    }
Esempio n. 27
0
        // This procedure performs the basic control operation for the CAM.
        protected static uint CAM_Control(Memory_Operation mode, ulong key)
        {
            uint  tmp_addr = 0x00, addr = 0x00;
            ulong tmp_key;
            //tmp_addr=0x00;
            bool busy = true;

            // 1 cycle read latency, 16 cycles write latency
            // mode=true , WRITE operation
            //Kiwi.Pause();
            // Poll until CAM is ready
            while (cam_busy)
            {
                Kiwi.Pause();
            }

            //addr = mem_controller_cnt;
            //tmp_key = key;

            //if(mem_controller_cnt == (uint)(MEM_SIZE-1U)) mem_controller_cnt = 0;

            switch (mode)
            {                          // WRITE operation - returns the address in which the key is stored
            case Memory_Operation.SET: // 0x01
                cam_din     = key;
                cam_wr_addr = (byte)mem_controller_cnt;
                tmp_addr    = (byte)mem_controller_cnt;
                Kiwi.Pause();
                cam_we = true;
                Kiwi.Pause();
                cam_we = false;
                Kiwi.Pause();

                break;

            // READ operation - return the address if we have a match otherwhise MEM_SIZE
            case Memory_Operation.GET:             // 0x00
                cam_cmp_din = key;
                Kiwi.Pause();
                cam_cmp_din = key;
                Kiwi.Pause();

                tmp_addr = (cam_match) ? (uint)cam_match_addr : (uint)MEM_SIZE;

                break;

            // DELETE operation - return the address if we have a match otherwhise MEM_SIZE
            case Memory_Operation.DELETE:             // 0x04
                cam_cmp_din = key;
                Kiwi.Pause();
                cam_cmp_din = key;
                Kiwi.Pause();
                if (cam_match)
                {
                    tmp_addr = (uint)cam_match_addr;
                }
                else
                {
                    tmp_addr = (uint)MEM_SIZE;
                }

                Kiwi.Pause();
                if (cam_match)
                {
                    Kiwi.Pause();
                    cam_din     = (ulong)0x00;
                    cam_wr_addr = (byte)tmp_addr;
                    Kiwi.Pause();
                    cam_we = true;
                    Kiwi.Pause();
                    cam_we = false;
                    Kiwi.Pause();
                }
                break;

            default:
                break;
            }

            if (mem_controller_cnt == (uint)(MEM_SIZE - 1U))
            {
                mem_controller_cnt = 0;
            }
            else
            {
                mem_controller_cnt += 1U;
            }

            return(tmp_addr);
        }
Esempio n. 28
0
        protected void SeedData(InheritanceContext context)
        {
            var kiwi = new Kiwi
            {
                Species      = "Apteryx haastii",
                Name         = "Great spotted kiwi",
                IsFlightless = true,
                FoundOn      = Island.South
            };

            var eagle = new Eagle
            {
                Species = "Aquila chrysaetos canadensis",
                Name    = "American golden eagle",
                Group   = EagleGroup.Booted
            };

            eagle.Prey.Add(kiwi);

            var rose = new Rose
            {
                Species   = "Rosa canina",
                Name      = "Dog-rose",
                HasThorns = true
            };

            var daisy = new Daisy
            {
                Species = "Bellis perennis",
                Name    = "Common daisy"
            };

            var nz = new Country {
                Id = 1, Name = "New Zealand"
            };

            nz.Animals.Add(kiwi);

            var usa = new Country {
                Id = 2, Name = "USA"
            };

            usa.Animals.Add(eagle);

            context.Set <Animal>().Add(kiwi);
            context.Set <Bird>().Add(eagle);
            context.Set <Country>().Add(nz);
            context.Set <Country>().Add(usa);
            context.Set <Rose>().Add(rose);
            context.Set <Daisy>().Add(daisy);

            context.AddRange(
                new Tea {
                HasMilk = true, CaffeineGrams = 1
            },
                new Lilt {
                SugarGrams = 4, Carbination = 7
            },
                new Coke {
                SugarGrams = 6, CaffeineGrams = 4, Carbination = 5
            });

            context.SaveChanges();
        }
Esempio n. 29
0
    /*FIXME would like to do this to push the compiler to inline as much as it can,
     *      but this annotation seems to require .NET 4.5:
     * [MethodImpl(MethodImplOptions.AggressiveInlining)]*/
    override public void Apply(ref NetFPGA_Data dataplane)
    {
        bool  dstmac_lut_hit   = false;
        bool  srcmac_lut_exist = false;
        ulong lut_element_op   = 0; // Output port

        // Get the destination MAC from the buffer.
        ulong dst_mac = dataplane.tdata.Destination_MAC();

        //We structure "srcmac_port" as follows: src_mac_hi | src_mac_low | src_port;
        ulong srcmac_port = (dataplane.tdata.Source_MAC() << 16) | ((dataplane.tuser_low[0] >> 16) & 0xff);

        Kiwi.Pause();

        // Once we have the destination MAC, check if it exists in the LUT.
        // We will later set the appropriate metadata into the tuser field accordingly.
        // We also check if the source MAC is in our LUT. If it isn't then we will
        // later add it, to map to the source port number.
        // FIXME how to make an API that can be backed by a CAM rather than this loop for look-up?
        foreach (ulong lut_element in LUT)
        {
            // Get the mac address from LUT
            ulong lut_element_mac = lut_element.Extract_Bytes(length: 6);
            // Get the output port from LUT
            lut_element_op = lut_element.Extract_Bytes(from_byte: 6, length: 2);
            Kiwi.Pause();
            if (!dstmac_lut_hit && lut_element_mac == dst_mac)
            {
                dstmac_lut_hit = true;
            }

            if (!srcmac_lut_exist && srcmac_port == lut_element)
            {
                srcmac_lut_exist = true;
            }
        }

        Kiwi.Pause();
        // If the frame does not contain an IPv4 packet then we do not set its
        // output port; this implicitly drops the frame.
        if (dataplane.tdata.EtherType_Is(Ethernet.EtherTypes.IPv4))
        {
            // Configure the metadata such that if we have a hit then set the appropriate output
            // port in the metadata, otherwise broadcast.
            if (dstmac_lut_hit)
            {
                NetFPGA.Set_Output_Port(ref dataplane, lut_element_op);
            }
            else
            {
                NetFPGA.Broadcast(ref dataplane);
            }
        }
        Kiwi.Pause();

        // Add source MAC to our LUT if it's not already there, thus the switch "learns".
        if (!srcmac_lut_exist)
        {
            LUT[free] = srcmac_port;
            free      = (free > (LUT_SIZE - 1)) ? 0 : free++;
        }
    }
Esempio n. 30
0
    // This method describes the main logic functionality of TCP response
    static public void tcp_ping_logic()
    {
        ulong local_icmp_code_type, local_chksum_udp;
        uint  i = 0, free = 0, mem_cnt = 0;
        byte  ii = 0, local_magic_num = 0, local_opcode = 0;

        uint  pkt_size = 0;
        bool  exist = false, is_ipv4 = false, is_udp = false, is_icmp = false, is_tcp = false;
        uint  cam_addr = 0, tmp_addr = 0, addr = 0, random_seq_num = 100U;
        bool  good_IP_checksum = false, error = false;
        ulong local_key_value, local_extras, local_flag, local_TCP_length;

        random_seq_num = 100U;

        while (true)         // Process packets indefinately
        {
            pkt_size = ReceiveFrame();

            for (i = 0; i <= 5; i++)
            {
                Extract_headers(i, tdata[i], tuser_low[i]);
                Kiwi.Pause();
            }

            is_ipv4 = IPv4;
            is_udp  = proto_UDP;
            is_icmp = proto_ICMP;
            is_tcp  = proto_TCP;
            local_icmp_code_type = ICMP_code_type;
            Kiwi.Pause();

            // ###########################################################################################
            // #                TCP - PING
            if (is_ipv4 && is_tcp)
            {
                // Validate the IP checksum
                chksumIP = calc_IP_checksum();
                Kiwi.Pause();
                good_IP_checksum = (chksumIP == (ulong)0x00);
                // Set the IP total length to big endianess and subtract 20B (IP header)
                tmp1 = (IP_total_length >> 8 | (IP_total_length & (ulong)0x00ff) << 8) - 20U;
                // Turn it back to little endian - TCP length
                local_TCP_length = tmp1 >> 8 | (tmp1 & (ulong)0x00ff) << 8;
                // Include in the TCP checksum the IP pseudo header
                tmp  = (ulong)(src_ip << 32 | dst_ip);
                tmp2 = (ulong)0x000600 | local_TCP_length << 32;
                Kiwi.Pause();
                calc_checksum(tmp2);                // (optimization) 6U = 0x06 = TCP proto_type , TCP length
                Kiwi.Pause();
                calc_checksum(tmp);                 // (optimization) src, dst IPs

                // Validate the TCP checksum
                for (i = 4; i <= pkt_size; i++)
                {
                    tmp2 = (i != 4) ? tdata[i] : tdata[i] >> 16;
                    Kiwi.Pause();
                    calc_checksum(tmp2);
                }
                Kiwi.Pause();

                // TCP - echo request
                if (TCP_SYN_flag && good_IP_checksum && chksum_UDP == (ulong)0x00ffff)
                {
                    swap_multiple_fields(is_udp | is_tcp, is_icmp);
                    chksum_UDP = (ulong)0x00;

                    // Set the seq_num to big endian and add 1
                    tmp1 = (TCP_seq_num >> 24 | (TCP_seq_num & (ulong)0x00ff0000) >> 8 | (TCP_seq_num & (ulong)0x0000ff00) << 8 | (TCP_seq_num & (ulong)0x00ff) << 24) + 1U;
                    Kiwi.Pause();
                    TCP_seq_num = (tmp1 >> 24 | (tmp1 & (ulong)0x00ff0000) >> 8 | (tmp1 & (ulong)0x0000ff00) << 8 | (tmp1 & (ulong)0x00ff) << 24);
                    tmp         = (ulong)((random_seq_num & (uint)0x00ff00) >> 8 | (random_seq_num & (uint)0x00ff) << 8);

                    // **************************************************
                    // Set i.the RST-ACK, ii.seq_num, iii.part of ack_num		**** RST-ACK ****
                    //***************************************************
                    tmp2 = (ulong)0x0014 << 56 | TCP_seq_num << 16 | tmp;
                    // **************************************************
                    // Set i.the SYN-ACK, ii.seq_num, iii.part of ack_num		**** SYN-ACK ****
                    // **************************************************
                    //tmp2 = (ulong)0x0012<<56 | TCP_seq_num<<16 | tmp;

                    tmp3 = tdata[5] & (ulong)0x00ff000000000000;
                    Kiwi.Pause();
                    // Set the ACK flag + seq num + ack num
                    tmp3    |= tmp2;
                    tdata[5] = tmp3;
                    Kiwi.Pause();
                    // Set part of the seq_num
                    tmp = tdata[4] & (ulong)0x0000ffffffffffff;
                    Kiwi.Pause();
                    // Set the seq to the right position
                    tmp     |= (ulong)((random_seq_num & (uint)0x00ff0000) << 32 | (random_seq_num & (uint)0x00ff000000) << 32);
                    tdata[4] = tmp;
                    Kiwi.Pause();

                    // Set the IP total length to big endianess and subtract 20B (IP header)
                    tmp1 = (IP_total_length >> 8 | (IP_total_length & (ulong)0x00ff) << 8) - 20U;
                    // Turn it back to little endian - TCP length
                    local_TCP_length = tmp1 >> 8 | (tmp1 & (ulong)0x00ff) << 8;
                    // Include in the TCP checksum, the IP pseudo header
                    tmp  = (ulong)(src_ip << 32 | dst_ip);
                    tmp2 = (ulong)0x000600 | local_TCP_length << 32;
                    Kiwi.Pause();
                    calc_checksum(tmp2);                    // (optimization) 6U = 0x06 = TCP proto_type , TCP length
                    Kiwi.Pause();
                    calc_checksum(tmp);                     // (optimization) src, dst IPs

                    // Reset the TCP checksum
                    tmp = tdata[6] & (ulong)0xffffffff0000ffff;
                    Kiwi.Pause();
                    tdata[6] = tmp;

                    // The 4th element in the buffer is the start of the TCP frame
                    for (i = 4; i <= pkt_size; i++)
                    {
                        tmp2 = (i != 4) ? tdata[i] : tdata[i] >> 16;
                        Kiwi.Pause();
                        calc_checksum(tmp2);
                    }

                    // 1's complement of the result
                    tmp1 = (chksum_UDP ^ ~(ulong)0x00) & (ulong)0x00ffff;
                    Kiwi.Pause();
                    // make it back to little endian
                    tmp2 = ((tmp1 >> 8) | (tmp1 & (ulong)0x00ff) << 8);
                    // Set the new TCP checksum
                    tdata[6] = tmp | tmp2 << 16;
                    tmp3     = tuser_low[0];
                    Kiwi.Pause();
                    // Set the output port
                    tuser_low[0] = (src_port << 24) | (src_port << 16) | tmp3;

                    random_seq_num += 1U;
                }
            }
            Kiwi.Pause();
            // #
            // ###########################################################################################

            // Procedure calchksum_ICMPl for transmiting packet
            SendFrame(pkt_size);
            //End of frame, ready for next frame
            IPv4         = false;
            proto_UDP    = false;
            proto_ICMP   = false;
            proto_TCP    = false;
            TCP_SYN_flag = false;
            chksum_UDP   = 0x00;
            pkt_size     = 0x00;
        }
    }
Esempio n. 31
0
    /*FIXME would like to do this to push the compiler to inline as much as it can,
     *      but this annotation seems to require .NET 4.5:
     * [MethodImpl(MethodImplOptions.AggressiveInlining)]*/
    override public void Apply(ref NetFPGA_Data dataplane)
    {
        bool  lut_hit        = false;
        ulong lut_element_op = 0; // Output port

        ulong tmp = 0;

        // Get the destination MAC from the buffer.
        ulong dst_mac = dataplane.tdata.Destination_MAC();

        // Once we have the destination MAC, check if it exists in the LUT.
        // We will later set the appropriate metadata into the tuser field accordingly.
        foreach (ulong lut_element in LUT)
        {
            // Get the mac address from LUT
            ulong lut_element_mac = lut_element.Extract_Bytes(length: 6);        /*LUT[i] & (ulong)0xffffffffffff0000;*/
            // Get the output port from LUT
            lut_element_op = lut_element.Extract_Bytes(from_byte: 6, length: 2); /*LUT[i] & (ulong)0x000000000000ffff*/
            Kiwi.Pause();
            if (lut_element_mac == dst_mac)
            {
                lut_hit = true;
                break;
            }
        }

        Kiwi.Pause();
        // If the frame does not contain an IPv4 packet then we do not set its
        // output port; this implicitly drops the frame.
        if (dataplane.tdata.EtherType_Is(Ethernet.EtherTypes.IPv4))
        {
            // Configure the metadata such that if we have a hit then set the appropriate output
            // port in the metadata, otherwise broadcast.
            if (lut_hit)
            {
                NetFPGA.Set_Output_Port(ref dataplane, lut_element_op);
            }
            else
            {
                NetFPGA.Broadcast(ref dataplane);
            }
        }
        Kiwi.Pause();


        // Check if the source MAC is in our LUT. If it isn't then add it,
        // to map to the source port number.

        //We structure "tmp" as follows: src_mac_hi | src_mac_low | src_port;
        tmp = (dataplane.tdata.Source_MAC() << 16) | ((dataplane.tuser_low[0] >> 16) & 0xff);
        Kiwi.Pause();

        // Check if we need to store a new entry into the LUT
        if (!lut_hit)
        {
#if Kiwi_Extension
            // NOTE the Kiwi interpretation of IndexOf might need to insert hard pauses.
            bool exist = Array.IndexOf(LUT, tmp) > -1 ? true : false;
#else
            bool exist = false;
            foreach (ulong element in LUT)
            {
                Kiwi.Pause();
                // Get rid off the oq, keep only the mac
                if (tmp == element)
                {
                    exist = true;
                    break;
                }
            }
#endif
            if (!exist)
            {
                LUT[free] = tmp;
                free      = (free > (LUT_SIZE - 1)) ? 0 : free++;
            }
        }
    }