~ubuntu-branches/ubuntu/saucy/quagga/saucy

« back to all changes in this revision

Viewing changes to debian/patches/20_md5_bsd_linux_v9.dpatch

  • Committer: Bazaar Package Importer
  • Author(s): Christian Hammers
  • Date: 2008-04-12 12:53:51 UTC
  • Revision ID: james.westby@ubuntu.com-20080412125351-cm31kisia6z464vw
Tags: 0.99.9-6
Fixed FTBFS by adding a build-dep to libpcre3-dev (thanks to  Luk Claes).
Closes: #469891

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#! /bin/sh /usr/share/dpatch/dpatch-run
 
2
## 99-unnamed.dpatch by  <ch@debian.org>
 
3
##
 
4
## All lines beginning with `## DP:' are a description of the patch.
 
5
## DP: [quagga-users 9315] New md5 signature patch for bgp... quagga_md5_bsd_linux_v9.diff
 
6
## DP: http://www.wittsend.com/mhw/md5sig/quagga_md5_bsd_linux_v9.diff
 
7
## DP: Removed configure.ac part and replaced with corresponding diff to configure
 
8
## DP: as that works better for the Debian build process which does not run aclocal.
 
9
 
 
10
@DPATCH@
 
11
 
 
12
diff -ruN quagga-0.99.9/bgpd/bgpd.c quagga-0.99.9-v9/bgpd/bgpd.c
 
13
--- quagga-0.99.9/bgpd/bgpd.c   2007-07-25 12:49:06.000000000 -0400
 
14
+++ quagga-0.99.9-v9/bgpd/bgpd.c        2007-09-24 20:28:55.000000000 -0400
 
15
@@ -788,6 +788,7 @@
 
16
   peer->status = Idle;
 
17
   peer->ostatus = Idle;
 
18
   peer->weight = 0;
 
19
+  peer->password = NULL;
 
20
   peer->bgp = bgp;
 
21
   peer = peer_lock (peer); /* initial reference */
 
22
 
 
23
@@ -1202,6 +1203,20 @@
 
24
   peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE;
 
25
   bgp_stop (peer);
 
26
   bgp_fsm_change_status (peer, Deleted);
 
27
+
 
28
+#ifdef HAVE_TCP_MD5SIG
 
29
+  /* Password configuration */
 
30
+  if (peer->password)
 
31
+    {
 
32
+      free (peer->password);
 
33
+      peer->password = NULL;
 
34
+
 
35
+      if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)
 
36
+          && sockunion_family (&peer->su) == AF_INET)
 
37
+       bgp_md5_set (bm->sock, &peer->su.sin, NULL);
 
38
+    }
 
39
+#endif /* HAVE_TCP_MD5SIG */
 
40
 
41
   bgp_timer_set (peer); /* stops all timers for Deleted */
 
42
   
 
43
   /* Delete from all peer list. */
 
44
@@ -1417,6 +1432,27 @@
 
45
   else
 
46
     peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
 
47
 
 
48
+#ifdef HAVE_TCP_MD5SIG
 
49
+  /* password apply */
 
50
+  if (CHECK_FLAG (conf->flags, PEER_FLAG_PASSWORD))
 
51
+    {
 
52
+      if (peer->password)
 
53
+       free (peer->password);
 
54
+      peer->password = strdup (conf->password);
 
55
+
 
56
+      if (sockunion_family (&peer->su) == AF_INET)
 
57
+       bgp_md5_set (bm->sock, &peer->su.sin, peer->password);
 
58
+    }
 
59
+  else if (peer->password)
 
60
+    {
 
61
+      free (peer->password);
 
62
+      peer->password = NULL;
 
63
+
 
64
+      if (sockunion_family (&peer->su) == AF_INET)
 
65
+        bgp_md5_set (bm->sock, &peer->su.sin, NULL);
 
66
+    }
 
67
+#endif /* HAVE_TCP_MD5SIG */
 
68
+
 
69
   /* maximum-prefix */
 
70
   peer->pmax[afi][safi] = conf->pmax[afi][safi];
 
71
   peer->pmax_threshold[afi][safi] = conf->pmax_threshold[afi][safi];
 
72
@@ -3379,6 +3415,125 @@
 
73
   return 0;
 
74
 }
 
75
 
 
76
+#ifdef HAVE_TCP_MD5SIG
 
77
+/* Set password for authenticating with the peer. */
 
78
+int
 
79
+peer_password_set (struct peer *peer, const char *password)
 
80
+{
 
81
+  struct peer_group *group;
 
82
+  struct listnode *nn, *nnode;
 
83
+  int len = password ? strlen(password) : 0;
 
84
+
 
85
+  if ((len < PEER_PASSWORD_MINLEN) || (len > PEER_PASSWORD_MAXLEN))
 
86
+    return BGP_ERR_INVALID_VALUE;
 
87
+
 
88
+  if (peer->password && strcmp (peer->password, password) == 0
 
89
+      && ! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 
90
+       return 0;
 
91
+
 
92
+  SET_FLAG (peer->flags, PEER_FLAG_PASSWORD);
 
93
+  if (peer->password)
 
94
+    free (peer->password);
 
95
+  peer->password = strdup (password);
 
96
+
 
97
+  if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 
98
+    {
 
99
+      if (peer->status == Established)
 
100
+          bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
 
101
+      else
 
102
+        BGP_EVENT_ADD (peer, BGP_Stop);
 
103
+
 
104
+      if (sockunion_family (&peer->su) == AF_INET)
 
105
+       bgp_md5_set (bm->sock, &peer->su.sin, peer->password);
 
106
+      return 0;
 
107
+    }
 
108
+
 
109
+  group = peer->group;
 
110
+  /* #42# LIST_LOOP (group->peer, peer, nn) */
 
111
+  for (ALL_LIST_ELEMENTS (group->peer, nn, nnode, peer))
 
112
+    {
 
113
+      if (peer->password && strcmp (peer->password, password) == 0)
 
114
+       continue;
 
115
+
 
116
+      SET_FLAG (peer->flags, PEER_FLAG_PASSWORD);
 
117
+      if (peer->password)
 
118
+        free (peer->password);
 
119
+      peer->password = strdup (password);
 
120
+
 
121
+      if (peer->status == Established)
 
122
+        bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
 
123
+      else
 
124
+        BGP_EVENT_ADD (peer, BGP_Stop);
 
125
+
 
126
+      if (sockunion_family (&peer->su) == AF_INET)
 
127
+       bgp_md5_set (bm->sock, &peer->su.sin, peer->password);
 
128
+    }
 
129
+
 
130
+  return 0;
 
131
+}
 
132
+
 
133
+int
 
134
+peer_password_unset (struct peer *peer)
 
135
+{
 
136
+  struct peer_group *group;
 
137
+  struct listnode *nn, *nnode;
 
138
+
 
139
+  if (! CHECK_FLAG (peer->flags, PEER_FLAG_PASSWORD)
 
140
+      && ! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 
141
+    return 0;
 
142
+
 
143
+  if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 
144
+    {
 
145
+      if (peer_group_active (peer)
 
146
+         && CHECK_FLAG (peer->group->conf->flags, PEER_FLAG_PASSWORD))
 
147
+       return BGP_ERR_PEER_GROUP_HAS_THE_FLAG;
 
148
+
 
149
+      if (peer->status == Established)
 
150
+        bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
 
151
+      else
 
152
+        BGP_EVENT_ADD (peer, BGP_Stop);
 
153
+
 
154
+      if (sockunion_family (&peer->su) == AF_INET)
 
155
+       bgp_md5_set (bm->sock, &peer->su.sin, NULL);
 
156
+
 
157
+      UNSET_FLAG (peer->flags, PEER_FLAG_PASSWORD);
 
158
+      if (peer->password)
 
159
+       free (peer->password);
 
160
+      peer->password = NULL;
 
161
+
 
162
+      return 0;
 
163
+    }
 
164
+
 
165
+  UNSET_FLAG (peer->flags, PEER_FLAG_PASSWORD);
 
166
+  if (peer->password)
 
167
+    free (peer->password);
 
168
+  peer->password = NULL;
 
169
+
 
170
+  group = peer->group;
 
171
+  /* #42# LIST_LOOP (group->peer, peer, nn) */
 
172
+  for (ALL_LIST_ELEMENTS (group->peer, nn, nnode, peer))
 
173
+    {
 
174
+      if (! CHECK_FLAG (peer->flags, PEER_FLAG_PASSWORD))
 
175
+       continue;
 
176
+
 
177
+      if (peer->status == Established)
 
178
+        bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
 
179
+      else
 
180
+        BGP_EVENT_ADD (peer, BGP_Stop);
 
181
+
 
182
+      if (sockunion_family (&peer->su) == AF_INET)
 
183
+       bgp_md5_set (bm->sock, &peer->su.sin, NULL);
 
184
+
 
185
+      UNSET_FLAG (peer->flags, PEER_FLAG_PASSWORD);
 
186
+      if (peer->password)
 
187
+        free (peer->password);
 
188
+      peer->password = NULL;
 
189
+    }
 
190
+
 
191
+  return 0;
 
192
+}
 
193
+#endif /* HAVE_TCP_MD5SIG */
 
194
+
 
195
 /* Set distribute list to the peer. */
 
196
 int
 
197
 peer_distribute_set (struct peer *peer, afi_t afi, safi_t safi, int direct, 
 
198
@@ -4416,6 +4571,16 @@
 
199
            ! CHECK_FLAG (g_peer->flags, PEER_FLAG_SHUTDOWN))
 
200
          vty_out (vty, " neighbor %s shutdown%s", addr, VTY_NEWLINE);
 
201
 
 
202
+#ifdef HAVE_TCP_MD5SIG
 
203
+      /* Password. */
 
204
+      if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSWORD))
 
205
+       if (! peer_group_active (peer)
 
206
+           || ! CHECK_FLAG (g_peer->flags, PEER_FLAG_PASSWORD)
 
207
+           || strcmp (peer->password, g_peer->password) != 0)
 
208
+         vty_out (vty, " neighbor %s password %s%s", addr, peer->password,
 
209
+                  VTY_NEWLINE);
 
210
+#endif /* HAVE_TCP_MD5SIG */
 
211
+
 
212
       /* BGP port. */
 
213
       if (peer->port != BGP_PORT_DEFAULT)
 
214
        vty_out (vty, " neighbor %s port %d%s", addr, peer->port, 
 
215
@@ -4951,6 +5116,9 @@
 
216
   bm->port = BGP_PORT_DEFAULT;
 
217
   bm->master = thread_master_create ();
 
218
   bm->start_time = time (NULL);
 
219
+#ifdef HAVE_TCP_MD5SIG
 
220
+  bm->sock = -1;
 
221
+#endif /* HAVE_TCP_MD5SIG */
 
222
 }
 
223
 
 
224
 
 
225
diff -ruN quagga-0.99.9/bgpd/bgpd.h quagga-0.99.9-v9/bgpd/bgpd.h
 
226
--- quagga-0.99.9/bgpd/bgpd.h   2007-08-06 11:22:43.000000000 -0400
 
227
+++ quagga-0.99.9-v9/bgpd/bgpd.h        2007-09-24 20:28:55.000000000 -0400
 
228
@@ -52,6 +52,11 @@
 
229
 #define BGP_OPT_NO_FIB                   (1 << 0)
 
230
 #define BGP_OPT_MULTIPLE_INSTANCE        (1 << 1)
 
231
 #define BGP_OPT_CONFIG_CISCO             (1 << 2)
 
232
+
 
233
+#ifdef HAVE_TCP_MD5SIG
 
234
+  /* bgp receive socket */
 
235
+  int sock;
 
236
+#endif /* HAVE_TCP_MD5SIG */
 
237
 };
 
238
 
 
239
 /* BGP instance structure.  */
 
240
@@ -349,6 +354,7 @@
 
241
 
 
242
   /* NSF mode (graceful restart) */
 
243
   u_char nsf[AFI_MAX][SAFI_MAX];
 
244
+#define PEER_FLAG_PASSWORD                  (1 << 9) /* password */
 
245
 
 
246
   /* Per AF configuration flags. */
 
247
   u_int32_t af_flags[AFI_MAX][SAFI_MAX];
 
248
@@ -370,6 +376,9 @@
 
249
 #define PEER_FLAG_MAX_PREFIX_WARNING        (1 << 15) /* maximum prefix warning-only */
 
250
 #define PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED   (1 << 16) /* leave link-local nexthop unchanged */ 
 
251
 
 
252
+  /* MD5 password */
 
253
+  char *password;
 
254
+
 
255
   /* default-originate route-map.  */
 
256
   struct
 
257
   {
 
258
@@ -525,6 +534,13 @@
 
259
 #define PEER_RMAP_TYPE_EXPORT         (1 << 7) /* neighbor route-map export */
 
260
 };
 
261
 
 
262
+#if defined(HAVE_TCP_MD5SIG)
 
263
+
 
264
+#define PEER_PASSWORD_MINLEN   (1)
 
265
+#define PEER_PASSWORD_MAXLEN   (80)
 
266
+
 
267
+#endif /* HAVE_TCP_MD5SIG */
 
268
+
 
269
 /* This structure's member directly points incoming packet data
 
270
    stream. */
 
271
 struct bgp_nlri
 
272
@@ -913,6 +929,11 @@
 
273
 extern int peer_route_map_unset (struct peer *, afi_t, safi_t, int);
 
274
 
 
275
 extern int peer_unsuppress_map_set (struct peer *, afi_t, safi_t, const char *);
 
276
+#ifdef HAVE_TCP_MD5SIG
 
277
+extern int peer_password_set (struct peer *, const char *);
 
278
+extern int peer_password_unset (struct peer *);
 
279
+#endif /* HAVE_TCP_MD5SIG */
 
280
+
 
281
 extern int peer_unsuppress_map_unset (struct peer *, afi_t, safi_t);
 
282
 
 
283
 extern int peer_maximum_prefix_set (struct peer *, afi_t, safi_t, u_int32_t, u_char, int, u_int16_t);
 
284
diff -ruN quagga-0.99.9/bgpd/bgp_network.c quagga-0.99.9-v9/bgpd/bgp_network.c
 
285
--- quagga-0.99.9/bgpd/bgp_network.c    2007-05-09 16:59:33.000000000 -0400
 
286
+++ quagga-0.99.9-v9/bgpd/bgp_network.c 2007-09-27 18:50:49.000000000 -0400
 
287
@@ -22,6 +22,7 @@
 
288
 
 
289
 #include "thread.h"
 
290
 #include "sockunion.h"
 
291
+#include "sockopt.h"
 
292
 #include "memory.h"
 
293
 #include "log.h"
 
294
 #include "if.h"
 
295
@@ -38,6 +39,34 @@
 
296
 extern struct zebra_privs_t bgpd_privs;
 
297
 
 
298
 
 
299
+#if defined(HAVE_TCP_MD5SIG)
 
300
+/*
 
301
+ * Set MD5 key for the socket, for the given IPv4 peer address.
 
302
+ * If the password is NULL or zero-length, the option will be disabled.
 
303
+ */
 
304
+int
 
305
+bgp_md5_set (int sock, struct sockaddr_in *sin, const char *password)
 
306
+{
 
307
+  int ret, en;
 
308
+
 
309
+  if ( bgpd_privs.change (ZPRIVS_RAISE) )
 
310
+    zlog_err ("bgp_md5_set: could not raise privs");
 
311
+
 
312
+  ret = sockopt_tcp_signature (sock, sin, password);
 
313
+  en  = errno;
 
314
+
 
315
+  if (bgpd_privs.change (ZPRIVS_LOWER) )
 
316
+    zlog_err ("bgp_md5_set: could not lower privs");
 
317
+
 
318
+  if (ret < 0)
 
319
+    zlog (NULL, LOG_WARNING, "can't set TCP_MD5SIG option on socket %d: %s",
 
320
+         sock, safe_strerror (en));
 
321
+
 
322
+  return ret;
 
323
+}
 
324
+
 
325
+#endif /* HAVE_TCP_MD5SIG */
 
326
+
 
327
 /* Accept bgp connection. */
 
328
 static int
 
329
 bgp_accept (struct thread *thread)
 
330
@@ -238,6 +267,12 @@
 
331
   sockopt_reuseaddr (peer->fd);
 
332
   sockopt_reuseport (peer->fd);
 
333
 
 
334
+#ifdef HAVE_TCP_MD5SIG
 
335
+  if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSWORD))
 
336
+    if (sockunion_family (&peer->su) == AF_INET)
 
337
+      bgp_md5_set (peer->fd, &peer->su.sin, peer->password);
 
338
+#endif /* HAVE_TCP_MD5SIG */
 
339
+
 
340
   /* Bind socket. */
 
341
   bgp_bind (peer);
 
342
 
 
343
@@ -288,6 +323,10 @@
 
344
   struct addrinfo req;
 
345
   struct addrinfo *ainfo;
 
346
   struct addrinfo *ainfo_save;
 
347
+#if defined(HAVE_TCP_MD5SIG) && defined(IPV6_V6ONLY)
 
348
+  struct sockaddr_in sin;
 
349
+  int socklen, on = 1;
 
350
+#endif
 
351
   int sock = 0;
 
352
   char port_str[BUFSIZ];
 
353
 
 
354
@@ -323,6 +362,21 @@
 
355
       sockopt_reuseaddr (sock);
 
356
       sockopt_reuseport (sock);
 
357
       
 
358
+#if defined(HAVE_TCP_MD5SIG) && defined(IPV6_V6ONLY)
 
359
+/*     We can not apply MD5SIG to an IPv6 socket.  If this is an AF_INET6
 
360
+       socket, we'll have to create another socket for IPv4*/
 
361
+
 
362
+      if (ainfo->ai_family == AF_INET6) {
 
363
+/*     Mark this one for IPv6 only     */
 
364
+          ret = setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY, 
 
365
+                   (void *) &on, sizeof (on));
 
366
+          if( ret < 0 ) {
 
367
+              en = errno;
 
368
+             zlog_err ("setsockopt V6ONLY: %s", safe_strerror (en));
 
369
+          }
 
370
+      }
 
371
+#endif
 
372
+
 
373
       if (bgpd_privs.change (ZPRIVS_RAISE) )
 
374
         zlog_err ("bgp_socket: could not raise privs");
 
375
 
 
376
@@ -346,7 +400,65 @@
 
377
          continue;
 
378
        }
 
379
 
 
380
+#if defined(HAVE_TCP_MD5SIG) && defined(IPV6_V6ONLY)
 
381
+      thread_add_read (master, bgp_accept, bgp, sock);
 
382
+
 
383
+      if (ainfo->ai_family != AF_INET6)
 
384
+       continue;
 
385
+     
 
386
+      /* If first socket was an IPv6 socket, we need to create an IPv4
 
387
+       socket for use by the TCP_MD5SIG logic.  This code is blatently
 
388
+       copied and modified from the alternate IPv4 only code from below... */
 
389
+
 
390
+      sock = socket (AF_INET, SOCK_STREAM, 0);
 
391
+      if (sock < 0)
 
392
+        {
 
393
+          zlog_err ("socket: %s", safe_strerror (errno));
 
394
+          continue;
 
395
+        }
 
396
+
 
397
+      sockopt_reuseaddr (sock);
 
398
+      sockopt_reuseport (sock);
 
399
+
 
400
+      memset (&sin, 0, sizeof (struct sockaddr_in));
 
401
+
 
402
+      sin.sin_family = AF_INET;
 
403
+      sin.sin_port = htons (port);
 
404
+      socklen = sizeof (struct sockaddr_in);
 
405
+#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
 
406
+      sin.sin_len = socklen;
 
407
+#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
 
408
+
 
409
+      if ( bgpd_privs.change (ZPRIVS_RAISE) )
 
410
+        zlog_err ("bgp_socket: could not raise privs");
 
411
+
 
412
+      ret = bind (sock, (struct sockaddr *) &sin, socklen);
 
413
+      en = errno;
 
414
+      if (bgpd_privs.change (ZPRIVS_LOWER) )
 
415
+       zlog_err ("bgp_bind_address: could not lower privs");
 
416
+
 
417
+      if (ret < 0)
 
418
+       {
 
419
+         zlog_err ("bind: %s", safe_strerror (en));
 
420
+         close(sock);
 
421
+         continue;
 
422
+       }
 
423
+      
 
424
+      ret = listen (sock, 3);
 
425
+      if (ret < 0) 
 
426
+       {
 
427
+         zlog_err ("listen: %s", safe_strerror (errno));
 
428
+         close (sock);
 
429
+         continue;
 
430
+       }
 
431
+#endif
 
432
+
 
433
+#ifdef HAVE_TCP_MD5SIG
 
434
+      bm->sock = sock;
 
435
+#endif /* HAVE_TCP_MD5SIG */
 
436
+
 
437
       thread_add_read (master, bgp_accept, bgp, sock);
 
438
+
 
439
     }
 
440
   while ((ainfo = ainfo->ai_next) != NULL);
 
441
 
 
442
@@ -406,6 +518,9 @@
 
443
       close (sock);
 
444
       return ret;
 
445
     }
 
446
+#ifdef HAVE_TCP_MD5SIG
 
447
+  bm->sock = sock;
 
448
+#endif /* HAVE_TCP_MD5SIG */
 
449
 
 
450
   thread_add_read (bm->master, bgp_accept, bgp, sock);
 
451
 
 
452
diff -ruN quagga-0.99.9/bgpd/bgp_network.h quagga-0.99.9-v9/bgpd/bgp_network.h
 
453
--- quagga-0.99.9/bgpd/bgp_network.h    2007-06-29 09:41:43.000000000 -0400
 
454
+++ quagga-0.99.9-v9/bgpd/bgp_network.h 2007-09-24 20:28:55.000000000 -0400
 
455
@@ -21,6 +21,10 @@
 
456
 #ifndef _QUAGGA_BGP_NETWORK_H
 
457
 #define _QUAGGA_BGP_NETWORK_H
 
458
 
 
459
+#if defined(HAVE_TCP_MD5SIG) 
 
460
+extern int bgp_md5_set (int, struct sockaddr_in *, const char *);
 
461
+#endif /* HAVE_TCP_MD5SIG */
 
462
+
 
463
 extern int bgp_socket (struct bgp *, unsigned short);
 
464
 extern int bgp_connect (struct peer *);
 
465
 extern void bgp_getsockname (struct peer *);
 
466
diff -ruN quagga-0.99.9/bgpd/bgp_vty.c quagga-0.99.9-v9/bgpd/bgp_vty.c
 
467
--- quagga-0.99.9/bgpd/bgp_vty.c        2007-08-06 11:17:46.000000000 -0400
 
468
+++ quagga-0.99.9-v9/bgpd/bgp_vty.c     2007-09-24 20:28:55.000000000 -0400
 
469
@@ -1479,6 +1479,46 @@
 
470
        "AS number used as local AS\n"
 
471
        "Do not prepend local-as to updates from ebgp peers\n")
 
472
 
 
473
+#ifdef HAVE_TCP_MD5SIG
 
474
+DEFUN (neighbor_password,
 
475
+       neighbor_password_cmd,
 
476
+       NEIGHBOR_CMD2 "password LINE",
 
477
+       NEIGHBOR_STR
 
478
+       NEIGHBOR_ADDR_STR2
 
479
+       "Set a password\n"
 
480
+       "The password\n")
 
481
+{
 
482
+  struct peer *peer;
 
483
+  int ret;
 
484
+
 
485
+  peer = peer_and_group_lookup_vty (vty, argv[0]);
 
486
+  if (! peer)
 
487
+    return CMD_WARNING;
 
488
+
 
489
+  ret = peer_password_set (peer, argv[1]);
 
490
+  return bgp_vty_return (vty, ret);
 
491
+}
 
492
+
 
493
+DEFUN (no_neighbor_password,
 
494
+       no_neighbor_password_cmd,
 
495
+       NO_NEIGHBOR_CMD2 "password",
 
496
+       NO_STR
 
497
+       NEIGHBOR_STR
 
498
+       NEIGHBOR_ADDR_STR2
 
499
+       "Set a password\n")
 
500
+{
 
501
+  struct peer *peer;
 
502
+  int ret;
 
503
+
 
504
+  peer = peer_and_group_lookup_vty (vty, argv[0]);
 
505
+  if (! peer)
 
506
+    return CMD_WARNING;
 
507
+
 
508
+  ret = peer_password_unset (peer);
 
509
+  return bgp_vty_return (vty, ret);
 
510
+}
 
511
+#endif /* HAVE_TCP_MD5SIG */
 
512
+
 
513
 DEFUN (neighbor_activate,
 
514
        neighbor_activate_cmd,
 
515
        NEIGHBOR_CMD2 "activate",
 
516
@@ -8894,6 +8934,12 @@
 
517
   install_element (BGP_NODE, &no_neighbor_local_as_val_cmd);
 
518
   install_element (BGP_NODE, &no_neighbor_local_as_val2_cmd);
 
519
 
 
520
+#ifdef HAVE_TCP_MD5SIG
 
521
+  /* "neighbor password" commands. */
 
522
+  install_element (BGP_NODE, &neighbor_password_cmd);
 
523
+  install_element (BGP_NODE, &no_neighbor_password_cmd);
 
524
+#endif /* HAVE_TCP_MD5SIG */
 
525
+
 
526
   /* "neighbor activate" commands. */
 
527
   install_element (BGP_NODE, &neighbor_activate_cmd);
 
528
   install_element (BGP_IPV4_NODE, &neighbor_activate_cmd);
 
529
diff -ruN quagga-0.99.9/config.h.in quagga-0.99.9-v9/config.h.in
 
530
--- quagga-0.99.9/config.h.in   2007-09-07 12:56:20.000000000 -0400
 
531
+++ quagga-0.99.9-v9/config.h.in        2008-01-28 13:47:20.000000000 -0500
 
532
@@ -487,6 +487,9 @@
 
533
 /* Use TCP for zebra communication */
 
534
 #undef HAVE_TCP_ZEBRA
 
535
 
 
536
+/* Define to 1 for TCP MD5 Signatures */
 
537
+#undef HAVE_TCP_MD5SIG
 
538
+
 
539
 /* Define to 1 if you have the <ucontext.h> header file. */
 
540
 #undef HAVE_UCONTEXT_H
 
541
 
 
542
diff -ruN quagga-0.99.9/lib/sockopt.c quagga-0.99.9-v9/lib/sockopt.c
 
543
--- quagga-0.99.9/lib/sockopt.c 2007-08-22 12:22:54.000000000 -0400
 
544
+++ quagga-0.99.9-v9/lib/sockopt.c      2007-09-24 20:28:55.000000000 -0400
 
545
@@ -480,3 +480,36 @@
 
546
 
 
547
   iph->ip_id = ntohs(iph->ip_id);
 
548
 }
 
549
+
 
550
+#if defined(HAVE_TCP_MD5SIG)
 
551
+int
 
552
+sockopt_tcp_signature (int sock, struct sockaddr_in *sin, const char *password)
 
553
+{
 
554
+  int keylen = password ? strlen(password) : 0;
 
555
+
 
556
+#if defined(GNU_LINUX)
 
557
+
 
558
+  struct tcp_md5sig md5sig;
 
559
+
 
560
+  bzero ((char *)&md5sig, sizeof(md5sig));
 
561
+  memcpy (&md5sig.tcpm_addr, sin, sizeof(*sin));
 
562
+  md5sig.tcpm_keylen = keylen;
 
563
+  if (keylen)
 
564
+    memcpy (md5sig.tcpm_key, password, keylen);
 
565
+
 
566
+  return setsockopt (sock, IPPROTO_TCP, TCP_MD5SIG, &md5sig, sizeof md5sig);
 
567
+
 
568
+#else /* !GNU_LINUX */
 
569
+
 
570
+  int enable = keylen ? (TCP_SIG_SPI_BASE + sin->sin_port) : 0;
 
571
+
 
572
+  /*
 
573
+   * XXX Need to do PF_KEY operation here to add/remove an SA entry,
 
574
+   * and add/remove an SP entry for this peer's packet flows also.
 
575
+   */
 
576
+  return setsockopt (sock, IPPROTO_TCP, TCP_MD5SIG, &enable,
 
577
+                    sizeof(enable));
 
578
+
 
579
+#endif /* !GNU_LINUX */
 
580
+}
 
581
+#endif /* HAVE_TCP_MD5SIG */
 
582
diff -ruN quagga-0.99.9/lib/sockopt.h quagga-0.99.9-v9/lib/sockopt.h
 
583
--- quagga-0.99.9/lib/sockopt.h 2007-08-22 12:22:54.000000000 -0400
 
584
+++ quagga-0.99.9-v9/lib/sockopt.h      2007-09-24 20:28:55.000000000 -0400
 
585
@@ -98,4 +98,32 @@
 
586
 extern void sockopt_iphdrincl_swab_htosys (struct ip *iph);
 
587
 extern void sockopt_iphdrincl_swab_systoh (struct ip *iph);
 
588
 
 
589
+#if defined(HAVE_TCP_MD5SIG)
 
590
+
 
591
+#if defined(GNU_LINUX) && !defined(TCP_MD5SIG)
 
592
+
 
593
+/* XXX these will come from <linux/tcp.h> eventually */
 
594
+
 
595
+#define TCP_MD5SIG             14
 
596
+#define TCP_MD5SIG_MAXKEYLEN   80
 
597
+
 
598
+struct tcp_md5sig {
 
599
+        struct sockaddr_storage tcpm_addr;      /* address associated */
 
600
+        __u16   __tcpm_pad1;                            /* zero */
 
601
+        __u16   tcpm_keylen;                            /* key length */
 
602
+        __u32   __tcpm_pad2;                            /* zero */
 
603
+        __u8    tcpm_key[TCP_MD5SIG_MAXKEYLEN];         /* key (binary) */
 
604
+};
 
605
+
 
606
+#endif /* defined(GNU_LINUX) && !defined(TCP_MD5SIG) */
 
607
+
 
608
+#if !defined(GNU_LINUX) && !defined(TCP_SIG_SPI_BASE)
 
609
+#define TCP_SIG_SPI_BASE 1000 /* XXX this will go away */
 
610
+#endif
 
611
+
 
612
+extern int sockopt_tcp_signature(int sock, struct sockaddr_in *sin,
 
613
+                                 const char *password);
 
614
+
 
615
+#endif /* HAVE_TCP_MD5SIG */
 
616
+
 
617
 #endif /*_ZEBRA_SOCKOPT_H */
 
618
--- old/configure       2008-01-29 20:34:58.000000000 +0100
 
619
+++ new/configure       2008-01-29 20:34:10.000000000 +0100
 
620
@@ -1528,6 +1528,7 @@
 
621
   --enable-broken-aliases enable aliases as distinct interfaces for Linux 2.2.X
 
622
   --enable-snmp           enable SNMP support
 
623
   --enable-tcp-zebra      enable TCP/IP socket connection between zebra and protocol daemon
 
624
+  --enable-tcp-md5        enable TCP/IP md5 in BGPd
 
625
   --enable-opaque-lsa     enable OSPF Opaque-LSA with OSPFAPI support (RFC2370)
 
626
   --disable-ospfapi       do not build OSPFAPI to access the OSPF LSA Database,
 
627
                           (this is the default if --enable-opaque-lsa is not set)
 
628
@@ -10843,6 +10844,11 @@
 
629
   enableval=$enable_tcp_zebra;
 
630
 fi
 
631
 
 
632
+# Check whether --enable-tcp-md5 was given.
 
633
+if test "${enable_tcp_md5+set}" = set; then
 
634
+  enableval=$enable_tcp_md5;
 
635
+fi
 
636
+
 
637
 # Check whether --enable-opaque-lsa was given.
 
638
 if test "${enable_opaque_lsa+set}" = set; then
 
639
   enableval=$enable_opaque_lsa;
 
640
@@ -10982,6 +10988,14 @@
 
641
 
 
642
 fi
 
643
 
 
644
+if test "${enable_tcp_md5}" = "yes"; then
 
645
+
 
646
+cat >>confdefs.h <<\_ACEOF
 
647
+#define HAVE_TCP_MD5SIG 1
 
648
+_ACEOF
 
649
+
 
650
+fi
 
651
+
 
652
 if test "${enable_opaque_lsa}" = "yes"; then
 
653
 
 
654
 cat >>confdefs.h <<\_ACEOF