• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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 package com.android.networkstack.tethering.apishim.common;
18 
19 import android.net.MacAddress;
20 import android.util.SparseArray;
21 
22 import androidx.annotation.NonNull;
23 import androidx.annotation.Nullable;
24 
25 import com.android.networkstack.tethering.BpfCoordinator.Dependencies;
26 import com.android.networkstack.tethering.BpfCoordinator.Ipv6ForwardingRule;
27 import com.android.networkstack.tethering.Tether4Key;
28 import com.android.networkstack.tethering.Tether4Value;
29 import com.android.networkstack.tethering.TetherStatsValue;
30 
31 import java.util.function.BiConsumer;
32 
33 /**
34  * Bpf coordinator class for API shims.
35  */
36 public abstract class BpfCoordinatorShim {
37     /**
38      * Get BpfCoordinatorShim object by OS build version.
39      */
40     @NonNull
getBpfCoordinatorShim(@onNull final Dependencies deps)41     public static BpfCoordinatorShim getBpfCoordinatorShim(@NonNull final Dependencies deps) {
42         if (deps.isAtLeastS()) {
43             return new com.android.networkstack.tethering.apishim.api31.BpfCoordinatorShimImpl(
44                     deps);
45         } else {
46             return new com.android.networkstack.tethering.apishim.api30.BpfCoordinatorShimImpl(
47                     deps);
48         }
49     }
50 
51     /**
52      * Return true if this class has been initialized, otherwise return false.
53      */
isInitialized()54     public abstract boolean isInitialized();
55 
56     /**
57      * Adds a tethering offload rule to BPF map, or updates it if it already exists.
58      *
59      * Currently, only downstream /128 IPv6 entries are supported. An existing rule will be updated
60      * if the input interface and destination prefix match. Otherwise, a new rule will be created.
61      * Note that this can be only called on handler thread.
62      *
63      * @param rule The rule to add or update.
64      */
tetherOffloadRuleAdd(@onNull Ipv6ForwardingRule rule)65     public abstract boolean tetherOffloadRuleAdd(@NonNull Ipv6ForwardingRule rule);
66 
67     /**
68      * Deletes a tethering offload rule from the BPF map.
69      *
70      * Currently, only downstream /128 IPv6 entries are supported. An existing rule will be deleted
71      * if the destination IP address and the source interface match. It is not an error if there is
72      * no matching rule to delete.
73      *
74      * @param rule The rule to delete.
75      */
tetherOffloadRuleRemove(@onNull Ipv6ForwardingRule rule)76     public abstract boolean tetherOffloadRuleRemove(@NonNull Ipv6ForwardingRule rule);
77 
78     /**
79      * Starts IPv6 forwarding between the specified interfaces.
80 
81      * @param downstreamIfindex the downstream interface index
82      * @param upstreamIfindex the upstream interface index
83      * @param inDstMac the destination MAC address to use for XDP
84      * @param outSrcMac the source MAC address to use for packets
85      * @param outDstMac the destination MAC address to use for packets
86      * @return true if operation succeeded or was a no-op, false otherwise
87      */
startUpstreamIpv6Forwarding(int downstreamIfindex, int upstreamIfindex, @NonNull MacAddress inDstMac, @NonNull MacAddress outSrcMac, @NonNull MacAddress outDstMac, int mtu)88     public abstract boolean startUpstreamIpv6Forwarding(int downstreamIfindex, int upstreamIfindex,
89             @NonNull MacAddress inDstMac, @NonNull MacAddress outSrcMac,
90             @NonNull MacAddress outDstMac, int mtu);
91 
92     /**
93      * Stops IPv6 forwarding between the specified interfaces.
94 
95      * @param downstreamIfindex the downstream interface index
96      * @param upstreamIfindex the upstream interface index
97      * @param inDstMac the destination MAC address to use for XDP
98      * @return true if operation succeeded or was a no-op, false otherwise
99      */
stopUpstreamIpv6Forwarding(int downstreamIfindex, int upstreamIfindex, @NonNull MacAddress inDstMac)100     public abstract boolean stopUpstreamIpv6Forwarding(int downstreamIfindex,
101             int upstreamIfindex, @NonNull MacAddress inDstMac);
102 
103     /**
104      * Return BPF tethering offload statistics.
105      *
106      * @return an array of TetherStatsValue's, where each entry contains the upstream interface
107      *         index and its tethering statistics since tethering was first started.
108      *         There will only ever be one entry for a given interface index.
109      */
110     @Nullable
tetherOffloadGetStats()111     public abstract SparseArray<TetherStatsValue> tetherOffloadGetStats();
112 
113    /**
114     * Set a per-interface quota for tethering offload.
115     *
116     * @param ifIndex Index of upstream interface
117     * @param quotaBytes The quota defined as the number of bytes, starting from zero and counting
118     *       from *now*. A value of QUOTA_UNLIMITED (-1) indicates there is no limit.
119     */
120     @Nullable
tetherOffloadSetInterfaceQuota(int ifIndex, long quotaBytes)121     public abstract boolean tetherOffloadSetInterfaceQuota(int ifIndex, long quotaBytes);
122 
123     /**
124      * Return BPF tethering offload statistics and clear the stats for a given upstream.
125      *
126      * Must only be called once all offload rules have already been deleted for the given upstream
127      * interface. The existing stats will be fetched and returned. The stats and the limit for the
128      * given upstream interface will be deleted as well.
129      *
130      * The stats and limit for a given upstream interface must be initialized (using
131      * tetherOffloadSetInterfaceQuota) before any offload will occur on that interface.
132      *
133      * Note that this can be only called while the BPF maps were initialized.
134      *
135      * @param ifIndex Index of upstream interface.
136      * @return TetherStatsValue, which contains the given upstream interface's tethering statistics
137      *         since tethering was first started on that upstream interface.
138      */
139     @Nullable
tetherOffloadGetAndClearStats(int ifIndex)140     public abstract TetherStatsValue tetherOffloadGetAndClearStats(int ifIndex);
141 
142     /**
143      * Adds a tethering IPv4 offload rule to appropriate BPF map.
144      */
tetherOffloadRuleAdd(boolean downstream, @NonNull Tether4Key key, @NonNull Tether4Value value)145     public abstract boolean tetherOffloadRuleAdd(boolean downstream, @NonNull Tether4Key key,
146             @NonNull Tether4Value value);
147 
148     /**
149      * Deletes a tethering IPv4 offload rule from the appropriate BPF map.
150      *
151      * @param downstream true if downstream, false if upstream.
152      * @param key the key to delete.
153      * @return true iff the map was modified, false if the key did not exist or there was an error.
154      */
tetherOffloadRuleRemove(boolean downstream, @NonNull Tether4Key key)155     public abstract boolean tetherOffloadRuleRemove(boolean downstream, @NonNull Tether4Key key);
156 
157     /**
158      * Iterate through the map and handle each key -> value retrieved base on the given BiConsumer.
159      *
160      * @param downstream true if downstream, false if upstream.
161      * @param action represents the action for each key -> value. The entry deletion is not
162      *        allowed and use #tetherOffloadRuleRemove instead.
163      */
164     @Nullable
tetherOffloadRuleForEach(boolean downstream, @NonNull BiConsumer<Tether4Key, Tether4Value> action)165     public abstract void tetherOffloadRuleForEach(boolean downstream,
166             @NonNull BiConsumer<Tether4Key, Tether4Value> action);
167 
168     /**
169      * Whether there is currently any IPv4 rule on the specified upstream.
170      */
isAnyIpv4RuleOnUpstream(int ifIndex)171     public abstract boolean isAnyIpv4RuleOnUpstream(int ifIndex);
172 
173     /**
174      * Attach BPF program.
175      *
176      * TODO: consider using InterfaceParams to replace interface name.
177      */
attachProgram(@onNull String iface, boolean downstream)178     public abstract boolean attachProgram(@NonNull String iface, boolean downstream);
179 
180     /**
181      * Detach BPF program.
182      *
183      * TODO: consider using InterfaceParams to replace interface name.
184      */
detachProgram(@onNull String iface)185     public abstract boolean detachProgram(@NonNull String iface);
186 
187     /**
188      * Add interface index mapping.
189      */
addDevMap(int ifIndex)190     public abstract boolean addDevMap(int ifIndex);
191 
192     /**
193      * Remove interface index mapping.
194      */
removeDevMap(int ifIndex)195     public abstract boolean removeDevMap(int ifIndex);
196 }
197 
198