Thanks for testing. I pushed this to master.
On Tue, Dec 06, 2011 at 01:38:16PM -0800, Luca Giraudo wrote: > It seems to work properly. No differences from the my patch. > > Luca > > On Tue, Dec 6, 2011 at 1:02 PM, Ben Pfaff <b...@nicira.com> wrote: > > > From: Luca Giraudo <lgira...@nicira.com> > > > > Bug #2407. > > --- > > Hi Luca, here's a version of your patch that I tweaked a bit. > > I assume that you have a test case for this feature? Will you > > please try this version of the patch out to verify that I did > > not break it? > > > > Thanks, > > > > Ben. > > > > diff --git a/AUTHORS b/AUTHORS > > index 994fc46..db482c0 100644 > > --- a/AUTHORS > > +++ b/AUTHORS > > @@ -26,6 +26,7 @@ Joe Perches j...@perches.com > > Jun Nakajima jun.nakaj...@intel.com > > Justin Pettit jpet...@nicira.com > > Keith Amidon ke...@nicira.com > > +Luca Giraudo lgira...@nicira.com > > Martin Casado cas...@nicira.com > > Natasha Gude nata...@nicira.com > > Neil McKee neil.mc...@inmon.com > > diff --git a/NEWS b/NEWS > > index 8d7addf..61b74dd 100644 > > --- a/NEWS > > +++ b/NEWS > > @@ -20,6 +20,8 @@ v1.4.0 - xx xxx xxxx > > now be properly mirrored for any flows, regardless of their > > actions. > > - Track packet and byte statistics sent on mirrors. > > + - The sFlow implementation can now usually infer the correct agent > > + device instead of having to be told explicitly. > > - ovs-appctl: > > - New "fdb/flush" command to flush bridge's MAC learning table. > > - ovs-test: > > diff --git a/lib/netdev.c b/lib/netdev.c > > index e77fcdf..eff6e4c 100644 > > --- a/lib/netdev.c > > +++ b/lib/netdev.c > > @@ -692,6 +692,26 @@ netdev_set_in4(struct netdev *netdev, struct in_addr > > addr, struct in_addr mask) > > : EOPNOTSUPP); > > } > > > > +/* Obtains ad IPv4 address from device name and save the address in > > + * in4. Returns 0 if successful, otherwise a positive errno value. > > + */ > > +int > > +netdev_get_in4_by_name(const char *device_name, struct in_addr *in4) > > +{ > > + struct netdev *netdev; > > + int error; > > + > > + error = netdev_open(device_name, "system", &netdev); > > + if (error) { > > + in4->s_addr = htonl(0); > > + return error; > > + } > > + > > + error = netdev_get_in4(netdev, in4, NULL); > > + netdev_close(netdev); > > + return error; > > +} > > + > > /* Adds 'router' as a default IP gateway for the TCP/IP stack that > > corresponds > > * to 'netdev'. */ > > int > > diff --git a/lib/netdev.h b/lib/netdev.h > > index 02271d4..24a9b64 100644 > > --- a/lib/netdev.h > > +++ b/lib/netdev.h > > @@ -131,6 +131,7 @@ int netdev_set_advertisements(struct netdev *, > > uint32_t advertise); > > int netdev_get_in4(const struct netdev *, struct in_addr *address, > > struct in_addr *netmask); > > int netdev_set_in4(struct netdev *, struct in_addr addr, struct in_addr > > mask); > > +int netdev_get_in4_by_name(const char *device_name, struct in_addr *in4); > > int netdev_get_in6(const struct netdev *, struct in6_addr *); > > int netdev_add_router(struct netdev *, struct in_addr router); > > int netdev_get_next_hop(const struct netdev *, const struct in_addr *host, > > diff --git a/ofproto/ofproto-dpif-sflow.c b/ofproto/ofproto-dpif-sflow.c > > index d17b0be..7dc6d28 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" > > @@ -223,25 +225,35 @@ sflow_agent_get_counters(void *ds_, SFLPoller > > *poller, > > * The sFlow agent address should be a local IP address that is persistent > > and > > * reachable over the network, if possible. The IP address associated with > > * 'agent_device' is used if it has one, and otherwise 'control_ip', the IP > > - * address used to talk to the controller. */ > > + * address used to talk to the controller. If the agent device is not > > + * specified then it is figured out by taking a look at the routing table > > based > > + * on 'targets'. */ > > 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) > > { > > + const char *target; > > struct in_addr in4; > > > > memset(agent_addr, 0, sizeof *agent_addr); > > agent_addr->type = SFLADDRESSTYPE_IP_V4; > > > > if (agent_device) { > > - struct netdev *netdev; > > - > > - if (!netdev_open(agent_device, "system", &netdev)) { > > - int error = netdev_get_in4(netdev, &in4, NULL); > > - netdev_close(netdev); > > - if (!error) { > > - goto success; > > - } > > + if (!netdev_get_in4_by_name(agent_device, &in4)) { > > + goto success; > > + } > > + } > > + > > + SSET_FOR_EACH (target, targets) { > > + struct sockaddr_in sin; > > + char name[IFNAMSIZ]; > > + > > + if (inet_parse_active(target, SFL_DEFAULT_COLLECTOR_PORT, &sin) > > + && route_table_get_name(sin.sin_addr.s_addr, name) > > + && !netdev_get_in4_by_name(name, &in4)) { > > + goto success; > > } > > } > > > > @@ -289,6 +301,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 +321,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 +445,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 +460,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 +588,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; > > diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml > > index 51309bf..84d91da 100644 > > --- a/vswitchd/vswitch.xml > > +++ b/vswitchd/vswitch.xml > > @@ -2771,10 +2771,12 @@ > > > > <column name="agent"> > > Name of the network device whose IP address should be reported as the > > - ``agent address'' to collectors. If not specified, the IP address > > + ``agent address'' to collectors. If not specified, the agent > > device is > > + figured from the first target address and the routing table. If the > > + routing table does not contain a route to the target, the IP address > > defaults to the <ref table="Controller" column="local_ip"/> in the > > collector's <ref table="Controller"/>. If an agent IP address > > cannot be > > - determined either way, sFlow is disabled. > > + determined any of these ways, sFlow is disabled. > > </column> > > > > <column name="header"> > > -- > > 1.7.4.4 > > > > _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev