DHCP relay: support for dual ToR (#6066)
* DHCP relay: support for dual ToR * update to use -U option * update * update
This commit is contained in:
parent
2610ad8453
commit
c59975c7da
269
src/isc-dhcp/patch/0009-Support-for-dual-tor-scenario.patch
Normal file
269
src/isc-dhcp/patch/0009-Support-for-dual-tor-scenario.patch
Normal file
@ -0,0 +1,269 @@
|
||||
From 768df61b57a0a7bda23aa8bc7e08c5b2a96a8087 Mon Sep 17 00:00:00 2001
|
||||
From: Tianrong Zhang <trzhang@microsoft.com>
|
||||
Date: Tue, 1 Dec 2020 16:33:34 -0800
|
||||
Subject: [PATCH] support for dual tor scenario
|
||||
|
||||
---
|
||||
relay/dhcrelay.c | 117 +++++++++++++++++++++++++++++++++++++++--------
|
||||
1 file changed, 98 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c
|
||||
index e158efe..055d97f 100644
|
||||
--- a/relay/dhcrelay.c
|
||||
+++ b/relay/dhcrelay.c
|
||||
@@ -56,6 +56,8 @@ int bogus_agent_drops = 0; /* Packets dropped because agent option
|
||||
specified. */
|
||||
int bogus_giaddr_drops = 0; /* Packets sent to us to relay back to a
|
||||
client, but with a bogus giaddr. */
|
||||
+int bogus_yiaddr_drops = 0; /* Packets sent to us to relay back to a
|
||||
+ client, but with a bogus yiaddr. */
|
||||
int client_packets_relayed = 0; /* Packets relayed from client to server. */
|
||||
int server_packet_errors = 0; /* Errors sending packets to servers. */
|
||||
int server_packets_relayed = 0; /* Packets relayed from server to client. */
|
||||
@@ -83,6 +85,13 @@ int max_hop_count = 10; /* Maximum hop count */
|
||||
int no_daemon = 0;
|
||||
int dfd[2] = { -1, -1 };
|
||||
|
||||
+int enable_support_for_dual_tor = 0;
|
||||
+
|
||||
+struct downstream_intf_list {
|
||||
+ struct downstream_intf_list *next;
|
||||
+ struct interface_info *interface;
|
||||
+} *downstream_intfs = NULL;
|
||||
+
|
||||
#ifdef DHCPv6
|
||||
/* Force use of DHCPv6 interface-id option. */
|
||||
isc_boolean_t use_if_id = ISC_FALSE;
|
||||
@@ -156,6 +165,8 @@ 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 void free_downstream_intfs(void);
|
||||
+
|
||||
static const char copyright[] =
|
||||
"Copyright 2004-2018 Internet Systems Consortium.";
|
||||
static const char arr[] = "All rights reserved.";
|
||||
@@ -189,6 +200,7 @@ char *progname;
|
||||
" [-iu interface0 [ ... -iu interfaceN]\n" \
|
||||
" [-id interface0 [ ... -id interfaceN]\n" \
|
||||
" [-U interface]\n" \
|
||||
+" [-dt]\n"\
|
||||
" server0 [ ... serverN]\n\n" \
|
||||
" %s -6 [-d] [-q] [-I] [-c <hops>]\n" \
|
||||
" [-p <port> | -rp <relay-port>]\n" \
|
||||
@@ -210,6 +222,7 @@ char *progname;
|
||||
" [-iu interface0 [ ... -iu interfaceN]\n" \
|
||||
" [-id interface0 [ ... -id interfaceN]\n" \
|
||||
" [-U interface]\n" \
|
||||
+" [-dt]\n"\
|
||||
" server0 [ ... serverN]\n\n" \
|
||||
" %s -6 [-d] [-q] [-I] [-c <hops>] [-p <port>]\n" \
|
||||
" [-pf <pid-file>] [--no-pid]\n" \
|
||||
@@ -231,6 +244,7 @@ char *progname;
|
||||
" [-iu interface0 [ ... -iu interfaceN]\n" \
|
||||
" [-id interface0 [ ... -id interfaceN]\n" \
|
||||
" [-U interface]\n" \
|
||||
+" [-dt]\n"\
|
||||
" server0 [ ... serverN]\n\n" DHCRELAY_OPTION82_USAGE \
|
||||
" %s {--version|--help|-h}"
|
||||
#else
|
||||
@@ -242,6 +256,7 @@ char *progname;
|
||||
" [-iu interface0 [ ... -iu interfaceN]\n" \
|
||||
" [-id interface0 [ ... -id interfaceN]\n" \
|
||||
" [-U interface]\n" \
|
||||
+" [-dt]\n"\
|
||||
" server0 [ ... serverN]\n\n" DHCRELAY_OPTION82_USAGE \
|
||||
" %s {--version|--help|-h}"
|
||||
#endif
|
||||
@@ -639,7 +654,16 @@ main(int argc, char **argv) {
|
||||
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 (argv[i][0] == '-') {
|
||||
+ } else if (!strcmp(argv[i], "-dt")) {
|
||||
+#ifdef DHCPv6
|
||||
+ if (local_family_set && (local_family == AF_INET6)) {
|
||||
+ usage(use_v4command, argv[i]);
|
||||
+ }
|
||||
+ local_family_set = 1;
|
||||
+ local_family = AF_INET;
|
||||
+#endif
|
||||
+ enable_support_for_dual_tor = 1;
|
||||
+ } else if (argv[i][0] == '-') {
|
||||
usage("Unknown command: %s", argv[i]);
|
||||
} else {
|
||||
struct hostent *he;
|
||||
@@ -747,7 +771,6 @@ main(int argc, char **argv) {
|
||||
log_fatal("No servers specified.");
|
||||
}
|
||||
|
||||
-
|
||||
/* Set up the server sockaddrs. */
|
||||
for (sp = servers; sp; sp = sp->next) {
|
||||
sp->to.sin_port = local_port;
|
||||
@@ -862,6 +885,8 @@ main(int argc, char **argv) {
|
||||
|
||||
/* In fact dispatch() never returns. */
|
||||
free_interface_alias_map();
|
||||
+ free_downstream_intfs();
|
||||
+
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -885,25 +910,50 @@ do_relay4(struct interface_info *ip, struct dhcp_packet *packet,
|
||||
return;
|
||||
}
|
||||
|
||||
- /* Find the interface that corresponds to the giaddr
|
||||
- in the packet. */
|
||||
- if (packet->giaddr.s_addr) {
|
||||
- for (out = interfaces; out; out = out->next) {
|
||||
- int i;
|
||||
+ if (enable_support_for_dual_tor) {
|
||||
+ if (packet->yiaddr.s_addr) {
|
||||
+ out = NULL;
|
||||
+
|
||||
+ for (struct downstream_intf_list *cdi = downstream_intfs; cdi; cdi = cdi->next) {
|
||||
+ int i = 0;
|
||||
+ out = cdi->interface;
|
||||
+
|
||||
+ for (i = 0 ; i < out->address_count ; i++ ) {
|
||||
+ if ((out->addresses[i].s_addr & out->netmasks[i].s_addr) == (packet->yiaddr.s_addr & out->netmasks[i].s_addr)) {
|
||||
+ i = -1;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
- for (i = 0 ; i < out->address_count ; i++ ) {
|
||||
- if (out->addresses[i].s_addr ==
|
||||
- packet->giaddr.s_addr) {
|
||||
- i = -1;
|
||||
+ if (i == -1) {
|
||||
break;
|
||||
+ } else {
|
||||
+ out = NULL;
|
||||
}
|
||||
}
|
||||
-
|
||||
- if (i == -1)
|
||||
- break;
|
||||
+ } else {
|
||||
+ out = NULL;
|
||||
}
|
||||
} else {
|
||||
- out = NULL;
|
||||
+ /* Find the interface that corresponds to the giaddr in the packet. */
|
||||
+ if (packet->giaddr.s_addr) {
|
||||
+ for (out = interfaces; out; out = out->next) {
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0 ; i < out->address_count ; i++ ) {
|
||||
+ if (out->addresses[i].s_addr ==
|
||||
+ packet->giaddr.s_addr) {
|
||||
+ i = -1;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (i == -1)
|
||||
+ break;
|
||||
+ }
|
||||
+ } else {
|
||||
+ out = NULL;
|
||||
+ }
|
||||
}
|
||||
|
||||
/* If it's a bootreply, forward it to the client. */
|
||||
@@ -913,6 +963,10 @@ do_relay4(struct interface_info *ip, struct dhcp_packet *packet,
|
||||
return;
|
||||
}
|
||||
|
||||
+ /* This bootreply does not belong to the current vlan. */
|
||||
+ if (enable_support_for_dual_tor && !out)
|
||||
+ return;
|
||||
+
|
||||
if (!(packet->flags & htons(BOOTP_BROADCAST)) &&
|
||||
can_unicast_without_arp(out)) {
|
||||
to.sin_addr = packet->yiaddr;
|
||||
@@ -945,9 +999,13 @@ do_relay4(struct interface_info *ip, struct dhcp_packet *packet,
|
||||
return;
|
||||
|
||||
if (!out) {
|
||||
- log_error("Packet to bogus giaddr %s.\n",
|
||||
- inet_ntoa(packet->giaddr));
|
||||
- ++bogus_giaddr_drops;
|
||||
+ if (!enable_support_for_dual_tor) {
|
||||
+ log_error("Packet to bogus giaddr %s.\n", inet_ntoa(packet->giaddr));
|
||||
+ ++bogus_giaddr_drops;
|
||||
+ } else {
|
||||
+ log_error("Packet to bogus yiaddr %s.\n", inet_ntoa(packet->yiaddr));
|
||||
+ ++bogus_yiaddr_drops;
|
||||
+ }
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -989,6 +1047,7 @@ do_relay4(struct interface_info *ip, struct dhcp_packet *packet,
|
||||
that set giaddr, so we won't see it. */
|
||||
if (!packet->giaddr.s_addr)
|
||||
packet->giaddr = ip->addresses[0];
|
||||
+
|
||||
if (packet->hops < max_hop_count)
|
||||
packet->hops = packet->hops + 1;
|
||||
else
|
||||
@@ -1264,7 +1323,6 @@ find_interface_by_agent_option(struct dhcp_packet *packet,
|
||||
|
||||
/* Scan the interface list looking for an interface whose
|
||||
name matches the one specified in circuit_id. */
|
||||
-
|
||||
for (ip = interfaces; ip; ip = ip->next) {
|
||||
if (ip->circuit_id &&
|
||||
ip->circuit_id_len == circuit_id_len &&
|
||||
@@ -1668,6 +1726,7 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet,
|
||||
*sp++ = 4u;
|
||||
memcpy(sp, &giaddr.s_addr, 4);
|
||||
sp += 4;
|
||||
+
|
||||
packet->giaddr = uplink->addresses[0];
|
||||
log_debug ("Adding link selection suboption"
|
||||
" with addr: %s", inet_ntoa(giaddr));
|
||||
@@ -2398,6 +2457,7 @@ void request_v4_interface(const char* name, int flags) {
|
||||
struct interface_info *tmp = NULL;
|
||||
int len = strlen(name);
|
||||
isc_result_t status;
|
||||
+ struct downstream_intf_list *ci = NULL;
|
||||
|
||||
if (len >= sizeof(tmp->name)) {
|
||||
log_fatal("%s: interface name too long (is %d)", name, len);
|
||||
@@ -2413,6 +2473,15 @@ void request_v4_interface(const char* name, int flags) {
|
||||
(flags & INTERFACE_UPSTREAM ? 'Y' : 'N'),
|
||||
(flags & INTERFACE_DOWNSTREAM ? 'Y' : 'N'));
|
||||
|
||||
+ if (flags & INTERFACE_DOWNSTREAM) {
|
||||
+ ci = ((struct downstream_intf_list *)dmalloc(sizeof *ci, MDL));
|
||||
+ if (!ci)
|
||||
+ log_fatal("no memory for downstream interface pointer.\n");
|
||||
+ ci->next = downstream_intfs;
|
||||
+ downstream_intfs = ci;
|
||||
+ ci->interface = tmp;
|
||||
+ }
|
||||
+
|
||||
strncpy(tmp->name, name, len);
|
||||
interface_snorf(tmp, (INTERFACE_REQUESTED | flags));
|
||||
interface_dereference(&tmp, MDL);
|
||||
@@ -2487,3 +2556,13 @@ free_interface_alias_map(void) {
|
||||
free(g_interface_name_alias_map);
|
||||
g_interface_name_alias_map_size = 0;
|
||||
}
|
||||
+
|
||||
+static void
|
||||
+free_downstream_intfs(void) {
|
||||
+ struct downstream_intf_list *cdi;
|
||||
+ while (downstream_intfs) {
|
||||
+ cdi = downstream_intfs;
|
||||
+ downstream_intfs = downstream_intfs->next;
|
||||
+ free(cdi);
|
||||
+ }
|
||||
+}
|
||||
--
|
||||
2.17.1
|
||||
|
@ -0,0 +1,24 @@
|
||||
From b19547b0574132e4b2efbda012f3169e4db7923c Mon Sep 17 00:00:00 2001
|
||||
From: Tianrong Zhang <trzhang@microsoft.com>
|
||||
Date: Mon, 30 Nov 2020 18:42:09 -0800
|
||||
Subject: [PATCH] Bugfix: correctly set interface netmask
|
||||
|
||||
---
|
||||
common/discover.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/common/discover.c b/common/discover.c
|
||||
index c6b2431..06e0b12 100644
|
||||
--- a/common/discover.c
|
||||
+++ b/common/discover.c
|
||||
@@ -479,6 +479,7 @@ next_iface(struct iface_info *info, int *err, struct iface_conf_list *ifaces) {
|
||||
sa_len = ifaces->next->ifa_addr->sa_len;
|
||||
#endif
|
||||
memcpy(&info->addr, ifaces->next->ifa_addr, sa_len);
|
||||
+ memcpy(&info->netmask, ifaces->next->ifa_netmask, sa_len);
|
||||
}
|
||||
info->flags = ifaces->next->ifa_flags;
|
||||
ifaces->next = ifaces->next->ifa_next;
|
||||
--
|
||||
2.17.1
|
||||
|
@ -1,4 +1,4 @@
|
||||
# This series applies on GIT commit d613b77d0473054fb0071b00d01eaa1623e50a07
|
||||
# This series applies on GIT commit d0d58776805d720029619ea06df5c57706eecd5a
|
||||
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
|
||||
@ -7,3 +7,5 @@
|
||||
0006-Bugfix-Ensure-HAVE_SO_BINDTODEVICE-has-a-chance-to-b.patch
|
||||
0007-If-destination-of-BOOTREQUEST-is-directed-broadcast-.patch
|
||||
0008-Don-t-skip-down-interfaces-when-discovering-interfac.patch
|
||||
0009-Support-for-dual-tor-scenario.patch
|
||||
0010-Bugfix-correctly-set-interface-netmask.patch
|
||||
|
Loading…
Reference in New Issue
Block a user