diff options
Diffstat (limited to 'net/openvswitch/flow.c')
-rw-r--r-- | net/openvswitch/flow.c | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c index 733cbf49ed1f..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); |
@@ -802,6 +804,7 @@ const int ovs_key_lens[OVS_KEY_ATTR_MAX + 1] = { | |||
802 | [OVS_KEY_ATTR_ENCAP] = -1, | 804 | [OVS_KEY_ATTR_ENCAP] = -1, |
803 | [OVS_KEY_ATTR_PRIORITY] = sizeof(u32), | 805 | [OVS_KEY_ATTR_PRIORITY] = sizeof(u32), |
804 | [OVS_KEY_ATTR_IN_PORT] = sizeof(u32), | 806 | [OVS_KEY_ATTR_IN_PORT] = sizeof(u32), |
807 | [OVS_KEY_ATTR_SKB_MARK] = sizeof(u32), | ||
805 | [OVS_KEY_ATTR_ETHERNET] = sizeof(struct ovs_key_ethernet), | 808 | [OVS_KEY_ATTR_ETHERNET] = sizeof(struct ovs_key_ethernet), |
806 | [OVS_KEY_ATTR_VLAN] = sizeof(__be16), | 809 | [OVS_KEY_ATTR_VLAN] = sizeof(__be16), |
807 | [OVS_KEY_ATTR_ETHERTYPE] = sizeof(__be16), | 810 | [OVS_KEY_ATTR_ETHERTYPE] = sizeof(__be16), |
@@ -987,6 +990,10 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp, | |||
987 | } else { | 990 | } else { |
988 | swkey->phy.in_port = DP_MAX_PORTS; | 991 | swkey->phy.in_port = DP_MAX_PORTS; |
989 | } | 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 | } | ||
990 | 997 | ||
991 | /* Data attributes. */ | 998 | /* Data attributes. */ |
992 | if (!(attrs & (1 << OVS_KEY_ATTR_ETHERNET))) | 999 | if (!(attrs & (1 << OVS_KEY_ATTR_ETHERNET))) |
@@ -1086,7 +1093,8 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp, | |||
1086 | if (err) | 1093 | if (err) |
1087 | return err; | 1094 | return err; |
1088 | } | 1095 | } |
1089 | } 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)) { | ||
1090 | const struct ovs_key_arp *arp_key; | 1098 | const struct ovs_key_arp *arp_key; |
1091 | 1099 | ||
1092 | if (!(attrs & (1 << OVS_KEY_ATTR_ARP))) | 1100 | if (!(attrs & (1 << OVS_KEY_ATTR_ARP))) |
@@ -1113,6 +1121,8 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp, | |||
1113 | 1121 | ||
1114 | /** | 1122 | /** |
1115 | * 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 | ||
1116 | * @in_port: receives the extracted input port. | 1126 | * @in_port: receives the extracted input port. |
1117 | * @key: Netlink attribute holding nested %OVS_KEY_ATTR_* Netlink attribute | 1127 | * @key: Netlink attribute holding nested %OVS_KEY_ATTR_* Netlink attribute |
1118 | * sequence. | 1128 | * sequence. |
@@ -1122,7 +1132,7 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp, | |||
1122 | * 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 |
1123 | * extracted from the packet itself. | 1133 | * extracted from the packet itself. |
1124 | */ | 1134 | */ |
1125 | 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, |
1126 | const struct nlattr *attr) | 1136 | const struct nlattr *attr) |
1127 | { | 1137 | { |
1128 | const struct nlattr *nla; | 1138 | const struct nlattr *nla; |
@@ -1130,6 +1140,7 @@ int ovs_flow_metadata_from_nlattrs(u32 *priority, u16 *in_port, | |||
1130 | 1140 | ||
1131 | *in_port = DP_MAX_PORTS; | 1141 | *in_port = DP_MAX_PORTS; |
1132 | *priority = 0; | 1142 | *priority = 0; |
1143 | *mark = 0; | ||
1133 | 1144 | ||
1134 | nla_for_each_nested(nla, attr, rem) { | 1145 | nla_for_each_nested(nla, attr, rem) { |
1135 | int type = nla_type(nla); | 1146 | int type = nla_type(nla); |
@@ -1148,6 +1159,10 @@ int ovs_flow_metadata_from_nlattrs(u32 *priority, u16 *in_port, | |||
1148 | return -EINVAL; | 1159 | return -EINVAL; |
1149 | *in_port = nla_get_u32(nla); | 1160 | *in_port = nla_get_u32(nla); |
1150 | break; | 1161 | break; |
1162 | |||
1163 | case OVS_KEY_ATTR_SKB_MARK: | ||
1164 | *mark = nla_get_u32(nla); | ||
1165 | break; | ||
1151 | } | 1166 | } |
1152 | } | 1167 | } |
1153 | } | 1168 | } |
@@ -1169,6 +1184,10 @@ int ovs_flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb) | |||
1169 | 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)) |
1170 | goto nla_put_failure; | 1185 | goto nla_put_failure; |
1171 | 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 | |||
1172 | nla = nla_reserve(skb, OVS_KEY_ATTR_ETHERNET, sizeof(*eth_key)); | 1191 | nla = nla_reserve(skb, OVS_KEY_ATTR_ETHERNET, sizeof(*eth_key)); |
1173 | if (!nla) | 1192 | if (!nla) |
1174 | goto nla_put_failure; | 1193 | goto nla_put_failure; |
@@ -1222,7 +1241,8 @@ int ovs_flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb) | |||
1222 | ipv6_key->ipv6_tclass = swkey->ip.tos; | 1241 | ipv6_key->ipv6_tclass = swkey->ip.tos; |
1223 | ipv6_key->ipv6_hlimit = swkey->ip.ttl; | 1242 | ipv6_key->ipv6_hlimit = swkey->ip.ttl; |
1224 | ipv6_key->ipv6_frag = swkey->ip.frag; | 1243 | ipv6_key->ipv6_frag = swkey->ip.frag; |
1225 | } 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)) { | ||
1226 | struct ovs_key_arp *arp_key; | 1246 | struct ovs_key_arp *arp_key; |
1227 | 1247 | ||
1228 | nla = nla_reserve(skb, OVS_KEY_ATTR_ARP, sizeof(*arp_key)); | 1248 | nla = nla_reserve(skb, OVS_KEY_ATTR_ARP, sizeof(*arp_key)); |