From b73af5e07acf62e5d2d2a7b61103c0ccb6ab9502 Mon Sep 17 00:00:00 2001 From: Joe LeVeque Date: Sun, 28 Apr 2019 22:51:46 -0700 Subject: [PATCH] [dhcp_relay] Base DHCP Relay Docker container on Debian Stretch (#2832) * Base DHCP relay Docker image on Strech base Docker * Change URL for isc-dhcp source repository * Upgrade isc-dhcp source branch to 4.3.5-3.1 * Update patch #0001 to apply to isc-dhcp 4.3.5-3.1 * Update patch #0002 to apply to isc-dhcp 4.3.5-3.1 * Update patch #0003 to apply to isc-dhcp 4.3.5-3.1 * Update patch #0004 to apply to isc-dhcp 4.3.5-3.1 * Remove security patches, as they are now applied as part of 4.3.5-3.1 source * Reorder patches to apply bug fix first, then features * Extend makefile to build debug Docker image * Update commit that series file applies against --- dockers/docker-dhcp-relay/Dockerfile.j2 | 2 +- rules/docker-dhcp-relay.mk | 18 +- rules/isc-dhcp.mk | 4 +- src/isc-dhcp/Makefile | 2 +- ...t-log-messages-to-stderr-in-release.patch} | 6 +- ...ion-82-circuit-ID-and-remote-ID-fiel.patch | 273 ------------------ ...ion-82-circuit-ID-and-remote-ID-fiel.patch | 265 +++++++++++++++++ ...ining-name-of-physical-interface-tha.patch | 114 -------- ...ing-port-alias-map-file-to-replace-p.patch | 187 ------------ ...ining-name-of-physical-interface-tha.patch | 98 +++++++ ...ing-port-alias-map-file-to-replace-p.patch | 189 ++++++++++++ src/isc-dhcp/patch/0005-CVE-2017-3144.patch | 47 --- src/isc-dhcp/patch/0006-CVE-2018-5733.patch | 145 ---------- src/isc-dhcp/patch/0007-CVE-2018-5732.patch | 144 --------- src/isc-dhcp/patch/series | 13 +- 15 files changed, 580 insertions(+), 927 deletions(-) rename src/isc-dhcp/patch/{0004-Bugfix-Don-t-print-log-messages-to-stderr-in-release.patch => 0001-Bugfix-Don-t-print-log-messages-to-stderr-in-release.patch} (82%) delete mode 100644 src/isc-dhcp/patch/0001-Customizable-Option-82-circuit-ID-and-remote-ID-fiel.patch create mode 100644 src/isc-dhcp/patch/0002-Customizable-Option-82-circuit-ID-and-remote-ID-fiel.patch delete mode 100644 src/isc-dhcp/patch/0002-Support-for-obtaining-name-of-physical-interface-tha.patch delete mode 100644 src/isc-dhcp/patch/0003-Support-for-loading-port-alias-map-file-to-replace-p.patch create mode 100644 src/isc-dhcp/patch/0003-Support-for-obtaining-name-of-physical-interface-tha.patch create mode 100644 src/isc-dhcp/patch/0004-Support-for-loading-port-alias-map-file-to-replace-p.patch delete mode 100644 src/isc-dhcp/patch/0005-CVE-2017-3144.patch delete mode 100644 src/isc-dhcp/patch/0006-CVE-2018-5733.patch delete mode 100644 src/isc-dhcp/patch/0007-CVE-2018-5732.patch diff --git a/dockers/docker-dhcp-relay/Dockerfile.j2 b/dockers/docker-dhcp-relay/Dockerfile.j2 index 0a760d301f3a..3db714d4df94 100644 --- a/dockers/docker-dhcp-relay/Dockerfile.j2 +++ b/dockers/docker-dhcp-relay/Dockerfile.j2 @@ -1,4 +1,4 @@ -FROM docker-config-engine +FROM docker-config-engine-stretch ARG docker_container_name RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf diff --git a/rules/docker-dhcp-relay.mk b/rules/docker-dhcp-relay.mk index 44d3904d7394..f1f19d974a8e 100644 --- a/rules/docker-dhcp-relay.mk +++ b/rules/docker-dhcp-relay.mk @@ -1,12 +1,24 @@ # Docker image for DHCP relay -DOCKER_DHCP_RELAY = docker-dhcp-relay.gz -$(DOCKER_DHCP_RELAY)_PATH = $(DOCKERS_PATH)/docker-dhcp-relay +DOCKER_DHCP_RELAY_STEM = docker-dhcp-relay +DOCKER_DHCP_RELAY = $(DOCKER_DHCP_RELAY_STEM).gz +DOCKER_DHCP_RELAY_DBG = $(DOCKER_DHCP_RELAY_STEM)-$(DBG_IMAGE_MARK).gz + +$(DOCKER_DHCP_RELAY)_PATH = $(DOCKERS_PATH)/$(DOCKER_DHCP_RELAY_STEM) + $(DOCKER_DHCP_RELAY)_DEPENDS += $(ISC_DHCP_COMMON) $(ISC_DHCP_RELAY) -$(DOCKER_DHCP_RELAY)_LOAD_DOCKERS = $(DOCKER_CONFIG_ENGINE) +$(DOCKER_DHCP_RELAY)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_DEPENDS) +$(DOCKER_DHCP_RELAY)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_STRETCH)_DBG_IMAGE_PACKAGES) + +$(DOCKER_DHCP_RELAY)_LOAD_DOCKERS = $(DOCKER_CONFIG_ENGINE_STRETCH) + SONIC_DOCKER_IMAGES += $(DOCKER_DHCP_RELAY) SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_DHCP_RELAY) +SONIC_STRETCH_DOCKERS += $(DOCKER_DHCP_RELAY) +SONIC_DOCKER_DBG_IMAGES += $(DOCKER_DHCP_RELAY_DBG) +SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_DHCP_RELAY_DBG) +SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_DHCP_RELAY_DBG) $(DOCKER_DHCP_RELAY)_CONTAINER_NAME = dhcp_relay $(DOCKER_DHCP_RELAY)_RUN_OPT += --net=host --privileged -t diff --git a/rules/isc-dhcp.mk b/rules/isc-dhcp.mk index 7b7f69c6cfc6..16b14ac5c082 100644 --- a/rules/isc-dhcp.mk +++ b/rules/isc-dhcp.mk @@ -1,6 +1,6 @@ # isc-dhcp packages -ISC_DHCP_VERSION = 4.3.3-6 +ISC_DHCP_VERSION = 4.3.5-3.1 export ISC_DHCP_VERSION @@ -10,3 +10,5 @@ SONIC_MAKE_DEBS += $(ISC_DHCP_COMMON) ISC_DHCP_RELAY = isc-dhcp-relay_$(ISC_DHCP_VERSION)_amd64.deb $(eval $(call add_derived_package,$(ISC_DHCP_COMMON),$(ISC_DHCP_RELAY))) + +SONIC_STRETCH_DEBS += $(ISC_DHCP_COMMON) $(ISC_DHCP_RELAY) diff --git a/src/isc-dhcp/Makefile b/src/isc-dhcp/Makefile index ce4fbc62608f..1227b3a0c33f 100644 --- a/src/isc-dhcp/Makefile +++ b/src/isc-dhcp/Makefile @@ -10,7 +10,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : rm -rf ./isc-dhcp # Clone isc-dhcp repo - git clone https://salsa.debian.org/berni/isc-dhcp.git + git clone https://salsa.debian.org/dhcp-team/isc-dhcp.git pushd ./isc-dhcp # Reset HEAD to the commit of the proper tag diff --git a/src/isc-dhcp/patch/0004-Bugfix-Don-t-print-log-messages-to-stderr-in-release.patch b/src/isc-dhcp/patch/0001-Bugfix-Don-t-print-log-messages-to-stderr-in-release.patch similarity index 82% rename from src/isc-dhcp/patch/0004-Bugfix-Don-t-print-log-messages-to-stderr-in-release.patch rename to src/isc-dhcp/patch/0001-Bugfix-Don-t-print-log-messages-to-stderr-in-release.patch index 428f4471a1f7..2ddbc1a90f93 100644 --- a/src/isc-dhcp/patch/0004-Bugfix-Don-t-print-log-messages-to-stderr-in-release.patch +++ b/src/isc-dhcp/patch/0001-Bugfix-Don-t-print-log-messages-to-stderr-in-release.patch @@ -1,6 +1,6 @@ -From 2bb21fcf4a9ad7535867809c50d2cf0ba1088e17 Mon Sep 17 00:00:00 2001 +From 7c1cfd636be589317710a8556a7ec667debee53a Mon Sep 17 00:00:00 2001 From: Joe LeVeque -Date: Fri, 9 Mar 2018 01:43:35 +0000 +Date: Fri, 26 Apr 2019 01:37:54 +0000 Subject: [PATCH] [Bugfix] Don't print log messages to stderr in release builds --- @@ -24,5 +24,5 @@ index 7c91d9d..aa74fd8 100644 void (*log_cleanup) (void); -- -2.1.4 +2.17.1 diff --git a/src/isc-dhcp/patch/0001-Customizable-Option-82-circuit-ID-and-remote-ID-fiel.patch b/src/isc-dhcp/patch/0001-Customizable-Option-82-circuit-ID-and-remote-ID-fiel.patch deleted file mode 100644 index 22a8f7faedd1..000000000000 --- a/src/isc-dhcp/patch/0001-Customizable-Option-82-circuit-ID-and-remote-ID-fiel.patch +++ /dev/null @@ -1,273 +0,0 @@ -From 284c87ff4b3873d0215904273fe3c86b07b4ba94 Mon Sep 17 00:00:00 2001 -From: Joe LeVeque -Date: Mon, 11 Dec 2017 23:21:08 +0000 -Subject: [PATCH 1/3] Customizable Option 82 circuit ID and remote ID fields - ---- - relay/dhcrelay.c | 182 ++++++++++++++++++++++++++++++++++++++++++++++--------- - 1 file changed, 152 insertions(+), 30 deletions(-) - -diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c -index 15b4997..b9f8326 100644 ---- a/relay/dhcrelay.c -+++ b/relay/dhcrelay.c -@@ -73,6 +73,8 @@ int bad_circuit_id = 0; /* Circuit ID option in matching RAI option - did not match any known circuit ID. */ - int missing_circuit_id = 0; /* Circuit ID option in matching RAI option - was missing. */ -+const char *agent_circuit_id_fmt = NULL; /* Circuit ID custom format string. */ -+const char *agent_remote_id_fmt = NULL; /* Remote ID custom format string. */ - int max_hop_count = 10; /* Maximum hop count */ - - #ifdef DHCPv6 -@@ -140,9 +142,19 @@ static const char message[] = - static const char url[] = - "For info, please visit https://www.isc.org/software/dhcp/"; - -+#define DHCRELAY_OPTION82_USAGE \ -+"circuit_id/remote_id interpreted sequences are:\n" \ -+"\n" \ -+" %%%% A single %%\n" \ -+" %%h Hostname of device\n" \ -+" %%p Name of interface that generated the request\n" \ -+" %%P Hardware address of interface that generated the request\n" \ -+" %%C Client hardware address\n" \ -+" %%I DHCP relay agent IP Address\n" \ -+ - #ifdef DHCPv6 - #define DHCRELAY_USAGE \ --"Usage: dhcrelay [-4] [-d] [-q] [-a] [-D]\n"\ -+"Usage: dhcrelay [-4] [-d] [-q] [-a ] [-D]\n"\ - " [-A ] [-c ] [-p ]\n" \ - " [-pf ] [--no-pid]\n"\ - " [-m append|replace|forward|discard]\n" \ -@@ -154,14 +166,15 @@ static const char url[] = - " -l lower0 [ ... -l lowerN]\n" \ - " -u upper0 [ ... -u upperN]\n" \ - " lower (client link): [address%%]interface[#index]\n" \ --" upper (server link): [address%%]interface" -+" upper (server link): [address%%]interface\n\n" DHCRELAY_OPTION82_USAGE - #else - #define DHCRELAY_USAGE \ --"Usage: dhcrelay [-d] [-q] [-a] [-D] [-A ] [-c ] [-p ]\n" \ --" [-pf ] [--no-pid]\n" \ -+"Usage: dhcrelay [-d] [-q] [-a ] [-D]\n" \ -+" [-A ] [-c ] [-p ]\n" \ -+" [-pf ] [--no-pid]\n"\ - " [-m append|replace|forward|discard]\n" \ - " [-i interface0 [ ... -i interfaceN]\n" \ --" server0 [ ... serverN]\n\n" -+" server0 [ ... serverN]\n\n" DHCRELAY_OPTION82_USAGE - #endif - - static void usage() { -@@ -287,6 +300,15 @@ main(int argc, char **argv) { - local_family_set = 1; - local_family = AF_INET; - #endif -+ if (++i == argc) -+ usage(); -+ -+ if (argv[i] != NULL && argv[i][0] != '-') -+ agent_circuit_id_fmt = argv[i++]; -+ -+ if (argv[i] != NULL && argv[i][0] != '-') -+ agent_remote_id_fmt = argv[i]; -+ - add_agent_options = 1; - } else if (!strcmp(argv[i], "-A")) { - #ifdef DHCPv6 -@@ -938,6 +960,80 @@ find_interface_by_agent_option(struct dhcp_packet *packet, - } - - /* -+ * Format the message that will be used by circuit_id and remote_id -+ */ -+static int -+format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_packet *packet, -+ const char *format, char *msg, size_t msgn) { -+ size_t len = 0; -+ char hostname[HOST_NAME_MAX] = { 0 }; -+ char ifname[IFNAMSIZ] = { 0 }; -+ char *buf = msg; -+ -+ for ( ; format && *format && len < msgn; ++format) { -+ size_t strn = 0; -+ const char *str = NULL; -+ -+ if (*format == '%') { -+ switch (*++format) { -+ case '\0': -+ --format; -+ break; -+ -+ case '%': /* A literal '%' */ -+ str = "%"; -+ break; -+ -+ case 'h': /* Hostname */ -+ gethostname(hostname, HOST_NAME_MAX); -+ hostname[HOST_NAME_MAX - 1] = '\0'; -+ str = hostname; -+ break; -+ -+ case 'p': /* Name of interface that we received the request from */ -+ strncpy(ifname, ip->name, IFNAMSIZ); -+ str = ifname; -+ break; -+ -+ case 'P': /* Physical address of interface that we received the request from */ -+ str = print_hw_addr(ip->hw_address.hbuf[0], ip->hw_address.hlen - 1, &ip->hw_address.hbuf[1]); -+ break; -+ -+ case 'C': /* 24: Client hardware address */ -+ str = print_hw_addr(packet->htype, packet->hlen, packet->chaddr); -+ break; -+ -+ case 'I': /* 20: DHCP relay agent IP address */ -+ str = inet_ntoa(packet->giaddr); -+ break; -+ -+ default: -+ log_error("Option %%%c is unrecognized and will not be formatted!", *format); -+ continue; -+ } -+ -+ if (str) -+ strn = strlen(str); -+ } else { -+ str = format; -+ strn = 1; -+ } -+ -+ // Do we have room? -+ if ((strn+len) >= msgn) { -+ return 0; -+ } -+ -+ if (str && strn > 0) { -+ memcpy(buf+len, str, strn); -+ len += strn; -+ } -+ } -+ -+ return len; -+} -+ -+/* - * Examine a packet to see if it's a candidate to have a Relay - * Agent Information option tacked onto its tail. If it is, tack - * the option on. -@@ -946,8 +1042,11 @@ static int - add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, - unsigned length, struct in_addr giaddr) { - int is_dhcp = 0, mms; -- unsigned optlen; -+ unsigned optlen = 0; - u_int8_t *op, *nextop, *sp, *max, *end_pad = NULL; -+ char circuit_id_buf[256] = { '\0' }; -+ char remote_id_buf[256] = { '\0' }; -+ size_t circuit_id_len = 0, remote_id_len = 0; - - /* If we're not adding agent options to packets, we can skip - this. */ -@@ -1077,24 +1176,47 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, - op = sp; - #endif - -- /* Sanity check. Had better not ever happen. */ -- if ((ip->circuit_id_len > 255) ||(ip->circuit_id_len < 1)) -- log_fatal("Circuit ID length %d out of range [1-255] on " -- "%s\n", ip->circuit_id_len, ip->name); -- optlen = ip->circuit_id_len + 2; /* RAI_CIRCUIT_ID + len */ -- -- if (ip->remote_id) { -- if (ip->remote_id_len > 255 || ip->remote_id_len < 1) -- log_fatal("Remote ID length %d out of range [1-255] " -- "on %s\n", ip->circuit_id_len, ip->name); -- optlen += ip->remote_id_len + 2; /* RAI_REMOTE_ID + len */ -- } -+ /* option82: custom string for circuit_id */ -+ if (agent_circuit_id_fmt) { -+ circuit_id_len = format_relay_agent_rfc3046_msg(ip, packet, agent_circuit_id_fmt, -+ circuit_id_buf, sizeof(circuit_id_buf)); -+ -+ if (circuit_id_len == 0) { -+ strncpy(circuit_id_buf, ip->name, sizeof(ip->name)); -+ circuit_id_len = strlen(circuit_id_buf); -+ } -+ -+ /* Sanity check. Had better not ever happen. */ -+ if (circuit_id_len > 255 || circuit_id_len < 1) -+ log_fatal("Circuit ID length %d out of range [1-255] on %s\n", -+ (int)circuit_id_len, ip->name); -+ -+ optlen = circuit_id_len + 2; // RAI_CIRCUIT_ID + len -+ -+ //log_debug("Sending on %s option82:circuit_id='%s' (%d)", -+ // ip->name, circuit_id_buf, (int)circuit_id_len); -+ } -+ -+ /* option82: custom string for remote_id */ -+ if (agent_remote_id_fmt) { -+ remote_id_len = format_relay_agent_rfc3046_msg(ip, packet, agent_remote_id_fmt, -+ remote_id_buf, sizeof(remote_id_buf)); -+ -+ if (remote_id_len > 255 || remote_id_len < 1) -+ log_fatal("Remote ID length %d out of range [1-255] on %s\n", -+ (int)remote_id_len, ip->name); -+ -+ optlen += remote_id_len + 2; // RAI_REMOTE_ID + len -+ -+ //log_debug("Sending on %s option82:remote_id='%s' (%d)", -+ // ip->name, remote_id_buf, (int)remote_id_len); -+ } - -- /* We do not support relay option fragmenting(multiple options to -- * support an option data exceeding 255 bytes). -+ /* We do not support relay option fragmenting (multiple options to -+ * support an option data exceeding 255 bytes) - */ -- if ((optlen < 3) ||(optlen > 255)) -- log_fatal("Total agent option length(%u) out of range " -+ if (optlen < 3 || optlen > 255) -+ log_fatal("Total agent option length (%u) out of range " - "[3 - 255] on %s\n", optlen, ip->name); - - /* -@@ -1102,7 +1224,7 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, - * If not, forward without adding the option. - */ - if (max - sp >= optlen + 3) { -- log_debug("Adding %d-byte relay agent option", optlen + 3); -+ //log_debug("Adding %d-byte relay agent option", optlen + 3); - - /* Okay, cons up *our* Relay Agent Information option. */ - *sp++ = DHO_DHCP_AGENT_OPTIONS; -@@ -1110,16 +1232,16 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, - - /* Copy in the circuit id... */ - *sp++ = RAI_CIRCUIT_ID; -- *sp++ = ip->circuit_id_len; -- memcpy(sp, ip->circuit_id, ip->circuit_id_len); -- sp += ip->circuit_id_len; -+ *sp++ = circuit_id_len; -+ memcpy(sp, circuit_id_buf, circuit_id_len); -+ sp += circuit_id_len; - - /* Copy in remote ID... */ -- if (ip->remote_id) { -+ if (remote_id_len > 0) { - *sp++ = RAI_REMOTE_ID; -- *sp++ = ip->remote_id_len; -- memcpy(sp, ip->remote_id, ip->remote_id_len); -- sp += ip->remote_id_len; -+ *sp++ = remote_id_len; -+ memcpy(sp, remote_id_buf, remote_id_len); -+ sp += remote_id_len; - } - } else { - ++agent_option_errors; --- -2.1.4 - diff --git a/src/isc-dhcp/patch/0002-Customizable-Option-82-circuit-ID-and-remote-ID-fiel.patch b/src/isc-dhcp/patch/0002-Customizable-Option-82-circuit-ID-and-remote-ID-fiel.patch new file mode 100644 index 000000000000..a796845e516b --- /dev/null +++ b/src/isc-dhcp/patch/0002-Customizable-Option-82-circuit-ID-and-remote-ID-fiel.patch @@ -0,0 +1,265 @@ +From 6b4c2e815118fb7312b8e8a07ac61a772b57e91a Mon Sep 17 00:00:00 2001 +From: Joe LeVeque +Date: Thu, 25 Apr 2019 22:07:20 +0000 +Subject: [PATCH] Customizable Option 82 circuit ID and remote ID fields + +--- + relay/dhcrelay.c | 171 ++++++++++++++++++++++++++++++++++++++++------- + 1 file changed, 147 insertions(+), 24 deletions(-) + +diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c +index 344cee7..7b4c1ef 100644 +--- a/relay/dhcrelay.c ++++ b/relay/dhcrelay.c +@@ -75,6 +75,8 @@ int bad_circuit_id = 0; /* Circuit ID option in matching RAI option + did not match any known circuit ID. */ + int missing_circuit_id = 0; /* Circuit ID option in matching RAI option + was missing. */ ++const char *agent_circuit_id_fmt = NULL; /* Circuit ID custom format string. */ ++const char *agent_remote_id_fmt = NULL; /* Remote ID custom format string. */ + int max_hop_count = 10; /* Maximum hop count */ + + #ifdef DHCPv6 +@@ -148,9 +150,19 @@ static const char url[] = + + char *progname; + ++#define DHCRELAY_OPTION82_USAGE \ ++"circuit_id/remote_id interpreted sequences are:\n" \ ++"\n" \ ++" %%%% A single %%\n" \ ++" %%h Hostname of device\n" \ ++" %%p Name of interface that generated the request\n" \ ++" %%P Hardware address of interface that generated the request\n" \ ++" %%C Client hardware address\n" \ ++" %%I DHCP relay agent IP Address\n" \ ++ + #ifdef DHCPv6 + #define DHCRELAY_USAGE \ +-"Usage: %s [-4] [-d] [-q] [-a] [-D]\n"\ ++"Usage: %s [-4] [-d] [-q] [-a ] [-D]\n"\ + " [-A ] [-c ] [-p ]\n" \ + " [-pf ] [--no-pid]\n"\ + " [-m append|replace|forward|discard]\n" \ +@@ -165,17 +177,18 @@ char *progname; + " -l lower0 [ ... -l lowerN]\n" \ + " -u upper0 [ ... -u upperN]\n" \ + " lower (client link): [address%%]interface[#index]\n" \ +-" upper (server link): [address%%]interface" ++" upper (server link): [address%%]interface\n\n" DHCRELAY_OPTION82_USAGE + #else + #define DHCRELAY_USAGE \ +-"Usage: %s [-d] [-q] [-a] [-D] [-A ] [-c ] [-p ]\n" \ ++"Usage: %s [-d] [-q] [-a ] [-D]\n" \ ++" [-A ] [-c ] [-p ]\n" \ + " [-pf ] [--no-pid]\n" \ + " [-m append|replace|forward|discard]\n" \ + " [-i interface0 [ ... -i interfaceN]\n" \ + " [-iu interface0 [ ... -iu interfaceN]\n" \ + " [-id interface0 [ ... -id interfaceN]\n" \ + " [-U interface]\n" \ +-" server0 [ ... serverN]\n\n" ++" server0 [ ... serverN]\n\n" DHCRELAY_OPTION82_USAGE + #endif + + /*! +@@ -354,6 +367,15 @@ main(int argc, char **argv) { + local_family_set = 1; + local_family = AF_INET; + #endif ++ if (++i == argc) ++ usage(use_noarg, argv[i-1]); ++ ++ if (argv[i] != NULL && argv[i][0] != '-') ++ agent_circuit_id_fmt = argv[i++]; ++ ++ if (argv[i] != NULL && argv[i][0] != '-') ++ agent_remote_id_fmt = argv[i]; ++ + add_agent_options = 1; + } else if (!strcmp(argv[i], "-A")) { + #ifdef DHCPv6 +@@ -1050,6 +1072,81 @@ find_interface_by_agent_option(struct dhcp_packet *packet, + return (-1); + } + ++/* ++ * Format the message that will be used by circuit_id and remote_id ++ */ ++static int ++format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_packet *packet, ++ const char *format, char *msg, size_t msgn) { ++ size_t len = 0; ++ char hostname[HOST_NAME_MAX] = { 0 }; ++ char ifname[IFNAMSIZ] = { 0 }; ++ char *buf = msg; ++ ++ for ( ; format && *format && len < msgn; ++format) { ++ size_t strn = 0; ++ const char *str = NULL; ++ ++ if (*format == '%') { ++ switch (*++format) { ++ case '\0': ++ --format; ++ break; ++ ++ case '%': /* A literal '%' */ ++ str = "%"; ++ break; ++ ++ case 'h': /* Hostname */ ++ gethostname(hostname, HOST_NAME_MAX); ++ hostname[HOST_NAME_MAX - 1] = '\0'; ++ str = hostname; ++ break; ++ ++ case 'p': /* Name of interface that we received the request from */ ++ strncpy(ifname, ip->name, IFNAMSIZ); ++ str = ifname; ++ break; ++ ++ case 'P': /* Physical address of interface that we received the request from */ ++ str = print_hw_addr(ip->hw_address.hbuf[0], ip->hw_address.hlen - 1, &ip->hw_address.hbuf[1]); ++ break; ++ ++ case 'C': /* 24: Client hardware address */ ++ str = print_hw_addr(packet->htype, packet->hlen, packet->chaddr); ++ break; ++ ++ case 'I': /* 20: DHCP relay agent IP address */ ++ str = inet_ntoa(packet->giaddr); ++ break; ++ ++ default: ++ log_error("Option %%%c is unrecognized and will not be formatted!", *format); ++ continue; ++ } ++ ++ if (str) { ++ strn = strlen(str); ++ } ++ } else { ++ str = format; ++ strn = 1; ++ } ++ ++ // Do we have room? ++ if ((strn+len) >= msgn) { ++ return 0; ++ } ++ ++ if (str && strn > 0) { ++ memcpy(buf+len, str, strn); ++ len += strn; ++ } ++ } ++ ++ return len; ++} ++ + /* + * Examine a packet to see if it's a candidate to have a Relay + * Agent Information option tacked onto its tail. If it is, tack +@@ -1059,9 +1156,12 @@ static int + add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, + unsigned length, struct in_addr giaddr) { + int is_dhcp = 0, mms; +- unsigned optlen; ++ unsigned optlen = 0; + u_int8_t *op, *nextop, *sp, *max, *end_pad = NULL; + int adding_link_select; ++ char circuit_id_buf[256] = { '\0' }; ++ char remote_id_buf[256] = { '\0' }; ++ size_t circuit_id_len = 0, remote_id_len = 0; + + /* If we're not adding agent options to packets, we can skip + this. */ +@@ -1195,17 +1295,40 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, + op = sp; + #endif + +- /* Sanity check. Had better not ever happen. */ +- if ((ip->circuit_id_len > 255) ||(ip->circuit_id_len < 1)) +- log_fatal("Circuit ID length %d out of range [1-255] on " +- "%s\n", ip->circuit_id_len, ip->name); +- optlen = ip->circuit_id_len + 2; /* RAI_CIRCUIT_ID + len */ +- +- if (ip->remote_id) { +- if (ip->remote_id_len > 255 || ip->remote_id_len < 1) +- log_fatal("Remote ID length %d out of range [1-255] " +- "on %s\n", ip->remote_id_len, ip->name); +- optlen += ip->remote_id_len + 2; /* RAI_REMOTE_ID + len */ ++ /* option82: custom string for circuit_id */ ++ if (agent_circuit_id_fmt) { ++ circuit_id_len = format_relay_agent_rfc3046_msg(ip, packet, agent_circuit_id_fmt, ++ circuit_id_buf, sizeof(circuit_id_buf)); ++ ++ if (circuit_id_len == 0) { ++ strncpy(circuit_id_buf, ip->name, sizeof(ip->name)); ++ circuit_id_len = strlen(circuit_id_buf); ++ } ++ ++ /* Sanity check. Had better not ever happen. */ ++ if (circuit_id_len > 255 || circuit_id_len < 1) ++ log_fatal("Circuit ID length %d out of range [1-255] on %s\n", ++ (int)circuit_id_len, ip->name); ++ ++ optlen = circuit_id_len + 2; // RAI_CIRCUIT_ID + len ++ ++ //log_debug("Sending on %s option82:circuit_id='%s' (%d)", ++ // ip->name, circuit_id_buf, (int)circuit_id_len); ++ } ++ ++ /* option82: custom string for remote_id */ ++ if (agent_remote_id_fmt) { ++ remote_id_len = format_relay_agent_rfc3046_msg(ip, packet, agent_remote_id_fmt, ++ remote_id_buf, sizeof(remote_id_buf)); ++ ++ if (remote_id_len > 255 || remote_id_len < 1) ++ log_fatal("Remote ID length %d out of range [1-255] on %s\n", ++ (int)remote_id_len, ip->name); ++ ++ optlen += remote_id_len + 2; // RAI_REMOTE_ID + len ++ ++ //log_debug("Sending on %s option82:remote_id='%s' (%d)", ++ // ip->name, remote_id_buf, (int)remote_id_len); + } + + if (adding_link_select) { +@@ -1224,7 +1347,7 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, + * If not, forward without adding the option. + */ + if (max - sp >= optlen + 3) { +- log_debug("Adding %d-byte relay agent option", optlen + 3); ++ //log_debug("Adding %d-byte relay agent option", optlen + 3); + + /* Okay, cons up *our* Relay Agent Information option. */ + *sp++ = DHO_DHCP_AGENT_OPTIONS; +@@ -1232,16 +1355,16 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, + + /* Copy in the circuit id... */ + *sp++ = RAI_CIRCUIT_ID; +- *sp++ = ip->circuit_id_len; +- memcpy(sp, ip->circuit_id, ip->circuit_id_len); +- sp += ip->circuit_id_len; ++ *sp++ = circuit_id_len; ++ memcpy(sp, circuit_id_buf, circuit_id_len); ++ sp += circuit_id_len; + + /* Copy in remote ID... */ +- if (ip->remote_id) { ++ if (remote_id_len > 0) { + *sp++ = RAI_REMOTE_ID; +- *sp++ = ip->remote_id_len; +- memcpy(sp, ip->remote_id, ip->remote_id_len); +- sp += ip->remote_id_len; ++ *sp++ = remote_id_len; ++ memcpy(sp, remote_id_buf, remote_id_len); ++ sp += remote_id_len; + } + + /* RFC3527: Use the inbound packet's interface address in +-- +2.17.1 + diff --git a/src/isc-dhcp/patch/0002-Support-for-obtaining-name-of-physical-interface-tha.patch b/src/isc-dhcp/patch/0002-Support-for-obtaining-name-of-physical-interface-tha.patch deleted file mode 100644 index ee85a7736287..000000000000 --- a/src/isc-dhcp/patch/0002-Support-for-obtaining-name-of-physical-interface-tha.patch +++ /dev/null @@ -1,114 +0,0 @@ -From caad3e05c31c9fad8cda378ce95a1969def771a2 Mon Sep 17 00:00:00 2001 -From: Joe LeVeque -Date: Mon, 11 Dec 2017 23:39:10 +0000 -Subject: [PATCH 2/3] Support for obtaining name of physical interface that is - a member of a bridge interface - ---- - relay/dhcrelay.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- - 1 file changed, 67 insertions(+), 2 deletions(-) - -diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c -index b9f8326..8458ea9 100644 ---- a/relay/dhcrelay.c -+++ b/relay/dhcrelay.c -@@ -758,6 +758,7 @@ do_relay4(struct interface_info *ip, struct dhcp_packet *packet, - print_hw_addr(packet->htype, packet->hlen, - packet->chaddr), - inet_ntoa(sp->to.sin_addr)); -+ - ++client_packets_relayed; - } - } -@@ -917,6 +918,7 @@ find_interface_by_agent_option(struct dhcp_packet *packet, - ++corrupt_agent_options; - return (-1); - } -+ - switch(buf[i]) { - /* Remember where the circuit ID is... */ - case RAI_CIRCUIT_ID: -@@ -959,6 +961,47 @@ find_interface_by_agent_option(struct dhcp_packet *packet, - return (-1); - } - -+static int -+_bridgefdbquery(const char *hwAddr, char *interface, int *vlanid) { -+ -+#define xstr(s) str(s) -+#define str(s) #s -+#define FDB_STRING_LEN 100 -+#define FDB_BUFFER_LEN (FDB_STRING_LEN + 1) -+ -+/* -+ * Format for sscanf() to read the 1st, 3th, and 5th -+ * space-delimited fields -+ * -+ * bridge fdb show output -+ * 6c:64:1a:00:06:13 dev swp35 vlan 0 master bridge permanent -+ */ -+#define FDB_LINE_FORMAT "%" xstr(FDB_STRING_LEN) "s %*s " \ -+ "%" xstr(FDB_STRING_LEN) "s %*s %d %*s" -+ -+ char cmdstr[FDB_BUFFER_LEN]; -+ char buf[FDB_BUFFER_LEN]; -+ char macAddr[FDB_BUFFER_LEN]; -+ -+ if ((interface == NULL) || (vlanid == NULL)) { -+ return 0; -+ } -+ sprintf(cmdstr, "bridge fdb show | grep -m 1 %s", hwAddr); -+ FILE *cmd = popen(cmdstr, "r"); -+ -+ if (cmd != NULL) { -+ while (fgets(buf, sizeof(buf), cmd)) { -+ sscanf(buf, FDB_LINE_FORMAT, macAddr, interface, vlanid); -+ //log_debug("bridgefdbquery: macAddr: %s interface: %s vlanid: %d", -+ // macAddr, interface, *vlanid); -+ } -+ pclose(cmd); -+ return 0; -+ } -+ -+ return -1; -+} -+ - /* - * Format the message that will be used by circuit_id and remote_id - */ -@@ -991,8 +1034,30 @@ format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_pack - break; - - case 'p': /* Name of interface that we received the request from */ -- strncpy(ifname, ip->name, IFNAMSIZ); -- str = ifname; -+ /* -+ * Query FDB to identify the exact physical interface only when source MAC address -+ * is present and '20: DHCP relay agent IP address' (giaddr) is not present -+ */ -+ if (packet->htype && !packet->giaddr.s_addr) { -+ int ret = 0, vlanid = 0; -+ -+ ret = _bridgefdbquery(print_hw_addr(packet->htype, packet->hlen, packet->chaddr), -+ ifname, -+ &vlanid); -+ -+ // If we failed to find a physical interface using the source mac, default -+ // to the interface name we received it on. -+ if (ret < 0) { -+ //log_debug("MAC Address: %s (interface:%s vlan:%d) not found in bridge fdb show", -+ // print_hw_addr (packet->htype, packet->hlen, packet->chaddr), -+ // ip->name, -+ // vlanid); -+ -+ strncpy(ifname, ip->name, IFNAMSIZ); -+ } -+ -+ str = ifname; -+ } - break; - - case 'P': /* Physical address of interface that we received the request from */ --- -2.1.4 - diff --git a/src/isc-dhcp/patch/0003-Support-for-loading-port-alias-map-file-to-replace-p.patch b/src/isc-dhcp/patch/0003-Support-for-loading-port-alias-map-file-to-replace-p.patch deleted file mode 100644 index 7411e1c4ff3e..000000000000 --- a/src/isc-dhcp/patch/0003-Support-for-loading-port-alias-map-file-to-replace-p.patch +++ /dev/null @@ -1,187 +0,0 @@ -From 3a42b497716375c9347b51c3a28c5e91e7cd4cf4 Mon Sep 17 00:00:00 2001 -From: Joe LeVeque -Date: Tue, 12 Dec 2017 00:49:09 +0000 -Subject: [PATCH 3/3] Support for loading port alias map file to replace port - name with alias in circuit id - ---- - relay/dhcrelay.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 105 insertions(+), 1 deletion(-) - -diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c -index 8458ea9..15f0acf 100644 ---- a/relay/dhcrelay.c -+++ b/relay/dhcrelay.c -@@ -122,6 +122,14 @@ static void setup_streams(void); - char *dhcrelay_sub_id = NULL; - #endif - -+struct interface_name_alias_tuple { -+ char if_name[IFNAMSIZ]; -+ char if_alias[IFNAMSIZ]; -+}; -+ -+static struct interface_name_alias_tuple *g_interface_name_alias_map = NULL; -+static size_t g_interface_name_alias_map_size = 0; -+ - static void do_relay4(struct interface_info *, struct dhcp_packet *, - unsigned int, unsigned int, struct iaddr, - struct hardware *); -@@ -134,6 +142,10 @@ static int strip_relay_agent_options(struct interface_info *, - struct interface_info **, - struct dhcp_packet *, unsigned); - -+static int load_interface_alias_map(const char *port_alias_map_file_path); -+static int get_interface_alias_by_name(const char *if_name, char *if_alias_out); -+static void free_interface_alias_map(void); -+ - static const char copyright[] = - "Copyright 2004-2015 Internet Systems Consortium."; - static const char arr[] = "All rights reserved."; -@@ -147,7 +159,7 @@ static const char url[] = - "\n" \ - " %%%% A single %%\n" \ - " %%h Hostname of device\n" \ --" %%p Name of interface that generated the request\n" \ -+" %%p Alias of interface that generated the request\n" \ - " %%P Hardware address of interface that generated the request\n" \ - " %%C Client hardware address\n" \ - " %%I DHCP relay agent IP Address\n" \ -@@ -158,10 +170,12 @@ static const char url[] = - " [-A ] [-c ] [-p ]\n" \ - " [-pf ] [--no-pid]\n"\ - " [-m append|replace|forward|discard]\n" \ -+" [--name-alias-map-file ]\n" \ - " [-i interface0 [ ... -i interfaceN]\n" \ - " server0 [ ... serverN]\n\n" \ - " dhcrelay -6 [-d] [-q] [-I] [-c ] [-p ]\n" \ - " [-pf ] [--no-pid]\n" \ -+" [--name-alias-map-file ]\n" \ - " [-s ]\n" \ - " -l lower0 [ ... -l lowerN]\n" \ - " -u upper0 [ ... -u upperN]\n" \ -@@ -405,6 +419,11 @@ main(int argc, char **argv) { - no_dhcrelay_pid = ISC_TRUE; - } else if (!strcmp(argv[i], "--no-pid")) { - no_pid_file = ISC_TRUE; -+ } else if (!strcmp(argv[i], "--name-alias-map-file")) { -+ if (++i == argc) -+ usage(); -+ if (load_interface_alias_map(argv[i]) != 0) -+ log_fatal("Failed to load interface name-alias map."); - } else if (!strcmp(argv[i], "--version")) { - log_info("isc-dhcrelay-%s", PACKAGE_VERSION); - exit(0); -@@ -624,6 +643,8 @@ main(int argc, char **argv) { - dispatch(); - - /* In fact dispatch() never returns. */ -+ free_interface_alias_map(); -+ - return (0); - } - -@@ -1040,6 +1061,7 @@ format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_pack - */ - if (packet->htype && !packet->giaddr.s_addr) { - int ret = 0, vlanid = 0; -+ char ifalias[IFNAMSIZ] = { 0 }; - - ret = _bridgefdbquery(print_hw_addr(packet->htype, packet->hlen, packet->chaddr), - ifname, -@@ -1056,6 +1078,18 @@ format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_pack - strncpy(ifname, ip->name, IFNAMSIZ); - } - -+ // Attempt to translate SONiC interface name to vendor alias -+ ret = get_interface_alias_by_name(ifname, ifalias); -+ if (ret < 0) { -+ //log_debug("Failed to retrieve alias for interface name '%s'. Defaulting to interface name.", ifname); -+ } -+ else { -+ //log_debug("Mapped interface name '%s' to alias '%s'. Adding as option 82 interface alias for MAC Address %s", -+ // ifname, ifalias, print_hw_addr (packet->htype, packet->hlen, packet->chaddr)); -+ -+ strncpy(ifname, ifalias, IFNAMSIZ); -+ } -+ - str = ifname; - } - break; -@@ -1922,3 +1956,73 @@ dhcp_set_control_state(control_object_state_t oldstate, - - exit(0); - } -+ -+#define MAX_PORT_CONFIG_LINE_LEN 1024 -+ -+// Allocates and loads global map g_interface_name_alias_map -+// Also sets global g_interface_name_alias_map_size -+static int -+load_interface_alias_map(const char *port_alias_map_file_path) { -+ int i = 0; -+ FILE *fp = NULL; -+ char line[MAX_PORT_CONFIG_LINE_LEN] = { 0 }; -+ -+ fp = fopen(port_alias_map_file_path,"r"); -+ if (fp == NULL) { -+ log_error("Unable to open %s", port_alias_map_file_path); -+ return -1; -+ } -+ -+ g_interface_name_alias_map_size = 0; -+ -+ // Count the number of interfaces listed in the file -+ while (fgets(line, sizeof(line), fp)) { -+ g_interface_name_alias_map_size++; -+ } -+ -+ // Allocate our map accordingly -+ g_interface_name_alias_map = ((struct interface_name_alias_tuple *) -+ dmalloc((sizeof(struct interface_name_alias_tuple) * g_interface_name_alias_map_size), -+ MDL)); -+ -+ // Reset file position indicator to beginning of file -+ fseek(fp, 0, SEEK_SET); -+ -+ // Every line should contain exactly one name-alias pair -+ while (fgets(line, sizeof(line), fp)) { -+ // Each line should read as "" -+ sscanf(line, "%s %s", g_interface_name_alias_map[i].if_name, g_interface_name_alias_map[i].if_alias); -+ i++; -+ } -+ -+ fclose(fp); -+ -+ log_info("Loaded %d interface name-alias mappings", i); -+ -+ return 0; -+} -+ -+// Locates alias for port named if_name, copies alias into if_alias_out, up to a -+// max of IFNAMSIZ bytes. -+// Returns 0 on success, -1 on failure -+static int -+get_interface_alias_by_name(const char *if_name, char *if_alias_out) { -+ int i = 0; -+ -+ for (i = 0; i < g_interface_name_alias_map_size; i++) { -+ if (strncmp(if_name, g_interface_name_alias_map[i].if_name, IFNAMSIZ) == 0) { -+ strncpy(if_alias_out, g_interface_name_alias_map[i].if_alias, IFNAMSIZ); -+ return 0; -+ } -+ } -+ -+ return -1; -+} -+ -+// Frees global map g_interface_name_alias_map -+// Sets g_interface_name_alias_map_size to 0 -+static void -+free_interface_alias_map(void) { -+ free(g_interface_name_alias_map); -+ g_interface_name_alias_map_size = 0; -+} --- -2.1.4 - diff --git a/src/isc-dhcp/patch/0003-Support-for-obtaining-name-of-physical-interface-tha.patch b/src/isc-dhcp/patch/0003-Support-for-obtaining-name-of-physical-interface-tha.patch new file mode 100644 index 000000000000..fd9ff420d970 --- /dev/null +++ b/src/isc-dhcp/patch/0003-Support-for-obtaining-name-of-physical-interface-tha.patch @@ -0,0 +1,98 @@ +From ab0be27d3862c7287e3b181cc6a70effa054be1c Mon Sep 17 00:00:00 2001 +From: Joe LeVeque +Date: Fri, 26 Apr 2019 01:06:49 +0000 +Subject: [PATCH] Support for obtaining name of physical interface that is a + member of a bridge interface + +--- + relay/dhcrelay.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 65 insertions(+), 2 deletions(-) + +diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c +index 4659660..0f7d658 100644 +--- a/relay/dhcrelay.c ++++ b/relay/dhcrelay.c +@@ -1072,6 +1072,47 @@ find_interface_by_agent_option(struct dhcp_packet *packet, + return (-1); + } + ++static int ++_bridgefdbquery(const char *hwAddr, char *interface, int *vlanid) { ++ ++#define xstr(s) str(s) ++#define str(s) #s ++#define FDB_STRING_LEN 100 ++#define FDB_BUFFER_LEN (FDB_STRING_LEN + 1) ++ ++/* ++ * Format for sscanf() to read the 1st, 3th, and 5th ++ * space-delimited fields ++ * ++ * bridge fdb show output ++ * 6c:64:1a:00:06:13 dev swp35 vlan 0 master bridge permanent ++ */ ++#define FDB_LINE_FORMAT "%" xstr(FDB_STRING_LEN) "s %*s " \ ++ "%" xstr(FDB_STRING_LEN) "s %*s %d %*s" ++ ++ char cmdstr[FDB_BUFFER_LEN]; ++ char buf[FDB_BUFFER_LEN]; ++ char macAddr[FDB_BUFFER_LEN]; ++ ++ if ((interface == NULL) || (vlanid == NULL)) { ++ return 0; ++ } ++ sprintf(cmdstr, "bridge fdb show | grep -m 1 %s", hwAddr); ++ FILE *cmd = popen(cmdstr, "r"); ++ ++ if (cmd != NULL) { ++ while (fgets(buf, sizeof(buf), cmd)) { ++ sscanf(buf, FDB_LINE_FORMAT, macAddr, interface, vlanid); ++ //log_debug("bridgefdbquery: macAddr: %s interface: %s vlanid: %d", ++ // macAddr, interface, *vlanid); ++ } ++ pclose(cmd); ++ return 0; ++ } ++ ++ return -1; ++} ++ + /* + * Format the message that will be used by circuit_id and remote_id + */ +@@ -1104,8 +1145,30 @@ format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_pack + break; + + case 'p': /* Name of interface that we received the request from */ +- strncpy(ifname, ip->name, IFNAMSIZ); +- str = ifname; ++ /* ++ * Query FDB to identify the exact physical interface only when source MAC address ++ * is present and '20: DHCP relay agent IP address' (giaddr) is not present ++ */ ++ if (packet->htype && !packet->giaddr.s_addr) { ++ int ret = 0, vlanid = 0; ++ ++ ret = _bridgefdbquery(print_hw_addr(packet->htype, packet->hlen, packet->chaddr), ++ ifname, ++ &vlanid); ++ ++ // If we failed to find a physical interface using the source mac, default ++ // to the interface name we received it on. ++ if (ret < 0) { ++ //log_debug("MAC Address: %s (interface:%s vlan:%d) not found in bridge fdb show", ++ // print_hw_addr (packet->htype, packet->hlen, packet->chaddr), ++ // ip->name, ++ // vlanid); ++ ++ strncpy(ifname, ip->name, IFNAMSIZ); ++ } ++ ++ str = ifname; ++ } + break; + + case 'P': /* Physical address of interface that we received the request from */ +-- +2.17.1 + diff --git a/src/isc-dhcp/patch/0004-Support-for-loading-port-alias-map-file-to-replace-p.patch b/src/isc-dhcp/patch/0004-Support-for-loading-port-alias-map-file-to-replace-p.patch new file mode 100644 index 000000000000..b564a0822a0c --- /dev/null +++ b/src/isc-dhcp/patch/0004-Support-for-loading-port-alias-map-file-to-replace-p.patch @@ -0,0 +1,189 @@ +From 9d255bbd7d7aadac5b57cba2ab4e29cecdf0180f Mon Sep 17 00:00:00 2001 +From: Joe LeVeque +Date: Fri, 26 Apr 2019 01:26:45 +0000 +Subject: [PATCH] Support for loading port alias map file to replace port name + with alias in circuit id + +--- + relay/dhcrelay.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 104 insertions(+), 1 deletion(-) + +diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c +index 0f7d658..797dac6 100644 +--- a/relay/dhcrelay.c ++++ b/relay/dhcrelay.c +@@ -126,6 +126,14 @@ static void setup_streams(void); + char *dhcrelay_sub_id = NULL; + #endif + ++struct interface_name_alias_tuple { ++ char if_name[IFNAMSIZ]; ++ char if_alias[IFNAMSIZ]; ++}; ++ ++static struct interface_name_alias_tuple *g_interface_name_alias_map = NULL; ++static size_t g_interface_name_alias_map_size = 0; ++ + static void do_relay4(struct interface_info *, struct dhcp_packet *, + unsigned int, unsigned int, struct iaddr, + struct hardware *); +@@ -140,6 +148,10 @@ static int strip_relay_agent_options(struct interface_info *, + + static void request_v4_interface(const char* name, int flags); + ++static int load_interface_alias_map(const char *port_alias_map_file_path); ++static int get_interface_alias_by_name(const char *if_name, char *if_alias_out); ++static void free_interface_alias_map(void); ++ + static const char copyright[] = + "Copyright 2004-2016 Internet Systems Consortium."; + static const char arr[] = "All rights reserved."; +@@ -155,7 +167,7 @@ char *progname; + "\n" \ + " %%%% A single %%\n" \ + " %%h Hostname of device\n" \ +-" %%p Name of interface that generated the request\n" \ ++" %%p Alias of interface that generated the request\n" \ + " %%P Hardware address of interface that generated the request\n" \ + " %%C Client hardware address\n" \ + " %%I DHCP relay agent IP Address\n" \ +@@ -166,6 +178,7 @@ char *progname; + " [-A ] [-c ] [-p ]\n" \ + " [-pf ] [--no-pid]\n"\ + " [-m append|replace|forward|discard]\n" \ ++" [--name-alias-map-file ]\n" \ + " [-i interface0 [ ... -i interfaceN]\n" \ + " [-iu interface0 [ ... -iu interfaceN]\n" \ + " [-id interface0 [ ... -id interfaceN]\n" \ +@@ -173,6 +186,7 @@ char *progname; + " server0 [ ... serverN]\n\n" \ + " %s -6 [-d] [-q] [-I] [-c ] [-p ]\n" \ + " [-pf ] [--no-pid]\n" \ ++" [--name-alias-map-file ]\n" \ + " [-s ]\n" \ + " -l lower0 [ ... -l lowerN]\n" \ + " -u upper0 [ ... -u upperN]\n" \ +@@ -503,6 +517,11 @@ main(int argc, char **argv) { + no_dhcrelay_pid = ISC_TRUE; + } else if (!strcmp(argv[i], "--no-pid")) { + no_pid_file = ISC_TRUE; ++ } else if (!strcmp(argv[i], "--name-alias-map-file")) { ++ if (++i == argc) ++ usage(use_noarg, argv[i-1]); ++ if (load_interface_alias_map(argv[i]) != 0) ++ log_fatal("Failed to load interface name-alias map."); + } else if (!strcmp(argv[i], "--version")) { + log_info("isc-dhcrelay-%s", PACKAGE_VERSION); + exit(0); +@@ -726,6 +745,7 @@ main(int argc, char **argv) { + dispatch(); + + /* In fact dispatch() never returns. */ ++ free_interface_alias_map(); + return (0); + } + +@@ -1151,6 +1171,7 @@ format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_pack + */ + if (packet->htype && !packet->giaddr.s_addr) { + int ret = 0, vlanid = 0; ++ char ifalias[IFNAMSIZ] = { 0 }; + + ret = _bridgefdbquery(print_hw_addr(packet->htype, packet->hlen, packet->chaddr), + ifname, +@@ -1167,6 +1188,18 @@ format_relay_agent_rfc3046_msg(const struct interface_info *ip, struct dhcp_pack + strncpy(ifname, ip->name, IFNAMSIZ); + } + ++ // Attempt to translate SONiC interface name to vendor alias ++ ret = get_interface_alias_by_name(ifname, ifalias); ++ if (ret < 0) { ++ //log_debug("Failed to retrieve alias for interface name '%s'. Defaulting to interface name.", ifname); ++ } ++ else { ++ //log_debug("Mapped interface name '%s' to alias '%s'. Adding as option 82 interface alias for MAC Address %s", ++ // ifname, ifalias, print_hw_addr (packet->htype, packet->hlen, packet->chaddr)); ++ ++ strncpy(ifname, ifalias, IFNAMSIZ); ++ } ++ + str = ifname; + } + break; +@@ -2096,3 +2129,73 @@ void request_v4_interface(const char* name, int flags) { + interface_snorf(tmp, (INTERFACE_REQUESTED | flags)); + interface_dereference(&tmp, MDL); + } ++ ++#define MAX_PORT_CONFIG_LINE_LEN 1024 ++ ++// Allocates and loads global map g_interface_name_alias_map ++// Also sets global g_interface_name_alias_map_size ++static int ++load_interface_alias_map(const char *port_alias_map_file_path) { ++ int i = 0; ++ FILE *fp = NULL; ++ char line[MAX_PORT_CONFIG_LINE_LEN] = { 0 }; ++ ++ fp = fopen(port_alias_map_file_path,"r"); ++ if (fp == NULL) { ++ log_error("Unable to open %s", port_alias_map_file_path); ++ return -1; ++ } ++ ++ g_interface_name_alias_map_size = 0; ++ ++ // Count the number of interfaces listed in the file ++ while (fgets(line, sizeof(line), fp)) { ++ g_interface_name_alias_map_size++; ++ } ++ ++ // Allocate our map accordingly ++ g_interface_name_alias_map = ((struct interface_name_alias_tuple *) ++ dmalloc((sizeof(struct interface_name_alias_tuple) * g_interface_name_alias_map_size), ++ MDL)); ++ ++ // Reset file position indicator to beginning of file ++ fseek(fp, 0, SEEK_SET); ++ ++ // Every line should contain exactly one name-alias pair ++ while (fgets(line, sizeof(line), fp)) { ++ // Each line should read as "" ++ sscanf(line, "%s %s", g_interface_name_alias_map[i].if_name, g_interface_name_alias_map[i].if_alias); ++ i++; ++ } ++ ++ fclose(fp); ++ ++ log_info("Loaded %d interface name-alias mappings", i); ++ ++ return 0; ++} ++ ++// Locates alias for port named if_name, copies alias into if_alias_out, up to a ++// max of IFNAMSIZ bytes. ++// Returns 0 on success, -1 on failure ++static int ++get_interface_alias_by_name(const char *if_name, char *if_alias_out) { ++ int i = 0; ++ ++ for (i = 0; i < g_interface_name_alias_map_size; i++) { ++ if (strncmp(if_name, g_interface_name_alias_map[i].if_name, IFNAMSIZ) == 0) { ++ strncpy(if_alias_out, g_interface_name_alias_map[i].if_alias, IFNAMSIZ); ++ return 0; ++ } ++ } ++ ++ return -1; ++} ++ ++// Frees global map g_interface_name_alias_map ++// Sets g_interface_name_alias_map_size to 0 ++static void ++free_interface_alias_map(void) { ++ free(g_interface_name_alias_map); ++ g_interface_name_alias_map_size = 0; ++} +-- +2.17.1 + diff --git a/src/isc-dhcp/patch/0005-CVE-2017-3144.patch b/src/isc-dhcp/patch/0005-CVE-2017-3144.patch deleted file mode 100644 index fe066e177a8c..000000000000 --- a/src/isc-dhcp/patch/0005-CVE-2017-3144.patch +++ /dev/null @@ -1,47 +0,0 @@ -From: Thomas Markwalder -Date: Thu, 7 Dec 2017 11:23:36 -0500 -Subject: [master] Plugs a socket descriptor leak in OMAPI -Origin: https://source.isc.org/cgi-bin/gitweb.cgi?p=dhcp.git;a=commit;h=1a6b62fe17a42b00fa234d06b6dfde3d03451894 -Bug: https://bugs.isc.org/Public/Bug/Display.html?id=46767 -Bug-Debian: https://bugs.debian.org/887413 -Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2017-3144 - - Merges in rt46767. ---- - -diff --git a/omapip/buffer.c b/omapip/buffer.c -index 6e0621b5..a21f0a80 100644 ---- a/omapip/buffer.c -+++ b/omapip/buffer.c -@@ -565,6 +565,15 @@ isc_result_t omapi_connection_writer (omapi_object_t *h) - omapi_buffer_dereference (&buffer, MDL); - } - } -+ -+ /* If we had data left to write when we're told to disconnect, -+ * we need recall disconnect, now that we're done writing. -+ * See rt46767. */ -+ if (c->out_bytes == 0 && c->state == omapi_connection_disconnecting) { -+ omapi_disconnect (h, 1); -+ return ISC_R_SHUTTINGDOWN; -+ } -+ - return ISC_R_SUCCESS; - } - -diff --git a/omapip/message.c b/omapip/message.c -index ee15d821..37abbd25 100644 ---- a/omapip/message.c -+++ b/omapip/message.c -@@ -339,7 +339,7 @@ isc_result_t omapi_message_unregister (omapi_object_t *mo) - } - - #ifdef DEBUG_PROTOCOL --static const char *omapi_message_op_name(int op) { -+const char *omapi_message_op_name(int op) { - switch (op) { - case OMAPI_OP_OPEN: return "OMAPI_OP_OPEN"; - case OMAPI_OP_REFRESH: return "OMAPI_OP_REFRESH"; --- -2.16.2 - diff --git a/src/isc-dhcp/patch/0006-CVE-2018-5733.patch b/src/isc-dhcp/patch/0006-CVE-2018-5733.patch deleted file mode 100644 index f2ddff0503eb..000000000000 --- a/src/isc-dhcp/patch/0006-CVE-2018-5733.patch +++ /dev/null @@ -1,145 +0,0 @@ -From: Zhenggen Xu -Date: Thu, 11 Oct 2018 17:18:32 -0700 -Subject: [PATCH] Subject: [master] Corrected refcnt loss in option parsing - Origin: - https://source.isc.org/cgi-bin/gitweb.cgi?p=dhcp.git;a=commit;h=197b26f25309f947b97a83b8fdfc414b767798f8 - Bug: https://bugs.isc.org/Public/Bug/Display.html?id=47140 Bug-Debian: - https://bugs.debian.org/891785 Bug-Debian-Security: - https://security-tracker.debian.org/tracker/CVE-2018-5733 - - Merges in 47140. ---- - common/options.c | 2 + - common/tests/Makefile.am | 11 ++++- - common/tests/option_unittest.c | 79 ++++++++++++++++++++++++++++++++++ - 3 files changed, 91 insertions(+), 1 deletion(-) - create mode 100644 common/tests/option_unittest.c - -diff --git a/common/options.c b/common/options.c -index 74f1fb5..db28b5c 100644 ---- a/common/options.c -+++ b/common/options.c -@@ -177,6 +177,8 @@ int parse_option_buffer (options, buffer, length, universe) - - /* If the length is outrageous, the options are bad. */ - if (offset + len > length) { -+ /* Avoid reference count overflow */ -+ option_dereference(&option, MDL); - reason = "option length exceeds option buffer length"; - bogus: - log_error("parse_option_buffer: malformed option " -diff --git a/common/tests/Makefile.am b/common/tests/Makefile.am -index 32e055c..19521c9 100644 ---- a/common/tests/Makefile.am -+++ b/common/tests/Makefile.am -@@ -8,7 +8,8 @@ ATF_TESTS = - - if HAVE_ATF - --ATF_TESTS += alloc_unittest dns_unittest misc_unittest ns_name_unittest -+ATF_TESTS += alloc_unittest dns_unittest misc_unittest ns_name_unittest \ -+ option_unittest - - alloc_unittest_SOURCES = test_alloc.c $(top_srcdir)/tests/t_api_dhcp.c - alloc_unittest_LDADD = $(ATF_LDFLAGS) -@@ -34,6 +35,14 @@ ns_name_unittest_LDADD += ../libdhcp.a \ - ../../omapip/libomapi.a ../../bind/lib/libirs.a \ - ../../bind/lib/libdns.a ../../bind/lib/libisccfg.a ../../bind/lib/libisc.a - -+option_unittest_SOURCES = option_unittest.c $(top_srcdir)/tests/t_api_dhcp.c -+option_unittest_LDADD = $(ATF_LDFLAGS) -+option_unittest_LDADD += ../libdhcp.@A@ ../../omapip/libomapi.@A@ \ -+ @BINDLIBIRSDIR@/libirs.@A@ \ -+ @BINDLIBDNSDIR@/libdns.@A@ \ -+ @BINDLIBISCCFGDIR@/libisccfg.@A@ \ -+ @BINDLIBISCDIR@/libisc.@A@ -+ - check: $(ATF_TESTS) - sh ${top_srcdir}/tests/unittest.sh - -diff --git a/common/tests/option_unittest.c b/common/tests/option_unittest.c -new file mode 100644 -index 0000000..36236b8 ---- /dev/null -+++ b/common/tests/option_unittest.c -@@ -0,0 +1,79 @@ -+/* -+ * Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC") -+ * -+ * This Source Code Form is subject to the terms of the Mozilla Public -+ * License, v. 2.0. If a copy of the MPL was not distributed with this -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH -+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, -+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -+ * PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+#include -+#include -+#include "dhcpd.h" -+ -+ATF_TC(option_refcnt); -+ -+ATF_TC_HEAD(option_refcnt, tc) -+{ -+ atf_tc_set_md_var(tc, "descr", -+ "Verify option reference count does not overflow."); -+} -+ -+/* This test does a simple check to see if option reference count is -+ * decremented even an error path exiting parse_option_buffer() -+ */ -+ATF_TC_BODY(option_refcnt, tc) -+{ -+ struct option_state *options; -+ struct option *option; -+ unsigned code; -+ int refcnt; -+ unsigned char buffer[3] = { 15, 255, 0 }; -+ -+ initialize_common_option_spaces(); -+ -+ options = NULL; -+ if (!option_state_allocate(&options, MDL)) { -+ atf_tc_fail("can't allocate option state"); -+ } -+ -+ option = NULL; -+ code = 15; /* domain-name */ -+ if (!option_code_hash_lookup(&option, dhcp_universe.code_hash, -+ &code, 0, MDL)) { -+ atf_tc_fail("can't find option 15"); -+ } -+ if (option == NULL) { -+ atf_tc_fail("option is NULL"); -+ } -+ refcnt = option->refcnt; -+ -+ buffer[0] = 15; -+ buffer[1] = 255; /* invalid */ -+ buffer[2] = 0; -+ -+ if (parse_option_buffer(options, buffer, 3, &dhcp_universe)) { -+ atf_tc_fail("parse_option_buffer is expected to fail"); -+ } -+ -+ if (refcnt != option->refcnt) { -+ atf_tc_fail("refcnt changed from %d to %d", refcnt, option->refcnt); -+ } -+} -+ -+/* This macro defines main() method that will call specified -+ test cases. tp and simple_test_case names can be whatever you want -+ as long as it is a valid variable identifier. */ -+ATF_TP_ADD_TCS(tp) -+{ -+ ATF_TP_ADD_TC(tp, option_refcnt); -+ -+ return (atf_no_error()); -+} - diff --git a/src/isc-dhcp/patch/0007-CVE-2018-5732.patch b/src/isc-dhcp/patch/0007-CVE-2018-5732.patch deleted file mode 100644 index d6c10e2e6532..000000000000 --- a/src/isc-dhcp/patch/0007-CVE-2018-5732.patch +++ /dev/null @@ -1,144 +0,0 @@ -From: Thomas Markwalder -Date: Sat, 10 Feb 2018 12:15:27 -0500 -Subject: [master] Correct buffer overrun in pretty_print_option -Origin: https://source.isc.org/cgi-bin/gitweb.cgi?p=dhcp.git;a=commit;h=c5931725b48b121d232df4ba9e45bc41e0ba114d -Bug: https://bugs.isc.org/Public/Bug/Display.html?id=47139 -Bug-Debian: https://bugs.debian.org/891786 -Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2018-5732 - - Merges in rt47139. ---- - -diff --git a/common/options.c b/common/options.c -index 6f23bc15..fc0e0889 100644 ---- a/common/options.c -+++ b/common/options.c -@@ -1776,7 +1776,8 @@ format_min_length(format, oc) - - - /* Format the specified option so that a human can easily read it. */ -- -+/* Maximum pretty printed size */ -+#define MAX_OUTPUT_SIZE 32*1024 - const char *pretty_print_option (option, data, len, emit_commas, emit_quotes) - struct option *option; - const unsigned char *data; -@@ -1784,8 +1785,9 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes) - int emit_commas; - int emit_quotes; - { -- static char optbuf [32768]; /* XXX */ -- static char *endbuf = &optbuf[sizeof(optbuf)]; -+ /* We add 128 byte pad so we don't have to add checks everywhere. */ -+ static char optbuf [MAX_OUTPUT_SIZE + 128]; /* XXX */ -+ static char *endbuf = optbuf + MAX_OUTPUT_SIZE; - int hunksize = 0; - int opthunk = 0; - int hunkinc = 0; -@@ -2211,7 +2213,14 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes) - log_error ("Unexpected format code %c", - fmtbuf [j]); - } -+ - op += strlen (op); -+ if (op >= endbuf) { -+ log_error ("Option data exceeds" -+ " maximum size %d", MAX_OUTPUT_SIZE); -+ return (""); -+ } -+ - if (dp == data + len) - break; - if (j + 1 < numelem && comma != ':') -diff --git a/common/tests/option_unittest.c b/common/tests/option_unittest.c -index 36236b84..cd52cfb4 100644 ---- a/common/tests/option_unittest.c -+++ b/common/tests/option_unittest.c -@@ -43,7 +43,7 @@ ATF_TC_BODY(option_refcnt, tc) - if (!option_state_allocate(&options, MDL)) { - atf_tc_fail("can't allocate option state"); - } -- -+ - option = NULL; - code = 15; /* domain-name */ - if (!option_code_hash_lookup(&option, dhcp_universe.code_hash, -@@ -68,12 +68,75 @@ ATF_TC_BODY(option_refcnt, tc) - } - } - -+ATF_TC(pretty_print_option); -+ -+ATF_TC_HEAD(pretty_print_option, tc) -+{ -+ atf_tc_set_md_var(tc, "descr", -+ "Verify pretty_print_option does not overrun its buffer."); -+} -+ -+ -+/* -+ * This test verifies that pretty_print_option() will not overrun its -+ * internal, static buffer when given large 'x/X' format options. -+ * -+ */ -+ATF_TC_BODY(pretty_print_option, tc) -+{ -+ struct option *option; -+ unsigned code; -+ unsigned char bad_data[32*1024]; -+ unsigned char good_data[] = { 1,2,3,4,5,6 }; -+ int emit_commas = 1; -+ int emit_quotes = 1; -+ const char *output_buf; -+ -+ /* Initialize whole thing to non-printable chars */ -+ memset(bad_data, 0x1f, sizeof(bad_data)); -+ -+ initialize_common_option_spaces(); -+ -+ /* We'll use dhcp_client_identitifer because it happens to be format X */ -+ code = 61; -+ option = NULL; -+ if (!option_code_hash_lookup(&option, dhcp_universe.code_hash, -+ &code, 0, MDL)) { -+ atf_tc_fail("can't find option %d", code); -+ } -+ -+ if (option == NULL) { -+ atf_tc_fail("option is NULL"); -+ } -+ -+ /* First we will try a good value we know should fit. */ -+ output_buf = pretty_print_option (option, good_data, sizeof(good_data), -+ emit_commas, emit_quotes); -+ -+ /* Make sure we get what we expect */ -+ if (!output_buf || strcmp(output_buf, "1:2:3:4:5:6")) { -+ atf_tc_fail("pretty_print_option did not return \"\""); -+ } -+ -+ -+ /* Now we'll try a data value that's too large */ -+ output_buf = pretty_print_option (option, bad_data, sizeof(bad_data), -+ emit_commas, emit_quotes); -+ -+ /* Make sure we safely get an error */ -+ if (!output_buf || strcmp(output_buf, "")) { -+ atf_tc_fail("pretty_print_option did not return \"\""); -+ } -+} -+ -+ - /* This macro defines main() method that will call specified - test cases. tp and simple_test_case names can be whatever you want - as long as it is a valid variable identifier. */ - ATF_TP_ADD_TCS(tp) - { - ATF_TP_ADD_TC(tp, option_refcnt); -+ ATF_TP_ADD_TC(tp, pretty_print_option); - - return (atf_no_error()); - } --- -2.16.2 - diff --git a/src/isc-dhcp/patch/series b/src/isc-dhcp/patch/series index 3e1c15338687..9f7164f5c4a9 100644 --- a/src/isc-dhcp/patch/series +++ b/src/isc-dhcp/patch/series @@ -1,9 +1,6 @@ -# This series applies on GIT commit ee3dffdda38a8cfc6ad2005d8d64a165d2a709ba -0001-Customizable-Option-82-circuit-ID-and-remote-ID-fiel.patch -0002-Support-for-obtaining-name-of-physical-interface-tha.patch -0003-Support-for-loading-port-alias-map-file-to-replace-p.patch -0004-Bugfix-Don-t-print-log-messages-to-stderr-in-release.patch -0005-CVE-2017-3144.patch -0006-CVE-2018-5733.patch -0007-CVE-2018-5732.patch +# This series applies on GIT commit d613b77d0473054fb0071b00d01eaa1623e50a07 +0001-Bugfix-Don-t-print-log-messages-to-stderr-in-release.patch +0002-Customizable-Option-82-circuit-ID-and-remote-ID-fiel.patch +0003-Support-for-obtaining-name-of-physical-interface-tha.patch +0004-Support-for-loading-port-alias-map-file-to-replace-p.patch