Merge from Master
[l2tpns.git] / l2tplac.c
index 3851fa0..5fb361e 100644 (file)
--- a/l2tplac.c
+++ b/l2tplac.c
@@ -1,15 +1,23 @@
 /*
+ * Fernando ALVES 2013
  * Add functionality "LAC" to l2tpns.
  * Used to forward a ppp session to another "LNS".
+ * GPL licenced
  */
+
 #include <errno.h>
 #include <string.h>
+#include <linux/rtnetlink.h>
+#include <netinet/ip6.h>
 
 #include "md5.h"
+#include "dhcp6.h"
 #include "l2tpns.h"
 #include "util.h"
+#include "cluster.h"
 
 #include "l2tplac.h"
+#include "pppoe.h"
 
 /* sequence diagram: Client <--> LAC <--> LNS1 <--> LNS2
  *
@@ -290,6 +298,7 @@ static int lac_create_tunnelsession(tunnelidt t, sessionidt s, confrlnsidt i_con
                tunnel[t].port = pconfigrlns[i_conf].port;
                tunnel[t].window = 4; // default window
                tunnel[t].isremotelns = i_conf;
+               tunnel[t].indexudp = config->indexlacudpfd;
                STAT(tunnel_created);
 
                random_data(pconfigrlns[i_conf].auth, sizeof(pconfigrlns[i_conf].auth));
@@ -444,7 +453,7 @@ void lac_calc_rlns_auth(tunnelidt t, uint8_t id, uint8_t *out)
 }
 
 // Forward session to LAC or Remote LNS
-int lac_session_forward(uint8_t *buf, int len, sessionidt sess, uint16_t proto)
+int lac_session_forward(uint8_t *buf, int len, sessionidt sess, uint16_t proto, in_addr_t s_addr, int sin_port, uint16_t indexudpfd)
 {
        uint16_t t = 0, s = 0;
        uint8_t *p = buf + 2; // First word L2TP options
@@ -465,10 +474,29 @@ int lac_session_forward(uint8_t *buf, int len, sessionidt sess, uint16_t proto)
 
        if ((!tunnel[t].isremotelns) && (!tunnel[session[sess].tunnel].isremotelns))
        {
-               LOG(0, sess, session[sess].tunnel, "Link Tunnel Session (%u) broken\n", s);
+               LOG(0, sess, session[sess].tunnel, "Link Tunnel Session (%u/%u) broken\n", s, t);
                return 0;
        }
 
+       if (!config->cluster_iam_master)
+       {
+               if ( (proto == PPPIPCP) || (proto == PPPLCP) ||
+                        (proto == PPPPAP) || (proto == PPPCHAP) ||
+                        (proto == PPPIPV6CP && config->ipv6_prefix.s6_addr[0]) ||
+                        (proto == PPPCCP) )
+               {
+                       session[sess].last_packet = time_now;
+                       master_forward_packet(buf, len, s_addr, sin_port, indexudpfd);
+                       return 1;
+               }
+       }
+
+       if (t == TUNNEL_ID_PPPOE)
+       {
+               pppoe_forwardto_session_pppoe(buf, len, sess, proto);
+               return 1;
+       }
+
        if (*buf & 0x40)
        {       // length
                p += 2;