Add --dhcp-split-relay option.

This makes a DHCPv4 relay which is functional when
client and server networks aren't mutually route-able.
This commit is contained in:
Simon Kelley
2025-07-25 18:47:33 +01:00
parent ea5b0e64e2
commit fc9f6985ab
8 changed files with 247 additions and 127 deletions

View File

@@ -196,6 +196,7 @@ struct myoption {
#define LOPT_NO_ENCODE 387
#define LOPT_DO_ENCODE 388
#define LOPT_LEASEQUERY 389
#define LOPT_SPLIT_RELAY 390
#ifdef HAVE_GETOPT_LONG
static const struct option opts[] =
@@ -374,6 +375,7 @@ static const struct myoption opts[] =
{ "dnssec-timestamp", 1, 0, LOPT_DNSSEC_STAMP },
{ "dnssec-limits", 1, 0, LOPT_DNSSEC_LIMITS },
{ "dhcp-relay", 1, 0, LOPT_RELAY },
{ "dhcp-split-relay", 1, 0, LOPT_SPLIT_RELAY },
{ "ra-param", 1, 0, LOPT_RA_PARAM },
{ "quiet-dhcp", 0, 0, LOPT_QUIET_DHCP },
{ "quiet-dhcp6", 0, 0, LOPT_QUIET_DHCP6 },
@@ -542,6 +544,7 @@ static struct {
{ LOPT_GEN_NAMES, ARG_DUP, "[=tag:<tag>]", gettext_noop("Generate hostnames based on MAC address for nameless clients."), NULL},
{ LOPT_PROXY, ARG_DUP, "[=<ipaddr>]...", gettext_noop("Use these DHCP relays as full proxies."), NULL },
{ LOPT_RELAY, ARG_DUP, "<local-addr>,<server>[,<iface>]", gettext_noop("Relay DHCP requests to a remote server"), NULL},
{ LOPT_SPLIT_RELAY, ARG_DUP, "<local-addr>,<server>,<iface>", gettext_noop("Relay DHCP requests to a remote server"), NULL},
{ LOPT_CNAME, ARG_DUP, "<alias>,<target>[,<ttl>]", gettext_noop("Specify alias name for LOCAL DNS name."), NULL },
{ LOPT_PXE_PROMT, ARG_DUP, "<prompt>,[<timeout>]", gettext_noop("Prompt to send to PXE clients."), NULL },
{ LOPT_PXE_SERV, ARG_DUP, "<service>", gettext_noop("Boot service for PXE menu."), NULL },
@@ -4716,11 +4719,21 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
break;
case LOPT_RELAY: /* --dhcp-relay */
case LOPT_SPLIT_RELAY: /* --dhcp-splt-relay */
{
struct dhcp_relay *new = opt_malloc(sizeof(struct dhcp_relay));
char *two = split(arg);
char *three = split(two);
if (option == LOPT_SPLIT_RELAY)
{
new->split_mode = 1;
/* split mode must have two addresses and a non-wildcard interface name. */
if (!three || strchr(three, '*'))
two = NULL;
}
new->iface_index = 0;
if (two)
@@ -4748,7 +4761,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
daemon->relay4 = new;
}
#ifdef HAVE_DHCP6
else if (inet_pton(AF_INET6, arg, &new->local))
else if (inet_pton(AF_INET6, arg, &new->local) && !new->split_mode)
{
char *hash = split_chr(two, '#');
@@ -4769,7 +4782,9 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
daemon->relay6 = new;
}
#endif
else
two = NULL;
new->interface = opt_string_alloc(three);
}