add list operation and squash structs
diff --git a/acceptance/openstack/networking/v2/extensions/portsbinding/portsbinding_test.go b/acceptance/openstack/networking/v2/extensions/portsbinding/portsbinding_test.go
index 71fc7dc..5a79945 100644
--- a/acceptance/openstack/networking/v2/extensions/portsbinding/portsbinding_test.go
+++ b/acceptance/openstack/networking/v2/extensions/portsbinding/portsbinding_test.go
@@ -10,6 +10,7 @@
 	"github.com/rackspace/gophercloud/openstack/networking/v2/networks"
 	"github.com/rackspace/gophercloud/openstack/networking/v2/ports"
 	"github.com/rackspace/gophercloud/openstack/networking/v2/subnets"
+	"github.com/rackspace/gophercloud/pagination"
 	th "github.com/rackspace/gophercloud/testhelper"
 )
 
@@ -53,11 +54,40 @@
 	th.AssertNoErr(t, err)
 	th.AssertEquals(t, p.HostID, newHostID)
 
+	// List ports
+	t.Logf("Listing all ports")
+	listPorts(t)
+
 	// Delete port
 	res := ports.Delete(base.Client, portID)
 	th.AssertNoErr(t, res.Err)
 }
 
+func listPorts(t *testing.T) {
+	count := 0
+	pager := ports.List(base.Client, ports.ListOpts{})
+	err := pager.EachPage(func(page pagination.Page) (bool, error) {
+		count++
+		t.Logf("--- Page ---")
+
+		portList, err := portsbinding.ExtractPorts(page)
+		th.AssertNoErr(t, err)
+
+		for _, p := range portList {
+			t.Logf("Port: ID [%s] Name [%s] HostID [%s] VNICType [%s] VIFType [%s]",
+				p.ID, p.Name, p.HostID, p.VNICType, p.VIFType)
+		}
+
+		return true, nil
+	})
+
+	th.CheckNoErr(t, err)
+
+	if count == 0 {
+		t.Logf("No pages were iterated over when listing ports")
+	}
+}
+
 func createPort(t *testing.T, networkID, subnetID, hostID string) string {
 	enable := false
 	opts := portsbinding.CreateOpts{
diff --git a/openstack/networking/v2/extensions/portsbinding/requests_test.go b/openstack/networking/v2/extensions/portsbinding/requests_test.go
index 43a001f..a226031 100644
--- a/openstack/networking/v2/extensions/portsbinding/requests_test.go
+++ b/openstack/networking/v2/extensions/portsbinding/requests_test.go
@@ -1,7 +1,6 @@
 package portsbinding
 
 import (
-	"fmt"
 	"testing"
 
 	fake "github.com/rackspace/gophercloud/openstack/networking/v2/common"
@@ -44,11 +43,10 @@
 					DeviceID:       "9ae135f4-b6e0-4dad-9e91-3c223e385824",
 				},
 				VNICType: "normal",
+				HostID:   "devstack",
 			},
 		}
 
-		fmt.Printf("%#v", actual)
-
 		th.CheckDeepEquals(t, expected, actual)
 
 		return true, nil
@@ -81,8 +79,11 @@
 	th.AssertEquals(t, n.ID, "46d4bfb9-b26e-41f3-bd2e-e6dcc1ccedb2")
 	th.AssertDeepEquals(t, n.SecurityGroups, []string{})
 	th.AssertEquals(t, n.DeviceID, "5e3898d7-11be-483e-9732-b2f5eccd2b2e")
-	th.AssertEquals(t, n.HostID, "HOST1")
+
+	th.AssertEquals(t, n.HostID, "devstack")
 	th.AssertEquals(t, n.VNICType, "normal")
+	th.AssertEquals(t, n.VIFType, "ovs")
+	th.AssertDeepEquals(t, n.VIFDetails, map[string]interface{}{"port_filter": true, "ovs_hybrid_plug": true})
 }
 
 func TestCreate(t *testing.T) {
diff --git a/openstack/networking/v2/extensions/portsbinding/results.go b/openstack/networking/v2/extensions/portsbinding/results.go
index 7a0d1c3..356e51c 100644
--- a/openstack/networking/v2/extensions/portsbinding/results.go
+++ b/openstack/networking/v2/extensions/portsbinding/results.go
@@ -51,12 +51,12 @@
 // Port represents a Neutron port. See package documentation for a top-level
 // description of what this is.
 type Port struct {
-	ports.Port
+	ports.Port `mapstructure:",squash"`
 	// The ID of the host where the port is allocated
 	HostID string `mapstructure:"binding:host_id" json:"binding:host_id"`
 	// A dictionary that enables the application to pass information about
 	// functions that the Networking API provides.
-	VIFDetails map[string]string `mapstructure:"binding:vif_details" json:"binding:vif_details"`
+	VIFDetails map[string]interface{} `mapstructure:"binding:vif_details" json:"binding:vif_details"`
 	// The VIF type for the port.
 	VIFType string `mapstructure:"binding:vif_type" json:"binding:vif_type"`
 	// The virtual network interface card (vNIC) type that is bound to the