static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) { struct instance *o = vo; o->i = i; // read arguments NCDValRef ifname_arg; NCDValRef addr_arg; NCDValRef prefix_arg = NCDVal_NewInvalid(); if (!NCDVal_ListRead(params->args, 2, &ifname_arg, &addr_arg) && !NCDVal_ListRead(params->args, 3, &ifname_arg, &addr_arg, &prefix_arg) ) { ModuleLog(o->i, BLOG_ERROR, "wrong arity"); goto fail0; } if (!NCDVal_IsStringNoNulls(ifname_arg) || !NCDVal_IsString(addr_arg) || (!NCDVal_IsInvalid(prefix_arg) && !NCDVal_IsString(prefix_arg)) ) { ModuleLog(o->i, BLOG_ERROR, "wrong type"); goto fail0; } // null terminate ifname if (!NCDVal_StringNullTerminate(ifname_arg, &o->ifname_nts)) { ModuleLog(i, BLOG_ERROR, "NCDVal_StringNullTerminate failed"); goto fail0; } if (NCDVal_IsInvalid(prefix_arg)) { if (!ipaddr6_parse_ipv6_ifaddr_bin(NCDVal_StringData(addr_arg), NCDVal_StringLength(addr_arg), &o->ifaddr)) { ModuleLog(o->i, BLOG_ERROR, "wrong CIDR notation address"); goto fail1; } } else { if (!ipaddr6_parse_ipv6_addr_bin(NCDVal_StringData(addr_arg), NCDVal_StringLength(addr_arg), &o->ifaddr.addr)) { ModuleLog(o->i, BLOG_ERROR, "wrong address"); goto fail1; } if (!ipaddr6_parse_ipv6_prefix_bin(NCDVal_StringData(prefix_arg), NCDVal_StringLength(prefix_arg), &o->ifaddr.prefix)) { ModuleLog(o->i, BLOG_ERROR, "wrong prefix"); goto fail1; } } // add address if (!NCDIfConfig_add_ipv6_addr(o->ifname_nts.data, o->ifaddr)) { ModuleLog(o->i, BLOG_ERROR, "failed to add IP address"); goto fail1; } // signal up NCDModuleInst_Backend_Up(o->i); return; fail1: NCDValNullTermString_Free(&o->ifname_nts); fail0: NCDModuleInst_Backend_DeadError(i); }
static void func_new_common (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params, int is_ifnot) { struct instance *o = vo; o->i = i; // read arguments NCDValRef arg_addr; NCDValRef arg_net_addr; NCDValRef arg_net_prefix = NCDVal_NewInvalid(); if (!NCDVal_ListRead(params->args, 2, &arg_addr, &arg_net_addr) && !NCDVal_ListRead(params->args, 3, &arg_addr, &arg_net_addr, &arg_net_prefix) ) { ModuleLog(o->i, BLOG_ERROR, "wrong arity"); goto fail0; } if (!NCDVal_IsString(arg_addr) || !NCDVal_IsString(arg_net_addr) || (!NCDVal_IsInvalid(arg_net_prefix) && !NCDVal_IsString(arg_net_prefix)) ) { ModuleLog(o->i, BLOG_ERROR, "wrong type"); goto fail0; } // parse addr struct ipv6_addr addr; if (!ipaddr6_parse_ipv6_addr_bin(NCDVal_StringData(arg_addr), NCDVal_StringLength(arg_addr), &addr)) { ModuleLog(o->i, BLOG_ERROR, "bad address"); goto fail0; } // parse network struct ipv6_ifaddr network; if (NCDVal_IsInvalid(arg_net_prefix)) { if (!ipaddr6_parse_ipv6_ifaddr_bin(NCDVal_StringData(arg_net_addr), NCDVal_StringLength(arg_net_addr), &network)) { ModuleLog(o->i, BLOG_ERROR, "bad network in CIDR notation"); goto fail0; } } else { if (!ipaddr6_parse_ipv6_addr_bin(NCDVal_StringData(arg_net_addr), NCDVal_StringLength(arg_net_addr), &network.addr)) { ModuleLog(o->i, BLOG_ERROR, "bad network address"); goto fail0; } if (!ipaddr6_parse_ipv6_prefix_bin(NCDVal_StringData(arg_net_prefix), NCDVal_StringLength(arg_net_prefix), &network.prefix)) { ModuleLog(o->i, BLOG_ERROR, "bad network prefix"); goto fail0; } } // test o->value = ipaddr6_ipv6_addrs_in_network(addr, network.addr, network.prefix); if (is_ifnot && o->value) { ModuleLog(o->i, BLOG_ERROR, "addresses belong to same subnet, not proceeding"); } // signal up if (!is_ifnot || !o->value) { NCDModuleInst_Backend_Up(o->i); } return; fail0: NCDModuleInst_Backend_DeadError(i); }
static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) { struct instance *o = vo; o->i = i; // read arguments NCDValRef dest_arg; NCDValRef dest_prefix_arg = NCDVal_NewInvalid(); NCDValRef gateway_arg; NCDValRef metric_arg; NCDValRef ifname_arg; if (!NCDVal_ListRead(params->args, 4, &dest_arg, &gateway_arg, &metric_arg, &ifname_arg) && !NCDVal_ListRead(params->args, 5, &dest_arg, &dest_prefix_arg, &gateway_arg, &metric_arg, &ifname_arg) ) { ModuleLog(o->i, BLOG_ERROR, "wrong arity"); goto fail0; } if (!NCDVal_IsString(dest_arg) || !NCDVal_IsString(gateway_arg) || !NCDVal_IsStringNoNulls(ifname_arg) || (!NCDVal_IsInvalid(dest_prefix_arg) && !NCDVal_IsString(dest_prefix_arg)) ) { ModuleLog(o->i, BLOG_ERROR, "wrong type"); goto fail0; } // read dest if (NCDVal_IsInvalid(dest_prefix_arg)) { if (!ipaddr6_parse_ipv6_ifaddr_bin(NCDVal_StringData(dest_arg), NCDVal_StringLength(dest_arg), &o->dest)) { ModuleLog(o->i, BLOG_ERROR, "wrong CIDR notation dest"); goto fail0; } } else { if (!ipaddr6_parse_ipv6_addr_bin(NCDVal_StringData(dest_arg), NCDVal_StringLength(dest_arg), &o->dest.addr)) { ModuleLog(o->i, BLOG_ERROR, "wrong dest addr"); goto fail0; } if (!ipaddr6_parse_ipv6_prefix_bin(NCDVal_StringData(dest_prefix_arg), NCDVal_StringLength(dest_prefix_arg), &o->dest.prefix)) { ModuleLog(o->i, BLOG_ERROR, "wrong dest prefix"); goto fail0; } } // read gateway and choose type if (NCDVal_StringEquals(gateway_arg, "none")) { o->type = TYPE_IFONLY; } else if (NCDVal_StringEquals(gateway_arg, "blackhole")) { o->type = TYPE_BLACKHOLE; } else { if (!ipaddr6_parse_ipv6_addr_bin(NCDVal_StringData(gateway_arg), NCDVal_StringLength(gateway_arg), &o->gateway)) { ModuleLog(o->i, BLOG_ERROR, "wrong gateway"); goto fail0; } o->type = TYPE_NORMAL; } // read metric uintmax_t metric; if (!ncd_read_uintmax(metric_arg, &metric) || metric > INT_MAX) { ModuleLog(i, BLOG_ERROR, "bad metric"); goto fail0; } o->metric = metric; // null terminate ifname if (!NCDVal_StringNullTerminate(ifname_arg, &o->ifname_nts)) { ModuleLog(i, BLOG_ERROR, "NCDVal_StringNullTerminate failed"); goto fail0; } // add route int res = 0; // to remove warning switch (o->type) { case TYPE_NORMAL: res = NCDIfConfig_add_ipv6_route(o->dest, &o->gateway, o->metric, o->ifname_nts.data); break; case TYPE_IFONLY: res = NCDIfConfig_add_ipv6_route(o->dest, NULL, o->metric, o->ifname_nts.data); break; case TYPE_BLACKHOLE: res = NCDIfConfig_add_ipv6_blackhole_route(o->dest, o->metric); break; default: ASSERT(0); } if (!res) { ModuleLog(o->i, BLOG_ERROR, "failed to add route"); goto fail1; } // signal up NCDModuleInst_Backend_Up(o->i); return; fail1: NCDValNullTermString_Free(&o->ifname_nts); fail0: NCDModuleInst_Backend_DeadError(i); }