X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=datapath%2Fbrcompat.c;h=be361ece2026be3498d521c9228248b91892d760;hb=449776d81d7b03d9b5f552b402c8a619323e8aa2;hp=d945e4e6de9328b08f6befffbf3794e82fab5083;hpb=e5307f55aa89b7ade27cb4bf92223c3b9c099eef;p=openvswitch diff --git a/datapath/brcompat.c b/datapath/brcompat.c index d945e4e6..be361ece 100644 --- a/datapath/brcompat.c +++ b/datapath/brcompat.c @@ -20,7 +20,6 @@ #include "compat.h" #include "openvswitch/brcompat-netlink.h" #include "brc_procfs.h" -#include "brc_sysfs.h" #include "datapath.h" #include "dp_dev.h" @@ -261,6 +260,64 @@ brc_get_port_list(struct net_device *dev, int __user *uindices, int num) return num; } +/* + * Format up to a page worth of forwarding table entries + * userbuf -- where to copy result + * maxnum -- maximum number of entries desired + * (limited to a page for sanity) + * offset -- number of records to skip + */ +static int brc_get_fdb_entries(struct net_device *dev, void __user *userbuf, + unsigned long maxnum, unsigned long offset) +{ + struct nlattr *attrs[BRC_GENL_A_MAX + 1]; + struct sk_buff *request, *reply; + int retval; + int len; + + /* Clamp size to PAGE_SIZE, test maxnum to avoid overflow */ + if (maxnum > PAGE_SIZE/sizeof(struct __fdb_entry)) + maxnum = PAGE_SIZE/sizeof(struct __fdb_entry); + + request = brc_make_request(BRC_GENL_C_FDB_QUERY, dev->name, NULL); + if (!request) + return -ENOMEM; + NLA_PUT_U64(request, BRC_GENL_A_FDB_COUNT, maxnum); + NLA_PUT_U64(request, BRC_GENL_A_FDB_SKIP, offset); + + rtnl_unlock(); + reply = brc_send_command(request, attrs); + retval = PTR_ERR(reply); + if (IS_ERR(reply)) + goto exit; + + retval = -nla_get_u32(attrs[BRC_GENL_A_ERR_CODE]); + if (retval < 0) + goto exit_free_skb; + + retval = -EINVAL; + if (!attrs[BRC_GENL_A_FDB_DATA]) + goto exit_free_skb; + len = nla_len(attrs[BRC_GENL_A_FDB_DATA]); + if (len % sizeof(struct __fdb_entry) || + len / sizeof(struct __fdb_entry) > maxnum) + goto exit_free_skb; + + retval = len / sizeof(struct __fdb_entry); + if (copy_to_user(userbuf, nla_data(attrs[BRC_GENL_A_FDB_DATA]), len)) + retval = -EFAULT; + +exit_free_skb: + kfree_skb(reply); +exit: + rtnl_lock(); + return retval; + +nla_put_failure: + kfree_skb(request); + return -ENOMEM; +} + /* Legacy ioctl's through SIOCDEVPRIVATE. Called with rtnl_lock. */ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) @@ -281,6 +338,10 @@ old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case BRCTL_GET_PORT_LIST: return brc_get_port_list(dev, (int __user *)args[1], args[2]); + + case BRCTL_GET_FDB_ENTRIES: + return brc_get_fdb_entries(dev, (void __user *)args[1], + args[2], args[3]); } return -EOPNOTSUPP; @@ -357,9 +418,12 @@ static struct genl_ops brc_genl_ops_query_dp = { /* Attribute policy: what each attribute may contain. */ static struct nla_policy brc_genl_policy[BRC_GENL_A_MAX + 1] = { [BRC_GENL_A_ERR_CODE] = { .type = NLA_U32 }, + [BRC_GENL_A_PROC_DIR] = { .type = NLA_NUL_STRING }, [BRC_GENL_A_PROC_NAME] = { .type = NLA_NUL_STRING }, [BRC_GENL_A_PROC_DATA] = { .type = NLA_NUL_STRING }, + + [BRC_GENL_A_FDB_DATA] = { .type = NLA_UNSPEC }, }; static int @@ -458,27 +522,6 @@ error: return ERR_PTR(error); } -int brc_add_dp(struct datapath *dp) -{ - if (!try_module_get(THIS_MODULE)) - return -ENODEV; -#ifdef SUPPORT_SYSFS - brc_sysfs_add_dp(dp); -#endif - - return 0; -} - -int brc_del_dp(struct datapath *dp) -{ -#ifdef SUPPORT_SYSFS - brc_sysfs_del_dp(dp); -#endif - module_put(THIS_MODULE); - - return 0; -} - static int __init brc_init(void) { @@ -503,16 +546,6 @@ __init brc_init(void) /* Set the openvswitch_mod device ioctl handler */ dp_ioctl_hook = brc_dev_ioctl; - /* Register hooks for datapath adds and deletes */ - dp_add_dp_hook = brc_add_dp; - dp_del_dp_hook = brc_del_dp; - - /* Register hooks for interface adds and deletes */ -#ifdef SUPPORT_SYSFS - dp_add_if_hook = brc_sysfs_add_if; - dp_del_if_hook = brc_sysfs_del_if; -#endif - /* Randomize the initial sequence number. This is not a security * feature; it only helps avoid crossed wires between userspace and * the kernel when the module is unloaded and reloaded. */ @@ -553,14 +586,6 @@ error: static void brc_cleanup(void) { - /* Unregister hooks for datapath adds and deletes */ - dp_add_dp_hook = NULL; - dp_del_dp_hook = NULL; - - /* Unregister hooks for interface adds and deletes */ - dp_add_if_hook = NULL; - dp_del_if_hook = NULL; - /* Unregister ioctl hooks */ dp_ioctl_hook = NULL; brioctl_set(NULL);