X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=datapath%2Fvport.c;h=945ef448589c6aef7802dadc93cb43731ee5f11f;hb=3223e977cae4125b24ebb9498e0b67b4d8fac4c3;hp=5656672c465fa37937680809ff23fcf70785a189;hpb=44e05ecafe7c164a328a0108b8685f21569d2a37;p=openvswitch diff --git a/datapath/vport.c b/datapath/vport.c index 5656672c..945ef448 100644 --- a/datapath/vport.c +++ b/datapath/vport.c @@ -14,16 +14,20 @@ #include #include #include +#include #include "vport.h" +#include "vport-internal_dev.h" extern struct vport_ops netdev_vport_ops; extern struct vport_ops internal_vport_ops; +extern struct vport_ops patch_vport_ops; extern struct vport_ops gre_vport_ops; static struct vport_ops *base_vport_ops_list[] = { &netdev_vport_ops, &internal_vport_ops, + &patch_vport_ops, &gre_vport_ops, }; @@ -228,6 +232,24 @@ vport_add(const struct odp_vport_add __user *uvport_config) return do_vport_add(&vport_config); } +#ifdef CONFIG_COMPAT +int +compat_vport_add(struct compat_odp_vport_add *ucompat) +{ + struct compat_odp_vport_add compat; + struct odp_vport_add vport_config; + + if (copy_from_user(&compat, ucompat, sizeof(struct compat_odp_vport_add))) + return -EFAULT; + + memcpy(vport_config.port_type, compat.port_type, VPORT_TYPE_SIZE); + memcpy(vport_config.devname, compat.devname, IFNAMSIZ); + vport_config.config = compat_ptr(compat.config); + + return do_vport_add(&vport_config); +} +#endif + /** * vport_mod - modify existing vport device (for userspace callers) * @@ -273,6 +295,23 @@ vport_mod(const struct odp_vport_mod __user *uvport_config) return do_vport_mod(&vport_config); } +#ifdef CONFIG_COMPAT +int +compat_vport_mod(struct compat_odp_vport_mod *ucompat) +{ + struct compat_odp_vport_mod compat; + struct odp_vport_mod vport_config; + + if (copy_from_user(&compat, ucompat, sizeof(struct compat_odp_vport_mod))) + return -EFAULT; + + memcpy(vport_config.devname, compat.devname, IFNAMSIZ); + vport_config.config = compat_ptr(compat.config); + + return do_vport_mod(&vport_config); +} +#endif + /** * vport_del - delete existing vport device (for userspace callers) * @@ -364,9 +403,12 @@ vport_stats_get(struct odp_vport_stats_req __user *ustats_req) goto out; } - if (vport->ops->get_stats) + if (vport->ops->get_stats) { + rcu_read_lock(); err = vport->ops->get_stats(vport, &stats_req.stats); - else if (vport->ops->flags & VPORT_F_GEN_STATS) { + rcu_read_unlock(); + + } else if (vport->ops->flags & VPORT_F_GEN_STATS) { int i; memset(&stats_req.stats, 0, sizeof(struct odp_vport_stats)); @@ -439,7 +481,9 @@ vport_ether_get(struct odp_vport_ether __user *uvport_ether) goto out; } + rcu_read_lock(); memcpy(vport_ether.ether_addr, vport_get_addr(vport), ETH_ALEN); + rcu_read_unlock(); out: vport_unlock(); @@ -596,11 +640,17 @@ vport_locate(const char *name) dump_stack(); } + rcu_read_lock(); + hlist_for_each_entry(vport, node, bucket, hash_node) if (!strcmp(name, vport_get_name(vport))) - return vport; + goto out; + + vport = NULL; - return NULL; +out: + rcu_read_unlock(); + return vport; } static void @@ -835,9 +885,20 @@ vport_set_mtu(struct vport *vport, int mtu) if (mtu < 68) return -EINVAL; - if (vport->ops->set_mtu) - return vport->ops->set_mtu(vport, mtu); - else + if (vport->ops->set_mtu) { + int ret; + + ret = vport->ops->set_mtu(vport, mtu); + + if (!ret && !is_internal_vport(vport)) { + struct dp_port *dp_port = vport_get_dp_port(vport); + + if (dp_port) + set_internal_devs_mtu(dp_port->dp); + } + + return ret; + } else return -EOPNOTSUPP; } @@ -1051,10 +1112,9 @@ vport_get_mtu(const struct vport *vport) * @vport: vport that received the packet * @skb: skb that was received * - * Must be called with rcu_read_lock and bottom halves disabled. The packet - * cannot be shared and skb->data should point to the Ethernet header. The - * caller must have already called compute_ip_summed() to initialize the - * checksumming fields. + * Must be called with rcu_read_lock. The packet cannot be shared and + * skb->data should point to the Ethernet header. The caller must have already + * called compute_ip_summed() to initialize the checksumming fields. */ void vport_receive(struct vport *vport, struct sk_buff *skb) @@ -1170,25 +1230,3 @@ vport_record_error(struct vport *vport, enum vport_err_type err_type) spin_unlock_bh(&vport->err_stats.lock); } } - -/** - * vport_gen_ether_addr - generate an Ethernet address - * - * @addr: location to store generated address - * - * Generates a random Ethernet address for use when creating a device that - * has no natural address. - */ -void -vport_gen_ether_addr(u8 *addr) -{ - random_ether_addr(addr); - - /* Set the OUI to the Nicira one. */ - addr[0] = 0x00; - addr[1] = 0x23; - addr[2] = 0x20; - - /* Set the top bit to indicate random address. */ - addr[3] |= 0x80; -}