func AddInterface(c *gophercloud.ServiceClient, id string, opts InterfaceOpts) InterfaceResult {
	var res InterfaceResult
	if (opts.SubnetID == "" && opts.PortID == "") || (opts.SubnetID != "" && opts.PortID != "") {
		res.Err = errInvalidInterfaceOpts
		return res
	}
	type request struct {
		SubnetID string `json:"subnet_id,omitempty"`
		PortID   string `json:"port_id,omitempty"`
	}
	body := request{SubnetID: opts.SubnetID, PortID: opts.PortID}
	_, res.Err = c.Request("PUT", addInterfaceURL(c, id), gophercloud.RequestOpts{
		JSONBody:     &body,
		JSONResponse: &res.Body,
		OkCodes:      []int{200},
	})
	return res
}
AddInterface attaches a subnet to an internal router interface. You must
specify either a SubnetID or PortID in the request body. If you specify both,
the operation will fail and an error will be returned.

If you specify a SubnetID, the gateway IP address for that particular subnet
is used to create the router interface. Alternatively, if you specify a
PortID, the IP address associated with the port is used to create the router
interface.

If you reference a port that is associated with multiple IP addresses, or
if the port is associated with zero IP addresses, the operation will fail and
a 400 Bad Request error will be returned.

If you reference a port already in use, the operation will fail and a 409
Conflict error will be returned.

The PortID that is returned after using Extract() on the result of this
operation can either be the same PortID passed in or, on the other hand, the
identifier of a new port created by this operation. After the operation
completes, the device ID of the port is set to the router ID, and the
device owner attribute is set to `network:router_interface'.
package routers
import (
	"errors"
	"github.com/rackspace/gophercloud"
	"github.com/rackspace/gophercloud/pagination"
)
type ListOpts struct {
	ID           string `q:"id"`
	Name         string `q:"name"`
	AdminStateUp *bool  `q:"admin_state_up"`
	Status       string `q:"status"`
	TenantID     string `q:"tenant_id"`
	Limit        int    `q:"limit"`
	Marker       string `q:"marker"`
	SortKey      string `q:"sort_key"`
	SortDir      string `q:"sort_dir"`
}
func List(c *gophercloud.ServiceClient, opts ListOpts) pagination.Pager {
	q, err := gophercloud.BuildQueryString(&opts)
	if err != nil {
		return pagination.Pager{Err: err}
	}
	u := rootURL(c) + q.String()
	return pagination.NewPager(c, u, func(r pagination.PageResult) pagination.Page {
		return RouterPage{pagination.LinkedPageBase{PageResult: r}}
	})
}
type CreateOpts struct {
	Name         string
	AdminStateUp *bool
	TenantID     string
	GatewayInfo  *GatewayInfo
}
func Create(c *gophercloud.ServiceClient, opts CreateOpts) CreateResult {
	type router struct {
		Name         *string      `json:"name,omitempty"`
		AdminStateUp *bool        `json:"admin_state_up,omitempty"`
		TenantID     *string      `json:"tenant_id,omitempty"`
		GatewayInfo  *GatewayInfo `json:"external_gateway_info,omitempty"`
	}
	type request struct {
		Router router `json:"router"`
	}
	reqBody := request{Router: router{
		Name:         gophercloud.MaybeString(opts.Name),
		AdminStateUp: opts.AdminStateUp,
		TenantID:     gophercloud.MaybeString(opts.TenantID),
	}}
	if opts.GatewayInfo != nil {
		reqBody.Router.GatewayInfo = opts.GatewayInfo
	}
	var res CreateResult
	_, res.Err = c.Request("POST", rootURL(c), gophercloud.RequestOpts{
		JSONBody:     &reqBody,
		JSONResponse: &res.Body,
		OkCodes:      []int{201},
	})
	return res
}
func Get(c *gophercloud.ServiceClient, id string) GetResult {
	var res GetResult
	_, res.Err = c.Request("GET", resourceURL(c, id), gophercloud.RequestOpts{
		JSONResponse: &res.Body,
		OkCodes:      []int{200},
	})
	return res
}
type UpdateOpts struct {
	Name         string
	AdminStateUp *bool
	GatewayInfo  *GatewayInfo
}
func Update(c *gophercloud.ServiceClient, id string, opts UpdateOpts) UpdateResult {
	type router struct {
		Name         *string      `json:"name,omitempty"`
		AdminStateUp *bool        `json:"admin_state_up,omitempty"`
		GatewayInfo  *GatewayInfo `json:"external_gateway_info,omitempty"`
	}
	type request struct {
		Router router `json:"router"`
	}
	reqBody := request{Router: router{
		Name:         gophercloud.MaybeString(opts.Name),
		AdminStateUp: opts.AdminStateUp,
	}}
	if opts.GatewayInfo != nil {
		reqBody.Router.GatewayInfo = opts.GatewayInfo
	}
	var res UpdateResult
	_, res.Err = c.Request("PUT", resourceURL(c, id), gophercloud.RequestOpts{
		JSONBody:     &reqBody,
		JSONResponse: &res.Body,
		OkCodes:      []int{200},
	})
	return res
}
func Delete(c *gophercloud.ServiceClient, id string) DeleteResult {
	var res DeleteResult
	_, res.Err = c.Request("DELETE", resourceURL(c, id), gophercloud.RequestOpts{
		OkCodes: []int{204},
	})
	return res
}
var errInvalidInterfaceOpts = errors.New("When adding a router interface you must provide either a subnet ID or a port ID")
type InterfaceOpts struct {
	SubnetID string
	PortID   string
}