mirror of
https://github.com/FRRouting/frr.git
synced 2025-04-30 21:47:15 +02:00
Quagga: Implement VRF change semantics for an interface
Implement VRF change semantics for an interface to be invoked when an interface is moved from one VRF (e.g., the Default) to another. This includes the message definition as well as updating, deleting or adding the interface from clients, depending on their interest in the VRFs (old and new). Also handle replay of the addresses on the interface upon VRF change, if required. Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com> Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com> Reviewed-by: Don Slice <dslice@cumulusnetworks.com> Ticket: CM-9527 Reviewed By: CCR-4174 Testing Done: Manual tests of various scenarios
This commit is contained in:
parent
b47b0a8480
commit
c8e264b60e
|
@ -874,7 +874,8 @@ static const struct zebra_desc_table command_types[] = {
|
|||
DESC_ENTRY (ZEBRA_REDISTRIBUTE_IPV4_ADD),
|
||||
DESC_ENTRY (ZEBRA_REDISTRIBUTE_IPV4_DEL),
|
||||
DESC_ENTRY (ZEBRA_REDISTRIBUTE_IPV6_ADD),
|
||||
DESC_ENTRY (ZEBRA_REDISTRIBUTE_IPV6_DEL)
|
||||
DESC_ENTRY (ZEBRA_REDISTRIBUTE_IPV6_DEL),
|
||||
DESC_ENTRY (ZEBRA_INTERFACE_VRF_UPDATE)
|
||||
};
|
||||
#undef DESC_ENTRY
|
||||
|
||||
|
|
|
@ -1211,6 +1211,33 @@ zebra_interface_nbr_address_read (int type, struct stream *s, vrf_id_t vrf_id)
|
|||
return ifc;
|
||||
}
|
||||
|
||||
struct interface *
|
||||
zebra_interface_vrf_update_read (struct stream *s, vrf_id_t vrf_id,
|
||||
vrf_id_t *new_vrf_id)
|
||||
{
|
||||
unsigned int ifindex;
|
||||
struct interface *ifp;
|
||||
vrf_id_t new_id = VRF_DEFAULT;
|
||||
|
||||
/* Get interface index. */
|
||||
ifindex = stream_getl (s);
|
||||
|
||||
/* Lookup interface. */
|
||||
ifp = if_lookup_by_index_vrf (ifindex, vrf_id);
|
||||
if (ifp == NULL)
|
||||
{
|
||||
zlog_warn ("INTERFACE_VRF_UPDATE: Cannot find IF %u in VRF %d",
|
||||
ifindex, vrf_id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Fetch new VRF Id. */
|
||||
new_id = stream_getw (s);
|
||||
|
||||
*new_vrf_id = new_id;
|
||||
return ifp;
|
||||
}
|
||||
|
||||
/* Zebra client message read function. */
|
||||
static int
|
||||
zclient_read (struct thread *thread)
|
||||
|
@ -1357,6 +1384,10 @@ zclient_read (struct thread *thread)
|
|||
if (zclient->interface_down)
|
||||
(*zclient->interface_down) (command, zclient, length, vrf_id);
|
||||
break;
|
||||
case ZEBRA_INTERFACE_VRF_UPDATE:
|
||||
if (zclient->interface_vrf_update)
|
||||
(*zclient->interface_vrf_update) (command, zclient, length, vrf_id);
|
||||
break;
|
||||
case ZEBRA_IPV4_ROUTE_ADD:
|
||||
if (zclient->ipv4_route_add)
|
||||
(*zclient->ipv4_route_add) (command, zclient, length, vrf_id);
|
||||
|
|
|
@ -98,6 +98,7 @@ struct zclient
|
|||
int (*interface_bfd_dest_update) (int, struct zclient *, uint16_t, vrf_id_t);
|
||||
int (*interface_nbr_address_add) (int, struct zclient *, uint16_t, vrf_id_t);
|
||||
int (*interface_nbr_address_delete) (int, struct zclient *, uint16_t, vrf_id_t);
|
||||
int (*interface_vrf_update) (int, struct zclient *, uint16_t, vrf_id_t);
|
||||
int (*ipv4_route_add) (int, struct zclient *, uint16_t, vrf_id_t);
|
||||
int (*ipv4_route_delete) (int, struct zclient *, uint16_t, vrf_id_t);
|
||||
int (*ipv6_route_add) (int, struct zclient *, uint16_t, vrf_id_t);
|
||||
|
@ -200,6 +201,8 @@ extern struct interface *zebra_interface_add_read (struct stream *, vrf_id_t);
|
|||
extern struct interface *zebra_interface_state_read (struct stream *s, vrf_id_t);
|
||||
extern struct connected *zebra_interface_address_read (int, struct stream *, vrf_id_t);
|
||||
extern struct nbr_connected *zebra_interface_nbr_address_read (int, struct stream *, vrf_id_t);
|
||||
extern struct interface * zebra_interface_vrf_update_read (struct stream *s, vrf_id_t vrf_id,
|
||||
vrf_id_t *new_vrf_id);
|
||||
extern void zebra_interface_if_set_value (struct stream *, struct interface *);
|
||||
extern void zebra_router_id_update_read (struct stream *s, struct prefix *rid);
|
||||
extern int zapi_ipv4_route (u_char, struct zclient *, struct prefix_ipv4 *,
|
||||
|
|
|
@ -445,7 +445,8 @@ struct in_pktinfo
|
|||
#define ZEBRA_VRF_UNREGISTER 42
|
||||
#define ZEBRA_VRF_ADD 43
|
||||
#define ZEBRA_VRF_DELETE 44
|
||||
#define ZEBRA_MESSAGE_MAX 45
|
||||
#define ZEBRA_INTERFACE_VRF_UPDATE 45
|
||||
#define ZEBRA_MESSAGE_MAX 46
|
||||
|
||||
/* Marker value used in new Zserv, in the byte location corresponding
|
||||
* the command value in the old zserv header. To allow old and new
|
||||
|
|
|
@ -54,6 +54,8 @@
|
|||
const char *rtadv_pref_strs[] = { "medium", "high", "INVALID", "low", 0 };
|
||||
#endif /* HAVE_RTADV */
|
||||
|
||||
static void if_down_del_nbr_connected (struct interface *ifp);
|
||||
|
||||
struct zebra_ns *dzns;
|
||||
|
||||
/* Called when new interface is added. */
|
||||
|
@ -482,9 +484,56 @@ if_add_update (struct interface *ifp)
|
|||
}
|
||||
}
|
||||
|
||||
/* Handle an interface delete event */
|
||||
void
|
||||
if_delete_update (struct interface *ifp)
|
||||
/* Install connected routes corresponding to an interface. */
|
||||
static void
|
||||
if_install_connected (struct interface *ifp)
|
||||
{
|
||||
struct listnode *node;
|
||||
struct listnode *next;
|
||||
struct connected *ifc;
|
||||
struct prefix *p;
|
||||
|
||||
if (ifp->connected)
|
||||
{
|
||||
for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
|
||||
{
|
||||
p = ifc->address;
|
||||
|
||||
if (p->family == AF_INET)
|
||||
connected_up_ipv4 (ifp, ifc);
|
||||
else if (p->family == AF_INET6)
|
||||
connected_up_ipv6 (ifp, ifc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Uninstall connected routes corresponding to an interface. */
|
||||
static void
|
||||
if_uninstall_connected (struct interface *ifp)
|
||||
{
|
||||
struct listnode *node;
|
||||
struct listnode *next;
|
||||
struct connected *ifc;
|
||||
struct prefix *p;
|
||||
|
||||
if (ifp->connected)
|
||||
{
|
||||
for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
|
||||
{
|
||||
p = ifc->address;
|
||||
|
||||
if (p->family == AF_INET)
|
||||
connected_down_ipv4 (ifp, ifc);
|
||||
else if (p->family == AF_INET6)
|
||||
connected_down_ipv6 (ifp, ifc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Uninstall and delete connected routes corresponding to an interface. */
|
||||
/* TODO - Check why IPv4 handling here is different from install or if_down */
|
||||
static void
|
||||
if_delete_connected (struct interface *ifp)
|
||||
{
|
||||
struct connected *ifc;
|
||||
struct prefix *p;
|
||||
|
@ -493,21 +542,6 @@ if_delete_update (struct interface *ifp)
|
|||
|
||||
zebra_if = ifp->info;
|
||||
|
||||
if (if_is_up(ifp))
|
||||
{
|
||||
zlog_err ("interface %s vrf %u index %d is still up while being deleted.",
|
||||
ifp->name, ifp->vrf_id, ifp->ifindex);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Mark interface as inactive */
|
||||
UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
|
||||
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug ("interface %s vrf %u index %d is now inactive.",
|
||||
ifp->name, ifp->vrf_id, ifp->ifindex);
|
||||
|
||||
/* Delete connected routes from the kernel. */
|
||||
if (ifp->connected)
|
||||
{
|
||||
struct listnode *node;
|
||||
|
@ -571,7 +605,6 @@ if_delete_update (struct interface *ifp)
|
|||
rn->info = NULL;
|
||||
route_unlock_node (rn);
|
||||
}
|
||||
#ifdef HAVE_IPV6
|
||||
else if (p->family == AF_INET6)
|
||||
{
|
||||
connected_down_ipv6 (ifp, ifc);
|
||||
|
@ -589,13 +622,36 @@ if_delete_update (struct interface *ifp)
|
|||
connected_free (ifc);
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_IPV6 */
|
||||
else
|
||||
{
|
||||
last = node;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle an interface delete event */
|
||||
void
|
||||
if_delete_update (struct interface *ifp)
|
||||
{
|
||||
if (if_is_up(ifp))
|
||||
{
|
||||
zlog_err ("interface %s vrf %u index %d is still up while being deleted.",
|
||||
ifp->name, ifp->vrf_id, ifp->ifindex);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Mark interface as inactive */
|
||||
UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
|
||||
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug ("interface %s vrf %u index %d is now inactive.",
|
||||
ifp->name, ifp->vrf_id, ifp->ifindex);
|
||||
|
||||
/* Delete connected routes from the kernel. */
|
||||
if_delete_connected (ifp);
|
||||
|
||||
/* Send out notification on interface delete. */
|
||||
zebra_interface_delete_update (ifp);
|
||||
|
||||
if_unlink_per_ns(ifp);
|
||||
|
@ -608,6 +664,55 @@ if_delete_update (struct interface *ifp)
|
|||
ifp->ifindex = IFINDEX_INTERNAL;
|
||||
}
|
||||
|
||||
/* VRF change for an interface */
|
||||
void
|
||||
if_handle_vrf_change (struct interface *ifp, vrf_id_t vrf_id)
|
||||
{
|
||||
vrf_id_t old_vrf_id;
|
||||
|
||||
old_vrf_id = ifp->vrf_id;
|
||||
|
||||
/* Uninstall connected routes. */
|
||||
if_uninstall_connected (ifp);
|
||||
|
||||
/* Delete any IPv4 neighbors created to implement RFC 5549 */
|
||||
if_nbr_ipv6ll_to_ipv4ll_neigh_del_all (ifp);
|
||||
|
||||
/* Delete all neighbor addresses learnt through IPv6 RA */
|
||||
if_down_del_nbr_connected (ifp);
|
||||
|
||||
/* Suppress RAs on this interface, if enabled. */
|
||||
ipv6_nd_suppress_ra_set (ifp, RA_SUPPRESS);
|
||||
|
||||
/* Send out notification on interface VRF change. */
|
||||
/* This is to issue an UPDATE or a DELETE, as appropriate. */
|
||||
zebra_interface_vrf_update_del (ifp, vrf_id);
|
||||
|
||||
/* update VRF */
|
||||
if_update_vrf (ifp, ifp->name, strlen (ifp->name), vrf_id);
|
||||
|
||||
/* Send out notification on interface VRF change. */
|
||||
/* This is to issue an ADD, if needed. */
|
||||
zebra_interface_vrf_update_add (ifp, old_vrf_id);
|
||||
|
||||
/* Install connected routes (in new VRF). */
|
||||
if_install_connected (ifp);
|
||||
|
||||
/* Enable RAs on this interface, if IPv6 addresses are present. */
|
||||
if (ipv6_address_configured(ifp))
|
||||
ipv6_nd_suppress_ra_set (ifp, RA_ENABLE);
|
||||
|
||||
/* Due to connected route change, schedule RIB processing for both old
|
||||
* and new VRF.
|
||||
*/
|
||||
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
||||
zlog_debug ("%u: IF %s VRF change, scheduling RIB processing",
|
||||
ifp->vrf_id, ifp->name);
|
||||
rib_update (old_vrf_id, RIB_UPDATE_IF_CHANGE);
|
||||
rib_update (ifp->vrf_id, RIB_UPDATE_IF_CHANGE);
|
||||
}
|
||||
|
||||
|
||||
/* Handle VRF addition */
|
||||
void
|
||||
vrf_add_update (struct vrf *vrfp)
|
||||
|
@ -728,11 +833,6 @@ if_down_del_nbr_connected (struct interface *ifp)
|
|||
void
|
||||
if_up (struct interface *ifp)
|
||||
{
|
||||
struct listnode *node;
|
||||
struct listnode *next;
|
||||
struct connected *ifc;
|
||||
struct prefix *p;
|
||||
|
||||
/* Notify the protocol daemons. */
|
||||
if (ifp->ptm_enable && (ifp->ptm_status == ZEBRA_PTM_STATUS_DOWN)) {
|
||||
zlog_warn("%s: interface %s hasn't passed ptm check\n", __func__,
|
||||
|
@ -744,20 +844,7 @@ if_up (struct interface *ifp)
|
|||
if_nbr_ipv6ll_to_ipv4ll_neigh_add_all (ifp);
|
||||
|
||||
/* Install connected routes to the kernel. */
|
||||
if (ifp->connected)
|
||||
{
|
||||
for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
|
||||
{
|
||||
p = ifc->address;
|
||||
|
||||
if (p->family == AF_INET)
|
||||
connected_up_ipv4 (ifp, ifc);
|
||||
#ifdef HAVE_IPV6
|
||||
else if (p->family == AF_INET6)
|
||||
connected_up_ipv6 (ifp, ifc);
|
||||
#endif /* HAVE_IPV6 */
|
||||
}
|
||||
}
|
||||
if_install_connected (ifp);
|
||||
|
||||
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
||||
zlog_debug ("%u: IF %s up, scheduling RIB processing",
|
||||
|
@ -770,29 +857,11 @@ if_up (struct interface *ifp)
|
|||
void
|
||||
if_down (struct interface *ifp)
|
||||
{
|
||||
struct listnode *node;
|
||||
struct listnode *next;
|
||||
struct connected *ifc;
|
||||
struct prefix *p;
|
||||
|
||||
/* Notify to the protocol daemons. */
|
||||
zebra_interface_down_update (ifp);
|
||||
|
||||
/* Delete connected routes from the kernel. */
|
||||
if (ifp->connected)
|
||||
{
|
||||
for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
|
||||
{
|
||||
p = ifc->address;
|
||||
|
||||
if (p->family == AF_INET)
|
||||
connected_down_ipv4 (ifp, ifc);
|
||||
#ifdef HAVE_IPV6
|
||||
else if (p->family == AF_INET6)
|
||||
connected_down_ipv6 (ifp, ifc);
|
||||
#endif /* HAVE_IPV6 */
|
||||
}
|
||||
}
|
||||
/* Uninstall connected routes from the kernel. */
|
||||
if_uninstall_connected (ifp);
|
||||
|
||||
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
||||
zlog_debug ("%u: IF %s down, scheduling RIB processing",
|
||||
|
|
|
@ -225,6 +225,7 @@ extern void if_flags_update (struct interface *, uint64_t);
|
|||
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 if_handle_vrf_change (struct interface *ifp, vrf_id_t vrf_id);
|
||||
|
||||
extern void vrf_delete_update (struct vrf *vrfp);
|
||||
extern void vrf_add_update (struct vrf *vrfp);
|
||||
|
|
|
@ -558,6 +558,74 @@ zebra_interface_address_delete_update (struct interface *ifp,
|
|||
}
|
||||
}
|
||||
|
||||
/* Interface VRF change. May need to delete from clients not interested in
|
||||
* the new VRF. Note that this function is invoked *prior* to the VRF change.
|
||||
*/
|
||||
void
|
||||
zebra_interface_vrf_update_del (struct interface *ifp, vrf_id_t new_vrf_id)
|
||||
{
|
||||
struct listnode *node, *nnode;
|
||||
struct zserv *client;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_EVENT)
|
||||
zlog_debug ("MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/DEL %s VRF Id %u -> %u",
|
||||
ifp->name, ifp->vrf_id, new_vrf_id);
|
||||
|
||||
for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
|
||||
{
|
||||
/* Skip clients not interested in both VRFs. */
|
||||
if (!vrf_bitmap_check (client->ifinfo, ifp->vrf_id) &&
|
||||
!vrf_bitmap_check (client->ifinfo, new_vrf_id))
|
||||
continue;
|
||||
|
||||
if (!vrf_bitmap_check (client->ifinfo, new_vrf_id))
|
||||
{
|
||||
/* Need to delete if the client is not interested in the new VRF. */
|
||||
zsend_interface_update (ZEBRA_INTERFACE_DOWN, client, ifp);
|
||||
client->ifdel_cnt++;
|
||||
zsend_interface_delete (client, ifp);
|
||||
}
|
||||
else if (vrf_bitmap_check (client->ifinfo, ifp->vrf_id))
|
||||
{
|
||||
/* Client is interested in both VRFs, inform about the change. */
|
||||
zsend_interface_vrf_update (client, ifp, new_vrf_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Interface VRF change. This function is invoked *post* VRF change and sends an
|
||||
* add to clients who are interested in the new VRF but not in the old VRF.
|
||||
*/
|
||||
void
|
||||
zebra_interface_vrf_update_add (struct interface *ifp, vrf_id_t old_vrf_id)
|
||||
{
|
||||
struct listnode *node, *nnode;
|
||||
struct zserv *client;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_EVENT)
|
||||
zlog_debug ("MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/ADD %s VRF Id %u -> %u",
|
||||
ifp->name, old_vrf_id, ifp->vrf_id);
|
||||
|
||||
for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
|
||||
{
|
||||
/* Skip clients interested in both VRFs - they would've got an Update. */
|
||||
if (vrf_bitmap_check (client->ifinfo, ifp->vrf_id) &&
|
||||
vrf_bitmap_check (client->ifinfo, old_vrf_id))
|
||||
continue;
|
||||
|
||||
/* Skip clients not interested in the new VRF - they would've
|
||||
* got a Delete.
|
||||
*/
|
||||
if (!vrf_bitmap_check (client->ifinfo, ifp->vrf_id))
|
||||
continue;
|
||||
|
||||
/* Need to add if the client is interested in the new VRF. */
|
||||
client->ifadd_cnt++;
|
||||
zsend_interface_add (client, ifp);
|
||||
zsend_interface_addresses (client, ifp);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
zebra_add_import_table_entry (struct route_node *rn, struct rib *rib)
|
||||
{
|
||||
|
|
|
@ -52,6 +52,8 @@ extern void zebra_interface_address_add_update (struct interface *,
|
|||
struct connected *);
|
||||
extern void zebra_interface_address_delete_update (struct interface *,
|
||||
struct connected *c);
|
||||
extern void zebra_interface_vrf_update_del (struct interface *, vrf_id_t new_vrf_id);
|
||||
extern void zebra_interface_vrf_update_add (struct interface *, vrf_id_t old_vrf_id);
|
||||
extern int zebra_import_table (afi_t afi, u_int32_t table_id,
|
||||
u_int32_t metric, int add);
|
||||
|
||||
|
|
|
@ -63,6 +63,12 @@ void zebra_interface_address_delete_update (struct interface *a,
|
|||
{ return; }
|
||||
#endif
|
||||
|
||||
void zebra_interface_vrf_update_del (struct interface *a, vrf_id_t new_vrf_id)
|
||||
{ return; }
|
||||
|
||||
void zebra_interface_vrf_update_add (struct interface *a, vrf_id_t old_vrf_id)
|
||||
{ return; }
|
||||
|
||||
int zebra_import_table (afi_t afi, u_int32_t table_id, u_int32_t metric,
|
||||
int add)
|
||||
{ return 0; }
|
||||
|
|
|
@ -357,7 +357,7 @@ zsend_interface_nbr_address (int cmd, struct zserv *client,
|
|||
struct prefix *p;
|
||||
|
||||
/* Check this client need interface information. */
|
||||
if (! client->ifinfo)
|
||||
if (! vrf_bitmap_check (client->ifinfo, ifp->vrf_id))
|
||||
return 0;
|
||||
|
||||
s = client->obuf;
|
||||
|
@ -433,6 +433,61 @@ zebra_interface_nbr_address_delete_update (struct interface *ifp,
|
|||
zsend_interface_nbr_address (ZEBRA_INTERFACE_NBR_ADDRESS_DELETE, client, ifp, ifc);
|
||||
}
|
||||
|
||||
/* Send addresses on interface to client */
|
||||
int
|
||||
zsend_interface_addresses (struct zserv *client, struct interface *ifp)
|
||||
{
|
||||
struct listnode *cnode, *cnnode;
|
||||
struct connected *c;
|
||||
struct nbr_connected *nc;
|
||||
|
||||
/* Send interface addresses. */
|
||||
for (ALL_LIST_ELEMENTS (ifp->connected, cnode, cnnode, c))
|
||||
{
|
||||
if (!CHECK_FLAG (c->conf, ZEBRA_IFC_REAL))
|
||||
continue;
|
||||
|
||||
if (zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD, client,
|
||||
ifp, c) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Send interface neighbors. */
|
||||
for (ALL_LIST_ELEMENTS (ifp->nbr_connected, cnode, cnnode, nc))
|
||||
{
|
||||
if (zsend_interface_nbr_address (ZEBRA_INTERFACE_NBR_ADDRESS_ADD,
|
||||
client, ifp, nc) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Notify client about interface moving from one VRF to another.
|
||||
* Whether client is interested in old and new VRF is checked by caller.
|
||||
*/
|
||||
int
|
||||
zsend_interface_vrf_update (struct zserv *client, struct interface *ifp,
|
||||
vrf_id_t vrf_id)
|
||||
{
|
||||
struct stream *s;
|
||||
|
||||
s = client->obuf;
|
||||
stream_reset (s);
|
||||
|
||||
zserv_create_header (s, ZEBRA_INTERFACE_VRF_UPDATE, ifp->vrf_id);
|
||||
|
||||
/* Fill in the ifIndex of the interface and its new VRF (id) */
|
||||
stream_putl (s, ifp->ifindex);
|
||||
stream_putw (s, vrf_id);
|
||||
|
||||
/* Write packet size. */
|
||||
stream_putw_at (s, 0, stream_get_endp (s));
|
||||
|
||||
client->if_vrfchg_cnt++;
|
||||
return zebra_server_send_message(client);
|
||||
}
|
||||
|
||||
/* Add new nbr connected IPv6 address if none exists already, or replace the
|
||||
existing one if an ifc entry is found on the interface. */
|
||||
void
|
||||
|
@ -1030,10 +1085,7 @@ static int
|
|||
zread_interface_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
|
||||
{
|
||||
struct listnode *ifnode, *ifnnode;
|
||||
struct listnode *cnode, *cnnode;
|
||||
struct interface *ifp;
|
||||
struct connected *c;
|
||||
struct nbr_connected *nc;
|
||||
|
||||
/* Interface information is needed. */
|
||||
vrf_bitmap_set (client->ifinfo, vrf_id);
|
||||
|
@ -1047,21 +1099,9 @@ zread_interface_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
|
|||
if (zsend_interface_add (client, ifp) < 0)
|
||||
return -1;
|
||||
|
||||
for (ALL_LIST_ELEMENTS (ifp->connected, cnode, cnnode, c))
|
||||
{
|
||||
if (CHECK_FLAG (c->conf, ZEBRA_IFC_REAL) &&
|
||||
(zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD, client,
|
||||
ifp, c) < 0))
|
||||
if (zsend_interface_addresses (client, ifp) < 0)
|
||||
return -1;
|
||||
}
|
||||
for (ALL_LIST_ELEMENTS (ifp->nbr_connected, cnode, cnnode, nc))
|
||||
{
|
||||
if (zsend_interface_nbr_address (ZEBRA_INTERFACE_NBR_ADDRESS_ADD, client,
|
||||
ifp, nc) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -102,6 +102,7 @@ struct zserv
|
|||
u_int32_t bfd_peer_replay_cnt;
|
||||
u_int32_t vrfadd_cnt;
|
||||
u_int32_t vrfdel_cnt;
|
||||
u_int32_t if_vrfchg_cnt;
|
||||
|
||||
time_t connect_time;
|
||||
time_t last_read_time;
|
||||
|
@ -148,6 +149,7 @@ 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_addresses (struct zserv *, struct interface *);
|
||||
extern int zsend_interface_address (int, struct zserv *, struct interface *,
|
||||
struct connected *);
|
||||
extern void nbr_connected_replacement_add_ipv6 (struct interface *,
|
||||
|
@ -158,6 +160,8 @@ extern int zsend_redistribute_route (int, struct zserv *, struct prefix *,
|
|||
struct rib *);
|
||||
extern int zsend_router_id_update (struct zserv *, struct prefix *,
|
||||
vrf_id_t);
|
||||
extern int zsend_interface_vrf_update (struct zserv *, struct interface *,
|
||||
vrf_id_t);
|
||||
|
||||
extern pid_t pid;
|
||||
|
||||
|
|
Loading…
Reference in a new issue