ASR_BASE
Change-Id: Icf3719cc0afe3eeb3edc7fa80a2eb5199ca9dda1
diff --git a/marvell/services/piped/piped_nw.c b/marvell/services/piped/piped_nw.c
new file mode 100644
index 0000000..44b1a7d
--- /dev/null
+++ b/marvell/services/piped/piped_nw.c
@@ -0,0 +1,374 @@
+
+#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
+