]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
move DHCPv4 to new process state machine
authorAlan T. DeKok <aland@freeradius.org>
Tue, 23 Mar 2021 18:47:06 +0000 (14:47 -0400)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 31 Mar 2021 15:10:00 +0000 (16:10 +0100)
share/dictionary/dhcpv4/dictionary.freeradius.internal
share/dictionary/dhcpv4/dictionary.rfc2131
src/listen/dhcpv4/proto_dhcpv4.c
src/listen/dhcpv4/proto_dhcpv4.h
src/process/dhcpv4/base.c
src/protocols/dhcpv4/dhcpv4.h

index a8250378c14ebefc39146cc9f5a93b93d92603cf..175576f15cc12bd7f2fd7e91722db9ca6ecf962b 100644 (file)
@@ -88,8 +88,6 @@ VALUE Hardware-Type           HFI                     37
 
 ATTRIBUTE      Packet-Type                             273     integer
 
-VALUE  Packet-Type                     Do-Not-Respond  0
-VALUE  Packet-Type                     Do-Not-Respond          0
 VALUE  Packet-Type                     Discover                1
 VALUE  Packet-Type                     Offer           2
 VALUE  Packet-Type                     Request         3
@@ -106,6 +104,8 @@ VALUE       Packet-Type                     Lease-Active    13
 VALUE  Packet-Type                     Bulk-Lease-Query        14
 VALUE  Packet-Type                     Lease-Query-Done        15
 
+VALUE  Packet-Type                     Do-Not-Respond  256
+
 # This subnet is assigned on a hierarchical basis to then determine
 # the subnet which the client belongs to.  Stored as a prefix to
 # enable closest subnet matching
index 415c48853f6bb003cc92f9e3e6fd3e128d39894c..e0f3f9e124c93b14f6efec4f7e84e62ea5414562 100644 (file)
@@ -89,7 +89,6 @@ ATTRIBUTE     IP-Address-Lease-Time           51      integer
 ATTRIBUTE      Overload                                52      byte
 ATTRIBUTE      Message-Type                    53      byte
 
-VALUE  Message-Type            Do-Not-Respond          0
 VALUE  Message-Type            Discover                1
 VALUE  Message-Type            Offer                   2
 VALUE  Message-Type            Request                 3
index cae5d5d5a417b1cef4529782e931826356be44ba..b4d1585e78c1bf07cb093333a7d839215d6e0dfe 100644 (file)
@@ -128,7 +128,7 @@ static int type_parse(UNUSED TALLOC_CTX *ctx, void *out, void *parent,
        value = cf_pair_value(cp);
 
        dv = fr_dict_enum_by_name(attr_packet_type, value, -1);
-       if (!dv || (dv->value->vb_uint32 >= FR_DHCP_MAX)) {
+       if (!dv || (dv->value->vb_uint32 >= FR_DHCP_CODE_MAX)) {
                cf_log_err(ci, "Unknown DHCPv4 packet type '%s'", value);
                return -1;
        }
@@ -257,8 +257,8 @@ static ssize_t mod_encode(void const *instance, request_t *request, uint8_t *buf
         *      send replies to a release.
         */
        if ((buffer_len == 1) ||
-           (request->reply->code == FR_MESSAGE_TYPE_VALUE_DO_NOT_RESPOND) ||
-           (request->reply->code == 0) || (request->reply->code >= FR_DHCP_MAX) ||
+           (request->reply->code == FR_DHCP_DO_NOT_RESPOND) ||
+           (request->reply->code == 0) || (request->reply->code >= FR_DHCP_CODE_MAX) ||
            (request->packet->code == FR_DHCP_RELEASE)) {
                track->do_not_respond = true;
                return 1;
@@ -347,7 +347,7 @@ static int mod_priority_set(void const *instance, uint8_t const *buffer, size_t
        fr_assert(code != NULL);
        fr_assert(code[1] == 1);
        fr_assert(code[2] != 0);
-       fr_assert(code[2] < FR_DHCP_MAX);
+       fr_assert(code[2] < FR_DHCP_CODE_MAX);
 
        /*
         *      Disallowed packet
index 9709720557487a0ee6ddf765438d237242617b7b..67578f4ea366376ead4142ce5bb780e559767e75 100644 (file)
@@ -33,12 +33,12 @@ typedef struct {
        fr_io_instance_t                io;                             //!< wrapper for IO abstraction
 
        char                            **allowed_types;                //!< names for for 'type = ...'
-       bool                            allowed[FR_DHCP_MAX];   //!< indexed by value
+       bool                            allowed[FR_DHCP_CODE_MAX];      //!< indexed by value
 
        uint32_t                        max_packet_size;                //!< for message ring buffer.
        uint32_t                        num_messages;                   //!< for message ring buffer.
 
-       uint32_t                        priorities[FR_DHCP_MAX];        //!< priorities for individual packets
+       uint32_t                        priorities[FR_DHCP_CODE_MAX];   //!< priorities for individual packets
 } proto_dhcpv4_t;
 
 /*
index b91b666c0f42fe944ed63cdb1743b1e5dfd5c0bb..a2a3cb3f358d983eb4e4a93c8e05dfc1f0b6d5fd 100644 (file)
@@ -26,7 +26,6 @@
 
 #include <freeradius-devel/io/application.h>
 #include <freeradius-devel/server/protocol.h>
-#include <freeradius-devel/server/process.h>
 #include <freeradius-devel/unlang/base.h>
 #include <freeradius-devel/util/dict.h>
 #include <freeradius-devel/util/debug.h>
@@ -43,11 +42,13 @@ fr_dict_autoload_t process_dhcpv4_dict[] = {
 
 static fr_dict_attr_t const *attr_message_type;
 static fr_dict_attr_t const *attr_yiaddr;
+static fr_dict_attr_t const *attr_packet_type;
 
 extern fr_dict_attr_autoload_t process_dhcpv4_dict_attr[];
 fr_dict_attr_autoload_t process_dhcpv4_dict_attr[] = {
        { .out = &attr_message_type, .name = "Message-Type", .type = FR_TYPE_UINT8, .dict = &dict_dhcpv4},
        { .out = &attr_yiaddr, .name = "Your-IP-Address", .type = FR_TYPE_IPV4_ADDR, .dict = &dict_dhcpv4},
+       { .out = &attr_packet_type, .name = "Packet-Type", .type = FR_TYPE_UINT32, .dict = &dict_dhcpv4},
        { NULL }
 };
 
@@ -109,199 +110,219 @@ static void dhcpv4_packet_debug(request_t *request, fr_radius_packet_t *packet,
        }
 }
 
-static unlang_action_t mod_process(rlm_rcode_t *p_result, UNUSED module_ctx_t const *mctx, request_t *request)
+typedef struct {
+       uint64_t        nothing;                // so that the next field isn't at offset 0
+
+       CONF_SECTION    *discover;
+       CONF_SECTION    *offer;
+       CONF_SECTION    *request;
+       CONF_SECTION    *decline;
+       CONF_SECTION    *ack;
+       CONF_SECTION    *nak;
+       CONF_SECTION    *release;
+       CONF_SECTION    *inform;
+       CONF_SECTION    *force_renew;
+#if 0
+       CONF_SECTION    *lease_query;
+       CONF_SECTION    *lease_unassigned;
+       CONF_SECTION    *lease_unknown;
+       CONF_SECTION    *lease_active;
+#endif
+       CONF_SECTION    *do_not_respond;
+} process_dhcpv4_sections_t;
+
+typedef struct {
+       process_dhcpv4_sections_t sections;
+} process_dhcpv4_t;
+
+#define PROCESS_PACKET_TYPE            fr_dhcpv4_packet_code_t
+#define PROCESS_CODE_MAX               FR_DHCP_CODE_MAX
+#define PROCESS_CODE_DO_NOT_RESPOND    FR_DHCP_DO_NOT_RESPOND
+#define PROCESS_PACKET_CODE_VALID      FR_DHCP_PACKET_CODE_VALID
+#define PROCESS_INST                   process_dhcpv4_t
+#include <freeradius-devel/server/process.h>
+
+RESUME(check_yiaddr)
 {
-       rlm_rcode_t rcode;
-       CONF_SECTION *unlang;
-       fr_dict_enum_t const *dv;
        fr_pair_t *vp;
 
-       static int reply_ok[] = {
-               [0]                     = FR_MESSAGE_TYPE_VALUE_DO_NOT_RESPOND,
-               [FR_DHCP_DISCOVER]      = FR_DHCP_OFFER,
-               [FR_DHCP_OFFER]         = FR_DHCP_OFFER,
-               [FR_DHCP_REQUEST]       = FR_DHCP_ACK,
-               [FR_DHCP_DECLINE]       = 0,
-               [FR_DHCP_ACK]           = FR_DHCP_ACK,
-               [FR_DHCP_NAK]           = FR_DHCP_NAK,
-               [FR_DHCP_RELEASE]       = 0,
-               [FR_DHCP_INFORM]        = FR_DHCP_ACK,
-               [FR_DHCP_LEASE_QUERY]   = FR_DHCP_LEASE_ACTIVE, /* not really correct, but whatever */
-       };
-
-       static int reply_fail[] = {
-               [0]                     = FR_MESSAGE_TYPE_VALUE_DO_NOT_RESPOND,
-               [FR_DHCP_DISCOVER]      = 0,
-               [FR_DHCP_OFFER]         = FR_DHCP_NAK,
-               [FR_DHCP_REQUEST]       = FR_DHCP_NAK,
-               [FR_DHCP_DECLINE]       = 0,
-               [FR_DHCP_ACK]           = FR_DHCP_NAK,
-               [FR_DHCP_NAK]           = FR_DHCP_NAK,
-               [FR_DHCP_RELEASE]       = 0,
-               [FR_DHCP_INFORM]        = FR_MESSAGE_TYPE_VALUE_DO_NOT_RESPOND,
-               [FR_DHCP_LEASE_QUERY]   = FR_DHCP_LEASE_UNKNOWN,
-       };
-
-#define REPLY_OK(_code, _default)      ((_code < NUM_ELEMENTS(reply_ok)) ? reply_ok[_code] : _default)
-#define REPLY_FAIL(_code, _default)    ((_code < NUM_ELEMENTS(reply_fail)) ? reply_fail[_code] : _default)
-
-       REQUEST_VERIFY(request);
-       fr_assert(request->packet->code > 0);
-       fr_assert(request->packet->code < NUM_ELEMENTS(reply_ok));
-
-       switch (request->request_state) {
-       case REQUEST_INIT:
-               dhcpv4_packet_debug(request, request->packet, &request->request_pairs, true);
-
-               request->component = "dhcpv4";
-
-               dv = fr_dict_enum_by_value(attr_message_type, fr_box_uint8(request->packet->code));
-               if (!dv) {
-                       REDEBUG("Failed to find value for &request.DHCP-Message-Type");
-                       RETURN_MODULE_FAIL;
-               }
-
-               unlang = cf_section_find(unlang_call_current(request), "recv", dv->name);
-               if (!unlang) {
-                       RWDEBUG("Failed to find 'recv %s' section", dv->name);
-                       request->reply->code = FR_MESSAGE_TYPE_VALUE_DO_NOT_RESPOND;
-                       goto send_reply;
-               }
-
-               RDEBUG("Running 'recv %s' from file %s", cf_section_name2(unlang), cf_filename(unlang));
-               if (unlang_interpret_push_section(request, unlang, RLM_MODULE_NOOP, UNLANG_TOP_FRAME) < 0) {
-                       RETURN_MODULE_FAIL;
-               }
-
-               request->request_state = REQUEST_RECV;
-               FALL_THROUGH;
-
-       case REQUEST_RECV:
-               rcode = unlang_interpret(request);
-
-               if (request->master_state == REQUEST_STOP_PROCESSING) {
-                       *p_result = RLM_MODULE_HANDLED;
-                       return UNLANG_ACTION_STOP_PROCESSING;
-               }
-
-               if (rcode == RLM_MODULE_YIELD) return UNLANG_ACTION_YIELD;
-
-               /*
-                *      Allow the admin to explicitly set the reply
-                *      type.
-                */
-               vp = fr_pair_find_by_da(&request->reply_pairs, attr_message_type);
-               if (vp) {
-                       request->reply->code = vp->vp_uint8;
-               } else switch (rcode) {
-               case RLM_MODULE_NOOP:
-               case RLM_MODULE_OK:
-               case RLM_MODULE_UPDATED:
-                       request->reply->code = REPLY_OK(request->packet->code, FR_MESSAGE_TYPE_VALUE_DO_NOT_RESPOND);
-                       break;
-
-               default:
-               case RLM_MODULE_REJECT:
-               case RLM_MODULE_FAIL:
-                       request->reply->code = REPLY_FAIL(request->packet->code, FR_MESSAGE_TYPE_VALUE_DO_NOT_RESPOND);
-                       break;
-
-               case RLM_MODULE_HANDLED:
-                       if (!request->reply->code) request->reply->code = FR_MESSAGE_TYPE_VALUE_DO_NOT_RESPOND;
-                       break;
-               }
-
-               /*
-                *      Release / Decline doesn't send a reply, and doesn't run "send Do-Not-Respond"
-                */
-               if (!request->reply->code) {
-                       RETURN_MODULE_HANDLED;
-               }
-
-               /*
-                *      Offer and ACK MUST have YIADDR.
-                */
-               if ((request->reply->code == FR_DHCP_OFFER) || (request->reply->code == FR_DHCP_ACK)) {
-                       vp = fr_pair_find_by_da(&request->reply_pairs, attr_yiaddr);
-                       if (!vp) {
-                               REDEBUG("%s packet does not have YIADDR.  The client will not receive an IP address.",
-                                       dhcp_message_types[request->reply->code]);
-                       }
-               }
-
-               dv = fr_dict_enum_by_value(attr_message_type, fr_box_uint8(request->reply->code));
-               unlang = NULL;
-               if (dv) unlang = cf_section_find(unlang_call_current(request), "send", dv->name);
-
-               if (!unlang) goto send_reply;
-
-       rerun_nak:
-               RDEBUG("Running 'send %s' from file %s", cf_section_name2(unlang), cf_filename(unlang));
-               if (unlang_interpret_push_section(request, unlang, RLM_MODULE_NOOP, UNLANG_TOP_FRAME) < 0) {
-                       RETURN_MODULE_FAIL;
-               }
-
-               request->request_state = REQUEST_SEND;
-               FALL_THROUGH;
-
-       case REQUEST_SEND:
-               rcode = unlang_interpret(request);
-
-               if (request->master_state == REQUEST_STOP_PROCESSING) {
-                       *p_result = RLM_MODULE_HANDLED;
-                       return UNLANG_ACTION_STOP_PROCESSING;
-               }
-
-               if (rcode == RLM_MODULE_YIELD) return UNLANG_ACTION_YIELD;
-
-               switch (rcode) {
-               case RLM_MODULE_NOOP:
-               case RLM_MODULE_OK:
-               case RLM_MODULE_UPDATED:
-               case RLM_MODULE_HANDLED:
-                       /* reply is already set */
-                       break;
-
-               default:
-                       /*
-                        *      If we over-ride an ACK with a NAK, run
-                        *      the NAK section.
-                        */
-                       if (request->reply->code != FR_MESSAGE_TYPE_VALUE_DO_NOT_RESPOND) {
-                               dv = fr_dict_enum_by_value(attr_message_type, fr_box_uint8(request->reply->code));
-                               RWDEBUG("Failed running 'send %s', trying 'send Do-Not-Respond'", dv->name);
-
-                               request->reply->code = FR_MESSAGE_TYPE_VALUE_DO_NOT_RESPOND;
-
-                               dv = fr_dict_enum_by_value(attr_message_type, fr_box_uint8(request->reply->code));
-                               unlang = NULL;
-                               if (!dv) goto send_reply;
-
-                               unlang = cf_section_find(unlang_call_current(request), "send", dv->name);
-                               if (unlang) goto rerun_nak;
-
-                               RWDEBUG("Not running 'send %s' section as it does not exist", dv->name);
-                       }
-                       break;
-               }
-
-       send_reply:
-               /*
-                *      Check for "do not respond".
-                */
-               if (request->reply->code == FR_MESSAGE_TYPE_VALUE_DO_NOT_RESPOND) {
-                       RDEBUG("Not sending reply to client");
-                       RETURN_MODULE_HANDLED;
-               }
-
-               if (RDEBUG_ENABLED) dhcpv4_packet_debug(request, request->reply, &request->reply_pairs, false);
-               break;
-
-       default:
-               RETURN_MODULE_FAIL;
+       vp = fr_pair_find_by_da(&request->reply_pairs, attr_yiaddr);
+       if (!vp) {
+               REDEBUG("%s packet does not have YIADDR.  The client will not receive an IP address.",
+                       dhcp_message_types[request->reply->code]);
        }
 
-       RETURN_MODULE_OK;
+       return CALL_RESUME(send_generic);
+}
+
+static fr_process_state_t const process_state[] = {
+       [FR_DHCP_DISCOVER] = {
+               .packet_type = {
+                       [RLM_MODULE_OK] =       FR_DHCP_OFFER,
+                       [RLM_MODULE_NOOP] =     FR_DHCP_DO_NOT_RESPOND,
+                       [RLM_MODULE_UPDATED] =  FR_DHCP_OFFER,
+
+                       [RLM_MODULE_REJECT] =   FR_DHCP_DO_NOT_RESPOND,
+                       [RLM_MODULE_FAIL] =     FR_DHCP_DO_NOT_RESPOND,
+                       [RLM_MODULE_INVALID] =  FR_DHCP_DO_NOT_RESPOND,
+                       [RLM_MODULE_DISALLOW] = FR_DHCP_DO_NOT_RESPOND,
+                       [RLM_MODULE_NOTFOUND] = FR_DHCP_DO_NOT_RESPOND,
+               },
+               .rcode = RLM_MODULE_NOOP,
+               .default_reply = FR_DHCP_DO_NOT_RESPOND,
+               .recv = recv_generic,
+               .resume = resume_recv_generic,
+               .section_offset = PROCESS_CONF_OFFSET(discover),
+       },
+       [FR_DHCP_OFFER] = {
+               .packet_type = {
+                       [RLM_MODULE_OK] =       FR_DHCP_OFFER,
+                       [RLM_MODULE_NOOP] =     FR_DHCP_DO_NOT_RESPOND,
+                       [RLM_MODULE_UPDATED] =  FR_DHCP_OFFER,
+
+                       [RLM_MODULE_REJECT] =   FR_DHCP_DO_NOT_RESPOND,
+                       [RLM_MODULE_FAIL] =     FR_DHCP_DO_NOT_RESPOND,
+                       [RLM_MODULE_INVALID] =  FR_DHCP_DO_NOT_RESPOND,
+                       [RLM_MODULE_DISALLOW] = FR_DHCP_DO_NOT_RESPOND,
+                       [RLM_MODULE_NOTFOUND] = FR_DHCP_DO_NOT_RESPOND,
+               },
+               .rcode = RLM_MODULE_NOOP,
+               .default_reply = FR_DHCP_DO_NOT_RESPOND,
+               .send = send_generic,
+               .resume = resume_check_yiaddr,
+               .section_offset = PROCESS_CONF_OFFSET(offer),
+       },
+
+       [FR_DHCP_REQUEST] = {
+               .packet_type = {
+                       [RLM_MODULE_OK] =       FR_DHCP_ACK,
+                       [RLM_MODULE_NOOP] =     FR_DHCP_DO_NOT_RESPOND,
+                       [RLM_MODULE_UPDATED] =  FR_DHCP_ACK,
+
+                       [RLM_MODULE_REJECT] =   FR_DHCP_NAK,
+                       [RLM_MODULE_FAIL] =     FR_DHCP_NAK,
+                       [RLM_MODULE_INVALID] =  FR_DHCP_NAK,
+                       [RLM_MODULE_DISALLOW] = FR_DHCP_NAK,
+                       [RLM_MODULE_NOTFOUND] = FR_DHCP_NAK,
+               },
+               .rcode = RLM_MODULE_NOOP,
+               .default_reply = FR_DHCP_DO_NOT_RESPOND,
+               .recv = recv_generic,
+               .resume = resume_recv_generic,
+               .section_offset = PROCESS_CONF_OFFSET(request),
+       },
+       [FR_DHCP_ACK] = {
+               .packet_type = {
+                       [RLM_MODULE_OK] =       FR_DHCP_ACK,
+                       [RLM_MODULE_NOOP] =     FR_DHCP_DO_NOT_RESPOND,
+                       [RLM_MODULE_UPDATED] =  FR_DHCP_ACK,
+
+                       [RLM_MODULE_REJECT] =   FR_DHCP_NAK,
+                       [RLM_MODULE_FAIL] =     FR_DHCP_NAK,
+                       [RLM_MODULE_INVALID] =  FR_DHCP_NAK,
+                       [RLM_MODULE_DISALLOW] = FR_DHCP_NAK,
+                       [RLM_MODULE_NOTFOUND] = FR_DHCP_NAK,
+               },
+               .rcode = RLM_MODULE_NOOP,
+               .default_reply = FR_DHCP_DO_NOT_RESPOND,
+               .send = send_generic,
+               .resume = resume_check_yiaddr,
+               .section_offset = PROCESS_CONF_OFFSET(ack),
+       },
+       [FR_DHCP_NAK] = {
+               .packet_type = {
+                       [RLM_MODULE_OK] =       FR_DHCP_NAK,
+                       [RLM_MODULE_NOOP] =     FR_DHCP_DO_NOT_RESPOND,
+                       [RLM_MODULE_UPDATED] =  FR_DHCP_NAK,
+
+                       [RLM_MODULE_REJECT] =   FR_DHCP_NAK,
+                       [RLM_MODULE_FAIL] =     FR_DHCP_NAK,
+                       [RLM_MODULE_INVALID] =  FR_DHCP_NAK,
+                       [RLM_MODULE_DISALLOW] = FR_DHCP_NAK,
+                       [RLM_MODULE_NOTFOUND] = FR_DHCP_NAK,
+               },
+               .rcode = RLM_MODULE_NOOP,
+               .default_reply = FR_DHCP_DO_NOT_RESPOND,
+               .send = send_generic,
+               .resume = resume_send_generic,
+               .section_offset = PROCESS_CONF_OFFSET(ack),
+       },
+
+       [FR_DHCP_INFORM] = {
+               .packet_type = {
+                       [RLM_MODULE_OK] =       FR_DHCP_ACK,
+                       [RLM_MODULE_NOOP] =     FR_DHCP_DO_NOT_RESPOND,
+                       [RLM_MODULE_UPDATED] =  FR_DHCP_ACK,
+
+                       [RLM_MODULE_REJECT] =   FR_DHCP_DO_NOT_RESPOND,
+                       [RLM_MODULE_FAIL] =     FR_DHCP_DO_NOT_RESPOND,
+                       [RLM_MODULE_INVALID] =  FR_DHCP_DO_NOT_RESPOND,
+                       [RLM_MODULE_DISALLOW] = FR_DHCP_DO_NOT_RESPOND,
+                       [RLM_MODULE_NOTFOUND] = FR_DHCP_DO_NOT_RESPOND,
+               },
+               .rcode = RLM_MODULE_NOOP,
+               .default_reply = FR_DHCP_DO_NOT_RESPOND,
+               .recv = recv_generic,
+               .resume = resume_recv_generic,
+               .section_offset = PROCESS_CONF_OFFSET(inform),
+       },
+
+       [FR_DHCP_RELEASE] = {   /* releases are not responded to */
+               .packet_type = {
+                       [RLM_MODULE_OK] =       FR_DHCP_DO_NOT_RESPOND,
+                       [RLM_MODULE_NOOP] =     FR_DHCP_DO_NOT_RESPOND,
+                       [RLM_MODULE_UPDATED] =  FR_DHCP_DO_NOT_RESPOND,
+
+                       [RLM_MODULE_REJECT] =   FR_DHCP_DO_NOT_RESPOND,
+                       [RLM_MODULE_FAIL] =     FR_DHCP_DO_NOT_RESPOND,
+                       [RLM_MODULE_INVALID] =  FR_DHCP_DO_NOT_RESPOND,
+                       [RLM_MODULE_DISALLOW] = FR_DHCP_DO_NOT_RESPOND,
+                       [RLM_MODULE_NOTFOUND] = FR_DHCP_DO_NOT_RESPOND,
+               },
+               .rcode = RLM_MODULE_NOOP,
+               .default_reply = FR_DHCP_DO_NOT_RESPOND,
+               .recv = recv_generic,
+               .resume = resume_recv_generic,
+               .section_offset = PROCESS_CONF_OFFSET(request),
+       },
+
+       [FR_DHCP_DO_NOT_RESPOND] = {
+               .packet_type = {
+                       [RLM_MODULE_OK] =       FR_DHCP_DO_NOT_RESPOND,
+                       [RLM_MODULE_NOOP] =     FR_DHCP_DO_NOT_RESPOND,
+                       [RLM_MODULE_UPDATED] =  FR_DHCP_DO_NOT_RESPOND,
+
+                       [RLM_MODULE_REJECT] =   FR_DHCP_DO_NOT_RESPOND,
+                       [RLM_MODULE_FAIL] =     FR_DHCP_DO_NOT_RESPOND,
+                       [RLM_MODULE_INVALID] =  FR_DHCP_DO_NOT_RESPOND,
+                       [RLM_MODULE_DISALLOW] = FR_DHCP_DO_NOT_RESPOND,
+                       [RLM_MODULE_NOTFOUND] = FR_DHCP_DO_NOT_RESPOND,
+               },
+               .rcode = RLM_MODULE_NOOP,
+               .default_reply = FR_DHCP_DO_NOT_RESPOND,
+               .recv = recv_generic,
+               .resume = resume_recv_generic,
+               .section_offset = PROCESS_CONF_OFFSET(do_not_respond),
+       },
+};
+
+static unlang_action_t mod_process(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
+{
+       fr_process_state_t const *state;
+
+       PROCESS_TRACE;
+
+       (void)talloc_get_type_abort_const(mctx->instance, process_dhcpv4_t);
+       fr_assert(PROCESS_PACKET_CODE_VALID(request->packet->code));
+
+       request->component = "dhcpv4";
+       fr_assert(request->dict == dict_dhcpv4);
+
+       UPDATE_STATE(packet);
+
+       dhcpv4_packet_debug(request, request->packet, &request->request_pairs, true);
+
+       return state->recv(p_result, mctx, request);
 }
 
 static const virtual_server_compile_t compile_list[] = {
@@ -317,11 +338,13 @@ static const virtual_server_compile_t compile_list[] = {
                        },
                        COMPILE_TERMINATOR
                },
+               .offset = PROCESS_CONF_OFFSET(discover),
        },
        {
                .name = "send",
                .name2 = "Offer",
                .component = MOD_POST_AUTH,
+               .offset = PROCESS_CONF_OFFSET(offer),
        },
        {
                .name = "recv",
@@ -335,17 +358,20 @@ static const virtual_server_compile_t compile_list[] = {
                        },
                        COMPILE_TERMINATOR
                },
+               .offset = PROCESS_CONF_OFFSET(request),
        },
 
        {
                .name = "send",
                .name2 = "Ack",
                .component = MOD_POST_AUTH,
+               .offset = PROCESS_CONF_OFFSET(ack),
        },
        {
                .name = "send",
                .name2 = "NAK",
                .component = MOD_POST_AUTH,
+               .offset = PROCESS_CONF_OFFSET(nak),
        },
        {
                .name = "recv",
@@ -359,6 +385,7 @@ static const virtual_server_compile_t compile_list[] = {
                        },
                        COMPILE_TERMINATOR
                },
+               .offset = PROCESS_CONF_OFFSET(decline),
        },
 
        {
@@ -373,37 +400,50 @@ static const virtual_server_compile_t compile_list[] = {
                        },
                        COMPILE_TERMINATOR
                },
+               .offset = PROCESS_CONF_OFFSET(release),
        },
        {
                .name = "recv",
                .name2 = "Inform",
                .component = MOD_POST_AUTH,
-       },
-       {
-               .name = "send",
-               .name2 = "Do-Not-Respond",
-               .component = MOD_POST_AUTH,
+               .offset = PROCESS_CONF_OFFSET(inform),
        },
 
+#if 0
+       /*
+        *      These are for TCP transport.
+        */
        {
                .name = "recv",
                .name2 = "Lease-Query",
                .component = MOD_POST_AUTH,
+               .offset = PROCESS_CONF_OFFSET(lease_query),
        },
        {
                .name = "send",
                .name2 = "Lease-Unassigned",
                .component = MOD_POST_AUTH,
+               .offset = PROCESS_CONF_OFFSET(lease_unassigned),
        },
        {
                .name = "send",
                .name2 = "Lease-Unknown",
                .component = MOD_POST_AUTH,
+               .offset = PROCESS_CONF_OFFSET(lease_unknown),
        },
        {
                .name = "send",
                .name2 = "Lease-Active",
                .component = MOD_POST_AUTH,
+               .offset = PROCESS_CONF_OFFSET(lease_active),
+       },
+#endif
+
+       {
+               .name = "send",
+               .name2 = "Do-Not-Respond",
+               .component = MOD_POST_AUTH,
+               .offset = PROCESS_CONF_OFFSET(do_not_respond),
        },
 
        COMPILE_TERMINATOR
index eeb59afaf7ce0dd5e82e5ca09f2c967a14c0d588..4de151d76777a1a617b8861bebf7839f0ddb8181 100644 (file)
@@ -41,23 +41,27 @@ extern "C" {
 #define DHCP_OPTION_MAGIC_NUMBER (0x63825363)
 
 typedef enum {
-       FR_DHCP_DISCOVER = (1),
-       FR_DHCP_OFFER = (2),
-       FR_DHCP_REQUEST = (3),
-       FR_DHCP_DECLINE = (4),
-       FR_DHCP_ACK = (5),
-       FR_DHCP_NAK = (6),
-       FR_DHCP_RELEASE = (7),
-       FR_DHCP_INFORM = (8),
-       FR_DHCP_FORCE_RENEW = (9),
-       FR_DHCP_LEASE_QUERY = (10),
-       FR_DHCP_LEASE_UNASSIGNED = (11),
-       FR_DHCP_LEASE_UNKNOWN = (12),
-       FR_DHCP_LEASE_ACTIVE = (13),
-       FR_DHCP_BULK_LEASE_QUERY = (14),
-       FR_DHCP_LEASE_QUERY_DONE = (15),
-       FR_DHCP_MAX = (16)
-} fr_dhcpv4_codes_t;
+       FR_DHCP_INVALID = 0,
+       FR_DHCP_DISCOVER = 1,
+       FR_DHCP_OFFER = 2,
+       FR_DHCP_REQUEST = 3,
+       FR_DHCP_DECLINE = 4,
+       FR_DHCP_ACK = 5,
+       FR_DHCP_NAK = 6,
+       FR_DHCP_RELEASE = 7,
+       FR_DHCP_INFORM = 8,
+       FR_DHCP_FORCE_RENEW = 9,
+       FR_DHCP_LEASE_QUERY = 10,
+       FR_DHCP_LEASE_UNASSIGNED = 11,
+       FR_DHCP_LEASE_UNKNOWN = 12,
+       FR_DHCP_LEASE_ACTIVE = 13,
+       FR_DHCP_BULK_LEASE_QUERY = 14,
+       FR_DHCP_LEASE_QUERY_DONE = 15,
+       FR_DHCP_CODE_MAX = 16,
+       FR_DHCP_DO_NOT_RESPOND = 256,
+} fr_dhcpv4_packet_code_t;
+
+#define FR_DHCP_PACKET_CODE_VALID(_code) (((_code) > 0) && ((_code) < FR_DHCP_CODE_MAX))
 
 /** subtype values for DHCPv4 and DHCPv6
  *