placeRoutes :: Chan (EthernetAddress, Loc) -> IO (Chan Policy)
placeRoutes pktChan = do
  polChan <- newChan
  -- When a hosts location arrives, update the map and recompute the forwarding
  -- policy.
  locsRef <- newIORef Map.empty
  -- Initially, flood all packets
  writeChan polChan (Any ==> allPorts unmodified)
  forkIO $ forever $ do
    (dlSrc, Loc sw pt) <- readChan pktChan
    locs <- readIORef locsRef
    let locs' = Map.insert (sw, dlSrc) pt locs
    let fwdPol = foldr (<+>) PoBottom (map (fwdTo locs') (Map.toList locs'))
    -- Flood all other packets to maintain connectivity.
    let floodPol = Not (poDom fwdPol) ==> allPorts unmodified
    writeChan polChan (fwdPol <+> floodPol)
    writeIORef locsRef locs'
  return polChan
placeRoutes :: Chan (EthernetAddress, Loc) -> IO (Chan Policy)
placeRoutes pktChan = do
  polChan <- newChan
  -- When a hosts location arrives, update the map and recompute the forwarding
  -- policy.
  locsRef <- newIORef Map.empty
  -- Initially, flood all packets
  writeChan polChan (Any ==> allPorts unmodified)
  forkIO $ forever $ do
    (dlSrc, Loc sw pt) <- readChan pktChan
    locs <- readIORef locsRef
    let locs' = Map.insert (sw, dlSrc) pt locs
    let fwdPol = foldr (<+>) PoBottom (map (fwdTo locs') (Map.toList locs'))
    -- Flood all other packets to maintain connectivity.
    let floodPol = Not (poDom fwdPol) ==> allPorts unmodified
    writeChan polChan (fwdPol <+> floodPol)
    writeIORef locsRef locs'
  return polChan
placeRoutes pktChan = do
  polChan <- newChan
  -- When a hosts location arrives, update the map and recompute the forwarding
  -- policy.
  locsRef <- newIORef Map.empty
  -- Initially, flood all packets
  writeChan polChan (Any ==> allPorts unmodified)
  forkIO $ forever $ do
    (dlSrc, Loc sw pt) <- readChan pktChan
    locs <- readIORef locsRef
    let locs' = Map.insert (sw, dlSrc) pt locs
    let fwdPol = foldr (<+>) PoBottom (map (fwdTo locs') (Map.toList locs'))
    -- Flood all other packets to maintain connectivity.
    let floodPol = Not (poDom fwdPol) ==> allPorts unmodified
    writeChan polChan (fwdPol <+> floodPol)
    writeIORef locsRef locs'
  return polChan