forked from sonic-net/sonic-buildimage
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
DHCP relay: support for dual ToR (sonic-net#6066)
* DHCP relay: support for dual ToR * update to use -U option * update * update
- Loading branch information
trzhang-msft
authored
Dec 2, 2020
1 parent
2610ad8
commit c59975c
Showing
3 changed files
with
296 additions
and
1 deletion.
There are no files selected for viewing
269 changes: 269 additions & 0 deletions
269
src/isc-dhcp/patch/0009-Support-for-dual-tor-scenario.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,269 @@ | ||
From 768df61b57a0a7bda23aa8bc7e08c5b2a96a8087 Mon Sep 17 00:00:00 2001 | ||
From: Tianrong Zhang <[email protected]> | ||
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 | ||
|
24 changes: 24 additions & 0 deletions
24
src/isc-dhcp/patch/0010-Bugfix-correctly-set-interface-netmask.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
From b19547b0574132e4b2efbda012f3169e4db7923c Mon Sep 17 00:00:00 2001 | ||
From: Tianrong Zhang <[email protected]> | ||
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 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters