mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-28 11:25:21 +01:00
Add a transport neutral kernel snapshot for NIC-specific SR-IOV VF status and an optional iflib provider method. Providers gather state under driver defined synchronization. Honor RTEXT_FILTER_VF on RTM_GETLINK requests and encode the status as native typed route Netlink attributes. Represent VFs, driver namespaces, and namespace fields as directly repeated nested attributes. Presence masks in consumers can distinguish omission from false or zero. Drivers may add custom status under stable, versioned namespaces. The named, typed representation lets generic transports and consumers carry or display fields without knowing their driver-specific schemas, while the driver retains ownership of their names and meanings. Document the ABI and add parser and RTM_GETLINK coverage. Reviewed by: melifaro, iflib (gallatin), kgalazka (previous version) Sponsored by: BBOX.io Differential Revision: https://reviews.freebsd.org/D58776
955 lines
26 KiB
Python
955 lines
26 KiB
Python
import socket
|
|
import struct
|
|
from ctypes import c_int
|
|
from ctypes import c_ubyte
|
|
from ctypes import c_uint
|
|
from ctypes import c_ushort
|
|
from ctypes import sizeof
|
|
from ctypes import Structure
|
|
from enum import auto
|
|
from enum import Enum
|
|
|
|
from atf_python.sys.netlink.attrs import NlAttr
|
|
from atf_python.sys.netlink.attrs import NlAttrIp
|
|
from atf_python.sys.netlink.attrs import NlAttrNested
|
|
from atf_python.sys.netlink.attrs import NlAttrStr
|
|
from atf_python.sys.netlink.attrs import NlAttrU16
|
|
from atf_python.sys.netlink.attrs import NlAttrU32
|
|
from atf_python.sys.netlink.attrs import NlAttrU64
|
|
from atf_python.sys.netlink.attrs import NlAttrU8
|
|
from atf_python.sys.netlink.message import StdNetlinkMessage
|
|
from atf_python.sys.netlink.message import NlMsgProps
|
|
from atf_python.sys.netlink.message import NlMsgCategory
|
|
from atf_python.sys.netlink.utils import AttrDescr
|
|
from atf_python.sys.netlink.utils import get_bitmask_str
|
|
from atf_python.sys.netlink.utils import prepare_attrs_map
|
|
|
|
|
|
class RtattrType(Enum):
|
|
RTA_UNSPEC = 0
|
|
RTA_DST = 1
|
|
RTA_SRC = 2
|
|
RTA_IIF = 3
|
|
RTA_OIF = 4
|
|
RTA_GATEWAY = 5
|
|
RTA_PRIORITY = 6
|
|
RTA_PREFSRC = 7
|
|
RTA_METRICS = 8
|
|
RTA_MULTIPATH = 9
|
|
# RTA_PROTOINFO = 10
|
|
RTA_KNH_ID = 10
|
|
RTA_FLOW = 11
|
|
RTA_CACHEINFO = 12
|
|
RTA_SESSION = 13
|
|
# RTA_MP_ALGO = 14
|
|
RTA_RTFLAGS = 14
|
|
RTA_TABLE = 15
|
|
RTA_MARK = 16
|
|
RTA_MFC_STATS = 17
|
|
RTA_VIA = 18
|
|
RTA_NEWDST = 19
|
|
RTA_PREF = 20
|
|
RTA_ENCAP_TYPE = 21
|
|
RTA_ENCAP = 22
|
|
RTA_EXPIRES = 23
|
|
RTA_PAD = 24
|
|
RTA_UID = 25
|
|
RTA_TTL_PROPAGATE = 26
|
|
RTA_IP_PROTO = 27
|
|
RTA_SPORT = 28
|
|
RTA_DPORT = 29
|
|
RTA_NH_ID = 30
|
|
|
|
|
|
class NlRtMsgType(Enum):
|
|
RTM_NEWLINK = 16
|
|
RTM_DELLINK = 17
|
|
RTM_GETLINK = 18
|
|
RTM_SETLINK = 19
|
|
RTM_NEWADDR = 20
|
|
RTM_DELADDR = 21
|
|
RTM_GETADDR = 22
|
|
RTM_NEWROUTE = 24
|
|
RTM_DELROUTE = 25
|
|
RTM_GETROUTE = 26
|
|
RTM_NEWNEIGH = 28
|
|
RTM_DELNEIGH = 29
|
|
RTM_GETNEIGH = 30
|
|
RTM_NEWRULE = 32
|
|
RTM_DELRULE = 33
|
|
RTM_GETRULE = 34
|
|
RTM_NEWQDISC = 36
|
|
RTM_DELQDISC = 37
|
|
RTM_GETQDISC = 38
|
|
RTM_NEWTCLASS = 40
|
|
RTM_DELTCLASS = 41
|
|
RTM_GETTCLASS = 42
|
|
RTM_NEWTFILTER = 44
|
|
RTM_DELTFILTER = 45
|
|
RTM_GETTFILTER = 46
|
|
RTM_NEWACTION = 48
|
|
RTM_DELACTION = 49
|
|
RTM_GETACTION = 50
|
|
RTM_NEWPREFIX = 52
|
|
RTM_GETMULTICAST = 58
|
|
RTM_GETANYCAST = 62
|
|
RTM_NEWNEIGHTBL = 64
|
|
RTM_GETNEIGHTBL = 66
|
|
RTM_SETNEIGHTBL = 67
|
|
RTM_NEWNDUSEROPT = 68
|
|
RTM_NEWADDRLABEL = 72
|
|
RTM_DELADDRLABEL = 73
|
|
RTM_GETADDRLABEL = 74
|
|
RTM_GETDCB = 78
|
|
RTM_SETDCB = 79
|
|
RTM_NEWNETCONF = 80
|
|
RTM_GETNETCONF = 82
|
|
RTM_NEWMDB = 84
|
|
RTM_DELMDB = 85
|
|
RTM_GETMDB = 86
|
|
RTM_NEWNSID = 88
|
|
RTM_DELNSID = 89
|
|
RTM_GETNSID = 90
|
|
RTM_NEWSTATS = 92
|
|
RTM_GETSTATS = 94
|
|
|
|
|
|
class RtAttr(Structure):
|
|
_fields_ = [
|
|
("rta_len", c_ushort),
|
|
("rta_type", c_ushort),
|
|
]
|
|
|
|
|
|
class RtMsgHdr(Structure):
|
|
_fields_ = [
|
|
("rtm_family", c_ubyte),
|
|
("rtm_dst_len", c_ubyte),
|
|
("rtm_src_len", c_ubyte),
|
|
("rtm_tos", c_ubyte),
|
|
("rtm_table", c_ubyte),
|
|
("rtm_protocol", c_ubyte),
|
|
("rtm_scope", c_ubyte),
|
|
("rtm_type", c_ubyte),
|
|
("rtm_flags", c_uint),
|
|
]
|
|
|
|
|
|
class RtMsgFlags(Enum):
|
|
RTM_F_NOTIFY = 0x100
|
|
RTM_F_CLONED = 0x200
|
|
RTM_F_EQUALIZE = 0x400
|
|
RTM_F_PREFIX = 0x800
|
|
RTM_F_LOOKUP_TABLE = 0x1000
|
|
RTM_F_FIB_MATCH = 0x2000
|
|
RTM_F_OFFLOAD = 0x4000
|
|
RTM_F_TRAP = 0x8000
|
|
RTM_F_OFFLOAD_FAILED = 0x20000000
|
|
|
|
|
|
class RtScope(Enum):
|
|
RT_SCOPE_UNIVERSE = 0
|
|
RT_SCOPE_SITE = 200
|
|
RT_SCOPE_LINK = 253
|
|
RT_SCOPE_HOST = 254
|
|
RT_SCOPE_NOWHERE = 255
|
|
|
|
|
|
class RtType(Enum):
|
|
RTN_UNSPEC = 0
|
|
RTN_UNICAST = auto()
|
|
RTN_LOCAL = auto()
|
|
RTN_BROADCAST = auto()
|
|
RTN_ANYCAST = auto()
|
|
RTN_MULTICAST = auto()
|
|
RTN_BLACKHOLE = auto()
|
|
RTN_UNREACHABLE = auto()
|
|
RTN_PROHIBIT = auto()
|
|
RTN_THROW = auto()
|
|
RTN_NAT = auto()
|
|
RTN_XRESOLVE = auto()
|
|
|
|
|
|
class RtProto(Enum):
|
|
RTPROT_UNSPEC = 0
|
|
RTPROT_REDIRECT = 1
|
|
RTPROT_KERNEL = 2
|
|
RTPROT_BOOT = 3
|
|
RTPROT_STATIC = 4
|
|
RTPROT_GATED = 8
|
|
RTPROT_RA = 9
|
|
RTPROT_MRT = 10
|
|
RTPROT_ZEBRA = 11
|
|
RTPROT_BIRD = 12
|
|
RTPROT_DNROUTED = 13
|
|
RTPROT_XORP = 14
|
|
RTPROT_NTK = 15
|
|
RTPROT_DHCP = 16
|
|
RTPROT_MROUTED = 17
|
|
RTPROT_KEEPALIVED = 18
|
|
RTPROT_BABEL = 42
|
|
RTPROT_OPENR = 99
|
|
RTPROT_BGP = 186
|
|
RTPROT_ISIS = 187
|
|
RTPROT_OSPF = 188
|
|
RTPROT_RIP = 189
|
|
RTPROT_EIGRP = 192
|
|
|
|
|
|
class NlRtaxType(Enum):
|
|
RTAX_UNSPEC = 0
|
|
RTAX_LOCK = auto()
|
|
RTAX_MTU = auto()
|
|
RTAX_WINDOW = auto()
|
|
RTAX_RTT = auto()
|
|
RTAX_RTTVAR = auto()
|
|
RTAX_SSTHRESH = auto()
|
|
RTAX_CWND = auto()
|
|
RTAX_ADVMSS = auto()
|
|
RTAX_REORDERING = auto()
|
|
RTAX_HOPLIMIT = auto()
|
|
RTAX_INITCWND = auto()
|
|
RTAX_FEATURES = auto()
|
|
RTAX_RTO_MIN = auto()
|
|
RTAX_INITRWND = auto()
|
|
RTAX_QUICKACK = auto()
|
|
RTAX_CC_ALGO = auto()
|
|
RTAX_FASTOPEN_NO_COOKIE = auto()
|
|
|
|
|
|
class RtFlagsBSD(Enum):
|
|
RTF_UP = 0x1
|
|
RTF_GATEWAY = 0x2
|
|
RTF_HOST = 0x4
|
|
RTF_REJECT = 0x8
|
|
RTF_DYNAMIC = 0x10
|
|
RTF_MODIFIED = 0x20
|
|
RTF_DONE = 0x40
|
|
RTF_XRESOLVE = 0x200
|
|
RTF_LLINFO = 0x400
|
|
RTF_LLDATA = 0x400
|
|
RTF_STATIC = 0x800
|
|
RTF_BLACKHOLE = 0x1000
|
|
RTF_PROTO2 = 0x4000
|
|
RTF_PROTO1 = 0x8000
|
|
RTF_PROTO3 = 0x40000
|
|
RTF_FIXEDMTU = 0x80000
|
|
RTF_PINNED = 0x100000
|
|
RTF_LOCAL = 0x200000
|
|
RTF_BROADCAST = 0x400000
|
|
RTF_MULTICAST = 0x800000
|
|
RTF_STICKY = 0x10000000
|
|
RTF_RNH_LOCKED = 0x40000000
|
|
RTF_GWFLAG_COMPAT = 0x80000000
|
|
|
|
|
|
class NlRtGroup(Enum):
|
|
RTNLGRP_NONE = 0
|
|
RTNLGRP_LINK = auto()
|
|
RTNLGRP_NOTIFY = auto()
|
|
RTNLGRP_NEIGH = auto()
|
|
RTNLGRP_TC = auto()
|
|
RTNLGRP_IPV4_IFADDR = auto()
|
|
RTNLGRP_IPV4_MROUTE = auto()
|
|
RTNLGRP_IPV4_ROUTE = auto()
|
|
RTNLGRP_IPV4_RULE = auto()
|
|
RTNLGRP_IPV6_IFADDR = auto()
|
|
RTNLGRP_IPV6_MROUTE = auto()
|
|
RTNLGRP_IPV6_ROUTE = auto()
|
|
RTNLGRP_IPV6_IFINFO = auto()
|
|
RTNLGRP_DECnet_IFADDR = auto()
|
|
RTNLGRP_NOP2 = auto()
|
|
RTNLGRP_DECnet_ROUTE = auto()
|
|
RTNLGRP_DECnet_RULE = auto()
|
|
RTNLGRP_NOP4 = auto()
|
|
RTNLGRP_IPV6_PREFIX = auto()
|
|
RTNLGRP_IPV6_RULE = auto()
|
|
RTNLGRP_ND_USEROPT = auto()
|
|
RTNLGRP_PHONET_IFADDR = auto()
|
|
RTNLGRP_PHONET_ROUTE = auto()
|
|
RTNLGRP_DCB = auto()
|
|
RTNLGRP_IPV4_NETCONF = auto()
|
|
RTNLGRP_IPV6_NETCONF = auto()
|
|
RTNLGRP_MDB = auto()
|
|
RTNLGRP_MPLS_ROUTE = auto()
|
|
RTNLGRP_NSID = auto()
|
|
RTNLGRP_MPLS_NETCONF = auto()
|
|
RTNLGRP_IPV4_MROUTE_R = auto()
|
|
RTNLGRP_IPV6_MROUTE_R = auto()
|
|
RTNLGRP_NEXTHOP = auto()
|
|
RTNLGRP_BRVLAN = auto()
|
|
|
|
|
|
class IfinfoMsg(Structure):
|
|
_fields_ = [
|
|
("ifi_family", c_ubyte),
|
|
("__ifi_pad", c_ubyte),
|
|
("ifi_type", c_ushort),
|
|
("ifi_index", c_int),
|
|
("ifi_flags", c_uint),
|
|
("ifi_change", c_uint),
|
|
]
|
|
|
|
|
|
class IflattrType(Enum):
|
|
IFLA_UNSPEC = 0
|
|
IFLA_ADDRESS = 1
|
|
IFLA_BROADCAST = 2
|
|
IFLA_IFNAME = 3
|
|
IFLA_MTU = 4
|
|
IFLA_LINK = 5
|
|
IFLA_QDISC = 6
|
|
IFLA_STATS = 7
|
|
IFLA_COST = 8
|
|
IFLA_PRIORITY = 9
|
|
IFLA_MASTER = 10
|
|
IFLA_WIRELESS = 11
|
|
IFLA_PROTINFO = 12
|
|
IFLA_TXQLEN = 13
|
|
IFLA_MAP = 14
|
|
IFLA_WEIGHT = 15
|
|
IFLA_OPERSTATE = 16
|
|
IFLA_LINKMODE = 17
|
|
IFLA_LINKINFO = 18
|
|
IFLA_NET_NS_PID = 19
|
|
IFLA_IFALIAS = 20
|
|
IFLA_NUM_VF = 21
|
|
IFLA_VFINFO_LIST = 22
|
|
IFLA_STATS64 = 23
|
|
IFLA_VF_PORTS = 24
|
|
IFLA_PORT_SELF = 25
|
|
IFLA_AF_SPEC = 26
|
|
IFLA_GROUP = 27
|
|
IFLA_NET_NS_FD = 28
|
|
IFLA_EXT_MASK = 29
|
|
IFLA_PROMISCUITY = 30
|
|
IFLA_NUM_TX_QUEUES = 31
|
|
IFLA_NUM_RX_QUEUES = 32
|
|
IFLA_CARRIER = 33
|
|
IFLA_PHYS_PORT_ID = 34
|
|
IFLA_CARRIER_CHANGES = 35
|
|
IFLA_PHYS_SWITCH_ID = 36
|
|
IFLA_LINK_NETNSID = 37
|
|
IFLA_PHYS_PORT_NAME = 38
|
|
IFLA_PROTO_DOWN = 39
|
|
IFLA_GSO_MAX_SEGS = 40
|
|
IFLA_GSO_MAX_SIZE = 41
|
|
IFLA_PAD = 42
|
|
IFLA_XDP = 43
|
|
IFLA_EVENT = 44
|
|
IFLA_NEW_NETNSID = 45
|
|
IFLA_IF_NETNSID = 46
|
|
IFLA_CARRIER_UP_COUNT = 47
|
|
IFLA_CARRIER_DOWN_COUNT = 48
|
|
IFLA_NEW_IFINDEX = 49
|
|
IFLA_MIN_MTU = 50
|
|
IFLA_MAX_MTU = 51
|
|
IFLA_PROP_LIST = 52
|
|
IFLA_ALT_IFNAME = 53
|
|
IFLA_PERM_ADDRESS = 54
|
|
IFLA_PROTO_DOWN_REASON = 55
|
|
IFLA_PARENT_DEV_NAME = 56
|
|
IFLA_PARENT_DEV_BUS_NAME = 57
|
|
IFLA_GRO_MAX_SIZE = 58
|
|
IFLA_TSO_MAX_SEGS = 59
|
|
IFLA_ALLMULTI = 60
|
|
IFLA_DEVLINK_PORT = 61
|
|
IFLA_GSO_IPV4_MAX_SIZE = 62
|
|
IFLA_GRO_IPV4_MAX_SIZE = 63
|
|
IFLA_FREEBSD = 64
|
|
IFLA_FREEBSD_VF = 65
|
|
|
|
|
|
class IflafAttrType(Enum):
|
|
IFLAF_UNSPEC = 0
|
|
IFLAF_ORIG_IFNAME = 1
|
|
IFLAF_ORIG_HWADDR = 2
|
|
IFLAF_CAPS = 3
|
|
IFLAF_VF_STATUS = 5
|
|
|
|
|
|
class IflafVfStatusType(Enum):
|
|
IFLAF_VFS_UNSPEC = 0
|
|
IFLAF_VFS_ERROR = 1
|
|
IFLAF_VFS_PF_LINK_STATE = 2
|
|
IFLAF_VFS_PF_LINK_SPEED = 3
|
|
|
|
|
|
class IflafVfType(Enum):
|
|
IFLAF_VF_UNSPEC = 0
|
|
IFLAF_VF_INDEX = 1
|
|
IFLAF_VF_CONFIGURED = 2
|
|
IFLAF_VF_INITIALIZED = 3
|
|
IFLAF_VF_MAC = 4
|
|
IFLAF_VF_VLAN_MODE = 5
|
|
IFLAF_VF_VLAN = 6
|
|
IFLAF_VF_VLAN_PCP = 7
|
|
IFLAF_VF_VLAN_PROTO = 8
|
|
IFLAF_VF_VLAN_COUNT = 9
|
|
IFLAF_VF_VLAN_LIMIT = 10
|
|
IFLAF_VF_NUM_TX_QUEUES = 11
|
|
IFLAF_VF_NUM_RX_QUEUES = 12
|
|
IFLAF_VF_MIN_TX_RATE = 13
|
|
IFLAF_VF_MAX_TX_RATE = 14
|
|
IFLAF_VF_ALLOW_SET_MAC = 15
|
|
IFLAF_VF_ALLOW_SET_VLAN = 16
|
|
IFLAF_VF_MAC_ANTI_SPOOF = 17
|
|
IFLAF_VF_ALLOW_PROMISC = 18
|
|
IFLAF_VF_TRAFFIC_ALLOWED = 19
|
|
IFLAF_VF_FAULT_BLOCKED = 20
|
|
IFLAF_VF_QUARANTINED = 21
|
|
IFLAF_VF_API_VERSION = 22
|
|
IFLAF_VF_LINK_STATE_POLICY = 23
|
|
IFLAF_VF_DRIVER = 24
|
|
|
|
|
|
class IflafVfDriverType(Enum):
|
|
IFLAF_VFD_UNSPEC = 0
|
|
IFLAF_VFD_NAME = 1
|
|
IFLAF_VFD_VERSION = 2
|
|
IFLAF_VFD_FIELD = 3
|
|
|
|
|
|
class IflafVfDriverFieldType(Enum):
|
|
IFLAF_VFDF_UNSPEC = 0
|
|
IFLAF_VFDF_NAME = 1
|
|
IFLAF_VFDF_BOOL = 2
|
|
IFLAF_VFDF_NUMBER = 3
|
|
IFLAF_VFDF_STRING = 4
|
|
IFLAF_VFDF_BINARY = 5
|
|
|
|
|
|
class IflinkInfo(Enum):
|
|
IFLA_INFO_UNSPEC = 0
|
|
IFLA_INFO_KIND = auto()
|
|
IFLA_INFO_DATA = auto()
|
|
IFLA_INFO_XSTATS = auto()
|
|
IFLA_INFO_SLAVE_KIND = auto()
|
|
IFLA_INFO_SLAVE_DATA = auto()
|
|
|
|
|
|
class IfLinkInfoDataVlan(Enum):
|
|
IFLA_VLAN_UNSPEC = 0
|
|
IFLA_VLAN_ID = auto()
|
|
IFLA_VLAN_FLAGS = auto()
|
|
IFLA_VLAN_EGRESS_QOS = auto()
|
|
IFLA_VLAN_INGRESS_QOS = auto()
|
|
IFLA_VLAN_PROTOCOL = auto()
|
|
|
|
|
|
class IfaddrMsg(Structure):
|
|
_fields_ = [
|
|
("ifa_family", c_ubyte),
|
|
("ifa_prefixlen", c_ubyte),
|
|
("ifa_flags", c_ubyte),
|
|
("ifa_scope", c_ubyte),
|
|
("ifa_index", c_uint),
|
|
]
|
|
|
|
|
|
class IfaAttrType(Enum):
|
|
IFA_UNSPEC = 0
|
|
IFA_ADDRESS = 1
|
|
IFA_LOCAL = 2
|
|
IFA_LABEL = 3
|
|
IFA_BROADCAST = 4
|
|
IFA_ANYCAST = 5
|
|
IFA_CACHEINFO = 6
|
|
IFA_MULTICAST = 7
|
|
IFA_FLAGS = 8
|
|
IFA_RT_PRIORITY = 9
|
|
IFA_TARGET_NETNSID = 10
|
|
IFA_FREEBSD = 11
|
|
|
|
|
|
class IfafAttrType(Enum):
|
|
IFAF_UNSPEC = 0
|
|
IFAF_VHID = 1
|
|
IFAF_FLAGS = 2
|
|
|
|
|
|
class IfaCacheInfo(Structure):
|
|
_fields_ = [
|
|
("ifa_prefered", c_uint), # seconds till the end of the prefix considered preferred
|
|
("ifa_valid", c_uint), # seconds till the end of the prefix considered valid
|
|
("cstamp", c_uint), # creation time in 1ms intervals from the boot time
|
|
("tstamp", c_uint), # update time in 1ms intervals from the boot time
|
|
]
|
|
|
|
|
|
class IfaFlags(Enum):
|
|
IFA_F_TEMPORARY = 0x01
|
|
IFA_F_NODAD = 0x02
|
|
IFA_F_OPTIMISTIC = 0x04
|
|
IFA_F_DADFAILED = 0x08
|
|
IFA_F_HOMEADDRESS = 0x10
|
|
IFA_F_DEPRECATED = 0x20
|
|
IFA_F_TENTATIVE = 0x40
|
|
IFA_F_PERMANENT = 0x80
|
|
IFA_F_MANAGETEMPADDR = 0x100
|
|
IFA_F_NOPREFIXROUTE = 0x200
|
|
IFA_F_MCAUTOJOIN = 0x400
|
|
IFA_F_STABLE_PRIVACY = 0x800
|
|
|
|
|
|
class IfafFlags6(Enum):
|
|
IN6_IFF_ANYCAST = 0x01
|
|
IN6_IFF_TENTATIVE = 0x02
|
|
IN6_IFF_DUPLICATED = 0x04
|
|
IN6_IFF_DETACHED = 0x08
|
|
IN6_IFF_DEPRECATED = 0x10
|
|
IN6_IFF_NODAD = 0x20
|
|
IN6_IFF_AUTOCONF = 0x40
|
|
IN6_IFF_TEMPORARY = 0x80
|
|
IN6_IFF_PREFER_SOURCE = 0x100
|
|
|
|
|
|
class NdMsg(Structure):
|
|
_fields_ = [
|
|
("ndm_family", c_ubyte),
|
|
("ndm_pad1", c_ubyte),
|
|
("ndm_pad2", c_ubyte),
|
|
("ndm_ifindex", c_uint),
|
|
("ndm_state", c_ushort),
|
|
("ndm_flags", c_ubyte),
|
|
("ndm_type", c_ubyte),
|
|
]
|
|
|
|
|
|
class NdAttrType(Enum):
|
|
NDA_UNSPEC = 0
|
|
NDA_DST = 1
|
|
NDA_LLADDR = 2
|
|
NDA_CACHEINFO = 3
|
|
NDA_PROBES = 4
|
|
NDA_VLAN = 5
|
|
NDA_PORT = 6
|
|
NDA_VNI = 7
|
|
NDA_IFINDEX = 8
|
|
NDA_MASTER = 9
|
|
NDA_LINK_NETNSID = 10
|
|
NDA_SRC_VNI = 11
|
|
NDA_PROTOCOL = 12
|
|
NDA_NH_ID = 13
|
|
NDA_FDB_EXT_ATTRS = 14
|
|
NDA_FLAGS_EXT = 15
|
|
NDA_NDM_STATE_MASK = 16
|
|
NDA_NDM_FLAGS_MASK = 17
|
|
|
|
|
|
class NlAttrRtFlags(NlAttrU32):
|
|
def _print_attr_value(self):
|
|
s = get_bitmask_str(RtFlagsBSD, self.u32)
|
|
return " rtflags={}".format(s)
|
|
|
|
|
|
class NlAttrIfindex(NlAttrU32):
|
|
def _print_attr_value(self):
|
|
try:
|
|
ifname = socket.if_indextoname(self.u32)
|
|
return " iface={}(#{})".format(ifname, self.u32)
|
|
except OSError:
|
|
pass
|
|
return " iface=if#{}".format(self.u32)
|
|
|
|
|
|
class NlAttrTable(NlAttrU32):
|
|
def _print_attr_value(self):
|
|
return " rtable={}".format(self.u32)
|
|
|
|
|
|
class NlAttrNhId(NlAttrU32):
|
|
def _print_attr_value(self):
|
|
return " nh_id={}".format(self.u32)
|
|
|
|
|
|
class NlAttrKNhId(NlAttrU32):
|
|
def _print_attr_value(self):
|
|
return " knh_id={}".format(self.u32)
|
|
|
|
|
|
class NlAttrMac(NlAttr):
|
|
def _print_attr_value(self):
|
|
return ' mac="' + ":".join(["{:02X}".format(b) for b in self._data]) + '"'
|
|
|
|
|
|
class NlAttrIfStats(NlAttr):
|
|
def _print_attr_value(self):
|
|
return " stats={...}"
|
|
|
|
|
|
class NlAttrCacheInfo(NlAttr):
|
|
def __init__(self, nla_type, data):
|
|
super().__init__(nla_type, data)
|
|
self.ci = IfaCacheInfo.from_buffer_copy(data)
|
|
|
|
@staticmethod
|
|
def _validate(data):
|
|
nla_len, nla_type = struct.unpack("@HH", data[:4])
|
|
data_len = nla_len - 4
|
|
if data_len != sizeof(IfaCacheInfo):
|
|
raise ValueError(
|
|
"Error validating attr {}: wrong size".format(nla_type)
|
|
) # noqa: E501
|
|
|
|
def _print_attr_value(self):
|
|
return " ifa_prefered={} ifa_valid={} cstamp={} tstamp={}".format(
|
|
self.ci.ifa_prefered, self.ci.ifa_valid, self.ci.cstamp, self.ci.tstamp)
|
|
|
|
|
|
class NlAttrVia(NlAttr):
|
|
def __init__(self, nla_type, family, addr: str):
|
|
super().__init__(nla_type, b"")
|
|
self.addr = addr
|
|
self.family = family
|
|
|
|
@staticmethod
|
|
def _validate(data):
|
|
nla_len, nla_type = struct.unpack("@HH", data[:4])
|
|
data_len = nla_len - 4
|
|
if data_len == 0:
|
|
raise ValueError(
|
|
"Error validating attr {}: empty data".format(nla_type)
|
|
) # noqa: E501
|
|
family = int(data_len[0])
|
|
if family not in (socket.AF_INET, socket.AF_INET6):
|
|
raise ValueError(
|
|
"Error validating attr {}: unsupported AF {}".format( # noqa: E501
|
|
nla_type, family
|
|
)
|
|
)
|
|
if family == socket.AF_INET:
|
|
expected_len = 1 + 4
|
|
else:
|
|
expected_len = 1 + 16
|
|
if data_len != expected_len:
|
|
raise ValueError(
|
|
"Error validating attr {}: expected len {} got {}".format( # noqa: E501
|
|
nla_type, expected_len, data_len
|
|
)
|
|
)
|
|
|
|
@property
|
|
def nla_len(self):
|
|
if self.family == socket.AF_INET6:
|
|
return 21
|
|
else:
|
|
return 9
|
|
|
|
@classmethod
|
|
def _parse(cls, data):
|
|
nla_len, nla_type, family = struct.unpack("@HHB", data[:5])
|
|
off = 5
|
|
if family == socket.AF_INET:
|
|
addr = socket.inet_ntop(family, data[off:off + 4])
|
|
else:
|
|
addr = socket.inet_ntop(family, data[off:off + 16])
|
|
return cls(nla_type, family, addr)
|
|
|
|
def __bytes__(self):
|
|
addr = socket.inet_pton(self.family, self.addr)
|
|
return self._to_bytes(struct.pack("@B", self.family) + addr)
|
|
|
|
def _print_attr_value(self):
|
|
return " via={}".format(self.addr)
|
|
|
|
|
|
rtnl_route_attrs = prepare_attrs_map(
|
|
[
|
|
AttrDescr(RtattrType.RTA_DST, NlAttrIp),
|
|
AttrDescr(RtattrType.RTA_SRC, NlAttrIp),
|
|
AttrDescr(RtattrType.RTA_IIF, NlAttrIfindex),
|
|
AttrDescr(RtattrType.RTA_OIF, NlAttrIfindex),
|
|
AttrDescr(RtattrType.RTA_GATEWAY, NlAttrIp),
|
|
AttrDescr(RtattrType.RTA_TABLE, NlAttrTable),
|
|
AttrDescr(RtattrType.RTA_PRIORITY, NlAttrU32),
|
|
AttrDescr(RtattrType.RTA_VIA, NlAttrVia),
|
|
AttrDescr(RtattrType.RTA_NH_ID, NlAttrNhId),
|
|
AttrDescr(RtattrType.RTA_KNH_ID, NlAttrKNhId),
|
|
AttrDescr(RtattrType.RTA_RTFLAGS, NlAttrRtFlags),
|
|
AttrDescr(
|
|
RtattrType.RTA_METRICS,
|
|
NlAttrNested,
|
|
[
|
|
AttrDescr(NlRtaxType.RTAX_MTU, NlAttrU32),
|
|
],
|
|
),
|
|
]
|
|
)
|
|
|
|
rtnl_iflaf_vf_driver_field_attrs = [
|
|
AttrDescr(IflafVfDriverFieldType.IFLAF_VFDF_NAME, NlAttrStr),
|
|
AttrDescr(IflafVfDriverFieldType.IFLAF_VFDF_BOOL, NlAttrU8),
|
|
AttrDescr(IflafVfDriverFieldType.IFLAF_VFDF_NUMBER, NlAttrU64),
|
|
AttrDescr(IflafVfDriverFieldType.IFLAF_VFDF_STRING, NlAttrStr),
|
|
AttrDescr(IflafVfDriverFieldType.IFLAF_VFDF_BINARY, NlAttr),
|
|
]
|
|
|
|
rtnl_iflaf_vf_driver_attrs = [
|
|
AttrDescr(IflafVfDriverType.IFLAF_VFD_NAME, NlAttrStr),
|
|
AttrDescr(IflafVfDriverType.IFLAF_VFD_VERSION, NlAttrU32),
|
|
AttrDescr(
|
|
IflafVfDriverType.IFLAF_VFD_FIELD,
|
|
NlAttrNested,
|
|
rtnl_iflaf_vf_driver_field_attrs,
|
|
),
|
|
]
|
|
|
|
rtnl_iflaf_vf_attrs = [
|
|
AttrDescr(IflafVfType.IFLAF_VF_INDEX, NlAttrU32),
|
|
AttrDescr(IflafVfType.IFLAF_VF_CONFIGURED, NlAttrU8),
|
|
AttrDescr(IflafVfType.IFLAF_VF_INITIALIZED, NlAttrU8),
|
|
AttrDescr(IflafVfType.IFLAF_VF_MAC, NlAttrMac),
|
|
AttrDescr(IflafVfType.IFLAF_VF_VLAN_MODE, NlAttrU8),
|
|
AttrDescr(IflafVfType.IFLAF_VF_VLAN, NlAttrU16),
|
|
AttrDescr(IflafVfType.IFLAF_VF_VLAN_PCP, NlAttrU8),
|
|
AttrDescr(IflafVfType.IFLAF_VF_VLAN_PROTO, NlAttrU16),
|
|
AttrDescr(IflafVfType.IFLAF_VF_VLAN_COUNT, NlAttrU32),
|
|
AttrDescr(IflafVfType.IFLAF_VF_VLAN_LIMIT, NlAttrU32),
|
|
AttrDescr(IflafVfType.IFLAF_VF_NUM_TX_QUEUES, NlAttrU16),
|
|
AttrDescr(IflafVfType.IFLAF_VF_NUM_RX_QUEUES, NlAttrU16),
|
|
AttrDescr(IflafVfType.IFLAF_VF_MIN_TX_RATE, NlAttrU64),
|
|
AttrDescr(IflafVfType.IFLAF_VF_MAX_TX_RATE, NlAttrU64),
|
|
AttrDescr(IflafVfType.IFLAF_VF_ALLOW_SET_MAC, NlAttrU8),
|
|
AttrDescr(IflafVfType.IFLAF_VF_ALLOW_SET_VLAN, NlAttrU8),
|
|
AttrDescr(IflafVfType.IFLAF_VF_MAC_ANTI_SPOOF, NlAttrU8),
|
|
AttrDescr(IflafVfType.IFLAF_VF_ALLOW_PROMISC, NlAttrU8),
|
|
AttrDescr(IflafVfType.IFLAF_VF_TRAFFIC_ALLOWED, NlAttrU8),
|
|
AttrDescr(IflafVfType.IFLAF_VF_FAULT_BLOCKED, NlAttrU8),
|
|
AttrDescr(IflafVfType.IFLAF_VF_QUARANTINED, NlAttrU8),
|
|
AttrDescr(IflafVfType.IFLAF_VF_API_VERSION, NlAttrStr),
|
|
AttrDescr(IflafVfType.IFLAF_VF_LINK_STATE_POLICY, NlAttrU8),
|
|
AttrDescr(
|
|
IflafVfType.IFLAF_VF_DRIVER,
|
|
NlAttrNested,
|
|
rtnl_iflaf_vf_driver_attrs,
|
|
),
|
|
]
|
|
|
|
rtnl_iflaf_vf_status_attrs = [
|
|
AttrDescr(IflafVfStatusType.IFLAF_VFS_ERROR, NlAttrU32),
|
|
AttrDescr(IflafVfStatusType.IFLAF_VFS_PF_LINK_STATE, NlAttrU8),
|
|
AttrDescr(IflafVfStatusType.IFLAF_VFS_PF_LINK_SPEED, NlAttrU64),
|
|
]
|
|
|
|
rtnl_ifla_attrs = prepare_attrs_map(
|
|
[
|
|
AttrDescr(IflattrType.IFLA_ADDRESS, NlAttrMac),
|
|
AttrDescr(IflattrType.IFLA_BROADCAST, NlAttrMac),
|
|
AttrDescr(IflattrType.IFLA_IFNAME, NlAttrStr),
|
|
AttrDescr(IflattrType.IFLA_MTU, NlAttrU32),
|
|
AttrDescr(IflattrType.IFLA_LINK, NlAttrU32),
|
|
AttrDescr(IflattrType.IFLA_PROMISCUITY, NlAttrU32),
|
|
AttrDescr(IflattrType.IFLA_OPERSTATE, NlAttrU8),
|
|
AttrDescr(IflattrType.IFLA_CARRIER, NlAttrU8),
|
|
AttrDescr(IflattrType.IFLA_IFALIAS, NlAttrStr),
|
|
AttrDescr(IflattrType.IFLA_NUM_VF, NlAttrU32),
|
|
AttrDescr(IflattrType.IFLA_STATS64, NlAttrIfStats),
|
|
AttrDescr(IflattrType.IFLA_NEW_IFINDEX, NlAttrU32),
|
|
AttrDescr(
|
|
IflattrType.IFLA_LINKINFO,
|
|
NlAttrNested,
|
|
[
|
|
AttrDescr(IflinkInfo.IFLA_INFO_KIND, NlAttrStr),
|
|
AttrDescr(IflinkInfo.IFLA_INFO_DATA, NlAttr),
|
|
],
|
|
),
|
|
AttrDescr(
|
|
IflattrType.IFLA_FREEBSD,
|
|
NlAttrNested,
|
|
[
|
|
AttrDescr(IflafAttrType.IFLAF_ORIG_HWADDR, NlAttrMac),
|
|
AttrDescr(
|
|
IflafAttrType.IFLAF_VF_STATUS,
|
|
NlAttrNested,
|
|
rtnl_iflaf_vf_status_attrs,
|
|
),
|
|
],
|
|
),
|
|
AttrDescr(
|
|
IflattrType.IFLA_FREEBSD_VF,
|
|
NlAttrNested,
|
|
rtnl_iflaf_vf_attrs,
|
|
),
|
|
]
|
|
)
|
|
|
|
rtnl_ifa_attrs = prepare_attrs_map(
|
|
[
|
|
AttrDescr(IfaAttrType.IFA_ADDRESS, NlAttrIp),
|
|
AttrDescr(IfaAttrType.IFA_LOCAL, NlAttrIp),
|
|
AttrDescr(IfaAttrType.IFA_LABEL, NlAttrStr),
|
|
AttrDescr(IfaAttrType.IFA_BROADCAST, NlAttrIp),
|
|
AttrDescr(IfaAttrType.IFA_ANYCAST, NlAttrIp),
|
|
AttrDescr(IfaAttrType.IFA_FLAGS, NlAttrU32),
|
|
AttrDescr(IfaAttrType.IFA_CACHEINFO, NlAttrCacheInfo),
|
|
AttrDescr(
|
|
IfaAttrType.IFA_FREEBSD,
|
|
NlAttrNested,
|
|
[
|
|
AttrDescr(IfafAttrType.IFAF_VHID, NlAttrU32),
|
|
AttrDescr(IfafAttrType.IFAF_FLAGS, NlAttrU32),
|
|
],
|
|
),
|
|
]
|
|
)
|
|
|
|
|
|
rtnl_nd_attrs = prepare_attrs_map(
|
|
[
|
|
AttrDescr(NdAttrType.NDA_DST, NlAttrIp),
|
|
AttrDescr(NdAttrType.NDA_IFINDEX, NlAttrIfindex),
|
|
AttrDescr(NdAttrType.NDA_FLAGS_EXT, NlAttrU32),
|
|
AttrDescr(NdAttrType.NDA_LLADDR, NlAttrMac),
|
|
]
|
|
)
|
|
|
|
|
|
class BaseNetlinkRtMessage(StdNetlinkMessage):
|
|
pass
|
|
|
|
|
|
class NetlinkRtMessage(BaseNetlinkRtMessage):
|
|
messages = [
|
|
NlMsgProps(NlRtMsgType.RTM_NEWROUTE, NlMsgCategory.NEW),
|
|
NlMsgProps(NlRtMsgType.RTM_DELROUTE, NlMsgCategory.DELETE),
|
|
NlMsgProps(NlRtMsgType.RTM_GETROUTE, NlMsgCategory.GET),
|
|
]
|
|
nl_attrs_map = rtnl_route_attrs
|
|
|
|
def __init__(self, helper, nlm_type):
|
|
super().__init__(helper, nlm_type)
|
|
self.base_hdr = RtMsgHdr()
|
|
|
|
def parse_base_header(self, data):
|
|
if len(data) < sizeof(RtMsgHdr):
|
|
raise ValueError("length less than rtmsg header")
|
|
rtm_hdr = RtMsgHdr.from_buffer_copy(data)
|
|
return (rtm_hdr, sizeof(RtMsgHdr))
|
|
|
|
def print_base_header(self, hdr, prepend=""):
|
|
family = self.helper.get_af_name(hdr.rtm_family)
|
|
print(
|
|
"{}family={}, dst_len={}, src_len={}, tos={}, table={}, protocol={}({}), scope={}({}), type={}({}), flags={}({})".format( # noqa: E501
|
|
prepend,
|
|
family,
|
|
hdr.rtm_dst_len,
|
|
hdr.rtm_src_len,
|
|
hdr.rtm_tos,
|
|
hdr.rtm_table,
|
|
self.helper.get_attr_byval(RtProto, hdr.rtm_protocol),
|
|
hdr.rtm_protocol,
|
|
self.helper.get_attr_byval(RtScope, hdr.rtm_scope),
|
|
hdr.rtm_scope,
|
|
self.helper.get_attr_byval(RtType, hdr.rtm_type),
|
|
hdr.rtm_type,
|
|
self.helper.get_bitmask_str(RtMsgFlags, hdr.rtm_flags),
|
|
hdr.rtm_flags,
|
|
)
|
|
)
|
|
|
|
|
|
class NetlinkIflaMessage(BaseNetlinkRtMessage):
|
|
messages = [
|
|
NlMsgProps(NlRtMsgType.RTM_NEWLINK, NlMsgCategory.NEW),
|
|
NlMsgProps(NlRtMsgType.RTM_DELLINK, NlMsgCategory.DELETE),
|
|
NlMsgProps(NlRtMsgType.RTM_GETLINK, NlMsgCategory.GET),
|
|
]
|
|
nl_attrs_map = rtnl_ifla_attrs
|
|
|
|
def __init__(self, helper, nlm_type):
|
|
super().__init__(helper, nlm_type)
|
|
self.base_hdr = IfinfoMsg()
|
|
|
|
def parse_base_header(self, data):
|
|
if len(data) < sizeof(IfinfoMsg):
|
|
raise ValueError("length less than IfinfoMsg header")
|
|
rtm_hdr = IfinfoMsg.from_buffer_copy(data)
|
|
return (rtm_hdr, sizeof(IfinfoMsg))
|
|
|
|
def print_base_header(self, hdr, prepend=""):
|
|
family = self.helper.get_af_name(hdr.ifi_family)
|
|
print(
|
|
"{}family={}, ifi_type={}, ifi_index={}, ifi_flags={}, ifi_change={}".format( # noqa: E501
|
|
prepend,
|
|
family,
|
|
hdr.ifi_type,
|
|
hdr.ifi_index,
|
|
hdr.ifi_flags,
|
|
hdr.ifi_change,
|
|
)
|
|
)
|
|
|
|
|
|
class NetlinkIfaMessage(BaseNetlinkRtMessage):
|
|
messages = [
|
|
NlMsgProps(NlRtMsgType.RTM_NEWADDR, NlMsgCategory.NEW),
|
|
NlMsgProps(NlRtMsgType.RTM_DELADDR, NlMsgCategory.DELETE),
|
|
NlMsgProps(NlRtMsgType.RTM_GETADDR, NlMsgCategory.GET),
|
|
]
|
|
nl_attrs_map = rtnl_ifa_attrs
|
|
|
|
def __init__(self, helper, nlm_type):
|
|
super().__init__(helper, nlm_type)
|
|
self.base_hdr = IfaddrMsg()
|
|
|
|
def parse_base_header(self, data):
|
|
if len(data) < sizeof(IfaddrMsg):
|
|
raise ValueError("length less than IfaddrMsg header")
|
|
rtm_hdr = IfaddrMsg.from_buffer_copy(data)
|
|
return (rtm_hdr, sizeof(IfaddrMsg))
|
|
|
|
def print_base_header(self, hdr, prepend=""):
|
|
family = self.helper.get_af_name(hdr.ifa_family)
|
|
print(
|
|
"{}family={}, ifa_prefixlen={}, ifa_flags={}, ifa_scope={}, ifa_index={}".format( # noqa: E501
|
|
prepend,
|
|
family,
|
|
hdr.ifa_prefixlen,
|
|
hdr.ifa_flags,
|
|
hdr.ifa_scope,
|
|
hdr.ifa_index,
|
|
)
|
|
)
|
|
|
|
|
|
class NetlinkNdMessage(BaseNetlinkRtMessage):
|
|
messages = [
|
|
NlMsgProps(NlRtMsgType.RTM_NEWNEIGH, NlMsgCategory.NEW),
|
|
NlMsgProps(NlRtMsgType.RTM_DELNEIGH, NlMsgCategory.DELETE),
|
|
NlMsgProps(NlRtMsgType.RTM_GETNEIGH, NlMsgCategory.GET),
|
|
]
|
|
nl_attrs_map = rtnl_nd_attrs
|
|
|
|
def __init__(self, helper, nlm_type):
|
|
super().__init__(helper, nlm_type)
|
|
self.base_hdr = NdMsg()
|
|
|
|
def parse_base_header(self, data):
|
|
if len(data) < sizeof(NdMsg):
|
|
raise ValueError("length less than NdMsg header")
|
|
nd_hdr = NdMsg.from_buffer_copy(data)
|
|
return (nd_hdr, sizeof(NdMsg))
|
|
|
|
def print_base_header(self, hdr, prepend=""):
|
|
family = self.helper.get_af_name(hdr.ndm_family)
|
|
print(
|
|
"{}family={}, ndm_ifindex={}, ndm_state={}, ndm_flags={}".format( # noqa: E501
|
|
prepend,
|
|
family,
|
|
hdr.ndm_ifindex,
|
|
hdr.ndm_state,
|
|
hdr.ndm_flags,
|
|
)
|
|
)
|
|
|
|
|
|
handler_classes = {
|
|
"netlink_route": [
|
|
NetlinkRtMessage,
|
|
NetlinkIflaMessage,
|
|
NetlinkIfaMessage,
|
|
NetlinkNdMessage,
|
|
],
|
|
}
|