Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

openvswitch: prepare for stolen verdict coming from conntrack and nat engine

At this time, conntrack either returns NF_ACCEPT or NF_DROP.
To improve debuging it would be nice to be able to replace NF_DROP
verdict with NF_DROP_REASON() helper,

This helper releases the skb instantly (so drop_monitor can pinpoint
precise location) and returns NF_STOLEN.

Prepare call sites to deal with this before introducing such changes
in conntrack and nat core.

Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Aaron Conole <aconole@redhat.om>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Florian Westphal and committed by
David S. Miller
c7f79f26 aba43bdf

+37 -10
+37 -10
net/openvswitch/conntrack.c
··· 679 679 action |= BIT(NF_NAT_MANIP_DST); 680 680 681 681 err = nf_ct_nat(skb, ct, ctinfo, &action, &info->range, info->commit); 682 + if (err != NF_ACCEPT) 683 + return err; 682 684 683 685 if (action & BIT(NF_NAT_MANIP_SRC)) 684 686 ovs_nat_update_key(key, skb, NF_NAT_MANIP_SRC); ··· 698 696 return NF_ACCEPT; 699 697 } 700 698 #endif 699 + 700 + static int verdict_to_errno(unsigned int verdict) 701 + { 702 + switch (verdict & NF_VERDICT_MASK) { 703 + case NF_ACCEPT: 704 + return 0; 705 + case NF_DROP: 706 + return -EINVAL; 707 + case NF_STOLEN: 708 + return -EINPROGRESS; 709 + default: 710 + break; 711 + } 712 + 713 + return -EINVAL; 714 + } 701 715 702 716 /* Pass 'skb' through conntrack in 'net', using zone configured in 'info', if 703 717 * not done already. Update key with new CT state after passing the packet ··· 753 735 754 736 err = nf_conntrack_in(skb, &state); 755 737 if (err != NF_ACCEPT) 756 - return -ENOENT; 738 + return verdict_to_errno(err); 757 739 758 740 /* Clear CT state NAT flags to mark that we have not yet done 759 741 * NAT after the nf_conntrack_in() call. We can actually clear ··· 780 762 * the key->ct_state. 781 763 */ 782 764 if (info->nat && !(key->ct_state & OVS_CS_F_NAT_MASK) && 783 - (nf_ct_is_confirmed(ct) || info->commit) && 784 - ovs_ct_nat(net, key, info, skb, ct, ctinfo) != NF_ACCEPT) { 785 - return -EINVAL; 765 + (nf_ct_is_confirmed(ct) || info->commit)) { 766 + int err = ovs_ct_nat(net, key, info, skb, ct, ctinfo); 767 + 768 + err = verdict_to_errno(err); 769 + if (err) 770 + return err; 786 771 } 787 772 788 773 /* Userspace may decide to perform a ct lookup without a helper ··· 816 795 * - When committing an unconfirmed connection. 817 796 */ 818 797 if ((nf_ct_is_confirmed(ct) ? !cached || add_helper : 819 - info->commit) && 820 - nf_ct_helper(skb, ct, ctinfo, info->family) != NF_ACCEPT) { 821 - return -EINVAL; 798 + info->commit)) { 799 + int err = nf_ct_helper(skb, ct, ctinfo, info->family); 800 + 801 + err = verdict_to_errno(err); 802 + if (err) 803 + return err; 822 804 } 823 805 824 806 if (nf_ct_protonum(ct) == IPPROTO_TCP && ··· 1025 1001 /* This will take care of sending queued events even if the connection 1026 1002 * is already confirmed. 1027 1003 */ 1028 - if (nf_conntrack_confirm(skb) != NF_ACCEPT) 1029 - return -EINVAL; 1004 + err = nf_conntrack_confirm(skb); 1030 1005 1031 - return 0; 1006 + return verdict_to_errno(err); 1032 1007 } 1033 1008 1034 1009 /* Returns 0 on success, -EINPROGRESS if 'skb' is stolen, or other nonzero ··· 1061 1038 err = ovs_ct_commit(net, key, info, skb); 1062 1039 else 1063 1040 err = ovs_ct_lookup(net, key, info, skb); 1041 + 1042 + /* conntrack core returned NF_STOLEN */ 1043 + if (err == -EINPROGRESS) 1044 + return err; 1064 1045 1065 1046 skb_push_rcsum(skb, nh_ofs); 1066 1047 if (err)