aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIdo Schimmel <idosch@mellanox.com>2018-10-17 08:53:12 +0000
committerDavid S. Miller <davem@davemloft.net>2018-10-17 17:45:07 -0700
commit28e450333d4d1328710e258d38793c61658d4c95 (patch)
tree3a380928f8708c44c877984467d8cb065661d784
parentvxlan: Export address checking functions (diff)
downloadlinux-dev-28e450333d4d1328710e258d38793c61658d4c95.tar.xz
linux-dev-28e450333d4d1328710e258d38793c61658d4c95.zip
inet: Refactor INET_ECN_decapsulate()
Drivers that support tunnel decapsulation (IPinIP or NVE) need to configure the underlying device to conform to the behavior outlined in RFC 6040 with respect to the ECN bits. This behavior is implemented by INET_ECN_decapsulate() which requires an skb to be passed where the ECN CE bit can be potentially set. Since these drivers do not need to mark an skb, but only configure the device to do so, factor out the business logic to __INET_ECN_decapsulate() and potentially perform the marking in INET_ECN_decapsulate(). This allows drivers to invoke __INET_ECN_decapsulate() and configure the device. Signed-off-by: Ido Schimmel <idosch@mellanox.com> Suggested-by: Petr Machata <petrm@mellanox.com> Reviewed-by: Petr Machata <petrm@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/inet_ecn.h18
1 files changed, 14 insertions, 4 deletions
diff --git a/include/net/inet_ecn.h b/include/net/inet_ecn.h
index 482a1b705362..c8e2bebd8d93 100644
--- a/include/net/inet_ecn.h
+++ b/include/net/inet_ecn.h
@@ -183,8 +183,7 @@ static inline int INET_ECN_set_ce(struct sk_buff *skb)
* 1 if something is broken and should be logged (!!! above)
* 2 if packet should be dropped
*/
-static inline int INET_ECN_decapsulate(struct sk_buff *skb,
- __u8 outer, __u8 inner)
+static inline int __INET_ECN_decapsulate(__u8 outer, __u8 inner, bool *set_ce)
{
if (INET_ECN_is_not_ect(inner)) {
switch (outer & INET_ECN_MASK) {
@@ -198,10 +197,21 @@ static inline int INET_ECN_decapsulate(struct sk_buff *skb,
}
}
- if (INET_ECN_is_ce(outer))
+ *set_ce = INET_ECN_is_ce(outer);
+ return 0;
+}
+
+static inline int INET_ECN_decapsulate(struct sk_buff *skb,
+ __u8 outer, __u8 inner)
+{
+ bool set_ce = false;
+ int rc;
+
+ rc = __INET_ECN_decapsulate(outer, inner, &set_ce);
+ if (!rc && set_ce)
INET_ECN_set_ce(skb);
- return 0;
+ return rc;
}
static inline int IP_ECN_decapsulate(const struct iphdr *oiph,