1 From: Pablo Neira Ayuso <pablo@netfilter.org>
2 Date: Wed, 24 Mar 2021 02:30:38 +0100
3 Subject: [PATCH] netfilter: flowtable: add xmit path types
5 Add the xmit_type field that defines the two supported xmit paths in the
6 flowtable data plane, which are the neighbour and the xfrm xmit paths.
7 This patch prepares for new flowtable xmit path types to come.
9 Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
12 --- a/include/net/netfilter/nf_flow_table.h
13 +++ b/include/net/netfilter/nf_flow_table.h
14 @@ -89,6 +89,11 @@ enum flow_offload_tuple_dir {
16 #define FLOW_OFFLOAD_DIR_MAX IP_CT_DIR_MAX
18 +enum flow_offload_xmit_type {
19 + FLOW_OFFLOAD_XMIT_NEIGH = 0,
20 + FLOW_OFFLOAD_XMIT_XFRM,
23 struct flow_offload_tuple {
25 struct in_addr src_v4;
26 @@ -111,7 +116,8 @@ struct flow_offload_tuple {
27 /* All members above are keys for lookups, see flow_offload_hash(). */
36 @@ -157,7 +163,8 @@ static inline __s32 nf_flow_timeout_delt
38 struct nf_flow_route {
40 - struct dst_entry *dst;
41 + struct dst_entry *dst;
42 + enum flow_offload_xmit_type xmit_type;
43 } tuple[FLOW_OFFLOAD_DIR_MAX];
46 --- a/net/netfilter/nf_flow_table_core.c
47 +++ b/net/netfilter/nf_flow_table_core.c
48 @@ -95,6 +95,7 @@ static int flow_offload_fill_route(struc
51 flow_tuple->iifidx = other_dst->dev->ifindex;
52 + flow_tuple->xmit_type = route->tuple[dir].xmit_type;
53 flow_tuple->dst_cache = dst;
56 --- a/net/netfilter/nf_flow_table_ip.c
57 +++ b/net/netfilter/nf_flow_table_ip.c
58 @@ -235,8 +235,6 @@ nf_flow_offload_ip_hook(void *priv, stru
60 dir = tuplehash->tuple.dir;
61 flow = container_of(tuplehash, struct flow_offload, tuplehash[dir]);
62 - rt = (struct rtable *)flow->tuplehash[dir].tuple.dst_cache;
63 - outdev = rt->dst.dev;
65 if (unlikely(nf_flow_exceeds_mtu(skb, flow->tuplehash[dir].tuple.mtu)))
67 @@ -265,13 +263,16 @@ nf_flow_offload_ip_hook(void *priv, stru
68 if (flow_table->flags & NF_FLOWTABLE_COUNTER)
69 nf_ct_acct_update(flow->ct, tuplehash->tuple.dir, skb->len);
71 - if (unlikely(dst_xfrm(&rt->dst))) {
72 + rt = (struct rtable *)tuplehash->tuple.dst_cache;
74 + if (unlikely(tuplehash->tuple.xmit_type == FLOW_OFFLOAD_XMIT_XFRM)) {
75 memset(skb->cb, 0, sizeof(struct inet_skb_parm));
76 IPCB(skb)->iif = skb->dev->ifindex;
77 IPCB(skb)->flags = IPSKB_FORWARDED;
78 return nf_flow_xmit_xfrm(skb, state, &rt->dst);
81 + outdev = rt->dst.dev;
83 nexthop = rt_nexthop(rt, flow->tuplehash[!dir].tuple.src_v4.s_addr);
84 skb_dst_set_noref(skb, &rt->dst);
85 @@ -456,8 +457,6 @@ nf_flow_offload_ipv6_hook(void *priv, st
87 dir = tuplehash->tuple.dir;
88 flow = container_of(tuplehash, struct flow_offload, tuplehash[dir]);
89 - rt = (struct rt6_info *)flow->tuplehash[dir].tuple.dst_cache;
90 - outdev = rt->dst.dev;
92 if (unlikely(nf_flow_exceeds_mtu(skb, flow->tuplehash[dir].tuple.mtu)))
94 @@ -485,13 +484,16 @@ nf_flow_offload_ipv6_hook(void *priv, st
95 if (flow_table->flags & NF_FLOWTABLE_COUNTER)
96 nf_ct_acct_update(flow->ct, tuplehash->tuple.dir, skb->len);
98 - if (unlikely(dst_xfrm(&rt->dst))) {
99 + rt = (struct rt6_info *)tuplehash->tuple.dst_cache;
101 + if (unlikely(tuplehash->tuple.xmit_type == FLOW_OFFLOAD_XMIT_XFRM)) {
102 memset(skb->cb, 0, sizeof(struct inet6_skb_parm));
103 IP6CB(skb)->iif = skb->dev->ifindex;
104 IP6CB(skb)->flags = IP6SKB_FORWARDED;
105 return nf_flow_xmit_xfrm(skb, state, &rt->dst);
108 + outdev = rt->dst.dev;
110 nexthop = rt6_nexthop(rt, &flow->tuplehash[!dir].tuple.src_v6);
111 skb_dst_set_noref(skb, &rt->dst);
112 --- a/net/netfilter/nft_flow_offload.c
113 +++ b/net/netfilter/nft_flow_offload.c
114 @@ -19,6 +19,22 @@ struct nft_flow_offload {
115 struct nft_flowtable *flowtable;
118 +static enum flow_offload_xmit_type nft_xmit_type(struct dst_entry *dst)
121 + return FLOW_OFFLOAD_XMIT_XFRM;
123 + return FLOW_OFFLOAD_XMIT_NEIGH;
126 +static void nft_default_forward_path(struct nf_flow_route *route,
127 + struct dst_entry *dst_cache,
128 + enum ip_conntrack_dir dir)
130 + route->tuple[dir].dst = dst_cache;
131 + route->tuple[dir].xmit_type = nft_xmit_type(dst_cache);
134 static int nft_flow_route(const struct nft_pktinfo *pkt,
135 const struct nf_conn *ct,
136 struct nf_flow_route *route,
137 @@ -44,8 +60,8 @@ static int nft_flow_route(const struct n
141 - route->tuple[dir].dst = this_dst;
142 - route->tuple[!dir].dst = other_dst;
143 + nft_default_forward_path(route, this_dst, dir);
144 + nft_default_forward_path(route, other_dst, !dir);