Introducing new opts interface idea :smirk:
diff --git a/openstack/networking/v2/extensions/external/requests.go b/openstack/networking/v2/extensions/external/requests.go
new file mode 100644
index 0000000..0d20bb1
--- /dev/null
+++ b/openstack/networking/v2/extensions/external/requests.go
@@ -0,0 +1,33 @@
+package external
+
+import "github.com/rackspace/gophercloud/openstack/networking/v2/networks"
+
+type CreateOpts struct {
+	Parent   networks.CreateOpts
+	External bool
+}
+
+func (o CreateOpts) ToMap() map[string]map[string]interface{} {
+	outer := o.Parent.ToMap()
+
+	outer["network"]["router:external"] = o.External
+
+	return outer
+}
+
+func (o CreateOpts) IsCreateOpts() bool { return true }
+
+type UpdateOpts struct {
+	Parent   networks.UpdateOpts
+	External bool
+}
+
+func (o UpdateOpts) ToMap() map[string]map[string]interface{} {
+	outer := o.Parent.ToMap()
+
+	outer["network"]["router:external"] = o.External
+
+	return outer
+}
+
+func (o UpdateOpts) IsUpdateOpts() bool { return true }
diff --git a/openstack/networking/v2/extensions/external/results_test.go b/openstack/networking/v2/extensions/external/results_test.go
index 6c7e69a..9831d8b 100644
--- a/openstack/networking/v2/extensions/external/results_test.go
+++ b/openstack/networking/v2/extensions/external/results_test.go
@@ -182,8 +182,10 @@
 		`)
 	})
 
-	options := networks.CreateOpts{External: true}
+	iTrue := true
+	options := CreateOpts{networks.CreateOpts{Name: "ext_net", AdminStateUp: &iTrue}, true}
 	res := networks.Create(serviceClient(), options)
+
 	n, err := ExtractCreate(res)
 
 	th.AssertNoErr(t, err)
@@ -202,7 +204,8 @@
 		th.TestJSONRequest(t, r, `
 {
 		"network": {
-				"router:external": true
+				"router:external": true,
+				"name": "new_name"
 		}
 }
 			`)
@@ -215,7 +218,7 @@
 	"network": {
 			"admin_state_up": true,
 			"id": "8d05a1b1-297a-46ca-8974-17debf51ca3c",
-			"name": "ext_net",
+			"name": "new_name",
 			"router:external": true,
 			"shared": false,
 			"status": "ACTIVE",
@@ -228,8 +231,7 @@
 		`)
 	})
 
-	shared := true
-	options := networks.UpdateOpts{External: true}
+	options := UpdateOpts{networks.UpdateOpts{Name: "new_name"}, true}
 	res := networks.Update(serviceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", options)
 	n, err := ExtractUpdate(res)
 
diff --git a/openstack/networking/v2/networks/requests.go b/openstack/networking/v2/networks/requests.go
index 3a1613e..180914f 100644
--- a/openstack/networking/v2/networks/requests.go
+++ b/openstack/networking/v2/networks/requests.go
@@ -1,6 +1,7 @@
 package networks
 
 import (
+	"fmt"
 	"strconv"
 
 	"github.com/racker/perigee"
@@ -10,7 +11,7 @@
 )
 
 type networkOpts struct {
-	AdminStateUp bool
+	AdminStateUp *bool
 	Name         string
 	Shared       *bool
 	TenantID     string
@@ -89,13 +90,37 @@
 	return res
 }
 
-type CreateOpts interface {
-	ToMap() map[string]interface{}
+type CreateOptsInt interface {
+	ToMap() map[string]map[string]interface{}
+	IsCreateOpts() bool
 }
 
-// CreateOpts represents the attributes used when creating a new network.
 type CreateOpts networkOpts
 
+func (o CreateOpts) ToMap() map[string]map[string]interface{} {
+	inner := make(map[string]interface{})
+
+	if o.AdminStateUp != nil {
+		inner["admin_state_up"] = &o.AdminStateUp
+	}
+	if o.Name != "" {
+		inner["name"] = o.Name
+	}
+	if o.Shared != nil {
+		inner["shared"] = &o.Shared
+	}
+	if o.TenantID != "" {
+		inner["tenant_id"] = o.TenantID
+	}
+
+	outer := make(map[string]map[string]interface{})
+	outer["network"] = inner
+
+	return outer
+}
+
+func (o CreateOpts) IsCreateOpts() bool { return true }
+
 // Create accepts a CreateOpts struct and creates a new network using the values
 // provided. This operation does not actually require a request body, i.e. the
 // CreateOpts struct argument can be empty.
@@ -103,31 +128,17 @@
 // The tenant ID that is contained in the URI is the tenant that creates the
 // network. An admin user, however, has the option of specifying another tenant
 // ID in the CreateOpts struct.
-func Create(c *gophercloud.ServiceClient, opts CreateOpts) CreateResult {
-	// Define structures
-	type network struct {
-		AdminStateUp bool    `json:"admin_state_up,omitempty"`
-		Name         string  `json:"name,omitempty"`
-		Shared       *bool   `json:"shared,omitempty"`
-		TenantID     *string `json:"tenant_id,omitempty"`
-	}
-	type request struct {
-		Network network `json:"network"`
+func Create(c *gophercloud.ServiceClient, opts CreateOptsInt) CreateResult {
+	var res CreateResult
+
+	if opts.IsCreateOpts() != true {
+		res.Err = fmt.Errorf("Must provide valid create opts")
+		return res
 	}
 
-	// Populate request body
-	reqBody := request{Network: network{
-		AdminStateUp: opts.AdminStateUp,
-		Name:         opts.Name,
-		Shared:       opts.Shared,
-	}}
-
-	if opts.TenantID != "" {
-		reqBody.Network.TenantID = &opts.TenantID
-	}
+	reqBody := opts.ToMap()
 
 	// Send request to API
-	var res CreateResult
 	_, err := perigee.Request("POST", createURL(c), perigee.Options{
 		MoreHeaders: c.Provider.AuthenticatedHeaders(),
 		ReqBody:     &reqBody,
@@ -138,32 +149,47 @@
 	return res
 }
 
-// UpdateOpts represents the attributes used when updating an existing network.
+type UpdateOptsInt interface {
+	ToMap() map[string]map[string]interface{}
+	IsUpdateOpts() bool
+}
+
 type UpdateOpts networkOpts
 
+func (o UpdateOpts) ToMap() map[string]map[string]interface{} {
+	inner := make(map[string]interface{})
+
+	if o.AdminStateUp != nil {
+		inner["admin_state_up"] = &o.AdminStateUp
+	}
+	if o.Name != "" {
+		inner["name"] = o.Name
+	}
+	if o.Shared != nil {
+		inner["shared"] = &o.Shared
+	}
+
+	outer := make(map[string]map[string]interface{})
+	outer["network"] = inner
+
+	return outer
+}
+
+func (o UpdateOpts) IsUpdateOpts() bool { return true }
+
 // Update accepts a UpdateOpts struct and updates an existing network using the
 // values provided. For more information, see the Create function.
-func Update(c *gophercloud.ServiceClient, networkID string, opts UpdateOpts) UpdateResult {
-	// Define structures
-	type network struct {
-		AdminStateUp bool   `json:"admin_state_up"`
-		Name         string `json:"name"`
-		Shared       *bool  `json:"shared,omitempty"`
+func Update(c *gophercloud.ServiceClient, networkID string, opts UpdateOptsInt) UpdateResult {
+	var res UpdateResult
+
+	if opts.IsUpdateOpts() != true {
+		res.Err = fmt.Errorf("Must provide valid update opts")
+		return res
 	}
 
-	type request struct {
-		Network network `json:"network"`
-	}
-
-	// Populate request body
-	reqBody := request{Network: network{
-		AdminStateUp: opts.AdminStateUp,
-		Name:         opts.Name,
-		Shared:       opts.Shared,
-	}}
+	reqBody := opts.ToMap()
 
 	// Send request to API
-	var res UpdateResult
 	_, err := perigee.Request("PUT", getURL(c, networkID), perigee.Options{
 		MoreHeaders: c.Provider.AuthenticatedHeaders(),
 		ReqBody:     &reqBody,
diff --git a/openstack/networking/v2/networks/requests_test.go b/openstack/networking/v2/networks/requests_test.go
index 4c50b87..cc70354 100644
--- a/openstack/networking/v2/networks/requests_test.go
+++ b/openstack/networking/v2/networks/requests_test.go
@@ -180,7 +180,8 @@
 		`)
 	})
 
-	options := CreateOpts{Name: "sample_network", AdminStateUp: true}
+	iTrue := true
+	options := CreateOpts{Name: "sample_network", AdminStateUp: &iTrue}
 	n, err := Create(ServiceClient(), options).Extract()
 	th.AssertNoErr(t, err)
 
@@ -216,8 +217,8 @@
 		w.WriteHeader(http.StatusCreated)
 	})
 
-	shared := true
-	options := CreateOpts{Name: "sample_network", AdminStateUp: true, Shared: &shared, TenantID: "12345"}
+	iTrue := true
+	options := CreateOpts{Name: "sample_network", AdminStateUp: &iTrue, Shared: &iTrue, TenantID: "12345"}
 	_, err := Create(ServiceClient(), options).Extract()
 	th.AssertNoErr(t, err)
 }
@@ -259,8 +260,8 @@
 		`)
 	})
 
-	shared := true
-	options := UpdateOpts{Name: "new_network_name", AdminStateUp: false, Shared: &shared}
+	iTrue, iFalse := true, false
+	options := UpdateOpts{Name: "new_network_name", AdminStateUp: &iFalse, Shared: &iTrue}
 	n, err := Update(ServiceClient(), "4e8e5957-649f-477b-9e5b-f1f75b21c03c", options).Extract()
 	th.AssertNoErr(t, err)