Merge pull request #221 from mrunalp/txq

Adds a tx_queuelen setting for veth in the network configuration
This commit is contained in:
Mrunal Patel 2014-10-15 16:07:28 -07:00
commit 55f555495d
7 changed files with 28 additions and 13 deletions

View File

@ -681,7 +681,7 @@ func NetworkChangeName(iface *net.Interface, newName string) error {
// Add a new VETH pair link on the host // Add a new VETH pair link on the host
// This is identical to running: ip link add name $name type veth peer name $peername // This is identical to running: ip link add name $name type veth peer name $peername
func NetworkCreateVethPair(name1, name2 string) error { func NetworkCreateVethPair(name1, name2 string, txQueueLen int) error {
s, err := getNetlinkSocket() s, err := getNetlinkSocket()
if err != nil { if err != nil {
return err return err
@ -696,6 +696,11 @@ func NetworkCreateVethPair(name1, name2 string) error {
nameData := newRtAttr(syscall.IFLA_IFNAME, zeroTerminated(name1)) nameData := newRtAttr(syscall.IFLA_IFNAME, zeroTerminated(name1))
wb.AddData(nameData) wb.AddData(nameData)
txqLen := make([]byte, 4)
native.PutUint32(txqLen, uint32(txQueueLen))
txqData := newRtAttr(syscall.IFLA_TXQLEN, txqLen)
wb.AddData(txqData)
nest1 := newRtAttr(syscall.IFLA_LINKINFO, nil) nest1 := newRtAttr(syscall.IFLA_LINKINFO, nil)
newRtAttrChild(nest1, IFLA_INFO_KIND, zeroTerminated("veth")) newRtAttrChild(nest1, IFLA_INFO_KIND, zeroTerminated("veth"))
nest2 := newRtAttrChild(nest1, IFLA_INFO_DATA, nil) nest2 := newRtAttrChild(nest1, IFLA_INFO_DATA, nil)
@ -704,6 +709,10 @@ func NetworkCreateVethPair(name1, name2 string) error {
newIfInfomsgChild(nest3, syscall.AF_UNSPEC) newIfInfomsgChild(nest3, syscall.AF_UNSPEC)
newRtAttrChild(nest3, syscall.IFLA_IFNAME, zeroTerminated(name2)) newRtAttrChild(nest3, syscall.IFLA_IFNAME, zeroTerminated(name2))
txqLen2 := make([]byte, 4)
native.PutUint32(txqLen2, uint32(txQueueLen))
newRtAttrChild(nest3, syscall.IFLA_TXQLEN, txqLen2)
wb.AddData(nest1) wb.AddData(nest1)
if err := s.Send(wb); err != nil { if err := s.Send(wb); err != nil {

View File

@ -290,7 +290,7 @@ func TestCreateVethPair(t *testing.T) {
name2 = "veth2" name2 = "veth2"
) )
if err := NetworkCreateVethPair(name1, name2); err != nil { if err := NetworkCreateVethPair(name1, name2, 0); err != nil {
t.Fatalf("Could not create veth pair %s %s: %s", name1, name2, err) t.Fatalf("Could not create veth pair %s %s: %s", name1, name2, err)
} }
defer NetworkLinkDel(name1) defer NetworkLinkDel(name1)

View File

@ -47,7 +47,7 @@ func NetworkSetMTU(iface *net.Interface, mtu int) error {
return ErrNotImplemented return ErrNotImplemented
} }
func NetworkCreateVethPair(name1, name2 string) error { func NetworkCreateVethPair(name1, name2 string, txQueueLen int) error {
return ErrNotImplemented return ErrNotImplemented
} }

View File

@ -32,8 +32,8 @@ func ChangeInterfaceName(old, newName string) error {
return netlink.NetworkChangeName(iface, newName) return netlink.NetworkChangeName(iface, newName)
} }
func CreateVethPair(name1, name2 string) error { func CreateVethPair(name1, name2 string, txQueueLen int) error {
return netlink.NetworkCreateVethPair(name1, name2) return netlink.NetworkCreateVethPair(name1, name2, txQueueLen)
} }
func SetInterfaceInNamespacePid(name string, nsPid int) error { func SetInterfaceInNamespacePid(name string, nsPid int) error {

View File

@ -36,6 +36,11 @@ type Network struct {
// container's interfaces if a pair is created, specifically in the case of type veth // container's interfaces if a pair is created, specifically in the case of type veth
// Note: This does not apply to loopback interfaces. // Note: This does not apply to loopback interfaces.
Mtu int `json:"mtu,omitempty"` Mtu int `json:"mtu,omitempty"`
// TxQueueLen sets the tx_queuelen value for the interface and will be mirrored on both the host and
// container's interfaces if a pair is created, specifically in the case of type veth
// Note: This does not apply to loopback interfaces.
TxQueueLen int `json:"txqueuelen,omitempty"`
} }
// Struct describing the network specific runtime state that will be maintained by libcontainer for all running containers // Struct describing the network specific runtime state that will be maintained by libcontainer for all running containers

View File

@ -21,6 +21,7 @@ func (v *Veth) Create(n *Network, nspid int, networkState *NetworkState) error {
var ( var (
bridge = n.Bridge bridge = n.Bridge
prefix = n.VethPrefix prefix = n.VethPrefix
txQueueLen = n.TxQueueLen
) )
if bridge == "" { if bridge == "" {
return fmt.Errorf("bridge is not specified") return fmt.Errorf("bridge is not specified")
@ -28,7 +29,7 @@ func (v *Veth) Create(n *Network, nspid int, networkState *NetworkState) error {
if prefix == "" { if prefix == "" {
return fmt.Errorf("veth prefix is not specified") return fmt.Errorf("veth prefix is not specified")
} }
name1, name2, err := createVethPair(prefix) name1, name2, err := createVethPair(prefix, txQueueLen)
if err != nil { if err != nil {
return err return err
} }
@ -96,7 +97,7 @@ func (v *Veth) Initialize(config *Network, networkState *NetworkState) error {
// createVethPair will automatically generage two random names for // createVethPair will automatically generage two random names for
// the veth pair and ensure that they have been created // the veth pair and ensure that they have been created
func createVethPair(prefix string) (name1 string, name2 string, err error) { func createVethPair(prefix string, txQueueLen int) (name1 string, name2 string, err error) {
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
if name1, err = utils.GenerateRandomName(prefix, 7); err != nil { if name1, err = utils.GenerateRandomName(prefix, 7); err != nil {
return return
@ -106,7 +107,7 @@ func createVethPair(prefix string) (name1 string, name2 string, err error) {
return return
} }
if err = CreateVethPair(name1, name2); err != nil { if err = CreateVethPair(name1, name2, txQueueLen); err != nil {
if err == netlink.ErrInterfaceExists { if err == netlink.ErrInterfaceExists {
continue continue
} }

View File

@ -15,7 +15,7 @@ func TestGenerateVethNames(t *testing.T) {
prefix := "veth" prefix := "veth"
name1, name2, err := createVethPair(prefix) name1, name2, err := createVethPair(prefix, 0)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -36,13 +36,13 @@ func TestCreateDuplicateVethPair(t *testing.T) {
prefix := "veth" prefix := "veth"
name1, name2, err := createVethPair(prefix) name1, name2, err := createVethPair(prefix, 0)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
// retry to create the name interfaces and make sure that we get the correct error // retry to create the name interfaces and make sure that we get the correct error
err = CreateVethPair(name1, name2) err = CreateVethPair(name1, name2, 0)
if err == nil { if err == nil {
t.Fatal("expected error to not be nil with duplicate interface") t.Fatal("expected error to not be nil with duplicate interface")
} }