pppol2tp: Connect up/down events to notifiers and add IPv6 ones
authorBenjamin Cama <benjamin.cama@telecom-bretagne.eu>
Wed, 26 Feb 2014 18:13:40 +0000 (19:13 +0100)
committerPaul Mackerras <paulus@samba.org>
Sun, 9 Mar 2014 03:55:18 +0000 (14:55 +1100)
Connect ip up/down events instead of using hooks, and add IPv6 up/down
events notifications too, so that we signal IPv6-only sessions
correctly; otherwise, they may get taken down because the L2TP daemon
has not received any notification.

Signed-off-by: Benjamin Cama <benjamin.cama@telecom-bretagne.eu>
Signed-off-by: Paul Mackerras <paulus@samba.org>
pppd/plugins/pppol2tp/pppol2tp.c

index a7e3400e72faed5ac0fac7991910af704f7920bf..0e28606f9ae4caae126f32bcabd49d9ae79ce78e 100644 (file)
@@ -74,8 +74,6 @@ struct channel pppol2tp_channel;
 
 static void (*old_snoop_recv_hook)(unsigned char *p, int len) = NULL;
 static void (*old_snoop_send_hook)(unsigned char *p, int len) = NULL;
-static void (*old_ip_up_hook)(void) = NULL;
-static void (*old_ip_down_hook)(void) = NULL;
 
 /* Hook provided to allow other plugins to handle ACCM changes */
 void (*pppol2tp_send_accm_hook)(int tunnel_id, int session_id,
@@ -436,22 +434,18 @@ static void pppol2tp_lcp_snoop_send(unsigned char *p, int len)
  * Interface up/down events
  *****************************************************************************/
 
-static void pppol2tp_ip_up_hook(void)
+static void pppol2tp_ip_up(void *opaque, int arg)
 {
-       if (old_ip_up_hook != NULL)
-               (*old_ip_up_hook)();
-
+       /* may get called twice (for IPv4 and IPv6) but the hook handles that well */
        if (pppol2tp_ip_updown_hook != NULL) {
                (*pppol2tp_ip_updown_hook)(pppol2tp_tunnel_id,
                                           pppol2tp_session_id, 1);
        }
 }
 
-static void pppol2tp_ip_down_hook(void)
+static void pppol2tp_ip_down(void *opaque, int arg)
 {
-       if (old_ip_down_hook != NULL)
-               (*old_ip_down_hook)();
-
+       /* may get called twice (for IPv4 and IPv6) but the hook handles that well */
        if (pppol2tp_ip_updown_hook != NULL) {
                (*pppol2tp_ip_updown_hook)(pppol2tp_tunnel_id,
                                           pppol2tp_session_id, 0);
@@ -478,14 +472,6 @@ static void pppol2tp_check_options(void)
                snoop_recv_hook = pppol2tp_lcp_snoop_recv;
                snoop_send_hook = pppol2tp_lcp_snoop_send;
        }
-
-       /* Hook up ip up/down hooks to send indicator to openl2tpd
-        * that the link is up
-        */
-       old_ip_up_hook = ip_up_hook;
-       ip_up_hook = pppol2tp_ip_up_hook;
-       old_ip_down_hook = ip_down_hook;
-       ip_down_hook = pppol2tp_ip_down_hook;
 }
 
 /* Called just before pppd exits.
@@ -509,6 +495,14 @@ void plugin_init(void)
        fatal("No PPPoL2TP support on this OS");
 #endif
        add_options(pppol2tp_options);
+
+       /* Hook up ip up/down notifiers to send indicator to openl2tpd
+        * that the link is up
+        */
+       add_notifier(&ip_up_notifier, pppol2tp_ip_up, NULL);
+       add_notifier(&ip_down_notifier, pppol2tp_ip_down, NULL);
+       add_notifier(&ipv6_up_notifier, pppol2tp_ip_up, NULL);
+       add_notifier(&ipv6_down_notifier, pppol2tp_ip_down, NULL);
 }
 
 struct channel pppol2tp_channel = {