On Dec 6, 2011, at 2:18 PM, Luca Giraudo wrote:
> Hi Neil,
> replies in-line.
>
> On Tue, Dec 6, 2011 at 1:43 PM, Neil Mckee <[email protected]> wrote:
> Hi Luca,
>
> Just checking.... does this mean that the sFlow-agent-address might change
> just because the first collector in the list changed? Or because there was a
> routing change and the packet path to the collector went out a different
> interface?
>
> I think you are right in the first case: if the first collector changes and
> if the sflow agent is reconfigured then you may have a different agent
> address if the outgoing interface/bridge is different from the previous one
> (i.e. collectors not in the same subnet or different routing). You are
> partially right in the second case (it should be a different interface on a
> different OVS bridge, since the IP address is assigned to the bridge)
>
>
> The primary purpose of the sflow-agent-address is to provide a persistent
> identifier. One that can be used as a key to store the data under. It's
> helpful if that is also an address that can be talked to, but connectivity
> is not the main thing. The main thing is for it to stay the same across
> reboots, routing-changes and collector-changes.
>
> It sounds like you can still set this address explicitly, which is good,
> but if you are choosing one on the fly then please consider ways to make that
> decision as "sticky" as possible. For example, one approach is to select
> the lowest-numbered loopback-address (if there are any) and fall back on the
> lowest numbered interface address (perhaps preferring IPv4 addresses over
> IPv6 addresses). Another approach is to choose one any way you like, but
> then keep it the same for as long as that IP belongs to the switch.
>
> The previous configuration method works as before (agent address or
> controller address) so the persistence is maintained. Regarding your
> suggestion, eventually we can choose firstly the control_ip as the agent
> address and then the outgoing interface as the last resource to make the
> selection more "sticky". What do you think?
That would certainly be an improvement.
It still seems like it might fluctuate in the case where the control_ip is not
set, but I don't have a feel for how often that will happen? (Or, more
specifically, how often that will happen in a switch where there really are
multiple IP's to choose from.)
Neil
>
> Luca
>
>
> Neil
>
>
>
> On Dec 6, 2011, at 12:42 PM, Luca Giraudo wrote:
>
> > ---
> > NEWS | 3 ++
> > lib/netdev.c | 21 +++++++++++++++
> > lib/netdev.h | 1 +
> > ofproto/ofproto-dpif-sflow.c | 56
> > +++++++++++++++++++++++++++++++----------
> > vswitchd/vswitch.xml | 4 ++-
> > 5 files changed, 70 insertions(+), 15 deletions(-)
> >
> > diff --git a/NEWS b/NEWS
> > index 8d7addf..6dc6a3a 100644
> > --- a/NEWS
> > +++ b/NEWS
> > @@ -26,6 +26,9 @@ v1.4.0 - xx xxx xxxx
> > - A new distributed testing tool that allows one to diagnose
> > performance
> > and connectivity issues. This tool currently is not included in RH
> > or
> > Xen packages.
> > + - ovs-vsctl:
> > + - sFlow configuration without "agent" parameter in the case the
> > routing
> > + table contains a route to the first sFlow target in the list.
> > - RHEL packaging now supports integration with Red Hat network scripts.
> >
> >
> > diff --git a/lib/netdev.c b/lib/netdev.c
> > index e77fcdf..053bf48 100644
> > --- a/lib/netdev.c
> > +++ b/lib/netdev.c
> > @@ -692,6 +692,27 @@ 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
> > + true is successful, false on failure.
> > + */
> > +bool
> > +netdev_get_in4_by_name(const char *device_name, struct in_addr *in4)
> > +{
> > + struct netdev *netdev;
> > +
> > + int error = netdev_open(device_name, "system", &netdev);
> > + if (!error) {
> > + error = netdev_get_in4(netdev, in4, NULL);
> > + netdev_close(netdev);
> > +
> > + if(!error) {
> > + return true;
> > + }
> > + }
> > +
> > + return false;
> > +}
> > +
> > /* 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..10923b6 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);
> > +bool 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..a6c5517 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,9 +225,14 @@ 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 and at
> > target
> > + * list.
> > + */
> > 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;
> > @@ -234,12 +241,28 @@ sflow_choose_agent_address(const char *agent_device,
> > const char *control_ip,
> > agent_addr->type = SFLADDRESSTYPE_IP_V4;
> >
> > if (agent_device) {
> > - struct netdev *netdev;
> > + bool ret = netdev_get_in4_by_name(agent_device, &in4);
> > +
> > + if (ret == true) {
> > + goto success;
> > + }
> > + } else if (!sset_is_empty(targets)) {
> > + const char *target;
> > + ovs_be32 target_ip = 0;
> > + char name[IFNAMSIZ];
> > +
> > + SSET_FOR_EACH (target, targets) {
> > + struct sockaddr_in target_addr;
> > + if (inet_parse_active(target, SFL_DEFAULT_COLLECTOR_PORT,
> > &target_addr)) {
> > + target_ip = target_addr.sin_addr.s_addr;
> > + break;
> > + }
> > + }
> >
> > - if (!netdev_open(agent_device, "system", &netdev)) {
> > - int error = netdev_get_in4(netdev, &in4, NULL);
> > - netdev_close(netdev);
> > - if (!error) {
> > + if (target_ip && route_table_get_name(target_ip, name)) {
> > + bool ret = netdev_get_in4_by_name(name, &in4);
> > +
> > + if (ret == true) {
> > goto success;
> > }
> > }
> > @@ -289,6 +312,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 +332,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 +456,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 +471,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 +599,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..948e756 100644
> > --- a/vswitchd/vswitch.xml
> > +++ b/vswitchd/vswitch.xml
> > @@ -2771,7 +2771,9 @@
> >
> > <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.
> > --
> > 1.7.2.5
> >
> > _______________________________________________
> > dev mailing list
> > [email protected]
> > http://openvswitch.org/mailman/listinfo/dev
>
>
_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev