Skip to content

Commit 9972f13

Browse files
David Aherndavem330
authored andcommitted
net: frags: Add VRF device index to cache and lookup
Fragmentation cache uses information from the IP header to reassemble packets. That information can be duplicated across VRFs -- same source and destination addresses, protocol and id. Handle fragmentation with VRFs by adding the VRF device index to entries in the cache and the lookup arg. Signed-off-by: David Ahern <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent f7ba868 commit 9972f13

File tree

1 file changed

+13
-5
lines changed

1 file changed

+13
-5
lines changed

net/ipv4/ip_fragment.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include <linux/inet.h>
4949
#include <linux/netfilter_ipv4.h>
5050
#include <net/inet_ecn.h>
51+
#include <net/vrf.h>
5152

5253
/* NOTE. Logic of IP defragmentation is parallel to corresponding IPv6
5354
* code now. If you change something here, _PLEASE_ update ipv6/reassembly.c
@@ -77,6 +78,7 @@ struct ipq {
7778
u8 ecn; /* RFC3168 support */
7879
u16 max_df_size; /* largest frag with DF set seen */
7980
int iif;
81+
int vif; /* VRF device index */
8082
unsigned int rid;
8183
struct inet_peer *peer;
8284
};
@@ -99,6 +101,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
99101
struct ip4_create_arg {
100102
struct iphdr *iph;
101103
u32 user;
104+
int vif;
102105
};
103106

104107
static unsigned int ipqhashfn(__be16 id, __be32 saddr, __be32 daddr, u8 prot)
@@ -127,7 +130,8 @@ static bool ip4_frag_match(const struct inet_frag_queue *q, const void *a)
127130
qp->saddr == arg->iph->saddr &&
128131
qp->daddr == arg->iph->daddr &&
129132
qp->protocol == arg->iph->protocol &&
130-
qp->user == arg->user;
133+
qp->user == arg->user &&
134+
qp->vif == arg->vif;
131135
}
132136

133137
static void ip4_frag_init(struct inet_frag_queue *q, const void *a)
@@ -144,6 +148,7 @@ static void ip4_frag_init(struct inet_frag_queue *q, const void *a)
144148
qp->ecn = ip4_frag_ecn(arg->iph->tos);
145149
qp->saddr = arg->iph->saddr;
146150
qp->daddr = arg->iph->daddr;
151+
qp->vif = arg->vif;
147152
qp->user = arg->user;
148153
qp->peer = sysctl_ipfrag_max_dist ?
149154
inet_getpeer_v4(net->ipv4.peers, arg->iph->saddr, 1) : NULL;
@@ -244,14 +249,16 @@ static void ip_expire(unsigned long arg)
244249
/* Find the correct entry in the "incomplete datagrams" queue for
245250
* this IP datagram, and create new one, if nothing is found.
246251
*/
247-
static struct ipq *ip_find(struct net *net, struct iphdr *iph, u32 user)
252+
static struct ipq *ip_find(struct net *net, struct iphdr *iph,
253+
u32 user, int vif)
248254
{
249255
struct inet_frag_queue *q;
250256
struct ip4_create_arg arg;
251257
unsigned int hash;
252258

253259
arg.iph = iph;
254260
arg.user = user;
261+
arg.vif = vif;
255262

256263
hash = ipqhashfn(iph->id, iph->saddr, iph->daddr, iph->protocol);
257264

@@ -648,14 +655,15 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
648655
/* Process an incoming IP datagram fragment. */
649656
int ip_defrag(struct sk_buff *skb, u32 user)
650657
{
658+
struct net_device *dev = skb->dev ? : skb_dst(skb)->dev;
659+
int vif = vrf_master_ifindex_rcu(dev);
660+
struct net *net = dev_net(dev);
651661
struct ipq *qp;
652-
struct net *net;
653662

654-
net = skb->dev ? dev_net(skb->dev) : dev_net(skb_dst(skb)->dev);
655663
IP_INC_STATS_BH(net, IPSTATS_MIB_REASMREQDS);
656664

657665
/* Lookup (or create) queue header */
658-
qp = ip_find(net, ip_hdr(skb), user);
666+
qp = ip_find(net, ip_hdr(skb), user, vif);
659667
if (qp) {
660668
int ret;
661669

0 commit comments

Comments
 (0)