1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #ifndef NET_FIREWALL_EVENT_H
16 #define NET_FIREWALL_EVENT_H
17 
18 #include "netfirewall_types.h"
19 #include "netfirewall_event_map.h"
20 
21 /**
22  * @brief output event to ring buffer for user polling
23  *
24  * @param type enum event_type
25  * @param data event data
26  * @param len  event data len
27  */
output_to_user(enum event_type type,void * data,__u32 len)28 static __always_inline void output_to_user(enum event_type type, void *data, __u32 len)
29 {
30     if (data && len > 0) {
31         struct event *e = bpf_ringbuf_reserve(&EVENT_MAP, sizeof(struct event), 0);
32         if (!e) {
33             return;
34         }
35 
36         e->type = type;
37         e->len = len;
38 
39         switch (type) {
40             case EVENT_DEBUG:
41                 memcpy(&(e->debug), data, len);
42                 break;
43             case EVENT_INTERCEPT:
44                 memcpy(&(e->intercept), data, len);
45                 break;
46             case EVENT_TUPLE_DEBUG:
47                 memcpy(&(e->tuple), data, len);
48                 break;
49             default:
50                 break;
51         }
52 
53         bpf_ringbuf_submit(e, 0);
54     }
55 }
56 
57 /**
58  * @brief send intercept info to ring buffer for user polling
59  *
60  * @param tuple struct match_tuple
61  */
log_intercept(struct match_tuple * tuple)62 static __always_inline void log_intercept(struct match_tuple *tuple)
63 {
64     if (!tuple) {
65         return;
66     }
67 
68     struct intercept_event ev = {
69         .dir = tuple->dir,
70         .family = tuple->family,
71         .protocol = tuple->protocol,
72         .sport = tuple->sport,
73         .dport = tuple->dport,
74         .appuid = tuple->appuid,
75     };
76 
77     if (AF_INET == tuple->family) {
78         ev.ipv4.saddr = tuple->ipv4.saddr;
79         ev.ipv4.daddr = tuple->ipv4.daddr;
80     } else if (AF_INET6 == tuple->family) {
81         ev.ipv6.saddr = tuple->ipv6.saddr;
82         ev.ipv6.daddr = tuple->ipv6.daddr;
83     }
84     output_to_user(EVENT_INTERCEPT, &ev, sizeof(struct intercept_event));
85 }
86 
87 #if NET_FIREWALL_DEBUG_TUPLE
88 /**
89  * @brief send match tuple to ring buffer for user polling
90  *
91  * @param tuple struct match_tuple
92  */
log_tuple(struct match_tuple * tuple)93 static __always_inline void log_tuple(struct match_tuple *tuple)
94 {
95     if (!tuple) {
96         return;
97     }
98 
99     output_to_user(EVENT_TUPLE_DEBUG, tuple, sizeof(struct match_tuple));
100 }
101 
102 #else // NET_FIREWALL_DEBUG_TUPLE
103 
104 #define log_tuple(tuple)
105 
106 #endif // NET_FIREWALL_DEBUG_TUPLE
107 
108 #if NET_FIREWALL_DEBUG
log_dbg_any(enum debug_type type,__u32 arg1)109 static __always_inline void log_dbg_any(enum debug_type type, __u32 arg1)
110 {
111     struct debug_event ev = {
112         .type = type,
113         .arg1 = arg1,
114     };
115 
116     output_to_user(EVENT_DEBUG, &ev, sizeof(struct debug_event));
117 }
118 
log_dbg(enum debug_type type,enum stream_dir dir,__u32 arg1)119 static __always_inline void log_dbg(enum debug_type type, enum stream_dir dir, __u32 arg1)
120 {
121     struct debug_event ev = {
122         .type = type,
123         .dir = dir,
124         .arg1 = arg1,
125     };
126 
127     output_to_user(EVENT_DEBUG, &ev, sizeof(struct debug_event));
128 }
129 
log_dbg2(enum debug_type type,enum stream_dir dir,__u32 arg1,__u32 arg2)130 static __always_inline void log_dbg2(enum debug_type type, enum stream_dir dir, __u32 arg1, __u32 arg2)
131 {
132     struct debug_event ev = {
133         .type = type,
134         .dir = dir,
135         .arg1 = arg1,
136         .arg2 = arg2,
137     };
138 
139     output_to_user(EVENT_DEBUG, &ev, sizeof(struct debug_event));
140 }
141 
log_dbg3(enum debug_type type,enum stream_dir dir,__u32 arg1,__u32 arg2,__u32 arg3)142 static __always_inline void log_dbg3(enum debug_type type, enum stream_dir dir, __u32 arg1, __u32 arg2, __u32 arg3)
143 {
144     struct debug_event ev = {
145         .type = type,
146         .dir = dir,
147         .arg1 = arg1,
148         .arg2 = arg2,
149         .arg3 = arg3,
150     };
151 
152     output_to_user(EVENT_DEBUG, &ev, sizeof(struct debug_event));
153 }
154 
log_dbg4(enum debug_type type,enum stream_dir dir,__u32 arg1,__u32 arg2,__u32 arg3,__u32 arg4)155 static __always_inline void log_dbg4(enum debug_type type, enum stream_dir dir, __u32 arg1, __u32 arg2, __u32 arg3,
156     __u32 arg4)
157 {
158     struct debug_event ev = {
159         .type = type,
160         .dir = dir,
161         .arg1 = arg1,
162         .arg2 = arg2,
163         .arg3 = arg3,
164         .arg4 = arg4,
165     };
166 
167     output_to_user(EVENT_DEBUG, &ev, sizeof(struct debug_event));
168 }
169 
log_dbg5(enum debug_type type,enum stream_dir dir,__u32 arg1,__u32 arg2,__u32 arg3,__u32 arg4,__u32 arg5)170 static __always_inline void log_dbg5(enum debug_type type, enum stream_dir dir, __u32 arg1, __u32 arg2, __u32 arg3,
171     __u32 arg4, __u32 arg5)
172 {
173     struct debug_event ev = {
174         .type = type,
175         .dir = dir,
176         .arg1 = arg1,
177         .arg2 = arg2,
178         .arg3 = arg3,
179         .arg4 = arg4,
180         .arg5 = arg5,
181     };
182 
183     output_to_user(EVENT_DEBUG, &ev, sizeof(struct debug_event));
184 }
185 
186 #else // NET_FIREWALL_DEBUG
187 
188 #define log_dbg_any(type, arg1)
189 #define log_dbg(type, dir, arg1)
190 #define log_dbg2(type, dir, arg1, arg2)
191 #define log_dbg3(type, dir, arg1, arg2, arg3)
192 #define log_dbg4(type, dir, arg1, arg2, arg3, arg4)
193 #define log_dbg5(type, dir, arg1, arg2, arg3, arg4, arg5)
194 
195 #endif // NET_FIREWALL_DEBUG
196 #endif // NET_FIREWALL_EVENT_H