aboutsummaryrefslogtreecommitdiffstats
path: root/net/openvswitch/flow.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/openvswitch/flow.c')
-rw-r--r--net/openvswitch/flow.c28
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 */
1125int ovs_flow_metadata_from_nlattrs(u32 *priority, u16 *in_port, 1135int 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));