]> git.proxmox.com Git - mirror_frr.git/commitdiff
Merge pull request #2608 from pacovn/PVS-Studio_dead_code_1
authorDonald Sharp <sharpd@cumulusnetworks.com>
Thu, 19 Jul 2018 12:50:01 +0000 (08:50 -0400)
committerGitHub <noreply@github.com>
Thu, 19 Jul 2018 12:50:01 +0000 (08:50 -0400)
eigrpd lib pimd zebra: dead code (PVS-Studio)

114 files changed:
Makefile.am
bgpd/IMPLEMENTATION.txt
bgpd/bgp_clist.c
bgpd/bgp_ecommunity.c
bgpd/bgp_evpn.c
bgpd/bgp_flowspec.c
bgpd/bgp_flowspec_vty.c
bgpd/bgp_label.c
bgpd/bgp_lcommunity.c
bgpd/bgp_mplsvpn.c
bgpd/bgp_mplsvpn.h
bgpd/bgp_nexthop.c
bgpd/bgp_open.h
bgpd/bgp_pbr.c
bgpd/bgp_pbr.h
bgpd/bgp_route.c
bgpd/bgp_routemap.c
bgpd/bgp_rpki.c
bgpd/bgp_table.c
bgpd/bgp_table.h
bgpd/bgp_vnc_types.h
bgpd/bgp_vty.c
bgpd/bgp_zebra.c
bgpd/bgpd.c
bgpd/bgpd.h
bgpd/rfapi/rfapi.c
bgpd/rfapi/rfapi_rib.c
bgpd/rfapi/vnc_export_bgp.c
bgpd/rfapi/vnc_import_bgp.c
configure.ac
doc/Makefile.am
doc/developer/maintainer-release-build.rst [new file with mode: 0644]
doc/developer/workflow.rst
doc/user/bgp.rst
doc/user/conf.py
doc/user/flowspec.rst [new file with mode: 0644]
doc/user/installation.rst
doc/user/rpki.rst
doc/user/zebra.rst
docker/alpine/Dockerfile-coverage [new file with mode: 0644]
eigrpd/eigrp_hello.c
eigrpd/eigrp_packet.c
ldpd/ldpd.h
ldpd/neighbor.c
ldpd/packet.c
ldpd/pfkey.c
ldpd/socket.c
ldpd/util.c
lib/hash.c
lib/hash.h
lib/if.c
lib/netns_linux.c
lib/nexthop_group.h
lib/srcdest_table.c
lib/srcdest_table.h
lib/vty.c
lib/workqueue.c
nhrpd/nhrp_event.c
nhrpd/nhrp_packet.c
nhrpd/vici.c
ospfd/ospf_ase.c
ospfd/ospf_flood.c
ospfd/ospf_lsa.c
ospfd/ospf_ri.c
ospfd/ospf_vty.c
pimd/mtracebis_netlink.c
pimd/pim_br.c
pimd/pim_cmd.c
pimd/pim_iface.c
pimd/pim_ifchannel.c
pimd/pim_igmp.c
pimd/pim_igmpv3.c
pimd/pim_instance.c
pimd/pim_jp_agg.c
pimd/pim_mroute.c
pimd/pim_msdp.c
pimd/pim_neighbor.c
pimd/pim_nht.c
pimd/pim_oil.c
pimd/pim_rp.c
pimd/pim_ssmpingd.c
pimd/pim_static.c
pimd/pim_tlv.c
pimd/pim_upstream.c
pimd/pim_zebra.c
redhat/frr.spec.in
ripngd/ripng_interface.c
ripngd/ripngd.c
tests/.gitignore
tests/Makefile.am
tests/bgpd/test_bgp_table.c [new file with mode: 0644]
tests/bgpd/test_bgp_table.py [new file with mode: 0644]
tests/lib/test_srcdest_table.c
zebra/connected.c
zebra/kernel_netlink.c
zebra/kernel_netlink.h
zebra/redistribute.c
zebra/redistribute.h
zebra/rib.h
zebra/rt.h
zebra/rt_netlink.c
zebra/rt_socket.c
zebra/rtadv.c
zebra/zapi_msg.c
zebra/zapi_msg.h
zebra/zebra_mpls.c
zebra/zebra_netns_notify.c
zebra/zebra_rib.c
zebra/zebra_routemap.c
zebra/zebra_routemap.h
zebra/zebra_static.c
zebra/zebra_static.h
zebra/zebra_vrf.c
zebra/zserv.c

index 5dc80b4983d57969e9f1f4d1042ed9dc1c406b25..ed22c60e7c748704a0a9bd4e4a4e30a2925e41d2 100644 (file)
@@ -115,3 +115,23 @@ noinst_HEADERS += defaults.h
 
 indent:
        tools/indent.py `find sharpd bgpd eigrpd include isisd lib nhrpd ospf6d ospfd pimd qpb ripd vtysh zebra -name '*.[ch]' | grep -v include/linux`
+
+if HAVE_GCOV
+
+coverage: check
+       @ find . -name '*.o' -exec gcov {} \;
+
+yorn:
+       @ echo "OK to upload coverage to https://coverage.io [y/N]:"
+       @ read yn; test "$$yn" = "y"
+
+upload-check-coverage:
+       @ if [ "x${COMMIT}" = "x" ]; then echo "COMMIT required"; exit 1; fi
+       @ if [ "x${TOKEN}" = "x" ]; then echo "TOKEN required"; exit 1; fi
+       curl -s https://codecov.io/bash | bash -s - -C ${COMMIT} -t ${TOKEN}
+
+force-check-coverage: coverage upload-check-coverage
+
+check-coverage: coverage yorn upload-check-coverage
+
+endif
index fff360ab96934d23b927c0f8b7cbf9529edd8fb0..0f063596867158c2efe5f609be6adf5633271806 100644 (file)
@@ -131,7 +131,6 @@ bgpd.h
   struct peer_group
   struct bgp_notify: (in-core representation of wire format?)
   struct bgp_nexthop: (v4 and v6 addresses, *ifp)
-  struct bgp_rd: router distinguisher: 8 octects
   struct bgp_filter: distribute, prefix, aslist, route_maps
   struct peer: neighbor structure (very rich/complex)
   struct bgp_nlri: reference to wire format
index 0ffbe174ed9d609579c4201684cc55cf53ada050..b2f34dd968b8851bfda67cc986fdcd4076732085 100644 (file)
@@ -274,8 +274,7 @@ static void community_list_entry_add(struct community_list *list,
 
 /* Delete community-list entry from the list.  */
 static void community_list_entry_delete(struct community_list *list,
-                                       struct community_entry *entry,
-                                       int style)
+                                       struct community_entry *entry)
 {
        if (entry->next)
                entry->next->prev = entry->prev;
@@ -882,7 +881,7 @@ int community_list_unset(struct community_list_handler *ch, const char *name,
        if (!entry)
                return COMMUNITY_LIST_ERR_CANT_FIND_LIST;
 
-       community_list_entry_delete(list, entry, style);
+       community_list_entry_delete(list, entry);
        route_map_notify_dependencies(name, RMAP_EVENT_CLIST_DELETED);
 
        return 0;
@@ -1040,7 +1039,7 @@ int lcommunity_list_unset(struct community_list_handler *ch, const char *name,
        if (!entry)
                return COMMUNITY_LIST_ERR_CANT_FIND_LIST;
 
-       community_list_entry_delete(list, entry, style);
+       community_list_entry_delete(list, entry);
 
        return 0;
 }
@@ -1057,8 +1056,6 @@ int extcommunity_list_set(struct community_list_handler *ch, const char *name,
        if (str == NULL)
                return COMMUNITY_LIST_ERR_MALFORMED_VAL;
 
-       entry = NULL;
-
        /* Get community list. */
        list = community_list_get(ch, name, EXTCOMMUNITY_LIST_MASTER);
 
@@ -1149,7 +1146,7 @@ int extcommunity_list_unset(struct community_list_handler *ch, const char *name,
        if (!entry)
                return COMMUNITY_LIST_ERR_CANT_FIND_LIST;
 
-       community_list_entry_delete(list, entry, style);
+       community_list_entry_delete(list, entry);
        route_map_notify_dependencies(name, RMAP_EVENT_ECLIST_DELETED);
 
        return 0;
index 8c5356c99804040af5bf71cd83fd65a73e512c76..2c372124d2935b51f2bdd5e926f278eec4ab51c0 100644 (file)
@@ -65,7 +65,6 @@ void ecommunity_free(struct ecommunity **ecom)
        if ((*ecom)->str)
                XFREE(MTYPE_ECOMMUNITY_STR, (*ecom)->str);
        XFREE(MTYPE_ECOMMUNITY, *ecom);
-       ecom = NULL;
 }
 
 static void ecommunity_hash_free(struct ecommunity *ecom)
index 959418658c9587ae8be1afcb8bcbd0ac9a1992ef..a026df59a06f717fb0cf05e630c1439d491f62e8 100644 (file)
@@ -4639,7 +4639,6 @@ int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr,
        int addpath_encoded;
        int psize = 0;
        uint8_t rtype;
-       uint8_t rlen;
        struct prefix p;
 
        /* Start processing the NLRI - there may be multiple in the MP_REACH */
@@ -4673,7 +4672,7 @@ int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr,
                        return -1;
 
                rtype = *pnt++;
-               psize = rlen = *pnt++;
+               psize = *pnt++;
 
                /* When packet overflow occur return immediately. */
                if (pnt + psize > lim)
@@ -5216,7 +5215,7 @@ int bgp_evpn_local_l3vni_add(vni_t l3vni, vrf_id_t vrf_id, struct ethaddr *rmac,
        struct bgpevpn *vpn = NULL;
        as_t as = 0;
 
-       /* get the default instamce - required to get the AS number for VRF
+       /* get the default instance - required to get the AS number for VRF
         * auto-creatio
         */
        bgp_def = bgp_get_default();
@@ -5319,11 +5318,12 @@ int bgp_evpn_local_l3vni_del(vni_t l3vni, vrf_id_t vrf_id)
                return -1;
        }
 
-       /* unimport remote routes from VRF, if it is AUTO vrf bgp_delete will
-        * take care of uninstalling the routes from zebra
+       /* Remove remote routes from BGT VRF even if BGP_VRF_AUTO is configured,
+        * bgp_delete would not remove/decrement bgp_info of the ip_prefix
+        * routes. This will uninstalling the routes from zebra and decremnt the
+        * bgp info count.
         */
-       if (!CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_AUTO))
-               uninstall_routes_for_vrf(bgp_vrf);
+       uninstall_routes_for_vrf(bgp_vrf);
 
        /* delete/withdraw all type-5 routes */
        delete_withdraw_vrf_routes(bgp_vrf);
index 9b998d4497f9031c81362ff3acdb98ffab103bf6..2d336fa6d8ceb0d9f16f3ce34c330270c2d56d38 100644 (file)
@@ -91,7 +91,6 @@ int bgp_nlri_parse_flowspec(struct peer *peer, struct attr *attr,
        afi_t afi;
        safi_t safi;
        int psize = 0;
-       uint8_t rlen;
        struct prefix p;
        int ret;
        void *temp;
@@ -121,7 +120,7 @@ int bgp_nlri_parse_flowspec(struct peer *peer, struct attr *attr,
                if (pnt + 1 > lim)
                        return -1;
 
-               psize = rlen = *pnt++;
+               psize = *pnt++;
 
                /* When packet overflow occur return immediately. */
                if (pnt + psize > lim) {
index 90acd8fcb16f48beb0f07ac2436dae0eacd5c4d2..c695e7f12509b22132eca3db7f94e32400ef2a55 100644 (file)
@@ -274,7 +274,7 @@ void route_vty_out_flowspec(struct vty *vty, struct prefix *p,
                        else
                                json_nlri_path = json_paths;
                }
-               if (display == NLRI_STRING_FORMAT_LARGE)
+               if (display == NLRI_STRING_FORMAT_LARGE && binfo)
                        vty_out(vty, "BGP flowspec entry: (flags 0x%x)\n",
                                binfo->flags);
                bgp_fs_nlri_get_string((unsigned char *)
index ceca644de2f3a2d5393747f4da22456aa043e082..8a051b7ff0c986e6e30ebb9faaed469076361e27 100644 (file)
@@ -57,7 +57,7 @@ int bgp_parse_fec_update(void)
        memset(&p, 0, sizeof(struct prefix));
        p.family = stream_getw(s);
        p.prefixlen = stream_getc(s);
-       stream_get(&p.u.prefix, s, PSIZE(p.prefixlen));
+       stream_get(p.u.val, s, PSIZE(p.prefixlen));
        label = stream_getl(s);
 
        /* hack for the bgp instance & SAFI = have to send/receive it */
index 33f4d139b8271027baecad6b7355a119f578024b..3e160bc56ed95b55d65dbe113400c810dcc04c61 100644 (file)
@@ -50,7 +50,6 @@ void lcommunity_free(struct lcommunity **lcom)
        if ((*lcom)->str)
                XFREE(MTYPE_LCOMMUNITY_STR, (*lcom)->str);
        XFREE(MTYPE_LCOMMUNITY, *lcom);
-       lcom = NULL;
 }
 
 static void lcommunity_hash_free(struct lcommunity *lcom)
index 3a854be534bf39ff17534db70e3213d91be5ae44..f72104dd33d6bda1c1b1abdb2a8be0f4fef1d17c 100644 (file)
@@ -220,7 +220,7 @@ int bgp_nlri_parse_vpn(struct peer *peer, struct attr *attr,
                p.prefixlen =
                        prefixlen
                        - VPN_PREFIXLEN_MIN_BYTES * 8; /* exclude label & RD */
-               memcpy(&p.u.prefix, pnt + VPN_PREFIXLEN_MIN_BYTES,
+               memcpy(p.u.val, pnt + VPN_PREFIXLEN_MIN_BYTES,
                       psize - VPN_PREFIXLEN_MIN_BYTES);
 
                if (attr) {
@@ -490,7 +490,7 @@ leak_update(
         * (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;
@@ -1356,8 +1356,7 @@ void vpn_leak_to_vrf_update_all(struct bgp *bgp_vrf, /* to */
        struct bgp_node *prn;
        safi_t safi = SAFI_MPLS_VPN;
 
-       if (!bgp_vpn)
-               return;
+       assert(bgp_vpn);
 
        /*
         * Walk vpn table
@@ -2253,3 +2252,66 @@ vrf_id_t get_first_vrf_for_redirect_with_rt(struct ecommunity *eckey)
        }
        return VRF_UNKNOWN;
 }
+
+/*
+ * The purpose of this function is to process leaks that were deferred
+ * from earlier per-vrf configuration due to not-yet-existing default
+ * vrf, in other words, configuration such as:
+ *
+ *     router bgp MMM vrf FOO
+ *       address-family ipv4 unicast
+ *         rd vpn export 1:1
+ *       exit-address-family
+ *
+ *     router bgp NNN
+ *       ...
+ *
+ * This function gets called when the default instance ("router bgp NNN")
+ * is created.
+ */
+void vpn_leak_postchange_all(void)
+{
+       struct listnode *next;
+       struct bgp *bgp;
+       struct bgp *bgp_default = bgp_get_default();
+
+       assert(bgp_default);
+
+       /* First, do any exporting from VRFs to the single VPN RIB */
+       for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, bgp)) {
+
+               if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
+                       continue;
+
+               vpn_leak_postchange(
+                       BGP_VPN_POLICY_DIR_TOVPN,
+                       AFI_IP,
+                       bgp_default,
+                       bgp);
+
+               vpn_leak_postchange(
+                       BGP_VPN_POLICY_DIR_TOVPN,
+                       AFI_IP6,
+                       bgp_default,
+                       bgp);
+       }
+
+       /* Now, do any importing to VRFs from the single VPN RIB */
+       for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, bgp)) {
+
+               if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
+                       continue;
+
+               vpn_leak_postchange(
+                       BGP_VPN_POLICY_DIR_FROMVPN,
+                       AFI_IP,
+                       bgp_default,
+                       bgp);
+
+               vpn_leak_postchange(
+                       BGP_VPN_POLICY_DIR_FROMVPN,
+                       AFI_IP6,
+                       bgp_default,
+                       bgp);
+       }
+}
index 384108dc0c475bc7af4ce81265705c146bfd3571..b0add40da9f94f0982ceaaa2785773ef09c9e98a 100644 (file)
@@ -182,6 +182,10 @@ static inline void vpn_leak_prechange(vpn_policy_direction_t direction,
                                      afi_t afi, struct bgp *bgp_vpn,
                                      struct bgp *bgp_vrf)
 {
+       /* Detect when default bgp instance is not (yet) defined by config */
+       if (!bgp_vpn)
+               return;
+
        if ((direction == BGP_VPN_POLICY_DIR_FROMVPN) &&
                vpn_leak_from_vpn_active(bgp_vrf, afi, NULL)) {
 
@@ -198,6 +202,10 @@ static inline void vpn_leak_postchange(vpn_policy_direction_t direction,
                                       afi_t afi, struct bgp *bgp_vpn,
                                       struct bgp *bgp_vrf)
 {
+       /* Detect when default bgp instance is not (yet) defined by config */
+       if (!bgp_vpn)
+               return;
+
        if (direction == BGP_VPN_POLICY_DIR_FROMVPN)
                vpn_leak_to_vrf_update_all(bgp_vrf, bgp_vpn, afi);
        if (direction == BGP_VPN_POLICY_DIR_TOVPN) {
@@ -216,4 +224,6 @@ extern void vpn_policy_routemap_event(const char *rmap_name);
 
 extern vrf_id_t get_first_vrf_for_redirect_with_rt(struct ecommunity *eckey);
 
+extern void vpn_leak_postchange_all(void);
+
 #endif /* _QUAGGA_BGP_MPLSVPN_H */
index 32011d210ba29f02e3806e7ec9ddd3c5e3da7f9a..76bfa73feeb143f559e25f4eac79aff61c3be40a 100644 (file)
@@ -447,8 +447,6 @@ int bgp_subgrp_multiaccess_check_v4(struct in_addr nexthop,
        p.family = AF_INET;
        p.prefixlen = IPV4_MAX_BITLEN;
 
-       rn2 = NULL;
-
        bgp = SUBGRP_INST(subgrp);
        rn1 = bgp_node_match(bgp->connected_table[AFI_IP], &np);
        if (!rn1)
index c92fd9b0a72737953fd0ba10d8162dc5a7ee2aa6..42ebe97f2e64b780954f8ce86f9e4bc43035f596 100644 (file)
@@ -34,21 +34,12 @@ struct capability_mp_data {
        uint8_t safi; /* iana_safi_t */
 };
 
-struct capability_as4 {
-       uint32_t as4;
-};
-
 struct graceful_restart_af {
        afi_t afi;
        safi_t safi;
        uint8_t flag;
 };
 
-struct capability_gr {
-       uint16_t restart_flag_time;
-       struct graceful_restart_af gr[];
-};
-
 /* Capability Code */
 #define CAPABILITY_CODE_MP              1 /* Multiprotocol Extensions */
 #define CAPABILITY_CODE_REFRESH         2 /* Route Refresh Capability */
index 45ec21631c0f2fcb6113ed1f273b52b4d4b614ef..b5ddfd4b2112a9eadc9da3937e8f6271469bcd9d 100644 (file)
@@ -348,7 +348,7 @@ static bool bgp_pbr_extract_enumerate(struct bgp_pbr_match_val list[],
                                      void *valmask, uint8_t type_entry)
 {
        bool ret;
-       uint8_t unary_operator_val = unary_operator;
+       uint8_t unary_operator_val;
        bool double_check = false;
 
        if ((unary_operator & OPERATOR_UNARY_OR) &&
index 307a34e34f4c02749f49604601b0cc90b9151532..e853784afda6974a27601af4da266318f60c4df2 100644 (file)
@@ -57,17 +57,13 @@ struct bgp_pbr_match_val {
        uint16_t value;
        uint8_t compare_operator;
        uint8_t unary_operator;
-} bgp_pbr_value_t;
+};
 
 #define FRAGMENT_DONT  1
 #define FRAGMENT_IS    2
 #define FRAGMENT_FIRST 4
 #define FRAGMENT_LAST  8
 
-struct bgp_pbr_fragment_val {
-       uint8_t bitmask;
-};
-
 struct bgp_pbr_entry_action {
        /* used to store enum bgp_pbr_action_enum enumerate */
        uint8_t action;
index 7057b62f2b00a47271b8eaa19d28602ae7599392..795bd15613a0c41376c2b291f5903d33f2948331 100644 (file)
@@ -2168,7 +2168,6 @@ struct bgp_process_queue {
 static void bgp_process_main_one(struct bgp *bgp, struct bgp_node *rn,
                                 afi_t afi, safi_t safi)
 {
-       struct prefix *p = &rn->p;
        struct bgp_info *new_select;
        struct bgp_info *old_select;
        struct bgp_info_pair old_and_new;
@@ -2191,6 +2190,8 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_node *rn,
                return;
        }
 
+       struct prefix *p = &rn->p;
+
        debug = bgp_debug_bestpath(&rn->p);
        if (debug) {
                prefix2str(&rn->p, pfx_buf, sizeof(pfx_buf));
@@ -2672,14 +2673,12 @@ static void bgp_rib_withdraw(struct bgp_node *rn, struct bgp_info *ri,
                             struct peer *peer, afi_t afi, safi_t safi,
                             struct prefix_rd *prd)
 {
-       int status = BGP_DAMP_NONE;
-
        /* apply dampening, if result is suppressed, we'll be retaining
         * the bgp_info in the RIB for historical reference.
         */
        if (CHECK_FLAG(peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
            && peer->sort == BGP_PEER_EBGP)
-               if ((status = bgp_damp_withdraw(ri, rn, afi, safi, 0))
+               if ((bgp_damp_withdraw(ri, rn, afi, safi, 0))
                    == BGP_DAMP_SUPPRESSED) {
                        bgp_aggregate_decrement(peer->bgp, &rn->p, ri, afi,
                                                safi);
@@ -4237,7 +4236,7 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
                }
 
                /* Fetch prefix from NLRI packet. */
-               memcpy(&p.u.prefix, pnt, psize);
+               memcpy(p.u.val, pnt, psize);
 
                /* Check address. */
                if (afi == AFI_IP && safi == SAFI_UNICAST) {
index f7c79f873df0b84d35cf7d4e3f2180b84981798c..f9f5142cd08260763a85793dee15788474928518 100644 (file)
@@ -1298,6 +1298,9 @@ static route_map_result_t route_set_ip_nexthop(void *rule,
                        bgp_info->attr->nexthop = *rins->address;
                        SET_FLAG(bgp_info->attr->rmap_change_flags,
                                 BATTR_RMAP_IPV4_NHOP_CHANGED);
+                       /* case for MP-BGP : MPLS VPN */
+                       bgp_info->attr->mp_nexthop_global_in = *rins->address;
+                       bgp_info->attr->mp_nexthop_len = sizeof(*rins->address);
                }
        }
 
index 82e857dbf4e426560fd6cde0919fd619e7e47efe..774c4847843d6ccb4e49849b713665f57381de6f 100644 (file)
@@ -5,8 +5,8 @@
  * Berlin
  * Copyright (C) 2016-2017 Colin Sames (colin.sames@haw-hamburg.de), for HAW
  * Hamburg
- * Copyright (C) 2017 Marcel Röthke (marcel.roethke@haw-hamburg.de), for HAW
- * Hamburg
+ * Copyright (C) 2017-2018 Marcel Röthke (marcel.roethke@haw-hamburg.de),
+ * for HAW Hamburg
  *
  * This file is part of FRRouting.
  *
@@ -47,6 +47,7 @@
 #include "bgpd/bgp_attr.h"
 #include "bgpd/bgp_aspath.h"
 #include "bgpd/bgp_route.h"
+#include "lib/thread.h"
 #include "rtrlib/rtrlib.h"
 #include "rtrlib/rtr_mgr.h"
 #include "rtrlib/lib/ip.h"
@@ -128,16 +129,22 @@ static void route_match_free(void *rule);
 static route_map_result_t route_match(void *rule, struct prefix *prefix,
                                      route_map_object_t type, void *object);
 static void *route_match_compile(const char *arg);
+static void revalidate_bgp_node(struct bgp_node *bgp_node, afi_t afi,
+                               safi_t safi);
 
 static struct rtr_mgr_config *rtr_config;
 static struct list *cache_list;
 static int rtr_is_running;
+static int rtr_is_stopping;
+static int rtr_is_starting;
 static int rpki_debug;
 static unsigned int polling_period;
 static unsigned int expire_interval;
 static unsigned int retry_interval;
 static unsigned int timeout;
 static unsigned int initial_synchronisation_timeout;
+static int rpki_sync_socket_rtr;
+static int rpki_sync_socket_bgpd;
 
 static struct cmd_node rpki_node = {RPKI_NODE, "%s(config-rpki)# ", 1};
 static struct route_map_rule_cmd route_match_rpki_cmd = {
@@ -185,6 +192,22 @@ static void free_tr_socket(struct cache *cache)
 static int rpki_validate_prefix(struct peer *peer, struct attr *attr,
                                struct prefix *prefix);
 
+static void ipv6_addr_to_network_byte_order(const uint32_t *src, uint32_t *dest)
+{
+       int i;
+
+       for (i = 0; i < 4; i++)
+               dest[i] = htonl(src[i]);
+}
+
+static void ipv6_addr_to_host_byte_order(const uint32_t *src, uint32_t *dest)
+{
+       int i;
+
+       for (i = 0; i < 4; i++)
+               dest[i] = ntohl(src[i]);
+}
+
 static route_map_result_t route_match(void *rule, struct prefix *prefix,
                                      route_map_object_t type, void *object)
 {
@@ -295,10 +318,159 @@ inline int is_running(void)
        return rtr_is_running;
 }
 
+static struct prefix *pfx_record_to_prefix(struct pfx_record *record)
+{
+       struct prefix *prefix = prefix_new();
+
+       prefix->prefixlen = record->min_len;
+
+       if (record->prefix.ver == LRTR_IPV4) {
+               prefix->family = AF_INET;
+               prefix->u.prefix4.s_addr = htonl(record->prefix.u.addr4.addr);
+       } else {
+               prefix->family = AF_INET6;
+               ipv6_addr_to_network_byte_order(record->prefix.u.addr6.addr,
+                                               prefix->u.prefix6.s6_addr32);
+       }
+
+       return prefix;
+}
+
+static int bgpd_sync_callback(struct thread *thread)
+{
+       struct bgp *bgp;
+       struct listnode *node;
+       struct prefix *prefix;
+       struct pfx_record rec;
+
+       thread_add_read(bm->master, bgpd_sync_callback, NULL,
+                       rpki_sync_socket_bgpd, NULL);
+       int retval =
+               read(rpki_sync_socket_bgpd, &rec, sizeof(struct pfx_record));
+       if (retval != sizeof(struct pfx_record)) {
+               RPKI_DEBUG("Could not read from rpki_sync_socket_bgpd");
+               return retval;
+       }
+       prefix = pfx_record_to_prefix(&rec);
+
+       afi_t afi = (rec.prefix.ver == LRTR_IPV4) ? AFI_IP : AFI_IP6;
+
+       for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp)) {
+               safi_t safi;
+
+               for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
+                       if (!bgp->rib[afi][safi])
+                               continue;
+
+                       struct list *matches = list_new();
+
+                       matches->del = (void (*)(void *))bgp_unlock_node;
+
+                       bgp_table_range_lookup(bgp->rib[afi][safi], prefix,
+                                              rec.max_len, matches);
+
+
+                       struct bgp_node *bgp_node;
+
+                       for (ALL_LIST_ELEMENTS_RO(matches, node, bgp_node))
+                               revalidate_bgp_node(bgp_node, afi, safi);
+
+                       list_delete_and_null(&matches);
+               }
+       }
+
+       prefix_free(prefix);
+       return 0;
+}
+
+static void revalidate_bgp_node(struct bgp_node *bgp_node, afi_t afi,
+                               safi_t safi)
+{
+       struct bgp_adj_in *ain;
+
+       for (ain = bgp_node->adj_in; ain; ain = ain->next) {
+               int ret;
+               struct bgp_info *bgp_info = bgp_node->info;
+               mpls_label_t *label = NULL;
+               uint32_t num_labels = 0;
+
+               if (bgp_info && bgp_info->extra) {
+                       label = bgp_info->extra->label;
+                       num_labels = bgp_info->extra->num_labels;
+               }
+               ret = bgp_update(ain->peer, &bgp_node->p, 0, ain->attr, afi,
+                                safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL,
+                                label, num_labels, 1, NULL);
+
+               if (ret < 0) {
+                       bgp_unlock_node(bgp_node);
+                       return;
+               }
+       }
+}
+
+static void revalidate_all_routes(void)
+{
+       struct bgp *bgp;
+       struct listnode *node;
+       struct bgp_node *bgp_node;
+
+       for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp)) {
+               for (size_t i = 0; i < 2; i++) {
+                       safi_t safi;
+                       afi_t afi = (i == 0) ? AFI_IP : AFI_IP6;
+
+                       for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
+                               if (!bgp->rib[afi][safi])
+                                       continue;
+
+                               for (bgp_node =
+                                            bgp_table_top(bgp->rib[afi][safi]);
+                                    bgp_node;
+                                    bgp_node = bgp_route_next(bgp_node)) {
+                                       if (bgp_node->info != NULL) {
+                                               revalidate_bgp_node(bgp_node,
+                                                                   afi, safi);
+                                       }
+                               }
+                       }
+               }
+       }
+}
+
+static void rpki_update_cb_sync_rtr(struct pfx_table *p __attribute__((unused)),
+                                   const struct pfx_record rec,
+                                   const bool added __attribute__((unused)))
+{
+       if (rtr_is_stopping || rtr_is_starting)
+               return;
+
+       int retval =
+               write(rpki_sync_socket_rtr, &rec, sizeof(struct pfx_record));
+       if (retval != sizeof(struct pfx_record))
+               RPKI_DEBUG("Could not write to rpki_sync_socket_rtr");
+}
+
+static void rpki_init_sync_socket(void)
+{
+       int fds[2];
+
+       RPKI_DEBUG("initializing sync socket");
+       if (socketpair(PF_LOCAL, SOCK_DGRAM, 0, fds) != 0) {
+               RPKI_DEBUG("Could not open rpki sync socket");
+               return;
+       }
+       rpki_sync_socket_rtr = fds[0];
+       rpki_sync_socket_bgpd = fds[1];
+       thread_add_read(bm->master, bgpd_sync_callback, NULL,
+                       rpki_sync_socket_bgpd, NULL);
+}
+
 static int bgp_rpki_init(struct thread_master *master)
 {
        rpki_debug = 0;
        rtr_is_running = 0;
+       rtr_is_stopping = 0;
 
        cache_list = list_new();
        cache_list->del = (void (*)(void *)) & free_cache;
@@ -310,6 +482,7 @@ static int bgp_rpki_init(struct thread_master *master)
        initial_synchronisation_timeout =
                INITIAL_SYNCHRONISATION_TIMEOUT_DEFAULT;
        install_cli_commands();
+       rpki_init_sync_socket();
        return 0;
 }
 
@@ -318,6 +491,9 @@ static int bgp_rpki_fini(void)
        stop();
        list_delete_and_null(&cache_list);
 
+       close(rpki_sync_socket_rtr);
+       close(rpki_sync_socket_bgpd);
+
        return 0;
 }
 
@@ -336,6 +512,9 @@ static int start(void)
        unsigned int waiting_time = 0;
        int ret;
 
+       rtr_is_stopping = 0;
+       rtr_is_starting = 1;
+
        if (list_isempty(cache_list)) {
                RPKI_DEBUG(
                        "No caches were found in config. Prefix validation is off.");
@@ -345,9 +524,10 @@ static int start(void)
        int groups_len = listcount(cache_list);
        struct rtr_mgr_group *groups = get_groups();
 
+       RPKI_DEBUG("Polling period: %d", polling_period);
        ret = rtr_mgr_init(&rtr_config, groups, groups_len, polling_period,
-                          expire_interval, retry_interval, NULL, NULL, NULL,
-                          NULL);
+                          expire_interval, retry_interval,
+                          rpki_update_cb_sync_rtr, NULL, NULL, NULL);
        if (ret == RTR_ERROR) {
                RPKI_DEBUG("Init rtr_mgr failed.");
                return ERROR;
@@ -370,9 +550,13 @@ static int start(void)
        }
        if (rtr_mgr_conf_in_sync(rtr_config)) {
                RPKI_DEBUG("Got synchronisation with at least one RPKI cache!");
+               RPKI_DEBUG("Forcing revalidation.");
+               rtr_is_starting = 0;
+               revalidate_all_routes();
        } else {
                RPKI_DEBUG(
                        "Timeout expired! Proceeding without RPKI validation data.");
+               rtr_is_starting = 0;
        }
 
        XFREE(MTYPE_BGP_RPKI_CACHE_GROUP, groups);
@@ -382,6 +566,7 @@ static int start(void)
 
 static void stop(void)
 {
+       rtr_is_stopping = 1;
        if (rtr_is_running) {
                rtr_mgr_stop(rtr_config);
                rtr_mgr_free(rtr_config);
@@ -479,13 +664,11 @@ static int rpki_validate_prefix(struct peer *peer, struct attr *attr,
                ip_addr_prefix.u.addr4.addr = ntohl(prefix->u.prefix4.s_addr);
                break;
 
-#ifdef HAVE_IPV6
        case AF_INET6:
                ip_addr_prefix.ver = LRTR_IPV6;
                ipv6_addr_to_host_byte_order(prefix->u.prefix6.s6_addr32,
                                             ip_addr_prefix.u.addr6.addr);
                break;
-#endif /* HAVE_IPV6 */
 
        default:
                return 0;
@@ -858,7 +1041,7 @@ DEFPY (rpki_cache,
        "Preference of the cache server\n"
        "Preference value\n")
 {
-       int return_value = SUCCESS;
+       int return_value;
 
        // use ssh connection
        if (ssh_uname) {
@@ -867,6 +1050,7 @@ DEFPY (rpki_cache,
                        add_ssh_cache(cache, sshport, ssh_uname, ssh_privkey,
                                      ssh_pubkey, server_pubkey, preference);
 #else
+               return_value = SUCCESS;
                vty_out(vty,
                        "ssh sockets are not supported. "
                        "Please recompile rtrlib and frr with ssh support. "
index 613b924d0d7ace099115d19cb4672a6496cd98c9..94e2d83cfe1ff287f99fbb6430c0a3a1e72f66c3 100644 (file)
@@ -114,3 +114,65 @@ struct bgp_table *bgp_table_init(struct bgp *bgp, afi_t afi, safi_t safi)
 
        return rt;
 }
+
+static struct bgp_node *
+bgp_route_next_until_maxlen(struct bgp_node *node, const struct bgp_node *limit,
+                           const uint8_t maxlen)
+{
+       if (node->l_left && node->p.prefixlen < maxlen
+           && node->l_left->p.prefixlen <= maxlen) {
+               return bgp_node_from_rnode(node->l_left);
+       }
+       if (node->l_right && node->p.prefixlen < maxlen
+           && node->l_right->p.prefixlen <= maxlen) {
+               return bgp_node_from_rnode(node->l_right);
+       }
+
+       while (node->parent && node != limit) {
+               if (bgp_node_from_rnode(node->parent->l_left) == node
+                   && node->parent->l_right) {
+                       return bgp_node_from_rnode(node->parent->l_right);
+               }
+               node = bgp_node_from_rnode(node->parent);
+       }
+       return NULL;
+}
+
+void bgp_table_range_lookup(const struct bgp_table *table, struct prefix *p,
+                           uint8_t maxlen, struct list *matches)
+{
+       struct bgp_node *node = bgp_node_from_rnode(table->route_table->top);
+       struct bgp_node *matched = NULL;
+
+       if (node == NULL)
+               return;
+
+       while (node && node->p.prefixlen <= p->prefixlen
+              && prefix_match(&node->p, p)) {
+               if (node->info && node->p.prefixlen == p->prefixlen) {
+                       matched = node;
+                       break;
+               }
+               node = bgp_node_from_rnode(node->link[prefix_bit(
+                       &p->u.prefix, node->p.prefixlen)]);
+       }
+
+       if ((matched == NULL && node->p.prefixlen > maxlen) || !node->parent)
+               return;
+       else if (matched == NULL)
+               matched = node = bgp_node_from_rnode(node->parent);
+
+       if (matched->info) {
+               bgp_lock_node(matched);
+               listnode_add(matches, matched);
+       }
+
+       while ((node = bgp_route_next_until_maxlen(node, matched, maxlen))) {
+               if (prefix_match(p, &node->p)) {
+                       if (node->info) {
+                               bgp_lock_node(node);
+                               listnode_add(matches, node);
+                       }
+               }
+       }
+}
index 388c2472270572ded9e058ff8c50815f29915611..60c2cbd4a483c3e646595ebc4434b2f16badd6ff 100644 (file)
@@ -24,6 +24,7 @@
 #include "mpls.h"
 #include "table.h"
 #include "queue.h"
+#include "linklist.h"
 
 struct bgp_table {
        /* table belongs to this instance */
@@ -309,4 +310,7 @@ static inline uint64_t bgp_table_version(struct bgp_table *table)
        return table->version;
 }
 
+void bgp_table_range_lookup(const struct bgp_table *table, struct prefix *p,
+                           uint8_t maxlen, struct list *matches);
+
 #endif /* _QUAGGA_BGP_TABLE_H */
index 70f5646e9473ffe0eade5763bbd91f18223459e0..f4202ff75e9f1728c69a6f354031d8e182d50128 100644 (file)
@@ -25,16 +25,5 @@ typedef enum {
        BGP_VNC_SUBTLV_TYPE_RFPOPTION = 2, /* deprecated */
 } bgp_vnc_subtlv_types;
 
-/*
- * VNC Attribute subtlvs
- */
-struct bgp_vnc_subtlv_lifetime {
-       uint32_t lifetime;
-};
-
-struct bgp_vnc_subtlv_unaddr {
-       struct prefix un_address; /* IPv4 or IPv6; pfx length ignored */
-};
-
 #endif /* ENABLE_BGP_VNC */
 #endif /* _QUAGGA_BGP_VNC_TYPES_H */
index 86f3f97c4934f7eb04197e50eea2c9d6baa2c5a8..e9d9a846af810490248a7494ac75ec2a48400b74 100644 (file)
@@ -928,6 +928,14 @@ DEFUN_NOSH (router_bgp,
                        return CMD_WARNING_CONFIG_FAILED;
                }
 
+               /*
+                * If we just instantiated the default instance, complete
+                * any pending VRF-VPN leaking that was configured via
+                * earlier "router bgp X vrf FOO" blocks.
+                */
+               if (inst_type == BGP_INSTANCE_TYPE_DEFAULT)
+                       vpn_leak_postchange_all();
+
                /* Pending: handle when user tries to change a view to vrf n vv.
                 */
        }
@@ -3372,8 +3380,6 @@ DEFUN (neighbor_set_peer_group,
        struct peer *peer;
        struct peer_group *group;
 
-       peer = NULL;
-
        ret = str2sockunion(argv[idx_peer]->arg, &su);
        if (ret < 0) {
                peer = peer_lookup_by_conf_if(bgp, argv[idx_peer]->arg);
index df3f9ddd6fd51c2b207b2b177ea79e01a9406406..714f6791c14c2bed7ee435395817b42ef73900d5 100644 (file)
@@ -1190,7 +1190,7 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
        mpls_label_t label;
        int nh_othervrf = 0;
        char buf_prefix[PREFIX_STRLEN]; /* filled in if we are debugging */
-       bool is_evpn = false;
+       bool is_evpn;
        int nh_updated;
 
        /* Don't try to install if we're not connected to Zebra or Zebra doesn't
index 283949ab2a709bf60a3ad5449db3e82e17f73d2c..e5b269eb70c27e1f5968aaff4b88df558f8b0129 100644 (file)
@@ -888,129 +888,6 @@ static bool peergroup_filter_check(struct peer *peer, afi_t afi, safi_t safi,
        }
 }
 
-/* Reset all address family specific configuration.  */
-static void peer_af_flag_reset(struct peer *peer, afi_t afi, safi_t safi)
-{
-       int i;
-       struct bgp_filter *filter;
-       char orf_name[BUFSIZ];
-
-       filter = &peer->filter[afi][safi];
-
-       /* Clear neighbor filter and route-map */
-       for (i = FILTER_IN; i < FILTER_MAX; i++) {
-               if (filter->dlist[i].name) {
-                       XFREE(MTYPE_BGP_FILTER_NAME, filter->dlist[i].name);
-                       filter->dlist[i].name = NULL;
-               }
-               if (filter->plist[i].name) {
-                       XFREE(MTYPE_BGP_FILTER_NAME, filter->plist[i].name);
-                       filter->plist[i].name = NULL;
-               }
-               if (filter->aslist[i].name) {
-                       XFREE(MTYPE_BGP_FILTER_NAME, filter->aslist[i].name);
-                       filter->aslist[i].name = NULL;
-               }
-       }
-       for (i = RMAP_IN; i < RMAP_MAX; i++) {
-               if (filter->map[i].name) {
-                       XFREE(MTYPE_BGP_FILTER_NAME, filter->map[i].name);
-                       filter->map[i].name = NULL;
-               }
-       }
-
-       /* Clear unsuppress map.  */
-       if (filter->usmap.name)
-               XFREE(MTYPE_BGP_FILTER_NAME, filter->usmap.name);
-       filter->usmap.name = NULL;
-       filter->usmap.map = NULL;
-
-       /* Clear neighbor's all address family flags.  */
-       peer->af_flags[afi][safi] = 0;
-
-       /* Clear neighbor's all address family sflags. */
-       peer->af_sflags[afi][safi] = 0;
-
-       /* Clear neighbor's all address family capabilities. */
-       peer->af_cap[afi][safi] = 0;
-
-       /* Clear ORF info */
-       peer->orf_plist[afi][safi] = NULL;
-       sprintf(orf_name, "%s.%d.%d", peer->host, afi, safi);
-       prefix_bgp_orf_remove_all(afi, orf_name);
-
-       /* Set default neighbor send-community.  */
-       if (!bgp_option_check(BGP_OPT_CONFIG_CISCO)) {
-               SET_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY);
-               SET_FLAG(peer->af_flags[afi][safi],
-                        PEER_FLAG_SEND_EXT_COMMUNITY);
-               SET_FLAG(peer->af_flags[afi][safi],
-                        PEER_FLAG_SEND_LARGE_COMMUNITY);
-
-               SET_FLAG(peer->af_flags_invert[afi][safi],
-                        PEER_FLAG_SEND_COMMUNITY);
-               SET_FLAG(peer->af_flags_invert[afi][safi],
-                        PEER_FLAG_SEND_EXT_COMMUNITY);
-               SET_FLAG(peer->af_flags_invert[afi][safi],
-                        PEER_FLAG_SEND_LARGE_COMMUNITY);
-       }
-
-       /* Clear neighbor default_originate_rmap */
-       if (peer->default_rmap[afi][safi].name)
-               XFREE(MTYPE_ROUTE_MAP_NAME, peer->default_rmap[afi][safi].name);
-       peer->default_rmap[afi][safi].name = NULL;
-       peer->default_rmap[afi][safi].map = NULL;
-
-       /* Clear neighbor maximum-prefix */
-       peer->pmax[afi][safi] = 0;
-       peer->pmax_threshold[afi][safi] = MAXIMUM_PREFIX_THRESHOLD_DEFAULT;
-}
-
-/* peer global config reset */
-static void peer_global_config_reset(struct peer *peer)
-{
-       int saved_flags = 0;
-
-       peer->change_local_as = 0;
-       peer->ttl = (peer_sort(peer) == BGP_PEER_IBGP ? MAXTTL : 1);
-       if (peer->update_source) {
-               sockunion_free(peer->update_source);
-               peer->update_source = NULL;
-       }
-       if (peer->update_if) {
-               XFREE(MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
-               peer->update_if = NULL;
-       }
-
-       if (peer_sort(peer) == BGP_PEER_IBGP)
-               peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
-       else
-               peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
-
-       /* These are per-peer specific flags and so we must preserve them */
-       saved_flags |= CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY);
-       saved_flags |= CHECK_FLAG(peer->flags, PEER_FLAG_SHUTDOWN);
-       peer->flags = 0;
-       SET_FLAG(peer->flags, saved_flags);
-
-       peer->holdtime = 0;
-       peer->keepalive = 0;
-       peer->connect = 0;
-       peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;
-
-       /* Reset some other configs back to defaults. */
-       peer->v_start = BGP_INIT_START_TIMER;
-       peer->password = NULL;
-       peer->local_id = peer->bgp->router_id;
-       peer->v_holdtime = peer->bgp->default_holdtime;
-       peer->v_keepalive = peer->bgp->default_keepalive;
-
-       bfd_info_free(&(peer->bfd_info));
-
-       /* Set back the CONFIG_NODE flag. */
-       SET_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE);
-}
-
 /* Check peer's AS number and determines if this peer is IBGP or EBGP */
 static inline bgp_peer_sort_t peer_calc_sort(struct peer *peer)
 {
@@ -1026,9 +903,11 @@ static inline bgp_peer_sort_t peer_calc_sort(struct peer *peer)
                else if (peer->as_type == AS_EXTERNAL)
                        return BGP_PEER_EBGP;
 
-               else if (peer->as_type == AS_SPECIFIED && peer->as)
+               else if (peer->as_type == AS_SPECIFIED && peer->as) {
+                       assert(bgp);
                        return (bgp->as == peer->as ? BGP_PEER_IBGP
                                                    : BGP_PEER_EBGP);
+               }
 
                else {
                        struct peer *peer1;
@@ -2819,61 +2698,6 @@ int peer_group_bind(struct bgp *bgp, union sockunion *su, struct peer *peer,
        return 0;
 }
 
-int peer_group_unbind(struct bgp *bgp, struct peer *peer,
-                     struct peer_group *group)
-{
-       struct peer *other;
-       afi_t afi;
-       safi_t safi;
-
-       if (group != peer->group)
-               return BGP_ERR_PEER_GROUP_MISMATCH;
-
-       FOREACH_AFI_SAFI (afi, safi) {
-               if (peer->afc[afi][safi]) {
-                       peer->afc[afi][safi] = 0;
-                       peer_af_flag_reset(peer, afi, safi);
-
-                       if (peer_af_delete(peer, afi, safi) != 0) {
-                               zlog_err(
-                                       "couldn't delete af structure for peer %s",
-                                       peer->host);
-                       }
-               }
-       }
-
-       assert(listnode_lookup(group->peer, peer));
-       peer_unlock(peer); /* peer group list reference */
-       listnode_delete(group->peer, peer);
-       peer->group = NULL;
-       other = peer->doppelganger;
-
-       if (group->conf->as) {
-               peer_delete(peer);
-               if (other && other->status != Deleted) {
-                       if (other->group) {
-                               peer_unlock(other);
-                               listnode_delete(group->peer, other);
-                       }
-                       other->group = NULL;
-                       peer_delete(other);
-               }
-               return 0;
-       }
-
-       bgp_bfd_deregister_peer(peer);
-       peer_global_config_reset(peer);
-
-       if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
-               peer->last_reset = PEER_DOWN_RMAP_UNBIND;
-               bgp_notify_send(peer, BGP_NOTIFY_CEASE,
-                               BGP_NOTIFY_CEASE_CONFIG_CHANGE);
-       } else
-               bgp_session_reset(peer);
-
-       return 0;
-}
-
 static int bgp_startup_timer_expire(struct thread *thread)
 {
        struct bgp *bgp;
@@ -3823,9 +3647,6 @@ struct peer_flag_action {
 
        /* Action when the flag is changed.  */
        enum peer_change_type type;
-
-       /* Peer down cause */
-       uint8_t peer_down;
 };
 
 static const struct peer_flag_action peer_flag_action_list[] = {
@@ -7647,10 +7468,6 @@ int bgp_config_write(struct vty *vty)
                        vty_out(vty, " bgp default subgroup-pkt-queue-max %u\n",
                                bgp->default_subgroup_pkt_queue_max);
 
-               /* BGP default autoshutdown neighbors */
-               if (bgp->autoshutdown)
-                       vty_out(vty, " bgp default shutdown\n");
-
                /* BGP client-to-client reflection. */
                if (bgp_flag_check(bgp, BGP_FLAG_NO_CLIENT_TO_CLIENT))
                        vty_out(vty, " no bgp client-to-client reflection\n");
@@ -7804,6 +7621,16 @@ int bgp_config_write(struct vty *vty)
                /* listen range and limit for dynamic BGP neighbors */
                bgp_config_write_listen(vty, bgp);
 
+               /*
+                * BGP default autoshutdown neighbors
+                *
+                * This must be placed after any peer and peer-group
+                * configuration, to avoid setting all peers to shutdown after
+                * a daemon restart, which is undesired behavior. (see #2286)
+                */
+               if (bgp->autoshutdown)
+                       vty_out(vty, " bgp default shutdown\n");
+
                /* No auto-summary */
                if (bgp_option_check(BGP_OPT_CONFIG_CISCO))
                        vty_out(vty, " no auto-summary\n");
@@ -7912,8 +7739,6 @@ static void bgp_if_finish(struct bgp *bgp)
        }
 }
 
-extern void bgp_snmp_init(void);
-
 static void bgp_viewvrf_autocomplete(vector comps, struct cmd_token *token)
 {
        struct vrf *vrf = NULL;
index 1fbc0a0db9fe0e8c04ad5b5dac5e0a09c7decc3f..06eb86da95559f7c679b930405aef52d1a8b3106 100644 (file)
@@ -590,13 +590,7 @@ struct bgp_nexthop {
 
 #define BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE 1
 
-/* BGP router distinguisher value.  */
-#define BGP_RD_SIZE                8
-
-struct bgp_rd {
-       uint8_t val[BGP_RD_SIZE];
-};
-
+/* Route map direction */
 #define RMAP_IN  0
 #define RMAP_OUT 1
 #define RMAP_MAX 2
@@ -1590,7 +1584,6 @@ extern int peer_afc_set(struct peer *, afi_t, safi_t, int);
 
 extern int peer_group_bind(struct bgp *, union sockunion *, struct peer *,
                           struct peer_group *, as_t *);
-extern int peer_group_unbind(struct bgp *, struct peer *, struct peer_group *);
 
 extern int peer_flag_set(struct peer *, uint32_t);
 extern int peer_flag_unset(struct peer *, uint32_t);
index 177244d2778bb882b6bd84f1592c2484795fb724..a1f1169a7abf751924d06703fde838a4b95ef94f 100644 (file)
@@ -2336,7 +2336,7 @@ int rfapi_reopen(struct rfapi_descriptor *rfd, struct bgp *bgp)
 
                h = bgp->rfapi;
 
-               assert(!CHECK_FLAG(h->flags, RFAPI_INCALLBACK));
+               assert(h != NULL && !CHECK_FLAG(h->flags, RFAPI_INCALLBACK));
 
                if (CHECK_FLAG(rfd->flags,
                               RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY)
@@ -3197,8 +3197,8 @@ DEFUN (debug_rfapi_register_vn_un_l2o,
        memset(optary, 0, sizeof(optary));
        optary[opt_next].v.l2addr.logical_net_id =
                strtoul(argv[14]->arg, NULL, 10);
-       if ((rc = rfapiStr2EthAddr(argv[12]->arg,
-                                  &optary[opt_next].v.l2addr.macaddr))) {
+       if (rfapiStr2EthAddr(argv[12]->arg,
+                            &optary[opt_next].v.l2addr.macaddr)) {
                vty_out(vty, "Bad mac address \"%s\"\n", argv[12]->arg);
                return CMD_WARNING_CONFIG_FAILED;
        }
index c71f59563fa830d8a1911921f18d9784f60b57e5..60534fece0b9d43e843092f27ea3030df74ed173 100644 (file)
@@ -2099,7 +2099,6 @@ rfapiRibPreload(struct bgp *bgp, struct rfapi_descriptor *rfd,
                        nhp->vn_options = NULL;
 
                        XFREE(MTYPE_RFAPI_NEXTHOP, nhp);
-                       nhp = NULL;
                }
        }
 
index ae31c3fe9e6b7b47455cf6c82c1b758f99262862..d4dd34d1dd89dfb5dc98b11c023ff9273b346517 100644 (file)
@@ -402,7 +402,6 @@ void vnc_direct_bgp_del_route_ce(struct bgp *bgp, struct route_node *rn,
 
 static void vnc_direct_bgp_vpn_enable_ce(struct bgp *bgp, afi_t afi)
 {
-       struct rfapi_cfg *hc;
        struct route_node *rn;
        struct bgp_info *ri;
 
@@ -411,7 +410,7 @@ static void vnc_direct_bgp_vpn_enable_ce(struct bgp *bgp, afi_t afi)
        if (!bgp)
                return;
 
-       if (!(hc = bgp->rfapi_cfg))
+       if (!(bgp->rfapi_cfg))
                return;
 
        if (!VNC_EXPORT_BGP_CE_ENABLED(bgp->rfapi_cfg)) {
index 4bc5535e1bcaf82faec8d4758250be7fef433aec..156572b57fefaf10b6c40797d5dbeeeac3c87659 100644 (file)
@@ -557,7 +557,6 @@ static void vnc_import_bgp_add_route_mode_resolve_nve(
        struct bgp_info *info)                  /* unicast info */
 {
        afi_t afi = family2afi(prefix->family);
-       struct rfapi_cfg *hc = NULL;
 
        struct prefix pfx_unicast_nexthop = {0}; /* happy valgrind */
 
@@ -607,7 +606,7 @@ static void vnc_import_bgp_add_route_mode_resolve_nve(
                return;
        }
 
-       if (!(hc = bgp->rfapi_cfg)) {
+       if (!(bgp->rfapi_cfg)) {
                vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping",
                                       __func__);
                return;
@@ -698,7 +697,7 @@ static void vnc_import_bgp_add_route_mode_plain(struct bgp *bgp,
        struct peer *peer = info->peer;
        struct attr *attr = info->attr;
        struct attr hattr;
-       struct rfapi_cfg *hc = NULL;
+       struct rfapi_cfg *hc = bgp->rfapi_cfg;
        struct attr *iattr = NULL;
 
        struct rfapi_ip_addr vnaddr;
@@ -723,7 +722,7 @@ static void vnc_import_bgp_add_route_mode_plain(struct bgp *bgp,
                return;
        }
 
-       if (!(hc = bgp->rfapi_cfg)) {
+       if (!hc) {
                vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping",
                                       __func__);
                return;
@@ -886,7 +885,6 @@ vnc_import_bgp_add_route_mode_nvegroup(struct bgp *bgp, struct prefix *prefix,
        struct peer *peer = info->peer;
        struct attr *attr = info->attr;
        struct attr hattr;
-       struct rfapi_cfg *hc = NULL;
        struct attr *iattr = NULL;
 
        struct rfapi_ip_addr vnaddr;
@@ -911,7 +909,7 @@ vnc_import_bgp_add_route_mode_nvegroup(struct bgp *bgp, struct prefix *prefix,
                return;
        }
 
-       if (!(hc = bgp->rfapi_cfg)) {
+       if (!(bgp->rfapi_cfg)) {
                vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping",
                                       __func__);
                return;
@@ -2904,6 +2902,8 @@ void vnc_import_bgp_redist_disable(struct bgp *bgp, afi_t afi)
                                                struct rfapi_descriptor *rfd;
                                                vncHDBgpDirect.peer = bi->peer;
 
+                                               assert(bi->extra);
+
                                                rfd = bi->extra->vnc.export
                                                              .rfapi_handle;
 
index 3ec29cc38fd8637e8b30d33a7a01c673fd60602f..8846fcdf717c3d031e5ca2c4c826f6529faee1a5 100755 (executable)
@@ -226,7 +226,14 @@ AC_ARG_ENABLE([memory-sanitizer], AS_HELP_STRING([--enable-memory-sanitizer], \
               ])
 
 dnl if the user has specified any CFLAGS, override our settings
-if test "x${enable_dev_build}" = "xyes"; then
+if test "x${enable_gcov}" = "xyes"; then
+   if test "z$orig_cflags" = "z"; then
+      AC_C_FLAG([-coverage])
+      AC_C_FLAG([-O0])
+   fi
+
+   LDFLAGS="${LDFLAGS} -lgcov"
+elif test "x${enable_dev_build}" = "xyes"; then
    AC_DEFINE(DEV_BUILD,,Build for development)
    if test "z$orig_cflags" = "z"; then
       AC_C_FLAG([-g3])
@@ -441,6 +448,8 @@ AC_ARG_ENABLE([clippy-only],
   AS_HELP_STRING([--enable-clippy-only], [Only build clippy]))
 AC_ARG_ENABLE([numeric_version],
   AS_HELP_STRING([--enable-numeric-version], [Only numeric digits allowed in version (for Alpine)]))
+AC_ARG_ENABLE([gcov],
+  AS_HELP_STRING([--enable-gcov], [Add code coverage information]))
 
 AS_IF([test "${enable_clippy_only}" != "yes"], [
 AC_CHECK_HEADERS(json-c/json.h)
@@ -692,6 +701,11 @@ AC_DEFINE_UNQUOTED(MULTIPATH_NUM, $MPATH_NUM, Maximum number of paths for a rout
 
 AC_DEFINE_UNQUOTED(VTYSH_PAGER, "$VTYSH_PAGER", [What pager to use])
 
+dnl --------------------
+dnl Enable code coverage
+dnl --------------------
+AM_CONDITIONAL([HAVE_GCOV],[test '!' "$enable_gcov" = no])
+
 dnl ------------------------------------
 dnl Alpine only accepts numeric versions
 dnl ------------------------------------
index 1f27e4a8e7fdc42e0794ea41e282a511a5cf2184..62cb3c2edb452e7e859fe6eafef2d863c7ca4a08 100644 (file)
@@ -183,6 +183,7 @@ EXTRA_DIST = frr-sphinx.mk \
        developer/ldpd-basic-test-setup.md \
        developer/library.rst \
        developer/Makefile.in \
+       developer/maintainer-release-build.rst \
        developer/memtypes.rst \
        developer/modules.rst \
        developer/next-hop-tracking.rst \
diff --git a/doc/developer/maintainer-release-build.rst b/doc/developer/maintainer-release-build.rst
new file mode 100644 (file)
index 0000000..907bd14
--- /dev/null
@@ -0,0 +1,89 @@
+Release Build Procedure for FRR maintainers
+=========================================================
+
+1. Rename branch (if needed)
+
+.. code-block:: shell
+
+   git clone git@github.com:FRRouting/frr.git
+   cd frr
+   git checkout dev/5.0
+   git push origin :refs/heads/dev/5.0
+   git push origin dev/5.0:refs/heads/stable/5.0
+
+2. Checkout the new stable branch:
+
+.. code-block:: shell
+
+   git checkout stable/5.0
+
+3. Update Changelog for RedHat Package:
+
+   Edit :file:`redhat/frr.spec.in` and look for the ``%changelog`` section:
+
+   - Change last (top of list) entry from ``%{version}`` to previous fixed
+     version number, i.e.::
+
+        * Tue Nov  7 2017 Martin Winter <mwinter@opensourcerouting.org> - %{version}
+
+     to::
+
+        * Tue Nov  7 2017 Martin Winter <mwinter@opensourcerouting.org> - 3.0.2
+
+   - Add new entry to the top of the list with ``%{version}`` tag and changelog
+     for version.
+     Make sure to watch the format, i.e. the day is always 2 characters, with
+     the 1st character being a space if the day is one digit.
+
+4. Update Changelog for Debian Packages:
+
+   Edit :file:`debianpkg/changelog.in`:
+
+   - Change last (top of list) entry from ``@VERSION@`` to previous fixed
+     version number, i.e.::
+
+        frr (@VERSION@) RELEASED; urgency=medium
+
+     to::
+
+        frr (3.0.2) RELEASED; urgency=medium
+
+   - Add a new entry to the top of the list with a ``@VERSION@`` tag and
+     changelog for version.
+
+5. Change main version number:
+
+    - Edit :file:`configure.ac` and change version in the ``AC_INIT`` command
+    - Create a new entry with the version as ``%{version}`` tag
+
+6. Test building at least a Red Hat and Ubuntu package (or create a PR to have
+   the CI system test them)
+
+7. Commit the changes, adding the changelog to the commit message
+
+8. Create a git tag for the version:
+
+   .. code-block:: shell
+
+      git tag -a frr-5.0 -m "FRRouting Release 5.0"
+
+9. Push the commit and tag(s) and watch for errors on CI:
+
+   .. code-block:: shell
+
+      git push
+      git push --tags
+
+10. Kick off the Release build plan on the CI system for the correct release
+
+11. Send a Release Announcement with changes to
+    ``announce@lists.frrouting.org``
+
+12. Kick off the Snapcraft build plan for the correct release
+
+13. After CI plans succeed, release on GitHub by going to
+    https://github.com/FRRouting/frr/releases and selecting "Draft a new
+    release".
+
+14. Deploy Snapcraft release (after CI system finishes the tests for snapcraft
+    testplan)
index b29769da4947592de6355697719b502d69989020..cd03d2733d251abc6ed0e1b2f02498cb3e37d4fa 100644 (file)
@@ -300,6 +300,37 @@ Documentation should be written in reStructuredText. Sphinx extensions may be
 utilized but pure ReST is preferred where possible. See
 :ref:`documentation`.
 
+Code Reviews
+============
+
+Code quality is paramount for any large program. Consequently we require
+reviews of all submitted patches by at least one person other than the
+submitter before the patch is merged.
+
+Because of the nature of the software, FRR's maintainer list (i.e. those with
+commit permissions) tends to contain employees / members of various
+organizations. In order to prevent conflicts of interest, we use an honor
+system in which submissions from an individual representing one company should
+be merged by someone unaffiliated with that company.
+
+Guidelines for code review
+""""""""""""""""""""""""""
+
+- As a rule of thumb, the depth of the review should be proportional to the
+  scope and / or impact of the patch.
+
+- Anyone may review a patch.
+
+- When using GitHub reviews, marking "Approve" on a code review indicates
+  willingness to merge the PR.
+
+- For individuals with merge rights, marking "Changes requested" is equivalent
+  to a NAK.
+
+- For a PR you marked with "Changes requested", please respond to updates in a
+  timely manner to avoid impeding the flow of development.
+
+
 Coding Practices & Style
 ========================
 
index 0ea93a62e7a9cc1edf63f58d4cf7d88cccba46a4..579b0b6497edeee2f0909af0962b8da281409ff3 100644 (file)
@@ -1783,8 +1783,8 @@ kernel routing tables.
        neighbor 10.0.0.3 remote-as 4
        neighbor 10.0.0.4 remote-as 5
 
-.. index:: show ip bgp view NAME
-.. clicmd:: show ip bgp view NAME
+.. index:: show [ip] bgp view NAME
+.. clicmd:: show [ip] bgp view NAME
 
    Display the routing table of BGP view ``NAME``.
 
@@ -1864,22 +1864,22 @@ Debugging
 
    Show all enabled debugs.
 
-.. index:: [no] debug neighbor-events
-.. clicmd:: [no] debug neighbor-events
+.. index:: [no] debug bgp neighbor-events
+.. clicmd:: [no] debug bgp neighbor-events
 
    Enable or disable debugging for neighbor events. This provides general
    information on BGP events such as peer connection / disconnection, session
    establishment / teardown, and capability negotiation.
 
-.. index:: [no] debug updates
-.. clicmd:: [no] debug updates
+.. index:: [no] debug bgp updates
+.. clicmd:: [no] debug bgp updates
 
    Enable or disable debugging for BGP updates. This provides information on
    BGP UPDATE messages transmitted and received between local and remote
    instances.
 
-.. index:: [no] debug keepalives
-.. clicmd:: [no] debug keepalives
+.. index:: [no] debug bgp keepalives
+.. clicmd:: [no] debug bgp keepalives
 
    Enable or disable debugging for BGP keepalives. This provides information on
    BGP KEEPALIVE messages transmitted and received between local and remote
@@ -1981,17 +1981,27 @@ Other BGP Commands
 Displaying BGP Information
 ==========================
 
+The following four commands display the IPv6 and IPv4 routing tables, depending
+on whether or not the ``ip`` keyword is used.
+Actually, :clicmd:`show ip bgp` command was used on older `Quagga` routing
+daemon project, while :clicmd:`show bgp` command is the new format. The choice
+has been done to keep old format with IPv4 routing table, while new format
+displays IPv6 routing table.
+
 .. index:: show ip bgp
 .. clicmd:: show ip bgp
 
 .. index:: show ip bgp A.B.C.D
 .. clicmd:: show ip bgp A.B.C.D
 
-.. index:: show ip bgp X:X::X:X
-.. clicmd:: show ip bgp X:X::X:X
+.. index:: show bgp
+.. clicmd:: show bgp
+
+.. index:: show bgp X:X::X:X
+.. clicmd:: show bgp X:X::X:X
 
    These commands display BGP routes. When no route is specified, the default
-   is to display all IPv4 BGP routes.
+   is to display all BGP routes.
 
    ::
 
@@ -2004,31 +2014,56 @@ Displaying BGP Information
 
          Total number of prefixes 1
 
-.. index:: show ip bgp regexp LINE
-.. clicmd:: show ip bgp regexp LINE
+Some other commands provide additional options for filtering the output.
+
+.. index:: show [ip] bgp regexp LINE
+.. clicmd:: show [ip] bgp regexp LINE
 
    This command displays BGP routes using AS path regular expression
    (:ref:`bgp-regular-expressions`).
 
-.. index:: show bgp <ipv4|ipv6> summary
-.. clicmd:: show bgp <ipv4|ipv6> summary
+.. index:: show [ip] bgp summary
+.. clicmd:: show [ip] bgp summary
 
    Show a bgp peer summary for the specified address family.
 
-.. index:: show bgp <ipv4|ipv6> neighbor [PEER]
-.. clicmd:: show bgp <ipv4|ipv6> neighbor [PEER]
+The old command structure :clicmd:`show ip bgp` may be removed in the future
+and should no longer be used. In order to reach the other BGP routing tables
+other than the IPv6 routing table given by :clicmd:`show bgp`, the new command
+structure is extended with :clicmd:`show bgp [afi] [safi]`.
+
+.. index:: show bgp [afi] [safi]
+.. clicmd:: show bgp [afi] [safi]
+
+.. index:: show bgp <ipv4|ipv6> <unicast|multicast|vpn|labeled-unicast>
+.. clicmd:: show bgp <ipv4|ipv6> <unicast|multicast|vpn|labeled-unicast>
 
-   This command shows information on a specific BGP `peer`.
+   These commands display BGP routes for the specific routing table indicated by
+   the selected afi and the selected safi. If no afi and no safi value is given,
+   the command falls back to the default IPv6 routing table
 
-.. index:: show bgp <ipv4|ipv6> dampening dampened-paths
-.. clicmd:: show bgp <ipv4|ipv6> dampening dampened-paths
+.. index:: show bgp [afi] [safi] summary
+.. clicmd:: show bgp [afi] [safi] summary
 
-   Display paths suppressed due to dampening.
+   Show a bgp peer summary for the specified address family, and subsequent
+   address-family.
 
-.. index:: show bgp <ipv4|ipv6> dampening flap-statistics
-.. clicmd:: show bgp <ipv4|ipv6> dampening flap-statistics
+.. index:: show bgp [afi] [safi] neighbor [PEER]
+.. clicmd:: show bgp [afi] [safi] neighbor [PEER]
 
-   Display flap statistics of routes.
+   This command shows information on a specific BGP peer of the relevant
+   afi and safi selected.
+
+.. index:: show bgp [afi] [safi] dampening dampened-paths
+.. clicmd:: show bgp [afi] [safi] dampening dampened-paths
+
+   Display paths suppressed due to dampening of the selected afi and safi
+   selected.
+
+.. index:: show bgp [afi] [safi] dampening flap-statistics
+.. clicmd:: show bgp [afi] [safi] dampening flap-statistics
+
+   Display flap statistics of routes of the selected afi and safi selected.
 
 .. _bgp-display-routes-by-community:
 
@@ -2073,11 +2108,11 @@ Displaying Routes by AS Path
    This commands displays BGP routes that matches a regular
    expression `line` (:ref:`bgp-regular-expressions`).
 
-.. index:: show ip bgp ipv4 vpn
-.. clicmd:: show ip bgp ipv4 vpn
+.. index:: show [ip] bgp ipv4 vpn
+.. clicmd:: show [ip] bgp ipv4 vpn
 
-.. index:: show ipv6 bgp ipv6 vpn
-.. clicmd:: show ipv6 bgp ipv6 vpn
+.. index:: show [ip] bgp ipv6 vpn
+.. clicmd:: show [ip] bgp ipv6 vpn
 
    Print active IPV4 or IPV6 routes advertised via the VPN SAFI.
 
@@ -2448,6 +2483,8 @@ Example of how to set up a 6-Bone connection.
 
 .. include:: rpki.rst
 
+.. include:: flowspec.rst
+
 .. [#med-transitivity-rant] For some set of objects to have an order, there *must* be some binary ordering relation that is defined for *every* combination of those objects, and that relation *must* be transitive. I.e.:, if the relation operator is <, and if a < b and b < c then that relation must carry over and it *must* be that a < c for the objects to have an order. The ordering relation may allow for equality, i.e. a < b and b < a may both be true and imply that a and b are equal in the order and not distinguished by it, in which case the set has a partial order. Otherwise, if there is an order, all the objects have a distinct place in the order and the set has a total order)
 .. [bgp-route-osci-cond] McPherson, D. and Gill, V. and Walton, D., "Border Gateway Protocol (BGP) Persistent Route Oscillation Condition", IETF RFC3345
 .. [stable-flexible-ibgp] Flavel, A. and M. Roughan, "Stable and flexible iBGP", ACM SIGCOMM 2009
index 3fced110240aa379a5ba0780fa285c72ed555120..28081bca7d52378eb7ced343f046fae731d3312a 100644 (file)
@@ -131,7 +131,8 @@ language = None
 
 # List of patterns, relative to source directory, that match files and
 # directories to ignore when looking for source files.
-exclude_patterns = ['_build', 'rpki.rst', 'routeserver.rst', 'ospf_fundamentals.rst']
+exclude_patterns = ['_build', 'rpki.rst', 'routeserver.rst',
+                    'ospf_fundamentals.rst', 'flowspec.rst']
 
 # The reST default role (used for this markup: `text`) to use for all
 # documents.
diff --git a/doc/user/flowspec.rst b/doc/user/flowspec.rst
new file mode 100644 (file)
index 0000000..f6af88c
--- /dev/null
@@ -0,0 +1,351 @@
+.. _flowspec:
+
+Flowspec
+========
+
+.. _features-of-the-current-implementation-flowspec:
+
+Overview
+---------
+
+Flowspec introduces a new :abbr:`NLRI (Network Layer Reachability Information)`
+encoding format that is used to distribute traffic rule flow specifications.
+Basically, instead of simply relying on destination IP address for IP prefixes,
+the IP prefix is replaced by a n-tuple consisting of a rule. That rule can be a
+more or less complex combination of the following:
+
+
+- Network source/destination (can be one or the other, or both).
+- Layer 4 information for UDP/TCP: source port, destination port, or any port.
+- Layer 4 information for ICMP type and ICMP code.
+- Layer 4 information for TCP Flags.
+- Layer 3 information: DSCP value, Protocol type, packet length, fragmentation.
+- Misc layer 4 TCP flags.
+
+A combination of the above rules is applied for traffic filtering. This is
+encoded as part of specific BGP extended communities and the action can range
+from the obvious rerouting (to nexthop or to separate VRF) to shaping, or
+discard.
+
+The following IETF drafts and RFCs have been used to implement FRR Flowspec:
+
+- :rfc:`5575`
+- [Draft-IETF-IDR-Flowspec-redirect-IP]_
+
+.. _design-principles-flowspec:
+
+Design Principles
+-----------------
+
+FRR implements the Flowspec client side, that is to say that BGP is able to
+receive Flowspec entries, but is not able to act as manager and send Flowspec
+entries.
+
+Linux provides the following mechanisms to implement policy based routing:
+
+- Filtering the traffic with ``Netfilter``.
+  ``Netfilter`` provides a set of tools like ``ipset`` and ``iptables`` that are
+  powerful enough to be able to filter such Flowspec filter rule.
+
+- using non standard routing tables via ``iproute2`` (via the ``ip rule``
+  command provided by ``iproute2``).
+  ``iproute2`` is already used by FRR's :ref:`pbr` daemon which provides basic
+  policy based routing based on IP source and destination criterion.
+
+Below example is an illustration of what Flowspec will inject in the underlying
+system:
+
+.. code-block:: shell
+
+   # linux shell
+   ipset create match0x102 hash:net,net counters
+   ipset add match0x102 32.0.0.0/16,40.0.0.0/16
+   iptables -N match0x102 -t mangle
+   iptables -A match0x102 -t mangle -j MARK --set-mark 102
+   iptables -A match0x102 -t mangle -j ACCEPT
+   iptables -i ntfp3 -t mangle -I PREROUTING -m set --match-set match0x102
+                src,dst -g match0x102
+   ip rule add fwmark 102 lookup 102
+   ip route add 40.0.0.0/16 via 44.0.0.2 table 102
+
+For handling an incoming Flowspec entry, the following workflow is applied:
+
+- Incoming Flowspec entries are handled by *bgpd*, stored in the BGP RIB.
+- Flowspec entry is installed according to its complexity.
+
+It will be installed if one of the following filtering action is seen on the
+BGP extended community: either redirect IP, or redirect VRF, in conjunction
+with rate option, for redirecting traffic. Or rate option set to 0, for
+discarding traffic.
+
+According to the degree of complexity of the Flowspec entry, it will be
+installed in *zebra* RIB. For more information about what is supported in the
+FRR implementation as rule, see :ref:`flowspec-known-issues` chapter. Flowspec
+entry is split in several parts before being sent to *zebra*.
+
+- *zebra* daemon receives the policy routing configuration
+
+Policy Based Routing entities necessary to policy route the traffic in the
+underlying system, are received by *zebra*. Two filtering contexts will be
+created or appended in ``Netfilter``: ``ipset`` and ``iptable`` context. The
+former is used to define an IP filter based on multiple criterium. For
+instance, an ipset ``net:net`` is based on two ip addresses, while
+``net,port,net`` is based on two ip addresses and one port (for ICMP, UDP, or
+TCP). The way the filtering is used (for example, is src port or dst port
+used?) is defined by the latter filtering context. ``iptable`` command will
+reference the ``ipset`` context and will tell how to filter and what to do. In
+our case, a marker will be set to indicate ``iproute2`` where to forward the
+traffic to. Sometimes, for dropping action, there is no need to add a marker;
+the ``iptable`` will tell to drop all packets matching the ``ipset`` entry.
+
+Configuration Guide
+-------------------
+
+In order to configure an IPv4 Flowspec engine, use the following configuration.
+As of today, it is only possible to configure Flowspec on the default VRF.
+
+.. code-block:: frr
+
+   router bgp <AS>
+     neighbor <A.B.C.D> remote-as <remoteAS>
+     address-family ipv4 flowspec
+      neighbor <A.B.C.D> activate
+    exit
+   exit
+
+You can see Flowspec entries, by using one of the following show commands:
+
+.. index:: show bgp ipv4 flowspec [detail | A.B.C.D]
+.. clicmd:: show bgp ipv4 flowspec [detail | A.B.C.D]
+
+
+Per-interface configuration
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+One nice feature to use is the ability to apply Flowspec to a specific
+interface, instead of applying it to the whole machine. Despite the following
+IETF draft [Draft-IETF-IDR-Flowspec-Interface-Set]_ is not implemented, it is
+possible to manually limit Flowspec application to some incoming interfaces.
+Actually, not using it can result to some unexpected behaviour like accounting
+twice the traffic, or slow down the traffic (filtering costs). To limit
+Flowspec to one specific interface, use the following command, under
+`flowspec address-family` node.
+
+.. index:: [no] local-install <IFNAME | any>
+.. clicmd:: [no] local-install <IFNAME | any>
+
+By default, Flowspec is activated on all interfaces. Installing it to a named
+interface will result in allowing only this interface. Conversely, enabling any
+interface will flush all previously configured interfaces.
+
+VRF redirection
+^^^^^^^^^^^^^^^
+
+Another nice feature to configure is the ability to redirect traffic to a
+separate VRF. This feature does not go against the ability to configure
+Flowspec only on default VRF. Actually, when you receive incoming BGP flowspec
+entries on that default VRF, you can redirect traffic to an other VRF.
+
+As a reminder, BGP flowspec entries have a BGP extended community that contains
+a Route Target. Finding out a local VRF based on Route Target consists in the
+following:
+
+- A configuration of each VRF must be done, with its Route Target set
+  Each VRF is being configured within a BGP VRF instance with its own Route
+  Target list. Route Target accepted format matches the following:
+  ``A.B.C.D:U16``, or ``U16:U32``, ``U32:U16``.
+
+- The first VRF with the matching Route Target will be selected to route traffic
+  to. Use the following command under ipv4 unicast address-family node
+
+.. index:: [no] rt redirect import RTLIST...
+.. clicmd:: [no] rt redirect import RTLIST...
+
+In order to illustrate, if the Route Target configured in the Flowspec entry is
+``E.F.G.H:II``, then a BGP VRF instance with the same Route Target will be set
+set.  That VRF will then be selected. The below full configuration example
+depicts how Route Targets are configured and how VRFs and cross VRF
+configuration is done.  Note that the VRF are mapped on Linux Network
+Namespaces. For data traffic to cross VRF boundaries, virtual ethernet
+interfaces are created with private IP adressing scheme.
+
+.. code-block:: frr
+
+   router bgp <ASx>
+    neighbor <A.B.C.D> remote-as <ASz>
+    address-family ipv4 flowspec
+     neighbor A.B.C.D activate
+    exit
+   exit
+   router bgp <ASy> vrf vrf2
+    address-family ipv4 unicast
+     rt redirect import <E.F.G.H:II>
+    exit
+   exit
+
+Flowspec monitoring & troubleshooting
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+You can monitor policy-routing objects by using one of the following commands.
+Those command rely on the filtering contexts configured from BGP, and get the
+statistics information retrieved from the underlying system. In other words,
+those statistics are retrieved from ``Netfilter``.
+
+.. index:: show pbr ipset IPSETNAME | iptable
+.. clicmd:: show pbr ipset IPSETNAME | iptable
+
+``IPSETNAME`` is the policy routing object name created by ``ipset``.  About
+rule contexts, it is possible to know which rule has been configured to
+policy-route some specific traffic. The :clicmd:`show pbr iptable` command
+displays for forwarded traffic, which table is used. Then it is easy to use
+that table identifier to dump the routing table that the forwarded traffic will
+match.
+
+.. code-block:: frr
+
+.. index:: show ip route table TABLEID
+.. clicmd:: show ip route table TABLEID
+
+   ``TABLEID`` is the table number identifier referencing the non standard
+   routing table used in this example.
+
+.. index:: [no] debug bgp flowspec
+.. clicmd:: [no] debug bgp flowspec
+
+   You can troubleshoot Flowspec, or BGP policy based routing. For instance, if
+   you encounter some issues when decoding a Flowspec entry, you should enable
+   :clicmd:`debug bgp flowspec`.
+
+.. index:: [no] debug bgp pbr [error]
+.. clicmd:: [no] debug bgp pbr [error]
+
+   If you fail to apply the flowspec entry into *zebra*, there should be some
+   relationship with policy routing mechanism. Here,
+   :clicmd:`debug bgp pbr error` could help.
+
+   To get information about policy routing contexts created/removed, only use
+   :clicmd:`debug bgp pbr` command.
+
+Ensuring that a Flowspec entry has been correctly installed and that incoming
+traffic is policy-routed correctly can be checked as demonstrated below. First
+of all, you must check whether the Flowspec entry has been installed or not.
+
+.. code-block:: frr
+
+   CLI# show bgp ipv4 flowspec 5.5.5.2/32
+    BGP flowspec entry: (flags 0x418)
+      Destination Address 5.5.5.2/32
+      IP Protocol = 17
+      Destination Port >= 50 , <= 90
+      FS:redirect VRF RT:255.255.255.255:255
+      received for 18:41:37
+      installed in PBR (match0x271ce00)
+
+This means that the Flowspec entry has been installed in an ``iptable`` named
+``match0x271ce00``. Once you have confirmation it is installed, you can check
+whether you find the associate entry by executing following command. You can
+also check whether incoming traffic has been matched by looking at counter
+line.
+
+.. code-block:: frr
+
+   CLI# show pbr ipset match0x271ce00
+   IPset match0x271ce00 type net,port
+        to 5.5.5.0/24:proto 6:80-120 (8)
+           pkts 1000, bytes 1000000
+        to 5.5.5.2:proto 17:50-90 (5)
+           pkts 1692918, bytes 157441374
+
+As you can see, the entry is present. note that an ``iptable`` entry can be
+used to host several Flowspec entries. In order to know where the matching
+traffic is redirected to, you have to look at the policy routing rules. The
+policy-routing is done by forwarding traffic to a routing table number. That
+routing table number is reached by using a ``iptable``. The relationship
+between the routing table number and the incoming traffic is a ``MARKER`` that
+is set by the IPtable referencing the IPSet. In Flowspec case, ``iptable``
+referencing the ``ipset`` context have the same name. So it is easy to know
+which routing table is used by issuing following command:
+
+.. code-block:: frr
+
+   CLI# show pbr iptable
+      IPtable match0x271ce00 action redirect (5)
+        pkts 1700000, bytes 158000000
+        table 257, fwmark 257
+   ...
+
+As you can see, by using following Linux commands, the MARKER ``0x101`` is
+present in both ``iptable`` and ``ip rule`` contexts.
+
+.. code-block:: shell
+
+   # iptables -t mangle --list match0x271ce00 -v
+   Chain match0x271ce00 (1 references)
+   pkts bytes target     prot opt in     out     source              destination
+   1700K  158M MARK       all  --  any    any     anywhere             anywhere
+        MARK set 0x101
+   1700K  158M ACCEPT     all  --  any    any     anywhere             anywhere
+
+   # ip rule list
+   0:from all lookup local
+   0:from all fwmark 0x101 lookup 257
+   32766:from all lookup main
+   32767:from all lookup default
+
+This allows us to see where the traffic is forwarded to.
+
+.. _flowspec-known-issues:
+
+Limitations / Known Issues
+--------------------------
+
+As you can see, Flowspec is rich and can be very complex. As of today, not all
+Flowspec rules will be able to be converted into Policy Based Routing actions.
+
+- The ``Netfilter`` driver is not integrated into FRR yet. Not having this
+  piece of code prevents from injecting flowspec entries into the underlying
+  system.
+
+- There are some limitations around filtering contexts
+
+  If I take example of UDP ports, or TCP ports in Flowspec, the information
+  can be a range of ports, or a unique value. This case is handled.
+  However, complexity can be increased, if the flow is a combination of a list
+  of range of ports and an enumerate of unique values. Here this case is not
+  handled. Similarly, it is not possible to create a filter for both src port
+  and dst port. For instance, filter on src port from [1-1000] and dst port =
+  80. The same kind of complexity is not possible for packet length, ICMP type,
+  ICMP code.
+
+There are some other known issues:
+
+- The validation procedure depicted in :rfc:`5575` is not available.
+
+  This validation procedure has not been implemented, as this feature was not
+  used in the existing setups you shared wih us.
+
+- The filtering action shaper value, if positive, is not used to apply shaping.
+
+  If value is positive, the traffic is redirected to the wished destination,
+  without any other action configured by Flowspec.
+  It is recommended to configure Quality of Service if needed, more globally on
+  a per interface basis.
+
+- Upon an unexpected crash or other event, *zebra* may not have time to flush
+  PBR contexts.
+
+  That is to say ``ipset``, ``iptable`` and ``ip rule`` contexts. This is also a
+  consequence due to the fact that ip rule / ipset / iptables are not discovered
+  at startup (not able to read appropriate contexts coming from Flowspec).
+
+Appendix
+--------
+
+More information with a public presentation that explains the design of Flowspec
+inside FRRouting.
+
+[Presentation]_
+
+.. [Draft-IETF-IDR-Flowspec-redirect-IP] <https://tools.ietf.org/id/draft-ietf-idr-flowspec-redirect-ip-02.txt>
+.. [Draft-IETF-IDR-Flowspec-Interface-Set] <https://tools.ietf.org/id/draft-ietf-idr-flowspec-interfaceset-03.txt>
+.. [Presentation] <https://docs.google.com/presentation/d/1ekQygUAG5yvQ3wWUyrw4Wcag0LgmbW1kV02IWcU4iUg/edit#slide=id.g378f0e1b5e_1_44>
index 26d30f1e10e71ca00ab934a16243a647b3a71412..158e2c8595243418b726194b38d873d8a682e8ad 100644 (file)
@@ -205,6 +205,15 @@ options from the list below.
    hardcoded arrays that FRR builds towards, so we need to know how big to
    make these arrays at build time.
 
+.. option:: --enable-gcov
+
+   Code coverage reports from gcov require adjustments to the C and LD flags.
+   With this option, gcov instrumentation is added to the build and coverage
+   reports are created during execution.  The check-coverage make target is
+   also created to ease report uploading to codecov.io.  The upload requires
+   the COMMIT (git hash) and TOKEN (codecov upload token) environment variables
+   be set.
+
 You may specify any combination of the above options to the configure
 script. By default, the executables are placed in :file:`/usr/local/sbin`
 and the configuration files in :file:`/usr/local/etc`. The :file:`/usr/local/`
index 93a8e4396a261d113ea2e13f992ebcb530fe8447..38b2b68e98e022520f1b01f0cf3bf83ed7099ed4 100644 (file)
@@ -44,6 +44,9 @@ In a nutshell, the current implementation provides the following features
 - Route maps can be configured to match a specific RPKI validation state. This
   allows the creation of local policies, which handle BGP routes based on the
   outcome of the Prefix Origin Validation.
+- Updates from the RPKI cache servers are directly applied and path selection
+  is updated accordingly. (Soft reconfiguration **must** be enabled for this
+  to work).
 
 
 .. _enabling-rpki:
@@ -65,6 +68,32 @@ Enabling RPKI
 
 .. _configuring-rpki-rtr-cache-servers:
 
+.. index:: daemons.conf
+
+   When first installing FRR with RPKI support from the pre-packaged binaries. Remember
+   to append '-M rpki' in the /etc/frr/daemons.conf file to the bgpd_options.
+   
+   bgpd_options="   --daemon -A 127.0.0.1 -M rpki"
+   instead of the default setting
+   bgpd_options="   --daemon -A 127.0.0.1"
+   
+
+   Else you will encounter an error when trying to enter RPKI configuration mode. Because
+   the rpki module is not loaded when the BGP daemon is initialized.
+
+   Examples of the error:
+
+   router(config)# debug rpki
+   % [BGP] Unknown command: debug rpki
+   
+   router(config)# rpki
+   % [BGP] Unknown command: rpki
+   
+   Note that the rpki commands will be available in vtysh when running 'find rpki'.
+   Even if the RPKI module is NOT loaded.
+   The RPKI commands will be unavailable if you try running the same command in the
+   cli specific to the BGP daemon.
+
 Configuring RPKI/RTR Cache Servers
 ----------------------------------
 
index 180d2d7efd8d6ca4a1204ad284583459f6f0f291..08606c2128a268e5f23b0fd9a1a3850f2bb78a4a 100644 (file)
@@ -521,6 +521,94 @@ entered within the VRF context the static routes are created in the VRF.
    show ip table vrf r1-cust1 table 43
 
 
+.. _zebra-mpls:
+
+MPLS Commands
+=============
+
+You can configure static mpls entries in zebra. Basically, handling MPLS
+consists of popping, swapping or pushing labels to IP packets.
+
+MPLS Acronyms
+-------------
+
+:abbr:`LSR (Labeled Switch Router)`
+   Networking devices handling labels used to forward traffic between and through
+   them.
+
+:abbr:`LER (Labeled Edge Router)`
+   A Labeled edge router is located at the edge of an MPLS network, generally
+   between an IP network and an MPLS network.
+
+MPLS Push Action
+----------------
+
+The push action is generally used for LER devices, which want to encapsulate
+all traffic for a wished destination into an MPLS label. This action is stored
+in routing entry, and can be configured like a route:
+
+.. index:: [no] ip route NETWORK MASK GATEWAY|INTERFACE label LABEL
+.. clicmd:: [no] ip route NETWORK MASK GATEWAY|INTERFACE label LABEL
+
+   NETWORK ans MASK stand for the IP prefix entry to be added as static
+   route entry.
+   GATEWAY is the gateway IP address to reach, in order to reach the prefix.
+   INTERFACE is the interface behind which the prefix is located.
+   LABEL is the MPLS label to use to reach the prefix abovementioned.
+
+   You can check that the static entry is stored in the zebra RIB database, by
+   looking at the presence of the entry.
+
+   ::
+
+      zebra(configure)# ip route 1.1.1.1/32 10.0.1.1 label 777
+      zebra# show ip route
+      Codes: K - kernel route, C - connected, S - static, R - RIP,
+      O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
+      T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
+      F - PBR,
+      > - selected route, * - FIB route
+
+      S>* 1.1.1.1/32 [1/0] via 10.0.1.1, r2-eth0, label 777, 00:39:42
+
+MPLS Swap and Pop Action
+------------------------
+
+The swap action is generally used for LSR devices, which swap a packet with a
+label, with an other label. The Pop action is used on LER devices, at the
+termination of the MPLS traffic; this is used to remove MPLS header.
+
+.. index:: [no] mpls lsp INCOMING_LABEL GATEWAY OUTGOING_LABEL|explicit-null|implicit-null
+.. clicmd:: [no] mpls lsp INCOMING_LABEL GATEWAY OUTGOING_LABEL|explicit-null|implicit-null
+
+   INCOMING_LABEL and OUTGOING_LABEL are MPLS labels with values ranging from 16
+   to 1048575.
+   GATEWAY is the gateway IP address where to send MPLS packet.
+   The outgoing label can either be a value or have an explicit-null label header. This
+   specific header can be read by IP devices. The incoming label can also be removed; in
+   that case the implicit-null keyword is used, and the outgoing packet emitted is an IP
+   packet without MPLS header.
+
+You can check that the MPLS actions are stored in the zebra MPLS table, by looking at the
+presence of the entry.
+
+.. index:: show mpls table
+.. clicmd:: show mpls table
+
+::
+
+   zebra(configure)# mpls lsp 18 10.125.0.2 implicit-null
+   zebra(configure)# mpls lsp 19 10.125.0.2 20
+   zebra(configure)# mpls lsp 21 10.125.0.2 explicit-null
+   zebra# show mpls table
+   Inbound                            Outbound
+   Label     Type          Nexthop     Label
+   --------  -------  ---------------  --------
+   18     Static       10.125.0.2  implicit-null
+   19     Static       10.125.0.2  20
+   21     Static       10.125.0.2  IPv4 Explicit Null
+
+
 .. _multicast-rib-commands:
 
 Multicast RIB Commands
diff --git a/docker/alpine/Dockerfile-coverage b/docker/alpine/Dockerfile-coverage
new file mode 100644 (file)
index 0000000..5fdb117
--- /dev/null
@@ -0,0 +1,12 @@
+FROM alpine:3.7
+ARG commit
+ARG token
+ENV COMMIT=${commit}
+ENV TOKEN=${token}
+ADD . /src
+RUN cd /src && \
+       source alpine/APKBUILD.in && \
+       apk add --no-cache alpine-sdk $makedepends $checkdepends && \
+       ./bootstrap.sh && \
+       ./configure --enable-gcov
+ENTRYPOINT [ "/bin/sh", "-c", "cd /src && make && make -j 1 check-coverage" ]
index d9e89357ca13ba0d92105a74338572cb528da3c5..2e55d57c3154984698350c1b3afe5c7d3e257407 100644 (file)
@@ -417,7 +417,8 @@ void eigrp_sw_version_initialize(void)
        if (dash)
                dash[0] = '\0';
 
-       ret = sscanf(ver_string, "%d.%d", &FRR_MAJOR, &FRR_MINOR);
+       ret = sscanf(ver_string, "%" SCNu32 ".%" SCNu32, &FRR_MAJOR,
+                    &FRR_MINOR);
        if (ret != 2)
                zlog_err("Did not Properly parse %s, please fix VERSION string",
                         VERSION);
index 129b5aedde5ff0f08ea94fb0c34645e72aaa62f8..027f30563f8a2516b49541c2c85c0ef0ce15b8c8 100644 (file)
@@ -725,12 +725,12 @@ static struct stream *eigrp_recv_packet(int fd, struct interface **ifp,
                zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno));
                return NULL;
        }
-       if ((unsigned int)ret < sizeof(iph)) /* ret must be > 0 now */
+       if ((unsigned int)ret < sizeof(*iph)) /* ret must be > 0 now */
        {
                zlog_warn(
                        "eigrp_recv_packet: discarding runt packet of length %d "
                        "(ip header size is %u)",
-                       ret, (unsigned int)sizeof(iph));
+                       ret, (unsigned int)sizeof(*iph));
                return NULL;
        }
 
index ed0a5407b2bf476fa6ecc42530cabf96d79e885a..91135055817fa1cb8b477383b554bfe2ef1c1888 100644 (file)
@@ -691,7 +691,8 @@ void                 embedscope(struct sockaddr_in6 *);
 void            recoverscope(struct sockaddr_in6 *);
 void            addscope(struct sockaddr_in6 *, uint32_t);
 void            clearscope(struct in6_addr *);
-struct sockaddr        *addr2sa(int af, union ldpd_addr *, uint16_t);
+void            addr2sa(int af, const union ldpd_addr *, uint16_t,
+                   union sockunion *su);
 void            sa2addr(struct sockaddr *, int *, union ldpd_addr *,
                    in_port_t *);
 socklen_t       sockaddr_len(struct sockaddr *);
index 1c3f650dff3baede6f9fb730b862d3603106f1ad..78a6131ca404f6e2f15a00c9cca73ee01988cbec 100644 (file)
@@ -584,8 +584,8 @@ nbr_connect_cb(struct thread *thread)
 int
 nbr_establish_connection(struct nbr *nbr)
 {
-       struct sockaddr_storage  local_sa;
-       struct sockaddr_storage  remote_sa;
+       union sockunion          local_su;
+       union sockunion          remote_su;
        struct adj              *adj;
        struct nbr_params       *nbrp;
 #ifdef __OpenBSD__
@@ -619,16 +619,14 @@ nbr_establish_connection(struct nbr *nbr)
 #endif
        }
 
-       memcpy(&local_sa, addr2sa(nbr->af, &nbr->laddr, 0), sizeof(local_sa));
-       memcpy(&remote_sa, addr2sa(nbr->af, &nbr->raddr, LDP_PORT),
-           sizeof(local_sa));
+       addr2sa(nbr->af, &nbr->laddr, 0, &local_su);
+       addr2sa(nbr->af, &nbr->raddr, LDP_PORT, &remote_su);
        if (nbr->af == AF_INET6 && nbr->raddr_scope)
-               addscope((struct sockaddr_in6 *)&remote_sa, nbr->raddr_scope);
+               addscope(&remote_su.sin6, nbr->raddr_scope);
 
-       if (bind(nbr->fd, (struct sockaddr *)&local_sa,
-           sockaddr_len((struct sockaddr *)&local_sa)) == -1) {
+       if (bind(nbr->fd, &local_su.sa, sockaddr_len(&local_su.sa)) == -1) {
                log_warn("%s: error while binding socket to %s", __func__,
-                   log_sockaddr((struct sockaddr *)&local_sa));
+                        log_sockaddr(&local_su.sa));
                close(nbr->fd);
                return (-1);
        }
@@ -646,15 +644,15 @@ nbr_establish_connection(struct nbr *nbr)
                send_hello(adj->source.type, adj->source.link.ia,
                    adj->source.target);
 
-       if (connect(nbr->fd, (struct sockaddr *)&remote_sa,
-           sockaddr_len((struct sockaddr *)&remote_sa)) == -1) {
+       if (connect(nbr->fd, &remote_su.sa, sockaddr_len(&remote_su.sa))
+           == -1) {
                if (errno == EINPROGRESS) {
                        thread_add_write(master, nbr_connect_cb, nbr, nbr->fd,
                                         &nbr->ev_connect);
                        return (0);
                }
                log_warn("%s: error while connecting to %s", __func__,
-                   log_sockaddr((struct sockaddr *)&remote_sa));
+                        log_sockaddr(&remote_su.sa));
                close(nbr->fd);
                return (-1);
        }
index b0f9c5eb14f8abadd7dcbf8129f6647610ff061d..8ca90841de82e57ce7ead41e2c6dc747016853ad 100644 (file)
@@ -70,7 +70,7 @@ int
 send_packet(int fd, int af, union ldpd_addr *dst, struct iface_af *ia,
     void *pkt, size_t len)
 {
-       struct sockaddr         *sa;
+       union sockunion su;
 
        switch (af) {
        case AF_INET:
@@ -97,10 +97,10 @@ send_packet(int fd, int af, union ldpd_addr *dst, struct iface_af *ia,
                fatalx("send_packet: unknown af");
        }
 
-       sa = addr2sa(af, dst, LDP_PORT);
-       if (sendto(fd, pkt, len, 0, sa, sockaddr_len(sa)) == -1) {
+       addr2sa(af, dst, LDP_PORT, &su);
+       if (sendto(fd, pkt, len, 0, &su.sa, sockaddr_len(&su.sa)) == -1) {
                log_warn("%s: error sending packet to %s", __func__,
-                   log_sockaddr(sa));
+                        log_sockaddr(&su.sa));
                return (-1);
        }
 
index a1a79dabfd359291611a7c776494da86c14af4b0..906737217c0e0513a7279b6658f9f9dde1e2ca22 100644 (file)
@@ -64,17 +64,17 @@ pfkey_send(int sd, uint8_t satype, uint8_t mtype, uint8_t dir,
        ssize_t                 n;
        int                     len = 0;
        int                     iov_cnt;
-       struct sockaddr_storage ssrc, sdst, smask, dmask;
-       struct sockaddr         *saptr;
+       struct sockaddr_storage smask, dmask;
+       union sockunion         su_src, su_dst;
 
        if (!pid)
                pid = getpid();
 
        /* we need clean sockaddr... no ports set */
-       memset(&ssrc, 0, sizeof(ssrc));
        memset(&smask, 0, sizeof(smask));
-       if ((saptr = addr2sa(af, src, 0)))
-               memcpy(&ssrc, saptr, sizeof(ssrc));
+
+       addr2sa(af, src, 0, &su_src);
+
        switch (af) {
        case AF_INET:
                memset(&((struct sockaddr_in *)&smask)->sin_addr, 0xff, 32/8);
@@ -86,13 +86,13 @@ pfkey_send(int sd, uint8_t satype, uint8_t mtype, uint8_t dir,
        default:
                return (-1);
        }
-       smask.ss_family = ssrc.ss_family;
-       smask.ss_len = ssrc.ss_len;
+       smask.ss_family = su_src.sa.sa_family;
+       smask.ss_len = sockaddr_len(&su_src.sa);
 
-       memset(&sdst, 0, sizeof(sdst));
        memset(&dmask, 0, sizeof(dmask));
-       if ((saptr = addr2sa(af, dst, 0)))
-               memcpy(&sdst, saptr, sizeof(sdst));
+
+       addr2sa(af, dst, 0, &su_dst);
+
        switch (af) {
        case AF_INET:
                memset(&((struct sockaddr_in *)&dmask)->sin_addr, 0xff, 32/8);
@@ -104,8 +104,8 @@ pfkey_send(int sd, uint8_t satype, uint8_t mtype, uint8_t dir,
        default:
                return (-1);
        }
-       dmask.ss_family = sdst.ss_family;
-       dmask.ss_len = sdst.ss_len;
+       dmask.ss_family = su_dst.sa.sa_family;
+       dmask.ss_len = sockaddr_len(&su_dst.sa);
 
        memset(&smsg, 0, sizeof(smsg));
        smsg.sadb_msg_version = PF_KEY_V2;
@@ -138,11 +138,13 @@ pfkey_send(int sd, uint8_t satype, uint8_t mtype, uint8_t dir,
 
        memset(&sa_src, 0, sizeof(sa_src));
        sa_src.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
-       sa_src.sadb_address_len = (sizeof(sa_src) + ROUNDUP(ssrc.ss_len)) / 8;
+       sa_src.sadb_address_len =
+               (sizeof(sa_src) + ROUNDUP(sockaddr_len(&su_src.sa))) / 8;
 
        memset(&sa_dst, 0, sizeof(sa_dst));
        sa_dst.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
-       sa_dst.sadb_address_len = (sizeof(sa_dst) + ROUNDUP(sdst.ss_len)) / 8;
+       sa_dst.sadb_address_len =
+               (sizeof(sa_dst) + ROUNDUP(sockaddr_len(&su_dst.sa))) / 8;
 
        sa.sadb_sa_auth = aalg;
        sa.sadb_sa_encrypt = SADB_X_EALG_AES; /* XXX */
@@ -195,8 +197,8 @@ pfkey_send(int sd, uint8_t satype, uint8_t mtype, uint8_t dir,
        iov[iov_cnt].iov_base = &sa_dst;
        iov[iov_cnt].iov_len = sizeof(sa_dst);
        iov_cnt++;
-       iov[iov_cnt].iov_base = &sdst;
-       iov[iov_cnt].iov_len = ROUNDUP(sdst.ss_len);
+       iov[iov_cnt].iov_base = &su_dst;
+       iov[iov_cnt].iov_len = ROUNDUP(sockaddr_len(&su_dst.sa));
        smsg.sadb_msg_len += sa_dst.sadb_address_len;
        iov_cnt++;
 
@@ -204,8 +206,8 @@ pfkey_send(int sd, uint8_t satype, uint8_t mtype, uint8_t dir,
        iov[iov_cnt].iov_base = &sa_src;
        iov[iov_cnt].iov_len = sizeof(sa_src);
        iov_cnt++;
-       iov[iov_cnt].iov_base = &ssrc;
-       iov[iov_cnt].iov_len = ROUNDUP(ssrc.ss_len);
+       iov[iov_cnt].iov_base = &su_src;
+       iov[iov_cnt].iov_len = ROUNDUP(sockaddr_len(&su_src.sa));
        smsg.sadb_msg_len += sa_src.sadb_address_len;
        iov_cnt++;
 
index eaea9973a015d237b40b6c84b80f96fe15a2e9e9..aefa3461a8781a42be5b3182f4ee155dc71452b9 100644 (file)
@@ -37,7 +37,7 @@ ldp_create_socket(int af, enum socket_type type)
 {
        int                      fd, domain, proto;
        union ldpd_addr          addr;
-       struct sockaddr_storage  local_sa;
+       union sockunion          local_su;
 #ifdef __OpenBSD__
        int                      opt;
 #endif
@@ -70,14 +70,12 @@ ldp_create_socket(int af, enum socket_type type)
        case LDP_SOCKET_DISC:
                /* listen on all addresses */
                memset(&addr, 0, sizeof(addr));
-               memcpy(&local_sa, addr2sa(af, &addr, LDP_PORT),
-                   sizeof(local_sa));
+               addr2sa(af, &addr, LDP_PORT, &local_su);
                break;
        case LDP_SOCKET_EDISC:
        case LDP_SOCKET_SESSION:
                addr = (ldp_af_conf_get(ldpd_conf, af))->trans_addr;
-               memcpy(&local_sa, addr2sa(af, &addr, LDP_PORT),
-                   sizeof(local_sa));
+               addr2sa(af, &addr, LDP_PORT, &local_su);
                /* ignore any possible error */
                sock_set_bindany(fd, 1);
                break;
@@ -90,8 +88,7 @@ ldp_create_socket(int af, enum socket_type type)
                close(fd);
                return (-1);
        }
-       if (bind(fd, (struct sockaddr *)&local_sa,
-           sockaddr_len((struct sockaddr *)&local_sa)) == -1) {
+       if (bind(fd, &local_su.sa, sockaddr_len(&local_su.sa)) == -1) {
                save_errno = errno;
                if (ldpd_privs.change(ZPRIVS_LOWER))
                        log_warn("%s: could not lower privs", __func__);
@@ -307,7 +304,7 @@ sock_set_md5sig(int fd, int af, union ldpd_addr *addr, const char *password)
        if (fd == -1)
                return (0);
 #if HAVE_DECL_TCP_MD5SIG
-       memcpy(&su, addr2sa(af, addr, 0), sizeof(su));
+       addr2sa(af, addr, 0, &su);
 
        if (ldpe_privs.change(ZPRIVS_RAISE)) {
                log_warn("%s: could not raise privs", __func__);
index e735263f5fdcd316cb575ce10756286ccf206edd..12f9cb0ccf94d580d5b1e259c5167be2d52564c8 100644 (file)
@@ -305,14 +305,13 @@ clearscope(struct in6_addr *in6)
        }
 }
 
-struct sockaddr *
-addr2sa(int af, union ldpd_addr *addr, uint16_t port)
+void
+addr2sa(int af, const union ldpd_addr *addr, uint16_t port, union sockunion *su)
 {
-       static struct sockaddr_storage   ss;
-       struct sockaddr_in              *sa_in = (struct sockaddr_in *)&ss;
-       struct sockaddr_in6             *sa_in6 = (struct sockaddr_in6 *)&ss;
+       struct sockaddr_in              *sa_in = &su->sin;
+       struct sockaddr_in6             *sa_in6 = &su->sin6;
 
-       memset(&ss, 0, sizeof(ss));
+       memset(su, 0, sizeof(*su));
        switch (af) {
        case AF_INET:
                sa_in->sin_family = AF_INET;
@@ -333,8 +332,6 @@ addr2sa(int af, union ldpd_addr *addr, uint16_t port)
        default:
                fatalx("addr2sa: unknown af");
        }
-
-       return ((struct sockaddr *)&ss);
 }
 
 void
index 37f6cdcc8f86a4c3d65e405131942fa2d1fe1367..ee5401b2367a4816111439863c3b67f1d8df51d7 100644 (file)
@@ -241,21 +241,15 @@ void hash_iterate(struct hash *hash, void (*func)(struct hash_backet *, void *),
        unsigned int i;
        struct hash_backet *hb;
        struct hash_backet *hbnext;
-       uint32_t count = 0;
 
-       for (i = 0; i < hash->size; i++) {
+       for (i = 0; i < hash->size; i++)
                for (hb = hash->index[i]; hb; hb = hbnext) {
                        /* get pointer to next hash backet here, in case (*func)
                         * decides to delete hb by calling hash_release
                         */
                        hbnext = hb->next;
                        (*func)(hb, arg);
-                       count++;
-
                }
-               if (count == hash->count)
-                       return;
-       }
 }
 
 void hash_walk(struct hash *hash, int (*func)(struct hash_backet *, void *),
@@ -265,7 +259,6 @@ void hash_walk(struct hash *hash, int (*func)(struct hash_backet *, void *),
        struct hash_backet *hb;
        struct hash_backet *hbnext;
        int ret = HASHWALK_CONTINUE;
-       uint32_t count = 0;
 
        for (i = 0; i < hash->size; i++) {
                for (hb = hash->index[i]; hb; hb = hbnext) {
@@ -276,10 +269,7 @@ void hash_walk(struct hash *hash, int (*func)(struct hash_backet *, void *),
                        ret = (*func)(hb, arg);
                        if (ret == HASHWALK_ABORT)
                                return;
-                       count++;
                }
-               if (count == hash->count)
-                       return;
        }
 }
 
index c7e670b7238affa725ae7c038d484fad5870de4c..12c214e469571d10f1360b9f9adba736c27a4d15 100644 (file)
@@ -232,7 +232,9 @@ extern void *hash_release(struct hash *hash, void *data);
  * Iterate over the elements in a hash table.
  *
  * It is safe to delete items passed to the iteration function from the hash
- * table during iteration.
+ * table during iteration.  Please note that adding entries to the hash
+ * during the walk will cause undefined behavior in that some new entries
+ * will be walked and some will not.  So do not do this.
  *
  * hash
  *    hash table to operate on
@@ -250,7 +252,9 @@ extern void hash_iterate(struct hash *hash,
  * Iterate over the elements in a hash table, stopping on condition.
  *
  * It is safe to delete items passed to the iteration function from the hash
- * table during iteration.
+ * table during iteration.  Please note that adding entries to the hash
+ * during the walk will cause undefined behavior in that some new entries
+ * will be walked and some will not.  So do not do this.
  *
  * hash
  *    hash table to operate on
index 2541e6e45affd5893f278a532c06c54eb8c298ec..2320093a15c6e6428d461c6ee8f4d9d3d831c725 100644 (file)
--- a/lib/if.c
+++ b/lib/if.c
@@ -222,18 +222,6 @@ struct interface *if_lookup_by_index(ifindex_t ifindex, vrf_id_t vrf_id)
        struct vrf *vrf;
        struct interface if_tmp;
 
-       if (vrf_id == VRF_UNKNOWN) {
-               struct interface *ifp;
-
-               RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
-                       ifp = if_lookup_by_index(ifindex, vrf->vrf_id);
-                       if (ifp)
-                               return ifp;
-               }
-
-               return NULL;
-       }
-
        vrf = vrf_lookup_by_id(vrf_id);
        if (!vrf)
                return NULL;
index a3fae8f39fab05a591a12acf35af9d9c1a651e77..a80b51fa007be00861dd032926ddb08b2e87034f 100644 (file)
@@ -435,10 +435,13 @@ char *ns_netns_pathname(struct vty *vty, const char *name)
 
        if (!result) {
                if (vty)
-                       vty_out(vty, "Invalid pathname: %s\n",
+                       vty_out(vty, "Invalid pathname for %s: %s\n",
+                               pathname,
                                safe_strerror(errno));
                else
-                       zlog_warn("Invalid pathname: %s", safe_strerror(errno));
+                       zlog_warn("Invalid pathname for %s: %s",
+                                 pathname,
+                                 safe_strerror(errno));
                return NULL;
        }
        check_base = basename(pathname);
index a44f4e35426e65f21b072d0347975d7a3fa43af5..473ecb34fc4df110bf0b3d27be0261f5e9a5ba21 100644 (file)
@@ -56,6 +56,11 @@ void copy_nexthops(struct nexthop **tnh, struct nexthop *nh,
        (nhop);                                                         \
        (nhop) = nexthop_next(nhop)
 
+#define ALL_NEXTHOPS_PTR(head, nhop)                                   \
+       (nhop) = ((head)->nexthop);                                     \
+       (nhop);                                                         \
+       (nhop) = nexthop_next(nhop)
+
 
 struct nexthop_hold {
        char *nhvrf_name;
index a70574cff2022e4cba51be92a462a574a45da7ce..32f8e8ca5b473d6c7eb21185edc00648ac6535ee 100644 (file)
@@ -127,7 +127,7 @@ route_table_delegate_t _srcdest_srcnode_delegate = {
 
 /* NB: read comments in code for refcounting before using! */
 static struct route_node *srcdest_srcnode_get(struct route_node *rn,
-                                             struct prefix_ipv6 *src_p)
+                                             const struct prefix_ipv6 *src_p)
 {
        struct srcdest_rnode *srn;
 
@@ -158,11 +158,12 @@ static struct route_node *srcdest_srcnode_get(struct route_node *rn,
                route_unlock_node(rn);
        }
 
-       return route_node_get(srn->src_table, (struct prefix *)src_p);
+       return route_node_get(srn->src_table, (const struct prefix *)src_p);
 }
 
-static struct route_node *srcdest_srcnode_lookup(struct route_node *rn,
-                                                struct prefix_ipv6 *src_p)
+static struct route_node *srcdest_srcnode_lookup(
+       struct route_node *rn,
+       const struct prefix_ipv6 *src_p)
 {
        struct srcdest_rnode *srn;
 
@@ -180,7 +181,7 @@ static struct route_node *srcdest_srcnode_lookup(struct route_node *rn,
        if (!srn->src_table)
                return NULL;
 
-       return route_node_lookup(srn->src_table, (struct prefix *)src_p);
+       return route_node_lookup(srn->src_table, (const struct prefix *)src_p);
 }
 
 /* ----- exported functions ----- */
@@ -233,25 +234,25 @@ struct route_node *srcdest_route_next(struct route_node *rn)
 }
 
 struct route_node *srcdest_rnode_get(struct route_table *table,
-                                    union prefixptr dst_pu,
-                                    struct prefix_ipv6 *src_p)
+                                    union prefixconstptr dst_pu,
+                                    const struct prefix_ipv6 *src_p)
 {
-       struct prefix_ipv6 *dst_p = dst_pu.p6;
+       const struct prefix_ipv6 *dst_p = dst_pu.p6;
        struct route_node *rn;
 
-       rn = route_node_get(table, (struct prefix *)dst_p);
+       rn = route_node_get(table, (const struct prefix *)dst_p);
        return srcdest_srcnode_get(rn, src_p);
 }
 
 struct route_node *srcdest_rnode_lookup(struct route_table *table,
-                                       union prefixptr dst_pu,
-                                       struct prefix_ipv6 *src_p)
+                                       union prefixconstptr dst_pu,
+                                       const struct prefix_ipv6 *src_p)
 {
-       struct prefix_ipv6 *dst_p = dst_pu.p6;
+       const struct prefix_ipv6 *dst_p = dst_pu.p6;
        struct route_node *rn;
        struct route_node *srn;
 
-       rn = route_node_lookup_maynull(table, (struct prefix *)dst_p);
+       rn = route_node_lookup_maynull(table, (const struct prefix *)dst_p);
        srn = srcdest_srcnode_lookup(rn, src_p);
 
        if (rn != NULL && rn == srn && !rn->info) {
@@ -263,8 +264,8 @@ struct route_node *srcdest_rnode_lookup(struct route_table *table,
        return srn;
 }
 
-void srcdest_rnode_prefixes(struct route_node *rn, struct prefix **p,
-                           struct prefix **src_p)
+void srcdest_rnode_prefixes(struct route_node *rn, const struct prefix **p,
+                           const struct prefix **src_p)
 {
        if (rnode_is_srcnode(rn)) {
                struct route_node *dst_rn = rn->table->info;
@@ -282,7 +283,7 @@ void srcdest_rnode_prefixes(struct route_node *rn, struct prefix **p,
 
 const char *srcdest_rnode2str(struct route_node *rn, char *str, int size)
 {
-       struct prefix *dst_p, *src_p;
+       const struct prefix *dst_p, *src_p;
        char dst_buf[PREFIX_STRLEN], src_buf[PREFIX_STRLEN];
 
        srcdest_rnode_prefixes(rn, &dst_p, &src_p);
index 669068a79b4f7ec095e6a2197e117bd5c143f0ba..5f97f02bacfd757707dba9b87eba39ebc8eddd80 100644 (file)
@@ -56,13 +56,14 @@ extern route_table_delegate_t _srcdest_srcnode_delegate;
 
 extern struct route_table *srcdest_table_init(void);
 extern struct route_node *srcdest_rnode_get(struct route_table *table,
-                                           union prefixptr dst_pu,
-                                           struct prefix_ipv6 *src_p);
+                                           union prefixconstptr dst_pu,
+                                           const struct prefix_ipv6 *src_p);
 extern struct route_node *srcdest_rnode_lookup(struct route_table *table,
-                                              union prefixptr dst_pu,
-                                              struct prefix_ipv6 *src_p);
-extern void srcdest_rnode_prefixes(struct route_node *rn, struct prefix **p,
-                                  struct prefix **src_p);
+                                              union prefixconstptr dst_pu,
+                                              const struct prefix_ipv6 *src_p);
+extern void srcdest_rnode_prefixes(struct route_node *rn,
+                                  const struct prefix **p,
+                                  const struct prefix **src_p);
 extern const char *srcdest_rnode2str(struct route_node *rn, char *str,
                                     int size);
 extern struct route_node *srcdest_route_next(struct route_node *rn);
index e9d1f2e323747eaf7879af78fb34b1e22513352e..073092dfb6470d762fbb44ec2583787c700bbac0 100644 (file)
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -479,6 +479,8 @@ static int vty_command(struct vty *vty, char *buf)
        const char *protocolname;
        char *cp = NULL;
 
+       assert(vty);
+
        /*
         * Log non empty command lines
         */
@@ -496,13 +498,13 @@ static int vty_command(struct vty *vty, char *buf)
 
                /* format the base vty info */
                snprintf(vty_str, sizeof(vty_str), "vty[??]@%s", vty->address);
-               if (vty)
-                       for (i = 0; i < vector_active(vtyvec); i++)
-                               if (vty == vector_slot(vtyvec, i)) {
-                                       snprintf(vty_str, sizeof(vty_str),
-                                                "vty[%d]@%s", i, vty->address);
-                                       break;
-                               }
+
+               for (i = 0; i < vector_active(vtyvec); i++)
+                       if (vty == vector_slot(vtyvec, i)) {
+                               snprintf(vty_str, sizeof(vty_str), "vty[%d]@%s",
+                                        i, vty->address);
+                               break;
+                       }
 
                /* format the prompt */
                snprintf(prompt_str, sizeof(prompt_str), cmd_prompt(vty->node),
index 1af51c06c130ab06c0989a21ce088c8999c0e9a2..39dd142afb9d69f3f837332b2932a0e69d2ad47a 100644 (file)
@@ -245,10 +245,11 @@ int work_queue_run(struct thread *thread)
        char yielded = 0;
 
        wq = THREAD_ARG(thread);
-       wq->thread = NULL;
 
        assert(wq);
 
+       wq->thread = NULL;
+
        /* calculate cycle granularity:
         * list iteration == 1 run
         * listnode processing == 1 cycle
index e7adc971e53f41c73a778d702a483c74ff02f6d7..7ca9731765d2d1c6691d0d869e2a1eb67f24ef85 100644 (file)
@@ -59,7 +59,7 @@ static void evmgr_recv_message(struct event_manager *evmgr, struct zbuf *zb)
                buf[len] = 0;
 
                debugf(NHRP_DEBUG_EVENT, "evmgr: msg: %s", buf);
-               if (sscanf(buf, "eventid=%d", &eventid) != 1)
+               if (sscanf(buf, "eventid=%" SCNu32, &eventid) != 1)
                        continue;
                if (sscanf(buf, "result=%63s", result) != 1)
                        continue;
index c27ebe1d902d17f204c8e8cf335f8fbc9770f602..e62ee1ef72206a17924c031a0d4281d85ce92c51 100644 (file)
@@ -164,7 +164,7 @@ struct nhrp_cie_header *nhrp_cie_pull(struct zbuf *zb,
        if (!cie)
                return NULL;
 
-       if (cie->nbma_address_len + cie->nbma_subaddress_len) {
+       if (cie->nbma_address_len + cie->nbma_subaddress_len > 0) {
                sockunion_set(nbma, afi2family(htons(hdr->afnum)),
                              zbuf_pulln(zb,
                                         cie->nbma_address_len
index 3bb0d8308ecbb94c1574eadbf57e7ca486985883..eb3827a12fdda935fea7773bd03999e0da29fc14 100644 (file)
@@ -306,7 +306,7 @@ static void vici_recv_message(struct vici_conn *vici, struct zbuf *msg)
        uint32_t msglen;
        uint8_t msgtype;
        struct blob name;
-       struct vici_message_ctx ctx;
+       struct vici_message_ctx ctx = { .nsections = 0 };
 
        msglen = zbuf_get_be32(msg);
        msgtype = zbuf_get8(msg);
index c799a4b30f9840e4bbb65f6a4934075af9ce6ada..d84fd26ac4af74b90d1e3f2640d9ed907cae964e 100644 (file)
@@ -543,7 +543,7 @@ static int ospf_ase_route_match_same(struct route_table *rt,
                                     struct ospf_route *newor)
 {
        struct route_node *rn;
-       struct ospf_route * or ;
+       struct ospf_route *or;
        struct ospf_path *op;
        struct ospf_path *newop;
        struct listnode *n1;
@@ -559,6 +559,9 @@ static int ospf_ase_route_match_same(struct route_table *rt,
        route_unlock_node(rn);
 
        or = rn->info;
+
+       assert(or);
+
        if (or->path_type != newor->path_type)
                return 0;
 
@@ -577,6 +580,8 @@ static int ospf_ase_route_match_same(struct route_table *rt,
                return 0;
        }
 
+       assert(or->paths);
+
        if (or->paths->count != newor->paths->count)
                return 0;
 
index 820b8921767f65955c8da8c267f71632f9e10b6e..002c6bba8d7023a52743955ed84b09466c538be5 100644 (file)
@@ -91,7 +91,7 @@ struct external_info *ospf_external_info_check(struct ospf *ospf,
        p.prefix = lsa->data->id;
        p.prefixlen = ip_masklen(al->mask);
 
-       for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
+       for (type = 0; type < ZEBRA_ROUTE_MAX; type++) {
                int redist_on = 0;
 
                redist_on =
index 729e50886554438c672652345ce9ef8a824cd2fb..502f23303640f4cd2b370eae68a647d86d5587e9 100644 (file)
@@ -1889,7 +1889,7 @@ struct ospf_lsa *ospf_translated_nssa_refresh(struct ospf *ospf,
                        zlog_debug(
                                "ospf_translated_nssa_refresh(): no Type-7 found for "
                                "Type-5 LSA Id %s",
-                               inet_ntoa(type5->data->id));
+                               type5 ? inet_ntoa(type5->data->id) : "(null)");
                return NULL;
        }
 
@@ -1899,7 +1899,7 @@ struct ospf_lsa *ospf_translated_nssa_refresh(struct ospf *ospf,
                        zlog_debug(
                                "ospf_translated_nssa_refresh(): No translated Type-5 "
                                "found for Type-7 with Id %s",
-                               inet_ntoa(type7->data->id));
+                               type7 ? inet_ntoa(type7->data->id) : "(null)");
                return NULL;
        }
 
@@ -1912,7 +1912,7 @@ struct ospf_lsa *ospf_translated_nssa_refresh(struct ospf *ospf,
                        zlog_debug(
                                "ospf_translated_nssa_refresh(): Could not translate "
                                "Type-7 for %s to Type-5",
-                               inet_ntoa(type7->data->id));
+                               type7 ? inet_ntoa(type7->data->id) : "(null)");
                return NULL;
        }
 
@@ -1921,7 +1921,7 @@ struct ospf_lsa *ospf_translated_nssa_refresh(struct ospf *ospf,
                        zlog_debug(
                                "ospf_translated_nssa_refresh(): Could not install "
                                "translated LSA, Id %s",
-                               inet_ntoa(type7->data->id));
+                               type7 ? inet_ntoa(type7->data->id) : "(null)");
                return NULL;
        }
 
index 93267156f2f9381b53d4c823d9ed73ff9598ca95..fa7dd04d19f800f6a48a408a7eb8fbb7330dff1a 100644 (file)
@@ -1649,7 +1649,7 @@ DEFUN (pce_domain,
        if (!ospf_ri_enabled(vty))
                return CMD_WARNING_CONFIG_FAILED;
 
-       if (sscanf(argv[idx_number]->arg, "%d", &as) != 1) {
+       if (sscanf(argv[idx_number]->arg, "%" SCNu32, &as) != 1) {
                vty_out(vty, "pce_domain: fscanf: %s\n", safe_strerror(errno));
                return CMD_WARNING_CONFIG_FAILED;
        }
@@ -1684,7 +1684,7 @@ DEFUN (no_pce_domain,
        uint32_t as;
        struct ospf_pce_info *pce = &OspfRI.pce_info;
 
-       if (sscanf(argv[idx_number]->arg, "%d", &as) != 1) {
+       if (sscanf(argv[idx_number]->arg, "%" SCNu32, &as) != 1) {
                vty_out(vty, "no_pce_domain: fscanf: %s\n",
                        safe_strerror(errno));
                return CMD_WARNING_CONFIG_FAILED;
@@ -1718,7 +1718,7 @@ DEFUN (pce_neigbhor,
        if (!ospf_ri_enabled(vty))
                return CMD_WARNING_CONFIG_FAILED;
 
-       if (sscanf(argv[idx_number]->arg, "%d", &as) != 1) {
+       if (sscanf(argv[idx_number]->arg, "%" SCNu32, &as) != 1) {
                vty_out(vty, "pce_neighbor: fscanf: %s\n",
                        safe_strerror(errno));
                return CMD_WARNING_CONFIG_FAILED;
@@ -1754,7 +1754,7 @@ DEFUN (no_pce_neighbor,
        uint32_t as;
        struct ospf_pce_info *pce = &OspfRI.pce_info;
 
-       if (sscanf(argv[idx_number]->arg, "%d", &as) != 1) {
+       if (sscanf(argv[idx_number]->arg, "%" SCNu32, &as) != 1) {
                vty_out(vty, "no_pce_neighbor: fscanf: %s\n",
                        safe_strerror(errno));
                return CMD_WARNING_CONFIG_FAILED;
index ddf9133ed96ff30ae1dc3c50e6af8990904a18e3..fb9770d09ad9e7842c107a18558f1158ce490d68 100644 (file)
@@ -2336,27 +2336,6 @@ DEFUN (no_ospf_timers_lsa_min_arrival,
        return CMD_SUCCESS;
 }
 
-#if defined(VERSION_TYPE_DEV) && CONFDATE > 20180708
-CPP_NOTICE("ospf: `timers lsa arrival (0-1000)` deprecated 2017/07/08")
-#endif
-ALIAS_HIDDEN(ospf_timers_lsa_min_arrival, ospf_timers_lsa_arrival_cmd,
-            "timers lsa arrival (0-1000)",
-            "adjust routing timers\n"
-            "throttling link state advertisement delays\n"
-            "ospf minimum arrival interval delay\n"
-            "delay (msec) between accepted lsas\n");
-
-#if defined(VERSION_TYPE_DEV) && CONFDATE > 20180708
-CPP_NOTICE("ospf: `no timers lsa arrival (0-1000)` deprecated 2017/07/08")
-#endif
-ALIAS_HIDDEN(no_ospf_timers_lsa_min_arrival, no_ospf_timers_lsa_arrival_cmd,
-            "no timers lsa arrival (0-1000)", NO_STR
-            "adjust routing timers\n"
-            "throttling link state advertisement delays\n"
-            "ospf minimum arrival interval delay\n"
-            "delay (msec) between accepted lsas\n");
-
-
 DEFUN (ospf_neighbor,
        ospf_neighbor_cmd,
        "neighbor A.B.C.D [priority (0-255) [poll-interval (1-65535)]]",
@@ -4809,16 +4788,19 @@ static void show_ip_ospf_nbr_nbma_detail_sub(struct vty *vty,
                vty_out(vty, "    Poll interval %d\n", nbr_nbma->v_poll);
 
        /* Show poll-interval timer. */
-       if (use_json) {
-               long time_store;
-               time_store = monotime_until(&nbr_nbma->t_poll->u.sands, NULL)
-                            / 1000LL;
-               json_object_int_add(json_sub, "pollIntervalTimerDueMsec",
-                                   time_store);
-       } else
-               vty_out(vty, "    Poll timer due in %s\n",
-                       ospf_timer_dump(nbr_nbma->t_poll, timebuf,
-                                       sizeof(timebuf)));
+       if (nbr_nbma->t_poll) {
+               if (use_json) {
+                       long time_store;
+                       time_store = monotime_until(&nbr_nbma->t_poll->u.sands,
+                                                   NULL) / 1000LL;
+                       json_object_int_add(json_sub,
+                                           "pollIntervalTimerDueMsec",
+                                           time_store);
+               } else
+                       vty_out(vty, "    Poll timer due in %s\n",
+                               ospf_timer_dump(nbr_nbma->t_poll, timebuf,
+                                               sizeof(timebuf)));
+       }
 
        /* Show poll-interval timer thread. */
        if (use_json) {
@@ -10658,8 +10640,6 @@ void ospf_vty_init(void)
        install_element(OSPF_NODE, &no_ospf_timers_min_ls_interval_cmd);
        install_element(OSPF_NODE, &ospf_timers_lsa_min_arrival_cmd);
        install_element(OSPF_NODE, &no_ospf_timers_lsa_min_arrival_cmd);
-       install_element(OSPF_NODE, &ospf_timers_lsa_arrival_cmd);
-       install_element(OSPF_NODE, &no_ospf_timers_lsa_arrival_cmd);
 
        /* refresh timer commands */
        install_element(OSPF_NODE, &ospf_refresh_timer_cmd);
index a66da87e1b0175208303d4bc63ecf10d3a168fbc..b4bf6bada34b256c4ef2eab050cdce6c1a05fbd9 100644 (file)
@@ -489,7 +489,6 @@ int rtnl_listen(struct rtnl_handle *rtnl, rtnl_filter_t handler, void *jarg)
 
 int rtnl_from_file(FILE *rtnl, rtnl_filter_t handler, void *jarg)
 {
-       int status;
        struct sockaddr_nl nladdr;
        char buf[8192];
        struct nlmsghdr *h = (void *)buf;
@@ -500,37 +499,43 @@ int rtnl_from_file(FILE *rtnl, rtnl_filter_t handler, void *jarg)
        nladdr.nl_groups = 0;
 
        while (1) {
-               int err, len;
-               int l;
+               int err;
+               size_t l, rl, arl;
 
-               status = fread(&buf, 1, sizeof(*h), rtnl);
+               rl = sizeof(*h);
+               arl = fread(&buf, 1, rl, rtnl);
 
-               if (status < 0) {
-                       if (errno == EINTR)
-                               continue;
-                       perror("rtnl_from_file: fread");
+               if (arl != rl) {
+                       if (arl == 0)
+                               return 0;
+
+                       if (ferror(rtnl))
+                               fprintf(stderr, "%s: header read failed\n",
+                                       __func__);
+                       else
+                               fprintf(stderr, "%s: truncated header\n",
+                                       __func__);
                        return -1;
                }
-               if (status == 0)
-                       return 0;
 
-               len = h->nlmsg_len;
-               l = len - sizeof(*h);
+               l = h->nlmsg_len > rl ? h->nlmsg_len - rl : 0;
 
-               if (l < 0 || len > (int)sizeof(buf)) {
-                       fprintf(stderr, "!!!malformed message: len=%d @%lu\n",
-                               len, ftell(rtnl));
+               if (l == 0 || (l + (size_t)NLMSG_HDRLEN) > sizeof(buf)) {
+                       fprintf(stderr, "%s: malformed message: len=%zu @%lu\n",
+                               __func__, (size_t)h->nlmsg_len, ftell(rtnl));
                        return -1;
                }
 
-               status = fread(NLMSG_DATA(h), 1, NLMSG_ALIGN(l), rtnl);
+               rl = NLMSG_ALIGN(l);
+               arl = fread(NLMSG_DATA(h), 1, rl, rtnl);
 
-               if (status < 0) {
-                       perror("rtnl_from_file: fread");
-                       return -1;
-               }
-               if (status < l) {
-                       fprintf(stderr, "rtnl-from_file: truncated message\n");
+               if (arl != rl) {
+                       if (ferror(rtnl))
+                               fprintf(stderr, "%s: msg read failed\n",
+                                       __func__);
+                       else
+                               fprintf(stderr, "%s: truncated message\n",
+                                       __func__);
                        return -1;
                }
 
index f297b0591db7fb3230ef8da086238b07c30e5591..6184ea12c416706a7b6339d8e21c0212ba525a10 100644 (file)
@@ -64,10 +64,6 @@ void pim_br_set_pmbr(struct prefix_sg *sg, struct in_addr br)
 
        if (!pim_br) {
                pim_br = XCALLOC(MTYPE_PIM_BR, sizeof(*pim_br));
-               if (!pim_br) {
-                       zlog_err("PIM XCALLOC(%zu) failure", sizeof(*pim_br));
-                       return;
-               }
 
                pim_br->sg = *sg;
 
@@ -100,9 +96,4 @@ void pim_br_clear_pmbr(struct prefix_sg *sg)
 void pim_br_init(void)
 {
        pim_br_list = list_new();
-       if (!pim_br_list) {
-               zlog_err("%s: Failure to create pim_br_list",
-                        __PRETTY_FUNCTION__);
-               return;
-       }
 }
index 123c47568cb0a5b6ec61b4c6cb7a05a877901f37..ae2daf40aa709834126c393e9fd4027937ca3a60 100644 (file)
@@ -2038,7 +2038,7 @@ static void pim_show_state(struct pim_instance *pim, struct vty *vty,
                } else {
                        vty_out(vty, "%-9d %-15s  %-15s  %-7s  ",
                                c_oil->installed, src_str, grp_str,
-                               ifp_in->name);
+                               in_ifname);
                }
 
                for (oif_vif_index = 0; oif_vif_index < MAXVIFS;
index 5c4d99ad4d0099e032d4eeb1f2556a0849dbcdcd..e075ff5ac29cbf1abf5d3296da624fb8f003eea6 100644 (file)
@@ -75,36 +75,6 @@ void pim_if_terminate(struct pim_instance *pim)
        return;
 }
 
-static void *if_list_clean(struct pim_interface *pim_ifp)
-{
-       struct pim_ifchannel *ch;
-
-       if (pim_ifp->igmp_join_list)
-               list_delete_and_null(&pim_ifp->igmp_join_list);
-
-       if (pim_ifp->igmp_socket_list)
-               list_delete_and_null(&pim_ifp->igmp_socket_list);
-
-       if (pim_ifp->pim_neighbor_list)
-               list_delete_and_null(&pim_ifp->pim_neighbor_list);
-
-       if (pim_ifp->upstream_switch_list)
-               list_delete_and_null(&pim_ifp->upstream_switch_list);
-
-       if (pim_ifp->sec_addr_list)
-               list_delete_and_null(&pim_ifp->sec_addr_list);
-
-       while (!RB_EMPTY(pim_ifchannel_rb, &pim_ifp->ifchannel_rb)) {
-               ch = RB_ROOT(pim_ifchannel_rb, &pim_ifp->ifchannel_rb);
-
-               pim_ifchannel_delete(ch);
-       }
-
-       XFREE(MTYPE_PIM_INTERFACE, pim_ifp);
-
-       return 0;
-}
-
 static void pim_sec_addr_free(struct pim_secondary_addr *sec_addr)
 {
        XFREE(MTYPE_PIM_SEC_ADDR, sec_addr);
@@ -145,10 +115,6 @@ struct pim_interface *pim_if_new(struct interface *ifp, int igmp, int pim)
        zassert(!ifp->info);
 
        pim_ifp = XCALLOC(MTYPE_PIM_INTERFACE, sizeof(*pim_ifp));
-       if (!pim_ifp) {
-               zlog_err("PIM XCALLOC(%zu) failure", sizeof(*pim_ifp));
-               return 0;
-       }
 
        pim_ifp->options = 0;
        pim_ifp->pim = pim_get_pim_instance(ifp->vrf_id);
@@ -186,38 +152,18 @@ struct pim_interface *pim_if_new(struct interface *ifp, int igmp, int pim)
 
        /* list of struct igmp_sock */
        pim_ifp->igmp_socket_list = list_new();
-       if (!pim_ifp->igmp_socket_list) {
-               zlog_err("%s: failure: igmp_socket_list=list_new()",
-                        __PRETTY_FUNCTION__);
-               return if_list_clean(pim_ifp);
-       }
        pim_ifp->igmp_socket_list->del = (void (*)(void *))igmp_sock_free;
 
        /* list of struct pim_neighbor */
        pim_ifp->pim_neighbor_list = list_new();
-       if (!pim_ifp->pim_neighbor_list) {
-               zlog_err("%s: failure: pim_neighbor_list=list_new()",
-                        __PRETTY_FUNCTION__);
-               return if_list_clean(pim_ifp);
-       }
        pim_ifp->pim_neighbor_list->del = (void (*)(void *))pim_neighbor_free;
 
        pim_ifp->upstream_switch_list = list_new();
-       if (!pim_ifp->upstream_switch_list) {
-               zlog_err("%s: failure: upstream_switch_list=list_new()",
-                        __PRETTY_FUNCTION__);
-               return if_list_clean(pim_ifp);
-       }
        pim_ifp->upstream_switch_list->del =
                (void (*)(void *))pim_jp_agg_group_list_free;
        pim_ifp->upstream_switch_list->cmp = pim_jp_agg_group_list_cmp;
 
        pim_ifp->sec_addr_list = list_new();
-       if (!pim_ifp->sec_addr_list) {
-               zlog_err("%s: failure: secondary addresslist",
-                        __PRETTY_FUNCTION__);
-               return if_list_clean(pim_ifp);
-       }
        pim_ifp->sec_addr_list->del = (void (*)(void *))pim_sec_addr_free;
        pim_ifp->sec_addr_list->cmp =
                (int (*)(void *, void *))pim_sec_addr_comp;
@@ -404,8 +350,6 @@ static int pim_sec_addr_add(struct pim_interface *pim_ifp, struct prefix *addr)
        }
 
        sec_addr = XCALLOC(MTYPE_PIM_SEC_ADDR, sizeof(*sec_addr));
-       if (!sec_addr)
-               return changed;
 
        changed = 1;
        sec_addr->addr = *addr;
@@ -1286,20 +1230,6 @@ static struct igmp_join *igmp_join_new(struct interface *ifp,
        }
 
        ij = XCALLOC(MTYPE_PIM_IGMP_JOIN, sizeof(*ij));
-       if (!ij) {
-               char group_str[INET_ADDRSTRLEN];
-               char source_str[INET_ADDRSTRLEN];
-               pim_inet4_dump("<grp?>", group_addr, group_str,
-                              sizeof(group_str));
-               pim_inet4_dump("<src?>", source_addr, source_str,
-                              sizeof(source_str));
-               zlog_err(
-                       "%s: XCALLOC(%zu) failure for IGMP group %s source %s on interface %s",
-                       __PRETTY_FUNCTION__, sizeof(*ij), group_str, source_str,
-                       ifp->name);
-               close(join_fd);
-               return 0;
-       }
 
        ij->sock_fd = join_fd;
        ij->group_addr = group_addr;
@@ -1325,9 +1255,6 @@ ferr_r pim_if_igmp_join_add(struct interface *ifp, struct in_addr group_addr,
 
        if (!pim_ifp->igmp_join_list) {
                pim_ifp->igmp_join_list = list_new();
-               if (!pim_ifp->igmp_join_list) {
-                       return ferr_cfg_invalid("Insufficient memory");
-               }
                pim_ifp->igmp_join_list->del = (void (*)(void *))igmp_join_free;
        }
 
index 6c347a430ff3cd6634504cca7825c03b8e05634d..eb3307589ec0b826e8470974157a3385c44dd77a 100644 (file)
@@ -519,12 +519,6 @@ struct pim_ifchannel *pim_ifchannel_add(struct interface *ifp,
        pim_ifp = ifp->info;
 
        ch = XCALLOC(MTYPE_PIM_IFCHANNEL, sizeof(*ch));
-       if (!ch) {
-               zlog_warn(
-                       "%s: pim_ifchannel_new() failure for (S,G)=%s on interface %s",
-                       __PRETTY_FUNCTION__, pim_str_sg_dump(sg), ifp->name);
-               return NULL;
-       }
 
        ch->flags = 0;
        if ((source_flags & PIM_ENCODE_RPT_BIT)
index 92993ff1b968838d52f39170c0523ca004bc9112..b46f1b5e9dde1870297c7fcb633d64bcc2a3fa83 100644 (file)
@@ -860,18 +860,8 @@ static struct igmp_sock *igmp_sock_new(int fd, struct in_addr ifaddr,
        }
 
        igmp = XCALLOC(MTYPE_PIM_IGMP_SOCKET, sizeof(*igmp));
-       if (!igmp) {
-               zlog_warn("%s %s: XCALLOC() failure", __FILE__,
-                         __PRETTY_FUNCTION__);
-               return 0;
-       }
 
        igmp->igmp_group_list = list_new();
-       if (!igmp->igmp_group_list) {
-               zlog_err("%s %s: failure: igmp_group_list = list_new()",
-                        __FILE__, __PRETTY_FUNCTION__);
-               return 0;
-       }
        igmp->igmp_group_list->del = (void (*)(void *))igmp_group_free;
 
        snprintf(hash_name, 64, "IGMP %s hash", ifp->name);
@@ -1129,19 +1119,8 @@ struct igmp_group *igmp_add_group_by_addr(struct igmp_sock *igmp,
        */
 
        group = XCALLOC(MTYPE_PIM_IGMP_GROUP, sizeof(*group));
-       if (!group) {
-               zlog_warn("%s %s: XCALLOC() failure", __FILE__,
-                         __PRETTY_FUNCTION__);
-               return NULL; /* error, not found, could not create */
-       }
 
        group->group_source_list = list_new();
-       if (!group->group_source_list) {
-               zlog_warn("%s %s: list_new() failure", __FILE__,
-                         __PRETTY_FUNCTION__);
-               XFREE(MTYPE_PIM_IGMP_GROUP, group); /* discard group */
-               return NULL; /* error, not found, could not initialize */
-       }
        group->group_source_list->del = (void (*)(void *))igmp_source_free;
 
        group->t_group_timer = NULL;
index 5ccad39b3356e32cbc60841881139f933702a9d0..b32d71cc0d216ec6ad56cd03c46e5514b08ac8c7 100644 (file)
@@ -457,11 +457,6 @@ struct igmp_source *source_new(struct igmp_group *group,
        }
 
        src = XCALLOC(MTYPE_PIM_IGMP_GROUP_SOURCE, sizeof(*src));
-       if (!src) {
-               zlog_warn("%s %s: XCALLOC() failure", __FILE__,
-                         __PRETTY_FUNCTION__);
-               return 0; /* error, not found, could not create */
-       }
 
        src->t_source_timer = NULL;
        src->source_group = group; /* back pointer */
index cb70ee79046f888aaf41d468e414bcf53d02546a..5121dc94ca278c6dd885ca2a9f9c60ad40e11df7 100644 (file)
@@ -69,8 +69,6 @@ static struct pim_instance *pim_instance_init(struct vrf *vrf)
        char hash_name[64];
 
        pim = XCALLOC(MTYPE_PIM_PIM_INSTANCE, sizeof(struct pim_instance));
-       if (!pim)
-               return NULL;
 
        pim_if_init(pim);
 
@@ -102,12 +100,6 @@ static struct pim_instance *pim_instance_init(struct vrf *vrf)
        }
 
        pim->static_routes = list_new();
-       if (!pim->static_routes) {
-               zlog_err("%s %s: failure: static_routes=list_new()", __FILE__,
-                        __PRETTY_FUNCTION__);
-               pim_instance_terminate(pim);
-               return NULL;
-       }
        pim->static_routes->del = (void (*)(void *))pim_static_route_free;
 
        pim->send_v6_secondary = 1;
index e87dfbca95b89b1e9aac68ce1668b0636ea858ff..c5f5b9c5e0960d846d2fcef0552d89c0dff34c9b 100644 (file)
@@ -329,7 +329,6 @@ void pim_jp_agg_single_upstream_send(struct pim_rpf *rpf,
 
        if (first) {
                groups = list_new();
-
                jag.sources = list_new();
 
                listnode_add(groups, &jag);
index 8462a4fdf8d6a20ea311d007dd9238017677ef59..dd306784055a04d0bbc0e9a0b50c7914f268f187 100644 (file)
@@ -152,13 +152,13 @@ static int pim_mroute_msg_nocache(int fd, struct interface *ifp,
        struct pim_rpf *rpg;
        struct prefix_sg sg;
 
-       rpg = RP(pim_ifp->pim, msg->im_dst);
+       rpg = pim_ifp ? RP(pim_ifp->pim, msg->im_dst) : NULL;
        /*
         * If the incoming interface is unknown OR
         * the Interface type is SSM we don't need to
         * do anything here
         */
-       if ((pim_rpf_addr_is_inaddr_none(rpg)) || (!pim_ifp)
+       if (!rpg || (pim_rpf_addr_is_inaddr_none(rpg))
            || (!(PIM_I_am_DR(pim_ifp)))) {
                if (PIM_DEBUG_MROUTE_DETAIL)
                        zlog_debug(
@@ -278,7 +278,7 @@ static int pim_mroute_msg_wholepkt(int fd, struct interface *ifp,
 
        pim_ifp = up->rpf.source_nexthop.interface->info;
 
-       rpg = RP(pim_ifp->pim, sg.grp);
+       rpg = pim_ifp ? RP(pim_ifp->pim, sg.grp) : NULL;
 
        if ((pim_rpf_addr_is_inaddr_none(rpg)) || (!pim_ifp)
            || (!(PIM_I_am_DR(pim_ifp)))) {
index e798d70a51122c9fb5f954349fe6359302c4461f..951e743494a8f290ea6b806b4252e15a4c04dc1e 100644 (file)
@@ -240,11 +240,6 @@ static struct pim_msdp_sa *pim_msdp_sa_new(struct pim_instance *pim,
        struct pim_msdp_sa *sa;
 
        sa = XCALLOC(MTYPE_PIM_MSDP_SA, sizeof(*sa));
-       if (!sa) {
-               zlog_err("%s: PIM XCALLOC(%zu) failure", __PRETTY_FUNCTION__,
-                        sizeof(*sa));
-               return NULL;
-       }
 
        sa->pim = pim;
        sa->sg = *sg;
@@ -1069,11 +1064,6 @@ static enum pim_msdp_err pim_msdp_peer_new(struct pim_instance *pim,
        pim_msdp_enable(pim);
 
        mp = XCALLOC(MTYPE_PIM_MSDP_PEER, sizeof(*mp));
-       if (!mp) {
-               zlog_err("%s: PIM XCALLOC(%zu) failure", __PRETTY_FUNCTION__,
-                        sizeof(*mp));
-               return PIM_MSDP_ERR_OOM;
-       }
 
        mp->pim = pim;
        mp->peer = peer_addr;
@@ -1277,11 +1267,6 @@ static struct pim_msdp_mg *pim_msdp_mg_new(const char *mesh_group_name)
        struct pim_msdp_mg *mg;
 
        mg = XCALLOC(MTYPE_PIM_MSDP_MG, sizeof(*mg));
-       if (!mg) {
-               zlog_err("%s: PIM XCALLOC(%zu) failure", __PRETTY_FUNCTION__,
-                        sizeof(*mg));
-               return NULL;
-       }
 
        mg->mesh_group_name = XSTRDUP(MTYPE_PIM_MSDP_MG_NAME, mesh_group_name);
        mg->mbr_list = list_new();
@@ -1395,13 +1380,6 @@ enum pim_msdp_err pim_msdp_mg_mbr_add(struct pim_instance *pim,
        }
 
        mbr = XCALLOC(MTYPE_PIM_MSDP_MG_MBR, sizeof(*mbr));
-       if (!mbr) {
-               zlog_err("%s: PIM XCALLOC(%zu) failure", __PRETTY_FUNCTION__,
-                        sizeof(*mbr));
-               /* if there are no references to the mg free it */
-               pim_msdp_mg_free(pim, mg);
-               return PIM_MSDP_ERR_OOM;
-       }
        mbr->mbr_ip = mbr_ip;
        listnode_add_sort(mg->mbr_list, mbr);
 
index 20a942b4fdfd9d571f274d2a016812120be4f288..2730f5e7aa36c86095966703b54ac346f0a558b4 100644 (file)
@@ -305,11 +305,6 @@ pim_neighbor_new(struct interface *ifp, struct in_addr source_addr,
        zassert(pim_ifp);
 
        neigh = XCALLOC(MTYPE_PIM_NEIGHBOR, sizeof(*neigh));
-       if (!neigh) {
-               zlog_err("%s: PIM XCALLOC(%zu) failure", __PRETTY_FUNCTION__,
-                        sizeof(*neigh));
-               return 0;
-       }
 
        neigh->creation = pim_time_monotonic_sec();
        neigh->source_addr = source_addr;
index d0fa90f0db71b583083c378064c171f9e8efee11..ac49373da07a07fccc7c1508ebcc7b91c4983b7a 100644 (file)
@@ -92,10 +92,6 @@ static struct pim_nexthop_cache *pim_nexthop_cache_add(struct pim_instance *pim,
 
        pnc = XCALLOC(MTYPE_PIM_NEXTHOP_CACHE,
                      sizeof(struct pim_nexthop_cache));
-       if (!pnc) {
-               zlog_err("%s: NHT PIM XCALLOC failure ", __PRETTY_FUNCTION__);
-               return NULL;
-       }
        pnc->rpf.rpf_addr.family = rpf_addr->rpf_addr.family;
        pnc->rpf.rpf_addr.prefixlen = rpf_addr->rpf_addr.prefixlen;
        pnc->rpf.rpf_addr.u.prefix4.s_addr =
@@ -140,14 +136,6 @@ int pim_find_or_track_nexthop(struct pim_instance *pim, struct prefix *addr,
        pnc = pim_nexthop_cache_find(pim, &rpf);
        if (!pnc) {
                pnc = pim_nexthop_cache_add(pim, &rpf);
-               if (!pnc) {
-                       char rpf_str[PREFIX_STRLEN];
-                       pim_addr_dump("<nht-pnc?>", addr, rpf_str,
-                                     sizeof(rpf_str));
-                       zlog_warn("%s: pnc node allocation failed. addr %s ",
-                                 __PRETTY_FUNCTION__, rpf_str);
-                       return 0;
-               }
                pim_sendmsg_zebra_rnh(pim, zclient, pnc,
                                      ZEBRA_NEXTHOP_REGISTER);
                if (PIM_DEBUG_PIM_NHT) {
index d49484f869f91fdb8c325e9017d431a9a0ea32e4..f0f336fb7308ccbfb02330fa8f31235d313b93ef 100644 (file)
@@ -107,11 +107,6 @@ void pim_oil_init(struct pim_instance *pim)
                                                 pim_oil_equal, hash_name);
 
        pim->channel_oil_list = list_new();
-       if (!pim->channel_oil_list) {
-               zlog_err("%s %s: failure: channel_oil_list=list_new()",
-                        __FILE__, __PRETTY_FUNCTION__);
-               return;
-       }
        pim->channel_oil_list->del = (void (*)(void *))pim_channel_oil_free;
        pim->channel_oil_list->cmp =
                (int (*)(void *, void *))pim_channel_oil_compare;
@@ -182,10 +177,6 @@ struct channel_oil *pim_channel_oil_add(struct pim_instance *pim,
        }
 
        c_oil = XCALLOC(MTYPE_PIM_CHANNEL_OIL, sizeof(*c_oil));
-       if (!c_oil) {
-               zlog_err("PIM XCALLOC(%zu) failure", sizeof(*c_oil));
-               return NULL;
-       }
 
        c_oil->oil.mfcc_mcastgrp = sg->grp;
        c_oil->oil.mfcc_origin = sg->src;
index a8cf58cd363df3242b1f6c76940d651027b973bb..7e053d2aa01c36c8293951dbe99900a59bd2c049 100644 (file)
@@ -115,13 +115,6 @@ void pim_rp_init(struct pim_instance *pim)
 
        rp_info = XCALLOC(MTYPE_PIM_RP, sizeof(*rp_info));
 
-       if (!rp_info) {
-               zlog_err("Unable to alloc rp_info");
-               route_table_finish(pim->rp_table);
-               list_delete_and_null(&pim->rp_list);
-               return;
-       }
-
        if (!str2prefix("224.0.0.0/4", &rp_info->group)) {
                zlog_err("Unable to convert 224.0.0.0/4 to prefix");
                list_delete_and_null(&pim->rp_list);
@@ -365,8 +358,6 @@ int pim_rp_new(struct pim_instance *pim, const char *rp,
        struct route_node *rn;
 
        rp_info = XCALLOC(MTYPE_PIM_RP, sizeof(*rp_info));
-       if (!rp_info)
-               return PIM_MALLOC_FAIL;
 
        if (group_range == NULL)
                result = str2prefix("224.0.0.0/4", &rp_info->group);
@@ -534,12 +525,6 @@ int pim_rp_new(struct pim_instance *pim, const char *rp,
 
        listnode_add_sort(pim->rp_list, rp_info);
        rn = route_node_get(pim->rp_table, &rp_info->group);
-       if (!rn) {
-               char buf[PREFIX_STRLEN];
-               zlog_err("Failure to get route node for pim->rp_table: %s",
-                        prefix2str(&rp_info->group, buf, sizeof(buf)));
-               return PIM_MALLOC_FAIL;
-       }
        rn->info = rp_info;
 
        if (PIM_DEBUG_TRACE) {
index 8e7da0f121e86c60bf3ac4c221776795854fec9c..bdf303d5c565faadb816725cde2ac08d30a6f776 100644 (file)
@@ -348,12 +348,6 @@ static struct ssmpingd_sock *ssmpingd_new(struct pim_instance *pim,
 
        if (!pim->ssmpingd_list) {
                pim->ssmpingd_list = list_new();
-               if (!pim->ssmpingd_list) {
-                       zlog_err(
-                               "%s %s: failure: qpim_ssmpingd_list=list_new()",
-                               __FILE__, __PRETTY_FUNCTION__);
-                       return 0;
-               }
                pim->ssmpingd_list->del = (void (*)(void *))ssmpingd_free;
        }
 
@@ -369,15 +363,6 @@ static struct ssmpingd_sock *ssmpingd_new(struct pim_instance *pim,
        }
 
        ss = XCALLOC(MTYPE_PIM_SSMPINGD, sizeof(*ss));
-       if (!ss) {
-               char source_str[INET_ADDRSTRLEN];
-               pim_inet4_dump("<src?>", source_addr, source_str,
-                              sizeof(source_str));
-               zlog_err("%s: XCALLOC(%zu) failure for ssmpingd source %s",
-                        __PRETTY_FUNCTION__, sizeof(*ss), source_str);
-               close(sock_fd);
-               return 0;
-       }
 
        ss->pim = pim;
        ss->sock_fd = sock_fd;
index 3d44a01c78803d09161a8ac7f029f2dc2008dc98..9569b7dcac2fa86cfb91e2a329c3cdc202fda3f0 100644 (file)
@@ -39,14 +39,7 @@ void pim_static_route_free(struct static_route *s_route)
 
 static struct static_route *static_route_alloc()
 {
-       struct static_route *s_route;
-
-       s_route = XCALLOC(MTYPE_PIM_STATIC_ROUTE, sizeof(*s_route));
-       if (!s_route) {
-               zlog_err("PIM XCALLOC(%zu) failure", sizeof(*s_route));
-               return 0;
-       }
-       return s_route;
+       return XCALLOC(MTYPE_PIM_STATIC_ROUTE, sizeof(struct static_route));
 }
 
 static struct static_route *static_route_new(unsigned int iif, unsigned int oif,
@@ -55,9 +48,6 @@ static struct static_route *static_route_new(unsigned int iif, unsigned int oif,
 {
        struct static_route *s_route;
        s_route = static_route_alloc();
-       if (!s_route) {
-               return 0;
-       }
 
        s_route->group = group;
        s_route->source = source;
index eddec3c29e81acb16a6144d07ae6cf6122fec5e6..80bda336dfefeba9adefb0538713bb26a17f558e 100644 (file)
@@ -757,12 +757,6 @@ int pim_tlv_parse_addr_list(const char *ifname, struct in_addr src_addr,
                 */
                if (!*hello_option_addr_list) {
                        *hello_option_addr_list = list_new();
-                       if (!*hello_option_addr_list) {
-                               zlog_err(
-                                       "%s %s: failure: hello_option_addr_list=list_new()",
-                                       __FILE__, __PRETTY_FUNCTION__);
-                               return -2;
-                       }
                        (*hello_option_addr_list)->del =
                                (void (*)(void *))prefix_free;
                }
index 9329d72ce05536b16f04956efc80efe79aa0299b..e3488b6a66d7423b527e358fa1e48cc4689583cb 100644 (file)
@@ -603,11 +603,6 @@ static struct pim_upstream *pim_upstream_new(struct pim_instance *pim,
        struct pim_upstream *up;
 
        up = XCALLOC(MTYPE_PIM_UPSTREAM, sizeof(*up));
-       if (!up) {
-               zlog_err("%s: PIM XCALLOC(%zu) failure", __PRETTY_FUNCTION__,
-                        sizeof(*up));
-               return NULL;
-       }
 
        up->sg = *sg;
        pim_str_sg_set(sg, up->sg_str);
index cb384bfe1da8d2dd021f2c18a44c91df73d3d459..a58dfcdd5f0e5bc85e34b5f66b336fa3a15d1e7e 100644 (file)
@@ -202,7 +202,7 @@ static int pim_zebra_if_state_up(int command, struct zclient *zclient,
         * If we have a pimreg device callback and it's for a specific
         * table set the master appropriately
         */
-       if (sscanf(ifp->name, "pimreg%d", &table_id) == 1) {
+       if (sscanf(ifp->name, "pimreg%" SCNu32, &table_id) == 1) {
                struct vrf *vrf;
                RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
                        if ((table_id == vrf->data.l.table_id)
index 064b78b260ea900f85da86bf2c7a7ce6517b9ec5..e2be7050d7ad98f406d79b4ae90ae14401f27aa5 100644 (file)
 
 #################### FRRouting (FRR) configure options #####################
 # with-feature options
-%{!?with_pam:           %global  with_pam           0 }
-%{!?with_ospfclient:    %global  with_ospfclient    1 }
-%{!?with_ospfapi:       %global  with_ospfapi       1 }
-%{!?with_rtadv:         %global  with_rtadv         1 }
-%{!?with_ldpd:          %global  with_ldpd          1 }
-%{!?with_nhrpd:         %global  with_nhrpd         1 }
-%{!?with_eigrpd:        %global  with_eigrpd        1 }
 %{!?with_babeld:        %global  with_babeld        1 }
-%{!?with_shared:        %global  with_shared        1 }
-%{!?with_multipath:     %global  with_multipath     256 }
-%{!?frr_user:           %global  frr_user           frr }
-%{!?vty_group:          %global  vty_group          frrvty }
-%{!?with_fpm:           %global  with_fpm           1 }
-%{!?with_watchfrr:      %global  with_watchfrr      1 }
 %{!?with_bgp_vnc:       %global  with_bgp_vnc       0 }
+%{!?with_cumulus:       %global  with_cumulus       0 }
+%{!?with_eigrpd:        %global  with_eigrpd        1 }
+%{!?with_fpm:           %global  with_fpm           1 }
+%{!?with_ldpd:          %global  with_ldpd          1 }
+%{!?with_multipath:     %global  with_multipath     256 }
+%{!?with_nhrpd:         %global  with_nhrpd         1 }
+%{!?with_ospfapi:       %global  with_ospfapi       1 }
+%{!?with_ospfclient:    %global  with_ospfclient    1 }
+%{!?with_pam:           %global  with_pam           0 }
+%{!?with_pbrd:          %global  with_pbrd          1 }
 %{!?with_pimd:          %global  with_pimd          1 }
 %{!?with_rpki:          %global  with_rpki          0 }
-%{!?with_pbrd:          %global  with_pbrd          1 }
+%{!?with_rtadv:         %global  with_rtadv         1 }
+%{!?with_watchfrr:      %global  with_watchfrr      1 }
+
+# user and group
+%{!?frr_user:           %global  frr_user           frr }
+%{!?vty_group:          %global  vty_group          frrvty }
 
 # path defines
-%define     _sysconfdir   /etc/frr
-%define     _sbindir      /usr/lib/frr
-%define     zeb_src       %{_builddir}/%{name}-%{frrversion}
-%define     zeb_rh_src    %{zeb_src}/redhat
-%define     zeb_docs      %{zeb_src}/doc
-%define     frr_tools     %{zeb_src}/tools
+%define     configdir   %{_sysconfdir}/%{name}
+%define     _sbindir    /usr/lib/frr
+%define     zeb_src     %{_builddir}/%{name}-%{frrversion}
+%define     zeb_rh_src  %{zeb_src}/redhat
+%define     zeb_docs    %{zeb_src}/doc
+%define     frr_tools   %{zeb_src}/tools
 
 # defines for configure
-%define     _localstatedir  /var/run/frr
+%define     rundir  %{_localstatedir}/run/%{name}
 
 # define for sphinx-build binary
 %if 0%{?rhel} && 0%{?rhel} < 7
-%define     sphinx sphinx-build2.7
+    %define sphinx sphinx-build2.7
 %else
-%define     sphinx sphinx-build
+    %define sphinx sphinx-build
 %endif
 ############################################################################
 
 %{!?frr_gid:            %global  frr_gid            92 }
 %{!?vty_gid:            %global  vty_gid            85 }
 
-%define     daemon_list zebra ripd ospfd bgpd isisd ripngd ospf6d pbrd
+%define daemon_list zebra ripd ospfd bgpd isisd ripngd ospf6d pbrd
 
 %if %{with_ldpd}
-%define daemon_ldpd ldpd
+    %define daemon_ldpd ldpd
 %else
-%define daemon_ldpd ""
+    %define daemon_ldpd ""
 %endif
 
 %if %{with_pimd}
-%define daemon_pimd pimd
+    %define daemon_pimd pimd
 %else
-%define daemon_pimd ""
+    %define daemon_pimd ""
 %endif
 
 %if %{with_pbrd}
-%define daemon_pbrd pbrd
+    %define daemon_pbrd pbrd
 %else
-%define daemon_pbrd ""
+    %define daemon_pbrd ""
 %endif
 
 %if %{with_nhrpd}
-%define daemon_nhrpd nhrpd
+    %define daemon_nhrpd nhrpd
 %else
-%define daemon_nhrpd ""
+    %define daemon_nhrpd ""
 %endif
 
 %if %{with_eigrpd}
-%define daemon_eigrpd eigrpd
+    %define daemon_eigrpd eigrpd
 %else
-%define daemon_eigrpd ""
+    %define daemon_eigrpd ""
 %endif
 
 %if %{with_babeld}
-%define daemon_babeld babeld
+    %define daemon_babeld babeld
 %else
-%define daemon_babeld ""
+    %define daemon_babeld ""
 %endif
 
 %if %{with_watchfrr}
-%define daemon_watchfrr watchfrr
+    %define daemon_watchfrr watchfrr
 %else
-%define daemon_watchfrr ""
+    %define daemon_watchfrr ""
 %endif
 
 %define all_daemons %{daemon_list} %{daemon_ldpd} %{daemon_pimd} %{daemon_nhrpd} %{daemon_eigrpd} %{daemon_babeld} %{daemon_watchfrr} %{daemon_pbrd}
 
-# allow build dir to be kept
-%{!?keep_build:         %global  keep_build         0 }
-
 #release sub-revision (the two digits after the CONFDATE)
 %{!?release_rev:        %global  release_rev        01 }
 
@@ -143,19 +142,27 @@ License:        GPLv2+
 Group:          System Environment/Daemons
 Source0:        https://github.com/FRRouting/frr/archive/%{name}-%{frrversion}.tar.gz
 URL:            https://www.frrouting.org
+Requires(pre):  shadow-utils
 Requires(preun): info
 Requires(post): info
-BuildRequires:  gcc patch libcap-devel
-BuildRequires:  readline-devel ncurses-devel
-BuildRequires:  json-c-devel bison >= 2.7 flex make
-BuildRequires:  c-ares-devel texinfo
+BuildRequires:  bison >= 2.7
+BuildRequires:  c-ares-devel
+BuildRequires:  flex
+BuildRequires:  gcc
+BuildRequires:  json-c-devel
+BuildRequires:  libcap-devel
+BuildRequires:  make
+BuildRequires:  ncurses-devel
+BuildRequires:  readline-devel
+BuildRequires:  texinfo
 %if 0%{?rhel} && 0%{?rhel} < 7
 #python27-devel is available from ius community repo for RedHat/CentOS 6
-BuildRequires:  python27-devel python27-sphinx
+BuildRequires:  python27-devel
+BuildRequires:  python27-sphinx
 %else
-BuildRequires:  python-devel >= 2.7 python-sphinx
+BuildRequires:  python-devel >= 2.7
+BuildRequires:  python-sphinx
 %endif
-Requires:       json-c initscripts
 %if %{with_pam}
 BuildRequires:  pam-devel
 %endif
@@ -163,7 +170,8 @@ BuildRequires:  pam-devel
 BuildRequires:  librtr-devel >= 0.5
 %endif
 %if "%{initsystem}" == "systemd"
-BuildRequires:      systemd systemd-devel
+BuildRequires:      systemd
+BuildRequires:      systemd-devel
 Requires(post):     systemd
 Requires(preun):    systemd
 Requires(postun):   systemd
@@ -172,12 +180,13 @@ Requires(post):     chkconfig
 Requires(preun):    chkconfig
 # Initscripts > 5.60 is required for IPv6 support
 Requires(pre):      initscripts >= 5.60
+Requires:           initscripts
 %endif
 Provides:           routingdaemon = %{version}-%{release}
-BuildRoot:          %{_tmppath}/%{name}-%{version}-root
 Obsoletes:          gated mrt zebra frr-sysvinit
 Conflicts:          bird
 
+
 %description
 FRRouting is a free software that manages TCP/IP based routing
 protocol. It takes multi-server and multi-thread approach to resolve
@@ -188,6 +197,7 @@ NHRP, Babel, PBR and EIGRP.
 
 FRRouting is a fork of Quagga.
 
+
 %package contrib
 Summary: contrib tools for frr
 Group: System Environment/Daemons
@@ -195,6 +205,7 @@ Group: System Environment/Daemons
 %description contrib
 Contributed/3rd party tools which may be of use with frr.
 
+
 %package pythontools
 Summary: python tools for frr
 BuildRequires: python
@@ -204,6 +215,7 @@ Group: System Environment/Daemons
 %description pythontools
 Contributed python 2.7 tools which may be of use with frr.
 
+
 %package devel
 Summary: Header and object files for frr development
 Group: System Environment/Daemons
@@ -213,8 +225,10 @@ Requires: %{name} = %{version}-%{release}
 The frr-devel package contains the header and object files neccessary for
 developing OSPF-API and frr applications.
 
+
 %prep
-%setup  -q -n frr-%{frrversion}
+%setup -q -n frr-%{frrversion}
+
 
 %build
 
@@ -230,15 +244,11 @@ developing OSPF-API and frr applications.
 
 %configure \
     --sbindir=%{_sbindir} \
-    --sysconfdir=%{_sysconfdir} \
-    --libdir=%{_libdir} \
-    --libexecdir=%{_libexecdir} \
-    --localstatedir=%{_localstatedir} \
+    --sysconfdir=%{configdir} \
+    --localstatedir=%{rundir} \
+    --disable-static \
     --disable-werror \
     --enable-irdp \
-%if !%{with_shared}
-    --disable-shared \
-%endif
 %if %{with_multipath}
     --enable-multipath=%{with_multipath} \
 %endif
@@ -292,11 +302,11 @@ developing OSPF-API and frr applications.
     --with-libpam \
 %endif
 %if 0%{?frr_user:1}
-    --enable-user=%frr_user \
-    --enable-group=%frr_user \
+    --enable-user=%{frr_user} \
+    --enable-group=%{frr_user} \
 %endif
 %if 0%{?vty_group:1}
-    --enable-vty-group=%vty_group \
+    --enable-vty-group=%{vty_group} \
 %endif
 %if %{with_fpm}
     --enable-fpm \
@@ -308,6 +318,9 @@ developing OSPF-API and frr applications.
 %else
     --disable-watchfrr \
 %endif
+%if %{with_cumulus}
+    --enable-cumulus \
+%endif
 %if %{with_bgp_vnc}
     --enable-bgp-vnc \
 %else
@@ -318,9 +331,10 @@ developing OSPF-API and frr applications.
     --enable-systemd \
 %endif
 %if %{with_rpki}
-    --enable-rpki \
+    --enable-rpki
+%else
+    --disable-rpki
 %endif
-    --enable-poll
 
 make %{?_smp_mflags} MAKEINFO="makeinfo --no-split" SPHINXBUILD=%{sphinx}
 
@@ -328,9 +342,10 @@ pushd doc
 make SPHINXBUILD=%{sphinx} info
 popd
 
+
 %install
-mkdir -p %{buildroot}/etc/{frr,sysconfig,logrotate.d,pam.d,default} \
-         %{buildroot}/var/log/frr %{buildroot}%{_infodir}
+mkdir -p %{buildroot}%{_sysconfdir}/{frr,sysconfig,logrotate.d,pam.d,default} \
+         %{buildroot}%{_localstatedir}/log/frr %{buildroot}%{_infodir}
 make DESTDIR=%{buildroot} INSTALL="install -p" CP="cp -p" SPHINXBUILD=%{sphinx} install
 
 # Remove this file, as it is uninstalled and causes errors when building on RH9
@@ -339,53 +354,47 @@ rm -rf %{buildroot}/usr/share/info/dir
 # Remove debian init script if it was installed
 rm -f %{buildroot}%{_sbindir}/frr
 
-# kill bogus libtool files for modules
-rm -f %{buildroot}%{_libdir}/frr/modules/*.la
+# kill bogus libtool files
+rm -vf %{buildroot}%{_libdir}/frr/modules/*.la
+rm -vf %{buildroot}%{_libdir}/*.la
 
 # install /etc sources
 %if "%{initsystem}" == "systemd"
 mkdir -p %{buildroot}%{_unitdir}
-install -m644 %{zeb_rh_src}/frr.service \
-    %{buildroot}%{_unitdir}/frr.service
-install %{zeb_rh_src}/frr.init \
-    %{buildroot}%{_sbindir}/frr
+install -m644 %{zeb_rh_src}/frr.service %{buildroot}%{_unitdir}/frr.service
+install %{zeb_rh_src}/frr.init %{buildroot}%{_sbindir}/frr
 %else
-mkdir -p %{buildroot}/etc/rc.d/init.d
-install %{zeb_rh_src}/frr.init \
-    %{buildroot}%{_sbindir}/frr
-ln -s %{_sbindir}/frr \
-    %{buildroot}/etc/rc.d/init.d/frr
+mkdir -p %{buildroot}%{_initddir}
+install %{zeb_rh_src}/frr.init %{buildroot}%{_sbindir}/frr
+ln -s %{_sbindir}/frr %{buildroot}%{_initddir}/frr
 %endif
 
-install %{zeb_rh_src}/daemons %{buildroot}/etc/frr
-install -m644 %{zeb_rh_src}/frr.pam \
-    %{buildroot}/etc/pam.d/frr
-install -m644 %{zeb_rh_src}/frr.logrotate \
-    %{buildroot}/etc/logrotate.d/frr
-install -d -m750  %{buildroot}/var/run/frr
+install %{zeb_rh_src}/daemons %{buildroot}%{_sysconfdir}/frr
+install -m644 %{zeb_rh_src}/frr.pam %{buildroot}%{_sysconfdir}/pam.d/frr
+install -m644 %{zeb_rh_src}/frr.logrotate %{buildroot}%{_sysconfdir}/logrotate.d/frr
+install -d -m750 %{buildroot}%{rundir}
+
 
 %pre
 # add vty_group
 %if 0%{?vty_group:1}
-if getent group %vty_group > /dev/null ; then : ; else \
- /usr/sbin/groupadd -r -g %vty_gid %vty_group > /dev/null || : ; fi
+    getent group %{vty_group} >/dev/null || groupadd -r -g %{vty_gid} %{vty_group}
 %endif
 
 # add frr user and group
 %if 0%{?frr_user:1}
-# Ensure that frr_gid gets correctly allocated
-if getent group %frr_user >/dev/null; then : ; else \
- /usr/sbin/groupadd -g %frr_gid %frr_user > /dev/null || : ; \
-fi
-if getent passwd %frr_user >/dev/null ; then : ; else \
- /usr/sbin/useradd  -u %frr_uid -g %frr_gid \
-  -M -r -s /sbin/nologin -c "FRRouting suite" \
-  -d %_localstatedir %frr_user 2> /dev/null || : ; \
-fi
-%if 0%{?vty_group:1}
-/usr/sbin/usermod -a -G %vty_group %frr_user
-%endif
+    # Ensure that frr_gid gets correctly allocated
+    getent group %{frr_user} >/dev/null || groupadd -g %{frr_gid} %{frr_user}
+    getent passwd %{frr_user} >/dev/null || \
+    useradd -r -u %{frr_uid} -g %{frr_user} \
+        -s /sbin/nologin -c "FRRouting suite" \
+        -d %{rundir} %{frr_user}
+
+    %if 0%{?vty_group:1}
+        usermod -a -G %{vty_group} %{frr_user}
+    %endif
 %endif
+exit 0
 
 
 %post
@@ -395,9 +404,9 @@ fi
 zebra_spec_add_service ()
 {
     # Add port /etc/services entry if it isn't already there
-    if [ -f /etc/services ] && \
-        ! %__sed -e 's/#.*$//' /etc/services | %__grep -wq $1 ; then
-        echo "$1        $2          # $3"  >> /etc/services
+    if [ -f %{_sysconfdir}/services ] && \
+        ! %__sed -e 's/#.*$//' %{_sysconfdir}/services | %__grep -wq $1 ; then
+        echo "$1        $2          # $3"  >> %{_sysconfdir}/services
     fi
 }
 
@@ -408,86 +417,87 @@ zebra_spec_add_service ripngd   2603/tcp "RIPngd vty"
 zebra_spec_add_service ospfd    2604/tcp "OSPFd vty"
 zebra_spec_add_service bgpd     2605/tcp "BGPd vty"
 zebra_spec_add_service ospf6d   2606/tcp "OSPF6d vty"
+zebra_spec_add_service isisd    2608/tcp "ISISd vty"
 %if %{with_ospfapi}
-zebra_spec_add_service ospfapi  2607/tcp "OSPF-API"
+    zebra_spec_add_service ospfapi  2607/tcp "OSPF-API"
 %endif
-zebra_spec_add_service isisd    2608/tcp "ISISd vty"
 %if %{with_babeld}
-zebra_spec_add_service babeld   2609/tcp "BABELd vty"
+    zebra_spec_add_service babeld   2609/tcp "BABELd vty"
 %endif
 %if %{with_nhrpd}
-zebra_spec_add_service nhrpd    2610/tcp "NHRPd vty"
+    zebra_spec_add_service nhrpd    2610/tcp "NHRPd vty"
 %endif
 %if %{with_pimd}
-zebra_spec_add_service pimd     2611/tcp "PIMd vty"
+    zebra_spec_add_service pimd     2611/tcp "PIMd vty"
 %endif
 %if %{with_pbrd}
-zebra_spec_add_service pbrd     2615/tcp "PBRd vty"
+    zebra_spec_add_service pbrd     2615/tcp "PBRd vty"
 %endif
 %if %{with_ldpd}
-zebra_spec_add_service ldpd     2612/tcp "LDPd vty"
+    zebra_spec_add_service ldpd     2612/tcp "LDPd vty"
 %endif
 %if %{with_eigrpd}
-zebra_spec_add_service eigrpd   2613/tcp "EIGRPd vty"
+    zebra_spec_add_service eigrpd   2613/tcp "EIGRPd vty"
 %endif
 
 %if "%{initsystem}" == "systemd"
-for daemon in %all_daemons ; do
-    %systemd_post frr.service
-done
+    for daemon in %all_daemons ; do
+        %systemd_post frr.service
+    done
 %else
-/sbin/chkconfig --add frr
+    /sbin/chkconfig --add frr
 %endif
 
 # Fix bad path in previous config files
 #  Config files won't get replaced by default, so we do this ugly hack to fix it
-%__sed -i 's|/etc/init.d/|%{_sbindir}/|g' %{_sysconfdir}/daemons 2> /dev/null || true
+%__sed -i 's|/etc/init.d/|%{_sbindir}/|g' %{configdir}/daemons 2> /dev/null || true
 
 # With systemd, watchfrr is mandatory. Fix config to make sure it's enabled if
 # we install or upgrade to a frr built with systemd
 %if "%{initsystem}" == "systemd"
-    %__sed -i 's|watchfrr_enable=no|watchfrr_enable=yes|g' %{_sysconfdir}/daemons 2> /dev/null || true
+    %__sed -i 's|watchfrr_enable=no|watchfrr_enable=yes|g' %{configdir}/daemons 2> /dev/null || true
 %endif
 
 /sbin/install-info %{_infodir}/frr.info.gz %{_infodir}/dir
 
 # Create dummy files if they don't exist so basic functions can be used.
-if [ ! -e %{_sysconfdir}/zebra.conf ]; then
-    echo "hostname `hostname`" > %{_sysconfdir}/zebra.conf
+if [ ! -e %{configdir}/zebra.conf ]; then
+    echo "hostname `hostname`" > %{configdir}/zebra.conf
 %if 0%{?frr_user:1}
-    chown %frr_user:%frr_user %{_sysconfdir}/zebra.conf*
+    chown %{frr_user}:%{frr_user} %{configdir}/zebra.conf*
 %endif
-    chmod 640 %{_sysconfdir}/zebra.conf*
+    chmod 640 %{configdir}/zebra.conf*
 fi
 for daemon in %{all_daemons} ; do
     if [ x"${daemon}" != x"" ] ; then
-        if [ ! -e %{_sysconfdir}/${daemon}.conf ]; then
-            touch %{_sysconfdir}/${daemon}.conf
+        if [ ! -e %{configdir}/${daemon}.conf ]; then
+            touch %{configdir}/${daemon}.conf
             %if 0%{?frr_user:1}
-                chown %frr_user:%frr_user %{_sysconfdir}/${daemon}.conf*
+                chown %{frr_user}:%{frr_user} %{configdir}/${daemon}.conf*
             %endif
         fi
     fi
 done
 %if 0%{?frr_user:1}
-    chown %frr_user:%frr_user %{_sysconfdir}/daemons
+    chown %{frr_user}:%{frr_user} %{configdir}/daemons
 %endif
 
 %if %{with_watchfrr}
     # No config for watchfrr - this is part of /etc/sysconfig/frr
-    rm -f %{_sysconfdir}/watchfrr.*
+    rm -f %{configdir}/watchfrr.*
 %endif
 
-if [ ! -e %{_sysconfdir}/vtysh.conf ]; then
-    touch %{_sysconfdir}/vtysh.conf
-    chmod 640 %{_sysconfdir}/vtysh.conf
+if [ ! -e %{configdir}/vtysh.conf ]; then
+    touch %{configdir}/vtysh.conf
+    chmod 640 %{configdir}/vtysh.conf
 %if 0%{?frr_user:1}
-%if 0%{?vty_group:1}
-    chown %{frr_user}:%{vty_group} %{_sysconfdir}/vtysh.conf*
-%endif
+    %if 0%{?vty_group:1}
+        chown %{frr_user}:%{vty_group} %{configdir}/vtysh.conf*
+    %endif
 %endif
 fi
 
+
 %postun
 if [ "$1" -ge 1 ]; then
     #
@@ -502,11 +512,12 @@ if [ "$1" -ge 1 ]; then
         ##
         ## init.d Version
         ##
-        /etc/rc.d/init.d/frr restart >/dev/null 2>&1
+        service frr restart >/dev/null 2>&1
     %endif
     :
 fi
 
+
 %preun
 %if "%{initsystem}" == "systemd"
     ##
@@ -520,33 +531,28 @@ fi
     ## init.d Version
     ##
     if [ $1 -eq 0 ] ; then
-        /etc/rc.d/init.d/frr stop  >/dev/null 2>&1
+        service frr stop  >/dev/null 2>&1
         /sbin/chkconfig --del frr
     fi
 %endif
 /sbin/install-info --delete %{_infodir}/frr.info.gz %{_infodir}/dir
 
-%clean
-%if !0%{?keep_build:1}
-rm -rf %{buildroot}
-%endif
 
 %files
-%defattr(-,root,root)
 %doc */*.sample* AUTHORS COPYING
 %doc doc/mpls
 %doc ChangeLog NEWS README
 %if 0%{?frr_user:1}
-%dir %attr(751,%frr_user,%frr_user) %{_sysconfdir}
-%dir %attr(750,%frr_user,%frr_user) /var/log/frr
-%dir %attr(751,%frr_user,%frr_user) /var/run/frr
+    %dir %attr(751,%{frr_user},%{frr_user}) %{configdir}
+    %dir %attr(750,%{frr_user},%{frr_user}) %{_localstatedir}/log/frr
+    %dir %attr(751,%{frr_user},%{frr_user}) %{rundir}
 %else
-%dir %attr(750,root,root) %{_sysconfdir}
-%dir %attr(750,root,root) /var/log/frr
-%dir %attr(750,root,root) /var/run/frr
+    %dir %attr(750,root,root) %{configdir}
+    %dir %attr(750,root,root) %{_localstatedir}/log/frr
+    %dir %attr(750,root,root) %{rundir}
 %endif
 %if 0%{?vty_group:1}
-%attr(750,%frr_user,%vty_group) %{_sysconfdir}/vtysh.conf.sample
+    %attr(750,%{frr_user},%{vty_group}) %{configdir}/vtysh.conf.sample
 %endif
 %{_infodir}/frr.info.gz
 %{_mandir}/man*/*
@@ -579,63 +585,60 @@ rm -rf %{buildroot}
 %if %{with_babeld}
     %{_sbindir}/babeld
 %endif
-%if %{with_shared}
-%{_libdir}/lib*.so
 %{_libdir}/lib*.so.0
-%attr(755,root,root) %{_libdir}/lib*.so.0.*
-%endif
+%{_libdir}/lib*.so.0.*
 %if %{with_fpm}
-%attr(755,root,root) %{_libdir}/frr/modules/zebra_fpm.so
+    %{_libdir}/frr/modules/zebra_fpm.so
 %endif
 %if %{with_rpki}
-%attr(755,root,root) %{_libdir}/frr/modules/bgpd_rpki.so
+    %{_libdir}/frr/modules/bgpd_rpki.so
 %endif
-%attr(755,root,root) %{_libdir}/frr/modules/zebra_irdp.so
+%{_libdir}/frr/modules/zebra_irdp.so
 %{_bindir}/*
-%config(noreplace) /etc/frr/[!v]*.conf*
-%config(noreplace) %attr(750,%frr_user,%frr_user) /etc/frr/daemons
+%config(noreplace) %{configdir}/[!v]*.conf*
+%config(noreplace) %attr(750,%{frr_user},%{frr_user}) %{configdir}/daemons
 %if "%{initsystem}" == "systemd"
     %{_unitdir}/frr.service
 %else
-    /etc/rc.d/init.d/frr
+    %{_initddir}/frr
 %endif
 %{_sbindir}/frr
-%config(noreplace) /etc/pam.d/frr
-%config(noreplace) /etc/logrotate.d/frr
+%config(noreplace) %{_sysconfdir}/pam.d/frr
+%config(noreplace) %{_sysconfdir}/logrotate.d/frr
 %{_sbindir}/frr-reload
 
+
 %files contrib
-%defattr(-,root,root)
 %doc tools
 
+
 %files pythontools
-%defattr(-,root,root)
 %{_sbindir}/frr-reload.py
 %{_sbindir}/frr-reload.pyc
 %{_sbindir}/frr-reload.pyo
 
+
 %files devel
-%defattr(-,root,root)
+%{_libdir}/lib*.so
 %if %{with_ospfclient}
-%{_sbindir}/ospfclient
-%endif
-%{_libdir}/*.a
-%{_libdir}/*.la
-%dir %attr(755,root,root) %{_includedir}/%{name}
-%{_includedir}/%name/*.h
-%dir %attr(755,root,root) %{_includedir}/%{name}/ospfd
-%{_includedir}/%name/ospfd/*.h
+    %{_sbindir}/ospfclient
+%endif
+%dir %{_includedir}/%{name}
+%{_includedir}/%{name}/*.h
+%dir %{_includedir}/%{name}/ospfd
+%{_includedir}/%{name}/ospfd/*.h
 %if %{with_ospfapi}
-%dir %attr(755,root,root) %{_includedir}/%{name}/ospfapi
-%{_includedir}/%name/ospfapi/*.h
+    %dir %{_includedir}/%{name}/ospfapi
+    %{_includedir}/%{name}/ospfapi/*.h
 %endif
 %if %{with_eigrpd}
-%dir %attr(755,root,root) %{_includedir}/%{name}/eigrpd
-%{_includedir}/%name/eigrpd/*.h
+    %dir %{_includedir}/%{name}/eigrpd
+    %{_includedir}/%{name}/eigrpd/*.h
 %endif
 
+
 %changelog
-* Sun May 20 2018 Martin Winter <mwinter@opensourcerouting.org> - %{version}
+* Sun May 20 2018 Martin Winter <mwinter@opensourcerouting.org>
 - Fixed RPKI RPM build
 
 * Sun Mar  4 2018 Martin Winter <mwinter@opensourcerouting.org>
index d1057bf53e219eb715f01bcac5b665ca0802ee67..c463630b12964c4000e8e9479b6002eda67a0709 100644 (file)
@@ -492,7 +492,7 @@ static int ripng_enable_network_lookup_if(struct interface *ifp)
 
        for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) {
                struct prefix *p;
-               struct route_node *node;
+               struct route_node *n;
 
                p = connected->address;
 
@@ -501,10 +501,10 @@ static int ripng_enable_network_lookup_if(struct interface *ifp)
                        address.prefix = p->u.prefix6;
                        address.prefixlen = IPV6_MAX_BITLEN;
 
-                       node = route_node_match(ripng_enable_network,
-                                               (struct prefix *)&address);
-                       if (node) {
-                               route_unlock_node(node);
+                       n = route_node_match(ripng_enable_network,
+                                            (struct prefix *)&address);
+                       if (n) {
+                               route_unlock_node(n);
                                return 1;
                        }
                }
index 840157516fb673a81d13ace34a404d999199b9c8..565e151c53eea19b5176ad0869b7b8551b402764 100644 (file)
@@ -1516,9 +1516,10 @@ int ripng_write_rte(int num, struct stream *s, struct prefix_ipv6 *p,
        }
 
        /* Write routing table entry. */
-       if (!nexthop)
+       if (!nexthop) {
+               assert(p);
                stream_write(s, (uint8_t *)&p->prefix, sizeof(struct in6_addr));
-       else
+       else
                stream_write(s, (uint8_t *)nexthop, sizeof(struct in6_addr));
        stream_putw(s, tag);
        if (p)
index 5b90b7046c6e5fad8985c6c096e3f467fd955c6f..c8368b39b613985f3c0ed8d99b28e32fdedd72d1 100644 (file)
@@ -21,6 +21,7 @@ TAGS
 __pycache__
 .pytest_cache
 /bgpd/test_aspath
+/bgpd/test_bgp_table
 /bgpd/test_capability
 /bgpd/test_ecommunity
 /bgpd/test_mp_attr
index 32d2db768a0fa8e19aa6a8e3d3a3b5918e345672..a7dec67348218df46fecb8927998c576fe371187 100644 (file)
@@ -21,7 +21,8 @@ TESTS_BGPD = \
        bgpd/test_peer_attr \
        bgpd/test_ecommunity \
        bgpd/test_mp_attr \
-       bgpd/test_mpath
+       bgpd/test_mpath \
+       bgpd/test_bgp_table
 else
 TESTS_BGPD =
 endif
@@ -143,6 +144,7 @@ bgpd_test_peer_attr_SOURCES = bgpd/test_peer_attr.c
 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
+bgpd_test_bgp_table_SOURCES = bgpd/test_bgp_table.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
@@ -186,6 +188,7 @@ bgpd_test_peer_attr_LDADD = $(BGP_TEST_LDADD)
 bgpd_test_ecommunity_LDADD = $(BGP_TEST_LDADD)
 bgpd_test_mp_attr_LDADD = $(BGP_TEST_LDADD)
 bgpd_test_mpath_LDADD = $(BGP_TEST_LDADD)
+bgpd_test_bgp_table_LDADD = $(BGP_TEST_LDADD)
 isisd_test_fuzz_isis_tlv_LDADD = $(ISISD_TEST_LDADD)
 isisd_test_isis_vertex_queue_LDADD = $(ISISD_TEST_LDADD)
 ospf6d_test_lsdb_LDADD = $(OSPF6_TEST_LDADD)
diff --git a/tests/bgpd/test_bgp_table.c b/tests/bgpd/test_bgp_table.c
new file mode 100644 (file)
index 0000000..01ce748
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+ * BGP Routing table range lookup test
+ * Copyright (C) 2012 OSR.
+ * Copyright (C) 2018 Marcel Röthke (marcel.roethke@haw-hamburg.de), for HAW
+ * Hamburg
+ *
+ * This file is part of FRRouting
+ *
+ * Quagga is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * Quagga is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <zebra.h>
+
+#include "prefix.h"
+#include "table.h"
+#include "bgpd/bgp_table.h"
+#include "linklist.h"
+
+/*
+ * test_node_t
+ *
+ * Information that is kept for each node in the radix tree.
+ */
+struct test_node_t {
+
+       /*
+        * Human readable representation of the string. Allocated using
+        * malloc()/dup().
+        */
+       char *prefix_str;
+};
+
+/*
+ * add_node
+ *
+ * Add the given prefix (passed in as a string) to the given table.
+ */
+static void add_node(struct bgp_table *table, const char *prefix_str)
+{
+       struct prefix_ipv4 p;
+       struct test_node_t *node;
+       struct bgp_node *rn;
+
+       assert(prefix_str);
+
+       if (str2prefix_ipv4(prefix_str, &p) <= 0)
+               assert(0);
+
+       rn = bgp_node_get(table, (struct prefix *)&p);
+       if (rn->info) {
+               assert(0);
+               return;
+       }
+
+       node = malloc(sizeof(struct test_node_t));
+       assert(node);
+       node->prefix_str = strdup(prefix_str);
+       assert(node->prefix_str);
+       rn->info = node;
+}
+
+static void print_range_result(struct list *list)
+{
+
+       struct listnode *listnode;
+       struct bgp_node *bnode;
+
+       for (ALL_LIST_ELEMENTS_RO(list, listnode, bnode)) {
+               char buf[PREFIX2STR_BUFFER];
+
+               prefix2str(&bnode->p, buf, PREFIX2STR_BUFFER);
+               printf("%s\n", buf);
+       }
+}
+
+static void check_lookup_result(struct list *list, va_list arglist)
+{
+       char *prefix_str;
+       unsigned int prefix_count = 0;
+
+       printf("Searching results\n");
+       while ((prefix_str = va_arg(arglist, char *))) {
+               struct listnode *listnode;
+               struct bgp_node *bnode;
+               struct prefix p;
+               bool found = false;
+
+               prefix_count++;
+               printf("Searching for %s\n", prefix_str);
+
+               if (str2prefix(prefix_str, &p) <= 0)
+                       assert(0);
+
+               for (ALL_LIST_ELEMENTS_RO(list, listnode, bnode)) {
+                       if (prefix_same(&bnode->p, &p))
+                               found = true;
+               }
+
+               assert(found);
+       }
+
+       printf("Checking for unexpected result items\n");
+       printf("Expecting %d found %d\n", prefix_count, listcount(list));
+       assert(prefix_count == listcount(list));
+}
+
+static void do_test(struct bgp_table *table, const char *prefix, uint8_t maxlen,
+                   ...)
+{
+       va_list arglist;
+       struct list *list = list_new();
+       struct prefix p;
+
+       list->del = (void (*)(void *))bgp_unlock_node;
+
+       va_start(arglist, maxlen);
+       printf("\nDoing lookup for %s-%d\n", prefix, maxlen);
+       if (str2prefix(prefix, &p) <= 0)
+               assert(0);
+       bgp_table_range_lookup(table, &p, maxlen, list);
+       print_range_result(list);
+
+       check_lookup_result(list, arglist);
+
+       list_delete_and_null(&list);
+
+       va_end(arglist);
+
+       printf("Checks successfull\n");
+}
+
+/*
+ * test_range_lookup
+ */
+static void test_range_lookup(void)
+{
+       struct bgp_table *table = bgp_table_init(NULL, AFI_IP, SAFI_UNICAST);
+
+       printf("Testing bgp_table_range_lookup\n");
+
+       printf("Setup bgp_table");
+       const char *prefixes[] = {"1.16.0.0/16",   "1.16.128.0/18",
+                                 "1.16.192.0/18", "1.16.64.0/19",
+                                 "1.16.160.0/19", "1.16.32.0/20",
+                                 "1.16.32.0/21",  "16.0.0.0/16"};
+
+       int num_prefixes = sizeof(prefixes) / sizeof(prefixes[0]);
+
+       for (int i = 0; i < num_prefixes; i++)
+               add_node(table, prefixes[i]);
+
+       do_test(table, "1.16.0.0/17", 20, "1.16.64.0/19", "1.16.32.0/20", NULL);
+       do_test(table, "1.16.128.0/17", 20, "1.16.128.0/18", "1.16.192.0/18",
+               "1.16.160.0/19", NULL);
+
+       do_test(table, "1.16.128.0/17", 20, "1.16.128.0/18", "1.16.192.0/18",
+               "1.16.160.0/19", NULL);
+
+       do_test(table, "1.16.0.0/16", 18, "1.16.0.0/16", "1.16.128.0/18",
+               "1.16.192.0/18", NULL);
+
+       do_test(table, "1.16.0.0/16", 21, "1.16.0.0/16", "1.16.128.0/18",
+               "1.16.192.0/18", "1.16.64.0/19", "1.16.160.0/19",
+               "1.16.32.0/20", "1.16.32.0/21", NULL);
+
+       do_test(table, "1.17.0.0/16", 20, NULL);
+
+       do_test(table, "128.0.0.0/8", 16, NULL);
+
+       do_test(table, "16.0.0.0/8", 16, "16.0.0.0/16", NULL);
+
+       do_test(table, "0.0.0.0/3", 21, "1.16.0.0/16", "1.16.128.0/18",
+               "1.16.192.0/18", "1.16.64.0/19", "1.16.160.0/19",
+               "1.16.32.0/20", "1.16.32.0/21", "16.0.0.0/16", NULL);
+}
+
+int main(void)
+{
+       test_range_lookup();
+}
diff --git a/tests/bgpd/test_bgp_table.py b/tests/bgpd/test_bgp_table.py
new file mode 100644 (file)
index 0000000..4423530
--- /dev/null
@@ -0,0 +1,7 @@
+import frrtest
+
+class TestTable(frrtest.TestMultiOut):
+    program = './test_bgp_table'
+
+for i in range(6):
+    TestTable.onesimple('Checks successfull')
index 04e85435d157b11a0dabf45c423e8d391cbd203e..53180564bd950364cb84149a2e834aec32d52da0 100644 (file)
@@ -228,7 +228,8 @@ static void test_dump(struct test_state *test)
 }
 
 static void test_failed(struct test_state *test, const char *message,
-                       struct prefix_ipv6 *dst_p, struct prefix_ipv6 *src_p)
+                       const struct prefix_ipv6 *dst_p,
+                       const struct prefix_ipv6 *src_p)
 {
        char *route_id = format_srcdest(dst_p, src_p);
 
@@ -250,7 +251,7 @@ static void test_state_verify(struct test_state *test)
        /* Verify that there are no elements in the table which have never
         * been added */
        for (rn = route_top(test->table); rn; rn = srcdest_route_next(rn)) {
-               struct prefix_ipv6 *dst_p, *src_p;
+               const struct prefix_ipv6 *dst_p, *src_p;
 
                /* While we are iterating, we hold a lock on the current
                 * route_node,
@@ -288,10 +289,10 @@ static void test_state_verify(struct test_state *test)
                                expected_lock++;
 
                        if (rn->lock != expected_lock) {
-                               struct prefix_ipv6 *dst_p, *src_p;
+                               const struct prefix_ipv6 *dst_p, *src_p;
                                srcdest_rnode_prefixes(
-                                       rn, (struct prefix **)&dst_p,
-                                       (struct prefix **)&src_p);
+                                       rn, (const struct prefix **)&dst_p,
+                                       (const struct prefix **)&src_p);
 
                                test_failed(
                                        test,
@@ -305,8 +306,8 @@ static void test_state_verify(struct test_state *test)
 
                assert(rn->info == (void *)0xdeadbeef);
 
-               srcdest_rnode_prefixes(rn, (struct prefix **)&dst_p,
-                                      (struct prefix **)&src_p);
+               srcdest_rnode_prefixes(rn, (const struct prefix **)&dst_p,
+                                      (const struct prefix **)&src_p);
                memcpy(&hash_entry[0], dst_p, sizeof(*dst_p));
                if (src_p)
                        memcpy(&hash_entry[1], src_p, sizeof(*src_p));
@@ -377,7 +378,7 @@ static void test_state_del_one_route(struct test_state *test, struct prng *prng)
        which_route = prng_rand(prng) % test->log->count;
 
        struct route_node *rn;
-       struct prefix *dst_p, *src_p;
+       const struct prefix *dst_p, *src_p;
        struct prefix_ipv6 dst6_p, src6_p;
 
        for (rn = route_top(test->table); rn; rn = srcdest_route_next(rn)) {
index a9a4dfe08f469f786a45af04438c95aa67c8c38f..8869d34fd6f886f9a1b69e077b8fe9e9b09e268c 100644 (file)
@@ -564,7 +564,7 @@ void connected_delete_ipv6(struct interface *ifp, struct in6_addr *address,
        if (broad) {
                memset(&d, 0, sizeof(struct prefix));
                d.family = AF_INET6;
-               IPV6_ADDR_COPY(&d.u.prefix, broad);
+               IPV6_ADDR_COPY(&d.u.prefix6, broad);
                d.prefixlen = prefixlen;
                ifc = connected_check_ptp(ifp, &p, &d);
        } else
index d9c663184531acb27f873f4ac1664bed917ceb93..8703b013191f8a94edf3355a8bcaf1d300df274a 100644 (file)
@@ -390,8 +390,8 @@ void netlink_parse_rtattr(struct rtattr **tb, int max, struct rtattr *rta,
        }
 }
 
-int addattr_l(struct nlmsghdr *n, unsigned int maxlen, int type, void *data,
-             unsigned int alen)
+int addattr_l(struct nlmsghdr *n, unsigned int maxlen, int type,
+             const void *data, unsigned int alen)
 {
        int len;
        struct rtattr *rta;
@@ -415,8 +415,8 @@ int addattr_l(struct nlmsghdr *n, unsigned int maxlen, int type, void *data,
        return 0;
 }
 
-int rta_addattr_l(struct rtattr *rta, unsigned int maxlen, int type, void *data,
-                 unsigned int alen)
+int rta_addattr_l(struct rtattr *rta, unsigned int maxlen, int type,
+                 const void *data, unsigned int alen)
 {
        unsigned int len;
        struct rtattr *subrta;
@@ -829,9 +829,6 @@ int netlink_talk(int (*filter)(struct nlmsghdr *, ns_id_t, int startup),
        n->nlmsg_seq = ++nl->seq;
        n->nlmsg_pid = nl->snl.nl_pid;
 
-       /* Request an acknowledgement by setting NLM_F_ACK */
-       n->nlmsg_flags |= NLM_F_ACK;
-
        if (IS_ZEBRA_DEBUG_KERNEL)
                zlog_debug(
                        "netlink_talk: %s type %s(%u), len=%d seq=%u flags 0x%x",
@@ -942,12 +939,20 @@ void kernel_init(struct zebra_ns *zns)
        snprintf(zns->netlink.name, sizeof(zns->netlink.name),
                 "netlink-listen (NS %u)", zns->ns_id);
        zns->netlink.sock = -1;
-       netlink_socket(&zns->netlink, groups, zns->ns_id);
+       if (netlink_socket(&zns->netlink, groups, zns->ns_id) < 0) {
+               zlog_err("Failure to create %s socket",
+                        zns->netlink.name);
+               exit(-1);
+       }
 
        snprintf(zns->netlink_cmd.name, sizeof(zns->netlink_cmd.name),
                 "netlink-cmd (NS %u)", zns->ns_id);
        zns->netlink_cmd.sock = -1;
-       netlink_socket(&zns->netlink_cmd, 0, zns->ns_id);
+       if (netlink_socket(&zns->netlink_cmd, 0, zns->ns_id) < 0) {
+               zlog_err("Failure to create %s socket",
+                        zns->netlink_cmd.name);
+               exit(-1);
+       }
 
        /*
         * SOL_NETLINK is not available on all platforms yet
@@ -969,23 +974,24 @@ void kernel_init(struct zebra_ns *zns)
 #endif
 
        /* Register kernel socket. */
-       if (zns->netlink.sock > 0) {
-               /* Only want non-blocking on the netlink event socket */
-               if (fcntl(zns->netlink.sock, F_SETFL, O_NONBLOCK) < 0)
-                       zlog_err("Can't set %s socket flags: %s",
-                                zns->netlink.name, safe_strerror(errno));
-
-               /* Set receive buffer size if it's set from command line */
-               if (nl_rcvbufsize)
-                       netlink_recvbuf(&zns->netlink, nl_rcvbufsize);
-
-               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);
-       }
+       if (fcntl(zns->netlink.sock, F_SETFL, O_NONBLOCK) < 0)
+               zlog_err("Can't set %s socket error: %s(%d)",
+                        zns->netlink.name, safe_strerror(errno), errno);
+
+       if (fcntl(zns->netlink_cmd.sock, F_SETFL, O_NONBLOCK) < 0)
+               zlog_err("Can't set %s socket error: %s(%d)",
+                        zns->netlink_cmd.name, safe_strerror(errno), errno);
+
+       /* Set receive buffer size if it's set from command line */
+       if (nl_rcvbufsize)
+               netlink_recvbuf(&zns->netlink, nl_rcvbufsize);
+
+       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);
 
        rt_netlink_init();
 }
index 3b4048ff6992147cd6c11be6b469ec66f7fb2292..80bb876e0bc328736d5a40bf6c0c6ecdace70a81 100644 (file)
@@ -29,9 +29,9 @@
 extern void netlink_parse_rtattr(struct rtattr **tb, int max,
                                 struct rtattr *rta, int len);
 extern int addattr_l(struct nlmsghdr *n, unsigned int maxlen, int type,
-                    void *data, unsigned int alen);
+                    const void *data, unsigned int alen);
 extern int rta_addattr_l(struct rtattr *rta, unsigned int maxlen, int type,
-                        void *data, unsigned int alen);
+                        const void *data, unsigned int alen);
 extern int addattr16(struct nlmsghdr *n, unsigned int maxlen, int type,
                     uint16_t data);
 extern int addattr32(struct nlmsghdr *n, unsigned int maxlen, int type,
index be53b74b3f1fd411edfa4fc66b17af46bb6b0534..69c0ebb7ec50474d0f996cd661aeae64a16bfbfe 100644 (file)
@@ -113,7 +113,7 @@ static void zebra_redistribute(struct zserv *client, int type,
 
        for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
                RNODE_FOREACH_RE (rn, newre) {
-                       struct prefix *dst_p, *src_p;
+                       const struct prefix *dst_p, *src_p;
                        char buf[PREFIX_STRLEN];
 
                        srcdest_rnode_prefixes(rn, &dst_p, &src_p);
@@ -147,7 +147,7 @@ static void zebra_redistribute(struct zserv *client, int type,
 
 /* Either advertise a route for redistribution to registered clients or */
 /* withdraw redistribution if add cannot be done for client */
-void redistribute_update(struct prefix *p, struct prefix *src_p,
+void redistribute_update(const struct prefix *p, const struct prefix *src_p,
                         struct route_entry *re, struct route_entry *prev_re)
 {
        struct listnode *node, *nnode;
@@ -216,7 +216,7 @@ void redistribute_update(struct prefix *p, struct prefix *src_p,
        }
 }
 
-void redistribute_delete(struct prefix *p, struct prefix *src_p,
+void redistribute_delete(const struct prefix *p, const struct prefix *src_p,
                         struct route_entry *re)
 {
        struct listnode *node, *nnode;
@@ -274,7 +274,7 @@ void zebra_redistribute_add(ZAPI_HANDLER_ARGS)
                        __func__, zebra_route_string(client->proto), afi,
                        zebra_route_string(type), zvrf_id(zvrf), instance);
 
-       if (afi == 0 || afi > AFI_MAX) {
+       if (afi == 0 || afi >= AFI_MAX) {
                zlog_warn("%s: Specified afi %d does not exist",
                          __PRETTY_FUNCTION__, afi);
                return;
@@ -320,7 +320,7 @@ void zebra_redistribute_delete(ZAPI_HANDLER_ARGS)
        STREAM_GETC(msg, type);
        STREAM_GETW(msg, instance);
 
-       if (afi == 0 || afi > AFI_MAX) {
+       if (afi == 0 || afi >= AFI_MAX) {
                zlog_warn("%s: Specified afi %d does not exist",
                          __PRETTY_FUNCTION__, afi);
                return;
index 9b4820acd493f8b1f8e23601228a41f4bb7d165e..a0fbd13cf96d43a96d31e4fd193784e37b167455 100644 (file)
@@ -36,9 +36,11 @@ extern void zebra_redistribute_default_add(ZAPI_HANDLER_ARGS);
 extern void zebra_redistribute_default_delete(ZAPI_HANDLER_ARGS);
 /* ----------------- */
 
-extern void redistribute_update(struct prefix *, struct prefix *,
+extern void redistribute_update(const struct prefix *p,
+                               const struct prefix *src_p,
                                struct route_entry *, struct route_entry *);
-extern void redistribute_delete(struct prefix *, struct prefix *,
+extern void redistribute_delete(const struct prefix *p,
+                               const struct prefix *src_p,
                                struct route_entry *);
 
 extern void zebra_interface_up_update(struct interface *);
index 209f085ed13d7fc618d6b35096b3c061c6a2990c..6509cdaba79b0b7e0d1efed3153afc7735efc7c3 100644 (file)
@@ -289,7 +289,7 @@ extern int rib_lookup_ipv4_route(struct prefix_ipv4 *p, union sockunion *qgate,
 
 extern int is_zebra_valid_kernel_table(uint32_t table_id);
 extern int is_zebra_main_routing_table(uint32_t table_id);
-extern int zebra_check_addr(struct prefix *p);
+extern int zebra_check_addr(const struct prefix *p);
 
 extern void rib_addnode(struct route_node *rn, struct route_entry *re,
                        int process);
index ad1fe9a1f57704432b8cc55329419cdd9279b0a3..57e62e4f6ee5cc9963ce6ab5ee8e719bc5abb6b2 100644 (file)
@@ -67,8 +67,8 @@ enum dp_req_result {
  * a re-add.
  */
 extern enum dp_req_result kernel_route_rib(struct route_node *rn,
-                                          struct prefix *p,
-                                          struct prefix *src_p,
+                                          const struct prefix *p,
+                                          const struct prefix *src_p,
                                           struct route_entry *old,
                                           struct route_entry *new);
 
@@ -77,7 +77,8 @@ extern enum dp_req_result kernel_route_rib(struct route_node *rn,
  * so let's separate it out and allow the result to
  * be passed back up.
  */
-extern void kernel_route_rib_pass_fail(struct route_node *rn, struct prefix *p,
+extern void kernel_route_rib_pass_fail(struct route_node *rn,
+                                      const struct prefix *p,
                                       struct route_entry *re,
                                       enum dp_results res);
 
index 90334915491e1c9f69c51314602c78fbf4386b3d..485abc3f1230331d214f325be3922f6af3a0fb3d 100644 (file)
@@ -483,7 +483,9 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id,
                                memcpy(&nh.gate, gate, sz);
 
                        if (index) {
-                               ifp = if_lookup_by_index(index, VRF_UNKNOWN);
+                               ifp = if_lookup_by_index_per_ns(
+                                               zebra_ns_lookup(ns_id),
+                                               index);
                                if (ifp)
                                        nh_vrf_id = ifp->vrf_id;
                        }
@@ -526,8 +528,9 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id,
                                         * using the last one looked
                                         * up right now
                                         */
-                                       ifp = if_lookup_by_index(index,
-                                                                VRF_UNKNOWN);
+                                       ifp = if_lookup_by_index_per_ns(
+                                                       zebra_ns_lookup(ns_id),
+                                                       index);
                                        if (ifp)
                                                nh_vrf_id = ifp->vrf_id;
                                        else {
@@ -1287,8 +1290,8 @@ _netlink_mpls_build_multipath(const char *routedesc, zebra_nhlfe_t *nhlfe,
  * @param zvrf: The vrf we are in
  * @param tableid: The table we are working on
  */
-static void _netlink_route_debug(int cmd, struct prefix *p,
-                                int family, struct zebra_vrf *zvrf,
+static void _netlink_route_debug(int cmd, const struct prefix *p,
+                                int family, vrf_id_t vrfid,
                                 uint32_t tableid)
 {
        if (IS_ZEBRA_DEBUG_KERNEL) {
@@ -1297,7 +1300,7 @@ static void _netlink_route_debug(int cmd, struct prefix *p,
                        "netlink_route_multipath(): %s %s vrf %u(%u)",
                        nl_msg_type_to_str(cmd),
                        prefix2str(p, buf, sizeof(buf)),
-                       zvrf_id(zvrf), tableid);
+                       vrfid, tableid);
        }
 }
 
@@ -1340,8 +1343,9 @@ static int netlink_neigh_update(int cmd, int ifindex, uint32_t addr, char *lla,
 
 /* Routing table change via netlink interface. */
 /* Update flag indicates whether this is a "replace" or not. */
-static int netlink_route_multipath(int cmd, struct prefix *p,
-                                  struct prefix *src_p, struct route_entry *re,
+static int netlink_route_multipath(int cmd, const struct prefix *p,
+                                  const struct prefix *src_p,
+                                  struct route_entry *re,
                                   int update)
 {
        int bytelen;
@@ -1416,7 +1420,7 @@ static int netlink_route_multipath(int cmd, struct prefix *p,
                addattr32(&req.n, sizeof req, RTA_TABLE, re->table);
        }
 
-       _netlink_route_debug(cmd, p, family, zvrf, re->table);
+       _netlink_route_debug(cmd, p, family, zvrf_id(zvrf), re->table);
 
        /*
         * If we are not updating the route and we have received
@@ -1699,8 +1703,8 @@ int kernel_get_ipmr_sg_stats(struct zebra_vrf *zvrf, void *in)
 }
 
 enum dp_req_result kernel_route_rib(struct route_node *rn,
-                                   struct prefix *p,
-                                   struct prefix *src_p,
+                                   const struct prefix *p,
+                                   const struct prefix *src_p,
                                    struct route_entry *old,
                                    struct route_entry *new)
 {
index 441f518e9166ff522b7ad7c50dec46a7b5542ec4..cba0376300abe962f47d5fa70108e9e150698bcf 100644 (file)
@@ -386,8 +386,8 @@ static int kernel_rtm(int cmd, struct prefix *p, struct route_entry *re)
 }
 
 enum dp_req_result kernel_route_rib(struct route_node *rn,
-                                   struct prefix *p,
-                                   struct prefix *src_p,
+                                   const struct prefix *p,
+                                   const struct prefix *src_p,
                                    struct route_entry *old,
                                    struct route_entry *new)
 {
index dc918b1a9b335e92d802972d124d2b4144c3dcda..49ffcdd490528777609de6beb653328a28fbec06 100644 (file)
@@ -518,7 +518,7 @@ static void rtadv_process_advert(uint8_t *msg, unsigned int len,
 
        /* Create entry for neighbor if not known. */
        p.family = AF_INET6;
-       IPV6_ADDR_COPY(&p.u.prefix, &addr->sin6_addr);
+       IPV6_ADDR_COPY(&p.u.prefix6, &addr->sin6_addr);
        p.prefixlen = IPV6_MAX_PREFIXLEN;
 
        if (!nbr_connected_check(ifp, &p))
index 6e0d86d668eeb5d251df638bd9f6fb17383841f8..c16fa70857d5ac162291e5e406e1a80a5b0e5b3d 100644 (file)
@@ -448,7 +448,7 @@ void nbr_connected_add_ipv6(struct interface *ifp, struct in6_addr *address)
        struct prefix p;
 
        p.family = AF_INET6;
-       IPV6_ADDR_COPY(&p.u.prefix, address);
+       IPV6_ADDR_COPY(&p.u.prefix6, address);
        p.prefixlen = IPV6_MAX_PREFIXLEN;
 
        ifc = listnode_head(ifp->nbr_connected);
@@ -473,7 +473,7 @@ void nbr_connected_delete_ipv6(struct interface *ifp, struct in6_addr *address)
        struct prefix p;
 
        p.family = AF_INET6;
-       IPV6_ADDR_COPY(&p.u.prefix, address);
+       IPV6_ADDR_COPY(&p.u.prefix6, address);
        p.prefixlen = IPV6_MAX_PREFIXLEN;
 
        ifc = nbr_connected_check(ifp, &p);
@@ -514,8 +514,9 @@ int zsend_interface_update(int cmd, struct zserv *client, struct interface *ifp)
        return zserv_send_message(client, s);
 }
 
-int zsend_redistribute_route(int cmd, struct zserv *client, struct prefix *p,
-                            struct prefix *src_p, struct route_entry *re)
+int zsend_redistribute_route(int cmd, struct zserv *client,
+                            const struct prefix *p,
+                            const struct prefix *src_p, struct route_entry *re)
 {
        struct zapi_route api;
        struct zapi_nexthop *api_nh;
@@ -677,22 +678,28 @@ static int zsend_ipv4_nexthop_lookup_mrib(struct zserv *client,
        return zserv_send_message(client, s);
 }
 
-int zsend_route_notify_owner(struct route_entry *re, struct prefix *p,
-                            enum zapi_route_notify_owner note)
+/*
+ * Common utility send route notification, called from a path using a
+ * route_entry and from a path using a dataplane context.
+ */
+static int route_notify_internal(const struct prefix *p, int type,
+                                uint16_t instance, vrf_id_t vrf_id,
+                                uint32_t table_id,
+                                enum zapi_route_notify_owner note)
 {
        struct zserv *client;
        struct stream *s;
        uint8_t blen;
 
-       client = zserv_find_client(re->type, re->instance);
+       client = zserv_find_client(type, instance);
        if (!client || !client->notify_owner) {
                if (IS_ZEBRA_DEBUG_PACKET) {
                        char buff[PREFIX_STRLEN];
 
                        zlog_debug(
                                "Not Notifying Owner: %u about prefix %s(%u) %d vrf: %u",
-                               re->type, prefix2str(p, buff, sizeof(buff)),
-                               re->table, note, re->vrf_id);
+                               type, prefix2str(p, buff, sizeof(buff)),
+                               table_id, note, vrf_id);
                }
                return 0;
        }
@@ -701,14 +708,14 @@ int zsend_route_notify_owner(struct route_entry *re, struct prefix *p,
                char buff[PREFIX_STRLEN];
 
                zlog_debug("Notifying Owner: %u about prefix %s(%u) %d vrf: %u",
-                          re->type, prefix2str(p, buff, sizeof(buff)),
-                          re->table, note, re->vrf_id);
+                          type, prefix2str(p, buff, sizeof(buff)),
+                          table_id, note, vrf_id);
        }
 
        s = stream_new(ZEBRA_MAX_PACKET_SIZ);
        stream_reset(s);
 
-       zclient_create_header(s, ZEBRA_ROUTE_NOTIFY_OWNER, re->vrf_id);
+       zclient_create_header(s, ZEBRA_ROUTE_NOTIFY_OWNER, vrf_id);
 
        stream_put(s, &note, sizeof(note));
 
@@ -718,13 +725,20 @@ int zsend_route_notify_owner(struct route_entry *re, struct prefix *p,
        stream_putc(s, p->prefixlen);
        stream_put(s, &p->u.prefix, blen);
 
-       stream_putl(s, re->table);
+       stream_putl(s, table_id);
 
        stream_putw_at(s, 0, stream_get_endp(s));
 
        return zserv_send_message(client, s);
 }
 
+int zsend_route_notify_owner(struct route_entry *re, const struct prefix *p,
+                            enum zapi_route_notify_owner note)
+{
+       return (route_notify_internal(p, re->type, re->instance, re->vrf_id,
+                                     re->table, note));
+}
+
 void zsend_rule_notify_owner(struct zebra_pbr_rule *rule,
                             enum zapi_rule_notify_owner note)
 {
@@ -2820,7 +2834,9 @@ static inline void zread_rule(ZAPI_HANDLER_ARGS)
                STREAM_GETL(s, ifindex);
 
                if (ifindex) {
-                       zpr.ifp = if_lookup_by_index(ifindex, VRF_UNKNOWN);
+                       zpr.ifp = if_lookup_by_index_per_ns(
+                                               zvrf->zns,
+                                               ifindex);
                        if (!zpr.ifp) {
                                zlog_debug("Failed to lookup ifindex: %u",
                                           ifindex);
index f27897580a98d16e17a23092b91c3ccc15f93684..8289e33c6a66df85e87847637d2cff6e957af1f8 100644 (file)
@@ -56,7 +56,8 @@ extern void nbr_connected_delete_ipv6(struct interface *ifp,
 extern int zsend_interface_update(int cmd, struct zserv *client,
                                  struct interface *ifp);
 extern int zsend_redistribute_route(int cmd, struct zserv *zclient,
-                                   struct prefix *p, struct prefix *src_p,
+                                   const struct prefix *p,
+                                   const struct prefix *src_p,
                                    struct route_entry *re);
 extern int zsend_router_id_update(struct zserv *zclient, struct prefix *p,
                                  vrf_id_t vrf_id);
@@ -65,7 +66,8 @@ extern int zsend_interface_vrf_update(struct zserv *zclient,
 extern int zsend_interface_link_params(struct zserv *zclient,
                                       struct interface *ifp);
 extern int zsend_pw_update(struct zserv *client, struct zebra_pw *pw);
-extern int zsend_route_notify_owner(struct route_entry *re, struct prefix *p,
+extern int zsend_route_notify_owner(struct route_entry *re,
+                                   const struct prefix *p,
                                    enum zapi_route_notify_owner note);
 
 extern void zsend_rule_notify_owner(struct zebra_pbr_rule *rule,
index fe0837a63a75b6767de74b34bd086b6990fa5a17..cfe208d35b0b9960b544ebc59f673cb58b4c1b81 100644 (file)
@@ -38,6 +38,7 @@
 
 #include "zebra/rib.h"
 #include "zebra/rt.h"
+#include "zebra/interface.h"
 #include "zebra/zserv.h"
 #include "zebra/redistribute.h"
 #include "zebra/debug.h"
@@ -704,6 +705,7 @@ static int nhlfe_nexthop_active(zebra_nhlfe_t *nhlfe)
 {
        struct nexthop *nexthop;
        struct interface *ifp;
+       struct zebra_ns *zns;
 
        nexthop = nhlfe->nexthop;
        if (!nexthop) // unexpected
@@ -721,7 +723,8 @@ static int nhlfe_nexthop_active(zebra_nhlfe_t *nhlfe)
                 * which will not be in the default
                 * VRF.  So let's look in all of them
                 */
-               ifp = if_lookup_by_index(nexthop->ifindex, VRF_UNKNOWN);
+               zns = zebra_ns_lookup(NS_DEFAULT);
+               ifp = if_lookup_by_index_per_ns(zns, nexthop->ifindex);
                if (ifp && if_is_operative(ifp))
                        SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
                else
@@ -2752,10 +2755,13 @@ void zebra_mpls_print_lsp_table(struct vty *vty, struct zebra_vrf *zvrf,
 
                                switch (nexthop->type) {
                                case NEXTHOP_TYPE_IFINDEX: {
+                                       struct zebra_ns *zns;
                                        struct interface *ifp;
 
-                                       ifp = if_lookup_by_index(
-                                               nexthop->ifindex, VRF_UNKNOWN);
+                                       zns = zebra_ns_lookup(NS_DEFAULT);
+                                       ifp = if_lookup_by_index_per_ns(
+                                                       zns,
+                                                       nexthop->ifindex);
                                        vty_out(vty, "%15s", ifp->name);
                                        break;
                                }
index d0ea661403d0bdc0ffecce3289ec8a4d3ac540ae..60b72298a145094452d03ef0cb64a9e247ae7e99 100644 (file)
@@ -80,6 +80,8 @@ static void zebra_ns_notify_create_context_from_entry_name(const char *name)
        ns_id = zebra_ns_id_get(netnspath);
        if (zserv_privs.change(ZPRIVS_LOWER))
                zlog_err("Can't lower privileges");
+       if (ns_id == NS_UNKNOWN)
+               return;
        ns_id_external = ns_map_nsid_with_external(ns_id, true);
        /* if VRF with NS ID already present */
        vrf = vrf_lookup_by_id((vrf_id_t)ns_id_external);
index 8935956b2572f94a3e4d02a01ea9e63c4cd8a1c2..9bf6bfa22f08d949d19879a43408b744315e49f4 100644 (file)
@@ -156,7 +156,7 @@ int is_zebra_main_routing_table(uint32_t table_id)
        return 0;
 }
 
-int zebra_check_addr(struct prefix *p)
+int zebra_check_addr(const struct prefix *p)
 {
        if (p->family == AF_INET) {
                uint32_t addr;
@@ -325,7 +325,7 @@ struct nexthop *route_entry_nexthop_blackhole_add(struct route_entry *re,
        return nexthop;
 }
 
-static void nexthop_set_resolved(afi_t afi, struct nexthop *newhop,
+static void nexthop_set_resolved(afi_t afi, const struct nexthop *newhop,
                                 struct nexthop *nexthop)
 {
        struct nexthop *resolved_hop;
@@ -843,7 +843,7 @@ static unsigned nexthop_active_check(struct route_node *rn,
        route_map_result_t ret = RMAP_MATCH;
        int family;
        char buf[SRCDEST2STR_BUFFER];
-       struct prefix *p, *src_p;
+       const struct prefix *p, *src_p;
        srcdest_rnode_prefixes(rn, &p, &src_p);
 
        if (rn->p.family == AF_INET)
@@ -1012,7 +1012,7 @@ int zebra_rib_labeled_unicast(struct route_entry *re)
        return 1;
 }
 
-void kernel_route_rib_pass_fail(struct route_node *rn, struct prefix *p,
+void kernel_route_rib_pass_fail(struct route_node *rn, const struct prefix *p,
                                struct route_entry *re,
                                enum dp_results res)
 {
@@ -1085,7 +1085,7 @@ void rib_install_kernel(struct route_node *rn, struct route_entry *re,
 {
        struct nexthop *nexthop;
        rib_table_info_t *info = srcdest_rnode_table_info(rn);
-       struct prefix *p, *src_p;
+       const struct prefix *p, *src_p;
        struct zebra_vrf *zvrf = vrf_info_lookup(re->vrf_id);
 
        srcdest_rnode_prefixes(rn, &p, &src_p);
@@ -1143,7 +1143,7 @@ void rib_uninstall_kernel(struct route_node *rn, struct route_entry *re)
 {
        struct nexthop *nexthop;
        rib_table_info_t *info = srcdest_rnode_table_info(rn);
-       struct prefix *p, *src_p;
+       const struct prefix *p, *src_p;
        struct zebra_vrf *zvrf = vrf_info_lookup(re->vrf_id);
 
        srcdest_rnode_prefixes(rn, &p, &src_p);
@@ -1194,7 +1194,8 @@ static void rib_uninstall(struct route_node *rn, struct route_entry *re)
        }
 
        if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED)) {
-               struct prefix *p, *src_p;
+               const struct prefix *p, *src_p;
+
                srcdest_rnode_prefixes(rn, &p, &src_p);
 
                redistribute_delete(p, src_p, re);
@@ -1536,7 +1537,8 @@ static void rib_process(struct route_node *rn)
        char buf[SRCDEST2STR_BUFFER];
        rib_dest_t *dest;
        struct zebra_vrf *zvrf = NULL;
-       struct prefix *p, *src_p;
+       const struct prefix *p, *src_p;
+
        srcdest_rnode_prefixes(rn, &p, &src_p);
        vrf_id_t vrf_id = VRF_UNKNOWN;
 
index ce51f54a65b7d7d68d13abe3857e2aff9b163486..bf6718164f087d9b7d6217f632dc6fae5fe91d82 100644 (file)
@@ -1337,7 +1337,8 @@ void zebra_route_map_write_delay_timer(struct vty *vty)
 }
 
 route_map_result_t zebra_route_map_check(int family, int rib_type,
-                                        uint8_t instance, struct prefix *p,
+                                        uint8_t instance,
+                                        const struct prefix *p,
                                         struct nexthop *nexthop,
                                         vrf_id_t vrf_id, route_tag_t tag)
 {
@@ -1358,7 +1359,8 @@ route_map_result_t zebra_route_map_check(int family, int rib_type,
                rmap = route_map_lookup_by_name(
                        proto_rm[family][ZEBRA_ROUTE_MAX]);
        if (rmap) {
-               ret = route_map_apply(rmap, p, RMAP_ZEBRA, &nh_obj);
+               ret = route_map_apply(rmap, (struct prefix *)p,
+                                     RMAP_ZEBRA, &nh_obj);
        }
 
        return (ret);
index 20d425a2bcebb81a45844572b937bffb2b70f668..688c8b7203d2544f94de5d95c6300e254e86f41e 100644 (file)
@@ -40,7 +40,7 @@ zebra_import_table_route_map_check(int family, int rib_type, uint8_t instance,
                                   const char *rmap_name);
 extern route_map_result_t
 zebra_route_map_check(int family, int rib_type, uint8_t instance,
-                     struct prefix *p, struct nexthop *nexthop,
+                     const struct prefix *p, struct nexthop *nexthop,
                      vrf_id_t vrf_id, route_tag_t tag);
 extern route_map_result_t
 zebra_nht_route_map_check(int family, int client_proto, struct prefix *p,
index 67b2954f35799e5770ae7c6a45f7af8048b74be4..76346f6b663e62aced2cd8f5a4bfeb33afeffddb 100644 (file)
@@ -37,8 +37,9 @@
 #include "zebra/zebra_memory.h"
 
 /* Install static route into rib. */
-void static_install_route(afi_t afi, safi_t safi, struct prefix *p,
-                         struct prefix_ipv6 *src_p, struct static_route *si)
+void static_install_route(afi_t afi, safi_t safi, const struct prefix *p,
+                         const struct prefix_ipv6 *src_p,
+                         struct static_route *si)
 {
        struct route_entry *re;
        struct route_node *rn;
@@ -292,8 +293,9 @@ static int static_nexthop_same(struct nexthop *nexthop, struct static_route *si)
 }
 
 /* Uninstall static route from RIB. */
-void static_uninstall_route(afi_t afi, safi_t safi, struct prefix *p,
-                           struct prefix_ipv6 *src_p, struct static_route *si)
+void static_uninstall_route(afi_t afi, safi_t safi, const struct prefix *p,
+                           const struct prefix_ipv6 *src_p,
+                           struct static_route *si)
 {
        struct route_node *rn;
        struct route_entry *re;
@@ -610,7 +612,7 @@ static void static_ifindex_update_af(struct interface *ifp, bool up, afi_t afi,
        struct route_table *stable;
        struct route_node *rn;
        struct static_route *si;
-       struct prefix *p, *src_pp;
+       const struct prefix *p, *src_pp;
        struct prefix_ipv6 *src_p;
        struct vrf *vrf;
 
index 7dc47d6190d5227c559a4e9138546ec005bb3200..0be434fff2220e9eea14b1fc714b74567852d031 100644 (file)
@@ -82,11 +82,12 @@ struct static_route {
        uint32_t table_id;
 };
 
-extern void static_install_route(afi_t afi, safi_t safi, struct prefix *p,
-                                struct prefix_ipv6 *src_p,
+extern void static_install_route(afi_t afi, safi_t safi, const struct prefix *p,
+                                const struct prefix_ipv6 *src_p,
                                 struct static_route *si);
-extern void static_uninstall_route(afi_t afi, safi_t safi, struct prefix *p,
-                                  struct prefix_ipv6 *src_p,
+extern void static_uninstall_route(afi_t afi, safi_t safi,
+                                  const struct prefix *p,
+                                  const struct prefix_ipv6 *src_p,
                                   struct static_route *si);
 
 extern int static_add_route(afi_t, safi_t safi, uint8_t type, struct prefix *p,
index d443f725b0ec3a86a7227469db073ad9aaca1ced..3c21c3c1e585eb5c6fe35509d043b9cc2d0cea62 100644 (file)
@@ -134,14 +134,6 @@ static int zebra_vrf_enable(struct vrf *vrf)
                zvrf->import_check_table[afi] = table;
        }
 
-       static_fixup_vrf_ids(zvrf);
-
-       /*
-        * We may have static routes that are now possible to
-        * insert into the appropriate tables
-        */
-       static_config_install_delayed_routes(zvrf);
-
        /* Kick off any VxLAN-EVPN processing. */
        zebra_vxlan_vrf_enable(zvrf);
 
index b297f75ed943b4b5c2433650345d56fbf390bab6..b08da9cebd087102e5b618b48c874d3d3aed47d4 100644 (file)
@@ -69,7 +69,7 @@ extern struct zebra_privs_t zserv_privs;
  * Client thread events.
  *
  * These are used almost exclusively by client threads to drive their own event
- * loops. The only exception is in zebra_client_create(), which pushes an
+ * loops. The only exception is in zserv_client_create(), which pushes an
  * initial ZSERV_CLIENT_READ event to start the API handler loop.
  */
 enum zserv_client_event {
@@ -618,14 +618,6 @@ static int zserv_handle_client_close(struct thread *thread)
 {
        struct zserv *client = THREAD_ARG(thread);
 
-       /*
-        * Ensure these have been nulled. This does not equate to the
-        * associated task(s) being scheduled or unscheduled on the client
-        * pthread's threadmaster.
-        */
-       assert(!client->t_read);
-       assert(!client->t_write);
-
        /* synchronously stop thread */
        frr_pthread_stop(client->pthread, NULL);
 
@@ -1033,7 +1025,7 @@ void zserv_read_file(char *input)
        struct zserv *client = NULL;
        struct thread t;
 
-       zebra_client_create(-1);
+       zserv_client_create(-1);
 
        frr_pthread_stop(client->pthread, NULL);
        frr_pthread_destroy(client->pthread);