]> git.proxmox.com Git - mirror_frr.git/commitdiff
Merge pull request #2514 from pacovn/Coverity_1462467_1465497_Control_flow_issues
authorRuss White <russ@riw.us>
Fri, 29 Jun 2018 17:24:42 +0000 (13:24 -0400)
committerGitHub <noreply@github.com>
Fri, 29 Jun 2018 17:24:42 +0000 (13:24 -0400)
zebra: control flow issues (Coverity 1462467 1465497)

72 files changed:
bgpd/bgp_aspath.c
bgpd/bgp_attr.c
bgpd/bgp_clist.c
bgpd/bgp_io.c
bgpd/bgp_mplsvpn.c
bgpd/bgp_nexthop.c
bgpd/bgp_open.c
bgpd/bgp_route.c
bgpd/bgp_updgrp_packet.c
bgpd/bgp_vpn.c
bgpd/bgp_vty.c
bgpd/rfapi/bgp_rfapi_cfg.c
bgpd/rfapi/rfapi_vty.c
doc/user/basic.rst
eigrpd/eigrp_fsm.c
eigrpd/eigrp_interface.c
eigrpd/eigrp_topology.c
include/linux/netlink.h [new file with mode: 0644]
include/subdir.am
isisd/isis_lsp.c
isisd/isis_pfpacket.c
isisd/isis_spf.c
isisd/isis_te.c
isisd/isisd.c
ldpd/ldp_debug.c
ldpd/ldp_vty_conf.c
ldpd/ldpd.c
lib/clippy.c
lib/command.c
lib/command.h
lib/command_match.c
lib/imsg.c
lib/libfrr.c
lib/libfrr.h
lib/linklist.h
lib/plist.c
lib/privs.c
lib/sbuf.c
lib/sockopt.c
lib/sockunion.c
lib/vty.c
lib/vty.h
nhrpd/vici.c
ospf6d/ospf6_abr.c
ospf6d/ospf6_asbr.c
ospf6d/ospf6_flood.c
ospf6d/ospf6_intra.c
ospf6d/ospf6_proto.c
ospf6d/ospf6_proto.h
ospf6d/ospf6_spf.c
ospfd/ospf_api.c
ospfd/ospf_apiserver.c
ospfd/ospf_ase.c
ospfd/ospf_route.c
ospfd/ospf_te.c
ospfd/ospf_vty.c
ospfd/ospf_zebra.c
ospfd/ospfd.c
pimd/mtracebis.c
pimd/pim_cmd.c
pimd/pim_igmp_mtrace.c
pimd/pim_pim.c
ripd/ripd.c
sharpd/sharp_main.c
tests/Makefile.am
tools/start-stop-daemon.c
vtysh/vtysh.c
zebra/if_netlink.c
zebra/kernel_netlink.c
zebra/rt_netlink.c
zebra/rule_netlink.c
zebra/zebra_netns_notify.c

index e02617691fa783a402fca224740a6ec51100e5c5..05e67baa8a83140277a6274568e1e755034eae4c 100644 (file)
@@ -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;
index 2c52b57b36f8e7c370e57cc5336d0c42087e4389..6596e7cfa2643d1e4b650ecdeb4d5705d3762230 100644 (file)
@@ -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);
        }
index 7cf14775496cdb2bb6e8f0cc9eb04f2c5bb20b31..0ffbe174ed9d609579c4201684cc55cf53ada050 100644 (file)
@@ -1054,6 +1054,9 @@ int extcommunity_list_set(struct community_list_handler *ch, const char *name,
        struct ecommunity *ecom = NULL;
        regex_t *regex = NULL;
 
+       if (str == NULL)
+               return COMMUNITY_LIST_ERR_MALFORMED_VAL;
+
        entry = NULL;
 
        /* Get community list. */
@@ -1089,7 +1092,7 @@ int extcommunity_list_set(struct community_list_handler *ch, const char *name,
        entry = community_entry_new();
        entry->direct = direct;
        entry->style = style;
-       entry->any = (str ? 0 : 1);
+       entry->any = 0;
        if (ecom)
                entry->config = ecommunity_ecom2str(
                        ecom, ECOMMUNITY_FORMAT_COMMUNITY_LIST, 0);
index 69c92e829c59ce6174a792ee08df89470cd6e6b6..c8d5b1daa121a3ed51817f242e0dc53fde9fc21e 100644 (file)
@@ -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;
                }
index 28e8ceb15d3e3144258ea26c1e6dcdbe95995833..3a854be534bf39ff17534db70e3213d91be5ae44 100644 (file)
@@ -466,6 +466,7 @@ leak_update(
 {
        struct prefix *p = &bn->p;
        struct bgp_info *bi;
+       struct bgp_info *bi_ultimate;
        struct bgp_info *new;
        char buf_prefix[PREFIX_STRLEN];
 
@@ -476,6 +477,26 @@ leak_update(
                        source_bi->type, source_bi->sub_type);
        }
 
+       /*
+        * Routes that are redistributed into BGP from zebra do not get
+        * nexthop tracking. However, if those routes are subsequently
+        * imported to other RIBs within BGP, the leaked routes do not
+        * carry the original BGP_ROUTE_REDISTRIBUTE sub_type. Therefore,
+        * in order to determine if the route we are currently leaking
+        * should have nexthop tracking, we must find the ultimate
+        * parent so we can check its sub_type.
+        *
+        * As of now, source_bi may at most be a second-generation route
+        * (only one hop back to ultimate parent for vrf-vpn-vrf scheme).
+        * Using a loop here supports more complex intra-bgp import-export
+        * schemes that could be implemented in the future.
+        * 
+        */
+       for (bi_ultimate = source_bi;
+               bi_ultimate->extra && bi_ultimate->extra->parent;
+               bi_ultimate = bi_ultimate->extra->parent)
+                       ;
+
        /*
         * match parent
         */
@@ -528,7 +549,7 @@ leak_update(
                        bgp_nexthop = bi->extra->bgp_orig;
 
                /* No nexthop tracking for redistributed routes */
-               if (source_bi->sub_type == BGP_ROUTE_REDISTRIBUTE)
+               if (bi_ultimate->sub_type == BGP_ROUTE_REDISTRIBUTE)
                        nh_valid = 1;
                else
                        /*
@@ -591,7 +612,7 @@ leak_update(
         * their originating protocols will do the tracking and
         * withdraw those routes if the nexthops become unreachable
         */
-       if (source_bi->sub_type == BGP_ROUTE_REDISTRIBUTE)
+       if (bi_ultimate->sub_type == BGP_ROUTE_REDISTRIBUTE)
                nh_valid = 1;
        else
                /*
index fd8d894878a55aa277a2cfbf177bcba85efbd2a9..32011d210ba29f02e3806e7ec9ddd3c5e3da7f9a 100644 (file)
@@ -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);
index aa98f8a55726423371b215cc2f7f34339537549f..da90bbd67dad6591b5747da3c1696948dee160ab 100644 (file)
@@ -80,8 +80,9 @@ void bgp_capability_vty_out(struct vty *vty, struct peer *peer,
                        afi_t afi;
                        safi_t safi;
 
-                       bgp_map_afi_safi_iana2int(ntohs(mpc.afi), mpc.safi,
-                                                 &afi, &safi);
+                       (void)bgp_map_afi_safi_iana2int(ntohs(mpc.afi),
+                                                       mpc.safi, &afi, &safi);
+
                        if (use_json) {
                                switch (afi) {
                                case AFI_IP:
index 95e7def8fb0eadea55c0905d48ba78c532c1ccb8..0b1deba5171fb57ac64d4a9df0f7035aad95792f 100644 (file)
@@ -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);
                }
        }
index cabd5b5cbd795027ae9a4797a2b2e17abce90d4f..34ddbfcd14171db41b90934ff5acf73dddee0aa8 100644 (file)
@@ -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))
index cc051947031949ba75b2106da7d4678ddf4b2390..a771eedf0f74019bc78790bbf23b9821782609ba 100644 (file)
@@ -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 = {
index 4e0f7155baff92d3832435504aba736b07cc6cb9..3d1fdfd38de9fd858d07b6733b55b692cfba1c8b 100644 (file)
@@ -2009,27 +2009,19 @@ DEFUN (no_bgp_fast_external_failover,
 CPP_NOTICE("bgpd: remove deprecated '[no] bgp enforce-first-as' commands")
 #endif
 
-DEFUN_DEPRECATED (bgp_enforce_first_as,
-       bgp_enforce_first_as_cmd,
-       "bgp enforce-first-as",
-       BGP_STR
-       "Enforce the first AS for EBGP routes\n")
+DEFUN_HIDDEN (bgp_enforce_first_as,
+             bgp_enforce_first_as_cmd,
+             "[no] bgp enforce-first-as",
+             NO_STR
+             BGP_STR
+             "Enforce the first AS for EBGP routes\n")
 {
        VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_flag_set(bgp, BGP_FLAG_ENFORCE_FIRST_AS);
 
-       return CMD_SUCCESS;
-}
-
-DEFUN_DEPRECATED (no_bgp_enforce_first_as,
-       no_bgp_enforce_first_as_cmd,
-       "no bgp enforce-first-as",
-       NO_STR
-       BGP_STR
-       "Enforce the first AS for EBGP routes\n")
-{
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_flag_unset(bgp, BGP_FLAG_ENFORCE_FIRST_AS);
+       if (strmatch(argv[0]->text, "no"))
+               bgp_flag_unset(bgp, BGP_FLAG_ENFORCE_FIRST_AS);
+       else
+               bgp_flag_set(bgp, BGP_FLAG_ENFORCE_FIRST_AS);
 
        return CMD_SUCCESS;
 }
@@ -6745,6 +6737,11 @@ DEFPY (bgp_imexport_vrf,
        safi_t safi;
        afi_t afi;
 
+       if (import_name == NULL) {
+               vty_out(vty, "%% Missing import name\n");
+               return CMD_WARNING;
+       }
+
        if (argv_find(argv, argc, "no", &idx))
                remove = true;
 
@@ -11409,7 +11406,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
@@ -12440,7 +12436,6 @@ void bgp_vty_init(void)
 
        /* "bgp enforce-first-as" commands */
        install_element(BGP_NODE, &bgp_enforce_first_as_cmd);
-       install_element(BGP_NODE, &no_bgp_enforce_first_as_cmd);
 
        /* "bgp bestpath compare-routerid" commands */
        install_element(BGP_NODE, &bgp_bestpath_compare_router_id_cmd);
index 72255e54fbd35b77830b866e9d5bf1e0d0070fd6..8553846c9025137bbf0b5a0db3f14b6cf60f522c 100644 (file)
@@ -1426,7 +1426,8 @@ DEFUN (vnc_export_nvegroup,
        if (rfg_new == NULL) {
                rfg_new = bgp_rfapi_cfg_match_byname(bgp, argv[5]->arg,
                                                     RFAPI_GROUP_CFG_VRF);
-               vnc_add_vrf_opener(bgp, rfg_new);
+               if (rfg_new)
+                       vnc_add_vrf_opener(bgp, rfg_new);
        }
 
        if (rfg_new == NULL) {
@@ -4518,7 +4519,7 @@ void bgp_rfapi_show_summary(struct bgp *bgp, struct vty *vty)
        if (VNC_EXPORT_ZEBRA_GRP_ENABLED(hc)) {
                redist++;
                vty_out(vty, "%sToZebra Groups={", (redist == 1 ? "" : " "));
-               if (hc->rfg_export_direct_bgp_l) {
+               if (hc->rfg_export_zebra_l) {
                        int cnt = 0;
                        struct listnode *node, *nnode;
                        struct rfapi_rfg_name *rfgn;
index 18a979e531ea26c6ba09072d68cc2ceede9b63e0..2f8f132fcdbfba7fec298b596379251aa4968f24 100644 (file)
@@ -388,15 +388,11 @@ int rfapiStream2Vty(void *stream,                    /* input */
                return 1;
        }
 
-       if (stream) {
-               *vty = stream; /* VTYNL requires vty to be legit */
-               *fp = (int (*)(void *, const char *, ...))vty_out;
-               *outstream = stream;
-               *vty_newline = str_vty_newline(*vty);
-               return 1;
-       }
-
-       return 0;
+       *vty = stream; /* VTYNL requires vty to be legit */
+       *fp = (int (*)(void *, const char *, ...))vty_out;
+       *outstream = stream;
+       *vty_newline = str_vty_newline(*vty);
+       return 1;
 }
 
 /* called from bgpd/bgp_vty.c'route_vty_out() */
index a75017c4429ec3ef582ec39eee483d6b58cf513d..cb46080055bde7fc1d69621f320a7f0d4a3388b8 100644 (file)
@@ -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
index 4107d440901c01e2690808d8efe1215b4ab6590e..eeefc519688ccce2c37f7298254b46bfa46b91be 100644 (file)
@@ -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);
index cd459fdc42940fbb8fa580972971b5a91c96eaa2..cd62811fdfdadf34da3698590019f8974155b998 100644 (file)
@@ -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);
index becb29a95faafb530994c6303284b98eeeaf1daf..8ca0e282a8cdfb09814505934e8cd94e46fb3877 100644 (file)
@@ -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;
 
@@ -442,6 +448,8 @@ void eigrp_topology_update_node_flags(struct eigrp_prefix_entry *dest)
        struct eigrp_nexthop_entry *entry;
        struct eigrp *eigrp = eigrp_lookup();
 
+       assert(eigrp);
+
        for (ALL_LIST_ELEMENTS_RO(dest->entries, node, entry)) {
                if (entry->reported_distance < dest->fdistance) {
                        // is feasible successor, can be successor
@@ -471,11 +479,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/include/linux/netlink.h b/include/linux/netlink.h
new file mode 100644 (file)
index 0000000..0b2c29b
--- /dev/null
@@ -0,0 +1,247 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef __LINUX_NETLINK_H
+#define __LINUX_NETLINK_H
+
+#include <linux/kernel.h>
+#include <linux/socket.h> /* for __kernel_sa_family_t */
+#include <linux/types.h>
+
+#define NETLINK_ROUTE          0       /* Routing/device hook                          */
+#define NETLINK_UNUSED         1       /* Unused number                                */
+#define NETLINK_USERSOCK       2       /* Reserved for user mode socket protocols      */
+#define NETLINK_FIREWALL       3       /* Unused number, formerly ip_queue             */
+#define NETLINK_SOCK_DIAG      4       /* socket monitoring                            */
+#define NETLINK_NFLOG          5       /* netfilter/iptables ULOG */
+#define NETLINK_XFRM           6       /* ipsec */
+#define NETLINK_SELINUX                7       /* SELinux event notifications */
+#define NETLINK_ISCSI          8       /* Open-iSCSI */
+#define NETLINK_AUDIT          9       /* auditing */
+#define NETLINK_FIB_LOOKUP     10      
+#define NETLINK_CONNECTOR      11
+#define NETLINK_NETFILTER      12      /* netfilter subsystem */
+#define NETLINK_IP6_FW         13
+#define NETLINK_DNRTMSG                14      /* DECnet routing messages */
+#define NETLINK_KOBJECT_UEVENT 15      /* Kernel messages to userspace */
+#define NETLINK_GENERIC                16
+/* leave room for NETLINK_DM (DM Events) */
+#define NETLINK_SCSITRANSPORT  18      /* SCSI Transports */
+#define NETLINK_ECRYPTFS       19
+#define NETLINK_RDMA           20
+#define NETLINK_CRYPTO         21      /* Crypto layer */
+#define NETLINK_SMC            22      /* SMC monitoring */
+
+#define NETLINK_INET_DIAG      NETLINK_SOCK_DIAG
+
+#define MAX_LINKS 32           
+
+struct sockaddr_nl {
+       __kernel_sa_family_t    nl_family;      /* AF_NETLINK   */
+       unsigned short  nl_pad;         /* zero         */
+       __u32           nl_pid;         /* port ID      */
+               __u32           nl_groups;      /* multicast groups mask */
+};
+
+struct nlmsghdr {
+       __u32           nlmsg_len;      /* Length of message including header */
+       __u16           nlmsg_type;     /* Message content */
+       __u16           nlmsg_flags;    /* Additional flags */
+       __u32           nlmsg_seq;      /* Sequence number */
+       __u32           nlmsg_pid;      /* Sending process port ID */
+};
+
+/* Flags values */
+
+#define NLM_F_REQUEST          0x01    /* It is request message.       */
+#define NLM_F_MULTI            0x02    /* Multipart message, terminated by NLMSG_DONE */
+#define NLM_F_ACK              0x04    /* Reply with ack, with zero or error code */
+#define NLM_F_ECHO             0x08    /* Echo this request            */
+#define NLM_F_DUMP_INTR                0x10    /* Dump was inconsistent due to sequence change */
+#define NLM_F_DUMP_FILTERED    0x20    /* Dump was filtered as requested */
+
+/* Modifiers to GET request */
+#define NLM_F_ROOT     0x100   /* specify tree root    */
+#define NLM_F_MATCH    0x200   /* return all matching  */
+#define NLM_F_ATOMIC   0x400   /* atomic GET           */
+#define NLM_F_DUMP     (NLM_F_ROOT|NLM_F_MATCH)
+
+/* Modifiers to NEW request */
+#define NLM_F_REPLACE  0x100   /* Override existing            */
+#define NLM_F_EXCL     0x200   /* Do not touch, if it exists   */
+#define NLM_F_CREATE   0x400   /* Create, if it does not exist */
+#define NLM_F_APPEND   0x800   /* Add to end of list           */
+
+/* Modifiers to DELETE request */
+#define NLM_F_NONREC   0x100   /* Do not delete recursively    */
+
+/* Flags for ACK message */
+#define NLM_F_CAPPED   0x100   /* request was capped */
+#define NLM_F_ACK_TLVS 0x200   /* extended ACK TVLs were included */
+
+/*
+   4.4BSD ADD          NLM_F_CREATE|NLM_F_EXCL
+   4.4BSD CHANGE       NLM_F_REPLACE
+
+   True CHANGE         NLM_F_CREATE|NLM_F_REPLACE
+   Append              NLM_F_CREATE
+   Check               NLM_F_EXCL
+ */
+
+#define NLMSG_ALIGNTO  4U
+#define NLMSG_ALIGN(len) ( ((len)+NLMSG_ALIGNTO-1) & ~(NLMSG_ALIGNTO-1) )
+#define NLMSG_HDRLEN    ((int) NLMSG_ALIGN(sizeof(struct nlmsghdr)))
+#define NLMSG_LENGTH(len) ((len) + NLMSG_HDRLEN)
+#define NLMSG_SPACE(len) NLMSG_ALIGN(NLMSG_LENGTH(len))
+#define NLMSG_DATA(nlh)  ((void*)(((char*)nlh) + NLMSG_LENGTH(0)))
+#define NLMSG_NEXT(nlh,len)     ((len) -= NLMSG_ALIGN((nlh)->nlmsg_len), \
+                                 (struct nlmsghdr*)(((char*)(nlh)) + NLMSG_ALIGN((nlh)->nlmsg_len)))
+#define NLMSG_OK(nlh,len) ((len) >= (int)sizeof(struct nlmsghdr) && \
+                          (nlh)->nlmsg_len >= sizeof(struct nlmsghdr) && \
+                          (nlh)->nlmsg_len <= (len))
+#define NLMSG_PAYLOAD(nlh,len) ((nlh)->nlmsg_len - NLMSG_SPACE((len)))
+
+#define NLMSG_NOOP             0x1     /* Nothing.             */
+#define NLMSG_ERROR            0x2     /* Error                */
+#define NLMSG_DONE             0x3     /* End of a dump        */
+#define NLMSG_OVERRUN          0x4     /* Data lost            */
+
+#define NLMSG_MIN_TYPE         0x10    /* < 0x10: reserved control messages */
+
+struct nlmsgerr {
+       int             error;
+       struct nlmsghdr msg;
+       /*
+        * followed by the message contents unless NETLINK_CAP_ACK was set
+        * or the ACK indicates success (error == 0)
+        * message length is aligned with NLMSG_ALIGN()
+        */
+       /*
+        * followed by TLVs defined in enum nlmsgerr_attrs
+        * if NETLINK_EXT_ACK was set
+        */
+};
+
+/**
+ * enum nlmsgerr_attrs - nlmsgerr attributes
+ * @NLMSGERR_ATTR_UNUSED: unused
+ * @NLMSGERR_ATTR_MSG: error message string (string)
+ * @NLMSGERR_ATTR_OFFS: offset of the invalid attribute in the original
+ *      message, counting from the beginning of the header (u32)
+ * @NLMSGERR_ATTR_COOKIE: arbitrary subsystem specific cookie to
+ *     be used - in the success case - to identify a created
+ *     object or operation or similar (binary)
+ * @__NLMSGERR_ATTR_MAX: number of attributes
+ * @NLMSGERR_ATTR_MAX: highest attribute number
+ */
+enum nlmsgerr_attrs {
+       NLMSGERR_ATTR_UNUSED,
+       NLMSGERR_ATTR_MSG,
+       NLMSGERR_ATTR_OFFS,
+       NLMSGERR_ATTR_COOKIE,
+
+       __NLMSGERR_ATTR_MAX,
+       NLMSGERR_ATTR_MAX = __NLMSGERR_ATTR_MAX - 1
+};
+
+#define NETLINK_ADD_MEMBERSHIP         1
+#define NETLINK_DROP_MEMBERSHIP                2
+#define NETLINK_PKTINFO                        3
+#define NETLINK_BROADCAST_ERROR                4
+#define NETLINK_NO_ENOBUFS             5
+#define NETLINK_RX_RING                        6
+#define NETLINK_TX_RING                        7
+#define NETLINK_LISTEN_ALL_NSID                8
+#define NETLINK_LIST_MEMBERSHIPS       9
+#define NETLINK_CAP_ACK                        10
+#define NETLINK_EXT_ACK                        11
+
+struct nl_pktinfo {
+       __u32   group;
+};
+
+struct nl_mmap_req {
+       unsigned int    nm_block_size;
+       unsigned int    nm_block_nr;
+       unsigned int    nm_frame_size;
+       unsigned int    nm_frame_nr;
+};
+
+struct nl_mmap_hdr {
+       unsigned int    nm_status;
+       unsigned int    nm_len;
+       __u32           nm_group;
+       /* credentials */
+       __u32           nm_pid;
+       __u32           nm_uid;
+       __u32           nm_gid;
+};
+
+enum nl_mmap_status {
+       NL_MMAP_STATUS_UNUSED,
+       NL_MMAP_STATUS_RESERVED,
+       NL_MMAP_STATUS_VALID,
+       NL_MMAP_STATUS_COPY,
+       NL_MMAP_STATUS_SKIP,
+};
+
+#define NL_MMAP_MSG_ALIGNMENT          NLMSG_ALIGNTO
+#define NL_MMAP_MSG_ALIGN(sz)          __ALIGN_KERNEL(sz, NL_MMAP_MSG_ALIGNMENT)
+#define NL_MMAP_HDRLEN                 NL_MMAP_MSG_ALIGN(sizeof(struct nl_mmap_hdr))
+
+#define NET_MAJOR 36           /* Major 36 is reserved for networking                                          */
+
+enum {
+       NETLINK_UNCONNECTED = 0,
+       NETLINK_CONNECTED,
+};
+
+/*
+ *  <------- NLA_HDRLEN ------> <-- NLA_ALIGN(payload)-->
+ * +---------------------+- - -+- - - - - - - - - -+- - -+
+ * |        Header       | Pad |     Payload       | Pad |
+ * |   (struct nlattr)   | ing |                   | ing |
+ * +---------------------+- - -+- - - - - - - - - -+- - -+
+ *  <-------------- nlattr->nla_len -------------->
+ */
+
+struct nlattr {
+       __u16           nla_len;
+       __u16           nla_type;
+};
+
+/*
+ * nla_type (16 bits)
+ * +---+---+-------------------------------+
+ * | N | O | Attribute Type                |
+ * +---+---+-------------------------------+
+ * N := Carries nested attributes
+ * O := Payload stored in network byte order
+ *
+ * Note: The N and O flag are mutually exclusive.
+ */
+#define NLA_F_NESTED           (1 << 15)
+#define NLA_F_NET_BYTEORDER    (1 << 14)
+#define NLA_TYPE_MASK          ~(NLA_F_NESTED | NLA_F_NET_BYTEORDER)
+
+#define NLA_ALIGNTO            4
+#define NLA_ALIGN(len)         (((len) + NLA_ALIGNTO - 1) & ~(NLA_ALIGNTO - 1))
+#define NLA_HDRLEN             ((int) NLA_ALIGN(sizeof(struct nlattr)))
+
+/* Generic 32 bitflags attribute content sent to the kernel.
+ *
+ * The value is a bitmap that defines the values being set
+ * The selector is a bitmask that defines which value is legit
+ *
+ * Examples:
+ *  value = 0x0, and selector = 0x1
+ *  implies we are selecting bit 1 and we want to set its value to 0.
+ *
+ *  value = 0x2, and selector = 0x2
+ *  implies we are selecting bit 2 and we want to set its value to 1.
+ *
+ */
+struct nla_bitfield32 {
+       __u32 value;
+       __u32 selector;
+};
+
+#endif /* __LINUX_NETLINK_H */
index db5ed06c61e85880c8a6010c6513aeb5e326cc94..731785d4b4dd61ffdfe802197d8abf8601e5f69e 100644 (file)
@@ -4,6 +4,7 @@ noinst_HEADERS += \
        include/linux/lwtunnel.h \
        include/linux/mpls_iptunnel.h \
        include/linux/neighbour.h \
+       include/linux/netlink.h \
        include/linux/rtnetlink.h \
        include/linux/socket.h \
        include/linux/net_namespace.h \
index bba86d4c1ff07b4375860fe3943d6927835e6a97..c8ef829064b54bfa268ee21a284f49a8fec8f5c2 100644 (file)
@@ -622,7 +622,7 @@ static const char *lsp_bits2string(uint8_t lsp_bits, char *buf, size_t buf_size)
        pos += sprintf(pos, "%d/",
                       ISIS_MASK_LSP_PARTITION_BIT(lsp_bits) ? 1 : 0);
 
-       pos += sprintf(pos, "%d", ISIS_MASK_LSP_OL_BIT(lsp_bits) ? 1 : 0);
+       sprintf(pos, "%d", ISIS_MASK_LSP_OL_BIT(lsp_bits) ? 1 : 0);
 
        return buf;
 }
@@ -1052,6 +1052,7 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
                                        uint8_t subtlv_len;
 
                                        if (IS_MPLS_TE(isisMplsTE)
+                                           && circuit->interface != NULL
                                            && HAS_LINK_PARAMS(
                                                       circuit->interface))
                                                /* Update Local and Remote IP
index 6e56870ebd8c432b1236f86f85bd222445a70e01..fd82b85f51e71e0d844b6d794029870a37b7a10e 100644 (file)
@@ -309,9 +309,9 @@ int isis_recv_pdu_p2p(struct isis_circuit *circuit, uint8_t *ssnpa)
        addr_len = sizeof(s_addr);
 
        /* we can read directly to the stream */
-       stream_recvfrom(circuit->rcv_stream, circuit->fd,
-                       circuit->interface->mtu, 0, (struct sockaddr *)&s_addr,
-                       (socklen_t *)&addr_len);
+       (void)stream_recvfrom(
+               circuit->rcv_stream, circuit->fd, circuit->interface->mtu, 0,
+               (struct sockaddr *)&s_addr, (socklen_t *)&addr_len);
 
        if (s_addr.sll_pkttype == PACKET_OUTGOING) {
                /*  Read the packet into discard buff */
index a55a0e1902168b6b934acb6e58f20f6d53be01a8..2e2933db332b5925850a3b4d9cf1ade228b61c8b 100644 (file)
@@ -77,14 +77,13 @@ enum vertextype {
 /*
  * Triple <N, d(N), {Adj(N)}>
  */
+union isis_N {
+       uint8_t id[ISIS_SYS_ID_LEN + 1];
+       struct prefix prefix;
+};
 struct isis_vertex {
        enum vertextype type;
-
-       union {
-               uint8_t id[ISIS_SYS_ID_LEN + 1];
-               struct prefix prefix;
-       } N;
-
+       union isis_N N;
        uint32_t d_N;     /* d(N) Distance from this IS      */
        uint16_t depth; /* The depth in the imaginary tree */
        struct list *Adj_N;    /* {Adj(N)} next hop or neighbor list */
@@ -407,28 +406,28 @@ static const char *vid2string(struct isis_vertex *vertex, char *buff, int size)
        return "UNKNOWN";
 }
 
-static void isis_vertex_id_init(struct isis_vertex *vertex, void *id,
+static void isis_vertex_id_init(struct isis_vertex *vertex, union isis_N *n,
                                enum vertextype vtype)
 {
        vertex->type = vtype;
 
        if (VTYPE_IS(vtype) || VTYPE_ES(vtype)) {
-               memcpy(vertex->N.id, (uint8_t *)id, ISIS_SYS_ID_LEN + 1);
+               memcpy(vertex->N.id, n->id, ISIS_SYS_ID_LEN + 1);
        } else if (VTYPE_IP(vtype)) {
-               memcpy(&vertex->N.prefix, (struct prefix *)id,
-                      sizeof(struct prefix));
+               memcpy(&vertex->N.prefix, &n->prefix, sizeof(struct prefix));
        } else {
                zlog_err("WTF!");
        }
 }
 
-static struct isis_vertex *isis_vertex_new(void *id, enum vertextype vtype)
+static struct isis_vertex *isis_vertex_new(union isis_N *n,
+                                          enum vertextype vtype)
 {
        struct isis_vertex *vertex;
 
        vertex = XCALLOC(MTYPE_ISIS_VERTEX, sizeof(struct isis_vertex));
 
-       isis_vertex_id_init(vertex, id, vtype);
+       isis_vertex_id_init(vertex, n, vtype);
 
        vertex->Adj_N = list_new();
        vertex->parents = list_new();
@@ -598,17 +597,17 @@ static struct isis_vertex *isis_spf_add_root(struct isis_spftree *spftree,
 #ifdef EXTREME_DEBUG
        char buff[PREFIX2STR_BUFFER];
 #endif /* EXTREME_DEBUG */
-       uint8_t id[ISIS_SYS_ID_LEN + 1];
+       union isis_N n;
 
-       memcpy(id, sysid, ISIS_SYS_ID_LEN);
-       LSP_PSEUDO_ID(id) = 0;
+       memcpy(n.id, sysid, ISIS_SYS_ID_LEN);
+       LSP_PSEUDO_ID(n.id) = 0;
 
        lsp = isis_root_system_lsp(spftree->area, spftree->level, sysid);
        if (lsp == NULL)
                zlog_warn("ISIS-Spf: could not find own l%d LSP!",
                          spftree->level);
 
-       vertex = isis_vertex_new(id,
+       vertex = isis_vertex_new(&n,
                                 spftree->area->oldmetric
                                         ? VTYPE_NONPSEUDO_IS
                                         : VTYPE_NONPSEUDO_TE_IS);
@@ -625,11 +624,12 @@ static struct isis_vertex *isis_spf_add_root(struct isis_spftree *spftree,
 }
 
 static struct isis_vertex *isis_find_vertex(struct isis_vertex_queue *queue,
-                                           void *id, enum vertextype vtype)
+                                           union isis_N *n,
+                                           enum vertextype vtype)
 {
        struct isis_vertex querier;
 
-       isis_vertex_id_init(&querier, id, vtype);
+       isis_vertex_id_init(&querier, n, vtype);
        return hash_lookup(queue->hash, &querier);
 }
 
@@ -1212,7 +1212,7 @@ static void add_to_paths(struct isis_spftree *spftree,
 {
        char buff[PREFIX2STR_BUFFER];
 
-       if (isis_find_vertex(&spftree->paths, vertex->N.id, vertex->type))
+       if (isis_find_vertex(&spftree->paths, &vertex->N, vertex->type))
                return;
        isis_vertex_queue_append(&spftree->paths, vertex);
 
index 6834f52a82a63c2bbab54ac4b332a753e6451c8c..8e53df3b61fe5dfb8c46e172772f9110a45c3af7 100644 (file)
@@ -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) {
index 6f04d72082bc589c3a2afe7bd0eaf4c0735d016e..cecaa0693dba709ee8212a699230edc0ffdbbf1c 100644 (file)
@@ -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];
index 39e20ef7c84d467d2b2081af8823653be3a0df29..ec70ef510adecd14d82c2cc76ed3f3f462aefe1e 100644 (file)
@@ -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);
index 382b00688440d854285b66b10e0bd75479f5b87a..4ef57f574a75c21b90f09202653a543041926703 100644 (file)
@@ -89,6 +89,9 @@ struct cmd_node ldp_pseudowire_node =
 int
 ldp_get_address(const char *str, int *af, union ldpd_addr *addr)
 {
+       if (!str || !af || !addr)
+               return (-1);
+
        memset(addr, 0, sizeof(*addr));
 
        if (inet_pton(AF_INET, str, &addr->v4) == 1) {
@@ -428,6 +431,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 +715,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 +787,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 +809,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 +1030,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 +1130,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 +1180,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 +1214,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 +1240,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 +1283,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 +1336,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
index b265c98dae3d43d990d246807035a576f8016d03..b51ff82cea5a9b035fa182dddcc4b64009d44ad0 100644 (file)
@@ -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 ||
index bcec6c2ccab3113a76183729b2047e642445686e..44dcc02eb8645b765a5ee04ccd5a363b8aa45bd7 100644 (file)
 #define pychar wchar_t
 static wchar_t *wconv(const char *s)
 {
-       size_t outlen = mbstowcs(NULL, s, 0);
+       size_t outlen = s ? mbstowcs(NULL, s, 0) : 0;
        wchar_t *out = malloc((outlen + 1) * sizeof(wchar_t));
-       mbstowcs(out, s, outlen + 1);
+
+       if (outlen > 0)
+               mbstowcs(out, s, outlen);
        out[outlen] = 0;
        return out;
 }
index a8e61c6bb4f1a8784ea2a441be104b1760c6deb9..0bf856f2484b4ac07d74466629e11f6f92982723 100644 (file)
@@ -261,8 +261,11 @@ void print_version(const char *progname)
 
 char *argv_concat(struct cmd_token **argv, int argc, int shift)
 {
-       int cnt = argc - shift;
-       const char *argstr[cnt];
+       int cnt = MAX(argc - shift, 0);
+       const char *argstr[cnt + 1];
+
+       if (!cnt)
+               return NULL;
 
        for (int i = 0; i < cnt; i++)
                argstr[i] = argv[i + shift]->arg;
@@ -515,13 +518,6 @@ static int config_write_host(struct vty *vty)
                                        host.enable);
                }
 
-               if (zlog_default->default_lvl != LOG_DEBUG) {
-                       vty_out(vty,
-                               "! N.B. The 'log trap' command is deprecated.\n");
-                       vty_out(vty, "log trap %s\n",
-                               zlog_priority[zlog_default->default_lvl]);
-               }
-
                if (host.logfile
                    && (zlog_default->maxlvl[ZLOG_DEST_FILE]
                        != ZLOG_DISABLED)) {
@@ -2429,7 +2425,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 +2442,39 @@ 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, ":");
+       if (token == NULL)
+               return;
+
+       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>]",
@@ -2552,36 +2582,6 @@ DEFUN (no_config_log_facility,
        return CMD_SUCCESS;
 }
 
-DEFUN_DEPRECATED(
-       config_log_trap, config_log_trap_cmd,
-       "log trap <emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>",
-       "Logging control\n"
-       "(Deprecated) Set logging level and default for all destinations\n" LOG_LEVEL_DESC)
-{
-       int new_level;
-       int i;
-
-       if ((new_level = level_match(argv[2]->arg)) == ZLOG_DISABLED)
-               return CMD_ERR_NO_MATCH;
-
-       zlog_default->default_lvl = new_level;
-       for (i = 0; i < ZLOG_NUM_DESTS; i++)
-               if (zlog_default->maxlvl[i] != ZLOG_DISABLED)
-                       zlog_default->maxlvl[i] = new_level;
-       return CMD_SUCCESS;
-}
-
-DEFUN_DEPRECATED(
-       no_config_log_trap, no_config_log_trap_cmd,
-       "no log trap [emergencies|alerts|critical|errors|warnings|notifications|informational|debugging]",
-       NO_STR
-       "Logging control\n"
-       "Permit all logging information\n" LOG_LEVEL_DESC)
-{
-       zlog_default->default_lvl = LOG_DEBUG;
-       return CMD_SUCCESS;
-}
-
 DEFUN (config_log_record_priority,
        config_log_record_priority_cmd,
        "log record-priority",
@@ -2871,8 +2871,6 @@ void cmd_init(int terminal)
                install_element(CONFIG_NODE, &no_config_log_syslog_cmd);
                install_element(CONFIG_NODE, &config_log_facility_cmd);
                install_element(CONFIG_NODE, &no_config_log_facility_cmd);
-               install_element(CONFIG_NODE, &config_log_trap_cmd);
-               install_element(CONFIG_NODE, &no_config_log_trap_cmd);
                install_element(CONFIG_NODE, &config_log_record_priority_cmd);
                install_element(CONFIG_NODE,
                                &no_config_log_record_priority_cmd);
index 9bf482f41b6054c902adce326dd8839140a374fe..2d333b098a0c39d8f74edb7a221f3a6c3f4adae6 100644 (file)
@@ -240,9 +240,6 @@ struct cmd_node {
 #define DEFUN_HIDDEN(funcname, cmdname, cmdstr, helpstr)                       \
        DEFUN_ATTR(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_HIDDEN)
 
-#define DEFUN_DEPRECATED(funcname, cmdname, cmdstr, helpstr)                   \
-       DEFUN_ATTR(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_DEPRECATED)
-
 /* DEFUN_NOSH for commands that vtysh should ignore */
 #define DEFUN_NOSH(funcname, cmdname, cmdstr, helpstr)                         \
        DEFUN(funcname, cmdname, cmdstr, helpstr)
@@ -479,4 +476,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 */
index 99ec03e0c2486d3e4a3f9c1aa03b6a35f7bcbd06..c165305d78315a7c9e4f440f574e825af7a0ad1d 100644 (file)
@@ -608,11 +608,14 @@ static struct cmd_token *disambiguate_tokens(struct cmd_token *first,
 static struct list *disambiguate(struct list *first, struct list *second,
                                 vector vline, unsigned int n)
 {
+       assert(first != NULL);
+       assert(second != NULL);
        // doesn't make sense for these to be inequal length
        assert(first->count == second->count);
        assert(first->count == vector_active(vline) - n + 1);
 
-       struct listnode *fnode = listhead(first), *snode = listhead(second);
+       struct listnode *fnode = listhead_unchecked(first),
+                       *snode = listhead_unchecked(second);
        struct cmd_token *ftok = listgetdata(fnode), *stok = listgetdata(snode),
                         *best = NULL;
 
index 6419f805abb57c6ed2f568d4ccf05e1dfe29cff1..54241407205d203f0ae3964e784afbf27bc03e7d 100644 (file)
@@ -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;
index 88203fbeb6bb57e424d5a1a2a5bfbd7db0d78fd2..9ea5e985cd424ab631362335ef33cdb7da5715c6 100644 (file)
@@ -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();
@@ -813,7 +846,9 @@ static int frr_daemon_ctl(struct thread *t)
        switch (buf[0]) {
        case 'S': /* SIGTSTP */
                vty_stdio_suspend();
-               send(daemon_ctl_sock, "s", 1, 0);
+               if (send(daemon_ctl_sock, "s", 1, 0) < 0)
+                       zlog_err("%s send(\"s\") error (SIGTSTP propagation)",
+                                (di && di->name ? di->name : ""));
                break;
        case 'R': /* SIGTCNT [implicit] */
                vty_stdio_resume();
index 7ffa780bfb9a75d8d6316a0b73d564d9399650d4..d2552799069ce9233d048c7f2a46f8383e9d3f64 100644 (file)
@@ -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);
index 39e70293d24bafd974afaf87f5221bef01c3861a..1e2631ea46157157d05f406adb052cbcb9524637 100644 (file)
@@ -52,7 +52,9 @@ struct list {
 };
 
 #define listnextnode(X) ((X) ? ((X)->next) : NULL)
+#define listnextnode_unchecked(X) ((X)->next)
 #define listhead(X) ((X) ? ((X)->head) : NULL)
+#define listhead_unchecked(X) ((X)->head)
 #define listtail(X) ((X) ? ((X)->tail) : NULL)
 #define listcount(X) ((X)->count)
 #define list_isempty(X) ((X)->head == NULL && (X)->tail == NULL)
index 5ed1589f456630b3b325a007fab9097a9a0f0556..056b737f540ce8895dc037082362652a81d4a8df 100644 (file)
@@ -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);
index cfe7d6d6f81bdf802191e2559f1438ab7c985e98..7c99742d3407bf3454b30ac2c50436b226a8d79f 100644 (file)
@@ -824,6 +824,19 @@ void zprivs_init(struct zebra_privs_t *zprivs)
 
 #ifdef HAVE_CAPABILITIES
        zprivs_caps_init(zprivs);
+
+       /*
+        * If we have initialized the system with no requested
+        * capabilities, change will not have been set
+        * to anything by zprivs_caps_init, As such
+        * we should make sure that when we attempt
+        * to raize privileges that we actually have
+        * a do nothing function to call instead of a
+        * crash :).
+        */
+       if (!zprivs->change)
+               zprivs->change = zprivs_change_null;
+
 #else  /* !HAVE_CAPABILITIES */
        /* we dont have caps. we'll need to maintain rid and saved uid
         * and change euid back to saved uid (who we presume has all neccessary
index 37c1e5283deac6ed38a7114ca94cbfa5e7cf3a7a..03a2be3e09fa39dc0ea6ac9405b679a64f422afc 100644 (file)
@@ -63,13 +63,12 @@ void sbuf_push(struct sbuf *buf, int indent, const char *format, ...)
        int written;
 
        if (!buf->fixed) {
-               char dummy;
                int written1, written2;
                size_t new_size;
 
-               written1 = snprintf(&dummy, 0, "%*s", indent, "");
+               written1 = indent;
                va_start(args, format);
-               written2 = vsnprintf(&dummy, 0, format, args);
+               written2 = vsnprintf(NULL, 0, format, args);
                va_end(args);
 
                new_size = buf->size;
index 1d8d9990df5d812cd4a2014ac33991ae84280350..815be86c2e152eec3f943f4d87007ca25363e8a2 100644 (file)
@@ -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)
index 28a7f647cba7faf80c1fef56da5b8f42a8c3045c..44378b536303060f9aaf3999ddac6994c76e694b 100644 (file)
@@ -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);
index 280b2ace51a64bd64c5df459b5291854bc2ab554..e9d1f2e323747eaf7879af78fb34b1e22513352e 100644 (file)
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -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. */
index d14ddf5908d69dbe4a7825ba061dd764288bff79..b55abf22043f4956617b05ce4aab9084e3807b47 100644 (file)
--- a/lib/vty.h
+++ b/lib/vty.h
@@ -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 *);
index e6111f9d7120e618f6a0c3471e8694bb2c482374..3bb0d8308ecbb94c1574eadbf57e7ca486985883 100644 (file)
@@ -287,6 +287,7 @@ static void vici_recv_sa(struct vici_conn *vici, struct zbuf *msg, int event)
        char buf[32];
        struct handle_sa_ctx ctx = {
                .event = event,
+               .msgctx.nsections = 0
        };
 
        vici_parse_message(vici, msg, parse_sa_message, &ctx.msgctx);
index b3aa3b21d2b5221e1d3eb76cf9395cd6764b1a23..7bccc78e00882fe4f93daea760c176f2e4eaeaa6 100644 (file)
@@ -161,9 +161,10 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
            && route->type != OSPF6_DEST_TYPE_RANGE
            && ((route->type != OSPF6_DEST_TYPE_ROUTER)
                || !CHECK_FLAG(route->path.router_bits, OSPF6_ROUTER_BIT_E))) {
-               if (is_debug)
-                       zlog_debug(
-                               "Route type is none of network, range nor ASBR, ignore");
+#if 0
+               zlog_debug(
+                       "Route type is none of network, range nor ASBR, ignore");
+#endif
                return 0;
        }
 
@@ -177,16 +178,17 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
 
        /* do not generate if the path's area is the same as target area */
        if (route->path.area_id == area->area_id) {
-               if (is_debug)
-                       zlog_debug("The route is in the area itself, ignore");
+#if 0
+               zlog_debug("The route is in the area itself, ignore");
+#endif
                return 0;
        }
 
        /* do not generate if the nexthops belongs to the target area */
        if (ospf6_abr_nexthops_belong_to_area(route, area)) {
-               if (is_debug)
-                       zlog_debug(
-                               "The route's nexthop is in the same area, ignore");
+#if 0
+               zlog_debug("The route's nexthop is in the same area, ignore");
+#endif
                return 0;
        }
 
@@ -641,6 +643,11 @@ void ospf6_abr_originate_summary(struct ospf6_route *route)
 
        if (route->type == OSPF6_DEST_TYPE_NETWORK) {
                oa = ospf6_area_lookup(route->path.area_id, ospf6);
+               if (!oa) {
+                       zlog_err("OSPFv6 area lookup failed");
+                       return;
+               }
+
                range = ospf6_route_lookup_bestmatch(&route->prefix,
                                                     oa->range_table);
                if (range) {
@@ -864,7 +871,8 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
                                lsa->header);
                prefix.family = AF_INET6;
                prefix.prefixlen = prefix_lsa->prefix.prefix_length;
-               ospf6_prefix_in6_addr(&prefix.u.prefix6, &prefix_lsa->prefix);
+               ospf6_prefix_in6_addr(&prefix.u.prefix6, prefix_lsa,
+                                     &prefix_lsa->prefix);
                if (is_debug)
                        prefix2str(&prefix, buf, sizeof(buf));
                table = oa->ospf6->route_table;
@@ -1284,7 +1292,7 @@ static char *ospf6_inter_area_prefix_lsa_get_prefix_str(struct ospf6_lsa *lsa,
                        (struct ospf6_inter_prefix_lsa *)OSPF6_LSA_HEADER_END(
                                lsa->header);
 
-               ospf6_prefix_in6_addr(&in6, &prefix_lsa->prefix);
+               ospf6_prefix_in6_addr(&in6, prefix_lsa, &prefix_lsa->prefix);
                if (buf) {
                        inet_ntop(AF_INET6, &in6, buf, buflen);
                        sprintf(&buf[strlen(buf)], "/%d",
index 7f575ee50638b8e5da6c56add7fa7f4cc802a34c..a7233965077b03b703500a94bd13ac59cc89b0e5 100644 (file)
@@ -497,7 +497,8 @@ void ospf6_asbr_lsa_add(struct ospf6_lsa *lsa)
        route->type = OSPF6_DEST_TYPE_NETWORK;
        route->prefix.family = AF_INET6;
        route->prefix.prefixlen = external->prefix.prefix_length;
-       ospf6_prefix_in6_addr(&route->prefix.u.prefix6, &external->prefix);
+       ospf6_prefix_in6_addr(&route->prefix.u.prefix6, external,
+                             &external->prefix);
 
        route->path.area_id = asbr_entry->path.area_id;
        route->path.origin.type = lsa->header->type;
@@ -576,7 +577,7 @@ void ospf6_asbr_lsa_remove(struct ospf6_lsa *lsa,
        route_to_del->type = OSPF6_DEST_TYPE_NETWORK;
        route_to_del->prefix.family = AF_INET6;
        route_to_del->prefix.prefixlen = external->prefix.prefix_length;
-       ospf6_prefix_in6_addr(&route_to_del->prefix.u.prefix6,
+       ospf6_prefix_in6_addr(&route_to_del->prefix.u.prefix6, external,
                              &external->prefix);
 
        route_to_del->path.origin.type = lsa->header->type;
@@ -603,7 +604,7 @@ void ospf6_asbr_lsa_remove(struct ospf6_lsa *lsa,
        memset(&prefix, 0, sizeof(struct prefix));
        prefix.family = AF_INET6;
        prefix.prefixlen = external->prefix.prefix_length;
-       ospf6_prefix_in6_addr(&prefix.u.prefix6, &external->prefix);
+       ospf6_prefix_in6_addr(&prefix.u.prefix6, external, &external->prefix);
 
        route = ospf6_route_lookup(&prefix, ospf6->route_table);
        if (route == NULL) {
@@ -1705,7 +1706,8 @@ static char *ospf6_as_external_lsa_get_prefix_str(struct ospf6_lsa *lsa,
                        lsa->header);
 
                if (pos == 0) {
-                       ospf6_prefix_in6_addr(&in6, &external->prefix);
+                       ospf6_prefix_in6_addr(&in6, external,
+                                             &external->prefix);
                        prefix_length = external->prefix.prefix_length;
                } else {
                        in6 = *((struct in6_addr
index 2059d8486829c099daf136c1b853df2d8e418fc0..ae26668c8ae8c199230459dd29818fcb20234726 100644 (file)
@@ -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)
index d99541ebaddfa8c28ae9a1423546b551921d3430..0ce08a61e259b67e9fdde0fddfc6ea5dc6481299 100644 (file)
@@ -1323,6 +1323,8 @@ static void ospf6_intra_prefix_update_route_origin(struct ospf6_route *oa_route)
        g_route = ospf6_route_lookup(&oa_route->prefix,
                                     ospf6->route_table);
 
+       assert(g_route);
+
        for (ospf6_route_lock(g_route); g_route &&
             ospf6_route_is_prefix(&oa_route->prefix, g_route);
             g_route = nroute) {
@@ -1698,7 +1700,8 @@ void ospf6_intra_prefix_lsa_add(struct ospf6_lsa *lsa)
                memset(&route->prefix, 0, sizeof(struct prefix));
                route->prefix.family = AF_INET6;
                route->prefix.prefixlen = op->prefix_length;
-               ospf6_prefix_in6_addr(&route->prefix.u.prefix6, op);
+               ospf6_prefix_in6_addr(&route->prefix.u.prefix6,
+                                     intra_prefix_lsa, op);
 
                route->type = OSPF6_DEST_TYPE_NETWORK;
                route->path.origin.type = lsa->header->type;
@@ -1880,7 +1883,7 @@ void ospf6_intra_prefix_lsa_remove(struct ospf6_lsa *lsa)
                memset(&prefix, 0, sizeof(struct prefix));
                prefix.family = AF_INET6;
                prefix.prefixlen = op->prefix_length;
-               ospf6_prefix_in6_addr(&prefix.u.prefix6, op);
+               ospf6_prefix_in6_addr(&prefix.u.prefix6, intra_prefix_lsa, op);
 
                route = ospf6_route_lookup(&prefix, oa->route_table);
                if (route == NULL)
index 4b56a64b7f66803e9e788c3808316ccad5f356a2..864974c9a4c3d952723a1a9a6dede2e786c685ab 100644 (file)
 
 #include "ospf6_proto.h"
 
+void ospf6_prefix_in6_addr(struct in6_addr *in6, const void *prefix_buf,
+                          const struct ospf6_prefix *p)
+{
+       ptrdiff_t in6_off = (caddr_t)p->addr - (caddr_t)prefix_buf;
+
+       memset(in6, 0, sizeof(struct in6_addr));
+       memcpy(in6, (uint8_t *)prefix_buf + in6_off,
+              OSPF6_PREFIX_SPACE(p->prefix_length));
+}
+
 void ospf6_prefix_apply_mask(struct ospf6_prefix *op)
 {
        uint8_t *pnt, mask;
index ca2804c47624d52eeb7b0aa46ed1bc241f58fcb5..c9e7b549db8b4443cb99f86fb33c87b41ff11f44 100644 (file)
@@ -84,13 +84,8 @@ struct ospf6_prefix {
 #define OSPF6_PREFIX_NEXT(x)                                                   \
        ((struct ospf6_prefix *)((caddr_t)(x) + OSPF6_PREFIX_SIZE(x)))
 
-#define ospf6_prefix_in6_addr(in6, op)                                         \
-       do {                                                                   \
-               memset(in6, 0, sizeof(struct in6_addr));                       \
-               memcpy(in6, (caddr_t)(op) + sizeof(struct ospf6_prefix),       \
-                      OSPF6_PREFIX_SPACE((op)->prefix_length));               \
-       } while (0)
-
+extern void ospf6_prefix_in6_addr(struct in6_addr *in6, const void *prefix_buf,
+                                 const struct ospf6_prefix *p);
 extern void ospf6_prefix_apply_mask(struct ospf6_prefix *op);
 extern void ospf6_prefix_options_printbuf(uint8_t prefix_options, char *buf,
                                          int size);
index 28c3459825e0a5ce756d2af40c8ba4808a0742d2..5b6691e6bf1b4039f9724a2130d019d18a59cd68 100644 (file)
@@ -677,6 +677,10 @@ void ospf6_spf_schedule(struct ospf6 *ospf6, unsigned int reason)
 {
        unsigned long delay, elapsed, ht;
 
+       /* OSPF instance does not exist. */
+       if (ospf6 == NULL)
+               return;
+
        ospf6_set_spf_reason(ospf6, reason);
 
        if (IS_OSPF6_DEBUG_SPF(PROCESS) || IS_OSPF6_DEBUG_SPF(TIME)) {
@@ -686,10 +690,6 @@ void ospf6_spf_schedule(struct ospf6 *ospf6, unsigned int reason)
                           rbuf);
        }
 
-       /* OSPF instance does not exist. */
-       if (ospf6 == NULL)
-               return;
-
        /* SPF calculation timer is already scheduled. */
        if (ospf6->t_spf_calc) {
                if (IS_OSPF6_DEBUG_SPF(PROCESS) || IS_OSPF6_DEBUG_SPF(TIME))
index 8369dde82215ad67cbe64511a14f7cda623554c3..b1175a2f68cc3f7e080fff2048a7a3945b439c49 100644 (file)
@@ -510,17 +510,18 @@ struct msg *new_msg_originate_request(uint32_t seqnum, struct in_addr ifaddr,
        struct msg_originate_request *omsg;
        unsigned int omsglen;
        char buf[OSPF_API_MAX_MSG_SIZE];
+       size_t off_data = offsetof(struct msg_originate_request, data);
+       size_t data_maxs = sizeof(buf) - off_data;
+       struct lsa_header *omsg_data = (struct lsa_header *)&buf[off_data];
 
        omsg = (struct msg_originate_request *)buf;
        omsg->ifaddr = ifaddr;
        omsg->area_id = area_id;
 
        omsglen = ntohs(data->length);
-       if (omsglen
-           > sizeof(buf) - offsetof(struct msg_originate_request, data))
-               omsglen = sizeof(buf)
-                         - offsetof(struct msg_originate_request, data);
-       memcpy(&omsg->data, data, omsglen);
+       if (omsglen > data_maxs)
+               omsglen = data_maxs;
+       memcpy(omsg_data, data, omsglen);
        omsglen += sizeof(struct msg_originate_request)
                   - sizeof(struct lsa_header);
 
@@ -630,6 +631,9 @@ struct msg *new_msg_lsa_change_notify(uint8_t msgtype, uint32_t seqnum,
        uint8_t buf[OSPF_API_MAX_MSG_SIZE];
        struct msg_lsa_change_notify *nmsg;
        unsigned int len;
+       size_t off_data = offsetof(struct msg_lsa_change_notify, data);
+       size_t data_maxs = sizeof(buf) - off_data;
+       struct lsa_header *nmsg_data = (struct lsa_header *)&buf[off_data];
 
        assert(data);
 
@@ -640,10 +644,9 @@ struct msg *new_msg_lsa_change_notify(uint8_t msgtype, uint32_t seqnum,
        memset(&nmsg->pad, 0, sizeof(nmsg->pad));
 
        len = ntohs(data->length);
-       if (len > sizeof(buf) - offsetof(struct msg_lsa_change_notify, data))
-               len = sizeof(buf)
-                     - offsetof(struct msg_lsa_change_notify, data);
-       memcpy(&nmsg->data, data, len);
+       if (len > data_maxs)
+               len = data_maxs;
+       memcpy(nmsg_data, data, len);
        len += sizeof(struct msg_lsa_change_notify) - sizeof(struct lsa_header);
 
        return msg_new(msgtype, nmsg, seqnum, len);
index 37735e36119e3129cb091bc5d2d3f06b8312bb80..8f8900e147fee286bc442f9d970055d35674655a 100644 (file)
@@ -1741,6 +1741,8 @@ struct ospf_lsa *ospf_apiserver_lsa_refresher(struct ospf_lsa *lsa)
        struct ospf_lsa *new = NULL;
        struct ospf *ospf;
 
+       assert(lsa);
+
        ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
        assert(ospf);
 
@@ -1751,6 +1753,7 @@ struct ospf_lsa *ospf_apiserver_lsa_refresher(struct ospf_lsa *lsa)
                        dump_lsa_key(lsa));
                lsa->data->ls_age =
                        htons(OSPF_LSA_MAXAGE); /* Flush it anyway. */
+               goto out;
        }
 
        if (IS_LSA_MAXAGE(lsa)) {
index d42562486299fa4f336f28848bb48ba8e6eb43c0..c799a4b30f9840e4bbb65f6a4934075af9ce6ada 100644 (file)
@@ -582,7 +582,7 @@ static int ospf_ase_route_match_same(struct route_table *rt,
 
        /* Check each path. */
        for (n1 = listhead(or->paths), n2 = listhead(newor->paths); n1 && n2;
-            n1 = listnextnode(n1), n2 = listnextnode(n2)) {
+            n1 = listnextnode_unchecked(n1), n2 = listnextnode_unchecked(n2)) {
                op = listgetdata(n1);
                newop = listgetdata(n2);
 
index b964bbab74092763cab8639056c71eb04459f775..b36f2f4652069ee0f95d2775af6980a96856f5ea 100644 (file)
@@ -170,8 +170,8 @@ int ospf_route_match_same(struct route_table *rt, struct prefix_ipv4 *prefix,
                        /* Check each path. */
                        for (n1 = listhead(or->paths),
                            n2 = listhead(newor->paths);
-                            n1 && n2;
-                            n1 = listnextnode(n1), n2 = listnextnode(n2)) {
+                            n1 && n2; n1 = listnextnode_unchecked(n1),
+                           n2 = listnextnode_unchecked(n2)) {
                                op = listgetdata(n1);
                                newop = listgetdata(n2);
 
index 2b1b328617e31e1c1ef034095b0da3eb5e68eae6..86125d0c769fcb11ea3e55da2295ddbc59999fc8 100644 (file)
@@ -2051,12 +2051,11 @@ static uint16_t ospf_mpls_te_show_link_subtlv(struct vty *vty,
                                              struct tlv_header *tlvh0,
                                              uint16_t subtotal, uint16_t total)
 {
-       struct tlv_header *tlvh, *next;
+       struct tlv_header *tlvh;
        uint16_t sum = subtotal;
 
        for (tlvh = tlvh0; sum < total;
-            tlvh = (next ? next : TLV_HDR_NEXT(tlvh))) {
-               next = NULL;
+            tlvh = TLV_HDR_NEXT(tlvh)) {
                switch (ntohs(tlvh->type)) {
                case TE_LINK_SUBTLV_LINK_TYPE:
                        sum += show_vty_link_subtlv_link_type(vty, tlvh);
index 31cffea7f2350be03bd6233a409073da3d3bb380..ddf9133ed96ff30ae1dc3c50e6af8990904a18e3 100644 (file)
@@ -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);
@@ -8166,6 +8166,11 @@ DEFUN (ospf_redistribute_instance_source,
 
        source = proto_redistnum(AFI_IP, argv[idx_ospf_table]->text);
 
+       if (source < 0) {
+               vty_out(vty, "Unknown instance redistribution\n");
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
        instance = strtoul(argv[idx_number]->arg, NULL, 10);
 
        if ((source == ZEBRA_ROUTE_OSPF) && !ospf->instance) {
index 141ece9c7a74b228c6f075dff134d233d8943742..0a7776cced054c5dac2eb563530f0e3c80c46b7f 100644 (file)
@@ -670,6 +670,16 @@ int ospf_redistribute_set(struct ospf *ospf, int type, unsigned short instance,
        struct ospf_redist *red;
 
        red = ospf_redist_lookup(ospf, type, instance);
+
+       if (red == NULL) {
+               zlog_err(
+                        "Redistribute[%s][%d]: Lookup failed  Type[%d] , Metric[%d]",
+                        ospf_redist_string(type), instance,
+                        metric_type(ospf, type, instance),
+                        metric_value(ospf, type, instance));
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
        if (ospf_is_type_redistributed(ospf, type, instance)) {
                if (mtype != red->dmetric.type) {
                        red->dmetric.type = mtype;
index 4cf38439c658e6efdefdc2de52cdd74d26574db2..f315421843ee1e9df1fd9e0e4c9042de1eaf21b7 100644 (file)
@@ -243,13 +243,14 @@ static struct ospf *ospf_new(unsigned short instance, const char *name)
                        zlog_debug(
                                "%s: Create new ospf instance with vrf_name %s vrf_id %u",
                                __PRETTY_FUNCTION__, name, new->vrf_id);
-               if (vrf)
-                       ospf_vrf_link(new, vrf);
        } else {
                new->vrf_id = VRF_DEFAULT;
                vrf = vrf_lookup_by_id(VRF_DEFAULT);
-               ospf_vrf_link(new, vrf);
        }
+
+       if (vrf)
+               ospf_vrf_link(new, vrf);
+
        ospf_zebra_vrf_register(new);
 
        new->abr_type = OSPF_ABR_DEFAULT;
index 731fdb1beb5c5e71f9d382820e30439549a41c0d..c0d95aeed9e3799542ee7097f3d982b899a8e98e 100644 (file)
@@ -266,6 +266,8 @@ static int recv_response(int fd, int *hops, struct igmp_mtrace *mtracer)
        int mtrace_len;
        int responses;
        unsigned short sum;
+       size_t mtrace_off;
+       size_t ip_len;
 
        recvd = recvfrom(fd, mtrace_buf, IP_AND_MTRACE_BUF_LEN, 0, NULL, 0);
 
@@ -292,17 +294,20 @@ static int recv_response(int fd, int *hops, struct igmp_mtrace *mtracer)
        if (sum != in_cksum(ip, ip->ip_hl * 4))
                return -1;
 
-       mtrace = (struct igmp_mtrace *)(mtrace_buf + (4 * ip->ip_hl));
-
-       mtrace_len = ntohs(ip->ip_len) - ip->ip_hl * 4;
-
-       if ((char *)mtrace + mtrace_len
-           > (char *)mtrace_buf + IP_AND_MTRACE_BUF_LEN)
+       /* Header overflow check */
+       mtrace_off = 4 * ip->ip_hl;
+       if (mtrace_off > MTRACE_BUF_LEN)
                return -1;
 
-       if (mtrace_len < (int)MTRACE_HDR_SIZE)
+       /* Underflow/overflow check */
+       ip_len = ntohs(ip->ip_len);
+       if (ip_len < mtrace_off || ip_len < MTRACE_HDR_SIZE
+           || ip_len > MTRACE_BUF_LEN)
                return -1;
 
+       mtrace_len = ip_len - mtrace_off;
+       mtrace = (struct igmp_mtrace *)(mtrace_buf + mtrace_off);
+
        sum = mtrace->checksum;
        mtrace->checksum = 0;
        if (sum != in_cksum(mtrace, mtrace_len)) {
@@ -336,7 +341,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);
index 55222ecddbd81ab973ca2702eefdc6a77fbc570e..123c47568cb0a5b6ec61b4c6cb7a05a877901f37 100644 (file)
@@ -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];
index 673e2ca5b8f2e66566128a7ce92da6ec89440646..95d0278a34317a789275e5357ee9dab41b33e310 100644 (file)
@@ -817,7 +817,7 @@ int igmp_mtrace_recv_qry_req(struct igmp_sock *igmp, struct ip *ip_hdr,
                 * Previous-hop router not known,
                 * packet is sent to an appropriate multicast address
                 */
-               inet_aton(MCAST_ALL_ROUTERS, &nh_addr);
+               (void)inet_aton(MCAST_ALL_ROUTERS, &nh_addr);
        }
 
        /* 6.2.2 8. If this router is the Rendez-vous Point */
index de09b070f467a3f2d4cf45fc3e9b8270dd9ead46..f506875282d3cb65f9d797b06e3f55b2f00bb474 100644 (file)
@@ -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;
 
index 92c27106d583be85b09f9ba645e354e5b9408026..90dc7808ebb802be538ff46dcada1e10a4185cec 100644 (file)
@@ -799,11 +799,11 @@ static int rip_auth_simple_password(struct rte *rte, struct sockaddr_in *from,
                                    struct interface *ifp)
 {
        struct rip_interface *ri;
-       char *auth_str = (char *)&rte->prefix;
+       char *auth_str = (char *)rte + offsetof(struct rte, prefix);
        int i;
 
        /* reject passwords with zeros in the middle of the string */
-       for (i = strlen(auth_str); i < 16; i++) {
+       for (i = strnlen(auth_str, 16); i < 16; i++) {
                if (auth_str[i] != '\0')
                        return 0;
        }
index a478b416bf7f687700db89c2493ec7f2b3cb6fef..22a19da0b3257114b300c4c5d70e904f2b5eb260 100644 (file)
@@ -51,7 +51,6 @@ uint32_t installed_routes = 0;
 uint32_t removed_routes = 0;
 
 zebra_capabilities_t _caps_p[] = {
-       ZCAP_NET_RAW, ZCAP_BIND, ZCAP_NET_ADMIN,
 };
 
 struct zebra_privs_t sharp_privs = {
index 9b60312cef61603cc65ebbb3373831c1930f8631..32d2db768a0fa8e19aa6a8e3d3a3b5918e345672 100644 (file)
@@ -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
 
index 8c3fe0c3c5743ce963e930deda0bd75bea2c8cc1..de58e0a20e2b75756bc168828a9563872ad033da 100644 (file)
@@ -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 */
index 309493b13e9fc199d717c445868b967fc8185603..0697cd8b751811ae6568d20260d214edccb9e16c 100644 (file)
@@ -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;
 }
@@ -2440,24 +2441,6 @@ DEFUNSH(VTYSH_ALL, no_vtysh_log_facility, no_vtysh_log_facility_cmd,
        return CMD_SUCCESS;
 }
 
-DEFUNSH_DEPRECATED(
-       VTYSH_ALL, vtysh_log_trap, vtysh_log_trap_cmd,
-       "log trap <emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>",
-       "Logging control\n"
-       "(Deprecated) Set logging level and default for all destinations\n" LOG_LEVEL_DESC)
-{
-       return CMD_SUCCESS;
-}
-
-DEFUNSH_DEPRECATED(VTYSH_ALL, no_vtysh_log_trap, no_vtysh_log_trap_cmd,
-                  "no log trap [LEVEL]", NO_STR
-                  "Logging control\n"
-                  "Permit all logging information\n"
-                  "Logging level\n")
-{
-       return CMD_SUCCESS;
-}
-
 DEFUNSH(VTYSH_ALL, vtysh_log_record_priority, vtysh_log_record_priority_cmd,
        "log record-priority",
        "Logging control\n"
@@ -2634,8 +2617,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);
 }
 
@@ -3760,8 +3748,6 @@ void vtysh_init_vty(void)
        install_element(CONFIG_NODE, &no_vtysh_log_monitor_cmd);
        install_element(CONFIG_NODE, &vtysh_log_syslog_cmd);
        install_element(CONFIG_NODE, &no_vtysh_log_syslog_cmd);
-       install_element(CONFIG_NODE, &vtysh_log_trap_cmd);
-       install_element(CONFIG_NODE, &no_vtysh_log_trap_cmd);
        install_element(CONFIG_NODE, &vtysh_log_facility_cmd);
        install_element(CONFIG_NODE, &no_vtysh_log_facility_cmd);
        install_element(CONFIG_NODE, &vtysh_log_record_priority_cmd);
index e6d324ab6a64d0697e44943f31c7bdd55e620bcb..5c84219418422842abf7cad504a8da98aa8408dd 100644 (file)
@@ -586,8 +586,13 @@ static int netlink_interface(struct nlmsghdr *h, ns_id_t ns_id, int startup)
                return 0;
 
        len = h->nlmsg_len - NLMSG_LENGTH(sizeof(struct ifinfomsg));
-       if (len < 0)
+       if (len < 0) {
+               zlog_err("%s: Message received from netlink is of a broken size: %d %zu",
+                        __PRETTY_FUNCTION__,
+                        h->nlmsg_len,
+                        (size_t)NLMSG_LENGTH(sizeof(struct ifinfomsg)));
                return -1;
+       }
 
        /* We are interested in some AF_BRIDGE notifications. */
        if (ifi->ifi_family == AF_BRIDGE)
@@ -893,8 +898,13 @@ int netlink_interface_addr(struct nlmsghdr *h, ns_id_t ns_id, int startup)
                return 0;
 
        len = h->nlmsg_len - NLMSG_LENGTH(sizeof(struct ifaddrmsg));
-       if (len < 0)
+       if (len < 0) {
+               zlog_err("%s: Message received from netlink is of a broken size: %d %zu",
+                        __PRETTY_FUNCTION__,
+                        h->nlmsg_len,
+                        (size_t)NLMSG_LENGTH(sizeof(struct ifaddrmsg)));
                return -1;
+       }
 
        memset(tb, 0, sizeof tb);
        netlink_parse_rtattr(tb, IFA_MAX, IFA_RTA(ifa), len);
@@ -1105,8 +1115,12 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
        }
 
        len = h->nlmsg_len - NLMSG_LENGTH(sizeof(struct ifinfomsg));
-       if (len < 0)
+       if (len < 0) {
+               zlog_err("%s: Message received from netlink is of a broken size %d %zu",
+                        __PRETTY_FUNCTION__, h->nlmsg_len,
+                        (size_t)NLMSG_LENGTH(sizeof(struct ifinfomsg)));
                return -1;
+       }
 
        /* We are interested in some AF_BRIDGE notifications. */
        if (ifi->ifi_family == AF_BRIDGE)
index 0e79b8253319d8da60830ceed8daf580ad371462..d9c663184531acb27f873f4ac1664bed917ceb93 100644 (file)
@@ -498,6 +498,75 @@ const char *nl_rttype_to_str(uint8_t rttype)
        return lookup_msg(rttype_str, rttype, "");
 }
 
+#define NL_OK(nla, len)                                                        \
+       ((len) >= (int)sizeof(struct nlattr)                                   \
+        && (nla)->nla_len >= sizeof(struct nlattr)                            \
+        && (nla)->nla_len <= (len))
+#define NL_NEXT(nla, attrlen)                                                  \
+       ((attrlen) -= RTA_ALIGN((nla)->nla_len),                               \
+        (struct nlattr *)(((char *)(nla)) + RTA_ALIGN((nla)->nla_len)))
+#define NL_RTA(r)                                                              \
+       ((struct nlattr *)(((char *)(r))                                       \
+                          + NLMSG_ALIGN(sizeof(struct nlmsgerr))))
+
+static void netlink_parse_nlattr(struct nlattr **tb, int max,
+                                struct nlattr *nla, int len)
+{
+       while (NL_OK(nla, len)) {
+               if (nla->nla_type <= max)
+                       tb[nla->nla_type] = nla;
+               nla = NL_NEXT(nla, len);
+       }
+}
+
+static void netlink_parse_extended_ack(struct nlmsghdr *h)
+{
+       struct nlattr *tb[NLMSGERR_ATTR_MAX + 1];
+       const struct nlmsgerr *err =
+               (const struct nlmsgerr *)((uint8_t *)h
+                                         + NLMSG_ALIGN(
+                                                   sizeof(struct nlmsghdr)));
+       const struct nlmsghdr *err_nlh = NULL;
+       uint32_t hlen = sizeof(*err);
+       const char *msg = NULL;
+       uint32_t off = 0;
+
+       if (!(h->nlmsg_flags & NLM_F_CAPPED))
+               hlen += h->nlmsg_len - NLMSG_ALIGN(sizeof(struct nlmsghdr));
+
+       memset(tb, 0, sizeof(tb));
+       netlink_parse_nlattr(tb, NLMSGERR_ATTR_MAX, NL_RTA(h), hlen);
+
+       if (tb[NLMSGERR_ATTR_MSG])
+               msg = (const char *)RTA_DATA(tb[NLMSGERR_ATTR_MSG]);
+
+       if (tb[NLMSGERR_ATTR_OFFS]) {
+               off = *(uint32_t *)RTA_DATA(tb[NLMSGERR_ATTR_OFFS]);
+
+               if (off > h->nlmsg_len) {
+                       zlog_err("Invalid offset for NLMSGERR_ATTR_OFFS\n");
+               } else if (!(h->nlmsg_flags & NLM_F_CAPPED)) {
+                       /*
+                        * Header of failed message
+                        * we are not doing anything currently with it
+                        * but noticing it for later.
+                        */
+                       err_nlh = &err->msg;
+                       zlog_warn("%s: Received %d extended Ack",
+                                 __PRETTY_FUNCTION__, err_nlh->nlmsg_type);
+               }
+       }
+
+       if (msg && *msg != '\0') {
+               bool is_err = !!err->error;
+
+               if (is_err)
+                       zlog_err("Extended Error: %s", msg);
+               else
+                       zlog_warn("Extended Warning: %s", msg);
+       }
+}
+
 /*
  * netlink_parse_info
  *
@@ -582,6 +651,23 @@ int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int),
                                int errnum = err->error;
                                int msg_type = err->msg.nlmsg_type;
 
+                               if (h->nlmsg_len
+                                   < NLMSG_LENGTH(sizeof(struct nlmsgerr))) {
+                                       zlog_err("%s error: message truncated",
+                                                nl->name);
+                                       return -1;
+                               }
+
+                               /*
+                                * Parse the extended information before
+                                * we actually handle it.
+                                * At this point in time we do not
+                                * do anything other than report the
+                                * issue.
+                                */
+                               if (h->nlmsg_flags & NLM_F_ACK_TLVS)
+                                       netlink_parse_extended_ack(h);
+
                                /* If the error field is zero, then this is an
                                 * ACK */
                                if (err->error == 0) {
@@ -603,13 +689,6 @@ int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int),
                                        continue;
                                }
 
-                               if (h->nlmsg_len
-                                   < NLMSG_LENGTH(sizeof(struct nlmsgerr))) {
-                                       zlog_err("%s error: message truncated",
-                                                nl->name);
-                                       return -1;
-                               }
-
                                /* Deal with errors that occur because of races
                                 * in link handling */
                                if (nl == &zns->netlink_cmd
@@ -692,6 +771,7 @@ int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int),
                        error = (*filter)(h, zns->ns_id, startup);
                        if (error < 0) {
                                zlog_err("%s filter function error", nl->name);
+                               zlog_backtrace(LOG_ERR);
                                ret = error;
                        }
                }
@@ -836,6 +916,9 @@ int netlink_request(struct nlsock *nl, struct nlmsghdr *n)
 void kernel_init(struct zebra_ns *zns)
 {
        unsigned long groups;
+#if defined SOL_NETLINK
+       int one, ret;
+#endif
 
        /*
         * Initialize netlink sockets
@@ -866,6 +949,25 @@ void kernel_init(struct zebra_ns *zns)
        zns->netlink_cmd.sock = -1;
        netlink_socket(&zns->netlink_cmd, 0, zns->ns_id);
 
+       /*
+        * SOL_NETLINK is not available on all platforms yet
+        * apparently.  It's in bits/socket.h which I am not
+        * sure that we want to pull into our build system.
+        */
+#if defined SOL_NETLINK
+       /*
+        * Let's tell the kernel that we want to receive extended
+        * ACKS over our command socket
+        */
+       one = 1;
+       ret = setsockopt(zns->netlink_cmd.sock, SOL_NETLINK, NETLINK_EXT_ACK,
+                        &one, sizeof(one));
+
+       if (ret < 0)
+               zlog_notice("Registration for extended ACK failed : %d %s",
+                           errno, safe_strerror(errno));
+#endif
+
        /* Register kernel socket. */
        if (zns->netlink.sock > 0) {
                /* Only want non-blocking on the netlink event socket */
@@ -880,6 +982,7 @@ void kernel_init(struct zebra_ns *zns)
                netlink_install_filter(zns->netlink.sock,
                                       zns->netlink_cmd.snl.nl_pid);
                zns->t_netlink = NULL;
+
                thread_add_read(zebrad.master, kernel_read, zns,
                                zns->netlink.sock, &zns->t_netlink);
        }
index a5f288f54117f155eb1d8b652c0f9dd27e4d4528..90334915491e1c9f69c51314602c78fbf4386b3d 100644 (file)
@@ -295,8 +295,12 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id,
        }
 
        len = h->nlmsg_len - NLMSG_LENGTH(sizeof(struct rtmsg));
-       if (len < 0)
+       if (len < 0) {
+               zlog_err("%s: Message received from netlink is of a broken size %d %zu",
+                        __PRETTY_FUNCTION__, h->nlmsg_len,
+                        (size_t)NLMSG_LENGTH(sizeof(struct rtmsg)));
                return -1;
+       }
 
        memset(tb, 0, sizeof tb);
        netlink_parse_rtattr(tb, RTA_MAX, RTM_RTA(rtm), len);
@@ -747,8 +751,13 @@ int netlink_route_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
                return 0;
 
        len = h->nlmsg_len - NLMSG_LENGTH(sizeof(struct rtmsg));
-       if (len < 0)
+       if (len < 0) {
+               zlog_err("%s: Message received from netlink is of a broken size: %d %zu",
+                        __PRETTY_FUNCTION__,
+                        h->nlmsg_len,
+                        (size_t)NLMSG_LENGTH(sizeof(struct rtmsg)));
                return -1;
+       }
 
        if (rtm->rtm_type == RTN_MULTICAST)
                netlink_route_change_read_multicast(h, ns_id, startup);
@@ -2356,8 +2365,12 @@ int netlink_neigh_change(struct nlmsghdr *h, ns_id_t ns_id)
 
        /* Length validity. */
        len = h->nlmsg_len - NLMSG_LENGTH(sizeof(struct ndmsg));
-       if (len < 0)
+       if (len < 0) {
+               zlog_err("%s: Message received from netlink is of a broken size %d %zu",
+                        __PRETTY_FUNCTION__, h->nlmsg_len,
+                        (size_t)NLMSG_LENGTH(sizeof(struct ndmsg)));
                return -1;
+       }
 
        /* Is this a notification for the MAC FDB or IP neighbor table? */
        ndm = NLMSG_DATA(h);
index bcffdf47221e9980a4eb7d18f076322112db7d0e..c7a8517e17c73c0ea496db700a5df9db85d24960 100644 (file)
@@ -196,8 +196,12 @@ int netlink_rule_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
                return 0;
 
        len = h->nlmsg_len - NLMSG_LENGTH(sizeof(struct fib_rule_hdr));
-       if (len < 0)
+       if (len < 0) {
+               zlog_err("%s: Message received from netlink is of a broken size: %d %zu",
+                        __PRETTY_FUNCTION__, h->nlmsg_len,
+                        (size_t)NLMSG_LENGTH(sizeof(struct fib_rule_hdr)));
                return -1;
+       }
 
        frh = NLMSG_DATA(h);
        if (frh->family != AF_INET && frh->family != AF_INET6)
index bb6a5652115179086c53a3fb4e92e5006f243c85..d0ea661403d0bdc0ffecce3289ec8a4d3ac540ae 100644 (file)
@@ -212,11 +212,18 @@ static int zebra_ns_notify_read(struct thread *t)
                        continue;
                if (event->mask & IN_DELETE)
                        return zebra_ns_delete(event->name);
-               if (&event->name[event->len] >= &buf[sizeof(buf)]) {
+
+               if (offsetof(struct inotify_event, name) + event->len
+                   >= sizeof(buf)) {
                        zlog_err("NS notify read: buffer underflow");
                        break;
                }
-               event->name[event->len] = 0;
+
+               if (strnlen(event->name, event->len) == event->len) {
+                       zlog_err("NS notify error: bad event name");
+                       break;
+               }
+
                netnspath = ns_netns_pathname(NULL, event->name);
                if (!netnspath)
                        continue;