Skip to content

Commit

Permalink
ipv6: use TOS marks from sockets for routing decision
Browse files Browse the repository at this point in the history
In IPv6 the ToS values are part of the flowlabel in flowi6 and get
extracted during fib rule lookup, but we forgot to correctly initialize
the flowlabel before the routing lookup.

Reported-by: <liam.mcbirnie@boeing.com>
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Hannes Frederic Sowa authored and David S. Miller committed Jun 11, 2016
1 parent e69f73b commit 38b7097
Show file tree
Hide file tree
Showing 6 changed files with 23 additions and 11 deletions.
4 changes: 3 additions & 1 deletion net/ipv6/icmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -502,12 +502,14 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
else if (!fl6.flowi6_oif)
fl6.flowi6_oif = np->ucast_oif;

ipc6.tclass = np->tclass;
fl6.flowlabel = ip6_make_flowinfo(ipc6.tclass, fl6.flowlabel);

dst = icmpv6_route_lookup(net, skb, sk, &fl6);
if (IS_ERR(dst))
goto out;

ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
ipc6.tclass = np->tclass;
ipc6.dontfrag = np->dontfrag;
ipc6.opt = NULL;

Expand Down
4 changes: 3 additions & 1 deletion net/ipv6/ping.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
else if (!fl6.flowi6_oif)
fl6.flowi6_oif = np->ucast_oif;

ipc6.tclass = np->tclass;
fl6.flowlabel = ip6_make_flowinfo(ipc6.tclass, fl6.flowlabel);

dst = ip6_sk_dst_lookup_flow(sk, &fl6, daddr);
if (IS_ERR(dst))
return PTR_ERR(dst);
Expand All @@ -140,7 +143,6 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
pfh.family = AF_INET6;

ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
ipc6.tclass = np->tclass;
ipc6.dontfrag = np->dontfrag;
ipc6.opt = NULL;

Expand Down
8 changes: 5 additions & 3 deletions net/ipv6/raw.c
Original file line number Diff line number Diff line change
Expand Up @@ -878,6 +878,11 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
if (inet->hdrincl)
fl6.flowi6_flags |= FLOWI_FLAG_KNOWN_NH;

if (ipc6.tclass < 0)
ipc6.tclass = np->tclass;

fl6.flowlabel = ip6_make_flowinfo(ipc6.tclass, fl6.flowlabel);

dst = ip6_dst_lookup_flow(sk, &fl6, final_p);
if (IS_ERR(dst)) {
err = PTR_ERR(dst);
Expand All @@ -886,9 +891,6 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
if (ipc6.hlimit < 0)
ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);

if (ipc6.tclass < 0)
ipc6.tclass = np->tclass;

if (ipc6.dontfrag < 0)
ipc6.dontfrag = np->dontfrag;

Expand Down
2 changes: 2 additions & 0 deletions net/ipv6/route.c
Original file line number Diff line number Diff line change
Expand Up @@ -3306,6 +3306,8 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh)

err = -EINVAL;
memset(&fl6, 0, sizeof(fl6));
rtm = nlmsg_data(nlh);
fl6.flowlabel = ip6_make_flowinfo(rtm->rtm_tos, 0);

if (tb[RTA_SRC]) {
if (nla_len(tb[RTA_SRC]) < sizeof(struct in6_addr))
Expand Down
8 changes: 5 additions & 3 deletions net/ipv6/udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1246,6 +1246,11 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)

security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));

if (ipc6.tclass < 0)
ipc6.tclass = np->tclass;

fl6.flowlabel = ip6_make_flowinfo(ipc6.tclass, fl6.flowlabel);

dst = ip6_sk_dst_lookup_flow(sk, &fl6, final_p);
if (IS_ERR(dst)) {
err = PTR_ERR(dst);
Expand All @@ -1256,9 +1261,6 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
if (ipc6.hlimit < 0)
ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);

if (ipc6.tclass < 0)
ipc6.tclass = np->tclass;

if (msg->msg_flags&MSG_CONFIRM)
goto do_confirm;
back_from_confirm:
Expand Down
8 changes: 5 additions & 3 deletions net/l2tp/l2tp_ip6.c
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,11 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)

security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));

if (ipc6.tclass < 0)
ipc6.tclass = np->tclass;

fl6.flowlabel = ip6_make_flowinfo(ipc6.tclass, fl6.flowlabel);

dst = ip6_dst_lookup_flow(sk, &fl6, final_p);
if (IS_ERR(dst)) {
err = PTR_ERR(dst);
Expand All @@ -620,9 +625,6 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
if (ipc6.hlimit < 0)
ipc6.hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);

if (ipc6.tclass < 0)
ipc6.tclass = np->tclass;

if (ipc6.dontfrag < 0)
ipc6.dontfrag = np->dontfrag;

Expand Down

0 comments on commit 38b7097

Please sign in to comment.