Fixed rtnetlink attributes packaging into netlink message.
I've also added NetworkLinkDel() function which allows deleting of the existing network links. Docker-DCO-1.1-Signed-off-by: Milos Gajdos <milosgajdos83@gmail.com> (github: milosgajdos83)
This commit is contained in:
parent
f538117a7b
commit
c5f4d90da5
|
@ -189,13 +189,15 @@ func newRtAttrChild(parent *RtAttr, attrType int, data []byte) *RtAttr {
|
|||
}
|
||||
|
||||
func (a *RtAttr) Len() int {
|
||||
if len(a.children) == 0 {
|
||||
return (syscall.SizeofRtAttr + len(a.Data))
|
||||
}
|
||||
|
||||
l := 0
|
||||
for _, child := range a.children {
|
||||
l += child.Len() + syscall.SizeofRtAttr
|
||||
}
|
||||
if l == 0 {
|
||||
l++
|
||||
l += child.Len()
|
||||
}
|
||||
l += syscall.SizeofRtAttr
|
||||
return rtaAlignOf(l + len(a.Data))
|
||||
}
|
||||
|
||||
|
@ -203,7 +205,7 @@ func (a *RtAttr) ToWireFormat() []byte {
|
|||
native := nativeEndian()
|
||||
|
||||
length := a.Len()
|
||||
buf := make([]byte, rtaAlignOf(length+syscall.SizeofRtAttr))
|
||||
buf := make([]byte, rtaAlignOf(length))
|
||||
|
||||
if a.Data != nil {
|
||||
copy(buf[4:], a.Data)
|
||||
|
@ -216,11 +218,10 @@ func (a *RtAttr) ToWireFormat() []byte {
|
|||
}
|
||||
}
|
||||
|
||||
if l := uint16(rtaAlignOf(length)); l != 0 {
|
||||
native.PutUint16(buf[0:2], l+1)
|
||||
if l := uint16(length); l != 0 {
|
||||
native.PutUint16(buf[0:2], l)
|
||||
}
|
||||
native.PutUint16(buf[2:4], a.Type)
|
||||
|
||||
return buf
|
||||
}
|
||||
|
||||
|
@ -700,6 +701,10 @@ func nonZeroTerminated(s string) []byte {
|
|||
// Add a new network link of a specified type. This is identical to
|
||||
// running: ip add link $name type $linkType
|
||||
func NetworkLinkAdd(name string, linkType string) error {
|
||||
if name == "" || linkType == "" {
|
||||
return fmt.Errorf("Neither link name nor link type can be empty!")
|
||||
}
|
||||
|
||||
s, err := getNetlinkSocket()
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -711,15 +716,43 @@ func NetworkLinkAdd(name string, linkType string) error {
|
|||
msg := newIfInfomsg(syscall.AF_UNSPEC)
|
||||
wb.AddData(msg)
|
||||
|
||||
if name != "" {
|
||||
nameData := newRtAttr(syscall.IFLA_IFNAME, zeroTerminated(name))
|
||||
wb.AddData(nameData)
|
||||
linkInfo := newRtAttr(syscall.IFLA_LINKINFO, nil)
|
||||
newRtAttrChild(linkInfo, IFLA_INFO_KIND, nonZeroTerminated(linkType))
|
||||
wb.AddData(linkInfo)
|
||||
|
||||
nameData := newRtAttr(syscall.IFLA_IFNAME, zeroTerminated(name))
|
||||
wb.AddData(nameData)
|
||||
|
||||
if err := s.Send(wb); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
kindData := newRtAttr(IFLA_INFO_KIND, nonZeroTerminated(linkType))
|
||||
return s.HandleAck(wb.Seq)
|
||||
}
|
||||
|
||||
infoData := newRtAttr(syscall.IFLA_LINKINFO, kindData.ToWireFormat())
|
||||
wb.AddData(infoData)
|
||||
// Delete a network link. This is identical to
|
||||
// running: ip link del $name
|
||||
func NetworkLinkDel(name string) error {
|
||||
if name == "" {
|
||||
return fmt.Errorf("Network link name can not be empty!")
|
||||
}
|
||||
|
||||
s, err := getNetlinkSocket()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
iface, err := net.InterfaceByName(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
wb := newNetlinkRequest(syscall.RTM_DELLINK, syscall.NLM_F_ACK)
|
||||
|
||||
msg := newIfInfomsg(syscall.AF_UNSPEC)
|
||||
msg.Index = int32(iface.Index)
|
||||
wb.AddData(msg)
|
||||
|
||||
if err := s.Send(wb); err != nil {
|
||||
return err
|
||||
|
|
|
@ -27,10 +27,35 @@ func TestCreateBridgeWithMac(t *testing.T) {
|
|||
}
|
||||
|
||||
if _, err := net.InterfaceByName(name); err == nil {
|
||||
t.Fatal("expected error getting interface because bridge was deleted")
|
||||
t.Fatal("expected error getting interface because %s bridge was deleted", name)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateBridgeLink(t *testing.T) {
|
||||
if testing.Short() {
|
||||
return
|
||||
}
|
||||
|
||||
name := "mybrlink"
|
||||
|
||||
if err := NetworkLinkAdd(name, "bridge"); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err := net.InterfaceByName(name); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := NetworkLinkDel(name); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err := net.InterfaceByName(name); err == nil {
|
||||
t.Fatal("expected error getting interface because %s bridge was deleted", name)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestCreateVethPair(t *testing.T) {
|
||||
if testing.Short() {
|
||||
return
|
||||
|
|
|
@ -19,6 +19,10 @@ func NetworkLinkAdd(name string, linkType string) error {
|
|||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func NetworkLinkDel(name string) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func NetworkLinkUp(iface *net.Interface) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue