Merge branch 'cmaster-next' into vtysh-grammar

Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>

Conflicts:
	lib/.gitignore
	lib/command.c
	lib/command.h
This commit is contained in:
Quentin Young 2016-09-21 22:11:53 +00:00
commit 844ec28cee
266 changed files with 15534 additions and 7229 deletions

View File

@ -26,6 +26,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "hash.h"
#include "thread.h"
#include "queue.h"
#include "filter.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_table.h"

View File

@ -30,6 +30,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "stream.h"
#include "jhash.h"
#include "queue.h"
#include "filter.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_aspath.h"

View File

@ -31,6 +31,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "jhash.h"
#include "queue.h"
#include "table.h"
#include "filter.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_attr.h"
@ -1314,7 +1315,8 @@ bgp_attr_nexthop (struct bgp_attr_parser_args *args)
gets ignored in any of these cases. */
nexthop_n = stream_get_ipv4 (peer->ibuf);
nexthop_h = ntohl (nexthop_n);
if (IPV4_NET0 (nexthop_h) || IPV4_NET127 (nexthop_h) || IPV4_CLASS_DE (nexthop_h))
if ((IPV4_NET0 (nexthop_h) || IPV4_NET127 (nexthop_h) || IPV4_CLASS_DE (nexthop_h))
&& !BGP_DEBUG (allow_martians, ALLOW_MARTIANS)) /* loopbacks may be used in testing */
{
char buf[INET_ADDRSTRLEN];
inet_ntop (AF_INET, &nexthop_n, buf, INET_ADDRSTRLEN);
@ -1946,7 +1948,7 @@ bgp_attr_encap(
}
while (length >= 4) {
uint16_t subtype;
uint16_t subtype = 0;
uint16_t sublength = 0;
struct bgp_attr_encap_subtlv *tlv;

View File

@ -99,6 +99,9 @@ struct attr_extra
/* MP Nexthop length */
u_char mp_nexthop_len;
/* MP Nexthop preference */
u_char mp_nexthop_prefer_global;
/* route tag */
u_short tag;
@ -128,7 +131,7 @@ struct attr
struct in_addr nexthop;
u_int32_t med;
u_int32_t local_pref;
u_int32_t nh_ifindex;
ifindex_t nh_ifindex;
/* Path origin attribute */
u_char origin;
@ -145,6 +148,7 @@ struct attr
#define BATTR_RMAP_NEXTHOP_UNCHANGED (1 << 3)
#define BATTR_RMAP_IPV6_GLOBAL_NHOP_CHANGED (1 << 4)
#define BATTR_RMAP_IPV6_LL_NHOP_CHANGED (1 << 5)
#define BATTR_RMAP_IPV6_PREFER_GLOBAL_CHANGED (1 << 6)
/* Router Reflector related structure. */
struct cluster_list
@ -274,6 +278,7 @@ bgp_rmap_nhop_changed(u_int32_t out_rmap_flags, u_int32_t in_rmap_flags)
CHECK_FLAG(out_rmap_flags, BATTR_RMAP_NEXTHOP_UNCHANGED) ||
CHECK_FLAG(out_rmap_flags, BATTR_RMAP_IPV4_NHOP_CHANGED) ||
CHECK_FLAG(out_rmap_flags, BATTR_RMAP_IPV6_GLOBAL_NHOP_CHANGED) ||
CHECK_FLAG(out_rmap_flags, BATTR_RMAP_IPV6_PREFER_GLOBAL_CHANGED) ||
CHECK_FLAG(out_rmap_flags, BATTR_RMAP_IPV6_LL_NHOP_CHANGED) ||
CHECK_FLAG(in_rmap_flags, BATTR_RMAP_NEXTHOP_UNCHANGED)) ? 1 : 0);
}

View File

@ -34,6 +34,8 @@
#include "vty.h"
#include "bfd.h"
#include "lib/json.h"
#include "filter.h"
#include "bgpd/bgpd.h"
#include "bgp_fsm.h"
#include "bgpd/bgp_bfd.h"
@ -71,7 +73,7 @@ bgp_bfd_peer_group2peer_copy(struct peer *conf, struct peer *peer)
/*
* bgp_bfd_is_peer_multihop - returns whether BFD peer is multi-hop or single hop.
*/
static int
int
bgp_bfd_is_peer_multihop(struct peer *peer)
{
struct bfd_info *bfd_info;
@ -711,7 +713,4 @@ bgp_bfd_init(void)
install_element (BGP_NODE, &no_neighbor_bfd_cmd);
install_element (BGP_NODE, &no_neighbor_bfd_val_cmd);
install_element (BGP_NODE, &no_neighbor_bfd_type_cmd);
/* Send the client registration */
bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER);
}

View File

@ -42,4 +42,7 @@ bgp_bfd_peer_config_write(struct vty *vty, struct peer *peer, char *addr);
extern void
bgp_bfd_show_info(struct vty *vty, struct peer *peer, u_char use_json, json_object *json_neigh);
extern int
bgp_bfd_is_peer_multihop(struct peer *peer);
#endif /* _QUAGGA_BGP_BFD_H */

View File

@ -27,6 +27,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "command.h"
#include "memory.h"
#include "privs.h"
#include "filter.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_dump.h"
@ -143,7 +144,7 @@ main (int argc, char **argv)
size_t len;
int source_as;
int dest_as;
int ifindex;
ifindex_t ifindex;
int family;
struct in_addr sip;
struct in_addr dip;

View File

@ -24,6 +24,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "prefix.h"
#include "memory.h"
#include "queue.h"
#include "filter.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_community.h"

View File

@ -27,6 +27,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "log.h"
#include "thread.h"
#include "queue.h"
#include "filter.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_damp.h"

View File

@ -30,6 +30,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "sockunion.h"
#include "memory.h"
#include "queue.h"
#include "filter.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_aspath.h"
@ -48,6 +49,7 @@ unsigned long conf_bgp_debug_keepalive;
unsigned long conf_bgp_debug_update;
unsigned long conf_bgp_debug_bestpath;
unsigned long conf_bgp_debug_zebra;
unsigned long conf_bgp_debug_allow_martians;
unsigned long conf_bgp_debug_nht;
unsigned long conf_bgp_debug_update_groups;
@ -60,6 +62,7 @@ unsigned long term_bgp_debug_keepalive;
unsigned long term_bgp_debug_update;
unsigned long term_bgp_debug_bestpath;
unsigned long term_bgp_debug_zebra;
unsigned long term_bgp_debug_allow_martians;
unsigned long term_bgp_debug_nht;
unsigned long term_bgp_debug_update_groups;
@ -1518,6 +1521,48 @@ DEFUN (no_debug_bgp_zebra_prefix,
return CMD_SUCCESS;
}
DEFUN (debug_bgp_allow_martians,
debug_bgp_allow_martians_cmd,
"debug bgp allow-martians",
DEBUG_STR
BGP_STR
"BGP allow martian next hops\n")
{
if (vty->node == CONFIG_NODE)
DEBUG_ON (allow_martians, ALLOW_MARTIANS);
else
{
TERM_DEBUG_ON (allow_martians, ALLOW_MARTIANS);
vty_out (vty, "BGP allow_martian next hop debugging is on%s", VTY_NEWLINE);
}
return CMD_SUCCESS;
}
DEFUN (no_debug_bgp_allow_martians,
no_debug_bgp_allow_martians_cmd,
"no debug bgp allow-martians",
NO_STR
DEBUG_STR
BGP_STR
"BGP allow martian next hops\n")
{
if (vty->node == CONFIG_NODE)
DEBUG_OFF (allow_martians, ALLOW_MARTIANS);
else
{
TERM_DEBUG_OFF (allow_martians, ALLOW_MARTIANS);
vty_out (vty, "BGP allow martian next hop debugging is off%s", VTY_NEWLINE);
}
return CMD_SUCCESS;
}
ALIAS (no_debug_bgp_allow_martians,
undebug_bgp_allow_martians_cmd,
"undebug bgp allow-martians",
UNDEBUG_STR
BGP_STR
"BGP allow martian next hops\n")
/* debug bgp update-groups */
DEFUN (debug_bgp_update_groups,
debug_bgp_update_groups_cmd,
@ -1580,6 +1625,7 @@ DEFUN (no_debug_bgp,
TERM_DEBUG_OFF (as4, AS4_SEGMENT);
TERM_DEBUG_OFF (neighbor_events, NEIGHBOR_EVENTS);
TERM_DEBUG_OFF (zebra, ZEBRA);
TERM_DEBUG_OFF (allow_martians, ALLOW_MARTIANS);
vty_out (vty, "All possible debugging has been turned off%s", VTY_NEWLINE);
return CMD_SUCCESS;
@ -1634,6 +1680,8 @@ DEFUN (show_debugging_bgp,
bgp_debug_list_print (vty, " BGP zebra debugging is on",
bgp_debug_zebra_prefixes);
if (BGP_DEBUG (allow_martians, ALLOW_MARTIANS))
vty_out (vty, " BGP allow martian next hop debugging is on%s", VTY_NEWLINE);
vty_out (vty, "%s", VTY_NEWLINE);
return CMD_SUCCESS;
}
@ -1663,7 +1711,7 @@ bgp_config_write_debug (struct vty *vty)
if (CONF_BGP_DEBUG (keepalive, KEEPALIVE))
{
write += bgp_debug_list_conf_print (vty, "debug bgp keepalive",
write += bgp_debug_list_conf_print (vty, "debug bgp keepalives",
bgp_debug_keepalive_peers);
}
@ -1717,6 +1765,12 @@ bgp_config_write_debug (struct vty *vty)
}
}
if (CONF_BGP_DEBUG (allow_martians, ALLOW_MARTIANS))
{
vty_out (vty, "debug bgp allow-martians%s", VTY_NEWLINE);
write++;
}
return write;
}
@ -1749,6 +1803,8 @@ bgp_debug_init (void)
install_element (CONFIG_NODE, &debug_bgp_update_cmd);
install_element (ENABLE_NODE, &debug_bgp_zebra_cmd);
install_element (CONFIG_NODE, &debug_bgp_zebra_cmd);
install_element (ENABLE_NODE, &debug_bgp_allow_martians_cmd);
install_element (CONFIG_NODE, &debug_bgp_allow_martians_cmd);
install_element (ENABLE_NODE, &debug_bgp_update_groups_cmd);
install_element (CONFIG_NODE, &debug_bgp_update_groups_cmd);
install_element (ENABLE_NODE, &debug_bgp_bestpath_prefix_cmd);
@ -1805,6 +1861,9 @@ bgp_debug_init (void)
install_element (CONFIG_NODE, &no_debug_bgp_update_cmd);
install_element (ENABLE_NODE, &no_debug_bgp_zebra_cmd);
install_element (CONFIG_NODE, &no_debug_bgp_zebra_cmd);
install_element (ENABLE_NODE, &no_debug_bgp_allow_martians_cmd);
install_element (ENABLE_NODE, &undebug_bgp_allow_martians_cmd);
install_element (CONFIG_NODE, &no_debug_bgp_allow_martians_cmd);
install_element (ENABLE_NODE, &no_debug_bgp_update_groups_cmd);
install_element (CONFIG_NODE, &no_debug_bgp_update_groups_cmd);
install_element (ENABLE_NODE, &no_debug_bgp_cmd);

View File

@ -66,6 +66,7 @@ extern unsigned long conf_bgp_debug_keepalive;
extern unsigned long conf_bgp_debug_update;
extern unsigned long conf_bgp_debug_bestpath;
extern unsigned long conf_bgp_debug_zebra;
extern unsigned long conf_bgp_debug_allow_martians;
extern unsigned long conf_bgp_debug_nht;
extern unsigned long conf_bgp_debug_update_groups;
@ -76,6 +77,7 @@ extern unsigned long term_bgp_debug_keepalive;
extern unsigned long term_bgp_debug_update;
extern unsigned long term_bgp_debug_bestpath;
extern unsigned long term_bgp_debug_zebra;
extern unsigned long term_bgp_debug_allow_martians;
extern unsigned long term_bgp_debug_nht;
extern unsigned long term_bgp_debug_update_groups;
@ -104,6 +106,7 @@ struct bgp_debug_filter
#define BGP_DEBUG_UPDATE_OUT 0x02
#define BGP_DEBUG_UPDATE_PREFIX 0x04
#define BGP_DEBUG_ZEBRA 0x01
#define BGP_DEBUG_ALLOW_MARTIANS 0x01
#define BGP_DEBUG_NHT 0x01
#define BGP_DEBUG_UPDATE_GROUPS 0x01

View File

@ -29,9 +29,9 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "linklist.h"
#include "queue.h"
#include "memory.h"
#include "filter.h"
#include "bgpd/bgp_table.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_route.h"
#include "bgpd/bgp_attr.h"
@ -771,15 +771,41 @@ DEFUN (dump_bgp_all,
DEFUN (no_dump_bgp_all,
no_dump_bgp_all_cmd,
"no dump bgp (all|updates|routes-mrt) [PATH] [INTERVAL]",
"no dump bgp (all|all-et|updates|updates-et|routes-mrt) [PATH] [INTERVAL]",
NO_STR
"Stop dump packet\n"
"Stop BGP packet dump\n"
"Stop dump process all/all-et\n"
"Stop dump process updates/updates-et\n"
"Stop dump process all\n"
"Stop dump process all-et\n"
"Stop dump process updates\n"
"Stop dump process updates-et\n"
"Stop dump process route-mrt\n")
{
return bgp_dump_unset (vty, &bgp_dump_all);
int bgp_dump_type = 0;
const struct bgp_dump_type_map *map = NULL;
struct bgp_dump *bgp_dump_struct = NULL;
for (map = bgp_dump_type_map; map->str; map++)
if (strcmp(argv[0], map->str) == 0)
bgp_dump_type = map->type;
switch (bgp_dump_type)
{
case BGP_DUMP_ALL:
case BGP_DUMP_ALL_ET:
bgp_dump_struct = &bgp_dump_all;
break;
case BGP_DUMP_UPDATES:
case BGP_DUMP_UPDATES_ET:
bgp_dump_struct = &bgp_dump_updates;
break;
case BGP_DUMP_ROUTES:
default:
bgp_dump_struct = &bgp_dump_routes;
break;
}
return bgp_dump_unset (vty, bgp_dump_struct);
}
/* BGP node structure. */

View File

@ -25,6 +25,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "prefix.h"
#include "command.h"
#include "queue.h"
#include "filter.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_ecommunity.h"
@ -769,7 +770,9 @@ ecommunity_match (const struct ecommunity *ecom1,
/* Every community on com2 needs to be on com1 for this to match */
while (i < ecom1->size && j < ecom2->size)
{
if (memcmp (ecom1->val + i, ecom2->val + j, ECOMMUNITY_SIZE) == 0)
if (memcmp (ecom1->val + i * ECOMMUNITY_SIZE,
ecom2->val + j * ECOMMUNITY_SIZE,
ECOMMUNITY_SIZE) == 0)
j++;
i++;
}
@ -779,4 +782,3 @@ ecommunity_match (const struct ecommunity *ecom1,
else
return 0;
}

View File

@ -25,6 +25,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "memory.h"
#include "buffer.h"
#include "queue.h"
#include "filter.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_aspath.h"
@ -66,18 +67,12 @@ struct as_filter
char *reg_str;
};
enum as_list_type
{
ACCESS_TYPE_STRING,
ACCESS_TYPE_NUMBER
};
/* AS path filter list. */
struct as_list
{
char *name;
enum as_list_type type;
enum access_type type;
struct as_list *next;
struct as_list *prev;

View File

@ -32,6 +32,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "plist.h"
#include "workqueue.h"
#include "queue.h"
#include "filter.h"
#include "lib/json.h"
#include "bgpd/bgpd.h"
@ -1331,8 +1332,10 @@ bgp_start (struct peer *peer)
if (bgp_debug_neighbor_events(peer))
zlog_debug ("%s [FSM] Waiting for NHT", peer->host);
#if !defined (HAVE_BGP_STANDALONE)
BGP_EVENT_ADD(peer, TCP_connection_open_failed);
return 0;
#endif
}
status = bgp_connect (peer);

View File

@ -68,6 +68,7 @@ static const struct option longopts[] =
{ "no_kernel", no_argument, NULL, 'n'},
{ "user", required_argument, NULL, 'u'},
{ "group", required_argument, NULL, 'g'},
{ "skip_runas", no_argument, NULL, 'S'},
{ "version", no_argument, NULL, 'v'},
{ "dryrun", no_argument, NULL, 'C'},
{ "help", no_argument, NULL, 'h'},
@ -163,6 +164,7 @@ redistribution between different routing protocols.\n\n\
-n, --no_kernel Do not install route to kernel.\n\
-u, --user User to run as\n\
-g, --group Group to run as\n\
-S, --skip_runas Skip user and group run as\n\
-v, --version Print program version\n\
-C, --dryrun Check configuration for validity and exit\n\
-h, --help Display this help and exit\n\
@ -200,9 +202,12 @@ sigint (void)
zlog_notice ("Terminating on signal");
if (! retain_mode)
{
bgp_terminate ();
if (bgpd_privs.user) /* NULL if skip_runas flag set */
zprivs_terminate (&bgpd_privs);
}
bgp_exit (0);
exit (0);
@ -227,7 +232,6 @@ bgp_exit (int status)
{
struct bgp *bgp;
struct listnode *node, *nnode;
extern struct zclient *zclient;
/* it only makes sense for this to be called on a clean exit */
assert (status == 0);
@ -277,8 +281,8 @@ bgp_exit (int status)
bgp_vrf_terminate ();
cmd_terminate ();
vty_terminate ();
if (zclient)
zclient_free (zclient);
bgp_zebra_destroy();
if (bgp_nexthop_buf)
stream_free (bgp_nexthop_buf);
if (bgp_ifindices_buf)
@ -317,6 +321,7 @@ bgp_vrf_enable (vrf_id_t vrf_id, const char *name, void **info)
{
struct vrf *vrf;
struct bgp *bgp;
vrf_id_t old_vrf_id;
vrf = vrf_lookup (vrf_id);
if (!vrf) // unexpected
@ -328,8 +333,13 @@ bgp_vrf_enable (vrf_id_t vrf_id, const char *name, void **info)
bgp = bgp_lookup_by_name(name);
if (bgp)
{
old_vrf_id = bgp->vrf_id;
/* We have instance configured, link to VRF and make it "up". */
bgp_vrf_link (bgp, vrf);
/* Update any redistribute vrf bitmaps if the vrf_id changed */
if (old_vrf_id != bgp->vrf_id)
bgp_update_redist_vrf_bitmaps(bgp, old_vrf_id);
bgp_instance_up (bgp);
}
@ -341,6 +351,7 @@ bgp_vrf_disable (vrf_id_t vrf_id, const char *name, void **info)
{
struct vrf *vrf;
struct bgp *bgp;
vrf_id_t old_vrf_id;
if (vrf_id == VRF_DEFAULT)
return 0;
@ -355,8 +366,12 @@ bgp_vrf_disable (vrf_id_t vrf_id, const char *name, void **info)
bgp = bgp_lookup_by_name(name);
if (bgp)
{
old_vrf_id = bgp->vrf_id;
/* We have instance configured, unlink from VRF and make it "down". */
bgp_vrf_unlink (bgp, vrf);
/* Update any redistribute vrf bitmaps if the vrf_id changed */
if (old_vrf_id != bgp->vrf_id)
bgp_update_redist_vrf_bitmaps(bgp, old_vrf_id);
bgp_instance_down (bgp);
}
@ -398,6 +413,7 @@ main (int argc, char **argv)
char *progname;
struct thread thread;
int tmp_port;
int skip_runas = 0;
/* Set umask before anything for security */
umask (0027);
@ -405,18 +421,13 @@ main (int argc, char **argv)
/* Preserve name of myself. */
progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
zlog_default = openzlog (progname, ZLOG_BGP, 0,
LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
zprivs_init (&bgpd_privs);
zlog_set_file (NULL, LOG_DEFAULT_FILENAME, zlog_default->default_lvl);
/* BGP master init. */
bgp_master_init ();
/* Command line argument treatment. */
while (1)
{
opt = getopt_long (argc, argv, "df:i:z:hp:l:A:P:rnu:g:vC", longopts, 0);
opt = getopt_long (argc, argv, "df:i:z:hp:l:A:P:rnu:g:vCS", longopts, 0);
if (opt == EOF)
break;
@ -474,6 +485,9 @@ main (int argc, char **argv)
case 'g':
bgpd_privs.group = optarg;
break;
case 'S': /* skip run as = override bgpd_privs */
skip_runas = 1;
break;
case 'v':
print_version (progname);
exit (0);
@ -490,6 +504,16 @@ main (int argc, char **argv)
}
}
zlog_default = openzlog (progname, ZLOG_BGP, 0,
LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
if (skip_runas)
memset (&bgpd_privs, 0, sizeof (bgpd_privs));
zprivs_init (&bgpd_privs);
#if defined(HAVE_CUMULUS)
zlog_set_level (NULL, ZLOG_DEST_SYSLOG, zlog_default->default_lvl);
#endif
/* Initializations. */
srandom (time (NULL));

View File

@ -29,6 +29,7 @@
#include "sockunion.h"
#include "memory.h"
#include "queue.h"
#include "filter.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_table.h"
@ -467,6 +468,11 @@ bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info *new_best,
bgp_info_mpath_dequeue (old_best);
}
if (debug)
zlog_debug("%s: starting mpath update, newbest %s num candidates %d old-mpath-count %d",
pfx_buf, new_best ? new_best->peer->host : "NONE",
listcount (mp_list), old_mpath_count);
/*
* We perform an ordered walk through both lists in parallel.
* The reason for the ordered walk is that if there are paths
@ -480,6 +486,8 @@ bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info *new_best,
*/
while (mp_node || cur_mpath)
{
struct bgp_info *tmp_info;
/*
* We can bail out of this loop if all existing paths on the
* multipath list have been visited (for cleanup purposes) and
@ -490,6 +498,12 @@ bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info *new_best,
mp_next_node = mp_node ? listnextnode (mp_node) : NULL;
next_mpath = cur_mpath ? bgp_info_mpath_next (cur_mpath) : NULL;
tmp_info = mp_node ? listgetdata (mp_node) : NULL;
if (debug)
zlog_debug("%s: comparing candidate %s with existing mpath %s",
pfx_buf, tmp_info ? tmp_info->peer->host : "NONE",
cur_mpath ? cur_mpath->peer->host : "NONE");
/*
* If equal, the path was a multipath and is still a multipath.
@ -505,6 +519,12 @@ bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info *new_best,
bgp_info_mpath_enqueue (prev_mpath, cur_mpath);
prev_mpath = cur_mpath;
mpath_count++;
if (debug)
{
bgp_info_path_with_addpath_rx_str(cur_mpath, path_buf);
zlog_debug("%s: %s is still multipath, cur count %d",
pfx_buf, path_buf, mpath_count);
}
}
else
{
@ -512,10 +532,11 @@ bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info *new_best,
if (debug)
{
bgp_info_path_with_addpath_rx_str(cur_mpath, path_buf);
zlog_debug ("%s remove mpath nexthop %s %s", pfx_buf,
zlog_debug ("%s: remove mpath %s nexthop %s, cur count %d",
pfx_buf, path_buf,
inet_ntop (AF_INET, &cur_mpath->attr->nexthop,
nh_buf[0], sizeof (nh_buf[0])),
path_buf);
mpath_count);
}
}
mp_node = mp_next_node;
@ -538,10 +559,11 @@ bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info *new_best,
if (debug)
{
bgp_info_path_with_addpath_rx_str(cur_mpath, path_buf);
zlog_debug ("%s remove mpath nexthop %s %s", pfx_buf,
zlog_debug ("%s: remove mpath %s nexthop %s, cur count %d",
pfx_buf, path_buf,
inet_ntop (AF_INET, &cur_mpath->attr->nexthop,
nh_buf[0], sizeof (nh_buf[0])),
path_buf);
mpath_count);
}
cur_mpath = next_mpath;
}
@ -574,10 +596,11 @@ bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info *new_best,
if (debug)
{
bgp_info_path_with_addpath_rx_str(new_mpath, path_buf);
zlog_debug ("%s add mpath nexthop %s %s", pfx_buf,
zlog_debug ("%s: add mpath %s nexthop %s, cur count %d",
pfx_buf, path_buf,
inet_ntop (AF_INET, &new_mpath->attr->nexthop,
nh_buf[0], sizeof (nh_buf[0])),
path_buf);
mpath_count);
}
}
mp_node = mp_next_node;
@ -586,6 +609,10 @@ bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info *new_best,
if (new_best)
{
if (debug)
zlog_debug("%s: New mpath count (incl newbest) %d mpath-change %s",
pfx_buf, mpath_count, mpath_changed ? "YES" : "NO");
bgp_info_mpath_count_set (new_best, mpath_count-1);
if (mpath_changed || (bgp_info_mpath_count (new_best) != old_mpath_count))
SET_FLAG (new_best->flags, BGP_INFO_MULTIPATH_CHG);

View File

@ -26,6 +26,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "memory.h"
#include "stream.h"
#include "queue.h"
#include "filter.h"
#include "lib/json.h"
#include "bgpd/bgpd.h"
@ -481,7 +482,7 @@ show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd, u
{
u_int16_t type;
struct rd_as rd_as;
struct rd_ip rd_ip = { 0, { 0 }, 0};
struct rd_ip rd_ip = {0};
u_char *pnt;
pnt = rn->p.u.val;
@ -671,7 +672,7 @@ bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd *prd, enum bgp_show_type ty
{
u_int16_t type;
struct rd_as rd_as;
struct rd_ip rd_ip = { 0, { 0 }, 0};
struct rd_ip rd_ip = {0};
u_char *pnt;
pnt = rn->p.u.val;

View File

@ -33,6 +33,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "network.h"
#include "queue.h"
#include "hash.h"
#include "filter.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_open.h"
@ -62,7 +63,9 @@ bgp_md5_set_socket (int socket, union sockunion *su, const char *password)
{
int ret = -1;
int en = ENOSYS;
#if HAVE_DECL_TCP_MD5SIG
union sockunion su2;
#endif /* HAVE_TCP_MD5SIG */
assert (socket >= 0);
@ -228,6 +231,17 @@ bgp_set_socket_ttl (struct peer *peer, int bgp_sock)
static int
bgp_get_instance_for_inc_conn (int sock, struct bgp **bgp_inst)
{
#ifndef SO_BINDTODEVICE
/* only Linux has SO_BINDTODEVICE, but we're in Linux-specific code here
* anyway since the assumption is that the interface name returned by
* getsockopt() is useful in identifying the VRF, particularly with Linux's
* VRF l3master device. The whole mechanism is specific to Linux, so...
* when other platforms add VRF support, this will need handling here as
* well. (or, some restructuring) */
*bgp_inst = bgp_get_default ();
return !*bgp_inst;
#else
char name[VRF_NAMSIZ + 1];
socklen_t name_len = VRF_NAMSIZ;
struct bgp *bgp;
@ -239,13 +253,18 @@ bgp_get_instance_for_inc_conn (int sock, struct bgp **bgp_inst)
rc = getsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, name, &name_len);
if (rc != 0)
{
#if !defined (HAVE_BGP_STANDALONE)
zlog_err ("[Error] BGP SO_BINDTODEVICE get failed (%s), sock %d",
safe_strerror (errno), sock);
return -1;
#endif
}
if (!strlen(name))
{
*bgp_inst = bgp_get_default ();
return 0; /* default instance. */
}
/* First try match to instance; if that fails, check for interfaces. */
bgp = bgp_lookup_by_name (name);
@ -275,6 +294,7 @@ bgp_get_instance_for_inc_conn (int sock, struct bgp **bgp_inst)
/* We didn't match to either an instance or an interface. */
return -1;
#endif
}
/* Accept bgp connection. */
@ -566,7 +586,7 @@ bgp_update_source (struct peer *peer)
int
bgp_connect (struct peer *peer)
{
unsigned int ifindex = 0;
ifindex_t ifindex = 0;
if (peer->conf_if && BGP_PEER_SU_UNSPEC(peer))
{
@ -656,7 +676,9 @@ bgp_getsockname (struct peer *peer)
{
zlog_err ("%s: nexthop_set failed, resetting connection - intf %p",
peer->host, peer->nexthop.ifp);
#if !defined (HAVE_BGP_STANDALONE)
return -1;
#endif
}
return 0;

View File

@ -32,6 +32,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "jhash.h"
#include "nexthop.h"
#include "queue.h"
#include "filter.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_table.h"
@ -236,6 +237,7 @@ bgp_connected_add (struct bgp *bgp, struct connected *ifc)
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
{
if (peer->conf_if && (strcmp (peer->conf_if, ifc->ifp->name) == 0) &&
peer->status != Established &&
!CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY))
{
if (peer_active(peer))
@ -562,12 +564,13 @@ bgp_scan_init (struct bgp *bgp)
bgp->connected_table[AFI_IP] = bgp_table_init (AFI_IP, SAFI_UNICAST);
bgp->import_check_table[AFI_IP] = bgp_table_init (AFI_IP, SAFI_UNICAST);
#ifdef HAVE_IPV6
bgp->nexthop_cache_table[AFI_IP6] = bgp_table_init (AFI_IP6, SAFI_UNICAST);
bgp->connected_table[AFI_IP6] = bgp_table_init (AFI_IP6, SAFI_UNICAST);
bgp->import_check_table[AFI_IP6] = bgp_table_init (AFI_IP6, SAFI_UNICAST);
#endif /* HAVE_IPV6 */
bgp->nexthop_cache_table[AFI_ETHER] = bgp_table_init (AFI_ETHER, SAFI_UNICAST);
bgp->connected_table[AFI_ETHER] = bgp_table_init (AFI_ETHER, SAFI_UNICAST);
bgp->import_check_table[AFI_ETHER] = bgp_table_init (AFI_ETHER, SAFI_UNICAST);
}
void

View File

@ -31,6 +31,7 @@
#include "memory.h"
#include "nexthop.h"
#include "vrf.h"
#include "filter.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_table.h"
@ -370,8 +371,8 @@ bgp_parse_nexthop_update (int command, vrf_id_t vrf_id)
{
char buf[PREFIX2STR_BUFFER];
prefix2str(&p, buf, sizeof (buf));
zlog_debug("parse nexthop update(%s): metric=%d, #nexthop=%d", buf,
metric, nexthop_num);
zlog_debug("%d: NH update for %s - metric %d (cur %d) #nhops %d (cur %d)",
vrf_id, buf, metric, bnc->metric, nexthop_num, bnc->nexthop_num);
}
if (metric != bnc->metric)
@ -396,30 +397,35 @@ bgp_parse_nexthop_update (int command, vrf_id_t vrf_id)
nexthop->type = stream_getc (s);
switch (nexthop->type)
{
case ZEBRA_NEXTHOP_IPV4:
case NEXTHOP_TYPE_IPV4:
nexthop->gate.ipv4.s_addr = stream_get_ipv4 (s);
break;
case ZEBRA_NEXTHOP_IFINDEX:
case NEXTHOP_TYPE_IFINDEX:
nexthop->ifindex = stream_getl (s);
break;
case ZEBRA_NEXTHOP_IPV4_IFINDEX:
case NEXTHOP_TYPE_IPV4_IFINDEX:
nexthop->gate.ipv4.s_addr = stream_get_ipv4 (s);
nexthop->ifindex = stream_getl (s);
break;
#ifdef HAVE_IPV6
case ZEBRA_NEXTHOP_IPV6:
case NEXTHOP_TYPE_IPV6:
stream_get (&nexthop->gate.ipv6, s, 16);
break;
case ZEBRA_NEXTHOP_IPV6_IFINDEX:
case NEXTHOP_TYPE_IPV6_IFINDEX:
stream_get (&nexthop->gate.ipv6, s, 16);
nexthop->ifindex = stream_getl (s);
break;
#endif
default:
/* do nothing */
break;
}
if (BGP_DEBUG(nht, NHT))
{
char buf[NEXTHOP_STRLEN];
zlog_debug(" nhop via %s",
nexthop2str (nexthop, buf, sizeof (buf)));
}
if (nhlist_tail)
{
nhlist_tail->next = nexthop;
@ -642,6 +648,14 @@ evaluate_paths (struct bgp_nexthop_cache *bnc)
int afi;
struct peer *peer = (struct peer *)bnc->nht_info;
if (BGP_DEBUG(nht, NHT))
{
char buf[PREFIX2STR_BUFFER];
bnc_str(bnc, buf, PREFIX2STR_BUFFER);
zlog_debug("NH update for %s - flags 0x%x chgflags 0x%x - evaluate paths",
buf, bnc->flags, bnc->change_flags);
}
LIST_FOREACH(path, &(bnc->paths), nh_thread)
{
if (!(path->type == ZEBRA_ROUTE_BGP &&
@ -681,8 +695,6 @@ evaluate_paths (struct bgp_nexthop_cache *bnc)
if (CHECK_FLAG(bnc->change_flags, BGP_NEXTHOP_METRIC_CHANGED) ||
CHECK_FLAG(bnc->change_flags, BGP_NEXTHOP_CHANGED))
SET_FLAG(path->flags, BGP_INFO_IGP_CHANGED);
else
UNSET_FLAG (path->flags, BGP_INFO_IGP_CHANGED);
bgp_process(bgp, rn, afi, SAFI_UNICAST);
}

View File

@ -28,6 +28,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "command.h"
#include "memory.h"
#include "queue.h"
#include "filter.h"
#include "lib/json.h"
#include "bgpd/bgpd.h"
@ -195,6 +196,9 @@ bgp_afi_safi_valid_indices (afi_t afi, safi_t *safi)
return 1;
}
break;
case AFI_ETHER:
default:
break;
}
zlog_debug ("unknown afi/safi (%u/%u)", afi, *safi);
@ -1473,7 +1477,7 @@ bgp_open_capability (struct stream *s, struct peer *peer)
stream_putc(s, len);
stream_put(s, names.nodename, len);
#ifdef _GNU_SOURCE
#ifdef HAVE_STRUCT_UTSNAME_DOMAINNAME
if ((names.domainname[0] != '\0') &&
(strcmp(names.domainname, "(none)") != 0))
{
@ -1497,8 +1501,13 @@ bgp_open_capability (struct stream *s, struct peer *peer)
stream_putc_at(s, capp, len);
if (bgp_debug_neighbor_events(peer))
#ifdef HAVE_STRUCT_UTSNAME_DOMAINNAME
zlog_debug("%s Sending hostname cap with hn = %s, dn = %s",
peer->host, names.nodename, names.domainname);
#else
zlog_debug("%s Sending hostname cap with hn = %s", peer->host,
names.nodename);
#endif
}
/* Sending base graceful-restart capability irrespective of the config */

View File

@ -32,6 +32,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "linklist.h"
#include "plist.h"
#include "queue.h"
#include "filter.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_table.h"
@ -1162,10 +1163,12 @@ bgp_open_receive (struct peer *peer, bgp_size_t size)
{
if (!peer->nexthop.v4.s_addr)
{
#if !defined (HAVE_BGP_STANDALONE)
zlog_err ("%s: No local IPv4 addr resetting connection, fd %d",
peer->host, peer->fd);
bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_SUBCODE_UNSPECIFIC);
return -1;
#endif
}
}
if (peer->afc_nego[AFI_IP6][SAFI_UNICAST] ||
@ -1175,10 +1178,12 @@ bgp_open_receive (struct peer *peer, bgp_size_t size)
{
if (IN6_IS_ADDR_UNSPECIFIED (&peer->nexthop.v6_global))
{
#if !defined (HAVE_BGP_STANDALONE)
zlog_err ("%s: No local IPv6 addr resetting connection, fd %d",
peer->host, peer->fd);
bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_SUBCODE_UNSPECIFIC);
return -1;
#endif
}
}
peer->rtt = sockopt_tcp_rtt (peer->fd);

View File

@ -24,6 +24,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "command.h"
#include "memory.h"
#include "queue.h"
#include "filter.h"
#include "bgpd.h"
#include "bgp_aspath.h"

View File

@ -376,7 +376,11 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist,
}
if (debug)
{
bgp_info_path_with_addpath_rx_str (exist, exist_buf);
zlog_debug("%s: Comparing %s flags 0x%x with %s flags 0x%x",
pfx_buf, new_buf, new->flags, exist_buf, exist->flags);
}
newattr = new->attr;
existattr = exist->attr;
@ -705,6 +709,15 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist,
* TODO: If unequal cost ibgp multipath is enabled we can
* mark the paths as equal here instead of returning
*/
if (debug)
{
if (ret == 1)
zlog_debug("%s: %s wins over %s after IGP metric comparison",
pfx_buf, new_buf, exist_buf);
else
zlog_debug("%s: %s loses to %s after IGP metric comparison",
pfx_buf, new_buf, exist_buf);
}
return ret;
}
@ -1638,14 +1651,19 @@ bgp_best_selection (struct bgp *bgp, struct bgp_node *rn,
/* Now that we know which path is the bestpath see if any of the other paths
* qualify as multipaths
*/
if (do_mpath && new_select)
{
if (debug)
{
if (new_select)
bgp_info_path_with_addpath_rx_str (new_select, path_buf);
zlog_debug("%s: %s is the bestpath, now find multipaths", pfx_buf, path_buf);
else
sprintf (path_buf, "NONE");
zlog_debug("%s: After path selection, newbest is %s oldbest was %s",
pfx_buf, path_buf,
old_select ? old_select->peer->host : "NONE");
}
if (do_mpath && new_select)
{
for (ri = rn->info; (ri != NULL) && (nextri = ri->next, 1); ri = nextri)
{
@ -1749,6 +1767,57 @@ subgroup_process_announce_selected (struct update_subgroup *subgrp,
return 0;
}
/*
* Clear IGP changed flag and attribute changed flag for a route (all paths).
* This is called at the end of route processing.
*/
static void
bgp_zebra_clear_route_change_flags (struct bgp_node *rn)
{
struct bgp_info *ri;
for (ri = rn->info; ri; ri = ri->next)
{
if (BGP_INFO_HOLDDOWN (ri))
continue;
UNSET_FLAG (ri->flags, BGP_INFO_IGP_CHANGED);
UNSET_FLAG (ri->flags, BGP_INFO_ATTR_CHANGED);
}
}
/*
* Has the route changed from the RIB's perspective? This is invoked only
* if the route selection returns the same best route as earlier - to
* determine if we need to update zebra or not.
*/
static int
bgp_zebra_has_route_changed (struct bgp_node *rn, struct bgp_info *selected)
{
struct bgp_info *mpinfo;
/* If this is multipath, check all selected paths for any nexthop change or
* attribute change. Some attribute changes (e.g., community) aren't of
* relevance to the RIB, but we'll update zebra to ensure we handle the
* case of BGP nexthop change. This is the behavior when the best path has
* an attribute change anyway.
*/
if (CHECK_FLAG (selected->flags, BGP_INFO_IGP_CHANGED) ||
CHECK_FLAG (selected->flags, BGP_INFO_MULTIPATH_CHG))
return 1;
/* If this is multipath, check all selected paths for any nexthop change */
for (mpinfo = bgp_info_mpath_first (selected); mpinfo;
mpinfo = bgp_info_mpath_next (mpinfo))
{
if (CHECK_FLAG (mpinfo->flags, BGP_INFO_IGP_CHANGED)
|| CHECK_FLAG (mpinfo->flags, BGP_INFO_ATTR_CHANGED))
return 1;
}
/* Nothing has changed from the RIB's perspective. */
return 0;
}
struct bgp_process_queue
{
struct bgp *bgp;
@ -1799,11 +1868,11 @@ bgp_process_main (struct work_queue *wq, void *data)
!CHECK_FLAG(old_select->flags, BGP_INFO_ATTR_CHANGED) &&
!bgp->addpath_tx_used[afi][safi])
{
if (CHECK_FLAG (old_select->flags, BGP_INFO_IGP_CHANGED) ||
CHECK_FLAG (old_select->flags, BGP_INFO_MULTIPATH_CHG))
if (bgp_zebra_has_route_changed (rn, old_select))
bgp_zebra_announce (p, old_select, bgp, afi, safi);
UNSET_FLAG (old_select->flags, BGP_INFO_MULTIPATH_CHG);
bgp_zebra_clear_route_change_flags (rn);
UNSET_FLAG (rn->flags, BGP_NODE_PROCESS_SCHEDULED);
return WQ_SUCCESS;
}
@ -1857,6 +1926,9 @@ bgp_process_main (struct work_queue *wq, void *data)
}
}
/* Clear any route change flags. */
bgp_zebra_clear_route_change_flags (rn);
/* Reap old select bgp_info, if it has been removed */
if (old_select && CHECK_FLAG (old_select->flags, BGP_INFO_REMOVED))
bgp_info_reap (rn, old_select);
@ -5873,7 +5945,7 @@ route_vty_out (struct vty *vty, struct prefix *p,
vty_out (vty, "%-16s", inet_ntoa (attr->nexthop));
}
}
#ifdef HAVE_IPV6
/* IPv6 Next Hop */
else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr))
{
@ -5901,8 +5973,9 @@ route_vty_out (struct vty *vty, struct prefix *p,
json_object_string_add(json_nexthop_ll, "afi", "ipv6");
json_object_string_add(json_nexthop_ll, "scope", "link-local");
if (IPV6_ADDR_CMP (&attr->extra->mp_nexthop_global,
&attr->extra->mp_nexthop_local) != 0)
if ((IPV6_ADDR_CMP (&attr->extra->mp_nexthop_global,
&attr->extra->mp_nexthop_local) != 0) &&
!attr->extra->mp_nexthop_prefer_global)
json_object_boolean_true_add(json_nexthop_ll, "used");
else
json_object_boolean_true_add(json_nexthop_global, "used");
@ -5912,7 +5985,10 @@ route_vty_out (struct vty *vty, struct prefix *p,
}
else
{
if ((attr->extra->mp_nexthop_len == 32) || (binfo->peer->conf_if))
/* Display LL if LL/Global both in table unless prefer-global is set */
if (((attr->extra->mp_nexthop_len == 32) &&
!attr->extra->mp_nexthop_prefer_global) ||
(binfo->peer->conf_if))
{
if (binfo->peer->conf_if)
{
@ -5954,7 +6030,6 @@ route_vty_out (struct vty *vty, struct prefix *p,
}
}
}
#endif /* HAVE_IPV6 */
/* MED/Metric */
if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
@ -6635,7 +6710,6 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
if (json_paths)
json_object_string_add(json_nexthop_global, "afi", "ipv4");
}
#ifdef HAVE_IPV6
else
{
assert (attr->extra);
@ -6654,8 +6728,6 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
buf, INET6_ADDRSTRLEN));
}
}
#endif /* HAVE_IPV6 */
/* Display the IGP cost or 'inaccessible' */
if (! CHECK_FLAG (binfo->flags, BGP_INFO_VALID))
@ -6761,7 +6833,6 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
if (!json_paths)
vty_out (vty, "%s", VTY_NEWLINE);
#ifdef HAVE_IPV6
/* display the link-local nexthop */
if (attr->extra && attr->extra->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
{
@ -6775,13 +6846,19 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
json_object_string_add(json_nexthop_ll, "scope", "link-local");
json_object_boolean_true_add(json_nexthop_ll, "accessible");
if (!attr->extra->mp_nexthop_prefer_global)
json_object_boolean_true_add(json_nexthop_ll, "used");
else
json_object_boolean_true_add(json_nexthop_global, "used");
}
else
{
vty_out (vty, " (%s) (used)%s",
vty_out (vty, " (%s) %s%s",
inet_ntop (AF_INET6, &attr->extra->mp_nexthop_local,
buf, INET6_ADDRSTRLEN),
attr->extra->mp_nexthop_prefer_global ?
"(prefer-global)" : "(used)",
VTY_NEWLINE);
}
}
@ -6791,7 +6868,6 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
if (json_paths)
json_object_boolean_true_add(json_nexthop_global, "used");
}
#endif /* HAVE_IPV6 */
/* Line 3 display Origin, Med, Locpref, Weight, Tag, valid, Int/Ext/Local, Atomic, best */
if (json_paths)
@ -7634,7 +7710,9 @@ route_vty_out_detail_header (struct vty *vty, struct bgp *bgp,
{
vty_out (vty, ", best #%d", best);
if (safi == SAFI_UNICAST)
vty_out (vty, ", table Default-IP-Routing-Table");
vty_out (vty, ", table %s",
(bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
? "Default-IP-Routing-Table" : bgp->name);
}
else
vty_out (vty, ", no best path");
@ -9304,6 +9382,66 @@ DEFUN (show_ip_bgp_dampening_info,
return bgp_show_dampening_parameters (vty, AFI_IP, SAFI_UNICAST);
}
DEFUN (show_ip_bgp_ipv4_dampening_parameters,
show_ip_bgp_ipv4_dampening_parameters_cmd,
"show ip bgp ipv4 (unicast|multicast) dampening parameters",
SHOW_STR
IP_STR
BGP_STR
"Address family\n"
"Address Family modifier\n"
"Address Family modifier\n"
"Display detailed information about dampening\n"
"Display detail of configured dampening parameters\n")
{
if (strncmp(argv[0], "m", 1) == 0)
return bgp_show_dampening_parameters (vty, AFI_IP, SAFI_MULTICAST);
return bgp_show_dampening_parameters (vty, AFI_IP, SAFI_UNICAST);
}
DEFUN (show_ip_bgp_ipv4_dampening_flap_stats,
show_ip_bgp_ipv4_dampening_flap_stats_cmd,
"show ip bgp ipv4 (unicast|multicast) dampening flap-statistics",
SHOW_STR
IP_STR
BGP_STR
"Address family\n"
"Address Family modifier\n"
"Address Family modifier\n"
"Display detailed information about dampening\n"
"Display flap statistics of routes\n")
{
if (strncmp(argv[0], "m", 1) == 0)
return bgp_show (vty, NULL, AFI_IP, SAFI_MULTICAST,
bgp_show_type_flap_statistics, NULL, 0);
return bgp_show (vty, NULL, AFI_IP, SAFI_MULTICAST,
bgp_show_type_flap_statistics, NULL, 0);
}
DEFUN (show_ip_bgp_ipv4_dampening_dampd_paths,
show_ip_bgp_ipv4_dampening_dampd_paths_cmd,
"show ip bgp ipv4 (unicast|multicast) dampening dampened-paths",
SHOW_STR
IP_STR
BGP_STR
"Address family\n"
"Address Family modifier\n"
"Address Family modifier\n"
"Display detailed information about dampening\n"
"Display paths suppressed due to dampening\n")
{
if (strncmp(argv[0], "m", 1) == 0)
return bgp_show (vty, NULL, AFI_IP, SAFI_MULTICAST,
bgp_show_type_dampend_paths, NULL, 0);
return bgp_show (vty, NULL, AFI_IP, SAFI_MULTICAST,
bgp_show_type_dampend_paths, NULL, 0);
}
static int
bgp_show_route_map (struct vty *vty, const char *name,
const char *rmap_str, afi_t afi,
@ -14438,7 +14576,10 @@ bgp_route_init (void)
install_element (VIEW_NODE, &show_ip_bgp_neighbor_received_prefix_filter_cmd);
install_element (VIEW_NODE, &show_ip_bgp_ipv4_neighbor_received_prefix_filter_cmd);
install_element (VIEW_NODE, &show_ip_bgp_dampening_params_cmd);
install_element (VIEW_NODE, &show_ip_bgp_ipv4_dampening_parameters_cmd);
install_element (VIEW_NODE, &show_ip_bgp_dampened_paths_cmd);
install_element (VIEW_NODE, &show_ip_bgp_ipv4_dampening_dampd_paths_cmd);
install_element (VIEW_NODE, &show_ip_bgp_ipv4_dampening_flap_stats_cmd);
install_element (VIEW_NODE, &show_ip_bgp_damp_dampened_paths_cmd);
install_element (VIEW_NODE, &show_ip_bgp_flap_statistics_cmd);
install_element (VIEW_NODE, &show_ip_bgp_damp_flap_statistics_cmd);
@ -14591,6 +14732,9 @@ bgp_route_init (void)
install_element (ENABLE_NODE, &show_ip_bgp_ipv4_neighbor_received_prefix_filter_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_dampening_params_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_dampened_paths_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_ipv4_dampening_parameters_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_ipv4_dampening_dampd_paths_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_ipv4_dampening_flap_stats_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_damp_dampened_paths_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_flap_statistics_cmd);
install_element (ENABLE_NODE, &show_ip_bgp_damp_flap_statistics_cmd);
@ -15000,6 +15144,13 @@ bgp_route_init (void)
install_element (BGP_IPV4_NODE, &bgp_damp_unset_cmd);
install_element (BGP_IPV4_NODE, &bgp_damp_unset2_cmd);
install_element (BGP_IPV4_NODE, &bgp_damp_unset3_cmd);
/* IPv4 Multicast Mode */
install_element (BGP_IPV4M_NODE, &bgp_damp_set_cmd);
install_element (BGP_IPV4M_NODE, &bgp_damp_set2_cmd);
install_element (BGP_IPV4M_NODE, &bgp_damp_set3_cmd);
install_element (BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
install_element (BGP_IPV4M_NODE, &bgp_damp_unset2_cmd);
}
void

View File

@ -103,6 +103,7 @@ o Cisco route-map
o Local extensions
set ipv6 next-hop global: Done
set ipv6 next-hop prefer-global: Done
set ipv6 next-hop local : Done
set as-path exclude : Done
@ -2192,6 +2193,67 @@ struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd =
route_set_ipv6_nexthop_global_free
};
/* Set next-hop preference value. */
static route_map_result_t
route_set_ipv6_nexthop_prefer_global (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
struct bgp_info *bgp_info;
struct peer *peer;
if (type == RMAP_BGP)
{
/* Fetch routemap's rule information. */
bgp_info = object;
peer = bgp_info->peer;
if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
&& peer->su_remote
&& sockunion_family (peer->su_remote) == AF_INET6)
{
/* Set next hop preference to global */
bgp_info->attr->extra->mp_nexthop_prefer_global = TRUE;
SET_FLAG(bgp_info->attr->rmap_change_flags,
BATTR_RMAP_IPV6_PREFER_GLOBAL_CHANGED);
}
else
{
bgp_info->attr->extra->mp_nexthop_prefer_global = FALSE;
SET_FLAG(bgp_info->attr->rmap_change_flags,
BATTR_RMAP_IPV6_PREFER_GLOBAL_CHANGED);
}
}
return RMAP_OKAY;
}
static void *
route_set_ipv6_nexthop_prefer_global_compile (const char *arg)
{
int *rins = NULL;
rins = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (int));
*rins = 1;
return rins;
}
/* Free route map's compiled `ip next-hop' value. */
static void
route_set_ipv6_nexthop_prefer_global_free (void *rule)
{
XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
}
/* Route map commands for ip nexthop set preferred. */
struct route_map_rule_cmd route_set_ipv6_nexthop_prefer_global_cmd =
{
"ipv6 next-hop prefer-global",
route_set_ipv6_nexthop_prefer_global,
route_set_ipv6_nexthop_prefer_global_compile,
route_set_ipv6_nexthop_prefer_global_free
};
/* `set ipv6 nexthop local IP_ADDRESS' */
/* Set nexthop to object. ojbect must be pointer to struct attr. */
@ -2935,8 +2997,8 @@ DEFUN (match_peer,
"match peer (A.B.C.D|X:X::X:X)",
MATCH_STR
"Match peer address\n"
"IPv6 address of peer\n"
"IP address of peer\n")
"IP address of peer\n"
"IPv6 address of peer\n")
{
return bgp_route_match_add (vty, vty->index, "peer", argv[0],
RMAP_EVENT_MATCH_ADDED);
@ -2974,8 +3036,8 @@ ALIAS (no_match_peer,
NO_STR
MATCH_STR
"Match peer address\n"
"IPv6 address of peer\n"
"IP address of peer\n")
"IP address of peer\n"
"IPv6 address of peer\n")
ALIAS (no_match_peer,
no_match_peer_local_cmd,
@ -4366,11 +4428,34 @@ DEFUN (no_set_ipv6_nexthop_peer,
SET_STR
IPV6_STR
"IPv6 next-hop address\n"
)
"Use peer address (for BGP only)\n")
{
return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop peer-address", NULL);
}
DEFUN (set_ipv6_nexthop_prefer_global,
set_ipv6_nexthop_prefer_global_cmd,
"set ipv6 next-hop prefer-global",
SET_STR
IPV6_STR
"IPv6 next-hop address\n"
"Prefer global over link-local if both exist\n")
{
return bgp_route_set_add (vty, vty->index, "ipv6 next-hop prefer-global", NULL);;
}
DEFUN (no_set_ipv6_nexthop_prefer_global,
no_set_ipv6_nexthop_prefer_global_cmd,
"no set ipv6 next-hop prefer-global",
NO_STR
SET_STR
IPV6_STR
"IPv6 next-hop address\n"
"Prefer global over link-local if both exist\n")
{
return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop prefer-global", NULL);
}
DEFUN (set_ipv6_nexthop_global,
set_ipv6_nexthop_global_cmd,
"set ipv6 next-hop global X:X::X:X",
@ -4704,6 +4789,7 @@ bgp_route_map_init (void)
route_map_install_match (&route_match_ipv6_next_hop_cmd);
route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
route_map_install_set (&route_set_ipv6_nexthop_prefer_global_cmd);
route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
route_map_install_set (&route_set_ipv6_nexthop_peer_cmd);
@ -4716,6 +4802,8 @@ bgp_route_map_init (void)
install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
install_element (RMAP_NODE, &set_ipv6_nexthop_prefer_global_cmd);
install_element (RMAP_NODE, &no_set_ipv6_nexthop_prefer_global_cmd);
install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);

View File

@ -30,6 +30,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "command.h"
#include "thread.h"
#include "smux.h"
#include "filter.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_table.h"
@ -116,8 +117,8 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
SNMP_LOCAL_VARIABLES
/* BGP-MIB instances. */
oid bgp_oid [] = { BGP4MIB };
oid bgp_trap_oid [] = { BGP4MIB, 0 };
static oid bgp_oid [] = { BGP4MIB };
static oid bgp_trap_oid [] = { BGP4MIB, 0 };
/* IP address 0.0.0.0. */
static struct in_addr bgp_empty_addr = { .s_addr = 0 };
@ -137,7 +138,7 @@ static u_char *bgp4PathAttrTable (struct variable *, oid [], size_t *,
int, size_t *, WriteMethod **);
/* static u_char *bgpTraps (); */
struct variable bgp_variables[] =
static struct variable bgp_variables[] =
{
/* BGP version. */
{BGPVERSION, OCTET_STRING, RONLY, bgpVersion,
@ -831,7 +832,7 @@ bgp4PathAttrTable (struct variable *v, oid name[], size_t *length,
}
/* BGP Traps. */
struct trap_object bgpTrapList[] =
static struct trap_object bgpTrapList[] =
{
{3, {3, 1, BGPPEERLASTERROR}},
{3, {3, 1, BGPPEERSTATE}}

View File

@ -25,6 +25,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "sockunion.h"
#include "vty.h"
#include "queue.h"
#include "filter.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_table.h"

View File

@ -35,7 +35,7 @@ struct bgp_table
struct peer *owner;
struct route_table *route_table;
u_int64_t version;
uint64_t version;
};
struct bgp_node
@ -56,7 +56,7 @@ struct bgp_node
struct bgp_node *prn;
u_int64_t version;
uint64_t version;
u_char flags;
#define BGP_NODE_PROCESS_SCHEDULED (1 << 0)
#define BGP_NODE_USER_CLEAR (1 << 1)
@ -112,44 +112,6 @@ bgp_node_table (struct bgp_node *node)
return bgp_node_to_rnode (node)->table->info;
}
/*
* bgp_node_info
*
* Returns the 'info' pointer corresponding to a bgp node.
*/
static inline void *
bgp_node_info (const struct bgp_node *node)
{
return node->info;
}
/*
* bgp_node_set_info
*/
static inline void
bgp_node_set_info (struct bgp_node *node, void *info)
{
node->info = info;
}
/*
* bgp_node_prefix
*/
static inline struct prefix *
bgp_node_prefix (struct bgp_node *node)
{
return &node->p;
}
/*
* bgp_node_prefixlen
*/
static inline u_char
bgp_node_prefixlen (struct bgp_node *node)
{
return bgp_node_prefix (node)->prefixlen;
}
/*
* bgp_node_parent_nolock
*
@ -349,13 +311,13 @@ bgp_table_iter_started (bgp_table_iter_t * iter)
/* This would benefit from a real atomic operation...
* until then. */
static inline u_int64_t
static inline uint64_t
bgp_table_next_version (struct bgp_table *table)
{
return ++table->version;
}
static inline u_int64_t
static inline uint64_t
bgp_table_version (struct bgp_table *table)
{
return table->version;

View File

@ -668,7 +668,7 @@ updgrp_show_packet_queue_walkcb (struct update_group *updgrp, void *arg)
*/
void
update_group_show_packet_queue (struct bgp *bgp, afi_t afi, safi_t safi,
struct vty *vty, u_int64_t id)
struct vty *vty, uint64_t id)
{
struct updwalk_context ctx;
@ -1587,7 +1587,7 @@ update_bgp_group_free (struct bgp *bgp)
void
update_group_show (struct bgp *bgp, afi_t afi, safi_t safi, struct vty *vty,
u_int64_t subgrp_id)
uint64_t subgrp_id)
{
struct updwalk_context ctx;
memset (&ctx, 0, sizeof (ctx));

View File

@ -133,7 +133,7 @@ struct update_group
safi_t safi;
int afid;
u_int64_t id;
uint64_t id;
time_t uptime;
u_int32_t join_events;
@ -231,8 +231,8 @@ struct update_subgroup
*/
struct
{
u_int64_t update_group_id;
u_int64_t subgroup_id;
uint64_t update_group_id;
uint64_t subgroup_id;
} split_from;
u_int32_t join_events;
@ -248,7 +248,7 @@ struct update_subgroup
u_int32_t split_events;
u_int32_t merge_checks_triggered;
u_int64_t id;
uint64_t id;
struct zlog *log;
u_int16_t sflags;
@ -297,8 +297,8 @@ struct updwalk_context
struct vty *vty;
struct bgp_node *rn;
struct bgp_info *ri;
u_int64_t updgrp_id;
u_int64_t subgrp_id;
uint64_t updgrp_id;
uint64_t subgrp_id;
bgp_policy_type_e policy_type;
const char *policy_name;
int policy_event_start_flag;
@ -367,7 +367,7 @@ extern void update_bgp_group_init (struct bgp *);
extern void udpate_bgp_group_free (struct bgp *);
extern void
update_group_show (struct bgp *bgp, afi_t afi, safi_t safi, struct vty *vty, u_int64_t subgrp_id);
update_group_show (struct bgp *bgp, afi_t afi, safi_t safi, struct vty *vty, uint64_t subgrp_id);
extern void update_group_show_stats (struct bgp *bgp, struct vty *vty);
extern void update_group_adjust_peer (struct peer_af *paf);
extern int update_group_adjust_soloness (struct peer *peer, int set);
@ -439,13 +439,13 @@ extern struct bgp_advertise *bgp_advertise_clean_subgroup (struct
*adj);
extern void update_group_show_adj_queue (struct bgp *bgp, afi_t afi,
safi_t safi, struct vty *vty,
u_int64_t id);
uint64_t id);
extern void update_group_show_advertised (struct bgp *bgp, afi_t afi,
safi_t safi, struct vty *vty,
u_int64_t id);
uint64_t id);
extern void update_group_show_packet_queue (struct bgp *bgp, afi_t afi,
safi_t safi, struct vty *vty,
u_int64_t id);
uint64_t id);
extern void subgroup_announce_route (struct update_subgroup *subgrp);
extern void subgroup_announce_all (struct update_subgroup *subgrp);

View File

@ -36,6 +36,7 @@
#include "thread.h"
#include "queue.h"
#include "routemap.h"
#include "filter.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_table.h"
@ -276,7 +277,7 @@ updgrp_show_adj_walkcb (struct update_group *updgrp, void *arg)
static void
updgrp_show_adj (struct bgp *bgp, afi_t afi, safi_t safi,
struct vty *vty, u_int64_t id, u_int8_t flags)
struct vty *vty, uint64_t id, u_int8_t flags)
{
struct updwalk_context ctx;
memset (&ctx, 0, sizeof (ctx));
@ -849,14 +850,14 @@ group_announce_route (struct bgp *bgp, afi_t afi, safi_t safi,
void
update_group_show_adj_queue (struct bgp *bgp, afi_t afi, safi_t safi,
struct vty *vty, u_int64_t id)
struct vty *vty, uint64_t id)
{
updgrp_show_adj (bgp, afi, safi, vty, id, UPDWALK_FLAGS_ADVQUEUE);
}
void
update_group_show_advertised (struct bgp *bgp, afi_t afi, safi_t safi,
struct vty *vty, u_int64_t id)
struct vty *vty, uint64_t id)
{
updgrp_show_adj (bgp, afi, safi, vty, id, UPDWALK_FLAGS_ADVERTISED);
}

View File

@ -32,8 +32,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "memory.h"
#include "hash.h"
#include "queue.h"
#include "if.h"
#include "vrf.h"
#include "filter.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_advertise.h"
@ -64,12 +63,20 @@ listen_range_exists (struct bgp *bgp, struct prefix *range, int exact);
afi_t
bgp_node_afi (struct vty *vty)
{
if (vty->node == BGP_IPV6_NODE ||
vty->node == BGP_IPV6M_NODE ||
vty->node == BGP_VPNV6_NODE ||
vty->node == BGP_ENCAPV6_NODE)
return AFI_IP6;
return AFI_IP;
afi_t afi;
switch (vty->node)
{
case BGP_IPV6_NODE:
case BGP_IPV6M_NODE:
case BGP_VPNV6_NODE:
case BGP_ENCAPV6_NODE:
afi = AFI_IP6;
break;
default:
afi = AFI_IP;
break;
}
return afi;
}
/* Utility function to get subsequent address family from current
@ -77,13 +84,26 @@ bgp_node_afi (struct vty *vty)
safi_t
bgp_node_safi (struct vty *vty)
{
if (vty->node == BGP_VPNV4_NODE || vty->node == BGP_VPNV6_NODE)
return SAFI_MPLS_VPN;
if (vty->node == BGP_ENCAP_NODE || vty->node == BGP_ENCAPV6_NODE)
return SAFI_ENCAP;
if (vty->node == BGP_IPV4M_NODE || vty->node == BGP_IPV6M_NODE)
return SAFI_MULTICAST;
return SAFI_UNICAST;
safi_t safi;
switch (vty->node)
{
case BGP_ENCAP_NODE:
case BGP_ENCAPV6_NODE:
safi = SAFI_ENCAP;
break;
case BGP_VPNV4_NODE:
case BGP_VPNV6_NODE:
safi = SAFI_MPLS_VPN;
break;
case BGP_IPV4M_NODE:
case BGP_IPV6M_NODE:
safi = SAFI_MULTICAST;
break;
default:
safi = SAFI_UNICAST;
break;
}
return safi;
}
int
@ -304,6 +324,9 @@ bgp_vty_return (struct vty *vty, int ret)
case BGP_ERR_INVALID_FOR_DYNAMIC_PEER:
str = "Operation not allowed on a dynamic neighbor";
break;
case BGP_ERR_INVALID_FOR_DIRECT_PEER:
str = "Operation not allowed on a directly connected neighbor";
break;
}
if (str)
{
@ -533,26 +556,22 @@ bgp_clear_vty (struct vty *vty, const char *name, afi_t afi, safi_t safi,
/* clear soft inbound */
static void
bgp_clear_star_soft_in (struct vty *vty)
bgp_clear_star_soft_in (struct vty *vty, const char *name)
{
bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_all,
bgp_clear_vty (vty,name, AFI_IP, SAFI_UNICAST, clear_all,
BGP_CLEAR_SOFT_IN, NULL);
#ifdef HAVE_IPV6
bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_all,
bgp_clear_vty (vty, name, AFI_IP6, SAFI_UNICAST, clear_all,
BGP_CLEAR_SOFT_IN, NULL);
#endif /* HAVE_IPV6 */
}
/* clear soft outbound */
static void
bgp_clear_star_soft_out (struct vty *vty)
bgp_clear_star_soft_out (struct vty *vty, const char *name)
{
bgp_clear_vty (vty, NULL, AFI_IP, SAFI_UNICAST, clear_all,
bgp_clear_vty (vty, name, AFI_IP, SAFI_UNICAST, clear_all,
BGP_CLEAR_SOFT_OUT, NULL);
#ifdef HAVE_IPV6
bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_all,
bgp_clear_vty (vty, name, AFI_IP6, SAFI_UNICAST, clear_all,
BGP_CLEAR_SOFT_OUT, NULL);
#endif /* HAVE_IPV6 */
}
@ -742,6 +761,27 @@ DEFUN (no_router_bgp,
struct bgp *bgp;
const char *name = NULL;
// "no router bgp" without an ASN
if (argc < 1)
{
//Pending: Make VRF option available for ASN less config
bgp = bgp_get_default();
if (bgp == NULL)
{
vty_out (vty, "%% No BGP process is configured%s", VTY_NEWLINE);
return CMD_WARNING;
}
if (listcount(bm->bgp) > 1)
{
vty_out (vty, "%% Multiple BGP processes are configured%s", VTY_NEWLINE);
return CMD_WARNING;
}
}
else
{
VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
if (argc == 3)
@ -754,6 +794,7 @@ DEFUN (no_router_bgp,
vty_out (vty, "%% Can't find BGP instance%s", VTY_NEWLINE);
return CMD_WARNING;
}
}
bgp_delete (bgp);
@ -770,6 +811,13 @@ ALIAS (no_router_bgp,
"BGP view\nBGP VRF\n"
"View/VRF name\n")
ALIAS (no_router_bgp,
no_router_bgp_noasn_cmd,
"no router bgp",
NO_STR
ROUTER_STR
BGP_STR)
/* BGP router-id. */
DEFUN (bgp_router_id,
@ -792,11 +840,7 @@ DEFUN (bgp_router_id,
return CMD_WARNING;
}
if (IPV4_ADDR_SAME (&bgp->router_id_static, &id))
return CMD_SUCCESS;
bgp->router_id_static = id;
bgp_router_id_set (bgp, &id);
bgp_router_id_static_set (bgp, id);
return CMD_SUCCESS;
}
@ -811,10 +855,6 @@ DEFUN (no_bgp_router_id,
int ret;
struct in_addr id;
struct bgp *bgp;
struct interface *ifp;
struct listnode *node;
struct connected *ifc;
struct prefix *p;
bgp = vty->index;
@ -823,21 +863,9 @@ DEFUN (no_bgp_router_id,
ret = inet_aton (argv[0], &id);
if (! ret)
{
ifp = if_lookup_by_name_vrf(argv[0], bgp->vrf_id);
if (!ifp) {
vty_out (vty, "%% Malformed BGP router identifier%s", VTY_NEWLINE);
return CMD_WARNING;
}
for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc))
{
p = ifc->address;
if (p && (p->family == AF_INET))
{
id = p->u.prefix4;
break;
}
}
}
if (! IPV4_ADDR_SAME (&bgp->router_id_static, &id))
{
@ -846,8 +874,8 @@ DEFUN (no_bgp_router_id,
}
}
bgp->router_id_static.s_addr = 0;
bgp_router_id_set (bgp, &bgp->router_id_zebra);
id.s_addr = 0;
bgp_router_id_static_set (bgp, id);
return CMD_SUCCESS;
}
@ -860,56 +888,6 @@ ALIAS (no_bgp_router_id,
"Override configured router identifier\n"
"Manually configured router identifier\n")
DEFUN (bgp_router_id_interface,
bgp_router_id_interface_cmd,
"bgp router-id IFNAME",
BGP_STR
"Override configured router identifier\n"
"Interface name\n")
{
struct bgp *bgp;
struct interface *ifp;
struct connected *ifc;
struct listnode *node;
struct prefix *p;
struct vrf *vrf;
bgp = vty->index;
p = NULL;
ifp = if_lookup_by_name_vrf(argv[0], bgp->vrf_id);
if (!ifp)
{
vrf = vrf_lookup(bgp->vrf_id);
vty_out (vty, "%% Couldnt find interface %s in VRF %s%s", argv[0], vrf? vrf->name:"", VTY_NEWLINE);
return CMD_WARNING;
}
for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc))
{
p = ifc->address;
if (p && (p->family == AF_INET))
{
if (IPV4_ADDR_SAME (&bgp->router_id_static, &p->u.prefix4))
return CMD_SUCCESS;
bgp->router_id_static = p->u.prefix4;
bgp_router_id_set (bgp, &p->u.prefix4);
return CMD_SUCCESS;
}
}
vty_out (vty, "%% Couldnt assign the router-id%s", VTY_NEWLINE);
return CMD_WARNING;
}
ALIAS (no_bgp_router_id,
no_bgp_router_id_interface_cmd,
"no bgp router-id IFNAME",
NO_STR
BGP_STR
"Override configured router identifier\n"
"Interface name\n")
/* BGP Cluster ID. */
DEFUN (bgp_cluster_id,
@ -933,7 +911,7 @@ DEFUN (bgp_cluster_id,
}
bgp_cluster_id_set (bgp, &cluster);
bgp_clear_star_soft_out (vty);
bgp_clear_star_soft_out (vty, bgp->name);
return CMD_SUCCESS;
}
@ -969,7 +947,7 @@ DEFUN (no_bgp_cluster_id,
}
bgp_cluster_id_unset (bgp);
bgp_clear_star_soft_out (vty);
bgp_clear_star_soft_out (vty, bgp->name);
return CMD_SUCCESS;
}
@ -1666,7 +1644,7 @@ DEFUN (bgp_client_to_client_reflection,
bgp = vty->index;
bgp_flag_unset (bgp, BGP_FLAG_NO_CLIENT_TO_CLIENT);
bgp_clear_star_soft_out (vty);
bgp_clear_star_soft_out (vty, bgp->name);
return CMD_SUCCESS;
}
@ -1683,7 +1661,7 @@ DEFUN (no_bgp_client_to_client_reflection,
bgp = vty->index;
bgp_flag_set (bgp, BGP_FLAG_NO_CLIENT_TO_CLIENT);
bgp_clear_star_soft_out (vty);
bgp_clear_star_soft_out (vty, bgp->name);
return CMD_SUCCESS;
}
@ -1838,6 +1816,26 @@ DEFUN (bgp_graceful_restart_stalepath_time,
return CMD_SUCCESS;
}
DEFUN (bgp_graceful_restart_restart_time,
bgp_graceful_restart_restart_time_cmd,
"bgp graceful-restart restart-time <1-3600>",
"BGP specific commands\n"
"Graceful restart capability parameters\n"
"Set the time to wait to delete stale routes before a BGP open message is received\n"
"Delay value (seconds)\n")
{
struct bgp *bgp;
u_int32_t restart;
bgp = vty->index;
if (! bgp)
return CMD_WARNING;
VTY_GET_INTEGER_RANGE ("restart-time", restart, argv[0], 1, 3600);
bgp->restart_time = restart;
return CMD_SUCCESS;
}
DEFUN (no_bgp_graceful_restart_stalepath_time,
no_bgp_graceful_restart_stalepath_time_cmd,
"no bgp graceful-restart stalepath-time",
@ -1856,6 +1854,24 @@ DEFUN (no_bgp_graceful_restart_stalepath_time,
return CMD_SUCCESS;
}
DEFUN (no_bgp_graceful_restart_restart_time,
no_bgp_graceful_restart_restart_time_cmd,
"no bgp graceful-restart restart-time",
NO_STR
"BGP specific commands\n"
"Graceful restart capability parameters\n"
"Set the time to wait to delete stale routes before a BGP open message is received\n")
{
struct bgp *bgp;
bgp = vty->index;
if (! bgp)
return CMD_WARNING;
bgp->restart_time = BGP_DEFAULT_RESTART_TIME;
return CMD_SUCCESS;
}
ALIAS (no_bgp_graceful_restart_stalepath_time,
no_bgp_graceful_restart_stalepath_time_val_cmd,
"no bgp graceful-restart stalepath-time <1-3600>",
@ -1865,6 +1881,15 @@ ALIAS (no_bgp_graceful_restart_stalepath_time,
"Set the max time to hold onto restarting peer's stale paths\n"
"Delay value (seconds)\n")
ALIAS (no_bgp_graceful_restart_restart_time,
no_bgp_graceful_restart_restart_time_val_cmd,
"no bgp graceful-restart restart-time <1-3600>",
NO_STR
"BGP specific commands\n"
"Graceful restart capability parameters\n"
"Set the time to wait to delete stale routes before a BGP open message is received\n"
"Delay value (seconds)\n")
/* "bgp fast-external-failover" configuration. */
DEFUN (bgp_fast_external_failover,
bgp_fast_external_failover_cmd,
@ -1904,7 +1929,7 @@ DEFUN (bgp_enforce_first_as,
bgp = vty->index;
bgp_flag_set (bgp, BGP_FLAG_ENFORCE_FIRST_AS);
bgp_clear_star_soft_in (vty);
bgp_clear_star_soft_in (vty, bgp->name);
return CMD_SUCCESS;
}
@ -1920,7 +1945,7 @@ DEFUN (no_bgp_enforce_first_as,
bgp = vty->index;
bgp_flag_unset (bgp, BGP_FLAG_ENFORCE_FIRST_AS);
bgp_clear_star_soft_in (vty);
bgp_clear_star_soft_in (vty, bgp->name);
return CMD_SUCCESS;
}
@ -2338,7 +2363,7 @@ DEFUN (bgp_default_local_preference,
VTY_GET_INTEGER ("local preference", local_pref, argv[0]);
bgp_default_local_preference_set (bgp, local_pref);
bgp_clear_star_soft_in (vty);
bgp_clear_star_soft_in (vty, bgp->name);
return CMD_SUCCESS;
}
@ -2355,7 +2380,7 @@ DEFUN (no_bgp_default_local_preference,
bgp = vty->index;
bgp_default_local_preference_unset (bgp);
bgp_clear_star_soft_in (vty);
bgp_clear_star_soft_in (vty, bgp->name);
return CMD_SUCCESS;
}
@ -2428,7 +2453,7 @@ DEFUN (bgp_rr_allow_outbound_policy,
{
bgp_flag_set(bgp, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY);
update_group_announce_rrclients(bgp);
bgp_clear_star_soft_out (vty);
bgp_clear_star_soft_out (vty, bgp->name);
}
return CMD_SUCCESS;
@ -2450,7 +2475,7 @@ DEFUN (no_bgp_rr_allow_outbound_policy,
{
bgp_flag_unset(bgp, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY);
update_group_announce_rrclients(bgp);
bgp_clear_star_soft_out (vty);
bgp_clear_star_soft_out (vty, bgp->name);
}
return CMD_SUCCESS;
@ -2697,7 +2722,7 @@ DEFUN (bgp_disable_connected_route_check,
bgp = vty->index;
bgp_flag_set (bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK);
bgp_clear_star_soft_in (vty);
bgp_clear_star_soft_in (vty, bgp->name);
return CMD_SUCCESS;
}
@ -2713,7 +2738,7 @@ DEFUN (no_bgp_disable_connected_route_check,
bgp = vty->index;
bgp_flag_unset (bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK);
bgp_clear_star_soft_in (vty);
bgp_clear_star_soft_in (vty, bgp->name);
return CMD_SUCCESS;
}
@ -2802,9 +2827,11 @@ DEFUN (neighbor_remote_as,
static int
peer_conf_interface_get (struct vty *vty, const char *conf_if, afi_t afi,
safi_t safi, int v6only, const char *peer_group_name)
safi_t safi, int v6only, const char *peer_group_name,
const char *as_str)
{
as_t as;
as_t as = 0;
int as_type = AS_UNSPECIFIED;
struct bgp *bgp;
struct peer *peer;
struct peer_group *group;
@ -2820,14 +2847,34 @@ peer_conf_interface_get (struct vty *vty, const char *conf_if, afi_t afi,
return CMD_WARNING;
}
if (as_str)
{
if (strncmp(as_str, "internal", strlen("internal")) == 0)
{
as_type = AS_INTERNAL;
}
else if (strncmp(as_str, "external", strlen("external")) == 0)
{
as_type = AS_EXTERNAL;
}
else
{
/* Get AS number. */
VTY_GET_INTEGER_RANGE ("AS", as, as_str, 1, BGP_AS4_MAX);
as_type = AS_SPECIFIED;
}
}
peer = peer_lookup_by_conf_if (bgp, conf_if);
if (!peer)
{
if (bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4)
&& afi == AFI_IP && safi == SAFI_UNICAST)
peer = peer_create (NULL, conf_if, bgp, bgp->as, 0, AS_UNSPECIFIED, 0, 0, NULL);
peer = peer_create (NULL, conf_if, bgp, bgp->as, as, as_type, 0, 0,
NULL);
else
peer = peer_create (NULL, conf_if, bgp, bgp->as, 0, AS_UNSPECIFIED, afi, safi, NULL);
peer = peer_create (NULL, conf_if, bgp, bgp->as, as, as_type, afi, safi,
NULL);
if (peer && v6only)
SET_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY);
@ -2838,8 +2885,11 @@ peer_conf_interface_get (struct vty *vty, const char *conf_if, afi_t afi,
* gets deleted later etc.)
*/
if (peer->ifp)
{
bgp_zebra_initiate_radv (bgp, peer);
}
peer_flag_set (peer, PEER_FLAG_CAPABILITY_ENHE);
}
else if ((v6only && !CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY)) ||
(!v6only && CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY)))
{
@ -2885,9 +2935,11 @@ DEFUN (neighbor_interface_config,
"Enable BGP on interface\n")
{
if (argc == 2)
return peer_conf_interface_get (vty, argv[0], AFI_IP, SAFI_UNICAST, 0, argv[1]);
return peer_conf_interface_get (vty, argv[0], AFI_IP, SAFI_UNICAST, 0,
argv[1], NULL);
else
return peer_conf_interface_get (vty, argv[0], AFI_IP, SAFI_UNICAST, 0, NULL);
return peer_conf_interface_get (vty, argv[0], AFI_IP, SAFI_UNICAST, 0,
NULL, NULL);
}
ALIAS (neighbor_interface_config,
@ -2908,9 +2960,11 @@ DEFUN (neighbor_interface_config_v6only,
"Enable BGP with v6 link-local only\n")
{
if (argc == 2)
return peer_conf_interface_get (vty, argv[0], AFI_IP, SAFI_UNICAST, 1, argv[1]);
return peer_conf_interface_get (vty, argv[0], AFI_IP, SAFI_UNICAST, 1,
argv[1], NULL);
else
return peer_conf_interface_get (vty, argv[0], AFI_IP, SAFI_UNICAST, 1, NULL);
return peer_conf_interface_get (vty, argv[0], AFI_IP, SAFI_UNICAST, 1,
NULL, NULL);
}
ALIAS (neighbor_interface_config_v6only,
@ -2923,6 +2977,30 @@ ALIAS (neighbor_interface_config_v6only,
"Member of the peer-group\n"
"peer-group name\n")
DEFUN (neighbor_interface_config_remote_as,
neighbor_interface_config_remote_as_cmd,
"neighbor WORD interface remote-as (" CMD_AS_RANGE "|external|internal)",
NEIGHBOR_STR
"Interface name or neighbor tag\n"
"Enable BGP on interface\n"
AS_STR)
{
return peer_conf_interface_get (vty, argv[0], AFI_IP, SAFI_UNICAST, 0,
NULL, argv[1]);
}
DEFUN (neighbor_interface_v6only_config_remote_as,
neighbor_interface_v6only_config_remote_as_cmd,
"neighbor WORD interface v6only remote-as (" CMD_AS_RANGE "|external|internal)",
NEIGHBOR_STR
"Interface name or neighbor tag\n"
"Enable BGP on interface\n"
AS_STR)
{
return peer_conf_interface_get (vty, argv[0], AFI_IP, SAFI_UNICAST, 1,
NULL, argv[1]);
}
DEFUN (neighbor_peer_group,
neighbor_peer_group_cmd,
"neighbor WORD peer-group",
@ -3073,6 +3151,24 @@ ALIAS (no_neighbor_interface_config,
"Member of the peer-group\n"
"peer-group name\n")
ALIAS (no_neighbor_interface_config,
no_neighbor_interface_config_remote_as_cmd,
"no neighbor WORD interface remote-as (" CMD_AS_RANGE "|internal|external)",
NO_STR
NEIGHBOR_STR
"Interface name\n"
"Configure BGP on interface\n"
AS_STR)
ALIAS (no_neighbor_interface_config,
no_neighbor_interface_config_v6only_remote_as_cmd,
"no neighbor WORD interface v6only remote-as (" CMD_AS_RANGE "|internal|external)",
NO_STR
NEIGHBOR_STR
"Interface name\n"
"Configure BGP on interface\n"
"Enable BGP with v6 link-local only\n"
AS_STR)
DEFUN (no_neighbor_peer_group,
no_neighbor_peer_group_cmd,
@ -4434,6 +4530,9 @@ peer_ebgp_multihop_set_vty (struct vty *vty, const char *ip_str,
if (! peer)
return CMD_WARNING;
if (peer->conf_if)
return bgp_vty_return (vty, BGP_ERR_INVALID_FOR_DIRECT_PEER);
if (! ttl_str)
ttl = MAXTTL;
else
@ -12982,7 +13081,7 @@ DEFUN (show_ip_bgp_attr_info,
static int bgp_show_update_groups(struct vty *vty, const char *name,
int afi, int safi,
u_int64_t subgrp_id)
uint64_t subgrp_id)
{
struct bgp *bgp;
@ -13109,7 +13208,7 @@ DEFUN (show_ip_bgp_updgrps_s,
"Detailed info about dynamic update groups\n"
"Specific subgroup to display detailed info for\n")
{
u_int64_t subgrp_id;
uint64_t subgrp_id;
VTY_GET_ULL("subgroup-id", subgrp_id, argv[0]);
return (bgp_show_update_groups(vty, NULL, AFI_IP, SAFI_UNICAST, subgrp_id));
@ -13125,7 +13224,7 @@ DEFUN (show_ip_bgp_instance_updgrps_s,
"Detailed info about dynamic update groups\n"
"Specific subgroup to display detailed info for\n")
{
u_int64_t subgrp_id;
uint64_t subgrp_id;
VTY_GET_ULL("subgroup-id", subgrp_id, argv[2]);
return (bgp_show_update_groups(vty, argv[1], AFI_IP, SAFI_UNICAST, subgrp_id));
@ -13139,7 +13238,7 @@ DEFUN (show_bgp_ipv6_updgrps_s,
"Detailed info about v6 dynamic update groups\n"
"Specific subgroup to display detailed info for\n")
{
u_int64_t subgrp_id;
uint64_t subgrp_id;
VTY_GET_ULL("subgroup-id", subgrp_id, argv[0]);
return(bgp_show_update_groups(vty, NULL, AFI_IP6, SAFI_UNICAST, subgrp_id));
@ -13153,7 +13252,7 @@ DEFUN (show_bgp_instance_ipv6_updgrps_s,
"Detailed info about v6 dynamic update groups\n"
"Specific subgroup to display detailed info for\n")
{
u_int64_t subgrp_id;
uint64_t subgrp_id;
VTY_GET_ULL("subgroup-id", subgrp_id, argv[2]);
return(bgp_show_update_groups(vty, argv[1], AFI_IP6, SAFI_UNICAST, subgrp_id));
@ -13173,7 +13272,7 @@ DEFUN (show_bgp_updgrps_s,
{
afi_t afi;
safi_t safi;
u_int64_t subgrp_id;
uint64_t subgrp_id;
afi = (strcmp(argv[0], "ipv4") == 0) ? AFI_IP : AFI_IP6;
safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
@ -13220,7 +13319,7 @@ DEFUN (show_bgp_instance_updgrps_stats,
static void
show_bgp_updgrps_adj_info_aux (struct vty *vty, const char *name,
afi_t afi, safi_t safi,
const char *what, u_int64_t subgrp_id)
const char *what, uint64_t subgrp_id)
{
struct bgp *bgp;
@ -13339,7 +13438,7 @@ DEFUN (show_ip_bgp_updgrps_adj_s,
"Packet queue\n")
{
u_int64_t subgrp_id;
uint64_t subgrp_id;
VTY_GET_ULL("subgroup-id", subgrp_id, argv[0]);
@ -13361,7 +13460,7 @@ DEFUN (show_ip_bgp_instance_updgrps_adj_s,
"Packet queue\n")
{
u_int64_t subgrp_id;
uint64_t subgrp_id;
VTY_GET_ULL("subgroup-id", subgrp_id, argv[2]);
@ -13387,7 +13486,7 @@ DEFUN (show_bgp_updgrps_afi_adj_s,
{
afi_t afi;
safi_t safi;
u_int64_t subgrp_id;
uint64_t subgrp_id;
afi = (strcmp(argv[0], "ipv4") == 0) ? AFI_IP : AFI_IP6;
safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
@ -13408,7 +13507,7 @@ DEFUN (show_bgp_updgrps_adj_s,
"Announced routes\n"
"Packet queue\n")
{
u_int64_t subgrp_id;
uint64_t subgrp_id;
VTY_GET_ULL("subgroup-id", subgrp_id, argv[0]);
@ -13428,7 +13527,7 @@ DEFUN (show_bgp_instance_updgrps_adj_s,
"Announced routes\n"
"Packet queue\n")
{
u_int64_t subgrp_id;
uint64_t subgrp_id;
VTY_GET_ULL("subgroup-id", subgrp_id, argv[2]);
@ -13569,7 +13668,7 @@ bgp_show_peer_group (struct vty *vty, struct bgp *bgp,
}
if (type == show_peer_group && ! find)
vty_out (vty, "%% No such peer-groupr%s", VTY_NEWLINE);
vty_out (vty, "%% No such peer-group%s", VTY_NEWLINE);
return CMD_SUCCESS;
}
@ -14376,13 +14475,12 @@ bgp_vty_init (void)
/* "no router bgp" commands. */
install_element (CONFIG_NODE, &no_router_bgp_cmd);
install_element (CONFIG_NODE, &no_router_bgp_instance_cmd);
install_element (CONFIG_NODE, &no_router_bgp_noasn_cmd);
/* "bgp router-id" commands. */
install_element (BGP_NODE, &bgp_router_id_cmd);
install_element (BGP_NODE, &no_bgp_router_id_cmd);
install_element (BGP_NODE, &no_bgp_router_id_val_cmd);
install_element (BGP_NODE, &bgp_router_id_interface_cmd);
install_element (BGP_NODE, &no_bgp_router_id_interface_cmd);
/* "bgp cluster-id" commands. */
install_element (BGP_NODE, &bgp_cluster_id_cmd);
@ -14481,6 +14579,9 @@ bgp_vty_init (void)
install_element (BGP_NODE, &bgp_graceful_restart_stalepath_time_cmd);
install_element (BGP_NODE, &no_bgp_graceful_restart_stalepath_time_cmd);
install_element (BGP_NODE, &no_bgp_graceful_restart_stalepath_time_val_cmd);
install_element (BGP_NODE, &bgp_graceful_restart_restart_time_cmd);
install_element (BGP_NODE, &no_bgp_graceful_restart_restart_time_cmd);
install_element (BGP_NODE, &no_bgp_graceful_restart_restart_time_val_cmd);
/* "bgp fast-external-failover" commands */
install_element (BGP_NODE, &bgp_fast_external_failover_cmd);
@ -14560,12 +14661,16 @@ bgp_vty_init (void)
install_element (BGP_NODE, &neighbor_interface_config_v6only_cmd);
install_element (BGP_NODE, &neighbor_interface_config_peergroup_cmd);
install_element (BGP_NODE, &neighbor_interface_config_v6only_peergroup_cmd);
install_element (BGP_NODE, &neighbor_interface_config_remote_as_cmd);
install_element (BGP_NODE, &neighbor_interface_v6only_config_remote_as_cmd);
install_element (BGP_NODE, &no_neighbor_cmd);
install_element (BGP_NODE, &no_neighbor_remote_as_cmd);
install_element (BGP_NODE, &no_neighbor_interface_config_cmd);
install_element (BGP_NODE, &no_neighbor_interface_config_v6only_cmd);
install_element (BGP_NODE, &no_neighbor_interface_config_peergroup_cmd);
install_element (BGP_NODE, &no_neighbor_interface_config_v6only_peergroup_cmd);
install_element (BGP_NODE, &no_neighbor_interface_config_remote_as_cmd);
install_element (BGP_NODE, &no_neighbor_interface_config_v6only_remote_as_cmd);
/* "neighbor peer-group" commands. */
install_element (BGP_NODE, &neighbor_peer_group_cmd);

View File

@ -32,6 +32,8 @@ Boston, MA 02111-1307, USA. */
#include "queue.h"
#include "memory.h"
#include "lib/json.h"
#include "lib/bfd.h"
#include "filter.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_route.h"
@ -109,8 +111,6 @@ bgp_router_id_update (int command, struct zclient *zclient, zebra_size_t length,
vrf_id_t vrf_id)
{
struct prefix router_id;
struct listnode *node, *nnode;
struct bgp *bgp;
zebra_router_id_update_read(zclient->ibuf,&router_id);
@ -121,32 +121,7 @@ bgp_router_id_update (int command, struct zclient *zclient, zebra_size_t length,
zlog_debug("Rx Router Id update VRF %u Id %s", vrf_id, buf);
}
if (vrf_id == VRF_DEFAULT)
{
/* Router-id change for default VRF has to also update all views. */
for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
{
if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
continue;
bgp->router_id_zebra = router_id.u.prefix4;
if (!bgp->router_id_static.s_addr)
bgp_router_id_set (bgp, &router_id.u.prefix4);
}
}
else
{
bgp = bgp_lookup_by_vrf_id (vrf_id);
if (bgp)
{
bgp->router_id_zebra = router_id.u.prefix4;
if (!bgp->router_id_static.s_addr)
bgp_router_id_set (bgp, &router_id.u.prefix4);
}
}
bgp_router_id_zebra_bump (vrf_id, &router_id);
return 0;
}
@ -385,7 +360,16 @@ bgp_interface_down (int command, struct zclient *zclient, zebra_size_t length,
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
{
#if defined(HAVE_CUMULUS)
/* Take down directly connected EBGP peers as well as 1-hop BFD
* tracked (directly connected) IBGP peers.
*/
if ((peer->ttl != 1) && (peer->gtsm_hops != 1) &&
(!peer->bfd_info || bgp_bfd_is_peer_multihop(peer)))
#else
/* Take down directly connected EBGP peers */
if ((peer->ttl != 1) && (peer->gtsm_hops != 1))
#endif
continue;
if (ifp == peer->nexthop.ifp)
@ -882,7 +866,7 @@ if_lookup_by_ipv4_exact (struct in_addr *addr, vrf_id_t vrf_id)
#ifdef HAVE_IPV6
struct interface *
if_lookup_by_ipv6 (struct in6_addr *addr, unsigned int ifindex, vrf_id_t vrf_id)
if_lookup_by_ipv6 (struct in6_addr *addr, ifindex_t ifindex, vrf_id_t vrf_id)
{
struct listnode *ifnode;
struct listnode *cnode;
@ -904,7 +888,7 @@ if_lookup_by_ipv6 (struct in6_addr *addr, unsigned int ifindex, vrf_id_t vrf_id)
if (cp->family == AF_INET6)
if (prefix_match (cp, (struct prefix *)&p))
{
if (IN6_IS_ADDR_LINKLOCAL(&cp->u.prefix6.s6_addr32[0]))
if (IN6_IS_ADDR_LINKLOCAL(&cp->u.prefix6))
{
if (ifindex == ifp->ifindex)
return ifp;
@ -918,7 +902,7 @@ if_lookup_by_ipv6 (struct in6_addr *addr, unsigned int ifindex, vrf_id_t vrf_id)
}
struct interface *
if_lookup_by_ipv6_exact (struct in6_addr *addr, unsigned int ifindex, vrf_id_t vrf_id)
if_lookup_by_ipv6_exact (struct in6_addr *addr, ifindex_t ifindex, vrf_id_t vrf_id)
{
struct listnode *ifnode;
struct listnode *cnode;
@ -1162,6 +1146,11 @@ bgp_info_to_ipv6_nexthop (struct bgp_info *info)
/* If both global and link-local address present. */
if (info->attr->extra->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
{
/* Check if route-map is set to prefer global over link-local */
if (info->attr->extra->mp_nexthop_prefer_global)
nexthop = &info->attr->extra->mp_nexthop_global;
else
{
/* Workaround for Cisco's nexthop bug. */
if (IN6_IS_ADDR_UNSPECIFIED (&info->attr->extra->mp_nexthop_global)
@ -1170,6 +1159,7 @@ bgp_info_to_ipv6_nexthop (struct bgp_info *info)
else
nexthop = &info->attr->extra->mp_nexthop_local;
}
}
return nexthop;
}
@ -1401,7 +1391,7 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
if (p->family == AF_INET6 ||
(p->family == AF_INET && BGP_ATTR_NEXTHOP_AFI_IP6(info->attr)))
{
unsigned int ifindex;
ifindex_t ifindex;
struct in6_addr *nexthop;
struct zapi_ipv6 api;
int valid_nh_count = 0;
@ -1547,7 +1537,7 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp,
api.nexthop = (struct in6_addr **)STREAM_DATA (bgp_nexthop_buf);
SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
api.ifindex_num = valid_nh_count;
api.ifindex = (unsigned int *)STREAM_DATA (bgp_ifindices_buf);
api.ifindex = (ifindex_t *)STREAM_DATA (bgp_ifindices_buf);
SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
api.metric = metric;
api.tag = 0;
@ -1891,11 +1881,25 @@ bgp_redistribute_metric_set (struct bgp *bgp, struct bgp_redist *red, afi_t afi,
red->redist_metric_flag = 1;
red->redist_metric = metric;
for (rn = bgp_table_top(bgp->rib[afi][SAFI_UNICAST]); rn; rn = bgp_route_next(rn)) {
for (ri = rn->info; ri; ri = ri->next) {
if (ri->sub_type == BGP_ROUTE_REDISTRIBUTE && ri->type == type &&
ri->instance == red->instance) {
ri->attr->med = red->redist_metric;
for (rn = bgp_table_top(bgp->rib[afi][SAFI_UNICAST]); rn; rn = bgp_route_next(rn))
{
for (ri = rn->info; ri; ri = ri->next)
{
if (ri->sub_type == BGP_ROUTE_REDISTRIBUTE &&
ri->type == type &&
ri->instance == red->instance)
{
struct attr *old_attr;
struct attr new_attr;
struct attr_extra new_extra;
new_attr.extra = &new_extra;
bgp_attr_dup (&new_attr, ri->attr);
new_attr.med = red->redist_metric;
old_attr = ri->attr;
ri->attr = bgp_attr_intern (&new_attr);
bgp_attr_unintern (&old_attr);
bgp_info_set_flag(rn, ri, BGP_INFO_ATTR_CHANGED);
bgp_process(bgp, rn, afi, SAFI_UNICAST);
}
@ -1972,6 +1976,24 @@ bgp_redistribute_unset (struct bgp *bgp, afi_t afi, int type, u_short instance)
return CMD_SUCCESS;
}
/* Update redistribute vrf bitmap during triggers like
restart networking or delete/add VRFs */
void
bgp_update_redist_vrf_bitmaps (struct bgp *bgp, vrf_id_t old_vrf_id)
{
int i;
afi_t afi;
for (afi = AFI_IP; afi < AFI_MAX; afi++)
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
if (vrf_bitmap_check (zclient->redist[afi][i], old_vrf_id))
{
vrf_bitmap_unset (zclient->redist[afi][i], old_vrf_id);
vrf_bitmap_set (zclient->redist[afi][i], bgp->vrf_id);
}
return;
}
void
bgp_zclient_reset (void)
{
@ -2057,6 +2079,9 @@ bgp_zebra_connected (struct zclient *zclient)
bgp_zebra_instance_register (bgp);
/* Send the client registration */
bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER);
/* TODO - What if we have peers and networks configured, do we have to
* kick-start them?
*/

View File

@ -58,8 +58,8 @@ extern int bgp_redistribute_unreg (struct bgp *, afi_t, int, u_short);
extern struct interface *if_lookup_by_ipv4 (struct in_addr *, vrf_id_t);
extern struct interface *if_lookup_by_ipv4_exact (struct in_addr *, vrf_id_t);
#ifdef HAVE_IPV6
extern struct interface *if_lookup_by_ipv6 (struct in6_addr *, unsigned int, vrf_id_t);
extern struct interface *if_lookup_by_ipv6_exact (struct in6_addr *, unsigned int, vrf_id_t);
extern struct interface *if_lookup_by_ipv6 (struct in6_addr *, ifindex_t, vrf_id_t);
extern struct interface *if_lookup_by_ipv6_exact (struct in6_addr *, ifindex_t, vrf_id_t);
#endif /* HAVE_IPV6 */
#endif /* _QUAGGA_BGP_ZEBRA_H */

View File

@ -209,8 +209,8 @@ bgp_config_check (struct bgp *bgp, int config)
}
/* Set BGP router identifier. */
int
bgp_router_id_set (struct bgp *bgp, struct in_addr *id)
static int
bgp_router_id_set (struct bgp *bgp, const struct in_addr *id)
{
struct peer *peer;
struct listnode *node, *nnode;
@ -235,6 +235,46 @@ bgp_router_id_set (struct bgp *bgp, struct in_addr *id)
return 0;
}
void
bgp_router_id_zebra_bump (vrf_id_t vrf_id, const struct prefix *router_id)
{
struct listnode *node, *nnode;
struct bgp *bgp;
if (vrf_id == VRF_DEFAULT)
{
/* Router-id change for default VRF has to also update all views. */
for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
{
if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
continue;
bgp->router_id_zebra = router_id->u.prefix4;
if (!bgp->router_id_static.s_addr)
bgp_router_id_set (bgp, &router_id->u.prefix4);
}
}
else
{
bgp = bgp_lookup_by_vrf_id (vrf_id);
if (bgp)
{
bgp->router_id_zebra = router_id->u.prefix4;
if (!bgp->router_id_static.s_addr)
bgp_router_id_set (bgp, &router_id->u.prefix4);
}
}
}
int
bgp_router_id_static_set (struct bgp *bgp, struct in_addr id)
{
bgp->router_id_static = id;
bgp_router_id_set (bgp, id.s_addr ? &id : &bgp->router_id_zebra);
return 0;
}
/* BGP's cluster-id control. */
int
bgp_cluster_id_set (struct bgp *bgp, struct in_addr *cluster_id)
@ -1255,7 +1295,7 @@ bgp_peer_conf_if_to_su_update_v4 (struct peer *peer, struct interface *ifp)
{
struct connected *ifc;
struct prefix p;
u_int32_t s_addr;
u_int32_t addr;
struct listnode *node;
/* If our IPv4 address on the interface is /30 or /31, we can derive the
@ -1269,26 +1309,26 @@ bgp_peer_conf_if_to_su_update_v4 (struct peer *peer, struct interface *ifp)
if (p.prefixlen == 30)
{
peer->su.sa.sa_family = AF_INET;
s_addr = ntohl(p.u.prefix4.s_addr);
if (s_addr % 4 == 1)
peer->su.sin.sin_addr.s_addr = htonl(s_addr+1);
else if (s_addr % 4 == 2)
peer->su.sin.sin_addr.s_addr = htonl(s_addr-1);
addr = ntohl(p.u.prefix4.s_addr);
if (addr % 4 == 1)
peer->su.sin.sin_addr.s_addr = htonl(addr+1);
else if (addr % 4 == 2)
peer->su.sin.sin_addr.s_addr = htonl(addr-1);
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
peer->su->sin.sin_len = sizeof(struct sockaddr_in);
peer->su.sin.sin_len = sizeof(struct sockaddr_in);
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
return 1;
}
else if (p.prefixlen == 31)
{
peer->su.sa.sa_family = AF_INET;
s_addr = ntohl(p.u.prefix4.s_addr);
if (s_addr % 2 == 0)
peer->su.sin.sin_addr.s_addr = htonl(s_addr+1);
addr = ntohl(p.u.prefix4.s_addr);
if (addr % 2 == 0)
peer->su.sin.sin_addr.s_addr = htonl(addr+1);
else
peer->su.sin.sin_addr.s_addr = htonl(s_addr-1);
peer->su.sin.sin_addr.s_addr = htonl(addr-1);
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
peer->su->sin.sin_len = sizeof(struct sockaddr_in);
peer->su.sin.sin_len = sizeof(struct sockaddr_in);
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
return 1;
}
@ -1827,6 +1867,15 @@ peer_deactivate (struct peer *peer, afi_t afi, safi_t safi)
return ret;
}
int
peer_afc_set (struct peer *peer, afi_t afi, safi_t safi, int enable)
{
if (enable)
return peer_activate (peer, afi, safi);
else
return peer_deactivate (peer, afi, safi);
}
static void
peer_nsf_stop (struct peer *peer)
{
@ -2546,6 +2595,7 @@ peer_group_bind (struct bgp *bgp, union sockunion *su, struct peer *peer,
int first_member = 0;
afi_t afi;
safi_t safi;
int cap_enhe_preset = 0;
/* Lookup the peer. */
if (!peer)
@ -2580,8 +2630,18 @@ peer_group_bind (struct bgp *bgp, union sockunion *su, struct peer *peer,
first_member = 1;
}
if (CHECK_FLAG (peer->flags, PEER_FLAG_CAPABILITY_ENHE))
cap_enhe_preset = 1;
peer_group2peer_config_copy(group, peer);
/*
* Capability extended-nexthop is enabled for an interface neighbor by
* default. So, fix that up here.
*/
if (peer->ifp && cap_enhe_preset)
peer_flag_set (peer, PEER_FLAG_CAPABILITY_ENHE);
for (afi = AFI_IP; afi < AFI_MAX; afi++)
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
{
@ -3167,6 +3227,8 @@ bgp_free (struct bgp *bgp)
bgp_table_finish (&bgp->rib[afi][safi]);
}
bgp_address_destroy (bgp);
/* If Default instance or VRF, unlink from the VRF structure. */
vrf = bgp_vrf_lookup_by_instance_type (bgp);
if (vrf)
@ -4078,7 +4140,7 @@ peer_ebgp_multihop_unset (struct peer *peer)
/* Neighbor description. */
int
peer_description_set (struct peer *peer, char *desc)
peer_description_set (struct peer *peer, const char *desc)
{
if (peer->desc)
XFREE (MTYPE_PEER_DESC, peer->desc);
@ -4171,7 +4233,7 @@ peer_update_source_if_set (struct peer *peer, const char *ifname)
}
int
peer_update_source_addr_set (struct peer *peer, union sockunion *su)
peer_update_source_addr_set (struct peer *peer, const union sockunion *su)
{
struct peer_group *group;
struct listnode *node, *nnode;
@ -6269,6 +6331,8 @@ bgp_config_write_peer_global (struct vty *vty, struct bgp *bgp,
struct peer *g_peer = NULL;
char buf[SU_ADDRSTRLEN];
char *addr;
int if_pg_printed = FALSE;
int if_ras_printed = FALSE;
/* Skip dynamic neighbors. */
if (peer_dynamic_neighbor (peer))
@ -6290,7 +6354,25 @@ bgp_config_write_peer_global (struct vty *vty, struct bgp *bgp,
vty_out (vty, " neighbor %s interface", addr);
if (peer_group_active (peer))
{
vty_out (vty, " peer-group %s", peer->group->name);
if_pg_printed = TRUE;
}
else if (peer->as_type == AS_SPECIFIED)
{
vty_out (vty, " remote-as %u", peer->as);
if_ras_printed = TRUE;
}
else if (peer->as_type == AS_INTERNAL)
{
vty_out (vty, " remote-as internal");
if_ras_printed = TRUE;
}
else if (peer->as_type == AS_EXTERNAL)
{
vty_out (vty, " remote-as external");
if_ras_printed = TRUE;
}
vty_out (vty, "%s", VTY_NEWLINE);
}
@ -6301,7 +6383,7 @@ bgp_config_write_peer_global (struct vty *vty, struct bgp *bgp,
{
g_peer = peer->group->conf;
if (g_peer->as_type == AS_UNSPECIFIED)
if (g_peer->as_type == AS_UNSPECIFIED && !if_ras_printed)
{
if (peer->as_type == AS_SPECIFIED)
{
@ -6320,7 +6402,7 @@ bgp_config_write_peer_global (struct vty *vty, struct bgp *bgp,
/* For swpX peers we displayed the peer-group
* via 'neighbor swpX interface peer-group WORD' */
if (!peer->conf_if)
if (!if_pg_printed)
vty_out (vty, " neighbor %s peer-group %s%s", addr,
peer->group->name, VTY_NEWLINE);
}
@ -6335,6 +6417,8 @@ bgp_config_write_peer_global (struct vty *vty, struct bgp *bgp,
VTY_NEWLINE);
}
if (!if_ras_printed)
{
if (peer->as_type == AS_SPECIFIED)
{
vty_out (vty, " neighbor %s remote-as %u%s", addr, peer->as,
@ -6349,6 +6433,7 @@ bgp_config_write_peer_global (struct vty *vty, struct bgp *bgp,
vty_out (vty, " neighbor %s remote-as external%s", addr, VTY_NEWLINE);
}
}
}
/* local-as */
if (peer->change_local_as)
@ -6541,7 +6626,17 @@ bgp_config_write_peer_global (struct vty *vty, struct bgp *bgp,
}
/* capability extended-nexthop */
if (CHECK_FLAG (peer->flags, PEER_FLAG_CAPABILITY_ENHE))
if (peer->ifp && !CHECK_FLAG (peer->flags, PEER_FLAG_CAPABILITY_ENHE))
{
if (! peer_group_active (peer) ||
! CHECK_FLAG (g_peer->flags, PEER_FLAG_CAPABILITY_ENHE))
{
vty_out (vty, " no neighbor %s capability extended-nexthop%s", addr,
VTY_NEWLINE);
}
}
if (!peer->ifp && CHECK_FLAG (peer->flags, PEER_FLAG_CAPABILITY_ENHE))
{
if (! peer_group_active (peer) ||
! CHECK_FLAG (g_peer->flags, PEER_FLAG_CAPABILITY_ENHE))
@ -6630,10 +6725,32 @@ bgp_config_write_peer_af (struct vty *vty, struct bgp *bgp,
{
if (peer->afc[afi][safi])
{
if ((afi == AFI_IP) && (safi == SAFI_UNICAST))
{
if (bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4))
{
afi_header_vty_out(vty, afi, safi, write,
" neighbor %s activate%s",
addr, VTY_NEWLINE);
}
}
else
afi_header_vty_out (vty, afi, safi, write,
" neighbor %s activate%s",
addr, VTY_NEWLINE);
}
else
{
if ((afi == AFI_IP) && (safi == SAFI_UNICAST))
{
if (!bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4))
{
afi_header_vty_out (vty, afi, safi, write,
" no neighbor %s activate%s",
addr, VTY_NEWLINE);
}
}
}
}
/* addpath TX knobs */
@ -7116,6 +7233,9 @@ bgp_config_write (struct vty *vty)
if (bgp->stalepath_time != BGP_DEFAULT_STALEPATH_TIME)
vty_out (vty, " bgp graceful-restart stalepath-time %d%s",
bgp->stalepath_time, VTY_NEWLINE);
if (bgp->restart_time != BGP_DEFAULT_RESTART_TIME)
vty_out (vty, " bgp graceful-restart restart-time %d%s",
bgp->restart_time, VTY_NEWLINE);
if (bgp_flag_check (bgp, BGP_FLAG_GRACEFUL_RESTART))
vty_out (vty, " bgp graceful-restart%s", VTY_NEWLINE);
@ -7216,8 +7336,6 @@ bgp_config_write (struct vty *vty)
/* ENCAPv6 configuration. */
write += bgp_config_write_family (vty, bgp, AFI_IP6, SAFI_ENCAP);
vty_out (vty, " exit%s", VTY_NEWLINE);
write++;
}
return write;

View File

@ -112,8 +112,8 @@ struct bgp_master
#define BGP_OPT_CONFIG_CISCO (1 << 2)
#define BGP_OPT_NO_LISTEN (1 << 3)
u_int64_t updgrp_idspace;
u_int64_t subgrp_idspace;
uint64_t updgrp_idspace;
uint64_t subgrp_idspace;
/* timer to dampen route map changes */
struct thread *t_rmap_update; /* Handle route map updates */
@ -518,7 +518,7 @@ struct peer
/* BGP peer group. */
struct peer_group *group;
u_int64_t version[AFI_MAX][SAFI_MAX];
uint64_t version[AFI_MAX][SAFI_MAX];
/* BGP peer_af structures, per configured AF on this peer */
struct peer_af *peer_af_array[BGP_AF_MAX];
@ -583,7 +583,7 @@ struct peer
time_t readtime; /* Last read time */
time_t resettime; /* Last reset time */
unsigned int ifindex; /* ifindex of the BGP connection. */
ifindex_t ifindex; /* ifindex of the BGP connection. */
char *conf_if; /* neighbor interface config name. */
struct interface *ifp; /* corresponding interface */
char *ifname; /* bind interface name. */
@ -1120,6 +1120,7 @@ enum bgp_clear_type
#define BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_NOT_FOUND -31
#define BGP_ERR_INVALID_FOR_DYNAMIC_PEER -32
#define BGP_ERR_MAX -33
#define BGP_ERR_INVALID_FOR_DIRECT_PEER -34
/*
* Enumeration of different policy kinds a peer can be configured with.
@ -1207,7 +1208,8 @@ extern int bgp_flag_check (struct bgp *, int);
extern void bgp_lock (struct bgp *);
extern void bgp_unlock (struct bgp *);
extern int bgp_router_id_set (struct bgp *, struct in_addr *);
extern void bgp_router_id_zebra_bump (vrf_id_t, const struct prefix*);
extern int bgp_router_id_static_set (struct bgp *, struct in_addr);
extern int bgp_cluster_id_set (struct bgp *, struct in_addr *);
extern int bgp_cluster_id_unset (struct bgp *);
@ -1219,7 +1221,7 @@ extern int bgp_confederation_peers_check (struct bgp *, as_t);
extern int bgp_confederation_peers_add (struct bgp *, as_t);
extern int bgp_confederation_peers_remove (struct bgp *, as_t);
extern int bgp_timers_set (struct bgp *, u_int32_t, u_int32_t);
extern int bgp_timers_set (struct bgp *, u_int32_t keepalive, u_int32_t holdtime);
extern int bgp_timers_unset (struct bgp *);
extern int bgp_default_local_preference_set (struct bgp *, u_int32_t);
@ -1244,6 +1246,7 @@ extern int peer_group_listen_range_add(struct peer_group *, struct prefix *);
extern int peer_activate (struct peer *, afi_t, safi_t);
extern int peer_deactivate (struct peer *, afi_t, safi_t);
extern int peer_afc_set (struct peer *, afi_t, safi_t, int);
extern int peer_group_bind (struct bgp *, union sockunion *, struct peer *,
struct peer_group *, as_t *);
@ -1260,11 +1263,11 @@ extern int peer_ebgp_multihop_set (struct peer *, int);
extern int peer_ebgp_multihop_unset (struct peer *);
extern int is_ebgp_multihop_configured (struct peer *peer);
extern int peer_description_set (struct peer *, char *);
extern int peer_description_set (struct peer *, const char *);
extern int peer_description_unset (struct peer *);
extern int peer_update_source_if_set (struct peer *, const char *);
extern int peer_update_source_addr_set (struct peer *, union sockunion *);
extern int peer_update_source_addr_set (struct peer *, const union sockunion *);
extern int peer_update_source_unset (struct peer *);
extern int peer_default_originate_set (struct peer *, afi_t, safi_t, const char *);
@ -1276,7 +1279,7 @@ extern int peer_port_unset (struct peer *);
extern int peer_weight_set (struct peer *, u_int16_t);
extern int peer_weight_unset (struct peer *);
extern int peer_timers_set (struct peer *, u_int32_t, u_int32_t);
extern int peer_timers_set (struct peer *, u_int32_t keepalive, u_int32_t holdtime);
extern int peer_timers_unset (struct peer *);
extern int peer_timers_connect_set (struct peer *, u_int32_t);
@ -1501,4 +1504,5 @@ bgp_vrf_unlink (struct bgp *bgp, struct vrf *vrf)
bgp->vrf_id = VRF_UNKNOWN;
}
extern void bgp_update_redist_vrf_bitmaps (struct bgp*, vrf_id_t);
#endif /* _QUAGGA_BGPD_H */

View File

@ -7,7 +7,7 @@
##
AC_PREREQ(2.60)
AC_INIT(Quagga, 0.99.24+cl3u2, [https://bugzilla.quagga.net])
AC_INIT(Quagga, 0.99.24+cl3u3, [https://bugzilla.quagga.net])
CONFIG_ARGS="$*"
AC_SUBST(CONFIG_ARGS)
AC_CONFIG_SRCDIR(lib/zebra.h)
@ -21,6 +21,7 @@ AC_CANONICAL_HOST()
AC_CANONICAL_TARGET()
AM_INIT_AUTOMAKE(1.6)
m4_ifndef([AM_SILENT_RULES], [m4_define([AM_SILENT_RULES],[])])
AM_SILENT_RULES([yes])
AC_CONFIG_HEADERS(config.h)
@ -265,15 +266,11 @@ AC_ARG_WITH(libpam,
AS_HELP_STRING([--with-libpam], [use libpam for PAM support in vtysh]))
AC_ARG_ENABLE(tcp-zebra,
AS_HELP_STRING([--enable-tcp-zebra], [enable TCP/IP socket connection between zebra and protocol daemon]))
AC_ARG_ENABLE(opaque-lsa,
AS_HELP_STRING([--disable-opaque-lsa],[do not build OSPF Opaque-LSA with OSPFAPI support (RFC2370)]))
AC_ARG_ENABLE(ospfapi,
AS_HELP_STRING([--disable-ospfapi], [do not build OSPFAPI to access the OSPF LSA Database]))
AC_ARG_ENABLE(ospfclient,
AS_HELP_STRING([--disable-ospfclient], [do not build OSPFAPI client for OSPFAPI,
(this is the default if --disable-ospfapi is set)]))
AC_ARG_ENABLE(ospf-te,
AS_HELP_STRING([--disable-ospf-te],[disable Traffic Engineering Extension to OSPF]))
AC_ARG_ENABLE(multipath,
AS_HELP_STRING([--enable-multipath=ARG], [enable multipath function, ARG must be digit]))
AC_ARG_ENABLE(user,
@ -320,13 +317,18 @@ AC_ARG_ENABLE(werror,
AS_HELP_STRING([--enable-werror], [enable -Werror (recommended for developers only)]))
AC_ARG_ENABLE(cumulus,
AS_HELP_STRING([--enable-cumulus], [enable Cumulus Switch Special Extensions]))
AC_ARG_ENABLE(bgp-standalone,
AS_HELP_STRING([--enable-bgp-standalone], [Modify code to allow BGP to work without Zebra]))
AC_ARG_ENABLE(rr-semantics,
AS_HELP_STRING([--disable-rr-semantics], [disable the v6 Route Replace semantics]))
AC_CHECK_HEADERS(json-c/json.h)
AC_CHECK_LIB(json-c, json_object_get, LIBS="$LIBS -ljson-c")
if test $ac_cv_lib_json_c_json_object_get = no; then
AC_CHECK_LIB(json, json_object_get, LIBS="$LIBS -ljson")
if test $ac_cv_lib_json_json_object_get = no; then
AC_MSG_ERROR([lib json is needed to compile])
fi
fi
if test x"${enable_gcc_rdynamic}" != x"no" ; then
@ -368,6 +370,10 @@ if test "${enable_cumulus}" = "yes" ; then
AC_DEFINE(HAVE_CUMULUS,,Compile Special Cumulus Code in)
fi
if test "${enable_bgp_standalone}" = "yes" ; then
AC_DEFINE(HAVE_BGP_STANDALONE,,Allow BGP to work without Zebra)
fi
if test "${enable_shell_access}" = "yes"; then
AC_DEFINE(HAVE_SHELL_ACCESS,,Allow user to use ssh/telnet/bash)
fi
@ -380,15 +386,6 @@ if test "${enable_tcp_zebra}" = "yes"; then
AC_DEFINE(HAVE_TCP_ZEBRA,,Use TCP for zebra communication)
fi
if test "${enable_opaque_lsa}" != "no"; then
AC_DEFINE(HAVE_OPAQUE_LSA,,OSPF Opaque LSA)
fi
if test "${enable_ospf_te}" != "no"; then
AC_DEFINE(HAVE_OPAQUE_LSA,,OSPF Opaque LSA)
AC_DEFINE(HAVE_OSPF_TE,,OSPF TE)
fi
if test "${enable_linux24_tcp_md5}" = "yes"; then
AC_DEFINE(HAVE_TCP_MD5_LINUX24,,Old Linux 2.4 TCP MD5 Signature Patch)
fi
@ -416,16 +413,22 @@ AC_SUBST(ISIS_TOPOLOGY_INCLUDES)
AC_SUBST(ISIS_TOPOLOGY_DIR)
AC_SUBST(ISIS_TOPOLOGY_LIB)
if test "${enable_user}" = "yes" || test x"${enable_user}" = x""; then
if test x"${enable_user}" = x"no"; then
enable_user=""
else
if test x"${enable_user}" = x"yes" || test x"${enable_user}" = x""; then
enable_user="quagga"
elif test "${enable_user}" = "no"; then
enable_user="root"
fi
AC_DEFINE_UNQUOTED(QUAGGA_USER, "${enable_user}", Quagga User)
fi
if test "${enable_group}" = "yes" || test x"${enable_group}" = x""; then
if test x"${enable_group}" = x"no"; then
enable_group=""
else
if test x"${enable_group}" = x"yes" || test x"${enable_group}" = x""; then
enable_group="quagga"
elif test "${enable_group}" = "no"; then
enable_group="root"
fi
AC_DEFINE_UNQUOTED(QUAGGA_GROUP, "${enable_group}", Quagga Group)
fi
if test x"${enable_vty_group}" = x"yes" ; then
@ -438,8 +441,6 @@ fi
AC_SUBST([enable_user])
AC_SUBST([enable_group])
AC_SUBST([enable_vty_group])
AC_DEFINE_UNQUOTED(QUAGGA_USER, "${enable_user}", Quagga User)
AC_DEFINE_UNQUOTED(QUAGGA_GROUP, "${enable_group}", Quagga Group)
enable_configfile_mask=${enable_configfile_mask:-0600}
AC_DEFINE_UNQUOTED(CONFIGFILE_MASK, ${enable_configfile_mask}, Mask for config files)
@ -710,7 +711,7 @@ dnl [TODO] on Linux, and in [TODO] on Solaris.
)]
)]
)
AC_CHECK_LIB(readline, main, LIBREADLINE="$LIBREADLINE -lreadline",,
AC_CHECK_LIB(readline, main, LIBREADLINE="-lreadline $LIBREADLINE",,
"$LIBREADLINE")
if test $ac_cv_lib_readline_main = no; then
AC_MSG_ERROR([vtysh needs libreadline but was not found and usable on your system.])
@ -851,6 +852,14 @@ AC_CHECK_FUNCS([dup2 ftruncate getcwd gethostbyname getpagesize gettimeofday \
if_nametoindex if_indextoname getifaddrs \
uname fcntl getgrouplist])
AC_CHECK_HEADER([asm-generic/unistd.h],
[AC_CHECK_DECL(__NR_setns,
AC_DEFINE(HAVE_NETNS,, Have netns),,
QUAGGA_INCLUDES [#include <asm-generic/unistd.h>
])
AC_CHECK_FUNCS(setns, AC_DEFINE(HAVE_SETNS,, Have setns))]
)
dnl ------------------------------------
dnl Determine routing get and set method
dnl ------------------------------------
@ -993,11 +1002,46 @@ dnl figure out how to specify an interface in multicast sockets API
dnl ---------------------------------------------------------------
AC_CHECK_MEMBERS([struct ip_mreqn.imr_ifindex], [], [], QUAGGA_INCLUDES)
AC_CHECK_HEADERS([linux/mroute.h], [], [],
[
#if HAVE_NETINET_IN_H
#include<netinet/in.h>
#endif])
AC_CHECK_HEADERS([linux/mroute.h], [], [],[
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#define _LINUX_IN_H /* For Linux <= 2.6.25 */
#include <linux/types.h>
])
m4_define([QUAGGA_INCLUDES],
QUAGGA_INCLUDES
[#if HAVE_LINUX_MROUTE_H
# include <linux/mroute.h>
#endif
])dnl
AC_CHECK_HEADERS([netinet/ip_mroute.h], [], [],[
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#ifdef HAVE_NET_ROUTE_H
# include <net/route.h>
#endif
])
m4_define([QUAGGA_INCLUDES],
QUAGGA_INCLUDES
[#if HAVE_NETINET_IP_MROUTE_H
# include <netinet/ip_mroute.h>
#endif
])dnl
AC_MSG_CHECKING([for BSD struct ip_mreq hack])
AC_TRY_COMPILE([#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
@ -1095,6 +1139,11 @@ AC_SUBST(IPFORWARD)
AC_CHECK_FUNCS(getaddrinfo, [have_getaddrinfo=yes], [have_getaddrinfo=no])
dnl ----------------------------------------------------------------------------
dnl figure out if domainname is available in the utsname struct (GNU extension).
dnl ----------------------------------------------------------------------------
AC_CHECK_MEMBERS([struct utsname.domainname], [], [], [#include <sys/utsname.h>])
dnl ----------
dnl IPv6 check
dnl ----------
@ -1202,16 +1251,14 @@ fi
AM_CONDITIONAL(WATCHQUAGGA, test "x$WATCHQUAGGA" = "xwatchquagga")
OSPFCLIENT=""
if test "${enable_opaque_lsa}" != "no"; then
if test "${enable_ospfapi}" != "no";then
if test "${enable_ospfapi}" != "no";then
AC_DEFINE(SUPPORT_OSPF_API,,OSPFAPI)
if test "${enable_ospfclient}" != "no";then
OSPFCLIENT="ospfclient"
fi
fi
fi
AM_CONDITIONAL(OSPFCLIENT, test "x$OSPFCLIENT" = "xospfclient")
case "${enable_ripngd}" in

View File

@ -0,0 +1,2 @@
log file /var/log/quagga/quagga.log
log timestamp precision 6

View File

@ -1,3 +0,0 @@
hostname bgpd
log timestamp precision 6
log file /var/log/quagga/bgpd.log

View File

@ -1,3 +0,0 @@
hostname ospfd
log timestamp precision 6
log file /var/log/quagga/ospf6d.log

View File

@ -1,3 +0,0 @@
hostname ospfd
log timestamp precision 6
log file /var/log/quagga/ospfd.log

View File

@ -1,5 +0,0 @@
hostname pimd
password cn321
enable password cn321
log timestamp precision 6
log file /var/log/quagga/pimd.log

View File

@ -1,2 +0,0 @@
hostname zebra
log file /var/log/quagga/zebra.log

View File

@ -56,8 +56,9 @@
#include <limits.h>
#include <assert.h>
#include <ctype.h>
#include <error.h>
#ifdef linux
#include <linux/sched.h>
#endif
static int testmode = 0;
static int quietmode = 0;
@ -241,6 +242,7 @@ next_dirname(const char *s)
return cur;
}
#ifdef linux
static void
add_namespace(const char *path)
{
@ -270,6 +272,7 @@ add_namespace(const char *path)
namespace->nstype = nstype;
LIST_INSERT_HEAD(&namespace_head, namespace, list);
}
#endif
#ifdef HAVE_LXC
static void
@ -567,7 +570,9 @@ parse_options(int argc, char * const *argv)
changeroot = optarg;
break;
case 'd': /* --namespace /.../<ipcns>|<netns>|<utsns>/name */
#ifdef linux
add_namespace(optarg);
#endif
break;
case 'N': /* --nice */
nicelevel = atoi(optarg);

10
debian/changelog vendored
View File

@ -1,4 +1,12 @@
quagga (0.99.23.1-1+cl3u2) Release; urgency=medium
quagga (0.99.24+cl3u3) RELEASED; urgency=medium
* New Enabled: Merge up-to 0.99.24 code from upstream
* New Enabled: Additional CLI simplification
* New Enabled: Various Bug Fixes
-- dev-support <dev-support@cumulusnetworks.com> Thu, 04 Aug 2016 08:43:36 -0700
quagga (0.99.23.1-1+cl3u2) RELEASED; urgency=medium
* New Enabled: VRF - See Documentation for how to use
* New Enabled: Improved interface statistics

View File

@ -1,6 +1,5 @@
etc/quagga/
usr/bin/vtysh
usr/bin/test_igmpv3_join
usr/include/quagga/
usr/lib/
tools/quagga-reload.py usr/lib/quagga/

3
debian/rules vendored
View File

@ -39,6 +39,8 @@ override_dh_auto_configure:
--sysconfdir=/etc/quagga \
$(USE_SNMP) \
--enable-ospfapi=yes \
--enable-vtysh=yes \
--enable-isisd=yes \
--enable-multipath=256 \
--enable-user=quagga \
--enable-group=quagga \
@ -51,6 +53,7 @@ override_dh_auto_configure:
--enable-systemd=yes \
--enable-poll=yes \
--enable-cumulus=yes \
--enable-pimd=no \
--enable-dependency-tracking; \
fi

1
doc/.gitignore vendored
View File

@ -32,3 +32,4 @@ stamp-vti
.arch-ids
*~
*.loT
refix

View File

@ -6,7 +6,7 @@ software
.SH SYNOPSIS
.B bgpd
[
.B \-dhrv
.B \-dhrSv
] [
.B \-f
.I config-file
@ -74,6 +74,9 @@ Specify the user to run as. Default is \fIquagga\fR.
\fB\-r\fR, \fB\-\-retain\fR
When the program terminates, retain routes added by \fBbgpd\fR.
.TP
\fB\-S\fR, \fB\-\-skip_runas\fR
Skip setting the process effective user and group.
.TP
\fB\-v\fR, \fB\-\-version\fR
Print the version and exit.
.SH FILES

View File

@ -83,8 +83,17 @@ OSPF-API is enabled if --enable-opaque-lsa is set.
@item --disable-ospfclient
Disable building of the example OSPF-API client.
@item --disable-ospf-te
Disable support for OSPF Traffic Engineering Extension (internet-draft) this
Disable support for OSPF Traffic Engineering Extension (RFC3630) this
requires support for Opaque LSAs.
@item --disable-ospf-ri
Disable support for OSPF Router Information (RFC4970 & RFC5088) this
requires support for Opaque LSAs and Traffic Engineering.
@item --enable-isisd
Build isisd.
@item --enable-isis-topology
Enable IS-IS topology generator.
@item --enable-isis-te
Enable Traffic Engineering Extension for ISIS (RFC5305)
@item --enable-multipath=@var{ARG}
Enable support for Equal Cost Multipath. @var{ARG} is the maximum number
of ECMP paths to allow, set to 0 to allow unlimited number of paths.

432
doc/isisd.texi Normal file
View File

@ -0,0 +1,432 @@
@cindex ISIS
@node ISIS
@chapter ISIS
@acronym{ISIS,Intermediate System to Intermediate System} is a routing protocol
which is described in @cite{ISO10589, RFC1195, RFC5308}. ISIS is an
@acronym{IGP,Interior Gateway Protocol}. Compared with @acronym{RIP},
@acronym{ISIS} can provide scalable network support and faster
convergence times like @acronym{OSPF}. ISIS is widely used in large networks such as
@acronym{ISP,Internet Service Provider} and carrier backbone networks.
@menu
* Configuring isisd::
* ISIS router::
* ISIS Timer::
* ISIS region::
* ISIS interface::
* Showing ISIS information::
* ISIS Traffic Engineering::
* Debugging ISIS::
* ISIS Configuration Examples::
@end menu
@node Configuring isisd
@section Configuring isisd
There are no @command{isisd} specific options. Common options can be
specified (@pxref{Common Invocation Options}) to @command{isisd}.
@command{isisd} needs to acquire interface information from
@command{zebra} in order to function. Therefore @command{zebra} must be
running before invoking @command{isisd}. Also, if @command{zebra} is
restarted then @command{isisd} must be too.
Like other daemons, @command{isisd} configuration is done in @acronym{ISIS}
specific configuration file @file{isisd.conf}.
@node ISIS router
@section ISIS router
To start ISIS process you have to specify the ISIS router. As of this
writing, @command{isisd} does not support multiple ISIS processes.
@deffn Command {router isis WORD} {}
@deffnx Command {no router isis WORD} {}
@anchor{router isis WORD}Enable or disable the ISIS process by specifying the ISIS domain with 'WORD'.
@command{isisd} does not yet support multiple ISIS processes but you must specify
the name of ISIS process. The ISIS process name 'WORD' is then used for interface
(see command @ref{ip router isis WORD}).
@end deffn
@deffn {ISIS Command} {net XX.XXXX. ... .XXX.XX} {}
@deffnx {ISIS Command} {no net XX.XXXX. ... .XXX.XX} {}
Set/Unset network entity title (NET) provided in ISO format.
@end deffn
@deffn {ISIS Command} {hostname dynamic} {}
@deffnx {ISIS Command} {no hostname dynamic} {}
Enable support for dynamic hostname.
@end deffn
@deffn {ISIS Command} {area-password [clear | md5] <password>} {}
@deffnx {ISIS Command} {domain-password [clear | md5] <password>} {}
@deffnx {ISIS Command} {no area-password} {}
@deffnx {ISIS Command} {no domain-password} {}
Configure the authentication password for an area, respectively a domain,
as clear text or md5 one.
@end deffn
@deffn {ISIS Command} {log-adjacency-changes} {}
@deffnx {ISIS Command} {no log-adjacency-changes} {}
Log changes in adjacency state.
@end deffn
@deffn {ISIS Command} {metric-style [narrow | transition | wide]} {}
@deffnx {ISIS Command} {no metric-style} {}
@anchor{metric-style}Set old-style (ISO 10589) or new-style packet formats:
- narrow Use old style of TLVs with narrow metric
- transition Send and accept both styles of TLVs during transition
- wide Use new style of TLVs to carry wider metric
@end deffn
@deffn {ISIS Command} {set-overload-bit} {}
@deffnx {ISIS Command} {no set-overload-bit} {}
Set overload bit to avoid any transit traffic.
@end deffn
@node ISIS Timer
@section ISIS Timer
@deffn {ISIS Command} {lsp-gen-interval <1-120>} {}
@deffnx {ISIS Command} {lsp-gen-interval [level-1 | level-2] <1-120>} {}
@deffnx {ISIS Command} {no lsp-gen-interval} {}
@deffnx {ISIS Command} {no lsp-gen-interval [level-1 | level-2]} {}
Set minimum interval in seconds between regenerating same LSP,
globally, for an area (level-1) or a domain (level-2).
@end deffn
@deffn {ISIS Command} {lsp-refresh-interval <1-65235>} {}
@deffnx {ISIS Command} {lsp-refresh-interval [level-1 | level-2] <1-65235>} {}
@deffnx {ISIS Command} {no lsp-refresh-interval} {}
@deffnx {ISIS Command} {no lsp-refresh-interval [level-1 | level-2]} {}
Set LSP refresh interval in seconds, globally, for an area (level-1) or a domain (level-2).
@end deffn
@deffn {ISIS Command} {lsp-refresh-interval <1-65235>} {}
@deffnx {ISIS Command} {lsp-refresh-interval [level-1 | level-2] <1-65235>} {}
@deffnx {ISIS Command} {no lsp-refresh-interval} {}
@deffnx {ISIS Command} {no lsp-refresh-interval [level-1 | level-2]} {}
Set LSP refresh interval in seconds, globally, for an area (level-1) or a domain (level-2).
@end deffn
@deffn {ISIS Command} {max-lsp-lifetime <360-65535>} {}
@deffnx {ISIS Command} {max-lsp-lifetime [level-1 | level-2] <360-65535>} {}
@deffnx {ISIS Command} {no max-lsp-lifetime} {}
@deffnx {ISIS Command} {no max-lsp-lifetime [level-1 | level-2]} {}
Set LSP maximum LSP lifetime in seconds, globally, for an area (level-1) or a domain (level-2).
@end deffn
@deffn {ISIS Command} {spf-interval <1-120>} {}
@deffnx {ISIS Command} {spf-interval [level-1 | level-2] <1-120>} {}
@deffnx {ISIS Command} {no spf-interval} {}
@deffnx {ISIS Command} {no spf-interval [level-1 | level-2]} {}
Set minimum interval between consecutive SPF calculations in seconds.
@end deffn
@node ISIS region
@section ISIS region
@deffn {ISIS Command} {is-type [level-1 | level-1-2 | level-2-only]} {}
@deffnx {ISIS Command} {no is-type} {}
Define the ISIS router behavior:
- level-1 Act as a station router only
- level-1-2 Act as both a station router and an area router
- level-2-only Act as an area router only
@end deffn
@node ISIS interface
@section ISIS interface
@deffn {Interface Command} {ip router isis WORD} {}
@deffnx {Interface Command} {no ip router isis WORD} {}
@anchor{ip router isis WORD}Activate ISIS adjacency on this interface. Note that the name
of ISIS instance must be the same as the one used to configure the ISIS process
(see command @ref{router isis WORD}).
@end deffn
@deffn {Interface Command} {isis circuit-type [level-1 | level-1-2 | level-2]} {}
@deffnx {Interface Command} {no isis circuit-type} {}
Configure circuit type for interface:
- level-1 Level-1 only adjacencies are formed
- level-1-2 Level-1-2 adjacencies are formed
- level-2-only Level-2 only adjacencies are formed
@end deffn
@deffn {Interface Command} {isis csnp-interval <1-600>} {}
@deffnx {Interface Command} {isis csnp-interval <1-600> [level-1 | level-2]} {}
@deffnx {Interface Command} {no isis csnp-interval} {}
@deffnx {Interface Command} {no isis csnp-interval [level-1 | level-2]} {}
Set CSNP interval in seconds globally, for an area (level-1) or a domain (level-2).
@end deffn
@deffn {Interface Command} {isis hello padding} {}
Add padding to IS-IS hello packets.
@end deffn
@deffn {Interface Command} {isis hello-interval <1-600>} {}
@deffnx {Interface Command} {isis hello-interval <1-600> [level-1 | level-2]} {}
@deffnx {Interface Command} {no isis hello-interval} {}
@deffnx {Interface Command} {no isis hello-interval [level-1 | level-2]} {}
Set Hello interval in seconds globally, for an area (level-1) or a domain (level-2).
@end deffn
@deffn {Interface Command} {isis hello-multiplier <2-100>} {}
@deffnx {Interface Command} {isis hello-multiplier <2-100> [level-1 | level-2]} {}
@deffnx {Interface Command} {no isis hello-multiplier} {}
@deffnx {Interface Command} {no isis hello-multiplier [level-1 | level-2]} {}
Set multiplier for Hello holding time globally, for an area (level-1) or a domain (level-2).
@end deffn
@deffn {Interface Command} {isis metric [<0-255> | <0-16777215>]} {}
@deffnx {Interface Command} {isis metric [<0-255> | <0-16777215>] [level-1 | level-2]} {}
@deffnx {Interface Command} {no isis metric} {}
@deffnx {Interface Command} {no isis metric [level-1 | level-2]} {}
Set default metric value globally, for an area (level-1) or a domain (level-2).
Max value depend if metric support narrow or wide value (see command @ref{metric-style}).
@end deffn
@deffn {Interface Command} {isis network point-to-point} {}
@deffnx {Interface Command} {no isis network point-to-point} {}
Set network type to 'Point-to-Point' (broadcast by default).
@end deffn
@deffn {Interface Command} {isis passive} {}
@deffnx {Interface Command} {no isis passive} {}
Configure the passive mode for this interface.
@end deffn
@deffn {Interface Command} {isis password [clear | md5] <password>} {}
@deffnx {Interface Command} {no isis password} {}
Configure the authentication password (clear or encoded text) for the interface.
@end deffn
@deffn {Interface Command} {isis priority <0-127>} {}
@deffnx {Interface Command} {isis priority <0-127> [level-1 | level-2]} {}
@deffnx {Interface Command} {no isis priority} {}
@deffnx {Interface Command} {no isis priority [level-1 | level-2]} {}
Set priority for Designated Router election, globally, for the area (level-1)
or the domain (level-2).
@end deffn
@deffn {Interface Command} {isis psnp-interval <1-120>} {}
@deffnx {Interface Command} {isis psnp-interval <1-120> [level-1 | level-2]} {}
@deffnx {Interface Command} {no isis psnp-interval} {}
@deffnx {Interface Command} {no isis psnp-interval [level-1 | level-2]} {}
Set PSNP interval in seconds globally, for an area (level-1) or a domain (level-2).
@end deffn
@node Showing ISIS information
@section Showing ISIS information
@deffn {Command} {show isis summary} {}
Show summary information about ISIS.
@end deffn
@deffn {Command} {show isis hostname} {}
Show information about ISIS node.
@end deffn
@deffn {Command} {show isis interface} {}
@deffnx {Command} {show isis interface detail} {}
@deffnx {Command} {show isis interface <interface name>} {}
Show state and configuration of ISIS specified interface, or all
interfaces if no interface is given with or without details.
@end deffn
@deffn {Command} {show isis neighbor} {}
@deffnx {Command} {show isis neighbor <System Id>} {}
@deffnx {Command} {show isis neighbor detail} {}
Show state and information of ISIS specified neighbor, or all
neighbors if no system id is given with or without details.
@end deffn
@deffn {Command} {show isis database} {}
@deffnx {Command} {show isis database [detail]} {}
@deffnx {Command} {show isis database <LSP id> [detail]} {}
@deffnx {Command} {show isis database detail <LSP id>} {}
Show the ISIS database globally, for a specific LSP id without or with details.
@end deffn
@deffn {Command} {show isis topology} {}
@deffnx {Command} {show isis topology [level-1|level-2]} {}
Show topology IS-IS paths to Intermediate Systems, globally,
in area (level-1) or domain (level-2).
@end deffn
@deffn {Command} {show ip route isis} {}
Show the ISIS routing table, as determined by the most recent SPF calculation.
@end deffn
@node ISIS Traffic Engineering
@section Traffic Engineering
@deffn {ISIS Command} {mpls-te on} {}
@deffnx {ISIS Command} {no mpls-te} {}
Enable Traffic Engineering LSP flooding.
@end deffn
@deffn {ISIS Command} {mpls-te router-address <A.B.C.D>} {}
@deffnx {ISIS Command} {no mpls-te router-address} {}
Configure stable IP address for MPLS-TE.
@end deffn
@deffn {Command} {show isis mpls-te interface} {}
@deffnx {Command} {show isis mpls-te interface @var{interface}} {}
Show MPLS Traffic Engineering parameters for all or specified interface.
@end deffn
@deffn {Command} {show isis mpls-te router} {}
Show Traffic Engineering router parameters.
@end deffn
@node Debugging ISIS
@section Debugging ISIS
@deffn {Command} {debug isis adj-packets} {}
@deffnx {Command} {no debug isis adj-packets} {}
IS-IS Adjacency related packets.
@end deffn
@deffn {Command} {debug isis checksum-errors} {}
@deffnx {Command} {no debug isis checksum-errors} {}
IS-IS LSP checksum errors.
@end deffn
@deffn {Command} {debug isis events} {}
@deffnx {Command} {no debug isis events} {}
IS-IS Events.
@end deffn
@deffn {Command} {debug isis local-updates} {}
@deffnx {Command} {no debug isis local-updates} {}
IS-IS local update packets.
@end deffn
@deffn {Command} {debug isis packet-dump} {}
@deffnx {Command} {no debug isis packet-dump} {}
IS-IS packet dump.
@end deffn
@deffn {Command} {debug isis protocol-errors} {}
@deffnx {Command} {no debug isis protocol-errors} {}
IS-IS LSP protocol errors.
@end deffn
@deffn {Command} {debug isis route-events} {}
@deffnx {Command} {no debug isis route-events} {}
IS-IS Route related events.
@end deffn
@deffn {Command} {debug isis snp-packets} {}
@deffnx {Command} {no debug isis snp-packets} {}
IS-IS CSNP/PSNP packets.
@end deffn
@deffn {Command} {debug isis spf-events} {}
@deffnx {Command} {debug isis spf-statistics} {}
@deffnx {Command} {debug isis spf-triggers} {}
@deffnx {Command} {no debug isis spf-events} {}
@deffnx {Command} {no debug isis spf-statistics} {}
@deffnx {Command} {no debug isis spf-triggers} {}
IS-IS Shortest Path First Events, Timing and Statistic Data
and triggering events.
@end deffn
@deffn {Command} {debug isis update-packets} {}
@deffnx {Command} {no debug isis update-packets} {}
Update related packets.
@end deffn
@deffn {Command} {show debugging isis} {}
Print which ISIS debug level is activate.
@end deffn
@node ISIS Configuration Examples
@section ISIS Configuration Examples
A simple example, with MD5 authentication enabled:
@example
@group
!
interface eth0
ip router isis FOO
isis network point-to-point
isis circuit-type level-2-only
!
router isis FOO
net 47.0023.0000.0000.0000.0000.0000.0000.1900.0004.00
metric-style wide
is-type level-2-only
@end group
@end example
A Traffic Engineering configuration, with Inter-ASv2 support.
- First, the 'zebra.conf' part:
@example
@group
hostname HOSTNAME
password PASSWORD
log file /var/log/zebra.log
!
interface eth0
ip address 10.2.2.2/24
mpls-te on
mpls-te link metric 10
mpls-te link max-bw 1.25e+06
mpls-te link max-rsv-bw 1.25e+06
mpls-te link unrsv-bw 0 1.25e+06
mpls-te link unrsv-bw 1 1.25e+06
mpls-te link unrsv-bw 2 1.25e+06
mpls-te link unrsv-bw 3 1.25e+06
mpls-te link unrsv-bw 4 1.25e+06
mpls-te link unrsv-bw 5 1.25e+06
mpls-te link unrsv-bw 6 1.25e+06
mpls-te link unrsv-bw 7 1.25e+06
mpls-te link rsc-clsclr 0xab
!
interface eth1
ip address 10.1.1.1/24
mpls-te on
mpls-te link metric 10
mpls-te link max-bw 1.25e+06
mpls-te link max-rsv-bw 1.25e+06
mpls-te link unrsv-bw 0 1.25e+06
mpls-te link unrsv-bw 1 1.25e+06
mpls-te link unrsv-bw 2 1.25e+06
mpls-te link unrsv-bw 3 1.25e+06
mpls-te link unrsv-bw 4 1.25e+06
mpls-te link unrsv-bw 5 1.25e+06
mpls-te link unrsv-bw 6 1.25e+06
mpls-te link unrsv-bw 7 1.25e+06
mpls-te link rsc-clsclr 0xab
mpls-te neighbor 10.1.1.2 as 65000
@end group
@end example
- Then the 'isisd.conf' itself:
@example
@group
hostname HOSTNAME
password PASSWORD
log file /var/log/isisd.log
!
!
interface eth0
ip router isis FOO
!
interface eth1
ip router isis FOO
!
!
router isis FOO
isis net 47.0023.0000.0000.0000.0000.0000.0000.1900.0004.00
mpls-te on
mpls-te router-address 10.1.1.1
!
line vty
@end group
@end example

View File

@ -42,6 +42,14 @@ When program terminates, retain routes added by zebra.
@node Interface Commands
@section Interface Commands
@menu
* Standard Commands::
* Link Parameters Commands::
@end menu
@node Standard Commands
@subsection Standard Commands
@deffn Command {interface @var{ifname}} {}
@end deffn
@ -86,6 +94,59 @@ only Linux and Solaris, and only where network interface drivers support reporti
link-state via the IFF_RUNNING flag.
@end deffn
@node Link Parameters Commands
@subsection Link Parameters Commands
@deffn {Interface Command} {link-params} {}
@deffnx {Interface Command} {no link-param} {}
Enter into the link parameters sub node. At least 'enable' must be set to activate the link parameters,
and consequently Traffic Engineering on this interface. MPLS-TE must be enable at the OSPF (@ref{OSPF Traffic Engineering})
or ISIS (@ref{ISIS Traffic Engineering}) router level in complement to this.
Disable link parameters for this interface.
@end deffn
Under link parameter statement, the following commands set the different TE values:
@deffn link-params {enable}
Enable link parameters for this interface.
@end deffn
@deffn link-params {metric <0-4294967295>} {}
@deffnx link-params {max-bw @var{bandwidth}} {}
@deffnx link-params {max-rsv-bw @var{bandwidth}} {}
@deffnx link-params {unrsv-bw <0-7> @var{bandwidth}} {}
@deffnx link-params {admin-grp @var{bandwidth}} {}
These commands specifies the Traffic Engineering parameters of the interface in conformity to RFC3630 (OSPF)
or RFC5305 (ISIS).
There are respectively the TE Metric (different from the OSPF or ISIS metric), Maximum Bandwidth (interface speed
by default), Maximum Reservable Bandwidth, Unreserved Bandwidth for each 0-7 priority and Admin Group (ISIS) or
Resource Class/Color (OSPF).
Note that @var{bandwidth} are specified in IEEE floating point format and express in Bytes/second.
@end deffn
@deffn link-param {delay <0-16777215> [min <0-16777215> | max <0-16777215>]} {}
@deffnx link-param {delay-variation <0-16777215>} {}
@deffnx link-param {packet-loss @var{percentage}} {}
@deffnx link-param {res-bw @var{bandwidth}} {}
@deffnx link-param {ava-bw @var{bandwidth}} {}
@deffnx link-param {use-bw @var{bandwidth}} {}
These command specifies additionnal Traffic Engineering parameters of the interface in conformity to
draft-ietf-ospf-te-metrics-extension-05.txt and draft-ietf-isis-te-metrics-extension-03.txt. There are
respectively the delay, jitter, loss, available bandwidth, reservable bandwidth and utilized bandwidth.
Note that @var{bandwidth} are specified in IEEE floating point format and express in Bytes/second.
Delays and delay variation are express in micro-second (µs). Loss is specified in @var{percentage} ranging
from 0 to 50.331642% by step of 0.000003.
@end deffn
@deffn link-param {neighbor <A.B.C.D> as <0-65535>} {}
@deffnx link-param {no neighbor} {}
Specifies the remote ASBR IP address and Autonomous System (AS) number for InterASv2 link in OSPF (RFC5392).
Note that this option is not yet supported for ISIS (RFC5316).
@end deffn
@node Static Route Commands
@section Static Route Commands

View File

@ -1,3 +1,16 @@
----- * ----- * ----- * ----- * ----- * ----- * ----- * ----- * ----- * -----
Changes 2013.07.01
1. Feature enhancements
1.1 Update ospf_te.[c,h] in conformance to RFC3630 and clean the code.
Add new directive to enable MPLS-TE per interface instead of globally
1.2 Add support for RFC4970 "Router Information" and RFC5088 "PCE
Capabilities announcement".
1.3 Incorporate the mpls documentation into the main stream doc.
----- * ----- * ----- * ----- * ----- * ----- * ----- * ----- * ----- * -----
Changes 2001.12.03

View File

@ -17,6 +17,7 @@ debug ospf packet all detail
interface fxp0
ip ospf hello-interval 60
ip ospf dead-interval 240
mpls-te on
mpls-te link metric 999
mpls-te link max-bw 1.25e+06
mpls-te link max-rsv-bw 1.25e+06

View File

@ -1,3 +1,4 @@
@cindex OSPFv2
@node OSPFv2
@chapter OSPFv2
@ -18,6 +19,9 @@ networks.
* OSPF interface::
* Redistribute routes to OSPF::
* Showing OSPF information::
* Opaque LSA::
* OSPF Traffic Engineering::
* Router Information::
* Debugging OSPF::
* OSPF Configuration Examples::
@end menu
@ -616,35 +620,137 @@ interfaces if no interface is given.
Show the OSPF routing table, as determined by the most recent SPF calculation.
@end deffn
@node Opaque LSA
@section Opaque LSA
@deffn {OSPF Command} {ospf opaque-lsa} {}
@deffnx {OSPF Command} {capability opaque} {}
@deffnx {OSPF Command} {no ospf opaque-lsa} {}
@deffnx {OSPF Command} {no capability opaque} {}
@command{ospfd} support Opaque LSA (RFC2370) as fondment for MPLS Traffic Engineering LSA. Prior to used MPLS TE, opaque-lsa must be enable in the configuration file. Alternate command could be "mpls-te on" (@ref{OSPF Traffic Engineering}).
@end deffn
@deffn {Command} {show ip ospf database (opaque-link|opaque-area|opaque-external)} {}
@deffnx {Command} {show ip ospf database (opaque-link|opaque-area|opaque-external) @var{link-state-id}} {}
@deffnx {Command} {show ip ospf database (opaque-link|opaque-area|opaque-external) @var{link-state-id} adv-router @var{adv-router}} {}
@deffnx {Command} {show ip ospf database (opaque-link|opaque-area|opaque-external) adv-router @var{adv-router}} {}
@deffnx {Command} {show ip ospf database (opaque-link|opaque-area|opaque-external) @var{link-state-id} self-originate} {}
@deffnx {Command} {show ip ospf database (opaque-link|opaque-area|opaque-external) self-originate} {}
Show Opaque LSA from the database.
@end deffn
@node OSPF Traffic Engineering
@section Traffic Engineering
@deffn {OSPF Command} {mpls-te on} {}
@deffnx {OSPF Command} {no mpls-te} {}
Enable Traffic Engineering LSA flooding.
@end deffn
@deffn {OSPF Command} {mpls-te router-address <A.B.C.D>} {}
@deffnx {OSPF Command} {no mpls-te} {}
Configure stable IP address for MPLS-TE. This IP address is then advertise in Opaque LSA Type-10 TLV=1 (TE)
option 1 (Router-Address).
@end deffn
@deffn {OSPF Command} {mpls-te inter-as area <area-id>|as} {}
@deffnx {OSPF Command} {no mpls-te inter-as} {}
Enable RFC5392 suuport - Inter-AS TE v2 - to flood Traffic Engineering parameters of Inter-AS link.
2 modes are supported: AREA and AS; LSA are flood in AREA <area-id> with Opaque Type-10,
respectively in AS with Opaque Type-11. In all case, Opaque-LSA TLV=6.
@end deffn
@deffn {Command} {show ip ospf mpls-te interface} {}
@deffnx {Command} {show ip ospf mpls-te interface @var{interface}} {}
Show MPLS Traffic Engineering parameters for all or specified interface.
@end deffn
@deffn {Command} {show ip ospf mpls-te router} {}
Show Traffic Engineering router parameters.
@end deffn
@node Router Information
@section Router Information
@deffn {OSPF Command} {router-info [as | area <A.B.C.D>]} {}
@deffnx {OSPF Command} {no router-info} {}
Enable Router Information (RFC4970) LSA advertisement with AS scope (default) or Area scope flooding
when area is specified.
@end deffn
@deffn {OSPF Command} {pce address <A.B.C.D>} {}
@deffnx {OSPF Command} {no pce address} {}
@deffnx {OSPF Command} {pce domain as <0-65535>} {}
@deffnx {OSPF Command} {no pce domain as <0-65535>} {}
@deffnx {OSPF Command} {pce neighbor as <0-65535>} {}
@deffnx {OSPF Command} {no pce neighbor as <0-65535>} {}
@deffnx {OSPF Command} {pce flag BITPATTERN} {}
@deffnx {OSPF Command} {no pce flag} {}
@deffnx {OSPF Command} {pce scope BITPATTERN} {}
@deffnx {OSPF Command} {no pce scope} {}
The commands are conform to RFC 5088 and allow OSPF router announce Path Compuatation Elemenent (PCE) capabilities
through the Router Information (RI) LSA. Router Information must be enable prior to this. The command set/unset
respectively the PCE IP adress, Autonomous System (AS) numbers of controlled domains, neighbor ASs, flag and scope.
For flag and scope, please refer to RFC5088 for the BITPATTERN recognition. Multiple 'pce neighbor' command could
be specified in order to specify all PCE neighbours.
@end deffn
@deffn {Command} {show ip ospf router-info} {}
Show Router Capabilities flag.
@end deffn
@deffn {Command} {show ip ospf router-info pce} {}
Show Router Capabilities PCE parameters.
@end deffn
@node Debugging OSPF
@section Debugging OSPF
@deffn {Command} {debug ospf packet (hello|dd|ls-request|ls-update|ls-ack|all) (send|recv) [detail]} {}
@deffnx {Command} {no debug ospf packet (hello|dd|ls-request|ls-update|ls-ack|all) (send|recv) [detail]} {}
Dump Packet for debugging
@end deffn
@deffn {Command} {debug ospf ism} {}
@deffnx {Command} {debug ospf ism (status|events|timers)} {}
@deffnx {Command} {no debug ospf ism} {}
@deffnx {Command} {no debug ospf ism (status|events|timers)} {}
Show debug information of Interface State Machine
@end deffn
@deffn {Command} {debug ospf nsm} {}
@deffnx {Command} {debug ospf nsm (status|events|timers)} {}
@deffnx {Command} {no debug ospf nsm} {}
@deffnx {Command} {no debug ospf nsm (status|events|timers)} {}
Show debug information of Network State Machine
@end deffn
@deffn {Command} {debug ospf event} {}
@deffnx {Command} {no debug ospf event} {}
Show debug information of OSPF event
@end deffn
@deffn {Command} {debug ospf nssa} {}
@deffnx {Command} {no debug ospf nssa} {}
Show debug information about Not So Stub Area
@end deffn
@deffn {Command} {debug ospf lsa} {}
@deffnx {Command} {debug ospf lsa (generate|flooding|refresh)} {}
@deffnx {Command} {no debug ospf lsa} {}
@deffnx {Command} {no debug ospf lsa (generate|flooding|refresh)} {}
Show debug detail of Link State messages
@end deffn
@deffn {Command} {debug ospf te} {}
@deffnx {Command} {no debug ospf te} {}
Show debug information about Traffic Engineering LSA
@end deffn
@deffn {Command} {debug ospf zebra} {}
@deffnx {Command} {debug ospf zebra (interface|redistribute)} {}
@deffnx {Command} {no debug ospf zebra} {}
@deffnx {Command} {no debug ospf zebra (interface|redistribute)} {}
Show debug information of ZEBRA API
@end deffn
@deffn {Command} {show debugging ospf} {}
@ -702,3 +808,100 @@ router ospf
!
@end group
@end example
A Traffic Engineering configuration, with Inter-ASv2 support.
- First, the 'zebra.conf' part:
@example
@group
hostname HOSTNAME
password PASSWORD
log file /var/log/zebra.log
!
interface eth0
ip address 198.168.1.1/24
mpls-te on
mpls-te link metric 10
mpls-te link max-bw 1.25e+06
mpls-te link max-rsv-bw 1.25e+06
mpls-te link unrsv-bw 0 1.25e+06
mpls-te link unrsv-bw 1 1.25e+06
mpls-te link unrsv-bw 2 1.25e+06
mpls-te link unrsv-bw 3 1.25e+06
mpls-te link unrsv-bw 4 1.25e+06
mpls-te link unrsv-bw 5 1.25e+06
mpls-te link unrsv-bw 6 1.25e+06
mpls-te link unrsv-bw 7 1.25e+06
mpls-te link rsc-clsclr 0xab
!
interface eth1
ip address 192.168.2.1/24
mpls-te on
mpls-te link metric 10
mpls-te link max-bw 1.25e+06
mpls-te link max-rsv-bw 1.25e+06
mpls-te link unrsv-bw 0 1.25e+06
mpls-te link unrsv-bw 1 1.25e+06
mpls-te link unrsv-bw 2 1.25e+06
mpls-te link unrsv-bw 3 1.25e+06
mpls-te link unrsv-bw 4 1.25e+06
mpls-te link unrsv-bw 5 1.25e+06
mpls-te link unrsv-bw 6 1.25e+06
mpls-te link unrsv-bw 7 1.25e+06
mpls-te link rsc-clsclr 0xab
mpls-te neighbor 192.168.2.2 as 65000
@end group
@end example
- Then the 'ospfd.conf' itself:
@example
@group
hostname HOSTNAME
password PASSWORD
log file /var/log/ospfd.log
!
!
interface eth0
ip ospf hello-interval 60
ip ospf dead-interval 240
!
interface eth1
ip ospf hello-interval 60
ip ospf dead-interval 240
!
!
router ospf
ospf router-id 192.168.1.1
network 192.168.0.0/16 area 1
ospf opaque-lsa
mpls-te
mpls-te router-address 192.168.1.1
mpls-te inter-as area 1
!
line vty
@end group
@end example
A router information example with PCE advsertisement:
@example
@group
!
router ospf
ospf router-id 192.168.1.1
network 192.168.0.0/16 area 1
capability opaque
mpls-te
mpls-te router-address 192.168.1.1
router-info area 0.0.0.1
pce address 192.168.1.1
pce flag 0x80
pce domain as 65400
pce neighbor as 65500
pce neighbor as 65200
pce scope 0x80
!
@end group
@end example

View File

@ -85,6 +85,7 @@ for @value{PACKAGE_STRING}. @uref{http://www.quagga.net,,Quagga} is a fork of
* RIPng::
* OSPFv2::
* OSPFv3::
* ISIS::
* BGP::
* Configuring Quagga as a Route Server::
* VTY shell::
@ -109,6 +110,7 @@ for @value{PACKAGE_STRING}. @uref{http://www.quagga.net,,Quagga} is a fork of
@include ripngd.texi
@include ospfd.texi
@include ospf6d.texi
@include isisd.texi
@include bgpd.texi
@include routeserver.texi
@include vtysh.texi

View File

@ -2,3 +2,4 @@ Sampo Saaristo <sambo@cs.tut.fi>
Ofer Wald <ofersf@islands.co.il>
Hannes Gredler <hannes@gredler.at>
Subbaiah Venkata <svenkata@google.com>
Olivier Dugeon <olivier.dugeon@orange.com>

View File

@ -16,7 +16,8 @@ libisis_a_SOURCES = \
isis_adjacency.c isis_lsp.c dict.c isis_circuit.c isis_pdu.c \
isis_tlv.c isisd.c isis_misc.c isis_zebra.c isis_dr.c \
isis_flags.c isis_dynhn.c iso_checksum.c isis_csm.c isis_events.c \
isis_spf.c isis_redist.c isis_route.c isis_routemap.c
isis_spf.c isis_redist.c isis_route.c isis_routemap.c isis_te.c \
isis_vty.c
noinst_HEADERS = \
@ -24,7 +25,7 @@ noinst_HEADERS = \
isis_lsp.h dict.h isis_circuit.h isis_misc.h isis_network.h \
isis_zebra.h isis_dr.h isis_flags.h isis_dynhn.h isis_common.h \
iso_checksum.h isis_csm.h isis_events.h isis_spf.h isis_redist.h \
isis_route.h isis_routemap.h \
isis_route.h isis_routemap.h isis_te.h \
include-netbsd/clnp.h include-netbsd/esis.h include-netbsd/iso.h
isisd_SOURCES = \

File diff suppressed because it is too large Load Diff

View File

@ -24,6 +24,10 @@
#define ISIS_CIRCUIT_H
#include "vty.h"
#include "if.h"
#include "isis_constants.h"
#include "isis_common.h"
#define CIRCUIT_MAX 255
@ -108,13 +112,14 @@ struct isis_circuit
*/
struct isis_passwd passwd; /* Circuit rx/tx password */
int is_type; /* circuit is type == level of circuit
* diffrenciated from circuit type (media) */
* differentiated from circuit type (media) */
u_int32_t hello_interval[2]; /* l1HelloInterval in msecs */
u_int16_t hello_multiplier[2]; /* l1HelloMultiplier */
u_int16_t csnp_interval[2]; /* level-1 csnp-interval in seconds */
u_int16_t psnp_interval[2]; /* level-1 psnp-interval in seconds */
struct metric metrics[2]; /* l1XxxMetric */
u_int8_t metric[2];
u_int32_t te_metric[2];
struct mpls_te_circuit *mtc; /* Support for MPLS-TE parameters - see isis_te.[c,h] */
int ip_router; /* Route IP ? */
int is_passive; /* Is Passive ? */
struct list *ip_addrs; /* our IP addresses */
@ -167,4 +172,16 @@ void isis_circuit_print_vty (struct isis_circuit *circuit, struct vty *vty,
size_t isis_circuit_pdu_size(struct isis_circuit *circuit);
void isis_circuit_stream(struct isis_circuit *circuit, struct stream **stream);
struct isis_circuit *isis_circuit_create (struct isis_area *area, struct interface *ifp);
void isis_circuit_af_set (struct isis_circuit *circuit, bool ip_router, bool ipv6_router);
int isis_circuit_passive_set (struct isis_circuit *circuit, bool passive);
void isis_circuit_is_type_set (struct isis_circuit *circuit, int is_type);
int isis_circuit_circ_type_set (struct isis_circuit *circuit, int circ_type);
int isis_circuit_metric_set (struct isis_circuit *circuit, int level, int metric);
int isis_circuit_passwd_unset (struct isis_circuit *circuit);
int isis_circuit_passwd_cleartext_set (struct isis_circuit *circuit, const char *passwd);
int isis_circuit_passwd_hmac_md5_set (struct isis_circuit *circuit, const char *passwd);
#endif /* _ZEBRA_ISIS_CIRCUIT_H */

View File

@ -77,119 +77,6 @@ isis_event_circuit_state_change (struct isis_circuit *circuit,
return;
}
static void
area_resign_level (struct isis_area *area, int level)
{
if (area->lspdb[level - 1])
{
lsp_db_destroy (area->lspdb[level - 1]);
area->lspdb[level - 1] = NULL;
}
if (area->spftree[level - 1])
{
isis_spftree_del (area->spftree[level - 1]);
area->spftree[level - 1] = NULL;
}
#ifdef HAVE_IPV6
if (area->spftree6[level - 1])
{
isis_spftree_del (area->spftree6[level - 1]);
area->spftree6[level - 1] = NULL;
}
#endif
if (area->route_table[level - 1])
{
route_table_finish (area->route_table[level - 1]);
area->route_table[level - 1] = NULL;
}
#ifdef HAVE_IPV6
if (area->route_table6[level - 1])
{
route_table_finish (area->route_table6[level - 1]);
area->route_table6[level - 1] = NULL;
}
#endif /* HAVE_IPV6 */
sched_debug("ISIS (%s): Resigned from L%d - canceling LSP regeneration timer.",
area->area_tag, level);
THREAD_TIMER_OFF (area->t_lsp_refresh[level - 1]);
area->lsp_regenerate_pending[level - 1] = 0;
}
void
isis_event_system_type_change (struct isis_area *area, int newtype)
{
struct listnode *node;
struct isis_circuit *circuit;
if (isis->debugs & DEBUG_EVENTS)
zlog_debug ("ISIS-Evt (%s) system type change %s -> %s", area->area_tag,
circuit_t2string (area->is_type), circuit_t2string (newtype));
if (area->is_type == newtype)
return; /* No change */
switch (area->is_type)
{
case IS_LEVEL_1:
if (newtype == IS_LEVEL_2)
area_resign_level (area, IS_LEVEL_1);
if (area->lspdb[1] == NULL)
area->lspdb[1] = lsp_db_init ();
if (area->route_table[1] == NULL)
area->route_table[1] = route_table_init ();
#ifdef HAVE_IPV6
if (area->route_table6[1] == NULL)
area->route_table6[1] = route_table_init ();
#endif /* HAVE_IPV6 */
break;
case IS_LEVEL_1_AND_2:
if (newtype == IS_LEVEL_1)
area_resign_level (area, IS_LEVEL_2);
else
area_resign_level (area, IS_LEVEL_1);
break;
case IS_LEVEL_2:
if (newtype == IS_LEVEL_1)
area_resign_level (area, IS_LEVEL_2);
if (area->lspdb[0] == NULL)
area->lspdb[0] = lsp_db_init ();
if (area->route_table[0] == NULL)
area->route_table[0] = route_table_init ();
#ifdef HAVE_IPV6
if (area->route_table6[0] == NULL)
area->route_table6[0] = route_table_init ();
#endif /* HAVE_IPV6 */
break;
default:
break;
}
area->is_type = newtype;
/* override circuit's is_type */
if (area->is_type != IS_LEVEL_1_AND_2)
{
for (ALL_LIST_ELEMENTS_RO (area->circuit_list, node, circuit))
isis_event_circuit_type_change (circuit, newtype);
}
spftree_area_init (area);
if (newtype & IS_LEVEL_1)
lsp_generate (area, IS_LEVEL_1);
if (newtype & IS_LEVEL_2)
lsp_generate (area, IS_LEVEL_2);
lsp_regenerate_schedule (area, IS_LEVEL_1 | IS_LEVEL_2, 1);
return;
}
static void
circuit_commence_level (struct isis_circuit *circuit, int level)
{
@ -258,7 +145,7 @@ circuit_resign_level (struct isis_circuit *circuit, int level)
}
void
isis_event_circuit_type_change (struct isis_circuit *circuit, int newtype)
isis_circuit_is_type_set (struct isis_circuit *circuit, int newtype)
{
if (circuit->state != C_STATE_UP)
{

View File

@ -22,11 +22,6 @@
#ifndef _ZEBRA_ISIS_EVENTS_H
#define _ZEBRA_ISIS_EVENTS_H
/*
* Events related to area
*/
void isis_event_system_type_change (struct isis_area *area, int newtype);
/*
* Events related to circuit
*/

View File

@ -52,6 +52,7 @@
#include "isisd/isis_csm.h"
#include "isisd/isis_adjacency.h"
#include "isisd/isis_spf.h"
#include "isisd/isis_te.h"
#ifdef TOPOLOGY_GENERATE
#include "spgrid.h"
@ -981,6 +982,8 @@ lsp_print_detail (struct isis_lsp *lsp, struct vty *vty, char dynhost)
lspid_print (te_is_neigh->neigh_id, LSPid, dynhost, 0);
vty_out (vty, " Metric : %-8d IS-Extended : %s%s",
GET_TE_METRIC(te_is_neigh), LSPid, VTY_NEWLINE);
if (IS_MPLS_TE(isisMplsTE))
mpls_te_print_detail(vty, te_is_neigh);
}
/* TE IPv4 tlv */
@ -1091,6 +1094,64 @@ lsp_tlv_fit (struct isis_lsp *lsp, struct list **from, struct list **to,
return;
}
/* Process IS_NEIGHBOURS TLV with TE subTLVs */
void
lsp_te_tlv_fit (struct isis_lsp *lsp, struct list **from, struct list **to, int frag_thold)
{
int count, size = 0;
struct listnode *node, *nextnode;
struct te_is_neigh *elem;
/* Start computing real size of TLVs */
for (ALL_LIST_ELEMENTS (*from, node, nextnode, elem))
size = size + elem->sub_tlvs_length + IS_NEIGHBOURS_LEN;
/* can we fit all ? */
if (!FRAG_NEEDED (lsp->pdu, frag_thold, size))
{
tlv_add_te_is_neighs (*from, lsp->pdu);
if (listcount (*to) != 0)
{
for (ALL_LIST_ELEMENTS (*from, node, nextnode, elem))
{
listnode_add (*to, elem);
list_delete_node (*from, node);
}
}
else
{
list_free (*to);
*to = *from;
*from = NULL;
}
}
else
{
/* fit all we can */
/* Compute remaining place in LSP PDU */
count = FRAG_THOLD (lsp->pdu, frag_thold) - 2 -
(STREAM_SIZE (lsp->pdu) - STREAM_REMAIN (lsp->pdu));
/* Determine size of TE SubTLVs */
elem = (struct te_is_neigh *)listgetdata ((struct listnode *)listhead (*from));
count = count - elem->sub_tlvs_length - IS_NEIGHBOURS_LEN;
if (count > 0)
{
while (count > 0)
{
listnode_add (*to, listgetdata ((struct listnode *)listhead (*from)));
listnode_delete (*from, listgetdata ((struct listnode *)listhead (*from)));
elem = (struct te_is_neigh *)listgetdata ((struct listnode *)listhead (*from));
count = count - elem->sub_tlvs_length - IS_NEIGHBOURS_LEN;
}
tlv_add_te_is_neighs (*to, lsp->pdu);
}
}
lsp->lsp_header->pdu_len = htons (stream_get_endp (lsp->pdu));
return;
}
static u_int16_t
lsp_rem_lifetime (struct isis_area *area, int level)
{
@ -1481,7 +1542,10 @@ lsp_build (struct isis_lsp *lsp, struct isis_area *area)
{
ipreach =
XMALLOC (MTYPE_ISIS_TLV, sizeof (struct ipv4_reachability));
ipreach->metrics = circuit->metrics[level - 1];
ipreach->metrics.metric_default = circuit->metric[level - 1];
ipreach->metrics.metric_expense = METRICS_UNSUPPORTED;
ipreach->metrics.metric_error = METRICS_UNSUPPORTED;
ipreach->metrics.metric_delay = METRICS_UNSUPPORTED;
masklen2ip (ipv4->prefixlen, &ipreach->mask);
ipreach->prefix.s_addr = ((ipreach->mask.s_addr) &
(ipv4->prefix.s_addr));
@ -1506,7 +1570,7 @@ lsp_build (struct isis_lsp *lsp, struct isis_area *area)
((ipv4->prefixlen + 7)/8) - 1);
if (area->oldmetric)
te_ipreach->te_metric = htonl (circuit->metrics[level - 1].metric_default);
te_ipreach->te_metric = htonl (circuit->metric[level - 1]);
else
te_ipreach->te_metric = htonl (circuit->te_metric[level - 1]);
@ -1541,7 +1605,7 @@ lsp_build (struct isis_lsp *lsp, struct isis_area *area)
if (area->oldmetric)
ip6reach->metric =
htonl (circuit->metrics[level - 1].metric_default);
htonl (circuit->metric[level - 1]);
else
ip6reach->metric = htonl (circuit->te_metric[level - 1]);
@ -1580,7 +1644,10 @@ lsp_build (struct isis_lsp *lsp, struct isis_area *area)
else
memcpy (is_neigh->neigh_id,
circuit->u.bc.l2_desig_is, ISIS_SYS_ID_LEN + 1);
is_neigh->metrics = circuit->metrics[level - 1];
is_neigh->metrics.metric_default = circuit->metric[level - 1];
is_neigh->metrics.metric_expense = METRICS_UNSUPPORTED;
is_neigh->metrics.metric_error = METRICS_UNSUPPORTED;
is_neigh->metrics.metric_delay = METRICS_UNSUPPORTED;
if (!memcmp (is_neigh->neigh_id, zero_id,
ISIS_SYS_ID_LEN + 1))
{
@ -1612,7 +1679,7 @@ lsp_build (struct isis_lsp *lsp, struct isis_area *area)
memcpy (te_is_neigh->neigh_id,
circuit->u.bc.l2_desig_is, ISIS_SYS_ID_LEN + 1);
if (area->oldmetric)
metric = circuit->metrics[level - 1].metric_default;
metric = circuit->metric[level - 1];
else
metric = circuit->te_metric[level - 1];
SET_TE_METRIC(te_is_neigh, metric);
@ -1625,6 +1692,14 @@ lsp_build (struct isis_lsp *lsp, struct isis_area *area)
}
else
{
/* Check if MPLS_TE is activate */
if (IS_MPLS_TE(isisMplsTE) && HAS_LINK_PARAMS(circuit->interface))
/* Add SubTLVs & Adjust real size of SubTLVs */
te_is_neigh->sub_tlvs_length = add_te_subtlvs(te_is_neigh->sub_tlvs, circuit->mtc);
else
/* Or keep only TE metric with no SubTLVs if MPLS_TE is off */
te_is_neigh->sub_tlvs_length = 0;
listnode_add (tlv_data.te_is_neighs, te_is_neigh);
lsp_debug("ISIS (%s): Adding DIS %s.%02x as te-style neighbor",
area->area_tag, sysid_print(te_is_neigh->neigh_id),
@ -1651,7 +1726,10 @@ lsp_build (struct isis_lsp *lsp, struct isis_area *area)
}
is_neigh = XCALLOC (MTYPE_ISIS_TLV, sizeof (struct is_neigh));
memcpy (is_neigh->neigh_id, nei->sysid, ISIS_SYS_ID_LEN);
is_neigh->metrics = circuit->metrics[level - 1];
is_neigh->metrics.metric_default = circuit->metric[level - 1];
is_neigh->metrics.metric_expense = METRICS_UNSUPPORTED;
is_neigh->metrics.metric_error = METRICS_UNSUPPORTED;
is_neigh->metrics.metric_delay = METRICS_UNSUPPORTED;
listnode_add (tlv_data.is_neighs, is_neigh);
lsp_debug("ISIS (%s): Adding old-style is reach for %s", area->area_tag,
sysid_print(is_neigh->neigh_id));
@ -1670,6 +1748,18 @@ lsp_build (struct isis_lsp *lsp, struct isis_area *area)
memcpy (te_is_neigh->neigh_id, nei->sysid, ISIS_SYS_ID_LEN);
metric = circuit->te_metric[level - 1];
SET_TE_METRIC(te_is_neigh, metric);
/* Check if MPLS_TE is activate */
if (IS_MPLS_TE(isisMplsTE) && HAS_LINK_PARAMS(circuit->interface))
/* Update Local and Remote IP address for MPLS TE circuit parameters */
/* NOTE sure that it is the pertinent place for that updates */
/* Local IP address could be updated in isis_circuit.c - isis_circuit_add_addr() */
/* But, where update remote IP address ? in isis_pdu.c - process_p2p_hello() ? */
/* Add SubTLVs & Adjust real size of SubTLVs */
te_is_neigh->sub_tlvs_length = add_te_subtlvs(te_is_neigh->sub_tlvs, circuit->mtc);
else
/* Or keep only TE metric with no SubTLVs if MPLS_TE is off */
te_is_neigh->sub_tlvs_length = 0;
listnode_add (tlv_data.te_is_neighs, te_is_neigh);
lsp_debug("ISIS (%s): Adding te-style is reach for %s", area->area_tag,
sysid_print(te_is_neigh->neigh_id));

View File

@ -112,6 +112,8 @@ void lsp_print_detail (struct isis_lsp *lsp, struct vty *vty, char dynhost);
int lsp_print_all (struct vty *vty, dict_t * lspdb, char detail,
char dynhost);
const char *lsp_bits2string (u_char *);
void lsp_te_tlv_fit (struct isis_lsp *lsp, struct list **from,
struct list **to, int frag_thold);
/* sets SRMflags for all active circuits of an lsp */
void lsp_set_all_srmflags (struct isis_lsp *lsp);

View File

@ -50,6 +50,8 @@
#include "isisd/isis_route.h"
#include "isisd/isis_routemap.h"
#include "isisd/isis_zebra.h"
#include "isisd/isis_tlv.h"
#include "isisd/isis_te.h"
/* Default configuration file name */
#define ISISD_DEFAULT_CONFIG "isisd.conf"
@ -245,7 +247,9 @@ main (int argc, char **argv, char **envp)
zlog_default = openzlog (progname, ZLOG_ISIS, 0,
LOG_CONS | LOG_NDELAY | LOG_PID, LOG_DAEMON);
zprivs_init (&isisd_privs);
zlog_set_file (NULL, LOG_DEFAULT_FILENAME , zlog_default->default_lvl);
#if defined(HAVE_CUMULUS)
zlog_set_level (NULL, ZLOG_DEST_SYSLOG, zlog_default->default_lvl);
#endif
/* for reload */
_argc = argc;
@ -346,6 +350,7 @@ main (int argc, char **argv, char **envp)
isis_spf_cmds_init ();
isis_redist_init ();
isis_route_map_init();
isis_mpls_te_init();
/* create the global 'isis' instance */
isis_new (1);

View File

@ -53,6 +53,7 @@
#include "isisd/iso_checksum.h"
#include "isisd/isis_csm.h"
#include "isisd/isis_events.h"
#include "isisd/isis_te.h"
#define ISIS_MINIMUM_FIXED_HDR_LEN 15
#define ISIS_MIN_PDU_LEN 13 /* partial seqnum pdu with id_len=2 */
@ -630,6 +631,15 @@ process_p2p_hello (struct isis_circuit *circuit)
if (found & TLVFLAG_IPV4_ADDR)
tlvs_to_adj_ipv4_addrs (&tlvs, adj);
/* Update MPLS TE Remote IP address parameter if possible */
if (IS_MPLS_TE(isisMplsTE) && circuit->mtc && IS_CIRCUIT_TE(circuit->mtc))
if (adj->ipv4_addrs != NULL && listcount(adj->ipv4_addrs) != 0)
{
struct in_addr *ip_addr;
ip_addr = (struct in_addr *)listgetdata ((struct listnode *)listhead (adj->ipv4_addrs));
set_circuitparams_rmt_ipaddr (circuit->mtc, *ip_addr);
}
#ifdef HAVE_IPV6
if (found & TLVFLAG_IPV6_ADDR)
tlvs_to_adj_ipv6_addrs (&tlvs, adj);

View File

@ -44,6 +44,7 @@ struct isis_redist
struct isis_area;
struct prefix;
struct vty;
struct route_table *get_ext_reach(struct isis_area *area,
int family, int level);

View File

@ -50,7 +50,7 @@
#include "isis_zebra.h"
static struct isis_nexthop *
isis_nexthop_create (struct in_addr *ip, unsigned int ifindex)
isis_nexthop_create (struct in_addr *ip, ifindex_t ifindex)
{
struct listnode *node;
struct isis_nexthop *nexthop;
@ -91,7 +91,7 @@ isis_nexthop_delete (struct isis_nexthop *nexthop)
static int
nexthoplookup (struct list *nexthops, struct in_addr *ip,
unsigned int ifindex)
ifindex_t ifindex)
{
struct listnode *node;
struct isis_nexthop *nh;
@ -130,7 +130,7 @@ nexthops_print (struct list *nhs)
#ifdef HAVE_IPV6
static struct isis_nexthop6 *
isis_nexthop6_new (struct in6_addr *ip6, unsigned int ifindex)
isis_nexthop6_new (struct in6_addr *ip6, ifindex_t ifindex)
{
struct isis_nexthop6 *nexthop6;
@ -144,7 +144,7 @@ isis_nexthop6_new (struct in6_addr *ip6, unsigned int ifindex)
}
static struct isis_nexthop6 *
isis_nexthop6_create (struct in6_addr *ip6, unsigned int ifindex)
isis_nexthop6_create (struct in6_addr *ip6, ifindex_t ifindex)
{
struct listnode *node;
struct isis_nexthop6 *nexthop6;
@ -181,7 +181,7 @@ isis_nexthop6_delete (struct isis_nexthop6 *nexthop6)
static int
nexthop6lookup (struct list *nexthops6, struct in6_addr *ip6,
unsigned int ifindex)
ifindex_t ifindex)
{
struct listnode *node;
struct isis_nexthop6 *nh6;

View File

@ -28,7 +28,7 @@
#ifdef HAVE_IPV6
struct isis_nexthop6
{
unsigned int ifindex;
ifindex_t ifindex;
struct in6_addr ip6;
struct in6_addr router_address6;
unsigned int lock;
@ -37,7 +37,7 @@ struct isis_nexthop6
struct isis_nexthop
{
unsigned int ifindex;
ifindex_t ifindex;
struct in_addr ip;
struct in_addr router_address;
unsigned int lock;

View File

@ -545,13 +545,13 @@ isis_spf_add2tent (struct isis_spftree *spftree, enum vertextype vtype,
v = listgetdata (node);
if (v->d_N > vertex->d_N)
{
list_add_node_prev (spftree->tents, node, vertex);
listnode_add_before (spftree->tents, node, vertex);
break;
}
else if (v->d_N == vertex->d_N && v->type > vertex->type)
{
/* Tie break, add according to type */
list_add_node_prev (spftree->tents, node, vertex);
listnode_add_before (spftree->tents, node, vertex);
break;
}
}

1369
isisd/isis_te.c Normal file

File diff suppressed because it is too large Load Diff

331
isisd/isis_te.h Normal file
View File

@ -0,0 +1,331 @@
/*
* IS-IS Rout(e)ing protocol - isis_te.c
*
* This is an implementation of RFC5305, RFC 5307 and draft-ietf-isis-te-metric-extensions-11
*
* Copyright (C) 2014 Orange Labs
* http://www.orange.com
*
* 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_ISIS_MPLS_TE_H
#define _ZEBRA_ISIS_MPLS_TE_H
/*
* Traffic Engineering information are transport through LSP:
* - Extended IS Reachability TLV = 22
* - Traffic Engineering Router ID TLV = 134
* - Extended IP Reachability TLV = 135
* - Inter-AS Reachability Information TLV = 141
*
* and support following sub-TLV:
*
* Name Value Status
* _________________________________________________
* Administartive group (color) 3 RFC5305
* Link Local/Remote Identifiers 4 RFC5307
* IPv4 interface address 6 RFC5305
* IPv4 neighbor address 8 RFC5305
* Maximum link bandwidth 9 RFC5305
* Reservable link bandwidth 10 RFC5305
* Unreserved bandwidth 11 RFC5305
* TE Default metric 18 RFC5305
* Link Protection Type 20 RFC5307
* Interface Switching Capability 21 RFC5307
* Remote AS number 24 RFC5316
* IPv4 Remote ASBR identifier 25 RFC5316
*
*/
/* NOTE: RFC5316 is not yet supported in this version */
/* Following define the type of TE link regarding the various RFC */
#define STD_TE 0x01
#define GMPLS 0x02
#define INTER_AS 0x04
#define FLOOD_L1 0x10
#define FLOOD_L2 0x20
#define FLOOD_AS 0x40
#define EMULATED 0x80
#define IS_STD_TE(x) (x & STD_TE)
#define IS_INTER_AS(x) (x & INTER_AS)
#define IS_EMULATED(x) (x & EMULATED)
#define IS_FLOOD_L1(x) (x & FLOOD_L1)
#define IS_FLOOD_L2(x) (x & FLOOD_L2)
#define IS_FLOOD_AS(x) (x & FLOOD_AS)
#define IS_INTER_AS_EMU(x) (x & INTER_AS & EMULATED)
#define IS_INTER_AS_AS(x) (x & INTER_AS & FLOOD_AS)
/*
* Following section defines subTLV (tag, length, value) structures,
* used for Traffic Engineering.
*/
struct subtlv_header
{
u_char type; /* sub_TLV_XXX type (see above) */
u_char length; /* Value portion only, in byte */
};
#define SUBTLV_HDR_SIZE 2 /* (sizeof (struct sub_tlv_header)) */
#define SUBTLV_SIZE(stlvh) (SUBTLV_HDR_SIZE + (stlvh)->length)
#define SUBTLV_HDR_TOP(lsph) (struct subtlv_header *)((char *)(lsph) + ISIS_LSP_HEADER_SIZE)
#define SUBTLV_HDR_NEXT(stlvh) (struct subtlv_header *)((char *)(stlvh) + SUBTLV_SIZE(stlvh))
#define SUBTLV_TYPE(stlvh) stlvh.header.type
#define SUBTLV_LEN(stlvh) stlvh.header.length
#define SUBTLV_VAL(stlvh) stlvh.value
#define SUBTLV_DATA(stlvh) stlvh + SUBTLV_HDR_SIZE
#define SUBTLV_DEF_SIZE 4
/* Link Sub-TLV: Resource Class/Color - RFC 5305 */
#define TE_SUBTLV_ADMIN_GRP 3
struct te_subtlv_admin_grp
{
struct subtlv_header header; /* Value length is 4 octets. */
u_int32_t value; /* Admin. group membership. */
} __attribute__((__packed__));
/* Link Local/Remote Identifiers - RFC 5307 */
#define TE_SUBTLV_LLRI 4
#define TE_SUBTLV_LLRI_SIZE 8
struct te_subtlv_llri
{
struct subtlv_header header; /* Value length is 8 octets. */
u_int32_t local; /* Link Local Identifier */
u_int32_t remote; /* Link Remote Identifier */
} __attribute__((__packed__));
/* Link Sub-TLV: Local Interface IP Address - RFC 5305 */
#define TE_SUBTLV_LOCAL_IPADDR 6
struct te_subtlv_local_ipaddr
{
struct subtlv_header header; /* Value length is 4 x N octets. */
struct in_addr value; /* Local IP address(es). */
} __attribute__((__packed__));
/* Link Sub-TLV: Neighbor Interface IP Address - RFC 5305 */
#define TE_SUBTLV_RMT_IPADDR 8
struct te_subtlv_rmt_ipaddr
{
struct subtlv_header header; /* Value length is 4 x N octets. */
struct in_addr value; /* Neighbor's IP address(es). */
} __attribute__((__packed__));
/* Link Sub-TLV: Maximum Bandwidth - RFC 5305 */
#define TE_SUBTLV_MAX_BW 9
struct te_subtlv_max_bw
{
struct subtlv_header header; /* Value length is 4 octets. */
float value; /* bytes/sec */
} __attribute__((__packed__));
/* Link Sub-TLV: Maximum Reservable Bandwidth - RFC 5305 */
#define TE_SUBTLV_MAX_RSV_BW 10
struct te_subtlv_max_rsv_bw
{
struct subtlv_header header; /* Value length is 4 octets. */
float value; /* bytes/sec */
} __attribute__((__packed__));
/* Link Sub-TLV: Unreserved Bandwidth - RFC 5305 */
#define TE_SUBTLV_UNRSV_BW 11
#define TE_SUBTLV_UNRSV_SIZE 32
struct te_subtlv_unrsv_bw
{
struct subtlv_header header; /* Value length is 32 octets. */
float value[8]; /* One for each priority level. */
} __attribute__((__packed__));
/* Link Sub-TLV: Traffic Engineering Metric - RFC 5305 */
#define TE_SUBTLV_TE_METRIC 18
#define TE_SUBTLV_TE_METRIC_SIZE 3
struct te_subtlv_te_metric
{
struct subtlv_header header; /* Value length is 4 octets. */
u_char value[3]; /* Link metric for TE purpose. */
} __attribute__((__packed__));
/* Remote AS Number sub-TLV - RFC5316 */
#define TE_SUBTLV_RAS 24
struct te_subtlv_ras
{
struct subtlv_header header; /* Value length is 4 octets. */
u_int32_t value; /* Remote AS number */
} __attribute__((__packed__));
/* IPv4 Remote ASBR ID Sub-TLV - RFC5316 */
#define TE_SUBTLV_RIP 25
struct te_subtlv_rip
{
struct subtlv_header header; /* Value length is 4 octets. */
struct in_addr value; /* Remote ASBR IP address */
} __attribute__((__packed__));
/* draft-ietf-isis-te-metric-extensions-11.txt */
/* Link Sub-TLV: Average Link Delay */
#define TE_SUBTLV_AV_DELAY 33
struct te_subtlv_av_delay
{
struct subtlv_header header; /* Value length is 4 bytes. */
u_int32_t value; /* Average delay in micro-seconds only 24 bits => 0 ... 16777215
with Anomalous Bit (A) as Upper most bit */
} __attribute__((__packed__));
/* Link Sub-TLV: Low/High Link Delay */
#define TE_SUBTLV_MM_DELAY 34
#define TE_SUBTLV_MM_DELAY_SIZE 8
struct te_subtlv_mm_delay
{
struct subtlv_header header; /* Value length is 8 bytes. */
u_int32_t low; /* low delay in micro-seconds only 24 bits => 0 ... 16777215
with Anomalous Bit (A) as Upper most bit */
u_int32_t high; /* high delay in micro-seconds only 24 bits => 0 ... 16777215 */
} __attribute__((__packed__));
/* Link Sub-TLV: Link Delay Variation i.e. Jitter */
#define TE_SUBTLV_DELAY_VAR 35
struct te_subtlv_delay_var
{
struct subtlv_header header; /* Value length is 4 bytes. */
u_int32_t value; /* interval in micro-seconds only 24 bits => 0 ... 16777215 */
} __attribute__((__packed__));
/* Link Sub-TLV: Routine Unidirectional Link Packet Loss */
#define TE_SUBTLV_PKT_LOSS 36
struct te_subtlv_pkt_loss
{
struct subtlv_header header; /* Value length is 4 bytes. */
u_int32_t value; /* in percentage of total traffic only 24 bits (2^24 - 2)
with Anomalous Bit (A) as Upper most bit */
} __attribute__((__packed__));
/* Link Sub-TLV: Unidirectional Residual Bandwidth */ /* Optional */
#define TE_SUBTLV_RES_BW 37
struct te_subtlv_res_bw
{
struct subtlv_header header; /* Value length is 4 bytes. */
float value; /* bandwidth in IEEE floating point format with units in bytes per second */
} __attribute__((__packed__));
/* Link Sub-TLV: Unidirectional Available Bandwidth */ /* Optional */
#define TE_SUBTLV_AVA_BW 38
struct te_subtlv_ava_bw
{
struct subtlv_header header; /* Value length is 4 octets. */
float value; /* bandwidth in IEEE floating point format with units in bytes per second */
} __attribute__((__packed__));
/* Link Sub-TLV: Unidirectional Utilized Bandwidth */ /* Optional */
#define TE_SUBTLV_USE_BW 39
struct te_subtlv_use_bw
{
struct subtlv_header header; /* Value length is 4 octets. */
float value; /* bandwidth in IEEE floating point format with units in bytes per second */
} __attribute__((__packed__));
#define TE_SUBTLV_MAX 40 /* Last SUBTLV + 1 */
/* Following declaration concerns the MPLS-TE and LINk-TE management */
typedef enum _status_t { disable, enable, learn } status_t;
/* Mode for Inter-AS LSP */ /* TODO: Check how if LSP is flooded in RFC5316 */
typedef enum _interas_mode_t { off, region, as, emulate } interas_mode_t;
#define IS_MPLS_TE(m) (m.status == enable)
#define IS_CIRCUIT_TE(c) (c->status == enable)
/* Following structure are internal use only. */
struct isis_mpls_te
{
/* Status of MPLS-TE: enable or disable */
status_t status;
/* L1, L1-L2, L2-Only */
u_int8_t level;
/* RFC5316 */
interas_mode_t inter_as;
struct in_addr interas_areaid;
/* Circuit list on which TE are enable */
struct list *cir_list;
/* MPLS_TE router ID */
struct in_addr router_id;
};
extern struct isis_mpls_te isisMplsTE;
struct mpls_te_circuit
{
/* Status of MPLS-TE on this interface */
status_t status;
/* Type of MPLS-TE circuit: STD_TE(RFC5305), INTER_AS(RFC5316), INTER_AS_EMU(RFC5316 emulated) */
u_int8_t type;
/* Total size of sub_tlvs */
u_char length;
/* Store subTLV in network byte order. */
/* RFC5305 */
struct te_subtlv_admin_grp admin_grp;
/* RFC5307 */
struct te_subtlv_llri llri;
/* RFC5305 */
struct te_subtlv_local_ipaddr local_ipaddr;
struct te_subtlv_rmt_ipaddr rmt_ipaddr;
struct te_subtlv_max_bw max_bw;
struct te_subtlv_max_rsv_bw max_rsv_bw;
struct te_subtlv_unrsv_bw unrsv_bw;
struct te_subtlv_te_metric te_metric;
/* RFC5316 */
struct te_subtlv_ras ras;
struct te_subtlv_rip rip;
/* draft-ietf-isis-te-metric-extension */
struct te_subtlv_av_delay av_delay;
struct te_subtlv_mm_delay mm_delay;
struct te_subtlv_delay_var delay_var;
struct te_subtlv_pkt_loss pkt_loss;
struct te_subtlv_res_bw res_bw;
struct te_subtlv_ava_bw ava_bw;
struct te_subtlv_use_bw use_bw;
};
/* Prototypes. */
void isis_mpls_te_init (void);
struct mpls_te_circuit *mpls_te_circuit_new(void);
void mpls_te_print_detail(struct vty *, struct te_is_neigh *);
void set_circuitparams_local_ipaddr (struct mpls_te_circuit *, struct in_addr);
void set_circuitparams_rmt_ipaddr (struct mpls_te_circuit *, struct in_addr);
u_char subtlvs_len (struct mpls_te_circuit *);
u_char add_te_subtlvs(u_char *, struct mpls_te_circuit *);
u_char build_te_subtlvs(u_char *, struct isis_circuit *);
void isis_link_params_update(struct isis_circuit *, struct interface *);
void isis_mpls_te_update(struct interface *);
void isis_mpls_te_config_write_router (struct vty *);
#endif /* _ZEBRA_ISIS_MPLS_TE_H */

View File

@ -42,6 +42,7 @@
#include "isisd/isis_misc.h"
#include "isisd/isis_pdu.h"
#include "isisd/isis_lsp.h"
#include "isisd/isis_te.h"
void
free_tlv (void *val)
@ -229,9 +230,23 @@ parse_tlvs (char *areatag, u_char * stream, int size, u_int32_t * expected,
while (length > value_len)
{
te_is_nei = (struct te_is_neigh *) pnt;
value_len += 11;
pnt += 11;
value_len += IS_NEIGHBOURS_LEN;
pnt += IS_NEIGHBOURS_LEN;
/* FIXME - subtlvs are handled here, for now we skip */
/* FIXME: All TE SubTLVs are not necessary present in LSP PDU. */
/* So, it must be copied in a new te_is_neigh structure */
/* rather than just initialize pointer to the original LSP PDU */
/* to avoid consider the rest of lspdu as subTLVs or buffer overflow */
if (IS_MPLS_TE(isisMplsTE))
{
struct te_is_neigh *new = XCALLOC(MTYPE_ISIS_TLV, sizeof(struct te_is_neigh));
memcpy(new->neigh_id, te_is_nei->neigh_id, ISIS_SYS_ID_LEN + 1);
memcpy(new->te_metric, te_is_nei->te_metric, 3);
new->sub_tlvs_length = te_is_nei->sub_tlvs_length;
memcpy(new->sub_tlvs, pnt, te_is_nei->sub_tlvs_length);
te_is_nei = new;
}
/* Skip SUB TLVs payload */
value_len += te_is_nei->sub_tlvs_length;
pnt += te_is_nei->sub_tlvs_length;
@ -845,8 +860,8 @@ tlv_add_te_is_neighs (struct list *te_is_neighs, struct stream *stream)
for (ALL_LIST_ELEMENTS_RO (te_is_neighs, node, te_is_neigh))
{
/* FIXME: This will be wrong if we are going to add TE sub TLVs. */
if (pos - value + IS_NEIGHBOURS_LEN > 255)
/* FIXME: Check if Total SubTLVs size doesn't exceed 255 */
if (pos - value + IS_NEIGHBOURS_LEN + te_is_neigh->sub_tlvs_length > 255)
{
retval = add_tlv (TE_IS_NEIGHBOURS, pos - value, value, stream);
if (retval != ISIS_OK)
@ -858,9 +873,15 @@ tlv_add_te_is_neighs (struct list *te_is_neighs, struct stream *stream)
pos += ISIS_SYS_ID_LEN + 1;
memcpy (pos, te_is_neigh->te_metric, 3);
pos += 3;
/* Sub TLVs length. */
*pos = 0;
/* Set the total size of Sub TLVs */
*pos = te_is_neigh->sub_tlvs_length;
pos++;
/* Copy Sub TLVs if any */
if (te_is_neigh->sub_tlvs_length > 0)
{
memcpy (pos, te_is_neigh->sub_tlvs, te_is_neigh->sub_tlvs_length);
pos += te_is_neigh->sub_tlvs_length;
}
}
return add_tlv (TE_IS_NEIGHBOURS, pos - value, value, stream);

View File

@ -39,7 +39,7 @@
* LSP Entries 9 n n y ISO10589
* Authentication 10 y y y ISO10589, RFC3567
* Checksum 12 y n y RFC3358
* TE IS Reachability 22 n y n RFC5305
* Extended IS Reachability 22 n y n RFC5305
* IS Alias 24 n y n RFC3786
* IP Int. Reachability 128 n y n RFC1195
* Protocols Supported 129 y y n RFC1195
@ -50,6 +50,7 @@
* Extended IP Reachability 135 n y n RFC5305
* Dynamic Hostname 137 n y n RFC2763
* Shared Risk Link Group 138 n y y RFC5307
* Inter-AS Reachability 141 n y n RFC5316
* Restart TLV 211 y n n RFC3847
* MT IS Reachability 222 n y n RFC5120
* MT Supported 229 y y n RFC5120
@ -59,10 +60,10 @@
* MT IPv6 IP Reachability 237 n y n RFC5120
* P2P Adjacency State 240 y n n RFC3373
* IIH Sequence Number 241 y n n draft-shen-isis-iih-sequence
* Router Capability 242 - - - draft-ietf-isis-caps
* Router Capability 242 n y n RFC4971
*
*
* IS Reachability sub-TLVs we (should) support.
* IS Reachability sub-TLVs we support (See isis_te.[c,h])
* ____________________________________________________________________________
* Name Value Status
* ____________________________________________________________________________
@ -76,6 +77,8 @@
* TE Default metric 18 RFC5305
* Link Protection Type 20 RFC5307
* Interface Switching Capability 21 RFC5307
* Remote AS number 24 RFC5316
* IPv4 Remote ASBR identifier 25 RFC5316
*
*
* IP Reachability sub-TLVs we (should) support.
@ -109,6 +112,7 @@
#define IPV6_ADDR 232
#define IPV6_REACHABILITY 236
#define WAY3_HELLO 240
#define ROUTER_INFORMATION 242
#define AUTH_INFO_HDRLEN 3
@ -121,6 +125,8 @@
#define IPV6_REACH_LEN 22
#define TE_IPV4_REACH_LEN 9
#define MAX_SUBTLV_SIZE 256
/* struct for neighbor */
struct is_neigh
{
@ -128,12 +134,18 @@ struct is_neigh
u_char neigh_id[ISIS_SYS_ID_LEN + 1];
};
/* struct for te is neighbor */
/* struct for te metric */
struct te_is_neigh
{
u_char neigh_id[ISIS_SYS_ID_LEN + 1];
u_char te_metric[3];
u_char sub_tlvs_length;
/* Theorical Maximum SubTLVs is 256 because the sub_tlvs_length is 8 bits */
/* Practically, 118 bytes are necessary to store all supported TE parameters */
/* FIXME: A pointer will use less memory, but need to be free */
/* which is hard to fix, especially within free_tlvs() function */
/* and malloc() / free() as a CPU cost compared to the memory usage */
u_char sub_tlvs[MAX_SUBTLV_SIZE]; /* SUB TLVs storage */
};
/* Decode and encode three-octet metric into host byte order integer */

2428
isisd/isis_vty.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -49,6 +49,7 @@
#include "isisd/isis_lsp.h"
#include "isisd/isis_route.h"
#include "isisd/isis_zebra.h"
#include "isisd/isis_te.h"
struct zclient *zclient = NULL;
@ -61,6 +62,13 @@ isis_router_id_update_zebra (int command, struct zclient *zclient,
struct listnode *node;
struct prefix router_id;
/*
* If ISIS TE is enable, TE Router ID is set through specific command.
* See mpls_te_router_addr() command in isis_te.c
*/
if (IS_MPLS_TE(isisMplsTE))
return 0;
zebra_router_id_update_read (zclient->ibuf, &router_id);
if (isis->router_id == router_id.u.prefix4.s_addr)
return 0;
@ -228,6 +236,23 @@ isis_zebra_if_address_del (int command, struct zclient *client,
return 0;
}
static int
isis_zebra_link_params (int command, struct zclient *zclient,
zebra_size_t length)
{
struct interface *ifp;
ifp = zebra_interface_link_params_read (zclient->ibuf);
if (ifp == NULL)
return 0;
/* Update TE TLV */
isis_mpls_te_update(ifp);
return 0;
}
static void
isis_zebra_route_add_ipv4 (struct prefix *prefix,
struct isis_route_info *route_info)
@ -278,12 +303,12 @@ isis_zebra_route_add_ipv4 (struct prefix *prefix,
/* FIXME: can it be ? */
if (nexthop->ip.s_addr != INADDR_ANY)
{
stream_putc (stream, ZEBRA_NEXTHOP_IPV4);
stream_putc (stream, NEXTHOP_TYPE_IPV4);
stream_put_in_addr (stream, &nexthop->ip);
}
else
{
stream_putc (stream, ZEBRA_NEXTHOP_IFINDEX);
stream_putc (stream, NEXTHOP_TYPE_IFINDEX);
stream_putl (stream, nexthop->ifindex);
}
}
@ -333,7 +358,7 @@ isis_zebra_route_add_ipv6 (struct prefix *prefix,
{
struct zapi_ipv6 api;
struct in6_addr **nexthop_list;
unsigned int *ifindex_list;
ifindex_t *ifindex_list;
struct isis_nexthop6 *nexthop6;
int i, size;
struct listnode *node;
@ -370,7 +395,7 @@ isis_zebra_route_add_ipv6 (struct prefix *prefix,
/* allocate memory for ifindex_list */
size = sizeof (unsigned int) * listcount (route_info->nexthops6);
ifindex_list = (unsigned int *) XMALLOC (MTYPE_ISIS_TMP, size);
ifindex_list = (ifindex_t *) XMALLOC (MTYPE_ISIS_TMP, size);
if (!ifindex_list)
{
zlog_err ("isis_zebra_add_route_ipv6: out of memory!");
@ -420,7 +445,7 @@ isis_zebra_route_del_ipv6 (struct prefix *prefix,
{
struct zapi_ipv6 api;
struct in6_addr **nexthop_list;
unsigned int *ifindex_list;
ifindex_t *ifindex_list;
struct isis_nexthop6 *nexthop6;
int i, size;
struct listnode *node;
@ -451,7 +476,7 @@ isis_zebra_route_del_ipv6 (struct prefix *prefix,
/* allocate memory for ifindex_list */
size = sizeof (unsigned int) * listcount (route_info->nexthops6);
ifindex_list = (unsigned int *) XMALLOC (MTYPE_ISIS_TMP, size);
ifindex_list = (ifindex_t *) XMALLOC (MTYPE_ISIS_TMP, size);
if (!ifindex_list)
{
zlog_err ("isis_zebra_route_del_ipv6: out of memory!");
@ -680,6 +705,7 @@ isis_zebra_init (struct thread_master *master)
zclient->interface_down = isis_zebra_if_state_down;
zclient->interface_address_add = isis_zebra_if_address_add;
zclient->interface_address_delete = isis_zebra_if_address_del;
zclient->interface_link_params = isis_zebra_link_params;
zclient->ipv4_route_add = isis_zebra_read_ipv4;
zclient->ipv4_route_delete = isis_zebra_read_ipv4;
zclient->redistribute_route_ipv4_add = isis_zebra_read_ipv4;

File diff suppressed because it is too large Load Diff

View File

@ -27,7 +27,11 @@
#define ISISD_VERSION "0.0.7"
#include "isisd/isis_constants.h"
#include "isisd/isis_common.h"
#include "isisd/isis_redist.h"
#include "isis_flags.h"
#include "dict.h"
/* uncomment if you are a developer in bug hunt */
/* #define EXTREME_DEBUG */
@ -139,6 +143,25 @@ struct isis_area *isis_area_lookup (const char *);
int isis_area_get (struct vty *vty, const char *area_tag);
void print_debug(struct vty *, int, int);
void isis_area_overload_bit_set(struct isis_area *area, bool overload_bit);
void isis_area_attached_bit_set(struct isis_area *area, bool attached_bit);
void isis_area_dynhostname_set(struct isis_area *area, bool dynhostname);
void isis_area_metricstyle_set(struct isis_area *area, bool old_metric,
bool new_metric);
void isis_area_lsp_mtu_set(struct isis_area *area, unsigned int lsp_mtu);
void isis_area_is_type_set(struct isis_area *area, int is_type);
void isis_area_max_lsp_lifetime_set(struct isis_area *area, int level,
uint16_t max_lsp_lifetime);
void isis_area_lsp_refresh_set(struct isis_area *area, int level,
uint16_t lsp_refresh);
/* IS_LEVEL_1 sets area_passwd, IS_LEVEL_2 domain_passwd */
int isis_area_passwd_unset (struct isis_area *area, int level);
int isis_area_passwd_cleartext_set (struct isis_area *area, int level,
const char *passwd, u_char snp_auth);
int isis_area_passwd_hmac_md5_set (struct isis_area *area, int level,
const char *passwd, u_char snp_auth);
void isis_vty_init (void);
/* Master of threads. */
extern struct thread_master *master;
@ -174,4 +197,8 @@ extern struct thread_master *master;
} \
while (0)
#define DEBUG_TE (1<<13)
#define IS_DEBUG_ISIS(x) (isis->debugs & x)
#endif /* ISISD_H */

1
lib/.gitignore vendored
View File

@ -19,3 +19,4 @@ route_types.h
command_lex.c
command_parse.c
command_parse.h
refix

View File

@ -17,7 +17,7 @@ libzebra_la_SOURCES = \
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 \
sigevent.c pqueue.c jhash.c memtypes.c workqueue.c nexthop.c json.c \
ptm_lib.c csv.c bfd.c vrf.c systemd.c
ptm_lib.c csv.c bfd.c vrf.c systemd.c ns.c
BUILT_SOURCES = memtypes.h route_types.h gitversion.h command_parse.h
@ -35,7 +35,7 @@ pkginclude_HEADERS = \
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 \
workqueue.h route_types.h libospf.h nexthop.h json.h \
ptm_lib.h csv.h bfd.h vrf.h systemd.h bitfield.h
ptm_lib.h csv.h bfd.h vrf.h ns.h systemd.h bitfield.h
noinst_HEADERS = \
plist_int.h

View File

@ -24,11 +24,110 @@
#if defined HAVE_SNMP && defined SNMP_AGENTX
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include <net-snmp/agent/snmp_vars.h>
#include "command.h"
#include "smux.h"
#include "memory.h"
#include "linklist.h"
int agentx_enabled = 0;
static int agentx_enabled = 0;
static struct thread_master *agentx_tm;
static struct thread *timeout_thr = NULL;
static struct list *events = NULL;
static void agentx_events_update(void);
static int
agentx_timeout(struct thread *t)
{
timeout_thr = NULL;
snmp_timeout ();
run_alarms ();
netsnmp_check_outstanding_agent_requests ();
agentx_events_update ();
return 0;
}
static int
agentx_read(struct thread *t)
{
fd_set fds;
struct listnode *ln = THREAD_ARG (t);
list_delete_node (events, ln);
FD_ZERO (&fds);
FD_SET (THREAD_FD (t), &fds);
snmp_read (&fds);
netsnmp_check_outstanding_agent_requests ();
agentx_events_update ();
return 0;
}
static void
agentx_events_update(void)
{
int maxfd = 0;
int block = 1;
struct timeval timeout = { .tv_sec = 0, .tv_usec = 0 };
fd_set fds;
struct listnode *ln;
struct thread *thr;
int fd, thr_fd;
THREAD_OFF (timeout_thr);
FD_ZERO (&fds);
snmp_select_info (&maxfd, &fds, &timeout, &block);
if (!block)
timeout_thr = thread_add_timer_tv (agentx_tm, agentx_timeout, NULL, &timeout);
ln = listhead (events);
thr = ln ? listgetdata (ln) : NULL;
thr_fd = thr ? THREAD_FD (thr) : -1;
/* "two-pointer" / two-list simultaneous iteration
* ln/thr/thr_fd point to the next existing event listener to hit while
* fd counts to catch up */
for (fd = 0; fd < maxfd; fd++)
{
/* caught up */
if (thr_fd == fd)
{
struct listnode *nextln = listnextnode (ln);
if (!FD_ISSET (fd, &fds))
{
thread_cancel (thr);
list_delete_node (events, ln);
}
ln = nextln;
thr = ln ? listgetdata (ln) : NULL;
thr_fd = thr ? THREAD_FD (thr) : -1;
}
/* need listener, but haven't hit one where it would be */
else if (FD_ISSET (fd, &fds))
{
struct listnode *newln;
thr = thread_add_read (agentx_tm, agentx_read, NULL, fd);
newln = listnode_add_before (events, ln, thr);
thr->arg = newln;
}
}
/* leftover event listeners at this point have fd > maxfd, delete them */
while (ln)
{
struct listnode *nextln = listnextnode (ln);
thread_cancel (listgetdata (ln));
list_delete_node (events, ln);
ln = nextln;
}
}
/* AgentX node. */
static struct cmd_node agentx_node =
@ -77,6 +176,8 @@ DEFUN (agentx_enable,
if (!agentx_enabled)
{
init_snmp("quagga");
events = list_new();
agentx_events_update ();
agentx_enabled = 1;
return CMD_SUCCESS;
}
@ -99,6 +200,8 @@ DEFUN (no_agentx,
void
smux_init (struct thread_master *tm)
{
agentx_tm = tm;
netsnmp_enable_subagent ();
snmp_disable_log ();
snmp_enable_calllog ();
@ -207,6 +310,7 @@ smux_trap (struct variable *vp, size_t vp_len,
send_v2trap (notification_vars);
snmp_free_varbind (notification_vars);
agentx_events_update ();
return 1;
}

View File

@ -504,8 +504,8 @@ bfd_client_sendmsg (struct zclient *zclient, int command)
if (ret < 0)
{
if (bfd_debug)
zlog_debug ("bfd_client_sendmsg %d: zclient_send_message() failed",
getpid());
zlog_debug ("bfd_client_sendmsg %ld: zclient_send_message() failed",
(long) getpid());
return;
}

View File

@ -666,8 +666,12 @@ node_parent ( enum node_type node )
case KEYCHAIN_KEY_NODE:
ret = KEYCHAIN_NODE;
break;
case LINK_PARAMS_NODE:
ret = INTERFACE_NODE;
break;
default:
ret = CONFIG_NODE;
break;
}
return ret;
@ -961,6 +965,7 @@ DEFUN (config_exit,
vty_config_unlock (vty);
break;
case INTERFACE_NODE:
case NS_NODE:
case VRF_NODE:
case ZEBRA_NODE:
case BGP_NODE:
@ -989,6 +994,9 @@ DEFUN (config_exit,
case KEYCHAIN_KEY_NODE:
vty->node = KEYCHAIN_NODE;
break;
case LINK_PARAMS_NODE:
vty->node = INTERFACE_NODE;
break;
default:
break;
}
@ -1016,6 +1024,7 @@ DEFUN (config_end,
break;
case CONFIG_NODE:
case INTERFACE_NODE:
case NS_NODE:
case VRF_NODE:
case ZEBRA_NODE:
case RIP_NODE:
@ -1038,6 +1047,7 @@ DEFUN (config_end,
case MASC_NODE:
case PIM_NODE:
case VTY_NODE:
case LINK_PARAMS_NODE:
vty_config_unlock (vty);
vty->node = ENABLE_NODE;
break;
@ -1757,6 +1767,10 @@ set_log_file(struct vty *vty, const char *fname, int loglevel)
host.logfile = XSTRDUP (MTYPE_HOST, fname);
#if defined(HAVE_CUMULUS)
if (zlog_default->maxlvl[ZLOG_DEST_SYSLOG] != ZLOG_DISABLED)
zlog_default->maxlvl[ZLOG_DEST_SYSLOG] = ZLOG_DISABLED;
#endif
return CMD_SUCCESS;
}
@ -1955,11 +1969,25 @@ DEFUN (no_config_log_timestamp_precision,
int
cmd_banner_motd_file (const char *file)
{
int success = CMD_SUCCESS;
char p[PATH_MAX];
char *rpath;
char *in;
rpath = realpath (file, p);
if (!rpath)
return CMD_ERR_NO_FILE;
in = strstr (rpath, SYSCONFDIR);
if (in == rpath)
{
if (host.motdfile)
XFREE (MTYPE_HOST, host.motdfile);
host.motdfile = XSTRDUP (MTYPE_HOST, file);
}
else
success = CMD_WARNING;
return CMD_SUCCESS;
return success;
}
DEFUN (banner_motd_file,
@ -1970,7 +1998,15 @@ DEFUN (banner_motd_file,
"Banner from a file\n"
"Filename\n")
{
return cmd_banner_motd_file (argv[3]->arg);
int cmd = cmd_banner_motd_file (argv[3]->arg);
if (cmd == CMD_ERR_NO_FILE)
vty_out (vty, "%s does not exist", argv[3]->arg);
else if (cmd == CMD_WARNING)
vty_out (vty, "%s must be in %s",
argv[0], SYSCONFDIR);
return cmd;
}
DEFUN (banner_motd_default,
@ -2098,7 +2134,6 @@ cmd_init (int terminal)
install_element (RESTRICTED_NODE, &config_enable_cmd);
install_element (RESTRICTED_NODE, &config_terminal_length_cmd);
install_element (RESTRICTED_NODE, &config_terminal_no_length_cmd);
install_element (RESTRICTED_NODE, &show_commandtree_cmd);
install_element (RESTRICTED_NODE, &echo_cmd);
}
@ -2167,7 +2202,6 @@ cmd_init (int terminal)
vrf_install_commands ();
}
install_element (CONFIG_NODE, &show_commandtree_cmd);
srandom(time(NULL));
}

View File

@ -75,6 +75,7 @@ enum node_type
AAA_NODE, /* AAA node. */
KEYCHAIN_NODE, /* Key-chain node. */
KEYCHAIN_KEY_NODE, /* Key-chain key node. */
NS_NODE, /* Logical-Router node. */
VRF_NODE, /* VRF mode node. */
INTERFACE_NODE, /* Interface mode node. */
ZEBRA_NODE, /* zebra connection node. */
@ -109,6 +110,7 @@ enum node_type
FORWARDING_NODE, /* IP forwarding node. */
PROTOCOL_NODE, /* protocol filtering node */
VTY_NODE, /* Vty node. */
LINK_PARAMS_NODE, /* Link-parameters node */
};
/* Node which has some commands and prompt string and configuration
@ -356,6 +358,10 @@ struct cmd_element
#define AREA_TAG_STR "[area tag]\n"
#define COMMUNITY_AANN_STR "Community number where AA and NN are (0-65535)\n"
#define COMMUNITY_VAL_STR "Community number in AA:NN format (where AA and NN are (0-65535)) or local-AS|no-advertise|no-export|internet or additive\n"
#define MPLS_TE_STR "MPLS-TE specific commands\n"
#define LINK_PARAMS_STR "Configure interface link parameters\n"
#define OSPF_RI_STR "OSPF Router Information specific commands\n"
#define PCE_STR "PCE Router Information specific commands\n"
#define CONF_BACKUP_EXT ".sav"

View File

@ -25,6 +25,11 @@
#include "if.h"
/* Filter direction. */
#define FILTER_IN 0
#define FILTER_OUT 1
#define FILTER_MAX 2
/* Filter type is made by `permit', `deny' and `dynamic'. */
enum filter_type
{

130
lib/if.c
View File

@ -205,6 +205,8 @@ if_delete (struct interface *ifp)
list_free (ifp->connected);
list_free (ifp->nbr_connected);
if_link_params_free (ifp);
XFREE (MTYPE_IF, ifp);
}
@ -226,41 +228,41 @@ if_add_hook (int type, int (*func)(struct interface *ifp))
/* Interface existance check by index. */
struct interface *
if_lookup_by_index_vrf (unsigned int index, vrf_id_t vrf_id)
if_lookup_by_index_vrf (ifindex_t ifindex, vrf_id_t vrf_id)
{
struct listnode *node;
struct interface *ifp;
for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
{
if (ifp->ifindex == index)
if (ifp->ifindex == ifindex)
return ifp;
}
return NULL;
}
struct interface *
if_lookup_by_index (unsigned int index)
if_lookup_by_index (ifindex_t ifindex)
{
return if_lookup_by_index_vrf (index, VRF_DEFAULT);
return if_lookup_by_index_vrf (ifindex, VRF_DEFAULT);
}
const char *
ifindex2ifname_vrf (unsigned int index, vrf_id_t vrf_id)
ifindex2ifname_vrf (ifindex_t ifindex, vrf_id_t vrf_id)
{
struct interface *ifp;
return ((ifp = if_lookup_by_index_vrf (index, vrf_id)) != NULL) ?
return ((ifp = if_lookup_by_index_vrf (ifindex, vrf_id)) != NULL) ?
ifp->name : "unknown";
}
const char *
ifindex2ifname (unsigned int index)
ifindex2ifname (ifindex_t ifindex)
{
return ifindex2ifname_vrf (index, VRF_DEFAULT);
return ifindex2ifname_vrf (ifindex, VRF_DEFAULT);
}
unsigned int
ifindex_t
ifname2ifindex_vrf (const char *name, vrf_id_t vrf_id)
{
struct interface *ifp;
@ -269,7 +271,7 @@ ifname2ifindex_vrf (const char *name, vrf_id_t vrf_id)
: IFINDEX_INTERNAL;
}
unsigned int
ifindex_t
ifname2ifindex (const char *name)
{
return ifname2ifindex_vrf (name, VRF_DEFAULT);
@ -1167,7 +1169,7 @@ connected_add_by_prefix (struct interface *ifp, struct prefix *p,
}
#ifndef HAVE_IF_NAMETOINDEX
unsigned int
ifindex_t
if_nametoindex (const char *name)
{
struct interface *ifp;
@ -1179,7 +1181,7 @@ if_nametoindex (const char *name)
#ifndef HAVE_IF_INDEXTONAME
char *
if_indextoname (unsigned int ifindex, char *name)
if_indextoname (ifindex_t ifindex, char *name)
{
struct interface *ifp;
@ -1244,7 +1246,7 @@ ifaddr_ipv4_delete (struct in_addr *ifaddr, struct interface *ifp)
/* Lookup interface by interface's IP address or interface index. */
static struct interface *
ifaddr_ipv4_lookup (struct in_addr *addr, unsigned int ifindex)
ifaddr_ipv4_lookup (struct in_addr *addr, ifindex_t ifindex)
{
struct prefix_ipv4 p;
struct route_node *rn;
@ -1304,3 +1306,105 @@ if_terminate (struct list **intf_list)
list_delete (*intf_list);
*intf_list = NULL;
}
const char *
if_link_type_str (enum zebra_link_type llt)
{
switch (llt)
{
#define llts(T,S) case (T): return (S)
llts(ZEBRA_LLT_UNKNOWN, "Unknown");
llts(ZEBRA_LLT_ETHER, "Ethernet");
llts(ZEBRA_LLT_EETHER, "Experimental Ethernet");
llts(ZEBRA_LLT_AX25, "AX.25 Level 2");
llts(ZEBRA_LLT_PRONET, "PROnet token ring");
llts(ZEBRA_LLT_IEEE802, "IEEE 802.2 Ethernet/TR/TB");
llts(ZEBRA_LLT_ARCNET, "ARCnet");
llts(ZEBRA_LLT_APPLETLK, "AppleTalk");
llts(ZEBRA_LLT_DLCI, "Frame Relay DLCI");
llts(ZEBRA_LLT_ATM, "ATM");
llts(ZEBRA_LLT_METRICOM, "Metricom STRIP");
llts(ZEBRA_LLT_IEEE1394, "IEEE 1394 IPv4");
llts(ZEBRA_LLT_EUI64, "EUI-64");
llts(ZEBRA_LLT_INFINIBAND, "InfiniBand");
llts(ZEBRA_LLT_SLIP, "SLIP");
llts(ZEBRA_LLT_CSLIP, "Compressed SLIP");
llts(ZEBRA_LLT_SLIP6, "SLIPv6");
llts(ZEBRA_LLT_CSLIP6, "Compressed SLIPv6");
llts(ZEBRA_LLT_ROSE, "ROSE packet radio");
llts(ZEBRA_LLT_X25, "CCITT X.25");
llts(ZEBRA_LLT_PPP, "PPP");
llts(ZEBRA_LLT_CHDLC, "Cisco HDLC");
llts(ZEBRA_LLT_RAWHDLC, "Raw HDLC");
llts(ZEBRA_LLT_LAPB, "LAPB");
llts(ZEBRA_LLT_IPIP, "IPIP Tunnel");
llts(ZEBRA_LLT_IPIP6, "IPIP6 Tunnel");
llts(ZEBRA_LLT_FRAD, "FRAD");
llts(ZEBRA_LLT_SKIP, "SKIP vif");
llts(ZEBRA_LLT_LOOPBACK, "Loopback");
llts(ZEBRA_LLT_LOCALTLK, "Localtalk");
llts(ZEBRA_LLT_FDDI, "FDDI");
llts(ZEBRA_LLT_SIT, "IPv6-in-IPv4 SIT");
llts(ZEBRA_LLT_IPDDP, "IP-in-DDP tunnel");
llts(ZEBRA_LLT_IPGRE, "GRE over IP");
llts(ZEBRA_LLT_PIMREG, "PIMSM registration");
llts(ZEBRA_LLT_HIPPI, "HiPPI");
llts(ZEBRA_LLT_IRDA, "IrDA");
llts(ZEBRA_LLT_FCPP, "Fibre-Channel PtP");
llts(ZEBRA_LLT_FCAL, "Fibre-Channel Arbitrated Loop");
llts(ZEBRA_LLT_FCPL, "Fibre-Channel Public Loop");
llts(ZEBRA_LLT_FCFABRIC, "Fibre-Channel Fabric");
llts(ZEBRA_LLT_IEEE802_TR, "IEEE 802.2 Token Ring");
llts(ZEBRA_LLT_IEEE80211, "IEEE 802.11");
llts(ZEBRA_LLT_IEEE80211_RADIOTAP, "IEEE 802.11 Radiotap");
llts(ZEBRA_LLT_IEEE802154, "IEEE 802.15.4");
llts(ZEBRA_LLT_IEEE802154_PHY, "IEEE 802.15.4 Phy");
default:
zlog_warn ("Unknown value %d", llt);
return "Unknown type!";
#undef llts
}
return NULL;
}
struct if_link_params *
if_link_params_get (struct interface *ifp)
{
int i;
if (ifp->link_params != NULL)
return ifp->link_params;
struct if_link_params *iflp = XCALLOC(MTYPE_IF_LINK_PARAMS,
sizeof (struct if_link_params));
if (iflp == NULL) return NULL;
/* Set TE metric == standard metric */
iflp->te_metric = ifp->metric;
/* Compute default bandwidth based on interface */
int bw = (float)((ifp->bandwidth ? ifp->bandwidth : DEFAULT_BANDWIDTH)
* TE_KILO_BIT / TE_BYTE);
/* Set Max, Reservable and Unreserved Bandwidth */
iflp->max_bw = bw;
iflp->max_rsv_bw = bw;
for (i = 0; i < MAX_CLASS_TYPE; i++)
iflp->unrsv_bw[i] = bw;
/* Update Link parameters status */
iflp->lp_status = LP_TE | LP_MAX_BW | LP_MAX_RSV_BW | LP_UNRSV_BW;
/* Finally attach newly created Link Parameters */
ifp->link_params = iflp;
return iflp;
}
void
if_link_params_free (struct interface *ifp)
{
if (ifp->link_params == NULL) return;
XFREE(MTYPE_IF_LINK_PARAMS, ifp->link_params);
ifp->link_params = NULL;
}

163
lib/if.h
View File

@ -21,8 +21,69 @@ Boston, MA 02111-1307, USA. */
#ifndef _ZEBRA_IF_H
#define _ZEBRA_IF_H
#include "zebra.h"
#include "linklist.h"
/* Interface link-layer type, if known. Derived from:
*
* net/if_arp.h on various platforms - Linux especially.
* http://www.iana.org/assignments/arp-parameters/arp-parameters.xhtml
*
* Some of the more obviously defunct technologies left out.
*/
enum zebra_link_type {
ZEBRA_LLT_UNKNOWN = 0,
ZEBRA_LLT_ETHER,
ZEBRA_LLT_EETHER,
ZEBRA_LLT_AX25,
ZEBRA_LLT_PRONET,
ZEBRA_LLT_IEEE802,
ZEBRA_LLT_ARCNET,
ZEBRA_LLT_APPLETLK,
ZEBRA_LLT_DLCI,
ZEBRA_LLT_ATM,
ZEBRA_LLT_METRICOM,
ZEBRA_LLT_IEEE1394,
ZEBRA_LLT_EUI64,
ZEBRA_LLT_INFINIBAND,
ZEBRA_LLT_SLIP,
ZEBRA_LLT_CSLIP,
ZEBRA_LLT_SLIP6,
ZEBRA_LLT_CSLIP6,
ZEBRA_LLT_RSRVD,
ZEBRA_LLT_ADAPT,
ZEBRA_LLT_ROSE,
ZEBRA_LLT_X25,
ZEBRA_LLT_PPP,
ZEBRA_LLT_CHDLC,
ZEBRA_LLT_LAPB,
ZEBRA_LLT_RAWHDLC,
ZEBRA_LLT_IPIP,
ZEBRA_LLT_IPIP6,
ZEBRA_LLT_FRAD,
ZEBRA_LLT_SKIP,
ZEBRA_LLT_LOOPBACK,
ZEBRA_LLT_LOCALTLK,
ZEBRA_LLT_FDDI,
ZEBRA_LLT_SIT,
ZEBRA_LLT_IPDDP,
ZEBRA_LLT_IPGRE,
ZEBRA_LLT_IP6GRE,
ZEBRA_LLT_PIMREG,
ZEBRA_LLT_HIPPI,
ZEBRA_LLT_ECONET,
ZEBRA_LLT_IRDA,
ZEBRA_LLT_FCPP,
ZEBRA_LLT_FCAL,
ZEBRA_LLT_FCPL,
ZEBRA_LLT_FCFABRIC,
ZEBRA_LLT_IEEE802_TR,
ZEBRA_LLT_IEEE80211,
ZEBRA_LLT_IEEE80211_RADIOTAP,
ZEBRA_LLT_IEEE802154,
ZEBRA_LLT_IEEE802154_PHY,
};
/*
Interface name length.
@ -36,6 +97,8 @@ Boston, MA 02111-1307, USA. */
#define INTERFACE_NAMSIZ 20
#define INTERFACE_HWADDR_MAX 20
typedef signed int ifindex_t;
#ifdef HAVE_PROC_NET_DEV
struct if_stats
{
@ -68,6 +131,63 @@ struct if_stats
};
#endif /* HAVE_PROC_NET_DEV */
/* Here are "non-official" architectural constants. */
#define TE_EXT_MASK 0x0FFFFFFF
#define TE_EXT_ANORMAL 0x80000000
#define LOSS_PRECISION 0.000003
#define TE_KILO_BIT 1000
#define TE_BYTE 8
#define DEFAULT_BANDWIDTH 10000
#define MAX_CLASS_TYPE 8
#define MAX_PKT_LOSS 50.331642
/* Link Parameters Status: 0: unset, 1: set, */
#define LP_UNSET 0x0000
#define LP_TE 0x0001
#define LP_MAX_BW 0x0002
#define LP_MAX_RSV_BW 0x0004
#define LP_UNRSV_BW 0x0008
#define LP_ADM_GRP 0x0010
#define LP_RMT_AS 0x0020
#define LP_DELAY 0x0040
#define LP_MM_DELAY 0x0080
#define LP_DELAY_VAR 0x0100
#define LP_PKT_LOSS 0x0200
#define LP_RES_BW 0x0400
#define LP_AVA_BW 0x0800
#define LP_USE_BW 0x1000
#define IS_PARAM_UNSET(lp, st) !(lp->lp_status & st)
#define IS_PARAM_SET(lp, st) (lp->lp_status & st)
#define IS_LINK_PARAMS_SET(lp) (lp->lp_status != LP_UNSET)
#define SET_PARAM(lp, st) (lp->lp_status) |= (st)
#define UNSET_PARAM(lp, st) (lp->lp_status) &= ~(st)
#define RESET_LINK_PARAM(lp) (lp->lp_status = LP_UNSET)
/* Link Parameters for Traffic Engineering */
struct if_link_params {
u_int32_t lp_status; /* Status of Link Parameters: */
u_int32_t te_metric; /* Traffic Engineering metric */
float max_bw; /* Maximum Bandwidth */
float max_rsv_bw; /* Maximum Reservable Bandwidth */
float unrsv_bw[MAX_CLASS_TYPE]; /* Unreserved Bandwidth per Class Type (8) */
u_int32_t admin_grp; /* Administrative group */
u_int32_t rmt_as; /* Remote AS number */
struct in_addr rmt_ip; /* Remote IP address */
u_int32_t av_delay; /* Link Average Delay */
u_int32_t min_delay; /* Link Min Delay */
u_int32_t max_delay; /* Link Max Delay */
u_int32_t delay_var; /* Link Delay Variation */
float pkt_loss; /* Link Packet Loss */
float res_bw; /* Residual Bandwidth */
float ava_bw; /* Available Bandwidth */
float use_bw; /* Utilized Bandwidth */
};
#define INTERFACE_LINK_PARAMS_SIZE sizeof(struct if_link_params)
#define HAS_LINK_PARAMS(ifp) ((ifp)->link_params != NULL)
/* Interface structure */
struct interface
{
@ -82,9 +202,9 @@ struct interface
/* Interface index (should be IFINDEX_INTERNAL for non-kernel or
deleted interfaces). */
unsigned int ifindex;
ifindex_t ifindex;
#define IFINDEX_INTERNAL 0
#define IFINDEX_DELETED UINT_MAX
#define IFINDEX_DELETED INT_MAX
/* Zebra internal interface status */
u_char status;
@ -103,24 +223,17 @@ struct interface
unsigned int mtu; /* IPv4 MTU */
unsigned int mtu6; /* IPv6 MTU - probably, but not neccessarily same as mtu */
/* Hardware address. */
#ifdef HAVE_STRUCT_SOCKADDR_DL
union {
/* note that sdl_storage is never accessed, it only exists to make space.
* all actual uses refer to sdl - but use sizeof(sdl_storage)! this fits
* best with C aliasing rules. */
struct sockaddr_dl sdl;
struct sockaddr_storage sdl_storage;
};
#else
unsigned short hw_type;
/* Link-layer information and hardware address */
enum zebra_link_type ll_type;
u_char hw_addr[INTERFACE_HWADDR_MAX];
int hw_addr_len;
#endif /* HAVE_STRUCT_SOCKADDR_DL */
/* interface bandwidth, kbits */
unsigned int bandwidth;
/* Link parameters for Traffic Engineering */
struct if_link_params *link_params;
/* description of the interface. */
char *desc;
@ -264,7 +377,7 @@ struct nbr_connected
/* Prototypes. */
extern int if_cmp_name_func (char *, char *);
extern struct interface *if_create (const char *name, int namelen);
extern struct interface *if_lookup_by_index (unsigned int);
extern struct interface *if_lookup_by_index (ifindex_t);
extern struct interface *if_lookup_exact_address (void *matchaddr, int family);
extern struct interface *if_lookup_address (void *matchaddr, int family);
extern struct interface *if_lookup_prefix (struct prefix *prefix);
@ -273,8 +386,7 @@ extern void if_update_vrf (struct interface *, const char *name, int namelen,
vrf_id_t vrf_id);
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_by_index_vrf (ifindex_t, 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,
@ -328,18 +440,19 @@ extern void if_init (struct list **);
extern void if_terminate (struct list **);
extern void if_dump_all (void);
extern const char *if_flag_dump(unsigned long);
extern const char *if_link_type_str (enum zebra_link_type);
/* Please use ifindex2ifname instead of if_indextoname where possible;
ifindex2ifname uses internal interface info, whereas if_indextoname must
make a system call. */
extern const char *ifindex2ifname (unsigned int);
extern const char *ifindex2ifname_vrf (unsigned int, vrf_id_t vrf_id);
extern const char *ifindex2ifname (ifindex_t);
extern const char *ifindex2ifname_vrf (ifindex_t, vrf_id_t vrf_id);
/* Please use ifname2ifindex instead of if_nametoindex where possible;
ifname2ifindex uses internal interface info, whereas if_nametoindex must
make a system call. */
extern unsigned int ifname2ifindex(const char *ifname);
extern unsigned int ifname2ifindex_vrf(const char *ifname, vrf_id_t vrf_id);
extern ifindex_t ifname2ifindex(const char *ifname);
extern ifindex_t ifname2ifindex_vrf(const char *ifname, vrf_id_t vrf_id);
/* Connected address functions. */
extern struct connected *connected_new (void);
@ -359,12 +472,16 @@ extern void nbr_connected_free (struct nbr_connected *);
struct nbr_connected *nbr_connected_check (struct interface *, struct prefix *);
#ifndef HAVE_IF_NAMETOINDEX
extern unsigned int if_nametoindex (const char *);
extern ifindex_t if_nametoindex (const char *);
#endif
#ifndef HAVE_IF_INDEXTONAME
extern char *if_indextoname (unsigned int, char *);
extern char *if_indextoname (ifindex_t, char *);
#endif
/* link parameters */
struct if_link_params *if_link_params_get (struct interface *);
void if_link_params_free (struct interface *);
/* Exported variables. */
extern struct cmd_element interface_desc_cmd;
extern struct cmd_element no_interface_desc_cmd;

View File

@ -122,7 +122,7 @@ listnode_add_sort (struct list *list, void *val)
list->count++;
}
void
struct listnode *
listnode_add_after (struct list *list, struct listnode *pp, void *val)
{
struct listnode *nn;
@ -157,6 +157,45 @@ listnode_add_after (struct list *list, struct listnode *pp, void *val)
pp->next = nn;
}
list->count++;
return nn;
}
struct listnode *
listnode_add_before (struct list *list, struct listnode *pp, void *val)
{
struct listnode *nn;
assert (val != NULL);
nn = listnode_new ();
nn->data = val;
if (pp == NULL)
{
if (list->tail)
list->tail->next = nn;
else
list->head = nn;
nn->prev = list->tail;
nn->next = pp;
list->tail = nn;
}
else
{
if (pp->prev)
pp->prev->next = nn;
else
list->head = nn;
nn->prev = pp->prev;
nn->next = pp;
pp->prev = nn;
}
list->count++;
return nn;
}
/* Move given listnode to tail of the list */
@ -266,52 +305,6 @@ list_delete_node (struct list *list, struct listnode *node)
listnode_free (node);
}
/* ospf_spf.c */
void
list_add_node_prev (struct list *list, struct listnode *current, void *val)
{
struct listnode *node;
assert (val != NULL);
node = listnode_new ();
node->next = current;
node->data = val;
if (current->prev == NULL)
list->head = node;
else
current->prev->next = node;
node->prev = current->prev;
current->prev = node;
list->count++;
}
/* ospf_spf.c */
void
list_add_node_next (struct list *list, struct listnode *current, void *val)
{
struct listnode *node;
assert (val != NULL);
node = listnode_new ();
node->prev = current;
node->data = val;
if (current->next == NULL)
list->tail = node;
else
current->next->prev = node;
node->next = current->next;
current->next = node;
list->count++;
}
/* ospf_spf.c */
void
list_add_list (struct list *l, struct list *m)

View File

@ -67,7 +67,8 @@ extern void list_free (struct list *);
extern void listnode_add (struct list *, void *);
extern void listnode_add_sort (struct list *, void *);
extern void listnode_add_after (struct list *, struct listnode *, void *);
extern struct listnode *listnode_add_after (struct list *, struct listnode *, void *);
extern struct listnode *listnode_add_before (struct list *, struct listnode *, void *);
extern void listnode_move_to_tail (struct list *, struct listnode *);
extern void listnode_delete (struct list *, void *);
extern struct listnode *listnode_lookup (struct list *, void *);
@ -80,8 +81,6 @@ extern void list_delete_all_node (struct list *);
extern void list_delete_node (struct list *, struct listnode *);
/* For ospf_spf.c */
extern void list_add_node_prev (struct list *, struct listnode *, void *);
extern void list_add_node_next (struct list *, struct listnode *, void *);
extern void list_add_list (struct list *, struct list *);
/* List iteration macro.

View File

@ -179,6 +179,7 @@ static void
vzlog (struct zlog *zl, int priority, const char *format, va_list args)
{
char proto_str[32];
int original_errno = errno;
struct timestamp_control tsctl;
tsctl.already_rendered = 0;
@ -197,6 +198,7 @@ vzlog (struct zlog *zl, int priority, const char *format, va_list args)
fflush (stderr);
/* In this case we return at here. */
errno = original_errno;
return;
}
tsctl.precision = zl->timestamp_precision;
@ -249,6 +251,8 @@ vzlog (struct zlog *zl, int priority, const char *format, va_list args)
if (priority <= zl->maxlvl[ZLOG_DEST_MONITOR])
vty_log ((zl->record_priority ? zlog_priority[priority] : NULL),
proto_str, format, &tsctl, args);
errno = original_errno;
}
static char *

View File

@ -80,9 +80,11 @@ zmalloc (int type, size_t size)
/*
* Allocate memory as in zmalloc, and also clear the memory.
* Add an extra 'z' prefix to function name to avoid collision when linking
* statically with zlib that exports the 'zcalloc' symbol.
*/
void *
zcalloc (int type, size_t size)
zzcalloc (int type, size_t size)
{
void *memory;
@ -97,9 +99,9 @@ zcalloc (int type, size_t size)
}
/*
* Given a pointer returned by zmalloc or zcalloc, free it and
* Given a pointer returned by zmalloc or zzcalloc, free it and
* return a pointer to a new size, basically acting like realloc().
* Requires: ptr was returned by zmalloc, zcalloc, or zrealloc with the
* Requires: ptr was returned by zmalloc, zzcalloc, or zrealloc with the
* same type.
* Effects: Returns a pointer to the new memory, or aborts.
*/
@ -109,7 +111,7 @@ zrealloc (int type, void *ptr, size_t size)
void *memory;
if (ptr == NULL) /* is really alloc */
return zcalloc(type, size);
return zzcalloc(type, size);
memory = realloc (ptr, size);
if (memory == NULL)
@ -122,7 +124,7 @@ zrealloc (int type, void *ptr, size_t size)
/*
* Free memory allocated by z*alloc or zstrdup.
* Requires: ptr was returned by zmalloc, zcalloc, or zrealloc with the
* Requires: ptr was returned by zmalloc, zzcalloc, or zrealloc with the
* same type.
* Effects: The memory is freed and may no longer be referenced.
*/
@ -196,7 +198,7 @@ mtype_zcalloc (const char *file, int line, int type, size_t size)
mstat[type].c_calloc++;
mstat[type].t_calloc++;
memory = zcalloc (type, size);
memory = zzcalloc (type, size);
mtype_log ("xcalloc", memory, file, line, type);
return memory;

View File

@ -56,7 +56,7 @@ extern struct mlist mlists[];
mtype_zstrdup (__FILE__, __LINE__, (mtype), (str))
#else
#define XMALLOC(mtype, size) zmalloc ((mtype), (size))
#define XCALLOC(mtype, size) zcalloc ((mtype), (size))
#define XCALLOC(mtype, size) zzcalloc ((mtype), (size))
#define XREALLOC(mtype, ptr, size) zrealloc ((mtype), (ptr), (size))
#define XFREE(mtype, ptr) do { \
zfree ((mtype), (ptr)); \
@ -67,7 +67,7 @@ extern struct mlist mlists[];
/* Prototypes of memory function. */
extern void *zmalloc (int type, size_t size);
extern void *zcalloc (int type, size_t size);
extern void *zzcalloc (int type, size_t size);
extern void *zrealloc (int type, void *ptr, size_t size);
extern void zfree (int type, void *ptr);
extern char *zstrdup (int type, const char *str);

View File

@ -77,6 +77,10 @@ struct memory_list memory_list_lib[] =
{ MTYPE_VRF, "VRF" },
{ MTYPE_VRF_NAME, "VRF name" },
{ MTYPE_VRF_BITMAP, "VRF bit-map" },
{ MTYPE_NS, "Logical-Router" },
{ MTYPE_NS_NAME, "Logical-Router Name" },
{ MTYPE_NS_BITMAP, "Logical-Router bit-map" },
{ MTYPE_IF_LINK_PARAMS, "Informational Link Parameters" },
{ -1, NULL },
};
@ -228,6 +232,8 @@ struct memory_list memory_list_ospf[] =
{ MTYPE_OSPF_IF_INFO, "OSPF if info" },
{ MTYPE_OSPF_IF_PARAMS, "OSPF if params" },
{ MTYPE_OSPF_MESSAGE, "OSPF message" },
{ MTYPE_OSPF_MPLS_TE, "OSPF MPLS parameters" },
{ MTYPE_OSPF_PCE_PARAMS, "OSPF PCE parameters" },
{ -1, NULL },
};
@ -269,6 +275,7 @@ struct memory_list memory_list_isis[] =
{ MTYPE_ISIS_NEXTHOP6, "ISIS nexthop6" },
{ MTYPE_ISIS_DICT, "ISIS dictionary" },
{ MTYPE_ISIS_DICT_NODE, "ISIS dictionary node" },
{ MTYPE_ISIS_MPLS_TE, "ISIS MPLS_TE parameters" },
{ -1, NULL },
};

View File

@ -93,3 +93,21 @@ set_nonblocking(int fd)
}
return 0;
}
float
htonf (float host)
{
u_int32_t lu1, lu2;
float convert;
memcpy (&lu1, &host, sizeof (u_int32_t));
lu2 = htonl (lu1);
memcpy (&convert, &lu2, sizeof (u_int32_t));
return convert;
}
float
ntohf (float net)
{
return htonf (net);
}

View File

@ -37,4 +37,7 @@ extern int set_nonblocking(int fd);
#define ERRNO_IO_RETRY(EN) \
(((EN) == EAGAIN) || ((EN) == EWOULDBLOCK) || ((EN) == EINTR))
extern float htonf (float);
extern float ntohf (float);
#endif /* _ZEBRA_NETWORK_H */

View File

@ -153,3 +153,36 @@ nexthops_free (struct nexthop *nexthop)
nexthop_free (nh);
}
}
const char *
nexthop2str (struct nexthop *nexthop, char *str, int size)
{
switch (nexthop->type)
{
case NEXTHOP_TYPE_IFINDEX:
snprintf (str, size, "if %u", nexthop->ifindex);
break;
case NEXTHOP_TYPE_IPV4:
snprintf (str, size, "%s", inet_ntoa (nexthop->gate.ipv4));
break;
case NEXTHOP_TYPE_IPV4_IFINDEX:
snprintf (str, size, "%s if %u",
inet_ntoa (nexthop->gate.ipv4), nexthop->ifindex);
break;
case NEXTHOP_TYPE_IPV6:
snprintf (str, size, "%s", inet6_ntoa (nexthop->gate.ipv6));
break;
case NEXTHOP_TYPE_IPV6_IFINDEX:
snprintf (str, size, "%s if %u",
inet6_ntoa (nexthop->gate.ipv6), nexthop->ifindex);
break;
case NEXTHOP_TYPE_BLACKHOLE:
snprintf (str, size, "blackhole");
break;
default:
snprintf (str, size, "unknown");
break;
}
return str;
}

View File

@ -26,6 +26,9 @@
#include "prefix.h"
/* Maximum next hop string length - gateway + ifindex */
#define NEXTHOP_STRLEN (INET6_ADDRSTRLEN + 30)
union g_addr {
struct in_addr ipv4;
struct in6_addr ipv6;
@ -48,7 +51,7 @@ struct nexthop
struct nexthop *prev;
/* Interface index. */
unsigned int ifindex;
ifindex_t ifindex;
enum nexthop_types_t type;
@ -97,4 +100,5 @@ void nexthops_free (struct nexthop *nexthop);
extern const char *nexthop_type_to_str (enum nexthop_types_t nh_type);
extern int nexthop_same_no_recurse (struct nexthop *next1, struct nexthop *next2);
extern const char * nexthop2str (struct nexthop *nexthop, char *str, int size);
#endif /*_LIB_NEXTHOP_H */

734
lib/ns.c Normal file
View File

@ -0,0 +1,734 @@
/*
* NS 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>
#ifdef HAVE_NETNS
#undef _GNU_SOURCE
#define _GNU_SOURCE
#include <sched.h>
#endif
#include "if.h"
#include "ns.h"
#include "prefix.h"
#include "table.h"
#include "log.h"
#include "memory.h"
#include "command.h"
#include "vty.h"
#ifndef CLONE_NEWNET
#define CLONE_NEWNET 0x40000000 /* New network namespace (lo, device, names sockets, etc) */
#endif
#ifndef HAVE_SETNS
static inline int setns(int fd, int nstype)
{
#ifdef __NR_setns
return syscall(__NR_setns, fd, nstype);
#else
errno = ENOSYS;
return -1;
#endif
}
#endif /* HAVE_SETNS */
#ifdef HAVE_NETNS
#define NS_DEFAULT_NAME "/proc/self/ns/net"
static int have_netns_enabled = -1;
#else /* !HAVE_NETNS */
#define NS_DEFAULT_NAME "Default-logical-router"
#endif /* HAVE_NETNS */
static int have_netns(void)
{
#ifdef HAVE_NETNS
if (have_netns_enabled < 0)
{
int fd = open (NS_DEFAULT_NAME, O_RDONLY);
if (fd < 0)
have_netns_enabled = 0;
else
{
have_netns_enabled = 1;
close(fd);
}
}
return have_netns_enabled;
#else
return 0;
#endif
}
struct ns
{
/* Identifier, same as the vector index */
ns_id_t ns_id;
/* Name */
char *name;
/* File descriptor */
int fd;
/* Master list of interfaces belonging to this NS */
struct list *iflist;
/* User data */
void *info;
};
/* Holding NS hooks */
struct ns_master
{
int (*ns_new_hook) (ns_id_t, void **);
int (*ns_delete_hook) (ns_id_t, void **);
int (*ns_enable_hook) (ns_id_t, void **);
int (*ns_disable_hook) (ns_id_t, void **);
} ns_master = {0,};
/* NS table */
struct route_table *ns_table = NULL;
static int ns_is_enabled (struct ns *ns);
static int ns_enable (struct ns *ns);
static void ns_disable (struct ns *ns);
/* Build the table key */
static void
ns_build_key (ns_id_t ns_id, struct prefix *p)
{
p->family = AF_INET;
p->prefixlen = IPV4_MAX_BITLEN;
p->u.prefix4.s_addr = ns_id;
}
/* Get a NS. If not found, create one. */
static struct ns *
ns_get (ns_id_t ns_id)
{
struct prefix p;
struct route_node *rn;
struct ns *ns;
ns_build_key (ns_id, &p);
rn = route_node_get (ns_table, &p);
if (rn->info)
{
ns = (struct ns *)rn->info;
route_unlock_node (rn); /* get */
return ns;
}
ns = XCALLOC (MTYPE_NS, sizeof (struct ns));
ns->ns_id = ns_id;
ns->fd = -1;
rn->info = ns;
/*
* Initialize interfaces.
*
* I'm not sure if this belongs here or in
* the vrf code.
*/
// if_init (&ns->iflist);
zlog_info ("NS %u is created.", ns_id);
if (ns_master.ns_new_hook)
(*ns_master.ns_new_hook) (ns_id, &ns->info);
return ns;
}
/* Delete a NS. This is called in ns_terminate(). */
static void
ns_delete (struct ns *ns)
{
zlog_info ("NS %u is to be deleted.", ns->ns_id);
ns_disable (ns);
if (ns_master.ns_delete_hook)
(*ns_master.ns_delete_hook) (ns->ns_id, &ns->info);
/*
* I'm not entirely sure if the vrf->iflist
* needs to be moved into here or not.
*/
//if_terminate (&ns->iflist);
if (ns->name)
XFREE (MTYPE_NS_NAME, ns->name);
XFREE (MTYPE_NS, ns);
}
/* Look up a NS by identifier. */
static struct ns *
ns_lookup (ns_id_t ns_id)
{
struct prefix p;
struct route_node *rn;
struct ns *ns = NULL;
ns_build_key (ns_id, &p);
rn = route_node_lookup (ns_table, &p);
if (rn)
{
ns = (struct ns *)rn->info;
route_unlock_node (rn); /* lookup */
}
return ns;
}
/*
* Check whether the NS is enabled - that is, whether the NS
* is ready to allocate resources. Currently there's only one
* type of resource: socket.
*/
static int
ns_is_enabled (struct ns *ns)
{
if (have_netns())
return ns && ns->fd >= 0;
else
return ns && ns->fd == -2 && ns->ns_id == NS_DEFAULT;
}
/*
* Enable a NS - that is, let the NS be ready to use.
* The NS_ENABLE_HOOK callback will be called to inform
* that they can allocate resources in this NS.
*
* RETURN: 1 - enabled successfully; otherwise, 0.
*/
static int
ns_enable (struct ns *ns)
{
if (!ns_is_enabled (ns))
{
if (have_netns()) {
ns->fd = open (ns->name, O_RDONLY);
} else {
ns->fd = -2; /* Remember that ns_enable_hook has been called */
errno = -ENOTSUP;
}
if (!ns_is_enabled (ns))
{
zlog_err ("Can not enable NS %u: %s!",
ns->ns_id, safe_strerror (errno));
return 0;
}
if (have_netns())
zlog_info ("NS %u is associated with NETNS %s.",
ns->ns_id, ns->name);
zlog_info ("NS %u is enabled.", ns->ns_id);
if (ns_master.ns_enable_hook)
(*ns_master.ns_enable_hook) (ns->ns_id, &ns->info);
}
return 1;
}
/*
* Disable a NS - that is, let the NS be unusable.
* The NS_DELETE_HOOK callback will be called to inform
* that they must release the resources in the NS.
*/
static void
ns_disable (struct ns *ns)
{
if (ns_is_enabled (ns))
{
zlog_info ("NS %u is to be disabled.", ns->ns_id);
if (ns_master.ns_disable_hook)
(*ns_master.ns_disable_hook) (ns->ns_id, &ns->info);
if (have_netns())
close (ns->fd);
ns->fd = -1;
}
}
/* Add a NS hook. Please add hooks before calling ns_init(). */
void
ns_add_hook (int type, int (*func)(ns_id_t, void **))
{
switch (type) {
case NS_NEW_HOOK:
ns_master.ns_new_hook = func;
break;
case NS_DELETE_HOOK:
ns_master.ns_delete_hook = func;
break;
case NS_ENABLE_HOOK:
ns_master.ns_enable_hook = func;
break;
case NS_DISABLE_HOOK:
ns_master.ns_disable_hook = func;
break;
default:
break;
}
}
/* Return the iterator of the first NS. */
ns_iter_t
ns_first (void)
{
struct route_node *rn;
for (rn = route_top (ns_table); rn; rn = route_next (rn))
if (rn->info)
{
route_unlock_node (rn); /* top/next */
return (ns_iter_t)rn;
}
return NS_ITER_INVALID;
}
/* Return the next NS iterator to the given iterator. */
ns_iter_t
ns_next (ns_iter_t iter)
{
struct route_node *rn = NULL;
/* Lock it first because route_next() will unlock it. */
if (iter != NS_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 (ns_iter_t)rn;
}
return NS_ITER_INVALID;
}
/* Return the NS iterator of the given NS ID. If it does not exist,
* the iterator of the next existing NS is returned. */
ns_iter_t
ns_iterator (ns_id_t ns_id)
{
struct prefix p;
struct route_node *rn;
ns_build_key (ns_id, &p);
rn = route_node_get (ns_table, &p);
if (rn->info)
{
/* OK, the NS exists. */
route_unlock_node (rn); /* get */
return (ns_iter_t)rn;
}
/* Find the next NS. */
for (rn = route_next (rn); rn; rn = route_next (rn))
if (rn->info)
{
route_unlock_node (rn); /* next */
return (ns_iter_t)rn;
}
return NS_ITER_INVALID;
}
/* Obtain the NS ID from the given NS iterator. */
ns_id_t
ns_iter2id (ns_iter_t iter)
{
struct route_node *rn = (struct route_node *) iter;
return (rn && rn->info) ? ((struct ns *)rn->info)->ns_id : NS_DEFAULT;
}
/* Obtain the data pointer from the given NS iterator. */
void *
ns_iter2info (ns_iter_t iter)
{
struct route_node *rn = (struct route_node *) iter;
return (rn && rn->info) ? ((struct ns *)rn->info)->info : NULL;
}
/* Obtain the interface list from the given NS iterator. */
struct list *
ns_iter2iflist (ns_iter_t iter)
{
struct route_node *rn = (struct route_node *) iter;
return (rn && rn->info) ? ((struct ns *)rn->info)->iflist : NULL;
}
/* Get the data pointer of the specified NS. If not found, create one. */
void *
ns_info_get (ns_id_t ns_id)
{
struct ns *ns = ns_get (ns_id);
return ns->info;
}
/* Look up the data pointer of the specified NS. */
void *
ns_info_lookup (ns_id_t ns_id)
{
struct ns *ns = ns_lookup (ns_id);
return ns ? ns->info : NULL;
}
/* Look up the interface list in a NS. */
struct list *
ns_iflist (ns_id_t ns_id)
{
struct ns * ns = ns_lookup (ns_id);
return ns ? ns->iflist : NULL;
}
/* Get the interface list of the specified NS. Create one if not find. */
struct list *
ns_iflist_get (ns_id_t ns_id)
{
struct ns * ns = ns_get (ns_id);
return ns->iflist;
}
/*
* NS bit-map
*/
#define NS_BITMAP_NUM_OF_GROUPS 8
#define NS_BITMAP_NUM_OF_BITS_IN_GROUP \
(UINT16_MAX / NS_BITMAP_NUM_OF_GROUPS)
#define NS_BITMAP_NUM_OF_BYTES_IN_GROUP \
(NS_BITMAP_NUM_OF_BITS_IN_GROUP / CHAR_BIT + 1) /* +1 for ensure */
#define NS_BITMAP_GROUP(_id) \
((_id) / NS_BITMAP_NUM_OF_BITS_IN_GROUP)
#define NS_BITMAP_BIT_OFFSET(_id) \
((_id) % NS_BITMAP_NUM_OF_BITS_IN_GROUP)
#define NS_BITMAP_INDEX_IN_GROUP(_bit_offset) \
((_bit_offset) / CHAR_BIT)
#define NS_BITMAP_FLAG(_bit_offset) \
(((u_char)1) << ((_bit_offset) % CHAR_BIT))
struct ns_bitmap
{
u_char *groups[NS_BITMAP_NUM_OF_GROUPS];
};
ns_bitmap_t
ns_bitmap_init (void)
{
return (ns_bitmap_t) XCALLOC (MTYPE_NS_BITMAP, sizeof (struct ns_bitmap));
}
void
ns_bitmap_free (ns_bitmap_t bmap)
{
struct ns_bitmap *bm = (struct ns_bitmap *) bmap;
int i;
if (bmap == NS_BITMAP_NULL)
return;
for (i = 0; i < NS_BITMAP_NUM_OF_GROUPS; i++)
if (bm->groups[i])
XFREE (MTYPE_NS_BITMAP, bm->groups[i]);
XFREE (MTYPE_NS_BITMAP, bm);
}
void
ns_bitmap_set (ns_bitmap_t bmap, ns_id_t ns_id)
{
struct ns_bitmap *bm = (struct ns_bitmap *) bmap;
u_char group = NS_BITMAP_GROUP (ns_id);
u_char offset = NS_BITMAP_BIT_OFFSET (ns_id);
if (bmap == NS_BITMAP_NULL)
return;
if (bm->groups[group] == NULL)
bm->groups[group] = XCALLOC (MTYPE_NS_BITMAP,
NS_BITMAP_NUM_OF_BYTES_IN_GROUP);
SET_FLAG (bm->groups[group][NS_BITMAP_INDEX_IN_GROUP (offset)],
NS_BITMAP_FLAG (offset));
}
void
ns_bitmap_unset (ns_bitmap_t bmap, ns_id_t ns_id)
{
struct ns_bitmap *bm = (struct ns_bitmap *) bmap;
u_char group = NS_BITMAP_GROUP (ns_id);
u_char offset = NS_BITMAP_BIT_OFFSET (ns_id);
if (bmap == NS_BITMAP_NULL || bm->groups[group] == NULL)
return;
UNSET_FLAG (bm->groups[group][NS_BITMAP_INDEX_IN_GROUP (offset)],
NS_BITMAP_FLAG (offset));
}
int
ns_bitmap_check (ns_bitmap_t bmap, ns_id_t ns_id)
{
struct ns_bitmap *bm = (struct ns_bitmap *) bmap;
u_char group = NS_BITMAP_GROUP (ns_id);
u_char offset = NS_BITMAP_BIT_OFFSET (ns_id);
if (bmap == NS_BITMAP_NULL || bm->groups[group] == NULL)
return 0;
return CHECK_FLAG (bm->groups[group][NS_BITMAP_INDEX_IN_GROUP (offset)],
NS_BITMAP_FLAG (offset)) ? 1 : 0;
}
/*
* NS realization with NETNS
*/
static char *
ns_netns_pathname (struct vty *vty, const char *name)
{
static char pathname[PATH_MAX];
char *result;
if (name[0] == '/') /* absolute pathname */
result = realpath (name, pathname);
else /* relevant pathname */
{
char tmp_name[PATH_MAX];
snprintf (tmp_name, PATH_MAX, "%s/%s", NS_RUN_DIR, name);
result = realpath (tmp_name, pathname);
}
if (! result)
{
vty_out (vty, "Invalid pathname: %s%s", safe_strerror (errno),
VTY_NEWLINE);
return NULL;
}
return pathname;
}
DEFUN (ns_netns,
ns_netns_cmd,
"logical-router <1-65535> ns NAME",
"Enable a logical-router\n"
"Specify the logical-router indentifier\n"
"The Name Space\n"
"The file name in " NS_RUN_DIR ", or a full pathname\n")
{
ns_id_t ns_id = NS_DEFAULT;
struct ns *ns = NULL;
char *pathname = ns_netns_pathname (vty, argv[1]);
if (!pathname)
return CMD_WARNING;
VTY_GET_INTEGER ("NS ID", ns_id, argv[0]);
ns = ns_get (ns_id);
if (ns->name && strcmp (ns->name, pathname) != 0)
{
vty_out (vty, "NS %u is already configured with NETNS %s%s",
ns->ns_id, ns->name, VTY_NEWLINE);
return CMD_WARNING;
}
if (!ns->name)
ns->name = XSTRDUP (MTYPE_NS_NAME, pathname);
if (!ns_enable (ns))
{
vty_out (vty, "Can not associate NS %u with NETNS %s%s",
ns->ns_id, ns->name, VTY_NEWLINE);
return CMD_WARNING;
}
return CMD_SUCCESS;
}
DEFUN (no_ns_netns,
no_ns_netns_cmd,
"no logical-router <1-65535> ns NAME",
NO_STR
"Enable a Logical-Router\n"
"Specify the Logical-Router identifier\n"
"The Name Space\n"
"The file name in " NS_RUN_DIR ", or a full pathname\n")
{
ns_id_t ns_id = NS_DEFAULT;
struct ns *ns = NULL;
char *pathname = ns_netns_pathname (vty, argv[1]);
if (!pathname)
return CMD_WARNING;
VTY_GET_INTEGER ("NS ID", ns_id, argv[0]);
ns = ns_lookup (ns_id);
if (!ns)
{
vty_out (vty, "NS %u is not found%s", ns_id, VTY_NEWLINE);
return CMD_SUCCESS;
}
if (ns->name && strcmp (ns->name, pathname) != 0)
{
vty_out (vty, "Incorrect NETNS file name%s", VTY_NEWLINE);
return CMD_WARNING;
}
ns_disable (ns);
if (ns->name)
{
XFREE (MTYPE_NS_NAME, ns->name);
ns->name = NULL;
}
return CMD_SUCCESS;
}
/* NS node. */
static struct cmd_node ns_node =
{
NS_NODE,
"", /* NS node has no interface. */
1
};
/* NS configuration write function. */
static int
ns_config_write (struct vty *vty)
{
struct route_node *rn;
struct ns *ns;
int write = 0;
for (rn = route_top (ns_table); rn; rn = route_next (rn))
if ((ns = rn->info) != NULL &&
ns->ns_id != NS_DEFAULT && ns->name)
{
vty_out (vty, "logical-router %u netns %s%s", ns->ns_id, ns->name, VTY_NEWLINE);
write++;
}
return write;
}
/* Initialize NS module. */
void
ns_init (void)
{
struct ns *default_ns;
/* Allocate NS table. */
ns_table = route_table_init ();
/* The default NS always exists. */
default_ns = ns_get (NS_DEFAULT);
if (!default_ns)
{
zlog_err ("ns_init: failed to create the default NS!");
exit (1);
}
/* Set the default NS name. */
default_ns->name = XSTRDUP (MTYPE_NS_NAME, NS_DEFAULT_NAME);
/* Enable the default NS. */
if (!ns_enable (default_ns))
{
zlog_err ("ns_init: failed to enable the default NS!");
exit (1);
}
if (have_netns())
{
/* Install NS commands. */
install_node (&ns_node, ns_config_write);
install_element (CONFIG_NODE, &ns_netns_cmd);
install_element (CONFIG_NODE, &no_ns_netns_cmd);
}
}
/* Terminate NS module. */
void
ns_terminate (void)
{
struct route_node *rn;
struct ns *ns;
for (rn = route_top (ns_table); rn; rn = route_next (rn))
if ((ns = rn->info) != NULL)
ns_delete (ns);
route_table_finish (ns_table);
ns_table = NULL;
}
/* Create a socket for the NS. */
int
ns_socket (int domain, int type, int protocol, ns_id_t ns_id)
{
struct ns *ns = ns_lookup (ns_id);
int ret = -1;
if (!ns_is_enabled (ns))
{
errno = ENOSYS;
return -1;
}
if (have_netns())
{
ret = (ns_id != NS_DEFAULT) ? setns (ns->fd, CLONE_NEWNET) : 0;
if (ret >= 0)
{
ret = socket (domain, type, protocol);
if (ns_id != NS_DEFAULT)
setns (ns_lookup (NS_DEFAULT)->fd, CLONE_NEWNET);
}
}
else
ret = socket (domain, type, protocol);
return ret;
}

142
lib/ns.h Normal file
View File

@ -0,0 +1,142 @@
/*
* NS 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_NS_H
#define _ZEBRA_NS_H
#include "linklist.h"
typedef u_int16_t ns_id_t;
/* The default NS ID */
#define NS_DEFAULT 0
/*
* The command strings
*/
#define NS_RUN_DIR "/var/run/netns"
#define NS_CMD_STR "logical-router <0-65535>"
#define NS_CMD_HELP_STR "Specify the Logical-Router\nThe Logical-Router ID\n"
#define NS_ALL_CMD_STR "logical-router all"
#define NS_ALL_CMD_HELP_STR "Specify the logical-router\nAll logical-router's\n"
/*
* NS hooks
*/
#define NS_NEW_HOOK 0 /* a new logical-router is just created */
#define NS_DELETE_HOOK 1 /* a logical-router is to be deleted */
#define NS_ENABLE_HOOK 2 /* a logical-router is ready to use */
#define NS_DISABLE_HOOK 3 /* a logical-router is to be unusable */
/*
* Add a specific hook ns module.
* @param1: hook type
* @param2: the callback function
* - param 1: the NS ID
* - param 2: the address of the user data pointer (the user data
* can be stored in or freed from there)
*/
extern void ns_add_hook (int, int (*)(ns_id_t, void **));
/*
* NS iteration
*/
typedef void * ns_iter_t;
#define NS_ITER_INVALID NULL /* invalid value of the iterator */
/*
* NS iteration utilities. Example for the usage:
*
* ns_iter_t iter = ns_first();
* for (; iter != NS_ITER_INVALID; iter = ns_next (iter))
*
* or
*
* ns_iter_t iter = ns_iterator (<a given NS ID>);
* for (; iter != NS_ITER_INVALID; iter = ns_next (iter))
*/
/* Return the iterator of the first NS. */
extern ns_iter_t ns_first (void);
/* Return the next NS iterator to the given iterator. */
extern ns_iter_t ns_next (ns_iter_t);
/* Return the NS iterator of the given NS ID. If it does not exist,
* the iterator of the next existing NS is returned. */
extern ns_iter_t ns_iterator (ns_id_t);
/*
* NS iterator to properties
*/
extern ns_id_t ns_iter2id (ns_iter_t);
extern void *ns_iter2info (ns_iter_t);
extern struct list *ns_iter2iflist (ns_iter_t);
/*
* Utilities to obtain the user data
*/
/* Get the data pointer of the specified NS. If not found, create one. */
extern void *ns_info_get (ns_id_t);
/* Look up the data pointer of the specified NS. */
extern void *ns_info_lookup (ns_id_t);
/*
* Utilities to obtain the interface list
*/
/* Look up the interface list of the specified NS. */
extern struct list *ns_iflist (ns_id_t);
/* Get the interface list of the specified NS. Create one if not find. */
extern struct list *ns_iflist_get (ns_id_t);
/*
* NS bit-map: maintaining flags, one bit per NS ID
*/
typedef void * ns_bitmap_t;
#define NS_BITMAP_NULL NULL
extern ns_bitmap_t ns_bitmap_init (void);
extern void ns_bitmap_free (ns_bitmap_t);
extern void ns_bitmap_set (ns_bitmap_t, ns_id_t);
extern void ns_bitmap_unset (ns_bitmap_t, ns_id_t);
extern int ns_bitmap_check (ns_bitmap_t, ns_id_t);
/*
* NS initializer/destructor
*/
/* Please add hooks before calling ns_init(). */
extern void ns_init (void);
extern void ns_terminate (void);
/*
* NS utilities
*/
/* Create a socket serving for the given NS */
extern int ns_socket (int, int, int, ns_id_t);
#endif /*_ZEBRA_NS_H*/

Some files were not shown because too many files have changed in this diff Show More