restore logic for icmp and null ports
diff --git a/openstack/compute/v2/extensions/defsecrules/fixtures.go b/openstack/compute/v2/extensions/defsecrules/fixtures.go
index bf708f8..4fee896 100644
--- a/openstack/compute/v2/extensions/defsecrules/fixtures.go
+++ b/openstack/compute/v2/extensions/defsecrules/fixtures.go
@@ -83,8 +83,8 @@
 {
   "security_group_default_rule": {
     "ip_protocol": "ICMP",
-    "from_port": 80,
-    "to_port": 80,
+    "from_port": 0,
+    "to_port": 0,
     "cidr": "10.10.12.0/24"
   }
 }
@@ -96,13 +96,13 @@
 		fmt.Fprintf(w, `
 {
   "security_group_default_rule": {
-    "from_port": 80,
+    "from_port": 0,
     "id": "{ruleID}",
     "ip_protocol": "ICMP",
     "ip_range": {
       "cidr": "10.10.12.0/24"
     },
-    "to_port": 80
+    "to_port": 0
   }
 }
 `)
diff --git a/openstack/compute/v2/extensions/defsecrules/requests.go b/openstack/compute/v2/extensions/defsecrules/requests.go
index 5d74256..184fdc9 100644
--- a/openstack/compute/v2/extensions/defsecrules/requests.go
+++ b/openstack/compute/v2/extensions/defsecrules/requests.go
@@ -1,6 +1,8 @@
 package defsecrules
 
 import (
+	"strings"
+
 	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/pagination"
 )
@@ -15,9 +17,9 @@
 // CreateOpts represents the configuration for adding a new default rule.
 type CreateOpts struct {
 	// The lower bound of the port range that will be opened.s
-	FromPort int `json:"from_port" required:"true"`
+	FromPort int `json:"from_port"`
 	// The upper bound of the port range that will be opened.
-	ToPort int `json:"to_port" required:"true"`
+	ToPort int `json:"to_port"`
 	// The protocol type that will be allowed, e.g. TCP.
 	IPProtocol string `json:"ip_protocol" required:"true"`
 	// ONLY required if FromGroupID is blank. This represents the IP range that
@@ -33,6 +35,12 @@
 
 // ToRuleCreateMap builds the create rule options into a serializable format.
 func (opts CreateOpts) ToRuleCreateMap() (map[string]interface{}, error) {
+	if opts.FromPort == 0 && strings.ToUpper(opts.IPProtocol) != "ICMP" {
+		return nil, gophercloud.ErrMissingInput{Argument: "FromPort"}
+	}
+	if opts.ToPort == 0 && strings.ToUpper(opts.IPProtocol) != "ICMP" {
+		return nil, gophercloud.ErrMissingInput{Argument: "ToPort"}
+	}
 	return gophercloud.BuildRequestBody(opts, "security_group_default_rule")
 }
 
diff --git a/openstack/compute/v2/extensions/defsecrules/requests_test.go b/openstack/compute/v2/extensions/defsecrules/requests_test.go
index 3cbc990..df568fe 100644
--- a/openstack/compute/v2/extensions/defsecrules/requests_test.go
+++ b/openstack/compute/v2/extensions/defsecrules/requests_test.go
@@ -77,8 +77,8 @@
 
 	opts := CreateOpts{
 		IPProtocol: "ICMP",
-		FromPort:   80,
-		ToPort:     80,
+		FromPort:   0,
+		ToPort:     0,
 		CIDR:       "10.10.12.0/24",
 	}
 
@@ -87,8 +87,8 @@
 
 	expected := &DefaultRule{
 		ID:         ruleID,
-		FromPort:   80,
-		ToPort:     80,
+		FromPort:   0,
+		ToPort:     0,
 		IPProtocol: "ICMP",
 		IPRange:    secgroups.IPRange{CIDR: "10.10.12.0/24"},
 	}
diff --git a/openstack/compute/v2/extensions/secgroups/fixtures.go b/openstack/compute/v2/extensions/secgroups/fixtures.go
index 4e4c0e4..e4ca587 100644
--- a/openstack/compute/v2/extensions/secgroups/fixtures.go
+++ b/openstack/compute/v2/extensions/secgroups/fixtures.go
@@ -226,9 +226,9 @@
 		th.TestJSONRequest(t, r, `
 {
   "security_group_rule": {
-    "from_port": 80,
+    "from_port": 0,
     "ip_protocol": "ICMP",
-    "to_port": 80,
+    "to_port": 0,
     "parent_group_id": "{groupID}",
     "cidr": "0.0.0.0/0"
   }
@@ -240,10 +240,10 @@
 		fmt.Fprintf(w, `
 {
   "security_group_rule": {
-    "from_port": 80,
+    "from_port": 0,
     "group": {},
     "ip_protocol": "ICMP",
-    "to_port": 80,
+    "to_port": 0,
     "parent_group_id": "{groupID}",
     "ip_range": {
       "cidr": "0.0.0.0/0"
diff --git a/openstack/compute/v2/extensions/secgroups/requests.go b/openstack/compute/v2/extensions/secgroups/requests.go
index 1cdbde0..ec8019f 100644
--- a/openstack/compute/v2/extensions/secgroups/requests.go
+++ b/openstack/compute/v2/extensions/secgroups/requests.go
@@ -104,9 +104,9 @@
 	// the ID of the group that this rule will be added to.
 	ParentGroupID string `json:"parent_group_id" required:"true"`
 	// the lower bound of the port range that will be opened.
-	FromPort int `json:"from_port" required:"true"`
+	FromPort int `json:"from_port"`
 	// the upper bound of the port range that will be opened.
-	ToPort int `json:"to_port" required:"true"`
+	ToPort int `json:"to_port"`
 	// the protocol type that will be allowed, e.g. TCP.
 	IPProtocol string `json:"ip_protocol" required:"true"`
 	// ONLY required if FromGroupID is blank. This represents the IP range that
diff --git a/openstack/compute/v2/extensions/secgroups/requests_test.go b/openstack/compute/v2/extensions/secgroups/requests_test.go
index 1509733..bdbedcd 100644
--- a/openstack/compute/v2/extensions/secgroups/requests_test.go
+++ b/openstack/compute/v2/extensions/secgroups/requests_test.go
@@ -225,8 +225,8 @@
 
 	opts := CreateRuleOpts{
 		ParentGroupID: groupID,
-		FromPort:      80,
-		ToPort:        80,
+		FromPort:      0,
+		ToPort:        0,
 		IPProtocol:    "ICMP",
 		CIDR:          "0.0.0.0/0",
 	}
@@ -235,8 +235,8 @@
 	th.AssertNoErr(t, err)
 
 	expected := &Rule{
-		FromPort:      80,
-		ToPort:        80,
+		FromPort:      0,
+		ToPort:        0,
 		Group:         Group{},
 		IPProtocol:    "ICMP",
 		ParentGroupID: groupID,