summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/routemap.h10
-rw-r--r--lib/table.c1
-rw-r--r--lib/thread.c76
-rw-r--r--lib/thread.h1
-rw-r--r--ospfd/ospf_abr.c2
-rw-r--r--ospfd/ospf_interface.c2
-rw-r--r--ospfd/ospf_route.c1
-rw-r--r--ospfd/ospf_routemap.c21
-rw-r--r--ripd/rip_routemap.c41
-rw-r--r--ripngd/ripng_routemap.c42
10 files changed, 110 insertions, 87 deletions
diff --git a/lib/routemap.h b/lib/routemap.h
index b166de1e09..8c00e8104c 100644
--- a/lib/routemap.h
+++ b/lib/routemap.h
@@ -194,7 +194,15 @@ extern int route_map_delete_set(struct route_map_index *index,
/* Install rule command to the match list. */
extern void route_map_install_match(struct route_map_rule_cmd *cmd);
-/* Install rule command to the set list. */
+/*
+ * Install rule command to the set list.
+ *
+ * When installing a particular item, Allow a difference of handling
+ * of bad cli inputted(return NULL) -vs- this particular daemon cannot use
+ * this form of the command(return a pointer and handle it appropriately
+ * in the apply command). See 'set metric' command
+ * as it is handled in ripd/ripngd and ospfd.
+ */
extern void route_map_install_set(struct route_map_rule_cmd *cmd);
/* Lookup route map by name. */
diff --git a/lib/table.c b/lib/table.c
index 67cf6aeec3..b0b0d24ea0 100644
--- a/lib/table.c
+++ b/lib/table.c
@@ -281,6 +281,7 @@ struct route_node *route_node_get(struct route_table *const table,
u_char prefixlen = p->prefixlen;
const u_char *prefix = &p->u.prefix;
+ apply_mask((struct prefix *)p);
node = hash_get(table->hash, (void *)p, NULL);
if (node && node->info)
return route_lock_node(node);
diff --git a/lib/thread.c b/lib/thread.c
index 4a5c61d036..b39f2d55c2 100644
--- a/lib/thread.c
+++ b/lib/thread.c
@@ -47,9 +47,6 @@ DEFINE_MTYPE_STATIC(LIB, THREAD_STATS, "Thread stats")
write(m->io_pipe[1], &wakebyte, 1); \
} while (0);
-/* max # of thread_fetch() calls before we force a poll() */
-#define MAX_TICK_IO 1000
-
/* control variable for initializer */
pthread_once_t init_once = PTHREAD_ONCE_INIT;
pthread_key_t thread_current;
@@ -552,7 +549,7 @@ void thread_master_free(struct thread_master *m)
{
listnode_delete(masters, m);
if (masters->count == 0) {
- list_free (masters);
+ list_free(masters);
masters = NULL;
}
}
@@ -1320,6 +1317,20 @@ struct thread *thread_fetch(struct thread_master *m, struct thread *fetch)
do_thread_cancel(m);
/*
+ * Attempt to flush ready queue before going into poll().
+ * This is performance-critical. Think twice before modifying.
+ */
+ if ((thread = thread_trim_head(&m->ready))) {
+ fetch = thread_run(m, thread, fetch);
+ if (fetch->ref)
+ *fetch->ref = NULL;
+ pthread_mutex_unlock(&m->mtx);
+ break;
+ }
+
+ /* otherwise, tick through scheduling sequence */
+
+ /*
* Post events to ready queue. This must come before the
* following block since events should occur immediately
*/
@@ -1362,44 +1373,26 @@ struct thread *thread_fetch(struct thread_master *m, struct thread *fetch)
memcpy(m->handler.copy, m->handler.pfds,
m->handler.copycount * sizeof(struct pollfd));
- /*
- * Attempt to flush ready queue before going into poll().
- * This is performance-critical. Think twice before modifying.
- */
- if (m->ready.count == 0 || m->tick_since_io >= MAX_TICK_IO) {
- pthread_mutex_unlock(&m->mtx);
- {
- m->tick_since_io = 0;
- num = fd_poll(m, m->handler.copy,
- m->handler.pfdsize,
- m->handler.copycount, tw);
- }
- pthread_mutex_lock(&m->mtx);
-
- /* Handle any errors received in poll() */
- if (num < 0) {
- if (errno == EINTR) {
- pthread_mutex_unlock(&m->mtx);
- /* loop around to signal handler */
- continue;
- }
+ pthread_mutex_unlock(&m->mtx);
+ {
+ num = fd_poll(m, m->handler.copy, m->handler.pfdsize,
+ m->handler.copycount, tw);
+ }
+ pthread_mutex_lock(&m->mtx);
- /* else die */
- zlog_warn("poll() error: %s",
- safe_strerror(errno));
+ /* Handle any errors received in poll() */
+ if (num < 0) {
+ if (errno == EINTR) {
pthread_mutex_unlock(&m->mtx);
- fetch = NULL;
- break;
+ /* loop around to signal handler */
+ continue;
}
- /*
- * Since we could have received more cancellation
- * requests during poll(), process those
- */
- do_thread_cancel(m);
-
- } else {
- m->tick_since_io++;
+ /* else die */
+ zlog_warn("poll() error: %s", safe_strerror(errno));
+ pthread_mutex_unlock(&m->mtx);
+ fetch = NULL;
+ break;
}
/* Post timers to ready queue. */
@@ -1410,13 +1403,6 @@ struct thread *thread_fetch(struct thread_master *m, struct thread *fetch)
if (num > 0)
thread_process_io(m, num);
- /* have a ready task ==> return it to caller */
- if ((thread = thread_trim_head(&m->ready))) {
- fetch = thread_run(m, thread, fetch);
- if (fetch->ref)
- *fetch->ref = NULL;
- }
-
pthread_mutex_unlock(&m->mtx);
} while (!thread && m->spin);
diff --git a/lib/thread.h b/lib/thread.h
index 86bf4df7c0..c830446e10 100644
--- a/lib/thread.h
+++ b/lib/thread.h
@@ -70,7 +70,6 @@ struct cancel_req {
struct thread_master {
char *name;
- int tick_since_io;
struct thread **read;
struct thread **write;
struct pqueue *timer;
diff --git a/ospfd/ospf_abr.c b/ospfd/ospf_abr.c
index c6d4364fa3..968461b4d0 100644
--- a/ospfd/ospf_abr.c
+++ b/ospfd/ospf_abr.c
@@ -76,6 +76,7 @@ static void ospf_area_range_add(struct ospf_area *area,
p.family = AF_INET;
p.prefixlen = range->masklen;
p.prefix = range->addr;
+ apply_mask_ipv4(&p);
rn = route_node_get(area->ranges, (struct prefix *)&p);
if (rn->info)
@@ -123,6 +124,7 @@ struct ospf_area_range *ospf_area_range_lookup_next(struct ospf_area *area,
p.family = AF_INET;
p.prefixlen = IPV4_MAX_BITLEN;
p.prefix = *range_net;
+ apply_mask_ipv4(&p);
if (first)
rn = route_top(area->ranges);
diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c
index 54639afd6c..422e1a2a6b 100644
--- a/ospfd/ospf_interface.c
+++ b/ospfd/ospf_interface.c
@@ -171,6 +171,7 @@ static void ospf_add_to_if(struct interface *ifp, struct ospf_interface *oi)
p = *oi->address;
p.prefixlen = IPV4_MAX_PREFIXLEN;
+ apply_mask(&p);
rn = route_node_get(IF_OIFS(ifp), &p);
/* rn->info should either be NULL or equal to this oi
@@ -562,6 +563,7 @@ struct ospf_if_params *ospf_get_if_params(struct interface *ifp,
p.family = AF_INET;
p.prefixlen = IPV4_MAX_PREFIXLEN;
p.prefix = addr;
+ apply_mask_ipv4(&p);
rn = route_node_get(IF_OIFS_PARAMS(ifp), (struct prefix *)&p);
diff --git a/ospfd/ospf_route.c b/ospfd/ospf_route.c
index 9c4dca2e2f..89ea331b52 100644
--- a/ospfd/ospf_route.c
+++ b/ospfd/ospf_route.c
@@ -356,6 +356,7 @@ void ospf_intra_add_router(struct route_table *rt, struct vertex *v,
p.family = AF_INET;
p.prefix = v->id;
p.prefixlen = IPV4_MAX_BITLEN;
+ apply_mask_ipv4(&p);
if (IS_DEBUG_OSPF_EVENT)
zlog_debug("ospf_intra_add_router: talking about %s/%d",
diff --git a/ospfd/ospf_routemap.c b/ospfd/ospf_routemap.c
index 547e1e8f53..f47e2b6f1e 100644
--- a/ospfd/ospf_routemap.c
+++ b/ospfd/ospf_routemap.c
@@ -336,6 +336,10 @@ static struct route_map_rule_cmd route_match_tag_cmd = {
route_map_rule_tag_free,
};
+struct ospf_metric {
+ bool used;
+ u_int32_t metric;
+};
/* `set metric METRIC' */
/* Set metric to attribute. */
@@ -343,7 +347,7 @@ static route_map_result_t route_set_metric(void *rule, struct prefix *prefix,
route_map_object_t type,
void *object)
{
- u_int32_t *metric;
+ struct ospf_metric *metric;
struct external_info *ei;
if (type == RMAP_OSPF) {
@@ -352,7 +356,8 @@ static route_map_result_t route_set_metric(void *rule, struct prefix *prefix,
ei = object;
/* Set metric out value. */
- ei->route_map_set.metric = *metric;
+ if (metric->used)
+ ei->route_map_set.metric = metric->metric;
}
return RMAP_OKAY;
}
@@ -360,7 +365,10 @@ static route_map_result_t route_set_metric(void *rule, struct prefix *prefix,
/* set metric compilation. */
static void *route_set_metric_compile(const char *arg)
{
- u_int32_t *metric;
+ struct ospf_metric *metric;
+
+ metric = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(u_int32_t));
+ metric->used = false;
/* OSPF doesn't support the +/- in
set metric <+/-metric> check
@@ -373,11 +381,12 @@ static void *route_set_metric_compile(const char *arg)
if (strmatch(arg, "+rtt") || strmatch(arg, "-rtt"))
zlog_warn(
"OSPF does not support 'set metric +rtt / -rtt'");
- return NULL;
+
+ return metric;
}
}
- metric = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(u_int32_t));
- *metric = strtoul(arg, NULL, 10);
+ metric->metric = strtoul(arg, NULL, 10);
+ metric->used = true;
return metric;
}
diff --git a/ripd/rip_routemap.c b/ripd/rip_routemap.c
index 7255df5e67..7d39023b38 100644
--- a/ripd/rip_routemap.c
+++ b/ripd/rip_routemap.c
@@ -36,8 +36,8 @@
struct rip_metric_modifier {
enum { metric_increment, metric_decrement, metric_absolute } type;
-
- u_char metric;
+ bool used;
+ u_int8_t metric;
};
/* Hook function for updating route_map assignment. */
@@ -365,6 +365,9 @@ static route_map_result_t route_set_metric(void *rule, struct prefix *prefix,
mod = rule;
rinfo = object;
+ if (!mod->used)
+ return RMAP_OKAY;
+
if (mod->type == metric_increment)
rinfo->metric_out += mod->metric;
else if (mod->type == metric_decrement)
@@ -387,43 +390,49 @@ static void *route_set_metric_compile(const char *arg)
{
int len;
const char *pnt;
- int type;
long metric;
char *endptr = NULL;
struct rip_metric_modifier *mod;
+ mod = XMALLOC(MTYPE_ROUTE_MAP_COMPILED,
+ sizeof(struct rip_metric_modifier));
+ mod->used = false;
+
len = strlen(arg);
pnt = arg;
if (len == 0)
- return NULL;
+ return mod;
/* Examine first character. */
if (arg[0] == '+') {
- type = metric_increment;
+ mod->type = metric_increment;
pnt++;
} else if (arg[0] == '-') {
- type = metric_decrement;
+ mod->type = metric_decrement;
pnt++;
} else
- type = metric_absolute;
+ mod->type = metric_absolute;
/* Check beginning with digit string. */
if (*pnt < '0' || *pnt > '9')
- return NULL;
+ return mod;
/* Convert string to integer. */
metric = strtol(pnt, &endptr, 10);
- if (metric == LONG_MAX || *endptr != '\0')
- return NULL;
- if (metric < 0 || metric > RIP_METRIC_INFINITY)
- return NULL;
+ if (*endptr != '\0' || mod->metric < 0) {
+ metric = 0;
+ return mod;
+ }
+ if (metric > RIP_METRIC_INFINITY) {
+ zlog_info("%s: Metric specified: %ld is greater than RIP_METRIC_INFINITY, using INFINITY instead",
+ __PRETTY_FUNCTION__, metric);
+ mod->metric = RIP_METRIC_INFINITY;
+ } else
+ mod->metric = metric;
- mod = XMALLOC(MTYPE_ROUTE_MAP_COMPILED,
- sizeof(struct rip_metric_modifier));
- mod->type = type;
- mod->metric = metric;
+ mod->used = true;
return mod;
}
diff --git a/ripngd/ripng_routemap.c b/ripngd/ripng_routemap.c
index 3080801fb3..e518585c74 100644
--- a/ripngd/ripng_routemap.c
+++ b/ripngd/ripng_routemap.c
@@ -32,8 +32,8 @@
struct rip_metric_modifier {
enum { metric_increment, metric_decrement, metric_absolute } type;
-
- u_char metric;
+ bool used;
+ u_int8_t metric;
};
/* `match metric METRIC' */
@@ -168,6 +168,9 @@ static route_map_result_t route_set_metric(void *rule, struct prefix *prefix,
mod = rule;
rinfo = object;
+ if (!mod->used)
+ return RMAP_OKAY;
+
if (mod->type == metric_increment)
rinfo->metric_out += mod->metric;
else if (mod->type == metric_decrement)
@@ -190,7 +193,6 @@ static void *route_set_metric_compile(const char *arg)
{
int len;
const char *pnt;
- int type;
long metric;
char *endptr = NULL;
struct rip_metric_modifier *mod;
@@ -198,38 +200,42 @@ static void *route_set_metric_compile(const char *arg)
len = strlen(arg);
pnt = arg;
+ mod = XMALLOC(MTYPE_ROUTE_MAP_COMPILED,
+ sizeof(struct rip_metric_modifier));
+ mod->used = false;
+
if (len == 0)
- return NULL;
+ return mod;
/* Examine first character. */
if (arg[0] == '+') {
- type = metric_increment;
+ mod->type = metric_increment;
pnt++;
} else if (arg[0] == '-') {
- type = metric_decrement;
+ mod->type = metric_decrement;
pnt++;
} else
- type = metric_absolute;
+ mod->type = metric_absolute;
/* Check beginning with digit string. */
if (*pnt < '0' || *pnt > '9')
- return NULL;
+ return mod;
/* Convert string to integer. */
metric = strtol(pnt, &endptr, 10);
- if (metric == LONG_MAX || *endptr != '\0')
- return NULL;
- /* Commented out by Hasso Tepper, to avoid problems in vtysh. */
- /* if (metric < 0 || metric > RIPNG_METRIC_INFINITY) */
- if (metric < 0)
- return NULL;
+ if (*endptr != '\0' || metric < 0)
+ return mod;
- mod = XMALLOC(MTYPE_ROUTE_MAP_COMPILED,
- sizeof(struct rip_metric_modifier));
- mod->type = type;
- mod->metric = metric;
+ if (metric > RIPNG_METRIC_INFINITY) {
+ zlog_info("%s: Metric specified: %ld is being converted into METRIC_INFINITY",
+ __PRETTY_FUNCTION__,
+ metric);
+ mod->metric = RIPNG_METRIC_INFINITY;
+ } else
+ mod->metric = metric;
+ mod->used = true;
return mod;
}