]> git.proxmox.com Git - mirror_frr.git/blobdiff - zebra/zserv.c
[autoconf] bugs 162,303,178: Fix 'present but can not be compiled' warnings
[mirror_frr.git] / zebra / zserv.c
index e90fe0194a101f8da509b8f834bd5fc135e96af5..ef79eaad3da06f9dbfbf3b4dd17b951e5d2384aa 100644 (file)
@@ -52,34 +52,6 @@ static void zebra_event (enum event event, int sock, struct zserv *client);
 
 extern struct zebra_privs_t zserv_privs;
 \f
-/* For logging of zebra meesages. */
-static const char *zebra_command_str [] =
-{
-  "NULL",
-  "ZEBRA_INTERFACE_ADD",
-  "ZEBRA_INTERFACE_DELETE",
-  "ZEBRA_INTERFACE_ADDRESS_ADD",
-  "ZEBRA_INTERFACE_ADDRESS_DELETE",
-  "ZEBRA_INTERFACE_UP",
-  "ZEBRA_INTERFACE_DOWN",
-  "ZEBRA_IPV4_ROUTE_ADD",
-  "ZEBRA_IPV4_ROUTE_DELETE",
-  "ZEBRA_IPV6_ROUTE_ADD",
-  "ZEBRA_IPV6_ROUTE_DELETE",
-  "ZEBRA_REDISTRIBUTE_ADD",
-  "ZEBRA_REDISTRIBUTE_DELETE",
-  "ZEBRA_REDISTRIBUTE_DEFAULT_ADD",
-  "ZEBRA_REDISTRIBUTE_DEFAULT_DELETE",
-  "ZEBRA_IPV4_NEXTHOP_LOOKUP",
-  "ZEBRA_IPV6_NEXTHOP_LOOKUP",
-  "ZEBRA_IPV4_IMPORT_LOOKUP",
-  "ZEBRA_IPV6_IMPORT_LOOKUP",
-  "ZEBRA_ROUTER_ID_ADD",
-  "ZEBRA_ROUTER_ID_DELETE",
-  "ZEBRA_ROUTER_ID_UPDATE"
-};
-\f
-
 static void zebra_client_close (struct zserv *client);
 
 static int
@@ -138,7 +110,6 @@ zebra_server_send_message(struct zserv *client)
       client->t_suicide = thread_add_event(zebrad.master, zserv_delayed_close,
                                           client, 0);
       return -1;
-      break;
     case BUFFER_EMPTY:
       THREAD_OFF(client->t_write);
       break;
@@ -150,6 +121,16 @@ zebra_server_send_message(struct zserv *client)
   return 0;
 }
 
+static void
+zserv_create_header (struct stream *s, uint16_t cmd)
+{
+  /* length placeholder, caller can update */
+  stream_putw (s, ZEBRA_HEADER_SIZE);
+  stream_putc (s, ZEBRA_HEADER_MARKER);
+  stream_putc (s, ZSERV_VERSION);
+  stream_putw (s, cmd);
+}
+
 /* Interface is added. Send ZEBRA_INTERFACE_ADD to client. */
 /*
  * This function is called in the following situations:
@@ -173,28 +154,25 @@ zsend_interface_add (struct zserv *client, struct interface *ifp)
   s = client->obuf;
   stream_reset (s);
 
-  /* Place holder for size. */
-  stream_putw (s, 0);
-
   /* Message type. */
-  stream_putc (s, ZEBRA_INTERFACE_ADD);
+  zserv_create_header (s, ZEBRA_INTERFACE_ADD);
 
   /* Interface information. */
   stream_put (s, ifp->name, INTERFACE_NAMSIZ);
   stream_putl (s, ifp->ifindex);
   stream_putc (s, ifp->status);
-  stream_putl (s, ifp->flags);
+  stream_putq (s, ifp->flags);
   stream_putl (s, ifp->metric);
   stream_putl (s, ifp->mtu);
   stream_putl (s, ifp->mtu6);
   stream_putl (s, ifp->bandwidth);
-#ifdef HAVE_SOCKADDR_DL
+#ifdef HAVE_STRUCT_SOCKADDR_DL
   stream_put (s, &ifp->sdl, sizeof (ifp->sdl));
 #else
   stream_putl (s, ifp->hw_addr_len);
   if (ifp->hw_addr_len)
     stream_put (s, ifp->hw_addr, ifp->hw_addr_len);
-#endif /* HAVE_SOCKADDR_DL */
+#endif /* HAVE_STRUCT_SOCKADDR_DL */
 
   /* Write packet size. */
   stream_putw_at (s, 0, stream_get_endp (s));
@@ -203,12 +181,6 @@ zsend_interface_add (struct zserv *client, struct interface *ifp)
 }
 
 /* Interface deletion from zebra daemon. */
-/*
- * This function is only called  when support for 
- * RTM_IFANNOUNCE or AF_NETLINK sockets (RTM_DELLINK message)
- * is available. It is not called on Solaris.
- */
-#if (defined(RTM_IFANNOUNCE) || defined(HAVE_NETLINK))
 int
 zsend_interface_delete (struct zserv *client, struct interface *ifp)
 {
@@ -220,16 +192,14 @@ zsend_interface_delete (struct zserv *client, struct interface *ifp)
 
   s = client->obuf;
   stream_reset (s);
-
-  /* Packet length placeholder. */
-  stream_putw (s, 0);
-
+  
+  zserv_create_header (s, ZEBRA_INTERFACE_DELETE);
+  
   /* Interface information. */
-  stream_putc (s, ZEBRA_INTERFACE_DELETE);
   stream_put (s, ifp->name, INTERFACE_NAMSIZ);
   stream_putl (s, ifp->ifindex);
   stream_putc (s, ifp->status);
-  stream_putl (s, ifp->flags);
+  stream_putq (s, ifp->flags);
   stream_putl (s, ifp->metric);
   stream_putl (s, ifp->mtu);
   stream_putl (s, ifp->mtu6);
@@ -240,7 +210,6 @@ zsend_interface_delete (struct zserv *client, struct interface *ifp)
 
   return zebra_server_send_message (client);
 }
-#endif /* (defined(RTM_IFANNOUNCE) || defined(HAVE_LINUX_RTNETLINK_H)) */
 
 /* Interface address is added/deleted. Send ZEBRA_INTERFACE_ADDRESS_ADD or
  * ZEBRA_INTERFACE_ADDRESS_DELETE to the client. 
@@ -266,8 +235,8 @@ zsend_interface_delete (struct zserv *client, struct interface *ifp)
  *                           |                        
  *          zebra_interface_address_delete_update    
  *             ^                        ^      ^
- *             |                        |      if_delete_update (not called on 
- *             |                        |                         Solaris)
+ *             |                        |      if_delete_update
+ *             |                        |
  *         ip_address_uninstall        connected_delete_ipv4
  *         [ipv6_addresss_uninstall]   [connected_delete_ipv6]
  *             ^                        ^
@@ -294,11 +263,8 @@ zsend_interface_address (int cmd, struct zserv *client,
 
   s = client->obuf;
   stream_reset (s);
-
-  /* Place holder for size. */
-  stream_putw (s, 0);
-
-  stream_putc (s, cmd);
+  
+  zserv_create_header (s, cmd);
   stream_putl (s, ifp->ifindex);
 
   /* Interface address flag. */
@@ -352,17 +318,13 @@ zsend_interface_update (int cmd, struct zserv *client, struct interface *ifp)
   s = client->obuf;
   stream_reset (s);
 
-  /* Place holder for size. */
-  stream_putw (s, 0);
-
-  /* Zebra command. */
-  stream_putc (s, cmd);
+  zserv_create_header (s, cmd);
 
   /* Interface information. */
   stream_put (s, ifp->name, INTERFACE_NAMSIZ);
   stream_putl (s, ifp->ifindex);
   stream_putc (s, ifp->status);
-  stream_putl (s, ifp->flags);
+  stream_putq (s, ifp->flags);
   stream_putl (s, ifp->metric);
   stream_putl (s, ifp->mtu);
   stream_putl (s, ifp->mtu6);
@@ -404,29 +366,22 @@ zsend_route_multipath (int cmd, struct zserv *client, struct prefix *p,
   int psize;
   struct stream *s;
   struct nexthop *nexthop;
-  unsigned long nhnummark = 0;
+  unsigned long nhnummark = 0, messmark = 0;
   int nhnum = 0;
-  u_char zapi_flags = ZAPI_MESSAGE_NEXTHOP | ZAPI_MESSAGE_IFINDEX;
+  u_char zapi_flags = 0;
   
   s = client->obuf;
   stream_reset (s);
-
-  /* Place holder for size. */
-  stream_putw (s, 0);
-
-  /* Put command, type and nexthop. */
-  stream_putc (s, cmd);
+  
+  zserv_create_header (s, cmd);
+  
+  /* Put type and nexthop. */
   stream_putc (s, rib->type);
   stream_putc (s, rib->flags);
-
-  /* 
-   * XXX no need to set ZAPI_MESSAGE_NEXTHOP if we are going to
-   * send empty nexthop?
-   */
-  if (cmd == ZEBRA_IPV4_ROUTE_ADD || ZEBRA_IPV6_ROUTE_ADD)
-    zapi_flags |= ZAPI_MESSAGE_METRIC;
-
-  stream_putc (s, zapi_flags);
+  
+  /* marker for message flags field */
+  messmark = stream_get_endp (s);
+  stream_putc (s, 0);
 
   /* Prefix. */
   psize = PSIZE (p->prefixlen);
@@ -442,12 +397,20 @@ zsend_route_multipath (int cmd, struct zserv *client, struct prefix *p,
    * is hard-coded.
    */
   /* Nexthop */
+  
   for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
     {
       if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
         {
-          nhnummark = stream_get_endp (s);
-          stream_putc (s, 1); /* placeholder */
+          SET_FLAG (zapi_flags, ZAPI_MESSAGE_NEXTHOP);
+          SET_FLAG (zapi_flags, ZAPI_MESSAGE_IFINDEX);
+          
+          if (nhnummark == 0)
+            {
+              nhnummark = stream_get_endp (s);
+              stream_putc (s, 1); /* placeholder */
+            }
+          
           nhnum++;
 
           switch(nexthop->type) 
@@ -488,8 +451,17 @@ zsend_route_multipath (int cmd, struct zserv *client, struct prefix *p,
     }
 
   /* Metric */
-  stream_putl (s, rib->metric);
-
+  if (cmd == ZEBRA_IPV4_ROUTE_ADD || ZEBRA_IPV6_ROUTE_ADD)
+    {
+      SET_FLAG (zapi_flags, ZAPI_MESSAGE_DISTANCE);
+      stream_putc (s, rib->distance);
+      SET_FLAG (zapi_flags, ZAPI_MESSAGE_METRIC);
+      stream_putl (s, rib->metric);
+    }
+  
+  /* write real message flags value */
+  stream_putc_at (s, messmark, zapi_flags);
+  
   /* Write next-hop number */
   if (nhnummark)
     stream_putc_at (s, nhnummark, nhnum);
@@ -518,8 +490,7 @@ zsend_ipv6_nexthop_lookup (struct zserv *client, struct in6_addr *addr)
   stream_reset (s);
 
   /* Fill in result. */
-  stream_putw (s, 0);
-  stream_putc (s, ZEBRA_IPV6_NEXTHOP_LOOKUP);
+  zserv_create_header (s, ZEBRA_IPV6_NEXTHOP_LOOKUP);
   stream_put (s, &addr, 16);
 
   if (rib)
@@ -583,8 +554,7 @@ zsend_ipv4_nexthop_lookup (struct zserv *client, struct in_addr addr)
   stream_reset (s);
 
   /* Fill in result. */
-  stream_putw (s, 0);
-  stream_putc (s, ZEBRA_IPV4_NEXTHOP_LOOKUP);
+  zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP);
   stream_put_in_addr (s, &addr);
 
   if (rib)
@@ -642,8 +612,7 @@ zsend_ipv4_import_lookup (struct zserv *client, struct prefix_ipv4 *p)
   stream_reset (s);
 
   /* Fill in result. */
-  stream_putw (s, 0);
-  stream_putc (s, ZEBRA_IPV4_IMPORT_LOOKUP);
+  zserv_create_header (s, ZEBRA_IPV4_IMPORT_LOOKUP);
   stream_put_in_addr (s, &p->prefix);
 
   if (rib)
@@ -698,11 +667,8 @@ zsend_router_id_update (struct zserv *client, struct prefix *p)
   s = client->obuf;
   stream_reset (s);
 
-  /* Place holder for size. */
-  stream_putw (s, 0);
-
   /* Message type. */
-  stream_putc (s, ZEBRA_ROUTER_ID_UPDATE);
+  zserv_create_header (s, ZEBRA_ROUTER_ID_UPDATE);
 
   /* Prefix information. */
   stream_putc (s, p->family);
@@ -780,9 +746,8 @@ zread_ipv4_add (struct zserv *client, u_short length)
   s = client->ibuf;
 
   /* Allocate new rib. */
-  rib = XMALLOC (MTYPE_RIB, sizeof (struct rib));
-  memset (rib, 0, sizeof (struct rib));
-
+  rib = XCALLOC (MTYPE_RIB, sizeof (struct rib));
+  
   /* Type, flags, message. */
   rib->type = stream_getc (s);
   rib->flags = stream_getc (s);
@@ -816,7 +781,7 @@ zread_ipv4_add (struct zserv *client, u_short length)
              break;
            case ZEBRA_NEXTHOP_IPV4:
              nexthop.s_addr = stream_get_ipv4 (s);
-             nexthop_ipv4_add (rib, &nexthop);
+             nexthop_ipv4_add (rib, &nexthop, NULL);
              break;
            case ZEBRA_NEXTHOP_IPV6:
              stream_forward_getp (s, IPV6_MAX_BYTELEN);
@@ -836,6 +801,8 @@ zread_ipv4_add (struct zserv *client, u_short length)
   if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))
     rib->metric = stream_getl (s);
     
+  /* Table */
+  rib->table=zebrad.rtm_table_default;
   rib_add_ipv4_multipath (&p, rib);
   return 0;
 }
@@ -997,9 +964,11 @@ zread_ipv6_add (struct zserv *client, u_short length)
     api.metric = 0;
     
   if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
-    rib_add_ipv6 (api.type, api.flags, &p, NULL, ifindex, 0);
+    rib_add_ipv6 (api.type, api.flags, &p, NULL, ifindex, 0, api.metric,
+                 api.distance);
   else
-    rib_add_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, 0);
+    rib_add_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, 0, api.metric,
+                 api.distance);
   return 0;
 }
 
@@ -1165,8 +1134,8 @@ zebra_client_read (struct thread *thread)
   int sock;
   struct zserv *client;
   size_t already;
-  u_short length;
-  u_char command;
+  uint16_t length, command;
+  uint8_t marker, version;
 
   /* Get thread data.  Reset reading thread because I'm running. */
   sock = THREAD_FD (thread);
@@ -1204,9 +1173,19 @@ zebra_client_read (struct thread *thread)
   /* Reset to read from the beginning of the incoming packet. */
   stream_set_getp(client->ibuf, 0);
 
+  /* Fetch header values */
   length = stream_getw (client->ibuf);
-  command = stream_getc (client->ibuf);
+  marker = stream_getc (client->ibuf);
+  version = stream_getc (client->ibuf);
+  command = stream_getw (client->ibuf);
 
+  if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION)
+    {
+      zlog_err("%s: socket %d version mismatch, marker %d, version %d",
+               __func__, sock, marker, version);
+      zebra_client_close (client);
+      return -1;
+    }
   if (length < ZEBRA_HEADER_SIZE) 
     {
       zlog_warn("%s: socket %d message length %u is less than header size %d",
@@ -1251,7 +1230,7 @@ zebra_client_read (struct thread *thread)
 
   if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
     zlog_debug ("zebra message received [%s] %d", 
-              zebra_command_str[command], length);
+              zserv_command_string (command), length);
 
   switch (command) 
     {
@@ -1376,9 +1355,9 @@ zebra_serv ()
   memset (&addr, 0, sizeof (struct sockaddr_in));
   addr.sin_family = AF_INET;
   addr.sin_port = htons (ZEBRA_PORT);
-#ifdef HAVE_SIN_LEN
+#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
   addr.sin_len = sizeof (struct sockaddr_in);
-#endif /* HAVE_SIN_LEN */
+#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
   addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
 
   sockopt_reuseaddr (accept_sock);
@@ -1447,11 +1426,11 @@ zebra_serv_un (const char *path)
   memset (&serv, 0, sizeof (struct sockaddr_un));
   serv.sun_family = AF_UNIX;
   strncpy (serv.sun_path, path, strlen (path));
-#ifdef HAVE_SUN_LEN
+#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
   len = serv.sun_len = SUN_LEN(&serv);
 #else
   len = sizeof (serv.sun_family) + strlen (serv.sun_path);
-#endif /* HAVE_SUN_LEN */
+#endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
 
   ret = bind (sock, (struct sockaddr *) &serv, len);
   if (ret < 0)
@@ -1720,7 +1699,7 @@ struct cmd_node forwarding_node =
 \f
 /* Initialisation of zebra and installation of commands. */
 void
-zebra_init ()
+zebra_init (void)
 {
   /* Client list init. */
   zebrad.client_list = list_new ();
@@ -1754,4 +1733,7 @@ zebra_init ()
   install_element (CONFIG_NODE, &ipv6_forwarding_cmd);
   install_element (CONFIG_NODE, &no_ipv6_forwarding_cmd);
 #endif /* HAVE_IPV6 */
+
+  /* Route-map */
+  zebra_route_map_init ();
 }