From 8aec5cc096fcf6ac31d8041aabb1ac5e8fea0b83 Mon Sep 17 00:00:00 2001
From: Dmitry Kozlov <xeb@mail.ru>
Date: Tue, 11 Jun 2013 15:05:45 +0400
Subject: ipoe: add per-interface 'src' option (use it as source in route)

---
 accel-pppd/accel-ppp.conf.5 |  5 +++++
 accel-pppd/ctrl/ipoe/ipoe.c | 20 ++++++++++++++++++--
 accel-pppd/ctrl/ipoe/ipoe.h |  1 +
 3 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/accel-pppd/accel-ppp.conf.5 b/accel-pppd/accel-ppp.conf.5
index 4aca90fa..9311d228 100644
--- a/accel-pppd/accel-ppp.conf.5
+++ b/accel-pppd/accel-ppp.conf.5
@@ -243,6 +243,7 @@ parameter.
 .BI "" [,range=x.x.x.x/mask][,ifcfg=0|1]
 .BI "" [,relay=x.x.x.x]
 .BI "" [,giaddr=x.x.x.x]
+.BI "" [,src=x.x.x.x]
 .br
 Specifies interface to listen dhcp or unclassified packets. You may specify multiple
 .B interface
@@ -289,6 +290,10 @@ is also needed.
 The
 .B giaddr
 parameter specifies relay agent IP address.
+.br
+The
+.B src
+parameter specifies ip address to use as source when adding route to client.
 .TP
 .BI "local-net=" x.x.x.x/mask
 Specifies networks from which packets will be treated as unclassified. You may specify multiple local-net options.
diff --git a/accel-pppd/ctrl/ipoe/ipoe.c b/accel-pppd/ctrl/ipoe/ipoe.c
index b0d52013..3b3624bb 100644
--- a/accel-pppd/ctrl/ipoe/ipoe.c
+++ b/accel-pppd/ctrl/ipoe/ipoe.c
@@ -50,6 +50,8 @@ static int conf_mode = 0;
 static int conf_shared = 1;
 static int conf_ifcfg = 1;
 static int conf_nat = 0;
+static uint32_t conf_src;
+
 //static int conf_dhcpv6;
 static int conf_username;
 static int conf_unit_cache;
@@ -516,6 +518,9 @@ static void __ipoe_session_start(struct ipoe_session *ses)
 		if (!ses->siaddr && ses->router != ses->yiaddr)
 			ses->siaddr = ses->router;
 		
+		if (!ses->siaddr)
+			ses->siaddr = ses->serv->opt_src;		
+
 		if (!ses->siaddr && ses->serv->dhcpv4_relay)
 			ses->siaddr = ses->serv->dhcpv4_relay->giaddr;
 
@@ -600,9 +605,9 @@ static void ipoe_ifcfg_add(struct ipoe_session *ses)
 				log_ppp_warn("ipoe: failed to add addess to interface '%s'\n", serv->ifname);
 			pthread_mutex_unlock(&serv->lock);
 		}
-		if (iproute_add(serv->ifindex, ses->siaddr, ses->yiaddr))
+		if (iproute_add(serv->ifindex, ses->serv->opt_src ? ses->serv->opt_src : ses->router, ses->yiaddr))
 			log_ppp_warn("ipoe: failed to add route to interface '%s'\n", serv->ifname);
-	} else if (iproute_add(serv->ifindex, ses->siaddr, ses->yiaddr))
+	} else if (iproute_add(serv->ifindex, ses->serv->opt_src ? ses->serv->opt_src : ses->router, ses->yiaddr))
 		log_ppp_warn("ipoe: failed to add route to interface '%s'\n", serv->ifname);
 
 	ses->ifcfg = 1;
@@ -1545,6 +1550,7 @@ static void add_interface(const char *ifname, int ifindex, const char *opt)
 	const char *opt_giaddr = NULL;
 	in_addr_t relay_addr = 0;
 	in_addr_t giaddr = 0;
+	in_addr_t opt_src = conf_src;
 
 	str0 = strchr(opt, ',');
 	if (str0) {
@@ -1595,6 +1601,8 @@ static void add_interface(const char *ifname, int ifindex, const char *opt)
 				giaddr = inet_addr(ptr1);
 			} else if (strcmp(str, "nat") == 0) {
 				opt_nat = atoi(ptr1);
+			} else if (strcmp(str, "src") == 0) {
+				opt_src = inet_addr(ptr1);
 			}
 
 			if (end)
@@ -1651,6 +1659,7 @@ static void add_interface(const char *ifname, int ifindex, const char *opt)
 		serv->opt_mode = opt_mode;
 		serv->opt_ifcfg = opt_ifcfg;
 		serv->opt_nat = opt_nat;
+		serv->opt_src = opt_src;
 
 		if (str0)
 			_free(str0);
@@ -1669,6 +1678,7 @@ static void add_interface(const char *ifname, int ifindex, const char *opt)
 	serv->opt_mode = opt_mode;
 	serv->opt_ifcfg = opt_ifcfg;
 	serv->opt_nat = opt_nat;
+	serv->opt_src = opt_src;
 	serv->active = 1;
 	INIT_LIST_HEAD(&serv->sessions);
 	INIT_LIST_HEAD(&serv->addr_list);
@@ -1979,6 +1989,12 @@ static void load_config(void)
 		conf_nat = atoi(opt);
 	else
 		conf_nat = 0;
+
+	opt = conf_get_opt("ipoe", "src");
+	if (opt)
+		conf_src = inet_addr(opt);
+	else
+		conf_src = 0;
 	
 	opt = conf_get_opt("ipoe", "mode");
 	if (opt) {
diff --git a/accel-pppd/ctrl/ipoe/ipoe.h b/accel-pppd/ctrl/ipoe/ipoe.h
index 034092e1..1dd2db97 100644
--- a/accel-pppd/ctrl/ipoe/ipoe.h
+++ b/accel-pppd/ctrl/ipoe/ipoe.h
@@ -22,6 +22,7 @@ struct ipoe_serv
 	struct dhcpv4_relay *dhcpv4_relay;
 	pthread_mutex_t lock;
 	int opt_mode;
+	uint32_t opt_src;
 	int opt_shared:1;
 	int opt_dhcpv4:1;
 	int opt_up:1;
-- 
cgit v1.2.3