From fe18ee2d44027e0d1933b462868a938005174259 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 13 Apr 2016 22:40:18 -0400 Subject: [PATCH] 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 Reviewed-by: Don Slice Reviewed-by: Vivek Venkatraman --- lib/memtypes.c | 1 + zebra/Makefile.am | 10 +++-- zebra/if_null.c | 32 ++++++++++++++++ zebra/interface.c | 7 ++-- zebra/main.c | 69 +++++----------------------------- zebra/rib.h | 38 +------------------ zebra/rt_netlink.c | 16 ++++---- zebra/rtadv.c | 1 + zebra/rtadv_null.c | 7 ++++ zebra/test_main.c | 2 +- zebra/zebra_ns.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++ zebra/zebra_ns.h | 69 ++++++++++++++++++++++++++++++++++ zebra/zebra_rnh.c | 8 ++-- 13 files changed, 238 insertions(+), 115 deletions(-) create mode 100644 zebra/if_null.c create mode 100644 zebra/zebra_ns.c create mode 100644 zebra/zebra_ns.h diff --git a/lib/memtypes.c b/lib/memtypes.c index cfb969f531..d77ba0e97a 100644 --- a/lib/memtypes.c +++ b/lib/memtypes.c @@ -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" }, diff --git a/zebra/Makefile.am b/zebra/Makefile.am index dbefb8176c..e4b6b792ca 100644 --- a/zebra/Makefile.am +++ b/zebra/Makefile.am @@ -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) diff --git a/zebra/if_null.c b/zebra/if_null.c new file mode 100644 index 0000000000..2ccea56c81 --- /dev/null +++ b/zebra/if_null.c @@ -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 + +#include +#include + +#include +#include + +void interface_list (struct zebra_ns *zns) +{ return; } diff --git a/zebra/interface.c b/zebra/interface.c index df6848f05a..1fff39da4c 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -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) diff --git a/zebra/main.c b/zebra/main.c index 5da91042d3..c1a2c69021 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -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 (); diff --git a/zebra/rib.h b/zebra/rib.h index 431389cf3c..662bb697a3 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -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); diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 9f8b96b6e5..7756f76358 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -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); diff --git a/zebra/rtadv.c b/zebra/rtadv.c index af8a32d92a..233d600734 100644 --- a/zebra/rtadv.c +++ b/zebra/rtadv.c @@ -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; diff --git a/zebra/rtadv_null.c b/zebra/rtadv_null.c index d4678d5751..851c8e0a64 100644 --- a/zebra/rtadv_null.c +++ b/zebra/rtadv_null.c @@ -22,6 +22,13 @@ #include #include #include +#include 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; } diff --git a/zebra/test_main.c b/zebra/test_main.c index 6639bc3499..8fbf39951c 100644 --- a/zebra/test_main.c +++ b/zebra/test_main.c @@ -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); diff --git a/zebra/zebra_ns.c b/zebra/zebra_ns.c new file mode 100644 index 0000000000..da03dff37c --- /dev/null +++ b/zebra/zebra_ns.c @@ -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; +} diff --git a/zebra/zebra_ns.h b/zebra/zebra_ns.h new file mode 100644 index 0000000000..07fcfcdac1 --- /dev/null +++ b/zebra/zebra_ns.h @@ -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 diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c index a584602e90..313dae3f11 100644 --- a/zebra/zebra_rnh.c +++ b/zebra/zebra_rnh.c @@ -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"); -- 2.39.5