Blame SOURCES/0004-Support-unicast-BOOTP-for-IBM-pSeries-systems-and-ma.patch

f9ed25
From 7e8cc8388ac31c5c2b1a423c6b2da0491b19f6f9 Mon Sep 17 00:00:00 2001
f9ed25
From: Pavel Zhukov <pzhukov@redhat.com>
f9ed25
Date: Thu, 21 Feb 2019 10:22:41 +0100
f9ed25
Subject: [PATCH 04/26] Support unicast BOOTP for IBM pSeries systems (and
f9ed25
 maybe others)
f9ed25
Cc: pzhukov@redhat.com
f9ed25
f9ed25
---
f9ed25
 server/bootp.c | 12 +++++++++++-
f9ed25
 server/dhcp.c  | 33 ++++++++++++++++++++++++++-------
f9ed25
 2 files changed, 37 insertions(+), 8 deletions(-)
f9ed25
f9ed25
diff --git a/server/bootp.c b/server/bootp.c
f9ed25
index 26a7607..2212f31 100644
f9ed25
--- a/server/bootp.c
f9ed25
+++ b/server/bootp.c
f9ed25
@@ -52,6 +52,7 @@ void bootp (packet)
f9ed25
 	char msgbuf [1024];
f9ed25
 	int ignorep;
f9ed25
 	int peer_has_leases = 0;
f9ed25
+	int norelay = 0;
f9ed25
 
f9ed25
 	if (packet -> raw -> op != BOOTREQUEST)
f9ed25
 		return;
f9ed25
@@ -67,7 +68,7 @@ void bootp (packet)
f9ed25
 		 ? inet_ntoa (packet -> raw -> giaddr)
f9ed25
 		 : packet -> interface -> name);
f9ed25
 
f9ed25
-	if (!locate_network (packet)) {
f9ed25
+	if ((norelay = locate_network (packet)) == 0) {
f9ed25
 		log_info ("%s: network unknown", msgbuf);
f9ed25
 		return;
f9ed25
 	}
f9ed25
@@ -428,6 +429,15 @@ void bootp (packet)
f9ed25
 
f9ed25
 			goto out;
f9ed25
 		}
f9ed25
+	} else if (norelay == 2) {
f9ed25
+		to.sin_addr = raw.ciaddr;
f9ed25
+		to.sin_port = remote_port;
f9ed25
+		if (fallback_interface) {
f9ed25
+			result = send_packet (fallback_interface, NULL, &raw,
f9ed25
+					      outgoing.packet_length, from,
f9ed25
+					      &to, &hto);
f9ed25
+			goto out;
f9ed25
+		}
f9ed25
 
f9ed25
 	/* If it comes from a client that already knows its address
f9ed25
 	   and is not requesting a broadcast response, and we can
f9ed25
diff --git a/server/dhcp.c b/server/dhcp.c
f9ed25
index 6f3a91f..20f2a62 100644
f9ed25
--- a/server/dhcp.c
f9ed25
+++ b/server/dhcp.c
f9ed25
@@ -5224,6 +5224,7 @@ int locate_network (packet)
f9ed25
 	struct data_string data;
f9ed25
 	struct subnet *subnet = (struct subnet *)0;
f9ed25
 	struct option_cache *oc;
f9ed25
+	int norelay = 0;
f9ed25
 
f9ed25
 #if defined(DHCPv6) && defined(DHCP4o6)
f9ed25
 	if (dhcpv4_over_dhcpv6 && (packet->dhcp4o6_response != NULL)) {
f9ed25
@@ -5245,12 +5246,24 @@ int locate_network (packet)
f9ed25
 	   from the interface, if there is one.   If not, fail. */
f9ed25
 	if (!oc && !packet -> raw -> giaddr.s_addr) {
f9ed25
 		if (packet -> interface -> shared_network) {
f9ed25
-			shared_network_reference
f9ed25
-				(&packet -> shared_network,
f9ed25
-				 packet -> interface -> shared_network, MDL);
f9ed25
-			return 1;
f9ed25
+			struct in_addr any_addr;
f9ed25
+			any_addr.s_addr = INADDR_ANY;
f9ed25
+
f9ed25
+			if (!packet -> packet_type && memcmp(&packet -> raw -> ciaddr, &any_addr, 4)) {
f9ed25
+				struct iaddr cip;
f9ed25
+				memcpy(cip.iabuf, &packet -> raw -> ciaddr, 4);
f9ed25
+				cip.len = 4;
f9ed25
+				if (!find_grouped_subnet(&subnet, packet->interface->shared_network, cip, MDL))
f9ed25
+					norelay = 2;
f9ed25
+			}
f9ed25
+
f9ed25
+			if (!norelay) {
f9ed25
+				shared_network_reference(&packet -> shared_network, packet -> interface -> shared_network, MDL);
f9ed25
+				return 1;
f9ed25
+			}
f9ed25
+		} else {
f9ed25
+			return 0;
f9ed25
 		}
f9ed25
-		return 0;
f9ed25
 	}
f9ed25
 
f9ed25
 	/* If there's an option indicating link connection, and it's valid,
f9ed25
@@ -5277,7 +5290,10 @@ int locate_network (packet)
f9ed25
 		data_string_forget (&data, MDL);
f9ed25
 	} else {
f9ed25
 		ia.len = 4;
f9ed25
-		memcpy (ia.iabuf, &packet -> raw -> giaddr, 4);
f9ed25
+		if (norelay)
f9ed25
+			memcpy (ia.iabuf, &packet->raw->ciaddr, 4);
f9ed25
+		else
f9ed25
+			memcpy (ia.iabuf, &packet->raw->giaddr, 4);
f9ed25
 	}
f9ed25
 
f9ed25
 	/* If we know the subnet on which the IP address lives, use it. */
f9ed25
@@ -5285,7 +5301,10 @@ int locate_network (packet)
f9ed25
 		shared_network_reference (&packet -> shared_network,
f9ed25
 					  subnet -> shared_network, MDL);
f9ed25
 		subnet_dereference (&subnet, MDL);
f9ed25
-		return 1;
f9ed25
+		if (norelay)
f9ed25
+			return norelay;
f9ed25
+		else
f9ed25
+			return 1;
f9ed25
 	}
f9ed25
 
f9ed25
 	/* Otherwise, fail. */
f9ed25
-- 
f9ed25
2.14.5
f9ed25