[RFC PATCH v3] Add option to omit link configuration for IPv4
Philipp Gesang
Mon Jan 30 08:46:37 2017
Adds a command line option --noconfigure and checks at relevant
locations immediately before calling out into platform specific
code to configure a link.
This patch is incomplete in that it only covers the bits dealing
with IPv4.
Signed-off-by: Philipp Gesang <philipp.gesang@xxxxxxxxxxxxx>
---
dhcp.c | 2 +-
dhcpcd.8.in | 16 ++++++++++++++++
dhcpcd.conf.5.in | 20 +++++++++++++++-----
if-linux.c | 6 ++++++
if-options.c | 10 +++++++++-
if-options.h | 1 +
ipv4.c | 29 ++++++++++++++++++++---------
route.c | 4 ++++
8 files changed, 72 insertions(+), 16 deletions(-)
diff --git a/dhcp.c b/dhcp.c
index f2ee5044..37c98863 100644
--- a/dhcp.c
+++ b/dhcp.c
@@ -760,7 +760,7 @@ make_message(struct bootp **bootpm, const struct interface *ifp, uint8_t type)
if ((mtu = if_getmtu(ifp)) == -1)
logger(ifp->ctx, LOG_ERR,
"%s: if_getmtu: %m", ifp->name);
- else if (mtu < MTU_MIN) {
+ else if (mtu < MTU_MIN && ifo->options & DHCPCD_CONFIGURE_LINK) {
if (if_setmtu(ifp, MTU_MIN) == -1)
logger(ifp->ctx, LOG_ERR,
"%s: if_setmtu: %m", ifp->name);
diff --git a/dhcpcd.8.in b/dhcpcd.8.in
index 6fccbdca..222f515b 100644
--- a/dhcpcd.8.in
+++ b/dhcpcd.8.in
@@ -60,6 +60,7 @@
.Op Fl Z , Fl Fl denyinterfaces Ar pattern
.Op Fl z , Fl Fl allowinterfaces Ar pattern
.Op Fl Fl inactive
+.Op Fl Fl noconfigure
.Op interface
.Op ...
.Nm
@@ -193,6 +194,11 @@ To force starting in Master mode with only one interface, the
.Fl M , Fl Fl master
option can be used.
.Pp
+Note that when active on a single interface or a list of interfaces,
+.Nm
+will still affect interfaces not specified to prevent conflicts of a lease
+with their configuration.
+.Pp
Interfaces are preferred by carrier, DHCP lease/IPv4LL and then lowest metric.
For systems that support route metrics, each route will be tagged with the
metric, otherwise
@@ -715,6 +721,16 @@ commands to start each interface as required.
Don't load any
.Pa /dev
management modules.
+.It Fl Fl noconfigure
+Don't change the configuration of any interfaces and routes. Normally,
+.Nm
+will apply a lease it receives to the respective interface and resolve
+potential conflicts by removing addresses from other interfaces. Use
+.Fl Fl noconfigure
+if the link configuration is handled elsewhere, for example by another process
+that receives the lease data from the script.
+.Pp
+Currently affects only DHCPv4.
.El
.Sh 3RDPARTY LINK MANAGEMENT
Some interfaces require configuration by 3rd parties, such as PPP or VPN.
diff --git a/dhcpcd.conf.5.in b/dhcpcd.conf.5.in
index d8176c0e..5e378d21 100644
--- a/dhcpcd.conf.5.in
+++ b/dhcpcd.conf.5.in
@@ -453,6 +453,16 @@ This also disables IPv4LL.
.It Ic noauthrequired
Don't require authentication even though we requested it.
Also allows FORCERENEW and RECONFIGURE messages without authentication.
+.It Ic noconfigure
+Don't change the configuration of any interfaces and routes. Normally,
+.Nm dhcpcd
+will apply a lease it receives to the respective interface and resolve
+potential conflicts by removing addresses from other interfaces. Use
+.Fl Fl noconfigure
+if the link configuration is handled elsewhere, for example by another process
+that receives the lease data from the script.
+.Pp
+Currently affects only DHCPv4.
.It Ic nodelay
Don't delay for an initial randomised time when starting protocols.
.It Ic nodev
@@ -496,9 +506,9 @@ You should only set this for buggy interface drivers.
.It Ic noup
Don't bring the interface up when in master mode.
If
-.Nm
+.Nm dhcpcd
cannot determine the carrier state,
-.Nm
+.Nm dhcpcd
will enter a tight polling loop until the interface is marked up and running
or a valid carrier state is reported.
.It Ic option Ar option
@@ -555,7 +565,7 @@ This is useful when you cannot use
to select / de-select BOOTP messages.
.It Ic destination Ar option
If
-.Nm
+.Nm dhcpcd
detects an address added to a point to point interface (PPP, TUN, etc) then
it will set the listed DHCP options to the destination address of the
interface.
@@ -695,10 +705,10 @@ Wait for an address to be assigned before forking to the background.
4 means wait for an IPv4 address to be assigned.
6 means wait for an IPv6 address to be assigned.
If no argument is given,
-.Nm
+.Nm dhcpcd
will wait for any address protocol to be assigned.
It is possible to wait for more than one address protocol and
-.Nm
+.Nm dhcpcd
will only fork to the background when all waiting conditions are satisfied.
.It Ic xidhwaddr
Use the last four bytes of the hardware address as the DHCP xid instead
diff --git a/if-linux.c b/if-linux.c
index 26f4d3ca..1957c6a8 100644
--- a/if-linux.c
+++ b/if-linux.c
@@ -226,6 +226,12 @@ if_init(struct interface *ifp)
return errno == ENOENT ? 0 : -1;
if (n == 1)
return 0;
+ if (!(ifp->ctx->options & DHCPCD_CONFIGURE_LINK)) {
+ logger(ifp->ctx, LOG_DEBUG,
+ "%s: leaving IPv4 sysctl promote_secondaries unset",
+ ifp->name);
+ return 0;
+ }
return write_path(path, "1") == -1 ? -1 : 0;
}
diff --git a/if-options.c b/if-options.c
index 7dd6a439..44340a93 100644
--- a/if-options.c
+++ b/if-options.c
@@ -104,6 +104,7 @@
#define O_LASTLEASE_EXTEND O_BASE + 46
#define O_INACTIVE O_BASE + 47
#define O_MUDURL O_BASE + 48
+#define O_NOCONFIGURE O_BASE + 49
const struct option cf_options[] = {
{"background", no_argument, NULL, 'b'},
@@ -205,6 +206,7 @@ const struct option cf_options[] = {
{"lastleaseextend", no_argument, NULL, O_LASTLEASE_EXTEND},
{"inactive", no_argument, NULL, O_INACTIVE},
{"mudurl", required_argument, NULL, O_MUDURL},
+ {"noconfigure", no_argument, NULL, O_NOCONFIGURE},
{NULL, 0, NULL, '\0'}
};
@@ -2146,6 +2148,11 @@ err_sla:
}
*ifo->mudurl = (uint8_t)s;
break;
+ case O_NOCONFIGURE:
+ logger(ctx, LOG_DEBUG,
+ "noconfigure: suppressing link configuration");
+ ifo->options &= ~DHCPCD_CONFIGURE_LINK;
+ break;
default:
return 0;
}
@@ -2251,7 +2258,8 @@ default_config(struct dhcpcd_ctx *ctx)
logger(ctx, LOG_ERR, "%s: %m", __func__);
return NULL;
}
- ifo->options |= DHCPCD_IF_UP | DHCPCD_LINK | DHCPCD_INITIAL_DELAY;
+ ifo->options |= DHCPCD_IF_UP | DHCPCD_LINK | DHCPCD_INITIAL_DELAY
+ | DHCPCD_CONFIGURE_LINK;
ifo->timeout = DEFAULT_TIMEOUT;
ifo->reboot = DEFAULT_REBOOT;
ifo->metric = -1;
diff --git a/if-options.h b/if-options.h
index 3f2eb04d..93216f66 100644
--- a/if-options.h
+++ b/if-options.h
@@ -118,6 +118,7 @@
#define DHCPCD_PRINT_PIDFILE (1ULL << 59)
#define DHCPCD_ONESHOT (1ULL << 60)
#define DHCPCD_INACTIVE (1ULL << 61)
+#define DHCPCD_CONFIGURE_LINK (1ULL << 62)
#define DHCPCD_NODROP (DHCPCD_EXITING | DHCPCD_PERSISTENT)
diff --git a/ipv4.c b/ipv4.c
index 57a19dfe..bdddcbc2 100644
--- a/ipv4.c
+++ b/ipv4.c
@@ -465,6 +465,12 @@ ipv4_deladdr(struct ipv4_addr *addr, int keeparp)
UNUSED(keeparp);
#endif
+ if (!(addr->iface->ctx->options & DHCPCD_CONFIGURE_LINK)) {
+ logger(addr->iface->ctx, LOG_DEBUG,
+ "%s: noconfigure: not deleting IP address %s",
+ addr->iface->name, addr->saddr);
+ return 0;
+ }
logger(addr->iface->ctx, LOG_DEBUG,
"%s: deleting IP address %s", addr->iface->name, addr->saddr);
@@ -638,15 +644,20 @@ ipv4_addaddr(struct interface *ifp, const struct in_addr *addr,
ia->alias, ia->saddr);
#endif
- logger(ifp->ctx, LOG_DEBUG, "%s: adding IP address %s broadcast %s",
- ifp->name, ia->saddr, inet_ntoa(*bcast));
- if (if_address(RTM_NEWADDR, ia) == -1) {
- if (errno != EEXIST)
- logger(ifp->ctx, LOG_ERR, "%s: if_addaddress: %m",
- __func__);
- free(ia);
- return NULL;
- }
+ if (ifp->options->options & DHCPCD_CONFIGURE_LINK) {
+ logger(ifp->ctx, LOG_DEBUG, "%s: adding IP address %s broadcast %s",
+ ifp->name, ia->saddr, inet_ntoa(*bcast));
+ if (if_address(RTM_NEWADDR, ia) == -1) {
+ if (errno != EEXIST)
+ logger(ifp->ctx, LOG_ERR, "%s: if_addaddress: %m",
+ __func__);
+ free(ia);
+ return NULL;
+ }
+ } else
+ logger(ifp->ctx, LOG_DEBUG,
+ "%s: noconfigure: skipping IP address %s broadcast %s",
+ ifp->name, ia->saddr, inet_ntoa(*bcast));
#ifdef ALIAS_ADDR
if (replaced) {
diff --git a/route.c b/route.c
index 1e6bd84e..3da6cde9 100644
--- a/route.c
+++ b/route.c
@@ -290,6 +290,8 @@ rt_add(struct rt *nrt, struct rt *ort)
sa_is_unspecified(&nrt->rt_dest) &&
sa_is_unspecified(&nrt->rt_netmask))
return false;
+ if (!(options & DHCPCD_CONFIGURE_LINK))
+ return false;
rt_desc(ort == NULL ? "adding" : "changing", nrt);
@@ -394,6 +396,8 @@ rt_delete(struct rt *rt)
{
int retval;
+ if (!(rt->rt_ifp->options->options & DHCPCD_CONFIGURE_LINK))
+ return false;
rt_desc("deleting", rt);
retval = if_route(RTM_DELETE, rt) == -1 ? false : true;
if (!retval && errno != ENOENT && errno != ESRCH)
--
2.11.0
Archive administrator: postmaster@marples.name