summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--babeld/babel_main.c2
-rw-r--r--babeld/babel_zebra.c2
-rw-r--r--babeld/babeld.h2
-rw-r--r--bgpd/bgp_debug.c1
-rw-r--r--bgpd/bgp_network.c2
-rw-r--r--bgpd/bgp_zebra.c13
-rw-r--r--bgpd/rfapi/vnc_zebra.c3
-rw-r--r--eigrpd/eigrp_network.c2
-rw-r--r--eigrpd/eigrp_structs.h2
-rw-r--r--eigrpd/eigrp_topology.c181
-rw-r--r--eigrpd/eigrp_topology.h24
-rw-r--r--eigrpd/eigrp_update.c47
-rw-r--r--eigrpd/eigrp_vty.c11
-rw-r--r--eigrpd/eigrp_zebra.c2
-rw-r--r--eigrpd/eigrpd.c4
-rw-r--r--eigrpd/eigrpd.h1
-rw-r--r--isisd/isis_bpf.c2
-rw-r--r--isisd/isis_dlpi.c2
-rw-r--r--isisd/isis_pfpacket.c2
-rw-r--r--isisd/isis_zebra.c2
-rw-r--r--isisd/isisd.h2
-rw-r--r--ldpd/lde.c4
-rw-r--r--ldpd/ldp_zebra.c4
-rw-r--r--lib/buffer.c14
-rw-r--r--lib/zclient.c12
-rw-r--r--lib/zclient.h5
-rw-r--r--nhrpd/nhrp_main.c2
-rw-r--r--nhrpd/nhrp_route.c2
-rw-r--r--nhrpd/nhrpd.h2
-rw-r--r--ospf6d/ospf6_area.c1
-rw-r--r--ospf6d/ospf6_intra.c127
-rw-r--r--ospf6d/ospf6_network.c3
-rw-r--r--ospf6d/ospf6_zebra.c2
-rw-r--r--ospf6d/ospf6d.h1
-rw-r--r--ospfd/ospf_interface.c12
-rw-r--r--ospfd/ospf_network.c2
-rw-r--r--ospfd/ospf_packet.c20
-rw-r--r--ospfd/ospf_vty.c215
-rw-r--r--ospfd/ospf_zebra.c2
-rw-r--r--ospfd/ospfd.c1
-rw-r--r--ospfd/ospfd.h1
-rw-r--r--pimd/pim_zebra.c2
-rw-r--r--pimd/pim_zlookup.c1
-rw-r--r--redhat/README.rpm_build.md11
-rw-r--r--redhat/daemons2
-rw-r--r--redhat/frr.spec.in29
-rw-r--r--ripd/rip_interface.c2
-rw-r--r--ripd/rip_zebra.c2
-rw-r--r--ripd/ripd.c3
-rw-r--r--ripd/ripd.h2
-rw-r--r--ripngd/ripng_interface.c2
-rw-r--r--ripngd/ripng_zebra.c2
-rw-r--r--ripngd/ripngd.c2
-rw-r--r--ripngd/ripngd.h2
-rw-r--r--tests/isisd/test_fuzz_isis_tlv.c2
-rw-r--r--tests/isisd/test_isis_vertex_queue.c2
-rw-r--r--zebra/rtadv.c2
-rw-r--r--zebra/rtadv.h2
-rw-r--r--zebra/zebra_fpm.c41
-rw-r--r--zebra/zebra_mroute.c2
-rw-r--r--zebra/zebra_mroute.h2
-rw-r--r--zebra/zebra_ptm.c12
-rw-r--r--zebra/zebra_ptm.h6
-rw-r--r--zebra/zebra_vxlan.c14
-rw-r--r--zebra/zebra_vxlan.h12
-rw-r--r--zebra/zserv.c334
66 files changed, 807 insertions, 427 deletions
diff --git a/babeld/babel_main.c b/babeld/babel_main.c
index 239ab71f06..48f6994d82 100644
--- a/babeld/babel_main.c
+++ b/babeld/babel_main.c
@@ -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,
diff --git a/babeld/babel_zebra.c b/babeld/babel_zebra.c
index 337b7b3927..e7c27e8e21 100644
--- a/babeld/babel_zebra.c
+++ b/babeld/babel_zebra.c
@@ -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;
diff --git a/babeld/babeld.h b/babeld/babeld.h
index 899b4f175c..bc284c1e96 100644
--- a/babeld/babeld.h
+++ b/babeld/babeld.h
@@ -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,
diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c
index 6de9ba3cc6..1fb930fdef 100644
--- a/bgpd/bgp_debug.c
+++ b/bgpd/bgp_debug.c
@@ -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;
diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c
index 70299ea456..101e0e62bb 100644
--- a/bgpd/bgp_network.c
+++ b/bgpd/bgp_network.c
@@ -675,7 +675,7 @@ static int bgp_listener(int sock, struct sockaddr *sa, socklen_t salen)
return ret;
}
- ret = listen(sock, 3);
+ ret = listen(sock, SOMAXCONN);
if (ret < 0) {
zlog_err("listen: %s", safe_strerror(errno));
return ret;
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index ddf461f1b1..0d1d768294 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -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;
diff --git a/bgpd/rfapi/vnc_zebra.c b/bgpd/rfapi/vnc_zebra.c
index b8058cf1e5..478d3b5ac7 100644
--- a/bgpd/rfapi/vnc_zebra.c
+++ b/bgpd/rfapi/vnc_zebra.c
@@ -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;
diff --git a/eigrpd/eigrp_network.c b/eigrpd/eigrp_network.c
index 56327f1205..21413bf446 100644
--- a/eigrpd/eigrp_network.c
+++ b/eigrpd/eigrp_network.c
@@ -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"
diff --git a/eigrpd/eigrp_structs.h b/eigrpd/eigrp_structs.h
index 4441f5d004..324181c21e 100644
--- a/eigrpd/eigrp_structs.h
+++ b/eigrpd/eigrp_structs.h
@@ -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*/
diff --git a/eigrpd/eigrp_topology.c b/eigrpd/eigrp_topology.c
index 94775622d9..7d352b8bed 100644
--- a/eigrpd/eigrp_topology.c
+++ b/eigrpd/eigrp_topology.c
@@ -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;
diff --git a/eigrpd/eigrp_topology.h b/eigrpd/eigrp_topology.h
index ef5b32d5bf..c8772c8c3a 100644
--- a/eigrpd/eigrp_topology.h
+++ b/eigrpd/eigrp_topology.h
@@ -33,23 +33,25 @@
#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
diff --git a/eigrpd/eigrp_update.c b/eigrpd/eigrp_update.c
index 4a86b48944..b4d1c58870 100644
--- a/eigrpd/eigrp_update.c
+++ b/eigrpd/eigrp_update.c
@@ -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);
}
diff --git a/eigrpd/eigrp_vty.c b/eigrpd/eigrp_vty.c
index d93abbb8b7..34a07f5fe3 100644
--- a/eigrpd/eigrp_vty.c
+++ b/eigrpd/eigrp_vty.c
@@ -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)
diff --git a/eigrpd/eigrp_zebra.c b/eigrpd/eigrp_zebra.c
index 28d2f29811..9076a50f57 100644
--- a/eigrpd/eigrp_zebra.c
+++ b/eigrpd/eigrp_zebra.c
@@ -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;
diff --git a/eigrpd/eigrpd.c b/eigrpd/eigrpd.c
index a8173f4efd..42d398458e 100644
--- a/eigrpd/eigrpd.c
+++ b/eigrpd/eigrpd.c
@@ -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;
diff --git a/eigrpd/eigrpd.h b/eigrpd/eigrpd.h
index 5ec6c8e1f7..de7c881ac0 100644
--- a/eigrpd/eigrpd.h
+++ b/eigrpd/eigrpd.h
@@ -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);
diff --git a/isisd/isis_bpf.c b/isisd/isis_bpf.c
index 2c8b126088..591af3b8ed 100644
--- a/isisd/isis_bpf.c
+++ b/isisd/isis_bpf.c
@@ -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),
diff --git a/isisd/isis_dlpi.c b/isisd/isis_dlpi.c
index 7ac8b54fa4..ccde4fbbe1 100644
--- a/isisd/isis_dlpi.c
+++ b/isisd/isis_dlpi.c
@@ -47,8 +47,6 @@
#include "privs.h"
-extern struct zebra_privs_t isisd_privs;
-
static t_uscalar_t dlpi_ctl[1024]; /* DLPI control messages */
/*
diff --git a/isisd/isis_pfpacket.c b/isisd/isis_pfpacket.c
index e24901b0de..974d2b78cf 100644
--- a/isisd/isis_pfpacket.c
+++ b/isisd/isis_pfpacket.c
@@ -44,8 +44,6 @@
#include "privs.h"
-extern struct zebra_privs_t isisd_privs;
-
/* tcpdump -i eth0 'isis' -dd */
static struct sock_filter isisfilter[] =
{
diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c
index 387f99938e..c186dd56ad 100644
--- a/isisd/isis_zebra.c
+++ b/isisd/isis_zebra.c
@@ -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;
diff --git a/isisd/isisd.h b/isisd/isisd.h
index a10748fd45..427d314df6 100644
--- a/isisd/isisd.h
+++ b/isisd/isisd.h
@@ -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 */
diff --git a/ldpd/lde.c b/ldpd/lde.c
index a7f933bbe5..8122b88cca 100644
--- a/ldpd/lde.c
+++ b/ldpd/lde.c
@@ -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);
diff --git a/ldpd/ldp_zebra.c b/ldpd/ldp_zebra.c
index 7f68f0b694..8fe51cb9d1 100644
--- a/ldpd/ldp_zebra.c
+++ b/ldpd/ldp_zebra.c
@@ -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;
diff --git a/lib/buffer.c b/lib/buffer.c
index a7c4fe4f2f..191fbf875a 100644
--- a/lib/buffer.c
+++ b/lib/buffer.c
@@ -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.
diff --git a/lib/zclient.c b/lib/zclient.c
index ad5c30584c..d23e5fbd79 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -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++)
diff --git a/lib/zclient.h b/lib/zclient.h
index 288951eb1a..23fe0e41f4 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -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 *);
diff --git a/nhrpd/nhrp_main.c b/nhrpd/nhrp_main.c
index 3a7186c1d7..767907aa53 100644
--- a/nhrpd/nhrp_main.c
+++ b/nhrpd/nhrp_main.c
@@ -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,
diff --git a/nhrpd/nhrp_route.c b/nhrpd/nhrp_route.c
index 495e226f15..7701dcbb88 100644
--- a/nhrpd/nhrp_route.c
+++ b/nhrpd/nhrp_route.c
@@ -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)
diff --git a/nhrpd/nhrpd.h b/nhrpd/nhrpd.h
index 3071371969..2ab40a4d39 100644
--- a/nhrpd/nhrpd.h
+++ b/nhrpd/nhrpd.h
@@ -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);
diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c
index b126786246..6bbab46ad8 100644
--- a/ospf6d/ospf6_area.c
+++ b/ospf6d/ospf6_area.c
@@ -234,6 +234,7 @@ struct ospf6_area *ospf6_area_create(u_int32_t area_id, struct ospf6 *o, int df)
oa->summary_prefix->scope = oa;
oa->summary_router = OSPF6_ROUTE_TABLE_CREATE(AREA, SUMMARY_ROUTERS);
oa->summary_router->scope = oa;
+ oa->router_lsa_size_limit = 1024 + 256;
/* set default options */
if (CHECK_FLAG(o->flag, OSPF6_STUB_ROUTER)) {
diff --git a/ospf6d/ospf6_intra.c b/ospf6d/ospf6_intra.c
index a2caeccb86..b5a0a9209b 100644
--- a/ospf6d/ospf6_intra.c
+++ b/ospf6d/ospf6_intra.c
@@ -52,6 +52,7 @@ unsigned char conf_debug_ospf6_brouter = 0;
u_int32_t conf_debug_ospf6_brouter_specific_router_id;
u_int32_t conf_debug_ospf6_brouter_specific_area_id;
+#define MAX_LSA_PAYLOAD (1024 + 256)
/******************************/
/* RFC2740 3.4.3.1 Router-LSA */
/******************************/
@@ -214,8 +215,7 @@ int ospf6_router_lsa_originate(struct thread *thread)
ospf6_router_lsa_options_set(oa, router_lsa);
/* describe links for each interfaces */
- lsdesc = (struct ospf6_router_lsdesc
- *)((caddr_t)router_lsa
+ lsdesc = (struct ospf6_router_lsdesc *)((caddr_t)router_lsa
+ sizeof(struct ospf6_router_lsa));
for (ALL_LIST_ELEMENTS(oa->if_list, node, nnode, oi)) {
@@ -248,6 +248,41 @@ int ospf6_router_lsa_originate(struct thread *thread)
return 0;
}
+ /* Fill LSA Header */
+ lsa_header->age = 0;
+ lsa_header->type = htons(OSPF6_LSTYPE_ROUTER);
+ lsa_header->id = htonl(link_state_id);
+ lsa_header->adv_router = oa->ospf6->router_id;
+ lsa_header->seqnum =
+ ospf6_new_ls_seqnum(lsa_header->type,
+ lsa_header->id,
+ lsa_header->adv_router, oa->lsdb);
+ lsa_header->length =
+ htons((caddr_t)lsdesc - (caddr_t)buffer);
+
+ /* LSA checksum */
+ ospf6_lsa_checksum(lsa_header);
+
+ /* create LSA */
+ lsa = ospf6_lsa_create(lsa_header);
+
+ /* Originate */
+ ospf6_lsa_originate_area(lsa, oa);
+
+ /* Reset Buffer to fill next Router LSA */
+ memset(buffer, 0, sizeof(buffer));
+ lsa_header = (struct ospf6_lsa_header *)buffer;
+ router_lsa =
+ (struct ospf6_router_lsa *)((caddr_t)lsa_header
+ + sizeof(struct ospf6_lsa_header));
+
+ ospf6_router_lsa_options_set(oa, router_lsa);
+
+ /* describe links for each interfaces */
+ lsdesc = (struct ospf6_router_lsdesc *)
+ ((caddr_t)router_lsa +
+ sizeof(struct ospf6_router_lsa));
+
link_state_id++;
}
@@ -861,7 +896,7 @@ int ospf6_intra_prefix_lsa_originate_stub(struct thread *thread)
char buffer[OSPF6_MAX_LSASIZE];
struct ospf6_lsa_header *lsa_header;
- struct ospf6_lsa *old, *lsa;
+ struct ospf6_lsa *old, *lsa, *old_next = NULL;
struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
struct ospf6_interface *oi;
@@ -873,6 +908,7 @@ int ospf6_intra_prefix_lsa_originate_stub(struct thread *thread)
unsigned short prefix_num = 0;
char buf[PREFIX2STR_BUFFER];
struct ospf6_route_table *route_advertise;
+ int ls_id = 0;
oa = (struct ospf6_area *)THREAD_ARG(thread);
oa->thread_intra_prefix_lsa = NULL;
@@ -882,8 +918,22 @@ int ospf6_intra_prefix_lsa_originate_stub(struct thread *thread)
oa->ospf6->router_id, oa->lsdb);
if (!IS_AREA_ENABLED(oa)) {
- if (old)
+ if (old) {
ospf6_lsa_purge(old);
+ /* find previous LSA */
+ old_next = ospf6_lsdb_lookup(
+ htons(OSPF6_LSTYPE_INTRA_PREFIX),
+ htonl(++ls_id),
+ oa->ospf6->router_id, oa->lsdb);
+
+ while (old_next) {
+ ospf6_lsa_purge(old_next);
+ old_next = ospf6_lsdb_lookup(
+ htons(OSPF6_LSTYPE_INTRA_PREFIX),
+ htonl(++ls_id),
+ oa->ospf6->router_id, oa->lsdb);
+ }
+ }
return 0;
}
@@ -895,8 +945,7 @@ int ospf6_intra_prefix_lsa_originate_stub(struct thread *thread)
/* prepare buffer */
memset(buffer, 0, sizeof(buffer));
lsa_header = (struct ospf6_lsa_header *)buffer;
- intra_prefix_lsa = (struct ospf6_intra_prefix_lsa
- *)((caddr_t)lsa_header
+ intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)((caddr_t)lsa_header
+ sizeof(struct ospf6_lsa_header));
/* Fill Intra-Area-Prefix-LSA */
@@ -945,8 +994,23 @@ int ospf6_intra_prefix_lsa_originate_stub(struct thread *thread)
}
if (route_advertise->count == 0) {
- if (old)
+ if (old) {
+ ls_id = 0;
ospf6_lsa_purge(old);
+ /* find previous LSA */
+ old_next = ospf6_lsdb_lookup(
+ htons(OSPF6_LSTYPE_INTRA_PREFIX),
+ htonl(++ls_id),
+ oa->ospf6->router_id, oa->lsdb);
+
+ while (old_next) {
+ ospf6_lsa_purge(old_next);
+ old_next = ospf6_lsdb_lookup(
+ htons(OSPF6_LSTYPE_INTRA_PREFIX),
+ htonl(++ls_id),
+ oa->ospf6->router_id, oa->lsdb);
+ }
+ }
ospf6_route_table_delete(route_advertise);
return 0;
}
@@ -957,13 +1021,58 @@ int ospf6_intra_prefix_lsa_originate_stub(struct thread *thread)
+ sizeof(struct ospf6_intra_prefix_lsa));
for (route = ospf6_route_head(route_advertise); route;
route = ospf6_route_best_next(route)) {
+ if (((caddr_t)op - (caddr_t)lsa_header) > MAX_LSA_PAYLOAD) {
+
+ intra_prefix_lsa->prefix_num = htons(prefix_num);
+
+ /* Fill LSA Header */
+ lsa_header->age = 0;
+ lsa_header->type = htons(OSPF6_LSTYPE_INTRA_PREFIX);
+ lsa_header->id = htonl(ls_id++);
+ lsa_header->adv_router = oa->ospf6->router_id;
+ lsa_header->seqnum =
+ ospf6_new_ls_seqnum(lsa_header->type,
+ lsa_header->id,
+ lsa_header->adv_router,
+ oa->lsdb);
+ lsa_header->length = htons((caddr_t)op -
+ (caddr_t)lsa_header);
+
+ /* LSA checksum */
+ ospf6_lsa_checksum(lsa_header);
+
+ /* Create LSA */
+ lsa = ospf6_lsa_create(lsa_header);
+
+ /* Originate */
+ ospf6_lsa_originate_area(lsa, oa);
+
+ /* Prepare next buffer */
+ memset(buffer, 0, sizeof(buffer));
+ lsa_header = (struct ospf6_lsa_header *)buffer;
+ intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
+ ((caddr_t)lsa_header
+ + sizeof(struct ospf6_lsa_header));
+
+ /* Fill Intra-Area-Prefix-LSA */
+ intra_prefix_lsa->ref_type = htons(OSPF6_LSTYPE_ROUTER);
+ intra_prefix_lsa->ref_id = htonl(0);
+ intra_prefix_lsa->ref_adv_router = oa->ospf6->router_id;
+
+ /* Put next set of prefixes to advertise */
+ prefix_num = 0;
+ op = (struct ospf6_prefix *)((caddr_t)intra_prefix_lsa
+ + sizeof(struct ospf6_intra_prefix_lsa));
+ }
+
op->prefix_length = route->prefix.prefixlen;
op->prefix_options = route->path.prefix_options;
op->prefix_metric = htons(route->path.cost);
memcpy(OSPF6_PREFIX_BODY(op), &route->prefix.u.prefix6,
OSPF6_PREFIX_SPACE(op->prefix_length));
- op = OSPF6_PREFIX_NEXT(op);
prefix_num++;
+
+ op = OSPF6_PREFIX_NEXT(op);
}
ospf6_route_table_delete(route_advertise);
@@ -980,7 +1089,7 @@ int ospf6_intra_prefix_lsa_originate_stub(struct thread *thread)
/* Fill LSA Header */
lsa_header->age = 0;
lsa_header->type = htons(OSPF6_LSTYPE_INTRA_PREFIX);
- lsa_header->id = htonl(0);
+ lsa_header->id = htonl(ls_id++);
lsa_header->adv_router = oa->ospf6->router_id;
lsa_header->seqnum =
ospf6_new_ls_seqnum(lsa_header->type, lsa_header->id,
diff --git a/ospf6d/ospf6_network.c b/ospf6d/ospf6_network.c
index 4d9c259443..9f81bb89fb 100644
--- a/ospf6d/ospf6_network.c
+++ b/ospf6d/ospf6_network.c
@@ -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;
diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c
index b032bd7a79..022b913168 100644
--- a/ospf6d/ospf6_zebra.c
+++ b/ospf6d/ospf6_zebra.c
@@ -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;
diff --git a/ospf6d/ospf6d.h b/ospf6d/ospf6d.h
index 77a40eac63..f95381084d 100644
--- a/ospf6d/ospf6d.h
+++ b/ospf6d/ospf6d.h
@@ -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);
diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c
index 34a1e6f6d6..e8700e7eb0 100644
--- a/ospfd/ospf_interface.c
+++ b/ospfd/ospf_interface.c
@@ -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))
diff --git a/ospfd/ospf_network.c b/ospfd/ospf_network.c
index 699f2341d5..519e3f9cf4 100644
--- a/ospfd/ospf_network.c
+++ b/ospfd/ospf_network.c
@@ -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"
diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c
index 47f5ee76d2..633c3deeaf 100644
--- a/ospfd/ospf_packet.c
+++ b/ospfd/ospf_packet.c
@@ -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);
diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c
index 70e0da1158..df3cd16c1c 100644
--- a/ospfd/ospf_vty.c
+++ b/ospfd/ospf_vty.c
@@ -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",
@@ -9484,6 +9697,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);
diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c
index 7e6146e0d3..76fa6fa6dd 100644
--- a/ospfd/ospf_zebra.c
+++ b/ospfd/ospf_zebra.c
@@ -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;
diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c
index 8ee32289c1..3771f94630 100644
--- a/ospfd/ospfd.c
+++ b/ospfd/ospfd.c
@@ -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 *);
diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h
index 4b0ebc8eb8..4c5bb756f6 100644
--- a/ospfd/ospfd.h
+++ b/ospfd/ospfd.h
@@ -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);
diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c
index db11e5f171..8c90ccbed1 100644
--- a/pimd/pim_zebra.c
+++ b/pimd/pim_zebra.c
@@ -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");
}
diff --git a/pimd/pim_zlookup.c b/pimd/pim_zlookup.c
index df8ad4e428..fd75a699b3 100644
--- a/pimd/pim_zlookup.c
+++ b/pimd/pim_zlookup.c
@@ -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);
diff --git a/redhat/README.rpm_build.md b/redhat/README.rpm_build.md
index c05331256a..2de64b8f40 100644
--- a/redhat/README.rpm_build.md
+++ b/redhat/README.rpm_build.md
@@ -9,11 +9,10 @@ Building your own FRRouting RPM
Newer automake/autoconf/bison is only needed to build the rpm and is
**not** needed to install the binary rpm package
-2. Install the following packages to build the RPMs:
+2. Install the build packages as documented in doc/Building_on_xxxxx.md
+ and the following additional packages:
- yum install git autoconf automake libtool make gawk readline-devel \
- texinfo net-snmp-devel groff pkgconfig rpm-build json-c-devel \
- pam-devel texi2html bison libcap-devel flex
+ yum install rpm-build net-snmp-devel pam-devel
Additionally, on systems with systemd (CentOS 7, Fedora)
@@ -21,10 +20,6 @@ Building your own FRRouting RPM
(use `dnf install` on new Fedora instead of `yum install`)
- **CentOS 6:** Please check doc/Building_FRR_on_CentOS6.md for details on
- how to install required version of autoconf, automake and bison. The
- versions in the common Repo are too old.
-
3. Checkout FRR under a **unpriviledged** user account
git clone https://github.com/frrouting/frr.git frr
diff --git a/redhat/daemons b/redhat/daemons
index 8d12a1f5b8..c28414f0ea 100644
--- a/redhat/daemons
+++ b/redhat/daemons
@@ -35,7 +35,7 @@
# group "frrvty" and set to ug=rw,o= though. Check /etc/pam.d/frr, too.
#
watchfrr_enable=no
-watchfrr_options=("-b_" "-r/etc/init.d/frr_restart_%s" "-s/etc/init.d/frr_start_%s" "-k/etc/init.d/frr_stop_%s")
+watchfrr_options=("-b_" "-r/usr/lib/frr/frr_restart_%s" "-s/usr/lib/frr/frr_start_%s" "-k/usr/lib/frr/frr_stop_%s")
#
zebra=no
bgpd=no
diff --git a/redhat/frr.spec.in b/redhat/frr.spec.in
index ea8a312364..4e05f7828c 100644
--- a/redhat/frr.spec.in
+++ b/redhat/frr.spec.in
@@ -333,6 +333,8 @@ install %{zeb_rh_src}/frr.init \
%else
mkdir -p %{buildroot}/etc/rc.d/init.d
install %{zeb_rh_src}/frr.init \
+ %{buildroot}%{_sbindir}/frr
+ln -s %{_sbindir}/frr \
%{buildroot}/etc/rc.d/init.d/frr
%endif
@@ -415,6 +417,10 @@ done
/sbin/chkconfig --add frr
%endif
+# Fix bad path in previous config files
+# Config files won't get replaced by default, so we do this ugly hack to fix it
+%__sed -i 's|/etc/init.d/|%{_sbindir}/|g' %{_sysconfdir}/daemons 2> /dev/null || true
+
/sbin/install-info %{_infodir}/frr.info.gz %{_infodir}/dir
# Create dummy files if they don't exist so basic functions can be used.
@@ -463,7 +469,7 @@ if [ "$1" -ge 1 ]; then
##
## Systemd Version
##
- %systemd_postun frr.service
+ %systemd_postun_with_restart frr.service
%else
##
## init.d Version
@@ -478,18 +484,14 @@ fi
##
## Systemd Version
##
- if [ "$1" = "0" ]; then
- for daemon in %all_daemons ; do
- if [ x"${daemon}" != x"" ] ; then
- %systemd_preun frr.service
- fi
- done
+ if [ $1 -eq 0 ] ; then
+ %systemd_preun frr.service
fi
%else
##
## init.d Version
##
- if [ "$1" = "0" ]; then
+ if [ $1 -eq 0 ] ; then
/etc/rc.d/init.d/frr stop >/dev/null 2>&1
/sbin/chkconfig --del frr
fi
@@ -557,10 +559,11 @@ rm -rf %{buildroot}
%config(noreplace) /etc/frr/[!v]*.conf*
%config(noreplace) %attr(750,%frr_user,%frr_user) /etc/frr/daemons
%if "%{initsystem}" == "systemd"
- %config %{_unitdir}/frr.service
+ %attr(644,root,root) %{_unitdir}/frr.service
%{_sbindir}/frr
%else
- %config /etc/rc.d/init.d/frr
+ /etc/rc.d/init.d/frr
+ %{_sbindir}/frr
%endif
%config(noreplace) /etc/pam.d/frr
%config(noreplace) %attr(640,root,root) /etc/logrotate.d/*
@@ -596,7 +599,11 @@ rm -rf %{buildroot}
%endif
%changelog
-* Mon Jun 5 2017 Martin Winter <mwinter@opensourcerouting.org> - %{version}
+* Fri Oct 20 2017 Martin Winter <mwinter@opensourcerouting.org> - %{version}
+- Fix script location for watchfrr restart functions in daemon config
+- Fix postun script to restart frr during upgrade
+
+* Mon Jun 5 2017 Martin Winter <mwinter@opensourcerouting.org>
- added NHRP and EIGRP daemon
* Mon Apr 17 2017 Martin Winter <mwinter@opensourcerouting.org>
diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c
index 9282896c28..a997ca5f2e 100644
--- a/ripd/rip_interface.c
+++ b/ripd/rip_interface.c
@@ -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;
diff --git a/ripd/rip_zebra.c b/ripd/rip_zebra.c
index 28144a2435..3772f6223e 100644
--- a/ripd/rip_zebra.c
+++ b/ripd/rip_zebra.c
@@ -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;
diff --git a/ripd/ripd.c b/ripd/ripd.c
index a4b56d9fbf..aece5d03cd 100644
--- a/ripd/ripd.c
+++ b/ripd/ripd.c
@@ -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;
diff --git a/ripd/ripd.h b/ripd/ripd.h
index 895a48c3db..ae34ed3f48 100644
--- a/ripd/ripd.h
+++ b/ripd/ripd.h
@@ -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;
diff --git a/ripngd/ripng_interface.c b/ripngd/ripng_interface.c
index d450d5a7f9..d1057bf53e 100644
--- a/ripngd/ripng_interface.c
+++ b/ripngd/ripng_interface.c
@@ -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 *);
diff --git a/ripngd/ripng_zebra.c b/ripngd/ripng_zebra.c
index 7edaaa5dff..084d58ee53 100644
--- a/ripngd/ripng_zebra.c
+++ b/ripngd/ripng_zebra.c
@@ -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;
diff --git a/ripngd/ripngd.c b/ripngd/ripngd.c
index df3af2a17f..daa2526a0c 100644
--- a/ripngd/ripngd.c
+++ b/ripngd/ripngd.c
@@ -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);
diff --git a/ripngd/ripngd.h b/ripngd/ripngd.h
index 9a609cab8a..25a5b46c02 100644
--- a/ripngd/ripngd.h
+++ b/ripngd/ripngd.h
@@ -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. */
diff --git a/tests/isisd/test_fuzz_isis_tlv.c b/tests/isisd/test_fuzz_isis_tlv.c
index 1f5abba392..67a1593500 100644
--- a/tests/isisd/test_fuzz_isis_tlv.c
+++ b/tests/isisd/test_fuzz_isis_tlv.c
@@ -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)
diff --git a/tests/isisd/test_isis_vertex_queue.c b/tests/isisd/test_isis_vertex_queue.c
index 674482cd17..0e473d7a6b 100644
--- a/tests/isisd/test_isis_vertex_queue.c
+++ b/tests/isisd/test_isis_vertex_queue.c
@@ -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;
diff --git a/zebra/rtadv.c b/zebra/rtadv.c
index 6a8e2ac594..7f9bc47315 100644
--- a/zebra/rtadv.c
+++ b/zebra/rtadv.c
@@ -799,7 +799,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;
diff --git a/zebra/rtadv.h b/zebra/rtadv.h
index dcaeb3ed28..9ec1bffa8d 100644
--- a/zebra/rtadv.h
+++ b/zebra/rtadv.h
@@ -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);
diff --git a/zebra/zebra_fpm.c b/zebra/zebra_fpm.c
index 6d3a8de8c9..a5d256b7aa 100644
--- a/zebra/zebra_fpm.c
+++ b/zebra/zebra_fpm.c
@@ -92,7 +92,6 @@ typedef struct zfpm_stats_t_ {
unsigned long updates_triggered;
unsigned long redundant_triggers;
- unsigned long non_fpm_table_triggers;
unsigned long dests_del_after_update;
@@ -312,31 +311,6 @@ static time_t zfpm_get_elapsed_time(time_t reference)
}
/*
- * zfpm_is_table_for_fpm
- *
- * Returns TRUE if the the given table is to be communicated to the
- * FPM.
- */
-static inline int zfpm_is_table_for_fpm(struct route_table *table)
-{
- rib_table_info_t *info;
-
- info = rib_table_info(table);
-
- /*
- * We only send the unicast tables in the main instance to the FPM
- * at this point.
- */
- if (zvrf_id(info->zvrf) != 0)
- return 0;
-
- if (info->safi != SAFI_UNICAST)
- return 0;
-
- return 1;
-}
-
-/*
* zfpm_rnodes_iter_init
*/
static inline void zfpm_rnodes_iter_init(zfpm_rnodes_iter_t *iter)
@@ -371,10 +345,7 @@ static inline struct route_node *zfpm_rnodes_iter_next(zfpm_rnodes_iter_t *iter)
*/
route_table_iter_cleanup(&iter->iter);
- while ((table = rib_tables_iter_next(&iter->tables_iter))) {
- if (zfpm_is_table_for_fpm(table))
- break;
- }
+ table = rib_tables_iter_next(&iter->tables_iter);
if (!table)
return NULL;
@@ -1278,15 +1249,6 @@ static int zfpm_trigger_update(struct route_node *rn, const char *reason)
dest = rib_dest_from_rnode(rn);
- /*
- * Ignore the trigger if the dest is not in a table that we would
- * send to the FPM.
- */
- if (!zfpm_is_table_for_fpm(rib_dest_table(dest))) {
- zfpm_g->stats.non_fpm_table_triggers++;
- return 0;
- }
-
if (CHECK_FLAG(dest->flags, RIB_DEST_UPDATE_FPM)) {
zfpm_g->stats.redundant_triggers++;
return 0;
@@ -1401,7 +1363,6 @@ static void zfpm_show_stats(struct vty *vty)
ZFPM_SHOW_STAT(route_adds);
ZFPM_SHOW_STAT(route_dels);
ZFPM_SHOW_STAT(updates_triggered);
- ZFPM_SHOW_STAT(non_fpm_table_triggers);
ZFPM_SHOW_STAT(redundant_triggers);
ZFPM_SHOW_STAT(dests_del_after_update);
ZFPM_SHOW_STAT(t_conn_down_starts);
diff --git a/zebra/zebra_mroute.c b/zebra/zebra_mroute.c
index 75d5d5d627..8fa00b83c9 100644
--- a/zebra/zebra_mroute.c
+++ b/zebra/zebra_mroute.c
@@ -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;
diff --git a/zebra/zebra_mroute.h b/zebra/zebra_mroute.h
index fda97e80d7..616c3a83ab 100644
--- a/zebra/zebra_mroute.h
+++ b/zebra/zebra_mroute.h
@@ -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
diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c
index 93b0723d8b..464a8cf875 100644
--- a/zebra/zebra_ptm.c
+++ b/zebra/zebra_ptm.c
@@ -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);
diff --git a/zebra/zebra_ptm.h b/zebra/zebra_ptm.h
index 9f9269ab55..664221eff7 100644
--- a/zebra/zebra_ptm.h
+++ b/zebra/zebra_ptm.h
@@ -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,
diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c
index c0b5f9d10f..bd430423b3 100644
--- a/zebra/zebra_vxlan.c
+++ b/zebra/zebra_vxlan.c
@@ -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;
diff --git a/zebra/zebra_vxlan.h b/zebra/zebra_vxlan.h
index 8b43615bb3..290d19bcf3 100644
--- a/zebra/zebra_vxlan.h
+++ b/zebra/zebra_vxlan.h
@@ -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);
diff --git a/zebra/zserv.c b/zebra/zserv.c
index cbc9f2bed9..6295de0c2e 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -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");