Create def sec group
diff --git a/openstack/compute/v2/extensions/defsecrules/fixtures.go b/openstack/compute/v2/extensions/defsecrules/fixtures.go
index 0b11338..c0dc62b 100644
--- a/openstack/compute/v2/extensions/defsecrules/fixtures.go
+++ b/openstack/compute/v2/extensions/defsecrules/fixtures.go
@@ -36,3 +36,39 @@
       `)
 	})
 }
+
+func mockCreateRuleResponse(t *testing.T) {
+	th.Mux.HandleFunc(rootPath, func(w http.ResponseWriter, r *http.Request) {
+		th.TestMethod(t, r, "POST")
+		th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
+
+		th.TestJSONRequest(t, r, `
+{
+  "security_group_default_rule": {
+    "ip_protocol": "TCP",
+    "from_port": 80,
+    "to_port": 80,
+    "cidr": "10.10.12.0/24"
+  }
+}
+	`)
+
+		w.Header().Add("Content-Type", "application/json")
+		w.WriteHeader(http.StatusOK)
+
+		fmt.Fprintf(w, `
+{
+  "security_group_default_rule": {
+    "from_port": 80,
+    "id": 1,
+    "ip_protocol": "TCP",
+    "ip_range": {
+      "cidr": "10.10.12.0/24"
+    },
+    "to_port": 80,
+		"id": "b0e0d7dd-2ca4-49a9-ba82-c44a148b66a5"
+  }
+}
+`)
+	})
+}
diff --git a/openstack/compute/v2/extensions/defsecrules/requests.go b/openstack/compute/v2/extensions/defsecrules/requests.go
index 66337a5..2973cf0 100644
--- a/openstack/compute/v2/extensions/defsecrules/requests.go
+++ b/openstack/compute/v2/extensions/defsecrules/requests.go
@@ -1,6 +1,10 @@
 package defsecrules
 
 import (
+	"errors"
+
+	"github.com/racker/perigee"
+
 	"github.com/rackspace/gophercloud"
 	"github.com/rackspace/gophercloud/pagination"
 )
@@ -13,3 +17,69 @@
 
 	return pagination.NewPager(client, rootURL(client), createPage)
 }
+
+// CreateOpts represents the configuration for adding a new default rule.
+type CreateOpts struct {
+	// Required - the lower bound of the port range that will be opened.
+	FromPort int `json:"from_port"`
+
+	// Required - the upper bound of the port range that will be opened.
+	ToPort int `json:"to_port"`
+
+	// Required - the protocol type that will be allowed, e.g. TCP.
+	IPProtocol string `json:"ip_protocol"`
+
+	// ONLY required if FromGroupID is blank. This represents the IP range that
+	// will be the source of network traffic to your security group. Use
+	// 0.0.0.0/0 to allow all IP addresses.
+	CIDR string `json:"cidr,omitempty"`
+}
+
+// CreateRuleOptsBuilder builds the create rule options into a serializable format.
+type CreateOptsBuilder interface {
+	ToRuleCreateMap() (map[string]interface{}, error)
+}
+
+// ToRuleCreateMap builds the create rule options into a serializable format.
+func (opts CreateOpts) ToRuleCreateMap() (map[string]interface{}, error) {
+	rule := make(map[string]interface{})
+
+	if opts.FromPort == 0 {
+		return rule, errors.New("A FromPort must be set")
+	}
+	if opts.ToPort == 0 {
+		return rule, errors.New("A ToPort must be set")
+	}
+	if opts.IPProtocol == "" {
+		return rule, errors.New("A IPProtocol must be set")
+	}
+	if opts.CIDR == "" {
+		return rule, errors.New("A CIDR must be set")
+	}
+
+	rule["from_port"] = opts.FromPort
+	rule["to_port"] = opts.ToPort
+	rule["ip_protocol"] = opts.IPProtocol
+	rule["cidr"] = opts.CIDR
+
+	return map[string]interface{}{"security_group_default_rule": rule}, nil
+}
+
+func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult {
+	var result CreateResult
+
+	reqBody, err := opts.ToRuleCreateMap()
+	if err != nil {
+		result.Err = err
+		return result
+	}
+
+	_, result.Err = perigee.Request("POST", rootURL(client), perigee.Options{
+		Results:     &result.Body,
+		ReqBody:     &reqBody,
+		MoreHeaders: client.AuthenticatedHeaders(),
+		OkCodes:     []int{200},
+	})
+
+	return result
+}
diff --git a/openstack/compute/v2/extensions/defsecrules/requests_test.go b/openstack/compute/v2/extensions/defsecrules/requests_test.go
index af12796..fd3fe17 100644
--- a/openstack/compute/v2/extensions/defsecrules/requests_test.go
+++ b/openstack/compute/v2/extensions/defsecrules/requests_test.go
@@ -40,3 +40,29 @@
 	th.AssertNoErr(t, err)
 	th.AssertEquals(t, 1, count)
 }
+
+func TestCreate(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+
+	mockCreateRuleResponse(t)
+
+	opts := CreateOpts{
+		IPProtocol: "TCP",
+		FromPort:   80,
+		ToPort:     80,
+		CIDR:       "10.10.12.0/24",
+	}
+
+	group, err := Create(client.ServiceClient(), opts).Extract()
+	th.AssertNoErr(t, err)
+
+	expected := &DefaultRule{
+		ID:         "b0e0d7dd-2ca4-49a9-ba82-c44a148b66a5",
+		FromPort:   80,
+		ToPort:     80,
+		IPProtocol: "TCP",
+		IPRange:    secgroups.IPRange{CIDR: "10.10.12.0/24"},
+	}
+	th.AssertDeepEquals(t, expected, group)
+}
diff --git a/openstack/compute/v2/extensions/defsecrules/results.go b/openstack/compute/v2/extensions/defsecrules/results.go
index ae46b59..5f84b0e 100644
--- a/openstack/compute/v2/extensions/defsecrules/results.go
+++ b/openstack/compute/v2/extensions/defsecrules/results.go
@@ -3,6 +3,7 @@
 import (
 	"github.com/mitchellh/mapstructure"
 
+	"github.com/rackspace/gophercloud"
 	"github.com/rackspace/gophercloud/openstack/compute/v2/extensions/secgroups"
 	"github.com/rackspace/gophercloud/pagination"
 )
@@ -35,3 +36,32 @@
 
 	return response.Rules, err
 }
+
+type commonResult struct {
+	gophercloud.Result
+}
+
+// CreateResult represents the result of a create operation.
+type CreateResult struct {
+	commonResult
+}
+
+// GetResult represents the result of a get operation.
+type GetResult struct {
+	commonResult
+}
+
+// Extract will extract a DefaultRule struct from most responses.
+func (r commonResult) Extract() (*DefaultRule, error) {
+	if r.Err != nil {
+		return nil, r.Err
+	}
+
+	var response struct {
+		Rule DefaultRule `mapstructure:"security_group_default_rule"`
+	}
+
+	err := mapstructure.Decode(r.Body, &response)
+
+	return &response.Rule, err
+}