Commit 9597f197 authored by Natanael Copa's avatar Natanael Copa

main/linux-grsec: upgrade to 2.6.30.4

parent d2655ad2
From: Timo Teras <timo.teras@iki.fi>
Date: Tue, 20 Jan 2009 01:22:12 +0000 (-0800)
Subject: gre: strict physical device binding
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fdavem%2Fnet-next-2.6.git;a=commitdiff_plain;h=749c10f931923451a4c59b4435d182aa9ae27a4f;hp=57a574993d94671b495cdbe8aeb78b745abfe14f
gre: strict physical device binding
Check the device on receive path and allow otherwise identical devices
as long as the physical device differs.
This is useful for NBMA tunnels, where you want to use different gre IP
for each public IP available via different physical devices.
Signed-off-by: Timo Teras <timo.teras@iki.fi>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 0101521..4a43739 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -164,67 +164,113 @@ static DEFINE_RWLOCK(ipgre_lock);
/* Given src, dst and key, find appropriate for input tunnel. */
-static struct ip_tunnel * ipgre_tunnel_lookup(struct net *net,
+static struct ip_tunnel * ipgre_tunnel_lookup(struct net_device *dev,
__be32 remote, __be32 local,
__be32 key, __be16 gre_proto)
{
+ struct net *net = dev_net(dev);
+ int link = dev->ifindex;
unsigned h0 = HASH(remote);
unsigned h1 = HASH(key);
- struct ip_tunnel *t;
- struct ip_tunnel *t2 = NULL;
+ struct ip_tunnel *t, *sel[4] = { NULL, NULL, NULL, NULL };
struct ipgre_net *ign = net_generic(net, ipgre_net_id);
int dev_type = (gre_proto == htons(ETH_P_TEB)) ?
ARPHRD_ETHER : ARPHRD_IPGRE;
+ int idx;
for (t = ign->tunnels_r_l[h0^h1]; t; t = t->next) {
- if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr) {
- if (t->parms.i_key == key && t->dev->flags & IFF_UP) {
- if (t->dev->type == dev_type)
- return t;
- if (t->dev->type == ARPHRD_IPGRE && !t2)
- t2 = t;
- }
- }
+ if (local != t->parms.iph.saddr ||
+ remote != t->parms.iph.daddr ||
+ key != t->parms.i_key ||
+ !(t->dev->flags & IFF_UP))
+ continue;
+
+ if (t->dev->type != ARPHRD_IPGRE &&
+ t->dev->type != dev_type)
+ continue;
+
+ idx = 0;
+ if (t->parms.link != link)
+ idx |= 1;
+ if (t->dev->type != dev_type)
+ idx |= 2;
+ if (idx == 0)
+ return t;
+ if (sel[idx] == NULL)
+ sel[idx] = t;
}
for (t = ign->tunnels_r[h0^h1]; t; t = t->next) {
- if (remote == t->parms.iph.daddr) {
- if (t->parms.i_key == key && t->dev->flags & IFF_UP) {
- if (t->dev->type == dev_type)
- return t;
- if (t->dev->type == ARPHRD_IPGRE && !t2)
- t2 = t;
- }
- }
+ if (remote != t->parms.iph.daddr ||
+ key != t->parms.i_key ||
+ !(t->dev->flags & IFF_UP))
+ continue;
+
+ if (t->dev->type != ARPHRD_IPGRE &&
+ t->dev->type != dev_type)
+ continue;
+
+ idx = 0;
+ if (t->parms.link != link)
+ idx |= 1;
+ if (t->dev->type != dev_type)
+ idx |= 2;
+ if (idx == 0)
+ return t;
+ if (sel[idx] == NULL)
+ sel[idx] = t;
}
for (t = ign->tunnels_l[h1]; t; t = t->next) {
- if (local == t->parms.iph.saddr ||
- (local == t->parms.iph.daddr &&
- ipv4_is_multicast(local))) {
- if (t->parms.i_key == key && t->dev->flags & IFF_UP) {
- if (t->dev->type == dev_type)
- return t;
- if (t->dev->type == ARPHRD_IPGRE && !t2)
- t2 = t;
- }
- }
+ if ((local != t->parms.iph.saddr &&
+ (local != t->parms.iph.daddr ||
+ !ipv4_is_multicast(local))) ||
+ key != t->parms.i_key ||
+ !(t->dev->flags & IFF_UP))
+ continue;
+
+ if (t->dev->type != ARPHRD_IPGRE &&
+ t->dev->type != dev_type)
+ continue;
+
+ idx = 0;
+ if (t->parms.link != link)
+ idx |= 1;
+ if (t->dev->type != dev_type)
+ idx |= 2;
+ if (idx == 0)
+ return t;
+ if (sel[idx] == NULL)
+ sel[idx] = t;
}
for (t = ign->tunnels_wc[h1]; t; t = t->next) {
- if (t->parms.i_key == key && t->dev->flags & IFF_UP) {
- if (t->dev->type == dev_type)
- return t;
- if (t->dev->type == ARPHRD_IPGRE && !t2)
- t2 = t;
- }
+ if (t->parms.i_key != key ||
+ !(t->dev->flags & IFF_UP))
+ continue;
+
+ if (t->dev->type != ARPHRD_IPGRE &&
+ t->dev->type != dev_type)
+ continue;
+
+ idx = 0;
+ if (t->parms.link != link)
+ idx |= 1;
+ if (t->dev->type != dev_type)
+ idx |= 2;
+ if (idx == 0)
+ return t;
+ if (sel[idx] == NULL)
+ sel[idx] = t;
}
- if (t2)
- return t2;
+ for (idx = 1; idx < ARRAY_SIZE(sel); idx++)
+ if (sel[idx] != NULL)
+ return sel[idx];
- if (ign->fb_tunnel_dev->flags&IFF_UP)
+ if (ign->fb_tunnel_dev->flags & IFF_UP)
return netdev_priv(ign->fb_tunnel_dev);
+
return NULL;
}
@@ -284,6 +330,7 @@ static struct ip_tunnel *ipgre_tunnel_find(struct net *net,
__be32 remote = parms->iph.daddr;
__be32 local = parms->iph.saddr;
__be32 key = parms->i_key;
+ int link = parms->link;
struct ip_tunnel *t, **tp;
struct ipgre_net *ign = net_generic(net, ipgre_net_id);
@@ -291,6 +338,7 @@ static struct ip_tunnel *ipgre_tunnel_find(struct net *net,
if (local == t->parms.iph.saddr &&
remote == t->parms.iph.daddr &&
key == t->parms.i_key &&
+ link == t->parms.link &&
type == t->dev->type)
break;
@@ -421,7 +469,7 @@ static void ipgre_err(struct sk_buff *skb, u32 info)
}
read_lock(&ipgre_lock);
- t = ipgre_tunnel_lookup(dev_net(skb->dev), iph->daddr, iph->saddr,
+ t = ipgre_tunnel_lookup(skb->dev, iph->daddr, iph->saddr,
flags & GRE_KEY ?
*(((__be32 *)p) + (grehlen / 4) - 1) : 0,
p[1]);
@@ -518,7 +566,7 @@ static int ipgre_rcv(struct sk_buff *skb)
gre_proto = *(__be16 *)(h + 2);
read_lock(&ipgre_lock);
- if ((tunnel = ipgre_tunnel_lookup(dev_net(skb->dev),
+ if ((tunnel = ipgre_tunnel_lookup(skb->dev,
iph->saddr, iph->daddr, key,
gre_proto))) {
struct net_device_stats *stats = &tunnel->dev->stats;
From: Timo Teras <timo.teras@iki.fi>
Date: Tue, 27 Jan 2009 04:56:10 +0000 (-0800)
Subject: gre: optimize hash lookup
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fdavem%2Fnet-next-2.6.git;a=commitdiff_plain;h=afcf12422ec8236dc8b9238fef7a475876eea8da;hp=3eacdf58c2c0b9507afedfc19108e98b992c31e4
gre: optimize hash lookup
Instead of keeping candidate tunnel device from all categories,
keep only one candidate with best score. This optimizes stack
usage and speeds up exit code.
Signed-off-by: Timo Teras <timo.teras@iki.fi>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 4a43739..07a188a 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -172,11 +172,11 @@ static struct ip_tunnel * ipgre_tunnel_lookup(struct net_device *dev,
int link = dev->ifindex;
unsigned h0 = HASH(remote);
unsigned h1 = HASH(key);
- struct ip_tunnel *t, *sel[4] = { NULL, NULL, NULL, NULL };
+ struct ip_tunnel *t, *cand = NULL;
struct ipgre_net *ign = net_generic(net, ipgre_net_id);
int dev_type = (gre_proto == htons(ETH_P_TEB)) ?
ARPHRD_ETHER : ARPHRD_IPGRE;
- int idx;
+ int score, cand_score = 4;
for (t = ign->tunnels_r_l[h0^h1]; t; t = t->next) {
if (local != t->parms.iph.saddr ||
@@ -189,15 +189,18 @@ static struct ip_tunnel * ipgre_tunnel_lookup(struct net_device *dev,
t->dev->type != dev_type)
continue;
- idx = 0;
+ score = 0;
if (t->parms.link != link)
- idx |= 1;
+ score |= 1;
if (t->dev->type != dev_type)
- idx |= 2;
- if (idx == 0)
+ score |= 2;
+ if (score == 0)
return t;
- if (sel[idx] == NULL)
- sel[idx] = t;
+
+ if (score < cand_score) {
+ cand = t;
+ cand_score = score;
+ }
}
for (t = ign->tunnels_r[h0^h1]; t; t = t->next) {
@@ -210,15 +213,18 @@ static struct ip_tunnel * ipgre_tunnel_lookup(struct net_device *dev,
t->dev->type != dev_type)
continue;
- idx = 0;
+ score = 0;
if (t->parms.link != link)
- idx |= 1;
+ score |= 1;
if (t->dev->type != dev_type)
- idx |= 2;
- if (idx == 0)
+ score |= 2;
+ if (score == 0)
return t;
- if (sel[idx] == NULL)
- sel[idx] = t;
+
+ if (score < cand_score) {
+ cand = t;
+ cand_score = score;
+ }
}
for (t = ign->tunnels_l[h1]; t; t = t->next) {
@@ -233,15 +239,18 @@ static struct ip_tunnel * ipgre_tunnel_lookup(struct net_device *dev,
t->dev->type != dev_type)
continue;
- idx = 0;
+ score = 0;
if (t->parms.link != link)
- idx |= 1;
+ score |= 1;
if (t->dev->type != dev_type)
- idx |= 2;
- if (idx == 0)
+ score |= 2;
+ if (score == 0)
return t;
- if (sel[idx] == NULL)
- sel[idx] = t;
+
+ if (score < cand_score) {
+ cand = t;
+ cand_score = score;
+ }
}
for (t = ign->tunnels_wc[h1]; t; t = t->next) {
@@ -253,20 +262,22 @@ static struct ip_tunnel * ipgre_tunnel_lookup(struct net_device *dev,
t->dev->type != dev_type)
continue;
- idx = 0;
+ score = 0;
if (t->parms.link != link)
- idx |= 1;
+ score |= 1;
if (t->dev->type != dev_type)
- idx |= 2;
- if (idx == 0)
+ score |= 2;
+ if (score == 0)
return t;
- if (sel[idx] == NULL)
- sel[idx] = t;
+
+ if (score < cand_score) {
+ cand = t;
+ cand_score = score;
+ }
}
- for (idx = 1; idx < ARRAY_SIZE(sel); idx++)
- if (sel[idx] != NULL)
- return sel[idx];
+ if (cand != NULL)
+ return cand;
if (ign->fb_tunnel_dev->flags & IFF_UP)
return netdev_priv(ign->fb_tunnel_dev);
......@@ -2,9 +2,9 @@
_flavor=grsec
pkgname=linux-${_flavor}
pkgver=2.6.29.6
_kernver=2.6.29
pkgrel=2
pkgver=2.6.30.4
_kernver=2.6.30
pkgrel=1
pkgdesc="Linux kernel with grsecurity"
url=http://grsecurity.net
depends="mkinitfs"
......@@ -13,9 +13,8 @@ _config=${config:-kernelconfig}
install="$pkgname.post-install $pkgname.post-upgrade"
source="ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-$_kernver.tar.bz2
ftp://ftp.kernel.org/pub/linux/kernel/v2.6/patch-$pkgver.bz2
grsecurity-2.1.14-2.6.29.6-200907231934.patch
0001-linux-2.6.28.5-ipgre-strict-binding.patch
0002-linux-2.6.28.5-ipgre-optimize-hash-lookup.patch
grsecurity-2.1.14-2.6.30.4-200908041752.patch
linux-nbma-mroute-v4-2.6.30.diff
net-next-2.6.git-5ef12d98a19254ee5dc851bd83e214b43ec1f725.patch
$_config
$install
......@@ -31,7 +30,7 @@ _prepare() {
bunzip2 -c < ../patch-$pkgver.bz2 | patch -p1 || return 1
fi
for i in ../*.patch; do
for i in ../*.diff ../*.patch; do
msg "Applying $i..."
patch -p1 -N < $i || return 1
done
......@@ -112,12 +111,11 @@ dev() {
"$subpkgdir"/lib/modules/${_abi_release}/build
}
md5sums="64921b5ff5cdadbccfcd3820f03be7d8 linux-2.6.29.tar.bz2
0317760b52c9ac7a11de997da19a366e patch-2.6.29.6.bz2
bc067ccfe86517c4e4568b76b4a50e06 grsecurity-2.1.14-2.6.29.6-200907231934.patch
7673b4521283ad41434a18ca18b16ad8 0001-linux-2.6.28.5-ipgre-strict-binding.patch
8f405c738b150c532c46eaad5390cca2 0002-linux-2.6.28.5-ipgre-optimize-hash-lookup.patch
md5sums="7a80058a6382e5108cdb5554d1609615 linux-2.6.30.tar.bz2
d0fc44b54ba5953140b3f2aa9a1f2580 patch-2.6.30.4.bz2
7d9fd867108074ec9dcc9d2385ff1e7b grsecurity-2.1.14-2.6.30.4-200908041752.patch
7420c0b1095335990313656b114e1379 linux-nbma-mroute-v4-2.6.30.diff
ca05fd252783b82e01610e775cf56498 net-next-2.6.git-5ef12d98a19254ee5dc851bd83e214b43ec1f725.patch
c9443dcc46eb70267b4cfe6a6694f637 kernelconfig
13bdad159b0d99281c931a7dcb7d31ae kernelconfig
2834240b15805b248ef2a973b1ad4416 linux-grsec.post-install
2834240b15805b248ef2a973b1ad4416 linux-grsec.post-upgrade"
This diff is collapsed.
diff --git a/include/linux/mroute.h b/include/linux/mroute.h
index 0d45b4e..406ef6f 100644
--- a/include/linux/mroute.h
+++ b/include/linux/mroute.h
@@ -33,7 +33,7 @@
#define SIOCGETSGCNT (SIOCPROTOPRIVATE+1)
#define SIOCGETRPF (SIOCPROTOPRIVATE+2)
-#define MAXVIFS 32
+#define MAXVIFS 256
typedef unsigned long vifbitmap_t; /* User mode code depends on this lot */
typedef unsigned short vifi_t;
#define ALL_VIFS ((vifi_t)(-1))
@@ -66,6 +66,7 @@ struct vifctl {
#define VIFF_TUNNEL 0x1 /* IPIP tunnel */
#define VIFF_SRCRT 0x2 /* NI */
#define VIFF_REGISTER 0x4 /* register vif */
+#define VIFF_NBMA 0x10
/*
* Cache manipulation structures for mrouted and PIMd
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 13e9dd3..43c988b 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -105,6 +105,31 @@ static struct net_protocol pim_protocol;
static struct timer_list ipmr_expire_timer;
+static __be32 ipmr_get_skb_nbma(struct sk_buff *skb)
+{
+ union {
+ char addr[MAX_ADDR_LEN];
+ __be32 inaddr;
+ } u;
+
+ if (dev_parse_header(skb, u.addr) != 4)
+ return INADDR_ANY;
+
+ return u.inaddr;
+}
+
+static int ip_mr_match_vif_skb(struct vif_device *vif, struct sk_buff *skb)
+{
+ if (vif->dev != skb->dev)
+ return 0;
+
+ if (vif->flags & VIFF_NBMA)
+ return ipmr_get_skb_nbma(skb) == vif->remote;
+
+ return 1;
+}
+
+
/* Service routines creating virtual interfaces: DVMRP tunnels and PIMREG */
static void ipmr_del_tunnel(struct net_device *dev, struct vifctl *v)
@@ -470,6 +495,7 @@ static int vif_add(struct net *net, struct vifctl *vifc, int mrtsock)
return err;
}
break;
+ case VIFF_NBMA:
case 0:
dev = ip_dev_find(net, vifc->vifc_lcl_addr.s_addr);
if (!dev)
@@ -504,7 +530,7 @@ static int vif_add(struct net *net, struct vifctl *vifc, int mrtsock)
v->pkt_in = 0;
v->pkt_out = 0;
v->link = dev->ifindex;
- if (v->flags&(VIFF_TUNNEL|VIFF_REGISTER))
+ if (v->flags&(VIFF_TUNNEL|VIFF_REGISTER|VIFF_NBMA))
v->link = dev->iflink;
/* And finish update writing critical data */
@@ -1212,12 +1238,15 @@ static inline int ipmr_forward_finish(struct sk_buff *skb)
{
struct ip_options * opt = &(IPCB(skb)->opt);
- IP_INC_STATS_BH(dev_net(skb->dst->dev), IPSTATS_MIB_OUTFORWDATAGRAMS);
+ IP_INC_STATS_BH(dev_net(skb->dev), IPSTATS_MIB_OUTFORWDATAGRAMS);
if (unlikely(opt->optlen))
ip_forward_options(skb);
- return dst_output(skb);
+ if (skb->dst != NULL)
+ return dst_output(skb);
+ else
+ return dev_queue_xmit(skb);
}
/*
@@ -1230,7 +1259,8 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, int vifi)
const struct iphdr *iph = ip_hdr(skb);
struct vif_device *vif = &net->ipv4.vif_table[vifi];
struct net_device *dev;
- struct rtable *rt;
+ struct net_device *fromdev = skb->dev;
+ struct rtable *rt = NULL;
int encap = 0;
if (vif->dev == NULL)
@@ -1257,6 +1287,19 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, int vifi)
if (ip_route_output_key(net, &rt, &fl))
goto out_free;
encap = sizeof(struct iphdr);
+ dev = rt->u.dst.dev;
+ } else if (vif->flags&VIFF_NBMA) {
+ /* Fixme, we should take tunnel source address from the
+ * tunnel device binding if it exists */
+ struct flowi fl = { .oif = vif->link,
+ .nl_u = { .ip4_u =
+ { .daddr = vif->remote,
+ .tos = RT_TOS(iph->tos) } },
+ .proto = IPPROTO_GRE };
+ if (ip_route_output_key(&init_net, &rt, &fl))
+ goto out_free;
+ encap = LL_RESERVED_SPACE(rt->u.dst.dev);
+ dev = vif->dev;
} else {
struct flowi fl = { .oif = vif->link,
.nl_u = { .ip4_u =
@@ -1265,34 +1308,39 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, int vifi)
.proto = IPPROTO_IPIP };
if (ip_route_output_key(net, &rt, &fl))
goto out_free;
+ dev = rt->u.dst.dev;
}
- dev = rt->u.dst.dev;
+ if (!(vif->flags & VIFF_NBMA)) {
+ if (skb->len+encap > dst_mtu(&rt->u.dst) && (ntohs(iph->frag_off) & IP_DF)) {
+ /* Do not fragment multicasts. Alas, IPv4 does not
+ allow to send ICMP, so that packets will disappear
+ to blackhole.
+ */
- if (skb->len+encap > dst_mtu(&rt->u.dst) && (ntohs(iph->frag_off) & IP_DF)) {
- /* Do not fragment multicasts. Alas, IPv4 does not
- allow to send ICMP, so that packets will disappear
- to blackhole.
- */
-
- IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_FRAGFAILS);
- ip_rt_put(rt);
- goto out_free;
+ IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_FRAGFAILS);
+ goto out_free_rt;
+ }
}
encap += LL_RESERVED_SPACE(dev) + rt->u.dst.header_len;
- if (skb_cow(skb, encap)) {
- ip_rt_put(rt);
- goto out_free;
- }
+ if (skb_cow(skb, encap))
+ goto out_free_rt;
vif->pkt_out++;
vif->bytes_out += skb->len;
dst_release(skb->dst);
- skb->dst = &rt->u.dst;
+ if (vif->flags & VIFF_NBMA) {
+ ip_rt_put(rt);
+ skb->dst = NULL;
+ rt = NULL;
+ } else {
+ skb->dst = &rt->u.dst;
+ }
ip_decrease_ttl(ip_hdr(skb));
+ skb->dev = dev;
/* FIXME: forward and output firewalls used to be called here.
* What do we do with netfilter? -- RR */
@@ -1301,6 +1349,10 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, int vifi)
/* FIXME: extra output firewall step used to be here. --RR */
vif->dev->stats.tx_packets++;
vif->dev->stats.tx_bytes += skb->len;
+ } else if (vif->flags & VIFF_NBMA) {
+ if (dev_hard_header(skb, dev, ntohs(skb->protocol),
+ &vif->remote, NULL, 4) < 0)
+ goto out_free_rt;
}
IPCB(skb)->flags |= IPSKB_FORWARDED;
@@ -1316,21 +1368,30 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, int vifi)
* not mrouter) cannot join to more than one interface - it will
* result in receiving multiple packets.
*/
- NF_HOOK(PF_INET, NF_INET_FORWARD, skb, skb->dev, dev,
+ NF_HOOK(PF_INET, NF_INET_FORWARD, skb, fromdev, dev,
ipmr_forward_finish);
return;
+out_free_rt:
+ if (rt != NULL)
+ ip_rt_put(rt);
out_free:
kfree_skb(skb);
return;
}
-static int ipmr_find_vif(struct net_device *dev)
+static int ipmr_find_vif(struct net_device *dev, __be32 nbma_origin)
{
struct net *net = dev_net(dev);
int ct;
for (ct = net->ipv4.maxvif-1; ct >= 0; ct--) {
- if (net->ipv4.vif_table[ct].dev == dev)
+ if (net->ipv4.vif_table[ct].dev != dev)
+ continue;
+
+ if (net->ipv4.vif_table[ct].flags & VIFF_NBMA) {
+ if (net->ipv4.vif_table[ct].remote == nbma_origin)
+ break;
+ } else if (nbma_origin == INADDR_ANY)
break;
}
return ct;
@@ -1351,7 +1412,7 @@ static int ip_mr_forward(struct sk_buff *skb, struct mfc_cache *cache, int local
/*
* Wrong interface: drop packet and (maybe) send PIM assert.
*/
- if (net->ipv4.vif_table[vif].dev != skb->dev) {
+ if (!ip_mr_match_vif_skb(&net->ipv4.vif_table[vif], skb)) {
int true_vifi;
if (skb->rtable->fl.iif == 0) {
@@ -1370,7 +1431,7 @@ static int ip_mr_forward(struct sk_buff *skb, struct mfc_cache *cache, int local
}
cache->mfc_un.res.wrong_if++;
- true_vifi = ipmr_find_vif(skb->dev);
+ true_vifi = ipmr_find_vif(skb->dev, ipmr_get_skb_nbma(skb));
if (true_vifi >= 0 && net->ipv4.mroute_do_assert &&
/* pimsm uses asserts, when switching from RPT to SPT,
@@ -1479,7 +1540,7 @@ int ip_mr_input(struct sk_buff *skb)
skb = skb2;
}
- vif = ipmr_find_vif(skb->dev);