X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=datapath%2Fdatapath.c;h=eec998ca4c48d58d7bdc16686cf1114f52a0e180;hb=6d7568dc38fb832b7e152c184b0bdfdca6bb9527;hp=4f74795e8c05ff4b6f21923a18cbbeaff3e72281;hpb=968f7c8d772e704ff96bd2923d474c7f969c7c6b;p=openvswitch diff --git a/datapath/datapath.c b/datapath/datapath.c index 4f74795e..eec998ca 100644 --- a/datapath/datapath.c +++ b/datapath/datapath.c @@ -428,8 +428,7 @@ got_port_no: if (err) goto out_unlock_dp; - if (!(port.flags & ODP_PORT_INTERNAL)) - set_internal_devs_mtu(dp); + set_internal_devs_mtu(dp); dp_sysfs_add_if(dp->ports[port_no]); err = __put_user(port_no, &portp->port); @@ -523,7 +522,6 @@ void dp_process_received_packet(struct dp_port *p, struct sk_buff *skb) skb_warn_if_lro(skb); OVS_CB(skb)->dp_port = p; - compute_ip_summed(skb, false); /* BHs are off so we don't have to use get_cpu()/put_cpu() here. */ stats = percpu_ptr(dp->stats_percpu, smp_processor_id()); @@ -551,22 +549,9 @@ void dp_process_received_packet(struct dp_port *p, struct sk_buff *skb) } #if defined(CONFIG_XEN) && defined(HAVE_PROTO_DATA_VALID) -/* This code is based on a skb_checksum_setup from net/dev/core.c from a - * combination of Lenny's 2.6.26 Xen kernel and Xen's - * linux-2.6.18-92.1.10.el5.xs5.0.0.394.644. We can't call this function - * directly because it isn't exported in all versions. */ -static int skb_pull_up_to(struct sk_buff *skb, void *ptr) -{ - if (ptr < (void *)skb->tail) - return 1; - if (__pskb_pull_tail(skb, - ptr - (void *)skb->data - skb_headlen(skb))) { - return 1; - } else { - return 0; - } -} - +/* This code is based on skb_checksum_setup() from Xen's net/dev/core.c. We + * can't call this function directly because it isn't exported in all + * versions. */ int vswitch_skb_checksum_setup(struct sk_buff *skb) { struct iphdr *iph; @@ -580,7 +565,7 @@ int vswitch_skb_checksum_setup(struct sk_buff *skb) if (skb->protocol != htons(ETH_P_IP)) goto out; - if (!skb_pull_up_to(skb, skb_network_header(skb) + sizeof(struct iphdr))) + if (!pskb_may_pull(skb, skb_network_header(skb) + sizeof(struct iphdr) - skb->data)) goto out; iph = ip_hdr(skb); @@ -602,7 +587,7 @@ int vswitch_skb_checksum_setup(struct sk_buff *skb) goto out; } - if (!skb_pull_up_to(skb, th + csum_offset + 2)) + if (!pskb_may_pull(skb, th + csum_offset + 2 - skb->data)) goto out; skb->ip_summed = CHECKSUM_PARTIAL; @@ -639,8 +624,7 @@ out: * be computed if it is sent off box. Unfortunately on earlier kernels, * this case is impossible to distinguish from #2, despite having opposite * meanings. Xen adds an extra field on earlier kernels (see #4) in order - * to distinguish the different states. The only real user of this type - * with bridging is Xen (on later kernels). + * to distinguish the different states. * 4. CHECKSUM_UNNECESSARY (with proto_csum_blank true): This packet was * generated locally by a Xen DomU and has a partial checksum. If it is * handled on this machine (Dom0 or DomU), then the checksum will not be @@ -664,12 +648,7 @@ out: * packet is processed by the local IP stack, in which case it will need to * be reverified). If we receive a packet with CHECKSUM_HW that really means * CHECKSUM_PARTIAL, it will be sent with the wrong checksum. However, there - * shouldn't be any devices that do this with bridging. - * - * The bridge has similar behavior and this function closely resembles - * skb_forward_csum(). It is slightly different because we are only concerned - * with bridging and not other types of forwarding and can get away with - * slightly more optimal behavior.*/ + * shouldn't be any devices that do this with bridging. */ void compute_ip_summed(struct sk_buff *skb, bool xmit) { @@ -684,14 +663,14 @@ compute_ip_summed(struct sk_buff *skb, bool xmit) break; #ifdef CHECKSUM_HW /* In theory this could be either CHECKSUM_PARTIAL or CHECKSUM_COMPLETE. - * However, we should only get CHECKSUM_PARTIAL packets from Xen, which - * uses some special fields to represent this (see below). Since we - * can only make one type work, pick the one that actually happens in - * practice. + * However, on the receive side we should only get CHECKSUM_PARTIAL + * packets from Xen, which uses some special fields to represent this + * (see below). Since we can only make one type work, pick the one + * that actually happens in practice. * - * The one exception to this is if we are on the transmit path - * (basically after skb_checksum_setup() has been run) the type has - * already been converted, so we should stay with that. */ + * On the transmit side (basically after skb_checksum_setup() + * has been run or on internal dev transmit), packets with + * CHECKSUM_COMPLETE aren't generated, so assume CHECKSUM_PARTIAL. */ case CHECKSUM_HW: if (!xmit) OVS_CB(skb)->ip_summed = OVS_CSUM_COMPLETE; @@ -724,6 +703,10 @@ compute_ip_summed(struct sk_buff *skb, bool xmit) #endif } +/* This function closely resembles skb_forward_csum() used by the bridge. It + * is slightly different because we are only concerned with bridging and not + * other types of forwarding and can get away with slightly more optimal + * behavior.*/ void forward_ip_summed(struct sk_buff *skb) { @@ -755,9 +738,7 @@ queue_control_packets(struct sk_buff *skb, struct sk_buff_head *queue, skb->next = NULL; /* If a checksum-deferred packet is forwarded to the - * controller, correct the pointers and checksum. This happens - * on a regular basis only on Xen, on which VMs can pass up - * packets that do not have their checksum computed. + * controller, correct the pointers and checksum. */ err = vswitch_skb_checksum_setup(skb); if (err) @@ -1162,7 +1143,8 @@ error: static int query_flows(struct datapath *dp, const struct odp_flowvec *flowvec) { struct tbl *table = rcu_dereference(dp->table); - int i; + u32 i; + for (i = 0; i < flowvec->n_flows; i++) { struct __user odp_flow *ufp = &flowvec->flows[i]; struct odp_flow uf; @@ -1186,8 +1168,8 @@ static int query_flows(struct datapath *dp, const struct odp_flowvec *flowvec) struct list_flows_cbdata { struct odp_flow __user *uflows; - int n_flows; - int listed_flows; + u32 n_flows; + u32 listed_flows; }; static int list_flow(struct tbl_node *node, void *cbdata_) @@ -1371,7 +1353,7 @@ int dp_min_mtu(const struct datapath *dp) } /* Sets the MTU of all datapath devices to the minimum of the ports. Must - * be called with RTNL lock and dp_mutex. */ + * be called with RTNL lock. */ void set_internal_devs_mtu(const struct datapath *dp) { struct dp_port *p;