diff --git a/src/opnsense/mvc/app/controllers/OPNsense/TrafficShaper/Api/ServiceController.php b/src/opnsense/mvc/app/controllers/OPNsense/TrafficShaper/Api/ServiceController.php
new file mode 100644
index 000000000..0e828d5d5
--- /dev/null
+++ b/src/opnsense/mvc/app/controllers/OPNsense/TrafficShaper/Api/ServiceController.php
@@ -0,0 +1,55 @@
+request->isPost()) {
+ // close session for long running action
+ $this->sessionClose();
+
+ return array("status" => "ok");
+ } else {
+ return array("status" => "failed");
+ }
+ }
+}
diff --git a/src/opnsense/mvc/app/controllers/OPNsense/TrafficShaper/Api/SettingsController.php b/src/opnsense/mvc/app/controllers/OPNsense/TrafficShaper/Api/SettingsController.php
new file mode 100644
index 000000000..8b75c15fc
--- /dev/null
+++ b/src/opnsense/mvc/app/controllers/OPNsense/TrafficShaper/Api/SettingsController.php
@@ -0,0 +1,134 @@
+array());
+
+ for ($i=1; $i<100; $i++) {
+ $result['rows'][] = array('id'=>$i,'sender'=>$i.'xyz','receiver'=>'xxx'.$i);
+ }
+
+ $result['rowCount'] = count($result['rows']);
+ $result['current'] = 1;
+
+ return $result;
+ }
+
+ /**
+ * retrieve settings
+ * @return array
+ */
+ public function searchPipesAction()
+ {
+ if ($this->request->isPost()) {
+ $mdlShaper = new TrafficShaper();
+
+ // parse search parameters
+ if ($this->request->hasPost('rowCount')) {
+ $itemsPerPage = $this->request->getPost('rowCount');
+ } else {
+ $itemsPerPage = 9999;
+ }
+ if ($this->request->hasPost('current')) {
+ $currentPage = $this->request->getPost('current');
+ } else {
+ $currentPage = 1;
+ }
+
+ if ($this->request->hasPost('sort')) {
+ $sortBy = array_keys($this->request->getPost("sort"));
+ if ($this->request->getPost("sort")[$sortBy[0]] == "desc") {
+ $sortDescending = true;
+ } else {
+ $sortDescending = false;
+ }
+ } else {
+ $sortBy = array("number");
+ $sortDescending = false;
+ }
+
+
+
+ //searchPhrase
+ //sort
+
+ //$mdlShaper
+
+ $result = array('rows'=>array());
+
+ $fields = array("number", "bandwidth","bandwidthMetric");
+ $recordIndex = 0;
+ foreach ($mdlShaper->pipes->pipe->sortedBy($sortBy, $sortDescending) as $pipe) {
+ if (count($result['rows']) < $itemsPerPage &&
+ $recordIndex >= ($itemsPerPage*($currentPage-1))
+ ) {
+ $row = array();
+ $row['uuid'] = $pipe->getAttributes()['uuid'];
+ foreach ($fields as $fieldname) {
+ $row[$fieldname] = $pipe->$fieldname->getNodeData();
+ if (is_array($row[$fieldname])) {
+ foreach ($row[$fieldname] as $fieldKey => $fieldValue) {
+ if ($fieldValue['selected'] == 1) {
+ $row[$fieldname] = $fieldValue['value'];
+ }
+ }
+ }
+ }
+ $result['rows'][] = $row;
+ }
+ $recordIndex++;
+ }
+
+
+ $result['rowCount'] = count($result['rows']);
+ $result['total'] = $recordIndex;
+ $result['current'] = (int)$currentPage;
+
+ return $result;
+ }
+
+ }
+
+}
diff --git a/src/opnsense/mvc/app/controllers/OPNsense/TrafficShaper/IndexController.php b/src/opnsense/mvc/app/controllers/OPNsense/TrafficShaper/IndexController.php
new file mode 100644
index 000000000..92e1e0343
--- /dev/null
+++ b/src/opnsense/mvc/app/controllers/OPNsense/TrafficShaper/IndexController.php
@@ -0,0 +1,42 @@
+view->title = "Traffic Shaper";
+ $this->view->pick('OPNsense/TrafficShaper/index');
+ }
+}
diff --git a/src/opnsense/mvc/app/models/OPNsense/TrafficShaper/TrafficShaper.xml b/src/opnsense/mvc/app/models/OPNsense/TrafficShaper/TrafficShaper.xml
index 24d6491cb..163c6b50c 100644
--- a/src/opnsense/mvc/app/models/OPNsense/TrafficShaper/TrafficShaper.xml
+++ b/src/opnsense/mvc/app/models/OPNsense/TrafficShaper/TrafficShaper.xml
@@ -40,10 +40,39 @@
| Number | +Bandwidth | +BandwidthMetric | +Commands | +ID | ++ | + | + | + | + + |
|---|