mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-02 13:23:44 +00:00
zebra, lib/memtypes.c: the netlink sockets work per VRF
This patch lets the netlink sockets work per VRF. * The definition of "struct nlsock" is moved into zebra/rib.h. * The previous global variables "netlink" and "netlink_cmd" now become the members of "struct zebra_vrf", and are initialized in zebra_vrf_alloc(). * All relative functions now work for a specific VRF, by adding a new parameter which specifies the working VRF, except those functions in which the VRF ID can be obtained from the interface. * kernel_init(), interface_list() and route_read() are now also working per VRF, and moved from main() to zebra_vrf_enable(). * A new function kernel_terminate() is added to release the netlink sockets. It is called from zebra_vrf_disable(). * Correct VRF ID, instead of the previous VRF_DEFAULT, are now passed to the functions of processing interfaces or route entries. Signed-off-by: Feng Lu <lu.feng@6wind.com> Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Acked-by: Donald Sharp <sharpd@cumulusnetworks.com> Conflicts: lib/memtypes.c zebra/rib.h zebra/rt_netlink.c Conflicts: zebra/if_netlink.c zebra/if_sysctl.c zebra/kernel_null.c zebra/rib.h zebra/rt_netlink.c zebra/rt_netlink.h
This commit is contained in:
parent
cd80d74fb2
commit
8f7d9fc088
@ -90,6 +90,7 @@ struct memory_list memory_list_zebra[] =
|
||||
{ MTYPE_RIB_DEST, "RIB destination" },
|
||||
{ MTYPE_RIB_TABLE_INFO, "RIB table info" },
|
||||
{ MTYPE_RNH, "Nexthop tracking object" },
|
||||
{ MTYPE_NETLINK_NAME, "Netlink name" },
|
||||
{ -1, NULL },
|
||||
};
|
||||
|
||||
|
@ -29,8 +29,10 @@
|
||||
#include "connected.h"
|
||||
#include "memory.h"
|
||||
#include "log.h"
|
||||
#include "vrf.h"
|
||||
|
||||
#include "zebra/interface.h"
|
||||
#include "zebra/rib.h"
|
||||
|
||||
/* Interface looking up using infamous SIOCGIFCONF. */
|
||||
static int
|
||||
@ -442,8 +444,13 @@ interface_info_ioctl ()
|
||||
|
||||
/* Lookup all interface information. */
|
||||
void
|
||||
interface_list ()
|
||||
interface_list (struct zebra_vrf *zvrf)
|
||||
{
|
||||
if (zvrf->vrf_id != VRF_DEFAULT)
|
||||
{
|
||||
zlog_warn ("interface_list: ignore VRF %u", zvrf->vrf_id);
|
||||
return;
|
||||
}
|
||||
/* Linux can do both proc & ioctl, ioctl is the only way to get
|
||||
interface aliases in 2.2 series kernels. */
|
||||
#ifdef HAVE_PROC_NET_DEV
|
||||
|
@ -30,8 +30,10 @@
|
||||
#include "memory.h"
|
||||
#include "log.h"
|
||||
#include "privs.h"
|
||||
#include "vrf.h"
|
||||
|
||||
#include "zebra/interface.h"
|
||||
#include "zebra/rib.h"
|
||||
|
||||
void lifreq_set_name (struct lifreq *, const char *);
|
||||
int if_get_flags_direct (const char *, uint64_t *, unsigned int af);
|
||||
@ -349,8 +351,13 @@ interface_info_ioctl (struct interface *ifp)
|
||||
|
||||
/* Lookup all interface information. */
|
||||
void
|
||||
interface_list ()
|
||||
interface_list (struct zebra_vrf *zvrf)
|
||||
{
|
||||
if (zvrf->vrf_id != VRF_DEFAULT)
|
||||
{
|
||||
zlog_warn ("interface_list: ignore VRF %u", zvrf->vrf_id);
|
||||
return;
|
||||
}
|
||||
interface_list_ioctl (AF_INET);
|
||||
interface_list_ioctl (AF_INET6);
|
||||
interface_list_ioctl (AF_UNSPEC);
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
/* Interface information read by netlink. */
|
||||
void
|
||||
interface_list (void)
|
||||
interface_list (struct zebra_vrf *zvrf)
|
||||
{
|
||||
interface_lookup_netlink ();
|
||||
interface_lookup_netlink (zvrf);
|
||||
}
|
||||
|
@ -29,9 +29,15 @@
|
||||
#include "memory.h"
|
||||
#include "ioctl.h"
|
||||
#include "log.h"
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
#include "interface.h"
|
||||
#include "vrf.h"
|
||||
>>>>>>> 3c27b5f... zebra, lib/memtypes.c: the netlink sockets work per VRF
|
||||
|
||||
#include "zebra/rt.h"
|
||||
#include "zebra/kernel_socket.h"
|
||||
#include "zebra/rib.h"
|
||||
|
||||
void
|
||||
ifstat_update_sysctl (void)
|
||||
@ -90,7 +96,7 @@ ifstat_update_sysctl (void)
|
||||
|
||||
/* Interface listing up function using sysctl(). */
|
||||
void
|
||||
interface_list ()
|
||||
interface_list (struct zebra_vrf *zvrf)
|
||||
{
|
||||
caddr_t ref, buf, end;
|
||||
size_t bufsiz;
|
||||
@ -107,6 +113,12 @@ interface_list ()
|
||||
0
|
||||
};
|
||||
|
||||
if (zvrf->vrf_id != VRF_DEFAULT)
|
||||
{
|
||||
zlog_warn ("interface_list: ignore VRF %u", zvrf->vrf_id);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Query buffer size. */
|
||||
if (sysctl (mib, MIBSIZ, NULL, &bufsiz, NULL, 0) < 0)
|
||||
{
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "zebra/redistribute.h"
|
||||
#include "zebra/connected.h"
|
||||
#include "zebra/rt_netlink.h"
|
||||
#include "zebra/rib.h"
|
||||
|
||||
int kernel_add_ipv4 (struct prefix *a, struct rib *b) { return 0; }
|
||||
int kernel_update_ipv4 (struct prefix *a, struct rib *b) { return 0; }
|
||||
@ -54,9 +55,10 @@ int netlink_neigh_update (int cmd, int ifindex, __u32 addr, char *lla, int llale
|
||||
return 0;
|
||||
}
|
||||
|
||||
void kernel_init (void) { return; }
|
||||
void kernel_init (struct zebra_vrf *zvrf) { return; }
|
||||
void kernel_terminate (struct zebra_vrf *zvrf) { return; }
|
||||
#ifdef HAVE_SYS_WEAK_ALIAS_PRAGMA
|
||||
#pragma weak route_read = kernel_init
|
||||
#else
|
||||
void route_read (void) { return; }
|
||||
void route_read (struct zebra_vrf *zvrf) { return; }
|
||||
#endif
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "zebra/zserv.h"
|
||||
#include "zebra/debug.h"
|
||||
#include "zebra/kernel_socket.h"
|
||||
#include "zebra/rib.h"
|
||||
|
||||
extern struct zebra_privs_t zserv_privs;
|
||||
extern struct zebra_t zebrad;
|
||||
@ -1262,8 +1263,11 @@ kernel_read (struct thread *thread)
|
||||
|
||||
/* Make routing socket. */
|
||||
static void
|
||||
routing_socket (void)
|
||||
routing_socket (struct zebra_vrf *zvrf)
|
||||
{
|
||||
if (zvrf->vrf_id != VRF_DEFAULT)
|
||||
return;
|
||||
|
||||
if ( zserv_privs.change (ZPRIVS_RAISE) )
|
||||
zlog_err ("routing_socket: Can't raise privileges");
|
||||
|
||||
@ -1294,7 +1298,13 @@ routing_socket (void)
|
||||
/* Exported interface function. This function simply calls
|
||||
routing_socket (). */
|
||||
void
|
||||
kernel_init (void)
|
||||
kernel_init (struct zebra_vrf *zvrf)
|
||||
{
|
||||
routing_socket ();
|
||||
routing_socket (zvrf);
|
||||
}
|
||||
|
||||
void
|
||||
kernel_terminate (struct zebra_vrf *zvrf)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -241,6 +241,10 @@ zebra_vrf_enable (vrf_id_t vrf_id, void **info)
|
||||
#ifdef RTADV
|
||||
rtadv_init (zvrf);
|
||||
#endif
|
||||
kernel_init (zvrf);
|
||||
interface_list (zvrf);
|
||||
route_read (zvrf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -268,6 +272,7 @@ zebra_vrf_disable (vrf_id_t vrf_id, void **info)
|
||||
#ifdef RTADV
|
||||
rtadv_terminate (zvrf);
|
||||
#endif
|
||||
kernel_terminate (zvrf);
|
||||
|
||||
list_delete_all_node (zvrf->rid_all_sorted_list);
|
||||
list_delete_all_node (zvrf->rid_lo_sorted_list);
|
||||
@ -428,9 +433,6 @@ main (int argc, char **argv)
|
||||
|
||||
/* Initialize VRF module, and make kernel routing socket. */
|
||||
zebra_vrf_init ();
|
||||
kernel_init ();
|
||||
interface_list ();
|
||||
route_read ();
|
||||
|
||||
#ifdef HAVE_SNMP
|
||||
zebra_snmp_init ();
|
||||
|
17
zebra/rib.h
17
zebra/rib.h
@ -310,6 +310,17 @@ struct rtadv
|
||||
};
|
||||
#endif /* RTADV && HAVE_IPV6 */
|
||||
|
||||
#ifdef HAVE_NETLINK
|
||||
/* Socket interface to kernel */
|
||||
struct nlsock
|
||||
{
|
||||
int sock;
|
||||
int seq;
|
||||
struct sockaddr_nl snl;
|
||||
const char *name;
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Routing table instance. */
|
||||
struct zebra_vrf
|
||||
{
|
||||
@ -340,6 +351,12 @@ struct zebra_vrf
|
||||
/* Routing tables off of main table for redistribute table */
|
||||
struct route_table *other_table[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX];
|
||||
|
||||
#ifdef HAVE_NETLINK
|
||||
struct nlsock netlink; /* kernel messages */
|
||||
struct nlsock netlink_cmd; /* command channel */
|
||||
struct thread *t_netlink;
|
||||
#endif
|
||||
|
||||
/* 2nd pointer type used primarily to quell a warning on
|
||||
* ALL_LIST_ELEMENTS_RO
|
||||
*/
|
||||
|
@ -47,16 +47,6 @@
|
||||
|
||||
#include "rt_netlink.h"
|
||||
|
||||
/* Socket interface to kernel */
|
||||
struct nlsock
|
||||
{
|
||||
int sock;
|
||||
int seq;
|
||||
struct sockaddr_nl snl;
|
||||
const char *name;
|
||||
} netlink = { -1, 0, {0}, "netlink-listen"}, /* kernel messages */
|
||||
netlink_cmd = { -1, 0, {0}, "netlink-cmd"}; /* command channel */
|
||||
|
||||
static const struct message nlmsg_str[] = {
|
||||
{RTM_NEWROUTE, "RTM_NEWROUTE"},
|
||||
{RTM_DELROUTE, "RTM_DELROUTE"},
|
||||
@ -156,7 +146,7 @@ netlink_recvbuf (struct nlsock *nl, uint32_t newsize)
|
||||
|
||||
/* Make socket for Linux netlink interface. */
|
||||
static int
|
||||
netlink_socket (struct nlsock *nl, unsigned long groups)
|
||||
netlink_socket (struct nlsock *nl, unsigned long groups, vrf_id_t vrf_id)
|
||||
{
|
||||
int ret;
|
||||
struct sockaddr_nl snl;
|
||||
@ -170,7 +160,7 @@ netlink_socket (struct nlsock *nl, unsigned long groups)
|
||||
return -1;
|
||||
}
|
||||
|
||||
sock = socket (AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
|
||||
sock = vrf_socket (AF_NETLINK, SOCK_RAW, NETLINK_ROUTE, vrf_id);
|
||||
if (sock < 0)
|
||||
{
|
||||
zlog (NULL, LOG_ERR, "Can't open %s socket: %s", nl->name,
|
||||
@ -273,8 +263,9 @@ netlink_request (int family, int type, struct nlsock *nl)
|
||||
/* Receive message from netlink interface and pass those information
|
||||
to the given function. */
|
||||
static int
|
||||
netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *),
|
||||
struct nlsock *nl)
|
||||
netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *,
|
||||
vrf_id_t),
|
||||
struct nlsock *nl, struct zebra_vrf *zvrf)
|
||||
{
|
||||
int status;
|
||||
int ret = 0;
|
||||
@ -363,7 +354,7 @@ netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *),
|
||||
}
|
||||
|
||||
/* Deal with errors that occur because of races in link handling */
|
||||
if (nl == &netlink_cmd
|
||||
if (nl == &zvrf->netlink_cmd
|
||||
&& ((msg_type == RTM_DELROUTE &&
|
||||
(-errnum == ENODEV || -errnum == ESRCH))
|
||||
|| (msg_type == RTM_NEWROUTE && -errnum == EEXIST)))
|
||||
@ -376,7 +367,7 @@ netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *),
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (nl == &netlink_cmd
|
||||
if (nl == &zvrf->netlink_cmd
|
||||
&& msg_type == RTM_NEWROUTE && -errnum == ESRCH)
|
||||
{
|
||||
/* This is known to happen in some situations, don't log
|
||||
@ -407,16 +398,17 @@ netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *),
|
||||
/* skip unsolicited messages originating from command socket
|
||||
* linux sets the originators port-id for {NEW|DEL}ADDR messages,
|
||||
* so this has to be checked here. */
|
||||
if (nl != &netlink_cmd && h->nlmsg_pid == netlink_cmd.snl.nl_pid
|
||||
if (nl != &zvrf->netlink_cmd
|
||||
&& h->nlmsg_pid == zvrf->netlink_cmd.snl.nl_pid
|
||||
&& (h->nlmsg_type != RTM_NEWADDR && h->nlmsg_type != RTM_DELADDR))
|
||||
{
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug ("netlink_parse_info: %s packet comes from %s",
|
||||
netlink_cmd.name, nl->name);
|
||||
zvrf->netlink_cmd.name, nl->name);
|
||||
continue;
|
||||
}
|
||||
|
||||
error = (*filter) (&snl, h);
|
||||
error = (*filter) (&snl, h, zvrf->vrf_id);
|
||||
if (error < 0)
|
||||
{
|
||||
zlog (NULL, LOG_ERR, "%s filter function error", nl->name);
|
||||
@ -487,7 +479,8 @@ netlink_interface_update_hw_addr (struct rtattr **tb, struct interface *ifp)
|
||||
/* Called from interface_lookup_netlink(). This function is only used
|
||||
during bootstrap. */
|
||||
static int
|
||||
netlink_interface (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
||||
netlink_interface (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
vrf_id_t vrf_id)
|
||||
{
|
||||
int len;
|
||||
struct ifinfomsg *ifi;
|
||||
@ -523,7 +516,7 @@ netlink_interface (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
||||
name = (char *) RTA_DATA (tb[IFLA_IFNAME]);
|
||||
|
||||
/* Add interface. */
|
||||
ifp = if_get_by_name (name);
|
||||
ifp = if_get_by_name_vrf (name, vrf_id);
|
||||
set_ifindex(ifp, ifi->ifi_index);
|
||||
ifp->flags = ifi->ifi_flags & 0x0000fffff;
|
||||
ifp->mtu6 = ifp->mtu = *(uint32_t *) RTA_DATA (tb[IFLA_MTU]);
|
||||
@ -540,7 +533,8 @@ netlink_interface (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
||||
|
||||
/* Lookup interface IPv4/IPv6 address. */
|
||||
static int
|
||||
netlink_interface_addr (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
||||
netlink_interface_addr (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
vrf_id_t vrf_id)
|
||||
{
|
||||
int len;
|
||||
struct ifaddrmsg *ifa;
|
||||
@ -570,19 +564,19 @@ 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 (ifa->ifa_index);
|
||||
ifp = if_lookup_by_index_vrf (ifa->ifa_index, vrf_id);
|
||||
if (ifp == NULL)
|
||||
{
|
||||
zlog_err ("netlink_interface_addr can't find interface by index %d",
|
||||
ifa->ifa_index);
|
||||
zlog_err ("netlink_interface_addr can't find interface by index %d vrf %u",
|
||||
ifa->ifa_index, vrf_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (IS_ZEBRA_DEBUG_KERNEL) /* remove this line to see initial ifcfg */
|
||||
{
|
||||
char buf[BUFSIZ];
|
||||
zlog_debug ("netlink_interface_addr %s %s:",
|
||||
lookup (nlmsg_str, h->nlmsg_type), ifp->name);
|
||||
zlog_debug ("netlink_interface_addr %s %s vrf %u:",
|
||||
lookup (nlmsg_str, h->nlmsg_type), ifp->name, vrf_id);
|
||||
if (tb[IFA_LOCAL])
|
||||
zlog_debug (" IFA_LOCAL %s/%d",
|
||||
inet_ntop (ifa->ifa_family, RTA_DATA (tb[IFA_LOCAL]),
|
||||
@ -675,7 +669,8 @@ netlink_interface_addr (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
||||
|
||||
/* Looking up routing table by netlink interface. */
|
||||
static int
|
||||
netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
||||
netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
vrf_id_t vrf_id)
|
||||
{
|
||||
int len;
|
||||
struct rtmsg *rtm;
|
||||
@ -756,7 +751,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
||||
|
||||
if (!tb[RTA_MULTIPATH])
|
||||
rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, flags, &p, gate, src, index,
|
||||
VRF_DEFAULT, table, metric, 0, SAFI_UNICAST);
|
||||
vrf_id, table, metric, 0, SAFI_UNICAST);
|
||||
else
|
||||
{
|
||||
/* This is a multipath route */
|
||||
@ -772,7 +767,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
||||
rib->distance = 0;
|
||||
rib->flags = flags;
|
||||
rib->metric = metric;
|
||||
rib->vrf_id = VRF_DEFAULT;
|
||||
rib->vrf_id = vrf_id;
|
||||
rib->table = table;
|
||||
rib->nexthop_num = 0;
|
||||
rib->uptime = time (NULL);
|
||||
@ -823,7 +818,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
||||
memcpy (&p.prefix, dest, 16);
|
||||
p.prefixlen = rtm->rtm_dst_len;
|
||||
|
||||
rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, 0, flags, &p, gate, index, VRF_DEFAULT,
|
||||
rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, 0, flags, &p, gate, index, vrf_id,
|
||||
table, metric, 0, SAFI_UNICAST);
|
||||
}
|
||||
#endif /* HAVE_IPV6 */
|
||||
@ -848,7 +843,8 @@ static const struct message rtproto_str[] = {
|
||||
|
||||
/* Routing information change from the kernel. */
|
||||
static int
|
||||
netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
||||
netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
vrf_id_t vrf_id)
|
||||
{
|
||||
int len;
|
||||
struct rtmsg *rtm;
|
||||
@ -870,18 +866,19 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
||||
if (!(h->nlmsg_type == RTM_NEWROUTE || h->nlmsg_type == RTM_DELROUTE))
|
||||
{
|
||||
/* If this is not route add/delete message print warning. */
|
||||
zlog_warn ("Kernel message: %d\n", h->nlmsg_type);
|
||||
zlog_warn ("Kernel message: %d vrf %u\n", h->nlmsg_type, vrf_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Connected route. */
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug ("%s %s %s proto %s",
|
||||
zlog_debug ("%s %s %s proto %s vrf %u",
|
||||
h->nlmsg_type ==
|
||||
RTM_NEWROUTE ? "RTM_NEWROUTE" : "RTM_DELROUTE",
|
||||
rtm->rtm_family == AF_INET ? "ipv4" : "ipv6",
|
||||
rtm->rtm_type == RTN_UNICAST ? "unicast" : "multicast",
|
||||
lookup (rtproto_str, rtm->rtm_protocol));
|
||||
lookup (rtproto_str, rtm->rtm_protocol),
|
||||
vrf_id);
|
||||
|
||||
if (rtm->rtm_type != RTN_UNICAST)
|
||||
{
|
||||
@ -913,7 +910,7 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
||||
|
||||
if (rtm->rtm_src_len != 0)
|
||||
{
|
||||
zlog_warn ("netlink_route_change(): no src len");
|
||||
zlog_warn ("netlink_route_change(): no src len, vrf %u", vrf_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -949,18 +946,16 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
||||
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
{
|
||||
if (h->nlmsg_type == RTM_NEWROUTE)
|
||||
zlog_debug ("RTM_NEWROUTE %s/%d",
|
||||
inet_ntoa (p.prefix), p.prefixlen);
|
||||
else
|
||||
zlog_debug ("RTM_DELROUTE %s/%d",
|
||||
inet_ntoa (p.prefix), p.prefixlen);
|
||||
char buf[BUFSIZ];
|
||||
zlog_debug ("%s %s vrf %u",
|
||||
h->nlmsg_type == RTM_NEWROUTE ? "RTM_NEWROUTE" : "RTM_DELROUTE",
|
||||
prefix2str (&p, buf, sizeof(buf)), vrf_id);
|
||||
}
|
||||
|
||||
if (h->nlmsg_type == RTM_NEWROUTE)
|
||||
{
|
||||
if (!tb[RTA_MULTIPATH])
|
||||
rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, 0, &p, gate, src, index, VRF_DEFAULT,
|
||||
rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, 0, &p, gate, src, index, vrf_id,
|
||||
table, metric, 0, SAFI_UNICAST);
|
||||
else
|
||||
{
|
||||
@ -977,7 +972,7 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
||||
rib->distance = 0;
|
||||
rib->flags = 0;
|
||||
rib->metric = metric;
|
||||
rib->vrf_id = VRF_DEFAULT;
|
||||
rib->vrf_id = vrf_id;
|
||||
rib->table = table;
|
||||
rib->nexthop_num = 0;
|
||||
rib->uptime = time (NULL);
|
||||
@ -1023,7 +1018,7 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
||||
}
|
||||
else
|
||||
rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, gate, index,
|
||||
VRF_DEFAULT, table, SAFI_UNICAST);
|
||||
vrf_id, table, SAFI_UNICAST);
|
||||
}
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
@ -1038,22 +1033,17 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
||||
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
{
|
||||
if (h->nlmsg_type == RTM_NEWROUTE)
|
||||
zlog_debug ("RTM_NEWROUTE %s/%d",
|
||||
inet_ntop (AF_INET6, &p.prefix, buf, BUFSIZ),
|
||||
p.prefixlen);
|
||||
else
|
||||
zlog_debug ("RTM_DELROUTE %s/%d",
|
||||
inet_ntop (AF_INET6, &p.prefix, buf, BUFSIZ),
|
||||
p.prefixlen);
|
||||
zlog_debug ("%s %s vrf %u",
|
||||
h->nlmsg_type == RTM_NEWROUTE ? "RTM_NEWROUTE" : "RTM_DELROUTE",
|
||||
prefix2str (&p, buf, sizeof(buf)), vrf_id);
|
||||
}
|
||||
|
||||
if (h->nlmsg_type == RTM_NEWROUTE)
|
||||
rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, 0, 0, &p, gate, index, VRF_DEFAULT,
|
||||
rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, 0, 0, &p, gate, index, vrf_id,
|
||||
table, metric, 0, SAFI_UNICAST);
|
||||
else
|
||||
rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, gate, index,
|
||||
VRF_DEFAULT, table, SAFI_UNICAST);
|
||||
vrf_id, table, SAFI_UNICAST);
|
||||
}
|
||||
#endif /* HAVE_IPV6 */
|
||||
|
||||
@ -1061,7 +1051,8 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
||||
}
|
||||
|
||||
static int
|
||||
netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
||||
netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
vrf_id_t vrf_id)
|
||||
{
|
||||
int len;
|
||||
struct ifinfomsg *ifi;
|
||||
@ -1074,8 +1065,8 @@ netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
||||
if (!(h->nlmsg_type == RTM_NEWLINK || h->nlmsg_type == RTM_DELLINK))
|
||||
{
|
||||
/* If this is not link add/delete message so print warning. */
|
||||
zlog_warn ("netlink_link_change: wrong kernel message %d\n",
|
||||
h->nlmsg_type);
|
||||
zlog_warn ("netlink_link_change: wrong kernel message %d vrf %u\n",
|
||||
h->nlmsg_type, vrf_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1092,7 +1083,8 @@ netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
||||
if ((tb[IFLA_WIRELESS] != NULL) && (ifi->ifi_change == 0))
|
||||
{
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug ("%s: ignoring IFLA_WIRELESS message", __func__);
|
||||
zlog_debug ("%s: ignoring IFLA_WIRELESS message, vrf %u", __func__,
|
||||
vrf_id);
|
||||
return 0;
|
||||
}
|
||||
#endif /* IFLA_WIRELESS */
|
||||
@ -1104,12 +1096,12 @@ netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
||||
/* Add interface. */
|
||||
if (h->nlmsg_type == RTM_NEWLINK)
|
||||
{
|
||||
ifp = if_lookup_by_name (name);
|
||||
ifp = if_lookup_by_name_vrf (name, vrf_id);
|
||||
|
||||
if (ifp == NULL || !CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
|
||||
{
|
||||
if (ifp == NULL)
|
||||
ifp = if_get_by_name (name);
|
||||
ifp = if_get_by_name_vrf (name, vrf_id);
|
||||
|
||||
set_ifindex(ifp, ifi->ifi_index);
|
||||
ifp->flags = ifi->ifi_flags & 0x0000fffff;
|
||||
@ -1150,12 +1142,12 @@ netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
||||
else
|
||||
{
|
||||
/* RTM_DELLINK. */
|
||||
ifp = if_lookup_by_name (name);
|
||||
ifp = if_lookup_by_name_vrf (name, vrf_id);
|
||||
|
||||
if (ifp == NULL)
|
||||
{
|
||||
zlog (NULL, LOG_WARNING, "interface %s is deleted but can't find",
|
||||
name);
|
||||
zlog_warn ("interface %s vrf %u is deleted but can't find",
|
||||
name, vrf_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1166,7 +1158,8 @@ netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
||||
}
|
||||
|
||||
static int
|
||||
netlink_information_fetch (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
||||
netlink_information_fetch (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
vrf_id_t vrf_id)
|
||||
{
|
||||
/* JF: Ignore messages that aren't from the kernel */
|
||||
if ( snl->nl_pid != 0 )
|
||||
@ -1178,25 +1171,26 @@ netlink_information_fetch (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
||||
switch (h->nlmsg_type)
|
||||
{
|
||||
case RTM_NEWROUTE:
|
||||
return netlink_route_change (snl, h);
|
||||
return netlink_route_change (snl, h, vrf_id);
|
||||
break;
|
||||
case RTM_DELROUTE:
|
||||
return netlink_route_change (snl, h);
|
||||
return netlink_route_change (snl, h, vrf_id);
|
||||
break;
|
||||
case RTM_NEWLINK:
|
||||
return netlink_link_change (snl, h);
|
||||
return netlink_link_change (snl, h, vrf_id);
|
||||
break;
|
||||
case RTM_DELLINK:
|
||||
return netlink_link_change (snl, h);
|
||||
return netlink_link_change (snl, h, vrf_id);
|
||||
break;
|
||||
case RTM_NEWADDR:
|
||||
return netlink_interface_addr (snl, h);
|
||||
return netlink_interface_addr (snl, h, vrf_id);
|
||||
break;
|
||||
case RTM_DELADDR:
|
||||
return netlink_interface_addr (snl, h);
|
||||
return netlink_interface_addr (snl, h, vrf_id);
|
||||
break;
|
||||
default:
|
||||
zlog_warn ("Unknown netlink nlmsg_type %d\n", h->nlmsg_type);
|
||||
zlog_warn ("Unknown netlink nlmsg_type %d vrf %u\n", h->nlmsg_type,
|
||||
vrf_id);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
@ -1204,32 +1198,32 @@ netlink_information_fetch (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
||||
|
||||
/* Interface lookup by netlink socket. */
|
||||
int
|
||||
interface_lookup_netlink (void)
|
||||
interface_lookup_netlink (struct zebra_vrf *zvrf)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Get interface information. */
|
||||
ret = netlink_request (AF_PACKET, RTM_GETLINK, &netlink_cmd);
|
||||
ret = netlink_request (AF_PACKET, RTM_GETLINK, &zvrf->netlink_cmd);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = netlink_parse_info (netlink_interface, &netlink_cmd);
|
||||
ret = netlink_parse_info (netlink_interface, &zvrf->netlink_cmd, zvrf);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Get IPv4 address of the interfaces. */
|
||||
ret = netlink_request (AF_INET, RTM_GETADDR, &netlink_cmd);
|
||||
ret = netlink_request (AF_INET, RTM_GETADDR, &zvrf->netlink_cmd);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = netlink_parse_info (netlink_interface_addr, &netlink_cmd);
|
||||
ret = netlink_parse_info (netlink_interface_addr, &zvrf->netlink_cmd, zvrf);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
/* Get IPv6 address of the interfaces. */
|
||||
ret = netlink_request (AF_INET6, RTM_GETADDR, &netlink_cmd);
|
||||
ret = netlink_request (AF_INET6, RTM_GETADDR, &zvrf->netlink_cmd);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = netlink_parse_info (netlink_interface_addr, &netlink_cmd);
|
||||
ret = netlink_parse_info (netlink_interface_addr, &zvrf->netlink_cmd, zvrf);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
#endif /* HAVE_IPV6 */
|
||||
@ -1240,24 +1234,24 @@ interface_lookup_netlink (void)
|
||||
/* Routing table read function using netlink interface. Only called
|
||||
bootstrap time. */
|
||||
int
|
||||
netlink_route_read (void)
|
||||
netlink_route_read (struct zebra_vrf *zvrf)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Get IPv4 routing table. */
|
||||
ret = netlink_request (AF_INET, RTM_GETROUTE, &netlink_cmd);
|
||||
ret = netlink_request (AF_INET, RTM_GETROUTE, &zvrf->netlink_cmd);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = netlink_parse_info (netlink_routing_table, &netlink_cmd);
|
||||
ret = netlink_parse_info (netlink_routing_table, &zvrf->netlink_cmd, zvrf);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
/* Get IPv6 routing table. */
|
||||
ret = netlink_request (AF_INET6, RTM_GETROUTE, &netlink_cmd);
|
||||
ret = netlink_request (AF_INET6, RTM_GETROUTE, &zvrf->netlink_cmd);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = netlink_parse_info (netlink_routing_table, &netlink_cmd);
|
||||
ret = netlink_parse_info (netlink_routing_table, &zvrf->netlink_cmd, zvrf);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
#endif /* HAVE_IPV6 */
|
||||
@ -1330,15 +1324,17 @@ addattr32 (struct nlmsghdr *n, unsigned int maxlen, int type, int data)
|
||||
}
|
||||
|
||||
static int
|
||||
netlink_talk_filter (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
||||
netlink_talk_filter (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
vrf_id_t vrf_id)
|
||||
{
|
||||
zlog_warn ("netlink_talk: ignoring message type 0x%04x", h->nlmsg_type);
|
||||
zlog_warn ("netlink_talk: ignoring message type 0x%04x vrf %u", h->nlmsg_type,
|
||||
vrf_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* sendmsg() to netlink socket then recvmsg(). */
|
||||
static int
|
||||
netlink_talk (struct nlmsghdr *n, struct nlsock *nl)
|
||||
netlink_talk (struct nlmsghdr *n, struct nlsock *nl, struct zebra_vrf *zvrf)
|
||||
{
|
||||
int status;
|
||||
struct sockaddr_nl snl;
|
||||
@ -1388,7 +1384,7 @@ netlink_talk (struct nlmsghdr *n, struct nlsock *nl)
|
||||
* Get reply from netlink socket.
|
||||
* The reply should either be an acknowlegement or an error.
|
||||
*/
|
||||
return netlink_parse_info (netlink_talk_filter, nl);
|
||||
return netlink_parse_info (netlink_talk_filter, nl, zvrf);
|
||||
}
|
||||
|
||||
/* Routing table change via netlink interface. */
|
||||
@ -1401,6 +1397,8 @@ netlink_route (int cmd, int family, void *dest, int length, void *gate,
|
||||
struct sockaddr_nl snl;
|
||||
int discard;
|
||||
|
||||
struct zebra_vrf *zvrf = vrf_info_lookup (VRF_DEFAULT); //Pending
|
||||
|
||||
struct
|
||||
{
|
||||
struct nlmsghdr n;
|
||||
@ -1462,7 +1460,7 @@ netlink_route (int cmd, int family, void *dest, int length, void *gate,
|
||||
snl.nl_family = AF_NETLINK;
|
||||
|
||||
/* Talk to netlink socket. */
|
||||
ret = netlink_talk (&req.n, &netlink_cmd);
|
||||
ret = netlink_talk (&req.n, &zvrf->netlink_cmd, VRF_DEFAULT);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
|
||||
@ -1763,11 +1761,12 @@ _netlink_route_debug(
|
||||
struct prefix *p,
|
||||
struct nexthop *nexthop,
|
||||
const char *routedesc,
|
||||
int family)
|
||||
int family,
|
||||
struct zebra_vrf *zvrf)
|
||||
{
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
{
|
||||
zlog_debug ("netlink_route_multipath() (%s): %s %s/%d type %s",
|
||||
zlog_debug ("netlink_route_multipath() (%s): %s %s/%d vrf %u type %s",
|
||||
routedesc,
|
||||
lookup (nlmsg_str, cmd),
|
||||
#ifdef HAVE_IPV6
|
||||
@ -1776,7 +1775,7 @@ _netlink_route_debug(
|
||||
#else
|
||||
inet_ntoa (p->u.prefix4),
|
||||
#endif /* HAVE_IPV6 */
|
||||
p->prefixlen, nexthop_type_to_str (nexthop->type));
|
||||
p->prefixlen, zvrf->vrf_id, nexthop_type_to_str (nexthop->type));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1789,6 +1788,8 @@ netlink_neigh_update (int cmd, int ifindex, __u32 addr, char *lla, int llalen)
|
||||
char buf[256];
|
||||
} req;
|
||||
|
||||
struct zebra_vrf *zvrf = vrf_info_lookup (VRF_DEFAULT); //Pending
|
||||
|
||||
memset(&req.n, 0, sizeof(req.n));
|
||||
memset(&req.ndm, 0, sizeof(req.ndm));
|
||||
|
||||
@ -1803,7 +1804,7 @@ netlink_neigh_update (int cmd, int ifindex, __u32 addr, char *lla, int llalen)
|
||||
addattr_l(&req.n, sizeof(req), NDA_DST, &addr, 4);
|
||||
addattr_l(&req.n, sizeof(req), NDA_LLADDR, lla, llalen);
|
||||
|
||||
return netlink_talk (&req.n, &netlink_cmd);
|
||||
return netlink_talk (&req.n, &zvrf->netlink_cmd, VRF_DEFAULT);
|
||||
}
|
||||
|
||||
/* Routing table change via netlink interface. */
|
||||
@ -1829,6 +1830,8 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
|
||||
char buf[NL_PKT_BUF_SIZE];
|
||||
} req;
|
||||
|
||||
struct zebra_vrf *zvrf = vrf_info_lookup (rib->vrf_id);
|
||||
|
||||
memset (&req, 0, sizeof req - NL_PKT_BUF_SIZE);
|
||||
|
||||
bytelen = (family == AF_INET ? 4 : 16);
|
||||
@ -1950,7 +1953,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
|
||||
{
|
||||
routedesc = recursing ? "recursive, 1 hop" : "single hop";
|
||||
|
||||
_netlink_route_debug(cmd, p, nexthop, routedesc, family);
|
||||
_netlink_route_debug(cmd, p, nexthop, routedesc, family, zvrf);
|
||||
_netlink_route_build_singlepath(routedesc, bytelen,
|
||||
nexthop, &req.n, &req.r,
|
||||
sizeof req, cmd);
|
||||
@ -2031,7 +2034,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
|
||||
nexthop_num++;
|
||||
|
||||
_netlink_route_debug(cmd, p, nexthop,
|
||||
routedesc, family);
|
||||
routedesc, family, zvrf);
|
||||
_netlink_route_build_multipath(routedesc, bytelen,
|
||||
nexthop, rta, rtnh, &req.r, &src1);
|
||||
rtnh = RTNH_NEXT (rtnh);
|
||||
@ -2079,7 +2082,7 @@ skip:
|
||||
snl.nl_family = AF_NETLINK;
|
||||
|
||||
/* Talk to netlink socket. */
|
||||
return netlink_talk (&req.n, &netlink_cmd);
|
||||
return netlink_talk (&req.n, &zvrf->netlink_cmd, zvrf);
|
||||
}
|
||||
|
||||
int
|
||||
@ -2142,6 +2145,8 @@ netlink_address (int cmd, int family, struct interface *ifp,
|
||||
char buf[NL_PKT_BUF_SIZE];
|
||||
} req;
|
||||
|
||||
struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id);
|
||||
|
||||
p = ifc->address;
|
||||
memset (&req, 0, sizeof req - NL_PKT_BUF_SIZE);
|
||||
|
||||
@ -2174,7 +2179,7 @@ netlink_address (int cmd, int family, struct interface *ifp,
|
||||
addattr_l (&req.n, sizeof req, IFA_LABEL, ifc->label,
|
||||
strlen (ifc->label) + 1);
|
||||
|
||||
return netlink_talk (&req.n, &netlink_cmd);
|
||||
return netlink_talk (&req.n, &zvrf->netlink_cmd, zvrf);
|
||||
}
|
||||
|
||||
int
|
||||
@ -2196,8 +2201,10 @@ extern struct thread_master *master;
|
||||
static int
|
||||
kernel_read (struct thread *thread)
|
||||
{
|
||||
netlink_parse_info (netlink_information_fetch, &netlink);
|
||||
thread_add_read (zebrad.master, kernel_read, NULL, netlink.sock);
|
||||
struct zebra_vrf *zvrf = (struct zebra_vrf *)THREAD_ARG (thread);
|
||||
netlink_parse_info (netlink_information_fetch, &zvrf->netlink, zvrf);
|
||||
zvrf->t_netlink = thread_add_read (zebrad.master, kernel_read, zvrf,
|
||||
zvrf->netlink.sock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -2236,7 +2243,7 @@ static void netlink_install_filter (int sock, __u32 pid)
|
||||
/* Exported interface function. This function simply calls
|
||||
netlink_socket (). */
|
||||
void
|
||||
kernel_init (void)
|
||||
kernel_init (struct zebra_vrf *zvrf)
|
||||
{
|
||||
unsigned long groups;
|
||||
|
||||
@ -2244,23 +2251,42 @@ kernel_init (void)
|
||||
#ifdef HAVE_IPV6
|
||||
groups |= RTMGRP_IPV6_ROUTE | RTMGRP_IPV6_IFADDR;
|
||||
#endif /* HAVE_IPV6 */
|
||||
netlink_socket (&netlink, groups);
|
||||
netlink_socket (&netlink_cmd, 0);
|
||||
netlink_socket (&zvrf->netlink, groups, zvrf->vrf_id);
|
||||
netlink_socket (&zvrf->netlink_cmd, 0, zvrf->vrf_id);
|
||||
|
||||
/* Register kernel socket. */
|
||||
if (netlink.sock > 0)
|
||||
if (zvrf->netlink.sock > 0)
|
||||
{
|
||||
/* Only want non-blocking on the netlink event socket */
|
||||
if (fcntl (netlink.sock, F_SETFL, O_NONBLOCK) < 0)
|
||||
zlog (NULL, LOG_ERR, "Can't set %s socket flags: %s", netlink.name,
|
||||
safe_strerror (errno));
|
||||
if (fcntl (zvrf->netlink.sock, F_SETFL, O_NONBLOCK) < 0)
|
||||
zlog_err ("Can't set %s socket flags: %s", zvrf->netlink.name,
|
||||
safe_strerror (errno));
|
||||
|
||||
/* Set receive buffer size if it's set from command line */
|
||||
if (nl_rcvbufsize)
|
||||
netlink_recvbuf (&netlink, nl_rcvbufsize);
|
||||
netlink_recvbuf (&zvrf->netlink, nl_rcvbufsize);
|
||||
|
||||
netlink_install_filter (netlink.sock, netlink_cmd.snl.nl_pid);
|
||||
thread_add_read (zebrad.master, kernel_read, NULL, netlink.sock);
|
||||
netlink_install_filter (zvrf->netlink.sock, zvrf->netlink_cmd.snl.nl_pid);
|
||||
zvrf->t_netlink = thread_add_read (zebrad.master, kernel_read, zvrf,
|
||||
zvrf->netlink.sock);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
kernel_terminate (struct zebra_vrf *zvrf)
|
||||
{
|
||||
THREAD_READ_OFF (zvrf->t_netlink);
|
||||
|
||||
if (zvrf->netlink.sock >= 0)
|
||||
{
|
||||
close (zvrf->netlink.sock);
|
||||
zvrf->netlink.sock = -1;
|
||||
}
|
||||
|
||||
if (zvrf->netlink_cmd.sock >= 0)
|
||||
{
|
||||
close (zvrf->netlink_cmd.sock);
|
||||
zvrf->netlink_cmd.sock = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -44,8 +44,8 @@ nl_rtproto_to_str (u_char rtproto);
|
||||
int
|
||||
netlink_neigh_update (int cmd, int ifindex, __u32 addr, char *lla, int llalen);
|
||||
|
||||
extern int netlink_route_read(void);
|
||||
extern int interface_lookup_netlink(void);
|
||||
extern int interface_lookup_netlink (struct zebra_vrf *zvrf);
|
||||
extern int netlink_route_read (struct zebra_vrf *zvrf);
|
||||
|
||||
#endif /* HAVE_NETLINK */
|
||||
|
||||
|
@ -95,7 +95,7 @@ handle_route_entry (mib2_ipRouteEntry_t *routeEntry)
|
||||
}
|
||||
|
||||
void
|
||||
route_read (void)
|
||||
route_read (struct zebra_vrf *zvrf)
|
||||
{
|
||||
char storage[RT_BUFSIZ];
|
||||
|
||||
@ -110,6 +110,10 @@ route_read (void)
|
||||
struct strbuf msgdata;
|
||||
int flags, dev, retval, process;
|
||||
|
||||
if (zvrf->vrf_id != VRF_DEFAULT) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((dev = open (_PATH_GETMSG_ROUTE, O_RDWR)) == -1) {
|
||||
zlog_warn ("can't open %s: %s", _PATH_GETMSG_ROUTE,
|
||||
safe_strerror (errno));
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include "zebra/zserv.h"
|
||||
#include "zebra/rt_netlink.h"
|
||||
|
||||
void route_read (void)
|
||||
void route_read (struct zebra_vrf *zvrf)
|
||||
{
|
||||
netlink_route_read ();
|
||||
netlink_route_read (zvrf);
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include "memory.h"
|
||||
#include "log.h"
|
||||
#include "vrf.h"
|
||||
|
||||
#include "zebra/zserv.h"
|
||||
#include "zebra/rt.h"
|
||||
@ -31,7 +32,7 @@
|
||||
|
||||
/* Kernel routing table read up by sysctl function. */
|
||||
void
|
||||
route_read (void)
|
||||
route_read (struct zebra_vrf *zvrf)
|
||||
{
|
||||
caddr_t buf, end, ref;
|
||||
size_t bufsiz;
|
||||
@ -47,7 +48,10 @@ route_read (void)
|
||||
NET_RT_DUMP,
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
if (zvrf->vrf_id != VRF_DEFAULT)
|
||||
return;
|
||||
|
||||
/* Get buffer size. */
|
||||
if (sysctl (mib, MIBSIZ, NULL, &bufsiz, NULL, 0) < 0)
|
||||
{
|
||||
|
@ -225,6 +225,9 @@ zebra_vrf_enable (vrf_id_t vrf_id, void **info)
|
||||
|
||||
assert (zvrf);
|
||||
|
||||
kernel_init (zvrf);
|
||||
route_read (zvrf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -249,6 +252,8 @@ zebra_vrf_disable (vrf_id_t vrf_id, void **info)
|
||||
if_down (ifp);
|
||||
}
|
||||
|
||||
kernel_terminate (zvrf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -363,8 +368,6 @@ main (int argc, char **argv)
|
||||
|
||||
/* Make kernel routing socket. */
|
||||
zebra_vrf_init ();
|
||||
kernel_init ();
|
||||
route_read ();
|
||||
zebra_vty_init();
|
||||
|
||||
/* Configuration file read*/
|
||||
|
@ -4135,6 +4135,9 @@ struct zebra_vrf *
|
||||
zebra_vrf_alloc (vrf_id_t vrf_id)
|
||||
{
|
||||
struct zebra_vrf *zvrf;
|
||||
#ifdef HAVE_NETLINK
|
||||
char nl_name[64];
|
||||
#endif
|
||||
|
||||
zvrf = XCALLOC (MTYPE_ZEBRA_VRF, sizeof (struct zebra_vrf));
|
||||
|
||||
@ -4157,6 +4160,17 @@ zebra_vrf_alloc (vrf_id_t vrf_id)
|
||||
/* Set VRF ID */
|
||||
zvrf->vrf_id = vrf_id;
|
||||
|
||||
#ifdef HAVE_NETLINK
|
||||
/* Initialize netlink sockets */
|
||||
snprintf (nl_name, 64, "netlink-listen (vrf %u)", vrf_id);
|
||||
zvrf->netlink.sock = -1;
|
||||
zvrf->netlink.name = XSTRDUP (MTYPE_NETLINK_NAME, nl_name);
|
||||
|
||||
snprintf (nl_name, 64, "netlink-cmd (vrf %u)", vrf_id);
|
||||
zvrf->netlink_cmd.sock = -1;
|
||||
zvrf->netlink_cmd.name = XSTRDUP (MTYPE_NETLINK_NAME, nl_name);
|
||||
#endif
|
||||
|
||||
return zvrf;
|
||||
}
|
||||
|
||||
|
@ -134,9 +134,10 @@ extern void zebra_if_init (void);
|
||||
extern void zebra_zserv_socket_init (char *path);
|
||||
extern void hostinfo_get (void);
|
||||
extern void rib_init (void);
|
||||
extern void interface_list (void);
|
||||
extern void kernel_init (void);
|
||||
extern void route_read (void);
|
||||
extern void interface_list (struct zebra_vrf *);
|
||||
extern void route_read (struct zebra_vrf *);
|
||||
extern void kernel_init (struct zebra_vrf *);
|
||||
extern void kernel_terminate (struct zebra_vrf *);
|
||||
extern void zebra_route_map_init (void);
|
||||
extern void zebra_snmp_init (void);
|
||||
extern void zebra_vty_init (void);
|
||||
|
Loading…
Reference in New Issue
Block a user