mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-11 11:21:07 +00:00
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:
commit
844ec28cee
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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. */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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 ();
|
||||
{
|
||||
bgp_terminate ();
|
||||
if (bgpd_privs.user) /* NULL if skip_runas flag set */
|
||||
zprivs_terminate (&bgpd_privs);
|
||||
}
|
||||
|
||||
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));
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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))
|
||||
return 0; /* default instance. */
|
||||
{
|
||||
*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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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"
|
||||
|
201
bgpd/bgp_route.c
201
bgpd/bgp_route.c
@ -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);
|
||||
{
|
||||
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 (debug)
|
||||
{
|
||||
if (new_select)
|
||||
bgp_info_path_with_addpath_rx_str (new_select, 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)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
for (ri = rn->info; (ri != NULL) && (nextri = ri->next, 1); ri = nextri)
|
||||
{
|
||||
|
||||
@ -1657,7 +1675,7 @@ bgp_best_selection (struct bgp *bgp, struct bgp_node *rn,
|
||||
if (debug)
|
||||
zlog_debug("%s: %s is the bestpath, add to the multipath list",
|
||||
pfx_buf, path_buf);
|
||||
bgp_mp_list_add (&mp_list, ri);
|
||||
bgp_mp_list_add (&mp_list, ri);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
@ -1856,7 +1925,10 @@ bgp_process_main (struct work_queue *wq, void *data)
|
||||
bgp_zebra_withdraw (p, old_select, safi);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 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");
|
||||
json_object_boolean_true_add(json_nexthop_ll, "used");
|
||||
|
||||
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",
|
||||
inet_ntop (AF_INET6, &attr->extra->mp_nexthop_local,
|
||||
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
|
||||
|
@ -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);
|
||||
|
@ -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}}
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
407
bgpd/bgp_vty.c
407
bgpd/bgp_vty.c
@ -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,17 +761,39 @@ DEFUN (no_router_bgp,
|
||||
struct bgp *bgp;
|
||||
const char *name = NULL;
|
||||
|
||||
VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
|
||||
|
||||
if (argc == 3)
|
||||
name = argv[2];
|
||||
|
||||
/* Lookup bgp structure. */
|
||||
bgp = bgp_lookup (as, name);
|
||||
if (! bgp)
|
||||
// "no router bgp" without an ASN
|
||||
if (argc < 1)
|
||||
{
|
||||
vty_out (vty, "%% Can't find BGP instance%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
//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)
|
||||
name = argv[2];
|
||||
|
||||
/* Lookup bgp structure. */
|
||||
bgp = bgp_lookup (as, name);
|
||||
if (! 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;
|
||||
|
||||
@ -822,32 +862,20 @@ 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
vty_out (vty, "%% Malformed BGP router identifier%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
if (! IPV4_ADDR_SAME (&bgp->router_id_static, &id))
|
||||
{
|
||||
vty_out (vty, "%% BGP router-id doesn't match%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
{
|
||||
vty_out (vty, "%% BGP router-id doesn't match%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
}
|
||||
|
||||
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,7 +2885,10 @@ 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);
|
||||
{
|
||||
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);
|
||||
|
119
bgpd/bgp_zebra.c
119
bgpd/bgp_zebra.c
@ -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;
|
||||
@ -1163,12 +1147,18 @@ 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)
|
||||
{
|
||||
/* Workaround for Cisco's nexthop bug. */
|
||||
if (IN6_IS_ADDR_UNSPECIFIED (&info->attr->extra->mp_nexthop_global)
|
||||
&& info->peer->su_remote->sa.sa_family == AF_INET6)
|
||||
nexthop = &info->peer->su_remote->sin6.sin6_addr;
|
||||
/* 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
|
||||
nexthop = &info->attr->extra->mp_nexthop_local;
|
||||
{
|
||||
/* Workaround for Cisco's nexthop bug. */
|
||||
if (IN6_IS_ADDR_UNSPECIFIED (&info->attr->extra->mp_nexthop_global)
|
||||
&& info->peer->su_remote->sa.sa_family == AF_INET6)
|
||||
nexthop = &info->peer->su_remote->sin6.sin6_addr;
|
||||
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,16 +1881,30 @@ 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;
|
||||
bgp_info_set_flag(rn, ri, BGP_INFO_ATTR_CHANGED);
|
||||
bgp_process(bgp, rn, afi, SAFI_UNICAST);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -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?
|
||||
*/
|
||||
|
@ -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 */
|
||||
|
190
bgpd/bgpd.c
190
bgpd/bgpd.c
@ -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);
|
||||
{
|
||||
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,18 +6417,21 @@ bgp_config_write_peer_global (struct vty *vty, struct bgp *bgp,
|
||||
VTY_NEWLINE);
|
||||
}
|
||||
|
||||
if (peer->as_type == AS_SPECIFIED)
|
||||
if (!if_ras_printed)
|
||||
{
|
||||
vty_out (vty, " neighbor %s remote-as %u%s", addr, peer->as,
|
||||
VTY_NEWLINE);
|
||||
}
|
||||
else if (peer->as_type == AS_INTERNAL)
|
||||
{
|
||||
vty_out (vty, " neighbor %s remote-as internal%s", addr, VTY_NEWLINE);
|
||||
}
|
||||
else if (peer->as_type == AS_EXTERNAL)
|
||||
{
|
||||
vty_out (vty, " neighbor %s remote-as external%s", addr, VTY_NEWLINE);
|
||||
if (peer->as_type == AS_SPECIFIED)
|
||||
{
|
||||
vty_out (vty, " neighbor %s remote-as %u%s", addr, peer->as,
|
||||
VTY_NEWLINE);
|
||||
}
|
||||
else if (peer->as_type == AS_INTERNAL)
|
||||
{
|
||||
vty_out (vty, " neighbor %s remote-as internal%s", addr, VTY_NEWLINE);
|
||||
}
|
||||
else if (peer->as_type == AS_EXTERNAL)
|
||||
{
|
||||
vty_out (vty, " neighbor %s remote-as external%s", addr, VTY_NEWLINE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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])
|
||||
{
|
||||
afi_header_vty_out (vty, afi, safi, write,
|
||||
" neighbor %s activate%s",
|
||||
addr, VTY_NEWLINE);
|
||||
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;
|
||||
|
22
bgpd/bgpd.h
22
bgpd/bgpd.h
@ -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 */
|
||||
|
119
configure.ac
119
configure.ac
@ -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_MSG_ERROR([lib json is needed to compile])
|
||||
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
|
||||
enable_user="quagga"
|
||||
elif test "${enable_user}" = "no"; then
|
||||
enable_user="root"
|
||||
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"
|
||||
fi
|
||||
AC_DEFINE_UNQUOTED(QUAGGA_USER, "${enable_user}", Quagga User)
|
||||
fi
|
||||
|
||||
if test "${enable_group}" = "yes" || test x"${enable_group}" = x""; then
|
||||
enable_group="quagga"
|
||||
elif test "${enable_group}" = "no"; then
|
||||
enable_group="root"
|
||||
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"
|
||||
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
|
||||
if test "${enable_ospfclient}" != "no";then
|
||||
OSPFCLIENT="ospfclient"
|
||||
fi
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(OSPFCLIENT, test "x$OSPFCLIENT" = "xospfclient")
|
||||
|
||||
case "${enable_ripngd}" in
|
||||
|
2
cumulus/etc/quagga/Quagga.conf
Normal file
2
cumulus/etc/quagga/Quagga.conf
Normal file
@ -0,0 +1,2 @@
|
||||
log file /var/log/quagga/quagga.log
|
||||
log timestamp precision 6
|
@ -1,3 +0,0 @@
|
||||
hostname bgpd
|
||||
log timestamp precision 6
|
||||
log file /var/log/quagga/bgpd.log
|
@ -1,3 +0,0 @@
|
||||
hostname ospfd
|
||||
log timestamp precision 6
|
||||
log file /var/log/quagga/ospf6d.log
|
@ -1,3 +0,0 @@
|
||||
hostname ospfd
|
||||
log timestamp precision 6
|
||||
log file /var/log/quagga/ospfd.log
|
@ -1,5 +0,0 @@
|
||||
hostname pimd
|
||||
password cn321
|
||||
enable password cn321
|
||||
log timestamp precision 6
|
||||
log file /var/log/quagga/pimd.log
|
@ -1,2 +0,0 @@
|
||||
hostname zebra
|
||||
log file /var/log/quagga/zebra.log
|
@ -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
10
debian/changelog
vendored
@ -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
|
||||
|
1
debian/quagga.install
vendored
1
debian/quagga.install
vendored
@ -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
3
debian/rules
vendored
@ -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
1
doc/.gitignore
vendored
@ -32,3 +32,4 @@ stamp-vti
|
||||
.arch-ids
|
||||
*~
|
||||
*.loT
|
||||
refix
|
||||
|
@ -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
|
||||
|
@ -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
432
doc/isisd.texi
Normal 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
|
@ -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
|
||||
|
||||
@ -74,18 +82,71 @@ Enable or disables multicast flag for the interface.
|
||||
|
||||
@deffn {Interface Command} {bandwidth <1-10000000>} {}
|
||||
@deffnx {Interface Command} {no bandwidth <1-10000000>} {}
|
||||
Set bandwidth value of the interface in kilobits/sec. This is for
|
||||
calculating OSPF cost. This command does not affect the actual device
|
||||
Set bandwidth value of the interface in kilobits/sec. This is for
|
||||
calculating OSPF cost. This command does not affect the actual device
|
||||
configuration.
|
||||
@end deffn
|
||||
|
||||
@deffn {Interface Command} {link-detect} {}
|
||||
@deffnx {Interface Command} {no link-detect} {}
|
||||
Enable/disable link-detect on platforms which support this. Currently
|
||||
Enable/disable link-detect on platforms which support this. Currently
|
||||
only Linux and Solaris, and only where network interface drivers support reporting
|
||||
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
|
||||
|
||||
@ -162,7 +223,7 @@ prevent traffic destined for a prefix to match less-specific routes (eg
|
||||
default) should the specified gateways not be reachable. Eg:
|
||||
|
||||
@example
|
||||
zebra> show ip route 10.0.0.0/8
|
||||
zebra> show ip route 10.0.0.0/8
|
||||
Routing entry for 10.0.0.0/8
|
||||
Known via "static", distance 1, metric 0
|
||||
10.0.0.2 inactive
|
||||
@ -182,7 +243,7 @@ These behave similarly to their ipv4 counterparts.
|
||||
@deffn Command {table @var{tableno}} {}
|
||||
Select the primary kernel routing table to be used. This only works
|
||||
for kernels supporting multiple routing tables (like GNU/Linux 2.2.x
|
||||
and later). After setting @var{tableno} with this command,
|
||||
and later). After setting @var{tableno} with this command,
|
||||
static routes defined after this are added to the specified table.
|
||||
@end deffn
|
||||
|
||||
@ -365,8 +426,8 @@ Display current routes which zebra holds in its database.
|
||||
|
||||
@example
|
||||
@group
|
||||
Router# show ip route
|
||||
Codes: K - kernel route, C - connected, S - static, R - RIP,
|
||||
Router# show ip route
|
||||
Codes: K - kernel route, C - connected, S - static, R - RIP,
|
||||
B - BGP * - FIB route.
|
||||
|
||||
K* 0.0.0.0/0 203.181.89.241
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
203
doc/ospfd.texi
203
doc/ospfd.texi
@ -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
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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 = \
|
||||
|
1716
isisd/isis_circuit.c
1716
isisd/isis_circuit.c
File diff suppressed because it is too large
Load Diff
@ -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 */
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
*/
|
||||
|
102
isisd/isis_lsp.c
102
isisd/isis_lsp.c
@ -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));
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
1369
isisd/isis_te.c
Normal file
File diff suppressed because it is too large
Load Diff
331
isisd/isis_te.h
Normal file
331
isisd/isis_te.h
Normal 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 */
|
@ -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;
|
||||
/* FIXME - subtlvs are handled here, for now we skip */
|
||||
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);
|
||||
|
@ -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
2428
isisd/isis_vty.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
|
1395
isisd/isisd.c
1395
isisd/isisd.c
File diff suppressed because it is too large
Load Diff
@ -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
1
lib/.gitignore
vendored
@ -19,3 +19,4 @@ route_types.h
|
||||
command_lex.c
|
||||
command_parse.c
|
||||
command_parse.h
|
||||
refix
|
||||
|
@ -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
|
||||
|
106
lib/agentx.c
106
lib/agentx.c
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
if (host.motdfile)
|
||||
XFREE (MTYPE_HOST, host.motdfile);
|
||||
host.motdfile = XSTRDUP (MTYPE_HOST, file);
|
||||
int success = CMD_SUCCESS;
|
||||
char p[PATH_MAX];
|
||||
char *rpath;
|
||||
char *in;
|
||||
|
||||
return CMD_SUCCESS;
|
||||
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 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));
|
||||
}
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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
130
lib/if.c
@ -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
163
lib/if.h
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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 *
|
||||
|
14
lib/memory.c
14
lib/memory.c
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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 },
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
734
lib/ns.c
Normal 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
142
lib/ns.h
Normal 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
Loading…
Reference in New Issue
Block a user