aboutsummaryrefslogtreecommitdiffstats
path: root/net/openvswitch/datapath.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/openvswitch/datapath.c')
-rw-r--r--net/openvswitch/datapath.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index 6cfb44f3a7f0..c2ac340e19fb 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -274,6 +274,7 @@ void ovs_dp_process_packet(struct sk_buff *skb, struct sw_flow_key *key)
274 upcall.key = key; 274 upcall.key = key;
275 upcall.userdata = NULL; 275 upcall.userdata = NULL;
276 upcall.portid = ovs_vport_find_upcall_portid(p, skb); 276 upcall.portid = ovs_vport_find_upcall_portid(p, skb);
277 upcall.egress_tun_info = NULL;
277 error = ovs_dp_upcall(dp, skb, &upcall); 278 error = ovs_dp_upcall(dp, skb, &upcall);
278 if (unlikely(error)) 279 if (unlikely(error))
279 kfree_skb(skb); 280 kfree_skb(skb);
@@ -375,7 +376,7 @@ static int queue_gso_packets(struct datapath *dp, struct sk_buff *skb,
375 return err; 376 return err;
376} 377}
377 378
378static size_t upcall_msg_size(const struct nlattr *userdata, 379static size_t upcall_msg_size(const struct dp_upcall_info *upcall_info,
379 unsigned int hdrlen) 380 unsigned int hdrlen)
380{ 381{
381 size_t size = NLMSG_ALIGN(sizeof(struct ovs_header)) 382 size_t size = NLMSG_ALIGN(sizeof(struct ovs_header))
@@ -383,8 +384,12 @@ static size_t upcall_msg_size(const struct nlattr *userdata,
383 + nla_total_size(ovs_key_attr_size()); /* OVS_PACKET_ATTR_KEY */ 384 + nla_total_size(ovs_key_attr_size()); /* OVS_PACKET_ATTR_KEY */
384 385
385 /* OVS_PACKET_ATTR_USERDATA */ 386 /* OVS_PACKET_ATTR_USERDATA */
386 if (userdata) 387 if (upcall_info->userdata)
387 size += NLA_ALIGN(userdata->nla_len); 388 size += NLA_ALIGN(upcall_info->userdata->nla_len);
389
390 /* OVS_PACKET_ATTR_EGRESS_TUN_KEY */
391 if (upcall_info->egress_tun_info)
392 size += nla_total_size(ovs_tun_key_attr_size());
388 393
389 return size; 394 return size;
390} 395}
@@ -440,7 +445,7 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb,
440 else 445 else
441 hlen = skb->len; 446 hlen = skb->len;
442 447
443 len = upcall_msg_size(upcall_info->userdata, hlen); 448 len = upcall_msg_size(upcall_info, hlen);
444 user_skb = genlmsg_new_unicast(len, &info, GFP_ATOMIC); 449 user_skb = genlmsg_new_unicast(len, &info, GFP_ATOMIC);
445 if (!user_skb) { 450 if (!user_skb) {
446 err = -ENOMEM; 451 err = -ENOMEM;
@@ -461,6 +466,14 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb,
461 nla_len(upcall_info->userdata), 466 nla_len(upcall_info->userdata),
462 nla_data(upcall_info->userdata)); 467 nla_data(upcall_info->userdata));
463 468
469 if (upcall_info->egress_tun_info) {
470 nla = nla_nest_start(user_skb, OVS_PACKET_ATTR_EGRESS_TUN_KEY);
471 err = ovs_nla_put_egress_tunnel_key(user_skb,
472 upcall_info->egress_tun_info);
473 BUG_ON(err);
474 nla_nest_end(user_skb, nla);
475 }
476
464 /* Only reserve room for attribute header, packet data is added 477 /* Only reserve room for attribute header, packet data is added
465 * in skb_zerocopy() */ 478 * in skb_zerocopy() */
466 if (!(nla = nla_reserve(user_skb, OVS_PACKET_ATTR_PACKET, 0))) { 479 if (!(nla = nla_reserve(user_skb, OVS_PACKET_ATTR_PACKET, 0))) {