patching service unicast messaging for loopback interface
IPv6 does not support multicast messaging on the loopback interface. Therefore to support patch agent to controller messaging when the management network is associated with the loopback interface it must operate using unicast messaging. This is sufficient since it does not need to communicate with multiple process instances when operating in this local mode. Change-Id: I95efd06be9717a76ccbd543c1fd16408fd89dbeb Closes-Bug: #1830779 Signed-off-by: Matt Peters <matt.peters@windriver.com>
This commit is contained in:
parent
4b1e9e453f
commit
319252db74
|
@ -64,18 +64,19 @@ class PatchService:
|
|||
self.sock_out.bind((mgmt_ip, 0))
|
||||
self.sock_in.bind(('', self.port))
|
||||
|
||||
# These options are for outgoing multicast messages
|
||||
self.sock_out.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, interface_addr)
|
||||
self.sock_out.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 1)
|
||||
# Since only the controllers are sending to this address,
|
||||
# we want the loopback so the local agent can receive it
|
||||
self.sock_out.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, 1)
|
||||
if self.mcast_addr:
|
||||
# These options are for outgoing multicast messages
|
||||
self.sock_out.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, interface_addr)
|
||||
self.sock_out.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 1)
|
||||
# Since only the controllers are sending to this address,
|
||||
# we want the loopback so the local agent can receive it
|
||||
self.sock_out.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, 1)
|
||||
|
||||
# Register the multicast group
|
||||
group = socket.inet_pton(socket.AF_INET, self.mcast_addr)
|
||||
mreq = struct.pack('=4s4s', group, interface_addr)
|
||||
# Register the multicast group
|
||||
group = socket.inet_pton(socket.AF_INET, self.mcast_addr)
|
||||
mreq = struct.pack('=4s4s', group, interface_addr)
|
||||
|
||||
self.sock_in.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
|
||||
self.sock_in.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
|
||||
|
||||
return self.sock_in
|
||||
|
||||
|
@ -106,18 +107,19 @@ class PatchService:
|
|||
self.sock_out.bind((mgmt_ip, 0))
|
||||
self.sock_in.bind(('', self.port))
|
||||
|
||||
# These options are for outgoing multicast messages
|
||||
mgmt_ifindex = utils.if_nametoindex(cfg.get_mgmt_iface())
|
||||
self.sock_out.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_IF, mgmt_ifindex)
|
||||
self.sock_out.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_HOPS, 1)
|
||||
# Since only the controllers are sending to this address,
|
||||
# we want the loopback so the local agent can receive it
|
||||
self.sock_out.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_LOOP, 1)
|
||||
if self.mcast_addr:
|
||||
# These options are for outgoing multicast messages
|
||||
mgmt_ifindex = utils.if_nametoindex(cfg.get_mgmt_iface())
|
||||
self.sock_out.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_IF, mgmt_ifindex)
|
||||
self.sock_out.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_HOPS, 1)
|
||||
# Since only the controllers are sending to this address,
|
||||
# we want the loopback so the local agent can receive it
|
||||
self.sock_out.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_LOOP, 1)
|
||||
|
||||
# Register the multicast group
|
||||
if_index_packed = struct.pack('I', mgmt_ifindex)
|
||||
group = socket.inet_pton(socket.AF_INET6, self.mcast_addr) + if_index_packed
|
||||
self.sock_in.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, group)
|
||||
# Register the multicast group
|
||||
if_index_packed = struct.pack('I', mgmt_ifindex)
|
||||
group = socket.inet_pton(socket.AF_INET6, self.mcast_addr) + if_index_packed
|
||||
self.sock_in.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, group)
|
||||
|
||||
return self.sock_in
|
||||
|
||||
|
@ -145,6 +147,10 @@ class PatchService:
|
|||
return None
|
||||
|
||||
def audit_socket(self):
|
||||
if not self.mcast_addr:
|
||||
# Multicast address not configured, therefore nothing to do
|
||||
return
|
||||
|
||||
# Ensure multicast address is still allocated
|
||||
cmd = "ip maddr show %s | awk 'BEGIN {ORS=\"\"}; {if ($2 == \"%s\") print $2}'" % \
|
||||
(cfg.get_mgmt_iface(), self.mcast_addr)
|
||||
|
|
|
@ -114,7 +114,6 @@ def get_mgmt_iface():
|
|||
try:
|
||||
value = str(config.get('platform_conf', 'management_interface'))
|
||||
|
||||
global nodetype
|
||||
mgmt_if = value
|
||||
|
||||
platform_conf_mtime = os.stat(tsc.PLATFORM_CONF_FILE).st_mtime
|
||||
|
|
|
@ -43,3 +43,5 @@ CLI_OPT_RECURSIVE = '--recursive'
|
|||
CLI_OPT_RELEASE = '--release'
|
||||
|
||||
ENABLE_DEV_CERTIFICATE_PATCH_IDENTIFIER = 'ENABLE_DEV_CERTIFICATE'
|
||||
|
||||
LOOPBACK_INTERFACE_NAME = "lo"
|
||||
|
|
|
@ -172,9 +172,10 @@ class PatchMessageHelloAgentAck(messages.PatchMessage):
|
|||
LOG.error("Should not get here")
|
||||
|
||||
def send(self, sock):
|
||||
global pa
|
||||
self.encode()
|
||||
message = json.dumps(self.message)
|
||||
sock.sendto(message, (cfg.controller_mcast_group, cfg.controller_port))
|
||||
sock.sendto(message, (pa.controller_address, cfg.controller_port))
|
||||
|
||||
|
||||
class PatchMessageQueryDetailed(messages.PatchMessage):
|
||||
|
@ -292,6 +293,7 @@ class PatchAgent(PatchService):
|
|||
PatchService.__init__(self)
|
||||
self.sock_out = None
|
||||
self.sock_in = None
|
||||
self.controller_address = None
|
||||
self.listener = None
|
||||
self.changes = False
|
||||
self.installed = {}
|
||||
|
@ -323,8 +325,15 @@ class PatchAgent(PatchService):
|
|||
if self.port != cfg.agent_port:
|
||||
self.port = cfg.agent_port
|
||||
|
||||
if self.mcast_addr != cfg.agent_mcast_group:
|
||||
# Loopback interface does not support multicast messaging, therefore
|
||||
# revert to using unicast messaging when configured against the
|
||||
# loopback device
|
||||
if cfg.get_mgmt_iface() == constants.LOOPBACK_INTERFACE_NAME:
|
||||
self.mcast_addr = None
|
||||
self.controller_address = cfg.get_mgmt_ip()
|
||||
else:
|
||||
self.mcast_addr = cfg.agent_mcast_group
|
||||
self.controller_address = cfg.controller_mcast_group
|
||||
|
||||
def setup_tcp_socket(self):
|
||||
address_family = utils.get_management_family()
|
||||
|
|
|
@ -230,9 +230,10 @@ class PatchMessageHello(messages.PatchMessage):
|
|||
resp.send(sock)
|
||||
|
||||
def send(self, sock):
|
||||
global pc
|
||||
self.encode()
|
||||
message = json.dumps(self.message)
|
||||
sock.sendto(message, (cfg.controller_mcast_group, cfg.controller_port))
|
||||
sock.sendto(message, (pc.controller_address, cfg.controller_port))
|
||||
|
||||
|
||||
class PatchMessageHelloAck(messages.PatchMessage):
|
||||
|
@ -254,9 +255,10 @@ class PatchMessageHelloAck(messages.PatchMessage):
|
|||
pc.controller_neighbours_lock.release()
|
||||
|
||||
def send(self, sock):
|
||||
global pc
|
||||
self.encode()
|
||||
message = json.dumps(self.message)
|
||||
sock.sendto(message, (cfg.controller_mcast_group, cfg.controller_port))
|
||||
sock.sendto(message, (pc.controller_address, cfg.controller_port))
|
||||
|
||||
|
||||
class PatchMessageSyncReq(messages.PatchMessage):
|
||||
|
@ -283,10 +285,11 @@ class PatchMessageSyncReq(messages.PatchMessage):
|
|||
resp.send(sock)
|
||||
|
||||
def send(self, sock):
|
||||
global pc
|
||||
LOG.info("sending sync req")
|
||||
self.encode()
|
||||
message = json.dumps(self.message)
|
||||
sock.sendto(message, (cfg.controller_mcast_group, cfg.controller_port))
|
||||
sock.sendto(message, (pc.controller_address, cfg.controller_port))
|
||||
|
||||
|
||||
class PatchMessageSyncComplete(messages.PatchMessage):
|
||||
|
@ -309,10 +312,11 @@ class PatchMessageSyncComplete(messages.PatchMessage):
|
|||
pc.controller_neighbours_lock.release()
|
||||
|
||||
def send(self, sock):
|
||||
global pc
|
||||
LOG.info("sending sync complete")
|
||||
self.encode()
|
||||
message = json.dumps(self.message)
|
||||
sock.sendto(message, (cfg.controller_mcast_group, cfg.controller_port))
|
||||
sock.sendto(message, (pc.controller_address, cfg.controller_port))
|
||||
|
||||
|
||||
class PatchMessageHelloAgent(messages.PatchMessage):
|
||||
|
@ -328,10 +332,11 @@ class PatchMessageHelloAgent(messages.PatchMessage):
|
|||
LOG.error("Should not get here")
|
||||
|
||||
def send(self, sock):
|
||||
global pc
|
||||
self.encode()
|
||||
message = json.dumps(self.message)
|
||||
local_hostname = utils.ip_to_versioned_localhost(cfg.agent_mcast_group)
|
||||
sock.sendto(message, (cfg.agent_mcast_group, cfg.agent_port))
|
||||
sock.sendto(message, (pc.agent_address, cfg.agent_port))
|
||||
sock.sendto(message, (local_hostname, cfg.agent_port))
|
||||
|
||||
|
||||
|
@ -549,9 +554,10 @@ class PatchMessageDropHostReq(messages.PatchMessage):
|
|||
return
|
||||
|
||||
def send(self, sock):
|
||||
global pc
|
||||
self.encode()
|
||||
message = json.dumps(self.message)
|
||||
sock.sendto(message, (cfg.controller_mcast_group, cfg.controller_port))
|
||||
sock.sendto(message, (pc.controller_address, cfg.controller_port))
|
||||
|
||||
|
||||
class PatchController(PatchService):
|
||||
|
@ -577,6 +583,8 @@ class PatchController(PatchService):
|
|||
|
||||
self.sock_out = None
|
||||
self.sock_in = None
|
||||
self.controller_address = None
|
||||
self.agent_address = None
|
||||
self.patch_op_counter = 1
|
||||
self.patch_data = PatchData()
|
||||
self.patch_data.load_all()
|
||||
|
@ -605,8 +613,18 @@ class PatchController(PatchService):
|
|||
if self.port != cfg.controller_port:
|
||||
self.port = cfg.controller_port
|
||||
|
||||
if self.mcast_addr != cfg.controller_mcast_group:
|
||||
# Loopback interface does not support multicast messaging, therefore
|
||||
# revert to using unicast messaging when configured against the
|
||||
# loopback device
|
||||
if cfg.get_mgmt_iface() == constants.LOOPBACK_INTERFACE_NAME:
|
||||
mgmt_ip = cfg.get_mgmt_ip()
|
||||
self.mcast_addr = None
|
||||
self.controller_address = mgmt_ip
|
||||
self.agent_address = mgmt_ip
|
||||
else:
|
||||
self.mcast_addr = cfg.controller_mcast_group
|
||||
self.controller_address = cfg.controller_mcast_group
|
||||
self.agent_address = cfg.agent_mcast_group
|
||||
|
||||
def socket_lock_acquire(self):
|
||||
self.socket_lock.acquire()
|
||||
|
|
Loading…
Reference in New Issue