mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-29 12:21:25 +00:00
Merge branch 'cmaster' of ssh://stash.cumulusnetworks.com:7999/quag/quagga into cmaster
Conflicts: zebra/rib.h zebra/zebra_rib.c zebra/zebra_vty.c
This commit is contained in:
commit
be5e48abec
@ -55,6 +55,7 @@ THE SOFTWARE.
|
|||||||
#include "neighbour.h"
|
#include "neighbour.h"
|
||||||
#include "route.h"
|
#include "route.h"
|
||||||
#include "xroute.h"
|
#include "xroute.h"
|
||||||
|
#include "vrf.h"
|
||||||
|
|
||||||
|
|
||||||
#define IS_ENABLE(ifp) (babel_enable_if_lookup(ifp->name) >= 0)
|
#define IS_ENABLE(ifp) (babel_enable_if_lookup(ifp->name) >= 0)
|
||||||
@ -878,7 +879,7 @@ void
|
|||||||
babel_if_init ()
|
babel_if_init ()
|
||||||
{
|
{
|
||||||
/* initialize interface list */
|
/* initialize interface list */
|
||||||
if_init();
|
vrf_init();
|
||||||
if_add_hook (IF_NEW_HOOK, babel_if_new_hook);
|
if_add_hook (IF_NEW_HOOK, babel_if_new_hook);
|
||||||
if_add_hook (IF_DELETE_HOOK, babel_if_delete_hook);
|
if_add_hook (IF_DELETE_HOOK, babel_if_delete_hook);
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|||||||
#include "plist.h"
|
#include "plist.h"
|
||||||
#include "stream.h"
|
#include "stream.h"
|
||||||
#include "queue.h"
|
#include "queue.h"
|
||||||
|
#include "vrf.h"
|
||||||
|
|
||||||
#include "bgpd/bgpd.h"
|
#include "bgpd/bgpd.h"
|
||||||
#include "bgpd/bgp_attr.h"
|
#include "bgpd/bgp_attr.h"
|
||||||
@ -238,17 +239,14 @@ bgp_exit (int status)
|
|||||||
/* reverse bgp_zebra_init/if_init */
|
/* reverse bgp_zebra_init/if_init */
|
||||||
if (retain_mode)
|
if (retain_mode)
|
||||||
if_add_hook (IF_DELETE_HOOK, NULL);
|
if_add_hook (IF_DELETE_HOOK, NULL);
|
||||||
for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
|
for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
|
||||||
{
|
{
|
||||||
struct listnode *c_node, *c_nnode;
|
struct listnode *c_node, *c_nnode;
|
||||||
struct connected *c;
|
struct connected *c;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS (ifp->connected, c_node, c_nnode, c))
|
for (ALL_LIST_ELEMENTS (ifp->connected, c_node, c_nnode, c))
|
||||||
bgp_connected_delete (c);
|
bgp_connected_delete (c);
|
||||||
|
|
||||||
if_delete (ifp);
|
|
||||||
}
|
}
|
||||||
list_free (iflist);
|
|
||||||
|
|
||||||
/* reverse bgp_attr_init */
|
/* reverse bgp_attr_init */
|
||||||
bgp_attr_finish ();
|
bgp_attr_finish ();
|
||||||
@ -280,6 +278,7 @@ bgp_exit (int status)
|
|||||||
/* reverse community_list_init */
|
/* reverse community_list_init */
|
||||||
community_list_terminate (bgp_clist);
|
community_list_terminate (bgp_clist);
|
||||||
|
|
||||||
|
vrf_terminate ();
|
||||||
cmd_terminate ();
|
cmd_terminate ();
|
||||||
vty_terminate ();
|
vty_terminate ();
|
||||||
if (zclient)
|
if (zclient)
|
||||||
@ -412,6 +411,7 @@ main (int argc, char **argv)
|
|||||||
cmd_init (1);
|
cmd_init (1);
|
||||||
vty_init (bm->master);
|
vty_init (bm->master);
|
||||||
memory_init ();
|
memory_init ();
|
||||||
|
vrf_init ();
|
||||||
|
|
||||||
/* BGP related initialization. */
|
/* BGP related initialization. */
|
||||||
bgp_init ();
|
bgp_init ();
|
||||||
|
@ -477,7 +477,8 @@ show_ip_bgp_nexthop_table (struct vty *vty, int detail)
|
|||||||
VTY_NEWLINE);
|
VTY_NEWLINE);
|
||||||
break;
|
break;
|
||||||
case NEXTHOP_TYPE_IFINDEX:
|
case NEXTHOP_TYPE_IFINDEX:
|
||||||
vty_out (vty, " ifidx %u%s", nexthop->ifindex,
|
vty_out (vty, " if %s%s",
|
||||||
|
ifindex2ifname(nexthop->ifindex),
|
||||||
VTY_NEWLINE);
|
VTY_NEWLINE);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -1136,12 +1136,16 @@ bgp_peer_remove_private_as(struct bgp *bgp, afi_t afi, safi_t safi,
|
|||||||
struct peer *peer, struct attr *attr)
|
struct peer *peer, struct attr *attr)
|
||||||
{
|
{
|
||||||
if (peer->sort == BGP_PEER_EBGP &&
|
if (peer->sort == BGP_PEER_EBGP &&
|
||||||
peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS))
|
(peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE) ||
|
||||||
|
peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE) ||
|
||||||
|
peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_ALL) ||
|
||||||
|
peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS)))
|
||||||
{
|
{
|
||||||
// Take action on the entire aspath
|
// Take action on the entire aspath
|
||||||
if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_ALL))
|
if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE) ||
|
||||||
|
peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_ALL))
|
||||||
{
|
{
|
||||||
if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
|
if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE))
|
||||||
attr->aspath = aspath_replace_private_asns (attr->aspath, bgp->as);
|
attr->aspath = aspath_replace_private_asns (attr->aspath, bgp->as);
|
||||||
|
|
||||||
// The entire aspath consists of private ASNs so create an empty aspath
|
// The entire aspath consists of private ASNs so create an empty aspath
|
||||||
@ -1500,7 +1504,8 @@ subgroup_announce_check (struct bgp_info *ri, struct update_subgroup *subgrp,
|
|||||||
!CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED))
|
!CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED))
|
||||||
{
|
{
|
||||||
/* We can reset the nexthop, if setting (or forcing) it to 'self' */
|
/* We can reset the nexthop, if setting (or forcing) it to 'self' */
|
||||||
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_SELF))
|
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_SELF) ||
|
||||||
|
CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_FORCE_NEXTHOP_SELF))
|
||||||
{
|
{
|
||||||
if (!reflect ||
|
if (!reflect ||
|
||||||
CHECK_FLAG (peer->af_flags[afi][safi],
|
CHECK_FLAG (peer->af_flags[afi][safi],
|
||||||
|
@ -2666,8 +2666,9 @@ bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
|
|||||||
* modifications.
|
* modifications.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
bgp_route_map_process_peer (const char *rmap_name, struct peer *peer,
|
bgp_route_map_process_peer (const char *rmap_name, struct route_map *map,
|
||||||
int afi, int safi, int route_update)
|
struct peer *peer, int afi, int safi,
|
||||||
|
int route_update)
|
||||||
{
|
{
|
||||||
|
|
||||||
int update;
|
int update;
|
||||||
@ -2687,8 +2688,7 @@ bgp_route_map_process_peer (const char *rmap_name, struct peer *peer,
|
|||||||
if (filter->map[RMAP_IN].name &&
|
if (filter->map[RMAP_IN].name &&
|
||||||
(strcmp(rmap_name, filter->map[RMAP_IN].name) == 0))
|
(strcmp(rmap_name, filter->map[RMAP_IN].name) == 0))
|
||||||
{
|
{
|
||||||
filter->map[RMAP_IN].map =
|
filter->map[RMAP_IN].map = map;
|
||||||
route_map_lookup_by_name (filter->map[RMAP_IN].name);
|
|
||||||
|
|
||||||
if (route_update && peer->status == Established)
|
if (route_update && peer->status == Established)
|
||||||
{
|
{
|
||||||
@ -2723,17 +2723,14 @@ bgp_route_map_process_peer (const char *rmap_name, struct peer *peer,
|
|||||||
if (filter->map[RMAP_IMPORT].name &&
|
if (filter->map[RMAP_IMPORT].name &&
|
||||||
(strcmp(rmap_name, filter->map[RMAP_IMPORT].name) == 0))
|
(strcmp(rmap_name, filter->map[RMAP_IMPORT].name) == 0))
|
||||||
{
|
{
|
||||||
filter->map[RMAP_IMPORT].map =
|
filter->map[RMAP_IMPORT].map = map;
|
||||||
route_map_lookup_by_name (filter->map[RMAP_IMPORT].name);
|
|
||||||
update = 1;
|
update = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filter->map[RMAP_EXPORT].name &&
|
if (filter->map[RMAP_EXPORT].name &&
|
||||||
(strcmp(rmap_name, filter->map[RMAP_EXPORT].name) == 0))
|
(strcmp(rmap_name, filter->map[RMAP_EXPORT].name) == 0))
|
||||||
{
|
{
|
||||||
filter->map[RMAP_EXPORT].map =
|
filter->map[RMAP_EXPORT].map = map;
|
||||||
route_map_lookup_by_name (filter->map[RMAP_EXPORT].name);
|
|
||||||
|
|
||||||
update = 1;
|
update = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2769,21 +2766,20 @@ bgp_route_map_process_peer (const char *rmap_name, struct peer *peer,
|
|||||||
*/
|
*/
|
||||||
if (filter->map[RMAP_OUT].name &&
|
if (filter->map[RMAP_OUT].name &&
|
||||||
(strcmp(rmap_name, filter->map[RMAP_OUT].name) == 0))
|
(strcmp(rmap_name, filter->map[RMAP_OUT].name) == 0))
|
||||||
filter->map[RMAP_OUT].map =
|
filter->map[RMAP_OUT].map = map;
|
||||||
route_map_lookup_by_name (filter->map[RMAP_OUT].name);
|
|
||||||
|
|
||||||
if (filter->usmap.name &&
|
if (filter->usmap.name &&
|
||||||
(strcmp(rmap_name, filter->usmap.name) == 0))
|
(strcmp(rmap_name, filter->usmap.name) == 0))
|
||||||
filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
|
filter->usmap.map = map;
|
||||||
|
|
||||||
if (peer->default_rmap[afi][safi].name &&
|
if (peer->default_rmap[afi][safi].name &&
|
||||||
(strcmp (rmap_name, peer->default_rmap[afi][safi].name) == 0))
|
(strcmp (rmap_name, peer->default_rmap[afi][safi].name) == 0))
|
||||||
peer->default_rmap[afi][safi].map =
|
peer->default_rmap[afi][safi].map = map;
|
||||||
route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
bgp_route_map_update_peer_group(const char *rmap_name, struct bgp *bgp)
|
bgp_route_map_update_peer_group(const char *rmap_name, struct route_map *map,
|
||||||
|
struct bgp *bgp)
|
||||||
{
|
{
|
||||||
struct peer_group *group;
|
struct peer_group *group;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
@ -2807,16 +2803,22 @@ bgp_route_map_update_peer_group(const char *rmap_name, struct bgp *bgp)
|
|||||||
{
|
{
|
||||||
if ((filter->map[direct].name) &&
|
if ((filter->map[direct].name) &&
|
||||||
(strcmp(rmap_name, filter->map[direct].name) == 0))
|
(strcmp(rmap_name, filter->map[direct].name) == 0))
|
||||||
filter->map[direct].map =
|
filter->map[direct].map = map;
|
||||||
route_map_lookup_by_name (filter->map[direct].name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filter->usmap.name &&
|
if (filter->usmap.name &&
|
||||||
(strcmp(rmap_name, filter->usmap.name) == 0))
|
(strcmp(rmap_name, filter->usmap.name) == 0))
|
||||||
filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
|
filter->usmap.map = map;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note that if an extreme number (tens of thousands) of route-maps are in use
|
||||||
|
* and if bgp has an extreme number of peers, network statements, etc then this
|
||||||
|
* function can consume a lot of cycles. This is due to this function being
|
||||||
|
* called for each route-map and within this function we walk the list of peers,
|
||||||
|
* network statements, etc looking to see if they use this route-map.
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
bgp_route_map_process_update (void *arg, const char *rmap_name, int route_update)
|
bgp_route_map_process_update (void *arg, const char *rmap_name, int route_update)
|
||||||
{
|
{
|
||||||
@ -2828,11 +2830,14 @@ bgp_route_map_process_update (void *arg, const char *rmap_name, int route_update
|
|||||||
struct bgp_static *bgp_static;
|
struct bgp_static *bgp_static;
|
||||||
struct bgp *bgp = (struct bgp *)arg;
|
struct bgp *bgp = (struct bgp *)arg;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
|
struct route_map *map;
|
||||||
char buf[INET6_ADDRSTRLEN];
|
char buf[INET6_ADDRSTRLEN];
|
||||||
|
|
||||||
if (!bgp)
|
if (!bgp)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
|
map = route_map_lookup_by_name (rmap_name);
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
|
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -2848,7 +2853,7 @@ bgp_route_map_process_update (void *arg, const char *rmap_name, int route_update
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* process in/out/import/export/default-orig route-maps */
|
/* process in/out/import/export/default-orig route-maps */
|
||||||
bgp_route_map_process_peer(rmap_name, peer, afi, safi, route_update);
|
bgp_route_map_process_peer(rmap_name, map, peer, afi, safi, route_update);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2857,49 +2862,46 @@ bgp_route_map_process_update (void *arg, const char *rmap_name, int route_update
|
|||||||
route_update, 0);
|
route_update, 0);
|
||||||
|
|
||||||
/* update peer-group config (template) */
|
/* update peer-group config (template) */
|
||||||
bgp_route_map_update_peer_group(rmap_name, bgp);
|
bgp_route_map_update_peer_group(rmap_name, map, bgp);
|
||||||
|
|
||||||
/* For table route-map updates. */
|
|
||||||
for (afi = AFI_IP; afi < AFI_MAX; afi++)
|
for (afi = AFI_IP; afi < AFI_MAX; afi++)
|
||||||
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
|
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
|
||||||
{
|
{
|
||||||
|
/* For table route-map updates. */
|
||||||
if (bgp->table_map[afi][safi].name &&
|
if (bgp->table_map[afi][safi].name &&
|
||||||
(strcmp(rmap_name, bgp->table_map[afi][safi].name) == 0))
|
(strcmp(rmap_name, bgp->table_map[afi][safi].name) == 0))
|
||||||
{
|
{
|
||||||
bgp->table_map[afi][safi].map =
|
bgp->table_map[afi][safi].map = map;
|
||||||
route_map_lookup_by_name (bgp->table_map[afi][safi].name);
|
|
||||||
if (BGP_DEBUG (zebra, ZEBRA))
|
if (BGP_DEBUG (zebra, ZEBRA))
|
||||||
zlog_debug("Processing route_map %s update on "
|
zlog_debug("Processing route_map %s update on "
|
||||||
"table map", rmap_name);
|
"table map", rmap_name);
|
||||||
if (route_update)
|
if (route_update)
|
||||||
bgp_zebra_announce_table(bgp, afi, safi);
|
bgp_zebra_announce_table(bgp, afi, safi);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* For network route-map updates. */
|
/* For network route-map updates. */
|
||||||
for (afi = AFI_IP; afi < AFI_MAX; afi++)
|
for (bn = bgp_table_top (bgp->route[afi][safi]); bn; bn = bgp_route_next (bn))
|
||||||
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
|
if ((bgp_static = bn->info) != NULL)
|
||||||
for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
|
{
|
||||||
bn = bgp_route_next (bn))
|
if (bgp_static->rmap.name &&
|
||||||
if ((bgp_static = bn->info) != NULL)
|
(strcmp(rmap_name, bgp_static->rmap.name) == 0))
|
||||||
{
|
{
|
||||||
if (bgp_static->rmap.name &&
|
bgp_static->rmap.map = map;
|
||||||
(strcmp(rmap_name, bgp_static->rmap.name) == 0))
|
|
||||||
{
|
if (route_update)
|
||||||
bgp_static->rmap.map =
|
if (!bgp_static->backdoor)
|
||||||
route_map_lookup_by_name (bgp_static->rmap.name);
|
{
|
||||||
if (route_update)
|
if (bgp_debug_zebra(&bn->p))
|
||||||
if (!bgp_static->backdoor)
|
zlog_debug("Processing route_map %s update on "
|
||||||
{
|
"static route %s", rmap_name,
|
||||||
if (bgp_debug_zebra(&bn->p))
|
inet_ntop (bn->p.family, &bn->p.u.prefix,
|
||||||
zlog_debug("Processing route_map %s update on "
|
buf, INET6_ADDRSTRLEN));
|
||||||
"static route %s", rmap_name,
|
bgp_static_update (bgp, &bn->p, bgp_static, afi, safi);
|
||||||
inet_ntop (bn->p.family, &bn->p.u.prefix,
|
}
|
||||||
buf, INET6_ADDRSTRLEN));
|
}
|
||||||
bgp_static_update (bgp, &bn->p, bgp_static, afi, safi);
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* For redistribute route-map updates. */
|
/* For redistribute route-map updates. */
|
||||||
for (afi = AFI_IP; afi < AFI_MAX; afi++)
|
for (afi = AFI_IP; afi < AFI_MAX; afi++)
|
||||||
@ -2918,8 +2920,7 @@ bgp_route_map_process_update (void *arg, const char *rmap_name, int route_update
|
|||||||
if (red->rmap.name &&
|
if (red->rmap.name &&
|
||||||
(strcmp(rmap_name, red->rmap.name) == 0))
|
(strcmp(rmap_name, red->rmap.name) == 0))
|
||||||
{
|
{
|
||||||
red->rmap.map =
|
red->rmap.map = map;
|
||||||
route_map_lookup_by_name (red->rmap.name);
|
|
||||||
|
|
||||||
if (route_update)
|
if (route_update)
|
||||||
{
|
{
|
||||||
|
@ -1719,9 +1719,6 @@ update_group_adjust_soloness (struct peer *peer, int set)
|
|||||||
struct peer_group *group;
|
struct peer_group *group;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
|
|
||||||
if (peer_group_active (peer))
|
|
||||||
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
|
|
||||||
|
|
||||||
if (!CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
|
if (!CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
|
||||||
{
|
{
|
||||||
peer_lonesoul_or_not (peer, set);
|
peer_lonesoul_or_not (peer, set);
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
PEER_FLAG_REMOVE_PRIVATE_AS | \
|
PEER_FLAG_REMOVE_PRIVATE_AS | \
|
||||||
PEER_FLAG_REMOVE_PRIVATE_AS_ALL | \
|
PEER_FLAG_REMOVE_PRIVATE_AS_ALL | \
|
||||||
PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE | \
|
PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE | \
|
||||||
|
PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE | \
|
||||||
PEER_FLAG_AS_OVERRIDE)
|
PEER_FLAG_AS_OVERRIDE)
|
||||||
|
|
||||||
#define PEER_UPDGRP_CAP_FLAGS (PEER_CAP_AS4_RCV)
|
#define PEER_UPDGRP_CAP_FLAGS (PEER_CAP_AS4_RCV)
|
||||||
|
133
bgpd/bgp_vty.c
133
bgpd/bgp_vty.c
@ -57,6 +57,9 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|||||||
|
|
||||||
extern struct in_addr router_id_zebra;
|
extern struct in_addr router_id_zebra;
|
||||||
|
|
||||||
|
static struct peer_group *
|
||||||
|
listen_range_exists (struct bgp *bgp, struct prefix *range, int exact);
|
||||||
|
|
||||||
/* Utility function to get address family from current node. */
|
/* Utility function to get address family from current node. */
|
||||||
afi_t
|
afi_t
|
||||||
bgp_node_afi (struct vty *vty)
|
bgp_node_afi (struct vty *vty)
|
||||||
@ -207,18 +210,9 @@ bgp_vty_return (struct vty *vty, int ret)
|
|||||||
case BGP_ERR_INVALID_FLAG:
|
case BGP_ERR_INVALID_FLAG:
|
||||||
str = "Invalid flag";
|
str = "Invalid flag";
|
||||||
break;
|
break;
|
||||||
case BGP_ERR_PEER_INACTIVE:
|
|
||||||
str = "Activate the neighbor for the address family first";
|
|
||||||
break;
|
|
||||||
case BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER:
|
|
||||||
str = "Invalid command for a peer-group member";
|
|
||||||
break;
|
|
||||||
case BGP_ERR_PEER_GROUP_SHUTDOWN:
|
case BGP_ERR_PEER_GROUP_SHUTDOWN:
|
||||||
str = "Peer-group has been shutdown. Activate the peer-group first";
|
str = "Peer-group has been shutdown. Activate the peer-group first";
|
||||||
break;
|
break;
|
||||||
case BGP_ERR_PEER_GROUP_HAS_THE_FLAG:
|
|
||||||
str = "This peer is a peer-group member. Please change peer-group configuration";
|
|
||||||
break;
|
|
||||||
case BGP_ERR_PEER_FLAG_CONFLICT:
|
case BGP_ERR_PEER_FLAG_CONFLICT:
|
||||||
str = "Can't set override-capability and strict-capability-match at the same time";
|
str = "Can't set override-capability and strict-capability-match at the same time";
|
||||||
break;
|
break;
|
||||||
@ -2353,6 +2347,38 @@ DEFUN (no_bgp_listen_limit,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if this listen range is already configured. Check for exact
|
||||||
|
* match or overlap based on input.
|
||||||
|
*/
|
||||||
|
static struct peer_group *
|
||||||
|
listen_range_exists (struct bgp *bgp, struct prefix *range, int exact)
|
||||||
|
{
|
||||||
|
struct listnode *node, *nnode;
|
||||||
|
struct listnode *node1, *nnode1;
|
||||||
|
struct peer_group *group;
|
||||||
|
struct prefix *lr;
|
||||||
|
afi_t afi;
|
||||||
|
int match;
|
||||||
|
|
||||||
|
afi = family2afi(range->family);
|
||||||
|
for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
|
||||||
|
{
|
||||||
|
for (ALL_LIST_ELEMENTS (group->listen_range[afi], node1,
|
||||||
|
nnode1, lr))
|
||||||
|
{
|
||||||
|
if (exact)
|
||||||
|
match = prefix_same (range, lr);
|
||||||
|
else
|
||||||
|
match = (prefix_match (range, lr) || prefix_match (lr, range));
|
||||||
|
if (match)
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
DEFUN (bgp_listen_range,
|
DEFUN (bgp_listen_range,
|
||||||
bgp_listen_range_cmd,
|
bgp_listen_range_cmd,
|
||||||
LISTEN_RANGE_CMD "peer-group WORD" ,
|
LISTEN_RANGE_CMD "peer-group WORD" ,
|
||||||
@ -2363,7 +2389,7 @@ DEFUN (bgp_listen_range,
|
|||||||
{
|
{
|
||||||
struct bgp *bgp;
|
struct bgp *bgp;
|
||||||
struct prefix range;
|
struct prefix range;
|
||||||
struct peer_group *group;
|
struct peer_group *group, *existing_group;
|
||||||
afi_t afi;
|
afi_t afi;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -2392,6 +2418,27 @@ DEFUN (bgp_listen_range,
|
|||||||
|
|
||||||
apply_mask (&range);
|
apply_mask (&range);
|
||||||
|
|
||||||
|
/* Check if same listen range is already configured. */
|
||||||
|
existing_group = listen_range_exists (bgp, &range, 1);
|
||||||
|
if (existing_group)
|
||||||
|
{
|
||||||
|
if (strcmp (existing_group->name, argv[1]) == 0)
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vty_out (vty, "%% Same listen range is attached to peer-group %s%s",
|
||||||
|
existing_group->name, VTY_NEWLINE);
|
||||||
|
return CMD_WARNING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if an overlapping listen range exists. */
|
||||||
|
if (listen_range_exists (bgp, &range, 0))
|
||||||
|
{
|
||||||
|
vty_out (vty, "%% Listen range overlaps with existing listen range%s",
|
||||||
|
VTY_NEWLINE);
|
||||||
|
return CMD_WARNING;
|
||||||
|
}
|
||||||
|
|
||||||
group = peer_group_lookup (bgp, argv[1]);
|
group = peer_group_lookup (bgp, argv[1]);
|
||||||
if (! group)
|
if (! group)
|
||||||
@ -3399,8 +3446,7 @@ DEFUN (neighbor_nexthop_self_force,
|
|||||||
{
|
{
|
||||||
return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
|
return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
|
||||||
bgp_node_safi (vty),
|
bgp_node_safi (vty),
|
||||||
(PEER_FLAG_FORCE_NEXTHOP_SELF |
|
PEER_FLAG_FORCE_NEXTHOP_SELF);
|
||||||
PEER_FLAG_NEXTHOP_SELF));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUN (no_neighbor_nexthop_self,
|
DEFUN (no_neighbor_nexthop_self,
|
||||||
@ -3413,11 +3459,10 @@ DEFUN (no_neighbor_nexthop_self,
|
|||||||
{
|
{
|
||||||
return peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
|
return peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
|
||||||
bgp_node_safi (vty),
|
bgp_node_safi (vty),
|
||||||
(PEER_FLAG_NEXTHOP_SELF |
|
PEER_FLAG_NEXTHOP_SELF);
|
||||||
PEER_FLAG_FORCE_NEXTHOP_SELF));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ALIAS (no_neighbor_nexthop_self,
|
DEFUN (no_neighbor_nexthop_self_force,
|
||||||
no_neighbor_nexthop_self_force_cmd,
|
no_neighbor_nexthop_self_force_cmd,
|
||||||
NO_NEIGHBOR_CMD2 "next-hop-self force",
|
NO_NEIGHBOR_CMD2 "next-hop-self force",
|
||||||
NO_STR
|
NO_STR
|
||||||
@ -3425,6 +3470,11 @@ ALIAS (no_neighbor_nexthop_self,
|
|||||||
NEIGHBOR_ADDR_STR2
|
NEIGHBOR_ADDR_STR2
|
||||||
"Disable the next hop calculation for this neighbor\n"
|
"Disable the next hop calculation for this neighbor\n"
|
||||||
"Set the next hop to self for reflected routes\n")
|
"Set the next hop to self for reflected routes\n")
|
||||||
|
{
|
||||||
|
return peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
|
||||||
|
bgp_node_safi (vty),
|
||||||
|
PEER_FLAG_FORCE_NEXTHOP_SELF);
|
||||||
|
}
|
||||||
|
|
||||||
/* neighbor as-override */
|
/* neighbor as-override */
|
||||||
DEFUN (neighbor_as_override,
|
DEFUN (neighbor_as_override,
|
||||||
@ -3460,10 +3510,6 @@ DEFUN (neighbor_remove_private_as,
|
|||||||
NEIGHBOR_ADDR_STR2
|
NEIGHBOR_ADDR_STR2
|
||||||
"Remove private ASNs in outbound updates\n")
|
"Remove private ASNs in outbound updates\n")
|
||||||
{
|
{
|
||||||
peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
|
|
||||||
bgp_node_safi (vty),
|
|
||||||
PEER_FLAG_REMOVE_PRIVATE_AS_ALL|
|
|
||||||
PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE);
|
|
||||||
return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
|
return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
|
||||||
bgp_node_safi (vty),
|
bgp_node_safi (vty),
|
||||||
PEER_FLAG_REMOVE_PRIVATE_AS);
|
PEER_FLAG_REMOVE_PRIVATE_AS);
|
||||||
@ -3477,12 +3523,8 @@ DEFUN (neighbor_remove_private_as_all,
|
|||||||
"Remove private ASNs in outbound updates\n"
|
"Remove private ASNs in outbound updates\n"
|
||||||
"Apply to all AS numbers")
|
"Apply to all AS numbers")
|
||||||
{
|
{
|
||||||
peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
|
|
||||||
bgp_node_safi (vty),
|
|
||||||
PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE);
|
|
||||||
return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
|
return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
|
||||||
bgp_node_safi (vty),
|
bgp_node_safi (vty),
|
||||||
PEER_FLAG_REMOVE_PRIVATE_AS|
|
|
||||||
PEER_FLAG_REMOVE_PRIVATE_AS_ALL);
|
PEER_FLAG_REMOVE_PRIVATE_AS_ALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3494,12 +3536,8 @@ DEFUN (neighbor_remove_private_as_replace_as,
|
|||||||
"Remove private ASNs in outbound updates\n"
|
"Remove private ASNs in outbound updates\n"
|
||||||
"Replace private ASNs with our ASN in outbound updates\n")
|
"Replace private ASNs with our ASN in outbound updates\n")
|
||||||
{
|
{
|
||||||
peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
|
|
||||||
bgp_node_safi (vty),
|
|
||||||
PEER_FLAG_REMOVE_PRIVATE_AS_ALL);
|
|
||||||
return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
|
return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
|
||||||
bgp_node_safi (vty),
|
bgp_node_safi (vty),
|
||||||
PEER_FLAG_REMOVE_PRIVATE_AS|
|
|
||||||
PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE);
|
PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3514,9 +3552,7 @@ DEFUN (neighbor_remove_private_as_all_replace_as,
|
|||||||
{
|
{
|
||||||
return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
|
return peer_af_flag_set_vty (vty, argv[0], bgp_node_afi (vty),
|
||||||
bgp_node_safi (vty),
|
bgp_node_safi (vty),
|
||||||
PEER_FLAG_REMOVE_PRIVATE_AS|
|
PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE);
|
||||||
PEER_FLAG_REMOVE_PRIVATE_AS_ALL|
|
|
||||||
PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUN (no_neighbor_remove_private_as,
|
DEFUN (no_neighbor_remove_private_as,
|
||||||
@ -3529,12 +3565,10 @@ DEFUN (no_neighbor_remove_private_as,
|
|||||||
{
|
{
|
||||||
return peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
|
return peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
|
||||||
bgp_node_safi (vty),
|
bgp_node_safi (vty),
|
||||||
PEER_FLAG_REMOVE_PRIVATE_AS|
|
PEER_FLAG_REMOVE_PRIVATE_AS);
|
||||||
PEER_FLAG_REMOVE_PRIVATE_AS_ALL|
|
|
||||||
PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ALIAS (no_neighbor_remove_private_as,
|
DEFUN (no_neighbor_remove_private_as_all,
|
||||||
no_neighbor_remove_private_as_all_cmd,
|
no_neighbor_remove_private_as_all_cmd,
|
||||||
NO_NEIGHBOR_CMD2 "remove-private-AS all",
|
NO_NEIGHBOR_CMD2 "remove-private-AS all",
|
||||||
NO_STR
|
NO_STR
|
||||||
@ -3542,8 +3576,13 @@ ALIAS (no_neighbor_remove_private_as,
|
|||||||
NEIGHBOR_ADDR_STR2
|
NEIGHBOR_ADDR_STR2
|
||||||
"Remove private ASNs in outbound updates\n"
|
"Remove private ASNs in outbound updates\n"
|
||||||
"Apply to all AS numbers")
|
"Apply to all AS numbers")
|
||||||
|
{
|
||||||
|
return peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
|
||||||
|
bgp_node_safi (vty),
|
||||||
|
PEER_FLAG_REMOVE_PRIVATE_AS_ALL);
|
||||||
|
}
|
||||||
|
|
||||||
ALIAS (no_neighbor_remove_private_as,
|
DEFUN (no_neighbor_remove_private_as_replace_as,
|
||||||
no_neighbor_remove_private_as_replace_as_cmd,
|
no_neighbor_remove_private_as_replace_as_cmd,
|
||||||
NO_NEIGHBOR_CMD2 "remove-private-AS replace-AS",
|
NO_NEIGHBOR_CMD2 "remove-private-AS replace-AS",
|
||||||
NO_STR
|
NO_STR
|
||||||
@ -3551,8 +3590,13 @@ ALIAS (no_neighbor_remove_private_as,
|
|||||||
NEIGHBOR_ADDR_STR2
|
NEIGHBOR_ADDR_STR2
|
||||||
"Remove private ASNs in outbound updates\n"
|
"Remove private ASNs in outbound updates\n"
|
||||||
"Replace private ASNs with our ASN in outbound updates\n")
|
"Replace private ASNs with our ASN in outbound updates\n")
|
||||||
|
{
|
||||||
|
return peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
|
||||||
|
bgp_node_safi (vty),
|
||||||
|
PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE);
|
||||||
|
}
|
||||||
|
|
||||||
ALIAS (no_neighbor_remove_private_as,
|
DEFUN (no_neighbor_remove_private_as_all_replace_as,
|
||||||
no_neighbor_remove_private_as_all_replace_as_cmd,
|
no_neighbor_remove_private_as_all_replace_as_cmd,
|
||||||
NO_NEIGHBOR_CMD2 "remove-private-AS all replace-AS",
|
NO_NEIGHBOR_CMD2 "remove-private-AS all replace-AS",
|
||||||
NO_STR
|
NO_STR
|
||||||
@ -3561,6 +3605,11 @@ ALIAS (no_neighbor_remove_private_as,
|
|||||||
"Remove private ASNs in outbound updates\n"
|
"Remove private ASNs in outbound updates\n"
|
||||||
"Apply to all AS numbers"
|
"Apply to all AS numbers"
|
||||||
"Replace private ASNs with our ASN in outbound updates\n")
|
"Replace private ASNs with our ASN in outbound updates\n")
|
||||||
|
{
|
||||||
|
return peer_af_flag_unset_vty (vty, argv[0], bgp_node_afi (vty),
|
||||||
|
bgp_node_safi (vty),
|
||||||
|
PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* neighbor send-community. */
|
/* neighbor send-community. */
|
||||||
@ -9153,8 +9202,12 @@ bgp_show_peer_afi (struct vty *vty, struct peer *p, afi_t afi, safi_t safi,
|
|||||||
if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
|
if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
|
||||||
json_object_boolean_true_add(json_addr, "inboundSoftConfigPermit");
|
json_object_boolean_true_add(json_addr, "inboundSoftConfigPermit");
|
||||||
|
|
||||||
if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
|
if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE))
|
||||||
|
json_object_boolean_true_add(json_addr, "privateAsNumsAllReplacedInUpdatesToNbr");
|
||||||
|
else if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
|
||||||
json_object_boolean_true_add(json_addr, "privateAsNumsReplacedInUpdatesToNbr");
|
json_object_boolean_true_add(json_addr, "privateAsNumsReplacedInUpdatesToNbr");
|
||||||
|
else if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_REMOVE_PRIVATE_AS_ALL))
|
||||||
|
json_object_boolean_true_add(json_addr, "privateAsNumsAllRemovedInUpdatesToNbr");
|
||||||
else if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_REMOVE_PRIVATE_AS))
|
else if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_REMOVE_PRIVATE_AS))
|
||||||
json_object_boolean_true_add(json_addr, "privateAsNumsRemovedInUpdatesToNbr");
|
json_object_boolean_true_add(json_addr, "privateAsNumsRemovedInUpdatesToNbr");
|
||||||
|
|
||||||
@ -9336,8 +9389,12 @@ bgp_show_peer_afi (struct vty *vty, struct peer *p, afi_t afi, safi_t safi,
|
|||||||
if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
|
if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
|
||||||
vty_out (vty, " Inbound soft reconfiguration allowed%s", VTY_NEWLINE);
|
vty_out (vty, " Inbound soft reconfiguration allowed%s", VTY_NEWLINE);
|
||||||
|
|
||||||
if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
|
if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE))
|
||||||
|
vty_out (vty, " Private AS numbers (all) replaced in updates to this neighbor%s", VTY_NEWLINE);
|
||||||
|
else if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
|
||||||
vty_out (vty, " Private AS numbers replaced in updates to this neighbor%s", VTY_NEWLINE);
|
vty_out (vty, " Private AS numbers replaced in updates to this neighbor%s", VTY_NEWLINE);
|
||||||
|
else if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_REMOVE_PRIVATE_AS_ALL))
|
||||||
|
vty_out (vty, " Private AS numbers (all) removed in updates to this neighbor%s", VTY_NEWLINE);
|
||||||
else if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_REMOVE_PRIVATE_AS))
|
else if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_REMOVE_PRIVATE_AS))
|
||||||
vty_out (vty, " Private AS numbers removed in updates to this neighbor%s", VTY_NEWLINE);
|
vty_out (vty, " Private AS numbers removed in updates to this neighbor%s", VTY_NEWLINE);
|
||||||
|
|
||||||
|
@ -438,6 +438,7 @@ zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length)
|
|||||||
struct in_addr nexthop;
|
struct in_addr nexthop;
|
||||||
struct prefix_ipv4 p;
|
struct prefix_ipv4 p;
|
||||||
unsigned int ifindex;
|
unsigned int ifindex;
|
||||||
|
int i;
|
||||||
|
|
||||||
s = zclient->ibuf;
|
s = zclient->ibuf;
|
||||||
nexthop.s_addr = 0;
|
nexthop.s_addr = 0;
|
||||||
@ -497,6 +498,20 @@ zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length)
|
|||||||
api.metric,
|
api.metric,
|
||||||
api.tag);
|
api.tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The ADD message is actually an UPDATE and there is no explicit DEL
|
||||||
|
* for a prior redistributed route, if any. So, perform an implicit
|
||||||
|
* DEL processing for the same redistributed route from any other
|
||||||
|
* source type.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
|
||||||
|
{
|
||||||
|
if (i != api.type)
|
||||||
|
bgp_redistribute_delete((struct prefix *)&p, i, api.instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now perform the add/update. */
|
||||||
bgp_redistribute_add((struct prefix *)&p, &nexthop, NULL, ifindex,
|
bgp_redistribute_add((struct prefix *)&p, &nexthop, NULL, ifindex,
|
||||||
api.metric, api.type, api.instance, api.tag);
|
api.metric, api.type, api.instance, api.tag);
|
||||||
}
|
}
|
||||||
@ -530,6 +545,7 @@ zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length)
|
|||||||
struct in6_addr nexthop;
|
struct in6_addr nexthop;
|
||||||
struct prefix_ipv6 p;
|
struct prefix_ipv6 p;
|
||||||
unsigned int ifindex;
|
unsigned int ifindex;
|
||||||
|
int i;
|
||||||
|
|
||||||
s = zclient->ibuf;
|
s = zclient->ibuf;
|
||||||
memset (&nexthop, 0, sizeof (struct in6_addr));
|
memset (&nexthop, 0, sizeof (struct in6_addr));
|
||||||
@ -595,6 +611,19 @@ zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length)
|
|||||||
api.metric,
|
api.metric,
|
||||||
api.tag);
|
api.tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The ADD message is actually an UPDATE and there is no explicit DEL
|
||||||
|
* for a prior redistributed route, if any. So, perform an implicit
|
||||||
|
* DEL processing for the same redistributed route from any other
|
||||||
|
* source type.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
|
||||||
|
{
|
||||||
|
if (i != api.type)
|
||||||
|
bgp_redistribute_delete((struct prefix *)&p, i, api.instance);
|
||||||
|
}
|
||||||
|
|
||||||
bgp_redistribute_add ((struct prefix *)&p, NULL, &nexthop, ifindex,
|
bgp_redistribute_add ((struct prefix *)&p, NULL, &nexthop, ifindex,
|
||||||
api.metric, api.type, api.instance, api.tag);
|
api.metric, api.type, api.instance, api.tag);
|
||||||
}
|
}
|
||||||
@ -1709,9 +1738,6 @@ bgp_zebra_init (struct thread_master *master)
|
|||||||
zclient->nexthop_update = bgp_read_nexthop_update;
|
zclient->nexthop_update = bgp_read_nexthop_update;
|
||||||
zclient->import_check_update = bgp_read_import_check_update;
|
zclient->import_check_update = bgp_read_import_check_update;
|
||||||
|
|
||||||
/* Interface related init. */
|
|
||||||
if_init ();
|
|
||||||
|
|
||||||
bgp_nexthop_buf = stream_new(BGP_NEXTHOP_BUF_SIZE);
|
bgp_nexthop_buf = stream_new(BGP_NEXTHOP_BUF_SIZE);
|
||||||
bgp_ifindices_buf = stream_new(BGP_IFINDICES_BUF_SIZE);
|
bgp_ifindices_buf = stream_new(BGP_IFINDICES_BUF_SIZE);
|
||||||
}
|
}
|
||||||
|
586
bgpd/bgpd.c
586
bgpd/bgpd.c
@ -722,6 +722,35 @@ peer_af_flag_check (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag)
|
|||||||
return CHECK_FLAG (peer->af_flags[afi][safi], flag);
|
return CHECK_FLAG (peer->af_flags[afi][safi], flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return true if flag is set for the peer but not the peer-group */
|
||||||
|
static int
|
||||||
|
peergroup_af_flag_check (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag)
|
||||||
|
{
|
||||||
|
struct peer *g_peer = NULL;
|
||||||
|
|
||||||
|
if (peer_af_flag_check (peer, afi, safi, flag))
|
||||||
|
{
|
||||||
|
if (peer_group_active (peer))
|
||||||
|
{
|
||||||
|
g_peer = peer->group->conf;
|
||||||
|
|
||||||
|
/* If this flag is not set for the peer's peer-group then return true */
|
||||||
|
if (!peer->af_group[afi][safi] || !peer_af_flag_check (g_peer, afi, safi, flag))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* peer is not in a peer-group but the flag is set to return true */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Reset all address family specific configuration. */
|
/* Reset all address family specific configuration. */
|
||||||
static void
|
static void
|
||||||
peer_af_flag_reset (struct peer *peer, afi_t afi, safi_t safi)
|
peer_af_flag_reset (struct peer *peer, afi_t afi, safi_t safi)
|
||||||
@ -1694,7 +1723,7 @@ peer_deactivate (struct peer *peer, afi_t afi, safi_t safi)
|
|||||||
|
|
||||||
/* De-activate the address family configuration. */
|
/* De-activate the address family configuration. */
|
||||||
peer->afc[afi][safi] = 0;
|
peer->afc[afi][safi] = 0;
|
||||||
peer_af_flag_reset (peer, afi, safi);
|
|
||||||
if (peer_af_delete(peer, afi, safi) != 0)
|
if (peer_af_delete(peer, afi, safi) != 0)
|
||||||
{
|
{
|
||||||
zlog_err("couldn't delete af structure for peer %s", peer->host);
|
zlog_err("couldn't delete af structure for peer %s", peer->host);
|
||||||
@ -3448,6 +3477,7 @@ static const struct peer_flag_action peer_af_flag_action_list[] =
|
|||||||
{ PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED, 0, peer_change_reset_out },
|
{ PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED, 0, peer_change_reset_out },
|
||||||
{ PEER_FLAG_FORCE_NEXTHOP_SELF, 1, peer_change_reset_out },
|
{ PEER_FLAG_FORCE_NEXTHOP_SELF, 1, peer_change_reset_out },
|
||||||
{ PEER_FLAG_AS_OVERRIDE, 1, peer_change_reset_out },
|
{ PEER_FLAG_AS_OVERRIDE, 1, peer_change_reset_out },
|
||||||
|
{ PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE,1, peer_change_reset_out },
|
||||||
{ 0, 0, 0 }
|
{ 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -3570,10 +3600,6 @@ peer_flag_modify (struct peer *peer, u_int32_t flag, int set)
|
|||||||
if (! found)
|
if (! found)
|
||||||
return BGP_ERR_INVALID_FLAG;
|
return BGP_ERR_INVALID_FLAG;
|
||||||
|
|
||||||
/* Not for peer-group member. */
|
|
||||||
if (action.not_for_member && peer_group_active (peer))
|
|
||||||
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
|
|
||||||
|
|
||||||
/* When unset the peer-group member's flag we have to check
|
/* When unset the peer-group member's flag we have to check
|
||||||
peer-group configuration. */
|
peer-group configuration. */
|
||||||
if (! set && peer_group_active (peer))
|
if (! set && peer_group_active (peer))
|
||||||
@ -3581,8 +3607,6 @@ peer_flag_modify (struct peer *peer, u_int32_t flag, int set)
|
|||||||
{
|
{
|
||||||
if (flag == PEER_FLAG_SHUTDOWN)
|
if (flag == PEER_FLAG_SHUTDOWN)
|
||||||
return BGP_ERR_PEER_GROUP_SHUTDOWN;
|
return BGP_ERR_PEER_GROUP_SHUTDOWN;
|
||||||
else
|
|
||||||
return BGP_ERR_PEER_GROUP_HAS_THE_FLAG;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Flag conflict check. */
|
/* Flag conflict check. */
|
||||||
@ -3646,14 +3670,6 @@ peer_flag_unset (struct peer *peer, u_int32_t flag)
|
|||||||
return peer_flag_modify (peer, flag, 0);
|
return peer_flag_modify (peer, flag, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
peer_is_group_member (struct peer *peer, afi_t afi, safi_t safi)
|
|
||||||
{
|
|
||||||
if (peer->af_group[afi][safi])
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
peer_af_flag_modify (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag,
|
peer_af_flag_modify (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag,
|
||||||
int set)
|
int set)
|
||||||
@ -3673,20 +3689,12 @@ peer_af_flag_modify (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag,
|
|||||||
if (! found)
|
if (! found)
|
||||||
return BGP_ERR_INVALID_FLAG;
|
return BGP_ERR_INVALID_FLAG;
|
||||||
|
|
||||||
/* Adress family must be activated. */
|
/* Special check for reflector client. */
|
||||||
if (! peer->afc[afi][safi])
|
|
||||||
return BGP_ERR_PEER_INACTIVE;
|
|
||||||
|
|
||||||
/* Not for peer-group member. */
|
|
||||||
if (action.not_for_member && peer_is_group_member (peer, afi, safi))
|
|
||||||
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
|
|
||||||
|
|
||||||
/* Spcecial check for reflector client. */
|
|
||||||
if (flag & PEER_FLAG_REFLECTOR_CLIENT
|
if (flag & PEER_FLAG_REFLECTOR_CLIENT
|
||||||
&& peer_sort (peer) != BGP_PEER_IBGP)
|
&& peer_sort (peer) != BGP_PEER_IBGP)
|
||||||
return BGP_ERR_NOT_INTERNAL_PEER;
|
return BGP_ERR_NOT_INTERNAL_PEER;
|
||||||
|
|
||||||
/* Spcecial check for remove-private-AS. */
|
/* Special check for remove-private-AS. */
|
||||||
if (flag & PEER_FLAG_REMOVE_PRIVATE_AS
|
if (flag & PEER_FLAG_REMOVE_PRIVATE_AS
|
||||||
&& peer_sort (peer) == BGP_PEER_IBGP)
|
&& peer_sort (peer) == BGP_PEER_IBGP)
|
||||||
return BGP_ERR_REMOVE_PRIVATE_AS;
|
return BGP_ERR_REMOVE_PRIVATE_AS;
|
||||||
@ -3696,12 +3704,6 @@ peer_af_flag_modify (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag,
|
|||||||
&& peer_sort (peer) == BGP_PEER_IBGP)
|
&& peer_sort (peer) == BGP_PEER_IBGP)
|
||||||
return BGP_ERR_AS_OVERRIDE;
|
return BGP_ERR_AS_OVERRIDE;
|
||||||
|
|
||||||
/* When unset the peer-group member's flag we have to check
|
|
||||||
peer-group configuration. */
|
|
||||||
if (! set && peer->af_group[afi][safi])
|
|
||||||
if (CHECK_FLAG (peer->group->conf->af_flags[afi][safi], flag))
|
|
||||||
return BGP_ERR_PEER_GROUP_HAS_THE_FLAG;
|
|
||||||
|
|
||||||
/* When current flag configuration is same as requested one. */
|
/* When current flag configuration is same as requested one. */
|
||||||
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
|
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
|
||||||
{
|
{
|
||||||
@ -4162,14 +4164,6 @@ peer_default_originate_set (struct peer *peer, afi_t afi, safi_t safi,
|
|||||||
struct peer_group *group;
|
struct peer_group *group;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
|
|
||||||
/* Adress family must be activated. */
|
|
||||||
if (! peer->afc[afi][safi])
|
|
||||||
return BGP_ERR_PEER_INACTIVE;
|
|
||||||
|
|
||||||
/* Default originate can't be used for peer group memeber. */
|
|
||||||
if (peer_is_group_member (peer, afi, safi))
|
|
||||||
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
|
|
||||||
|
|
||||||
if (! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE)
|
if (! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE)
|
||||||
|| (rmap && ! peer->default_rmap[afi][safi].name)
|
|| (rmap && ! peer->default_rmap[afi][safi].name)
|
||||||
|| (rmap && strcmp (rmap, peer->default_rmap[afi][safi].name) != 0))
|
|| (rmap && strcmp (rmap, peer->default_rmap[afi][safi].name) != 0))
|
||||||
@ -4224,14 +4218,6 @@ peer_default_originate_unset (struct peer *peer, afi_t afi, safi_t safi)
|
|||||||
struct peer_group *group;
|
struct peer_group *group;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
|
|
||||||
/* Adress family must be activated. */
|
|
||||||
if (! peer->afc[afi][safi])
|
|
||||||
return BGP_ERR_PEER_INACTIVE;
|
|
||||||
|
|
||||||
/* Default originate can't be used for peer group memeber. */
|
|
||||||
if (peer_is_group_member (peer, afi, safi))
|
|
||||||
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
|
|
||||||
|
|
||||||
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE))
|
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE))
|
||||||
{
|
{
|
||||||
UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE);
|
UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE);
|
||||||
@ -4339,10 +4325,6 @@ peer_timers_set (struct peer *peer, u_int32_t keepalive, u_int32_t holdtime)
|
|||||||
struct peer_group *group;
|
struct peer_group *group;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
|
|
||||||
/* Not for peer group memeber. */
|
|
||||||
if (peer_group_active (peer))
|
|
||||||
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
|
|
||||||
|
|
||||||
/* keepalive value check. */
|
/* keepalive value check. */
|
||||||
if (keepalive > 65535)
|
if (keepalive > 65535)
|
||||||
return BGP_ERR_INVALID_VALUE;
|
return BGP_ERR_INVALID_VALUE;
|
||||||
@ -4380,9 +4362,6 @@ peer_timers_unset (struct peer *peer)
|
|||||||
struct peer_group *group;
|
struct peer_group *group;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
|
|
||||||
if (peer_group_active (peer))
|
|
||||||
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
|
|
||||||
|
|
||||||
/* Clear configuration. */
|
/* Clear configuration. */
|
||||||
UNSET_FLAG (peer->config, PEER_CONFIG_TIMER);
|
UNSET_FLAG (peer->config, PEER_CONFIG_TIMER);
|
||||||
peer->keepalive = 0;
|
peer->keepalive = 0;
|
||||||
@ -4409,9 +4388,6 @@ peer_timers_connect_set (struct peer *peer, u_int32_t connect)
|
|||||||
struct peer_group *group;
|
struct peer_group *group;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
|
|
||||||
if (peer_group_active (peer))
|
|
||||||
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
|
|
||||||
|
|
||||||
if (connect > 65535)
|
if (connect > 65535)
|
||||||
return BGP_ERR_INVALID_VALUE;
|
return BGP_ERR_INVALID_VALUE;
|
||||||
|
|
||||||
@ -4442,9 +4418,6 @@ peer_timers_connect_unset (struct peer *peer)
|
|||||||
struct peer_group *group;
|
struct peer_group *group;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
|
|
||||||
if (peer_group_active (peer))
|
|
||||||
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
|
|
||||||
|
|
||||||
/* Clear configuration. */
|
/* Clear configuration. */
|
||||||
UNSET_FLAG (peer->config, PEER_CONFIG_CONNECT);
|
UNSET_FLAG (peer->config, PEER_CONFIG_CONNECT);
|
||||||
peer->connect = 0;
|
peer->connect = 0;
|
||||||
@ -4472,9 +4445,6 @@ peer_advertise_interval_set (struct peer *peer, u_int32_t routeadv)
|
|||||||
struct peer_group *group;
|
struct peer_group *group;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
|
|
||||||
if (peer_group_active (peer))
|
|
||||||
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
|
|
||||||
|
|
||||||
if (routeadv > 600)
|
if (routeadv > 600)
|
||||||
return BGP_ERR_INVALID_VALUE;
|
return BGP_ERR_INVALID_VALUE;
|
||||||
|
|
||||||
@ -4510,9 +4480,6 @@ peer_advertise_interval_unset (struct peer *peer)
|
|||||||
struct peer_group *group;
|
struct peer_group *group;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
|
|
||||||
if (peer_group_active (peer))
|
|
||||||
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
|
|
||||||
|
|
||||||
UNSET_FLAG (peer->config, PEER_CONFIG_ROUTEADV);
|
UNSET_FLAG (peer->config, PEER_CONFIG_ROUTEADV);
|
||||||
peer->routeadv = 0;
|
peer->routeadv = 0;
|
||||||
|
|
||||||
@ -4640,9 +4607,6 @@ peer_local_as_set (struct peer *peer, as_t as, int no_prepend, int replace_as)
|
|||||||
if (bgp->as == as)
|
if (bgp->as == as)
|
||||||
return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS;
|
return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS;
|
||||||
|
|
||||||
if (peer_group_active (peer))
|
|
||||||
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
|
|
||||||
|
|
||||||
if (peer->as == as)
|
if (peer->as == as)
|
||||||
return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS;
|
return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS;
|
||||||
|
|
||||||
@ -4710,9 +4674,6 @@ peer_local_as_unset (struct peer *peer)
|
|||||||
struct peer_group *group;
|
struct peer_group *group;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
|
|
||||||
if (peer_group_active (peer))
|
|
||||||
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
|
|
||||||
|
|
||||||
if (! peer->change_local_as)
|
if (! peer->change_local_as)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -4822,11 +4783,6 @@ peer_password_unset (struct peer *peer)
|
|||||||
|
|
||||||
if (!CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
|
if (!CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
|
||||||
{
|
{
|
||||||
if (peer_group_active (peer)
|
|
||||||
&& peer->group->conf->password
|
|
||||||
&& strcmp (peer->group->conf->password, peer->password) == 0)
|
|
||||||
return BGP_ERR_PEER_GROUP_HAS_THE_FLAG;
|
|
||||||
|
|
||||||
if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
|
if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
|
||||||
bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
|
bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
|
||||||
else
|
else
|
||||||
@ -4903,15 +4859,9 @@ peer_distribute_set (struct peer *peer, afi_t afi, safi_t safi, int direct,
|
|||||||
struct peer_group *group;
|
struct peer_group *group;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
|
|
||||||
if (! peer->afc[afi][safi])
|
|
||||||
return BGP_ERR_PEER_INACTIVE;
|
|
||||||
|
|
||||||
if (direct != FILTER_IN && direct != FILTER_OUT)
|
if (direct != FILTER_IN && direct != FILTER_OUT)
|
||||||
return BGP_ERR_INVALID_VALUE;
|
return BGP_ERR_INVALID_VALUE;
|
||||||
|
|
||||||
if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
|
|
||||||
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
|
|
||||||
|
|
||||||
filter = &peer->filter[afi][safi];
|
filter = &peer->filter[afi][safi];
|
||||||
|
|
||||||
if (filter->plist[direct].name)
|
if (filter->plist[direct].name)
|
||||||
@ -4956,15 +4906,9 @@ peer_distribute_unset (struct peer *peer, afi_t afi, safi_t safi, int direct)
|
|||||||
struct peer_group *group;
|
struct peer_group *group;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
|
|
||||||
if (! peer->afc[afi][safi])
|
|
||||||
return BGP_ERR_PEER_INACTIVE;
|
|
||||||
|
|
||||||
if (direct != FILTER_IN && direct != FILTER_OUT)
|
if (direct != FILTER_IN && direct != FILTER_OUT)
|
||||||
return BGP_ERR_INVALID_VALUE;
|
return BGP_ERR_INVALID_VALUE;
|
||||||
|
|
||||||
if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
|
|
||||||
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
|
|
||||||
|
|
||||||
filter = &peer->filter[afi][safi];
|
filter = &peer->filter[afi][safi];
|
||||||
|
|
||||||
/* apply peer-group filter */
|
/* apply peer-group filter */
|
||||||
@ -5080,15 +5024,9 @@ peer_prefix_list_set (struct peer *peer, afi_t afi, safi_t safi, int direct,
|
|||||||
struct peer_group *group;
|
struct peer_group *group;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
|
|
||||||
if (! peer->afc[afi][safi])
|
|
||||||
return BGP_ERR_PEER_INACTIVE;
|
|
||||||
|
|
||||||
if (direct != FILTER_IN && direct != FILTER_OUT)
|
if (direct != FILTER_IN && direct != FILTER_OUT)
|
||||||
return BGP_ERR_INVALID_VALUE;
|
return BGP_ERR_INVALID_VALUE;
|
||||||
|
|
||||||
if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
|
|
||||||
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
|
|
||||||
|
|
||||||
filter = &peer->filter[afi][safi];
|
filter = &peer->filter[afi][safi];
|
||||||
|
|
||||||
if (filter->dlist[direct].name)
|
if (filter->dlist[direct].name)
|
||||||
@ -5132,15 +5070,9 @@ peer_prefix_list_unset (struct peer *peer, afi_t afi, safi_t safi, int direct)
|
|||||||
struct peer_group *group;
|
struct peer_group *group;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
|
|
||||||
if (! peer->afc[afi][safi])
|
|
||||||
return BGP_ERR_PEER_INACTIVE;
|
|
||||||
|
|
||||||
if (direct != FILTER_IN && direct != FILTER_OUT)
|
if (direct != FILTER_IN && direct != FILTER_OUT)
|
||||||
return BGP_ERR_INVALID_VALUE;
|
return BGP_ERR_INVALID_VALUE;
|
||||||
|
|
||||||
if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
|
|
||||||
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
|
|
||||||
|
|
||||||
filter = &peer->filter[afi][safi];
|
filter = &peer->filter[afi][safi];
|
||||||
|
|
||||||
/* apply peer-group filter */
|
/* apply peer-group filter */
|
||||||
@ -5259,15 +5191,9 @@ peer_aslist_set (struct peer *peer, afi_t afi, safi_t safi, int direct,
|
|||||||
struct peer_group *group;
|
struct peer_group *group;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
|
|
||||||
if (! peer->afc[afi][safi])
|
|
||||||
return BGP_ERR_PEER_INACTIVE;
|
|
||||||
|
|
||||||
if (direct != FILTER_IN && direct != FILTER_OUT)
|
if (direct != FILTER_IN && direct != FILTER_OUT)
|
||||||
return BGP_ERR_INVALID_VALUE;
|
return BGP_ERR_INVALID_VALUE;
|
||||||
|
|
||||||
if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
|
|
||||||
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
|
|
||||||
|
|
||||||
filter = &peer->filter[afi][safi];
|
filter = &peer->filter[afi][safi];
|
||||||
|
|
||||||
if (filter->aslist[direct].name)
|
if (filter->aslist[direct].name)
|
||||||
@ -5308,15 +5234,9 @@ peer_aslist_unset (struct peer *peer,afi_t afi, safi_t safi, int direct)
|
|||||||
struct peer_group *group;
|
struct peer_group *group;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
|
|
||||||
if (! peer->afc[afi][safi])
|
|
||||||
return BGP_ERR_PEER_INACTIVE;
|
|
||||||
|
|
||||||
if (direct != FILTER_IN && direct != FILTER_OUT)
|
if (direct != FILTER_IN && direct != FILTER_OUT)
|
||||||
return BGP_ERR_INVALID_VALUE;
|
return BGP_ERR_INVALID_VALUE;
|
||||||
|
|
||||||
if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
|
|
||||||
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
|
|
||||||
|
|
||||||
filter = &peer->filter[afi][safi];
|
filter = &peer->filter[afi][safi];
|
||||||
|
|
||||||
/* apply peer-group filter */
|
/* apply peer-group filter */
|
||||||
@ -5445,17 +5365,10 @@ peer_route_map_set (struct peer *peer, afi_t afi, safi_t safi, int direct,
|
|||||||
struct peer_group *group;
|
struct peer_group *group;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
|
|
||||||
if (! peer->afc[afi][safi])
|
|
||||||
return BGP_ERR_PEER_INACTIVE;
|
|
||||||
|
|
||||||
if (direct != RMAP_IN && direct != RMAP_OUT &&
|
if (direct != RMAP_IN && direct != RMAP_OUT &&
|
||||||
direct != RMAP_IMPORT && direct != RMAP_EXPORT)
|
direct != RMAP_IMPORT && direct != RMAP_EXPORT)
|
||||||
return BGP_ERR_INVALID_VALUE;
|
return BGP_ERR_INVALID_VALUE;
|
||||||
|
|
||||||
if ( (direct == RMAP_OUT || direct == RMAP_IMPORT)
|
|
||||||
&& peer_is_group_member (peer, afi, safi))
|
|
||||||
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
|
|
||||||
|
|
||||||
filter = &peer->filter[afi][safi];
|
filter = &peer->filter[afi][safi];
|
||||||
|
|
||||||
if (filter->map[direct].name)
|
if (filter->map[direct].name)
|
||||||
@ -5498,17 +5411,10 @@ peer_route_map_unset (struct peer *peer, afi_t afi, safi_t safi, int direct)
|
|||||||
struct peer_group *group;
|
struct peer_group *group;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
|
|
||||||
if (! peer->afc[afi][safi])
|
|
||||||
return BGP_ERR_PEER_INACTIVE;
|
|
||||||
|
|
||||||
if (direct != RMAP_IN && direct != RMAP_OUT &&
|
if (direct != RMAP_IN && direct != RMAP_OUT &&
|
||||||
direct != RMAP_IMPORT && direct != RMAP_EXPORT)
|
direct != RMAP_IMPORT && direct != RMAP_EXPORT)
|
||||||
return BGP_ERR_INVALID_VALUE;
|
return BGP_ERR_INVALID_VALUE;
|
||||||
|
|
||||||
if ( (direct == RMAP_OUT || direct == RMAP_IMPORT)
|
|
||||||
&& peer_is_group_member (peer, afi, safi))
|
|
||||||
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
|
|
||||||
|
|
||||||
filter = &peer->filter[afi][safi];
|
filter = &peer->filter[afi][safi];
|
||||||
|
|
||||||
/* apply peer-group filter */
|
/* apply peer-group filter */
|
||||||
@ -5567,12 +5473,6 @@ peer_unsuppress_map_set (struct peer *peer, afi_t afi, safi_t safi,
|
|||||||
struct peer_group *group;
|
struct peer_group *group;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
|
|
||||||
if (! peer->afc[afi][safi])
|
|
||||||
return BGP_ERR_PEER_INACTIVE;
|
|
||||||
|
|
||||||
if (peer_is_group_member (peer, afi, safi))
|
|
||||||
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
|
|
||||||
|
|
||||||
filter = &peer->filter[afi][safi];
|
filter = &peer->filter[afi][safi];
|
||||||
|
|
||||||
if (filter->usmap.name)
|
if (filter->usmap.name)
|
||||||
@ -5612,12 +5512,6 @@ peer_unsuppress_map_unset (struct peer *peer, afi_t afi, safi_t safi)
|
|||||||
struct peer_group *group;
|
struct peer_group *group;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
|
|
||||||
if (! peer->afc[afi][safi])
|
|
||||||
return BGP_ERR_PEER_INACTIVE;
|
|
||||||
|
|
||||||
if (peer_is_group_member (peer, afi, safi))
|
|
||||||
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
|
|
||||||
|
|
||||||
filter = &peer->filter[afi][safi];
|
filter = &peer->filter[afi][safi];
|
||||||
|
|
||||||
if (filter->usmap.name)
|
if (filter->usmap.name)
|
||||||
@ -5656,9 +5550,6 @@ peer_maximum_prefix_set (struct peer *peer, afi_t afi, safi_t safi,
|
|||||||
struct peer_group *group;
|
struct peer_group *group;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
|
|
||||||
if (! peer->afc[afi][safi])
|
|
||||||
return BGP_ERR_PEER_INACTIVE;
|
|
||||||
|
|
||||||
SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
|
SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
|
||||||
peer->pmax[afi][safi] = max;
|
peer->pmax[afi][safi] = max;
|
||||||
peer->pmax_threshold[afi][safi] = threshold;
|
peer->pmax_threshold[afi][safi] = threshold;
|
||||||
@ -5704,9 +5595,6 @@ peer_maximum_prefix_unset (struct peer *peer, afi_t afi, safi_t safi)
|
|||||||
struct peer_group *group;
|
struct peer_group *group;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
|
|
||||||
if (! peer->afc[afi][safi])
|
|
||||||
return BGP_ERR_PEER_INACTIVE;
|
|
||||||
|
|
||||||
/* apply peer-group config */
|
/* apply peer-group config */
|
||||||
if (peer->af_group[afi][safi])
|
if (peer->af_group[afi][safi])
|
||||||
{
|
{
|
||||||
@ -6141,9 +6029,35 @@ peer_uptime (time_t uptime2, char *buf, size_t len, u_char use_json, json_object
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
afi_header_vty_out (struct vty *vty, afi_t afi, safi_t safi,
|
||||||
|
int *write, const char *format, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
int len = 0;
|
||||||
|
char buf[1024];
|
||||||
|
|
||||||
|
bgp_config_write_family_header (vty, afi, safi, write);
|
||||||
|
|
||||||
|
if (vty_shell (vty))
|
||||||
|
{
|
||||||
|
va_start (args, format);
|
||||||
|
vprintf (format, args);
|
||||||
|
va_end (args);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
va_start (args, format);
|
||||||
|
len = vsnprintf (buf, sizeof(buf), format, args);
|
||||||
|
va_end (args);
|
||||||
|
|
||||||
|
buffer_put (vty->obuf, (u_char *) buf, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
bgp_config_write_filter (struct vty *vty, struct peer *peer,
|
bgp_config_write_filter (struct vty *vty, struct peer *peer,
|
||||||
afi_t afi, safi_t safi)
|
afi_t afi, safi_t safi, int *write)
|
||||||
{
|
{
|
||||||
struct bgp_filter *filter;
|
struct bgp_filter *filter;
|
||||||
struct bgp_filter *gfilter = NULL;
|
struct bgp_filter *gfilter = NULL;
|
||||||
@ -6160,55 +6074,93 @@ bgp_config_write_filter (struct vty *vty, struct peer *peer,
|
|||||||
if (filter->dlist[in].name)
|
if (filter->dlist[in].name)
|
||||||
if (! gfilter || ! gfilter->dlist[in].name
|
if (! gfilter || ! gfilter->dlist[in].name
|
||||||
|| strcmp (filter->dlist[in].name, gfilter->dlist[in].name) != 0)
|
|| strcmp (filter->dlist[in].name, gfilter->dlist[in].name) != 0)
|
||||||
vty_out (vty, " neighbor %s distribute-list %s in%s", addr,
|
{
|
||||||
filter->dlist[in].name, VTY_NEWLINE);
|
afi_header_vty_out (vty, afi, safi, write,
|
||||||
|
" neighbor %s distribute-list %s in%s",
|
||||||
|
addr, filter->dlist[in].name, VTY_NEWLINE);
|
||||||
|
}
|
||||||
|
|
||||||
if (filter->dlist[out].name && ! gfilter)
|
if (filter->dlist[out].name && ! gfilter)
|
||||||
vty_out (vty, " neighbor %s distribute-list %s out%s", addr,
|
{
|
||||||
filter->dlist[out].name, VTY_NEWLINE);
|
afi_header_vty_out (vty, afi, safi, write,
|
||||||
|
" neighbor %s distribute-list %s out%s",
|
||||||
|
addr, filter->dlist[out].name, VTY_NEWLINE);
|
||||||
|
}
|
||||||
|
|
||||||
/* prefix-list. */
|
/* prefix-list. */
|
||||||
if (filter->plist[in].name)
|
if (filter->plist[in].name)
|
||||||
if (! gfilter || ! gfilter->plist[in].name
|
if (! gfilter || ! gfilter->plist[in].name
|
||||||
|| strcmp (filter->plist[in].name, gfilter->plist[in].name) != 0)
|
|| strcmp (filter->plist[in].name, gfilter->plist[in].name) != 0)
|
||||||
vty_out (vty, " neighbor %s prefix-list %s in%s", addr,
|
{
|
||||||
filter->plist[in].name, VTY_NEWLINE);
|
afi_header_vty_out (vty, afi, safi, write,
|
||||||
|
" neighbor %s prefix-list %s in%s",
|
||||||
|
addr, filter->plist[in].name, VTY_NEWLINE);
|
||||||
|
}
|
||||||
|
|
||||||
if (filter->plist[out].name && ! gfilter)
|
if (filter->plist[out].name && ! gfilter)
|
||||||
vty_out (vty, " neighbor %s prefix-list %s out%s", addr,
|
{
|
||||||
filter->plist[out].name, VTY_NEWLINE);
|
afi_header_vty_out (vty, afi, safi, write,
|
||||||
|
" neighbor %s prefix-list %s out%s",
|
||||||
|
addr, filter->plist[out].name, VTY_NEWLINE);
|
||||||
|
}
|
||||||
|
|
||||||
/* route-map. */
|
/* route-map. */
|
||||||
if (filter->map[RMAP_IN].name)
|
if (filter->map[RMAP_IN].name)
|
||||||
if (! gfilter || ! gfilter->map[RMAP_IN].name
|
if (! gfilter || ! gfilter->map[RMAP_IN].name
|
||||||
|| strcmp (filter->map[RMAP_IN].name, gfilter->map[RMAP_IN].name) != 0)
|
|| strcmp (filter->map[RMAP_IN].name, gfilter->map[RMAP_IN].name) != 0)
|
||||||
vty_out (vty, " neighbor %s route-map %s in%s", addr,
|
{
|
||||||
filter->map[RMAP_IN].name, VTY_NEWLINE);
|
afi_header_vty_out (vty, afi, safi, write,
|
||||||
|
" neighbor %s route-map %s in%s",
|
||||||
|
addr, filter->map[RMAP_IN].name, VTY_NEWLINE);
|
||||||
|
}
|
||||||
|
|
||||||
if (filter->map[RMAP_OUT].name && ! gfilter)
|
if (filter->map[RMAP_OUT].name && ! gfilter)
|
||||||
vty_out (vty, " neighbor %s route-map %s out%s", addr,
|
{
|
||||||
filter->map[RMAP_OUT].name, VTY_NEWLINE);
|
afi_header_vty_out (vty, afi, safi, write,
|
||||||
|
" neighbor %s route-map %s out%s",
|
||||||
|
addr, filter->map[RMAP_OUT].name, VTY_NEWLINE);
|
||||||
|
}
|
||||||
|
|
||||||
if (filter->map[RMAP_IMPORT].name && ! gfilter)
|
if (filter->map[RMAP_IMPORT].name && ! gfilter)
|
||||||
vty_out (vty, " neighbor %s route-map %s import%s", addr,
|
{
|
||||||
filter->map[RMAP_IMPORT].name, VTY_NEWLINE);
|
afi_header_vty_out (vty, afi, safi, write,
|
||||||
|
" neighbor %s route-map %s import%s",
|
||||||
|
addr, filter->map[RMAP_IMPORT].name, VTY_NEWLINE);
|
||||||
|
}
|
||||||
|
|
||||||
if (filter->map[RMAP_EXPORT].name)
|
if (filter->map[RMAP_EXPORT].name)
|
||||||
if (! gfilter || ! gfilter->map[RMAP_EXPORT].name
|
if (! gfilter || ! gfilter->map[RMAP_EXPORT].name
|
||||||
|| strcmp (filter->map[RMAP_EXPORT].name,
|
|| strcmp (filter->map[RMAP_EXPORT].name, gfilter->map[RMAP_EXPORT].name) != 0)
|
||||||
gfilter->map[RMAP_EXPORT].name) != 0)
|
{
|
||||||
vty_out (vty, " neighbor %s route-map %s export%s", addr,
|
afi_header_vty_out (vty, afi, safi, write,
|
||||||
filter->map[RMAP_EXPORT].name, VTY_NEWLINE);
|
" neighbor %s route-map %s export%s",
|
||||||
|
addr, filter->map[RMAP_EXPORT].name, VTY_NEWLINE);
|
||||||
|
}
|
||||||
|
|
||||||
/* unsuppress-map */
|
/* unsuppress-map */
|
||||||
if (filter->usmap.name && ! gfilter)
|
if (filter->usmap.name && ! gfilter)
|
||||||
vty_out (vty, " neighbor %s unsuppress-map %s%s", addr,
|
{
|
||||||
filter->usmap.name, VTY_NEWLINE);
|
afi_header_vty_out (vty, afi, safi, write,
|
||||||
|
" neighbor %s unsuppress-map %s%s",
|
||||||
|
addr, filter->usmap.name, VTY_NEWLINE);
|
||||||
|
}
|
||||||
|
|
||||||
/* filter-list. */
|
/* filter-list. */
|
||||||
if (filter->aslist[in].name)
|
if (filter->aslist[in].name)
|
||||||
if (! gfilter || ! gfilter->aslist[in].name
|
if (! gfilter || ! gfilter->aslist[in].name
|
||||||
|| strcmp (filter->aslist[in].name, gfilter->aslist[in].name) != 0)
|
|| strcmp (filter->aslist[in].name, gfilter->aslist[in].name) != 0)
|
||||||
vty_out (vty, " neighbor %s filter-list %s in%s", addr,
|
{
|
||||||
filter->aslist[in].name, VTY_NEWLINE);
|
afi_header_vty_out (vty, afi, safi, write,
|
||||||
|
" neighbor %s filter-list %s in%s",
|
||||||
|
addr, filter->aslist[in].name, VTY_NEWLINE);
|
||||||
|
}
|
||||||
|
|
||||||
if (filter->aslist[out].name && ! gfilter)
|
if (filter->aslist[out].name && ! gfilter)
|
||||||
vty_out (vty, " neighbor %s filter-list %s out%s", addr,
|
{
|
||||||
filter->aslist[out].name, VTY_NEWLINE);
|
afi_header_vty_out (vty, afi, safi, write,
|
||||||
|
" neighbor %s filter-list %s out%s",
|
||||||
|
addr, filter->aslist[out].name, VTY_NEWLINE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BGP peer configuration display function. */
|
/* BGP peer configuration display function. */
|
||||||
@ -6446,6 +6398,7 @@ bgp_config_write_peer_global (struct vty *vty, struct bgp *bgp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (CHECK_FLAG (peer->config, PEER_CONFIG_CONNECT) &&
|
if (CHECK_FLAG (peer->config, PEER_CONFIG_CONNECT) &&
|
||||||
|
peer->connect != BGP_DEFAULT_CONNECT_RETRY &&
|
||||||
! peer_group_active (peer))
|
! peer_group_active (peer))
|
||||||
{
|
{
|
||||||
vty_out (vty, " neighbor %s timers connect %d%s", addr,
|
vty_out (vty, " neighbor %s timers connect %d%s", addr,
|
||||||
@ -6518,11 +6471,11 @@ bgp_config_write_peer_global (struct vty *vty, struct bgp *bgp,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* BGP peer configuration display function. */
|
/* BGP peer configuration display function. */
|
||||||
static void
|
static void
|
||||||
bgp_config_write_peer_af (struct vty *vty, struct bgp *bgp,
|
bgp_config_write_peer_af (struct vty *vty, struct bgp *bgp,
|
||||||
struct peer *peer, afi_t afi, safi_t safi)
|
struct peer *peer, afi_t afi, safi_t safi,
|
||||||
|
int *write)
|
||||||
{
|
{
|
||||||
struct peer *g_peer = NULL;
|
struct peer *g_peer = NULL;
|
||||||
char *addr;
|
char *addr;
|
||||||
@ -6543,22 +6496,31 @@ bgp_config_write_peer_af (struct vty *vty, struct bgp *bgp,
|
|||||||
****** Per AF to the neighbor ******
|
****** Per AF to the neighbor ******
|
||||||
************************************/
|
************************************/
|
||||||
if (peer->af_group[afi][safi])
|
if (peer->af_group[afi][safi])
|
||||||
vty_out (vty, " neighbor %s peer-group %s%s", addr,
|
{
|
||||||
peer->group->name, VTY_NEWLINE);
|
afi_header_vty_out (vty, afi, safi, write,
|
||||||
|
" neighbor %s peer-group %s%s", addr,
|
||||||
|
peer->group->name, VTY_NEWLINE);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
vty_out (vty, " neighbor %s activate%s", addr, VTY_NEWLINE);
|
if (peer->afc[afi][safi])
|
||||||
|
{
|
||||||
|
afi_header_vty_out (vty, afi, safi, write,
|
||||||
|
" neighbor %s activate%s",
|
||||||
|
addr, VTY_NEWLINE);
|
||||||
|
}
|
||||||
|
|
||||||
/* ORF capability. */
|
/* ORF capability. */
|
||||||
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
|
if (peergroup_af_flag_check (peer, afi, safi, PEER_FLAG_ORF_PREFIX_SM) ||
|
||||||
|| CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
|
peergroup_af_flag_check (peer, afi, safi, PEER_FLAG_ORF_PREFIX_RM))
|
||||||
if (! peer->af_group[afi][safi])
|
|
||||||
{
|
{
|
||||||
vty_out (vty, " neighbor %s capability orf prefix-list", addr);
|
afi_header_vty_out (vty, afi, safi, write,
|
||||||
|
" neighbor %s capability orf prefix-list",
|
||||||
|
addr);
|
||||||
|
|
||||||
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
|
if (peergroup_af_flag_check (peer, afi, safi, PEER_FLAG_ORF_PREFIX_SM) &&
|
||||||
&& CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
|
peergroup_af_flag_check (peer, afi, safi, PEER_FLAG_ORF_PREFIX_RM))
|
||||||
vty_out (vty, " both");
|
vty_out (vty, " both");
|
||||||
else if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM))
|
else if (peergroup_af_flag_check (peer, afi, safi, PEER_FLAG_ORF_PREFIX_SM))
|
||||||
vty_out (vty, " send");
|
vty_out (vty, " send");
|
||||||
else
|
else
|
||||||
vty_out (vty, " receive");
|
vty_out (vty, " receive");
|
||||||
@ -6566,87 +6528,138 @@ bgp_config_write_peer_af (struct vty *vty, struct bgp *bgp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Route reflector client. */
|
/* Route reflector client. */
|
||||||
if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REFLECTOR_CLIENT)
|
if (peergroup_af_flag_check (peer, afi, safi, PEER_FLAG_REFLECTOR_CLIENT))
|
||||||
&& ! peer->af_group[afi][safi])
|
{
|
||||||
vty_out (vty, " neighbor %s route-reflector-client%s", addr,
|
afi_header_vty_out (vty, afi, safi, write,
|
||||||
VTY_NEWLINE);
|
" neighbor %s route-reflector-client%s",
|
||||||
|
addr, VTY_NEWLINE);
|
||||||
|
}
|
||||||
|
|
||||||
/* Nexthop self. */
|
/* next-hop-self force */
|
||||||
if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_FORCE_NEXTHOP_SELF)
|
if (peergroup_af_flag_check (peer, afi, safi, PEER_FLAG_FORCE_NEXTHOP_SELF))
|
||||||
&& ! peer->af_group[afi][safi])
|
{
|
||||||
vty_out (vty, " neighbor %s next-hop-self force%s",
|
afi_header_vty_out (vty, afi, safi, write,
|
||||||
addr, VTY_NEWLINE);
|
" neighbor %s next-hop-self force%s",
|
||||||
else if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_NEXTHOP_SELF)
|
addr, VTY_NEWLINE);
|
||||||
&& ! peer->af_group[afi][safi])
|
}
|
||||||
vty_out (vty, " neighbor %s next-hop-self%s", addr, VTY_NEWLINE);
|
|
||||||
|
/* next-hop-self */
|
||||||
|
if (peergroup_af_flag_check (peer, afi, safi, PEER_FLAG_NEXTHOP_SELF))
|
||||||
|
{
|
||||||
|
afi_header_vty_out (vty, afi, safi, write,
|
||||||
|
" neighbor %s next-hop-self%s",
|
||||||
|
addr, VTY_NEWLINE);
|
||||||
|
}
|
||||||
|
|
||||||
/* remove-private-AS */
|
/* remove-private-AS */
|
||||||
if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS) && !peer->af_group[afi][safi])
|
if (peergroup_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE))
|
||||||
{
|
{
|
||||||
if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_ALL) &&
|
afi_header_vty_out (vty, afi, safi, write,
|
||||||
peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
|
" neighbor %s remove-private-AS all replace-AS%s",
|
||||||
vty_out (vty, " neighbor %s remove-private-AS all replace-AS%s", addr, VTY_NEWLINE);
|
addr, VTY_NEWLINE);
|
||||||
|
}
|
||||||
|
|
||||||
else if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
|
else if (peergroup_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
|
||||||
vty_out (vty, " neighbor %s remove-private-AS replace-AS%s", addr, VTY_NEWLINE);
|
{
|
||||||
|
afi_header_vty_out (vty, afi, safi, write,
|
||||||
|
" neighbor %s remove-private-AS replace-AS%s",
|
||||||
|
addr, VTY_NEWLINE);
|
||||||
|
}
|
||||||
|
|
||||||
else if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_ALL))
|
else if (peergroup_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_ALL))
|
||||||
vty_out (vty, " neighbor %s remove-private-AS all%s", addr, VTY_NEWLINE);
|
{
|
||||||
|
afi_header_vty_out (vty, afi, safi, write,
|
||||||
|
" neighbor %s remove-private-AS all%s",
|
||||||
|
addr, VTY_NEWLINE);
|
||||||
|
}
|
||||||
|
|
||||||
else
|
else if (peergroup_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS))
|
||||||
vty_out (vty, " neighbor %s remove-private-AS%s", addr, VTY_NEWLINE);
|
{
|
||||||
|
afi_header_vty_out (vty, afi, safi, write,
|
||||||
|
" neighbor %s remove-private-AS%s",
|
||||||
|
addr, VTY_NEWLINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* as-override */
|
/* as-override */
|
||||||
if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_AS_OVERRIDE) &&
|
if (peergroup_af_flag_check (peer, afi, safi, PEER_FLAG_AS_OVERRIDE))
|
||||||
!peer->af_group[afi][safi])
|
{
|
||||||
vty_out (vty, " neighbor %s as-override%s", addr, VTY_NEWLINE);
|
afi_header_vty_out (vty, afi, safi, write,
|
||||||
|
" neighbor %s as-override%s",
|
||||||
|
addr, VTY_NEWLINE);
|
||||||
|
}
|
||||||
|
|
||||||
/* send-community print. */
|
/* send-community print. */
|
||||||
if (! peer->af_group[afi][safi])
|
if (bgp_option_check (BGP_OPT_CONFIG_CISCO))
|
||||||
{
|
{
|
||||||
if (bgp_option_check (BGP_OPT_CONFIG_CISCO))
|
if (peergroup_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY)
|
||||||
{
|
&& peergroup_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY))
|
||||||
if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY)
|
{
|
||||||
&& peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY))
|
afi_header_vty_out (vty, afi, safi, write,
|
||||||
vty_out (vty, " neighbor %s send-community both%s", addr, VTY_NEWLINE);
|
" neighbor %s send-community both%s",
|
||||||
else if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY))
|
addr, VTY_NEWLINE);
|
||||||
vty_out (vty, " neighbor %s send-community extended%s",
|
}
|
||||||
addr, VTY_NEWLINE);
|
else if (peergroup_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY))
|
||||||
else if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY))
|
{
|
||||||
vty_out (vty, " neighbor %s send-community%s", addr, VTY_NEWLINE);
|
afi_header_vty_out (vty, afi, safi, write,
|
||||||
}
|
" neighbor %s send-community extended%s",
|
||||||
else
|
addr, VTY_NEWLINE);
|
||||||
{
|
}
|
||||||
if (! peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY)
|
else if (peergroup_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY))
|
||||||
&& ! peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY))
|
{
|
||||||
vty_out (vty, " no neighbor %s send-community both%s",
|
afi_header_vty_out (vty, afi, safi, write,
|
||||||
addr, VTY_NEWLINE);
|
" neighbor %s send-community%s",
|
||||||
else if (! peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY))
|
addr, VTY_NEWLINE);
|
||||||
vty_out (vty, " no neighbor %s send-community extended%s",
|
}
|
||||||
addr, VTY_NEWLINE);
|
}
|
||||||
else if (! peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY))
|
else
|
||||||
vty_out (vty, " no neighbor %s send-community%s",
|
{
|
||||||
addr, VTY_NEWLINE);
|
if (!peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY) &&
|
||||||
}
|
peer_af_flag_check (g_peer, afi, safi, PEER_FLAG_SEND_COMMUNITY) &&
|
||||||
|
!peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY) &&
|
||||||
|
peer_af_flag_check (g_peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY))
|
||||||
|
{
|
||||||
|
afi_header_vty_out (vty, afi, safi, write,
|
||||||
|
" no neighbor %s send-community both%s",
|
||||||
|
addr, VTY_NEWLINE);
|
||||||
|
}
|
||||||
|
else if (!peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY) &&
|
||||||
|
peer_af_flag_check (g_peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY))
|
||||||
|
{
|
||||||
|
afi_header_vty_out (vty, afi, safi, write,
|
||||||
|
" no neighbor %s send-community extended%s",
|
||||||
|
addr, VTY_NEWLINE);
|
||||||
|
}
|
||||||
|
else if (!peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY) &&
|
||||||
|
peer_af_flag_check (g_peer, afi, safi, PEER_FLAG_SEND_COMMUNITY))
|
||||||
|
{
|
||||||
|
afi_header_vty_out (vty, afi, safi, write,
|
||||||
|
" no neighbor %s send-community%s",
|
||||||
|
addr, VTY_NEWLINE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Default information */
|
/* Default information */
|
||||||
if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_DEFAULT_ORIGINATE)
|
if (peergroup_af_flag_check (peer, afi, safi, PEER_FLAG_DEFAULT_ORIGINATE) ||
|
||||||
&& ! peer->af_group[afi][safi])
|
(g_peer &&
|
||||||
|
((peer->default_rmap[afi][safi].name && !g_peer->default_rmap[afi][safi].name) ||
|
||||||
|
(!peer->default_rmap[afi][safi].name && g_peer->default_rmap[afi][safi].name) ||
|
||||||
|
(peer->default_rmap[afi][safi].name &&
|
||||||
|
strcmp(peer->default_rmap[afi][safi].name, g_peer->default_rmap[afi][safi].name)))))
|
||||||
{
|
{
|
||||||
vty_out (vty, " neighbor %s default-originate", addr);
|
afi_header_vty_out (vty, afi, safi, write,
|
||||||
|
" neighbor %s default-originate", addr);
|
||||||
if (peer->default_rmap[afi][safi].name)
|
if (peer->default_rmap[afi][safi].name)
|
||||||
vty_out (vty, " route-map %s", peer->default_rmap[afi][safi].name);
|
vty_out (vty, " route-map %s", peer->default_rmap[afi][safi].name);
|
||||||
vty_out (vty, "%s", VTY_NEWLINE);
|
vty_out (vty, "%s", VTY_NEWLINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Soft reconfiguration inbound. */
|
/* Soft reconfiguration inbound. */
|
||||||
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
|
if (peergroup_af_flag_check (peer, afi, safi, PEER_FLAG_SOFT_RECONFIG))
|
||||||
if (! peer->af_group[afi][safi] ||
|
{
|
||||||
! CHECK_FLAG (g_peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
|
afi_header_vty_out (vty, afi, safi, write,
|
||||||
vty_out (vty, " neighbor %s soft-reconfiguration inbound%s", addr,
|
" neighbor %s soft-reconfiguration inbound%s",
|
||||||
VTY_NEWLINE);
|
addr, VTY_NEWLINE);
|
||||||
|
}
|
||||||
|
|
||||||
/* maximum-prefix. */
|
/* maximum-prefix. */
|
||||||
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
|
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
|
||||||
@ -6656,7 +6669,9 @@ bgp_config_write_peer_af (struct vty *vty, struct bgp *bgp,
|
|||||||
|| CHECK_FLAG (g_peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING)
|
|| CHECK_FLAG (g_peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING)
|
||||||
!= CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING))
|
!= CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING))
|
||||||
{
|
{
|
||||||
vty_out (vty, " neighbor %s maximum-prefix %ld", addr, peer->pmax[afi][safi]);
|
afi_header_vty_out (vty, afi, safi, write,
|
||||||
|
" neighbor %s maximum-prefix %ld",
|
||||||
|
addr, peer->pmax[afi][safi]);
|
||||||
if (peer->pmax_threshold[afi][safi] != MAXIMUM_PREFIX_THRESHOLD_DEFAULT)
|
if (peer->pmax_threshold[afi][safi] != MAXIMUM_PREFIX_THRESHOLD_DEFAULT)
|
||||||
vty_out (vty, " %d", peer->pmax_threshold[afi][safi]);
|
vty_out (vty, " %d", peer->pmax_threshold[afi][safi]);
|
||||||
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING))
|
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING))
|
||||||
@ -6667,14 +6682,20 @@ bgp_config_write_peer_af (struct vty *vty, struct bgp *bgp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Route server client. */
|
/* Route server client. */
|
||||||
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
|
if (peergroup_af_flag_check (peer, afi, safi, PEER_FLAG_RSERVER_CLIENT))
|
||||||
&& ! peer->af_group[afi][safi])
|
{
|
||||||
vty_out (vty, " neighbor %s route-server-client%s", addr, VTY_NEWLINE);
|
afi_header_vty_out (vty, afi, safi, write,
|
||||||
|
" neighbor %s route-server-client%s",
|
||||||
|
addr, VTY_NEWLINE);
|
||||||
|
}
|
||||||
|
|
||||||
/* Nexthop-local unchanged. */
|
/* Nexthop-local unchanged. */
|
||||||
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)
|
if (peergroup_af_flag_check (peer, afi, safi, PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED))
|
||||||
&& ! peer->af_group[afi][safi])
|
{
|
||||||
vty_out (vty, " neighbor %s nexthop-local unchanged%s", addr, VTY_NEWLINE);
|
afi_header_vty_out (vty, afi, safi, write,
|
||||||
|
" neighbor %s nexthop-local unchanged%s",
|
||||||
|
addr, VTY_NEWLINE);
|
||||||
|
}
|
||||||
|
|
||||||
/* Allow AS in. */
|
/* Allow AS in. */
|
||||||
if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_ALLOWAS_IN))
|
if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_ALLOWAS_IN))
|
||||||
@ -6683,33 +6704,46 @@ bgp_config_write_peer_af (struct vty *vty, struct bgp *bgp,
|
|||||||
|| peer->allowas_in[afi][safi] != g_peer->allowas_in[afi][safi])
|
|| peer->allowas_in[afi][safi] != g_peer->allowas_in[afi][safi])
|
||||||
{
|
{
|
||||||
if (peer->allowas_in[afi][safi] == 3)
|
if (peer->allowas_in[afi][safi] == 3)
|
||||||
vty_out (vty, " neighbor %s allowas-in%s", addr, VTY_NEWLINE);
|
{
|
||||||
else
|
afi_header_vty_out (vty, afi, safi, write,
|
||||||
vty_out (vty, " neighbor %s allowas-in %d%s", addr,
|
" neighbor %s allowas-in%s",
|
||||||
peer->allowas_in[afi][safi], VTY_NEWLINE);
|
addr, VTY_NEWLINE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
afi_header_vty_out (vty, afi, safi, write,
|
||||||
|
" neighbor %s allowas-in %d%s",
|
||||||
|
addr, peer->allowas_in[afi][safi], VTY_NEWLINE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Filter. */
|
/* Filter. */
|
||||||
bgp_config_write_filter (vty, peer, afi, safi);
|
bgp_config_write_filter (vty, peer, afi, safi, write);
|
||||||
|
|
||||||
/* atribute-unchanged. */
|
/* atribute-unchanged. */
|
||||||
if ((CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED)
|
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED)
|
||||||
|| CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED)
|
|| CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED)
|
||||||
|| CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MED_UNCHANGED))
|
|| CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MED_UNCHANGED))
|
||||||
&& ! peer->af_group[afi][safi])
|
|
||||||
{
|
{
|
||||||
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED)
|
if (peergroup_af_flag_check (peer, afi, safi, PEER_FLAG_AS_PATH_UNCHANGED)
|
||||||
&& CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED)
|
&& peergroup_af_flag_check (peer, afi, safi, PEER_FLAG_NEXTHOP_UNCHANGED)
|
||||||
&& CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MED_UNCHANGED))
|
&& peergroup_af_flag_check (peer, afi, safi, PEER_FLAG_MED_UNCHANGED))
|
||||||
vty_out (vty, " neighbor %s attribute-unchanged%s", addr, VTY_NEWLINE);
|
{
|
||||||
|
afi_header_vty_out (vty, afi, safi, write,
|
||||||
|
" neighbor %s attribute-unchanged%s",
|
||||||
|
addr, VTY_NEWLINE);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
vty_out (vty, " neighbor %s attribute-unchanged%s%s%s%s", addr,
|
{
|
||||||
(CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED)) ?
|
afi_header_vty_out (vty, afi, safi, write,
|
||||||
" as-path" : "",
|
" neighbor %s attribute-unchanged%s%s%s%s", addr,
|
||||||
(CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED)) ?
|
peergroup_af_flag_check (peer, afi, safi, PEER_FLAG_AS_PATH_UNCHANGED) ?
|
||||||
" next-hop" : "",
|
" as-path" : "",
|
||||||
(CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MED_UNCHANGED)) ?
|
peergroup_af_flag_check (peer, afi, safi, PEER_FLAG_NEXTHOP_UNCHANGED) ?
|
||||||
" med" : "", VTY_NEWLINE);
|
" next-hop" : "",
|
||||||
|
peergroup_af_flag_check (peer, afi, safi, PEER_FLAG_MED_UNCHANGED) ?
|
||||||
|
" med" : "", VTY_NEWLINE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6760,27 +6794,17 @@ bgp_config_write_family (struct vty *vty, struct bgp *bgp, afi_t afi,
|
|||||||
bgp_config_write_redistribute (vty, bgp, afi, safi, &write);
|
bgp_config_write_redistribute (vty, bgp, afi, safi, &write);
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
|
for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
|
||||||
{
|
bgp_config_write_peer_af (vty, bgp, group->conf, afi, safi, &write);
|
||||||
if (group->conf->afc[afi][safi])
|
|
||||||
{
|
|
||||||
bgp_config_write_family_header (vty, afi, safi, &write);
|
|
||||||
bgp_config_write_peer_af (vty, bgp, group->conf, afi, safi);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
|
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
|
||||||
{
|
{
|
||||||
/* Skip dynamic neighbors. */
|
/* Skip dynamic neighbors. */
|
||||||
if (peer_dynamic_neighbor (peer))
|
if (peer_dynamic_neighbor (peer))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (peer->afc[afi][safi])
|
/* Do not display doppelganger peers */
|
||||||
{
|
if (CHECK_FLAG (peer->flags, PEER_FLAG_CONFIG_NODE))
|
||||||
if (CHECK_FLAG (peer->flags, PEER_FLAG_CONFIG_NODE))
|
bgp_config_write_peer_af (vty, bgp, peer, afi, safi, &write);
|
||||||
{
|
|
||||||
bgp_config_write_family_header (vty, afi, safi, &write);
|
|
||||||
bgp_config_write_peer_af (vty, bgp, peer, afi, safi);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bgp_config_write_maxpaths (vty, bgp, afi, safi, &write);
|
bgp_config_write_maxpaths (vty, bgp, afi, safi, &write);
|
||||||
|
46
bgpd/bgpd.h
46
bgpd/bgpd.h
@ -647,6 +647,7 @@ struct peer
|
|||||||
#define PEER_FLAG_REMOVE_PRIVATE_AS_ALL (1 << 18) /* remove-private-as all */
|
#define PEER_FLAG_REMOVE_PRIVATE_AS_ALL (1 << 18) /* remove-private-as all */
|
||||||
#define PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE (1 << 19) /* remove-private-as replace-as */
|
#define PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE (1 << 19) /* remove-private-as replace-as */
|
||||||
#define PEER_FLAG_AS_OVERRIDE (1 << 20) /* as-override */
|
#define PEER_FLAG_AS_OVERRIDE (1 << 20) /* as-override */
|
||||||
|
#define PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE (1 << 21) /* remove-private-as all replace-as */
|
||||||
|
|
||||||
/* MD5 password */
|
/* MD5 password */
|
||||||
char *password;
|
char *password;
|
||||||
@ -1068,30 +1069,27 @@ enum bgp_clear_type
|
|||||||
#define BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT -13
|
#define BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT -13
|
||||||
#define BGP_ERR_MULTIPLE_INSTANCE_NOT_SET -14
|
#define BGP_ERR_MULTIPLE_INSTANCE_NOT_SET -14
|
||||||
#define BGP_ERR_AS_MISMATCH -15
|
#define BGP_ERR_AS_MISMATCH -15
|
||||||
#define BGP_ERR_PEER_INACTIVE -16
|
#define BGP_ERR_PEER_FLAG_CONFLICT -16
|
||||||
#define BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER -17
|
#define BGP_ERR_PEER_GROUP_SHUTDOWN -17
|
||||||
#define BGP_ERR_PEER_GROUP_HAS_THE_FLAG -18
|
#define BGP_ERR_PEER_FILTER_CONFLICT -18
|
||||||
#define BGP_ERR_PEER_FLAG_CONFLICT -19
|
#define BGP_ERR_NOT_INTERNAL_PEER -19
|
||||||
#define BGP_ERR_PEER_GROUP_SHUTDOWN -20
|
#define BGP_ERR_REMOVE_PRIVATE_AS -20
|
||||||
#define BGP_ERR_PEER_FILTER_CONFLICT -21
|
#define BGP_ERR_AF_UNCONFIGURED -21
|
||||||
#define BGP_ERR_NOT_INTERNAL_PEER -22
|
#define BGP_ERR_SOFT_RECONFIG_UNCONFIGURED -22
|
||||||
#define BGP_ERR_REMOVE_PRIVATE_AS -23
|
#define BGP_ERR_INSTANCE_MISMATCH -23
|
||||||
#define BGP_ERR_AF_UNCONFIGURED -24
|
#define BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP -24
|
||||||
#define BGP_ERR_SOFT_RECONFIG_UNCONFIGURED -25
|
#define BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS -25
|
||||||
#define BGP_ERR_INSTANCE_MISMATCH -26
|
#define BGP_ERR_TCPSIG_FAILED -26
|
||||||
#define BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP -27
|
#define BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK -27
|
||||||
#define BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS -28
|
#define BGP_ERR_NO_IBGP_WITH_TTLHACK -28
|
||||||
#define BGP_ERR_TCPSIG_FAILED -29
|
#define BGP_ERR_NO_INTERFACE_CONFIG -29
|
||||||
#define BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK -30
|
#define BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS -30
|
||||||
#define BGP_ERR_NO_IBGP_WITH_TTLHACK -31
|
#define BGP_ERR_AS_OVERRIDE -31
|
||||||
#define BGP_ERR_NO_INTERFACE_CONFIG -32
|
#define BGP_ERR_INVALID_DYNAMIC_NEIGHBORS_LIMIT -32
|
||||||
#define BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS -33
|
#define BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_EXISTS -33
|
||||||
#define BGP_ERR_AS_OVERRIDE -34
|
#define BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_NOT_FOUND -34
|
||||||
#define BGP_ERR_INVALID_DYNAMIC_NEIGHBORS_LIMIT -35
|
#define BGP_ERR_INVALID_FOR_DYNAMIC_PEER -35
|
||||||
#define BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_EXISTS -36
|
#define BGP_ERR_MAX -36
|
||||||
#define BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_NOT_FOUND -37
|
|
||||||
#define BGP_ERR_INVALID_FOR_DYNAMIC_PEER -38
|
|
||||||
#define BGP_ERR_MAX -39
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enumeration of different policy kinds a peer can be configured with.
|
* Enumeration of different policy kinds a peer can be configured with.
|
||||||
|
@ -78,12 +78,12 @@ When the program terminates, retain routes added by \fBbgpd\fR.
|
|||||||
Print the version and exit.
|
Print the version and exit.
|
||||||
.SH FILES
|
.SH FILES
|
||||||
.TP
|
.TP
|
||||||
.BI /usr/local/sbin/bgpd
|
.BI /usr/lib/quagga/bgpd
|
||||||
The default location of the
|
The default location of the
|
||||||
.B bgpd
|
.B bgpd
|
||||||
binary.
|
binary.
|
||||||
.TP
|
.TP
|
||||||
.BI /usr/local/etc/bgpd.conf
|
.BI /etc/quagga/bgpd.conf
|
||||||
The default location of the
|
The default location of the
|
||||||
.B bgpd
|
.B bgpd
|
||||||
config file.
|
config file.
|
||||||
|
@ -67,12 +67,12 @@ Specify the user to run as. Default is \fIquagga\fR.
|
|||||||
Print the version and exit.
|
Print the version and exit.
|
||||||
.SH FILES
|
.SH FILES
|
||||||
.TP
|
.TP
|
||||||
.BI /usr/local/sbin/isisd
|
.BI /usr/lib/quagga/isisd
|
||||||
The default location of the
|
The default location of the
|
||||||
.B isisd
|
.B isisd
|
||||||
binary.
|
binary.
|
||||||
.TP
|
.TP
|
||||||
.BI /usr/local/etc/isisd.conf
|
.BI /etc/quagga/isisd.conf
|
||||||
The default location of the
|
The default location of the
|
||||||
.B isisd
|
.B isisd
|
||||||
config file.
|
config file.
|
||||||
|
@ -68,12 +68,12 @@ Specify the user to run as. Default is \fIquagga\fR.
|
|||||||
Print the version and exit.
|
Print the version and exit.
|
||||||
.SH FILES
|
.SH FILES
|
||||||
.TP
|
.TP
|
||||||
.BI /usr/local/sbin/ospf6d
|
.BI /usr/lib/quagga/ospf6d
|
||||||
The default location of the
|
The default location of the
|
||||||
.B ospf6d
|
.B ospf6d
|
||||||
binary.
|
binary.
|
||||||
.TP
|
.TP
|
||||||
.BI /usr/local/etc/ospf6d.conf
|
.BI /etc/quagga/ospf6d.conf
|
||||||
The default location of the
|
The default location of the
|
||||||
.B ospf6d
|
.B ospf6d
|
||||||
config file.
|
config file.
|
||||||
|
@ -70,12 +70,12 @@ Enable OSPF apiserver. Default is disabled.
|
|||||||
Print the version and exit.
|
Print the version and exit.
|
||||||
.SH FILES
|
.SH FILES
|
||||||
.TP
|
.TP
|
||||||
.BI /usr/local/sbin/ospfd
|
.BI /usr/lib/quagga/ospfd
|
||||||
The default location of the
|
The default location of the
|
||||||
.B ospfd
|
.B ospfd
|
||||||
binary.
|
binary.
|
||||||
.TP
|
.TP
|
||||||
.BI /usr/local/etc/ospfd.conf
|
.BI /etc/quagga/ospfd.conf
|
||||||
The default location of the
|
The default location of the
|
||||||
.B ospfd
|
.B ospfd
|
||||||
config file.
|
config file.
|
||||||
|
@ -71,12 +71,12 @@ When the program terminates, retain routes added by \fBripd\fR.
|
|||||||
Print the version and exit.
|
Print the version and exit.
|
||||||
.SH FILES
|
.SH FILES
|
||||||
.TP
|
.TP
|
||||||
.BI /usr/local/sbin/ripd
|
.BI /usr/lib/quagga/ripd
|
||||||
The default location of the
|
The default location of the
|
||||||
.B ripd
|
.B ripd
|
||||||
binary.
|
binary.
|
||||||
.TP
|
.TP
|
||||||
.BI /usr/local/etc/ripd.conf
|
.BI /etc/quagga/ripd.conf
|
||||||
The default location of the
|
The default location of the
|
||||||
.B ripd
|
.B ripd
|
||||||
config file.
|
config file.
|
||||||
|
@ -71,12 +71,12 @@ When the program terminates, retain routes added by \fBripd\fR.
|
|||||||
Print the version and exit.
|
Print the version and exit.
|
||||||
.SH FILES
|
.SH FILES
|
||||||
.TP
|
.TP
|
||||||
.BI /usr/local/sbin/ripngd
|
.BI /usr/lib/quagga/ripngd
|
||||||
The default location of the
|
The default location of the
|
||||||
.B ripngd
|
.B ripngd
|
||||||
binary.
|
binary.
|
||||||
.TP
|
.TP
|
||||||
.BI /usr/local/etc/ripngd.conf
|
.BI /etc/quagga/ripngd.conf
|
||||||
The default location of the
|
The default location of the
|
||||||
.B ripngd
|
.B ripngd
|
||||||
config file.
|
config file.
|
||||||
|
@ -68,12 +68,12 @@ Display a usage message on standard output and exit.
|
|||||||
This should be the name of the pager to use. Default is \fBmore\fR.
|
This should be the name of the pager to use. Default is \fBmore\fR.
|
||||||
.SH FILES
|
.SH FILES
|
||||||
.TP
|
.TP
|
||||||
.BI /usr/local/etc/vtysh.conf
|
.BI /etc/quagga/vtysh.conf
|
||||||
The default location of the
|
The default location of the
|
||||||
.B vtysh
|
.B vtysh
|
||||||
config file.
|
config file.
|
||||||
.TP
|
.TP
|
||||||
.BI /usr/local/etc/Quagga.conf
|
.BI /etc/quagga/Quagga.conf
|
||||||
The default location of the integrated Quagga routing engine config file
|
The default location of the integrated Quagga routing engine config file
|
||||||
if integrated config file is in use (not default).
|
if integrated config file is in use (not default).
|
||||||
.SH WARNING
|
.SH WARNING
|
||||||
|
@ -90,12 +90,12 @@ Note that this affects Linux only.
|
|||||||
Print the version and exit.
|
Print the version and exit.
|
||||||
.SH FILES
|
.SH FILES
|
||||||
.TP
|
.TP
|
||||||
.BI /usr/local/sbin/zebra
|
.BI /usr/lib/quagga/zebra
|
||||||
The default location of the
|
The default location of the
|
||||||
.B zebra
|
.B zebra
|
||||||
binary.
|
binary.
|
||||||
.TP
|
.TP
|
||||||
.BI /usr/local/etc/zebra.conf
|
.BI /etc/quagga/zebra.conf
|
||||||
The default location of the
|
The default location of the
|
||||||
.B zebra
|
.B zebra
|
||||||
config file.
|
config file.
|
||||||
|
@ -2739,7 +2739,6 @@ void
|
|||||||
isis_circuit_init ()
|
isis_circuit_init ()
|
||||||
{
|
{
|
||||||
/* Initialize Zebra interface data structure */
|
/* Initialize Zebra interface data structure */
|
||||||
if_init ();
|
|
||||||
if_add_hook (IF_NEW_HOOK, isis_if_new_hook);
|
if_add_hook (IF_NEW_HOOK, isis_if_new_hook);
|
||||||
if_add_hook (IF_DELETE_HOOK, isis_if_delete_hook);
|
if_add_hook (IF_DELETE_HOOK, isis_if_delete_hook);
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
#include "sigevent.h"
|
#include "sigevent.h"
|
||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "zclient.h"
|
#include "zclient.h"
|
||||||
|
#include "vrf.h"
|
||||||
|
|
||||||
#include "isisd/dict.h"
|
#include "isisd/dict.h"
|
||||||
#include "include-netbsd/iso.h"
|
#include "include-netbsd/iso.h"
|
||||||
@ -335,6 +336,7 @@ main (int argc, char **argv, char **envp)
|
|||||||
vty_init (master);
|
vty_init (master);
|
||||||
memory_init ();
|
memory_init ();
|
||||||
access_list_init();
|
access_list_init();
|
||||||
|
vrf_init ();
|
||||||
isis_init ();
|
isis_init ();
|
||||||
isis_circuit_init ();
|
isis_circuit_init ();
|
||||||
isis_spf_cmds_init ();
|
isis_spf_cmds_init ();
|
||||||
|
@ -14,7 +14,7 @@ libzebra_la_SOURCES = \
|
|||||||
filter.c routemap.c distribute.c stream.c str.c log.c plist.c \
|
filter.c routemap.c distribute.c stream.c str.c log.c plist.c \
|
||||||
zclient.c sockopt.c smux.c agentx.c snmp.c md5.c if_rmap.c keychain.c privs.c \
|
zclient.c sockopt.c smux.c agentx.c snmp.c md5.c if_rmap.c keychain.c privs.c \
|
||||||
sigevent.c pqueue.c jhash.c memtypes.c workqueue.c nexthop.c json.c \
|
sigevent.c pqueue.c jhash.c memtypes.c workqueue.c nexthop.c json.c \
|
||||||
ptm_lib.c csv.c bfd.c
|
ptm_lib.c csv.c bfd.c vrf.c
|
||||||
|
|
||||||
BUILT_SOURCES = memtypes.h route_types.h gitversion.h
|
BUILT_SOURCES = memtypes.h route_types.h gitversion.h
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ pkginclude_HEADERS = \
|
|||||||
plist.h zclient.h sockopt.h smux.h md5.h if_rmap.h keychain.h \
|
plist.h zclient.h sockopt.h smux.h md5.h if_rmap.h keychain.h \
|
||||||
privs.h sigevent.h pqueue.h jhash.h zassert.h memtypes.h \
|
privs.h sigevent.h pqueue.h jhash.h zassert.h memtypes.h \
|
||||||
workqueue.h route_types.h libospf.h nexthop.h json.h \
|
workqueue.h route_types.h libospf.h nexthop.h json.h \
|
||||||
ptm_lib.h csv.h bfd.h
|
ptm_lib.h csv.h bfd.h vrf.h
|
||||||
|
|
||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
regex.c regex-gnu.h \
|
regex.c regex-gnu.h \
|
||||||
|
259
lib/if.c
259
lib/if.c
@ -27,6 +27,7 @@
|
|||||||
#include "vector.h"
|
#include "vector.h"
|
||||||
#include "vty.h"
|
#include "vty.h"
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
|
#include "vrf.h"
|
||||||
#include "if.h"
|
#include "if.h"
|
||||||
#include "sockunion.h"
|
#include "sockunion.h"
|
||||||
#include "prefix.h"
|
#include "prefix.h"
|
||||||
@ -36,7 +37,7 @@
|
|||||||
#include "str.h"
|
#include "str.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
/* Master list of interfaces. */
|
/* List of interfaces in only the default VRF */
|
||||||
struct list *iflist;
|
struct list *iflist;
|
||||||
int ptm_enable = 0;
|
int ptm_enable = 0;
|
||||||
|
|
||||||
@ -45,7 +46,7 @@ struct if_master
|
|||||||
{
|
{
|
||||||
int (*if_new_hook) (struct interface *);
|
int (*if_new_hook) (struct interface *);
|
||||||
int (*if_delete_hook) (struct interface *);
|
int (*if_delete_hook) (struct interface *);
|
||||||
} if_master;
|
} if_master = {0,};
|
||||||
|
|
||||||
/* Compare interface names, returning an integer greater than, equal to, or
|
/* Compare interface names, returning an integer greater than, equal to, or
|
||||||
* less than 0, (following the strcmp convention), according to the
|
* less than 0, (following the strcmp convention), according to the
|
||||||
@ -114,9 +115,10 @@ if_cmp_func (struct interface *ifp1, struct interface *ifp2)
|
|||||||
|
|
||||||
/* Create new interface structure. */
|
/* Create new interface structure. */
|
||||||
struct interface *
|
struct interface *
|
||||||
if_create (const char *name, int namelen)
|
if_create_vrf (const char *name, int namelen, vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
|
struct list *intf_list = vrf_iflist_get (vrf_id);
|
||||||
|
|
||||||
ifp = XCALLOC (MTYPE_IF, sizeof (struct interface));
|
ifp = XCALLOC (MTYPE_IF, sizeof (struct interface));
|
||||||
ifp->ifindex = IFINDEX_INTERNAL;
|
ifp->ifindex = IFINDEX_INTERNAL;
|
||||||
@ -125,11 +127,12 @@ if_create (const char *name, int namelen)
|
|||||||
assert (namelen <= INTERFACE_NAMSIZ); /* Need space for '\0' at end. */
|
assert (namelen <= INTERFACE_NAMSIZ); /* Need space for '\0' at end. */
|
||||||
strncpy (ifp->name, name, namelen);
|
strncpy (ifp->name, name, namelen);
|
||||||
ifp->name[namelen] = '\0';
|
ifp->name[namelen] = '\0';
|
||||||
if (if_lookup_by_name(ifp->name) == NULL)
|
ifp->vrf_id = vrf_id;
|
||||||
listnode_add_sort (iflist, ifp);
|
if (if_lookup_by_name_vrf (ifp->name, vrf_id) == NULL)
|
||||||
|
listnode_add_sort (intf_list, ifp);
|
||||||
else
|
else
|
||||||
zlog_err("if_create(%s): corruption detected -- interface with this "
|
zlog_err("if_create(%s): corruption detected -- interface with this "
|
||||||
"name exists already!", ifp->name);
|
"name exists already in VRF %u!", ifp->name, vrf_id);
|
||||||
ifp->connected = list_new ();
|
ifp->connected = list_new ();
|
||||||
ifp->connected->del = (void (*) (void *)) connected_free;
|
ifp->connected->del = (void (*) (void *)) connected_free;
|
||||||
|
|
||||||
@ -145,6 +148,12 @@ if_create (const char *name, int namelen)
|
|||||||
return ifp;
|
return ifp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct interface *
|
||||||
|
if_create (const char *name, int namelen)
|
||||||
|
{
|
||||||
|
return if_create_vrf (name, namelen, VRF_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
/* Delete interface structure. */
|
/* Delete interface structure. */
|
||||||
void
|
void
|
||||||
if_delete_retain (struct interface *ifp)
|
if_delete_retain (struct interface *ifp)
|
||||||
@ -163,7 +172,7 @@ if_delete_retain (struct interface *ifp)
|
|||||||
void
|
void
|
||||||
if_delete (struct interface *ifp)
|
if_delete (struct interface *ifp)
|
||||||
{
|
{
|
||||||
listnode_delete (iflist, ifp);
|
listnode_delete (vrf_iflist (ifp->vrf_id), ifp);
|
||||||
|
|
||||||
if_delete_retain(ifp);
|
if_delete_retain(ifp);
|
||||||
|
|
||||||
@ -191,12 +200,12 @@ if_add_hook (int type, int (*func)(struct interface *ifp))
|
|||||||
|
|
||||||
/* Interface existance check by index. */
|
/* Interface existance check by index. */
|
||||||
struct interface *
|
struct interface *
|
||||||
if_lookup_by_index (unsigned int index)
|
if_lookup_by_index_vrf (unsigned int index, vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp))
|
for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
|
||||||
{
|
{
|
||||||
if (ifp->ifindex == index)
|
if (ifp->ifindex == index)
|
||||||
return ifp;
|
return ifp;
|
||||||
@ -204,33 +213,51 @@ if_lookup_by_index (unsigned int index)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct interface *
|
||||||
|
if_lookup_by_index (unsigned int index)
|
||||||
|
{
|
||||||
|
return if_lookup_by_index_vrf (index, VRF_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
ifindex2ifname (unsigned int index)
|
ifindex2ifname_vrf (unsigned int index, vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
|
|
||||||
return ((ifp = if_lookup_by_index(index)) != NULL) ?
|
return ((ifp = if_lookup_by_index_vrf (index, vrf_id)) != NULL) ?
|
||||||
ifp->name : "unknown";
|
ifp->name : "unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
ifindex2ifname (unsigned int index)
|
||||||
|
{
|
||||||
|
return ifindex2ifname_vrf (index, VRF_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
ifname2ifindex_vrf (const char *name, vrf_id_t vrf_id)
|
||||||
|
{
|
||||||
|
struct interface *ifp;
|
||||||
|
|
||||||
|
return ((ifp = if_lookup_by_name_vrf (name, vrf_id)) != NULL) ? ifp->ifindex
|
||||||
|
: IFINDEX_INTERNAL;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
ifname2ifindex (const char *name)
|
ifname2ifindex (const char *name)
|
||||||
{
|
{
|
||||||
struct interface *ifp;
|
return ifname2ifindex_vrf (name, VRF_DEFAULT);
|
||||||
|
|
||||||
return ((ifp = if_lookup_by_name(name)) != NULL) ? ifp->ifindex
|
|
||||||
: IFINDEX_INTERNAL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Interface existance check by interface name. */
|
/* Interface existance check by interface name. */
|
||||||
struct interface *
|
struct interface *
|
||||||
if_lookup_by_name (const char *name)
|
if_lookup_by_name_vrf (const char *name, vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
|
|
||||||
if (name)
|
if (name)
|
||||||
for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
|
for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
|
||||||
{
|
{
|
||||||
if (strcmp(name, ifp->name) == 0)
|
if (strcmp(name, ifp->name) == 0)
|
||||||
return ifp;
|
return ifp;
|
||||||
@ -239,7 +266,13 @@ if_lookup_by_name (const char *name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct interface *
|
struct interface *
|
||||||
if_lookup_by_name_len(const char *name, size_t namelen)
|
if_lookup_by_name (const char *name)
|
||||||
|
{
|
||||||
|
return if_lookup_by_name_vrf (name, VRF_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct interface *
|
||||||
|
if_lookup_by_name_len_vrf (const char *name, size_t namelen, vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
@ -247,7 +280,7 @@ if_lookup_by_name_len(const char *name, size_t namelen)
|
|||||||
if (namelen > INTERFACE_NAMSIZ)
|
if (namelen > INTERFACE_NAMSIZ)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
|
for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
|
||||||
{
|
{
|
||||||
if (!memcmp(name, ifp->name, namelen) && (ifp->name[namelen] == '\0'))
|
if (!memcmp(name, ifp->name, namelen) && (ifp->name[namelen] == '\0'))
|
||||||
return ifp;
|
return ifp;
|
||||||
@ -255,9 +288,15 @@ if_lookup_by_name_len(const char *name, size_t namelen)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct interface *
|
||||||
|
if_lookup_by_name_len(const char *name, size_t namelen)
|
||||||
|
{
|
||||||
|
return if_lookup_by_name_len_vrf (name, namelen, VRF_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
/* Lookup interface by IPv4 address. */
|
/* Lookup interface by IPv4 address. */
|
||||||
struct interface *
|
struct interface *
|
||||||
if_lookup_exact_address (void *src, int family)
|
if_lookup_exact_address_vrf (void *src, int family, vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
struct listnode *cnode;
|
struct listnode *cnode;
|
||||||
@ -265,7 +304,7 @@ if_lookup_exact_address (void *src, int family)
|
|||||||
struct prefix *p;
|
struct prefix *p;
|
||||||
struct connected *c;
|
struct connected *c;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
|
for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
|
||||||
{
|
{
|
||||||
for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, c))
|
for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, c))
|
||||||
{
|
{
|
||||||
@ -289,9 +328,15 @@ if_lookup_exact_address (void *src, int family)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct interface *
|
||||||
|
if_lookup_exact_address (void *src, int family)
|
||||||
|
{
|
||||||
|
return if_lookup_exact_address_vrf (src, family, VRF_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
/* Lookup interface by IPv4 address. */
|
/* Lookup interface by IPv4 address. */
|
||||||
struct interface *
|
struct interface *
|
||||||
if_lookup_address (void *matchaddr, int family)
|
if_lookup_address_vrf (void *matchaddr, int family, vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
struct prefix addr;
|
struct prefix addr;
|
||||||
@ -316,7 +361,7 @@ if_lookup_address (void *matchaddr, int family)
|
|||||||
|
|
||||||
match = NULL;
|
match = NULL;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
|
for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
|
||||||
{
|
{
|
||||||
for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, c))
|
for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, c))
|
||||||
{
|
{
|
||||||
@ -332,6 +377,12 @@ if_lookup_address (void *matchaddr, int family)
|
|||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct interface *
|
||||||
|
if_lookup_address (void *matchaddr, int family)
|
||||||
|
{
|
||||||
|
return if_lookup_address_vrf (matchaddr, family, VRF_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
/* Lookup anchor interface by IPv4 address. */
|
/* Lookup anchor interface by IPv4 address. */
|
||||||
struct connected *
|
struct connected *
|
||||||
if_anchor_lookup_by_address (struct in_addr src)
|
if_anchor_lookup_by_address (struct in_addr src)
|
||||||
@ -364,14 +415,14 @@ if_anchor_lookup_by_address (struct in_addr src)
|
|||||||
|
|
||||||
/* Lookup interface by prefix */
|
/* Lookup interface by prefix */
|
||||||
struct interface *
|
struct interface *
|
||||||
if_lookup_prefix (struct prefix *prefix)
|
if_lookup_prefix_vrf (struct prefix *prefix, vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
struct listnode *cnode;
|
struct listnode *cnode;
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
struct connected *c;
|
struct connected *c;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
|
for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
|
||||||
{
|
{
|
||||||
for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, c))
|
for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, c))
|
||||||
{
|
{
|
||||||
@ -384,24 +435,42 @@ if_lookup_prefix (struct prefix *prefix)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct interface *
|
||||||
|
if_lookup_prefix (struct prefix *prefix)
|
||||||
|
{
|
||||||
|
return if_lookup_prefix_vrf (prefix, VRF_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
/* Get interface by name if given name interface doesn't exist create
|
/* Get interface by name if given name interface doesn't exist create
|
||||||
one. */
|
one. */
|
||||||
struct interface *
|
struct interface *
|
||||||
if_get_by_name (const char *name)
|
if_get_by_name_vrf (const char *name, vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
|
|
||||||
return ((ifp = if_lookup_by_name(name)) != NULL) ? ifp :
|
return ((ifp = if_lookup_by_name_vrf (name, vrf_id)) != NULL) ? ifp :
|
||||||
if_create(name, strlen(name));
|
if_create_vrf (name, strlen(name), vrf_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct interface *
|
struct interface *
|
||||||
if_get_by_name_len(const char *name, size_t namelen)
|
if_get_by_name (const char *name)
|
||||||
|
{
|
||||||
|
return if_get_by_name_vrf (name, VRF_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct interface *
|
||||||
|
if_get_by_name_len_vrf (const char *name, size_t namelen, vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
|
|
||||||
return ((ifp = if_lookup_by_name_len(name, namelen)) != NULL) ? ifp :
|
return ((ifp = if_lookup_by_name_len_vrf (name, namelen, vrf_id)) != NULL) ? \
|
||||||
if_create(name, namelen);
|
ifp : if_create_vrf (name, namelen, vrf_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct interface *
|
||||||
|
if_get_by_name_len (const char *name, size_t namelen)
|
||||||
|
{
|
||||||
|
return if_get_by_name_len_vrf (name, namelen, VRF_DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Does interface up ? */
|
/* Does interface up ? */
|
||||||
@ -521,12 +590,12 @@ if_flag_dump (unsigned long flag)
|
|||||||
static void
|
static void
|
||||||
if_dump (const struct interface *ifp)
|
if_dump (const struct interface *ifp)
|
||||||
{
|
{
|
||||||
zlog_info ("Interface %s index %d metric %d mtu %d "
|
zlog_info ("Interface %s vrf %u index %d metric %d mtu %d "
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
"mtu6 %d "
|
"mtu6 %d "
|
||||||
#endif /* HAVE_IPV6 */
|
#endif /* HAVE_IPV6 */
|
||||||
"%s",
|
"%s",
|
||||||
ifp->name, ifp->ifindex, ifp->metric, ifp->mtu,
|
ifp->name, ifp->vrf_id, ifp->ifindex, ifp->metric, ifp->mtu,
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
ifp->mtu6,
|
ifp->mtu6,
|
||||||
#endif /* HAVE_IPV6 */
|
#endif /* HAVE_IPV6 */
|
||||||
@ -537,11 +606,15 @@ if_dump (const struct interface *ifp)
|
|||||||
void
|
void
|
||||||
if_dump_all (void)
|
if_dump_all (void)
|
||||||
{
|
{
|
||||||
|
struct list *intf_list;
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
void *p;
|
void *p;
|
||||||
|
vrf_iter_t iter;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO (iflist, node, p))
|
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||||
if_dump (p);
|
if ((intf_list = vrf_iter2iflist (iter)) != NULL)
|
||||||
|
for (ALL_LIST_ELEMENTS_RO (intf_list, node, p))
|
||||||
|
if_dump (p);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUN (interface_desc,
|
DEFUN (interface_desc,
|
||||||
@ -601,12 +674,12 @@ DEFUN (no_interface_desc,
|
|||||||
* - no idea, just get the name in its entirety.
|
* - no idea, just get the name in its entirety.
|
||||||
*/
|
*/
|
||||||
static struct interface *
|
static struct interface *
|
||||||
if_sunwzebra_get (const char *name, size_t nlen)
|
if_sunwzebra_get (const char *name, size_t nlen, vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
size_t seppos = 0;
|
size_t seppos = 0;
|
||||||
|
|
||||||
if ( (ifp = if_lookup_by_name_len(name, nlen)) != NULL)
|
if ( (ifp = if_lookup_by_name_len_vrf (name, nlen, vrf_id)) != NULL)
|
||||||
return ifp;
|
return ifp;
|
||||||
|
|
||||||
/* hunt the primary interface name... */
|
/* hunt the primary interface name... */
|
||||||
@ -615,9 +688,9 @@ if_sunwzebra_get (const char *name, size_t nlen)
|
|||||||
|
|
||||||
/* Wont catch seperator as last char, e.g. 'foo0:' but thats invalid */
|
/* Wont catch seperator as last char, e.g. 'foo0:' but thats invalid */
|
||||||
if (seppos < nlen)
|
if (seppos < nlen)
|
||||||
return if_get_by_name_len (name, seppos);
|
return if_get_by_name_len_vrf (name, seppos, vrf_id);
|
||||||
else
|
else
|
||||||
return if_get_by_name_len (name, nlen);
|
return if_get_by_name_len_vrf (name, nlen, vrf_id);
|
||||||
}
|
}
|
||||||
#endif /* SUNOS_5 */
|
#endif /* SUNOS_5 */
|
||||||
|
|
||||||
@ -629,6 +702,7 @@ DEFUN (interface,
|
|||||||
{
|
{
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
size_t sl;
|
size_t sl;
|
||||||
|
vrf_id_t vrf_id = VRF_DEFAULT;
|
||||||
|
|
||||||
if ((sl = strlen(argv[0])) > INTERFACE_NAMSIZ)
|
if ((sl = strlen(argv[0])) > INTERFACE_NAMSIZ)
|
||||||
{
|
{
|
||||||
@ -638,10 +712,13 @@ DEFUN (interface,
|
|||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (argc > 1)
|
||||||
|
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
|
||||||
|
|
||||||
#ifdef SUNOS_5
|
#ifdef SUNOS_5
|
||||||
ifp = if_sunwzebra_get (argv[0], sl);
|
ifp = if_sunwzebra_get (argv[0], sl, vrf_id);
|
||||||
#else
|
#else
|
||||||
ifp = if_get_by_name_len(argv[0], sl);
|
ifp = if_get_by_name_len_vrf (argv[0], sl, vrf_id);
|
||||||
#endif /* SUNOS_5 */
|
#endif /* SUNOS_5 */
|
||||||
|
|
||||||
vty->index = ifp;
|
vty->index = ifp;
|
||||||
@ -650,6 +727,13 @@ DEFUN (interface,
|
|||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ALIAS (interface,
|
||||||
|
interface_vrf_cmd,
|
||||||
|
"interface IFNAME " VRF_CMD_STR,
|
||||||
|
"Select an interface to configure\n"
|
||||||
|
"Interface's name\n"
|
||||||
|
VRF_CMD_HELP_STR)
|
||||||
|
|
||||||
DEFUN_NOSH (no_interface,
|
DEFUN_NOSH (no_interface,
|
||||||
no_interface_cmd,
|
no_interface_cmd,
|
||||||
"no interface IFNAME",
|
"no interface IFNAME",
|
||||||
@ -659,8 +743,12 @@ DEFUN_NOSH (no_interface,
|
|||||||
{
|
{
|
||||||
// deleting interface
|
// deleting interface
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
|
vrf_id_t vrf_id = VRF_DEFAULT;
|
||||||
|
|
||||||
ifp = if_lookup_by_name (argv[0]);
|
if (argc > 1)
|
||||||
|
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
|
||||||
|
|
||||||
|
ifp = if_lookup_by_name_vrf (argv[0], vrf_id);
|
||||||
|
|
||||||
if (ifp == NULL)
|
if (ifp == NULL)
|
||||||
{
|
{
|
||||||
@ -680,6 +768,14 @@ DEFUN_NOSH (no_interface,
|
|||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ALIAS (no_interface,
|
||||||
|
no_interface_vrf_cmd,
|
||||||
|
"no interface IFNAME " VRF_CMD_STR,
|
||||||
|
NO_STR
|
||||||
|
"Delete a pseudo interface's configuration\n"
|
||||||
|
"Interface's name\n"
|
||||||
|
VRF_CMD_HELP_STR)
|
||||||
|
|
||||||
/* For debug purpose. */
|
/* For debug purpose. */
|
||||||
DEFUN (show_address,
|
DEFUN (show_address,
|
||||||
show_address_cmd,
|
show_address_cmd,
|
||||||
@ -692,8 +788,12 @@ DEFUN (show_address,
|
|||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
struct connected *ifc;
|
struct connected *ifc;
|
||||||
struct prefix *p;
|
struct prefix *p;
|
||||||
|
vrf_id_t vrf_id = VRF_DEFAULT;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
|
if (argc > 0)
|
||||||
|
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
|
||||||
|
|
||||||
|
for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
|
||||||
{
|
{
|
||||||
for (ALL_LIST_ELEMENTS_RO (ifp->connected, node2, ifc))
|
for (ALL_LIST_ELEMENTS_RO (ifp->connected, node2, ifc))
|
||||||
{
|
{
|
||||||
@ -707,6 +807,52 @@ DEFUN (show_address,
|
|||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ALIAS (show_address,
|
||||||
|
show_address_vrf_cmd,
|
||||||
|
"show address " VRF_CMD_STR,
|
||||||
|
SHOW_STR
|
||||||
|
"address\n"
|
||||||
|
VRF_CMD_HELP_STR)
|
||||||
|
|
||||||
|
DEFUN (show_address_vrf_all,
|
||||||
|
show_address_vrf_all_cmd,
|
||||||
|
"show address " VRF_ALL_CMD_STR,
|
||||||
|
SHOW_STR
|
||||||
|
"address\n"
|
||||||
|
VRF_ALL_CMD_HELP_STR)
|
||||||
|
{
|
||||||
|
struct list *intf_list;
|
||||||
|
struct listnode *node;
|
||||||
|
struct listnode *node2;
|
||||||
|
struct interface *ifp;
|
||||||
|
struct connected *ifc;
|
||||||
|
struct prefix *p;
|
||||||
|
vrf_iter_t iter;
|
||||||
|
|
||||||
|
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||||
|
{
|
||||||
|
intf_list = vrf_iter2iflist (iter);
|
||||||
|
if (!intf_list || !listcount (intf_list))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
vty_out (vty, "%sVRF %u%s%s", VTY_NEWLINE, vrf_iter2id (iter),
|
||||||
|
VTY_NEWLINE, VTY_NEWLINE);
|
||||||
|
|
||||||
|
for (ALL_LIST_ELEMENTS_RO (intf_list, node, ifp))
|
||||||
|
{
|
||||||
|
for (ALL_LIST_ELEMENTS_RO (ifp->connected, node2, ifc))
|
||||||
|
{
|
||||||
|
p = ifc->address;
|
||||||
|
|
||||||
|
if (p->family == AF_INET)
|
||||||
|
vty_out (vty, "%s/%d%s", inet_ntoa (p->u.prefix4), p->prefixlen,
|
||||||
|
VTY_NEWLINE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/* Allocate connected structure. */
|
/* Allocate connected structure. */
|
||||||
struct connected *
|
struct connected *
|
||||||
connected_new (void)
|
connected_new (void)
|
||||||
@ -773,8 +919,8 @@ connected_log (struct connected *connected, char *str)
|
|||||||
ifp = connected->ifp;
|
ifp = connected->ifp;
|
||||||
p = connected->address;
|
p = connected->address;
|
||||||
|
|
||||||
snprintf (logbuf, BUFSIZ, "%s interface %s %s %s/%d ",
|
snprintf (logbuf, BUFSIZ, "%s interface %s vrf %u %s %s/%d ",
|
||||||
str, ifp->name, prefix_family_str (p),
|
str, ifp->name, ifp->vrf_id, prefix_family_str (p),
|
||||||
inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
|
inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
|
||||||
p->prefixlen);
|
p->prefixlen);
|
||||||
|
|
||||||
@ -1004,35 +1150,36 @@ ifaddr_ipv4_lookup (struct in_addr *addr, unsigned int ifindex)
|
|||||||
|
|
||||||
/* Initialize interface list. */
|
/* Initialize interface list. */
|
||||||
void
|
void
|
||||||
if_init (void)
|
if_init (vrf_id_t vrf_id, struct list **intf_list)
|
||||||
{
|
{
|
||||||
iflist = list_new ();
|
*intf_list = list_new ();
|
||||||
#if 0
|
#if 0
|
||||||
ifaddr_ipv4_table = route_table_init ();
|
ifaddr_ipv4_table = route_table_init ();
|
||||||
#endif /* ifaddr_ipv4_table */
|
#endif /* ifaddr_ipv4_table */
|
||||||
|
|
||||||
if (iflist) {
|
(*intf_list)->cmp = (int (*)(void *, void *))if_cmp_func;
|
||||||
iflist->cmp = (int (*)(void *, void *))if_cmp_func;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset (&if_master, 0, sizeof if_master);
|
if (vrf_id == VRF_DEFAULT)
|
||||||
|
iflist = *intf_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
if_terminate (void)
|
if_terminate (vrf_id_t vrf_id, struct list **intf_list)
|
||||||
{
|
{
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
|
|
||||||
ifp = listnode_head (iflist);
|
ifp = listnode_head (*intf_list);
|
||||||
if (ifp == NULL)
|
if (ifp == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if_delete (ifp);
|
if_delete (ifp);
|
||||||
}
|
}
|
||||||
|
|
||||||
list_delete (iflist);
|
list_delete (*intf_list);
|
||||||
iflist = NULL;
|
*intf_list = NULL;
|
||||||
|
|
||||||
|
if (vrf_id == VRF_DEFAULT)
|
||||||
|
iflist = NULL;
|
||||||
}
|
}
|
||||||
|
37
lib/if.h
37
lib/if.h
@ -145,6 +145,8 @@ struct interface
|
|||||||
#ifdef HAVE_NET_RT_IFLIST
|
#ifdef HAVE_NET_RT_IFLIST
|
||||||
struct if_data stats;
|
struct if_data stats;
|
||||||
#endif /* HAVE_NET_RT_IFLIST */
|
#endif /* HAVE_NET_RT_IFLIST */
|
||||||
|
|
||||||
|
vrf_id_t vrf_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Connected address structure. */
|
/* Connected address structure. */
|
||||||
@ -271,17 +273,38 @@ extern struct interface *if_lookup_address (void *matchaddr, int family);
|
|||||||
extern struct interface *if_lookup_prefix (struct prefix *prefix);
|
extern struct interface *if_lookup_prefix (struct prefix *prefix);
|
||||||
extern struct connected *if_anchor_lookup_by_address (struct in_addr src);
|
extern struct connected *if_anchor_lookup_by_address (struct in_addr src);
|
||||||
|
|
||||||
|
extern struct interface *if_create_vrf (const char *name, int namelen,
|
||||||
|
vrf_id_t vrf_id);
|
||||||
|
extern struct interface *if_lookup_by_index_vrf (unsigned int,
|
||||||
|
vrf_id_t vrf_id);
|
||||||
|
extern struct interface *if_lookup_exact_address_vrf (void *matchaddr, int family,
|
||||||
|
vrf_id_t vrf_id);
|
||||||
|
extern struct interface *if_lookup_address_vrf (void *matchaddr, int family,
|
||||||
|
vrf_id_t vrf_id);
|
||||||
|
extern struct interface *if_lookup_prefix_vrf (struct prefix *prefix,
|
||||||
|
vrf_id_t vrf_id);
|
||||||
|
|
||||||
/* These 2 functions are to be used when the ifname argument is terminated
|
/* These 2 functions are to be used when the ifname argument is terminated
|
||||||
by a '\0' character: */
|
by a '\0' character: */
|
||||||
extern struct interface *if_lookup_by_name (const char *ifname);
|
extern struct interface *if_lookup_by_name (const char *ifname);
|
||||||
extern struct interface *if_get_by_name (const char *ifname);
|
extern struct interface *if_get_by_name (const char *ifname);
|
||||||
|
|
||||||
|
extern struct interface *if_lookup_by_name_vrf (const char *ifname,
|
||||||
|
vrf_id_t vrf_id);
|
||||||
|
extern struct interface *if_get_by_name_vrf (const char *ifname,
|
||||||
|
vrf_id_t vrf_id);
|
||||||
|
|
||||||
/* For these 2 functions, the namelen argument should be the precise length
|
/* For these 2 functions, the namelen argument should be the precise length
|
||||||
of the ifname string (not counting any optional trailing '\0' character).
|
of the ifname string (not counting any optional trailing '\0' character).
|
||||||
In most cases, strnlen should be used to calculate the namelen value. */
|
In most cases, strnlen should be used to calculate the namelen value. */
|
||||||
extern struct interface *if_lookup_by_name_len(const char *ifname,
|
extern struct interface *if_lookup_by_name_len(const char *ifname,
|
||||||
size_t namelen);
|
size_t namelen);
|
||||||
extern struct interface *if_get_by_name_len(const char *ifname, size_t namelen);
|
extern struct interface *if_get_by_name_len(const char *ifname,size_t namelen);
|
||||||
|
|
||||||
|
extern struct interface *if_lookup_by_name_len_vrf(const char *ifname,
|
||||||
|
size_t namelen, vrf_id_t vrf_id);
|
||||||
|
extern struct interface *if_get_by_name_len_vrf(const char *ifname,
|
||||||
|
size_t namelen, vrf_id_t vrf_id);
|
||||||
|
|
||||||
|
|
||||||
/* Delete the interface, but do not free the structure, and leave it in the
|
/* Delete the interface, but do not free the structure, and leave it in the
|
||||||
@ -302,8 +325,8 @@ extern int if_is_broadcast (struct interface *);
|
|||||||
extern int if_is_pointopoint (struct interface *);
|
extern int if_is_pointopoint (struct interface *);
|
||||||
extern int if_is_multicast (struct interface *);
|
extern int if_is_multicast (struct interface *);
|
||||||
extern void if_add_hook (int, int (*)(struct interface *));
|
extern void if_add_hook (int, int (*)(struct interface *));
|
||||||
extern void if_init (void);
|
extern void if_init (vrf_id_t, struct list **);
|
||||||
extern void if_terminate (void);
|
extern void if_terminate (vrf_id_t, struct list **);
|
||||||
extern void if_dump_all (void);
|
extern void if_dump_all (void);
|
||||||
extern const char *if_flag_dump(unsigned long);
|
extern const char *if_flag_dump(unsigned long);
|
||||||
|
|
||||||
@ -311,11 +334,13 @@ extern const char *if_flag_dump(unsigned long);
|
|||||||
ifindex2ifname uses internal interface info, whereas if_indextoname must
|
ifindex2ifname uses internal interface info, whereas if_indextoname must
|
||||||
make a system call. */
|
make a system call. */
|
||||||
extern const char *ifindex2ifname (unsigned int);
|
extern const char *ifindex2ifname (unsigned int);
|
||||||
|
extern const char *ifindex2ifname_vrf (unsigned int, vrf_id_t vrf_id);
|
||||||
|
|
||||||
/* Please use ifname2ifindex instead of if_nametoindex where possible;
|
/* Please use ifname2ifindex instead of if_nametoindex where possible;
|
||||||
ifname2ifindex uses internal interface info, whereas if_nametoindex must
|
ifname2ifindex uses internal interface info, whereas if_nametoindex must
|
||||||
make a system call. */
|
make a system call. */
|
||||||
extern unsigned int ifname2ifindex(const char *ifname);
|
extern unsigned int ifname2ifindex(const char *ifname);
|
||||||
|
extern unsigned int ifname2ifindex_vrf(const char *ifname, vrf_id_t vrf_id);
|
||||||
|
|
||||||
/* Connected address functions. */
|
/* Connected address functions. */
|
||||||
extern struct connected *connected_new (void);
|
extern struct connected *connected_new (void);
|
||||||
@ -345,8 +370,12 @@ extern struct cmd_element interface_desc_cmd;
|
|||||||
extern struct cmd_element no_interface_desc_cmd;
|
extern struct cmd_element no_interface_desc_cmd;
|
||||||
extern struct cmd_element interface_cmd;
|
extern struct cmd_element interface_cmd;
|
||||||
extern struct cmd_element no_interface_cmd;
|
extern struct cmd_element no_interface_cmd;
|
||||||
|
extern struct cmd_element interface_vrf_cmd;
|
||||||
|
extern struct cmd_element no_interface_vrf_cmd;
|
||||||
extern struct cmd_element interface_pseudo_cmd;
|
extern struct cmd_element interface_pseudo_cmd;
|
||||||
extern struct cmd_element no_interface_pseudo_cmd;
|
extern struct cmd_element no_interface_pseudo_cmd;
|
||||||
extern struct cmd_element show_address_cmd;
|
extern struct cmd_element show_address_cmd;
|
||||||
|
extern struct cmd_element show_address_vrf_cmd;
|
||||||
|
extern struct cmd_element show_address_vrf_all_cmd;
|
||||||
|
|
||||||
#endif /* _ZEBRA_IF_H */
|
#endif /* _ZEBRA_IF_H */
|
||||||
|
43
lib/memory.c
43
lib/memory.c
@ -437,41 +437,28 @@ memory_init (void)
|
|||||||
const char *
|
const char *
|
||||||
mtype_memstr (char *buf, size_t len, unsigned long bytes)
|
mtype_memstr (char *buf, size_t len, unsigned long bytes)
|
||||||
{
|
{
|
||||||
unsigned int t, g, m, k;
|
unsigned int m, k;
|
||||||
|
|
||||||
/* easy cases */
|
/* easy cases */
|
||||||
if (!bytes)
|
if (!bytes)
|
||||||
return "0 bytes";
|
return "0 bytes";
|
||||||
if (bytes == 1)
|
if (bytes == 1)
|
||||||
return "1 byte";
|
return "1 byte";
|
||||||
|
|
||||||
if (sizeof (unsigned long) >= 8)
|
/*
|
||||||
/* Hacked to make it not warn on ILP32 machines
|
* When we pass the 2gb barrier mallinfo() can no longer report
|
||||||
* Shift will always be 40 at runtime. See below too */
|
* correct data so it just does something odd...
|
||||||
t = bytes >> (sizeof (unsigned long) >= 8 ? 40 : 0);
|
* Reporting like Terrabytes of data. Which makes users...
|
||||||
else
|
* edgy.. yes edgy that's the term for it.
|
||||||
t = 0;
|
* So let's just give up gracefully
|
||||||
g = bytes >> 30;
|
*/
|
||||||
|
if (bytes > 0x7fffffff)
|
||||||
|
return "> 2GB";
|
||||||
|
|
||||||
m = bytes >> 20;
|
m = bytes >> 20;
|
||||||
k = bytes >> 10;
|
k = bytes >> 10;
|
||||||
|
|
||||||
if (t > 10)
|
if (m > 10)
|
||||||
{
|
|
||||||
/* The shift will always be 39 at runtime.
|
|
||||||
* Just hacked to make it not warn on 'smaller' machines.
|
|
||||||
* Static compiler analysis should mean no extra code
|
|
||||||
*/
|
|
||||||
if (bytes & (1UL << (sizeof (unsigned long) >= 8 ? 39 : 0)))
|
|
||||||
t++;
|
|
||||||
snprintf (buf, len, "%4d TiB", t);
|
|
||||||
}
|
|
||||||
else if (g > 10)
|
|
||||||
{
|
|
||||||
if (bytes & (1 << 29))
|
|
||||||
g++;
|
|
||||||
snprintf (buf, len, "%d GiB", g);
|
|
||||||
}
|
|
||||||
else if (m > 10)
|
|
||||||
{
|
{
|
||||||
if (bytes & (1 << 19))
|
if (bytes & (1 << 19))
|
||||||
m++;
|
m++;
|
||||||
|
@ -73,14 +73,15 @@ struct memory_list memory_list_lib[] =
|
|||||||
{ MTYPE_PQUEUE_DATA, "Priority queue data" },
|
{ MTYPE_PQUEUE_DATA, "Priority queue data" },
|
||||||
{ MTYPE_HOST, "Host config" },
|
{ MTYPE_HOST, "Host config" },
|
||||||
{ MTYPE_BFD_INFO, "BFD info" },
|
{ MTYPE_BFD_INFO, "BFD info" },
|
||||||
|
{ MTYPE_VRF, "VRF" },
|
||||||
|
{ MTYPE_VRF_NAME, "VRF name" },
|
||||||
{ -1, NULL },
|
{ -1, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
struct memory_list memory_list_zebra[] =
|
struct memory_list memory_list_zebra[] =
|
||||||
{
|
{
|
||||||
{ MTYPE_RTADV_PREFIX, "Router Advertisement Prefix" },
|
{ MTYPE_RTADV_PREFIX, "Router Advertisement Prefix" },
|
||||||
{ MTYPE_VRF, "VRF" },
|
{ MTYPE_ZEBRA_VRF, "ZEBRA VRF" },
|
||||||
{ MTYPE_VRF_NAME, "VRF name" },
|
|
||||||
{ MTYPE_NEXTHOP, "Nexthop" },
|
{ MTYPE_NEXTHOP, "Nexthop" },
|
||||||
{ MTYPE_RIB, "RIB" },
|
{ MTYPE_RIB, "RIB" },
|
||||||
{ MTYPE_RIB_QUEUE, "RIB process work queue" },
|
{ MTYPE_RIB_QUEUE, "RIB process work queue" },
|
||||||
@ -88,6 +89,7 @@ struct memory_list memory_list_zebra[] =
|
|||||||
{ MTYPE_RIB_DEST, "RIB destination" },
|
{ MTYPE_RIB_DEST, "RIB destination" },
|
||||||
{ MTYPE_RIB_TABLE_INFO, "RIB table info" },
|
{ MTYPE_RIB_TABLE_INFO, "RIB table info" },
|
||||||
{ MTYPE_RNH, "Nexthop tracking object" },
|
{ MTYPE_RNH, "Nexthop tracking object" },
|
||||||
|
{ MTYPE_NETLINK_NAME, "Netlink name" },
|
||||||
{ -1, NULL },
|
{ -1, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -766,14 +766,15 @@ str2prefix (const char *str, struct prefix *p)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
const char *
|
||||||
prefix2str (const struct prefix *p, char *str, int size)
|
prefix2str (union prefix46constptr pu, char *str, int size)
|
||||||
{
|
{
|
||||||
|
const struct prefix *p = pu.p;
|
||||||
char buf[BUFSIZ];
|
char buf[BUFSIZ];
|
||||||
|
|
||||||
inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ);
|
inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ);
|
||||||
snprintf (str, size, "%s/%d", buf, p->prefixlen);
|
snprintf (str, size, "%s/%d", buf, p->prefixlen);
|
||||||
return 0;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct prefix *
|
struct prefix *
|
||||||
|
@ -179,7 +179,7 @@ extern void prefix_free (struct prefix *);
|
|||||||
extern const char *prefix_family_str (const struct prefix *);
|
extern const char *prefix_family_str (const struct prefix *);
|
||||||
extern int prefix_blen (const struct prefix *);
|
extern int prefix_blen (const struct prefix *);
|
||||||
extern int str2prefix (const char *, struct prefix *);
|
extern int str2prefix (const char *, struct prefix *);
|
||||||
extern int prefix2str (const struct prefix *, char *, int);
|
extern const char *prefix2str (union prefix46constptr, char *, int);
|
||||||
extern int prefix_match (const struct prefix *, const struct prefix *);
|
extern int prefix_match (const struct prefix *, const struct prefix *);
|
||||||
extern int prefix_same (const struct prefix *, const struct prefix *);
|
extern int prefix_same (const struct prefix *, const struct prefix *);
|
||||||
extern int prefix_cmp (const struct prefix *, const struct prefix *);
|
extern int prefix_cmp (const struct prefix *, const struct prefix *);
|
||||||
|
@ -66,6 +66,38 @@ struct route_map_list
|
|||||||
|
|
||||||
/* Master list of route map. */
|
/* Master list of route map. */
|
||||||
static struct route_map_list route_map_master = { NULL, NULL, NULL, NULL, NULL };
|
static struct route_map_list route_map_master = { NULL, NULL, NULL, NULL, NULL };
|
||||||
|
struct hash *route_map_master_hash = NULL;
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
route_map_hash_key_make (void *p)
|
||||||
|
{
|
||||||
|
const struct route_map *map = p;
|
||||||
|
return string_hash_make (map->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
route_map_hash_cmp(const void *p1, const void *p2)
|
||||||
|
{
|
||||||
|
const struct route_map *map1 = p1;
|
||||||
|
const struct route_map *map2 = p2;
|
||||||
|
|
||||||
|
if (map1->deleted == map2->deleted)
|
||||||
|
{
|
||||||
|
if (map1->name && map2->name)
|
||||||
|
{
|
||||||
|
if (!strcmp (map1->name, map2->name))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!map1->name && !map2->name)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
enum route_map_upd8_type
|
enum route_map_upd8_type
|
||||||
{
|
{
|
||||||
@ -127,7 +159,10 @@ route_map_add (const char *name)
|
|||||||
|
|
||||||
map = route_map_new (name);
|
map = route_map_new (name);
|
||||||
list = &route_map_master;
|
list = &route_map_master;
|
||||||
|
|
||||||
|
/* Add map to the hash */
|
||||||
|
hash_get(route_map_master_hash, map, hash_alloc_intern);
|
||||||
|
|
||||||
map->next = NULL;
|
map->next = NULL;
|
||||||
map->prev = list->tail;
|
map->prev = list->tail;
|
||||||
if (list->tail)
|
if (list->tail)
|
||||||
@ -172,6 +207,7 @@ route_map_free_map (struct route_map *map)
|
|||||||
else
|
else
|
||||||
list->head = map->next;
|
list->head = map->next;
|
||||||
|
|
||||||
|
hash_release(route_map_master_hash, map);
|
||||||
XFREE (MTYPE_ROUTE_MAP_NAME, map->name);
|
XFREE (MTYPE_ROUTE_MAP_NAME, map->name);
|
||||||
XFREE (MTYPE_ROUTE_MAP, map);
|
XFREE (MTYPE_ROUTE_MAP, map);
|
||||||
}
|
}
|
||||||
@ -211,14 +247,17 @@ struct route_map *
|
|||||||
route_map_lookup_by_name (const char *name)
|
route_map_lookup_by_name (const char *name)
|
||||||
{
|
{
|
||||||
struct route_map *map;
|
struct route_map *map;
|
||||||
|
struct route_map tmp_map;
|
||||||
|
|
||||||
if (!name)
|
if (!name)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
for (map = route_map_master.head; map; map = map->next)
|
// map.deleted is 0 via memset
|
||||||
if ((strcmp (map->name, name) == 0) && (!map->deleted))
|
memset(&tmp_map, 0, sizeof(struct route_map));
|
||||||
return map;
|
tmp_map.name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, name);
|
||||||
return NULL;
|
map = hash_lookup(route_map_master_hash, &tmp_map);
|
||||||
|
XFREE(MTYPE_ROUTE_MAP_NAME, tmp_map.name);
|
||||||
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -226,17 +265,30 @@ route_map_mark_updated (const char *name, int del_later)
|
|||||||
{
|
{
|
||||||
struct route_map *map;
|
struct route_map *map;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
struct route_map tmp_map;
|
||||||
|
|
||||||
/* We need to do this walk manually instead of calling lookup_by_name()
|
if (!name)
|
||||||
* because the lookup function doesn't return route maps marked as
|
return (ret);
|
||||||
* deleted.
|
|
||||||
|
map = route_map_lookup_by_name(name);
|
||||||
|
|
||||||
|
/* If we did not find the routemap with deleted=0 try again
|
||||||
|
* with deleted=1
|
||||||
*/
|
*/
|
||||||
for (map = route_map_master.head; map; map = map->next)
|
if (!map)
|
||||||
if (strcmp (map->name, name) == 0)
|
{
|
||||||
{
|
memset(&tmp_map, 0, sizeof(struct route_map));
|
||||||
map->to_be_processed = 1;
|
tmp_map.name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, name);
|
||||||
ret = 0;
|
tmp_map.deleted = 1;
|
||||||
}
|
map = hash_lookup(route_map_master_hash, &tmp_map);
|
||||||
|
XFREE(MTYPE_ROUTE_MAP_NAME, tmp_map.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (map)
|
||||||
|
{
|
||||||
|
map->to_be_processed = 1;
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
@ -386,8 +438,12 @@ vty_show_route_map (struct vty *vty, const char *name)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vty_out (vty, "%%route-map %s not found%s", name, VTY_NEWLINE);
|
if (zlog_default)
|
||||||
return CMD_WARNING;
|
vty_out (vty, "%s", zlog_proto_names[zlog_default->protocol]);
|
||||||
|
if (zlog_default->instance)
|
||||||
|
vty_out (vty, " %d", zlog_default->instance);
|
||||||
|
vty_out (vty, ": 'route-map %s' not found%s", name, VTY_NEWLINE);
|
||||||
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1049,6 +1105,7 @@ route_map_init (void)
|
|||||||
/* Make vector for match and set. */
|
/* Make vector for match and set. */
|
||||||
route_match_vec = vector_init (1);
|
route_match_vec = vector_init (1);
|
||||||
route_set_vec = vector_init (1);
|
route_set_vec = vector_init (1);
|
||||||
|
route_map_master_hash = hash_create(route_map_hash_key_make, route_map_hash_cmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
401
lib/vrf.c
Normal file
401
lib/vrf.c
Normal file
@ -0,0 +1,401 @@
|
|||||||
|
/*
|
||||||
|
* VRF functions.
|
||||||
|
* Copyright (C) 2014 6WIND S.A.
|
||||||
|
*
|
||||||
|
* This file is part of GNU Zebra.
|
||||||
|
*
|
||||||
|
* GNU Zebra is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published
|
||||||
|
* by the Free Software Foundation; either version 2, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* GNU Zebra is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with GNU Zebra; see the file COPYING. If not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <zebra.h>
|
||||||
|
|
||||||
|
#include "if.h"
|
||||||
|
#include "vrf.h"
|
||||||
|
#include "prefix.h"
|
||||||
|
#include "table.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "memory.h"
|
||||||
|
|
||||||
|
#define VRF_DEFAULT_NAME "Default-IP-Routing-Table"
|
||||||
|
|
||||||
|
struct vrf
|
||||||
|
{
|
||||||
|
/* Identifier, same as the vector index */
|
||||||
|
vrf_id_t vrf_id;
|
||||||
|
/* Name */
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
/* Master list of interfaces belonging to this VRF */
|
||||||
|
struct list *iflist;
|
||||||
|
|
||||||
|
/* User data */
|
||||||
|
void *info;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Holding VRF hooks */
|
||||||
|
struct vrf_master
|
||||||
|
{
|
||||||
|
int (*vrf_new_hook) (vrf_id_t, void **);
|
||||||
|
int (*vrf_delete_hook) (vrf_id_t, void **);
|
||||||
|
int (*vrf_enable_hook) (vrf_id_t, void **);
|
||||||
|
int (*vrf_disable_hook) (vrf_id_t, void **);
|
||||||
|
} vrf_master = {0,};
|
||||||
|
|
||||||
|
/* VRF table */
|
||||||
|
struct route_table *vrf_table = NULL;
|
||||||
|
|
||||||
|
static int vrf_is_enabled (struct vrf *vrf);
|
||||||
|
static int vrf_enable (struct vrf *vrf);
|
||||||
|
static void vrf_disable (struct vrf *vrf);
|
||||||
|
|
||||||
|
|
||||||
|
/* Build the table key */
|
||||||
|
static void
|
||||||
|
vrf_build_key (vrf_id_t vrf_id, struct prefix *p)
|
||||||
|
{
|
||||||
|
p->family = AF_INET;
|
||||||
|
p->prefixlen = IPV4_MAX_BITLEN;
|
||||||
|
p->u.prefix4.s_addr = vrf_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get a VRF. If not found, create one. */
|
||||||
|
static struct vrf *
|
||||||
|
vrf_get (vrf_id_t vrf_id)
|
||||||
|
{
|
||||||
|
struct prefix p;
|
||||||
|
struct route_node *rn;
|
||||||
|
struct vrf *vrf;
|
||||||
|
|
||||||
|
vrf_build_key (vrf_id, &p);
|
||||||
|
rn = route_node_get (vrf_table, &p);
|
||||||
|
if (rn->info)
|
||||||
|
{
|
||||||
|
vrf = (struct vrf *)rn->info;
|
||||||
|
route_unlock_node (rn); /* get */
|
||||||
|
return vrf;
|
||||||
|
}
|
||||||
|
|
||||||
|
vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
|
||||||
|
vrf->vrf_id = vrf_id;
|
||||||
|
rn->info = vrf;
|
||||||
|
|
||||||
|
/* Initialize interfaces. */
|
||||||
|
if_init (vrf_id, &vrf->iflist);
|
||||||
|
|
||||||
|
zlog_info ("VRF %u is created.", vrf_id);
|
||||||
|
|
||||||
|
if (vrf_master.vrf_new_hook)
|
||||||
|
(*vrf_master.vrf_new_hook) (vrf_id, &vrf->info);
|
||||||
|
|
||||||
|
return vrf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Delete a VRF. This is called in vrf_terminate(). */
|
||||||
|
static void
|
||||||
|
vrf_delete (struct vrf *vrf)
|
||||||
|
{
|
||||||
|
zlog_info ("VRF %u is to be deleted.", vrf->vrf_id);
|
||||||
|
|
||||||
|
if (vrf_is_enabled (vrf))
|
||||||
|
vrf_disable (vrf);
|
||||||
|
|
||||||
|
if (vrf_master.vrf_delete_hook)
|
||||||
|
(*vrf_master.vrf_delete_hook) (vrf->vrf_id, &vrf->info);
|
||||||
|
|
||||||
|
if_terminate (vrf->vrf_id, &vrf->iflist);
|
||||||
|
|
||||||
|
if (vrf->name)
|
||||||
|
XFREE (MTYPE_VRF_NAME, vrf->name);
|
||||||
|
|
||||||
|
XFREE (MTYPE_VRF, vrf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Look up a VRF by identifier. */
|
||||||
|
static struct vrf *
|
||||||
|
vrf_lookup (vrf_id_t vrf_id)
|
||||||
|
{
|
||||||
|
struct prefix p;
|
||||||
|
struct route_node *rn;
|
||||||
|
struct vrf *vrf = NULL;
|
||||||
|
|
||||||
|
vrf_build_key (vrf_id, &p);
|
||||||
|
rn = route_node_lookup (vrf_table, &p);
|
||||||
|
if (rn)
|
||||||
|
{
|
||||||
|
vrf = (struct vrf *)rn->info;
|
||||||
|
route_unlock_node (rn); /* lookup */
|
||||||
|
}
|
||||||
|
return vrf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check whether the VRF is enabled - that is, whether the VRF
|
||||||
|
* is ready to allocate resources. Currently there's only one
|
||||||
|
* type of resource: socket.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
vrf_is_enabled (struct vrf *vrf)
|
||||||
|
{
|
||||||
|
return vrf && vrf->vrf_id == VRF_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enable a VRF - that is, let the VRF be ready to use.
|
||||||
|
* The VRF_ENABLE_HOOK callback will be called to inform
|
||||||
|
* that they can allocate resources in this VRF.
|
||||||
|
*
|
||||||
|
* RETURN: 1 - enabled successfully; otherwise, 0.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
vrf_enable (struct vrf *vrf)
|
||||||
|
{
|
||||||
|
/* Till now, only the default VRF can be enabled. */
|
||||||
|
if (vrf->vrf_id == VRF_DEFAULT)
|
||||||
|
{
|
||||||
|
zlog_info ("VRF %u is enabled.", vrf->vrf_id);
|
||||||
|
|
||||||
|
if (vrf_master.vrf_enable_hook)
|
||||||
|
(*vrf_master.vrf_enable_hook) (vrf->vrf_id, &vrf->info);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disable a VRF - that is, let the VRF be unusable.
|
||||||
|
* The VRF_DELETE_HOOK callback will be called to inform
|
||||||
|
* that they must release the resources in the VRF.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
vrf_disable (struct vrf *vrf)
|
||||||
|
{
|
||||||
|
if (vrf_is_enabled (vrf))
|
||||||
|
{
|
||||||
|
zlog_info ("VRF %u is to be disabled.", vrf->vrf_id);
|
||||||
|
|
||||||
|
/* Till now, nothing to be done for the default VRF. */
|
||||||
|
|
||||||
|
if (vrf_master.vrf_disable_hook)
|
||||||
|
(*vrf_master.vrf_disable_hook) (vrf->vrf_id, &vrf->info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Add a VRF hook. Please add hooks before calling vrf_init(). */
|
||||||
|
void
|
||||||
|
vrf_add_hook (int type, int (*func)(vrf_id_t, void **))
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case VRF_NEW_HOOK:
|
||||||
|
vrf_master.vrf_new_hook = func;
|
||||||
|
break;
|
||||||
|
case VRF_DELETE_HOOK:
|
||||||
|
vrf_master.vrf_delete_hook = func;
|
||||||
|
break;
|
||||||
|
case VRF_ENABLE_HOOK:
|
||||||
|
vrf_master.vrf_enable_hook = func;
|
||||||
|
break;
|
||||||
|
case VRF_DISABLE_HOOK:
|
||||||
|
vrf_master.vrf_disable_hook = func;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the iterator of the first VRF. */
|
||||||
|
vrf_iter_t
|
||||||
|
vrf_first (void)
|
||||||
|
{
|
||||||
|
struct route_node *rn;
|
||||||
|
|
||||||
|
for (rn = route_top (vrf_table); rn; rn = route_next (rn))
|
||||||
|
if (rn->info)
|
||||||
|
{
|
||||||
|
route_unlock_node (rn); /* top/next */
|
||||||
|
return (vrf_iter_t)rn;
|
||||||
|
}
|
||||||
|
return VRF_ITER_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the next VRF iterator to the given iterator. */
|
||||||
|
vrf_iter_t
|
||||||
|
vrf_next (vrf_iter_t iter)
|
||||||
|
{
|
||||||
|
struct route_node *rn = NULL;
|
||||||
|
|
||||||
|
/* Lock it first because route_next() will unlock it. */
|
||||||
|
if (iter != VRF_ITER_INVALID)
|
||||||
|
rn = route_next (route_lock_node ((struct route_node *)iter));
|
||||||
|
|
||||||
|
for (; rn; rn = route_next (rn))
|
||||||
|
if (rn->info)
|
||||||
|
{
|
||||||
|
route_unlock_node (rn); /* next */
|
||||||
|
return (vrf_iter_t)rn;
|
||||||
|
}
|
||||||
|
return VRF_ITER_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the VRF iterator of the given VRF ID. If it does not exist,
|
||||||
|
* the iterator of the next existing VRF is returned. */
|
||||||
|
vrf_iter_t
|
||||||
|
vrf_iterator (vrf_id_t vrf_id)
|
||||||
|
{
|
||||||
|
struct prefix p;
|
||||||
|
struct route_node *rn;
|
||||||
|
|
||||||
|
vrf_build_key (vrf_id, &p);
|
||||||
|
rn = route_node_get (vrf_table, &p);
|
||||||
|
if (rn->info)
|
||||||
|
{
|
||||||
|
/* OK, the VRF exists. */
|
||||||
|
route_unlock_node (rn); /* get */
|
||||||
|
return (vrf_iter_t)rn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find the next VRF. */
|
||||||
|
for (rn = route_next (rn); rn; rn = route_next (rn))
|
||||||
|
if (rn->info)
|
||||||
|
{
|
||||||
|
route_unlock_node (rn); /* next */
|
||||||
|
return (vrf_iter_t)rn;
|
||||||
|
}
|
||||||
|
|
||||||
|
return VRF_ITER_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Obtain the VRF ID from the given VRF iterator. */
|
||||||
|
vrf_id_t
|
||||||
|
vrf_iter2id (vrf_iter_t iter)
|
||||||
|
{
|
||||||
|
struct route_node *rn = (struct route_node *) iter;
|
||||||
|
return (rn && rn->info) ? ((struct vrf *)rn->info)->vrf_id : VRF_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Obtain the data pointer from the given VRF iterator. */
|
||||||
|
void *
|
||||||
|
vrf_iter2info (vrf_iter_t iter)
|
||||||
|
{
|
||||||
|
struct route_node *rn = (struct route_node *) iter;
|
||||||
|
return (rn && rn->info) ? ((struct vrf *)rn->info)->info : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Obtain the interface list from the given VRF iterator. */
|
||||||
|
struct list *
|
||||||
|
vrf_iter2iflist (vrf_iter_t iter)
|
||||||
|
{
|
||||||
|
struct route_node *rn = (struct route_node *) iter;
|
||||||
|
return (rn && rn->info) ? ((struct vrf *)rn->info)->iflist : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the data pointer of the specified VRF. If not found, create one. */
|
||||||
|
void *
|
||||||
|
vrf_info_get (vrf_id_t vrf_id)
|
||||||
|
{
|
||||||
|
struct vrf *vrf = vrf_get (vrf_id);
|
||||||
|
return vrf->info;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Look up the data pointer of the specified VRF. */
|
||||||
|
void *
|
||||||
|
vrf_info_lookup (vrf_id_t vrf_id)
|
||||||
|
{
|
||||||
|
struct vrf *vrf = vrf_lookup (vrf_id);
|
||||||
|
return vrf ? vrf->info : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Look up the interface list in a VRF. */
|
||||||
|
struct list *
|
||||||
|
vrf_iflist (vrf_id_t vrf_id)
|
||||||
|
{
|
||||||
|
struct vrf * vrf = vrf_lookup (vrf_id);
|
||||||
|
return vrf ? vrf->iflist : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the interface list of the specified VRF. Create one if not find. */
|
||||||
|
struct list *
|
||||||
|
vrf_iflist_get (vrf_id_t vrf_id)
|
||||||
|
{
|
||||||
|
struct vrf * vrf = vrf_get (vrf_id);
|
||||||
|
return vrf->iflist;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize VRF module. */
|
||||||
|
void
|
||||||
|
vrf_init (void)
|
||||||
|
{
|
||||||
|
struct vrf *default_vrf;
|
||||||
|
|
||||||
|
/* Allocate VRF table. */
|
||||||
|
vrf_table = route_table_init ();
|
||||||
|
|
||||||
|
/* The default VRF always exists. */
|
||||||
|
default_vrf = vrf_get (VRF_DEFAULT);
|
||||||
|
if (!default_vrf)
|
||||||
|
{
|
||||||
|
zlog_err ("vrf_init: failed to create the default VRF!");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the default VRF name. */
|
||||||
|
default_vrf->name = XSTRDUP (MTYPE_VRF_NAME, VRF_DEFAULT_NAME);
|
||||||
|
|
||||||
|
/* Enable the default VRF. */
|
||||||
|
if (!vrf_enable (default_vrf))
|
||||||
|
{
|
||||||
|
zlog_err ("vrf_init: failed to enable the default VRF!");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Terminate VRF module. */
|
||||||
|
void
|
||||||
|
vrf_terminate (void)
|
||||||
|
{
|
||||||
|
struct route_node *rn;
|
||||||
|
struct vrf *vrf;
|
||||||
|
|
||||||
|
for (rn = route_top (vrf_table); rn; rn = route_next (rn))
|
||||||
|
if ((vrf = rn->info) != NULL)
|
||||||
|
vrf_delete (vrf);
|
||||||
|
|
||||||
|
route_table_finish (vrf_table);
|
||||||
|
vrf_table = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a socket for the VRF. */
|
||||||
|
int
|
||||||
|
vrf_socket (int domain, int type, int protocol, vrf_id_t vrf_id)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (!vrf_is_enabled (vrf_lookup (vrf_id)))
|
||||||
|
{
|
||||||
|
errno = ENOSYS;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vrf_id == VRF_DEFAULT)
|
||||||
|
ret = socket (domain, type, protocol);
|
||||||
|
else
|
||||||
|
errno = ENOSYS;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
127
lib/vrf.h
Normal file
127
lib/vrf.h
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
/*
|
||||||
|
* VRF related header.
|
||||||
|
* Copyright (C) 2014 6WIND S.A.
|
||||||
|
*
|
||||||
|
* This file is part of GNU Zebra.
|
||||||
|
*
|
||||||
|
* GNU Zebra is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published
|
||||||
|
* by the Free Software Foundation; either version 2, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* GNU Zebra is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with GNU Zebra; see the file COPYING. If not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ZEBRA_VRF_H
|
||||||
|
#define _ZEBRA_VRF_H
|
||||||
|
|
||||||
|
#include "linklist.h"
|
||||||
|
|
||||||
|
/* The default VRF ID */
|
||||||
|
#define VRF_DEFAULT 0
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The command strings
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define VRF_CMD_STR "vrf <0-65535>"
|
||||||
|
#define VRF_CMD_HELP_STR "Specify the VRF\nThe VRF ID\n"
|
||||||
|
|
||||||
|
#define VRF_ALL_CMD_STR "vrf all"
|
||||||
|
#define VRF_ALL_CMD_HELP_STR "Specify the VRF\nAll VRFs\n"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* VRF hooks
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define VRF_NEW_HOOK 0 /* a new VRF is just created */
|
||||||
|
#define VRF_DELETE_HOOK 1 /* a VRF is to be deleted */
|
||||||
|
#define VRF_ENABLE_HOOK 2 /* a VRF is ready to use */
|
||||||
|
#define VRF_DISABLE_HOOK 3 /* a VRF is to be unusable */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add a specific hook to VRF module.
|
||||||
|
* @param1: hook type
|
||||||
|
* @param2: the callback function
|
||||||
|
* - param 1: the VRF ID
|
||||||
|
* - param 2: the address of the user data pointer (the user data
|
||||||
|
* can be stored in or freed from there)
|
||||||
|
*/
|
||||||
|
extern void vrf_add_hook (int, int (*)(vrf_id_t, void **));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* VRF iteration
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef void * vrf_iter_t;
|
||||||
|
#define VRF_ITER_INVALID NULL /* invalid value of the iterator */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* VRF iteration utilities. Example for the usage:
|
||||||
|
*
|
||||||
|
* vrf_iter_t iter = vrf_first();
|
||||||
|
* for (; iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||||
|
*
|
||||||
|
* or
|
||||||
|
*
|
||||||
|
* vrf_iter_t iter = vrf_iterator (<a given VRF ID>);
|
||||||
|
* for (; iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Return the iterator of the first VRF. */
|
||||||
|
extern vrf_iter_t vrf_first (void);
|
||||||
|
/* Return the next VRF iterator to the given iterator. */
|
||||||
|
extern vrf_iter_t vrf_next (vrf_iter_t);
|
||||||
|
/* Return the VRF iterator of the given VRF ID. If it does not exist,
|
||||||
|
* the iterator of the next existing VRF is returned. */
|
||||||
|
extern vrf_iter_t vrf_iterator (vrf_id_t);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* VRF iterator to properties
|
||||||
|
*/
|
||||||
|
extern vrf_id_t vrf_iter2id (vrf_iter_t);
|
||||||
|
extern void *vrf_iter2info (vrf_iter_t);
|
||||||
|
extern struct list *vrf_iter2iflist (vrf_iter_t);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Utilities to obtain the user data
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Get the data pointer of the specified VRF. If not found, create one. */
|
||||||
|
extern void *vrf_info_get (vrf_id_t);
|
||||||
|
/* Look up the data pointer of the specified VRF. */
|
||||||
|
extern void *vrf_info_lookup (vrf_id_t);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Utilities to obtain the interface list
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Look up the interface list of the specified VRF. */
|
||||||
|
extern struct list *vrf_iflist (vrf_id_t);
|
||||||
|
/* Get the interface list of the specified VRF. Create one if not find. */
|
||||||
|
extern struct list *vrf_iflist_get (vrf_id_t);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* VRF initializer/destructor
|
||||||
|
*/
|
||||||
|
/* Please add hooks before calling vrf_init(). */
|
||||||
|
extern void vrf_init (void);
|
||||||
|
extern void vrf_terminate (void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* VRF utilities
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Create a socket serving for the given VRF */
|
||||||
|
extern int vrf_socket (int, int, int, vrf_id_t);
|
||||||
|
|
||||||
|
#endif /*_ZEBRA_VRF_H*/
|
||||||
|
|
@ -556,6 +556,9 @@ typedef u_int8_t safi_t;
|
|||||||
typedef u_int16_t zebra_size_t;
|
typedef u_int16_t zebra_size_t;
|
||||||
typedef u_int16_t zebra_command_t;
|
typedef u_int16_t zebra_command_t;
|
||||||
|
|
||||||
|
/* VRF ID type. */
|
||||||
|
typedef u_int16_t vrf_id_t;
|
||||||
|
|
||||||
/* FIFO -- first in first out structure and macros. */
|
/* FIFO -- first in first out structure and macros. */
|
||||||
struct fifo
|
struct fifo
|
||||||
{
|
{
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include "privs.h"
|
#include "privs.h"
|
||||||
#include "sigevent.h"
|
#include "sigevent.h"
|
||||||
#include "zclient.h"
|
#include "zclient.h"
|
||||||
|
#include "vrf.h"
|
||||||
|
|
||||||
#include "ospf6d.h"
|
#include "ospf6d.h"
|
||||||
#include "ospf6_top.h"
|
#include "ospf6_top.h"
|
||||||
@ -151,7 +152,7 @@ ospf6_exit (int status)
|
|||||||
ospf6_asbr_terminate ();
|
ospf6_asbr_terminate ();
|
||||||
ospf6_lsa_terminate ();
|
ospf6_lsa_terminate ();
|
||||||
|
|
||||||
if_terminate ();
|
vrf_terminate ();
|
||||||
vty_terminate ();
|
vty_terminate ();
|
||||||
cmd_terminate ();
|
cmd_terminate ();
|
||||||
|
|
||||||
@ -322,7 +323,7 @@ main (int argc, char *argv[], char *envp[])
|
|||||||
cmd_init (1);
|
cmd_init (1);
|
||||||
vty_init (master);
|
vty_init (master);
|
||||||
memory_init ();
|
memory_init ();
|
||||||
if_init ();
|
vrf_init ();
|
||||||
access_list_init ();
|
access_list_init ();
|
||||||
prefix_list_init ();
|
prefix_list_init ();
|
||||||
|
|
||||||
|
@ -1269,7 +1269,6 @@ void
|
|||||||
ospf_if_init ()
|
ospf_if_init ()
|
||||||
{
|
{
|
||||||
/* Initialize Zebra interface data structure. */
|
/* Initialize Zebra interface data structure. */
|
||||||
if_init ();
|
|
||||||
om->iflist = iflist;
|
om->iflist = iflist;
|
||||||
if_add_hook (IF_NEW_HOOK, ospf_if_new_hook);
|
if_add_hook (IF_NEW_HOOK, ospf_if_new_hook);
|
||||||
if_add_hook (IF_DELETE_HOOK, ospf_if_delete_hook);
|
if_add_hook (IF_DELETE_HOOK, ospf_if_delete_hook);
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
#include "privs.h"
|
#include "privs.h"
|
||||||
#include "sigevent.h"
|
#include "sigevent.h"
|
||||||
#include "zclient.h"
|
#include "zclient.h"
|
||||||
|
#include "vrf.h"
|
||||||
|
|
||||||
#include "ospfd/ospfd.h"
|
#include "ospfd/ospfd.h"
|
||||||
#include "ospfd/ospf_interface.h"
|
#include "ospfd/ospf_interface.h"
|
||||||
@ -300,6 +301,7 @@ main (int argc, char **argv)
|
|||||||
debug_init ();
|
debug_init ();
|
||||||
vty_init (master);
|
vty_init (master);
|
||||||
memory_init ();
|
memory_init ();
|
||||||
|
vrf_init ();
|
||||||
|
|
||||||
access_list_init ();
|
access_list_init ();
|
||||||
prefix_list_init ();
|
prefix_list_init ();
|
||||||
|
@ -2077,7 +2077,6 @@ void
|
|||||||
rip_if_init (void)
|
rip_if_init (void)
|
||||||
{
|
{
|
||||||
/* Default initial size of interface vector. */
|
/* Default initial size of interface vector. */
|
||||||
if_init();
|
|
||||||
if_add_hook (IF_NEW_HOOK, rip_interface_new_hook);
|
if_add_hook (IF_NEW_HOOK, rip_interface_new_hook);
|
||||||
if_add_hook (IF_DELETE_HOOK, rip_interface_delete_hook);
|
if_add_hook (IF_DELETE_HOOK, rip_interface_delete_hook);
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include "privs.h"
|
#include "privs.h"
|
||||||
#include "sigevent.h"
|
#include "sigevent.h"
|
||||||
#include "zclient.h"
|
#include "zclient.h"
|
||||||
|
#include "vrf.h"
|
||||||
|
|
||||||
#include "ripd/ripd.h"
|
#include "ripd/ripd.h"
|
||||||
|
|
||||||
@ -280,6 +281,7 @@ main (int argc, char **argv)
|
|||||||
vty_init (master);
|
vty_init (master);
|
||||||
memory_init ();
|
memory_init ();
|
||||||
keychain_init ();
|
keychain_init ();
|
||||||
|
vrf_init ();
|
||||||
|
|
||||||
/* RIP related initialization. */
|
/* RIP related initialization. */
|
||||||
rip_init ();
|
rip_init ();
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
#include "table.h"
|
#include "table.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
#include "privs.h"
|
#include "privs.h"
|
||||||
|
#include "vrf.h"
|
||||||
|
|
||||||
#include "ripngd/ripngd.h"
|
#include "ripngd/ripngd.h"
|
||||||
#include "ripngd/ripng_debug.h"
|
#include "ripngd/ripng_debug.h"
|
||||||
@ -1200,7 +1201,6 @@ void
|
|||||||
ripng_if_init ()
|
ripng_if_init ()
|
||||||
{
|
{
|
||||||
/* Interface initialize. */
|
/* Interface initialize. */
|
||||||
iflist = list_new ();
|
|
||||||
if_add_hook (IF_NEW_HOOK, ripng_if_new_hook);
|
if_add_hook (IF_NEW_HOOK, ripng_if_new_hook);
|
||||||
if_add_hook (IF_DELETE_HOOK, ripng_if_delete_hook);
|
if_add_hook (IF_DELETE_HOOK, ripng_if_delete_hook);
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include "if.h"
|
#include "if.h"
|
||||||
#include "privs.h"
|
#include "privs.h"
|
||||||
#include "sigevent.h"
|
#include "sigevent.h"
|
||||||
|
#include "vrf.h"
|
||||||
|
|
||||||
#include "ripngd/ripngd.h"
|
#include "ripngd/ripngd.h"
|
||||||
|
|
||||||
@ -276,6 +277,7 @@ main (int argc, char **argv)
|
|||||||
cmd_init (1);
|
cmd_init (1);
|
||||||
vty_init (master);
|
vty_init (master);
|
||||||
memory_init ();
|
memory_init ();
|
||||||
|
vrf_init ();
|
||||||
|
|
||||||
/* RIPngd inits. */
|
/* RIPngd inits. */
|
||||||
ripng_init ();
|
ripng_init ();
|
||||||
|
@ -31,6 +31,7 @@ print <<EOF;
|
|||||||
EOF
|
EOF
|
||||||
|
|
||||||
$ignore{'"interface IFNAME"'} = "ignore";
|
$ignore{'"interface IFNAME"'} = "ignore";
|
||||||
|
$ignore{'"interface IFNAME " "vrf <0-65535>"'} = "ignore";
|
||||||
$ignore{'"ip vrf NAME"'} = "ignore";
|
$ignore{'"ip vrf NAME"'} = "ignore";
|
||||||
$ignore{'"router rip"'} = "ignore";
|
$ignore{'"router rip"'} = "ignore";
|
||||||
$ignore{'"router ripng"'} = "ignore";
|
$ignore{'"router ripng"'} = "ignore";
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
#include "vtysh/vtysh.h"
|
#include "vtysh/vtysh.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "bgpd/bgp_vty.h"
|
#include "bgpd/bgp_vty.h"
|
||||||
|
#include "vrf.h"
|
||||||
|
|
||||||
/* Struct VTY. */
|
/* Struct VTY. */
|
||||||
struct vty *vty;
|
struct vty *vty;
|
||||||
@ -1498,6 +1499,14 @@ DEFUNSH (VTYSH_INTERFACE,
|
|||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ALIAS_SH (VTYSH_ZEBRA,
|
||||||
|
vtysh_interface,
|
||||||
|
vtysh_interface_vrf_cmd,
|
||||||
|
"interface IFNAME " VRF_CMD_STR,
|
||||||
|
"Select an interface to configure\n"
|
||||||
|
"Interface's name\n"
|
||||||
|
VRF_CMD_HELP_STR)
|
||||||
|
|
||||||
/* TODO Implement "no interface command in isisd. */
|
/* TODO Implement "no interface command in isisd. */
|
||||||
DEFSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D,
|
DEFSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D,
|
||||||
vtysh_no_interface_cmd,
|
vtysh_no_interface_cmd,
|
||||||
@ -1506,6 +1515,14 @@ DEFSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D,
|
|||||||
"Delete a pseudo interface's configuration\n"
|
"Delete a pseudo interface's configuration\n"
|
||||||
"Interface's name\n")
|
"Interface's name\n")
|
||||||
|
|
||||||
|
DEFSH (VTYSH_ZEBRA,
|
||||||
|
vtysh_no_interface_vrf_cmd,
|
||||||
|
"no interface IFNAME " VRF_CMD_STR,
|
||||||
|
NO_STR
|
||||||
|
"Delete a pseudo interface's configuration\n"
|
||||||
|
"Interface's name\n"
|
||||||
|
VRF_CMD_HELP_STR)
|
||||||
|
|
||||||
/* TODO Implement interface description commands in ripngd, ospf6d
|
/* TODO Implement interface description commands in ripngd, ospf6d
|
||||||
* and isisd. */
|
* and isisd. */
|
||||||
DEFSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_OSPFD,
|
DEFSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_OSPFD,
|
||||||
@ -2823,6 +2840,8 @@ vtysh_init_vty (void)
|
|||||||
install_element (KEYCHAIN_KEY_NODE, &key_chain_cmd);
|
install_element (KEYCHAIN_KEY_NODE, &key_chain_cmd);
|
||||||
install_element (CONFIG_NODE, &vtysh_interface_cmd);
|
install_element (CONFIG_NODE, &vtysh_interface_cmd);
|
||||||
install_element (CONFIG_NODE, &vtysh_no_interface_cmd);
|
install_element (CONFIG_NODE, &vtysh_no_interface_cmd);
|
||||||
|
install_element (CONFIG_NODE, &vtysh_interface_vrf_cmd);
|
||||||
|
install_element (CONFIG_NODE, &vtysh_no_interface_vrf_cmd);
|
||||||
install_element (ENABLE_NODE, &vtysh_show_running_config_cmd);
|
install_element (ENABLE_NODE, &vtysh_show_running_config_cmd);
|
||||||
install_element (ENABLE_NODE, &vtysh_show_running_config_daemon_cmd);
|
install_element (ENABLE_NODE, &vtysh_show_running_config_daemon_cmd);
|
||||||
install_element (ENABLE_NODE, &vtysh_copy_runningconfig_startupconfig_cmd);
|
install_element (ENABLE_NODE, &vtysh_copy_runningconfig_startupconfig_cmd);
|
||||||
|
@ -209,15 +209,15 @@ connected_up_ipv4 (struct interface *ifp, struct connected *ifc)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, 0, &p, NULL, NULL, ifp->ifindex,
|
rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, 0, &p, NULL, NULL, ifp->ifindex,
|
||||||
RT_TABLE_MAIN, ifp->metric, 0, SAFI_UNICAST);
|
ifp->vrf_id, RT_TABLE_MAIN, ifp->metric, 0, SAFI_UNICAST);
|
||||||
|
|
||||||
rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, 0, &p, NULL, NULL, ifp->ifindex,
|
rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, 0, &p, NULL, NULL, ifp->ifindex,
|
||||||
RT_TABLE_MAIN, ifp->metric, 0, SAFI_MULTICAST);
|
ifp->vrf_id, RT_TABLE_MAIN, ifp->metric, 0, SAFI_MULTICAST);
|
||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_RIB)
|
if (IS_ZEBRA_DEBUG_RIB)
|
||||||
zlog_debug ("%s: calling rib_update", __func__);
|
zlog_debug ("%s: calling rib_update", __func__);
|
||||||
|
|
||||||
rib_update ();
|
rib_update (ifp->vrf_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add connected IPv4 route to the interface. */
|
/* Add connected IPv4 route to the interface. */
|
||||||
@ -327,14 +327,16 @@ connected_down_ipv4 (struct interface *ifp, struct connected *ifc)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
/* Same logic as for connected_up_ipv4(): push the changes into the head. */
|
/* Same logic as for connected_up_ipv4(): push the changes into the head. */
|
||||||
rib_delete_ipv4 (ZEBRA_ROUTE_CONNECT, 0, 0, &p, NULL, ifp->ifindex, 0, SAFI_UNICAST);
|
rib_delete_ipv4 (ZEBRA_ROUTE_CONNECT, 0, 0, &p, NULL, ifp->ifindex, ifp->vrf_id, 0,
|
||||||
|
SAFI_UNICAST);
|
||||||
|
|
||||||
rib_delete_ipv4 (ZEBRA_ROUTE_CONNECT, 0, 0, &p, NULL, ifp->ifindex, 0, SAFI_MULTICAST);
|
rib_delete_ipv4 (ZEBRA_ROUTE_CONNECT, 0, 0, &p, NULL, ifp->ifindex, ifp->vrf_id, 0,
|
||||||
|
SAFI_MULTICAST);
|
||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_RIB)
|
if (IS_ZEBRA_DEBUG_RIB)
|
||||||
zlog_debug ("%s: calling rib_update_static", __func__);
|
zlog_debug ("%s: calling rib_update_static", __func__);
|
||||||
|
|
||||||
rib_update_static ();
|
rib_update_static (ifp->vrf_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -397,7 +399,7 @@ connected_delete_ipv4 (struct interface *ifp, int flags, struct in_addr *addr,
|
|||||||
if (IS_ZEBRA_DEBUG_RIB)
|
if (IS_ZEBRA_DEBUG_RIB)
|
||||||
zlog_debug ("%s: calling rib_update_static", __func__);
|
zlog_debug ("%s: calling rib_update_static", __func__);
|
||||||
|
|
||||||
rib_update_static();
|
rib_update_static(ifp->vrf_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
@ -420,13 +422,13 @@ connected_up_ipv6 (struct interface *ifp, struct connected *ifc)
|
|||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
rib_add_ipv6 (ZEBRA_ROUTE_CONNECT, 0, 0, &p, NULL, ifp->ifindex, RT_TABLE_MAIN,
|
rib_add_ipv6 (ZEBRA_ROUTE_CONNECT, 0, 0, &p, NULL, ifp->ifindex, ifp->vrf_id,
|
||||||
ifp->metric, 0, SAFI_UNICAST);
|
RT_TABLE_MAIN, ifp->metric, 0, SAFI_UNICAST);
|
||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_RIB)
|
if (IS_ZEBRA_DEBUG_RIB)
|
||||||
zlog_debug ("%s: calling rib_update", __func__);
|
zlog_debug ("%s: calling rib_update", __func__);
|
||||||
|
|
||||||
rib_update ();
|
rib_update (ifp->vrf_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add connected IPv6 route to the interface. */
|
/* Add connected IPv6 route to the interface. */
|
||||||
@ -509,12 +511,13 @@ connected_down_ipv6 (struct interface *ifp, struct connected *ifc)
|
|||||||
if (IN6_IS_ADDR_UNSPECIFIED (&p.prefix))
|
if (IN6_IS_ADDR_UNSPECIFIED (&p.prefix))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
rib_delete_ipv6 (ZEBRA_ROUTE_CONNECT, 0, 0, &p, NULL, ifp->ifindex, 0, SAFI_UNICAST);
|
rib_delete_ipv6 (ZEBRA_ROUTE_CONNECT, 0, 0, &p, NULL, ifp->ifindex,
|
||||||
|
ifp->vrf_id, 0, SAFI_UNICAST);
|
||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_RIB)
|
if (IS_ZEBRA_DEBUG_RIB)
|
||||||
zlog_debug ("%s: calling rib_update_static", __func__);
|
zlog_debug ("%s: calling rib_update_static", __func__);
|
||||||
|
|
||||||
rib_update_static ();
|
rib_update_static (ifp->vrf_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -538,6 +541,6 @@ connected_delete_ipv6 (struct interface *ifp, struct in6_addr *address,
|
|||||||
if (IS_ZEBRA_DEBUG_RIB)
|
if (IS_ZEBRA_DEBUG_RIB)
|
||||||
zlog_debug ("%s: calling rib_update_static", __func__);
|
zlog_debug ("%s: calling rib_update_static", __func__);
|
||||||
|
|
||||||
rib_update_static();
|
rib_update_static(ifp->vrf_id);
|
||||||
}
|
}
|
||||||
#endif /* HAVE_IPV6 */
|
#endif /* HAVE_IPV6 */
|
||||||
|
@ -29,8 +29,10 @@
|
|||||||
#include "connected.h"
|
#include "connected.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "vrf.h"
|
||||||
|
|
||||||
#include "zebra/interface.h"
|
#include "zebra/interface.h"
|
||||||
|
#include "zebra/rib.h"
|
||||||
|
|
||||||
/* Interface looking up using infamous SIOCGIFCONF. */
|
/* Interface looking up using infamous SIOCGIFCONF. */
|
||||||
static int
|
static int
|
||||||
@ -442,8 +444,13 @@ interface_info_ioctl ()
|
|||||||
|
|
||||||
/* Lookup all interface information. */
|
/* Lookup all interface information. */
|
||||||
void
|
void
|
||||||
interface_list ()
|
interface_list (struct zebra_vrf *zvrf)
|
||||||
{
|
{
|
||||||
|
if (zvrf->vrf_id != VRF_DEFAULT)
|
||||||
|
{
|
||||||
|
zlog_warn ("interface_list: ignore VRF %u", zvrf->vrf_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
/* Linux can do both proc & ioctl, ioctl is the only way to get
|
/* Linux can do both proc & ioctl, ioctl is the only way to get
|
||||||
interface aliases in 2.2 series kernels. */
|
interface aliases in 2.2 series kernels. */
|
||||||
#ifdef HAVE_PROC_NET_DEV
|
#ifdef HAVE_PROC_NET_DEV
|
||||||
|
@ -30,8 +30,10 @@
|
|||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "privs.h"
|
#include "privs.h"
|
||||||
|
#include "vrf.h"
|
||||||
|
|
||||||
#include "zebra/interface.h"
|
#include "zebra/interface.h"
|
||||||
|
#include "zebra/rib.h"
|
||||||
|
|
||||||
void lifreq_set_name (struct lifreq *, const char *);
|
void lifreq_set_name (struct lifreq *, const char *);
|
||||||
int if_get_flags_direct (const char *, uint64_t *, unsigned int af);
|
int if_get_flags_direct (const char *, uint64_t *, unsigned int af);
|
||||||
@ -349,8 +351,13 @@ interface_info_ioctl (struct interface *ifp)
|
|||||||
|
|
||||||
/* Lookup all interface information. */
|
/* Lookup all interface information. */
|
||||||
void
|
void
|
||||||
interface_list ()
|
interface_list (struct zebra_vrf *zvrf)
|
||||||
{
|
{
|
||||||
|
if (zvrf->vrf_id != VRF_DEFAULT)
|
||||||
|
{
|
||||||
|
zlog_warn ("interface_list: ignore VRF %u", zvrf->vrf_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
interface_list_ioctl (AF_INET);
|
interface_list_ioctl (AF_INET);
|
||||||
interface_list_ioctl (AF_INET6);
|
interface_list_ioctl (AF_INET6);
|
||||||
interface_list_ioctl (AF_UNSPEC);
|
interface_list_ioctl (AF_UNSPEC);
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
/* Interface information read by netlink. */
|
/* Interface information read by netlink. */
|
||||||
void
|
void
|
||||||
interface_list (void)
|
interface_list (struct zebra_vrf *zvrf)
|
||||||
{
|
{
|
||||||
interface_lookup_netlink ();
|
interface_lookup_netlink (zvrf);
|
||||||
}
|
}
|
||||||
|
@ -29,9 +29,15 @@
|
|||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "ioctl.h"
|
#include "ioctl.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
<<<<<<< HEAD
|
||||||
|
=======
|
||||||
|
#include "interface.h"
|
||||||
|
#include "vrf.h"
|
||||||
|
>>>>>>> 3c27b5f... zebra, lib/memtypes.c: the netlink sockets work per VRF
|
||||||
|
|
||||||
#include "zebra/rt.h"
|
#include "zebra/rt.h"
|
||||||
#include "zebra/kernel_socket.h"
|
#include "zebra/kernel_socket.h"
|
||||||
|
#include "zebra/rib.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
ifstat_update_sysctl (void)
|
ifstat_update_sysctl (void)
|
||||||
@ -90,7 +96,7 @@ ifstat_update_sysctl (void)
|
|||||||
|
|
||||||
/* Interface listing up function using sysctl(). */
|
/* Interface listing up function using sysctl(). */
|
||||||
void
|
void
|
||||||
interface_list ()
|
interface_list (struct zebra_vrf *zvrf)
|
||||||
{
|
{
|
||||||
caddr_t ref, buf, end;
|
caddr_t ref, buf, end;
|
||||||
size_t bufsiz;
|
size_t bufsiz;
|
||||||
@ -107,6 +113,12 @@ interface_list ()
|
|||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (zvrf->vrf_id != VRF_DEFAULT)
|
||||||
|
{
|
||||||
|
zlog_warn ("interface_list: ignore VRF %u", zvrf->vrf_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Query buffer size. */
|
/* Query buffer size. */
|
||||||
if (sysctl (mib, MIBSIZ, NULL, &bufsiz, NULL, 0) < 0)
|
if (sysctl (mib, MIBSIZ, NULL, &bufsiz, NULL, 0) < 0)
|
||||||
{
|
{
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include "connected.h"
|
#include "connected.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "zclient.h"
|
#include "zclient.h"
|
||||||
|
#include "vrf.h"
|
||||||
|
|
||||||
#include "zebra/interface.h"
|
#include "zebra/interface.h"
|
||||||
#include "zebra/rtadv.h"
|
#include "zebra/rtadv.h"
|
||||||
@ -388,21 +389,23 @@ if_add_update (struct interface *ifp)
|
|||||||
if (if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
|
if (if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)
|
||||||
{
|
{
|
||||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||||
zlog_debug ("interface %s index %d is shutdown. Won't wake it up.",
|
zlog_debug ("interface %s vrf %u index %d is shutdown. "
|
||||||
ifp->name, ifp->ifindex);
|
"Won't wake it up.",
|
||||||
|
ifp->name, ifp->vrf_id, ifp->ifindex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if_addr_wakeup (ifp);
|
if_addr_wakeup (ifp);
|
||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||||
zlog_debug ("interface %s index %d becomes active.",
|
zlog_debug ("interface %s vrf %u index %d becomes active.",
|
||||||
ifp->name, ifp->ifindex);
|
ifp->name, ifp->vrf_id, ifp->ifindex);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||||
zlog_debug ("interface %s index %d is added.", ifp->name, ifp->ifindex);
|
zlog_debug ("interface %s vrf %u index %d is added.",
|
||||||
|
ifp->name, ifp->vrf_id, ifp->ifindex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -419,8 +422,8 @@ if_delete_update (struct interface *ifp)
|
|||||||
|
|
||||||
if (if_is_up(ifp))
|
if (if_is_up(ifp))
|
||||||
{
|
{
|
||||||
zlog_err ("interface %s index %d is still up while being deleted.",
|
zlog_err ("interface %s vrf %u index %d is still up while being deleted.",
|
||||||
ifp->name, ifp->ifindex);
|
ifp->name, ifp->vrf_id, ifp->ifindex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -428,8 +431,8 @@ if_delete_update (struct interface *ifp)
|
|||||||
UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
|
UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
|
||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||||
zlog_debug ("interface %s index %d is now inactive.",
|
zlog_debug ("interface %s vrf %u index %d is now inactive.",
|
||||||
ifp->name, ifp->ifindex);
|
ifp->name, ifp->vrf_id, ifp->ifindex);
|
||||||
|
|
||||||
/* Delete connected routes from the kernel. */
|
/* Delete connected routes from the kernel. */
|
||||||
if (ifp->connected)
|
if (ifp->connected)
|
||||||
@ -641,7 +644,7 @@ if_up (struct interface *ifp)
|
|||||||
ifp->name);
|
ifp->name);
|
||||||
|
|
||||||
/* Examine all static routes. */
|
/* Examine all static routes. */
|
||||||
rib_update ();
|
rib_update (ifp->vrf_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Interface goes down. We have to manage different behavior of based
|
/* Interface goes down. We have to manage different behavior of based
|
||||||
@ -678,7 +681,7 @@ if_down (struct interface *ifp)
|
|||||||
zlog_debug ("%s: calling rib_update_static on interface %s down", __func__,
|
zlog_debug ("%s: calling rib_update_static on interface %s down", __func__,
|
||||||
ifp->name);
|
ifp->name);
|
||||||
|
|
||||||
rib_update_static ();
|
rib_update_static (ifp->vrf_id);
|
||||||
|
|
||||||
if_nbr_ipv6ll_to_ipv4ll_neigh_del_all (ifp);
|
if_nbr_ipv6ll_to_ipv4ll_neigh_del_all (ifp);
|
||||||
|
|
||||||
@ -846,6 +849,8 @@ if_dump_vty (struct vty *vty, struct interface *ifp)
|
|||||||
|
|
||||||
zebra_ptm_show_status(vty, ifp);
|
zebra_ptm_show_status(vty, ifp);
|
||||||
|
|
||||||
|
vty_out (vty, " vrf: %u%s", ifp->vrf_id, VTY_NEWLINE);
|
||||||
|
|
||||||
if (ifp->desc)
|
if (ifp->desc)
|
||||||
vty_out (vty, " Description: %s%s", ifp->desc,
|
vty_out (vty, " Description: %s%s", ifp->desc,
|
||||||
VTY_NEWLINE);
|
VTY_NEWLINE);
|
||||||
@ -1029,6 +1034,13 @@ DEFUN_NOSH (zebra_interface,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ALIAS (zebra_interface,
|
||||||
|
zebra_interface_vrf_cmd,
|
||||||
|
"interface IFNAME " VRF_CMD_STR,
|
||||||
|
"Select an interface to configure\n"
|
||||||
|
"Interface's name\n"
|
||||||
|
VRF_CMD_HELP_STR)
|
||||||
|
|
||||||
struct cmd_node interface_node =
|
struct cmd_node interface_node =
|
||||||
{
|
{
|
||||||
INTERFACE_NODE,
|
INTERFACE_NODE,
|
||||||
@ -1036,16 +1048,16 @@ struct cmd_node interface_node =
|
|||||||
1
|
1
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Show all or specified interface to vty. */
|
/* Show all interfaces to vty. */
|
||||||
DEFUN (show_interface, show_interface_cmd,
|
DEFUN (show_interface, show_interface_cmd,
|
||||||
"show interface [IFNAME]",
|
"show interface",
|
||||||
SHOW_STR
|
SHOW_STR
|
||||||
"Interface status and configuration\n"
|
"Interface status and configuration\n")
|
||||||
"Inteface name\n")
|
|
||||||
{
|
{
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
|
vrf_id_t vrf_id = VRF_DEFAULT;
|
||||||
|
|
||||||
#ifdef HAVE_PROC_NET_DEV
|
#ifdef HAVE_PROC_NET_DEV
|
||||||
/* If system has interface statistics via proc file system, update
|
/* If system has interface statistics via proc file system, update
|
||||||
statistics. */
|
statistics. */
|
||||||
@ -1055,39 +1067,144 @@ DEFUN (show_interface, show_interface_cmd,
|
|||||||
ifstat_update_sysctl ();
|
ifstat_update_sysctl ();
|
||||||
#endif /* HAVE_NET_RT_IFLIST */
|
#endif /* HAVE_NET_RT_IFLIST */
|
||||||
|
|
||||||
/* Specified interface print. */
|
if (argc > 0)
|
||||||
if (argc != 0)
|
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
|
||||||
{
|
|
||||||
ifp = if_lookup_by_name (argv[0]);
|
|
||||||
if (ifp == NULL)
|
|
||||||
{
|
|
||||||
vty_out (vty, "%% Can't find interface %s%s", argv[0],
|
|
||||||
VTY_NEWLINE);
|
|
||||||
return CMD_WARNING;
|
|
||||||
}
|
|
||||||
if_dump_vty (vty, ifp);
|
|
||||||
return CMD_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* All interface print. */
|
/* All interface print. */
|
||||||
for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
|
for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
|
||||||
if_dump_vty (vty, ifp);
|
if_dump_vty (vty, ifp);
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUN (show_interface_desc,
|
ALIAS (show_interface,
|
||||||
show_interface_desc_cmd,
|
show_interface_vrf_cmd,
|
||||||
"show interface description",
|
"show interface " VRF_CMD_STR,
|
||||||
SHOW_STR
|
SHOW_STR
|
||||||
"Interface status and configuration\n"
|
"Interface status and configuration\n"
|
||||||
"Interface description\n")
|
VRF_CMD_HELP_STR)
|
||||||
|
|
||||||
|
/* Show all interfaces to vty. */
|
||||||
|
DEFUN (show_interface_vrf_all, show_interface_vrf_all_cmd,
|
||||||
|
"show interface " VRF_ALL_CMD_STR,
|
||||||
|
SHOW_STR
|
||||||
|
"Interface status and configuration\n"
|
||||||
|
VRF_ALL_CMD_HELP_STR)
|
||||||
|
{
|
||||||
|
struct listnode *node;
|
||||||
|
struct interface *ifp;
|
||||||
|
vrf_iter_t iter;
|
||||||
|
|
||||||
|
#ifdef HAVE_PROC_NET_DEV
|
||||||
|
/* If system has interface statistics via proc file system, update
|
||||||
|
statistics. */
|
||||||
|
ifstat_update_proc ();
|
||||||
|
#endif /* HAVE_PROC_NET_DEV */
|
||||||
|
#ifdef HAVE_NET_RT_IFLIST
|
||||||
|
ifstat_update_sysctl ();
|
||||||
|
#endif /* HAVE_NET_RT_IFLIST */
|
||||||
|
|
||||||
|
/* All interface print. */
|
||||||
|
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||||
|
for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp))
|
||||||
|
if_dump_vty (vty, ifp);
|
||||||
|
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Show specified interface to vty. */
|
||||||
|
DEFUN (show_interface_name, show_interface_name_cmd,
|
||||||
|
"show interface IFNAME",
|
||||||
|
SHOW_STR
|
||||||
|
"Interface status and configuration\n"
|
||||||
|
"Inteface name\n")
|
||||||
|
{
|
||||||
|
struct interface *ifp;
|
||||||
|
vrf_id_t vrf_id = VRF_DEFAULT;
|
||||||
|
|
||||||
|
#ifdef HAVE_PROC_NET_DEV
|
||||||
|
/* If system has interface statistics via proc file system, update
|
||||||
|
statistics. */
|
||||||
|
ifstat_update_proc ();
|
||||||
|
#endif /* HAVE_PROC_NET_DEV */
|
||||||
|
#ifdef HAVE_NET_RT_IFLIST
|
||||||
|
ifstat_update_sysctl ();
|
||||||
|
#endif /* HAVE_NET_RT_IFLIST */
|
||||||
|
|
||||||
|
if (argc > 1)
|
||||||
|
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
|
||||||
|
|
||||||
|
/* Specified interface print. */
|
||||||
|
ifp = if_lookup_by_name_vrf (argv[0], vrf_id);
|
||||||
|
if (ifp == NULL)
|
||||||
|
{
|
||||||
|
vty_out (vty, "%% Can't find interface %s%s", argv[0],
|
||||||
|
VTY_NEWLINE);
|
||||||
|
return CMD_WARNING;
|
||||||
|
}
|
||||||
|
if_dump_vty (vty, ifp);
|
||||||
|
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALIAS (show_interface_name,
|
||||||
|
show_interface_name_vrf_cmd,
|
||||||
|
"show interface IFNAME " VRF_CMD_STR,
|
||||||
|
SHOW_STR
|
||||||
|
"Interface status and configuration\n"
|
||||||
|
"Inteface name\n"
|
||||||
|
VRF_CMD_HELP_STR)
|
||||||
|
|
||||||
|
/* Show specified interface to vty. */
|
||||||
|
DEFUN (show_interface_name_vrf_all, show_interface_name_vrf_all_cmd,
|
||||||
|
"show interface IFNAME " VRF_ALL_CMD_STR,
|
||||||
|
SHOW_STR
|
||||||
|
"Interface status and configuration\n"
|
||||||
|
"Inteface name\n"
|
||||||
|
VRF_ALL_CMD_HELP_STR)
|
||||||
|
{
|
||||||
|
struct interface *ifp;
|
||||||
|
vrf_iter_t iter;
|
||||||
|
int found = 0;
|
||||||
|
|
||||||
|
#ifdef HAVE_PROC_NET_DEV
|
||||||
|
/* If system has interface statistics via proc file system, update
|
||||||
|
statistics. */
|
||||||
|
ifstat_update_proc ();
|
||||||
|
#endif /* HAVE_PROC_NET_DEV */
|
||||||
|
#ifdef HAVE_NET_RT_IFLIST
|
||||||
|
ifstat_update_sysctl ();
|
||||||
|
#endif /* HAVE_NET_RT_IFLIST */
|
||||||
|
|
||||||
|
/* All interface print. */
|
||||||
|
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||||
|
{
|
||||||
|
/* Specified interface print. */
|
||||||
|
ifp = if_lookup_by_name_vrf (argv[0], vrf_iter2id (iter));
|
||||||
|
if (ifp)
|
||||||
|
{
|
||||||
|
if_dump_vty (vty, ifp);
|
||||||
|
found++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
vty_out (vty, "%% Can't find interface %s%s", argv[0], VTY_NEWLINE);
|
||||||
|
return CMD_WARNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
if_show_description (struct vty *vty, vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
|
|
||||||
vty_out (vty, "Interface Status Protocol Description%s", VTY_NEWLINE);
|
vty_out (vty, "Interface Status Protocol Description%s", VTY_NEWLINE);
|
||||||
for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
|
for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
@ -1118,6 +1235,52 @@ DEFUN (show_interface_desc,
|
|||||||
vty_out (vty, "%s", ifp->desc);
|
vty_out (vty, "%s", ifp->desc);
|
||||||
vty_out (vty, "%s", VTY_NEWLINE);
|
vty_out (vty, "%s", VTY_NEWLINE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFUN (show_interface_desc,
|
||||||
|
show_interface_desc_cmd,
|
||||||
|
"show interface description",
|
||||||
|
SHOW_STR
|
||||||
|
"Interface status and configuration\n"
|
||||||
|
"Interface description\n")
|
||||||
|
{
|
||||||
|
vrf_id_t vrf_id = VRF_DEFAULT;
|
||||||
|
|
||||||
|
if (argc > 0)
|
||||||
|
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
|
||||||
|
|
||||||
|
if_show_description (vty, vrf_id);
|
||||||
|
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALIAS (show_interface_desc,
|
||||||
|
show_interface_desc_vrf_cmd,
|
||||||
|
"show interface description " VRF_CMD_STR,
|
||||||
|
SHOW_STR
|
||||||
|
"Interface status and configuration\n"
|
||||||
|
"Interface description\n"
|
||||||
|
VRF_CMD_HELP_STR)
|
||||||
|
|
||||||
|
DEFUN (show_interface_desc_vrf_all,
|
||||||
|
show_interface_desc_vrf_all_cmd,
|
||||||
|
"show interface description " VRF_ALL_CMD_STR,
|
||||||
|
SHOW_STR
|
||||||
|
"Interface status and configuration\n"
|
||||||
|
"Interface description\n"
|
||||||
|
VRF_ALL_CMD_HELP_STR)
|
||||||
|
{
|
||||||
|
vrf_iter_t iter;
|
||||||
|
|
||||||
|
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||||
|
if (!list_isempty (vrf_iter2iflist (iter)))
|
||||||
|
{
|
||||||
|
vty_out (vty, "%s\tVRF %u%s%s", VTY_NEWLINE,
|
||||||
|
vrf_iter2id (iter),
|
||||||
|
VTY_NEWLINE, VTY_NEWLINE);
|
||||||
|
if_show_description (vty, vrf_iter2id (iter));
|
||||||
|
}
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1685,10 +1848,12 @@ if_config_write (struct vty *vty)
|
|||||||
{
|
{
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
|
vrf_iter_t iter;
|
||||||
|
|
||||||
zebra_ptm_write (vty);
|
zebra_ptm_write (vty);
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
|
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||||
|
for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp))
|
||||||
{
|
{
|
||||||
struct zebra_if *if_data;
|
struct zebra_if *if_data;
|
||||||
struct listnode *addrnode;
|
struct listnode *addrnode;
|
||||||
@ -1696,9 +1861,12 @@ if_config_write (struct vty *vty)
|
|||||||
struct prefix *p;
|
struct prefix *p;
|
||||||
|
|
||||||
if_data = ifp->info;
|
if_data = ifp->info;
|
||||||
|
|
||||||
vty_out (vty, "interface %s%s", ifp->name,
|
if (ifp->vrf_id == VRF_DEFAULT)
|
||||||
VTY_NEWLINE);
|
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_NEWLINE);
|
||||||
|
|
||||||
if (if_data)
|
if (if_data)
|
||||||
{
|
{
|
||||||
@ -1762,7 +1930,6 @@ void
|
|||||||
zebra_if_init (void)
|
zebra_if_init (void)
|
||||||
{
|
{
|
||||||
/* Initialize interface and new hook. */
|
/* Initialize interface and new hook. */
|
||||||
if_init ();
|
|
||||||
if_add_hook (IF_NEW_HOOK, if_zebra_new_hook);
|
if_add_hook (IF_NEW_HOOK, if_zebra_new_hook);
|
||||||
if_add_hook (IF_DELETE_HOOK, if_zebra_delete_hook);
|
if_add_hook (IF_DELETE_HOOK, if_zebra_delete_hook);
|
||||||
|
|
||||||
@ -1770,10 +1937,24 @@ zebra_if_init (void)
|
|||||||
install_node (&interface_node, if_config_write);
|
install_node (&interface_node, if_config_write);
|
||||||
|
|
||||||
install_element (VIEW_NODE, &show_interface_cmd);
|
install_element (VIEW_NODE, &show_interface_cmd);
|
||||||
|
install_element (VIEW_NODE, &show_interface_vrf_cmd);
|
||||||
|
install_element (VIEW_NODE, &show_interface_vrf_all_cmd);
|
||||||
|
install_element (VIEW_NODE, &show_interface_name_cmd);
|
||||||
|
install_element (VIEW_NODE, &show_interface_name_vrf_cmd);
|
||||||
|
install_element (VIEW_NODE, &show_interface_name_vrf_all_cmd);
|
||||||
install_element (ENABLE_NODE, &show_interface_cmd);
|
install_element (ENABLE_NODE, &show_interface_cmd);
|
||||||
|
install_element (ENABLE_NODE, &show_interface_vrf_cmd);
|
||||||
|
install_element (ENABLE_NODE, &show_interface_vrf_all_cmd);
|
||||||
|
install_element (ENABLE_NODE, &show_interface_name_cmd);
|
||||||
|
install_element (ENABLE_NODE, &show_interface_name_vrf_cmd);
|
||||||
|
install_element (ENABLE_NODE, &show_interface_name_vrf_all_cmd);
|
||||||
install_element (ENABLE_NODE, &show_interface_desc_cmd);
|
install_element (ENABLE_NODE, &show_interface_desc_cmd);
|
||||||
|
install_element (ENABLE_NODE, &show_interface_desc_vrf_cmd);
|
||||||
|
install_element (ENABLE_NODE, &show_interface_desc_vrf_all_cmd);
|
||||||
install_element (CONFIG_NODE, &zebra_interface_cmd);
|
install_element (CONFIG_NODE, &zebra_interface_cmd);
|
||||||
|
install_element (CONFIG_NODE, &zebra_interface_vrf_cmd);
|
||||||
install_element (CONFIG_NODE, &no_interface_cmd);
|
install_element (CONFIG_NODE, &no_interface_cmd);
|
||||||
|
install_element (CONFIG_NODE, &no_interface_vrf_cmd);
|
||||||
install_default (INTERFACE_NODE);
|
install_default (INTERFACE_NODE);
|
||||||
install_element (INTERFACE_NODE, &interface_desc_cmd);
|
install_element (INTERFACE_NODE, &interface_desc_cmd);
|
||||||
install_element (INTERFACE_NODE, &no_interface_desc_cmd);
|
install_element (INTERFACE_NODE, &no_interface_desc_cmd);
|
||||||
|
@ -38,11 +38,13 @@
|
|||||||
#define IF_ZEBRA_SHUTDOWN_ON 1
|
#define IF_ZEBRA_SHUTDOWN_ON 1
|
||||||
|
|
||||||
/* Router advertisement feature. */
|
/* Router advertisement feature. */
|
||||||
|
#ifndef RTADV
|
||||||
#if (defined(LINUX_IPV6) && (defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1)) || defined(KAME)
|
#if (defined(LINUX_IPV6) && (defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1)) || defined(KAME)
|
||||||
#ifdef HAVE_RTADV
|
#ifdef HAVE_RTADV
|
||||||
#define RTADV
|
#define RTADV
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef RTADV
|
#ifdef RTADV
|
||||||
/* Router advertisement parameter. From RFC4861, RFC6275 and RFC4191. */
|
/* Router advertisement parameter. From RFC4861, RFC6275 and RFC4191. */
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "zebra/redistribute.h"
|
#include "zebra/redistribute.h"
|
||||||
#include "zebra/connected.h"
|
#include "zebra/connected.h"
|
||||||
#include "zebra/rt_netlink.h"
|
#include "zebra/rt_netlink.h"
|
||||||
|
#include "zebra/rib.h"
|
||||||
|
|
||||||
int kernel_add_ipv4 (struct prefix *a, struct rib *b) { return 0; }
|
int kernel_add_ipv4 (struct prefix *a, struct rib *b) { return 0; }
|
||||||
int kernel_update_ipv4 (struct prefix *a, struct rib *b) { return 0; }
|
int kernel_update_ipv4 (struct prefix *a, struct rib *b) { return 0; }
|
||||||
@ -54,9 +55,10 @@ int netlink_neigh_update (int cmd, int ifindex, __u32 addr, char *lla, int llale
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void kernel_init (void) { return; }
|
void kernel_init (struct zebra_vrf *zvrf) { return; }
|
||||||
|
void kernel_terminate (struct zebra_vrf *zvrf) { return; }
|
||||||
#ifdef HAVE_SYS_WEAK_ALIAS_PRAGMA
|
#ifdef HAVE_SYS_WEAK_ALIAS_PRAGMA
|
||||||
#pragma weak route_read = kernel_init
|
#pragma weak route_read = kernel_init
|
||||||
#else
|
#else
|
||||||
void route_read (void) { return; }
|
void route_read (struct zebra_vrf *zvrf) { return; }
|
||||||
#endif
|
#endif
|
||||||
|
@ -32,11 +32,13 @@
|
|||||||
#include "table.h"
|
#include "table.h"
|
||||||
#include "rib.h"
|
#include "rib.h"
|
||||||
#include "privs.h"
|
#include "privs.h"
|
||||||
|
#include "vrf.h"
|
||||||
|
|
||||||
#include "zebra/interface.h"
|
#include "zebra/interface.h"
|
||||||
#include "zebra/zserv.h"
|
#include "zebra/zserv.h"
|
||||||
#include "zebra/debug.h"
|
#include "zebra/debug.h"
|
||||||
#include "zebra/kernel_socket.h"
|
#include "zebra/kernel_socket.h"
|
||||||
|
#include "zebra/rib.h"
|
||||||
|
|
||||||
extern struct zebra_privs_t zserv_privs;
|
extern struct zebra_privs_t zserv_privs;
|
||||||
extern struct zebra_t zebrad;
|
extern struct zebra_t zebrad;
|
||||||
@ -870,8 +872,8 @@ rtm_read (struct rt_msghdr *rtm)
|
|||||||
int ret;
|
int ret;
|
||||||
if (! IS_ZEBRA_DEBUG_RIB)
|
if (! IS_ZEBRA_DEBUG_RIB)
|
||||||
return;
|
return;
|
||||||
ret = rib_lookup_ipv4_route (&p, &gate);
|
ret = rib_lookup_ipv4_route (&p, &gate, VRF_DEFAULT);
|
||||||
inet_ntop (AF_INET, &p.prefix, buf, INET_ADDRSTRLEN);
|
prefix2str (&p, buf, sizeof(buf));
|
||||||
switch (rtm->rtm_type)
|
switch (rtm->rtm_type)
|
||||||
{
|
{
|
||||||
case RTM_ADD:
|
case RTM_ADD:
|
||||||
@ -935,16 +937,16 @@ rtm_read (struct rt_msghdr *rtm)
|
|||||||
*/
|
*/
|
||||||
if (rtm->rtm_type == RTM_CHANGE)
|
if (rtm->rtm_type == RTM_CHANGE)
|
||||||
rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p,
|
rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p,
|
||||||
NULL, 0, 0, SAFI_UNICAST);
|
NULL, 0, VRF_DEFAULT, SAFI_UNICAST);
|
||||||
|
|
||||||
if (rtm->rtm_type == RTM_GET
|
if (rtm->rtm_type == RTM_GET
|
||||||
|| rtm->rtm_type == RTM_ADD
|
|| rtm->rtm_type == RTM_ADD
|
||||||
|| rtm->rtm_type == RTM_CHANGE)
|
|| rtm->rtm_type == RTM_CHANGE)
|
||||||
rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags,
|
rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags,
|
||||||
&p, &gate.sin.sin_addr, NULL, 0, 0, 0, 0, SAFI_UNICAST);
|
&p, &gate.sin.sin_addr, NULL, 0, VRF_DEFAULT, 0, 0, SAFI_UNICAST);
|
||||||
else
|
else
|
||||||
rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, 0 zebra_flags,
|
rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, 0 zebra_flags,
|
||||||
&p, &gate.sin.sin_addr, 0, 0, SAFI_UNICAST);
|
&p, &gate.sin.sin_addr, 0, VRF_DEFAULT, SAFI_UNICAST);
|
||||||
}
|
}
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
if (dest.sa.sa_family == AF_INET6)
|
if (dest.sa.sa_family == AF_INET6)
|
||||||
@ -977,16 +979,16 @@ rtm_read (struct rt_msghdr *rtm)
|
|||||||
*/
|
*/
|
||||||
if (rtm->rtm_type == RTM_CHANGE)
|
if (rtm->rtm_type == RTM_CHANGE)
|
||||||
rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p,
|
rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p,
|
||||||
NULL, 0, 0, SAFI_UNICAST);
|
NULL, 0, VRF_DEFAULT, SAFI_UNICAST);
|
||||||
|
|
||||||
if (rtm->rtm_type == RTM_GET
|
if (rtm->rtm_type == RTM_GET
|
||||||
|| rtm->rtm_type == RTM_ADD
|
|| rtm->rtm_type == RTM_ADD
|
||||||
|| rtm->rtm_type == RTM_CHANGE)
|
|| rtm->rtm_type == RTM_CHANGE)
|
||||||
rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags,
|
rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags,
|
||||||
&p, &gate.sin6.sin6_addr, ifindex, 0, 0, 0, SAFI_UNICAST);
|
&p, &gate.sin6.sin6_addr, ifindex, VRF_DEFAULT, 0, 0, SAFI_UNICAST);
|
||||||
else
|
else
|
||||||
rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags,
|
rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags,
|
||||||
&p, &gate.sin6.sin6_addr, ifindex, 0, SAFI_UNICAST);
|
&p, &gate.sin6.sin6_addr, ifindex, VRF_DEFAULT, SAFI_UNICAST);
|
||||||
}
|
}
|
||||||
#endif /* HAVE_IPV6 */
|
#endif /* HAVE_IPV6 */
|
||||||
}
|
}
|
||||||
@ -1261,8 +1263,11 @@ kernel_read (struct thread *thread)
|
|||||||
|
|
||||||
/* Make routing socket. */
|
/* Make routing socket. */
|
||||||
static void
|
static void
|
||||||
routing_socket (void)
|
routing_socket (struct zebra_vrf *zvrf)
|
||||||
{
|
{
|
||||||
|
if (zvrf->vrf_id != VRF_DEFAULT)
|
||||||
|
return;
|
||||||
|
|
||||||
if ( zserv_privs.change (ZPRIVS_RAISE) )
|
if ( zserv_privs.change (ZPRIVS_RAISE) )
|
||||||
zlog_err ("routing_socket: Can't raise privileges");
|
zlog_err ("routing_socket: Can't raise privileges");
|
||||||
|
|
||||||
@ -1293,7 +1298,13 @@ routing_socket (void)
|
|||||||
/* Exported interface function. This function simply calls
|
/* Exported interface function. This function simply calls
|
||||||
routing_socket (). */
|
routing_socket (). */
|
||||||
void
|
void
|
||||||
kernel_init (void)
|
kernel_init (struct zebra_vrf *zvrf)
|
||||||
{
|
{
|
||||||
routing_socket ();
|
routing_socket (zvrf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
kernel_terminate (struct zebra_vrf *zvrf)
|
||||||
|
{
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
87
zebra/main.c
87
zebra/main.c
@ -32,6 +32,7 @@
|
|||||||
#include "plist.h"
|
#include "plist.h"
|
||||||
#include "privs.h"
|
#include "privs.h"
|
||||||
#include "sigevent.h"
|
#include "sigevent.h"
|
||||||
|
#include "vrf.h"
|
||||||
|
|
||||||
#include "zebra/rib.h"
|
#include "zebra/rib.h"
|
||||||
#include "zebra/zserv.h"
|
#include "zebra/zserv.h"
|
||||||
@ -213,6 +214,82 @@ struct quagga_signal_t zebra_signals[] =
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Callback upon creating a new VRF. */
|
||||||
|
static int
|
||||||
|
zebra_vrf_new (vrf_id_t vrf_id, void **info)
|
||||||
|
{
|
||||||
|
struct zebra_vrf *zvrf = *info;
|
||||||
|
|
||||||
|
if (! zvrf)
|
||||||
|
{
|
||||||
|
zvrf = zebra_vrf_alloc (vrf_id);
|
||||||
|
*info = (void *)zvrf;
|
||||||
|
router_id_init (zvrf);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Callback upon enabling a VRF. */
|
||||||
|
static int
|
||||||
|
zebra_vrf_enable (vrf_id_t vrf_id, void **info)
|
||||||
|
{
|
||||||
|
struct zebra_vrf *zvrf = (struct zebra_vrf *) (*info);
|
||||||
|
|
||||||
|
assert (zvrf);
|
||||||
|
|
||||||
|
#ifdef RTADV
|
||||||
|
rtadv_init (zvrf);
|
||||||
|
#endif
|
||||||
|
kernel_init (zvrf);
|
||||||
|
interface_list (zvrf);
|
||||||
|
route_read (zvrf);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Callback upon disabling a VRF. */
|
||||||
|
static int
|
||||||
|
zebra_vrf_disable (vrf_id_t vrf_id, void **info)
|
||||||
|
{
|
||||||
|
struct zebra_vrf *zvrf = (struct zebra_vrf *) (*info);
|
||||||
|
struct listnode *list_node;
|
||||||
|
struct interface *ifp;
|
||||||
|
|
||||||
|
assert (zvrf);
|
||||||
|
|
||||||
|
rib_close_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
|
||||||
|
rib_close_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
|
||||||
|
|
||||||
|
for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), list_node, ifp))
|
||||||
|
{
|
||||||
|
int operative = if_is_operative (ifp);
|
||||||
|
UNSET_FLAG (ifp->flags, IFF_UP);
|
||||||
|
if (operative)
|
||||||
|
if_down (ifp);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef RTADV
|
||||||
|
rtadv_terminate (zvrf);
|
||||||
|
#endif
|
||||||
|
kernel_terminate (zvrf);
|
||||||
|
|
||||||
|
list_delete_all_node (zvrf->rid_all_sorted_list);
|
||||||
|
list_delete_all_node (zvrf->rid_lo_sorted_list);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Zebra VRF initialization. */
|
||||||
|
static void
|
||||||
|
zebra_vrf_init (void)
|
||||||
|
{
|
||||||
|
vrf_add_hook (VRF_NEW_HOOK, zebra_vrf_new);
|
||||||
|
vrf_add_hook (VRF_ENABLE_HOOK, zebra_vrf_enable);
|
||||||
|
vrf_add_hook (VRF_DISABLE_HOOK, zebra_vrf_disable);
|
||||||
|
vrf_init ();
|
||||||
|
}
|
||||||
|
|
||||||
/* Main startup routine. */
|
/* Main startup routine. */
|
||||||
int
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
@ -336,12 +413,12 @@ main (int argc, char **argv)
|
|||||||
rib_init ();
|
rib_init ();
|
||||||
zebra_if_init ();
|
zebra_if_init ();
|
||||||
zebra_debug_init ();
|
zebra_debug_init ();
|
||||||
router_id_init();
|
router_id_cmd_init ();
|
||||||
zebra_vty_init ();
|
zebra_vty_init ();
|
||||||
access_list_init ();
|
access_list_init ();
|
||||||
prefix_list_init ();
|
prefix_list_init ();
|
||||||
#ifdef RTADV
|
#ifdef RTADV
|
||||||
rtadv_init ();
|
rtadv_cmd_init ();
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_IRDP
|
#ifdef HAVE_IRDP
|
||||||
irdp_init();
|
irdp_init();
|
||||||
@ -354,10 +431,8 @@ main (int argc, char **argv)
|
|||||||
/* For debug purpose. */
|
/* For debug purpose. */
|
||||||
/* SET_FLAG (zebra_debug_event, ZEBRA_DEBUG_EVENT); */
|
/* SET_FLAG (zebra_debug_event, ZEBRA_DEBUG_EVENT); */
|
||||||
|
|
||||||
/* Make kernel routing socket. */
|
/* Initialize VRF module, and make kernel routing socket. */
|
||||||
kernel_init ();
|
zebra_vrf_init ();
|
||||||
interface_list ();
|
|
||||||
route_read ();
|
|
||||||
|
|
||||||
#ifdef HAVE_SNMP
|
#ifdef HAVE_SNMP
|
||||||
zebra_snmp_init ();
|
zebra_snmp_init ();
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include "zclient.h"
|
#include "zclient.h"
|
||||||
#include "linklist.h"
|
#include "linklist.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "vrf.h"
|
||||||
|
|
||||||
#include "zebra/rib.h"
|
#include "zebra/rib.h"
|
||||||
#include "zebra/zserv.h"
|
#include "zebra/zserv.h"
|
||||||
@ -96,7 +97,7 @@ zebra_redistribute_default (struct zserv *client)
|
|||||||
p.family = AF_INET;
|
p.family = AF_INET;
|
||||||
|
|
||||||
/* Lookup table. */
|
/* Lookup table. */
|
||||||
table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
|
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
|
||||||
if (table)
|
if (table)
|
||||||
{
|
{
|
||||||
rn = route_node_lookup (table, (struct prefix *)&p);
|
rn = route_node_lookup (table, (struct prefix *)&p);
|
||||||
@ -116,7 +117,7 @@ zebra_redistribute_default (struct zserv *client)
|
|||||||
p6.family = AF_INET6;
|
p6.family = AF_INET6;
|
||||||
|
|
||||||
/* Lookup table. */
|
/* Lookup table. */
|
||||||
table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
|
table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT);
|
||||||
if (table)
|
if (table)
|
||||||
{
|
{
|
||||||
rn = route_node_lookup (table, (struct prefix *)&p6);
|
rn = route_node_lookup (table, (struct prefix *)&p6);
|
||||||
@ -140,7 +141,7 @@ zebra_redistribute (struct zserv *client, int type, u_short instance)
|
|||||||
struct route_table *table;
|
struct route_table *table;
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
|
|
||||||
table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
|
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
|
||||||
if (table)
|
if (table)
|
||||||
for (rn = route_top (table); rn; rn = route_next (rn))
|
for (rn = route_top (table); rn; rn = route_next (rn))
|
||||||
RNODE_FOREACH_RIB (rn, newrib)
|
RNODE_FOREACH_RIB (rn, newrib)
|
||||||
@ -155,7 +156,7 @@ zebra_redistribute (struct zserv *client, int type, u_short instance)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
|
table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT);
|
||||||
if (table)
|
if (table)
|
||||||
for (rn = route_top (table); rn; rn = route_next (rn))
|
for (rn = route_top (table); rn; rn = route_next (rn))
|
||||||
RNODE_FOREACH_RIB (rn, newrib)
|
RNODE_FOREACH_RIB (rn, newrib)
|
||||||
@ -499,7 +500,7 @@ zebra_add_import_table_entry (struct route_node *rn, struct rib *rib)
|
|||||||
|
|
||||||
rib_add_ipv4(ZEBRA_ROUTE_TABLE, rib->table, 0, &p4,
|
rib_add_ipv4(ZEBRA_ROUTE_TABLE, rib->table, 0, &p4,
|
||||||
gate, &nhop->src.ipv4,
|
gate, &nhop->src.ipv4,
|
||||||
nhop->ifindex, zebrad.rtm_table_default,
|
nhop->ifindex, rib->vrf_id, zebrad.rtm_table_default,
|
||||||
rib->metric,
|
rib->metric,
|
||||||
zebra_import_table_distance[AFI_IP][rib->table],
|
zebra_import_table_distance[AFI_IP][rib->table],
|
||||||
SAFI_UNICAST);
|
SAFI_UNICAST);
|
||||||
@ -539,7 +540,7 @@ zebra_del_import_table_entry (struct route_node *rn, struct rib *rib)
|
|||||||
p4.prefix = rn->p.u.prefix4;
|
p4.prefix = rn->p.u.prefix4;
|
||||||
|
|
||||||
rib_delete_ipv4(ZEBRA_ROUTE_TABLE, rib->table, rib->flags, &p4, NULL,
|
rib_delete_ipv4(ZEBRA_ROUTE_TABLE, rib->table, rib->flags, &p4, NULL,
|
||||||
0, zebrad.rtm_table_default, SAFI_UNICAST);
|
0, rib->vrf_id, zebrad.rtm_table_default, SAFI_UNICAST);
|
||||||
}
|
}
|
||||||
/* DD: Add IPv6 code */
|
/* DD: Add IPv6 code */
|
||||||
|
|
||||||
@ -561,7 +562,7 @@ zebra_import_table (afi_t afi, u_int32_t table_id, u_int32_t distance, int add)
|
|||||||
if (afi >= AFI_MAX)
|
if (afi >= AFI_MAX)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
table = vrf_other_route_table(afi, table_id, 0);
|
table = zebra_vrf_other_route_table(afi, table_id, VRF_DEFAULT);
|
||||||
if (table == NULL)
|
if (table == NULL)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
127
zebra/rib.h
127
zebra/rib.h
@ -23,6 +23,7 @@
|
|||||||
#ifndef _ZEBRA_RIB_H
|
#ifndef _ZEBRA_RIB_H
|
||||||
#define _ZEBRA_RIB_H
|
#define _ZEBRA_RIB_H
|
||||||
|
|
||||||
|
#include "linklist.h"
|
||||||
#include "prefix.h"
|
#include "prefix.h"
|
||||||
#include "table.h"
|
#include "table.h"
|
||||||
#include "queue.h"
|
#include "queue.h"
|
||||||
@ -52,6 +53,9 @@ struct rib
|
|||||||
/* Source protocol instance */
|
/* Source protocol instance */
|
||||||
u_short instance;
|
u_short instance;
|
||||||
|
|
||||||
|
/* VRF identifier. */
|
||||||
|
vrf_id_t vrf_id;
|
||||||
|
|
||||||
/* Which routing table */
|
/* Which routing table */
|
||||||
uint32_t table;
|
uint32_t table;
|
||||||
|
|
||||||
@ -171,6 +175,9 @@ struct static_route
|
|||||||
struct static_route *prev;
|
struct static_route *prev;
|
||||||
struct static_route *next;
|
struct static_route *next;
|
||||||
|
|
||||||
|
/* VRF identifier. */
|
||||||
|
vrf_id_t vrf_id;
|
||||||
|
|
||||||
/* Administrative distance. */
|
/* Administrative distance. */
|
||||||
u_char distance;
|
u_char distance;
|
||||||
|
|
||||||
@ -187,7 +194,7 @@ struct static_route
|
|||||||
#define STATIC_IPV6_IFNAME 6
|
#define STATIC_IPV6_IFNAME 6
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Nexthop value.
|
* Nexthop value.
|
||||||
*
|
*
|
||||||
* Under IPv4 addr and ifname are
|
* Under IPv4 addr and ifname are
|
||||||
* used independentyly.
|
* used independentyly.
|
||||||
@ -205,6 +212,7 @@ struct static_route
|
|||||||
*/
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* The following for loop allows to iterate over the nexthop
|
/* The following for loop allows to iterate over the nexthop
|
||||||
* structure of routes.
|
* structure of routes.
|
||||||
*
|
*
|
||||||
@ -251,11 +259,45 @@ struct static_route
|
|||||||
: ((tnexthop) = (nexthop)->next)) \
|
: ((tnexthop) = (nexthop)->next)) \
|
||||||
: (((recursing) = 0),((tnexthop) = (tnexthop)->next)))
|
: (((recursing) = 0),((tnexthop) = (tnexthop)->next)))
|
||||||
|
|
||||||
/* Routing table instance. */
|
/* Router advertisement feature. */
|
||||||
struct vrf
|
#ifndef RTADV
|
||||||
|
#if (defined(LINUX_IPV6) && (defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1)) || defined(KAME)
|
||||||
|
#ifdef HAVE_RTADV
|
||||||
|
#define RTADV
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined (RTADV)
|
||||||
|
/* Structure which hold status of router advertisement. */
|
||||||
|
struct rtadv
|
||||||
{
|
{
|
||||||
/* Identifier. This is same as routing table vector index. */
|
int sock;
|
||||||
u_int32_t id;
|
|
||||||
|
int adv_if_count;
|
||||||
|
int adv_msec_if_count;
|
||||||
|
|
||||||
|
struct thread *ra_read;
|
||||||
|
struct thread *ra_timer;
|
||||||
|
};
|
||||||
|
#endif /* RTADV */
|
||||||
|
|
||||||
|
#ifdef HAVE_NETLINK
|
||||||
|
/* Socket interface to kernel */
|
||||||
|
struct nlsock
|
||||||
|
{
|
||||||
|
int sock;
|
||||||
|
int seq;
|
||||||
|
struct sockaddr_nl snl;
|
||||||
|
const char *name;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Routing table instance. */
|
||||||
|
struct zebra_vrf
|
||||||
|
{
|
||||||
|
/* Identifier. */
|
||||||
|
vrf_id_t vrf_id;
|
||||||
|
|
||||||
/* Routing table name. */
|
/* Routing table name. */
|
||||||
char *name;
|
char *name;
|
||||||
@ -280,6 +322,25 @@ struct vrf
|
|||||||
|
|
||||||
/* Routing tables off of main table for redistribute table */
|
/* Routing tables off of main table for redistribute table */
|
||||||
struct route_table *other_table[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX];
|
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
|
||||||
|
*/
|
||||||
|
struct list _rid_all_sorted_list;
|
||||||
|
struct list _rid_lo_sorted_list;
|
||||||
|
struct list *rid_all_sorted_list;
|
||||||
|
struct list *rid_lo_sorted_list;
|
||||||
|
struct prefix rid_user_assigned;
|
||||||
|
|
||||||
|
#if defined (RTADV)
|
||||||
|
struct rtadv rtadv;
|
||||||
|
#endif /* RTADV */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -292,9 +353,9 @@ typedef struct rib_table_info_t_
|
|||||||
{
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Back pointer to vrf.
|
* Back pointer to zebra_vrf.
|
||||||
*/
|
*/
|
||||||
struct vrf *vrf;
|
struct zebra_vrf *zvrf;
|
||||||
afi_t afi;
|
afi_t afi;
|
||||||
safi_t safi;
|
safi_t safi;
|
||||||
|
|
||||||
@ -313,7 +374,7 @@ typedef enum
|
|||||||
*/
|
*/
|
||||||
typedef struct rib_tables_iter_t_
|
typedef struct rib_tables_iter_t_
|
||||||
{
|
{
|
||||||
uint32_t vrf_id;
|
vrf_id_t vrf_id;
|
||||||
int afi_safi_ix;
|
int afi_safi_ix;
|
||||||
|
|
||||||
rib_tables_iter_state_t state;
|
rib_tables_iter_state_t state;
|
||||||
@ -341,7 +402,8 @@ extern void rib_lookup_and_pushup (struct prefix_ipv4 *);
|
|||||||
#define rib_dump(prefix ,rib) _rib_dump(__func__, prefix, rib)
|
#define rib_dump(prefix ,rib) _rib_dump(__func__, prefix, rib)
|
||||||
extern void _rib_dump (const char *,
|
extern void _rib_dump (const char *,
|
||||||
union prefix46constptr, const struct rib *);
|
union prefix46constptr, const struct rib *);
|
||||||
extern int rib_lookup_ipv4_route (struct prefix_ipv4 *, union sockunion *);
|
extern int rib_lookup_ipv4_route (struct prefix_ipv4 *, union sockunion *,
|
||||||
|
vrf_id_t);
|
||||||
#define ZEBRA_RIB_LOOKUP_ERROR -1
|
#define ZEBRA_RIB_LOOKUP_ERROR -1
|
||||||
#define ZEBRA_RIB_FOUND_EXACT 0
|
#define ZEBRA_RIB_FOUND_EXACT 0
|
||||||
#define ZEBRA_RIB_FOUND_NOGATE 1
|
#define ZEBRA_RIB_FOUND_NOGATE 1
|
||||||
@ -358,11 +420,12 @@ extern int
|
|||||||
rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
|
rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
|
||||||
struct in6_addr *gate, unsigned int ifindex, int table);
|
struct in6_addr *gate, unsigned int ifindex, int table);
|
||||||
|
|
||||||
extern struct vrf *vrf_lookup (u_int32_t);
|
extern struct zebra_vrf *zebra_vrf_lookup (vrf_id_t vrf_id);
|
||||||
extern struct route_table *vrf_table (afi_t afi, safi_t safi, u_int32_t id);
|
extern struct zebra_vrf *zebra_vrf_alloc (vrf_id_t);
|
||||||
extern struct route_table *vrf_static_table (afi_t afi, safi_t safi, u_int32_t id);
|
extern struct route_table *zebra_vrf_table (afi_t, safi_t, vrf_id_t);
|
||||||
extern struct route_table *vrf_other_route_table (afi_t afi, u_int32_t table_id,
|
extern struct route_table *zebra_vrf_static_table (afi_t, safi_t, vrf_id_t);
|
||||||
u_int32_t vrf_id);
|
extern struct route_table *zebra_vrf_other_route_table (afi_t afi, u_int32_t table_id,
|
||||||
|
vrf_id_t vrf_id);
|
||||||
extern int is_zebra_valid_kernel_table(u_int32_t table_id);
|
extern int is_zebra_valid_kernel_table(u_int32_t table_id);
|
||||||
extern int is_zebra_main_routing_table(u_int32_t table_id);
|
extern int is_zebra_main_routing_table(u_int32_t table_id);
|
||||||
extern int zebra_check_addr (struct prefix *p);
|
extern int zebra_check_addr (struct prefix *p);
|
||||||
@ -372,23 +435,24 @@ extern int zebra_check_addr (struct prefix *p);
|
|||||||
* also implicitly withdraw equal prefix of same type. */
|
* also implicitly withdraw equal prefix of same type. */
|
||||||
extern int rib_add_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p,
|
extern int rib_add_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p,
|
||||||
struct in_addr *gate, struct in_addr *src,
|
struct in_addr *gate, struct in_addr *src,
|
||||||
unsigned int ifindex, u_int32_t vrf_id,
|
unsigned int ifindex, vrf_id_t vrf_id, u_int32_t table_id,
|
||||||
u_int32_t, u_char, safi_t);
|
u_int32_t, u_char, safi_t);
|
||||||
|
|
||||||
extern int rib_add_ipv4_multipath (struct prefix_ipv4 *, struct rib *, safi_t);
|
extern int rib_add_ipv4_multipath (struct prefix_ipv4 *, struct rib *, safi_t);
|
||||||
|
|
||||||
extern int rib_delete_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p,
|
extern int rib_delete_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p,
|
||||||
struct in_addr *gate, unsigned int ifindex,
|
struct in_addr *gate, unsigned int ifindex,
|
||||||
u_int32_t, safi_t safi);
|
vrf_id_t, u_int32_t, safi_t safi);
|
||||||
|
|
||||||
extern struct rib *rib_match_ipv4 (struct in_addr);
|
extern struct rib *rib_match_ipv4 (struct in_addr, vrf_id_t);
|
||||||
|
|
||||||
extern struct rib *rib_lookup_ipv4 (struct prefix_ipv4 *);
|
extern struct rib *rib_lookup_ipv4 (struct prefix_ipv4 *, vrf_id_t);
|
||||||
|
|
||||||
extern void rib_update (void);
|
extern void rib_update (vrf_id_t);
|
||||||
extern void rib_update_static (void);
|
extern void rib_update_static (vrf_id_t);
|
||||||
extern void rib_weed_tables (void);
|
extern void rib_weed_tables (void);
|
||||||
extern void rib_sweep_route (void);
|
extern void rib_sweep_route (void);
|
||||||
|
extern void rib_close_table (struct route_table *);
|
||||||
extern void rib_close (void);
|
extern void rib_close (void);
|
||||||
extern void rib_init (void);
|
extern void rib_init (void);
|
||||||
extern unsigned long rib_score_proto (u_char proto, u_short instance);
|
extern unsigned long rib_score_proto (u_char proto, u_short instance);
|
||||||
@ -398,31 +462,32 @@ extern void rib_queue_add (struct zebra_t *zebra, struct route_node *rn);
|
|||||||
|
|
||||||
extern int
|
extern int
|
||||||
static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
|
static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
|
||||||
u_char flags, u_short tag, u_char distance, u_int32_t vrf_id);
|
u_char flags, u_short tag, u_char distance, vrf_id_t vrf_id);
|
||||||
|
|
||||||
extern int
|
extern int
|
||||||
static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
|
static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
|
||||||
u_short tag, u_char distance, u_int32_t vrf_id);
|
u_short tag, u_char distance, vrf_id_t vrf_id);
|
||||||
|
|
||||||
extern int
|
extern int
|
||||||
rib_add_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
|
rib_add_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
|
||||||
struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id,
|
struct in6_addr *gate, unsigned int ifindex, vrf_id_t vrf_id,
|
||||||
u_int32_t metric, u_char distance, safi_t safi);
|
u_int32_t table_id, u_int32_t metric, u_char distance, safi_t safi);
|
||||||
|
|
||||||
extern int
|
extern int
|
||||||
rib_delete_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
|
rib_delete_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
|
||||||
struct in6_addr *gate, unsigned int ifindex, u_int32_t vrf_id, safi_t safi);
|
struct in6_addr *gate, unsigned int ifindex, vrf_id_t vrf_id,
|
||||||
|
u_int32_t table_id, safi_t safi);
|
||||||
|
|
||||||
extern struct rib *rib_lookup_ipv6 (struct in6_addr *);
|
extern struct rib *rib_lookup_ipv6 (struct in6_addr *, vrf_id_t);
|
||||||
|
|
||||||
extern struct rib *rib_match_ipv6 (struct in6_addr *);
|
extern struct rib *rib_match_ipv6 (struct in6_addr *, vrf_id_t);
|
||||||
|
|
||||||
extern struct route_table *rib_table_ipv6;
|
extern struct route_table *rib_table_ipv6;
|
||||||
|
|
||||||
extern int
|
extern int
|
||||||
static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
|
static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
|
||||||
const char *ifname, u_char flags, u_short tag,
|
const char *ifname, u_char flags, u_short tag,
|
||||||
u_char distance, u_int32_t vrf_id);
|
u_char distance, vrf_id_t vrf_id);
|
||||||
|
|
||||||
extern int
|
extern int
|
||||||
rib_add_ipv6_multipath (struct prefix *, struct rib *, safi_t,
|
rib_add_ipv6_multipath (struct prefix *, struct rib *, safi_t,
|
||||||
@ -431,7 +496,7 @@ rib_add_ipv6_multipath (struct prefix *, struct rib *, safi_t,
|
|||||||
extern int
|
extern int
|
||||||
static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
|
static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
|
||||||
const char *ifname, u_short tag, u_char distance,
|
const char *ifname, u_short tag, u_char distance,
|
||||||
u_int32_t vrf_id);
|
vrf_id_t vrf_id);
|
||||||
|
|
||||||
extern int rib_gc_dest (struct route_node *rn);
|
extern int rib_gc_dest (struct route_node *rn);
|
||||||
extern struct route_table *rib_tables_iter_next (rib_tables_iter_t *iter);
|
extern struct route_table *rib_tables_iter_next (rib_tables_iter_t *iter);
|
||||||
@ -508,10 +573,10 @@ rib_dest_table (rib_dest_t *dest)
|
|||||||
/*
|
/*
|
||||||
* rib_dest_vrf
|
* rib_dest_vrf
|
||||||
*/
|
*/
|
||||||
static inline struct vrf *
|
static inline struct zebra_vrf *
|
||||||
rib_dest_vrf (rib_dest_t *dest)
|
rib_dest_vrf (rib_dest_t *dest)
|
||||||
{
|
{
|
||||||
return rib_table_info (rib_dest_table (dest))->vrf;
|
return rib_table_info (rib_dest_table (dest))->zvrf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -36,16 +36,12 @@
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "table.h"
|
#include "table.h"
|
||||||
#include "rib.h"
|
#include "rib.h"
|
||||||
|
#include "vrf.h"
|
||||||
|
|
||||||
#include "zebra/zserv.h"
|
#include "zebra/zserv.h"
|
||||||
#include "zebra/router-id.h"
|
#include "zebra/router-id.h"
|
||||||
#include "zebra/redistribute.h"
|
#include "zebra/redistribute.h"
|
||||||
|
|
||||||
static struct list _rid_all_sorted_list;
|
|
||||||
static struct list _rid_lo_sorted_list;
|
|
||||||
static struct list *rid_all_sorted_list = &_rid_all_sorted_list;
|
|
||||||
static struct list *rid_lo_sorted_list = &_rid_lo_sorted_list;
|
|
||||||
static struct prefix rid_user_assigned;
|
|
||||||
|
|
||||||
/* master zebra server structure */
|
/* master zebra server structure */
|
||||||
extern struct zebra_t zebrad;
|
extern struct zebra_t zebrad;
|
||||||
@ -77,44 +73,55 @@ router_id_bad_address (struct connected *ifc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
router_id_get (struct prefix *p)
|
router_id_get (struct prefix *p, vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
struct connected *c;
|
struct connected *c;
|
||||||
|
struct zebra_vrf *zvrf = vrf_info_get (vrf_id);
|
||||||
|
|
||||||
p->u.prefix4.s_addr = 0;
|
p->u.prefix4.s_addr = 0;
|
||||||
p->family = AF_INET;
|
p->family = AF_INET;
|
||||||
p->prefixlen = 32;
|
p->prefixlen = 32;
|
||||||
|
|
||||||
if (rid_user_assigned.u.prefix4.s_addr)
|
if (zvrf->rid_user_assigned.u.prefix4.s_addr)
|
||||||
p->u.prefix4.s_addr = rid_user_assigned.u.prefix4.s_addr;
|
p->u.prefix4.s_addr = zvrf->rid_user_assigned.u.prefix4.s_addr;
|
||||||
else if (!list_isempty (rid_lo_sorted_list))
|
else if (!list_isempty (zvrf->rid_lo_sorted_list))
|
||||||
{
|
{
|
||||||
node = listtail (rid_lo_sorted_list);
|
node = listtail (zvrf->rid_lo_sorted_list);
|
||||||
c = listgetdata (node);
|
c = listgetdata (node);
|
||||||
p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
|
p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
|
||||||
}
|
}
|
||||||
else if (!list_isempty (rid_all_sorted_list))
|
else if (!list_isempty (zvrf->rid_all_sorted_list))
|
||||||
{
|
{
|
||||||
node = listtail (rid_all_sorted_list);
|
node = listtail (zvrf->rid_all_sorted_list);
|
||||||
c = listgetdata (node);
|
c = listgetdata (node);
|
||||||
p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
|
p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
router_id_set (struct prefix *p)
|
router_id_set (struct prefix *p, vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
struct prefix p2;
|
struct prefix p2;
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
struct zserv *client;
|
struct zserv *client;
|
||||||
|
struct zebra_vrf *zvrf;
|
||||||
|
|
||||||
rid_user_assigned.u.prefix4.s_addr = p->u.prefix4.s_addr;
|
if (p->u.prefix4.s_addr == 0) /* unset */
|
||||||
|
{
|
||||||
|
zvrf = vrf_info_lookup (vrf_id);
|
||||||
|
if (! zvrf)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else /* set */
|
||||||
|
zvrf = vrf_info_get (vrf_id);
|
||||||
|
|
||||||
router_id_get (&p2);
|
zvrf->rid_user_assigned.u.prefix4.s_addr = p->u.prefix4.s_addr;
|
||||||
|
|
||||||
|
router_id_get (&p2, vrf_id);
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
|
for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
|
||||||
zsend_router_id_update (client, &p2);
|
zsend_router_id_update (client, &p2, vrf_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -125,28 +132,29 @@ router_id_add_address (struct connected *ifc)
|
|||||||
struct prefix before;
|
struct prefix before;
|
||||||
struct prefix after;
|
struct prefix after;
|
||||||
struct zserv *client;
|
struct zserv *client;
|
||||||
|
struct zebra_vrf *zvrf = vrf_info_get (ifc->ifp->vrf_id);
|
||||||
|
|
||||||
if (router_id_bad_address (ifc))
|
if (router_id_bad_address (ifc))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
router_id_get (&before);
|
router_id_get (&before, zvrf->vrf_id);
|
||||||
|
|
||||||
if (!strncmp (ifc->ifp->name, "lo", 2)
|
if (!strncmp (ifc->ifp->name, "lo", 2)
|
||||||
|| !strncmp (ifc->ifp->name, "dummy", 5))
|
|| !strncmp (ifc->ifp->name, "dummy", 5))
|
||||||
l = rid_lo_sorted_list;
|
l = zvrf->rid_lo_sorted_list;
|
||||||
else
|
else
|
||||||
l = rid_all_sorted_list;
|
l = zvrf->rid_all_sorted_list;
|
||||||
|
|
||||||
if (!router_id_find_node (l, ifc))
|
if (!router_id_find_node (l, ifc))
|
||||||
listnode_add_sort (l, ifc);
|
listnode_add_sort (l, ifc);
|
||||||
|
|
||||||
router_id_get (&after);
|
router_id_get (&after, zvrf->vrf_id);
|
||||||
|
|
||||||
if (prefix_same (&before, &after))
|
if (prefix_same (&before, &after))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
|
for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
|
||||||
zsend_router_id_update (client, &after);
|
zsend_router_id_update (client, &after, zvrf->vrf_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -158,36 +166,51 @@ router_id_del_address (struct connected *ifc)
|
|||||||
struct prefix before;
|
struct prefix before;
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
struct zserv *client;
|
struct zserv *client;
|
||||||
|
struct zebra_vrf *zvrf = vrf_info_get (ifc->ifp->vrf_id);
|
||||||
|
|
||||||
if (router_id_bad_address (ifc))
|
if (router_id_bad_address (ifc))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
router_id_get (&before);
|
router_id_get (&before, zvrf->vrf_id);
|
||||||
|
|
||||||
if (!strncmp (ifc->ifp->name, "lo", 2)
|
if (!strncmp (ifc->ifp->name, "lo", 2)
|
||||||
|| !strncmp (ifc->ifp->name, "dummy", 5))
|
|| !strncmp (ifc->ifp->name, "dummy", 5))
|
||||||
l = rid_lo_sorted_list;
|
l = zvrf->rid_lo_sorted_list;
|
||||||
else
|
else
|
||||||
l = rid_all_sorted_list;
|
l = zvrf->rid_all_sorted_list;
|
||||||
|
|
||||||
if ((c = router_id_find_node (l, ifc)))
|
if ((c = router_id_find_node (l, ifc)))
|
||||||
listnode_delete (l, c);
|
listnode_delete (l, c);
|
||||||
|
|
||||||
router_id_get (&after);
|
router_id_get (&after, zvrf->vrf_id);
|
||||||
|
|
||||||
if (prefix_same (&before, &after))
|
if (prefix_same (&before, &after))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
|
for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
|
||||||
zsend_router_id_update (client, &after);
|
zsend_router_id_update (client, &after, zvrf->vrf_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
router_id_write (struct vty *vty)
|
router_id_write (struct vty *vty)
|
||||||
{
|
{
|
||||||
if (rid_user_assigned.u.prefix4.s_addr)
|
struct zebra_vrf *zvrf;
|
||||||
vty_out (vty, "router-id %s%s", inet_ntoa (rid_user_assigned.u.prefix4),
|
vrf_iter_t iter;
|
||||||
VTY_NEWLINE);
|
|
||||||
|
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||||
|
if ((zvrf = vrf_iter2info (iter)) != NULL)
|
||||||
|
if (zvrf->rid_user_assigned.u.prefix4.s_addr)
|
||||||
|
{
|
||||||
|
if (zvrf->vrf_id == VRF_DEFAULT)
|
||||||
|
vty_out (vty, "router-id %s%s",
|
||||||
|
inet_ntoa (zvrf->rid_user_assigned.u.prefix4),
|
||||||
|
VTY_NEWLINE);
|
||||||
|
else
|
||||||
|
vty_out (vty, "router-id %s vrf %u%s",
|
||||||
|
inet_ntoa (zvrf->rid_user_assigned.u.prefix4),
|
||||||
|
zvrf->vrf_id,
|
||||||
|
VTY_NEWLINE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUN (router_id,
|
DEFUN (router_id,
|
||||||
@ -197,6 +220,7 @@ DEFUN (router_id,
|
|||||||
"IP address to use for router-id\n")
|
"IP address to use for router-id\n")
|
||||||
{
|
{
|
||||||
struct prefix rid;
|
struct prefix rid;
|
||||||
|
vrf_id_t vrf_id = VRF_DEFAULT;
|
||||||
|
|
||||||
rid.u.prefix4.s_addr = inet_addr (argv[0]);
|
rid.u.prefix4.s_addr = inet_addr (argv[0]);
|
||||||
if (!rid.u.prefix4.s_addr)
|
if (!rid.u.prefix4.s_addr)
|
||||||
@ -205,11 +229,21 @@ DEFUN (router_id,
|
|||||||
rid.prefixlen = 32;
|
rid.prefixlen = 32;
|
||||||
rid.family = AF_INET;
|
rid.family = AF_INET;
|
||||||
|
|
||||||
router_id_set (&rid);
|
if (argc > 1)
|
||||||
|
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[1]);
|
||||||
|
|
||||||
|
router_id_set (&rid, vrf_id);
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ALIAS (router_id,
|
||||||
|
router_id_vrf_cmd,
|
||||||
|
"router-id A.B.C.D " VRF_CMD_STR,
|
||||||
|
"Manually set the router-id\n"
|
||||||
|
"IP address to use for router-id\n"
|
||||||
|
VRF_CMD_HELP_STR)
|
||||||
|
|
||||||
DEFUN (no_router_id,
|
DEFUN (no_router_id,
|
||||||
no_router_id_cmd,
|
no_router_id_cmd,
|
||||||
"no router-id",
|
"no router-id",
|
||||||
@ -217,16 +251,27 @@ DEFUN (no_router_id,
|
|||||||
"Remove the manually configured router-id\n")
|
"Remove the manually configured router-id\n")
|
||||||
{
|
{
|
||||||
struct prefix rid;
|
struct prefix rid;
|
||||||
|
vrf_id_t vrf_id = VRF_DEFAULT;
|
||||||
|
|
||||||
rid.u.prefix4.s_addr = 0;
|
rid.u.prefix4.s_addr = 0;
|
||||||
rid.prefixlen = 0;
|
rid.prefixlen = 0;
|
||||||
rid.family = AF_INET;
|
rid.family = AF_INET;
|
||||||
|
|
||||||
router_id_set (&rid);
|
if (argc > 0)
|
||||||
|
VTY_GET_INTEGER ("VRF ID", vrf_id, argv[0]);
|
||||||
|
|
||||||
|
router_id_set (&rid, vrf_id);
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ALIAS (no_router_id,
|
||||||
|
no_router_id_vrf_cmd,
|
||||||
|
"no router-id " VRF_CMD_STR,
|
||||||
|
NO_STR
|
||||||
|
"Remove the manually configured router-id\n"
|
||||||
|
VRF_CMD_HELP_STR)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
router_id_cmp (void *a, void *b)
|
router_id_cmp (void *a, void *b)
|
||||||
{
|
{
|
||||||
@ -237,18 +282,27 @@ router_id_cmp (void *a, void *b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
router_id_init (void)
|
router_id_cmd_init (void)
|
||||||
{
|
{
|
||||||
install_element (CONFIG_NODE, &router_id_cmd);
|
install_element (CONFIG_NODE, &router_id_cmd);
|
||||||
install_element (CONFIG_NODE, &no_router_id_cmd);
|
install_element (CONFIG_NODE, &no_router_id_cmd);
|
||||||
|
install_element (CONFIG_NODE, &router_id_vrf_cmd);
|
||||||
memset (rid_all_sorted_list, 0, sizeof (_rid_all_sorted_list));
|
install_element (CONFIG_NODE, &no_router_id_vrf_cmd);
|
||||||
memset (rid_lo_sorted_list, 0, sizeof (_rid_lo_sorted_list));
|
}
|
||||||
memset (&rid_user_assigned, 0, sizeof (rid_user_assigned));
|
|
||||||
|
void
|
||||||
rid_all_sorted_list->cmp = router_id_cmp;
|
router_id_init (struct zebra_vrf *zvrf)
|
||||||
rid_lo_sorted_list->cmp = router_id_cmp;
|
{
|
||||||
|
zvrf->rid_all_sorted_list = &zvrf->_rid_all_sorted_list;
|
||||||
rid_user_assigned.family = AF_INET;
|
zvrf->rid_lo_sorted_list = &zvrf->_rid_lo_sorted_list;
|
||||||
rid_user_assigned.prefixlen = 32;
|
|
||||||
|
memset (zvrf->rid_all_sorted_list, 0, sizeof (zvrf->_rid_all_sorted_list));
|
||||||
|
memset (zvrf->rid_lo_sorted_list, 0, sizeof (zvrf->_rid_lo_sorted_list));
|
||||||
|
memset (&zvrf->rid_user_assigned, 0, sizeof (zvrf->rid_user_assigned));
|
||||||
|
|
||||||
|
zvrf->rid_all_sorted_list->cmp = router_id_cmp;
|
||||||
|
zvrf->rid_lo_sorted_list->cmp = router_id_cmp;
|
||||||
|
|
||||||
|
zvrf->rid_user_assigned.family = AF_INET;
|
||||||
|
zvrf->rid_user_assigned.prefixlen = 32;
|
||||||
}
|
}
|
||||||
|
@ -33,8 +33,9 @@
|
|||||||
|
|
||||||
extern void router_id_add_address(struct connected *);
|
extern void router_id_add_address(struct connected *);
|
||||||
extern void router_id_del_address(struct connected *);
|
extern void router_id_del_address(struct connected *);
|
||||||
extern void router_id_init(void);
|
extern void router_id_init(struct zebra_vrf *);
|
||||||
|
extern void router_id_cmd_init(void);
|
||||||
extern void router_id_write(struct vty *);
|
extern void router_id_write(struct vty *);
|
||||||
extern void router_id_get(struct prefix *);
|
extern void router_id_get(struct prefix *, vrf_id_t);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
#include "privs.h"
|
#include "privs.h"
|
||||||
#include "nexthop.h"
|
#include "nexthop.h"
|
||||||
|
#include "vrf.h"
|
||||||
|
|
||||||
#include "zebra/zserv.h"
|
#include "zebra/zserv.h"
|
||||||
#include "zebra/rt.h"
|
#include "zebra/rt.h"
|
||||||
@ -46,16 +47,6 @@
|
|||||||
|
|
||||||
#include "rt_netlink.h"
|
#include "rt_netlink.h"
|
||||||
|
|
||||||
/* Socket interface to kernel */
|
|
||||||
struct nlsock
|
|
||||||
{
|
|
||||||
int sock;
|
|
||||||
int seq;
|
|
||||||
struct sockaddr_nl snl;
|
|
||||||
const char *name;
|
|
||||||
} netlink = { -1, 0, {0}, "netlink-listen"}, /* kernel messages */
|
|
||||||
netlink_cmd = { -1, 0, {0}, "netlink-cmd"}; /* command channel */
|
|
||||||
|
|
||||||
static const struct message nlmsg_str[] = {
|
static const struct message nlmsg_str[] = {
|
||||||
{RTM_NEWROUTE, "RTM_NEWROUTE"},
|
{RTM_NEWROUTE, "RTM_NEWROUTE"},
|
||||||
{RTM_DELROUTE, "RTM_DELROUTE"},
|
{RTM_DELROUTE, "RTM_DELROUTE"},
|
||||||
@ -155,7 +146,7 @@ netlink_recvbuf (struct nlsock *nl, uint32_t newsize)
|
|||||||
|
|
||||||
/* Make socket for Linux netlink interface. */
|
/* Make socket for Linux netlink interface. */
|
||||||
static int
|
static int
|
||||||
netlink_socket (struct nlsock *nl, unsigned long groups)
|
netlink_socket (struct nlsock *nl, unsigned long groups, vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct sockaddr_nl snl;
|
struct sockaddr_nl snl;
|
||||||
@ -169,7 +160,7 @@ netlink_socket (struct nlsock *nl, unsigned long groups)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
sock = socket (AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
|
sock = vrf_socket (AF_NETLINK, SOCK_RAW, NETLINK_ROUTE, vrf_id);
|
||||||
if (sock < 0)
|
if (sock < 0)
|
||||||
{
|
{
|
||||||
zlog (NULL, LOG_ERR, "Can't open %s socket: %s", nl->name,
|
zlog (NULL, LOG_ERR, "Can't open %s socket: %s", nl->name,
|
||||||
@ -272,8 +263,9 @@ netlink_request (int family, int type, struct nlsock *nl)
|
|||||||
/* Receive message from netlink interface and pass those information
|
/* Receive message from netlink interface and pass those information
|
||||||
to the given function. */
|
to the given function. */
|
||||||
static int
|
static int
|
||||||
netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *),
|
netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *,
|
||||||
struct nlsock *nl)
|
vrf_id_t),
|
||||||
|
struct nlsock *nl, struct zebra_vrf *zvrf)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@ -362,7 +354,7 @@ netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *),
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Deal with errors that occur because of races in link handling */
|
/* Deal with errors that occur because of races in link handling */
|
||||||
if (nl == &netlink_cmd
|
if (nl == &zvrf->netlink_cmd
|
||||||
&& ((msg_type == RTM_DELROUTE &&
|
&& ((msg_type == RTM_DELROUTE &&
|
||||||
(-errnum == ENODEV || -errnum == ESRCH))
|
(-errnum == ENODEV || -errnum == ESRCH))
|
||||||
|| (msg_type == RTM_NEWROUTE && -errnum == EEXIST)))
|
|| (msg_type == RTM_NEWROUTE && -errnum == EEXIST)))
|
||||||
@ -375,7 +367,7 @@ netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *),
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nl == &netlink_cmd
|
if (nl == &zvrf->netlink_cmd
|
||||||
&& msg_type == RTM_NEWROUTE && -errnum == ESRCH)
|
&& msg_type == RTM_NEWROUTE && -errnum == ESRCH)
|
||||||
{
|
{
|
||||||
/* This is known to happen in some situations, don't log
|
/* This is known to happen in some situations, don't log
|
||||||
@ -406,16 +398,17 @@ netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *),
|
|||||||
/* skip unsolicited messages originating from command socket
|
/* skip unsolicited messages originating from command socket
|
||||||
* linux sets the originators port-id for {NEW|DEL}ADDR messages,
|
* linux sets the originators port-id for {NEW|DEL}ADDR messages,
|
||||||
* so this has to be checked here. */
|
* so this has to be checked here. */
|
||||||
if (nl != &netlink_cmd && h->nlmsg_pid == netlink_cmd.snl.nl_pid
|
if (nl != &zvrf->netlink_cmd
|
||||||
|
&& h->nlmsg_pid == zvrf->netlink_cmd.snl.nl_pid
|
||||||
&& (h->nlmsg_type != RTM_NEWADDR && h->nlmsg_type != RTM_DELADDR))
|
&& (h->nlmsg_type != RTM_NEWADDR && h->nlmsg_type != RTM_DELADDR))
|
||||||
{
|
{
|
||||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||||
zlog_debug ("netlink_parse_info: %s packet comes from %s",
|
zlog_debug ("netlink_parse_info: %s packet comes from %s",
|
||||||
netlink_cmd.name, nl->name);
|
zvrf->netlink_cmd.name, nl->name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = (*filter) (&snl, h);
|
error = (*filter) (&snl, h, zvrf->vrf_id);
|
||||||
if (error < 0)
|
if (error < 0)
|
||||||
{
|
{
|
||||||
zlog (NULL, LOG_ERR, "%s filter function error", nl->name);
|
zlog (NULL, LOG_ERR, "%s filter function error", nl->name);
|
||||||
@ -486,7 +479,8 @@ netlink_interface_update_hw_addr (struct rtattr **tb, struct interface *ifp)
|
|||||||
/* Called from interface_lookup_netlink(). This function is only used
|
/* Called from interface_lookup_netlink(). This function is only used
|
||||||
during bootstrap. */
|
during bootstrap. */
|
||||||
static int
|
static int
|
||||||
netlink_interface (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
netlink_interface (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||||
|
vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
struct ifinfomsg *ifi;
|
struct ifinfomsg *ifi;
|
||||||
@ -522,7 +516,7 @@ netlink_interface (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
|||||||
name = (char *) RTA_DATA (tb[IFLA_IFNAME]);
|
name = (char *) RTA_DATA (tb[IFLA_IFNAME]);
|
||||||
|
|
||||||
/* Add interface. */
|
/* Add interface. */
|
||||||
ifp = if_get_by_name (name);
|
ifp = if_get_by_name_vrf (name, vrf_id);
|
||||||
set_ifindex(ifp, ifi->ifi_index);
|
set_ifindex(ifp, ifi->ifi_index);
|
||||||
ifp->flags = ifi->ifi_flags & 0x0000fffff;
|
ifp->flags = ifi->ifi_flags & 0x0000fffff;
|
||||||
ifp->mtu6 = ifp->mtu = *(uint32_t *) RTA_DATA (tb[IFLA_MTU]);
|
ifp->mtu6 = ifp->mtu = *(uint32_t *) RTA_DATA (tb[IFLA_MTU]);
|
||||||
@ -539,7 +533,8 @@ netlink_interface (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
|||||||
|
|
||||||
/* Lookup interface IPv4/IPv6 address. */
|
/* Lookup interface IPv4/IPv6 address. */
|
||||||
static int
|
static int
|
||||||
netlink_interface_addr (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
netlink_interface_addr (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||||
|
vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
struct ifaddrmsg *ifa;
|
struct ifaddrmsg *ifa;
|
||||||
@ -569,19 +564,19 @@ netlink_interface_addr (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
|||||||
memset (tb, 0, sizeof tb);
|
memset (tb, 0, sizeof tb);
|
||||||
netlink_parse_rtattr (tb, IFA_MAX, IFA_RTA (ifa), len);
|
netlink_parse_rtattr (tb, IFA_MAX, IFA_RTA (ifa), len);
|
||||||
|
|
||||||
ifp = if_lookup_by_index (ifa->ifa_index);
|
ifp = if_lookup_by_index_vrf (ifa->ifa_index, vrf_id);
|
||||||
if (ifp == NULL)
|
if (ifp == NULL)
|
||||||
{
|
{
|
||||||
zlog_err ("netlink_interface_addr can't find interface by index %d",
|
zlog_err ("netlink_interface_addr can't find interface by index %d vrf %u",
|
||||||
ifa->ifa_index);
|
ifa->ifa_index, vrf_id);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_KERNEL) /* remove this line to see initial ifcfg */
|
if (IS_ZEBRA_DEBUG_KERNEL) /* remove this line to see initial ifcfg */
|
||||||
{
|
{
|
||||||
char buf[BUFSIZ];
|
char buf[BUFSIZ];
|
||||||
zlog_debug ("netlink_interface_addr %s %s:",
|
zlog_debug ("netlink_interface_addr %s %s vrf %u:",
|
||||||
lookup (nlmsg_str, h->nlmsg_type), ifp->name);
|
lookup (nlmsg_str, h->nlmsg_type), ifp->name, vrf_id);
|
||||||
if (tb[IFA_LOCAL])
|
if (tb[IFA_LOCAL])
|
||||||
zlog_debug (" IFA_LOCAL %s/%d",
|
zlog_debug (" IFA_LOCAL %s/%d",
|
||||||
inet_ntop (ifa->ifa_family, RTA_DATA (tb[IFA_LOCAL]),
|
inet_ntop (ifa->ifa_family, RTA_DATA (tb[IFA_LOCAL]),
|
||||||
@ -674,7 +669,8 @@ netlink_interface_addr (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
|||||||
|
|
||||||
/* Looking up routing table by netlink interface. */
|
/* Looking up routing table by netlink interface. */
|
||||||
static int
|
static int
|
||||||
netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||||
|
vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
struct rtmsg *rtm;
|
struct rtmsg *rtm;
|
||||||
@ -755,7 +751,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
|||||||
|
|
||||||
if (!tb[RTA_MULTIPATH])
|
if (!tb[RTA_MULTIPATH])
|
||||||
rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, flags, &p, gate, src, index,
|
rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, flags, &p, gate, src, index,
|
||||||
table, metric, 0, SAFI_UNICAST);
|
vrf_id, table, metric, 0, SAFI_UNICAST);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* This is a multipath route */
|
/* This is a multipath route */
|
||||||
@ -771,6 +767,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
|||||||
rib->distance = 0;
|
rib->distance = 0;
|
||||||
rib->flags = flags;
|
rib->flags = flags;
|
||||||
rib->metric = metric;
|
rib->metric = metric;
|
||||||
|
rib->vrf_id = vrf_id;
|
||||||
rib->table = table;
|
rib->table = table;
|
||||||
rib->nexthop_num = 0;
|
rib->nexthop_num = 0;
|
||||||
rib->uptime = time (NULL);
|
rib->uptime = time (NULL);
|
||||||
@ -821,8 +818,8 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
|||||||
memcpy (&p.prefix, dest, 16);
|
memcpy (&p.prefix, dest, 16);
|
||||||
p.prefixlen = rtm->rtm_dst_len;
|
p.prefixlen = rtm->rtm_dst_len;
|
||||||
|
|
||||||
rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, 0, flags, &p, gate, index, table,
|
rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, 0, flags, &p, gate, index, vrf_id,
|
||||||
metric, 0, SAFI_UNICAST);
|
table, metric, 0, SAFI_UNICAST);
|
||||||
}
|
}
|
||||||
#endif /* HAVE_IPV6 */
|
#endif /* HAVE_IPV6 */
|
||||||
|
|
||||||
@ -846,7 +843,8 @@ static const struct message rtproto_str[] = {
|
|||||||
|
|
||||||
/* Routing information change from the kernel. */
|
/* Routing information change from the kernel. */
|
||||||
static int
|
static int
|
||||||
netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||||
|
vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
struct rtmsg *rtm;
|
struct rtmsg *rtm;
|
||||||
@ -868,18 +866,19 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
|||||||
if (!(h->nlmsg_type == RTM_NEWROUTE || h->nlmsg_type == RTM_DELROUTE))
|
if (!(h->nlmsg_type == RTM_NEWROUTE || h->nlmsg_type == RTM_DELROUTE))
|
||||||
{
|
{
|
||||||
/* If this is not route add/delete message print warning. */
|
/* If this is not route add/delete message print warning. */
|
||||||
zlog_warn ("Kernel message: %d\n", h->nlmsg_type);
|
zlog_warn ("Kernel message: %d vrf %u\n", h->nlmsg_type, vrf_id);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Connected route. */
|
/* Connected route. */
|
||||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||||
zlog_debug ("%s %s %s proto %s",
|
zlog_debug ("%s %s %s proto %s vrf %u",
|
||||||
h->nlmsg_type ==
|
h->nlmsg_type ==
|
||||||
RTM_NEWROUTE ? "RTM_NEWROUTE" : "RTM_DELROUTE",
|
RTM_NEWROUTE ? "RTM_NEWROUTE" : "RTM_DELROUTE",
|
||||||
rtm->rtm_family == AF_INET ? "ipv4" : "ipv6",
|
rtm->rtm_family == AF_INET ? "ipv4" : "ipv6",
|
||||||
rtm->rtm_type == RTN_UNICAST ? "unicast" : "multicast",
|
rtm->rtm_type == RTN_UNICAST ? "unicast" : "multicast",
|
||||||
lookup (rtproto_str, rtm->rtm_protocol));
|
lookup (rtproto_str, rtm->rtm_protocol),
|
||||||
|
vrf_id);
|
||||||
|
|
||||||
if (rtm->rtm_type != RTN_UNICAST)
|
if (rtm->rtm_type != RTN_UNICAST)
|
||||||
{
|
{
|
||||||
@ -911,7 +910,7 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
|||||||
|
|
||||||
if (rtm->rtm_src_len != 0)
|
if (rtm->rtm_src_len != 0)
|
||||||
{
|
{
|
||||||
zlog_warn ("netlink_route_change(): no src len");
|
zlog_warn ("netlink_route_change(): no src len, vrf %u", vrf_id);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -947,19 +946,17 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
|||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||||
{
|
{
|
||||||
if (h->nlmsg_type == RTM_NEWROUTE)
|
char buf[BUFSIZ];
|
||||||
zlog_debug ("RTM_NEWROUTE %s/%d",
|
zlog_debug ("%s %s vrf %u",
|
||||||
inet_ntoa (p.prefix), p.prefixlen);
|
h->nlmsg_type == RTM_NEWROUTE ? "RTM_NEWROUTE" : "RTM_DELROUTE",
|
||||||
else
|
prefix2str (&p, buf, sizeof(buf)), vrf_id);
|
||||||
zlog_debug ("RTM_DELROUTE %s/%d",
|
|
||||||
inet_ntoa (p.prefix), p.prefixlen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (h->nlmsg_type == RTM_NEWROUTE)
|
if (h->nlmsg_type == RTM_NEWROUTE)
|
||||||
{
|
{
|
||||||
if (!tb[RTA_MULTIPATH])
|
if (!tb[RTA_MULTIPATH])
|
||||||
rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, 0, &p, gate, src, index, table,
|
rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, 0, &p, gate, src, index, vrf_id,
|
||||||
metric, 0, SAFI_UNICAST);
|
table, metric, 0, SAFI_UNICAST);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* This is a multipath route */
|
/* This is a multipath route */
|
||||||
@ -975,6 +972,7 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
|||||||
rib->distance = 0;
|
rib->distance = 0;
|
||||||
rib->flags = 0;
|
rib->flags = 0;
|
||||||
rib->metric = metric;
|
rib->metric = metric;
|
||||||
|
rib->vrf_id = vrf_id;
|
||||||
rib->table = table;
|
rib->table = table;
|
||||||
rib->nexthop_num = 0;
|
rib->nexthop_num = 0;
|
||||||
rib->uptime = time (NULL);
|
rib->uptime = time (NULL);
|
||||||
@ -1020,7 +1018,7 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, gate, index,
|
rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, gate, index,
|
||||||
table, SAFI_UNICAST);
|
vrf_id, table, SAFI_UNICAST);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
@ -1035,21 +1033,17 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
|||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||||
{
|
{
|
||||||
if (h->nlmsg_type == RTM_NEWROUTE)
|
zlog_debug ("%s %s vrf %u",
|
||||||
zlog_debug ("RTM_NEWROUTE %s/%d",
|
h->nlmsg_type == RTM_NEWROUTE ? "RTM_NEWROUTE" : "RTM_DELROUTE",
|
||||||
inet_ntop (AF_INET6, &p.prefix, buf, BUFSIZ),
|
prefix2str (&p, buf, sizeof(buf)), vrf_id);
|
||||||
p.prefixlen);
|
|
||||||
else
|
|
||||||
zlog_debug ("RTM_DELROUTE %s/%d",
|
|
||||||
inet_ntop (AF_INET6, &p.prefix, buf, BUFSIZ),
|
|
||||||
p.prefixlen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (h->nlmsg_type == RTM_NEWROUTE)
|
if (h->nlmsg_type == RTM_NEWROUTE)
|
||||||
rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, 0, 0, &p, gate, index, table, metric, 0, SAFI_UNICAST);
|
rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, 0, 0, &p, gate, index, vrf_id,
|
||||||
|
table, metric, 0, SAFI_UNICAST);
|
||||||
else
|
else
|
||||||
rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, gate, index,
|
rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, gate, index,
|
||||||
table, SAFI_UNICAST);
|
vrf_id, table, SAFI_UNICAST);
|
||||||
}
|
}
|
||||||
#endif /* HAVE_IPV6 */
|
#endif /* HAVE_IPV6 */
|
||||||
|
|
||||||
@ -1057,7 +1051,8 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||||
|
vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
struct ifinfomsg *ifi;
|
struct ifinfomsg *ifi;
|
||||||
@ -1070,8 +1065,8 @@ netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
|||||||
if (!(h->nlmsg_type == RTM_NEWLINK || h->nlmsg_type == RTM_DELLINK))
|
if (!(h->nlmsg_type == RTM_NEWLINK || h->nlmsg_type == RTM_DELLINK))
|
||||||
{
|
{
|
||||||
/* If this is not link add/delete message so print warning. */
|
/* If this is not link add/delete message so print warning. */
|
||||||
zlog_warn ("netlink_link_change: wrong kernel message %d\n",
|
zlog_warn ("netlink_link_change: wrong kernel message %d vrf %u\n",
|
||||||
h->nlmsg_type);
|
h->nlmsg_type, vrf_id);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1088,7 +1083,8 @@ netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
|||||||
if ((tb[IFLA_WIRELESS] != NULL) && (ifi->ifi_change == 0))
|
if ((tb[IFLA_WIRELESS] != NULL) && (ifi->ifi_change == 0))
|
||||||
{
|
{
|
||||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||||
zlog_debug ("%s: ignoring IFLA_WIRELESS message", __func__);
|
zlog_debug ("%s: ignoring IFLA_WIRELESS message, vrf %u", __func__,
|
||||||
|
vrf_id);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* IFLA_WIRELESS */
|
#endif /* IFLA_WIRELESS */
|
||||||
@ -1100,12 +1096,12 @@ netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
|||||||
/* Add interface. */
|
/* Add interface. */
|
||||||
if (h->nlmsg_type == RTM_NEWLINK)
|
if (h->nlmsg_type == RTM_NEWLINK)
|
||||||
{
|
{
|
||||||
ifp = if_lookup_by_name (name);
|
ifp = if_lookup_by_name_vrf (name, vrf_id);
|
||||||
|
|
||||||
if (ifp == NULL || !CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
|
if (ifp == NULL || !CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
|
||||||
{
|
{
|
||||||
if (ifp == NULL)
|
if (ifp == NULL)
|
||||||
ifp = if_get_by_name (name);
|
ifp = if_get_by_name_vrf (name, vrf_id);
|
||||||
|
|
||||||
set_ifindex(ifp, ifi->ifi_index);
|
set_ifindex(ifp, ifi->ifi_index);
|
||||||
ifp->flags = ifi->ifi_flags & 0x0000fffff;
|
ifp->flags = ifi->ifi_flags & 0x0000fffff;
|
||||||
@ -1146,12 +1142,12 @@ netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* RTM_DELLINK. */
|
/* RTM_DELLINK. */
|
||||||
ifp = if_lookup_by_name (name);
|
ifp = if_lookup_by_name_vrf (name, vrf_id);
|
||||||
|
|
||||||
if (ifp == NULL)
|
if (ifp == NULL)
|
||||||
{
|
{
|
||||||
zlog (NULL, LOG_WARNING, "interface %s is deleted but can't find",
|
zlog_warn ("interface %s vrf %u is deleted but can't find",
|
||||||
name);
|
name, vrf_id);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1162,7 +1158,8 @@ netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
netlink_information_fetch (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
netlink_information_fetch (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||||
|
vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
/* JF: Ignore messages that aren't from the kernel */
|
/* JF: Ignore messages that aren't from the kernel */
|
||||||
if ( snl->nl_pid != 0 )
|
if ( snl->nl_pid != 0 )
|
||||||
@ -1174,25 +1171,26 @@ netlink_information_fetch (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
|||||||
switch (h->nlmsg_type)
|
switch (h->nlmsg_type)
|
||||||
{
|
{
|
||||||
case RTM_NEWROUTE:
|
case RTM_NEWROUTE:
|
||||||
return netlink_route_change (snl, h);
|
return netlink_route_change (snl, h, vrf_id);
|
||||||
break;
|
break;
|
||||||
case RTM_DELROUTE:
|
case RTM_DELROUTE:
|
||||||
return netlink_route_change (snl, h);
|
return netlink_route_change (snl, h, vrf_id);
|
||||||
break;
|
break;
|
||||||
case RTM_NEWLINK:
|
case RTM_NEWLINK:
|
||||||
return netlink_link_change (snl, h);
|
return netlink_link_change (snl, h, vrf_id);
|
||||||
break;
|
break;
|
||||||
case RTM_DELLINK:
|
case RTM_DELLINK:
|
||||||
return netlink_link_change (snl, h);
|
return netlink_link_change (snl, h, vrf_id);
|
||||||
break;
|
break;
|
||||||
case RTM_NEWADDR:
|
case RTM_NEWADDR:
|
||||||
return netlink_interface_addr (snl, h);
|
return netlink_interface_addr (snl, h, vrf_id);
|
||||||
break;
|
break;
|
||||||
case RTM_DELADDR:
|
case RTM_DELADDR:
|
||||||
return netlink_interface_addr (snl, h);
|
return netlink_interface_addr (snl, h, vrf_id);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
zlog_warn ("Unknown netlink nlmsg_type %d\n", h->nlmsg_type);
|
zlog_warn ("Unknown netlink nlmsg_type %d vrf %u\n", h->nlmsg_type,
|
||||||
|
vrf_id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -1200,32 +1198,32 @@ netlink_information_fetch (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
|||||||
|
|
||||||
/* Interface lookup by netlink socket. */
|
/* Interface lookup by netlink socket. */
|
||||||
int
|
int
|
||||||
interface_lookup_netlink (void)
|
interface_lookup_netlink (struct zebra_vrf *zvrf)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Get interface information. */
|
/* Get interface information. */
|
||||||
ret = netlink_request (AF_PACKET, RTM_GETLINK, &netlink_cmd);
|
ret = netlink_request (AF_PACKET, RTM_GETLINK, &zvrf->netlink_cmd);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
ret = netlink_parse_info (netlink_interface, &netlink_cmd);
|
ret = netlink_parse_info (netlink_interface, &zvrf->netlink_cmd, zvrf);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* Get IPv4 address of the interfaces. */
|
/* Get IPv4 address of the interfaces. */
|
||||||
ret = netlink_request (AF_INET, RTM_GETADDR, &netlink_cmd);
|
ret = netlink_request (AF_INET, RTM_GETADDR, &zvrf->netlink_cmd);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
ret = netlink_parse_info (netlink_interface_addr, &netlink_cmd);
|
ret = netlink_parse_info (netlink_interface_addr, &zvrf->netlink_cmd, zvrf);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
/* Get IPv6 address of the interfaces. */
|
/* Get IPv6 address of the interfaces. */
|
||||||
ret = netlink_request (AF_INET6, RTM_GETADDR, &netlink_cmd);
|
ret = netlink_request (AF_INET6, RTM_GETADDR, &zvrf->netlink_cmd);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
ret = netlink_parse_info (netlink_interface_addr, &netlink_cmd);
|
ret = netlink_parse_info (netlink_interface_addr, &zvrf->netlink_cmd, zvrf);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
#endif /* HAVE_IPV6 */
|
#endif /* HAVE_IPV6 */
|
||||||
@ -1236,24 +1234,24 @@ interface_lookup_netlink (void)
|
|||||||
/* Routing table read function using netlink interface. Only called
|
/* Routing table read function using netlink interface. Only called
|
||||||
bootstrap time. */
|
bootstrap time. */
|
||||||
int
|
int
|
||||||
netlink_route_read (void)
|
netlink_route_read (struct zebra_vrf *zvrf)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Get IPv4 routing table. */
|
/* Get IPv4 routing table. */
|
||||||
ret = netlink_request (AF_INET, RTM_GETROUTE, &netlink_cmd);
|
ret = netlink_request (AF_INET, RTM_GETROUTE, &zvrf->netlink_cmd);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
ret = netlink_parse_info (netlink_routing_table, &netlink_cmd);
|
ret = netlink_parse_info (netlink_routing_table, &zvrf->netlink_cmd, zvrf);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
/* Get IPv6 routing table. */
|
/* Get IPv6 routing table. */
|
||||||
ret = netlink_request (AF_INET6, RTM_GETROUTE, &netlink_cmd);
|
ret = netlink_request (AF_INET6, RTM_GETROUTE, &zvrf->netlink_cmd);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
ret = netlink_parse_info (netlink_routing_table, &netlink_cmd);
|
ret = netlink_parse_info (netlink_routing_table, &zvrf->netlink_cmd, zvrf);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
#endif /* HAVE_IPV6 */
|
#endif /* HAVE_IPV6 */
|
||||||
@ -1326,15 +1324,17 @@ addattr32 (struct nlmsghdr *n, unsigned int maxlen, int type, int data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
netlink_talk_filter (struct sockaddr_nl *snl, struct nlmsghdr *h)
|
netlink_talk_filter (struct sockaddr_nl *snl, struct nlmsghdr *h,
|
||||||
|
vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
zlog_warn ("netlink_talk: ignoring message type 0x%04x", h->nlmsg_type);
|
zlog_warn ("netlink_talk: ignoring message type 0x%04x vrf %u", h->nlmsg_type,
|
||||||
|
vrf_id);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sendmsg() to netlink socket then recvmsg(). */
|
/* sendmsg() to netlink socket then recvmsg(). */
|
||||||
static int
|
static int
|
||||||
netlink_talk (struct nlmsghdr *n, struct nlsock *nl)
|
netlink_talk (struct nlmsghdr *n, struct nlsock *nl, struct zebra_vrf *zvrf)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
struct sockaddr_nl snl;
|
struct sockaddr_nl snl;
|
||||||
@ -1384,7 +1384,7 @@ netlink_talk (struct nlmsghdr *n, struct nlsock *nl)
|
|||||||
* Get reply from netlink socket.
|
* Get reply from netlink socket.
|
||||||
* The reply should either be an acknowlegement or an error.
|
* The reply should either be an acknowlegement or an error.
|
||||||
*/
|
*/
|
||||||
return netlink_parse_info (netlink_talk_filter, nl);
|
return netlink_parse_info (netlink_talk_filter, nl, zvrf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Routing table change via netlink interface. */
|
/* Routing table change via netlink interface. */
|
||||||
@ -1397,6 +1397,8 @@ netlink_route (int cmd, int family, void *dest, int length, void *gate,
|
|||||||
struct sockaddr_nl snl;
|
struct sockaddr_nl snl;
|
||||||
int discard;
|
int discard;
|
||||||
|
|
||||||
|
struct zebra_vrf *zvrf = vrf_info_lookup (VRF_DEFAULT); //Pending
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
struct nlmsghdr n;
|
struct nlmsghdr n;
|
||||||
@ -1458,7 +1460,7 @@ netlink_route (int cmd, int family, void *dest, int length, void *gate,
|
|||||||
snl.nl_family = AF_NETLINK;
|
snl.nl_family = AF_NETLINK;
|
||||||
|
|
||||||
/* Talk to netlink socket. */
|
/* Talk to netlink socket. */
|
||||||
ret = netlink_talk (&req.n, &netlink_cmd);
|
ret = netlink_talk (&req.n, &zvrf->netlink_cmd, VRF_DEFAULT);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -1759,11 +1761,12 @@ _netlink_route_debug(
|
|||||||
struct prefix *p,
|
struct prefix *p,
|
||||||
struct nexthop *nexthop,
|
struct nexthop *nexthop,
|
||||||
const char *routedesc,
|
const char *routedesc,
|
||||||
int family)
|
int family,
|
||||||
|
struct zebra_vrf *zvrf)
|
||||||
{
|
{
|
||||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||||
{
|
{
|
||||||
zlog_debug ("netlink_route_multipath() (%s): %s %s/%d type %s",
|
zlog_debug ("netlink_route_multipath() (%s): %s %s/%d vrf %u type %s",
|
||||||
routedesc,
|
routedesc,
|
||||||
lookup (nlmsg_str, cmd),
|
lookup (nlmsg_str, cmd),
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
@ -1772,7 +1775,7 @@ _netlink_route_debug(
|
|||||||
#else
|
#else
|
||||||
inet_ntoa (p->u.prefix4),
|
inet_ntoa (p->u.prefix4),
|
||||||
#endif /* HAVE_IPV6 */
|
#endif /* HAVE_IPV6 */
|
||||||
p->prefixlen, nexthop_type_to_str (nexthop->type));
|
p->prefixlen, zvrf->vrf_id, nexthop_type_to_str (nexthop->type));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1785,6 +1788,8 @@ netlink_neigh_update (int cmd, int ifindex, __u32 addr, char *lla, int llalen)
|
|||||||
char buf[256];
|
char buf[256];
|
||||||
} req;
|
} req;
|
||||||
|
|
||||||
|
struct zebra_vrf *zvrf = vrf_info_lookup (VRF_DEFAULT); //Pending
|
||||||
|
|
||||||
memset(&req.n, 0, sizeof(req.n));
|
memset(&req.n, 0, sizeof(req.n));
|
||||||
memset(&req.ndm, 0, sizeof(req.ndm));
|
memset(&req.ndm, 0, sizeof(req.ndm));
|
||||||
|
|
||||||
@ -1799,7 +1804,7 @@ netlink_neigh_update (int cmd, int ifindex, __u32 addr, char *lla, int llalen)
|
|||||||
addattr_l(&req.n, sizeof(req), NDA_DST, &addr, 4);
|
addattr_l(&req.n, sizeof(req), NDA_DST, &addr, 4);
|
||||||
addattr_l(&req.n, sizeof(req), NDA_LLADDR, lla, llalen);
|
addattr_l(&req.n, sizeof(req), NDA_LLADDR, lla, llalen);
|
||||||
|
|
||||||
return netlink_talk (&req.n, &netlink_cmd);
|
return netlink_talk (&req.n, &zvrf->netlink_cmd, VRF_DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Routing table change via netlink interface. */
|
/* Routing table change via netlink interface. */
|
||||||
@ -1825,6 +1830,8 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
|
|||||||
char buf[NL_PKT_BUF_SIZE];
|
char buf[NL_PKT_BUF_SIZE];
|
||||||
} req;
|
} req;
|
||||||
|
|
||||||
|
struct zebra_vrf *zvrf = vrf_info_lookup (rib->vrf_id);
|
||||||
|
|
||||||
memset (&req, 0, sizeof req - NL_PKT_BUF_SIZE);
|
memset (&req, 0, sizeof req - NL_PKT_BUF_SIZE);
|
||||||
|
|
||||||
bytelen = (family == AF_INET ? 4 : 16);
|
bytelen = (family == AF_INET ? 4 : 16);
|
||||||
@ -1946,7 +1953,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
|
|||||||
{
|
{
|
||||||
routedesc = recursing ? "recursive, 1 hop" : "single hop";
|
routedesc = recursing ? "recursive, 1 hop" : "single hop";
|
||||||
|
|
||||||
_netlink_route_debug(cmd, p, nexthop, routedesc, family);
|
_netlink_route_debug(cmd, p, nexthop, routedesc, family, zvrf);
|
||||||
_netlink_route_build_singlepath(routedesc, bytelen,
|
_netlink_route_build_singlepath(routedesc, bytelen,
|
||||||
nexthop, &req.n, &req.r,
|
nexthop, &req.n, &req.r,
|
||||||
sizeof req, cmd);
|
sizeof req, cmd);
|
||||||
@ -2027,7 +2034,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
|
|||||||
nexthop_num++;
|
nexthop_num++;
|
||||||
|
|
||||||
_netlink_route_debug(cmd, p, nexthop,
|
_netlink_route_debug(cmd, p, nexthop,
|
||||||
routedesc, family);
|
routedesc, family, zvrf);
|
||||||
_netlink_route_build_multipath(routedesc, bytelen,
|
_netlink_route_build_multipath(routedesc, bytelen,
|
||||||
nexthop, rta, rtnh, &req.r, &src1);
|
nexthop, rta, rtnh, &req.r, &src1);
|
||||||
rtnh = RTNH_NEXT (rtnh);
|
rtnh = RTNH_NEXT (rtnh);
|
||||||
@ -2075,7 +2082,7 @@ skip:
|
|||||||
snl.nl_family = AF_NETLINK;
|
snl.nl_family = AF_NETLINK;
|
||||||
|
|
||||||
/* Talk to netlink socket. */
|
/* Talk to netlink socket. */
|
||||||
return netlink_talk (&req.n, &netlink_cmd);
|
return netlink_talk (&req.n, &zvrf->netlink_cmd, zvrf);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -2138,6 +2145,8 @@ netlink_address (int cmd, int family, struct interface *ifp,
|
|||||||
char buf[NL_PKT_BUF_SIZE];
|
char buf[NL_PKT_BUF_SIZE];
|
||||||
} req;
|
} req;
|
||||||
|
|
||||||
|
struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id);
|
||||||
|
|
||||||
p = ifc->address;
|
p = ifc->address;
|
||||||
memset (&req, 0, sizeof req - NL_PKT_BUF_SIZE);
|
memset (&req, 0, sizeof req - NL_PKT_BUF_SIZE);
|
||||||
|
|
||||||
@ -2170,7 +2179,7 @@ netlink_address (int cmd, int family, struct interface *ifp,
|
|||||||
addattr_l (&req.n, sizeof req, IFA_LABEL, ifc->label,
|
addattr_l (&req.n, sizeof req, IFA_LABEL, ifc->label,
|
||||||
strlen (ifc->label) + 1);
|
strlen (ifc->label) + 1);
|
||||||
|
|
||||||
return netlink_talk (&req.n, &netlink_cmd);
|
return netlink_talk (&req.n, &zvrf->netlink_cmd, zvrf);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -2192,8 +2201,10 @@ extern struct thread_master *master;
|
|||||||
static int
|
static int
|
||||||
kernel_read (struct thread *thread)
|
kernel_read (struct thread *thread)
|
||||||
{
|
{
|
||||||
netlink_parse_info (netlink_information_fetch, &netlink);
|
struct zebra_vrf *zvrf = (struct zebra_vrf *)THREAD_ARG (thread);
|
||||||
thread_add_read (zebrad.master, kernel_read, NULL, netlink.sock);
|
netlink_parse_info (netlink_information_fetch, &zvrf->netlink, zvrf);
|
||||||
|
zvrf->t_netlink = thread_add_read (zebrad.master, kernel_read, zvrf,
|
||||||
|
zvrf->netlink.sock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -2232,7 +2243,7 @@ static void netlink_install_filter (int sock, __u32 pid)
|
|||||||
/* Exported interface function. This function simply calls
|
/* Exported interface function. This function simply calls
|
||||||
netlink_socket (). */
|
netlink_socket (). */
|
||||||
void
|
void
|
||||||
kernel_init (void)
|
kernel_init (struct zebra_vrf *zvrf)
|
||||||
{
|
{
|
||||||
unsigned long groups;
|
unsigned long groups;
|
||||||
|
|
||||||
@ -2240,23 +2251,42 @@ kernel_init (void)
|
|||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
groups |= RTMGRP_IPV6_ROUTE | RTMGRP_IPV6_IFADDR;
|
groups |= RTMGRP_IPV6_ROUTE | RTMGRP_IPV6_IFADDR;
|
||||||
#endif /* HAVE_IPV6 */
|
#endif /* HAVE_IPV6 */
|
||||||
netlink_socket (&netlink, groups);
|
netlink_socket (&zvrf->netlink, groups, zvrf->vrf_id);
|
||||||
netlink_socket (&netlink_cmd, 0);
|
netlink_socket (&zvrf->netlink_cmd, 0, zvrf->vrf_id);
|
||||||
|
|
||||||
/* Register kernel socket. */
|
/* Register kernel socket. */
|
||||||
if (netlink.sock > 0)
|
if (zvrf->netlink.sock > 0)
|
||||||
{
|
{
|
||||||
/* Only want non-blocking on the netlink event socket */
|
/* Only want non-blocking on the netlink event socket */
|
||||||
if (fcntl (netlink.sock, F_SETFL, O_NONBLOCK) < 0)
|
if (fcntl (zvrf->netlink.sock, F_SETFL, O_NONBLOCK) < 0)
|
||||||
zlog (NULL, LOG_ERR, "Can't set %s socket flags: %s", netlink.name,
|
zlog_err ("Can't set %s socket flags: %s", zvrf->netlink.name,
|
||||||
safe_strerror (errno));
|
safe_strerror (errno));
|
||||||
|
|
||||||
/* Set receive buffer size if it's set from command line */
|
/* Set receive buffer size if it's set from command line */
|
||||||
if (nl_rcvbufsize)
|
if (nl_rcvbufsize)
|
||||||
netlink_recvbuf (&netlink, nl_rcvbufsize);
|
netlink_recvbuf (&zvrf->netlink, nl_rcvbufsize);
|
||||||
|
|
||||||
netlink_install_filter (netlink.sock, netlink_cmd.snl.nl_pid);
|
netlink_install_filter (zvrf->netlink.sock, zvrf->netlink_cmd.snl.nl_pid);
|
||||||
thread_add_read (zebrad.master, kernel_read, NULL, netlink.sock);
|
zvrf->t_netlink = thread_add_read (zebrad.master, kernel_read, zvrf,
|
||||||
|
zvrf->netlink.sock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
kernel_terminate (struct zebra_vrf *zvrf)
|
||||||
|
{
|
||||||
|
THREAD_READ_OFF (zvrf->t_netlink);
|
||||||
|
|
||||||
|
if (zvrf->netlink.sock >= 0)
|
||||||
|
{
|
||||||
|
close (zvrf->netlink.sock);
|
||||||
|
zvrf->netlink.sock = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zvrf->netlink_cmd.sock >= 0)
|
||||||
|
{
|
||||||
|
close (zvrf->netlink_cmd.sock);
|
||||||
|
zvrf->netlink_cmd.sock = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,8 +44,8 @@ nl_rtproto_to_str (u_char rtproto);
|
|||||||
int
|
int
|
||||||
netlink_neigh_update (int cmd, int ifindex, __u32 addr, char *lla, int llalen);
|
netlink_neigh_update (int cmd, int ifindex, __u32 addr, char *lla, int llalen);
|
||||||
|
|
||||||
extern int netlink_route_read(void);
|
extern int interface_lookup_netlink (struct zebra_vrf *zvrf);
|
||||||
extern int interface_lookup_netlink(void);
|
extern int netlink_route_read (struct zebra_vrf *zvrf);
|
||||||
|
|
||||||
#endif /* HAVE_NETLINK */
|
#endif /* HAVE_NETLINK */
|
||||||
|
|
||||||
|
146
zebra/rtadv.c
146
zebra/rtadv.c
@ -31,6 +31,7 @@
|
|||||||
#include "linklist.h"
|
#include "linklist.h"
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
#include "privs.h"
|
#include "privs.h"
|
||||||
|
#include "vrf.h"
|
||||||
|
|
||||||
#include "zebra/interface.h"
|
#include "zebra/interface.h"
|
||||||
#include "zebra/rtadv.h"
|
#include "zebra/rtadv.h"
|
||||||
@ -62,31 +63,11 @@ extern struct zebra_t zebrad;
|
|||||||
enum rtadv_event {RTADV_START, RTADV_STOP, RTADV_TIMER,
|
enum rtadv_event {RTADV_START, RTADV_STOP, RTADV_TIMER,
|
||||||
RTADV_TIMER_MSEC, RTADV_READ};
|
RTADV_TIMER_MSEC, RTADV_READ};
|
||||||
|
|
||||||
static void rtadv_event (enum rtadv_event, int);
|
static void rtadv_event (struct zebra_vrf *, enum rtadv_event, int);
|
||||||
|
|
||||||
static int if_join_all_router (int, struct interface *);
|
static int if_join_all_router (int, struct interface *);
|
||||||
static int if_leave_all_router (int, struct interface *);
|
static int if_leave_all_router (int, struct interface *);
|
||||||
|
|
||||||
/* Structure which hold status of router advertisement. */
|
|
||||||
struct rtadv
|
|
||||||
{
|
|
||||||
int sock;
|
|
||||||
|
|
||||||
int adv_if_count;
|
|
||||||
int adv_msec_if_count;
|
|
||||||
|
|
||||||
struct thread *ra_read;
|
|
||||||
struct thread *ra_timer;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct rtadv *rtadv = NULL;
|
|
||||||
|
|
||||||
static struct rtadv *
|
|
||||||
rtadv_new (void)
|
|
||||||
{
|
|
||||||
return XCALLOC (MTYPE_TMP, sizeof (struct rtadv));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
rtadv_recv_packet (int sock, u_char *buf, int buflen,
|
rtadv_recv_packet (int sock, u_char *buf, int buflen,
|
||||||
struct sockaddr_in6 *from, unsigned int *ifindex,
|
struct sockaddr_in6 *from, unsigned int *ifindex,
|
||||||
@ -389,24 +370,25 @@ rtadv_send_packet (int sock, struct interface *ifp)
|
|||||||
static int
|
static int
|
||||||
rtadv_timer (struct thread *thread)
|
rtadv_timer (struct thread *thread)
|
||||||
{
|
{
|
||||||
|
struct zebra_vrf *zvrf = THREAD_ARG (thread);
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
struct zebra_if *zif;
|
struct zebra_if *zif;
|
||||||
int period;
|
int period;
|
||||||
|
|
||||||
rtadv->ra_timer = NULL;
|
zvrf->rtadv.ra_timer = NULL;
|
||||||
if (rtadv->adv_msec_if_count == 0)
|
if (zvrf->rtadv.adv_msec_if_count == 0)
|
||||||
{
|
{
|
||||||
period = 1000; /* 1 s */
|
period = 1000; /* 1 s */
|
||||||
rtadv_event (RTADV_TIMER, 1 /* 1 s */);
|
rtadv_event (zvrf, RTADV_TIMER, 1 /* 1 s */);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
period = 10; /* 10 ms */
|
period = 10; /* 10 ms */
|
||||||
rtadv_event (RTADV_TIMER_MSEC, 10 /* 10 ms */);
|
rtadv_event (zvrf, RTADV_TIMER_MSEC, 10 /* 10 ms */);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
|
for (ALL_LIST_ELEMENTS (vrf_iflist (zvrf->vrf_id), node, nnode, ifp))
|
||||||
{
|
{
|
||||||
if (if_is_loopback (ifp) || ! if_is_operative (ifp))
|
if (if_is_loopback (ifp) || ! if_is_operative (ifp))
|
||||||
continue;
|
continue;
|
||||||
@ -421,7 +403,7 @@ rtadv_timer (struct thread *thread)
|
|||||||
/* FIXME: using MaxRtrAdvInterval each time isn't what section
|
/* FIXME: using MaxRtrAdvInterval each time isn't what section
|
||||||
6.2.4 of RFC4861 tells to do. */
|
6.2.4 of RFC4861 tells to do. */
|
||||||
zif->rtadv.AdvIntervalTimer = zif->rtadv.MaxRtrAdvInterval;
|
zif->rtadv.AdvIntervalTimer = zif->rtadv.MaxRtrAdvInterval;
|
||||||
rtadv_send_packet (rtadv->sock, ifp);
|
rtadv_send_packet (zvrf->rtadv.sock, ifp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -431,9 +413,11 @@ rtadv_timer (struct thread *thread)
|
|||||||
static void
|
static void
|
||||||
rtadv_process_solicit (struct interface *ifp)
|
rtadv_process_solicit (struct interface *ifp)
|
||||||
{
|
{
|
||||||
zlog_info ("Router solicitation received on %s", ifp->name);
|
struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id);
|
||||||
|
|
||||||
rtadv_send_packet (rtadv->sock, ifp);
|
zlog_info ("Router solicitation received on %s vrf %u", ifp->name, zvrf->vrf_id);
|
||||||
|
|
||||||
|
rtadv_send_packet (zvrf->rtadv.sock, ifp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -513,17 +497,17 @@ rtadv_process_advert (u_char *msg, unsigned int len, struct interface *ifp,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
rtadv_process_packet (u_char *buf, unsigned int len, unsigned int ifindex, int hoplimit,
|
rtadv_process_packet (u_char *buf, unsigned int len, unsigned int ifindex, int hoplimit,
|
||||||
struct sockaddr_in6 *from)
|
struct sockaddr_in6 *from, vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
struct icmp6_hdr *icmph;
|
struct icmp6_hdr *icmph;
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
struct zebra_if *zif;
|
struct zebra_if *zif;
|
||||||
|
|
||||||
/* Interface search. */
|
/* Interface search. */
|
||||||
ifp = if_lookup_by_index (ifindex);
|
ifp = if_lookup_by_index_vrf (ifindex, vrf_id);
|
||||||
if (ifp == NULL)
|
if (ifp == NULL)
|
||||||
{
|
{
|
||||||
zlog_warn ("Unknown interface index: %d", ifindex);
|
zlog_warn ("Unknown interface index: %d, vrf %u", ifindex, vrf_id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -578,12 +562,13 @@ rtadv_read (struct thread *thread)
|
|||||||
struct sockaddr_in6 from;
|
struct sockaddr_in6 from;
|
||||||
unsigned int ifindex = 0;
|
unsigned int ifindex = 0;
|
||||||
int hoplimit = -1;
|
int hoplimit = -1;
|
||||||
|
struct zebra_vrf *zvrf = THREAD_ARG (thread);
|
||||||
|
|
||||||
sock = THREAD_FD (thread);
|
sock = THREAD_FD (thread);
|
||||||
rtadv->ra_read = NULL;
|
zvrf->rtadv.ra_read = NULL;
|
||||||
|
|
||||||
/* Register myself. */
|
/* Register myself. */
|
||||||
rtadv_event (RTADV_READ, sock);
|
rtadv_event (zvrf, RTADV_READ, sock);
|
||||||
|
|
||||||
len = rtadv_recv_packet (sock, buf, BUFSIZ, &from, &ifindex, &hoplimit);
|
len = rtadv_recv_packet (sock, buf, BUFSIZ, &from, &ifindex, &hoplimit);
|
||||||
|
|
||||||
@ -593,13 +578,13 @@ rtadv_read (struct thread *thread)
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
rtadv_process_packet (buf, (unsigned)len, ifindex, hoplimit, &from);
|
rtadv_process_packet (buf, (unsigned)len, ifindex, hoplimit, &from, zvrf->vrf_id);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
rtadv_make_socket (void)
|
rtadv_make_socket (vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
int sock;
|
int sock;
|
||||||
int ret;
|
int ret;
|
||||||
@ -609,7 +594,7 @@ rtadv_make_socket (void)
|
|||||||
zlog_err ("rtadv_make_socket: could not raise privs, %s",
|
zlog_err ("rtadv_make_socket: could not raise privs, %s",
|
||||||
safe_strerror (errno) );
|
safe_strerror (errno) );
|
||||||
|
|
||||||
sock = socket (AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
|
sock = vrf_socket (AF_INET6, SOCK_RAW, IPPROTO_ICMPV6, vrf_id);
|
||||||
|
|
||||||
if ( zserv_privs.change (ZPRIVS_LOWER) )
|
if ( zserv_privs.change (ZPRIVS_LOWER) )
|
||||||
zlog_err ("rtadv_make_socket: could not lower privs, %s",
|
zlog_err ("rtadv_make_socket: could not lower privs, %s",
|
||||||
@ -731,9 +716,11 @@ DEFUN (ipv6_nd_suppress_ra,
|
|||||||
{
|
{
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
struct zebra_if *zif;
|
struct zebra_if *zif;
|
||||||
|
struct zebra_vrf *zvrf;
|
||||||
|
|
||||||
ifp = vty->index;
|
ifp = vty->index;
|
||||||
zif = ifp->info;
|
zif = ifp->info;
|
||||||
|
zvrf = vrf_info_lookup (ifp->vrf_id);
|
||||||
|
|
||||||
if (if_is_loopback (ifp))
|
if (if_is_loopback (ifp))
|
||||||
{
|
{
|
||||||
@ -745,12 +732,12 @@ DEFUN (ipv6_nd_suppress_ra,
|
|||||||
{
|
{
|
||||||
zif->rtadv.AdvSendAdvertisements = 0;
|
zif->rtadv.AdvSendAdvertisements = 0;
|
||||||
zif->rtadv.AdvIntervalTimer = 0;
|
zif->rtadv.AdvIntervalTimer = 0;
|
||||||
rtadv->adv_if_count--;
|
zvrf->rtadv.adv_if_count--;
|
||||||
|
|
||||||
if_leave_all_router (rtadv->sock, ifp);
|
if_leave_all_router (zvrf->rtadv.sock, ifp);
|
||||||
|
|
||||||
if (rtadv->adv_if_count == 0)
|
if (zvrf->rtadv.adv_if_count == 0)
|
||||||
rtadv_event (RTADV_STOP, 0);
|
rtadv_event (zvrf, RTADV_STOP, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
@ -766,9 +753,11 @@ DEFUN (no_ipv6_nd_suppress_ra,
|
|||||||
{
|
{
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
struct zebra_if *zif;
|
struct zebra_if *zif;
|
||||||
|
struct zebra_vrf *zvrf;
|
||||||
|
|
||||||
ifp = vty->index;
|
ifp = vty->index;
|
||||||
zif = ifp->info;
|
zif = ifp->info;
|
||||||
|
zvrf = vrf_info_lookup (ifp->vrf_id);
|
||||||
|
|
||||||
if (if_is_loopback (ifp))
|
if (if_is_loopback (ifp))
|
||||||
{
|
{
|
||||||
@ -780,12 +769,12 @@ DEFUN (no_ipv6_nd_suppress_ra,
|
|||||||
{
|
{
|
||||||
zif->rtadv.AdvSendAdvertisements = 1;
|
zif->rtadv.AdvSendAdvertisements = 1;
|
||||||
zif->rtadv.AdvIntervalTimer = 0;
|
zif->rtadv.AdvIntervalTimer = 0;
|
||||||
rtadv->adv_if_count++;
|
zvrf->rtadv.adv_if_count++;
|
||||||
|
|
||||||
if_join_all_router (rtadv->sock, ifp);
|
if_join_all_router (zvrf->rtadv.sock, ifp);
|
||||||
|
|
||||||
if (rtadv->adv_if_count == 1)
|
if (zvrf->rtadv.adv_if_count == 1)
|
||||||
rtadv_event (RTADV_START, rtadv->sock);
|
rtadv_event (zvrf, RTADV_START, zvrf->rtadv.sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
@ -802,6 +791,7 @@ DEFUN (ipv6_nd_ra_interval_msec,
|
|||||||
unsigned interval;
|
unsigned interval;
|
||||||
struct interface *ifp = (struct interface *) vty->index;
|
struct interface *ifp = (struct interface *) vty->index;
|
||||||
struct zebra_if *zif = ifp->info;
|
struct zebra_if *zif = ifp->info;
|
||||||
|
struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id);
|
||||||
|
|
||||||
VTY_GET_INTEGER_RANGE ("router advertisement interval", interval, argv[0], 70, 1800000);
|
VTY_GET_INTEGER_RANGE ("router advertisement interval", interval, argv[0], 70, 1800000);
|
||||||
if ((zif->rtadv.AdvDefaultLifetime != -1 && interval > (unsigned)zif->rtadv.AdvDefaultLifetime * 1000))
|
if ((zif->rtadv.AdvDefaultLifetime != -1 && interval > (unsigned)zif->rtadv.AdvDefaultLifetime * 1000))
|
||||||
@ -811,10 +801,10 @@ DEFUN (ipv6_nd_ra_interval_msec,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (zif->rtadv.MaxRtrAdvInterval % 1000)
|
if (zif->rtadv.MaxRtrAdvInterval % 1000)
|
||||||
rtadv->adv_msec_if_count--;
|
zvrf->rtadv.adv_msec_if_count--;
|
||||||
|
|
||||||
if (interval % 1000)
|
if (interval % 1000)
|
||||||
rtadv->adv_msec_if_count++;
|
zvrf->rtadv.adv_msec_if_count++;
|
||||||
|
|
||||||
zif->rtadv.MaxRtrAdvInterval = interval;
|
zif->rtadv.MaxRtrAdvInterval = interval;
|
||||||
zif->rtadv.MinRtrAdvInterval = 0.33 * interval;
|
zif->rtadv.MinRtrAdvInterval = 0.33 * interval;
|
||||||
@ -834,6 +824,7 @@ DEFUN (ipv6_nd_ra_interval,
|
|||||||
unsigned interval;
|
unsigned interval;
|
||||||
struct interface *ifp = (struct interface *) vty->index;
|
struct interface *ifp = (struct interface *) vty->index;
|
||||||
struct zebra_if *zif = ifp->info;
|
struct zebra_if *zif = ifp->info;
|
||||||
|
struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id);
|
||||||
|
|
||||||
VTY_GET_INTEGER_RANGE ("router advertisement interval", interval, argv[0], 1, 1800);
|
VTY_GET_INTEGER_RANGE ("router advertisement interval", interval, argv[0], 1, 1800);
|
||||||
if ((zif->rtadv.AdvDefaultLifetime != -1 && interval > (unsigned)zif->rtadv.AdvDefaultLifetime))
|
if ((zif->rtadv.AdvDefaultLifetime != -1 && interval > (unsigned)zif->rtadv.AdvDefaultLifetime))
|
||||||
@ -843,7 +834,7 @@ DEFUN (ipv6_nd_ra_interval,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (zif->rtadv.MaxRtrAdvInterval % 1000)
|
if (zif->rtadv.MaxRtrAdvInterval % 1000)
|
||||||
rtadv->adv_msec_if_count--;
|
zvrf->rtadv.adv_msec_if_count--;
|
||||||
|
|
||||||
/* convert to milliseconds */
|
/* convert to milliseconds */
|
||||||
interval = interval * 1000;
|
interval = interval * 1000;
|
||||||
@ -865,12 +856,14 @@ DEFUN (no_ipv6_nd_ra_interval,
|
|||||||
{
|
{
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
struct zebra_if *zif;
|
struct zebra_if *zif;
|
||||||
|
struct zebra_vrf *zvrf;
|
||||||
|
|
||||||
ifp = (struct interface *) vty->index;
|
ifp = (struct interface *) vty->index;
|
||||||
zif = ifp->info;
|
zif = ifp->info;
|
||||||
|
zvrf = vrf_info_lookup (ifp->vrf_id);
|
||||||
|
|
||||||
if (zif->rtadv.MaxRtrAdvInterval % 1000)
|
if (zif->rtadv.MaxRtrAdvInterval % 1000)
|
||||||
rtadv->adv_msec_if_count--;
|
zvrf->rtadv.adv_msec_if_count--;
|
||||||
|
|
||||||
zif->rtadv.MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
|
zif->rtadv.MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
|
||||||
zif->rtadv.MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL;
|
zif->rtadv.MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL;
|
||||||
@ -1609,9 +1602,6 @@ rtadv_config_write (struct vty *vty, struct interface *ifp)
|
|||||||
u_char buf[INET6_ADDRSTRLEN];
|
u_char buf[INET6_ADDRSTRLEN];
|
||||||
int interval;
|
int interval;
|
||||||
|
|
||||||
if (! rtadv)
|
|
||||||
return;
|
|
||||||
|
|
||||||
zif = ifp->info;
|
zif = ifp->info;
|
||||||
|
|
||||||
if (! if_is_loopback (ifp))
|
if (! if_is_loopback (ifp))
|
||||||
@ -1696,16 +1686,18 @@ rtadv_config_write (struct vty *vty, struct interface *ifp)
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rtadv_event (enum rtadv_event event, int val)
|
rtadv_event (struct zebra_vrf *zvrf, enum rtadv_event event, int val)
|
||||||
{
|
{
|
||||||
|
struct rtadv *rtadv = &zvrf->rtadv;
|
||||||
|
|
||||||
switch (event)
|
switch (event)
|
||||||
{
|
{
|
||||||
case RTADV_START:
|
case RTADV_START:
|
||||||
if (! rtadv->ra_read)
|
if (! rtadv->ra_read)
|
||||||
rtadv->ra_read = thread_add_read (zebrad.master, rtadv_read, NULL, val);
|
rtadv->ra_read = thread_add_read (zebrad.master, rtadv_read, zvrf, val);
|
||||||
if (! rtadv->ra_timer)
|
if (! rtadv->ra_timer)
|
||||||
rtadv->ra_timer = thread_add_event (zebrad.master, rtadv_timer,
|
rtadv->ra_timer = thread_add_event (zebrad.master, rtadv_timer,
|
||||||
NULL, 0);
|
zvrf, 0);
|
||||||
break;
|
break;
|
||||||
case RTADV_STOP:
|
case RTADV_STOP:
|
||||||
if (rtadv->ra_timer)
|
if (rtadv->ra_timer)
|
||||||
@ -1721,17 +1713,17 @@ rtadv_event (enum rtadv_event event, int val)
|
|||||||
break;
|
break;
|
||||||
case RTADV_TIMER:
|
case RTADV_TIMER:
|
||||||
if (! rtadv->ra_timer)
|
if (! rtadv->ra_timer)
|
||||||
rtadv->ra_timer = thread_add_timer (zebrad.master, rtadv_timer, NULL,
|
rtadv->ra_timer = thread_add_timer (zebrad.master, rtadv_timer, zvrf,
|
||||||
val);
|
val);
|
||||||
break;
|
break;
|
||||||
case RTADV_TIMER_MSEC:
|
case RTADV_TIMER_MSEC:
|
||||||
if (! rtadv->ra_timer)
|
if (! rtadv->ra_timer)
|
||||||
rtadv->ra_timer = thread_add_timer_msec (zebrad.master, rtadv_timer,
|
rtadv->ra_timer = thread_add_timer_msec (zebrad.master, rtadv_timer,
|
||||||
NULL, val);
|
zvrf, val);
|
||||||
break;
|
break;
|
||||||
case RTADV_READ:
|
case RTADV_READ:
|
||||||
if (! rtadv->ra_read)
|
if (! rtadv->ra_read)
|
||||||
rtadv->ra_read = thread_add_read (zebrad.master, rtadv_read, NULL, val);
|
rtadv->ra_read = thread_add_read (zebrad.master, rtadv_read, zvrf, val);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -1740,17 +1732,29 @@ rtadv_event (enum rtadv_event event, int val)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rtadv_init (void)
|
rtadv_init (struct zebra_vrf *zvrf)
|
||||||
{
|
{
|
||||||
int sock;
|
zvrf->rtadv.sock = rtadv_make_socket (zvrf->vrf_id);
|
||||||
|
}
|
||||||
|
|
||||||
sock = rtadv_make_socket ();
|
void
|
||||||
if (sock < 0)
|
rtadv_terminate (struct zebra_vrf *zvrf)
|
||||||
return;
|
{
|
||||||
|
rtadv_event (zvrf, RTADV_STOP, 0);
|
||||||
|
|
||||||
rtadv = rtadv_new ();
|
if (zvrf->rtadv.sock >= 0)
|
||||||
rtadv->sock = sock;
|
{
|
||||||
|
close (zvrf->rtadv.sock);
|
||||||
|
zvrf->rtadv.sock = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
zvrf->rtadv.adv_if_count = 0;
|
||||||
|
zvrf->rtadv.adv_msec_if_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rtadv_cmd_init (void)
|
||||||
|
{
|
||||||
install_element (INTERFACE_NODE, &ipv6_nd_suppress_ra_cmd);
|
install_element (INTERFACE_NODE, &ipv6_nd_suppress_ra_cmd);
|
||||||
install_element (INTERFACE_NODE, &no_ipv6_nd_suppress_ra_cmd);
|
install_element (INTERFACE_NODE, &no_ipv6_nd_suppress_ra_cmd);
|
||||||
install_element (INTERFACE_NODE, &ipv6_nd_ra_interval_cmd);
|
install_element (INTERFACE_NODE, &ipv6_nd_ra_interval_cmd);
|
||||||
@ -1845,7 +1849,17 @@ if_leave_all_router (int sock, struct interface *ifp)
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
void
|
void
|
||||||
rtadv_init (void)
|
rtadv_init (struct zebra_vrf *zvrf)
|
||||||
|
{
|
||||||
|
/* Empty.*/;
|
||||||
|
}
|
||||||
|
void
|
||||||
|
rtadv_terminate (struct zebra_vrf *zvrf)
|
||||||
|
{
|
||||||
|
/* Empty.*/;
|
||||||
|
}
|
||||||
|
void
|
||||||
|
rtadv_cmd_init (void)
|
||||||
{
|
{
|
||||||
/* Empty.*/;
|
/* Empty.*/;
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,6 @@ struct rtadv_prefix
|
|||||||
};
|
};
|
||||||
|
|
||||||
extern void rtadv_config_write (struct vty *, struct interface *);
|
extern void rtadv_config_write (struct vty *, struct interface *);
|
||||||
extern void rtadv_init (void);
|
|
||||||
|
|
||||||
/* RFC4584 Extension to Sockets API for Mobile IPv6 */
|
/* RFC4584 Extension to Sockets API for Mobile IPv6 */
|
||||||
|
|
||||||
@ -101,4 +100,8 @@ extern const char *rtadv_pref_strs[];
|
|||||||
|
|
||||||
#endif /* RTADV */
|
#endif /* RTADV */
|
||||||
|
|
||||||
|
extern void rtadv_init (struct zebra_vrf *);
|
||||||
|
extern void rtadv_terminate (struct zebra_vrf *);
|
||||||
|
extern void rtadv_cmd_init (void);
|
||||||
|
|
||||||
#endif /* _ZEBRA_RTADV_H */
|
#endif /* _ZEBRA_RTADV_H */
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "prefix.h"
|
#include "prefix.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "if.h"
|
#include "if.h"
|
||||||
|
#include "vrf.h"
|
||||||
|
|
||||||
#include "zebra/rib.h"
|
#include "zebra/rib.h"
|
||||||
#include "zebra/zserv.h"
|
#include "zebra/zserv.h"
|
||||||
@ -90,11 +91,11 @@ handle_route_entry (mib2_ipRouteEntry_t *routeEntry)
|
|||||||
gateway.s_addr = routeEntry->ipRouteNextHop;
|
gateway.s_addr = routeEntry->ipRouteNextHop;
|
||||||
|
|
||||||
rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &prefix,
|
rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &prefix,
|
||||||
&gateway, NULL, 0, 0, 0, 0, SAFI_UNICAST);
|
&gateway, NULL, 0, VRF_DEFAULT, 0, 0, 0, SAFI_UNICAST);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
route_read (void)
|
route_read (struct zebra_vrf *zvrf)
|
||||||
{
|
{
|
||||||
char storage[RT_BUFSIZ];
|
char storage[RT_BUFSIZ];
|
||||||
|
|
||||||
@ -109,6 +110,10 @@ route_read (void)
|
|||||||
struct strbuf msgdata;
|
struct strbuf msgdata;
|
||||||
int flags, dev, retval, process;
|
int flags, dev, retval, process;
|
||||||
|
|
||||||
|
if (zvrf->vrf_id != VRF_DEFAULT) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ((dev = open (_PATH_GETMSG_ROUTE, O_RDWR)) == -1) {
|
if ((dev = open (_PATH_GETMSG_ROUTE, O_RDWR)) == -1) {
|
||||||
zlog_warn ("can't open %s: %s", _PATH_GETMSG_ROUTE,
|
zlog_warn ("can't open %s: %s", _PATH_GETMSG_ROUTE,
|
||||||
safe_strerror (errno));
|
safe_strerror (errno));
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
#include "zebra/zserv.h"
|
#include "zebra/zserv.h"
|
||||||
#include "zebra/rt_netlink.h"
|
#include "zebra/rt_netlink.h"
|
||||||
|
|
||||||
void route_read (void)
|
void route_read (struct zebra_vrf *zvrf)
|
||||||
{
|
{
|
||||||
netlink_route_read ();
|
netlink_route_read (zvrf);
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "vrf.h"
|
||||||
|
|
||||||
#include "zebra/zserv.h"
|
#include "zebra/zserv.h"
|
||||||
#include "zebra/rt.h"
|
#include "zebra/rt.h"
|
||||||
@ -31,7 +32,7 @@
|
|||||||
|
|
||||||
/* Kernel routing table read up by sysctl function. */
|
/* Kernel routing table read up by sysctl function. */
|
||||||
void
|
void
|
||||||
route_read (void)
|
route_read (struct zebra_vrf *zvrf)
|
||||||
{
|
{
|
||||||
caddr_t buf, end, ref;
|
caddr_t buf, end, ref;
|
||||||
size_t bufsiz;
|
size_t bufsiz;
|
||||||
@ -47,7 +48,10 @@ route_read (void)
|
|||||||
NET_RT_DUMP,
|
NET_RT_DUMP,
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (zvrf->vrf_id != VRF_DEFAULT)
|
||||||
|
return;
|
||||||
|
|
||||||
/* Get buffer size. */
|
/* Get buffer size. */
|
||||||
if (sysctl (mib, MIBSIZ, NULL, &bufsiz, NULL, 0) < 0)
|
if (sysctl (mib, MIBSIZ, NULL, &bufsiz, NULL, 0) < 0)
|
||||||
{
|
{
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "privs.h"
|
#include "privs.h"
|
||||||
#include "sigevent.h"
|
#include "sigevent.h"
|
||||||
|
#include "vrf.h"
|
||||||
|
|
||||||
#include "zebra/rib.h"
|
#include "zebra/rib.h"
|
||||||
#include "zebra/zserv.h"
|
#include "zebra/zserv.h"
|
||||||
@ -201,6 +202,71 @@ struct quagga_signal_t zebra_signals[] =
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Callback upon creating a new VRF. */
|
||||||
|
static int
|
||||||
|
zebra_vrf_new (vrf_id_t vrf_id, void **info)
|
||||||
|
{
|
||||||
|
struct zebra_vrf *zvrf = *info;
|
||||||
|
|
||||||
|
if (! zvrf)
|
||||||
|
{
|
||||||
|
zvrf = zebra_vrf_alloc (vrf_id);
|
||||||
|
*info = (void *)zvrf;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Callback upon enabling a VRF. */
|
||||||
|
static int
|
||||||
|
zebra_vrf_enable (vrf_id_t vrf_id, void **info)
|
||||||
|
{
|
||||||
|
struct zebra_vrf *zvrf = (struct zebra_vrf *) (*info);
|
||||||
|
|
||||||
|
assert (zvrf);
|
||||||
|
|
||||||
|
kernel_init (zvrf);
|
||||||
|
route_read (zvrf);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Callback upon disabling a VRF. */
|
||||||
|
static int
|
||||||
|
zebra_vrf_disable (vrf_id_t vrf_id, void **info)
|
||||||
|
{
|
||||||
|
struct zebra_vrf *zvrf = (struct zebra_vrf *) (*info);
|
||||||
|
struct listnode *list_node;
|
||||||
|
struct interface *ifp;
|
||||||
|
|
||||||
|
assert (zvrf);
|
||||||
|
|
||||||
|
rib_close_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
|
||||||
|
rib_close_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
|
||||||
|
|
||||||
|
for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), list_node, ifp))
|
||||||
|
{
|
||||||
|
int operative = if_is_operative (ifp);
|
||||||
|
UNSET_FLAG (ifp->flags, IFF_UP);
|
||||||
|
if (operative)
|
||||||
|
if_down (ifp);
|
||||||
|
}
|
||||||
|
|
||||||
|
kernel_terminate (zvrf);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Zebra VRF initialization. */
|
||||||
|
static void
|
||||||
|
zebra_vrf_init (void)
|
||||||
|
{
|
||||||
|
vrf_add_hook (VRF_NEW_HOOK, zebra_vrf_new);
|
||||||
|
vrf_add_hook (VRF_ENABLE_HOOK, zebra_vrf_enable);
|
||||||
|
vrf_add_hook (VRF_DISABLE_HOOK, zebra_vrf_disable);
|
||||||
|
vrf_init ();
|
||||||
|
}
|
||||||
|
|
||||||
/* Main startup routine. */
|
/* Main startup routine. */
|
||||||
int
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
@ -292,7 +358,6 @@ main (int argc, char **argv)
|
|||||||
cmd_init (1);
|
cmd_init (1);
|
||||||
vty_init (zebrad.master);
|
vty_init (zebrad.master);
|
||||||
memory_init ();
|
memory_init ();
|
||||||
if_init();
|
|
||||||
zebra_debug_init ();
|
zebra_debug_init ();
|
||||||
zebra_if_init ();
|
zebra_if_init ();
|
||||||
test_cmd_init ();
|
test_cmd_init ();
|
||||||
@ -302,8 +367,7 @@ main (int argc, char **argv)
|
|||||||
access_list_init ();
|
access_list_init ();
|
||||||
|
|
||||||
/* Make kernel routing socket. */
|
/* Make kernel routing socket. */
|
||||||
kernel_init ();
|
zebra_vrf_init ();
|
||||||
route_read ();
|
|
||||||
zebra_vty_init();
|
zebra_vty_init();
|
||||||
|
|
||||||
/* Configuration file read*/
|
/* Configuration file read*/
|
||||||
|
@ -330,7 +330,7 @@ zfpm_is_table_for_fpm (struct route_table *table)
|
|||||||
* We only send the unicast tables in the main instance to the FPM
|
* We only send the unicast tables in the main instance to the FPM
|
||||||
* at this point.
|
* at this point.
|
||||||
*/
|
*/
|
||||||
if (info->vrf->id != 0)
|
if (info->zvrf->vrf_id != 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (info->safi != SAFI_UNICAST)
|
if (info->safi != SAFI_UNICAST)
|
||||||
|
@ -246,7 +246,7 @@ netlink_route_info_fill (netlink_route_info_t *ri, int cmd,
|
|||||||
ri->af = rib_dest_af (dest);
|
ri->af = rib_dest_af (dest);
|
||||||
|
|
||||||
ri->nlmsg_type = cmd;
|
ri->nlmsg_type = cmd;
|
||||||
ri->rtm_table = rib_dest_vrf (dest)->id;
|
ri->rtm_table = rib_dest_vrf (dest)->vrf_id;
|
||||||
ri->rtm_protocol = RTPROT_UNSPEC;
|
ri->rtm_protocol = RTPROT_UNSPEC;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
#include "prefix.h"
|
#include "prefix.h"
|
||||||
#include "routemap.h"
|
#include "routemap.h"
|
||||||
#include "nexthop.h"
|
#include "nexthop.h"
|
||||||
|
#include "vrf.h"
|
||||||
|
|
||||||
#include "zebra/rib.h"
|
#include "zebra/rib.h"
|
||||||
#include "zebra/rt.h"
|
#include "zebra/rt.h"
|
||||||
@ -78,137 +79,29 @@ static const struct
|
|||||||
/* no entry/default: 150 */
|
/* no entry/default: 150 */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Vector for routing table. */
|
|
||||||
static vector vrf_vector;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vrf_table_create
|
* nexthop_type_to_str
|
||||||
*/
|
*/
|
||||||
static void
|
const char *
|
||||||
vrf_table_create (struct vrf *vrf, afi_t afi, safi_t safi)
|
nexthop_type_to_str (enum nexthop_types_t nh_type)
|
||||||
{
|
{
|
||||||
rib_table_info_t *info;
|
static const char *desc[] = {
|
||||||
struct route_table *table;
|
"none",
|
||||||
|
"Directly connected",
|
||||||
|
"Interface route",
|
||||||
|
"IPv4 nexthop",
|
||||||
|
"IPv4 nexthop with ifindex",
|
||||||
|
"IPv4 nexthop with ifname",
|
||||||
|
"IPv6 nexthop",
|
||||||
|
"IPv6 nexthop with ifindex",
|
||||||
|
"IPv6 nexthop with ifname",
|
||||||
|
"Null0 nexthop",
|
||||||
|
};
|
||||||
|
|
||||||
assert (!vrf->table[afi][safi]);
|
if (nh_type >= ZEBRA_NUM_OF (desc))
|
||||||
|
return "<Invalid nh type>";
|
||||||
|
|
||||||
table = route_table_init ();
|
return desc[nh_type];
|
||||||
vrf->table[afi][safi] = table;
|
|
||||||
|
|
||||||
info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info));
|
|
||||||
info->vrf = vrf;
|
|
||||||
info->afi = afi;
|
|
||||||
info->safi = safi;
|
|
||||||
table->info = info;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate new VRF. */
|
|
||||||
static struct vrf *
|
|
||||||
vrf_alloc (const char *name)
|
|
||||||
{
|
|
||||||
struct vrf *vrf;
|
|
||||||
|
|
||||||
vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
|
|
||||||
|
|
||||||
/* Put name. */
|
|
||||||
if (name)
|
|
||||||
vrf->name = XSTRDUP (MTYPE_VRF_NAME, name);
|
|
||||||
|
|
||||||
/* Allocate routing table and static table. */
|
|
||||||
vrf_table_create (vrf, AFI_IP, SAFI_UNICAST);
|
|
||||||
vrf_table_create (vrf, AFI_IP6, SAFI_UNICAST);
|
|
||||||
vrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init ();
|
|
||||||
vrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init ();
|
|
||||||
vrf_table_create (vrf, AFI_IP, SAFI_MULTICAST);
|
|
||||||
vrf_table_create (vrf, AFI_IP6, SAFI_MULTICAST);
|
|
||||||
vrf->stable[AFI_IP][SAFI_MULTICAST] = route_table_init ();
|
|
||||||
vrf->stable[AFI_IP6][SAFI_MULTICAST] = route_table_init ();
|
|
||||||
|
|
||||||
vrf->rnh_table[AFI_IP] = route_table_init();
|
|
||||||
vrf->rnh_table[AFI_IP6] = route_table_init();
|
|
||||||
|
|
||||||
vrf->import_check_table[AFI_IP] = route_table_init();
|
|
||||||
vrf->import_check_table[AFI_IP6] = route_table_init();
|
|
||||||
|
|
||||||
return vrf;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Lookup VRF by identifier. */
|
|
||||||
struct vrf *
|
|
||||||
vrf_lookup (u_int32_t id)
|
|
||||||
{
|
|
||||||
return vector_lookup (vrf_vector, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize VRF. */
|
|
||||||
static void
|
|
||||||
vrf_init (void)
|
|
||||||
{
|
|
||||||
struct vrf *default_table;
|
|
||||||
|
|
||||||
/* Allocate VRF vector. */
|
|
||||||
vrf_vector = vector_init (1);
|
|
||||||
|
|
||||||
/* Allocate default main table. */
|
|
||||||
default_table = vrf_alloc ("Default-IP-Routing-Table");
|
|
||||||
|
|
||||||
/* Default table index must be 0. */
|
|
||||||
vector_set_index (vrf_vector, 0, default_table);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Lookup route table. */
|
|
||||||
struct route_table *
|
|
||||||
vrf_table (afi_t afi, safi_t safi, u_int32_t id)
|
|
||||||
{
|
|
||||||
struct vrf *vrf;
|
|
||||||
|
|
||||||
vrf = vrf_lookup (id);
|
|
||||||
if (! vrf)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if( afi >= AFI_MAX || safi >= SAFI_MAX )
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return vrf->table[afi][safi];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Lookup static route table. */
|
|
||||||
struct route_table *
|
|
||||||
vrf_static_table (afi_t afi, safi_t safi, u_int32_t id)
|
|
||||||
{
|
|
||||||
struct vrf *vrf;
|
|
||||||
|
|
||||||
vrf = vrf_lookup (id);
|
|
||||||
if (! vrf)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if( afi >= AFI_MAX || safi >= SAFI_MAX )
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return vrf->stable[afi][safi];
|
|
||||||
}
|
|
||||||
|
|
||||||
struct route_table *
|
|
||||||
vrf_other_route_table (afi_t afi, u_int32_t table_id, u_int32_t vrf_id)
|
|
||||||
{
|
|
||||||
struct vrf *vrf;
|
|
||||||
|
|
||||||
vrf = vrf_lookup (vrf_id);
|
|
||||||
if (! vrf)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if(afi >= AFI_MAX)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (table_id >= ZEBRA_KERNEL_TABLE_MAX)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (vrf->other_table[afi][table_id] == NULL)
|
|
||||||
{
|
|
||||||
vrf->other_table[afi][table_id] = route_table_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
return (vrf->other_table[afi][table_id]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -583,7 +476,7 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
|
|||||||
p.prefix = nexthop->gate.ipv4;
|
p.prefix = nexthop->gate.ipv4;
|
||||||
|
|
||||||
/* Lookup table. */
|
/* Lookup table. */
|
||||||
table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
|
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, rib->vrf_id);
|
||||||
if (! table)
|
if (! table)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -791,7 +684,7 @@ nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
|
|||||||
p.prefix = nexthop->gate.ipv6;
|
p.prefix = nexthop->gate.ipv6;
|
||||||
|
|
||||||
/* Lookup table. */
|
/* Lookup table. */
|
||||||
table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
|
table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, rib->vrf_id);
|
||||||
if (! table)
|
if (! table)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -944,7 +837,7 @@ nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct rib *
|
struct rib *
|
||||||
rib_match_ipv4 (struct in_addr addr)
|
rib_match_ipv4 (struct in_addr addr, vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
struct prefix_ipv4 p;
|
struct prefix_ipv4 p;
|
||||||
struct route_table *table;
|
struct route_table *table;
|
||||||
@ -954,7 +847,7 @@ rib_match_ipv4 (struct in_addr addr)
|
|||||||
int recursing;
|
int recursing;
|
||||||
|
|
||||||
/* Lookup table. */
|
/* Lookup table. */
|
||||||
table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
|
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
|
||||||
if (! table)
|
if (! table)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -1006,7 +899,7 @@ rib_match_ipv4 (struct in_addr addr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct rib *
|
struct rib *
|
||||||
rib_lookup_ipv4 (struct prefix_ipv4 *p)
|
rib_lookup_ipv4 (struct prefix_ipv4 *p, vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
struct route_table *table;
|
struct route_table *table;
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
@ -1015,7 +908,7 @@ rib_lookup_ipv4 (struct prefix_ipv4 *p)
|
|||||||
int recursing;
|
int recursing;
|
||||||
|
|
||||||
/* Lookup table. */
|
/* Lookup table. */
|
||||||
table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
|
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
|
||||||
if (! table)
|
if (! table)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -1062,7 +955,8 @@ rib_lookup_ipv4 (struct prefix_ipv4 *p)
|
|||||||
* 3: no matches found
|
* 3: no matches found
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate)
|
rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate,
|
||||||
|
vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
struct route_table *table;
|
struct route_table *table;
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
@ -1072,7 +966,7 @@ rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate)
|
|||||||
int nexthops_active;
|
int nexthops_active;
|
||||||
|
|
||||||
/* Lookup table. */
|
/* Lookup table. */
|
||||||
table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
|
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
|
||||||
if (! table)
|
if (! table)
|
||||||
return ZEBRA_RIB_LOOKUP_ERROR;
|
return ZEBRA_RIB_LOOKUP_ERROR;
|
||||||
|
|
||||||
@ -1127,7 +1021,7 @@ rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct rib *
|
struct rib *
|
||||||
rib_match_ipv6 (struct in6_addr *addr)
|
rib_match_ipv6 (struct in6_addr *addr, vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
struct prefix_ipv6 p;
|
struct prefix_ipv6 p;
|
||||||
struct route_table *table;
|
struct route_table *table;
|
||||||
@ -1137,7 +1031,7 @@ rib_match_ipv6 (struct in6_addr *addr)
|
|||||||
int recursing;
|
int recursing;
|
||||||
|
|
||||||
/* Lookup table. */
|
/* Lookup table. */
|
||||||
table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
|
table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
|
||||||
if (! table)
|
if (! table)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -1220,7 +1114,7 @@ nexthop_active_check (struct route_node *rn, struct rib *rib,
|
|||||||
switch (nexthop->type)
|
switch (nexthop->type)
|
||||||
{
|
{
|
||||||
case NEXTHOP_TYPE_IFINDEX:
|
case NEXTHOP_TYPE_IFINDEX:
|
||||||
ifp = if_lookup_by_index (nexthop->ifindex);
|
ifp = if_lookup_by_index_vrf (nexthop->ifindex, rib->vrf_id);
|
||||||
if (ifp && if_is_operative(ifp))
|
if (ifp && if_is_operative(ifp))
|
||||||
SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
||||||
else
|
else
|
||||||
@ -1229,7 +1123,7 @@ nexthop_active_check (struct route_node *rn, struct rib *rib,
|
|||||||
case NEXTHOP_TYPE_IPV6_IFNAME:
|
case NEXTHOP_TYPE_IPV6_IFNAME:
|
||||||
family = AFI_IP6;
|
family = AFI_IP6;
|
||||||
case NEXTHOP_TYPE_IFNAME:
|
case NEXTHOP_TYPE_IFNAME:
|
||||||
ifp = if_lookup_by_name (nexthop->ifname);
|
ifp = if_lookup_by_name_vrf (nexthop->ifname, rib->vrf_id);
|
||||||
if (ifp && if_is_operative(ifp))
|
if (ifp && if_is_operative(ifp))
|
||||||
{
|
{
|
||||||
if (set)
|
if (set)
|
||||||
@ -1264,7 +1158,7 @@ nexthop_active_check (struct route_node *rn, struct rib *rib,
|
|||||||
family = AFI_IP6;
|
family = AFI_IP6;
|
||||||
if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
|
if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
|
||||||
{
|
{
|
||||||
ifp = if_lookup_by_index (nexthop->ifindex);
|
ifp = if_lookup_by_index_vrf (nexthop->ifindex, rib->vrf_id);
|
||||||
if (ifp && if_is_operative(ifp))
|
if (ifp && if_is_operative(ifp))
|
||||||
SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
||||||
else
|
else
|
||||||
@ -1306,7 +1200,8 @@ nexthop_active_check (struct route_node *rn, struct rib *rib,
|
|||||||
memset(&nexthop->rmap_src.ipv6, 0, sizeof(union g_addr));
|
memset(&nexthop->rmap_src.ipv6, 0, sizeof(union g_addr));
|
||||||
|
|
||||||
/* It'll get set if required inside */
|
/* It'll get set if required inside */
|
||||||
ret = zebra_route_map_check(family, rib->type, &rn->p, nexthop, rib->tag);
|
ret = zebra_route_map_check(family, rib->type, &rn->p, nexthop, rib->vrf_id,
|
||||||
|
rib->tag);
|
||||||
if (ret == RMAP_DENYMATCH)
|
if (ret == RMAP_DENYMATCH)
|
||||||
{
|
{
|
||||||
if (IS_ZEBRA_DEBUG_RIB)
|
if (IS_ZEBRA_DEBUG_RIB)
|
||||||
@ -2238,7 +2133,7 @@ rib_delnode (struct route_node *rn, struct rib *rib)
|
|||||||
int
|
int
|
||||||
rib_add_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p,
|
rib_add_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p,
|
||||||
struct in_addr *gate, struct in_addr *src,
|
struct in_addr *gate, struct in_addr *src,
|
||||||
unsigned int ifindex, u_int32_t table_id,
|
unsigned int ifindex, vrf_id_t vrf_id, u_int32_t table_id,
|
||||||
u_int32_t metric, u_char distance, safi_t safi)
|
u_int32_t metric, u_char distance, safi_t safi)
|
||||||
{
|
{
|
||||||
struct rib *rib;
|
struct rib *rib;
|
||||||
@ -2250,11 +2145,11 @@ rib_add_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p,
|
|||||||
/* Lookup table. */
|
/* Lookup table. */
|
||||||
if ((table_id == RT_TABLE_MAIN) || (table_id == zebrad.rtm_table_default))
|
if ((table_id == RT_TABLE_MAIN) || (table_id == zebrad.rtm_table_default))
|
||||||
{
|
{
|
||||||
table = vrf_table (AFI_IP, safi, 0);
|
table = zebra_vrf_table (AFI_IP, safi, vrf_id);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
table = vrf_other_route_table (AFI_IP, table_id, 0);
|
table = zebra_vrf_other_route_table (AFI_IP, table_id, vrf_id);
|
||||||
}
|
}
|
||||||
if (! table)
|
if (! table)
|
||||||
return 0;
|
return 0;
|
||||||
@ -2314,6 +2209,7 @@ rib_add_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p,
|
|||||||
rib->flags = flags;
|
rib->flags = flags;
|
||||||
rib->metric = metric;
|
rib->metric = metric;
|
||||||
rib->table = table_id;
|
rib->table = table_id;
|
||||||
|
rib->vrf_id = vrf_id;
|
||||||
rib->nexthop_num = 0;
|
rib->nexthop_num = 0;
|
||||||
rib->uptime = time (NULL);
|
rib->uptime = time (NULL);
|
||||||
|
|
||||||
@ -2367,8 +2263,8 @@ void _rib_dump (const char * func,
|
|||||||
struct nexthop *nexthop, *tnexthop;
|
struct nexthop *nexthop, *tnexthop;
|
||||||
int recursing;
|
int recursing;
|
||||||
|
|
||||||
inet_ntop (p->family, &p->u.prefix, straddr, INET6_ADDRSTRLEN);
|
zlog_debug ("%s: dumping RIB entry %p for %s vrf %u", func, rib,
|
||||||
zlog_debug ("%s: dumping RIB entry %p for %s/%d", func, rib, straddr, p->prefixlen);
|
prefix2str(pp, straddr, sizeof(straddr)), rib->vrf_id);
|
||||||
zlog_debug
|
zlog_debug
|
||||||
(
|
(
|
||||||
"%s: refcnt == %lu, uptime == %lu, type == %u, instance == %d, table == %d",
|
"%s: refcnt == %lu, uptime == %lu, type == %u, instance == %d, table == %d",
|
||||||
@ -2426,10 +2322,10 @@ void rib_lookup_and_dump (struct prefix_ipv4 * p)
|
|||||||
char prefix_buf[INET_ADDRSTRLEN];
|
char prefix_buf[INET_ADDRSTRLEN];
|
||||||
|
|
||||||
/* Lookup table. */
|
/* Lookup table. */
|
||||||
table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
|
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
|
||||||
if (! table)
|
if (! table)
|
||||||
{
|
{
|
||||||
zlog_err ("%s: vrf_table() returned NULL", __func__);
|
zlog_err ("%s: zebra_vrf_table() returned NULL", __func__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2475,9 +2371,9 @@ void rib_lookup_and_pushup (struct prefix_ipv4 * p)
|
|||||||
struct rib *rib;
|
struct rib *rib;
|
||||||
unsigned changed = 0;
|
unsigned changed = 0;
|
||||||
|
|
||||||
if (NULL == (table = vrf_table (AFI_IP, SAFI_UNICAST, 0)))
|
if (NULL == (table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT)))
|
||||||
{
|
{
|
||||||
zlog_err ("%s: vrf_table() returned NULL", __func__);
|
zlog_err ("%s: zebra_vrf_table() returned NULL", __func__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2527,11 +2423,11 @@ rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib, safi_t safi)
|
|||||||
/* Lookup table. */
|
/* Lookup table. */
|
||||||
if ((rib->table == zebrad.rtm_table_default) || (rib->table == RT_TABLE_MAIN))
|
if ((rib->table == zebrad.rtm_table_default) || (rib->table == RT_TABLE_MAIN))
|
||||||
{
|
{
|
||||||
table = vrf_table (AFI_IP, safi, 0);
|
table = zebra_vrf_table (AFI_IP, safi, rib->vrf_id);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
table = vrf_other_route_table (AFI_IP, rib->table, 0);
|
table = zebra_vrf_other_route_table (AFI_IP, rib->table, rib->vrf_id);
|
||||||
}
|
}
|
||||||
if (! table)
|
if (! table)
|
||||||
return 0;
|
return 0;
|
||||||
@ -2601,7 +2497,7 @@ rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib, safi_t safi)
|
|||||||
/* XXX factor with rib_delete_ipv6 */
|
/* XXX factor with rib_delete_ipv6 */
|
||||||
int
|
int
|
||||||
rib_delete_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p,
|
rib_delete_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p,
|
||||||
struct in_addr *gate, unsigned int ifindex,
|
struct in_addr *gate, unsigned int ifindex, vrf_id_t vrf_id,
|
||||||
u_int32_t table_id, safi_t safi)
|
u_int32_t table_id, safi_t safi)
|
||||||
{
|
{
|
||||||
struct route_table *table;
|
struct route_table *table;
|
||||||
@ -2617,11 +2513,11 @@ rib_delete_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p,
|
|||||||
/* Lookup table. */
|
/* Lookup table. */
|
||||||
if ((table_id == RT_TABLE_MAIN) || (table_id == zebrad.rtm_table_default))
|
if ((table_id == RT_TABLE_MAIN) || (table_id == zebrad.rtm_table_default))
|
||||||
{
|
{
|
||||||
table = vrf_table (AFI_IP, safi, 0);
|
table = zebra_vrf_table (AFI_IP, safi, vrf_id);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
table = vrf_other_route_table(AFI_IP, table_id, 0);
|
table = zebra_vrf_other_route_table(AFI_IP, table_id, vrf_id);
|
||||||
}
|
}
|
||||||
if (! table)
|
if (! table)
|
||||||
return 0;
|
return 0;
|
||||||
@ -2632,15 +2528,13 @@ rib_delete_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p,
|
|||||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||||
{
|
{
|
||||||
if (gate)
|
if (gate)
|
||||||
zlog_debug ("rib_delete_ipv4(): route delete %s/%d via %s ifindex %d",
|
zlog_debug ("rib_delete_ipv4(): route delete %s vrf %u via %s ifindex %d",
|
||||||
inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
|
prefix2str (p, buf1, sizeof(buf1)), vrf_id,
|
||||||
p->prefixlen,
|
|
||||||
inet_ntoa (*gate),
|
inet_ntoa (*gate),
|
||||||
ifindex);
|
ifindex);
|
||||||
else
|
else
|
||||||
zlog_debug ("rib_delete_ipv4(): route delete %s/%d ifindex %d",
|
zlog_debug ("rib_delete_ipv4(): route delete %s vrf %u ifindex %d",
|
||||||
inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
|
prefix2str (p, buf1, sizeof(buf1)), vrf_id,
|
||||||
p->prefixlen,
|
|
||||||
ifindex);
|
ifindex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2651,15 +2545,13 @@ rib_delete_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p,
|
|||||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||||
{
|
{
|
||||||
if (gate)
|
if (gate)
|
||||||
zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
|
zlog_debug ("route %s vrf %u via %s ifindex %d doesn't exist in rib",
|
||||||
inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
|
prefix2str (p, buf1, sizeof(buf1)), vrf_id,
|
||||||
p->prefixlen,
|
|
||||||
inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
|
inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
|
||||||
ifindex);
|
ifindex);
|
||||||
else
|
else
|
||||||
zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
|
zlog_debug ("route %s vrf %u ifindex %d doesn't exist in rib",
|
||||||
inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
|
prefix2str (p, buf1, sizeof(buf1)), vrf_id,
|
||||||
p->prefixlen,
|
|
||||||
ifindex);
|
ifindex);
|
||||||
}
|
}
|
||||||
return ZEBRA_ERR_RTNOEXIST;
|
return ZEBRA_ERR_RTNOEXIST;
|
||||||
@ -2744,16 +2636,15 @@ rib_delete_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p,
|
|||||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||||
{
|
{
|
||||||
if (gate)
|
if (gate)
|
||||||
zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
|
zlog_debug ("route %s vrf %u via %s ifindex %d type %d "
|
||||||
inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
|
"doesn't exist in rib",
|
||||||
p->prefixlen,
|
prefix2str (p, buf1, sizeof(buf1)), vrf_id,
|
||||||
inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
|
inet_ntop (AF_INET, gate, buf2, INET_ADDRSTRLEN),
|
||||||
ifindex,
|
ifindex,
|
||||||
type);
|
type);
|
||||||
else
|
else
|
||||||
zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
|
zlog_debug ("route %s vrf %u ifindex %d type %d doesn't exist in rib",
|
||||||
inet_ntop (AF_INET, &p->prefix, buf1, INET_ADDRSTRLEN),
|
prefix2str (p, buf1, sizeof(buf1)), vrf_id,
|
||||||
p->prefixlen,
|
|
||||||
ifindex,
|
ifindex,
|
||||||
type);
|
type);
|
||||||
}
|
}
|
||||||
@ -2779,7 +2670,7 @@ static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_ro
|
|||||||
struct prefix nh_p;
|
struct prefix nh_p;
|
||||||
|
|
||||||
/* Lookup table. */
|
/* Lookup table. */
|
||||||
table = vrf_table (afi, safi, 0);
|
table = zebra_vrf_table (afi, safi, si->vrf_id);
|
||||||
if (! table)
|
if (! table)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -2843,6 +2734,7 @@ static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_ro
|
|||||||
rib->instance = 0;
|
rib->instance = 0;
|
||||||
rib->distance = si->distance;
|
rib->distance = si->distance;
|
||||||
rib->metric = 0;
|
rib->metric = 0;
|
||||||
|
rib->vrf_id = si->vrf_id;
|
||||||
rib->table = zebrad.rtm_table_default;
|
rib->table = zebrad.rtm_table_default;
|
||||||
rib->nexthop_num = 0;
|
rib->nexthop_num = 0;
|
||||||
rib->tag = si->tag;
|
rib->tag = si->tag;
|
||||||
@ -2926,7 +2818,7 @@ static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_
|
|||||||
struct prefix nh_p;
|
struct prefix nh_p;
|
||||||
|
|
||||||
/* Lookup table. */
|
/* Lookup table. */
|
||||||
table = vrf_table (afi, safi, 0);
|
table = zebra_vrf_table (afi, safi, si->vrf_id);
|
||||||
if (! table)
|
if (! table)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -3026,7 +2918,7 @@ static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, struct static_
|
|||||||
/* Add static route into static route configuration. */
|
/* Add static route into static route configuration. */
|
||||||
int
|
int
|
||||||
static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
|
static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
|
||||||
u_char flags, u_short tag, u_char distance, u_int32_t vrf_id)
|
u_char flags, u_short tag, u_char distance, vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
u_char type = 0;
|
u_char type = 0;
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
@ -3034,10 +2926,9 @@ static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
|
|||||||
struct static_route *pp;
|
struct static_route *pp;
|
||||||
struct static_route *cp;
|
struct static_route *cp;
|
||||||
struct static_route *update = NULL;
|
struct static_route *update = NULL;
|
||||||
struct route_table *stable;
|
struct zebra_vrf *zvrf = vrf_info_get (vrf_id);
|
||||||
|
struct route_table *stable = zvrf->stable[AFI_IP][SAFI_UNICAST];
|
||||||
|
|
||||||
/* Lookup table. */
|
|
||||||
stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
|
|
||||||
if (! stable)
|
if (! stable)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -3080,6 +2971,7 @@ static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
|
|||||||
si->distance = distance;
|
si->distance = distance;
|
||||||
si->flags = flags;
|
si->flags = flags;
|
||||||
si->tag = tag;
|
si->tag = tag;
|
||||||
|
si->vrf_id = vrf_id;
|
||||||
|
|
||||||
if (gate)
|
if (gate)
|
||||||
si->addr.ipv4 = *gate;
|
si->addr.ipv4 = *gate;
|
||||||
@ -3122,7 +3014,7 @@ static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
|
|||||||
/* Delete static route from static route configuration. */
|
/* Delete static route from static route configuration. */
|
||||||
int
|
int
|
||||||
static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
|
static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
|
||||||
u_short tag, u_char distance, u_int32_t vrf_id)
|
u_short tag, u_char distance, vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
u_char type = 0;
|
u_char type = 0;
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
@ -3130,7 +3022,7 @@ static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
|
|||||||
struct route_table *stable;
|
struct route_table *stable;
|
||||||
|
|
||||||
/* Lookup table. */
|
/* Lookup table. */
|
||||||
stable = vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
|
stable = zebra_vrf_static_table (AFI_IP, SAFI_UNICAST, vrf_id);
|
||||||
if (! stable)
|
if (! stable)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -3208,8 +3100,8 @@ rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
|
|||||||
|
|
||||||
int
|
int
|
||||||
rib_add_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
|
rib_add_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
|
||||||
struct in6_addr *gate, unsigned int ifindex, u_int32_t table_id,
|
struct in6_addr *gate, unsigned int ifindex, vrf_id_t vrf_id,
|
||||||
u_int32_t metric, u_char distance, safi_t safi)
|
u_int32_t table_id, u_int32_t metric, u_char distance, safi_t safi)
|
||||||
{
|
{
|
||||||
struct rib *rib;
|
struct rib *rib;
|
||||||
struct rib *same = NULL;
|
struct rib *same = NULL;
|
||||||
@ -3220,11 +3112,11 @@ rib_add_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
|
|||||||
/* Lookup table. */
|
/* Lookup table. */
|
||||||
if ((table_id == RT_TABLE_MAIN) || (table_id == zebrad.rtm_table_default))
|
if ((table_id == RT_TABLE_MAIN) || (table_id == zebrad.rtm_table_default))
|
||||||
{
|
{
|
||||||
table = vrf_table (AFI_IP6, safi, 0);
|
table = zebra_vrf_table (AFI_IP6, safi, vrf_id);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
table = vrf_other_route_table(AFI_IP6, table_id, 0);
|
table = zebra_vrf_other_route_table(AFI_IP6, table_id, vrf_id);
|
||||||
}
|
}
|
||||||
if (! table)
|
if (! table)
|
||||||
return 0;
|
return 0;
|
||||||
@ -3280,6 +3172,7 @@ rib_add_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
|
|||||||
rib->flags = flags;
|
rib->flags = flags;
|
||||||
rib->metric = metric;
|
rib->metric = metric;
|
||||||
rib->table = table_id;
|
rib->table = table_id;
|
||||||
|
rib->vrf_id = vrf_id;
|
||||||
rib->nexthop_num = 0;
|
rib->nexthop_num = 0;
|
||||||
rib->uptime = time (NULL);
|
rib->uptime = time (NULL);
|
||||||
|
|
||||||
@ -3340,7 +3233,7 @@ rib_add_ipv6_multipath (struct prefix *p, struct rib *rib, safi_t safi,
|
|||||||
if (!rib)
|
if (!rib)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
table = vrf_table (AFI_IP, safi, 0);
|
table = zebra_vrf_table (AFI_IP, safi, VRF_DEFAULT);
|
||||||
if (!table)
|
if (!table)
|
||||||
return 0;
|
return 0;
|
||||||
/* Make it sure prefixlen is applied to the prefix. */
|
/* Make it sure prefixlen is applied to the prefix. */
|
||||||
@ -3356,11 +3249,11 @@ rib_add_ipv6_multipath (struct prefix *p, struct rib *rib, safi_t safi,
|
|||||||
/* Lookup table. */
|
/* Lookup table. */
|
||||||
if ((table_id == RT_TABLE_MAIN) || (table_id == zebrad.rtm_table_default))
|
if ((table_id == RT_TABLE_MAIN) || (table_id == zebrad.rtm_table_default))
|
||||||
{
|
{
|
||||||
table = vrf_table (AFI_IP6, safi, 0);
|
table = zebra_vrf_table (AFI_IP6, safi, VRF_DEFAULT);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
table = vrf_other_route_table(AFI_IP6, table_id, 0);
|
table = zebra_vrf_other_route_table(AFI_IP6, table_id, VRF_DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! table)
|
if (! table)
|
||||||
@ -3443,7 +3336,8 @@ rib_add_ipv6_multipath (struct prefix *p, struct rib *rib, safi_t safi,
|
|||||||
/* XXX factor with rib_delete_ipv6 */
|
/* XXX factor with rib_delete_ipv6 */
|
||||||
int
|
int
|
||||||
rib_delete_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
|
rib_delete_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
|
||||||
struct in6_addr *gate, unsigned int ifindex, u_int32_t table_id, safi_t safi)
|
struct in6_addr *gate, unsigned int ifindex, vrf_id_t vrf_id,
|
||||||
|
u_int32_t table_id, safi_t safi)
|
||||||
{
|
{
|
||||||
struct route_table *table;
|
struct route_table *table;
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
@ -3461,11 +3355,11 @@ rib_delete_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
|
|||||||
/* Lookup table. */
|
/* Lookup table. */
|
||||||
if ((table_id == RT_TABLE_MAIN) || (table_id == zebrad.rtm_table_default))
|
if ((table_id == RT_TABLE_MAIN) || (table_id == zebrad.rtm_table_default))
|
||||||
{
|
{
|
||||||
table = vrf_table (AFI_IP6, safi, 0);
|
table = zebra_vrf_table (AFI_IP6, safi, vrf_id);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
table = vrf_other_route_table(AFI_IP6, table_id, 0);
|
table = zebra_vrf_other_route_table(AFI_IP6, table_id, VRF_DEFAULT);
|
||||||
}
|
}
|
||||||
if (! table)
|
if (! table)
|
||||||
return 0;
|
return 0;
|
||||||
@ -3477,15 +3371,13 @@ rib_delete_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
|
|||||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||||
{
|
{
|
||||||
if (gate)
|
if (gate)
|
||||||
zlog_debug ("route %s/%d via %s ifindex %d doesn't exist in rib",
|
zlog_debug ("route %s vrf %u via %s ifindex %d doesn't exist in rib",
|
||||||
inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
|
prefix2str (p, buf1, sizeof(buf1)), vrf_id,
|
||||||
p->prefixlen,
|
|
||||||
inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
|
inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
|
||||||
ifindex);
|
ifindex);
|
||||||
else
|
else
|
||||||
zlog_debug ("route %s/%d ifindex %d doesn't exist in rib",
|
zlog_debug ("route %s vrf %u ifindex %d doesn't exist in rib",
|
||||||
inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
|
prefix2str (p, buf1, sizeof(buf1)), vrf_id,
|
||||||
p->prefixlen,
|
|
||||||
ifindex);
|
ifindex);
|
||||||
}
|
}
|
||||||
return ZEBRA_ERR_RTNOEXIST;
|
return ZEBRA_ERR_RTNOEXIST;
|
||||||
@ -3571,16 +3463,15 @@ rib_delete_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
|
|||||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||||
{
|
{
|
||||||
if (gate)
|
if (gate)
|
||||||
zlog_debug ("route %s/%d via %s ifindex %d type %d doesn't exist in rib",
|
zlog_debug ("route %s vrf %u via %s ifindex %d type %d "
|
||||||
inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
|
"doesn't exist in rib",
|
||||||
p->prefixlen,
|
prefix2str (p, buf1, sizeof(buf1)), vrf_id,
|
||||||
inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
|
inet_ntop (AF_INET6, gate, buf2, INET6_ADDRSTRLEN),
|
||||||
ifindex,
|
ifindex,
|
||||||
type);
|
type);
|
||||||
else
|
else
|
||||||
zlog_debug ("route %s/%d ifindex %d type %d doesn't exist in rib",
|
zlog_debug ("route %s vrf %u ifindex %d type %d doesn't exist in rib",
|
||||||
inet_ntop (AF_INET6, &p->prefix, buf1, INET6_ADDRSTRLEN),
|
prefix2str (p, buf1, sizeof(buf1)), vrf_id,
|
||||||
p->prefixlen,
|
|
||||||
ifindex,
|
ifindex,
|
||||||
type);
|
type);
|
||||||
}
|
}
|
||||||
@ -3600,17 +3491,16 @@ rib_delete_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p,
|
|||||||
int
|
int
|
||||||
static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
|
static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
|
||||||
const char *ifname, u_char flags, u_short tag,
|
const char *ifname, u_char flags, u_short tag,
|
||||||
u_char distance, u_int32_t vrf_id)
|
u_char distance, vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
struct static_route *si;
|
struct static_route *si;
|
||||||
struct static_route *pp;
|
struct static_route *pp;
|
||||||
struct static_route *cp;
|
struct static_route *cp;
|
||||||
struct static_route *update = NULL;
|
struct static_route *update = NULL;
|
||||||
struct route_table *stable;
|
struct zebra_vrf *zvrf = vrf_info_get (vrf_id);
|
||||||
|
struct route_table *stable = zvrf->stable[AFI_IP6][SAFI_UNICAST];
|
||||||
|
|
||||||
/* Lookup table. */
|
|
||||||
stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
|
|
||||||
if (! stable)
|
if (! stable)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -3653,6 +3543,7 @@ static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
|
|||||||
si->distance = distance;
|
si->distance = distance;
|
||||||
si->flags = flags;
|
si->flags = flags;
|
||||||
si->tag = tag;
|
si->tag = tag;
|
||||||
|
si->vrf_id = vrf_id;
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
@ -3698,14 +3589,14 @@ static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
|
|||||||
int
|
int
|
||||||
static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
|
static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
|
||||||
const char *ifname, u_short tag, u_char distance,
|
const char *ifname, u_short tag, u_char distance,
|
||||||
u_int32_t vrf_id)
|
vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
struct static_route *si;
|
struct static_route *si;
|
||||||
struct route_table *stable;
|
struct route_table *stable;
|
||||||
|
|
||||||
/* Lookup table. */
|
/* Lookup table. */
|
||||||
stable = vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
|
stable = zebra_vrf_static_table (AFI_IP6, SAFI_UNICAST, vrf_id);
|
||||||
if (! stable)
|
if (! stable)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -3751,13 +3642,13 @@ static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
|
|||||||
|
|
||||||
/* RIB update function. */
|
/* RIB update function. */
|
||||||
void
|
void
|
||||||
rib_update_static (void)
|
rib_update_static (vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
struct route_table *table;
|
struct route_table *table;
|
||||||
struct rib *rib, *next;
|
struct rib *rib, *next;
|
||||||
|
|
||||||
table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
|
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
|
||||||
if (table)
|
if (table)
|
||||||
for (rn = route_top (table); rn; rn = route_next (rn))
|
for (rn = route_top (table); rn; rn = route_next (rn))
|
||||||
RNODE_FOREACH_RIB_SAFE (rn, rib, next)
|
RNODE_FOREACH_RIB_SAFE (rn, rib, next)
|
||||||
@ -3767,7 +3658,7 @@ rib_update_static (void)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
|
table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
|
||||||
if (table)
|
if (table)
|
||||||
for (rn = route_top (table); rn; rn = route_next (rn))
|
for (rn = route_top (table); rn; rn = route_next (rn))
|
||||||
RNODE_FOREACH_RIB_SAFE (rn, rib, next)
|
RNODE_FOREACH_RIB_SAFE (rn, rib, next)
|
||||||
@ -3780,18 +3671,18 @@ rib_update_static (void)
|
|||||||
|
|
||||||
/* RIB update function. */
|
/* RIB update function. */
|
||||||
void
|
void
|
||||||
rib_update (void)
|
rib_update (vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
struct route_table *table;
|
struct route_table *table;
|
||||||
|
|
||||||
table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
|
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id);
|
||||||
if (table)
|
if (table)
|
||||||
for (rn = route_top (table); rn; rn = route_next (rn))
|
for (rn = route_top (table); rn; rn = route_next (rn))
|
||||||
if (rnode_to_ribs (rn))
|
if (rnode_to_ribs (rn))
|
||||||
rib_queue_add (&zebrad, rn);
|
rib_queue_add (&zebrad, rn);
|
||||||
|
|
||||||
table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
|
table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id);
|
||||||
if (table)
|
if (table)
|
||||||
for (rn = route_top (table); rn; rn = route_next (rn))
|
for (rn = route_top (table); rn; rn = route_next (rn))
|
||||||
if (rnode_to_ribs (rn))
|
if (rnode_to_ribs (rn))
|
||||||
@ -3824,8 +3715,15 @@ rib_weed_table (struct route_table *table)
|
|||||||
void
|
void
|
||||||
rib_weed_tables (void)
|
rib_weed_tables (void)
|
||||||
{
|
{
|
||||||
rib_weed_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
|
vrf_iter_t iter;
|
||||||
rib_weed_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
|
struct zebra_vrf *zvrf;
|
||||||
|
|
||||||
|
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||||
|
if ((zvrf = vrf_iter2info (iter)) != NULL)
|
||||||
|
{
|
||||||
|
rib_weed_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
|
||||||
|
rib_weed_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delete self installed routes after zebra is relaunched. */
|
/* Delete self installed routes after zebra is relaunched. */
|
||||||
@ -3858,8 +3756,15 @@ rib_sweep_table (struct route_table *table)
|
|||||||
void
|
void
|
||||||
rib_sweep_route (void)
|
rib_sweep_route (void)
|
||||||
{
|
{
|
||||||
rib_sweep_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
|
vrf_iter_t iter;
|
||||||
rib_sweep_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
|
struct zebra_vrf *zvrf;
|
||||||
|
|
||||||
|
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||||
|
if ((zvrf = vrf_iter2info (iter)) != NULL)
|
||||||
|
{
|
||||||
|
rib_sweep_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
|
||||||
|
rib_sweep_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove specific by protocol routes from 'table'. */
|
/* Remove specific by protocol routes from 'table'. */
|
||||||
@ -3891,12 +3796,20 @@ rib_score_proto_table (u_char proto, u_short instance, struct route_table *table
|
|||||||
unsigned long
|
unsigned long
|
||||||
rib_score_proto (u_char proto, u_short instance)
|
rib_score_proto (u_char proto, u_short instance)
|
||||||
{
|
{
|
||||||
return rib_score_proto_table (proto, instance, vrf_table (AFI_IP, SAFI_UNICAST, 0))
|
vrf_iter_t iter;
|
||||||
+rib_score_proto_table (proto, instance, vrf_table (AFI_IP6, SAFI_UNICAST, 0));
|
struct zebra_vrf *zvrf;
|
||||||
|
unsigned long cnt = 0;
|
||||||
|
|
||||||
|
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||||
|
if ((zvrf = vrf_iter2info (iter)) != NULL)
|
||||||
|
cnt += rib_score_proto_table (proto, instance, zvrf->table[AFI_IP][SAFI_UNICAST])
|
||||||
|
+rib_score_proto_table (proto, instance, zvrf->table[AFI_IP6][SAFI_UNICAST]);
|
||||||
|
|
||||||
|
return cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Close RIB and clean up kernel routes. */
|
/* Close RIB and clean up kernel routes. */
|
||||||
static void
|
void
|
||||||
rib_close_table (struct route_table *table)
|
rib_close_table (struct route_table *table)
|
||||||
{
|
{
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
@ -3920,14 +3833,21 @@ rib_close_table (struct route_table *table)
|
|||||||
void
|
void
|
||||||
rib_close (void)
|
rib_close (void)
|
||||||
{
|
{
|
||||||
struct listnode *node, *nnode;
|
vrf_iter_t iter;
|
||||||
|
struct zebra_vrf *zvrf;
|
||||||
|
struct listnode *node;
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
|
|
||||||
rib_close_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
|
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||||
rib_close_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
|
{
|
||||||
|
if ((zvrf = vrf_iter2info (iter)) != NULL)
|
||||||
for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
|
{
|
||||||
if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp);
|
rib_close_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
|
||||||
|
rib_close_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
|
||||||
|
}
|
||||||
|
for (ALL_LIST_ELEMENTS_RO (vrf_iter2iflist (iter), node, ifp))
|
||||||
|
if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Routing information base initialize. */
|
/* Routing information base initialize. */
|
||||||
@ -3935,8 +3855,6 @@ void
|
|||||||
rib_init (void)
|
rib_init (void)
|
||||||
{
|
{
|
||||||
rib_queue_init (&zebrad);
|
rib_queue_init (&zebrad);
|
||||||
/* VRF initialization. */
|
|
||||||
vrf_init ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3947,15 +3865,19 @@ rib_init (void)
|
|||||||
* Returns TRUE if a vrf id was found, FALSE otherwise.
|
* Returns TRUE if a vrf id was found, FALSE otherwise.
|
||||||
*/
|
*/
|
||||||
static inline int
|
static inline int
|
||||||
vrf_id_get_next (uint32_t id, uint32_t *next_id_p)
|
vrf_id_get_next (vrf_id_t vrf_id, vrf_id_t *next_id_p)
|
||||||
{
|
{
|
||||||
while (++id < vector_active (vrf_vector))
|
vrf_iter_t iter = vrf_iterator (vrf_id);
|
||||||
|
struct zebra_vrf *zvrf = vrf_iter2info (iter);
|
||||||
|
|
||||||
|
/* The same one ? Then find out the next. */
|
||||||
|
if (zvrf && (zvrf->vrf_id == vrf_id))
|
||||||
|
zvrf = vrf_iter2info (vrf_next (iter));
|
||||||
|
|
||||||
|
if (zvrf)
|
||||||
{
|
{
|
||||||
if (vrf_lookup (id))
|
*next_id_p = zvrf->vrf_id;
|
||||||
{
|
return 1;
|
||||||
*next_id_p = id;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -4003,7 +3925,7 @@ rib_tables_iter_next (rib_tables_iter_t *iter)
|
|||||||
|
|
||||||
while (iter->afi_safi_ix < (int) ZEBRA_NUM_OF (afi_safis))
|
while (iter->afi_safi_ix < (int) ZEBRA_NUM_OF (afi_safis))
|
||||||
{
|
{
|
||||||
table = vrf_table (afi_safis[iter->afi_safi_ix].afi,
|
table = zebra_vrf_table (afi_safis[iter->afi_safi_ix].afi,
|
||||||
afi_safis[iter->afi_safi_ix].safi,
|
afi_safis[iter->afi_safi_ix].safi,
|
||||||
iter->vrf_id);
|
iter->vrf_id);
|
||||||
if (table)
|
if (table)
|
||||||
@ -4041,3 +3963,130 @@ rib_tables_iter_next (rib_tables_iter_t *iter)
|
|||||||
|
|
||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a routing table for the specific AFI/SAFI in the given VRF.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
zebra_vrf_table_create (struct zebra_vrf *zvrf, afi_t afi, safi_t safi)
|
||||||
|
{
|
||||||
|
rib_table_info_t *info;
|
||||||
|
struct route_table *table;
|
||||||
|
|
||||||
|
assert (!zvrf->table[afi][safi]);
|
||||||
|
|
||||||
|
table = route_table_init ();
|
||||||
|
zvrf->table[afi][safi] = table;
|
||||||
|
|
||||||
|
info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info));
|
||||||
|
info->zvrf = zvrf;
|
||||||
|
info->afi = afi;
|
||||||
|
info->safi = safi;
|
||||||
|
table->info = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate new zebra VRF. */
|
||||||
|
struct zebra_vrf *
|
||||||
|
zebra_vrf_alloc (vrf_id_t vrf_id)
|
||||||
|
{
|
||||||
|
struct zebra_vrf *zvrf;
|
||||||
|
#ifdef HAVE_NETLINK
|
||||||
|
char nl_name[64];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
zvrf = XCALLOC (MTYPE_ZEBRA_VRF, sizeof (struct zebra_vrf));
|
||||||
|
|
||||||
|
/* Allocate routing table and static table. */
|
||||||
|
zebra_vrf_table_create (zvrf, AFI_IP, SAFI_UNICAST);
|
||||||
|
zebra_vrf_table_create (zvrf, AFI_IP6, SAFI_UNICAST);
|
||||||
|
zvrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init ();
|
||||||
|
zvrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init ();
|
||||||
|
zebra_vrf_table_create (zvrf, AFI_IP, SAFI_MULTICAST);
|
||||||
|
zebra_vrf_table_create (zvrf, AFI_IP6, SAFI_MULTICAST);
|
||||||
|
zvrf->stable[AFI_IP][SAFI_MULTICAST] = route_table_init ();
|
||||||
|
zvrf->stable[AFI_IP6][SAFI_MULTICAST] = route_table_init ();
|
||||||
|
|
||||||
|
zvrf->rnh_table[AFI_IP] = route_table_init();
|
||||||
|
zvrf->rnh_table[AFI_IP6] = route_table_init();
|
||||||
|
|
||||||
|
zvrf->import_check_table[AFI_IP] = route_table_init();
|
||||||
|
zvrf->import_check_table[AFI_IP6] = route_table_init();
|
||||||
|
|
||||||
|
/* Set VRF ID */
|
||||||
|
zvrf->vrf_id = vrf_id;
|
||||||
|
|
||||||
|
#ifdef HAVE_NETLINK
|
||||||
|
/* Initialize netlink sockets */
|
||||||
|
snprintf (nl_name, 64, "netlink-listen (vrf %u)", vrf_id);
|
||||||
|
zvrf->netlink.sock = -1;
|
||||||
|
zvrf->netlink.name = XSTRDUP (MTYPE_NETLINK_NAME, nl_name);
|
||||||
|
|
||||||
|
snprintf (nl_name, 64, "netlink-cmd (vrf %u)", vrf_id);
|
||||||
|
zvrf->netlink_cmd.sock = -1;
|
||||||
|
zvrf->netlink_cmd.name = XSTRDUP (MTYPE_NETLINK_NAME, nl_name);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return zvrf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Lookup VRF by identifier. */
|
||||||
|
struct zebra_vrf *
|
||||||
|
zebra_vrf_lookup (vrf_id_t vrf_id)
|
||||||
|
{
|
||||||
|
return vrf_info_lookup (vrf_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Lookup the routing table in an enabled VRF. */
|
||||||
|
struct route_table *
|
||||||
|
zebra_vrf_table (afi_t afi, safi_t safi, vrf_id_t vrf_id)
|
||||||
|
{
|
||||||
|
struct zebra_vrf *zvrf = vrf_info_lookup (vrf_id);
|
||||||
|
|
||||||
|
if (!zvrf)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (afi >= AFI_MAX || safi >= SAFI_MAX)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return zvrf->table[afi][safi];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Lookup the static routing table in a VRF. */
|
||||||
|
struct route_table *
|
||||||
|
zebra_vrf_static_table (afi_t afi, safi_t safi, vrf_id_t vrf_id)
|
||||||
|
{
|
||||||
|
struct zebra_vrf *zvrf = vrf_info_lookup (vrf_id);
|
||||||
|
|
||||||
|
if (!zvrf)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (afi >= AFI_MAX || safi >= SAFI_MAX)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return zvrf->stable[afi][safi];
|
||||||
|
}
|
||||||
|
|
||||||
|
struct route_table *
|
||||||
|
zebra_vrf_other_route_table (afi_t afi, u_int32_t table_id, vrf_id_t vrf_id)
|
||||||
|
{
|
||||||
|
struct zebra_vrf *zvrf;
|
||||||
|
|
||||||
|
zvrf = vrf_info_lookup (vrf_id);
|
||||||
|
if (! zvrf)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if(afi >= AFI_MAX)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (table_id >= ZEBRA_KERNEL_TABLE_MAX)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (zvrf->other_table[afi][table_id] == NULL)
|
||||||
|
{
|
||||||
|
zvrf->other_table[afi][table_id] = route_table_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (zvrf->other_table[afi][table_id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include "routemap.h"
|
#include "routemap.h"
|
||||||
#include "stream.h"
|
#include "stream.h"
|
||||||
#include "nexthop.h"
|
#include "nexthop.h"
|
||||||
|
#include "vrf.h"
|
||||||
|
|
||||||
#include "zebra/rib.h"
|
#include "zebra/rib.h"
|
||||||
#include "zebra/rt.h"
|
#include "zebra/rt.h"
|
||||||
@ -50,6 +51,16 @@ extern struct zebra_t zebrad;
|
|||||||
static void free_state(struct rib *rib, struct route_node *rn);
|
static void free_state(struct rib *rib, struct route_node *rn);
|
||||||
static void copy_state(struct rnh *rnh, struct rib *rib,
|
static void copy_state(struct rnh *rnh, struct rib *rib,
|
||||||
struct route_node *rn);
|
struct route_node *rn);
|
||||||
|
#define lookup_rnh_table(v, f) \
|
||||||
|
({ \
|
||||||
|
struct zebra_vrf *zvrf; \
|
||||||
|
struct route_table *t = NULL; \
|
||||||
|
zvrf = zebra_vrf_lookup(v); \
|
||||||
|
if (zvrf) \
|
||||||
|
t = zvrf->rnh_table[family2afi(f)]; \
|
||||||
|
t; \
|
||||||
|
})
|
||||||
|
|
||||||
static int compare_state(struct rib *r1, struct rib *r2);
|
static int compare_state(struct rib *r1, struct rib *r2);
|
||||||
static int send_client(struct rnh *rnh, struct zserv *client, rnh_type_t type);
|
static int send_client(struct rnh *rnh, struct zserv *client, rnh_type_t type);
|
||||||
static void print_rnh(struct route_node *rn, struct vty *vty);
|
static void print_rnh(struct route_node *rn, struct vty *vty);
|
||||||
@ -57,21 +68,21 @@ static void print_rnh(struct route_node *rn, struct vty *vty);
|
|||||||
int zebra_rnh_ip_default_route = 0;
|
int zebra_rnh_ip_default_route = 0;
|
||||||
int zebra_rnh_ipv6_default_route = 0;
|
int zebra_rnh_ipv6_default_route = 0;
|
||||||
|
|
||||||
static inline struct route_table *get_rnh_table(int vrfid, int family,
|
static inline struct route_table *get_rnh_table(vrf_id_t vrfid, int family,
|
||||||
rnh_type_t type)
|
rnh_type_t type)
|
||||||
{
|
{
|
||||||
struct vrf *vrf;
|
struct zebra_vrf *zvrf;
|
||||||
struct route_table *t = NULL;
|
struct route_table *t = NULL;
|
||||||
|
|
||||||
vrf = vrf_lookup(vrfid);
|
zvrf = zebra_vrf_lookup(vrfid);
|
||||||
if (vrf)
|
if (zvrf)
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case RNH_NEXTHOP_TYPE:
|
case RNH_NEXTHOP_TYPE:
|
||||||
t = vrf->rnh_table[family2afi(family)];
|
t = zvrf->rnh_table[family2afi(family)];
|
||||||
break;
|
break;
|
||||||
case RNH_IMPORT_CHECK_TYPE:
|
case RNH_IMPORT_CHECK_TYPE:
|
||||||
t = vrf->import_check_table[family2afi(family)];
|
t = zvrf->import_check_table[family2afi(family)];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +96,7 @@ char *rnh_str (struct rnh *rnh, char *buf, int size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct rnh *
|
struct rnh *
|
||||||
zebra_add_rnh (struct prefix *p, u_int32_t vrfid, rnh_type_t type)
|
zebra_add_rnh (struct prefix *p, vrf_id_t vrfid, rnh_type_t type)
|
||||||
{
|
{
|
||||||
struct route_table *table;
|
struct route_table *table;
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
@ -125,7 +136,7 @@ zebra_add_rnh (struct prefix *p, u_int32_t vrfid, rnh_type_t type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct rnh *
|
struct rnh *
|
||||||
zebra_lookup_rnh (struct prefix *p, u_int32_t vrfid, rnh_type_t type)
|
zebra_lookup_rnh (struct prefix *p, vrf_id_t vrfid, rnh_type_t type)
|
||||||
{
|
{
|
||||||
struct route_table *table;
|
struct route_table *table;
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
@ -262,7 +273,7 @@ zebra_evaluate_rnh_nexthops(int family, struct rib *rib, struct route_node *prn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
zebra_evaluate_rnh (int vrfid, int family, int force, rnh_type_t type,
|
zebra_evaluate_rnh (vrf_id_t vrfid, int family, int force, rnh_type_t type,
|
||||||
struct prefix *p)
|
struct prefix *p)
|
||||||
{
|
{
|
||||||
struct route_table *ptable;
|
struct route_table *ptable;
|
||||||
@ -289,7 +300,7 @@ zebra_evaluate_rnh (int vrfid, int family, int force, rnh_type_t type,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptable = vrf_table(family2afi(family), SAFI_UNICAST, vrfid);
|
ptable = zebra_vrf_table(family2afi(family), SAFI_UNICAST, vrfid);
|
||||||
if (!ptable)
|
if (!ptable)
|
||||||
{
|
{
|
||||||
zlog_debug("evaluate_rnh_table: prefix table not found\n");
|
zlog_debug("evaluate_rnh_table: prefix table not found\n");
|
||||||
@ -557,7 +568,7 @@ zebra_evaluate_rnh (int vrfid, int family, int force, rnh_type_t type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
zebra_dispatch_rnh_table (int vrfid, int family, struct zserv *client,
|
zebra_dispatch_rnh_table (vrf_id_t vrfid, int family, struct zserv *client,
|
||||||
rnh_type_t type)
|
rnh_type_t type)
|
||||||
{
|
{
|
||||||
struct route_table *ntable;
|
struct route_table *ntable;
|
||||||
@ -591,7 +602,7 @@ zebra_dispatch_rnh_table (int vrfid, int family, struct zserv *client,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
zebra_print_rnh_table (int vrfid, int af, struct vty *vty, rnh_type_t type)
|
zebra_print_rnh_table (vrf_id_t vrfid, int af, struct vty *vty, rnh_type_t type)
|
||||||
{
|
{
|
||||||
struct route_table *table;
|
struct route_table *table;
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
@ -609,7 +620,7 @@ zebra_print_rnh_table (int vrfid, int af, struct vty *vty, rnh_type_t type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
zebra_cleanup_rnh_client (int vrfid, int family, struct zserv *client,
|
zebra_cleanup_rnh_client (vrf_id_t vrfid, int family, struct zserv *client,
|
||||||
rnh_type_t type)
|
rnh_type_t type)
|
||||||
{
|
{
|
||||||
struct route_table *ntable;
|
struct route_table *ntable;
|
||||||
|
@ -52,9 +52,9 @@ typedef enum
|
|||||||
extern int zebra_rnh_ip_default_route;
|
extern int zebra_rnh_ip_default_route;
|
||||||
extern int zebra_rnh_ipv6_default_route;
|
extern int zebra_rnh_ipv6_default_route;
|
||||||
|
|
||||||
extern struct rnh *zebra_add_rnh(struct prefix *p, u_int32_t vrfid,
|
extern struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid,
|
||||||
rnh_type_t type);
|
rnh_type_t type);
|
||||||
extern struct rnh *zebra_lookup_rnh(struct prefix *p, u_int32_t vrfid,
|
extern struct rnh *zebra_lookup_rnh(struct prefix *p, vrf_id_t vrfid,
|
||||||
rnh_type_t type);
|
rnh_type_t type);
|
||||||
extern void zebra_delete_rnh(struct rnh *rnh, rnh_type_t type);
|
extern void zebra_delete_rnh(struct rnh *rnh, rnh_type_t type);
|
||||||
extern void zebra_add_rnh_client(struct rnh *rnh, struct zserv *client, rnh_type_t type);
|
extern void zebra_add_rnh_client(struct rnh *rnh, struct zserv *client, rnh_type_t type);
|
||||||
@ -62,11 +62,11 @@ extern void zebra_register_rnh_static_nh(struct prefix *, struct route_node *);
|
|||||||
extern void zebra_deregister_rnh_static_nh(struct prefix *, struct route_node *);
|
extern void zebra_deregister_rnh_static_nh(struct prefix *, struct route_node *);
|
||||||
extern void zebra_remove_rnh_client(struct rnh *rnh, struct zserv *client,
|
extern void zebra_remove_rnh_client(struct rnh *rnh, struct zserv *client,
|
||||||
rnh_type_t type);
|
rnh_type_t type);
|
||||||
extern int zebra_evaluate_rnh(int vrfid, int family, int force, rnh_type_t type,
|
extern int zebra_evaluate_rnh(vrf_id_t vrfid, int family, int force, rnh_type_t type,
|
||||||
struct prefix *p);
|
struct prefix *p);
|
||||||
extern int zebra_dispatch_rnh_table(int vrfid, int family, struct zserv *cl, rnh_type_t);
|
extern int zebra_dispatch_rnh_table(vrf_id_t vrfid, int family, struct zserv *cl, rnh_type_t);
|
||||||
extern void zebra_print_rnh_table(int vrfid, int family, struct vty *vty, rnh_type_t);
|
extern void zebra_print_rnh_table(vrf_id_t vrfid, int family, struct vty *vty, rnh_type_t);
|
||||||
extern char *rnh_str(struct rnh *rnh, char *buf, int size);
|
extern char *rnh_str(struct rnh *rnh, char *buf, int size);
|
||||||
extern int zebra_cleanup_rnh_client(int vrf, int family, struct zserv *client,
|
extern int zebra_cleanup_rnh_client(vrf_id_t vrf, int family, struct zserv *client,
|
||||||
rnh_type_t type);
|
rnh_type_t type);
|
||||||
#endif /*_ZEBRA_RNH_H */
|
#endif /*_ZEBRA_RNH_H */
|
||||||
|
@ -6,11 +6,11 @@
|
|||||||
int zebra_rnh_ip_default_route = 0;
|
int zebra_rnh_ip_default_route = 0;
|
||||||
int zebra_rnh_ipv6_default_route = 0;
|
int zebra_rnh_ipv6_default_route = 0;
|
||||||
|
|
||||||
int zebra_evaluate_rnh (int vrfid, int family, int force, rnh_type_t type,
|
int zebra_evaluate_rnh (vrf_id_t vrfid, int family, int force, rnh_type_t type,
|
||||||
struct prefix *p)
|
struct prefix *p)
|
||||||
{ return 0; }
|
{ return 0; }
|
||||||
|
|
||||||
void zebra_print_rnh_table (int vrfid, int family, struct vty *vty,
|
void zebra_print_rnh_table (vrf_id_t vrfid, int family, struct vty *vty,
|
||||||
rnh_type_t type)
|
rnh_type_t type)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "plist.h"
|
#include "plist.h"
|
||||||
#include "nexthop.h"
|
#include "nexthop.h"
|
||||||
|
#include "vrf.h"
|
||||||
|
|
||||||
#include "zebra/zserv.h"
|
#include "zebra/zserv.h"
|
||||||
#include "zebra/debug.h"
|
#include "zebra/debug.h"
|
||||||
@ -45,6 +46,7 @@ extern struct zebra_t zebrad;
|
|||||||
struct nh_rmap_obj
|
struct nh_rmap_obj
|
||||||
{
|
{
|
||||||
struct nexthop *nexthop;
|
struct nexthop *nexthop;
|
||||||
|
vrf_id_t vrf_id;
|
||||||
u_int32_t source_protocol;
|
u_int32_t source_protocol;
|
||||||
int metric;
|
int metric;
|
||||||
u_short tag;
|
u_short tag;
|
||||||
@ -255,12 +257,12 @@ route_match_interface (void *rule, struct prefix *prefix,
|
|||||||
{
|
{
|
||||||
if (strcasecmp(ifname, "any") == 0)
|
if (strcasecmp(ifname, "any") == 0)
|
||||||
return RMAP_MATCH;
|
return RMAP_MATCH;
|
||||||
ifindex = ifname2ifindex(ifname);
|
|
||||||
if (ifindex == 0)
|
|
||||||
return RMAP_NOMATCH;
|
|
||||||
nh_data = object;
|
nh_data = object;
|
||||||
if (!nh_data || !nh_data->nexthop)
|
if (!nh_data || !nh_data->nexthop)
|
||||||
return RMAP_NOMATCH;
|
return RMAP_NOMATCH;
|
||||||
|
ifindex = ifname2ifindex_vrf (ifname, nh_data->vrf_id);
|
||||||
|
if (ifindex == 0)
|
||||||
|
return RMAP_NOMATCH;
|
||||||
if (nh_data->nexthop->ifindex == ifindex)
|
if (nh_data->nexthop->ifindex == ifindex)
|
||||||
return RMAP_MATCH;
|
return RMAP_MATCH;
|
||||||
}
|
}
|
||||||
@ -657,6 +659,7 @@ DEFUN (set_src,
|
|||||||
struct interface *pif = NULL;
|
struct interface *pif = NULL;
|
||||||
int family;
|
int family;
|
||||||
struct prefix p;
|
struct prefix p;
|
||||||
|
vrf_iter_t iter;
|
||||||
|
|
||||||
if (inet_pton(AF_INET, argv[0], &src.ipv4) != 1)
|
if (inet_pton(AF_INET, argv[0], &src.ipv4) != 1)
|
||||||
{
|
{
|
||||||
@ -683,10 +686,18 @@ DEFUN (set_src,
|
|||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (family == AF_INET)
|
for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
|
||||||
pif = if_lookup_exact_address ((void *)&src.ipv4, AF_INET);
|
{
|
||||||
else if (family == AF_INET6)
|
if (family == AF_INET)
|
||||||
pif = if_lookup_exact_address ((void *)&src.ipv6, AF_INET6);
|
pif = if_lookup_exact_address_vrf ((void *)&src.ipv4, AF_INET,
|
||||||
|
vrf_iter2id (iter));
|
||||||
|
else if (family == AF_INET6)
|
||||||
|
pif = if_lookup_exact_address_vrf ((void *)&src.ipv6, AF_INET6,
|
||||||
|
vrf_iter2id (iter));
|
||||||
|
|
||||||
|
if (pif != NULL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (!pif)
|
if (!pif)
|
||||||
{
|
{
|
||||||
@ -767,7 +778,7 @@ DEFUN (ip_protocol,
|
|||||||
if (IS_ZEBRA_DEBUG_RIB)
|
if (IS_ZEBRA_DEBUG_RIB)
|
||||||
zlog_debug ("%s: calling rib_update", __func__);
|
zlog_debug ("%s: calling rib_update", __func__);
|
||||||
|
|
||||||
rib_update();
|
rib_update(VRF_DEFAULT);
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -804,7 +815,7 @@ DEFUN (no_ip_protocol,
|
|||||||
if (IS_ZEBRA_DEBUG_RIB)
|
if (IS_ZEBRA_DEBUG_RIB)
|
||||||
zlog_debug ("%s: calling rib_update", __func__);
|
zlog_debug ("%s: calling rib_update", __func__);
|
||||||
|
|
||||||
rib_update();
|
rib_update(VRF_DEFAULT);
|
||||||
}
|
}
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -879,7 +890,7 @@ DEFUN (ipv6_protocol,
|
|||||||
if (IS_ZEBRA_DEBUG_RIB)
|
if (IS_ZEBRA_DEBUG_RIB)
|
||||||
zlog_debug ("%s: calling rib_update", __func__);
|
zlog_debug ("%s: calling rib_update", __func__);
|
||||||
|
|
||||||
rib_update();
|
rib_update(VRF_DEFAULT);
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -916,7 +927,7 @@ DEFUN (no_ipv6_protocol,
|
|||||||
if (IS_ZEBRA_DEBUG_RIB)
|
if (IS_ZEBRA_DEBUG_RIB)
|
||||||
zlog_debug ("%s: calling rib_update", __func__);
|
zlog_debug ("%s: calling rib_update", __func__);
|
||||||
|
|
||||||
rib_update();
|
rib_update(VRF_DEFAULT);
|
||||||
}
|
}
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -1590,7 +1601,7 @@ zebra_route_map_update_timer (struct thread *thread)
|
|||||||
if (IS_ZEBRA_DEBUG_RIB)
|
if (IS_ZEBRA_DEBUG_RIB)
|
||||||
zlog_debug ("%s: calling rib_update", __func__);
|
zlog_debug ("%s: calling rib_update", __func__);
|
||||||
|
|
||||||
rib_update();
|
rib_update(VRF_DEFAULT);
|
||||||
zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
|
zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL);
|
||||||
zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
|
zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL);
|
||||||
|
|
||||||
@ -1621,13 +1632,14 @@ zebra_route_map_write_delay_timer (struct vty *vty)
|
|||||||
|
|
||||||
route_map_result_t
|
route_map_result_t
|
||||||
zebra_route_map_check (int family, int rib_type, struct prefix *p,
|
zebra_route_map_check (int family, int rib_type, struct prefix *p,
|
||||||
struct nexthop *nexthop, u_short tag)
|
struct nexthop *nexthop, vrf_id_t vrf_id, u_short tag)
|
||||||
{
|
{
|
||||||
struct route_map *rmap = NULL;
|
struct route_map *rmap = NULL;
|
||||||
route_map_result_t ret = RMAP_MATCH;
|
route_map_result_t ret = RMAP_MATCH;
|
||||||
struct nh_rmap_obj nh_obj;
|
struct nh_rmap_obj nh_obj;
|
||||||
|
|
||||||
nh_obj.nexthop = nexthop;
|
nh_obj.nexthop = nexthop;
|
||||||
|
nh_obj.vrf_id = vrf_id;
|
||||||
nh_obj.source_protocol = rib_type;
|
nh_obj.source_protocol = rib_type;
|
||||||
nh_obj.metric = 0;
|
nh_obj.metric = 0;
|
||||||
nh_obj.tag = tag;
|
nh_obj.tag = tag;
|
||||||
@ -1652,6 +1664,7 @@ zebra_nht_route_map_check (int family, int client_proto, struct prefix *p,
|
|||||||
struct nh_rmap_obj nh_obj;
|
struct nh_rmap_obj nh_obj;
|
||||||
|
|
||||||
nh_obj.nexthop = nexthop;
|
nh_obj.nexthop = nexthop;
|
||||||
|
nh_obj.vrf_id = rib->vrf_id;
|
||||||
nh_obj.source_protocol = rib->type;
|
nh_obj.source_protocol = rib->type;
|
||||||
nh_obj.metric = rib->metric;
|
nh_obj.metric = rib->metric;
|
||||||
nh_obj.tag = rib->tag;
|
nh_obj.tag = rib->tag;
|
||||||
|
@ -19,6 +19,10 @@
|
|||||||
* 02111-1307, USA.
|
* 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Currently SNMP is only running properly for MIBs in the default VRF.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <zebra.h>
|
#include <zebra.h>
|
||||||
|
|
||||||
#ifdef HAVE_SNMP
|
#ifdef HAVE_SNMP
|
||||||
@ -31,6 +35,7 @@
|
|||||||
#include "command.h"
|
#include "command.h"
|
||||||
#include "smux.h"
|
#include "smux.h"
|
||||||
#include "table.h"
|
#include "table.h"
|
||||||
|
#include "vrf.h"
|
||||||
|
|
||||||
#include "zebra/rib.h"
|
#include "zebra/rib.h"
|
||||||
#include "zebra/zserv.h"
|
#include "zebra/zserv.h"
|
||||||
@ -143,7 +148,7 @@ ipFwNumber (struct variable *v, oid objid[], size_t *objid_len,
|
|||||||
if (smux_header_generic(v, objid, objid_len, exact, val_len, write_method) == MATCH_FAILED)
|
if (smux_header_generic(v, objid, objid_len, exact, val_len, write_method) == MATCH_FAILED)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
|
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
|
||||||
if (! table)
|
if (! table)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -168,7 +173,7 @@ ipCidrNumber (struct variable *v, oid objid[], size_t *objid_len,
|
|||||||
if (smux_header_generic(v, objid, objid_len, exact, val_len, write_method) == MATCH_FAILED)
|
if (smux_header_generic(v, objid, objid_len, exact, val_len, write_method) == MATCH_FAILED)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
|
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
|
||||||
if (! table)
|
if (! table)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -330,7 +335,7 @@ get_fwtable_route_node(struct variable *v, oid objid[], size_t *objid_len,
|
|||||||
if (exact && (*objid_len != (unsigned) v->namelen + 10))
|
if (exact && (*objid_len != (unsigned) v->namelen + 10))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
|
table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
|
||||||
if (! table)
|
if (! table)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
2788
zebra/zebra_vty.c
2788
zebra/zebra_vty.c
File diff suppressed because it is too large
Load Diff
@ -37,6 +37,7 @@
|
|||||||
#include "network.h"
|
#include "network.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "nexthop.h"
|
#include "nexthop.h"
|
||||||
|
#include "vrf.h"
|
||||||
|
|
||||||
#include "zebra/zserv.h"
|
#include "zebra/zserv.h"
|
||||||
#include "zebra/router-id.h"
|
#include "zebra/router-id.h"
|
||||||
@ -643,7 +644,7 @@ zsend_ipv6_nexthop_lookup (struct zserv *client, struct in6_addr *addr)
|
|||||||
struct nexthop *nexthop;
|
struct nexthop *nexthop;
|
||||||
|
|
||||||
/* Lookup nexthop. */
|
/* Lookup nexthop. */
|
||||||
rib = rib_match_ipv6 (addr);
|
rib = rib_match_ipv6 (addr, VRF_DEFAULT);
|
||||||
|
|
||||||
/* Get output stream. */
|
/* Get output stream. */
|
||||||
s = client->obuf;
|
s = client->obuf;
|
||||||
@ -710,7 +711,7 @@ zsend_ipv4_nexthop_lookup (struct zserv *client, struct in_addr addr)
|
|||||||
struct nexthop *nexthop;
|
struct nexthop *nexthop;
|
||||||
|
|
||||||
/* Lookup nexthop. */
|
/* Lookup nexthop. */
|
||||||
rib = rib_match_ipv4 (addr);
|
rib = rib_match_ipv4 (addr, VRF_DEFAULT);
|
||||||
|
|
||||||
/* Get output stream. */
|
/* Get output stream. */
|
||||||
s = client->obuf;
|
s = client->obuf;
|
||||||
@ -892,7 +893,7 @@ zsend_ipv4_import_lookup (struct zserv *client, struct prefix_ipv4 *p)
|
|||||||
struct nexthop *nexthop;
|
struct nexthop *nexthop;
|
||||||
|
|
||||||
/* Lookup nexthop. */
|
/* Lookup nexthop. */
|
||||||
rib = rib_lookup_ipv4 (p);
|
rib = rib_lookup_ipv4 (p, VRF_DEFAULT);
|
||||||
|
|
||||||
/* Get output stream. */
|
/* Get output stream. */
|
||||||
s = client->obuf;
|
s = client->obuf;
|
||||||
@ -947,7 +948,8 @@ zsend_ipv4_import_lookup (struct zserv *client, struct prefix_ipv4 *p)
|
|||||||
|
|
||||||
/* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */
|
/* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */
|
||||||
int
|
int
|
||||||
zsend_router_id_update (struct zserv *client, struct prefix *p)
|
zsend_router_id_update (struct zserv *client, struct prefix *p,
|
||||||
|
vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
struct stream *s;
|
struct stream *s;
|
||||||
int blen;
|
int blen;
|
||||||
@ -1076,6 +1078,9 @@ zread_ipv4_add (struct zserv *client, u_short length)
|
|||||||
p.prefixlen = stream_getc (s);
|
p.prefixlen = stream_getc (s);
|
||||||
stream_get (&p.prefix, s, PSIZE (p.prefixlen));
|
stream_get (&p.prefix, s, PSIZE (p.prefixlen));
|
||||||
|
|
||||||
|
/* VRF ID */
|
||||||
|
rib->vrf_id = VRF_DEFAULT;
|
||||||
|
|
||||||
/* Nexthop parse. */
|
/* Nexthop parse. */
|
||||||
if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
|
if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP))
|
||||||
{
|
{
|
||||||
@ -1231,7 +1236,7 @@ zread_ipv4_delete (struct zserv *client, u_short length)
|
|||||||
api.tag = 0;
|
api.tag = 0;
|
||||||
|
|
||||||
rib_delete_ipv4 (api.type, api.instance, api.flags, &p, nexthop_p, ifindex,
|
rib_delete_ipv4 (api.type, api.instance, api.flags, &p, nexthop_p, ifindex,
|
||||||
client->rtm_table, api.safi);
|
VRF_DEFAULT, client->rtm_table, api.safi);
|
||||||
client->v4_route_del_cnt++;
|
client->v4_route_del_cnt++;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1505,6 +1510,7 @@ zread_ipv6_add (struct zserv *client, u_short length)
|
|||||||
|
|
||||||
/* Table */
|
/* Table */
|
||||||
rib->table=zebrad.rtm_table_default;
|
rib->table=zebrad.rtm_table_default;
|
||||||
|
rib->vrf_id = VRF_DEFAULT;
|
||||||
ret = rib_add_ipv6_multipath ((struct prefix *)&p, rib, safi, ifindex);
|
ret = rib_add_ipv6_multipath ((struct prefix *)&p, rib, safi, ifindex);
|
||||||
/* Stats */
|
/* Stats */
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
@ -1584,9 +1590,11 @@ zread_ipv6_delete (struct zserv *client, u_short length)
|
|||||||
api.tag = 0;
|
api.tag = 0;
|
||||||
|
|
||||||
if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
|
if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
|
||||||
rib_delete_ipv6 (api.type, api.instance, api.flags, &p, NULL, ifindex, client->rtm_table, api.safi);
|
rib_delete_ipv6 (api.type, api.instance, api.flags, &p, NULL, ifindex,
|
||||||
|
VRF_DEFAULT, client->rtm_table, api.safi);
|
||||||
else
|
else
|
||||||
rib_delete_ipv6 (api.type, api.instance, api.flags, &p, &nexthop, ifindex, client->rtm_table, api.safi);
|
rib_delete_ipv6 (api.type, api.instance, api.flags, &p, &nexthop, ifindex,
|
||||||
|
VRF_DEFAULT, client->rtm_table, api.safi);
|
||||||
|
|
||||||
client->v6_route_del_cnt++;
|
client->v6_route_del_cnt++;
|
||||||
return 0;
|
return 0;
|
||||||
@ -1616,9 +1624,9 @@ zread_router_id_add (struct zserv *client, u_short length)
|
|||||||
/* Router-id information is needed. */
|
/* Router-id information is needed. */
|
||||||
client->ridinfo = 1;
|
client->ridinfo = 1;
|
||||||
|
|
||||||
router_id_get (&p);
|
router_id_get (&p, VRF_DEFAULT);
|
||||||
|
|
||||||
return zsend_router_id_update (client,&p);
|
return zsend_router_id_update (client, &p, VRF_DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unregister zebra server router-id information. */
|
/* Unregister zebra server router-id information. */
|
||||||
|
@ -134,9 +134,10 @@ extern void zebra_if_init (void);
|
|||||||
extern void zebra_zserv_socket_init (char *path);
|
extern void zebra_zserv_socket_init (char *path);
|
||||||
extern void hostinfo_get (void);
|
extern void hostinfo_get (void);
|
||||||
extern void rib_init (void);
|
extern void rib_init (void);
|
||||||
extern void interface_list (void);
|
extern void interface_list (struct zebra_vrf *);
|
||||||
extern void kernel_init (void);
|
extern void route_read (struct zebra_vrf *);
|
||||||
extern void route_read (void);
|
extern void kernel_init (struct zebra_vrf *);
|
||||||
|
extern void kernel_terminate (struct zebra_vrf *);
|
||||||
extern void zebra_route_map_init (void);
|
extern void zebra_route_map_init (void);
|
||||||
extern void zebra_snmp_init (void);
|
extern void zebra_snmp_init (void);
|
||||||
extern void zebra_vty_init (void);
|
extern void zebra_vty_init (void);
|
||||||
@ -151,7 +152,9 @@ extern void nbr_connected_delete_ipv6 (struct interface *, struct in6_addr *, u_
|
|||||||
extern int zsend_interface_update (int, struct zserv *, struct interface *);
|
extern int zsend_interface_update (int, struct zserv *, struct interface *);
|
||||||
extern int zsend_redistribute_route (int, struct zserv *, struct prefix *,
|
extern int zsend_redistribute_route (int, struct zserv *, struct prefix *,
|
||||||
struct rib *);
|
struct rib *);
|
||||||
extern int zsend_router_id_update(struct zserv *, struct prefix *);
|
extern int zsend_router_id_update (struct zserv *, struct prefix *,
|
||||||
|
vrf_id_t);
|
||||||
|
|
||||||
extern pid_t pid;
|
extern pid_t pid;
|
||||||
|
|
||||||
extern void zserv_create_header(struct stream *s, uint16_t cmd);
|
extern void zserv_create_header(struct stream *s, uint16_t cmd);
|
||||||
@ -162,6 +165,7 @@ extern void zebra_route_map_write_delay_timer(struct vty *);
|
|||||||
extern route_map_result_t zebra_route_map_check (int family, int rib_type,
|
extern route_map_result_t zebra_route_map_check (int family, int rib_type,
|
||||||
struct prefix *p,
|
struct prefix *p,
|
||||||
struct nexthop *nexthop,
|
struct nexthop *nexthop,
|
||||||
|
vrf_id_t vrf_id,
|
||||||
u_short tag);
|
u_short tag);
|
||||||
extern route_map_result_t zebra_nht_route_map_check (int family,
|
extern route_map_result_t zebra_nht_route_map_check (int family,
|
||||||
int client_proto,
|
int client_proto,
|
||||||
|
Loading…
Reference in New Issue
Block a user