/* * VLAN IOCTL handler. * o execute requested action or pass command to the device driver * arg is really a void* to a vlan_ioctl_args structure. */ int vlan_ioctl_handler(unsigned long arg) { int err = 0; unsigned short vid = 0; struct vlan_ioctl_args args; if (copy_from_user(&args, (void*)arg, sizeof(struct vlan_ioctl_args))) return -EFAULT; /* Null terminate this sucker, just in case. */ args.device1[23] = 0; args.u.device2[23] = 0; #ifdef VLAN_DEBUG printk(VLAN_DBG "%s: args.cmd: %x\n", __FUNCTION__, args.cmd); #endif switch (args.cmd) { case SET_VLAN_INGRESS_PRIORITY_CMD: if (!capable(CAP_NET_ADMIN)) return -EPERM; err = vlan_dev_set_ingress_priority(args.device1, args.u.skb_priority, args.vlan_qos); break; case SET_VLAN_EGRESS_PRIORITY_CMD: if (!capable(CAP_NET_ADMIN)) return -EPERM; err = vlan_dev_set_egress_priority(args.device1, args.u.skb_priority, args.vlan_qos); break; case SET_VLAN_FLAG_CMD: if (!capable(CAP_NET_ADMIN)) return -EPERM; err = vlan_dev_set_vlan_flag(args.device1, args.u.flag, args.vlan_qos); break; case SET_VLAN_NAME_TYPE_CMD: if (!capable(CAP_NET_ADMIN)) return -EPERM; if ((args.u.name_type >= 0) && (args.u.name_type < VLAN_NAME_TYPE_HIGHEST)) { vlan_name_type = args.u.name_type; err = 0; } else { err = -EINVAL; } break; case ADD_VLAN_CMD: if (!capable(CAP_NET_ADMIN)) return -EPERM; /* we have been given the name of the Ethernet Device we want to * talk to: args.dev1 We also have the * VLAN ID: args.u.VID */ if (register_vlan_device(args.device1, args.u.VID)) { err = 0; } else { err = -EINVAL; } break; case DEL_VLAN_CMD: if (!capable(CAP_NET_ADMIN)) return -EPERM; /* Here, the args.dev1 is the actual VLAN we want * to get rid of. */ err = unregister_vlan_device(args.device1); break; case GET_VLAN_INGRESS_PRIORITY_CMD: /* TODO: Implement err = vlan_dev_get_ingress_priority(args); if (copy_to_user((void*)arg, &args, sizeof(struct vlan_ioctl_args))) { err = -EFAULT; } */ err = -EINVAL; break; case GET_VLAN_EGRESS_PRIORITY_CMD: /* TODO: Implement err = vlan_dev_get_egress_priority(args.device1, &(args.args); if (copy_to_user((void*)arg, &args, sizeof(struct vlan_ioctl_args))) { err = -EFAULT; } */ err = -EINVAL; break; case GET_VLAN_REALDEV_NAME_CMD: err = vlan_dev_get_realdev_name(args.device1, args.u.device2); if (copy_to_user((void*)arg, &args, sizeof(struct vlan_ioctl_args))) { err = -EFAULT; } break; case GET_VLAN_VID_CMD: err = vlan_dev_get_vid(args.device1, &vid); args.u.VID = vid; if (copy_to_user((void*)arg, &args, sizeof(struct vlan_ioctl_args))) { err = -EFAULT; } break; default: /* pass on to underlying device instead?? */ printk(VLAN_DBG "%s: Unknown VLAN CMD: %x \n", __FUNCTION__, args.cmd); return -EINVAL; }; return err; }
/* * VLAN IOCTL handler. * o execute requested action or pass command to the device driver * arg is really a void* to a vlan_ioctl_args structure. */ int vlan_ioctl_handler(unsigned long arg) { int err = 0; struct vlan_ioctl_args args; /* everything here needs root permissions, except aguably the * hack ioctls for sending packets. However, I know _I_ don't * want users running that on my network! --BLG */ if (!capable(CAP_NET_ADMIN)) return -EPERM; if (copy_from_user(&args, (void*)arg, sizeof(struct vlan_ioctl_args))) return -EFAULT; /* Null terminate this sucker, just in case. */ args.device1[23] = 0; args.u.device2[23] = 0; #ifdef VLAN_DEBUG printk(VLAN_DBG "%s: args.cmd: %x\n", __FUNCTION__, args.cmd); #endif switch (args.cmd) { #ifdef CONFIG_RG_VLAN_DSCP case RESET_ALL_VLAN_INGRESS_DSCP_CMD: { struct net_device *dev = dev_get_by_name(args.device1); if (!dev) return -EINVAL; err = vlan_dev_reset_all_ingress_dscp(dev); dev_put(dev); } break; case SET_VLAN_INGRESS_DSCP_CMD: err = vlan_dev_set_ingress_dscp(args.device1, args.u.dscp, args.vlan_qos); break; #endif case SET_VLAN_INGRESS_PRIORITY_CMD: err = vlan_dev_set_ingress_priority(args.device1, args.u.skb_priority, args.vlan_qos); break; case SET_VLAN_EGRESS_PRIORITY_CMD: err = vlan_dev_set_egress_priority(args.device1, args.u.skb_priority, args.vlan_qos); break; case SET_VLAN_FLAG_CMD: err = vlan_dev_set_vlan_flag(args.device1, args.u.flag, args.vlan_qos); break; case SET_VLAN_NAME_TYPE_CMD: if ((args.u.name_type >= 0) && (args.u.name_type < VLAN_NAME_TYPE_HIGHEST)) { vlan_name_type = args.u.name_type; err = 0; } else { err = -EINVAL; } break; /* TODO: Figure out how to pass info back... case GET_VLAN_INGRESS_PRIORITY_IOCTL: err = vlan_dev_get_ingress_priority(args); break; case GET_VLAN_EGRESS_PRIORITY_IOCTL: err = vlan_dev_get_egress_priority(args); break; */ case ADD_VLAN_CMD: /* we have been given the name of the Ethernet Device we want to * talk to: args.dev1 We also have the * VLAN ID: args.u.VID */ if (register_vlan_device(args.device1, args.u.VID)) { err = 0; } else { err = -EINVAL; } break; case DEL_VLAN_CMD: /* Here, the args.dev1 is the actual VLAN we want * to get rid of. */ err = unregister_vlan_device(args.device1); break; default: /* pass on to underlying device instead?? */ printk(VLAN_DBG "%s: Unknown VLAN CMD: %x \n", __FUNCTION__, args.cmd); return -EINVAL; }; return err; }