aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/ipv6.h3
-rw-r--r--include/uapi/linux/in6.h1
-rw-r--r--net/ipv6/ip6_flowlabel.c8
-rw-r--r--net/ipv6/ipv6_sockglue.c5
4 files changed, 14 insertions, 3 deletions
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 6d80f51897a5..78d3d5124918 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -253,7 +253,8 @@ struct ipv6_txoptions *fl6_merge_options(struct ipv6_txoptions *opt_space,
253 struct ipv6_txoptions *fopt); 253 struct ipv6_txoptions *fopt);
254void fl6_free_socklist(struct sock *sk); 254void fl6_free_socklist(struct sock *sk);
255int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen); 255int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen);
256int ipv6_flowlabel_opt_get(struct sock *sk, struct in6_flowlabel_req *freq); 256int ipv6_flowlabel_opt_get(struct sock *sk, struct in6_flowlabel_req *freq,
257 int flags);
257int ip6_flowlabel_init(void); 258int ip6_flowlabel_init(void);
258void ip6_flowlabel_cleanup(void); 259void ip6_flowlabel_cleanup(void);
259 260
diff --git a/include/uapi/linux/in6.h b/include/uapi/linux/in6.h
index 02c0cd685a27..633b93cac1ed 100644
--- a/include/uapi/linux/in6.h
+++ b/include/uapi/linux/in6.h
@@ -86,6 +86,7 @@ struct in6_flowlabel_req {
86#define IPV6_FL_F_CREATE 1 86#define IPV6_FL_F_CREATE 1
87#define IPV6_FL_F_EXCL 2 87#define IPV6_FL_F_EXCL 2
88#define IPV6_FL_F_REFLECT 4 88#define IPV6_FL_F_REFLECT 4
89#define IPV6_FL_F_REMOTE 8
89 90
90#define IPV6_FL_S_NONE 0 91#define IPV6_FL_S_NONE 0
91#define IPV6_FL_S_EXCL 1 92#define IPV6_FL_S_EXCL 1
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index 55823f187446..01bf2524c72a 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -481,11 +481,17 @@ static inline void fl_link(struct ipv6_pinfo *np, struct ipv6_fl_socklist *sfl,
481 spin_unlock_bh(&ip6_sk_fl_lock); 481 spin_unlock_bh(&ip6_sk_fl_lock);
482} 482}
483 483
484int ipv6_flowlabel_opt_get(struct sock *sk, struct in6_flowlabel_req *freq) 484int ipv6_flowlabel_opt_get(struct sock *sk, struct in6_flowlabel_req *freq,
485 int flags)
485{ 486{
486 struct ipv6_pinfo *np = inet6_sk(sk); 487 struct ipv6_pinfo *np = inet6_sk(sk);
487 struct ipv6_fl_socklist *sfl; 488 struct ipv6_fl_socklist *sfl;
488 489
490 if (flags & IPV6_FL_F_REMOTE) {
491 freq->flr_label = np->rcv_flowinfo & IPV6_FLOWLABEL_MASK;
492 return 0;
493 }
494
489 if (np->repflow) { 495 if (np->repflow) {
490 freq->flr_label = np->flow_label; 496 freq->flr_label = np->flow_label;
491 return 0; 497 return 0;
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 2855b00ed49d..7024a874e901 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -1221,6 +1221,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
1221 case IPV6_FLOWLABEL_MGR: 1221 case IPV6_FLOWLABEL_MGR:
1222 { 1222 {
1223 struct in6_flowlabel_req freq; 1223 struct in6_flowlabel_req freq;
1224 int flags;
1224 1225
1225 if (len < sizeof(freq)) 1226 if (len < sizeof(freq))
1226 return -EINVAL; 1227 return -EINVAL;
@@ -1232,9 +1233,11 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
1232 return -EINVAL; 1233 return -EINVAL;
1233 1234
1234 len = sizeof(freq); 1235 len = sizeof(freq);
1236 flags = freq.flr_flags;
1237
1235 memset(&freq, 0, sizeof(freq)); 1238 memset(&freq, 0, sizeof(freq));
1236 1239
1237 val = ipv6_flowlabel_opt_get(sk, &freq); 1240 val = ipv6_flowlabel_opt_get(sk, &freq, flags);
1238 if (val < 0) 1241 if (val < 0)
1239 return val; 1242 return val;
1240 1243