mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-01 00:25:52 +00:00
lib, zebra: The Bulk of the conversion over to NS and VRF
Convert the rest of zebra over to use a Namespae and VRF. Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com> Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
parent
244a59d228
commit
12f6fb9731
@ -443,7 +443,9 @@ struct in_pktinfo
|
||||
#define ZEBRA_REDISTRIBUTE_IPV6_ADD 40
|
||||
#define ZEBRA_REDISTRIBUTE_IPV6_DEL 41
|
||||
#define ZEBRA_VRF_UNREGISTER 42
|
||||
#define ZEBRA_MESSAGE_MAX 43
|
||||
#define ZEBRA_VRF_ADD 43
|
||||
#define ZEBRA_VRF_DELETE 44
|
||||
#define ZEBRA_MESSAGE_MAX 45
|
||||
|
||||
/* Marker value used in new Zserv, in the byte location corresponding
|
||||
* the command value in the old zserv header. To allow old and new
|
||||
|
@ -444,13 +444,11 @@ interface_info_ioctl ()
|
||||
|
||||
/* Lookup all interface information. */
|
||||
void
|
||||
interface_list (struct zebra_vrf *zvrf)
|
||||
interface_list (struct zebra_ns *zns)
|
||||
{
|
||||
if (zvrf->vrf_id != VRF_DEFAULT)
|
||||
{
|
||||
zlog_warn ("interface_list: ignore VRF %u", zvrf->vrf_id);
|
||||
return;
|
||||
}
|
||||
|
||||
zlog_info ("interface_list: NS %u", zns->ns_id);
|
||||
|
||||
/* 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
|
||||
|
@ -351,11 +351,11 @@ interface_info_ioctl (struct interface *ifp)
|
||||
|
||||
/* Lookup all interface information. */
|
||||
void
|
||||
interface_list (struct zebra_vrf *zvrf)
|
||||
interface_list (struct zebra_ns *zns)
|
||||
{
|
||||
if (zvrf->vrf_id != VRF_DEFAULT)
|
||||
if (zns->ns_id != NS_DEFAULT)
|
||||
{
|
||||
zlog_warn ("interface_list: ignore VRF %u", zvrf->vrf_id);
|
||||
zlog_warn ("interface_list: ignore NS %u", zns->ns_id);
|
||||
return;
|
||||
}
|
||||
interface_list_ioctl (AF_INET);
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
/* Interface information read by netlink. */
|
||||
void
|
||||
interface_list (struct zebra_vrf *zvrf)
|
||||
interface_list (struct zebra_ns *zns)
|
||||
{
|
||||
interface_lookup_netlink (zvrf);
|
||||
interface_lookup_netlink (zns);
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ ifstat_update_sysctl (void)
|
||||
|
||||
/* Interface listing up function using sysctl(). */
|
||||
void
|
||||
interface_list (struct zebra_vrf *zvrf)
|
||||
interface_list (struct zebra_ns *zns)
|
||||
{
|
||||
caddr_t ref, buf, end;
|
||||
size_t bufsiz;
|
||||
@ -110,9 +110,9 @@ interface_list (struct zebra_vrf *zvrf)
|
||||
0
|
||||
};
|
||||
|
||||
if (zvrf->vrf_id != VRF_DEFAULT)
|
||||
if (zns->ns_id != NS_DEFAULT)
|
||||
{
|
||||
zlog_warn ("interface_list: ignore VRF %u", zvrf->vrf_id);
|
||||
zlog_warn ("interface_list: ignore NS %u", zns->ns_id);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -54,6 +54,8 @@
|
||||
const char *rtadv_pref_strs[] = { "medium", "high", "INVALID", "low", 0 };
|
||||
#endif /* HAVE_RTADV */
|
||||
|
||||
struct zebra_ns *dzns;
|
||||
|
||||
/* Called when new interface is added. */
|
||||
static int
|
||||
if_zebra_new_hook (struct interface *ifp)
|
||||
@ -121,6 +123,67 @@ if_zebra_delete_hook (struct interface *ifp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Build the table key */
|
||||
static void
|
||||
if_build_key (u_int32_t ifindex, struct prefix *p)
|
||||
{
|
||||
p->family = AF_INET;
|
||||
p->prefixlen = IPV4_MAX_BITLEN;
|
||||
p->u.prefix4.s_addr = ifindex;
|
||||
}
|
||||
|
||||
/* Link an interface in a per NS interface tree */
|
||||
struct interface *
|
||||
if_link_per_ns (struct zebra_ns *ns, struct interface *ifp)
|
||||
{
|
||||
struct prefix p;
|
||||
struct route_node *rn;
|
||||
|
||||
if (ifp->ifindex == IFINDEX_INTERNAL)
|
||||
return NULL;
|
||||
|
||||
if_build_key (ifp->ifindex, &p);
|
||||
rn = route_node_get (ns->if_table, &p);
|
||||
if (rn->info)
|
||||
{
|
||||
ifp = (struct interface *)rn->info;
|
||||
route_unlock_node (rn); /* get */
|
||||
return ifp;
|
||||
}
|
||||
|
||||
rn->info = ifp;
|
||||
ifp->node = rn;
|
||||
|
||||
return ifp;
|
||||
}
|
||||
|
||||
/* Delete a VRF. This is called in vrf_terminate(). */
|
||||
void
|
||||
if_unlink_per_ns (struct interface *ifp)
|
||||
{
|
||||
ifp->node->info = NULL;
|
||||
route_unlock_node(ifp->node);
|
||||
}
|
||||
|
||||
/* Look up an interface by identifier within a NS */
|
||||
struct interface *
|
||||
if_lookup_by_index_per_ns (struct zebra_ns *ns, u_int32_t ifindex)
|
||||
{
|
||||
struct prefix p;
|
||||
struct route_node *rn;
|
||||
struct interface *ifp = NULL;
|
||||
|
||||
if_build_key (ifindex, &p);
|
||||
rn = route_node_lookup (ns->if_table, &p);
|
||||
if (rn)
|
||||
{
|
||||
ifp = (struct interface *)rn->info;
|
||||
route_unlock_node (rn); /* lookup */
|
||||
}
|
||||
return ifp;
|
||||
}
|
||||
|
||||
|
||||
/* Tie an interface address to its derived subnet list of addresses. */
|
||||
int
|
||||
if_subnet_add (struct interface *ifp, struct connected *ifc)
|
||||
@ -374,6 +437,8 @@ if_add_update (struct interface *ifp)
|
||||
{
|
||||
struct zebra_if *if_data;
|
||||
|
||||
if_link_per_ns(dzns, ifp);
|
||||
|
||||
if_data = ifp->info;
|
||||
if (if_data->multicast == IF_ZEBRA_MULTICAST_ON)
|
||||
if_set_flags (ifp, IFF_MULTICAST);
|
||||
@ -525,6 +590,8 @@ if_delete_update (struct interface *ifp)
|
||||
}
|
||||
zebra_interface_delete_update (ifp);
|
||||
|
||||
if_unlink_per_ns(ifp);
|
||||
|
||||
/* Update ifindex after distributing the delete message. This is in
|
||||
case any client needs to have the old value of ifindex available
|
||||
while processing the deletion. Each client daemon is responsible
|
||||
@ -533,6 +600,52 @@ if_delete_update (struct interface *ifp)
|
||||
ifp->ifindex = IFINDEX_INTERNAL;
|
||||
}
|
||||
|
||||
/* Handle VRF addition */
|
||||
void
|
||||
vrf_add_update (struct vrf *vrfp)
|
||||
{
|
||||
zebra_vrf_add_update (vrfp);
|
||||
|
||||
if (! CHECK_FLAG (vrfp->status, ZEBRA_VRF_ACTIVE))
|
||||
{
|
||||
SET_FLAG (vrfp->status, ZEBRA_VRF_ACTIVE);
|
||||
|
||||
//Pending: Check if the equivalent of if_addr_wakeup (ifp) is needed here.
|
||||
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug ("VRF %s id %u becomes active.",
|
||||
vrfp->name, vrfp->vrf_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug ("VRF %s id %u is added.",
|
||||
vrfp->name, vrfp->vrf_id);
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle an interface delete event */
|
||||
void
|
||||
vrf_delete_update (struct vrf *vrfp)
|
||||
{
|
||||
/* Mark VRF as inactive */
|
||||
UNSET_FLAG (vrfp->status, ZEBRA_VRF_ACTIVE);
|
||||
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug ("VRF %s id %u is now inactive.",
|
||||
vrfp->name, vrfp->vrf_id);
|
||||
|
||||
zebra_vrf_delete_update (vrfp);
|
||||
|
||||
/* Pending: Update ifindex after distributing the delete message. This is in
|
||||
case any client needs to have the old value of ifindex available
|
||||
while processing the deletion. Each client daemon is responsible
|
||||
for setting vrf-id to IFINDEX_INTERNAL after processing the
|
||||
interface deletion message. */
|
||||
vrfp->vrf_id = 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ipv6_ll_address_to_mac (struct in6_addr *address, u_char *mac)
|
||||
{
|
||||
@ -1043,6 +1156,34 @@ struct cmd_node interface_node =
|
||||
1
|
||||
};
|
||||
|
||||
/* Wrapper hook point for zebra daemon so that ifindex can be set
|
||||
* DEFUN macro not used as extract.pl HAS to ignore this
|
||||
* See also interface_cmd in lib/if.c
|
||||
*/
|
||||
DEFUN_NOSH (zebra_vrf,
|
||||
zebra_vrf_cmd,
|
||||
"vrf NAME",
|
||||
"Select a VRF to configure\n"
|
||||
"VRF's name\n")
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Call lib vrf() */
|
||||
if ((ret = vrf_cmd.func (self, vty, argc, argv)) != CMD_SUCCESS)
|
||||
return ret;
|
||||
|
||||
// vrfp = vty->index;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct cmd_node vrf_node =
|
||||
{
|
||||
VRF_NODE,
|
||||
"%s(config-vrf)# ",
|
||||
1
|
||||
};
|
||||
|
||||
/* Show all interfaces to vty. */
|
||||
DEFUN (show_interface, show_interface_cmd,
|
||||
"show interface",
|
||||
@ -1063,7 +1204,7 @@ DEFUN (show_interface, show_interface_cmd,
|
||||
#endif /* HAVE_NET_RT_IFLIST */
|
||||
|
||||
if (argc > 0)
|
||||
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
|
||||
VRF_GET_ID (vrf_id, argv[0]);
|
||||
|
||||
/* All interface print. */
|
||||
for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
|
||||
@ -1127,7 +1268,7 @@ DEFUN (show_interface_name, show_interface_name_cmd,
|
||||
#endif /* HAVE_NET_RT_IFLIST */
|
||||
|
||||
if (argc > 1)
|
||||
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
|
||||
VRF_GET_ID (vrf_id, argv[1]);
|
||||
|
||||
/* Specified interface print. */
|
||||
ifp = if_lookup_by_name_vrf (argv[0], vrf_id);
|
||||
@ -1242,7 +1383,7 @@ DEFUN (show_interface_desc,
|
||||
vrf_id_t vrf_id = VRF_DEFAULT;
|
||||
|
||||
if (argc > 0)
|
||||
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
|
||||
VRF_GET_ID (vrf_id, argv[0]);
|
||||
|
||||
if_show_description (vty, vrf_id);
|
||||
|
||||
@ -1874,13 +2015,15 @@ if_config_write (struct vty *vty)
|
||||
struct listnode *addrnode;
|
||||
struct connected *ifc;
|
||||
struct prefix *p;
|
||||
struct vrf *vrf;
|
||||
|
||||
if_data = ifp->info;
|
||||
vrf = vrf_lookup(ifp->vrf_id);
|
||||
|
||||
if (ifp->vrf_id == VRF_DEFAULT)
|
||||
vty_out (vty, "interface %s%s", ifp->name, VTY_NEWLINE);
|
||||
else
|
||||
vty_out (vty, "interface %s vrf %u%s", ifp->name, ifp->vrf_id,
|
||||
vty_out (vty, "interface %s vrf %s%s", ifp->name, vrf->name,
|
||||
VTY_NEWLINE);
|
||||
|
||||
if (if_data)
|
||||
@ -1940,6 +2083,23 @@ if_config_write (struct vty *vty)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
vrf_config_write (struct vty *vty)
|
||||
{
|
||||
struct listnode *node;
|
||||
struct vrf *vrf;
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO (vrf_list, node, vrf))
|
||||
{
|
||||
if (strcmp(vrf->name, VRF_DEFAULT_NAME))
|
||||
{
|
||||
vty_out (vty, "vrf %s%s", vrf->name, VTY_NEWLINE);
|
||||
vty_out (vty, "!%s", VTY_NEWLINE);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Allocate and initialize interface vector. */
|
||||
void
|
||||
zebra_if_init (void)
|
||||
@ -1950,6 +2110,7 @@ zebra_if_init (void)
|
||||
|
||||
/* Install configuration write function. */
|
||||
install_node (&interface_node, if_config_write);
|
||||
install_node (&vrf_node, vrf_config_write);
|
||||
|
||||
install_element (VIEW_NODE, &show_interface_cmd);
|
||||
install_element (VIEW_NODE, &show_interface_vrf_cmd);
|
||||
@ -1992,4 +2153,9 @@ zebra_if_init (void)
|
||||
install_element (INTERFACE_NODE, &ip_address_label_cmd);
|
||||
install_element (INTERFACE_NODE, &no_ip_address_label_cmd);
|
||||
#endif /* HAVE_NETLINK */
|
||||
|
||||
install_element (CONFIG_NODE, &zebra_vrf_cmd);
|
||||
install_element (CONFIG_NODE, &no_vrf_cmd);
|
||||
install_default (VRF_NODE);
|
||||
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
#define _ZEBRA_INTERFACE_H
|
||||
|
||||
#include "redistribute.h"
|
||||
#include "vrf.h"
|
||||
|
||||
#ifdef HAVE_IRDP
|
||||
#include "zebra/irdp.h"
|
||||
@ -206,6 +207,10 @@ struct zebra_if
|
||||
#endif /* SUNOS_5 */
|
||||
};
|
||||
|
||||
|
||||
extern struct interface *if_lookup_by_index_per_ns (struct zebra_ns *, u_int32_t);
|
||||
extern struct interface *if_link_per_ns (struct zebra_ns *, struct interface *);
|
||||
extern void if_unlink_per_ns (struct interface *);
|
||||
extern void if_nbr_ipv6ll_to_ipv4ll_neigh_update (struct interface *ifp,
|
||||
struct in6_addr *address, int add);
|
||||
extern void if_nbr_ipv6ll_to_ipv4ll_neigh_del_all (struct interface *ifp);
|
||||
@ -219,6 +224,9 @@ extern int if_subnet_add (struct interface *, struct connected *);
|
||||
extern int if_subnet_delete (struct interface *, struct connected *);
|
||||
extern int ipv6_address_configured (struct interface *ifp);
|
||||
|
||||
extern void vrf_delete_update (struct vrf *vrfp);
|
||||
extern void vrf_add_update (struct vrf *vrfp);
|
||||
|
||||
#ifdef HAVE_PROC_NET_DEV
|
||||
extern void ifstat_update_proc (void);
|
||||
#endif /* HAVE_PROC_NET_DEV */
|
||||
|
@ -196,7 +196,7 @@ if_set_prefix (struct interface *ifp, struct connected *ifc)
|
||||
struct prefix_ipv4 *p;
|
||||
|
||||
p = (struct prefix_ipv4 *) ifc->address;
|
||||
rib_lookup_and_pushup (p);
|
||||
rib_lookup_and_pushup (p, ifp->vrf_id);
|
||||
|
||||
memset (&addreq, 0, sizeof addreq);
|
||||
strncpy ((char *)&addreq.ifra_name, ifp->name, sizeof addreq.ifra_name);
|
||||
|
@ -56,10 +56,10 @@ int netlink_neigh_update (int cmd, int ifindex, __u32 addr, char *lla, int llale
|
||||
return 0;
|
||||
}
|
||||
|
||||
void kernel_init (struct zebra_vrf *zvrf) { return; }
|
||||
void kernel_terminate (struct zebra_vrf *zvrf) { return; }
|
||||
void kernel_init (struct zebra_ns *zns) { return; }
|
||||
void kernel_terminate (struct zebra_ns *zns) { return; }
|
||||
#ifdef HAVE_SYS_WEAK_ALIAS_PRAGMA
|
||||
#pragma weak route_read = kernel_init
|
||||
#else
|
||||
void route_read (struct zebra_vrf *zvrf) { return; }
|
||||
void route_read (struct zebra_ns *zns) { return; }
|
||||
#endif
|
||||
|
@ -1263,11 +1263,8 @@ kernel_read (struct thread *thread)
|
||||
|
||||
/* Make routing socket. */
|
||||
static void
|
||||
routing_socket (struct zebra_vrf *zvrf)
|
||||
routing_socket (struct zebra_ns *zns)
|
||||
{
|
||||
if (zvrf->vrf_id != VRF_DEFAULT)
|
||||
return;
|
||||
|
||||
if ( zserv_privs.change (ZPRIVS_RAISE) )
|
||||
zlog_err ("routing_socket: Can't raise privileges");
|
||||
|
||||
@ -1298,13 +1295,13 @@ routing_socket (struct zebra_vrf *zvrf)
|
||||
/* Exported interface function. This function simply calls
|
||||
routing_socket (). */
|
||||
void
|
||||
kernel_init (struct zebra_vrf *zvrf)
|
||||
kernel_init (struct zebra_ns *zns)
|
||||
{
|
||||
routing_socket (zvrf);
|
||||
routing_socket (zns);
|
||||
}
|
||||
|
||||
void
|
||||
kernel_terminate (struct zebra_vrf *zvrf)
|
||||
kernel_terminate (struct zebra_ns *zns)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
55
zebra/main.c
55
zebra/main.c
@ -220,9 +220,11 @@ zebra_vrf_new (vrf_id_t vrf_id, const char *name, void **info)
|
||||
{
|
||||
struct zebra_vrf *zvrf = *info;
|
||||
|
||||
zlog_info ("ZVRF %s with id %u", name, vrf_id);
|
||||
|
||||
if (! zvrf)
|
||||
{
|
||||
zvrf = zebra_vrf_alloc (vrf_id);
|
||||
zvrf = zebra_vrf_alloc (vrf_id, name);
|
||||
*info = (void *)zvrf;
|
||||
router_id_init (zvrf);
|
||||
}
|
||||
@ -230,6 +232,32 @@ 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
|
||||
|
||||
#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)
|
||||
@ -241,13 +269,22 @@ zebra_vrf_enable (vrf_id_t vrf_id, const char *name, void **info)
|
||||
#if defined (HAVE_RTADV)
|
||||
rtadv_init (zvrf);
|
||||
#endif
|
||||
kernel_init (zvrf);
|
||||
interface_list (zvrf);
|
||||
route_read (zvrf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
static int
|
||||
zebra_ns_disable (ns_id_t ns_id, void **info)
|
||||
{
|
||||
struct zebra_ns *zns = (struct zebra_ns *) (*info);
|
||||
|
||||
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)
|
||||
@ -272,7 +309,6 @@ zebra_vrf_disable (vrf_id_t vrf_id, const char *name, void **info)
|
||||
#if defined (HAVE_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);
|
||||
@ -284,10 +320,19 @@ zebra_vrf_disable (vrf_id_t vrf_id, const char *name, void **info)
|
||||
static 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);
|
||||
|
||||
/* 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. */
|
||||
|
@ -456,6 +456,47 @@ zebra_interface_delete_update (struct interface *ifp)
|
||||
}
|
||||
}
|
||||
|
||||
/* VRF information update. */
|
||||
void
|
||||
zebra_vrf_add_update (struct vrf *vrfp)
|
||||
{
|
||||
struct listnode *node, *nnode;
|
||||
struct zserv *client;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_EVENT)
|
||||
zlog_debug ("MESSAGE: ZEBRA_VRF_ADD %s", vrfp->name);
|
||||
|
||||
for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
|
||||
zsend_vrf_add (client, vrfp);
|
||||
}
|
||||
|
||||
void
|
||||
zebra_vrf_delete_update (struct vrf *vrfp)
|
||||
{
|
||||
struct listnode *node, *nnode;
|
||||
struct zserv *client;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_EVENT)
|
||||
zlog_debug ("MESSAGE: ZEBRA_VRF_DELETE %s", vrfp->name);
|
||||
|
||||
for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
|
||||
zsend_vrf_delete (client, vrfp);
|
||||
}
|
||||
|
||||
void
|
||||
zebra_vrf_update_all (struct zserv *client)
|
||||
{
|
||||
struct vrf *vrf;
|
||||
vrf_iter_t iter;
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
{
|
||||
if ((vrf = vrf_iter2vrf (iter)) && vrf->vrf_id)
|
||||
zsend_vrf_add (client, vrf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Interface address addition. */
|
||||
void
|
||||
zebra_interface_address_add_update (struct interface *ifp,
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "table.h"
|
||||
#include "zserv.h"
|
||||
#include "vty.h"
|
||||
#include "vrf.h"
|
||||
|
||||
extern void zebra_redistribute_add (int, struct zserv *, int, vrf_id_t);
|
||||
extern void zebra_redistribute_delete (int, struct zserv *, int, vrf_id_t);
|
||||
@ -41,6 +42,9 @@ extern void redistribute_delete (struct prefix *, struct rib *);
|
||||
extern void zebra_interface_up_update (struct interface *);
|
||||
extern void zebra_interface_down_update (struct interface *);
|
||||
|
||||
extern void zebra_vrf_add_update (struct vrf *);
|
||||
extern void zebra_vrf_update_all (struct zserv *);
|
||||
extern void zebra_vrf_delete_update (struct vrf *);
|
||||
extern void zebra_interface_add_update (struct interface *);
|
||||
extern void zebra_interface_delete_update (struct interface *);
|
||||
|
||||
|
@ -47,6 +47,11 @@ void zebra_interface_delete_update (struct interface *a)
|
||||
{ return; }
|
||||
#endif
|
||||
|
||||
void zebra_vrf_add_update (struct vrf *a)
|
||||
{ return; }
|
||||
void zebra_vrf_delete_update (struct vrf *a)
|
||||
{ return; }
|
||||
|
||||
void zebra_interface_address_add_update (struct interface *a,
|
||||
struct connected *b)
|
||||
{ return; }
|
||||
|
21
zebra/rib.h
21
zebra/rib.h
@ -295,10 +295,15 @@ struct zebra_ns
|
||||
/* 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;
|
||||
};
|
||||
|
||||
|
||||
/* Routing table instance. */
|
||||
struct zebra_vrf
|
||||
{
|
||||
@ -331,12 +336,6 @@ 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
|
||||
*/
|
||||
@ -356,6 +355,8 @@ struct zebra_vrf
|
||||
struct zebra_ns *zns;
|
||||
};
|
||||
|
||||
extern struct zebra_ns *dzns;
|
||||
|
||||
/*
|
||||
* rib_table_info_t
|
||||
*
|
||||
@ -413,8 +414,8 @@ extern void rib_nexthop_add (struct rib *rib, struct nexthop *nexthop);
|
||||
extern void rib_copy_nexthops (struct rib *rib, struct nexthop *nh);
|
||||
|
||||
extern int nexthop_has_fib_child(struct nexthop *);
|
||||
extern void rib_lookup_and_dump (struct prefix_ipv4 *);
|
||||
extern void rib_lookup_and_pushup (struct prefix_ipv4 *);
|
||||
extern void rib_lookup_and_dump (struct prefix_ipv4 *, vrf_id_t);
|
||||
extern void rib_lookup_and_pushup (struct prefix_ipv4 *, vrf_id_t);
|
||||
#define rib_dump(prefix ,rib) _rib_dump(__func__, prefix, rib)
|
||||
extern void _rib_dump (const char *,
|
||||
union prefix46constptr, const struct rib *);
|
||||
@ -432,7 +433,7 @@ extern struct nexthop *rib_nexthop_ipv6_ifindex_add (struct rib *rib,
|
||||
unsigned int ifindex);
|
||||
|
||||
extern struct zebra_vrf *zebra_vrf_lookup (vrf_id_t vrf_id);
|
||||
extern struct zebra_vrf *zebra_vrf_alloc (vrf_id_t);
|
||||
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);
|
||||
extern struct route_table *zebra_vrf_static_table (afi_t, safi_t, vrf_id_t);
|
||||
extern struct route_table *zebra_vrf_other_route_table (afi_t afi, u_int32_t table_id,
|
||||
|
@ -230,7 +230,7 @@ DEFUN (router_id,
|
||||
rid.family = AF_INET;
|
||||
|
||||
if (argc > 1)
|
||||
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
|
||||
VRF_GET_ID (vrf_id, argv[1]);
|
||||
|
||||
router_id_set (&rid, vrf_id);
|
||||
|
||||
@ -258,7 +258,7 @@ DEFUN (no_router_id,
|
||||
rid.family = AF_INET;
|
||||
|
||||
if (argc > 1)
|
||||
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
|
||||
VRF_GET_ID (vrf_id, argv[1]);
|
||||
|
||||
router_id_set (&rid, vrf_id);
|
||||
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "zebra/redistribute.h"
|
||||
#include "zebra/interface.h"
|
||||
#include "zebra/debug.h"
|
||||
#include "zebra/rtadv.h"
|
||||
|
||||
#include "rt_netlink.h"
|
||||
|
||||
@ -73,7 +74,7 @@ set_ifindex(struct interface *ifp, unsigned int ifi_index)
|
||||
{
|
||||
struct interface *oifp;
|
||||
|
||||
if (((oifp = if_lookup_by_index(ifi_index)) != NULL) && (oifp != ifp))
|
||||
if (((oifp = if_lookup_by_index_per_ns (dzns, ifi_index)) != NULL) && (oifp != ifp))
|
||||
{
|
||||
if (ifi_index == IFINDEX_INTERNAL)
|
||||
zlog_err("Netlink is setting interface %s ifindex to reserved "
|
||||
@ -146,7 +147,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, vrf_id_t vrf_id)
|
||||
netlink_socket (struct nlsock *nl, unsigned long groups, ns_id_t ns_id)
|
||||
{
|
||||
int ret;
|
||||
struct sockaddr_nl snl;
|
||||
@ -160,7 +161,7 @@ netlink_socket (struct nlsock *nl, unsigned long groups, vrf_id_t vrf_id)
|
||||
return -1;
|
||||
}
|
||||
|
||||
sock = vrf_socket (AF_NETLINK, SOCK_RAW, NETLINK_ROUTE, vrf_id);
|
||||
sock = vrf_socket (AF_NETLINK, SOCK_RAW, NETLINK_ROUTE, ns_id);
|
||||
if (sock < 0)
|
||||
{
|
||||
zlog (NULL, LOG_ERR, "Can't open %s socket: %s", nl->name,
|
||||
@ -260,12 +261,33 @@ netlink_request (int family, int type, struct nlsock *nl)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Pending: create an efficient table_id (in a tree/hash) based lookup)
|
||||
*/
|
||||
static vrf_id_t
|
||||
vrf_lookup_by_table (u_int32_t table_id)
|
||||
{
|
||||
struct zebra_vrf *zvrf;
|
||||
vrf_iter_t iter;
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
{
|
||||
if ((zvrf = vrf_iter2info (iter)) == NULL ||
|
||||
(zvrf->table_id != table_id))
|
||||
continue;
|
||||
|
||||
return zvrf->vrf_id;
|
||||
}
|
||||
|
||||
return VRF_DEFAULT;
|
||||
}
|
||||
|
||||
/* 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 *,
|
||||
vrf_id_t),
|
||||
struct nlsock *nl, struct zebra_vrf *zvrf)
|
||||
ns_id_t),
|
||||
struct nlsock *nl, struct zebra_ns *zns)
|
||||
{
|
||||
int status;
|
||||
int ret = 0;
|
||||
@ -354,7 +376,7 @@ netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *,
|
||||
}
|
||||
|
||||
/* Deal with errors that occur because of races in link handling */
|
||||
if (nl == &zvrf->netlink_cmd
|
||||
if (nl == &zns->netlink_cmd
|
||||
&& ((msg_type == RTM_DELROUTE &&
|
||||
(-errnum == ENODEV || -errnum == ESRCH))
|
||||
|| (msg_type == RTM_NEWROUTE && -errnum == EEXIST)))
|
||||
@ -367,7 +389,7 @@ netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (nl == &zvrf->netlink_cmd
|
||||
if (nl == &zns->netlink_cmd
|
||||
&& msg_type == RTM_NEWROUTE && -errnum == ESRCH)
|
||||
{
|
||||
/* This is known to happen in some situations, don't log
|
||||
@ -398,17 +420,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 != &zvrf->netlink_cmd
|
||||
&& h->nlmsg_pid == zvrf->netlink_cmd.snl.nl_pid
|
||||
if (nl != &zns->netlink_cmd
|
||||
&& h->nlmsg_pid == zns->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",
|
||||
zvrf->netlink_cmd.name, nl->name);
|
||||
zns->netlink_cmd.name, nl->name);
|
||||
continue;
|
||||
}
|
||||
|
||||
error = (*filter) (&snl, h, zvrf->vrf_id);
|
||||
error = (*filter) (&snl, h, zns->ns_id);
|
||||
if (error < 0)
|
||||
{
|
||||
zlog (NULL, LOG_ERR, "%s filter function error", nl->name);
|
||||
@ -476,6 +498,98 @@ netlink_interface_update_hw_addr (struct rtattr **tb, struct interface *ifp)
|
||||
}
|
||||
}
|
||||
|
||||
#define parse_rtattr_nested(tb, max, rta) \
|
||||
netlink_parse_rtattr((tb), (max), RTA_DATA(rta), RTA_PAYLOAD(rta))
|
||||
|
||||
static void
|
||||
netlink_vrf_change (struct nlmsghdr *h, struct rtattr *tb, const char *name)
|
||||
{
|
||||
struct ifinfomsg *ifi;
|
||||
struct rtattr *linkinfo[IFLA_INFO_MAX+1];
|
||||
struct rtattr *attr[IFLA_VRF_MAX+1];
|
||||
struct vrf *vrf;
|
||||
struct zebra_vrf *zvrf;
|
||||
u_int32_t nl_table_id;
|
||||
|
||||
ifi = NLMSG_DATA (h);
|
||||
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug ("%s: received VRF device message: %s", __func__, name);
|
||||
|
||||
parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, tb);
|
||||
|
||||
if (!linkinfo[IFLA_INFO_DATA]) {
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug ("%s: IFLA_INFO_DATA missing from VRF message: %s", __func__, name);
|
||||
return;
|
||||
}
|
||||
|
||||
parse_rtattr_nested(attr, IFLA_VRF_MAX, linkinfo[IFLA_INFO_DATA]);
|
||||
if (!attr[IFLA_VRF_TABLE]) {
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug ("%s: IFLA_VRF_TABLE missing from VRF message: %s", __func__, name);
|
||||
return;
|
||||
}
|
||||
|
||||
nl_table_id = *(u_int32_t *)RTA_DATA(attr[IFLA_VRF_TABLE]);
|
||||
|
||||
if (h->nlmsg_type == RTM_NEWLINK)
|
||||
{
|
||||
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug ("%s: RTM_NEWLINK for VRF index %u, table %u", __func__,
|
||||
ifi->ifi_index, nl_table_id);
|
||||
|
||||
vrf = vrf_get((vrf_id_t)ifi->ifi_index, name); // It would create vrf
|
||||
if (!vrf)
|
||||
{
|
||||
zlog_err ("VRF %s id %u not created", name, ifi->ifi_index);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Enable the created VRF. */
|
||||
if (!vrf_enable (vrf))
|
||||
{
|
||||
zlog_err ("Failed to enable VRF %s id %u", name, ifi->ifi_index);
|
||||
return;
|
||||
}
|
||||
|
||||
/*Pending: See if you want to optimize this code.. vrf, zvrf all have name */
|
||||
zvrf = vrf->info;
|
||||
zvrf->table_id = nl_table_id;
|
||||
|
||||
vrf_add_update(vrf);
|
||||
}
|
||||
else //h->nlmsg_type == RTM_DELLINK
|
||||
{
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug ("%s: RTM_DELLINK for vrf id %u", __func__, ifi->ifi_index);
|
||||
|
||||
vrf = vrf_lookup ((vrf_id_t)ifi->ifi_index);
|
||||
|
||||
if (!vrf)
|
||||
zlog_warn ("%s: vrf not found", __func__);
|
||||
|
||||
vrf_delete_update(vrf);
|
||||
|
||||
//Pending: keeping VRF around just like its for other links.
|
||||
//vrf_delete (vrf);
|
||||
}
|
||||
}
|
||||
|
||||
static char *
|
||||
parse_link_kind (struct rtattr *tb)
|
||||
{
|
||||
struct rtattr *linkinfo[IFLA_INFO_MAX+1];
|
||||
|
||||
memset (linkinfo, 0, sizeof(struct rtattr *)*(IFLA_INFO_MAX+1));
|
||||
parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, tb);
|
||||
|
||||
if (linkinfo[IFLA_INFO_KIND])
|
||||
return RTA_DATA(linkinfo[IFLA_INFO_KIND]);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
/* Called from interface_lookup_netlink(). This function is only used
|
||||
during bootstrap. */
|
||||
static int
|
||||
@ -518,6 +632,20 @@ netlink_interface (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
return -1;
|
||||
name = (char *) RTA_DATA (tb[IFLA_IFNAME]);
|
||||
|
||||
if (tb[IFLA_LINKINFO])
|
||||
{
|
||||
char *kind = parse_link_kind(tb[IFLA_LINKINFO]);
|
||||
|
||||
if (kind && strcmp(kind, "vrf") == 0)
|
||||
{
|
||||
netlink_vrf_change(h, tb[IFLA_LINKINFO], name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (tb[IFLA_MASTER])
|
||||
vrf_id = *(u_int32_t *)RTA_DATA(tb[IFLA_MASTER]);
|
||||
|
||||
/* Add interface. */
|
||||
ifp = if_get_by_name_vrf (name, vrf_id);
|
||||
set_ifindex(ifp, ifi->ifi_index);
|
||||
@ -537,7 +665,7 @@ 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,
|
||||
vrf_id_t vrf_id)
|
||||
ns_id_t ns_id)
|
||||
{
|
||||
int len;
|
||||
struct ifaddrmsg *ifa;
|
||||
@ -548,6 +676,8 @@ netlink_interface_addr (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
u_char flags = 0;
|
||||
char *label = NULL;
|
||||
|
||||
vrf_id_t vrf_id = ns_id;
|
||||
|
||||
ifa = NLMSG_DATA (h);
|
||||
|
||||
if (ifa->ifa_family != AF_INET
|
||||
@ -567,7 +697,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_vrf (ifa->ifa_index, vrf_id);
|
||||
ifp = if_lookup_by_index_per_ns (dzns, ifa->ifa_index);
|
||||
if (ifp == NULL)
|
||||
{
|
||||
zlog_err ("netlink_interface_addr can't find interface by index %d vrf %u",
|
||||
@ -708,6 +838,8 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
if (!is_zebra_valid_kernel_table(table) && !is_zebra_main_routing_table(table))
|
||||
return 0;
|
||||
|
||||
vrf_id = vrf_lookup_by_table(table);
|
||||
|
||||
len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct rtmsg));
|
||||
if (len < 0)
|
||||
return -1;
|
||||
@ -854,7 +986,7 @@ static const struct message rtproto_str[] = {
|
||||
/* Routing information change from the kernel. */
|
||||
static int
|
||||
netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
vrf_id_t vrf_id)
|
||||
ns_id_t ns_id)
|
||||
{
|
||||
int len;
|
||||
struct rtmsg *rtm;
|
||||
@ -871,6 +1003,8 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
void *gate;
|
||||
void *src;
|
||||
|
||||
vrf_id_t vrf_id = ns_id;
|
||||
|
||||
rtm = NLMSG_DATA (h);
|
||||
|
||||
if (!(h->nlmsg_type == RTM_NEWROUTE || h->nlmsg_type == RTM_DELROUTE))
|
||||
@ -899,6 +1033,8 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
if (!is_zebra_valid_kernel_table(table) && !is_zebra_main_routing_table(table))
|
||||
return 0;
|
||||
|
||||
vrf_id = vrf_lookup_by_table(table);
|
||||
|
||||
len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct rtmsg));
|
||||
if (len < 0)
|
||||
return -1;
|
||||
@ -1062,13 +1198,17 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
|
||||
static int
|
||||
netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
vrf_id_t vrf_id)
|
||||
ns_id_t ns_id)
|
||||
{
|
||||
int len;
|
||||
struct ifinfomsg *ifi;
|
||||
struct rtattr *tb[IFLA_MAX + 1];
|
||||
struct interface *ifp;
|
||||
char *name;
|
||||
struct connected *ifc;
|
||||
struct listnode *node;
|
||||
|
||||
vrf_id_t vrf_id = ns_id;
|
||||
|
||||
ifi = NLMSG_DATA (h);
|
||||
|
||||
@ -1106,21 +1246,58 @@ netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
return -1;
|
||||
name = (char *) RTA_DATA (tb[IFLA_IFNAME]);
|
||||
|
||||
if (tb[IFLA_LINKINFO])
|
||||
{
|
||||
char *kind = parse_link_kind(tb[IFLA_LINKINFO]);
|
||||
|
||||
if (kind && strcmp(kind, "vrf") == 0)
|
||||
{
|
||||
netlink_vrf_change(h, tb[IFLA_LINKINFO], name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add interface. */
|
||||
if (h->nlmsg_type == RTM_NEWLINK)
|
||||
{
|
||||
ifp = if_lookup_by_name_vrf (name, vrf_id);
|
||||
if (tb[IFLA_MASTER])
|
||||
vrf_id = *(u_int32_t *)RTA_DATA(tb[IFLA_MASTER]);
|
||||
|
||||
if (ifp == NULL || !CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
|
||||
/* clean up any old ifps in a different VRF */
|
||||
ifp = if_lookup_by_index_per_ns (dzns, ifi->ifi_index);
|
||||
if (ifp && ifp->vrf_id != vrf_id)
|
||||
{
|
||||
if_down (ifp); //Ideally, we should have down/delete come from kernel
|
||||
// if_delete_update (ifp); //Pending: see how best to make the old ifp unusable
|
||||
for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, ifc))
|
||||
if (ifc->address->family == AF_INET6)
|
||||
ipv6_nd_suppress_ra_set (ifp, RA_SUPPRESS);
|
||||
}
|
||||
|
||||
if (ifp == NULL || !CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE) ||
|
||||
ifp->vrf_id != vrf_id)
|
||||
{
|
||||
if (ifp == NULL)
|
||||
ifp = if_get_by_name_vrf (name, vrf_id);
|
||||
else
|
||||
{
|
||||
if_update_vrf (ifp, name, strlen(name), vrf_id);
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, ifc))
|
||||
if (ifc->address->family == AF_INET6)
|
||||
ipv6_nd_suppress_ra_set (ifp, RA_ENABLE);
|
||||
}
|
||||
|
||||
set_ifindex(ifp, ifi->ifi_index);
|
||||
ifp->flags = ifi->ifi_flags & 0x0000fffff;
|
||||
ifp->mtu6 = ifp->mtu = *(int *) RTA_DATA (tb[IFLA_MTU]);
|
||||
ifp->metric = 0;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug ("%s: RTM_NEWLINK for %s vrf_id %u", __func__, name,
|
||||
ifp->vrf_id);
|
||||
|
||||
|
||||
netlink_interface_update_hw_addr (tb, ifp);
|
||||
|
||||
/* If new link is added. */
|
||||
@ -1133,6 +1310,12 @@ netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
ifp->mtu6 = ifp->mtu = *(int *) RTA_DATA (tb[IFLA_MTU]);
|
||||
ifp->metric = 0;
|
||||
|
||||
// Pending, handle the vrf_id change..
|
||||
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug ("%s: RTM_NEWLINK status for %s vrf_id %u", __func__, name,
|
||||
ifp->vrf_id);
|
||||
|
||||
netlink_interface_update_hw_addr (tb, ifp);
|
||||
|
||||
if (if_is_no_ptm_operative (ifp))
|
||||
@ -1154,6 +1337,9 @@ netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tb[IFLA_MASTER])
|
||||
vrf_id = *(u_int32_t *)RTA_DATA(tb[IFLA_MASTER]);
|
||||
|
||||
/* RTM_DELLINK. */
|
||||
ifp = if_lookup_by_name_vrf (name, vrf_id);
|
||||
|
||||
@ -1172,7 +1358,7 @@ netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
|
||||
static int
|
||||
netlink_information_fetch (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
vrf_id_t vrf_id)
|
||||
ns_id_t ns_id)
|
||||
{
|
||||
/* JF: Ignore messages that aren't from the kernel */
|
||||
if ( snl->nl_pid != 0 )
|
||||
@ -1184,26 +1370,26 @@ netlink_information_fetch (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
switch (h->nlmsg_type)
|
||||
{
|
||||
case RTM_NEWROUTE:
|
||||
return netlink_route_change (snl, h, vrf_id);
|
||||
return netlink_route_change (snl, h, ns_id);
|
||||
break;
|
||||
case RTM_DELROUTE:
|
||||
return netlink_route_change (snl, h, vrf_id);
|
||||
return netlink_route_change (snl, h, ns_id);
|
||||
break;
|
||||
case RTM_NEWLINK:
|
||||
return netlink_link_change (snl, h, vrf_id);
|
||||
return netlink_link_change (snl, h, ns_id);
|
||||
break;
|
||||
case RTM_DELLINK:
|
||||
return netlink_link_change (snl, h, vrf_id);
|
||||
return netlink_link_change (snl, h, ns_id);
|
||||
break;
|
||||
case RTM_NEWADDR:
|
||||
return netlink_interface_addr (snl, h, vrf_id);
|
||||
return netlink_interface_addr (snl, h, ns_id);
|
||||
break;
|
||||
case RTM_DELADDR:
|
||||
return netlink_interface_addr (snl, h, vrf_id);
|
||||
return netlink_interface_addr (snl, h, ns_id);
|
||||
break;
|
||||
default:
|
||||
zlog_warn ("Unknown netlink nlmsg_type %d vrf %u\n", h->nlmsg_type,
|
||||
vrf_id);
|
||||
ns_id);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
@ -1211,32 +1397,32 @@ netlink_information_fetch (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
|
||||
/* Interface lookup by netlink socket. */
|
||||
int
|
||||
interface_lookup_netlink (struct zebra_vrf *zvrf)
|
||||
interface_lookup_netlink (struct zebra_ns *zns)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Get interface information. */
|
||||
ret = netlink_request (AF_PACKET, RTM_GETLINK, &zvrf->netlink_cmd);
|
||||
ret = netlink_request (AF_PACKET, RTM_GETLINK, &zns->netlink_cmd);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = netlink_parse_info (netlink_interface, &zvrf->netlink_cmd, zvrf);
|
||||
ret = netlink_parse_info (netlink_interface, &zns->netlink_cmd, zns);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Get IPv4 address of the interfaces. */
|
||||
ret = netlink_request (AF_INET, RTM_GETADDR, &zvrf->netlink_cmd);
|
||||
ret = netlink_request (AF_INET, RTM_GETADDR, &zns->netlink_cmd);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = netlink_parse_info (netlink_interface_addr, &zvrf->netlink_cmd, zvrf);
|
||||
ret = netlink_parse_info (netlink_interface_addr, &zns->netlink_cmd, zns);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
/* Get IPv6 address of the interfaces. */
|
||||
ret = netlink_request (AF_INET6, RTM_GETADDR, &zvrf->netlink_cmd);
|
||||
ret = netlink_request (AF_INET6, RTM_GETADDR, &zns->netlink_cmd);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = netlink_parse_info (netlink_interface_addr, &zvrf->netlink_cmd, zvrf);
|
||||
ret = netlink_parse_info (netlink_interface_addr, &zns->netlink_cmd, zns);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
#endif /* HAVE_IPV6 */
|
||||
@ -1247,24 +1433,24 @@ interface_lookup_netlink (struct zebra_vrf *zvrf)
|
||||
/* Routing table read function using netlink interface. Only called
|
||||
bootstrap time. */
|
||||
int
|
||||
netlink_route_read (struct zebra_vrf *zvrf)
|
||||
netlink_route_read (struct zebra_ns *zns)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Get IPv4 routing table. */
|
||||
ret = netlink_request (AF_INET, RTM_GETROUTE, &zvrf->netlink_cmd);
|
||||
ret = netlink_request (AF_INET, RTM_GETROUTE, &zns->netlink_cmd);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = netlink_parse_info (netlink_routing_table, &zvrf->netlink_cmd, zvrf);
|
||||
ret = netlink_parse_info (netlink_routing_table, &zns->netlink_cmd, zns);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
/* Get IPv6 routing table. */
|
||||
ret = netlink_request (AF_INET6, RTM_GETROUTE, &zvrf->netlink_cmd);
|
||||
ret = netlink_request (AF_INET6, RTM_GETROUTE, &zns->netlink_cmd);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = netlink_parse_info (netlink_routing_table, &zvrf->netlink_cmd, zvrf);
|
||||
ret = netlink_parse_info (netlink_routing_table, &zns->netlink_cmd, zns);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
#endif /* HAVE_IPV6 */
|
||||
@ -1338,16 +1524,16 @@ addattr32 (struct nlmsghdr *n, unsigned int maxlen, int type, int data)
|
||||
|
||||
static int
|
||||
netlink_talk_filter (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||
vrf_id_t vrf_id)
|
||||
ns_id_t ns_id)
|
||||
{
|
||||
zlog_warn ("netlink_talk: ignoring message type 0x%04x vrf %u", h->nlmsg_type,
|
||||
vrf_id);
|
||||
zlog_warn ("netlink_talk: ignoring message type 0x%04x NS %u", h->nlmsg_type,
|
||||
ns_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* sendmsg() to netlink socket then recvmsg(). */
|
||||
static int
|
||||
netlink_talk (struct nlmsghdr *n, struct nlsock *nl, struct zebra_vrf *zvrf)
|
||||
netlink_talk (struct nlmsghdr *n, struct nlsock *nl, struct zebra_ns *zns)
|
||||
{
|
||||
int status;
|
||||
struct sockaddr_nl snl;
|
||||
@ -1397,7 +1583,7 @@ netlink_talk (struct nlmsghdr *n, struct nlsock *nl, struct zebra_vrf *zvrf)
|
||||
* Get reply from netlink socket.
|
||||
* The reply should either be an acknowlegement or an error.
|
||||
*/
|
||||
return netlink_parse_info (netlink_talk_filter, nl, zvrf);
|
||||
return netlink_parse_info (netlink_talk_filter, nl, zns);
|
||||
}
|
||||
|
||||
/* Routing table change via netlink interface. */
|
||||
@ -1410,7 +1596,7 @@ 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 zebra_ns *zns = dzns;
|
||||
|
||||
struct
|
||||
{
|
||||
@ -1473,7 +1659,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, &zvrf->netlink_cmd, VRF_DEFAULT);
|
||||
ret = netlink_talk (&req.n, &zns->netlink_cmd, NS_DEFAULT);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
|
||||
@ -1789,7 +1975,7 @@ 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
|
||||
struct zebra_ns *zns = dzns;
|
||||
|
||||
memset(&req.n, 0, sizeof(req.n));
|
||||
memset(&req.ndm, 0, sizeof(req.ndm));
|
||||
@ -1805,7 +1991,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, &zvrf->netlink_cmd, VRF_DEFAULT);
|
||||
return netlink_talk (&req.n, &zns->netlink_cmd, NS_DEFAULT);
|
||||
}
|
||||
|
||||
/* Routing table change via netlink interface. */
|
||||
@ -1831,6 +2017,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_vrf *zvrf = vrf_info_lookup (rib->vrf_id);
|
||||
|
||||
memset (&req, 0, sizeof req - NL_PKT_BUF_SIZE);
|
||||
@ -2083,7 +2270,7 @@ skip:
|
||||
snl.nl_family = AF_NETLINK;
|
||||
|
||||
/* Talk to netlink socket. */
|
||||
return netlink_talk (&req.n, &zvrf->netlink_cmd, zvrf);
|
||||
return netlink_talk (&req.n, &zns->netlink_cmd, zns);
|
||||
}
|
||||
|
||||
int
|
||||
@ -2152,7 +2339,7 @@ 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);
|
||||
struct zebra_ns *zns = dzns; //vrf_info_lookup (ifp->vrf_id);
|
||||
|
||||
p = ifc->address;
|
||||
memset (&req, 0, sizeof req - NL_PKT_BUF_SIZE);
|
||||
@ -2186,7 +2373,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, &zvrf->netlink_cmd, zvrf);
|
||||
return netlink_talk (&req.n, &zns->netlink_cmd, zns);
|
||||
}
|
||||
|
||||
int
|
||||
@ -2208,10 +2395,10 @@ extern struct thread_master *master;
|
||||
static int
|
||||
kernel_read (struct thread *thread)
|
||||
{
|
||||
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);
|
||||
struct zebra_ns *zns = (struct zebra_ns *)THREAD_ARG (thread);
|
||||
netlink_parse_info (netlink_information_fetch, &zns->netlink, zns);
|
||||
zns->t_netlink = thread_add_read (zebrad.master, kernel_read, zns,
|
||||
zns->netlink.sock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -2250,7 +2437,7 @@ static void netlink_install_filter (int sock, __u32 pid)
|
||||
/* Exported interface function. This function simply calls
|
||||
netlink_socket (). */
|
||||
void
|
||||
kernel_init (struct zebra_vrf *zvrf)
|
||||
kernel_init (struct zebra_ns *zns)
|
||||
{
|
||||
unsigned long groups;
|
||||
|
||||
@ -2258,42 +2445,42 @@ kernel_init (struct zebra_vrf *zvrf)
|
||||
#ifdef HAVE_IPV6
|
||||
groups |= RTMGRP_IPV6_ROUTE | RTMGRP_IPV6_IFADDR;
|
||||
#endif /* HAVE_IPV6 */
|
||||
netlink_socket (&zvrf->netlink, groups, zvrf->vrf_id);
|
||||
netlink_socket (&zvrf->netlink_cmd, 0, zvrf->vrf_id);
|
||||
netlink_socket (&zns->netlink, groups, zns->ns_id);
|
||||
netlink_socket (&zns->netlink_cmd, 0, zns->ns_id);
|
||||
|
||||
/* Register kernel socket. */
|
||||
if (zvrf->netlink.sock > 0)
|
||||
if (zns->netlink.sock > 0)
|
||||
{
|
||||
/* Only want non-blocking on the netlink event socket */
|
||||
if (fcntl (zvrf->netlink.sock, F_SETFL, O_NONBLOCK) < 0)
|
||||
zlog_err ("Can't set %s socket flags: %s", zvrf->netlink.name,
|
||||
if (fcntl (zns->netlink.sock, F_SETFL, O_NONBLOCK) < 0)
|
||||
zlog_err ("Can't set %s socket flags: %s", zns->netlink.name,
|
||||
safe_strerror (errno));
|
||||
|
||||
/* Set receive buffer size if it's set from command line */
|
||||
if (nl_rcvbufsize)
|
||||
netlink_recvbuf (&zvrf->netlink, nl_rcvbufsize);
|
||||
netlink_recvbuf (&zns->netlink, nl_rcvbufsize);
|
||||
|
||||
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);
|
||||
netlink_install_filter (zns->netlink.sock, zns->netlink_cmd.snl.nl_pid);
|
||||
zns->t_netlink = thread_add_read (zebrad.master, kernel_read, zns,
|
||||
zns->netlink.sock);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
kernel_terminate (struct zebra_vrf *zvrf)
|
||||
kernel_terminate (struct zebra_ns *zns)
|
||||
{
|
||||
THREAD_READ_OFF (zvrf->t_netlink);
|
||||
THREAD_READ_OFF (zns->t_netlink);
|
||||
|
||||
if (zvrf->netlink.sock >= 0)
|
||||
if (zns->netlink.sock >= 0)
|
||||
{
|
||||
close (zvrf->netlink.sock);
|
||||
zvrf->netlink.sock = -1;
|
||||
close (zns->netlink.sock);
|
||||
zns->netlink.sock = -1;
|
||||
}
|
||||
|
||||
if (zvrf->netlink_cmd.sock >= 0)
|
||||
if (zns->netlink_cmd.sock >= 0)
|
||||
{
|
||||
close (zvrf->netlink_cmd.sock);
|
||||
zvrf->netlink_cmd.sock = -1;
|
||||
close (zns->netlink_cmd.sock);
|
||||
zns->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 interface_lookup_netlink (struct zebra_vrf *zvrf);
|
||||
extern int netlink_route_read (struct zebra_vrf *zvrf);
|
||||
extern int interface_lookup_netlink (struct zebra_ns *zns);
|
||||
extern int netlink_route_read (struct zebra_ns *zns);
|
||||
|
||||
#endif /* HAVE_NETLINK */
|
||||
|
||||
|
@ -95,7 +95,7 @@ handle_route_entry (mib2_ipRouteEntry_t *routeEntry)
|
||||
}
|
||||
|
||||
void
|
||||
route_read (struct zebra_vrf *zvrf)
|
||||
route_read (struct zebra_ns *zns)
|
||||
{
|
||||
char storage[RT_BUFSIZ];
|
||||
|
||||
@ -110,10 +110,6 @@ route_read (struct zebra_vrf *zvrf)
|
||||
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 (struct zebra_vrf *zvrf)
|
||||
void route_read (struct zebra_ns *zns)
|
||||
{
|
||||
netlink_route_read (zvrf);
|
||||
netlink_route_read (zns);
|
||||
}
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
/* Kernel routing table read up by sysctl function. */
|
||||
void
|
||||
route_read (struct zebra_vrf *zvrf)
|
||||
route_read (struct zebra_ns *zns)
|
||||
{
|
||||
caddr_t buf, end, ref;
|
||||
size_t bufsiz;
|
||||
@ -49,7 +49,7 @@ route_read (struct zebra_vrf *zvrf)
|
||||
0
|
||||
};
|
||||
|
||||
if (zvrf->vrf_id != VRF_DEFAULT)
|
||||
if (zns->ns_id != NS_DEFAULT)
|
||||
return;
|
||||
|
||||
/* Get buffer size. */
|
||||
|
@ -210,7 +210,7 @@ zebra_vrf_new (vrf_id_t vrf_id, const char *name, void **info)
|
||||
|
||||
if (! zvrf)
|
||||
{
|
||||
zvrf = zebra_vrf_alloc (vrf_id);
|
||||
zvrf = zebra_vrf_alloc (vrf_id, name);
|
||||
*info = (void *)zvrf;
|
||||
}
|
||||
|
||||
@ -225,9 +225,6 @@ zebra_vrf_enable (vrf_id_t vrf_id, const char *name, void **info)
|
||||
|
||||
assert (zvrf);
|
||||
|
||||
kernel_init (zvrf);
|
||||
route_read (zvrf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -252,8 +249,6 @@ zebra_vrf_disable (vrf_id_t vrf_id, const char *name, void **info)
|
||||
if_down (ifp);
|
||||
}
|
||||
|
||||
kernel_terminate (zvrf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -100,7 +100,7 @@ zsend_bfd_peer_replay (int cmd, struct zserv *client)
|
||||
s = client->obuf;
|
||||
stream_reset (s);
|
||||
|
||||
zserv_create_header (s, cmd, VRF_DEFAULT); //Pending:
|
||||
zserv_create_header (s, cmd, VRF_DEFAULT); //Pending: adjust when multi-vrf bfd work
|
||||
|
||||
/* Write packet size. */
|
||||
stream_putw_at (s, 0, stream_get_endp (s));
|
||||
|
@ -213,6 +213,9 @@ rib_nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4,
|
||||
nexthop->src.ipv4 = *src;
|
||||
nexthop->ifindex = ifindex;
|
||||
ifp = if_lookup_by_index (nexthop->ifindex);
|
||||
/*Pending: need to think if null ifp here is ok during bootup?
|
||||
There was a crash because ifp here was coming to be NULL */
|
||||
if (ifp)
|
||||
if (connected_is_unnumbered(ifp)) {
|
||||
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK);
|
||||
}
|
||||
@ -1891,19 +1894,13 @@ rib_link (struct route_node *rn, struct rib *rib, int process)
|
||||
rib->next = head;
|
||||
dest->routes = rib;
|
||||
|
||||
/* Further processing only if entry is in main table */
|
||||
if ((rib->table == RT_TABLE_MAIN) || (rib->table == zebrad.rtm_table_default))
|
||||
{
|
||||
if (process)
|
||||
rib_queue_add (&zebrad, rn);
|
||||
}
|
||||
afi = (rn->p.family == AF_INET) ? AFI_IP :
|
||||
(rn->p.family == AF_INET6) ? AFI_IP6 : AFI_MAX;
|
||||
if (is_zebra_import_table_enabled (afi, rib->table))
|
||||
zebra_add_import_table_entry(rn, rib);
|
||||
else
|
||||
{
|
||||
afi = (rn->p.family == AF_INET) ? AFI_IP :
|
||||
(rn->p.family == AF_INET6) ? AFI_IP6 : AFI_MAX;
|
||||
if (is_zebra_import_table_enabled (afi, rib->table))
|
||||
zebra_add_import_table_entry(rn, rib);
|
||||
}
|
||||
if (process)
|
||||
rib_queue_add (&zebrad, rn);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1962,14 +1959,11 @@ rib_delnode (struct route_node *rn, struct rib *rib)
|
||||
|
||||
SET_FLAG (rib->status, RIB_ENTRY_REMOVED);
|
||||
|
||||
if ((rib->table == RT_TABLE_MAIN) || (rib->table == zebrad.rtm_table_default))
|
||||
rib_queue_add (&zebrad, rn);
|
||||
else
|
||||
afi = (rn->p.family == AF_INET) ? AFI_IP :
|
||||
(rn->p.family == AF_INET6) ? AFI_IP6 : AFI_MAX;
|
||||
if (is_zebra_import_table_enabled (afi, rib->table))
|
||||
{
|
||||
afi = (rn->p.family == AF_INET) ? AFI_IP :
|
||||
(rn->p.family == AF_INET6) ? AFI_IP6 : AFI_MAX;
|
||||
if (is_zebra_import_table_enabled (afi, rib->table))
|
||||
zebra_del_import_table_entry(rn, rib);
|
||||
zebra_del_import_table_entry(rn, rib);
|
||||
/* Just clean up if non main table */
|
||||
if (IS_ZEBRA_DEBUG_RIB)
|
||||
{
|
||||
@ -1984,6 +1978,10 @@ rib_delnode (struct route_node *rn, struct rib *rib)
|
||||
|
||||
rib_unlink(rn, rib);
|
||||
}
|
||||
else
|
||||
{
|
||||
rib_queue_add (&zebrad, rn);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
@ -2174,7 +2172,7 @@ void _rib_dump (const char * func,
|
||||
* RIB entry found by rib_lookup_ipv4_route()
|
||||
*/
|
||||
|
||||
void rib_lookup_and_dump (struct prefix_ipv4 * p)
|
||||
void rib_lookup_and_dump (struct prefix_ipv4 * p, vrf_id_t vrf_id)
|
||||
{
|
||||
struct route_table *table;
|
||||
struct route_node *rn;
|
||||
@ -2182,7 +2180,7 @@ void rib_lookup_and_dump (struct prefix_ipv4 * p)
|
||||
char prefix_buf[INET_ADDRSTRLEN];
|
||||
|
||||
/* Lookup table. */
|
||||
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
|
||||
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
|
||||
if (! table)
|
||||
{
|
||||
zlog_err ("%s: zebra_vrf_table() returned NULL", __func__);
|
||||
@ -2224,14 +2222,14 @@ void rib_lookup_and_dump (struct prefix_ipv4 * p)
|
||||
* actions, if needed: remove such a route from FIB and deSELECT
|
||||
* corresponding RIB entry. Then put affected RN into RIBQ head.
|
||||
*/
|
||||
void rib_lookup_and_pushup (struct prefix_ipv4 * p)
|
||||
void rib_lookup_and_pushup (struct prefix_ipv4 * p, vrf_id_t vrf_id)
|
||||
{
|
||||
struct route_table *table;
|
||||
struct route_node *rn;
|
||||
struct rib *rib;
|
||||
unsigned changed = 0;
|
||||
|
||||
if (NULL == (table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT)))
|
||||
if (NULL == (table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id)))
|
||||
{
|
||||
zlog_err ("%s: zebra_vrf_table() returned NULL", __func__);
|
||||
return;
|
||||
@ -2591,7 +2589,7 @@ static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_ro
|
||||
rib->distance = si->distance;
|
||||
rib->metric = 0;
|
||||
rib->vrf_id = si->vrf_id;
|
||||
rib->table = zebrad.rtm_table_default;
|
||||
rib->table = si->vrf_id ? (zebra_vrf_lookup(si->vrf_id))->table_id : zebrad.rtm_table_default;
|
||||
rib->nexthop_num = 0;
|
||||
rib->tag = si->tag;
|
||||
|
||||
@ -3069,7 +3067,7 @@ rib_add_ipv6_multipath (struct prefix *p, struct rib *rib, safi_t safi,
|
||||
if (!rib)
|
||||
return 0;
|
||||
|
||||
table = zebra_vrf_table (AFI_IP, safi, VRF_DEFAULT);
|
||||
table = zebra_vrf_table (AFI_IP, safi, rib->vrf_id);
|
||||
if (!table)
|
||||
return 0;
|
||||
/* Make it sure prefixlen is applied to the prefix. */
|
||||
@ -3085,11 +3083,11 @@ rib_add_ipv6_multipath (struct prefix *p, struct rib *rib, safi_t safi,
|
||||
/* Lookup table. */
|
||||
if ((table_id == RT_TABLE_MAIN) || (table_id == zebrad.rtm_table_default))
|
||||
{
|
||||
table = zebra_vrf_table (AFI_IP6, safi, VRF_DEFAULT);
|
||||
table = zebra_vrf_table (AFI_IP6, safi, rib->vrf_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
table = zebra_vrf_other_route_table(AFI_IP6, table_id, VRF_DEFAULT);
|
||||
table = zebra_vrf_other_route_table(AFI_IP6, table_id, rib->vrf_id);
|
||||
}
|
||||
|
||||
if (! table)
|
||||
@ -3179,6 +3177,7 @@ rib_add_ipv6_multipath (struct prefix *p, struct rib *rib, safi_t safi,
|
||||
}
|
||||
|
||||
/* XXX factor with rib_delete_ipv6 */
|
||||
|
||||
int
|
||||
rib_delete_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
|
||||
struct in6_addr *gate, unsigned int ifindex, vrf_id_t vrf_id,
|
||||
@ -3204,7 +3203,7 @@ rib_delete_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
|
||||
}
|
||||
else
|
||||
{
|
||||
table = zebra_vrf_other_route_table(AFI_IP6, table_id, VRF_DEFAULT);
|
||||
table = zebra_vrf_other_route_table(AFI_IP6, table_id, vrf_id);
|
||||
}
|
||||
if (! table)
|
||||
return 0;
|
||||
@ -3845,12 +3844,9 @@ zebra_vrf_table_create (struct zebra_vrf *zvrf, afi_t afi, safi_t safi)
|
||||
|
||||
/* Allocate new zebra VRF. */
|
||||
struct zebra_vrf *
|
||||
zebra_vrf_alloc (vrf_id_t vrf_id)
|
||||
zebra_vrf_alloc (vrf_id_t vrf_id, const char *name)
|
||||
{
|
||||
struct zebra_vrf *zvrf;
|
||||
#ifdef HAVE_NETLINK
|
||||
char nl_name[64];
|
||||
#endif
|
||||
|
||||
zvrf = XCALLOC (MTYPE_ZEBRA_VRF, sizeof (struct zebra_vrf));
|
||||
|
||||
@ -3873,16 +3869,11 @@ 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
|
||||
if (name)
|
||||
{
|
||||
strncpy (zvrf->name, name, strlen(name));
|
||||
zvrf->name[strlen(name)] = '\0';
|
||||
}
|
||||
|
||||
return zvrf;
|
||||
}
|
||||
@ -3939,12 +3930,22 @@ zebra_vrf_other_route_table (afi_t afi, u_int32_t table_id, vrf_id_t vrf_id)
|
||||
if (table_id >= ZEBRA_KERNEL_TABLE_MAX)
|
||||
return NULL;
|
||||
|
||||
/* Pending: This is a MUST-DO for import-table feature.
|
||||
- Making it work like zebra_vrf_table() for now. Ideally, we want to
|
||||
implement import table in a way, so that the other_table doesnt have to be
|
||||
maintained separately.
|
||||
- Need to explore how to provide import table concept
|
||||
(May be only the default VRF?)
|
||||
- How/if to provide some safety against picking a import table to be same as
|
||||
a table associated/used in some other vrf.
|
||||
if (zvrf->other_table[afi][table_id] == NULL)
|
||||
{
|
||||
zvrf->other_table[afi][table_id] = route_table_init();
|
||||
}
|
||||
|
||||
return (zvrf->other_table[afi][table_id]);
|
||||
*/
|
||||
|
||||
return zvrf->table[afi][SAFI_UNICAST];
|
||||
}
|
||||
|
||||
|
||||
|
@ -88,7 +88,7 @@ zebra_static_ipv4 (struct vty *vty, int add_cmd, const char *dest_str,
|
||||
|
||||
/* VRF id */
|
||||
if (vrf_id_str)
|
||||
VTY_GET_INTEGER ("VRF ID", vrf_id, vrf_id_str);
|
||||
VRF_GET_ID (vrf_id, vrf_id_str); //Pending: create VRF if the given vrf doesnt exist?
|
||||
|
||||
/* Null0 static route. */
|
||||
if ((gate_str != NULL) && (strncasecmp (gate_str, "Null0", strlen (gate_str)) == 0))
|
||||
@ -2030,8 +2030,12 @@ DEFUN (show_ip_route,
|
||||
struct route_node *rn;
|
||||
struct rib *rib;
|
||||
int first = 1;
|
||||
vrf_id_t vrf_id = VRF_DEFAULT;
|
||||
|
||||
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
|
||||
if (argc)
|
||||
VRF_GET_ID (vrf_id, argv[0]);
|
||||
|
||||
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
|
||||
if (! table)
|
||||
return CMD_SUCCESS;
|
||||
|
||||
@ -2056,10 +2060,23 @@ DEFUN (show_ip_nht,
|
||||
IP_STR
|
||||
"IP nexthop tracking table\n")
|
||||
{
|
||||
zebra_print_rnh_table(0, AF_INET, vty, RNH_NEXTHOP_TYPE);
|
||||
vrf_id_t vrf_id = VRF_DEFAULT;
|
||||
|
||||
if (argc)
|
||||
VRF_GET_ID (vrf_id, argv[0]);
|
||||
|
||||
zebra_print_rnh_table(vrf_id, AF_INET, vty, RNH_NEXTHOP_TYPE);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
ALIAS (show_ip_nht,
|
||||
show_ip_nht_vrf_cmd,
|
||||
"show ip nht " VRF_CMD_STR,
|
||||
SHOW_STR
|
||||
IP_STR
|
||||
"IP nexthop tracking table\n"
|
||||
VRF_CMD_HELP_STR)
|
||||
|
||||
DEFUN (show_ipv6_nht,
|
||||
show_ipv6_nht_cmd,
|
||||
"show ipv6 nht",
|
||||
@ -2067,10 +2084,23 @@ DEFUN (show_ipv6_nht,
|
||||
IP_STR
|
||||
"IPv6 nexthop tracking table\n")
|
||||
{
|
||||
zebra_print_rnh_table(0, AF_INET6, vty, RNH_NEXTHOP_TYPE);
|
||||
vrf_id_t vrf_id = VRF_DEFAULT;
|
||||
|
||||
if (argc)
|
||||
VRF_GET_ID (vrf_id, argv[0]);
|
||||
|
||||
zebra_print_rnh_table(vrf_id, AF_INET6, vty, RNH_NEXTHOP_TYPE);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
ALIAS (show_ipv6_nht,
|
||||
show_ipv6_nht_vrf_cmd,
|
||||
"show ipv6 nht " VRF_CMD_STR,
|
||||
SHOW_STR
|
||||
IP_STR
|
||||
"IPv6 nexthop tracking table\n"
|
||||
VRF_CMD_HELP_STR)
|
||||
|
||||
DEFUN (ip_nht_default_route,
|
||||
ip_nht_default_route_cmd,
|
||||
"ip nht resolve-via-default",
|
||||
@ -2206,7 +2236,7 @@ DEFUN (show_ip_route_prefix_longer,
|
||||
}
|
||||
|
||||
if (argc > 1)
|
||||
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
|
||||
VRF_GET_ID (vrf_id, argv[1]);
|
||||
|
||||
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
|
||||
if (! table)
|
||||
@ -2253,7 +2283,7 @@ DEFUN (show_ip_route_supernets,
|
||||
vrf_id_t vrf_id = VRF_DEFAULT;
|
||||
|
||||
if (argc > 0)
|
||||
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
|
||||
VRF_GET_ID (vrf_id, argv[0]);
|
||||
|
||||
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
|
||||
if (! table)
|
||||
@ -2312,7 +2342,7 @@ DEFUN (show_ip_route_protocol,
|
||||
}
|
||||
|
||||
if (argc > 1)
|
||||
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
|
||||
VRF_GET_ID (vrf_id, argv[1]);
|
||||
|
||||
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
|
||||
if (! table)
|
||||
@ -2400,7 +2430,7 @@ DEFUN (show_ip_route_addr,
|
||||
}
|
||||
|
||||
if (argc > 1)
|
||||
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
|
||||
VRF_GET_ID (vrf_id, argv[1]);
|
||||
|
||||
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
|
||||
if (! table)
|
||||
@ -2451,7 +2481,7 @@ DEFUN (show_ip_route_prefix,
|
||||
}
|
||||
|
||||
if (argc > 1)
|
||||
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
|
||||
VRF_GET_ID (vrf_id, argv[1]);
|
||||
|
||||
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
|
||||
if (! table)
|
||||
@ -2641,7 +2671,7 @@ DEFUN (show_ip_route_summary,
|
||||
vrf_id_t vrf_id = VRF_DEFAULT;
|
||||
|
||||
if (argc > 0)
|
||||
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
|
||||
VRF_GET_ID (vrf_id, argv[0]);
|
||||
|
||||
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
|
||||
if (! table)
|
||||
@ -2675,7 +2705,7 @@ DEFUN (show_ip_route_summary_prefix,
|
||||
vrf_id_t vrf_id = VRF_DEFAULT;
|
||||
|
||||
if (argc > 0)
|
||||
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
|
||||
VRF_GET_ID (vrf_id, argv[0]);
|
||||
|
||||
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
|
||||
if (! table)
|
||||
@ -3056,7 +3086,12 @@ static_config_ipv4 (struct vty *vty, safi_t safi, const char *cmd)
|
||||
vty_out (vty, " %d", si->distance);
|
||||
|
||||
if (si->vrf_id != VRF_DEFAULT)
|
||||
vty_out (vty, " vrf %u", si->vrf_id);
|
||||
{
|
||||
struct vrf *vrf;
|
||||
|
||||
vrf = vrf_lookup(si->vrf_id);
|
||||
vty_out (vty, " vrf %s", vrf ? vrf->name : "");
|
||||
}
|
||||
|
||||
vty_out (vty, "%s", VTY_NEWLINE);
|
||||
|
||||
@ -3084,7 +3119,7 @@ DEFUN (show_ip_mroute,
|
||||
vrf_id_t vrf_id = VRF_DEFAULT;
|
||||
|
||||
if (argc > 0)
|
||||
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
|
||||
VRF_GET_ID (vrf_id, argv[0]);
|
||||
|
||||
table = zebra_vrf_table (AFI_IP, SAFI_MULTICAST, vrf_id);
|
||||
if (! table)
|
||||
@ -3251,7 +3286,7 @@ static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
|
||||
|
||||
/* VRF id */
|
||||
if (vrf_id_str)
|
||||
VTY_GET_INTEGER ("VRF ID", vrf_id, vrf_id_str);
|
||||
VRF_GET_ID (vrf_id, vrf_id_str);
|
||||
|
||||
if (add_cmd)
|
||||
static_add_ipv6 (&p, type, gate, ifindex, flag, tag, distance, vrf_id);
|
||||
@ -4459,7 +4494,7 @@ DEFUN (show_ipv6_route,
|
||||
vrf_id_t vrf_id = VRF_DEFAULT;
|
||||
|
||||
if (argc > 0)
|
||||
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
|
||||
VRF_GET_ID (vrf_id, argv[0]);
|
||||
|
||||
table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
|
||||
if (! table)
|
||||
@ -4551,7 +4586,7 @@ DEFUN (show_ipv6_route_prefix_longer,
|
||||
}
|
||||
|
||||
if (argc > 1)
|
||||
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
|
||||
VRF_GET_ID (vrf_id, argv[1]);
|
||||
|
||||
table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
|
||||
if (! table)
|
||||
@ -4605,7 +4640,7 @@ DEFUN (show_ipv6_route_protocol,
|
||||
}
|
||||
|
||||
if (argc > 1)
|
||||
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
|
||||
VRF_GET_ID (vrf_id, argv[1]);
|
||||
|
||||
table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
|
||||
if (! table)
|
||||
@ -4657,7 +4692,7 @@ DEFUN (show_ipv6_route_addr,
|
||||
}
|
||||
|
||||
if (argc > 1)
|
||||
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
|
||||
VRF_GET_ID (vrf_id, argv[1]);
|
||||
|
||||
table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
|
||||
if (! table)
|
||||
@ -4708,7 +4743,7 @@ DEFUN (show_ipv6_route_prefix,
|
||||
}
|
||||
|
||||
if (argc > 1)
|
||||
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
|
||||
VRF_GET_ID (vrf_id, argv[1]);
|
||||
|
||||
table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
|
||||
if (! table)
|
||||
@ -4750,7 +4785,7 @@ DEFUN (show_ipv6_route_summary,
|
||||
vrf_id_t vrf_id = VRF_DEFAULT;
|
||||
|
||||
if (argc > 0)
|
||||
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
|
||||
VRF_GET_ID (vrf_id, argv[0]);
|
||||
|
||||
table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
|
||||
if (! table)
|
||||
@ -4784,7 +4819,7 @@ DEFUN (show_ipv6_route_summary_prefix,
|
||||
vrf_id_t vrf_id = VRF_DEFAULT;
|
||||
|
||||
if (argc > 0)
|
||||
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
|
||||
VRF_GET_ID (vrf_id, argv[0]);
|
||||
|
||||
table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
|
||||
if (! table)
|
||||
@ -4824,7 +4859,7 @@ DEFUN (show_ipv6_mroute,
|
||||
vrf_id_t vrf_id = VRF_DEFAULT;
|
||||
|
||||
if (argc > 0)
|
||||
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
|
||||
VRF_GET_ID (vrf_id, argv[0]);
|
||||
|
||||
table = zebra_vrf_table (AFI_IP6, SAFI_MULTICAST, vrf_id);
|
||||
if (! table)
|
||||
@ -5232,6 +5267,31 @@ DEFUN (no_allow_external_route_update,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
/* show vrf */
|
||||
DEFUN (show_vrf,
|
||||
show_vrf_cmd,
|
||||
"show vrf",
|
||||
SHOW_STR
|
||||
"VRF\n")
|
||||
{
|
||||
struct zebra_vrf *zvrf;
|
||||
vrf_iter_t iter;
|
||||
|
||||
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||
{
|
||||
if ((zvrf = vrf_iter2info (iter)) == NULL)
|
||||
continue;
|
||||
if (!zvrf->vrf_id)
|
||||
continue;
|
||||
|
||||
vty_out (vty, "vrf %s id %u table %u%s",
|
||||
zvrf->name, zvrf->vrf_id, zvrf->table_id, VTY_NEWLINE);
|
||||
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
/* Static ip route configuration write function. */
|
||||
static int
|
||||
zebra_ip_config (struct vty *vty)
|
||||
@ -5419,11 +5479,14 @@ zebra_vty_init (void)
|
||||
install_element (CONFIG_NODE, &no_ip_zebra_import_table_cmd);
|
||||
install_element (CONFIG_NODE, &no_ip_zebra_import_table_distance_cmd);
|
||||
|
||||
install_element (VIEW_NODE, &show_vrf_cmd);
|
||||
install_element (VIEW_NODE, &show_ip_route_cmd);
|
||||
install_element (VIEW_NODE, &show_ip_route_ospf_instance_cmd);
|
||||
install_element (VIEW_NODE, &show_ip_route_tag_cmd);
|
||||
install_element (VIEW_NODE, &show_ip_nht_cmd);
|
||||
install_element (VIEW_NODE, &show_ip_nht_vrf_cmd);
|
||||
install_element (VIEW_NODE, &show_ipv6_nht_cmd);
|
||||
install_element (VIEW_NODE, &show_ipv6_nht_vrf_cmd);
|
||||
install_element (VIEW_NODE, &show_ip_route_addr_cmd);
|
||||
install_element (VIEW_NODE, &show_ip_route_prefix_cmd);
|
||||
install_element (VIEW_NODE, &show_ip_route_prefix_longer_cmd);
|
||||
@ -5431,11 +5494,13 @@ zebra_vty_init (void)
|
||||
install_element (VIEW_NODE, &show_ip_route_supernets_cmd);
|
||||
install_element (VIEW_NODE, &show_ip_route_summary_cmd);
|
||||
install_element (VIEW_NODE, &show_ip_route_summary_prefix_cmd);
|
||||
install_element (ENABLE_NODE, &show_vrf_cmd);
|
||||
install_element (ENABLE_NODE, &show_ip_route_cmd);
|
||||
install_element (ENABLE_NODE, &show_ip_route_ospf_instance_cmd);
|
||||
install_element (ENABLE_NODE, &show_ip_route_tag_cmd);
|
||||
install_element (ENABLE_NODE, &show_ip_nht_cmd);
|
||||
install_element (ENABLE_NODE, &show_ipv6_nht_cmd);
|
||||
install_element (ENABLE_NODE, &show_ip_nht_vrf_cmd);
|
||||
install_element (ENABLE_NODE, &show_ipv6_nht_vrf_cmd);
|
||||
install_element (ENABLE_NODE, &show_ip_route_addr_cmd);
|
||||
install_element (ENABLE_NODE, &show_ip_route_prefix_cmd);
|
||||
install_element (ENABLE_NODE, &show_ip_route_prefix_longer_cmd);
|
||||
|
118
zebra/zserv.c
118
zebra/zserv.c
@ -171,6 +171,16 @@ zserv_encode_interface (struct stream *s, struct interface *ifp)
|
||||
stream_putw_at (s, 0, stream_get_endp (s));
|
||||
}
|
||||
|
||||
static void
|
||||
zserv_encode_vrf (struct stream *s, struct vrf *vrfp)
|
||||
{
|
||||
/* Interface information. */
|
||||
stream_put (s, vrfp->name, VRF_NAMSIZ);
|
||||
|
||||
/* Write packet size. */
|
||||
stream_putw_at (s, 0, stream_get_endp (s));
|
||||
}
|
||||
|
||||
/* Interface is added. Send ZEBRA_INTERFACE_ADD to client. */
|
||||
/*
|
||||
* This function is called in the following situations:
|
||||
@ -221,6 +231,37 @@ zsend_interface_delete (struct zserv *client, struct interface *ifp)
|
||||
return zebra_server_send_message (client);
|
||||
}
|
||||
|
||||
int
|
||||
zsend_vrf_add (struct zserv *client, struct vrf *vrfp)
|
||||
{
|
||||
struct stream *s;
|
||||
|
||||
s = client->obuf;
|
||||
stream_reset (s);
|
||||
|
||||
zserv_create_header (s, ZEBRA_VRF_ADD, vrfp->vrf_id);
|
||||
zserv_encode_vrf (s, vrfp);
|
||||
|
||||
client->vrfadd_cnt++;
|
||||
return zebra_server_send_message(client);
|
||||
}
|
||||
|
||||
/* VRF deletion from zebra daemon. */
|
||||
int
|
||||
zsend_vrf_delete (struct zserv *client, struct vrf *vrfp)
|
||||
{
|
||||
struct stream *s;
|
||||
|
||||
s = client->obuf;
|
||||
stream_reset (s);
|
||||
|
||||
zserv_create_header (s, ZEBRA_VRF_DELETE, vrfp->vrf_id);
|
||||
zserv_encode_vrf (s, vrfp);
|
||||
|
||||
client->vrfdel_cnt++;
|
||||
return zebra_server_send_message (client);
|
||||
}
|
||||
|
||||
/* Interface address is added/deleted. Send ZEBRA_INTERFACE_ADDRESS_ADD or
|
||||
* ZEBRA_INTERFACE_ADDRESS_DELETE to the client.
|
||||
*
|
||||
@ -819,7 +860,7 @@ zserv_rnh_register (struct zserv *client, int sock, u_short length,
|
||||
p.family);
|
||||
return -1;
|
||||
}
|
||||
rnh = zebra_add_rnh(&p, 0, type);
|
||||
rnh = zebra_add_rnh(&p, vrf_id, type);
|
||||
if (type == RNH_NEXTHOP_TYPE)
|
||||
{
|
||||
if (flags && !CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED))
|
||||
@ -837,7 +878,7 @@ zserv_rnh_register (struct zserv *client, int sock, u_short length,
|
||||
|
||||
zebra_add_rnh_client(rnh, client, type, vrf_id);
|
||||
/* Anything not AF_INET/INET6 has been filtered out above */
|
||||
zebra_evaluate_rnh(0, p.family, 1, type, &p);
|
||||
zebra_evaluate_rnh(vrf_id, p.family, 1, type, &p);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -845,7 +886,7 @@ zserv_rnh_register (struct zserv *client, int sock, u_short length,
|
||||
/* Nexthop register */
|
||||
static int
|
||||
zserv_rnh_unregister (struct zserv *client, int sock, u_short length,
|
||||
rnh_type_t type)
|
||||
rnh_type_t type, vrf_id_t vrf_id)
|
||||
{
|
||||
struct rnh *rnh;
|
||||
struct stream *s;
|
||||
@ -880,7 +921,7 @@ zserv_rnh_unregister (struct zserv *client, int sock, u_short length,
|
||||
p.family);
|
||||
return -1;
|
||||
}
|
||||
rnh = zebra_lookup_rnh(&p, 0, type);
|
||||
rnh = zebra_lookup_rnh(&p, vrf_id, type);
|
||||
if (rnh)
|
||||
{
|
||||
client->nh_dereg_time = quagga_time(NULL);
|
||||
@ -1137,7 +1178,18 @@ zread_ipv4_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
|
||||
rib->tag = 0;
|
||||
|
||||
/* Table */
|
||||
rib->table=zebrad.rtm_table_default;
|
||||
if (vrf_id)
|
||||
{
|
||||
struct zebra_vrf *zvrf;
|
||||
|
||||
zvrf = vrf_info_lookup (vrf_id);
|
||||
if (zvrf)
|
||||
rib->table = zvrf->table_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
rib->table=zebrad.rtm_table_default;
|
||||
}
|
||||
ret = rib_add_ipv4_multipath (&p, rib, safi);
|
||||
|
||||
/* Stats */
|
||||
@ -1160,6 +1212,9 @@ zread_ipv4_delete (struct zserv *client, u_short length, vrf_id_t vrf_id)
|
||||
struct prefix_ipv4 p;
|
||||
u_char nexthop_num;
|
||||
u_char nexthop_type;
|
||||
u_int32_t table_id;
|
||||
|
||||
table_id = client->rtm_table;
|
||||
|
||||
s = client->ibuf;
|
||||
ifindex = 0;
|
||||
@ -1227,8 +1282,21 @@ zread_ipv4_delete (struct zserv *client, u_short length, vrf_id_t vrf_id)
|
||||
else
|
||||
api.tag = 0;
|
||||
|
||||
if (vrf_id)
|
||||
{
|
||||
struct zebra_vrf *zvrf;
|
||||
|
||||
zvrf = vrf_info_lookup (vrf_id);
|
||||
if (zvrf)
|
||||
table_id = zvrf->table_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
table_id = client->rtm_table;
|
||||
}
|
||||
|
||||
rib_delete_ipv4 (api.type, api.instance, api.flags, &p, nexthop_p, ifindex,
|
||||
vrf_id, client->rtm_table, api.safi);
|
||||
vrf_id, table_id, api.safi);
|
||||
client->v4_route_del_cnt++;
|
||||
return 0;
|
||||
}
|
||||
@ -1265,7 +1333,7 @@ zread_ipv4_import_lookup (struct zserv *client, u_short length,
|
||||
#ifdef HAVE_IPV6
|
||||
/* Zebra server IPv6 prefix add function. */
|
||||
static int
|
||||
zread_ipv4_route_ipv6_nexthop_add (struct zserv *client, u_short length)
|
||||
zread_ipv4_route_ipv6_nexthop_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
|
||||
{
|
||||
int i;
|
||||
struct stream *s;
|
||||
@ -1373,7 +1441,18 @@ zread_ipv4_route_ipv6_nexthop_add (struct zserv *client, u_short length)
|
||||
rib->tag = 0;
|
||||
|
||||
/* Table */
|
||||
rib->table=zebrad.rtm_table_default;
|
||||
if (vrf_id)
|
||||
{
|
||||
struct zebra_vrf *zvrf;
|
||||
|
||||
zvrf = vrf_info_lookup (vrf_id);
|
||||
if (zvrf)
|
||||
rib->table = zvrf->table_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
rib->table=zebrad.rtm_table_default;
|
||||
}
|
||||
ret = rib_add_ipv6_multipath ((struct prefix *)&p, rib, safi, ifindex);
|
||||
/* Stats */
|
||||
if (ret > 0)
|
||||
@ -1489,9 +1568,20 @@ zread_ipv6_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
|
||||
else
|
||||
rib->tag = 0;
|
||||
|
||||
/* Table */
|
||||
rib->table=zebrad.rtm_table_default;
|
||||
rib->vrf_id = vrf_id;
|
||||
/* Table */
|
||||
if (vrf_id)
|
||||
{
|
||||
struct zebra_vrf *zvrf;
|
||||
|
||||
zvrf = vrf_info_lookup (vrf_id);
|
||||
if (zvrf)
|
||||
rib->table = zvrf->table_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
rib->table=zebrad.rtm_table_default;
|
||||
}
|
||||
ret = rib_add_ipv6_multipath ((struct prefix *)&p, rib, safi, ifindex);
|
||||
/* Stats */
|
||||
if (ret > 0)
|
||||
@ -1736,6 +1826,8 @@ zebra_client_create (int sock)
|
||||
|
||||
/* Make new read thread. */
|
||||
zebra_event (ZEBRA_READ, sock, client);
|
||||
|
||||
zebra_vrf_update_all (client);
|
||||
}
|
||||
|
||||
/* Handler of zebra service request. */
|
||||
@ -1870,7 +1962,7 @@ zebra_client_read (struct thread *thread)
|
||||
break;
|
||||
#ifdef HAVE_IPV6
|
||||
case ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD:
|
||||
zread_ipv4_route_ipv6_nexthop_add (client, length);
|
||||
zread_ipv4_route_ipv6_nexthop_add (client, length, vrf_id);
|
||||
break;
|
||||
case ZEBRA_IPV6_ROUTE_ADD:
|
||||
zread_ipv6_add (client, length, vrf_id);
|
||||
@ -1909,13 +2001,13 @@ zebra_client_read (struct thread *thread)
|
||||
zserv_rnh_register(client, sock, length, RNH_NEXTHOP_TYPE, vrf_id);
|
||||
break;
|
||||
case ZEBRA_NEXTHOP_UNREGISTER:
|
||||
zserv_rnh_unregister(client, sock, length, RNH_NEXTHOP_TYPE);
|
||||
zserv_rnh_unregister(client, sock, length, RNH_NEXTHOP_TYPE, vrf_id);
|
||||
break;
|
||||
case ZEBRA_IMPORT_ROUTE_REGISTER:
|
||||
zserv_rnh_register(client, sock, length, RNH_IMPORT_CHECK_TYPE, vrf_id);
|
||||
break;
|
||||
case ZEBRA_IMPORT_ROUTE_UNREGISTER:
|
||||
zserv_rnh_unregister(client, sock, length, RNH_IMPORT_CHECK_TYPE);
|
||||
zserv_rnh_unregister(client, sock, length, RNH_IMPORT_CHECK_TYPE, vrf_id);
|
||||
break;
|
||||
case ZEBRA_BFD_DEST_UPDATE:
|
||||
case ZEBRA_BFD_DEST_REGISTER:
|
||||
|
@ -100,6 +100,8 @@ struct zserv
|
||||
u_int32_t bfd_peer_upd8_cnt;
|
||||
u_int32_t bfd_peer_del_cnt;
|
||||
u_int32_t bfd_peer_replay_cnt;
|
||||
u_int32_t vrfadd_cnt;
|
||||
u_int32_t vrfdel_cnt;
|
||||
|
||||
time_t connect_time;
|
||||
time_t last_read_time;
|
||||
@ -133,14 +135,17 @@ 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 (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 interface_list (struct zebra_ns *);
|
||||
extern void route_read (struct zebra_ns *);
|
||||
extern void kernel_init (struct zebra_ns *);
|
||||
extern void kernel_terminate (struct zebra_ns *);
|
||||
extern void zebra_route_map_init (void);
|
||||
extern void zebra_snmp_init (void);
|
||||
extern void zebra_vty_init (void);
|
||||
|
||||
extern int zsend_vrf_add (struct zserv *, struct vrf *);
|
||||
extern int zsend_vrf_delete (struct zserv *, struct vrf *);
|
||||
|
||||
extern int zsend_interface_add (struct zserv *, struct interface *);
|
||||
extern int zsend_interface_delete (struct zserv *, struct interface *);
|
||||
extern int zsend_interface_address (int, struct zserv *, struct interface *,
|
||||
|
Loading…
Reference in New Issue
Block a user