summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorLorenzo Colitti <lorenzo@google.com>2014-05-10 11:56:37 +0900
committerJP Abgrall <jpa@google.com>2014-05-16 19:20:43 +0000
commit2cf4347e486ca01b5ca6429b50e79b93de07adf8 (patch)
tree176bbd60f4a736ef4ec27c51f5f6d93ca89cad9d /net
parent5a87fa6a43733e241406e8d62fe28fdc0735bf93 (diff)
net: Use fwmark reflection in PMTU discovery.
Currently, routing lookups used for Path PMTU Discovery in absence of a socket or on unmarked sockets use a mark of 0. This causes PMTUD not to work when using routing based on netfilter fwmark mangling and fwmark ip rules, such as: iptables -j MARK --set-mark 17 ip rule add fwmark 17 lookup 100 This patch causes these route lookups to use the fwmark from the received ICMP error when the fwmark_reflect sysctl is enabled. This allows the administrator to make PMTUD work by configuring appropriate fwmark rules to mark the inbound ICMP packets. Black-box tested using user-mode linux by pointing different fwmarks at routing tables egressing on different interfaces, and using iptables mangling to mark packets inbound on each interface with the interface's fwmark. ICMPv4 and ICMPv6 PMTU discovery work as expected when mark reflection is enabled and fail when it is disabled. Change-Id: Id7fefb7ec1ff7f5142fba43db1960b050e0dfaec Signed-off-by: Lorenzo Colitti <lorenzo@google.com>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/route.c7
-rw-r--r--net/ipv6/route.c2
2 files changed, 8 insertions, 1 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index d35bbf0cf404..c04359196ebc 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -956,6 +956,9 @@ void ipv4_update_pmtu(struct sk_buff *skb, struct net *net, u32 mtu,
struct flowi4 fl4;
struct rtable *rt;
+ if (!mark)
+ mark = IP4_REPLY_MARK(net, skb->mark);
+
__build_flow_key(&fl4, NULL, iph, oif,
RT_TOS(iph->tos), protocol, mark, flow_flags);
rt = __ip_route_output_key(net, &fl4);
@@ -973,6 +976,10 @@ static void __ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu)
struct rtable *rt;
__build_flow_key(&fl4, sk, iph, 0, 0, 0, 0, 0);
+
+ if (!fl4.flowi4_mark)
+ fl4.flowi4_mark = IP4_REPLY_MARK(sock_net(sk), skb->mark);
+
rt = __ip_route_output_key(sock_net(sk), &fl4);
if (!IS_ERR(rt)) {
__ip_rt_update_pmtu(rt, &fl4, mtu);
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 29f389caf522..8ecf44af7c2e 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1107,7 +1107,7 @@ void ip6_update_pmtu(struct sk_buff *skb, struct net *net, __be32 mtu,
memset(&fl6, 0, sizeof(fl6));
fl6.flowi6_oif = oif;
- fl6.flowi6_mark = mark;
+ fl6.flowi6_mark = mark ? mark : IP6_REPLY_MARK(net, skb->mark);
fl6.flowi6_flags = 0;
fl6.daddr = iph->daddr;
fl6.saddr = iph->saddr;