示例#1
0
文件: links.go 项目: yetu/go-netlink
func (self *LinkHandler) SetLinkState(flag link.Flags) (err error) {
	var qry *netlink.Message
	if hdr, ok := self.cache.Header.(*link.Header); ok {
		// While rtnetlink(7) says changes should always be IFF_QUERY, it has some
		// behaviours that are undocumented - like limiting actions on SETLINK's to
		// specific FLAGs.
		hdr = link.NewHeader(hdr.InterfaceFamily(), hdr.InterfaceType(), hdr.InterfaceIndex(), flag&link.IFF_UP, link.IFF_UP)
		msg := rtnetlink.Message{Header: hdr}
		qry, err = netlink.NewMessage(rtnetlink.RTM_SETLINK, netlink.NLM_F_ACK|netlink.NLM_F_REQUEST, msg)
	} else {
		err = errors.New("Cant set link flags (invalid cache)")
	}
	if err != nil {
		return
	}
	mch, err := self.h.Query(*qry, 1)
	if err == nil {
		for m := range mch {
			switch m.Header.MessageType() {
			case netlink.NLMSG_ERROR:
				emsg := &netlink.Error{}
				err = emsg.UnmarshalNetlink(m.Body)
				if err == nil && emsg.Code() != 0 {
					err = emsg
				}
			default:
				err = errors.New("Unexpected netlink message")
				log.Printf("NetlinkError: %v", err)
			}
		}
		close(mch)
	}
	return
}
示例#2
0
文件: links.go 项目: yetu/go-netlink
func (self *linkFinder) GetLinkByID(i uint32) (lh *LinkHandler, err error) {
	qry, err := netlink.NewMessage(rtnetlink.RTM_GETLINK, netlink.NLM_F_REQUEST,
		link.NewHeader(rtnetlink.AF_UNSPEC, 0, i, 0, 0))
	if err == nil {
		var mch chan netlink.Message
		mch, err = self.h.Query(*qry, 1)
		if err == nil {
			for ii := range mch {
				switch ii.Header.MessageType() {
				default:
					err = errors.New("Unknown message type in response to RTM_GETLINK")
				case netlink.NLMSG_ERROR:
					emsg := &netlink.Error{}
					err = emsg.UnmarshalNetlink(ii.Body)
					if err == nil && emsg.Code() != 0 {
						err = emsg
					}
				case rtnetlink.RTM_NEWLINK:
					lhdr := &link.Header{}
					msg := &rtnetlink.Message{Header: lhdr}
					err = msg.UnmarshalNetlink(ii.Body)
					if err == nil {
						lh = &LinkHandler{h: self.h, cache: msg}
					}
				}
			}
			close(mch)
		}
	}
	return
}
示例#3
0
func main() {
	// This imitates the functionality of rtnl_wilddump_req_filter from bridge/vlan.c in the
	// iproute2 code. Note that the filter requires kernel 3.9 or newer
	data := make([]byte, 4)
	binary.LittleEndian.PutUint32(data, link.RTEXT_FILTER_BRVLAN)
	lnmsg := link.NewHeader(rtnetlink.AF_BRIDGE, 0, 0, 0, 0)
	msg := rtnetlink.NewMessage(lnmsg, []netlink.Attribute{{link.IFLA_EXT_MASK, data}})
	nlmsg, err := netlink.NewMessage(rtnetlink.RTM_GETLINK, netlink.NLM_F_DUMP|netlink.NLM_F_REQUEST, msg)
	if err != nil {
		log.Panicf("Couldn't construct message: %v", err)
	}
	nlsock, err := netlink.Dial(netlink.NETLINK_ROUTE)
	if err != nil {
		log.Panicf("Couldn't dial netlink: %v", err)
	}
	h := netlink.NewHandler(nlsock)
	ec := make(chan error)
	go h.Start(ec)
	c, err := h.Query(*nlmsg, 1)
	if err != nil {
		log.Panicf("Couldn't write netlink: %v", err)
	}
	for i := range c {
		if i.Header.MessageType() == netlink.NLMSG_DONE {
			break
		}
		switch i.Header.MessageType() {
		case rtnetlink.RTM_NEWLINK:
			hdr := &link.Header{}
			msg := rtnetlink.NewMessage(hdr, nil)
			err = msg.UnmarshalNetlink(i.Body)
			if err == nil {
				log.Printf("Link[%d] (Family: %v; Type: %v; Flags: %v; Changes: %v)",
					hdr.InterfaceIndex(),
					hdr.InterfaceFamily(), hdr.InterfaceType(), hdr.Flags(),
					hdr.InterfaceChanges())
				for i := range msg.Attributes {
					log.Printf("Attribute[%d]: %v", i, msg.Attributes[i])
				}
			} else {
				log.Printf("Unmarshal error: %v", err)
			}
		default:
			log.Printf("Unknown type: %v", i)
		}
	}
}
示例#4
0
文件: links.go 项目: yetu/go-netlink
func (self *linkFinder) GetLinks() (lhs []*LinkHandler, err error) {
	qry, err := netlink.NewMessage(rtnetlink.RTM_GETLINK, netlink.NLM_F_REQUEST|netlink.NLM_F_ROOT,
		link.NewHeader(rtnetlink.AF_UNSPEC, 0, 0, 0, 0))
	if err != nil {
		return
	}
	var mch chan netlink.Message
	mch, err = self.h.Query(*qry, 1)
	if err == nil {
		for ii := range mch {
			if ii.Header.MessageType() == netlink.NLMSG_DONE {
				break
			}
			switch ii.Header.MessageType() {
			default:
				err = errors.New("Unknown message type in response to RTM_GETLINK")
			case netlink.NLMSG_ERROR:
				emsg := &netlink.Error{}
				err = emsg.UnmarshalNetlink(ii.Body)
				if err == nil && emsg.Code() != 0 {
					err = emsg
				}
			case rtnetlink.RTM_NEWLINK:
				lhdr := &link.Header{}
				msg := &rtnetlink.Message{Header: lhdr}
				err = msg.UnmarshalNetlink(ii.Body)
				if err == nil {
					lhs = append(lhs, &LinkHandler{h: self.h, cache: msg})
				}
			}
			if err != nil {
				log.Printf("Internal netlink failure: %v", err)
			}
		}
	}
	close(mch)
	return
}