diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv6/exthdrs.c | 19 | ||||
-rw-r--r-- | net/ipv6/ip6_flowlabel.c | 16 | ||||
-rw-r--r-- | net/ipv6/raw.c | 4 | ||||
-rw-r--r-- | net/ipv6/udp.c | 4 |
4 files changed, 31 insertions, 12 deletions
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index 748577b76d75..be6faf311387 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c | |||
@@ -673,3 +673,22 @@ out: | |||
673 | return ERR_PTR(err); | 673 | return ERR_PTR(err); |
674 | } | 674 | } |
675 | 675 | ||
676 | struct ipv6_txoptions *ipv6_fixup_options(struct ipv6_txoptions *opt_space, | ||
677 | struct ipv6_txoptions *opt) | ||
678 | { | ||
679 | /* | ||
680 | * ignore the dest before srcrt unless srcrt is being included. | ||
681 | * --yoshfuji | ||
682 | */ | ||
683 | if (opt && opt->dst0opt && !opt->srcrt) { | ||
684 | if (opt_space != opt) { | ||
685 | memcpy(opt_space, opt, sizeof(*opt_space)); | ||
686 | opt = opt_space; | ||
687 | } | ||
688 | opt->opt_nflen -= ipv6_optlen(opt->dst0opt); | ||
689 | opt->dst0opt = NULL; | ||
690 | } | ||
691 | |||
692 | return opt; | ||
693 | } | ||
694 | |||
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c index bbbe80cdaf72..1cf02765fb5c 100644 --- a/net/ipv6/ip6_flowlabel.c +++ b/net/ipv6/ip6_flowlabel.c | |||
@@ -225,20 +225,16 @@ struct ipv6_txoptions *fl6_merge_options(struct ipv6_txoptions * opt_space, | |||
225 | struct ip6_flowlabel * fl, | 225 | struct ip6_flowlabel * fl, |
226 | struct ipv6_txoptions * fopt) | 226 | struct ipv6_txoptions * fopt) |
227 | { | 227 | { |
228 | struct ipv6_txoptions * fl_opt = fl ? fl->opt : NULL; | 228 | struct ipv6_txoptions * fl_opt = fl->opt; |
229 | 229 | ||
230 | if (fopt == NULL || fopt->opt_flen == 0) { | 230 | if (fopt == NULL || fopt->opt_flen == 0) |
231 | if (!fl_opt || !fl_opt->dst0opt || fl_opt->srcrt) | 231 | return fl_opt; |
232 | return fl_opt; | 232 | |
233 | } | ||
234 | |||
235 | if (fl_opt != NULL) { | 233 | if (fl_opt != NULL) { |
236 | opt_space->hopopt = fl_opt->hopopt; | 234 | opt_space->hopopt = fl_opt->hopopt; |
237 | opt_space->dst0opt = fl_opt->srcrt ? fl_opt->dst0opt : NULL; | 235 | opt_space->dst0opt = fl_opt->dst0opt; |
238 | opt_space->srcrt = fl_opt->srcrt; | 236 | opt_space->srcrt = fl_opt->srcrt; |
239 | opt_space->opt_nflen = fl_opt->opt_nflen; | 237 | opt_space->opt_nflen = fl_opt->opt_nflen; |
240 | if (fl_opt->dst0opt && !fl_opt->srcrt) | ||
241 | opt_space->opt_nflen -= ipv6_optlen(fl_opt->dst0opt); | ||
242 | } else { | 238 | } else { |
243 | if (fopt->opt_nflen == 0) | 239 | if (fopt->opt_nflen == 0) |
244 | return fopt; | 240 | return fopt; |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index a1265a320b11..d77d3352c967 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -756,7 +756,9 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
756 | } | 756 | } |
757 | if (opt == NULL) | 757 | if (opt == NULL) |
758 | opt = np->opt; | 758 | opt = np->opt; |
759 | opt = fl6_merge_options(&opt_space, flowlabel, opt); | 759 | if (flowlabel) |
760 | opt = fl6_merge_options(&opt_space, flowlabel, opt); | ||
761 | opt = ipv6_fixup_options(&opt_space, opt); | ||
760 | 762 | ||
761 | fl.proto = proto; | 763 | fl.proto = proto; |
762 | rawv6_probe_proto_opt(&fl, msg); | 764 | rawv6_probe_proto_opt(&fl, msg); |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index bf9519341fd3..e2b87cc68b7b 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -778,7 +778,9 @@ do_udp_sendmsg: | |||
778 | } | 778 | } |
779 | if (opt == NULL) | 779 | if (opt == NULL) |
780 | opt = np->opt; | 780 | opt = np->opt; |
781 | opt = fl6_merge_options(&opt_space, flowlabel, opt); | 781 | if (flowlabel) |
782 | opt = fl6_merge_options(&opt_space, flowlabel, opt); | ||
783 | opt = ipv6_fixup_options(&opt_space, opt); | ||
782 | 784 | ||
783 | fl->proto = IPPROTO_UDP; | 785 | fl->proto = IPPROTO_UDP; |
784 | ipv6_addr_copy(&fl->fl6_dst, daddr); | 786 | ipv6_addr_copy(&fl->fl6_dst, daddr); |