static void vrrp_vrid_handler(vector_t *strvec) { vrrp_t *vrrp = LIST_TAIL_DATA(vrrp_data->vrrp); vrrp->vrid = atoi(vector_slot(strvec, 1)); if (VRRP_IS_BAD_VID(vrrp->vrid)) { log_message(LOG_INFO, "VRRP Error : VRID not valid !"); log_message(LOG_INFO, " must be between 1 & 255. reconfigure !"); vrrp->vrid = 0; return; } alloc_vrrp_bucket(vrrp); }
static void vrrp_strict_mode_handler(vector_t *strvec) { int res; vrrp_t *vrrp = LIST_TAIL_DATA(vrrp_data->vrrp); if (vector_size(strvec) >= 2) { res = check_true_false(vector_slot(strvec, 1)); if (res >= 0) vrrp->strict_mode = res; else log_message(LOG_INFO, "(%s): invalid strict_mode %s specified", vrrp->iname, FMT_STR_VSLOT(strvec, 1)); } else { /* Defaults to true */ vrrp->strict_mode = true; } }
static void vrrp_int_handler(vector_t *strvec) { vrrp_t *vrrp = LIST_TAIL_DATA(vrrp_data->vrrp); char *name = vector_slot(strvec, 1); vrrp->ifp = if_get_by_ifname(name); if (!vrrp->ifp) { log_message(LOG_INFO, "Cant find interface %s for vrrp_instance %s !!!" , name, vrrp->iname); return; } if (vrrp->vmac_flags & VRRP_VMAC_FL_SET) { netlink_link_add_vmac(vrrp); } }
static void lbkind_handler(vector_t *strvec) { virtual_server_t *vs = LIST_TAIL_DATA(check_data->vs); char *str = vector_slot(strvec, 1); if (!strcmp(str, "NAT")) vs->loadbalancing_kind = IP_VS_CONN_F_MASQ; else if (!strcmp(str, "DR")) vs->loadbalancing_kind = IP_VS_CONN_F_DROUTE; else if (!strcmp(str, "TUN")) vs->loadbalancing_kind = IP_VS_CONN_F_TUNNEL; else if (!strcmp(str, "FNAT")) vs->loadbalancing_kind = IP_VS_CONN_F_FULLNAT; else log_message(LOG_INFO, "PARSER : unknown [%s] routing method.", str); }
static void vrrp_auth_pass_handler(vector_t *strvec) { vrrp_t *vrrp = LIST_TAIL_DATA(vrrp_data->vrrp); char *str = vector_slot(strvec, 1); int max_size = sizeof (vrrp->auth_data); int str_len = strlen(str); if (str_len > max_size) { str_len = max_size; log_message(LOG_INFO, "Truncating auth_pass to %d characters", max_size); } memset(vrrp->auth_data, 0, max_size); memcpy(vrrp->auth_data, str, str_len); }
struct cnode * cnode_lookup(struct cnode *cnode, const char *name) { uint32_t i; struct cnode *cn; if (cnode == NULL) { return NULL; } for (i = 0; i < vector_max(cnode->v); i++) { if ((cn = vector_slot(cnode->v, i)) != NULL) { if (strcmp(cn->name, name) == 0) { return cn; } } } return NULL; }
/* Delete interface from ripng_enable_if. */ static int ripng_enable_if_delete (const char *ifname) { int index; char *str; index = ripng_enable_if_lookup (ifname); if (index < 0) return -1; str = vector_slot (ripng_enable_if, index); free (str); vector_unset (ripng_enable_if, index); ripng_enable_apply_all(); return 1; }
static int ripng_passive_interface_unset (struct vty *vty, const char *ifname) { int i; char *str; i = ripng_passive_interface_lookup (ifname); if (i < 0) return CMD_WARNING; str = vector_slot (Vripng_passive_interface, i); free (str); vector_unset (Vripng_passive_interface, i); ripng_passive_interface_apply_all (); return CMD_SUCCESS; }
/* Set instances group pointer */ void vrrp_sync_set_group(vrrp_sgroup_t *vgroup) { vrrp_t *vrrp; char *str; int i; for (i = 0; i < vector_size(vgroup->iname); i++) { str = vector_slot(vgroup->iname, i); vrrp = vrrp_get_instance(str); if (vrrp) { if (LIST_ISEMPTY(vgroup->index_list)) vgroup->index_list = alloc_list(NULL, NULL); list_add(vgroup->index_list, vrrp); vrrp->sync = vgroup; } } }
static void vrrp_vmac_handler(vector_t *strvec) { vrrp_t *vrrp = LIST_TAIL_DATA(vrrp_data->vrrp); vrrp->vmac_flags |= VRRP_VMAC_FL_SET; if (!vrrp->saddr.ss_family && vrrp->family == AF_INET) inet_ip4tosockaddr(IF_ADDR(vrrp->ifp), &vrrp->saddr); if (vector_size(strvec) == 2) { strncpy(vrrp->vmac_ifname, vector_slot(strvec, 1), IFNAMSIZ - 1); } else if (vrrp->vrid) { snprintf(vrrp->vmac_ifname, IFNAMSIZ, "vrrp.%d", vrrp->vrid); } else { return; } netlink_link_add_vmac(vrrp); }
static void vrrp_state_handler(vector_t *strvec) { char *str = vector_slot(strvec, 1); vrrp_t *vrrp = LIST_TAIL_DATA(vrrp_data->vrrp); vrrp_sgroup_t *vgroup = vrrp->sync; if (!strcmp(str, "MASTER")) { vrrp->wantstate = VRRP_STATE_MAST; vrrp->init_state = VRRP_STATE_MAST; } else if (strcmp(str, "BACKUP")) log_message(LOG_INFO,"(%s): unknown state '%s', defaulting to BACKUP", vrrp->iname, str); /* set eventual sync group */ if (vgroup) vgroup->state = vrrp->wantstate; }
static void vrrp_vrid_handler(vector_t *strvec) { vrrp_t *vrrp = LIST_TAIL_DATA(vrrp_data->vrrp); vrrp->vrid = atoi(vector_slot(strvec, 1)); if (VRRP_IS_BAD_VID(vrrp->vrid)) { log_message(LOG_INFO, "VRRP Error : VRID not valid !"); log_message(LOG_INFO, " must be between 1 & 255. reconfigure !"); } else { alloc_vrrp_bucket(vrrp); if (vrrp->vmac_flags & VRRP_VMAC_FL_SET) { if (strlen(vrrp->vmac_ifname) == 0) snprintf(vrrp->vmac_ifname, IFNAMSIZ, "vrrp.%d", vrrp->vrid); netlink_link_add_vmac(vrrp); } } }
static void vrrp_version_handler(vector_t *strvec) { vrrp_t *vrrp = LIST_TAIL_DATA(vrrp_data->vrrp); uint8_t version = atoi(vector_slot(strvec, 1)); if (VRRP_IS_BAD_VERSION(version)) { log_message(LOG_INFO, "VRRP Error : Version not valid !"); log_message(LOG_INFO, " must be between either 2 or 3. reconfigure !"); return; } if ((vrrp->version && vrrp->version != version) || (version == VRRP_VERSION_2 && vrrp->family == AF_INET6)) { log_message(LOG_INFO, "(%s): vrrp_version conflicts with configured or deduced version; ignoring.", vrrp->iname); return; } vrrp->version = version; }
static void vrrp_vip_handler(vector_t *strvec) { vrrp_t *vrrp = LIST_TAIL_DATA(vrrp_data->vrrp); char *buf; char *str = NULL; vector_t *vec = NULL; int address_family; buf = (char *) MALLOC(MAXBUF); while (read_line(buf, MAXBUF)) { address_family = AF_UNSPEC; vec = alloc_strvec(buf); if (vec) { str = vector_slot(vec, 0); if (!strcmp(str, EOB)) { free_strvec(vec); break; } if (vector_size(vec)) { alloc_vrrp_vip(vec); if (!LIST_ISEMPTY(vrrp->vip)) address_family = IP_FAMILY((ip_address_t*)LIST_TAIL_DATA(vrrp->vip)); } if (address_family != AF_UNSPEC) { if (vrrp->family == AF_UNSPEC) vrrp->family = address_family; else if (address_family != vrrp->family) { log_message(LOG_INFO, "(%s): address family must match VRRP instance [%s] - ignoring", vrrp->iname, buf); free_list_element(vrrp->vip, LIST_TAIL_DATA(vrrp->vip)); } } free_strvec(vec); } memset(buf, 0, MAXBUF); } FREE(buf); }
static void vrrp_vrid_handler(vector_t *strvec) { vrrp_t *vrrp = LIST_TAIL_DATA(vrrp_data->vrrp); vrrp->vrid = atoi(vector_slot(strvec, 1)); if (VRRP_IS_BAD_VID(vrrp->vrid)) { log_message(LOG_INFO, "VRRP Error : VRID not valid !"); log_message(LOG_INFO, " must be between 1 & 255. reconfigure !"); } else { alloc_vrrp_bucket(vrrp); if (vrrp->vmac && strlen(vrrp->vmac_ifname) == 0) { snprintf(vrrp->vmac_ifname, IFNAMSIZ, "vrrp.%d" , vrrp->vrid); log_message(LOG_INFO, "vmac_ifname=%s for vrrp_instace %s" , vrrp->vmac_ifname , vrrp->iname); } } }
void * set_value(vector_t *strvec) { char *str; size_t size; char *alloc; if (vector_size(strvec) < 2) return NULL; str = vector_slot(strvec, 1); size = strlen(str); alloc = (char *) MALLOC(size + 1); if (!alloc) return NULL; memcpy(alloc, str, size); return alloc; }
static void bfd_handler(vector_t *strvec) { char *name; global_data->have_bfd_config = true; /* If we are not the bfd process, we don't need any more information */ if (!strvec) return; name = vector_slot(strvec, 1); if (!check_new_bfd(name)) { skip_block(true); return; } alloc_bfd(name); specified_event_processes = 0; }
static void vrrp_vip_handler(vector_t *strvec) { vrrp_t *vrrp = LIST_TAIL_DATA(vrrp_data->vrrp); char *buf; char *str = NULL; vector_t *vec = NULL; int nbvip = 0; buf = (char *) MALLOC(MAXBUF); while (read_line(buf, MAXBUF)) { vec = alloc_strvec(buf); if (vec) { str = vector_slot(vec, 0); if (!strcmp(str, EOB)) { free_strvec(vec); break; } if (vector_size(vec)) { nbvip++; if (nbvip > VRRP_MAX_VIP) { log_message(LOG_INFO, "VRRP_Instance(%s) " "trunc to the first %d VIPs.", vrrp->iname, VRRP_MAX_VIP); log_message(LOG_INFO, " => Declare others VIPs into" " the excluded vip block"); } else alloc_vrrp_vip(vec); } free_strvec(vec); } memset(buf, 0, MAXBUF); } FREE(buf); }
static void vrrp_srcip_handler(vector_t *strvec) { vrrp_t *vrrp = LIST_TAIL_DATA(vrrp_data->vrrp); struct sockaddr_storage *saddr = &vrrp->saddr; int ret; ret = inet_stosockaddr(vector_slot(strvec, 1), 0, saddr); if (ret < 0) { log_message(LOG_ERR, "Configuration error: VRRP instance[%s] malformed unicast" " src address[%s]. Skipping..." , vrrp->iname, FMT_STR_VSLOT(strvec, 1)); return; } if (saddr->ss_family != vrrp->family) { log_message(LOG_ERR, "Configuration error: VRRP instance[%s] and unicast src address" "[%s] MUST be of the same family !!! Skipping..." , vrrp->iname, FMT_STR_VSLOT(strvec, 1)); memset(saddr, 0, sizeof(struct sockaddr_storage)); } }
/* Set instances group pointer */ void vrrp_sync_set_group(vrrp_sgroup_t *vgroup) { vrrp_t *vrrp; char *str; unsigned int i; vrrp_t *vrrp_last = NULL; /* Can't handle no members of the group */ if (!vgroup->iname) return; vgroup->index_list = alloc_list(NULL, NULL); for (i = 0; i < vector_size(vgroup->iname); i++) { str = vector_slot(vgroup->iname, i); vrrp = vrrp_get_instance(str); if (vrrp) { if (vrrp->sync) log_message(LOG_INFO, "Virtual router %s cannot exist in more than one sync group; ignoring %s", str, vgroup->gname); else { list_add(vgroup->index_list, vrrp); vrrp->sync = vgroup; vrrp_last = vrrp; } } else log_message(LOG_INFO, "Virtual router %s specified in sync group %s doesn't exist - ignoring", str, vgroup->gname); } if (LIST_SIZE(vgroup->index_list) <= 1) { /* The sync group will be removed by the calling function */ log_message(LOG_INFO, "Sync group %s has only %d virtual router(s) - removing", vgroup->gname, LIST_SIZE(vgroup->index_list)); /* If there is only one entry in the group, remove the group from the vrrp entry */ if (vrrp_last) vrrp_last->sync = NULL; } }
static void dump_keywords(vector_t *keydump, int level, FILE *fp) { unsigned int i; keyword_t *keyword_vec; char file_name[21]; if (!level) { snprintf(file_name, sizeof(file_name), "/tmp/keywords.%d", getpid()); fp = fopen(file_name, "w"); if (!fp) return; } for (i = 0; i < vector_size(keydump); i++) { keyword_vec = vector_slot(keydump, i); fprintf(fp, "%*sKeyword : %s (%s)\n", level * 2, "", keyword_vec->string, keyword_vec->active ? "active": "disabled"); if (keyword_vec->sub) dump_keywords(keyword_vec->sub, level + 1, fp); } if (!level) fclose(fp); }
void cparam_free(struct cparam *cparam) { if (cparam->args) { vindex_t i; for (i = 0; i < vector_max(cparam->args); i++) { free(vector_slot(cparam->args, i)); } vector_free(cparam->args); } if (cparam->matched) { vector_free(cparam->matched); } if (cparam->candidate) { vector_free(cparam->candidate); } if (cparam->argv) { vector_free(cparam->argv); } free(cparam); }
/* Utility function for getting command vector. */ static vector cmd_node_vector (vector v, enum node_type ntype) { struct cmd_node *cnode = vector_slot (v, ntype); return cnode->cmd_vector; }
/* Filter vector by command character with index. */ static enum match_type cmd_filter_by_string (char *command, vector v, unsigned int index) { unsigned int i; const char *str; struct cmd_element *cmd_element; enum match_type match_type; vector descvec; struct desc * desc; match_type = no_match; /* If command and cmd_element string does not match set NULL to vector */ for (i = 0; i < vector_active (v); i++) if ((cmd_element = vector_slot (v, i)) != NULL) { /* If given index is bigger than max string vector of command, set NULL */ if (index >= vector_active (cmd_element->strvec)) vector_slot (v, i) = NULL; else { unsigned int j; int matched = 0; descvec = vector_slot (cmd_element->strvec, index); for (j = 0; j < vector_active (descvec); j++) if ((desc = vector_slot (descvec, j))) { str = desc->cmd; if (CMD_VARARG (str)) { if (match_type < vararg_match) match_type = vararg_match; matched++; } else if (CMD_IPV4 (str)) { if (cmd_ipv4_match (command) == exact_match) { if (match_type < ipv4_match) match_type = ipv4_match; matched++; } } else if (CMD_IPV4_PREFIX (str)) { if (cmd_ipv4_prefix_match (command) == exact_match) { if (match_type < ipv4_prefix_match) match_type = ipv4_prefix_match; matched++; } } else if (CMD_OPTION (str) || CMD_VARIABLE (str)) { if (match_type < extend_match) match_type = extend_match; matched++; } else { if (strcmp (command, str) == 0) { match_type = exact_match; matched++; } } } if(!matched) vector_slot(v,i) = NULL; } } return match_type; }
/* Sorry Servers handlers */ static void ssvr_handler(vector_t *strvec) { alloc_ssvr(vector_slot(strvec, 1), vector_slot(strvec, 2)); }
static void vs_handler(vector_t *strvec) { alloc_vs(vector_slot(strvec, 1), vector_slot(strvec, 2)); }
/* "bindto" keyword */ static void co_srcip_handler(vector_t *strvec) { conn_opts_t *co = CHECKER_GET_CO(); inet_stosockaddr(vector_slot(strvec, 1), 0, &co->bindto); }
static void process_stream(vector_t *keywords_vec, int need_bob) { unsigned int i; keyword_t *keyword_vec; char *str; char *buf; vector_t *strvec; vector_t *prev_keywords = current_keywords; current_keywords = keywords_vec; int bob_needed = 0; size_t config_id_len = 0; char *buf_start; if (config_id) config_id_len = strlen(config_id); buf = MALLOC(MAXBUF); while (read_line(buf, MAXBUF)) { if (buf[0] == '@') { /* If the line starts '@', check the following word matches the system id */ if (!config_id) continue; buf_start = strpbrk(buf, " \t"); if ((size_t)(buf_start - (buf + 1)) != config_id_len || strncmp(buf + 1, config_id, config_id_len)) continue; } else buf_start = buf; strvec = alloc_strvec(buf_start); memset(buf, 0, MAXBUF); if (!strvec) continue; str = vector_slot(strvec, 0); if (skip_sublevel == -1) { /* There wasn't a '{' on the keyword line */ if (!strcmp(str, BOB)) { /* We've got the opening '{' now */ skip_sublevel = 1; free_strvec(strvec); continue; } else { /* The skipped keyword doesn't have a {} block, so we no longer want to skip */ skip_sublevel = 0; } } if (skip_sublevel) { for (i = 0; i < vector_size(strvec); i++) { str = vector_slot(strvec,i); if (!strcmp(str,BOB)) skip_sublevel++; else if (!strcmp(str,EOB)) { if (--skip_sublevel == 0) break; } } free_strvec(strvec); continue; } if (need_bob) { need_bob = 0; if (!strcmp(str, BOB) && kw_level > 0) { free_strvec(strvec); continue; } else log_message(LOG_INFO, "Missing '{' at beginning of configuration block"); } else if (!strcmp(str, BOB)) { log_message(LOG_INFO, "Unexpected '{' - ignoring"); free_strvec(strvec); continue; } if (!strcmp(str, EOB) && kw_level > 0) { free_strvec(strvec); break; } for (i = 0; i < vector_size(keywords_vec); i++) { keyword_vec = vector_slot(keywords_vec, i); if (!strcmp(keyword_vec->string, str)) { if (!keyword_vec->active) { if (!strcmp(vector_slot(strvec, vector_size(strvec)-1), BOB)) skip_sublevel = 1; else skip_sublevel = -1; } /* There is an inconsistency here. 'static_ipaddress' for example * does not have sub levels, but needs a '{' */ if (keyword_vec->sub) { /* Remove a trailing '{' */ char *bob = vector_slot(strvec, vector_size(strvec)-1) ; if (!strcmp(bob, BOB)) { vector_unset(strvec, vector_size(strvec)-1); FREE(bob); bob_needed = 0; } else bob_needed = 1; } if (keyword_vec->handler) (*keyword_vec->handler) (strvec); if (keyword_vec->sub) { kw_level++; process_stream(keyword_vec->sub, bob_needed); kw_level--; if (keyword_vec->active && keyword_vec->sub_close_handler) (*keyword_vec->sub_close_handler) (); } break; } } if (i >= vector_size(keywords_vec)) log_message(LOG_INFO, "Unknown keyword '%s'", str ); free_strvec(strvec); } current_keywords = prev_keywords; FREE(buf); return; }
/* Execute command by argument readline. */ int cmd_execute_command_strict (vector vline, struct vty *vty, struct cmd_element **cmd) { unsigned int i; unsigned int index; vector cmd_vector; enum match_type match = 0; struct cmd_element *cmd_element; struct cmd_element *matched_element; unsigned int matched_count, incomplete_count; int argc; const char *argv[CMD_ARGC_MAX]; int varflag; char * command; cmd_vector = vector_copy(cmd_node_vector(cmdvec, vty->node)); for(index = 0; index < vector_active(vline); index++) { if((command = vector_slot(vline, index))) { int ret; match = cmd_filter_by_string(vector_slot(vline, index), cmd_vector, index); if(match == vararg_match) break; ret = is_cmd_ambiguous (command, cmd_vector, index, match); if (ret == 1) { vector_free (cmd_vector); return CMD_ERR_AMBIGUOUS; } if (ret == 2) { vector_free (cmd_vector); return CMD_ERR_NO_MATCH; } } } /* Check matched count. */ matched_element = NULL; matched_count = 0; incomplete_count = 0; for (i = 0; i < vector_active (cmd_vector); i++) if (vector_slot (cmd_vector, i) != NULL) { cmd_element = vector_slot (cmd_vector, i); if (match == vararg_match || index >= cmd_element->cmdsize) { matched_element = cmd_element; matched_count++; } else incomplete_count++; } /* Finish of using cmd_vector. */ vector_free (cmd_vector); /* To execute command, matched_count must be 1. */ if (matched_count == 0) { if (incomplete_count) return CMD_ERR_INCOMPLETE; else return CMD_ERR_NO_MATCH; } if (matched_count > 1) return CMD_ERR_AMBIGUOUS; /* Argument treatment */ varflag = 0; argc = 0; for (i = 0; i < vector_active (vline); i++) { if (varflag) argv[argc++] = vector_slot (vline, i); else { vector descvec = vector_slot (matched_element->strvec, i); if (vector_active (descvec) == 1) { struct desc *desc = vector_slot (descvec, 0); if (CMD_VARARG (desc->cmd)) varflag = 1; if (varflag || CMD_VARIABLE (desc->cmd) || CMD_OPTION (desc->cmd)) argv[argc++] = vector_slot (vline, i); } else argv[argc++] = vector_slot (vline, i); } if (argc >= CMD_ARGC_MAX) return CMD_ERR_EXEED_ARGC_MAX; } /* For vtysh execution. */ if (cmd) *cmd = matched_element; if (matched_element->daemon) return CMD_SUCCESS_DAEMON; /* Now execute matched command */ return (*matched_element->func) (matched_element, vty, argc, argv); }
static void natmask_handler(vector_t *strvec) { virtual_server_t *vs = LIST_TAIL_DATA(check_data->vs); inet_ston(vector_slot(strvec, 1), &vs->nat_mask); }