diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 08398192f3..fa941e8e6a 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -1144,8 +1144,7 @@ const u_int8_t attr_flags_values [] = { [BGP_ATTR_AS4_PATH] = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS, [BGP_ATTR_AS4_AGGREGATOR] = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS, }; -static const size_t attr_flags_values_max = - sizeof (attr_flags_values) / sizeof (attr_flags_values[0]); +static const size_t attr_flags_values_max = array_size(attr_flags_values) - 1; static int bgp_attr_flag_invalid (struct bgp_attr_parser_args *args) diff --git a/bgpd/bgp_clist.c b/bgpd/bgp_clist.c index 12c936b190..9032b1e2f4 100644 --- a/bgpd/bgp_clist.c +++ b/bgpd/bgp_clist.c @@ -403,17 +403,22 @@ community_str_get (struct community *com, int i) static int community_regexp_include (regex_t * reg, struct community *com, int i) { - const char *str; + char *str; + int rv; /* When there is no communities attribute it is treated as empty * string. */ if (com == NULL || com->size == 0) - str = ""; + str = XSTRDUP(MTYPE_COMMUNITY_STR, ""); else str = community_str_get (com, i); /* Regular expression match. */ - if (regexec (reg, str, 0, NULL, 0) == 0) + rv = regexec (reg, str, 0, NULL, 0); + + XFREE(MTYPE_COMMUNITY_STR, str); + + if (rv == 0) return 1; /* No match. */ diff --git a/bgpd/bgp_encap.c b/bgpd/bgp_encap.c index bb62e37134..499401bd4f 100644 --- a/bgpd/bgp_encap.c +++ b/bgpd/bgp_encap.c @@ -631,24 +631,23 @@ DEFUN (show_bgp_ipv4_encap_neighbor_routes, "Display routes learned from neighbor\n") { int idx_peer = 5; - union sockunion *su; + union sockunion su; struct peer *peer; - - su = sockunion_str2su (argv[idx_peer]->arg); - if (su == NULL) + + if (sockunion_str2su (argv[idx_peer]->arg)) { vty_out (vty, "Malformed address: %s%s", argv[idx_peer]->arg, VTY_NEWLINE); return CMD_WARNING; } - peer = peer_lookup (NULL, su); + peer = peer_lookup (NULL, &su); if (! peer || ! peer->afc[AFI_IP][SAFI_ENCAP]) { vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); return CMD_WARNING; } - return bgp_show_encap (vty, AFI_IP, NULL, bgp_show_type_neighbor, su, 0); + return bgp_show_encap (vty, AFI_IP, NULL, bgp_show_type_neighbor, &su, 0); } #ifdef HAVE_IPV6 DEFUN (show_bgp_ipv6_encap_neighbor_routes, @@ -663,24 +662,23 @@ DEFUN (show_bgp_ipv6_encap_neighbor_routes, "Display routes learned from neighbor\n") { int idx_peer = 5; - union sockunion *su; + union sockunion su; struct peer *peer; - su = sockunion_str2su (argv[idx_peer]->arg); - if (su == NULL) + if (str2sockunion(argv[idx_peer]->arg, &su)) { vty_out (vty, "Malformed address: %s%s", argv[idx_peer]->arg, VTY_NEWLINE); return CMD_WARNING; } - peer = peer_lookup (NULL, su); + peer = peer_lookup (NULL, &su); if (! peer || ! peer->afc[AFI_IP6][SAFI_ENCAP]) { vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); return CMD_WARNING; } - return bgp_show_encap (vty, AFI_IP6, NULL, bgp_show_type_neighbor, su, 0); + return bgp_show_encap (vty, AFI_IP6, NULL, bgp_show_type_neighbor, &su, 0); } #endif @@ -701,7 +699,7 @@ DEFUN (show_bgp_ipv4_encap_rd_neighbor_routes, int idx_rd = 5; int idx_peer = 7; int ret; - union sockunion *su; + union sockunion su; struct peer *peer; struct prefix_rd prd; @@ -712,21 +710,20 @@ DEFUN (show_bgp_ipv4_encap_rd_neighbor_routes, return CMD_WARNING; } - su = sockunion_str2su (argv[idx_peer]->arg); - if (su == NULL) + if (str2sockunion(argv[idx_peer]->arg, &su)) { vty_out (vty, "Malformed address: %s%s", argv[idx_peer]->arg, VTY_NEWLINE); return CMD_WARNING; } - peer = peer_lookup (NULL, su); + peer = peer_lookup (NULL, &su); if (! peer || ! peer->afc[AFI_IP][SAFI_ENCAP]) { vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); return CMD_WARNING; } - return bgp_show_encap (vty, AFI_IP, &prd, bgp_show_type_neighbor, su, 0); + return bgp_show_encap (vty, AFI_IP, &prd, bgp_show_type_neighbor, &su, 0); } #ifdef HAVE_IPV6 DEFUN (show_bgp_ipv6_encap_rd_neighbor_routes, @@ -746,7 +743,7 @@ DEFUN (show_bgp_ipv6_encap_rd_neighbor_routes, int idx_rd = 5; int idx_peer = 7; int ret; - union sockunion *su; + union sockunion su; struct peer *peer; struct prefix_rd prd; @@ -757,21 +754,20 @@ DEFUN (show_bgp_ipv6_encap_rd_neighbor_routes, return CMD_WARNING; } - su = sockunion_str2su (argv[idx_peer]->arg); - if (su == NULL) + if (str2sockunion(argv[idx_peer]->arg, &su)) { vty_out (vty, "Malformed address: %s%s", argv[idx_peer]->arg, VTY_NEWLINE); return CMD_WARNING; } - peer = peer_lookup (NULL, su); + peer = peer_lookup (NULL, &su); if (! peer || ! peer->afc[AFI_IP6][SAFI_ENCAP]) { vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); return CMD_WARNING; } - return bgp_show_encap (vty, AFI_IP6, &prd, bgp_show_type_neighbor, su, 0); + return bgp_show_encap (vty, AFI_IP6, &prd, bgp_show_type_neighbor, &su, 0); } #endif diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c index 3aa16b2632..50ca7eda4c 100644 --- a/bgpd/bgp_main.c +++ b/bgpd/bgp_main.c @@ -253,9 +253,6 @@ bgp_exit (int status) bgp_delete (bgp); list_free (bm->bgp); - /* reverse bgp_attr_init */ - bgp_attr_finish (); - /* reverse bgp_dump_init */ bgp_dump_finish (); @@ -265,6 +262,9 @@ bgp_exit (int status) /* cleanup route maps */ bgp_route_map_terminate(); + /* reverse bgp_attr_init */ + bgp_attr_finish (); + /* reverse access_list_init */ access_list_add_hook (NULL); access_list_delete_hook (NULL); diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index b03b296ea8..cfe4f8b7b4 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -8110,15 +8110,6 @@ DEFUN (show_ip_bgp_ipv4, if (strmatch(argv[idx]->text, "cidr-only")) return bgp_show (vty, bgp, afi, safi, bgp_show_type_cidr_only, NULL, uj); - else if (strmatch(argv[idx]->text, "dampening")) - { - if (strmatch(argv[idx + 1]->text, "dampened-paths")) - return bgp_show (vty, bgp, afi, safi, bgp_show_type_dampend_paths, NULL, uj); - - else if (strmatch(argv[idx + 1]->text, "flap-statistics")) - return bgp_show (vty, bgp, afi, safi, bgp_show_type_flap_statistics, NULL, uj); - } - else if (strmatch(argv[idx]->text, "dampened-paths")) return bgp_show (vty, bgp, afi, safi, bgp_show_type_dampend_paths, NULL, uj); @@ -8295,10 +8286,14 @@ DEFUN (show_ip_bgp_instance_all, return CMD_SUCCESS; } + static int bgp_show_regexp (struct vty *vty, int argc, struct cmd_token **argv, afi_t afi, safi_t safi, enum bgp_show_type type) { + return CMD_SUCCESS; +/* XXX(vtysh-grammar): Needs updating for new CLI backend. + int i; struct buffer *b; char *regstr; @@ -8338,6 +8333,7 @@ bgp_show_regexp (struct vty *vty, int argc, struct cmd_token **argv, afi_t afi, rc = bgp_show (vty, NULL, afi, safi, type, regex, 0); bgp_regex_free (regex); return rc; +*/ } static int @@ -9827,7 +9823,7 @@ DEFUN (show_ip_bgp_neighbor_routes, return bgp_show_neighbor_route (vty, peer, afi, safi, sh_type, uj); } -struct bgp_table *bgp_distance_table; +struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX]; struct bgp_distance { @@ -9855,12 +9851,17 @@ bgp_distance_set (struct vty *vty, const char *distance_str, const char *ip_str, const char *access_list_str) { int ret; - struct prefix_ipv4 p; + afi_t afi; + safi_t safi; + struct prefix p; u_char distance; struct bgp_node *rn; struct bgp_distance *bdistance; - ret = str2prefix_ipv4 (ip_str, &p); + afi = bgp_node_afi (vty); + safi = bgp_node_safi (vty); + + ret = str2prefix (ip_str, &p); if (ret == 0) { vty_out (vty, "Malformed prefix%s", VTY_NEWLINE); @@ -9870,7 +9871,7 @@ bgp_distance_set (struct vty *vty, const char *distance_str, distance = atoi (distance_str); /* Get BGP distance node. */ - rn = bgp_node_get (bgp_distance_table, (struct prefix *) &p); + rn = bgp_node_get (bgp_distance_table[afi][safi], (struct prefix *) &p); if (rn->info) { bdistance = rn->info; @@ -9902,19 +9903,24 @@ bgp_distance_unset (struct vty *vty, const char *distance_str, const char *ip_str, const char *access_list_str) { int ret; + afi_t afi; + safi_t safi; + struct prefix p; int distance; - struct prefix_ipv4 p; struct bgp_node *rn; struct bgp_distance *bdistance; - ret = str2prefix_ipv4 (ip_str, &p); + afi = bgp_node_afi (vty); + safi = bgp_node_safi (vty); + + ret = str2prefix (ip_str, &p); if (ret == 0) { vty_out (vty, "Malformed prefix%s", VTY_NEWLINE); return CMD_WARNING; } - rn = bgp_node_lookup (bgp_distance_table, (struct prefix *)&p); + rn = bgp_node_lookup (bgp_distance_table[afi][safi], (struct prefix *)&p); if (! rn) { vty_out (vty, "Can't find specified prefix%s", VTY_NEWLINE); @@ -9943,10 +9949,11 @@ bgp_distance_unset (struct vty *vty, const char *distance_str, /* Apply BGP information to distance method. */ u_char -bgp_distance_apply (struct prefix *p, struct bgp_info *rinfo, struct bgp *bgp) +bgp_distance_apply (struct prefix *p, struct bgp_info *rinfo, afi_t afi, + safi_t safi, struct bgp *bgp) { struct bgp_node *rn; - struct prefix_ipv4 q; + struct prefix q; struct peer *peer; struct bgp_distance *bdistance; struct access_list *alist; @@ -9955,21 +9962,11 @@ bgp_distance_apply (struct prefix *p, struct bgp_info *rinfo, struct bgp *bgp) if (! bgp) return 0; - if (p->family != AF_INET) - return 0; - peer = rinfo->peer; - if (peer->su.sa.sa_family != AF_INET) - return 0; - - memset (&q, 0, sizeof (struct prefix_ipv4)); - q.family = AF_INET; - q.prefix = peer->su.sin.sin_addr; - q.prefixlen = IPV4_MAX_BITLEN; - /* Check source address. */ - rn = bgp_node_match (bgp_distance_table, (struct prefix *) &q); + sockunion2hostprefix (&peer->su, &q); + rn = bgp_node_match (bgp_distance_table[afi][safi], &q); if (rn) { bdistance = rn->info; @@ -9977,7 +9974,7 @@ bgp_distance_apply (struct prefix *p, struct bgp_info *rinfo, struct bgp *bgp) if (bdistance->access_list) { - alist = access_list_lookup (AFI_IP, bdistance->access_list); + alist = access_list_lookup (afi, bdistance->access_list); if (alist && access_list_apply (alist, p) == FILTER_PERMIT) return bdistance->distance; } @@ -9986,7 +9983,7 @@ bgp_distance_apply (struct prefix *p, struct bgp_info *rinfo, struct bgp *bgp) } /* Backdoor check. */ - rn = bgp_node_lookup (bgp->route[AFI_IP][SAFI_UNICAST], p); + rn = bgp_node_lookup (bgp->route[afi][safi], p); if (rn) { bgp_static = rn->info; @@ -9994,8 +9991,8 @@ bgp_distance_apply (struct prefix *p, struct bgp_info *rinfo, struct bgp *bgp) if (bgp_static->backdoor) { - if (bgp->distance_local) - return bgp->distance_local; + if (bgp->distance_local[afi][safi]) + return bgp->distance_local[afi][safi]; else return ZEBRA_IBGP_DISTANCE_DEFAULT; } @@ -10003,14 +10000,14 @@ bgp_distance_apply (struct prefix *p, struct bgp_info *rinfo, struct bgp *bgp) if (peer->sort == BGP_PEER_EBGP) { - if (bgp->distance_ebgp) - return bgp->distance_ebgp; + if (bgp->distance_ebgp[afi][safi]) + return bgp->distance_ebgp[afi][safi]; return ZEBRA_EBGP_DISTANCE_DEFAULT; } else { - if (bgp->distance_ibgp) - return bgp->distance_ibgp; + if (bgp->distance_ibgp[afi][safi]) + return bgp->distance_ibgp[afi][safi]; return ZEBRA_IBGP_DISTANCE_DEFAULT; } } @@ -10028,12 +10025,16 @@ DEFUN (bgp_distance, int idx_number_2 = 3; int idx_number_3 = 4; struct bgp *bgp; + afi_t afi; + safi_t safi; bgp = vty->index; + afi = bgp_node_afi (vty); + safi = bgp_node_safi (vty); - bgp->distance_ebgp = atoi (argv[idx_number]->arg); - bgp->distance_ibgp = atoi (argv[idx_number_2]->arg); - bgp->distance_local = atoi (argv[idx_number_3]->arg); + bgp->distance_ebgp[afi][safi] = atoi (argv[idx_number]->arg); + bgp->distance_ibgp[afi][safi] = atoi (argv[idx_number_2]->arg); + bgp->distance_local[afi][safi] = atoi (argv[idx_number_3]->arg); return CMD_SUCCESS; } @@ -10048,12 +10049,16 @@ DEFUN (no_bgp_distance, "Distance for local routes\n") { struct bgp *bgp; + afi_t afi; + safi_t safi; bgp = vty->index; + afi = bgp_node_afi (vty); + safi = bgp_node_safi (vty); - bgp->distance_ebgp= 0; - bgp->distance_ibgp = 0; - bgp->distance_local = 0; + bgp->distance_ebgp[afi][safi] = 0; + bgp->distance_ibgp[afi][safi] = 0; + bgp->distance_local[afi][safi] = 0; return CMD_SUCCESS; } @@ -10116,6 +10121,54 @@ DEFUN (no_bgp_distance_source_access_list, return CMD_SUCCESS; } +DEFUN (ipv6_bgp_distance_source, + ipv6_bgp_distance_source_cmd, + "distance (1-255) X:X::X:X/M", + "Define an administrative distance\n" + "Administrative distance\n" + "IP source prefix\n") +{ + bgp_distance_set (vty, argv[1]->arg, argv[2]->arg, NULL); + return CMD_SUCCESS; +} + +DEFUN (no_ipv6_bgp_distance_source, + no_ipv6_bgp_distance_source_cmd, + "no distance (1-255) X:X::X:X/M", + NO_STR + "Define an administrative distance\n" + "Administrative distance\n" + "IP source prefix\n") +{ + bgp_distance_unset (vty, argv[2]->arg, argv[3]->arg, NULL); + return CMD_SUCCESS; +} + +DEFUN (ipv6_bgp_distance_source_access_list, + ipv6_bgp_distance_source_access_list_cmd, + "distance (1-255) X:X::X:X/M WORD", + "Define an administrative distance\n" + "Administrative distance\n" + "IP source prefix\n" + "Access list name\n") +{ + bgp_distance_set (vty, argv[1]->arg, argv[2]->arg, argv[3]->arg); + return CMD_SUCCESS; +} + +DEFUN (no_ipv6_bgp_distance_source_access_list, + no_ipv6_bgp_distance_source_access_list_cmd, + "no distance (1-255) X:X::X:X/M WORD", + NO_STR + "Define an administrative distance\n" + "Administrative distance\n" + "IP source prefix\n" + "Access list name\n") +{ + bgp_distance_unset (vty, argv[2]->arg, argv[3]->arg, argv[4]->arg); + return CMD_SUCCESS; +} + DEFUN (bgp_damp_set, bgp_damp_set_cmd, "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]", @@ -10484,40 +10537,53 @@ bgp_config_write_network (struct vty *vty, struct bgp *bgp, } int -bgp_config_write_distance (struct vty *vty, struct bgp *bgp) +bgp_config_write_distance (struct vty *vty, struct bgp *bgp, afi_t afi, + safi_t safi, int *write) { struct bgp_node *rn; struct bgp_distance *bdistance; /* Distance configuration. */ - if (bgp->distance_ebgp - && bgp->distance_ibgp - && bgp->distance_local - && (bgp->distance_ebgp != ZEBRA_EBGP_DISTANCE_DEFAULT - || bgp->distance_ibgp != ZEBRA_IBGP_DISTANCE_DEFAULT - || bgp->distance_local != ZEBRA_IBGP_DISTANCE_DEFAULT)) - vty_out (vty, " distance bgp %d %d %d%s", - bgp->distance_ebgp, bgp->distance_ibgp, bgp->distance_local, - VTY_NEWLINE); - - for (rn = bgp_table_top (bgp_distance_table); rn; rn = bgp_route_next (rn)) + if (bgp->distance_ebgp[afi][safi] + && bgp->distance_ibgp[afi][safi] + && bgp->distance_local[afi][safi] + && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT + || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT + || bgp->distance_local[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT)) + { + bgp_config_write_family_header (vty, afi, safi, write); + vty_out (vty, " distance bgp %d %d %d%s", + bgp->distance_ebgp[afi][safi], bgp->distance_ibgp[afi][safi], + bgp->distance_local[afi][safi], VTY_NEWLINE); + } + + for (rn = bgp_table_top (bgp_distance_table[afi][safi]); rn; + rn = bgp_route_next (rn)) if ((bdistance = rn->info) != NULL) { - vty_out (vty, " distance %d %s/%d %s%s", bdistance->distance, - inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen, + char buf[PREFIX_STRLEN]; + + bgp_config_write_family_header (vty, afi, safi, write); + vty_out (vty, " distance %d %s %s%s", bdistance->distance, + prefix2str (&rn->p, buf, sizeof (buf)), bdistance->access_list ? bdistance->access_list : "", VTY_NEWLINE); } - return 0; + return *write; } /* Allocate routing table structure and install commands. */ void bgp_route_init (void) { + afi_t afi; + safi_t safi; + /* Init BGP distance table. */ - bgp_distance_table = bgp_table_init (AFI_IP, SAFI_UNICAST); + for (afi = AFI_IP; afi < AFI_MAX; afi++) + for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) + bgp_distance_table[afi][safi] = bgp_table_init (afi, safi); /* IPv4 BGP commands. */ install_element (BGP_NODE, &bgp_table_map_cmd); @@ -10656,6 +10722,30 @@ bgp_route_init (void) install_element (BGP_NODE, &no_bgp_distance_source_cmd); install_element (BGP_NODE, &bgp_distance_source_access_list_cmd); install_element (BGP_NODE, &no_bgp_distance_source_access_list_cmd); + install_element (BGP_IPV4_NODE, &bgp_distance_cmd); + install_element (BGP_IPV4_NODE, &no_bgp_distance_cmd); + install_element (BGP_IPV4_NODE, &bgp_distance_source_cmd); + install_element (BGP_IPV4_NODE, &no_bgp_distance_source_cmd); + install_element (BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd); + install_element (BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd); + install_element (BGP_IPV4M_NODE, &bgp_distance_cmd); + install_element (BGP_IPV4M_NODE, &no_bgp_distance_cmd); + install_element (BGP_IPV4M_NODE, &bgp_distance_source_cmd); + install_element (BGP_IPV4M_NODE, &no_bgp_distance_source_cmd); + install_element (BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd); + install_element (BGP_IPV4M_NODE, &no_bgp_distance_source_access_list_cmd); + install_element (BGP_IPV6_NODE, &bgp_distance_cmd); + install_element (BGP_IPV6_NODE, &no_bgp_distance_cmd); + install_element (BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd); + install_element (BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd); + install_element (BGP_IPV6_NODE, &ipv6_bgp_distance_source_access_list_cmd); + install_element (BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_access_list_cmd); + install_element (BGP_IPV6M_NODE, &bgp_distance_cmd); + install_element (BGP_IPV6M_NODE, &no_bgp_distance_cmd); + install_element (BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd); + install_element (BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd); + install_element (BGP_IPV6M_NODE, &ipv6_bgp_distance_source_access_list_cmd); + install_element (BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_access_list_cmd); install_element (BGP_NODE, &bgp_damp_set_cmd); install_element (BGP_NODE, &bgp_damp_unset_cmd); @@ -10670,6 +10760,13 @@ bgp_route_init (void) void bgp_route_finish (void) { - bgp_table_unlock (bgp_distance_table); - bgp_distance_table = NULL; + afi_t afi; + safi_t safi; + + for (afi = AFI_IP; afi < AFI_MAX; afi++) + for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) + { + bgp_table_unlock (bgp_distance_table[afi][safi]); + bgp_distance_table[afi][safi] = NULL; + } } diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 0dce5da572..bb06204689 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -307,14 +307,14 @@ extern void bgp_add_eoiu_mark (struct bgp *); extern int bgp_config_write_table_map (struct vty *, struct bgp *, afi_t, safi_t, int *); extern int bgp_config_write_network (struct vty *, struct bgp *, afi_t, safi_t, int *); -extern int bgp_config_write_distance (struct vty *, struct bgp *); +extern int bgp_config_write_distance (struct vty *, struct bgp *, afi_t, safi_t, int *); extern void bgp_aggregate_increment (struct bgp *, struct prefix *, struct bgp_info *, afi_t, safi_t); extern void bgp_aggregate_decrement (struct bgp *, struct prefix *, struct bgp_info *, afi_t, safi_t); -extern u_char bgp_distance_apply (struct prefix *, struct bgp_info *, struct bgp *); +extern u_char bgp_distance_apply (struct prefix *, struct bgp_info *, afi_t, safi_t, struct bgp *); extern afi_t bgp_node_afi (struct vty *); extern safi_t bgp_node_safi (struct vty *); diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 6933611abd..1ddae3cd88 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -2268,7 +2268,6 @@ route_set_ipv6_nexthop_peer (void *rule, struct prefix *prefix, struct in6_addr peer_address; struct bgp_info *bgp_info; struct peer *peer; - char peer_addr_buf[INET6_ADDRSTRLEN]; if (type == RMAP_BGP) { @@ -2281,10 +2280,7 @@ route_set_ipv6_nexthop_peer (void *rule, struct prefix *prefix, && peer->su_remote && sockunion_family (peer->su_remote) == AF_INET6) { - inet_pton (AF_INET6, sockunion2str (peer->su_remote, - peer_addr_buf, - INET6_ADDRSTRLEN), - &peer_address); + peer_address = peer->su_remote->sin6.sin6_addr; /* Set next hop value and length in attribute. */ if (IN6_IS_ADDR_LINKLOCAL(&peer_address)) { diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 11e888d7e9..8ecd025397 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1367,8 +1367,7 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp, api.tag = tag; } - distance = bgp_distance_apply (p, info, bgp); - + distance = bgp_distance_apply (p, info, afi, safi, bgp); if (distance) { SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE); @@ -1554,6 +1553,13 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp, api.tag = tag; } + distance = bgp_distance_apply (p, info, afi, safi, bgp); + if (distance) + { + SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE); + api.distance = distance; + } + if (p->family == AF_INET) { if (bgp_debug_zebra(p)) diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 64ebbea6a6..0cb8e6bb9f 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -6193,7 +6193,6 @@ peer_clear_soft (struct peer *peer, afi_t afi, safi_t safi, } /* Display peer uptime.*/ -/* XXX: why does this function return char * when it takes buffer? */ char * peer_uptime (time_t uptime2, char *buf, size_t len, u_char use_json, json_object *json) { @@ -6216,7 +6215,10 @@ peer_uptime (time_t uptime2, char *buf, size_t len, u_char use_json, json_object if (uptime2 == 0) { if (use_json) - json_object_string_add(json, "peerUptime", "never"); + { + json_object_string_add(json, "peerUptime", "never"); + json_object_int_add(json, "peerUptimeMsec", 0); + } else snprintf (buf, len, "never"); return buf; @@ -6232,24 +6234,6 @@ peer_uptime (time_t uptime2, char *buf, size_t len, u_char use_json, json_object #define ONE_WEEK_SECOND ONE_DAY_SECOND*7 #define ONE_YEAR_SECOND ONE_DAY_SECOND*365 - if (use_json) - { - unsigned long time_store; - unsigned long sec_msec = 1000; - unsigned long minute_msec = sec_msec * 60; - unsigned long hour_msec = minute_msec * 60; - unsigned long day_msec = hour_msec * 24; - unsigned long year_msec = day_msec *365; - - time_store = - year_msec * tm->tm_year + - day_msec * tm->tm_yday + - hour_msec * tm->tm_hour + - minute_msec * tm->tm_min + - sec_msec * tm->tm_sec; - json_object_int_add(json, "peerUptimeMsec", time_store); - } - if (uptime1 < ONE_DAY_SECOND) snprintf (buf, len, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min, tm->tm_sec); @@ -6264,6 +6248,12 @@ peer_uptime (time_t uptime2, char *buf, size_t len, u_char use_json, json_object tm->tm_year - 70, tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7)); + if (use_json) + { + json_object_string_add(json, "peerUptime", buf); + json_object_long_add(json, "peerUptimeMsec", uptime1 * 1000); + } + return buf; } @@ -7123,6 +7113,8 @@ bgp_config_write_family (struct vty *vty, struct bgp *bgp, afi_t afi, struct peer_group *group; struct listnode *node, *nnode; + bgp_config_write_distance (vty, bgp, afi, safi, &write); + bgp_config_write_network (vty, bgp, afi, safi, &write); bgp_config_write_redistribute (vty, bgp, afi, safi, &write); @@ -7371,9 +7363,6 @@ bgp_config_write (struct vty *vty) bgp_config_write_peer_global (vty, bgp, peer); } - /* Distance configuration. */ - bgp_config_write_distance (vty, bgp); - /* listen range and limit for dynamic BGP neighbors */ bgp_config_write_listen (vty, bgp); diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index ee105201e8..f6e8598494 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -320,9 +320,9 @@ struct bgp #define RMAP_DEFAULT_ORIGINATE_EVAL_TIMER 5 /* BGP distance configuration. */ - u_char distance_ebgp; - u_char distance_ibgp; - u_char distance_local; + u_char distance_ebgp[AFI_MAX][SAFI_MAX]; + u_char distance_ibgp[AFI_MAX][SAFI_MAX]; + u_char distance_local[AFI_MAX][SAFI_MAX]; /* BGP default local-preference. */ u_int32_t default_local_pref; diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c index c66fa48263..c2b7ec7507 100644 --- a/isisd/isis_circuit.c +++ b/isisd/isis_circuit.c @@ -979,7 +979,7 @@ isis_circuit_print_vty (struct isis_circuit *circuit, struct vty *vty, vty_out(vty, " %s%s", buf, VTY_NEWLINE); } } - if (circuit->ipv6_link && listcount(circuit->ipv6_non_link) > 0) + if (circuit->ipv6_non_link && listcount(circuit->ipv6_non_link) > 0) { vty_out(vty, " IPv6 Prefixes:%s", VTY_NEWLINE); for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_non_link, node, ip_addr)) diff --git a/isisd/isis_routemap.c b/isisd/isis_routemap.c index 1d734fbc2f..61f3315f08 100644 --- a/isisd/isis_routemap.c +++ b/isisd/isis_routemap.c @@ -230,7 +230,7 @@ route_set_metric_compile(const char *arg) if (arg[0] == '\0' || *endp != '\0' || metric > MAX_WIDE_PATH_METRIC) return NULL; - ret = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(ret)); + ret = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(*ret)); *ret = metric; return ret; diff --git a/lib/command.c b/lib/command.c index 3416bcd1c7..f9c4107745 100644 --- a/lib/command.c +++ b/lib/command.c @@ -213,6 +213,18 @@ argv_find (struct cmd_token **argv, int argc, const char *text, int *index) return found; } +static unsigned int +cmd_hash_key (void *p) +{ + return (uintptr_t) p; +} + +static int +cmd_hash_cmp (const void *a, const void *b) +{ + return a == b; +} + /* Install top node of command vector. */ void install_node (struct cmd_node *node, @@ -225,6 +237,7 @@ install_node (struct cmd_node *node, // add start node struct cmd_token *token = new_cmd_token (START_TKN, NULL, NULL); graph_new_node (node->cmdgraph, token, (void (*)(void *)) &del_cmd_token); + node->cmd_hash = hash_create (cmd_hash_key, cmd_hash_cmp); } /* Breaking up string into each command piece. I assume given @@ -332,8 +345,12 @@ install_element (enum node_type ntype, struct cmd_element *cmd) /* cmd_init hasn't been called */ if (!cmdvec) - return; - + { + fprintf (stderr, "%s called before cmd_init, breakage likely\n", + __func__); + return; + } + cnode = vector_slot (cmdvec, ntype); if (cnode == NULL) @@ -342,19 +359,17 @@ install_element (enum node_type ntype, struct cmd_element *cmd) ntype); exit (EXIT_FAILURE); } - - // add node to command graph and command vector - // idiotic O(n) deduplication logic, should just use a merkle tree - for (unsigned int i = 0; i < vector_active (cnode->cmd_vector); i++) - { - struct cmd_element *existing = vector_slot (cnode->cmd_vector, i); - if (strmatch (existing->string, cmd->string)) + + if (hash_lookup (cnode->cmd_hash, cmd) != NULL) { - zlog_warn ("Duplicate command: %s\n", cmd->string); + fprintf (stderr, + "Multiple command installs to node %d of command:\n%s\n", + ntype, cmd->string); return; } - } - + + assert (hash_get (cnode->cmd_hash, cmd, hash_alloc_intern)); + command_parse_format (cnode->cmdgraph, cmd); vector_set (cnode->cmd_vector, cmd); @@ -2433,6 +2448,9 @@ cmd_terminate () // deleting the graph delets the cmd_element as well graph_delete_graph (cmd_node->cmdgraph); vector_free (cmd_node->cmd_vector); + hash_clean (cmd_node->cmd_hash, NULL); + hash_free (cmd_node->cmd_hash); + cmd_node->cmd_hash = NULL; } vector_free (cmdvec); diff --git a/lib/command.h b/lib/command.h index 0e2d27f19c..4d60c5b4fe 100644 --- a/lib/command.h +++ b/lib/command.h @@ -28,6 +28,7 @@ #include "lib/route_types.h" #include "graph.h" #include "memory.h" +#include "hash.h" DECLARE_MTYPE(HOST) @@ -152,6 +153,9 @@ struct cmd_node /* Vector of this node's command list. */ vector cmd_vector; + + /* Hashed index of command node list, for de-dupping primarily */ + struct hash *cmd_hash; }; /** diff --git a/lib/json.c b/lib/json.c index 1d22180e10..966d24f005 100644 --- a/lib/json.c +++ b/lib/json.c @@ -54,6 +54,12 @@ json_object_int_add(struct json_object* obj, const char *key, int32_t i) json_object_object_add(obj, key, json_object_new_int(i)); } +void +json_object_long_add(struct json_object* obj, const char *key, int64_t i) +{ + json_object_object_add(obj, key, json_object_new_int64(i)); +} + void json_object_boolean_false_add(struct json_object* obj, const char *key) { diff --git a/lib/json.h b/lib/json.h index e3d73d9d88..0ceffd4e8e 100644 --- a/lib/json.h +++ b/lib/json.h @@ -39,6 +39,8 @@ extern void json_object_string_add(struct json_object* obj, const char *key, const char *s); extern void json_object_int_add(struct json_object* obj, const char *key, int32_t i); +extern void json_object_long_add(struct json_object* obj, const char *key, + int64_t i); extern void json_object_boolean_false_add(struct json_object* obj, const char *key); extern void json_object_boolean_true_add(struct json_object* obj, diff --git a/ospf6d/ospf6_spf.c b/ospf6d/ospf6_spf.c index 67958be06c..df8925c453 100644 --- a/ospf6d/ospf6_spf.c +++ b/ospf6d/ospf6_spf.c @@ -444,7 +444,7 @@ void ospf6_spf_reason_string (unsigned int reason, char *buf, int size) if (!buf) return; - for (bit = 0; bit <= (sizeof(ospf6_spf_reason_str) / sizeof(char *)); bit++) + for (bit = 0; bit < array_size(ospf6_spf_reason_str); bit++) { if ((reason & (1 << bit)) && (len < size)) { diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c index 31cdbd3c5d..5471e58622 100644 --- a/ospf6d/ospf6_top.c +++ b/ospf6d/ospf6_top.c @@ -155,6 +155,8 @@ ospf6_create (void) o->ref_bandwidth = OSPF6_REFERENCE_BANDWIDTH; + o->distance_table = route_table_init (); + /* Enable "log-adjacency-changes" */ SET_FLAG(o->config_flags, OSPF6_LOG_ADJACENCY_CHANGES); @@ -184,6 +186,9 @@ ospf6_delete (struct ospf6 *o) ospf6_route_table_delete (o->external_table); route_table_finish (o->external_id_table); + ospf6_distance_reset (o); + route_table_finish (o->distance_table); + XFREE (MTYPE_OSPF6_TOP, o); } @@ -448,6 +453,213 @@ DEFUN (no_ospf6_timers_lsa, } +DEFUN (ospf6_distance, + ospf6_distance_cmd, + "distance (1-255)", + "Administrative distance\n" + "OSPF6 Administrative distance\n") +{ + struct ospf6 *o = vty->index; + + o->distance_all = atoi (argv[1]->arg); + + return CMD_SUCCESS; +} + +DEFUN (no_ospf6_distance, + no_ospf6_distance_cmd, + "no distance (1-255)", + NO_STR + "Administrative distance\n" + "OSPF6 Administrative distance\n") +{ + struct ospf6 *o = vty->index; + + o->distance_all = 0; + + return CMD_SUCCESS; +} + +DEFUN (ospf6_distance_ospf6, + ospf6_distance_ospf6_cmd, + "distance ospf6 ", + "Administrative distance\n" + "OSPF6 distance\n" + "Intra-area routes\n" + "Distance for intra-area routes\n" + "Inter-area routes\n" + "Distance for inter-area routes\n" + "External routes\n" + "Distance for external routes\n" + "Intra-area routes\n" + "Distance for intra-area routes\n" + "Inter-area routes\n" + "Distance for inter-area routes\n" + "External routes\n" + "Distance for external routes\n" + "Intra-area routes\n" + "Distance for intra-area routes\n" + "Inter-area routes\n" + "Distance for inter-area routes\n" + "External routes\n" + "Distance for external routes\n") +{ + struct ospf6 *o = vty->index; + + char *intra, *inter, *external; + intra = inter = external = NULL; + + int idx = 0; + if (argv_find (argv, argc, "intra-area", &idx)) + intra = argv[++idx]->arg; + if (argv_find (argv, argc, "intra-area", &idx)) + { + vty_out (vty, "%% Cannot specify intra-area distance twice%s", VTY_NEWLINE); + return CMD_WARNING; + } + + idx = 0; + if (argv_find (argv, argc, "inter-area", &idx)) + inter = argv[++idx]->arg; + if (argv_find (argv, argc, "inter-area", &idx)) + { + vty_out (vty, "%% Cannot specify inter-area distance twice%s", VTY_NEWLINE); + return CMD_WARNING; + } + + idx = 0; + if (argv_find (argv, argc, "external", &idx)) + external = argv[++idx]->arg; + if (argv_find (argv, argc, "external", &idx)) + { + vty_out (vty, "%% Cannot specify external distance twice%s", VTY_NEWLINE); + return CMD_WARNING; + } + + + if (intra) + o->distance_intra = atoi (intra); + + if (inter) + o->distance_inter = atoi (inter); + + if (external) + o->distance_external = atoi (external); + + return CMD_SUCCESS; +} + +DEFUN (no_ospf6_distance_ospf6, + no_ospf6_distance_ospf6_cmd, + "no distance ospf6 [ ]", + NO_STR + "Administrative distance\n" + "OSPF6 distance\n" + "Intra-area routes\n" + "Distance for intra-area routes\n" + "Inter-area routes\n" + "Distance for inter-area routes\n" + "External routes\n" + "Distance for external routes\n" + "Intra-area routes\n" + "Distance for intra-area routes\n" + "Inter-area routes\n" + "Distance for inter-area routes\n" + "External routes\n" + "Distance for external routes\n" + "Intra-area routes\n" + "Distance for intra-area routes\n" + "Inter-area routes\n" + "Distance for inter-area routes\n" + "External routes\n" + "Distance for external routes\n") +{ + struct ospf6 *o = vty->index; + + char *intra, *inter, *external; + intra = inter = external = NULL; + + if (argc == 3) + { + /* If no arguments are given, clear all distance information */ + o->distance_intra = 0; + o->distance_inter = 0; + o->distance_external = 0; + return CMD_SUCCESS; + } + + int idx = 0; + if (argv_find (argv, argc, "intra-area", &idx)) + intra = argv[++idx]->arg; + if (argv_find (argv, argc, "intra-area", &idx)) + { + vty_out (vty, "%% Cannot specify intra-area distance twice%s", VTY_NEWLINE); + return CMD_WARNING; + } + + idx = 0; + if (argv_find (argv, argc, "inter-area", &idx)) + inter = argv[++idx]->arg; + if (argv_find (argv, argc, "inter-area", &idx)) + { + vty_out (vty, "%% Cannot specify inter-area distance twice%s", VTY_NEWLINE); + return CMD_WARNING; + } + + idx = 0; + if (argv_find (argv, argc, "external", &idx)) + external = argv[++idx]->arg; + if (argv_find (argv, argc, "external", &idx)) + { + vty_out (vty, "%% Cannot specify external distance twice%s", VTY_NEWLINE); + return CMD_WARNING; + } + if (argc < 3) /* should not happen */ + return CMD_WARNING; + + if (intra) + o->distance_intra = 0; + + if (inter) + o->distance_inter = 0; + + if (external) + o->distance_external = 0; + + return CMD_SUCCESS; +} + +DEFUN (ospf6_distance_source, + ospf6_distance_source_cmd, + "distance (1-255) X:X::X:X/M [WORD]", + "Administrative distance\n" + "Distance value\n" + "IP source prefix\n" + "Access list name\n") +{ + struct ospf6 *o = vty->index; + char *alname = (argc == 4) ? argv[3]->arg : NULL; + ospf6_distance_set (vty, o, argv[1]->arg, argv[2]->arg, alname); + + return CMD_SUCCESS; +} + +DEFUN (no_ospf6_distance_source, + no_ospf6_distance_source_cmd, + "no distance (1-255) X:X::X:X/M [WORD]", + NO_STR + "Administrative distance\n" + "Distance value\n" + "IP source prefix\n" + "Access list name\n") +{ + struct ospf6 *o = vty->index; + char *alname = (argc == 5) ? argv[4]->arg : NULL; + ospf6_distance_unset (vty, o, argv[2]->arg, argv[3]->arg, alname); + + return CMD_SUCCESS; +} + DEFUN (ospf6_interface_area, ospf6_interface_area_cmd, "interface IFNAME area A.B.C.D", @@ -855,6 +1067,44 @@ ospf6_stub_router_config_write (struct vty *vty) return; } +static int +ospf6_distance_config_write (struct vty *vty) +{ + struct route_node *rn; + struct ospf6_distance *odistance; + + if (ospf6->distance_all) + vty_out (vty, " distance %u%s", ospf6->distance_all, VTY_NEWLINE); + + if (ospf6->distance_intra + || ospf6->distance_inter + || ospf6->distance_external) + { + vty_out (vty, " distance ospf6"); + + if (ospf6->distance_intra) + vty_out (vty, " intra-area %u", ospf6->distance_intra); + if (ospf6->distance_inter) + vty_out (vty, " inter-area %u", ospf6->distance_inter); + if (ospf6->distance_external) + vty_out (vty, " external %u", ospf6->distance_external); + + vty_out (vty, "%s", VTY_NEWLINE); + } + + for (rn = route_top (ospf6->distance_table); rn; rn = route_next (rn)) + if ((odistance = rn->info) != NULL) + { + char buf[PREFIX_STRLEN]; + + vty_out (vty, " distance %u %s %s%s", odistance->distance, + prefix2str (&rn->p, buf, sizeof (buf)), + odistance->access_list ? odistance->access_list : "", + VTY_NEWLINE); + } + return 0; +} + /* OSPF configuration write function. */ static int config_write_ospf6 (struct vty *vty) @@ -897,6 +1147,7 @@ config_write_ospf6 (struct vty *vty) ospf6_redistribute_config_write (vty); ospf6_area_config_write (vty); ospf6_spf_config_write (vty); + ospf6_distance_config_write (vty); for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, j, oa)) { @@ -953,6 +1204,13 @@ ospf6_top_init (void) install_element (OSPF6_NODE, &ospf6_stub_router_shutdown_cmd); install_element (OSPF6_NODE, &no_ospf6_stub_router_shutdown_cmd); */ + + install_element (OSPF6_NODE, &ospf6_distance_cmd); + install_element (OSPF6_NODE, &no_ospf6_distance_cmd); + install_element (OSPF6_NODE, &ospf6_distance_ospf6_cmd); + install_element (OSPF6_NODE, &no_ospf6_distance_ospf6_cmd); +#if 0 + install_element (OSPF6_NODE, &ospf6_distance_source_cmd); + install_element (OSPF6_NODE, &no_ospf6_distance_source_cmd); +#endif } - - diff --git a/ospf6d/ospf6_top.h b/ospf6d/ospf6_top.h index 518db3860c..8985eeaa28 100644 --- a/ospf6d/ospf6_top.h +++ b/ospf6d/ospf6_top.h @@ -85,6 +85,14 @@ struct ospf6 struct thread *maxage_remover; u_int32_t ref_bandwidth; + + /* Distance parameters */ + u_char distance_all; + u_char distance_intra; + u_char distance_inter; + u_char distance_external; + + struct route_table *distance_table; }; #define OSPF6_DISABLED 0x01 diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c index c3b8739532..a5303fb1b8 100644 --- a/ospf6d/ospf6_zebra.c +++ b/ospf6d/ospf6_zebra.c @@ -40,6 +40,8 @@ #include "ospf6_zebra.h" #include "ospf6d.h" +DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_DISTANCE, "OSPF6 distance") + unsigned char conf_debug_ospf6_zebra = 0; /* information about zebra. */ @@ -456,6 +458,10 @@ ospf6_zebra_route_update (int type, struct ospf6_route *request) } dest = (struct prefix_ipv6 *) &request->prefix; + + SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE); + api.distance = ospf6_distance_apply (dest, request); + if (type == REM) ret = zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, dest, &api); else @@ -640,6 +646,150 @@ DEFUN (no_redistribute_ospf6, return CMD_SUCCESS; } +static struct ospf6_distance * +ospf6_distance_new (void) +{ + return XCALLOC (MTYPE_OSPF6_DISTANCE, sizeof (struct ospf6_distance)); +} + +static void +ospf6_distance_free (struct ospf6_distance *odistance) +{ + XFREE (MTYPE_OSPF6_DISTANCE, odistance); +} + +int +ospf6_distance_set (struct vty *vty, struct ospf6 *o, + const char *distance_str, + const char *ip_str, + const char *access_list_str) +{ + int ret; + struct prefix_ipv6 p; + u_char distance; + struct route_node *rn; + struct ospf6_distance *odistance; + + ret = str2prefix_ipv6 (ip_str, &p); + if (ret == 0) + { + vty_out (vty, "Malformed prefix%s", VTY_NEWLINE); + return CMD_WARNING; + } + + distance = atoi (distance_str); + + /* Get OSPF6 distance node. */ + rn = route_node_get (o->distance_table, (struct prefix *) &p); + if (rn->info) + { + odistance = rn->info; + route_unlock_node (rn); + } + else + { + odistance = ospf6_distance_new (); + rn->info = odistance; + } + + /* Set distance value. */ + odistance->distance = distance; + + /* Reset access-list configuration. */ + if (odistance->access_list) + { + free (odistance->access_list); + odistance->access_list = NULL; + } + if (access_list_str) + odistance->access_list = strdup (access_list_str); + + return CMD_SUCCESS; +} + +int +ospf6_distance_unset (struct vty *vty, struct ospf6 *o, + const char *distance_str, + const char *ip_str, + const char *access_list_str) +{ + int ret; + struct prefix_ipv6 p; + struct route_node *rn; + struct ospf6_distance *odistance; + + ret = str2prefix_ipv6 (ip_str, &p); + if (ret == 0) + { + vty_out (vty, "Malformed prefix%s", VTY_NEWLINE); + return CMD_WARNING; + } + + rn = route_node_lookup (o->distance_table, (struct prefix *) &p); + if (!rn) + { + vty_out (vty, "Cant't find specified prefix%s", VTY_NEWLINE); + return CMD_WARNING; + } + + odistance = rn->info; + + if (odistance->access_list) + free (odistance->access_list); + ospf6_distance_free (odistance); + + rn->info = NULL; + route_unlock_node (rn); + route_unlock_node (rn); + + return CMD_SUCCESS; +} + +void +ospf6_distance_reset (struct ospf6 *o) +{ + struct route_node *rn; + struct ospf6_distance *odistance; + + for (rn = route_top (o->distance_table); rn; rn = route_next (rn)) + if ((odistance = rn->info) != NULL) + { + if (odistance->access_list) + free (odistance->access_list); + ospf6_distance_free (odistance); + rn->info = NULL; + route_unlock_node (rn); + } +} + +u_char +ospf6_distance_apply (struct prefix_ipv6 *p, struct ospf6_route *or) +{ + struct ospf6 *o; + + o = ospf6; + if (o == NULL) + return 0; + + if (o->distance_intra) + if (or->path.type == OSPF6_PATH_TYPE_INTRA) + return o->distance_intra; + + if (o->distance_inter) + if (or->path.type == OSPF6_PATH_TYPE_INTER) + return o->distance_inter; + + if (o->distance_external) + if(or->path.type == OSPF6_PATH_TYPE_EXTERNAL1 + || or->path.type == OSPF6_PATH_TYPE_EXTERNAL2) + return o->distance_external; + + if (o->distance_all) + return o->distance_all; + + return 0; +} + static void ospf6_zebra_connected (struct zclient *zclient) { diff --git a/ospf6d/ospf6_zebra.h b/ospf6d/ospf6_zebra.h index 5b28c07636..83032b64b1 100644 --- a/ospf6d/ospf6_zebra.h +++ b/ospf6d/ospf6_zebra.h @@ -35,6 +35,16 @@ extern unsigned char conf_debug_ospf6_zebra; #define IS_OSPF6_DEBUG_ZEBRA(e) \ (conf_debug_ospf6_zebra & OSPF6_DEBUG_ZEBRA_ ## e) +/* OSPF6 distance */ +struct ospf6_distance +{ + /* Distance value for the IP source prefix */ + u_char distance; + + /* Name of the access-list to be matched */ + char *access_list; +}; + extern struct zclient *zclient; extern void ospf6_zebra_route_update_add (struct ospf6_route *request); @@ -48,6 +58,15 @@ extern void ospf6_zebra_init (struct thread_master *); extern void ospf6_zebra_add_discard (struct ospf6_route *request); extern void ospf6_zebra_delete_discard (struct ospf6_route *request); +struct ospf6; +extern void ospf6_distance_reset (struct ospf6 *); +extern u_char ospf6_distance_apply (struct prefix_ipv6 *, struct ospf6_route *); + +extern int ospf6_distance_set (struct vty *, struct ospf6 *, const char *, + const char *, const char *); +extern int ospf6_distance_unset (struct vty *, struct ospf6 *, const char *, + const char *, const char *); + extern int config_write_ospf6_debug_zebra (struct vty *vty); extern void install_element_ospf6_debug_zebra (void); diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 8261a96a20..a447fbb35c 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -946,7 +946,7 @@ static int ospf_vl_set_timers (struct ospf_vl_data *vl_data, struct ospf_vl_config_data *vl_config) { - struct interface *ifp = ifp = vl_data->vl_oi->ifp; + struct interface *ifp = vl_data->vl_oi->ifp; /* Virtual Link data initialised to defaults, so only set if a value given */ if (vl_config->hello_interval) diff --git a/pimd/pim_static.c b/pimd/pim_static.c index c1154dc088..5882142b32 100644 --- a/pimd/pim_static.c +++ b/pimd/pim_static.c @@ -198,6 +198,10 @@ int pim_static_add(struct interface *iif, struct interface *oif, struct in_addr pim_static_route_free(s_route); } + if (original_s_route) { + pim_static_route_free(original_s_route); + } + return -1; } diff --git a/ripd/ripd.c b/ripd/ripd.c index 7b04368496..24ba74c73f 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -748,9 +748,9 @@ rip_packet_dump (struct rip_packet *packet, int size, const char *sndrcv) zlog_debug (" family 0x%X type %d (MD5 data)", ntohs (rte->family), ntohs (rte->tag)); zlog_debug (" MD5: %02X%02X%02X%02X%02X%02X%02X%02X" - "%02X%02X%02X%02X%02X%02X%02X", + "%02X%02X%02X%02X%02X%02X%02X%02X", p[0], p[1], p[2], p[3], p[4], p[5], p[6], - p[7], p[9], p[10], p[11], p[12], p[13], + p[7], p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); } else diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index 6eac461895..7a56d3802e 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -185,7 +185,8 @@ vtysh_client_run (struct vtysh_client *vclient, const char *line, FILE *fp) memmove (buf, eol, bufvalid - eol); bufvalid -= eol - buf; - end -= eol - buf; + if (end) + end -= eol - buf; } if (bufvalid == buf + bufsz)