/* Linux Kernel Hacking: net/atm/br2684.c // MC_FastPath_Enter() net/ipv4/ipmr.c // ipmr_cache_find() and mcast forward */ #include <linux/ipv6.h> #include <linux/mroute.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> #include "ip6mc_fastpath_core.h" #define MODULE_NAME "Realtek IPv6 MCast FastPath" #define PROCFS_NAME "ip6mc_FastPath" extern struct mfc6_cache *ip6mr_cache_find(struct net *net, struct in6_addr *origin, struct in6_addr *mcastgrp); extern int ip6_mr_forward(struct sk_buff *skb, struct mfc6_cache *cache); static int ip6mc_fp_on=1; static struct proc_dir_entry *FP_Proc_File; int Ip6_MC_FastPath_Enter(struct sk_buff *skb) /* Ethertype = 0x0800 (IP Packet) */ { struct mfc6_cache *cache; struct net *net = dev_net(skb->dev); if (!ip6mc_fp_on) return 0; cache = ip6mr_cache_find(net, &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr); if (cache) { return ip6_mr_forward(skb, cache); } return 0; } static int ip6_fp_proc_read(struct seq_file*s, void *v) { if(ip6mc_fp_on == 1) seq_printf(s, "ipv6 mcast fastpath ON!\n"); if(ip6mc_fp_on == 0) seq_printf(s, "ipv6 mcast fastpath OFF!\n"); return 0; } static int ip6_fp_proc_open(struct inode *inode, struct file *file) { return single_open(file, ip6_fp_proc_read, NULL); } static ssize_t ip6_fp_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *data) { char proc_buffer[count]; /* write data to the buffer */ memset(proc_buffer, 0, sizeof(proc_buffer)); if ( copy_from_user(proc_buffer, buffer, count) ) { return -EFAULT; } switch(proc_buffer[0]) { case '0': ip6mc_fp_on = 0; break; case '1': ip6mc_fp_on = 1; break; default: printk("Error setting!\n"); } return -1; } static const struct file_operations ip6_fp_proc_fops = { .open = ip6_fp_proc_open, .write = ip6_fp_proc_write, .read = seq_read, .llseek = seq_lseek, .release = single_release, }; static int __init ip6mc_fastpath_init(void) { printk("%s\n",MODULE_NAME); //create proc FP_Proc_File= proc_create_data(PROCFS_NAME, 0644, NULL, &ip6_fp_proc_fops, NULL); if (FP_Proc_File == NULL) { printk(KERN_ALERT "Error: Could not initialize /proc/%s\n", PROCFS_NAME); return -ENOMEM; } printk(KERN_INFO "/proc/%s created\n", PROCFS_NAME); return 0; } static void __exit ip6mc_fastpath_exit(void) { printk("%s removed!\n", MODULE_NAME); } module_init(ip6mc_fastpath_init); module_exit(ip6mc_fastpath_exit);