diff --git a/nlmanager/nlmanager.py b/nlmanager/nlmanager.py index 438da09..58ed9d0 100644 --- a/nlmanager/nlmanager.py +++ b/nlmanager/nlmanager.py @@ -587,3 +587,42 @@ class NetlinkManager(object): nbr.add_attribute(Neighbor.NDA_LLADDR, mac) nbr.build_message(self.sequence.next(), self.pid) return self.tx_nlpacket(nbr) + + def link_add_vxlan(self, ifname, vxlanid, dstport=None, local=None, + group=None, learning='on', ageing=None): + + debug = RTM_NEWLINK in self.debug + + info_data = {Link.IFLA_VXLAN_ID: int(vxlanid)} + if dstport: + info_data[Link.IFLA_VXLAN_PORT] = int(dstport) + if local: + info_data[Link.IFLA_VXLAN_LOCAL] = local + if group: + info_data[Link.IFLA_VXLAN_GROUP] = group + + learning = 0 if learning == 'off' else 1 + info_data[Link.IFLA_VXLAN_LEARNING] = learning + + ifindex = self.get_iface_index(ifname) + if ifindex: + info_data[Link.IFLA_VXLAN_LINK] = ifindex + + if ageing: + info_data[Link.IFLA_VXLAN_AGEING] = int(ageing) + + link = Link(RTM_NEWLINK, debug) + link.flags = NLM_F_CREATE | NLM_F_REQUEST + link.body = pack('Bxxxiii', socket.AF_UNSPEC, 0, 0, 0) + link.add_attribute(Link.IFLA_IFNAME, ifname) + + if ifindex: + link.add_attribute(Link.IFLA_LINK, ifindex) + + link.add_attribute(Link.IFLA_LINKINFO, { + Link.IFLA_INFO_KIND: "vxlan", + Link.IFLA_INFO_DATA: info_data + }) + + link.build_message(self.sequence.next(), self.pid) + return self.tx_nlpacket(link) diff --git a/nlmanager/nlpacket.py b/nlmanager/nlpacket.py index 83e8c12..ac474d3 100644 --- a/nlmanager/nlpacket.py +++ b/nlmanager/nlpacket.py @@ -718,7 +718,7 @@ class AttributeIFLA_LINKINFO(Attribute): kind = self.value[Link.IFLA_INFO_KIND] - if kind not in ('vlan', 'macvlan'): + if kind not in ('vlan', 'macvlan', 'vxlan'): raise Exception('Unsupported IFLA_INFO_KIND %s' % kind) # For now this assumes that all data will be packed in the native endian @@ -770,6 +770,64 @@ class AttributeIFLA_LINKINFO(Attribute): else: self.log.debug('Add support for encoding IFLA_INFO_DATA macvlan sub-attribute type %d' % info_data_type) + elif kind == 'vxlan': + if info_data_type in (Link.IFLA_VXLAN_ID, + Link.IFLA_VXLAN_LINK, + Link.IFLA_VXLAN_AGEING, + Link.IFLA_VXLAN_LIMIT, + Link.IFLA_VXLAN_PORT_RANGE): + sub_attr_pack_layout.append('HH') + sub_attr_payload.append(8) # length + sub_attr_payload.append(info_data_type) + + sub_attr_pack_layout.append('L') + sub_attr_payload.append(info_data_value) + + elif info_data_type in (Link.IFLA_VXLAN_GROUP, + Link.IFLA_VXLAN_LOCAL): + sub_attr_pack_layout.append('HH') + sub_attr_payload.append(8) # length + sub_attr_payload.append(info_data_type) + + sub_attr_pack_layout.append('L') + + reorder = unpack('