From 82be3c91d5ed996cbf22a4e1c0705085dfa4964a Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Thu, 22 Aug 2024 10:20:04 -0400 Subject: [PATCH] Add support for relay DHCP Use the relay DHCP agent information as basis for subnet comparison instead of self, when present. Use the candidate prefix length verbatim since the relay will offer no hint as to the 'proper' prefix length for the target segment. --- .../confluent/discovery/protocols/pxe.py | 3 ++- confluent_server/confluent/netutil.py | 12 +++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/confluent_server/confluent/discovery/protocols/pxe.py b/confluent_server/confluent/discovery/protocols/pxe.py index 133d8abd..9e88318b 100644 --- a/confluent_server/confluent/discovery/protocols/pxe.py +++ b/confluent_server/confluent/discovery/protocols/pxe.py @@ -728,9 +728,10 @@ def reply_dhcp4(node, info, packet, cfg, reqview, httpboot, cfd, profile): repview[1:10] = reqview[1:10] # duplicate txid, hwlen, and others repview[10:11] = b'\x80' # always set broadcast repview[28:44] = reqview[28:44] # copy chaddr field + relayip = reqview[24:28].tobytes() gateway = None netmask = None - niccfg = netutil.get_nic_config(cfg, node, ifidx=info['netinfo']['ifidx']) + niccfg = netutil.get_nic_config(cfg, node, ifidx=info['netinfo']['ifidx'], relayip=relayip) nicerr = niccfg.get('error_msg', False) if nicerr: log.log({'error': nicerr}) diff --git a/confluent_server/confluent/netutil.py b/confluent_server/confluent/netutil.py index c1a9210a..a852d96c 100644 --- a/confluent_server/confluent/netutil.py +++ b/confluent_server/confluent/netutil.py @@ -408,7 +408,7 @@ def noneify(cfgdata): # the ip as reported by recvmsg to match the subnet of that net.* interface # if switch and port available, that should match. def get_nic_config(configmanager, node, ip=None, mac=None, ifidx=None, - serverip=None): + serverip=None, relayipn=b'\x00\x00\x00\x00'): """Fetch network configuration parameters for a nic For a given node and interface, find and retrieve the pertinent network @@ -489,6 +489,10 @@ def get_nic_config(configmanager, node, ip=None, mac=None, ifidx=None, bestsrvbyfam = {} for myaddr in myaddrs: fam, svrip, prefix = myaddr[:3] + if fam == socket.AF_INET and relayipn != b'\x00\x00\x00\x00': + bootsvrip = relayipn + else: + bootsvrip = svrip candsrvs.append((fam, svrip, prefix)) if fam == socket.AF_INET: nver = '4' @@ -508,6 +512,8 @@ def get_nic_config(configmanager, node, ip=None, mac=None, ifidx=None, candip = cfgbyname[candidate].get('ipv{}_address'.format(nver), None) if candip and '/' in candip: candip, candprefix = candip.split('/') + if fam == socket.AF_INET and relayipn != b'\x00\x00\x00\x00': + prefix = int(candprefix) if int(candprefix) != prefix: continue candgw = cfgbyname[candidate].get('ipv{}_gateway'.format(nver), None) @@ -515,7 +521,7 @@ def get_nic_config(configmanager, node, ip=None, mac=None, ifidx=None, try: for inf in socket.getaddrinfo(candip, 0, fam, socket.SOCK_STREAM): candipn = socket.inet_pton(fam, inf[-1][0]) - if ipn_on_same_subnet(fam, svrip, candipn, prefix): + if ipn_on_same_subnet(fam, bootsvrip, candipn, prefix): bestsrvbyfam[fam] = svrip cfgdata['ipv{}_address'.format(nver)] = candip cfgdata['ipv{}_method'.format(nver)] = ipmethod @@ -533,7 +539,7 @@ def get_nic_config(configmanager, node, ip=None, mac=None, ifidx=None, elif candgw: for inf in socket.getaddrinfo(candgw, 0, fam, socket.SOCK_STREAM): candgwn = socket.inet_pton(fam, inf[-1][0]) - if ipn_on_same_subnet(fam, svrip, candgwn, prefix): + if ipn_on_same_subnet(fam, bootsvrip, candgwn, prefix): candgws.append((fam, candgwn, prefix)) if foundaddr: return noneify(cfgdata)