mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-28 17:42:20 +00:00
Merge pull request #7058 from Niral-Networks/niral_dev_vrf_ospf6
ospf6d : Socket change for ospf6d vrf support.
This commit is contained in:
commit
bd407b54d2
@ -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();
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user