Exemple #1
0
/* ARGSUSED */
static int
show_flow_stats(dladm_handle_t handle, dladm_flow_attr_t *attr, void *arg)
{
	show_flow_state_t	*state = (show_flow_state_t *)arg;
	char			*name = attr->fa_flowname;
	pktsum_t		stats, diff_stats;
	flow_args_t		fargs;

	if (state->fs_firstonly) {
		if (state->fs_donefirst)
			return (DLADM_WALK_TERMINATE);
		state->fs_donefirst = B_TRUE;
	} else {
		bzero(&state->fs_prevstats, sizeof (state->fs_prevstats));
	}

	get_flow_stats(name, &stats);
	dladm_stats_diff(&diff_stats, &stats, &state->fs_prevstats);

	fargs.flow_s_flow = name;
	fargs.flow_s_psum = &diff_stats;
	ofmt_print(state->fs_ofmt, (void *)&fargs);
	state->fs_prevstats = stats;

	return (DLADM_WALK_CONTINUE);
}
static char *
parse_dump_flows( char *cmd, const uint64_t own_datapath_id ) {
  if ( prefixcmp( cmd, "dump_flows" ) ) {
    return NULL;
  }
  char *opt = strchr ( cmd, ' ' );
  assert( opt );

  uint64_t datapath_val;
  uint32_t in_port_val;
  uint16_t eth_type_val;
  uint8_t ip_proto_val;
  uint64_t metadata_val[ 2 ];
  uint16_t udp_src_val;
  uint16_t udp_dst_val;
  uint8_t table_id_val;
  uint32_t out_port_val;
  uint32_t out_group_val;
  uint64_t cookie_val[ 2 ];


  struct option opts[] = {
    OPT_UINT64( "--datapath_id", "datapath_id:", OPT_NO_MASK, &datapath_val ),
    OPT_UINT32( "--in_port", "in_port:", OPT_NO_MASK, &in_port_val ),
    OPT_UINT16( "--eth_type", "eth_type:", OPT_NO_MASK, &eth_type_val ),
    OPT_UINT8( "--ip_proto", "ip_proto:", OPT_NO_MASK, &ip_proto_val ),
    OPT_UINT64( "--metadata", "metadata:", OPT_HAS_MASK, &metadata_val ),
    OPT_UINT16( "--udp_src", "udp_src:", OPT_NO_MASK, &udp_src_val ),
    OPT_UINT16( "--udp_dst", "udp_dst:", OPT_NO_MASK, &udp_dst_val ),
    OPT_UINT8( "--table_id", "table_id:", OPT_NO_MASK, &table_id_val ),
    OPT_UINT64( "--cookie", "cookie:", OPT_HAS_MASK, &cookie_val ),
    OPT_UINT32( "--out_port", "out_port:", OPT_NO_MASK, &out_port_val ),
    OPT_UINT32( "--out_group", "out_group:", OPT_NO_MASK, &out_group_val ),
    OPT_END()
  };

  
  char *saveptr;
  const char *sep = " ";

  for ( opt = strtok_r( opt, sep, &saveptr ); opt; opt = strtok_r( NULL, sep, &saveptr ) ) {
    parse_option( opt, opts );
    if ( *( uint64_t * ) opts[ 0 ].value != own_datapath_id ) {
      return NULL;
    }
  }
  match *match = create_match();
  parse_match( match, opts );

  flow_stats *stats = NULL;
  uint32_t nr_stats;
  OFDPE ret = get_flow_stats( ( uint8_t ) table_id_val, match, cookie_val[ 0 ], cookie_val[ 1 ], out_port_val, out_group_val, &stats, &nr_stats );
  if ( ret != OFDPE_SUCCESS ) {
    error( "Failed to retrieve flow stats from datapath ( ret = %d ).", ret );
  }
  delete_match( match );
  
  char *reply_buf = xmalloc( PATH_MAX + 1 );
  reply_buf[ 0 ] = '\0';
  size_t used = 0;
  int left;
  const char *term = ",";
  const char *orig = "{ \"dump_flows\": [";
  if ( stats != NULL && nr_stats ) {
    for ( uint32_t i = 0; i < nr_stats; i++ ) {
      if ( i != 0 ) {
        orig = "";
      }
      if ( i == nr_stats - 1 ) {
        term = "]}";
      }
      left = snprintf( reply_buf + used, PATH_MAX - used, "%s {" DUMP_FLOW_FIELDS "} %s",
                       orig,
                       stats->table_id,
                       stats->duration_sec,
                       stats->priority,
                       stats->idle_timeout,
                       stats->hard_timeout, 
                       stats->flags,
                       stats->cookie,
                       stats->packet_count,
                       stats->byte_count,
                       term );
      used = ( size_t ) left - used;
      stats++;
    }
  }

  return reply_buf;
}
  size_t match_len = 0;
  if ( ofp_match != NULL ) {
    match_len = ofp_match->length - offsetof( struct ofp_match, oxm_fields );
    // translate the ofp_match to datapath match.
    const oxm_match_header *hdr = ( const oxm_match_header * ) ofp_match->oxm_fields;
    while ( match_len > 0 ) {
      assign_match( flow_match, hdr );
      match_len -= ( sizeof( *hdr ) + OXM_LENGTH( *hdr ) );
      if ( match_len > 0 ) {
        hdr = ( const oxm_match_header * ) ( ( const char * ) hdr + sizeof( *hdr ) + OXM_LENGTH( *hdr ) );
      }
    }
  }

  flow_stats *stats = NULL;
  OFDPE ret = get_flow_stats( table_id, flow_match, cookie, cookie_mask, out_port, out_group, &stats, nr_stats );
  if ( ret != OFDPE_SUCCESS ) {
    error( "Failed to retrieve flow stats from datapath ( ret = %d ).", ret );
  }
  delete_match( flow_match );

  return stats;
}


static uint16_t
bucket_list_length( bucket_list **list ) {
  if ( *list == NULL ) {
    return 0;
  }
  uint16_t length = 0;