]> git.proxmox.com Git - mirror_frr.git/commitdiff
Merge pull request #3657 from nitinsoniism/ospf_mtu_crash
authorRuss White <russ@riw.us>
Tue, 29 Jan 2019 14:58:53 +0000 (09:58 -0500)
committerGitHub <noreply@github.com>
Tue, 29 Jan 2019 14:58:53 +0000 (09:58 -0500)
ospfd: ospfd core if hello packet exceeds link MTU

114 files changed:
Makefile.am
babeld/babel_interface.c
babeld/babeld.c
babeld/message.c
babeld/neighbour.c
babeld/resend.c
babeld/route.c
babeld/source.c
babeld/util.c
babeld/xroute.c
bgpd/bgp_evpn.c
bgpd/bgp_evpn.h
bgpd/bgp_keepalives.c
bgpd/bgp_updgrp_packet.c
bgpd/bgp_vty.c
bgpd/bgp_zebra.c
bgpd/bgpd.c
bgpd/bgpd.h
bgpd/rfapi/bgp_rfapi_cfg.c
bgpd/rfapi/rfapi_import.c
bgpd/rfapi/rfapi_rib.c
bgpd/rfapi/rfapi_vty.c
bgpd/rfp-example/librfp/rfp_example.c
bgpd/rfp-example/rfptest/rfptest.c
configure.ac
doc/developer/building-libyang.rst
doc/developer/modules.rst
doc/user/installation.rst
eigrpd/eigrp_dump.c
eigrpd/eigrp_interface.c
eigrpd/eigrp_packet.c
eigrpd/eigrp_topology.c
eigrpd/eigrpd.c
include/linux/if_addr.h [new file with mode: 0644]
include/subdir.am
isisd/isis_circuit.c
isisd/isis_spf.c
isisd/isis_te.c
isisd/isisd.c
lib/command.c
lib/filter.c
lib/frr_pthread.c
lib/graph.c
lib/hash.c
lib/if.h
lib/if_rmap.c
lib/keychain.c
lib/md5.c
lib/plist.c
lib/prefix.c
lib/route_types.pl
lib/skiplist.c
lib/termtable.c
lib/thread.c
lib/vty.c
lib/yang.c
lib/zclient.h
ospf6d/ospf6_asbr.c
ospf6d/ospf6_interface.c
ospf6d/ospf6_interface.h
ospfd/ospf_api.c
ospfd/ospf_interface.c
ospfd/ospf_lsa.c
ospfd/ospf_lsdb.c
ospfd/ospf_packet.c
ospfd/ospf_ri.c
ospfd/ospf_route.c
ospfd/ospf_te.c
pimd/pim_signals.c
pimd/pim_static.c
pimd/pim_time.c
pimd/pimd.c
ripd/rip_interface.c
ripd/rip_offset.c
ripd/rip_routemap.c
ripngd/ripng_debug.c
ripngd/ripng_interface.c
ripngd/ripng_peer.c
ripngd/ripng_routemap.c
ripngd/ripng_zebra.c
ripngd/ripngd.c
tests/bgpd/test_aspath.c
tests/bgpd/test_peer_attr.py
tests/helpers/c/main.c
tests/lib/test_heavy.c
tests/lib/test_heavy_thread.c
tests/lib/test_heavy_wq.c
tests/lib/test_table.c
tools/start-stop-daemon.c
vtysh/extract.pl.in
vtysh/vtysh.c
vtysh/vtysh_config.c
vtysh/vtysh_user.c
yang/libyang_plugins/subdir.am
zebra/connected.c
zebra/connected.h
zebra/if_ioctl.c
zebra/if_ioctl_solaris.c
zebra/if_netlink.c
zebra/irdp_interface.c
zebra/kernel_socket.c
zebra/label_manager.c
zebra/rt_socket.c
zebra/zebra_dplane.c
zebra/zebra_fpm_netlink.c
zebra/zebra_rib.c
zebra/zebra_rnh.c
zebra/zebra_routemap.c
zebra/zebra_router.c
zebra/zebra_router.h
zebra/zebra_vty.c
zebra/zebra_vxlan.c
zebra/zebra_vxlan.h
zebra/zebra_vxlan_private.h

index c56a551aa50d7afb24307d9e25eb95f1989271ef..7f7d7d62360059b72b67f04741138ca65c5af4de 100644 (file)
@@ -226,8 +226,8 @@ noinst_HEADERS += defaults.h
 clean-local: clean-python
 .PHONY: clean-python
 clean-python:
-       find -name __pycache__ -o -name .pytest_cache | xargs rm -rf
-       find -name "*.pyc" -o -name "*_clippy.c" | xargs rm -f
+       find -name __pycache__ -o -name .pytest_cache | xargs rm -rf
+       find -name "*.pyc" -o -name "*_clippy.c" | xargs rm -f
 
 redistclean:
        $(MAKE) distclean CONFIG_CLEAN_FILES="$(filter-out $(EXTRA_DIST), $(CONFIG_CLEAN_FILES))"
index a8698bfce34dea829d7e4ba9d22f73785d811f5f..79242f5b85c5910c8da1a259051ace4aadd1731f 100644 (file)
@@ -1262,7 +1262,7 @@ DEFUN (show_babel_parameters,
 }
 
 void
-babel_if_init ()
+babel_if_init(void)
 {
     /* initialize interface list */
     hook_register_prio(if_add, 0, babel_if_new_hook);
index 702c1fbabb7c8c6f7c9ef5e27900c41eb97fb5ea..39451b435a44ec59b7876dafcb2dbdf39cc0ac42 100644 (file)
@@ -307,7 +307,7 @@ babel_initial_noise(void)
 
 /* Delete all the added babel routes, make babeld only speak to zebra. */
 static void
-babel_clean_routing_process()
+babel_clean_routing_process(void)
 {
     flush_all_routes();
     babel_interface_close_all();
index f85a08ac3a62544833e788e2af3bc1da668c38fa..794b6e997609b31f3437709d2732fd4e0f4a02df 100644 (file)
@@ -1430,7 +1430,7 @@ send_wildcard_retraction(struct interface *ifp)
 }
 
 void
-update_myseqno()
+update_myseqno(void)
 {
     myseqno = seqno_plus(myseqno, 1);
 }
index 83f05bb5cf337698dc0b8622ee7394d26c6ba45e..d962a0961c9299c0a4c66c94c6458dc3d69ec2dc 100644 (file)
@@ -234,7 +234,7 @@ neighbour_txcost(struct neighbour *neigh)
 }
 
 unsigned
-check_neighbours()
+check_neighbours(void)
 {
     struct neighbour *neigh;
     int changed, rc;
index 8949075f67d0beaced0dddd29f878780f726305d..f08897fbd1cbe3b8083cf0cd559636e48b24b9d6 100644 (file)
@@ -238,7 +238,7 @@ satisfy_request(const unsigned char *prefix, unsigned char plen,
 }
 
 void
-expire_resend()
+expire_resend(void)
 {
     struct resend *current, *previous;
     int recompute = 0;
@@ -267,7 +267,7 @@ expire_resend()
 }
 
 void
-recompute_resend_time()
+recompute_resend_time(void)
 {
     struct resend *request;
     struct timeval resend = {0, 0};
@@ -286,7 +286,7 @@ recompute_resend_time()
 }
 
 void
-do_resend()
+do_resend(void)
 {
     struct resend *resend;
 
index 76f038cda5f4793fc90bdf6dff77d7e1c486ea2b..ab104aa2b10f8216d28664b8a62132c4a81a926d 100644 (file)
@@ -248,7 +248,7 @@ flush_route(struct babel_route *route)
 }
 
 void
-flush_all_routes()
+flush_all_routes(void)
 {
     int i;
 
index ed165b41b44d8956a8c1ca69efba9b0a810d7de8..2c303b624fde950df5c8bdb24ee06fec0d6639ed 100644 (file)
@@ -135,7 +135,7 @@ update_source(struct source *src,
 }
 
 void
-expire_sources()
+expire_sources(void)
 {
     struct source *src;
 
index 880cda2fce7ceb540fa067642192081cb9e303f6..c6606e4f0e39f8c3fe1e1ae722fc82d354c2a2df 100644 (file)
@@ -441,7 +441,7 @@ uchar_to_in6addr(struct in6_addr *dest, const unsigned char *src)
 }
 
 int
-daemonise()
+daemonise(void)
 {
     int rc;
 
index 88e9479e4b868f27440c2d7b5eff18085a28cc55..61ea5a1ac13b74a9489b923d90bbcffc1c12d3f8 100644 (file)
@@ -169,7 +169,7 @@ add_xroute(unsigned char prefix[16], unsigned char plen,
 
 /* Returns an overestimate of the number of xroutes. */
 int
-xroutes_estimate()
+xroutes_estimate(void)
 {
     return numxroutes;
 }
index 7f6d34808f1f9eb26aabd833c70adba79f799b17..c74d7829bd527f620c5289281b3b89e566d7dda4 100644 (file)
@@ -887,17 +887,26 @@ static void add_mac_mobility_to_attr(uint32_t seq_num, struct attr *attr)
 
 /* Install EVPN route into zebra. */
 static int evpn_zebra_install(struct bgp *bgp, struct bgpevpn *vpn,
-                             struct prefix_evpn *p,
-                             struct in_addr remote_vtep_ip, uint8_t flags,
-                             uint32_t seq)
+                             struct prefix_evpn *p, struct bgp_path_info *pi)
 {
        int ret;
+       uint8_t flags;
 
-       if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE)
-               ret = bgp_zebra_send_remote_macip(bgp, vpn, p, remote_vtep_ip,
-                                                 1, flags, seq);
-       else
+       if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) {
+               flags = 0;
+               if (pi->attr->sticky)
+                       SET_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
+               if (pi->attr->default_gw)
+                       SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
+               if (is_evpn_prefix_ipaddr_v6(p) &&
+                   pi->attr->router_flag)
+                       SET_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG);
+               ret = bgp_zebra_send_remote_macip(
+                       bgp, vpn, p, pi->attr->nexthop, 1, flags,
+                       mac_mobility_seqnum(pi->attr));
+       } else {
                ret = bgp_zebra_send_remote_vtep(bgp, vpn, p, 1);
+       }
 
        return ret;
 }
@@ -1121,11 +1130,9 @@ static int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn,
 {
        struct bgp_path_info *old_select, *new_select;
        struct bgp_path_info_pair old_and_new;
-       struct prefix_evpn *evp;
        afi_t afi = AFI_L2VPN;
        safi_t safi = SAFI_EVPN;
        int ret = 0;
-       uint8_t flags = 0;
 
        /* Compute the best path. */
        bgp_best_selection(bgp, rn, &bgp->maxpaths[afi][safi], &old_and_new,
@@ -1133,7 +1140,6 @@ static int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn,
        old_select = old_and_new.old;
        new_select = old_and_new.new;
 
-       evp = (struct prefix_evpn *)&rn->p;
        /* If the best path hasn't changed - see if there is still something to
         * update
         * to zebra RIB.
@@ -1144,20 +1150,10 @@ static int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn,
            && !CHECK_FLAG(rn->flags, BGP_NODE_USER_CLEAR)
            && !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
            && !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
-               if (bgp_zebra_has_route_changed(rn, old_select)) {
-                       if (old_select->attr->sticky)
-                               SET_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
-                       if (old_select->attr->default_gw)
-                               SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
-                       if (is_evpn_prefix_ipaddr_v6(evp) &&
-                           old_select->attr->router_flag)
-                               SET_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG);
-
+               if (bgp_zebra_has_route_changed(rn, old_select))
                        ret = evpn_zebra_install(
                                bgp, vpn, (struct prefix_evpn *)&rn->p,
-                               old_select->attr->nexthop, flags,
-                               mac_mobility_seqnum(old_select->attr));
-               }
+                               old_select);
                UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
                bgp_zebra_clear_route_change_flags(rn);
                return ret;
@@ -1182,18 +1178,9 @@ static int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn,
 
        if (new_select && new_select->type == ZEBRA_ROUTE_BGP
            && new_select->sub_type == BGP_ROUTE_IMPORTED) {
-               flags = 0;
-               if (new_select->attr->sticky)
-                       SET_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
-               if (new_select->attr->default_gw)
-                       SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
-               if (is_evpn_prefix_ipaddr_v6(evp) &&
-                   new_select->attr->router_flag)
-                       SET_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG);
-
                ret = evpn_zebra_install(bgp, vpn, (struct prefix_evpn *)&rn->p,
-                                        new_select->attr->nexthop, flags,
-                                        mac_mobility_seqnum(new_select->attr));
+                                        new_select);
+
                /* If an old best existed and it was a "local" route, the only
                 * reason
                 * it would be supplanted is due to MAC mobility procedures. So,
@@ -1698,6 +1685,27 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
        return route_change;
 }
 
+static void evpn_zebra_reinstall_best_route(struct bgp *bgp,
+               struct bgpevpn *vpn, struct bgp_node *rn)
+{
+       struct bgp_path_info *tmp_ri;
+       struct bgp_path_info *curr_select = NULL;
+
+       for (tmp_ri = bgp_node_get_bgp_path_info(rn);
+            tmp_ri; tmp_ri = tmp_ri->next) {
+               if (CHECK_FLAG(tmp_ri->flags, BGP_PATH_SELECTED)) {
+                       curr_select = tmp_ri;
+                       break;
+               }
+       }
+
+       if (curr_select && curr_select->type == ZEBRA_ROUTE_BGP
+                       && curr_select->sub_type == BGP_ROUTE_IMPORTED)
+               evpn_zebra_install(bgp, vpn,
+                               (struct prefix_evpn *)&rn->p,
+                               curr_select);
+}
+
 /*
  * If the local route was not selected evict it and tell zebra to re-add
  * the best remote dest.
@@ -1717,9 +1725,6 @@ static void evpn_cleanup_local_non_best_route(struct bgp *bgp,
                                              struct bgp_node *rn,
                                              struct bgp_path_info *local_pi)
 {
-       struct bgp_path_info *tmp_pi;
-       struct bgp_path_info *curr_select = NULL;
-       uint8_t flags = 0;
        char buf[PREFIX_STRLEN];
 
        /* local path was not picked as the winner; kick it out */
@@ -1731,24 +1736,7 @@ static void evpn_cleanup_local_non_best_route(struct bgp *bgp,
        bgp_path_info_reap(rn, local_pi);
 
        /* tell zebra to re-add the best remote path */
-       for (tmp_pi = bgp_node_get_bgp_path_info(rn);
-            tmp_pi; tmp_pi = tmp_pi->next) {
-               if (CHECK_FLAG(tmp_pi->flags, BGP_PATH_SELECTED)) {
-                       curr_select = tmp_pi;
-                       break;
-               }
-       }
-       if (curr_select &&
-           curr_select->type == ZEBRA_ROUTE_BGP
-           && curr_select->sub_type == BGP_ROUTE_IMPORTED) {
-               if (curr_select->attr->sticky)
-                       SET_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
-               if (curr_select->attr->default_gw)
-                       SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
-               evpn_zebra_install(bgp, vpn, (struct prefix_evpn *)&rn->p,
-                                  curr_select->attr->nexthop, flags,
-                                  mac_mobility_seqnum(curr_select->attr));
-       }
+       evpn_zebra_reinstall_best_route(bgp, vpn, rn);
 }
 
 /*
@@ -5324,10 +5312,11 @@ int bgp_filter_evpn_routes_upon_martian_nh_change(struct bgp *bgp)
  * Handle del of a local MACIP.
  */
 int bgp_evpn_local_macip_del(struct bgp *bgp, vni_t vni, struct ethaddr *mac,
-                            struct ipaddr *ip)
+                            struct ipaddr *ip, int state)
 {
        struct bgpevpn *vpn;
        struct prefix_evpn p;
+       struct bgp_node *rn;
 
        /* Lookup VNI hash - should exist. */
        vpn = bgp_evpn_lookup_vni(bgp, vni);
@@ -5338,9 +5327,16 @@ int bgp_evpn_local_macip_del(struct bgp *bgp, vni_t vni, struct ethaddr *mac,
                return -1;
        }
 
-       /* Remove EVPN type-2 route and schedule for processing. */
        build_evpn_type2_prefix(&p, mac, ip);
-       delete_evpn_route(bgp, vpn, &p);
+       if (state == ZEBRA_NEIGH_ACTIVE) {
+               /* Remove EVPN type-2 route and schedule for processing. */
+               delete_evpn_route(bgp, vpn, &p);
+       } else {
+               /* Re-instate the current remote best path if any */
+               rn = bgp_node_lookup(vpn->route_table, (struct prefix *)&p);
+               if (rn)
+                       evpn_zebra_reinstall_best_route(bgp, vpn, rn);
+       }
 
        return 0;
 }
index 8728fdcab7633278c0c3c1ff4076f67b72eec03a..5c3d4ce3aa9a1f60a56b1dc99651b43731d9b703 100644 (file)
@@ -129,7 +129,8 @@ extern int bgp_evpn_unimport_route(struct bgp *bgp, afi_t afi, safi_t safi,
                                   struct prefix *p, struct bgp_path_info *ri);
 extern int bgp_filter_evpn_routes_upon_martian_nh_change(struct bgp *bgp);
 extern int bgp_evpn_local_macip_del(struct bgp *bgp, vni_t vni,
-                                   struct ethaddr *mac, struct ipaddr *ip);
+                                   struct ethaddr *mac, struct ipaddr *ip,
+                                       int state);
 extern int bgp_evpn_local_macip_add(struct bgp *bgp, vni_t vni,
                                    struct ethaddr *mac, struct ipaddr *ip,
                                    uint8_t flags, uint32_t seq);
index 87e3ff2495270c8285657fcb30146d58f7398fe4..910c8a7372d8e3cd816867cd05c7b13bd2dca63a 100644 (file)
@@ -288,7 +288,7 @@ void bgp_keepalives_off(struct peer *peer)
        pthread_mutex_unlock(peerhash_mtx);
 }
 
-void bgp_keepalives_wake()
+void bgp_keepalives_wake(void)
 {
        pthread_mutex_lock(peerhash_mtx);
        {
index ca6bb5ab82ea86e4d9dfc5ce8365f7baa77108a6..cbbf8b230290bfc96baa3ffa95b4599d355f12dd 100644 (file)
@@ -65,7 +65,7 @@
 /********************
  * PUBLIC FUNCTIONS
  ********************/
-struct bpacket *bpacket_alloc()
+struct bpacket *bpacket_alloc(void)
 {
        struct bpacket *pkt;
 
index c6e48cc16083d97fdfc7061c8ef0e2ed40a01f43..43adf342473c4b82ec84752d63d6c32e61b899ff 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "command.h"
 #include "lib/json.h"
+#include "lib/zclient.h"
 #include "prefix.h"
 #include "plist.h"
 #include "buffer.h"
@@ -897,7 +898,7 @@ DEFUN_HIDDEN (no_bgp_local_mac,
                return CMD_WARNING;
        }
 
-       rv = bgp_evpn_local_macip_del(bgp, vni, &mac, &ip);
+       rv = bgp_evpn_local_macip_del(bgp, vni, &mac, &ip, ZEBRA_NEIGH_ACTIVE);
        if (rv < 0) {
                vty_out(vty, "Internal error\n");
                return CMD_WARNING;
@@ -2846,13 +2847,11 @@ static int peer_remote_as_vty(struct vty *vty, const char *peer_str,
        switch (ret) {
        case BGP_ERR_PEER_GROUP_MEMBER:
                vty_out(vty,
-                       "%% Peer-group AS %u. Cannot configure remote-as for member\n",
-                       as);
+                       "%% Peer-group member cannot override remote-as of peer-group\n");
                return CMD_WARNING_CONFIG_FAILED;
        case BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT:
                vty_out(vty,
-                       "%% The AS# can not be changed from %u to %s, peer-group members must be all internal or all external\n",
-                       as, as_str);
+                       "%% Peer-group members must be all internal or all external\n");
                return CMD_WARNING_CONFIG_FAILED;
        }
        return bgp_vty_return(vty, ret);
@@ -2973,7 +2972,7 @@ static int peer_conf_interface_get(struct vty *vty, const char *conf_if,
        if (!CHECK_FLAG(peer->flags_invert, PEER_FLAG_CAPABILITY_ENHE)) {
                SET_FLAG(peer->flags, PEER_FLAG_CAPABILITY_ENHE);
                SET_FLAG(peer->flags_invert, PEER_FLAG_CAPABILITY_ENHE);
-               UNSET_FLAG(peer->flags_override, PEER_FLAG_CAPABILITY_ENHE);
+               SET_FLAG(peer->flags_override, PEER_FLAG_CAPABILITY_ENHE);
        }
 
        if (peer_group_name) {
@@ -9212,8 +9211,8 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
                                ? " replace-as"
                                : "");
        }
-       /* peer type internal, external, confed-internal or confed-external */
-       if (p->as == p->local_as) {
+       /* peer type internal or confed-internal */
+       if ((p->as == p->local_as) || (p->as_type == AS_INTERNAL)) {
                if (use_json) {
                        if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION))
                                json_object_boolean_true_add(
@@ -9227,7 +9226,8 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
                        else
                                vty_out(vty, "internal link\n");
                }
-       } else {
+       /* peer type external or confed-external */
+       } else if (p->as || (p->as_type == AS_EXTERNAL)) {
                if (use_json) {
                        if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION))
                                json_object_boolean_true_add(
@@ -9241,6 +9241,12 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
                        else
                                vty_out(vty, "external link\n");
                }
+       } else {
+               if (use_json)
+                       json_object_boolean_true_add(json_neigh,
+                                                    "nbrUnspecifiedLink");
+               else
+                       vty_out(vty, "unspecified link\n");
        }
 
        /* Description. */
@@ -11006,6 +11012,7 @@ static void bgp_show_all_instances_neighbors_vty(struct vty *vty,
                        bgp_show_neighbor(vty, bgp, show_all, NULL, NULL,
                                          use_json, json);
                }
+               json_object_free(json);
        }
 
        if (use_json) {
index 3c4b219466ce37d643cb77eb16151b8aa733a39d..17de9433815967d8442711f640a56b8c9de39e8e 100644 (file)
@@ -2480,6 +2480,7 @@ static int bgp_zebra_process_local_macip(int command, struct zclient *zclient,
        char buf1[INET6_ADDRSTRLEN];
        uint8_t flags = 0;
        uint32_t seqnum = 0;
+       int state = 0;
 
        memset(&ip, 0, sizeof(ip));
        s = zclient->ibuf;
@@ -2503,6 +2504,8 @@ static int bgp_zebra_process_local_macip(int command, struct zclient *zclient,
        if (command == ZEBRA_MACIP_ADD) {
                flags = stream_getc(s);
                seqnum = stream_getl(s);
+       } else {
+               state = stream_getl(s);
        }
 
        bgp = bgp_lookup_by_vrf_id(vrf_id);
@@ -2510,16 +2513,17 @@ static int bgp_zebra_process_local_macip(int command, struct zclient *zclient,
                return 0;
 
        if (BGP_DEBUG(zebra, ZEBRA))
-               zlog_debug("%u:Recv MACIP %s flags 0x%x MAC %s IP %s VNI %u seq %u",
+               zlog_debug("%u:Recv MACIP %s flags 0x%x MAC %s IP %s VNI %u seq %u state %d",
                           vrf_id, (command == ZEBRA_MACIP_ADD) ? "Add" : "Del",
                           flags, prefix_mac2str(&mac, buf, sizeof(buf)),
-                          ipaddr2str(&ip, buf1, sizeof(buf1)), vni, seqnum);
+                          ipaddr2str(&ip, buf1, sizeof(buf1)), vni, seqnum,
+                          state);
 
        if (command == ZEBRA_MACIP_ADD)
                return bgp_evpn_local_macip_add(bgp, vni, &mac, &ip,
                                                flags, seqnum);
        else
-               return bgp_evpn_local_macip_del(bgp, vni, &mac, &ip);
+               return bgp_evpn_local_macip_del(bgp, vni, &mac, &ip, state);
 }
 
 static void bgp_zebra_process_local_ip_prefix(int cmd, struct zclient *zclient,
index 5b8ceb054149e1999990d802cd1872a6aca531ed..28f6239b8a420460cbf9014c90556b8ddd9a9e0a 100644 (file)
@@ -1001,7 +1001,26 @@ static inline bgp_peer_sort_t peer_calc_sort(struct peer *peer)
 
                return BGP_PEER_EBGP;
        } else {
-               if (peer->as_type != AS_SPECIFIED)
+               if (peer->as_type == AS_UNSPECIFIED) {
+                       /* check if in peer-group with AS information */
+                       if (peer->group
+                           && (peer->group->conf->as_type != AS_UNSPECIFIED)) {
+                               if (peer->group->conf->as_type
+                                   == AS_SPECIFIED) {
+                                       if (peer->local_as
+                                           == peer->group->conf->as)
+                                               return BGP_PEER_IBGP;
+                                       else
+                                               return BGP_PEER_EBGP;
+                               } else if (peer->group->conf->as_type
+                                          == AS_INTERNAL)
+                                       return BGP_PEER_IBGP;
+                               else
+                                       return BGP_PEER_EBGP;
+                       }
+                       /* no AS information anywhere, let caller know */
+                       return BGP_PEER_UNSPECIFIED;
+               } else if (peer->as_type != AS_SPECIFIED)
                        return (peer->as_type == AS_INTERNAL ? BGP_PEER_IBGP
                                                             : BGP_PEER_EBGP);
 
@@ -1711,20 +1730,32 @@ int peer_remote_as(struct bgp *bgp, union sockunion *su, const char *conf_if,
 
                /* When this peer is a member of peer-group.  */
                if (peer->group) {
-                       if (peer->group->conf->as) {
+                       /* peer-group already has AS number/internal/external */
+                       if (peer->group->conf->as
+                           || peer->group->conf->as_type) {
                                /* Return peer group's AS number.  */
                                *as = peer->group->conf->as;
                                return BGP_ERR_PEER_GROUP_MEMBER;
                        }
-                       if (peer_sort(peer->group->conf) == BGP_PEER_IBGP) {
-                               if ((as_type != AS_INTERNAL)
-                                   && (bgp->as != *as)) {
+
+                       bgp_peer_sort_t peer_sort_type =
+                                               peer_sort(peer->group->conf);
+
+                       /* Explicit AS numbers used, compare AS numbers */
+                       if (as_type == AS_SPECIFIED) {
+                               if (((peer_sort_type == BGP_PEER_IBGP)
+                                   && (bgp->as != *as))
+                                   || ((peer_sort_type == BGP_PEER_EBGP)
+                                   && (bgp->as == *as))) {
                                        *as = peer->as;
                                        return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT;
                                }
                        } else {
-                               if ((as_type != AS_EXTERNAL)
-                                   && (bgp->as == *as)) {
+                               /* internal/external used, compare as-types */
+                               if (((peer_sort_type == BGP_PEER_IBGP)
+                                   && (as_type != AS_INTERNAL))
+                                   || ((peer_sort_type == BGP_PEER_EBGP)
+                                   && (as_type != AS_EXTERNAL)))  {
                                        *as = peer->as;
                                        return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT;
                                }
@@ -2688,6 +2719,7 @@ int peer_group_bind(struct bgp *bgp, union sockunion *su, struct peer *peer,
                if (peer->as_type == AS_UNSPECIFIED) {
                        peer->as_type = group->conf->as_type;
                        peer->as = group->conf->as;
+                       peer->sort = group->conf->sort;
                }
 
                if (!group->conf->as) {
@@ -7020,14 +7052,17 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp,
 
        /* capability extended-nexthop */
        if (peergroup_flag_check(peer, PEER_FLAG_CAPABILITY_ENHE)) {
-               if (CHECK_FLAG(peer->flags_invert, PEER_FLAG_CAPABILITY_ENHE))
-                       vty_out(vty,
-                               " no neighbor %s capability extended-nexthop\n",
-                               addr);
-               else
-                       vty_out(vty,
-                               " neighbor %s capability extended-nexthop\n",
-                               addr);
+               if (!peer->conf_if) {
+                       if (CHECK_FLAG(peer->flags_invert,
+                                      PEER_FLAG_CAPABILITY_ENHE))
+                               vty_out(vty,
+                                       " no neighbor %s capability extended-nexthop\n",
+                                       addr);
+                       else
+                               vty_out(vty,
+                                       " neighbor %s capability extended-nexthop\n",
+                                       addr);
+               }
        }
 
        /* dont-capability-negotiation */
@@ -7839,7 +7874,7 @@ static const struct cmd_variable_handler bgp_viewvrf_var_handlers[] = {
 struct frr_pthread *bgp_pth_io;
 struct frr_pthread *bgp_pth_ka;
 
-static void bgp_pthreads_init()
+static void bgp_pthreads_init(void)
 {
        assert(!bgp_pth_io);
        assert(!bgp_pth_ka);
@@ -7858,7 +7893,7 @@ static void bgp_pthreads_init()
        bgp_pth_ka = frr_pthread_new(&ka, "BGP Keepalives thread", "bgpd_ka");
 }
 
-void bgp_pthreads_run()
+void bgp_pthreads_run(void)
 {
        frr_pthread_run(bgp_pth_io, NULL);
        frr_pthread_run(bgp_pth_ka, NULL);
@@ -7868,7 +7903,7 @@ void bgp_pthreads_run()
        frr_pthread_wait_running(bgp_pth_ka);
 }
 
-void bgp_pthreads_finish()
+void bgp_pthreads_finish(void)
 {
        frr_pthread_stop_all();
        frr_pthread_finish();
index 484fc105e808dccee102462faad766bdf0776e9d..58ae119af1f075fe59823060654be8da37c9a6fb 100644 (file)
@@ -646,7 +646,8 @@ struct bgp_filter {
 /* IBGP/EBGP identifier.  We also have a CONFED peer, which is to say,
    a peer who's AS is part of our Confederation.  */
 typedef enum {
-       BGP_PEER_IBGP = 1,
+       BGP_PEER_UNSPECIFIED,
+       BGP_PEER_IBGP,
        BGP_PEER_EBGP,
        BGP_PEER_INTERNAL,
        BGP_PEER_CONFED,
index e4e676061264b609a2978d6dfbc0e0862f9951ea..05e057f07fe358b54d1fcd1374d698cc00447d19 100644 (file)
@@ -575,7 +575,7 @@ static struct rfapi_l2_group_cfg *rfapi_l2_group_lookup_byname(struct bgp *bgp,
        return NULL;
 }
 
-static struct rfapi_l2_group_cfg *rfapi_l2_group_new()
+static struct rfapi_l2_group_cfg *rfapi_l2_group_new(void)
 {
        struct rfapi_l2_group_cfg *rfg;
 
@@ -1396,7 +1396,7 @@ DEFUN (vnc_export_mode,
        return CMD_SUCCESS;
 }
 
-static struct rfapi_rfg_name *rfgn_new()
+static struct rfapi_rfg_name *rfgn_new(void)
 {
        return XCALLOC(MTYPE_RFAPI_RFG_NAME, sizeof(struct rfapi_rfg_name));
 }
index 904d43c65ad8137d1444104555117dbb30c1bd11..6b37073e0e7b0744596a766e5000c6fa0ff3f167 100644 (file)
@@ -123,7 +123,7 @@ void rfapiDebugBacktrace(void)
  * Count remote routes and compare with actively-maintained values.
  * Abort if they disagree.
  */
-void rfapiCheckRouteCount()
+void rfapiCheckRouteCount(void)
 {
        struct bgp *bgp = bgp_get_default();
        struct rfapi *h;
index 520cc141c08a0db67624f7334616b2c7e85615fe..8e8acbfb91c3c35fffab3f4a7d9db4129650c4e3 100644 (file)
@@ -222,7 +222,7 @@ void rfapiRibCheckCounts(
        assert(t_ri_active + t_ri_deleted + t_ri_pend + offset == alloc_count);
 }
 
-static struct rfapi_info *rfapi_info_new()
+static struct rfapi_info *rfapi_info_new(void)
 {
        return XCALLOC(MTYPE_RFAPI_INFO, sizeof(struct rfapi_info));
 }
index 04ddff934dc04b450ef0249961969845e65aa449..ea82c254bcecbea7168ac2f5ef6b8b0869e7970c 100644 (file)
@@ -4964,7 +4964,7 @@ DEFUN (clear_vrf_all,
        return vnc_clear_vrf(vty, NULL, arg_vrf, NULL, NULL);
 }
 
-void rfapi_vty_init()
+void rfapi_vty_init(void)
 {
        install_element(ENABLE_NODE, &add_vnc_prefix_cost_life_lnh_cmd);
        install_element(ENABLE_NODE, &add_vnc_prefix_life_cost_lnh_cmd);
index e8f670cf1272f33d5fed49c7fc87bccdcd685f08..060fc765509626bc7e7f6b9813847d4371eeacb8 100644 (file)
@@ -107,7 +107,7 @@ DEFUN (rfp_full_table_download,
        return CMD_SUCCESS;
 }
 
-static void rfp_vty_install()
+static void rfp_vty_install(void)
 {
        static int installed = 0;
        if (installed) /* do this only once */
index 48df6c0cc7689250b7ece7ffb786764ed7937617..1036829b899ff68b80e55fe5af6de1fa990b7e90 100644 (file)
@@ -26,7 +26,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include "rfptest.h"
-int main()
+int main(void)
 {
        printf("Your test code goes here.\n");
        exit(1);
index abc1e8d15e183a871ce3b9b12edebac53de6c496..afdc6336b0251c668badaeb3916d24350958aebc 100755 (executable)
@@ -346,7 +346,7 @@ AM_CONDITIONAL([STATIC_BIN], [test "x$enable_static_bin" = "xyes"])
 
 dnl $AR and $RANLIB are set by LT_INIT above
 AC_MSG_CHECKING([whether $AR supports D option])
-if $AR crD conftest.a; then
+if $AR crD conftest.a >/dev/null 2>/dev/null; then
   AC_MSG_RESULT([yes])
   dnl ARFLAGS is for automake, AR_FLAGS for libtool m-(
   ARFLAGS="crD"
@@ -360,7 +360,7 @@ AC_SUBST([ARFLAGS])
 AC_SUBST([AR_FLAGS])
 
 AC_MSG_CHECKING([whether $RANLIB supports D option])
-if $RANLIB -D conftest.a; then
+if $RANLIB -D conftest.a >/dev/null 2>/dev/null; then
   AC_MSG_RESULT([yes])
   RANLIB="$RANLIB -D"
 else
@@ -817,15 +817,17 @@ fi
 AM_CONDITIONAL([GIT_VERSION], [test "x$with_pkg_git_version" = "xyes"])
 
 AC_CHECK_TOOL([OBJCOPY], [objcopy], [:])
-AC_CACHE_CHECK([for .interp value to use], [frr_cv_interp], [
-  frr_cv_interp=""
-  AC_LINK_IFELSE([AC_LANG_SOURCE([[int main() { return 0; }]])], [
-    if $OBJCOPY -j.interp -Obinary conftest conftest.interp; then
-      frr_cv_interp="`xargs -0 echo < conftest.interp`"
-    fi
-    test -f conftest.interp && rm conftest.interp
+if test "x${OBJCOPY}" != "x:"; then
+  AC_CACHE_CHECK([for .interp value to use], [frr_cv_interp], [
+    frr_cv_interp=""
+    AC_LINK_IFELSE([AC_LANG_SOURCE([[int main() { return 0; }]])], [
+      if $OBJCOPY -j.interp -Obinary conftest conftest.interp; then
+        frr_cv_interp="`xargs -0 echo < conftest.interp`"
+      fi
+      test -f conftest.interp && rm conftest.interp
+    ])
   ])
-])
+fi
 if test -n "$frr_cv_interp"; then
   AC_DEFINE_UNQUOTED([INTERP], ["$frr_cv_interp"], [.interp value])
 fi
@@ -1608,6 +1610,24 @@ AC_CHECK_MEMBER([struct lyd_node.priv], [], [
   ])
 ], [[#include <libyang/libyang.h>]])
 
+ac_ld_flag_save="$LDFLAGS"
+LDFLAGS="$LDFLAGS $libyang_LIBS"
+AC_CHECK_FUNC([ly_register_types], [
+  libyang_ext_builtin=true
+  AC_DEFINE([LIBYANG_EXT_BUILTIN], [1], [have ly_register_types()])
+], [
+  libyang_ext_builtin=false
+  AC_MSG_WARN([===== old libyang (before 0.16.74) detected =====])
+  AC_MSG_WARN([The available version of libyang does not seem to support])
+  AC_MSG_WARN([built-in YANG extension modules.  This will cause "make check"])
+  AC_MSG_WARN([to fail and may create installation and version mismatch issues.])
+  AC_MSG_WARN([Support for the old mechanism will be removed at some point.])
+  AC_MSG_WARN([Please update libyang to version 0.16.74 or newer.])
+  AC_MSG_WARN([===== old libyang (before 0.16.74) detected =====])
+])
+AM_CONDITIONAL([LIBYANG_EXT_BUILTIN], [$libyang_ext_builtin])
+LDFLAGS="$ac_ld_flag_save"
+
 dnl ---------------
 dnl configuration rollbacks
 dnl ---------------
index 005b6ba78680a49ac39d13e226934c8d2e69bded..c45c294b75295db8640da9422235c04e2a093fc7 100644 (file)
@@ -4,6 +4,13 @@ The libyang library can be installed from third-party packages available `here
 Note: the libyang dev/devel packages need to be installed in addition
 to the libyang core package in order to build FRR successfully.
 
+.. warning::
+   libyang ABI version 0.16.74 or newer will be required to build FRR in the
+   near future since it significantly eases build and installation
+   considerations.  "0.16-r3" is equal to 0.16.105 and will work, "0.16-r2"
+   is equal to 0.16.52 and will stop working.  The CI artifacts will be
+   updated shortly.
+
 For example, for CentOS 7.x:
 
 .. code-block:: shell
@@ -21,6 +28,14 @@ or Ubuntu 18.04:
    sudo apt install libpcre3-dev
    sudo dpkg -i libyang-dev_0.16.46_amd64.deb libyang_0.16.46_amd64.deb
 
+.. note::
+   For Debian-based systems, the official libyang package requires recent
+   versions of swig (3.0.12) and debhelper (11) which are only available in
+   Debian buster (10).  However, libyang packages built on Debian buster can
+   be installed on both Debian jessie (8) and Debian stretch (9), as well as
+   various Ubuntu systems.  The python3-yang package will not work, but the
+   other packages (libyang-dev is the one needed for FRR) will.
+
 Alternatively, libyang can be built and installed manually by following
 the steps below:
 
index 99c79462abd57b6c721c808241f7ab40af0d50b6..763d8b1b8d5a1636448e01358adb7378a4717e36 100644 (file)
@@ -53,6 +53,14 @@ Basic boilerplate:
 
     #include "hook.h"
     #include "module.h"
+    #include "libfrr.h"
+    #include "thread.h"
+
+    static int module_late_init(struct thread_master *master)
+    {
+        /* Do initialization stuff here */
+        return 0;
+    }
 
     static int
     module_init (void)
index ebca53ea32ea48134c434e4bd1778da8046f64ff..4e1582ccd8f8a2a57b924b6e89d1f61fd24c05b8 100644 (file)
@@ -335,6 +335,9 @@ options to the configuration script.
    Look for libyang plugins in `dir` [`prefix`/lib/frr/libyang_plugins].
    Note that the FRR libyang plugins will be installed here.
 
+   This option is meaningless with libyang 0.16.74 or newer and will be
+   removed once support for older libyang versions is dropped.
+
 When it's desired to run FRR without installing it in the system, it's possible
 to configure it as follows to look for YANG modules and libyang plugins in the
 compile directory:
index c975c0abc7b6cef50b2b48c03edd4560e4194445..876e1cac0735ade2c1fee7248b3d86b096799cb9 100644 (file)
@@ -605,7 +605,7 @@ static struct cmd_node eigrp_debug_node = {
 };
 
 /* Initialize debug commands. */
-void eigrp_debug_init()
+void eigrp_debug_init(void)
 {
        install_node(&eigrp_debug_node, config_write_debug);
 
index e450c7d999322c23a718bda5c2f30b690d8c87e9..e6cfe1deea7f00127bbb6c55bf737708d4102111 100644 (file)
@@ -122,7 +122,7 @@ int eigrp_if_delete_hook(struct interface *ifp)
 
 struct list *eigrp_iflist;
 
-void eigrp_if_init()
+void eigrp_if_init(void)
 {
        /* Initialize Zebra interface data structure. */
        // hook_register_prio(if_add, 0, eigrp_if_new);
index f3b583abdde65cfddf1e33793abb4f0223b7c67d..ee0476b28dab00a8d8895facc00c157280c6909e 100644 (file)
@@ -1101,7 +1101,7 @@ struct eigrp_packet *eigrp_packet_duplicate(struct eigrp_packet *old,
        return new;
 }
 
-static struct TLV_IPv4_Internal_type *eigrp_IPv4_InternalTLV_new()
+static struct TLV_IPv4_Internal_type *eigrp_IPv4_InternalTLV_new(void)
 {
        struct TLV_IPv4_Internal_type *new;
 
@@ -1327,7 +1327,7 @@ uint16_t eigrp_add_authTLV_SHA256_to_stream(struct stream *s,
        return 0;
 }
 
-struct TLV_MD5_Authentication_Type *eigrp_authTLV_MD5_new()
+struct TLV_MD5_Authentication_Type *eigrp_authTLV_MD5_new(void)
 {
        struct TLV_MD5_Authentication_Type *new;
 
@@ -1342,7 +1342,7 @@ void eigrp_authTLV_MD5_free(struct TLV_MD5_Authentication_Type *authTLV)
        XFREE(MTYPE_EIGRP_AUTH_TLV, authTLV);
 }
 
-struct TLV_SHA256_Authentication_Type *eigrp_authTLV_SHA256_new()
+struct TLV_SHA256_Authentication_Type *eigrp_authTLV_SHA256_new(void)
 {
        struct TLV_SHA256_Authentication_Type *new;
 
@@ -1363,7 +1363,7 @@ void eigrp_IPv4_InternalTLV_free(
        XFREE(MTYPE_EIGRP_IPV4_INT_TLV, IPv4_InternalTLV);
 }
 
-struct TLV_Sequence_Type *eigrp_SequenceTLV_new()
+struct TLV_Sequence_Type *eigrp_SequenceTLV_new(void)
 {
        struct TLV_Sequence_Type *new;
 
index 0cb4e0e9f45c3d2086fd399393f287ab16ebf7d1..2d0ebf1bc56b083b56cb4073d2bad2383e5f6e3e 100644 (file)
@@ -61,7 +61,7 @@ static int eigrp_nexthop_entry_cmp(struct eigrp_nexthop_entry *,
  * del - assigned function executed before deleting topology node by list
  * function
  */
-struct route_table *eigrp_topology_new()
+struct route_table *eigrp_topology_new(void)
 {
        return route_table_init();
 }
@@ -70,7 +70,7 @@ struct route_table *eigrp_topology_new()
  * Returns new created toplogy node
  * cmp - assigned function for comparing topology entry
  */
-struct eigrp_prefix_entry *eigrp_prefix_entry_new()
+struct eigrp_prefix_entry *eigrp_prefix_entry_new(void)
 {
        struct eigrp_prefix_entry *new;
        new = XCALLOC(MTYPE_EIGRP_PREFIX_ENTRY,
@@ -102,7 +102,7 @@ static int eigrp_nexthop_entry_cmp(struct eigrp_nexthop_entry *entry1,
  * Returns new topology entry
  */
 
-struct eigrp_nexthop_entry *eigrp_nexthop_entry_new()
+struct eigrp_nexthop_entry *eigrp_nexthop_entry_new(void)
 {
        struct eigrp_nexthop_entry *new;
 
index 5541ec15f343f695971ee2f63624d5244533b555..69d947e59fbb0b14752bef48db626f1823fc8ad4 100644 (file)
@@ -122,7 +122,7 @@ void eigrp_router_id_update(struct eigrp *eigrp)
        }
 }
 
-void eigrp_master_init()
+void eigrp_master_init(void)
 {
        struct timeval tv;
 
diff --git a/include/linux/if_addr.h b/include/linux/if_addr.h
new file mode 100644 (file)
index 0000000..a924606
--- /dev/null
@@ -0,0 +1,69 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef __LINUX_IF_ADDR_H
+#define __LINUX_IF_ADDR_H
+
+#include <linux/types.h>
+#include <linux/netlink.h>
+
+struct ifaddrmsg {
+       __u8            ifa_family;
+       __u8            ifa_prefixlen;  /* The prefix length            */
+       __u8            ifa_flags;      /* Flags                        */
+       __u8            ifa_scope;      /* Address scope                */
+       __u32           ifa_index;      /* Link index                   */
+};
+
+/*
+ * Important comment:
+ * IFA_ADDRESS is prefix address, rather than local interface address.
+ * It makes no difference for normally configured broadcast interfaces,
+ * but for point-to-point IFA_ADDRESS is DESTINATION address,
+ * local address is supplied in IFA_LOCAL attribute.
+ *
+ * IFA_FLAGS is a u32 attribute that extends the u8 field ifa_flags.
+ * If present, the value from struct ifaddrmsg will be ignored.
+ */
+enum {
+       IFA_UNSPEC,
+       IFA_ADDRESS,
+       IFA_LOCAL,
+       IFA_LABEL,
+       IFA_BROADCAST,
+       IFA_ANYCAST,
+       IFA_CACHEINFO,
+       IFA_MULTICAST,
+       IFA_FLAGS,
+       IFA_RT_PRIORITY,  /* u32, priority/metric for prefix route */
+       __IFA_MAX,
+};
+
+#define IFA_MAX (__IFA_MAX - 1)
+
+/* ifa_flags */
+#define IFA_F_SECONDARY                0x01
+#define IFA_F_TEMPORARY                IFA_F_SECONDARY
+
+#define        IFA_F_NODAD             0x02
+#define IFA_F_OPTIMISTIC       0x04
+#define IFA_F_DADFAILED                0x08
+#define        IFA_F_HOMEADDRESS       0x10
+#define IFA_F_DEPRECATED       0x20
+#define IFA_F_TENTATIVE                0x40
+#define IFA_F_PERMANENT                0x80
+#define IFA_F_MANAGETEMPADDR   0x100
+#define IFA_F_NOPREFIXROUTE    0x200
+#define IFA_F_MCAUTOJOIN       0x400
+#define IFA_F_STABLE_PRIVACY   0x800
+
+struct ifa_cacheinfo {
+       __u32   ifa_prefered;
+       __u32   ifa_valid;
+       __u32   cstamp; /* created timestamp, hundredths of seconds */
+       __u32   tstamp; /* updated timestamp, hundredths of seconds */
+};
+
+/* backwards compatibility for userspace */
+#define IFA_RTA(r)  ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifaddrmsg))))
+#define IFA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifaddrmsg))
+
+#endif
index 731785d4b4dd61ffdfe802197d8abf8601e5f69e..0d7fed28529e12bcf0f6fe869640363dd974908c 100644 (file)
@@ -1,4 +1,5 @@
 noinst_HEADERS += \
+       include/linux/if_addr.h \
        include/linux/if_bridge.h \
        include/linux/if_link.h \
        include/linux/lwtunnel.h \
index 81b4b397ecb0eda77620eddc650fac68b0e02360..36d4a0d7c06a7b24883daa9cce9db68f49df3690 100644 (file)
@@ -69,7 +69,7 @@ int isis_interface_config_write(struct vty *);
 int isis_if_new_hook(struct interface *);
 int isis_if_delete_hook(struct interface *);
 
-struct isis_circuit *isis_circuit_new()
+struct isis_circuit *isis_circuit_new(void)
 {
        struct isis_circuit *circuit;
        int i;
@@ -1393,7 +1393,7 @@ int isis_if_delete_hook(struct interface *ifp)
        return 0;
 }
 
-void isis_circuit_init()
+void isis_circuit_init(void)
 {
        /* Initialize Zebra interface data structure */
        hook_register_prio(if_add, 0, isis_if_new_hook);
index b6f751463a7ce187478f50f557ba319a456c0213..1f283091050ba7809e2f33cfee79345831e82860 100644 (file)
@@ -1471,7 +1471,7 @@ DEFUN (show_isis_topology,
        return CMD_SUCCESS;
 }
 
-void isis_spf_cmds_init()
+void isis_spf_cmds_init(void)
 {
        install_element(VIEW_NODE, &show_isis_topology_cmd);
 }
index a69c95cadf8ce9073661cf07e5f00a68e39fa7bf..23a1f10a18adf3d20102a839a048ad11c4a914b6 100644 (file)
@@ -68,7 +68,7 @@ const char *mode2text[] = {"Disable", "Area", "AS", "Emulate"};
  *------------------------------------------------------------------------*/
 
 /* Create new MPLS TE Circuit context */
-struct mpls_te_circuit *mpls_te_circuit_new()
+struct mpls_te_circuit *mpls_te_circuit_new(void)
 {
        struct mpls_te_circuit *mtc;
 
index 419127c34e4db8edc6c227273a84f7cf2773aa1b..13cd510dd13885293516ef376c82bcff405cdf72 100644 (file)
@@ -2161,7 +2161,7 @@ int isis_config_write(struct vty *vty)
 
 struct cmd_node router_node = {ROUTER_NODE, "%s(config-router)# ", 1};
 
-void isis_init()
+void isis_init(void)
 {
        /* Install IS-IS top node */
        install_node(&router_node, isis_config_write);
index 05ccb52ab574a92b53e2a47be86b5fa44777371c..06879f6854470bd9fbdbd1a8db4a9090af52deea 100644 (file)
@@ -2515,8 +2515,6 @@ DEFUN (config_log_syslog,
 {
        int idx_log_levels = 2;
 
-       disable_log_file();
-
        if (argc == 3) {
                int level;
                if ((level = level_match(argv[idx_log_levels]->arg))
@@ -2883,7 +2881,7 @@ void cmd_init(int terminal)
 #endif
 }
 
-void cmd_terminate()
+void cmd_terminate(void)
 {
        struct cmd_node *cmd_node;
 
index 1aae58b61ca59c1b53ab7cf3c2f83548cba0fe1e..317c1b68b78609d1a8634b080b28c36a8cc9f21a 100644 (file)
@@ -2212,14 +2212,14 @@ static void access_list_init_ipv6(void)
        install_element(CONFIG_NODE, &no_ipv6_access_list_remark_comment_cmd);
 }
 
-void access_list_init()
+void access_list_init(void)
 {
        access_list_init_ipv4();
        access_list_init_ipv6();
        access_list_init_mac();
 }
 
-void access_list_reset()
+void access_list_reset(void)
 {
        access_list_reset_ipv4();
        access_list_reset_ipv6();
index d5a2007c4df64c7b1b1ca3046dcf6ff350516d60..fe18eb1051384bb06ca76f27a2dd0dff733c7798 100644 (file)
@@ -47,7 +47,7 @@ static struct list *frr_pthread_list;
 
 /* ------------------------------------------------------------------------ */
 
-void frr_pthread_init()
+void frr_pthread_init(void)
 {
        pthread_mutex_lock(&frr_pthread_list_mtx);
        {
@@ -57,7 +57,7 @@ void frr_pthread_init()
        pthread_mutex_unlock(&frr_pthread_list_mtx);
 }
 
-void frr_pthread_finish()
+void frr_pthread_finish(void)
 {
        pthread_mutex_lock(&frr_pthread_list_mtx);
        {
@@ -124,7 +124,7 @@ int frr_pthread_set_name(struct frr_pthread *fpt)
 #ifdef HAVE_PTHREAD_SETNAME_NP
 # ifdef GNU_LINUX
        ret = pthread_setname_np(fpt->thread, fpt->os_name);
-# else /* NetBSD */
+# elif defined(__NetBSD__)
        ret = pthread_setname_np(fpt->thread, fpt->os_name, NULL);
 # endif
 #elif defined(HAVE_PTHREAD_SET_NAME_NP)
@@ -178,7 +178,7 @@ int frr_pthread_stop(struct frr_pthread *fpt, void **result)
        return ret;
 }
 
-void frr_pthread_stop_all()
+void frr_pthread_stop_all(void)
 {
        pthread_mutex_lock(&frr_pthread_list_mtx);
        {
index 4bc3eb82b8521b9b4bc4dd331ef824d1fa8fbe3d..128e45c57002951d8e64ef70bb30f10dcb51d176 100644 (file)
@@ -27,7 +27,7 @@
 
 DEFINE_MTYPE_STATIC(LIB, GRAPH, "Graph")
 DEFINE_MTYPE_STATIC(LIB, GRAPH_NODE, "Graph Node")
-struct graph *graph_new()
+struct graph *graph_new(void)
 {
        struct graph *graph = XCALLOC(MTYPE_GRAPH, sizeof(struct graph));
        graph->nodes = vector_init(VECTOR_MIN_SIZE);
index 641c75136872800825d1795233e643e74406873a..6c3c953e977656547e0b9b0195cd5022eba781b1 100644 (file)
@@ -445,7 +445,7 @@ DEFUN_NOSH(show_hash_stats,
        return CMD_SUCCESS;
 }
 
-void hash_cmd_init()
+void hash_cmd_init(void)
 {
        install_element(ENABLE_NODE, &show_hash_stats_cmd);
 }
index 166bfa92b52b610e7ae95ca1627018e72204ee11..5b46ed820462db746164896767af1b66193fc32b 100644 (file)
--- a/lib/if.h
+++ b/lib/if.h
@@ -341,6 +341,8 @@ DECLARE_QOBJ_TYPE(interface)
 DECLARE_HOOK(if_add, (struct interface * ifp), (ifp))
 DECLARE_KOOH(if_del, (struct interface * ifp), (ifp))
 
+#define METRIC_MAX (~0)
+
 /* Connected address structure. */
 struct connected {
        /* Attached interface. */
@@ -388,6 +390,13 @@ struct connected {
 
        /* Label for Linux 2.2.X and upper. */
        char *label;
+
+       /*
+        * Used for setting the connected route's cost. If the metric
+        * here is set to METRIC_MAX the connected route falls back to
+        * "struct interface"
+        */
+       uint32_t metric;
 };
 
 /* Nbr Connected address structure. */
index 108ab7ec6b5dacc737970eae4fb60dbbf766938e..69da695dcbe2a21274494363223f68fa2947afd0 100644 (file)
@@ -287,7 +287,7 @@ int config_write_if_rmap(struct vty *vty)
        return write;
 }
 
-void if_rmap_reset()
+void if_rmap_reset(void)
 {
        hash_clean(ifrmaphash, (void (*)(void *))if_rmap_free);
 }
index 601b44a4f1abe71b2da86129fdd6e736e9f098a3..9aa3ef695f3833929e1149e6f1bc2e3aaa0565c4 100644 (file)
@@ -1040,7 +1040,7 @@ static int keychain_config_write(struct vty *vty)
        return 0;
 }
 
-void keychain_init()
+void keychain_init(void)
 {
        keychain_list = list_new();
 
index 8989a93c597b2fb133c4e009b4f00fca5609a4b0..5a3e7c8d1bb4871cc0d3304a0941d7fb660ab1a4 100644 (file)
--- a/lib/md5.c
+++ b/lib/md5.c
@@ -375,13 +375,8 @@ static void md5_calc(const uint8_t *b64, md5_ctxt *ctxt)
 }
 
 /* From RFC 2104 */
-void hmac_md5(text, text_len, key, key_len,
-             digest) unsigned char *text; /* pointer to data stream */
-int text_len;                             /* length of data stream */
-unsigned char *key;                       /* pointer to authentication key */
-int key_len;                              /* length of authentication key */
-uint8_t *digest;                          /* caller digest to be filled in */
-
+void hmac_md5(unsigned char *text, int text_len, unsigned char *key,
+             int key_len, uint8_t *digest)
 {
        MD5_CTX context;
        unsigned char k_ipad[65]; /* inner padding -
index ee68fbc0f12bfa57fda07547ec33a0d264508a16..41c8e4f8c0246fdc9b0921c77f7c33db8bf24d83 100644 (file)
@@ -2111,7 +2111,7 @@ static void prefix_list_init_ipv6(void)
        install_element(ENABLE_NODE, &clear_ipv6_prefix_list_cmd);
 }
 
-void prefix_list_init()
+void prefix_list_init(void)
 {
        cmd_variable_handler_register(plist_var_handlers);
 
@@ -2119,7 +2119,7 @@ void prefix_list_init()
        prefix_list_init_ipv6();
 }
 
-void prefix_list_reset()
+void prefix_list_reset(void)
 {
        prefix_list_reset_afi(AFI_IP, 0);
        prefix_list_reset_afi(AFI_IP6, 0);
index 0203301562f5df3382b8233423df420c1c0f891d..07eb1785b7f911bddf536bcb2220d18bb4882fe3 100644 (file)
@@ -820,7 +820,7 @@ const char *prefix_family_str(const struct prefix *p)
 }
 
 /* Allocate new prefix_ipv4 structure. */
-struct prefix_ipv4 *prefix_ipv4_new()
+struct prefix_ipv4 *prefix_ipv4_new(void)
 {
        struct prefix_ipv4 *p;
 
@@ -1359,7 +1359,7 @@ const char *prefix2str(union prefixconstptr pu, char *str, int size)
        return str;
 }
 
-struct prefix *prefix_new()
+struct prefix *prefix_new(void)
 {
        struct prefix *p;
 
index 66384fe4492af8e3f59037dbf7c178557308e295..7435272761c631f5ddd69121ee4a0684363f9462 100755 (executable)
@@ -121,7 +121,7 @@ sub codelist {
        }
        $str =~ s/ $//;
        push @lines, $str . "\\n\" \\\n";
-       push @lines, "  \"       > - selected route, * - FIB route\\n\\n\"";
+       push @lines, "  \"       > - selected route, * - FIB route, q - queued route, f - failed route\\n\\n\"";
        return join("", @lines);
 }
 
index 3933429c3b0bd737dde7fda12cea324dc81c4b15..dda442580a2c87d9e87e67cbde7b0514dfc93bf9 100644 (file)
@@ -88,7 +88,7 @@ static struct skiplist *skiplist_last_created; /* debugging hack */
 #endif
 
 
-static int randomLevel()
+static int randomLevel(void)
 {
        register int level = 0;
        register int b;
index 4f5f9ff218ef724de1e9e40c3b6966b3c21d57ea..01468b820363645e746a3f0ef53753f04b523941 100644 (file)
@@ -163,7 +163,7 @@ static struct ttable_cell *ttable_insert_row_va(struct ttable *tt, int i,
 
        orig = res;
 
-       while (res) {
+       while (res && col < tt->ncols) {
                section = strsep(&res, "|");
                row[col].text = XSTRDUP(MTYPE_TTABLE, section);
                row[col].style = tt->style.cell;
index 867ca2dc6040c43955aec479d0c7476e92790a47..ae8e375a27c9405b9a49916a9c4da582ad6ecbce 100644 (file)
@@ -400,7 +400,7 @@ static void cancelreq_del(void *cr)
 }
 
 /* initializer, only ever called once */
-static void initializer()
+static void initializer(void)
 {
        pthread_key_create(&thread_current, NULL);
 }
index 8450922c2bb26e2554da72ff469c1fe15239dc37..d6fda8cbb4596735b1c648de22ec5046ff1099cc 100644 (file)
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -1605,7 +1605,7 @@ static int vty_flush(struct thread *thread)
 }
 
 /* Allocate new vty struct. */
-struct vty *vty_new()
+struct vty *vty_new(void)
 {
        struct vty *new = XCALLOC(MTYPE_VTY, sizeof(struct vty));
 
@@ -3035,7 +3035,7 @@ struct cmd_node vty_node = {
 };
 
 /* Reset all VTY status. */
-void vty_reset()
+void vty_reset(void)
 {
        unsigned int i;
        struct vty *vty;
@@ -3100,7 +3100,7 @@ static void vty_save_cwd(void)
        strcpy(vty_cwd, cwd);
 }
 
-char *vty_get_cwd()
+char *vty_get_cwd(void)
 {
        return vty_cwd;
 }
@@ -3115,7 +3115,7 @@ int vty_shell_serv(struct vty *vty)
        return vty->type == VTY_SHELL_SERV ? 1 : 0;
 }
 
-void vty_init_vtysh()
+void vty_init_vtysh(void)
 {
        vtyvec = vector_init(VECTOR_MIN_SIZE);
 }
index 71b41c35d8225a660650a573549b1c93617c12a2..f62a8163f9760e0cd70d558529491ce154dbbdd7 100644 (file)
@@ -26,6 +26,8 @@
 #include "yang_translator.h"
 #include "northbound.h"
 
+#include <libyang/user_types.h>
+
 DEFINE_MTYPE(LIB, YANG_MODULE, "YANG module")
 DEFINE_MTYPE(LIB, YANG_DATA, "YANG data structure")
 
@@ -639,8 +641,18 @@ static void ly_log_cb(LY_LOG_LEVEL level, const char *msg, const char *path)
                zlog(priority, "libyang: %s", msg);
 }
 
+#if CONFDATE > 20190401
+CPP_NOTICE("lib/yang: time to remove non-LIBYANG_EXT_BUILTIN support")
+#endif
+
+#ifdef LIBYANG_EXT_BUILTIN
+extern struct lytype_plugin_list frr_user_types[];
+#endif
+
 void yang_init(void)
 {
+#ifndef LIBYANG_EXT_BUILTIN
+CPP_NOTICE("lib/yang: deprecated libyang <0.16.74 extension loading in use!")
        static char ly_plugin_dir[PATH_MAX];
        const char *const *ly_loaded_plugins;
        const char *ly_plugin;
@@ -650,11 +662,20 @@ void yang_init(void)
        snprintf(ly_plugin_dir, sizeof(ly_plugin_dir), "%s=%s",
                 "LIBYANG_USER_TYPES_PLUGINS_DIR", LIBYANG_PLUGINS_PATH);
        putenv(ly_plugin_dir);
+#endif
 
        /* Initialize libyang global parameters that affect all containers. */
        ly_set_log_clb(ly_log_cb, 1);
        ly_log_options(LY_LOLOG | LY_LOSTORE);
 
+#ifdef LIBYANG_EXT_BUILTIN
+       if (ly_register_types(frr_user_types, "frr_user_types")) {
+               flog_err(EC_LIB_LIBYANG_PLUGIN_LOAD,
+                        "ly_register_types() failed");
+               exit(1);
+       }
+#endif
+
        /* Initialize libyang container for native models. */
        ly_native_ctx =
                ly_ctx_new(YANG_MODELS_PATH, LY_CTX_DISABLE_SEARCHDIR_CWD);
@@ -665,6 +686,7 @@ void yang_init(void)
        ly_ctx_set_module_imp_clb(ly_native_ctx, yang_module_imp_clb, NULL);
        ly_ctx_set_priv_dup_clb(ly_native_ctx, ly_dup_cb);
 
+#ifndef LIBYANG_EXT_BUILTIN
        /* Detect if the required libyang plugin(s) were loaded successfully. */
        ly_loaded_plugins = ly_get_loaded_plugins();
        for (size_t i = 0; (ly_plugin = ly_loaded_plugins[i]); i++) {
@@ -678,6 +700,7 @@ void yang_init(void)
                         "%s: failed to load frr_user_types.so", __func__);
                exit(1);
        }
+#endif
 
        yang_translator_init();
 }
index 95f0a990b21c53cbbf1e26c4a061a2d5c52e4a0d..8a3423cdd8c16f23d97d3aac4cff311608a7ee80 100644 (file)
@@ -426,6 +426,8 @@ enum zapi_iptable_notify_owner {
 #define ZEBRA_MACIP_TYPE_ROUTER_FLAG           0x04 /* Router Flag - proxy NA */
 #define ZEBRA_MACIP_TYPE_OVERRIDE_FLAG         0x08 /* Override Flag */
 
+enum zebra_neigh_state { ZEBRA_NEIGH_INACTIVE = 0, ZEBRA_NEIGH_ACTIVE = 1 };
+
 struct zclient_options {
        bool receive_notify;
 };
index dc7a3f6d45766c8f8b848b45273fbdcab741a6da..671267aa05e7ace5f568db226f6db7af91ae3615 100644 (file)
@@ -1897,7 +1897,7 @@ int config_write_ospf6_debug_asbr(struct vty *vty)
        return 0;
 }
 
-void install_element_ospf6_debug_asbr()
+void install_element_ospf6_debug_asbr(void)
 {
        install_element(ENABLE_NODE, &debug_ospf6_asbr_cmd);
        install_element(ENABLE_NODE, &no_debug_ospf6_asbr_cmd);
index 2bfa4201cbce5bed54f907745c25223ba198f630..dd08144daaf33ece08b4f7a3dcc6e9c21fbf074a 100644 (file)
@@ -246,6 +246,7 @@ void ospf6_interface_delete(struct ospf6_interface *oi)
        THREAD_OFF(oi->thread_send_hello);
        THREAD_OFF(oi->thread_send_lsupdate);
        THREAD_OFF(oi->thread_send_lsack);
+       THREAD_OFF(oi->thread_sso);
 
        ospf6_lsdb_remove_all(oi->lsdb);
        ospf6_lsdb_remove_all(oi->lsupdate_list);
@@ -291,6 +292,7 @@ void ospf6_interface_disable(struct ospf6_interface *oi)
        THREAD_OFF(oi->thread_send_hello);
        THREAD_OFF(oi->thread_send_lsupdate);
        THREAD_OFF(oi->thread_send_lsack);
+       THREAD_OFF(oi->thread_sso);
 
        THREAD_OFF(oi->thread_network_lsa);
        THREAD_OFF(oi->thread_link_lsa);
@@ -381,9 +383,9 @@ void ospf6_interface_state_update(struct interface *ifp)
        if (if_is_operative(ifp)
            && (ospf6_interface_get_linklocal_address(oi->interface)
                || if_is_loopback(oi->interface)))
-               thread_add_event(master, interface_up, oi, 0, NULL);
+               thread_execute(master, interface_up, oi, 0);
        else
-               thread_add_event(master, interface_down, oi, 0, NULL);
+               thread_execute(master, interface_down, oi, 0);
 
        return;
 }
@@ -679,6 +681,12 @@ int interface_up(struct thread *thread)
        oi = (struct ospf6_interface *)THREAD_ARG(thread);
        assert(oi && oi->interface);
 
+       /*
+        * Remove old pointer. If this thread wasn't a timer this
+        * operation won't make a difference, because it is already NULL.
+        */
+       oi->thread_sso = NULL;
+
        if (IS_OSPF6_DEBUG_INTERFACE)
                zlog_debug("Interface Event %s: [InterfaceUp]",
                           oi->interface->name);
@@ -721,6 +729,22 @@ int interface_up(struct thread *thread)
                return 0;
        }
 
+#ifdef __FreeBSD__
+       /*
+        * XXX: Schedule IPv6 group join for later, otherwise we might
+        * lose the multicast group registration caused by IPv6 group
+        * leave race.
+        */
+       if (oi->sso_try_cnt == 0) {
+               oi->sso_try_cnt++;
+               zlog_info("Scheduling %s for sso", oi->interface->name);
+               thread_add_timer(master, interface_up, oi,
+                                OSPF6_INTERFACE_SSO_RETRY_INT,
+                                &oi->thread_sso);
+               return 0;
+       }
+#endif /* __FreeBSD__ */
+
        /* Join AllSPFRouters */
        if (ospf6_sso(oi->interface->ifindex, &allspfrouters6, IPV6_JOIN_GROUP)
            < 0) {
@@ -729,7 +753,8 @@ int interface_up(struct thread *thread)
                                "Scheduling %s for sso retry, trial count: %d",
                                oi->interface->name, oi->sso_try_cnt);
                        thread_add_timer(master, interface_up, oi,
-                                        OSPF6_INTERFACE_SSO_RETRY_INT, NULL);
+                                        OSPF6_INTERFACE_SSO_RETRY_INT,
+                                        &oi->thread_sso);
                }
                return 0;
        }
@@ -830,6 +855,9 @@ int interface_down(struct thread *thread)
        /* Stop Hellos */
        THREAD_OFF(oi->thread_send_hello);
 
+       /* Stop trying to set socket options. */
+       THREAD_OFF(oi->thread_sso);
+
        /* Leave AllSPFRouters */
        if (oi->state > OSPF6_INTERFACE_DOWN)
                ospf6_sso(oi->interface->ifindex, &allspfrouters6,
@@ -1602,6 +1630,7 @@ DEFUN (ipv6_ospf6_passive,
 
        SET_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE);
        THREAD_OFF(oi->thread_send_hello);
+       THREAD_OFF(oi->thread_sso);
 
        for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
                THREAD_OFF(on->inactivity_timer);
@@ -1631,7 +1660,7 @@ DEFUN (no_ipv6_ospf6_passive,
 
        UNSET_FLAG(oi->flag, OSPF6_INTERFACE_PASSIVE);
        THREAD_OFF(oi->thread_send_hello);
-       oi->thread_send_hello = NULL;
+       THREAD_OFF(oi->thread_sso);
        thread_add_event(master, ospf6_hello_send, oi, 0,
                         &oi->thread_send_hello);
 
@@ -1791,8 +1820,8 @@ DEFUN (ipv6_ospf6_network,
        }
 
        /* Reset the interface */
-       thread_add_event(master, interface_down, oi, 0, NULL);
-       thread_add_event(master, interface_up, oi, 0, NULL);
+       thread_execute(master, interface_down, oi, 0);
+       thread_execute(master, interface_up, oi, 0);
 
        return CMD_SUCCESS;
 }
@@ -1825,8 +1854,8 @@ DEFUN (no_ipv6_ospf6_network,
        oi->type = type;
 
        /* Reset the interface */
-       thread_add_event(master, interface_down, oi, 0, NULL);
-       thread_add_event(master, interface_up, oi, 0, NULL);
+       thread_execute(master, interface_down, oi, 0);
+       thread_execute(master, interface_up, oi, 0);
 
        return CMD_SUCCESS;
 }
@@ -1969,8 +1998,8 @@ static void ospf6_interface_clear(struct vty *vty, struct interface *ifp)
                zlog_debug("Interface %s: clear by reset", ifp->name);
 
        /* Reset the interface */
-       thread_add_event(master, interface_down, oi, 0, NULL);
-       thread_add_event(master, interface_up, oi, 0, NULL);
+       thread_execute(master, interface_down, oi, 0);
+       thread_execute(master, interface_up, oi, 0);
 }
 
 /* Clear interface */
index 8fd43f099a03c0b3bca4c549e4d3afdc543afc88..e0c39a29b40a83e9bb8c0be28bb4e71a3d828f70 100644 (file)
@@ -80,6 +80,7 @@ struct ospf6_interface {
 
        /* Interface socket setting trial counter, resets on success */
        uint8_t sso_try_cnt;
+       struct thread *thread_sso;
 
        /* OSPF6 Interface flag */
        char flag;
index b1175a2f68cc3f7e080fff2048a7a3945b439c49..a3b337a0c0b782dbd7caabb95af8ada37ee43d1a 100644 (file)
@@ -300,7 +300,7 @@ uint32_t msg_get_seq(struct msg *msg)
  * -----------------------------------------------------------
  */
 
-struct msg_fifo *msg_fifo_new()
+struct msg_fifo *msg_fifo_new(void)
 {
        return XCALLOC(MTYPE_OSPF_API_FIFO, sizeof(struct msg_fifo));
 }
index f1477ba14dc531ad32d3f9fba56515302c85aebe..ce1604a5b1c5a667058f549739f54dd7a39c3c4b 100644 (file)
@@ -1182,7 +1182,7 @@ int ospf_vls_in_area(struct ospf_area *area)
 }
 
 
-struct crypt_key *ospf_crypt_key_new()
+struct crypt_key *ospf_crypt_key_new(void)
 {
        return XCALLOC(MTYPE_OSPF_CRYPT_KEY, sizeof(struct crypt_key));
 }
@@ -1230,7 +1230,7 @@ uint8_t ospf_default_iftype(struct interface *ifp)
                return OSPF_IFTYPE_BROADCAST;
 }
 
-void ospf_if_init()
+void ospf_if_init(void)
 {
        /* Initialize Zebra interface data structure. */
        hook_register_prio(if_add, 0, ospf_if_new_hook);
index 609effd874163bff9047345a581eadf1535c0a16..c9710e9165851e24655e192c29be61d1a15716ca 100644 (file)
@@ -150,7 +150,7 @@ int ospf_lsa_checksum_valid(struct lsa_header *lsa)
 
 
 /* Create OSPF LSA. */
-struct ospf_lsa *ospf_lsa_new()
+struct ospf_lsa *ospf_lsa_new(void)
 {
        struct ospf_lsa *new;
 
index f39bea97684c1793fe19171ad77a9503c2a41e03..2e850c4e26705963f6b16bb79609ac40ecddf8ff 100644 (file)
@@ -31,7 +31,7 @@
 #include "ospfd/ospf_lsa.h"
 #include "ospfd/ospf_lsdb.h"
 
-struct ospf_lsdb *ospf_lsdb_new()
+struct ospf_lsdb *ospf_lsdb_new(void)
 {
        struct ospf_lsdb *new;
 
index 5320e77288a0570cf9f9e1efc969f7ec50976381..30f5a2a80e54030326f12a74805477a17b56a41c 100644 (file)
@@ -148,7 +148,7 @@ void ospf_packet_free(struct ospf_packet *op)
        XFREE(MTYPE_OSPF_PACKET, op);
 }
 
-struct ospf_fifo *ospf_fifo_new()
+struct ospf_fifo *ospf_fifo_new(void)
 {
        struct ospf_fifo *new;
 
index 72f6dbe08e220c95e43bf38e1f3cb7f191a140af..4a0d4add150859818160fb5b4677d9c3fcae09e7 100644 (file)
@@ -146,7 +146,7 @@ static int ospf_router_info_register(uint8_t scope)
        return rc;
 }
 
-static int ospf_router_info_unregister()
+static int ospf_router_info_unregister(void)
 {
 
        if ((OspfRI.scope != OSPF_OPAQUE_AS_LSA)
index 7ee91b5b6c9655427fea257512e7fc6f53018c43..da83c1ddafb8a557d39fb09dca88e377698c2725 100644 (file)
@@ -39,7 +39,7 @@
 #include "ospfd/ospf_zebra.h"
 #include "ospfd/ospf_dump.h"
 
-struct ospf_route *ospf_route_new()
+struct ospf_route *ospf_route_new(void)
 {
        struct ospf_route *new;
 
@@ -51,7 +51,7 @@ struct ospf_route *ospf_route_new()
        return new;
 }
 
-void ospf_route_free(struct ospf_route * or)
+void ospf_route_free(struct ospf_route *or)
 {
        if (or->paths)
                list_delete(& or->paths);
@@ -59,7 +59,7 @@ void ospf_route_free(struct ospf_route * or)
        XFREE(MTYPE_OSPF_ROUTE, or);
 }
 
-struct ospf_path *ospf_path_new()
+struct ospf_path *ospf_path_new(void)
 {
        struct ospf_path *new;
 
index 3efc219fcb8c38063bd46152636f178f939bb5ed..bd8cbee11ab2e2ed525649b13adc46b262686ecc 100644 (file)
@@ -150,7 +150,7 @@ static int ospf_mpls_te_register(enum inter_as_mode mode)
        return rc;
 }
 
-static int ospf_mpls_te_unregister()
+static int ospf_mpls_te_unregister(void)
 {
        uint8_t scope;
 
index 0e9b09bf8475d9e3a608264ac1f57d725f69ed69..38387d38c3a7d9f23d6e35476491f18a43e09245 100644 (file)
  * Signal handlers
  */
 
-static void pim_sighup()
+static void pim_sighup(void)
 {
        zlog_info("SIGHUP received, ignoring");
 }
 
-static void pim_sigint()
+static void pim_sigint(void)
 {
        zlog_notice("Terminating on signal SIGINT");
        pim_terminate();
        exit(1);
 }
 
-static void pim_sigterm()
+static void pim_sigterm(void)
 {
        zlog_notice("Terminating on signal SIGTERM");
        pim_terminate();
        exit(1);
 }
 
-static void pim_sigusr1()
+static void pim_sigusr1(void)
 {
        zlog_rotate();
 }
index 9569b7dcac2fa86cfb91e2a329c3cdc202fda3f0..442b22e06fc6c674a40ee62f9b65df0764d2381d 100644 (file)
@@ -37,12 +37,12 @@ void pim_static_route_free(struct static_route *s_route)
        XFREE(MTYPE_PIM_STATIC_ROUTE, s_route);
 }
 
-static struct static_route *static_route_alloc()
+static struct static_route *static_route_alloc(void)
 {
        return XCALLOC(MTYPE_PIM_STATIC_ROUTE, sizeof(struct static_route));
 }
 
-static struct static_route *static_route_new(unsigned int iif, unsigned int oif,
+static struct static_route *static_route_new(ifindex_t iif, ifindex_t oif,
                                             struct in_addr group,
                                             struct in_addr source)
 {
@@ -76,7 +76,7 @@ int pim_static_add(struct pim_instance *pim, struct interface *iif,
        ifindex_t iif_index = pim_iif ? pim_iif->mroute_vif_index : 0;
        ifindex_t oif_index = pim_oif ? pim_oif->mroute_vif_index : 0;
 
-       if (!iif_index || !oif_index) {
+       if (!iif_index || !oif_index || iif_index == -1 || oif_index == -1) {
                zlog_warn(
                        "%s %s: Unable to add static route: Invalid interface index(iif=%d,oif=%d)",
                        __FILE__, __PRETTY_FUNCTION__, iif_index, oif_index);
index 23c85c2fa8e7225d3725b1cf445339ba8ebaeba5..f12f767537512e272408dd99744789cc3b4dc717 100644 (file)
@@ -47,7 +47,7 @@ static int gettime_monotonic(struct timeval *tv)
   pim_time_monotonic_sec():
   number of seconds since some unspecified starting point
 */
-int64_t pim_time_monotonic_sec()
+int64_t pim_time_monotonic_sec(void)
 {
        struct timeval now_tv;
 
@@ -65,7 +65,7 @@ int64_t pim_time_monotonic_sec()
   pim_time_monotonic_dsec():
   number of deciseconds since some unspecified starting point
 */
-int64_t pim_time_monotonic_dsec()
+int64_t pim_time_monotonic_dsec(void)
 {
        struct timeval now_tv;
        int64_t now_dsec;
index b993bcdc03018acd88eb2e35cee0d312a6fc25ab..656b000579f380d73d633b27e9c7f79e2b2e49aa 100644 (file)
@@ -67,7 +67,7 @@ void pim_prefix_list_update(struct prefix_list *plist)
        }
 }
 
-static void pim_free()
+static void pim_free(void)
 {
        pim_route_map_terminate();
 
@@ -123,7 +123,7 @@ void pim_init(void)
        pim_cmd_init();
 }
 
-void pim_terminate()
+void pim_terminate(void)
 {
        struct zclient *zclient;
 
index 96b1cd89387d0a5ab30b0385a66d6104da47b11c..9575f6b8a8d466c80176177e4f35354909618f84 100644 (file)
@@ -563,7 +563,7 @@ int rip_if_down(struct interface *ifp)
 }
 
 /* Needed for stop RIP process. */
-void rip_if_down_all()
+void rip_if_down_all(void)
 {
        struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
        struct interface *ifp;
@@ -964,7 +964,7 @@ void rip_enable_apply(struct interface *ifp)
 }
 
 /* Apply network configuration to all interface. */
-void rip_enable_apply_all()
+void rip_enable_apply_all(void)
 {
        struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
        struct interface *ifp;
@@ -1029,7 +1029,7 @@ int rip_neighbor_delete(struct prefix_ipv4 *p)
 }
 
 /* Clear all network and neighbor configuration. */
-void rip_clean_network()
+void rip_clean_network(void)
 {
        unsigned int i;
        char *str;
index 418ec3fc7b73aef8556f559856d61b9eb7c03e5d..ca273c53b2fc41432a355ad4e7508aa7437c3282 100644 (file)
@@ -152,14 +152,14 @@ static int offset_list_cmp(struct rip_offset_list *o1,
        return strcmp(o1->ifname, o2->ifname);
 }
 
-void rip_offset_init()
+void rip_offset_init(void)
 {
        rip_offset_list_master = list_new();
        rip_offset_list_master->cmp = (int (*)(void *, void *))offset_list_cmp;
        rip_offset_list_master->del = (void (*)(void *))offset_list_del;
 }
 
-void rip_offset_clean()
+void rip_offset_clean(void)
 {
        list_delete(&rip_offset_list_master);
 
index b34f944c9e62ab23069c8cdcca84293789c9dd2f..3216b8f89fda9417eba84d1980cdc033d8e43378 100644 (file)
@@ -518,7 +518,7 @@ static struct route_map_rule_cmd route_set_tag_cmd = {
 #define SET_STR "Set values in destination routing protocol\n"
 
 /* Route-map init */
-void rip_route_map_init()
+void rip_route_map_init(void)
 {
        route_map_init();
 
index c56ff126271bcbb0d06a0d9ac0c094e7e3ca837c..fe63d8fdead1f5cc0db9ccebea0f386cf67b8cb1 100644 (file)
@@ -207,7 +207,7 @@ static int config_write_debug(struct vty *vty)
        return write;
 }
 
-void ripng_debug_init()
+void ripng_debug_init(void)
 {
        ripng_debug_event = 0;
        ripng_debug_packet = 0;
index 4d14fbab649290301604d853d2173e7782560426..e5dc6e6af69ccefb906185ca3804b0d623c13a90 100644 (file)
@@ -739,7 +739,7 @@ static void ripng_enable_apply_all(void)
 }
 
 /* Clear all network and neighbor configuration */
-void ripng_clean_network()
+void ripng_clean_network(void)
 {
        unsigned int i;
        char *str;
@@ -930,7 +930,7 @@ static struct cmd_node interface_node = {
 };
 
 /* Initialization of interface. */
-void ripng_if_init()
+void ripng_if_init(void)
 {
        /* Interface initialize. */
        hook_register_prio(if_add, 0, ripng_if_new_hook);
index 6b2a18353924921b6548a9ca877d567f1ef0c65e..756162d65c5d4ecfb232c51cf987790d3cecc040 100644 (file)
@@ -183,7 +183,7 @@ static int ripng_peer_list_cmp(struct ripng_peer *p1, struct ripng_peer *p2)
        return memcmp(&p1->addr, &p2->addr, sizeof(struct in6_addr));
 }
 
-void ripng_peer_init()
+void ripng_peer_init(void)
 {
        peer_list = list_new();
        peer_list->cmp = (int (*)(void *, void *))ripng_peer_list_cmp;
index 9a9e346a5931c33f0684e0f756f1778cd763da83..0604e272cdfd6800b6318f3746841616de5c6c61 100644 (file)
@@ -337,7 +337,7 @@ static struct route_map_rule_cmd route_set_tag_cmd = {
 #define MATCH_STR "Match values from routing table\n"
 #define SET_STR "Set values in destination routing protocol\n"
 
-void ripng_route_map_init()
+void ripng_route_map_init(void)
 {
        route_map_init();
 
index e3f42edf51266ddf6cafb1a401ca06482349fbdc..28a57f25d007bbbcf6814d82e733df6d92b50f98 100644 (file)
@@ -161,7 +161,7 @@ int ripng_redistribute_check(int type)
        return vrf_bitmap_check(zclient->redist[AFI_IP6][type], VRF_DEFAULT);
 }
 
-void ripng_redistribute_clean()
+void ripng_redistribute_clean(void)
 {
        for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) {
                if (!vrf_bitmap_check(zclient->redist[AFI_IP6][i], VRF_DEFAULT))
index ae8e8ab7d9d9ef099c2b57462fd6014a897d91a9..0022c726c5eb43f4ee3bb2358f4febf45fd3c8ec 100644 (file)
@@ -76,7 +76,7 @@ int ripng_route_rte(struct ripng_info *rinfo)
 }
 
 /* Allocate new ripng information. */
-struct ripng_info *ripng_info_new()
+struct ripng_info *ripng_info_new(void)
 {
        struct ripng_info *new;
 
@@ -2401,7 +2401,7 @@ static void ripng_distribute_update_all_wrapper(struct access_list *notused)
 }
 
 /* delete all the added ripng routes. */
-void ripng_clean()
+void ripng_clean(void)
 {
        int i;
        struct agg_node *rp;
@@ -2542,7 +2542,7 @@ static void ripng_routemap_update(const char *unused)
 }
 
 /* Initialize ripng structure and set commands. */
-void ripng_init()
+void ripng_init(void)
 {
        /* Install RIPNG_NODE. */
        install_node(&cmd_ripng_node, ripng_config_write);
index d2d960f278d77f8219329011821dafba30f52c72..b2612892f99cfd6c88718f406f330b6f480861fd 100644 (file)
@@ -1074,7 +1074,7 @@ static int validate(struct aspath *as, const struct test_spec *sp)
        return fails;
 }
 
-static void empty_get_test()
+static void empty_get_test(void)
 {
        struct aspath *as = aspath_empty_get();
        struct test_spec sp = {"", "", 0, 0, 0, 0, 0, 0};
@@ -1219,7 +1219,7 @@ static void aggregate_test(struct tests *t)
 }
 
 /* cmp_left tests  */
-static void cmp_test()
+static void cmp_test(void)
 {
        unsigned int i;
 #define CMP_TESTS_MAX (sizeof(left_compare) / sizeof(struct compare_tests))
index bafd131b78b8cb844a302feb897bca8bec917eb6..44068605eee8a0a178cf799084340f699a965eb2 100644 (file)
@@ -9,7 +9,7 @@ class TestFlag(frrtest.TestMultiOut):
 TestFlag.okfail('peer\\advertisement-interval')
 TestFlag.okfail('peer\\capability dynamic')
 TestFlag.okfail('peer\\capability extended-nexthop')
-TestFlag.okfail('peer\\capability extended-nexthop')
+#TestFlag.okfail('peer\\capability extended-nexthop')
 TestFlag.okfail('peer\\description')
 TestFlag.okfail('peer\\disable-connected-check')
 TestFlag.okfail('peer\\dont-capability-negotiate')
index 768cf296ad407c1e50ca71c7c41645922cdff883..11db2dabc38fafd53d941b19f2685307c4a79b17 100644 (file)
@@ -26,7 +26,7 @@
 #include "memory.h"
 #include "memory_vty.h"
 
-extern void test_init();
+extern void test_init(void);
 
 struct thread_master *master;
 
@@ -56,12 +56,12 @@ static int test_timer(struct thread *thread)
        return 0;
 }
 
-static void test_timer_init()
+static void test_timer_init(void)
 {
        thread_add_timer(master, test_timer, &timer_count, 10, NULL);
 }
 
-static void test_vty_init()
+static void test_vty_init(void)
 {
        install_element(VIEW_NODE, &daemon_exit_cmd);
 }
index e2a0a2d49a1e1c9c0c4c1d554d738db09a7ab682..afc7a08e662554bd85e83b66c2d1840d3b7a0342 100644 (file)
@@ -92,12 +92,12 @@ DEFUN (clear_foo,
        return CMD_SUCCESS;
 }
 
-static void slow_vty_init()
+static void slow_vty_init(void)
 {
        install_element(VIEW_NODE, &clear_foo_cmd);
 }
 
-void test_init()
+void test_init(void)
 {
        slow_vty_init();
 }
index b3c6e4c2f79073ca25a0259f97d8449b44fd046c..d516ed0de075ba7f37c8a3bb8b494887afe6d07d 100644 (file)
@@ -122,7 +122,7 @@ DEFUN (clear_foo,
        return CMD_SUCCESS;
 }
 
-void test_init()
+void test_init(void)
 {
        install_element(VIEW_NODE, &clear_foo_cmd);
 }
index 00ddc836d7cb80b63f7de6b92557ad4c410814da..442b8c83801f54ad6273fd030ea1a053f2115687 100644 (file)
@@ -139,7 +139,7 @@ DEFUN (clear_foo,
        return CMD_SUCCESS;
 }
 
-static int heavy_wq_init()
+static int heavy_wq_init(void)
 {
        heavy_wq = work_queue_new(master, "heavy_work_queue");
 
@@ -152,7 +152,7 @@ static int heavy_wq_init()
        return 0;
 }
 
-void test_init()
+void test_init(void)
 {
        install_element(VIEW_NODE, &clear_foo_cmd);
        heavy_wq_init();
index 2c2a010533d6758a909d0c646c38e307c280f908..2b65040627610f674297f8687e4ea7499dd7e400 100644 (file)
@@ -402,7 +402,7 @@ static void verify_prefix_iter_cmp(const char *p1, const char *p2,
  *
  * Tests comparision of prefixes according to order of iteration.
  */
-static void test_prefix_iter_cmp()
+static void test_prefix_iter_cmp(void)
 {
        printf("\n\nTesting route_table_prefix_iter_cmp()\n");
 
index f2a1e9434bc9d2d848ec4a6591844986444c59f8..5903f8732f2202e7e7fc7877471e635733d86b37 100644 (file)
@@ -280,7 +280,7 @@ static void add_namespace(const char *path)
 #endif
 
 #ifdef HAVE_LXC
-static void set_namespaces()
+static void set_namespaces(void)
 {
        struct namespace *namespace;
        int fd;
@@ -294,7 +294,7 @@ static void set_namespaces()
        }
 }
 #else
-static void set_namespaces()
+static void set_namespaces(void)
 {
        if (!LIST_EMPTY(&namespace_head))
                fatal("LCX namespaces not supported");
index 2b48f1f3609a2f91bd9f0af912a811ec3a073de9..332fd248caf5312c6fc865b1efabf34fb6a15286 100755 (executable)
@@ -248,8 +248,7 @@ foreach (sort keys %live) {
 
 # Output install_element
 print <<EOF;
-void
-vtysh_init_cmd ()
+void vtysh_init_cmd(void)
 {
 EOF
 
index 6cf45789dd97459ea5aa216c39e0139fd86c1059..340c9be60156e0d1456749dd904f4c6f6ec6f69c 100644 (file)
@@ -3464,7 +3464,7 @@ static const struct cmd_variable_handler vtysh_var_handler[] = {
         .completions = vtysh_autocomplete},
        {.completions = NULL}};
 
-void vtysh_uninit()
+void vtysh_uninit(void)
 {
        if (vty->of != stdout)
                fclose(vty->of);
index fe12f82ef28065a5c3406c790306175fb3b1aa0c..91e49c45c122de51fa447459d3a89901e7f5524b 100644 (file)
@@ -516,7 +516,7 @@ int vtysh_read_config(const char *config_default_dir)
  * be edited by hand. So, we handle only "write terminal" case here and
  * integrate vtysh specific conf with conf from daemons.
  */
-void vtysh_config_write()
+void vtysh_config_write(void)
 {
        char line[81];
 
@@ -539,7 +539,7 @@ void vtysh_config_write()
        user_config_write();
 }
 
-void vtysh_config_init()
+void vtysh_config_init(void)
 {
        config_top = list_new();
        config_top->del = (void (*)(void *))line_del;
index e575b7154914a8ed396154168e5d07efab69a7c9..dcf8ca0470f7081038663d2a32daa35352445aeb 100644 (file)
@@ -122,7 +122,7 @@ static struct vtysh_user *user_lookup(const char *name)
        return NULL;
 }
 
-void user_config_write()
+void user_config_write(void)
 {
        struct listnode *node, *nnode;
        struct vtysh_user *user;
index 956d22587c0bd150baeda3c4ce5c2e5ff9e87f9e..716478908342d2ede059e0b376c65f0bc44b3825 100644 (file)
@@ -1,7 +1,12 @@
 #
 # libyang user types
 #
+
+if LIBYANG_EXT_BUILTIN
+lib_libfrr_la_SOURCES += yang/libyang_plugins/frr_user_types.c
+else
 libyang_plugins_LTLIBRARIES += yang/libyang_plugins/frr_user_types.la
+endif
 
 yang_libyang_plugins_frr_user_types_la_CFLAGS = $(WERROR)
 yang_libyang_plugins_frr_user_types_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
index ab66eb3324aa86208f22d61d5beb2189365342b7..c449855f6dfb40901485e334a6b60a2544887ea9 100644 (file)
@@ -209,6 +209,7 @@ void connected_up(struct interface *ifp, struct connected *ifc)
                .ifindex = ifp->ifindex,
                .vrf_id = ifp->vrf_id,
        };
+       uint32_t metric;
 
        if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
                return;
@@ -243,11 +244,13 @@ void connected_up(struct interface *ifp, struct connected *ifc)
                break;
        }
 
+       metric = (ifc->metric < (uint32_t)METRIC_MAX) ?
+                               ifc->metric : ifp->metric;
        rib_add(afi, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0, &p,
-               NULL, &nh, RT_TABLE_MAIN, ifp->metric, 0, 0, 0);
+               NULL, &nh, RT_TABLE_MAIN, metric, 0, 0, 0);
 
        rib_add(afi, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0, &p,
-               NULL, &nh, RT_TABLE_MAIN, ifp->metric, 0, 0, 0);
+               NULL, &nh, RT_TABLE_MAIN, metric, 0, 0, 0);
 
        if (IS_ZEBRA_DEBUG_RIB_DETAILED) {
                char buf[PREFIX_STRLEN];
@@ -276,7 +279,7 @@ void connected_up(struct interface *ifp, struct connected *ifc)
 /* Add connected IPv4 route to the interface. */
 void connected_add_ipv4(struct interface *ifp, int flags, struct in_addr *addr,
                        uint16_t prefixlen, struct in_addr *broad,
-                       const char *label)
+                       const char *label, uint32_t metric)
 {
        struct prefix_ipv4 *p;
        struct connected *ifc;
@@ -288,6 +291,7 @@ void connected_add_ipv4(struct interface *ifp, int flags, struct in_addr *addr,
        ifc = connected_new();
        ifc->ifp = ifp;
        ifc->flags = flags;
+       ifc->metric = metric;
        /* If we get a notification from the kernel,
         * we can safely assume the address is known to the kernel */
        SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
@@ -500,7 +504,7 @@ void connected_delete_ipv4(struct interface *ifp, int flags,
 /* Add connected IPv6 route to the interface. */
 void connected_add_ipv6(struct interface *ifp, int flags, struct in6_addr *addr,
                        struct in6_addr *broad, uint16_t prefixlen,
-                       const char *label)
+                       const char *label, uint32_t metric)
 {
        struct prefix_ipv6 *p;
        struct connected *ifc;
@@ -512,6 +516,7 @@ void connected_add_ipv6(struct interface *ifp, int flags, struct in6_addr *addr,
        ifc = connected_new();
        ifc->ifp = ifp;
        ifc->flags = flags;
+       ifc->metric = metric;
        /* If we get a notification from the kernel,
         * we can safely assume the address is known to the kernel */
        SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
index 415ecfd96518148a67f450d22e408e504df4c49d..faba30b0d5c653a30a9e4208070cf9115295f905 100644 (file)
@@ -36,7 +36,8 @@ extern struct connected *connected_check_ptp(struct interface *ifp,
 
 extern void connected_add_ipv4(struct interface *ifp, int flags,
                               struct in_addr *addr, uint16_t prefixlen,
-                              struct in_addr *broad, const char *label);
+                              struct in_addr *broad, const char *label,
+                              uint32_t metric);
 
 extern void connected_delete_ipv4(struct interface *ifp, int flags,
                                  struct in_addr *addr, uint16_t prefixlen,
@@ -49,7 +50,8 @@ extern void connected_down(struct interface *ifp, struct connected *ifc);
 
 extern void connected_add_ipv6(struct interface *ifp, int flags,
                               struct in6_addr *address, struct in6_addr *broad,
-                              uint16_t prefixlen, const char *label);
+                              uint16_t prefixlen, const char *label,
+                              uint32_t metric);
 extern void connected_delete_ipv6(struct interface *ifp,
                                  struct in6_addr *address,
                                  struct in6_addr *broad, uint16_t prefixlen);
index df79d285a3609e3807523928be4dc83978b13290..debc151d752dd770beb6b4537b9438a3e6c95e37 100644 (file)
@@ -236,7 +236,8 @@ static int if_getaddrs(void)
                        }
 
                        connected_add_ipv4(ifp, flags, &addr->sin_addr,
-                                          prefixlen, dest_pnt, NULL);
+                                          prefixlen, dest_pnt, NULL,
+                                          METRIC_MAX);
                }
                if (ifap->ifa_addr->sa_family == AF_INET6) {
                        struct sockaddr_in6 *addr;
@@ -258,7 +259,7 @@ static int if_getaddrs(void)
 #endif
 
                        connected_add_ipv6(ifp, flags, &addr->sin6_addr, NULL,
-                                          prefixlen, NULL);
+                                          prefixlen, NULL, METRIC_MAX);
                }
        }
 
index 0206d4938efda498eb908772f28b574a8cb56396..2c29930c3f661d2ab80b6141d63e9b682bc05dbf 100644 (file)
@@ -302,10 +302,11 @@ static int if_get_addr(struct interface *ifp, struct sockaddr *addr,
        /* Set address to the interface. */
        if (af == AF_INET)
                connected_add_ipv4(ifp, flags, &SIN(addr)->sin_addr, prefixlen,
-                                  (struct in_addr *)dest_pnt, label);
+                                  (struct in_addr *)dest_pnt, label,
+                                  METRIC_MAX);
        else if (af == AF_INET6)
                connected_add_ipv6(ifp, flags, &SIN6(addr)->sin6_addr, NULL,
-                                  prefixlen, label);
+                                  prefixlen, label, METRIC_MAX);
 
        return 0;
 }
index 0cecce5e74b79c961f0a2d1821e6089518355fa8..47087d4ce01c5a6c0e589c3a606281e1ca58c4ec 100644 (file)
@@ -924,6 +924,7 @@ int netlink_interface_addr(struct nlmsghdr *h, ns_id_t ns_id, int startup)
        uint8_t flags = 0;
        char *label = NULL;
        struct zebra_ns *zns;
+       uint32_t metric = METRIC_MAX;
 
        zns = zebra_ns_lookup(ns_id);
        ifa = NLMSG_DATA(h);
@@ -1032,6 +1033,9 @@ int netlink_interface_addr(struct nlmsghdr *h, ns_id_t ns_id, int startup)
        if (label && strcmp(ifp->name, label) == 0)
                label = NULL;
 
+       if (tb[IFA_RT_PRIORITY])
+               metric = *(uint32_t *)RTA_DATA(tb[IFA_RT_PRIORITY]);
+
        /* Register interface address to the interface. */
        if (ifa->ifa_family == AF_INET) {
                if (ifa->ifa_prefixlen > IPV4_MAX_BITLEN) {
@@ -1044,7 +1048,8 @@ int netlink_interface_addr(struct nlmsghdr *h, ns_id_t ns_id, int startup)
                if (h->nlmsg_type == RTM_NEWADDR)
                        connected_add_ipv4(ifp, flags, (struct in_addr *)addr,
                                           ifa->ifa_prefixlen,
-                                          (struct in_addr *)broad, label);
+                                          (struct in_addr *)broad, label,
+                                          metric);
                else
                        connected_delete_ipv4(
                                ifp, flags, (struct in_addr *)addr,
@@ -1070,7 +1075,8 @@ int netlink_interface_addr(struct nlmsghdr *h, ns_id_t ns_id, int startup)
                                connected_add_ipv6(ifp, flags,
                                                   (struct in6_addr *)addr,
                                                   (struct in6_addr *)broad,
-                                                  ifa->ifa_prefixlen, label);
+                                                  ifa->ifa_prefixlen, label,
+                                                  metric);
                } else
                        connected_delete_ipv6(ifp, (struct in6_addr *)addr,
                                              (struct in6_addr *)broad,
index 3e50550dd2f8dcd9a541bff34baee9c147f0f9e6..ffc49d2c1364d14149c5e9cd755fb111de012b07 100644 (file)
@@ -706,7 +706,7 @@ DEFUN (ip_irdp_debug_disable,
        return CMD_SUCCESS;
 }
 
-void irdp_if_init()
+void irdp_if_init(void)
 {
        hook_register(zebra_if_config_wr, irdp_config_write);
        hook_register(if_del, irdp_if_delete);
index f3561cc19d3f7d6836c0482e6f17810520560bad..acd7f911dcefbf62888908f7305a67387ad1bc87 100644 (file)
@@ -906,7 +906,8 @@ int ifam_read(struct ifa_msghdr *ifam)
                        connected_add_ipv4(ifp, flags, &addr.sin.sin_addr,
                                           ip_masklen(mask.sin.sin_addr),
                                           &brd.sin.sin_addr,
-                                          (isalias ? ifname : NULL));
+                                          (isalias ? ifname : NULL),
+                                          METRIC_MAX);
                else
                        connected_delete_ipv4(ifp, flags, &addr.sin.sin_addr,
                                              ip_masklen(mask.sin.sin_addr),
@@ -923,7 +924,8 @@ int ifam_read(struct ifa_msghdr *ifam)
                        connected_add_ipv6(ifp, flags, &addr.sin6.sin6_addr,
                                           NULL,
                                           ip6_masklen(mask.sin6.sin6_addr),
-                                          (isalias ? ifname : NULL));
+                                          (isalias ? ifname : NULL),
+                                          METRIC_MAX);
                else
                        connected_delete_ipv6(ifp, &addr.sin6.sin6_addr, NULL,
                                              ip6_masklen(mask.sin6.sin6_addr));
index bfad8ea643f7aac5cec4e4e43211aa0639644387..13472059a0614ce0fee7ebe1b4264dcf81ac1f7a 100644 (file)
@@ -480,7 +480,7 @@ int release_label_chunk(uint8_t proto, unsigned short instance, uint32_t start,
 }
 
 
-void label_manager_close()
+void label_manager_close(void)
 {
        list_delete(&lbl_mgr.lc_list);
        stream_free(obuf);
index abcff22b6b183f315370370bdcd4629ad3c9ad7d..f25259f300cef721a1edf47fb91a57d07d212a93 100644 (file)
@@ -92,10 +92,9 @@ static int kernel_rtm(int cmd, const struct prefix *p,
         */
        if (cmd != RTM_ADD && cmd != RTM_DELETE) {
                if (IS_ZEBRA_DEBUG_KERNEL)
-                       zlog_debug("%s: %s odd command %s for flags %d",
+                       zlog_debug("%s: %s odd command %s",
                                   __func__, prefix_buf,
-                                  lookup_msg(rtm_type_str, cmd, NULL),
-                                  nexthop->flags);
+                                  lookup_msg(rtm_type_str, cmd, NULL));
                return 0;
        }
 
@@ -308,8 +307,7 @@ enum zebra_dplane_result kernel_route_update(struct zebra_dplane_ctx *ctx)
 
        if (dplane_ctx_get_src(ctx) != NULL) {
                zlog_err("route add: IPv6 sourcedest routes unsupported!");
-               res = ZEBRA_DPLANE_REQUEST_FAILURE;
-               goto done;
+               return ZEBRA_DPLANE_REQUEST_FAILURE;
        }
 
        frr_elevate_privs(&zserv_privs) {
@@ -341,8 +339,6 @@ enum zebra_dplane_result kernel_route_update(struct zebra_dplane_ctx *ctx)
                }
        } /* Elevated privs */
 
-done:
-
        return res;
 }
 
index fc316dbcb670bfff66d9fd76438c14b1a3329619..6fbad2f71ee72747ababe2ee9660ae18f805b99d 100644 (file)
@@ -24,6 +24,7 @@
 #include "lib/memory.h"
 #include "lib/queue.h"
 #include "lib/zebra.h"
+#include "zebra/zebra_router.h"
 #include "zebra/zebra_memory.h"
 #include "zebra/zserv.h"
 #include "zebra/zebra_dplane.h"
@@ -863,7 +864,7 @@ static int dplane_ctx_route_init(struct zebra_dplane_ctx *ctx,
        /* Trying out the sequence number idea, so we can try to detect
         * when a result is stale.
         */
-       re->dplane_sequence++;
+       re->dplane_sequence = zebra_router_get_next_sequence();
        ctx->zd_seq = re->dplane_sequence;
 
        ret = AOK;
@@ -1012,7 +1013,8 @@ dplane_route_update_internal(struct route_node *rn,
                    old_re && (old_re != re)) {
                        ctx->zd_is_update = true;
 
-                       old_re->dplane_sequence++;
+                       old_re->dplane_sequence =
+                               zebra_router_get_next_sequence();
                        ctx->zd_old_seq = old_re->dplane_sequence;
 
                        ctx->u.rinfo.zd_old_tag = old_re->tag;
index 207cbc0992221a9c2de839ff69a7cf9c23467813..28333526a7cf83c03ec8dddad822246aedceec23 100644 (file)
@@ -276,7 +276,7 @@ static int netlink_route_info_fill(netlink_route_info_t *ri, int cmd,
                if ((cmd == RTM_NEWROUTE
                     && CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
                    || (cmd == RTM_DELROUTE
-                       && CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB))) {
+                       && CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED))) {
                        netlink_route_info_add_nh(ri, nexthop);
                }
        }
index 0dc8a05e9c6d66742b9eeb34d4fde4769ef5b633..c66b78cc9dafa294cdc52a71a8211c9549c3db95 100644 (file)
@@ -566,8 +566,8 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
                } else if (CHECK_FLAG(re->flags, ZEBRA_FLAG_ALLOW_RECURSION)) {
                        resolved = 0;
                        for (ALL_NEXTHOPS(match->ng, newhop)) {
-                               if (!CHECK_FLAG(newhop->flags,
-                                               NEXTHOP_FLAG_FIB))
+                               if (!CHECK_FLAG(match->status,
+                                               ROUTE_ENTRY_INSTALLED))
                                        continue;
                                if (CHECK_FLAG(newhop->flags,
                                               NEXTHOP_FLAG_RECURSIVE))
@@ -592,8 +592,8 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
                } else if (re->type == ZEBRA_ROUTE_STATIC) {
                        resolved = 0;
                        for (ALL_NEXTHOPS(match->ng, newhop)) {
-                               if (!CHECK_FLAG(newhop->flags,
-                                               NEXTHOP_FLAG_FIB))
+                               if (!CHECK_FLAG(match->status,
+                                               ROUTE_ENTRY_INSTALLED))
                                        continue;
 
                                if (set) {
@@ -637,7 +637,6 @@ struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t vrf_id,
        struct route_table *table;
        struct route_node *rn;
        struct route_entry *match = NULL;
-       struct nexthop *newhop;
 
        /* Lookup table.  */
        table = zebra_vrf_table(afi, safi, vrf_id);
@@ -677,14 +676,8 @@ struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t vrf_id,
                                route_lock_node(rn);
                } else {
                        if (match->type != ZEBRA_ROUTE_CONNECT) {
-                               int found = 0;
-                               for (ALL_NEXTHOPS(match->ng, newhop))
-                                       if (CHECK_FLAG(newhop->flags,
-                                                      NEXTHOP_FLAG_FIB)) {
-                                               found = 1;
-                                               break;
-                                       }
-                               if (!found)
+                               if (!CHECK_FLAG(match->status,
+                                               ROUTE_ENTRY_INSTALLED))
                                        return NULL;
                        }
 
@@ -774,7 +767,6 @@ struct route_entry *rib_lookup_ipv4(struct prefix_ipv4 *p, vrf_id_t vrf_id)
        struct route_table *table;
        struct route_node *rn;
        struct route_entry *match = NULL;
-       struct nexthop *nexthop;
        rib_dest_t *dest;
 
        /* Lookup table.  */
@@ -802,9 +794,8 @@ struct route_entry *rib_lookup_ipv4(struct prefix_ipv4 *p, vrf_id_t vrf_id)
        if (match->type == ZEBRA_ROUTE_CONNECT)
                return match;
 
-       for (ALL_NEXTHOPS(match->ng, nexthop))
-               if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB))
-                       return match;
+       if (CHECK_FLAG(match->status, ROUTE_ENTRY_INSTALLED))
+               return match;
 
        return NULL;
 }
@@ -1089,6 +1080,9 @@ void rib_install_kernel(struct route_node *rn, struct route_entry *re,
 
        switch (ret) {
        case ZEBRA_DPLANE_REQUEST_QUEUED:
+               SET_FLAG(re->status, ROUTE_ENTRY_QUEUED);
+               if (old)
+                       SET_FLAG(old->status, ROUTE_ENTRY_QUEUED);
                if (zvrf)
                        zvrf->installs_queued++;
                break;
@@ -1119,6 +1113,7 @@ void rib_uninstall_kernel(struct route_node *rn, struct route_entry *re)
        struct zebra_vrf *zvrf = vrf_info_lookup(re->vrf_id);
 
        if (info->safi != SAFI_UNICAST) {
+               UNSET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
                for (ALL_NEXTHOPS(re->ng, nexthop))
                        UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
                return;
@@ -1171,6 +1166,8 @@ static void rib_uninstall(struct route_node *rn, struct route_entry *re)
 
                if (!RIB_SYSTEM_ROUTE(re))
                        rib_uninstall_kernel(rn, re);
+               else
+                       UNSET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
 
                dest->selected_fib = NULL;
 
@@ -1301,6 +1298,7 @@ static void rib_process_del_fib(struct zebra_vrf *zvrf, struct route_node *rn,
        if (!RIB_SYSTEM_ROUTE(old))
                rib_uninstall_kernel(rn, old);
        else {
+               UNSET_FLAG(old->status, ROUTE_ENTRY_INSTALLED);
                /*
                 * We are setting this to NULL here
                 * because that is what we traditionally
@@ -1381,6 +1379,7 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf,
 
                                rib_install_kernel(rn, new, old);
                        } else {
+                               UNSET_FLAG(new->status, ROUTE_ENTRY_INSTALLED);
                                /*
                                 * We do not need to install the
                                 * selected route because it
@@ -1400,7 +1399,13 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf,
                                if (RIB_SYSTEM_ROUTE(new)) {
                                        if (!RIB_SYSTEM_ROUTE(old))
                                                rib_uninstall_kernel(rn, old);
+                                       else
+                                               UNSET_FLAG(
+                                                       old->status,
+                                                       ROUTE_ENTRY_INSTALLED);
                                } else {
+                                       UNSET_FLAG(old->status,
+                                                  ROUTE_ENTRY_INSTALLED);
                                        for (nexthop = old->ng.nexthop; nexthop;
                                             nexthop = nexthop->next)
                                                UNSET_FLAG(nexthop->flags,
@@ -1437,8 +1442,10 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf,
 
                        if (!RIB_SYSTEM_ROUTE(old))
                                rib_uninstall_kernel(rn, old);
-                       else
+                       else {
+                               UNSET_FLAG(old->status, ROUTE_ENTRY_INSTALLED);
                                dest->selected_fib = NULL;
+                       }
                }
        } else {
                /*
@@ -1450,18 +1457,9 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf,
                 * is ready
                 * to add routes.
                 */
-               if (!RIB_SYSTEM_ROUTE(new)) {
-                       bool in_fib = false;
-
-                       for (ALL_NEXTHOPS(new->ng, nexthop))
-                               if (CHECK_FLAG(nexthop->flags,
-                                              NEXTHOP_FLAG_FIB)) {
-                                       in_fib = true;
-                                       break;
-                               }
-                       if (!in_fib)
-                               rib_install_kernel(rn, new, NULL);
-               }
+               if (!RIB_SYSTEM_ROUTE(new)
+                   && !CHECK_FLAG(new->status, ROUTE_ENTRY_INSTALLED))
+                       rib_install_kernel(rn, new, NULL);
        }
 
        /* Update prior route. */
@@ -1902,44 +1900,48 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx)
        /*
         * Check sequence number(s) to detect stale results before continuing
         */
-       if (re && (re->dplane_sequence != dplane_ctx_get_seq(ctx))) {
-               if (IS_ZEBRA_DEBUG_DPLANE_DETAIL) {
-                       zlog_debug("%u:%s Stale dplane result for re %p",
-                                  dplane_ctx_get_vrf(ctx), dest_str, re);
-               }
-               re = NULL;
-       }
-
-       if (old_re &&
-           (old_re->dplane_sequence != dplane_ctx_get_old_seq(ctx))) {
-               if (IS_ZEBRA_DEBUG_DPLANE_DETAIL) {
-                       zlog_debug("%u:%s Stale dplane result for old_re %p",
-                                  dplane_ctx_get_vrf(ctx), dest_str, old_re);
-               }
-               old_re = NULL;
-       }
-
-       /*
-        * Here's sort of a tough one: the route update result is stale.
-        * Is it better to use the context block info to generate
-        * redist and owner notification, or is it better to wait
-        * for the up-to-date result to arrive?
-        */
-       if (re == NULL) {
-               /* TODO -- for now, only expose up-to-date results */
-               goto done;
+       if (re) {
+               if (re->dplane_sequence != dplane_ctx_get_seq(ctx)) {
+                       if (IS_ZEBRA_DEBUG_DPLANE_DETAIL)
+                               zlog_debug("%u:%s Stale dplane result for re %p",
+                                          dplane_ctx_get_vrf(ctx),
+                                          dest_str, re);
+               } else
+                       UNSET_FLAG(re->status, ROUTE_ENTRY_QUEUED);
+       }
+
+       if (old_re) {
+               if (old_re->dplane_sequence != dplane_ctx_get_old_seq(ctx)) {
+                       if (IS_ZEBRA_DEBUG_DPLANE_DETAIL)
+                               zlog_debug("%u:%s Stale dplane result for old_re %p",
+                                          dplane_ctx_get_vrf(ctx),
+                                          dest_str, old_re);
+               } else
+                       UNSET_FLAG(re->status, ROUTE_ENTRY_QUEUED);
        }
 
        switch (op) {
        case DPLANE_OP_ROUTE_INSTALL:
        case DPLANE_OP_ROUTE_UPDATE:
                if (status == ZEBRA_DPLANE_REQUEST_SUCCESS) {
+                       if (re) {
+                               UNSET_FLAG(re->status, ROUTE_ENTRY_FAILED);
+                               SET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
+                       }
+                       if (old_re) {
+                               UNSET_FLAG(old_re->status, ROUTE_ENTRY_FAILED);
+                               UNSET_FLAG(old_re->status,
+                                          ROUTE_ENTRY_INSTALLED);
+                       }
                        /* Update zebra nexthop FIB flag for each
                         * nexthop that was installed.
                         */
                        for (ALL_NEXTHOPS_PTR(dplane_ctx_get_ng(ctx),
                                              ctx_nexthop)) {
 
+                               if (!re)
+                                       continue;
+
                                for (ALL_NEXTHOPS(re->ng, nexthop)) {
                                        if (nexthop_same(ctx_nexthop, nexthop))
                                                break;
@@ -1976,15 +1978,21 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx)
                         * 'old' context info was stale, 'old_re' will be
                         * NULL here and that delete will not be sent.
                         */
-                       redistribute_update(dest_pfx, src_pfx, re, old_re);
+                       if (re)
+                               redistribute_update(dest_pfx, src_pfx,
+                                                   re, old_re);
 
                        /* Notify route owner */
-                       zsend_route_notify_owner(re, dest_pfx,
-                                                ZAPI_ROUTE_INSTALLED);
+                       zsend_route_notify_owner_ctx(ctx, ZAPI_ROUTE_INSTALLED);
 
                } else {
-                       zsend_route_notify_owner(re, dest_pfx,
-                                                ZAPI_ROUTE_FAIL_INSTALL);
+                       if (re)
+                               SET_FLAG(re->status, ROUTE_ENTRY_FAILED);
+                       if (old_re)
+                               SET_FLAG(old_re->status, ROUTE_ENTRY_FAILED);
+                       if (re)
+                               zsend_route_notify_owner(re, dest_pfx,
+                                                        ZAPI_ROUTE_FAIL_INSTALL);
 
                        zlog_warn("%u:%s: Route install failed",
                                  dplane_ctx_get_vrf(ctx),
@@ -1993,17 +2001,25 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx)
                }
                break;
        case DPLANE_OP_ROUTE_DELETE:
+               if (re)
+                       SET_FLAG(re->status, ROUTE_ENTRY_FAILED);
                /*
                 * In the delete case, the zebra core datastructs were
                 * updated (or removed) at the time the delete was issued,
                 * so we're just notifying the route owner.
                 */
                if (status == ZEBRA_DPLANE_REQUEST_SUCCESS) {
+                       if (re) {
+                               UNSET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
+                               UNSET_FLAG(re->status, ROUTE_ENTRY_FAILED);
+                       }
                        zsend_route_notify_owner_ctx(ctx, ZAPI_ROUTE_REMOVED);
 
                        if (zvrf)
                                zvrf->removals++;
                } else {
+                       if (re)
+                               SET_FLAG(re->status, ROUTE_ENTRY_FAILED);
                        zsend_route_notify_owner_ctx(ctx,
                                                     ZAPI_ROUTE_REMOVE_FAIL);
 
@@ -2527,7 +2543,7 @@ void _route_entry_dump(const char *func, union prefixconstptr pp,
                           (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)
                                    ? "ACTIVE "
                                    : ""),
-                          (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)
+                          (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED)
                                    ? "FIB "
                                    : ""),
                           (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)
@@ -2708,9 +2724,11 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
        }
 
        /* If this route is kernel route, set FIB flag to the route. */
-       if (RIB_SYSTEM_ROUTE(re))
+       if (RIB_SYSTEM_ROUTE(re)) {
+               SET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
                for (nexthop = re->ng.nexthop; nexthop; nexthop = nexthop->next)
                        SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
+       }
 
        /* Link new re to node.*/
        if (IS_ZEBRA_DEBUG_RIB) {
@@ -2847,6 +2865,7 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
                                        rn, fib, fib->type);
                        }
                        if (allow_delete) {
+                               UNSET_FLAG(fib->status, ROUTE_ENTRY_INSTALLED);
                                /* Unset flags. */
                                for (rtnh = fib->ng.nexthop; rtnh;
                                     rtnh = rtnh->next)
@@ -3093,6 +3112,7 @@ void rib_sweep_table(struct route_table *table)
                         * to a different spot (ie startup )
                         * this decision needs to be revisited
                         */
+                       SET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
                        for (ALL_NEXTHOPS(re->ng, nexthop))
                                SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
 
index 317a7cdecad5c0b52a50fc27acf98b84ce181169..52637c6062d01ee4679cb17ec3f198f1bdf34f66 100644 (file)
@@ -370,14 +370,10 @@ static void zebra_rnh_eval_import_check_entry(vrf_id_t vrfid, afi_t afi,
        struct zserv *client;
        char bufn[INET6_ADDRSTRLEN];
        struct listnode *node;
-       struct nexthop *nexthop;
 
        if (re && (rnh->state == NULL)) {
-               for (ALL_NEXTHOPS(re->ng, nexthop))
-                       if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)) {
-                               state_changed = 1;
-                               break;
-                       }
+               if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED))
+                       state_changed = 1;
        } else if (!re && (rnh->state != NULL))
                state_changed = 1;
 
@@ -511,9 +507,10 @@ static void zebra_rnh_process_pbr_tables(afi_t afi, struct route_node *nrn,
  * check in a couple of places, so this is a single home for the logic we
  * use.
  */
-static bool rnh_nexthop_valid(const struct nexthop *nh)
+static bool rnh_nexthop_valid(const struct route_entry *re,
+                             const struct nexthop *nh)
 {
-       return (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_FIB)
+       return (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED)
                && CHECK_FLAG(nh->flags, NEXTHOP_FLAG_ACTIVE));
 }
 
@@ -566,7 +563,7 @@ zebra_rnh_resolve_nexthop_entry(struct zebra_vrf *zvrf, afi_t afi,
                         * have an installed nexthop to be useful.
                         */
                        for (ALL_NEXTHOPS(re->ng, nexthop)) {
-                               if (rnh_nexthop_valid(nexthop))
+                               if (rnh_nexthop_valid(re, nexthop))
                                        break;
                        }
 
@@ -820,6 +817,7 @@ static void copy_state(struct rnh *rnh, struct route_entry *re,
        state->distance = re->distance;
        state->metric = re->metric;
        state->vrf_id = re->vrf_id;
+       state->status = re->status;
 
        route_entry_copy_nexthops(state, re->ng.nexthop);
        rnh->state = state;
@@ -895,7 +893,7 @@ static int send_client(struct rnh *rnh, struct zserv *client, rnh_type_t type,
                nump = stream_get_endp(s);
                stream_putc(s, 0);
                for (ALL_NEXTHOPS(re->ng, nh))
-                       if (rnh_nexthop_valid(nh)) {
+                       if (rnh_nexthop_valid(re, nh)) {
                                stream_putl(s, nh->vrf_id);
                                stream_putc(s, nh->type);
                                switch (nh->type) {
index 5461a7883d8f52fc9d6fc00bcbaa64d18b62f3e8..6d52e5f9e6a08b04280ab9012954d32e768a1798 100644 (file)
@@ -1831,7 +1831,7 @@ void zebra_routemap_config_write_protocol(struct vty *vty,
                        zebra_rmap_update_timer);
 }
 
-void zebra_route_map_init()
+void zebra_route_map_init(void)
 {
        install_element(CONFIG_NODE, &ip_protocol_cmd);
        install_element(CONFIG_NODE, &no_ip_protocol_cmd);
index f0cc8d4fd759c72cfa60e5dcabf51454578294e9..3e94d6bca892dfc6ec7a401a37c3c488eae8e422 100644 (file)
@@ -21,6 +21,9 @@
  */
 #include "zebra.h"
 
+#include <pthread.h>
+#include "lib/frratomic.h"
+
 #include "zebra_router.h"
 #include "zebra_memory.h"
 #include "zebra_pbr.h"
@@ -169,6 +172,13 @@ static void zebra_router_free_table(struct zebra_router_table *zrt)
        XFREE(MTYPE_ZEBRA_NS, zrt);
 }
 
+uint32_t zebra_router_get_next_sequence(void)
+{
+       return 1
+              + atomic_fetch_add_explicit(&zrouter.sequence_num, 1,
+                                          memory_order_relaxed);
+}
+
 void zebra_router_terminate(void)
 {
        struct zebra_router_table *zrt, *tmp;
@@ -194,6 +204,8 @@ void zebra_router_terminate(void)
 
 void zebra_router_init(void)
 {
+       zrouter.sequence_num = 0;
+
        zebra_vxlan_init();
        zebra_mlag_init();
 
index 1e0788d1ba9ce1d68e06d42fb2289bca868b6a1e..f63dcd984ebcadba91cf7e2bf91e9c1d0a5cbd56 100644 (file)
@@ -62,6 +62,9 @@ struct zebra_router {
 #if defined(HAVE_RTADV)
        struct rtadv rtadv;
 #endif /* HAVE_RTADV */
+
+       /* A sequence number used for tracking routes */
+       _Atomic uint32_t sequence_num;
 };
 
 extern struct zebra_router zrouter;
@@ -83,4 +86,6 @@ extern unsigned long zebra_router_score_proto(uint8_t proto,
 extern void zebra_router_sweep_route(void);
 
 extern void zebra_router_show_table_summary(struct vty *vty);
+
+extern uint32_t zebra_router_get_next_sequence(void);
 #endif
index 87b279b1e9cdd44b99920e719cf6acbeac835653..14288d7bc4b3714880863e17c9f8db7800bd206c 100644 (file)
@@ -161,6 +161,28 @@ DEFUN (show_ip_rpf_addr,
        return CMD_SUCCESS;
 }
 
+static char re_status_output_char(struct route_entry *re, struct nexthop *nhop)
+{
+       if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED)) {
+               if (!CHECK_FLAG(nhop->flags, NEXTHOP_FLAG_DUPLICATE))
+                       return '*';
+               else
+                       return ' ';
+       }
+
+       if (CHECK_FLAG(re->status, ROUTE_ENTRY_FAILED)) {
+               if (CHECK_FLAG(re->status, ROUTE_ENTRY_QUEUED))
+                       return 'q';
+
+               return 'f';
+       }
+
+       if (CHECK_FLAG(re->status, ROUTE_ENTRY_QUEUED))
+               return 'q';
+
+       return ' ';
+}
+
 /* New RIB.  Detailed information for IPv4 route. */
 static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn,
                                     int mcast)
@@ -229,12 +251,7 @@ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn,
                        char addrstr[32];
 
                        vty_out(vty, "  %c%s",
-                               CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)
-                                       ? CHECK_FLAG(nexthop->flags,
-                                                    NEXTHOP_FLAG_DUPLICATE)
-                                                 ? ' '
-                                                 : '*'
-                                       : ' ',
+                               re_status_output_char(re, nexthop),
                                nexthop->rparent ? "  " : "");
 
                        switch (nexthop->type) {
@@ -389,6 +406,19 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
                if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED))
                        json_object_boolean_true_add(json_route, "selected");
 
+               json_object_int_add(json_route, "distance",
+                                   re->distance);
+               json_object_int_add(json_route, "metric", re->metric);
+
+               if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED))
+                       json_object_boolean_true_add(json_route, "installed");
+
+               if (CHECK_FLAG(re->status, ROUTE_ENTRY_FAILED))
+                       json_object_boolean_true_add(json_route, "failed");
+
+               if (CHECK_FLAG(re->status, ROUTE_ENTRY_QUEUED))
+                       json_object_boolean_true_add(json_route, "queued");
+
                if (re->type != ZEBRA_ROUTE_CONNECT) {
                        json_object_int_add(json_route, "distance",
                                            re->distance);
@@ -596,23 +626,18 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
                                CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED)
                                        ? '>'
                                        : ' ',
-                               CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)
-                                       ? '*'
-                                       : ' ',
+                               re_status_output_char(re, nexthop),
                                srcdest_rnode2str(rn, buf, sizeof buf));
 
                        /* Distance and metric display. */
-                       if (re->type != ZEBRA_ROUTE_CONNECT)
+                       if (((re->type == ZEBRA_ROUTE_CONNECT) &&
+                            (re->distance || re->metric)) ||
+                           (re->type != ZEBRA_ROUTE_CONNECT))
                                len += vty_out(vty, " [%u/%u]", re->distance,
                                               re->metric);
                } else {
                        vty_out(vty, "  %c%*c",
-                               CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)
-                                       ? CHECK_FLAG(nexthop->flags,
-                                                    NEXTHOP_FLAG_DUPLICATE)
-                                                 ? ' '
-                                                 : '*'
-                                       : ' ',
+                               re_status_output_char(re, nexthop),
                                len - 3 + (2 * nexthop_level(nexthop)), ' ');
                }
 
@@ -1409,21 +1434,20 @@ static void vty_show_ip_route_summary_prefix(struct vty *vty,
                         * In case of ECMP, count only once.
                         */
                        cnt = 0;
+                       if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED)) {
+                               fib_cnt[ZEBRA_ROUTE_TOTAL]++;
+                               fib_cnt[re->type]++;
+                       }
                        for (nexthop = re->ng.nexthop; (!cnt && nexthop);
                             nexthop = nexthop->next) {
                                cnt++;
                                rib_cnt[ZEBRA_ROUTE_TOTAL]++;
                                rib_cnt[re->type]++;
-                               if (CHECK_FLAG(nexthop->flags,
-                                              NEXTHOP_FLAG_FIB)) {
-                                       fib_cnt[ZEBRA_ROUTE_TOTAL]++;
-                                       fib_cnt[re->type]++;
-                               }
                                if (re->type == ZEBRA_ROUTE_BGP
                                    && CHECK_FLAG(re->flags, ZEBRA_FLAG_IBGP)) {
                                        rib_cnt[ZEBRA_ROUTE_IBGP]++;
-                                       if (CHECK_FLAG(nexthop->flags,
-                                                      NEXTHOP_FLAG_FIB))
+                                       if (CHECK_FLAG(re->status,
+                                                      ROUTE_ENTRY_INSTALLED))
                                                fib_cnt[ZEBRA_ROUTE_IBGP]++;
                                }
                        }
index 8c44838ade9cfe21514353a9e674b04e6a37c8db..45e6caebbe9ce05fcb0e799d35e2128ea2f676ed 100644 (file)
@@ -81,7 +81,7 @@ static void zvni_print_hash(struct hash_backet *backet, void *ctxt[]);
 
 static int zvni_macip_send_msg_to_client(vni_t vni, struct ethaddr *macaddr,
                                         struct ipaddr *ip, uint8_t flags,
-                                        uint32_t seq, uint16_t cmd);
+                                        uint32_t seq, int state, uint16_t cmd);
 static unsigned int neigh_hash_keymake(void *p);
 static void *zvni_neigh_alloc(void *p);
 static zebra_neigh_t *zvni_neigh_add(zebra_vni_t *zvni, struct ipaddr *ip,
@@ -97,7 +97,7 @@ static int zvni_neigh_send_add_to_client(vni_t vni, struct ipaddr *ip,
                                         uint8_t flags, uint32_t seq);
 static int zvni_neigh_send_del_to_client(vni_t vni, struct ipaddr *ip,
                                         struct ethaddr *macaddr,
-                                        uint8_t flags);
+                                        uint8_t flags, int state);
 static int zvni_neigh_install(zebra_vni_t *zvni, zebra_neigh_t *n);
 static int zvni_neigh_uninstall(zebra_vni_t *zvni, zebra_neigh_t *n);
 static zebra_vni_t *zvni_from_svi(struct interface *ifp,
@@ -163,7 +163,7 @@ static zebra_vni_t *zvni_add(vni_t vni);
 static int zvni_del(zebra_vni_t *zvni);
 static int zvni_send_add_to_client(zebra_vni_t *zvni);
 static int zvni_send_del_to_client(vni_t vni);
-static void zvni_build_hash_table();
+static void zvni_build_hash_table(void);
 static int zvni_vtep_match(struct in_addr *vtep_ip, zebra_vtep_t *zvtep);
 static zebra_vtep_t *zvni_vtep_find(zebra_vni_t *zvni, struct in_addr *vtep_ip);
 static zebra_vtep_t *zvni_vtep_add(zebra_vni_t *zvni, struct in_addr *vtep_ip);
@@ -2046,7 +2046,7 @@ static void zvni_print_hash_detail(struct hash_backet *backet, void *data)
  */
 static int zvni_macip_send_msg_to_client(vni_t vni, struct ethaddr *macaddr,
                                         struct ipaddr *ip, uint8_t flags,
-                                        uint32_t seq, uint16_t cmd)
+                                        uint32_t seq, int state, uint16_t cmd)
 {
        char buf[ETHER_ADDR_STRLEN];
        char buf2[INET6_ADDRSTRLEN];
@@ -2080,6 +2080,8 @@ static int zvni_macip_send_msg_to_client(vni_t vni, struct ethaddr *macaddr,
        if (cmd == ZEBRA_MACIP_ADD) {
                stream_putc(s, flags); /* sticky mac/gateway mac */
                stream_putl(s, seq); /* sequence number */
+       } else {
+               stream_putl(s, state); /* state - active/inactive */
        }
 
 
@@ -2218,7 +2220,7 @@ static void zvni_neigh_del_hash_entry(struct hash_backet *backet, void *arg)
                && IPV4_ADDR_SAME(&n->r_vtep_ip, &wctx->r_vtep_ip))) {
                if (wctx->upd_client && (n->flags & ZEBRA_NEIGH_LOCAL))
                        zvni_neigh_send_del_to_client(wctx->zvni->vni, &n->ip,
-                                                     &n->emac, 0);
+                                                     &n->emac, 0, n->state);
 
                if (wctx->uninstall)
                        zvni_neigh_uninstall(wctx->zvni, n);
@@ -2354,7 +2356,7 @@ static void zvni_process_neigh_on_local_mac_del(zebra_vni_t *zvni,
                                ZEBRA_NEIGH_SET_INACTIVE(n);
                                n->loc_seq = 0;
                                zvni_neigh_send_del_to_client(zvni->vni, &n->ip,
-                                                             &n->emac, 0);
+                                     &n->emac, 0, ZEBRA_NEIGH_ACTIVE);
                        }
                }
        }
@@ -2385,7 +2387,7 @@ static void zvni_process_neigh_on_remote_mac_add(zebra_vni_t *zvni,
                                ZEBRA_NEIGH_SET_INACTIVE(n);
                                n->loc_seq = 0;
                                zvni_neigh_send_del_to_client(zvni->vni, &n->ip,
-                                                             &n->emac, 0);
+                                             &n->emac, 0, ZEBRA_NEIGH_ACTIVE);
                        }
                }
        }
@@ -2418,17 +2420,18 @@ static int zvni_neigh_send_add_to_client(vni_t vni, struct ipaddr *ip,
                SET_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG);
 
        return zvni_macip_send_msg_to_client(vni, macaddr, ip, flags,
-                                            seq, ZEBRA_MACIP_ADD);
+                            seq, ZEBRA_NEIGH_ACTIVE, ZEBRA_MACIP_ADD);
 }
 
 /*
  * Inform BGP about local neighbor deletion.
  */
 static int zvni_neigh_send_del_to_client(vni_t vni, struct ipaddr *ip,
-                                        struct ethaddr *macaddr, uint8_t flags)
+                                        struct ethaddr *macaddr, uint8_t flags,
+                                        int state)
 {
        return zvni_macip_send_msg_to_client(vni, macaddr, ip, flags,
-                                            0, ZEBRA_MACIP_DEL);
+                                            0, state, ZEBRA_MACIP_DEL);
 }
 
 /*
@@ -2749,7 +2752,7 @@ static int zvni_gw_macip_del(struct interface *ifp, zebra_vni_t *zvni,
 
        /* Remove neighbor from BGP. */
        zvni_neigh_send_del_to_client(zvni->vni, &n->ip, &n->emac,
-                                     ZEBRA_MACIP_TYPE_GW);
+                                     ZEBRA_MACIP_TYPE_GW, ZEBRA_NEIGH_ACTIVE);
 
        /* Delete this neighbor entry. */
        zvni_neigh_del(zvni, n);
@@ -2963,7 +2966,7 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni,
                         */
                        if (IS_ZEBRA_NEIGH_ACTIVE(n))
                                zvni_neigh_send_del_to_client(zvni->vni, &n->ip,
-                                                             &n->emac, 0);
+                                             &n->emac, 0, n->state);
                        old_zmac = zvni_mac_lookup(zvni, &n->emac);
                        if (old_zmac) {
                                old_mac_seq = CHECK_FLAG(old_zmac->flags,
@@ -3319,7 +3322,7 @@ static int zvni_mac_send_add_to_client(vni_t vni, struct ethaddr *macaddr,
                SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
 
        return zvni_macip_send_msg_to_client(vni, macaddr, NULL, flags,
-                                            seq, ZEBRA_MACIP_ADD);
+                            seq, ZEBRA_NEIGH_ACTIVE, ZEBRA_MACIP_ADD);
 }
 
 /*
@@ -3328,7 +3331,7 @@ static int zvni_mac_send_add_to_client(vni_t vni, struct ethaddr *macaddr,
 static int zvni_mac_send_del_to_client(vni_t vni, struct ethaddr *macaddr)
 {
        return zvni_macip_send_msg_to_client(vni, macaddr, NULL, 0 /* flags */,
-                                            0 /* seq */, ZEBRA_MACIP_DEL);
+                            0 /* seq */, ZEBRA_NEIGH_ACTIVE, ZEBRA_MACIP_DEL);
 }
 
 /*
@@ -3841,7 +3844,7 @@ static int zvni_send_del_to_client(vni_t vni)
  * Build the VNI hash table by going over the VxLAN interfaces. This
  * is called when EVPN (advertise-all-vni) is enabled.
  */
-static void zvni_build_hash_table()
+static void zvni_build_hash_table(void)
 {
        struct zebra_ns *zns;
        struct route_node *rn;
@@ -5255,7 +5258,7 @@ static void process_remote_macip_add(vni_t vni,
                                    IS_ZEBRA_NEIGH_ACTIVE(n))
                                        zvni_neigh_send_del_to_client(
                                                zvni->vni, &n->ip,
-                                               &n->emac, 0);
+                                               &n->emac, 0, n->state);
 
                                /* update neigh list for macs */
                                old_mac = zvni_mac_lookup(zvni, &n->emac);
@@ -7074,8 +7077,8 @@ int zebra_vxlan_handle_kernel_neigh_del(struct interface *ifp,
        }
 
        /* Remove neighbor from BGP. */
-       if (IS_ZEBRA_NEIGH_ACTIVE(n))
-               zvni_neigh_send_del_to_client(zvni->vni, &n->ip, &n->emac, 0);
+       zvni_neigh_send_del_to_client(zvni->vni, &n->ip, &n->emac,
+                       0, n->state);
 
        /* Delete this neighbor entry. */
        zvni_neigh_del(zvni, n);
index c50664a28ba45c346d420cde7b6fddcd78a2a376..c25e7357edd532e793ae41e3995d2a9197cc901f 100644 (file)
@@ -37,7 +37,7 @@
 
 /* Is EVPN enabled? */
 #define EVPN_ENABLED(zvrf)  (zvrf)->advertise_all_vni
-static inline int is_evpn_enabled()
+static inline int is_evpn_enabled(void)
 {
        struct zebra_vrf *zvrf = NULL;
        zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
@@ -45,7 +45,7 @@ static inline int is_evpn_enabled()
 }
 
 static inline int
-is_vxlan_flooding_head_end()
+is_vxlan_flooding_head_end(void)
 {
        struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT);
 
index 3be7dc012ac2839bb4939f258c25a84c4e0e2495..cae0d62bb307910e890ff8a324c1658a1e98c9b8 100644 (file)
@@ -313,11 +313,9 @@ struct rmac_walk_ctx {
        struct json_object *json;
 };
 
-enum zebra_neigh_state { ZEBRA_NEIGH_INACTIVE = 0, ZEBRA_NEIGH_ACTIVE = 1 };
+#define IS_ZEBRA_NEIGH_ACTIVE(n) (n->state == ZEBRA_NEIGH_ACTIVE)
 
-#define IS_ZEBRA_NEIGH_ACTIVE(n) n->state == ZEBRA_NEIGH_ACTIVE
-
-#define IS_ZEBRA_NEIGH_INACTIVE(n) n->state == ZEBRA_NEIGH_INACTIVE
+#define IS_ZEBRA_NEIGH_INACTIVE(n) (n->state == ZEBRA_NEIGH_INACTIVE)
 
 #define ZEBRA_NEIGH_SET_ACTIVE(n) n->state = ZEBRA_NEIGH_ACTIVE