X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=datapath%2Fbrcompat.c;h=f23db93cefd417529a2cb73804ad2ed24b6c0678;hb=e22d4953ec00df611fff0fd36ac81087c63e1d1e;hp=b68720bd811f3e031aab7237faeb83cd59bcc06b;hpb=fceb2a5bb2063023777fc75c68a2670b5169fa13;p=openvswitch diff --git a/datapath/brcompat.c b/datapath/brcompat.c index b68720bd..f23db93c 100644 --- a/datapath/brcompat.c +++ b/datapath/brcompat.c @@ -6,6 +6,8 @@ * kernel, by Linus Torvalds and others. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -82,6 +84,9 @@ static int brc_add_del_bridge(char __user *uname, int add) struct sk_buff *request; char name[IFNAMSIZ]; + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + if (copy_from_user(name, uname, IFNAMSIZ)) return -EFAULT; @@ -194,6 +199,9 @@ static int brc_add_del_port(struct net_device *dev, int port_ifindex, int add) struct net_device *port; int err; + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + port = __dev_get_by_index(&init_net, port_ifindex); if (!port) return -EINVAL; @@ -216,14 +224,13 @@ static int brc_get_bridge_info(struct net_device *dev, struct __bridge_info __user *ub) { struct __bridge_info b; - u64 id = 0; - int i; memset(&b, 0, sizeof(struct __bridge_info)); - for (i=0; idev_addr[i] << (8*(ETH_ALEN-1 - i)); - b.bridge_id = cpu_to_be64(id); + /* First two bytes are the priority, which we should skip. This comes + * from struct bridge_id in br_private.h, which is unavailable to us. + */ + memcpy((u8 *)&b.bridge_id + 2, dev->dev_addr, ETH_ALEN); b.stp_enabled = 0; if (copy_to_user(ub, &b, sizeof(struct __bridge_info))) @@ -252,7 +259,7 @@ static int brc_get_port_list(struct net_device *dev, int __user *uindices, * (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, +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]; @@ -370,7 +377,7 @@ static int brc_genl_query(struct sk_buff *skb, struct genl_info *info) void *data; ans_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); - if (!ans_skb) + if (!ans_skb) return -ENOMEM; data = genlmsg_put_reply(ans_skb, info, &brc_genl_family, @@ -425,8 +432,7 @@ static int brc_genl_dp_result(struct sk_buff *skb, struct genl_info *info) if (brc_seq == info->snd_seq) { brc_seq++; - if (brc_reply) - kfree_skb(brc_reply); + kfree_skb(brc_reply); brc_reply = skb; complete(&brc_done); @@ -482,7 +488,7 @@ static struct sk_buff *brc_send_command(struct sk_buff *request, /* Wait for reply. */ error = -ETIMEDOUT; if (!wait_for_completion_timeout(&brc_done, BRC_TIMEOUT)) { - printk(KERN_WARNING "brcompat: timed out waiting for userspace\n"); + pr_warn("timed out waiting for userspace\n"); goto error; } @@ -531,15 +537,15 @@ static int __init brc_init(void) goto error; err = genl_register_ops(&brc_genl_family, &brc_genl_ops_query_dp); - if (err != 0) + if (err != 0) goto err_unregister; err = genl_register_ops(&brc_genl_family, &brc_genl_ops_dp_result); - if (err != 0) + if (err != 0) goto err_unregister; err = genl_register_ops(&brc_genl_family, &brc_genl_ops_set_proc); - if (err != 0) + if (err != 0) goto err_unregister; strcpy(brc_mc_group.name, "brcompat"); @@ -552,7 +558,7 @@ static int __init brc_init(void) err_unregister: genl_unregister_family(&brc_genl_family); error: - printk(KERN_EMERG "brcompat: failed to install!"); + pr_emerg("failed to install!\n"); return err; }