Add "delete" command to "radiusctl ipcp". Also, send "stop" that was
authoryasuoka <yasuoka@openbsd.org>
Sun, 15 Sep 2024 05:26:05 +0000 (05:26 +0000)
committeryasuoka <yasuoka@openbsd.org>
Sun, 15 Sep 2024 05:26:05 +0000 (05:26 +0000)
missing when disconnecting all when acct-{on,off} received.

usr.sbin/radiusctl/parser.c
usr.sbin/radiusctl/parser.h
usr.sbin/radiusctl/radiusctl.8
usr.sbin/radiusctl/radiusctl.c
usr.sbin/radiusd/radiusd_ipcp.c
usr.sbin/radiusd/radiusd_ipcp.h

index 5c7efbc..2662694 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: parser.c,v 1.5 2024/09/02 04:45:22 yasuoka Exp $      */
+/*     $OpenBSD: parser.c,v 1.6 2024/09/15 05:26:05 yasuoka Exp $      */
 
 /*
  * Copyright (c) 2010 Reyk Floeter <reyk@vantronix.net>
@@ -158,6 +158,7 @@ static const struct token t_ipcp[] = {
        { KEYWORD,      "dump",         IPCP_DUMP,      t_ipcp_flags },
        { KEYWORD,      "monitor",      IPCP_MONITOR,   t_ipcp_flags },
        { KEYWORD,      "disconnect",   IPCP_DISCONNECT,t_ipcp_session_seq },
+       { KEYWORD,      "delete",       IPCP_DELETE,    t_ipcp_session_seq },
        { ENDTOKEN,     "",             NONE,           NULL }
 };
 
index 6fefb0f..fb3e88d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: parser.h,v 1.4 2024/07/24 08:27:20 yasuoka Exp $      */
+/*     $OpenBSD: parser.h,v 1.5 2024/09/15 05:26:05 yasuoka Exp $      */
 
 /* This file is derived from OpenBSD:src/usr.sbin/ikectl/parser.h 1.9 */
 /*
@@ -29,6 +29,7 @@ enum actions {
        IPCP_SHOW,
        IPCP_DUMP,
        IPCP_MONITOR,
+       IPCP_DELETE,
        IPCP_DISCONNECT
 };
 
index 00ab5bc..43bb876 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: radiusctl.8,v 1.9 2024/07/24 08:27:20 yasuoka Exp $
+.\"    $OpenBSD: radiusctl.8,v 1.10 2024/09/15 05:26:05 yasuoka Exp $
 .\"
 .\" Copyright (c) YASUOKA Masahiko <yasuoka@yasuoka.net>
 .\"
@@ -15,7 +15,7 @@
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
 .\"
-.Dd $Mdocdate: July 24 2024 $
+.Dd $Mdocdate: September 15 2024 $
 .Dt RADIUSCTL 8
 .Os
 .Sh NAME
@@ -114,6 +114,10 @@ shows the sessions in JSON format.
 .It Cm ipcp disconnect Ar sequence
 Request to disconnect the session specified by the
 .Ar sequence .
+.It Cm ipcp delete Ar sequence
+Request to delete the session specified by the
+.Ar sequence
+without requesting disconnection.
 .El
 .Sh EXAMPLES
 .Bd -literal -offset indent
index 6b8a4fe..40fec84 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: radiusctl.c,v 1.12 2024/07/24 08:27:20 yasuoka Exp $  */
+/*     $OpenBSD: radiusctl.c,v 1.13 2024/09/15 05:26:05 yasuoka Exp $  */
 /*
  * Copyright (c) 2015 YASUOKA Masahiko <yasuoka@yasuoka.net>
  *
@@ -170,6 +170,7 @@ main(int argc, char *argv[])
                    IMSG_RADIUSD_MODULE_IPCP_MONITOR :
                    IMSG_RADIUSD_MODULE_IPCP_DUMP, 0, 0, -1, iov, niov);
                break;
+       case IPCP_DELETE:
        case IPCP_DISCONNECT:
                memset(module_name, 0, sizeof(module_name));
                strlcpy(module_name, "ipcp",
@@ -178,8 +179,10 @@ main(int argc, char *argv[])
                iov[niov++].iov_len = RADIUSD_MODULE_NAME_LEN;
                iov[niov].iov_base = &res->session_seq;
                iov[niov++].iov_len = sizeof(res->session_seq);
-               imsg_composev(&ibuf, IMSG_RADIUSD_MODULE_IPCP_DISCONNECT, 0, 0,
-                   -1, iov, niov);
+               imsg_composev(&ibuf,
+                   (res->action == IPCP_DELETE)
+                   ? IMSG_RADIUSD_MODULE_IPCP_DELETE
+                   : IMSG_RADIUSD_MODULE_IPCP_DISCONNECT, 0, 0, -1, iov, niov);
                break;
        }
        while (ibuf.w.queued) {
@@ -199,6 +202,7 @@ main(int argc, char *argv[])
                        case IPCP_SHOW:
                        case IPCP_DUMP:
                        case IPCP_MONITOR:
+                       case IPCP_DELETE:
                        case IPCP_DISCONNECT:
                                done = ipcp_handle_imsg(res, &imsg, cnt++);
                                break;
index 4f0200f..0100334 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: radiusd_ipcp.c,v 1.14 2024/08/27 06:06:14 florian Exp $       */
+/*     $OpenBSD: radiusd_ipcp.c,v 1.15 2024/09/15 05:26:05 yasuoka Exp $       */
 
 /*
  * Copyright (c) 2024 Internet Initiative Japan Inc.
@@ -178,6 +178,8 @@ struct assigned_ipv4
                    struct in_addr);
 static struct assigned_ipv4
                *ipcp_ipv4_find(struct module_ipcp *, struct in_addr);
+static void     ipcp_ipv4_delete(struct module_ipcp *,
+                   struct assigned_ipv4 *, const char *);
 static void     ipcp_ipv4_release(struct module_ipcp *,
                    struct assigned_ipv4 *);
 static int      assigned_ipv4_compar(struct assigned_ipv4 *,
@@ -624,10 +626,14 @@ ipcp_dispatch_control(void *ctx, struct imsg *imsg)
                freezero(dump ,dumpsiz);
                break;
        case IMSG_RADIUSD_MODULE_IPCP_DISCONNECT:
+       case IMSG_RADIUSD_MODULE_IPCP_DELETE:
                if (datalen < sizeof(unsigned)) {
                        log_warn("%s: received "
-                           "IMSG_RADIUSD_MODULE_IPCP_DISCONNECT message size "
-                           "is wrong", __func__);
+                           "%s message size is wrong", __func__,
+                           (imsg->hdr.type ==
+                           IMSG_RADIUSD_MODULE_IPCP_DISCONNECT)
+                           ? "IMSG_RADIUSD_MODULE_IPCP_DISCONNECT"
+                           : "IMSG_RADIUSD_MODULE_IPCP_DELETE");
                        goto fail;
                }
                seq = *(unsigned *)imsg->data;
@@ -640,12 +646,19 @@ ipcp_dispatch_control(void *ctx, struct imsg *imsg)
                }
                if (assign == NULL) {
                        cause = "session not found";
-                       log_warnx("Disconnect seq=%u requested, but the "
-                           "session is not found", seq);
+                       log_warnx("%s seq=%u requested, but the "
+                           "session is not found",
+                           (imsg->hdr.type ==
+                           IMSG_RADIUSD_MODULE_IPCP_DISCONNECT)? "Disconnect"
+                           : "Delete", seq);
                        module_imsg_compose(self->base, IMSG_NG,
                            imsg->hdr.peerid, 0, -1, cause, strlen(cause) + 1);
-               }
-               else {
+               } else if (imsg->hdr.type == IMSG_RADIUSD_MODULE_IPCP_DELETE) {
+                       log_info("Delete seq=%u by request", assign->seq);
+                       ipcp_ipv4_delete(self,  assign, "By control");
+                       module_imsg_compose(self->base, IMSG_OK,
+                           imsg->hdr.peerid, 0, -1, NULL, 0);
+               } else {
                        if (assign->dae == NULL)
                                log_warnx("Disconnect seq=%u requested, but "
                                    "DAE is not configured", assign->seq);
@@ -1061,8 +1074,9 @@ ipcp_accounting_request(void *ctx, u_int q_id, const u_char *pkt,
                                continue;
                        log_info("Delete record for %s", inet_ntop(AF_INET,
                            &assign->ipv4, buf, sizeof(buf)));
-                       ipcp_del_db(self, assign);
-                       ipcp_ipv4_release(self, assign);
+                       ipcp_ipv4_delete(self, assign,
+                           (type == RADIUS_ACCT_STATUS_TYPE_ACCT_ON)
+                           ? "Receive Acct-On" : "Receive Acct-Off");
                }
                return;
        }
@@ -1254,6 +1268,20 @@ ipcp_ipv4_find(struct module_ipcp *self, struct in_addr ina)
        return (ret);
 }
 
+void
+ipcp_ipv4_delete(struct module_ipcp *self, struct assigned_ipv4 *assign,
+    const char *cause)
+{
+       static struct radiusd_ipcp_statistics stat = { 0 };
+
+       memset(stat.cause, 0, sizeof(stat.cause));
+       strlcpy(stat.cause, cause, sizeof(stat.cause));
+
+       ipcp_del_db(self, assign);
+       ipcp_notice_startstop(self, assign, 0, &stat);
+       ipcp_ipv4_release(self, assign);
+}
+
 void
 ipcp_ipv4_release(struct module_ipcp *self, struct assigned_ipv4 *assign)
 {
index e86bbd0..287f727 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: radiusd_ipcp.h,v 1.1 2024/07/09 17:26:14 yasuoka Exp $        */
+/*     $OpenBSD: radiusd_ipcp.h,v 1.2 2024/09/15 05:26:05 yasuoka Exp $        */
 
 /*
  * Copyright (c) 2024 Internet Initiative Japan Inc.
@@ -30,6 +30,7 @@ enum imsg_module_ipcp_type {
        IMSG_RADIUSD_MODULE_IPCP_DUMP_AND_MONITOR,
        IMSG_RADIUSD_MODULE_IPCP_START,
        IMSG_RADIUSD_MODULE_IPCP_STOP,
+       IMSG_RADIUSD_MODULE_IPCP_DELETE,
        IMSG_RADIUSD_MODULE_IPCP_DISCONNECT
 };