X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=datapath%2Fdatapath.c;h=dc2cfad584b793f3dc11aae8a3a90fd7e5fe9bdd;hb=a3a0c29e2b11d8fcae86043cd16520ecbaa03731;hp=63713d87e2d6846e960f173fb140c135f3905bd2;hpb=7a6c067d1ad65ae4abdb723b25a4ab591d1d2bc3;p=openvswitch diff --git a/datapath/datapath.c b/datapath/datapath.c index 63713d87..dc2cfad5 100644 --- a/datapath/datapath.c +++ b/datapath/datapath.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #include #include @@ -62,8 +61,8 @@ #include "vport-internal_dev.h" #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) || \ - LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0) -#error Kernels before 2.6.18 or after 3.3 are not supported by this version of Open vSwitch. + LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) +#error Kernels before 2.6.18 or after 3.4 are not supported by this version of Open vSwitch. #endif #define REHASH_FLOW_INTERVAL (10 * 60 * HZ) @@ -405,14 +404,15 @@ static int queue_gso_packets(struct net *net, int dp_ifindex, struct sk_buff *skb, const struct dp_upcall_info *upcall_info) { + unsigned short gso_type = skb_shinfo(skb)->gso_type; struct dp_upcall_info later_info; struct sw_flow_key later_key; struct sk_buff *segs, *nskb; int err; segs = skb_gso_segment(skb, NETIF_F_SG | NETIF_F_HW_CSUM); - if (IS_ERR(skb)) - return PTR_ERR(skb); + if (IS_ERR(segs)) + return PTR_ERR(segs); /* Queue all of the segments. */ skb = segs; @@ -421,7 +421,7 @@ static int queue_gso_packets(struct net *net, int dp_ifindex, if (err) break; - if (skb == segs && skb_shinfo(skb)->gso_type & SKB_GSO_UDP) { + if (skb == segs && gso_type & SKB_GSO_UDP) { /* The initial flow key extracted by ovs_flow_extract() * in this case is for a first fragment, so we need to * properly mark later fragments. @@ -558,6 +558,19 @@ static int validate_sample(const struct nlattr *attr, return validate_actions(actions, key, depth + 1); } +static int validate_tp_port(const struct sw_flow_key *flow_key) +{ + if (flow_key->eth.type == htons(ETH_P_IP)) { + if (flow_key->ipv4.tp.src && flow_key->ipv4.tp.dst) + return 0; + } else if (flow_key->eth.type == htons(ETH_P_IPV6)) { + if (flow_key->ipv6.tp.src && flow_key->ipv6.tp.dst) + return 0; + } + + return -EINVAL; +} + static int validate_set(const struct nlattr *a, const struct sw_flow_key *flow_key) { @@ -600,18 +613,13 @@ static int validate_set(const struct nlattr *a, if (flow_key->ip.proto != IPPROTO_TCP) return -EINVAL; - if (!flow_key->ipv4.tp.src || !flow_key->ipv4.tp.dst) - return -EINVAL; - - break; + return validate_tp_port(flow_key); case OVS_KEY_ATTR_UDP: if (flow_key->ip.proto != IPPROTO_UDP) return -EINVAL; - if (!flow_key->ipv4.tp.src || !flow_key->ipv4.tp.dst) - return -EINVAL; - break; + return validate_tp_port(flow_key); default: return -EINVAL;