diff options
author | Ingo Molnar <mingo@kernel.org> | 2013-01-24 06:47:48 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2013-01-24 06:47:48 -0500 |
commit | befddb21c845f8fb49e637997891ef97c6a869dc (patch) | |
tree | 0e7629123184f2dd50291ad6d477b894175f0f26 /net/openvswitch/flow.c | |
parent | e716efde75267eab919cdb2bef5b2cb77f305326 (diff) | |
parent | 7d1f9aeff1ee4a20b1aeb377dd0f579fe9647619 (diff) |
Merge tag 'v3.8-rc4' into irq/core
Merge Linux 3.8-rc4 before pulling in new commits - we were on an old v3.7 base.
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'net/openvswitch/flow.c')
-rw-r--r-- | net/openvswitch/flow.c | 42 |
1 files changed, 29 insertions, 13 deletions
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c index 98c70630ad06..c3294cebc4f2 100644 --- a/net/openvswitch/flow.c +++ b/net/openvswitch/flow.c | |||
@@ -604,6 +604,7 @@ int ovs_flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key, | |||
604 | 604 | ||
605 | key->phy.priority = skb->priority; | 605 | key->phy.priority = skb->priority; |
606 | key->phy.in_port = in_port; | 606 | key->phy.in_port = in_port; |
607 | key->phy.skb_mark = skb->mark; | ||
607 | 608 | ||
608 | skb_reset_mac_header(skb); | 609 | skb_reset_mac_header(skb); |
609 | 610 | ||
@@ -689,7 +690,8 @@ int ovs_flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key, | |||
689 | } | 690 | } |
690 | } | 691 | } |
691 | 692 | ||
692 | } else if (key->eth.type == htons(ETH_P_ARP) && arphdr_ok(skb)) { | 693 | } else if ((key->eth.type == htons(ETH_P_ARP) || |
694 | key->eth.type == htons(ETH_P_RARP)) && arphdr_ok(skb)) { | ||
693 | struct arp_eth_header *arp; | 695 | struct arp_eth_header *arp; |
694 | 696 | ||
695 | arp = (struct arp_eth_header *)skb_network_header(skb); | 697 | arp = (struct arp_eth_header *)skb_network_header(skb); |
@@ -702,15 +704,11 @@ int ovs_flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key, | |||
702 | /* We only match on the lower 8 bits of the opcode. */ | 704 | /* We only match on the lower 8 bits of the opcode. */ |
703 | if (ntohs(arp->ar_op) <= 0xff) | 705 | if (ntohs(arp->ar_op) <= 0xff) |
704 | key->ip.proto = ntohs(arp->ar_op); | 706 | key->ip.proto = ntohs(arp->ar_op); |
705 | 707 | memcpy(&key->ipv4.addr.src, arp->ar_sip, sizeof(key->ipv4.addr.src)); | |
706 | if (key->ip.proto == ARPOP_REQUEST | 708 | memcpy(&key->ipv4.addr.dst, arp->ar_tip, sizeof(key->ipv4.addr.dst)); |
707 | || key->ip.proto == ARPOP_REPLY) { | 709 | memcpy(key->ipv4.arp.sha, arp->ar_sha, ETH_ALEN); |
708 | memcpy(&key->ipv4.addr.src, arp->ar_sip, sizeof(key->ipv4.addr.src)); | 710 | memcpy(key->ipv4.arp.tha, arp->ar_tha, ETH_ALEN); |
709 | memcpy(&key->ipv4.addr.dst, arp->ar_tip, sizeof(key->ipv4.addr.dst)); | 711 | key_len = SW_FLOW_KEY_OFFSET(ipv4.arp); |
710 | memcpy(key->ipv4.arp.sha, arp->ar_sha, ETH_ALEN); | ||
711 | memcpy(key->ipv4.arp.tha, arp->ar_tha, ETH_ALEN); | ||
712 | key_len = SW_FLOW_KEY_OFFSET(ipv4.arp); | ||
713 | } | ||
714 | } | 712 | } |
715 | } else if (key->eth.type == htons(ETH_P_IPV6)) { | 713 | } else if (key->eth.type == htons(ETH_P_IPV6)) { |
716 | int nh_len; /* IPv6 Header + Extensions */ | 714 | int nh_len; /* IPv6 Header + Extensions */ |
@@ -806,6 +804,7 @@ const int ovs_key_lens[OVS_KEY_ATTR_MAX + 1] = { | |||
806 | [OVS_KEY_ATTR_ENCAP] = -1, | 804 | [OVS_KEY_ATTR_ENCAP] = -1, |
807 | [OVS_KEY_ATTR_PRIORITY] = sizeof(u32), | 805 | [OVS_KEY_ATTR_PRIORITY] = sizeof(u32), |
808 | [OVS_KEY_ATTR_IN_PORT] = sizeof(u32), | 806 | [OVS_KEY_ATTR_IN_PORT] = sizeof(u32), |
807 | [OVS_KEY_ATTR_SKB_MARK] = sizeof(u32), | ||
809 | [OVS_KEY_ATTR_ETHERNET] = sizeof(struct ovs_key_ethernet), | 808 | [OVS_KEY_ATTR_ETHERNET] = sizeof(struct ovs_key_ethernet), |
810 | [OVS_KEY_ATTR_VLAN] = sizeof(__be16), | 809 | [OVS_KEY_ATTR_VLAN] = sizeof(__be16), |
811 | [OVS_KEY_ATTR_ETHERTYPE] = sizeof(__be16), | 810 | [OVS_KEY_ATTR_ETHERTYPE] = sizeof(__be16), |
@@ -991,6 +990,10 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp, | |||
991 | } else { | 990 | } else { |
992 | swkey->phy.in_port = DP_MAX_PORTS; | 991 | swkey->phy.in_port = DP_MAX_PORTS; |
993 | } | 992 | } |
993 | if (attrs & (1 << OVS_KEY_ATTR_SKB_MARK)) { | ||
994 | swkey->phy.skb_mark = nla_get_u32(a[OVS_KEY_ATTR_SKB_MARK]); | ||
995 | attrs &= ~(1 << OVS_KEY_ATTR_SKB_MARK); | ||
996 | } | ||
994 | 997 | ||
995 | /* Data attributes. */ | 998 | /* Data attributes. */ |
996 | if (!(attrs & (1 << OVS_KEY_ATTR_ETHERNET))) | 999 | if (!(attrs & (1 << OVS_KEY_ATTR_ETHERNET))) |
@@ -1090,7 +1093,8 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp, | |||
1090 | if (err) | 1093 | if (err) |
1091 | return err; | 1094 | return err; |
1092 | } | 1095 | } |
1093 | } else if (swkey->eth.type == htons(ETH_P_ARP)) { | 1096 | } else if (swkey->eth.type == htons(ETH_P_ARP) || |
1097 | swkey->eth.type == htons(ETH_P_RARP)) { | ||
1094 | const struct ovs_key_arp *arp_key; | 1098 | const struct ovs_key_arp *arp_key; |
1095 | 1099 | ||
1096 | if (!(attrs & (1 << OVS_KEY_ATTR_ARP))) | 1100 | if (!(attrs & (1 << OVS_KEY_ATTR_ARP))) |
@@ -1117,6 +1121,8 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp, | |||
1117 | 1121 | ||
1118 | /** | 1122 | /** |
1119 | * ovs_flow_metadata_from_nlattrs - parses Netlink attributes into a flow key. | 1123 | * ovs_flow_metadata_from_nlattrs - parses Netlink attributes into a flow key. |
1124 | * @priority: receives the skb priority | ||
1125 | * @mark: receives the skb mark | ||
1120 | * @in_port: receives the extracted input port. | 1126 | * @in_port: receives the extracted input port. |
1121 | * @key: Netlink attribute holding nested %OVS_KEY_ATTR_* Netlink attribute | 1127 | * @key: Netlink attribute holding nested %OVS_KEY_ATTR_* Netlink attribute |
1122 | * sequence. | 1128 | * sequence. |
@@ -1126,7 +1132,7 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp, | |||
1126 | * get the metadata, that is, the parts of the flow key that cannot be | 1132 | * get the metadata, that is, the parts of the flow key that cannot be |
1127 | * extracted from the packet itself. | 1133 | * extracted from the packet itself. |
1128 | */ | 1134 | */ |
1129 | int ovs_flow_metadata_from_nlattrs(u32 *priority, u16 *in_port, | 1135 | int ovs_flow_metadata_from_nlattrs(u32 *priority, u32 *mark, u16 *in_port, |
1130 | const struct nlattr *attr) | 1136 | const struct nlattr *attr) |
1131 | { | 1137 | { |
1132 | const struct nlattr *nla; | 1138 | const struct nlattr *nla; |
@@ -1134,6 +1140,7 @@ int ovs_flow_metadata_from_nlattrs(u32 *priority, u16 *in_port, | |||
1134 | 1140 | ||
1135 | *in_port = DP_MAX_PORTS; | 1141 | *in_port = DP_MAX_PORTS; |
1136 | *priority = 0; | 1142 | *priority = 0; |
1143 | *mark = 0; | ||
1137 | 1144 | ||
1138 | nla_for_each_nested(nla, attr, rem) { | 1145 | nla_for_each_nested(nla, attr, rem) { |
1139 | int type = nla_type(nla); | 1146 | int type = nla_type(nla); |
@@ -1152,6 +1159,10 @@ int ovs_flow_metadata_from_nlattrs(u32 *priority, u16 *in_port, | |||
1152 | return -EINVAL; | 1159 | return -EINVAL; |
1153 | *in_port = nla_get_u32(nla); | 1160 | *in_port = nla_get_u32(nla); |
1154 | break; | 1161 | break; |
1162 | |||
1163 | case OVS_KEY_ATTR_SKB_MARK: | ||
1164 | *mark = nla_get_u32(nla); | ||
1165 | break; | ||
1155 | } | 1166 | } |
1156 | } | 1167 | } |
1157 | } | 1168 | } |
@@ -1173,6 +1184,10 @@ int ovs_flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb) | |||
1173 | nla_put_u32(skb, OVS_KEY_ATTR_IN_PORT, swkey->phy.in_port)) | 1184 | nla_put_u32(skb, OVS_KEY_ATTR_IN_PORT, swkey->phy.in_port)) |
1174 | goto nla_put_failure; | 1185 | goto nla_put_failure; |
1175 | 1186 | ||
1187 | if (swkey->phy.skb_mark && | ||
1188 | nla_put_u32(skb, OVS_KEY_ATTR_SKB_MARK, swkey->phy.skb_mark)) | ||
1189 | goto nla_put_failure; | ||
1190 | |||
1176 | nla = nla_reserve(skb, OVS_KEY_ATTR_ETHERNET, sizeof(*eth_key)); | 1191 | nla = nla_reserve(skb, OVS_KEY_ATTR_ETHERNET, sizeof(*eth_key)); |
1177 | if (!nla) | 1192 | if (!nla) |
1178 | goto nla_put_failure; | 1193 | goto nla_put_failure; |
@@ -1226,7 +1241,8 @@ int ovs_flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb) | |||
1226 | ipv6_key->ipv6_tclass = swkey->ip.tos; | 1241 | ipv6_key->ipv6_tclass = swkey->ip.tos; |
1227 | ipv6_key->ipv6_hlimit = swkey->ip.ttl; | 1242 | ipv6_key->ipv6_hlimit = swkey->ip.ttl; |
1228 | ipv6_key->ipv6_frag = swkey->ip.frag; | 1243 | ipv6_key->ipv6_frag = swkey->ip.frag; |
1229 | } else if (swkey->eth.type == htons(ETH_P_ARP)) { | 1244 | } else if (swkey->eth.type == htons(ETH_P_ARP) || |
1245 | swkey->eth.type == htons(ETH_P_RARP)) { | ||
1230 | struct ovs_key_arp *arp_key; | 1246 | struct ovs_key_arp *arp_key; |
1231 | 1247 | ||
1232 | nla = nla_reserve(skb, OVS_KEY_ATTR_ARP, sizeof(*arp_key)); | 1248 | nla = nla_reserve(skb, OVS_KEY_ATTR_ARP, sizeof(*arp_key)); |