aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/ipmr.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/ipmr.c')
-rw-r--r--net/ipv4/ipmr.c418
1 files changed, 215 insertions, 203 deletions
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 601e3df69258..0ebae413ae87 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -62,6 +62,7 @@
62#include <linux/netfilter_ipv4.h> 62#include <linux/netfilter_ipv4.h>
63#include <net/ipip.h> 63#include <net/ipip.h>
64#include <net/checksum.h> 64#include <net/checksum.h>
65#include <net/netlink.h>
65 66
66#if defined(CONFIG_IP_PIMSM_V1) || defined(CONFIG_IP_PIMSM_V2) 67#if defined(CONFIG_IP_PIMSM_V1) || defined(CONFIG_IP_PIMSM_V2)
67#define CONFIG_IP_PIMSM 1 68#define CONFIG_IP_PIMSM 1
@@ -302,8 +303,8 @@ static void ipmr_destroy_unres(struct mfc_cache *c)
302 303
303 atomic_dec(&cache_resolve_queue_len); 304 atomic_dec(&cache_resolve_queue_len);
304 305
305 while((skb=skb_dequeue(&c->mfc_un.unres.unresolved))) { 306 while ((skb=skb_dequeue(&c->mfc_un.unres.unresolved))) {
306 if (skb->nh.iph->version == 0) { 307 if (ip_hdr(skb)->version == 0) {
307 struct nlmsghdr *nlh = (struct nlmsghdr *)skb_pull(skb, sizeof(struct iphdr)); 308 struct nlmsghdr *nlh = (struct nlmsghdr *)skb_pull(skb, sizeof(struct iphdr));
308 nlh->nlmsg_type = NLMSG_ERROR; 309 nlh->nlmsg_type = NLMSG_ERROR;
309 nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr)); 310 nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr));
@@ -479,7 +480,7 @@ static struct mfc_cache *ipmr_cache_find(__be32 origin, __be32 mcastgrp)
479static struct mfc_cache *ipmr_cache_alloc(void) 480static struct mfc_cache *ipmr_cache_alloc(void)
480{ 481{
481 struct mfc_cache *c=kmem_cache_zalloc(mrt_cachep, GFP_KERNEL); 482 struct mfc_cache *c=kmem_cache_zalloc(mrt_cachep, GFP_KERNEL);
482 if(c==NULL) 483 if (c==NULL)
483 return NULL; 484 return NULL;
484 c->mfc_un.res.minvif = MAXVIFS; 485 c->mfc_un.res.minvif = MAXVIFS;
485 return c; 486 return c;
@@ -488,7 +489,7 @@ static struct mfc_cache *ipmr_cache_alloc(void)
488static struct mfc_cache *ipmr_cache_alloc_unres(void) 489static struct mfc_cache *ipmr_cache_alloc_unres(void)
489{ 490{
490 struct mfc_cache *c=kmem_cache_zalloc(mrt_cachep, GFP_ATOMIC); 491 struct mfc_cache *c=kmem_cache_zalloc(mrt_cachep, GFP_ATOMIC);
491 if(c==NULL) 492 if (c==NULL)
492 return NULL; 493 return NULL;
493 skb_queue_head_init(&c->mfc_un.unres.unresolved); 494 skb_queue_head_init(&c->mfc_un.unres.unresolved);
494 c->mfc_un.unres.expires = jiffies + 10*HZ; 495 c->mfc_un.unres.expires = jiffies + 10*HZ;
@@ -508,12 +509,13 @@ static void ipmr_cache_resolve(struct mfc_cache *uc, struct mfc_cache *c)
508 * Play the pending entries through our router 509 * Play the pending entries through our router
509 */ 510 */
510 511
511 while((skb=__skb_dequeue(&uc->mfc_un.unres.unresolved))) { 512 while ((skb=__skb_dequeue(&uc->mfc_un.unres.unresolved))) {
512 if (skb->nh.iph->version == 0) { 513 if (ip_hdr(skb)->version == 0) {
513 struct nlmsghdr *nlh = (struct nlmsghdr *)skb_pull(skb, sizeof(struct iphdr)); 514 struct nlmsghdr *nlh = (struct nlmsghdr *)skb_pull(skb, sizeof(struct iphdr));
514 515
515 if (ipmr_fill_mroute(skb, c, NLMSG_DATA(nlh)) > 0) { 516 if (ipmr_fill_mroute(skb, c, NLMSG_DATA(nlh)) > 0) {
516 nlh->nlmsg_len = skb->tail - (u8*)nlh; 517 nlh->nlmsg_len = (skb_tail_pointer(skb) -
518 (u8 *)nlh);
517 } else { 519 } else {
518 nlh->nlmsg_type = NLMSG_ERROR; 520 nlh->nlmsg_type = NLMSG_ERROR;
519 nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr)); 521 nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr));
@@ -539,7 +541,7 @@ static void ipmr_cache_resolve(struct mfc_cache *uc, struct mfc_cache *c)
539static int ipmr_cache_report(struct sk_buff *pkt, vifi_t vifi, int assert) 541static int ipmr_cache_report(struct sk_buff *pkt, vifi_t vifi, int assert)
540{ 542{
541 struct sk_buff *skb; 543 struct sk_buff *skb;
542 int ihl = pkt->nh.iph->ihl<<2; 544 const int ihl = ip_hdrlen(pkt);
543 struct igmphdr *igmp; 545 struct igmphdr *igmp;
544 struct igmpmsg *msg; 546 struct igmpmsg *msg;
545 int ret; 547 int ret;
@@ -551,7 +553,7 @@ static int ipmr_cache_report(struct sk_buff *pkt, vifi_t vifi, int assert)
551#endif 553#endif
552 skb = alloc_skb(128, GFP_ATOMIC); 554 skb = alloc_skb(128, GFP_ATOMIC);
553 555
554 if(!skb) 556 if (!skb)
555 return -ENOBUFS; 557 return -ENOBUFS;
556 558
557#ifdef CONFIG_IP_PIMSM 559#ifdef CONFIG_IP_PIMSM
@@ -561,14 +563,17 @@ static int ipmr_cache_report(struct sk_buff *pkt, vifi_t vifi, int assert)
561 And all this only to mangle msg->im_msgtype and 563 And all this only to mangle msg->im_msgtype and
562 to set msg->im_mbz to "mbz" :-) 564 to set msg->im_mbz to "mbz" :-)
563 */ 565 */
564 msg = (struct igmpmsg*)skb_push(skb, sizeof(struct iphdr)); 566 skb_push(skb, sizeof(struct iphdr));
565 skb->nh.raw = skb->h.raw = (u8*)msg; 567 skb_reset_network_header(skb);
566 memcpy(msg, pkt->nh.raw, sizeof(struct iphdr)); 568 skb_reset_transport_header(skb);
569 msg = (struct igmpmsg *)skb_network_header(skb);
570 memcpy(msg, skb_network_header(pkt), sizeof(struct iphdr));
567 msg->im_msgtype = IGMPMSG_WHOLEPKT; 571 msg->im_msgtype = IGMPMSG_WHOLEPKT;
568 msg->im_mbz = 0; 572 msg->im_mbz = 0;
569 msg->im_vif = reg_vif_num; 573 msg->im_vif = reg_vif_num;
570 skb->nh.iph->ihl = sizeof(struct iphdr) >> 2; 574 ip_hdr(skb)->ihl = sizeof(struct iphdr) >> 2;
571 skb->nh.iph->tot_len = htons(ntohs(pkt->nh.iph->tot_len) + sizeof(struct iphdr)); 575 ip_hdr(skb)->tot_len = htons(ntohs(ip_hdr(pkt)->tot_len) +
576 sizeof(struct iphdr));
572 } else 577 } else
573#endif 578#endif
574 { 579 {
@@ -577,10 +582,11 @@ static int ipmr_cache_report(struct sk_buff *pkt, vifi_t vifi, int assert)
577 * Copy the IP header 582 * Copy the IP header
578 */ 583 */
579 584
580 skb->nh.iph = (struct iphdr *)skb_put(skb, ihl); 585 skb->network_header = skb->tail;
581 memcpy(skb->data,pkt->data,ihl); 586 skb_put(skb, ihl);
582 skb->nh.iph->protocol = 0; /* Flag to the kernel this is a route add */ 587 skb_copy_to_linear_data(skb, pkt->data, ihl);
583 msg = (struct igmpmsg*)skb->nh.iph; 588 ip_hdr(skb)->protocol = 0; /* Flag to the kernel this is a route add */
589 msg = (struct igmpmsg *)skb_network_header(skb);
584 msg->im_vif = vifi; 590 msg->im_vif = vifi;
585 skb->dst = dst_clone(pkt->dst); 591 skb->dst = dst_clone(pkt->dst);
586 592
@@ -592,8 +598,8 @@ static int ipmr_cache_report(struct sk_buff *pkt, vifi_t vifi, int assert)
592 igmp->type = 598 igmp->type =
593 msg->im_msgtype = assert; 599 msg->im_msgtype = assert;
594 igmp->code = 0; 600 igmp->code = 0;
595 skb->nh.iph->tot_len=htons(skb->len); /* Fix the length */ 601 ip_hdr(skb)->tot_len = htons(skb->len); /* Fix the length */
596 skb->h.raw = skb->nh.raw; 602 skb->transport_header = skb->network_header;
597 } 603 }
598 604
599 if (mroute_socket == NULL) { 605 if (mroute_socket == NULL) {
@@ -622,11 +628,12 @@ ipmr_cache_unresolved(vifi_t vifi, struct sk_buff *skb)
622{ 628{
623 int err; 629 int err;
624 struct mfc_cache *c; 630 struct mfc_cache *c;
631 const struct iphdr *iph = ip_hdr(skb);
625 632
626 spin_lock_bh(&mfc_unres_lock); 633 spin_lock_bh(&mfc_unres_lock);
627 for (c=mfc_unres_queue; c; c=c->next) { 634 for (c=mfc_unres_queue; c; c=c->next) {
628 if (c->mfc_mcastgrp == skb->nh.iph->daddr && 635 if (c->mfc_mcastgrp == iph->daddr &&
629 c->mfc_origin == skb->nh.iph->saddr) 636 c->mfc_origin == iph->saddr)
630 break; 637 break;
631 } 638 }
632 639
@@ -646,9 +653,9 @@ ipmr_cache_unresolved(vifi_t vifi, struct sk_buff *skb)
646 /* 653 /*
647 * Fill in the new cache entry 654 * Fill in the new cache entry
648 */ 655 */
649 c->mfc_parent=-1; 656 c->mfc_parent = -1;
650 c->mfc_origin=skb->nh.iph->saddr; 657 c->mfc_origin = iph->saddr;
651 c->mfc_mcastgrp=skb->nh.iph->daddr; 658 c->mfc_mcastgrp = iph->daddr;
652 659
653 /* 660 /*
654 * Reflect first query at mrouted. 661 * Reflect first query at mrouted.
@@ -734,7 +741,7 @@ static int ipmr_mfc_add(struct mfcctl *mfc, int mrtsock)
734 return 0; 741 return 0;
735 } 742 }
736 743
737 if(!MULTICAST(mfc->mfcc_mcastgrp.s_addr)) 744 if (!MULTICAST(mfc->mfcc_mcastgrp.s_addr))
738 return -EINVAL; 745 return -EINVAL;
739 746
740 c=ipmr_cache_alloc(); 747 c=ipmr_cache_alloc();
@@ -788,7 +795,7 @@ static void mroute_clean_tables(struct sock *sk)
788 /* 795 /*
789 * Shut down all active vif entries 796 * Shut down all active vif entries
790 */ 797 */
791 for(i=0; i<maxvif; i++) { 798 for (i=0; i<maxvif; i++) {
792 if (!(vif_table[i].flags&VIFF_STATIC)) 799 if (!(vif_table[i].flags&VIFF_STATIC))
793 vif_delete(i); 800 vif_delete(i);
794 } 801 }
@@ -858,119 +865,117 @@ int ip_mroute_setsockopt(struct sock *sk,int optname,char __user *optval,int opt
858 struct vifctl vif; 865 struct vifctl vif;
859 struct mfcctl mfc; 866 struct mfcctl mfc;
860 867
861 if(optname!=MRT_INIT) 868 if (optname != MRT_INIT) {
862 { 869 if (sk != mroute_socket && !capable(CAP_NET_ADMIN))
863 if(sk!=mroute_socket && !capable(CAP_NET_ADMIN))
864 return -EACCES; 870 return -EACCES;
865 } 871 }
866 872
867 switch(optname) 873 switch (optname) {
868 { 874 case MRT_INIT:
869 case MRT_INIT: 875 if (sk->sk_type != SOCK_RAW ||
870 if (sk->sk_type != SOCK_RAW || 876 inet_sk(sk)->num != IPPROTO_IGMP)
871 inet_sk(sk)->num != IPPROTO_IGMP) 877 return -EOPNOTSUPP;
872 return -EOPNOTSUPP; 878 if (optlen!=sizeof(int))
873 if(optlen!=sizeof(int)) 879 return -ENOPROTOOPT;
874 return -ENOPROTOOPT;
875
876 rtnl_lock();
877 if (mroute_socket) {
878 rtnl_unlock();
879 return -EADDRINUSE;
880 }
881
882 ret = ip_ra_control(sk, 1, mrtsock_destruct);
883 if (ret == 0) {
884 write_lock_bh(&mrt_lock);
885 mroute_socket=sk;
886 write_unlock_bh(&mrt_lock);
887 880
888 ipv4_devconf.mc_forwarding++; 881 rtnl_lock();
889 } 882 if (mroute_socket) {
890 rtnl_unlock(); 883 rtnl_unlock();
891 return ret; 884 return -EADDRINUSE;
892 case MRT_DONE: 885 }
893 if (sk!=mroute_socket) 886
894 return -EACCES; 887 ret = ip_ra_control(sk, 1, mrtsock_destruct);
895 return ip_ra_control(sk, 0, NULL); 888 if (ret == 0) {
896 case MRT_ADD_VIF: 889 write_lock_bh(&mrt_lock);
897 case MRT_DEL_VIF: 890 mroute_socket=sk;
898 if(optlen!=sizeof(vif)) 891 write_unlock_bh(&mrt_lock);
899 return -EINVAL; 892
900 if (copy_from_user(&vif,optval,sizeof(vif))) 893 ipv4_devconf.mc_forwarding++;
901 return -EFAULT; 894 }
902 if(vif.vifc_vifi >= MAXVIFS) 895 rtnl_unlock();
903 return -ENFILE; 896 return ret;
904 rtnl_lock(); 897 case MRT_DONE:
905 if (optname==MRT_ADD_VIF) { 898 if (sk!=mroute_socket)
906 ret = vif_add(&vif, sk==mroute_socket); 899 return -EACCES;
907 } else { 900 return ip_ra_control(sk, 0, NULL);
908 ret = vif_delete(vif.vifc_vifi); 901 case MRT_ADD_VIF:
909 } 902 case MRT_DEL_VIF:
910 rtnl_unlock(); 903 if (optlen!=sizeof(vif))
911 return ret; 904 return -EINVAL;
905 if (copy_from_user(&vif,optval,sizeof(vif)))
906 return -EFAULT;
907 if (vif.vifc_vifi >= MAXVIFS)
908 return -ENFILE;
909 rtnl_lock();
910 if (optname==MRT_ADD_VIF) {
911 ret = vif_add(&vif, sk==mroute_socket);
912 } else {
913 ret = vif_delete(vif.vifc_vifi);
914 }
915 rtnl_unlock();
916 return ret;
912 917
913 /* 918 /*
914 * Manipulate the forwarding caches. These live 919 * Manipulate the forwarding caches. These live
915 * in a sort of kernel/user symbiosis. 920 * in a sort of kernel/user symbiosis.
916 */ 921 */
917 case MRT_ADD_MFC: 922 case MRT_ADD_MFC:
918 case MRT_DEL_MFC: 923 case MRT_DEL_MFC:
919 if(optlen!=sizeof(mfc)) 924 if (optlen!=sizeof(mfc))
920 return -EINVAL; 925 return -EINVAL;
921 if (copy_from_user(&mfc,optval, sizeof(mfc))) 926 if (copy_from_user(&mfc,optval, sizeof(mfc)))
922 return -EFAULT; 927 return -EFAULT;
923 rtnl_lock(); 928 rtnl_lock();
924 if (optname==MRT_DEL_MFC) 929 if (optname==MRT_DEL_MFC)
925 ret = ipmr_mfc_delete(&mfc); 930 ret = ipmr_mfc_delete(&mfc);
926 else 931 else
927 ret = ipmr_mfc_add(&mfc, sk==mroute_socket); 932 ret = ipmr_mfc_add(&mfc, sk==mroute_socket);
928 rtnl_unlock(); 933 rtnl_unlock();
929 return ret; 934 return ret;
930 /* 935 /*
931 * Control PIM assert. 936 * Control PIM assert.
932 */ 937 */
933 case MRT_ASSERT: 938 case MRT_ASSERT:
934 { 939 {
935 int v; 940 int v;
936 if(get_user(v,(int __user *)optval)) 941 if (get_user(v,(int __user *)optval))
937 return -EFAULT; 942 return -EFAULT;
938 mroute_do_assert=(v)?1:0; 943 mroute_do_assert=(v)?1:0;
939 return 0; 944 return 0;
940 } 945 }
941#ifdef CONFIG_IP_PIMSM 946#ifdef CONFIG_IP_PIMSM
942 case MRT_PIM: 947 case MRT_PIM:
943 { 948 {
944 int v, ret; 949 int v, ret;
945 if(get_user(v,(int __user *)optval)) 950 if (get_user(v,(int __user *)optval))
946 return -EFAULT; 951 return -EFAULT;
947 v = (v)?1:0; 952 v = (v)?1:0;
948 rtnl_lock(); 953 rtnl_lock();
949 ret = 0; 954 ret = 0;
950 if (v != mroute_do_pim) { 955 if (v != mroute_do_pim) {
951 mroute_do_pim = v; 956 mroute_do_pim = v;
952 mroute_do_assert = v; 957 mroute_do_assert = v;
953#ifdef CONFIG_IP_PIMSM_V2 958#ifdef CONFIG_IP_PIMSM_V2
954 if (mroute_do_pim) 959 if (mroute_do_pim)
955 ret = inet_add_protocol(&pim_protocol, 960 ret = inet_add_protocol(&pim_protocol,
956 IPPROTO_PIM); 961 IPPROTO_PIM);
957 else 962 else
958 ret = inet_del_protocol(&pim_protocol, 963 ret = inet_del_protocol(&pim_protocol,
959 IPPROTO_PIM); 964 IPPROTO_PIM);
960 if (ret < 0) 965 if (ret < 0)
961 ret = -EAGAIN; 966 ret = -EAGAIN;
962#endif 967#endif
963 }
964 rtnl_unlock();
965 return ret;
966 } 968 }
969 rtnl_unlock();
970 return ret;
971 }
967#endif 972#endif
968 /* 973 /*
969 * Spurious command, or MRT_VERSION which you cannot 974 * Spurious command, or MRT_VERSION which you cannot
970 * set. 975 * set.
971 */ 976 */
972 default: 977 default:
973 return -ENOPROTOOPT; 978 return -ENOPROTOOPT;
974 } 979 }
975} 980}
976 981
@@ -983,7 +988,7 @@ int ip_mroute_getsockopt(struct sock *sk,int optname,char __user *optval,int __u
983 int olr; 988 int olr;
984 int val; 989 int val;
985 990
986 if(optname!=MRT_VERSION && 991 if (optname!=MRT_VERSION &&
987#ifdef CONFIG_IP_PIMSM 992#ifdef CONFIG_IP_PIMSM
988 optname!=MRT_PIM && 993 optname!=MRT_PIM &&
989#endif 994#endif
@@ -997,17 +1002,17 @@ int ip_mroute_getsockopt(struct sock *sk,int optname,char __user *optval,int __u
997 if (olr < 0) 1002 if (olr < 0)
998 return -EINVAL; 1003 return -EINVAL;
999 1004
1000 if(put_user(olr,optlen)) 1005 if (put_user(olr,optlen))
1001 return -EFAULT; 1006 return -EFAULT;
1002 if(optname==MRT_VERSION) 1007 if (optname==MRT_VERSION)
1003 val=0x0305; 1008 val=0x0305;
1004#ifdef CONFIG_IP_PIMSM 1009#ifdef CONFIG_IP_PIMSM
1005 else if(optname==MRT_PIM) 1010 else if (optname==MRT_PIM)
1006 val=mroute_do_pim; 1011 val=mroute_do_pim;
1007#endif 1012#endif
1008 else 1013 else
1009 val=mroute_do_assert; 1014 val=mroute_do_assert;
1010 if(copy_to_user(optval,&val,olr)) 1015 if (copy_to_user(optval,&val,olr))
1011 return -EFAULT; 1016 return -EFAULT;
1012 return 0; 1017 return 0;
1013} 1018}
@@ -1023,48 +1028,47 @@ int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg)
1023 struct vif_device *vif; 1028 struct vif_device *vif;
1024 struct mfc_cache *c; 1029 struct mfc_cache *c;
1025 1030
1026 switch(cmd) 1031 switch (cmd) {
1027 { 1032 case SIOCGETVIFCNT:
1028 case SIOCGETVIFCNT: 1033 if (copy_from_user(&vr,arg,sizeof(vr)))
1029 if (copy_from_user(&vr,arg,sizeof(vr))) 1034 return -EFAULT;
1030 return -EFAULT; 1035 if (vr.vifi>=maxvif)
1031 if(vr.vifi>=maxvif) 1036 return -EINVAL;
1032 return -EINVAL; 1037 read_lock(&mrt_lock);
1033 read_lock(&mrt_lock); 1038 vif=&vif_table[vr.vifi];
1034 vif=&vif_table[vr.vifi]; 1039 if (VIF_EXISTS(vr.vifi)) {
1035 if(VIF_EXISTS(vr.vifi)) { 1040 vr.icount=vif->pkt_in;
1036 vr.icount=vif->pkt_in; 1041 vr.ocount=vif->pkt_out;
1037 vr.ocount=vif->pkt_out; 1042 vr.ibytes=vif->bytes_in;
1038 vr.ibytes=vif->bytes_in; 1043 vr.obytes=vif->bytes_out;
1039 vr.obytes=vif->bytes_out;
1040 read_unlock(&mrt_lock);
1041
1042 if (copy_to_user(arg,&vr,sizeof(vr)))
1043 return -EFAULT;
1044 return 0;
1045 }
1046 read_unlock(&mrt_lock); 1044 read_unlock(&mrt_lock);
1047 return -EADDRNOTAVAIL;
1048 case SIOCGETSGCNT:
1049 if (copy_from_user(&sr,arg,sizeof(sr)))
1050 return -EFAULT;
1051 1045
1052 read_lock(&mrt_lock); 1046 if (copy_to_user(arg,&vr,sizeof(vr)))
1053 c = ipmr_cache_find(sr.src.s_addr, sr.grp.s_addr); 1047 return -EFAULT;
1054 if (c) { 1048 return 0;
1055 sr.pktcnt = c->mfc_un.res.pkt; 1049 }
1056 sr.bytecnt = c->mfc_un.res.bytes; 1050 read_unlock(&mrt_lock);
1057 sr.wrong_if = c->mfc_un.res.wrong_if; 1051 return -EADDRNOTAVAIL;
1058 read_unlock(&mrt_lock); 1052 case SIOCGETSGCNT:
1059 1053 if (copy_from_user(&sr,arg,sizeof(sr)))
1060 if (copy_to_user(arg,&sr,sizeof(sr))) 1054 return -EFAULT;
1061 return -EFAULT; 1055
1062 return 0; 1056 read_lock(&mrt_lock);
1063 } 1057 c = ipmr_cache_find(sr.src.s_addr, sr.grp.s_addr);
1058 if (c) {
1059 sr.pktcnt = c->mfc_un.res.pkt;
1060 sr.bytecnt = c->mfc_un.res.bytes;
1061 sr.wrong_if = c->mfc_un.res.wrong_if;
1064 read_unlock(&mrt_lock); 1062 read_unlock(&mrt_lock);
1065 return -EADDRNOTAVAIL; 1063
1066 default: 1064 if (copy_to_user(arg,&sr,sizeof(sr)))
1067 return -ENOIOCTLCMD; 1065 return -EFAULT;
1066 return 0;
1067 }
1068 read_unlock(&mrt_lock);
1069 return -EADDRNOTAVAIL;
1070 default:
1071 return -ENOIOCTLCMD;
1068 } 1072 }
1069} 1073}
1070 1074
@@ -1076,7 +1080,7 @@ static int ipmr_device_event(struct notifier_block *this, unsigned long event, v
1076 if (event != NETDEV_UNREGISTER) 1080 if (event != NETDEV_UNREGISTER)
1077 return NOTIFY_DONE; 1081 return NOTIFY_DONE;
1078 v=&vif_table[0]; 1082 v=&vif_table[0];
1079 for(ct=0;ct<maxvif;ct++,v++) { 1083 for (ct=0;ct<maxvif;ct++,v++) {
1080 if (v->dev==ptr) 1084 if (v->dev==ptr)
1081 vif_delete(ct); 1085 vif_delete(ct);
1082 } 1086 }
@@ -1096,11 +1100,17 @@ static struct notifier_block ip_mr_notifier={
1096 1100
1097static void ip_encap(struct sk_buff *skb, __be32 saddr, __be32 daddr) 1101static void ip_encap(struct sk_buff *skb, __be32 saddr, __be32 daddr)
1098{ 1102{
1099 struct iphdr *iph = (struct iphdr *)skb_push(skb,sizeof(struct iphdr)); 1103 struct iphdr *iph;
1104 struct iphdr *old_iph = ip_hdr(skb);
1105
1106 skb_push(skb, sizeof(struct iphdr));
1107 skb->transport_header = skb->network_header;
1108 skb_reset_network_header(skb);
1109 iph = ip_hdr(skb);
1100 1110
1101 iph->version = 4; 1111 iph->version = 4;
1102 iph->tos = skb->nh.iph->tos; 1112 iph->tos = old_iph->tos;
1103 iph->ttl = skb->nh.iph->ttl; 1113 iph->ttl = old_iph->ttl;
1104 iph->frag_off = 0; 1114 iph->frag_off = 0;
1105 iph->daddr = daddr; 1115 iph->daddr = daddr;
1106 iph->saddr = saddr; 1116 iph->saddr = saddr;
@@ -1110,8 +1120,6 @@ static void ip_encap(struct sk_buff *skb, __be32 saddr, __be32 daddr)
1110 ip_select_ident(iph, skb->dst, NULL); 1120 ip_select_ident(iph, skb->dst, NULL);
1111 ip_send_check(iph); 1121 ip_send_check(iph);
1112 1122
1113 skb->h.ipiph = skb->nh.iph;
1114 skb->nh.iph = iph;
1115 memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); 1123 memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
1116 nf_reset(skb); 1124 nf_reset(skb);
1117} 1125}
@@ -1134,7 +1142,7 @@ static inline int ipmr_forward_finish(struct sk_buff *skb)
1134 1142
1135static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, int vifi) 1143static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, int vifi)
1136{ 1144{
1137 struct iphdr *iph = skb->nh.iph; 1145 const struct iphdr *iph = ip_hdr(skb);
1138 struct vif_device *vif = &vif_table[vifi]; 1146 struct vif_device *vif = &vif_table[vifi];
1139 struct net_device *dev; 1147 struct net_device *dev;
1140 struct rtable *rt; 1148 struct rtable *rt;
@@ -1200,8 +1208,7 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, int vifi)
1200 1208
1201 dst_release(skb->dst); 1209 dst_release(skb->dst);
1202 skb->dst = &rt->u.dst; 1210 skb->dst = &rt->u.dst;
1203 iph = skb->nh.iph; 1211 ip_decrease_ttl(ip_hdr(skb));
1204 ip_decrease_ttl(iph);
1205 1212
1206 /* FIXME: forward and output firewalls used to be called here. 1213 /* FIXME: forward and output firewalls used to be called here.
1207 * What do we do with netfilter? -- RR */ 1214 * What do we do with netfilter? -- RR */
@@ -1301,7 +1308,7 @@ static int ip_mr_forward(struct sk_buff *skb, struct mfc_cache *cache, int local
1301 * Forward the frame 1308 * Forward the frame
1302 */ 1309 */
1303 for (ct = cache->mfc_un.res.maxvif-1; ct >= cache->mfc_un.res.minvif; ct--) { 1310 for (ct = cache->mfc_un.res.maxvif-1; ct >= cache->mfc_un.res.minvif; ct--) {
1304 if (skb->nh.iph->ttl > cache->mfc_un.res.ttls[ct]) { 1311 if (ip_hdr(skb)->ttl > cache->mfc_un.res.ttls[ct]) {
1305 if (psend != -1) { 1312 if (psend != -1) {
1306 struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); 1313 struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
1307 if (skb2) 1314 if (skb2)
@@ -1347,7 +1354,7 @@ int ip_mr_input(struct sk_buff *skb)
1347 if (IPCB(skb)->opt.router_alert) { 1354 if (IPCB(skb)->opt.router_alert) {
1348 if (ip_call_ra_chain(skb)) 1355 if (ip_call_ra_chain(skb))
1349 return 0; 1356 return 0;
1350 } else if (skb->nh.iph->protocol == IPPROTO_IGMP){ 1357 } else if (ip_hdr(skb)->protocol == IPPROTO_IGMP){
1351 /* IGMPv1 (and broken IGMPv2 implementations sort of 1358 /* IGMPv1 (and broken IGMPv2 implementations sort of
1352 Cisco IOS <= 11.2(8)) do not put router alert 1359 Cisco IOS <= 11.2(8)) do not put router alert
1353 option to IGMP packets destined to routable 1360 option to IGMP packets destined to routable
@@ -1366,7 +1373,7 @@ int ip_mr_input(struct sk_buff *skb)
1366 } 1373 }
1367 1374
1368 read_lock(&mrt_lock); 1375 read_lock(&mrt_lock);
1369 cache = ipmr_cache_find(skb->nh.iph->saddr, skb->nh.iph->daddr); 1376 cache = ipmr_cache_find(ip_hdr(skb)->saddr, ip_hdr(skb)->daddr);
1370 1377
1371 /* 1378 /*
1372 * No usable cache entry 1379 * No usable cache entry
@@ -1426,14 +1433,15 @@ int pim_rcv_v1(struct sk_buff * skb)
1426 if (!pskb_may_pull(skb, sizeof(*pim) + sizeof(*encap))) 1433 if (!pskb_may_pull(skb, sizeof(*pim) + sizeof(*encap)))
1427 goto drop; 1434 goto drop;
1428 1435
1429 pim = (struct igmphdr*)skb->h.raw; 1436 pim = igmp_hdr(skb);
1430 1437
1431 if (!mroute_do_pim || 1438 if (!mroute_do_pim ||
1432 skb->len < sizeof(*pim) + sizeof(*encap) || 1439 skb->len < sizeof(*pim) + sizeof(*encap) ||
1433 pim->group != PIM_V1_VERSION || pim->code != PIM_V1_REGISTER) 1440 pim->group != PIM_V1_VERSION || pim->code != PIM_V1_REGISTER)
1434 goto drop; 1441 goto drop;
1435 1442
1436 encap = (struct iphdr*)(skb->h.raw + sizeof(struct igmphdr)); 1443 encap = (struct iphdr *)(skb_transport_header(skb) +
1444 sizeof(struct igmphdr));
1437 /* 1445 /*
1438 Check that: 1446 Check that:
1439 a. packet is really destinted to a multicast group 1447 a. packet is really destinted to a multicast group
@@ -1455,9 +1463,9 @@ int pim_rcv_v1(struct sk_buff * skb)
1455 if (reg_dev == NULL) 1463 if (reg_dev == NULL)
1456 goto drop; 1464 goto drop;
1457 1465
1458 skb->mac.raw = skb->nh.raw; 1466 skb->mac_header = skb->network_header;
1459 skb_pull(skb, (u8*)encap - skb->data); 1467 skb_pull(skb, (u8*)encap - skb->data);
1460 skb->nh.iph = (struct iphdr *)skb->data; 1468 skb_reset_network_header(skb);
1461 skb->dev = reg_dev; 1469 skb->dev = reg_dev;
1462 skb->protocol = htons(ETH_P_IP); 1470 skb->protocol = htons(ETH_P_IP);
1463 skb->ip_summed = 0; 1471 skb->ip_summed = 0;
@@ -1486,7 +1494,7 @@ static int pim_rcv(struct sk_buff * skb)
1486 if (!pskb_may_pull(skb, sizeof(*pim) + sizeof(*encap))) 1494 if (!pskb_may_pull(skb, sizeof(*pim) + sizeof(*encap)))
1487 goto drop; 1495 goto drop;
1488 1496
1489 pim = (struct pimreghdr*)skb->h.raw; 1497 pim = (struct pimreghdr *)skb_transport_header(skb);
1490 if (pim->type != ((PIM_VERSION<<4)|(PIM_REGISTER)) || 1498 if (pim->type != ((PIM_VERSION<<4)|(PIM_REGISTER)) ||
1491 (pim->flags&PIM_NULL_REGISTER) || 1499 (pim->flags&PIM_NULL_REGISTER) ||
1492 (ip_compute_csum((void *)pim, sizeof(*pim)) != 0 && 1500 (ip_compute_csum((void *)pim, sizeof(*pim)) != 0 &&
@@ -1494,7 +1502,8 @@ static int pim_rcv(struct sk_buff * skb)
1494 goto drop; 1502 goto drop;
1495 1503
1496 /* check if the inner packet is destined to mcast group */ 1504 /* check if the inner packet is destined to mcast group */
1497 encap = (struct iphdr*)(skb->h.raw + sizeof(struct pimreghdr)); 1505 encap = (struct iphdr *)(skb_transport_header(skb) +
1506 sizeof(struct pimreghdr));
1498 if (!MULTICAST(encap->daddr) || 1507 if (!MULTICAST(encap->daddr) ||
1499 encap->tot_len == 0 || 1508 encap->tot_len == 0 ||
1500 ntohs(encap->tot_len) + sizeof(*pim) > skb->len) 1509 ntohs(encap->tot_len) + sizeof(*pim) > skb->len)
@@ -1510,9 +1519,9 @@ static int pim_rcv(struct sk_buff * skb)
1510 if (reg_dev == NULL) 1519 if (reg_dev == NULL)
1511 goto drop; 1520 goto drop;
1512 1521
1513 skb->mac.raw = skb->nh.raw; 1522 skb->mac_header = skb->network_header;
1514 skb_pull(skb, (u8*)encap - skb->data); 1523 skb_pull(skb, (u8*)encap - skb->data);
1515 skb->nh.iph = (struct iphdr *)skb->data; 1524 skb_reset_network_header(skb);
1516 skb->dev = reg_dev; 1525 skb->dev = reg_dev;
1517 skb->protocol = htons(ETH_P_IP); 1526 skb->protocol = htons(ETH_P_IP);
1518 skb->ip_summed = 0; 1527 skb->ip_summed = 0;
@@ -1537,7 +1546,7 @@ ipmr_fill_mroute(struct sk_buff *skb, struct mfc_cache *c, struct rtmsg *rtm)
1537 int ct; 1546 int ct;
1538 struct rtnexthop *nhp; 1547 struct rtnexthop *nhp;
1539 struct net_device *dev = vif_table[c->mfc_parent].dev; 1548 struct net_device *dev = vif_table[c->mfc_parent].dev;
1540 u8 *b = skb->tail; 1549 u8 *b = skb_tail_pointer(skb);
1541 struct rtattr *mp_head; 1550 struct rtattr *mp_head;
1542 1551
1543 if (dev) 1552 if (dev)
@@ -1557,12 +1566,12 @@ ipmr_fill_mroute(struct sk_buff *skb, struct mfc_cache *c, struct rtmsg *rtm)
1557 } 1566 }
1558 } 1567 }
1559 mp_head->rta_type = RTA_MULTIPATH; 1568 mp_head->rta_type = RTA_MULTIPATH;
1560 mp_head->rta_len = skb->tail - (u8*)mp_head; 1569 mp_head->rta_len = skb_tail_pointer(skb) - (u8 *)mp_head;
1561 rtm->rtm_type = RTN_MULTICAST; 1570 rtm->rtm_type = RTN_MULTICAST;
1562 return 1; 1571 return 1;
1563 1572
1564rtattr_failure: 1573rtattr_failure:
1565 skb_trim(skb, b - skb->data); 1574 nlmsg_trim(skb, b);
1566 return -EMSGSIZE; 1575 return -EMSGSIZE;
1567} 1576}
1568 1577
@@ -1577,6 +1586,7 @@ int ipmr_get_route(struct sk_buff *skb, struct rtmsg *rtm, int nowait)
1577 1586
1578 if (cache==NULL) { 1587 if (cache==NULL) {
1579 struct sk_buff *skb2; 1588 struct sk_buff *skb2;
1589 struct iphdr *iph;
1580 struct net_device *dev; 1590 struct net_device *dev;
1581 int vif; 1591 int vif;
1582 1592
@@ -1596,11 +1606,13 @@ int ipmr_get_route(struct sk_buff *skb, struct rtmsg *rtm, int nowait)
1596 return -ENOMEM; 1606 return -ENOMEM;
1597 } 1607 }
1598 1608
1599 skb2->nh.raw = skb_push(skb2, sizeof(struct iphdr)); 1609 skb_push(skb2, sizeof(struct iphdr));
1600 skb2->nh.iph->ihl = sizeof(struct iphdr)>>2; 1610 skb_reset_network_header(skb2);
1601 skb2->nh.iph->saddr = rt->rt_src; 1611 iph = ip_hdr(skb2);
1602 skb2->nh.iph->daddr = rt->rt_dst; 1612 iph->ihl = sizeof(struct iphdr) >> 2;
1603 skb2->nh.iph->version = 0; 1613 iph->saddr = rt->rt_src;
1614 iph->daddr = rt->rt_dst;
1615 iph->version = 0;
1604 err = ipmr_cache_unresolved(vif, skb2); 1616 err = ipmr_cache_unresolved(vif, skb2);
1605 read_unlock(&mrt_lock); 1617 read_unlock(&mrt_lock);
1606 return err; 1618 return err;
@@ -1625,7 +1637,7 @@ static struct vif_device *ipmr_vif_seq_idx(struct ipmr_vif_iter *iter,
1625 loff_t pos) 1637 loff_t pos)
1626{ 1638{
1627 for (iter->ct = 0; iter->ct < maxvif; ++iter->ct) { 1639 for (iter->ct = 0; iter->ct < maxvif; ++iter->ct) {
1628 if(!VIF_EXISTS(iter->ct)) 1640 if (!VIF_EXISTS(iter->ct))
1629 continue; 1641 continue;
1630 if (pos-- == 0) 1642 if (pos-- == 0)
1631 return &vif_table[iter->ct]; 1643 return &vif_table[iter->ct];
@@ -1649,7 +1661,7 @@ static void *ipmr_vif_seq_next(struct seq_file *seq, void *v, loff_t *pos)
1649 return ipmr_vif_seq_idx(iter, 0); 1661 return ipmr_vif_seq_idx(iter, 0);
1650 1662
1651 while (++iter->ct < maxvif) { 1663 while (++iter->ct < maxvif) {
1652 if(!VIF_EXISTS(iter->ct)) 1664 if (!VIF_EXISTS(iter->ct))
1653 continue; 1665 continue;
1654 return &vif_table[iter->ct]; 1666 return &vif_table[iter->ct];
1655 } 1667 }
@@ -1680,7 +1692,7 @@ static int ipmr_vif_seq_show(struct seq_file *seq, void *v)
1680 return 0; 1692 return 0;
1681} 1693}
1682 1694
1683static struct seq_operations ipmr_vif_seq_ops = { 1695static const struct seq_operations ipmr_vif_seq_ops = {
1684 .start = ipmr_vif_seq_start, 1696 .start = ipmr_vif_seq_start,
1685 .next = ipmr_vif_seq_next, 1697 .next = ipmr_vif_seq_next,
1686 .stop = ipmr_vif_seq_stop, 1698 .stop = ipmr_vif_seq_stop,
@@ -1732,14 +1744,14 @@ static struct mfc_cache *ipmr_mfc_seq_idx(struct ipmr_mfc_iter *it, loff_t pos)
1732 it->cache = mfc_cache_array; 1744 it->cache = mfc_cache_array;
1733 read_lock(&mrt_lock); 1745 read_lock(&mrt_lock);
1734 for (it->ct = 0; it->ct < MFC_LINES; it->ct++) 1746 for (it->ct = 0; it->ct < MFC_LINES; it->ct++)
1735 for(mfc = mfc_cache_array[it->ct]; mfc; mfc = mfc->next) 1747 for (mfc = mfc_cache_array[it->ct]; mfc; mfc = mfc->next)
1736 if (pos-- == 0) 1748 if (pos-- == 0)
1737 return mfc; 1749 return mfc;
1738 read_unlock(&mrt_lock); 1750 read_unlock(&mrt_lock);
1739 1751
1740 it->cache = &mfc_unres_queue; 1752 it->cache = &mfc_unres_queue;
1741 spin_lock_bh(&mfc_unres_lock); 1753 spin_lock_bh(&mfc_unres_lock);
1742 for(mfc = mfc_unres_queue; mfc; mfc = mfc->next) 1754 for (mfc = mfc_unres_queue; mfc; mfc = mfc->next)
1743 if (pos-- == 0) 1755 if (pos-- == 0)
1744 return mfc; 1756 return mfc;
1745 spin_unlock_bh(&mfc_unres_lock); 1757 spin_unlock_bh(&mfc_unres_lock);
@@ -1829,9 +1841,9 @@ static int ipmr_mfc_seq_show(struct seq_file *seq, void *v)
1829 mfc->mfc_un.res.wrong_if); 1841 mfc->mfc_un.res.wrong_if);
1830 1842
1831 if (it->cache != &mfc_unres_queue) { 1843 if (it->cache != &mfc_unres_queue) {
1832 for(n = mfc->mfc_un.res.minvif; 1844 for (n = mfc->mfc_un.res.minvif;
1833 n < mfc->mfc_un.res.maxvif; n++ ) { 1845 n < mfc->mfc_un.res.maxvif; n++ ) {
1834 if(VIF_EXISTS(n) 1846 if (VIF_EXISTS(n)
1835 && mfc->mfc_un.res.ttls[n] < 255) 1847 && mfc->mfc_un.res.ttls[n] < 255)
1836 seq_printf(seq, 1848 seq_printf(seq,
1837 " %2d:%-3d", 1849 " %2d:%-3d",
@@ -1843,7 +1855,7 @@ static int ipmr_mfc_seq_show(struct seq_file *seq, void *v)
1843 return 0; 1855 return 0;
1844} 1856}
1845 1857
1846static struct seq_operations ipmr_mfc_seq_ops = { 1858static const struct seq_operations ipmr_mfc_seq_ops = {
1847 .start = ipmr_mfc_seq_start, 1859 .start = ipmr_mfc_seq_start,
1848 .next = ipmr_mfc_seq_next, 1860 .next = ipmr_mfc_seq_next,
1849 .stop = ipmr_mfc_seq_stop, 1861 .stop = ipmr_mfc_seq_stop,