blob: 44b1a7dd0cb9d9df2c4f9d587ee37e5fff5d5890 [file] [log] [blame]
#include "piped.h"
#include "piped_uci.h"
#include "piped_util.h"
#include "piped_nw.h"
#include "piped_dhcp.h"
#include "piped_dns.h"
int pd_nw_add(struct pd_context *pdc, struct pd_iface *pdi)
{
char lan_alias[MAX_IP_STR_LEN];
char *lan_ip = NULL;
char *network_lan_ip = NULL;
struct uci_context *c = pdc->c;
int i = 0;
int last_oct;
int third_oct;
lan_ip = pd_uci_get_opt(c, UCI_PKG_PIPE, UCI_SEC_LAN, UCI_OPT_IPADDR);
if (!lan_ip) {
PD_ERR(pd_nw_add, "pd_uci_get_opt failed %s\n", UCI_OPT_IPADDR);
return 1;
}
ipv4_get_alias(pdi->ipaddr, lan_alias);
last_oct = ipv4_get_last_oct(pdi->ipaddr);
third_oct = ipv4_get_third_oct(pdi->ipaddr);
PD_ERR(pd_nw_add_m0, "pd_nw_add: lan_ip=%s, lan_alias=%s\n", lan_ip, lan_alias);
network_lan_ip = pd_uci_get_opt(c, UCI_PKG_NW, UCI_SEC_LAN, UCI_OPT_IPADDR);
PD_ERR(pd_nw_add_m27, "pd_nw_add: network_lan_ip=%s\n", network_lan_ip);
if (pd_uci_del(c, UCI_PKG_NW, UCI_SEC_LAN, UCI_OPT_IPADDR,
lan_ip)) {
PD_ERR(pd_nw_add1, "pd_uci_del failed %s\n", lan_ip);
// return 1;
}
PD_ERR(pd_nw_add_m0, "pd_nw_add: begin del ipaddr list, i=%d", i);
while(!pd_uci_del(c, UCI_PKG_NW, UCI_SEC_LAN, UCI_OPT_IPADDR, NULL)) {
PD_ERR(pd_nw_add_m35, "pd_nw_add: del ipaddr, i=%d", i);
i++;
}
if (pd_uci_add_list(c, UCI_PKG_NW, UCI_SEC_LAN, UCI_OPT_IPADDR,
lan_alias)) {
PD_ERR(pd_nw_add2, "pd_uci_add_listt failed %s\n", lan_alias);
return 1;
}
/*
if (pd_uci_add_list(c, UCI_PKG_NW, UCI_SEC_LAN, UCI_OPT_IPADDR,
lan_ip)) {
PD_ERR(pd_nw_add3, "pd_uci_add_list failed %s\n", lan_ip);
return 1;
}
*/
if (last_oct != 255 && last_oct != 0) {
if (pd_uci_set_opt(c, UCI_PKG_NW, UCI_SEC_LAN, UCI_OPT_NETMASK,
UCI_DHCP_DFLT_SNMASK)) {
PD_ERR(pd_nw_add59, "pd_uci_set_opt failed %s\n", UCI_DHCP_DFLT_SNMASK);
}
} else {
if (third_oct != 255 && third_oct != 0) {
if (pd_uci_set_opt(c, UCI_PKG_NW, UCI_SEC_LAN, UCI_OPT_NETMASK,
UCI_DHCP_DFLT_SNMASK1)) {
PD_ERR(pd_nw_add66, "pd_uci_set_opt failed %s\n", UCI_DHCP_DFLT_SNMASK1);
}
} else {
if (pd_uci_set_opt(c, UCI_PKG_NW, UCI_SEC_LAN, UCI_OPT_NETMASK,
UCI_DHCP_DFLT_SNMASK2)) {
PD_ERR(pd_nw_add71, "pd_uci_set_opt failed %s\n", UCI_DHCP_DFLT_SNMASK2);
}
}
}
pd_set(&pdc->status, PDC_NETWORK_CHANGED);
return 0;
}
int pd_nw_del(struct pd_context *pdc, struct pd_iface *pdi)
{
char lan_alias[MAX_IP_STR_LEN];
struct uci_context *c = pdc->c;
ipv4_get_alias(pdi->ipaddr, lan_alias);
PD_ERR(pd_nw_del_m0, "pd_uci_del_from_list %s\n", lan_alias);
if (pd_uci_del_from_list(c, UCI_PKG_NW, UCI_SEC_LAN, UCI_OPT_IPADDR,
lan_alias)) {
PD_ERR(pd_nw_del, "pd_uci_del_from_list failed %s\n", lan_alias);
return 1;
}
pd_set(&pdc->status, PDC_NETWORK_CHANGED);
return 0;
}
int pd_nw_change(struct pd_context *pdc, struct pd_iface *oldi,
struct pd_iface *newi)
{
int ret = 0;
if (pd_nw_del(pdc, oldi)) {
PD_ERR(pd_nw_change, "pd_nw_del failed for %s\n", oldi->sec);
return 1;
}
if (pd_nw_add(pdc, newi)) {
PD_ERR(pd_nw_change1, "pd_nw_add failed for %s\n", newi->sec);
return 1;
}
#ifdef CONFIG_NETWORK_WAN_IN_PIPE
if (!strncasecmp(oldi->sec, "wan", 3)) {
ret = pd_nw_wan_config(oldi, false);
pd_set(&pdc->status, PDC_NETWORK_CHANGED);
}
if (!strncasecmp(newi->sec, "wan", 3)) {
ret |= pd_nw_wan_config(newi, true);
pd_set(&pdc->status, PDC_NETWORK_CHANGED);
}
#endif
return ret;
}
void pd_nw_clean(struct pd_context *pdc)
{
struct uci_context *c = pdc->c;
PD_INFO(pd_nw_clean, "cleaning network configuration\n");
if (pd_uci_set_opt(c, UCI_PKG_NW, UCI_SEC_LAN, UCI_OPT_IPADDR,
UCI_NW_DFLT_IP)) {
PD_ERR(pd_nw_clean2, "pd_uci_set_opt failed %s\n", UCI_NW_DFLT_IP);
return;
}
if (pd_uci_set_opt(c, UCI_PKG_NW, UCI_SEC_LAN, UCI_OPT_NETMASK,
UCI_DHCP_DFLT_SNMASK)) {
PD_ERR(pd_nw_clean133, "pd_uci_set_opt failed %s\n", UCI_DHCP_DFLT_SNMASK);
}
pd_set(&pdc->status, PDC_NETWORK_CHANGED);
}
#ifdef CONFIG_NETWORK_WAN_IN_PIPE
int pd_nw_wan_add_del_addr(struct uci_context *c, struct pd_iface *pdi,
bool add)
{
int ret = 0;
char ip6addr[MAX_IP6_STR_LEN];
if (add){
ret = pd_uci_set_opt(c, UCI_PKG_NW, pdi->sec, UCI_OPT_PROT, UCI_STATIC);
ret |= pd_uci_set_opt(c, UCI_PKG_NW, pdi->sec, UCI_OPT_MTU, UCI_DFLT_MTU);
}
else{
ret = pd_uci_set_opt(c, UCI_PKG_NW, pdi->sec, UCI_OPT_PROT, UCI_NONE);
ret |= pd_uci_del(c, UCI_PKG_NW, pdi->sec, UCI_OPT_MTU, UCI_DFLT_MTU);
}
if(ret)
goto err;
if (add && pdi->flags & PDI_AUTO)
ret = pd_uci_set_opt(c, UCI_PKG_NW, pdi->sec, UCI_OPT_AUTO, "1");
else if (pdi->flags & PDI_AUTO)
ret = pd_uci_del(c, UCI_PKG_NW, pdi->sec, UCI_OPT_AUTO, "1");
if (ret)
goto err;
if(pdi->flags & PDI_DEDICATEAPN) {
if (add)
ret = pd_uci_set_opt(c, UCI_PKG_NW, pdi->sec, UCI_OPT_DEDICATE_OPT, "1");
else if (pdi->flags & PDI_DEDICATEAPN)
ret = pd_uci_del(c, UCI_PKG_NW, pdi->sec, UCI_OPT_DEDICATE_OPT, "1");
} else {
if (add)
ret = pd_uci_set_opt(c, UCI_PKG_NW, pdi->sec, UCI_OPT_DEDICATE_OPT, "0");
else if (pdi->flags & PDI_DEDICATEAPN)
ret = pd_uci_del(c, UCI_PKG_NW, pdi->sec, UCI_OPT_DEDICATE_OPT, "0");
}
if (ret)
goto err;
if (add && pdi->flags & PDI_COMBINE_IF)
ret = pd_uci_set_opt(c, UCI_PKG_NW, pdi->sec, UCI_OPT_COMBINE_IF_OPT, pdi->combine_if);
else if (pdi->flags & PDI_COMBINE_IF)
ret = pd_uci_del(c, UCI_PKG_NW, pdi->sec, UCI_OPT_COMBINE_IF_OPT, pdi->combine_if);
if (ret)
goto err;
PD_INFO(pd_nw_wan_add_del_addr0, "pd_nw_wan_add_del_addr: ip=%s\n", pdi->ipaddr);
if (add && pdi->flags & PDI_IPADDR)
ret = pd_uci_set_opt(c, UCI_PKG_NW, pdi->sec, UCI_OPT_IPADDR, pdi->ipaddr);
else if (pdi->flags & PDI_IPADDR)
ret = pd_uci_del(c, UCI_PKG_NW, pdi->sec, UCI_OPT_IPADDR, pdi->ipaddr);
if (ret)
goto err;
sprintf(ip6addr, "%s/%d", pdi->ip6addr, UCI_IPV6_DFLT_PREF);
PD_INFO(pd_nw_wan_add_del_addr1, "pd_nw_wan_add_del_addr: ip6=%s\n", ip6addr);
if (add && pdi->flags & PDI_IP6ADDR) {
ret = pd_uci_set_opt(c, UCI_PKG_NW, pdi->sec, UCI_OPT_IP6ADDR, ip6addr);
} else if (pdi->flags & PDI_IP6ADDR) {
ret = pd_uci_del(c, UCI_PKG_NW, pdi->sec, UCI_OPT_IP6ADDR, ip6addr);
}
if(ret)
goto err;
return 0;
err:
PD_ERR(pd_nw_wan_add_del_addr, "failed to [%s] ip address for [%s]\n", add ? "add" : "del", pdi->sec);
return ret;
}
int pd_nw_wan_add_del_dns(struct uci_context *c, struct pd_iface *pdi,
bool add)
{
int ret = 0;
uint i = 0;
int flags[] = {pdi->flags & PDI_DNS4P, pdi->flags & PDI_DNS4S,
pdi->flags & PDI_DNS6P, pdi->flags & PDI_DNS6S};
char *addr[] = {pdi->dns4p, pdi->dns4s, pdi->dns6p, pdi->dns6s};
PD_INFO(pd_nw_wan_add_del_dns, "%s, %d, add: %d\n", __FUNCTION__, __LINE__, add);
for (i = 0; i < sizeof(flags)/sizeof(int); i++) {
if (flags[i] && add)
ret = pd_uci_add_list(c, UCI_PKG_NW, pdi->sec, UCI_OPT_DNS,
addr[i]);
else if (flags[i])
ret = pd_uci_del_from_list(c, UCI_PKG_NW, pdi->sec, UCI_OPT_DNS,
addr[i]);
}
if (ret)
goto err;
return 0;
err:
PD_ERR(pd_nw_wan_add_del_dns2, "failed to [%s] dns for [%s]\n", add ? "add" : "del", pdi->sec);
return ret;
}
int pd_nw_wan_add_del_mask(struct uci_context *c, struct pd_iface *pdi,
bool add)
{
int ret = 0;
char netmask[MAX_IP_STR_LEN];
int last_oct;
int third_oct;
if (pdi->flags & PDI_IP6ADDR)
return 0;
last_oct = ipv4_get_last_oct(pdi->ipaddr);
third_oct = ipv4_get_third_oct(pdi->ipaddr);
if (last_oct != 255 && last_oct != 0)
memcpy(netmask, UCI_DHCP_DFLT_SNMASK, MAX_IP_STR_LEN);
else {
if (third_oct != 255 && third_oct != 0)
memcpy(netmask, UCI_DHCP_DFLT_SNMASK1, MAX_IP_STR_LEN);
else
memcpy(netmask, UCI_DHCP_DFLT_SNMASK2, MAX_IP_STR_LEN);
}
if (add)
ret = pd_uci_set_opt(c, UCI_PKG_NW, pdi->sec, UCI_OPT_NETMASK,
netmask);
else
ret = pd_uci_del(c, UCI_PKG_NW, pdi->sec, UCI_OPT_NETMASK,
netmask);
if (ret)
goto err;
return 0;
err:
PD_ERR(pd_nw_wan_add_del_mask, "failed to [%s] netmask for [%s]\n", add ? "add" : "del", pdi->sec);
return ret;
}
int pd_nw_wan_add_del_gw(struct uci_context *c, struct pd_iface *pdi,
bool add)
{
int ret = 0;
if (add)
ret = pd_uci_set_opt(c, UCI_PKG_NW, pdi->sec, UCI_OPT_GW, pdi->ipaddr);
else
ret = pd_uci_del(c, UCI_PKG_NW, pdi->sec, UCI_OPT_GW, pdi->ipaddr);
if (ret)
goto err;
return 0;
err:
PD_ERR(pd_nw_wan_add_del_gw, "failed to [%s] gw for [%s]\n", add ? "add" : "del", pdi->sec);
return ret;
}
int pd_nw_wan_uci_init(struct uci_context **c)
{
struct uci_package *p = NULL;
*c = uci_alloc_context();
if (!*c) {
PD_ERR(pd_nw_wan_uci_init, "failed to allocate context\n");
return 1;
}
uci_load(*c, UCI_PKG_NW, &p);
if (!p) {
uci_free_context(*c);
PD_ERR(pd_nw_wan_uci_init337, "failed to load network package\n");
return 1;
}
return 0;
}
void pd_nw_wan_uci_done(struct uci_context *c, bool commit)
{
struct uci_package *p;
if (!c)
return;
if (commit) {
if((p = uci_lookup_package(c, UCI_PKG_NW)))
uci_commit(c, &p, false);
}
uci_free_context(c);
}
int pd_nw_wan_config(struct pd_iface *pdi, bool add)
{
struct uci_context *c = NULL;
PD_INFO(pd_nw_wan_config, "Enter pd_nw_wan_config, add: %d\n", add);
if (pd_nw_wan_uci_init(&c))
goto err;
if (pd_nw_wan_add_del_addr(c, pdi, add))
goto err;
if (pd_nw_wan_add_del_gw(c, pdi, add))
goto err;
if (pd_nw_wan_add_del_mask(c, pdi, add))
goto err;
if (pd_nw_wan_add_del_dns(c, pdi, add))
goto err;
pd_nw_wan_uci_done(c, true);
return 0;
err:
PD_ERR(pd_nw_wan_config414, "pd_nw_wan_config failed\n");
pd_nw_wan_uci_done(c, false);
return -1;
}
#endif