--- ofproto/ofproto-dpif-sflow.c | 52 +++++++++++++++++++++++++++++++++++------ 1 files changed, 44 insertions(+), 8 deletions(-)
diff --git a/ofproto/ofproto-dpif-sflow.c b/ofproto/ofproto-dpif-sflow.c index d17b0be..e22c89d 100644 --- a/ofproto/ofproto-dpif-sflow.c +++ b/ofproto/ofproto-dpif-sflow.c @@ -18,6 +18,7 @@ #include <config.h> #include "ofproto-dpif-sflow.h" #include <inttypes.h> +#include <net/if.h> #include <stdlib.h> #include "collectors.h" #include "compiler.h" @@ -30,6 +31,7 @@ #include "ofproto.h" #include "packets.h" #include "poll-loop.h" +#include "route-table.h" #include "sflow_api.h" #include "socket-util.h" #include "timeval.h" @@ -225,7 +227,9 @@ sflow_agent_get_counters(void *ds_, SFLPoller *poller, * 'agent_device' is used if it has one, and otherwise 'control_ip', the IP * address used to talk to the controller. */ static bool -sflow_choose_agent_address(const char *agent_device, const char *control_ip, +sflow_choose_agent_address(const char *agent_device, + const struct sset *targets, + const char *control_ip, SFLAddress *agent_addr) { struct in_addr in4; @@ -239,10 +243,37 @@ sflow_choose_agent_address(const char *agent_device, const char *control_ip, if (!netdev_open(agent_device, "system", &netdev)) { int error = netdev_get_in4(netdev, &in4, NULL); netdev_close(netdev); + if (!error) { goto success; } } + } else if (!sset_is_empty(targets)) { + const char *target = NULL; + struct sockaddr_in target_addr; + ovs_be32 target_ip = 0; + uint16_t default_port = SFL_DEFAULT_COLLECTOR_PORT; + char name[IFNAMSIZ]; + + SSET_FOR_EACH (target, targets) { + if (inet_parse_active(target, default_port, &target_addr)) { + target_ip = target_addr.sin_addr.s_addr; + continue; + } + } + + if (target_ip && route_table_get_name(target_ip, name)) { + struct netdev *netdev; + + if (!netdev_open(name, "system", &netdev)) { + int error = netdev_get_in4(netdev, &in4, NULL); + netdev_close(netdev); + + if (!error) { + goto success; + } + } + } } if (control_ip && !lookup_ip(control_ip, &in4)) { @@ -289,6 +320,8 @@ dpif_sflow_create(struct dpif *dpif) ds->next_tick = time_now() + 1; hmap_init(&ds->ports); ds->probability = 0; + route_table_register(); + return ds; } @@ -307,6 +340,7 @@ dpif_sflow_destroy(struct dpif_sflow *ds) if (ds) { struct dpif_sflow_port *dsp, *next; + route_table_unregister(); dpif_sflow_clear(ds); HMAP_FOR_EACH_SAFE (dsp, next, hmap_node, &ds->ports) { dpif_sflow_del_port__(ds, dsp); @@ -430,6 +464,14 @@ dpif_sflow_set_options(struct dpif_sflow *ds, } } + /* Choose agent IP address and agent device (if not yet setup) */ + if (!sflow_choose_agent_address(options->agent_device, + &options->targets, + options->control_ip, &agentIP)) { + dpif_sflow_clear(ds); + return; + } + /* Avoid reconfiguring if options didn't change. */ if (!options_changed) { return; @@ -437,13 +479,6 @@ dpif_sflow_set_options(struct dpif_sflow *ds, ofproto_sflow_options_destroy(ds->options); ds->options = ofproto_sflow_options_clone(options); - /* Choose agent IP address. */ - if (!sflow_choose_agent_address(options->agent_device, - options->control_ip, &agentIP)) { - dpif_sflow_clear(ds); - return; - } - /* Create agent. */ VLOG_INFO("creating sFlow agent %d", options->sub_id); if (ds->sflow_agent) { @@ -572,6 +607,7 @@ dpif_sflow_run(struct dpif_sflow *ds) { if (dpif_sflow_is_enabled(ds)) { time_t now = time_now(); + route_table_run(); if (now >= ds->next_tick) { sfl_agent_tick(ds->sflow_agent, time_wall()); ds->next_tick = now + 1; -- 1.7.2.5 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev