Merge pull request #7058 from Niral-Networks/niral_dev_vrf_ospf6

ospf6d : Socket change for ospf6d vrf support.
This commit is contained in:
Rafael Zalamena 2020-10-07 12:07:09 -03:00 committed by GitHub
commit bd407b54d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 94 additions and 46 deletions

View File

@ -55,7 +55,7 @@
#define OSPF6_VTY_PORT 2606
/* ospf6d privileges */
zebra_capabilities_t _caps_p[] = {ZCAP_NET_RAW, ZCAP_BIND};
zebra_capabilities_t _caps_p[] = {ZCAP_NET_RAW, ZCAP_BIND, ZCAP_SYS_ADMIN};
struct zebra_privs_t ospf6d_privs = {
#if defined(FRR_USER)
@ -68,7 +68,7 @@ struct zebra_privs_t ospf6d_privs = {
.vty_group = VTY_GROUP,
#endif
.caps_p = _caps_p,
.cap_num_p = 2,
.cap_num_p = array_size(_caps_p),
.cap_num_i = 0};
/* ospf6d options, we use GNU getopt library. */
@ -86,6 +86,7 @@ static void __attribute__((noreturn)) ospf6_exit(int status)
if (ospf6) {
vrf = vrf_lookup_by_id(ospf6->vrf_id);
ospf6_serv_close(&ospf6->fd);
ospf6_delete(ospf6);
ospf6 = NULL;
} else
@ -101,7 +102,6 @@ static void __attribute__((noreturn)) ospf6_exit(int status)
ospf6_asbr_terminate();
ospf6_lsa_terminate();
ospf6_serv_close();
/* reverse access_list_init */
access_list_reset();

View File

@ -1532,10 +1532,14 @@ int ospf6_receive(struct thread *thread)
struct iovec iovector[2];
struct ospf6_interface *oi;
struct ospf6_header *oh;
struct ospf6 *ospf6;
/* add next read thread */
ospf6 = THREAD_ARG(thread);
sockfd = THREAD_FD(thread);
thread_add_read(master, ospf6_receive, NULL, sockfd, NULL);
thread_add_read(master, ospf6_receive, ospf6, ospf6->fd,
&ospf6->t_ospf6_receive);
/* initialize */
memset(&src, 0, sizeof(src));
@ -1548,7 +1552,7 @@ int ospf6_receive(struct thread *thread)
iovector[1].iov_len = 0;
/* receive message */
len = ospf6_recvmsg(&src, &dst, &ifindex, iovector);
len = ospf6_recvmsg(&src, &dst, &ifindex, iovector, sockfd);
if (len > iobuflen) {
flog_err(EC_LIB_DEVELOPMENT, "Excess message read");
return 0;
@ -1696,9 +1700,13 @@ static void ospf6_send(struct in6_addr *src, struct in6_addr *dst,
}
/* send message */
len = ospf6_sendmsg(src, dst, &oi->interface->ifindex, iovector);
if (len != ntohs(oh->length))
flog_err(EC_LIB_DEVELOPMENT, "Could not send entire message");
if (oi->area->ospf6->fd != -1) {
len = ospf6_sendmsg(src, dst, &oi->interface->ifindex, iovector,
oi->area->ospf6->fd);
if (len != ntohs(oh->length))
flog_err(EC_LIB_DEVELOPMENT,
"Could not send entire message");
}
}
static uint32_t ospf6_packet_max(struct ospf6_interface *oi)

View File

@ -26,18 +26,19 @@
#include "sockopt.h"
#include "privs.h"
#include "lib_errors.h"
#include "vrf.h"
#include "libospf.h"
#include "ospf6_proto.h"
#include "ospf6_network.h"
#include "ospf6d.h"
#include "ospf6_top.h"
int ospf6_sock;
struct in6_addr allspfrouters6;
struct in6_addr alldrouters6;
/* setsockopt MulticastLoop to off */
static void ospf6_reset_mcastloop(void)
static void ospf6_reset_mcastloop(int ospf6_sock)
{
unsigned int off = 0;
if (setsockopt(ospf6_sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &off,
@ -47,19 +48,19 @@ static void ospf6_reset_mcastloop(void)
safe_strerror(errno));
}
static void ospf6_set_pktinfo(void)
static void ospf6_set_pktinfo(int ospf6_sock)
{
setsockopt_ipv6_pktinfo(ospf6_sock, 1);
}
static void ospf6_set_transport_class(void)
static void ospf6_set_transport_class(int ospf6_sock)
{
#ifdef IPTOS_PREC_INTERNETCONTROL
setsockopt_ipv6_tclass(ospf6_sock, IPTOS_PREC_INTERNETCONTROL);
#endif
}
static void ospf6_set_checksum(void)
static void ospf6_set_checksum(int ospf6_sock)
{
int offset = 12;
#ifndef DISABLE_IPV6_CHECKSUM
@ -73,21 +74,30 @@ static void ospf6_set_checksum(void)
#endif /* DISABLE_IPV6_CHECKSUM */
}
void ospf6_serv_close(void)
void ospf6_serv_close(int *ospf6_sock)
{
if (ospf6_sock > 0) {
close(ospf6_sock);
ospf6_sock = -1;
if (*ospf6_sock != -1) {
close(*ospf6_sock);
*ospf6_sock = -1;
return;
}
}
/* Make ospf6d's server socket. */
int ospf6_serv_sock(void)
int ospf6_serv_sock(struct ospf6 *ospf6)
{
int ospf6_sock;
if (ospf6->fd != -1)
return -1;
if (ospf6->vrf_id == VRF_UNKNOWN)
return -1;
frr_with_privs(&ospf6d_privs) {
ospf6_sock = socket(AF_INET6, SOCK_RAW, IPPROTO_OSPFIGP);
ospf6_sock = vrf_socket(AF_INET6, SOCK_RAW, IPPROTO_OSPFIGP,
ospf6->vrf_id, ospf6->name);
if (ospf6_sock < 0) {
zlog_warn("Network: can't create OSPF6 socket.");
return -1;
@ -100,11 +110,12 @@ int ospf6_serv_sock(void)
#else
ospf6_set_reuseaddr();
#endif /*1*/
ospf6_reset_mcastloop();
ospf6_set_pktinfo();
ospf6_set_transport_class();
ospf6_set_checksum();
ospf6_reset_mcastloop(ospf6_sock);
ospf6_set_pktinfo(ospf6_sock);
ospf6_set_transport_class(ospf6_sock);
ospf6_set_checksum(ospf6_sock);
ospf6->fd = ospf6_sock;
/* setup global in6_addr, allspf6 and alldr6 for later use */
inet_pton(AF_INET6, ALLSPFROUTERS6, &allspfrouters6);
inet_pton(AF_INET6, ALLDROUTERS6, &alldrouters6);
@ -119,11 +130,14 @@ int ospf6_sso(ifindex_t ifindex, struct in6_addr *group, int option)
int ret;
int bufsize = (8 * 1024 * 1024);
if (ospf6->fd == -1)
return -1;
assert(ifindex);
mreq6.ipv6mr_interface = ifindex;
memcpy(&mreq6.ipv6mr_multiaddr, group, sizeof(struct in6_addr));
ret = setsockopt(ospf6_sock, IPPROTO_IPV6, option, &mreq6,
ret = setsockopt(ospf6->fd, IPPROTO_IPV6, option, &mreq6,
sizeof(mreq6));
if (ret < 0) {
flog_err_sys(
@ -133,8 +147,8 @@ int ospf6_sso(ifindex_t ifindex, struct in6_addr *group, int option)
return ret;
}
setsockopt_so_sendbuf(ospf6_sock, bufsize);
setsockopt_so_recvbuf(ospf6_sock, bufsize);
setsockopt_so_sendbuf(ospf6->fd, bufsize);
setsockopt_so_recvbuf(ospf6->fd, bufsize);
return 0;
}
@ -157,7 +171,7 @@ static int iov_totallen(struct iovec *iov)
}
int ospf6_sendmsg(struct in6_addr *src, struct in6_addr *dst,
ifindex_t *ifindex, struct iovec *message)
ifindex_t *ifindex, struct iovec *message, int ospf6_sock)
{
int retval;
struct msghdr smsghdr;
@ -216,7 +230,7 @@ int ospf6_sendmsg(struct in6_addr *src, struct in6_addr *dst,
}
int ospf6_recvmsg(struct in6_addr *src, struct in6_addr *dst,
ifindex_t *ifindex, struct iovec *message)
ifindex_t *ifindex, struct iovec *message, int ospf6_sock)
{
int retval;
struct msghdr rmsghdr;

View File

@ -21,17 +21,17 @@
#ifndef OSPF6_NETWORK_H
#define OSPF6_NETWORK_H
extern int ospf6_sock;
struct ospf6 *ospf6;
extern struct in6_addr allspfrouters6;
extern struct in6_addr alldrouters6;
extern int ospf6_serv_sock(void);
extern void ospf6_serv_close(void);
extern int ospf6_serv_sock(struct ospf6 *ospf6);
extern void ospf6_serv_close(int *ospf6_sock);
extern int ospf6_sso(ifindex_t ifindex, struct in6_addr *group, int option);
extern int ospf6_sendmsg(struct in6_addr *, struct in6_addr *, ifindex_t *,
struct iovec *);
struct iovec *, int ospf6_sock);
extern int ospf6_recvmsg(struct in6_addr *, struct in6_addr *, ifindex_t *,
struct iovec *);
struct iovec *, int ospf6_sock);
#endif /* OSPF6_NETWORK_H */

View File

@ -29,6 +29,7 @@
#include "thread.h"
#include "command.h"
#include "defaults.h"
#include "lib_errors.h"
#include "ospf6_proto.h"
#include "ospf6_message.h"
@ -41,6 +42,7 @@
#include "ospf6_area.h"
#include "ospf6_interface.h"
#include "ospf6_neighbor.h"
#include "ospf6_network.h"
#include "ospf6_flood.h"
#include "ospf6_asbr.h"
@ -141,15 +143,21 @@ static void ospf6_top_brouter_hook_remove(struct ospf6_route *route)
ospf6_abr_originate_summary(route);
}
static struct ospf6 *ospf6_create(vrf_id_t vrf_id)
static struct ospf6 *ospf6_create(const char *name)
{
struct ospf6 *o;
struct vrf *vrf = NULL;
o = XCALLOC(MTYPE_OSPF6_TOP, sizeof(struct ospf6));
vrf = vrf_lookup_by_name(name);
if (vrf) {
o->vrf_id = vrf->vrf_id;
/* Freed in ospf6_delete */
o->name = XSTRDUP(MTYPE_OSPF6_TOP, name);
}
/* initialize */
monotime(&o->starttime);
o->vrf_id = vrf_id;
o->area_list = list_new();
o->area_list->cmp = ospf6_area_cmp;
o->lsdb = ospf6_lsdb_create(o);
@ -183,12 +191,28 @@ static struct ospf6 *ospf6_create(vrf_id_t vrf_id)
o->ref_bandwidth = OSPF6_REFERENCE_BANDWIDTH;
o->distance_table = route_table_init();
o->fd = -1;
QOBJ_REG(o, ospf6);
/* Make ospf protocol socket. */
ospf6_serv_sock(o);
return o;
}
void ospf6_instance_create(const char *name)
{
ospf6 = ospf6_create(name);
if (DFLT_OSPF6_LOG_ADJACENCY_CHANGES)
SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
if (ospf6->router_id == 0)
ospf6_router_id_update();
thread_add_read(master, ospf6_receive, ospf6, ospf6->fd,
&ospf6->t_ospf6_receive);
}
void ospf6_delete(struct ospf6 *o)
{
struct listnode *node, *nnode;
@ -217,6 +241,7 @@ void ospf6_delete(struct ospf6 *o)
ospf6_distance_reset(o);
route_table_finish(o->distance_table);
XFREE(MTYPE_OSPF6_TOP, o->name);
XFREE(MTYPE_OSPF6_TOP, o);
}
@ -242,6 +267,7 @@ static void ospf6_disable(struct ospf6 *o)
THREAD_OFF(o->t_spf_calc);
THREAD_OFF(o->t_ase_calc);
THREAD_OFF(o->t_distribute_update);
THREAD_OFF(o->t_ospf6_receive);
}
}
@ -325,14 +351,9 @@ DEFUN_NOSH (router_ospf6,
ROUTER_STR
OSPF6_STR)
{
if (ospf6 == NULL) {
ospf6 = ospf6_create(VRF_DEFAULT);
if (DFLT_OSPF6_LOG_ADJACENCY_CHANGES)
SET_FLAG(ospf6->config_flags,
OSPF6_LOG_ADJACENCY_CHANGES);
if (ospf6->router_id == 0)
ospf6_router_id_update();
}
if (ospf6 == NULL)
ospf6_instance_create(VRF_DEFAULT_NAME);
/* set current ospf point. */
VTY_PUSH_CONTEXT(OSPF6_NODE, ospf6);
@ -350,6 +371,7 @@ DEFUN (no_router_ospf6,
if (ospf6 == NULL)
vty_out(vty, "OSPFv3 is not configured\n");
else {
ospf6_serv_close(&ospf6->fd);
ospf6_delete(ospf6);
ospf6 = NULL;
}

View File

@ -40,6 +40,8 @@ struct ospf6 {
/* The relevant vrf_id */
vrf_id_t vrf_id;
char *name; /* VRF name */
/* my router id */
in_addr_t router_id;
@ -92,11 +94,13 @@ struct ospf6 {
struct timeval ts_spf_duration; /* Execution time of last SPF */
unsigned int last_spf_reason; /* Last SPF reason */
int fd;
/* Threads */
struct thread *t_spf_calc; /* SPF calculation timer. */
struct thread *t_ase_calc; /* ASE calculation timer. */
struct thread *maxage_remover;
struct thread *t_distribute_update; /* Distirbute update timer. */
struct thread *t_ospf6_receive; /* OSPF6 receive timer */
uint32_t ref_bandwidth;
@ -130,5 +134,6 @@ extern void ospf6_delete(struct ospf6 *o);
extern void ospf6_router_id_update(void);
extern void ospf6_maxage_remove(struct ospf6 *o);
extern void ospf6_instance_create(const char *name);
#endif /* OSPF6_TOP_H */

View File

@ -1268,9 +1268,8 @@ void ospf6_init(void)
&show_ipv6_ospf6_database_type_self_originated_linkstate_id_cmd);
install_element(VIEW_NODE, &show_ipv6_ospf6_database_aggr_router_cmd);
/* Make ospf protocol socket. */
ospf6_serv_sock();
thread_add_read(master, ospf6_receive, NULL, ospf6_sock, NULL);
if (ospf6 == NULL)
ospf6_instance_create(VRF_DEFAULT_NAME);
}
void ospf6_clean(void)