projects
/
openvswitch
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
dpif-netdev: Fix segfault handling packets.
[openvswitch]
/
datapath
/
flow.c
diff --git
a/datapath/flow.c
b/datapath/flow.c
index 9823b9feb31ef5fadc321d1e2e91d4b2d4a745ae..fe05df324c529af3b10f771631d074f93c09ff8f 100644
(file)
--- a/
datapath/flow.c
+++ b/
datapath/flow.c
@@
-34,6
+34,8
@@
#include <net/ipv6.h>
#include <net/ndisc.h>
#include <net/ipv6.h>
#include <net/ndisc.h>
+#include "vlan.h"
+
static struct kmem_cache *flow_cache;
static unsigned int hash_seed __read_mostly;
static struct kmem_cache *flow_cache;
static unsigned int hash_seed __read_mostly;
@@
-449,8
+451,12
@@
int flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key,
/* dl_type, dl_vlan, dl_vlan_pcp. */
__skb_pull(skb, 2 * ETH_ALEN);
/* dl_type, dl_vlan, dl_vlan_pcp. */
__skb_pull(skb, 2 * ETH_ALEN);
- if (eth->h_proto == htons(ETH_P_8021Q))
+
+ if (vlan_tx_tag_present(skb))
+ key->dl_tci = htons(vlan_get_tci(skb));
+ else if (eth->h_proto == htons(ETH_P_8021Q))
parse_vlan(skb, key);
parse_vlan(skb, key);
+
key->dl_type = parse_ethertype(skb);
skb_reset_network_header(skb);
__skb_push(skb, skb->data - (unsigned char *)eth);
key->dl_type = parse_ethertype(skb);
skb_reset_network_header(skb);
__skb_push(skb, skb->data - (unsigned char *)eth);
@@
-813,6
+819,11
@@
int flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb)
struct odp_key_ethernet *eth_key;
struct nlattr *nla;
struct odp_key_ethernet *eth_key;
struct nlattr *nla;
+ /* This is an imperfect sanity-check that FLOW_BUFSIZE doesn't need
+ * to be updated, but will at least raise awareness when new ODP key
+ * types are added. */
+ BUILD_BUG_ON(__ODP_KEY_ATTR_MAX != 14);
+
if (swkey->tun_id != cpu_to_be64(0))
NLA_PUT_BE64(skb, ODP_KEY_ATTR_TUN_ID, swkey->tun_id);
if (swkey->tun_id != cpu_to_be64(0))
NLA_PUT_BE64(skb, ODP_KEY_ATTR_TUN_ID, swkey->tun_id);
@@
-845,6
+856,7
@@
int flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb)
if (!nla)
goto nla_put_failure;
ipv4_key = nla_data(nla);
if (!nla)
goto nla_put_failure;
ipv4_key = nla_data(nla);
+ memset(ipv4_key, 0, sizeof(struct odp_key_ipv4));
ipv4_key->ipv4_src = swkey->ipv4_src;
ipv4_key->ipv4_dst = swkey->ipv4_dst;
ipv4_key->ipv4_proto = swkey->nw_proto;
ipv4_key->ipv4_src = swkey->ipv4_src;
ipv4_key->ipv4_dst = swkey->ipv4_dst;
ipv4_key->ipv4_proto = swkey->nw_proto;
@@
-856,6
+868,7
@@
int flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb)
if (!nla)
goto nla_put_failure;
ipv6_key = nla_data(nla);
if (!nla)
goto nla_put_failure;
ipv6_key = nla_data(nla);
+ memset(ipv6_key, 0, sizeof(struct odp_key_ipv6));
memcpy(ipv6_key->ipv6_src, swkey->ipv6_src,
sizeof(ipv6_key->ipv6_src));
memcpy(ipv6_key->ipv6_dst, swkey->ipv6_dst,
memcpy(ipv6_key->ipv6_src, swkey->ipv6_src,
sizeof(ipv6_key->ipv6_src));
memcpy(ipv6_key->ipv6_dst, swkey->ipv6_dst,
@@
-869,6
+882,7
@@
int flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb)
if (!nla)
goto nla_put_failure;
arp_key = nla_data(nla);
if (!nla)
goto nla_put_failure;
arp_key = nla_data(nla);
+ memset(arp_key, 0, sizeof(struct odp_key_arp));
arp_key->arp_sip = swkey->ipv4_src;
arp_key->arp_tip = swkey->ipv4_dst;
arp_key->arp_op = htons(swkey->nw_proto);
arp_key->arp_sip = swkey->ipv4_src;
arp_key->arp_tip = swkey->ipv4_dst;
arp_key->arp_op = htons(swkey->nw_proto);