[IPV6]: Support several new sockopt / ancillary data in Advanced API (RFC3542).
Support several new socket options / ancillary data:
IPV6_RECVPKTINFO, IPV6_PKTINFO,
IPV6_RECVHOPOPTS, IPV6_HOPOPTS,
IPV6_RECVDSTOPTS, IPV6_DSTOPTS, IPV6_RTHDRDSTOPTS,
IPV6_RECVRTHDR, IPV6_RTHDR,
IPV6_RECVHOPOPTS, IPV6_HOPOPTS
Old semantics are preserved as IPV6_2292xxxx so that
we can maintain backward compatibility.
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index b6c73da..2d5ce37 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -225,16 +225,20 @@
struct ip6_flowlabel * fl,
struct ipv6_txoptions * fopt)
{
- struct ipv6_txoptions * fl_opt = fl->opt;
+ struct ipv6_txoptions * fl_opt = fl ? fl->opt : NULL;
- if (fopt == NULL || fopt->opt_flen == 0)
- return fl_opt;
+ if (fopt == NULL || fopt->opt_flen == 0) {
+ if (!fl_opt || !fl_opt->dst0opt || fl_opt->srcrt)
+ return fl_opt;
+ }
if (fl_opt != NULL) {
opt_space->hopopt = fl_opt->hopopt;
- opt_space->dst0opt = fl_opt->dst0opt;
+ opt_space->dst0opt = fl_opt->srcrt ? fl_opt->dst0opt : NULL;
opt_space->srcrt = fl_opt->srcrt;
opt_space->opt_nflen = fl_opt->opt_nflen;
+ if (fl_opt->dst0opt && !fl_opt->srcrt)
+ opt_space->opt_nflen -= ipv6_optlen(fl_opt->dst0opt);
} else {
if (fopt->opt_nflen == 0)
return fopt;