mirror of
https://github.com/xcat2/confluent.git
synced 2025-03-19 01:47:45 +00:00
Change to built in neigh fetch
Rather than outsource, slowly, to ip neigh for this frequent task, call netlink directly.
This commit is contained in:
parent
06cfd408fc
commit
69b58836f6
@ -19,8 +19,9 @@
|
||||
# use ip neigh for the moment
|
||||
|
||||
import confluent.util as util
|
||||
import eventlet.green.subprocess as subprocess
|
||||
import os
|
||||
import eventlet.green.socket as socket
|
||||
import struct
|
||||
|
||||
neightable = {}
|
||||
neightime = 0
|
||||
@ -33,29 +34,40 @@ _validmac = re.compile('..:..:..:..:..:..')
|
||||
def update_neigh():
|
||||
global neightable
|
||||
global neightime
|
||||
neightable = {}
|
||||
if os.name == 'nt':
|
||||
return
|
||||
ipn = subprocess.Popen(['ip', 'neigh'], stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
(neighdata, err) = ipn.communicate()
|
||||
neighdata = util.stringify(neighdata)
|
||||
for entry in neighdata.split('\n'):
|
||||
entry = entry.split(' ')
|
||||
if len(entry) < 5 or not entry[4]:
|
||||
continue
|
||||
if entry[0] in ('192.168.0.100', '192.168.70.100', '192.168.70.125'):
|
||||
# Note that these addresses are common static ip addresses
|
||||
# that are hopelessly ambiguous if there are many
|
||||
# so ignore such entries and move on
|
||||
# ideally the system network steers clear of this landmine of
|
||||
# a subnet, but just in case
|
||||
continue
|
||||
if not _validmac.match(entry[4]):
|
||||
continue
|
||||
neightable[entry[0]] = entry[4]
|
||||
neightime = os.times()[4]
|
||||
s = socket.socket(socket.AF_NETLINK, socket.SOCK_RAW, socket.NETLINK_ROUTE)
|
||||
s.bind((0, 0))
|
||||
# RTM_GETNEIGH
|
||||
nlhdr = b'\x1c\x00\x00\x00\x1e\x00\x01\x03\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
ndmsg= b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
s.sendall(nlhdr + ndmsg)
|
||||
while True:
|
||||
pdata = s.recv(65536)
|
||||
v = memoryview(pdata)
|
||||
if struct.unpack('H', v[4:6])[0] == 3:
|
||||
break
|
||||
while len(v):
|
||||
length, typ = struct.unpack('IH', v[:6])
|
||||
if typ == 28:
|
||||
hlen = struct.calcsize('BIHBB')
|
||||
fam, idx, state, flags, typ = struct.unpack('BIHBB', v[16:16+hlen])
|
||||
if typ == 1: # only handle unicast entries
|
||||
curraddr = None
|
||||
currip = None
|
||||
rta = v[16+hlen:length]
|
||||
while len(rta):
|
||||
rtalen, rtatyp = struct.unpack('HH', rta[:4])
|
||||
if rtatyp == 2: # hwaddr
|
||||
hwlen = rtalen - 4
|
||||
curraddr = ':'.join(['{:02x}'.format(x) for x in bytearray(rta[4:rtalen].tobytes())])
|
||||
elif rtatyp == 1: # ip address
|
||||
currip = socket.inet_ntop(fam, rta[4:rtalen].tobytes())
|
||||
rta = rta[rtalen:]
|
||||
if not rtalen:
|
||||
if curraddr and currip:
|
||||
neightable[currip] = curraddr
|
||||
break
|
||||
v = v[length:]
|
||||
|
||||
|
||||
def refresh_neigh():
|
||||
|
Loading…
x
Reference in New Issue
Block a user