diff options
| -rw-r--r-- | bgpd/bgp_aspath.c | 2 | ||||
| -rw-r--r-- | bgpd/bgp_attr.c | 3 | ||||
| -rw-r--r-- | bgpd/bgp_io.c | 7 | ||||
| -rw-r--r-- | bgpd/bgp_nexthop.c | 4 | ||||
| -rw-r--r-- | bgpd/bgp_route.c | 12 | ||||
| -rw-r--r-- | bgpd/bgp_updgrp_packet.c | 2 | ||||
| -rw-r--r-- | bgpd/bgp_vpn.c | 2 | ||||
| -rw-r--r-- | bgpd/bgp_vty.c | 1 | ||||
| -rw-r--r-- | doc/user/basic.rst | 12 | ||||
| -rw-r--r-- | eigrpd/eigrp_fsm.c | 8 | ||||
| -rw-r--r-- | eigrpd/eigrp_interface.c | 3 | ||||
| -rw-r--r-- | eigrpd/eigrp_topology.c | 14 | ||||
| -rw-r--r-- | isisd/isis_te.c | 2 | ||||
| -rw-r--r-- | isisd/isisd.c | 2 | ||||
| -rw-r--r-- | ldpd/ldp_debug.c | 3 | ||||
| -rw-r--r-- | ldpd/ldp_vty_conf.c | 51 | ||||
| -rw-r--r-- | ldpd/ldpd.c | 19 | ||||
| -rw-r--r-- | lib/command.c | 33 | ||||
| -rw-r--r-- | lib/command.h | 1 | ||||
| -rw-r--r-- | lib/imsg.c | 5 | ||||
| -rw-r--r-- | lib/libfrr.c | 47 | ||||
| -rw-r--r-- | lib/libfrr.h | 5 | ||||
| -rw-r--r-- | lib/plist.c | 5 | ||||
| -rw-r--r-- | lib/sockopt.c | 9 | ||||
| -rw-r--r-- | lib/sockunion.c | 3 | ||||
| -rw-r--r-- | lib/vty.c | 10 | ||||
| -rw-r--r-- | lib/vty.h | 2 | ||||
| -rw-r--r-- | ospf6d/ospf6_flood.c | 1 | ||||
| -rw-r--r-- | ospfd/ospf_vty.c | 8 | ||||
| -rw-r--r-- | pimd/mtracebis.c | 2 | ||||
| -rw-r--r-- | pimd/pim_cmd.c | 4 | ||||
| -rw-r--r-- | pimd/pim_pim.c | 2 | ||||
| -rw-r--r-- | tests/Makefile.am | 5 | ||||
| -rw-r--r-- | tools/start-stop-daemon.c | 6 | ||||
| -rw-r--r-- | vtysh/vtysh.c | 14 |
35 files changed, 246 insertions, 63 deletions
diff --git a/bgpd/bgp_aspath.c b/bgpd/bgp_aspath.c index e02617691f..05e67baa8a 100644 --- a/bgpd/bgp_aspath.c +++ b/bgpd/bgp_aspath.c @@ -1632,7 +1632,7 @@ struct aspath *aspath_reconcile_as4(struct aspath *aspath, struct aspath *newpath = NULL, *mergedpath; int hops, cpasns = 0; - if (!aspath) + if (!aspath || !as4path) return NULL; seg = aspath->segments; diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 2c52b57b36..6596e7cfa2 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -1513,6 +1513,9 @@ bgp_attr_munge_as4_attrs(struct peer *const peer, struct attr *const attr, if (!ignore_as4_path && (attr->flag & (ATTR_FLAG_BIT(BGP_ATTR_AS4_PATH)))) { newpath = aspath_reconcile_as4(attr->aspath, as4_path); + if (!newpath) + return BGP_ATTR_PARSE_ERROR; + aspath_unintern(&attr->aspath); attr->aspath = aspath_intern(newpath); } diff --git a/bgpd/bgp_io.c b/bgpd/bgp_io.c index 69c92e829c..c8d5b1daa1 100644 --- a/bgpd/bgp_io.c +++ b/bgpd/bgp_io.c @@ -174,7 +174,6 @@ static int bgp_process_reads(struct thread *thread) bool more = true; // whether we got more data bool fatal = false; // whether fatal error occurred bool added_pkt = false; // whether we pushed onto ->ibuf - bool header_valid = true; // whether header is valid /* clang-format on */ peer = THREAD_ARG(thread); @@ -214,10 +213,8 @@ static int bgp_process_reads(struct thread *thread) if (ringbuf_remain(ibw) < BGP_HEADER_SIZE) break; - /* validate header */ - header_valid = validate_header(peer); - - if (!header_valid) { + /* check that header is valid */ + if (!validate_header(peer)) { fatal = true; break; } diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c index fd8d894878..32011d210b 100644 --- a/bgpd/bgp_nexthop.c +++ b/bgpd/bgp_nexthop.c @@ -438,7 +438,7 @@ int bgp_subgrp_multiaccess_check_v4(struct in_addr nexthop, struct bgp_node *rn1, *rn2; struct peer_af *paf; struct prefix p, np; - struct bgp *bgp = NULL; + struct bgp *bgp; np.family = AF_INET; np.prefixlen = IPV4_MAX_BITLEN; @@ -447,7 +447,7 @@ int bgp_subgrp_multiaccess_check_v4(struct in_addr nexthop, p.family = AF_INET; p.prefixlen = IPV4_MAX_BITLEN; - rn1 = rn2 = NULL; + rn2 = NULL; bgp = SUBGRP_INST(subgrp); rn1 = bgp_node_match(bgp->connected_table[AFI_IP], &np); diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 95e7def8fb..0b1deba517 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -1318,6 +1318,8 @@ void bgp_attr_add_gshut_community(struct attr *attr) old = attr->community; gshut = community_str2com("graceful-shutdown"); + assert(gshut); + if (old) { merge = community_merge(community_dup(old), gshut); @@ -6564,14 +6566,8 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo, } else { char buf[BUFSIZ]; - if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_EVPN)) - snprintf(buf, sizeof(buf), "%s%s", - inet_ntoa(attr->mp_nexthop_global_in), - vrf_id_str); - else - snprintf(buf, sizeof(buf), "%s%s", - inet_ntoa(attr->nexthop), - vrf_id_str); + snprintf(buf, sizeof(buf), "%s%s", + inet_ntoa(attr->nexthop), vrf_id_str); vty_out(vty, "%-16s", buf); } } diff --git a/bgpd/bgp_updgrp_packet.c b/bgpd/bgp_updgrp_packet.c index cabd5b5cbd..34ddbfcd14 100644 --- a/bgpd/bgp_updgrp_packet.c +++ b/bgpd/bgp_updgrp_packet.c @@ -397,7 +397,7 @@ struct stream *bpacket_reformat_for_peer(struct bpacket *pkt, vec = &pkt->arr.entries[BGP_ATTR_VEC_NH]; if (CHECK_FLAG(vec->flags, BPKT_ATTRVEC_FLAGS_UPDATED)) { uint8_t nhlen; - afi_t nhafi = AFI_MAX; /* NH AFI is based on nhlen! */ + afi_t nhafi; int route_map_sets_nh; nhlen = stream_getc_from(s, vec->offset); if (peer_cap_enhe(peer, paf->afi, paf->safi)) diff --git a/bgpd/bgp_vpn.c b/bgpd/bgp_vpn.c index cc05194703..a771eedf0f 100644 --- a/bgpd/bgp_vpn.c +++ b/bgpd/bgp_vpn.c @@ -125,7 +125,7 @@ int show_adj_route_vpn(struct vty *vty, struct peer *peer, if (rd_header) { uint16_t type; - struct rd_as rd_as; + struct rd_as rd_as = {0}; struct rd_ip rd_ip = {0}; #if ENABLE_BGP_VNC struct rd_vnc_eth rd_vnc_eth = { diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 4e0f7155ba..d98104a9fa 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -11409,7 +11409,6 @@ DEFUN (show_ip_bgp_peer_groups, "Peer group name\n") { char *vrf, *pg; - vrf = pg = NULL; int idx = 0; vrf = argv_find(argv, argc, "VIEWVRFNAME", &idx) ? argv[idx]->arg diff --git a/doc/user/basic.rst b/doc/user/basic.rst index a75017c442..cb46080055 100644 --- a/doc/user/basic.rst +++ b/doc/user/basic.rst @@ -405,6 +405,18 @@ These options apply to all |PACKAGE_NAME| daemons. Print program version. +.. option:: --log <stdout|syslog|file:/path/to/log/file> + + When initializing the daemon, setup the log to go to either stdout, + syslog or to a file. These values will be displayed as part of + a show run. Additionally they can be overridden at runtime if + desired via the normal log commands. + +.. option:: --log-level <emergencies|alerts|critical|errors|warnings|notifications|informational|debugging> + + When initializing the daemon, allow the specification of a default + log level at startup from one of the specified levels. + .. _loadable-module-support: Loadable Module Support diff --git a/eigrpd/eigrp_fsm.c b/eigrpd/eigrp_fsm.c index 4107d44090..eeefc51968 100644 --- a/eigrpd/eigrp_fsm.c +++ b/eigrpd/eigrp_fsm.c @@ -486,6 +486,7 @@ int eigrp_fsm_event_q_fcn(struct eigrp_fsm_action_message *msg) int eigrp_fsm_event_keep_state(struct eigrp_fsm_action_message *msg) { + struct eigrp *eigrp; struct eigrp_prefix_entry *prefix = msg->prefix; struct eigrp_nexthop_entry *ne = listnode_head(prefix->entries); @@ -498,9 +499,10 @@ int eigrp_fsm_event_keep_state(struct eigrp_fsm_action_message *msg) if (msg->packet_type == EIGRP_OPC_QUERY) eigrp_send_reply(msg->adv_router, prefix); prefix->req_action |= EIGRP_FSM_NEED_UPDATE; - listnode_add( - (eigrp_lookup())->topology_changes_internalIPV4, - prefix); + eigrp = eigrp_lookup(); + assert(eigrp); + listnode_add(eigrp->topology_changes_internalIPV4, + prefix); } eigrp_topology_update_node_flags(prefix); eigrp_update_routing_table(prefix); diff --git a/eigrpd/eigrp_interface.c b/eigrpd/eigrp_interface.c index cd459fdc42..cd62811fdf 100644 --- a/eigrpd/eigrp_interface.c +++ b/eigrpd/eigrp_interface.c @@ -336,6 +336,9 @@ void eigrp_if_free(struct eigrp_interface *ei, int source) struct eigrp_prefix_entry *pe; struct eigrp *eigrp = eigrp_lookup(); + if (!eigrp) + return; + if (source == INTERFACE_DOWN_BY_VTY) { THREAD_OFF(ei->t_hello); eigrp_hello_send(ei, EIGRP_HELLO_GRACEFUL_SHUTDOWN, NULL); diff --git a/eigrpd/eigrp_topology.c b/eigrpd/eigrp_topology.c index becb29a95f..4e26446ebe 100644 --- a/eigrpd/eigrp_topology.c +++ b/eigrpd/eigrp_topology.c @@ -182,6 +182,9 @@ void eigrp_prefix_entry_delete(struct route_table *table, struct eigrp *eigrp = eigrp_lookup(); struct route_node *rn; + if (!eigrp) + return; + rn = route_node_lookup(table, pe->destination); if (!rn) return; @@ -426,6 +429,9 @@ void eigrp_topology_update_all_node_flags(struct eigrp *eigrp) struct eigrp_prefix_entry *pe; struct route_node *rn; + if (!eigrp) + return; + for (rn = route_top(eigrp->topology_table); rn; rn = route_next(rn)) { pe = rn->info; @@ -471,11 +477,15 @@ void eigrp_topology_update_node_flags(struct eigrp_prefix_entry *dest) void eigrp_update_routing_table(struct eigrp_prefix_entry *prefix) { struct eigrp *eigrp = eigrp_lookup(); - struct list *successors = - eigrp_topology_get_successor_max(prefix, eigrp->max_paths); + struct list *successors; struct listnode *node; struct eigrp_nexthop_entry *entry; + if (!eigrp) + return; + + successors = eigrp_topology_get_successor_max(prefix, eigrp->max_paths); + if (successors) { eigrp_zebra_route_add(prefix->destination, successors); for (ALL_LIST_ELEMENTS_RO(successors, node, entry)) diff --git a/isisd/isis_te.c b/isisd/isis_te.c index 6834f52a82..8e53df3b61 100644 --- a/isisd/isis_te.c +++ b/isisd/isis_te.c @@ -884,7 +884,7 @@ static uint8_t print_subtlv_use_bw(struct sbuf *buf, int indent, static uint8_t print_unknown_tlv(struct sbuf *buf, int indent, struct subtlv_header *tlvh) { - int i, rtn = 1; + int i, rtn; uint8_t *v = (uint8_t *)tlvh; if (tlvh->length != 0) { diff --git a/isisd/isisd.c b/isisd/isisd.c index 6f04d72082..cecaa0693d 100644 --- a/isisd/isisd.c +++ b/isisd/isisd.c @@ -1373,7 +1373,7 @@ static int show_isis_database(struct vty *vty, const char *argv, int ui_level) struct isis_area *area; struct isis_lsp *lsp; struct isis_dynhn *dynhn; - const char *pos = argv; + const char *pos; uint8_t lspid[ISIS_SYS_ID_LEN + 2]; char sysid[255]; uint8_t number[3]; diff --git a/ldpd/ldp_debug.c b/ldpd/ldp_debug.c index 39e20ef7c8..ec70ef510a 100644 --- a/ldpd/ldp_debug.c +++ b/ldpd/ldp_debug.c @@ -41,6 +41,9 @@ int ldp_vty_debug(struct vty *vty, const char *negate, const char *type_str, const char *dir_str, const char *all) { + if (type_str == NULL) + return (CMD_WARNING_CONFIG_FAILED); + if (strcmp(type_str, "discovery") == 0) { if (dir_str == NULL) return (CMD_WARNING_CONFIG_FAILED); diff --git a/ldpd/ldp_vty_conf.c b/ldpd/ldp_vty_conf.c index 382b006884..e5832c5086 100644 --- a/ldpd/ldp_vty_conf.c +++ b/ldpd/ldp_vty_conf.c @@ -428,6 +428,9 @@ ldp_vty_address_family(struct vty *vty, const char *negate, const char *af_str) struct ldpd_af_conf *af_conf; int af; + if (af_str == NULL) + return (CMD_WARNING_CONFIG_FAILED); + if (strcmp(af_str, "ipv4") == 0) { af = AF_INET; af_conf = &vty_conf->ipv4; @@ -709,6 +712,11 @@ ldp_vty_interface(struct vty *vty, const char *negate, const char *ifname) struct iface *iface; struct iface_af *ia; + if (ifname == NULL) { + vty_out (vty, "%% Missing IF name\n"); + return (CMD_WARNING_CONFIG_FAILED); + } + af = ldp_vty_get_af(vty); iface = if_lookup_name(vty_conf, ifname); @@ -776,8 +784,9 @@ ldp_vty_trans_addr(struct vty *vty, const char *negate, const char *addr_str) if (negate) memset(&af_conf->trans_addr, 0, sizeof(af_conf->trans_addr)); else { - if (inet_pton(af, addr_str, &af_conf->trans_addr) != 1 || - bad_addr(af, &af_conf->trans_addr)) { + if (addr_str == NULL + || inet_pton(af, addr_str, &af_conf->trans_addr) != 1 + || bad_addr(af, &af_conf->trans_addr)) { vty_out (vty, "%% Malformed address\n"); return (CMD_SUCCESS); } @@ -797,7 +806,7 @@ ldp_vty_neighbor_targeted(struct vty *vty, const char *negate, const char *addr_ af = ldp_vty_get_af(vty); - if (inet_pton(af, addr_str, &addr) != 1 || + if (addr_str == NULL || inet_pton(af, addr_str, &addr) != 1 || bad_addr(af, &addr)) { vty_out (vty, "%% Malformed address\n"); return (CMD_WARNING_CONFIG_FAILED); @@ -1018,6 +1027,11 @@ ldp_vty_neighbor_password(struct vty *vty, const char *negate, struct in_addr ls size_t password_len; struct nbr_params *nbrp; + if (password_str == NULL) { + vty_out (vty, "%% Missing password\n"); + return (CMD_WARNING_CONFIG_FAILED); + } + if (bad_addr_v4(lsr_id)) { vty_out (vty, "%% Malformed address\n"); return (CMD_WARNING_CONFIG_FAILED); @@ -1113,6 +1127,11 @@ ldp_vty_l2vpn(struct vty *vty, const char *negate, const char *name_str) struct l2vpn_if *lif; struct l2vpn_pw *pw; + if (name_str == NULL) { + vty_out (vty, "%% Missing name\n"); + return (CMD_WARNING_CONFIG_FAILED); + } + l2vpn = l2vpn_find(vty_conf, name_str); if (negate) { @@ -1158,8 +1177,13 @@ ldp_vty_l2vpn_bridge(struct vty *vty, const char *negate, const char *ifname) if (negate) memset(l2vpn->br_ifname, 0, sizeof(l2vpn->br_ifname)); - else + else { + if (ifname == NULL) { + vty_out (vty, "%% Missing IF name\n"); + return (CMD_WARNING_CONFIG_FAILED); + } strlcpy(l2vpn->br_ifname, ifname, sizeof(l2vpn->br_ifname)); + } ldp_config_apply(vty, vty_conf); @@ -1187,6 +1211,11 @@ ldp_vty_l2vpn_pwtype(struct vty *vty, const char *negate, const char *type_str) VTY_DECLVAR_CONTEXT(l2vpn, l2vpn); int pw_type; + if (type_str == NULL) { + vty_out (vty, "%% Missing type\n"); + return (CMD_WARNING_CONFIG_FAILED); + } + if (strcmp(type_str, "ethernet") == 0) pw_type = PW_TYPE_ETHERNET; else @@ -1208,6 +1237,11 @@ ldp_vty_l2vpn_interface(struct vty *vty, const char *negate, const char *ifname) VTY_DECLVAR_CONTEXT(l2vpn, l2vpn); struct l2vpn_if *lif; + if (ifname == NULL) { + vty_out (vty, "%% Missing IF name\n"); + return (CMD_WARNING_CONFIG_FAILED); + } + lif = l2vpn_if_find(l2vpn, ifname); if (negate) { @@ -1246,6 +1280,11 @@ ldp_vty_l2vpn_pseudowire(struct vty *vty, const char *negate, const char *ifname VTY_DECLVAR_CONTEXT(l2vpn, l2vpn); struct l2vpn_pw *pw; + if (ifname == NULL) { + vty_out (vty, "%% Missing IF name\n"); + return (CMD_WARNING_CONFIG_FAILED); + } + pw = l2vpn_pw_find(l2vpn, ifname); if (negate) { @@ -1294,6 +1333,10 @@ ldp_vty_l2vpn_pw_cword(struct vty *vty, const char *negate, const char *preferen if (negate) pw->flags |= F_PW_CWORD_CONF; else { + if (!preference_str) { + vty_out (vty, "%% Missing preference\n"); + return (CMD_WARNING_CONFIG_FAILED); + } if (preference_str[0] == 'e') pw->flags &= ~F_PW_CWORD_CONF; else diff --git a/ldpd/ldpd.c b/ldpd/ldpd.c index b265c98dae..b51ff82cea 100644 --- a/ldpd/ldpd.c +++ b/ldpd/ldpd.c @@ -187,6 +187,22 @@ FRR_DAEMON_INFO(ldpd, LDP, .privs = &ldpd_privs, ) +static int ldp_config_fork_apply(struct thread *t) +{ + /* + * So the frr_config_fork() function schedules + * the read of the vty config( if there is a + * non-integrated config ) to be after the + * end of startup and we are starting the + * main process loop. We need to schedule + * the application of this if necessary + * after the read in of the config. + */ + ldp_config_apply(NULL, vty_conf); + + return 0; +} + int main(int argc, char *argv[]) { @@ -195,6 +211,7 @@ main(int argc, char *argv[]) int pipe_parent2ldpe[2], pipe_parent2ldpe_sync[2]; int pipe_parent2lde[2], pipe_parent2lde_sync[2]; char *ctl_sock_name; + struct thread *thread = NULL; ldpd_process = PROC_MAIN; log_procname = log_procnames[ldpd_process]; @@ -331,7 +348,7 @@ main(int argc, char *argv[]) frr_config_fork(); /* apply configuration */ - ldp_config_apply(NULL, vty_conf); + thread_add_event(master, ldp_config_fork_apply, NULL, 0, &thread); /* setup pipes to children */ if ((iev_ldpe = calloc(1, sizeof(struct imsgev))) == NULL || diff --git a/lib/command.c b/lib/command.c index a8e61c6bb4..4ab47e5fc2 100644 --- a/lib/command.c +++ b/lib/command.c @@ -2429,7 +2429,8 @@ static int set_log_file(struct vty *vty, const char *fname, int loglevel) XFREE(MTYPE_TMP, p); if (!ret) { - vty_out(vty, "can't open logfile %s\n", fname); + if (vty) + vty_out(vty, "can't open logfile %s\n", fname); return CMD_WARNING_CONFIG_FAILED; } @@ -2445,6 +2446,36 @@ static int set_log_file(struct vty *vty, const char *fname, int loglevel) return CMD_SUCCESS; } +void command_setup_early_logging(const char *dest, const char *level) +{ + char *token; + + if (level) { + int nlevel = level_match(level); + + if (nlevel != ZLOG_DISABLED) + zlog_default->default_lvl = nlevel; + } + + if (!dest) + return; + + if (strcmp(dest, "stdout") == 0) { + zlog_set_level(ZLOG_DEST_STDOUT, zlog_default->default_lvl); + return; + } + + if (strcmp(dest, "syslog") == 0) { + zlog_set_level(ZLOG_DEST_SYSLOG, zlog_default->default_lvl); + return; + } + + token = strstr(dest, ":"); + token++; + + set_log_file(NULL, token, zlog_default->default_lvl); +} + DEFUN (config_log_file, config_log_file_cmd, "log file FILENAME [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]", diff --git a/lib/command.h b/lib/command.h index 9bf482f41b..395c971c55 100644 --- a/lib/command.h +++ b/lib/command.h @@ -479,4 +479,5 @@ extern void cmd_variable_handler_register(const struct cmd_variable_handler *cvh); extern char *cmd_variable_comp2str(vector comps, unsigned short cols); +extern void command_setup_early_logging(const char *dest, const char *level); #endif /* _ZEBRA_COMMAND_H */ diff --git a/lib/imsg.c b/lib/imsg.c index 6419f805ab..5424140720 100644 --- a/lib/imsg.c +++ b/lib/imsg.c @@ -77,7 +77,7 @@ ssize_t imsg_read(struct imsgbuf *ibuf) char buf[CMSG_SPACE(sizeof(int) * 1)]; } cmsgbuf; struct iovec iov; - ssize_t n = -1; + ssize_t n; int fd; struct imsg_fd *ifd; @@ -110,7 +110,8 @@ again: return (-1); } - if ((n = recvmsg(ibuf->fd, &msg, 0)) == -1) { + n = recvmsg(ibuf->fd, &msg, 0); + if (n == -1) { if (errno == EINTR) goto again; goto fail; diff --git a/lib/libfrr.c b/lib/libfrr.c index 88203fbeb6..505bea9b18 100644 --- a/lib/libfrr.c +++ b/lib/libfrr.c @@ -78,6 +78,8 @@ static void opt_extend(const struct optspec *os) #define OPTION_VTYSOCK 1000 #define OPTION_MODULEDIR 1002 +#define OPTION_LOG 1003 +#define OPTION_LOGLEVEL 1004 static const struct option lo_always[] = { {"help", no_argument, NULL, 'h'}, @@ -86,6 +88,8 @@ static const struct option lo_always[] = { {"module", no_argument, NULL, 'M'}, {"vty_socket", required_argument, NULL, OPTION_VTYSOCK}, {"moduledir", required_argument, NULL, OPTION_MODULEDIR}, + {"log", required_argument, NULL, OPTION_LOG}, + {"log-level", required_argument, NULL, OPTION_LOGLEVEL}, {NULL}}; static const struct optspec os_always = { "hvdM:", @@ -94,7 +98,9 @@ static const struct optspec os_always = { " -d, --daemon Runs in daemon mode\n" " -M, --module Load specified module\n" " --vty_socket Override vty socket path\n" - " --moduledir Override modules directory\n", + " --moduledir Override modules directory\n" + " --log Set Logging to stdout, syslog, or file:<name>\n" + " --log-level Set Logging Level to use, debug, info, warn, etc\n", lo_always}; @@ -444,6 +450,12 @@ static int frr_opt(int opt) return 1; di->privs->group = optarg; break; + case OPTION_LOG: + di->early_logging = optarg; + break; + case OPTION_LOGLEVEL: + di->early_loglevel = optarg; + break; default: return 1; } @@ -543,9 +555,8 @@ struct thread_master *frr_init(void) openzlog(di->progname, di->logname, di->instance, LOG_CONS | LOG_NDELAY | LOG_PID, LOG_DAEMON); -#if defined(HAVE_CUMULUS) - zlog_set_level(ZLOG_DEST_SYSLOG, zlog_default->default_lvl); -#endif + + command_setup_early_logging(di->early_logging, di->early_loglevel); if (!frr_zclient_addr(&zclient_addr, &zclient_addr_len, frr_zclientpath)) { @@ -721,15 +732,37 @@ static void frr_daemonize(void) frr_daemon_wait(fds[0]); } +/* + * Why is this a thread? + * + * The read in of config for integrated config happens *after* + * thread execution starts( because it is passed in via a vtysh -b -n ) + * While if you are not using integrated config we want the ability + * to read the config in after thread execution starts, so that + * we can match this behavior. + */ +static int frr_config_read_in(struct thread *t) +{ + if (!vty_read_config(di->config_file, config_default) && + di->backup_config_file) { + zlog_info("Attempting to read backup config file: %s specified", + di->backup_config_file); + vty_read_config(di->backup_config_file, config_default); + } + return 0; +} + void frr_config_fork(void) { hook_call(frr_late_init, master); - vty_read_config(di->config_file, config_default); - /* Don't start execution if we are in dry-run mode */ - if (di->dryrun) + if (di->dryrun) { + frr_config_read_in(NULL); exit(0); + } + + thread_add_event(master, frr_config_read_in, NULL, 0, &di->read_in); if (di->daemon_mode || di->terminal) frr_daemonize(); diff --git a/lib/libfrr.h b/lib/libfrr.h index 7ffa780bfb..d255279906 100644 --- a/lib/libfrr.h +++ b/lib/libfrr.h @@ -50,11 +50,16 @@ struct frr_daemon_info { bool dryrun; bool daemon_mode; bool terminal; + + struct thread *read_in; const char *config_file; + const char *backup_config_file; const char *pid_file; const char *vty_path; const char *module_path; const char *pathspace; + const char *early_logging; + const char *early_loglevel; const char *proghelp; void (*printhelp)(FILE *target); diff --git a/lib/plist.c b/lib/plist.c index 5ed1589f45..056b737f54 100644 --- a/lib/plist.c +++ b/lib/plist.c @@ -850,6 +850,11 @@ static int vty_prefix_list_install(struct vty *vty, afi_t afi, const char *name, int lenum = 0; int genum = 0; + if (name == NULL || prefix == NULL || typestr == NULL) { + vty_out(vty, "%% Missing prefix or type\n"); + return CMD_WARNING_CONFIG_FAILED; + } + /* Sequential number. */ if (seq) seqnum = (int64_t)atol(seq); diff --git a/lib/sockopt.c b/lib/sockopt.c index 1d8d9990df..815be86c2e 100644 --- a/lib/sockopt.c +++ b/lib/sockopt.c @@ -457,8 +457,7 @@ int setsockopt_ifindex(int af, int sock, ifindex_t val) */ static ifindex_t getsockopt_ipv4_ifindex(struct msghdr *msgh) { - /* XXX: initialize to zero? (Always overwritten, so just cosmetic.) */ - ifindex_t ifindex = -1; + ifindex_t ifindex; #if defined(IP_PKTINFO) /* Linux pktinfo based ifindex retrieval */ @@ -466,7 +465,11 @@ static ifindex_t getsockopt_ipv4_ifindex(struct msghdr *msgh) pktinfo = (struct in_pktinfo *)getsockopt_cmsg_data(msgh, IPPROTO_IP, IP_PKTINFO); - /* XXX Can pktinfo be NULL? Clean up post 0.98. */ + + /* getsockopt_ifindex() will forward this, being 0 "not found" */ + if (pktinfo == NULL) + return 0; + ifindex = pktinfo->ipi_ifindex; #elif defined(IP_RECVIF) diff --git a/lib/sockunion.c b/lib/sockunion.c index 28a7f647cb..44378b5363 100644 --- a/lib/sockunion.c +++ b/lib/sockunion.c @@ -46,6 +46,9 @@ int str2sockunion(const char *str, union sockunion *su) { int ret; + if (str == NULL) + return -1; + memset(su, 0, sizeof(union sockunion)); ret = inet_pton(AF_INET, str, &su->sin.sin_addr); @@ -2462,12 +2462,13 @@ static FILE *vty_use_backup_config(const char *fullpath) } /* Read up configuration file from file_name. */ -void vty_read_config(const char *config_file, char *config_default_dir) +bool vty_read_config(const char *config_file, char *config_default_dir) { char cwd[MAXPATHLEN]; FILE *confp = NULL; const char *fullpath; char *tmp = NULL; + bool read_success = false; /* If -f flag specified. */ if (config_file != NULL) { @@ -2525,8 +2526,10 @@ void vty_read_config(const char *config_file, char *config_default_dir) if (strstr(config_default_dir, "vtysh") == NULL) { ret = stat(integrate_default, &conf_stat); - if (ret >= 0) + if (ret >= 0) { + read_success = true; goto tmp_free_and_out; + } } #endif /* VTYSH */ confp = fopen(config_default_dir, "r"); @@ -2550,6 +2553,7 @@ void vty_read_config(const char *config_file, char *config_default_dir) } vty_read_file(confp); + read_success = true; fclose(confp); @@ -2558,6 +2562,8 @@ void vty_read_config(const char *config_file, char *config_default_dir) tmp_free_and_out: if (tmp) XFREE(MTYPE_TMP, tmp); + + return read_success; } /* Small utility function which output log to the VTY. */ @@ -242,7 +242,7 @@ extern void vty_frame(struct vty *, const char *, ...) PRINTF_ATTRIBUTE(2, 3); extern void vty_endframe(struct vty *, const char *); bool vty_set_include(struct vty *vty, const char *regexp); -extern void vty_read_config(const char *, char *); +extern bool vty_read_config(const char *, char *); extern void vty_time_print(struct vty *, int); extern void vty_serv_sock(const char *, unsigned short, const char *); extern void vty_close(struct vty *); diff --git a/ospf6d/ospf6_flood.c b/ospf6d/ospf6_flood.c index 2059d84868..ae26668c8a 100644 --- a/ospf6d/ospf6_flood.c +++ b/ospf6d/ospf6_flood.c @@ -347,6 +347,7 @@ void ospf6_flood_interface(struct ospf6_neighbor *from, struct ospf6_lsa *lsa, "Received is newer, remove requesting"); if (req == on->last_ls_req) { ospf6_lsa_unlock(req); + req = NULL; on->last_ls_req = NULL; } if (req) diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 31cffea7f2..7d748419fa 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -2412,8 +2412,8 @@ DEFUN (ospf_neighbor_poll_interval, int idx_poll = 3; int idx_pri = 5; struct in_addr nbr_addr; - unsigned int priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT; - unsigned int interval = OSPF_POLL_INTERVAL_DEFAULT; + unsigned int priority; + unsigned int interval; if (!inet_aton(argv[idx_ipv4]->arg, &nbr_addr)) { vty_out(vty, "Please specify Neighbor ID by A.B.C.D\n"); @@ -2422,8 +2422,8 @@ DEFUN (ospf_neighbor_poll_interval, interval = strtoul(argv[idx_poll]->arg, NULL, 10); - if (argc > 4) - priority = strtoul(argv[idx_pri]->arg, NULL, 10); + priority = argc > 4 ? strtoul(argv[idx_pri]->arg, NULL, 10) + : OSPF_NEIGHBOR_PRIORITY_DEFAULT; ospf_nbr_nbma_set(ospf, nbr_addr); ospf_nbr_nbma_poll_interval_set(ospf, nbr_addr, interval); diff --git a/pimd/mtracebis.c b/pimd/mtracebis.c index 731fdb1beb..c63a6eeca9 100644 --- a/pimd/mtracebis.c +++ b/pimd/mtracebis.c @@ -336,7 +336,7 @@ static int wait_for_response(int fd, int *hops, struct igmp_mtrace *mtrace, { fd_set readfds; struct timeval timeout; - int ret = -1; + int ret; long msec, rmsec, tmsec; FD_ZERO(&readfds); diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 55222ecddb..123c47568c 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -4504,8 +4504,8 @@ static void show_mroute(struct pim_instance *pim, struct vty *vty, bool fill, json_object *json_source = NULL; json_object *json_oil = NULL; json_object *json_ifp_out = NULL; - int found_oif = 0; - int first = 1; + int found_oif; + int first; char grp_str[INET_ADDRSTRLEN]; char src_str[INET_ADDRSTRLEN]; char in_ifname[INTERFACE_NAMSIZ + 1]; diff --git a/pimd/pim_pim.c b/pimd/pim_pim.c index de09b070f4..f506875282 100644 --- a/pimd/pim_pim.c +++ b/pimd/pim_pim.c @@ -521,7 +521,7 @@ int pim_msg_send(int fd, struct in_addr src, struct in_addr dst, socklen_t tolen; unsigned char buffer[10000]; unsigned char *msg_start; - uint8_t ttl = MAXTTL; + uint8_t ttl; struct pim_msg_header *header; struct ip *ip; diff --git a/tests/Makefile.am b/tests/Makefile.am index 9b60312cef..32d2db768a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -102,8 +102,6 @@ lib/cli/test_commands_defun.c: ../vtysh/vtysh_cmd.c isisd/test_fuzz_isis_tlv_tests.h: $(top_srcdir)/tests/isisd/test_fuzz_isis_tlv_tests.h.gz gzip -d < $(top_srcdir)/tests/isisd/test_fuzz_isis_tlv_tests.h.gz > "$@" -isisd/isisd_test_fuzz_isis_tlv-test_fuzz_isis_tlv.$(OBJEXT): \ - isisd/test_fuzz_isis_tlv_tests.h noinst_HEADERS = \ ./helpers/c/prng.h \ @@ -146,6 +144,9 @@ bgpd_test_ecommunity_SOURCES = bgpd/test_ecommunity.c bgpd_test_mp_attr_SOURCES = bgpd/test_mp_attr.c bgpd_test_mpath_SOURCES = bgpd/test_mpath.c isisd_test_fuzz_isis_tlv_SOURCES = isisd/test_fuzz_isis_tlv.c +nodist_isisd_test_fuzz_isis_tlv_SOURCES = isisd/test_fuzz_isis_tlv_tests.h +BUILT_SOURCES=isisd/test_fuzz_isis_tlv_tests.h +CLEANFILES=isisd/test_fuzz_isis_tlv_tests.h isisd_test_fuzz_isis_tlv_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_builddir)/tests/isisd isisd_test_isis_vertex_queue_SOURCES = isisd/test_isis_vertex_queue.c diff --git a/tools/start-stop-daemon.c b/tools/start-stop-daemon.c index 8c3fe0c3c5..de58e0a20e 100644 --- a/tools/start-stop-daemon.c +++ b/tools/start-stop-daemon.c @@ -1024,8 +1024,10 @@ int main(int argc, char **argv) close(i); /* change tty */ fd = open("/dev/tty", O_RDWR); - ioctl(fd, TIOCNOTTY, 0); - close(fd); + if (fd >= 0) { + ioctl(fd, TIOCNOTTY, 0); + close(fd); + } chdir("/"); umask(022); /* set a default for dumb programs */ setpgid(0, 0); /* set the process group */ diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index 309493b13e..66b49800dd 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -2415,10 +2415,11 @@ DEFUNSH(VTYSH_ALL, vtysh_log_syslog, vtysh_log_syslog_cmd, } DEFUNSH(VTYSH_ALL, no_vtysh_log_syslog, no_vtysh_log_syslog_cmd, - "no log syslog [LEVEL]", NO_STR + "no log syslog [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]", + NO_STR "Logging control\n" "Cancel logging to syslog\n" - "Logging level\n") + LOG_LEVEL_DESC) { return CMD_SUCCESS; } @@ -2634,8 +2635,13 @@ static void backup_config_file(const char *fbackup) strcat(integrate_sav, CONF_BACKUP_EXT); /* Move current configuration file to backup config file. */ - unlink(integrate_sav); - rename(fbackup, integrate_sav); + if (unlink(integrate_sav) != 0) { + vty_out(vty, "Warning: %s unlink failed\n", integrate_sav); + } + if (rename(fbackup, integrate_sav) != 0) { + vty_out(vty, "Error renaming %s to %s\n", fbackup, + integrate_sav); + } free(integrate_sav); } |
