-/* $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>
{ 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 }
};
-/* $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>
*
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",
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) {
case IPCP_SHOW:
case IPCP_DUMP:
case IPCP_MONITOR:
+ case IPCP_DELETE:
case IPCP_DISCONNECT:
done = ipcp_handle_imsg(res, &imsg, cnt++);
break;
-/* $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.
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 *,
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;
}
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);
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;
}
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)
{