Also the machinery in peer.c to make it work, and documentation for the
new command and matching notification.
if the server has or hasn't (respectively) become a daemon.
.RE
.SP
if the server has or hasn't (respectively) become a daemon.
.RE
.SP
+.BI "SETIFNAME " peer " " new-name
+Informs the server that the
+.IR peer 's
+tunnel-interface name has been changed to
+.IR new-name .
+This is useful if firewalling decisions are made based on interface
+names: a setup script for a particular peer can change the name, and
+then update the server's records so that they're accurate.
+.SP
.BI "STATS " peer
Emits a number of
.B INFO
.BI "STATS " peer
Emits a number of
.B INFO
.BR ADDR ,
.BR IFNAME ,
.BR KILL ,
.BR ADDR ,
.BR IFNAME ,
.BR KILL ,
and
.BR STATS .)
There is no peer called
and
.BR STATS .)
There is no peer called
has begun or restarted. If key exchange keeps failing, this message
will be repeated periodically.
.SP
has begun or restarted. If key exchange keeps failing, this message
will be repeated periodically.
.SP
+.BI "NEWIFNAME " peer " " old-name " " new-name
+The given
+.IR peer 's
+tunnel interface name has been changed from
+.I old-name
+to
+.IR new-name ,
+as a result of a
+.B SETIFNAME
+command.
+.SP
.BI "USER " tokens\fR...
An administration client issued a notification using the
.B NOTIFY
.BI "USER " tokens\fR...
An administration client issued a notification using the
.B NOTIFY
+static void acmd_setifname(admin *a, unsigned ac, char *av[])
+{
+ peer *p;
+
+ if ((p = a_findpeer(a, av[0])) != 0) {
+ a_notify("NEWIFNAME", "?PEER", p, "%s", p_ifname(p), "%s", av[1], A_END);
+ p_setifname(p, av[1]);
+ a_ok(a);
+ }
+}
+
static void acmd_getchal(admin *a, unsigned ac, char *av[])
{
buf b;
static void acmd_getchal(admin *a, unsigned ac, char *av[])
{
buf b;
{ "quit", 0, 0, 0, acmd_quit },
{ "reload", 0, 0, 0, acmd_reload },
{ "servinfo", 0, 0, 0, acmd_servinfo },
{ "quit", 0, 0, 0, acmd_quit },
{ "reload", 0, 0, 0, acmd_reload },
{ "servinfo", 0, 0, 0, acmd_servinfo },
+ { "setifname", "PEER NEW-NAME", 2, 2, acmd_setifname },
{ "stats", "PEER", 1, 1, acmd_stats },
#ifndef NTRACE
{ "trace", "[OPTIONS]", 0, 1, acmd_trace },
{ "stats", "PEER", 1, 1, acmd_stats },
#ifndef NTRACE
{ "trace", "[OPTIONS]", 0, 1, acmd_trace },
* Returns: A pointer to the peer's interface name.
*/
* Returns: A pointer to the peer's interface name.
*/
-const char *p_ifname(peer *p) { return (p->t->ops->ifname(p->t)); }
+const char *p_ifname(peer *p) { return (p->ifname); }
+
+/* --- @p_setifname@ --- *
+ *
+ * Arguments: @peer *p@ = pointer to a peer block
+ * @const char *name@ = pointer to the new name
+ *
+ * Returns: ---
+ *
+ * Use: Changes the name held for a peer's interface.
+ */
+
+void p_setifname(peer *p, const char *name)
+ { if (p->ifname) xfree(p->ifname); p->ifname = xstrdup(name); }
p->ks = 0;
p->prev = 0;
p->pings = 0;
p->ks = 0;
p->prev = 0;
p->pings = 0;
memset(&p->st, 0, sizeof(stats));
p->st.t_start = time(0);
if ((p->t = spec->tops->create(p)) == 0)
memset(&p->st, 0, sizeof(stats));
p->st.t_start = time(0);
if ((p->t = spec->tops->create(p)) == 0)
p_setkatimer(p);
if (kx_init(&p->kx, p, &p->ks))
goto tidy_1;
p_setkatimer(p);
if (kx_init(&p->kx, p, &p->ks))
goto tidy_1;
+ p_setifname(p, spec->tops->ifname(p->t));
p->next = peers;
if (peers)
peers->prev = p;
peers = p;
a_notify("ADD",
"?PEER", p,
p->next = peers;
if (peers)
peers->prev = p;
peers = p;
a_notify("ADD",
"?PEER", p,
- "%s", p->t->ops->ifname(p->t),
"?ADDR", &p->spec.sa,
A_END);
a_notify("KXSTART", "?PEER", p, A_END);
"?ADDR", &p->spec.sa,
A_END);
a_notify("KXSTART", "?PEER", p, A_END);
a_notify("KILL", "%s", p->spec.name, A_END);
ksl_free(&p->ks);
kx_free(&p->kx);
a_notify("KILL", "%s", p->spec.name, A_END);
ksl_free(&p->ks);
kx_free(&p->kx);
+ if (p->ifname)
+ xfree(p->ifname);
p->t->ops->destroy(p->t);
if (p->spec.t_ka)
sel_rmtimer(&p->tka);
p->t->ops->destroy(p->t);
if (p->spec.t_ka)
sel_rmtimer(&p->tka);
struct ping *pings; /* Pings we're waiting for */
peerspec spec; /* Specifications for this peer */
tunnel *t; /* Tunnel for local packets */
struct ping *pings; /* Pings we're waiting for */
peerspec spec; /* Specifications for this peer */
tunnel *t; /* Tunnel for local packets */
+ char *ifname; /* Interface name for tunnel */
keyset *ks; /* List head for keysets */
buf b; /* Buffer for sending packets */
stats st; /* Statistics */
keyset *ks; /* List head for keysets */
buf b; /* Buffer for sending packets */
stats st; /* Statistics */
extern const char *p_ifname(peer */*p*/);
extern const char *p_ifname(peer */*p*/);
+/* --- @p_setifname@ --- *
+ *
+ * Arguments: @peer *p@ = pointer to a peer block
+ * @const char *name@ = pointer to the new name
+ *
+ * Returns: ---
+ *
+ * Use: Changes the name held for a peer's interface.
+ */
+
+extern void p_setifname(peer */*p*/, const char */*name*/);
+
/* --- @p_addr@ --- *
*
* Arguments: @peer *p@ = pointer to a peer block
/* --- @p_addr@ --- *
*
* Arguments: @peer *p@ = pointer to a peer block