diff options
author | Neil McKee <neil.mckee@inmon.com> | 2015-07-17 21:37:02 -0700 |
---|---|---|
committer | Ben Pfaff <blp@nicira.com> | 2015-07-21 14:19:04 -0700 |
commit | 7321bda384c366ae36bbca445f235a65d8f2b1f8 (patch) | |
tree | 6f76129ee3fb02512389632a3b4a2d82b63ad7ab /tests/test-sflow.c | |
parent | 4b8df0378747a83ec2478ded1e9cefe64d6a9f86 (diff) | |
download | openvswitch-7321bda384c366ae36bbca445f235a65d8f2b1f8.tar.gz |
Extend sFlow agent to report tunnel and MPLS structures
Packets are still sampled at ingress only, so the egress
tunnel and/or MPLS structures are only included when there is just 1 output
port. The actions are either provided by the datapath in the sample upcall
or looked up in the userspace cache. The former is preferred because it is
more reliable and does not present any new demands or constraints on the
userspace cache, however the code falls back on the userspace lookup so that
this solution can work with existing kernel datapath modules. If the lookup
fails it is not critical: the compiled user-action-cookie is still available
and provides the essential output port and output VLAN forwarding information
just as before.
The openvswitch actions can express almost any tunneling/mangling so the only
totally faithful representation would be to somehow encode the whole list of
flow actions in the sFlow output. However the standard sFlow tunnel structures
can express most common real-world scenarios, so in parsing the actions we
look for those and skip the encoding if we see anything unusual. For example,
a single set(tunnel()) or tnl_push() is interpreted, but if a second such
action is encountered then the egress tunnel reporting is suppressed.
The sFlow standard allows "best effort" encoding so that if a field is not
knowable or too onerous to look up then it can be left out. This is often
the case for the layer-4 source port or even the src ip address of a tunnel.
The assumption is that monitoring is enabled everywhere so a missing field
can typically be seen at ingress to the next switch in the path.
This patch also adds unit tests to check the sFlow encoding of set(tunnel()),
tnl_push() and push_mpls() actions.
The netlink attribute to request that actions be included in the upcall
from the datapath is inserted for sFlow sampling only. To make that option
be explicit would require further changes to the printing and parsing of
actions in lib/odp-util.c, and to scripts in the test suite.
Further enhancements to report on 802.1AD QinQ, 64-bit tunnel IDs, and NAT
transformations can follow in future patches that make only incremental
changes.
Signed-off-by: Neil McKee <neil.mckee@inmon.com>
[blp@nicira.com made stylistic and semantic changes]
Signed-off-by: Ben Pfaff <blp@nicira.com>
Diffstat (limited to 'tests/test-sflow.c')
-rw-r--r-- | tests/test-sflow.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/tests/test-sflow.c b/tests/test-sflow.c index 70a037256..3f6ffb231 100644 --- a/tests/test-sflow.c +++ b/tests/test-sflow.c @@ -63,6 +63,7 @@ static unixctl_cb_func test_sflow_exit; #define SFLOW_TAG_PKT_TUNNEL4_IN 1024 #define SFLOW_TAG_PKT_TUNNEL_VNI_OUT 1029 #define SFLOW_TAG_PKT_TUNNEL_VNI_IN 1030 +#define SFLOW_TAG_PKT_MPLS 1006 /* string sizes */ #define SFL_MAX_PORTNAME_LEN 255 @@ -113,6 +114,7 @@ struct sflow_xdr { uint32_t TUNNEL4_IN; uint32_t TUNNEL_VNI_OUT; uint32_t TUNNEL_VNI_IN; + uint32_t MPLS; uint32_t IFCOUNTERS; uint32_t LACPCOUNTERS; uint32_t OPENFLOWPORT; @@ -379,6 +381,32 @@ process_flow_sample(struct sflow_xdr *x) printf( " tunnel_out_vni=%"PRIu32, sflowxdr_next(x)); } + if (x->offset.MPLS) { + uint32_t addr_type, stack_depth, ii; + ovs_be32 mpls_lse; + sflowxdr_setc(x, x->offset.MPLS); + /* OVS only sets the out_stack. The rest will be blank. */ + /* skip next hop address */ + addr_type = sflowxdr_next(x); + sflowxdr_skip(x, addr_type == SFLOW_ADDRTYPE_IP6 ? 4 : 1); + /* skip in_stack */ + stack_depth = sflowxdr_next(x); + sflowxdr_skip(x, stack_depth); + /* print out_stack */ + stack_depth = sflowxdr_next(x); + for(ii = 0; ii < stack_depth; ii++) { + mpls_lse=sflowxdr_next_n(x); + printf(" mpls_label_%"PRIu32"=%"PRIu32, + ii, mpls_lse_to_label(mpls_lse)); + printf(" mpls_tc_%"PRIu32"=%"PRIu32, + ii, mpls_lse_to_tc(mpls_lse)); + printf(" mpls_ttl_%"PRIu32"=%"PRIu32, + ii, mpls_lse_to_ttl(mpls_lse)); + printf(" mpls_bos_%"PRIu32"=%"PRIu32, + ii, mpls_lse_to_bos(mpls_lse)); + } + } + if (x->offset.SWITCH) { sflowxdr_setc(x, x->offset.SWITCH); printf(" in_vlan=%"PRIu32, sflowxdr_next(x)); @@ -578,6 +606,10 @@ process_datagram(struct sflow_xdr *x) sflowxdr_mark_unique(x, &x->offset.TUNNEL_VNI_IN); break; + case SFLOW_TAG_PKT_MPLS: + sflowxdr_mark_unique(x, &x->offset.MPLS); + break; + /* Add others here... */ } |