Commit 32ccf110 authored by Guillaume Nault's avatar Guillaume Nault Committed by Jakub Kicinski

ipv4: Use dscp_t in struct fib_alias

Use the new dscp_t type to replace the fa_tos field of fib_alias. This
ensures ECN bits are ignored and makes the field compatible with the
fc_dscp field of struct fib_config.

Converting old *tos variables and fields to dscp_t allows sparse to
flag incorrect uses of DSCP and ECN bits. This patch is entirely about
type annotation and shouldn't change any existing behaviour.
Signed-off-by: default avatarGuillaume Nault <gnault@redhat.com>
Acked-by: default avatarDavid Ahern <dsahern@kernel.org>
Reviewed-by: default avatarToke Høiland-Jørgensen <toke@redhat.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent f55fbb6a
...@@ -4,13 +4,14 @@ ...@@ -4,13 +4,14 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/list.h> #include <linux/list.h>
#include <net/inet_dscp.h>
#include <net/ip_fib.h> #include <net/ip_fib.h>
#include <net/nexthop.h> #include <net/nexthop.h>
struct fib_alias { struct fib_alias {
struct hlist_node fa_list; struct hlist_node fa_list;
struct fib_info *fa_info; struct fib_info *fa_info;
u8 fa_tos; dscp_t fa_dscp;
u8 fa_type; u8 fa_type;
u8 fa_state; u8 fa_state;
u8 fa_slen; u8 fa_slen;
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include <linux/hash.h> #include <linux/hash.h>
#include <net/arp.h> #include <net/arp.h>
#include <net/inet_dscp.h>
#include <net/ip.h> #include <net/ip.h>
#include <net/protocol.h> #include <net/protocol.h>
#include <net/route.h> #include <net/route.h>
...@@ -523,7 +524,7 @@ void rtmsg_fib(int event, __be32 key, struct fib_alias *fa, ...@@ -523,7 +524,7 @@ void rtmsg_fib(int event, __be32 key, struct fib_alias *fa,
fri.tb_id = tb_id; fri.tb_id = tb_id;
fri.dst = key; fri.dst = key;
fri.dst_len = dst_len; fri.dst_len = dst_len;
fri.tos = fa->fa_tos; fri.tos = inet_dscp_to_dsfield(fa->fa_dscp);
fri.type = fa->fa_type; fri.type = fa->fa_type;
fri.offload = fa->offload; fri.offload = fa->offload;
fri.trap = fa->trap; fri.trap = fa->trap;
...@@ -2039,7 +2040,7 @@ static void fib_select_default(const struct flowi4 *flp, struct fib_result *res) ...@@ -2039,7 +2040,7 @@ static void fib_select_default(const struct flowi4 *flp, struct fib_result *res)
int order = -1, last_idx = -1; int order = -1, last_idx = -1;
struct fib_alias *fa, *fa1 = NULL; struct fib_alias *fa, *fa1 = NULL;
u32 last_prio = res->fi->fib_priority; u32 last_prio = res->fi->fib_priority;
u8 last_tos = 0; dscp_t last_dscp = 0;
hlist_for_each_entry_rcu(fa, fa_head, fa_list) { hlist_for_each_entry_rcu(fa, fa_head, fa_list) {
struct fib_info *next_fi = fa->fa_info; struct fib_info *next_fi = fa->fa_info;
...@@ -2047,19 +2048,20 @@ static void fib_select_default(const struct flowi4 *flp, struct fib_result *res) ...@@ -2047,19 +2048,20 @@ static void fib_select_default(const struct flowi4 *flp, struct fib_result *res)
if (fa->fa_slen != slen) if (fa->fa_slen != slen)
continue; continue;
if (fa->fa_tos && fa->fa_tos != flp->flowi4_tos) if (fa->fa_dscp &&
fa->fa_dscp != inet_dsfield_to_dscp(flp->flowi4_tos))
continue; continue;
if (fa->tb_id != tb->tb_id) if (fa->tb_id != tb->tb_id)
continue; continue;
if (next_fi->fib_priority > last_prio && if (next_fi->fib_priority > last_prio &&
fa->fa_tos == last_tos) { fa->fa_dscp == last_dscp) {
if (last_tos) if (last_dscp)
continue; continue;
break; break;
} }
if (next_fi->fib_flags & RTNH_F_DEAD) if (next_fi->fib_flags & RTNH_F_DEAD)
continue; continue;
last_tos = fa->fa_tos; last_dscp = fa->fa_dscp;
last_prio = next_fi->fib_priority; last_prio = next_fi->fib_priority;
if (next_fi->fib_scope != res->scope || if (next_fi->fib_scope != res->scope ||
......
...@@ -82,7 +82,7 @@ static int call_fib_entry_notifier(struct notifier_block *nb, ...@@ -82,7 +82,7 @@ static int call_fib_entry_notifier(struct notifier_block *nb,
.dst = dst, .dst = dst,
.dst_len = dst_len, .dst_len = dst_len,
.fi = fa->fa_info, .fi = fa->fa_info,
.tos = fa->fa_tos, .tos = inet_dscp_to_dsfield(fa->fa_dscp),
.type = fa->fa_type, .type = fa->fa_type,
.tb_id = fa->tb_id, .tb_id = fa->tb_id,
}; };
...@@ -99,7 +99,7 @@ static int call_fib_entry_notifiers(struct net *net, ...@@ -99,7 +99,7 @@ static int call_fib_entry_notifiers(struct net *net,
.dst = dst, .dst = dst,
.dst_len = dst_len, .dst_len = dst_len,
.fi = fa->fa_info, .fi = fa->fa_info,
.tos = fa->fa_tos, .tos = inet_dscp_to_dsfield(fa->fa_dscp),
.type = fa->fa_type, .type = fa->fa_type,
.tb_id = fa->tb_id, .tb_id = fa->tb_id,
}; };
...@@ -974,13 +974,13 @@ static struct key_vector *fib_find_node(struct trie *t, ...@@ -974,13 +974,13 @@ static struct key_vector *fib_find_node(struct trie *t,
return n; return n;
} }
/* Return the first fib alias matching TOS with /* Return the first fib alias matching DSCP with
* priority less than or equal to PRIO. * priority less than or equal to PRIO.
* If 'find_first' is set, return the first matching * If 'find_first' is set, return the first matching
* fib alias, regardless of TOS and priority. * fib alias, regardless of DSCP and priority.
*/ */
static struct fib_alias *fib_find_alias(struct hlist_head *fah, u8 slen, static struct fib_alias *fib_find_alias(struct hlist_head *fah, u8 slen,
u8 tos, u32 prio, u32 tb_id, dscp_t dscp, u32 prio, u32 tb_id,
bool find_first) bool find_first)
{ {
struct fib_alias *fa; struct fib_alias *fa;
...@@ -989,6 +989,10 @@ static struct fib_alias *fib_find_alias(struct hlist_head *fah, u8 slen, ...@@ -989,6 +989,10 @@ static struct fib_alias *fib_find_alias(struct hlist_head *fah, u8 slen,
return NULL; return NULL;
hlist_for_each_entry(fa, fah, fa_list) { hlist_for_each_entry(fa, fah, fa_list) {
/* Avoid Sparse warning when using dscp_t in inequalities */
u8 __fa_dscp = inet_dscp_to_dsfield(fa->fa_dscp);
u8 __dscp = inet_dscp_to_dsfield(dscp);
if (fa->fa_slen < slen) if (fa->fa_slen < slen)
continue; continue;
if (fa->fa_slen != slen) if (fa->fa_slen != slen)
...@@ -999,9 +1003,9 @@ static struct fib_alias *fib_find_alias(struct hlist_head *fah, u8 slen, ...@@ -999,9 +1003,9 @@ static struct fib_alias *fib_find_alias(struct hlist_head *fah, u8 slen,
break; break;
if (find_first) if (find_first)
return fa; return fa;
if (fa->fa_tos > tos) if (__fa_dscp > __dscp)
continue; continue;
if (fa->fa_info->fib_priority >= prio || fa->fa_tos < tos) if (fa->fa_info->fib_priority >= prio || __fa_dscp < __dscp)
return fa; return fa;
} }
...@@ -1028,8 +1032,8 @@ fib_find_matching_alias(struct net *net, const struct fib_rt_info *fri) ...@@ -1028,8 +1032,8 @@ fib_find_matching_alias(struct net *net, const struct fib_rt_info *fri)
hlist_for_each_entry_rcu(fa, &l->leaf, fa_list) { hlist_for_each_entry_rcu(fa, &l->leaf, fa_list) {
if (fa->fa_slen == slen && fa->tb_id == fri->tb_id && if (fa->fa_slen == slen && fa->tb_id == fri->tb_id &&
fa->fa_tos == fri->tos && fa->fa_info == fri->fi && fa->fa_dscp == inet_dsfield_to_dscp(fri->tos) &&
fa->fa_type == fri->type) fa->fa_info == fri->fi && fa->fa_type == fri->type)
return fa; return fa;
} }
...@@ -1211,9 +1215,9 @@ int fib_table_insert(struct net *net, struct fib_table *tb, ...@@ -1211,9 +1215,9 @@ int fib_table_insert(struct net *net, struct fib_table *tb,
struct fib_info *fi; struct fib_info *fi;
u8 plen = cfg->fc_dst_len; u8 plen = cfg->fc_dst_len;
u8 slen = KEYLENGTH - plen; u8 slen = KEYLENGTH - plen;
dscp_t dscp;
u32 key; u32 key;
int err; int err;
u8 tos;
key = ntohl(cfg->fc_dst); key = ntohl(cfg->fc_dst);
...@@ -1228,13 +1232,13 @@ int fib_table_insert(struct net *net, struct fib_table *tb, ...@@ -1228,13 +1232,13 @@ int fib_table_insert(struct net *net, struct fib_table *tb,
goto err; goto err;
} }
tos = inet_dscp_to_dsfield(cfg->fc_dscp); dscp = cfg->fc_dscp;
l = fib_find_node(t, &tp, key); l = fib_find_node(t, &tp, key);
fa = l ? fib_find_alias(&l->leaf, slen, tos, fi->fib_priority, fa = l ? fib_find_alias(&l->leaf, slen, dscp, fi->fib_priority,
tb->tb_id, false) : NULL; tb->tb_id, false) : NULL;
/* Now fa, if non-NULL, points to the first fib alias /* Now fa, if non-NULL, points to the first fib alias
* with the same keys [prefix,tos,priority], if such key already * with the same keys [prefix,dscp,priority], if such key already
* exists or to the node before which we will insert new one. * exists or to the node before which we will insert new one.
* *
* If fa is NULL, we will need to allocate a new one and * If fa is NULL, we will need to allocate a new one and
...@@ -1242,7 +1246,7 @@ int fib_table_insert(struct net *net, struct fib_table *tb, ...@@ -1242,7 +1246,7 @@ int fib_table_insert(struct net *net, struct fib_table *tb,
* of the new alias. * of the new alias.
*/ */
if (fa && fa->fa_tos == tos && if (fa && fa->fa_dscp == dscp &&
fa->fa_info->fib_priority == fi->fib_priority) { fa->fa_info->fib_priority == fi->fib_priority) {
struct fib_alias *fa_first, *fa_match; struct fib_alias *fa_first, *fa_match;
...@@ -1262,7 +1266,7 @@ int fib_table_insert(struct net *net, struct fib_table *tb, ...@@ -1262,7 +1266,7 @@ int fib_table_insert(struct net *net, struct fib_table *tb,
hlist_for_each_entry_from(fa, fa_list) { hlist_for_each_entry_from(fa, fa_list) {
if ((fa->fa_slen != slen) || if ((fa->fa_slen != slen) ||
(fa->tb_id != tb->tb_id) || (fa->tb_id != tb->tb_id) ||
(fa->fa_tos != tos)) (fa->fa_dscp != dscp))
break; break;
if (fa->fa_info->fib_priority != fi->fib_priority) if (fa->fa_info->fib_priority != fi->fib_priority)
break; break;
...@@ -1290,7 +1294,7 @@ int fib_table_insert(struct net *net, struct fib_table *tb, ...@@ -1290,7 +1294,7 @@ int fib_table_insert(struct net *net, struct fib_table *tb,
goto out; goto out;
fi_drop = fa->fa_info; fi_drop = fa->fa_info;
new_fa->fa_tos = fa->fa_tos; new_fa->fa_dscp = fa->fa_dscp;
new_fa->fa_info = fi; new_fa->fa_info = fi;
new_fa->fa_type = cfg->fc_type; new_fa->fa_type = cfg->fc_type;
state = fa->fa_state; state = fa->fa_state;
...@@ -1353,7 +1357,7 @@ int fib_table_insert(struct net *net, struct fib_table *tb, ...@@ -1353,7 +1357,7 @@ int fib_table_insert(struct net *net, struct fib_table *tb,
goto out; goto out;
new_fa->fa_info = fi; new_fa->fa_info = fi;
new_fa->fa_tos = tos; new_fa->fa_dscp = dscp;
new_fa->fa_type = cfg->fc_type; new_fa->fa_type = cfg->fc_type;
new_fa->fa_state = 0; new_fa->fa_state = 0;
new_fa->fa_slen = slen; new_fa->fa_slen = slen;
...@@ -1569,7 +1573,8 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp, ...@@ -1569,7 +1573,8 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp,
if (index >= (1ul << fa->fa_slen)) if (index >= (1ul << fa->fa_slen))
continue; continue;
} }
if (fa->fa_tos && fa->fa_tos != flp->flowi4_tos) if (fa->fa_dscp &&
inet_dscp_to_dsfield(fa->fa_dscp) != flp->flowi4_tos)
continue; continue;
if (fi->fib_dead) if (fi->fib_dead)
continue; continue;
...@@ -1705,8 +1710,8 @@ int fib_table_delete(struct net *net, struct fib_table *tb, ...@@ -1705,8 +1710,8 @@ int fib_table_delete(struct net *net, struct fib_table *tb,
struct key_vector *l, *tp; struct key_vector *l, *tp;
u8 plen = cfg->fc_dst_len; u8 plen = cfg->fc_dst_len;
u8 slen = KEYLENGTH - plen; u8 slen = KEYLENGTH - plen;
dscp_t dscp;
u32 key; u32 key;
u8 tos;
key = ntohl(cfg->fc_dst); key = ntohl(cfg->fc_dst);
...@@ -1717,12 +1722,13 @@ int fib_table_delete(struct net *net, struct fib_table *tb, ...@@ -1717,12 +1722,13 @@ int fib_table_delete(struct net *net, struct fib_table *tb,
if (!l) if (!l)
return -ESRCH; return -ESRCH;
tos = inet_dscp_to_dsfield(cfg->fc_dscp); dscp = cfg->fc_dscp;
fa = fib_find_alias(&l->leaf, slen, tos, 0, tb->tb_id, false); fa = fib_find_alias(&l->leaf, slen, dscp, 0, tb->tb_id, false);
if (!fa) if (!fa)
return -ESRCH; return -ESRCH;
pr_debug("Deleting %08x/%d tos=%d t=%p\n", key, plen, tos, t); pr_debug("Deleting %08x/%d dsfield=0x%02x t=%p\n", key, plen,
inet_dscp_to_dsfield(dscp), t);
fa_to_delete = NULL; fa_to_delete = NULL;
hlist_for_each_entry_from(fa, fa_list) { hlist_for_each_entry_from(fa, fa_list) {
...@@ -1730,7 +1736,7 @@ int fib_table_delete(struct net *net, struct fib_table *tb, ...@@ -1730,7 +1736,7 @@ int fib_table_delete(struct net *net, struct fib_table *tb,
if ((fa->fa_slen != slen) || if ((fa->fa_slen != slen) ||
(fa->tb_id != tb->tb_id) || (fa->tb_id != tb->tb_id) ||
(fa->fa_tos != tos)) (fa->fa_dscp != dscp))
break; break;
if ((!cfg->fc_type || fa->fa_type == cfg->fc_type) && if ((!cfg->fc_type || fa->fa_type == cfg->fc_type) &&
...@@ -2298,7 +2304,7 @@ static int fn_trie_dump_leaf(struct key_vector *l, struct fib_table *tb, ...@@ -2298,7 +2304,7 @@ static int fn_trie_dump_leaf(struct key_vector *l, struct fib_table *tb,
fri.tb_id = tb->tb_id; fri.tb_id = tb->tb_id;
fri.dst = xkey; fri.dst = xkey;
fri.dst_len = KEYLENGTH - fa->fa_slen; fri.dst_len = KEYLENGTH - fa->fa_slen;
fri.tos = fa->fa_tos; fri.tos = inet_dscp_to_dsfield(fa->fa_dscp);
fri.type = fa->fa_type; fri.type = fa->fa_type;
fri.offload = fa->offload; fri.offload = fa->offload;
fri.trap = fa->trap; fri.trap = fa->trap;
...@@ -2810,8 +2816,9 @@ static int fib_trie_seq_show(struct seq_file *seq, void *v) ...@@ -2810,8 +2816,9 @@ static int fib_trie_seq_show(struct seq_file *seq, void *v)
fa->fa_info->fib_scope), fa->fa_info->fib_scope),
rtn_type(buf2, sizeof(buf2), rtn_type(buf2, sizeof(buf2),
fa->fa_type)); fa->fa_type));
if (fa->fa_tos) if (fa->fa_dscp)
seq_printf(seq, " tos=%d", fa->fa_tos); seq_printf(seq, " tos=%d",
inet_dscp_to_dsfield(fa->fa_dscp));
seq_putc(seq, '\n'); seq_putc(seq, '\n');
} }
} }
......
...@@ -84,6 +84,7 @@ ...@@ -84,6 +84,7 @@
#include <linux/jhash.h> #include <linux/jhash.h>
#include <net/dst.h> #include <net/dst.h>
#include <net/dst_metadata.h> #include <net/dst_metadata.h>
#include <net/inet_dscp.h>
#include <net/net_namespace.h> #include <net/net_namespace.h>
#include <net/ip.h> #include <net/ip.h>
#include <net/route.h> #include <net/route.h>
...@@ -3391,7 +3392,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, ...@@ -3391,7 +3392,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
if (fa->fa_slen == slen && if (fa->fa_slen == slen &&
fa->tb_id == fri.tb_id && fa->tb_id == fri.tb_id &&
fa->fa_tos == fri.tos && fa->fa_dscp == inet_dsfield_to_dscp(fri.tos) &&
fa->fa_info == res.fi && fa->fa_info == res.fi &&
fa->fa_type == fri.type) { fa->fa_type == fri.type) {
fri.offload = fa->offload; fri.offload = fa->offload;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment