mirror of
				https://git.proxmox.com/git/mirror_frr
				synced 2025-11-04 08:04:27 +00:00 
			
		
		
		
	rib_add_ipv6() function so that IPv6 routes in RIB can have correct metric. No IPv6 routing daemon uses distance yet though. * zserv.c, connected.c, kernel_socket.c, rt_netlink.c, rtread_proc.c,zserv.c: Pass metric and distance info to the rib_add_ipv6(). Forwardport from stable branch.
		
			
				
	
	
		
			176 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			176 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * Kernel routing readup by /proc filesystem
 | 
						|
 * Copyright (C) 1997 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 "prefix.h"
 | 
						|
#include "log.h"
 | 
						|
#include "if.h"
 | 
						|
#include "rib.h"
 | 
						|
 | 
						|
#include "zebra/zserv.h"
 | 
						|
#include "zebra/rt.h"
 | 
						|
 | 
						|
/* Proc file system to read IPv4 routing table. */
 | 
						|
#ifndef _PATH_PROCNET_ROUTE
 | 
						|
#define _PATH_PROCNET_ROUTE      "/proc/net/route"
 | 
						|
#endif /* _PATH_PROCNET_ROUTE */
 | 
						|
 | 
						|
/* Proc file system to read IPv6 routing table. */
 | 
						|
#ifndef _PATH_PROCNET_ROUTE6
 | 
						|
#define _PATH_PROCNET_ROUTE6     "/proc/net/ipv6_route"
 | 
						|
#endif /* _PATH_PROCNET_ROUTE6 */
 | 
						|
 | 
						|
/* To read interface's name */
 | 
						|
#define INTERFACE_NAMSIZ 20  
 | 
						|
 | 
						|
/* Reading buffer for one routing entry. */
 | 
						|
#define RT_BUFSIZ 1024
 | 
						|
 | 
						|
/* Kernel routing table read up by /proc filesystem. */
 | 
						|
static int
 | 
						|
proc_route_read (void)
 | 
						|
{
 | 
						|
  FILE *fp;
 | 
						|
  char buf[RT_BUFSIZ];
 | 
						|
  char iface[INTERFACE_NAMSIZ], dest[9], gate[9], mask[9];
 | 
						|
  int flags, refcnt, use, metric, mtu, window, rtt;
 | 
						|
 | 
						|
  /* Open /proc filesystem */
 | 
						|
  fp = fopen (_PATH_PROCNET_ROUTE, "r");
 | 
						|
  if (fp == NULL)
 | 
						|
    {
 | 
						|
      zlog_warn ("Can't open %s : %s\n", _PATH_PROCNET_ROUTE, safe_strerror (errno));
 | 
						|
      return -1;
 | 
						|
    }
 | 
						|
  
 | 
						|
  /* Drop first label line. */
 | 
						|
  fgets (buf, RT_BUFSIZ, fp);
 | 
						|
 | 
						|
  while (fgets (buf, RT_BUFSIZ, fp) != NULL)
 | 
						|
    {
 | 
						|
      int n;
 | 
						|
      struct prefix_ipv4 p;
 | 
						|
      struct in_addr tmpmask;
 | 
						|
      struct in_addr gateway;
 | 
						|
      u_char zebra_flags = 0;
 | 
						|
 | 
						|
      n = sscanf (buf, "%s %s %s %x %d %d %d %s %d %d %d",
 | 
						|
		  iface, dest, gate, &flags, &refcnt, &use, &metric, 
 | 
						|
		  mask, &mtu, &window, &rtt);
 | 
						|
      if (n != 11)
 | 
						|
	{	
 | 
						|
	  zlog_warn ("can't read all of routing information\n");
 | 
						|
	  continue;
 | 
						|
	}
 | 
						|
      if (! (flags & RTF_UP))
 | 
						|
	continue;
 | 
						|
      if (! (flags & RTF_GATEWAY))
 | 
						|
	continue;
 | 
						|
 | 
						|
      if (flags & RTF_DYNAMIC)
 | 
						|
	zebra_flags |= ZEBRA_FLAG_SELFROUTE;
 | 
						|
 | 
						|
      p.family = AF_INET;
 | 
						|
      sscanf (dest, "%lX", (unsigned long *)&p.prefix);
 | 
						|
      sscanf (mask, "%lX", (unsigned long *)&tmpmask);
 | 
						|
      p.prefixlen = ip_masklen (tmpmask);
 | 
						|
      sscanf (gate, "%lX", (unsigned long *)&gateway);
 | 
						|
 | 
						|
      rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, &gateway, 0, 0, 0, 0);
 | 
						|
    }
 | 
						|
 | 
						|
  fclose (fp);
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
#ifdef HAVE_IPV6
 | 
						|
static int
 | 
						|
proc_ipv6_route_read ()
 | 
						|
{
 | 
						|
  FILE *fp;
 | 
						|
  char buf [RT_BUFSIZ];
 | 
						|
 | 
						|
  /* Open /proc filesystem */
 | 
						|
  fp = fopen (_PATH_PROCNET_ROUTE6, "r");
 | 
						|
  if (fp == NULL)
 | 
						|
    {
 | 
						|
      zlog_warn ("Can't open %s : %s", _PATH_PROCNET_ROUTE6, 
 | 
						|
		safe_strerror (errno));
 | 
						|
      return -1;
 | 
						|
    }
 | 
						|
  
 | 
						|
  /* There is no title line, so we don't drop first line.  */
 | 
						|
  while (fgets (buf, RT_BUFSIZ, fp) != NULL)
 | 
						|
    {
 | 
						|
      int n;
 | 
						|
      char dest[33], src[33], gate[33];
 | 
						|
      char iface[INTERFACE_NAMSIZ];
 | 
						|
      int dest_plen, src_plen;
 | 
						|
      int metric, use, refcnt, flags;
 | 
						|
      struct prefix_ipv6 p;
 | 
						|
      struct in6_addr gateway;
 | 
						|
      u_char zebra_flags = 0;
 | 
						|
 | 
						|
      /* Linux 2.1.x write this information at net/ipv6/route.c
 | 
						|
         rt6_info_node () */
 | 
						|
      n = sscanf (buf, "%32s %02x %32s %02x %32s %08x %08x %08x %08x %s",
 | 
						|
		  dest, &dest_plen, src, &src_plen, gate,
 | 
						|
		  &metric, &use, &refcnt, &flags, iface);
 | 
						|
 | 
						|
      if (n != 10)
 | 
						|
	{	
 | 
						|
	  /* zlog_warn ("can't read all of routing information %d\n%s\n", n, buf); */
 | 
						|
	  continue;
 | 
						|
	}
 | 
						|
 | 
						|
      if (! (flags & RTF_UP))
 | 
						|
	continue;
 | 
						|
      if (! (flags & RTF_GATEWAY))
 | 
						|
	continue;
 | 
						|
 | 
						|
      if (flags & RTF_DYNAMIC)
 | 
						|
	zebra_flags |= ZEBRA_FLAG_SELFROUTE;
 | 
						|
 | 
						|
      p.family = AF_INET6;
 | 
						|
      str2in6_addr (dest, &p.prefix);
 | 
						|
      str2in6_addr (gate, &gateway);
 | 
						|
      p.prefixlen = dest_plen;
 | 
						|
 | 
						|
      rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, &gateway, 0, 0,
 | 
						|
		    metric, 0);
 | 
						|
    }
 | 
						|
 | 
						|
  fclose (fp);
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
#endif /* HAVE_IPV6 */
 | 
						|
 | 
						|
void
 | 
						|
route_read (void)
 | 
						|
{
 | 
						|
  proc_route_read ();
 | 
						|
#ifdef HAVE_IPV6
 | 
						|
  proc_ipv6_route_read ();
 | 
						|
#endif /* HAVE_IPV6 */
 | 
						|
}
 |