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

View file

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

View file

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

View file

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

View file

@ -29,6 +29,7 @@
#include "thread.h" #include "thread.h"
#include "command.h" #include "command.h"
#include "defaults.h" #include "defaults.h"
#include "lib_errors.h"
#include "ospf6_proto.h" #include "ospf6_proto.h"
#include "ospf6_message.h" #include "ospf6_message.h"
@ -41,6 +42,7 @@
#include "ospf6_area.h" #include "ospf6_area.h"
#include "ospf6_interface.h" #include "ospf6_interface.h"
#include "ospf6_neighbor.h" #include "ospf6_neighbor.h"
#include "ospf6_network.h"
#include "ospf6_flood.h" #include "ospf6_flood.h"
#include "ospf6_asbr.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); 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 ospf6 *o;
struct vrf *vrf = NULL;
o = XCALLOC(MTYPE_OSPF6_TOP, sizeof(struct ospf6)); 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 */ /* initialize */
monotime(&o->starttime); monotime(&o->starttime);
o->vrf_id = vrf_id;
o->area_list = list_new(); o->area_list = list_new();
o->area_list->cmp = ospf6_area_cmp; o->area_list->cmp = ospf6_area_cmp;
o->lsdb = ospf6_lsdb_create(o); 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->ref_bandwidth = OSPF6_REFERENCE_BANDWIDTH;
o->distance_table = route_table_init(); o->distance_table = route_table_init();
o->fd = -1;
QOBJ_REG(o, ospf6); QOBJ_REG(o, ospf6);
/* Make ospf protocol socket. */
ospf6_serv_sock(o);
return 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) void ospf6_delete(struct ospf6 *o)
{ {
struct listnode *node, *nnode; struct listnode *node, *nnode;
@ -217,6 +241,7 @@ void ospf6_delete(struct ospf6 *o)
ospf6_distance_reset(o); ospf6_distance_reset(o);
route_table_finish(o->distance_table); route_table_finish(o->distance_table);
XFREE(MTYPE_OSPF6_TOP, o->name);
XFREE(MTYPE_OSPF6_TOP, o); 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_spf_calc);
THREAD_OFF(o->t_ase_calc); THREAD_OFF(o->t_ase_calc);
THREAD_OFF(o->t_distribute_update); THREAD_OFF(o->t_distribute_update);
THREAD_OFF(o->t_ospf6_receive);
} }
} }
@ -325,14 +351,9 @@ DEFUN_NOSH (router_ospf6,
ROUTER_STR ROUTER_STR
OSPF6_STR) OSPF6_STR)
{ {
if (ospf6 == NULL) { if (ospf6 == NULL)
ospf6 = ospf6_create(VRF_DEFAULT); ospf6_instance_create(VRF_DEFAULT_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();
}
/* set current ospf point. */ /* set current ospf point. */
VTY_PUSH_CONTEXT(OSPF6_NODE, ospf6); VTY_PUSH_CONTEXT(OSPF6_NODE, ospf6);
@ -350,6 +371,7 @@ DEFUN (no_router_ospf6,
if (ospf6 == NULL) if (ospf6 == NULL)
vty_out(vty, "OSPFv3 is not configured\n"); vty_out(vty, "OSPFv3 is not configured\n");
else { else {
ospf6_serv_close(&ospf6->fd);
ospf6_delete(ospf6); ospf6_delete(ospf6);
ospf6 = NULL; ospf6 = NULL;
} }

View file

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

View file

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