]> git.puffer.fish Git - matthieu/frr.git/commitdiff
ptm-integration.patch
authorDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 20 May 2015 00:40:44 +0000 (17:40 -0700)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 20 May 2015 00:40:44 +0000 (17:40 -0700)
Integrates Prescriptive Topology Module(ptm) into quagga.

If this module is enabled, link ups are notified only after the link is verified
as being connected to the neighbor specified. The neighbor specification and
checking is done by the ptm daemon.

12 files changed:
lib/if.c
lib/if.h
lib/zclient.c
vtysh/Makefile.am
zebra/Makefile.am
zebra/interface.c
zebra/main.c
zebra/redistribute.c
zebra/rt_netlink.c
zebra/zebra_ptm.c [new file with mode: 0644]
zebra/zebra_ptm.h [new file with mode: 0644]
zebra/zserv.c

index 3425e3a8b1b6143370c4efbf4ce8488c10e9f6eb..b3decf3be981a9a07542a7ad1f8f3ec07c4b959b 100644 (file)
--- a/lib/if.c
+++ b/lib/if.c
@@ -38,6 +38,7 @@
 
 /* Master list of interfaces. */
 struct list *iflist;
+int ptm_enable = 0;
 
 /* One for each program.  This structure is needed to store hooks. */
 struct if_master
@@ -373,12 +374,25 @@ if_is_running (struct interface *ifp)
 }
 
 /* Is the interface operative, eg. either UP & RUNNING
-   or UP & !ZEBRA_INTERFACE_LINK_DETECTION */
+   or UP & !ZEBRA_INTERFACE_LINK_DETECTION and
+   if ptm checking is enabled, then ptm check has passed */
 int
 if_is_operative (struct interface *ifp)
 {
   return ((ifp->flags & IFF_UP) &&
-         (ifp->flags & IFF_RUNNING || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)));
+         (((ifp->flags & IFF_RUNNING) &&
+           (ifp->ptm_status || !ifp->ptm_enable)) ||
+          !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)));
+}
+
+/* Is the interface operative, eg. either UP & RUNNING
+   or UP & !ZEBRA_INTERFACE_LINK_DETECTION, without PTM check */
+int
+if_is_no_ptm_operative (struct interface *ifp)
+{
+  return ((ifp->flags & IFF_UP) &&
+         ((ifp->flags & IFF_RUNNING) ||
+          !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)));
 }
 
 /* Is this loopback interface ? */
index 80b62e6e6c408462080087e0df1d183f0219c9cd..287d26cf978706985dd5e2a47a6b57a2b48be058 100644 (file)
--- a/lib/if.h
+++ b/lib/if.h
@@ -135,6 +135,9 @@ struct interface
   /* Daemon specific interface data pointer. */
   void *info;
 
+  char ptm_enable;             /* Should we look at ptm_status ? */
+  char ptm_status;
+
   /* Statistics fileds. */
 #ifdef HAVE_PROC_NET_DEV
   struct if_stats stats;
@@ -285,6 +288,7 @@ extern void if_delete (struct interface *);
 extern int if_is_up (struct interface *);
 extern int if_is_running (struct interface *);
 extern int if_is_operative (struct interface *);
+extern int if_is_no_ptm_operative (struct interface *);
 extern int if_is_loopback (struct interface *);
 extern int if_is_broadcast (struct interface *);
 extern int if_is_pointopoint (struct interface *);
index fab130f646525a5734f3051ad41347c86899280c..8b4597714e90a1fe2d1937d5bb4d42acaf4ce3eb 100644 (file)
@@ -729,6 +729,8 @@ zebra_interface_if_set_value (struct stream *s, struct interface *ifp)
 
   /* Read interface's value. */
   ifp->flags = stream_getq (s);
+  ifp->ptm_enable = stream_getc (s);
+  ifp->ptm_status = stream_getc (s);
   ifp->metric = stream_getl (s);
   ifp->mtu = stream_getl (s);
   ifp->mtu6 = stream_getl (s);
index 5c325ec26124f876e12b278f2084651c45e559ee..9652a92e0a0bcba7b90f852147f23e783383e311 100644 (file)
@@ -34,7 +34,8 @@ vtysh_cmd_FILES = $(top_srcdir)/bgpd/*.c $(top_srcdir)/isisd/*.c \
                  $(top_srcdir)/zebra/rtadv.c $(top_srcdir)/zebra/zebra_vty.c \
                  $(top_srcdir)/zebra/zserv.c $(top_srcdir)/zebra/router-id.c \
                  $(top_srcdir)/zebra/zebra_routemap.c \
-                 $(top_srcdir)/zebra/zebra_fpm.c
+                 $(top_srcdir)/zebra/zebra_fpm.c \
+                 $(top_srcdir)/zebra/zebra_ptm.c
 
 vtysh_cmd.c: $(vtysh_cmd_FILES)
        ./$(EXTRA_DIST) $(vtysh_cmd_FILES) > vtysh_cmd.c
index 9aa135236b13b2f361e6322e9b967d2735e4b474..03f9cc144f14c77a811800c3d985adccac131d50 100644 (file)
@@ -34,10 +34,10 @@ zebra_SOURCES = \
        zserv.c main.c interface.c connected.c zebra_rib.c zebra_routemap.c \
        redistribute.c debug.c rtadv.c zebra_snmp.c zebra_vty.c \
        irdp_main.c irdp_interface.c irdp_packet.c router-id.c zebra_fpm.c \
-       $(othersrc) zebra_rnh.c
+       $(othersrc) zebra_ptm.c zebra_rnh.c
 
 testzebra_SOURCES = test_main.c zebra_rib.c interface.c connected.c debug.c \
-       zebra_vty.c \
+       zebra_vty.c zebra_ptm.c \
        kernel_null.c  redistribute_null.c ioctl_null.c misc_null.c zebra_rnh_null.c
 
 noinst_HEADERS = \
index fe5e3e2be8fcb0f75b13c58d10d2ab704a43caf1..10344c62818cc6ae90ce240188c09d2f5935b23a 100644 (file)
@@ -40,6 +40,9 @@
 #include "zebra/redistribute.h"
 #include "zebra/debug.h"
 #include "zebra/irdp.h"
+#include "zebra/zebra_ptm.h"
+
+#define ZEBRA_PTM_SUPPORT
 
 #ifdef RTADV
 /* Order is intentional.  Matches RFC4191.  This array is also used for
@@ -58,6 +61,7 @@ if_zebra_new_hook (struct interface *ifp)
   zebra_if->multicast = IF_ZEBRA_MULTICAST_UNSPEC;
   zebra_if->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
 
+  ifp->ptm_enable = ptm_enable;
 #ifdef RTADV
   {
     /* Set default router advertise values. */
@@ -261,7 +265,7 @@ if_flags_update (struct interface *ifp, uint64_t newflags)
 {
   if_flags_mangle (ifp, &newflags);
     
-  if (if_is_operative (ifp))
+  if (if_is_no_ptm_operative (ifp))
     {
       /* operative -> inoperative? */
       ifp->flags = newflags;
@@ -533,8 +537,14 @@ if_up (struct interface *ifp)
   struct prefix *p;
 
   /* Notify the protocol daemons. */
+  if (ifp->ptm_enable && !ifp->ptm_status) {
+    zlog_warn("%s: interface %s hasn't passed ptm check\n", __func__,
+             ifp->name);
+    return;
+  }
   zebra_interface_up_update (ifp);
 
+
   /* Install connected routes to the kernel. */
   if (ifp->connected)
     {
@@ -742,6 +752,17 @@ if_dump_vty (struct vty *vty, struct interface *ifp)
     vty_out (vty, "down%s", VTY_NEWLINE);
   }
 
+  vty_out (vty, "  PTM status: ");
+  if (ifp->ptm_enable) {
+    if (ifp->ptm_status) {
+      vty_out (vty, "pass%s", VTY_NEWLINE);
+    } else {
+      vty_out (vty, "fail%s", VTY_NEWLINE);
+    }
+  } else {
+    vty_out (vty, "disabled%s", VTY_NEWLINE);
+  }
+
   if (ifp->desc)
     vty_out (vty, "  Description: %s%s", ifp->desc,
             VTY_NEWLINE);
@@ -1079,11 +1100,11 @@ DEFUN (linkdetect,
   int if_was_operative;
   
   ifp = (struct interface *) vty->index;
-  if_was_operative = if_is_operative(ifp);
+  if_was_operative = if_is_no_ptm_operative(ifp);
   SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
 
   /* When linkdetection is enabled, if might come down */
-  if (!if_is_operative(ifp) && if_was_operative) if_down(ifp);
+  if (!if_is_no_ptm_operative(ifp) && if_was_operative) if_down(ifp);
 
   /* FIXME: Will defer status change forwarding if interface
      does not come down! */
@@ -1102,7 +1123,7 @@ DEFUN (no_linkdetect,
   int if_was_operative;
 
   ifp = (struct interface *) vty->index;
-  if_was_operative = if_is_operative(ifp);
+  if_was_operative = if_is_no_ptm_operative(ifp);
   UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
   
   /* Interface may come up after disabling link detection */
@@ -1570,6 +1591,8 @@ if_config_write (struct vty *vty)
   struct listnode *node;
   struct interface *ifp;
 
+  zebra_ptm_write (vty);
+
   for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
     {
       struct zebra_if *if_data;
index 306468fce342e457468913d36be91c6e7230c554..13ad08eff59e4660b032aba2e296418bcb5f181d 100644 (file)
@@ -40,6 +40,9 @@
 #include "zebra/irdp.h"
 #include "zebra/rtadv.h"
 #include "zebra/zebra_fpm.h"
+#include "zebra/zebra_ptm.h"
+
+#define ZEBRA_PTM_SUPPORT
 
 /* Zebra instance */
 struct zebra_t zebrad =
@@ -334,6 +337,10 @@ main (int argc, char **argv)
 #ifdef HAVE_IRDP
   irdp_init();
 #endif
+  /* PTM socket */
+#ifdef ZEBRA_PTM_SUPPORT
+  zebra_ptm_init();
+#endif
 
   /* For debug purpose. */
   /* SET_FLAG (zebra_debug_event, ZEBRA_DEBUG_EVENT); */
index 078c2ad0b36ec5ed44d7a94bb8047670e9dc3b6b..4767d9dbfe962d290f74aa5fdbdd8b51df9637d4 100644 (file)
@@ -37,6 +37,9 @@
 #include "zebra/debug.h"
 #include "zebra/router-id.h"
 
+#define ZEBRA_PTM_SUPPORT
+
+
 /* master zebra server structure */
 extern struct zebra_t zebrad;
 
@@ -292,8 +295,10 @@ zebra_interface_up_update (struct interface *ifp)
   if (IS_ZEBRA_DEBUG_EVENT)
     zlog_debug ("MESSAGE: ZEBRA_INTERFACE_UP %s", ifp->name);
 
-  for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
-    zsend_interface_update (ZEBRA_INTERFACE_UP, client, ifp);
+  if (ifp->ptm_status || !ifp->ptm_enable) {
+    for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
+      zsend_interface_update (ZEBRA_INTERFACE_UP, client, ifp);
+  }
 }
 
 /* Interface down information. */
index 290c8bc282bbf9cbf86901e12126cf03e6feae8b..ea2d42ab3ba7040ee6174d1803a8e6f6d6b49b1a 100644 (file)
@@ -1114,12 +1114,12 @@ netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
 
           netlink_interface_update_hw_addr (tb, ifp);
 
-          if (if_is_operative (ifp))
+          if (if_is_no_ptm_operative (ifp))
             {
               ifp->flags = ifi->ifi_flags & 0x0000fffff;
-              if (!if_is_operative (ifp))
+              if (!if_is_no_ptm_operative (ifp))
                 if_down (ifp);
-             else
+             else if (if_is_operative (ifp))
                /* Must notify client daemons of new interface status. */
                zebra_interface_up_update (ifp);
             }
diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c
new file mode 100644 (file)
index 0000000..6201b60
--- /dev/null
@@ -0,0 +1,308 @@
+/* Kernel routing table updates using netlink over GNU/Linux system.
+ * Copyright (C) 1997, 98, 99 Kunihiro Ishiguro
+ *
+ * This file is part of GNU Zebra.
+ *
+ * GNU Zebra is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * GNU Zebra is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Zebra; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <zebra.h>
+#include <sys/un.h>            /* for sockaddr_un */
+#include <net/if.h>
+#include "zebra/zserv.h"
+#include "zebra/interface.h"
+#include "zebra/debug.h"
+#include "zebra/zebra_ptm.h"
+#include "if.h"
+#include "command.h"
+
+#define ZEBRA_PTM_RECONNECT_TIME_INITIAL 1 /* initial reconnect is 1s */
+#define ZEBRA_PTM_RECONNECT_TIME_MAX     300
+extern struct zebra_t zebrad;
+int ptm_enable;
+
+int zebra_ptm_sock = -1;
+struct thread *zebra_ptm_thread = NULL;
+
+static int zebra_ptm_reconnect_time = ZEBRA_PTM_RECONNECT_TIME_INITIAL;
+
+static void zebra_ptm_finish(void);
+static int zebra_ptm_socket_init(void);
+static void zebra_ptm_process_msg(char *msg);
+int zebra_ptm_sock_read(struct thread *);
+static void zebra_ptm_install_commands (void);
+
+const char ZEBRA_PTM_SOCK_NAME[] = "\0/var/run/ptmd.socket";
+
+typedef enum ptm_msg_type {
+    PTM_LLDP = 0,
+    PTM_BFD,
+    PTM_MAX
+} ptm_msg_t;
+
+void
+zebra_ptm_init (void)
+{
+  zebra_ptm_install_commands();
+}
+
+int
+zebra_ptm_connect (struct thread *t)
+{
+  zebra_ptm_socket_init();
+
+  if (zebra_ptm_sock != -1) {
+    zebra_ptm_thread = thread_add_read (zebrad.master, zebra_ptm_sock_read, NULL, zebra_ptm_sock);
+    zebra_ptm_reconnect_time = ZEBRA_PTM_RECONNECT_TIME_INITIAL;
+  } else {
+    zlog_err("%s: Socket connect to %s failed with err = %d\n", __func__,
+            ZEBRA_PTM_SOCK_NAME, errno);
+    zebra_ptm_reconnect_time *= 2;
+    if (zebra_ptm_reconnect_time > ZEBRA_PTM_RECONNECT_TIME_MAX)
+      zebra_ptm_reconnect_time = ZEBRA_PTM_RECONNECT_TIME_MAX;
+
+    zebra_ptm_thread = thread_add_timer (zebrad.master, zebra_ptm_connect, NULL,
+                                        zebra_ptm_reconnect_time);
+  }
+
+  return(errno);
+}
+
+static void
+zebra_ptm_finish (void)
+{
+  if (zebra_ptm_sock != -1)
+    {
+      if (zebra_ptm_thread != NULL)
+       {
+         thread_cancel(zebra_ptm_thread);
+         zebra_ptm_thread = NULL;
+       }
+      close (zebra_ptm_sock);
+      zebra_ptm_sock = -1;
+    }
+}
+
+DEFUN (zebra_ptm_enable,
+       zebra_ptm_enable_cmd,
+       "ptm-enable",
+       "Enable neighbor check with specified topology\n")
+{
+  struct listnode *i;
+  struct interface *ifp;
+
+  ptm_enable = 1;
+
+  for (ALL_LIST_ELEMENTS_RO (iflist, i, ifp))
+    if (!ifp->ptm_enable)
+      {
+       ifp->ptm_enable = 1;
+       ifp->ptm_status = 1;    /* to bring down ports that may fail check */
+      }
+
+  zebra_ptm_connect(NULL);
+
+  return CMD_SUCCESS;
+}
+
+DEFUN (no_zebra_ptm_enable,
+       no_zebra_ptm_enable_cmd,
+       "no ptm-enable",
+       NO_STR
+       "Enable neighbor check with specified topology\n")
+{
+  struct listnode *i;
+  struct interface *ifp;
+  int send_linkup;
+
+  ptm_enable = 0;
+  for (ALL_LIST_ELEMENTS_RO (iflist, i, ifp))
+    {
+      if (ifp->ptm_enable)
+       {
+         if (!if_is_operative(ifp))
+           send_linkup = 1;
+
+         ifp->ptm_enable = 0;
+         if (if_is_operative (ifp) && send_linkup) {
+           zlog_debug ("%s: Bringing up interface %s\n", __func__,
+                       ifp->name);
+           if_up (ifp);
+         }
+       }
+    }
+  zebra_ptm_finish();
+
+  return CMD_SUCCESS;
+}
+
+void
+zebra_ptm_write (struct vty *vty)
+{
+  if (ptm_enable)
+    vty_out (vty, "ptm-enable%s", VTY_NEWLINE);
+
+  return;
+}
+
+static int
+zebra_ptm_socket_init (void)
+{
+  int ret;
+  int sock;
+  struct sockaddr_un addr;
+
+  zebra_ptm_sock = -1;
+  sock = socket (PF_UNIX, SOCK_STREAM, 0);
+  if (sock < 0)
+    return -1;
+
+  /* Make server socket. */
+  memset (&addr, 0, sizeof (struct sockaddr_un));
+  addr.sun_family = AF_UNIX;
+  memcpy (&addr.sun_path, ZEBRA_PTM_SOCK_NAME,
+         sizeof(ZEBRA_PTM_SOCK_NAME));
+
+  ret = connect(sock, (struct sockaddr *) &addr,
+               sizeof (addr.sun_family)+sizeof (ZEBRA_PTM_SOCK_NAME)-1);
+  if (ret < 0)
+    {
+      zlog_err("%s: Unable to connect to socket %s, errno=%d\n",
+              __func__, ZEBRA_PTM_SOCK_NAME, errno);
+      close (sock);
+      return -1;
+    }
+  zlog_debug ("%s: connection to ptm socket %s succeeded\n",
+             __func__, ZEBRA_PTM_SOCK_NAME);
+  zebra_ptm_sock = sock;
+  return sock;
+}
+
+static void
+zebra_ptm_install_commands (void)
+{
+  install_element (CONFIG_NODE, &zebra_ptm_enable_cmd);
+  install_element (CONFIG_NODE, &no_zebra_ptm_enable_cmd);
+}
+
+static void
+zebra_ptm_process_msg (char *buf)
+{
+  char port_name[IF_NAMESIZE+1];
+  char status[8];
+  char tgt_ip[12];
+  char type[2];
+  char byte_len[4];
+  struct interface *ifp;
+  int scan_count, bytes_read;
+  char *pos;
+  const char *delim = "\n";
+  struct in_addr dest_addr;
+  struct prefix dest_prefix;
+  ptm_msg_t msg_type;
+
+  /* the messages from the ptm ctl socket are in text only */
+  /* with a fixed format:<count> <portname> <type> <pass|fail> */
+  pos = strtok(buf, delim);
+  while (pos != NULL) {
+    if (strstr(pos, "EOF") != NULL)
+      break;
+    scan_count = sscanf(pos, "%3s %16s %1s %4s %n", byte_len, port_name, type, status, &bytes_read);
+
+    if (scan_count == 4) {
+
+      zlog_debug("%s: %s received new status %s, type %s with scan count = %d\n",
+                 __func__, port_name, type, status, scan_count);
+
+      ifp = if_lookup_by_name(port_name);
+      if (ifp == NULL) {
+       zlog_err("%s: %s not found in interface list\n", __func__, port_name);
+       return;
+      }
+
+      if (strchr(type, "B") == 0) {
+        msg_type = PTM_BFD;
+        pos = pos + bytes_read;
+        scan_count = sscanf(pos, "%11s", tgt_ip);
+      } else {
+        msg_type = PTM_LLDP;
+      }
+
+      if (strcmp(status, "pass") == 0) {
+       if (!ifp->ptm_status) {
+         ifp->ptm_status = 1;
+         if (ifp->ptm_enable && if_is_no_ptm_operative (ifp))
+           if_up (ifp);
+       }
+      } else if (strcmp (status, "fail") == 0) {
+        if (ifp->ptm_status) {
+          ifp->ptm_status = 0;
+          if (ifp->ptm_enable && if_is_no_ptm_operative (ifp)) {
+            if (msg_type == PTM_BFD) {
+
+              if (inet_pton(AF_INET, tgt_ip, &dest_addr) <= 0) {
+                  zlog_err ("%s: Not a valid destination address: %s",
+                            __func__, tgt_ip);
+                  return;
+              }
+              dest_prefix.family = AF_INET;
+              dest_prefix.u.prefix4 = dest_addr;
+              dest_prefix.prefixlen = IPV4_MAX_PREFIXLEN;
+
+              /* Send BFD message with ifp and dest_prefix to protocols */
+            } else {
+              if_down (ifp);
+            }
+          }
+       }
+      }
+    }
+    pos = strtok(NULL, delim);
+  }
+}
+
+int
+zebra_ptm_sock_read (struct thread *thread)
+{
+  int sock;
+  char rcvbuf[ZEBRA_PTM_MAX_SOCKBUF];
+  int nbytes;
+
+  sock = THREAD_FD (thread);
+
+  if (sock == -1)
+    return -1;
+
+  nbytes = recv(sock, rcvbuf, sizeof(rcvbuf), 0);
+
+  if (nbytes <= 0)
+    {
+      if (nbytes < 0 && errno != EWOULDBLOCK && errno != EAGAIN)
+       zlog_warn ("routing socket error: %s", safe_strerror (errno));
+
+      zebra_ptm_sock = -1;
+      zebra_ptm_thread = thread_add_timer (zebrad.master, zebra_ptm_connect, NULL,
+                                          zebra_ptm_reconnect_time);
+      return (-1);
+    }
+
+  zlog_debug ("%s: Received message \n%s\n", __func__, rcvbuf);
+  zebra_ptm_thread = thread_add_read (zebrad.master, zebra_ptm_sock_read, NULL, sock);
+
+  zebra_ptm_process_msg (rcvbuf);
+
+  return(0);
+}
diff --git a/zebra/zebra_ptm.h b/zebra/zebra_ptm.h
new file mode 100644 (file)
index 0000000..126c448
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Definitions for prescriptive topology module (PTM).
+ * Copyright (C) 1998, 99, 2000 Kunihiro Ishiguro, Toshiaki Takada
+ *
+ * This file is part of GNU Zebra.
+ *
+ * GNU Zebra is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * GNU Zebra is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Zebra; see the file COPYING.  If not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef _ZEBRA_PTM_H
+#define _ZEBRA_PTM_H
+
+extern const char ZEBRA_PTM_SOCK_NAME[];
+#define ZEBRA_PTM_MAX_SOCKBUF 3200 /* 25B *128 ports */
+extern int ptm_enable;
+
+void zebra_ptm_init (void);
+int zebra_ptm_connect (struct thread *t);
+void zebra_ptm_write (struct vty *vty);
+
+#endif
index 98b6f91c9bb3f52587986ef86c69d4df0e426c0a..f4ce81f788845b9234a43b00a1c0e35fbba88b8d 100644 (file)
@@ -150,6 +150,8 @@ zserv_encode_interface (struct stream *s, struct interface *ifp)
   stream_putl (s, ifp->ifindex);
   stream_putc (s, ifp->status);
   stream_putq (s, ifp->flags);
+  stream_putc (s, ifp->ptm_enable);
+  stream_putc (s, ifp->ptm_status);
   stream_putl (s, ifp->metric);
   stream_putl (s, ifp->mtu);
   stream_putl (s, ifp->mtu6);