lib, zebra: Rework zebra_ns to be a bit more modular

The struct zebra_ns was littered throughout the code
base in a half-hazard fashion.  Gather up the references
and isolate the code a bit better.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Reviewed-by: Don Slice <dslice@cumulusnetworks.com>
Reviewed-by: Vivek Venkatraman <vivek@cumulusnetworks.com>
This commit is contained in:
Donald Sharp 2016-04-13 22:40:18 -04:00
parent 44e9909db4
commit fe18ee2d44
13 changed files with 238 additions and 115 deletions

View File

@ -83,6 +83,7 @@ struct memory_list memory_list_lib[] =
struct memory_list memory_list_zebra[] =
{
{ MTYPE_RTADV_PREFIX, "Router Advertisement Prefix" },
{ MTYPE_ZEBRA_NS, "Zebra Name Space" },
{ MTYPE_ZEBRA_VRF, "ZEBRA VRF" },
{ MTYPE_NEXTHOP, "Nexthop" },
{ MTYPE_RIB, "RIB" },

View File

@ -34,18 +34,20 @@ zebra_SOURCES = \
zserv.c main.c interface.c connected.c zebra_rib.c zebra_routemap.c \
redistribute.c debug.c rtadv.c zebra_snmp.c zebra_vty.c \
irdp_main.c irdp_interface.c irdp_packet.c router-id.c zebra_fpm.c \
$(othersrc) zebra_ptm.c zebra_rnh.c zebra_ptm_redistribute.c
$(othersrc) zebra_ptm.c zebra_rnh.c zebra_ptm_redistribute.c \
zebra_ns.c
testzebra_SOURCES = test_main.c zebra_rib.c interface.c connected.c debug.c \
zebra_vty.c zebra_ptm.c zebra_routemap.c \
zebra_vty.c zebra_ptm.c zebra_routemap.c zebra_ns.c \
kernel_null.c redistribute_null.c ioctl_null.c misc_null.c zebra_rnh_null.c \
zebra_ptm_null.c rtadv_null.c
zebra_ptm_null.c rtadv_null.c if_null.c
noinst_HEADERS = \
connected.h ioctl.h rib.h rt.h zserv.h redistribute.h debug.h rtadv.h \
interface.h ipforward.h irdp.h router-id.h kernel_socket.h \
rt_netlink.h zebra_fpm.h zebra_fpm_private.h zebra_rnh.h \
zebra_ptm_redistribute.h zebra_ptm.h zebra_routemap.h
zebra_ptm_redistribute.h zebra_ptm.h zebra_routemap.h \
zebra_ns.h
zebra_LDADD = $(otherobj) ../lib/libzebra.la $(LIBCAP) $(LIB_IPV6)

32
zebra/if_null.c Normal file
View File

@ -0,0 +1,32 @@
/*
* Copyright (C) 2015 Cumulus Networks, Inc.
* Donald Sharp
*
* This file is part of Quagga.
*
* Quagga is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* Quagga is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Quagga; see the file COPYING. If not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include <zebra.h>
#include <vrf.h>
#include <prefix.h>
#include <rtadv.h>
#include <zebra_ns.h>
void interface_list (struct zebra_ns *zns)
{ return; }

View File

@ -38,13 +38,14 @@
#include "zebra/rtadv.h"
#include "zebra/rib.h"
#include "zebra/zserv.h"
#include "zebra/zebra_ns.h"
#include "zebra/redistribute.h"
#include "zebra/debug.h"
#include "zebra/irdp.h"
#include "zebra/zebra_ptm.h"
#include "zebra/rt_netlink.h"
#include "zebra/zserv.h"
#include "zebra/interface.h"
#include "zebra/zebra_ns.h"
#define ZEBRA_PTM_SUPPORT
@ -56,8 +57,6 @@ const char *rtadv_pref_strs[] = { "medium", "high", "INVALID", "low", 0 };
static void if_down_del_nbr_connected (struct interface *ifp);
struct zebra_ns *dzns;
/* Called when new interface is added. */
static int
if_zebra_new_hook (struct interface *ifp)
@ -447,7 +446,7 @@ if_add_update (struct interface *ifp)
{
struct zebra_if *if_data;
if_link_per_ns(dzns, ifp);
if_link_per_ns(zebra_ns_lookup (NS_DEFAULT), ifp);
if_data = ifp->info;
if (if_data->multicast == IF_ZEBRA_MULTICAST_ON)

View File

@ -43,6 +43,7 @@
#include "zebra/rtadv.h"
#include "zebra/zebra_fpm.h"
#include "zebra/zebra_ptm.h"
#include "zebra/zebra_ns.h"
#include "zebra/redistribute.h"
#define ZEBRA_PTM_SUPPORT
@ -125,8 +126,6 @@ char config_default[] = SYSCONFDIR DEFAULT_CONFIG_FILE;
/* Process ID saved for use by init system */
const char *pid_file = PATH_ZEBRA_PID;
static int zebra_ns_disable (ns_id_t ns_id, void **info);
/* Help information display. */
static void
usage (char *progname, int status)
@ -179,6 +178,8 @@ sighup (void)
static void
sigint (void)
{
struct zebra_ns *zns;
zlog_notice ("Terminating on signal");
if (!retain_mode)
@ -188,7 +189,9 @@ sigint (void)
#endif
zebra_ptm_finish();
zebra_ns_disable (0, (void **)&dzns);
zns = zebra_ns_lookup (NS_DEFAULT);
zebra_ns_disable (0, (void **)&zns);
systemd_send_stopping();
exit (0);
}
@ -231,7 +234,7 @@ zebra_vrf_new (vrf_id_t vrf_id, const char *name, void **info)
if (! zvrf)
{
zvrf = zebra_vrf_alloc (vrf_id, name);
zvrf->zns = dzns; /* Point to the global (single) NS */
zvrf->zns = zebra_ns_lookup (NS_DEFAULT); /* Point to the global (single) NS */
*info = (void *)zvrf;
router_id_init (zvrf);
}
@ -239,36 +242,6 @@ zebra_vrf_new (vrf_id_t vrf_id, const char *name, void **info)
return 0;
}
static int
zebra_ns_enable (ns_id_t ns_id, void **info)
{
struct zebra_ns *zns = (struct zebra_ns *) (*info);
#ifdef HAVE_NETLINK
char nl_name[64];
#endif
#if defined (HAVE_RTADV)
rtadv_init (zns);
#endif
#ifdef HAVE_NETLINK
/* Initialize netlink sockets */
snprintf (nl_name, 64, "netlink-listen (NS %u)", ns_id);
zns->netlink.sock = -1;
zns->netlink.name = XSTRDUP (MTYPE_NETLINK_NAME, nl_name);
snprintf (nl_name, 64, "netlink-cmd (NS %u)", ns_id);
zns->netlink_cmd.sock = -1;
zns->netlink_cmd.name = XSTRDUP (MTYPE_NETLINK_NAME, nl_name);
#endif
zns->if_table = route_table_init ();
kernel_init (zns);
interface_list (zns);
route_read (zns);
return 0;
}
/* Callback upon enabling a VRF. */
static int
zebra_vrf_enable (vrf_id_t vrf_id, const char *name, void **info)
@ -282,20 +255,6 @@ zebra_vrf_enable (vrf_id_t vrf_id, const char *name, void **info)
return 0;
}
static int
zebra_ns_disable (ns_id_t ns_id, void **info)
{
struct zebra_ns *zns = (struct zebra_ns *) (*info);
#if defined (HAVE_RTADV)
rtadv_terminate (zns);
#endif
kernel_terminate (zns);
return 0;
}
/* Callback upon disabling a VRF. */
static int
zebra_vrf_disable (vrf_id_t vrf_id, const char *name, void **info)
@ -330,23 +289,15 @@ zebra_vrf_delete (vrf_id_t vrf_id, const char *name, void **info)
}
/* Zebra VRF initialization. */
static void
void
zebra_vrf_init (void)
{
struct zebra_ns *zns;
vrf_add_hook (VRF_NEW_HOOK, zebra_vrf_new);
vrf_add_hook (VRF_ENABLE_HOOK, zebra_vrf_enable);
vrf_add_hook (VRF_DISABLE_HOOK, zebra_vrf_disable);
vrf_add_hook (VRF_DELETE_HOOK, zebra_vrf_delete);
/* Default NS initialization */
zns = XCALLOC (MTYPE_ZEBRA_VRF, sizeof (struct zebra_ns));
dzns = zns; //Pending: Doing it all for the default namespace only for now.
vrf_init ();
zebra_ns_enable (0, (void **)&zns);
}
/* Main startup routine. */
@ -490,8 +441,8 @@ main (int argc, char **argv)
/* For debug purpose. */
/* SET_FLAG (zebra_debug_event, ZEBRA_DEBUG_EVENT); */
/* Initialize VRF module, and make kernel routing socket. */
zebra_vrf_init ();
/* Initialize NS( and implicitly the VRF module), and make kernel routing socket. */
zebra_ns_init ();
#ifdef HAVE_SNMP
zebra_snmp_init ();

View File

@ -273,41 +273,6 @@ struct rtadv
};
#endif /* HAVE_RTADV */
#ifdef HAVE_NETLINK
/* Socket interface to kernel */
struct nlsock
{
int sock;
int seq;
struct sockaddr_nl snl;
const char *name;
};
#endif
/* NetNS ID type. */
typedef u_int16_t ns_id_t;
struct zebra_ns
{
/* net-ns name. */
char name[VRF_NAMSIZ];
/* Identifier. */
ns_id_t ns_id;
#ifdef HAVE_NETLINK
struct nlsock netlink; /* kernel messages */
struct nlsock netlink_cmd; /* command channel */
struct thread *t_netlink;
#endif
struct route_table *if_table;
#if defined (HAVE_RTADV)
struct rtadv rtadv;
#endif /* HAVE_RTADV */
};
/* Routing table instance. */
struct zebra_vrf
{
@ -359,8 +324,6 @@ struct zebra_vrf
struct zebra_ns *zns;
};
extern struct zebra_ns *dzns;
/*
* rib_table_info_t
*
@ -436,6 +399,7 @@ extern struct nexthop *rib_nexthop_ipv6_ifindex_add (struct rib *rib,
struct in6_addr *ipv6,
unsigned int ifindex);
extern void zebra_vrf_init (void);
extern struct zebra_vrf *zebra_vrf_lookup (vrf_id_t vrf_id);
extern struct zebra_vrf *zebra_vrf_alloc (vrf_id_t, const char *);
extern struct route_table *zebra_vrf_table (afi_t, safi_t, vrf_id_t);

View File

@ -40,6 +40,7 @@
#include "vrf.h"
#include "zebra/zserv.h"
#include "zebra/zebra_ns.h"
#include "zebra/rt.h"
#include "zebra/redistribute.h"
#include "zebra/interface.h"
@ -74,8 +75,9 @@ static void
set_ifindex(struct interface *ifp, unsigned int ifi_index)
{
struct interface *oifp;
struct zebra_ns *zns = zebra_ns_lookup (NS_DEFAULT);
if (((oifp = if_lookup_by_index_per_ns (dzns, ifi_index)) != NULL) && (oifp != ifp))
if (((oifp = if_lookup_by_index_per_ns (zns, ifi_index)) != NULL) && (oifp != ifp))
{
if (ifi_index == IFINDEX_INTERNAL)
zlog_err("Netlink is setting interface %s ifindex to reserved "
@ -724,7 +726,7 @@ netlink_interface_addr (struct sockaddr_nl *snl, struct nlmsghdr *h,
memset (tb, 0, sizeof tb);
netlink_parse_rtattr (tb, IFA_MAX, IFA_RTA (ifa), len);
ifp = if_lookup_by_index_per_ns (dzns, ifa->ifa_index);
ifp = if_lookup_by_index_per_ns (zebra_ns_lookup (ns_id), ifa->ifa_index);
if (ifp == NULL)
{
zlog_err ("netlink_interface_addr can't find interface by index %d vrf %u",
@ -1313,7 +1315,7 @@ netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
}
/* See if interface is present. */
ifp = if_lookup_by_index_per_ns (dzns, ifi->ifi_index);
ifp = if_lookup_by_index_per_ns (zebra_ns_lookup (NS_DEFAULT), ifi->ifi_index);
if (h->nlmsg_type == RTM_NEWLINK)
{
@ -1666,7 +1668,7 @@ netlink_route (int cmd, int family, void *dest, int length, void *gate,
struct sockaddr_nl snl;
int discard;
struct zebra_ns *zns = dzns;
struct zebra_ns *zns = zebra_ns_lookup (NS_DEFAULT);
struct
{
@ -2053,7 +2055,7 @@ netlink_neigh_update (int cmd, int ifindex, __u32 addr, char *lla, int llalen)
char buf[256];
} req;
struct zebra_ns *zns = dzns;
struct zebra_ns *zns = zebra_ns_lookup (NS_DEFAULT);
memset(&req.n, 0, sizeof(req.n));
memset(&req.ndm, 0, sizeof(req.ndm));
@ -2095,7 +2097,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
char buf[NL_PKT_BUF_SIZE];
} req;
struct zebra_ns *zns = dzns;
struct zebra_ns *zns = zebra_ns_lookup (NS_DEFAULT);
struct zebra_vrf *zvrf = vrf_info_lookup (rib->vrf_id);
memset (&req, 0, sizeof req - NL_PKT_BUF_SIZE);
@ -2425,7 +2427,7 @@ netlink_address (int cmd, int family, struct interface *ifp,
char buf[NL_PKT_BUF_SIZE];
} req;
struct zebra_ns *zns = dzns; //vrf_info_lookup (ifp->vrf_id);
struct zebra_ns *zns = zebra_ns_lookup (NS_DEFAULT);
p = ifc->address;
memset (&req, 0, sizeof req - NL_PKT_BUF_SIZE);

View File

@ -38,6 +38,7 @@
#include "zebra/debug.h"
#include "zebra/rib.h"
#include "zebra/zserv.h"
#include "zebra/zebra_ns.h"
extern struct zebra_privs_t zserv_privs;

View File

@ -22,6 +22,13 @@
#include <zebra.h>
#include <lib/prefix.h>
#include <rtadv.h>
#include <zebra_ns.h>
void ipv6_nd_suppress_ra_set (struct interface *ifp, ipv6_nd_suppress_ra_status status)
{ return; }
void rtadv_init (struct zebra_ns *zns)
{ return; }
void rtadv_terminate (struct zebra_ns *zns)
{ return; }

View File

@ -253,7 +253,7 @@ zebra_vrf_disable (vrf_id_t vrf_id, const char *name, void **info)
}
/* Zebra VRF initialization. */
static void
void
zebra_vrf_init (void)
{
vrf_add_hook (VRF_NEW_HOOK, zebra_vrf_new);

93
zebra/zebra_ns.c Normal file
View File

@ -0,0 +1,93 @@
/* zebra NS Routines
* Copyright (C) 2016 Cumulus Networks, Inc.
* Donald Sharp
*
* This file is part of Quagga.
*
* Quagga is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* Quagga is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Quagga; see the file COPYING. If not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include "zebra.h"
#include "lib/vrf.h"
#include "lib/prefix.h"
#include "lib/memory.h"
#include "rtadv.h"
#include "zebra_ns.h"
struct zebra_ns *dzns;
struct zebra_ns *
zebra_ns_lookup (ns_id_t ns_id)
{
return dzns;
}
int
zebra_ns_enable (ns_id_t ns_id, void **info)
{
struct zebra_ns *zns = (struct zebra_ns *) (*info);
#ifdef HAVE_NETLINK
char nl_name[64];
#endif
#if defined (HAVE_RTADV)
rtadv_init (zns);
#endif
#ifdef HAVE_NETLINK
/* Initialize netlink sockets */
snprintf (nl_name, 64, "netlink-listen (NS %u)", ns_id);
zns->netlink.sock = -1;
zns->netlink.name = XSTRDUP (MTYPE_NETLINK_NAME, nl_name);
snprintf (nl_name, 64, "netlink-cmd (NS %u)", ns_id);
zns->netlink_cmd.sock = -1;
zns->netlink_cmd.name = XSTRDUP (MTYPE_NETLINK_NAME, nl_name);
#endif
zns->if_table = route_table_init ();
kernel_init (zns);
interface_list (zns);
route_read (zns);
return 0;
}
int
zebra_ns_disable (ns_id_t ns_id, void **info)
{
struct zebra_ns *zns = (struct zebra_ns *) (*info);
#if defined (HAVE_RTADV)
rtadv_terminate (zns);
#endif
kernel_terminate (zns);
return 0;
}
int
zebra_ns_init (void)
{
dzns = XCALLOC (MTYPE_ZEBRA_NS, sizeof (struct zebra_ns));
zebra_vrf_init ();
zebra_ns_enable (0, (void **)&dzns);
return 0;
}

69
zebra/zebra_ns.h Normal file
View File

@ -0,0 +1,69 @@
/*
* Zebra NS header
* Copyright (C) 2016 Cumulus Networks, Inc.
* Donald Sharp
*
* This file is part of Quagga.
*
* Quagga is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* Quagga is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Quagga; see the file COPYING. If not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#if !defined(__ZEBRA_NS_H__)
#define __ZEBRA_NS_H__
#ifdef HAVE_NETLINK
/* Socket interface to kernel */
struct nlsock
{
int sock;
int seq;
struct sockaddr_nl snl;
const char *name;
};
#endif
/* NetNS ID type. */
typedef u_int16_t ns_id_t;
struct zebra_ns
{
/* net-ns name. */
char name[VRF_NAMSIZ];
/* Identifier. */
ns_id_t ns_id;
#ifdef HAVE_NETLINK
struct nlsock netlink; /* kernel messages */
struct nlsock netlink_cmd; /* command channel */
struct thread *t_netlink;
#endif
struct route_table *if_table;
#if defined (HAVE_RTADV)
struct rtadv rtadv;
#endif /* HAVE_RTADV */
};
#define NS_DEFAULT 0
#define NS_UNKNOWN UINT16_MAX
struct zebra_ns *zebra_ns_lookup (ns_id_t ns_id);
int zebra_ns_init (void);
int zebra_ns_enable (ns_id_t ns_id, void **info);
int zebra_ns_disable (ns_id_t ns_id, void **info);
#endif

View File

@ -41,6 +41,7 @@
#include "zebra/rib.h"
#include "zebra/rt.h"
#include "zebra/zserv.h"
#include "zebra/zebra_ns.h"
#include "zebra/redistribute.h"
#include "zebra/debug.h"
#include "zebra/zebra_rnh.h"
@ -907,6 +908,7 @@ static void
print_nh (struct nexthop *nexthop, struct vty *vty)
{
char buf[BUFSIZ];
struct zebra_ns *zns = zebra_ns_lookup (NS_DEFAULT);
switch (nexthop->type)
{
@ -914,18 +916,18 @@ print_nh (struct nexthop *nexthop, struct vty *vty)
case NEXTHOP_TYPE_IPV4_IFINDEX:
vty_out (vty, " via %s", inet_ntoa (nexthop->gate.ipv4));
if (nexthop->ifindex)
vty_out (vty, ", %s", ifindex2ifname_per_ns (dzns, nexthop->ifindex));
vty_out (vty, ", %s", ifindex2ifname_per_ns (zns, nexthop->ifindex));
break;
case NEXTHOP_TYPE_IPV6:
case NEXTHOP_TYPE_IPV6_IFINDEX:
vty_out (vty, " %s",
inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
if (nexthop->ifindex)
vty_out (vty, ", via %s", ifindex2ifname_per_ns (dzns, nexthop->ifindex));
vty_out (vty, ", via %s", ifindex2ifname_per_ns (zns, nexthop->ifindex));
break;
case NEXTHOP_TYPE_IFINDEX:
vty_out (vty, " is directly connected, %s",
ifindex2ifname_per_ns (dzns, nexthop->ifindex));
ifindex2ifname_per_ns (zns, nexthop->ifindex));
break;
case NEXTHOP_TYPE_BLACKHOLE:
vty_out (vty, " is directly connected, Null0");