Skip to content

Commit

Permalink
ipv6: expose RFC4191 route preference via rtnetlink
Browse files Browse the repository at this point in the history
This makes it possible to retain the route preference when RAs are handled in
userspace.

Signed-off-by: Lubomir Rintel <[email protected]>
Reviewed-by: Jiri Pirko <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
lkundrak authored and davem330 committed Mar 12, 2015
1 parent ac70c05 commit c78ba6d
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 1 deletion.
1 change: 1 addition & 0 deletions include/uapi/linux/rtnetlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ enum rtattr_type_t {
RTA_MFC_STATS,
RTA_VIA,
RTA_NEWDST,
RTA_PREF,
__RTA_MAX
};

Expand Down
16 changes: 15 additions & 1 deletion net/ipv6/route.c
Original file line number Diff line number Diff line change
Expand Up @@ -2398,13 +2398,15 @@ static const struct nla_policy rtm_ipv6_policy[RTA_MAX+1] = {
[RTA_PRIORITY] = { .type = NLA_U32 },
[RTA_METRICS] = { .type = NLA_NESTED },
[RTA_MULTIPATH] = { .len = sizeof(struct rtnexthop) },
[RTA_PREF] = { .type = NLA_U8 },
};

static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh,
struct fib6_config *cfg)
{
struct rtmsg *rtm;
struct nlattr *tb[RTA_MAX+1];
unsigned int pref;
int err;

err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv6_policy);
Expand Down Expand Up @@ -2480,6 +2482,14 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh,
cfg->fc_mp_len = nla_len(tb[RTA_MULTIPATH]);
}

if (tb[RTA_PREF]) {
pref = nla_get_u8(tb[RTA_PREF]);
if (pref != ICMPV6_ROUTER_PREF_LOW &&
pref != ICMPV6_ROUTER_PREF_HIGH)
pref = ICMPV6_ROUTER_PREF_MEDIUM;
cfg->fc_flags |= RTF_PREF(pref);
}

err = 0;
errout:
return err;
Expand Down Expand Up @@ -2583,7 +2593,8 @@ static inline size_t rt6_nlmsg_size(void)
+ nla_total_size(4) /* RTA_PRIORITY */
+ RTAX_MAX * nla_total_size(4) /* RTA_METRICS */
+ nla_total_size(sizeof(struct rta_cacheinfo))
+ nla_total_size(TCP_CA_NAME_MAX); /* RTAX_CC_ALGO */
+ nla_total_size(TCP_CA_NAME_MAX) /* RTAX_CC_ALGO */
+ nla_total_size(1); /* RTA_PREF */
}

static int rt6_fill_node(struct net *net,
Expand Down Expand Up @@ -2724,6 +2735,9 @@ static int rt6_fill_node(struct net *net,
if (rtnl_put_cacheinfo(skb, &rt->dst, 0, expires, rt->dst.error) < 0)
goto nla_put_failure;

if (nla_put_u8(skb, RTA_PREF, IPV6_EXTRACT_PREF(rt->rt6i_flags)))
goto nla_put_failure;

nlmsg_end(skb, nlh);
return 0;

Expand Down

0 comments on commit c78ba6d

Please sign in to comment.