Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ipv6: Add flow label to route get requests

The default IPv6 multipath hash policy takes the flow label into account
when calculating a multipath hash and previous patches added a flow
label selector to IPv6 FIB rules.

Allow user space to specify a flow label in route get requests by adding
a new netlink attribute and using its value to populate the "flowlabel"
field in the IPv6 flow info structure prior to a route lookup.

Deny the attribute in RTM_{NEW,DEL}ROUTE requests by checking for it in
rtm_to_fib6_config() and returning an error if present.

A subsequent patch will use this capability to test the new flow label
selector in IPv6 FIB rules.

Reviewed-by: Petr Machata <petrm@nvidia.com>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Guillaume Nault <gnault@redhat.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

authored by

Ido Schimmel and committed by
Paolo Abeni
ba413803 c72004aa

+20 -1
+1
include/uapi/linux/rtnetlink.h
··· 393 393 RTA_SPORT, 394 394 RTA_DPORT, 395 395 RTA_NH_ID, 396 + RTA_FLOWLABEL, 396 397 __RTA_MAX 397 398 }; 398 399
+19 -1
net/ipv6/route.c
··· 5005 5005 [RTA_SPORT] = { .type = NLA_U16 }, 5006 5006 [RTA_DPORT] = { .type = NLA_U16 }, 5007 5007 [RTA_NH_ID] = { .type = NLA_U32 }, 5008 + [RTA_FLOWLABEL] = { .type = NLA_BE32 }, 5008 5009 }; 5009 5010 5010 5011 static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh, ··· 5028 5027 if (rtm->rtm_tos) { 5029 5028 NL_SET_ERR_MSG(extack, 5030 5029 "Invalid dsfield (tos): option not available for IPv6"); 5030 + goto errout; 5031 + } 5032 + 5033 + if (tb[RTA_FLOWLABEL]) { 5034 + NL_SET_ERR_MSG_ATTR(extack, tb[RTA_FLOWLABEL], 5035 + "Flow label cannot be specified for this operation"); 5031 5036 goto errout; 5032 5037 } 5033 5038 ··· 6020 6013 return -EINVAL; 6021 6014 } 6022 6015 6016 + if (tb[RTA_FLOWLABEL] && 6017 + (nla_get_be32(tb[RTA_FLOWLABEL]) & ~IPV6_FLOWLABEL_MASK)) { 6018 + NL_SET_ERR_MSG_ATTR(extack, tb[RTA_FLOWLABEL], 6019 + "Invalid flow label"); 6020 + return -EINVAL; 6021 + } 6022 + 6023 6023 for (i = 0; i <= RTA_MAX; i++) { 6024 6024 if (!tb[i]) 6025 6025 continue; ··· 6041 6027 case RTA_SPORT: 6042 6028 case RTA_DPORT: 6043 6029 case RTA_IP_PROTO: 6030 + case RTA_FLOWLABEL: 6044 6031 break; 6045 6032 default: 6046 6033 NL_SET_ERR_MSG_MOD(extack, "Unsupported attribute in get route request"); ··· 6064 6049 struct sk_buff *skb; 6065 6050 struct rtmsg *rtm; 6066 6051 struct flowi6 fl6 = {}; 6052 + __be32 flowlabel; 6067 6053 bool fibmatch; 6068 6054 6069 6055 err = inet6_rtm_valid_getroute_req(in_skb, nlh, tb, extack); ··· 6073 6057 6074 6058 err = -EINVAL; 6075 6059 rtm = nlmsg_data(nlh); 6076 - fl6.flowlabel = ip6_make_flowinfo(rtm->rtm_tos, 0); 6077 6060 fibmatch = !!(rtm->rtm_flags & RTM_F_FIB_MATCH); 6078 6061 6079 6062 if (tb[RTA_SRC]) { ··· 6117 6102 if (err) 6118 6103 goto errout; 6119 6104 } 6105 + 6106 + flowlabel = nla_get_be32_default(tb[RTA_FLOWLABEL], 0); 6107 + fl6.flowlabel = ip6_make_flowinfo(rtm->rtm_tos, flowlabel); 6120 6108 6121 6109 if (iif) { 6122 6110 struct net_device *dev;