| From ada9b203f9bab97a4176446a3c6084ad7d0909cd Mon Sep 17 00:00:00 2001 |
| From: Peter Qiu <zqiu@chromium.org> |
| Date: Wed, 27 May 2015 15:16:29 -0700 |
| Subject: [PATCH] Add RPC support for DHCPv4 client |
| |
| Define a RPC interface for the daemon to interact with other |
| applications (command execution and status update), and integrate |
| it with the DHCPv4 client. Default to stub implementation for now |
| until new RPC mechanism is implemented and enabled. |
| |
| Also add a new compiler flag "PASSIVE_MODE" which will be enabled |
| when a RPC mechanism is enabled (e.g. DBus). This compiler flag |
| will prevent the daemon from modifying system configurations |
| (e.g. routing table, interface address). The idea is that when |
| RPC is enabled, the daemon will provide configurations through |
| RPC, and the remote application will be the one responsible for |
| modifying system configurations. |
| |
| Integration with DHCPv6 client will be added in the future. |
| |
| Author: Paul Stewart <pstew@chromium.org> |
| Reviewed-on: https://chromium-review.googlesource.com/208835 |
| Review URL: http://codereview.chromium.org/3061018 |
| --- |
| Makefile | 2 +- |
| dhcp.c | 16 ++++++++++++- |
| dhcpcd.c | 7 ++++++ |
| ipv4.c | 17 +++++++++++++- |
| rpc-interface.h | 51 ++++++++++++++++++++++++++++++++++++++++++ |
| rpc-stub.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| 6 files changed, 159 insertions(+), 3 deletions(-) |
| create mode 100644 rpc-interface.h |
| create mode 100644 rpc-stub.c |
| |
| diff --git a/Makefile b/Makefile |
| index 36ff297..f277750 100644 |
| --- a/Makefile |
| +++ b/Makefile |
| @@ -2,7 +2,7 @@ |
| |
| PROG= dhcpcd |
| SRCS= common.c control.c dhcpcd.c duid.c eloop.c |
| -SRCS+= if.c if-options.c script.c |
| +SRCS+= if.c if-options.c script.c rpc-stub.c |
| SRCS+= dhcp-common.c |
| |
| CFLAGS?= -O2 |
| diff --git a/dhcp.c b/dhcp.c |
| index 9a2bea1..d3d0d05 100644 |
| --- a/dhcp.c |
| +++ b/dhcp.c |
| @@ -61,6 +61,7 @@ |
| #include "if.h" |
| #include "ipv4.h" |
| #include "ipv4ll.h" |
| +#include "rpc-interface.h" |
| #include "script.h" |
| |
| #define DAD "Duplicate address detected" |
| @@ -1820,6 +1821,7 @@ dhcp_discover(void *arg) |
| struct dhcp_state *state = D_STATE(ifp); |
| struct if_options *ifo = ifp->options; |
| |
| + rpc_signal_status("Discover"); |
| state->state = DHS_DISCOVER; |
| state->xid = dhcp_xid(ifp); |
| state->nak_receive_count = 0; |
| @@ -1849,6 +1851,7 @@ dhcp_request(void *arg) |
| struct interface *ifp = arg; |
| struct dhcp_state *state = D_STATE(ifp); |
| |
| + rpc_signal_status("Request"); |
| state->state = DHS_REQUEST; |
| state->nak_receive_count = 0; |
| send_request(ifp); |
| @@ -1882,6 +1885,7 @@ dhcp_renew(void *arg) |
| struct dhcp_state *state = D_STATE(ifp); |
| struct dhcp_lease *lease = &state->lease; |
| |
| + rpc_signal_status("Renew"); |
| logger(ifp->ctx, LOG_DEBUG, "%s: renewing lease of %s", |
| ifp->name, inet_ntoa(lease->addr)); |
| logger(ifp->ctx, LOG_DEBUG, "%s: rebind in %"PRIu32" seconds," |
| @@ -1910,6 +1914,7 @@ dhcp_rebind(void *arg) |
| struct dhcp_state *state = D_STATE(ifp); |
| struct dhcp_lease *lease = &state->lease; |
| |
| + rpc_signal_status("Rebind"); |
| logger(ifp->ctx, LOG_WARNING, |
| "%s: failed to renew DHCP, rebinding", ifp->name); |
| logger(ifp->ctx, LOG_DEBUG, "%s: expire in %"PRIu32" seconds", |
| @@ -2308,6 +2313,7 @@ dhcp_inform(struct interface *ifp) |
| } |
| } |
| |
| + rpc_signal_status("Inform"); |
| state->state = DHS_INFORM; |
| state->xid = dhcp_xid(ifp); |
| send_inform(ifp); |
| @@ -2341,6 +2347,7 @@ dhcp_reboot(struct interface *ifp) |
| |
| if (state == NULL) |
| return; |
| + rpc_signal_status("Reboot"); |
| ifo = ifp->options; |
| state->state = DHS_REBOOT; |
| state->interval = 0; |
| @@ -2595,7 +2602,7 @@ dhcp_probe_gw_response(struct arp_state *astate, const struct arp_msg *amsg) |
| amsg->sip.s_addr == astate->addr.s_addr) { |
| if (astate->dest_hwlen) { |
| /* Response to unicast ARP. */ |
| - /* TODO(zqiu): notify listener. */ |
| + rpc_notify_unicast_arp(astate->iface); |
| } else { |
| /* Response to arpgw request. */ |
| save_gateway_addr(astate->iface, amsg->sha); |
| @@ -2933,6 +2940,7 @@ dhcp_handledhcp(struct interface *ifp, struct dhcp_message **dhcpp, |
| return; |
| |
| log_dhcp(LOG_WARNING, "NAK (deferred):", ifp, dhcp, from); |
| + rpc_signal_status("NakDefer"); |
| if (state->nak_receive_count == 0) |
| eloop_timeout_add_sec(ifp->ctx->eloop, |
| DHCP_BASE, handle_nak, ifp); |
| @@ -3008,6 +3016,7 @@ dhcp_handledhcp(struct interface *ifp, struct dhcp_message **dhcpp, |
| (dhcp->ciaddr == INADDR_ANY || dhcp->ciaddr == INADDR_BROADCAST) && |
| (dhcp->yiaddr == INADDR_ANY || dhcp->yiaddr == INADDR_BROADCAST)) |
| { |
| + rpc_signal_status("IgnoreInvalidOffer"); |
| log_dhcp(LOG_WARNING, "reject invalid address", |
| ifp, dhcp, from); |
| return; |
| @@ -3036,6 +3045,7 @@ dhcp_handledhcp(struct interface *ifp, struct dhcp_message **dhcpp, |
| log_dhcp(LOG_WARNING, |
| "reject previously declined address", |
| ifp, dhcp, from); |
| + rpc_signal_status("IgnoreFailedOffer"); |
| state->failed_address_offer_count++; |
| return; |
| } |
| @@ -3079,6 +3089,7 @@ dhcp_handledhcp(struct interface *ifp, struct dhcp_message **dhcpp, |
| if (type == DHCP_OFFER) { |
| log_dhcp(LOG_WARNING, "ignoring offer of", |
| ifp, dhcp, from); |
| + rpc_signal_status("IgnoreAdditionalOffer"); |
| return; |
| } |
| |
| @@ -3086,6 +3097,7 @@ dhcp_handledhcp(struct interface *ifp, struct dhcp_message **dhcpp, |
| if (type != DHCP_ACK) { |
| log_dhcp(LOG_ERR, "not ACK or OFFER", |
| ifp, dhcp, from); |
| + rpc_signal_status("IgnoreNonOffer"); |
| return; |
| } |
| |
| @@ -3133,6 +3145,7 @@ dhcp_handledhcp(struct interface *ifp, struct dhcp_message **dhcpp, |
| #ifndef IN_IFF_TENTATIVE |
| arp_probe(astate); |
| #endif |
| + rpc_signal_status("ArpSelf"); |
| } |
| #ifndef IN_IFF_TENTATIVE |
| return; |
| @@ -3141,6 +3154,7 @@ dhcp_handledhcp(struct interface *ifp, struct dhcp_message **dhcpp, |
| } |
| |
| if ((ifo->options & DHCPCD_ARPGW) && (dhcp_probe_gw(ifp))) { |
| + rpc_signal_status("ArpGateway"); |
| return; |
| } |
| |
| diff --git a/dhcpcd.c b/dhcpcd.c |
| index 763e06f..a486ac2 100644 |
| --- a/dhcpcd.c |
| +++ b/dhcpcd.c |
| @@ -63,6 +63,7 @@ const char dhcpcd_copyright[] = "Copyright (c) 2006-2015 Roy Marples"; |
| #include "ipv4.h" |
| #include "ipv6.h" |
| #include "ipv6nd.h" |
| +#include "rpc-interface.h" |
| #include "script.h" |
| |
| #ifdef USE_SIGNALS |
| @@ -1777,6 +1778,12 @@ main(int argc, char **argv) |
| (DHCPCD_MASTER | DHCPCD_DEV)) |
| dev_start(&ctx); |
| |
| + if (rpc_init(&ctx) == -1) { |
| + /* NB: rpc_init generates a syslog msg */ |
| + goto exit_failure; |
| + } |
| + rpc_signal_status("Init"); |
| + |
| ctx.ifaces = if_discover(&ctx, ctx.ifc, ctx.ifv); |
| if (ctx.ifaces == NULL) { |
| logger(&ctx, LOG_ERR, "if_discover: %m"); |
| diff --git a/ipv4.c b/ipv4.c |
| index d088d80..f7b0d22 100644 |
| --- a/ipv4.c |
| +++ b/ipv4.c |
| @@ -47,6 +47,9 @@ |
| #include "if-options.h" |
| #include "ipv4.h" |
| #include "script.h" |
| +#ifdef PASSIVE_MODE |
| +#include "rpc-interface.h" |
| +#endif |
| |
| #define IPV4_LOOPBACK_ROUTE |
| #if defined(__linux__) || (defined(BSD) && defined(RTF_LOCAL)) |
| @@ -642,6 +645,8 @@ add_router_host_route(struct rt_head *rt, const struct interface *ifp) |
| void |
| ipv4_buildroutes(struct dhcpcd_ctx *ctx) |
| { |
| +/* Do not modify route table when running in passive mode. */ |
| +#ifndef PASSIVE_MODE |
| struct rt_head *nrs, *dnr; |
| struct rt *or, *rt, *rtn; |
| struct interface *ifp; |
| @@ -731,14 +736,16 @@ ipv4_buildroutes(struct dhcpcd_ctx *ctx) |
| } |
| ipv4_freeroutes(ctx->ipv4_routes); |
| ctx->ipv4_routes = nrs; |
| +#endif |
| } |
| |
| int |
| ipv4_deladdr(struct interface *ifp, |
| const struct in_addr *addr, const struct in_addr *net) |
| { |
| + int r = 0; |
| +#ifndef PASSIVE_MODE |
| struct dhcp_state *dstate; |
| - int r; |
| struct ipv4_state *state; |
| struct ipv4_addr *ap; |
| |
| @@ -769,6 +776,7 @@ ipv4_deladdr(struct interface *ifp, |
| break; |
| } |
| } |
| +#endif |
| return r; |
| } |
| |
| @@ -870,6 +878,7 @@ ipv4_finalisert(struct interface *ifp) |
| void |
| ipv4_finaliseaddr(struct interface *ifp) |
| { |
| +#ifndef PASSIVE_MODE |
| struct dhcp_state *state = D_STATE(ifp); |
| struct dhcp_lease *lease; |
| |
| @@ -886,11 +895,15 @@ ipv4_finaliseaddr(struct interface *ifp) |
| state->addr.s_addr = lease->addr.s_addr; |
| state->net.s_addr = lease->net.s_addr; |
| ipv4_finalisert(ifp); |
| +#endif |
| } |
| |
| void |
| ipv4_applyaddr(void *arg) |
| { |
| +#ifdef PASSIVE_MODE |
| + rpc_update_ipv4(arg); |
| +#else |
| struct interface *ifp = arg, *ifn; |
| struct dhcp_state *state = D_STATE(ifp), *nstate; |
| struct dhcp_message *dhcp; |
| @@ -1008,6 +1021,8 @@ ipv4_applyaddr(void *arg) |
| #endif |
| |
| ipv4_finaliseaddr(ifp); |
| + |
| +#endif /* PASSIVE_MODE */ |
| } |
| |
| void |
| diff --git a/rpc-interface.h b/rpc-interface.h |
| new file mode 100644 |
| index 0000000..6e1e7e0 |
| --- /dev/null |
| +++ b/rpc-interface.h |
| @@ -0,0 +1,51 @@ |
| +/* |
| + * dhcpcd - DHCP client daemon |
| + * Copyright (c) 2006-2015 Roy Marples <roy@marples.name> |
| + * All rights reserved |
| + |
| + * Redistribution and use in source and binary forms, with or without |
| + * modification, are permitted provided that the following conditions |
| + * are met: |
| + * 1. Redistributions of source code must retain the above copyright |
| + * notice, this list of conditions and the following disclaimer. |
| + * 2. Redistributions in binary form must reproduce the above copyright |
| + * notice, this list of conditions and the following disclaimer in the |
| + * documentation and/or other materials provided with the distribution. |
| + * |
| + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
| + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
| + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| + * SUCH DAMAGE. |
| + */ |
| + |
| +#ifndef RPC_INTERFACE_H |
| +#define RPC_INTERFACE_H |
| + |
| +#include "dhcpcd.h" |
| + |
| +/* Initialize RPC interface. Return 0 on success. */ |
| +int rpc_init(struct dhcpcd_ctx *ctx); |
| + |
| +/* Tear down RPC interface. */ |
| +void rpc_close(void); |
| + |
| +/* Emit signal status to RPC interface. */ |
| +void rpc_signal_status(const char *); |
| + |
| +/* Update IPv4 configuration. Return 0 on success. */ |
| +int rpc_update_ipv4(struct interface *ifp); |
| + |
| +/* Update IPv6 configuration. Return 0 on success. */ |
| +int rpc_update_ipv6(struct interface *ifp); |
| + |
| +/* Emit notification for successful unicast ARP. Return 0 on success. */ |
| +int rpc_notify_unicast_arp(struct interface *ifp); |
| + |
| +#endif |
| diff --git a/rpc-stub.c b/rpc-stub.c |
| new file mode 100644 |
| index 0000000..aa65097 |
| --- /dev/null |
| +++ b/rpc-stub.c |
| @@ -0,0 +1,69 @@ |
| +/* |
| + * dhcpcd - DHCP client daemon |
| + * Copyright (c) 2006-2015 Roy Marples <roy@marples.name> |
| + * All rights reserved |
| + |
| + * Redistribution and use in source and binary forms, with or without |
| + * modification, are permitted provided that the following conditions |
| + * are met: |
| + * 1. Redistributions of source code must retain the above copyright |
| + * notice, this list of conditions and the following disclaimer. |
| + * 2. Redistributions in binary form must reproduce the above copyright |
| + * notice, this list of conditions and the following disclaimer in the |
| + * documentation and/or other materials provided with the distribution. |
| + * |
| + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
| + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
| + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| + * SUCH DAMAGE. |
| + */ |
| + |
| +#include "rpc-interface.h" |
| + |
| +int |
| +rpc_init(struct dhcpcd_ctx *ctx) |
| +{ |
| + /* Stub implementation. */ |
| + return 0; |
| +} |
| + |
| +void |
| +rpc_close(void) |
| +{ |
| + /* Stub implementation. */ |
| +} |
| + |
| +void |
| +rpc_signal_status(const char *reason) |
| +{ |
| + /* Stub implementation. */ |
| +} |
| + |
| +int |
| +rpc_update_ipv4(struct interface *ifp) |
| +{ |
| + /* Stub implementation. */ |
| + return 0; |
| +} |
| + |
| +int |
| +rpc_update_ipv6(struct interface *ifp) |
| +{ |
| + /* Stub implementation. */ |
| + return 0; |
| +} |
| + |
| +int |
| +rpc_notify_unicast_arp(struct interface *ifp) |
| +{ |
| + /* Stub implementation. */ |
| + return 0; |
| +} |
| + |
| -- |
| 2.2.0.rc0.207.ga3a616c |
| |