Turned enforcement on by default at startup. Added a ulogd.conf config option to...
[distributedratelimiting.git] / drl / ulogd_DRL.c
index f785d30..f9d6d56 100644 (file)
  * Add the config options for DRL. 
  */
 
-static config_entry_t partition = {
+static config_entry_t enforce_on = {
     .next = NULL,
+    .key = "enforce_on",
+    .type = CONFIG_TYPE_INT,
+    .options = CONFIG_OPT_NONE,
+    .u = { .value = 1 },
+};
+
+static config_entry_t partition = {
+    .next = &enforce_on,
     .key = "partition_set",
     .type = CONFIG_TYPE_INT,
     .options = CONFIG_OPT_NONE,
@@ -586,6 +594,7 @@ static identity_t *new_identity(ident_config *config) {
     ident->ewma_weight = pow(ident->fixed_ewma_weight, 
                              (limiter.estintms/1000.0) * config->mainloop_intervals);
     ident->parent = NULL;
+    ident->independent = config->independent;
 
     pthread_mutex_init(&ident->table_mutex, NULL);
     switch (config->accounting) {
@@ -763,11 +772,17 @@ static int validate_configs(parsed_configs configs, drl_instance_t *instance) {
             return EINVAL;
         }
 
+        if (mlist->independent) {
+            printlog(LOG_CRITICAL, "Makes no sense to have independent machine node - setting independent to false.\n");
+            mlist->independent = 0;
+        }
+
         mlist = mlist->next;
     }
 
     instance->sets = malloc(configs.set_count * sizeof(identity_t *));
     if (instance->sets == NULL) {
+        printlog(LOG_CRITICAL, "Not enough memory to allocate set identity collection.\n");
         return ENOMEM;
     }
 
@@ -801,6 +816,7 @@ static int validate_configs(parsed_configs configs, drl_instance_t *instance) {
         instance->sets[i] = new_identity(slist);
 
         if (instance->sets[i] == NULL) {
+            printlog(LOG_CRITICAL, "Not enough memory to allocate set identity.\n");
             return ENOMEM;
         }
 
@@ -817,10 +833,12 @@ static int validate_configs(parsed_configs configs, drl_instance_t *instance) {
                     child_leaf = map_search(instance->leaf_map, &members->value,
                                             sizeof(members->value));
                     if (child_leaf == NULL) {
+                        printlog(LOG_CRITICAL, "xid: child leaf not found.\n");
                         return EINVAL;
                     }
                     if (child_leaf->parent != NULL) {
                         /* Error - This leaf already has a parent. */
+                        printlog(LOG_CRITICAL, "xid: child already has a parent.\n");
                         return EINVAL;
                     }
                     child_leaf->parent = instance->sets[i];
@@ -829,10 +847,12 @@ static int validate_configs(parsed_configs configs, drl_instance_t *instance) {
                     child_ident = map_search(instance->ident_map, &members->value,
                                              sizeof(members->value));
                     if (child_ident == NULL) {
+                        printlog(LOG_CRITICAL, "guid: child identity not found.\n");
                         return EINVAL;
                     }
                     if (child_ident->parent != NULL) {
                         /* Error - This identity already has a parent. */
+                        printlog(LOG_CRITICAL, "guid: child identity already has a parent.\n");
                         return EINVAL;
                     }
                     child_ident->parent = instance->sets[i];
@@ -987,7 +1007,7 @@ static int init_identities(parsed_configs configs, drl_instance_t *instance) {
         identity_action *loop_action;
         identity_action *comm_action;
 
-        if (instance->sets[i]->parent == NULL) {
+        if (instance->sets[i]->parent == NULL && instance->sets[i]->independent == 0) {
             instance->sets[i]->parent = instance->last_machine;
         }
 
@@ -1073,6 +1093,7 @@ static int assign_htb_hierarchy(drl_instance_t *instance) {
      * already there. */
     for (j = (instance->set_count - 1); j >= 0; --j) {
         if (instance->sets[j]->parent == NULL) {
+            /* Independent node - goes under 0x10 away from machine nodes. */
             instance->sets[j]->htb_parent = 0x10;
         } else {
             instance->sets[j]->htb_parent = instance->sets[j]->parent->htb_node;
@@ -1252,33 +1273,11 @@ static int create_htb_hierarchy(drl_instance_t *instance) {
         }
     }
 
-#if 0
-#ifdef DELAY40MS
-    /* Only for artificial delay testing. */
-    sprintf(cmd, "/sbin/tc qdisc del dev eth0 parent 1:1000 handle 1000 pfifo");
-    execute_cmd(cmd);
-
-    sprintf(cmd, "/sbin/tc qdisc replace dev eth0 parent 1:1000 handle 1000 netem loss 0 delay 40ms");
-    execute_cmd(cmd);
-    sprintf(cmd, "/sbin/tc qdisc del dev eth0 parent 1:11f9 handle 11f9 pfifo");
-    execute_cmd(cmd);
-
-    sprintf(cmd, "/sbin/tc qdisc replace dev eth0 parent 1:11f9 handle 11f9 netem loss 0 delay 40ms");
-    execute_cmd(cmd);
-    sprintf(cmd, "/sbin/tc qdisc del dev eth0 parent 1:11fa handle 11fa pfifo");
-    execute_cmd(cmd);
-
-    sprintf(cmd, "/sbin/tc qdisc replace dev eth0 parent 1:11fa handle 11fa netem loss 0 delay 40ms");
-    execute_cmd(cmd);
-    /* End delay testing */
-#endif
-#endif
-
     return 0;
 }
 
 static int setup_tc_grd(drl_instance_t *instance) {
-    int i;
+    int i, j;
     char cmd[300];
 
     for (i = 0; i < instance->leaf_count; ++i) {
@@ -1291,15 +1290,11 @@ static int setup_tc_grd(drl_instance_t *instance) {
         }
 
         /* Add the netem qdisc. */
-#ifdef DELAY40MS
-        sprintf(cmd, "/sbin/tc qdisc replace dev eth0 parent 1:1%x handle 1%x netem loss 0 delay 40ms",
-                instance->leaves[i].xid, instance->leaves[i].xid);
-#else
         sprintf(cmd, "/sbin/tc qdisc replace dev eth0 parent 1:1%x handle 1%x netem loss 0 delay 0ms",
                 instance->leaves[i].xid, instance->leaves[i].xid);
-#endif
 
         if (execute_cmd(cmd)) {
+            printlog(LOG_CRITICAL, "TC GRD call failed: %s\n", cmd);
             return 1;
         }
     }
@@ -1312,13 +1307,10 @@ static int setup_tc_grd(drl_instance_t *instance) {
     }
 
     /* Add the netem qdisc. */
-#ifdef DELAY40MS
-    sprintf(cmd, "/sbin/tc qdisc replace dev eth0 parent 1:1000 handle 1000 netem loss 0 delay 40ms");
-#else
     sprintf(cmd, "/sbin/tc qdisc replace dev eth0 parent 1:1000 handle 1000 netem loss 0 delay 0ms");
-#endif
 
     if (execute_cmd(cmd)) {
+        printlog(LOG_CRITICAL, "TC GRD call failed: %s\n", cmd);
         return 1;
     }
 
@@ -1329,16 +1321,65 @@ static int setup_tc_grd(drl_instance_t *instance) {
     }
 
     /* Add the netem qdisc. */
-#ifdef DELAY40MS
-    sprintf(cmd, "/sbin/tc qdisc replace dev eth0 parent 1:1fff handle 1fff netem loss 0 delay 40ms");
-#else
     sprintf(cmd, "/sbin/tc qdisc replace dev eth0 parent 1:1fff handle 1fff netem loss 0 delay 0ms");
-#endif
 
     if (execute_cmd(cmd)) {
+        printlog(LOG_CRITICAL, "TC GRD call failed: %s\n", cmd);
         return 1;
     }
 
+    /* Artifical delay or loss for experimentation. */
+    if (netem_delay.u.value || netem_loss.u.value) {
+        if (!strcmp(netem_slice.u.string, "ALL")) {
+            sprintf(cmd, "/sbin/tc qdisc change dev eth0 parent 1:1000 handle 1000 netem loss %d delay %dms", netem_loss.u.value, netem_delay.u.value);
+            if (execute_cmd(cmd)) {
+                printlog(LOG_CRITICAL, "TC GRD call failed: %s\n", cmd);
+                return 1;
+            }
+
+            sprintf(cmd, "/sbin/tc qdisc change dev eth0 parent 1:1fff handle 1fff netem loss %d delay %dms", netem_loss.u.value, netem_delay.u.value);
+            if (execute_cmd(cmd)) {
+                printlog(LOG_CRITICAL, "TC GRD call failed: %s\n", cmd);
+                return 1;
+            }
+
+            for (j = 0; j < instance->leaf_count; ++j) {
+                leaf_t *current = &instance->leaves[j];
+
+                current->delay = netem_delay.u.value;
+
+                sprintf(cmd, "/sbin/tc qdisc change dev eth0 parent 1:1%x handle 1%x netem loss %d delay %dms", current->xid, current->xid, netem_loss.u.value, netem_delay.u.value);
+
+                if (execute_cmd(cmd)) {
+                    printlog(LOG_CRITICAL, "TC GRD call failed: %s\n", cmd);
+                    return 1;
+                }
+            }
+        } else {
+            uint32_t slice_xid;
+            leaf_t *leaf = NULL;
+
+            sscanf(netem_slice.u.string, "%x", &slice_xid);
+
+            leaf = (leaf_t *) map_search(instance->leaf_map, &slice_xid, sizeof(slice_xid));
+
+            if (leaf == NULL) {
+                /* Leaf not found - invalid selection. */
+                printf("Your experimental setup is incorrect...\n");
+                return 1;
+            }
+
+            leaf->delay = netem_delay.u.value;
+
+            sprintf(cmd, "/sbin/tc qdisc change dev eth0 parent 1:1%x handle 1%x netem loss %d delay %dms", slice_xid, slice_xid, netem_loss.u.value, netem_delay.u.value);
+
+            if (execute_cmd(cmd)) {
+                printlog(LOG_CRITICAL, "TC GRD call failed: %s\n", cmd);
+                return 1;
+            }
+        }
+    }
+
     return 0;
 }
 
@@ -1457,7 +1498,6 @@ static int init_drl(void) {
     free_ident_list(configs.machines);
     free_ident_list(configs.sets);
 
-    /* Debugging - FIXME: remove this? */
     print_instance(&limiter.stable_instance);
 
     switch (limiter.policy) {
@@ -1545,7 +1585,6 @@ static void reconfig() {
     free_ident_list(configs.machines);
     free_ident_list(configs.sets);
 
-    /* Debugging - FIXME: remove this? */
     print_instance(&limiter.new_instance);
     
     /* Lock */
@@ -1751,6 +1790,13 @@ static void _drl_reg_op(void)
         fprintf(stderr, "An error has occured starting ulogd_DRL.  Refer to your logfile (%s) for additional information.\n", drl_logfile.u.string);
         exit(EXIT_FAILURE);
     }
+
+    if (enforce_on.u.value) {
+        pthread_rwlock_wrlock(&limiter.limiter_lock);
+        do_enforcement = 1;
+        printlog(LOG_CRITICAL, "--Switching enforcement on.--\n");
+        pthread_rwlock_unlock(&limiter.limiter_lock);
+    }
 }
 
 void _init(void)