diff options
Diffstat (limited to 'net/ipv4/ipmr.c')
-rw-r--r-- | net/ipv4/ipmr.c | 418 |
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) | |||
479 | static struct mfc_cache *ipmr_cache_alloc(void) | 480 | static 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) | |||
488 | static struct mfc_cache *ipmr_cache_alloc_unres(void) | 489 | static 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) | |||
539 | static int ipmr_cache_report(struct sk_buff *pkt, vifi_t vifi, int assert) | 541 | static 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 | ||
1097 | static void ip_encap(struct sk_buff *skb, __be32 saddr, __be32 daddr) | 1101 | static 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 | ||
1135 | static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, int vifi) | 1143 | static 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 | ||
1564 | rtattr_failure: | 1573 | rtattr_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 | ||
1683 | static struct seq_operations ipmr_vif_seq_ops = { | 1695 | static 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 | ||
1846 | static struct seq_operations ipmr_mfc_seq_ops = { | 1858 | static 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, |