INADDR_ANY in pflow(4)

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

INADDR_ANY in pflow(4)

Florian Obser-2
Since no one presented a case why sending from INADDR_ANY is a good
thing[tm], make it clear that it won't work.

The ifconfig(8) diff generates this output:
$ sudo ifconfig pflow0 up
$ ifconfig pflow0
pflow0: flags=1<UP> mtu 1492
        priority: 0
        pflow: sender: INVALID receiver: INVALID:INVALID version: 5
        groups: pflow

Comments/OK?

(While there make the SIOCSIFFLAGS and SIOCSETPFLOW cases symetric by
only sending templates if the interface is running, this doesn't
change behaviour because the pflow_sendout_{v9,ipfix}_tmpl functions
are checking for running themself.)

diff --git sbin/ifconfig/ifconfig.8 sbin/ifconfig/ifconfig.8
index 9e43660..fa65426 100644
--- sbin/ifconfig/ifconfig.8
+++ sbin/ifconfig/ifconfig.8
@@ -1224,11 +1224,12 @@ Pflow data will be sent to this address/port.
 Unset the receiver address and stop sending pflow data.
 .It Cm flowsrc Ar addr
 Set the source IP address for pflow packets.
+Must be defined to export pflow data.
 .Ar addr
 is the IP address used as sender of the UDP packets and may be used to
 identify the source of the data on the pflow collector.
 .It Fl flowsrc
-Unset the source address.
+Unset the source address and stop sending pflow data.
 .It Cm pflowproto Ar n
 Set the protocol version.
 The default is version 5.
diff --git sbin/ifconfig/ifconfig.c sbin/ifconfig/ifconfig.c
index da03a75..1351319 100644
--- sbin/ifconfig/ifconfig.c
+++ sbin/ifconfig/ifconfig.c
@@ -3808,9 +3808,14 @@ pflow_status(void)
  if (ioctl(s, SIOCGETPFLOW, (caddr_t)&ifr) == -1)
  return;
 
- printf("\tpflow: sender: %s ", inet_ntoa(preq.sender_ip));
- printf("receiver: %s:%u ", inet_ntoa(preq.receiver_ip),
-    ntohs(preq.receiver_port));
+ printf("\tpflow: sender: %s ", preq.sender_ip.s_addr != INADDR_ANY ?
+    inet_ntoa(preq.sender_ip) : "INVALID");
+ printf("receiver: %s:", preq.receiver_ip.s_addr != INADDR_ANY ?
+    inet_ntoa(preq.receiver_ip) : "INVALID");
+ if (preq.receiver_port == 0)
+ printf("%s ", "INVALID");
+ else
+ printf("%u ", ntohs(preq.receiver_port));
  printf("version: %d\n", preq.version);
 }
 
diff --git share/man/man4/pflow.4 share/man/man4/pflow.4
index 8b0e74b..6500888 100644
--- share/man/man4/pflow.4
+++ share/man/man4/pflow.4
@@ -42,8 +42,8 @@ Multiple
 interfaces can be created at runtime using the
 .Ic ifconfig pflow Ns Ar N Ic create
 command.
-Each interface must be configured with a flow receiver IP address and
-port number.
+Each interface must be configured with flow sender IP address and a flow
+receiver IP address and port number.
 .Pp
 Only states created by a rule marked with the
 .Ar pflow
@@ -91,6 +91,8 @@ collector.
 .Cm flowdst
 defines the collector IP address and the port.
 The
+.Cm flowsrc
+IP address and
 .Cm flowdst
 IP address and port must be defined to enable the export of flows.
 .Pp
diff --git sys/net/if_pflow.c sys/net/if_pflow.c
index ba51cb1..0f026f9 100644
--- sys/net/if_pflow.c
+++ sys/net/if_pflow.c
@@ -151,7 +151,7 @@ pflow_clone_create(struct if_clone *ifc, int unit)
     (sizeof(struct in_multi *) * IP_MIN_MEMBERSHIPS), M_IPMOPTS,
     M_WAITOK|M_ZERO);
  pflowif->sc_imo.imo_max_memberships = IP_MIN_MEMBERSHIPS;
- pflowif->sc_receiver_ip.s_addr = 0;
+ pflowif->sc_receiver_ip.s_addr = INADDR_ANY;
  pflowif->sc_receiver_port = 0;
  pflowif->sc_sender_ip.s_addr = INADDR_ANY;
  pflowif->sc_sender_port = pflow_get_dynport();
@@ -428,8 +428,10 @@ pflowioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
  case SIOCSIFDSTADDR:
  case SIOCSIFFLAGS:
  if ((ifp->if_flags & IFF_UP) &&
-    sc->sc_receiver_ip.s_addr != 0 &&
-    sc->sc_receiver_port != 0) {
+    sc->sc_receiver_ip.s_addr != INADDR_ANY &&
+    sc->sc_receiver_port != 0 &&
+    sc->sc_sender_ip.s_addr != INADDR_ANY &&
+    sc->sc_sender_port != 0) {
  ifp->if_flags |= IFF_RUNNING;
  sc->sc_gcounter=pflowstats.pflow_flows;
  /* send templates on startup */
@@ -491,7 +493,7 @@ pflowioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
  pflow_flush(sc);
 
  if (pflowr.addrmask & PFLOW_MASK_DSTIP)
- sc->sc_receiver_ip = pflowr.receiver_ip;
+ sc->sc_receiver_ip.s_addr = pflowr.receiver_ip.s_addr;
  if (pflowr.addrmask & PFLOW_MASK_DSTPRT)
  sc->sc_receiver_port = pflowr.receiver_port;
  if (pflowr.addrmask & PFLOW_MASK_SRCIP)
@@ -503,18 +505,24 @@ pflowioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
  pflow_setmtu(sc, ETHERMTU);
  pflow_init_timeouts(sc);
 
- if (sc->sc_version == PFLOW_PROTO_9)
- pflow_sendout_v9_tmpl(sc);
- else if (sc->sc_version == PFLOW_PROTO_10)
- pflow_sendout_ipfix_tmpl(sc);
-
  splx(s);
 
  if ((ifp->if_flags & IFF_UP) &&
-    sc->sc_receiver_ip.s_addr != 0 &&
-    sc->sc_receiver_port != 0) {
+    sc->sc_receiver_ip.s_addr != INADDR_ANY &&
+    sc->sc_receiver_port != 0 &&
+    sc->sc_sender_ip.s_addr != INADDR_ANY &&
+    sc->sc_sender_port != 0) {
  ifp->if_flags |= IFF_RUNNING;
  sc->sc_gcounter=pflowstats.pflow_flows;
+ if (sc->sc_version == PFLOW_PROTO_9) {
+ s = splnet();
+ pflow_sendout_v9_tmpl(sc);
+ splx(s);
+ } else if (sc->sc_version == PFLOW_PROTO_10) {
+ s = splnet();
+ pflow_sendout_ipfix_tmpl(sc);
+ splx(s);
+ }
  } else
  ifp->if_flags &= ~IFF_RUNNING;
 
--
I'm not entirely sure you are real.