summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlin Năstac <mrness@gentoo.org>2005-06-15 19:45:45 +0000
committerAlin Năstac <mrness@gentoo.org>2005-06-15 19:45:45 +0000
commit66408ea126204fb1adc4fb35f6a2ae764ca3667e (patch)
tree0bb620209f8a7b8229b1d8941d8180d7907ce5f2 /net-misc/quagga/files
parentmarked stable on x86 (diff)
downloadgentoo-2-66408ea126204fb1adc4fb35f6a2ae764ca3667e.tar.gz
gentoo-2-66408ea126204fb1adc4fb35f6a2ae764ca3667e.tar.bz2
gentoo-2-66408ea126204fb1adc4fb35f6a2ae764ca3667e.zip
version bump
(Portage version: 2.0.51.19)
Diffstat (limited to 'net-misc/quagga/files')
-rw-r--r--net-misc/quagga/files/digest-quagga-0.98.31
-rw-r--r--net-misc/quagga/files/patches-0.98.3/amir-connected-route.patch222
-rw-r--r--net-misc/quagga/files/patches-0.98.3/ht-20040304-classless-bgp.patch43
-rw-r--r--net-misc/quagga/files/patches-0.98.3/ht-20050110-0.98.0-bgp-md5.patch481
4 files changed, 747 insertions, 0 deletions
diff --git a/net-misc/quagga/files/digest-quagga-0.98.3 b/net-misc/quagga/files/digest-quagga-0.98.3
new file mode 100644
index 000000000000..cc7f58890ba8
--- /dev/null
+++ b/net-misc/quagga/files/digest-quagga-0.98.3
@@ -0,0 +1 @@
+MD5 68be5e911e4d604c0f5959338263356e quagga-0.98.3.tar.gz 2118348
diff --git a/net-misc/quagga/files/patches-0.98.3/amir-connected-route.patch b/net-misc/quagga/files/patches-0.98.3/amir-connected-route.patch
new file mode 100644
index 000000000000..40b660624050
--- /dev/null
+++ b/net-misc/quagga/files/patches-0.98.3/amir-connected-route.patch
@@ -0,0 +1,222 @@
+diff -Nur quagga-0.98.3.orig/zebra/connected.c quagga-0.98.3/zebra/connected.c
+--- quagga-0.98.3.orig/zebra/connected.c 2005-03-12 20:54:45.000000000 +0200
++++ quagga-0.98.3/zebra/connected.c 2005-06-15 08:33:06.012693968 +0300
+@@ -29,6 +29,7 @@
+ #include "rib.h"
+ #include "table.h"
+ #include "log.h"
++#include "rt.h"
+
+ #include "zebra/zserv.h"
+ #include "zebra/redistribute.h"
+@@ -85,6 +86,8 @@
+ rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0, 0, 0);
+
+ rib_update ();
++
++ kernel_connected_up(ifc);
+ }
+
+ /* Add connected IPv4 route to the interface. */
+@@ -221,6 +224,8 @@
+ rib_delete_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0);
+
+ rib_update ();
++
++ kernel_connected_down(ifc);
+ }
+
+ /* Delete connected IPv4 route to the interface. */
+@@ -314,6 +319,8 @@
+ rib_add_ipv6 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0);
+
+ rib_update ();
++
++ kernel_connected_up(ifc);
+ }
+
+ /* Add connected IPv6 route to the interface. */
+@@ -403,6 +410,8 @@
+ rib_delete_ipv6 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0);
+
+ rib_update ();
++
++ kernel_connected_down(ifc);
+ }
+
+ void
+diff -Nur quagga-0.98.3.orig/zebra/rt.h quagga-0.98.3/zebra/rt.h
+--- quagga-0.98.3.orig/zebra/rt.h 2002-12-13 22:15:30.000000000 +0200
++++ quagga-0.98.3/zebra/rt.h 2005-06-15 08:33:06.012693968 +0300
+@@ -29,6 +29,9 @@
+ int kernel_address_add_ipv4 (struct interface *, struct connected *);
+ int kernel_address_delete_ipv4 (struct interface *, struct connected *);
+
++int kernel_connected_up (struct connected *ifc);
++int kernel_connected_down (struct connected *ifc);
++
+ #ifdef HAVE_IPV6
+ int kernel_add_ipv6 (struct prefix *, struct rib *);
+ int kernel_delete_ipv6 (struct prefix *, struct rib *);
+diff -Nur quagga-0.98.3.orig/zebra/rt_ioctl.c quagga-0.98.3/zebra/rt_ioctl.c
+--- quagga-0.98.3.orig/zebra/rt_ioctl.c 2004-12-07 23:12:56.000000000 +0200
++++ quagga-0.98.3/zebra/rt_ioctl.c 2005-06-15 08:33:06.013693816 +0300
+@@ -44,6 +44,20 @@
+ return;
+ }
+
++/* Dummy function */
++int
++kernel_connected_up (struct connected *ifc)
++{
++ return 0;
++}
++
++/* Dummy function */
++int
++kernel_connected_down (struct connected *ifc)
++{
++ return 0;
++}
++
+ #if 0
+ /* Initialization prototype of struct sockaddr_in. */
+ static struct sockaddr_in sin_proto =
+diff -Nur quagga-0.98.3.orig/zebra/rt_netlink.c quagga-0.98.3/zebra/rt_netlink.c
+--- quagga-0.98.3.orig/zebra/rt_netlink.c 2005-03-31 23:26:59.000000000 +0300
++++ quagga-0.98.3/zebra/rt_netlink.c 2005-06-15 08:33:06.014693664 +0300
+@@ -1341,6 +1341,112 @@
+ return 0;
+ }
+
++/* Routing table change for connected route via netlink interface. */
++int
++netlink_routeconnected (int cmd, struct connected *ifc)
++{
++ int ret;
++ int bytelen;
++ struct sockaddr_nl snl;
++ u_char bufnet[BUFSIZ];
++ u_char bufaddr[BUFSIZ];
++ u_char bufsrc[BUFSIZ];
++
++ int cmds[] = { RTM_NEWROUTE, RTM_DELROUTE };
++
++ struct prefix *p = ifc->address;
++ int family = ifc->address->family;
++ int table = RT_TABLE_MAIN;
++ int index = ifc->ifp->ifindex;
++
++ struct prefix dest;
++ struct prefix src;
++ int length = p->prefixlen;
++
++ struct
++ {
++ struct nlmsghdr n;
++ struct rtmsg r;
++ char buf[1024];
++ } req;
++
++ if (! (index && p))
++ return -1;
++
++#ifdef HAVE_IPV6
++ if ((family == AF_INET6) && (IN6_IS_ADDR_LINKLOCAL(&p->u.prefix6)))
++ return -1;
++#endif /* HAVE_IPV6 */
++
++ memset (&dest, 0, sizeof dest);
++ memset (&req, 0, sizeof req);
++ memset (&src, 0, sizeof(struct prefix));
++
++ /* Copy prefix */
++ prefix_copy (&src, p);
++ prefix2str(&src, bufsrc, sizeof (bufaddr));
++
++ prefix_copy (&dest, p);
++ prefix2str(&dest, bufaddr, sizeof (bufaddr));
++
++ /* Make it sure prefixlen is applied to the prefix. */
++ apply_mask (&dest);
++ prefix2str(&dest, bufnet, sizeof (bufnet));
++
++ bytelen = (family == AF_INET ? 4 : 16);
++
++ req.n.nlmsg_len = NLMSG_LENGTH (sizeof (struct rtmsg));
++ req.n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST;
++ req.n.nlmsg_type = cmds[cmd];
++ req.r.rtm_family = family;
++ req.r.rtm_table = table;
++ req.r.rtm_dst_len = length;
++ req.r.rtm_src_len = IPV4_MAX_BITLEN;
++
++ req.r.rtm_protocol = RTPROT_KERNEL;
++ req.r.rtm_scope = RT_SCOPE_LINK;
++ req.r.rtm_type = RTN_UNICAST;
++
++ addattr_l (&req.n, sizeof req, RTA_DST, &dest.u.prefix, bytelen);
++ addattr_l (&req.n, sizeof req, RTA_PREFSRC, &src.u.prefix, bytelen);
++
++ if (index > 0)
++ addattr32 (&req.n, sizeof req, RTA_OIF, index);
++
++ /* Destination netlink address. */
++ memset (&snl, 0, sizeof snl);
++ snl.nl_family = AF_NETLINK;
++
++ if (! cmd)
++ zlog_warn ("netlink_routeconnected: connected route for if %s (%s) for net %s src %s in fib", ifc->ifp->name, bufaddr, bufnet, bufsrc);
++ else
++ zlog_warn ("netlink_routeconnected: connected route for if %s (%s) for net %s src %s in fib", ifc->ifp->name, bufaddr, bufnet, bufsrc);
++
++ /* Talk to netlink socket. */
++ ret = netlink_talk (&req.n, &netlink);
++ if (ret < 0)
++ return -1;
++
++ if (! cmd)
++ zlog_warn ("netlink_routeconnected: ACK: connected route for if %s (%s) for net %s src %s in fib", ifc->ifp->name, bufaddr, bufnet, bufsrc);
++ else
++ zlog_warn ("netlink_routeconnected: ACK: connected route for if %s (%s) for net %s src %s in fib", ifc->ifp->name, bufaddr, bufnet, bufsrc);
++
++ return 0;
++}
++
++int
++kernel_connected_up (struct connected *ifc)
++{
++ return netlink_routeconnected (0, ifc);
++}
++
++int
++kernel_connected_down (struct connected *ifc)
++{
++ return netlink_routeconnected (1, ifc);
++}
++
+ /* Routing table change via netlink interface. */
+ int
+ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
+diff -Nur quagga-0.98.3.orig/zebra/rt_socket.c quagga-0.98.3/zebra/rt_socket.c
+--- quagga-0.98.3.orig/zebra/rt_socket.c 2004-12-07 23:12:56.000000000 +0200
++++ quagga-0.98.3/zebra/rt_socket.c 2005-06-15 08:33:06.015693512 +0300
+@@ -480,4 +480,18 @@
+
+ return route;
+ }
++
++/* Dummy function */
++int
++kernel_connected_up (struct connected *ifc)
++{
++ return 0;
++}
++
++/* Dummy function */
++int
++kernel_connected_down (struct connected *ifc)
++{
++ return 0;
++}
+ #endif /* HAVE_IPV6 */
diff --git a/net-misc/quagga/files/patches-0.98.3/ht-20040304-classless-bgp.patch b/net-misc/quagga/files/patches-0.98.3/ht-20040304-classless-bgp.patch
new file mode 100644
index 000000000000..978dfa3dcdfa
--- /dev/null
+++ b/net-misc/quagga/files/patches-0.98.3/ht-20040304-classless-bgp.patch
@@ -0,0 +1,43 @@
+Index: bgpd/bgp_route.c
+===================================================================
+RCS file: /var/cvsroot/quagga/bgpd/bgp_route.c,v
+retrieving revision 1.10
+diff -u -3 -p -r1.10 bgp_route.c
+--- bgpd/bgp_route.c 17 Feb 2004 19:45:10 -0000 1.10
++++ bgpd/bgp_route.c 4 Mar 2004 19:44:42 -0000
+@@ -3710,16 +3710,7 @@ route_vty_out_route (struct prefix *p, s
+ {
+ len = vty_out (vty, "%s", inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ));
+ destination = ntohl (p->u.prefix4.s_addr);
+-
+- if ((IN_CLASSC (destination) && p->prefixlen == 24)
+- || (IN_CLASSB (destination) && p->prefixlen == 16)
+- || (IN_CLASSA (destination) && p->prefixlen == 8)
+- || p->u.prefix4.s_addr == 0)
+- {
+- /* When mask is natural, mask is not displayed. */
+- }
+- else
+- len += vty_out (vty, "/%d", p->prefixlen);
++ len += vty_out (vty, "/%d", p->prefixlen);
+ }
+ else
+ len = vty_out (vty, "%s/%d", inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
+@@ -8931,16 +8922,7 @@ bgp_config_write_network (struct vty *vt
+ masklen2ip (p->prefixlen, &netmask);
+ vty_out (vty, " network %s",
+ inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN));
+-
+- if ((IN_CLASSC (destination) && p->prefixlen == 24)
+- || (IN_CLASSB (destination) && p->prefixlen == 16)
+- || (IN_CLASSA (destination) && p->prefixlen == 8)
+- || p->u.prefix4.s_addr == 0)
+- {
+- /* Natural mask is not display. */
+- }
+- else
+- vty_out (vty, " mask %s", inet_ntoa (netmask));
++ vty_out (vty, " mask %s", inet_ntoa (netmask));
+ }
+ else
+ {
diff --git a/net-misc/quagga/files/patches-0.98.3/ht-20050110-0.98.0-bgp-md5.patch b/net-misc/quagga/files/patches-0.98.3/ht-20050110-0.98.0-bgp-md5.patch
new file mode 100644
index 000000000000..933304df7897
--- /dev/null
+++ b/net-misc/quagga/files/patches-0.98.3/ht-20050110-0.98.0-bgp-md5.patch
@@ -0,0 +1,481 @@
+==== Patch <ht-20050110-0.98.0-bgp-md5> level 1
+Source: [No source]
+Target: 53eccb64-3fed-0310-a953-aee945e670f6:/quagga/working-copy:832 [local]
+Log:
+Patch updated to the Quagga version 0.98.0.
+--- bgpd/bgp_network.c (revision 832)
++++ bgpd/bgp_network.c (patch ht-20050110-0.98.0-bgp-md5 level 1)
+@@ -38,6 +38,56 @@ Software Foundation, Inc., 59 Temple Pla
+ extern struct zebra_privs_t bgpd_privs;
+
+
++#if defined(HAVE_TCP_MD5) && defined(GNU_LINUX)
++/* Set MD5 key to the socket. */
++int
++bgp_md5_set (int sock, struct peer *peer, char *password)
++{
++ int ret;
++ struct tcp_rfc2385_cmd cmd;
++ struct in_addr *addr = &peer->su.sin.sin_addr;
++
++ cmd.command = TCP_MD5_AUTH_ADD;
++ cmd.address = addr->s_addr;
++ cmd.keylen = strlen (password);
++ cmd.key = password;
++
++ if ( bgpd_privs.change (ZPRIVS_RAISE) )
++ zlog_err ("bgp_md5_set: could not raise privs");
++
++ ret = setsockopt (sock, IPPROTO_TCP, TCP_MD5_AUTH, &cmd, sizeof cmd);
++
++ if (bgpd_privs.change (ZPRIVS_LOWER) )
++ zlog_err ("bgp_md5_set: could not lower privs");
++
++ return ret;
++}
++
++/* Unset MD5 key from the socket. */
++int
++bgp_md5_unset (int sock, struct peer *peer, char *password)
++{
++ int ret;
++ struct tcp_rfc2385_cmd cmd;
++ struct in_addr *addr = &peer->su.sin.sin_addr;
++
++ cmd.command = TCP_MD5_AUTH_DEL;
++ cmd.address = addr->s_addr;
++ cmd.keylen = strlen (password);
++ cmd.key = password;
++
++ if ( bgpd_privs.change (ZPRIVS_RAISE) )
++ zlog_err ("bgp_md5_unset: could not raise privs");
++
++ ret = setsockopt (sock, IPPROTO_TCP, TCP_MD5_AUTH, &cmd, sizeof cmd);
++
++ if (bgpd_privs.change (ZPRIVS_LOWER) )
++ zlog_err ("bgp_md5_unset: could not lower privs");
++
++ return ret;
++}
++#endif /* defined(HAVE_TCP_MD5) && defined(GNU_LINUX) */
++
+ /* Accept bgp connection. */
+ static int
+ bgp_accept (struct thread *thread)
+@@ -240,6 +290,12 @@ bgp_connect (struct peer *peer)
+ sockopt_reuseaddr (peer->fd);
+ sockopt_reuseport (peer->fd);
+
++#ifdef HAVE_TCP_MD5
++ if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSWORD))
++ if (sockunion_family (&peer->su) == AF_INET)
++ bgp_md5_set (peer->fd, peer, peer->password);
++#endif /* HAVE_TCP_MD5 */
++
+ /* Bind socket. */
+ bgp_bind (peer);
+
+@@ -287,6 +343,9 @@ int
+ bgp_socket (struct bgp *bgp, unsigned short port)
+ {
+ int ret, en;
++#ifdef IPV6_V6ONLY
++ int v6only = 1;
++#endif /* IPV6_V6ONLY */
+ struct addrinfo req;
+ struct addrinfo *ainfo;
+ struct addrinfo *ainfo_save;
+@@ -321,6 +380,11 @@ bgp_socket (struct bgp *bgp, unsigned sh
+ zlog_err ("socket: %s", safe_strerror (errno));
+ continue;
+ }
++#ifdef IPV6_V6ONLY
++ ret = setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&v6only, sizeof(v6only));
++ if (ret < 0)
++ zlog_err ("setsockopt IPV6_V6ONLY: i%s", strerror (errno));
++#endif /* IPV6_V6ONLY */
+
+ sockopt_reuseaddr (sock);
+ sockopt_reuseport (sock);
+@@ -348,6 +412,11 @@ bgp_socket (struct bgp *bgp, unsigned sh
+ continue;
+ }
+
++#ifdef HAVE_TCP_MD5
++ if (ainfo->ai_family == AF_INET)
++ bm->sock = sock;
++#endif /* HAVE_TCP_MD5 */
++
+ thread_add_read (master, bgp_accept, bgp, sock);
+ }
+ while ((ainfo = ainfo->ai_next) != NULL);
+@@ -408,6 +477,9 @@ bgp_socket (struct bgp *bgp, unsigned sh
+ close (sock);
+ return ret;
+ }
++#ifdef HAVE_TCP_MD5
++ bm->sock = sock;
++#endif /* HAVE_TCP_MD5 */
+
+ thread_add_read (bm->master, bgp_accept, bgp, sock);
+
+--- bgpd/bgp_network.h (revision 832)
++++ bgpd/bgp_network.h (patch ht-20050110-0.98.0-bgp-md5 level 1)
+@@ -18,6 +18,27 @@ along with GNU Zebra; see the file COPYI
+ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
++#if defined(HAVE_TCP_MD5) && defined(GNU_LINUX)
++/* setsockopt Number */
++#define TCP_MD5_AUTH 13
++
++/* Commands (used in the structure passed from userland) */
++#define TCP_MD5_AUTH_ADD 1
++#define TCP_MD5_AUTH_DEL 2
++
++struct tcp_rfc2385_cmd {
++ u_int8_t command; /* Command - Add/Delete */
++ u_int32_t address; /* IPV4 address associated */
++ u_int8_t keylen; /* MD5 Key len (do NOT assume 0 terminated ascii) */
++ void *key; /* MD5 Key */
++};
++#endif /* defined(HAVE_TCP_MD5) && defined(GNU_LINUX) */
++
++#ifdef HAVE_TCP_MD5
++int bgp_md5_set (int sock, struct peer *, char *);
++int bgp_md5_unset (int sock, struct peer *, char *);
++#endif /* HAVE_TCP_MD5 */
++
+ int bgp_socket (struct bgp *, unsigned short);
+ int bgp_connect (struct peer *);
+ void bgp_getsockname (struct peer *);
+--- bgpd/bgp_vty.c (revision 832)
++++ bgpd/bgp_vty.c (patch ht-20050110-0.98.0-bgp-md5 level 1)
+@@ -1386,6 +1386,46 @@ ALIAS (no_neighbor_local_as,
+ "AS number used as local AS\n"
+ "Do not prepend local-as to updates from ebgp peers\n")
+
++#ifdef HAVE_TCP_MD5
++DEFUN (neighbor_password,
++ neighbor_password_cmd,
++ NEIGHBOR_CMD2 "password LINE",
++ NEIGHBOR_STR
++ NEIGHBOR_ADDR_STR2
++ "Set a password\n"
++ "The password\n")
++{
++ struct peer *peer;
++ int ret;
++
++ peer = peer_and_group_lookup_vty (vty, argv[0]);
++ if (! peer)
++ return CMD_WARNING;
++
++ ret = peer_password_set (peer, argv[1]);
++ return bgp_vty_return (vty, ret);
++}
++
++DEFUN (no_neighbor_password,
++ no_neighbor_password_cmd,
++ NO_NEIGHBOR_CMD2 "password",
++ NO_STR
++ NEIGHBOR_STR
++ NEIGHBOR_ADDR_STR2
++ "Set a password\n")
++{
++ struct peer *peer;
++ int ret;
++
++ peer = peer_and_group_lookup_vty (vty, argv[0]);
++ if (! peer)
++ return CMD_WARNING;
++
++ ret = peer_password_unset (peer);
++ return bgp_vty_return (vty, ret);
++}
++#endif /* HAVE_TCP_MD5 */
++
+ DEFUN (neighbor_activate,
+ neighbor_activate_cmd,
+ NEIGHBOR_CMD2 "activate",
+@@ -8531,6 +8571,12 @@ bgp_vty_init ()
+ install_element (BGP_NODE, &no_neighbor_local_as_val_cmd);
+ install_element (BGP_NODE, &no_neighbor_local_as_val2_cmd);
+
++#ifdef HAVE_TCP_MD5
++ /* "neighbor password" commands. */
++ install_element (BGP_NODE, &neighbor_password_cmd);
++ install_element (BGP_NODE, &no_neighbor_password_cmd);
++#endif /* HAVE_TCP_MD5 */
++
+ /* "neighbor activate" commands. */
+ install_element (BGP_NODE, &neighbor_activate_cmd);
+ install_element (BGP_IPV4_NODE, &neighbor_activate_cmd);
+--- bgpd/bgpd.c (revision 832)
++++ bgpd/bgpd.c (patch ht-20050110-0.98.0-bgp-md5 level 1)
+@@ -707,6 +707,7 @@ peer_new ()
+ peer->ostatus = Idle;
+ peer->version = BGP_VERSION_4;
+ peer->weight = 0;
++ peer->password = NULL;
+
+ /* Set default flags. */
+ for (afi = AFI_IP; afi < AFI_MAX; afi++)
+@@ -1068,6 +1069,17 @@ peer_delete (struct peer *peer)
+ bgp_stop (peer);
+ bgp_fsm_change_status (peer, Idle);
+
++#ifdef HAVE_TCP_MD5
++ /* Password configuration */
++ if (peer->password)
++ {
++ if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)
++ && sockunion_family (&peer->su) == AF_INET)
++ bgp_md5_unset (bm->sock, peer, peer->password);
++ free (peer->password);
++ }
++#endif /* HAVE_TCP_MD5 */
++
+ /* Stop all timers. */
+ BGP_TIMER_OFF (peer->t_start);
+ BGP_TIMER_OFF (peer->t_connect);
+@@ -1293,6 +1305,26 @@ peer_group2peer_config_copy (struct peer
+ else
+ peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
+
++#ifdef HAVE_TCP_MD5
++ /* password apply */
++ if (CHECK_FLAG (conf->flags, PEER_FLAG_PASSWORD))
++ {
++ if (peer->password)
++ free (peer->password);
++ peer->password = strdup (conf->password);
++
++ if (sockunion_family (&peer->su) == AF_INET)
++ bgp_md5_set (bm->sock, peer, peer->password);
++ }
++ else if (peer->password)
++ {
++ if (sockunion_family (&peer->su) == AF_INET)
++ bgp_md5_unset (bm->sock, peer, peer->password);
++ free (peer->password);
++ peer->password = NULL;
++ }
++#endif /* HAVE_TCP_MD5 */
++
+ /* maximum-prefix */
+ peer->pmax[afi][safi] = conf->pmax[afi][safi];
+ peer->pmax_threshold[afi][safi] = conf->pmax_threshold[afi][safi];
+@@ -3270,6 +3302,119 @@ peer_local_as_unset (struct peer *peer)
+ return 0;
+ }
+
++#ifdef HAVE_TCP_MD5
++/* Set password for authenticating with the peer. */
++int
++peer_password_set (struct peer *peer, const char *password)
++{
++ struct peer_group *group;
++ struct listnode *nn;
++
++ if (peer->password && strcmp (peer->password, password) == 0
++ && ! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
++ return 0;
++
++ SET_FLAG (peer->flags, PEER_FLAG_PASSWORD);
++ if (peer->password)
++ free (peer->password);
++ peer->password = strdup (password);
++
++ if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
++ {
++ if (peer->status == Established)
++ bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
++ else
++ BGP_EVENT_ADD (peer, BGP_Stop);
++
++ if (sockunion_family (&peer->su) == AF_INET)
++ bgp_md5_set (bm->sock, peer, peer->password);
++ return 0;
++ }
++
++ group = peer->group;
++ LIST_LOOP (group->peer, peer, nn)
++ {
++ if (peer->password && strcmp (peer->password, password) == 0)
++ continue;
++
++ SET_FLAG (peer->flags, PEER_FLAG_PASSWORD);
++ if (peer->password)
++ free (peer->password);
++ peer->password = strdup (password);
++
++ if (peer->status == Established)
++ bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
++ else
++ BGP_EVENT_ADD (peer, BGP_Stop);
++
++ if (sockunion_family (&peer->su) == AF_INET)
++ bgp_md5_set (bm->sock, peer, peer->password);
++ }
++
++ return 0;
++}
++
++int
++peer_password_unset (struct peer *peer)
++{
++ struct peer_group *group;
++ struct listnode *nn;
++
++ if (! CHECK_FLAG (peer->flags, PEER_FLAG_PASSWORD)
++ && ! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
++ return 0;
++
++ if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
++ {
++ if (peer_group_active (peer)
++ && CHECK_FLAG (peer->group->conf->flags, PEER_FLAG_PASSWORD))
++ return BGP_ERR_PEER_GROUP_HAS_THE_FLAG;
++
++ if (peer->status == Established)
++ bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
++ else
++ BGP_EVENT_ADD (peer, BGP_Stop);
++
++ if (sockunion_family (&peer->su) == AF_INET)
++ bgp_md5_unset (bm->sock, peer, peer->password);
++
++ UNSET_FLAG (peer->flags, PEER_FLAG_PASSWORD);
++ if (peer->password)
++ free (peer->password);
++ peer->password = NULL;
++
++ return 0;
++ }
++
++ UNSET_FLAG (peer->flags, PEER_FLAG_PASSWORD);
++ if (peer->password)
++ free (peer->password);
++ peer->password = NULL;
++
++ group = peer->group;
++ LIST_LOOP (group->peer, peer, nn)
++ {
++ if (! CHECK_FLAG (peer->flags, PEER_FLAG_PASSWORD))
++ continue;
++
++ if (peer->status == Established)
++ bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
++ else
++ BGP_EVENT_ADD (peer, BGP_Stop);
++
++ if (sockunion_family (&peer->su) == AF_INET)
++ bgp_md5_unset (bm->sock, peer, peer->password);
++
++ UNSET_FLAG (peer->flags, PEER_FLAG_PASSWORD);
++ if (peer->password)
++ free (peer->password);
++ peer->password = NULL;
++ }
++
++ return 0;
++}
++#endif /* HAVE_TCP_MD5 */
++
+ /* Set distribute list to the peer. */
+ int
+ peer_distribute_set (struct peer *peer, afi_t afi, safi_t safi, int direct,
+@@ -4286,6 +4431,16 @@ bgp_config_write_peer (struct vty *vty,
+ ! CHECK_FLAG (g_peer->flags, PEER_FLAG_SHUTDOWN))
+ vty_out (vty, " neighbor %s shutdown%s", addr, VTY_NEWLINE);
+
++#ifdef HAVE_TCP_MD5
++ /* Password. */
++ if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSWORD))
++ if (! peer_group_active (peer)
++ || ! CHECK_FLAG (g_peer->flags, PEER_FLAG_PASSWORD)
++ || strcmp (peer->password, g_peer->password) != 0)
++ vty_out (vty, " neighbor %s password %s%s", addr, peer->password,
++ VTY_NEWLINE);
++#endif /* HAVE_TCP_MD5 */
++
+ /* BGP port. */
+ if (peer->port != BGP_PORT_DEFAULT)
+ vty_out (vty, " neighbor %s port %d%s", addr, peer->port,
+@@ -4817,6 +4972,9 @@ bgp_master_init ()
+ bm->port = BGP_PORT_DEFAULT;
+ bm->master = thread_master_create ();
+ bm->start_time = time (NULL);
++#ifdef HAVE_TCP_MD5
++ bm->sock = -1;
++#endif /* HAVE_TCP_MD5 */
+ }
+
+ void
+--- bgpd/bgpd.h (revision 832)
++++ bgpd/bgpd.h (patch ht-20050110-0.98.0-bgp-md5 level 1)
+@@ -45,6 +45,11 @@ struct bgp_master
+ #define BGP_OPT_NO_FIB (1 << 0)
+ #define BGP_OPT_MULTIPLE_INSTANCE (1 << 1)
+ #define BGP_OPT_CONFIG_CISCO (1 << 2)
++
++#ifdef HAVE_TCP_MD5
++ /* bgp receive socket */
++ int sock;
++#endif /* HAVE_TCP_MD5 */
+ };
+
+ /* BGP instance structure. */
+@@ -335,6 +340,7 @@ struct peer
+ #define PEER_FLAG_DYNAMIC_CAPABILITY (1 << 6) /* dynamic capability */
+ #define PEER_FLAG_ENFORCE_MULTIHOP (1 << 7) /* enforce-multihop */
+ #define PEER_FLAG_LOCAL_AS_NO_PREPEND (1 << 8) /* local-as no-prepend */
++#define PEER_FLAG_PASSWORD (1 << 9) /* password */
+
+ /* Per AF configuration flags. */
+ u_int32_t af_flags[AFI_MAX][SAFI_MAX];
+@@ -356,6 +362,9 @@ struct peer
+ #define PEER_FLAG_MAX_PREFIX_WARNING (1 << 15) /* maximum prefix warning-only */
+ #define PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED (1 << 16) /* leave link-local nexthop unchanged */
+
++ /* MD5 password */
++ char *password;
++
+ /* default-originate route-map. */
+ struct
+ {
+@@ -895,5 +904,10 @@ int peer_unsuppress_map_unset (struct pe
+ int peer_maximum_prefix_set (struct peer *, afi_t, safi_t, u_int32_t, u_char, int);
+ int peer_maximum_prefix_unset (struct peer *, afi_t, safi_t);
+
++#ifdef HAVE_TCP_MD5
++int peer_password_set (struct peer *, const char *);
++int peer_password_unset (struct peer *);
++#endif /* HAVE_TCP_MD5 */
++
+ int peer_clear (struct peer *);
+ int peer_clear_soft (struct peer *, afi_t, safi_t, enum bgp_clear_type);
+--- configure.ac (revision 832)
++++ configure.ac (patch ht-20050110-0.98.0-bgp-md5 level 1)
+@@ -153,6 +153,8 @@ AC_ARG_ENABLE(irdp,
+ [ --enable-irdp enable IRDP server support in zebra])
+ AC_ARG_ENABLE(capabilities,
+ [ --disable-capabilities disable using POSIX capabilities])
++AC_ARG_ENABLE(tcp-md5,
++[ --enable-tcp-md5 enable TCP MD5 Signature Option (RFC2385)])
+ AC_ARG_ENABLE(gcc_ultra_verbose,
+ [ --enable-gcc-ultra-verbose enable ultra verbose GCC warnings])
+ AC_ARG_ENABLE(gcc-rdynamic,
+@@ -192,6 +194,11 @@ if test "${enable_ospf_te}" = "yes"; the
+ AC_DEFINE(HAVE_OSPF_TE,,OSPF TE)
+ fi
+
++if test "${enable_tcp_md5}" = "yes"; then
++ AC_DEFINE(HAVE_TCP_MD5,,Linux TCP MD5 Signature Option)
++fi
++
++
+ AC_MSG_CHECKING(if zebra should be configurable to send Route Advertisements)
+ if test "${enable_rtadv}" != "no"; then
+ AC_MSG_RESULT(yes)