diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/command.c | 2 | ||||
-rw-r--r-- | lib/distribute.c | 25 | ||||
-rw-r--r-- | lib/hash.c | 11 | ||||
-rw-r--r-- | lib/hash.h | 2 | ||||
-rw-r--r-- | lib/if.c | 16 | ||||
-rw-r--r-- | lib/if_rmap.c | 12 | ||||
-rw-r--r-- | lib/memory.c | 10 | ||||
-rw-r--r-- | lib/memtypes.c | 1 | ||||
-rw-r--r-- | lib/prefix.c | 15 | ||||
-rw-r--r-- | lib/prefix.h | 20 | ||||
-rw-r--r-- | lib/sockunion.c | 40 | ||||
-rw-r--r-- | lib/sockunion.h | 2 | ||||
-rw-r--r-- | lib/table.c | 14 | ||||
-rw-r--r-- | lib/thread.c | 146 | ||||
-rw-r--r-- | lib/thread.h | 3 | ||||
-rw-r--r-- | lib/vty.c | 3 | ||||
-rw-r--r-- | lib/workqueue.c | 19 | ||||
-rw-r--r-- | lib/zclient.c | 23 |
18 files changed, 265 insertions, 99 deletions
diff --git a/lib/command.c b/lib/command.c index ebb50b40..4f6d184d 100644 --- a/lib/command.c +++ b/lib/command.c @@ -3648,6 +3648,8 @@ cmd_init (int terminal) install_element (VIEW_NODE, &show_thread_cpu_cmd); install_element (ENABLE_NODE, &show_thread_cpu_cmd); install_element (RESTRICTED_NODE, &show_thread_cpu_cmd); + + install_element (ENABLE_NODE, &clear_thread_cpu_cmd); install_element (VIEW_NODE, &show_work_queues_cmd); install_element (ENABLE_NODE, &show_work_queues_cmd); } diff --git a/lib/distribute.c b/lib/distribute.c index 7f84b80e..04889030 100644 --- a/lib/distribute.c +++ b/lib/distribute.c @@ -114,16 +114,11 @@ distribute_get (const char *ifname) } static unsigned int -distribute_hash_make (struct distribute *dist) +distribute_hash_make (void *arg) { - unsigned int i, key; + const struct distribute *dist = arg; - key = 0; - if (dist->ifname) - for (i = 0; i < strlen (dist->ifname); i++) - key += dist->ifname[i]; - - return key; + return dist->ifname ? string_hash_make (dist->ifname) : 0; } /* If two distribute-list have same value then return 1 else return @@ -304,7 +299,6 @@ DEFUN (distribute_list_all, "Filter outgoing routing updates\n") { enum distribute_type type; - struct distribute *dist; /* Check of distribute list type. */ if (strncmp (argv[1], "i", 1) == 0) @@ -319,7 +313,7 @@ DEFUN (distribute_list_all, } /* Get interface name corresponding distribute list. */ - dist = distribute_list_set (NULL, type, argv[0]); + distribute_list_set (NULL, type, argv[0]); return CMD_SUCCESS; } @@ -384,7 +378,6 @@ DEFUN (distribute_list, "Interface name\n") { enum distribute_type type; - struct distribute *dist; /* Check of distribute list type. */ if (strncmp (argv[1], "i", 1) == 0) @@ -398,7 +391,7 @@ DEFUN (distribute_list, } /* Get interface name corresponding distribute list. */ - dist = distribute_list_set (argv[2], type, argv[0]); + distribute_list_set (argv[2], type, argv[0]); return CMD_SUCCESS; } @@ -463,7 +456,6 @@ DEFUN (distribute_list_prefix_all, "Filter outgoing routing updates\n") { enum distribute_type type; - struct distribute *dist; /* Check of distribute list type. */ if (strncmp (argv[1], "i", 1) == 0) @@ -478,7 +470,7 @@ DEFUN (distribute_list_prefix_all, } /* Get interface name corresponding distribute list. */ - dist = distribute_list_prefix_set (NULL, type, argv[0]); + distribute_list_prefix_set (NULL, type, argv[0]); return CMD_SUCCESS; } @@ -546,7 +538,6 @@ DEFUN (distribute_list_prefix, distribute_list_prefix_cmd, "Interface name\n") { enum distribute_type type; - struct distribute *dist; /* Check of distribute list type. */ if (strncmp (argv[1], "i", 1) == 0) @@ -561,7 +552,7 @@ DEFUN (distribute_list_prefix, distribute_list_prefix_cmd, } /* Get interface name corresponding distribute list. */ - dist = distribute_list_prefix_set (argv[2], type, argv[0]); + distribute_list_prefix_set (argv[2], type, argv[0]); return CMD_SUCCESS; } @@ -763,7 +754,7 @@ distribute_list_reset () void distribute_list_init (int node) { - disthash = hash_create ((unsigned int (*) (void *)) distribute_hash_make, + disthash = hash_create (distribute_hash_make, (int (*) (const void *, const void *)) distribute_cmp); if(node==RIP_NODE) { @@ -101,6 +101,17 @@ hash_lookup (struct hash *hash, void *data) return hash_get (hash, data, NULL); } +/* Simple Bernstein hash which is simple and fast for common case */ +unsigned int string_hash_make (const char *str) +{ + unsigned int hash = 0; + + while (*str) + hash = (hash * 33) ^ (unsigned int) *str++; + + return hash; +} + /* This function release registered value from specified hash. When release is successfully finished, return the data pointer in the hash backet. */ @@ -70,4 +70,6 @@ extern void hash_iterate (struct hash *, extern void hash_clean (struct hash *, void (*) (void *)); extern void hash_free (struct hash *); +extern unsigned int string_hash_make (const char *); + #endif /* _ZEBRA_HASH_H */ @@ -426,16 +426,20 @@ if_flag_dump (unsigned long flag) static void if_dump (const struct interface *ifp) { - zlog_info ("Interface %s index %d metric %d mtu %d " + struct listnode *node; + struct connected *c; + + for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, c)) + zlog_info ("Interface %s index %d metric %d mtu %d " #ifdef HAVE_IPV6 - "mtu6 %d " + "mtu6 %d " #endif /* HAVE_IPV6 */ - "%s", - ifp->name, ifp->ifindex, ifp->metric, ifp->mtu, + "%s", + ifp->name, ifp->ifindex, ifp->metric, ifp->mtu, #ifdef HAVE_IPV6 - ifp->mtu6, + ifp->mtu6, #endif /* HAVE_IPV6 */ - if_flag_dump (ifp->flags)); + if_flag_dump (ifp->flags)); } /* Interface printing for all interface. */ diff --git a/lib/if_rmap.c b/lib/if_rmap.c index ddc62fd5..7d049b87 100644 --- a/lib/if_rmap.c +++ b/lib/if_rmap.c @@ -109,14 +109,9 @@ if_rmap_get (const char *ifname) static unsigned int if_rmap_hash_make (void *data) { - struct if_rmap *if_rmap = data; - unsigned int i, key; + const struct if_rmap *if_rmap = data; - key = 0; - for (i = 0; i < strlen (if_rmap->ifname); i++) - key += if_rmap->ifname[i]; - - return key; + return string_hash_make (if_rmap->ifname); } static int @@ -212,7 +207,6 @@ DEFUN (if_rmap, "Route map interface name\n") { enum if_rmap_type type; - struct if_rmap *if_rmap; if (strncmp (argv[1], "i", 1) == 0) type = IF_RMAP_IN; @@ -224,7 +218,7 @@ DEFUN (if_rmap, return CMD_WARNING; } - if_rmap = if_rmap_set (argv[2], type, argv[0]); + if_rmap_set (argv[2], type, argv[0]); return CMD_SUCCESS; } diff --git a/lib/memory.c b/lib/memory.c index 4bac31db..4090fd90 100644 --- a/lib/memory.c +++ b/lib/memory.c @@ -111,6 +111,9 @@ zrealloc (int type, void *ptr, size_t size) memory = realloc (ptr, size); if (memory == NULL) zerror ("realloc", type, size); + if (ptr == NULL) + alloc_inc (type); + return memory; } @@ -123,8 +126,11 @@ zrealloc (int type, void *ptr, size_t size) void zfree (int type, void *ptr) { - alloc_dec (type); - free (ptr); + if (ptr != NULL) + { + alloc_dec (type); + free (ptr); + } } /* diff --git a/lib/memtypes.c b/lib/memtypes.c index d0ce8c5e..d2bc1c62 100644 --- a/lib/memtypes.c +++ b/lib/memtypes.c @@ -106,6 +106,7 @@ struct memory_list memory_list_bgp[] = { MTYPE_BGP_NODE, "BGP node" }, { MTYPE_BGP_ROUTE, "BGP route" }, { MTYPE_BGP_ROUTE_EXTRA, "BGP ancillary route info" }, + { MTYPE_BGP_CONN, "BGP connected" }, { MTYPE_BGP_STATIC, "BGP static" }, { MTYPE_BGP_ADVERTISE_ATTR, "BGP adv attr" }, { MTYPE_BGP_ADVERTISE, "BGP adv" }, diff --git a/lib/prefix.c b/lib/prefix.c index ceda08de..5e8cff04 100644 --- a/lib/prefix.c +++ b/lib/prefix.c @@ -2317,6 +2317,21 @@ static const char map64kto17_nbo[0xffff + 1] = #define MASKBIT(offset) ((0xff << (PNBBY - (offset))) & 0xff) +unsigned int +prefix_bit (const u_char *prefix, const u_char prefixlen) +{ + unsigned int offset = prefixlen / 8; + unsigned int shift = 7 - (prefixlen % 8); + + return (prefix[offset] >> shift) & 1; +} + +unsigned int +prefix6_bit (const struct in6_addr *prefix, const u_char prefixlen) +{ + return prefix_bit((const u_char *) &prefix->s6_addr, prefixlen); +} + /* Address Famiy Identifier to Address Family converter. */ int afi2family (afi_t afi) diff --git a/lib/prefix.h b/lib/prefix.h index dab4202e..7f0d3607 100644 --- a/lib/prefix.h +++ b/lib/prefix.h @@ -128,26 +128,14 @@ struct prefix_rd /* Prefix's family member. */ #define PREFIX_FAMILY(p) ((p)->family) -/* Check bit of the prefix. */ -static inline unsigned int -prefix_bit (const u_char *prefix, const u_char prefixlen) -{ - unsigned int offset = prefixlen / 8; - unsigned int shift = 7 - (prefixlen % 8); - - return (prefix[offset] >> shift) & 1; -} - -static inline unsigned int -prefix6_bit (const struct in6_addr *prefix, const u_char prefixlen) -{ - return prefix_bit((const u_char *) &prefix->s6_addr, prefixlen); -} - /* Prototypes. */ extern int afi2family (afi_t); extern afi_t family2afi (int); +/* Check bit of the prefix. */ +extern unsigned int prefix_bit (const u_char *prefix, const u_char prefixlen); +extern unsigned int prefix6_bit (const struct in6_addr *prefix, const u_char prefixlen); + extern struct prefix *prefix_new (void); extern void prefix_free (struct prefix *); extern const char *prefix_family_str (const struct prefix *); diff --git a/lib/sockunion.c b/lib/sockunion.c index 10224a05..59770529 100644 --- a/lib/sockunion.c +++ b/lib/sockunion.c @@ -527,6 +527,46 @@ sockopt_ttl (int family, int sock, int ttl) } int +sockopt_cork (int sock, int onoff) +{ +#ifdef TCP_CORK + return setsockopt (sock, IPPROTO_TCP, TCP_CORK, &onoff, sizeof(onoff)); +#else + return 0; +#endif +} + +int +sockopt_minttl (int family, int sock, int minttl) +{ +#ifdef IP_MINTTL + if (family == AF_INET) + { + int ret = setsockopt (sock, IPPROTO_IP, IP_MINTTL, &minttl, sizeof(minttl)); + if (ret < 0) + zlog (NULL, LOG_WARNING, + "can't set sockopt IP_MINTTL to %d on socket %d: %s", + minttl, sock, safe_strerror (errno)); + return ret; + } +#endif /* IP_MINTTL */ +#ifdef IPV6_MINHOPCNT + if (family == AF_INET6) + { + int ret = setsockopt (sock, IPPROTO_IPV6, IPV6_MINHOPCNT, &minttl, sizeof(minttl)); + if (ret < 0) + zlog (NULL, LOG_WARNING, + "can't set sockopt IPV6_MINHOPCNT to %d on socket %d: %s", + minttl, sock, safe_strerror (errno)); + return ret; + } +#endif + + errno = EOPNOTSUPP; + return -1; +} + +int sockopt_v6only (int family, int sock) { int ret, on = 1; diff --git a/lib/sockunion.h b/lib/sockunion.h index db145cf2..4531f620 100644 --- a/lib/sockunion.h +++ b/lib/sockunion.h @@ -103,6 +103,8 @@ extern int sockopt_v6only (int family, int sock); extern int sockunion_bind (int sock, union sockunion *, unsigned short, union sockunion *); extern int sockopt_ttl (int family, int sock, int ttl); +extern int sockopt_minttl (int family, int sock, int minttl); +extern int sockopt_cork (int sock, int onoff); extern int sockunion_socket (union sockunion *su); extern const char *inet_sutop (union sockunion *su, char *str); extern enum connect_result sockunion_connect (int fd, union sockunion *su, diff --git a/lib/table.c b/lib/table.c index 04df3af5..e40e6707 100644 --- a/lib/table.c +++ b/lib/table.c @@ -209,6 +209,10 @@ route_node_match (const struct route_table *table, const struct prefix *p) { if (node->info) matched = node; + + if (node->p.prefixlen == p->prefixlen) + break; + node = node->link[prefix_bit(&p->u.prefix, node->p.prefixlen)]; } @@ -260,8 +264,8 @@ route_node_lookup (struct route_table *table, struct prefix *p) while (node && node->p.prefixlen <= p->prefixlen && prefix_match (&node->p, p)) { - if (node->p.prefixlen == p->prefixlen && node->info) - return route_lock_node (node); + if (node->p.prefixlen == p->prefixlen) + return node->info ? route_lock_node (node) : NULL; node = node->link[prefix_bit(&p->u.prefix, node->p.prefixlen)]; } @@ -283,10 +287,8 @@ route_node_get (struct route_table *table, struct prefix *p) prefix_match (&node->p, p)) { if (node->p.prefixlen == p->prefixlen) - { - route_lock_node (node); - return node; - } + return route_lock_node (node); + match = node; node = node->link[prefix_bit(&p->u.prefix, node->p.prefixlen)]; } diff --git a/lib/thread.c b/lib/thread.c index e89af541..6d3c3cb3 100644 --- a/lib/thread.c +++ b/lib/thread.c @@ -248,7 +248,7 @@ cpu_record_hash_free (void *a) XFREE (MTYPE_THREAD_STATS, hist); } -static inline void +static void vty_out_cpu_thread_history(struct vty* vty, struct cpu_thread_history *a) { @@ -303,7 +303,7 @@ cpu_record_print(struct vty *vty, thread_type filter) void *args[3] = {&tmp, vty, &filter}; memset(&tmp, 0, sizeof tmp); - tmp.funcname = "TOTAL"; + tmp.funcname = (char *)"TOTAL"; tmp.types = filter; #ifdef HAVE_RUSAGE @@ -382,6 +382,89 @@ DEFUN(show_thread_cpu, cpu_record_print(vty, filter); return CMD_SUCCESS; } + +static void +cpu_record_hash_clear (struct hash_backet *bucket, + void *args) +{ + thread_type *filter = args; + struct cpu_thread_history *a = bucket->data; + + a = bucket->data; + if ( !(a->types & *filter) ) + return; + + hash_release (cpu_record, bucket->data); +} + +static void +cpu_record_clear (thread_type filter) +{ + thread_type *tmp = &filter; + hash_iterate (cpu_record, + (void (*) (struct hash_backet*,void*)) cpu_record_hash_clear, + tmp); +} + +DEFUN(clear_thread_cpu, + clear_thread_cpu_cmd, + "clear thread cpu [FILTER]", + "Clear stored data\n" + "Thread information\n" + "Thread CPU usage\n" + "Display filter (rwtexb)\n") +{ + int i = 0; + thread_type filter = (thread_type) -1U; + + if (argc > 0) + { + filter = 0; + while (argv[0][i] != '\0') + { + switch ( argv[0][i] ) + { + case 'r': + case 'R': + filter |= (1 << THREAD_READ); + break; + case 'w': + case 'W': + filter |= (1 << THREAD_WRITE); + break; + case 't': + case 'T': + filter |= (1 << THREAD_TIMER); + break; + case 'e': + case 'E': + filter |= (1 << THREAD_EVENT); + break; + case 'x': + case 'X': + filter |= (1 << THREAD_EXECUTE); + break; + case 'b': + case 'B': + filter |= (1 << THREAD_BACKGROUND); + break; + default: + break; + } + ++i; + } + if (filter == 0) + { + vty_out(vty, "Invalid filter \"%s\" specified," + " must contain at least one of 'RWTEXB'%s", + argv[0], VTY_NEWLINE); + return CMD_WARNING; + } + } + + cpu_record_clear (filter); + return CMD_SUCCESS; +} /* List allocation and head/tail print out. */ static void @@ -525,7 +608,7 @@ thread_master_free (struct thread_master *m) } /* Thread list is empty or not. */ -static inline int +static int thread_empty (struct thread_list *list) { return list->head ? 0 : 1; @@ -903,6 +986,24 @@ thread_timer_process (struct thread_list *list, struct timeval *timenow) return ready; } +/* process a list en masse, e.g. for event thread lists */ +static unsigned int +thread_process (struct thread_list *list) +{ + struct thread *thread; + unsigned int ready = 0; + + for (thread = list->head; thread; thread = thread->next) + { + thread_list_delete (list, thread); + thread->type = THREAD_READY; + thread_list_add (&thread->master->ready, thread); + ready++; + } + return ready; +} + + /* Fetch next ready thread. */ struct thread * thread_fetch (struct thread_master *m, struct thread *fetch) @@ -911,41 +1012,48 @@ thread_fetch (struct thread_master *m, struct thread *fetch) fd_set readfd; fd_set writefd; fd_set exceptfd; - struct timeval timer_val; + struct timeval timer_val = { .tv_sec = 0, .tv_usec = 0 }; struct timeval timer_val_bg; - struct timeval *timer_wait; + struct timeval *timer_wait = &timer_val; struct timeval *timer_wait_bg; while (1) { int num = 0; - /* Signals are highest priority */ + /* Signals pre-empt everything */ quagga_sigevent_process (); - /* Normal event are the next highest priority. */ - if ((thread = thread_trim_head (&m->event)) != NULL) - return thread_run (m, thread, fetch); - - /* If there are any ready threads from previous scheduler runs, - * process top of them. + /* Drain the ready queue of already scheduled jobs, before scheduling + * more. */ if ((thread = thread_trim_head (&m->ready)) != NULL) return thread_run (m, thread, fetch); + /* To be fair to all kinds of threads, and avoid starvation, we + * need to be careful to consider all thread types for scheduling + * in each quanta. I.e. we should not return early from here on. + */ + + /* Normal event are the next highest priority. */ + thread_process (&m->event); + /* Structure copy. */ readfd = m->readfd; writefd = m->writefd; exceptfd = m->exceptfd; /* Calculate select wait timer if nothing else to do */ - quagga_get_relative (NULL); - timer_wait = thread_timer_wait (&m->timer, &timer_val); - timer_wait_bg = thread_timer_wait (&m->background, &timer_val_bg); - - if (timer_wait_bg && - (!timer_wait || (timeval_cmp (*timer_wait, *timer_wait_bg) > 0))) - timer_wait = timer_wait_bg; + if (m->ready.count == 0) + { + quagga_get_relative (NULL); + timer_wait = thread_timer_wait (&m->timer, &timer_val); + timer_wait_bg = thread_timer_wait (&m->background, &timer_val_bg); + + if (timer_wait_bg && + (!timer_wait || (timeval_cmp (*timer_wait, *timer_wait_bg) > 0))) + timer_wait = timer_wait_bg; + } num = select (FD_SETSIZE, &readfd, &writefd, &exceptfd, timer_wait); diff --git a/lib/thread.h b/lib/thread.h index b52bc541..978aa6b0 100644 --- a/lib/thread.h +++ b/lib/thread.h @@ -82,7 +82,7 @@ struct thread struct cpu_thread_history { int (*func)(struct thread *); - const char *funcname; + char *funcname; unsigned int total_calls; struct time_stats { @@ -197,6 +197,7 @@ extern int thread_should_yield (struct thread *); /* Internal libzebra exports */ extern void thread_getrusage (RUSAGE_T *); extern struct cmd_element show_thread_cpu_cmd; +extern struct cmd_element clear_thread_cpu_cmd; /* replacements for the system gettimeofday(), clock_gettime() and * time() functions, providing support for non-decrementing clock on @@ -1685,7 +1685,6 @@ static int vty_accept (struct thread *thread) { int vty_sock; - struct vty *vty; union sockunion su; int ret; unsigned int on; @@ -1770,7 +1769,7 @@ vty_accept (struct thread *thread) if (bufp) XFREE (MTYPE_TMP, bufp); - vty = vty_create (vty_sock, &su); + vty_create (vty_sock, &su); return 0; } diff --git a/lib/workqueue.c b/lib/workqueue.c index 7c811edd..61643bf8 100644 --- a/lib/workqueue.c +++ b/lib/workqueue.c @@ -103,7 +103,7 @@ work_queue_free (struct work_queue *wq) return; } -static inline int +static int work_queue_schedule (struct work_queue *wq, unsigned int delay) { /* if appropriate, schedule work queue thread */ @@ -341,7 +341,7 @@ work_queue_run (struct thread *thread) stats: -#define WQ_HYSTERIS_FACTOR 2 +#define WQ_HYSTERESIS_FACTOR 4 /* we yielded, check whether granularity should be reduced */ if (yielded && (cycles < wq->cycles.granularity)) @@ -349,17 +349,18 @@ stats: wq->cycles.granularity = ((cycles > 0) ? cycles : WORK_QUEUE_MIN_GRANULARITY); } - - if (cycles >= (wq->cycles.granularity)) + /* otherwise, should granularity increase? */ + else if (cycles >= (wq->cycles.granularity)) { if (cycles > wq->cycles.best) wq->cycles.best = cycles; - /* along with yielded check, provides hysteris for granularity */ - if (cycles > (wq->cycles.granularity * WQ_HYSTERIS_FACTOR * 2)) - wq->cycles.granularity *= WQ_HYSTERIS_FACTOR; /* quick ramp-up */ - else if (cycles > (wq->cycles.granularity * WQ_HYSTERIS_FACTOR)) - wq->cycles.granularity += WQ_HYSTERIS_FACTOR; + /* along with yielded check, provides hysteresis for granularity */ + if (cycles > (wq->cycles.granularity * WQ_HYSTERESIS_FACTOR + * WQ_HYSTERESIS_FACTOR)) + wq->cycles.granularity *= WQ_HYSTERESIS_FACTOR; /* quick ramp-up */ + else if (cycles > (wq->cycles.granularity * WQ_HYSTERESIS_FACTOR)) + wq->cycles.granularity += WQ_HYSTERESIS_FACTOR; } #undef WQ_HYSTERIS_FACTOR diff --git a/lib/zclient.c b/lib/zclient.c index 37ee2420..12d113e7 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -837,7 +837,6 @@ zebra_interface_address_read (int type, struct stream *s) static int zclient_read (struct thread *thread) { - int ret; size_t already; uint16_t length, command; uint8_t marker, version; @@ -932,47 +931,47 @@ zclient_read (struct thread *thread) { case ZEBRA_ROUTER_ID_UPDATE: if (zclient->router_id_update) - ret = (*zclient->router_id_update) (command, zclient, length); + (*zclient->router_id_update) (command, zclient, length); break; case ZEBRA_INTERFACE_ADD: if (zclient->interface_add) - ret = (*zclient->interface_add) (command, zclient, length); + (*zclient->interface_add) (command, zclient, length); break; case ZEBRA_INTERFACE_DELETE: if (zclient->interface_delete) - ret = (*zclient->interface_delete) (command, zclient, length); + (*zclient->interface_delete) (command, zclient, length); break; case ZEBRA_INTERFACE_ADDRESS_ADD: if (zclient->interface_address_add) - ret = (*zclient->interface_address_add) (command, zclient, length); + (*zclient->interface_address_add) (command, zclient, length); break; case ZEBRA_INTERFACE_ADDRESS_DELETE: if (zclient->interface_address_delete) - ret = (*zclient->interface_address_delete) (command, zclient, length); + (*zclient->interface_address_delete) (command, zclient, length); break; case ZEBRA_INTERFACE_UP: if (zclient->interface_up) - ret = (*zclient->interface_up) (command, zclient, length); + (*zclient->interface_up) (command, zclient, length); break; case ZEBRA_INTERFACE_DOWN: if (zclient->interface_down) - ret = (*zclient->interface_down) (command, zclient, length); + (*zclient->interface_down) (command, zclient, length); break; case ZEBRA_IPV4_ROUTE_ADD: if (zclient->ipv4_route_add) - ret = (*zclient->ipv4_route_add) (command, zclient, length); + (*zclient->ipv4_route_add) (command, zclient, length); break; case ZEBRA_IPV4_ROUTE_DELETE: if (zclient->ipv4_route_delete) - ret = (*zclient->ipv4_route_delete) (command, zclient, length); + (*zclient->ipv4_route_delete) (command, zclient, length); break; case ZEBRA_IPV6_ROUTE_ADD: if (zclient->ipv6_route_add) - ret = (*zclient->ipv6_route_add) (command, zclient, length); + (*zclient->ipv6_route_add) (command, zclient, length); break; case ZEBRA_IPV6_ROUTE_DELETE: if (zclient->ipv6_route_delete) - ret = (*zclient->ipv6_route_delete) (command, zclient, length); + (*zclient->ipv6_route_delete) (command, zclient, length); break; default: break; |