diff options
102 files changed, 1275 insertions, 341 deletions
diff --git a/babeld/babel_interface.c b/babeld/babel_interface.c index 5d66e51fa7..772aec1234 100644 --- a/babeld/babel_interface.c +++ b/babeld/babel_interface.c @@ -972,7 +972,7 @@ show_babel_routes_sub(struct babel_route *route, struct vty *vty, channels[0] = '\0'; else { int k, j = 0; - snprintf(channels, 100, " chan ("); + snprintf(channels, sizeof(channels), " chan ("); j = strlen(channels); for(k = 0; k < DIVERSITY_HOPS; k++) { if(route->channels[k] == 0) diff --git a/bgpd/bgp_clist.c b/bgpd/bgp_clist.c index 28b22997ed..5b3908442c 100644 --- a/bgpd/bgp_clist.c +++ b/bgpd/bgp_clist.c @@ -546,24 +546,20 @@ static char *lcommunity_str_get(struct lcommunity *lcom, int i) uint32_t localdata2; char *str; const uint8_t *ptr; - char *pnt; ptr = lcom->val + (i * LCOMMUNITY_SIZE); memcpy(&lcomval, ptr, LCOMMUNITY_SIZE); /* Allocate memory. 48 bytes taken off bgp_lcommunity.c */ - str = pnt = XMALLOC(MTYPE_LCOMMUNITY_STR, 48); - ptr = (uint8_t *)lcomval.val; ptr = ptr_get_be32(ptr, &globaladmin); ptr = ptr_get_be32(ptr, &localdata1); ptr = ptr_get_be32(ptr, &localdata2); (void)ptr; /* consume value */ - sprintf(pnt, "%u:%u:%u", globaladmin, localdata1, localdata2); - pnt += strlen(pnt); - *pnt = '\0'; + str = XMALLOC(MTYPE_LCOMMUNITY_STR, 48); + snprintf(str, 48, "%u:%u:%u", globaladmin, localdata1, localdata2); return str; } diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c index f503c1b18e..396b7ba702 100644 --- a/bgpd/bgp_debug.c +++ b/bgpd/bgp_debug.c @@ -570,34 +570,39 @@ static void bgp_debug_print_evpn_prefix(struct vty *vty, const char *desc, if (p->u.prefix_evpn.route_type == BGP_EVPN_MAC_IP_ROUTE) { if (is_evpn_prefix_ipaddr_none((struct prefix_evpn *)p)) { - sprintf(evpn_desc, "l2vpn evpn type macip mac %s", - prefix_mac2str( - &p->u.prefix_evpn.macip_addr.mac, - buf2, sizeof(buf2))); + snprintf( + evpn_desc, sizeof(evpn_desc), + "l2vpn evpn type macip mac %s", + prefix_mac2str(&p->u.prefix_evpn.macip_addr.mac, + buf2, sizeof(buf2))); } else { uint8_t family = is_evpn_prefix_ipaddr_v4( (struct prefix_evpn *)p) ? AF_INET : AF_INET6; - sprintf(evpn_desc, "l2vpn evpn type macip mac %s ip %s", - prefix_mac2str( - &p->u.prefix_evpn.macip_addr.mac, - buf2, sizeof(buf2)), - inet_ntop(family, + snprintf( + evpn_desc, sizeof(evpn_desc), + "l2vpn evpn type macip mac %s ip %s", + prefix_mac2str(&p->u.prefix_evpn.macip_addr.mac, + buf2, sizeof(buf2)), + inet_ntop( + family, &p->u.prefix_evpn.macip_addr.ip.ip.addr, buf, PREFIX2STR_BUFFER)); } } else if (p->u.prefix_evpn.route_type == BGP_EVPN_IMET_ROUTE) { - sprintf(evpn_desc, "l2vpn evpn type multicast ip %s", - inet_ntoa(p->u.prefix_evpn.imet_addr.ip.ipaddr_v4)); + snprintf(evpn_desc, sizeof(evpn_desc), + "l2vpn evpn type multicast ip %s", + inet_ntoa(p->u.prefix_evpn.imet_addr.ip.ipaddr_v4)); } else if (p->u.prefix_evpn.route_type == BGP_EVPN_IP_PREFIX_ROUTE) { uint8_t family = is_evpn_prefix_ipaddr_v4( (struct prefix_evpn *)p) ? AF_INET : AF_INET6; - sprintf(evpn_desc, "l2vpn evpn type prefix ip %s/%d", - inet_ntop(family, - &p->u.prefix_evpn.prefix_addr.ip.ip.addr, buf, - PREFIX2STR_BUFFER), - p->u.prefix_evpn.prefix_addr.ip_prefix_length); + snprintf(evpn_desc, sizeof(evpn_desc), + "l2vpn evpn type prefix ip %s/%d", + inet_ntop(family, + &p->u.prefix_evpn.prefix_addr.ip.ip.addr, + buf, PREFIX2STR_BUFFER), + p->u.prefix_evpn.prefix_addr.ip_prefix_length); } vty_out(vty, "%s %s\n", desc, evpn_desc); @@ -2592,12 +2597,14 @@ const char *bgp_debug_rdpfxpath2str(afi_t afi, safi_t safi, char tag_buf2[20]; bgp_evpn_label2str(label, num_labels, tag_buf2, 20); - sprintf(tag_buf, " label %s", tag_buf2); + snprintf(tag_buf, sizeof(tag_buf), " label %s", + tag_buf2); } else { uint32_t label_value; label_value = decode_label(label); - sprintf(tag_buf, " label %u", label_value); + snprintf(tag_buf, sizeof(tag_buf), " label %u", + label_value); } } diff --git a/bgpd/bgp_dump.c b/bgpd/bgp_dump.c index a79c5e0da0..c87849ad71 100644 --- a/bgpd/bgp_dump.c +++ b/bgpd/bgp_dump.c @@ -115,7 +115,8 @@ static FILE *bgp_dump_open_file(struct bgp_dump *bgp_dump) localtime_r(&clock, &tm); if (bgp_dump->filename[0] != DIRECTORY_SEP) { - sprintf(fullpath, "%s/%s", vty_get_cwd(), bgp_dump->filename); + snprintf(fullpath, sizeof(fullpath), "%s/%s", vty_get_cwd(), + bgp_dump->filename); ret = strftime(realpath, MAXPATHLEN, fullpath, &tm); } else ret = strftime(realpath, MAXPATHLEN, bgp_dump->filename, &tm); @@ -786,32 +787,6 @@ static struct cmd_node bgp_dump_node = { .config_write = config_write_bgp_dump, }; -#if 0 -char * -config_time2str (unsigned int interval) -{ - static char buf[BUFSIZ]; - - buf[0] = '\0'; - - if (interval / 3600) - { - sprintf (buf, "%dh", interval / 3600); - interval %= 3600; - } - if (interval / 60) - { - sprintf (buf + strlen (buf), "%dm", interval /60); - interval %= 60; - } - if (interval) - { - sprintf (buf + strlen (buf), "%d", interval); - } - return buf; -} -#endif - static int config_write_bgp_dump(struct vty *vty) { if (bgp_dump_all.filename) { diff --git a/bgpd/bgp_ecommunity.c b/bgpd/bgp_ecommunity.c index fe09aab956..062a6477fa 100644 --- a/bgpd/bgp_ecommunity.c +++ b/bgpd/bgp_ecommunity.c @@ -652,13 +652,16 @@ static int ecommunity_lb_str(char *buf, size_t bufsz, const uint8_t *pnt) as |= (*pnt++); (void)ptr_get_be32(pnt, &bw); if (bw >= ONE_GBPS_BYTES) - sprintf(bps_buf, "%.3f Gbps", (float)(bw/ONE_GBPS_BYTES)); + snprintf(bps_buf, sizeof(bps_buf), "%.3f Gbps", + (float)(bw / ONE_GBPS_BYTES)); else if (bw >= ONE_MBPS_BYTES) - sprintf(bps_buf, "%.3f Mbps", (float)(bw/ONE_MBPS_BYTES)); + snprintf(bps_buf, sizeof(bps_buf), "%.3f Mbps", + (float)(bw / ONE_MBPS_BYTES)); else if (bw >= ONE_KBPS_BYTES) - sprintf(bps_buf, "%.3f Kbps", (float)(bw/ONE_KBPS_BYTES)); + snprintf(bps_buf, sizeof(bps_buf), "%.3f Kbps", + (float)(bw / ONE_KBPS_BYTES)); else - sprintf(bps_buf, "%u bps", bw * 8); + snprintf(bps_buf, sizeof(bps_buf), "%u bps", bw * 8); len = snprintf(buf, bufsz, "LB:%u:%u (%s)", as, bw, bps_buf); return len; diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index fadccc5026..a10686189d 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -5386,7 +5386,8 @@ void bgp_evpn_derive_auto_rd(struct bgp *bgp, struct bgpevpn *vpn) vpn->prd.family = AF_UNSPEC; vpn->prd.prefixlen = 64; - sprintf(buf, "%s:%hu", inet_ntoa(bgp->router_id), vpn->rd_id); + snprintf(buf, sizeof(buf), "%s:%hu", inet_ntoa(bgp->router_id), + vpn->rd_id); (void)str2prefix_rd(buf, &vpn->prd); UNSET_FLAG(vpn->flags, VNI_FLAG_RD_CFGD); } @@ -5529,7 +5530,8 @@ struct evpnes *bgp_evpn_es_new(struct bgp *bgp, bf_assign_index(bm->rd_idspace, es->rd_id); es->prd.family = AF_UNSPEC; es->prd.prefixlen = 64; - sprintf(buf, "%s:%hu", inet_ntoa(bgp->router_id), es->rd_id); + snprintf(buf, sizeof(buf), "%s:%hu", inet_ntoa(bgp->router_id), + es->rd_id); (void)str2prefix_rd(buf, &es->prd); /* Initialize the ES route table */ diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index d20012f5fd..85604d856d 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -87,7 +87,7 @@ static void display_vrf_import_rt(struct vty *vty, struct vrf_irt_node *irt, eas.as |= (*pnt++); ptr_get_be32(pnt, &eas.val); - snprintf(rt_buf, RT_ADDRSTRLEN, "%u:%u", eas.as, eas.val); + snprintf(rt_buf, sizeof(rt_buf), "%u:%u", eas.as, eas.val); if (json) json_object_string_add(json_rt, "rt", rt_buf); @@ -102,7 +102,7 @@ static void display_vrf_import_rt(struct vty *vty, struct vrf_irt_node *irt, eip.val = (*pnt++ << 8); eip.val |= (*pnt++); - snprintf(rt_buf, RT_ADDRSTRLEN, "%s:%u", inet_ntoa(eip.ip), + snprintf(rt_buf, sizeof(rt_buf), "%s:%u", inet_ntoa(eip.ip), eip.val); if (json) @@ -117,7 +117,7 @@ static void display_vrf_import_rt(struct vty *vty, struct vrf_irt_node *irt, eas.val = (*pnt++ << 8); eas.val |= (*pnt++); - snprintf(rt_buf, RT_ADDRSTRLEN, "%u:%u", eas.as, eas.val); + snprintf(rt_buf, sizeof(rt_buf), "%u:%u", eas.as, eas.val); if (json) json_object_string_add(json_rt, "rt", rt_buf); @@ -197,7 +197,7 @@ static void display_import_rt(struct vty *vty, struct irt_node *irt, eas.as |= (*pnt++); ptr_get_be32(pnt, &eas.val); - snprintf(rt_buf, RT_ADDRSTRLEN, "%u:%u", eas.as, eas.val); + snprintf(rt_buf, sizeof(rt_buf), "%u:%u", eas.as, eas.val); if (json) json_object_string_add(json_rt, "rt", rt_buf); @@ -212,7 +212,7 @@ static void display_import_rt(struct vty *vty, struct irt_node *irt, eip.val = (*pnt++ << 8); eip.val |= (*pnt++); - snprintf(rt_buf, RT_ADDRSTRLEN, "%s:%u", inet_ntoa(eip.ip), + snprintf(rt_buf, sizeof(rt_buf), "%s:%u", inet_ntoa(eip.ip), eip.val); if (json) @@ -227,7 +227,7 @@ static void display_import_rt(struct vty *vty, struct irt_node *irt, eas.val = (*pnt++ << 8); eas.val |= (*pnt++); - snprintf(rt_buf, RT_ADDRSTRLEN, "%u:%u", eas.as, eas.val); + snprintf(rt_buf, sizeof(rt_buf), "%u:%u", eas.as, eas.val); if (json) json_object_string_add(json_rt, "rt", rt_buf); @@ -841,7 +841,7 @@ static void show_vni_routes_hash(struct hash_bucket *bucket, void *arg) json_object *json_vni = NULL; char vni_str[VNI_STR_LEN]; - snprintf(vni_str, VNI_STR_LEN, "%d", vpn->vni); + snprintf(vni_str, sizeof(vni_str), "%d", vpn->vni); if (json) { json_vni = json_object_new_object(); json_object_int_add(json_vni, "vni", vpn->vni); @@ -880,7 +880,7 @@ static void show_l3vni_entry(struct vty *vty, struct bgp *bgp, /* if an l3vni is present in bgp it is live */ buf1[0] = '\0'; - sprintf(buf1, "*"); + snprintf(buf1, sizeof(buf1), "*"); if (json) { json_object_int_add(json_vni, "vni", bgp->l3vni); @@ -921,9 +921,11 @@ static void show_l3vni_entry(struct vty *vty, struct bgp *bgp, json_object_new_string(ecom_str)); } else { if (listcount(bgp->vrf_import_rtl) > 1) - sprintf(rt_buf, "%s, ...", ecom_str); + snprintf(rt_buf, sizeof(rt_buf), "%s, ...", + ecom_str); else - sprintf(rt_buf, "%s", ecom_str); + snprintf(rt_buf, sizeof(rt_buf), "%s", + ecom_str); vty_out(vty, " %-25s", rt_buf); } @@ -947,9 +949,11 @@ static void show_l3vni_entry(struct vty *vty, struct bgp *bgp, json_object_new_string(ecom_str)); } else { if (listcount(bgp->vrf_export_rtl) > 1) - sprintf(rt_buf, "%s, ...", ecom_str); + snprintf(rt_buf, sizeof(rt_buf), "%s, ...", + ecom_str); else - sprintf(rt_buf, "%s", ecom_str); + snprintf(rt_buf, sizeof(rt_buf), "%s", + ecom_str); vty_out(vty, " %-25s", rt_buf); } @@ -968,7 +972,7 @@ static void show_l3vni_entry(struct vty *vty, struct bgp *bgp, char vni_str[VNI_STR_LEN]; json_object_object_add(json_vni, "exportRTs", json_export_rtl); - snprintf(vni_str, VNI_STR_LEN, "%u", bgp->l3vni); + snprintf(vni_str, sizeof(vni_str), "%u", bgp->l3vni); json_object_object_add(json, vni_str, json_vni); } else { vty_out(vty, "\n"); @@ -1046,7 +1050,7 @@ static void show_vni_entry(struct hash_bucket *bucket, void *args[]) buf1[0] = '\0'; if (is_vni_live(vpn)) - sprintf(buf1, "*"); + snprintf(buf1, sizeof(buf1), "*"); if (json) { json_object_int_add(json_vni, "vni", vpn->vni); @@ -1098,9 +1102,11 @@ static void show_vni_entry(struct hash_bucket *bucket, void *args[]) json_object_new_string(ecom_str)); } else { if (listcount(vpn->import_rtl) > 1) - sprintf(rt_buf, "%s, ...", ecom_str); + snprintf(rt_buf, sizeof(rt_buf), "%s, ...", + ecom_str); else - sprintf(rt_buf, "%s", ecom_str); + snprintf(rt_buf, sizeof(rt_buf), "%s", + ecom_str); vty_out(vty, " %-25s", rt_buf); } @@ -1124,9 +1130,11 @@ static void show_vni_entry(struct hash_bucket *bucket, void *args[]) json_object_new_string(ecom_str)); } else { if (listcount(vpn->export_rtl) > 1) - sprintf(rt_buf, "%s, ...", ecom_str); + snprintf(rt_buf, sizeof(rt_buf), "%s, ...", + ecom_str); else - sprintf(rt_buf, "%s", ecom_str); + snprintf(rt_buf, sizeof(rt_buf), "%s", + ecom_str); vty_out(vty, " %-25s", rt_buf); } @@ -1145,7 +1153,7 @@ static void show_vni_entry(struct hash_bucket *bucket, void *args[]) char vni_str[VNI_STR_LEN]; json_object_object_add(json_vni, "exportRTs", json_export_rtl); - snprintf(vni_str, VNI_STR_LEN, "%u", vpn->vni); + snprintf(vni_str, sizeof(vni_str), "%u", vpn->vni); json_object_object_add(json, vni_str, json_vni); } else { vty_out(vty, "\n"); diff --git a/bgpd/bgp_flowspec.c b/bgpd/bgp_flowspec.c index 9554638735..17c41636de 100644 --- a/bgpd/bgp_flowspec.c +++ b/bgpd/bgp_flowspec.c @@ -108,7 +108,7 @@ int bgp_nlri_parse_flowspec(struct peer *peer, struct attr *attr, return BGP_NLRI_PARSE_ERROR_FLOWSPEC_IPV6_NOT_SUPPORTED; } - if (packet->length >= FLOWSPEC_NLRI_SIZELIMIT) { + if (packet->length >= FLOWSPEC_NLRI_SIZELIMIT_EXTENDED) { flog_err(EC_BGP_FLOWSPEC_PACKET, "BGP flowspec nlri length maximum reached (%u)", packet->length); @@ -124,7 +124,11 @@ int bgp_nlri_parse_flowspec(struct peer *peer, struct attr *attr, return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW; psize = *pnt++; - + if (psize >= FLOWSPEC_NLRI_SIZELIMIT) { + psize &= 0x0f; + psize = psize << 8; + psize |= *pnt++; + } /* When packet overflow occur return immediately. */ if (pnt + psize > lim) { flog_err( diff --git a/bgpd/bgp_flowspec_private.h b/bgpd/bgp_flowspec_private.h index dede4e03d3..cec244c165 100644 --- a/bgpd/bgp_flowspec_private.h +++ b/bgpd/bgp_flowspec_private.h @@ -20,6 +20,7 @@ #define _FRR_BGP_FLOWSPEC_PRIVATE_H #define FLOWSPEC_NLRI_SIZELIMIT 240 +#define FLOWSPEC_NLRI_SIZELIMIT_EXTENDED 4095 /* Flowspec raffic action bit*/ #define FLOWSPEC_TRAFFIC_ACTION_TERMINAL 1 diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index fdffe374c0..ce5747dc2b 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -1321,7 +1321,8 @@ int bgp_stop(struct peer *peer) if ((peer->status == OpenConfirm) || (peer->status == Established)) { /* ORF received prefix-filter pnt */ - sprintf(orf_name, "%s.%d.%d", peer->host, afi, safi); + snprintf(orf_name, sizeof(orf_name), "%s.%d.%d", + peer->host, afi, safi); prefix_bgp_orf_remove_all(afi, orf_name); } } diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 7137c1a784..29c03f4014 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -1960,8 +1960,8 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size) break; /* ORF prefix-list name */ - sprintf(name, "%s.%d.%d", peer->host, afi, - safi); + snprintf(name, sizeof(name), "%s.%d.%d", + peer->host, afi, safi); while (p_pnt < p_end) { /* If the ORF entry is malformed, want diff --git a/bgpd/bgp_pbr.c b/bgpd/bgp_pbr.c index ab134b15c4..535a45690b 100644 --- a/bgpd/bgp_pbr.c +++ b/bgpd/bgp_pbr.c @@ -605,13 +605,15 @@ static int bgp_pbr_validate_policy_route(struct bgp_pbr_entry_main *api) api->fragment[i].value != 4 && api->fragment[i].value != 8) { success = false; - sprintf(fail_str, + snprintf( + fail_str, sizeof(fail_str), "Value not valid (%d) for this implementation", api->fragment[i].value); } } } else - sprintf(fail_str, "too complex. ignoring"); + snprintf(fail_str, sizeof(fail_str), + "too complex. ignoring"); if (!success) { if (BGP_DEBUG(pbr, PBR)) zlog_debug("BGP: match fragment operation (%d) %s", diff --git a/bgpd/bgp_rd.c b/bgpd/bgp_rd.c index 66d64066c4..e7f1108057 100644 --- a/bgpd/bgp_rd.c +++ b/bgpd/bgp_rd.c @@ -210,6 +210,6 @@ void form_auto_rd(struct in_addr router_id, prd->family = AF_UNSPEC; prd->prefixlen = 64; - sprintf(buf, "%s:%hu", inet_ntoa(router_id), rd_id); + snprintf(buf, sizeof(buf), "%s:%hu", inet_ntoa(router_id), rd_id); (void)str2prefix_rd(buf, prd); } diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 18343231b5..78f077eaca 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -2264,7 +2264,7 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_node *rn, bgp_path_info_path_with_addpath_rx_str(new_select, path_buf); else - sprintf(path_buf, "NONE"); + snprintf(path_buf, sizeof(path_buf), "NONE"); zlog_debug( "%s: After path selection, newbest is %s oldbest was %s", pfx_buf, path_buf, @@ -7645,17 +7645,17 @@ void route_vty_out(struct vty *vty, const struct prefix *p, switch (af) { case AF_INET: - sprintf(nexthop, "%s", - inet_ntop(af, &attr->mp_nexthop_global_in, buf, - BUFSIZ)); + snprintf(nexthop, sizeof(nexthop), "%s", + inet_ntop(af, &attr->mp_nexthop_global_in, buf, + BUFSIZ)); break; case AF_INET6: - sprintf(nexthop, "%s", - inet_ntop(af, &attr->mp_nexthop_global, buf, - BUFSIZ)); + snprintf(nexthop, sizeof(nexthop), "%s", + inet_ntop(af, &attr->mp_nexthop_global, buf, + BUFSIZ)); break; default: - sprintf(nexthop, "?"); + snprintf(nexthop, sizeof(nexthop), "?"); break; } @@ -12366,7 +12366,7 @@ DEFUN (show_ip_bgp_neighbor_received_prefix_filter, } } - sprintf(name, "%s.%d.%d", peer->host, afi, safi); + snprintf(name, sizeof(name), "%s.%d.%d", peer->host, afi, safi); count = prefix_bgp_show_prefix_list(NULL, afi, name, uj); if (count) { if (!uj) @@ -13259,8 +13259,9 @@ static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp, inet_ntop(family, &p->u.prefix_evpn.prefix_addr.ip.ip.addr, local_buf, PREFIX_STRLEN); - sprintf(buf, "%s/%u", local_buf, - p->u.prefix_evpn.prefix_addr.ip_prefix_length); + snprintf(buf, sizeof(buf), "%s/%u", local_buf, + p->u.prefix_evpn.prefix_addr + .ip_prefix_length); } else { prefix2str(p, buf, sizeof(buf)); } diff --git a/bgpd/bgp_updgrp_adv.c b/bgpd/bgp_updgrp_adv.c index e40b3320ea..6399bc93aa 100644 --- a/bgpd/bgp_updgrp_adv.c +++ b/bgpd/bgp_updgrp_adv.c @@ -533,6 +533,14 @@ void bgp_adj_out_unset_subgroup(struct bgp_node *rn, if (adj->adv) bgp_advertise_clean_subgroup(subgrp, adj); + /* If default originate is enabled and the route is default + * route, do not send withdraw. This will prevent deletion of + * the default route at the peer. + */ + if (CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE) + && is_default_prefix(&rn->p)) + return; + if (adj->attr && withdraw) { /* We need advertisement structure. */ adj->adv = bgp_advertise_new(); @@ -636,12 +644,25 @@ void subgroup_announce_table(struct update_subgroup *subgrp, rn_p, &attr)) bgp_adj_out_set_subgroup(rn, subgrp, &attr, ri); - else + else { + /* If default originate is enabled for + * the peer, do not send explicit + * withdraw. This will prevent deletion + * of default route advertised through + * default originate + */ + if (CHECK_FLAG( + peer->af_flags[afi][safi], + PEER_FLAG_DEFAULT_ORIGINATE) + && is_default_prefix(&rn->p)) + break; + bgp_adj_out_unset_subgroup( rn, subgrp, 1, bgp_addpath_id_for_peer( peer, afi, safi, &ri->tx_addpath)); + } } } @@ -709,7 +730,9 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) struct prefix p; struct peer *from; struct bgp_node *rn; + struct bgp_path_info *pi; struct peer *peer; + struct bgp_adj_out *adj; route_map_result_t ret = RMAP_DENYMATCH; afi_t afi; safi_t safi; @@ -732,10 +755,6 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) attr.local_pref = bgp->default_local_pref; - memset(&p, 0, sizeof(p)); - p.family = afi2family(afi); - p.prefixlen = 0; - if ((afi == AFI_IP6) || peer_cap_enhe(peer, afi, safi)) { /* IPv6 global nexthop must be included. */ attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL; @@ -778,21 +797,40 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) } } + /* Check if the default route is in local BGP RIB which is + * installed through redistribute or network command + */ + memset(&p, 0, sizeof(p)); + p.family = afi2family(afi); + p.prefixlen = 0; + rn = bgp_afi_node_lookup(bgp->rib[afi][safi], afi, safi, &p, NULL); + if (withdraw) { + /* Withdraw the default route advertised using default + * originate + */ if (CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) subgroup_default_withdraw_packet(subgrp); UNSET_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE); + + /* If default route is present in the local RIB, advertise the + * route + */ + if (rn != NULL) { + for (pi = bgp_node_get_bgp_path_info(rn); pi; + pi = pi->next) { + if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) + if (subgroup_announce_check( + rn, pi, subgrp, &rn->p, + &attr)) + bgp_adj_out_set_subgroup( + rn, subgrp, &attr, pi); + } + } } else { if (!CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) { - if (CHECK_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN)) - bgp_attr_add_gshut_community(new_attr); - - SET_FLAG(subgrp->sflags, - SUBGRP_STATUS_DEFAULT_ORIGINATE); - subgroup_default_update_packet(subgrp, new_attr, from); - /* The 'neighbor x.x.x.x default-originate' default will * act as an * implicit withdraw for any previous UPDATEs sent for @@ -800,15 +838,37 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) * clear adj_out for the 0.0.0.0/0 prefix in the BGP * table. */ - memset(&p, 0, sizeof(p)); - p.family = afi2family(afi); - p.prefixlen = 0; - - rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, - &p, NULL); - bgp_adj_out_unset_subgroup( - rn, subgrp, 0, - BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE); + if (rn != NULL) { + /* Remove the adjacency for the previously + * advertised default route + */ + adj = adj_lookup( + rn, subgrp, + BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE); + if (adj != NULL) { + /* Clean up previous advertisement. */ + if (adj->adv) + bgp_advertise_clean_subgroup( + subgrp, adj); + + /* Remove from adjacency. */ + RB_REMOVE(bgp_adj_out_rb, &rn->adj_out, + adj); + + /* Free allocated information. */ + adj_free(adj); + + bgp_unlock_node(rn); + } + } + + /* Advertise the default route */ + if (CHECK_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN)) + bgp_attr_add_gshut_community(new_attr); + + SET_FLAG(subgrp->sflags, + SUBGRP_STATUS_DEFAULT_ORIGINATE); + subgroup_default_update_packet(subgrp, new_attr, from); } } diff --git a/bgpd/bgp_vpn.c b/bgpd/bgp_vpn.c index af632a1340..1b95d0656b 100644 --- a/bgpd/bgp_vpn.c +++ b/bgpd/bgp_vpn.c @@ -180,12 +180,14 @@ int show_adj_route_vpn(struct vty *vty, struct peer *peer, if (type == RD_TYPE_AS || type == RD_TYPE_AS4) - sprintf(rd_str, "%u:%d", - rd_as.as, rd_as.val); + snprintf(rd_str, sizeof(rd_str), + "%u:%d", rd_as.as, + rd_as.val); else if (type == RD_TYPE_IP) - sprintf(rd_str, "%s:%d", - inet_ntoa(rd_ip.ip), - rd_ip.val); + snprintf(rd_str, sizeof(rd_str), + "%s:%d", + inet_ntoa(rd_ip.ip), + rd_ip.val); json_object_string_add( json_routes, "rd", rd_str); diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index a356564813..f565fa1746 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -8619,8 +8619,9 @@ static void bgp_show_peer_reset(struct vty * vty, struct peer *peer, peer->notify.code, peer->notify.subcode); - sprintf(errorcodesubcode_hexstr, "%02X%02X", - peer->notify.code, peer->notify.subcode); + snprintf(errorcodesubcode_hexstr, + sizeof(errorcodesubcode_hexstr), "%02X%02X", + peer->notify.code, peer->notify.subcode); json_object_string_add(json_peer, "lastErrorCodeSubcode", errorcodesubcode_hexstr); @@ -8799,12 +8800,14 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, if (peer->hostname && CHECK_FLAG(bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) - sprintf(neighbor_buf, "%s%s(%s) ", - dn_flag, peer->hostname, - peer->host); + snprintf(neighbor_buf, + sizeof(neighbor_buf), + "%s%s(%s) ", dn_flag, + peer->hostname, peer->host); else - sprintf(neighbor_buf, "%s%s ", dn_flag, - peer->host); + snprintf(neighbor_buf, + sizeof(neighbor_buf), "%s%s ", + dn_flag, peer->host); len = strlen(neighbor_buf); @@ -9047,10 +9050,12 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, vty_out(vty, "EstdCnt DropCnt ResetTime Reason\n"); else vty_out(vty, - "V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd\n"); + "V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd PfxSnt\n"); } } + paf = peer_af_find(peer, afi, pfx_rcd_safi); + count++; /* Works for both failed & successful cases */ if (peer_dynamic_neighbor(peer)) @@ -9106,7 +9111,6 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, json_object_int_add(json_peer, "pfxRcd", peer->pcount[afi][pfx_rcd_safi]); - paf = peer_af_find(peer, afi, pfx_rcd_safi); if (paf && PAF_SUBGRP(paf)) json_object_int_add(json_peer, "pfxSnt", @@ -9192,7 +9196,7 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, peer_uptime(peer->uptime, timebuf, BGP_UPTIME_LEN, 0, NULL)); - if (peer->status == Established) + if (peer->status == Established) { if (peer->afc_recv[afi][safi]) vty_out(vty, " %12" PRIu32, peer->pcount @@ -9200,7 +9204,12 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, [pfx_rcd_safi]); else vty_out(vty, " NoNeg"); - else { + + if (paf && PAF_SUBGRP(paf)) + vty_out(vty, " %8" PRIu32, + (PAF_SUBGRP(paf)) + ->scount); + } else { if (CHECK_FLAG(peer->flags, PEER_FLAG_SHUTDOWN)) vty_out(vty, " Idle (Admin)"); else if (CHECK_FLAG( @@ -9211,6 +9220,8 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, vty_out(vty, " %12s", lookup_msg(bgp_status_msg, peer->status, NULL)); + + vty_out(vty, " %8" PRIu32, 0); } vty_out(vty, "\n"); } @@ -9857,7 +9868,8 @@ static void bgp_show_peer_gr_status(struct vty *vty, struct peer *p, { char buf[SU_ADDRSTRLEN] = {0}; char dn_flag[2] = {0}; - char neighborAddr[INET6_ADDRSTRLEN] = {0}; + /* '*' + v6 address of neighbor */ + char neighborAddr[INET6_ADDRSTRLEN + 1] = {0}; if (!p->conf_if && peer_dynamic_neighbor(p)) dn_flag[0] = '*'; @@ -9877,7 +9889,8 @@ static void bgp_show_peer_gr_status(struct vty *vty, struct peer *p, : sockunion2str(&p->su, buf, SU_ADDRSTRLEN)); } else { - sprintf(neighborAddr, "%s%s", dn_flag, p->host); + snprintf(neighborAddr, sizeof(neighborAddr), "%s%s", dn_flag, + p->host); if (use_json) json_object_string_add(json, "neighborAddr", @@ -9978,7 +9991,8 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi, else json_object_free(json_af); - sprintf(orf_pfx_name, "%s.%d.%d", p->host, afi, safi); + snprintf(orf_pfx_name, sizeof(orf_pfx_name), "%s.%d.%d", + p->host, afi, safi); orf_pfx_count = prefix_bgp_show_prefix_list( NULL, afi, orf_pfx_name, use_json); @@ -10274,7 +10288,8 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi, PEER_CAP_ORF_PREFIX_RM_OLD_RCV, use_json, NULL); } - sprintf(orf_pfx_name, "%s.%d.%d", p->host, afi, safi); + snprintf(orf_pfx_name, sizeof(orf_pfx_name), "%s.%d.%d", + p->host, afi, safi); orf_pfx_count = prefix_bgp_show_prefix_list( NULL, afi, orf_pfx_name, use_json); diff --git a/bgpd/rfapi/bgp_rfapi_cfg.c b/bgpd/rfapi/bgp_rfapi_cfg.c index dd21a83913..2bcef97fc3 100644 --- a/bgpd/rfapi/bgp_rfapi_cfg.c +++ b/bgpd/rfapi/bgp_rfapi_cfg.c @@ -4627,7 +4627,8 @@ void bgp_rfapi_show_summary(struct bgp *bgp, struct vty *vty) (hc->rfp_cfg.download_type == RFAPI_RFP_DOWNLOAD_PARTIAL ? "(default)" : "")); - sprintf(tmp, "%u seconds", hc->rfp_cfg.ftd_advertisement_interval); + snprintf(tmp, sizeof(tmp), "%u seconds", + hc->rfp_cfg.ftd_advertisement_interval); vty_out(vty, "%-39s %-19s %s\n", " Advertisement Interval:", tmp, (hc->rfp_cfg.ftd_advertisement_interval == RFAPI_RFP_CFG_DEFAULT_FTD_ADVERTISEMENT_INTERVAL diff --git a/bgpd/rfapi/rfapi.c b/bgpd/rfapi/rfapi.c index a0d8995a0f..d6b6a78f62 100644 --- a/bgpd/rfapi/rfapi.c +++ b/bgpd/rfapi/rfapi.c @@ -3506,7 +3506,7 @@ DEFUN (debug_rfapi_show_import, "\nLNI-based Ethernet Tables:\n"); first_l2 = 0; } - snprintf(buf, BUFSIZ, "L2VPN LNI=%u", lni); + snprintf(buf, sizeof(buf), "L2VPN LNI=%u", lni); rfapiShowImportTable( vty, buf, it->imported_vpn[AFI_L2VPN], 1); diff --git a/bgpd/rfapi/rfapi_vty.c b/bgpd/rfapi/rfapi_vty.c index 7a42e5aed9..67f6a6a0fc 100644 --- a/bgpd/rfapi/rfapi_vty.c +++ b/bgpd/rfapi/rfapi_vty.c @@ -1038,7 +1038,7 @@ static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream, * Prefix */ buf_pfx[0] = 0; - snprintf(buf_pfx, BUFSIZ, "%s/%d", + snprintf(buf_pfx, sizeof(buf_pfx), "%s/%d", rfapi_ntop(p->family, &p->u.prefix, buf_ntop, BUFSIZ), p->prefixlen); buf_pfx[BUFSIZ - 1] = 0; @@ -1049,7 +1049,7 @@ static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream, */ buf_un[0] = 0; if (!rfapiGetUnAddrOfVpnBi(bpi, &pfx_un)) { - snprintf(buf_un, BUFSIZ, "%s", + snprintf(buf_un, sizeof(buf_un), "%s", inet_ntop(pfx_un.family, &pfx_un.u.prefix, buf_ntop, BUFSIZ)); } @@ -1063,18 +1063,18 @@ static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream, if (tun_type == BGP_ENCAP_TYPE_MPLS) { /* MPLS carries un in nrli next hop (same as vn for IP tunnels) */ - snprintf(buf_un, BUFSIZ, "%s", + snprintf(buf_un, sizeof(buf_un), "%s", inet_ntop(pfx_vn.family, &pfx_vn.u.prefix, buf_ntop, BUFSIZ)); if (bpi->extra) { uint32_t l = decode_label(&bpi->extra->label[0]); - snprintf(buf_vn, BUFSIZ, "Label: %d", l); + snprintf(buf_vn, sizeof(buf_vn), "Label: %d", l); } else /* should never happen */ { - snprintf(buf_vn, BUFSIZ, "Label: N/A"); + snprintf(buf_vn, sizeof(buf_vn), "Label: N/A"); } } else { - snprintf(buf_vn, BUFSIZ, "%s", + snprintf(buf_vn, sizeof(buf_vn), "%s", inet_ntop(pfx_vn.family, &pfx_vn.u.prefix, buf_ntop, BUFSIZ)); } diff --git a/bgpd/rfapi/vnc_import_bgp.c b/bgpd/rfapi/vnc_import_bgp.c index ac5beed0e3..0a8e1618fc 100644 --- a/bgpd/rfapi/vnc_import_bgp.c +++ b/bgpd/rfapi/vnc_import_bgp.c @@ -275,7 +275,12 @@ static void vnc_rhnck(char *tag) vnc_zlog_debug_verbose("%s: vnc_rhnck OK", tag); } -#define VNC_RHNCK(n) do {char buf[BUFSIZ];sprintf(buf,"%s: %s", __func__, #n);vnc_rhnck(buf);} while (0) +#define VNC_RHNCK(n) \ + do { \ + char buf[BUFSIZ]; \ + snprintf(buf, sizeof(buf), "%s: %s", __func__, #n); \ + vnc_rhnck(buf); \ + } while (0) #else diff --git a/doc/user/zebra.rst b/doc/user/zebra.rst index 3629b47877..9dfd08f733 100644 --- a/doc/user/zebra.rst +++ b/doc/user/zebra.rst @@ -831,7 +831,8 @@ FPM Commands .. index:: clear zebra fpm stats .. clicmd:: clear zebra fpm stats - Resets all FPM counters. + Reset statistics related to the zebra code that interacts with the + optional Forwarding Plane Manager (FPM) component. ``dplane_fpm_nl`` implementation @@ -879,7 +880,8 @@ FPM Commands .. index:: clear fpm counters .. clicmd:: clear fpm counters - Resets all FPM counters. + Reset statistics related to the zebra code that interacts with the + optional Forwarding Plane Manager (FPM) component. .. _zebra-dplane: @@ -999,18 +1001,6 @@ zebra Terminal Mode Commands total number of route nodes in the table. Which will be higher than the actual number of routes that are held. -.. index:: show zebra fpm stats -.. clicmd:: show zebra fpm stats - - Display statistics related to the zebra code that interacts with the - optional Forwarding Plane Manager (FPM) component. - -.. index:: clear zebra fpm stats -.. clicmd:: clear zebra fpm stats - - Reset statistics related to the zebra code that interacts with the - optional Forwarding Plane Manager (FPM) component. - .. index:: show nexthop-group rib [ID] [vrf NAME] [singleton [ip|ip6]] .. clicmd:: show nexthop-group rib [ID] [vrf NAME] diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c index c0b90e8439..effd19ed7d 100644 --- a/isisd/isis_lsp.c +++ b/isisd/isis_lsp.c @@ -603,7 +603,7 @@ static void lsp_set_time(struct isis_lsp *lsp) void lspid_print(uint8_t *lsp_id, char *dest, char dynhost, char frag) { struct isis_dynhn *dyn = NULL; - uint8_t id[SYSID_STRLEN]; + char id[SYSID_STRLEN]; if (dynhost) dyn = dynhn_find_by_id(lsp_id); @@ -611,9 +611,9 @@ void lspid_print(uint8_t *lsp_id, char *dest, char dynhost, char frag) dyn = NULL; if (dyn) - sprintf((char *)id, "%.14s", dyn->hostname); + snprintf(id, sizeof(id), "%.14s", dyn->hostname); else if (!memcmp(isis->sysid, lsp_id, ISIS_SYS_ID_LEN) && dynhost) - sprintf((char *)id, "%.14s", cmd_hostname_get()); + snprintf(id, sizeof(id), "%.14s", cmd_hostname_get()); else memcpy(id, sysid_print(lsp_id), 15); if (frag) @@ -659,7 +659,7 @@ void lsp_print(struct isis_lsp *lsp, struct vty *vty, char dynhost) vty_out(vty, "0x%08" PRIx32 " ", lsp->hdr.seqno); vty_out(vty, "0x%04" PRIx16 " ", lsp->hdr.checksum); if (lsp->hdr.rem_lifetime == 0) { - snprintf(age_out, 8, "(%d)", lsp->age_out); + snprintf(age_out, sizeof(age_out), "(%d)", lsp->age_out); age_out[7] = '\0'; vty_out(vty, "%7s ", age_out); } else diff --git a/ldpd/ldp_vty_exec.c b/ldpd/ldp_vty_exec.c index 66c127abdc..d317da7b20 100644 --- a/ldpd/ldp_vty_exec.c +++ b/ldpd/ldp_vty_exec.c @@ -193,7 +193,8 @@ show_interface_msg_json(struct imsg *imsg, struct show_params *params, json_object_int_add(json_iface, "adjacencyCount", iface->adj_cnt); - sprintf(key_name, "%s: %s", iface->name, af_name(iface->af)); + snprintf(key_name, sizeof(key_name), "%s: %s", iface->name, + af_name(iface->af)); json_object_object_add(json, key_name, json_iface); break; case IMSG_CTL_END: @@ -1328,7 +1329,8 @@ show_l2vpn_binding_msg_json(struct imsg *imsg, struct show_params *params, json_object_string_add(json_pw, "remoteLabel", "unassigned"); - sprintf(key_name, "%s: %u", inet_ntoa(pw->lsr_id), pw->pwid); + snprintf(key_name, sizeof(key_name), "%s: %u", + inet_ntoa(pw->lsr_id), pw->pwid); json_object_object_add(json, key_name, json_pw); break; case IMSG_CTL_END: diff --git a/lib/atomlist.h b/lib/atomlist.h index 96476c2cd2..5ca19cbcd4 100644 --- a/lib/atomlist.h +++ b/lib/atomlist.h @@ -20,6 +20,10 @@ #include "typesafe.h" #include "frratomic.h" +#ifdef __cplusplus +extern "C" { +#endif + /* pointer with lock/deleted/invalid bit in lowest bit * * for atomlist/atomsort, "locked" means "this pointer can't be updated, the @@ -361,4 +365,8 @@ void atomsort_del_hint(struct atomsort_head *h, struct atomsort_item *atomsort_pop(struct atomsort_head *h); +#ifdef __cplusplus +} +#endif + #endif /* _FRR_ATOMLIST_H */ diff --git a/lib/command.c b/lib/command.c index fbbf10c796..38a7b3fe7c 100644 --- a/lib/command.c +++ b/lib/command.c @@ -1536,7 +1536,8 @@ static int file_write_config(struct vty *vty) config_file_tmp = XMALLOC(MTYPE_TMP, strlen(config_file) + 8); - sprintf(config_file_tmp, "%s.XXXXXX", config_file); + snprintf(config_file_tmp, strlen(config_file) + 8, "%s.XXXXXX", + config_file); /* Open file to configuration write. */ fd = mkstemp(config_file_tmp); @@ -637,10 +637,10 @@ void csv_dump(csv_t *csv) static int get_memory_usage(pid_t pid) { int fd, data, stack; - char buf[4096], status_child[BUFSIZ]; + char buf[4096], status_child[PATH_MAX]; char *vm; - sprintf(status_child, "/proc/%d/status", pid); + snprintf(status_child, sizeof(status_child), "/proc/%d/status", pid); if ((fd = open(status_child, O_RDONLY)) < 0) return -1; @@ -672,8 +672,8 @@ int main() log_verbose("Mem: %d\n", get_memory_usage(getpid())); csv_init(&csv, buf, 256); - sprintf(hdr1, "%4d", 0); - sprintf(hdr2, "%4d", 1); + snprintf(hdr1, sizeof(hdr1), "%4d", 0); + snprintf(hdr2, sizeof(hdr2), "%4d", 1); log_verbose("(%zu/%zu/%d/%d)\n", strlen(hdr1), strlen(hdr2), atoi(hdr1), atoi(hdr2)); rec = csv_encode(&csv, 2, hdr1, hdr2); @@ -685,8 +685,8 @@ int main() } csv_encode(&csv, 2, "pdfadfadfadsadsaddfdfdsfdsd", "35444554545454545"); log_verbose("%s\n", buf); - sprintf(hdr1, "%4d", csv.csv_len); - sprintf(hdr2, "%4d", 1); + snprintf(hdr1, sizeof(hdr1), "%4d", csv.csv_len); + snprintf(hdr2, sizeof(hdr2), "%4d", 1); log_verbose("(%zu/%zu/%d/%d)\n", strlen(hdr1), strlen(hdr2), atoi(hdr1), atoi(hdr2)); rec = csv_encode_record(&csv, rec, 2, hdr1, hdr2); diff --git a/lib/defaults.h b/lib/defaults.h index 7cdd18120e..20ef28db31 100644 --- a/lib/defaults.h +++ b/lib/defaults.h @@ -22,6 +22,10 @@ #include "compiler.h" +#ifdef __cplusplus +extern "C" { +#endif + /* frr_default wraps information about a default that has different * values depending on FRR version or default-set * @@ -135,4 +139,8 @@ extern bool frr_defaults_profile_valid(const char *profile); /* like strcmp(), but with version ordering */ extern int frr_version_cmp(const char *aa, const char *bb); +#ifdef __cplusplus +} +#endif + #endif /* _FRR_DEFAULTS_H */ diff --git a/lib/frrcu.h b/lib/frrcu.h index 491e89aac2..47751ae7df 100644 --- a/lib/frrcu.h +++ b/lib/frrcu.h @@ -20,6 +20,10 @@ #include "memory.h" #include "atomlist.h" +#ifdef __cplusplus +extern "C" { +#endif + /* quick RCU primer: * There's a global sequence counter. Whenever a thread does a * rcu_read_lock(), it is marked as holding the current sequence counter. @@ -170,4 +174,8 @@ extern void rcu_enqueue(struct rcu_head *head, const struct rcu_action *action); extern void rcu_close(struct rcu_head_close *head, int fd); +#ifdef __cplusplus +} +#endif + #endif /* _FRRCU_H */ diff --git a/lib/iana_afi.h b/lib/iana_afi.h index ac03f73193..56e8a24b86 100644 --- a/lib/iana_afi.h +++ b/lib/iana_afi.h @@ -21,6 +21,10 @@ #include <prefix.h> +#ifdef __cplusplus +extern "C" { +#endif + /* * The above AFI and SAFI definitions are for internal use. The protocol * definitions (IANA values) as for example used in BGP protocol packets @@ -130,4 +134,8 @@ static inline const char *iana_safi2str(iana_safi_t safi) return safi2str(safi_iana2int(safi)); } +#ifdef __cplusplus +} +#endif + #endif @@ -949,8 +949,9 @@ connected_log(struct connected *connected, char *str) p = connected->address; 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), + snprintf(logbuf, sizeof(logbuf), "%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; @@ -973,8 +974,8 @@ nbr_connected_log(struct nbr_connected *connected, char *str) ifp = connected->ifp; p = connected->address; - snprintf(logbuf, BUFSIZ, "%s interface %s %s %s/%d ", str, ifp->name, - prefix_family_str(p), + snprintf(logbuf, sizeof(logbuf), "%s interface %s %s %s/%d ", str, + ifp->name, prefix_family_str(p), inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ), p->prefixlen); zlog_info("%s", logbuf); diff --git a/lib/log_vty.c b/lib/log_vty.c index 97026e5dbc..d1dcac2340 100644 --- a/lib/log_vty.c +++ b/lib/log_vty.c @@ -260,10 +260,11 @@ DEFUN_HIDDEN (no_config_log_monitor, static int set_log_file(struct zlog_cfg_file *target, struct vty *vty, const char *fname, int loglevel) { - char *p = NULL; + char path[MAXPATHLEN + 1]; const char *fullpath; bool ok; + /* Path detection. */ if (!IS_DIRECTORY_SEP(*fname)) { char cwd[MAXPATHLEN + 1]; @@ -276,17 +277,22 @@ static int set_log_file(struct zlog_cfg_file *target, struct vty *vty, return CMD_WARNING_CONFIG_FAILED; } - p = XMALLOC(MTYPE_TMP, strlen(cwd) + strlen(fname) + 2); - sprintf(p, "%s/%s", cwd, fname); - fullpath = p; + int pr = snprintf(path, sizeof(path), "%s/%s", cwd, fname); + if (pr < 0 || (unsigned int)pr >= sizeof(path)) { + flog_err_sys( + EC_LIB_SYSTEM_CALL, + "%s: Path too long ('%s/%s'); system maximum is %u", + __func__, cwd, fname, MAXPATHLEN); + return CMD_WARNING_CONFIG_FAILED; + } + + fullpath = path; } else fullpath = fname; target->prio_min = loglevel; ok = zlog_file_set_filename(target, fullpath); - XFREE(MTYPE_TMP, p); - if (!ok) { if (vty) vty_out(vty, "can't open logfile %s\n", fname); diff --git a/lib/log_vty.h b/lib/log_vty.h index 0fd60e9b07..16c4475467 100644 --- a/lib/log_vty.h +++ b/lib/log_vty.h @@ -23,6 +23,10 @@ #include "lib/hook.h" +#ifdef __cplusplus +extern "C" { +#endif + struct vty; extern void log_cmd_init(void); @@ -33,4 +37,8 @@ extern void log_show_syslog(struct vty *vty); DECLARE_HOOK(zlog_rotate, (), ()) extern void zlog_rotate(void); +#ifdef __cplusplus +} +#endif + #endif /* __LOG_VTY_H__ */ diff --git a/lib/netns_linux.c b/lib/netns_linux.c index 4d4376250f..98f359401e 100644 --- a/lib/netns_linux.c +++ b/lib/netns_linux.c @@ -431,7 +431,7 @@ char *ns_netns_pathname(struct vty *vty, const char *name) /* relevant pathname */ char tmp_name[PATH_MAX]; - snprintf(tmp_name, PATH_MAX, "%s/%s", NS_RUN_DIR, name); + snprintf(tmp_name, sizeof(tmp_name), "%s/%s", NS_RUN_DIR, name); result = realpath(tmp_name, pathname); } diff --git a/lib/pid_output.c b/lib/pid_output.c index f5f7b1d171..bd1d89a94c 100644 --- a/lib/pid_output.c +++ b/lib/pid_output.c @@ -65,7 +65,7 @@ pid_t pid_output(const char *path) exit(1); } - sprintf(buf, "%d\n", (int)pid); + snprintf(buf, sizeof(buf), "%d\n", (int)pid); pidsize = strlen(buf); if ((tmp = write(fd, buf, pidsize)) != (int)pidsize) flog_err_sys( diff --git a/lib/plist.c b/lib/plist.c index 67a91e2a0d..d18d51618a 100644 --- a/lib/plist.c +++ b/lib/plist.c @@ -1961,10 +1961,9 @@ int prefix_bgp_show_prefix_list(struct vty *vty, afi_t afi, char *name, char buf_a[BUFSIZ]; char buf_b[BUFSIZ]; - sprintf(buf_a, "%s/%d", - inet_ntop(p->family, p->u.val, buf_b, - BUFSIZ), - p->prefixlen); + snprintf(buf_a, sizeof(buf_a), "%s/%d", + inet_ntop(p->family, p->u.val, buf_b, BUFSIZ), + p->prefixlen); json_object_int_add(json_list, "seq", pentry->seq); json_object_string_add(json_list, "seqPrefixListType", diff --git a/lib/printfrr.h b/lib/printfrr.h index 7d9e288655..a775e1517b 100644 --- a/lib/printfrr.h +++ b/lib/printfrr.h @@ -24,6 +24,10 @@ #include "compiler.h" #include "memory.h" +#ifdef __cplusplus +extern "C" { +#endif + struct fbuf { char *buf; char *pos; @@ -156,4 +160,8 @@ void printfrr_ext_reg(const struct printfrr_ext *); } \ /* end */ +#ifdef __cplusplus +} +#endif + #endif diff --git a/lib/ptm_lib.c b/lib/ptm_lib.c index b66ae221cf..e00dd54290 100644 --- a/lib/ptm_lib.c +++ b/lib/ptm_lib.c @@ -65,10 +65,10 @@ static csv_record_t *_ptm_lib_encode_header(csv_t *csv, csv_record_t *rec, char client_buf[32]; csv_record_t *rec1; - sprintf(msglen_buf, "%4d", msglen); - sprintf(vers_buf, "%4d", version); - sprintf(type_buf, "%4d", type); - sprintf(cmdid_buf, "%4d", cmd_id); + snprintf(msglen_buf, sizeof(msglen_buf), "%4d", msglen); + snprintf(vers_buf, sizeof(vers_buf), "%4d", version); + snprintf(type_buf, sizeof(type_buf), "%4d", type); + snprintf(cmdid_buf, sizeof(cmdid_buf), "%4d", cmd_id); snprintf(client_buf, 17, "%16.16s", client_name); if (rec) { rec1 = csv_encode_record(csv, rec, 5, msglen_buf, vers_buf, diff --git a/lib/pullwr.h b/lib/pullwr.h index 601eac1b79..a0e89e0c30 100644 --- a/lib/pullwr.h +++ b/lib/pullwr.h @@ -26,6 +26,10 @@ #include "thread.h" #include "stream.h" +#ifdef __cplusplus +extern "C" { +#endif + struct pullwr; /* This is a "pull-driven" write event handler. Instead of having some buffer @@ -107,4 +111,8 @@ static inline void pullwr_write_stream(struct pullwr *pullwr, extern void pullwr_stats(struct pullwr *pullwr, uint64_t *total_written, size_t *pending, size_t *kernel_pending); +#ifdef __cplusplus +} +#endif + #endif /* _WRITEPOLL_H */ diff --git a/lib/resolver.h b/lib/resolver.h index 59bf0d0f55..5f922dcb57 100644 --- a/lib/resolver.h +++ b/lib/resolver.h @@ -13,6 +13,10 @@ #include "thread.h" #include "sockunion.h" +#ifdef __cplusplus +extern "C" { +#endif + struct resolver_query { void (*callback)(struct resolver_query *, const char *errstr, int n, union sockunion *); @@ -28,4 +32,8 @@ void resolver_resolve(struct resolver_query *query, int af, const char *, int, union sockunion *)); +#ifdef __cplusplus +} +#endif + #endif /* _FRR_RESOLVER_H */ diff --git a/lib/seqlock.h b/lib/seqlock.h index b551e3ffc4..bfbf97890e 100644 --- a/lib/seqlock.h +++ b/lib/seqlock.h @@ -27,6 +27,10 @@ #include <pthread.h> #include "frratomic.h" +#ifdef __cplusplus +extern "C" { +#endif + /* * this locking primitive is intended to use in a 1:N setup. * @@ -135,4 +139,8 @@ extern void seqlock_release(struct seqlock *sqlo); * anything other than reading RCU items was done */ +#ifdef __cplusplus +} +#endif + #endif /* _SEQLOCK_H */ diff --git a/lib/subdir.am b/lib/subdir.am index ed6cf31b34..f3f709fd24 100644 --- a/lib/subdir.am +++ b/lib/subdir.am @@ -120,6 +120,8 @@ nodist_lib_libfrr_la_SOURCES = \ yang/frr-module-translator.yang.c \ yang/frr-nexthop.yang.c \ yang/frr-igmp.yang.c \ + yang/frr-pim.yang.c \ + yang/frr-pim-rp.yang.c \ # end vtysh_scan += \ diff --git a/lib/version.h.in b/lib/version.h.in index 52c10f7d68..d535d131c8 100644 --- a/lib/version.h.in +++ b/lib/version.h.in @@ -28,6 +28,10 @@ #include "gitversion.h" #endif +#ifdef __cplusplus +extern "C" { +#endif + #ifndef GIT_SUFFIX #define GIT_SUFFIX "" #endif @@ -54,4 +58,8 @@ pid_t pid_output (const char *); +#ifdef __cplusplus +} +#endif + #endif /* _ZEBRA_VERSION_H */ @@ -1882,7 +1882,7 @@ static void vty_serv_sock_addrinfo(const char *hostname, unsigned short port) req.ai_flags = AI_PASSIVE; req.ai_family = AF_UNSPEC; req.ai_socktype = SOCK_STREAM; - sprintf(port_str, "%d", port); + snprintf(port_str, sizeof(port_str), "%d", port); port_str[sizeof(port_str) - 1] = '\0'; ret = getaddrinfo(hostname, port_str, &req, &ainfo); @@ -2380,7 +2380,7 @@ static FILE *vty_use_backup_config(const char *fullpath) } fullpath_tmp = malloc(strlen(fullpath) + 8); - sprintf(fullpath_tmp, "%s.XXXXXX", fullpath); + snprintf(fullpath_tmp, strlen(fullpath) + 8, "%s.XXXXXX", fullpath); /* Open file to configuration write. */ tmp = mkstemp(fullpath_tmp); diff --git a/lib/yang_wrappers.h b/lib/yang_wrappers.h index d853b61ae1..f61f252cdf 100644 --- a/lib/yang_wrappers.h +++ b/lib/yang_wrappers.h @@ -22,6 +22,10 @@ #include "prefix.h" +#ifdef __cplusplus +extern "C" { +#endif + /* bool */ extern bool yang_str2bool(const char *value); extern struct yang_data *yang_data_new_bool(const char *xpath, bool value); @@ -182,4 +186,8 @@ extern void yang_str2mac(const char *value, struct ethaddr *mac); extern const char *yang_nexthop_type2str(uint32_t ntype); +#ifdef __cplusplus +} +#endif + #endif /* _FRR_NORTHBOUND_WRAPPERS_H_ */ diff --git a/lib/zassert.h b/lib/zassert.h index d45e1be5f8..e50a88f407 100644 --- a/lib/zassert.h +++ b/lib/zassert.h @@ -19,6 +19,10 @@ #ifndef _QUAGGA_ASSERT_H #define _QUAGGA_ASSERT_H +#ifdef __cplusplus +extern "C" { +#endif + extern void _zlog_assert_failed(const char *assertion, const char *file, unsigned int line, const char *function) __attribute__((noreturn)); @@ -39,4 +43,8 @@ extern void _zlog_assert_failed(const char *assertion, const char *file, #undef assert #define assert(EX) zassert(EX) +#ifdef __cplusplus +} +#endif + #endif /* _QUAGGA_ASSERT_H */ diff --git a/lib/zclient.h b/lib/zclient.h index 6e8066381f..4ada064623 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -38,6 +38,10 @@ #include "mlag.h" +#ifdef __cplusplus +extern "C" { +#endif + /* Zebra types. Used in Zserv message header. */ typedef uint16_t zebra_size_t; @@ -826,4 +830,8 @@ extern void zclient_send_mlag_data(struct zclient *client, */ extern int zclient_send_hello(struct zclient *client); +#ifdef __cplusplus +} +#endif + #endif /* _ZEBRA_ZCLIENT_H */ diff --git a/lib/zlog.h b/lib/zlog.h index fd42ad50e4..904049c0f2 100644 --- a/lib/zlog.h +++ b/lib/zlog.h @@ -30,6 +30,10 @@ #include "memory.h" #include "hook.h" +#ifdef __cplusplus +extern "C" { +#endif + extern char zlog_prefix[]; extern size_t zlog_prefixsz; extern int zlog_tmpdirfd; @@ -183,4 +187,8 @@ extern void zlog_tls_buffer_init(void); extern void zlog_tls_buffer_flush(void); extern void zlog_tls_buffer_fini(void); +#ifdef __cplusplus +} +#endif + #endif /* _FRR_ZLOG_H */ diff --git a/lib/zlog_targets.h b/lib/zlog_targets.h index f95d349a57..6faf722ffd 100644 --- a/lib/zlog_targets.h +++ b/lib/zlog_targets.h @@ -21,6 +21,10 @@ #include "zlog.h" +#ifdef __cplusplus +extern "C" { +#endif + /* multiple file log targets can be active */ struct zlt_fd; @@ -63,4 +67,8 @@ extern int zlog_syslog_get_facility(void); extern void zlog_syslog_set_prio_min(int prio_min); extern int zlog_syslog_get_prio_min(void); +#ifdef __cplusplus +} +#endif + #endif /* _FRR_ZLOG_TARGETS_H */ diff --git a/nhrpd/linux.c b/nhrpd/linux.c index 85e941e7ba..59c82b1c55 100644 --- a/nhrpd/linux.c +++ b/nhrpd/linux.c @@ -25,6 +25,7 @@ #include <linux/ip.h> #include <linux/if_arp.h> #include <linux/if_tunnel.h> +#include <linux/limits.h> #include "nhrp_protocol.h" #include "os.h" @@ -127,10 +128,11 @@ static int linux_configure_arp(const char *iface, int on) static int linux_icmp_redirect_off(const char *iface) { - char fname[256]; + char fname[PATH_MAX]; int fd, ret = -1; - sprintf(fname, "/proc/sys/net/ipv4/conf/%s/send_redirects", iface); + snprintf(fname, sizeof(fname), + "/proc/sys/net/ipv4/conf/%s/send_redirects", iface); fd = open(fname, O_WRONLY); if (fd < 0) return -1; diff --git a/ospf6d/ospf6_lsa.c b/ospf6d/ospf6_lsa.c index aa32fae6ad..9e7479c797 100644 --- a/ospf6d/ospf6_lsa.c +++ b/ospf6d/ospf6_lsa.c @@ -397,10 +397,10 @@ void ospf6_lsa_show_summary(struct vty *vty, struct ospf6_lsa *lsa) (unsigned long)ntohl(lsa->header->seqnum), handler->lh_get_prefix_str(lsa, buf, sizeof(buf), 0)); } else if (type != OSPF6_LSTYPE_UNKNOWN) { - sprintf(tmpbuf, "%-4s %-15s%-15s%4hu %8lx", - ospf6_lstype_short_name(lsa->header->type), id, - adv_router, ospf6_lsa_age_current(lsa), - (unsigned long)ntohl(lsa->header->seqnum)); + snprintf(tmpbuf, sizeof(tmpbuf), "%-4s %-15s%-15s%4hu %8lx", + ospf6_lstype_short_name(lsa->header->type), id, + adv_router, ospf6_lsa_age_current(lsa), + (unsigned long)ntohl(lsa->header->seqnum)); while (handler->lh_get_prefix_str(lsa, buf, sizeof(buf), cnt) != NULL) { diff --git a/ospfd/ospf_ase.c b/ospfd/ospf_ase.c index 30940cf010..8747dd1f53 100644 --- a/ospfd/ospf_ase.c +++ b/ospfd/ospf_ase.c @@ -306,7 +306,7 @@ int ospf_ase_calculate_route(struct ospf *ospf, struct ospf_lsa *lsa) } if (IS_DEBUG_OSPF(lsa, LSA)) { - snprintf(buf1, INET_ADDRSTRLEN, "%s", + snprintf(buf1, sizeof(buf1), "%s", inet_ntoa(al->header.adv_router)); zlog_debug( "Route[External]: Calculate AS-external-LSA to %s/%d adv_router %s", diff --git a/ospfd/ospf_dump.c b/ospfd/ospf_dump.c index f0740349a0..3dcb2b481d 100644 --- a/ospfd/ospf_dump.c +++ b/ospfd/ospf_dump.c @@ -82,9 +82,8 @@ const char *ospf_area_name_string(struct ospf_area *area) return "-"; area_id = ntohl(area->area_id.s_addr); - snprintf(buf, OSPF_AREA_STRING_MAXLEN, "%d.%d.%d.%d", - (area_id >> 24) & 0xff, (area_id >> 16) & 0xff, - (area_id >> 8) & 0xff, area_id & 0xff); + snprintf(buf, sizeof(buf), "%d.%d.%d.%d", (area_id >> 24) & 0xff, + (area_id >> 16) & 0xff, (area_id >> 8) & 0xff, area_id & 0xff); return buf; } @@ -100,11 +99,11 @@ const char *ospf_area_desc_string(struct ospf_area *area) type = area->external_routing; switch (type) { case OSPF_AREA_NSSA: - snprintf(buf, OSPF_AREA_DESC_STRING_MAXLEN, "%s [NSSA]", + snprintf(buf, sizeof(buf), "%s [NSSA]", ospf_area_name_string(area)); break; case OSPF_AREA_STUB: - snprintf(buf, OSPF_AREA_DESC_STRING_MAXLEN, "%s [Stub]", + snprintf(buf, sizeof(buf), "%s [Stub]", ospf_area_name_string(area)); break; default: @@ -127,7 +126,7 @@ const char *ospf_if_name_string(struct ospf_interface *oi) return oi->ifp->name; ifaddr = ntohl(oi->address->u.prefix4.s_addr); - snprintf(buf, OSPF_IF_STRING_MAXLEN, "%s:%d.%d.%d.%d", oi->ifp->name, + snprintf(buf, sizeof(buf), "%s:%d.%d.%d.%d", oi->ifp->name, (ifaddr >> 24) & 0xff, (ifaddr >> 16) & 0xff, (ifaddr >> 8) & 0xff, ifaddr & 0xff); return buf; @@ -1669,7 +1668,7 @@ static int config_write_debug(struct vty *vty) return CMD_SUCCESS; if (ospf->instance) - sprintf(str, " %u", ospf->instance); + snprintf(str, sizeof(str), " %u", ospf->instance); /* debug ospf ism (status|events|timers). */ if (IS_CONF_DEBUG_OSPF(ism, ISM) == OSPF_DEBUG_ISM) diff --git a/ospfd/ospf_dump_api.c b/ospfd/ospf_dump_api.c index 1196339c34..e24936a473 100644 --- a/ospfd/ospf_dump_api.c +++ b/ospfd/ospf_dump_api.c @@ -105,7 +105,7 @@ char *ospf_options_dump(uint8_t options) { static char buf[OSPF_OPTION_STR_MAXLEN]; - snprintf(buf, OSPF_OPTION_STR_MAXLEN, "*|%s|%s|%s|%s|%s|%s|%s", + snprintf(buf, sizeof(buf), "*|%s|%s|%s|%s|%s|%s|%s", (options & OSPF_OPTION_O) ? "O" : "-", (options & OSPF_OPTION_DC) ? "DC" : "-", (options & OSPF_OPTION_EA) ? "EA" : "-", diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index 8cf2fad92e..d089ea76cd 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -299,7 +299,8 @@ const char *dump_lsa_key(struct ospf_lsa *lsa) strlcpy(id, inet_ntoa(lsah->id), sizeof(id)); strlcpy(ar, inet_ntoa(lsah->adv_router), sizeof(ar)); - sprintf(buf, "Type%d,id(%s),ar(%s)", lsah->type, id, ar); + snprintf(buf, sizeof(buf), "Type%d,id(%s),ar(%s)", lsah->type, + id, ar); } else strlcpy(buf, "NULL", sizeof(buf)); diff --git a/ospfd/ospf_sr.c b/ospfd/ospf_sr.c index 7a786ba7ab..2a35bd2ef9 100644 --- a/ospfd/ospf_sr.c +++ b/ospfd/ospf_sr.c @@ -2094,7 +2094,7 @@ static void show_sr_node(struct vty *vty, struct json_object *json, json_obj = json_object_new_object(); char tmp[2]; - snprintf(tmp, 2, "%u", i); + snprintf(tmp, sizeof(tmp), "%u", i); json_object_string_add(json_obj, tmp, srn->algo[i] == SR_ALGORITHM_SPF ? "SPF" @@ -2129,13 +2129,15 @@ static void show_sr_node(struct vty *vty, struct json_object *json, "--------------------- --------- ---------------\n"); } for (ALL_LIST_ELEMENTS_RO(srn->ext_prefix, node, srp)) { - snprintf(pref, 19, "%s/%u", inet_ntoa(srp->nhlfe.prefv4.prefix), + snprintf(pref, sizeof(pref), "%s/%u", + inet_ntoa(srp->nhlfe.prefv4.prefix), srp->nhlfe.prefv4.prefixlen); - snprintf(sid, 22, "SR Pfx (idx %u)", srp->sid); + snprintf(sid, sizeof(sid), "SR Pfx (idx %u)", srp->sid); if (srp->nhlfe.label_out == MPLS_LABEL_IMPLICIT_NULL) - sprintf(label, "pop"); + snprintf(label, sizeof(label), "pop"); else - sprintf(label, "%u", srp->nhlfe.label_out); + snprintf(label, sizeof(label), "%u", + srp->nhlfe.label_out); itf = if_lookup_by_index(srp->nhlfe.ifindex, VRF_DEFAULT); if (json) { if (!json_prefix) { @@ -2164,14 +2166,15 @@ static void show_sr_node(struct vty *vty, struct json_object *json, } for (ALL_LIST_ELEMENTS_RO(srn->ext_link, node, srl)) { - snprintf(pref, 19, "%s/%u", + snprintf(pref, sizeof(pref), "%s/%u", inet_ntoa(srl->nhlfe[0].prefv4.prefix), srl->nhlfe[0].prefv4.prefixlen); - snprintf(sid, 22, "SR Adj. (lbl %u)", srl->sid[0]); + snprintf(sid, sizeof(sid), "SR Adj. (lbl %u)", srl->sid[0]); if (srl->nhlfe[0].label_out == MPLS_LABEL_IMPLICIT_NULL) - sprintf(label, "pop"); + snprintf(label, sizeof(label), "pop"); else - sprintf(label, "%u", srl->nhlfe[0].label_out); + snprintf(label, sizeof(label), "%u", + srl->nhlfe[0].label_out); itf = if_lookup_by_index(srl->nhlfe[0].ifindex, VRF_DEFAULT); if (json) { if (!json_link) { @@ -2194,11 +2197,13 @@ static void show_sr_node(struct vty *vty, struct json_object *json, json_object_array_add(json_link, json_obj); /* Backup Link */ json_obj = json_object_new_object(); - snprintf(sid, 22, "SR Adj. (lbl %u)", srl->sid[1]); + snprintf(sid, sizeof(sid), "SR Adj. (lbl %u)", + srl->sid[1]); if (srl->nhlfe[1].label_out == MPLS_LABEL_IMPLICIT_NULL) - sprintf(label, "pop"); + snprintf(label, sizeof(label), "pop"); else - sprintf(label, "%u", srl->nhlfe[0].label_out); + snprintf(label, sizeof(label), "%u", + srl->nhlfe[0].label_out); json_object_string_add(json_obj, "prefix", pref); json_object_int_add(json_obj, "sid", srl->sid[1]); json_object_int_add(json_obj, "inputLabel", @@ -2215,11 +2220,13 @@ static void show_sr_node(struct vty *vty, struct json_object *json, srl->nhlfe[0].label_in, label, sid, itf ? itf->name : "-", inet_ntoa(srl->nhlfe[0].nexthop)); - snprintf(sid, 22, "SR Adj. (lbl %u)", srl->sid[1]); + snprintf(sid, sizeof(sid), "SR Adj. (lbl %u)", + srl->sid[1]); if (srl->nhlfe[1].label_out == MPLS_LABEL_IMPLICIT_NULL) - sprintf(label, "pop"); + snprintf(label, sizeof(label), "pop"); else - sprintf(label, "%u", srl->nhlfe[1].label_out); + snprintf(label, sizeof(label), "%u", + srl->nhlfe[1].label_out); vty_out(vty, "%18s %8u %9s %21s %9s %15s\n", pref, srl->nhlfe[1].label_in, label, sid, itf ? itf->name : "-", diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index a3a02a0f95..71275e49d2 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -83,7 +83,8 @@ static void area_id2str(char *buf, int length, struct in_addr *area_id, if (area_id_fmt == OSPF_AREA_ID_FMT_DOTTEDQUAD) inet_ntop(AF_INET, area_id, buf, length); else - sprintf(buf, "%lu", (unsigned long)ntohl(area_id->s_addr)); + snprintf(buf, length, "%lu", + (unsigned long)ntohl(area_id->s_addr)); } static int str2metric(const char *str, int *metric) @@ -9263,8 +9264,8 @@ static void show_ip_ospf_route_external(struct vty *vty, struct ospf *ospf, char buf1[19]; - snprintf(buf1, 19, "%s/%d", inet_ntoa(rn->p.u.prefix4), - rn->p.prefixlen); + snprintf(buf1, sizeof(buf1), "%s/%d", + inet_ntoa(rn->p.u.prefix4), rn->p.prefixlen); json_route = json_object_new_object(); if (json) { json_object_object_add(json, buf1, json_route); @@ -9997,7 +9998,7 @@ static int config_write_interface(struct vty *vty) static int config_write_network_area(struct vty *vty, struct ospf *ospf) { struct route_node *rn; - uint8_t buf[INET_ADDRSTRLEN]; + char buf[INET_ADDRSTRLEN]; /* `network area' print. */ for (rn = route_top(ospf->networks); rn; rn = route_next(rn)) @@ -10006,12 +10007,12 @@ static int config_write_network_area(struct vty *vty, struct ospf *ospf) /* Create Area ID string by specified Area ID format. */ if (n->area_id_fmt == OSPF_AREA_ID_FMT_DOTTEDQUAD) - inet_ntop(AF_INET, &n->area_id, (char *)buf, + inet_ntop(AF_INET, &n->area_id, buf, sizeof(buf)); else - sprintf((char *)buf, "%lu", - (unsigned long int)ntohl( - n->area_id.s_addr)); + snprintf(buf, sizeof(buf), "%lu", + (unsigned long int)ntohl( + n->area_id.s_addr)); /* Network print. */ vty_out(vty, " network %s/%d area %s\n", @@ -10026,13 +10027,13 @@ static int config_write_ospf_area(struct vty *vty, struct ospf *ospf) { struct listnode *node; struct ospf_area *area; - uint8_t buf[INET_ADDRSTRLEN]; + char buf[INET_ADDRSTRLEN]; /* Area configuration print. */ for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { struct route_node *rn1; - area_id2str((char *)buf, sizeof(buf), &area->area_id, + area_id2str(buf, sizeof(buf), &area->area_id, area->area_id_fmt); if (area->auth_type != OSPF_AUTH_NULL) { diff --git a/pimd/mtracebis.c b/pimd/mtracebis.c index 2f10abccee..1b812de92c 100644 --- a/pimd/mtracebis.c +++ b/pimd/mtracebis.c @@ -108,7 +108,7 @@ static const char *rtg_proto_str(enum mtrace_rtg_proto proto) case MTRACE_RTG_PROTO_PIM_ASSERT: return "PIM assert"; default: - sprintf(buf, "unknown protocol (%d)", proto); + snprintf(buf, sizeof(buf), "unknown protocol (%d)", proto); return buf; } } @@ -161,7 +161,7 @@ static const char *fwd_code_str(enum mtrace_fwd_code code) case MTRACE_FWD_CODE_ADMIN_PROHIB: return "admin. prohib."; default: - sprintf(buf, "unknown fwd. code (%d)", code); + snprintf(buf, sizeof(buf), "unknown fwd. code (%d)", code); return buf; } } diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index f6af98598b..fe9b5e1beb 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -2510,10 +2510,12 @@ static void pim_show_upstream(struct pim_instance *pim, struct vty *vty, pim_upstream_state2brief_str(up->join_state, state_str, sizeof(state_str)); if (up->reg_state != PIM_REG_NOINFO) { char tmp_str[PIM_REG_STATE_STR_LEN]; + char tmp[sizeof(state_str) + 1]; - sprintf(state_str + strlen(state_str), ",%s", - pim_reg_state2brief_str(up->reg_state, tmp_str, - sizeof(tmp_str))); + snprintf(tmp, sizeof(tmp), ",%s", + pim_reg_state2brief_str(up->reg_state, tmp_str, + sizeof(tmp_str))); + strlcat(state_str, tmp, sizeof(state_str)); } if (uj) { diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c index 461c2698d5..851b00b2ac 100644 --- a/pimd/pim_igmp.c +++ b/pimd/pim_igmp.c @@ -913,7 +913,7 @@ static struct igmp_sock *igmp_sock_new(int fd, struct in_addr ifaddr, igmp->igmp_group_list = list_new(); igmp->igmp_group_list->del = (void (*)(void *))igmp_group_free; - snprintf(hash_name, 64, "IGMP %s hash", ifp->name); + snprintf(hash_name, sizeof(hash_name), "IGMP %s hash", ifp->name); igmp->igmp_group_hash = hash_create(igmp_group_hash_key, igmp_group_hash_equal, hash_name); diff --git a/pimd/pim_igmpv3.c b/pimd/pim_igmpv3.c index ffd872ce03..8eaca75821 100644 --- a/pimd/pim_igmpv3.c +++ b/pimd/pim_igmpv3.c @@ -1945,7 +1945,8 @@ int igmp_v3_recv_report(struct igmp_sock *igmp, struct in_addr from, if (!inet_ntop(AF_INET, src, src_str, sizeof(src_str))) - sprintf(src_str, "<source?>"); + snprintf(src_str, sizeof(src_str), + "<source?>"); zlog_debug( " Recv IGMP report v3 from %s on %s: record=%d group=%s source=%s", diff --git a/pimd/pim_instance.c b/pimd/pim_instance.c index b4c2dd28cc..b7e49078ef 100644 --- a/pimd/pim_instance.c +++ b/pimd/pim_instance.c @@ -99,7 +99,7 @@ static struct pim_instance *pim_instance_init(struct vrf *vrf) pim_msdp_init(pim, router->master); pim_vxlan_init(pim); - snprintf(hash_name, 64, "PIM %s RPF Hash", vrf->name); + snprintf(hash_name, sizeof(hash_name), "PIM %s RPF Hash", vrf->name); pim->rpf_hash = hash_create_size(256, pim_rpf_hash_key, pim_rpf_equal, hash_name); diff --git a/pimd/pim_msdp.c b/pimd/pim_msdp.c index 52c989e644..b42092a464 100644 --- a/pimd/pim_msdp.c +++ b/pimd/pim_msdp.c @@ -1574,14 +1574,16 @@ void pim_msdp_init(struct pim_instance *pim, struct thread_master *master) pim->msdp.master = master; char hash_name[64]; - snprintf(hash_name, 64, "PIM %s MSDP Peer Hash", pim->vrf->name); + snprintf(hash_name, sizeof(hash_name), "PIM %s MSDP Peer Hash", + pim->vrf->name); pim->msdp.peer_hash = hash_create(pim_msdp_peer_hash_key_make, pim_msdp_peer_hash_eq, hash_name); pim->msdp.peer_list = list_new(); pim->msdp.peer_list->del = (void (*)(void *))pim_msdp_peer_free; pim->msdp.peer_list->cmp = (int (*)(void *, void *))pim_msdp_peer_comp; - snprintf(hash_name, 64, "PIM %s MSDP SA Hash", pim->vrf->name); + snprintf(hash_name, sizeof(hash_name), "PIM %s MSDP SA Hash", + pim->vrf->name); pim->msdp.sa_hash = hash_create(pim_msdp_sa_hash_key_make, pim_msdp_sa_hash_eq, hash_name); pim->msdp.sa_list = list_new(); diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c index 68d43c0556..a888d68f09 100644 --- a/pimd/pim_nht.c +++ b/pimd/pim_nht.c @@ -103,7 +103,7 @@ static struct pim_nexthop_cache *pim_nexthop_cache_add(struct pim_instance *pim, pnc->rp_list = list_new(); pnc->rp_list->cmp = pim_rp_list_cmp; - snprintf(hash_name, 64, "PNC %s(%s) Upstream Hash", + snprintf(hash_name, sizeof(hash_name), "PNC %s(%s) Upstream Hash", prefix2str(&pnc->rpf.rpf_addr, buf1, 64), pim->vrf->name); pnc->upstream_hash = hash_create_size(8192, pim_upstream_hash_key, pim_upstream_equal, hash_name); diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c index ef5f478226..1611eac95d 100644 --- a/pimd/pim_rp.c +++ b/pimd/pim_rp.c @@ -728,7 +728,7 @@ int pim_rp_del(struct pim_instance *pim, struct in_addr rp_addr, char rp_str[INET_ADDRSTRLEN]; if (!inet_ntop(AF_INET, &rp_addr, rp_str, sizeof(rp_str))) - sprintf(rp_str, "<rp?>"); + snprintf(rp_str, sizeof(rp_str), "<rp?>"); prefix2str(&group, grp_str, sizeof(grp_str)); if (plist) @@ -763,7 +763,9 @@ int pim_rp_del(struct pim_instance *pim, struct in_addr rp_addr, if (!inet_ntop(AF_INET, bsrp, bsrp_str, sizeof(bsrp_str))) - sprintf(bsrp_str, "<bsrp?>"); + snprintf(bsrp_str, + sizeof(bsrp_str), + "<bsrp?>"); zlog_debug( "%s: BSM RP %s found for the group %s", @@ -1289,6 +1291,10 @@ void pim_rp_show_information(struct pim_instance *pim, struct vty *vty, bool uj) json_rp_rows = json_object_new_array(); json_row = json_object_new_object(); + json_object_string_add( + json_row, "rpAddress", + inet_ntoa(rp_info->rp.rpf_addr.u + .prefix4)); if (rp_info->rp.source_nexthop.interface) json_object_string_add( json_row, "outboundInterface", diff --git a/pimd/pim_sock.c b/pimd/pim_sock.c index f0a71c96ce..504519c8a4 100644 --- a/pimd/pim_sock.c +++ b/pimd/pim_sock.c @@ -288,10 +288,10 @@ int pim_socket_join(int fd, struct in_addr group, struct in_addr ifaddr, char group_str[INET_ADDRSTRLEN]; char ifaddr_str[INET_ADDRSTRLEN]; if (!inet_ntop(AF_INET, &group, group_str, sizeof(group_str))) - sprintf(group_str, "<group?>"); + snprintf(group_str, sizeof(group_str), "<group?>"); if (!inet_ntop(AF_INET, &ifaddr, ifaddr_str, sizeof(ifaddr_str))) - sprintf(ifaddr_str, "<ifaddr?>"); + snprintf(ifaddr_str, sizeof(ifaddr_str), "<ifaddr?>"); flog_err( EC_LIB_SOCKET, @@ -304,10 +304,10 @@ int pim_socket_join(int fd, struct in_addr group, struct in_addr ifaddr, char group_str[INET_ADDRSTRLEN]; char ifaddr_str[INET_ADDRSTRLEN]; if (!inet_ntop(AF_INET, &group, group_str, sizeof(group_str))) - sprintf(group_str, "<group?>"); + snprintf(group_str, sizeof(group_str), "<group?>"); if (!inet_ntop(AF_INET, &ifaddr, ifaddr_str, sizeof(ifaddr_str))) - sprintf(ifaddr_str, "<ifaddr?>"); + snprintf(ifaddr_str, sizeof(ifaddr_str), "<ifaddr?>"); zlog_debug( "Socket fd=%d joined group %s on interface address %s", diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index 1e78f41359..cf5ea2fa53 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -2165,8 +2165,7 @@ void pim_upstream_init(struct pim_instance *pim) { char name[64]; - snprintf(name, 64, "PIM %s Timer Wheel", - pim->vrf->name); + snprintf(name, sizeof(name), "PIM %s Timer Wheel", pim->vrf->name); pim->upstream_sg_wheel = wheel_init(router->master, 31000, 100, pim_upstream_hash_key, pim_upstream_sg_running, name); diff --git a/pimd/pim_vty.c b/pimd/pim_vty.c index fee8d6ed1b..1f2ca11db3 100644 --- a/pimd/pim_vty.c +++ b/pimd/pim_vty.c @@ -172,9 +172,9 @@ int pim_global_config_write_worker(struct pim_instance *pim, struct vty *vty) char spaces[10]; if (pim->vrf_id == VRF_DEFAULT) - sprintf(spaces, "%s", ""); + snprintf(spaces, sizeof(spaces), "%s", ""); else - sprintf(spaces, "%s", " "); + snprintf(spaces, sizeof(spaces), "%s", " "); writes += pim_msdp_config_write(pim, vty, spaces); diff --git a/ripd/ripd.c b/ripd/ripd.c index 30d2a59d77..fc53796bd2 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -2974,8 +2974,8 @@ static void rip_distance_show(struct vty *vty, struct rip *rip) " Address Distance List\n"); header = 0; } - sprintf(buf, "%s/%d", inet_ntoa(rn->p.u.prefix4), - rn->p.prefixlen); + snprintf(buf, sizeof(buf), "%s/%d", + inet_ntoa(rn->p.u.prefix4), rn->p.prefixlen); vty_out(vty, " %-20s %4d %s\n", buf, rdistance->distance, rdistance->access_list ? rdistance->access_list diff --git a/staticd/static_vty.c b/staticd/static_vty.c index 16cd64bcb6..75bce82eef 100644 --- a/staticd/static_vty.c +++ b/staticd/static_vty.c @@ -614,8 +614,8 @@ int static_config(struct vty *vty, struct static_vrf *svrf, afi_t afi, if (stable == NULL) return write; - sprintf(spacing, "%s%s", (svrf->vrf->vrf_id == VRF_DEFAULT) ? "" : " ", - cmd); + snprintf(spacing, sizeof(spacing), "%s%s", + (svrf->vrf->vrf_id == VRF_DEFAULT) ? "" : " ", cmd); /* * Static routes for vrfs not fully inited diff --git a/tests/lib/test_zmq.c b/tests/lib/test_zmq.c index b6624915e8..fe330d98d4 100644 --- a/tests/lib/test_zmq.c +++ b/tests/lib/test_zmq.c @@ -120,7 +120,7 @@ static void run_client(int syncfd) /* write callback */ printf("---\n"); - snprintf(buf, 32, "Done receiving"); + snprintf(buf, sizeof(buf), "Done receiving"); printf("client send: %s\n", buf); fflush(stdout); send_delim(zmqsock); diff --git a/tests/topotests/all-protocol-startup/r1/show_bgp_ipv6_summary.ref b/tests/topotests/all-protocol-startup/r1/show_bgp_ipv6_summary.ref index 3b140e3698..1e41263e78 100644 --- a/tests/topotests/all-protocol-startup/r1/show_bgp_ipv6_summary.ref +++ b/tests/topotests/all-protocol-startup/r1/show_bgp_ipv6_summary.ref @@ -3,6 +3,6 @@ BGP table version 1 RIB entries 1, using XXXX bytes of memory Peers 2, using XXXX KiB of memory -Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd -fc00:0:0:8::1000 4 100 0 0 0 0 0 never Active -fc00:0:0:8::2000 4 200 0 0 0 0 0 never Active +Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd PfxSnt +fc00:0:0:8::1000 4 100 0 0 0 0 0 never Active 0 +fc00:0:0:8::2000 4 200 0 0 0 0 0 never Active 0 diff --git a/tests/topotests/all-protocol-startup/r1/show_ip_bgp_summary.ref b/tests/topotests/all-protocol-startup/r1/show_ip_bgp_summary.ref index 7a246b1149..3ffbf3ff42 100644 --- a/tests/topotests/all-protocol-startup/r1/show_ip_bgp_summary.ref +++ b/tests/topotests/all-protocol-startup/r1/show_ip_bgp_summary.ref @@ -3,8 +3,8 @@ BGP table version 1 RIB entries 1, using XXXX bytes of memory Peers 4, using XXXX KiB of memory -Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd -192.168.7.10 4 100 0 0 0 0 0 never Active -192.168.7.20 4 200 0 0 0 0 0 never Active -fc00:0:0:8::1000 4 100 0 0 0 0 0 never Active -fc00:0:0:8::2000 4 200 0 0 0 0 0 never Active +Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd PfxSnt +192.168.7.10 4 100 0 0 0 0 0 never Active 0 +192.168.7.20 4 200 0 0 0 0 0 never Active 0 +fc00:0:0:8::1000 4 100 0 0 0 0 0 never Active 0 +fc00:0:0:8::2000 4 200 0 0 0 0 0 never Active 0 diff --git a/tests/topotests/bgp_multiview_topo1/test_bgp_multiview_topo1.py b/tests/topotests/bgp_multiview_topo1/test_bgp_multiview_topo1.py index c342b17dd2..a2020ffa55 100755 --- a/tests/topotests/bgp_multiview_topo1/test_bgp_multiview_topo1.py +++ b/tests/topotests/bgp_multiview_topo1/test_bgp_multiview_topo1.py @@ -29,19 +29,19 @@ test_bgp_multiview_topo1.py: Simple Quagga/FRR Route-Server Test | peer1 | | peer2 | | peer3 | | peer4 | | peer5 | | AS 65001 | | AS 65002 | | AS 65003 | | AS 65004 | | AS 65005 | +-----+----+ +-----+----+ +-----+----+ +-----+----+ +-----+----+ - | .1 | .2 | .3 | .4 | .5 + | .1 | .2 | .3 | .4 | .5 | ______/ / / _________/ - \ / ________________/ / / - | | / _________________________/ / +----------+ + \ / ________________/ / / + | | / _________________________/ / +----------+ | | | / __________________________/ ___| peer6 | | | | | / ____________________________/.6 | AS 65006 | | | | | | / _________________________ +----------+ - | | | | | | / __________________ \ +----------+ + | | | | | | / __________________ \ +----------+ | | | | | | | / \ \___| peer7 | | | | | | | | | \ .7 | AS 65007 | ~~~~~~~~~~~~~~~~~~~~~ \ +----------+ ~~ SW1 ~~ \ +----------+ - ~~ Switch ~~ \_____| peer8 | + ~~ Switch ~~ \_____| peer8 | ~~ 172.16.1.0/24 ~~ .8 | AS 65008 | ~~~~~~~~~~~~~~~~~~~~~ +----------+ | @@ -49,7 +49,7 @@ test_bgp_multiview_topo1.py: Simple Quagga/FRR Route-Server Test +---------+---------+ | FRR R1 | | BGP Multi-View | - | Peer 1-3 > View 1 | + | Peer 1-3 > View 1 | | Peer 4-5 > View 2 | | Peer 6-8 > View 3 | +---------+---------+ @@ -226,7 +226,7 @@ def test_bgp_converge(): for i in range(1, 2): for view in range(1, 4): notConverged = net["r%s" % i].cmd( - 'vtysh -c "show ip bgp view %s summary" 2> /dev/null | grep ^[0-9] | grep -v " 11$"' + 'vtysh -c "show ip bgp view %s summary" 2> /dev/null | grep ^[0-9] | grep -vP " 11\s+(\d+)$"' % view ) if notConverged: diff --git a/tools/cocci.h b/tools/cocci.h index d25fcbbe23..8ca42b349f 100644 --- a/tools/cocci.h +++ b/tools/cocci.h @@ -27,3 +27,61 @@ struct type *le_next; /* next element */ \ struct type **le_prev; /* address of previous next element */ \ } + +#define STREAM_GETC(S, P) \ + do { \ + uint8_t _pval; \ + if (!stream_getc2((S), &_pval)) \ + goto stream_failure; \ + (P) = _pval; \ + } while (0) + +#define STREAM_GETW(S, P) \ + do { \ + uint16_t _pval; \ + if (!stream_getw2((S), &_pval)) \ + goto stream_failure; \ + (P) = _pval; \ + } while (0) + +#define STREAM_GETL(S, P) \ + do { \ + uint32_t _pval; \ + if (!stream_getl2((S), &_pval)) \ + goto stream_failure; \ + (P) = _pval; \ + } while (0) + +#define STREAM_GETF(S, P) \ + do { \ + union { \ + float r; \ + uint32_t d; \ + } _pval; \ + if (stream_getl2((S), &_pval.d)) \ + goto stream_failure; \ + (P) = _pval.r; \ + } while (0) + +#define STREAM_GETQ(S, P) \ + do { \ + uint64_t _pval; \ + if (!stream_getq2((S), &_pval)) \ + goto stream_failure; \ + (P) = _pval; \ + } while (0) + +#define STREAM_GET(P, STR, SIZE) \ + do { \ + if (!stream_get2((P), (STR), (SIZE))) \ + goto stream_failure; \ + } while (0) + +#define AF_FOREACH(af) for ((af) = BGP_AF_START; (af) < BGP_AF_MAX; (af)++) + +#define FOREACH_AFI_SAFI(afi, safi) \ + \ + for (afi = AFI_IP; afi < AFI_MAX; afi++) \ + for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) + +#define FOREACH_SAFI(safi) for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) diff --git a/tools/start-stop-daemon.c b/tools/start-stop-daemon.c index 13118a2769..7ad2a84500 100644 --- a/tools/start-stop-daemon.c +++ b/tools/start-stop-daemon.c @@ -605,9 +605,9 @@ static void parse_options(int argc, char *const *argv) static int pid_is_exec(pid_t pid, const struct stat *esb) { struct stat sb; - char buf[32]; + char buf[PATH_MAX]; - sprintf(buf, "/proc/%ld/exe", (long)pid); + snprintf(buf, sizeof(buf), "/proc/%ld/exe", (long)pid); if (stat(buf, &sb) != 0) return 0; return (sb.st_dev == esb->st_dev && sb.st_ino == esb->st_ino); @@ -617,9 +617,9 @@ static int pid_is_exec(pid_t pid, const struct stat *esb) static int pid_is_user(pid_t pid, uid_t uid) { struct stat sb; - char buf[32]; + char buf[PATH_MAX]; - sprintf(buf, "/proc/%ld", (long)pid); + snprintf(buf, sizeof(buf), "/proc/%ld", (long)pid); if (stat(buf, &sb) != 0) return 0; return (sb.st_uid == uid); @@ -628,11 +628,11 @@ static int pid_is_user(pid_t pid, uid_t uid) static int pid_is_cmd(pid_t pid, const char *name) { - char buf[32]; + char buf[PATH_MAX]; FILE *f; int c; - sprintf(buf, "/proc/%ld/stat", (long)pid); + snprintf(buf, sizeof(buf), "/proc/%ld/stat", (long)pid); f = fopen(buf, "r"); if (!f) return 0; diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c index 9b1f0208e0..abbb111f9d 100644 --- a/vtysh/vtysh_config.c +++ b/vtysh/vtysh_config.c @@ -543,7 +543,8 @@ void vtysh_config_write(void) } if (cmd_domainname_get()) { - sprintf(line, "domainname %s", cmd_domainname_get()); + snprintf(line, sizeof(line), "domainname %s", + cmd_domainname_get()); vtysh_config_parse_line(NULL, line); } if (vtysh_write_integrated == WRITE_INTEGRATED_NO) diff --git a/vtysh/vtysh_user.c b/vtysh/vtysh_user.c index a7067984c4..665e6ca90d 100644 --- a/vtysh/vtysh_user.c +++ b/vtysh/vtysh_user.c @@ -115,7 +115,8 @@ void user_config_write(void) for (ALL_LIST_ELEMENTS(userlist, node, nnode, user)) { if (user->nopassword) { - sprintf(line, "username %s nopassword", user->name); + snprintf(line, sizeof(line), "username %s nopassword", + user->name); config_add_line(config_top, line); } } diff --git a/yang/frr-igmp.yang b/yang/frr-igmp.yang index 7f750dcf3e..534fd78480 100644 --- a/yang/frr-igmp.yang +++ b/yang/frr-igmp.yang @@ -21,7 +21,7 @@ module frr-igmp { } organization - "Free Range Routing"; + "FRRouting"; contact "FRR Users List: <mailto:frog@lists.frrouting.org> diff --git a/yang/frr-pim-rp.yang b/yang/frr-pim-rp.yang new file mode 100644 index 0000000000..fb0a5aa209 --- /dev/null +++ b/yang/frr-pim-rp.yang @@ -0,0 +1,133 @@ +module frr-pim-rp { + yang-version "1.1"; + namespace "http://frrouting.org/yang/pim-rp"; + + prefix frr-pim-rp; + + import ietf-inet-types { + prefix "inet"; + } + + import ietf-routing-types { + prefix "rt-types"; + } + + import frr-routing { + prefix "frr-rt"; + } + + import frr-pim { + prefix "frr-pim"; + } + + organization + "FRRouting"; + + contact + "FRR Users List: <mailto:frog@lists.frrouting.org> + FRR Development List: <mailto:dev@lists.frrouting.org>"; + + description + "The module defines a collection of YANG definitions common for + all PIM (Protocol Independent Multicast) RP (Rendezvous Point) model."; + + revision 2017-03-09 { + description + "Initial revision."; + reference + "RFC XXXX: A YANG Data Model for PIM RP"; + } + + typedef ipv4-multicast-group-address-prefix { + type inet:ipv4-prefix{ + pattern '(2((2[4-9])|(3[0-9]))\.)(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){2}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(/(([4-9])|([1-2][0-9])|(3[0-2])))'; + } + description + "This type represents an IPv4 multicast group prefix, + which is in the range from 224.0.0.0 to 239.255.255.255."; + } + + typedef ipv6-multicast-group-address-prefix { + type inet:ipv6-prefix { + pattern + '(((FF|ff)[0-9a-fA-F]{2}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(/((1[6-9])|([2-9][0-9])|(1[0-1][0-9])|(12[0-8])))'; + pattern + '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)(/.+)'; + } + description + "This type represents an IPv6 multicast group prefix, + which is in the range of FF00::/8."; + } + + typedef ip-multicast-group-address-prefix { + description "The IP-Multicast-Group-Address-Prefix type represents an IP multicast address + prefix and is IP version neutral. The format of the textual representations implies the IP + version. It includes a prefix-length, separated by a '/' sign."; + type union { + type ipv4-multicast-group-address-prefix; + type ipv6-multicast-group-address-prefix; + } + } // typedef ip-multicast-group-address-prefix + + typedef plist-ref { + type string; + } + + /* + * Groupings + */ + grouping static-rp-container { + description + "Grouping of static RP container."; + + container static-rp { + description + "Containing static RP attributes."; + + list rp-list { + key "rp-address"; + description + "A list of RP addresses."; + + leaf rp-address { + type inet:ip-address; + description + "Specifies a static RP address."; + } + + choice group-list-or-prefix-list { + description "Use group-list or prefix-list"; + case group-list { + leaf-list group-list{ + type ip-multicast-group-address-prefix; + description + "List of multicast group address."; + } + } + case prefix-list { + leaf prefix-list { + type plist-ref; + description + "Group prefix-list filter"; + } + } + } + } + } // static-rp + } // static-rp-container + + /* + * Configuration data nodes + */ + augment "/frr-rt:routing/frr-rt:control-plane-protocols/" + + "frr-rt:control-plane-protocol/frr-pim:pim/" + + "frr-pim:address-family" { + description "PIM RP augmentation."; + + container rp { + description + "PIM RP configuration data."; + uses static-rp-container; + } // rp + } // augment +} diff --git a/yang/frr-pim.yang b/yang/frr-pim.yang new file mode 100644 index 0000000000..3b2ebdf6d3 --- /dev/null +++ b/yang/frr-pim.yang @@ -0,0 +1,446 @@ +module frr-pim { + yang-version "1.1"; + namespace "http://frrouting.org/yang/pim"; + + prefix frr-pim; + + import frr-interface { + prefix frr-interface; + } + + import frr-routing { + prefix "frr-rt"; + } + + import ietf-routing-types { + prefix "rt-types"; + } + + import ietf-inet-types { + prefix "inet"; + } + + organization + "FRRouting"; + + contact + "FRR Users List: <mailto:frog@lists.frrouting.org> + FRR Development List: <mailto:dev@lists.frrouting.org>"; + + description + "The module defines a collection of YANG definitions common for + PIM (Protocol Independent Multicast) model."; + + revision 2017-03-09 { + description + "Initial revision."; + reference + "RFC XXXX: A YANG Data Model for PIM"; + } + + identity pimd { + base frr-rt:routing-protocol; + description + "'Pim' routing pseudo-protocol."; + } + + typedef plist-ref { + type string; + } + + /* + * Groupings + */ + + grouping global-pim-config-attributes { + description + "A grouping defining pim global attributes."; + + leaf ecmp { + type empty; + description + "Enable PIM ECMP."; + } + + leaf ecmp-rebalance { + type empty; + description + "Enable PIM ECMP Rebalance."; + } + + leaf join-prune-interval { + type uint16 { + range "60..600"; + } + default "60"; + description + "Join Prune Send Interval in seconds."; + } + + leaf keep-alive-timer { + type uint16 { + range "31..60000"; + } + default "210"; + description + "Keep alive Timer in seconds."; + } + + leaf rp-keep-alive-timer { + type uint16 { + range "31..60000"; + } + default "210"; + description + "RP keep alive Timer in seconds."; + } + + leaf packets { + type uint8 { + range "1..100"; + } + default "3"; + description + "Number of packets to process at one time per fd."; + } + + leaf register-suppress-time { + type uint16 { + range "5..60000"; + } + default "60"; + description + "Register Suppress Timer."; + } + } + + grouping per-af-global-pim-config-attributes { + description + "A grouping defining per address family pim global attributes"; + + leaf send-v6-secondary { + when "../frr-pim:address-family = 'frr-rt:ipv4'" { + description + "Only applicable to IPv4 address family."; + } + type empty; + description + "Send v6 secondary addresses."; + } + + container spt-switchover { + description + "SPT-Switchover."; + + leaf spt-action { + type enumeration { + enum "PIM_SPT_IMMEDIATE" { + value 0; + description + "Immediate switch to SPT Tree."; + } + enum "PIM_SPT_INFINITY" { + value 1; + description + "Never switch to SPT Tree."; + } + } + default "PIM_SPT_IMMEDIATE"; + description + "SPT-Switchover action"; + } + + leaf spt-infinity-prefix-list { + when "../spt-action = 'PIM_SPT_INFINITY'" { + description + "This leaf is only valid when the spt action + is PIM_SPT_INFINITY."; + } + type plist-ref; + description + "Prefix-List to control which groups to switch."; + } + } + + leaf ssm-prefix-list { + type plist-ref; + description + "Prefix-list used to define Source-Specific Multicast address range."; + } + + leaf-list ssm-pingd-source-ip { + type inet:ip-address; + description + "Enable ssmpingd operation."; + } + + container msdp-mesh-group { + presence + "Configure MSDP mesh-group."; + + leaf mesh-group-name { + type string; + description + "MSDP mesh group name."; + } + + leaf-list member-ip { + type inet:ip-address; + description + "Peer ip address."; + } + + leaf source-ip { + type inet:ip-address; + description + "Source ip address for the TCP connection."; + } + } + + list msdp-peer { + key "peer-ip"; + description + "Configure MSDP peer."; + + leaf peer-ip { + type inet:ip-address; + description + "MSDP peer IP address."; + } + + leaf source-ip { + type inet:ip-address; + description + "MSDP source IP address."; + } + } + + container mlag { + description + "Multi-chassis link aggregation."; + + leaf peerlink-rif { + type frr-interface:interface-ref; + description + "Outgoing interface name."; + } + + leaf reg-address { + type inet:ip-address; + description + "reg address."; + } + + leaf my-role { + type enumeration { + enum "MLAG_ROLE_NONE" { + value 0; + description + "MLAG role none."; + } + enum "MLAG_ROLE_PRIMARY" { + value 1; + description + "MLAG role primary."; + } + + enum "MLAG_ROLE_SECONDARY" { + value 2; + description + "MLAG role secondary."; + } + } + default "MLAG_ROLE_NONE"; + description + "Mlag role."; + } + + leaf peer-state { + type boolean; + default "false"; + description + "Peer state"; + } + } + + leaf register-accept-list { + type plist-ref; + description + "Only accept registers from a specific source prefix list."; + } + } // per-af-global-pim-config-attributes + + grouping interface-pim-config-attributes { + description + "A grouping defining pim interface attributes."; + + leaf pim-enable { + type empty; + description + "Enable PIM flag on the interface."; + } + + leaf dr-priority { + type uint32 { + range "1..4294967295"; + } + default 1; + description + "DR (Designated Router) priority"; + } + + leaf hello-interval { + type uint16 { + range "1..180"; + } + default "30"; + description + "Hello interval"; + } + + leaf hello-holdtime { + type uint16 { + range "1..180"; + } + description + "Hello holdtime"; + } + + container bfd { + presence + "Enable BFD support on the interface."; + + leaf min-rx-interval { + type uint16 { + range "50..60000"; + } + default "300"; + description + "Required min receive interval"; + } + + leaf min-tx-interval { + type uint16 { + range "50..60000"; + } + default "300"; + description + "Desired min transmit interval"; + } + + leaf detect_mult { + type uint8 { + range "2..255"; + } + default "3"; + description + "Detect Multiplier"; + } + } + + leaf bsm { + type empty; + description + "Enables BSM support on the interface."; + } + + leaf unicast-bsm { + type empty; + description + "Accept/Send unicast BSM on the interface."; + } + + leaf active-active { + type empty; + description + "Mark interface as Active-Active for MLAG operations."; + } + } // interface-pim-config-attributes + + grouping per-af-interface-pim-config-attributes { + description + "A grouping defining pim interface attributes per address family."; + + leaf use-source { + type inet:ip-address; + description + "Primary address of the interface set by user."; + } + + leaf multicast-boundary-oil { + type plist-ref; + description + "Prefix-List to define multicast boundary"; + } + + list mroute { + key "source-addr group-addr"; + description + "Add multicast route."; + + leaf oif { + type frr-interface:interface-ref; + description + "Outgoing interface name."; + } + + leaf source-addr { + type inet:ip-address; + description + "Multicast source address."; + } + + leaf group-addr { + type rt-types:ip-multicast-group-address; + description + "Multicast group address."; + } + } + } // per-af-interface-pim-config-attributes + + /* + * Global Configuration data nodes + */ + augment "/frr-rt:routing/frr-rt:control-plane-protocols/" + + "frr-rt:control-plane-protocol" { + container pim { + when "../frr-rt:type = 'frr-pim:pimd'" { + description + "This container is only valid for the 'pim' routing + protocol."; + } + description + "PIM configuration data."; + + uses global-pim-config-attributes; + + list address-family { + key "address-family"; + description + "Each list entry for one address family."; + uses frr-rt:address-family; + uses per-af-global-pim-config-attributes; + + } //address-family + } // pim + } // augment + + /* + * Per-interface configuration data + */ + augment "/frr-interface:lib/frr-interface:interface" { + container pim { + description + "PIM interface parameters."; + uses interface-pim-config-attributes; + list address-family { + key "address-family"; + description + "Each list entry for one address family."; + uses frr-rt:address-family; + uses per-af-interface-pim-config-attributes; + } + } + } +} + diff --git a/yang/frr-routing.yang b/yang/frr-routing.yang index 615a81c722..ff84954aaf 100644 --- a/yang/frr-routing.yang +++ b/yang/frr-routing.yang @@ -12,7 +12,7 @@ module frr-routing { } organization - "Free Range Routing"; + "FRRouting"; contact "FRR Users List: <mailto:frog@lists.frrouting.org> diff --git a/yang/frr-staticd.yang b/yang/frr-staticd.yang index 58933c9040..ce8d641de1 100644 --- a/yang/frr-staticd.yang +++ b/yang/frr-staticd.yang @@ -17,7 +17,7 @@ module frr-staticd { } organization - "Free Range Routing"; + "FRRouting"; contact "FRR Users List: <mailto:frog@lists.frrouting.org> diff --git a/yang/subdir.am b/yang/subdir.am index 5393781d22..6caf9fc5f3 100644 --- a/yang/subdir.am +++ b/yang/subdir.am @@ -31,6 +31,8 @@ dist_yangmodels_DATA += yang/frr-routing.yang dist_yangmodels_DATA += yang/ietf/ietf-routing-types.yang dist_yangmodels_DATA += yang/frr-igmp.yang dist_yangmodels_DATA += yang/ietf/ietf-interfaces.yang +dist_yangmodels_DATA += yang/frr-pim.yang +dist_yangmodels_DATA += yang/frr-pim-rp.yang if BFDD dist_yangmodels_DATA += yang/frr-bfdd.yang diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index 78155b1455..17b6edfed0 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -275,7 +275,7 @@ static void netlink_determine_zebra_iftype(const char *kind, netlink_parse_rtattr((tb), (max), RTA_DATA(rta), RTA_PAYLOAD(rta)) static void netlink_vrf_change(struct nlmsghdr *h, struct rtattr *tb, - const char *name) + uint32_t ns_id, const char *name) { struct ifinfomsg *ifi; struct rtattr *linkinfo[IFLA_INFO_MAX + 1]; @@ -310,10 +310,22 @@ static void netlink_vrf_change(struct nlmsghdr *h, struct rtattr *tb, nl_table_id = *(uint32_t *)RTA_DATA(attr[IFLA_VRF_TABLE]); if (h->nlmsg_type == RTM_NEWLINK) { + vrf_id_t exist_id; + if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug("RTM_NEWLINK for VRF %s(%u) table %u", name, ifi->ifi_index, nl_table_id); + exist_id = vrf_lookup_by_table(nl_table_id, ns_id); + if (exist_id != VRF_DEFAULT) { + vrf = vrf_lookup_by_id(exist_id); + + flog_err( + EC_ZEBRA_VRF_MISCONFIGURED, + "VRF %s id %u table id overlaps existing vrf %s, misconfiguration exiting", + name, ifi->ifi_index, vrf->name); + exit(-1); + } /* * vrf_get is implied creation if it does not exist */ @@ -664,7 +676,7 @@ static int netlink_interface(struct nlmsghdr *h, ns_id_t ns_id, int startup) /* If VRF, create the VRF structure itself. */ if (zif_type == ZEBRA_IF_VRF && !vrf_is_backend_netns()) { - netlink_vrf_change(h, tb[IFLA_LINKINFO], name); + netlink_vrf_change(h, tb[IFLA_LINKINFO], ns_id, name); vrf_id = (vrf_id_t)ifi->ifi_index; } @@ -1226,7 +1238,7 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) /* If VRF, create or update the VRF structure itself. */ if (zif_type == ZEBRA_IF_VRF && !vrf_is_backend_netns()) { - netlink_vrf_change(h, tb[IFLA_LINKINFO], name); + netlink_vrf_change(h, tb[IFLA_LINKINFO], ns_id, name); vrf_id = (vrf_id_t)ifi->ifi_index; } diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 5c9d2f69a6..4630b8a8e9 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -290,7 +290,7 @@ static inline int proto2zebra(int proto, int family, bool is_nexthop) /* Pending: create an efficient table_id (in a tree/hash) based lookup) */ -static vrf_id_t vrf_lookup_by_table(uint32_t table_id, ns_id_t ns_id) +vrf_id_t vrf_lookup_by_table(uint32_t table_id, ns_id_t ns_id) { struct vrf *vrf; struct zebra_vrf *zvrf; @@ -904,8 +904,8 @@ static int netlink_route_change_read_multicast(struct nlmsghdr *h, ifp = if_lookup_by_index(oif[count], vrf); char temp[256]; - sprintf(temp, "%s(%d) ", ifp ? ifp->name : "Unknown", - oif[count]); + snprintf(temp, sizeof(temp), "%s(%d) ", + ifp ? ifp->name : "Unknown", oif[count]); strlcat(oif_list, temp, sizeof(oif_list)); } zvrf = zebra_vrf_lookup_by_id(vrf); @@ -1087,7 +1087,8 @@ static int build_label_stack(struct mpls_label_stack *nh_label, sprintf(label_buf, "label %u", nh_label->label[i]); else { - sprintf(label_buf1, "/%u", nh_label->label[i]); + snprintf(label_buf1, sizeof(label_buf1), "/%u", + nh_label->label[i]); strlcat(label_buf, label_buf1, label_buf_size); } } @@ -2686,7 +2687,7 @@ static int netlink_macfdb_change(struct nlmsghdr *h, int len, ns_id_t ns_id) if ((NDA_VLAN <= NDA_MAX) && tb[NDA_VLAN]) { vid_present = 1; vid = *(uint16_t *)RTA_DATA(tb[NDA_VLAN]); - sprintf(vid_buf, " VLAN %u", vid); + snprintf(vid_buf, sizeof(vid_buf), " VLAN %u", vid); } if (tb[NDA_DST]) { @@ -2694,7 +2695,8 @@ static int netlink_macfdb_change(struct nlmsghdr *h, int len, ns_id_t ns_id) dst_present = 1; memcpy(&vtep_ip.s_addr, RTA_DATA(tb[NDA_DST]), IPV4_MAX_BYTELEN); - sprintf(dst_buf, " dst %s", inet_ntoa(vtep_ip)); + snprintf(dst_buf, sizeof(dst_buf), " dst %s", + inet_ntoa(vtep_ip)); } if (IS_ZEBRA_DEBUG_KERNEL) diff --git a/zebra/rt_netlink.h b/zebra/rt_netlink.h index d6a993e78a..a364d305c5 100644 --- a/zebra/rt_netlink.h +++ b/zebra/rt_netlink.h @@ -92,6 +92,7 @@ extern int netlink_macfdb_read_specific_mac(struct zebra_ns *zns, struct ethaddr *mac, uint16_t vid); extern int netlink_neigh_read_specific_ip(struct ipaddr *ip, struct interface *vlan_if); +extern vrf_id_t vrf_lookup_by_table(uint32_t table_id, ns_id_t ns_id); #ifdef __cplusplus } diff --git a/zebra/zebra_errors.c b/zebra/zebra_errors.c index ef792d14c2..b75708031e 100644 --- a/zebra/zebra_errors.c +++ b/zebra/zebra_errors.c @@ -786,6 +786,12 @@ static struct log_ref ferr_zebra_err[] = { "See if the nexthop you are trying to add is already present in the fib." }, { + .code = EC_ZEBRA_VRF_MISCONFIGURED, + .title = "Duplicate VRF table id detected", + .description = "Zebra has detected a situation where there are two vrf devices with the exact same tableid. This is considered a complete misconfiguration of VRF devices and breaks a fundamental assumption in FRR about how VRF's work", + .suggestion = "Use different table id's for the VRF's in question" + }, + { .code = END_FERR, } }; diff --git a/zebra/zebra_errors.h b/zebra/zebra_errors.h index 4625a03ae6..395004d0bb 100644 --- a/zebra/zebra_errors.h +++ b/zebra/zebra_errors.h @@ -132,6 +132,7 @@ enum zebra_log_refs { EC_ZEBRA_DUP_IP_DETECTED, EC_ZEBRA_BAD_NHG_MESSAGE, EC_ZEBRA_DUPLICATE_NHG_MESSAGE, + EC_ZEBRA_VRF_MISCONFIGURED, }; void zebra_error_init(void); diff --git a/zebra/zebra_fpm.c b/zebra/zebra_fpm.c index 41d73f3c97..8f97c8cf47 100644 --- a/zebra/zebra_fpm.c +++ b/zebra/zebra_fpm.c @@ -760,8 +760,9 @@ static int zfpm_read_cb(struct thread *thread) if (nbyte == -1) { char buffer[1024]; - sprintf(buffer, "closed socket in read(%d): %s", - errno, safe_strerror(errno)); + snprintf(buffer, sizeof(buffer), + "closed socket in read(%d): %s", errno, + safe_strerror(errno)); zfpm_connection_down(buffer); } else zfpm_connection_down("closed socket in read"); @@ -797,8 +798,9 @@ static int zfpm_read_cb(struct thread *thread) if (nbyte == -1) { char buffer[1024]; - sprintf(buffer, "failed to read message(%d) %s", - errno, safe_strerror(errno)); + snprintf(buffer, sizeof(buffer), + "failed to read message(%d) %s", errno, + safe_strerror(errno)); zfpm_connection_down(buffer); } else zfpm_connection_down("failed to read message"); diff --git a/zebra/zebra_mlag.h b/zebra/zebra_mlag.h index d44a400666..66f5c4c67e 100644 --- a/zebra/zebra_mlag.h +++ b/zebra/zebra_mlag.h @@ -30,6 +30,10 @@ #include "mlag/mlag.pb-c.h" #endif +#ifdef __cplusplus +extern "C" { +#endif + #define ZEBRA_MLAG_BUF_LIMIT 2048 #define ZEBRA_MLAG_LEN_SIZE 4 @@ -73,4 +77,8 @@ int zebra_mlag_protobuf_encode_client_data(struct stream *s, uint32_t *msg_type); int zebra_mlag_protobuf_decode_message(struct stream *s, uint8_t *data, uint32_t len); +#ifdef __cplusplus +} +#endif + #endif diff --git a/zebra/zebra_mlag_vty.h b/zebra/zebra_mlag_vty.h index c3dfdf74e0..789154d684 100644 --- a/zebra/zebra_mlag_vty.h +++ b/zebra/zebra_mlag_vty.h @@ -22,10 +22,18 @@ #ifndef __ZEBRA_MLAG_VTY_CODE__ #define __ZEBRA_MLAG_VTY_CODE__ +#ifdef __cplusplus +extern "C" { +#endif + extern int32_t zebra_mlag_test_mlag_internal(const char *none, const char *primary, const char *secondary); extern void zebra_mlag_vty_init(void); +#ifdef __cplusplus +} +#endif + #endif diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index 999e91486d..0aaede4507 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -3335,7 +3335,8 @@ int zebra_mpls_write_lsp_config(struct vty *vty, struct zebra_vrf *zvrf) strlcpy(lstr, "implicit-null", sizeof(lstr)); break; default: - sprintf(lstr, "%u", snhlfe->out_label); + snprintf(lstr, sizeof(lstr), "%u", + snhlfe->out_label); break; } diff --git a/zebra/zebra_nb.h b/zebra/zebra_nb.h index 01a44e5525..32c72371e3 100644 --- a/zebra/zebra_nb.h +++ b/zebra/zebra_nb.h @@ -20,6 +20,10 @@ #ifndef ZEBRA_ZEBRA_NB_H_ #define ZEBRA_ZEBRA_NB_H_ +#ifdef __cplusplus +extern "C" { +#endif + extern const struct frr_yang_module_info frr_zebra_info; /* prototypes */ @@ -485,4 +489,8 @@ struct yang_data * lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_weight_get_elem( const char *xpath, const void *list_entry); +#ifdef __cplusplus +} +#endif + #endif diff --git a/zebra/zebra_netns_notify.c b/zebra/zebra_netns_notify.c index d42cf3d60a..c5d11f1837 100644 --- a/zebra/zebra_netns_notify.c +++ b/zebra/zebra_netns_notify.c @@ -153,10 +153,10 @@ static int zebra_ns_delete(char *name) static int zebra_ns_notify_self_identify(struct stat *netst) { - char net_path[64]; + char net_path[PATH_MAX]; int netns; - sprintf(net_path, "/proc/self/ns/net"); + snprintf(net_path, sizeof(net_path), "/proc/self/ns/net"); netns = open(net_path, O_RDONLY); if (netns < 0) return -1; @@ -178,7 +178,7 @@ static bool zebra_ns_notify_is_default_netns(const char *name) return false; memset(&st, 0, sizeof(struct stat)); - snprintf(netnspath, 64, "%s/%s", NS_RUN_DIR, name); + snprintf(netnspath, sizeof(netnspath), "%s/%s", NS_RUN_DIR, name); /* compare with local stat */ if (stat(netnspath, &st) == 0 && (st.st_dev == default_netns_stat.st_dev) && diff --git a/zebra/zebra_nhg.h b/zebra/zebra_nhg.h index 0a9e97ab48..5792584d0f 100644 --- a/zebra/zebra_nhg.h +++ b/zebra/zebra_nhg.h @@ -26,6 +26,10 @@ #include "lib/nexthop.h" #include "lib/nexthop_group.h" +#ifdef __cplusplus +extern "C" { +#endif + /* This struct is used exclusively for dataplane * interaction via a dataplane context. * @@ -269,4 +273,8 @@ extern void zebra_nhg_sweep_table(struct hash *hash); struct route_entry; /* Forward ref to avoid circular includes */ extern int nexthop_active_update(struct route_node *rn, struct route_entry *re); +#ifdef __cplusplus +} +#endif + #endif /* __ZEBRA_NHG_H__ */ diff --git a/zebra/zebra_nhg_private.h b/zebra/zebra_nhg_private.h index 92f438fcec..25048258d5 100644 --- a/zebra/zebra_nhg_private.h +++ b/zebra/zebra_nhg_private.h @@ -30,6 +30,10 @@ #include "zebra/zebra_nhg.h" +#ifdef __cplusplus +extern "C" { +#endif + /* Abstraction for connected trees */ struct nhg_connected { struct nhg_connected_tree_item tree_item; @@ -70,4 +74,8 @@ extern struct nhg_hash_entry * nhg_connected_tree_add_nhe(struct nhg_connected_tree_head *head, struct nhg_hash_entry *nhe); +#ifdef __cplusplus +} +#endif + #endif /* __ZEBRA_NHG_PRIVATE_H__ */ diff --git a/zebra/zebra_pbr.c b/zebra/zebra_pbr.c index c049aa14f6..62cbcbda4b 100644 --- a/zebra/zebra_pbr.c +++ b/zebra/zebra_pbr.c @@ -877,16 +877,15 @@ static void zebra_pbr_display_icmp(struct vty *vty, /* range icmp type */ if (zpie->src_port_max || zpie->dst_port_max) { - vty_out(vty, ":icmp:[type <%d:%d>;code <%d:%d>", + vty_out(vty, ":icmp:[type <%u:%u>;code <%u:%u>", zpie->src_port_min, zpie->src_port_max, zpie->dst_port_min, zpie->dst_port_max); } else { port = ((zpie->src_port_min << 8) & 0xff00) + (zpie->dst_port_min & 0xff); memset(decoded_str, 0, sizeof(decoded_str)); - sprintf(decoded_str, "%d/%d", - zpie->src_port_min, - zpie->dst_port_min); + snprintf(decoded_str, sizeof(decoded_str), "%u/%u", + zpie->src_port_min, zpie->dst_port_min); vty_out(vty, ":icmp:%s", lookup_msg(icmp_typecode_str, port, decoded_str)); @@ -1129,7 +1128,7 @@ static void zebra_pbr_show_iptable_unit(struct zebra_pbr_iptable *iptable, if (iptable->fragment) { char val_str[10]; - sprintf(val_str, "%d", iptable->fragment); + snprintf(val_str, sizeof(val_str), "%d", iptable->fragment); vty_out(vty, "\t fragment%s %s\n", iptable->filter_bm & MATCH_FRAGMENT_INVERSE_SET ? " not" : "", lookup_msg(fragment_value_str, diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c index 669cb2466f..88ea2b87b1 100644 --- a/zebra/zebra_ptm.c +++ b/zebra/zebra_ptm.c @@ -132,7 +132,7 @@ void zebra_ptm_init(void) ptm_cb.pid = getpid(); zebra_ptm_install_commands(); - sprintf(buf, "%s", FRR_PTM_NAME); + snprintf(buf, sizeof(buf), "%s", FRR_PTM_NAME); ptm_hdl = ptm_lib_register(buf, NULL, zebra_ptm_handle_msg_cb, zebra_ptm_handle_msg_cb); ptm_cb.wb = buffer_new(0); @@ -710,16 +710,17 @@ void zebra_ptm_bfd_dst_register(ZAPI_HANDLER_ARGS) } ptm_lib_init_msg(ptm_hdl, 0, PTMLIB_MSG_TYPE_CMD, NULL, &out_ctxt); - sprintf(tmp_buf, "%s", ZEBRA_PTM_BFD_START_CMD); + snprintf(tmp_buf, sizeof(tmp_buf), "%s", ZEBRA_PTM_BFD_START_CMD); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_CMD_STR, tmp_buf); - sprintf(tmp_buf, "%s", zebra_route_string(client->proto)); + snprintf(tmp_buf, sizeof(tmp_buf), "%s", + zebra_route_string(client->proto)); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_CLIENT_FIELD, tmp_buf); s = msg; STREAM_GETL(s, pid); - sprintf(tmp_buf, "%d", pid); + snprintf(tmp_buf, sizeof(tmp_buf), "%d", pid); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_SEQID_FIELD, tmp_buf); @@ -742,21 +743,21 @@ void zebra_ptm_bfd_dst_register(ZAPI_HANDLER_ARGS) } STREAM_GETL(s, min_rx_timer); - sprintf(tmp_buf, "%d", min_rx_timer); + snprintf(tmp_buf, sizeof(tmp_buf), "%d", min_rx_timer); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_MIN_RX_FIELD, tmp_buf); STREAM_GETL(s, min_tx_timer); - sprintf(tmp_buf, "%d", min_tx_timer); + snprintf(tmp_buf, sizeof(tmp_buf), "%d", min_tx_timer); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_MIN_TX_FIELD, tmp_buf); STREAM_GETC(s, detect_mul); - sprintf(tmp_buf, "%d", detect_mul); + snprintf(tmp_buf, sizeof(tmp_buf), "%d", detect_mul); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_DETECT_MULT_FIELD, tmp_buf); STREAM_GETC(s, multi_hop); if (multi_hop) { - sprintf(tmp_buf, "%d", 1); + snprintf(tmp_buf, sizeof(tmp_buf), "%d", 1); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_MULTI_HOP_FIELD, tmp_buf); STREAM_GETW(s, src_p.family); @@ -778,7 +779,7 @@ void zebra_ptm_bfd_dst_register(ZAPI_HANDLER_ARGS) } STREAM_GETC(s, multi_hop_cnt); - sprintf(tmp_buf, "%d", multi_hop_cnt); + snprintf(tmp_buf, sizeof(tmp_buf), "%d", multi_hop_cnt); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_MAX_HOP_CNT_FIELD, tmp_buf); @@ -818,11 +819,11 @@ void zebra_ptm_bfd_dst_register(ZAPI_HANDLER_ARGS) ZEBRA_PTM_BFD_IFNAME_FIELD, if_name); } STREAM_GETC(s, cbit_set); - sprintf(tmp_buf, "%d", cbit_set); + snprintf(tmp_buf, sizeof(tmp_buf), "%d", cbit_set); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_CBIT_FIELD, tmp_buf); - sprintf(tmp_buf, "%d", 1); + snprintf(tmp_buf, sizeof(tmp_buf), "%d", 1); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_SEND_EVENT, tmp_buf); @@ -869,17 +870,18 @@ void zebra_ptm_bfd_dst_deregister(ZAPI_HANDLER_ARGS) ptm_lib_init_msg(ptm_hdl, 0, PTMLIB_MSG_TYPE_CMD, NULL, &out_ctxt); - sprintf(tmp_buf, "%s", ZEBRA_PTM_BFD_STOP_CMD); + snprintf(tmp_buf, sizeof(tmp_buf), "%s", ZEBRA_PTM_BFD_STOP_CMD); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_CMD_STR, tmp_buf); - sprintf(tmp_buf, "%s", zebra_route_string(client->proto)); + snprintf(tmp_buf, sizeof(tmp_buf), "%s", + zebra_route_string(client->proto)); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_CLIENT_FIELD, tmp_buf); s = msg; STREAM_GETL(s, pid); - sprintf(tmp_buf, "%d", pid); + snprintf(tmp_buf, sizeof(tmp_buf), "%d", pid); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_SEQID_FIELD, tmp_buf); @@ -900,7 +902,7 @@ void zebra_ptm_bfd_dst_deregister(ZAPI_HANDLER_ARGS) STREAM_GETC(s, multi_hop); if (multi_hop) { - sprintf(tmp_buf, "%d", 1); + snprintf(tmp_buf, sizeof(tmp_buf), "%d", 1); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_MULTI_HOP_FIELD, tmp_buf); @@ -996,14 +998,15 @@ void zebra_ptm_bfd_client_register(ZAPI_HANDLER_ARGS) ptm_lib_init_msg(ptm_hdl, 0, PTMLIB_MSG_TYPE_CMD, NULL, &out_ctxt); - sprintf(tmp_buf, "%s", ZEBRA_PTM_BFD_CLIENT_REG_CMD); + snprintf(tmp_buf, sizeof(tmp_buf), "%s", ZEBRA_PTM_BFD_CLIENT_REG_CMD); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_CMD_STR, tmp_buf); - sprintf(tmp_buf, "%s", zebra_route_string(client->proto)); + snprintf(tmp_buf, sizeof(tmp_buf), "%s", + zebra_route_string(client->proto)); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_CLIENT_FIELD, tmp_buf); - sprintf(tmp_buf, "%d", pid); + snprintf(tmp_buf, sizeof(tmp_buf), "%d", pid); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_SEQID_FIELD, tmp_buf); @@ -1054,10 +1057,11 @@ int zebra_ptm_bfd_client_deregister(struct zserv *client) ptm_lib_init_msg(ptm_hdl, 0, PTMLIB_MSG_TYPE_CMD, NULL, &out_ctxt); - sprintf(tmp_buf, "%s", ZEBRA_PTM_BFD_CLIENT_DEREG_CMD); + snprintf(tmp_buf, sizeof(tmp_buf), "%s", + ZEBRA_PTM_BFD_CLIENT_DEREG_CMD); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_CMD_STR, tmp_buf); - sprintf(tmp_buf, "%s", zebra_route_string(proto)); + snprintf(tmp_buf, sizeof(tmp_buf), "%s", zebra_route_string(proto)); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_CLIENT_FIELD, tmp_buf); diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 2dbe907751..447f3dc28d 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -2456,11 +2456,12 @@ static void _route_entry_dump_nh(const struct route_entry *re, switch (nexthop->type) { case NEXTHOP_TYPE_BLACKHOLE: - sprintf(nhname, "Blackhole"); + snprintf(nhname, sizeof(nhname), "Blackhole"); break; case NEXTHOP_TYPE_IFINDEX: ifp = if_lookup_by_index(nexthop->ifindex, nexthop->vrf_id); - sprintf(nhname, "%s", ifp ? ifp->name : "Unknown"); + snprintf(nhname, sizeof(nhname), "%s", + ifp ? ifp->name : "Unknown"); break; case NEXTHOP_TYPE_IPV4: /* fallthrough */ diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c index 2b3b3afbb5..9b2a58fd17 100644 --- a/zebra/zebra_routemap.c +++ b/zebra/zebra_routemap.c @@ -1860,7 +1860,7 @@ void zebra_routemap_config_write_protocol(struct vty *vty, memset(space, 0, sizeof(space)); if (zvrf_id(zvrf) != VRF_DEFAULT) - sprintf(space, "%s", " "); + snprintf(space, sizeof(space), "%s", " "); for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { if (PROTO_RM_NAME(zvrf, AFI_IP, i)) diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index d23cdfccd8..b9e7251117 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -967,7 +967,7 @@ static void zvni_print_neigh_hash_all_vni(struct hash_bucket *bucket, } else { json_vni = json_object_new_object(); json_object_int_add(json_vni, "numArpNd", num_neigh); - snprintf(vni_str, VNI_STR_LEN, "%u", zvni->vni); + snprintf(vni_str, sizeof(vni_str), "%u", zvni->vni); } if (!num_neigh) { @@ -1063,7 +1063,7 @@ static void zvni_print_neigh_hash_all_vni_detail(struct hash_bucket *bucket, } else { json_vni = json_object_new_object(); json_object_int_add(json_vni, "numArpNd", num_neigh); - snprintf(vni_str, VNI_STR_LEN, "%u", zvni->vni); + snprintf(vni_str, sizeof(vni_str), "%u", zvni->vni); } if (!num_neigh) { if (json) @@ -1534,7 +1534,7 @@ static void zvni_print_mac_hash_all_vni(struct hash_bucket *bucket, void *ctxt) if (json) { json_vni = json_object_new_object(); json_mac = json_object_new_object(); - snprintf(vni_str, VNI_STR_LEN, "%u", zvni->vni); + snprintf(vni_str, sizeof(vni_str), "%u", zvni->vni); } if (!CHECK_FLAG(wctx->flags, SHOW_REMOTE_MAC_FROM_VTEP)) { @@ -1610,7 +1610,7 @@ static void zvni_print_mac_hash_all_vni_detail(struct hash_bucket *bucket, if (json) { json_vni = json_object_new_object(); json_mac = json_object_new_object(); - snprintf(vni_str, VNI_STR_LEN, "%u", zvni->vni); + snprintf(vni_str, sizeof(vni_str), "%u", zvni->vni); } if (!CHECK_FLAG(wctx->flags, SHOW_REMOTE_MAC_FROM_VTEP)) { @@ -1693,7 +1693,7 @@ static void zl3vni_print_nh_hash_all_vni(struct hash_bucket *bucket, if (json) { json_vni = json_object_new_object(); - snprintf(vni_str, VNI_STR_LEN, "%u", zl3vni->vni); + snprintf(vni_str, sizeof(vni_str), "%u", zl3vni->vni); } if (json == NULL) { @@ -1732,7 +1732,7 @@ static void zl3vni_print_rmac_hash_all_vni(struct hash_bucket *bucket, if (json) { json_vni = json_object_new_object(); - snprintf(vni_str, VNI_STR_LEN, "%u", zl3vni->vni); + snprintf(vni_str, sizeof(vni_str), "%u", zl3vni->vni); } if (json == NULL) { @@ -1968,7 +1968,7 @@ static void zl3vni_print_hash(struct hash_bucket *bucket, void *ctx[]) } else { char vni_str[VNI_STR_LEN]; - snprintf(vni_str, VNI_STR_LEN, "%u", zl3vni->vni); + snprintf(vni_str, sizeof(vni_str), "%u", zl3vni->vni); json_vni = json_object_new_object(); json_object_int_add(json_vni, "vni", zl3vni->vni); json_object_string_add(json_vni, "vxlanIf", @@ -2053,7 +2053,7 @@ static void zvni_print_hash(struct hash_bucket *bucket, void *ctxt[]) vrf_id_to_name(zvni->vrf_id)); else { char vni_str[VNI_STR_LEN]; - snprintf(vni_str, VNI_STR_LEN, "%u", zvni->vni); + snprintf(vni_str, sizeof(vni_str), "%u", zvni->vni); json_vni = json_object_new_object(); json_object_int_add(json_vni, "vni", zvni->vni); json_object_string_add(json_vni, "type", "L2"); |
