Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support dumping OVS flows for a Service with antctl #1877

Merged
merged 1 commit into from
Feb 27, 2021

Conversation

jianjuns
Copy link
Contributor

antctl get of -S antrea -n kube-system

FLOW
table=41, n_packets=0, n_bytes=0, priority=200,tcp,reg4=0x10000/0x70000,nw_dst=10.108.138.236,tp_dst=443 actions=group:5
table=42, n_packets=0, n_bytes=0, priority=200,tcp,reg3=0xad85d17,reg4=0x2286d/0x7ffff actions=ct(commit,table=50,zone=65520,nat(dst=10.216.93.23:10349),exec(load:0x21->NXM_NX_CT_MARK[]))
table=106, n_packets=0, n_bytes=0, priority=200,ip,nw_src=10.216.93.23,nw_dst=10.216.93.23 actions=set_field:169.254.169.252->ip_src,load:0x1->NXM_NX_REG0[18],goto_table:110
group_id=5,type=select,bucket=bucket_id:0,weight:100,actions=load:0xad85d17->NXM_NX_REG3[],load:0x286d->NXM_NX_REG4[0..15],load:0x2->NXM_NX_REG4[16..18],load:0x1->NXM_NX_REG0[19],resubmit(,42)

docs/antctl.md Show resolved Hide resolved
pkg/agent/apiserver/handlers/ovsflows/handler.go Outdated Show resolved Hide resolved
pkg/agent/openflow/client.go Outdated Show resolved Hide resolved
pkg/agent/openflow/client.go Outdated Show resolved Hide resolved
// modifying the proxy.Provider interface.
type Proxier interface {
// GetProxyProvider returns the real proxy Provider.
GetProxyProvider() k8sproxy.Provider
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we could just extend the k8sproxy.Provider instead of having this method.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not know if you changed k8sproxy.Provider already or not (that is why I hope you can describe all the changes made the kube-proxy pkgs somewhere). However, I feel always better to reduce the changes to copied code to make code sync easier.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the changes are described at the top of the files in third-party.
The change I actually suggested from this comment is like

type Proxier interface {
    k8sproxy.Provider
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you suggesting:

type Proxier interface {
    k8sproxy.Provider
    GetServiceFlowKeys(serviceName, namespace string) ([]string, []binding.GroupIDType)
}

I thought about it, but not sure if mockgen works or not. Do you know?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just tried and the mock contains all defined methods.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. But I recalled the problem is for NewDualStackProxier(). How would you return an instance that implements k8sproxy.Provider then?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should then use our own interface instead of the Provider.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I walked through the code and found there is no usage of Provider in the third party package.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That means we need to rewrite metaProxier too? I still hope to reduce changes to the copied code.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sense, I missed that part. Then current implementation looks good.


p.serviceEndpointsMapsMutex.Lock()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I sugges to using a function to wrap this snippet.

func() {
   lock()
   defer unlock()
   ...
}()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sense. In this case, as really not much after the lock protection in this func, I just change to put "defer p.serviceEndpointsMapsMutex.Unlock()" after "p.serviceEndpointsMapsMutex.Lock()". Let me know what you think.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good.

@@ -480,6 +488,17 @@ func (c *client) UninstallLoadBalancerServiceFromOutsideFlows(svcIP net.IP, svcP
return c.deleteFlows(c.serviceFlowCache, cacheKey)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@weiqiangt : BTW, I wonder why in InstallEndpointFlows() we pass the extra isIPv6 argument, but not just let net.ParseIP() return a net.IP and check it is v4 or v6 when necessary. Is it for some efficiency consideration?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, for efficiency consideration, otherwise we will create a small bytes slice each time we check. cc @ksamoray.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But in this case, the IP is checked at most twice: one in endpointDNATFlow() and one in hairpinSNATFlow, and the latter is only for local Endpoint. Is it worth to optimize?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Considering parameters passing is simple I thought it is OK. But a second thought is that the cost here is not that critical, I'm fine with the change also.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As endpointDNATFlow() performs To4() anyway for v4, this argument has no importance as To4() is later applied again here
https://github.com/vmware-tanzu/antrea/blob/main/pkg/agent/openflow/pipeline.go#L1830

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the info guys! So, let us remove the argument then.

@jianjuns jianjuns force-pushed the service-flows branch 2 times, most recently from 36d3029 to a0e91fb Compare February 22, 2021 18:47
return fmt.Sprintf("Service_%s_%d_%s", svcIP, svcPort, protocol)
}

func (c *client) InstallEndpointFlows(protocol binding.Protocol, endpoints []proxy.Endpoint) error {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed the isIPv6 argument, as I could not figure out why it is needed. Let me know if I am wrong. @weiqiangt

@jianjuns jianjuns force-pushed the service-flows branch 3 times, most recently from 25d7800 to b0ea83a Compare February 22, 2021 19:52
@codecov-io
Copy link

codecov-io commented Feb 22, 2021

Codecov Report

❗ No coverage uploaded for pull request base (main@6ec79a7). Click here to learn what that means.
The diff coverage is n/a.

Impacted file tree graph

@@           Coverage Diff           @@
##             main    #1877   +/-   ##
=======================================
  Coverage        ?   58.79%           
=======================================
  Files           ?      201           
  Lines           ?    17374           
  Branches        ?        0           
=======================================
  Hits            ?    10215           
  Misses          ?     6088           
  Partials        ?     1071           
Flag Coverage Δ
e2e-tests 44.98% <0.00%> (?)
unit-tests 41.19% <0.00%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

weiqiangt
weiqiangt previously approved these changes Feb 23, 2021
Copy link
Contributor

@weiqiangt weiqiangt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@jianjuns
Copy link
Contributor Author

/test-windows-conformance

@jianjuns
Copy link
Contributor Author

/test-all

1 similar comment
@weiqiangt
Copy link
Contributor

/test-all

weiqiangt
weiqiangt previously approved these changes Feb 25, 2021
antoninbas
antoninbas previously approved these changes Feb 26, 2021
Copy link
Contributor

@antoninbas antoninbas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Comment on lines 642 to 648
if v4Flows == nil {
if v6Flows == nil {
return nil, nil
}
// Not to return nil, even v6Flows is empty.
v4Flows = make([]string, 0, len(v6Flows))
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like a third parameter would have been clearer, i.e. the function could return (found bool, flowKeys []string, groupIDs []binding.GroupIDType)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. Change to what you suggested.

@@ -63,6 +64,27 @@ func (c *ovsCtlClient) DumpTableFlows(table uint8) ([]string, error) {
return c.DumpFlows(fmt.Sprintf("table=%d", table))
}

func (c *ovsCtlClient) DumpGroup(groupID int) (string, error) {
// There seems a bug in ovs-ofctl that dump-groups always returns all
// the groups when using Openflow13, even the group ID is provided. As
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/even the group ID is provided/even when the group ID is provided

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@@ -63,6 +64,27 @@ func (c *ovsCtlClient) DumpTableFlows(table uint8) ([]string, error) {
return c.DumpFlows(fmt.Sprintf("table=%d", table))
}

func (c *ovsCtlClient) DumpGroup(groupID int) (string, error) {
// There seems a bug in ovs-ofctl that dump-groups always returns all
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

out-of-curiosity did you report the bug?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not yet. Will do.

antoninbas
antoninbas previously approved these changes Feb 26, 2021
Copy link
Contributor

@antoninbas antoninbas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@jianjuns
Copy link
Contributor Author

/test-all

@jianjuns
Copy link
Contributor Author

/test-all-features-conformance

Extend Agent /ovsflows API handler to support returning OVS flows
for a Service.
Extend agent/proxy/proxier to query OVS flow keys and group IDs for a
Service.
Extend ovs/ovsctl/ofctl to support dumping a specific OVS group.
Extend "antctl get ovsflows" command to dump OVS flows for a Service.
@jianjuns
Copy link
Contributor Author

/test-all-features-conformance

1 similar comment
@jianjuns
Copy link
Contributor Author

/test-all-features-conformance

@jianjuns
Copy link
Contributor Author

/test-all

Copy link
Contributor

@antoninbas antoninbas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving again after rebase

@jianjuns jianjuns merged commit cdf357f into antrea-io:main Feb 27, 2021
jianjuns added a commit to jianjuns/antrea that referenced this pull request Feb 27, 2021
Extend Agent /ovsflows API handler to support returning OVS flows
for a Service.
Extend agent/proxy/proxier to query OVS flow keys and group IDs for a
Service.
Extend ovs/ovsctl/ofctl to support dumping a specific OVS group.
Extend "antctl get ovsflows" command to dump OVS flows for a Service.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants