blob: 18efdcbe5cfe90298b71bf4509317a41b9243394 [file] [log] [blame]
Kyle Swenson7900a3c2021-08-12 14:34:44 -06001/* cdu_nf_events.c
2 *
3 * This file handles client data usage netfilter conntrack events.
4 *
5 * Author: Cradlepoint Technology, Inc. <source@cradlepoint.com>
6 * Adrian Sitterle <asitterle@cradlepoint.com>
7 *
8 * Copyright (C) 2019 Cradlepoint Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 * as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 */
19
20#include <linux/version.h>
21#include <linux/types.h>
22#include <linux/kernel.h>
23#include <linux/module.h>
Kyle Swenson9e092e92024-01-15 11:57:45 -070024#include <linux/netfilter/x_tables.h>
Kyle Swenson7900a3c2021-08-12 14:34:44 -060025#include <net/netfilter/nf_conntrack.h>
26#include <net/netfilter/nf_conntrack_core.h>
27
28#include "cdu_db.h"
29#include "cdu_nf_events.h"
30#include "cdu_xt_target.h"
31#include "cdu_types.h"
32
33#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
34#error Can not use this module without conntrack events
35#endif
36
37static u_int8_t nf_registered;
38
39static int cdu_nf_event(struct notifier_block *this, unsigned long events, void *ptr)
40{
41 struct nf_ct_event *item = (struct nf_ct_event *)ptr;
42 struct nf_conn *ct = item->ct;
43
44 if (!ct) {
45 CDU_DEBUG("No ct available\n");
46 return -EINVAL;
47 }
48
49 if (ct->orig_direction == CDU_DIR_NOT_SET) {
50 /* This ct does not have a direction information because it didn't
51 * travel through the xt hook, which means that we don't care
52 * about this traffic
53 */
54 return NOTIFY_DONE;
55 }
56
57 /* Update data usage htable entry on end of flow trigger */
58 if (events & (1 << IPCT_DESTROY)) {
59 CDU_DEBUG("Caught %s NF event. mac=%pM, dir %s, ct %p\n",
60 events & (1 << IPCT_NEW)?"NEW":"DESTROY", ct->mac,
61 (ct->orig_direction == CDU_DIR_SRC)?"DIR_SRC":"DIR_DEST", ct);
62
63 cdu_db_update_entry(ct, CDU_DB_UPDATE_PERMA_SET, CDU_DB_CONNTR_NOCLEAR);
64 }
65
66 return NOTIFY_DONE;
67}
68
69static struct notifier_block cdu_nf_notifier = {
70 .notifier_call = cdu_nf_event,
71};
72
73int cdu_nf_events_register(void)
74{
75 int result;
76
77 if (!nf_registered) {
78 result = nf_conntrack_register_notifier(&init_net, &cdu_nf_notifier);
79 if (result < 0) {
80 CDU_INFO("Failed to register conntrack notifier %d\n", result);
81 return result;
82 }
83 nf_registered = 1;
84 }
85
86 CDU_DEBUG("initialized\n");
87 return 0;
88}
89
90void cdu_nf_events_unregister(void)
91{
92 if (nf_registered) {
93 nf_conntrack_unregister_notifier(&init_net, &cdu_nf_notifier);
94 CDU_DEBUG("uninitialized\n");
95 }
96}
97