diff options
Diffstat (limited to 'lib')
40 files changed, 1279 insertions, 201 deletions
diff --git a/lib/agentx.c b/lib/agentx.c index b479b5ea4c..d1b801fe8c 100644 --- a/lib/agentx.c +++ b/lib/agentx.c @@ -264,7 +264,7 @@ int smux_trap(struct variable *vp, size_t vp_len, const oid *ename, uint8_t sptrap) { oid objid_snmptrap[] = {1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0}; - size_t objid_snmptrap_len = sizeof objid_snmptrap / sizeof(oid); + size_t objid_snmptrap_len = sizeof(objid_snmptrap) / sizeof(oid); oid notification_oid[MAX_OID_LEN]; size_t notification_oid_len; unsigned int i; @@ -136,7 +136,7 @@ void bfd_peer_sendmsg(struct zclient *zclient, struct bfd_info *bfd_info, if (bfd_debug) zlog_debug( "%s: Suppressing BFD peer reg/dereg messages", - __FUNCTION__); + __func__); return; } @@ -146,7 +146,7 @@ void bfd_peer_sendmsg(struct zclient *zclient, struct bfd_info *bfd_info, zlog_debug( "%s: Can't send BFD peer register, Zebra client not " "established", - __FUNCTION__); + __func__); return; } @@ -328,7 +328,7 @@ static void bfd_last_update(time_t last_update, char *buf, size_t len) { time_t curr; time_t diff; - struct tm *tm; + struct tm tm; struct timeval tv; /* If no BFD satatus update has ever been received, print `never'. */ @@ -341,10 +341,10 @@ static void bfd_last_update(time_t last_update, char *buf, size_t len) monotime(&tv); curr = tv.tv_sec; diff = curr - last_update; - tm = gmtime(&diff); + gmtime_r(&diff, &tm); - snprintf(buf, len, "%d:%02d:%02d:%02d", tm->tm_yday, tm->tm_hour, - tm->tm_min, tm->tm_sec); + snprintf(buf, len, "%d:%02d:%02d:%02d", tm.tm_yday, tm.tm_hour, + tm.tm_min, tm.tm_sec); } /* @@ -454,7 +454,7 @@ void bfd_client_sendmsg(struct zclient *zclient, int command, zlog_debug( "%s: Can't send BFD client register, Zebra client not " "established", - __FUNCTION__); + __func__); return; } diff --git a/lib/buffer.c b/lib/buffer.c index 766b9791a5..ff49bc83df 100644 --- a/lib/buffer.c +++ b/lib/buffer.c @@ -288,7 +288,7 @@ buffer_status_t buffer_flush_window(struct buffer *b, int fd, int width, /* Previously print out is performed. */ if (erase_flag) { iov[iov_index].iov_base = erase; - iov[iov_index].iov_len = sizeof erase; + iov[iov_index].iov_len = sizeof(erase); iov_index++; } @@ -341,7 +341,7 @@ buffer_status_t buffer_flush_window(struct buffer *b, int fd, int width, /* In case of `more' display need. */ if (b->tail && (b->tail->sp < b->tail->cp) && !no_more_flag) { iov[iov_index].iov_base = more; - iov[iov_index].iov_len = sizeof more; + iov[iov_index].iov_len = sizeof(more); iov_index++; } diff --git a/lib/filter.c b/lib/filter.c index 80f8cf0bd0..3226fb2f5e 100644 --- a/lib/filter.c +++ b/lib/filter.c @@ -412,7 +412,7 @@ static int64_t filter_new_seq_get(struct access_list *access) int64_t newseq; struct filter *filter; - maxseq = newseq = 0; + maxseq = 0; for (filter = access->head; filter; filter = filter->next) { if (maxseq < filter->seq) diff --git a/lib/frr_zmq.c b/lib/frr_zmq.c index 7781beae5e..565936a410 100644 --- a/lib/frr_zmq.c +++ b/lib/frr_zmq.c @@ -177,7 +177,7 @@ int funcname_frrzmq_thread_add_read(struct thread_master *master, else { cb = XCALLOC(MTYPE_ZEROMQ_CB, sizeof(struct frrzmq_cb)); - cb->write.cancelled = 1; + cb->write.cancelled = true; *cbp = cb; } @@ -187,7 +187,7 @@ int funcname_frrzmq_thread_add_read(struct thread_master *master, cb->read.cb_msg = msgfunc; cb->read.cb_part = partfunc; cb->read.cb_error = errfunc; - cb->read.cancelled = 0; + cb->read.cancelled = false; if (events & ZMQ_POLLIN) { if (cb->read.thread) { @@ -285,7 +285,7 @@ int funcname_frrzmq_thread_add_write(struct thread_master *master, else { cb = XCALLOC(MTYPE_ZEROMQ_CB, sizeof(struct frrzmq_cb)); - cb->read.cancelled = 1; + cb->read.cancelled = true; *cbp = cb; } @@ -295,7 +295,7 @@ int funcname_frrzmq_thread_add_write(struct thread_master *master, cb->write.cb_msg = msgfunc; cb->write.cb_part = NULL; cb->write.cb_error = errfunc; - cb->write.cancelled = 0; + cb->write.cancelled = false; if (events & ZMQ_POLLOUT) { if (cb->write.thread) { @@ -316,7 +316,7 @@ void frrzmq_thread_cancel(struct frrzmq_cb **cb, struct cb_core *core) { if (!cb || !*cb) return; - core->cancelled = 1; + core->cancelled = true; if (core->thread) { thread_cancel(core->thread); core->thread = NULL; diff --git a/lib/getopt.h b/lib/getopt.h index 138870d199..63e12e947e 100644 --- a/lib/getopt.h +++ b/lib/getopt.h @@ -111,7 +111,7 @@ struct option { #if defined(__STDC__) && __STDC__ -#if REALLY_NEED_PLAIN_GETOPT +#ifdef REALLY_NEED_PLAIN_GETOPT /* * getopt is defined in POSIX.2. Assume that if the system defines diff --git a/lib/hash.h b/lib/hash.h index 7b3372d433..e7ba3187f5 100644 --- a/lib/hash.h +++ b/lib/hash.h @@ -36,11 +36,6 @@ extern "C" { #define HASHWALK_CONTINUE 0 #define HASHWALK_ABORT -1 -#if CONFDATE > 20200225 -CPP_NOTICE("hash.h: time to remove hash_backet #define") -#endif -#define hash_backet hash_bucket - struct hash_bucket { /* * if this bucket is the head of the linked listed, len denotes the @@ -745,12 +745,16 @@ static void if_dump(const struct interface *ifp) struct listnode *node; struct connected *c __attribute__((unused)); - for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, c)) + for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, c)) { + struct vrf *vrf = vrf_lookup_by_id(ifp->vrf_id); + zlog_info( - "Interface %s vrf %u index %d metric %d mtu %d " + "Interface %s vrf %s(%u) index %d metric %d mtu %d " "mtu6 %d %s", - ifp->name, ifp->vrf_id, ifp->ifindex, ifp->metric, - ifp->mtu, ifp->mtu6, if_flag_dump(ifp->flags)); + ifp->name, VRF_LOGNAME(vrf), ifp->vrf_id, ifp->ifindex, + ifp->metric, ifp->mtu, ifp->mtu6, + if_flag_dump(ifp->flags)); + } } /* Interface printing for all interface. */ @@ -811,27 +815,25 @@ DEFUN (show_address, "address\n" VRF_CMD_HELP_STR) { - int idx_vrf = 3; - struct listnode *node; - struct interface *ifp; - struct connected *ifc; - struct prefix *p; - vrf_id_t vrf_id = VRF_DEFAULT; + int idx_vrf = 3; + struct listnode *node; + struct interface *ifp; + struct connected *ifc; + struct prefix *p; + vrf_id_t vrf_id = VRF_DEFAULT; - if (argc > 2) - VRF_GET_ID (vrf_id, argv[idx_vrf]->arg); + if (argc > 2) + VRF_GET_ID (vrf_id, argv[idx_vrf]->arg); - FOR_ALL_INTERFACES (vrf, ifp) - { - for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, ifc)) - { - p = ifc->address; + FOR_ALL_INTERFACES (vrf, ifp) { + for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, ifc)) { + p = ifc->address; - if (p->family == AF_INET) - vty_out (vty, "%s/%d\n", inet_ntoa (p->u.prefix4), p->prefixlen); + if (p->family == AF_INET) + vty_out (vty, "%s/%d\n", inet_ntoa (p->u.prefix4), p->prefixlen); + } } - } - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFUN (show_address_vrf_all, @@ -841,31 +843,30 @@ DEFUN (show_address_vrf_all, "address\n" VRF_ALL_CMD_HELP_STR) { - struct vrf *vrf; - struct listnode *node; - struct interface *ifp; - struct connected *ifc; - struct prefix *p; + struct vrf *vrf; + struct listnode *node; + struct interface *ifp; + struct connected *ifc; + struct prefix *p; - RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) - { - if (RB_EMPTY (if_name_head, &vrf->ifaces_by_name)) - continue; + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) + { + if (RB_EMPTY (if_name_head, &vrf->ifaces_by_name)) + continue; - vty_out (vty, "\nVRF %u\n\n", vrf->vrf_id); + vty_out (vty, "\nVRF %s(%u)\n\n", + VRF_LOGNAME(vrf), vrf->vrf_id); - FOR_ALL_INTERFACES (vrf, ifp) - { - for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, ifc)) - { - p = ifc->address; + FOR_ALL_INTERFACES (vrf, ifp) { + for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, ifc)) { + p = ifc->address; - if (p->family == AF_INET) - vty_out (vty, "%s/%d\n", inet_ntoa (p->u.prefix4), p->prefixlen); - } - } - } - return CMD_SUCCESS; + if (p->family == AF_INET) + vty_out (vty, "%s/%d\n", inet_ntoa (p->u.prefix4), p->prefixlen); + } + } + } + return CMD_SUCCESS; } #endif @@ -886,11 +887,8 @@ void connected_free(struct connected **connected) { struct connected *ptr = *connected; - if (ptr->address) - prefix_free(&ptr->address); - - if (ptr->destination) - prefix_free(&ptr->destination); + prefix_free(&ptr->address); + prefix_free(&ptr->destination); XFREE(MTYPE_CONNECTED_LABEL, ptr->label); @@ -927,14 +925,16 @@ connected_log(struct connected *connected, char *str) { struct prefix *p; struct interface *ifp; + struct vrf *vrf; char logbuf[BUFSIZ]; char buf[BUFSIZ]; ifp = connected->ifp; p = connected->address; - snprintf(logbuf, BUFSIZ, "%s interface %s vrf %u %s %s/%d ", str, - ifp->name, ifp->vrf_id, prefix_family_str(p), + vrf = vrf_lookup_by_id(ifp->vrf_id); + snprintf(logbuf, BUFSIZ, "%s interface %s vrf %s(%u) %s %s/%d ", str, + ifp->name, VRF_LOGNAME(vrf), ifp->vrf_id, prefix_family_str(p), inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ), p->prefixlen); p = connected->destination; diff --git a/lib/ipaddr.h b/lib/ipaddr.h index 6bd614044c..c6372f1abb 100644 --- a/lib/ipaddr.h +++ b/lib/ipaddr.h @@ -119,10 +119,13 @@ static inline void ipv4_mapped_ipv6_to_ipv4(struct in6_addr *in6, memcpy(in, (char *)in6 + 12, sizeof(struct in_addr)); } +/* + * Check if a struct ipaddr has nonzero value + */ static inline bool ipaddr_isset(struct ipaddr *ip) { static struct ipaddr a = {}; - return (0 == memcmp(&a, ip, sizeof(struct ipaddr))); + return (0 != memcmp(&a, ip, sizeof(struct ipaddr))); } #ifdef __cplusplus diff --git a/lib/keychain.c b/lib/keychain.c index fc9f0f9cfa..ea512a2699 100644 --- a/lib/keychain.c +++ b/lib/keychain.c @@ -967,12 +967,12 @@ static struct cmd_node keychain_key_node = {KEYCHAIN_KEY_NODE, static int keychain_strftime(char *buf, int bufsiz, time_t *time) { - struct tm *tm; + struct tm tm; size_t len; - tm = localtime(time); + localtime_r(time, &tm); - len = strftime(buf, bufsiz, "%T %b %d %Y", tm); + len = strftime(buf, bufsiz, "%T %b %d %Y", &tm); return len; } diff --git a/lib/libfrr.c b/lib/libfrr.c index 4fb43edff2..3622890e46 100644 --- a/lib/libfrr.c +++ b/lib/libfrr.c @@ -383,7 +383,7 @@ static int frr_opt(int opt) exit(0); break; case 'd': - di->daemon_mode = 1; + di->daemon_mode = true; break; case 'M': oc = XMALLOC(MTYPE_TMP, sizeof(*oc)); @@ -467,12 +467,12 @@ static int frr_opt(int opt) case 'C': if (di->flags & FRR_NO_CFG_PID_DRY) return 1; - di->dryrun = 1; + di->dryrun = true; break; case 't': if (di->flags & FRR_NO_CFG_PID_DRY) return 1; - di->terminal = 1; + di->terminal = true; break; case 'z': di->zpathspace = true; @@ -220,11 +220,11 @@ size_t quagga_timestamp(int timestamp_precision, char *buf, size_t buflen) /* first, we update the cache if the time has changed */ if (cache.last != clock.tv_sec) { - struct tm *tm; + struct tm tm; cache.last = clock.tv_sec; - tm = localtime(&cache.last); + localtime_r(&cache.last, &tm); cache.len = strftime(cache.buf, sizeof(cache.buf), - "%Y/%m/%d %H:%M:%S", tm); + "%Y/%m/%d %H:%M:%S", &tm); } /* note: it's not worth caching the subsecond part, because chances are that back-to-back calls are not sufficiently close @@ -1092,6 +1092,11 @@ static const struct zebra_desc_table command_types[] = { DESC_ENTRY(ZEBRA_VXLAN_SG_ADD), DESC_ENTRY(ZEBRA_VXLAN_SG_DEL), DESC_ENTRY(ZEBRA_VXLAN_SG_REPLAY), + DESC_ENTRY(ZEBRA_MLAG_PROCESS_UP), + DESC_ENTRY(ZEBRA_MLAG_PROCESS_DOWN), + DESC_ENTRY(ZEBRA_MLAG_CLIENT_REGISTER), + DESC_ENTRY(ZEBRA_MLAG_CLIENT_UNREGISTER), + DESC_ENTRY(ZEBRA_MLAG_FORWARD_MSG), DESC_ENTRY(ZEBRA_ERROR), DESC_ENTRY(ZEBRA_CLIENT_CAPABILITIES)}; #undef DESC_ENTRY @@ -412,8 +412,8 @@ void hmac_md5(unsigned char *text, int text_len, unsigned char *key, */ /* start out by storing key in pads */ - bzero(k_ipad, sizeof k_ipad); - bzero(k_opad, sizeof k_opad); + bzero(k_ipad, sizeof(k_ipad)); + bzero(k_opad, sizeof(k_opad)); bcopy(key, k_ipad, key_len); bcopy(key, k_opad, key_len); diff --git a/lib/mlag.c b/lib/mlag.c index 1daf290725..733dd41ea8 100644 --- a/lib/mlag.c +++ b/lib/mlag.c @@ -81,22 +81,33 @@ char *mlag_lib_msgid_to_str(enum mlag_msg_type msg_type, char *buf, size_t size) } -int mlag_lib_decode_mlag_hdr(struct stream *s, struct mlag_msg *msg) +int mlag_lib_decode_mlag_hdr(struct stream *s, struct mlag_msg *msg, + size_t *length) { - if (s == NULL || msg == NULL) +#define LIB_MLAG_HDR_LENGTH 8 + *length = stream_get_endp(s); + + if (s == NULL || msg == NULL || *length < LIB_MLAG_HDR_LENGTH) return -1; + *length -= LIB_MLAG_HDR_LENGTH; + STREAM_GETL(s, msg->msg_type); STREAM_GETW(s, msg->data_len); STREAM_GETW(s, msg->msg_cnt); + return 0; stream_failure: return -1; } -int mlag_lib_decode_mroute_add(struct stream *s, struct mlag_mroute_add *msg) +#define MLAG_MROUTE_ADD_LENGTH \ + (VRF_NAMSIZ + INTERFACE_NAMSIZ + 4 + 4 + 4 + 4 + 1 + 1 + 4) + +int mlag_lib_decode_mroute_add(struct stream *s, struct mlag_mroute_add *msg, + size_t *length) { - if (s == NULL || msg == NULL) + if (s == NULL || msg == NULL || *length < MLAG_MROUTE_ADD_LENGTH) return -1; STREAM_GET(msg->vrf_name, s, VRF_NAMSIZ); @@ -108,14 +119,18 @@ int mlag_lib_decode_mroute_add(struct stream *s, struct mlag_mroute_add *msg) STREAM_GETC(s, msg->am_i_dual_active); STREAM_GETL(s, msg->vrf_id); STREAM_GET(msg->intf_name, s, INTERFACE_NAMSIZ); + return 0; stream_failure: return -1; } -int mlag_lib_decode_mroute_del(struct stream *s, struct mlag_mroute_del *msg) +#define MLAG_MROUTE_DEL_LENGTH (VRF_NAMSIZ + INTERFACE_NAMSIZ + 4 + 4 + 4 + 4) + +int mlag_lib_decode_mroute_del(struct stream *s, struct mlag_mroute_del *msg, + size_t *length) { - if (s == NULL || msg == NULL) + if (s == NULL || msg == NULL || *length < MLAG_MROUTE_DEL_LENGTH) return -1; STREAM_GET(msg->vrf_name, s, VRF_NAMSIZ); @@ -124,6 +139,7 @@ int mlag_lib_decode_mroute_del(struct stream *s, struct mlag_mroute_del *msg) STREAM_GETL(s, msg->owner_id); STREAM_GETL(s, msg->vrf_id); STREAM_GET(msg->intf_name, s, INTERFACE_NAMSIZ); + return 0; stream_failure: return -1; diff --git a/lib/mlag.h b/lib/mlag.h index c531fb5b68..37bb3aa6db 100644 --- a/lib/mlag.h +++ b/lib/mlag.h @@ -125,11 +125,14 @@ struct mlag_msg { extern char *mlag_role2str(enum mlag_role role, char *buf, size_t size); extern char *mlag_lib_msgid_to_str(enum mlag_msg_type msg_type, char *buf, size_t size); -extern int mlag_lib_decode_mlag_hdr(struct stream *s, struct mlag_msg *msg); +extern int mlag_lib_decode_mlag_hdr(struct stream *s, struct mlag_msg *msg, + size_t *length); extern int mlag_lib_decode_mroute_add(struct stream *s, - struct mlag_mroute_add *msg); + struct mlag_mroute_add *msg, + size_t *length); extern int mlag_lib_decode_mroute_del(struct stream *s, - struct mlag_mroute_del *msg); + struct mlag_mroute_del *msg, + size_t *length); extern int mlag_lib_decode_mlag_status(struct stream *s, struct mlag_status *msg); extern int mlag_lib_decode_vxlan_update(struct stream *s, diff --git a/lib/module.c b/lib/module.c index 098c550684..14d5cfd44f 100644 --- a/lib/module.c +++ b/lib/module.c @@ -58,7 +58,7 @@ static const char *execname = NULL; void frrmod_init(struct frrmod_runtime *modinfo) { - modinfo->finished_loading = 1; + modinfo->finished_loading = true; *frrmod_last = modinfo; frrmod_last = &modinfo->next; @@ -134,7 +134,7 @@ struct frrmod_runtime *frrmod_load(const char *spec, const char *dir, char *err, goto out_fail; } - rtinfo->finished_loading = 1; + rtinfo->finished_loading = true; *frrmod_last = rtinfo; frrmod_last = &rtinfo->next; diff --git a/lib/monotime.h b/lib/monotime.h index e246f177de..dda763784f 100644 --- a/lib/monotime.h +++ b/lib/monotime.h @@ -112,6 +112,26 @@ static inline char *time_to_string(time_t ts, char *buf) return ctime_r(&tbuf, buf); } +/* Convert interval to human-friendly string, used in cli output e.g. */ +static inline const char *frrtime_to_interval(time_t t, char *buf, + size_t buflen) +{ + struct tm tm; + + gmtime_r(&t, &tm); + + if (t < ONE_DAY_SECOND) + snprintf(buf, buflen, "%02d:%02d:%02d", tm.tm_hour, tm.tm_min, + tm.tm_sec); + else if (t < ONE_WEEK_SECOND) + snprintf(buf, buflen, "%dd%02dh%02dm", tm.tm_yday, tm.tm_hour, + tm.tm_min); + else + snprintf(buf, buflen, "%02dw%dd%02dh", tm.tm_yday / 7, + tm.tm_yday - ((tm.tm_yday / 7) * 7), tm.tm_hour); + return buf; +} + #ifdef __cplusplus } #endif diff --git a/lib/nexthop_group.c b/lib/nexthop_group.c index 3005a51c71..d660428bcd 100644 --- a/lib/nexthop_group.c +++ b/lib/nexthop_group.c @@ -216,7 +216,8 @@ struct nexthop_group *nexthop_group_new(void) return XCALLOC(MTYPE_NEXTHOP_GROUP, sizeof(struct nexthop_group)); } -void nexthop_group_copy(struct nexthop_group *to, struct nexthop_group *from) +void nexthop_group_copy(struct nexthop_group *to, + const struct nexthop_group *from) { /* Copy everything, including recursive info */ copy_nexthops(&to->nexthop, from->nexthop, NULL); diff --git a/lib/nexthop_group.h b/lib/nexthop_group.h index 73b020283a..f99a53f694 100644 --- a/lib/nexthop_group.h +++ b/lib/nexthop_group.h @@ -43,7 +43,7 @@ struct nexthop_group *nexthop_group_new(void); void nexthop_group_delete(struct nexthop_group **nhg); void nexthop_group_copy(struct nexthop_group *to, - struct nexthop_group *from); + const struct nexthop_group *from); /* * Copy a list of nexthops in 'nh' to an nhg, enforcing canonical sort order diff --git a/lib/northbound.c b/lib/northbound.c index 206a88d980..cebedcff09 100644 --- a/lib/northbound.c +++ b/lib/northbound.c @@ -996,7 +996,7 @@ static int nb_transaction_process(enum nb_event event, * Only try to release resources that were allocated * successfully. */ - if (event == NB_EV_ABORT && change->prepare_ok == false) + if (event == NB_EV_ABORT && !change->prepare_ok) break; /* Call the appropriate callback. */ diff --git a/lib/plist.c b/lib/plist.c index 662221beec..40131aebed 100644 --- a/lib/plist.c +++ b/lib/plist.c @@ -303,6 +303,8 @@ static void prefix_list_delete(struct prefix_list *plist) /* If prefix-list contain prefix_list_entry free all of it. */ for (pentry = plist->head; pentry; pentry = next) { + route_map_notify_pentry_dependencies(plist->name, pentry, + RMAP_EVENT_PLIST_DELETED); next = pentry->next; prefix_list_trie_del(plist, pentry); prefix_list_entry_free(pentry); @@ -385,7 +387,7 @@ static int64_t prefix_new_seq_get(struct prefix_list *plist) int64_t newseq; struct prefix_list_entry *pentry; - maxseq = newseq = 0; + maxseq = 0; for (pentry = plist->head; pentry; pentry = pentry->next) { if (maxseq < pentry->seq) @@ -518,6 +520,8 @@ static void prefix_list_entry_delete(struct prefix_list *plist, else plist->tail = pentry->prev; + route_map_notify_pentry_dependencies(plist->name, pentry, + RMAP_EVENT_PLIST_DELETED); prefix_list_entry_free(pentry); plist->count--; @@ -631,6 +635,9 @@ static void prefix_list_entry_add(struct prefix_list *plist, /* Increment count. */ plist->count++; + route_map_notify_pentry_dependencies(plist->name, pentry, + RMAP_EVENT_PLIST_ADDED); + /* Run hook function. */ if (plist->master->add_hook) (*plist->master->add_hook)(plist); @@ -2032,7 +2039,7 @@ static void prefix_list_reset_afi(afi_t afi, int orf) assert(master->str.head == NULL); assert(master->str.tail == NULL); - master->seqnum = 1; + master->seqnum = true; master->recent = NULL; } diff --git a/lib/prefix.c b/lib/prefix.c index 2b7727fd0a..80fe0f54a9 100644 --- a/lib/prefix.c +++ b/lib/prefix.c @@ -1082,7 +1082,7 @@ struct prefix *prefix_new(void) { struct prefix *p; - p = XCALLOC(MTYPE_PREFIX, sizeof *p); + p = XCALLOC(MTYPE_PREFIX, sizeof(*p)); return p; } diff --git a/lib/printf/printf-pos.c b/lib/printf/printf-pos.c index 20a58eacdc..cc03f7ef9a 100644 --- a/lib/printf/printf-pos.c +++ b/lib/printf/printf-pos.c @@ -686,7 +686,7 @@ build_arg_table(struct typetable *types, va_list ap, union arg **argtable) if (types->tablemax >= STATIC_ARG_TBL_SIZE) { *argtable = (union arg *) - malloc (sizeof (union arg) * (types->tablemax + 1)); + malloc (sizeof(union arg) * (types->tablemax + 1)); if (*argtable == NULL) return; } diff --git a/lib/ptm_lib.c b/lib/ptm_lib.c index 54f027deeb..b66ae221cf 100644 --- a/lib/ptm_lib.c +++ b/lib/ptm_lib.c @@ -143,7 +143,7 @@ int ptm_lib_append_msg(ptm_lib_handle_t *hdl, void *ctxt, const char *key, csv_record_t *mh_rec, *rec; if (!p_ctxt) { - ERRLOG("%s: no context \n", __FUNCTION__); + ERRLOG("%s: no context \n", __func__); return -1; } @@ -154,7 +154,7 @@ int ptm_lib_append_msg(ptm_lib_handle_t *hdl, void *ctxt, const char *key, /* append to the hdr record */ rec = csv_append_record(csv, rec, 1, key); if (!rec) { - ERRLOG("%s: Could not append key \n", __FUNCTION__); + ERRLOG("%s: Could not append key \n", __func__); return -1; } @@ -162,7 +162,7 @@ int ptm_lib_append_msg(ptm_lib_handle_t *hdl, void *ctxt, const char *key, /* append to the data record */ rec = csv_append_record(csv, rec, 1, val); if (!rec) { - ERRLOG("%s: Could not append val \n", __FUNCTION__); + ERRLOG("%s: Could not append val \n", __func__); return -1; } @@ -186,7 +186,7 @@ int ptm_lib_init_msg(ptm_lib_handle_t *hdl, int cmd_id, int type, void *in_ctxt, csv = csv_init(NULL, NULL, PTMLIB_MSG_SZ); if (!csv) { - ERRLOG("%s: Could not allocate csv \n", __FUNCTION__); + ERRLOG("%s: Could not allocate csv \n", __func__); return -1; } @@ -194,7 +194,7 @@ int ptm_lib_init_msg(ptm_lib_handle_t *hdl, int cmd_id, int type, void *in_ctxt, cmd_id, hdl->client_name); if (!rec) { - ERRLOG("%s: Could not allocate record \n", __FUNCTION__); + ERRLOG("%s: Could not allocate record \n", __func__); csv_clean(csv); csv_free(csv); return -1; @@ -202,7 +202,7 @@ int ptm_lib_init_msg(ptm_lib_handle_t *hdl, int cmd_id, int type, void *in_ctxt, p_ctxt = calloc(1, sizeof(*p_ctxt)); if (!p_ctxt) { - ERRLOG("%s: Could not allocate context \n", __FUNCTION__); + ERRLOG("%s: Could not allocate context \n", __func__); csv_clean(csv); csv_free(csv); return -1; @@ -234,7 +234,7 @@ int ptm_lib_cleanup_msg(ptm_lib_handle_t *hdl, void *ctxt) csv_t *csv; if (!p_ctxt) { - ERRLOG("%s: no context \n", __FUNCTION__); + ERRLOG("%s: no context \n", __func__); return -1; } @@ -254,7 +254,7 @@ int ptm_lib_complete_msg(ptm_lib_handle_t *hdl, void *ctxt, char *buf, int *len) csv_record_t *rec; if (!p_ctxt) { - ERRLOG("%s: no context \n", __FUNCTION__); + ERRLOG("%s: no context \n", __func__); return -1; } @@ -268,7 +268,7 @@ int ptm_lib_complete_msg(ptm_lib_handle_t *hdl, void *ctxt, char *buf, int *len) /* parse csv contents into string */ if (buf && len) { if (csv_serialize(csv, buf, *len)) { - ERRLOG("%s: cannot serialize\n", __FUNCTION__); + ERRLOG("%s: cannot serialize\n", __func__); return -1; } *len = csvlen(csv); @@ -425,8 +425,7 @@ int ptm_lib_process_msg(ptm_lib_handle_t *hdl, int fd, char *inbuf, int inlen, csv_decode(csv, inbuf); p_ctxt = calloc(1, sizeof(*p_ctxt)); if (!p_ctxt) { - ERRLOG("%s: Could not allocate context \n", - __FUNCTION__); + ERRLOG("%s: Could not allocate context \n", __func__); csv_clean(csv); csv_free(csv); return -1; diff --git a/lib/routemap.c b/lib/routemap.c index 0d5621d90e..e2baa36f24 100644 --- a/lib/routemap.c +++ b/lib/routemap.c @@ -31,6 +31,7 @@ #include "hash.h" #include "libfrr.h" #include "lib_errors.h" +#include "table.h" DEFINE_MTYPE_STATIC(LIB, ROUTE_MAP, "Route map") DEFINE_MTYPE(LIB, ROUTE_MAP_NAME, "Route map name") @@ -44,12 +45,52 @@ DEFINE_MTYPE_STATIC(LIB, ROUTE_MAP_DEP_DATA, "Route map dependency data") DEFINE_QOBJ_TYPE(route_map_index) DEFINE_QOBJ_TYPE(route_map) +#define IPv4_PREFIX_LIST "ip address prefix-list" +#define IPv6_PREFIX_LIST "ipv6 address prefix-list" +#define IPv4_MATCH_RULE "ip " +#define IPv6_MATCH_RULE "ipv6 " + +#define IS_RULE_IPv4_PREFIX_LIST(S) \ + (strncmp(S, IPv4_PREFIX_LIST, strlen(IPv4_PREFIX_LIST)) == 0) +#define IS_RULE_IPv6_PREFIX_LIST(S) \ + (strncmp(S, IPv6_PREFIX_LIST, strlen(IPv6_PREFIX_LIST)) == 0) + +#define IS_IPv4_RULE(S) \ + (strncmp(S, IPv4_MATCH_RULE, strlen(IPv4_MATCH_RULE)) == 0) +#define IS_IPv6_RULE(S) \ + (strncmp(S, IPv6_MATCH_RULE, strlen(IPv6_MATCH_RULE)) == 0) +struct route_map_pentry_dep { + struct prefix_list_entry *pentry; + const char *plist_name; + route_map_event_t event; +}; + /* Vector for route match rules. */ static vector route_match_vec; /* Vector for route set rules. */ static vector route_set_vec; +static void route_map_pfx_tbl_update(route_map_event_t event, + struct route_map_index *index, afi_t afi, + const char *plist_name); +static void route_map_pfx_table_add_default(afi_t afi, + struct route_map_index *index); +static void route_map_pfx_table_del_default(afi_t afi, + struct route_map_index *index); +static void route_map_add_plist_entries(afi_t afi, + struct route_map_index *index, + const char *plist_name, + struct prefix_list_entry *entry); +static void route_map_del_plist_entries(afi_t afi, + struct route_map_index *index, + const char *plist_name, + struct prefix_list_entry *entry); +static bool route_map_is_ip_rule_present(struct route_map_index *index); +static bool route_map_is_ipv6_rule_present(struct route_map_index *index); + +static struct hash *route_map_get_dep_hash(route_map_event_t event); + struct route_map_match_set_hooks rmap_match_set_hook; /* match interface */ @@ -566,6 +607,12 @@ static struct route_map *route_map_add(const char *name) route_map_notify_dependencies(name, RMAP_EVENT_CALL_ADDED); } + if (!map->ipv4_prefix_table) + map->ipv4_prefix_table = route_table_init(); + + if (!map->ipv6_prefix_table) + map->ipv6_prefix_table = route_table_init(); + if (rmap_debug) zlog_debug("Add route-map %s", name); return map; @@ -786,8 +833,9 @@ static void vty_show_route_map_entry(struct vty *vty, struct route_map *map) struct route_map_index *index; struct route_map_rule *rule; - vty_out(vty, "route-map: %s Invoked: %" PRIu64 "\n", - map->name, map->applied - map->applied_clear); + vty_out(vty, "route-map: %s Invoked: %" PRIu64 " Optimization: %s\n", + map->name, map->applied - map->applied_clear, + map->optimization_disabled ? "disabled" : "enabled"); for (index = map->head; index; index = index->next) { vty_out(vty, " %s, sequence %d Invoked %" PRIu64 "\n", @@ -914,6 +962,7 @@ static struct route_map_index *route_map_index_new(void) /* Free route map index. */ void route_map_index_delete(struct route_map_index *index, int notify) { + struct routemap_hook_context *rhc; struct route_map_rule *rule; QOBJ_UNREG(index); @@ -923,12 +972,21 @@ void route_map_index_delete(struct route_map_index *index, int notify) index->map->name, index->pref); /* Free route map northbound hook contexts. */ - while (!TAILQ_EMPTY(&index->rhclist)) - routemap_hook_context_free(TAILQ_FIRST(&index->rhclist)); + while ((rhc = TAILQ_FIRST(&index->rhclist)) != NULL) + routemap_hook_context_free(rhc); /* Free route match. */ - while ((rule = index->match_list.head) != NULL) + while ((rule = index->match_list.head) != NULL) { + if (IS_RULE_IPv4_PREFIX_LIST(rule->cmd->str)) + route_map_pfx_tbl_update(RMAP_EVENT_PLIST_DELETED, + index, AFI_IP, rule->rule_str); + else if (IS_RULE_IPv6_PREFIX_LIST(rule->cmd->str)) + route_map_pfx_tbl_update(RMAP_EVENT_PLIST_DELETED, + index, AFI_IP6, + rule->rule_str); + route_map_rule_delete(&index->match_list, rule); + } /* Free route set. */ while ((rule = index->set_list.head) != NULL) @@ -948,6 +1006,8 @@ void route_map_index_delete(struct route_map_index *index, int notify) /* Free 'char *nextrm' if not NULL */ XFREE(MTYPE_ROUTE_MAP_NAME, index->nextrm); + route_map_pfx_tbl_update(RMAP_EVENT_INDEX_DELETED, index, 0, NULL); + /* Execute event hook. */ if (route_map_master.event_hook && notify) { (*route_map_master.event_hook)(index->map->name); @@ -1007,6 +1067,8 @@ route_map_index_add(struct route_map *map, enum route_map_type type, int pref) point->prev = index; } + route_map_pfx_tbl_update(RMAP_EVENT_INDEX_ADDED, index, 0, NULL); + /* Execute event hook. */ if (route_map_master.event_hook) { (*route_map_master.event_hook)(map->name); @@ -1254,6 +1316,19 @@ enum rmap_compile_rets route_map_add_match(struct route_map_index *index, return RMAP_COMPILE_SUCCESS; } + /* If IPv4 or IPv6 prefix-list match criteria + * has been delete to the route-map index, update + * the route-map's prefix table. + */ + if (IS_RULE_IPv4_PREFIX_LIST(match_name)) + route_map_pfx_tbl_update( + RMAP_EVENT_PLIST_DELETED, index, AFI_IP, + rule->rule_str); + else if (IS_RULE_IPv6_PREFIX_LIST(match_name)) + route_map_pfx_tbl_update( + RMAP_EVENT_PLIST_DELETED, index, + AFI_IP6, rule->rule_str); + /* Remove the dependency of the route-map on the rule * that is being replaced. */ @@ -1282,6 +1357,38 @@ enum rmap_compile_rets route_map_add_match(struct route_map_index *index, /* Add new route match rule to linked list. */ route_map_rule_add(&index->match_list, rule); + /* If IPv4 or IPv6 prefix-list match criteria + * has been added to the route-map index, update + * the route-map's prefix table. + */ + if (IS_RULE_IPv4_PREFIX_LIST(match_name)) { + route_map_pfx_tbl_update(RMAP_EVENT_PLIST_ADDED, index, AFI_IP, + match_arg); + } else if (IS_RULE_IPv6_PREFIX_LIST(match_name)) { + route_map_pfx_tbl_update(RMAP_EVENT_PLIST_ADDED, index, AFI_IP6, + match_arg); + } else { + /* If IPv4 match criteria has been added to the route-map + * index, check for IPv6 prefix-list match rule presence and + * remove this index from the trie node created for each of the + * prefix-entry within the prefix-list. If no IPv6 prefix-list + * match rule is present, remove this index from the IPv6 + * default route's trie node. + */ + if (IS_IPv4_RULE(match_name)) + route_map_del_plist_entries(AFI_IP6, index, NULL, NULL); + + /* If IPv6 match criteria has been added to the route-map + * index, check for IPv4 prefix-list match rule presence and + * remove this index from the trie node created for each of the + * prefix-entry within the prefix-list. If no IPv4 prefix-list + * match rule is present, remove this index from the IPv4 + * default route's trie node. + */ + else if (IS_IPv6_RULE(match_name)) + route_map_del_plist_entries(AFI_IP, index, NULL, NULL); + } + /* Execute event hook. */ if (route_map_master.event_hook) { (*route_map_master.event_hook)(index->map->name); @@ -1329,6 +1436,45 @@ enum rmap_compile_rets route_map_delete_match(struct route_map_index *index, index->map->name); route_map_rule_delete(&index->match_list, rule); + + /* If IPv4 or IPv6 prefix-list match criteria + * has been delete to the route-map index, update + * the route-map's prefix table. + */ + if (IS_RULE_IPv4_PREFIX_LIST(match_name)) { + route_map_pfx_tbl_update( + RMAP_EVENT_PLIST_DELETED, index, AFI_IP, + match_arg); + } else if (IS_RULE_IPv6_PREFIX_LIST(match_name)) { + route_map_pfx_tbl_update( + RMAP_EVENT_PLIST_DELETED, index, + AFI_IP6, match_arg); + } else { + /* If no more IPv4 match rules are present in + * this index, check for IPv6 prefix-list match + * rule presence and add this index to trie node + * created for each of the prefix-entry within + * the prefix-list. If no IPv6 prefix-list match + * rule is present, add this index to the IPv6 + * default route's trie node. + */ + if (!route_map_is_ip_rule_present(index)) + route_map_add_plist_entries( + AFI_IP6, index, NULL, NULL); + + /* If no more IPv6 match rules are present in + * this index, check for IPv4 prefix-list match + * rule presence and add this index to trie node + * created for each of the prefix-entry within + * the prefix-list. If no IPv6 prefix-list match + * rule is present, add this index to the IPv4 + * default route's trie node. + */ + if (!route_map_is_ipv6_rule_present(index)) + route_map_add_plist_entries( + AFI_IP, index, NULL, NULL); + } + return RMAP_COMPILE_SUCCESS; } /* Can't find matched rule. */ @@ -1494,6 +1640,705 @@ route_map_apply_match(struct route_map_rule_list *match_list, return ret; } +static struct list *route_map_get_index_list(struct route_node **rn, + const struct prefix *prefix, + struct route_table *table) +{ + struct route_node *tmp_rn = NULL; + + if (!(*rn)) { + *rn = route_node_match(table, prefix); + + if (!(*rn)) + return NULL; + + if ((*rn)->info) + return (struct list *)((*rn)->info); + + /* If rn->info is NULL, get the parent. + * Store the rn in tmp_rn and unlock it later. + */ + tmp_rn = *rn; + } + + do { + *rn = (*rn)->parent; + if (tmp_rn) + route_unlock_node(tmp_rn); + + if (!(*rn)) + break; + + if ((*rn)->info) { + route_lock_node(*rn); + return (struct list *)((*rn)->info); + } + } while (!(*rn)->info); + + return NULL; +} + +/* + * This function returns the route-map index that best matches the prefix. + */ +static struct route_map_index * +route_map_get_index(struct route_map *map, const struct prefix *prefix, + route_map_object_t type, void *object, uint8_t *match_ret) +{ + int ret = 0; + struct list *candidate_rmap_list = NULL; + struct route_node *rn = NULL; + struct listnode *ln = NULL, *nn = NULL; + struct route_map_index *index = NULL, *best_index = NULL; + struct route_map_index *head_index = NULL; + struct route_table *table = NULL; + unsigned char family = prefix->family; + + if (family == AF_INET) + table = map->ipv4_prefix_table; + else + table = map->ipv6_prefix_table; + + if (!table) + return NULL; + + do { + candidate_rmap_list = + route_map_get_index_list(&rn, prefix, table); + if (!rn) + break; + + /* If the index at the head of the list is of seq higher + * than that in best_index, ignore the list and get the + * parent node's list. + */ + head_index = (struct route_map_index *)(listgetdata( + listhead(candidate_rmap_list))); + if (best_index && head_index + && (best_index->pref < head_index->pref)) { + route_unlock_node(rn); + continue; + } + + for (ALL_LIST_ELEMENTS(candidate_rmap_list, ln, nn, index)) { + /* If the index is of seq higher than that in + * best_index, ignore the list and get the parent + * node's list. + */ + if (best_index && (best_index->pref < index->pref)) + break; + + ret = route_map_apply_match(&index->match_list, prefix, + type, object); + + if (ret == RMAP_MATCH) { + *match_ret = ret; + best_index = index; + break; + } else if (ret == RMAP_NOOP) { + /* + * If match_ret is denymatch, even if we see + * more noops, we retain this return value and + * return this eventually if there are no + * matches. + */ + if (*match_ret != RMAP_NOMATCH) + *match_ret = ret; + } else { + /* + * ret is RMAP_NOMATCH. + */ + *match_ret = ret; + } + } + + route_unlock_node(rn); + + } while (rn); + + return best_index; +} + +static int route_map_candidate_list_cmp(struct route_map_index *idx1, + struct route_map_index *idx2) +{ + if (!idx1) + return -1; + if (!idx2) + return 1; + + return (idx1->pref - idx2->pref); +} + +/* + * This function adds the route-map index into the default route's + * route-node in the route-map's IPv4/IPv6 prefix-table. + */ +static void route_map_pfx_table_add_default(afi_t afi, + struct route_map_index *index) +{ + struct route_node *rn = NULL; + struct list *rmap_candidate_list = NULL; + struct prefix p; + bool updated_rn = false; + struct route_table *table = NULL; + + memset(&p, 0, sizeof(p)); + p.family = afi2family(afi); + p.prefixlen = 0; + + if (p.family == AF_INET) { + table = index->map->ipv4_prefix_table; + if (!table) + index->map->ipv4_prefix_table = route_table_init(); + + table = index->map->ipv4_prefix_table; + } else { + table = index->map->ipv6_prefix_table; + if (!table) + index->map->ipv6_prefix_table = route_table_init(); + + table = index->map->ipv6_prefix_table; + } + + /* Add default route to table */ + rn = route_node_get(table, &p); + + if (!rn) + return; + + if (!rn->info) { + rmap_candidate_list = list_new(); + rmap_candidate_list->cmp = + (int (*)(void *, void *))route_map_candidate_list_cmp; + rn->info = rmap_candidate_list; + } else { + rmap_candidate_list = (struct list *)rn->info; + updated_rn = true; + } + + listnode_add_sort_nodup(rmap_candidate_list, index); + if (updated_rn) + route_unlock_node(rn); +} + +/* + * This function removes the route-map index from the default route's + * route-node in the route-map's IPv4/IPv6 prefix-table. + */ +static void route_map_pfx_table_del_default(afi_t afi, + struct route_map_index *index) +{ + struct route_node *rn = NULL; + struct list *rmap_candidate_list = NULL; + struct prefix p; + struct route_table *table = NULL; + + memset(&p, 0, sizeof(p)); + p.family = afi2family(afi); + p.prefixlen = 0; + + if (p.family == AF_INET) + table = index->map->ipv4_prefix_table; + else + table = index->map->ipv6_prefix_table; + + /* Remove RMAP index from default route in table */ + rn = route_node_lookup(table, &p); + if (!rn || !rn->info) + return; + + rmap_candidate_list = (struct list *)rn->info; + + listnode_delete(rmap_candidate_list, index); + + if (listcount(rmap_candidate_list) == 0) { + list_delete(&rmap_candidate_list); + rn->info = NULL; + route_unlock_node(rn); + } + route_unlock_node(rn); +} + +/* + * This function adds the route-map index to the route-node for + * the prefix-entry in the route-map's IPv4/IPv6 prefix-table. + */ +static void route_map_pfx_table_add(struct route_table *table, + struct route_map_index *index, + struct prefix_list_entry *pentry) +{ + struct route_node *rn = NULL; + struct list *rmap_candidate_list = NULL; + bool updated_rn = false; + + rn = route_node_get(table, &pentry->prefix); + if (!rn) + return; + + if (!rn->info) { + rmap_candidate_list = list_new(); + rmap_candidate_list->cmp = + (int (*)(void *, void *))route_map_candidate_list_cmp; + rn->info = rmap_candidate_list; + } else { + rmap_candidate_list = (struct list *)rn->info; + updated_rn = true; + } + + listnode_add_sort_nodup(rmap_candidate_list, index); + if (updated_rn) + route_unlock_node(rn); +} + +/* + * This function removes the route-map index from the route-node for + * the prefix-entry in the route-map's IPv4/IPv6 prefix-table. + */ +static void route_map_pfx_table_del(struct route_table *table, + struct route_map_index *index, + struct prefix_list_entry *pentry) +{ + struct route_node *rn = NULL; + struct list *rmap_candidate_list = NULL; + + rn = route_node_lookup(table, &pentry->prefix); + if (!rn || !rn->info) + return; + + rmap_candidate_list = (struct list *)rn->info; + + listnode_delete(rmap_candidate_list, index); + + if (listcount(rmap_candidate_list) == 0) { + list_delete(&rmap_candidate_list); + rn->info = NULL; + route_unlock_node(rn); + } + route_unlock_node(rn); +} + +/* This function checks for the presence of an IPv4 match rule + * in the given route-map index. + */ +static bool route_map_is_ip_rule_present(struct route_map_index *index) +{ + struct route_map_rule_list *match_list = NULL; + struct route_map_rule *rule = NULL; + + match_list = &index->match_list; + for (rule = match_list->head; rule; rule = rule->next) + if (IS_IPv4_RULE(rule->cmd->str)) + return true; + + return false; +} + +/* This function checks for the presence of an IPv6 match rule + * in the given route-map index. + */ +static bool route_map_is_ipv6_rule_present(struct route_map_index *index) +{ + struct route_map_rule_list *match_list = NULL; + struct route_map_rule *rule = NULL; + + match_list = &index->match_list; + for (rule = match_list->head; rule; rule = rule->next) + if (IS_IPv6_RULE(rule->cmd->str)) + return true; + + return false; +} + +/* This function does the following: + * 1) If plist_name is not present, search for a IPv4 or IPv6 prefix-list + * match clause (based on the afi passed to this foo) and get the + * prefix-list name. + * 2) Look up the prefix-list using the name. + * 3) If the prefix-list is not found then, add the index to the IPv4/IPv6 + * default-route's node in the trie (based on the afi passed to this foo). + * 4) If the prefix-list is found then, remove the index from the IPv4/IPv6 + * default-route's node in the trie (based on the afi passed to this foo). + * 5) If a prefix-entry is passed then, create a route-node for this entry and + * add this index to the route-node. + * 6) If prefix-entry is not passed then, for every prefix-entry in the + * prefix-list, create a route-node for this entry and + * add this index to the route-node. + */ +static void route_map_add_plist_entries(afi_t afi, + struct route_map_index *index, + const char *plist_name, + struct prefix_list_entry *entry) +{ + struct route_map_rule_list *match_list = NULL; + struct route_map_rule *match = NULL; + struct prefix_list *plist = NULL; + struct prefix_list_entry *pentry = NULL; + bool plist_rule_is_present = false; + + if (!plist_name) { + match_list = &index->match_list; + + for (match = match_list->head; match; match = match->next) { + if (afi == AFI_IP) { + if (IS_RULE_IPv4_PREFIX_LIST(match->cmd->str)) { + plist_rule_is_present = true; + break; + } + } else { + if (IS_RULE_IPv6_PREFIX_LIST(match->cmd->str)) { + plist_rule_is_present = true; + break; + } + } + } + + if (plist_rule_is_present) + plist = prefix_list_lookup(afi, match->rule_str); + } else { + plist = prefix_list_lookup(afi, plist_name); + } + + if (!plist) { + route_map_pfx_table_add_default(afi, index); + return; + } + + route_map_pfx_table_del_default(afi, index); + + if (entry) { + if (afi == AFI_IP) { + route_map_pfx_table_add(index->map->ipv4_prefix_table, + index, entry); + } else { + route_map_pfx_table_add(index->map->ipv6_prefix_table, + index, entry); + } + } else { + for (pentry = plist->head; pentry; pentry = pentry->next) { + if (afi == AFI_IP) { + route_map_pfx_table_add( + index->map->ipv4_prefix_table, index, + pentry); + } else { + route_map_pfx_table_add( + index->map->ipv6_prefix_table, index, + pentry); + } + } + } +} + +/* This function does the following: + * 1) If plist_name is not present, search for a IPv4 or IPv6 prefix-list + * match clause (based on the afi passed to this foo) and get the + * prefix-list name. + * 2) Look up the prefix-list using the name. + * 3) If the prefix-list is not found then, delete the index from the IPv4/IPv6 + * default-route's node in the trie (based on the afi passed to this foo). + * 4) If a prefix-entry is passed then, remove this index from the route-node + * for the prefix in this prefix-entry. + * 5) If prefix-entry is not passed then, for every prefix-entry in the + * prefix-list, remove this index from the route-node + * for the prefix in this prefix-entry. + */ +static void route_map_del_plist_entries(afi_t afi, + struct route_map_index *index, + const char *plist_name, + struct prefix_list_entry *entry) +{ + struct route_map_rule_list *match_list = NULL; + struct route_map_rule *match = NULL; + struct prefix_list *plist = NULL; + struct prefix_list_entry *pentry = NULL; + bool plist_rule_is_present = false; + + if (!plist_name) { + match_list = &index->match_list; + + for (match = match_list->head; match; match = match->next) { + if (afi == AFI_IP) { + if (IS_RULE_IPv4_PREFIX_LIST(match->cmd->str)) { + plist_rule_is_present = true; + break; + } + } else { + if (IS_RULE_IPv6_PREFIX_LIST(match->cmd->str)) { + plist_rule_is_present = true; + break; + } + } + } + + if (plist_rule_is_present) + plist = prefix_list_lookup(afi, match->rule_str); + } else { + plist = prefix_list_lookup(afi, plist_name); + } + + if (!plist) { + route_map_pfx_table_del_default(afi, index); + return; + } + + if (entry) { + if (afi == AFI_IP) { + route_map_pfx_table_del(index->map->ipv4_prefix_table, + index, entry); + } else { + route_map_pfx_table_del(index->map->ipv6_prefix_table, + index, entry); + } + } else { + for (pentry = plist->head; pentry; pentry = pentry->next) { + if (afi == AFI_IP) { + route_map_pfx_table_del( + index->map->ipv4_prefix_table, index, + pentry); + } else { + route_map_pfx_table_del( + index->map->ipv6_prefix_table, index, + pentry); + } + } + } +} + +/* + * This function handles the cases where a prefix-list is added/removed + * as a match command from a particular route-map index. + * It updates the prefix-table of the route-map accordingly. + */ +static void route_map_trie_update(afi_t afi, route_map_event_t event, + struct route_map_index *index, + const char *plist_name) +{ + if (event == RMAP_EVENT_PLIST_ADDED) { + if (afi == AFI_IP) { + if (!route_map_is_ipv6_rule_present(index)) { + route_map_pfx_table_del_default(AFI_IP6, index); + route_map_add_plist_entries(afi, index, + plist_name, NULL); + } else { + route_map_del_plist_entries(AFI_IP6, index, + NULL, NULL); + } + } else { + if (!route_map_is_ip_rule_present(index)) { + route_map_pfx_table_del_default(AFI_IP, index); + route_map_add_plist_entries(afi, index, + plist_name, NULL); + } else { + route_map_del_plist_entries(AFI_IP, index, NULL, + NULL); + } + } + } else if (event == RMAP_EVENT_PLIST_DELETED) { + if (afi == AFI_IP) { + route_map_del_plist_entries(afi, index, plist_name, + NULL); + + if (!route_map_is_ipv6_rule_present(index)) + route_map_pfx_table_add_default(afi, index); + + if (!route_map_is_ip_rule_present(index)) + route_map_add_plist_entries(AFI_IP6, index, + NULL, NULL); + } else { + route_map_del_plist_entries(afi, index, plist_name, + NULL); + + if (!route_map_is_ip_rule_present(index)) + route_map_pfx_table_add_default(afi, index); + + if (!route_map_is_ipv6_rule_present(index)) + route_map_add_plist_entries(AFI_IP, index, NULL, + NULL); + } + } +} + +/* + * This function handles the cases where a route-map index and + * prefix-list is added/removed. + * It updates the prefix-table of the route-map accordingly. + */ +static void route_map_pfx_tbl_update(route_map_event_t event, + struct route_map_index *index, afi_t afi, + const char *plist_name) +{ + struct route_map *rmap = NULL; + + if (!index) + return; + + if (event == RMAP_EVENT_INDEX_ADDED) { + route_map_pfx_table_add_default(AFI_IP, index); + route_map_pfx_table_add_default(AFI_IP6, index); + return; + } + + if (event == RMAP_EVENT_INDEX_DELETED) { + route_map_pfx_table_del_default(AFI_IP, index); + route_map_pfx_table_del_default(AFI_IP6, index); + + if ((index->map->head == NULL) && (index->map->tail == NULL)) { + rmap = index->map; + + if (rmap->ipv4_prefix_table) { + route_table_finish(rmap->ipv4_prefix_table); + rmap->ipv4_prefix_table = NULL; + } + + if (rmap->ipv6_prefix_table) { + route_table_finish(rmap->ipv6_prefix_table); + rmap->ipv6_prefix_table = NULL; + } + } + return; + } + + /* Handle prefix-list match rule addition/deletion. + */ + route_map_trie_update(afi, event, index, plist_name); +} + +/* + * This function handles the cases where a new prefix-entry is added to + * a prefix-list or, an existing prefix-entry is removed from the prefix-list. + * It updates the prefix-table of the route-map accordingly. + */ +static void route_map_pentry_update(route_map_event_t event, + const char *plist_name, + struct route_map_index *index, + struct prefix_list_entry *pentry) +{ + struct prefix_list *plist = NULL; + afi_t afi; + unsigned char family = pentry->prefix.family; + + if (family == AF_INET) { + afi = AFI_IP; + plist = prefix_list_lookup(AFI_IP, plist_name); + } else { + afi = AFI_IP6; + plist = prefix_list_lookup(AFI_IP6, plist_name); + } + + if (event == RMAP_EVENT_PLIST_ADDED) { + if (plist->count == 1) { + if (afi == AFI_IP) { + if (!route_map_is_ipv6_rule_present(index)) + route_map_add_plist_entries( + afi, index, plist_name, pentry); + } else { + if (!route_map_is_ip_rule_present(index)) + route_map_add_plist_entries( + afi, index, plist_name, pentry); + } + } else { + route_map_add_plist_entries(afi, index, plist_name, + pentry); + } + } else if (event == RMAP_EVENT_PLIST_DELETED) { + route_map_del_plist_entries(afi, index, plist_name, pentry); + + if (plist->count == 1) { + if (afi == AFI_IP) { + if (!route_map_is_ipv6_rule_present(index)) + route_map_pfx_table_add_default(afi, + index); + } else { + if (!route_map_is_ip_rule_present(index)) + route_map_pfx_table_add_default(afi, + index); + } + } + } +} + +static void route_map_pentry_process_dependency(struct hash_bucket *backet, + void *data) +{ + char *rmap_name = NULL; + struct route_map *rmap = NULL; + struct route_map_index *index = NULL; + struct route_map_rule_list *match_list = NULL; + struct route_map_rule *match = NULL; + struct route_map_dep_data *dep_data = NULL; + struct route_map_pentry_dep *pentry_dep = + (struct route_map_pentry_dep *)data; + unsigned char family = pentry_dep->pentry->prefix.family; + + dep_data = (struct route_map_dep_data *)backet->data; + if (!dep_data) + return; + + rmap_name = dep_data->rname; + rmap = route_map_lookup_by_name(rmap_name); + if (!rmap || !rmap->head) + return; + + for (index = rmap->head; index; index = index->next) { + match_list = &index->match_list; + + if (!match_list) + continue; + + for (match = match_list->head; match; match = match->next) { + if (strcmp(match->rule_str, pentry_dep->plist_name) + == 0) { + if (IS_RULE_IPv4_PREFIX_LIST(match->cmd->str) + && family == AF_INET) { + route_map_pentry_update( + pentry_dep->event, + pentry_dep->plist_name, index, + pentry_dep->pentry); + } else if (IS_RULE_IPv6_PREFIX_LIST( + match->cmd->str) + && family == AF_INET6) { + route_map_pentry_update( + pentry_dep->event, + pentry_dep->plist_name, index, + pentry_dep->pentry); + } + } + } + } +} + +void route_map_notify_pentry_dependencies(const char *affected_name, + struct prefix_list_entry *pentry, + route_map_event_t event) +{ + struct route_map_dep *dep = NULL; + struct hash *upd8_hash = NULL; + struct route_map_pentry_dep pentry_dep; + + if (!affected_name || !pentry) + return; + + upd8_hash = route_map_get_dep_hash(event); + if (!upd8_hash) + return; + + dep = (struct route_map_dep *)hash_get(upd8_hash, (void *)affected_name, + NULL); + if (dep) { + if (!dep->this_hash) + dep->this_hash = upd8_hash; + + memset(&pentry_dep, 0, sizeof(struct route_map_pentry_dep)); + pentry_dep.pentry = pentry; + pentry_dep.plist_name = affected_name; + pentry_dep.event = event; + + hash_iterate(dep->dep_rmap_hash, + route_map_pentry_process_dependency, + (void *)&pentry_dep); + } +} + /* Apply route map's each index to the object. The matrix for a route-map looks like this: @@ -1547,9 +2392,10 @@ route_map_result_t route_map_apply(struct route_map *map, static int recursion = 0; enum route_map_cmd_result_t match_ret = RMAP_NOMATCH; route_map_result_t ret = RMAP_PERMITMATCH; - struct route_map_index *index; - struct route_map_rule *set; + struct route_map_index *index = NULL; + struct route_map_rule *set = NULL; char buf[PREFIX_STRLEN]; + bool skip_match_clause = false; if (recursion > RMAP_RECURSION_LIMIT) { flog_warn( @@ -1566,18 +2412,55 @@ route_map_result_t route_map_apply(struct route_map *map, } map->applied++; - for (index = map->head; index; index = index->next) { - /* Apply this index. */ - index->applied++; - match_ret = route_map_apply_match(&index->match_list, prefix, - type, object); - - if (rmap_debug) { - zlog_debug("Route-map: %s, sequence: %d, prefix: %s, result: %s", - map->name, index->pref, - prefix2str(prefix, buf, sizeof(buf)), - route_map_cmd_result_str(match_ret)); + + if ((!map->optimization_disabled) + && (map->ipv4_prefix_table || map->ipv6_prefix_table)) { + index = route_map_get_index(map, prefix, type, object, + (uint8_t *)&match_ret); + if (index) { + if (rmap_debug) + zlog_debug( + "Best match route-map: %s, sequence: %d for pfx: %s, result: %s", + map->name, index->pref, + prefix2str(prefix, buf, sizeof(buf)), + route_map_cmd_result_str(match_ret)); + } else { + if (rmap_debug) + zlog_debug( + "No best match sequence for pfx: %s in route-map: %s, result: %s", + prefix2str(prefix, buf, sizeof(buf)), + map->name, + route_map_cmd_result_str(match_ret)); + /* + * No index matches this prefix. Return deny unless, + * match_ret = RMAP_NOOP. + */ + if (match_ret == RMAP_NOOP) + ret = RMAP_PERMITMATCH; + else + ret = RMAP_DENYMATCH; + goto route_map_apply_end; } + skip_match_clause = true; + } else { + index = map->head; + } + + for (; index; index = index->next) { + if (!skip_match_clause) { + /* Apply this index. */ + match_ret = route_map_apply_match(&index->match_list, + prefix, type, object); + if (rmap_debug) { + zlog_debug( + "Route-map: %s, sequence: %d, prefix: %s, result: %s", + map->name, index->pref, + prefix2str(prefix, buf, sizeof(buf)), + route_map_cmd_result_str(match_ret)); + } + } else + skip_match_clause = false; + /* Now we apply the matrix from above */ if (match_ret == RMAP_NOOP) @@ -1801,8 +2684,7 @@ static void route_map_print_dependency(struct hash_bucket *bucket, void *data) char *rmap_name = dep_data->rname; char *dep_name = data; - zlog_debug("%s: Dependency for %s: %s", __FUNCTION__, dep_name, - rmap_name); + zlog_debug("%s: Dependency for %s: %s", __func__, dep_name, rmap_name); } static int route_map_dep_update(struct hash *dephash, const char *dep_name, @@ -2025,8 +2907,30 @@ void route_map_notify_dependencies(const char *affected_name, XFREE(MTYPE_ROUTE_MAP_NAME, name); } - /* VTY related functions. */ +DEFUN(no_routemap_optimization, no_routemap_optimization_cmd, + "no route-map optimization", + NO_STR + "route-map\n" + "optimization\n") +{ + VTY_DECLVAR_CONTEXT(route_map_index, index); + + index->map->optimization_disabled = true; + return CMD_SUCCESS; +} + +DEFUN(routemap_optimization, routemap_optimization_cmd, + "route-map optimization", + "route-map\n" + "optimization\n") +{ + VTY_DECLVAR_CONTEXT(route_map_index, index); + + index->map->optimization_disabled = false; + return CMD_SUCCESS; +} + static void clear_route_map_helper(struct route_map *map) { struct route_map_index *index; @@ -2201,6 +3105,121 @@ void route_map_counter_decrement(struct route_map *map) } } +DEFUN_HIDDEN(show_route_map_pfx_tbl, show_route_map_pfx_tbl_cmd, + "show route-map WORD prefix-table", + SHOW_STR + "route-map\n" + "route-map name\n" + "internal prefix-table\n") +{ + const char *rmap_name = argv[2]->arg; + struct route_map *rmap = NULL; + struct route_table *rm_pfx_tbl4 = NULL; + struct route_table *rm_pfx_tbl6 = NULL; + struct route_node *rn = NULL, *prn = NULL; + struct list *rmap_index_list = NULL; + struct listnode *ln = NULL, *nln = NULL; + struct route_map_index *index = NULL; + struct prefix *p = NULL, *pp = NULL; + char buf[SU_ADDRSTRLEN], pbuf[SU_ADDRSTRLEN]; + uint8_t len = 54; + + vty_out(vty, "%s:\n", frr_protonameinst); + rmap = route_map_lookup_by_name(rmap_name); + if (rmap) { + rm_pfx_tbl4 = rmap->ipv4_prefix_table; + if (rm_pfx_tbl4) { + vty_out(vty, "\n%s%43s%s\n", "IPv4 Prefix", "", + "Route-map Index List"); + vty_out(vty, "%s%39s%s\n", "_______________", "", + "____________________"); + for (rn = route_top(rm_pfx_tbl4); rn; + rn = route_next(rn)) { + p = &rn->p; + + vty_out(vty, " %s/%d (%d)\n", + inet_ntop(p->family, &p->u.prefix, buf, + SU_ADDRSTRLEN), + p->prefixlen, rn->lock); + + vty_out(vty, "(P) "); + prn = rn->parent; + if (prn) { + pp = &prn->p; + vty_out(vty, "%s/%d\n", + inet_ntop(pp->family, + &pp->u.prefix, pbuf, + SU_ADDRSTRLEN), + pp->prefixlen); + } + + vty_out(vty, "\n"); + rmap_index_list = (struct list *)rn->info; + if (!rmap_index_list + || !listcount(rmap_index_list)) + vty_out(vty, "%*s%s\n", len, "", "-"); + else + for (ALL_LIST_ELEMENTS(rmap_index_list, + ln, nln, + index)) { + vty_out(vty, "%*s%s seq %d\n", + len, "", + index->map->name, + index->pref); + } + vty_out(vty, "\n"); + } + } + + rm_pfx_tbl6 = rmap->ipv6_prefix_table; + if (rm_pfx_tbl6) { + vty_out(vty, "\n%s%43s%s\n", "IPv6 Prefix", "", + "Route-map Index List"); + vty_out(vty, "%s%39s%s\n", "_______________", "", + "____________________"); + for (rn = route_top(rm_pfx_tbl6); rn; + rn = route_next(rn)) { + p = &rn->p; + + vty_out(vty, " %s/%d (%d)\n", + inet_ntop(p->family, &p->u.prefix, buf, + SU_ADDRSTRLEN), + p->prefixlen, rn->lock); + + vty_out(vty, "(P) "); + prn = rn->parent; + if (prn) { + pp = &prn->p; + vty_out(vty, "%s/%d\n", + inet_ntop(pp->family, + &pp->u.prefix, pbuf, + SU_ADDRSTRLEN), + pp->prefixlen); + } + + vty_out(vty, "\n"); + rmap_index_list = (struct list *)rn->info; + if (!rmap_index_list + || !listcount(rmap_index_list)) + vty_out(vty, "%*s%s\n", len, "", "-"); + else + for (ALL_LIST_ELEMENTS(rmap_index_list, + ln, nln, + index)) { + vty_out(vty, "%*s%s seq %d\n", + len, "", + index->map->name, + index->pref); + } + vty_out(vty, "\n"); + } + } + } + + vty_out(vty, "\n"); + return CMD_SUCCESS; +} + /* Initialization of route map vector. */ void route_map_init(void) { @@ -2237,4 +3256,9 @@ void route_map_init(void) install_element(ENABLE_NODE, &debug_rmap_cmd); install_element(ENABLE_NODE, &no_debug_rmap_cmd); + + install_element(RMAP_NODE, &routemap_optimization_cmd); + install_element(RMAP_NODE, &no_routemap_optimization_cmd); + + install_element(ENABLE_NODE, &show_route_map_pfx_tbl_cmd); } diff --git a/lib/routemap.h b/lib/routemap.h index 05c958967c..e8cab64b47 100644 --- a/lib/routemap.h +++ b/lib/routemap.h @@ -25,6 +25,8 @@ #include "memory.h" #include "qobj.h" #include "vty.h" +#include "lib/plist.h" +#include "lib/plist_int.h" #ifdef __cplusplus extern "C" { @@ -220,6 +222,7 @@ struct route_map { /* Maintain update info */ bool to_be_processed; /* True if modification isn't acted on yet */ bool deleted; /* If 1, then this node will be deleted */ + bool optimization_disabled; /* How many times have we applied this route-map */ uint64_t applied; @@ -228,6 +231,12 @@ struct route_map { /* Counter to track active usage of this route-map */ uint16_t use_count; + /* Tables to maintain IPv4 and IPv6 prefixes from + * the prefix-list match clause. + */ + struct route_table *ipv4_prefix_table; + struct route_table *ipv6_prefix_table; + QOBJ_FIELDS }; DECLARE_QOBJ_TYPE(route_map) @@ -310,7 +319,10 @@ extern void route_map_upd8_dependency(route_map_event_t type, const char *arg, const char *rmap_name); extern void route_map_notify_dependencies(const char *affected_name, route_map_event_t event); - +extern void +route_map_notify_pentry_dependencies(const char *affected_name, + struct prefix_list_entry *pentry, + route_map_event_t event); extern int generic_match_add(struct vty *vty, struct route_map_index *index, const char *command, const char *arg, route_map_event_t type); diff --git a/lib/routemap_cli.c b/lib/routemap_cli.c index 7023710564..5b03b5266f 100644 --- a/lib/routemap_cli.c +++ b/lib/routemap_cli.c @@ -1064,7 +1064,6 @@ void route_map_cli_init(void) install_element(CONFIG_NODE, &no_route_map_all_cmd); /* Install the on-match stuff */ - install_element(RMAP_NODE, &route_map_cmd); install_element(RMAP_NODE, &rmap_onmatch_next_cmd); install_element(RMAP_NODE, &no_rmap_onmatch_next_cmd); install_element(RMAP_NODE, &rmap_onmatch_goto_cmd); diff --git a/lib/routemap_northbound.c b/lib/routemap_northbound.c index 68b112b09a..69cebbd2a1 100644 --- a/lib/routemap_northbound.c +++ b/lib/routemap_northbound.c @@ -221,8 +221,7 @@ static int lib_route_map_entry_description_modify(enum nb_event event, break; case NB_EV_APPLY: rmi = nb_running_get_entry(dnode, NULL, true); - if (rmi->description != NULL) - XFREE(MTYPE_TMP, rmi->description); + XFREE(MTYPE_TMP, rmi->description); rmi->description = resource->ptr; break; } @@ -243,9 +242,7 @@ static int lib_route_map_entry_description_destroy(enum nb_event event, break; case NB_EV_APPLY: rmi = nb_running_get_entry(dnode, NULL, true); - if (rmi->description != NULL) - XFREE(MTYPE_TMP, rmi->description); - rmi->description = NULL; + XFREE(MTYPE_TMP, rmi->description); break; } diff --git a/lib/seqlock.c b/lib/seqlock.c index c05ec19db4..77673146ea 100644 --- a/lib/seqlock.c +++ b/lib/seqlock.c @@ -165,7 +165,7 @@ bool seqlock_timedwait(struct seqlock *sqlo, seqlock_val_t val, /* * ABS_REALTIME - used on NetBSD, Solaris and OSX */ -#if TIME_ABS_REALTIME +#ifdef TIME_ABS_REALTIME #define time_arg1 &abs_rt #define time_arg2 NULL #define time_prep @@ -187,7 +187,7 @@ bool seqlock_timedwait(struct seqlock *sqlo, seqlock_val_t val, /* * RELATIVE - used on OpenBSD (might get a patch to get absolute monotime) */ -#elif TIME_RELATIVE +#elif defined(TIME_RELATIVE) struct timespec reltime; #define time_arg1 abs_monotime_limit @@ -254,7 +254,7 @@ bool seqlock_check(struct seqlock *sqlo, seqlock_val_t val) cur = atomic_load_explicit(&sqlo->pos, memory_order_relaxed); if (!(cur & SEQLOCK_HELD)) - return 1; + return true; cur = SEQLOCK_VAL(cur) - val - 1; assert(cur < 0x40000000 || cur > 0xc0000000); return cur < 0x80000000; diff --git a/lib/skiplist.c b/lib/skiplist.c index 6efa2c362d..d955c6eb9e 100644 --- a/lib/skiplist.c +++ b/lib/skiplist.c @@ -211,12 +211,12 @@ int skiplist_insert(register struct skiplist *l, register void *key, q = newNodeOfLevel(k); q->key = key; q->value = value; -#if SKIPLIST_0TIMER_DEBUG +#ifdef SKIPLIST_0TIMER_DEBUG q->flags = SKIPLIST_NODE_FLAG_INSERTED; /* debug */ #endif ++(l->stats->forward[k]); -#if SKIPLIST_DEBUG +#ifdef SKIPLIST_DEBUG zlog_debug("%s: incremented stats @%p:%d, now %ld", __func__, l, k, l->stats->forward[k] - (struct skiplistnode *)NULL); #endif @@ -281,7 +281,7 @@ int skiplist_delete(register struct skiplist *l, register void *key, /* * found node to delete */ -#if SKIPLIST_0TIMER_DEBUG +#ifdef SKIPLIST_0TIMER_DEBUG q->flags &= ~SKIPLIST_NODE_FLAG_INSERTED; #endif /* @@ -300,7 +300,7 @@ int skiplist_delete(register struct skiplist *l, register void *key, p->forward[k] = q->forward[k]; } --(l->stats->forward[k - 1]); -#if SKIPLIST_DEBUG +#ifdef SKIPLIST_DEBUG zlog_debug("%s: decremented stats @%p:%d, now %ld", __func__, l, k - 1, l->stats->forward[k - 1] @@ -378,7 +378,7 @@ int skiplist_next_value(register struct skiplist *l, /* in */ void **valuePointer, /* in/out */ void **cursor) /* in/out */ { - register int k, m; + register int k; register struct skiplistnode *p, *q; CHECKLAST(l); @@ -389,7 +389,7 @@ int skiplist_next_value(register struct skiplist *l, /* in */ if (!cursor || !*cursor) { p = l->header; - k = m = l->level; + k = l->level; /* * Find matching key @@ -549,7 +549,7 @@ int skiplist_delete_first(register struct skiplist *l) } } -#if SKIPLIST_0TIMER_DEBUG +#ifdef SKIPLIST_0TIMER_DEBUG q->flags &= ~SKIPLIST_NODE_FLAG_INSERTED; #endif /* @@ -561,7 +561,7 @@ int skiplist_delete_first(register struct skiplist *l) } --(l->stats->forward[nodelevel]); -#if SKIPLIST_DEBUG +#ifdef SKIPLIST_DEBUG zlog_debug("%s: decremented stats @%p:%d, now %ld", __func__, l, nodelevel, l->stats->forward[nodelevel] - (struct skiplistnode *)NULL); diff --git a/lib/sockopt.c b/lib/sockopt.c index d6c88c0aff..45d9008796 100644 --- a/lib/sockopt.c +++ b/lib/sockopt.c @@ -90,12 +90,11 @@ int getsockopt_so_recvbuf(const int sock) static void *getsockopt_cmsg_data(struct msghdr *msgh, int level, int type) { struct cmsghdr *cmsg; - void *ptr = NULL; for (cmsg = CMSG_FIRSTHDR(msgh); cmsg != NULL; cmsg = CMSG_NXTHDR(msgh, cmsg)) if (cmsg->cmsg_level == level && cmsg->cmsg_type == type) - return (ptr = CMSG_DATA(cmsg)); + return CMSG_DATA(cmsg); return NULL; } @@ -684,7 +683,7 @@ int sockopt_tcp_signature_ext(int sock, union sockunion *su, uint16_t prefixlen, #endif /* GNU_LINUX */ if ((ret = setsockopt(sock, IPPROTO_TCP, optname, &md5sig, - sizeof md5sig)) + sizeof(md5sig))) < 0) { /* ENOENT is harmless. It is returned when we clear a password for which diff --git a/lib/sockopt.h b/lib/sockopt.h index 59d8a65964..4081e6a45b 100644 --- a/lib/sockopt.h +++ b/lib/sockopt.h @@ -39,7 +39,7 @@ extern int setsockopt_ipv6_hoplimit(int, int); extern int setsockopt_ipv6_multicast_loop(int, int); extern int setsockopt_ipv6_tclass(int, int); -#define SOPT_SIZE_CMSG_PKTINFO_IPV6() (sizeof (struct in6_pktinfo)); +#define SOPT_SIZE_CMSG_PKTINFO_IPV6() (sizeof(struct in6_pktinfo)); /* * Size defines for control messages used to get ifindex. We define @@ -49,7 +49,7 @@ extern int setsockopt_ipv6_tclass(int, int); */ #if defined(IP_PKTINFO) /* Linux in_pktinfo. */ -#define SOPT_SIZE_CMSG_PKTINFO_IPV4() (CMSG_SPACE(sizeof (struct in_pktinfo))) +#define SOPT_SIZE_CMSG_PKTINFO_IPV4() (CMSG_SPACE(sizeof(struct in_pktinfo))) /* XXX This should perhaps be defined even if IP_PKTINFO is not. */ #define SOPT_SIZE_CMSG_PKTINFO(af) \ ((af == AF_INET) ? SOPT_SIZE_CMSG_PKTINFO_IPV4() \ @@ -60,9 +60,9 @@ extern int setsockopt_ipv6_tclass(int, int); /* BSD/Solaris */ #if defined(SUNOS_5) -#define SOPT_SIZE_CMSG_RECVIF_IPV4() (sizeof (uint_t)) +#define SOPT_SIZE_CMSG_RECVIF_IPV4() (sizeof(uint_t)) #else -#define SOPT_SIZE_CMSG_RECVIF_IPV4() (sizeof (struct sockaddr_dl)) +#define SOPT_SIZE_CMSG_RECVIF_IPV4() (sizeof(struct sockaddr_dl)) #endif /* SUNOS_5 */ #endif /* IP_RECVIF */ @@ -72,7 +72,7 @@ extern int setsockopt_ipv6_tclass(int, int); #elif defined(SOPT_SIZE_CMSG_RECVIF_IPV4) #define SOPT_SIZE_CMSG_IFINDEX_IPV4() SOPT_SIZE_CMSG_RECVIF_IPV4() #else /* Nothing available */ -#define SOPT_SIZE_CMSG_IFINDEX_IPV4() (sizeof (char *)) +#define SOPT_SIZE_CMSG_IFINDEX_IPV4() (sizeof(char *)) #endif /* SOPT_SIZE_CMSG_IFINDEX_IPV4 */ #define SOPT_SIZE_CMSG_IFINDEX(af) \ diff --git a/lib/sockunion.c b/lib/sockunion.c index e9c418fdf2..63d8a8c69b 100644 --- a/lib/sockunion.c +++ b/lib/sockunion.c @@ -214,7 +214,7 @@ enum connect_result sockunion_connect(int fd, const union sockunion *peersu, if (errno != EINPROGRESS) { char str[SU_ADDRSTRLEN]; zlog_info("can't connect to %s fd %d : %s", - sockunion_log(&su, str, sizeof str), fd, + sockunion_log(&su, str, sizeof(str)), fd, safe_strerror(errno)); return connect_error; } @@ -518,8 +518,8 @@ union sockunion *sockunion_getsockname(int fd) } name; union sockunion *su; - memset(&name, 0, sizeof name); - len = sizeof name; + memset(&name, 0, sizeof(name)); + len = sizeof(name); ret = getsockname(fd, (struct sockaddr *)&name, &len); if (ret < 0) { @@ -556,8 +556,8 @@ union sockunion *sockunion_getpeername(int fd) } name; union sockunion *su; - memset(&name, 0, sizeof name); - len = sizeof name; + memset(&name, 0, sizeof(name)); + len = sizeof(name); ret = getpeername(fd, (struct sockaddr *)&name, &len); if (ret < 0) { flog_err(EC_LIB_SOCKET, "Can't get remote address and port: %s", diff --git a/lib/stream.h b/lib/stream.h index c0d25e0579..36c65afa3c 100644 --- a/lib/stream.h +++ b/lib/stream.h @@ -110,7 +110,7 @@ struct stream { size_t getp; /* next get position */ size_t endp; /* last valid data position */ size_t size; /* size of data segment */ - unsigned char data[0]; /* data pointer */ + unsigned char data[]; /* data pointer */ }; /* First in first out queue structure. */ diff --git a/lib/systemd.c b/lib/systemd.c index 81b0400ab9..c5cc3aa447 100644 --- a/lib/systemd.c +++ b/lib/systemd.c @@ -114,8 +114,10 @@ void systemd_send_started(struct thread_master *m, int the_process) systemd_master = m; systemd_send_information("READY=1"); - if (wsecs != 0) + if (wsecs != 0) { + systemd_send_information("WATCHDOG=1"); thread_add_timer(m, systemd_send_watchdog, m, wsecs, NULL); + } } void systemd_send_status(const char *status) diff --git a/lib/thread.c b/lib/thread.c index 651d26dfb2..2217a60f0a 100644 --- a/lib/thread.c +++ b/lib/thread.c @@ -171,7 +171,7 @@ static void cpu_record_print(struct vty *vty, uint8_t filter) struct thread_master *m; struct listnode *ln; - memset(&tmp, 0, sizeof tmp); + memset(&tmp, 0, sizeof(tmp)); tmp.funcname = "TOTAL"; tmp.types = filter; @@ -493,8 +493,7 @@ void vrf_init(int (*create)(struct vrf *), int (*enable)(struct vrf *), /* initialise NS, in case VRF backend if NETNS */ ns_init(); if (debug_vrf) - zlog_debug("%s: Initializing VRF subsystem", - __PRETTY_FUNCTION__); + zlog_debug("%s: Initializing VRF subsystem", __func__); vrf_master.vrf_new_hook = create; vrf_master.vrf_enable_hook = enable; @@ -535,8 +534,7 @@ void vrf_terminate(void) struct vrf *vrf; if (debug_vrf) - zlog_debug("%s: Shutting down vrf subsystem", - __PRETTY_FUNCTION__); + zlog_debug("%s: Shutting down vrf subsystem", __func__); while (!RB_EMPTY(vrf_id_head, &vrfs_by_id)) { vrf = RB_ROOT(vrf_id_head, &vrfs_by_id); @@ -114,6 +114,8 @@ extern struct vrf *vrf_get(vrf_id_t, const char *); extern const char *vrf_id_to_name(vrf_id_t vrf_id); extern vrf_id_t vrf_name_to_id(const char *); +#define VRF_LOGNAME(V) V ? V->name : "Unknown" + #define VRF_GET_ID(V, NAME, USE_JSON) \ do { \ struct vrf *_vrf; \ diff --git a/lib/wheel.c b/lib/wheel.c index 8e479c931b..f5e5cc52c3 100644 --- a/lib/wheel.c +++ b/lib/wheel.c @@ -47,8 +47,8 @@ static int wheel_timer_thread_helper(struct thread *t) curr_slot = wheel->curr_slot % wheel->slots; if (debug_timer_wheel) - zlog_debug("%s: Wheel Slot: %lld(%lld) count: %d", - __PRETTY_FUNCTION__, wheel->curr_slot, curr_slot, + zlog_debug("%s: Wheel Slot: %lld(%lld) count: %d", __func__, + wheel->curr_slot, curr_slot, listcount(wheel->wheel_slot_lists[curr_slot])); for (ALL_LIST_ELEMENTS(wheel->wheel_slot_lists[curr_slot], node, @@ -146,8 +146,8 @@ int wheel_add_item(struct timer_wheel *wheel, void *item) slot = (*wheel->slot_key)(item); if (debug_timer_wheel) - zlog_debug("%s: Inserting %p: %lld %lld", __PRETTY_FUNCTION__, - item, slot, slot % wheel->slots); + zlog_debug("%s: Inserting %p: %lld %lld", __func__, item, slot, + slot % wheel->slots); listnode_add(wheel->wheel_slot_lists[slot % wheel->slots], item); return 0; @@ -160,8 +160,8 @@ int wheel_remove_item(struct timer_wheel *wheel, void *item) slot = (*wheel->slot_key)(item); if (debug_timer_wheel) - zlog_debug("%s: Removing %p: %lld %lld", __PRETTY_FUNCTION__, - item, slot, slot % wheel->slots); + zlog_debug("%s: Removing %p: %lld %lld", __func__, item, slot, + slot % wheel->slots); listnode_delete(wheel->wheel_slot_lists[slot % wheel->slots], item); return 0; diff --git a/lib/zclient.c b/lib/zclient.c index b0d2ea43a2..eac6c7081d 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -236,9 +236,8 @@ int zclient_socket_connect(struct zclient *zclient) ret = connect(sock, (struct sockaddr *)&zclient_addr, zclient_addr_len); if (ret < 0) { if (zclient_debug) - zlog_debug("%s connect failure: %d(%s)", - __PRETTY_FUNCTION__, errno, - safe_strerror(errno)); + zlog_debug("%s connect failure: %d(%s)", __func__, + errno, safe_strerror(errno)); close(sock); return -1; } @@ -958,7 +957,7 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api) if (api->type >= ZEBRA_ROUTE_MAX) { flog_err(EC_LIB_ZAPI_ENCODE, "%s: Specified route type (%u) is not a legal value\n", - __PRETTY_FUNCTION__, api->type); + __func__, api->type); return -1; } stream_putc(s, api->type); @@ -970,7 +969,7 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api) if (api->safi < SAFI_UNICAST || api->safi >= SAFI_MAX) { flog_err(EC_LIB_ZAPI_ENCODE, "%s: Specified route SAFI (%u) is not a legal value\n", - __PRETTY_FUNCTION__, api->safi); + __func__, api->safi); return -1; } stream_putc(s, api->safi); @@ -1122,7 +1121,7 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api) if (api->type >= ZEBRA_ROUTE_MAX) { flog_err(EC_LIB_ZAPI_ENCODE, "%s: Specified route type: %d is not a legal value\n", - __PRETTY_FUNCTION__, api->type); + __func__, api->type); return -1; } @@ -1133,7 +1132,7 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api) if (api->safi < SAFI_UNICAST || api->safi >= SAFI_MAX) { flog_err(EC_LIB_ZAPI_ENCODE, "%s: Specified route SAFI (%u) is not a legal value\n", - __PRETTY_FUNCTION__, api->safi); + __func__, api->safi); return -1; } @@ -1146,7 +1145,7 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api) flog_err( EC_LIB_ZAPI_ENCODE, "%s: V4 prefixlen is %d which should not be more than 32", - __PRETTY_FUNCTION__, api->prefix.prefixlen); + __func__, api->prefix.prefixlen); return -1; } break; @@ -1155,14 +1154,14 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api) flog_err( EC_LIB_ZAPI_ENCODE, "%s: v6 prefixlen is %d which should not be more than 128", - __PRETTY_FUNCTION__, api->prefix.prefixlen); + __func__, api->prefix.prefixlen); return -1; } break; default: flog_err(EC_LIB_ZAPI_ENCODE, - "%s: Specified family %d is not v4 or v6", - __PRETTY_FUNCTION__, api->prefix.family); + "%s: Specified family %d is not v4 or v6", __func__, + api->prefix.family); return -1; } STREAM_GET(&api->prefix.u.prefix, s, PSIZE(api->prefix.prefixlen)); @@ -1174,7 +1173,7 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api) flog_err( EC_LIB_ZAPI_ENCODE, "%s: SRC Prefix prefixlen received: %d is too large", - __PRETTY_FUNCTION__, api->src_prefix.prefixlen); + __func__, api->src_prefix.prefixlen); return -1; } STREAM_GET(&api->src_prefix.prefix, s, @@ -1185,7 +1184,7 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api) flog_err( EC_LIB_ZAPI_ENCODE, "%s: SRC prefix specified in some manner that makes no sense", - __PRETTY_FUNCTION__); + __func__); return -1; } } @@ -1309,8 +1308,7 @@ bool zapi_rule_notify_decode(struct stream *s, uint32_t *seqno, STREAM_GETL(s, ifi); if (zclient_debug) - zlog_debug("%s: %u %u %u %u", __PRETTY_FUNCTION__, seq, prio, - uni, ifi); + zlog_debug("%s: %u %u %u %u", __func__, seq, prio, uni, ifi); *seqno = seq; *priority = prio; *unique = uni; @@ -1332,7 +1330,7 @@ bool zapi_ipset_notify_decode(struct stream *s, uint32_t *unique, STREAM_GETL(s, uni); if (zclient_debug) - zlog_debug("%s: %u", __PRETTY_FUNCTION__, uni); + zlog_debug("%s: %u", __func__, uni); *unique = uni; return true; @@ -1354,7 +1352,7 @@ bool zapi_ipset_entry_notify_decode(struct stream *s, uint32_t *unique, STREAM_GET(ipset_name, s, ZEBRA_IPSET_NAME_SIZE); if (zclient_debug) - zlog_debug("%s: %u", __PRETTY_FUNCTION__, uni); + zlog_debug("%s: %u", __func__, uni); *unique = uni; return true; @@ -1374,7 +1372,7 @@ bool zapi_iptable_notify_decode(struct stream *s, STREAM_GETL(s, uni); if (zclient_debug) - zlog_debug("%s: %u", __PRETTY_FUNCTION__, uni); + zlog_debug("%s: %u", __func__, uni); *unique = uni; return true; @@ -1978,7 +1976,7 @@ struct connected *zebra_interface_address_read(int type, struct stream *s, "warning: interface %s address %s with peer flag set, but no peer address!", ifp->name, prefix2str(ifc->address, buf, - sizeof buf)); + sizeof(buf))); UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER); } } @@ -2664,8 +2662,7 @@ int zapi_labels_decode(struct stream *s, struct zapi_labels *zl) if (zl->route.prefix.prefixlen > IPV4_MAX_BITLEN) { zlog_debug( "%s: Specified prefix length %d is greater than a v4 address can support", - __PRETTY_FUNCTION__, - zl->route.prefix.prefixlen); + __func__, zl->route.prefix.prefixlen); return -1; } STREAM_GET(&zl->route.prefix.u.prefix4.s_addr, s, @@ -2675,8 +2672,7 @@ int zapi_labels_decode(struct stream *s, struct zapi_labels *zl) if (zl->route.prefix.prefixlen > IPV6_MAX_BITLEN) { zlog_debug( "%s: Specified prefix length %d is greater than a v6 address can support", - __PRETTY_FUNCTION__, - zl->route.prefix.prefixlen); + __func__, zl->route.prefix.prefixlen); return -1; } STREAM_GET(&zl->route.prefix.u.prefix6, s, psize); @@ -2684,7 +2680,7 @@ int zapi_labels_decode(struct stream *s, struct zapi_labels *zl) default: flog_err(EC_LIB_ZAPI_ENCODE, "%s: Specified family %u is not v4 or v6", - __PRETTY_FUNCTION__, zl->route.prefix.family); + __func__, zl->route.prefix.family); return -1; } |
