1
0
mirror of https://github.com/CumulusNetworks/ifupdown2.git synced 2024-05-06 15:54:50 +00:00

nlpacket:: add netconf support (RTM_GETNETCONF/RTM_NEWNETCONF)

$ cd python-nlmanager/examples
$ ./netconf_show.py
    2018-06-01 16:59:02,398   DEBUG: TXed RTM_GETNETCONF, length 32, seq 1, pid 14202, flags 0x0 ()

      Netlink Header
       1: 0x20000000   ...  Length 0x00000020 (32)
       2: 0x52000503  R...  Type 0x0052 (82 - RTM_GETNETCONF), Flags 0x0305 (NLM_F_REQUEST, NLM_F_ACK, NLM_F_DUMP)
       3: 0x01000000  ....  Sequence Number 0x00000001 (1)
       4: 0x7a370000  z7..  Process ID 0x0000377a (14202)
      Service Header
       5: 0x00000000  ....  Family 0x00 (0), Device Type 0x0000 (0 - ARPHRD_NETROM)
       6: 0x00000000  ....  Interface Index 0x00000000 (0)
       7: 0x00000000  ....  Device Flags 0x00000000 ()
       8: 0x00000000  ....  Change Mask 0x00000000
      Attributes

    Attributes Summary
    {}

    2018-06-01 16:59:02,401   DEBUG: RXed RTM_NEWNETCONF, length 68, seq 1, pid 14202, flags 0x2

      Netlink Header
       1: 0x44000000  D...  Length 0x00000044 (68)
       2: 0x50000200  P...  Type 0x0050 (80 - RTM_NEWNETCONF), Flags 0x0002 (NLM_F_MULTI)
       3: 0x01000000  ....  Sequence Number 0x00000001 (1)
       4: 0x7a370000  z7..  Process ID 0x0000377a (14202)
      Service Header
       1: 0x00000002  ....  Family 0x02 (2)
      Attributes
       5: 0x08000100  ....  Length 0x0008 (8), Type 0x0001 (1) NETCONFA_IFINDEX
       6: 0x01000000  ....  1
       7: 0x08000200  ....  Length 0x0008 (8), Type 0x0002 (2) NETCONFA_FORWARDING
       8: 0x01000000  ....  1
       9: 0x08000300  ....  Length 0x0008 (8), Type 0x0003 (3) NETCONFA_RP_FILTER
      10: 0x00000000  ....  0
      11: 0x08000400  ....  Length 0x0008 (8), Type 0x0004 (4) NETCONFA_MC_FORWARDING
      12: 0x00000000  ....  0
      13: 0x08000500  ....  Length 0x0008 (8), Type 0x0005 (5) NETCONFA_PROXY_NEIGH
      14: 0x00000000  ....  0
      15: 0x08000600  ....  Length 0x0008 (8), Type 0x0006 (6) NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN
      16: 0x01000000  ....  1

    Attributes Summary
    {'( 1) NETCONFA_IFINDEX': 1,
     '( 2) NETCONFA_FORWARDING': 1,
     '( 3) NETCONFA_RP_FILTER': 0,
     '( 4) NETCONFA_MC_FORWARDING': 0,
     '( 5) NETCONFA_PROXY_NEIGH': 0,
     '( 6) NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN': 1}

Signed-off-by: Julien Fortin <julien@cumulusnetworks.com>
This commit is contained in:
Julien Fortin
2018-08-29 17:21:54 +02:00
parent d00f527807
commit 3479a0c3bb
2 changed files with 120 additions and 3 deletions

View File

@ -129,6 +129,9 @@ class NetlinkManager(object):
def debug_route(self, enabled):
self._debug_set_clear((RTM_NEWROUTE, RTM_DELROUTE, RTM_GETROUTE), enabled)
def debug_netconf(self, enabled):
self._debug_set_clear((RTM_GETNETCONF, RTM_NEWNETCONF), enabled)
def debug_this_packet(self, mtype):
if mtype in self.debug:
return True
@ -328,6 +331,9 @@ class NetlinkManager(object):
elif msgtype == RTM_NEWROUTE or msgtype == RTM_DELROUTE:
msg = Route(msgtype, nlpacket.debug, use_color=self.use_color)
elif msgtype in (RTM_GETNETCONF, RTM_NEWNETCONF):
msg = Netconf(msgtype, nlpacket.debug, use_color=self.use_color)
else:
raise Exception("RXed unknown netlink message type %s" % msgtype)
@ -1019,3 +1025,20 @@ class NetlinkManager(object):
msg.build_message(self.sequence.next(), self.pid)
return self.tx_nlpacket_get_response(msg)
# =======
# Netconf
# =======
def netconf_dump(self):
"""
The attribute Netconf.NETCONFA_IFINDEX is available but don't let it fool you
it seems like the kernel doesn't really care about this attribute and will dump
everything according of the requested family (AF_UNSPEC for everything).
Device filtering needs to be done afterwards by the user.
"""
debug = RTM_GETNETCONF in self.debug
msg = Netconf(RTM_GETNETCONF, debug, use_color=self.use_color)
msg.body = pack('Bxxxiii', socket.AF_UNSPEC, 0, 0, 0)
msg.flags = NLM_F_REQUEST | NLM_F_DUMP | NLM_F_ACK
msg.build_message(self.sequence.next(), self.pid)
return self.tx_nlpacket_get_response(msg)

View File

@ -71,6 +71,9 @@ RTM_NEWQDISC = 0x24
RTM_DELQDISC = 0x25
RTM_GETQDISC = 0x26
RTM_NEWNETCONF = 80
RTM_GETNETCONF = 82
# Netlink message flags
NLM_F_REQUEST = 0x01 # It is query message.
NLM_F_MULTI = 0x02 # Multipart message, terminated by NLMSG_DONE
@ -2219,7 +2222,9 @@ class NetlinkPacket(object):
RTM_GETROUTE : 'RTM_GETROUTE',
RTM_NEWQDISC : 'RTM_NEWQDISC',
RTM_DELQDISC : 'RTM_DELQDISC',
RTM_GETQDISC : 'RTM_GETQDISC'
RTM_GETQDISC : 'RTM_GETQDISC',
RTM_NEWNETCONF: 'RTM_NEWNETCONF',
RTM_GETNETCONF: 'RTM_GETNETCONF'
}
af_family_to_string = {
@ -2299,7 +2304,7 @@ class NetlinkPacket(object):
foo.append('NLM_F_ECHO')
# Modifiers to GET query
if msg_type in (RTM_GETLINK, RTM_GETADDR, RTM_GETNEIGH, RTM_GETROUTE, RTM_GETQDISC):
if msg_type in (RTM_GETLINK, RTM_GETADDR, RTM_GETNEIGH, RTM_GETROUTE, RTM_GETQDISC, RTM_GETNETCONF):
if flags & NLM_F_DUMP:
foo.append('NLM_F_DUMP')
else:
@ -2433,7 +2438,7 @@ class NetlinkPacket(object):
take the family into account. For now we'll handle this as a special case for
MPLS but long term we may need to make key a tuple of the attr_type and family.
'''
if attr_type == Route.RTA_DST and self.family == AF_MPLS:
if self.msgtype not in (RTM_NEWNETCONF, RTM_GETNETCONF) and attr_type == Route.RTA_DST and self.family == AF_MPLS:
attr_string = 'RTA_DST'
attr_class = AttributeMplsLabel
@ -3721,6 +3726,95 @@ class Link(NetlinkPacket):
return False
class Netconf(Link):
"""
RTM_NEWNETCONF - Service Header
0 1
0 1 2 3 4 5 6 7 8
+-+-+-+-+-+-+-+-+
| Family |
+-+-+-+-+-+-+-+-+
RTM_GETNETCONF - Service Header
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Family | Reserved | Device Type |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Interface Index |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Device Flags |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Change Mask |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
"""
# Netconf attributes
# /usr/include/linux/netconf.h
NETCONFA_UNSPEC = 0
NETCONFA_IFINDEX = 1
NETCONFA_FORWARDING = 2
NETCONFA_RP_FILTER = 3
NETCONFA_MC_FORWARDING = 4
NETCONFA_PROXY_NEIGH = 5
NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN = 6
NETCONFA_INPUT = 7
__NETCONFA_MAX = 8
NETCONFA_MAX = (__NETCONFA_MAX - 1)
NETCONFA_ALL = -1
NETCONFA_IFINDEX_ALL = -1
NETCONFA_IFINDEX_DEFAULT = -2
NETCONF_ATTR_FAMILY = 0x0001
NETCONF_ATTR_IFINDEX = 0x0002
NETCONF_ATTR_RP_FILTER = 0x0004
NETCONF_ATTR_FWDING = 0x0008
NETCONF_ATTR_MC_FWDING = 0x0010
NETCONF_ATTR_PROXY_NEIGH = 0x0020
NETCONF_ATTR_IGNORE_RT_LINKDWN = 0x0040
attribute_to_class = {
NETCONFA_UNSPEC : ('NETCONFA_UNSPEC', AttributeGeneric),
NETCONFA_IFINDEX : ('NETCONFA_IFINDEX', AttributeFourByteValue),
NETCONFA_FORWARDING : ('NETCONFA_FORWARDING', AttributeFourByteValue),
NETCONFA_RP_FILTER : ('NETCONFA_RP_FILTER', AttributeFourByteValue),
NETCONFA_MC_FORWARDING : ('NETCONFA_MC_FORWARDING', AttributeFourByteValue),
NETCONFA_PROXY_NEIGH : ('NETCONFA_PROXY_NEIGH', AttributeFourByteValue),
NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN : ('NETCONFA_IGNORE_ROUTES_WITH_LINKDOWN', AttributeFourByteValue),
NETCONFA_INPUT : ('NETCONFA_INPUT', AttributeFourByteValue),
}
def __init__(self, msgtype, debug=False, logger=None, use_color=True):
NetlinkPacket.__init__(self, msgtype, debug, logger, use_color)
if msgtype == RTM_GETNETCONF: # same as RTM_GETLINK
self.PACK = 'BxHiII'
self.LEN = calcsize(self.PACK)
elif msgtype == RTM_NEWNETCONF:
self.PACK = 'Bxxx'
self.LEN = calcsize(self.PACK)
def decode_service_header(self):
# Nothing to do if the message did not contain a service header
if self.length == self.header_LEN:
return
if self.msgtype == RTM_GETNETCONF:
super(Netconf, self).decode_service_header()
elif self.msgtype == RTM_NEWNETCONF:
(self.family,) = unpack(self.PACK, self.msg_data[:self.LEN])
if self.debug:
color = yellow if self.use_color else None
color_start = "\033[%dm" % color if color else ""
color_end = "\033[0m" if color else ""
self.dump_buffer.append(" %sService Header%s" % (color_start, color_end))
self.dump_buffer.append(data_to_color_text(1, color, bytearray(struct.pack('!I', self.family)), "Family %s (%d)" % (zfilled_hex(self.family, 2), self.family)))
class Neighbor(NetlinkPacket):
"""
Service Header