diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/command.c | 4 | ||||
| -rw-r--r-- | lib/log.c | 1 | ||||
| -rw-r--r-- | lib/network.c | 9 | ||||
| -rw-r--r-- | lib/wheel.h | 50 | ||||
| -rw-r--r-- | lib/zebra.h | 25 |
5 files changed, 78 insertions, 11 deletions
diff --git a/lib/command.c b/lib/command.c index 6294e994e7..b5dae5f28e 100644 --- a/lib/command.c +++ b/lib/command.c @@ -541,8 +541,12 @@ completions_to_vec (struct list *completions) for (i = 0; i < vector_active (comps) && !exists; i++) { struct cmd_token *curr = vector_slot (comps, i); +#ifdef VTYSH_DEBUG exists = !strcmp (curr->text, token->text) && !strcmp (curr->desc, token->desc); +#else + exists = !strcmp (curr->text, token->text); +#endif /* VTYSH_DEBUG */ } if (!exists) @@ -988,6 +988,7 @@ static const struct zebra_desc_table command_types[] = { DESC_ENTRY (ZEBRA_IPV4_NEXTHOP_DELETE), DESC_ENTRY (ZEBRA_IPV6_NEXTHOP_ADD), DESC_ENTRY (ZEBRA_IPV6_NEXTHOP_DELETE), + DESC_ENTRY (ZEBRA_IPMR_ROUTE_STATS), }; #undef DESC_ENTRY diff --git a/lib/network.c b/lib/network.c index 506e019136..2b6f2fbab5 100644 --- a/lib/network.c +++ b/lib/network.c @@ -62,8 +62,13 @@ writen(int fd, const u_char *ptr, int nbytes) while (nleft > 0) { nwritten = write(fd, ptr, nleft); - - if (nwritten <= 0) + + if (nwritten < 0) + { + if (!ERRNO_IO_RETRY(errno)) + return nwritten; + } + if (nwritten == 0) return (nwritten); nleft -= nwritten; diff --git a/lib/wheel.h b/lib/wheel.h index ddb79988b4..79d21e124b 100644 --- a/lib/wheel.h +++ b/lib/wheel.h @@ -40,9 +40,49 @@ struct timer_wheel void (*slot_run) (void *); }; +/* + * Creates a timer wheel + * + * master - Thread master structure for the process + * period - The Time in seconds that the timer wheel will + * take before it starts issuing commands again + * for items in each slot + * slots - The number of slots to have in this particular + * timer wheel + * slot_key - A hashing function of some sort that will allow + * the timer wheel to put items into individual slots + * slot_run - The function to run over each item in a particular slot + * + * Creates a timer wheel that will wake up 'slots' times over the entire + * wheel. Each time the timer wheel wakes up it will iterate through + * and run the slot_run function for each item stored in that particular + * slot. + * + * The timer code is 'intelligent' in that it notices if anything is + * in a particular slot and can schedule the next timer to skip + * the empty slot. + * + * The general purpose of a timer wheel is to reduce events in a system. + * A perfect example of usage for this is say hello packets that need + * to be sent out to all your neighbors. Suppose a large routing protocol + * has to send keepalive packets every Y seconds to each of it's peers. + * At scale we can have a very large number of peers, X. + * This means that we will have X timing events every Y seconds. + * If you replace these events with a timer wheel that has Z slots + * you will have at most Y/Z timer events if each slot has a work item + * in it. + * + * When X is large the number of events in a system can quickly escalate + * and cause significant amount of time handling thread events instead + * of running your code. + */ struct timer_wheel *wheel_init (struct thread_master *master, int period, size_t slots, unsigned int (*slot_key) (void *), void (*slot_run) (void *)); + +/* + * Delete the specified timer wheel created + */ void wheel_delete (struct timer_wheel *); /* @@ -51,17 +91,25 @@ void wheel_delete (struct timer_wheel *); int wheel_stop (struct timer_wheel *wheel); /* - * Start the wheel from running again + * Start the wheel running again */ int wheel_start (struct timer_wheel *wheel); /* + * wheel - The Timer wheel being modified + * item - The generic data structure that will be handed + * to the slot_run function. + * * Add item to a slot setup by the slot_key, * possibly change next time pop. */ int wheel_add_item (struct timer_wheel *wheel, void *item); /* + * wheel - The Timer wheel being modified. + * item - The item to remove from one of the slots in + * the timer wheel. + * * Remove a item to a slot setup by the slot_key, * possibly change next time pop. */ diff --git a/lib/zebra.h b/lib/zebra.h index c9be1892e4..bb43d062bc 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -405,6 +405,7 @@ typedef enum { ZEBRA_IPV4_NEXTHOP_DELETE, ZEBRA_IPV6_NEXTHOP_ADD, ZEBRA_IPV6_NEXTHOP_DELETE, + ZEBRA_IPMR_ROUTE_STATS, } zebra_message_types_t; /* Marker value used in new Zserv, in the byte location corresponding @@ -477,6 +478,12 @@ typedef enum { #define SAFI_RESERVED_5 5 #define SAFI_MAX 6 +#define IANA_SAFI_RESERVED 0 +#define IANA_SAFI_UNICAST 1 +#define IANA_SAFI_MULTICAST 2 +#define IANA_SAFI_ENCAP 7 +#define IANA_SAFI_MPLS_VPN 128 + /* * The above AFI and SAFI definitions are for internal use. The protocol * definitions (IANA values) as for example used in BGP protocol packets @@ -486,12 +493,14 @@ typedef enum { * not optimal for use in data-structure sizing. * Note: Only useful (i.e., supported) values are defined below. */ -#define IANA_AFI_RESERVED 0 -#define IANA_AFI_IPV4 1 -#define IANA_AFI_IPV6 2 -#define IANA_AFI_L2VPN 25 -#define IANA_AFI_IPMR 128 -#define IANA_AFI_IP6MR 129 +typedef enum { + IANA_AFI_RESERVED = 0, + IANA_AFI_IPV4 = 1, + IANA_AFI_IPV6 = 2, + IANA_AFI_L2VPN = 25, + IANA_AFI_IPMR = 128, + IANA_AFI_IP6MR = 129 +} iana_afi_t; #define IANA_SAFI_RESERVED 0 #define IANA_SAFI_UNICAST 1 @@ -531,7 +540,7 @@ typedef uint32_t route_tag_t; #define ROUTE_TAG_MAX UINT32_MAX #define ROUTE_TAG_PRI PRIu32 -static inline afi_t afi_iana2int (afi_t afi) +static inline afi_t afi_iana2int (iana_afi_t afi) { if (afi == IANA_AFI_IPV4) return AFI_IP; @@ -540,7 +549,7 @@ static inline afi_t afi_iana2int (afi_t afi) return AFI_MAX; } -static inline afi_t afi_int2iana (afi_t afi) +static inline iana_afi_t afi_int2iana (afi_t afi) { if (afi == AFI_IP) return IANA_AFI_IPV4; |
