fwdTo :: Map.Map (Switch, EthernetAddress) Port
      -> ((Switch, EthernetAddress), Port) -- ^forwards to this
      -> Policy
fwdTo locs ((sw, dstMac), port) = foldr (<+>) PoBottom (map f srcMacs)
  where -- select only srcMacs at sw
        srcMacs = map (\((_, srcMac), _) -> srcMac) $
                    filter (\((sw', _), _) -> sw' == sw)
                      (Map.toList locs)
        f srcMac = (Switch sw <&&> DlSrc srcMac <&&> DlDst dstMac)
                   ==> forward [port]

-- |'placeRoutes pktChan' produces a stream of NetCore forwarding policies that
-- forward packets based on hosts' locations in 'pktChan'.
fwdTo :: Map.Map (Switch, EthernetAddress) Port
      -> ((Switch, EthernetAddress), Port) -- ^forwards to this
      -> Policy
fwdTo locs ((sw, dstMac), port) = foldr (<+>) PoBottom (map f srcMacs)
  where -- select only srcMacs at sw
        srcMacs = map (\((_, srcMac), _) -> srcMac) $
                    filter (\((sw', _), _) -> sw' == sw)
                      (Map.toList locs)
        f srcMac = (Switch sw <&&> DlSrc srcMac <&&> DlDst dstMac)
                   ==> forward [port]

-- |'placeRoutes pktChan' produces a stream of NetCore forwarding policies that
-- forward packets based on hosts' locations in 'pktChan'.
fwdTo locs ((sw, dstMac), port) = foldr (<+>) PoBottom (map f srcMacs)
  where -- select only srcMacs at sw
        srcMacs = map (\((_, srcMac), _) -> srcMac) $
                    filter (\((sw', _), _) -> sw' == sw)
                      (Map.toList locs)
        f srcMac = (Switch sw <&&> DlSrc srcMac <&&> DlDst dstMac)
                   ==> forward [port]

-- |'placeRoutes pktChan' produces a stream of NetCore forwarding policies that
-- forward packets based on hosts' locations in 'pktChan'.