dhcpv6: rework option passthrough logic
authorHans Dedecker <dedeckeh@gmail.com>
Tue, 16 Jan 2018 12:16:09 +0000 (13:16 +0100)
committerHans Dedecker <dedeckeh@gmail.com>
Tue, 16 Jan 2018 14:17:01 +0000 (15:17 +0100)
Options are not added to the passthru state depending on the option code
check. Rework this logic by defining the flag OPT_NO_PASSTHRU which is set
for options in the opts table; when constructing the passthru state the
option is added if the flag is not set.

Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
src/dhcpv6.c
src/odhcp6c.c
src/odhcp6c.h

index 742c3b007987eca7871fb4494eaf88a2ecd3f270..4728d896f488fd05f9fc82e925f54b2024fbd193 100644 (file)
@@ -988,7 +988,7 @@ static int dhcpv6_handle_reply(enum dhcpv6_msg orig, _unused const int rc,
 
                // Parse and find all matching IAs
                dhcpv6_for_each_option(opt, end, otype, olen, odata) {
-                       bool passthru = true;
+                       struct odhcp6c_opt *dopt = odhcp6c_find_opt(otype);
 
                        if ((otype == DHCPV6_OPT_IA_PD || otype == DHCPV6_OPT_IA_NA)
                                        && olen > -4 + sizeof(struct dhcpv6_ia_hdr)) {
@@ -1031,17 +1031,14 @@ static int dhcpv6_handle_reply(enum dhcpv6_msg orig, _unused const int rc,
                                        continue;
 
                                dhcpv6_parse_ia(ia_hdr, odata + olen);
-                               passthru = false;
-                       } else if (otype == DHCPV6_OPT_UNICAST && olen == sizeof(server_addr)) {
+                       } else if (otype == DHCPV6_OPT_UNICAST && olen == sizeof(server_addr))
                                server_addr = *(struct in6_addr *)odata;
-                               passthru = false;
-                       } else if (otype == DHCPV6_OPT_STATUS && olen >= 2) {
+                       else if (otype == DHCPV6_OPT_STATUS && olen >= 2) {
                                uint8_t *mdata = (olen > 2) ? &odata[2] : NULL;
                                uint16_t mlen = (olen > 2) ? olen - 2 : 0;
                                uint16_t code = ((int)odata[0]) << 8 | ((int)odata[1]);
 
                                dhcpv6_handle_status_code(orig, code, mdata, mlen, &ret);
-                               passthru = false;
                        } else if (otype == DHCPV6_OPT_DNS_SERVERS) {
                                if (olen % 16 == 0)
                                        odhcp6c_add_state(STATE_DNS, odata, olen);
@@ -1071,7 +1068,6 @@ static int dhcpv6_handle_reply(enum dhcpv6_msg orig, _unused const int rc,
                                odhcp6c_add_state(STATE_SIP_FQDN, odata, olen);
                        else if (otype == DHCPV6_OPT_INFO_REFRESH && olen >= 4) {
                                refresh = ntohl_unaligned(odata);
-                               passthru = false;
                        } else if (otype == DHCPV6_OPT_AUTH) {
                                if (olen == -4 + sizeof(struct dhcpv6_auth_reconfigure)) {
                                        struct dhcpv6_auth_reconfigure *r = (void*)&odata[-4];
@@ -1079,25 +1075,21 @@ static int dhcpv6_handle_reply(enum dhcpv6_msg orig, _unused const int rc,
                                                        r->reconf_type == 1)
                                                memcpy(reconf_key, r->key, sizeof(r->key));
                                }
-                               passthru = false;
                        } else if (otype == DHCPV6_OPT_AFTR_NAME && olen > 3) {
                                size_t cur_len;
                                odhcp6c_get_state(STATE_AFTR_NAME, &cur_len);
                                if (cur_len == 0)
                                        odhcp6c_add_state(STATE_AFTR_NAME, odata, olen);
-                               passthru = false;
                        } else if (otype == DHCPV6_OPT_SOL_MAX_RT && olen == 4) {
                                uint32_t sol_max_rt = ntohl_unaligned(odata);
                                if (sol_max_rt >= DHCPV6_SOL_MAX_RT_MIN &&
                                                sol_max_rt <= DHCPV6_SOL_MAX_RT_MAX)
                                        dhcpv6_retx[DHCPV6_MSG_SOLICIT].max_timeo = sol_max_rt;
-                               passthru = false;
                        } else if (otype == DHCPV6_OPT_INF_MAX_RT && olen == 4) {
                                uint32_t inf_max_rt = ntohl_unaligned(odata);
                                if (inf_max_rt >= DHCPV6_INF_MAX_RT_MIN &&
                                                inf_max_rt <= DHCPV6_INF_MAX_RT_MAX)
                                        dhcpv6_retx[DHCPV6_MSG_INFO_REQ].max_timeo = inf_max_rt;
-                               passthru = false;
        #ifdef EXT_CER_ID
                        } else if (otype == DHCPV6_OPT_CER_ID && olen == -4 +
                                        sizeof(struct dhcpv6_cer_id)) {
@@ -1105,32 +1097,20 @@ static int dhcpv6_handle_reply(enum dhcpv6_msg orig, _unused const int rc,
                                struct in6_addr any = IN6ADDR_ANY_INIT;
                                if (memcmp(&cer_id->addr, &any, sizeof(any)))
                                        odhcp6c_add_state(STATE_CER, &cer_id->addr, sizeof(any));
-                               passthru = false;
        #endif
                        } else if (otype == DHCPV6_OPT_S46_CONT_MAPT) {
                                odhcp6c_add_state(STATE_S46_MAPT, odata, olen);
-                               passthru = false;
                        } else if (otype == DHCPV6_OPT_S46_CONT_MAPE) {
                                size_t mape_len;
                                odhcp6c_get_state(STATE_S46_MAPE, &mape_len);
                                if (mape_len == 0)
                                        odhcp6c_add_state(STATE_S46_MAPE, odata, olen);
-                               passthru = false;
                        } else if (otype == DHCPV6_OPT_S46_CONT_LW) {
                                odhcp6c_add_state(STATE_S46_LW, odata, olen);
-                               passthru = false;
-                       } else if (otype == DHCPV6_OPT_CLIENTID ||
-                                       otype == DHCPV6_OPT_SERVERID ||
-                                       otype == DHCPV6_OPT_IA_TA ||
-                                       otype == DHCPV6_OPT_PREF ||
-                                       otype == DHCPV6_OPT_UNICAST ||
-                                       otype == DHCPV6_OPT_FQDN ||
-                                       otype == DHCPV6_OPT_RECONF_ACCEPT)
-                               passthru = false;
-                       else
+                       } else
                                odhcp6c_add_state(STATE_CUSTOM_OPTS, &odata[-4], olen + 4);
 
-                       if (passthru)
+                       if (!dopt || !(dopt->flags & OPT_NO_PASSTHRU))
                                odhcp6c_add_state(STATE_PASSTHRU, &odata[-4], olen + 4);
                }
        }
index e5c53c10ba1cf3d988574b948a25a2c95e88682c..e03f28219c882accdea831dae84bfd704ca2a83d 100644 (file)
@@ -69,49 +69,49 @@ static unsigned int script_sync_delay = 10;
 static unsigned int script_accu_delay = 1;
 
 static struct odhcp6c_opt opts[] = {
-       { .code = DHCPV6_OPT_CLIENTID, .flags = OPT_INTERNAL, .str = NULL },
-       { .code = DHCPV6_OPT_SERVERID, .flags = OPT_INTERNAL, .str = NULL },
-       { .code = DHCPV6_OPT_IA_NA, .flags = OPT_INTERNAL, .str= NULL },
-       { .code = DHCPV6_OPT_IA_TA, .flags = OPT_INTERNAL, .str = NULL },
-       { .code = DHCPV6_OPT_IA_ADDR, .flags = OPT_INTERNAL, .str = NULL },
+       { .code = DHCPV6_OPT_CLIENTID, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU, .str = NULL },
+       { .code = DHCPV6_OPT_SERVERID, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU, .str = NULL },
+       { .code = DHCPV6_OPT_IA_NA, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU, .str= NULL },
+       { .code = DHCPV6_OPT_IA_TA, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU, .str = NULL },
+       { .code = DHCPV6_OPT_IA_ADDR, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU, .str = NULL },
        { .code = DHCPV6_OPT_ORO, .flags = OPT_INTERNAL, .str = NULL },
-       { .code = DHCPV6_OPT_PREF, .flags = OPT_INTERNAL, .str = NULL },
+       { .code = DHCPV6_OPT_PREF, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU, .str = NULL },
        { .code = DHCPV6_OPT_ELAPSED, .flags = OPT_INTERNAL, .str = NULL },
        { .code = DHCPV6_OPT_RELAY_MSG, .flags = OPT_INTERNAL, .str = NULL },
-       { .code = DHCPV6_OPT_AUTH, .flags = OPT_U8, .str = "authentication" },
-       { .code = DHCPV6_OPT_UNICAST, .flags = OPT_INTERNAL, .str = NULL },
-       { .code = DHCPV6_OPT_STATUS, .flags = OPT_INTERNAL, .str = NULL },
+       { .code = DHCPV6_OPT_AUTH, .flags = OPT_U8 | OPT_NO_PASSTHRU, .str = "authentication" },
+       { .code = DHCPV6_OPT_UNICAST, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU, .str = NULL },
+       { .code = DHCPV6_OPT_STATUS, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU, .str = NULL },
        { .code = DHCPV6_OPT_RAPID_COMMIT, .flags = OPT_INTERNAL, .str = NULL },
        { .code = DHCPV6_OPT_USER_CLASS, .flags = OPT_USER_CLASS | OPT_ARRAY, .str = "userclass" },
        { .code = DHCPV6_OPT_VENDOR_CLASS, .flags = OPT_U8, .str = "vendorclass" },
        { .code = DHCPV6_OPT_INTERFACE_ID, .flags = OPT_INTERNAL, .str = NULL },
        { .code = DHCPV6_OPT_RECONF_MESSAGE, .flags = OPT_INTERNAL, .str = NULL },
-       { .code = DHCPV6_OPT_RECONF_ACCEPT, .flags = OPT_INTERNAL, .str = NULL },
-       { .code = DHCPV6_OPT_RECONF_ACCEPT, .flags = OPT_INTERNAL, .str = NULL },
+       { .code = DHCPV6_OPT_RECONF_ACCEPT, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU, .str = NULL },
        { .code = DHCPV6_OPT_DNS_SERVERS, .flags = OPT_IP6 | OPT_ARRAY, .str = "dns" },
        { .code = DHCPV6_OPT_DNS_DOMAIN, .flags = OPT_DNS_STR, .str = "search" },
-       { .code = DHCPV6_OPT_IA_PD, .flags = OPT_INTERNAL, .str = NULL },
+       { .code = DHCPV6_OPT_IA_PD, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU, .str = NULL },
        { .code = DHCPV6_OPT_IA_PREFIX, .flags = OPT_INTERNAL, .str = NULL },
        { .code = DHCPV6_OPT_SNTP_SERVERS, .flags = OPT_IP6 | OPT_ARRAY, .str = "sntpservers" },
-       { .code = DHCPV6_OPT_INFO_REFRESH, .flags = OPT_INTERNAL, .str = NULL },
+       { .code = DHCPV6_OPT_INFO_REFRESH, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU, .str = NULL },
+       { .code = DHCPV6_OPT_FQDN, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU, .str = NULL },
        { .code = DHCPV6_OPT_NTP_SERVER, .flags = OPT_U8, .str = "ntpserver" },
        { .code = DHCPV6_OPT_SIP_SERVER_D, .flags = OPT_DNS_STR, .str = "sipserver_d" },
        { .code = DHCPV6_OPT_SIP_SERVER_A, .flags = OPT_IP6 | OPT_ARRAY, .str = "sipserver_a" },
-       { .code = DHCPV6_OPT_AFTR_NAME, .flags = OPT_INTERNAL, .str = NULL },
+       { .code = DHCPV6_OPT_AFTR_NAME, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU, .str = NULL },
        { .code = DHCPV6_OPT_PD_EXCLUDE, .flags = OPT_INTERNAL, .str = NULL },
-       { .code = DHCPV6_OPT_SOL_MAX_RT, .flags = OPT_INTERNAL, .str = NULL },
-       { .code = DHCPV6_OPT_INF_MAX_RT, .flags = OPT_INTERNAL, .str = NULL },
+       { .code = DHCPV6_OPT_SOL_MAX_RT, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU, .str = NULL },
+       { .code = DHCPV6_OPT_INF_MAX_RT, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU, .str = NULL },
 #ifdef EXT_CER_ID
-       { .code = DHCPV6_OPT_CER_ID, .flags = OPT_INTERNAL, .str = NULL },
+       { .code = DHCPV6_OPT_CER_ID, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU, .str = NULL },
 #endif
-       { .code = DHCPV6_OPT_S46_RULE, .flags = OPT_INTERNAL, .str = NULL },
-       { .code = DHCPV6_OPT_S46_BR, .flags = OPT_INTERNAL, .str = NULL },
-       { .code = DHCPV6_OPT_S46_DMR, .flags = OPT_INTERNAL, .str = NULL },
-       { .code = DHCPV6_OPT_S46_V4V6BIND, .flags = OPT_INTERNAL, .str = NULL },
-       { .code = DHCPV6_OPT_S46_PORTPARAMS, .flags = OPT_INTERNAL, .str = NULL },
-       { .code = DHCPV6_OPT_S46_CONT_MAPE, .flags = OPT_INTERNAL, .str = NULL },
-       { .code = DHCPV6_OPT_S46_CONT_MAPT, .flags = OPT_INTERNAL, .str = NULL },
-       { .code = DHCPV6_OPT_S46_CONT_LW, .flags = OPT_INTERNAL, .str = NULL },
+       { .code = DHCPV6_OPT_S46_RULE, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU, .str = NULL },
+       { .code = DHCPV6_OPT_S46_BR, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU, .str = NULL },
+       { .code = DHCPV6_OPT_S46_DMR, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU, .str = NULL },
+       { .code = DHCPV6_OPT_S46_V4V6BIND, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU, .str = NULL },
+       { .code = DHCPV6_OPT_S46_PORTPARAMS, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU, .str = NULL },
+       { .code = DHCPV6_OPT_S46_CONT_MAPE, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU, .str = NULL },
+       { .code = DHCPV6_OPT_S46_CONT_MAPT, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU, .str = NULL },
+       { .code = DHCPV6_OPT_S46_CONT_LW, .flags = OPT_INTERNAL | OPT_NO_PASSTHRU, .str = NULL },
        { .code = 0, .flags = 0, .str = NULL },
 };
 
index 40fed3e0bc570da1ae2c5e3fae5713d98a3d52d7..e41aa3c56d3a5ae5f23b112746d0f57786e7bdbe 100644 (file)
@@ -330,6 +330,7 @@ enum odhcp6c_opt_flags {
        OPT_MASK_SIZE = 0x0F,
        OPT_ARRAY = 0x10,
        OPT_INTERNAL = 0x20,
+       OPT_NO_PASSTHRU = 0x40,
 };
 
 struct odhcp6c_opt {