[BLOG] Networking Functions on FPGA

This is a short note on networking functions on FPGA, as I am implementing some of them on FPGA, such as fast packet classification, flow table, network intrusion detection, etc.

NoC on FPGA

Basics

Example: TAPA NoC

// PE connected to a router (diagram)
// [   NoC   ] <- node_in/node_out -> [ router ]  <- pe_in/pe_out -> [   PE   ]
template <int index> void router(istream<Pkt>& node_in, istream<Pkt>& pe_in, 
    ostream<Pkt>& node_out, ostream<Pkt>& pe_out) {
  while (!pe_in.eot() ) {
    if (!pe_in.empty()) {
      node_out.write( pe_in.read() );
      if (!node_in.empty() && IsForThisNode( node_in.peek() ))
        Pkt pkt = node_in.read() ;    
        auto data = decompression(pkt.data); // actual computation
        pe_out.write(data)
      } else if (!node_in.empty()) {
        Pkt pkt = node_in.read() ;
        if (pkt.dst == PE_ADDR)
          pe_out.write(pkt);
        else
          node_out.write(pkt);
      }
  } 
} 
Pkt = hcl.Struct(
  data = Array[8, UInt[8]],
  dst = UInt[8]
)

def router(node_in: Pkt, node_out: Pkt):
    node_out = decompression(node_in)

# A ring NoC with N routers/PEs
for i in range(N):
    # 1. router data movement (to PE or next router)
    s.to(router[i].node_out, PE[i].data_in, when={router[i].node_in.dst == i})
    s.to(router[i].node_in, PE[(i+1)%N].node_in, when={router[i].node_in.dst !=i})

    # 2. PE data movement (to another PE)
    s.to(PE[i].data_out, router[i].node_in)

FPGA-based NIDS (Network Intrusion Detection System)

NIDS/Networking Basics

alert tcp any any → 172.198.2.1/32 333 (content: “ieca|
    4a4b|”; msg: “mounted success”;)

# Snort IDS pipeline
1. Parser (metadata: IPs, ports, etc.)
2. Reassembly (tracking flow states, reorder OOO packets)
3. MSPM (multi-pattern string matching) fast patterns in parallel
4. Full matching (RegEx, non-fast patterns etc.)
5. Action

Implementation: Fast MSPM

Android Studio Arctic Fox Beta and Xcode 13 Beta Side by Side with their respective cell views