1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef NFLOG_LISTENER_H
18 #define NFLOG_LISTENER_H
19 
20 #include <netdutils/Netfilter.h>
21 
22 #include "NetlinkListener.h"
23 #include "netdutils/StatusOr.h"
24 
25 namespace android {
26 namespace net {
27 
28 class NFLogListenerInterface {
29   public:
30     using DispatchFn =
31         std::function<void(const nlmsghdr& nlmsg, const nfgenmsg& nfmsg,
32                            const netdutils::Slice msg)>;
33 
34     virtual ~NFLogListenerInterface() = default;
35 
36     // Similar to NetlinkListener::subscribe() but performs an additional
37     // level of deserialization and dispatch.
38     //
39     // Threadsafe.
40     // All dispatch functions invoked on a single service thread.
41     // subscribe() and join() must not be called from the stack of fn().
42     virtual netdutils::Status subscribe(uint16_t nfLogGroup, const DispatchFn& fn) = 0;
43 
44     // Overloaded version of subscribe which allows to specify a copyRange for obtaining packet
45     // payloads.
46     virtual netdutils::Status subscribe(
47             uint16_t nfLogGroup, uint32_t copyRange, const DispatchFn& fn) = 0;
48 
49     // Halt delivery of messages from a nfLogGroup previously subscribed to above.
50     //
51     // Threadsafe.
52     virtual netdutils::Status unsubscribe(uint16_t nfLogGroup) = 0;
53 };
54 
55 // NFLogListener manages a single netlink socket with specialized
56 // settings required for processing of NFLOG messages.
57 //
58 // NFLogListener currently assumes that it is ok to drop messages
59 // generated by the kernel when under heavy load. This makes the
60 // class most suitable for advisory tasks and statistics.
61 class NFLogListener : public NFLogListenerInterface {
62   public:
63     using DispatchFn = NFLogListenerInterface::DispatchFn;
64 
65     // Do not invoke this constructor directly outside of tests. Use
66     // makeNFLogListener() instead.
67     NFLogListener(std::shared_ptr<NetlinkListenerInterface> listener);
68 
69     ~NFLogListener() override;
70 
71     netdutils::Status subscribe(uint16_t nfLogGroup, const DispatchFn& fn) override;
72 
73     netdutils::Status subscribe(
74             uint16_t nfLogGroup, uint32_t copyRange, const DispatchFn& fn) override;
75 
76     netdutils::Status unsubscribe(uint16_t nfLogGroup) override;
77 
78   private:
79     std::shared_ptr<NetlinkListenerInterface> mListener;
80     std::mutex mMutex;
81     std::map<uint16_t, DispatchFn> mDispatchMap;  // guarded by mMutex
82 };
83 
84 // Allocate and return a new NFLogListener. On success, the returned
85 // listener is ready to use with a running service thread.
86 netdutils::StatusOr<std::unique_ptr<NFLogListener>> makeNFLogListener();
87 
88 }  // namespace net
89 }  // namespace android
90 
91 #endif /* NFLOG_LISTENER_H */
92