48
48
#include <linux/inet.h>
49
49
#include <linux/netfilter_ipv4.h>
50
50
#include <net/inet_ecn.h>
51
+ #include <net/vrf.h>
51
52
52
53
/* NOTE. Logic of IP defragmentation is parallel to corresponding IPv6
53
54
* code now. If you change something here, _PLEASE_ update ipv6/reassembly.c
@@ -77,6 +78,7 @@ struct ipq {
77
78
u8 ecn ; /* RFC3168 support */
78
79
u16 max_df_size ; /* largest frag with DF set seen */
79
80
int iif ;
81
+ int vif ; /* VRF device index */
80
82
unsigned int rid ;
81
83
struct inet_peer * peer ;
82
84
};
@@ -99,6 +101,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
99
101
struct ip4_create_arg {
100
102
struct iphdr * iph ;
101
103
u32 user ;
104
+ int vif ;
102
105
};
103
106
104
107
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)
127
130
qp -> saddr == arg -> iph -> saddr &&
128
131
qp -> daddr == arg -> iph -> daddr &&
129
132
qp -> protocol == arg -> iph -> protocol &&
130
- qp -> user == arg -> user ;
133
+ qp -> user == arg -> user &&
134
+ qp -> vif == arg -> vif ;
131
135
}
132
136
133
137
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)
144
148
qp -> ecn = ip4_frag_ecn (arg -> iph -> tos );
145
149
qp -> saddr = arg -> iph -> saddr ;
146
150
qp -> daddr = arg -> iph -> daddr ;
151
+ qp -> vif = arg -> vif ;
147
152
qp -> user = arg -> user ;
148
153
qp -> peer = sysctl_ipfrag_max_dist ?
149
154
inet_getpeer_v4 (net -> ipv4 .peers , arg -> iph -> saddr , 1 ) : NULL ;
@@ -244,14 +249,16 @@ static void ip_expire(unsigned long arg)
244
249
/* Find the correct entry in the "incomplete datagrams" queue for
245
250
* this IP datagram, and create new one, if nothing is found.
246
251
*/
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 )
248
254
{
249
255
struct inet_frag_queue * q ;
250
256
struct ip4_create_arg arg ;
251
257
unsigned int hash ;
252
258
253
259
arg .iph = iph ;
254
260
arg .user = user ;
261
+ arg .vif = vif ;
255
262
256
263
hash = ipqhashfn (iph -> id , iph -> saddr , iph -> daddr , iph -> protocol );
257
264
@@ -648,14 +655,15 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
648
655
/* Process an incoming IP datagram fragment. */
649
656
int ip_defrag (struct sk_buff * skb , u32 user )
650
657
{
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 );
651
661
struct ipq * qp ;
652
- struct net * net ;
653
662
654
- net = skb -> dev ? dev_net (skb -> dev ) : dev_net (skb_dst (skb )-> dev );
655
663
IP_INC_STATS_BH (net , IPSTATS_MIB_REASMREQDS );
656
664
657
665
/* Lookup (or create) queue header */
658
- qp = ip_find (net , ip_hdr (skb ), user );
666
+ qp = ip_find (net , ip_hdr (skb ), user , vif );
659
667
if (qp ) {
660
668
int ret ;
661
669
0 commit comments