2
0
mirror of https://opendev.org/x/pyghmi synced 2025-01-27 19:37:44 +00:00

Implement MegaRAC IPv6 SNMP destinations

MegaRAC does not support IPv6 standard destinations,
implement an OEM fallback for no standard IPv6, and
provide the MegaRAC backend for it.

Change-Id: I4732f47182df71607db57292a2b7de58623f0f45
This commit is contained in:
Jarrod Johnson 2016-04-07 10:43:14 -04:00
parent 9712efcf52
commit 14fa128a18
3 changed files with 59 additions and 4 deletions

View File

@ -110,6 +110,7 @@ class Command(object):
self._sdr = None
self._oem = None
self._netchannel = None
self._ipv6support = None
if onlogon is not None:
self.ipmi_session = session.Session(bmc=bmc,
userid=userid,
@ -962,6 +963,18 @@ class Command(object):
rsp = self.xraw_command(netfn=0xc, command=2, data=(channel, 16, 0, 0))
return rsp['data'][1:].partition('\x00')[0]
@property
def _supports_standard_ipv6(self):
# Supports the *standard* ipv6 commands for various things
# used to internally steer some commands to standard or OEM
# handler of commands
lanchan = self.get_network_channel()
if self._ipv6support is None:
rsp = self.raw_command(netfn=0xc, command=0x2, data=(2, lanchan,
0x32, 0, 0))
self._ipv6support = rsp['code'] == 0
return self._ipv6support
def set_alert_destination(self, ip=None, acknowledge_required=None,
acknowledge_timeout=None, retries=None,
destination=0, channel=None):
@ -991,10 +1004,17 @@ class Command(object):
destdata.extend(parsedip)
destdata.extend('\x00\x00\x00\x00\x00\x00')
except socket.error:
parsedip = socket.inet_pton(socket.AF_INET6, ip)
destdata.append(0b10000000)
destdata.extend(parsedip)
self.xraw_command(netfn=0xc, command=1, data=destdata)
if self._supports_standard_ipv6:
parsedip = socket.inet_pton(socket.AF_INET6, ip)
destdata.append(0b10000000)
destdata.extend(parsedip)
else:
destdata = None
self.oem_init()
self._oem.set_alert_ipv6_destination(ip, destination,
channel)
if destdata:
self.xraw_command(netfn=0xc, command=1, data=destdata)
if (acknowledge_required is not None or retries is not None or
acknowledge_timeout is not None):
currtype = self.xraw_command(netfn=0xc, command=2, data=(

View File

@ -229,3 +229,18 @@ class OEMHandler(object):
def attach_remote_media(self, imagename, username, password):
raise exc.UnsupportedFunctionality()
def set_alert_ipv6_destination(self, ip, destination, channel):
"""Set an IPv6 alert destination
If and only if an implementation does not support standard
IPv6 but has an OEM implementation, override this to process
the data.
:param ip: IPv6 address to set
:param destination: Destination number
:param channel: Channel number to apply
:returns True if standard parameter set should be suppressed
"""
return False

View File

@ -131,6 +131,15 @@ class OEMHandler(generic.OEMHandler):
self.ipmicmd = weakref.proxy(ipmicmd)
self._has_megarac = None
self.oem_inventory_info = None
self._mrethidx = None
@property
def _megarac_eth_index(self):
if self._mrethidx is None:
chan = self.ipmicmd.get_network_channel()
rsp = self.ipmicmd.xraw_command(0x32, command=0x62, data=(chan,))
self._mrethidx = rsp['data'][0]
return self._mrethidx
def get_video_launchdata(self):
if self.has_tsm:
@ -571,6 +580,17 @@ class OEMHandler(generic.OEMHandler):
pass # Means that it's not going to be a megarac
return self._has_megarac
def set_alert_ipv6_destination(self, ip, destination, channel):
if self.has_megarac:
ethidx = self._megarac_eth_index
reqdata = bytearray([channel, 193, destination, ethidx, 0])
parsedip = socket.inet_pton(socket.AF_INET6, ip)
reqdata.extend(parsedip)
reqdata.extend('\x00\x00\x00\x00\x00\x00')
self.ipmicmd.xraw_command(netfn=0xc, command=1, data=reqdata)
return True
return False
def _set_short_ris_string(self, selector, value):
data = (1, selector, 0) + struct.unpack('{0}B'.format(len(value)),
value)