mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-28 15:05:03 +00:00
ospfd: support write socket per interface
Add support for a write socket per interface, enabled by default at the ospf instance level. An ospf instance-level config allows this to be disabled, reverting to the older behavior where a single per-instance socket is used for sending and receiving packets. Signed-off-by: Mark Stapp <mjs@labn.net>
This commit is contained in:
parent
e80c797a1f
commit
04a0401f2d
@ -651,6 +651,8 @@ int ospf_if_new_hook(struct interface *ifp)
|
|||||||
|
|
||||||
ifp->info = XCALLOC(MTYPE_OSPF_IF_INFO, sizeof(struct ospf_if_info));
|
ifp->info = XCALLOC(MTYPE_OSPF_IF_INFO, sizeof(struct ospf_if_info));
|
||||||
|
|
||||||
|
IF_OSPF_IF_INFO(ifp)->oii_fd = -1;
|
||||||
|
|
||||||
IF_OIFS(ifp) = route_table_init();
|
IF_OIFS(ifp) = route_table_init();
|
||||||
IF_OIFS_PARAMS(ifp) = route_table_init();
|
IF_OIFS_PARAMS(ifp) = route_table_init();
|
||||||
|
|
||||||
@ -691,6 +693,8 @@ static int ospf_if_delete_hook(struct interface *ifp)
|
|||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
|
struct ospf_if_info *oii;
|
||||||
|
|
||||||
rc = ospf_opaque_del_if(ifp);
|
rc = ospf_opaque_del_if(ifp);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -707,6 +711,13 @@ static int ospf_if_delete_hook(struct interface *ifp)
|
|||||||
route_table_finish(IF_OIFS(ifp));
|
route_table_finish(IF_OIFS(ifp));
|
||||||
route_table_finish(IF_OIFS_PARAMS(ifp));
|
route_table_finish(IF_OIFS_PARAMS(ifp));
|
||||||
|
|
||||||
|
/* Close per-interface socket */
|
||||||
|
oii = ifp->info;
|
||||||
|
if (oii && oii->oii_fd > 0) {
|
||||||
|
close(oii->oii_fd);
|
||||||
|
oii->oii_fd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
XFREE(MTYPE_OSPF_IF_INFO, ifp->info);
|
XFREE(MTYPE_OSPF_IF_INFO, ifp->info);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
@ -1367,6 +1378,16 @@ static int ospf_ifp_up(struct interface *ifp)
|
|||||||
struct ospf_interface *oi;
|
struct ospf_interface *oi;
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
struct ospf_if_info *oii = ifp->info;
|
struct ospf_if_info *oii = ifp->info;
|
||||||
|
struct ospf *ospf;
|
||||||
|
|
||||||
|
if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
|
||||||
|
zlog_debug("Zebra: Interface[%s] state change to up.",
|
||||||
|
ifp->name);
|
||||||
|
|
||||||
|
/* Open per-intf write socket if configured */
|
||||||
|
ospf = ifp->vrf->info;
|
||||||
|
if (ospf && ospf->intf_socket_enabled)
|
||||||
|
ospf_ifp_sock_init(ifp);
|
||||||
|
|
||||||
ospf_if_recalculate_output_cost(ifp);
|
ospf_if_recalculate_output_cost(ifp);
|
||||||
|
|
||||||
@ -1384,10 +1405,6 @@ static int ospf_ifp_up(struct interface *ifp)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
|
|
||||||
zlog_debug("Zebra: Interface[%s] state change to up.",
|
|
||||||
ifp->name);
|
|
||||||
|
|
||||||
for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
|
for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
|
||||||
if ((oi = rn->info) == NULL)
|
if ((oi = rn->info) == NULL)
|
||||||
continue;
|
continue;
|
||||||
@ -1416,6 +1433,9 @@ static int ospf_ifp_down(struct interface *ifp)
|
|||||||
ospf_if_down(oi);
|
ospf_if_down(oi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Close per-interface write socket if configured */
|
||||||
|
ospf_ifp_sock_close(ifp);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,6 +121,9 @@ struct ospf_if_info {
|
|||||||
membership_counts[MEMBER_MAX]; /* multicast group refcnts */
|
membership_counts[MEMBER_MAX]; /* multicast group refcnts */
|
||||||
|
|
||||||
uint32_t curr_mtu;
|
uint32_t curr_mtu;
|
||||||
|
|
||||||
|
/* Per-interface write socket, configured via 'ospf' object */
|
||||||
|
int oii_fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ospf_interface;
|
struct ospf_interface;
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "sockopt.h"
|
#include "sockopt.h"
|
||||||
#include "privs.h"
|
#include "privs.h"
|
||||||
#include "lib_errors.h"
|
#include "lib_errors.h"
|
||||||
|
#include "lib/table.h"
|
||||||
|
|
||||||
#include "ospfd/ospfd.h"
|
#include "ospfd/ospfd.h"
|
||||||
#include "ospfd/ospf_network.h"
|
#include "ospfd/ospf_network.h"
|
||||||
@ -119,61 +120,60 @@ int ospf_if_drop_alldrouters(struct ospf *top, struct prefix *p,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ospf_if_ipmulticast(struct ospf *top, struct prefix *p, ifindex_t ifindex)
|
int ospf_if_ipmulticast(int fd, struct prefix *p, ifindex_t ifindex)
|
||||||
{
|
{
|
||||||
uint8_t val;
|
uint8_t val;
|
||||||
int ret, len;
|
int ret, len;
|
||||||
|
|
||||||
/* Prevent receiving self-origined multicast packets. */
|
/* Prevent receiving self-origined multicast packets. */
|
||||||
ret = setsockopt_ipv4_multicast_loop(top->fd, 0);
|
ret = setsockopt_ipv4_multicast_loop(fd, 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
flog_err(EC_LIB_SOCKET,
|
flog_err(EC_LIB_SOCKET,
|
||||||
"can't setsockopt IP_MULTICAST_LOOP(0) for fd %d: %s",
|
"can't setsockopt IP_MULTICAST_LOOP(0) for fd %d: %s",
|
||||||
top->fd, safe_strerror(errno));
|
fd, safe_strerror(errno));
|
||||||
|
|
||||||
/* Explicitly set multicast ttl to 1 -- endo. */
|
/* Explicitly set multicast ttl to 1 -- endo. */
|
||||||
val = 1;
|
val = 1;
|
||||||
len = sizeof(val);
|
len = sizeof(val);
|
||||||
ret = setsockopt(top->fd, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&val,
|
ret = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&val, len);
|
||||||
len);
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
flog_err(EC_LIB_SOCKET,
|
flog_err(EC_LIB_SOCKET,
|
||||||
"can't setsockopt IP_MULTICAST_TTL(1) for fd %d: %s",
|
"can't setsockopt IP_MULTICAST_TTL(1) for fd %d: %s",
|
||||||
top->fd, safe_strerror(errno));
|
fd, safe_strerror(errno));
|
||||||
#ifndef GNU_LINUX
|
#ifndef GNU_LINUX
|
||||||
/* For GNU LINUX ospf_write uses IP_PKTINFO, in_pktinfo to send
|
/* For GNU LINUX ospf_write uses IP_PKTINFO, in_pktinfo to send
|
||||||
* packet out of ifindex. Below would be used Non Linux system.
|
* packet out of ifindex. Below would be used Non Linux system.
|
||||||
*/
|
*/
|
||||||
ret = setsockopt_ipv4_multicast_if(top->fd, p->u.prefix4, ifindex);
|
ret = setsockopt_ipv4_multicast_if(fd, p->u.prefix4, ifindex);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
flog_err(EC_LIB_SOCKET,
|
flog_err(EC_LIB_SOCKET,
|
||||||
"can't setsockopt IP_MULTICAST_IF(fd %d, addr %pI4, ifindex %u): %s",
|
"can't setsockopt IP_MULTICAST_IF(fd %d, addr %pI4, ifindex %u): %s",
|
||||||
top->fd, &p->u.prefix4, ifindex,
|
fd, &p->u.prefix4, ifindex,
|
||||||
safe_strerror(errno));
|
safe_strerror(errno));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ospf_sock_init(struct ospf *ospf)
|
/*
|
||||||
|
* Helper to open and set up a socket; returns the new fd on success,
|
||||||
|
* -1 on error.
|
||||||
|
*/
|
||||||
|
static int sock_init_common(vrf_id_t vrf_id, const char *name, int *pfd)
|
||||||
{
|
{
|
||||||
int ospf_sock;
|
int ospf_sock;
|
||||||
int ret, hincl = 1;
|
int ret, hincl = 1;
|
||||||
|
|
||||||
/* silently ignore. already done */
|
if (vrf_id == VRF_UNKNOWN) {
|
||||||
if (ospf->fd > 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (ospf->vrf_id == VRF_UNKNOWN) {
|
|
||||||
/* silently return since VRF is not ready */
|
/* silently return since VRF is not ready */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
frr_with_privs(&ospfd_privs) {
|
frr_with_privs(&ospfd_privs) {
|
||||||
ospf_sock = vrf_socket(AF_INET, SOCK_RAW, IPPROTO_OSPFIGP,
|
ospf_sock = vrf_socket(AF_INET, SOCK_RAW, IPPROTO_OSPFIGP,
|
||||||
ospf->vrf_id, ospf->name);
|
vrf_id, name);
|
||||||
if (ospf_sock < 0) {
|
if (ospf_sock < 0) {
|
||||||
flog_err(EC_LIB_SOCKET,
|
flog_err(EC_LIB_SOCKET, "%s: socket: %s", __func__,
|
||||||
"ospf_read_sock_init: socket: %s",
|
|
||||||
safe_strerror(errno));
|
safe_strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -212,10 +212,8 @@ int ospf_sock_init(struct ospf *ospf)
|
|||||||
ospf_sock);
|
ospf_sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update socket buffer sizes */
|
*pfd = ospf_sock;
|
||||||
ospf_sock_bufsize_update(ospf, ospf_sock, OSPF_SOCK_BOTH);
|
|
||||||
|
|
||||||
ospf->fd = ospf_sock;
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,3 +235,79 @@ void ospf_sock_bufsize_update(const struct ospf *ospf, int sock,
|
|||||||
setsockopt_so_sendbuf(sock, bufsize);
|
setsockopt_so_sendbuf(sock, bufsize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ospf_sock_init(struct ospf *ospf)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* silently ignore. already done */
|
||||||
|
if (ospf->fd > 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
ret = sock_init_common(ospf->vrf_id, ospf->name, &(ospf->fd));
|
||||||
|
|
||||||
|
if (ret >= 0) /* Update socket buffer sizes */
|
||||||
|
ospf_sock_bufsize_update(ospf, ospf->fd, OSPF_SOCK_BOTH);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Open per-interface write socket
|
||||||
|
*/
|
||||||
|
int ospf_ifp_sock_init(struct interface *ifp)
|
||||||
|
{
|
||||||
|
struct ospf_if_info *oii;
|
||||||
|
struct ospf_interface *oi;
|
||||||
|
struct ospf *ospf;
|
||||||
|
struct route_node *rn;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
oii = IF_OSPF_IF_INFO(ifp);
|
||||||
|
if (oii == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (oii->oii_fd > 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
rn = route_top(IF_OIFS(ifp));
|
||||||
|
if (rn && rn->info) {
|
||||||
|
oi = rn->info;
|
||||||
|
ospf = oi->ospf;
|
||||||
|
} else
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
ret = sock_init_common(ifp->vrf->vrf_id, ifp->name, &oii->oii_fd);
|
||||||
|
|
||||||
|
if (ret >= 0) /* Update socket buffer sizes */
|
||||||
|
ospf_sock_bufsize_update(ospf, oii->oii_fd, OSPF_SOCK_BOTH);
|
||||||
|
|
||||||
|
if (IS_DEBUG_OSPF_EVENT)
|
||||||
|
zlog_debug("%s: ifp %s, oii %p, fd %d", __func__, ifp->name,
|
||||||
|
oii, oii->oii_fd);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Close per-interface write socket
|
||||||
|
*/
|
||||||
|
int ospf_ifp_sock_close(struct interface *ifp)
|
||||||
|
{
|
||||||
|
struct ospf_if_info *oii;
|
||||||
|
|
||||||
|
oii = IF_OSPF_IF_INFO(ifp);
|
||||||
|
if (oii == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (oii->oii_fd > 0) {
|
||||||
|
if (IS_DEBUG_OSPF_EVENT)
|
||||||
|
zlog_debug("%s: ifp %s, oii %p, fd %d", __func__,
|
||||||
|
ifp->name, oii, oii->oii_fd);
|
||||||
|
|
||||||
|
close(oii->oii_fd);
|
||||||
|
oii->oii_fd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -13,8 +13,11 @@ extern int ospf_if_drop_allspfrouters(struct ospf *, struct prefix *,
|
|||||||
ifindex_t);
|
ifindex_t);
|
||||||
extern int ospf_if_add_alldrouters(struct ospf *, struct prefix *, ifindex_t);
|
extern int ospf_if_add_alldrouters(struct ospf *, struct prefix *, ifindex_t);
|
||||||
extern int ospf_if_drop_alldrouters(struct ospf *, struct prefix *, ifindex_t);
|
extern int ospf_if_drop_alldrouters(struct ospf *, struct prefix *, ifindex_t);
|
||||||
extern int ospf_if_ipmulticast(struct ospf *, struct prefix *, ifindex_t);
|
extern int ospf_if_ipmulticast(int fd, struct prefix *, ifindex_t);
|
||||||
extern int ospf_sock_init(struct ospf *ospf);
|
extern int ospf_sock_init(struct ospf *ospf);
|
||||||
|
/* Open, close per-interface write socket */
|
||||||
|
int ospf_ifp_sock_init(struct interface *ifp);
|
||||||
|
int ospf_ifp_sock_close(struct interface *ifp);
|
||||||
|
|
||||||
enum ospf_sock_type_e {
|
enum ospf_sock_type_e {
|
||||||
OSPF_SOCK_NONE = 0,
|
OSPF_SOCK_NONE = 0,
|
||||||
|
@ -618,7 +618,7 @@ static void ospf_write(struct event *thread)
|
|||||||
struct msghdr msg;
|
struct msghdr msg;
|
||||||
struct iovec iov[2];
|
struct iovec iov[2];
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
int ret;
|
int ret, fd;
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
#ifdef WANT_OSPF_WRITE_FRAGMENT
|
#ifdef WANT_OSPF_WRITE_FRAGMENT
|
||||||
@ -633,11 +633,12 @@ static void ospf_write(struct event *thread)
|
|||||||
struct cmsghdr *cm = (struct cmsghdr *)cmsgbuf;
|
struct cmsghdr *cm = (struct cmsghdr *)cmsgbuf;
|
||||||
struct in_pktinfo *pi;
|
struct in_pktinfo *pi;
|
||||||
#endif
|
#endif
|
||||||
|
fd = ospf->fd;
|
||||||
|
|
||||||
if (ospf->fd < 0 || ospf->oi_running == 0) {
|
if (fd < 0 || ospf->oi_running == 0) {
|
||||||
if (IS_DEBUG_OSPF_EVENT)
|
if (IS_DEBUG_OSPF_EVENT)
|
||||||
zlog_debug("%s failed to send, fd %d, instance %u",
|
zlog_debug("%s failed to send, fd %d, instance %u",
|
||||||
__func__, ospf->fd, ospf->oi_running);
|
__func__, fd, ospf->oi_running);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -657,6 +658,15 @@ static void ospf_write(struct event *thread)
|
|||||||
/* convenience - max OSPF data per packet */
|
/* convenience - max OSPF data per packet */
|
||||||
maxdatasize = oi->ifp->mtu - sizeof(struct ip);
|
maxdatasize = oi->ifp->mtu - sizeof(struct ip);
|
||||||
#endif /* WANT_OSPF_WRITE_FRAGMENT */
|
#endif /* WANT_OSPF_WRITE_FRAGMENT */
|
||||||
|
|
||||||
|
/* Reset socket fd to use. */
|
||||||
|
fd = ospf->fd;
|
||||||
|
|
||||||
|
/* Check for per-interface socket */
|
||||||
|
if (ospf->intf_socket_enabled &&
|
||||||
|
(IF_OSPF_IF_INFO(oi->ifp))->oii_fd > 0)
|
||||||
|
fd = (IF_OSPF_IF_INFO(oi->ifp))->oii_fd;
|
||||||
|
|
||||||
/* Get one packet from queue. */
|
/* Get one packet from queue. */
|
||||||
op = ospf_fifo_head(oi->obuf);
|
op = ospf_fifo_head(oi->obuf);
|
||||||
assert(op);
|
assert(op);
|
||||||
@ -664,8 +674,7 @@ static void ospf_write(struct event *thread)
|
|||||||
|
|
||||||
if (op->dst.s_addr == htonl(OSPF_ALLSPFROUTERS)
|
if (op->dst.s_addr == htonl(OSPF_ALLSPFROUTERS)
|
||||||
|| op->dst.s_addr == htonl(OSPF_ALLDROUTERS))
|
|| op->dst.s_addr == htonl(OSPF_ALLDROUTERS))
|
||||||
ospf_if_ipmulticast(ospf, oi->address,
|
ospf_if_ipmulticast(fd, oi->address, oi->ifp->ifindex);
|
||||||
oi->ifp->ifindex);
|
|
||||||
|
|
||||||
/* Rewrite the md5 signature & update the seq */
|
/* Rewrite the md5 signature & update the seq */
|
||||||
ospf_make_md5_digest(oi, op);
|
ospf_make_md5_digest(oi, op);
|
||||||
@ -760,13 +769,13 @@ static void ospf_write(struct event *thread)
|
|||||||
|
|
||||||
#ifdef WANT_OSPF_WRITE_FRAGMENT
|
#ifdef WANT_OSPF_WRITE_FRAGMENT
|
||||||
if (op->length > maxdatasize)
|
if (op->length > maxdatasize)
|
||||||
ospf_write_frags(ospf->fd, op, &iph, &msg, maxdatasize,
|
ospf_write_frags(fd, op, &iph, &msg, maxdatasize,
|
||||||
oi->ifp->mtu, flags, type);
|
oi->ifp->mtu, flags, type);
|
||||||
#endif /* WANT_OSPF_WRITE_FRAGMENT */
|
#endif /* WANT_OSPF_WRITE_FRAGMENT */
|
||||||
|
|
||||||
/* send final fragment (could be first) */
|
/* send final fragment (could be first) */
|
||||||
sockopt_iphdrincl_swab_htosys(&iph);
|
sockopt_iphdrincl_swab_htosys(&iph);
|
||||||
ret = sendmsg(ospf->fd, &msg, flags);
|
ret = sendmsg(fd, &msg, flags);
|
||||||
sockopt_iphdrincl_swab_systoh(&iph);
|
sockopt_iphdrincl_swab_systoh(&iph);
|
||||||
if (IS_DEBUG_OSPF_EVENT)
|
if (IS_DEBUG_OSPF_EVENT)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
|
@ -35,12 +35,11 @@
|
|||||||
#include "ospfd/ospf_spf.h"
|
#include "ospfd/ospf_spf.h"
|
||||||
#include "ospfd/ospf_route.h"
|
#include "ospfd/ospf_route.h"
|
||||||
#include "ospfd/ospf_zebra.h"
|
#include "ospfd/ospf_zebra.h"
|
||||||
/*#include "ospfd/ospf_routemap.h" */
|
|
||||||
#include "ospfd/ospf_vty.h"
|
#include "ospfd/ospf_vty.h"
|
||||||
#include "ospfd/ospf_dump.h"
|
#include "ospfd/ospf_dump.h"
|
||||||
#include "ospfd/ospf_bfd.h"
|
#include "ospfd/ospf_bfd.h"
|
||||||
#include "ospfd/ospf_ldp_sync.h"
|
#include "ospfd/ospf_ldp_sync.h"
|
||||||
|
#include "ospfd/ospf_network.h"
|
||||||
|
|
||||||
FRR_CFG_DEFAULT_BOOL(OSPF_LOG_ADJACENCY_CHANGES,
|
FRR_CFG_DEFAULT_BOOL(OSPF_LOG_ADJACENCY_CHANGES,
|
||||||
{ .val_bool = true, .match_profile = "datacenter", },
|
{ .val_bool = true, .match_profile = "datacenter", },
|
||||||
@ -12511,6 +12510,9 @@ static int ospf_config_write_one(struct vty *vty, struct ospf *ospf)
|
|||||||
if (ospf->fr_configured)
|
if (ospf->fr_configured)
|
||||||
vty_out(vty, " flood-reduction\n");
|
vty_out(vty, " flood-reduction\n");
|
||||||
|
|
||||||
|
if (!ospf->intf_socket_enabled)
|
||||||
|
vty_out(vty, " no socket-per-interface\n");
|
||||||
|
|
||||||
/* Redistribute information print. */
|
/* Redistribute information print. */
|
||||||
config_write_ospf_redistribute(vty, ospf);
|
config_write_ospf_redistribute(vty, ospf);
|
||||||
|
|
||||||
@ -13075,6 +13077,35 @@ DEFPY(ospf_socket_bufsizes,
|
|||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFPY (per_intf_socket,
|
||||||
|
per_intf_socket_cmd,
|
||||||
|
"[no] socket-per-interface",
|
||||||
|
NO_STR
|
||||||
|
"Use write socket per interface\n")
|
||||||
|
{
|
||||||
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
||||||
|
struct listnode *node;
|
||||||
|
struct ospf_interface *oi;
|
||||||
|
|
||||||
|
if (no) {
|
||||||
|
if (ospf->intf_socket_enabled) {
|
||||||
|
ospf->intf_socket_enabled = false;
|
||||||
|
|
||||||
|
/* Iterate and close any sockets */
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi))
|
||||||
|
ospf_ifp_sock_close(oi->ifp);
|
||||||
|
}
|
||||||
|
} else if (!ospf->intf_socket_enabled) {
|
||||||
|
ospf->intf_socket_enabled = true;
|
||||||
|
|
||||||
|
/* Iterate and open sockets */
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi))
|
||||||
|
ospf_ifp_sock_init(oi->ifp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
void ospf_vty_clear_init(void)
|
void ospf_vty_clear_init(void)
|
||||||
{
|
{
|
||||||
install_element(ENABLE_NODE, &clear_ip_ospf_interface_cmd);
|
install_element(ENABLE_NODE, &clear_ip_ospf_interface_cmd);
|
||||||
@ -13239,6 +13270,7 @@ void ospf_vty_init(void)
|
|||||||
install_element(OSPF_NODE, &no_flood_reduction_area_cmd);
|
install_element(OSPF_NODE, &no_flood_reduction_area_cmd);
|
||||||
|
|
||||||
install_element(OSPF_NODE, &ospf_socket_bufsizes_cmd);
|
install_element(OSPF_NODE, &ospf_socket_bufsizes_cmd);
|
||||||
|
install_element(OSPF_NODE, &per_intf_socket_cmd);
|
||||||
|
|
||||||
/* Init interface related vty commands. */
|
/* Init interface related vty commands. */
|
||||||
ospf_vty_if_init();
|
ospf_vty_if_init();
|
||||||
|
@ -419,6 +419,7 @@ struct ospf *ospf_new_alloc(unsigned short instance, const char *name)
|
|||||||
QOBJ_REG(new, ospf);
|
QOBJ_REG(new, ospf);
|
||||||
|
|
||||||
new->fd = -1;
|
new->fd = -1;
|
||||||
|
new->intf_socket_enabled = true;
|
||||||
|
|
||||||
new->recv_sock_bufsize = OSPF_DEFAULT_SOCK_BUFSIZE;
|
new->recv_sock_bufsize = OSPF_DEFAULT_SOCK_BUFSIZE;
|
||||||
new->send_sock_bufsize = OSPF_DEFAULT_SOCK_BUFSIZE;
|
new->send_sock_bufsize = OSPF_DEFAULT_SOCK_BUFSIZE;
|
||||||
|
@ -431,6 +431,9 @@ struct ospf {
|
|||||||
uint32_t recv_sock_bufsize;
|
uint32_t recv_sock_bufsize;
|
||||||
uint32_t send_sock_bufsize;
|
uint32_t send_sock_bufsize;
|
||||||
|
|
||||||
|
/* Per-interface write socket */
|
||||||
|
bool intf_socket_enabled;
|
||||||
|
|
||||||
QOBJ_FIELDS;
|
QOBJ_FIELDS;
|
||||||
};
|
};
|
||||||
DECLARE_QOBJ_TYPE(ospf);
|
DECLARE_QOBJ_TYPE(ospf);
|
||||||
|
Loading…
Reference in New Issue
Block a user