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