aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/ip6mr.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-01-31 11:32:31 -0500
committerIngo Molnar <mingo@elte.hu>2009-02-05 16:30:01 -0500
commit9d45cf9e36bf9bcf16df6e1cbf049807c8402823 (patch)
tree2118a16701418af10d215d2174df7ee0a5cbe6bd /net/ipv6/ip6mr.c
parenta146649bc19d5eba4f5bfac6720c5f252d517a71 (diff)
parent0cd5c3c80a0ebd68c08312fa7d8c13149cc61c4c (diff)
Merge branch 'x86/urgent' into x86/apic
Conflicts: arch/x86/mach-default/setup.c Semantic merge: arch/x86/kernel/irqinit_32.c Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'net/ipv6/ip6mr.c')
-rw-r--r--net/ipv6/ip6mr.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 3c51b2d827f4..228be551e9c1 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -48,6 +48,7 @@
48#include <linux/pim.h> 48#include <linux/pim.h>
49#include <net/addrconf.h> 49#include <net/addrconf.h>
50#include <linux/netfilter_ipv6.h> 50#include <linux/netfilter_ipv6.h>
51#include <net/ip6_checksum.h>
51 52
52/* Big lock, protecting vif table, mrt cache and mroute socket state. 53/* Big lock, protecting vif table, mrt cache and mroute socket state.
53 Note that the changes are semaphored via rtnl_lock. 54 Note that the changes are semaphored via rtnl_lock.
@@ -365,7 +366,9 @@ static int pim6_rcv(struct sk_buff *skb)
365 pim = (struct pimreghdr *)skb_transport_header(skb); 366 pim = (struct pimreghdr *)skb_transport_header(skb);
366 if (pim->type != ((PIM_VERSION << 4) | PIM_REGISTER) || 367 if (pim->type != ((PIM_VERSION << 4) | PIM_REGISTER) ||
367 (pim->flags & PIM_NULL_REGISTER) || 368 (pim->flags & PIM_NULL_REGISTER) ||
368 (ip_compute_csum((void *)pim, sizeof(*pim)) != 0 && 369 (csum_ipv6_magic(&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
370 sizeof(*pim), IPPROTO_PIM,
371 csum_partial((void *)pim, sizeof(*pim), 0)) &&
369 csum_fold(skb_checksum(skb, 0, skb->len, 0)))) 372 csum_fold(skb_checksum(skb, 0, skb->len, 0))))
370 goto drop; 373 goto drop;
371 374
@@ -392,7 +395,7 @@ static int pim6_rcv(struct sk_buff *skb)
392 skb_pull(skb, (u8 *)encap - skb->data); 395 skb_pull(skb, (u8 *)encap - skb->data);
393 skb_reset_network_header(skb); 396 skb_reset_network_header(skb);
394 skb->dev = reg_dev; 397 skb->dev = reg_dev;
395 skb->protocol = htons(ETH_P_IP); 398 skb->protocol = htons(ETH_P_IPV6);
396 skb->ip_summed = 0; 399 skb->ip_summed = 0;
397 skb->pkt_type = PACKET_HOST; 400 skb->pkt_type = PACKET_HOST;
398 dst_release(skb->dst); 401 dst_release(skb->dst);
@@ -481,6 +484,7 @@ static int mif6_delete(struct net *net, int vifi)
481{ 484{
482 struct mif_device *v; 485 struct mif_device *v;
483 struct net_device *dev; 486 struct net_device *dev;
487 struct inet6_dev *in6_dev;
484 if (vifi < 0 || vifi >= net->ipv6.maxvif) 488 if (vifi < 0 || vifi >= net->ipv6.maxvif)
485 return -EADDRNOTAVAIL; 489 return -EADDRNOTAVAIL;
486 490
@@ -513,6 +517,10 @@ static int mif6_delete(struct net *net, int vifi)
513 517
514 dev_set_allmulti(dev, -1); 518 dev_set_allmulti(dev, -1);
515 519
520 in6_dev = __in6_dev_get(dev);
521 if (in6_dev)
522 in6_dev->cnf.mc_forwarding--;
523
516 if (v->flags & MIFF_REGISTER) 524 if (v->flags & MIFF_REGISTER)
517 unregister_netdevice(dev); 525 unregister_netdevice(dev);
518 526
@@ -622,6 +630,7 @@ static int mif6_add(struct net *net, struct mif6ctl *vifc, int mrtsock)
622 int vifi = vifc->mif6c_mifi; 630 int vifi = vifc->mif6c_mifi;
623 struct mif_device *v = &net->ipv6.vif6_table[vifi]; 631 struct mif_device *v = &net->ipv6.vif6_table[vifi];
624 struct net_device *dev; 632 struct net_device *dev;
633 struct inet6_dev *in6_dev;
625 int err; 634 int err;
626 635
627 /* Is vif busy ? */ 636 /* Is vif busy ? */
@@ -662,6 +671,10 @@ static int mif6_add(struct net *net, struct mif6ctl *vifc, int mrtsock)
662 return -EINVAL; 671 return -EINVAL;
663 } 672 }
664 673
674 in6_dev = __in6_dev_get(dev);
675 if (in6_dev)
676 in6_dev->cnf.mc_forwarding++;
677
665 /* 678 /*
666 * Fill in the VIF structures 679 * Fill in the VIF structures
667 */ 680 */
@@ -838,8 +851,6 @@ static int ip6mr_cache_report(struct net *net, struct sk_buff *pkt, mifi_t mifi,
838 851
839 skb->dst = dst_clone(pkt->dst); 852 skb->dst = dst_clone(pkt->dst);
840 skb->ip_summed = CHECKSUM_UNNECESSARY; 853 skb->ip_summed = CHECKSUM_UNNECESSARY;
841
842 skb_pull(skb, sizeof(struct ipv6hdr));
843 } 854 }
844 855
845 if (net->ipv6.mroute6_sk == NULL) { 856 if (net->ipv6.mroute6_sk == NULL) {
@@ -1222,8 +1233,10 @@ static int ip6mr_sk_init(struct sock *sk)
1222 1233
1223 rtnl_lock(); 1234 rtnl_lock();
1224 write_lock_bh(&mrt_lock); 1235 write_lock_bh(&mrt_lock);
1225 if (likely(net->ipv6.mroute6_sk == NULL)) 1236 if (likely(net->ipv6.mroute6_sk == NULL)) {
1226 net->ipv6.mroute6_sk = sk; 1237 net->ipv6.mroute6_sk = sk;
1238 net->ipv6.devconf_all->mc_forwarding++;
1239 }
1227 else 1240 else
1228 err = -EADDRINUSE; 1241 err = -EADDRINUSE;
1229 write_unlock_bh(&mrt_lock); 1242 write_unlock_bh(&mrt_lock);
@@ -1242,6 +1255,7 @@ int ip6mr_sk_done(struct sock *sk)
1242 if (sk == net->ipv6.mroute6_sk) { 1255 if (sk == net->ipv6.mroute6_sk) {
1243 write_lock_bh(&mrt_lock); 1256 write_lock_bh(&mrt_lock);
1244 net->ipv6.mroute6_sk = NULL; 1257 net->ipv6.mroute6_sk = NULL;
1258 net->ipv6.devconf_all->mc_forwarding--;
1245 write_unlock_bh(&mrt_lock); 1259 write_unlock_bh(&mrt_lock);
1246 1260
1247 mroute_clean_tables(net); 1261 mroute_clean_tables(net);