This is the mail archive of the
libc-hacker@sourceware.cygnus.com
mailing list for the glibc project.
Re: PF_NETLINK support in glibc
[cc'ed to Alexey because it is his brain child]
On Thu, Nov 12, 1998 at 07:24:24PM +0100, Philip Blundell wrote:
> >The glibc CVS tree doesn't seem to have support for the new PF_NETLINK
> >& rtnetlink socket family in Linux 2.1. Unfortunately the linux/* include
> >file conflicts partly with glibc.
>
> Here's a patch I cooked up to add support for netlink sockets. Can you (and
> anybody else who's interested) take a look and let me know if it seems OK.
To make it useful at least support for rtnetlink (linux/rtnetlink.h) is needed.
rtnetlink is the IPv4 routing table interface which is the main
use of netlink currently.
>
> I don't have any applications here that use AF_NETLINK so I haven't tested
> it myself.
Applications using the new netlink interface are:
- gated with ANK's patches from ftp.inr.ac.ru:/ip-routing
- iproute2 (needs a few changes to compile with glibc), available from inr
too.
- zebra from ftp.zebra.org
- mtr somewhere on www.merit.edu
The beginning of some netlink documentation (not finished) is included
with my snapshot of the rewriten linux networking manpages at
ftp.muc.de:/people/ak/netman*
There is also a problem with NLMSG_NEXT IMHO: it doesn't return NULL at
the end or when the message is invalid like the similar cmsg function.
The caller has to do the NLMSG_DONE check himself and call NLMSG_OK
before looking at the message. I think it would be better if NLMSG_NEXT
did all so that when it returns != NULL the pointer is guranteed to
be valid. Unfortunately that would be an API change for existing
netlink programs.
Also the length argument of NLMSG_NEXT must be a lvalue,
that probably be documented.
-Andi
>
> p.
>
> 1998-11-12 Philip Blundell <philb@gnu.org>
>
> * sysdeps/unix/sysv/linux/netlink/netlink.h: New file, support for
> Linux AF_NETLINK sockets (needed since the kernel version is
> unusable).
> * sysdeps/unix/sysv/linux/Makefile: Install it.
> * sysdeps/unix/sysv/linux/Dist: Distribute it.
>
> --- libc/sysdeps/unix/sysv/linux/Makefile~ Thu Oct 29 03:07:00 1998
> +++ libc/sysdeps/unix/sysv/linux/Makefile Thu Nov 12 19:18:52 1998
> @@ -84,7 +84,7 @@
> netinet/if_fddi.h netinet/if_tr.h netinet/igmp.h \
> netipx/ipx.h netash/ash.h netax25/ax25.h netatalk/at.h \
> netrom/netrom.h netpacket/packet.h netrose/rose.h \
> - neteconet/ec.h
> + neteconet/ec.h netlink/netlink.h
> endif
>
> # Don't compile the ctype glue code, since there is no old non-GNU C library.
> --- libc/sysdeps/unix/sysv/linux/Dist~ Thu Oct 29 03:07:00 1998
> +++ libc/sysdeps/unix/sysv/linux/Dist Thu Nov 12 19:18:47 1998
> @@ -35,6 +35,7 @@
> netinet/igmp.h
> netinet/in_systm.h
> netinet/ip_fw.h
> +netlink/netlink.h
> netpacket/packet.h
> netipx/ipx.h
> netrom/netrom.h
> --- /dev/null Sun Oct 12 19:38:15 1997
> +++ libc/sysdeps/unix/sysv/linux/netlink/netlink.h Thu Nov 12 19:17:20 1998
> @@ -0,0 +1,125 @@
> +/* Definitions for use with Linux AF_NETLINK sockets.
> + Copyright (C) 1998 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
> +
> + The GNU C Library is free software; you can redistribute it and/or
> + modify it under the terms of the GNU Library General Public License as
> + published by the Free Software Foundation; either version 2 of the
> + License, or (at your option) any later version.
> +
> + The GNU C Library 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
> + Library General Public License for more details.
> +
> + You should have received a copy of the GNU Library General Public
> + License along with the GNU C Library; see the file COPYING.LIB. If not,
> + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
> + Boston, MA 02111-1307, USA. */
> +
> +#ifndef __NETLINK_NETLINK_H
> +#define __NETLINK_NETLINK_H 1
> +
> +#include <features.h>
> +
> +#include <sys/types.h>
> +#include <bits/sockaddr.h>
> +
> +__BEGIN_DECLS
> +
> +struct sockaddr_nl
> + {
> + __SOCKADDR_COMMON (nl_);
> + unsigned short nl_pad; /* zero. */
> + uint32_t nl_pid; /* process pid. */
> + uint32_t nl_groups; /* multicast groups mask. */
> + };
> +
> +#define NETLINK_ROUTE 0 /* Routing/device hook. */
> +#define NETLINK_SKIP 1 /* Reserved for ENskip. */
> +#define NETLINK_USERSOCK 2 /* Reserved for user mode
> + socket protocolss. */
> +#define NETLINK_FIREWALL 3 /* Firewalling hook. */
> +#define NETLINK_ARPD 8
> +#define NETLINK_ROUTE6 11 /* AF_INET6 route comm channel */
> +#define NETLINK_IP6_FW 13
> +#define NETLINK_TAPBASE 16 /* 16 to 31 are ethertap */
> +
> +#define MAX_LINKS 32
> +
> +struct nlmsghdr
> + {
> + uint32_t nlmsg_len; /* Length of message including header */
> + uint16_t nlmsg_type; /* Message content */
> + uint16_t nlmsg_flags; /* Additional flags */
> + uint32_t nlmsg_seq; /* Sequence number */
> + uint32_t nlmsg_pid; /* Sending process PID */
> + };
> +
> +/* Flag bits */
> +#define NLM_F_REQUEST 1 /* Message is a request. */
> +#define NLM_F_MULTI 2 /* Multipart message, terminated by
> + NLMSG_DONE. */
> +#define NLM_F_ACK 4 /* If operation succeeds, reply with ack. */
> +#define NLM_F_ECHO 8 /* Echo this request. */
> +
> +/* Modifiers to GET request */
> +#define NLM_F_ROOT 0x100 /* specify tree root. */
> +#define NLM_F_MATCH 0x200 /* return all matching. */
> +#define NLM_F_ATOMIC 0x400 /* atomic GET. */
> +#define NLM_F_DUMP (NLM_F_ROOT|NLM_F_MATCH)
> +
> +/* Modifiers to NEW request */
> +#define NLM_F_REPLACE 0x100 /* Override existing. */
> +#define NLM_F_EXCL 0x200 /* Do not touch, if it exists. */
> +#define NLM_F_CREATE 0x400 /* Create, if it does not exist. */
> +#define NLM_F_APPEND 0x800 /* Add to end of list. */
> +
> +/*
> + 4.4BSD ADD NLM_F_CREATE|NLM_F_EXCL
> + 4.4BSD CHANGE NLM_F_REPLACE
> +
> + True CHANGE NLM_F_CREATE|NLM_F_REPLACE
> + Append NLM_F_CREATE
> + Check NLM_F_EXCL
> + */
> +
> +#define NLMSG_ALIGNTO 4
> +
> +#define NLMSG_ALIGN(len) \
> + (((len)+NLMSG_ALIGNTO-1) & ~(NLMSG_ALIGNTO-1) )
> +
> +#define NLMSG_LENGTH(len) \
> + ((len)+NLMSG_ALIGN(sizeof(struct nlmsghdr)))
> +
> +#define NLMSG_SPACE(len) \
> + NLMSG_ALIGN(NLMSG_LENGTH(len))
> +
> +#define NLMSG_DATA(nlh) \
> + ((void*)(((char*)nlh) + NLMSG_LENGTH(0)))
> +
> +#define NLMSG_NEXT(nlh,len) \
> + ((len) -= NLMSG_ALIGN((nlh)->nlmsg_len), \
> + (struct nlmsghdr*)(((char*)(nlh)) + NLMSG_ALIGN((nlh)->nlmsg_len)))
> +
> +#define NLMSG_OK(nlh,len) \
> + ((len) > 0 && (nlh)->nlmsg_len >= sizeof(struct nlmsghdr)
> + && (nlh)->nlmsg_len <= (len))
> +
> +#define NLMSG_PAYLOAD(nlh,len) \
> + ((nlh)->nlmsg_len - NLMSG_SPACE((len)))
> +
> +#define NLMSG_NOOP 0x1 /* Nothing. */
> +#define NLMSG_ERROR 0x2 /* Error. */
> +#define NLMSG_DONE 0x3 /* End of a dump. */
> +#define NLMSG_OVERRUN 0x4 /* Data lost. */
> +
> +struct nlmsgerr
> + {
> + int error;
> + struct nlmsghdr msg;
> + };
> +
> +#define NET_MAJOR 36 /* Major 36 is reserved for networking */
> +
> +#endif
>
>