diff options
author | Florent Fourcot <florent.fourcot@enst-bretagne.fr> | 2014-01-17 17:15:03 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-01-20 02:12:31 +0100 |
commit | df3687ffc6653e4d32168338b4dee20c164ed7c9 (patch) | |
tree | 5600a02ddadc63d45a49964db3f9ac02f34e29e6 /net/ipv6/ip6_flowlabel.c | |
parent | ipv4: be friend with drop monitor (diff) | |
download | linux-df3687ffc6653e4d32168338b4dee20c164ed7c9.tar.xz linux-df3687ffc6653e4d32168338b4dee20c164ed7c9.zip |
ipv6: add the IPV6_FL_F_REFLECT flag to IPV6_FL_A_GET
With this option, the socket will reply with the flow label value read
on received packets.
The goal is to have a connection with the same flow label in both
direction of the communication.
Changelog of V4:
* Do not erase the flow label on the listening socket. Use pktopts to
store the received value
Signed-off-by: Florent Fourcot <florent.fourcot@enst-bretagne.fr>
Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/ip6_flowlabel.c')
-rw-r--r-- | net/ipv6/ip6_flowlabel.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c index cbc93517b455..55823f187446 100644 --- a/net/ipv6/ip6_flowlabel.c +++ b/net/ipv6/ip6_flowlabel.c @@ -486,6 +486,11 @@ int ipv6_flowlabel_opt_get(struct sock *sk, struct in6_flowlabel_req *freq) struct ipv6_pinfo *np = inet6_sk(sk); struct ipv6_fl_socklist *sfl; + if (np->repflow) { + freq->flr_label = np->flow_label; + return 0; + } + rcu_read_lock_bh(); for_each_sk_fl_rcu(np, sfl) { @@ -527,6 +532,15 @@ int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen) switch (freq.flr_action) { case IPV6_FL_A_PUT: + if (freq.flr_flags & IPV6_FL_F_REFLECT) { + if (sk->sk_protocol != IPPROTO_TCP) + return -ENOPROTOOPT; + if (!np->repflow) + return -ESRCH; + np->flow_label = 0; + np->repflow = 0; + return 0; + } spin_lock_bh(&ip6_sk_fl_lock); for (sflp = &np->ipv6_fl_list; (sfl = rcu_dereference(*sflp))!=NULL; @@ -567,6 +581,13 @@ int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen) return -ESRCH; case IPV6_FL_A_GET: + if (freq.flr_flags & IPV6_FL_F_REFLECT) { + if (sk->sk_protocol != IPPROTO_TCP) + return -ENOPROTOOPT; + np->repflow = 1; + return 0; + } + if (freq.flr_label & ~IPV6_FLOWLABEL_MASK) return -EINVAL; |