diff options
| -rw-r--r-- | lib/routemap.h | 10 | ||||
| -rw-r--r-- | lib/table.c | 1 | ||||
| -rw-r--r-- | lib/thread.c | 76 | ||||
| -rw-r--r-- | lib/thread.h | 1 | ||||
| -rw-r--r-- | ospfd/ospf_abr.c | 2 | ||||
| -rw-r--r-- | ospfd/ospf_interface.c | 2 | ||||
| -rw-r--r-- | ospfd/ospf_route.c | 1 | ||||
| -rw-r--r-- | ospfd/ospf_routemap.c | 21 | ||||
| -rw-r--r-- | ripd/rip_routemap.c | 41 | ||||
| -rw-r--r-- | ripngd/ripng_routemap.c | 42 |
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; } |
