diff options
Diffstat (limited to 'net/openvswitch')
-rw-r--r-- | net/openvswitch/datapath.c | 76 | ||||
-rw-r--r-- | net/openvswitch/flow.h | 21 |
2 files changed, 52 insertions, 45 deletions
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index bca63c8487bb..49ee37b83a29 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c | |||
@@ -337,6 +337,35 @@ static int queue_gso_packets(struct net *net, int dp_ifindex, | |||
337 | return err; | 337 | return err; |
338 | } | 338 | } |
339 | 339 | ||
340 | static size_t key_attr_size(void) | ||
341 | { | ||
342 | return nla_total_size(4) /* OVS_KEY_ATTR_PRIORITY */ | ||
343 | + nla_total_size(4) /* OVS_KEY_ATTR_IN_PORT */ | ||
344 | + nla_total_size(4) /* OVS_KEY_ATTR_SKB_MARK */ | ||
345 | + nla_total_size(12) /* OVS_KEY_ATTR_ETHERNET */ | ||
346 | + nla_total_size(2) /* OVS_KEY_ATTR_ETHERTYPE */ | ||
347 | + nla_total_size(4) /* OVS_KEY_ATTR_8021Q */ | ||
348 | + nla_total_size(0) /* OVS_KEY_ATTR_ENCAP */ | ||
349 | + nla_total_size(2) /* OVS_KEY_ATTR_ETHERTYPE */ | ||
350 | + nla_total_size(40) /* OVS_KEY_ATTR_IPV6 */ | ||
351 | + nla_total_size(2) /* OVS_KEY_ATTR_ICMPV6 */ | ||
352 | + nla_total_size(28); /* OVS_KEY_ATTR_ND */ | ||
353 | } | ||
354 | |||
355 | static size_t upcall_msg_size(const struct sk_buff *skb, | ||
356 | const struct nlattr *userdata) | ||
357 | { | ||
358 | size_t size = NLMSG_ALIGN(sizeof(struct ovs_header)) | ||
359 | + nla_total_size(skb->len) /* OVS_PACKET_ATTR_PACKET */ | ||
360 | + nla_total_size(key_attr_size()); /* OVS_PACKET_ATTR_KEY */ | ||
361 | |||
362 | /* OVS_PACKET_ATTR_USERDATA */ | ||
363 | if (userdata) | ||
364 | size += NLA_ALIGN(userdata->nla_len); | ||
365 | |||
366 | return size; | ||
367 | } | ||
368 | |||
340 | static int queue_userspace_packet(struct net *net, int dp_ifindex, | 369 | static int queue_userspace_packet(struct net *net, int dp_ifindex, |
341 | struct sk_buff *skb, | 370 | struct sk_buff *skb, |
342 | const struct dp_upcall_info *upcall_info) | 371 | const struct dp_upcall_info *upcall_info) |
@@ -345,7 +374,6 @@ static int queue_userspace_packet(struct net *net, int dp_ifindex, | |||
345 | struct sk_buff *nskb = NULL; | 374 | struct sk_buff *nskb = NULL; |
346 | struct sk_buff *user_skb; /* to be queued to userspace */ | 375 | struct sk_buff *user_skb; /* to be queued to userspace */ |
347 | struct nlattr *nla; | 376 | struct nlattr *nla; |
348 | unsigned int len; | ||
349 | int err; | 377 | int err; |
350 | 378 | ||
351 | if (vlan_tx_tag_present(skb)) { | 379 | if (vlan_tx_tag_present(skb)) { |
@@ -366,13 +394,7 @@ static int queue_userspace_packet(struct net *net, int dp_ifindex, | |||
366 | goto out; | 394 | goto out; |
367 | } | 395 | } |
368 | 396 | ||
369 | len = sizeof(struct ovs_header); | 397 | user_skb = genlmsg_new(upcall_msg_size(skb, upcall_info->userdata), GFP_ATOMIC); |
370 | len += nla_total_size(skb->len); | ||
371 | len += nla_total_size(FLOW_BUFSIZE); | ||
372 | if (upcall_info->userdata) | ||
373 | len += NLA_ALIGN(upcall_info->userdata->nla_len); | ||
374 | |||
375 | user_skb = genlmsg_new(len, GFP_ATOMIC); | ||
376 | if (!user_skb) { | 398 | if (!user_skb) { |
377 | err = -ENOMEM; | 399 | err = -ENOMEM; |
378 | goto out; | 400 | goto out; |
@@ -801,6 +823,16 @@ static struct genl_multicast_group ovs_dp_flow_multicast_group = { | |||
801 | .name = OVS_FLOW_MCGROUP | 823 | .name = OVS_FLOW_MCGROUP |
802 | }; | 824 | }; |
803 | 825 | ||
826 | static size_t ovs_flow_cmd_msg_size(const struct sw_flow_actions *acts) | ||
827 | { | ||
828 | return NLMSG_ALIGN(sizeof(struct ovs_header)) | ||
829 | + nla_total_size(key_attr_size()) /* OVS_FLOW_ATTR_KEY */ | ||
830 | + nla_total_size(sizeof(struct ovs_flow_stats)) /* OVS_FLOW_ATTR_STATS */ | ||
831 | + nla_total_size(1) /* OVS_FLOW_ATTR_TCP_FLAGS */ | ||
832 | + nla_total_size(8) /* OVS_FLOW_ATTR_USED */ | ||
833 | + nla_total_size(acts->actions_len); /* OVS_FLOW_ATTR_ACTIONS */ | ||
834 | } | ||
835 | |||
804 | /* Called with genl_lock. */ | 836 | /* Called with genl_lock. */ |
805 | static int ovs_flow_cmd_fill_info(struct sw_flow *flow, struct datapath *dp, | 837 | static int ovs_flow_cmd_fill_info(struct sw_flow *flow, struct datapath *dp, |
806 | struct sk_buff *skb, u32 portid, | 838 | struct sk_buff *skb, u32 portid, |
@@ -879,25 +911,11 @@ error: | |||
879 | static struct sk_buff *ovs_flow_cmd_alloc_info(struct sw_flow *flow) | 911 | static struct sk_buff *ovs_flow_cmd_alloc_info(struct sw_flow *flow) |
880 | { | 912 | { |
881 | const struct sw_flow_actions *sf_acts; | 913 | const struct sw_flow_actions *sf_acts; |
882 | int len; | ||
883 | 914 | ||
884 | sf_acts = rcu_dereference_protected(flow->sf_acts, | 915 | sf_acts = rcu_dereference_protected(flow->sf_acts, |
885 | lockdep_genl_is_held()); | 916 | lockdep_genl_is_held()); |
886 | 917 | ||
887 | /* OVS_FLOW_ATTR_KEY */ | 918 | return genlmsg_new(ovs_flow_cmd_msg_size(sf_acts), GFP_KERNEL); |
888 | len = nla_total_size(FLOW_BUFSIZE); | ||
889 | /* OVS_FLOW_ATTR_ACTIONS */ | ||
890 | len += nla_total_size(sf_acts->actions_len); | ||
891 | /* OVS_FLOW_ATTR_STATS */ | ||
892 | len += nla_total_size(sizeof(struct ovs_flow_stats)); | ||
893 | /* OVS_FLOW_ATTR_TCP_FLAGS */ | ||
894 | len += nla_total_size(1); | ||
895 | /* OVS_FLOW_ATTR_USED */ | ||
896 | len += nla_total_size(8); | ||
897 | |||
898 | len += NLMSG_ALIGN(sizeof(struct ovs_header)); | ||
899 | |||
900 | return genlmsg_new(len, GFP_KERNEL); | ||
901 | } | 919 | } |
902 | 920 | ||
903 | static struct sk_buff *ovs_flow_cmd_build_info(struct sw_flow *flow, | 921 | static struct sk_buff *ovs_flow_cmd_build_info(struct sw_flow *flow, |
@@ -1213,6 +1231,16 @@ static struct genl_multicast_group ovs_dp_datapath_multicast_group = { | |||
1213 | .name = OVS_DATAPATH_MCGROUP | 1231 | .name = OVS_DATAPATH_MCGROUP |
1214 | }; | 1232 | }; |
1215 | 1233 | ||
1234 | static size_t ovs_dp_cmd_msg_size(void) | ||
1235 | { | ||
1236 | size_t msgsize = NLMSG_ALIGN(sizeof(struct ovs_header)); | ||
1237 | |||
1238 | msgsize += nla_total_size(IFNAMSIZ); | ||
1239 | msgsize += nla_total_size(sizeof(struct ovs_dp_stats)); | ||
1240 | |||
1241 | return msgsize; | ||
1242 | } | ||
1243 | |||
1216 | static int ovs_dp_cmd_fill_info(struct datapath *dp, struct sk_buff *skb, | 1244 | static int ovs_dp_cmd_fill_info(struct datapath *dp, struct sk_buff *skb, |
1217 | u32 portid, u32 seq, u32 flags, u8 cmd) | 1245 | u32 portid, u32 seq, u32 flags, u8 cmd) |
1218 | { | 1246 | { |
@@ -1251,7 +1279,7 @@ static struct sk_buff *ovs_dp_cmd_build_info(struct datapath *dp, u32 portid, | |||
1251 | struct sk_buff *skb; | 1279 | struct sk_buff *skb; |
1252 | int retval; | 1280 | int retval; |
1253 | 1281 | ||
1254 | skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 1282 | skb = genlmsg_new(ovs_dp_cmd_msg_size(), GFP_KERNEL); |
1255 | if (!skb) | 1283 | if (!skb) |
1256 | return ERR_PTR(-ENOMEM); | 1284 | return ERR_PTR(-ENOMEM); |
1257 | 1285 | ||
diff --git a/net/openvswitch/flow.h b/net/openvswitch/flow.h index a7bb60ff3b5b..0875fde65b9c 100644 --- a/net/openvswitch/flow.h +++ b/net/openvswitch/flow.h | |||
@@ -138,27 +138,6 @@ int ovs_flow_extract(struct sk_buff *, u16 in_port, struct sw_flow_key *, | |||
138 | void ovs_flow_used(struct sw_flow *, struct sk_buff *); | 138 | void ovs_flow_used(struct sw_flow *, struct sk_buff *); |
139 | u64 ovs_flow_used_time(unsigned long flow_jiffies); | 139 | u64 ovs_flow_used_time(unsigned long flow_jiffies); |
140 | 140 | ||
141 | /* Upper bound on the length of a nlattr-formatted flow key. The longest | ||
142 | * nlattr-formatted flow key would be: | ||
143 | * | ||
144 | * struct pad nl hdr total | ||
145 | * ------ --- ------ ----- | ||
146 | * OVS_KEY_ATTR_PRIORITY 4 -- 4 8 | ||
147 | * OVS_KEY_ATTR_IN_PORT 4 -- 4 8 | ||
148 | * OVS_KEY_ATTR_SKB_MARK 4 -- 4 8 | ||
149 | * OVS_KEY_ATTR_ETHERNET 12 -- 4 16 | ||
150 | * OVS_KEY_ATTR_ETHERTYPE 2 2 4 8 (outer VLAN ethertype) | ||
151 | * OVS_KEY_ATTR_8021Q 4 -- 4 8 | ||
152 | * OVS_KEY_ATTR_ENCAP 0 -- 4 4 (VLAN encapsulation) | ||
153 | * OVS_KEY_ATTR_ETHERTYPE 2 2 4 8 (inner VLAN ethertype) | ||
154 | * OVS_KEY_ATTR_IPV6 40 -- 4 44 | ||
155 | * OVS_KEY_ATTR_ICMPV6 2 2 4 8 | ||
156 | * OVS_KEY_ATTR_ND 28 -- 4 32 | ||
157 | * ------------------------------------------------- | ||
158 | * total 152 | ||
159 | */ | ||
160 | #define FLOW_BUFSIZE 152 | ||
161 | |||
162 | int ovs_flow_to_nlattrs(const struct sw_flow_key *, struct sk_buff *); | 141 | int ovs_flow_to_nlattrs(const struct sw_flow_key *, struct sk_buff *); |
163 | int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp, | 142 | int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp, |
164 | const struct nlattr *); | 143 | const struct nlattr *); |