From a80beece645358417219714d9362af64340eebef Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Tue, 19 May 2015 17:40:40 -0700 Subject: [PATCH] 'neighbor interface' config support in BGP including RA/Zebra changes. Signed-off-by: Vipin Kumar Reviewed-by: Pradosh Mohapatra Dinesh Dutt --- bgpd/bgp_fsm.c | 6 + bgpd/bgp_network.c | 20 ++- bgpd/bgp_route.c | 350 +++++++++++++++++++++++++--------------- bgpd/bgp_vty.c | 388 +++++++++++++++++++++++++++++++-------------- bgpd/bgp_zebra.c | 118 +++++++++++++- bgpd/bgpd.c | 146 ++++++++++++++--- bgpd/bgpd.h | 22 ++- lib/command.h | 3 +- lib/if.c | 58 +++++++ lib/if.h | 16 ++ lib/log.c | 2 + lib/memtypes.c | 2 + lib/zclient.c | 83 ++++++++++ lib/zclient.h | 3 + lib/zebra.h | 4 +- zebra/interface.c | 20 +++ zebra/rtadv.c | 79 ++++++++- zebra/zserv.c | 145 +++++++++++++++++ zebra/zserv.h | 3 + 19 files changed, 1173 insertions(+), 295 deletions(-) diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index 062392166..35037fd37 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -970,6 +970,10 @@ bgp_stop (struct peer *peer) peer_delete(peer); ret = -1; } + else + { + bgp_peer_conf_if_to_su_update(peer); + } return ret; } @@ -1058,6 +1062,8 @@ bgp_start (struct peer *peer) { int status; + bgp_peer_conf_if_to_su_update(peer); + if (BGP_PEER_START_SUPPRESSED (peer)) { if (BGP_DEBUG (fsm, FSM)) diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c index e9d557b74..87ec784b3 100644 --- a/bgpd/bgp_network.c +++ b/bgpd/bgp_network.c @@ -276,7 +276,7 @@ bgp_accept (struct thread *thread) bgp_set_socket_ttl (peer1, bgp_sock); - peer = peer_create (&su, peer1->bgp, peer1->local_as, + peer = peer_create (&su, peer1->conf_if, peer1->bgp, peer1->local_as, peer1->as, 0, 0); peer_xfer_config(peer, peer1); @@ -318,11 +318,14 @@ bgp_bind (struct peer *peer) #ifdef SO_BINDTODEVICE int ret; struct ifreq ifreq; + char *name; - if (! peer->ifname) + if (! peer->ifname && !peer->conf_if) return 0; - strncpy ((char *)&ifreq.ifr_name, peer->ifname, sizeof (ifreq.ifr_name)); + name = (peer->conf_if ? peer->conf_if : peer->ifname); + + strncpy ((char *)&ifreq.ifr_name, name, sizeof (ifreq.ifr_name)); if ( bgpd_privs.change (ZPRIVS_RAISE) ) zlog_err ("bgp_bind: could not raise privs"); @@ -335,7 +338,7 @@ bgp_bind (struct peer *peer) if (ret < 0) { - zlog (peer->log, LOG_INFO, "bind to interface %s failed", peer->ifname); + zlog (peer->log, LOG_INFO, "bind to interface %s failed", name); return ret; } #endif /* SO_BINDTODEVICE */ @@ -406,6 +409,11 @@ bgp_connect (struct peer *peer) { unsigned int ifindex = 0; + if (peer->conf_if && BGP_PEER_SU_UNSPEC(peer)) + { + zlog_debug("Peer address not learnt: Returning from connect"); + return 0; + } /* Make socket for the peer. */ peer->fd = sockunion_socket (&peer->su); if (peer->fd < 0) @@ -444,8 +452,8 @@ bgp_connect (struct peer *peer) bgp_update_source (peer); #ifdef HAVE_IPV6 - if (peer->ifname) - ifindex = if_nametoindex (peer->ifname); + if (peer->conf_if || peer->ifname) + ifindex = if_nametoindex (peer->conf_if ? peer->conf_if : peer->ifname); #endif /* HAVE_IPV6 */ if (BGP_DEBUG (events, EVENTS)) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index ce15125ed..baa3087b2 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -9475,8 +9475,13 @@ peer_lookup_in_view (struct vty *vty, const char *view_name, ret = str2sockunion (ip_str, &su); if (ret < 0) { - vty_out (vty, "Malformed address: %s%s", ip_str, VTY_NEWLINE); - return NULL; + peer = peer_lookup_by_conf_if (bgp, ip_str); + if (!peer) + { + vty_out (vty, "%% Malformed address or name: %s%s", ip_str, VTY_NEWLINE); + return NULL; + } + return peer; } /* Peer structure lookup. */ @@ -9985,13 +9990,14 @@ bgp_peer_counts (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi) DEFUN (show_ip_bgp_neighbor_prefix_counts, show_ip_bgp_neighbor_prefix_counts_cmd, - "show ip bgp neighbors (A.B.C.D|X:X::X:X) prefix-counts", + "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) prefix-counts", SHOW_STR IP_STR BGP_STR "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display detailed prefix count information\n") { struct peer *peer; @@ -10005,13 +10011,14 @@ DEFUN (show_ip_bgp_neighbor_prefix_counts, DEFUN (show_bgp_ipv6_neighbor_prefix_counts, show_bgp_ipv6_neighbor_prefix_counts_cmd, - "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X) prefix-counts", + "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) prefix-counts", SHOW_STR BGP_STR "Address family\n" "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display detailed prefix count information\n") { struct peer *peer; @@ -10025,7 +10032,7 @@ DEFUN (show_bgp_ipv6_neighbor_prefix_counts, DEFUN (show_ip_bgp_ipv4_neighbor_prefix_counts, show_ip_bgp_ipv4_neighbor_prefix_counts_cmd, - "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X) prefix-counts", + "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X|WORD) prefix-counts", SHOW_STR IP_STR BGP_STR @@ -10035,6 +10042,7 @@ DEFUN (show_ip_bgp_ipv4_neighbor_prefix_counts, "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display detailed prefix count information\n") { struct peer *peer; @@ -10051,7 +10059,7 @@ DEFUN (show_ip_bgp_ipv4_neighbor_prefix_counts, DEFUN (show_ip_bgp_vpnv4_neighbor_prefix_counts, show_ip_bgp_vpnv4_neighbor_prefix_counts_cmd, - "show ip bgp vpnv4 all neighbors (A.B.C.D|X:X::X:X) prefix-counts", + "show ip bgp vpnv4 all neighbors (A.B.C.D|X:X::X:X|WORD) prefix-counts", SHOW_STR IP_STR BGP_STR @@ -10061,6 +10069,7 @@ DEFUN (show_ip_bgp_vpnv4_neighbor_prefix_counts, "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display detailed prefix count information\n") { struct peer *peer; @@ -10195,7 +10204,7 @@ peer_adj_routes (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi, DEFUN (show_ip_bgp_view_neighbor_advertised_route, show_ip_bgp_view_neighbor_advertised_route_cmd, - "show ip bgp view WORD neighbors (A.B.C.D|X:X::X:X) advertised-routes", + "show ip bgp view WORD neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes", SHOW_STR IP_STR BGP_STR @@ -10221,18 +10230,19 @@ DEFUN (show_ip_bgp_view_neighbor_advertised_route, ALIAS (show_ip_bgp_view_neighbor_advertised_route, show_ip_bgp_neighbor_advertised_route_cmd, - "show ip bgp neighbors (A.B.C.D|X:X::X:X) advertised-routes", + "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes", SHOW_STR IP_STR BGP_STR "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display the routes advertised to a BGP neighbor\n") DEFUN (show_ip_bgp_neighbor_advertised_route_csv, show_ip_bgp_neighbor_advertised_route_csv_cmd, - "show ip bgp neighbors (A.B.C.D|X:X::X:X) advertised-routes csv", + "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes csv", SHOW_STR IP_STR BGP_STR @@ -10241,6 +10251,7 @@ DEFUN (show_ip_bgp_neighbor_advertised_route_csv, "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display the routes advertised to a BGP neighbor\n") { struct peer *peer; @@ -10258,7 +10269,7 @@ DEFUN (show_ip_bgp_neighbor_advertised_route_csv, DEFUN (show_ip_bgp_ipv4_neighbor_advertised_route, show_ip_bgp_ipv4_neighbor_advertised_route_cmd, - "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X) advertised-routes", + "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes", SHOW_STR IP_STR BGP_STR @@ -10268,6 +10279,7 @@ DEFUN (show_ip_bgp_ipv4_neighbor_advertised_route, "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display the routes advertised to a BGP neighbor\n") { struct peer *peer; @@ -10285,7 +10297,7 @@ DEFUN (show_ip_bgp_ipv4_neighbor_advertised_route, #ifdef HAVE_IPV6 DEFUN (show_bgp_view_neighbor_advertised_route, show_bgp_view_neighbor_advertised_route_cmd, - "show bgp view WORD neighbors (A.B.C.D|X:X::X:X) advertised-routes", + "show bgp view WORD neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes", SHOW_STR BGP_STR "BGP view\n" @@ -10293,6 +10305,7 @@ DEFUN (show_bgp_view_neighbor_advertised_route, "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display the routes advertised to a BGP neighbor\n") { struct peer *peer; @@ -10310,7 +10323,7 @@ DEFUN (show_bgp_view_neighbor_advertised_route, DEFUN (show_bgp_view_neighbor_advertised_route_csv, show_bgp_view_neighbor_advertised_route_csv_cmd, - "show bgp view WORD neighbors (A.B.C.D|X:X::X:X) advertised-routes csv", + "show bgp view WORD neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes csv", SHOW_STR BGP_STR "BGP view\n" @@ -10318,6 +10331,7 @@ DEFUN (show_bgp_view_neighbor_advertised_route_csv, "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display the routes advertised to a BGP neighbor\n") { struct peer *peer; @@ -10335,7 +10349,7 @@ DEFUN (show_bgp_view_neighbor_advertised_route_csv, ALIAS (show_bgp_view_neighbor_advertised_route, show_bgp_view_ipv6_neighbor_advertised_route_cmd, - "show bgp view WORD ipv6 neighbors (A.B.C.D|X:X::X:X) advertised-routes", + "show bgp view WORD ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes", SHOW_STR BGP_STR "BGP view\n" @@ -10344,11 +10358,12 @@ ALIAS (show_bgp_view_neighbor_advertised_route, "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display the routes advertised to a BGP neighbor\n") ALIAS (show_bgp_view_neighbor_advertised_route_csv, show_bgp_view_ipv6_neighbor_advertised_route_csv_cmd, - "show bgp view WORD ipv6 neighbors (A.B.C.D|X:X::X:X) advertised-routes csv", + "show bgp view WORD ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes csv", SHOW_STR BGP_STR "BGP view\n" @@ -10357,11 +10372,12 @@ ALIAS (show_bgp_view_neighbor_advertised_route_csv, "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display the routes advertised to a BGP neighbor\n") DEFUN (show_bgp_view_neighbor_received_routes, show_bgp_view_neighbor_received_routes_cmd, - "show bgp view WORD neighbors (A.B.C.D|X:X::X:X) received-routes", + "show bgp view WORD neighbors (A.B.C.D|X:X::X:X|WORD) received-routes", SHOW_STR BGP_STR "BGP view\n" @@ -10369,6 +10385,7 @@ DEFUN (show_bgp_view_neighbor_received_routes, "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display the received routes from neighbor\n") { struct peer *peer; @@ -10386,7 +10403,7 @@ DEFUN (show_bgp_view_neighbor_received_routes, ALIAS (show_bgp_view_neighbor_received_routes, show_bgp_view_ipv6_neighbor_received_routes_cmd, - "show bgp view WORD ipv6 neighbors (A.B.C.D|X:X::X:X) received-routes", + "show bgp view WORD ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) received-routes", SHOW_STR BGP_STR "BGP view\n" @@ -10395,72 +10412,80 @@ ALIAS (show_bgp_view_neighbor_received_routes, "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display the received routes from neighbor\n") ALIAS (show_bgp_view_neighbor_advertised_route, show_bgp_neighbor_advertised_route_cmd, - "show bgp neighbors (A.B.C.D|X:X::X:X) advertised-routes", + "show bgp neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes", SHOW_STR BGP_STR "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display the routes advertised to a BGP neighbor\n") ALIAS (show_bgp_view_neighbor_advertised_route, show_bgp_ipv6_neighbor_advertised_route_cmd, - "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X) advertised-routes", + "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes", SHOW_STR BGP_STR "Address family\n" "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display the routes advertised to a BGP neighbor\n") ALIAS (show_bgp_view_neighbor_advertised_route_csv, show_bgp_neighbor_advertised_route_csv_cmd, - "show bgp neighbors (A.B.C.D|X:X::X:X) advertised-routes csv", + "show bgp neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes csv", SHOW_STR BGP_STR "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display the routes advertised to a BGP neighbor\n") ALIAS (show_bgp_view_neighbor_advertised_route_csv, show_bgp_ipv6_neighbor_advertised_route_csv_cmd, - "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X) advertised-routes csv", + "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes csv", SHOW_STR BGP_STR "Address family\n" "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display the routes advertised to a BGP neighbor\n") /* old command */ ALIAS (show_bgp_view_neighbor_advertised_route, ipv6_bgp_neighbor_advertised_route_cmd, - "show ipv6 bgp neighbors (A.B.C.D|X:X::X:X) advertised-routes", + "show ipv6 bgp neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes", SHOW_STR IPV6_STR BGP_STR "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display the routes advertised to a BGP neighbor\n") /* old command */ DEFUN (ipv6_mbgp_neighbor_advertised_route, ipv6_mbgp_neighbor_advertised_route_cmd, - "show ipv6 mbgp neighbors (A.B.C.D|X:X::X:X) advertised-routes", + "show ipv6 mbgp neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes", SHOW_STR IPV6_STR MBGP_STR "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" + "Neighbor on bgp configured interface\n" "Display the routes advertised to a BGP neighbor\n") { struct peer *peer; @@ -10475,7 +10500,7 @@ DEFUN (ipv6_mbgp_neighbor_advertised_route, DEFUN (show_ip_bgp_view_neighbor_received_routes, show_ip_bgp_view_neighbor_received_routes_cmd, - "show ip bgp view WORD neighbors (A.B.C.D|X:X::X:X) received-routes", + "show ip bgp view WORD neighbors (A.B.C.D|X:X::X:X|WORD) received-routes", SHOW_STR IP_STR BGP_STR @@ -10484,6 +10509,7 @@ DEFUN (show_ip_bgp_view_neighbor_received_routes, "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display the received routes from neighbor\n") { struct peer *peer; @@ -10501,18 +10527,19 @@ DEFUN (show_ip_bgp_view_neighbor_received_routes, ALIAS (show_ip_bgp_view_neighbor_received_routes, show_ip_bgp_neighbor_received_routes_cmd, - "show ip bgp neighbors (A.B.C.D|X:X::X:X) received-routes", + "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) received-routes", SHOW_STR IP_STR BGP_STR "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display the received routes from neighbor\n") DEFUN (show_ip_bgp_ipv4_neighbor_received_routes, show_ip_bgp_ipv4_neighbor_received_routes_cmd, - "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X) received-routes", + "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X|WORD) received-routes", SHOW_STR IP_STR BGP_STR @@ -10522,6 +10549,7 @@ DEFUN (show_ip_bgp_ipv4_neighbor_received_routes, "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display the received routes from neighbor\n") { struct peer *peer; @@ -10539,9 +10567,9 @@ DEFUN (show_ip_bgp_ipv4_neighbor_received_routes, DEFUN (show_bgp_view_afi_safi_neighbor_adv_recd_routes, show_bgp_view_afi_safi_neighbor_adv_recd_routes_cmd, #ifdef HAVE_IPV6 - "show bgp view WORD (ipv4|ipv6) (unicast|multicast) neighbors (A.B.C.D|X:X::X:X) (advertised-routes|received-routes)", + "show bgp view WORD (ipv4|ipv6) (unicast|multicast) neighbors (A.B.C.D|X:X::X:X|WORD) (advertised-routes|received-routes)", #else - "show bgp view WORD ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X) (advertised-routes|received-routes)", + "show bgp view WORD ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X|WORD) (advertised-routes|received-routes)", #endif SHOW_STR BGP_STR @@ -10556,6 +10584,7 @@ DEFUN (show_bgp_view_afi_safi_neighbor_adv_recd_routes, "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display the advertised routes to neighbor\n" "Display the received routes from neighbor\n") { @@ -10588,13 +10617,14 @@ DEFUN (show_bgp_view_afi_safi_neighbor_adv_recd_routes, DEFUN (show_ip_bgp_neighbor_received_prefix_filter, show_ip_bgp_neighbor_received_prefix_filter_cmd, - "show ip bgp neighbors (A.B.C.D|X:X::X:X) received prefix-filter", + "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) received prefix-filter", SHOW_STR IP_STR BGP_STR "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display information received from a BGP neighbor\n" "Display the prefixlist filter\n") { @@ -10606,13 +10636,19 @@ DEFUN (show_ip_bgp_neighbor_received_prefix_filter, ret = str2sockunion (argv[0], &su); if (ret < 0) { - vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE); - return CMD_WARNING; + peer = peer_lookup_by_conf_if (NULL, argv[0]); + if (!peer) + { + vty_out (vty, "Malformed address or name: %s%s", argv[0], VTY_NEWLINE); + return CMD_WARNING; + } + } + else + { + peer = peer_lookup (NULL, &su); + if (! peer) + return CMD_WARNING; } - - peer = peer_lookup (NULL, &su); - if (! peer) - return CMD_WARNING; sprintf (name, "%s.%d.%d", peer->host, AFI_IP, SAFI_UNICAST); count = prefix_bgp_show_prefix_list (NULL, AFI_IP, name); @@ -10627,7 +10663,7 @@ DEFUN (show_ip_bgp_neighbor_received_prefix_filter, DEFUN (show_ip_bgp_ipv4_neighbor_received_prefix_filter, show_ip_bgp_ipv4_neighbor_received_prefix_filter_cmd, - "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X) received prefix-filter", + "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X|WORD) received prefix-filter", SHOW_STR IP_STR BGP_STR @@ -10637,6 +10673,7 @@ DEFUN (show_ip_bgp_ipv4_neighbor_received_prefix_filter, "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display information received from a BGP neighbor\n" "Display the prefixlist filter\n") { @@ -10648,13 +10685,19 @@ DEFUN (show_ip_bgp_ipv4_neighbor_received_prefix_filter, ret = str2sockunion (argv[1], &su); if (ret < 0) { - vty_out (vty, "Malformed address: %s%s", argv[1], VTY_NEWLINE); - return CMD_WARNING; + peer = peer_lookup_by_conf_if (NULL, argv[1]); + if (!peer) + { + vty_out (vty, "Malformed address or name: %s%s", argv[1], VTY_NEWLINE); + return CMD_WARNING; + } + } + else + { + peer = peer_lookup (NULL, &su); + if (! peer) + return CMD_WARNING; } - - peer = peer_lookup (NULL, &su); - if (! peer) - return CMD_WARNING; if (strncmp (argv[0], "m", 1) == 0) { @@ -10684,33 +10727,36 @@ DEFUN (show_ip_bgp_ipv4_neighbor_received_prefix_filter, #ifdef HAVE_IPV6 ALIAS (show_bgp_view_neighbor_received_routes, show_bgp_neighbor_received_routes_cmd, - "show bgp neighbors (A.B.C.D|X:X::X:X) received-routes", + "show bgp neighbors (A.B.C.D|X:X::X:X|WORD) received-routes", SHOW_STR BGP_STR "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display the received routes from neighbor\n") ALIAS (show_bgp_view_neighbor_received_routes, show_bgp_ipv6_neighbor_received_routes_cmd, - "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X) received-routes", + "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) received-routes", SHOW_STR BGP_STR "Address family\n" "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display the received routes from neighbor\n") DEFUN (show_bgp_neighbor_received_prefix_filter, show_bgp_neighbor_received_prefix_filter_cmd, - "show bgp neighbors (A.B.C.D|X:X::X:X) received prefix-filter", + "show bgp neighbors (A.B.C.D|X:X::X:X|WORD) received prefix-filter", SHOW_STR BGP_STR "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display information received from a BGP neighbor\n" "Display the prefixlist filter\n") { @@ -10722,13 +10768,19 @@ DEFUN (show_bgp_neighbor_received_prefix_filter, ret = str2sockunion (argv[0], &su); if (ret < 0) { - vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE); - return CMD_WARNING; + peer = peer_lookup_by_conf_if (NULL, argv[0]); + if (!peer) + { + vty_out (vty, "Malformed address or name: %s%s", argv[0], VTY_NEWLINE); + return CMD_WARNING; + } + } + else + { + peer = peer_lookup (NULL, &su); + if (! peer) + return CMD_WARNING; } - - peer = peer_lookup (NULL, &su); - if (! peer) - return CMD_WARNING; sprintf (name, "%s.%d.%d", peer->host, AFI_IP6, SAFI_UNICAST); count = prefix_bgp_show_prefix_list (NULL, AFI_IP6, name); @@ -10743,38 +10795,41 @@ DEFUN (show_bgp_neighbor_received_prefix_filter, ALIAS (show_bgp_neighbor_received_prefix_filter, show_bgp_ipv6_neighbor_received_prefix_filter_cmd, - "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X) received prefix-filter", + "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) received prefix-filter", SHOW_STR BGP_STR "Address family\n" "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display information received from a BGP neighbor\n" "Display the prefixlist filter\n") /* old command */ ALIAS (show_bgp_view_neighbor_received_routes, ipv6_bgp_neighbor_received_routes_cmd, - "show ipv6 bgp neighbors (A.B.C.D|X:X::X:X) received-routes", + "show ipv6 bgp neighbors (A.B.C.D|X:X::X:X|WORD) received-routes", SHOW_STR IPV6_STR BGP_STR "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display the received routes from neighbor\n") /* old command */ DEFUN (ipv6_mbgp_neighbor_received_routes, ipv6_mbgp_neighbor_received_routes_cmd, - "show ipv6 mbgp neighbors (A.B.C.D|X:X::X:X) received-routes", + "show ipv6 mbgp neighbors (A.B.C.D|X:X::X:X|WORD) received-routes", SHOW_STR IPV6_STR MBGP_STR "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display the received routes from neighbor\n") { struct peer *peer; @@ -10788,7 +10843,7 @@ DEFUN (ipv6_mbgp_neighbor_received_routes, DEFUN (show_bgp_view_neighbor_received_prefix_filter, show_bgp_view_neighbor_received_prefix_filter_cmd, - "show bgp view WORD neighbors (A.B.C.D|X:X::X:X) received prefix-filter", + "show bgp view WORD neighbors (A.B.C.D|X:X::X:X|WORD) received prefix-filter", SHOW_STR BGP_STR "BGP view\n" @@ -10796,6 +10851,7 @@ DEFUN (show_bgp_view_neighbor_received_prefix_filter, "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display information received from a BGP neighbor\n" "Display the prefixlist filter\n") { @@ -10816,13 +10872,19 @@ DEFUN (show_bgp_view_neighbor_received_prefix_filter, ret = str2sockunion (argv[1], &su); if (ret < 0) { - vty_out (vty, "Malformed address: %s%s", argv[1], VTY_NEWLINE); - return CMD_WARNING; + peer = peer_lookup_by_conf_if (bgp, argv[1]); + if (!peer) + { + vty_out (vty, "%% Malformed address or name: %s%s", argv[1], VTY_NEWLINE); + return CMD_WARNING; + } + } + else + { + peer = peer_lookup (bgp, &su); + if (! peer) + return CMD_WARNING; } - - peer = peer_lookup (bgp, &su); - if (! peer) - return CMD_WARNING; sprintf (name, "%s.%d.%d", peer->host, AFI_IP6, SAFI_UNICAST); count = prefix_bgp_show_prefix_list (NULL, AFI_IP6, name); @@ -10837,7 +10899,7 @@ DEFUN (show_bgp_view_neighbor_received_prefix_filter, ALIAS (show_bgp_view_neighbor_received_prefix_filter, show_bgp_view_ipv6_neighbor_received_prefix_filter_cmd, - "show bgp view WORD ipv6 neighbors (A.B.C.D|X:X::X:X) received prefix-filter", + "show bgp view WORD ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) received prefix-filter", SHOW_STR BGP_STR "BGP view\n" @@ -10846,6 +10908,7 @@ ALIAS (show_bgp_view_neighbor_received_prefix_filter, "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display information received from a BGP neighbor\n" "Display the prefixlist filter\n") #endif /* HAVE_IPV6 */ @@ -10865,13 +10928,14 @@ bgp_show_neighbor_route (struct vty *vty, struct peer *peer, afi_t afi, DEFUN (show_ip_bgp_neighbor_routes, show_ip_bgp_neighbor_routes_cmd, - "show ip bgp neighbors (A.B.C.D|X:X::X:X) routes", + "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) routes", SHOW_STR IP_STR BGP_STR "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display routes learned from neighbor\n") { struct peer *peer; @@ -10886,13 +10950,14 @@ DEFUN (show_ip_bgp_neighbor_routes, DEFUN (show_ip_bgp_neighbor_routes_csv, show_ip_bgp_neighbor_routes_csv_cmd, - "show ip bgp neighbors (A.B.C.D|X:X::X:X) routes csv", + "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) routes csv", SHOW_STR IP_STR BGP_STR "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display routes learned from neighbor\n") { struct peer *peer; @@ -10907,13 +10972,14 @@ DEFUN (show_ip_bgp_neighbor_routes_csv, DEFUN (show_ip_bgp_neighbor_flap, show_ip_bgp_neighbor_flap_cmd, - "show ip bgp neighbors (A.B.C.D|X:X::X:X) flap-statistics", + "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) flap-statistics", SHOW_STR IP_STR BGP_STR "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display flap statistics of the routes learned from neighbor\n") { struct peer *peer; @@ -10928,13 +10994,14 @@ DEFUN (show_ip_bgp_neighbor_flap, DEFUN (show_ip_bgp_neighbor_damp, show_ip_bgp_neighbor_damp_cmd, - "show ip bgp neighbors (A.B.C.D|X:X::X:X) dampened-routes", + "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) dampened-routes", SHOW_STR IP_STR BGP_STR "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display the dampened routes received from neighbor\n") { struct peer *peer; @@ -10949,7 +11016,7 @@ DEFUN (show_ip_bgp_neighbor_damp, DEFUN (show_ip_bgp_ipv4_neighbor_routes, show_ip_bgp_ipv4_neighbor_routes_cmd, - "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X) routes", + "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X|WORD) routes", SHOW_STR IP_STR BGP_STR @@ -10959,6 +11026,7 @@ DEFUN (show_ip_bgp_ipv4_neighbor_routes, "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display routes learned from neighbor\n") { struct peer *peer; @@ -10977,14 +11045,14 @@ DEFUN (show_ip_bgp_ipv4_neighbor_routes, DEFUN (show_ip_bgp_view_rsclient, show_ip_bgp_view_rsclient_cmd, - "show ip bgp view WORD rsclient (A.B.C.D|X:X::X:X)", + "show ip bgp view WORD rsclient (A.B.C.D|X:X::X:X|WORD)", SHOW_STR IP_STR BGP_STR "BGP view\n" "View name\n" "Information about Route Server Client\n" - NEIGHBOR_ADDR_STR) + NEIGHBOR_ADDR_STR3) { struct bgp_table *table; struct peer *peer; @@ -11020,16 +11088,16 @@ DEFUN (show_ip_bgp_view_rsclient, ALIAS (show_ip_bgp_view_rsclient, show_ip_bgp_rsclient_cmd, - "show ip bgp rsclient (A.B.C.D|X:X::X:X)", + "show ip bgp rsclient (A.B.C.D|X:X::X:X|WORD)", SHOW_STR IP_STR BGP_STR "Information about Route Server Client\n" - NEIGHBOR_ADDR_STR) + NEIGHBOR_ADDR_STR3) DEFUN (show_bgp_view_ipv4_safi_rsclient, show_bgp_view_ipv4_safi_rsclient_cmd, - "show bgp view WORD ipv4 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X)", + "show bgp view WORD ipv4 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X|WORD)", SHOW_STR BGP_STR "BGP view\n" @@ -11038,7 +11106,7 @@ DEFUN (show_bgp_view_ipv4_safi_rsclient, "Address Family modifier\n" "Address Family modifier\n" "Information about Route Server Client\n" - NEIGHBOR_ADDR_STR) + NEIGHBOR_ADDR_STR3) { struct bgp_table *table; struct peer *peer; @@ -11078,25 +11146,25 @@ DEFUN (show_bgp_view_ipv4_safi_rsclient, ALIAS (show_bgp_view_ipv4_safi_rsclient, show_bgp_ipv4_safi_rsclient_cmd, - "show bgp ipv4 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X)", + "show bgp ipv4 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X|WORD)", SHOW_STR BGP_STR "Address family\n" "Address Family modifier\n" "Address Family modifier\n" "Information about Route Server Client\n" - NEIGHBOR_ADDR_STR) + NEIGHBOR_ADDR_STR3) DEFUN (show_ip_bgp_view_rsclient_route, show_ip_bgp_view_rsclient_route_cmd, - "show ip bgp view WORD rsclient (A.B.C.D|X:X::X:X) A.B.C.D", + "show ip bgp view WORD rsclient (A.B.C.D|X:X::X:X|WORD) A.B.C.D", SHOW_STR IP_STR BGP_STR "BGP view\n" "View name\n" "Information about Route Server Client\n" - NEIGHBOR_ADDR_STR + NEIGHBOR_ADDR_STR3 "Network in the BGP routing table to display\n") { struct bgp *bgp; @@ -11152,17 +11220,17 @@ DEFUN (show_ip_bgp_view_rsclient_route, ALIAS (show_ip_bgp_view_rsclient_route, show_ip_bgp_rsclient_route_cmd, - "show ip bgp rsclient (A.B.C.D|X:X::X:X) A.B.C.D", + "show ip bgp rsclient (A.B.C.D|X:X::X:X|WORD) A.B.C.D", SHOW_STR IP_STR BGP_STR "Information about Route Server Client\n" - NEIGHBOR_ADDR_STR + NEIGHBOR_ADDR_STR3 "Network in the BGP routing table to display\n") DEFUN (show_bgp_view_ipv4_safi_rsclient_route, show_bgp_view_ipv4_safi_rsclient_route_cmd, - "show bgp view WORD ipv4 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X) A.B.C.D", + "show bgp view WORD ipv4 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X|WORD) A.B.C.D", SHOW_STR BGP_STR "BGP view\n" @@ -11171,7 +11239,7 @@ DEFUN (show_bgp_view_ipv4_safi_rsclient_route, "Address Family modifier\n" "Address Family modifier\n" "Information about Route Server Client\n" - NEIGHBOR_ADDR_STR + NEIGHBOR_ADDR_STR3 "Network in the BGP routing table to display\n") { struct bgp *bgp; @@ -11231,26 +11299,26 @@ DEFUN (show_bgp_view_ipv4_safi_rsclient_route, ALIAS (show_bgp_view_ipv4_safi_rsclient_route, show_bgp_ipv4_safi_rsclient_route_cmd, - "show bgp ipv4 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X) A.B.C.D", + "show bgp ipv4 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X|WORD) A.B.C.D", SHOW_STR BGP_STR "Address family\n" "Address Family modifier\n" "Address Family modifier\n" "Information about Route Server Client\n" - NEIGHBOR_ADDR_STR + NEIGHBOR_ADDR_STR3 "Network in the BGP routing table to display\n") DEFUN (show_ip_bgp_view_rsclient_prefix, show_ip_bgp_view_rsclient_prefix_cmd, - "show ip bgp view WORD rsclient (A.B.C.D|X:X::X:X) A.B.C.D/M", + "show ip bgp view WORD rsclient (A.B.C.D|X:X::X:X|WORD) A.B.C.D/M", SHOW_STR IP_STR BGP_STR "BGP view\n" "View name\n" "Information about Route Server Client\n" - NEIGHBOR_ADDR_STR + NEIGHBOR_ADDR_STR3 "IP prefix /, e.g., 35.0.0.0/8\n") { struct bgp *bgp; @@ -11306,17 +11374,17 @@ DEFUN (show_ip_bgp_view_rsclient_prefix, ALIAS (show_ip_bgp_view_rsclient_prefix, show_ip_bgp_rsclient_prefix_cmd, - "show ip bgp rsclient (A.B.C.D|X:X::X:X) A.B.C.D/M", + "show ip bgp rsclient (A.B.C.D|X:X::X:X|WORD) A.B.C.D/M", SHOW_STR IP_STR BGP_STR "Information about Route Server Client\n" - NEIGHBOR_ADDR_STR + NEIGHBOR_ADDR_STR3 "IP prefix /, e.g., 35.0.0.0/8\n") DEFUN (show_bgp_view_ipv4_safi_rsclient_prefix, show_bgp_view_ipv4_safi_rsclient_prefix_cmd, - "show bgp view WORD ipv4 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X) A.B.C.D/M", + "show bgp view WORD ipv4 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X|WORD) A.B.C.D/M", SHOW_STR BGP_STR "BGP view\n" @@ -11325,7 +11393,7 @@ DEFUN (show_bgp_view_ipv4_safi_rsclient_prefix, "Address Family modifier\n" "Address Family modifier\n" "Information about Route Server Client\n" - NEIGHBOR_ADDR_STR + NEIGHBOR_ADDR_STR3 "IP prefix /, e.g., 35.0.0.0/8\n") { struct bgp *bgp; @@ -11385,20 +11453,20 @@ DEFUN (show_bgp_view_ipv4_safi_rsclient_prefix, ALIAS (show_bgp_view_ipv4_safi_rsclient_prefix, show_bgp_ipv4_safi_rsclient_prefix_cmd, - "show bgp ipv4 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X) A.B.C.D/M", + "show bgp ipv4 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X|WORD) A.B.C.D/M", SHOW_STR BGP_STR "Address family\n" "Address Family modifier\n" "Address Family modifier\n" "Information about Route Server Client\n" - NEIGHBOR_ADDR_STR + NEIGHBOR_ADDR_STR3 "IP prefix /, e.g., 35.0.0.0/8\n") #ifdef HAVE_IPV6 DEFUN (show_bgp_view_neighbor_routes, show_bgp_view_neighbor_routes_cmd, - "show bgp view WORD neighbors (A.B.C.D|X:X::X:X) routes", + "show bgp view WORD neighbors (A.B.C.D|X:X::X:X|WORD) routes", SHOW_STR BGP_STR "BGP view\n" @@ -11406,6 +11474,7 @@ DEFUN (show_bgp_view_neighbor_routes, "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display routes learned from neighbor\n") { struct peer *peer; @@ -11424,7 +11493,7 @@ DEFUN (show_bgp_view_neighbor_routes, DEFUN (show_bgp_view_neighbor_routes_csv, show_bgp_view_neighbor_routes_csv_cmd, - "show bgp view WORD neighbors (A.B.C.D|X:X::X:X) routes csv", + "show bgp view WORD neighbors (A.B.C.D|X:X::X:X|WORD) routes csv", SHOW_STR BGP_STR "BGP view\n" @@ -11432,6 +11501,7 @@ DEFUN (show_bgp_view_neighbor_routes_csv, "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display routes learned from neighbor\n") { struct peer *peer; @@ -11450,7 +11520,7 @@ DEFUN (show_bgp_view_neighbor_routes_csv, ALIAS (show_bgp_view_neighbor_routes, show_bgp_view_ipv6_neighbor_routes_cmd, - "show bgp view WORD ipv6 neighbors (A.B.C.D|X:X::X:X) routes", + "show bgp view WORD ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) routes", SHOW_STR BGP_STR "BGP view\n" @@ -11459,11 +11529,12 @@ ALIAS (show_bgp_view_neighbor_routes, "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display routes learned from neighbor\n") DEFUN (show_bgp_view_neighbor_damp, show_bgp_view_neighbor_damp_cmd, - "show bgp view WORD neighbors (A.B.C.D|X:X::X:X) dampened-routes", + "show bgp view WORD neighbors (A.B.C.D|X:X::X:X|WORD) dampened-routes", SHOW_STR BGP_STR "BGP view\n" @@ -11471,6 +11542,7 @@ DEFUN (show_bgp_view_neighbor_damp, "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display the dampened routes received from neighbor\n") { struct peer *peer; @@ -11489,7 +11561,7 @@ DEFUN (show_bgp_view_neighbor_damp, ALIAS (show_bgp_view_neighbor_damp, show_bgp_view_ipv6_neighbor_damp_cmd, - "show bgp view WORD ipv6 neighbors (A.B.C.D|X:X::X:X) dampened-routes", + "show bgp view WORD ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) dampened-routes", SHOW_STR BGP_STR "BGP view\n" @@ -11498,11 +11570,12 @@ ALIAS (show_bgp_view_neighbor_damp, "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display the dampened routes received from neighbor\n") DEFUN (show_bgp_view_neighbor_flap, show_bgp_view_neighbor_flap_cmd, - "show bgp view WORD neighbors (A.B.C.D|X:X::X:X) flap-statistics", + "show bgp view WORD neighbors (A.B.C.D|X:X::X:X|WORD) flap-statistics", SHOW_STR BGP_STR "BGP view\n" @@ -11510,6 +11583,7 @@ DEFUN (show_bgp_view_neighbor_flap, "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display flap statistics of the routes learned from neighbor\n") { struct peer *peer; @@ -11528,7 +11602,7 @@ DEFUN (show_bgp_view_neighbor_flap, ALIAS (show_bgp_view_neighbor_flap, show_bgp_view_ipv6_neighbor_flap_cmd, - "show bgp view WORD ipv6 neighbors (A.B.C.D|X:X::X:X) flap-statistics", + "show bgp view WORD ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) flap-statistics", SHOW_STR BGP_STR "BGP view\n" @@ -11537,86 +11611,94 @@ ALIAS (show_bgp_view_neighbor_flap, "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display flap statistics of the routes learned from neighbor\n") ALIAS (show_bgp_view_neighbor_routes, show_bgp_neighbor_routes_cmd, - "show bgp neighbors (A.B.C.D|X:X::X:X) routes", + "show bgp neighbors (A.B.C.D|X:X::X:X|WORD) routes", SHOW_STR BGP_STR "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display routes learned from neighbor\n") ALIAS (show_bgp_view_neighbor_routes, show_bgp_ipv6_neighbor_routes_cmd, - "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X) routes", + "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) routes", SHOW_STR BGP_STR "Address family\n" "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display routes learned from neighbor\n") /* old command */ ALIAS (show_bgp_view_neighbor_routes, ipv6_bgp_neighbor_routes_cmd, - "show ipv6 bgp neighbors (A.B.C.D|X:X::X:X) routes", + "show ipv6 bgp neighbors (A.B.C.D|X:X::X:X|WORD) routes", SHOW_STR IPV6_STR BGP_STR "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display routes learned from neighbor\n") ALIAS (show_bgp_view_neighbor_routes_csv, show_bgp_neighbor_routes_csv_cmd, - "show bgp neighbors (A.B.C.D|X:X::X:X) routes csv", + "show bgp neighbors (A.B.C.D|X:X::X:X|WORD) routes csv", SHOW_STR BGP_STR "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display routes learned from neighbor\n") ALIAS (show_bgp_view_neighbor_routes_csv, show_bgp_ipv6_neighbor_routes_csv_cmd, - "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X) routes csv", + "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) routes csv", SHOW_STR BGP_STR "Address family\n" "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display routes learned from neighbor\n") /* old command */ ALIAS (show_bgp_view_neighbor_routes_csv, ipv6_bgp_neighbor_routes_csv_cmd, - "show ipv6 bgp neighbors (A.B.C.D|X:X::X:X) routes csv", + "show ipv6 bgp neighbors (A.B.C.D|X:X::X:X|WORD) routes csv", SHOW_STR IPV6_STR BGP_STR "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display routes learned from neighbor\n") /* old command */ DEFUN (ipv6_mbgp_neighbor_routes, ipv6_mbgp_neighbor_routes_cmd, - "show ipv6 mbgp neighbors (A.B.C.D|X:X::X:X) routes", + "show ipv6 mbgp neighbors (A.B.C.D|X:X::X:X|WORD) routes", SHOW_STR IPV6_STR MBGP_STR "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display routes learned from neighbor\n") { struct peer *peer; @@ -11631,55 +11713,59 @@ DEFUN (ipv6_mbgp_neighbor_routes, ALIAS (show_bgp_view_neighbor_flap, show_bgp_neighbor_flap_cmd, - "show bgp neighbors (A.B.C.D|X:X::X:X) flap-statistics", + "show bgp neighbors (A.B.C.D|X:X::X:X|WORD) flap-statistics", SHOW_STR BGP_STR "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display flap statistics of the routes learned from neighbor\n") ALIAS (show_bgp_view_neighbor_flap, show_bgp_ipv6_neighbor_flap_cmd, - "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X) flap-statistics", + "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) flap-statistics", SHOW_STR BGP_STR "Address family\n" "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display flap statistics of the routes learned from neighbor\n") ALIAS (show_bgp_view_neighbor_damp, show_bgp_neighbor_damp_cmd, - "show bgp neighbors (A.B.C.D|X:X::X:X) dampened-routes", + "show bgp neighbors (A.B.C.D|X:X::X:X|WORD) dampened-routes", SHOW_STR BGP_STR "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display the dampened routes received from neighbor\n") ALIAS (show_bgp_view_neighbor_damp, show_bgp_ipv6_neighbor_damp_cmd, - "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X) dampened-routes", + "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) dampened-routes", SHOW_STR BGP_STR "Address family\n" "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n" "Display the dampened routes received from neighbor\n") DEFUN (show_bgp_view_rsclient, show_bgp_view_rsclient_cmd, - "show bgp view WORD rsclient (A.B.C.D|X:X::X:X)", + "show bgp view WORD rsclient (A.B.C.D|X:X::X:X|WORD)", SHOW_STR BGP_STR "BGP view\n" "View name\n" "Information about Route Server Client\n" - NEIGHBOR_ADDR_STR) + NEIGHBOR_ADDR_STR3) { struct bgp_table *table; struct peer *peer; @@ -11715,15 +11801,15 @@ DEFUN (show_bgp_view_rsclient, ALIAS (show_bgp_view_rsclient, show_bgp_rsclient_cmd, - "show bgp rsclient (A.B.C.D|X:X::X:X)", + "show bgp rsclient (A.B.C.D|X:X::X:X|WORD)", SHOW_STR BGP_STR "Information about Route Server Client\n" - NEIGHBOR_ADDR_STR) + NEIGHBOR_ADDR_STR3) DEFUN (show_bgp_view_ipv6_safi_rsclient, show_bgp_view_ipv6_safi_rsclient_cmd, - "show bgp view WORD ipv6 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X)", + "show bgp view WORD ipv6 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X|WORD)", SHOW_STR BGP_STR "BGP view\n" @@ -11732,7 +11818,7 @@ DEFUN (show_bgp_view_ipv6_safi_rsclient, "Address Family modifier\n" "Address Family modifier\n" "Information about Route Server Client\n" - NEIGHBOR_ADDR_STR) + NEIGHBOR_ADDR_STR3) { struct bgp_table *table; struct peer *peer; @@ -11772,24 +11858,24 @@ DEFUN (show_bgp_view_ipv6_safi_rsclient, ALIAS (show_bgp_view_ipv6_safi_rsclient, show_bgp_ipv6_safi_rsclient_cmd, - "show bgp ipv6 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X)", + "show bgp ipv6 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X|WORD)", SHOW_STR BGP_STR "Address family\n" "Address Family modifier\n" "Address Family modifier\n" "Information about Route Server Client\n" - NEIGHBOR_ADDR_STR) + NEIGHBOR_ADDR_STR3) DEFUN (show_bgp_view_rsclient_route, show_bgp_view_rsclient_route_cmd, - "show bgp view WORD rsclient (A.B.C.D|X:X::X:X) X:X::X:X", + "show bgp view WORD rsclient (A.B.C.D|X:X::X:X|WORD) X:X::X:X", SHOW_STR BGP_STR "BGP view\n" "View name\n" "Information about Route Server Client\n" - NEIGHBOR_ADDR_STR + NEIGHBOR_ADDR_STR3 "Network in the BGP routing table to display\n") { struct bgp *bgp; @@ -11845,16 +11931,16 @@ DEFUN (show_bgp_view_rsclient_route, ALIAS (show_bgp_view_rsclient_route, show_bgp_rsclient_route_cmd, - "show bgp rsclient (A.B.C.D|X:X::X:X) X:X::X:X", + "show bgp rsclient (A.B.C.D|X:X::X:X|WORD) X:X::X:X", SHOW_STR BGP_STR "Information about Route Server Client\n" - NEIGHBOR_ADDR_STR + NEIGHBOR_ADDR_STR3 "Network in the BGP routing table to display\n") DEFUN (show_bgp_view_ipv6_safi_rsclient_route, show_bgp_view_ipv6_safi_rsclient_route_cmd, - "show bgp view WORD ipv6 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X) X:X::X:X", + "show bgp view WORD ipv6 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X|WORD) X:X::X:X", SHOW_STR BGP_STR "BGP view\n" @@ -11863,7 +11949,7 @@ DEFUN (show_bgp_view_ipv6_safi_rsclient_route, "Address Family modifier\n" "Address Family modifier\n" "Information about Route Server Client\n" - NEIGHBOR_ADDR_STR + NEIGHBOR_ADDR_STR3 "Network in the BGP routing table to display\n") { struct bgp *bgp; @@ -11923,25 +12009,25 @@ DEFUN (show_bgp_view_ipv6_safi_rsclient_route, ALIAS (show_bgp_view_ipv6_safi_rsclient_route, show_bgp_ipv6_safi_rsclient_route_cmd, - "show bgp ipv6 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X) X:X::X:X", + "show bgp ipv6 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X|WORD) X:X::X:X", SHOW_STR BGP_STR "Address family\n" "Address Family modifier\n" "Address Family modifier\n" "Information about Route Server Client\n" - NEIGHBOR_ADDR_STR + NEIGHBOR_ADDR_STR3 "Network in the BGP routing table to display\n") DEFUN (show_bgp_view_rsclient_prefix, show_bgp_view_rsclient_prefix_cmd, - "show bgp view WORD rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M", + "show bgp view WORD rsclient (A.B.C.D|X:X::X:X|WORD) X:X::X:X/M", SHOW_STR BGP_STR "BGP view\n" "View name\n" "Information about Route Server Client\n" - NEIGHBOR_ADDR_STR + NEIGHBOR_ADDR_STR3 "IPv6 prefix /, e.g., 3ffe::/16\n") { struct bgp *bgp; @@ -11997,16 +12083,16 @@ DEFUN (show_bgp_view_rsclient_prefix, ALIAS (show_bgp_view_rsclient_prefix, show_bgp_rsclient_prefix_cmd, - "show bgp rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M", + "show bgp rsclient (A.B.C.D|X:X::X:X|WORD) X:X::X:X/M", SHOW_STR BGP_STR "Information about Route Server Client\n" - NEIGHBOR_ADDR_STR + NEIGHBOR_ADDR_STR3 "IPv6 prefix /, e.g., 3ffe::/16\n") DEFUN (show_bgp_view_ipv6_safi_rsclient_prefix, show_bgp_view_ipv6_safi_rsclient_prefix_cmd, - "show bgp view WORD ipv6 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M", + "show bgp view WORD ipv6 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X|WORD) X:X::X:X/M", SHOW_STR BGP_STR "BGP view\n" @@ -12015,7 +12101,7 @@ DEFUN (show_bgp_view_ipv6_safi_rsclient_prefix, "Address Family modifier\n" "Address Family modifier\n" "Information about Route Server Client\n" - NEIGHBOR_ADDR_STR + NEIGHBOR_ADDR_STR3 "IP prefix /, e.g., 3ffe::/16\n") { struct bgp *bgp; @@ -12075,14 +12161,14 @@ DEFUN (show_bgp_view_ipv6_safi_rsclient_prefix, ALIAS (show_bgp_view_ipv6_safi_rsclient_prefix, show_bgp_ipv6_safi_rsclient_prefix_cmd, - "show bgp ipv6 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M", + "show bgp ipv6 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X|WORD) X:X::X:X/M", SHOW_STR BGP_STR "Address family\n" "Address Family modifier\n" "Address Family modifier\n" "Information about Route Server Client\n" - NEIGHBOR_ADDR_STR + NEIGHBOR_ADDR_STR3 "IP prefix /, e.g., 3ffe::/16\n") #endif /* HAVE_IPV6 */ diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 6927ffc7e..9d7f0ba78 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -106,15 +106,22 @@ peer_lookup_vty (struct vty *vty, const char *ip_str) ret = str2sockunion (ip_str, &su); if (ret < 0) { - vty_out (vty, "%% Malformed address: %s%s", ip_str, VTY_NEWLINE); - return NULL; + peer = peer_lookup_by_conf_if (bgp, ip_str); + if (!peer) + { + vty_out (vty, "%% Malformed address or name: %s%s", ip_str, VTY_NEWLINE); + return NULL; + } } - - peer = peer_lookup (bgp, &su); - if (! peer) + else { - vty_out (vty, "%% Specify remote-as or peer-group commands first%s", VTY_NEWLINE); - return NULL; + peer = peer_lookup (bgp, &su); + if (! peer) + { + vty_out (vty, "%% Specify remote-as or peer-group commands first%s", + VTY_NEWLINE); + return NULL; + } } return peer; } @@ -140,6 +147,10 @@ peer_and_group_lookup_vty (struct vty *vty, const char *peer_str) } else { + peer = peer_lookup_by_conf_if (bgp, peer_str); + if (peer) + return peer; + group = peer_group_lookup (bgp, peer_str); if (group) return group->conf; @@ -1593,24 +1604,31 @@ peer_remote_as_vty (struct vty *vty, const char *peer_str, ret = str2sockunion (peer_str, &su); if (ret < 0) { - ret = peer_group_remote_as (bgp, peer_str, &as); + /* Check for peer by interface */ + ret = peer_remote_as (bgp, NULL, peer_str, &as, afi, safi); if (ret < 0) - { - vty_out (vty, "%% Create the peer-group first%s", VTY_NEWLINE); - return CMD_WARNING; - } - return CMD_SUCCESS; + { + ret = peer_group_remote_as (bgp, peer_str, &as); + if (ret < 0) + { + vty_out (vty, "%% Create the peer-group or interface first%s", + VTY_NEWLINE); + return CMD_WARNING; + } + return CMD_SUCCESS; + } } - - if (peer_address_self_check (&su)) + else { - vty_out (vty, "%% Can not configure the local system as neighbor%s", - VTY_NEWLINE); - return CMD_WARNING; + if (peer_address_self_check (&su)) + { + vty_out (vty, "%% Can not configure the local system as neighbor%s", + VTY_NEWLINE); + return CMD_WARNING; + } + ret = peer_remote_as (bgp, &su, NULL, &as, afi, safi); } - ret = peer_remote_as (bgp, &su, &as, afi, safi); - /* This peer belongs to peer group. */ switch (ret) { @@ -1635,17 +1653,51 @@ DEFUN (neighbor_remote_as, return peer_remote_as_vty (vty, argv[0], argv[1], AFI_IP, SAFI_UNICAST); } +DEFUN (neighbor_interface_config, + neighbor_interface_config_cmd, + "neighbor WORD interface", + NEIGHBOR_STR + "Interface name or neighbor tag\n" + "Enable BGP on interface\n") +{ + struct bgp *bgp; + struct peer *peer; + struct peer_group *group; + + bgp = vty->index; + group = peer_group_lookup (bgp, argv[0]); + if (group) + { + vty_out (vty, "%% Name conflict with peer-group %s", VTY_NEWLINE); + return CMD_WARNING; + } + + peer = peer_conf_interface_get (bgp, argv[0], AFI_IP, SAFI_UNICAST); + if (!peer) + return CMD_WARNING; + + return CMD_SUCCESS; +} + + DEFUN (neighbor_peer_group, neighbor_peer_group_cmd, "neighbor WORD peer-group", NEIGHBOR_STR - "Neighbor tag\n" + "Interface name or neighbor tag\n" "Configure peer-group\n") { struct bgp *bgp; + struct peer *peer; struct peer_group *group; bgp = vty->index; + peer = peer_lookup_by_conf_if (bgp, argv[0]); + if (peer) + { + vty_out (vty, "%% Name conflict with interface: %s", VTY_NEWLINE); + return CMD_WARNING; + } group = peer_group_get (bgp, argv[0]); if (! group) @@ -1670,6 +1722,14 @@ DEFUN (no_neighbor, ret = str2sockunion (argv[0], &su); if (ret < 0) { + /* look up for neighbor by interface name config. */ + peer = peer_lookup_by_conf_if (vty->index, argv[0]); + if (peer) + { + peer_delete (peer); + return CMD_SUCCESS; + } + group = peer_group_lookup (vty->index, argv[0]); if (group) peer_group_delete (group); @@ -1703,6 +1763,30 @@ ALIAS (no_neighbor, "Specify a BGP neighbor\n" AS_STR) +DEFUN (no_neighbor_interface_config, + no_neighbor_interface_config_cmd, + "no neighbor WORD interface", + NO_STR + NEIGHBOR_STR + "Interface name\n" + "Configure BGP on interface\n") +{ + struct peer *peer; + + /* look up for neighbor by interface name config. */ + peer = peer_lookup_by_conf_if (vty->index, argv[0]); + if (peer) + { + peer_delete (peer); + } + else + { + vty_out (vty, "%% Create the bgp interface first%s", VTY_NEWLINE); + return CMD_WARNING; + } + return CMD_SUCCESS; +} + DEFUN (no_neighbor_peer_group, no_neighbor_peer_group_cmd, "no neighbor WORD peer-group", @@ -1724,23 +1808,32 @@ DEFUN (no_neighbor_peer_group, return CMD_SUCCESS; } -DEFUN (no_neighbor_peer_group_remote_as, - no_neighbor_peer_group_remote_as_cmd, +DEFUN (no_neighbor_interface_peer_group_remote_as, + no_neighbor_interface_peer_group_remote_as_cmd, "no neighbor WORD remote-as " CMD_AS_RANGE, NO_STR NEIGHBOR_STR - "Neighbor tag\n" + "Interface name or neighbor tag\n" "Specify a BGP neighbor\n" AS_STR) { struct peer_group *group; + struct peer *peer; + + /* look up for neighbor by interface name config. */ + peer = peer_lookup_by_conf_if (vty->index, argv[0]); + if (peer) + { + peer_as_change (peer, 0); + return CMD_SUCCESS; + } group = peer_group_lookup (vty->index, argv[0]); if (group) peer_group_remote_as_delete (group); else { - vty_out (vty, "%% Create the peer-group first%s", VTY_NEWLINE); + vty_out (vty, "%% Create the peer-group or interface first%s", VTY_NEWLINE); return CMD_WARNING; } return CMD_SUCCESS; @@ -1935,9 +2028,9 @@ DEFUN (no_neighbor_activate, DEFUN (neighbor_set_peer_group, neighbor_set_peer_group_cmd, - NEIGHBOR_CMD "peer-group WORD", + NEIGHBOR_CMD2 "peer-group WORD", NEIGHBOR_STR - NEIGHBOR_ADDR_STR + NEIGHBOR_ADDR_STR2 "Member of the peer-group\n" "peer-group name\n") { @@ -1945,15 +2038,30 @@ DEFUN (neighbor_set_peer_group, as_t as; union sockunion su; struct bgp *bgp; + struct peer *peer; struct peer_group *group; bgp = vty->index; + peer = NULL; ret = str2sockunion (argv[0], &su); if (ret < 0) { - vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE); - return CMD_WARNING; + peer = peer_lookup_by_conf_if (bgp, argv[0]); + if (!peer) + { + vty_out (vty, "%% Malformed address or name: %s%s", argv[0], VTY_NEWLINE); + return CMD_WARNING; + } + } + else + { + if (peer_address_self_check (&su)) + { + vty_out (vty, "%% Can not configure the local system as neighbor%s", + VTY_NEWLINE); + return CMD_WARNING; + } } group = peer_group_lookup (bgp, argv[1]); @@ -1963,14 +2071,7 @@ DEFUN (neighbor_set_peer_group, return CMD_WARNING; } - if (peer_address_self_check (&su)) - { - vty_out (vty, "%% Can not configure the local system as neighbor%s", - VTY_NEWLINE); - return CMD_WARNING; - } - - ret = peer_group_bind (bgp, &su, group, bgp_node_afi (vty), + ret = peer_group_bind (bgp, &su, peer, group, bgp_node_afi (vty), bgp_node_safi (vty), &as); if (ret == BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT) @@ -1984,10 +2085,10 @@ DEFUN (neighbor_set_peer_group, DEFUN (no_neighbor_set_peer_group, no_neighbor_set_peer_group_cmd, - NO_NEIGHBOR_CMD "peer-group WORD", + NO_NEIGHBOR_CMD2 "peer-group WORD", NO_STR NEIGHBOR_STR - NEIGHBOR_ADDR_STR + NEIGHBOR_ADDR_STR2 "Member of the peer-group\n" "peer-group name\n") { @@ -3188,6 +3289,9 @@ peer_update_source_vty (struct vty *vty, const char *peer_str, if (! peer) return CMD_WARNING; + if (peer->conf_if) + return CMD_WARNING; + if (source_str) { union sockunion su; @@ -3656,7 +3760,7 @@ peer_interface_vty (struct vty *vty, const char *ip_str, const char *str) struct peer *peer; peer = peer_lookup_vty (vty, ip_str); - if (! peer) + if (! peer || peer->conf_if) return CMD_WARNING; if (str) @@ -4532,16 +4636,23 @@ bgp_clear (struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, /* Make sockunion for lookup. */ ret = str2sockunion (arg, &su); if (ret < 0) - { - vty_out (vty, "Malformed address: %s%s", arg, VTY_NEWLINE); - return CMD_WARNING; - } - peer = peer_lookup (bgp, &su); - if (! peer) - { - vty_out (vty, "%%BGP: Unknown neighbor - \"%s\"%s", arg, VTY_NEWLINE); - return CMD_WARNING; - } + { + peer = peer_lookup_by_conf_if (bgp, arg); + if (!peer) + { + vty_out (vty, "Malformed address or name: %s%s", arg, VTY_NEWLINE); + return CMD_WARNING; + } + } + else + { + peer = peer_lookup (bgp, &su); + if (! peer) + { + vty_out (vty, "%%BGP: Unknown neighbor - \"%s\"%s", arg, VTY_NEWLINE); + return CMD_WARNING; + } + } if (stype == BGP_CLEAR_SOFT_NONE) ret = peer_clear (peer, NULL); @@ -4713,32 +4824,35 @@ ALIAS (clear_ip_bgp_all, DEFUN (clear_ip_bgp_peer, clear_ip_bgp_peer_cmd, - "clear ip bgp (A.B.C.D|X:X::X:X)", + "clear ip bgp (A.B.C.D|X:X::X:X|WORD)", CLEAR_STR IP_STR BGP_STR "BGP neighbor IP address to clear\n" - "BGP IPv6 neighbor to clear\n") + "BGP IPv6 neighbor to clear\n" + "BGP neighbor on interface to clear\n") { return bgp_clear_vty (vty, NULL, 0, 0, clear_peer, BGP_CLEAR_SOFT_NONE, argv[0]); } ALIAS (clear_ip_bgp_peer, clear_bgp_peer_cmd, - "clear bgp (A.B.C.D|X:X::X:X)", + "clear bgp (A.B.C.D|X:X::X:X|WORD)", CLEAR_STR BGP_STR "BGP neighbor address to clear\n" - "BGP IPv6 neighbor to clear\n") + "BGP IPv6 neighbor to clear\n" + "BGP neighbor on interface to clear\n") ALIAS (clear_ip_bgp_peer, clear_bgp_ipv6_peer_cmd, - "clear bgp ipv6 (A.B.C.D|X:X::X:X)", + "clear bgp ipv6 (A.B.C.D|X:X::X:X|WORD)", CLEAR_STR BGP_STR "Address family\n" "BGP neighbor address to clear\n" - "BGP IPv6 neighbor to clear\n") + "BGP IPv6 neighbor to clear\n" + "BGP neighbor on interface to clear\n") DEFUN (clear_ip_bgp_peer_group, clear_ip_bgp_peer_group_cmd, @@ -5083,11 +5197,12 @@ ALIAS (clear_ip_bgp_peer_vpnv4_soft_out, DEFUN (clear_bgp_peer_soft_out, clear_bgp_peer_soft_out_cmd, - "clear bgp (A.B.C.D|X:X::X:X) soft out", + "clear bgp (A.B.C.D|X:X::X:X|WORD) soft out", CLEAR_STR BGP_STR "BGP neighbor address to clear\n" "BGP IPv6 neighbor to clear\n" + "BGP neighbor on interface to clear\n" "Soft reconfig\n" "Soft reconfig outbound update\n") { @@ -5097,32 +5212,35 @@ DEFUN (clear_bgp_peer_soft_out, ALIAS (clear_bgp_peer_soft_out, clear_bgp_ipv6_peer_soft_out_cmd, - "clear bgp ipv6 (A.B.C.D|X:X::X:X) soft out", + "clear bgp ipv6 (A.B.C.D|X:X::X:X|WORD) soft out", CLEAR_STR BGP_STR "Address family\n" "BGP neighbor address to clear\n" "BGP IPv6 neighbor to clear\n" + "BGP neighbor on interface to clear\n" "Soft reconfig\n" "Soft reconfig outbound update\n") ALIAS (clear_bgp_peer_soft_out, clear_bgp_peer_out_cmd, - "clear bgp (A.B.C.D|X:X::X:X) out", + "clear bgp (A.B.C.D|X:X::X:X|WORD) out", CLEAR_STR BGP_STR "BGP neighbor address to clear\n" "BGP IPv6 neighbor to clear\n" + "BGP neighbor on interface to clear\n" "Soft reconfig outbound update\n") ALIAS (clear_bgp_peer_soft_out, clear_bgp_ipv6_peer_out_cmd, - "clear bgp ipv6 (A.B.C.D|X:X::X:X) out", + "clear bgp ipv6 (A.B.C.D|X:X::X:X|WORD) out", CLEAR_STR BGP_STR "Address family\n" "BGP neighbor address to clear\n" "BGP IPv6 neighbor to clear\n" + "BGP neighbor on interface to clear\n" "Soft reconfig outbound update\n") DEFUN (clear_ip_bgp_peer_group_soft_out, @@ -5842,11 +5960,12 @@ ALIAS (clear_ip_bgp_peer_vpnv4_soft_in, DEFUN (clear_bgp_peer_soft_in, clear_bgp_peer_soft_in_cmd, - "clear bgp (A.B.C.D|X:X::X:X) soft in", + "clear bgp (A.B.C.D|X:X::X:X|WORD) soft in", CLEAR_STR BGP_STR "BGP neighbor address to clear\n" "BGP IPv6 neighbor to clear\n" + "BGP neighbor on interface to clear\n" "Soft reconfig\n" "Soft reconfig inbound update\n") { @@ -5856,41 +5975,45 @@ DEFUN (clear_bgp_peer_soft_in, ALIAS (clear_bgp_peer_soft_in, clear_bgp_ipv6_peer_soft_in_cmd, - "clear bgp ipv6 (A.B.C.D|X:X::X:X) soft in", + "clear bgp ipv6 (A.B.C.D|X:X::X:X|WORD) soft in", CLEAR_STR BGP_STR "Address family\n" "BGP neighbor address to clear\n" "BGP IPv6 neighbor to clear\n" + "BGP neighbor on interface to clear\n" "Soft reconfig\n" "Soft reconfig inbound update\n") ALIAS (clear_bgp_peer_soft_in, clear_bgp_peer_in_cmd, - "clear bgp (A.B.C.D|X:X::X:X) in", + "clear bgp (A.B.C.D|X:X::X:X|WORD) in", CLEAR_STR BGP_STR "BGP neighbor address to clear\n" "BGP IPv6 neighbor to clear\n" + "BGP neighbor on interface to clear\n" "Soft reconfig inbound update\n") ALIAS (clear_bgp_peer_soft_in, clear_bgp_ipv6_peer_in_cmd, - "clear bgp ipv6 (A.B.C.D|X:X::X:X) in", + "clear bgp ipv6 (A.B.C.D|X:X::X:X|WORD) in", CLEAR_STR BGP_STR "Address family\n" "BGP neighbor address to clear\n" "BGP IPv6 neighbor to clear\n" + "BGP neighbor on interface to clear\n" "Soft reconfig inbound update\n") DEFUN (clear_bgp_peer_in_prefix_filter, clear_bgp_peer_in_prefix_filter_cmd, - "clear bgp (A.B.C.D|X:X::X:X) in prefix-filter", + "clear bgp (A.B.C.D|X:X::X:X|WORD) in prefix-filter", CLEAR_STR BGP_STR "BGP neighbor address to clear\n" "BGP IPv6 neighbor to clear\n" + "BGP neighbor on interface to clear\n" "Soft reconfig inbound update\n" "Push out the existing ORF prefix-list\n") { @@ -5900,12 +6023,13 @@ DEFUN (clear_bgp_peer_in_prefix_filter, ALIAS (clear_bgp_peer_in_prefix_filter, clear_bgp_ipv6_peer_in_prefix_filter_cmd, - "clear bgp ipv6 (A.B.C.D|X:X::X:X) in prefix-filter", + "clear bgp ipv6 (A.B.C.D|X:X::X:X|WORD) in prefix-filter", CLEAR_STR BGP_STR "Address family\n" "BGP neighbor address to clear\n" "BGP IPv6 neighbor to clear\n" + "BGP neighbor on interface to clear\n" "Soft reconfig inbound update\n" "Push out the existing ORF prefix-list\n") @@ -6582,11 +6706,12 @@ DEFUN (clear_ip_bgp_peer_vpnv4_soft, DEFUN (clear_bgp_peer_soft, clear_bgp_peer_soft_cmd, - "clear bgp (A.B.C.D|X:X::X:X) soft", + "clear bgp (A.B.C.D|X:X::X:X|WORD) soft", CLEAR_STR BGP_STR "BGP neighbor address to clear\n" "BGP IPv6 neighbor to clear\n" + "BGP neighbor on interface to clear\n" "Soft reconfig\n") { return bgp_clear_vty (vty, NULL, AFI_IP6, SAFI_UNICAST, clear_peer, @@ -6595,12 +6720,13 @@ DEFUN (clear_bgp_peer_soft, ALIAS (clear_bgp_peer_soft, clear_bgp_ipv6_peer_soft_cmd, - "clear bgp ipv6 (A.B.C.D|X:X::X:X) soft", + "clear bgp ipv6 (A.B.C.D|X:X::X:X|WORD) soft", CLEAR_STR BGP_STR "Address family\n" "BGP neighbor address to clear\n" "BGP IPv6 neighbor to clear\n" + "BGP neighbor on interface to clear\n" "Soft reconfig\n") DEFUN (clear_ip_bgp_peer_group_soft, @@ -6864,11 +6990,12 @@ ALIAS (clear_ip_bgp_all_rsclient, #ifdef HAVE_IPV6 DEFUN (clear_bgp_peer_rsclient, clear_bgp_peer_rsclient_cmd, - "clear bgp (A.B.C.D|X:X::X:X) rsclient", + "clear bgp (A.B.C.D|X:X::X:X|WORD) rsclient", CLEAR_STR BGP_STR "BGP neighbor IP address to clear\n" "BGP IPv6 neighbor to clear\n" + "BGP neighbor on interface to clear\n" "Soft reconfig for rsclient RIB\n") { if (argc == 2) @@ -6881,28 +7008,30 @@ DEFUN (clear_bgp_peer_rsclient, ALIAS (clear_bgp_peer_rsclient, clear_bgp_ipv6_peer_rsclient_cmd, - "clear bgp ipv6 (A.B.C.D|X:X::X:X) rsclient", + "clear bgp ipv6 (A.B.C.D|X:X::X:X|WORD) rsclient", CLEAR_STR BGP_STR "Address family\n" "BGP neighbor IP address to clear\n" "BGP IPv6 neighbor to clear\n" + "BGP neighbor on interface to clear\n" "Soft reconfig for rsclient RIB\n") ALIAS (clear_bgp_peer_rsclient, clear_bgp_instance_peer_rsclient_cmd, - "clear bgp view WORD (A.B.C.D|X:X::X:X) rsclient", + "clear bgp view WORD (A.B.C.D|X:X::X:X|WORD) rsclient", CLEAR_STR BGP_STR "BGP view\n" "view name\n" "BGP neighbor IP address to clear\n" "BGP IPv6 neighbor to clear\n" + "BGP neighbor on interface to clear\n" "Soft reconfig for rsclient RIB\n") ALIAS (clear_bgp_peer_rsclient, clear_bgp_ipv6_instance_peer_rsclient_cmd, - "clear bgp ipv6 view WORD (A.B.C.D|X:X::X:X) rsclient", + "clear bgp ipv6 view WORD (A.B.C.D|X:X::X:X|WORD) rsclient", CLEAR_STR BGP_STR "Address family\n" @@ -6910,17 +7039,19 @@ ALIAS (clear_bgp_peer_rsclient, "view name\n" "BGP neighbor IP address to clear\n" "BGP IPv6 neighbor to clear\n" + "BGP neighbor on interface to clear\n" "Soft reconfig for rsclient RIB\n") #endif /* HAVE_IPV6 */ DEFUN (clear_ip_bgp_peer_rsclient, clear_ip_bgp_peer_rsclient_cmd, - "clear ip bgp (A.B.C.D|X:X::X:X) rsclient", + "clear ip bgp (A.B.C.D|X:X::X:X|WORD) rsclient", CLEAR_STR IP_STR BGP_STR "BGP neighbor IP address to clear\n" "BGP IPv6 neighbor to clear\n" + "BGP neighbor on interface to clear\n" "Soft reconfig for rsclient RIB\n") { if (argc == 2) @@ -6933,7 +7064,7 @@ DEFUN (clear_ip_bgp_peer_rsclient, ALIAS (clear_ip_bgp_peer_rsclient, clear_ip_bgp_instance_peer_rsclient_cmd, - "clear ip bgp view WORD (A.B.C.D|X:X::X:X) rsclient", + "clear ip bgp view WORD (A.B.C.D|X:X::X:X|WORD) rsclient", CLEAR_STR IP_STR BGP_STR @@ -6941,6 +7072,7 @@ ALIAS (clear_ip_bgp_peer_rsclient, "view name\n" "BGP neighbor IP address to clear\n" "BGP IPv6 neighbor to clear\n" + "BGP neighbor on interface to clear\n" "Soft reconfig for rsclient RIB\n") DEFUN (show_bgp_views, @@ -7836,7 +7968,7 @@ static void bgp_show_peer (struct vty *vty, struct peer *p) { struct bgp *bgp; - char buf1[BUFSIZ]; + char buf1[BUFSIZ], buf[SU_ADDRSTRLEN]; char timebuf[BGP_UPTIME_LEN]; afi_t afi; safi_t safi; @@ -7845,8 +7977,12 @@ bgp_show_peer (struct vty *vty, struct peer *p) bgp = p->bgp; - /* Configured IP address. */ - vty_out (vty, "BGP neighbor is %s, ", p->host); + if (p->conf_if) /* Configured interface name. */ + vty_out (vty, "BGP neighbor on %s: %s, ", p->conf_if, + BGP_PEER_SU_UNSPEC(p) ? "None" : + sockunion2str (&p->su, buf, SU_ADDRSTRLEN)); + else /* Configured IP address. */ + vty_out (vty, "BGP neighbor is %s, ", p->host); vty_out (vty, "remote AS %u, ", p->as); vty_out (vty, "local AS %u%s%s, ", p->change_local_as ? p->change_local_as : p->local_as, @@ -8237,7 +8373,7 @@ bgp_show_peer (struct vty *vty, struct peer *p) static int bgp_show_neighbor (struct vty *vty, struct bgp *bgp, - enum show_type type, union sockunion *su) + enum show_type type, union sockunion *su, const char *conf_if) { struct listnode *node, *nnode; struct peer *peer; @@ -8254,11 +8390,22 @@ bgp_show_neighbor (struct vty *vty, struct bgp *bgp, bgp_show_peer (vty, peer); break; case show_peer: - if (sockunion_same (&peer->su, su)) - { - find = 1; - bgp_show_peer (vty, peer); - } + if (conf_if) + { + if (peer->conf_if && !strcmp(peer->conf_if, conf_if)) + { + find = 1; + bgp_show_peer (vty, peer); + } + } + else + { + if (sockunion_same (&peer->su, su)) + { + find = 1; + bgp_show_peer (vty, peer); + } + } break; } } @@ -8277,35 +8424,35 @@ bgp_show_neighbor_vty (struct vty *vty, const char *name, struct bgp *bgp; union sockunion su; - if (ip_str) - { - ret = str2sockunion (ip_str, &su); - if (ret < 0) - { - vty_out (vty, "%% Malformed address: %s%s", ip_str, VTY_NEWLINE); - return CMD_WARNING; - } - } - if (name) { bgp = bgp_lookup_by_name (name); - if (! bgp) { vty_out (vty, "%% No such BGP instance exist%s", VTY_NEWLINE); return CMD_WARNING; } - - bgp_show_neighbor (vty, bgp, type, &su); - - return CMD_SUCCESS; } - - bgp = bgp_get_default (); + else + { + bgp = bgp_get_default (); + } if (bgp) - bgp_show_neighbor (vty, bgp, type, &su); + { + if (ip_str) + { + ret = str2sockunion (ip_str, &su); + if (ret < 0) + bgp_show_neighbor (vty, bgp, type, NULL, ip_str); + else + bgp_show_neighbor (vty, bgp, type, &su, NULL); + } + else + { + bgp_show_neighbor (vty, bgp, type, NULL, NULL); + } + } return CMD_SUCCESS; } @@ -8371,20 +8518,21 @@ ALIAS (show_ip_bgp_neighbors, DEFUN (show_ip_bgp_neighbors_peer, show_ip_bgp_neighbors_peer_cmd, - "show ip bgp neighbors (A.B.C.D|X:X::X:X)", + "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD)", SHOW_STR IP_STR BGP_STR "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" - "Neighbor to display information about\n") + "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n") { return bgp_show_neighbor_vty (vty, NULL, show_peer, argv[argc - 1]); } ALIAS (show_ip_bgp_neighbors_peer, show_ip_bgp_ipv4_neighbors_peer_cmd, - "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X)", + "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X|WORD)", SHOW_STR IP_STR BGP_STR @@ -8393,7 +8541,8 @@ ALIAS (show_ip_bgp_neighbors_peer, "Address Family modifier\n" "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" - "Neighbor to display information about\n") + "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n") ALIAS (show_ip_bgp_neighbors_peer, show_ip_bgp_vpnv4_all_neighbors_peer_cmd, @@ -8419,22 +8568,24 @@ ALIAS (show_ip_bgp_neighbors_peer, ALIAS (show_ip_bgp_neighbors_peer, show_bgp_neighbors_peer_cmd, - "show bgp neighbors (A.B.C.D|X:X::X:X)", + "show bgp neighbors (A.B.C.D|X:X::X:X|WORD)", SHOW_STR BGP_STR "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" - "Neighbor to display information about\n") + "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n") ALIAS (show_ip_bgp_neighbors_peer, show_bgp_ipv6_neighbors_peer_cmd, - "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X)", + "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X|WORD)", SHOW_STR BGP_STR "Address family\n" "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" - "Neighbor to display information about\n") + "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n") DEFUN (show_ip_bgp_instance_neighbors, show_ip_bgp_instance_neighbors_cmd, @@ -8470,7 +8621,7 @@ ALIAS (show_ip_bgp_instance_neighbors, DEFUN (show_ip_bgp_instance_neighbors_peer, show_ip_bgp_instance_neighbors_peer_cmd, - "show ip bgp view WORD neighbors (A.B.C.D|X:X::X:X)", + "show ip bgp view WORD neighbors (A.B.C.D|X:X::X:X|WORD)", SHOW_STR IP_STR BGP_STR @@ -8478,25 +8629,27 @@ DEFUN (show_ip_bgp_instance_neighbors_peer, "View name\n" "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" - "Neighbor to display information about\n") + "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n") { return bgp_show_neighbor_vty (vty, argv[0], show_peer, argv[1]); } ALIAS (show_ip_bgp_instance_neighbors_peer, show_bgp_instance_neighbors_peer_cmd, - "show bgp view WORD neighbors (A.B.C.D|X:X::X:X)", + "show bgp view WORD neighbors (A.B.C.D|X:X::X:X|WORD)", SHOW_STR BGP_STR "BGP view\n" "View name\n" "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" - "Neighbor to display information about\n") + "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n") ALIAS (show_ip_bgp_instance_neighbors_peer, show_bgp_instance_ipv6_neighbors_peer_cmd, - "show bgp view WORD ipv6 neighbors (A.B.C.D|X:X::X:X)", + "show bgp view WORD ipv6 neighbors (A.B.C.D|X:X::X:X|WORD)", SHOW_STR BGP_STR "BGP view\n" @@ -8504,7 +8657,8 @@ ALIAS (show_ip_bgp_instance_neighbors_peer, "Address family\n" "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" - "Neighbor to display information about\n") + "Neighbor to display information about\n" + "Neighbor on bgp configured interface\n") /* Show BGP's AS paths internal data. There are both `show ip bgp paths' and `show ip mbgp paths'. Those functions results are the @@ -9579,13 +9733,15 @@ bgp_vty_init (void) /* "neighbor remote-as" commands. */ install_element (BGP_NODE, &neighbor_remote_as_cmd); + install_element (BGP_NODE, &neighbor_interface_config_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); /* "neighbor peer-group" commands. */ install_element (BGP_NODE, &neighbor_peer_group_cmd); install_element (BGP_NODE, &no_neighbor_peer_group_cmd); - install_element (BGP_NODE, &no_neighbor_peer_group_remote_as_cmd); + install_element (BGP_NODE, &no_neighbor_interface_peer_group_remote_as_cmd); /* "neighbor local-as" commands. */ install_element (BGP_NODE, &neighbor_local_as_cmd); diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index bea28bee5..72634ae1f 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -122,6 +122,46 @@ bgp_read_nexthop_update (int command, struct zclient *zclient, return 0; } +static void +bgp_nbr_connected_add (struct nbr_connected *ifc) +{ + struct listnode *node, *nnode, *mnode; + struct bgp *bgp; + struct peer *peer; + + for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp)) + { + for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer)) + { + if (peer->conf_if && (strcmp (peer->conf_if, ifc->ifp->name) == 0)) + { + if (peer_active(peer)) + BGP_EVENT_ADD (peer, BGP_Stop); + BGP_EVENT_ADD (peer, BGP_Start); + } + } + } +} + +static void +bgp_nbr_connected_delete (struct nbr_connected *ifc) +{ + struct listnode *node, *nnode, *mnode; + struct bgp *bgp; + struct peer *peer; + + for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp)) + { + for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer)) + { + if (peer->conf_if && (strcmp (peer->conf_if, ifc->ifp->name) == 0)) + { + BGP_EVENT_ADD (peer, BGP_Stop); + } + } + } +} + /* Inteface addition message from zebra. */ static int bgp_interface_add (int command, struct zclient *zclient, zebra_size_t length) @@ -159,6 +199,7 @@ bgp_interface_up (int command, struct zclient *zclient, zebra_size_t length) struct stream *s; struct interface *ifp; struct connected *c; + struct nbr_connected *nc; struct listnode *node, *nnode; s = zclient->ibuf; @@ -173,6 +214,9 @@ bgp_interface_up (int command, struct zclient *zclient, zebra_size_t length) for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c)) bgp_connected_add (c); + for (ALL_LIST_ELEMENTS (ifp->nbr_connected, node, nnode, nc)) + bgp_nbr_connected_add (nc); + return 0; } @@ -182,6 +226,7 @@ bgp_interface_down (int command, struct zclient *zclient, zebra_size_t length) struct stream *s; struct interface *ifp; struct connected *c; + struct nbr_connected *nc; struct listnode *node, *nnode; s = zclient->ibuf; @@ -195,6 +240,9 @@ bgp_interface_down (int command, struct zclient *zclient, zebra_size_t length) for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c)) bgp_connected_delete (c); + for (ALL_LIST_ELEMENTS (ifp->nbr_connected, node, nnode, nc)) + bgp_nbr_connected_delete (nc); + /* Fast external-failover */ { struct listnode *mnode; @@ -272,6 +320,58 @@ bgp_interface_address_delete (int command, struct zclient *zclient, return 0; } +static int +bgp_interface_nbr_address_add (int command, struct zclient *zclient, + zebra_size_t length) +{ + struct nbr_connected *ifc = NULL; + + ifc = zebra_interface_nbr_address_read (command, zclient->ibuf); + + if (ifc == NULL) + return 0; + + if (BGP_DEBUG(zebra, ZEBRA)) + { + char buf[128]; + prefix2str(ifc->address, buf, sizeof(buf)); + zlog_debug("Zebra rcvd: interface %s nbr address add %s", + ifc->ifp->name, buf); + } + + if (if_is_operative (ifc->ifp)) + bgp_nbr_connected_add (ifc); + + return 0; +} + +static int +bgp_interface_nbr_address_delete (int command, struct zclient *zclient, + zebra_size_t length) +{ + struct nbr_connected *ifc = NULL; + + ifc = zebra_interface_nbr_address_read (command, zclient->ibuf); + + if (ifc == NULL) + return 0; + + if (BGP_DEBUG(zebra, ZEBRA)) + { + char buf[128]; + prefix2str(ifc->address, buf, sizeof(buf)); + zlog_debug("Zebra rcvd: interface %s nbr address delete %s", + ifc->ifp->name, buf); + } + + if (if_is_operative (ifc->ifp)) + bgp_nbr_connected_delete (ifc); + + nbr_connected_free (ifc); + + return 0; +} + /* Zebra route add and delete treatment. */ static int zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length) @@ -619,8 +719,8 @@ bgp_nexthop_set (union sockunion *local, union sockunion *remote, { if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr)) { - if (peer->ifname) - ifp = if_lookup_by_index (if_nametoindex (peer->ifname)); + if (peer->conf_if || peer->ifname) + ifp = if_lookup_by_index (if_nametoindex (peer->conf_if ? peer->conf_if : peer->ifname)); } else ifp = if_lookup_by_ipv6 (&local->sin6.sin6_addr); @@ -979,8 +1079,8 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp, ifindex = info->peer->nexthop.ifp->ifindex; if (!ifindex) - if (info->peer->ifname) - ifindex = if_nametoindex (info->peer->ifname); + if (info->peer->conf_if || info->peer->ifname) + ifindex = if_nametoindex (info->peer->conf_if ? info->peer->conf_if : info->peer->ifname); else if (info->peer->nexthop.ifp) ifindex = info->peer->nexthop.ifp->ifindex; @@ -1017,8 +1117,8 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp, ifindex = mpinfo->peer->nexthop.ifp->ifindex; if (!ifindex) - if (mpinfo->peer->ifname) - ifindex = if_nametoindex (mpinfo->peer->ifname); + if (mpinfo->peer->conf_if || mpinfo->peer->ifname) + ifindex = if_nametoindex (mpinfo->peer->conf_if ? mpinfo->peer->conf_if : mpinfo->peer->ifname); else if (mpinfo->peer->nexthop.ifp) ifindex = mpinfo->peer->nexthop.ifp->ifindex; @@ -1165,8 +1265,8 @@ bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi) return; if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex) - if (info->peer->ifname) - ifindex = if_nametoindex (info->peer->ifname); + if (info->peer->conf_if || info->peer->ifname) + ifindex = if_nametoindex (info->peer->conf_if ? info->peer->conf_if : info->peer->ifname); api.flags = flags; api.type = ZEBRA_ROUTE_BGP; @@ -1340,6 +1440,8 @@ bgp_zebra_init (void) zclient->interface_delete = bgp_interface_delete; zclient->interface_address_add = bgp_interface_address_add; zclient->interface_address_delete = bgp_interface_address_delete; + zclient->interface_nbr_address_add = bgp_interface_nbr_address_add; + zclient->interface_nbr_address_delete = bgp_interface_nbr_address_delete; zclient->ipv4_route_add = zebra_read_ipv4; zclient->ipv4_route_delete = zebra_read_ipv4; zclient->interface_up = bgp_interface_up; diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 3fbf9e6ac..128e9d9cd 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -775,6 +775,10 @@ peer_free (struct peer *peer) work_queue_free (peer->clear_node_queue); bgp_sync_delete (peer); + + if (peer->conf_if) + XFREE (MTYPE_PEER_CONF_IF, peer->conf_if); + memset (peer, 0, sizeof (struct peer)); XFREE (MTYPE_BGP_PEER, peer); @@ -969,17 +973,62 @@ peer_xfer_config (struct peer *peer_dst, struct peer *peer_src) } } +/* + * Set or reset the peer address socketunion structure based on the + * learnt peer address. Currently via the source address of the + * ipv6 ND router-advertisement. + */ +void +bgp_peer_conf_if_to_su_update (struct peer *peer) +{ + struct interface *ifp; + struct nbr_connected *ifc; + + if (!peer->conf_if) + return; + + if ((ifp = if_lookup_by_name(peer->conf_if)) && + ifp->nbr_connected && + (ifc = listnode_head(ifp->nbr_connected))) + { + peer->su.sa.sa_family = AF_INET6; + memcpy(&peer->su.sin6.sin6_addr, &ifc->address->u.prefix, + sizeof (struct in6_addr)); +#ifdef SIN6_LEN + peer->su.sin6.sin6_len = sizeof (struct sockaddr_in6); +#endif + } + else + { + /* This works as an indication of unresolved peer address + on a BGP interface*/ + peer->su.sa.sa_family = AF_UNSPEC; + memset(&peer->su.sin6.sin6_addr, 0, sizeof (struct in6_addr)); + } +} + /* Create new BGP peer. */ struct peer * -peer_create (union sockunion *su, struct bgp *bgp, as_t local_as, - as_t remote_as, afi_t afi, safi_t safi) +peer_create (union sockunion *su, const char *conf_if, struct bgp *bgp, + as_t local_as, as_t remote_as, afi_t afi, safi_t safi) { int active; struct peer *peer; char buf[SU_ADDRSTRLEN]; peer = peer_new (bgp); - peer->su = *su; + if (conf_if) + { + peer->conf_if = XSTRDUP (MTYPE_PEER_CONF_IF, conf_if); + bgp_peer_conf_if_to_su_update(peer); + peer->host = XSTRDUP (MTYPE_BGP_PEER_HOST, conf_if); + } + else if (su) + { + peer->su = *su; + sockunion2str (su, buf, SU_ADDRSTRLEN); + peer->host = XSTRDUP (MTYPE_BGP_PEER_HOST, buf); + } peer->local_as = local_as; peer->as = remote_as; peer->local_id = bgp->router_id; @@ -1006,10 +1055,6 @@ peer_create (union sockunion *su, struct bgp *bgp, as_t local_as, SET_FLAG (peer->flags, PEER_FLAG_CONFIG_NODE); - /* Make peer's address string. */ - sockunion2str (su, buf, SU_ADDRSTRLEN); - peer->host = XSTRDUP (MTYPE_BGP_PEER_HOST, buf); - /* Set up peer's events and timers. */ if (! active && peer_active (peer)) bgp_timer_set (peer); @@ -1017,6 +1062,26 @@ peer_create (union sockunion *su, struct bgp *bgp, as_t local_as, return peer; } +struct peer * +peer_conf_interface_get(struct bgp *bgp, const char *conf_if, afi_t afi, + safi_t safi) +{ + struct peer *peer; + + 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, 0, 0); + else + peer = peer_create (NULL, conf_if, bgp, bgp->as, 0, afi, safi); + + } + + return peer; +} + /* Make accept BGP peer. Called from bgp_accept (). */ struct peer * peer_create_accept (struct bgp *bgp) @@ -1032,7 +1097,7 @@ peer_create_accept (struct bgp *bgp) } /* Change peer's AS number. */ -static void +void peer_as_change (struct peer *peer, as_t as) { bgp_peer_sort_t type; @@ -1106,13 +1171,16 @@ peer_as_change (struct peer *peer, as_t as) /* If peer does not exist, create new one. If peer already exists, set AS number to the peer. */ int -peer_remote_as (struct bgp *bgp, union sockunion *su, as_t *as, - afi_t afi, safi_t safi) +peer_remote_as (struct bgp *bgp, union sockunion *su, const char *conf_if, as_t *as, + afi_t afi, safi_t safi) { struct peer *peer; as_t local_as; - peer = peer_lookup (bgp, su); + if (conf_if) + peer = peer_lookup_by_conf_if (bgp, conf_if); + else + peer = peer_lookup (bgp, su); if (peer) { @@ -1149,6 +1217,8 @@ peer_remote_as (struct bgp *bgp, union sockunion *su, as_t *as, } else { + if (conf_if) + return BGP_ERR_NO_INTERFACE_CONFIG; /* If the peer is not part of our confederation, and its not an iBGP peer then spoof the source AS */ @@ -1164,9 +1234,9 @@ peer_remote_as (struct bgp *bgp, union sockunion *su, as_t *as, if (bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4) && afi == AFI_IP && safi == SAFI_UNICAST) - peer = peer_create (su, bgp, local_as, *as, 0, 0); + peer = peer_create (su, conf_if, bgp, local_as, *as, 0, 0); else - peer = peer_create (su, bgp, local_as, *as, afi, safi); + peer = peer_create (su, conf_if, bgp, local_as, *as, afi, safi); } return 0; @@ -1908,10 +1978,9 @@ peer_group_remote_as_delete (struct peer_group *group) /* Bind specified peer to peer group. */ int -peer_group_bind (struct bgp *bgp, union sockunion *su, +peer_group_bind (struct bgp *bgp, union sockunion *su, struct peer *peer, struct peer_group *group, afi_t afi, safi_t safi, as_t *as) { - struct peer *peer; int first_member = 0; /* Check peer group's address family. */ @@ -1919,7 +1988,8 @@ peer_group_bind (struct bgp *bgp, union sockunion *su, return BGP_ERR_PEER_GROUP_AF_UNCONFIGURED; /* Lookup the peer. */ - peer = peer_lookup (bgp, su); + if (!peer) + peer = peer_lookup (bgp, su); /* Create a new peer. */ if (! peer) @@ -1927,7 +1997,7 @@ peer_group_bind (struct bgp *bgp, union sockunion *su, if (! group->conf->as) return BGP_ERR_PEER_GROUP_NO_REMOTE_AS; - peer = peer_create (su, bgp, bgp->as, group->conf->as, afi, safi); + peer = peer_create (su, NULL, bgp, bgp->as, group->conf->as, afi, safi); peer->group = group; peer->af_group[afi][safi] = 1; @@ -2382,6 +2452,35 @@ bgp_free (struct bgp *bgp) XFREE (MTYPE_BGP, bgp); } +struct peer * +peer_lookup_by_conf_if (struct bgp *bgp, const char *conf_if) +{ + struct peer *peer; + struct listnode *node, *nnode; + + if (!conf_if) + return NULL; + + if (bgp != NULL) + { + for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer)) + if (peer->conf_if && !strcmp(peer->conf_if, conf_if) + && ! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER)) + return peer; + } + else if (bm->bgp != NULL) + { + struct listnode *bgpnode, *nbgpnode; + + for (ALL_LIST_ELEMENTS (bm->bgp, bgpnode, nbgpnode, bgp)) + for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer)) + if (peer->conf_if && !strcmp(peer->conf_if, conf_if) + && ! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER)) + return peer; + } + return NULL; +} + struct peer * peer_lookup (struct bgp *bgp, union sockunion *su) { @@ -2412,6 +2511,8 @@ peer_lookup (struct bgp *bgp, union sockunion *su) int peer_active (struct peer *peer) { + if (BGP_PEER_SU_UNSPEC(peer)) + return 0; if (peer->afc[AFI_IP][SAFI_UNICAST] || peer->afc[AFI_IP][SAFI_MULTICAST] || peer->afc[AFI_IP][SAFI_MPLS_VPN] @@ -2877,7 +2978,7 @@ peer_ebgp_multihop_set (struct peer *peer, int ttl) struct listnode *node, *nnode; struct peer *peer1; - if (peer->sort == BGP_PEER_IBGP) + if (peer->sort == BGP_PEER_IBGP || peer->conf_if) return 0; /* see comment in peer_ttl_security_hops_set() */ @@ -5029,7 +5130,11 @@ bgp_config_write_peer (struct vty *vty, struct bgp *bgp, char buf[SU_ADDRSTRLEN]; char *addr; - addr = peer->host; + if (peer->conf_if) + addr = peer->conf_if; + else + addr = peer->host; + if (peer_group_active (peer)) g_peer = peer->group->conf; @@ -5038,6 +5143,9 @@ bgp_config_write_peer (struct vty *vty, struct bgp *bgp, ************************************/ if (afi == AFI_IP && safi == SAFI_UNICAST) { + if (peer->conf_if) + vty_out (vty, " neighbor %s interface%s", addr, VTY_NEWLINE); + /* remote-as. */ if (! peer_group_active (peer)) { diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 40e3d2abe..752c637ef 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -370,11 +370,13 @@ struct peer unsigned short port; /* Destination port for peer */ char *host; /* Printable address of the peer. */ union sockunion su; /* Sockunion address of the peer. */ +#define BGP_PEER_SU_UNSPEC(peer) (peer->su.sa.sa_family == AF_UNSPEC) time_t uptime; /* Last Up/Down time */ time_t readtime; /* Last read time */ time_t resettime; /* Last reset time */ unsigned int ifindex; /* ifindex of the BGP connection. */ + char *conf_if; /* neighbor interface config name. */ char *ifname; /* bind interface name. */ char *update_if; union sockunion *update_source; @@ -865,8 +867,9 @@ enum bgp_clear_type #define BGP_ERR_TCPSIG_FAILED -29 #define BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK -30 #define BGP_ERR_NO_IBGP_WITH_TTLHACK -31 -#define BGP_ERR_MAX -32 +#define BGP_ERR_NO_INTERFACE_CONFIG -32 #define BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS -33 +#define BGP_ERR_MAX -34 extern struct bgp_master *bm; @@ -883,6 +886,10 @@ extern struct bgp *bgp_get_default (void); extern struct bgp *bgp_lookup (as_t, const char *); extern struct bgp *bgp_lookup_by_name (const char *); extern struct peer *peer_lookup (struct bgp *, union sockunion *); +extern struct peer *peer_lookup_by_conf_if (struct bgp *, const char *); +extern struct peer *peer_conf_interface_get(struct bgp *, const char *, afi_t, + safi_t); +extern void bgp_peer_conf_if_to_su_update (struct peer *); extern struct peer_group *peer_group_lookup (struct bgp *, const char *); extern struct peer_group *peer_group_get (struct bgp *, const char *); extern struct peer *peer_lock (struct peer *); @@ -890,8 +897,8 @@ extern struct peer *peer_unlock (struct peer *); extern bgp_peer_sort_t peer_sort (struct peer *peer); extern int peer_active (struct peer *); extern int peer_active_nego (struct peer *); -extern struct peer *peer_create(union sockunion *su, struct bgp *bgp, as_t local_as, - as_t remote_as, afi_t afi, safi_t safi); +extern struct peer *peer_create(union sockunion *, const char *, struct bgp *, + as_t, as_t, afi_t, safi_t); extern struct peer *peer_create_accept (struct bgp *); extern void peer_xfer_config (struct peer *dst, struct peer *src); extern char *peer_uptime (time_t, char *, size_t); @@ -938,8 +945,9 @@ extern int bgp_default_local_preference_unset (struct bgp *); extern int bgp_update_delay_active (struct bgp *); extern int bgp_update_delay_configured (struct bgp *); extern int peer_rsclient_active (struct peer *); - -extern int peer_remote_as (struct bgp *, union sockunion *, as_t *, afi_t, safi_t); +extern void peer_as_change (struct peer *, as_t); +extern int peer_remote_as (struct bgp *, union sockunion *,const char *, as_t *, + afi_t, safi_t); extern int peer_group_remote_as (struct bgp *, const char *, as_t *); extern int peer_delete (struct peer *peer); extern int peer_group_delete (struct peer_group *); @@ -948,8 +956,8 @@ extern int peer_group_remote_as_delete (struct peer_group *); extern int peer_activate (struct peer *, afi_t, safi_t); extern int peer_deactivate (struct peer *, afi_t, safi_t); -extern int peer_group_bind (struct bgp *, union sockunion *, struct peer_group *, - afi_t, safi_t, as_t *); +extern int peer_group_bind (struct bgp *, union sockunion *, struct peer *, + struct peer_group *, afi_t, safi_t, as_t *); extern int peer_group_unbind (struct bgp *, struct peer *, struct peer_group *, afi_t, safi_t); diff --git a/lib/command.h b/lib/command.h index e47c42552..370b21614 100644 --- a/lib/command.h +++ b/lib/command.h @@ -493,7 +493,8 @@ struct cmd_token #define NEIGHBOR_ADDR_STR "Neighbor address\nIPv6 address\n" #define NEIGHBOR_CMD2 "neighbor (A.B.C.D|X:X::X:X|WORD) " #define NO_NEIGHBOR_CMD2 "no neighbor (A.B.C.D|X:X::X:X|WORD) " -#define NEIGHBOR_ADDR_STR2 "Neighbor address\nNeighbor IPv6 address\nNeighbor tag\n" +#define NEIGHBOR_ADDR_STR2 "Neighbor address\nNeighbor IPv6 address\nInterface name or neighbor tag\n" +#define NEIGHBOR_ADDR_STR3 "Neighbor address\nIPv6 address\nInterface name\n" #else #define NEIGHBOR_CMD "neighbor A.B.C.D " #define NO_NEIGHBOR_CMD "no neighbor A.B.C.D " diff --git a/lib/if.c b/lib/if.c index 532966410..3425e3a8b 100644 --- a/lib/if.c +++ b/lib/if.c @@ -132,6 +132,9 @@ if_create (const char *name, int namelen) ifp->connected = list_new (); ifp->connected->del = (void (*) (void *)) connected_free; + ifp->nbr_connected = list_new (); + ifp->nbr_connected->del = (void (*) (void *)) nbr_connected_free; + /* Enable Link-detection by default */ SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION); @@ -150,6 +153,9 @@ if_delete_retain (struct interface *ifp) /* Free connected address list */ list_delete_all_node (ifp->connected); + + /* Free connected nbr address list */ + list_delete_all_node (ifp->nbr_connected); } /* Delete and free interface structure. */ @@ -161,6 +167,7 @@ if_delete (struct interface *ifp) if_delete_retain(ifp); list_free (ifp->connected); + list_free (ifp->nbr_connected); XFREE (MTYPE_IF, ifp); } @@ -652,6 +659,13 @@ connected_new (void) return XCALLOC (MTYPE_CONNECTED, sizeof (struct connected)); } +/* Allocate nbr connected structure. */ +struct nbr_connected * +nbr_connected_new (void) +{ + return XCALLOC (MTYPE_NBR_CONNECTED, sizeof (struct nbr_connected)); +} + /* Free connected structure. */ void connected_free (struct connected *connected) @@ -668,6 +682,30 @@ connected_free (struct connected *connected) XFREE (MTYPE_CONNECTED, connected); } +/* Free nbr connected structure. */ +void +nbr_connected_free (struct nbr_connected *connected) +{ + if (connected->address) + prefix_free (connected->address); + + XFREE (MTYPE_NBR_CONNECTED, connected); +} + +/* If same interface nbr address already exists... */ +struct nbr_connected * +nbr_connected_check (struct interface *ifp, struct prefix *p) +{ + struct nbr_connected *ifc; + struct listnode *node; + + for (ALL_LIST_ELEMENTS_RO (ifp->nbr_connected, node, ifc)) + if (prefix_same (ifc->address, p)) + return ifc; + + return NULL; +} + /* Print if_addr structure. */ static void __attribute__ ((unused)) connected_log (struct connected *connected, char *str) @@ -694,6 +732,26 @@ connected_log (struct connected *connected, char *str) zlog (NULL, LOG_INFO, "%s", logbuf); } +/* Print if_addr structure. */ +static void __attribute__ ((unused)) +nbr_connected_log (struct nbr_connected *connected, char *str) +{ + struct prefix *p; + struct interface *ifp; + char logbuf[BUFSIZ]; + char buf[BUFSIZ]; + + ifp = connected->ifp; + p = connected->address; + + snprintf (logbuf, BUFSIZ, "%s interface %s %s %s/%d ", + str, ifp->name, prefix_family_str (p), + inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ), + p->prefixlen); + + zlog (NULL, LOG_INFO, "%s", logbuf); +} + /* If two connected address has same prefix return 1. */ static int connected_same_prefix (struct prefix *p1, struct prefix *p2) diff --git a/lib/if.h b/lib/if.h index 8081be87d..80b62e6e6 100644 --- a/lib/if.h +++ b/lib/if.h @@ -129,6 +129,9 @@ struct interface /* Connected address list. */ struct list *connected; + /* Neighbor connected address list. */ + struct list *nbr_connected; + /* Daemon specific interface data pointer. */ void *info; @@ -185,6 +188,16 @@ struct connected char *label; }; +/* Nbr Connected address structure. */ +struct nbr_connected +{ + /* Attached interface. */ + struct interface *ifp; + + /* Address of connected network. */ + struct prefix *address; +}; + /* Does the destination field contain a peer address? */ #define CONNECTED_PEER(C) CHECK_FLAG((C)->flags, ZEBRA_IFA_PEER) @@ -303,6 +316,9 @@ extern struct connected *connected_delete_by_prefix (struct interface *, struct prefix *); extern struct connected *connected_lookup_address (struct interface *, struct in_addr); +extern struct nbr_connected *nbr_connected_new (void); +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 *); diff --git a/lib/log.c b/lib/log.c index 7e03aa9af..99a5aadd9 100644 --- a/lib/log.c +++ b/lib/log.c @@ -848,6 +848,8 @@ static const struct zebra_desc_table command_types[] = { DESC_ENTRY (ZEBRA_NEXTHOP_REGISTER), DESC_ENTRY (ZEBRA_NEXTHOP_UNREGISTER), DESC_ENTRY (ZEBRA_NEXTHOP_UPDATE), + DESC_ENTRY (ZEBRA_INTERFACE_NBR_ADDRESS_ADD), + DESC_ENTRY (ZEBRA_INTERFACE_NBR_ADDRESS_DELETE), }; #undef DESC_ENTRY diff --git a/lib/memtypes.c b/lib/memtypes.c index 5af2642be..f418b3d0a 100644 --- a/lib/memtypes.c +++ b/lib/memtypes.c @@ -26,6 +26,7 @@ struct memory_list memory_list_lib[] = { MTYPE_VTY_HIST, "VTY history" }, { MTYPE_IF, "Interface" }, { MTYPE_CONNECTED, "Connected" }, + { MTYPE_NBR_CONNECTED, "Neighbor Connected" }, { MTYPE_CONNECTED_LABEL, "Connected interface label" }, { MTYPE_BUFFER, "Buffer" }, { MTYPE_BUFFER_DATA, "Buffer data" }, @@ -148,6 +149,7 @@ struct memory_list memory_list_bgp[] = { MTYPE_BGP_NEXTHOP_CACHE, "BGP nexthop" }, { MTYPE_BGP_CONFED_LIST, "BGP confed list" }, { MTYPE_PEER_UPDATE_SOURCE, "BGP peer update interface" }, + { MTYPE_PEER_CONF_IF, "BGP peer config interface" }, { MTYPE_BGP_DAMP_INFO, "Dampening info" }, { MTYPE_BGP_DAMP_ARRAY, "BGP Dampening array" }, { MTYPE_BGP_REGEXP, "BGP regexp" }, diff --git a/lib/zclient.c b/lib/zclient.c index b77fd3432..fab130f64 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -826,6 +826,81 @@ zebra_interface_address_read (int type, struct stream *s) return ifc; } +/* + * format of message for neighbor connected address is: + * 0 + * 0 1 2 3 4 5 6 7 + * +-+-+-+-+-+-+-+-+ + * | type | ZEBRA_INTERFACE_NBR_ADDRESS_ADD or + * +-+-+-+-+-+-+-+-+ ZEBRA_INTERFACE_NBR_ADDRES_DELETE + * | | + * + + + * | ifindex | + * + + + * | | + * + + + * | | + * +-+-+-+-+-+-+-+-+ + * | addr_family | + * +-+-+-+-+-+-+-+-+ + * | addr... | + * : : + * | | + * +-+-+-+-+-+-+-+-+ + * | addr_len | len of addr. + * +-+-+-+-+-+-+-+-+ + */ +struct nbr_connected * +zebra_interface_nbr_address_read (int type, struct stream *s) +{ + unsigned int ifindex; + struct interface *ifp; + struct prefix p; + struct nbr_connected *ifc; + + /* Get interface index. */ + ifindex = stream_getl (s); + + /* Lookup index. */ + ifp = if_lookup_by_index (ifindex); + if (ifp == NULL) + { + zlog_warn ("zebra_nbr_interface_address_read(%s): " + "Can't find interface by ifindex: %d ", + (type == ZEBRA_INTERFACE_NBR_ADDRESS_ADD? "ADD" : "DELETE"), + ifindex); + return NULL; + } + + p.family = stream_getc (s); + stream_get (&p.u.prefix, s, prefix_blen (&p)); + p.prefixlen = stream_getc (s); + + if (type == ZEBRA_INTERFACE_NBR_ADDRESS_ADD) + { + /* Currently only supporting P2P links, so any new RA source address is + considered as the replacement of the previously learnt Link-Local address. */ + if (!(ifc = listnode_head(ifp->nbr_connected))) + { + ifc = nbr_connected_new (); + ifc->address = prefix_new (); + ifc->ifp = ifp; + listnode_add (ifp->nbr_connected, ifc); + } + + prefix_copy(ifc->address, &p); + } + else + { + assert (type == ZEBRA_INTERFACE_NBR_ADDRESS_DELETE); + + ifc = nbr_connected_check(ifp, &p); + if (ifc) + listnode_delete (ifp->nbr_connected, ifc); + } + + return ifc; +} /* Zebra client message read function. */ static int @@ -943,6 +1018,14 @@ zclient_read (struct thread *thread) if (zclient->interface_address_delete) (*zclient->interface_address_delete) (command, zclient, length); break; + case ZEBRA_INTERFACE_NBR_ADDRESS_ADD: + if (zclient->interface_nbr_address_add) + (*zclient->interface_nbr_address_add) (command, zclient, length); + break; + case ZEBRA_INTERFACE_NBR_ADDRESS_DELETE: + if (zclient->interface_nbr_address_delete) + (*zclient->interface_nbr_address_delete) (command, zclient, length); + break; case ZEBRA_INTERFACE_UP: if (zclient->interface_up) (*zclient->interface_up) (command, zclient, length); diff --git a/lib/zclient.h b/lib/zclient.h index 2ece81ebc..5c24ee459 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -78,6 +78,8 @@ struct zclient int (*interface_down) (int, struct zclient *, uint16_t); int (*interface_address_add) (int, struct zclient *, uint16_t); int (*interface_address_delete) (int, struct zclient *, uint16_t); + int (*interface_nbr_address_add) (int, struct zclient *, uint16_t); + int (*interface_nbr_address_delete) (int, struct zclient *, uint16_t); int (*ipv4_route_add) (int, struct zclient *, uint16_t); int (*ipv4_route_delete) (int, struct zclient *, uint16_t); int (*ipv6_route_add) (int, struct zclient *, uint16_t); @@ -155,6 +157,7 @@ extern void zclient_create_header (struct stream *, uint16_t); extern struct interface *zebra_interface_add_read (struct stream *); extern struct interface *zebra_interface_state_read (struct stream *s); extern struct connected *zebra_interface_address_read (int, struct stream *); +extern struct nbr_connected *zebra_interface_nbr_address_read (int, struct stream *); extern void zebra_interface_if_set_value (struct stream *, struct interface *); extern void zebra_router_id_update_read (struct stream *s, struct prefix *rid); extern int zapi_ipv4_route (u_char, struct zclient *, struct prefix_ipv4 *, diff --git a/lib/zebra.h b/lib/zebra.h index 124431a85..7d68530ba 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -427,7 +427,9 @@ struct in_pktinfo #define ZEBRA_NEXTHOP_REGISTER 24 #define ZEBRA_NEXTHOP_UNREGISTER 25 #define ZEBRA_NEXTHOP_UPDATE 26 -#define ZEBRA_MESSAGE_MAX 27 +#define ZEBRA_INTERFACE_NBR_ADDRESS_ADD 27 +#define ZEBRA_INTERFACE_NBR_ADDRESS_DELETE 28 +#define ZEBRA_MESSAGE_MAX 29 /* Marker value used in new Zserv, in the byte location corresponding * the command value in the old zserv header. To allow old and new diff --git a/zebra/interface.c b/zebra/interface.c index 7e1d3dd86..fe5e3e2be 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -633,6 +633,21 @@ connected_dump_vty (struct vty *vty, struct connected *connected) vty_out (vty, "%s", VTY_NEWLINE); } +/* Dump interface neighbor address information to vty. */ +static void +nbr_connected_dump_vty (struct vty *vty, struct nbr_connected *connected) +{ + struct prefix *p; + + /* Print interface address. */ + p = connected->address; + vty_out (vty, " %s ", prefix_family_str (p)); + prefix_vty_out (vty, p); + vty_out (vty, "/%d", p->prefixlen); + + vty_out (vty, "%s", VTY_NEWLINE); +} + #ifdef RTADV /* Dump interface ND information to vty. */ static void @@ -704,6 +719,7 @@ if_dump_vty (struct vty *vty, struct interface *ifp) struct sockaddr_dl *sdl; #endif /* HAVE_STRUCT_SOCKADDR_DL */ struct connected *connected; + struct nbr_connected *nbr_connected; struct listnode *node; struct route_node *rn; struct zebra_if *zebra_if; @@ -802,6 +818,10 @@ if_dump_vty (struct vty *vty, struct interface *ifp) #ifdef RTADV nd_dump_vty (vty, ifp); #endif /* RTADV */ + if (listhead(ifp->nbr_connected)) + vty_out (vty, " Neighbor address(s):%s", VTY_NEWLINE); + for (ALL_LIST_ELEMENTS_RO (ifp->nbr_connected, node, nbr_connected)) + nbr_connected_dump_vty (vty, nbr_connected); #ifdef HAVE_PROC_NET_DEV /* Statistics print out using proc file system. */ diff --git a/zebra/rtadv.c b/zebra/rtadv.c index 21ca6da99..3188212c5 100644 --- a/zebra/rtadv.c +++ b/zebra/rtadv.c @@ -437,13 +437,82 @@ rtadv_process_solicit (struct interface *ifp) } static void -rtadv_process_advert (void) +rtadv_process_advert (u_char *msg, unsigned int len, struct interface *ifp, + struct sockaddr_in6 *addr) { - zlog_info ("Router advertisement received"); + struct nd_router_advert *radvert; + char addr_str[INET6_ADDRSTRLEN]; + struct zebra_if *zif; + + zif = ifp->info; + + inet_ntop (AF_INET6, &addr->sin6_addr, addr_str, INET6_ADDRSTRLEN); + + zlog_info ("Router advertisement received on %s from : %s", ifp->name, addr_str); + + if (len < sizeof(struct nd_router_advert)) { + zlog_warn("received icmpv6 RA packet with invalid length (%d) from %s", + len, addr_str); + return; + } + if (!IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr)) { + zlog_warn("received icmpv6 RA packet with non-linklocal source address from %s", + addr_str); + return; + } + + radvert = (struct nd_router_advert *) msg; + + if ((radvert->nd_ra_curhoplimit && zif->rtadv.AdvCurHopLimit) && + (radvert->nd_ra_curhoplimit != zif->rtadv.AdvCurHopLimit)) + { + zlog_warn("our AdvCurHopLimit on %s doesn't agree with %s", + ifp->name, addr_str); + } + + if ((radvert->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) && + !zif->rtadv.AdvManagedFlag) + { + zlog_warn("our AdvManagedFlag on %s doesn't agree with %s", + ifp->name, addr_str); + } + + if ((radvert->nd_ra_flags_reserved & ND_RA_FLAG_OTHER) && + !zif->rtadv.AdvOtherConfigFlag) + { + zlog_warn("our AdvOtherConfigFlag on %s doesn't agree with %s", + ifp->name, addr_str); + } + + if ((radvert->nd_ra_reachable && zif->rtadv.AdvReachableTime) && + (ntohl(radvert->nd_ra_reachable) != zif->rtadv.AdvReachableTime)) + { + zlog_warn("our AdvReachableTime on %s doesn't agree with %s", + ifp->name, addr_str); + } + + if ((radvert->nd_ra_retransmit && zif->rtadv.AdvRetransTimer) && + (ntohl(radvert->nd_ra_retransmit) != zif->rtadv.AdvRetransTimer)) + { + zlog_warn("our AdvRetransTimer on %s doesn't agree with %s", + ifp->name, addr_str); + } + + /* Currently supporting only P2P links, so any new RA source address is + considered as the replacement of the previously learnt Link-Local address. + As per the RFC, lifetime zero is to be considered a delete */ + if (ntohs(radvert->nd_ra_router_lifetime)) + nbr_connected_replacement_add_ipv6(ifp, &addr->sin6_addr, 128); + else + nbr_connected_delete_ipv6(ifp, &addr->sin6_addr, 128); + + return; } + static void -rtadv_process_packet (u_char *buf, unsigned int len, unsigned int ifindex, int hoplimit) +rtadv_process_packet (u_char *buf, unsigned int len, unsigned int ifindex, int hoplimit, + struct sockaddr_in6 *from) { struct icmp6_hdr *icmph; struct interface *ifp; @@ -494,7 +563,7 @@ rtadv_process_packet (u_char *buf, unsigned int len, unsigned int ifindex, int h if (icmph->icmp6_type == ND_ROUTER_SOLICIT) rtadv_process_solicit (ifp); else if (icmph->icmp6_type == ND_ROUTER_ADVERT) - rtadv_process_advert (); + rtadv_process_advert (buf, len, ifp, from); return; } @@ -523,7 +592,7 @@ rtadv_read (struct thread *thread) return len; } - rtadv_process_packet (buf, (unsigned)len, ifindex, hoplimit); + rtadv_process_packet (buf, (unsigned)len, ifindex, hoplimit, &from); return 0; } diff --git a/zebra/zserv.c b/zebra/zserv.c index ecb3bd05d..98b6f91c9 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -299,6 +299,143 @@ zsend_interface_address (int cmd, struct zserv *client, return zebra_server_send_message(client); } +static int +zsend_interface_nbr_address (int cmd, struct zserv *client, + struct interface *ifp, struct nbr_connected *ifc) +{ + int blen; + struct stream *s; + struct prefix *p; + + /* Check this client need interface information. */ + if (! client->ifinfo) + return 0; + + s = client->obuf; + stream_reset (s); + + zserv_create_header (s, cmd); + stream_putl (s, ifp->ifindex); + + /* Prefix information. */ + p = ifc->address; + stream_putc (s, p->family); + blen = prefix_blen (p); + stream_put (s, &p->u.prefix, blen); + + /* + * XXX gnu version does not send prefixlen for ZEBRA_INTERFACE_ADDRESS_DELETE + * but zebra_interface_address_delete_read() in the gnu version + * expects to find it + */ + stream_putc (s, p->prefixlen); + + /* Write packet size. */ + stream_putw_at (s, 0, stream_get_endp (s)); + + return zebra_server_send_message(client); +} + +/* Interface address addition. */ +static void +zebra_interface_nbr_address_add_update (struct interface *ifp, + struct nbr_connected *ifc) +{ + struct listnode *node, *nnode; + struct zserv *client; + struct prefix *p; + + if (IS_ZEBRA_DEBUG_EVENT) + { + char buf[INET6_ADDRSTRLEN]; + + p = ifc->address; + zlog_debug ("MESSAGE: ZEBRA_INTERFACE_NBR_ADDRESS_ADD %s/%d on %s", + inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN), + p->prefixlen, ifc->ifp->name); + } + + for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client)) + if (client->ifinfo) + zsend_interface_nbr_address (ZEBRA_INTERFACE_NBR_ADDRESS_ADD, client, ifp, ifc); +} + +/* Interface address deletion. */ +static void +zebra_interface_nbr_address_delete_update (struct interface *ifp, + struct nbr_connected *ifc) +{ + struct listnode *node, *nnode; + struct zserv *client; + struct prefix *p; + + if (IS_ZEBRA_DEBUG_EVENT) + { + char buf[INET6_ADDRSTRLEN]; + + p = ifc->address; + zlog_debug ("MESSAGE: ZEBRA_INTERFACE_NBR_ADDRESS_DELETE %s/%d on %s", + inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN), + p->prefixlen, ifc->ifp->name); + } + + for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client)) + if (client->ifinfo) + zsend_interface_nbr_address (ZEBRA_INTERFACE_NBR_ADDRESS_DELETE, client, ifp, ifc); +} + +/* Add new nbr connected IPv6 address if none exists already, or replace the + existing one if an ifc entry is found on the interface. */ +void +nbr_connected_replacement_add_ipv6 (struct interface *ifp, struct in6_addr *address, + u_char prefixlen) +{ + struct nbr_connected *ifc; + struct prefix p; + + p.family = AF_INET6; + IPV6_ADDR_COPY (&p.u.prefix, address); + p.prefixlen = prefixlen; + + if (nbr_connected_check(ifp, &p)) + return; + + if (!(ifc = listnode_head(ifp->nbr_connected))) + { + /* new addition */ + ifc = nbr_connected_new (); + ifc->address = prefix_new(); + ifc->ifp = ifp; + listnode_add (ifp->nbr_connected, ifc); + } + + prefix_copy(ifc->address, &p); + + zebra_interface_nbr_address_add_update (ifp, ifc); +} + +void +nbr_connected_delete_ipv6 (struct interface *ifp, struct in6_addr *address, + u_char prefixlen) +{ + struct nbr_connected *ifc; + struct prefix p; + + p.family = AF_INET6; + IPV6_ADDR_COPY (&p.u.prefix, address); + p.prefixlen = prefixlen; + + ifc = nbr_connected_check(ifp, &p); + if (!ifc) + return; + + listnode_delete (ifp->nbr_connected, ifc); + + zebra_interface_nbr_address_delete_update (ifp, ifc); + + nbr_connected_free (ifc); +} + /* * The cmd passed to zsend_interface_update may be ZEBRA_INTERFACE_UP or * ZEBRA_INTERFACE_DOWN. @@ -761,6 +898,7 @@ zread_interface_add (struct zserv *client, u_short length) struct listnode *cnode, *cnnode; struct interface *ifp; struct connected *c; + struct nbr_connected *nc; /* Interface information is needed. */ client->ifinfo = 1; @@ -781,6 +919,13 @@ zread_interface_add (struct zserv *client, u_short length) ifp, c) < 0)) return -1; } + for (ALL_LIST_ELEMENTS (ifp->nbr_connected, cnode, cnnode, nc)) + { + if (zsend_interface_nbr_address (ZEBRA_INTERFACE_NBR_ADDRESS_ADD, client, + ifp, nc) < 0) + return -1; + } + } return 0; } diff --git a/zebra/zserv.h b/zebra/zserv.h index 92b8ba3a6..edcfee0d4 100644 --- a/zebra/zserv.h +++ b/zebra/zserv.h @@ -106,6 +106,9 @@ extern int zsend_interface_add (struct zserv *, struct interface *); extern int zsend_interface_delete (struct zserv *, struct interface *); extern int zsend_interface_address (int, struct zserv *, struct interface *, struct connected *); +extern void nbr_connected_replacement_add_ipv6 (struct interface *, + struct in6_addr *, u_char); +extern void nbr_connected_delete_ipv6 (struct interface *, struct in6_addr *, u_char); extern int zsend_interface_update (int, struct zserv *, struct interface *); extern int zsend_route_multipath (int, struct zserv *, struct prefix *, struct rib *); -- 2.39.5