]> git.proxmox.com Git - mirror_frr.git/commitdiff
Merge pull request #1174 from opensourcerouting/show_route_defpy
authorDonald Sharp <sharpd@cumulusnetworks.com>
Fri, 27 Oct 2017 14:00:57 +0000 (10:00 -0400)
committerGitHub <noreply@github.com>
Fri, 27 Oct 2017 14:00:57 +0000 (10:00 -0400)
Refactor the 'show ip route' commands using DEFPY

90 files changed:
babeld/babel_main.c
babeld/babel_zebra.c
babeld/babeld.h
bgpd/bgp_debug.c
bgpd/bgp_evpn.c
bgpd/bgp_mpath.c
bgpd/bgp_route.c
bgpd/bgp_routemap.c
bgpd/bgp_updgrp_adv.c
bgpd/bgp_updgrp_packet.c
bgpd/bgp_vty.c
bgpd/bgp_zebra.c
bgpd/rfapi/rfapi_rib.c
bgpd/rfapi/vnc_zebra.c
bgpd/rfp-example/librfp/rfp_example.c
eigrpd/eigrp_network.c
eigrpd/eigrp_structs.h
eigrpd/eigrp_topology.c
eigrpd/eigrp_topology.h
eigrpd/eigrp_update.c
eigrpd/eigrp_vty.c
eigrpd/eigrp_zebra.c
eigrpd/eigrpd.c
eigrpd/eigrpd.h
isisd/isis_bpf.c
isisd/isis_circuit.c
isisd/isis_circuit.h
isisd/isis_constants.h
isisd/isis_dlpi.c
isisd/isis_lsp.c
isisd/isis_pdu.c
isisd/isis_pfpacket.c
isisd/isis_zebra.c
isisd/isisd.c
isisd/isisd.h
ldpd/lde.c
ldpd/ldp_zebra.c
lib/buffer.c
lib/command.c
lib/hash.c
lib/if.c
lib/keychain.c
lib/sockunion.c
lib/zclient.c
lib/zclient.h
nhrpd/nhrp_main.c
nhrpd/nhrp_route.c
nhrpd/nhrp_vty.c
nhrpd/nhrpd.h
ospf6d/ospf6_network.c
ospf6d/ospf6_zebra.c
ospf6d/ospf6d.h
ospfd/ospf_interface.c
ospfd/ospf_lsa.c
ospfd/ospf_network.c
ospfd/ospf_packet.c
ospfd/ospf_ri.c
ospfd/ospf_te.c
ospfd/ospf_vty.c
ospfd/ospf_zebra.c
ospfd/ospfd.c
ospfd/ospfd.h
pimd/pim_zebra.c
pimd/pim_zlookup.c
ripd/rip_interface.c
ripd/rip_zebra.c
ripd/ripd.c
ripd/ripd.h
ripngd/ripng_interface.c
ripngd/ripng_zebra.c
ripngd/ripngd.c
ripngd/ripngd.h
tests/isisd/test_fuzz_isis_tlv.c
tests/isisd/test_isis_vertex_queue.c
tools/start-stop-daemon.c
vtysh/vtysh.c
vtysh/vtysh_main.c
zebra/debug.c
zebra/interface.c
zebra/rt_netlink.c
zebra/rtadv.c
zebra/rtadv.h
zebra/zebra_mroute.c
zebra/zebra_mroute.h
zebra/zebra_ptm.c
zebra/zebra_ptm.h
zebra/zebra_pw.c
zebra/zebra_vxlan.c
zebra/zebra_vxlan.h
zebra/zserv.c

index 239ab71f066f0a987407fc80a5935fa34bafe574..48f6994d82b39056279251209becc74d945331a0 100644 (file)
@@ -84,7 +84,7 @@ static zebra_capabilities_t _caps_p [] =
     ZCAP_BIND
 };
 
-static struct zebra_privs_t babeld_privs =
+struct zebra_privs_t babeld_privs =
 {
 #if defined(FRR_USER)
     .user = FRR_USER,
index 337b7b3927163e40a52e998aa6484b302b9188d0..e7c27e8e21f3dbbf8363eac7c67e0c5b085650b1 100644 (file)
@@ -238,7 +238,7 @@ babel_zebra_connected (struct zclient *zclient)
 void babelz_zebra_init(void)
 {
     zclient = zclient_new(master);
-    zclient_init(zclient, ZEBRA_ROUTE_BABEL, 0);
+    zclient_init(zclient, ZEBRA_ROUTE_BABEL, 0, &babeld_privs);
 
     zclient->zebra_connected = babel_zebra_connected;
     zclient->interface_add = babel_interface_add;
index 899b4f175c46cca29449a8ff4e21ce67ec39fc53..bc284c1e96d5fa255ca6dbc1d0c8cbc5221423d1 100644 (file)
@@ -113,6 +113,8 @@ struct babel
     struct thread *t_update;  /* timers */
 };
 
+extern struct zebra_privs_t babeld_privs;
+
 extern void babeld_quagga_init(void);
 extern int input_filter(const unsigned char *id,
                         const unsigned char *prefix, unsigned short plen,
index 6de9ba3cc61a096e88256c47017fd096924031ab..1fb930fdef7bd2eda698d0392bc9660bc861539b 100644 (file)
@@ -1587,6 +1587,7 @@ DEFUN (no_debug_bgp,
        TERM_DEBUG_OFF(neighbor_events, NEIGHBOR_EVENTS);
        TERM_DEBUG_OFF(zebra, ZEBRA);
        TERM_DEBUG_OFF(allow_martians, ALLOW_MARTIANS);
+       TERM_DEBUG_OFF(nht, NHT);
        vty_out(vty, "All possible debugging has been turned off\n");
 
        return CMD_SUCCESS;
index a09d966d7b0086f8f925060dee45450f8e8d608a..182a6c64f2b3aad2a4c7dfef627959b4b77fd0d9 100644 (file)
@@ -2542,7 +2542,7 @@ void bgp_evpn_derive_auto_rd(struct bgp *bgp, struct bgpevpn *vpn)
        vpn->prd.family = AF_UNSPEC;
        vpn->prd.prefixlen = 64;
        sprintf(buf, "%s:%hu", inet_ntoa(bgp->router_id), vpn->rd_id);
-       str2prefix_rd(buf, &vpn->prd);
+       (void)str2prefix_rd(buf, &vpn->prd);
        UNSET_FLAG(vpn->flags, VNI_FLAG_RD_CFGD);
 }
 
index d3ee140bb412a0946dc7614498cac03c4c52d6bf..9d32c4bee11d916937162ef007df83be9b957c49 100644 (file)
@@ -751,6 +751,10 @@ void bgp_info_mpath_aggregate_update(struct bgp_info *new_best,
                        attr.ecommunity = ecomm;
                        attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
                }
+               if (lcomm) {
+                       attr.lcommunity = lcomm;
+                       attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES);
+               }
 
                /* Zap multipath attr nexthop so we set nexthop to self */
                attr.nexthop.s_addr = 0;
index 0c2a2f6fe9976203bb808ee874256244faeec3ad..af71088b7deba3346e24fd5a366bc4d99ea1036d 100644 (file)
@@ -10545,7 +10545,7 @@ DEFUN (show_bgp_afi_vpn_rd_route,
        afi_t afi = AFI_MAX;
        int idx = 0;
 
-       argv_find_and_parse_afi(argv, argc, &idx, &afi);
+       (void)argv_find_and_parse_afi(argv, argc, &idx, &afi);
        ret = str2prefix_rd(argv[5]->arg, &prd);
        if (!ret) {
                vty_out(vty, "%% Malformed Route Distinguisher\n");
index bb3def2fbe0c6464d90feb37ec7d3ca9792f098d..217916239c890c63a7002ea7a5ada7d019e19f42 100644 (file)
@@ -2913,10 +2913,6 @@ static void bgp_route_map_process_update(struct bgp *bgp, const char *rmap_name,
 
                for (afi = AFI_IP; afi < AFI_MAX; afi++)
                        for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
-                               /* Ignore inactive AFI/SAFI */
-                               if (!peer->afc[afi][safi])
-                                       continue;
-
                                /* process in/out/import/export/default-orig
                                 * route-maps */
                                bgp_route_map_process_peer(rmap_name, map, peer,
index fbbeaee9b252ff24eee1d3cbb71cdf697ab2afd8..8a24cba5980394373ddf9499693f214bce315310 100644 (file)
@@ -687,11 +687,11 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw)
 
        attr.local_pref = bgp->default_local_pref;
 
-       if (afi == AFI_IP)
-               str2prefix("0.0.0.0/0", &p);
-       else if (afi == AFI_IP6) {
-               str2prefix("::/0", &p);
+       memset(&p, 0, sizeof(p));
+       p.family = afi2family(afi);
+       p.prefixlen = 0;
 
+       if (afi == AFI_IP6) {
                /* IPv6 global nexthop must be included. */
                attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
 
@@ -759,10 +759,9 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw)
                         * clear adj_out for the 0.0.0.0/0 prefix in the BGP
                         * table.
                         */
-                       if (afi == AFI_IP)
-                               str2prefix("0.0.0.0/0", &p);
-                       else
-                               str2prefix("::/0", &p);
+                       memset(&p, 0, sizeof(p));
+                       p.family = afi2family(afi);
+                       p.prefixlen = 0;
 
                        rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi,
                                              &p, NULL);
index 433c5ce512d9eee07c985d0e4dd5e8e20e6d8be0..a35d814e477cc8c00f4473135aefcdecf61a57f6 100644 (file)
@@ -1090,10 +1090,9 @@ void subgroup_default_update_packet(struct update_subgroup *subgrp,
        bpacket_attr_vec_arr_reset(&vecarr);
        addpath_encode = bgp_addpath_encode_tx(peer, afi, safi);
 
-       if (afi == AFI_IP)
-               str2prefix("0.0.0.0/0", &p);
-       else
-               str2prefix("::/0", &p);
+       memset(&p, 0, sizeof(p));
+       p.family = afi2family(afi);
+       p.prefixlen = 0;
 
        /* Logging the attribute. */
        if (bgp_debug_update(NULL, &p, subgrp->update_group, 0)) {
@@ -1176,10 +1175,9 @@ void subgroup_default_withdraw_packet(struct update_subgroup *subgrp)
        safi = SUBGRP_SAFI(subgrp);
        addpath_encode = bgp_addpath_encode_tx(peer, afi, safi);
 
-       if (afi == AFI_IP)
-               str2prefix("0.0.0.0/0", &p);
-       else
-               str2prefix("::/0", &p);
+       memset(&p, 0, sizeof(p));
+       p.family = afi2family(afi);
+       p.prefixlen = 0;
 
        if (bgp_debug_update(NULL, &p, subgrp->update_group, 0)) {
                char buf[PREFIX_STRLEN];
index 02a194050cc65e91310d5d245761fcb0aa8c7bd3..749c9d25d42d9ce3c471e550c44b993da3dd5070 100644 (file)
@@ -3794,7 +3794,7 @@ DEFUN (neighbor_remove_private_as_all,
        NEIGHBOR_STR
        NEIGHBOR_ADDR_STR2
        "Remove private ASNs in outbound updates\n"
-       "Apply to all AS numbers")
+       "Apply to all AS numbers\n")
 {
        int idx_peer = 1;
        return peer_af_flag_set_vty(vty, argv[idx_peer]->arg, bgp_node_afi(vty),
@@ -5733,7 +5733,7 @@ DEFUN (neighbor_maximum_prefix_restart,
        "Maximum number of prefix accept from this peer\n"
        "maximum no. of prefix limit\n"
        "Restart bgp connection after limit is exceeded\n"
-       "Restart interval in minutes")
+       "Restart interval in minutes\n")
 {
        int idx_peer = 1;
        int idx_number = 3;
@@ -5751,7 +5751,7 @@ ALIAS_HIDDEN(
        "Maximum number of prefix accept from this peer\n"
        "maximum no. of prefix limit\n"
        "Restart bgp connection after limit is exceeded\n"
-       "Restart interval in minutes")
+       "Restart interval in minutes\n")
 
 DEFUN (neighbor_maximum_prefix_threshold_restart,
        neighbor_maximum_prefix_threshold_restart_cmd,
index ddf461f1b183bc93658c0267b2992ca540f501b7..0d1d768294ff572f152a52628b4453cccb2f5738 100644 (file)
@@ -1105,12 +1105,11 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
                                                          ->ifindex;
 
                        if (!ifindex) {
-                               if (mpinfo->peer->conf_if
-                                   || mpinfo->peer->ifname)
+                               if (mpinfo->peer->conf_if)
+                                       ifindex = mpinfo->peer->ifp->ifindex;
+                               else if (mpinfo->peer->ifname)
                                        ifindex = ifname2ifindex(
-                                               mpinfo->peer->conf_if
-                                                       ? mpinfo->peer->conf_if
-                                                       : mpinfo->peer->ifname,
+                                               mpinfo->peer->ifname,
                                                bgp->vrf_id);
                                else if (mpinfo->peer->nexthop.ifp)
                                        ifindex = mpinfo->peer->nexthop.ifp
@@ -1749,13 +1748,15 @@ static int bgp_zebra_process_local_macip(int command, struct zclient *zclient,
                return bgp_evpn_local_macip_del(bgp, vni, &mac, &ip);
 }
 
+extern struct zebra_privs_t bgpd_privs;
+
 void bgp_zebra_init(struct thread_master *master)
 {
        zclient_num_connects = 0;
 
        /* Set default values. */
        zclient = zclient_new(master);
-       zclient_init(zclient, ZEBRA_ROUTE_BGP, 0);
+       zclient_init(zclient, ZEBRA_ROUTE_BGP, 0, &bgpd_privs);
        zclient->zebra_connected = bgp_zebra_connected;
        zclient->router_id_update = bgp_router_id_update;
        zclient->interface_add = bgp_interface_add;
index 92cd1888ee267dee5b8c83da586cd4a8f5680fb4..36ae6e7273776644e6738bd5a7bdcb75513a981a 100644 (file)
@@ -1668,7 +1668,7 @@ void rfapiRibUpdatePendingNode(
 
                        struct prefix pfx_vn;
 
-                       rfapiRaddr2Qprefix(&rfd->vn_addr, &pfx_vn);
+                       assert(!rfapiRaddr2Qprefix(&rfd->vn_addr, &pfx_vn));
                        if (prefix_same(&pfx_vn, &pfx_nh))
                                continue;
                }
index b8058cf1e5eff4a3a33c113aee13bb69840ba488..478d3b5ac7669a9893fd90df6c91ccaffd032f90 100644 (file)
@@ -883,6 +883,7 @@ int vnc_redistribute_unset(struct bgp *bgp, afi_t afi, int type)
        return CMD_SUCCESS;
 }
 
+extern struct zebra_privs_t bgpd_privs;
 
 /*
  * Modeled after bgp_zebra.c'bgp_zebra_init()
@@ -892,7 +893,7 @@ void vnc_zebra_init(struct thread_master *master)
 {
        /* Set default values. */
        zclient_vnc = zclient_new(master);
-       zclient_init(zclient_vnc, ZEBRA_ROUTE_VNC, 0);
+       zclient_init(zclient_vnc, ZEBRA_ROUTE_VNC, 0, &bgpd_privs);
 
        zclient_vnc->redistribute_route_add = vnc_zebra_read_route;
        zclient_vnc->redistribute_route_del = vnc_zebra_read_route;
index fb112a8865e985da77702c0c3f68839029491460..cde2d7b3523123b1dd2ee60e826c2a4e3c7e69e4 100644 (file)
@@ -42,7 +42,7 @@ DEFUN (rfp_example_config_value,
        "rfp example-config-value VALUE",
        RFP_SHOW_STR
        "Example value to be configured\n"
-       "Value to display")
+       "Value to display\n")
 {
        uint32_t value = 0;
        struct rfp_instance_t *rfi = NULL;
index 56327f12051fdfb9d4f0318107084856016e7951..21413bf4460c45d3715c8a42125a3f96d03c4323 100644 (file)
@@ -38,8 +38,6 @@
 #include "table.h"
 #include "vty.h"
 
-extern struct zebra_privs_t eigrpd_privs;
-
 #include "eigrpd/eigrp_structs.h"
 #include "eigrpd/eigrpd.h"
 #include "eigrpd/eigrp_interface.h"
index 4441f5d00418c2016f47980351ed4bc297fd1658..324181c21ea5448c85e9ff0de0ee2a58e7ce73f2 100644 (file)
@@ -100,7 +100,7 @@ struct eigrp {
 
        struct route_table *networks; /* EIGRP config networks. */
 
-       struct list *topology_table;
+       struct route_table *topology_table;
 
        uint64_t serno; /* Global serial number counter for topology entry
                           changes*/
index 94775622d98d02d144d3c6eae26b983810f19df7..7d352b8bedf1d81c94f3162f3cd0d8cb0e227e77 100644 (file)
@@ -51,9 +51,6 @@
 #include "eigrpd/eigrp_fsm.h"
 #include "eigrpd/eigrp_memory.h"
 
-static int eigrp_prefix_entry_cmp(struct eigrp_prefix_entry *,
-                                 struct eigrp_prefix_entry *);
-static void eigrp_prefix_entry_del(struct eigrp_prefix_entry *);
 static int eigrp_nexthop_entry_cmp(struct eigrp_nexthop_entry *,
                                    struct eigrp_nexthop_entry *);
 
@@ -63,45 +60,9 @@ static int eigrp_nexthop_entry_cmp(struct eigrp_nexthop_entry *,
  * del - assigned function executed before deleting topology node by list
  * function
  */
-struct list *eigrp_topology_new()
+struct route_table *eigrp_topology_new()
 {
-       struct list *new = list_new();
-       new->cmp = (int (*)(void *, void *))eigrp_prefix_entry_cmp;
-       new->del = (void (*)(void *))eigrp_prefix_entry_del;
-
-       return new;
-}
-
-/*
- * Topology node comparison
- */
-
-static int eigrp_prefix_entry_cmp(struct eigrp_prefix_entry *node1,
-                                 struct eigrp_prefix_entry *node2)
-{
-       if (node1->af == AF_INET) {
-               if (node2->af == AF_INET) {
-                       if (node1->destination->u.prefix4.s_addr
-                           < node2->destination->u.prefix4.s_addr)
-                               return -1;
-                       if (node1->destination->u.prefix4.s_addr
-                           > node2->destination->u.prefix4.s_addr)
-                               return 1;
-                       else
-                               return 0;
-               } else
-                       return 1;
-       } else
-               return 1;
-}
-
-/*
- * Topology node delete
- */
-
-static void eigrp_prefix_entry_del(struct eigrp_prefix_entry *node)
-{
-       list_delete_and_null(&node->entries);
+       return route_table_init();
 }
 
 /*
@@ -155,30 +116,41 @@ struct eigrp_nexthop_entry *eigrp_nexthop_entry_new()
 /*
  * Freeing topology table list
  */
-void eigrp_topology_free(struct list *list)
+void eigrp_topology_free(struct route_table *table)
 {
-       list_delete_and_null(&list);
+       route_table_finish(table);
 }
 
 /*
  * Deleting all topology nodes in table
  */
-void eigrp_topology_cleanup(struct list *topology)
+void eigrp_topology_cleanup(struct route_table *table)
 {
-       assert(topology);
-
-       eigrp_topology_delete_all(topology);
+       eigrp_topology_delete_all(table);
 }
 
 /*
  * Adding topology node to topology table
  */
-void eigrp_prefix_entry_add(struct list *topology,
-                           struct eigrp_prefix_entry *node)
+void eigrp_prefix_entry_add(struct route_table *topology,
+                           struct eigrp_prefix_entry *pe)
 {
-       if (listnode_lookup(topology, node) == NULL) {
-               listnode_add_sort(topology, node);
+       struct route_node *rn;
+
+       rn = route_node_get(topology, pe->destination);
+       if (rn->info) {
+               if (IS_DEBUG_EIGRP_EVENT) {
+                       char buf[PREFIX_STRLEN];
+
+                       zlog_debug("%s: %s Should we have found this entry in the topo table?",
+                                  __PRETTY_FUNCTION__,
+                                  prefix2str(pe->destination, buf,
+                                             sizeof(buf)));
+               }
        }
+
+       rn->info = pe;
+       route_lock_node(rn);
 }
 
 /*
@@ -204,24 +176,30 @@ void eigrp_nexthop_entry_add(struct eigrp_prefix_entry *node,
 /*
  * Deleting topology node from topology table
  */
-void eigrp_prefix_entry_delete(struct list *topology,
-                              struct eigrp_prefix_entry *node)
+void eigrp_prefix_entry_delete(struct route_table *table,
+                              struct eigrp_prefix_entry *pe)
 {
        struct eigrp *eigrp = eigrp_lookup();
+       struct route_node *rn;
+
+       rn = route_node_lookup(table, pe->destination);
+       if (!rn)
+               return;
 
        /*
         * Emergency removal of the node from this list.
         * Whatever it is.
         */
-       listnode_delete(eigrp->topology_changes_internalIPV4, node);
+       listnode_delete(eigrp->topology_changes_internalIPV4, pe);
 
-       if (listnode_lookup(topology, node) != NULL) {
-               list_delete_and_null(&node->entries);
-               list_delete_and_null(&node->rij);
-               listnode_delete(topology, node);
-               eigrp_zebra_route_delete(node->destination);
-               XFREE(MTYPE_EIGRP_PREFIX_ENTRY, node);
-       }
+       list_delete_and_null(&pe->entries);
+       list_delete_and_null(&pe->rij);
+       eigrp_zebra_route_delete(pe->destination);
+
+       rn->info = NULL;
+       route_unlock_node(rn);  //Lookup above
+       route_unlock_node(rn);  //Initial creation
+       XFREE(MTYPE_EIGRP_PREFIX_ENTRY, pe);
 }
 
 /*
@@ -240,9 +218,19 @@ void eigrp_nexthop_entry_delete(struct eigrp_prefix_entry *node,
 /*
  * Deleting all nodes from topology table
  */
-void eigrp_topology_delete_all(struct list *topology)
+void eigrp_topology_delete_all(struct route_table *topology)
 {
-       list_delete_all_node(topology);
+       struct route_node *rn;
+       struct eigrp_prefix_entry *pe;
+
+       for (rn = route_top(topology); rn; rn = route_next(rn)) {
+               pe = rn->info;
+
+               if (!pe)
+                       continue;
+
+               eigrp_prefix_entry_delete(topology, pe);
+       }
 }
 
 /*
@@ -258,17 +246,21 @@ unsigned int eigrp_topology_table_isempty(struct list *topology)
 }
 
 struct eigrp_prefix_entry *
-eigrp_topology_table_lookup_ipv4(struct list *topology_table,
+eigrp_topology_table_lookup_ipv4(struct route_table *table,
                                 struct prefix *address)
 {
-       struct eigrp_prefix_entry *data;
-       struct listnode *node;
-       for (ALL_LIST_ELEMENTS_RO(topology_table, node, data)) {
-               if (prefix_same(data->destination, address))
-                       return data;
-       }
+       struct eigrp_prefix_entry *pe;
+       struct route_node *rn;
 
-       return NULL;
+       rn = route_node_lookup(table, address);
+       if (!rn)
+               return NULL;
+
+       pe = rn->info;
+
+       route_unlock_node(rn);
+
+       return pe;
 }
 
 /*
@@ -337,20 +329,24 @@ eigrp_prefix_entry_lookup(struct list *entries, struct eigrp_neighbor *nbr)
 struct list *eigrp_neighbor_prefixes_lookup(struct eigrp *eigrp,
                                            struct eigrp_neighbor *nbr)
 {
-       struct listnode *node1, *node11, *node2, *node22;
-       struct eigrp_prefix_entry *prefix;
+       struct listnode *node2, *node22;
        struct eigrp_nexthop_entry *entry;
+       struct eigrp_prefix_entry *pe;
+       struct route_node *rn;
 
        /* create new empty list for prefixes storage */
        struct list *prefixes = list_new();
 
        /* iterate over all prefixes in topology table */
-       for (ALL_LIST_ELEMENTS(eigrp->topology_table, node1, node11, prefix)) {
+       for (rn = route_top(eigrp->topology_table); rn; rn = route_next(rn)) {
+               if (!rn->info)
+                       continue;
+               pe = rn->info;
                /* iterate over all neighbor entry in prefix */
-               for (ALL_LIST_ELEMENTS(prefix->entries, node2, node22, entry)) {
+               for (ALL_LIST_ELEMENTS(pe->entries, node2, node22, entry)) {
                        /* if entry is from specified neighbor, add to list */
                        if (entry->adv_router == nbr) {
-                               listnode_add(prefixes, prefix);
+                               listnode_add(prefixes, pe);
                        }
                }
        }
@@ -426,11 +422,16 @@ enum metric_change eigrp_topology_update_distance(struct eigrp_fsm_action_messag
 
 void eigrp_topology_update_all_node_flags(struct eigrp *eigrp)
 {
-       struct list *table = eigrp->topology_table;
-       struct eigrp_prefix_entry *data;
-       struct listnode *node, *nnode;
-       for (ALL_LIST_ELEMENTS(table, node, nnode, data)) {
-               eigrp_topology_update_node_flags(data);
+       struct eigrp_prefix_entry *pe;
+       struct route_node *rn;
+
+       for (rn = route_top(eigrp->topology_table); rn; rn = route_next(rn)) {
+               pe = rn->info;
+
+               if (!pe)
+                       continue;
+
+               eigrp_topology_update_node_flags(pe);
        }
 }
 
@@ -484,12 +485,18 @@ void eigrp_update_routing_table(struct eigrp_prefix_entry *prefix)
 void eigrp_topology_neighbor_down(struct eigrp *eigrp,
                                  struct eigrp_neighbor *nbr)
 {
-       struct listnode *node1, *node11, *node2, *node22;
-       struct eigrp_prefix_entry *prefix;
+       struct listnode *node2, *node22;
+       struct eigrp_prefix_entry *pe;
        struct eigrp_nexthop_entry *entry;
+       struct route_node *rn;
+
+       for (rn = route_top(eigrp->topology_table); rn; rn = route_next(rn)) {
+               pe = rn->info;
+
+               if (!pe)
+                       continue;
 
-       for (ALL_LIST_ELEMENTS(eigrp->topology_table, node1, node11, prefix)) {
-               for (ALL_LIST_ELEMENTS(prefix->entries, node2, node22, entry)) {
+               for (ALL_LIST_ELEMENTS(pe->entries, node2, node22, entry)) {
                        struct eigrp_fsm_action_message msg;
 
                        if (entry->adv_router != nbr)
@@ -501,7 +508,7 @@ void eigrp_topology_neighbor_down(struct eigrp *eigrp,
                        msg.data_type = EIGRP_INT;
                        msg.adv_router = nbr;
                        msg.entry = entry;
-                       msg.prefix = prefix;
+                       msg.prefix = pe;
                        eigrp_fsm_event(&msg);
                }
        }
@@ -510,7 +517,7 @@ void eigrp_topology_neighbor_down(struct eigrp *eigrp,
        eigrp_update_send_all(eigrp, nbr->ei);
 }
 
-void eigrp_update_topology_table_prefix(struct list *table,
+void eigrp_update_topology_table_prefix(struct route_table *table,
                                        struct eigrp_prefix_entry *prefix)
 {
        struct listnode *node1, *node2;
index ef5b32d5bf491035de2c8469b266b572c398fe6b..c8772c8c3aea4ea5c3ac6ef922c371bfe0b4c0ac 100644 (file)
 #define _ZEBRA_EIGRP_TOPOLOGY_H
 
 /* EIGRP Topology table related functions. */
-extern struct list *eigrp_topology_new(void);
-extern void eigrp_topology_init(struct list *);
+extern struct route_table *eigrp_topology_new(void);
+extern void eigrp_topology_init(struct route_table *table);
 extern struct eigrp_prefix_entry *eigrp_prefix_entry_new(void);
 extern struct eigrp_nexthop_entry *eigrp_nexthop_entry_new(void);
-extern void eigrp_topology_free(struct list *);
-extern void eigrp_topology_cleanup(struct list *);
-extern void eigrp_prefix_entry_add(struct list *, struct eigrp_prefix_entry *);
+extern void eigrp_topology_free(struct route_table *table);
+extern void eigrp_topology_cleanup(struct route_table *table);
+extern void eigrp_prefix_entry_add(struct route_table *table,
+                                  struct eigrp_prefix_entry *pe);
 extern void eigrp_nexthop_entry_add(struct eigrp_prefix_entry *,
                                     struct eigrp_nexthop_entry *);
-extern void eigrp_prefix_entry_delete(struct list *,
-                                     struct eigrp_prefix_entry *);
+extern void eigrp_prefix_entry_delete(struct route_table *table,
+                                     struct eigrp_prefix_entry *pe);
 extern void eigrp_nexthop_entry_delete(struct eigrp_prefix_entry *,
                                        struct eigrp_nexthop_entry *);
-extern void eigrp_topology_delete_all(struct list *);
+extern void eigrp_topology_delete_all(struct route_table *table);
 extern unsigned int eigrp_topology_table_isempty(struct list *);
 extern struct eigrp_prefix_entry *
-eigrp_topology_table_lookup_ipv4(struct list *, struct prefix *);
+eigrp_topology_table_lookup_ipv4(struct route_table *table,
+                                struct prefix *p);
 extern struct list *eigrp_topology_get_successor(struct eigrp_prefix_entry *);
 extern struct list *
 eigrp_topology_get_successor_max(struct eigrp_prefix_entry *pe,
@@ -64,7 +66,7 @@ extern enum metric_change eigrp_topology_update_distance(struct eigrp_fsm_action
 extern void eigrp_update_routing_table(struct eigrp_prefix_entry *);
 extern void eigrp_topology_neighbor_down(struct eigrp *,
                                         struct eigrp_neighbor *);
-extern void eigrp_update_topology_table_prefix(struct list *,
-                                              struct eigrp_prefix_entry *);
+extern void eigrp_update_topology_table_prefix(struct route_table *table,
+                                              struct eigrp_prefix_entry *pe);
 
 #endif
index 4a86b489445eece31b209f4ec530f6a331c97626..b4d1c58870feb02668b7639b22b0017d60d429c0 100644 (file)
@@ -530,13 +530,15 @@ void eigrp_update_send_EOT(struct eigrp_neighbor *nbr)
        u_int16_t length = EIGRP_HEADER_LEN;
        struct eigrp_nexthop_entry *te;
        struct eigrp_prefix_entry *pe;
-       struct listnode *node, *node2, *nnode, *nnode2;
+       struct listnode *node2, *nnode2;
        struct eigrp_interface *ei = nbr->ei;
        struct eigrp *eigrp = ei->eigrp;
        struct prefix *dest_addr;
        u_int32_t seq_no = eigrp->sequence_number;
+       u_int16_t mtu = ei->ifp->mtu;
+       struct route_node *rn;
 
-       ep = eigrp_packet_new(ei->ifp->mtu, nbr);
+       ep = eigrp_packet_new(mtu, nbr);
 
        /* Prepare EIGRP EOT UPDATE header */
        eigrp_packet_header_init(EIGRP_OPC_UPDATE, eigrp,
@@ -549,20 +551,26 @@ void eigrp_update_send_EOT(struct eigrp_neighbor *nbr)
                length += eigrp_add_authTLV_MD5_to_stream(ep->s,ei);
        }
 
-       for (ALL_LIST_ELEMENTS(eigrp->topology_table, node, nnode, pe)) {
+       for (rn = route_top(eigrp->topology_table); rn; rn = route_next(rn)) {
+               if (!rn->info)
+                       continue;
+
+               pe = rn->info;
                for (ALL_LIST_ELEMENTS(pe->entries, node2, nnode2, te)) {
                        if (eigrp_nbr_split_horizon_check(te, ei))
                                continue;
 
-                       if ((length + 0x001D) > (u_int16_t)ei->ifp->mtu) {
+                       if ((length + 0x001D) > mtu) {
                                eigrp_update_place_on_nbr_queue (nbr, ep, seq_no, length);
                                seq_no++;
 
                                length = EIGRP_HEADER_LEN;
-                               ep = eigrp_packet_new(ei->ifp->mtu, nbr);
-                               eigrp_packet_header_init(EIGRP_OPC_UPDATE, eigrp,
+                               ep = eigrp_packet_new(mtu, nbr);
+                               eigrp_packet_header_init(EIGRP_OPC_UPDATE,
+                                                        nbr->ei->eigrp,
                                                         ep->s, EIGRP_EOT_FLAG,
-                                                        seq_no, nbr->recv_sequence_number);
+                                                        seq_no,
+                                                        nbr->recv_sequence_number);
 
                                if((ei->params.auth_type == EIGRP_AUTH_TYPE_MD5) &&
                                   (ei->params.auth_keychain != NULL))
@@ -736,7 +744,6 @@ static void eigrp_update_send_GR_part(struct eigrp_neighbor *nbr)
 {
        struct eigrp_packet *ep;
        u_int16_t length = EIGRP_HEADER_LEN;
-       struct listnode *node, *nnode;
        struct eigrp_prefix_entry *pe;
        struct prefix *dest_addr;
        struct eigrp_interface *ei = nbr->ei;
@@ -744,6 +751,7 @@ static void eigrp_update_send_GR_part(struct eigrp_neighbor *nbr)
        struct list *prefixes;
        u_int32_t flags;
        unsigned int send_prefixes;
+       struct route_node *rn;
 
        /* get prefixes to send to neighbor */
        prefixes = nbr->nbr_gr_prefixes_send;
@@ -795,7 +803,11 @@ static void eigrp_update_send_GR_part(struct eigrp_neighbor *nbr)
                length += eigrp_add_authTLV_MD5_to_stream(ep->s, ei);
        }
 
-       for (ALL_LIST_ELEMENTS(eigrp->topology_table, node, nnode, pe)) {
+       for (rn = route_top(eigrp->topology_table); rn; rn = route_next(rn)) {
+               if (!rn->info)
+                       continue;
+
+               pe = rn->info;
                /*
                 * Filtering
                 */
@@ -945,35 +957,40 @@ void eigrp_update_send_GR(struct eigrp_neighbor *nbr, enum GR_type gr_type,
                          struct vty *vty)
 {
        struct eigrp_prefix_entry *pe2;
-       struct listnode *node2, *nnode2;
        struct list *prefixes;
+       struct route_node *rn;
+       struct eigrp_interface *ei = nbr->ei;
+       struct eigrp *eigrp = ei->eigrp;
 
        if (gr_type == EIGRP_GR_FILTER) {
                /* function was called after applying filtration */
                zlog_info(
                        "Neighbor %s (%s) is resync: route configuration changed",
                        inet_ntoa(nbr->src),
-                       ifindex2ifname(nbr->ei->ifp->ifindex, VRF_DEFAULT));
+                       ifindex2ifname(ei->ifp->ifindex, VRF_DEFAULT));
        } else if (gr_type == EIGRP_GR_MANUAL) {
                /* Graceful restart was called manually */
                zlog_info("Neighbor %s (%s) is resync: manually cleared",
                          inet_ntoa(nbr->src),
-                         ifindex2ifname(nbr->ei->ifp->ifindex, VRF_DEFAULT));
+                         ifindex2ifname(ei->ifp->ifindex, VRF_DEFAULT));
 
                if (vty != NULL) {
                        vty_time_print(vty, 0);
                        vty_out(vty,
                                "Neighbor %s (%s) is resync: manually cleared\n",
                                inet_ntoa(nbr->src),
-                               ifindex2ifname(nbr->ei->ifp->ifindex,
+                               ifindex2ifname(ei->ifp->ifindex,
                                               VRF_DEFAULT));
                }
        }
 
        prefixes = list_new();
        /* add all prefixes from topology table to list */
-       for (ALL_LIST_ELEMENTS(nbr->ei->eigrp->topology_table, node2, nnode2,
-                              pe2)) {
+       for (rn = route_top(eigrp->topology_table); rn; rn = route_next(rn)) {
+               if (!rn->info)
+                       continue;
+
+               pe2 = rn->info;
                listnode_add(prefixes, pe2);
        }
 
index d93abbb8b7183c50283ff50971cacbbef430b10c..4e7642853574474c0f4e41651a2a7fe47bad02bd 100644 (file)
@@ -398,7 +398,7 @@ DEFUN (eigrp_network,
        struct prefix p;
        int ret;
 
-       str2prefix(argv[1]->arg, &p);
+       (void)str2prefix(argv[1]->arg, &p);
 
        ret = eigrp_network_set(eigrp, &p);
 
@@ -421,7 +421,7 @@ DEFUN (no_eigrp_network,
        struct prefix p;
        int ret;
 
-       str2prefix(argv[2]->arg, &p);
+       (void)str2prefix(argv[2]->arg, &p);
 
        ret = eigrp_network_unset(eigrp, &p);
 
@@ -466,9 +466,10 @@ DEFUN (show_ip_eigrp_topology,
        "Show all links in topology table\n")
 {
        struct eigrp *eigrp;
-       struct listnode *node, *node2;
+       struct listnode *node;
        struct eigrp_prefix_entry *tn;
        struct eigrp_nexthop_entry *te;
+       struct route_node *rn;
        int first;
 
        eigrp = eigrp_lookup();
@@ -479,9 +480,13 @@ DEFUN (show_ip_eigrp_topology,
 
        show_ip_eigrp_topology_header(vty, eigrp);
 
-       for (ALL_LIST_ELEMENTS_RO(eigrp->topology_table, node, tn)) {
+       for (rn = route_top(eigrp->topology_table); rn; rn = route_next(rn)) {
+               if (!rn->info)
+                       continue;
+
+               tn = rn->info;
                first = 1;
-               for (ALL_LIST_ELEMENTS_RO(tn->entries, node2, te)) {
+               for (ALL_LIST_ELEMENTS_RO(tn->entries, node, te)) {
                        if (argc == 5
                            || (((te->flags
                                  & EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG)
@@ -865,11 +870,10 @@ DEFUN (no_eigrp_ip_summary_address,
 DEFUN (no_eigrp_if_ip_holdinterval,
        no_eigrp_if_ip_holdinterval_cmd,
        "no ip hold-time eigrp",
-       "No"
+       NO_STR
        "Interface Internet Protocol config commands\n"
        "Configures EIGRP hello interval\n"
-       "Enhanced Interior Gateway Routing Protocol (EIGRP)\n"
-       "Seconds before neighbor is considered down\n")
+       "Enhanced Interior Gateway Routing Protocol (EIGRP)\n")
 {
        VTY_DECLVAR_CONTEXT(interface, ifp);
        struct eigrp_interface *ei = ifp->info;
index 28d2f298119a712331ba570f3b642694eb8fcb75..9076a50f57dfdcab97085f6b03975c7d2134c33e 100644 (file)
@@ -103,7 +103,7 @@ void eigrp_zebra_init(void)
 {
        zclient = zclient_new(master);
 
-       zclient_init(zclient, ZEBRA_ROUTE_EIGRP, 0);
+       zclient_init(zclient, ZEBRA_ROUTE_EIGRP, 0, &eigrpd_privs);
        zclient->zebra_connected = eigrp_zebra_connected;
        zclient->router_id_update = eigrp_router_id_update_zebra;
        zclient->interface_add = eigrp_interface_add;
index a8173f4efdc21943d78c4847c92f48f162a70ece..42d398458e12b2495f5cb118c66705689df9004c 100644 (file)
@@ -158,7 +158,7 @@ static struct eigrp *eigrp_new(const char *AS)
        /* init internal data structures */
        eigrp->eiflist = list_new();
        eigrp->passive_interface_default = EIGRP_IF_ACTIVE;
-       eigrp->networks = route_table_init();
+       eigrp->networks = eigrp_topology_new();
 
        if ((eigrp_socket = eigrp_sock_init()) < 0) {
                zlog_err(
@@ -181,7 +181,7 @@ static struct eigrp *eigrp_new(const char *AS)
        thread_add_read(master, eigrp_read, eigrp, eigrp->fd, &eigrp->t_read);
        eigrp->oi_write_q = list_new();
 
-       eigrp->topology_table = eigrp_topology_new();
+       eigrp->topology_table = route_table_init();
 
        eigrp->neighbor_self = eigrp_nbr_new(NULL);
        eigrp->neighbor_self->src.s_addr = INADDR_ANY;
index 5ec6c8e1f75256f3a4f40db13b52834c1ab7c770..de7c881ac01556f5ff71487987397aa57aef2989 100644 (file)
@@ -41,6 +41,7 @@
 extern struct zclient *zclient;
 extern struct thread_master *master;
 extern struct eigrp_master *eigrp_om;
+extern struct zebra_privs_t eigrpd_privs;
 
 /* Prototypes */
 extern void eigrp_master_init(void);
index 2c8b12608818fd8435f1b3c320b7847553c9338a..591af3b8eddf3a3dbc813b948a79a95b6d2cf7ed 100644 (file)
@@ -45,8 +45,6 @@
 
 #include "privs.h"
 
-extern struct zebra_privs_t isisd_privs;
-
 struct bpf_insn llcfilter[] = {
        /* check first byte */
        BPF_STMT(BPF_LD + BPF_B + BPF_ABS, ETH_ALEN),
index 5e4090facc4be460ad8dde9bbaaf649b74552933..30679367c04df30af569d36be28161dd86b4fbc8 100644 (file)
@@ -676,7 +676,7 @@ int isis_circuit_up(struct isis_circuit *circuit)
 
        circuit->lsp_queue = list_new();
        circuit->lsp_hash = isis_lsp_hash_new();
-       monotime(&circuit->lsp_queue_last_cleared);
+       circuit->lsp_queue_last_push = monotime(NULL);
 
        return ISIS_OK;
 }
index 29694deb349584ccf6de0ab182566c5520f1472c..ac1e15f6bf6f16035b52621df0933a789855bb54 100644 (file)
@@ -84,7 +84,7 @@ struct isis_circuit {
        struct thread *t_send_lsp;
        struct list *lsp_queue; /* LSPs to be txed (both levels) */
        struct isis_lsp_hash *lsp_hash; /* Hashtable synchronized with lsp_queue */
-       struct timeval lsp_queue_last_cleared; /* timestamp used to enforce transmit
+       time_t lsp_queue_last_push;    /* timestamp used to enforce transmit
                                        * interval;
                                        * for scalability, use one timestamp per
                                        * circuit, instead of one per lsp per
index b7b5d35c2e6df30671caab0c452ed0a406a30f4c..1046b0014c4fee743c543412f4aee8a75143b9bf 100644 (file)
@@ -73,7 +73,7 @@
 #define MAX_MIN_LSP_GEN_INTERVAL      120  /* RFC 4444 says 65535 */
 #define DEFAULT_MIN_LSP_GEN_INTERVAL  30
 
-#define MIN_LSP_TRANS_INTERVAL        20000 /* Microseconds */
+#define MIN_LSP_RETRANS_INTERVAL      5 /* Seconds */
 
 #define MIN_CSNP_INTERVAL             1
 #define MAX_CSNP_INTERVAL             600
index 7ac8b54fa4499ae90aec370dcfcd2c91a64aa9ed..ccde4fbbe1022a9482515e37ffb4378ff57b7367 100644 (file)
@@ -47,8 +47,6 @@
 
 #include "privs.h"
 
-extern struct zebra_privs_t isisd_privs;
-
 static t_uscalar_t dlpi_ctl[1024]; /* DLPI control messages */
 
 /*
index 07579446aacfa70ad774f36db05d82fca75bdd45..ff9114c506a63131ba3d4c6c2467105eb0cefeeb 100644 (file)
@@ -454,17 +454,6 @@ void lsp_update(struct isis_lsp *lsp, struct isis_lsp_hdr *hdr,
                struct isis_tlvs *tlvs, struct stream *stream,
                struct isis_area *area, int level, bool confusion)
 {
-       dnode_t *dnode = NULL;
-
-       /* Remove old LSP from database. This is required since the
-        * lsp_update_data will free the lsp->pdu (which has the key, lsp_id)
-        * and will update it with the new data in the stream.
-        * XXX: This doesn't hold true anymore since the header is now a copy.
-        * keeping the LSP in the dict if it is already present should be possible */
-       dnode = dict_lookup(area->lspdb[level - 1], lsp->hdr.lsp_id);
-       if (dnode)
-               dnode_destroy(dict_delete(area->lspdb[level - 1], dnode));
-
        if (lsp->own_lsp) {
                zlog_err(
                        "ISIS-Upd (%s): BUG updating LSP %s still marked as own LSP",
@@ -490,8 +479,8 @@ void lsp_update(struct isis_lsp *lsp, struct isis_lsp_hdr *hdr,
                        lsp_link_fragment(lsp, lsp0);
        }
 
-       /* insert the lsp back into the database */
-       lsp_insert(lsp, area->lspdb[level - 1]);
+       if (lsp->hdr.seqno)
+               isis_spf_schedule(lsp->area, lsp->level);
 }
 
 /* creation of LSP directly from what we received */
@@ -1805,6 +1794,7 @@ int lsp_tick(struct thread *thread)
        dnode_t *dnode, *dnode_next;
        int level;
        u_int16_t rem_lifetime;
+        time_t now = monotime(NULL);
 
        lsp_list = list_new();
 
@@ -1883,12 +1873,13 @@ int lsp_tick(struct thread *thread)
                                        if (!circuit->lsp_queue)
                                                continue;
 
-                                       if (monotime_since(
-                                                 &circuit->lsp_queue_last_cleared,
-                                                 NULL) < MIN_LSP_TRANS_INTERVAL) {
+                                       if (now - circuit->lsp_queue_last_push
+                                           < MIN_LSP_RETRANS_INTERVAL) {
                                                continue;
                                        }
 
+                                       circuit->lsp_queue_last_push = now;
+
                                        for (ALL_LIST_ELEMENTS_RO(
                                                     lsp_list, lspnode, lsp)) {
                                                if (circuit->upadjcount
index 9c68fe5966090b611bb140d2cf391fa2eed7d1e9..2ea1fe0a5f08e4d41ab34c65a7aa17e01c774545 100644 (file)
@@ -2059,12 +2059,8 @@ int send_lsp(struct thread *thread)
        lsp = isis_circuit_lsp_queue_pop(circuit);
        if (!lsp)
                return ISIS_OK;
-       /* Set the last-cleared time if the queue is empty. */
-       /* TODO: Is is possible that new lsps keep being added to the queue
-        * that the queue is never empty? */
-       if (list_isempty(circuit->lsp_queue)) {
-               monotime(&circuit->lsp_queue_last_cleared);
-       } else {
+
+       if (!list_isempty(circuit->lsp_queue)) {
                isis_circuit_schedule_lsp_send(circuit);
        }
 
index e24901b0defeb03ef97d002b3acf864cab99c01a..974d2b78cf4f7d34219c11a101c72564b12d19d9 100644 (file)
@@ -44,8 +44,6 @@
 
 #include "privs.h"
 
-extern struct zebra_privs_t isisd_privs;
-
 /* tcpdump -i eth0 'isis' -dd */
 static struct sock_filter isisfilter[] =
        {
index 387f99938e07646d14c05f5260dd3490b9c1b814..c186dd56ad367cda2b922baa44ed70dca6d96c74 100644 (file)
@@ -412,7 +412,7 @@ static void isis_zebra_connected(struct zclient *zclient)
 void isis_zebra_init(struct thread_master *master)
 {
        zclient = zclient_new(master);
-       zclient_init(zclient, ZEBRA_ROUTE_ISIS, 0);
+       zclient_init(zclient, ZEBRA_ROUTE_ISIS, 0, &isisd_privs);
        zclient->zebra_connected = isis_zebra_connected;
        zclient->router_id_update = isis_router_id_update_zebra;
        zclient->interface_add = isis_zebra_if_add;
index 5dd348089dac4e4fb193ba7b11f7a21ce6cd2594..d4e5a4e29b59f98de0fad297a586ff6127c4fb14 100644 (file)
@@ -1509,7 +1509,7 @@ DEFUN_NOSH (router_isis,
        "router isis WORD",
        ROUTER_STR
        "ISO IS-IS\n"
-       "ISO Routing area tag")
+       "ISO Routing area tag\n")
 {
        int idx_word = 2;
        return isis_area_get(vty, argv[idx_word]->arg);
index a10748fd45284cf6bfaba88245b530ad677827e6..427d314df656ac2a72080365d55a0072cc850a04 100644 (file)
@@ -33,6 +33,8 @@
 #include "isis_memory.h"
 #include "qobj.h"
 
+extern struct zebra_privs_t isisd_privs;
+
 /* uncomment if you are a developer in bug hunt */
 /* #define EXTREME_DEBUG  */
 /* #define EXTREME_DICT_DEBUG */
index a7f933bbe56e597a4a98df2c99072c523d2c5fde..8122b88cca3b1186288c35bfd87dc9d54a78468f 100644 (file)
@@ -77,7 +77,7 @@ struct thread_master *master;
 /* lde privileges */
 static zebra_capabilities_t _caps_p [] =
 {
-       /* none */
+       ZCAP_NET_ADMIN
 };
 
 static struct zebra_privs_t lde_privs =
@@ -1622,6 +1622,8 @@ zclient_sync_init(u_short instance)
        zclient_sync->sock = -1;
        zclient_sync->redist_default = ZEBRA_ROUTE_LDP;
        zclient_sync->instance = instance;
+       zclient_sync->privs = &lde_privs;
+
        while (zclient_socket_connect(zclient_sync) < 0) {
                log_warnx("Error connecting synchronous zclient!");
                sleep(1);
index 7f68f0b69438df54476d70d56f4d24fa9027226f..8fe51cb9d18f03175bd98ae9bd0dcec2e01720b7 100644 (file)
@@ -507,12 +507,14 @@ ldp_zebra_connected(struct zclient *zclient)
            ZEBRA_ROUTE_ALL, 0, VRF_DEFAULT);
 }
 
+extern struct zebra_privs_t ldpd_privs;
+
 void
 ldp_zebra_init(struct thread_master *master)
 {
        /* Set default values. */
        zclient = zclient_new(master);
-       zclient_init(zclient, ZEBRA_ROUTE_LDP, 0);
+       zclient_init(zclient, ZEBRA_ROUTE_LDP, 0, &ldpd_privs);
 
        /* set callbacks */
        zclient->zebra_connected = ldp_zebra_connected;
index a7c4fe4f2f77a4997245722976fcead2118416cf..191fbf875a9ee13cfd470a615ed27a899fe658d2 100644 (file)
@@ -482,12 +482,14 @@ buffer_status_t buffer_write(struct buffer *b, int fd, const void *p,
        ssize_t nbytes;
 
 #if 0
-  /* Should we attempt to drain any previously buffered data?  This could help
-     reduce latency in pushing out the data if we are stuck in a long-running
-     thread that is preventing the main select loop from calling the flush
-     thread... */
-  if (b->head && (buffer_flush_available(b, fd) == BUFFER_ERROR))
-    return BUFFER_ERROR;
+       /*
+        * Should we attempt to drain any previously buffered data?
+        * This could help reduce latency in pushing out the data if
+        * we are stuck in a long-running thread that is preventing
+        * the main select loop from calling the flush thread...
+        */
+       if (b->head && (buffer_flush_available(b, fd) == BUFFER_ERROR))
+               return BUFFER_ERROR;
 #endif
        if (b->head)
                /* Buffer is not empty, so do not attempt to write the new data.
index 97eba96c3a7f0a50edf71479b00838d8057336ad..2e91d84bf3b304fdcf76340eea015b5c46376d0d 100644 (file)
@@ -1367,7 +1367,7 @@ DEFUN (config_quit,
 DEFUN (config_end,
        config_end_cmd,
        "end",
-       "End current mode and change to enable mode.")
+       "End current mode and change to enable mode.\n")
 {
        switch (vty->node) {
        case VIEW_NODE:
index f222279216a6f590fa6aeccd789d523cddcbac3c..4894b65affedf705d1eb6de797408c8378c5a326 100644 (file)
@@ -395,6 +395,7 @@ DEFUN_NOSH(show_hash_stats,
        pthread_mutex_lock(&_hashes_mtx);
        if (!_hashes) {
                pthread_mutex_unlock(&_hashes_mtx);
+               ttable_del(tt);
                vty_out(vty, "No hash tables in use.\n");
                return CMD_SUCCESS;
        }
index 320dfba4b5a5be695ce91217c496dbb73567fc01..0fe7da1c0d532dfa72ccff91539f49d83b3e22ae 100644 (file)
--- a/lib/if.c
+++ b/lib/if.c
@@ -194,7 +194,10 @@ void if_delete_retain(struct interface *ifp)
 /* Delete and free interface structure. */
 void if_delete(struct interface *ifp)
 {
-       struct vrf *vrf = vrf_lookup_by_id(ifp->vrf_id);
+       struct vrf *vrf;
+
+       vrf = vrf_lookup_by_id(ifp->vrf_id);
+       assert(vrf);
 
        IFNAME_RB_REMOVE(vrf, ifp);
        if (ifp->ifindex != IFINDEX_INTERNAL)
@@ -213,9 +216,13 @@ void if_delete(struct interface *ifp)
 /* Interface existance check by index. */
 struct interface *if_lookup_by_index(ifindex_t ifindex, vrf_id_t vrf_id)
 {
-       struct vrf *vrf = vrf_lookup_by_id(vrf_id);
+       struct vrf *vrf;
        struct interface if_tmp;
 
+       vrf = vrf_lookup_by_id(vrf_id);
+       if (!vrf)
+               return NULL;
+
        if_tmp.ifindex = ifindex;
        return RB_FIND(if_index_head, &vrf->ifaces_by_index, &if_tmp);
 }
@@ -244,7 +251,8 @@ struct interface *if_lookup_by_name(const char *name, vrf_id_t vrf_id)
        struct vrf *vrf = vrf_lookup_by_id(vrf_id);
        struct interface if_tmp;
 
-       if (!name || strnlen(name, INTERFACE_NAMSIZ) == INTERFACE_NAMSIZ)
+       if (!vrf || !name
+           || strnlen(name, INTERFACE_NAMSIZ) == INTERFACE_NAMSIZ)
                return NULL;
 
        strlcpy(if_tmp.name, name, sizeof(if_tmp.name));
@@ -388,7 +396,10 @@ struct interface *if_get_by_name(const char *name, vrf_id_t vrf_id, int vty)
 
 void if_set_index(struct interface *ifp, ifindex_t ifindex)
 {
-       struct vrf *vrf = vrf_lookup_by_id(ifp->vrf_id);
+       struct vrf *vrf;
+
+       vrf = vrf_lookup_by_id(ifp->vrf_id);
+       assert(vrf);
 
        if (ifp->ifindex == ifindex)
                return;
index 23a2d72b17a638097ecd66aa522f5f378141a1ec..bb2c17335429cd2866b474291d5cc0ed71f6eae7 100644 (file)
@@ -633,7 +633,7 @@ DEFUN (accept_lifetime_infinite_day_month,
        "Day of th month to start\n"
        "Month of the year to start\n"
        "Year to start\n"
-       "Never expires")
+       "Never expires\n")
 {
        int idx_hhmmss = 1;
        int idx_number = 2;
@@ -654,7 +654,7 @@ DEFUN (accept_lifetime_infinite_month_day,
        "Month of the year to start\n"
        "Day of th month to start\n"
        "Year to start\n"
-       "Never expires")
+       "Never expires\n")
 {
        int idx_hhmmss = 1;
        int idx_month = 2;
@@ -843,7 +843,7 @@ DEFUN (send_lifetime_infinite_day_month,
        "Day of th month to start\n"
        "Month of the year to start\n"
        "Year to start\n"
-       "Never expires")
+       "Never expires\n")
 {
        int idx_hhmmss = 1;
        int idx_number = 2;
@@ -864,7 +864,7 @@ DEFUN (send_lifetime_infinite_month_day,
        "Month of the year to start\n"
        "Day of th month to start\n"
        "Year to start\n"
-       "Never expires")
+       "Never expires\n")
 {
        int idx_hhmmss = 1;
        int idx_month = 2;
index 559ae37ffb09130928d014525ca1dc0d8acf157e..ab8d8be3e54e38ed3eedf49d3bf6d4dead1e43cb 100644 (file)
@@ -175,15 +175,11 @@ static int sockunion_sizeof(const union sockunion *su)
        return ret;
 }
 
-/* sockunion_connect returns
-   -1 : error occured
-   0 : connect success
-   1 : connect is in progress */
+/* Performs a non-blocking connect().  */
 enum connect_result sockunion_connect(int fd, const union sockunion *peersu,
                                      unsigned short port, ifindex_t ifindex)
 {
        int ret;
-       int val;
        union sockunion su;
 
        memcpy(&su, peersu, sizeof(union sockunion));
@@ -203,18 +199,12 @@ enum connect_result sockunion_connect(int fd, const union sockunion *peersu,
                break;
        }
 
-       /* Make socket non-block. */
-       val = fcntl(fd, F_GETFL, 0);
-       fcntl(fd, F_SETFL, val | O_NONBLOCK);
-
        /* Call connect function. */
        ret = connect(fd, (struct sockaddr *)&su, sockunion_sizeof(&su));
 
        /* Immediate success */
-       if (ret == 0) {
-               fcntl(fd, F_SETFL, val);
+       if (ret == 0)
                return connect_success;
-       }
 
        /* If connect is in progress then return 1 else it's real error. */
        if (ret < 0) {
@@ -227,8 +217,6 @@ enum connect_result sockunion_connect(int fd, const union sockunion *peersu,
                }
        }
 
-       fcntl(fd, F_SETFL, val);
-
        return connect_in_progress;
 }
 
index ad5c30584c122671e1032c4275b61ef8b480d1f7..d23e5fbd796ae77b1d5a868b6aba36eb6f8ddb81 100644 (file)
@@ -35,6 +35,7 @@
 #include "table.h"
 #include "nexthop.h"
 #include "mpls.h"
+#include "sockopt.h"
 
 DEFINE_MTYPE_STATIC(LIB, ZCLIENT, "Zclient")
 DEFINE_MTYPE_STATIC(LIB, REDIST_INST, "Redistribution instance IDs")
@@ -180,7 +181,8 @@ void zclient_reset(struct zclient *zclient)
                        &zclient->mi_redist[afi][zclient->redist_default],
                        zclient->instance);
 
-       zclient_init(zclient, zclient->redist_default, zclient->instance);
+       zclient_init(zclient, zclient->redist_default,
+                    zclient->instance, zclient->privs);
 }
 
 /**
@@ -202,6 +204,10 @@ int zclient_socket_connect(struct zclient *zclient)
 
        set_cloexec(sock);
 
+       zclient->privs->change(ZPRIVS_RAISE);
+       setsockopt_so_sendbuf(sock, 1048576);
+       zclient->privs->change(ZPRIVS_LOWER);
+
        /* Connect to zebra. */
        ret = connect(sock, (struct sockaddr *)&zclient_addr,
                        zclient_addr_len);
@@ -543,12 +549,14 @@ int zclient_start(struct zclient *zclient)
 
 /* Initialize zebra client.  Argument redist_default is unwanted
    redistribute route type. */
-void zclient_init(struct zclient *zclient, int redist_default, u_short instance)
+void zclient_init(struct zclient *zclient, int redist_default,
+                 u_short instance, struct zebra_privs_t *privs)
 {
        int afi, i;
 
        /* Set -1 to the default socket value. */
        zclient->sock = -1;
+       zclient->privs = privs;
 
        /* Clear redistribution flags. */
        for (afi = AFI_IP; afi < AFI_MAX; afi++)
index 288951eb1aff47de97a40daa7296bc2f964fc18e..23fe0e41f406a306f06900a4c6ed3381d003d4b7 100644 (file)
@@ -134,6 +134,9 @@ struct zclient {
        /* The thread master we schedule ourselves on */
        struct thread_master *master;
 
+       /* Priviledges to change socket values */
+       struct zebra_privs_t *privs;
+
        /* Socket to zebra daemon. */
        int sock;
 
@@ -315,7 +318,7 @@ struct zapi_pw_status {
 
 /* Prototypes of zebra client service functions. */
 extern struct zclient *zclient_new(struct thread_master *);
-extern void zclient_init(struct zclient *, int, u_short);
+extern void zclient_init(struct zclient *, int, u_short, struct zebra_privs_t *privs);
 extern int zclient_start(struct zclient *);
 extern void zclient_stop(struct zclient *);
 extern void zclient_reset(struct zclient *);
index 3a7186c1d799dfcce0d315d258d11087c8be530f..767907aa531f9099f5d7d20e2a3b8758c3080bf3 100644 (file)
@@ -43,7 +43,7 @@ static zebra_capabilities_t _caps_p [] = {
        ZCAP_DAC_OVERRIDE,      /* for now needed to write to /proc/sys/net/ipv4/<if>/send_redirect */
 };
 
-static struct zebra_privs_t nhrpd_privs = {
+struct zebra_privs_t nhrpd_privs = {
 #if defined(FRR_USER) && defined(FRR_GROUP)
        .user = FRR_USER,
        .group = FRR_GROUP,
index 495e226f1516c71ba7771f06341b4338d9ff9bf1..7701dcbb88eae5d3054c867aa1646e35b1822798 100644 (file)
@@ -325,7 +325,7 @@ void nhrp_zebra_init(void)
        zclient->redistribute_route_add = nhrp_route_read;
        zclient->redistribute_route_del = nhrp_route_read;
 
-       zclient_init(zclient, ZEBRA_ROUTE_NHRP, 0);
+       zclient_init(zclient, ZEBRA_ROUTE_NHRP, 0, &nhrpd_privs);
 }
 
 void nhrp_zebra_terminate(void)
index ab052ac04a141e4cf7156322cf2d3ea72db2fb87..e0d0268e41e08f7683db0b4f8603e36a7cfed542 100644 (file)
@@ -438,7 +438,7 @@ DEFUN(if_nhrp_mtu, if_nhrp_mtu_cmd,
        NHRP_STR
        "Configure NHRP advertised MTU\n"
        "MTU value\n"
-       "Advertise bound interface MTU similar to OpenNHRP")
+       "Advertise bound interface MTU similar to OpenNHRP\n")
 {
        VTY_DECLVAR_CONTEXT(interface, ifp);
        struct nhrp_interface *nifp = ifp->info;
@@ -461,7 +461,7 @@ DEFUN(if_no_nhrp_mtu, if_no_nhrp_mtu_cmd,
        NHRP_STR
        "Configure NHRP advertised MTU\n"
        "MTU value\n"
-       "Advertise bound interface MTU similar to OpenNHRP")
+       "Advertise bound interface MTU similar to OpenNHRP\n")
 {
        VTY_DECLVAR_CONTEXT(interface, ifp);
        struct nhrp_interface *nifp = ifp->info;
index 3071371969f4f4eca33b447c4938009a12c146c4..2ab40a4d39f117bcd54fec420b40bf57496f8e21 100644 (file)
@@ -303,6 +303,8 @@ struct nhrp_interface {
        } afi[AFI_MAX];
 };
 
+extern struct zebra_privs_t nhrpd_privs;
+
 int sock_open_unix(const char *path);
 
 void nhrp_interface_init(void);
index 4d9c25944384fbf8ad199d6c3ba35af632b82841..9f81bb89fba9138c5e05ff365ce84a3841dac289 100644 (file)
@@ -29,8 +29,7 @@
 #include "libospf.h"
 #include "ospf6_proto.h"
 #include "ospf6_network.h"
-
-extern struct zebra_privs_t ospf6d_privs;
+#include "ospf6d.h"
 
 int ospf6_sock;
 struct in6_addr allspfrouters6;
index b032bd7a791c7429d07706fd67d18a3cfd4d1ee2..022b913168b5b63f04bbebf8470a39226f208233 100644 (file)
@@ -584,7 +584,7 @@ void ospf6_zebra_init(struct thread_master *master)
 {
        /* Allocate zebra structure. */
        zclient = zclient_new(master);
-       zclient_init(zclient, ZEBRA_ROUTE_OSPF6, 0);
+       zclient_init(zclient, ZEBRA_ROUTE_OSPF6, 0, &ospf6d_privs);
        zclient->zebra_connected = ospf6_zebra_connected;
        zclient->router_id_update = ospf6_router_id_update_zebra;
        zclient->interface_add = ospf6_zebra_if_add;
index 77a40eac63f60a441cee57d604a7b909dd77ea8e..f95381084d0a93e0d06c4dcc8035aed7637aacf1 100644 (file)
@@ -94,6 +94,7 @@ extern struct thread_master *master;
                return CMD_SUCCESS;                                            \
        }
 
+extern struct zebra_privs_t ospf6d_privs;
 
 /* Function Prototypes */
 extern struct route_node *route_prev(struct route_node *node);
index 34a1e6f6d6a984f7919b89552c5a062cd34300f2..e8700e7eb062611385170dd92bd40582912a52d2 100644 (file)
@@ -453,6 +453,15 @@ struct ospf_interface *ospf_if_lookup_recv_if(struct ospf *ospf,
        return match;
 }
 
+static void ospf_if_reset_stats(struct ospf_interface *oi)
+{
+       oi->hello_in = oi->hello_out = 0;
+       oi->db_desc_in = oi->db_desc_out = 0;
+       oi->ls_req_in = oi->ls_req_out = 0;
+       oi->ls_upd_in = oi->ls_upd_out = 0;
+       oi->ls_ack_in = oi->ls_ack_out = 0;
+}
+
 void ospf_if_stream_set(struct ospf_interface *oi)
 {
        /* set output fifo queue. */
@@ -468,6 +477,9 @@ void ospf_if_stream_unset(struct ospf_interface *oi)
                ospf_fifo_free(oi->obuf);
                oi->obuf = NULL;
 
+               /*reset protocol stats */
+               ospf_if_reset_stats(oi);
+
                if (oi->on_write_q) {
                        listnode_delete(ospf->oi_write_q, oi);
                        if (list_isempty(ospf->oi_write_q))
index 74d5178f55cded09649b7552d6a2a41a38601788..4e6769405952f8723660785a80ad8395d914eb46 100644 (file)
@@ -284,12 +284,12 @@ const char *dump_lsa_key(struct ospf_lsa *lsa)
 
        if (lsa != NULL && (lsah = lsa->data) != NULL) {
                char id[INET_ADDRSTRLEN], ar[INET_ADDRSTRLEN];
-               strcpy(id, inet_ntoa(lsah->id));
-               strcpy(ar, inet_ntoa(lsah->adv_router));
+               strlcpy(id, inet_ntoa(lsah->id), sizeof(id));
+               strlcpy(ar, inet_ntoa(lsah->adv_router), sizeof(ar));
 
                sprintf(buf, "Type%d,id(%s),ar(%s)", lsah->type, id, ar);
        } else
-               strcpy(buf, "NULL");
+               strlcpy(buf, "NULL", sizeof(buf));
 
        return buf;
 }
@@ -2713,7 +2713,8 @@ struct ospf_lsa *ospf_lsa_install(struct ospf *ospf, struct ospf_interface *oi,
                                              new->data->type, NULL));
                        break;
                default:
-                       strcpy(area_str, inet_ntoa(new->area->area_id));
+                       strlcpy(area_str, inet_ntoa(new->area->area_id),
+                               sizeof(area_str));
                        zlog_debug("LSA[%s]: Install %s to Area %s",
                                   dump_lsa_key(new),
                                   lookup_msg(ospf_lsa_type_msg,
index 699f2341d5618755d065e441cf181c34aac66891..519e3f9cf4b24f6e878269bad63df3691e26b91a 100644 (file)
@@ -30,8 +30,6 @@
 #include "sockopt.h"
 #include "privs.h"
 
-extern struct zebra_privs_t ospfd_privs;
-
 #include "ospfd/ospfd.h"
 #include "ospfd/ospf_network.h"
 #include "ospfd/ospf_interface.h"
index 47f5ee76d22e9f5720f440b825f67710455dfc6f..633c3deeafd92166e847d57b879c0ea18c1928e0 100644 (file)
@@ -825,6 +825,26 @@ static int ospf_write(struct thread *thread)
                                        "-----------------------------------------------------");
                }
 
+               switch (type) {
+                       case OSPF_MSG_HELLO:
+                               oi->hello_out++;
+                               break;
+                       case OSPF_MSG_DB_DESC:
+                               oi->db_desc_out++;
+                               break;
+                       case OSPF_MSG_LS_REQ:
+                               oi->ls_req_out++;
+                               break;
+                       case OSPF_MSG_LS_UPD:
+                               oi->ls_upd_out++;
+                               break;
+                       case OSPF_MSG_LS_ACK:
+                               oi->ls_ack_out++;
+                               break;
+                       default:
+                               break;
+               }
+
                /* Now delete packet from queue. */
                ospf_packet_delete(oi);
 
index 69f688318654be787a66c784bbe3e2a65a934307..ead6923435399ac3018a97a108df0a0bdb6049a1 100644 (file)
@@ -1119,7 +1119,7 @@ DEFUN (router_info,
        OSPF_RI_STR
        "Enable the Router Information functionality with AS flooding scope\n"
        "Enable the Router Information functionality with Area flooding scope\n"
-       "OSPF area ID in IP format")
+       "OSPF area ID in IP format\n")
 {
        int idx_ipv4 = 2;
        char *area = (argc == 3) ? argv[idx_ipv4]->arg : NULL;
index b13e833afd9405cd9a293d5e24387f6ec3bbb64d..253b272df67f266367d7bded1de589ba9a6bfb31 100644 (file)
@@ -1252,7 +1252,7 @@ static int ospf_mpls_te_lsa_originate1(struct ospf_area *area,
 
        if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
                char area_id[INET_ADDRSTRLEN];
-               strcpy(area_id, inet_ntoa(area->area_id));
+               strlcpy(area_id, inet_ntoa(area->area_id), sizeof(area_id));
                zlog_debug(
                        "LSA[Type%d:%s]: Originate Opaque-LSA/MPLS-TE: Area(%s), Link(%s)",
                        new->data->type, inet_ntoa(new->data->id), area_id,
index 70e0da1158922996a0b1824ed937a31716bc7ca2..f349979d187537948ff0e0f430880b5a326d3d26 100644 (file)
@@ -3666,6 +3666,154 @@ static int show_ip_ospf_interface_common(struct vty *vty, struct ospf *ospf,
        return CMD_SUCCESS;
 }
 
+static void show_ip_ospf_interface_traffic_sub(struct vty *vty,
+                                              struct ospf_interface *oi,
+                                              json_object *json_interface_sub,
+                                              u_char use_json)
+{
+       if (use_json) {
+               json_object_int_add(json_interface_sub,
+                           "ifIndex",
+                           oi->ifp->ifindex);
+               json_object_int_add(json_interface_sub,
+                           "helloIn",
+                           oi->hello_in);
+               json_object_int_add(json_interface_sub,
+                           "helloOut",
+                           oi->hello_out);
+               json_object_int_add(json_interface_sub,
+                           "dbDescIn",
+                           oi->db_desc_in);
+               json_object_int_add(json_interface_sub,
+                           "dbDescOut",
+                           oi->db_desc_out);
+               json_object_int_add(json_interface_sub,
+                           "lsReqIn",
+                           oi->ls_req_in);
+               json_object_int_add(json_interface_sub,
+                           "lsReqOut",
+                           oi->ls_req_out);
+               json_object_int_add(json_interface_sub,
+                           "lsUpdIn",
+                           oi->ls_upd_in);
+               json_object_int_add(json_interface_sub,
+                           "lsUpdOut",
+                           oi->ls_upd_out);
+               json_object_int_add(json_interface_sub,
+                           "lsAckIn",
+                           oi->ls_ack_in);
+               json_object_int_add(json_interface_sub,
+                           "lsAckOut",
+                           oi->ls_ack_out);
+       } else {
+               vty_out(vty,
+                       "%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u\n",
+                       oi->ifp->name, oi->hello_in,
+                       oi->hello_out,
+                       oi->db_desc_in, oi->db_desc_out,
+                       oi->ls_req_in, oi->ls_req_out,
+                       oi->ls_upd_in, oi->ls_upd_out,
+                       oi->ls_ack_in, oi->ls_ack_out);
+       }
+}
+
+/* OSPFv2 Packet Counters */
+static int show_ip_ospf_interface_traffic_common(struct vty *vty,
+                                                struct ospf *ospf,
+                                                char *intf_name,
+                                                int display_once,
+                                                u_char use_json)
+{
+       struct vrf *vrf = NULL;
+       struct interface *ifp = NULL;
+       json_object *json = NULL;
+       json_object *json_interface_sub = NULL;
+
+       if (!use_json && !display_once) {
+               vty_out(vty, "\n");
+               vty_out(vty, "%-12s%-17s%-17s%-17s%-17s%-17s\n",
+                       "Interface", "    HELLO", "    DB-Desc", "   LS-Req",
+                       "   LS-Update", "   LS-Ack");
+               vty_out(vty, "%-10s%-18s%-18s%-17s%-17s%-17s\n", "",
+                       "      Rx/Tx", "     Rx/Tx", "    Rx/Tx", "    Rx/Tx", "    Rx/Tx");
+               vty_out(vty,
+               "--------------------------------------------------------------------------------------------\n");
+       } else if (use_json) {
+               json = json_object_new_object();
+       }
+
+       if (intf_name == NULL) {
+               vrf = vrf_lookup_by_id(ospf->vrf_id);
+               FOR_ALL_INTERFACES (vrf, ifp) {
+                       struct route_node *rn;
+                       struct ospf_interface *oi;
+
+                       if (ospf_oi_count(ifp) == 0)
+                               continue;
+
+                       for (rn = route_top(IF_OIFS(ifp)); rn;
+                               rn = route_next(rn)) {
+                               oi = rn->info;
+
+                               if (oi == NULL)
+                                       continue;
+
+                               if (use_json) {
+                                       json_interface_sub =
+                                               json_object_new_object();
+                               }
+
+                               show_ip_ospf_interface_traffic_sub(vty, oi,
+                                                          json_interface_sub,
+                                                          use_json);
+                               if (use_json) {
+                                       json_object_object_add(json, ifp->name,
+                                               json_interface_sub);
+                               }
+                       }
+               }
+       } else {
+               /* Interface name is specified. */
+               ifp = if_lookup_by_name(intf_name, ospf->vrf_id);
+               if (ifp != NULL) {
+                       struct route_node *rn;
+                       struct ospf_interface *oi;
+
+                       if (ospf_oi_count(ifp) == 0) {
+                               vty_out(vty, "  OSPF not enabled on this interface %s\n",
+                                       ifp->name);
+                               return CMD_SUCCESS;
+                       }
+
+                       for (rn = route_top(IF_OIFS(ifp)); rn;
+                            rn = route_next(rn)) {
+                               oi = rn->info;
+
+                               if (use_json) {
+                                       json_interface_sub =
+                                               json_object_new_object();
+                               }
+
+                               show_ip_ospf_interface_traffic_sub(vty, oi,
+                                                          json_interface_sub,
+                                                          use_json);
+                               if (use_json) {
+                                       json_object_object_add(json, ifp->name,
+                                               json_interface_sub);
+                               }
+                       }
+               }
+       }
+
+       if (use_json) {
+               vty_out(vty, "%s\n", json_object_to_json_string_ext(
+                                            json, JSON_C_TO_STRING_PRETTY));
+               json_object_free(json);
+       }
+
+       return CMD_SUCCESS;
+}
+
 DEFUN (show_ip_ospf_interface,
        show_ip_ospf_interface_cmd,
        "show ip ospf [vrf <NAME|all>] interface [INTERFACE] [json]",
@@ -3753,6 +3901,71 @@ DEFUN (show_ip_ospf_instance_interface,
        return show_ip_ospf_interface_common(vty, ospf, argc, argv, 5, uj);
 }
 
+DEFUN (show_ip_ospf_interface_traffic,
+       show_ip_ospf_interface_traffic_cmd,
+       "show ip ospf [vrf <NAME|all>] interface traffic [INTERFACE] [json]",
+       SHOW_STR
+       IP_STR
+       "OSPF information\n"
+       VRF_CMD_HELP_STR
+       "All VRFs\n"
+       "Interface information\n"
+       "Protocol Packet counters\n"
+       "Interface name\n"
+       JSON_STR)
+{
+       struct ospf *ospf = NULL;
+       struct listnode *node = NULL;
+       char *vrf_name = NULL, *intf_name = NULL;
+       bool all_vrf = FALSE;
+       int inst = 0;
+       int idx_vrf = 0, idx_intf = 0;
+       u_char uj = use_json(argc, argv);
+       int ret = CMD_SUCCESS;
+       int display_once = 0;
+
+       if (uj)
+               argc--;
+
+
+       OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
+
+       if (argv_find(argv, argc, "INTERFACE", &idx_intf))
+               intf_name = argv[idx_intf]->arg;
+
+       if (vrf_name) {
+               if (all_vrf) {
+                       for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+                               if (!ospf->oi_running)
+                                       continue;
+
+                               ret = show_ip_ospf_interface_traffic_common(vty,
+                                                               ospf, intf_name,
+                                                               display_once,
+                                                               uj);
+                               display_once = 1;
+                       }
+                       return ret;
+               }
+               ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+               if (ospf == NULL || !ospf->oi_running)
+                       return CMD_SUCCESS;
+               ret = show_ip_ospf_interface_traffic_common(vty, ospf,
+                                                           intf_name,
+                                                           display_once, uj);
+       } else {
+               ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+               if (ospf == NULL || !ospf->oi_running)
+                       return CMD_SUCCESS;
+               ret = show_ip_ospf_interface_traffic_common(vty, ospf,
+                                                           intf_name,
+                                                           display_once, uj);
+       }
+
+       return ret;
+}
+
+
 static void show_ip_ospf_neighbour_header(struct vty *vty)
 {
        vty_out(vty, "\n%-15s %3s %-15s %9s %-15s %-20s %5s %5s %5s\n",
@@ -6030,7 +6243,7 @@ DEFUN (ip_ospf_authentication,
        "IP Information\n"
        "OSPF interface commands\n"
        "Enable authentication on this interface\n"
-       "Address of interface")
+       "Address of interface\n")
 {
        VTY_DECLVAR_CONTEXT(interface, ifp);
        int idx_ipv4 = 3;
@@ -6067,7 +6280,7 @@ DEFUN (no_ip_ospf_authentication_args,
        "Enable authentication on this interface\n"
        "Use null authentication\n"
        "Use message-digest authentication\n"
-       "Address of interface")
+       "Address of interface\n")
 {
        VTY_DECLVAR_CONTEXT(interface, ifp);
        int idx_encryption = 4;
@@ -6147,7 +6360,7 @@ DEFUN (no_ip_ospf_authentication,
        "IP Information\n"
        "OSPF interface commands\n"
        "Enable authentication on this interface\n"
-       "Address of interface")
+       "Address of interface\n")
 {
        VTY_DECLVAR_CONTEXT(interface, ifp);
        int idx_ipv4 = 4;
@@ -6224,7 +6437,7 @@ DEFUN (ip_ospf_authentication_key,
        "OSPF interface commands\n"
        "Authentication password (key)\n"
        "The OSPF password (key)\n"
-       "Address of interface")
+       "Address of interface\n")
 {
        VTY_DECLVAR_CONTEXT(interface, ifp);
        int idx = 0;
@@ -6436,7 +6649,9 @@ DEFUN_HIDDEN (no_ospf_message_digest_key,
               "OSPF interface commands\n"
               "Message digest authentication password (key)\n"
               "Key ID\n"
-              "Address of interface")
+              "Use MD5 algorithm\n"
+              "The OSPF password (key)\n"
+              "Address of interface\n")
 {
        return no_ip_ospf_message_digest_key(self, vty, argc, argv);
 }
@@ -6499,9 +6714,11 @@ DEFUN (no_ip_ospf_cost,
        no_ip_ospf_cost_cmd,
        "no ip ospf cost [(1-65535)] [A.B.C.D]",
        NO_STR
+       "IP Information\n"
        "OSPF interface commands\n"
        "Interface cost\n"
-       "Address of interface")
+       "Cost\n"
+       "Address of interface\n")
 {
        VTY_DECLVAR_CONTEXT(interface, ifp);
        int idx = 0;
@@ -6694,7 +6911,10 @@ DEFUN (no_ip_ospf_dead_interval,
        "OSPF interface commands\n"
        "Interval time after which a neighbor is declared down\n"
        "Seconds\n"
-       "Address of interface")
+       "Minimal 1s dead-interval with fast sub-second hellos\n"
+       "Hello multiplier factor\n"
+       "Number of Hellos to send each second\n"
+       "Address of interface\n")
 {
        VTY_DECLVAR_CONTEXT(interface, ifp);
        int idx_ipv4 = argc - 1;
@@ -6756,7 +6976,10 @@ DEFUN_HIDDEN (no_ospf_dead_interval,
               "OSPF interface commands\n"
               "Interval time after which a neighbor is declared down\n"
               "Seconds\n"
-              "Address of interface")
+              "Minimal 1s dead-interval with fast sub-second hellos\n"
+              "Hello multiplier factor\n"
+              "Number of Hellos to send each second\n"
+              "Address of interface\n")
 {
        return no_ip_ospf_dead_interval(self, vty, argc, argv);
 }
@@ -6985,7 +7208,7 @@ DEFUN (ip_ospf_priority,
        "OSPF interface commands\n"
        "Router priority\n"
        "Priority\n"
-       "Address of interface")
+       "Address of interface\n")
 {
        VTY_DECLVAR_CONTEXT(interface, ifp);
        int idx = 0;
@@ -7033,7 +7256,7 @@ DEFUN_HIDDEN (ospf_priority,
               "OSPF interface commands\n"
               "Router priority\n"
               "Priority\n"
-              "Address of interface")
+              "Address of interface\n")
 {
        return ip_ospf_priority(self, vty, argc, argv);
 }
@@ -7046,7 +7269,7 @@ DEFUN (no_ip_ospf_priority,
        "OSPF interface commands\n"
        "Router priority\n" // ignored
        "Priority\n"
-       "Address of interface")
+       "Address of interface\n")
 {
        VTY_DECLVAR_CONTEXT(interface, ifp);
        int idx = 0;
@@ -7098,7 +7321,7 @@ DEFUN_HIDDEN (no_ospf_priority,
               "OSPF interface commands\n"
               "Router priority\n"
               "Priority\n"
-              "Address of interface")
+              "Address of interface\n")
 {
        return no_ip_ospf_priority(self, vty, argc, argv);
 }
@@ -7110,7 +7333,7 @@ DEFUN (ip_ospf_retransmit_interval,
        "OSPF interface commands\n"
        "Time between retransmitting lost link state advertisements\n"
        "Seconds\n"
-       "Address of interface")
+       "Address of interface\n")
 {
        VTY_DECLVAR_CONTEXT(interface, ifp);
        int idx = 0;
@@ -7145,7 +7368,7 @@ DEFUN_HIDDEN (ospf_retransmit_interval,
               "OSPF interface commands\n"
               "Time between retransmitting lost link state advertisements\n"
               "Seconds\n"
-              "Address of interface")
+              "Address of interface\n")
 {
        return ip_ospf_retransmit_interval(self, vty, argc, argv);
 }
@@ -7209,7 +7432,7 @@ DEFUN (ip_ospf_transmit_delay,
        "OSPF interface commands\n"
        "Link state transmit delay\n"
        "Seconds\n"
-       "Address of interface")
+       "Address of interface\n")
 {
        VTY_DECLVAR_CONTEXT(interface, ifp);
        int idx = 0;
@@ -7244,7 +7467,7 @@ DEFUN_HIDDEN (ospf_transmit_delay,
               "OSPF interface commands\n"
               "Link state transmit delay\n"
               "Seconds\n"
-              "Address of interface")
+              "Address of interface\n")
 {
        return ip_ospf_transmit_delay(self, vty, argc, argv);
 }
@@ -7256,7 +7479,8 @@ DEFUN (no_ip_ospf_transmit_delay,
        "IP Information\n"
        "OSPF interface commands\n"
        "Link state transmit delay\n"
-       "Address of interface")
+       "Seconds\n"
+       "Address of interface\n")
 {
        VTY_DECLVAR_CONTEXT(interface, ifp);
        int idx = 0;
@@ -7296,7 +7520,7 @@ DEFUN_HIDDEN (no_ospf_transmit_delay,
               "OSPF interface commands\n"
               "Link state transmit delay\n"
               "Seconds\n"
-              "Address of interface")
+              "Address of interface\n")
 {
        return no_ip_ospf_transmit_delay(self, vty, argc, argv);
 }
@@ -7990,7 +8214,7 @@ DEFUN (ip_ospf_mtu_ignore,
        "IP Information\n"
        "OSPF interface commands\n"
        "Disable MTU mismatch detection on this interface\n"
-       "Address of interface")
+       "Address of interface\n")
 {
        VTY_DECLVAR_CONTEXT(interface, ifp);
        int idx_ipv4 = 3;
@@ -8026,10 +8250,11 @@ DEFUN (ip_ospf_mtu_ignore,
 DEFUN (no_ip_ospf_mtu_ignore,
        no_ip_ospf_mtu_ignore_addr_cmd,
        "no ip ospf mtu-ignore [A.B.C.D]",
+       NO_STR
        "IP Information\n"
        "OSPF interface commands\n"
        "Disable MTU mismatch detection on this interface\n"
-       "Address of interface")
+       "Address of interface\n")
 {
        VTY_DECLVAR_CONTEXT(interface, ifp);
        int idx_ipv4 = 4;
@@ -9484,6 +9709,8 @@ void ospf_vty_show_init(void)
        install_element(VIEW_NODE, &show_ip_ospf_interface_cmd);
 
        install_element(VIEW_NODE, &show_ip_ospf_instance_interface_cmd);
+       /* "show ip ospf interface traffic */
+       install_element(VIEW_NODE, &show_ip_ospf_interface_traffic_cmd);
 
        /* "show ip ospf neighbor" commands. */
        install_element(VIEW_NODE, &show_ip_ospf_neighbor_int_detail_cmd);
index 7e6146e0d38043664e833385ffe1c9b524a784df..76fa6fa6dd76980b34d7658c5b4838a2fa08ccc0 100644 (file)
@@ -1472,7 +1472,7 @@ void ospf_zebra_init(struct thread_master *master, u_short instance)
 {
        /* Allocate zebra structure. */
        zclient = zclient_new(master);
-       zclient_init(zclient, ZEBRA_ROUTE_OSPF, instance);
+       zclient_init(zclient, ZEBRA_ROUTE_OSPF, instance, &ospfd_privs);
        zclient->zebra_connected = ospf_zebra_connected;
        zclient->router_id_update = ospf_router_id_update_zebra;
        zclient->interface_add = ospf_interface_add;
index 8ee32289c175dc20a3361f3452e35b4d5c99f6a8..3771f946309d3073eafbb13741859e1fab0245f9 100644 (file)
@@ -67,7 +67,6 @@ struct ospf_master *om;
 
 extern struct zclient *zclient;
 extern struct in_addr router_id_zebra;
-extern struct zebra_privs_t ospfd_privs;
 
 
 static void ospf_remove_vls_through_area(struct ospf *, struct ospf_area *);
index 4b0ebc8eb84d63d0d77ad30dff8b88d065b48e09..4c5bb756f6e759731f33af69e76a785e294af44c 100644 (file)
@@ -502,6 +502,7 @@ extern const int ospf_redistributed_proto_max;
 extern struct zclient *zclient;
 extern struct thread_master *master;
 extern int ospf_zlog;
+extern struct zebra_privs_t ospfd_privs;
 
 /* Prototypes. */
 extern const char *ospf_redist_string(u_int route_type);
index db11e5f17119c5072aa91e2fe3301d671a824531..8c90ccbed16cd51c658457435bdab6097a0c57c4 100644 (file)
@@ -753,7 +753,7 @@ void pim_zebra_init(void)
        zclient->interface_address_delete = pim_zebra_if_address_del;
        zclient->nexthop_update = pim_parse_nexthop_update;
 
-       zclient_init(zclient, ZEBRA_ROUTE_PIM, 0);
+       zclient_init(zclient, ZEBRA_ROUTE_PIM, 0, &pimd_privs);
        if (PIM_DEBUG_PIM_TRACE) {
                zlog_info("zclient_init cleared redistribution request");
        }
index df8ad4e428c1a5e0789f9cd61018a5f3e54d6206..fd75a699b3bbdcddaeb531acdc4b6de999bf8ce8 100644 (file)
@@ -128,6 +128,7 @@ void zclient_lookup_new(void)
 
        zlookup->sock = -1;
        zlookup->t_connect = NULL;
+       zlookup->privs = &pimd_privs;
 
        zclient_lookup_sched_now(zlookup);
 
index 9282896c2845db2b1ffe77127033168d79069658..a997ca5f2e5f119548198ad4b54f94a152bf1fa1 100644 (file)
@@ -58,8 +58,6 @@ const struct message ri_version_msg[] = {{RI_RIP_VERSION_1, "1"},
                                         {RI_RIP_VERSION_NONE, "none"},
                                         {0}};
 
-extern struct zebra_privs_t ripd_privs;
-
 /* RIP enabled network vector. */
 vector rip_enable_interface;
 
index 28144a24351dd2aaf83233d949fb8e14f9bb22ea..3772f6223e66e7258b4cf42f0710ba3354dbf7a8 100644 (file)
@@ -586,7 +586,7 @@ void rip_zclient_init(struct thread_master *master)
 {
        /* Set default value to the zebra client structure. */
        zclient = zclient_new(master);
-       zclient_init(zclient, ZEBRA_ROUTE_RIP, 0);
+       zclient_init(zclient, ZEBRA_ROUTE_RIP, 0, &ripd_privs);
        zclient->zebra_connected = rip_zebra_connected;
        zclient->interface_add = rip_interface_add;
        zclient->interface_delete = rip_interface_delete;
index a4b56d9fbf40d645ac95665d5226d5f51e202988..aece5d03cd6aba8dcfb63e012e1c9e1c19f67287 100644 (file)
@@ -49,9 +49,6 @@ DEFINE_QOBJ_TYPE(rip)
 /* UDP receive buffer size */
 #define RIP_UDP_RCV_BUF 41600
 
-/* privileges global */
-extern struct zebra_privs_t ripd_privs;
-
 /* RIP Structure. */
 struct rip *rip = NULL;
 
index 895a48c3db920c9e03758743558f01dd78158323..ae34ed3f48124c1108809471b54bbf78367687c5 100644 (file)
@@ -427,6 +427,8 @@ extern struct rip_info *rip_ecmp_delete(struct rip_info *);
 /* There is only one rip strucutre. */
 extern struct rip *rip;
 
+extern struct zebra_privs_t ripd_privs;
+
 /* Master thread strucutre. */
 extern struct thread_master *master;
 
index d450d5a7f9806af2ebba4f0e31afdd2d51ae8055..d1057bf53e219eb715f01bcac5b665ca0802ee67 100644 (file)
@@ -47,8 +47,6 @@
 #define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP 
 #endif
 
-extern struct zebra_privs_t ripngd_privs;
-
 /* Static utility function. */
 static void ripng_enable_apply(struct interface *);
 static void ripng_passive_interface_apply(struct interface *);
index 7edaaa5dff6d165371f079412130c9da5e6f4167..084d58ee53927c3e3d9e2b510f1ed1cd51a6e56c 100644 (file)
@@ -414,7 +414,7 @@ void zebra_init(struct thread_master *master)
 {
        /* Allocate zebra structure. */
        zclient = zclient_new(master);
-       zclient_init(zclient, ZEBRA_ROUTE_RIPNG, 0);
+       zclient_init(zclient, ZEBRA_ROUTE_RIPNG, 0, &ripngd_privs);
 
        zclient->zebra_connected = ripng_zebra_connected;
        zclient->interface_up = ripng_interface_up;
index df3af2a17f3649c88d0d1761e71147b755d9d1ce..673f0637c79cfc83fa0c3dd96a74ce8f4e8053d6 100644 (file)
@@ -50,8 +50,6 @@ enum { ripng_all_route,
        ripng_changed_route,
 };
 
-extern struct zebra_privs_t ripngd_privs;
-
 /* Prototypes. */
 void ripng_output_process(struct interface *, struct sockaddr_in6 *, int);
 
@@ -103,21 +101,21 @@ static int ripng_make_socket(void)
        setsockopt_so_recvbuf(sock, 8096);
        ret = setsockopt_ipv6_pktinfo(sock, 1);
        if (ret < 0)
-               return ret;
+               goto error;
 #ifdef IPTOS_PREC_INTERNETCONTROL
        ret = setsockopt_ipv6_tclass(sock, IPTOS_PREC_INTERNETCONTROL);
        if (ret < 0)
-               return ret;
+               goto error;
 #endif
        ret = setsockopt_ipv6_multicast_hops(sock, 255);
        if (ret < 0)
-               return ret;
+               goto error;
        ret = setsockopt_ipv6_multicast_loop(sock, 0);
        if (ret < 0)
-               return ret;
+               goto error;
        ret = setsockopt_ipv6_hoplimit(sock, 1);
        if (ret < 0)
-               return ret;
+               goto error;
 
        memset(&ripaddr, 0, sizeof(ripaddr));
        ripaddr.sin6_family = AF_INET6;
@@ -134,11 +132,15 @@ static int ripng_make_socket(void)
                zlog_err("Can't bind ripng socket: %s.", safe_strerror(errno));
                if (ripngd_privs.change(ZPRIVS_LOWER))
                        zlog_err("ripng_make_socket: could not lower privs");
-               return ret;
+               goto error;
        }
        if (ripngd_privs.change(ZPRIVS_LOWER))
                zlog_err("ripng_make_socket: could not lower privs");
        return sock;
+
+error:
+       close(sock);
+       return ret;
 }
 
 /* Send RIPng packet. */
index 9a609cab8a899083767aee325bf6e720c8a8af5e..25a5b46c02e49774bab9178b994d75bc595a97ab 100644 (file)
@@ -327,7 +327,7 @@ enum ripng_event {
 
 /* Extern variables. */
 extern struct ripng *ripng;
-
+extern struct zebra_privs_t ripngd_privs;
 extern struct thread_master *master;
 
 /* Prototypes. */
index 1f5abba392803a1b020975434d21740fca297438..67a1593500b96ef92e41aef9cfcdf5948909dc47 100644 (file)
@@ -19,6 +19,8 @@ int isis_sock_init(struct isis_circuit *circuit)
        return 0;
 }
 
+struct zebra_privs_t isisd_privs;
+
 static bool atexit_registered;
 
 static void show_meminfo_at_exit(void)
index 674482cd17dcf2cbf8d60755a82efce5bb5629f5..0e473d7a6b4d86f7e021b0b763139761b3bcaa4e 100644 (file)
@@ -9,6 +9,8 @@ int isis_sock_init(struct isis_circuit *circuit)
        return 0;
 }
 
+struct zebra_privs_t isisd_privs;
+
 static struct isis_vertex **vertices;
 static size_t vertex_count;
 
index 30dc6484ae181a96b07054394a71cd40e9d763d7..8dc16f420922be9ebca533e846393a1720350423 100644 (file)
@@ -538,10 +538,7 @@ static void parse_options(int argc, char *const *argv)
                        execname = optarg;
                        break;
                case 'c': /* --chuid <username>|<uid> */
-                       /* we copy the string just in case we need the
-                        * argument later. */
-                       changeuser = strdup(optarg);
-                       changeuser = strtok(changeuser, ":");
+                       changeuser = strtok(optarg, ":");
                        changegroup = strtok(NULL, ":");
                        break;
                case 'r': /* --chroot /new/root */
index 061c25cea5f5a74cb1c7b7a40bac80590d4a864c..72a15f24ddb16c1147d147f710e83dcf6cf0820c 100644 (file)
@@ -573,6 +573,7 @@ int vtysh_mark_file(const char *filename)
                 * appropriate */
                if (strlen(vty_buf_trimmed) == 3
                    && strncmp("end", vty_buf_trimmed, 3) == 0) {
+                       cmd_free_strvec(vline);
                        continue;
                }
 
@@ -804,20 +805,22 @@ static int vtysh_rl_describe(void)
        } else if (rl_end && isspace((int)rl_line_buffer[rl_end - 1]))
                vector_set(vline, NULL);
 
-       describe = cmd_describe_command(vline, vty, &ret);
-
        fprintf(stdout, "\n");
 
+       describe = cmd_describe_command(vline, vty, &ret);
+
        /* Ambiguous and no match error. */
        switch (ret) {
        case CMD_ERR_AMBIGUOUS:
                cmd_free_strvec(vline);
+               vector_free(describe);
                fprintf(stdout, "%% Ambiguous command.\n");
                rl_on_new_line();
                return 0;
                break;
        case CMD_ERR_NO_MATCH:
                cmd_free_strvec(vline);
+               vector_free(describe);
                fprintf(stdout, "%% There is no matched command.\n");
                rl_on_new_line();
                return 0;
index 8509a8a05ab06ef67bf0d97c9a691211e2882bb5..57042f8e620949a788f2ec65ccbe446d9861bcc4 100644 (file)
@@ -533,7 +533,7 @@ int main(int argc, char **argv, char **env)
 
                        fp = open(history_file, O_CREAT | O_EXCL,
                                  S_IRUSR | S_IWUSR);
-                       if (fp)
+                       if (fp != -1)
                                close(fp);
 
                        read_history(history_file);
index ac96051abd8505b7101b94794aa91be4e9158494..1df547a0230e5a9081daa54d43c9144dfa2acbfa 100644 (file)
@@ -138,7 +138,7 @@ DEFUN (debug_zebra_vxlan,
 DEFUN (debug_zebra_pw,
        debug_zebra_pw_cmd,
        "[no] debug zebra pseudowires",
-       "Negate a command or set its defaults\n"
+       NO_STR
        DEBUG_STR
        "Zebra configuration\n"
        "Debug option set for zebra pseudowires\n")
index e912b2dcf8473b8164209e1579c58602daaf418c..dd1050ee7f066659b91e5ee2d52bada7ad6698af 100644 (file)
@@ -2539,7 +2539,7 @@ DEFUN (no_ip_address,
        NO_STR
        "Interface Internet Protocol config commands\n"
        "Set the IP address of an interface\n"
-       "IP Address (e.g. 10.0.0.1/8)")
+       "IP Address (e.g. 10.0.0.1/8)\n")
 {
        int idx_ipv4_prefixlen = 3;
        VTY_DECLVAR_CONTEXT(interface, ifp);
index 0cc2e0217f29c7dc594f31a329bf76803994b98a..c9a6335277ba48fe24dc366eac9de979bb64766a 100644 (file)
@@ -2370,7 +2370,6 @@ int netlink_mpls_multipath(int cmd, zebra_lsp_t *lsp)
 
        memset(&req, 0, sizeof req - NL_PKT_BUF_SIZE);
 
-
        /*
         * Count # nexthops so we can decide whether to use singlepath
         * or multipath case.
@@ -2394,11 +2393,9 @@ int netlink_mpls_multipath(int cmd, zebra_lsp_t *lsp)
                }
        }
 
-       if (nexthop_num == 0 || !lsp->best_nhlfe) // unexpected
+       if ((nexthop_num == 0) || (!lsp->best_nhlfe && (cmd != RTM_DELROUTE)))
                return 0;
 
-       route_type = re_type_from_lsp_type(lsp->best_nhlfe->type);
-
        req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
        req.n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST;
        req.n.nlmsg_type = cmd;
@@ -2407,14 +2404,18 @@ int netlink_mpls_multipath(int cmd, zebra_lsp_t *lsp)
        req.r.rtm_family = AF_MPLS;
        req.r.rtm_table = RT_TABLE_MAIN;
        req.r.rtm_dst_len = MPLS_LABEL_LEN_BITS;
-       req.r.rtm_protocol = zebra2proto(route_type);
        req.r.rtm_scope = RT_SCOPE_UNIVERSE;
        req.r.rtm_type = RTN_UNICAST;
 
-       if (cmd == RTM_NEWROUTE)
+       if (cmd == RTM_NEWROUTE) {
                /* We do a replace to handle update. */
                req.n.nlmsg_flags |= NLM_F_REPLACE;
 
+               /* set the protocol value if installing */
+               route_type = re_type_from_lsp_type(lsp->best_nhlfe->type);
+               req.r.rtm_protocol = zebra2proto(route_type);
+       }
+
        /* Fill destination */
        lse = mpls_lse_encode(lsp->ile.in_label, 0, 0, 1);
        addattr_l(&req.n, sizeof req, RTA_DST, &lse, sizeof(mpls_lse_t));
index 6a8e2ac594e2ac86fd134e9bb5c1a2281f697b7d..a1e1602bf833b6b4fbe9ded39500d0cb86279dec 100644 (file)
@@ -675,6 +675,7 @@ static int rtadv_make_socket(void)
                         sizeof(struct icmp6_filter));
        if (ret < 0) {
                zlog_info("ICMP6_FILTER set fail: %s", safe_strerror(errno));
+               close(sock);
                return ret;
        }
 
@@ -799,7 +800,7 @@ static void ipv6_nd_suppress_ra_set(struct interface *ifp,
  * if the operator has explicitly enabled RA. The enable request can also
  * specify a RA interval (in seconds).
  */
-void zebra_interface_radv_set(struct zserv *client, int sock, u_short length,
+void zebra_interface_radv_set(struct zserv *client, u_short length,
                              struct zebra_vrf *zvrf, int enable)
 {
        struct stream *s;
index dcaeb3ed28bf1e359add90fc355f670f10ec645a..9ec1bffa8deaa9e649a1cc4f6911a5459e1e2bbc 100644 (file)
@@ -103,7 +103,7 @@ typedef enum {
 extern void rtadv_init(struct zebra_ns *);
 extern void rtadv_terminate(struct zebra_ns *);
 extern void rtadv_cmd_init(void);
-extern void zebra_interface_radv_set(struct zserv *client, int sock,
+extern void zebra_interface_radv_set(struct zserv *client,
                                     u_short length, struct zebra_vrf *zvrf,
                                     int enable);
 
index 75d5d5d6276c0167a06e9ad2a473751237301215..8fa00b83c9343e311d5bc814593a827b96436974 100644 (file)
@@ -32,7 +32,7 @@
 #include "zebra/rt.h"
 #include "zebra/debug.h"
 
-int zebra_ipmr_route_stats(struct zserv *client, int fd, u_short length,
+int zebra_ipmr_route_stats(struct zserv *client, u_short length,
                           struct zebra_vrf *zvrf)
 {
        struct mcast_route_data mroute;
index fda97e80d74704a78e934f6fee021bff7fb5e3c1..616c3a83ab54c27227daf5e4c6ccfe5d47dc0898 100644 (file)
@@ -28,7 +28,7 @@ struct mcast_route_data {
        unsigned long long lastused;
 };
 
-int zebra_ipmr_route_stats(struct zserv *client, int sock, u_short length,
+int zebra_ipmr_route_stats(struct zserv *client, u_short length,
                           struct zebra_vrf *zvf);
 
 #endif
index 93b0723d8b8f235de6805db9ef50b87fcbcc5f2c..464a8cf875f2f9844c13fcd223befe1573b00d71 100644 (file)
@@ -661,7 +661,7 @@ int zebra_ptm_sock_read(struct thread *thread)
 }
 
 /* BFD peer/dst register/update */
-int zebra_ptm_bfd_dst_register(struct zserv *client, int sock, u_short length,
+int zebra_ptm_bfd_dst_register(struct zserv *client, u_short length,
                               int command, struct zebra_vrf *zvrf)
 {
        struct stream *s;
@@ -819,7 +819,7 @@ int zebra_ptm_bfd_dst_register(struct zserv *client, int sock, u_short length,
 }
 
 /* BFD peer/dst deregister */
-int zebra_ptm_bfd_dst_deregister(struct zserv *client, int sock, u_short length,
+int zebra_ptm_bfd_dst_deregister(struct zserv *client, u_short length,
                                 struct zebra_vrf *zvrf)
 {
        struct stream *s;
@@ -946,7 +946,7 @@ int zebra_ptm_bfd_dst_deregister(struct zserv *client, int sock, u_short length,
 }
 
 /* BFD client register */
-int zebra_ptm_bfd_client_register(struct zserv *client, int sock,
+int zebra_ptm_bfd_client_register(struct zserv *client,
                                  u_short length)
 {
        struct stream *s;
@@ -961,6 +961,9 @@ int zebra_ptm_bfd_client_register(struct zserv *client, int sock,
                zlog_debug("bfd_client_register msg from client %s: length=%d",
                           zebra_route_string(client->proto), length);
 
+       s = client->ibuf;
+       pid = stream_getl(s);
+
        if (ptm_cb.ptm_sock == -1) {
                ptm_cb.t_timer = NULL;
                thread_add_timer(zebrad.master, zebra_ptm_connect, NULL,
@@ -977,9 +980,6 @@ int zebra_ptm_bfd_client_register(struct zserv *client, int sock,
        ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_CLIENT_FIELD,
                           tmp_buf);
 
-       s = client->ibuf;
-
-       pid = stream_getl(s);
        sprintf(tmp_buf, "%d", pid);
        ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_SEQID_FIELD,
                           tmp_buf);
index 9f9269ab55b796069e8b33e22d5cb0d8b6f1a4a0..664221eff79e7eb32fb6d54c80ec3ce441768053 100644 (file)
@@ -62,12 +62,12 @@ int zebra_ptm_connect(struct thread *t);
 void zebra_ptm_write(struct vty *vty);
 int zebra_ptm_get_enable_state(void);
 
-int zebra_ptm_bfd_dst_register(struct zserv *client, int sock, u_short length,
+int zebra_ptm_bfd_dst_register(struct zserv *client, u_short length,
                               int command, struct zebra_vrf *zvrf);
-int zebra_ptm_bfd_dst_deregister(struct zserv *client, int sock, u_short length,
+int zebra_ptm_bfd_dst_deregister(struct zserv *client, u_short length,
                                 struct zebra_vrf *zvrf);
 void zebra_ptm_show_status(struct vty *vty, struct interface *ifp);
-int zebra_ptm_bfd_client_register(struct zserv *client, int sock,
+int zebra_ptm_bfd_client_register(struct zserv *client,
                                  u_short length);
 void zebra_ptm_if_init(struct zebra_if *zebra_ifp);
 void zebra_ptm_if_set_ptm_state(struct interface *ifp,
index 0ca7e34b238ba0f148fc46bcc084601ec9c767ad..d3492fb41c1a11c689f21cd7ecd40bfb7b4ced8d 100644 (file)
@@ -436,7 +436,7 @@ DEFUN (show_pseudowires,
        "show mpls pseudowires",
        SHOW_STR
        MPLS_STR
-       "Pseudowires")
+       "Pseudowires\n")
 {
        struct zebra_vrf *zvrf;
        struct zebra_pw *pw;
index c0b5f9d10fa51839102bf91a01617b99417a629a..bd430423b33a81b27911b75f2110b5984830e0c9 100644 (file)
@@ -3028,7 +3028,7 @@ int zebra_vxlan_local_neigh_add_update(struct interface *ifp,
 /*
  * Handle message from client to delete a remote MACIP for a VNI.
  */
-int zebra_vxlan_remote_macip_del(struct zserv *client, int sock, u_short length,
+int zebra_vxlan_remote_macip_del(struct zserv *client, u_short length,
                                 struct zebra_vrf *zvrf)
 {
        struct stream *s;
@@ -3168,7 +3168,7 @@ int zebra_vxlan_remote_macip_del(struct zserv *client, int sock, u_short length,
  * could be just the add of a MAC address or the add of a neighbor
  * (IP+MAC).
  */
-int zebra_vxlan_remote_macip_add(struct zserv *client, int sock, u_short length,
+int zebra_vxlan_remote_macip_add(struct zserv *client, u_short length,
                                 struct zebra_vrf *zvrf)
 {
        struct stream *s;
@@ -3671,7 +3671,7 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp,
 /*
  * Handle message from client to delete a remote VTEP for a VNI.
  */
-int zebra_vxlan_remote_vtep_del(struct zserv *client, int sock, u_short length,
+int zebra_vxlan_remote_vtep_del(struct zserv *client, u_short length,
                                struct zebra_vrf *zvrf)
 {
        struct stream *s;
@@ -3750,7 +3750,7 @@ int zebra_vxlan_remote_vtep_del(struct zserv *client, int sock, u_short length,
 /*
  * Handle message from client to add a remote VTEP for a VNI.
  */
-int zebra_vxlan_remote_vtep_add(struct zserv *client, int sock, u_short length,
+int zebra_vxlan_remote_vtep_add(struct zserv *client, u_short length,
                                struct zebra_vrf *zvrf)
 {
        struct stream *s;
@@ -4280,8 +4280,8 @@ int zebra_vxlan_if_add(struct interface *ifp)
  * Handle message from client to enable/disable advertisement of g/w macip
  * routes
  */
-int zebra_vxlan_advertise_gw_macip(struct zserv *client, int sock,
-                                  u_short length, struct zebra_vrf *zvrf)
+int zebra_vxlan_advertise_gw_macip(struct zserv *client, u_short length,
+                                  struct zebra_vrf *zvrf)
 {
        struct stream *s;
        int advertise;
@@ -4388,7 +4388,7 @@ int zebra_vxlan_advertise_gw_macip(struct zserv *client, int sock,
  * when disabled, the entries should be deleted and remote VTEPs and MACs
  * uninstalled from the kernel.
  */
-int zebra_vxlan_advertise_all_vni(struct zserv *client, int sock,
+int zebra_vxlan_advertise_all_vni(struct zserv *client,
                                  u_short length, struct zebra_vrf *zvrf)
 {
        struct stream *s;
index 8b43615bb3e17951a18f2985b3b085cf56f5e441..290d19bcf3302d2028fd6a574f07cf7d85c10fe5 100644 (file)
@@ -96,9 +96,9 @@ extern int zebra_vxlan_local_neigh_add_update(
 extern int zebra_vxlan_local_neigh_del(struct interface *ifp,
                                       struct interface *link_if,
                                       struct ipaddr *ip);
-extern int zebra_vxlan_remote_macip_add(struct zserv *client, int sock,
+extern int zebra_vxlan_remote_macip_add(struct zserv *client,
                                        u_short length, struct zebra_vrf *zvrf);
-extern int zebra_vxlan_remote_macip_del(struct zserv *client, int sock,
+extern int zebra_vxlan_remote_macip_del(struct zserv *client,
                                        u_short length, struct zebra_vrf *zvrf);
 extern int zebra_vxlan_local_mac_add_update(struct interface *ifp,
                                            struct interface *br_if,
@@ -119,14 +119,14 @@ extern int zebra_vxlan_if_down(struct interface *ifp);
 extern int zebra_vxlan_if_add(struct interface *ifp);
 extern int zebra_vxlan_if_update(struct interface *ifp, u_int16_t chgflags);
 extern int zebra_vxlan_if_del(struct interface *ifp);
-extern int zebra_vxlan_remote_vtep_add(struct zserv *client, int sock,
+extern int zebra_vxlan_remote_vtep_add(struct zserv *client,
                                       u_short length, struct zebra_vrf *zvrf);
-extern int zebra_vxlan_remote_vtep_del(struct zserv *client, int sock,
+extern int zebra_vxlan_remote_vtep_del(struct zserv *client,
                                       u_short length, struct zebra_vrf *zvrf);
-extern int zebra_vxlan_advertise_gw_macip(struct zserv *client, int sock,
+extern int zebra_vxlan_advertise_gw_macip(struct zserv *client,
                                          u_short length,
                                          struct zebra_vrf *zvrf);
-extern int zebra_vxlan_advertise_all_vni(struct zserv *client, int sock,
+extern int zebra_vxlan_advertise_all_vni(struct zserv *client,
                                         u_short length,
                                         struct zebra_vrf *zvrf);
 extern void zebra_vxlan_init_tables(struct zebra_vrf *zvrf);
index cbc9f2bed9dd41085ee7c1f25ad4cfa96e9bfff4..15bfd37da8dfc83511d5229eccdd2647ac8c96cc 100644 (file)
@@ -40,6 +40,7 @@
 #include "nexthop.h"
 #include "vrf.h"
 #include "libfrr.h"
+#include "sockopt.h"
 
 #include "zebra/zserv.h"
 #include "zebra/zebra_ns.h"
@@ -693,7 +694,7 @@ static int zsend_write_nexthop(struct stream *s, struct nexthop *nexthop)
 }
 
 /* Nexthop register */
-static int zserv_rnh_register(struct zserv *client, int sock, u_short length,
+static int zserv_rnh_register(struct zserv *client, u_short length,
                              rnh_type_t type, struct zebra_vrf *zvrf)
 {
        struct rnh *rnh;
@@ -754,7 +755,7 @@ static int zserv_rnh_register(struct zserv *client, int sock, u_short length,
 }
 
 /* Nexthop register */
-static int zserv_rnh_unregister(struct zserv *client, int sock, u_short length,
+static int zserv_rnh_unregister(struct zserv *client, u_short length,
                                rnh_type_t type, struct zebra_vrf *zvrf)
 {
        struct rnh *rnh;
@@ -798,7 +799,7 @@ static int zserv_rnh_unregister(struct zserv *client, int sock, u_short length,
 #define ZEBRA_MIN_FEC_LENGTH 5
 
 /* FEC register */
-static int zserv_fec_register(struct zserv *client, int sock, u_short length)
+static int zserv_fec_register(struct zserv *client, u_short length)
 {
        struct stream *s;
        struct zebra_vrf *zvrf;
@@ -849,7 +850,7 @@ static int zserv_fec_register(struct zserv *client, int sock, u_short length)
 }
 
 /* FEC unregister */
-static int zserv_fec_unregister(struct zserv *client, int sock, u_short length)
+static int zserv_fec_unregister(struct zserv *client, u_short length)
 {
        struct stream *s;
        struct zebra_vrf *zvrf;
@@ -1763,7 +1764,7 @@ static int zread_vrf_unregister(struct zserv *client, u_short length,
 }
 
 static void zread_mpls_labels(int command, struct zserv *client, u_short length,
-                             vrf_id_t vrf_id)
+                             struct zebra_vrf *zvrf)
 {
        struct stream *s;
        enum lsp_types_t type;
@@ -1773,11 +1774,6 @@ static void zread_mpls_labels(int command, struct zserv *client, u_short length,
        ifindex_t ifindex;
        mpls_label_t in_label, out_label;
        u_int8_t distance;
-       struct zebra_vrf *zvrf;
-
-       zvrf = vrf_info_lookup(vrf_id);
-       if (!zvrf)
-               return;
 
        /* Get input stream.  */
        s = client->ibuf;
@@ -1959,7 +1955,7 @@ static void zread_release_label_chunk(struct zserv *client)
        release_label_chunk(client->proto, client->instance, start, end);
 }
 static void zread_label_manager_request(int cmd, struct zserv *client,
-                                       vrf_id_t vrf_id)
+                                       struct zebra_vrf *zvrf)
 {
        /* to avoid sending other messages like ZERBA_INTERFACE_UP */
        if (cmd == ZEBRA_LABEL_MANAGER_CONNECT)
@@ -1967,11 +1963,13 @@ static void zread_label_manager_request(int cmd, struct zserv *client,
 
        /* external label manager */
        if (lm_is_external)
-               zread_relay_label_manager_request(cmd, client, vrf_id);
+               zread_relay_label_manager_request(cmd, client,
+                                                 zvrf_id(zvrf));
        /* this is a label manager */
        else {
                if (cmd == ZEBRA_LABEL_MANAGER_CONNECT)
-                       zread_label_manager_connect(client, vrf_id);
+                       zread_label_manager_connect(client,
+                                                   zvrf_id(zvrf));
                else {
                        /* Sanity: don't allow 'unidentified' requests */
                        if (!client->proto) {
@@ -1980,7 +1978,8 @@ static void zread_label_manager_request(int cmd, struct zserv *client,
                                return;
                        }
                        if (cmd == ZEBRA_GET_LABEL_CHUNK)
-                               zread_get_label_chunk(client, vrf_id);
+                               zread_get_label_chunk(client,
+                                                     zvrf_id(zvrf));
                        else if (cmd == ZEBRA_RELEASE_LABEL_CHUNK)
                                zread_release_label_chunk(client);
                }
@@ -1988,10 +1987,9 @@ static void zread_label_manager_request(int cmd, struct zserv *client,
 }
 
 static int zread_pseudowire(int command, struct zserv *client, u_short length,
-                           vrf_id_t vrf_id)
+                           struct zebra_vrf *zvrf)
 {
        struct stream *s;
-       struct zebra_vrf *zvrf;
        char ifname[IF_NAMESIZE];
        ifindex_t ifindex;
        int type;
@@ -2004,10 +2002,6 @@ static int zread_pseudowire(int command, struct zserv *client, u_short length,
        uint8_t protocol;
        struct zebra_pw *pw;
 
-       zvrf = vrf_info_lookup(vrf_id);
-       if (!zvrf)
-               return -1;
-
        /* Get input stream.  */
        s = client->ibuf;
 
@@ -2210,7 +2204,7 @@ static void zebra_client_create(int sock)
        zebra_vrf_update_all(client);
 }
 
-static int zread_interface_set_master(struct zserv *client, int sock,
+static int zread_interface_set_master(struct zserv *client,
                                      u_short length)
 {
        struct interface *master;
@@ -2235,122 +2229,11 @@ static int zread_interface_set_master(struct zserv *client, int sock,
        return 1;
 }
 
-/* Handler of zebra service request. */
-static int zebra_client_read(struct thread *thread)
+static inline void zserv_handle_commands(struct zserv *client,
+                                        uint16_t command,
+                                        uint16_t length,
+                                        struct zebra_vrf *zvrf)
 {
-       int sock;
-       struct zserv *client;
-       size_t already;
-       uint16_t length, command;
-       uint8_t marker, version;
-       vrf_id_t vrf_id;
-       struct zebra_vrf *zvrf;
-
-       /* Get thread data.  Reset reading thread because I'm running. */
-       sock = THREAD_FD(thread);
-       client = THREAD_ARG(thread);
-       client->t_read = NULL;
-
-       if (client->t_suicide) {
-               zebra_client_close(client);
-               return -1;
-       }
-
-       /* Read length and command (if we don't have it already). */
-       if ((already = stream_get_endp(client->ibuf)) < ZEBRA_HEADER_SIZE) {
-               ssize_t nbyte;
-               if (((nbyte = stream_read_try(client->ibuf, sock,
-                                             ZEBRA_HEADER_SIZE - already))
-                    == 0)
-                   || (nbyte == -1)) {
-                       if (IS_ZEBRA_DEBUG_EVENT)
-                               zlog_debug("connection closed socket [%d]",
-                                          sock);
-                       zebra_client_close(client);
-                       return -1;
-               }
-               if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE - already)) {
-                       /* Try again later. */
-                       zebra_event(ZEBRA_READ, sock, client);
-                       return 0;
-               }
-               already = ZEBRA_HEADER_SIZE;
-       }
-
-       /* Reset to read from the beginning of the incoming packet. */
-       stream_set_getp(client->ibuf, 0);
-
-       /* Fetch header values */
-       length = stream_getw(client->ibuf);
-       marker = stream_getc(client->ibuf);
-       version = stream_getc(client->ibuf);
-       vrf_id = stream_getw(client->ibuf);
-       command = stream_getw(client->ibuf);
-
-       if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION) {
-               zlog_err(
-                       "%s: socket %d version mismatch, marker %d, version %d",
-                       __func__, sock, marker, version);
-               zebra_client_close(client);
-               return -1;
-       }
-       if (length < ZEBRA_HEADER_SIZE) {
-               zlog_warn(
-                       "%s: socket %d message length %u is less than header size %d",
-                       __func__, sock, length, ZEBRA_HEADER_SIZE);
-               zebra_client_close(client);
-               return -1;
-       }
-       if (length > STREAM_SIZE(client->ibuf)) {
-               zlog_warn(
-                       "%s: socket %d message length %u exceeds buffer size %lu",
-                       __func__, sock, length,
-                       (u_long)STREAM_SIZE(client->ibuf));
-               zebra_client_close(client);
-               return -1;
-       }
-
-       /* Read rest of data. */
-       if (already < length) {
-               ssize_t nbyte;
-               if (((nbyte = stream_read_try(client->ibuf, sock,
-                                             length - already))
-                    == 0)
-                   || (nbyte == -1)) {
-                       if (IS_ZEBRA_DEBUG_EVENT)
-                               zlog_debug(
-                                       "connection closed [%d] when reading zebra data",
-                                       sock);
-                       zebra_client_close(client);
-                       return -1;
-               }
-               if (nbyte != (ssize_t)(length - already)) {
-                       /* Try again later. */
-                       zebra_event(ZEBRA_READ, sock, client);
-                       return 0;
-               }
-       }
-
-       length -= ZEBRA_HEADER_SIZE;
-
-       /* Debug packet information. */
-       if (IS_ZEBRA_DEBUG_EVENT)
-               zlog_debug("zebra message comes from socket [%d]", sock);
-
-       if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
-               zlog_debug("zebra message received [%s] %d in VRF %u",
-                          zserv_command_string(command), length, vrf_id);
-
-       client->last_read_time = monotime(NULL);
-       client->last_read_cmd = command;
-
-       zvrf = zebra_vrf_lookup_by_id(vrf_id);
-       if (!zvrf) {
-               if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
-                       zlog_debug("zebra received unknown VRF[%u]", vrf_id);
-               goto zclient_read_out;
-       }
-
        switch (command) {
        case ZEBRA_ROUTER_ID_ADD:
                zread_router_id_add(client, length, zvrf);
@@ -2405,101 +2288,227 @@ static int zebra_client_read(struct thread *thread)
                zread_hello(client);
                break;
        case ZEBRA_NEXTHOP_REGISTER:
-               zserv_rnh_register(client, sock, length, RNH_NEXTHOP_TYPE,
+               zserv_rnh_register(client, length, RNH_NEXTHOP_TYPE,
                                   zvrf);
                break;
        case ZEBRA_NEXTHOP_UNREGISTER:
-               zserv_rnh_unregister(client, sock, length, RNH_NEXTHOP_TYPE,
+               zserv_rnh_unregister(client, length, RNH_NEXTHOP_TYPE,
                                     zvrf);
                break;
        case ZEBRA_IMPORT_ROUTE_REGISTER:
-               zserv_rnh_register(client, sock, length, RNH_IMPORT_CHECK_TYPE,
+               zserv_rnh_register(client, length, RNH_IMPORT_CHECK_TYPE,
                                   zvrf);
                break;
        case ZEBRA_IMPORT_ROUTE_UNREGISTER:
-               zserv_rnh_unregister(client, sock, length,
+               zserv_rnh_unregister(client, length,
                                     RNH_IMPORT_CHECK_TYPE, zvrf);
                break;
        case ZEBRA_BFD_DEST_UPDATE:
        case ZEBRA_BFD_DEST_REGISTER:
-               zebra_ptm_bfd_dst_register(client, sock, length, command, zvrf);
+               zebra_ptm_bfd_dst_register(client, length, command, zvrf);
                break;
        case ZEBRA_BFD_DEST_DEREGISTER:
-               zebra_ptm_bfd_dst_deregister(client, sock, length, zvrf);
+               zebra_ptm_bfd_dst_deregister(client, length, zvrf);
                break;
        case ZEBRA_VRF_UNREGISTER:
                zread_vrf_unregister(client, length, zvrf);
                break;
        case ZEBRA_BFD_CLIENT_REGISTER:
-               zebra_ptm_bfd_client_register(client, sock, length);
+               zebra_ptm_bfd_client_register(client, length);
                break;
        case ZEBRA_INTERFACE_ENABLE_RADV:
 #if defined(HAVE_RTADV)
-               zebra_interface_radv_set(client, sock, length, zvrf, 1);
+               zebra_interface_radv_set(client, length, zvrf, 1);
 #endif
                break;
        case ZEBRA_INTERFACE_DISABLE_RADV:
 #if defined(HAVE_RTADV)
-               zebra_interface_radv_set(client, sock, length, zvrf, 0);
+               zebra_interface_radv_set(client, length, zvrf, 0);
 #endif
                break;
        case ZEBRA_MPLS_LABELS_ADD:
        case ZEBRA_MPLS_LABELS_DELETE:
-               zread_mpls_labels(command, client, length, vrf_id);
+               zread_mpls_labels(command, client, length, zvrf);
                break;
        case ZEBRA_IPMR_ROUTE_STATS:
-               zebra_ipmr_route_stats(client, sock, length, zvrf);
+               zebra_ipmr_route_stats(client, length, zvrf);
                break;
        case ZEBRA_LABEL_MANAGER_CONNECT:
        case ZEBRA_GET_LABEL_CHUNK:
        case ZEBRA_RELEASE_LABEL_CHUNK:
-               zread_label_manager_request(command, client, vrf_id);
+               zread_label_manager_request(command, client, zvrf);
                break;
        case ZEBRA_FEC_REGISTER:
-               zserv_fec_register(client, sock, length);
+               zserv_fec_register(client, length);
                break;
        case ZEBRA_FEC_UNREGISTER:
-               zserv_fec_unregister(client, sock, length);
+               zserv_fec_unregister(client, length);
                break;
        case ZEBRA_ADVERTISE_DEFAULT_GW:
-               zebra_vxlan_advertise_gw_macip(client, sock, length, zvrf);
+               zebra_vxlan_advertise_gw_macip(client, length, zvrf);
                break;
        case ZEBRA_ADVERTISE_ALL_VNI:
-               zebra_vxlan_advertise_all_vni(client, sock, length, zvrf);
+               zebra_vxlan_advertise_all_vni(client, length, zvrf);
                break;
        case ZEBRA_REMOTE_VTEP_ADD:
-               zebra_vxlan_remote_vtep_add(client, sock, length, zvrf);
+               zebra_vxlan_remote_vtep_add(client, length, zvrf);
                break;
        case ZEBRA_REMOTE_VTEP_DEL:
-               zebra_vxlan_remote_vtep_del(client, sock, length, zvrf);
+               zebra_vxlan_remote_vtep_del(client, length, zvrf);
                break;
        case ZEBRA_REMOTE_MACIP_ADD:
-               zebra_vxlan_remote_macip_add(client, sock, length, zvrf);
+               zebra_vxlan_remote_macip_add(client, length, zvrf);
                break;
        case ZEBRA_REMOTE_MACIP_DEL:
-               zebra_vxlan_remote_macip_del(client, sock, length, zvrf);
+               zebra_vxlan_remote_macip_del(client, length, zvrf);
                break;
        case ZEBRA_INTERFACE_SET_MASTER:
-               zread_interface_set_master(client, sock, length);
+               zread_interface_set_master(client, length);
                break;
        case ZEBRA_PW_ADD:
        case ZEBRA_PW_DELETE:
        case ZEBRA_PW_SET:
        case ZEBRA_PW_UNSET:
-               zread_pseudowire(command, client, length, vrf_id);
+               zread_pseudowire(command, client, length, zvrf);
                break;
        default:
                zlog_info("Zebra received unknown command %d", command);
                break;
        }
+}
+
+/* Handler of zebra service request. */
+static int zebra_client_read(struct thread *thread)
+{
+       int sock;
+       struct zserv *client;
+       size_t already;
+       uint16_t length, command;
+       uint8_t marker, version;
+       vrf_id_t vrf_id;
+       struct zebra_vrf *zvrf;
+       int packets = 10;
+
+       /* Get thread data.  Reset reading thread because I'm running. */
+       sock = THREAD_FD(thread);
+       client = THREAD_ARG(thread);
+       client->t_read = NULL;
 
        if (client->t_suicide) {
-               /* No need to wait for thread callback, just kill immediately.
-                */
                zebra_client_close(client);
                return -1;
        }
 
+       while (packets) {
+               /* Read length and command (if we don't have it already). */
+               if ((already = stream_get_endp(client->ibuf))
+                   < ZEBRA_HEADER_SIZE) {
+                       ssize_t nbyte;
+                       if (((nbyte =
+                             stream_read_try(client->ibuf, sock,
+                                             ZEBRA_HEADER_SIZE - already))
+                            == 0)
+                           || (nbyte == -1)) {
+                               if (IS_ZEBRA_DEBUG_EVENT)
+                                       zlog_debug("connection closed socket [%d]",
+                                                  sock);
+                               zebra_client_close(client);
+                               return -1;
+                       }
+                       if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE - already)) {
+                               /* Try again later. */
+                               zebra_event(ZEBRA_READ, sock, client);
+                               return 0;
+                       }
+                       already = ZEBRA_HEADER_SIZE;
+               }
+
+               /* Reset to read from the beginning of the incoming packet. */
+               stream_set_getp(client->ibuf, 0);
+
+               /* Fetch header values */
+               length = stream_getw(client->ibuf);
+               marker = stream_getc(client->ibuf);
+               version = stream_getc(client->ibuf);
+               vrf_id = stream_getw(client->ibuf);
+               command = stream_getw(client->ibuf);
+
+               if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION) {
+                       zlog_err(
+                               "%s: socket %d version mismatch, marker %d, version %d",
+                               __func__, sock, marker, version);
+                       zebra_client_close(client);
+                       return -1;
+               }
+               if (length < ZEBRA_HEADER_SIZE) {
+                       zlog_warn(
+                               "%s: socket %d message length %u is less than header size %d",
+                               __func__, sock, length, ZEBRA_HEADER_SIZE);
+                       zebra_client_close(client);
+                       return -1;
+               }
+               if (length > STREAM_SIZE(client->ibuf)) {
+                       zlog_warn(
+                               "%s: socket %d message length %u exceeds buffer size %lu",
+                               __func__, sock, length,
+                               (u_long)STREAM_SIZE(client->ibuf));
+                       zebra_client_close(client);
+                       return -1;
+               }
+
+               /* Read rest of data. */
+               if (already < length) {
+                       ssize_t nbyte;
+                       if (((nbyte = stream_read_try(client->ibuf, sock,
+                                                     length - already))
+                            == 0)
+                           || (nbyte == -1)) {
+                               if (IS_ZEBRA_DEBUG_EVENT)
+                                       zlog_debug(
+                                               "connection closed [%d] when reading zebra data",
+                                               sock);
+                               zebra_client_close(client);
+                               return -1;
+                       }
+                       if (nbyte != (ssize_t)(length - already)) {
+                               /* Try again later. */
+                               zebra_event(ZEBRA_READ, sock, client);
+                               return 0;
+                       }
+               }
+
+               length -= ZEBRA_HEADER_SIZE;
+
+               /* Debug packet information. */
+               if (IS_ZEBRA_DEBUG_EVENT)
+                       zlog_debug("zebra message comes from socket [%d]", sock);
+
+               if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
+                       zlog_debug("zebra message received [%s] %d in VRF %u",
+                                  zserv_command_string(command), length, vrf_id);
+
+               client->last_read_time = monotime(NULL);
+               client->last_read_cmd = command;
+
+               zvrf = zebra_vrf_lookup_by_id(vrf_id);
+               if (!zvrf) {
+                       if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
+                               zlog_debug("zebra received unknown VRF[%u]", vrf_id);
+                       goto zclient_read_out;
+               }
+
+               zserv_handle_commands(client, command, length, zvrf);
+
+               if (client->t_suicide) {
+                       /* No need to wait for thread callback, just kill immediately.
+                        */
+                       zebra_client_close(client);
+                       return -1;
+               }
+               packets -= 1;
+               stream_reset(client->ibuf);
+       }
+
 zclient_read_out:
        stream_reset(client->ibuf);
        zebra_event(ZEBRA_READ, sock, client);
@@ -2573,6 +2582,11 @@ void zebra_zserv_socket_init(char *path)
                        unlink(suna->sun_path);
        }
 
+       zserv_privs.change(ZPRIVS_RAISE);
+       setsockopt_so_recvbuf(sock, 1048576);
+       setsockopt_so_sendbuf(sock, 1048576);
+       zserv_privs.change(ZPRIVS_LOWER);
+
        if (sa.ss_family != AF_UNIX && zserv_privs.change(ZPRIVS_RAISE))
                zlog_err("Can't raise privileges");
 
@@ -2786,7 +2800,7 @@ DEFUN (ip_forwarding,
        ip_forwarding_cmd,
        "ip forwarding",
        IP_STR
-       "Turn on IP forwarding")
+       "Turn on IP forwarding\n")
 {
        int ret;
 
@@ -2807,7 +2821,7 @@ DEFUN (no_ip_forwarding,
        "no ip forwarding",
        NO_STR
        IP_STR
-       "Turn off IP forwarding")
+       "Turn off IP forwarding\n")
 {
        int ret;
 
@@ -2953,7 +2967,7 @@ DEFUN (ipv6_forwarding,
        ipv6_forwarding_cmd,
        "ipv6 forwarding",
        IPV6_STR
-       "Turn on IPv6 forwarding")
+       "Turn on IPv6 forwarding\n")
 {
        int ret;
 
@@ -2974,7 +2988,7 @@ DEFUN (no_ipv6_forwarding,
        "no ipv6 forwarding",
        NO_STR
        IPV6_STR
-       "Turn off IPv6 forwarding")
+       "Turn off IPv6 forwarding\n")
 {
        int ret;