Ejemplo n.º 1
0
static void ci_bonding_get_mcast_subs_entry_fn(ci_dllist* subscriptions,
                                               char* line, int line_len, 
                                               void* arg)
{
  struct ci_read_proc_net_igmp_state* state = 
    (struct ci_read_proc_net_igmp_state*)arg;
  struct ci_bonding_mcast_subscription *sub;
  int len, ifindex;

  if( state->in_right_netdev ) {
    if( line[0] >= '0' && line[0] <= '9' )
      /* Assume that if we were in the right net dev block and a new
       * block starts the new block is for a different net dev and so
       * no longer the right one.
       */
      state->in_right_netdev = 0;
    else {
      /* Line should represent state of each maddr */
      sub = kmalloc(sizeof(struct ci_bonding_mcast_subscription), GFP_KERNEL);
      if( sub != NULL ) {
        len = sscanf(line, " %x", &sub->maddr);
       /* TODO parse line further to generate more state here? */
        if( len == 1 ) {
          ci_dllist_push(subscriptions, &sub->list_link);
          OO_DEBUG_BONDING(ci_log("Found maddr %x for net dev %d", 
                                  sub->maddr, state->ifindex));

        } else {
          kfree(sub);
          OO_DEBUG_BONDING(ci_log("Parse error (1) in line %s", line));
        }
      }
    }
  } 
  else if( line[0] >= '0' && line[0] <= '9' ) {
    /* Start of new device block */
    len = sscanf(line, "%d", &ifindex);
    if( len == 1 ) {
      if( ifindex == state->ifindex )
        state->in_right_netdev = 1;
    }
    else 
      OO_DEBUG_BONDING(ci_log("Parse error (2) in line %s", line));
  }
}
Ejemplo n.º 2
0
static void ci_bonding_get_ifnames_entry_fn(ci_dllist* iflist, char* line, 
                                            int line_len, void *arg)
{
  char *next;
  struct ci_bonding_ifname *ifname;

  do {
    ifname = kmalloc(sizeof(struct ci_bonding_ifname), GFP_KERNEL);

    if( ifname == NULL)
      return;
    
    ci_assert(line != NULL);
    ci_assert(line_len);

    while( line_len > 0 && (*line == '\n' || *line == ' ' || *line == '\0') ) {
      ++line;
      --line_len;
    }

    if( line_len == 0 )
      return;

    next = strnchr(line, line_len, ' ');

    if( next != NULL ) {
      ci_assert(next - line <= IFNAMSIZ);
      strncpy(ifname->ifname, line, next - line);
      ifname->ifname[next - line] = '\0';
      next++; // move over space 
      line_len -= (next - line);
    }
    else {
      strncpy(ifname->ifname, line, IFNAMSIZ);
      line_len = 0;
    }

    ci_dllist_push(iflist, &ifname->list_link);

    line = next;
  } while (line != NULL);
}
Ejemplo n.º 3
0
/* This function assumes an option of the same form and types as
 * EF_TCP_FORCE_REUSEPORT
 */
static void get_env_opt_port_list(ci_uint64* opt, const char* name)
{
  char *s;
  unsigned v;
  if( (s = getenv(name)) ) {
    /* The memory used for this list is never freed, as we need it
     * persist until the process terminates 
     */
    *opt = (ci_uint64)(ci_uintptr_t)malloc(sizeof(ci_dllist));
    if( ! *opt )
      log("Could not allocate memory for %s list", name);
    else {
      struct ci_port_list *curr;
      ci_dllist *opt_list = (ci_dllist*)(ci_uintptr_t)*opt;
      ci_dllist_init(opt_list);

      while( sscanf(s, "%u", &v) == 1 ) {
        curr = malloc(sizeof(struct ci_port_list));
        if( ! curr ) {
          log("Could not allocate memory for %s list entry", name);
          break;
        }
        curr->port = v;
        if( curr->port != v ) {
          log("ERROR: %s contains value that is too large: %u", name, v);
          free(curr);
        }
        else {
          curr->port = htons(curr->port);
          ci_dllist_push(opt_list, &curr->link);
        }
        s = strchr(s, ',');
        if( s == NULL )
          break;
        s++;
      }
    }
  }
}
Ejemplo n.º 4
0
static void 
ci_bonding_get_lacp_active_slaves_entry_fn(ci_dllist* active_slaves,
                                           char* line, int line_len, 
                                           void* arg)
{
  int n, agg_id;
  char slave_name[IFNAMSIZ];
  struct ci_bonding_ifname *ifname;
  struct ci_read_proc_net_bonding_state* state = 
    (struct ci_read_proc_net_bonding_state*)arg;

  n = sscanf(line, " Aggregator ID: %d", &agg_id);

  if( n == 1 ) {
    if( state->agg_id == -1 )
      state->agg_id = agg_id;
    else {
      if( state->current_slave[0] != '\0' ) {
        if( state->agg_id == agg_id ) {
          ifname = kmalloc(sizeof(struct ci_bonding_ifname), GFP_KERNEL);
          if( ifname != NULL ) {
            strcpy(ifname->ifname, state->current_slave);
            ci_dllist_push(active_slaves, &ifname->list_link);
          }
        }
        state->current_slave[0] = '\0';
      }
      else {
        OO_DEBUG_BONDING(ci_log("Aggregator ID found without known slave"));
      }
    }
  }
  else {
    n = sscanf(line, "Slave Interface: %s", slave_name);
    if( n == 1 )
      strcpy(state->current_slave, slave_name);
  }
}
Ejemplo n.º 5
0
int  ci_buddy_ctor2(ci_buddy_allocator* b, unsigned order,
		    void* (*alloc_fn)(size_t), void (*free_fn)(void*))
{
  unsigned o;

  ci_assert(b);

  b->order = order;
  b->free_lists = (ci_dllist*) alloc_fn((order+1) * sizeof(ci_dllist));
  if( b->free_lists == 0 )  goto fail1;

  b->links = (ci_dllink*) alloc_fn(ci_pow2(order) * sizeof(ci_dllink));
  if( b->links == 0 )  goto fail2;

  b->orders = (ci_uint8*) alloc_fn(ci_pow2(order));
  if( b->orders == 0 )  goto fail3;

  CI_DEBUG(CI_ZERO_ARRAY(b->links, ci_pow2(order)));

  for( o = 0; o <= b->order; ++o )
    ci_dllist_init(b->free_lists + o);

  ci_dllist_push(FL(b, b->order), ADDR_TO_LINK(b, 0));
  ci_assert(b->order < 255);	
  b->orders[0] = (ci_uint8)b->order;

  ci_assert(!IS_BUSY(b, LINK_TO_ADDR(b, ci_dllist_head(FL(b, b->order)))));

  return 0;

 fail3:
  free_fn(b->links);
 fail2:
  free_fn(b->free_lists);
 fail1:
  return -ENOMEM;
}