LCOV - code coverage report
Current view: top level - ofproto - collectors.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 32 37 86.5 %
Date: 2016-09-14 01:02:56 Functions: 5 5 100.0 %
Branches: 17 28 60.7 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (c) 2008, 2009, 2010, 2011, 2013, 2014 Nicira, Inc.
       3                 :            :  *
       4                 :            :  * Licensed under the Apache License, Version 2.0 (the "License");
       5                 :            :  * you may not use this file except in compliance with the License.
       6                 :            :  * You may obtain a copy of the License at:
       7                 :            :  *
       8                 :            :  *     http://www.apache.org/licenses/LICENSE-2.0
       9                 :            :  *
      10                 :            :  * Unless required by applicable law or agreed to in writing, software
      11                 :            :  * distributed under the License is distributed on an "AS IS" BASIS,
      12                 :            :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      13                 :            :  * See the License for the specific language governing permissions and
      14                 :            :  * limitations under the License.
      15                 :            :  */
      16                 :            : 
      17                 :            : #include <config.h>
      18                 :            : 
      19                 :            : #include "collectors.h"
      20                 :            : 
      21                 :            : #include <errno.h>
      22                 :            : #include <stdlib.h>
      23                 :            : #include <sys/socket.h>
      24                 :            : #include <unistd.h>
      25                 :            : 
      26                 :            : #include "socket-util.h"
      27                 :            : #include "sset.h"
      28                 :            : #include "util.h"
      29                 :            : #include "openvswitch/vlog.h"
      30                 :            : 
      31                 :       1288 : VLOG_DEFINE_THIS_MODULE(collectors);
      32                 :            : 
      33                 :            : struct collectors {
      34                 :            :     int *fds;                     /* Sockets. */
      35                 :            :     size_t n_fds;                 /* Number of sockets. */
      36                 :            : };
      37                 :            : 
      38                 :            : /* Opens the targets specified in 'targets' for sending UDP packets.  This is
      39                 :            :  * useful for e.g. sending NetFlow or sFlow packets.  Returns 0 if successful,
      40                 :            :  * otherwise a positive errno value if opening at least one collector failed.
      41                 :            :  *
      42                 :            :  * Each target in 'targets' should be a string in the format "<host>[:<port>]".
      43                 :            :  * <port> may be omitted if 'default_port' is nonzero, in which case it
      44                 :            :  * defaults to 'default_port'.
      45                 :            :  *
      46                 :            :  * '*collectorsp' is set to a null pointer if no targets were successfully
      47                 :            :  * added, otherwise to a new collectors object if at least one was successfully
      48                 :            :  * added.  Thus, even on a failure return, it is possible that '*collectorsp'
      49                 :            :  * is nonnull, and even on a successful return, it is possible that
      50                 :            :  * '*collectorsp' is null, if 'target's is an empty sset. */
      51                 :            : int
      52                 :         17 : collectors_create(const struct sset *targets, uint16_t default_port,
      53                 :            :                   struct collectors **collectorsp)
      54                 :            : {
      55                 :            :     struct collectors *c;
      56                 :            :     const char *name;
      57                 :         17 :     int retval = 0;
      58                 :            : 
      59                 :         17 :     c = xmalloc(sizeof *c);
      60                 :         17 :     c->fds = xmalloc(sizeof *c->fds * sset_count(targets));
      61                 :         17 :     c->n_fds = 0;
      62 [ +  - ][ -  + ]:         34 :     SSET_FOR_EACH (name, targets) {
                 [ +  + ]
      63                 :            :         int error;
      64                 :            :         int fd;
      65                 :            : 
      66                 :         17 :         error = inet_open_active(SOCK_DGRAM, name, default_port, NULL, &fd, 0);
      67         [ +  - ]:         17 :         if (fd >= 0) {
      68                 :         17 :             c->fds[c->n_fds++] = fd;
      69                 :            :         } else {
      70                 :            :             static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
      71                 :            : 
      72         [ #  # ]:          0 :             VLOG_WARN_RL(&rl, "couldn't open connection to collector %s (%s)",
      73                 :            :                          name, ovs_strerror(error));
      74         [ #  # ]:          0 :             if (!retval) {
      75                 :          0 :                 retval = error;
      76                 :            :             }
      77                 :            :         }
      78                 :            :     }
      79                 :            : 
      80         [ +  - ]:         17 :     if (c->n_fds) {
      81                 :         17 :         *collectorsp = c;
      82                 :            :     } else {
      83                 :          0 :         collectors_destroy(c);
      84                 :          0 :         *collectorsp = NULL;
      85                 :            :     }
      86                 :            : 
      87                 :         17 :     return retval;
      88                 :            : }
      89                 :            : 
      90                 :            : /* Destroys 'c'. */
      91                 :            : void
      92                 :         51 : collectors_destroy(struct collectors *c)
      93                 :            : {
      94         [ +  + ]:         51 :     if (c) {
      95                 :            :         size_t i;
      96                 :            : 
      97         [ +  + ]:         22 :         for (i = 0; i < c->n_fds; i++) {
      98                 :         11 :             closesocket(c->fds[i]);
      99                 :            :         }
     100                 :         11 :         free(c->fds);
     101                 :         11 :         free(c);
     102                 :            :     }
     103                 :         51 : }
     104                 :            : 
     105                 :            : /* Sends the 'n'-byte 'payload' to each of the collectors in 'c'.
     106                 :            :  * Return the number of IPFIX packets which were sent unsuccessfully*/
     107                 :            : size_t
     108                 :         89 : collectors_send(const struct collectors *c, const void *payload, size_t n)
     109                 :            : {
     110                 :         89 :     size_t errors = 0;
     111                 :            : 
     112         [ +  - ]:         89 :     if (c) {
     113                 :            :         size_t i;
     114                 :            : 
     115         [ +  + ]:        178 :         for (i = 0; i < c->n_fds; i++) {
     116                 :            :             static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
     117         [ +  + ]:         89 :             if (send(c->fds[i], payload, n, 0) == -1) {
     118                 :         30 :                 char *s = describe_fd(c->fds[i]);
     119         [ +  - ]:         30 :                 VLOG_WARN_RL(&rl, "%s: sending to collector failed (%s)",
     120                 :            :                              s, ovs_strerror(errno));
     121                 :         30 :                 free(s);
     122                 :         30 :                 errors++;
     123                 :            :             }
     124                 :            :         }
     125                 :            :     }
     126                 :            : 
     127                 :         89 :     return errors;
     128                 :            : }
     129                 :            : 
     130                 :            : int
     131                 :         62 : collectors_count(const struct collectors *c)
     132                 :            : {
     133         [ +  - ]:         62 :     return c ? c->n_fds : 0;
     134                 :            : }

Generated by: LCOV version 1.12