aboutsummaryrefslogtreecommitdiffstats
path: root/net/openvswitch
diff options
context:
space:
mode:
Diffstat (limited to 'net/openvswitch')
-rw-r--r--net/openvswitch/actions.c40
-rw-r--r--net/openvswitch/conntrack.c69
-rw-r--r--net/openvswitch/datapath.c42
-rw-r--r--net/openvswitch/datapath.h5
-rw-r--r--net/openvswitch/flow_netlink.c9
-rw-r--r--net/openvswitch/vport-internal_dev.c2
-rw-r--r--net/openvswitch/vport.c1
7 files changed, 125 insertions, 43 deletions
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
index 9a3eb7a0ebf4..1ecbd7715f6d 100644
--- a/net/openvswitch/actions.c
+++ b/net/openvswitch/actions.c
@@ -750,6 +750,14 @@ static void do_output(struct datapath *dp, struct sk_buff *skb, int out_port,
750 750
751 if (likely(vport)) { 751 if (likely(vport)) {
752 u16 mru = OVS_CB(skb)->mru; 752 u16 mru = OVS_CB(skb)->mru;
753 u32 cutlen = OVS_CB(skb)->cutlen;
754
755 if (unlikely(cutlen > 0)) {
756 if (skb->len - cutlen > ETH_HLEN)
757 pskb_trim(skb, skb->len - cutlen);
758 else
759 pskb_trim(skb, ETH_HLEN);
760 }
753 761
754 if (likely(!mru || (skb->len <= mru + ETH_HLEN))) { 762 if (likely(!mru || (skb->len <= mru + ETH_HLEN))) {
755 ovs_vport_send(vport, skb); 763 ovs_vport_send(vport, skb);
@@ -775,7 +783,8 @@ static void do_output(struct datapath *dp, struct sk_buff *skb, int out_port,
775 783
776static int output_userspace(struct datapath *dp, struct sk_buff *skb, 784static int output_userspace(struct datapath *dp, struct sk_buff *skb,
777 struct sw_flow_key *key, const struct nlattr *attr, 785 struct sw_flow_key *key, const struct nlattr *attr,
778 const struct nlattr *actions, int actions_len) 786 const struct nlattr *actions, int actions_len,
787 uint32_t cutlen)
779{ 788{
780 struct dp_upcall_info upcall; 789 struct dp_upcall_info upcall;
781 const struct nlattr *a; 790 const struct nlattr *a;
@@ -822,7 +831,7 @@ static int output_userspace(struct datapath *dp, struct sk_buff *skb,
822 } /* End of switch. */ 831 } /* End of switch. */
823 } 832 }
824 833
825 return ovs_dp_upcall(dp, skb, key, &upcall); 834 return ovs_dp_upcall(dp, skb, key, &upcall, cutlen);
826} 835}
827 836
828static int sample(struct datapath *dp, struct sk_buff *skb, 837static int sample(struct datapath *dp, struct sk_buff *skb,
@@ -832,6 +841,7 @@ static int sample(struct datapath *dp, struct sk_buff *skb,
832 const struct nlattr *acts_list = NULL; 841 const struct nlattr *acts_list = NULL;
833 const struct nlattr *a; 842 const struct nlattr *a;
834 int rem; 843 int rem;
844 u32 cutlen = 0;
835 845
836 for (a = nla_data(attr), rem = nla_len(attr); rem > 0; 846 for (a = nla_data(attr), rem = nla_len(attr); rem > 0;
837 a = nla_next(a, &rem)) { 847 a = nla_next(a, &rem)) {
@@ -858,13 +868,24 @@ static int sample(struct datapath *dp, struct sk_buff *skb,
858 return 0; 868 return 0;
859 869
860 /* The only known usage of sample action is having a single user-space 870 /* The only known usage of sample action is having a single user-space
871 * action, or having a truncate action followed by a single user-space
861 * action. Treat this usage as a special case. 872 * action. Treat this usage as a special case.
862 * The output_userspace() should clone the skb to be sent to the 873 * The output_userspace() should clone the skb to be sent to the
863 * user space. This skb will be consumed by its caller. 874 * user space. This skb will be consumed by its caller.
864 */ 875 */
876 if (unlikely(nla_type(a) == OVS_ACTION_ATTR_TRUNC)) {
877 struct ovs_action_trunc *trunc = nla_data(a);
878
879 if (skb->len > trunc->max_len)
880 cutlen = skb->len - trunc->max_len;
881
882 a = nla_next(a, &rem);
883 }
884
865 if (likely(nla_type(a) == OVS_ACTION_ATTR_USERSPACE && 885 if (likely(nla_type(a) == OVS_ACTION_ATTR_USERSPACE &&
866 nla_is_last(a, rem))) 886 nla_is_last(a, rem)))
867 return output_userspace(dp, skb, key, a, actions, actions_len); 887 return output_userspace(dp, skb, key, a, actions,
888 actions_len, cutlen);
868 889
869 skb = skb_clone(skb, GFP_ATOMIC); 890 skb = skb_clone(skb, GFP_ATOMIC);
870 if (!skb) 891 if (!skb)
@@ -1051,6 +1072,7 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
1051 if (out_skb) 1072 if (out_skb)
1052 do_output(dp, out_skb, prev_port, key); 1073 do_output(dp, out_skb, prev_port, key);
1053 1074
1075 OVS_CB(skb)->cutlen = 0;
1054 prev_port = -1; 1076 prev_port = -1;
1055 } 1077 }
1056 1078
@@ -1059,8 +1081,18 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
1059 prev_port = nla_get_u32(a); 1081 prev_port = nla_get_u32(a);
1060 break; 1082 break;
1061 1083
1084 case OVS_ACTION_ATTR_TRUNC: {
1085 struct ovs_action_trunc *trunc = nla_data(a);
1086
1087 if (skb->len > trunc->max_len)
1088 OVS_CB(skb)->cutlen = skb->len - trunc->max_len;
1089 break;
1090 }
1091
1062 case OVS_ACTION_ATTR_USERSPACE: 1092 case OVS_ACTION_ATTR_USERSPACE:
1063 output_userspace(dp, skb, key, a, attr, len); 1093 output_userspace(dp, skb, key, a, attr,
1094 len, OVS_CB(skb)->cutlen);
1095 OVS_CB(skb)->cutlen = 0;
1064 break; 1096 break;
1065 1097
1066 case OVS_ACTION_ATTR_HASH: 1098 case OVS_ACTION_ATTR_HASH:
diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c
index d84312584ee4..b4069a90e375 100644
--- a/net/openvswitch/conntrack.c
+++ b/net/openvswitch/conntrack.c
@@ -834,6 +834,17 @@ static int ovs_ct_lookup(struct net *net, struct sw_flow_key *key,
834 return 0; 834 return 0;
835} 835}
836 836
837static bool labels_nonzero(const struct ovs_key_ct_labels *labels)
838{
839 size_t i;
840
841 for (i = 0; i < sizeof(*labels); i++)
842 if (labels->ct_labels[i])
843 return true;
844
845 return false;
846}
847
837/* Lookup connection and confirm if unconfirmed. */ 848/* Lookup connection and confirm if unconfirmed. */
838static int ovs_ct_commit(struct net *net, struct sw_flow_key *key, 849static int ovs_ct_commit(struct net *net, struct sw_flow_key *key,
839 const struct ovs_conntrack_info *info, 850 const struct ovs_conntrack_info *info,
@@ -844,24 +855,32 @@ static int ovs_ct_commit(struct net *net, struct sw_flow_key *key,
844 err = __ovs_ct_lookup(net, key, info, skb); 855 err = __ovs_ct_lookup(net, key, info, skb);
845 if (err) 856 if (err)
846 return err; 857 return err;
847 /* This is a no-op if the connection has already been confirmed. */ 858
859 /* Apply changes before confirming the connection so that the initial
860 * conntrack NEW netlink event carries the values given in the CT
861 * action.
862 */
863 if (info->mark.mask) {
864 err = ovs_ct_set_mark(skb, key, info->mark.value,
865 info->mark.mask);
866 if (err)
867 return err;
868 }
869 if (labels_nonzero(&info->labels.mask)) {
870 err = ovs_ct_set_labels(skb, key, &info->labels.value,
871 &info->labels.mask);
872 if (err)
873 return err;
874 }
875 /* This will take care of sending queued events even if the connection
876 * is already confirmed.
877 */
848 if (nf_conntrack_confirm(skb) != NF_ACCEPT) 878 if (nf_conntrack_confirm(skb) != NF_ACCEPT)
849 return -EINVAL; 879 return -EINVAL;
850 880
851 return 0; 881 return 0;
852} 882}
853 883
854static bool labels_nonzero(const struct ovs_key_ct_labels *labels)
855{
856 size_t i;
857
858 for (i = 0; i < sizeof(*labels); i++)
859 if (labels->ct_labels[i])
860 return true;
861
862 return false;
863}
864
865/* Returns 0 on success, -EINPROGRESS if 'skb' is stolen, or other nonzero 884/* Returns 0 on success, -EINPROGRESS if 'skb' is stolen, or other nonzero
866 * value if 'skb' is freed. 885 * value if 'skb' is freed.
867 */ 886 */
@@ -886,19 +905,7 @@ int ovs_ct_execute(struct net *net, struct sk_buff *skb,
886 err = ovs_ct_commit(net, key, info, skb); 905 err = ovs_ct_commit(net, key, info, skb);
887 else 906 else
888 err = ovs_ct_lookup(net, key, info, skb); 907 err = ovs_ct_lookup(net, key, info, skb);
889 if (err)
890 goto err;
891 908
892 if (info->mark.mask) {
893 err = ovs_ct_set_mark(skb, key, info->mark.value,
894 info->mark.mask);
895 if (err)
896 goto err;
897 }
898 if (labels_nonzero(&info->labels.mask))
899 err = ovs_ct_set_labels(skb, key, &info->labels.value,
900 &info->labels.mask);
901err:
902 skb_push(skb, nh_ofs); 909 skb_push(skb, nh_ofs);
903 if (err) 910 if (err)
904 kfree_skb(skb); 911 kfree_skb(skb);
@@ -1155,6 +1162,20 @@ static int parse_ct(const struct nlattr *attr, struct ovs_conntrack_info *info,
1155 } 1162 }
1156 } 1163 }
1157 1164
1165#ifdef CONFIG_NF_CONNTRACK_MARK
1166 if (!info->commit && info->mark.mask) {
1167 OVS_NLERR(log,
1168 "Setting conntrack mark requires 'commit' flag.");
1169 return -EINVAL;
1170 }
1171#endif
1172#ifdef CONFIG_NF_CONNTRACK_LABELS
1173 if (!info->commit && labels_nonzero(&info->labels.mask)) {
1174 OVS_NLERR(log,
1175 "Setting conntrack labels requires 'commit' flag.");
1176 return -EINVAL;
1177 }
1178#endif
1158 if (rem > 0) { 1179 if (rem > 0) {
1159 OVS_NLERR(log, "Conntrack attr has %d unknown bytes", rem); 1180 OVS_NLERR(log, "Conntrack attr has %d unknown bytes", rem);
1160 return -EINVAL; 1181 return -EINVAL;
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index 856bd8dba676..524c0fd3078e 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -137,10 +137,12 @@ EXPORT_SYMBOL_GPL(lockdep_ovsl_is_held);
137static struct vport *new_vport(const struct vport_parms *); 137static struct vport *new_vport(const struct vport_parms *);
138static int queue_gso_packets(struct datapath *dp, struct sk_buff *, 138static int queue_gso_packets(struct datapath *dp, struct sk_buff *,
139 const struct sw_flow_key *, 139 const struct sw_flow_key *,
140 const struct dp_upcall_info *); 140 const struct dp_upcall_info *,
141 uint32_t cutlen);
141static int queue_userspace_packet(struct datapath *dp, struct sk_buff *, 142static int queue_userspace_packet(struct datapath *dp, struct sk_buff *,
142 const struct sw_flow_key *, 143 const struct sw_flow_key *,
143 const struct dp_upcall_info *); 144 const struct dp_upcall_info *,
145 uint32_t cutlen);
144 146
145/* Must be called with rcu_read_lock. */ 147/* Must be called with rcu_read_lock. */
146static struct datapath *get_dp_rcu(struct net *net, int dp_ifindex) 148static struct datapath *get_dp_rcu(struct net *net, int dp_ifindex)
@@ -275,7 +277,7 @@ void ovs_dp_process_packet(struct sk_buff *skb, struct sw_flow_key *key)
275 upcall.cmd = OVS_PACKET_CMD_MISS; 277 upcall.cmd = OVS_PACKET_CMD_MISS;
276 upcall.portid = ovs_vport_find_upcall_portid(p, skb); 278 upcall.portid = ovs_vport_find_upcall_portid(p, skb);
277 upcall.mru = OVS_CB(skb)->mru; 279 upcall.mru = OVS_CB(skb)->mru;
278 error = ovs_dp_upcall(dp, skb, key, &upcall); 280 error = ovs_dp_upcall(dp, skb, key, &upcall, 0);
279 if (unlikely(error)) 281 if (unlikely(error))
280 kfree_skb(skb); 282 kfree_skb(skb);
281 else 283 else
@@ -300,7 +302,8 @@ out:
300 302
301int ovs_dp_upcall(struct datapath *dp, struct sk_buff *skb, 303int ovs_dp_upcall(struct datapath *dp, struct sk_buff *skb,
302 const struct sw_flow_key *key, 304 const struct sw_flow_key *key,
303 const struct dp_upcall_info *upcall_info) 305 const struct dp_upcall_info *upcall_info,
306 uint32_t cutlen)
304{ 307{
305 struct dp_stats_percpu *stats; 308 struct dp_stats_percpu *stats;
306 int err; 309 int err;
@@ -311,9 +314,9 @@ int ovs_dp_upcall(struct datapath *dp, struct sk_buff *skb,
311 } 314 }
312 315
313 if (!skb_is_gso(skb)) 316 if (!skb_is_gso(skb))
314 err = queue_userspace_packet(dp, skb, key, upcall_info); 317 err = queue_userspace_packet(dp, skb, key, upcall_info, cutlen);
315 else 318 else
316 err = queue_gso_packets(dp, skb, key, upcall_info); 319 err = queue_gso_packets(dp, skb, key, upcall_info, cutlen);
317 if (err) 320 if (err)
318 goto err; 321 goto err;
319 322
@@ -331,7 +334,8 @@ err:
331 334
332static int queue_gso_packets(struct datapath *dp, struct sk_buff *skb, 335static int queue_gso_packets(struct datapath *dp, struct sk_buff *skb,
333 const struct sw_flow_key *key, 336 const struct sw_flow_key *key,
334 const struct dp_upcall_info *upcall_info) 337 const struct dp_upcall_info *upcall_info,
338 uint32_t cutlen)
335{ 339{
336 unsigned short gso_type = skb_shinfo(skb)->gso_type; 340 unsigned short gso_type = skb_shinfo(skb)->gso_type;
337 struct sw_flow_key later_key; 341 struct sw_flow_key later_key;
@@ -360,7 +364,7 @@ static int queue_gso_packets(struct datapath *dp, struct sk_buff *skb,
360 if (gso_type & SKB_GSO_UDP && skb != segs) 364 if (gso_type & SKB_GSO_UDP && skb != segs)
361 key = &later_key; 365 key = &later_key;
362 366
363 err = queue_userspace_packet(dp, skb, key, upcall_info); 367 err = queue_userspace_packet(dp, skb, key, upcall_info, cutlen);
364 if (err) 368 if (err)
365 break; 369 break;
366 370
@@ -383,7 +387,8 @@ static size_t upcall_msg_size(const struct dp_upcall_info *upcall_info,
383{ 387{
384 size_t size = NLMSG_ALIGN(sizeof(struct ovs_header)) 388 size_t size = NLMSG_ALIGN(sizeof(struct ovs_header))
385 + nla_total_size(hdrlen) /* OVS_PACKET_ATTR_PACKET */ 389 + nla_total_size(hdrlen) /* OVS_PACKET_ATTR_PACKET */
386 + nla_total_size(ovs_key_attr_size()); /* OVS_PACKET_ATTR_KEY */ 390 + nla_total_size(ovs_key_attr_size()) /* OVS_PACKET_ATTR_KEY */
391 + nla_total_size(sizeof(unsigned int)); /* OVS_PACKET_ATTR_LEN */
387 392
388 /* OVS_PACKET_ATTR_USERDATA */ 393 /* OVS_PACKET_ATTR_USERDATA */
389 if (upcall_info->userdata) 394 if (upcall_info->userdata)
@@ -416,7 +421,8 @@ static void pad_packet(struct datapath *dp, struct sk_buff *skb)
416 421
417static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb, 422static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb,
418 const struct sw_flow_key *key, 423 const struct sw_flow_key *key,
419 const struct dp_upcall_info *upcall_info) 424 const struct dp_upcall_info *upcall_info,
425 uint32_t cutlen)
420{ 426{
421 struct ovs_header *upcall; 427 struct ovs_header *upcall;
422 struct sk_buff *nskb = NULL; 428 struct sk_buff *nskb = NULL;
@@ -461,7 +467,7 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb,
461 else 467 else
462 hlen = skb->len; 468 hlen = skb->len;
463 469
464 len = upcall_msg_size(upcall_info, hlen); 470 len = upcall_msg_size(upcall_info, hlen - cutlen);
465 user_skb = genlmsg_new(len, GFP_ATOMIC); 471 user_skb = genlmsg_new(len, GFP_ATOMIC);
466 if (!user_skb) { 472 if (!user_skb) {
467 err = -ENOMEM; 473 err = -ENOMEM;
@@ -509,15 +515,25 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb,
509 pad_packet(dp, user_skb); 515 pad_packet(dp, user_skb);
510 } 516 }
511 517
518 /* Add OVS_PACKET_ATTR_LEN when packet is truncated */
519 if (cutlen > 0) {
520 if (nla_put_u32(user_skb, OVS_PACKET_ATTR_LEN,
521 skb->len)) {
522 err = -ENOBUFS;
523 goto out;
524 }
525 pad_packet(dp, user_skb);
526 }
527
512 /* Only reserve room for attribute header, packet data is added 528 /* Only reserve room for attribute header, packet data is added
513 * in skb_zerocopy() */ 529 * in skb_zerocopy() */
514 if (!(nla = nla_reserve(user_skb, OVS_PACKET_ATTR_PACKET, 0))) { 530 if (!(nla = nla_reserve(user_skb, OVS_PACKET_ATTR_PACKET, 0))) {
515 err = -ENOBUFS; 531 err = -ENOBUFS;
516 goto out; 532 goto out;
517 } 533 }
518 nla->nla_len = nla_attr_size(skb->len); 534 nla->nla_len = nla_attr_size(skb->len - cutlen);
519 535
520 err = skb_zerocopy(user_skb, skb, skb->len, hlen); 536 err = skb_zerocopy(user_skb, skb, skb->len - cutlen, hlen);
521 if (err) 537 if (err)
522 goto out; 538 goto out;
523 539
diff --git a/net/openvswitch/datapath.h b/net/openvswitch/datapath.h
index 427e39a045cf..ab85c1cae255 100644
--- a/net/openvswitch/datapath.h
+++ b/net/openvswitch/datapath.h
@@ -100,11 +100,13 @@ struct datapath {
100 * @input_vport: The original vport packet came in on. This value is cached 100 * @input_vport: The original vport packet came in on. This value is cached
101 * when a packet is received by OVS. 101 * when a packet is received by OVS.
102 * @mru: The maximum received fragement size; 0 if the packet is not 102 * @mru: The maximum received fragement size; 0 if the packet is not
103 * @cutlen: The number of bytes from the packet end to be removed.
103 * fragmented. 104 * fragmented.
104 */ 105 */
105struct ovs_skb_cb { 106struct ovs_skb_cb {
106 struct vport *input_vport; 107 struct vport *input_vport;
107 u16 mru; 108 u16 mru;
109 u32 cutlen;
108}; 110};
109#define OVS_CB(skb) ((struct ovs_skb_cb *)(skb)->cb) 111#define OVS_CB(skb) ((struct ovs_skb_cb *)(skb)->cb)
110 112
@@ -194,7 +196,8 @@ extern struct genl_family dp_vport_genl_family;
194void ovs_dp_process_packet(struct sk_buff *skb, struct sw_flow_key *key); 196void ovs_dp_process_packet(struct sk_buff *skb, struct sw_flow_key *key);
195void ovs_dp_detach_port(struct vport *); 197void ovs_dp_detach_port(struct vport *);
196int ovs_dp_upcall(struct datapath *, struct sk_buff *, 198int ovs_dp_upcall(struct datapath *, struct sk_buff *,
197 const struct sw_flow_key *, const struct dp_upcall_info *); 199 const struct sw_flow_key *, const struct dp_upcall_info *,
200 uint32_t cutlen);
198 201
199const char *ovs_dp_name(const struct datapath *dp); 202const char *ovs_dp_name(const struct datapath *dp);
200struct sk_buff *ovs_vport_cmd_build_info(struct vport *, u32 pid, u32 seq, 203struct sk_buff *ovs_vport_cmd_build_info(struct vport *, u32 pid, u32 seq,
diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
index 0bb650f4f219..c78a6a1476fb 100644
--- a/net/openvswitch/flow_netlink.c
+++ b/net/openvswitch/flow_netlink.c
@@ -2229,6 +2229,7 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
2229 [OVS_ACTION_ATTR_SAMPLE] = (u32)-1, 2229 [OVS_ACTION_ATTR_SAMPLE] = (u32)-1,
2230 [OVS_ACTION_ATTR_HASH] = sizeof(struct ovs_action_hash), 2230 [OVS_ACTION_ATTR_HASH] = sizeof(struct ovs_action_hash),
2231 [OVS_ACTION_ATTR_CT] = (u32)-1, 2231 [OVS_ACTION_ATTR_CT] = (u32)-1,
2232 [OVS_ACTION_ATTR_TRUNC] = sizeof(struct ovs_action_trunc),
2232 }; 2233 };
2233 const struct ovs_action_push_vlan *vlan; 2234 const struct ovs_action_push_vlan *vlan;
2234 int type = nla_type(a); 2235 int type = nla_type(a);
@@ -2255,6 +2256,14 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
2255 return -EINVAL; 2256 return -EINVAL;
2256 break; 2257 break;
2257 2258
2259 case OVS_ACTION_ATTR_TRUNC: {
2260 const struct ovs_action_trunc *trunc = nla_data(a);
2261
2262 if (trunc->max_len < ETH_HLEN)
2263 return -EINVAL;
2264 break;
2265 }
2266
2258 case OVS_ACTION_ATTR_HASH: { 2267 case OVS_ACTION_ATTR_HASH: {
2259 const struct ovs_action_hash *act_hash = nla_data(a); 2268 const struct ovs_action_hash *act_hash = nla_data(a);
2260 2269
diff --git a/net/openvswitch/vport-internal_dev.c b/net/openvswitch/vport-internal_dev.c
index 2ee48e447b72..434e04c3a189 100644
--- a/net/openvswitch/vport-internal_dev.c
+++ b/net/openvswitch/vport-internal_dev.c
@@ -195,7 +195,7 @@ static struct vport *internal_dev_create(const struct vport_parms *parms)
195 } 195 }
196 196
197 vport->dev = alloc_netdev(sizeof(struct internal_dev), 197 vport->dev = alloc_netdev(sizeof(struct internal_dev),
198 parms->name, NET_NAME_UNKNOWN, do_setup); 198 parms->name, NET_NAME_USER, do_setup);
199 if (!vport->dev) { 199 if (!vport->dev) {
200 err = -ENOMEM; 200 err = -ENOMEM;
201 goto error_free_vport; 201 goto error_free_vport;
diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c
index 31cbc8c5c7db..6b21fd068d87 100644
--- a/net/openvswitch/vport.c
+++ b/net/openvswitch/vport.c
@@ -444,6 +444,7 @@ int ovs_vport_receive(struct vport *vport, struct sk_buff *skb,
444 444
445 OVS_CB(skb)->input_vport = vport; 445 OVS_CB(skb)->input_vport = vport;
446 OVS_CB(skb)->mru = 0; 446 OVS_CB(skb)->mru = 0;
447 OVS_CB(skb)->cutlen = 0;
447 if (unlikely(dev_net(skb->dev) != ovs_dp_get_net(vport->dp))) { 448 if (unlikely(dev_net(skb->dev) != ovs_dp_get_net(vport->dp))) {
448 u32 mark; 449 u32 mark;
449 450