X-Git-Url: http://git.cascardo.eti.br/?a=blobdiff_plain;f=tests%2Ftest-sflow.c;h=08591bf1a1e1608c422508e4b9c02f660f4ad7b6;hb=12e2ba2e85cc811b946ab867d6971d2f0938fc04;hp=3eb93c5b0da0dd746f6b9cbb7b24e3c32c84ae49;hpb=8073dd318b5a08fa447392f100d62b3bf54388a7;p=cascardo%2Fovs.git diff --git a/tests/test-sflow.c b/tests/test-sflow.c index 3eb93c5b0..08591bf1a 100644 --- a/tests/test-sflow.c +++ b/tests/test-sflow.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012 Nicira, Inc. + * Copyright (c) 2011, 2012, 2013, 2014, 2015 Nicira, Inc. * Copyright (c) 2013 InMon Corp. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,27 +16,28 @@ */ #include - +#undef NDEBUG +#include "netflow.h" +#include #include #include #include #include #include #include - #include "command-line.h" #include "daemon.h" #include "dynamic-string.h" -#include "netflow.h" #include "ofpbuf.h" +#include "ovstest.h" #include "packets.h" #include "poll-loop.h" #include "socket-util.h" #include "unixctl.h" #include "util.h" -#include "vlog.h" +#include "openvswitch/vlog.h" -static void usage(void) NO_RETURN; +OVS_NO_RETURN static void usage(void); static void parse_options(int argc, char *argv[]); static unixctl_cb_func test_sflow_exit; @@ -44,7 +45,6 @@ static unixctl_cb_func test_sflow_exit; /* Datagram. */ #define SFLOW_VERSION_5 5 #define SFLOW_MIN_LEN 36 -#define SFLOW_MAX_AGENTIP_STRLEN 64 /* Sample tag numbers. */ #define SFLOW_FLOW_SAMPLE 1 @@ -54,8 +54,19 @@ static unixctl_cb_func test_sflow_exit; /* Structure element tag numbers. */ #define SFLOW_TAG_CTR_IFCOUNTERS 1 +#define SFLOW_TAG_CTR_LACPCOUNTERS 7 +#define SFLOW_TAG_CTR_OPENFLOWPORT 1004 +#define SFLOW_TAG_CTR_PORTNAME 1005 #define SFLOW_TAG_PKT_HEADER 1 #define SFLOW_TAG_PKT_SWITCH 1001 +#define SFLOW_TAG_PKT_TUNNEL4_OUT 1023 +#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 struct sflow_addr { enum { @@ -82,7 +93,7 @@ struct sflow_xdr { /* Agent. */ struct sflow_addr agentAddr; - char agentIPStr[SFLOW_MAX_AGENTIP_STRLEN]; + char agentIPStr[INET6_ADDRSTRLEN + 2]; uint32_t subAgentId; uint32_t uptime_mS; @@ -99,7 +110,15 @@ struct sflow_xdr { struct { uint32_t HEADER; uint32_t SWITCH; + uint32_t TUNNEL4_OUT; + 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; + uint32_t PORTNAME; } offset; /* Flow sample fields. */ @@ -221,6 +240,63 @@ process_counter_sample(struct sflow_xdr *x) printf(" promiscuous=%"PRIu32, sflowxdr_next(x)); printf("\n"); } + if (x->offset.LACPCOUNTERS) { + struct eth_addr *mac; + union { + ovs_be32 all; + struct { + uint8_t actorAdmin; + uint8_t actorOper; + uint8_t partnerAdmin; + uint8_t partnerOper; + } v; + } state; + + sflowxdr_setc(x, x->offset.LACPCOUNTERS); + printf("LACPCOUNTERS"); + mac = (void *)sflowxdr_str(x); + printf(" sysID="ETH_ADDR_FMT, ETH_ADDR_ARGS(*mac)); + sflowxdr_skip(x, 2); + mac = (void *)sflowxdr_str(x); + printf(" partnerID="ETH_ADDR_FMT, ETH_ADDR_ARGS(*mac)); + sflowxdr_skip(x, 2); + printf(" aggID=%"PRIu32, sflowxdr_next(x)); + state.all = sflowxdr_next_n(x); + printf(" actorAdmin=0x%"PRIx32, state.v.actorAdmin); + printf(" actorOper=0x%"PRIx32, state.v.actorOper); + printf(" partnerAdmin=0x%"PRIx32, state.v.partnerAdmin); + printf(" partnerOper=0x%"PRIx32, state.v.partnerOper); + printf(" LACPUDsRx=%"PRIu32, sflowxdr_next(x)); + printf(" markerPDUsRx=%"PRIu32, sflowxdr_next(x)); + printf(" markerRespPDUsRx=%"PRIu32, sflowxdr_next(x)); + printf(" unknownRx=%"PRIu32, sflowxdr_next(x)); + printf(" illegalRx=%"PRIu32, sflowxdr_next(x)); + printf(" LACPUDsTx=%"PRIu32, sflowxdr_next(x)); + printf(" markerPDUsTx=%"PRIu32, sflowxdr_next(x)); + printf(" markerRespPDUsTx=%"PRIu32, sflowxdr_next(x)); + printf("\n"); + } + if (x->offset.OPENFLOWPORT) { + sflowxdr_setc(x, x->offset.OPENFLOWPORT); + printf("OPENFLOWPORT"); + printf(" datapath_id=%"PRIu64, sflowxdr_next_int64(x)); + printf(" port_no=%"PRIu32, sflowxdr_next(x)); + printf("\n"); + } + if (x->offset.PORTNAME) { + uint32_t pnLen; + const char *pnBytes; + char portName[SFL_MAX_PORTNAME_LEN + 1]; + sflowxdr_setc(x, x->offset.PORTNAME); + printf("PORTNAME"); + pnLen = sflowxdr_next(x); + SFLOWXDR_assert(x, (pnLen <= SFL_MAX_PORTNAME_LEN)); + pnBytes = sflowxdr_str(x); + memcpy(portName, pnBytes, pnLen); + portName[pnLen] = '\0'; + printf(" portName=%s", portName); + printf("\n"); + } } static char @@ -251,6 +327,25 @@ print_hex(const char *a, int len, char *buf, int bufLen) return b; } +static void +print_struct_ipv4(struct sflow_xdr *x, const char *prefix) +{ + ovs_be32 src, dst; + + printf(" %s_length=%"PRIu32, prefix, sflowxdr_next(x)); + printf(" %s_protocol=%"PRIu32, prefix, sflowxdr_next(x)); + + src = sflowxdr_next_n(x); + dst = sflowxdr_next_n(x); + printf(" %s_src="IP_FMT, prefix, IP_ARGS(src)); + printf(" %s_dst="IP_FMT, prefix, IP_ARGS(dst)); + + printf(" %s_src_port=%"PRIu32, prefix, sflowxdr_next(x)); + printf(" %s_dst_port=%"PRIu32, prefix, sflowxdr_next(x)); + printf(" %s_tcp_flags=%"PRIu32, prefix, sflowxdr_next(x)); + printf(" %s_tos=%"PRIu32, prefix, sflowxdr_next(x)); +} + #define SFLOW_HEX_SCRATCH 1024 static void @@ -266,6 +361,52 @@ process_flow_sample(struct sflow_xdr *x) x->agentIPStr, x->dsClass, x->dsIndex); printf(" fsSeqNo=%"PRIu32, x->fsSeqNo); + if (x->offset.TUNNEL4_IN) { + sflowxdr_setc(x, x->offset.TUNNEL4_IN); + print_struct_ipv4(x, "tunnel4_in"); + } + + if (x->offset.TUNNEL4_OUT) { + sflowxdr_setc(x, x->offset.TUNNEL4_OUT); + print_struct_ipv4(x, "tunnel4_out"); + } + + if (x->offset.TUNNEL_VNI_IN) { + sflowxdr_setc(x, x->offset.TUNNEL_VNI_IN); + printf( " tunnel_in_vni=%"PRIu32, sflowxdr_next(x)); + } + + if (x->offset.TUNNEL_VNI_OUT) { + sflowxdr_setc(x, x->offset.TUNNEL_VNI_OUT); + 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)); @@ -325,14 +466,12 @@ process_datagram(struct sflow_xdr *x) /* Store the agent address as a string. */ if (x->agentAddr.type == SFLOW_ADDRTYPE_IP6) { - snprintf(x->agentIPStr, SFLOW_MAX_AGENTIP_STRLEN, - "%04x:%04x:%04x:%04x", - x->agentAddr.a.ip6[0], - x->agentAddr.a.ip6[1], - x->agentAddr.a.ip6[2], - x->agentAddr.a.ip6[3]); + char ipstr[INET6_ADDRSTRLEN]; + inet_ntop(AF_INET6, (const void *) &x->agentAddr.a.ip6, + ipstr, INET6_ADDRSTRLEN); + snprintf(x->agentIPStr, sizeof x->agentIPStr, "[%s]", ipstr); } else { - snprintf(x->agentIPStr, SFLOW_MAX_AGENTIP_STRLEN, + snprintf(x->agentIPStr, sizeof x->agentIPStr, IP_FMT, IP_ARGS(x->agentAddr.a.ip4)); } @@ -374,6 +513,15 @@ process_datagram(struct sflow_xdr *x) case SFLOW_TAG_CTR_IFCOUNTERS: sflowxdr_mark_unique(x, &x->offset.IFCOUNTERS); break; + case SFLOW_TAG_CTR_LACPCOUNTERS: + sflowxdr_mark_unique(x, &x->offset.LACPCOUNTERS); + break; + case SFLOW_TAG_CTR_PORTNAME: + sflowxdr_mark_unique(x, &x->offset.PORTNAME); + break; + case SFLOW_TAG_CTR_OPENFLOWPORT: + sflowxdr_mark_unique(x, &x->offset.OPENFLOWPORT); + break; /* Add others here... */ } @@ -442,6 +590,26 @@ process_datagram(struct sflow_xdr *x) sflowxdr_mark_unique(x, &x->offset.SWITCH); break; + case SFLOW_TAG_PKT_TUNNEL4_OUT: + sflowxdr_mark_unique(x, &x->offset.TUNNEL4_OUT); + break; + + case SFLOW_TAG_PKT_TUNNEL4_IN: + sflowxdr_mark_unique(x, &x->offset.TUNNEL4_IN); + break; + + case SFLOW_TAG_PKT_TUNNEL_VNI_OUT: + sflowxdr_mark_unique(x, &x->offset.TUNNEL_VNI_OUT); + break; + + case SFLOW_TAG_PKT_TUNNEL_VNI_IN: + 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... */ } @@ -487,8 +655,8 @@ print_sflow(struct ofpbuf *buf) } } -int -main(int argc, char *argv[]) +static void +test_sflow_main(int argc, char *argv[]) { struct unixctl_server *server; enum { MAX_RECV = 1500 }; @@ -498,8 +666,9 @@ main(int argc, char *argv[]) int error; int sock; - proctitle_init(argc, argv); + ovs_cmdl_proctitle_init(argc, argv); set_program_name(argv[0]); + service_start(&argc, &argv); parse_options(argc, argv); if (argc - optind != 1) { @@ -508,13 +677,13 @@ main(int argc, char *argv[]) } target = argv[optind]; - sock = inet_open_passive(SOCK_DGRAM, target, 0, NULL, 0); + sock = inet_open_passive(SOCK_DGRAM, target, 0, NULL, 0, true); if (sock < 0) { - ovs_fatal(0, "%s: failed to open (%s)", argv[1], strerror(-sock)); + ovs_fatal(0, "%s: failed to open (%s)", target, ovs_strerror(-sock)); } daemon_save_fd(STDOUT_FILENO); - daemonize_start(); + daemonize_start(false); error = unixctl_server_create(NULL, &server); if (error) { @@ -532,7 +701,7 @@ main(int argc, char *argv[]) ofpbuf_clear(&buf); do { - retval = read(sock, buf.data, buf.allocated); + retval = recv(sock, buf.data, buf.allocated, 0); } while (retval < 0 && errno == EINTR); if (retval > 0) { ofpbuf_put_uninit(&buf, retval); @@ -548,23 +717,23 @@ main(int argc, char *argv[]) unixctl_server_wait(server); poll_block(); } - - return 0; } static void parse_options(int argc, char *argv[]) { enum { - DAEMON_OPTION_ENUMS + DAEMON_OPTION_ENUMS, + VLOG_OPTION_ENUMS }; - static struct option long_options[] = { + static const struct option long_options[] = { {"verbose", optional_argument, NULL, 'v'}, {"help", no_argument, NULL, 'h'}, DAEMON_LONG_OPTIONS, + VLOG_LONG_OPTIONS, {NULL, 0, NULL, 0}, }; - char *short_options = long_options_to_short_options(long_options); + char *short_options = ovs_cmdl_long_options_to_short_options(long_options); for (;;) { int c = getopt_long(argc, argv, short_options, long_options, NULL); @@ -576,11 +745,8 @@ parse_options(int argc, char *argv[]) case 'h': usage(); - case 'v': - vlog_set_verbosity(optarg); - break; - - DAEMON_OPTION_HANDLERS + DAEMON_OPTION_HANDLERS + VLOG_OPTION_HANDLERS case '?': exit(EXIT_FAILURE); @@ -616,3 +782,5 @@ test_sflow_exit(struct unixctl_conn *conn, *exiting = true; unixctl_command_reply(conn, NULL); } + +OVSTEST_REGISTER("test-sflow", test_sflow_main);