blob: 5e6527f5ca42b84b96d77426944d99e8375fd1d2 [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>
Harish Ambati8fb99a32023-02-16 15:44:20 +000024#include <linux/netfilter/xt_usage.h>
25#include <linux/netfilter/x_tables.h>
Kyle Swenson7900a3c2021-08-12 14:34:44 -060026#include <net/netfilter/nf_conntrack.h>
27#include <net/netfilter/nf_conntrack_core.h>
28
29#include "cdu_db.h"
30#include "cdu_nf_events.h"
31#include "cdu_xt_target.h"
32#include "cdu_types.h"
33
34#ifndef CONFIG_NF_CONNTRACK_CHAIN_EVENTS
35#error Can not use this module without conntrack events
36#endif
37
38static u_int8_t nf_registered;
39
40static int cdu_nf_event(struct notifier_block *this, unsigned long events, void *ptr)
41{
42 struct nf_ct_event *item = (struct nf_ct_event *)ptr;
43 struct nf_conn *ct = item->ct;
44
45 if (!ct) {
46 CDU_DEBUG("No ct available\n");
47 return -EINVAL;
48 }
49
50 if (ct->orig_direction == CDU_DIR_NOT_SET) {
51 /* This ct does not have a direction information because it didn't
52 * travel through the xt hook, which means that we don't care
53 * about this traffic
54 */
55 return NOTIFY_DONE;
56 }
57
58 /* Update data usage htable entry on end of flow trigger */
59 if (events & (1 << IPCT_DESTROY)) {
60 CDU_DEBUG("Caught %s NF event. mac=%pM, dir %s, ct %p\n",
61 events & (1 << IPCT_NEW)?"NEW":"DESTROY", ct->mac,
62 (ct->orig_direction == CDU_DIR_SRC)?"DIR_SRC":"DIR_DEST", ct);
63
64 cdu_db_update_entry(ct, CDU_DB_UPDATE_PERMA_SET, CDU_DB_CONNTR_NOCLEAR);
65 }
66
67 return NOTIFY_DONE;
68}
69
70static struct notifier_block cdu_nf_notifier = {
71 .notifier_call = cdu_nf_event,
72};
73
74int cdu_nf_events_register(void)
75{
76 int result;
77
78 if (!nf_registered) {
79 result = nf_conntrack_register_notifier(&init_net, &cdu_nf_notifier);
80 if (result < 0) {
81 CDU_INFO("Failed to register conntrack notifier %d\n", result);
82 return result;
83 }
84 nf_registered = 1;
85 }
86
87 CDU_DEBUG("initialized\n");
88 return 0;
89}
90
91void cdu_nf_events_unregister(void)
92{
93 if (nf_registered) {
94 nf_conntrack_unregister_notifier(&init_net, &cdu_nf_notifier);
95 CDU_DEBUG("uninitialized\n");
96 }
97}
98